@a-dray/aglib 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -136
- package/dist/harness/adapters/acp/index.d.ts +27 -11
- package/dist/harness/adapters/acp/index.js +58 -24
- package/dist/harness/adapters/acp/index.js.map +1 -1
- package/dist/harness/adapters/native/loop.js +0 -1
- package/dist/harness/adapters/native/loop.js.map +1 -1
- package/dist/harness/harness.d.ts +17 -6
- package/dist/harness/harness.js.map +1 -1
- package/dist/model/adapters/anthropic/index.js +21 -4
- package/dist/model/adapters/anthropic/index.js.map +1 -1
- package/dist/model/index.d.ts +0 -1
- package/dist/model/index.js +1 -1
- package/dist/model/index.js.map +1 -1
- package/dist/model/model.d.ts +8 -1
- package/dist/model/model.js +8 -1
- package/dist/model/model.js.map +1 -1
- package/dist/render.d.ts +100 -0
- package/dist/render.js +370 -0
- package/dist/render.js.map +1 -0
- package/dist/store/adapters/sqlite.js +25 -2
- package/dist/store/adapters/sqlite.js.map +1 -1
- package/dist/terminal.d.ts +23 -0
- package/dist/terminal.js +90 -0
- package/dist/terminal.js.map +1 -0
- package/dist/tools/execute.js +3 -1
- package/dist/tools/execute.js.map +1 -1
- package/dist/tools/tool.d.ts +8 -1
- package/dist/tools/tool.js.map +1 -1
- package/package.json +10 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/harness/adapters/acp/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Harness, HarnessContext, HarnessResult } from \"../../harness.js\";\nimport type { Entry, ToolCall, ToolResult } from \"../../../session/entry.js\";\nimport type { Sandbox, SandboxProcess } from \"../../../sandbox/sandbox.js\";\nimport type { Decide, ToolSpec } from \"../../../tools/tool.js\";\nimport type { JsonValue } from \"../../../json.js\";\nimport { textOf } from \"../../../content.js\";\nimport { err, ok, type Failure } from \"../../../result.js\";\nimport { createRpc, type Rpc } from \"./rpc.js\";\n\n/** An agent process: argv and the environment that selects its provider and model. */\nexport interface AcpAgent {\n command: readonly string[];\n env?: Readonly<Record<string, string>>;\n}\n\n/** A tool server the foreign agent connects to itself. This is how it gets ours. */\nexport interface AcpMcpServer {\n name: string;\n command: string;\n args?: readonly string[];\n env?: readonly { name: string; value: string }[];\n}\n\n/**\n * Something the agent lets a client change about a session.\n *\n * The protocol used to name models specifically; it now publishes a list of\n * options and gives each a category, so a client can tell a model selector\n * from a reasoning level without knowing the agent. We report them rather than\n * interpret them: the ids and the choices are the agent's, and a service that\n * mapped them onto its own three levels would be guessing at another product's\n * vocabulary.\n */\nexport interface AcpConfigOption {\n id: string;\n name: string;\n /** \"model\", \"thought_level\", \"mode\", \"model_config\", or whatever the agent says. */\n category: string;\n description?: string;\n current: string | boolean;\n /** Absent for a boolean option. */\n choices?: readonly { id: string; name: string }[];\n}\n\nexport interface AcpHarnessOptions {\n /** Names this harness in the log and in the UI. */\n id: string;\n agent: AcpAgent;\n /**\n * Where the agent runs. Not merely where its file requests are served: the\n * process itself is started here, because a coding agent runs its own shell\n * and only delegates the calls it chooses to.\n */\n sandbox: Sandbox;\n mcpServers?: readonly AcpMcpServer[];\n /**\n * What to set before prompting, by option id. Applied only where the agent\n * published that option and, for a select, that value — otherwise the run\n * fails naming what it does offer, rather than quietly running something else.\n */\n select?: Readonly<Record<string, string | boolean>>;\n /**\n * Requested model, matched against whichever option the agent categorised as\n * its model selector. A convenience over `select` for the one option every\n * agent has, and it fails the same way.\n */\n model?: string;\n /** What the agent published. The caller persists it so a session can offer the agent's own choices. */\n onConfig?(options: readonly AcpConfigOption[]): void;\n /** Agent-defined mode. Choosing one that asks before acting is what routes its own tools through `decide`. */\n mode?: string;\n /**\n * Applied to the agent's own tools, per call, before they run.\n *\n * The protocol carries a title and the raw arguments for these, but no\n * schema, so `spec.parameters` is `{}` and `spec.description` is the agent's\n * own title for the call. That is what we actually have.\n */\n decide?: Decide;\n /** The agent's previous session id, so this activation continues its context. */\n resume?: string;\n /** Called with the agent's session id, so the caller can persist it for the next activation. */\n onSession?(sessionId: string): void;\n}\n\nconst PROTOCOL_VERSION = 1;\n\n/**\n * Runs a foreign coding agent over the Agent Client Protocol.\n *\n * The adapter is not a remote control. It does three things the raw protocol\n * does not: it normalises whatever the agent did into this package's entries,\n * so one durable log describes a Claude Code turn and a native-loop turn\n * identically; it puts the agent's own tools under the application's decision\n * function, one call at a time; and it hands the agent tool servers of ours, so\n * agents can dispatch and message each other.\n */\nexport function createAcpHarness(options: AcpHarnessOptions): Harness {\n return {\n id: options.id,\n // Its tools are its own. We gate them and we record them; we do not claim\n // to have validated arguments we never had a schema for.\n toolUse: \"harness\",\n // The agent owns its context. Our entries describe what it did, and cannot\n // by themselves put it back mid-turn.\n recovery: \"none\",\n run: (context) => runTurn(options, context),\n };\n}\n\nasync function runTurn(options: AcpHarnessOptions, context: HarnessContext): Promise<HarnessResult> {\n const started = await options.sandbox.spawn({\n command: options.agent.command,\n cwd: options.sandbox.root,\n ...(options.agent.env ? { env: options.agent.env } : {}),\n });\n if (!started.ok) return { status: \"failed\", error: started.error };\n\n const rpc = createRpc(started.value);\n const turn = createTurn(options, context, rpc);\n try {\n return await turn.run();\n } finally {\n rpc.close();\n }\n}\n\n/** Cumulative state for one activation. Discarded with the process that produced it. */\nfunction createTurn(options: AcpHarnessOptions, context: HarnessContext, rpc: Rpc) {\n const sandbox = options.sandbox;\n const terminals = new Map<string, { process: SandboxProcess; output: () => string; exit: Promise<number> }>();\n const calls = new Map<string, { name: string; input: JsonValue; output?: JsonValue; failed?: boolean }>();\n let text = \"\";\n let sessionId = \"\";\n let terminalCount = 0;\n /**\n * Whether an update describes this activation, or the last one.\n *\n * `session/load` replays the whole conversation back as `session/update`\n * notifications — measured against `codex-acp`, which answers a load with the\n * user message and the agent message of every turn before it. Those are the\n * same words this log already committed when they were first said, so\n * treating them as output would append the entire history again on every\n * resumed activation, and prepend it to whatever the new turn actually says.\n * Nothing before the prompt belongs to the run the prompt starts.\n */\n let live = false;\n\n return { run };\n\n async function run(): Promise<HarnessResult> {\n serveFiles();\n serveTerminals();\n servePermission();\n rpc.onNotify(\"session/update\", (params) => { void receive(params); });\n\n const ready = await rpc.request(\"initialize\", {\n protocolVersion: PROTOCOL_VERSION,\n clientCapabilities: { fs: { readTextFile: true, writeTextFile: true }, terminal: true },\n clientInfo: { name: \"aglib\", version: \"0\" },\n });\n if (!ready.ok) return { status: \"failed\", error: ready.error };\n const capabilities = field(ready.value, \"agentCapabilities\");\n\n const opened = await openSession(truthy(field(capabilities, \"loadSession\")));\n if (!opened.ok) return { status: \"failed\", error: opened.error };\n sessionId = opened.value;\n options.onSession?.(sessionId);\n\n const configured = await configure(opened.value, opened.opened ?? undefined);\n if (!configured.ok) return { status: \"failed\", error: configured.error };\n\n const cancel = () => rpc.notify(\"session/cancel\", { sessionId });\n context.signal.addEventListener(\"abort\", cancel, { once: true });\n\n // Anything the agent replayed while opening has already been dispatched:\n // one stdio stream, read in order, so a load's echo is behind us here.\n live = true;\n const answered = await rpc.request(\"session/prompt\", {\n sessionId,\n prompt: [{ type: \"text\", text: inputFor(context) }],\n });\n context.signal.removeEventListener(\"abort\", cancel);\n for (const terminal of terminals.values()) terminal.process.kill();\n\n if (!answered.ok) return { status: \"failed\", error: answered.error };\n await flushText();\n return outcome(String(field(answered.value, \"stopReason\") ?? \"end_turn\"));\n }\n\n async function openSession(canLoad: boolean) {\n const parameters = {\n cwd: sandbox.root,\n mcpServers: (options.mcpServers ?? []).map((server) => ({\n type: \"stdio\", name: server.name, command: server.command,\n args: [...(server.args ?? [])], env: [...(server.env ?? [])],\n })),\n } as unknown as JsonValue;\n\n // The whole answer is carried out, not one field of it: what an agent\n // publishes about a session has changed shape once already.\n if (options.resume && canLoad) {\n const loaded = await rpc.request(\"session/load\", { ...(parameters as object), sessionId: options.resume } as JsonValue);\n if (loaded.ok) return { ...ok(options.resume), opened: loaded.value };\n }\n const created = await rpc.request(\"session/new\", parameters);\n if (!created.ok) return { ...created, opened: null };\n const id = field(created.value, \"sessionId\");\n if (typeof id !== \"string\") {\n return { ...err<Failure>({ code: \"protocol\", message: \"The agent opened no session.\", retryable: false }), opened: null };\n }\n return { ...ok(id), opened: created.value };\n }\n\n /**\n * Read what the agent lets us change, report it, and set what was asked for.\n *\n * Two shapes, because the protocol changed one into the other: `models` used\n * to be its own field on the session, and is now one entry in `configOptions`\n * carrying `category: \"model\"`. Both are read, so an agent on either version\n * is understood, and neither is required.\n *\n * A resumed session reads this from the `session/load` answer, and an agent\n * that answers a load without republishing is one whose options we do not\n * currently know. Setting one from what a previous session said would be\n * asserting a capability this connection never claimed — so a request for an\n * option that is not published fails, naming what is. Measured against\n * `claude-agent-acp`, which does republish on load.\n */\n async function configure(id: string, opened: JsonValue | undefined) {\n const { options: published, legacyModel } = readOptions(opened);\n if (published.length) options.onConfig?.(published);\n\n if (options.mode) {\n const set = await rpc.request(\"session/set_mode\", { sessionId: id, modeId: options.mode });\n if (!set.ok) return set;\n }\n\n const wanted: Record<string, string | boolean> = { ...options.select };\n if (options.model) {\n const selector = published.find((option) => option.category === \"model\");\n if (!selector) {\n return err<Failure>({\n code: \"unsupported\",\n message: `${options.id} publishes no model selector, so '${options.model}' cannot be chosen over the protocol. Point it at a model through its environment instead.`,\n retryable: false,\n });\n }\n wanted[selector.id] = options.model;\n }\n\n for (const [option, value] of Object.entries(wanted)) {\n const published_ = published.find((candidate) => candidate.id === option);\n if (!published_) {\n return err<Failure>({\n code: \"unsupported\",\n message: `${options.id} offers no option '${option}'. It offers: ${published.map((o) => o.id).join(\", \") || \"none\"}.`,\n retryable: false,\n });\n }\n if (published_.current === value) continue;\n if (published_.choices && !published_.choices.some((choice) => choice.id === value)) {\n return err<Failure>({\n code: \"unsupported\",\n message: `${options.id} does not offer '${String(value)}' for ${published_.name}. It offers: ${published_.choices.map((c) => c.id).join(\", \")}.`,\n retryable: false,\n });\n }\n const legacy = published_.id === legacyModel;\n const set = await rpc.request(\n legacy ? \"session/set_model\" : \"session/set_config_option\",\n legacy\n ? { sessionId: id, modelId: value }\n : { sessionId: id, configId: published_.id, value, ...(typeof value === \"boolean\" ? { type: \"boolean\" } : {}) },\n );\n if (!set.ok) return set;\n }\n return ok(undefined);\n }\n\n // ---- Normalising what the agent did into entries -------------------------\n\n /**\n * A tool call becomes entries when it finishes, in one commit: the assistant\n * turn that asked for it, the start, and the result. Committing the pieces as\n * they arrive would leave half-states in a log whose whole purpose is that it\n * can be replayed, and a live viewer is served by `emit` instead.\n */\n async function receive(params: JsonValue): Promise<void> {\n if (!live) return;\n const update = field(params, \"update\");\n const kind = String(field(update, \"sessionUpdate\") ?? \"\");\n\n if (kind === \"agent_message_chunk\") {\n const chunk = String(field(field(update, \"content\"), \"text\") ?? \"\");\n text += chunk;\n context.emit({ type: \"text.delta\", text: chunk });\n return;\n }\n if (kind === \"agent_thought_chunk\") {\n context.emit({ type: \"reasoning.delta\", text: String(field(field(update, \"content\"), \"text\") ?? \"\") });\n return;\n }\n if (kind === \"usage_update\") {\n // Dropped deliberately. This protocol reports a spend figure and no token\n // counts, and `Usage` carries tokens and no money, so there is nothing\n // here that could be recorded without inventing it. An agent behind this\n // harness is unaccounted for, and the capability table says so.\n return;\n }\n if (kind !== \"tool_call\" && kind !== \"tool_call_update\") return;\n\n const callId = String(field(update, \"toolCallId\") ?? \"\");\n if (!callId) return;\n const existing = calls.get(callId) ?? { name: \"\", input: null };\n const name = nameOf(update);\n const raw = field(update, \"rawInput\");\n calls.set(callId, {\n name: name || existing.name || \"tool\",\n input: raw === undefined || raw === null ? existing.input : raw,\n ...(existing.output === undefined ? {} : { output: existing.output }),\n });\n context.emit({ type: \"tool.progress\", callId, data: update ?? null });\n\n const status = String(field(update, \"status\") ?? \"\");\n if (status !== \"completed\" && status !== \"failed\") return;\n\n const call = calls.get(callId)!;\n calls.delete(callId);\n const result = resultOf(update, status === \"failed\");\n await context.commit(assistantAsking(call, callId).concat(\n { type: \"tool.started\", runId: context.runId, callId },\n { type: \"tool.finished\", runId: context.runId, callId, result },\n ));\n }\n\n function assistantAsking(call: { name: string; input: JsonValue }, callId: string): Entry[] {\n const asked: ToolCall = { callId, name: call.name, arguments: JSON.stringify(call.input ?? {}) };\n const said = text;\n text = \"\";\n return [{ type: \"assistant\", runId: context.runId, content: said, calls: [asked] }];\n }\n\n async function flushText(): Promise<void> {\n if (!text) return;\n const said = text;\n text = \"\";\n await context.commit([{ type: \"assistant\", runId: context.runId, content: said }]);\n }\n\n function outcome(stopReason: string): HarnessResult {\n if (stopReason === \"cancelled\") return { status: \"cancelled\" };\n if (stopReason === \"max_tokens\" || stopReason === \"max_turn_requests\") {\n return {\n status: \"failed\",\n error: { code: \"limit\", message: `${options.id} stopped: ${stopReason}.`, retryable: false },\n };\n }\n return { status: \"completed\", output: lastSaid(context) };\n }\n\n // ---- Serving the agent's requests from the sandbox ----------------------\n\n function serveFiles(): void {\n rpc.on(\"fs/read_text_file\", async (params) => {\n const read = await sandbox.readFile({ path: String(field(params, \"path\") ?? \"\") });\n return read.ok ? ok({ content: read.value }) : read;\n });\n rpc.on(\"fs/write_text_file\", async (params) => {\n const written = await sandbox.writeFile({\n path: String(field(params, \"path\") ?? \"\"),\n content: String(field(params, \"content\") ?? \"\"),\n });\n return written.ok ? ok(null) : written;\n });\n }\n\n /**\n * The protocol's terminal, served from the sandbox.\n *\n * Worth knowing before relying on it: an agent uses this only if it chooses\n * to, and the one measured here does not. `@agentclientprotocol/claude-agent-acp`\n * calls exactly four client methods — `fs/read_text_file`,\n * `fs/write_text_file`, `session/request_permission`, `session/update` — and\n * emits a terminal block for display while running the command itself. So\n * these handlers are correct and, for that agent, never reached. Containment\n * comes from starting the agent inside the sandbox, not from serving this.\n */\n function serveTerminals(): void {\n rpc.on(\"terminal/create\", async (params) => {\n const argv = [\"/bin/sh\", \"-lc\", [field(params, \"command\"), ...(asArray(field(params, \"args\")))].filter(Boolean).join(\" \")];\n const cwd = field(params, \"cwd\");\n const spawned = await sandbox.spawn({\n command: argv,\n ...(typeof cwd === \"string\" ? { cwd } : {}),\n });\n if (!spawned.ok) return spawned;\n const id = `terminal-${++terminalCount}`;\n let collected = \"\";\n const drain = async (stream: ReadableStream<Uint8Array>) => {\n const decoder = new TextDecoder();\n for await (const chunk of stream as unknown as AsyncIterable<Uint8Array>) {\n collected += decoder.decode(chunk, { stream: true });\n }\n };\n void drain(spawned.value.stdout);\n void drain(spawned.value.stderr);\n terminals.set(id, { process: spawned.value, output: () => collected, exit: spawned.value.exited });\n return ok({ terminalId: id });\n });\n\n rpc.on(\"terminal/output\", async (params) => {\n const terminal = terminals.get(String(field(params, \"terminalId\") ?? \"\"));\n if (!terminal) return err<Failure>({ code: \"not-found\", message: \"No such terminal.\", retryable: false });\n const finished = await Promise.race([terminal.exit, Promise.resolve(undefined)]);\n return ok({\n output: terminal.output(),\n truncated: false,\n ...(finished === undefined ? {} : { exitStatus: { exitCode: finished, signal: null } }),\n });\n });\n\n rpc.on(\"terminal/wait_for_exit\", async (params) => {\n const terminal = terminals.get(String(field(params, \"terminalId\") ?? \"\"));\n if (!terminal) return err<Failure>({ code: \"not-found\", message: \"No such terminal.\", retryable: false });\n return ok({ exitCode: await terminal.exit, signal: null });\n });\n\n rpc.on(\"terminal/kill\", async (params) => {\n terminals.get(String(field(params, \"terminalId\") ?? \"\"))?.process.kill();\n return ok(null);\n });\n\n rpc.on(\"terminal/release\", async (params) => {\n const id = String(field(params, \"terminalId\") ?? \"\");\n terminals.get(id)?.process.kill();\n terminals.delete(id);\n return ok(null);\n });\n }\n\n /**\n * The agent's own tools, one call at a time, through the application's rule.\n *\n * The agent is blocked on this reply, so the answer is yes or no and nothing\n * else. That constraint is why the permission model has two outcomes rather\n * than three: a rule that could park a call would be honourable in our own\n * loop and unhonourable here, which is the ragged surface the two-outcome\n * shape avoids.\n */\n function servePermission(): void {\n rpc.on(\"session/request_permission\", async (params) => {\n const call = field(params, \"toolCall\");\n const callId = String(field(call, \"toolCallId\") ?? \"\");\n const options_ = asArray(field(params, \"options\"));\n const pick = (...kinds: string[]) => {\n for (const kind of kinds) {\n const found = options_.find((option) => String(field(option, \"kind\") ?? \"\") === kind);\n if (found) return String(field(found, \"optionId\") ?? \"\");\n }\n return undefined;\n };\n const selected = (optionId: string | undefined) =>\n optionId === undefined\n ? ok({ outcome: { outcome: \"cancelled\" } })\n : ok({ outcome: { outcome: \"selected\", optionId } });\n\n if (!options.decide) return selected(pick(\"allow_once\", \"allow_always\"));\n\n const spec: ToolSpec = {\n name: nameOf(call) || \"tool\",\n description: String(field(call, \"title\") ?? \"\"),\n parameters: {},\n };\n const decided = await options.decide({\n tool: spec,\n input: (field(call, \"rawInput\") ?? {}) as JsonValue,\n sessionId: context.sessionId,\n runId: context.runId,\n callId,\n });\n if (decided.action === \"execute\") return selected(pick(\"allow_once\", \"allow_always\"));\n return selected(pick(\"reject_once\", \"reject_always\"));\n });\n }\n}\n\n/**\n * What the agent published, from either shape the protocol has used.\n *\n * `configOptions` is current. `models` is what the same fact was called before\n * it was generalised, and is normalised into an option categorised \"model\" so\n * a caller never has to know which version answered.\n */\nfunction readOptions(\n opened: JsonValue | undefined,\n): { options: readonly AcpConfigOption[]; legacyModel: string | null } {\n const found: AcpConfigOption[] = [];\n\n for (const raw of asArray(field(opened, \"configOptions\"))) {\n const id = field(raw, \"id\");\n if (typeof id !== \"string\") continue;\n const choices = asArray(field(raw, \"options\")).flatMap((choice) => {\n const value = field(choice, \"id\") ?? field(choice, \"value\");\n return typeof value === \"string\"\n ? [{ id: value, name: String(field(choice, \"name\") ?? value) }]\n : [];\n });\n const current = field(raw, \"currentValue\");\n found.push({\n id,\n name: String(field(raw, \"name\") ?? id),\n category: String(field(raw, \"category\") ?? \"\"),\n ...(typeof field(raw, \"description\") === \"string\" ? { description: String(field(raw, \"description\")) } : {}),\n current: typeof current === \"boolean\" ? current : String(current ?? \"\"),\n ...(choices.length ? { choices } : {}),\n });\n }\n\n const models = field(opened, \"models\");\n const available = asArray(field(models, \"availableModels\"));\n if (available.length && !found.some((option) => option.category === \"model\")) {\n found.push({\n id: \"model\",\n name: \"Model\",\n category: \"model\",\n current: String(field(models, \"currentModelId\") ?? \"\"),\n choices: available.flatMap((model) => {\n const id = field(model, \"modelId\");\n return typeof id === \"string\" ? [{ id, name: String(field(model, \"name\") ?? id) }] : [];\n }),\n });\n // An agent that published its models this way answers `session/set_model`\n // and has never heard of `session/set_config_option`. Both shapes carry\n // choices, so the option alone cannot say which method it takes: where it\n // was read is the only thing that distinguishes them.\n return { options: found, legacyModel: \"model\" };\n }\n return { options: found, legacyModel: null };\n}\n\n// ---- Reading the protocol's loosely-typed payloads --------------------------\n\nconst field = (value: JsonValue | undefined, key: string): JsonValue | undefined =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, JsonValue>)[key]\n : undefined;\n\nconst asArray = (value: JsonValue | undefined): JsonValue[] => (Array.isArray(value) ? value : []);\n\nconst truthy = (value: JsonValue | undefined): boolean => value === true;\n\n/** The agent's real tool name when it publishes one, else the protocol's coarse kind. */\nconst nameOf = (update: JsonValue | undefined): string => {\n const meta = field(update, \"_meta\");\n for (const vendor of Object.values((meta ?? {}) as Record<string, JsonValue>)) {\n const named = field(vendor, \"toolName\");\n if (typeof named === \"string\") return named;\n }\n return String(field(update, \"kind\") ?? \"\");\n};\n\nfunction resultOf(update: JsonValue | undefined, failed: boolean): ToolResult {\n const raw = field(update, \"rawOutput\");\n const blocks = asArray(field(update, \"content\"))\n .map((entry) => field(field(entry, \"content\"), \"text\"))\n .filter((value): value is string => typeof value === \"string\");\n const content = blocks.length ? blocks.join(\"\\n\") : typeof raw === \"string\" ? raw : JSON.stringify(raw ?? null);\n return {\n content,\n ...(raw === undefined ? {} : { details: raw }),\n ...(failed ? { isError: true } : {}),\n };\n}\n\n/** This activation's input: the entries `runAgent` committed before calling us. */\nconst inputFor = (context: HarnessContext): string =>\n context.entries()\n .filter((entry) => entry.type === \"run.started\" && entry.runId === context.runId)\n .map((entry) => textOf((entry as Extract<Entry, { type: \"run.started\" }>).input))\n .join(\"\\n\\n\");\n\n/** The agent's final word, read back from the log it was just committed to. */\nfunction lastSaid(context: HarnessContext): string {\n const entries = context.entries();\n for (let index = entries.length - 1; index >= 0; index -= 1) {\n const entry = entries[index]!;\n if (entry.type === \"assistant\" && entry.runId === context.runId) return textOf(entry.content);\n }\n return \"\";\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/harness/adapters/acp/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Harness, HarnessContext, HarnessResult } from \"../../harness.js\";\nimport type { Entry, ToolCall, ToolResult } from \"../../../session/entry.js\";\nimport type { Sandbox, SandboxProcess } from \"../../../sandbox/sandbox.js\";\nimport type { Decide, ToolSpec } from \"../../../tools/tool.js\";\nimport type { JsonValue } from \"../../../json.js\";\nimport { textOf } from \"../../../content.js\";\nimport { err, ok, type Failure, type Result } from \"../../../result.js\";\nimport { createRpc, type Rpc } from \"./rpc.js\";\n\n/** An agent process: argv and the environment that selects its provider and model. */\nexport interface AcpAgent {\n command: readonly string[];\n env?: Readonly<Record<string, string>>;\n}\n\n/** A tool server the foreign agent connects to itself. This is how it gets ours. */\nexport interface AcpMcpServer {\n name: string;\n command: string;\n args?: readonly string[];\n env?: readonly { name: string; value: string }[];\n}\n\n/**\n * Something the agent lets a client change about a session.\n *\n * The protocol used to name models specifically; it now publishes a list of\n * options and gives each a category, so a client can tell a model selector\n * from a reasoning level without knowing the agent. We report them rather than\n * interpret them: the ids and the choices are the agent's, and a service that\n * mapped them onto its own three levels would be guessing at another product's\n * vocabulary.\n */\nexport interface AcpConfigOption {\n id: string;\n name: string;\n /** \"model\", \"thought_level\", \"mode\", \"model_config\", or whatever the agent says. */\n category: string;\n description?: string;\n current: string | boolean;\n /** Absent for a boolean option. */\n choices?: readonly { id: string; name: string }[];\n}\n\nexport interface AcpHarnessOptions {\n /** Names this harness in the log and in the UI. */\n id: string;\n agent: AcpAgent;\n /**\n * Where the agent runs. Not merely where its file requests are served: the\n * process itself is started here, because a coding agent runs its own shell\n * and only delegates the calls it chooses to.\n */\n sandbox: Sandbox;\n mcpServers?: readonly AcpMcpServer[];\n /**\n * What to set before prompting, by option id — the agent's own ids, from\n * `onConfig`. The only configuration door, deliberately: an option this\n * package named would be a guess at another product's vocabulary, and one\n * that goes stale the first time an agent ships an axis nobody thought of.\n *\n * Applied only where the agent published that option and, for a select, that\n * value — otherwise the run fails naming what it does offer, rather than\n * quietly running something else.\n */\n select?: Readonly<Record<string, string | boolean>>;\n /** What the agent published. The caller persists it so a session can offer the agent's own choices. */\n onConfig?(options: readonly AcpConfigOption[]): void;\n /**\n * Applied to the agent's own tools, per call, before they run.\n *\n * The protocol carries a title and the raw arguments for these, but no\n * schema, so `spec.parameters` is `{}` and `spec.description` is the agent's\n * own title for the call. That is what we actually have.\n */\n decide?: Decide;\n /** The agent's previous session id, so this activation continues its context. */\n resume?: string;\n /** Called with the agent's session id, so the caller can persist it for the next activation. */\n onSession?(sessionId: string): void;\n}\n\nconst PROTOCOL_VERSION = 1;\n\n/**\n * The handshake, and what it claims for us.\n *\n * Two callers open a connection — a turn, and `acpOptions` — and an agent\n * decides what to offer from what the client says it can do. A second copy of\n * this is a second answer to the same question, and the two would drift.\n */\nconst initialize = (rpc: Rpc) =>\n rpc.request(\"initialize\", {\n protocolVersion: PROTOCOL_VERSION,\n clientCapabilities: { fs: { readTextFile: true, writeTextFile: true }, terminal: true },\n clientInfo: { name: \"aglib\", version: \"0\" },\n });\n\n/**\n * Runs a foreign coding agent over the Agent Client Protocol.\n *\n * The adapter is not a remote control. It does three things the raw protocol\n * does not: it normalises whatever the agent did into this package's entries,\n * so one durable log describes a Claude Code turn and a native-loop turn\n * identically; it puts the agent's own tools under the application's decision\n * function, one call at a time; and it hands the agent tool servers of ours, so\n * agents can dispatch and message each other.\n */\nexport function createAcpHarness(options: AcpHarnessOptions): Harness {\n return {\n id: options.id,\n // Its tools are its own. We gate them and we record them; we do not claim\n // to have validated arguments we never had a schema for.\n // The agent owns its context. Our entries describe what it did, and cannot\n // by themselves put it back mid-turn.\n recovery: \"none\",\n run: (context) => runTurn(options, context),\n };\n}\n\n/**\n * What an agent offers, before anyone has asked it anything.\n *\n * Over this protocol an agent publishes its options in the answer to\n * `session/new`, so nothing knows what a model, a mode or a reasoning level is\n * called until a session exists — and a session exists on the first prompt.\n * That left a client with a menu it could not draw until after the choice it\n * wanted to offer had already been made.\n *\n * So this opens one and asks. It spawns, initialises, opens a session, reads\n * what came back and closes: a process and a handshake, no prompt, no\n * generation, nothing billed. The session it opened is thrown away — the run\n * opens its own, exactly as it did before.\n */\nexport async function acpOptions(input: {\n agent: AcpAgent;\n sandbox: Sandbox;\n}): Promise<Result<readonly AcpConfigOption[], Failure>> {\n const started = await input.sandbox.spawn({\n command: input.agent.command,\n cwd: input.sandbox.root,\n ...(input.agent.env ? { env: input.agent.env } : {}),\n });\n if (!started.ok) return err(started.error);\n\n const rpc = createRpc(started.value);\n try {\n const ready = await initialize(rpc);\n if (!ready.ok) return err(ready.error);\n\n const opened = await rpc.request(\"session/new\", { cwd: input.sandbox.root, mcpServers: [] } as unknown as JsonValue);\n if (!opened.ok) return err(opened.error);\n return ok(readOptions(opened.value).options);\n } finally {\n rpc.close();\n }\n}\n\nasync function runTurn(options: AcpHarnessOptions, context: HarnessContext): Promise<HarnessResult> {\n const started = await options.sandbox.spawn({\n command: options.agent.command,\n cwd: options.sandbox.root,\n ...(options.agent.env ? { env: options.agent.env } : {}),\n });\n if (!started.ok) return { status: \"failed\", error: started.error };\n\n const rpc = createRpc(started.value);\n const turn = createTurn(options, context, rpc);\n try {\n return await turn.run();\n } finally {\n rpc.close();\n }\n}\n\n/** Cumulative state for one activation. Discarded with the process that produced it. */\nfunction createTurn(options: AcpHarnessOptions, context: HarnessContext, rpc: Rpc) {\n const sandbox = options.sandbox;\n const terminals = new Map<string, { process: SandboxProcess; output: () => string; exit: Promise<number> }>();\n const calls = new Map<string, { name: string; input: JsonValue; output?: JsonValue; failed?: boolean }>();\n let text = \"\";\n let sessionId = \"\";\n let terminalCount = 0;\n /**\n * Whether an update describes this activation, or the last one.\n *\n * `session/load` replays the whole conversation back as `session/update`\n * notifications — measured against `codex-acp`, which answers a load with the\n * user message and the agent message of every turn before it. Those are the\n * same words this log already committed when they were first said, so\n * treating them as output would append the entire history again on every\n * resumed activation, and prepend it to whatever the new turn actually says.\n * Nothing before the prompt belongs to the run the prompt starts.\n */\n let live = false;\n\n return { run };\n\n async function run(): Promise<HarnessResult> {\n serveFiles();\n serveTerminals();\n servePermission();\n rpc.onNotify(\"session/update\", (params) => { void receive(params); });\n\n const ready = await initialize(rpc);\n if (!ready.ok) return { status: \"failed\", error: ready.error };\n const capabilities = field(ready.value, \"agentCapabilities\");\n\n const opened = await openSession(truthy(field(capabilities, \"loadSession\")));\n if (!opened.ok) return { status: \"failed\", error: opened.error };\n sessionId = opened.value;\n options.onSession?.(sessionId);\n\n const configured = await configure(opened.value, opened.opened ?? undefined);\n if (!configured.ok) return { status: \"failed\", error: configured.error };\n\n const cancel = () => rpc.notify(\"session/cancel\", { sessionId });\n context.signal.addEventListener(\"abort\", cancel, { once: true });\n\n // Anything the agent replayed while opening has already been dispatched:\n // one stdio stream, read in order, so a load's echo is behind us here.\n live = true;\n const answered = await rpc.request(\"session/prompt\", {\n sessionId,\n prompt: [{ type: \"text\", text: inputFor(context) }],\n });\n context.signal.removeEventListener(\"abort\", cancel);\n for (const terminal of terminals.values()) terminal.process.kill();\n\n if (!answered.ok) return { status: \"failed\", error: answered.error };\n await flushText();\n return outcome(String(field(answered.value, \"stopReason\") ?? \"end_turn\"));\n }\n\n async function openSession(canLoad: boolean) {\n const parameters = {\n cwd: sandbox.root,\n mcpServers: (options.mcpServers ?? []).map((server) => ({\n type: \"stdio\", name: server.name, command: server.command,\n args: [...(server.args ?? [])], env: [...(server.env ?? [])],\n })),\n } as unknown as JsonValue;\n\n // The whole answer is carried out, not one field of it: what an agent\n // publishes about a session has changed shape once already.\n if (options.resume && canLoad) {\n const loaded = await rpc.request(\"session/load\", { ...(parameters as object), sessionId: options.resume } as JsonValue);\n if (loaded.ok) return { ...ok(options.resume), opened: loaded.value };\n }\n const created = await rpc.request(\"session/new\", parameters);\n if (!created.ok) return { ...created, opened: null };\n const id = field(created.value, \"sessionId\");\n if (typeof id !== \"string\") {\n return { ...err<Failure>({ code: \"protocol\", message: \"The agent opened no session.\", retryable: false }), opened: null };\n }\n return { ...ok(id), opened: created.value };\n }\n\n /**\n * Read what the agent lets us change, report it, and set what was asked for.\n *\n * Two shapes, because the protocol changed one into the other: `models` used\n * to be its own field on the session, and is now one entry in `configOptions`\n * carrying `category: \"model\"`. Both are read, so an agent on either version\n * is understood, and neither is required.\n *\n * A resumed session reads this from the `session/load` answer, and an agent\n * that answers a load without republishing is one whose options we do not\n * currently know. Setting one from what a previous session said would be\n * asserting a capability this connection never claimed — so a request for an\n * option that is not published fails, naming what is. Measured against\n * `claude-agent-acp`, which does republish on load.\n */\n async function configure(id: string, opened: JsonValue | undefined) {\n const { options: published, legacyModel } = readOptions(opened);\n if (published.length) options.onConfig?.(published);\n\n // One door, and `select` is it. There were two more — `mode`, which sent\n // `session/set_mode`, and `model`, which found whichever option the agent\n // had categorised as its selector. Both were conveniences naming an axis,\n // and naming an axis is guessing at a vocabulary that is not ours: the\n // agents measured here publish five categories between them, and no\n // shorthand was ever going to cover the next one. `session/set_config_option`\n // with `configId: \"mode\"` was checked against `claude-agent-acp` and does\n // what `session/set_mode` did, answering with the new state as well.\n for (const [option, value] of Object.entries(options.select ?? {})) {\n const published_ = published.find((candidate) => candidate.id === option);\n if (!published_) {\n return err<Failure>({\n code: \"unsupported\",\n message: `${options.id} offers no option '${option}'. It offers: ${published.map((o) => o.id).join(\", \") || \"none\"}.`,\n retryable: false,\n });\n }\n if (published_.current === value) continue;\n if (published_.choices && !published_.choices.some((choice) => choice.id === value)) {\n return err<Failure>({\n code: \"unsupported\",\n message: `${options.id} does not offer '${String(value)}' for ${published_.name}. It offers: ${published_.choices.map((c) => c.id).join(\", \")}.`,\n retryable: false,\n });\n }\n const legacy = published_.id === legacyModel;\n const set = await rpc.request(\n legacy ? \"session/set_model\" : \"session/set_config_option\",\n legacy\n ? { sessionId: id, modelId: value }\n : { sessionId: id, configId: published_.id, value, ...(typeof value === \"boolean\" ? { type: \"boolean\" } : {}) },\n );\n if (!set.ok) return set;\n }\n return ok(undefined);\n }\n\n // ---- Normalising what the agent did into entries -------------------------\n\n /**\n * A tool call becomes entries when it finishes, in one commit: the assistant\n * turn that asked for it, the start, and the result. Committing the pieces as\n * they arrive would leave half-states in a log whose whole purpose is that it\n * can be replayed, and a live viewer is served by `emit` instead.\n */\n async function receive(params: JsonValue): Promise<void> {\n if (!live) return;\n const update = field(params, \"update\");\n const kind = String(field(update, \"sessionUpdate\") ?? \"\");\n\n if (kind === \"agent_message_chunk\") {\n const chunk = String(field(field(update, \"content\"), \"text\") ?? \"\");\n text += chunk;\n context.emit({ type: \"text.delta\", text: chunk });\n return;\n }\n if (kind === \"agent_thought_chunk\") {\n context.emit({ type: \"reasoning.delta\", text: String(field(field(update, \"content\"), \"text\") ?? \"\") });\n return;\n }\n if (kind === \"usage_update\") {\n // Dropped deliberately. This protocol reports a spend figure and no token\n // counts, and `Usage` carries tokens and no money, so there is nothing\n // here that could be recorded without inventing it. An agent behind this\n // harness is unaccounted for, and the capability table says so.\n return;\n }\n if (kind !== \"tool_call\" && kind !== \"tool_call_update\") return;\n\n const callId = String(field(update, \"toolCallId\") ?? \"\");\n if (!callId) return;\n const existing = calls.get(callId) ?? { name: \"\", input: null };\n const name = nameOf(update);\n const raw = field(update, \"rawInput\");\n calls.set(callId, {\n name: name || existing.name || \"tool\",\n input: raw === undefined || raw === null ? existing.input : raw,\n ...(existing.output === undefined ? {} : { output: existing.output }),\n });\n context.emit({ type: \"tool.progress\", callId, data: update ?? null });\n\n const status = String(field(update, \"status\") ?? \"\");\n if (status !== \"completed\" && status !== \"failed\") return;\n\n const call = calls.get(callId)!;\n calls.delete(callId);\n const result = resultOf(update, status === \"failed\");\n await context.commit(assistantAsking(call, callId).concat(\n { type: \"tool.started\", runId: context.runId, callId },\n { type: \"tool.finished\", runId: context.runId, callId, result },\n ));\n }\n\n function assistantAsking(call: { name: string; input: JsonValue }, callId: string): Entry[] {\n const asked: ToolCall = { callId, name: call.name, arguments: JSON.stringify(call.input ?? {}) };\n const said = text;\n text = \"\";\n return [{ type: \"assistant\", runId: context.runId, content: said, calls: [asked] }];\n }\n\n async function flushText(): Promise<void> {\n if (!text) return;\n const said = text;\n text = \"\";\n await context.commit([{ type: \"assistant\", runId: context.runId, content: said }]);\n }\n\n function outcome(stopReason: string): HarnessResult {\n if (stopReason === \"cancelled\") return { status: \"cancelled\" };\n if (stopReason === \"max_tokens\" || stopReason === \"max_turn_requests\") {\n return {\n status: \"failed\",\n error: { code: \"limit\", message: `${options.id} stopped: ${stopReason}.`, retryable: false },\n };\n }\n return { status: \"completed\", output: lastSaid(context) };\n }\n\n // ---- Serving the agent's requests from the sandbox ----------------------\n\n function serveFiles(): void {\n rpc.on(\"fs/read_text_file\", async (params) => {\n const read = await sandbox.readFile({ path: String(field(params, \"path\") ?? \"\") });\n return read.ok ? ok({ content: read.value }) : read;\n });\n rpc.on(\"fs/write_text_file\", async (params) => {\n const written = await sandbox.writeFile({\n path: String(field(params, \"path\") ?? \"\"),\n content: String(field(params, \"content\") ?? \"\"),\n });\n return written.ok ? ok(null) : written;\n });\n }\n\n /**\n * The protocol's terminal, served from the sandbox.\n *\n * Worth knowing before relying on it: an agent uses this only if it chooses\n * to, and the one measured here does not. `@agentclientprotocol/claude-agent-acp`\n * calls exactly four client methods — `fs/read_text_file`,\n * `fs/write_text_file`, `session/request_permission`, `session/update` — and\n * emits a terminal block for display while running the command itself. So\n * these handlers are correct and, for that agent, never reached. Containment\n * comes from starting the agent inside the sandbox, not from serving this.\n */\n function serveTerminals(): void {\n rpc.on(\"terminal/create\", async (params) => {\n const argv = [\"/bin/sh\", \"-lc\", [field(params, \"command\"), ...(asArray(field(params, \"args\")))].filter(Boolean).join(\" \")];\n const cwd = field(params, \"cwd\");\n const spawned = await sandbox.spawn({\n command: argv,\n ...(typeof cwd === \"string\" ? { cwd } : {}),\n });\n if (!spawned.ok) return spawned;\n const id = `terminal-${++terminalCount}`;\n let collected = \"\";\n const drain = async (stream: ReadableStream<Uint8Array>) => {\n const decoder = new TextDecoder();\n for await (const chunk of stream as unknown as AsyncIterable<Uint8Array>) {\n collected += decoder.decode(chunk, { stream: true });\n }\n };\n void drain(spawned.value.stdout);\n void drain(spawned.value.stderr);\n terminals.set(id, { process: spawned.value, output: () => collected, exit: spawned.value.exited });\n return ok({ terminalId: id });\n });\n\n rpc.on(\"terminal/output\", async (params) => {\n const terminal = terminals.get(String(field(params, \"terminalId\") ?? \"\"));\n if (!terminal) return err<Failure>({ code: \"not-found\", message: \"No such terminal.\", retryable: false });\n const finished = await Promise.race([terminal.exit, Promise.resolve(undefined)]);\n return ok({\n output: terminal.output(),\n truncated: false,\n ...(finished === undefined ? {} : { exitStatus: { exitCode: finished, signal: null } }),\n });\n });\n\n rpc.on(\"terminal/wait_for_exit\", async (params) => {\n const terminal = terminals.get(String(field(params, \"terminalId\") ?? \"\"));\n if (!terminal) return err<Failure>({ code: \"not-found\", message: \"No such terminal.\", retryable: false });\n return ok({ exitCode: await terminal.exit, signal: null });\n });\n\n rpc.on(\"terminal/kill\", async (params) => {\n terminals.get(String(field(params, \"terminalId\") ?? \"\"))?.process.kill();\n return ok(null);\n });\n\n rpc.on(\"terminal/release\", async (params) => {\n const id = String(field(params, \"terminalId\") ?? \"\");\n terminals.get(id)?.process.kill();\n terminals.delete(id);\n return ok(null);\n });\n }\n\n /**\n * The agent's own tools, one call at a time, through the application's rule.\n *\n * The agent is blocked on this reply, so the answer is yes or no and nothing\n * else. That constraint is why the permission model has two outcomes rather\n * than three: a rule that could park a call would be honourable in our own\n * loop and unhonourable here, which is the ragged surface the two-outcome\n * shape avoids.\n */\n function servePermission(): void {\n rpc.on(\"session/request_permission\", async (params) => {\n const call = field(params, \"toolCall\");\n const callId = String(field(call, \"toolCallId\") ?? \"\");\n const options_ = asArray(field(params, \"options\"));\n const pick = (...kinds: string[]) => {\n for (const kind of kinds) {\n const found = options_.find((option) => String(field(option, \"kind\") ?? \"\") === kind);\n if (found) return String(field(found, \"optionId\") ?? \"\");\n }\n return undefined;\n };\n const selected = (optionId: string | undefined) =>\n optionId === undefined\n ? ok({ outcome: { outcome: \"cancelled\" } })\n : ok({ outcome: { outcome: \"selected\", optionId } });\n\n if (!options.decide) return selected(pick(\"allow_once\", \"allow_always\"));\n\n const spec: ToolSpec = {\n name: nameOf(call) || \"tool\",\n description: String(field(call, \"title\") ?? \"\"),\n parameters: {},\n };\n const decided = await options.decide({\n tool: spec,\n input: (field(call, \"rawInput\") ?? {}) as JsonValue,\n sessionId: context.sessionId,\n runId: context.runId,\n callId,\n });\n if (decided.action === \"execute\") return selected(pick(\"allow_once\", \"allow_always\"));\n return selected(pick(\"reject_once\", \"reject_always\"));\n });\n }\n}\n\n/**\n * What the agent published, from either shape the protocol has used.\n *\n * `configOptions` is current. `models` is what the same fact was called before\n * it was generalised, and is normalised into an option categorised \"model\" so\n * a caller never has to know which version answered.\n */\nfunction readOptions(\n opened: JsonValue | undefined,\n): { options: readonly AcpConfigOption[]; legacyModel: string | null } {\n const found: AcpConfigOption[] = [];\n\n for (const raw of asArray(field(opened, \"configOptions\"))) {\n const id = field(raw, \"id\");\n if (typeof id !== \"string\") continue;\n const choices = asArray(field(raw, \"options\")).flatMap((choice) => {\n const value = field(choice, \"id\") ?? field(choice, \"value\");\n return typeof value === \"string\"\n ? [{ id: value, name: String(field(choice, \"name\") ?? value) }]\n : [];\n });\n const current = field(raw, \"currentValue\");\n found.push({\n id,\n name: String(field(raw, \"name\") ?? id),\n category: String(field(raw, \"category\") ?? \"\"),\n ...(typeof field(raw, \"description\") === \"string\" ? { description: String(field(raw, \"description\")) } : {}),\n current: typeof current === \"boolean\" ? current : String(current ?? \"\"),\n ...(choices.length ? { choices } : {}),\n });\n }\n\n const models = field(opened, \"models\");\n const available = asArray(field(models, \"availableModels\"));\n if (available.length && !found.some((option) => option.category === \"model\")) {\n found.push({\n id: \"model\",\n name: \"Model\",\n category: \"model\",\n current: String(field(models, \"currentModelId\") ?? \"\"),\n choices: available.flatMap((model) => {\n const id = field(model, \"modelId\");\n return typeof id === \"string\" ? [{ id, name: String(field(model, \"name\") ?? id) }] : [];\n }),\n });\n // An agent that published its models this way answers `session/set_model`\n // and has never heard of `session/set_config_option`. Both shapes carry\n // choices, so the option alone cannot say which method it takes: where it\n // was read is the only thing that distinguishes them.\n return { options: found, legacyModel: \"model\" };\n }\n return { options: found, legacyModel: null };\n}\n\n// ---- Reading the protocol's loosely-typed payloads --------------------------\n\nconst field = (value: JsonValue | undefined, key: string): JsonValue | undefined =>\n value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, JsonValue>)[key]\n : undefined;\n\nconst asArray = (value: JsonValue | undefined): JsonValue[] => (Array.isArray(value) ? value : []);\n\nconst truthy = (value: JsonValue | undefined): boolean => value === true;\n\n/** The agent's real tool name when it publishes one, else the protocol's coarse kind. */\nconst nameOf = (update: JsonValue | undefined): string => {\n const meta = field(update, \"_meta\");\n for (const vendor of Object.values((meta ?? {}) as Record<string, JsonValue>)) {\n const named = field(vendor, \"toolName\");\n if (typeof named === \"string\") return named;\n }\n return String(field(update, \"kind\") ?? \"\");\n};\n\nfunction resultOf(update: JsonValue | undefined, failed: boolean): ToolResult {\n const raw = field(update, \"rawOutput\");\n const blocks = asArray(field(update, \"content\"))\n .map((entry) => field(field(entry, \"content\"), \"text\"))\n .filter((value): value is string => typeof value === \"string\");\n const content = blocks.length ? blocks.join(\"\\n\") : typeof raw === \"string\" ? raw : JSON.stringify(raw ?? null);\n return {\n content,\n ...(raw === undefined ? {} : { details: raw }),\n ...(failed ? { isError: true } : {}),\n };\n}\n\n/** This activation's input: the entries `runAgent` committed before calling us. */\nconst inputFor = (context: HarnessContext): string =>\n context.entries()\n .filter((entry) => entry.type === \"run.started\" && entry.runId === context.runId)\n .map((entry) => textOf((entry as Extract<Entry, { type: \"run.started\" }>).input))\n .join(\"\\n\\n\");\n\n/** The agent's final word, read back from the log it was just committed to. */\nfunction lastSaid(context: HarnessContext): string {\n const entries = context.entries();\n for (let index = entries.length - 1; index >= 0; index -= 1) {\n const entry = entries[index]!;\n if (entry.type === \"assistant\" && entry.runId === context.runId) return textOf(entry.content);\n }\n return \"\";\n}\n\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../../src/harness/adapters/native/loop.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Harness, HarnessContext, HarnessResult } from \"../../harness.js\";\nimport type { Entry } from \"../../../session/entry.js\";\nimport type { Message, Model } from \"../../../model/model.js\";\nimport { foldedThrough, toMessages } from \"../../../session/messages.js\";\nimport { compactionCut, estimateTokens, summarize } from \"./compaction.js\";\n\nexport interface NativeHarnessOptions {\n model: Model;\n /** Fold older turns into a summary once a request passes this size. */\n compaction?: {\n maxInputTokens: number;\n /** Defaults to the main model. A cheaper one is usually the right call. */\n model?: Model;\n prompt?: (messages: readonly Message[]) => string;\n };\n maxOutputTokens?: number;\n temperature?: number;\n /** How hard the model should think, where the provider supports it. */\n effort?: \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n}\n\n/**\n * Ask the model, run what it asks for, repeat.\n *\n * The loop holds no transcript. Every turn it re-reads `context.history()`,\n * which projects the committed log, and every result it produces goes back\n * through `context.commit` before the next turn is built. There is exactly one\n * representation of the conversation and it is the log.\n */\nexport function createNativeHarness(options: NativeHarnessOptions): Harness {\n return {\n id: \"native\",\n toolUse: \"application\",\n recovery: \"history\",\n\n async run(context: HarnessContext): Promise<HarnessResult> {\n const { runId } = context;\n let compacting = true;\n\n for (;;) {\n if (context.signal.aborted) return { status: \"cancelled\" };\n\n let history = context.history();\n\n if (compacting && options.compaction && estimateTokens(history) > options.compaction.maxInputTokens) {\n const entries = context.entries();\n const folded = foldedThrough(entries);\n const cut = compactionCut(entries);\n\n // Only ever fold forward. A cut at or behind the last summary removes\n // nothing, so committing one would buy a model call and another entry\n // and leave the request exactly as large — every turn, without end.\n if (cut !== undefined && cut > folded) {\n const summary = await summarize({\n model: options.compaction.model ?? options.model,\n // Exactly the span being replaced. Summarizing the whole history\n // put everything after the cut into the summary as well, so it\n // stayed in the request twice: once verbatim, once paraphrased.\n messages: toMessages({\n instructions: context.instructions,\n entries: entries.filter((entry) => entry.seq <= cut),\n }),\n ...(options.compaction.prompt ? { prompt: options.compaction.prompt } : {}),\n signal: context.signal,\n });\n if (!summary) {\n // Paid for and produced nothing. Attempted once per activation\n // rather than once per turn: retrying bought another model call\n // and another failure every turn, and the request stayed exactly\n // as large either way.\n compacting = false;\n }\n if (summary) {\n // The folded entries stay in the log. Compaction changes what the\n // model is shown on the next turn, never what happened.\n await context.commit([{ type: \"summary\", runId, content: summary, replaces: cut }]);\n history = context.history();\n }\n }\n }\n\n // One cache mark, at the end of the system prefix: instructions plus\n // run-scoped context, which are fixed for the life of the run.\n const cacheAfter = history.findIndex((message) => message.role !== \"system\");\n\n const startedAt = new Date().toISOString();\n const generation = options.model.generate({\n messages: history,\n ...(context.tools ? { tools: context.tools.list() } : {}),\n ...(options.maxOutputTokens !== undefined ? { maxOutputTokens: options.maxOutputTokens } : {}),\n ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),\n ...(options.effort ? { effort: options.effort } : {}),\n ...(cacheAfter > 0 ? { cacheAfter } : {}),\n signal: context.signal,\n });\n\n let step = await generation.next();\n while (!step.done) {\n const delta = step.value;\n if (delta.type === \"text.delta\") context.emit({ type: \"text.delta\", text: delta.text });\n if (delta.type === \"reasoning.delta\") context.emit({ type: \"reasoning.delta\", text: delta.text });\n if (delta.type === \"tool-call.delta\") {\n context.emit({ type: \"tool-call.delta\", callId: delta.callId, arguments: delta.arguments });\n }\n step = await generation.next();\n }\n if (!step.value.ok) {\n return step.value.error.code === \"cancelled\"\n ? { status: \"cancelled\" }\n : { status: \"failed\", error: step.value.error };\n }\n\n const endedAt = new Date().toISOString();\n const response = step.value.value;\n const calls = response.message.calls ?? [];\n\n await context.commit([{\n type: \"assistant\", runId, content: response.message.content,\n ...(calls.length ? { calls } : {}),\n usage: response.usage,\n generation: { ...(response.model ? { model: response.model } : {}), startedAt, endedAt },\n }]);\n\n if (!calls.length) {\n // The reason the model stopped decides the outcome, and it decides it\n // before the absence of tool calls does. A turn cut off by the output\n // ceiling or declined by a safety classifier is not an answer, and\n // reporting either as `completed` hands the caller a truncated or\n // refused response dressed as a finished one.\n if (response.finishReason === \"length\") {\n return { status: \"failed\", error: {\n code: \"output-truncated\",\n message: \"The response stopped at the output limit before it was finished.\",\n retryable: false,\n } };\n }\n if (response.finishReason === \"refusal\") {\n return { status: \"failed\", error: {\n code: \"refused\",\n message: \"The provider declined to answer.\",\n retryable: false,\n } };\n }\n return { status: \"completed\", output: response.message.content };\n }\n\n if (response.finishReason === \"length\") {\n // A truncated response can carry half-parsed arguments that happen to\n // be valid JSON. None of the batch runs; the model is told why and\n // can reissue.\n await context.commit(calls.map((call): Entry => ({\n type: \"tool.finished\", runId, callId: call.callId,\n result: { content: \"Not executed: the response was truncated. Reissue the call if it is still needed.\", isError: true },\n })));\n continue;\n }\n\n if (!context.tools) {\n await context.commit(calls.map((call): Entry => ({\n type: \"tool.finished\", runId, callId: call.callId,\n result: { content: `No tool named '${call.name}' is available.`, isError: true },\n })));\n continue;\n }\n\n // Recorded before anything runs. On restart an unmatched `tool.started`\n // is how we know the process died mid-effect — and why nothing is\n // re-executed automatically.\n await context.commit(calls.map((call): Entry => ({ type: \"tool.started\", runId, callId: call.callId })));\n\n const outcome = await context.tools.execute({ calls, signal: context.signal });\n await context.commit(outcome.results.map(({ callId, result }): Entry => ({\n type: \"tool.finished\", runId, callId, result,\n })));\n\n // Nothing is half-done here: every call asked for has been answered and\n // committed. Anything waiting is folded in before the next request is\n // built, so a message delivered to a busy session is read without the\n // activation having to be ended and its work thrown away.\n await context.drain?.();\n }\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../../src/harness/adapters/native/loop.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAiB3E;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,QAAQ,EAAE,SAAS;QAEnB,KAAK,CAAC,GAAG,CAAC,OAAuB;YAC/B,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;YAC1B,IAAI,UAAU,GAAG,IAAI,CAAC;YAEtB,SAAS,CAAC;gBACR,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;gBAE3D,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;gBAEhC,IAAI,UAAU,IAAI,OAAO,CAAC,UAAU,IAAI,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;oBACpG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;oBACtC,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;oBAEnC,sEAAsE;oBACtE,sEAAsE;oBACtE,oEAAoE;oBACpE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,EAAE,CAAC;wBACtC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC;4BAC9B,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK;4BAChD,iEAAiE;4BACjE,+DAA+D;4BAC/D,gEAAgE;4BAChE,QAAQ,EAAE,UAAU,CAAC;gCACnB,YAAY,EAAE,OAAO,CAAC,YAAY;gCAClC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC;6BACrD,CAAC;4BACF,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC3E,MAAM,EAAE,OAAO,CAAC,MAAM;yBACvB,CAAC,CAAC;wBACH,IAAI,CAAC,OAAO,EAAE,CAAC;4BACb,+DAA+D;4BAC/D,gEAAgE;4BAChE,iEAAiE;4BACjE,uBAAuB;4BACvB,UAAU,GAAG,KAAK,CAAC;wBACrB,CAAC;wBACD,IAAI,OAAO,EAAE,CAAC;4BACZ,kEAAkE;4BAClE,wDAAwD;4BACxD,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;4BACpF,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;wBAC9B,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,qEAAqE;gBACrE,+DAA+D;gBAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;gBAE7E,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;oBACxC,QAAQ,EAAE,OAAO;oBACjB,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzD,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC9F,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClF,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrD,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzC,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC,CAAC;gBAEH,IAAI,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;oBACzB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;wBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;oBACxF,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;wBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;oBAClG,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;wBACrC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;oBAC9F,CAAC;oBACD,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;gBACjC,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;oBACnB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW;wBAC1C,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE;wBACzB,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACpD,CAAC;gBAED,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;gBAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;gBAE3C,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;wBACpB,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO;wBAC3D,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAClC,KAAK,EAAE,QAAQ,CAAC,KAAK;wBACrB,UAAU,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;qBACzF,CAAC,CAAC,CAAC;gBAEJ,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBAClB,sEAAsE;oBACtE,sEAAsE;oBACtE,mEAAmE;oBACnE,kEAAkE;oBAClE,8CAA8C;oBAC9C,IAAI,QAAQ,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;wBACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;gCAChC,IAAI,EAAE,kBAAkB;gCACxB,OAAO,EAAE,kEAAkE;gCAC3E,SAAS,EAAE,KAAK;6BACjB,EAAE,CAAC;oBACN,CAAC;oBACD,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;wBACxC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;gCAChC,IAAI,EAAE,SAAS;gCACf,OAAO,EAAE,kCAAkC;gCAC3C,SAAS,EAAE,KAAK;6BACjB,EAAE,CAAC;oBACN,CAAC;oBACD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACnE,CAAC;gBAED,IAAI,QAAQ,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;oBACvC,sEAAsE;oBACtE,mEAAmE;oBACnE,eAAe;oBACf,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAS,EAAE,CAAC,CAAC;wBAC/C,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM;wBACjD,MAAM,EAAE,EAAE,OAAO,EAAE,mFAAmF,EAAE,OAAO,EAAE,IAAI,EAAE;qBACxH,CAAC,CAAC,CAAC,CAAC;oBACL,SAAS;gBACX,CAAC;gBAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBACnB,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAS,EAAE,CAAC,CAAC;wBAC/C,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM;wBACjD,MAAM,EAAE,EAAE,OAAO,EAAE,kBAAkB,IAAI,CAAC,IAAI,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE;qBACjF,CAAC,CAAC,CAAC,CAAC;oBACL,SAAS;gBACX,CAAC;gBAED,wEAAwE;gBACxE,kEAAkE;gBAClE,6BAA6B;gBAC7B,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAS,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;gBAEzG,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC/E,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAS,EAAE,CAAC,CAAC;oBACvE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM;iBAC7C,CAAC,CAAC,CAAC,CAAC;gBAEL,wEAAwE;gBACxE,sEAAsE;gBACtE,sEAAsE;gBACtE,0DAA0D;gBAC1D,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Harness, HarnessContext, HarnessResult } from \"../../harness.js\";\nimport type { Entry } from \"../../../session/entry.js\";\nimport type { Message, Model } from \"../../../model/model.js\";\nimport { foldedThrough, toMessages } from \"../../../session/messages.js\";\nimport { compactionCut, estimateTokens, summarize } from \"./compaction.js\";\n\nexport interface NativeHarnessOptions {\n model: Model;\n /** Fold older turns into a summary once a request passes this size. */\n compaction?: {\n maxInputTokens: number;\n /** Defaults to the main model. A cheaper one is usually the right call. */\n model?: Model;\n prompt?: (messages: readonly Message[]) => string;\n };\n maxOutputTokens?: number;\n temperature?: number;\n /** How hard the model should think, where the provider supports it. */\n effort?: \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n}\n\n/**\n * Ask the model, run what it asks for, repeat.\n *\n * The loop holds no transcript. Every turn it re-reads `context.history()`,\n * which projects the committed log, and every result it produces goes back\n * through `context.commit` before the next turn is built. There is exactly one\n * representation of the conversation and it is the log.\n */\nexport function createNativeHarness(options: NativeHarnessOptions): Harness {\n return {\n id: \"native\",\n recovery: \"history\",\n\n async run(context: HarnessContext): Promise<HarnessResult> {\n const { runId } = context;\n let compacting = true;\n\n for (;;) {\n if (context.signal.aborted) return { status: \"cancelled\" };\n\n let history = context.history();\n\n if (compacting && options.compaction && estimateTokens(history) > options.compaction.maxInputTokens) {\n const entries = context.entries();\n const folded = foldedThrough(entries);\n const cut = compactionCut(entries);\n\n // Only ever fold forward. A cut at or behind the last summary removes\n // nothing, so committing one would buy a model call and another entry\n // and leave the request exactly as large — every turn, without end.\n if (cut !== undefined && cut > folded) {\n const summary = await summarize({\n model: options.compaction.model ?? options.model,\n // Exactly the span being replaced. Summarizing the whole history\n // put everything after the cut into the summary as well, so it\n // stayed in the request twice: once verbatim, once paraphrased.\n messages: toMessages({\n instructions: context.instructions,\n entries: entries.filter((entry) => entry.seq <= cut),\n }),\n ...(options.compaction.prompt ? { prompt: options.compaction.prompt } : {}),\n signal: context.signal,\n });\n if (!summary) {\n // Paid for and produced nothing. Attempted once per activation\n // rather than once per turn: retrying bought another model call\n // and another failure every turn, and the request stayed exactly\n // as large either way.\n compacting = false;\n }\n if (summary) {\n // The folded entries stay in the log. Compaction changes what the\n // model is shown on the next turn, never what happened.\n await context.commit([{ type: \"summary\", runId, content: summary, replaces: cut }]);\n history = context.history();\n }\n }\n }\n\n // One cache mark, at the end of the system prefix: instructions plus\n // run-scoped context, which are fixed for the life of the run.\n const cacheAfter = history.findIndex((message) => message.role !== \"system\");\n\n const startedAt = new Date().toISOString();\n const generation = options.model.generate({\n messages: history,\n ...(context.tools ? { tools: context.tools.list() } : {}),\n ...(options.maxOutputTokens !== undefined ? { maxOutputTokens: options.maxOutputTokens } : {}),\n ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),\n ...(options.effort ? { effort: options.effort } : {}),\n ...(cacheAfter > 0 ? { cacheAfter } : {}),\n signal: context.signal,\n });\n\n let step = await generation.next();\n while (!step.done) {\n const delta = step.value;\n if (delta.type === \"text.delta\") context.emit({ type: \"text.delta\", text: delta.text });\n if (delta.type === \"reasoning.delta\") context.emit({ type: \"reasoning.delta\", text: delta.text });\n if (delta.type === \"tool-call.delta\") {\n context.emit({ type: \"tool-call.delta\", callId: delta.callId, arguments: delta.arguments });\n }\n step = await generation.next();\n }\n if (!step.value.ok) {\n return step.value.error.code === \"cancelled\"\n ? { status: \"cancelled\" }\n : { status: \"failed\", error: step.value.error };\n }\n\n const endedAt = new Date().toISOString();\n const response = step.value.value;\n const calls = response.message.calls ?? [];\n\n await context.commit([{\n type: \"assistant\", runId, content: response.message.content,\n ...(calls.length ? { calls } : {}),\n usage: response.usage,\n generation: { ...(response.model ? { model: response.model } : {}), startedAt, endedAt },\n }]);\n\n if (!calls.length) {\n // The reason the model stopped decides the outcome, and it decides it\n // before the absence of tool calls does. A turn cut off by the output\n // ceiling or declined by a safety classifier is not an answer, and\n // reporting either as `completed` hands the caller a truncated or\n // refused response dressed as a finished one.\n if (response.finishReason === \"length\") {\n return { status: \"failed\", error: {\n code: \"output-truncated\",\n message: \"The response stopped at the output limit before it was finished.\",\n retryable: false,\n } };\n }\n if (response.finishReason === \"refusal\") {\n return { status: \"failed\", error: {\n code: \"refused\",\n message: \"The provider declined to answer.\",\n retryable: false,\n } };\n }\n return { status: \"completed\", output: response.message.content };\n }\n\n if (response.finishReason === \"length\") {\n // A truncated response can carry half-parsed arguments that happen to\n // be valid JSON. None of the batch runs; the model is told why and\n // can reissue.\n await context.commit(calls.map((call): Entry => ({\n type: \"tool.finished\", runId, callId: call.callId,\n result: { content: \"Not executed: the response was truncated. Reissue the call if it is still needed.\", isError: true },\n })));\n continue;\n }\n\n if (!context.tools) {\n await context.commit(calls.map((call): Entry => ({\n type: \"tool.finished\", runId, callId: call.callId,\n result: { content: `No tool named '${call.name}' is available.`, isError: true },\n })));\n continue;\n }\n\n // Recorded before anything runs. On restart an unmatched `tool.started`\n // is how we know the process died mid-effect — and why nothing is\n // re-executed automatically.\n await context.commit(calls.map((call): Entry => ({ type: \"tool.started\", runId, callId: call.callId })));\n\n const outcome = await context.tools.execute({ calls, signal: context.signal });\n await context.commit(outcome.results.map(({ callId, result }): Entry => ({\n type: \"tool.finished\", runId, callId, result,\n })));\n\n // Nothing is half-done here: every call asked for has been answered and\n // committed. Anything waiting is folded in before the next request is\n // built, so a message delivered to a busy session is read without the\n // activation having to be ended and its work thrown away.\n await context.drain?.();\n }\n },\n };\n}\n"]}
|
|
@@ -114,15 +114,26 @@ export type HarnessResult = {
|
|
|
114
114
|
/**
|
|
115
115
|
* Executes one activation of an agent.
|
|
116
116
|
*
|
|
117
|
-
*
|
|
118
|
-
* optional output, a different subsystem, or something no consumer asked about
|
|
119
|
-
*
|
|
120
|
-
*
|
|
117
|
+
* One fact, not eight. Everything the old capability matrix carried was either
|
|
118
|
+
* optional output, a different subsystem, or something no consumer asked about.
|
|
119
|
+
*
|
|
120
|
+
* `toolUse` went the same way, one release later. It claimed to say whose tools
|
|
121
|
+
* ran — "application" through the executor, "harness" its own — and three
|
|
122
|
+
* things were wrong with it. Nothing branched on it; no document owned the
|
|
123
|
+
* claim; and the word did not survive contact with the adapters. A harness can
|
|
124
|
+
* run a *vendor's* tools through our executor, validated and authorized, and a
|
|
125
|
+
* harness can run tools *we wrote* inside its own process. Whose tools, whose
|
|
126
|
+
* code and whose authority are three questions, and one enum answered none of
|
|
127
|
+
* them reliably.
|
|
128
|
+
*
|
|
129
|
+
* The question it was reaching for — did anyone authorize this call — is a fact
|
|
130
|
+
* about a call, not about a harness, and belongs on the tool entry if and when
|
|
131
|
+
* something needs to read it. `recipes/vendored-agent` and
|
|
132
|
+
* `docs/ARCHITECTURE.md` carry the per-adapter comparison in prose, which is
|
|
133
|
+
* where a fact about adapters belongs and where it can be accurate.
|
|
121
134
|
*/
|
|
122
135
|
export interface Harness {
|
|
123
136
|
readonly id: string;
|
|
124
|
-
/** "application": through the executor, validated and authorized. "harness": its own, which we never claim to have authorized. */
|
|
125
|
-
readonly toolUse: "application" | "harness" | "none";
|
|
126
137
|
/** "history": committed entries are enough to restart. "none": an interrupted run is over. */
|
|
127
138
|
readonly recovery: "history" | "none";
|
|
128
139
|
run(context: HarnessContext): Promise<HarnessResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/harness/harness.ts"],"names":[],"mappings":"","sourcesContent":["import type { Content } from \"../content.js\";\nimport type { Entry, Stored } from \"../session/entry.js\";\nimport type { Message } from \"../model/model.js\";\nimport type { ToolExecutor } from \"../tools/tool.js\";\nimport type { Failure } from \"../result.js\";\nimport type { JsonValue } from \"../json.js\";\n\n/**\n * Ephemeral output for a live viewer. Only committed entries are recovery state.\n *\n * An `entry` update carries the whole `Stored` shape — sequence and commit time\n * both. Anything building a live projection off this stream needs the timestamp\n * the log already has, and inventing one at receipt would put a second answer\n * to the same question into the world.\n */\nexport type Update =\n | { type: \"text.delta\"; text: string }\n | { type: \"reasoning.delta\"; text: string }\n | { type: \"tool.progress\"; callId: string; data: JsonValue }\n /** Arguments arriving a fragment at a time, so a viewer can show a call forming. */\n | { type: \"tool-call.delta\"; callId: string; arguments: string }\n | { type: \"entry\"; entry: Stored };\n\nexport interface HarnessContext {\n sessionId: string;\n runId: string;\n instructions: Content;\n /**\n * The log projected for this turn. A function, not a snapshot: it is rebuilt\n * from committed entries every time it is read, so a harness cannot hold a\n * transcript that drifts from the log.\n */\n history(): readonly Message[];\n /**\n * The committed log itself. A harness needs it to reason in sequence numbers\n * — where a compaction may cut, which call has no result yet — which the\n * projection deliberately does not carry.\n */\n entries(): readonly Stored[];\n /**\n * Application context placed around the cache boundary. `run` is stable for\n * the whole run and sits inside the cached prefix; `turn` is for this request\n * only and sits after it. Getting that split right is the loop's job because\n * only the loop knows where the prefix ends.\n */\n context?: { run?: string; turn?: string };\n tools?: ToolExecutor;\n /**\n * Commit to the log. Returns when durable — a harness never holds\n * uncommitted state.\n *\n * A refused write **rejects**, and a harness must not catch it: a lost\n * compare-and-swap means another writer is at this position, and the run is\n * over. Anything the agent was sending with that write goes with it.\n */\n commit(entries: readonly Entry[]): Promise<void>;\n /**\n * Fold any waiting input into this activation, and say how much arrived.\n *\n * Called at a boundary the harness picks — ours takes it after each batch of\n * tool results, which is the last point at which nothing is half-done. This\n * is the whole of `priority: \"turn\"`: a message reaching a busy session\n * without the turn's work being thrown away to get its attention.\n *\n * A harness with no such point does not offer this, and a `\"turn\"` delivery\n * to it waits for the next activation instead. It is never promoted to\n * ending the one that is running — the sender asked for the place that costs\n * nothing, and the answer to \"I cannot\" is later, not more destructive.\n *\n * Absent when there is no store, because then nothing can be waiting.\n *\n * Two things it will not do. It folds nothing into an activation that has\n * been cancelled — a message taken off the queue by a run that is ending is a\n * message nobody answers and nothing can find again. And a store it cannot\n * read answers zero, the same as an empty queue: the failure is not hidden\n * for long, because the next commit meets it.\n */\n drain?(): Promise<number>;\n emit(update: Update): void;\n signal: AbortSignal;\n}\n\n/**\n * How one activation ended, and nothing about what it consumed.\n *\n * A harness used to report usage too, and that was a second answer to a\n * question the log already answers: every generation's counts are on the\n * `assistant` entry that carried it. `runAgent` sums those, so accounting is\n * the same fact for a harness that owns its own loop as for ours, and a\n * cancelled or failed activation still says what it spent.\n */\nexport type HarnessResult =\n | { status: \"completed\"; output: Content }\n | { status: \"cancelled\" }\n | { status: \"failed\"; error: Failure };\n\n/**\n * Executes one activation of an agent.\n *\n *
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/harness/harness.ts"],"names":[],"mappings":"","sourcesContent":["import type { Content } from \"../content.js\";\nimport type { Entry, Stored } from \"../session/entry.js\";\nimport type { Message } from \"../model/model.js\";\nimport type { ToolExecutor } from \"../tools/tool.js\";\nimport type { Failure } from \"../result.js\";\nimport type { JsonValue } from \"../json.js\";\n\n/**\n * Ephemeral output for a live viewer. Only committed entries are recovery state.\n *\n * An `entry` update carries the whole `Stored` shape — sequence and commit time\n * both. Anything building a live projection off this stream needs the timestamp\n * the log already has, and inventing one at receipt would put a second answer\n * to the same question into the world.\n */\nexport type Update =\n | { type: \"text.delta\"; text: string }\n | { type: \"reasoning.delta\"; text: string }\n | { type: \"tool.progress\"; callId: string; data: JsonValue }\n /** Arguments arriving a fragment at a time, so a viewer can show a call forming. */\n | { type: \"tool-call.delta\"; callId: string; arguments: string }\n | { type: \"entry\"; entry: Stored };\n\nexport interface HarnessContext {\n sessionId: string;\n runId: string;\n instructions: Content;\n /**\n * The log projected for this turn. A function, not a snapshot: it is rebuilt\n * from committed entries every time it is read, so a harness cannot hold a\n * transcript that drifts from the log.\n */\n history(): readonly Message[];\n /**\n * The committed log itself. A harness needs it to reason in sequence numbers\n * — where a compaction may cut, which call has no result yet — which the\n * projection deliberately does not carry.\n */\n entries(): readonly Stored[];\n /**\n * Application context placed around the cache boundary. `run` is stable for\n * the whole run and sits inside the cached prefix; `turn` is for this request\n * only and sits after it. Getting that split right is the loop's job because\n * only the loop knows where the prefix ends.\n */\n context?: { run?: string; turn?: string };\n tools?: ToolExecutor;\n /**\n * Commit to the log. Returns when durable — a harness never holds\n * uncommitted state.\n *\n * A refused write **rejects**, and a harness must not catch it: a lost\n * compare-and-swap means another writer is at this position, and the run is\n * over. Anything the agent was sending with that write goes with it.\n */\n commit(entries: readonly Entry[]): Promise<void>;\n /**\n * Fold any waiting input into this activation, and say how much arrived.\n *\n * Called at a boundary the harness picks — ours takes it after each batch of\n * tool results, which is the last point at which nothing is half-done. This\n * is the whole of `priority: \"turn\"`: a message reaching a busy session\n * without the turn's work being thrown away to get its attention.\n *\n * A harness with no such point does not offer this, and a `\"turn\"` delivery\n * to it waits for the next activation instead. It is never promoted to\n * ending the one that is running — the sender asked for the place that costs\n * nothing, and the answer to \"I cannot\" is later, not more destructive.\n *\n * Absent when there is no store, because then nothing can be waiting.\n *\n * Two things it will not do. It folds nothing into an activation that has\n * been cancelled — a message taken off the queue by a run that is ending is a\n * message nobody answers and nothing can find again. And a store it cannot\n * read answers zero, the same as an empty queue: the failure is not hidden\n * for long, because the next commit meets it.\n */\n drain?(): Promise<number>;\n emit(update: Update): void;\n signal: AbortSignal;\n}\n\n/**\n * How one activation ended, and nothing about what it consumed.\n *\n * A harness used to report usage too, and that was a second answer to a\n * question the log already answers: every generation's counts are on the\n * `assistant` entry that carried it. `runAgent` sums those, so accounting is\n * the same fact for a harness that owns its own loop as for ours, and a\n * cancelled or failed activation still says what it spent.\n */\nexport type HarnessResult =\n | { status: \"completed\"; output: Content }\n | { status: \"cancelled\" }\n | { status: \"failed\"; error: Failure };\n\n/**\n * Executes one activation of an agent.\n *\n * One fact, not eight. Everything the old capability matrix carried was either\n * optional output, a different subsystem, or something no consumer asked about.\n *\n * `toolUse` went the same way, one release later. It claimed to say whose tools\n * ran — \"application\" through the executor, \"harness\" its own — and three\n * things were wrong with it. Nothing branched on it; no document owned the\n * claim; and the word did not survive contact with the adapters. A harness can\n * run a *vendor's* tools through our executor, validated and authorized, and a\n * harness can run tools *we wrote* inside its own process. Whose tools, whose\n * code and whose authority are three questions, and one enum answered none of\n * them reliably.\n *\n * The question it was reaching for — did anyone authorize this call — is a fact\n * about a call, not about a harness, and belongs on the tool entry if and when\n * something needs to read it. `recipes/vendored-agent` and\n * `docs/ARCHITECTURE.md` carry the per-adapter comparison in prose, which is\n * where a fact about adapters belongs and where it can be accurate.\n */\nexport interface Harness {\n readonly id: string;\n /** \"history\": committed entries are enough to restart. \"none\": an interrupted run is over. */\n readonly recovery: \"history\" | \"none\";\n run(context: HarnessContext): Promise<HarnessResult>;\n}\n"]}
|
|
@@ -144,15 +144,32 @@ export function createAnthropicModel(options) {
|
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
147
|
-
* Text blocks rather than one joined string, so the
|
|
148
|
-
*
|
|
149
|
-
*
|
|
147
|
+
* Text blocks rather than one joined string, so the prefix can carry
|
|
148
|
+
* breakpoints.
|
|
149
|
+
*
|
|
150
|
+
* Two are marked: the **first** block and the **last**. A breakpoint caches
|
|
151
|
+
* everything before it, so the last one is what makes the whole prefix
|
|
152
|
+
* reusable across a conversation's turns — and marking every block between
|
|
153
|
+
* would buy nothing while spending a budget of four.
|
|
154
|
+
*
|
|
155
|
+
* The first earns its own for a different reason. The first block is an agent's
|
|
156
|
+
* standing instructions, which are identical for every conversation it serves;
|
|
157
|
+
* everything after it is composed per conversation and changes with it. With
|
|
158
|
+
* one breakpoint at the end, a new conversation shares nothing: its prefix
|
|
159
|
+
* differs from the last one somewhere in the middle, so the whole of it is
|
|
160
|
+
* written again, instructions included. With one at the head, the instructions
|
|
161
|
+
* are read from cache by every conversation and only what actually differs is
|
|
162
|
+
* paid for — which is the common case for an agent serving many callers at
|
|
163
|
+
* once, and free where there is only one.
|
|
164
|
+
*
|
|
165
|
+
* Skipped when there is a single block: the two marks would be the same one.
|
|
150
166
|
*/
|
|
151
167
|
function encodeSystem(blocks, cache) {
|
|
168
|
+
const marked = new Set(blocks.length > 1 ? [0, blocks.length - 1] : [blocks.length - 1]);
|
|
152
169
|
return blocks.map((text, index) => ({
|
|
153
170
|
type: "text",
|
|
154
171
|
text,
|
|
155
|
-
...(cache && index
|
|
172
|
+
...(cache && marked.has(index) ? { cache_control: { type: "ephemeral" } } : {}),
|
|
156
173
|
}));
|
|
157
174
|
}
|
|
158
175
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/model/adapters/anthropic/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContentPart, Message, Model, ModelDelta, ModelError, ModelRequest, ModelResponse, ToolCall, ToolSpec, Usage,\n} from \"../../model.js\";\nimport { err, ok, type Result } from \"../../../result.js\";\nimport { textOf } from \"../../../content.js\";\n\nexport interface AnthropicOptions {\n apiKey: string;\n model: string;\n baseUrl?: string;\n version?: string;\n fetch?: typeof fetch;\n}\n\n/**\n * The Anthropic Messages wire.\n *\n * A genuinely different shape from OpenAI's — the leading system prompt hoisted\n * out of the message list, tool results carried as user content blocks, cache\n * breakpoints marked inline — which is the point of it being here: a port\n * proved against one wire format has not been proved.\n *\n * Three things this wire will refuse, and what we send instead:\n *\n * - **Thinking budgets.** `thinking: { type: \"enabled\", budget_tokens }` is\n * removed on the current models and returns 400. Depth is `output_config.effort`\n * over adaptive thinking, so `effort` maps there and nothing computes a budget.\n * - **Sampling controls.** `temperature`, `top_p` and `top_k` are removed on the\n * same models. `ModelRequest.temperature` is therefore dropped here rather\n * than forwarded into a request the provider rejects.\n * - **A system message in the middle of a turn.** Only the *leading* run of\n * system messages becomes the `system` field. One arriving after the\n * conversation has started is turn-scoped context, which the projection\n * deliberately places after the cache boundary, so it stays in `messages` as\n * a mid-conversation system message. Hoisting it would put the one thing that\n * changes every turn at the front of the prefix that must not change.\n * Supported on Opus 5, Opus 4.8 and Fable 5; a model without it fails the\n * request rather than silently having its cache invalidated every turn.\n */\nexport function createAnthropicModel(options: AnthropicOptions): Model {\n const call = options.fetch ?? fetch;\n const baseUrl = options.baseUrl ?? \"https://api.anthropic.com/v1\";\n\n return {\n id: `anthropic:${options.model}`,\n\n async *generate(request: ModelRequest): AsyncGenerator<ModelDelta, Result<ModelResponse, ModelError>> {\n // Only the leading run of system messages is the system prompt. Anything\n // after it belongs where the projection put it — see the header.\n let lead = 0;\n while (lead < request.messages.length && request.messages[lead]!.role === \"system\") lead += 1;\n const system = request.messages.slice(0, lead).map((message) => textOf(message.content));\n const conversation = request.messages.slice(lead);\n\n // The prefix ends where the caller says it does. In practice that is the\n // end of the system prompt, which is the one span fixed for the whole\n // run; a mark past it is honoured too rather than quietly ignored.\n const boundary = request.cacheAfter;\n const cacheSystem = boundary !== undefined && boundary >= lead && system.length > 0;\n const cacheAt = boundary !== undefined && boundary > lead ? boundary - lead - 1 : -1;\n\n const maxOutputTokens = request.maxOutputTokens ?? 32_000;\n\n let response: Response;\n try {\n response = await call(`${baseUrl}/messages`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": options.apiKey,\n \"anthropic-version\": options.version ?? \"2023-06-01\",\n },\n body: JSON.stringify({\n model: options.model,\n max_tokens: maxOutputTokens,\n ...(system.length ? { system: encodeSystem(system, cacheSystem) } : {}),\n messages: encodeConversation(conversation, cacheAt),\n ...(request.tools?.length ? { tools: request.tools.map(encodeTool) } : {}),\n ...(request.effort\n ? { thinking: { type: \"adaptive\" }, output_config: { effort: request.effort } }\n : {}),\n stream: true,\n }),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (error) {\n return err(transportError(error, request.signal));\n }\n if (!response.ok) return err(await httpError(response));\n if (!response.body) return err({ code: \"provider\", message: \"No response body\", retryable: true });\n\n const text: string[] = [];\n const calls: ToolCall[] = [];\n let partial = \"\";\n let stop: string | undefined;\n let usage: Usage = {};\n let model: string | undefined;\n\n // A stream that dies mid-body — cancelled, dropped, truncated — must come\n // back as a typed failure like any other. Without this the generator throws,\n // `run.result` rejects instead of resolving `cancelled`, no `run.finished`\n // is ever committed, and the activation stays open until its claim expires.\n try {\n for await (const event of sseData(response.body)) {\n let frame: AnthropicFrame;\n try { frame = JSON.parse(event) as AnthropicFrame; } catch { continue; }\n\n if (frame.type === \"message_start\" && frame.message) {\n model = frame.message.model;\n usage = { ...usage, ...decodeUsage(frame.message.usage) };\n }\n if (frame.type === \"content_block_start\" && frame.content_block?.type === \"tool_use\") {\n calls.push({ callId: frame.content_block.id!, name: frame.content_block.name!, arguments: \"\" });\n partial = \"\";\n }\n if (frame.type === \"content_block_delta\") {\n const delta = frame.delta!;\n if (delta.type === \"text_delta\" && delta.text) { text.push(delta.text); yield { type: \"text.delta\", text: delta.text }; }\n if (delta.type === \"thinking_delta\" && delta.thinking) yield { type: \"reasoning.delta\", text: delta.thinking };\n if (delta.type === \"input_json_delta\" && delta.partial_json !== undefined) {\n partial += delta.partial_json;\n const current = calls.at(-1);\n if (current) yield { type: \"tool-call.delta\", callId: current.callId, arguments: delta.partial_json };\n }\n }\n if (frame.type === \"content_block_stop\" && calls.length) {\n const current = calls.at(-1)!;\n if (!current.arguments) current.arguments = partial || \"{}\";\n }\n if (frame.type === \"message_delta\") {\n stop = frame.delta?.stop_reason ?? stop;\n usage = { ...usage, ...decodeUsage(frame.usage) };\n }\n if (frame.type === \"error\") {\n return err({ code: \"provider\", message: frame.error?.message ?? \"Provider error\", retryable: true });\n }\n }\n } catch (error) {\n return err(transportError(error, request.signal));\n }\n\n return ok({\n message: { content: text.join(\"\"), ...(calls.length ? { calls } : {}) },\n finishReason: stop === \"max_tokens\" ? \"length\" : stop === \"refusal\" ? \"refusal\" : calls.length ? \"tool-calls\" : \"stop\",\n usage,\n ...(model ? { model } : {}),\n });\n },\n };\n}\n\n/**\n * Text blocks rather than one joined string, so the end of the prefix can carry\n * a breakpoint. Only the last block is marked: a breakpoint caches everything\n * before it, so marking each one would buy nothing and spend the budget of four.\n */\nfunction encodeSystem(blocks: readonly string[], cache: boolean): unknown[] {\n return blocks.map((text, index) => ({\n type: \"text\",\n text,\n ...(cache && index === blocks.length - 1 ? { cache_control: { type: \"ephemeral\" } } : {}),\n }));\n}\n\n/**\n * Tool results are user-role content blocks here, not a role of their own.\n *\n * `cacheAt` is an index into `messages`; the breakpoint lands on the last\n * content block that message produced. Tool results merge into a preceding user\n * block, so the mapping from message to block is not one to one and the mark is\n * placed as each message is encoded rather than computed afterwards.\n */\nfunction encodeConversation(messages: readonly Message[], cacheAt = -1): unknown[] {\n const out: { role: string; content: unknown[] }[] = [];\n let mark: unknown[] | undefined;\n\n messages.forEach((message, index) => {\n if (message.role === \"tool\") {\n const block = {\n type: \"tool_result\", tool_use_id: message.callId, content: textOf(message.content),\n ...(message.isError ? { is_error: true } : {}),\n };\n const last = out.at(-1);\n if (last?.role === \"user\") last.content.push(block);\n else out.push({ role: \"user\", content: [block] });\n } else if (message.role === \"assistant\") {\n const content: unknown[] = [];\n const spoken = textOf(message.content);\n if (spoken) content.push({ type: \"text\", text: spoken });\n for (const call of message.calls ?? []) {\n content.push({ type: \"tool_use\", id: call.callId, name: call.name, input: safeJson(call.arguments) });\n }\n out.push({ role: \"assistant\", content });\n } else if (message.role === \"system\") {\n // Turn-scoped context, kept where the projection put it: an operator\n // instruction inside the conversation leaves the cached prefix intact,\n // where rewriting the front of it would invalidate every following turn.\n out.push({ role: \"system\", content: encodeContent(message.content) });\n } else {\n out.push({ role: \"user\", content: encodeContent(message.content) });\n }\n if (index === cacheAt) mark = out.at(-1)?.content;\n });\n\n const block = mark?.at(-1) as Record<string, unknown> | undefined;\n if (block) block[\"cache_control\"] = { type: \"ephemeral\" };\n return out;\n}\n\nfunction encodeContent(content: Message[\"content\"]): unknown[] {\n if (typeof content === \"string\") return [{ type: \"text\", text: content }];\n const parts: unknown[] = [];\n for (const part of content as readonly ContentPart[]) {\n if (part.type === \"text\") parts.push({ type: \"text\", text: part.text });\n if (part.type === \"image\") {\n parts.push(part.source.kind === \"url\"\n ? { type: \"image\", source: { type: \"url\", url: part.source.url } }\n : { type: \"image\", source: { type: \"base64\", media_type: part.mediaType, data: part.source.data } });\n }\n }\n return parts;\n}\n\nconst encodeTool = (tool: ToolSpec) => ({\n name: tool.name, description: tool.description, input_schema: tool.parameters,\n});\n\nconst safeJson = (raw: string): unknown => { try { return JSON.parse(raw); } catch { return {}; } };\n\nconst decodeUsage = (usage: AnthropicUsage | undefined): Usage => usage ? {\n ...(usage.input_tokens !== undefined ? { inputTokens: usage.input_tokens } : {}),\n ...(usage.output_tokens !== undefined ? { outputTokens: usage.output_tokens } : {}),\n ...(usage.cache_read_input_tokens !== undefined ? { cacheReadTokens: usage.cache_read_input_tokens } : {}),\n ...(usage.cache_creation_input_tokens !== undefined ? { cacheWriteTokens: usage.cache_creation_input_tokens } : {}),\n} : {};\n\nasync function httpError(response: Response): Promise<ModelError> {\n const body = await response.text().catch(() => \"\");\n const code: ModelError[\"code\"] =\n response.status === 401 || response.status === 403 ? \"auth\"\n : response.status === 429 ? \"rate-limit\"\n : response.status === 400 && /prompt is too long|context/i.test(body) ? \"context-length\"\n : response.status >= 500 ? \"provider\"\n : \"failed\";\n return {\n code,\n message: `${response.status} ${response.statusText}${body ? `: ${body.slice(0, 400)}` : \"\"}`,\n retryable: code === \"rate-limit\" || code === \"provider\",\n };\n}\n\nfunction transportError(error: unknown, signal?: AbortSignal): ModelError {\n if (signal?.aborted) return { code: \"cancelled\", message: \"Generation cancelled\", retryable: false };\n return { code: \"provider\", message: error instanceof Error ? error.message : String(error), retryable: true };\n}\n\nasync function* sseData(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n for await (const chunk of body as unknown as AsyncIterable<Uint8Array>) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf(\"\\n\");\n while (newline >= 0) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (line.startsWith(\"data:\")) yield line.slice(5).trim();\n newline = buffer.indexOf(\"\\n\");\n }\n }\n}\n\ninterface AnthropicUsage {\n input_tokens?: number; output_tokens?: number;\n cache_read_input_tokens?: number; cache_creation_input_tokens?: number;\n}\ninterface AnthropicFrame {\n type: string;\n message?: { model?: string; usage?: AnthropicUsage };\n content_block?: { type: string; id?: string; name?: string };\n delta?: { type?: string; text?: string; thinking?: string; partial_json?: string; stop_reason?: string };\n usage?: AnthropicUsage;\n error?: { message?: string };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/model/adapters/anthropic/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContentPart, Message, Model, ModelDelta, ModelError, ModelRequest, ModelResponse, ToolCall, ToolSpec, Usage,\n} from \"../../model.js\";\nimport { err, ok, type Result } from \"../../../result.js\";\nimport { textOf } from \"../../../content.js\";\n\nexport interface AnthropicOptions {\n apiKey: string;\n model: string;\n baseUrl?: string;\n version?: string;\n fetch?: typeof fetch;\n}\n\n/**\n * The Anthropic Messages wire.\n *\n * A genuinely different shape from OpenAI's — the leading system prompt hoisted\n * out of the message list, tool results carried as user content blocks, cache\n * breakpoints marked inline — which is the point of it being here: a port\n * proved against one wire format has not been proved.\n *\n * Three things this wire will refuse, and what we send instead:\n *\n * - **Thinking budgets.** `thinking: { type: \"enabled\", budget_tokens }` is\n * removed on the current models and returns 400. Depth is `output_config.effort`\n * over adaptive thinking, so `effort` maps there and nothing computes a budget.\n * - **Sampling controls.** `temperature`, `top_p` and `top_k` are removed on the\n * same models. `ModelRequest.temperature` is therefore dropped here rather\n * than forwarded into a request the provider rejects.\n * - **A system message in the middle of a turn.** Only the *leading* run of\n * system messages becomes the `system` field. One arriving after the\n * conversation has started is turn-scoped context, which the projection\n * deliberately places after the cache boundary, so it stays in `messages` as\n * a mid-conversation system message. Hoisting it would put the one thing that\n * changes every turn at the front of the prefix that must not change.\n * Supported on Opus 5, Opus 4.8 and Fable 5; a model without it fails the\n * request rather than silently having its cache invalidated every turn.\n */\nexport function createAnthropicModel(options: AnthropicOptions): Model {\n const call = options.fetch ?? fetch;\n const baseUrl = options.baseUrl ?? \"https://api.anthropic.com/v1\";\n\n return {\n id: `anthropic:${options.model}`,\n\n async *generate(request: ModelRequest): AsyncGenerator<ModelDelta, Result<ModelResponse, ModelError>> {\n // Only the leading run of system messages is the system prompt. Anything\n // after it belongs where the projection put it — see the header.\n let lead = 0;\n while (lead < request.messages.length && request.messages[lead]!.role === \"system\") lead += 1;\n const system = request.messages.slice(0, lead).map((message) => textOf(message.content));\n const conversation = request.messages.slice(lead);\n\n // The prefix ends where the caller says it does. In practice that is the\n // end of the system prompt, which is the one span fixed for the whole\n // run; a mark past it is honoured too rather than quietly ignored.\n const boundary = request.cacheAfter;\n const cacheSystem = boundary !== undefined && boundary >= lead && system.length > 0;\n const cacheAt = boundary !== undefined && boundary > lead ? boundary - lead - 1 : -1;\n\n const maxOutputTokens = request.maxOutputTokens ?? 32_000;\n\n let response: Response;\n try {\n response = await call(`${baseUrl}/messages`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": options.apiKey,\n \"anthropic-version\": options.version ?? \"2023-06-01\",\n },\n body: JSON.stringify({\n model: options.model,\n max_tokens: maxOutputTokens,\n ...(system.length ? { system: encodeSystem(system, cacheSystem) } : {}),\n messages: encodeConversation(conversation, cacheAt),\n ...(request.tools?.length ? { tools: request.tools.map(encodeTool) } : {}),\n ...(request.effort\n ? { thinking: { type: \"adaptive\" }, output_config: { effort: request.effort } }\n : {}),\n stream: true,\n }),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (error) {\n return err(transportError(error, request.signal));\n }\n if (!response.ok) return err(await httpError(response));\n if (!response.body) return err({ code: \"provider\", message: \"No response body\", retryable: true });\n\n const text: string[] = [];\n const calls: ToolCall[] = [];\n let partial = \"\";\n let stop: string | undefined;\n let usage: Usage = {};\n let model: string | undefined;\n\n // A stream that dies mid-body — cancelled, dropped, truncated — must come\n // back as a typed failure like any other. Without this the generator throws,\n // `run.result` rejects instead of resolving `cancelled`, no `run.finished`\n // is ever committed, and the activation stays open until its claim expires.\n try {\n for await (const event of sseData(response.body)) {\n let frame: AnthropicFrame;\n try { frame = JSON.parse(event) as AnthropicFrame; } catch { continue; }\n\n if (frame.type === \"message_start\" && frame.message) {\n model = frame.message.model;\n usage = { ...usage, ...decodeUsage(frame.message.usage) };\n }\n if (frame.type === \"content_block_start\" && frame.content_block?.type === \"tool_use\") {\n calls.push({ callId: frame.content_block.id!, name: frame.content_block.name!, arguments: \"\" });\n partial = \"\";\n }\n if (frame.type === \"content_block_delta\") {\n const delta = frame.delta!;\n if (delta.type === \"text_delta\" && delta.text) { text.push(delta.text); yield { type: \"text.delta\", text: delta.text }; }\n if (delta.type === \"thinking_delta\" && delta.thinking) yield { type: \"reasoning.delta\", text: delta.thinking };\n if (delta.type === \"input_json_delta\" && delta.partial_json !== undefined) {\n partial += delta.partial_json;\n const current = calls.at(-1);\n if (current) yield { type: \"tool-call.delta\", callId: current.callId, arguments: delta.partial_json };\n }\n }\n if (frame.type === \"content_block_stop\" && calls.length) {\n const current = calls.at(-1)!;\n if (!current.arguments) current.arguments = partial || \"{}\";\n }\n if (frame.type === \"message_delta\") {\n stop = frame.delta?.stop_reason ?? stop;\n usage = { ...usage, ...decodeUsage(frame.usage) };\n }\n if (frame.type === \"error\") {\n return err({ code: \"provider\", message: frame.error?.message ?? \"Provider error\", retryable: true });\n }\n }\n } catch (error) {\n return err(transportError(error, request.signal));\n }\n\n return ok({\n message: { content: text.join(\"\"), ...(calls.length ? { calls } : {}) },\n finishReason: stop === \"max_tokens\" ? \"length\" : stop === \"refusal\" ? \"refusal\" : calls.length ? \"tool-calls\" : \"stop\",\n usage,\n ...(model ? { model } : {}),\n });\n },\n };\n}\n\n/**\n * Text blocks rather than one joined string, so the prefix can carry\n * breakpoints.\n *\n * Two are marked: the **first** block and the **last**. A breakpoint caches\n * everything before it, so the last one is what makes the whole prefix\n * reusable across a conversation's turns — and marking every block between\n * would buy nothing while spending a budget of four.\n *\n * The first earns its own for a different reason. The first block is an agent's\n * standing instructions, which are identical for every conversation it serves;\n * everything after it is composed per conversation and changes with it. With\n * one breakpoint at the end, a new conversation shares nothing: its prefix\n * differs from the last one somewhere in the middle, so the whole of it is\n * written again, instructions included. With one at the head, the instructions\n * are read from cache by every conversation and only what actually differs is\n * paid for — which is the common case for an agent serving many callers at\n * once, and free where there is only one.\n *\n * Skipped when there is a single block: the two marks would be the same one.\n */\nfunction encodeSystem(blocks: readonly string[], cache: boolean): unknown[] {\n const marked = new Set(blocks.length > 1 ? [0, blocks.length - 1] : [blocks.length - 1]);\n return blocks.map((text, index) => ({\n type: \"text\",\n text,\n ...(cache && marked.has(index) ? { cache_control: { type: \"ephemeral\" } } : {}),\n }));\n}\n\n/**\n * Tool results are user-role content blocks here, not a role of their own.\n *\n * `cacheAt` is an index into `messages`; the breakpoint lands on the last\n * content block that message produced. Tool results merge into a preceding user\n * block, so the mapping from message to block is not one to one and the mark is\n * placed as each message is encoded rather than computed afterwards.\n */\nfunction encodeConversation(messages: readonly Message[], cacheAt = -1): unknown[] {\n const out: { role: string; content: unknown[] }[] = [];\n let mark: unknown[] | undefined;\n\n messages.forEach((message, index) => {\n if (message.role === \"tool\") {\n const block = {\n type: \"tool_result\", tool_use_id: message.callId, content: textOf(message.content),\n ...(message.isError ? { is_error: true } : {}),\n };\n const last = out.at(-1);\n if (last?.role === \"user\") last.content.push(block);\n else out.push({ role: \"user\", content: [block] });\n } else if (message.role === \"assistant\") {\n const content: unknown[] = [];\n const spoken = textOf(message.content);\n if (spoken) content.push({ type: \"text\", text: spoken });\n for (const call of message.calls ?? []) {\n content.push({ type: \"tool_use\", id: call.callId, name: call.name, input: safeJson(call.arguments) });\n }\n out.push({ role: \"assistant\", content });\n } else if (message.role === \"system\") {\n // Turn-scoped context, kept where the projection put it: an operator\n // instruction inside the conversation leaves the cached prefix intact,\n // where rewriting the front of it would invalidate every following turn.\n out.push({ role: \"system\", content: encodeContent(message.content) });\n } else {\n out.push({ role: \"user\", content: encodeContent(message.content) });\n }\n if (index === cacheAt) mark = out.at(-1)?.content;\n });\n\n const block = mark?.at(-1) as Record<string, unknown> | undefined;\n if (block) block[\"cache_control\"] = { type: \"ephemeral\" };\n return out;\n}\n\nfunction encodeContent(content: Message[\"content\"]): unknown[] {\n if (typeof content === \"string\") return [{ type: \"text\", text: content }];\n const parts: unknown[] = [];\n for (const part of content as readonly ContentPart[]) {\n if (part.type === \"text\") parts.push({ type: \"text\", text: part.text });\n if (part.type === \"image\") {\n parts.push(part.source.kind === \"url\"\n ? { type: \"image\", source: { type: \"url\", url: part.source.url } }\n : { type: \"image\", source: { type: \"base64\", media_type: part.mediaType, data: part.source.data } });\n }\n }\n return parts;\n}\n\nconst encodeTool = (tool: ToolSpec) => ({\n name: tool.name, description: tool.description, input_schema: tool.parameters,\n});\n\nconst safeJson = (raw: string): unknown => { try { return JSON.parse(raw); } catch { return {}; } };\n\nconst decodeUsage = (usage: AnthropicUsage | undefined): Usage => usage ? {\n ...(usage.input_tokens !== undefined ? { inputTokens: usage.input_tokens } : {}),\n ...(usage.output_tokens !== undefined ? { outputTokens: usage.output_tokens } : {}),\n ...(usage.cache_read_input_tokens !== undefined ? { cacheReadTokens: usage.cache_read_input_tokens } : {}),\n ...(usage.cache_creation_input_tokens !== undefined ? { cacheWriteTokens: usage.cache_creation_input_tokens } : {}),\n} : {};\n\nasync function httpError(response: Response): Promise<ModelError> {\n const body = await response.text().catch(() => \"\");\n const code: ModelError[\"code\"] =\n response.status === 401 || response.status === 403 ? \"auth\"\n : response.status === 429 ? \"rate-limit\"\n : response.status === 400 && /prompt is too long|context/i.test(body) ? \"context-length\"\n : response.status >= 500 ? \"provider\"\n : \"failed\";\n return {\n code,\n message: `${response.status} ${response.statusText}${body ? `: ${body.slice(0, 400)}` : \"\"}`,\n retryable: code === \"rate-limit\" || code === \"provider\",\n };\n}\n\nfunction transportError(error: unknown, signal?: AbortSignal): ModelError {\n if (signal?.aborted) return { code: \"cancelled\", message: \"Generation cancelled\", retryable: false };\n return { code: \"provider\", message: error instanceof Error ? error.message : String(error), retryable: true };\n}\n\nasync function* sseData(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n for await (const chunk of body as unknown as AsyncIterable<Uint8Array>) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf(\"\\n\");\n while (newline >= 0) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (line.startsWith(\"data:\")) yield line.slice(5).trim();\n newline = buffer.indexOf(\"\\n\");\n }\n }\n}\n\ninterface AnthropicUsage {\n input_tokens?: number; output_tokens?: number;\n cache_read_input_tokens?: number; cache_creation_input_tokens?: number;\n}\ninterface AnthropicFrame {\n type: string;\n message?: { model?: string; usage?: AnthropicUsage };\n content_block?: { type: string; id?: string; name?: string };\n delta?: { type?: string; text?: string; thinking?: string; partial_json?: string; stop_reason?: string };\n usage?: AnthropicUsage;\n error?: { message?: string };\n}\n"]}
|
package/dist/model/index.d.ts
CHANGED
package/dist/model/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/model/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n Message, Model, ModelDelta, ModelError, ModelRequest, ModelResponse, ToolSpec,\n} from \"./model.js\";\n"]}
|
package/dist/model/model.d.ts
CHANGED
|
@@ -74,7 +74,14 @@ export interface Model {
|
|
|
74
74
|
readonly id: string;
|
|
75
75
|
generate(request: ModelRequest): AsyncGenerator<ModelDelta, Result<ModelResponse, ModelError>>;
|
|
76
76
|
}
|
|
77
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* Drains a generation and returns only its outcome.
|
|
79
|
+
*
|
|
80
|
+
* Not on the `aglib/model` subpath. It was, for a recipe that turned a `Model`
|
|
81
|
+
* into an Anthropic response; when that went, nothing outside the package
|
|
82
|
+
* consumed it. `Model`'s own contract above says what a caller who wants the
|
|
83
|
+
* whole response does, and this is the four lines of doing it.
|
|
84
|
+
*/
|
|
78
85
|
export declare function collect(generation: AsyncGenerator<ModelDelta, Result<ModelResponse, ModelError>>): Promise<Result<ModelResponse, ModelError>>;
|
|
79
86
|
/**
|
|
80
87
|
* The vocabulary an adapter needs, re-exported from the port it implements.
|
package/dist/model/model.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Drains a generation and returns only its outcome.
|
|
3
|
+
*
|
|
4
|
+
* Not on the `aglib/model` subpath. It was, for a recipe that turned a `Model`
|
|
5
|
+
* into an Anthropic response; when that went, nothing outside the package
|
|
6
|
+
* consumed it. `Model`'s own contract above says what a caller who wants the
|
|
7
|
+
* whole response does, and this is the four lines of doing it.
|
|
8
|
+
*/
|
|
2
9
|
export async function collect(generation) {
|
|
3
10
|
let step = await generation.next();
|
|
4
11
|
while (!step.done)
|