119 lines
4.1 KiB
TypeScript
119 lines
4.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { CLAUDE_IDENTITY_PREFIX } from "../auto-reply/claude.js";
|
|
import { OPENCODE_IDENTITY_PREFIX } from "../auto-reply/opencode.js";
|
|
import { claudeSpec } from "./claude.js";
|
|
import { codexSpec } from "./codex.js";
|
|
import { opencodeSpec } from "./opencode.js";
|
|
import { piSpec } from "./pi.js";
|
|
|
|
describe("agent buildArgs + parseOutput helpers", () => {
|
|
it("claudeSpec injects flags and identity once", () => {
|
|
const argv = ["claude", "hi"];
|
|
const built = claudeSpec.buildArgs({
|
|
argv,
|
|
bodyIndex: 1,
|
|
isNewSession: true,
|
|
sessionId: "sess",
|
|
sendSystemOnce: false,
|
|
systemSent: false,
|
|
identityPrefix: undefined,
|
|
format: "json",
|
|
});
|
|
expect(built).toContain("--output-format");
|
|
expect(built).toContain("json");
|
|
expect(built).toContain("-p");
|
|
expect(built.at(-1)).toContain(CLAUDE_IDENTITY_PREFIX);
|
|
|
|
const builtNoIdentity = claudeSpec.buildArgs({
|
|
argv,
|
|
bodyIndex: 1,
|
|
isNewSession: false,
|
|
sessionId: "sess",
|
|
sendSystemOnce: true,
|
|
systemSent: true,
|
|
identityPrefix: undefined,
|
|
format: "json",
|
|
});
|
|
expect(builtNoIdentity.at(-1)).not.toContain(CLAUDE_IDENTITY_PREFIX);
|
|
});
|
|
|
|
it("opencodeSpec adds format flag and identity prefix when needed", () => {
|
|
const argv = ["opencode", "body"];
|
|
const built = opencodeSpec.buildArgs({
|
|
argv,
|
|
bodyIndex: 1,
|
|
isNewSession: true,
|
|
sessionId: "sess",
|
|
sendSystemOnce: false,
|
|
systemSent: false,
|
|
identityPrefix: undefined,
|
|
format: "json",
|
|
});
|
|
expect(built).toContain("--format");
|
|
expect(built).toContain("json");
|
|
expect(built.at(-1)).toContain(OPENCODE_IDENTITY_PREFIX);
|
|
});
|
|
|
|
it("piSpec parses final assistant message and preserves usage meta", () => {
|
|
const stdout = [
|
|
'{"type":"message_start","message":{"role":"assistant"}}',
|
|
'{"type":"message_end","message":{"role":"assistant","content":[{"type":"text","text":"hello world"}],"usage":{"input":10,"output":5},"model":"pi-1","provider":"inflection","stopReason":"end"}}',
|
|
].join("\n");
|
|
const parsed = piSpec.parseOutput(stdout);
|
|
expect(parsed.text).toBe("hello world");
|
|
expect(parsed.meta?.provider).toBe("inflection");
|
|
expect((parsed.meta?.usage as { output?: number })?.output).toBe(5);
|
|
});
|
|
|
|
it("codexSpec parses agent_message and aggregates usage", () => {
|
|
const stdout = [
|
|
'{"type":"item.completed","item":{"type":"agent_message","text":"hi there"}}',
|
|
'{"type":"turn.completed","usage":{"input_tokens":50,"output_tokens":10,"cached_input_tokens":5}}',
|
|
].join("\n");
|
|
const parsed = codexSpec.parseOutput(stdout);
|
|
expect(parsed.text).toBe("hi there");
|
|
const usage = parsed.meta?.usage as {
|
|
input?: number;
|
|
output?: number;
|
|
cacheRead?: number;
|
|
total?: number;
|
|
};
|
|
expect(usage?.input).toBe(50);
|
|
expect(usage?.output).toBe(10);
|
|
expect(usage?.cacheRead).toBe(5);
|
|
expect(usage?.total).toBe(65);
|
|
});
|
|
|
|
it("opencodeSpec parses streamed events and summarizes meta", () => {
|
|
const stdout = [
|
|
'{"type":"step_start","timestamp":0}',
|
|
'{"type":"text","part":{"text":"hi"}}',
|
|
'{"type":"step_finish","timestamp":1200,"part":{"cost":0.002,"tokens":{"input":100,"output":20}}}',
|
|
].join("\n");
|
|
const parsed = opencodeSpec.parseOutput(stdout);
|
|
expect(parsed.text).toBe("hi");
|
|
expect(parsed.meta?.extra?.summary).toContain("duration=1200ms");
|
|
expect(parsed.meta?.extra?.summary).toContain("cost=$0.0020");
|
|
expect(parsed.meta?.extra?.summary).toContain("tokens=100+20");
|
|
});
|
|
|
|
it("codexSpec buildArgs enforces exec/json/sandbox defaults", () => {
|
|
const argv = ["codex", "hello world"];
|
|
const built = codexSpec.buildArgs({
|
|
argv,
|
|
bodyIndex: 1,
|
|
isNewSession: true,
|
|
sessionId: "sess",
|
|
sendSystemOnce: false,
|
|
systemSent: false,
|
|
identityPrefix: undefined,
|
|
format: "json",
|
|
});
|
|
expect(built[1]).toBe("exec");
|
|
expect(built).toContain("--json");
|
|
expect(built).toContain("--skip-git-repo-check");
|
|
expect(built).toContain("read-only");
|
|
});
|
|
});
|