@a-dray/aglib 0.1.0 → 0.2.0

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.
Files changed (42) hide show
  1. package/README.md +55 -136
  2. package/dist/agent.d.ts +12 -0
  3. package/dist/agent.js.map +1 -1
  4. package/dist/harness/adapters/acp/index.d.ts +27 -11
  5. package/dist/harness/adapters/acp/index.js +58 -24
  6. package/dist/harness/adapters/acp/index.js.map +1 -1
  7. package/dist/harness/adapters/native/compaction.d.ts +15 -0
  8. package/dist/harness/adapters/native/compaction.js +23 -8
  9. package/dist/harness/adapters/native/compaction.js.map +1 -1
  10. package/dist/harness/adapters/native/loop.d.ts +18 -1
  11. package/dist/harness/adapters/native/loop.js +0 -1
  12. package/dist/harness/adapters/native/loop.js.map +1 -1
  13. package/dist/harness/harness.d.ts +17 -6
  14. package/dist/harness/harness.js.map +1 -1
  15. package/dist/model/adapters/anthropic/index.js +21 -4
  16. package/dist/model/adapters/anthropic/index.js.map +1 -1
  17. package/dist/model/index.d.ts +0 -1
  18. package/dist/model/index.js +1 -1
  19. package/dist/model/index.js.map +1 -1
  20. package/dist/model/model.d.ts +8 -1
  21. package/dist/model/model.js +8 -1
  22. package/dist/model/model.js.map +1 -1
  23. package/dist/render.d.ts +100 -0
  24. package/dist/render.js +370 -0
  25. package/dist/render.js.map +1 -0
  26. package/dist/run.js +1 -0
  27. package/dist/run.js.map +1 -1
  28. package/dist/session/entry.d.ts +3 -2
  29. package/dist/session/entry.js.map +1 -1
  30. package/dist/session/messages.d.ts +9 -0
  31. package/dist/session/messages.js +5 -5
  32. package/dist/session/messages.js.map +1 -1
  33. package/dist/store/adapters/sqlite.js +25 -2
  34. package/dist/store/adapters/sqlite.js.map +1 -1
  35. package/dist/terminal.d.ts +23 -0
  36. package/dist/terminal.js +90 -0
  37. package/dist/terminal.js.map +1 -0
  38. package/dist/tools/execute.js +3 -1
  39. package/dist/tools/execute.js.map +1 -1
  40. package/dist/tools/tool.d.ts +8 -1
  41. package/dist/tools/tool.js.map +1 -1
  42. 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"]}
@@ -7,6 +7,21 @@ import type { Stored } from "../../../session/entry.js";
7
7
  * costs one early or late compaction, not correctness.
8
8
  */
9
9
  export declare function estimateTokens(messages: readonly Message[]): number;
10
+ /**
11
+ * The latest position that can be folded without separating a tool call from
12
+ * its results.
13
+ *
14
+ * A position is safe when the log is **drained** there: every call an assistant
15
+ * turn asked for has its `tool.finished`. The gap between two batches of calls
16
+ * is such a point, as are a turn that asked for nothing and the end of a run.
17
+ * Cutting anywhere else leaves one call of a batch summarized and its sibling
18
+ * live, which shows the model a result for a call it can no longer see.
19
+ *
20
+ * A finished run and an empty turn alone were not enough, and the run that
21
+ * needed compaction was exactly the run that had neither: inside one activation
22
+ * every assistant turn holds calls until the one that ends it, so a single long
23
+ * activation never folded and grew until the provider refused it.
24
+ */
10
25
  export declare function compactionCut(entries: readonly Stored[]): number | undefined;
11
26
  export declare function summarize(input: {
12
27
  model: Model;
@@ -9,24 +9,39 @@ import { textOf } from "../../../content.js";
9
9
  export function estimateTokens(messages) {
10
10
  return messages.reduce((total, message) => total + JSON.stringify(message).length, 0) / 4;
11
11
  }
12
+ /** How much of the tail is kept verbatim. A constant until a caller disagrees. */
13
+ const KEEP_FRACTION = 0.4;
12
14
  /**
13
15
  * The latest position that can be folded without separating a tool call from
14
16
  * its results.
15
17
  *
16
- * Only two entry types are clean boundaries: a finished run, and an assistant
17
- * turn that asked for nothing. Cutting anywhere else can leave one call of a
18
- * batch summarized and its sibling live, which shows the model a result for a
19
- * call it can no longer see.
18
+ * A position is safe when the log is **drained** there: every call an assistant
19
+ * turn asked for has its `tool.finished`. The gap between two batches of calls
20
+ * is such a point, as are a turn that asked for nothing and the end of a run.
21
+ * Cutting anywhere else leaves one call of a batch summarized and its sibling
22
+ * live, which shows the model a result for a call it can no longer see.
23
+ *
24
+ * A finished run and an empty turn alone were not enough, and the run that
25
+ * needed compaction was exactly the run that had neither: inside one activation
26
+ * every assistant turn holds calls until the one that ends it, so a single long
27
+ * activation never folded and grew until the provider refused it.
20
28
  */
21
- /** How much of the tail is kept verbatim. A constant until a caller disagrees. */
22
- const KEEP_FRACTION = 0.4;
23
29
  export function compactionCut(entries) {
24
30
  const boundary = Math.floor(entries.length * (1 - KEEP_FRACTION));
31
+ const awaiting = new Set();
25
32
  let cut;
26
33
  for (const entry of entries.slice(0, boundary)) {
34
+ if (entry.type === "assistant")
35
+ for (const call of entry.calls ?? [])
36
+ awaiting.add(call.callId);
37
+ if (entry.type === "tool.finished")
38
+ awaiting.delete(entry.callId);
39
+ // A run that ended takes its unanswered calls with it. The projection closes
40
+ // each one beside the turn that asked for it, so both fall on the same side
41
+ // of any later cut.
27
42
  if (entry.type === "run.finished")
28
- cut = entry.seq;
29
- if (entry.type === "assistant" && !entry.calls?.length)
43
+ awaiting.clear();
44
+ if (!awaiting.size)
30
45
  cut = entry.seq;
31
46
  }
32
47
  return cut;
@@ -1 +1 @@
1
- {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../../src/harness/adapters/native/compaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAA4B;IACzD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;AAC5F,CAAC;AAED;;;;;;;;GAQG;AACH,kFAAkF;AAClF,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,MAAM,UAAU,aAAa,CAAC,OAA0B;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAClE,IAAI,GAAuB,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;YAAE,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QACnD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM;YAAE,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IAC1E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4FAA4F;AAC5F,SAAS,aAAa,CAAC,QAA4B;IACjD,OAAO;QACL,6EAA6E;QAC7E,oEAAoE;QACpE,sDAAsD;QACtD,0CAA0C;QAC1C,wFAAwF;QACxF,wDAAwD;QACxD,EAAE;QACF,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;KACtF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAK/B;IACC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjD,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtF,eAAe,EAAE,KAAK;QACtB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAC,CAAC,CAAC;IACJ,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxE,CAAC","sourcesContent":["import type { Model, Message } from \"../../../model/model.js\";\nimport type { Stored } from \"../../../session/entry.js\";\nimport { collect } from \"../../../model/model.js\";\nimport { textOf } from \"../../../content.js\";\n\n/**\n * Crude and deliberate: four characters per token, over the serialized request.\n * A real count needs the provider's tokenizer, which would mean shipping one\n * per provider to decide a threshold that is itself a guess. Being wrong here\n * costs one early or late compaction, not correctness.\n */\nexport function estimateTokens(messages: readonly Message[]): number {\n return messages.reduce((total, message) => total + JSON.stringify(message).length, 0) / 4;\n}\n\n/**\n * The latest position that can be folded without separating a tool call from\n * its results.\n *\n * Only two entry types are clean boundaries: a finished run, and an assistant\n * turn that asked for nothing. Cutting anywhere else can leave one call of a\n * batch summarized and its sibling live, which shows the model a result for a\n * call it can no longer see.\n */\n/** How much of the tail is kept verbatim. A constant until a caller disagrees. */\nconst KEEP_FRACTION = 0.4;\n\nexport function compactionCut(entries: readonly Stored[]): number | undefined {\n const boundary = Math.floor(entries.length * (1 - KEEP_FRACTION));\n let cut: number | undefined;\n for (const entry of entries.slice(0, boundary)) {\n if (entry.type === \"run.finished\") cut = entry.seq;\n if (entry.type === \"assistant\" && !entry.calls?.length) cut = entry.seq;\n }\n return cut;\n}\n\n/** What the summary must preserve. Overridable, because what matters is domain-specific. */\nfunction summaryPrompt(messages: readonly Message[]): string {\n return [\n \"You are compacting an agent conversation that continues after this summary.\",\n \"Summarize the transcript below faithfully and concisely, covering:\",\n \"- Intent: the goal and the current state of the task\",\n \"- Decisions: choices made so far and why\",\n \"- Artifacts: files, outputs and results worth remembering (exact names, paths, values)\",\n \"- Pending: unfinished work, next steps, open questions\",\n \"\",\n messages.map((message) => `${message.role}: ${textOf(message.content)}`).join(\"\\n\\n\"),\n ].join(\"\\n\");\n}\n\nexport async function summarize(input: {\n model: Model;\n messages: readonly Message[];\n prompt?: (messages: readonly Message[]) => string;\n signal?: AbortSignal;\n}): Promise<string | undefined> {\n const outcome = await collect(input.model.generate({\n messages: [{ role: \"user\", content: (input.prompt ?? summaryPrompt)(input.messages) }],\n maxOutputTokens: 2_000,\n ...(input.signal ? { signal: input.signal } : {}),\n }));\n return outcome.ok ? textOf(outcome.value.message.content) : undefined;\n}\n"]}
1
+ {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../../src/harness/adapters/native/compaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAA4B;IACzD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;AAC5F,CAAC;AAED,kFAAkF;AAClF,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAAC,OAA0B;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,IAAI,GAAuB,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE;gBAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChG,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe;YAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,6EAA6E;QAC7E,4EAA4E;QAC5E,oBAAoB;QACpB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;YAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;QACpD,IAAI,CAAC,QAAQ,CAAC,IAAI;YAAE,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4FAA4F;AAC5F,SAAS,aAAa,CAAC,QAA4B;IACjD,OAAO;QACL,6EAA6E;QAC7E,oEAAoE;QACpE,sDAAsD;QACtD,0CAA0C;QAC1C,wFAAwF;QACxF,wDAAwD;QACxD,EAAE;QACF,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;KACtF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAK/B;IACC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjD,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,aAAa,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtF,eAAe,EAAE,KAAK;QACtB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAC,CAAC,CAAC;IACJ,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxE,CAAC","sourcesContent":["import type { Model, Message } from \"../../../model/model.js\";\nimport type { Stored } from \"../../../session/entry.js\";\nimport { collect } from \"../../../model/model.js\";\nimport { textOf } from \"../../../content.js\";\n\n/**\n * Crude and deliberate: four characters per token, over the serialized request.\n * A real count needs the provider's tokenizer, which would mean shipping one\n * per provider to decide a threshold that is itself a guess. Being wrong here\n * costs one early or late compaction, not correctness.\n */\nexport function estimateTokens(messages: readonly Message[]): number {\n return messages.reduce((total, message) => total + JSON.stringify(message).length, 0) / 4;\n}\n\n/** How much of the tail is kept verbatim. A constant until a caller disagrees. */\nconst KEEP_FRACTION = 0.4;\n\n/**\n * The latest position that can be folded without separating a tool call from\n * its results.\n *\n * A position is safe when the log is **drained** there: every call an assistant\n * turn asked for has its `tool.finished`. The gap between two batches of calls\n * is such a point, as are a turn that asked for nothing and the end of a run.\n * Cutting anywhere else leaves one call of a batch summarized and its sibling\n * live, which shows the model a result for a call it can no longer see.\n *\n * A finished run and an empty turn alone were not enough, and the run that\n * needed compaction was exactly the run that had neither: inside one activation\n * every assistant turn holds calls until the one that ends it, so a single long\n * activation never folded and grew until the provider refused it.\n */\nexport function compactionCut(entries: readonly Stored[]): number | undefined {\n const boundary = Math.floor(entries.length * (1 - KEEP_FRACTION));\n const awaiting = new Set<string>();\n let cut: number | undefined;\n for (const entry of entries.slice(0, boundary)) {\n if (entry.type === \"assistant\") for (const call of entry.calls ?? []) awaiting.add(call.callId);\n if (entry.type === \"tool.finished\") awaiting.delete(entry.callId);\n // A run that ended takes its unanswered calls with it. The projection closes\n // each one beside the turn that asked for it, so both fall on the same side\n // of any later cut.\n if (entry.type === \"run.finished\") awaiting.clear();\n if (!awaiting.size) cut = entry.seq;\n }\n return cut;\n}\n\n/** What the summary must preserve. Overridable, because what matters is domain-specific. */\nfunction summaryPrompt(messages: readonly Message[]): string {\n return [\n \"You are compacting an agent conversation that continues after this summary.\",\n \"Summarize the transcript below faithfully and concisely, covering:\",\n \"- Intent: the goal and the current state of the task\",\n \"- Decisions: choices made so far and why\",\n \"- Artifacts: files, outputs and results worth remembering (exact names, paths, values)\",\n \"- Pending: unfinished work, next steps, open questions\",\n \"\",\n messages.map((message) => `${message.role}: ${textOf(message.content)}`).join(\"\\n\\n\"),\n ].join(\"\\n\");\n}\n\nexport async function summarize(input: {\n model: Model;\n messages: readonly Message[];\n prompt?: (messages: readonly Message[]) => string;\n signal?: AbortSignal;\n}): Promise<string | undefined> {\n const outcome = await collect(input.model.generate({\n messages: [{ role: \"user\", content: (input.prompt ?? summaryPrompt)(input.messages) }],\n maxOutputTokens: 2_000,\n ...(input.signal ? { signal: input.signal } : {}),\n }));\n return outcome.ok ? textOf(outcome.value.message.content) : undefined;\n}\n"]}
@@ -4,8 +4,25 @@ export interface NativeHarnessOptions {
4
4
  model: Model;
5
5
  /** Fold older turns into a summary once a request passes this size. */
6
6
  compaction?: {
7
+ /**
8
+ * The estimated request size a fold happens above.
9
+ *
10
+ * A budget, not a provider fact: it belongs below the input window of the
11
+ * model that answers, with room for the turn that follows the fold. Folding
12
+ * early spends a model call and hands the run a paraphrase of work the log
13
+ * still holds in full; folding late risks the request a provider refuses.
14
+ */
7
15
  maxInputTokens: number;
8
- /** Defaults to the main model. A cheaper one is usually the right call. */
16
+ /**
17
+ * Who writes the summary. Defaults to the run's own model, so an
18
+ * application that says nothing meets neither a second provider nor a
19
+ * second credential.
20
+ *
21
+ * A cheaper one is right where the span being folded is long and reading it
22
+ * back is all the work — this is not the reasoning the main model is being
23
+ * paid for. It still has to take the whole span in one request, and to be
24
+ * good enough that what it drops is what did not matter.
25
+ */
9
26
  model?: Model;
10
27
  prompt?: (messages: readonly Message[]) => string;
11
28
  };
@@ -11,7 +11,6 @@ import { compactionCut, estimateTokens, summarize } from "./compaction.js";
11
11
  export function createNativeHarness(options) {
12
12
  return {
13
13
  id: "native",
14
- toolUse: "application",
15
14
  recovery: "history",
16
15
  async run(context) {
17
16
  const { runId } = context;
@@ -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":"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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 /**\n * The estimated request size a fold happens above.\n *\n * A budget, not a provider fact: it belongs below the input window of the\n * model that answers, with room for the turn that follows the fold. Folding\n * early spends a model call and hands the run a paraphrase of work the log\n * still holds in full; folding late risks the request a provider refuses.\n */\n maxInputTokens: number;\n /**\n * Who writes the summary. Defaults to the run's own model, so an\n * application that says nothing meets neither a second provider nor a\n * second credential.\n *\n * A cheaper one is right where the span being folded is long and reading it\n * back is all the work — this is not the reasoning the main model is being\n * paid for. It still has to take the whole span in one request, and to be\n * good enough that what it drops is what did not matter.\n */\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
- * Two facts, not eight. Everything the old capability matrix carried was either
118
- * optional output, a different subsystem, or something no consumer asked about:
119
- * a caller only ever needs to know whose tools run, and whether an unfinished
120
- * activation can restart from the log.
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 * Two facts, not eight. Everything the old capability matrix carried was either\n * optional output, a different subsystem, or something no consumer asked about:\n * a caller only ever needs to know whose tools run, and whether an unfinished\n * activation can restart from the log.\n */\nexport interface Harness {\n readonly id: string;\n /** \"application\": through the executor, validated and authorized. \"harness\": its own, which we never claim to have authorized. */\n readonly toolUse: \"application\" | \"harness\" | \"none\";\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"]}
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 end of the prefix can carry
148
- * a breakpoint. Only the last block is marked: a breakpoint caches everything
149
- * before it, so marking each one would buy nothing and spend the budget of four.
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 === blocks.length - 1 ? { cache_control: { type: "ephemeral" } } : {}),
172
+ ...(cache && marked.has(index) ? { cache_control: { type: "ephemeral" } } : {}),
156
173
  }));
157
174
  }
158
175
  /**