import { spawn } from "node:child_process"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { Readable, Writable } from "node:stream"; import * as acp from "@agentclientprotocol/sdk"; const root = await fs.mkdtemp(path.join(os.tmpdir(), "gori-image-e2e-spike-")); const workspace = path.join(root, "workspace"); await fs.mkdir(workspace, { recursive: true, mode: 0o700 }); const imageB64 = (await fs.readFile("/tmp/test7.b64", "utf8")).trim(); const child = spawn(process.env.KIMI_BIN || "kimi", ["acp"], { cwd: workspace, env: process.env, shell: false, stdio: ["pipe", "pipe", "pipe"] }); let stderr = ""; child.stderr.on("data", (chunk) => { stderr += chunk.toString("utf8"); }); let sessionId; const chunks = []; const app = acp.client({ name: "gori-image-e2e-spike", version: "0.1.0" }) .onNotification(acp.methods.client.session.update, ({ params }) => { if (params.sessionId !== sessionId) return; if (params.update.sessionUpdate === "agent_message_chunk" && params.update.content.type === "text") { chunks.push(params.update.content.text); } }); const stream = acp.ndJsonStream(Writable.toWeb(child.stdin), Readable.toWeb(child.stdout)); const connection = app.connect(stream); try { await connection.agent.request(acp.methods.agent.initialize, { protocolVersion: acp.PROTOCOL_VERSION, clientCapabilities: { fs: { readTextFile: false, writeTextFile: false } }, clientInfo: { name: "gori-image-e2e-spike", version: "0.1.0" } }); const created = await connection.agent.request(acp.methods.agent.session.new, { cwd: workspace, mcpServers: [] }); sessionId = created.sessionId; const result = await connection.agent.request(acp.methods.agent.session.prompt, { sessionId: created.sessionId, prompt: [ { type: "image", data: imageB64, mimeType: "image/png" }, { type: "text", text: "What number is drawn in this image? Answer with just the number." } ] }); console.log("stopReason:", result.stopReason); console.log("reply:", JSON.stringify(chunks.join(""))); } catch (error) { console.error("PROMPT ERROR:", error?.message || error); if (stderr) console.error("STDERR tail:", stderr.slice(-800)); process.exitCode = 1; } finally { child.kill("SIGKILL"); await fs.rm(root, { recursive: true, force: true }); }