Skip to content

Commit 0b39f9e

Browse files
committed
fix: Use inline data for local image URIs
Closes #231
1 parent b93225f commit 0b39f9e

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

src/CodexAcpClient.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ function buildPromptItems(prompt: acp.ContentBlock[]): UserInput[] {
703703
case "text":
704704
return {type: "text", text: block.text, text_elements: []};
705705
case "image": {
706-
const url = block.uri ?? `data:${block.mimeType};base64,${block.data}`;
706+
const url = shouldUseImageUri(block.uri) ? block.uri : imageDataUrl(block);
707707
return {type: "image", url};
708708
}
709709
case "resource_link":
@@ -729,6 +729,22 @@ function buildPromptItems(prompt: acp.ContentBlock[]): UserInput[] {
729729
}).filter((block): block is UserInput => block !== null);
730730
}
731731

732+
function imageDataUrl(block: acp.ContentBlock & { type: "image" }): string {
733+
return `data:${block.mimeType};base64,${block.data}`;
734+
}
735+
736+
function shouldUseImageUri(uri: string | null | undefined): uri is string {
737+
if (!uri) {
738+
return false;
739+
}
740+
try {
741+
const protocol = new URL(uri).protocol;
742+
return protocol === "http:" || protocol === "https:";
743+
} catch {
744+
return false;
745+
}
746+
}
747+
732748
function isImageMimeType(mimeType: string | null | undefined): mimeType is string {
733749
return mimeType?.startsWith("image/") ?? false;
734750
}

src/__tests__/CodexACPAgent/CodexAcpClient.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,24 @@ describe('ACP server test', { timeout: 40_000 }, () => {
14121412
}));
14131413
});
14141414

1415+
it ('should use inline image data when image uri is a local file', async () => {
1416+
const { mockFixture, turnStartSpy } = setupPromptFixture({
1417+
supportedInputModalities: ["text", "image"],
1418+
});
1419+
1420+
const prompt: acp.ContentBlock[] = [
1421+
{ type: "image", mimeType: "image/png", data: "abc123", uri: "file:///Users/test/Desktop/Screenshot%201.png" },
1422+
];
1423+
1424+
await mockFixture.getCodexAcpAgent().prompt({ sessionId: "id", prompt });
1425+
1426+
expect(turnStartSpy).toHaveBeenCalledWith(expect.objectContaining({
1427+
input: [
1428+
{ type: "image", url: "data:image/png;base64,abc123" },
1429+
]
1430+
}));
1431+
});
1432+
14151433
it ('should show rate limits from multiple sources in status', async () => {
14161434
const rateLimits: RateLimitsMap = new Map();
14171435
rateLimits.set("limit-1", {

0 commit comments

Comments
 (0)