mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-14 03:56:55 +03:00
99 lines
4.1 KiB
TypeScript
99 lines
4.1 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import { Base64 } from "effect/encoding"
|
|
import { ai, AIError, Media, Message } from "../src/effect.js"
|
|
import { OpenAI, OpenCode } from "../src/providers.js"
|
|
|
|
const PNG = Uint8Array.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0, 0, 0, 0])
|
|
const PNG_BASE64 = Base64.encode(PNG)
|
|
const UNKNOWN = Uint8Array.from([1, 2, 3])
|
|
|
|
describe("Media.make", () => {
|
|
test("passes assets through", () => {
|
|
const asset = Media.url("https://example.test/a.png")
|
|
expect(Media.make(asset)).toBe(asset)
|
|
})
|
|
|
|
test("sniffs bytes and array buffers", () => {
|
|
expect(Media.make(PNG).source).toEqual({ type: "bytes", data: PNG, mediaType: "image/png" })
|
|
expect(Media.make(PNG.slice().buffer).source).toEqual({ type: "bytes", data: PNG, mediaType: "image/png" })
|
|
expect(Media.make(UNKNOWN, "application/x-thing").mediaType).toBe("application/x-thing")
|
|
})
|
|
|
|
test("reads the media type from data URLs", () => {
|
|
expect(Media.make(`data:image/png;base64,${PNG_BASE64}`).source).toEqual({
|
|
type: "base64",
|
|
data: PNG_BASE64,
|
|
mediaType: "image/png",
|
|
})
|
|
expect(Media.make(new URL(`data:image/webp;base64,${PNG_BASE64}`)).mediaType).toBe("image/webp")
|
|
})
|
|
|
|
test("keeps http(s) and other URLs as url sources", () => {
|
|
expect(Media.make("https://example.test/a.png", "image/png").source).toEqual({
|
|
type: "url",
|
|
url: "https://example.test/a.png",
|
|
mediaType: "image/png",
|
|
})
|
|
expect(Media.make(new URL("gs://bucket/a.pdf")).source).toEqual({ type: "url", url: "gs://bucket/a.pdf" })
|
|
})
|
|
|
|
test("treats other strings as base64", () => {
|
|
expect(Media.make(PNG_BASE64).source).toEqual({ type: "base64", data: PNG_BASE64, mediaType: "image/png" })
|
|
expect(Media.make("AQID", "application/pdf").mediaType).toBe("application/pdf")
|
|
})
|
|
|
|
test("requires a mediaType when the type cannot be detected", () => {
|
|
expect(() => Media.make(UNKNOWN)).toThrow(AIError)
|
|
expect(() => Media.make("AQID")).toThrow(AIError)
|
|
expect(() => Media.make("data:text/plain,hello")).toThrow(AIError)
|
|
})
|
|
|
|
test("rejects strings that are not base64", () => {
|
|
expect(() => Media.make("./photo.png", "image/png")).toThrow("Media.file")
|
|
})
|
|
|
|
test("matches the data URL scheme in any case", () => {
|
|
expect(Media.make(`DATA:image/png;base64,${PNG_BASE64}`).mediaType).toBe("image/png")
|
|
})
|
|
})
|
|
|
|
describe("plain file input", () => {
|
|
test("request media parts accept plain data", () => {
|
|
const request = ai.request({
|
|
model: OpenAI.configure({ apiKey: "test" }).chat("gpt-4o-mini"),
|
|
prompt: [
|
|
{ type: "text", text: "Describe these" },
|
|
{ type: "media", media: PNG, filename: "a.png" },
|
|
{ type: "media", media: "AQID", mediaType: "application/pdf" },
|
|
Message.media(new URL("https://example.test/a.png")),
|
|
],
|
|
})
|
|
const parts = request.messages[0].content
|
|
expect(parts[1]).toEqual({ type: "media", media: Media.bytes(PNG, "image/png"), filename: "a.png" })
|
|
expect(parts[2]).toEqual({ type: "media", media: Media.base64("AQID", "application/pdf") })
|
|
expect(parts[3]).toEqual({ type: "media", media: Media.url("https://example.test/a.png") })
|
|
})
|
|
|
|
test("image edit inputs accept plain data", () => {
|
|
const request = ai.image.request({
|
|
model: OpenAI.configure({ apiKey: "test" }).image("gpt-image-2"),
|
|
prompt: "Make it blue",
|
|
images: [PNG, `data:image/png;base64,${PNG_BASE64}`, "https://example.test/a.png"],
|
|
})
|
|
expect(request.images?.map((image) => image.source.type)).toEqual(["bytes", "base64", "url"])
|
|
expect(request.images?.[0].mediaType).toBe("image/png")
|
|
})
|
|
|
|
test("decision media parts accept plain data", () => {
|
|
const request = ai.decision.request({
|
|
model: OpenCode.configure({ apiKey: "test" }).decision("jev-1.13"),
|
|
input: [
|
|
{ type: "text", text: "Is this a receipt?" },
|
|
{ type: "media", media: "AQID", mediaType: "image/png", filename: "a.png" },
|
|
],
|
|
questions: [{ name: "receipt", type: "predicate", instructions: "Is this a receipt?" }],
|
|
})
|
|
expect(request.input[1]).toEqual({ type: "media", media: Media.base64("AQID", "image/png"), filename: "a.png" })
|
|
})
|
|
})
|