Skip to content

Commit 51e310c

Browse files
zekerekram1-node
andauthored
fix(read): prevent unsupported image formats from being sending to provider (#21114)
Co-authored-by: Aiden Cline <[email protected]>
1 parent 4781564 commit 51e310c

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

packages/opencode/src/tool/read.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import DESCRIPTION from "./read.txt"
1010
import { InstanceState } from "@/effect/instance-state"
1111
import { assertExternalDirectoryEffect } from "./external-directory"
1212
import { Instruction } from "../session/instruction"
13-
import { isImageAttachment, isPdfAttachment, sniffAttachmentMime } from "@/util/media"
13+
import { isPdfAttachment, sniffAttachmentMime } from "@/util/media"
1414

1515
const DEFAULT_READ_LIMIT = 2000
1616
const MAX_LINE_LENGTH = 2000
1717
const MAX_LINE_SUFFIX = `... (line truncated to ${MAX_LINE_LENGTH} chars)`
1818
const MAX_BYTES = 50 * 1024
1919
const MAX_BYTES_LABEL = `${MAX_BYTES / 1024} KB`
2020
const SAMPLE_BYTES = 4096
21+
const SUPPORTED_IMAGE_MIMES = new Set(["image/jpeg", "image/png", "image/gif", "image/webp"])
2122

2223
// `offset` and `limit` were originally `z.coerce.number()` — the runtime
2324
// coercion was useful when the tool was called from a shell but serves no
@@ -220,7 +221,9 @@ export const ReadTool = Tool.define(
220221
const sample = yield* readSample(filepath, Number(stat.size), SAMPLE_BYTES)
221222

222223
const mime = sniffAttachmentMime(sample, AppFileSystem.mimeType(filepath))
223-
if (isImageAttachment(mime) || isPdfAttachment(mime)) {
224+
const isImage = SUPPORTED_IMAGE_MIMES.has(mime)
225+
226+
if (isImage || isPdfAttachment(mime)) {
224227
const bytes = yield* fs.readFile(filepath)
225228
const msg = isPdfAttachment(mime) ? "PDF read successfully" : "Image read successfully"
226229
return {

packages/opencode/test/tool/read.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,24 @@ root_type Monster;`
440440
expect(result.output).toContain("table Monster")
441441
}),
442442
)
443+
444+
it.live("falls through unsupported image mime types to text", () =>
445+
Effect.gen(function* () {
446+
const dir = yield* tmpdirScoped()
447+
const cases = [
448+
["image.bmp", "BM text content"],
449+
["photo.tiff", "II text content"],
450+
["photo.avif", "avif text content"],
451+
] as const
452+
453+
for (const item of cases) {
454+
yield* put(path.join(dir, item[0]), item[1])
455+
const result = yield* exec(dir, { filePath: path.join(dir, item[0]) })
456+
expect(result.attachments).toBeUndefined()
457+
expect(result.output).toContain(item[1])
458+
}
459+
}),
460+
)
443461
})
444462

445463
describe("tool.read loaded instructions", () => {

0 commit comments

Comments
 (0)