mirror of
https://gitee.com/zhangsken/opencode.git
synced 2026-10-16 10:30:01 +08:00
fix(app): restore attachment classification (#49932)
Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
839aa25c3e
commit
5848ee0d24
@@ -166,6 +166,45 @@ test.describe("session timeline projection", () => {
|
||||
await expect(longNotice.locator("[title]")).toHaveAttribute("title", `Switched to ${longName}`)
|
||||
await expect.poll(() => longNotice.evaluate((element) => element.scrollWidth <= element.clientWidth)).toBe(true)
|
||||
})
|
||||
|
||||
test("does not repeat a review comment file as an attachment", async ({ page }) => {
|
||||
const message = userMessage([
|
||||
userText("what's goin on here", { id: "prt_user_review_comment" }),
|
||||
{
|
||||
id: "prt_user_review_file",
|
||||
type: "file",
|
||||
mime: "text/plain",
|
||||
filename: "LiveRuntime.ts",
|
||||
url: "file:///repo/LiveRuntime.ts?start=14&end=32",
|
||||
},
|
||||
{
|
||||
id: "prt_user_unrelated_file",
|
||||
type: "file",
|
||||
mime: "text/plain",
|
||||
filename: "notes.txt",
|
||||
url: "data:text/plain;base64,bm90ZXM=",
|
||||
},
|
||||
])
|
||||
message.metadata = {
|
||||
displayText: "what's goin on here",
|
||||
comments: [
|
||||
{
|
||||
path: "LiveRuntime.ts",
|
||||
comment: "what's goin on here",
|
||||
selection: { startLine: 14, startChar: 0, endLine: 32, endChar: 0 },
|
||||
origin: "review",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
await setupTimeline(page, { messages: [message, assistantMessage()] })
|
||||
|
||||
const user = page.locator('[data-component="user-message"]')
|
||||
await expect(user.getByText("LiveRuntime.ts:14-32", { exact: true })).toBeVisible()
|
||||
const attachments = user.locator('[data-slot="user-message-attachments"]')
|
||||
await expect(attachments.getByText("LiveRuntime.ts", { exact: true })).toHaveCount(0)
|
||||
await expect(attachments.getByText("notes.txt", { exact: true })).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
function patchFile(file: string, status: "added" | "modified" | "deleted") {
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { typeLabel } from "./message-file"
|
||||
import type { PromptFileAttachment } from "@opencode/client/promise"
|
||||
import { attached, typeLabel } from "./message-file"
|
||||
|
||||
function file(source: PromptFileAttachment["source"], mention = false): PromptFileAttachment {
|
||||
return {
|
||||
data: "",
|
||||
mime: "text/plain",
|
||||
source,
|
||||
...(mention ? { mention: { text: "@README.md", start: 0, end: 10 } } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
describe("message-file", () => {
|
||||
test("only treats data-backed files without mentions as attachments", () => {
|
||||
expect(attached(file({ type: "inline" }))).toBe(true)
|
||||
expect(attached(file({ type: "uri", uri: "data:text/plain;base64,SGVsbG8=" }))).toBe(true)
|
||||
expect(attached(file({ type: "uri", uri: "file:///repo/README.md" }))).toBe(false)
|
||||
expect(attached(file({ type: "inline" }, true))).toBe(false)
|
||||
})
|
||||
|
||||
test("labels attachment types from the basename extension", () => {
|
||||
expect(typeLabel("list.md", "text/plain", "File")).toBe("Markdown")
|
||||
expect(typeLabel("/repo/src/main.ts", "text/plain", "File")).toBe("TypeScript")
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { bundledLanguagesInfo } from "shiki"
|
||||
import { getFilename } from "@opencode/util/path"
|
||||
import type { PromptFileAttachment } from "@opencode/client/promise"
|
||||
|
||||
export function attached(file: PromptFileAttachment) {
|
||||
if (file.mention) return false
|
||||
if (file.source.type === "inline") return true
|
||||
return file.source.uri.startsWith("data:")
|
||||
}
|
||||
|
||||
// language metadata only; grammars stay behind shiki's lazy imports
|
||||
const LANGUAGE_NAMES = new Map<string, string>(
|
||||
|
||||
@@ -27,7 +27,7 @@ import type {
|
||||
SessionMessageUser,
|
||||
} from "@opencode/client/promise"
|
||||
import type { SessionUserActions, SessionUserAttachmentReference, SessionUserComment } from "../actions"
|
||||
import { typeLabel } from "../components/message-file"
|
||||
import { attached, typeLabel } from "../components/message-file"
|
||||
|
||||
export async function writeClipboard(text: string): Promise<boolean> {
|
||||
const body = typeof document === "undefined" ? undefined : document.body
|
||||
@@ -214,7 +214,7 @@ export function CurrentUserMessageDisplay(props: {
|
||||
const dialog = useDialog()
|
||||
const i18n = useI18n()
|
||||
const [state, setState] = createStore({ copied: false, reverting: false })
|
||||
const attachments = createMemo(() => (props.message.files ?? []).filter((file) => !file.mention))
|
||||
const attachments = createMemo(() => (props.message.files ?? []).filter(attached))
|
||||
const references = createMemo(() => props.references ?? [])
|
||||
const inlineFiles = createMemo(() => (props.message.files ?? []).filter((file) => !!file.mention))
|
||||
const agents = createMemo(() => props.message.agents ?? [])
|
||||
|
||||
Reference in New Issue
Block a user