Sfoglia il codice sorgente

tweak: drop ids from attachments in tools, assign them in prompt.ts instead (#13890)

Aiden Cline 1 mese fa
parent
commit
a580fb47d2

+ 20 - 10
packages/opencode/src/session/prompt.ts

@@ -445,6 +445,12 @@ export namespace SessionPrompt {
           log.error("subtask execution failed", { error, agent: task.agent, description: task.description })
           return undefined
         })
+        const attachments = result?.attachments?.map((attachment) => ({
+          ...attachment,
+          id: Identifier.ascending("part"),
+          sessionID,
+          messageID: assistantMessage.id,
+        }))
         await Plugin.trigger(
           "tool.execute.after",
           {
@@ -467,7 +473,7 @@ export namespace SessionPrompt {
               title: result.title,
               metadata: result.metadata,
               output: result.output,
-              attachments: result.attachments,
+              attachments,
               time: {
                 ...part.state.time,
                 end: Date.now(),
@@ -797,6 +803,15 @@ export namespace SessionPrompt {
             },
           )
           const result = await item.execute(args, ctx)
+          const output = {
+            ...result,
+            attachments: result.attachments?.map((attachment) => ({
+              ...attachment,
+              id: Identifier.ascending("part"),
+              sessionID: ctx.sessionID,
+              messageID: input.processor.message.id,
+            })),
+          }
           await Plugin.trigger(
             "tool.execute.after",
             {
@@ -805,9 +820,9 @@ export namespace SessionPrompt {
               callID: ctx.callID,
               args,
             },
-            result,
+            output,
           )
-          return result
+          return output
         },
       })
     }
@@ -855,16 +870,13 @@ export namespace SessionPrompt {
         )
 
         const textParts: string[] = []
-        const attachments: MessageV2.FilePart[] = []
+        const attachments: Omit<MessageV2.FilePart, "id" | "sessionID" | "messageID">[] = []
 
         for (const contentItem of result.content) {
           if (contentItem.type === "text") {
             textParts.push(contentItem.text)
           } else if (contentItem.type === "image") {
             attachments.push({
-              id: Identifier.ascending("part"),
-              sessionID: input.session.id,
-              messageID: input.processor.message.id,
               type: "file",
               mime: contentItem.mimeType,
               url: `data:${contentItem.mimeType};base64,${contentItem.data}`,
@@ -876,9 +888,6 @@ export namespace SessionPrompt {
             }
             if (resource.blob) {
               attachments.push({
-                id: Identifier.ascending("part"),
-                sessionID: input.session.id,
-                messageID: input.processor.message.id,
                 type: "file",
                 mime: resource.mimeType ?? "application/octet-stream",
                 url: `data:${resource.mimeType ?? "application/octet-stream"};base64,${resource.blob}`,
@@ -1157,6 +1166,7 @@ export namespace SessionPrompt {
                       pieces.push(
                         ...result.attachments.map((attachment) => ({
                           ...attachment,
+                          id: Identifier.ascending("part"),
                           synthetic: true,
                           filename: attachment.filename ?? part.filename,
                           messageID: info.id,

+ 7 - 1
packages/opencode/src/tool/batch.ts

@@ -77,6 +77,12 @@ export const BatchTool = Tool.define("batch", async () => {
           })
 
           const result = await tool.execute(validatedParams, { ...ctx, callID: partID })
+          const attachments = result.attachments?.map((attachment) => ({
+            ...attachment,
+            id: Identifier.ascending("part"),
+            sessionID: ctx.sessionID,
+            messageID: ctx.messageID,
+          }))
 
           await Session.updatePart({
             id: partID,
@@ -91,7 +97,7 @@ export const BatchTool = Tool.define("batch", async () => {
               output: result.output,
               title: result.title,
               metadata: result.metadata,
-              attachments: result.attachments,
+              attachments,
               time: {
                 start: callStartTime,
                 end: Date.now(),

+ 0 - 4
packages/opencode/src/tool/read.ts

@@ -6,7 +6,6 @@ import { LSP } from "../lsp"
 import { FileTime } from "../file/time"
 import DESCRIPTION from "./read.txt"
 import { Instance } from "../project/instance"
-import { Identifier } from "../id/id"
 import { assertExternalDirectory } from "./external-directory"
 import { InstructionPrompt } from "../session/instruction"
 
@@ -127,9 +126,6 @@ export const ReadTool = Tool.define("read", {
         },
         attachments: [
           {
-            id: Identifier.ascending("part"),
-            sessionID: ctx.sessionID,
-            messageID: ctx.messageID,
             type: "file",
             mime,
             url: `data:${mime};base64,${Buffer.from(await file.bytes()).toString("base64")}`,

+ 1 - 1
packages/opencode/src/tool/tool.ts

@@ -36,7 +36,7 @@ export namespace Tool {
         title: string
         metadata: M
         output: string
-        attachments?: MessageV2.FilePart[]
+        attachments?: Omit<MessageV2.FilePart, "id" | "sessionID" | "messageID">[]
       }>
       formatValidationError?(error: z.ZodError): string
     }>

+ 0 - 4
packages/opencode/src/tool/webfetch.ts

@@ -3,7 +3,6 @@ import { Tool } from "./tool"
 import TurndownService from "turndown"
 import DESCRIPTION from "./webfetch.txt"
 import { abortAfterAny } from "../util/abort"
-import { Identifier } from "../id/id"
 
 const MAX_RESPONSE_SIZE = 5 * 1024 * 1024 // 5MB
 const DEFAULT_TIMEOUT = 30 * 1000 // 30 seconds
@@ -103,9 +102,6 @@ export const WebFetchTool = Tool.define("webfetch", {
         metadata: {},
         attachments: [
           {
-            id: Identifier.ascending("part"),
-            sessionID: ctx.sessionID,
-            messageID: ctx.messageID,
             type: "file",
             mime,
             url: `data:${mime};base64,${base64Content}`,

+ 6 - 0
packages/opencode/test/tool/read.test.ts

@@ -349,6 +349,9 @@ describe("tool.read truncation", () => {
         expect(result.metadata.truncated).toBe(false)
         expect(result.attachments).toBeDefined()
         expect(result.attachments?.length).toBe(1)
+        expect(result.attachments?.[0]).not.toHaveProperty("id")
+        expect(result.attachments?.[0]).not.toHaveProperty("sessionID")
+        expect(result.attachments?.[0]).not.toHaveProperty("messageID")
       },
     })
   })
@@ -363,6 +366,9 @@ describe("tool.read truncation", () => {
         expect(result.attachments).toBeDefined()
         expect(result.attachments?.length).toBe(1)
         expect(result.attachments?.[0].type).toBe("file")
+        expect(result.attachments?.[0]).not.toHaveProperty("id")
+        expect(result.attachments?.[0]).not.toHaveProperty("sessionID")
+        expect(result.attachments?.[0]).not.toHaveProperty("messageID")
       },
     })
   })

+ 3 - 0
packages/opencode/test/tool/webfetch.test.ts

@@ -46,6 +46,9 @@ describe("tool.webfetch", () => {
             expect(result.attachments?.[0].type).toBe("file")
             expect(result.attachments?.[0].mime).toBe("image/png")
             expect(result.attachments?.[0].url.startsWith("data:image/png;base64,")).toBe(true)
+            expect(result.attachments?.[0]).not.toHaveProperty("id")
+            expect(result.attachments?.[0]).not.toHaveProperty("sessionID")
+            expect(result.attachments?.[0]).not.toHaveProperty("messageID")
           },
         })
       },