Explorar o código

fix(opencode): decode MCP text blobs

Aiden Cline hai 2 meses
pai
achega
805a004f89

+ 11 - 1
packages/opencode/src/session/prompt.ts

@@ -741,13 +741,23 @@ export const layer = Layer.effect(
                   })
                   })
                 } else if ("blob" in c && c.blob) {
                 } else if ("blob" in c && c.blob) {
                   const mime = ("mimeType" in c ? c.mimeType : undefined) ?? part.mime
                   const mime = ("mimeType" in c ? c.mimeType : undefined) ?? part.mime
+                  const url = `data:${mime};base64,${c.blob}`
+                  if (mime === "text/plain") {
+                    pieces.push({
+                      messageID: info.id,
+                      sessionID: input.sessionID,
+                      type: "text",
+                      synthetic: true,
+                      text: decodeDataUrl(url),
+                    })
+                  }
                   pieces.push({
                   pieces.push({
                     messageID: info.id,
                     messageID: info.id,
                     sessionID: input.sessionID,
                     sessionID: input.sessionID,
                     type: "file",
                     type: "file",
                     mime,
                     mime,
                     filename: part.filename,
                     filename: part.filename,
-                    url: `data:${mime};base64,${c.blob}`,
+                    url,
                   })
                   })
                 }
                 }
               }
               }

+ 30 - 0
packages/opencode/test/session/prompt.test.ts

@@ -258,6 +258,14 @@ const resourceNoLLMServer = testEffect(
                   text: "# MCP resource fixture",
                   text: "# MCP resource fixture",
                 },
                 },
               ]
               ]
+            : uri === "opencode-fixture://text-blob"
+              ? [
+                  {
+                    uri,
+                    mimeType: "text/plain",
+                    blob: Buffer.from("MCP text blob fixture").toString("base64"),
+                  },
+                ]
             : [
             : [
                 {
                 {
                   uri,
                   uri,
@@ -2075,6 +2083,18 @@ resourceNoLLMServer.instance(
               text: { value: "@fixture-guide", start: 0, end: 14 },
               text: { value: "@fixture-guide", start: 0, end: 14 },
             },
             },
           },
           },
+          {
+            type: "file",
+            mime: "text/plain",
+            url: "opencode-fixture://text-blob",
+            filename: "fixture-text-blob",
+            source: {
+              type: "resource",
+              clientName: "resource-only-fixture",
+              uri: "opencode-fixture://text-blob",
+              text: { value: "@fixture-text-blob", start: 15, end: 33 },
+            },
+          },
           {
           {
             type: "file",
             type: "file",
             mime: "image/png",
             mime: "image/png",
@@ -2091,6 +2111,16 @@ resourceNoLLMServer.instance(
       })
       })
 
 
       expect(message.parts.some((part) => part.type === "text" && part.text === "# MCP resource fixture")).toBe(true)
       expect(message.parts.some((part) => part.type === "text" && part.text === "# MCP resource fixture")).toBe(true)
+      expect(message.parts.some((part) => part.type === "text" && part.text === "MCP text blob fixture")).toBe(true)
+      expect(
+        message.parts.some(
+          (part) =>
+            part.type === "file" &&
+            !part.source &&
+            part.mime === "text/plain" &&
+            part.url.startsWith("data:text/plain;base64,"),
+        ),
+      ).toBe(true)
       expect(
       expect(
         message.parts.some(
         message.parts.some(
           (part) => part.type === "file" && part.source?.type === "resource" && part.url === "opencode-fixture://pixel",
           (part) => part.type === "file" && part.source?.type === "resource" && part.url === "opencode-fixture://pixel",