7aa610294c
Proposal semantics: worker results no longer distinguish success/fail; only an explicit finish settles a pending proposal. Pending owner input follows up by resuming the original worker session. Dirty pending blocks start_next globally; clean pending only blocks its owner. QQ adapter now downloads image attachments and passes them as ACP image content blocks; video/file attachments degrade to link text.
36 lines
1.3 KiB
JavaScript
36 lines
1.3 KiB
JavaScript
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-cap-spike-"));
|
|
const workspace = path.join(root, "workspace");
|
|
await fs.mkdir(workspace, { recursive: true, mode: 0o700 });
|
|
|
|
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"); });
|
|
|
|
const app = acp.client({ name: "gori-image-cap-spike", version: "0.1.0" });
|
|
const stream = acp.ndJsonStream(Writable.toWeb(child.stdin), Readable.toWeb(child.stdout));
|
|
const connection = app.connect(stream);
|
|
|
|
try {
|
|
const initialized = await connection.agent.request(acp.methods.agent.initialize, {
|
|
protocolVersion: acp.PROTOCOL_VERSION,
|
|
clientCapabilities: { fs: { readTextFile: false, writeTextFile: false } },
|
|
clientInfo: { name: "gori-image-cap-spike", version: "0.1.0" }
|
|
});
|
|
console.log(JSON.stringify(initialized, null, 2));
|
|
} finally {
|
|
child.kill("SIGKILL");
|
|
await fs.rm(root, { recursive: true, force: true });
|
|
}
|