Explorar el Código

fix(acp): preserve resource text source (#33524)

Shoubhit Dash hace 2 meses
padre
commit
8e2d422ffe
Se han modificado 2 ficheros con 29 adiciones y 5 borrados
  1. 14 2
      packages/opencode/src/acp/content.ts
  2. 15 3
      packages/opencode/test/acp/content.test.ts

+ 14 - 2
packages/opencode/src/acp/content.ts

@@ -1,6 +1,6 @@
 import type { ContentBlock, ContentChunk, ResourceLink, Role } from "@agentclientprotocol/sdk"
 import path from "node:path"
-import { pathToFileURL } from "node:url"
+import { fileURLToPath, pathToFileURL } from "node:url"
 import { SessionV1 } from "@opencode-ai/core/v1/session"
 
 export type PromptPart = SessionV1.TextPartInput | SessionV1.FilePartInput
@@ -76,7 +76,19 @@ export function contentBlockToParts(block: ContentBlock): PromptPart[] {
 
     case "resource":
       if ("text" in block.resource) {
-        return [{ type: "text", text: block.resource.text }]
+        try {
+          const parsed = new URL(block.resource.uri)
+          if (parsed.protocol === "file:") {
+            const line = parsed.hash.match(/^#L(\d+)/)?.[1]
+            return [
+              {
+                type: "text",
+                text: `[${fileURLToPath(parsed)}${line ? `:${line}` : ""}]\n${block.resource.text}`,
+              },
+            ]
+          }
+        } catch {}
+        return [{ type: "text", text: `[${block.resource.uri}]\n${block.resource.text}` }]
       }
       if (block.resource.mimeType) {
         return [

+ 15 - 3
packages/opencode/test/acp/content.test.ts

@@ -99,17 +99,29 @@ describe("acp content conversion", () => {
     ])
   })
 
-  test("resource with text becomes a text part", () => {
+  test("resource with text becomes a sourced text part", () => {
     expect(
       contentBlockToParts({
         type: "resource",
         resource: {
-          uri: "file:///tmp/context.txt",
+          uri: "file:///tmp/context.txt#L12-L14",
           mimeType: "text/plain",
           text: "context",
         },
       }),
-    ).toEqual([{ type: "text", text: "context" }])
+    ).toEqual([{ type: "text", text: "[/tmp/context.txt:12]\ncontext" }])
+  })
+
+  test("resource with text uses URI fallback for non-file resources", () => {
+    expect(
+      contentBlockToParts({
+        type: "resource",
+        resource: {
+          uri: "mcp://server/context",
+          text: "context",
+        },
+      }),
+    ).toEqual([{ type: "text", text: "[mcp://server/context]\ncontext" }])
   })
 
   test("resource with blob and mimeType becomes a data URL file part", () => {