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

This commit is contained in:
Shoubhit Dash 2026-06-23 22:15:00 +05:30 committed by GitHub
parent a3825286cf
commit 8e2d422ffe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 5 deletions

View File

@ -1,6 +1,6 @@
import type { ContentBlock, ContentChunk, ResourceLink, Role } from "@agentclientprotocol/sdk" import type { ContentBlock, ContentChunk, ResourceLink, Role } from "@agentclientprotocol/sdk"
import path from "node:path" import path from "node:path"
import { pathToFileURL } from "node:url" import { fileURLToPath, pathToFileURL } from "node:url"
import { SessionV1 } from "@opencode-ai/core/v1/session" import { SessionV1 } from "@opencode-ai/core/v1/session"
export type PromptPart = SessionV1.TextPartInput | SessionV1.FilePartInput export type PromptPart = SessionV1.TextPartInput | SessionV1.FilePartInput
@ -76,7 +76,19 @@ export function contentBlockToParts(block: ContentBlock): PromptPart[] {
case "resource": case "resource":
if ("text" in block.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) { if (block.resource.mimeType) {
return [ return [

View File

@ -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( expect(
contentBlockToParts({ contentBlockToParts({
type: "resource", type: "resource",
resource: { resource: {
uri: "file:///tmp/context.txt", uri: "file:///tmp/context.txt#L12-L14",
mimeType: "text/plain", mimeType: "text/plain",
text: "context", 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", () => { test("resource with blob and mimeType becomes a data URL file part", () => {