@a-dray/aglib 0.2.0 → 0.3.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.
- package/dist/agent.d.ts +4 -9
- package/dist/agent.js.map +1 -1
- package/dist/harness/adapters/native/compaction.d.ts +10 -2
- package/dist/harness/adapters/native/compaction.js +29 -1
- package/dist/harness/adapters/native/compaction.js.map +1 -1
- package/dist/harness/adapters/native/loop.d.ts +1 -25
- package/dist/harness/adapters/native/loop.js +9 -38
- package/dist/harness/adapters/native/loop.js.map +1 -1
- package/dist/harness/harness.d.ts +31 -2
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/index.d.ts +2 -1
- package/dist/harness/index.js +1 -0
- package/dist/harness/index.js.map +1 -1
- package/dist/model/adapters/openai-compatible/index.js +1 -1
- package/dist/model/adapters/openai-compatible/index.js.map +1 -1
- package/dist/render.d.ts +1 -1
- package/dist/render.js +9 -0
- package/dist/render.js.map +1 -1
- package/dist/run.js +73 -39
- package/dist/run.js.map +1 -1
- package/dist/session/entry.d.ts +5 -0
- package/dist/session/entry.js.map +1 -1
- package/dist/session/messages.js +3 -0
- package/dist/session/messages.js.map +1 -1
- package/package.json +1 -1
package/dist/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A run, as lines someone can read.\n *\n * A root file rather than a module, and a projection rather than a port: this\n * is `textOf` one level out. `toMessages` folds committed entries into what a\n * model is shown; this folds the update stream into what a person is shown. No\n * adapter has to prove anything about it, so there is nothing here for a\n * conformance suite to hold, and nothing below it to rank against.\n *\n * **It is not a channel, and the difference is worth stating because it is\n * subtle.** A channel does three jobs: decide which session a person is talking\n * to, deliver a message exactly once, and put the result in a medium's own\n * shape. The first two are an application's — a mail thread maps to a session,\n * a webhook may arrive twice. Only the third is the same work for every medium,\n * and only the third is here. Email is a channel with no projection at all: it\n * sends `RunResult.output` and never looks at the stream. A terminal is the\n * other extreme — its identity is \"the one session\" and its delivery is a pipe\n * that cannot fail, so a terminal channel is *nothing but* this projection.\n *\n * **The answer and the stream are different things, and only one is a message.**\n * `RunResult.output` is what `finished` hands to `Delivery.input`: the same\n * `Content`, whether the recipient is a person or another session. The stream\n * is not a message and never becomes one — a `cancelled` or `failed` result has\n * no `output` field at all, so a run can stream a paragraph and produce nothing\n * that could be delivered.\n *\n * Showing that paragraph is not a mistake. Watching what an agent was saying\n * when it was cancelled is most of what debugging one is. What would be a\n * mistake is leaving the outcome implicit, so the text reads as an answer that\n * was never given — which is why `finish` always states it, and takes it from\n * the result rather than from whatever happened to stream.\n *\n * **`detail` is the knob that makes one projection serve every medium.** Three\n * levels, because what the knob is graduated in is the *internal stream* and\n * not the conversation: a tool call is the agent talking to itself, while a\n * message arriving from a subagent, a peer or a person is the conversation\n * happening. The log keeps those apart — one is an entry the loop wrote, the\n * other came through `enqueue` — so the projection does too.\n *\n * There is no level below `\"minimal\"`, and there was one. A medium with no\n * second channel says so by having no `status`, which drops the account\n * entirely; a `detail` that meant the same thing was a second way to state a\n * fact the `Sink` already stated. Failures are not behind a level either — an\n * agent that silently did nothing is the one outcome a reader cannot diagnose\n * from what they were shown.\n *\n * Two channels out, because they answer different questions. `write` carries\n * the answer, so redirecting it captures the answer and nothing else. `status`\n * carries what the agent did on the way — tools, provenance, what it spent.\n */\nimport type { AgentRun, RunResult } from \"./agent.js\";\nimport type { Update } from \"./harness/harness.js\";\nimport type { Content, ContentPart } from \"./content.js\";\nimport type { Stored, ToolCall, Usage } from \"./session/entry.js\";\nimport { textOf } from \"./content.js\";\n\nexport interface Sink {\n /** The answer: assistant text, exactly as it streamed. */\n write(text: string): void;\n /**\n * Everything else: tools, provenance, what the run spent.\n *\n * Omit it and that account is **dropped**, not folded into `write`. Falling\n * back would break the one promise `write` makes — that it holds the answer\n * and nothing else — for every caller who only wanted the answer and did not\n * think to say so.\n */\n status?(line: string): void;\n /** Enables colour and the elapsed-time ticker. A caller without a terminal leaves it off. */\n tty?: boolean;\n /**\n * How much of the run to show.\n *\n * `\"minimal\"` is the conversation: the answer, input that arrived from\n * somewhere else, and anything that failed. `\"standard\"` adds the internal\n * stream — tool calls, their results, and what the run spent. `\"detailed\"`\n * adds what it was thinking, arguments as they form, and the structured\n * `details` a tool returned.\n *\n * For the answer and nothing whatever beside it, give a sink with no\n * `status`.\n */\n detail?: \"minimal\" | \"standard\" | \"detailed\";\n /**\n * Marks a run being watched rather than driven — a subagent taken off the\n * queue, most often. A labelled run has no answer channel: nobody asked it\n * anything, so everything it says is an account of what the run it belongs\n * to is doing, and all of it is prefixed and sent to `status`.\n */\n label?: string;\n /** Milliseconds, for durations. Supplied by a test so its output is exact. */\n now?(): number;\n}\n\n/**\n * Not exported, and that is the gate's doing rather than an oversight.\n *\n * `renderRun` is the whole of what a caller needs, and nothing here composes a\n * renderer by hand. A surface that pushes updates itself — an HTTP stream, a\n * Slack message it keeps editing — would want this, and it can be exported the\n * day one exists. Surface without a consumer is surface nobody is holding to\n * account.\n */\ninterface Renderer {\n update(update: Update): void;\n /** The outcome and what it spent. */\n finish(result: RunResult): void;\n}\n\n/**\n * The one animation, and it is data rather than a dependency.\n *\n * Braille dots because they are one column wide in every terminal that has the\n * font and degrade to boxes rather than to a broken layout in the ones that do\n * not. Written to `status`, so the answer channel stays something a pipe can\n * read.\n */\nconst SPINNER = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"] as const;\n\nconst DIM = \"\\x1b[2m\";\nconst RED = \"\\x1b[31m\";\nconst GREEN = \"\\x1b[32m\";\nconst RESET = \"\\x1b[0m\";\n\n/** One line, however long the thing being described is. */\nconst oneLine = (text: string, limit = 96): string => {\n const flat = text.replace(/\\s+/g, \" \").trim();\n return flat.length > limit ? `${flat.slice(0, limit - 1)}…` : flat;\n};\n\nconst round = (count: number): string =>\n count >= 1000 ? `${(count / 1000).toFixed(1)}k` : `${count}`;\n\nconst seconds = (ms: number): string => `${(ms / 1000).toFixed(1)}s`;\n\n/**\n * Content as the model sees it, plus a marker for every part it cannot.\n *\n * `textOf` drops images, files and opaque blocks, which is right for a model\n * and wrong for a person: a screen showing less than the log holds, silently,\n * is the omission this package refuses everywhere else.\n */\nfunction readable(content: Content): string {\n if (typeof content === \"string\") return content;\n return content.map((part: ContentPart) =>\n part.type === \"text\" ? part.text\n : part.type === \"image\" ? `[image ${part.mediaType}]`\n : part.type === \"file\" ? `[file ${part.name ?? part.mediaType}]`\n : `[opaque ${part.provider}]`).join(\"\\n\");\n}\n\nfunction createRenderer(sink: Sink): Renderer {\n const status = sink.status ?? (() => {});\n const detail = sink.detail ?? \"standard\";\n const debugging = detail === \"detailed\";\n /** The agent talking to its own tools, as opposed to the conversation. */\n const internal = debugging || detail === \"standard\";\n const now = sink.now ?? (() => Date.now());\n const label = sink.label ? `${sink.label} ` : \"\";\n const started = now();\n\n const dim = (text: string) => (sink.tty ? `${DIM}${text}${RESET}` : text);\n const mark = (glyph: string, bad: boolean) =>\n sink.tty ? `${bad ? RED : GREEN}${glyph}${RESET}` : glyph;\n\n /** Names by call id. A tool entry carries only the id; the assistant entry above holds the name. */\n const names = new Map<string, string>();\n /** When each call started, so a result can say how long it took. */\n const clocks = new Map<string, number>();\n /**\n * What has been streamed since the last assistant entry.\n *\n * The harnesses disagree about deltas — some stream tokens, some emit one\n * delta per whole message, and some emit none at all. The entry stream is\n * the one channel every harness fills, so\n * the entry decides what is shown and the deltas decide how much of it\n * already has been.\n *\n * The rule the port does not state, and this therefore does not assume:\n * deltas preceding an assistant entry *ought* to concatenate to its text.\n * Where they do, the remainder is printed and nothing appears twice. Where\n * they are absent, the whole entry is printed. Where they are neither — a\n * harness that streamed something else, or stopped halfway — the entry is\n * printed in full on a fresh line, because showing a reader the same words\n * twice is a smaller failure than silently dropping the half nobody streamed.\n */\n let streamed = \"\";\n let turns = 0;\n /** Whether the last thing written ended mid-line, so a status line can open a fresh one. */\n let open = false;\n let thinking = false;\n\n /**\n * The calls in flight, and the one status line describing all of them.\n *\n * One ticker for the renderer rather than one per call. A tool call is not\n * exclusive — a harness may start four at once, and Pi does — and a per-call\n * interval meant each `tool.started` overwrote the last without clearing it:\n * the orphans kept drawing to the same line for the life of the process,\n * fighting each other and interleaving with committed lines. A terminal has\n * one status line, so there is one thing drawing it.\n *\n * No `at` is kept here. `clocks` already holds when each call started, and a\n * second copy is a second answer.\n */\n const running = new Set<string>();\n let ticker: ReturnType<typeof setInterval> | undefined;\n /** Whether the status line currently holds a spinner that must be erased before anything else. */\n let drawn = false;\n\n /**\n * Erase the spinner, leaving the cursor at the start of a clean line.\n *\n * Called before *every* write, because `\\r` returns to the start of whatever\n * line is current and half a streamed sentence is as much a casualty as a\n * status line. The ticker redraws on its next tick if work is still in\n * flight, so this costs nothing but a frame.\n */\n const clearSpinner = () => {\n if (!drawn) return;\n drawn = false;\n status(\"\\r\\x1b[K\");\n };\n\n const line = (text: string) => {\n clearSpinner();\n if (open) { sink.write(\"\\n\"); open = false; }\n status(`${label}${text}\\n`);\n };\n\n const stopTicker = () => {\n if (ticker) { clearInterval(ticker); ticker = undefined; }\n clearSpinner();\n };\n\n /**\n * What is running, in the width of one line.\n *\n * The oldest call names itself and carries the clock, because it is the one a\n * reader is waiting on; the rest are a count. Naming all four would be a\n * line that changes width every time one finishes.\n */\n const inFlight = (glyph: string): string => {\n const oldest = [...running].sort((a, b) => (clocks.get(a) ?? 0) - (clocks.get(b) ?? 0))[0];\n if (oldest === undefined) return \"\";\n const name = names.get(oldest) ?? oldest.slice(0, 8);\n const others = running.size - 1;\n return `${label}${glyph} ${name}${others ? ` +${others}` : \"\"} ${seconds(now() - (clocks.get(oldest) ?? now()))}`;\n };\n\n /**\n * The one piece of cursor control in this file, and the only reason a long\n * command is not silence. Unref'd so it can never hold a process open.\n *\n * It does not draw over an open line: `say` leaves the cursor mid-sentence\n * while text streams, and `\\r` there would eat the sentence. Nothing is lost\n * — the next tick after the newline draws it.\n */\n const startTicker = () => {\n if (ticker || !sink.tty) return;\n let frame = 0;\n ticker = setInterval(() => {\n if (open || !running.size) return;\n const text = inFlight(SPINNER[frame++ % SPINNER.length]!);\n if (!text) return;\n drawn = true;\n status(`\\r${DIM}${text}${RESET}\\x1b[K`);\n }, 90);\n ticker.unref?.();\n };\n\n /** Partial line held back while a labelled run streams, so the prefix stays whole. */\n let held = \"\";\n\n /**\n * Write text for the reader. The primitive; `say` is the streaming door to it.\n *\n * Only a delta counts as *streamed*. An entry printed through here must not\n * be added to `streamed`, or its own words become the \"already shown\" prefix\n * the next entry is measured against — and since a second turn's text does\n * not begin with a first turn's, `startsWith` failed and the whole turn was\n * printed again under the half that had already streamed.\n */\n const emit = (text: string) => {\n clearSpinner();\n if (thinking) { thinking = false; }\n if (!sink.label) {\n sink.write(text);\n open = !text.endsWith(\"\\n\");\n return;\n }\n // A prefix cannot be applied to half a line, so a labelled run buffers to\n // the newline. Nothing is lost: `finish` flushes whatever is left.\n held += text;\n let cut = held.indexOf(\"\\n\");\n while (cut !== -1) {\n line(held.slice(0, cut));\n held = held.slice(cut + 1);\n cut = held.indexOf(\"\\n\");\n }\n };\n\n /** A delta: written, and recorded as the part of the coming entry already shown. */\n const say = (text: string) => { streamed += text; emit(text); };\n\n const entry = (stored: Stored) => {\n if (stored.type === \"run.started\") {\n // Input with no `from` is what the caller just passed in. Echoing it says\n // everything twice. Input *with* one came from somewhere else — a\n // subagent's report, a peer, a person on a channel — and saying so is the\n // only way that arrival is visible as itself.\n if (stored.from) {\n line(dim(`◦ from ${stored.from.kind} ${stored.from.id.slice(0, 8)} · ${oneLine(readable(stored.input), 72)}`));\n }\n return;\n }\n if (stored.type === \"assistant\") {\n turns += 1;\n const said = readable(stored.content);\n if (said) {\n const shown = streamed;\n // Cleared first: `say` appends to it, and what matters is what had been\n // streamed *before* this entry arrived.\n streamed = \"\";\n if (!shown) emit(said.endsWith(\"\\n\") ? said : `${said}\\n`);\n else if (said.startsWith(shown)) {\n const rest = said.slice(shown.length);\n if (rest) emit(rest.endsWith(\"\\n\") ? rest : `${rest}\\n`);\n else if (open) emit(\"\\n\");\n } else {\n if (open) sink.write(\"\\n\");\n emit(said.endsWith(\"\\n\") ? said : `${said}\\n`);\n }\n } else {\n streamed = \"\";\n }\n for (const call of stored.calls ?? []) {\n // The name is recorded whatever the level: a result rendered later\n // reads it, and a reader who turns detail up mid-run should not meet a\n // call id where every other line has a name.\n names.set(call.callId, call.name);\n if (internal) line(dim(`→ ${call.name} ${oneLine(call.arguments, 72)}`));\n }\n return;\n }\n if (stored.type === \"tool.started\") {\n clocks.set(stored.callId, now());\n // At every level, unlike everything else about a call. A spinner is not\n // an account of what the agent did — it leaves no trace, and it is the\n // only thing between a reader and thirty seconds of silence.\n running.add(stored.callId);\n startTicker();\n return;\n }\n if (stored.type === \"tool.finished\") {\n running.delete(stored.callId);\n if (!running.size) stopTicker();\n const at = clocks.get(stored.callId);\n clocks.delete(stored.callId);\n const name = names.get(stored.callId) ?? stored.callId.slice(0, 8);\n const took = at === undefined ? \"\" : ` · ${seconds(now() - at)}`;\n const body = oneLine(readable(stored.result.content), 64);\n const failed = stored.result.isError === true;\n // A success is the agent working; a failure is something the reader has\n // to know about whatever they asked to be shown.\n if (failed || internal) {\n line(`${mark(failed ? \"✗\" : \"✓\", failed)} ${dim(`${name}${took}${body ? ` · ${body}` : \"\"}`)}`);\n }\n // `details` is the structured channel for an application's own UI and\n // holds whatever that application put there — which may include a\n // credential. Asked for explicitly it is shown; it is never volunteered.\n if (debugging && stored.result.details !== undefined) {\n line(dim(` ${oneLine(JSON.stringify(stored.result.details), 96)}`));\n }\n return;\n }\n if (stored.type === \"summary\") {\n if (internal) line(dim(`· compacted through seq ${stored.replaces}`));\n }\n // `run.finished` is not rendered here. `finish` owns the last line, because\n // `RunResult` carries what the entry cannot: what the run spent, on every\n // outcome including the ones with no answer.\n };\n\n return {\n update(next) {\n if (next.type === \"text.delta\") { say(next.text); return; }\n if (next.type === \"reasoning.delta\") {\n // Reasoning can outweigh the answer several times over, so it is behind\n // `\"detailed\"` rather than dimmed and always present.\n if (!debugging) return;\n if (!thinking) { line(dim(\"· thinking\")); thinking = true; }\n clearSpinner();\n status(dim(next.text));\n return;\n }\n // A harness that reports progress reports it several times per call, in\n // whatever shape its protocol happens to use — ACP forwards its whole\n // `session/update`. That is a debugging channel, not a reading one: the\n // call itself is announced by the entry that carries it, and the name is\n // not even known yet on the first of these. So it sits behind `\"detailed\"`\n // beside `tool-call.delta`, for the same reason.\n if (next.type === \"tool.progress\") {\n if (!debugging) return;\n const name = names.get(next.callId) ?? next.callId.slice(0, 8);\n line(dim(`⋯ ${name} ${oneLine(JSON.stringify(next.data), 64)}`));\n return;\n }\n // Arguments as they form are unparseable until complete and only one\n // harness emits them, so they are worth nothing to a reader and\n // everything to someone asking why a call came out the way it did.\n if (next.type === \"tool-call.delta\") {\n if (debugging) line(dim(` ${next.callId.slice(0, 8)} ${oneLine(next.arguments, 64)}`));\n return;\n }\n if (next.type === \"entry\") entry(next.entry);\n },\n\n finish(result) {\n running.clear();\n stopTicker();\n if (held) { line(held); held = \"\"; }\n if (open) { sink.write(\"\\n\"); open = false; }\n\n const spent = [\n result.usage.inputTokens !== undefined ? `${round(result.usage.inputTokens)} in` : undefined,\n result.usage.cacheReadTokens ? `${round(result.usage.cacheReadTokens)} cached` : undefined,\n result.usage.outputTokens !== undefined ? `${round(result.usage.outputTokens)} out` : undefined,\n ].filter((part): part is string => part !== undefined);\n\n // A count nobody reported is not a zero, so an absent one is left out\n // rather than printed as 0.\n const parts = [\n seconds(now() - started),\n `${turns} ${turns === 1 ? \"turn\" : \"turns\"}`,\n ...spent,\n ].join(\" · \");\n\n if (result.status === \"failed\") {\n line(`${mark(\"✗\", true)} ${dim(`failed (${result.error.code}): ${oneLine(result.error.message, 80)} · ${parts}`)}`);\n return;\n }\n // `cancelled` is an ending nobody asked for, so it is said at every\n // level that says anything. A clean completion is an accounting line.\n if (result.status === \"cancelled\" || internal) line(dim(`— ${result.status} · ${parts}`));\n },\n };\n}\n\n/**\n * Render a run to its end, and answer what it did.\n *\n * The loop every application writes by hand, with the two things a hand-written\n * one keeps getting wrong: everything the stream carries besides text, and an\n * outcome taken from the result rather than from whatever happened to stream.\n */\nexport async function renderRun(run: AgentRun, sink: Sink): Promise<RunResult> {\n const renderer = createRenderer(sink);\n for await (const update of run) renderer.update(update);\n const result = await run.result;\n renderer.finish(result);\n return result;\n}\n\n/** Re-exported so a caller composing a sink imports one thing. */\nexport type { Update, RunResult, Usage, ToolCall };\n"]}
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A run, as lines someone can read.\n *\n * A root file rather than a module, and a projection rather than a port: this\n * is `textOf` one level out. `toMessages` folds committed entries into what a\n * model is shown; this folds the update stream into what a person is shown. No\n * adapter has to prove anything about it, so there is nothing here for a\n * conformance suite to hold, and nothing below it to rank against.\n *\n * **It is not a channel, and the difference is worth stating because it is\n * subtle.** A channel does three jobs: decide which session a person is talking\n * to, deliver a message exactly once, and put the result in a medium's own\n * shape. The first two are an application's — a mail thread maps to a session,\n * a webhook may arrive twice. Only the third is the same work for every medium,\n * and only the third is here. Email is a channel with no projection at all: it\n * sends `RunResult.output` and never looks at the stream. A terminal is the\n * other extreme — its identity is \"the one session\" and its delivery is a pipe\n * that cannot fail, so a terminal channel is *nothing but* this projection.\n *\n * **The answer and the stream are different things, and only one is a message.**\n * `RunResult.output` is what `beforeStop` hands to `Delivery.input`: the same\n * `Content`, whether the recipient is a person or another session. The stream\n * is not a message and never becomes one — a `cancelled` or `failed` result has\n * no `output` field at all, so a run can stream a paragraph and produce nothing\n * that could be delivered.\n *\n * Showing that paragraph is not a mistake. Watching what an agent was saying\n * when it was cancelled is most of what debugging one is. What would be a\n * mistake is leaving the outcome implicit, so the text reads as an answer that\n * was never given — which is why `finish` always states it, and takes it from\n * the result rather than from whatever happened to stream.\n *\n * **`detail` is the knob that makes one projection serve every medium.** Three\n * levels, because what the knob is graduated in is the *internal stream* and\n * not the conversation: a tool call is the agent talking to itself, while a\n * message arriving from a subagent, a peer or a person is the conversation\n * happening. The log keeps those apart — one is an entry the loop wrote, the\n * other came through `enqueue` — so the projection does too.\n *\n * There is no level below `\"minimal\"`, and there was one. A medium with no\n * second channel says so by having no `status`, which drops the account\n * entirely; a `detail` that meant the same thing was a second way to state a\n * fact the `Sink` already stated. Failures are not behind a level either — an\n * agent that silently did nothing is the one outcome a reader cannot diagnose\n * from what they were shown.\n *\n * Two channels out, because they answer different questions. `write` carries\n * the answer, so redirecting it captures the answer and nothing else. `status`\n * carries what the agent did on the way — tools, provenance, what it spent.\n */\nimport type { AgentRun, RunResult } from \"./agent.js\";\nimport type { Update } from \"./harness/harness.js\";\nimport type { Content, ContentPart } from \"./content.js\";\nimport type { Stored, ToolCall, Usage } from \"./session/entry.js\";\nimport { textOf } from \"./content.js\";\n\nexport interface Sink {\n /** The answer: assistant text, exactly as it streamed. */\n write(text: string): void;\n /**\n * Everything else: tools, provenance, what the run spent.\n *\n * Omit it and that account is **dropped**, not folded into `write`. Falling\n * back would break the one promise `write` makes — that it holds the answer\n * and nothing else — for every caller who only wanted the answer and did not\n * think to say so.\n */\n status?(line: string): void;\n /** Enables colour and the elapsed-time ticker. A caller without a terminal leaves it off. */\n tty?: boolean;\n /**\n * How much of the run to show.\n *\n * `\"minimal\"` is the conversation: the answer, input that arrived from\n * somewhere else, and anything that failed. `\"standard\"` adds the internal\n * stream — tool calls, their results, and what the run spent. `\"detailed\"`\n * adds what it was thinking, arguments as they form, and the structured\n * `details` a tool returned.\n *\n * For the answer and nothing whatever beside it, give a sink with no\n * `status`.\n */\n detail?: \"minimal\" | \"standard\" | \"detailed\";\n /**\n * Marks a run being watched rather than driven — a subagent taken off the\n * queue, most often. A labelled run has no answer channel: nobody asked it\n * anything, so everything it says is an account of what the run it belongs\n * to is doing, and all of it is prefixed and sent to `status`.\n */\n label?: string;\n /** Milliseconds, for durations. Supplied by a test so its output is exact. */\n now?(): number;\n}\n\n/**\n * Not exported, and that is the gate's doing rather than an oversight.\n *\n * `renderRun` is the whole of what a caller needs, and nothing here composes a\n * renderer by hand. A surface that pushes updates itself — an HTTP stream, a\n * Slack message it keeps editing — would want this, and it can be exported the\n * day one exists. Surface without a consumer is surface nobody is holding to\n * account.\n */\ninterface Renderer {\n update(update: Update): void;\n /** The outcome and what it spent. */\n finish(result: RunResult): void;\n}\n\n/**\n * The one animation, and it is data rather than a dependency.\n *\n * Braille dots because they are one column wide in every terminal that has the\n * font and degrade to boxes rather than to a broken layout in the ones that do\n * not. Written to `status`, so the answer channel stays something a pipe can\n * read.\n */\nconst SPINNER = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"] as const;\n\nconst DIM = \"\\x1b[2m\";\nconst RED = \"\\x1b[31m\";\nconst GREEN = \"\\x1b[32m\";\nconst RESET = \"\\x1b[0m\";\n\n/** One line, however long the thing being described is. */\nconst oneLine = (text: string, limit = 96): string => {\n const flat = text.replace(/\\s+/g, \" \").trim();\n return flat.length > limit ? `${flat.slice(0, limit - 1)}…` : flat;\n};\n\nconst round = (count: number): string =>\n count >= 1000 ? `${(count / 1000).toFixed(1)}k` : `${count}`;\n\nconst seconds = (ms: number): string => `${(ms / 1000).toFixed(1)}s`;\n\n/**\n * Content as the model sees it, plus a marker for every part it cannot.\n *\n * `textOf` drops images, files and opaque blocks, which is right for a model\n * and wrong for a person: a screen showing less than the log holds, silently,\n * is the omission this package refuses everywhere else.\n */\nfunction readable(content: Content): string {\n if (typeof content === \"string\") return content;\n return content.map((part: ContentPart) =>\n part.type === \"text\" ? part.text\n : part.type === \"image\" ? `[image ${part.mediaType}]`\n : part.type === \"file\" ? `[file ${part.name ?? part.mediaType}]`\n : `[opaque ${part.provider}]`).join(\"\\n\");\n}\n\nfunction createRenderer(sink: Sink): Renderer {\n const status = sink.status ?? (() => {});\n const detail = sink.detail ?? \"standard\";\n const debugging = detail === \"detailed\";\n /** The agent talking to its own tools, as opposed to the conversation. */\n const internal = debugging || detail === \"standard\";\n const now = sink.now ?? (() => Date.now());\n const label = sink.label ? `${sink.label} ` : \"\";\n const started = now();\n\n const dim = (text: string) => (sink.tty ? `${DIM}${text}${RESET}` : text);\n const mark = (glyph: string, bad: boolean) =>\n sink.tty ? `${bad ? RED : GREEN}${glyph}${RESET}` : glyph;\n\n /** Names by call id. A tool entry carries only the id; the assistant entry above holds the name. */\n const names = new Map<string, string>();\n /** When each call started, so a result can say how long it took. */\n const clocks = new Map<string, number>();\n /**\n * What has been streamed since the last assistant entry.\n *\n * The harnesses disagree about deltas — some stream tokens, some emit one\n * delta per whole message, and some emit none at all. The entry stream is\n * the one channel every harness fills, so\n * the entry decides what is shown and the deltas decide how much of it\n * already has been.\n *\n * The rule the port does not state, and this therefore does not assume:\n * deltas preceding an assistant entry *ought* to concatenate to its text.\n * Where they do, the remainder is printed and nothing appears twice. Where\n * they are absent, the whole entry is printed. Where they are neither — a\n * harness that streamed something else, or stopped halfway — the entry is\n * printed in full on a fresh line, because showing a reader the same words\n * twice is a smaller failure than silently dropping the half nobody streamed.\n */\n let streamed = \"\";\n let turns = 0;\n /** Whether the last thing written ended mid-line, so a status line can open a fresh one. */\n let open = false;\n let thinking = false;\n\n /**\n * The calls in flight, and the one status line describing all of them.\n *\n * One ticker for the renderer rather than one per call. A tool call is not\n * exclusive — a harness may start four at once, and Pi does — and a per-call\n * interval meant each `tool.started` overwrote the last without clearing it:\n * the orphans kept drawing to the same line for the life of the process,\n * fighting each other and interleaving with committed lines. A terminal has\n * one status line, so there is one thing drawing it.\n *\n * No `at` is kept here. `clocks` already holds when each call started, and a\n * second copy is a second answer.\n */\n const running = new Set<string>();\n let ticker: ReturnType<typeof setInterval> | undefined;\n /** Whether the status line currently holds a spinner that must be erased before anything else. */\n let drawn = false;\n\n /**\n * Erase the spinner, leaving the cursor at the start of a clean line.\n *\n * Called before *every* write, because `\\r` returns to the start of whatever\n * line is current and half a streamed sentence is as much a casualty as a\n * status line. The ticker redraws on its next tick if work is still in\n * flight, so this costs nothing but a frame.\n */\n const clearSpinner = () => {\n if (!drawn) return;\n drawn = false;\n status(\"\\r\\x1b[K\");\n };\n\n const line = (text: string) => {\n clearSpinner();\n if (open) { sink.write(\"\\n\"); open = false; }\n status(`${label}${text}\\n`);\n };\n\n const stopTicker = () => {\n if (ticker) { clearInterval(ticker); ticker = undefined; }\n clearSpinner();\n };\n\n /**\n * What is running, in the width of one line.\n *\n * The oldest call names itself and carries the clock, because it is the one a\n * reader is waiting on; the rest are a count. Naming all four would be a\n * line that changes width every time one finishes.\n */\n const inFlight = (glyph: string): string => {\n const oldest = [...running].sort((a, b) => (clocks.get(a) ?? 0) - (clocks.get(b) ?? 0))[0];\n if (oldest === undefined) return \"\";\n const name = names.get(oldest) ?? oldest.slice(0, 8);\n const others = running.size - 1;\n return `${label}${glyph} ${name}${others ? ` +${others}` : \"\"} ${seconds(now() - (clocks.get(oldest) ?? now()))}`;\n };\n\n /**\n * The one piece of cursor control in this file, and the only reason a long\n * command is not silence. Unref'd so it can never hold a process open.\n *\n * It does not draw over an open line: `say` leaves the cursor mid-sentence\n * while text streams, and `\\r` there would eat the sentence. Nothing is lost\n * — the next tick after the newline draws it.\n */\n const startTicker = () => {\n if (ticker || !sink.tty) return;\n let frame = 0;\n ticker = setInterval(() => {\n if (open || !running.size) return;\n const text = inFlight(SPINNER[frame++ % SPINNER.length]!);\n if (!text) return;\n drawn = true;\n status(`\\r${DIM}${text}${RESET}\\x1b[K`);\n }, 90);\n ticker.unref?.();\n };\n\n /** Partial line held back while a labelled run streams, so the prefix stays whole. */\n let held = \"\";\n\n /**\n * Write text for the reader. The primitive; `say` is the streaming door to it.\n *\n * Only a delta counts as *streamed*. An entry printed through here must not\n * be added to `streamed`, or its own words become the \"already shown\" prefix\n * the next entry is measured against — and since a second turn's text does\n * not begin with a first turn's, `startsWith` failed and the whole turn was\n * printed again under the half that had already streamed.\n */\n const emit = (text: string) => {\n clearSpinner();\n if (thinking) { thinking = false; }\n if (!sink.label) {\n sink.write(text);\n open = !text.endsWith(\"\\n\");\n return;\n }\n // A prefix cannot be applied to half a line, so a labelled run buffers to\n // the newline. Nothing is lost: `finish` flushes whatever is left.\n held += text;\n let cut = held.indexOf(\"\\n\");\n while (cut !== -1) {\n line(held.slice(0, cut));\n held = held.slice(cut + 1);\n cut = held.indexOf(\"\\n\");\n }\n };\n\n /** A delta: written, and recorded as the part of the coming entry already shown. */\n const say = (text: string) => { streamed += text; emit(text); };\n\n const entry = (stored: Stored) => {\n if (stored.type === \"hook.input\") {\n if (debugging) line(dim(`◦ ${stored.hook} · ${oneLine(readable(stored.input), 72)}`));\n return;\n }\n if (stored.type === \"run.started\") {\n // Input with no `from` is what the caller just passed in. Echoing it says\n // everything twice. Input *with* one came from somewhere else — a\n // subagent's report, a peer, a person on a channel — and saying so is the\n // only way that arrival is visible as itself.\n if (stored.from) {\n line(dim(`◦ from ${stored.from.kind} ${stored.from.id.slice(0, 8)} · ${oneLine(readable(stored.input), 72)}`));\n }\n return;\n }\n if (stored.type === \"assistant\") {\n turns += 1;\n const said = readable(stored.content);\n if (said) {\n const shown = streamed;\n // Cleared first: `say` appends to it, and what matters is what had been\n // streamed *before* this entry arrived.\n streamed = \"\";\n if (!shown) emit(said.endsWith(\"\\n\") ? said : `${said}\\n`);\n else if (said.startsWith(shown)) {\n const rest = said.slice(shown.length);\n if (rest) emit(rest.endsWith(\"\\n\") ? rest : `${rest}\\n`);\n else if (open) emit(\"\\n\");\n } else {\n if (open) sink.write(\"\\n\");\n emit(said.endsWith(\"\\n\") ? said : `${said}\\n`);\n }\n } else {\n streamed = \"\";\n }\n for (const call of stored.calls ?? []) {\n // The name is recorded whatever the level: a result rendered later\n // reads it, and a reader who turns detail up mid-run should not meet a\n // call id where every other line has a name.\n names.set(call.callId, call.name);\n if (internal) line(dim(`→ ${call.name} ${oneLine(call.arguments, 72)}`));\n }\n return;\n }\n if (stored.type === \"tool.started\") {\n clocks.set(stored.callId, now());\n // At every level, unlike everything else about a call. A spinner is not\n // an account of what the agent did — it leaves no trace, and it is the\n // only thing between a reader and thirty seconds of silence.\n running.add(stored.callId);\n startTicker();\n return;\n }\n if (stored.type === \"tool.finished\") {\n running.delete(stored.callId);\n if (!running.size) stopTicker();\n const at = clocks.get(stored.callId);\n clocks.delete(stored.callId);\n const name = names.get(stored.callId) ?? stored.callId.slice(0, 8);\n const took = at === undefined ? \"\" : ` · ${seconds(now() - at)}`;\n const body = oneLine(readable(stored.result.content), 64);\n const failed = stored.result.isError === true;\n // A success is the agent working; a failure is something the reader has\n // to know about whatever they asked to be shown.\n if (failed || internal) {\n line(`${mark(failed ? \"✗\" : \"✓\", failed)} ${dim(`${name}${took}${body ? ` · ${body}` : \"\"}`)}`);\n }\n // `details` is the structured channel for an application's own UI and\n // holds whatever that application put there — which may include a\n // credential. Asked for explicitly it is shown; it is never volunteered.\n if (debugging && stored.result.details !== undefined) {\n line(dim(` ${oneLine(JSON.stringify(stored.result.details), 96)}`));\n }\n return;\n }\n if (stored.type === \"summary\") {\n if (internal) line(dim(`· compacted through seq ${stored.replaces}`));\n }\n // `run.finished` is not rendered here. `finish` owns the last line, because\n // `RunResult` carries what the entry cannot: what the run spent, on every\n // outcome including the ones with no answer.\n };\n\n return {\n update(next) {\n if (next.type === \"hook.error\") { line(`Hook ${next.hook}: ${next.message}`); return; }\n if (next.type === \"text.delta\") { say(next.text); return; }\n if (next.type === \"reasoning.delta\") {\n // Reasoning can outweigh the answer several times over, so it is behind\n // `\"detailed\"` rather than dimmed and always present.\n if (!debugging) return;\n if (!thinking) { line(dim(\"· thinking\")); thinking = true; }\n clearSpinner();\n status(dim(next.text));\n return;\n }\n // A harness that reports progress reports it several times per call, in\n // whatever shape its protocol happens to use — ACP forwards its whole\n // `session/update`. That is a debugging channel, not a reading one: the\n // call itself is announced by the entry that carries it, and the name is\n // not even known yet on the first of these. So it sits behind `\"detailed\"`\n // beside `tool-call.delta`, for the same reason.\n if (next.type === \"tool.progress\") {\n if (!debugging) return;\n const name = names.get(next.callId) ?? next.callId.slice(0, 8);\n line(dim(`⋯ ${name} ${oneLine(JSON.stringify(next.data), 64)}`));\n return;\n }\n // Arguments as they form are unparseable until complete and only one\n // harness emits them, so they are worth nothing to a reader and\n // everything to someone asking why a call came out the way it did.\n if (next.type === \"tool-call.delta\") {\n if (debugging) line(dim(` ${next.callId.slice(0, 8)} ${oneLine(next.arguments, 64)}`));\n return;\n }\n if (next.type === \"entry\") entry(next.entry);\n },\n\n finish(result) {\n running.clear();\n stopTicker();\n if (held) { line(held); held = \"\"; }\n if (open) { sink.write(\"\\n\"); open = false; }\n\n const spent = [\n result.usage.inputTokens !== undefined ? `${round(result.usage.inputTokens)} in` : undefined,\n result.usage.cacheReadTokens ? `${round(result.usage.cacheReadTokens)} cached` : undefined,\n result.usage.outputTokens !== undefined ? `${round(result.usage.outputTokens)} out` : undefined,\n ].filter((part): part is string => part !== undefined);\n\n // A count nobody reported is not a zero, so an absent one is left out\n // rather than printed as 0.\n const parts = [\n seconds(now() - started),\n `${turns} ${turns === 1 ? \"turn\" : \"turns\"}`,\n ...spent,\n ].join(\" · \");\n\n if (result.status === \"failed\") {\n line(`${mark(\"✗\", true)} ${dim(`failed (${result.error.code}): ${oneLine(result.error.message, 80)} · ${parts}`)}`);\n return;\n }\n // `cancelled` is an ending nobody asked for, so it is said at every\n // level that says anything. A clean completion is an accounting line.\n if (result.status === \"cancelled\" || internal) line(dim(`— ${result.status} · ${parts}`));\n },\n };\n}\n\n/**\n * Render a run to its end, and answer what it did.\n *\n * The loop every application writes by hand, with the two things a hand-written\n * one keeps getting wrong: everything the stream carries besides text, and an\n * outcome taken from the result rather than from whatever happened to stream.\n */\nexport async function renderRun(run: AgentRun, sink: Sink): Promise<RunResult> {\n const renderer = createRenderer(sink);\n for await (const update of run) renderer.update(update);\n const result = await run.result;\n renderer.finish(result);\n return result;\n}\n\n/** Re-exported so a caller composing a sink imports one thing. */\nexport type { Update, RunResult, Usage, ToolCall };\n"]}
|
package/dist/run.js
CHANGED
|
@@ -12,6 +12,10 @@ import { createExecutor } from "./tools/execute.js";
|
|
|
12
12
|
*/
|
|
13
13
|
export function runAgent(options) {
|
|
14
14
|
// A claim names its own session; a caller sending into a new one names none.
|
|
15
|
+
const hooks = options.agent.hooks ?? [];
|
|
16
|
+
if (new Set(hooks.map(hook => hook.name)).size !== hooks.length || hooks.some(hook => !hook.name)) {
|
|
17
|
+
throw new Error("Lifecycle hook names must be non-empty and unique.");
|
|
18
|
+
}
|
|
15
19
|
const claim = options.claim;
|
|
16
20
|
const sessionId = claim?.sessionId ?? options.sessionId ?? crypto.randomUUID();
|
|
17
21
|
const controller = new AbortController();
|
|
@@ -35,6 +39,8 @@ export function runAgent(options) {
|
|
|
35
39
|
// we own and a loop we do not — and so a run that failed still says what it
|
|
36
40
|
// burned on the way there.
|
|
37
41
|
const usage = {};
|
|
42
|
+
let hookContext;
|
|
43
|
+
let result;
|
|
38
44
|
try {
|
|
39
45
|
const { agent, store } = options;
|
|
40
46
|
const restored = store ? await open(store, sessionId, agent, options.key) : undefined;
|
|
@@ -47,7 +53,7 @@ export function runAgent(options) {
|
|
|
47
53
|
// The store's own position, not the last entry's. They agree only while
|
|
48
54
|
// nothing has ever been folded away, and the store is the one that knows.
|
|
49
55
|
const log = createLog(restored?.value.entries ?? [], restored?.value.seq ?? 0);
|
|
50
|
-
const stopping = (error) => ({ status: "failed", error, seq: log.seq, usage });
|
|
56
|
+
const stopping = (error) => (result = { status: "failed", error, seq: log.seq, usage });
|
|
51
57
|
// A claim was read at a position. If the session has moved since, this
|
|
52
58
|
// worker lost, and the deliveries it was carrying are still where it
|
|
53
59
|
// found them.
|
|
@@ -155,27 +161,6 @@ export function runAgent(options) {
|
|
|
155
161
|
controller.abort();
|
|
156
162
|
}
|
|
157
163
|
}
|
|
158
|
-
/**
|
|
159
|
-
* What the agent wants delivered as this run ends.
|
|
160
|
-
*
|
|
161
|
-
* A callback that throws must not cost the log its terminal entry: the
|
|
162
|
-
* run would stay open, and an open run nothing closes is claimed by
|
|
163
|
-
* `interrupted` every window for ever — the trap the no-recovery path above
|
|
164
|
-
* exists to close. So the throw is held, the run is ended without the
|
|
165
|
-
* deliveries, and it is re-thrown once the log is safe.
|
|
166
|
-
*/
|
|
167
|
-
let reportFailure;
|
|
168
|
-
async function reporting(run) {
|
|
169
|
-
if (!agent.finished)
|
|
170
|
-
return [];
|
|
171
|
-
try {
|
|
172
|
-
return await agent.finished({ sessionId, ...run });
|
|
173
|
-
}
|
|
174
|
-
catch (error) {
|
|
175
|
-
reportFailure = error;
|
|
176
|
-
return [];
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
164
|
// Input that arrived while this activation was running, taken from the
|
|
180
165
|
// front of the queue and committed as part of it. `takePending` removes
|
|
181
166
|
// exactly what was committed, in the same write, so losing the position
|
|
@@ -233,12 +218,7 @@ export function runAgent(options) {
|
|
|
233
218
|
message: `The ${agent.harness.id} harness cannot restart from history, so this activation cannot be continued.`,
|
|
234
219
|
retryable: false,
|
|
235
220
|
};
|
|
236
|
-
|
|
237
|
-
// parent expecting a child that can now never report is the same dead
|
|
238
|
-
// end one layer up.
|
|
239
|
-
const told = await reporting({ runId: interrupted, outcome: "failed", output: "" });
|
|
240
|
-
await commit([{ type: "run.finished", runId: interrupted, outcome: "failed", error: failure }], told);
|
|
241
|
-
return stopping(failure);
|
|
221
|
+
stopped = failure;
|
|
242
222
|
}
|
|
243
223
|
}
|
|
244
224
|
// An interrupted predecessor is ended before a new activation begins over
|
|
@@ -268,9 +248,8 @@ export function runAgent(options) {
|
|
|
268
248
|
// passed was never seen. Checked once here too, before the harness is
|
|
269
249
|
// handed anything.
|
|
270
250
|
stopped ??= exceeded();
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
: await agent.harness.run({
|
|
251
|
+
function makeContext() {
|
|
252
|
+
return {
|
|
274
253
|
sessionId, runId,
|
|
275
254
|
instructions: agent.instructions,
|
|
276
255
|
history: () => toMessages({
|
|
@@ -285,34 +264,89 @@ export function runAgent(options) {
|
|
|
285
264
|
commit: (entries) => commit(entries),
|
|
286
265
|
...(store ? { drain } : {}),
|
|
287
266
|
emit: (update) => updates.push(update),
|
|
288
|
-
signal,
|
|
289
|
-
}
|
|
267
|
+
signal, hooks,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
async function stoppingHooks(outcome) {
|
|
271
|
+
const inputs = [];
|
|
272
|
+
const outgoing = [];
|
|
273
|
+
for (const hook of hooks) {
|
|
274
|
+
const response = await hook.beforeStop?.(hookContext, outcome);
|
|
275
|
+
if (response && "input" in response && outcome.status === "completed" && !signal.aborted && !stopped &&
|
|
276
|
+
!log.entries.some(entry => entry.type === "hook.input" && entry.runId === runId && entry.hook === hook.name)) {
|
|
277
|
+
inputs.push({ type: "hook.input", runId, hook: hook.name, input: response.input });
|
|
278
|
+
}
|
|
279
|
+
if (response && "deliveries" in response)
|
|
280
|
+
outgoing.push(...response.deliveries);
|
|
281
|
+
}
|
|
282
|
+
return { inputs, deliveries: outgoing };
|
|
283
|
+
}
|
|
284
|
+
hookContext = makeContext();
|
|
285
|
+
let outcome;
|
|
286
|
+
let outgoing = [];
|
|
287
|
+
try {
|
|
288
|
+
for (const hook of hooks)
|
|
289
|
+
await hook.beforeRun?.(hookContext);
|
|
290
|
+
for (;;) {
|
|
291
|
+
outcome = stopped ? { status: "failed", error: stopped }
|
|
292
|
+
: signal.aborted ? { status: "cancelled" }
|
|
293
|
+
: await agent.harness.run(hookContext);
|
|
294
|
+
if (stopped)
|
|
295
|
+
outcome = { status: "failed", error: stopped };
|
|
296
|
+
else if (signal.aborted)
|
|
297
|
+
outcome = { status: "cancelled" };
|
|
298
|
+
const ending = await stoppingHooks(outcome);
|
|
299
|
+
if (!ending.inputs.length) {
|
|
300
|
+
outgoing = ending.deliveries;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
await commit(ending.inputs);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
if (error instanceof CommitFailed)
|
|
308
|
+
throw error;
|
|
309
|
+
outcome = { status: "failed", error: {
|
|
310
|
+
code: "hook-or-harness", message: error instanceof Error ? error.message : String(error), retryable: false,
|
|
311
|
+
} };
|
|
312
|
+
}
|
|
290
313
|
// A harness stopped by the ceiling reports a cancellation, because that is
|
|
291
314
|
// all it saw. The run knows why it was cancelled and says so instead.
|
|
292
315
|
const settled = stopped && outcome.status === "cancelled"
|
|
293
316
|
? { status: "failed", error: stopped }
|
|
294
317
|
: outcome;
|
|
295
|
-
const output = settled.status === "completed" ? settled.output : "";
|
|
296
|
-
const finished = await reporting({ runId, outcome: settled.status, output });
|
|
297
318
|
await commit([{
|
|
298
319
|
type: "run.finished", runId,
|
|
299
320
|
outcome: settled.status === "completed" ? "completed" : settled.status === "cancelled" ? "cancelled" : "failed",
|
|
300
321
|
...(settled.status === "failed" ? { error: settled.error } : {}),
|
|
301
|
-
}],
|
|
322
|
+
}], outgoing);
|
|
302
323
|
if (settled.status === "completed") {
|
|
303
|
-
return { status: "completed", output: settled.output, seq: log.seq, usage };
|
|
324
|
+
return result = { status: "completed", output: settled.output, seq: log.seq, usage };
|
|
304
325
|
}
|
|
305
326
|
if (settled.status === "cancelled")
|
|
306
|
-
return { status: "cancelled", seq: log.seq, usage };
|
|
327
|
+
return result = { status: "cancelled", seq: log.seq, usage };
|
|
307
328
|
return stopping(settled.error);
|
|
308
329
|
}
|
|
309
330
|
catch (error) {
|
|
310
331
|
if (error instanceof CommitFailed) {
|
|
311
|
-
return { status: "failed", error: error.failure, seq: error.seq, usage };
|
|
332
|
+
return result = { status: "failed", error: error.failure, seq: error.seq, usage };
|
|
312
333
|
}
|
|
313
334
|
throw error;
|
|
314
335
|
}
|
|
315
336
|
finally {
|
|
337
|
+
if (hookContext) {
|
|
338
|
+
const final = result ?? { status: "failed", error: {
|
|
339
|
+
code: "run-error", message: "The run could not finish.", retryable: false,
|
|
340
|
+
}, seq: hookContext.entries().at(-1)?.seq ?? 0, usage };
|
|
341
|
+
for (const hook of hooks) {
|
|
342
|
+
try {
|
|
343
|
+
await hook.afterRun?.(hookContext, final);
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
updates.push({ type: "hook.error", hook: hook.name, message: error instanceof Error ? error.message : String(error) });
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
316
350
|
updates.close();
|
|
317
351
|
}
|
|
318
352
|
}
|
package/dist/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, AgentRun, Arrival, RunAgentOptions, RunResult } from \"./agent.js\";\nimport type { Failure } from \"./result.js\";\nimport type { Update } from \"./harness/harness.js\";\nimport type { Delivery, Store, StoreConflict, StoreError } from \"./store/store.js\";\nimport type { Content } from \"./content.js\";\nimport type { Entry, Stored, Usage } from \"./session/entry.js\";\nimport { err } from \"./result.js\";\nimport { createLog } from \"./session/log.js\";\nimport { toMessages } from \"./session/messages.js\";\nimport { createExecutor } from \"./tools/execute.js\";\n\n/**\n * Start an agent on a session.\n *\n * Without a store the log lives in memory and the session is ephemeral; with\n * one, every commit is durable before the next turn is built. The agent\n * definition is identical either way — durability is a composition choice, not\n * a different program.\n */\nexport function runAgent(options: RunAgentOptions): AgentRun {\n // A claim names its own session; a caller sending into a new one names none.\n const claim = options.claim;\n const sessionId = claim?.sessionId ?? options.sessionId ?? crypto.randomUUID();\n const controller = new AbortController();\n // Composed rather than forwarded. `addEventListener(\"abort\", …)` never fires\n // on a signal that has already aborted, so a caller who gave up before\n // calling got a full run anyway; and a listener added per run to a signal\n // that outlives it is a leak the run cannot clean up.\n const signal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n\n const updates = createChannel<Update>();\n const result = execute();\n\n return {\n result,\n cancel: () => controller.abort(),\n [Symbol.asyncIterator]: () => updates.iterator(),\n };\n\n async function execute(): Promise<RunResult> {\n // What this activation consumed. Summed from the `assistant` entries it\n // commits rather than reported by the harness, so one answer serves a loop\n // we own and a loop we do not — and so a run that failed still says what it\n // burned on the way there.\n const usage: Usage = {};\n\n try {\n const { agent, store } = options;\n const restored = store ? await open(store, sessionId, agent, options.key) : undefined;\n if (restored && !restored.ok) {\n return {\n status: \"failed\", error: restored.error,\n seq: positionOf(restored.error, 0), usage,\n };\n }\n // The store's own position, not the last entry's. They agree only while\n // nothing has ever been folded away, and the store is the one that knows.\n const log = createLog(restored?.value.entries ?? [], restored?.value.seq ?? 0);\n const stopping = (error: Failure): RunResult => ({ status: \"failed\", error, seq: log.seq, usage });\n\n // A claim was read at a position. If the session has moved since, this\n // worker lost, and the deliveries it was carrying are still where it\n // found them.\n if (claim && claim.seq !== log.seq) {\n return stopping({ code: \"conflict\", message: `Session is at ${log.seq}, not ${claim.seq}`, retryable: true });\n }\n\n // A ceiling on money needs something that can count it. Refused here\n // rather than silently ignored, because a limit that is declared and not\n // enforced is the most expensive kind of nothing.\n\n // The activation still open on this log, if one is. It decides three\n // things below: whether there is anything to resume, which run a\n // resumption continues, and which run a fresh activation supersedes.\n const interrupted = openRunId(log.entries);\n\n // What this run is adding, then what was waiting. A claim's deliveries\n // are named so the log records who each came from; anything the worker\n // supplies itself leads, because the only thing that ever does is\n // orientation for a harness with nowhere else to put it.\n const arrivals: readonly Arrival[] = [\n ...arrivalsOf(options.input),\n ...(claim?.pending ?? []).map((delivery): Arrival => ({\n input: delivery.input,\n ...(delivery.from ? { from: delivery.from } : {}),\n })),\n ];\n\n // A resumption continues the run it was handed, under that run's id. A\n // fresh id would leave the log holding a `run.started` nothing closes and\n // a `run.finished` nothing opened — a pair that only the store's\n // type-based rule saves, and that anything grouping entries by run reads\n // as broken. A resumption without an interrupted run is refused below.\n const runId = arrivals.length || !interrupted ? crypto.randomUUID() : interrupted;\n\n // Deliveries ride the next commit, which is the one that records the work\n // that produced them. They used to be held back to the run's final entry\n // so that a failed run handed nothing to anyone — a stronger promise than\n // any caller needs, and it was being paid for with a lie: a `send` tool\n // returned \"Delivered\" and interrupted the recipient many turns before\n // the delivery existed, and never at all if a later turn failed.\n const deliveries: Delivery[] = [];\n\n // The ceiling has one owner, and it is here rather than in a harness.\n // Counting committed entries is the only way to bound a harness that owns\n // its own loop — which is most of them — so a limit declared on the agent\n // holds for every one instead of only for ours.\n const limits = agent.limits;\n let stopped: Failure | undefined;\n let turns = 0;\n let toolCalls = 0;\n\n function exceeded(): Failure | undefined {\n if (!limits) return undefined;\n if (limits.maxTurns !== undefined && turns >= limits.maxTurns) {\n return { code: \"turn-limit\", message: `Stopped after ${turns} turns.`, retryable: false };\n }\n if (limits.maxToolCalls !== undefined && toolCalls >= limits.maxToolCalls) {\n return { code: \"tool-call-limit\", message: `Stopped after ${toolCalls} tool calls.`, retryable: false };\n }\n // Checked where work is recorded rather than on a timer: a deadline\n // stops the next piece of work, it does not interrupt one mid-flight.\n if (limits.deadline !== undefined && Date.now() >= Date.parse(limits.deadline)) {\n return { code: \"deadline\", message: `Stopped at the deadline of ${limits.deadline}.`, retryable: false };\n }\n return undefined;\n }\n\n // How many deliveries the next write takes off this session's own queue:\n // what the claim was carrying, and afterwards whatever `drain` folded in.\n // Cleared by the write that lands, because the input is gone once the\n // entries carrying it are durable, and not before.\n let take = claim?.pending.length ?? 0;\n\n async function commit(entries: readonly Entry[], enqueue?: readonly Delivery[]): Promise<void> {\n const outgoing = [...deliveries, ...(enqueue ?? [])];\n deliveries.length = 0;\n if (!entries.length && !outgoing.length) return;\n // Counted before the write, not after: the tokens were consumed whether\n // or not this entry wins the compare-and-swap, and a run that reports\n // nothing after paying for a generation is the opposite of what\n // `RunResult.usage` promises.\n for (const entry of entries) {\n if (entry.type === \"assistant\" && entry.usage) accumulate(usage, entry.usage);\n }\n\n if (store) {\n const written = await store.append({\n sessionId, expectedSeq: log.seq, entries,\n ...(outgoing.length ? { enqueue: outgoing } : {}),\n ...(take ? { takePending: take } : {}),\n });\n if (!written.ok) throw new CommitFailed(written.error, positionOf(written.error, log.seq));\n take = 0;\n }\n for (const stored of log.append(entries)) updates.push({ type: \"entry\", entry: stored });\n\n if (!stopped) {\n for (const entry of entries) {\n if (entry.type === \"assistant\") turns += 1;\n // `tool.finished`, not `tool.started`: the start is committed before\n // the batch executes, so counting it there cancelled the very batch\n // that reached the ceiling — `maxToolCalls: 1` ran no tools at all,\n // and said it had stopped after one.\n if (entry.type === \"tool.finished\") toolCalls += 1;\n }\n stopped = exceeded();\n if (stopped) controller.abort();\n }\n }\n\n /**\n * What the agent wants delivered as this run ends.\n *\n * A callback that throws must not cost the log its terminal entry: the\n * run would stay open, and an open run nothing closes is claimed by\n * `interrupted` every window for ever — the trap the no-recovery path above\n * exists to close. So the throw is held, the run is ended without the\n * deliveries, and it is re-thrown once the log is safe.\n */\n let reportFailure: unknown;\n async function reporting(run: {\n runId: string; outcome: \"completed\" | \"failed\" | \"cancelled\"; output: Content;\n }): Promise<readonly Delivery[]> {\n if (!agent.finished) return [];\n try {\n return await agent.finished({ sessionId, ...run });\n } catch (error) {\n reportFailure = error;\n return [];\n }\n }\n\n // Input that arrived while this activation was running, taken from the\n // front of the queue and committed as part of it. `takePending` removes\n // exactly what was committed, in the same write, so losing the position\n // loses the turn and never the messages.\n async function drain(): Promise<number> {\n if (!store) return 0;\n // Nothing is folded into an activation that is over. Draining here\n // committed the waiting deliveries and took them off the queue, and the\n // loop then ended — leaving a peer's message answered by nobody and\n // invisible to `next` (nothing pending) and to `interrupted` (no open run),\n // which is the trap this whole path exists to close.\n if (signal.aborted) return 0;\n const current = await store.read({ sessionId, afterSeq: log.seq });\n if (!current.ok || !current.value.pending.length) return 0;\n const waiting = current.value.pending;\n take = waiting.length;\n await commit(waiting.map((delivery): Entry => ({\n type: \"run.started\", runId, input: delivery.input,\n ...(delivery.from ? { from: delivery.from } : {}),\n })));\n return waiting.length;\n }\n\n const executor = agent.tools?.length\n ? createExecutor({\n tools: agent.tools,\n ...(agent.decide ? { decide: agent.decide } : {}),\n sessionId, runId,\n enqueue: (delivery) => deliveries.push(delivery),\n report: (callId, data) => updates.push({ type: \"tool.progress\", callId, data }),\n })\n : undefined;\n\n if (!arrivals.length) {\n // An open run is what a resumption continues. Without one there is\n // nothing half-done here: a closed log would otherwise take a second\n // `run.finished` with no beginning to match it.\n if (!interrupted) {\n return stopping({\n code: \"nothing-to-resume\",\n message: \"An activation with no input continues an interrupted run, and this session has none open.\",\n retryable: false,\n });\n }\n if (agent.harness.recovery !== \"history\") {\n // Asked to continue a log this harness cannot read. The interrupted\n // run is ended rather than left open, because nothing else will\n // continue it either — the harness is a property of the session — and\n // a run that stays open is handed back by `interrupted` every window,\n // for ever. A worker that provisions anything before it runs pays for\n // that each time round.\n const failure: Failure = {\n code: \"no-recovery\",\n message: `The ${agent.harness.id} harness cannot restart from history, so this activation cannot be continued.`,\n retryable: false,\n };\n // Whoever was waiting on it is told, in the write that ends it. A\n // parent expecting a child that can now never report is the same dead\n // end one layer up.\n const told = await reporting({ runId: interrupted, outcome: \"failed\", output: \"\" });\n await commit([{ type: \"run.finished\", runId: interrupted, outcome: \"failed\", error: failure }], told);\n return stopping(failure);\n }\n }\n\n // An interrupted predecessor is ended before a new activation begins over\n // it, so one session never holds two open runs. Only on a claim: the\n // store established there that nothing else is running, where a bare\n // `sessionId` establishes nothing and the run may still be live.\n if (arrivals.length && interrupted && claim) {\n await commit([{\n type: \"run.finished\", runId: interrupted, outcome: \"cancelled\",\n error: {\n code: \"superseded\",\n message: \"This activation was interrupted, and a later one began over it.\",\n retryable: false,\n },\n }]);\n }\n\n // Nothing opens a resumption. A `run.started` recording input nobody sent\n // would be a second beginning for one conversation; the loop reads the\n // history it was handed instead, sees the call that already ran, and\n // carries on rather than asking for it again.\n await commit(arrivals.map((arrival): Entry => ({\n type: \"run.started\", runId, input: arrival.input,\n ...(arrival.from ? { from: arrival.from } : {}),\n })));\n\n // Every ceiling is checked where work is recorded, and a resumption\n // records nothing before its first turn — so a deadline that had already\n // passed was never seen. Checked once here too, before the harness is\n // handed anything.\n stopped ??= exceeded();\n\n const outcome = stopped\n ? { status: \"failed\" as const, error: stopped }\n : await agent.harness.run({\n sessionId, runId,\n instructions: agent.instructions,\n history: () => toMessages({\n instructions: agent.instructions,\n entries: log.entries,\n ...(agent.attribution ? { attribution: true } : {}),\n ...(options.context ? { context: options.context } : {}),\n }),\n entries: () => log.entries,\n ...(options.context ? { context: options.context } : {}),\n ...(executor ? { tools: executor } : {}),\n commit: (entries) => commit(entries),\n ...(store ? { drain } : {}),\n emit: (update) => updates.push(update),\n signal,\n });\n\n // A harness stopped by the ceiling reports a cancellation, because that is\n // all it saw. The run knows why it was cancelled and says so instead.\n const settled = stopped && outcome.status === \"cancelled\"\n ? { status: \"failed\" as const, error: stopped }\n : outcome;\n\n const output = settled.status === \"completed\" ? settled.output : \"\";\n const finished = await reporting({ runId, outcome: settled.status, output });\n\n await commit(\n [{\n type: \"run.finished\", runId,\n outcome: settled.status === \"completed\" ? \"completed\" : settled.status === \"cancelled\" ? \"cancelled\" : \"failed\",\n ...(settled.status === \"failed\" ? { error: settled.error } : {}),\n }],\n finished,\n );\n\n if (settled.status === \"completed\") {\n return { status: \"completed\", output: settled.output, seq: log.seq, usage };\n }\n if (settled.status === \"cancelled\") return { status: \"cancelled\", seq: log.seq, usage };\n return stopping(settled.error);\n } catch (error) {\n if (error instanceof CommitFailed) {\n return { status: \"failed\", error: error.failure, seq: error.seq, usage };\n }\n throw error;\n } finally {\n updates.close();\n }\n }\n}\n\nclass CommitFailed extends Error {\n constructor(readonly failure: Failure, readonly seq: number) {\n super(failure.message);\n }\n}\n\n/**\n * Where the session actually is after a refused write. A conflict knows; every\n * other failure leaves the caller with the position it already had. Reporting\n * zero told a caller at forty that it was at the beginning.\n *\n * The `typeof` is not defensive noise: a store may report a conflict, and only\n * a `StoreConflict` carries the position. Casting on the code alone produced a\n * `RunResult.seq` of `undefined` under a type that says `number`.\n */\nfunction positionOf(error: StoreError, fallback: number): number {\n const actual = (error as StoreConflict).actualSeq;\n return error.code === \"conflict\" && typeof actual === \"number\" ? actual : fallback;\n}\n\nconst isArrival = (value: unknown): value is Arrival =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && \"input\" in value;\n\n/**\n * One arrival, or several.\n *\n * The elements decide it, because the outer shape cannot: an arrival names its\n * `input`, a content part names its `type`, and nothing is both. Reading every\n * array as a batch is what turned one image-and-text message into one entry per\n * part, each holding a part where whole content belongs.\n */\nfunction arrivalsOf(input: RunAgentOptions[\"input\"]): readonly Arrival[] {\n if (input === undefined) return [];\n // Nothing sent is nothing sent. Falling through committed a `run.started`\n // whose input was an empty array of content parts.\n if (Array.isArray(input) && input.length === 0) return [];\n if (Array.isArray(input) && input.length > 0 && input.every(isArrival)) return input;\n if (isArrival(input)) return [input];\n return [{ input: input as Content }];\n}\n\n/**\n * The activation still open on this log, if one is.\n *\n * `run.started` opens and `run.finished` closes, which is the same rule the\n * store maintains its claim from — read here from the entries rather than asked\n * of the store, because the log is the only thing that knows.\n */\nfunction openRunId(entries: readonly Stored[]): string | undefined {\n let open: string | undefined;\n for (const entry of entries) {\n if (entry.type === \"run.started\") open = entry.runId;\n if (entry.type === \"run.finished\") open = undefined;\n }\n return open;\n}\n\n/** Token counts add; unknown stays unknown rather than becoming a zero. */\nfunction accumulate(total: Usage, turn: Usage): void {\n for (const key of [\"inputTokens\", \"outputTokens\", \"cacheReadTokens\", \"cacheWriteTokens\"] as const) {\n if (turn[key] !== undefined) total[key] = (total[key] ?? 0) + turn[key]!;\n }\n}\n\nasync function open(store: Store, sessionId: string, agent: Agent, key?: string) {\n const existing = await store.read({ sessionId });\n if (existing.ok) {\n // `version` is documented as the boundary past which an agent is no longer\n // compatible with an existing session. Nothing was comparing it, so the\n // boundary held for exactly as long as nobody crossed it.\n const stored = existing.value.agent;\n if (stored.id !== agent.id || stored.version !== agent.version) {\n return err<StoreError>({\n code: \"conflict\",\n message: `Session ${sessionId} belongs to ${stored.id}@${stored.version}, not ${agent.id}@${agent.version}`,\n retryable: false,\n });\n }\n return existing;\n }\n if (existing.error.code !== \"not-found\") return existing;\n const created = await store.create({\n sessionId, agent: { id: agent.id, version: agent.version }, ...(key ? { key } : {}),\n });\n if (!created.ok) return created;\n return store.read({ sessionId });\n}\n\n/**\n * A bounded fan-out queue for ephemeral updates.\n *\n * One buffer of recent updates, which every listener starts from and which\n * never grows past its limit. That single rule gives three things:\n *\n * **A run nobody drains costs a fixed amount.** A headless worker used to\n * accumulate every delta of an entire activation, because the queue only ever\n * grew. Dropping the oldest is safe precisely because updates are not recovery\n * state and the committed log is.\n *\n * **Arriving late loses nothing that matters.** The first entry commits before\n * `runAgent` returns, so a caller that iterates immediately would otherwise\n * never see its own run start. A UI reconnecting mid-run gets recent history\n * for the same reason, without asking the store for it.\n *\n * **Everyone sees everything.** Each listener drains its own copy, so an\n * application can watch a run for telemetry and for a UI at once instead of the\n * two stealing events from each other.\n */\nfunction createChannel<T>(limit = 1_024) {\n interface Listener { buffer: T[]; wake?: () => void }\n const listeners = new Set<Listener>();\n const replay: T[] = [];\n let closed = false;\n\n const bounded = (buffer: T[], value: T) => {\n if (buffer.length >= limit) buffer.shift();\n buffer.push(value);\n };\n\n return {\n push(value: T) {\n bounded(replay, value);\n for (const listener of listeners) {\n bounded(listener.buffer, value);\n listener.wake?.();\n }\n },\n close() {\n closed = true;\n for (const listener of listeners) listener.wake?.();\n },\n iterator(): AsyncIterator<T> {\n const listener: Listener = { buffer: [...replay] };\n listeners.add(listener);\n const done = (): IteratorResult<T> => {\n listeners.delete(listener);\n return { value: undefined, done: true };\n };\n return {\n async next(): Promise<IteratorResult<T>> {\n for (;;) {\n const value = listener.buffer.shift();\n if (value !== undefined) return { value, done: false };\n if (closed) return done();\n await new Promise<void>((resolve) => { listener.wake = resolve; });\n }\n },\n async return(): Promise<IteratorResult<T>> { return done(); },\n };\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, AgentRun, Arrival, RunAgentOptions, RunResult } from \"./agent.js\";\nimport type { Failure } from \"./result.js\";\nimport type { HarnessContext, HarnessResult, Update } from \"./harness/harness.js\";\nimport type { Delivery, Store, StoreConflict, StoreError } from \"./store/store.js\";\nimport type { Content } from \"./content.js\";\nimport type { Entry, Stored, Usage } from \"./session/entry.js\";\nimport { err } from \"./result.js\";\nimport { createLog } from \"./session/log.js\";\nimport { toMessages } from \"./session/messages.js\";\nimport { createExecutor } from \"./tools/execute.js\";\n\n/**\n * Start an agent on a session.\n *\n * Without a store the log lives in memory and the session is ephemeral; with\n * one, every commit is durable before the next turn is built. The agent\n * definition is identical either way — durability is a composition choice, not\n * a different program.\n */\nexport function runAgent(options: RunAgentOptions): AgentRun {\n // A claim names its own session; a caller sending into a new one names none.\n const hooks = options.agent.hooks ?? [];\n if (new Set(hooks.map(hook => hook.name)).size !== hooks.length || hooks.some(hook => !hook.name)) {\n throw new Error(\"Lifecycle hook names must be non-empty and unique.\");\n }\n const claim = options.claim;\n const sessionId = claim?.sessionId ?? options.sessionId ?? crypto.randomUUID();\n const controller = new AbortController();\n // Composed rather than forwarded. `addEventListener(\"abort\", …)` never fires\n // on a signal that has already aborted, so a caller who gave up before\n // calling got a full run anyway; and a listener added per run to a signal\n // that outlives it is a leak the run cannot clean up.\n const signal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n\n const updates = createChannel<Update>();\n const result = execute();\n\n return {\n result,\n cancel: () => controller.abort(),\n [Symbol.asyncIterator]: () => updates.iterator(),\n };\n\n async function execute(): Promise<RunResult> {\n // What this activation consumed. Summed from the `assistant` entries it\n // commits rather than reported by the harness, so one answer serves a loop\n // we own and a loop we do not — and so a run that failed still says what it\n // burned on the way there.\n const usage: Usage = {};\n let hookContext: HarnessContext | undefined;\n let result: RunResult | undefined;\n\n try {\n const { agent, store } = options;\n const restored = store ? await open(store, sessionId, agent, options.key) : undefined;\n if (restored && !restored.ok) {\n return {\n status: \"failed\", error: restored.error,\n seq: positionOf(restored.error, 0), usage,\n };\n }\n // The store's own position, not the last entry's. They agree only while\n // nothing has ever been folded away, and the store is the one that knows.\n const log = createLog(restored?.value.entries ?? [], restored?.value.seq ?? 0);\n const stopping = (error: Failure): RunResult => (result = { status: \"failed\", error, seq: log.seq, usage });\n\n // A claim was read at a position. If the session has moved since, this\n // worker lost, and the deliveries it was carrying are still where it\n // found them.\n if (claim && claim.seq !== log.seq) {\n return stopping({ code: \"conflict\", message: `Session is at ${log.seq}, not ${claim.seq}`, retryable: true });\n }\n\n // A ceiling on money needs something that can count it. Refused here\n // rather than silently ignored, because a limit that is declared and not\n // enforced is the most expensive kind of nothing.\n\n // The activation still open on this log, if one is. It decides three\n // things below: whether there is anything to resume, which run a\n // resumption continues, and which run a fresh activation supersedes.\n const interrupted = openRunId(log.entries);\n\n // What this run is adding, then what was waiting. A claim's deliveries\n // are named so the log records who each came from; anything the worker\n // supplies itself leads, because the only thing that ever does is\n // orientation for a harness with nowhere else to put it.\n const arrivals: readonly Arrival[] = [\n ...arrivalsOf(options.input),\n ...(claim?.pending ?? []).map((delivery): Arrival => ({\n input: delivery.input,\n ...(delivery.from ? { from: delivery.from } : {}),\n })),\n ];\n\n // A resumption continues the run it was handed, under that run's id. A\n // fresh id would leave the log holding a `run.started` nothing closes and\n // a `run.finished` nothing opened — a pair that only the store's\n // type-based rule saves, and that anything grouping entries by run reads\n // as broken. A resumption without an interrupted run is refused below.\n const runId = arrivals.length || !interrupted ? crypto.randomUUID() : interrupted;\n\n // Deliveries ride the next commit, which is the one that records the work\n // that produced them. They used to be held back to the run's final entry\n // so that a failed run handed nothing to anyone — a stronger promise than\n // any caller needs, and it was being paid for with a lie: a `send` tool\n // returned \"Delivered\" and interrupted the recipient many turns before\n // the delivery existed, and never at all if a later turn failed.\n const deliveries: Delivery[] = [];\n\n // The ceiling has one owner, and it is here rather than in a harness.\n // Counting committed entries is the only way to bound a harness that owns\n // its own loop — which is most of them — so a limit declared on the agent\n // holds for every one instead of only for ours.\n const limits = agent.limits;\n let stopped: Failure | undefined;\n let turns = 0;\n let toolCalls = 0;\n\n function exceeded(): Failure | undefined {\n if (!limits) return undefined;\n if (limits.maxTurns !== undefined && turns >= limits.maxTurns) {\n return { code: \"turn-limit\", message: `Stopped after ${turns} turns.`, retryable: false };\n }\n if (limits.maxToolCalls !== undefined && toolCalls >= limits.maxToolCalls) {\n return { code: \"tool-call-limit\", message: `Stopped after ${toolCalls} tool calls.`, retryable: false };\n }\n // Checked where work is recorded rather than on a timer: a deadline\n // stops the next piece of work, it does not interrupt one mid-flight.\n if (limits.deadline !== undefined && Date.now() >= Date.parse(limits.deadline)) {\n return { code: \"deadline\", message: `Stopped at the deadline of ${limits.deadline}.`, retryable: false };\n }\n return undefined;\n }\n\n // How many deliveries the next write takes off this session's own queue:\n // what the claim was carrying, and afterwards whatever `drain` folded in.\n // Cleared by the write that lands, because the input is gone once the\n // entries carrying it are durable, and not before.\n let take = claim?.pending.length ?? 0;\n\n async function commit(entries: readonly Entry[], enqueue?: readonly Delivery[]): Promise<void> {\n const outgoing = [...deliveries, ...(enqueue ?? [])];\n deliveries.length = 0;\n if (!entries.length && !outgoing.length) return;\n // Counted before the write, not after: the tokens were consumed whether\n // or not this entry wins the compare-and-swap, and a run that reports\n // nothing after paying for a generation is the opposite of what\n // `RunResult.usage` promises.\n for (const entry of entries) {\n if (entry.type === \"assistant\" && entry.usage) accumulate(usage, entry.usage);\n }\n\n if (store) {\n const written = await store.append({\n sessionId, expectedSeq: log.seq, entries,\n ...(outgoing.length ? { enqueue: outgoing } : {}),\n ...(take ? { takePending: take } : {}),\n });\n if (!written.ok) throw new CommitFailed(written.error, positionOf(written.error, log.seq));\n take = 0;\n }\n for (const stored of log.append(entries)) updates.push({ type: \"entry\", entry: stored });\n\n if (!stopped) {\n for (const entry of entries) {\n if (entry.type === \"assistant\") turns += 1;\n // `tool.finished`, not `tool.started`: the start is committed before\n // the batch executes, so counting it there cancelled the very batch\n // that reached the ceiling — `maxToolCalls: 1` ran no tools at all,\n // and said it had stopped after one.\n if (entry.type === \"tool.finished\") toolCalls += 1;\n }\n stopped = exceeded();\n if (stopped) controller.abort();\n }\n }\n\n // Input that arrived while this activation was running, taken from the\n // front of the queue and committed as part of it. `takePending` removes\n // exactly what was committed, in the same write, so losing the position\n // loses the turn and never the messages.\n async function drain(): Promise<number> {\n if (!store) return 0;\n // Nothing is folded into an activation that is over. Draining here\n // committed the waiting deliveries and took them off the queue, and the\n // loop then ended — leaving a peer's message answered by nobody and\n // invisible to `next` (nothing pending) and to `interrupted` (no open run),\n // which is the trap this whole path exists to close.\n if (signal.aborted) return 0;\n const current = await store.read({ sessionId, afterSeq: log.seq });\n if (!current.ok || !current.value.pending.length) return 0;\n const waiting = current.value.pending;\n take = waiting.length;\n await commit(waiting.map((delivery): Entry => ({\n type: \"run.started\", runId, input: delivery.input,\n ...(delivery.from ? { from: delivery.from } : {}),\n })));\n return waiting.length;\n }\n\n const executor = agent.tools?.length\n ? createExecutor({\n tools: agent.tools,\n ...(agent.decide ? { decide: agent.decide } : {}),\n sessionId, runId,\n enqueue: (delivery) => deliveries.push(delivery),\n report: (callId, data) => updates.push({ type: \"tool.progress\", callId, data }),\n })\n : undefined;\n\n if (!arrivals.length) {\n // An open run is what a resumption continues. Without one there is\n // nothing half-done here: a closed log would otherwise take a second\n // `run.finished` with no beginning to match it.\n if (!interrupted) {\n return stopping({\n code: \"nothing-to-resume\",\n message: \"An activation with no input continues an interrupted run, and this session has none open.\",\n retryable: false,\n });\n }\n if (agent.harness.recovery !== \"history\") {\n // Asked to continue a log this harness cannot read. The interrupted\n // run is ended rather than left open, because nothing else will\n // continue it either — the harness is a property of the session — and\n // a run that stays open is handed back by `interrupted` every window,\n // for ever. A worker that provisions anything before it runs pays for\n // that each time round.\n const failure: Failure = {\n code: \"no-recovery\",\n message: `The ${agent.harness.id} harness cannot restart from history, so this activation cannot be continued.`,\n retryable: false,\n };\n stopped = failure;\n }\n }\n\n // An interrupted predecessor is ended before a new activation begins over\n // it, so one session never holds two open runs. Only on a claim: the\n // store established there that nothing else is running, where a bare\n // `sessionId` establishes nothing and the run may still be live.\n if (arrivals.length && interrupted && claim) {\n await commit([{\n type: \"run.finished\", runId: interrupted, outcome: \"cancelled\",\n error: {\n code: \"superseded\",\n message: \"This activation was interrupted, and a later one began over it.\",\n retryable: false,\n },\n }]);\n }\n\n // Nothing opens a resumption. A `run.started` recording input nobody sent\n // would be a second beginning for one conversation; the loop reads the\n // history it was handed instead, sees the call that already ran, and\n // carries on rather than asking for it again.\n await commit(arrivals.map((arrival): Entry => ({\n type: \"run.started\", runId, input: arrival.input,\n ...(arrival.from ? { from: arrival.from } : {}),\n })));\n\n // Every ceiling is checked where work is recorded, and a resumption\n // records nothing before its first turn — so a deadline that had already\n // passed was never seen. Checked once here too, before the harness is\n // handed anything.\n stopped ??= exceeded();\n\n function makeContext(): HarnessContext {\n return {\n sessionId, runId,\n instructions: agent.instructions,\n history: () => toMessages({\n instructions: agent.instructions,\n entries: log.entries,\n ...(agent.attribution ? { attribution: true } : {}),\n ...(options.context ? { context: options.context } : {}),\n }),\n entries: () => log.entries,\n ...(options.context ? { context: options.context } : {}),\n ...(executor ? { tools: executor } : {}),\n commit: (entries) => commit(entries),\n ...(store ? { drain } : {}),\n emit: (update) => updates.push(update),\n signal, hooks,\n };\n }\n\n async function stoppingHooks(outcome: HarnessResult) {\n const inputs: Entry[] = [];\n const outgoing: Delivery[] = [];\n for (const hook of hooks) {\n const response = await hook.beforeStop?.(hookContext!, outcome);\n if (response && \"input\" in response && outcome.status === \"completed\" && !signal.aborted && !stopped &&\n !log.entries.some(entry => entry.type === \"hook.input\" && entry.runId === runId && entry.hook === hook.name)) {\n inputs.push({ type: \"hook.input\", runId, hook: hook.name, input: response.input });\n }\n if (response && \"deliveries\" in response) outgoing.push(...response.deliveries);\n }\n return { inputs, deliveries: outgoing };\n }\n\n hookContext = makeContext();\n let outcome: HarnessResult;\n let outgoing: readonly Delivery[] = [];\n try {\n for (const hook of hooks) await hook.beforeRun?.(hookContext);\n for (;;) {\n outcome = stopped ? { status: \"failed\", error: stopped }\n : signal.aborted ? { status: \"cancelled\" }\n : await agent.harness.run(hookContext);\n if (stopped) outcome = { status: \"failed\", error: stopped };\n else if (signal.aborted) outcome = { status: \"cancelled\" };\n const ending = await stoppingHooks(outcome);\n if (!ending.inputs.length) { outgoing = ending.deliveries; break; }\n await commit(ending.inputs);\n }\n } catch (error) {\n if (error instanceof CommitFailed) throw error;\n outcome = { status: \"failed\", error: {\n code: \"hook-or-harness\", message: error instanceof Error ? error.message : String(error), retryable: false,\n } };\n }\n\n // A harness stopped by the ceiling reports a cancellation, because that is\n // all it saw. The run knows why it was cancelled and says so instead.\n const settled = stopped && outcome.status === \"cancelled\"\n ? { status: \"failed\" as const, error: stopped }\n : outcome;\n\n await commit(\n [{\n type: \"run.finished\", runId,\n outcome: settled.status === \"completed\" ? \"completed\" : settled.status === \"cancelled\" ? \"cancelled\" : \"failed\",\n ...(settled.status === \"failed\" ? { error: settled.error } : {}),\n }],\n outgoing,\n );\n\n if (settled.status === \"completed\") {\n return result = { status: \"completed\", output: settled.output, seq: log.seq, usage };\n }\n if (settled.status === \"cancelled\") return result = { status: \"cancelled\", seq: log.seq, usage };\n return stopping(settled.error);\n } catch (error) {\n if (error instanceof CommitFailed) {\n return result = { status: \"failed\", error: error.failure, seq: error.seq, usage };\n }\n throw error;\n } finally {\n if (hookContext) {\n const final = result ?? { status: \"failed\" as const, error: {\n code: \"run-error\", message: \"The run could not finish.\", retryable: false,\n }, seq: hookContext.entries().at(-1)?.seq ?? 0, usage };\n for (const hook of hooks) {\n try { await hook.afterRun?.(hookContext, final); }\n catch (error) {\n updates.push({ type: \"hook.error\", hook: hook.name, message: error instanceof Error ? error.message : String(error) });\n }\n }\n }\n updates.close();\n }\n }\n}\n\nclass CommitFailed extends Error {\n constructor(readonly failure: Failure, readonly seq: number) {\n super(failure.message);\n }\n}\n\n/**\n * Where the session actually is after a refused write. A conflict knows; every\n * other failure leaves the caller with the position it already had. Reporting\n * zero told a caller at forty that it was at the beginning.\n *\n * The `typeof` is not defensive noise: a store may report a conflict, and only\n * a `StoreConflict` carries the position. Casting on the code alone produced a\n * `RunResult.seq` of `undefined` under a type that says `number`.\n */\nfunction positionOf(error: StoreError, fallback: number): number {\n const actual = (error as StoreConflict).actualSeq;\n return error.code === \"conflict\" && typeof actual === \"number\" ? actual : fallback;\n}\n\nconst isArrival = (value: unknown): value is Arrival =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && \"input\" in value;\n\n/**\n * One arrival, or several.\n *\n * The elements decide it, because the outer shape cannot: an arrival names its\n * `input`, a content part names its `type`, and nothing is both. Reading every\n * array as a batch is what turned one image-and-text message into one entry per\n * part, each holding a part where whole content belongs.\n */\nfunction arrivalsOf(input: RunAgentOptions[\"input\"]): readonly Arrival[] {\n if (input === undefined) return [];\n // Nothing sent is nothing sent. Falling through committed a `run.started`\n // whose input was an empty array of content parts.\n if (Array.isArray(input) && input.length === 0) return [];\n if (Array.isArray(input) && input.length > 0 && input.every(isArrival)) return input;\n if (isArrival(input)) return [input];\n return [{ input: input as Content }];\n}\n\n/**\n * The activation still open on this log, if one is.\n *\n * `run.started` opens and `run.finished` closes, which is the same rule the\n * store maintains its claim from — read here from the entries rather than asked\n * of the store, because the log is the only thing that knows.\n */\nfunction openRunId(entries: readonly Stored[]): string | undefined {\n let open: string | undefined;\n for (const entry of entries) {\n if (entry.type === \"run.started\") open = entry.runId;\n if (entry.type === \"run.finished\") open = undefined;\n }\n return open;\n}\n\n/** Token counts add; unknown stays unknown rather than becoming a zero. */\nfunction accumulate(total: Usage, turn: Usage): void {\n for (const key of [\"inputTokens\", \"outputTokens\", \"cacheReadTokens\", \"cacheWriteTokens\"] as const) {\n if (turn[key] !== undefined) total[key] = (total[key] ?? 0) + turn[key]!;\n }\n}\n\nasync function open(store: Store, sessionId: string, agent: Agent, key?: string) {\n const existing = await store.read({ sessionId });\n if (existing.ok) {\n // `version` is documented as the boundary past which an agent is no longer\n // compatible with an existing session. Nothing was comparing it, so the\n // boundary held for exactly as long as nobody crossed it.\n const stored = existing.value.agent;\n if (stored.id !== agent.id || stored.version !== agent.version) {\n return err<StoreError>({\n code: \"conflict\",\n message: `Session ${sessionId} belongs to ${stored.id}@${stored.version}, not ${agent.id}@${agent.version}`,\n retryable: false,\n });\n }\n return existing;\n }\n if (existing.error.code !== \"not-found\") return existing;\n const created = await store.create({\n sessionId, agent: { id: agent.id, version: agent.version }, ...(key ? { key } : {}),\n });\n if (!created.ok) return created;\n return store.read({ sessionId });\n}\n\n/**\n * A bounded fan-out queue for ephemeral updates.\n *\n * One buffer of recent updates, which every listener starts from and which\n * never grows past its limit. That single rule gives three things:\n *\n * **A run nobody drains costs a fixed amount.** A headless worker used to\n * accumulate every delta of an entire activation, because the queue only ever\n * grew. Dropping the oldest is safe precisely because updates are not recovery\n * state and the committed log is.\n *\n * **Arriving late loses nothing that matters.** The first entry commits before\n * `runAgent` returns, so a caller that iterates immediately would otherwise\n * never see its own run start. A UI reconnecting mid-run gets recent history\n * for the same reason, without asking the store for it.\n *\n * **Everyone sees everything.** Each listener drains its own copy, so an\n * application can watch a run for telemetry and for a UI at once instead of the\n * two stealing events from each other.\n */\nfunction createChannel<T>(limit = 1_024) {\n interface Listener { buffer: T[]; wake?: () => void }\n const listeners = new Set<Listener>();\n const replay: T[] = [];\n let closed = false;\n\n const bounded = (buffer: T[], value: T) => {\n if (buffer.length >= limit) buffer.shift();\n buffer.push(value);\n };\n\n return {\n push(value: T) {\n bounded(replay, value);\n for (const listener of listeners) {\n bounded(listener.buffer, value);\n listener.wake?.();\n }\n },\n close() {\n closed = true;\n for (const listener of listeners) listener.wake?.();\n },\n iterator(): AsyncIterator<T> {\n const listener: Listener = { buffer: [...replay] };\n listeners.add(listener);\n const done = (): IteratorResult<T> => {\n listeners.delete(listener);\n return { value: undefined, done: true };\n };\n return {\n async next(): Promise<IteratorResult<T>> {\n for (;;) {\n const value = listener.buffer.shift();\n if (value !== undefined) return { value, done: false };\n if (closed) return done();\n await new Promise<void>((resolve) => { listener.wake = resolve; });\n }\n },\n async return(): Promise<IteratorResult<T>> { return done(); },\n };\n },\n };\n}\n"]}
|
package/dist/session/entry.d.ts
CHANGED
|
@@ -93,6 +93,11 @@ export interface From {
|
|
|
93
93
|
* field for a value another field determines.
|
|
94
94
|
*/
|
|
95
95
|
export type Entry = {
|
|
96
|
+
type: "hook.input";
|
|
97
|
+
runId: string;
|
|
98
|
+
hook: string;
|
|
99
|
+
input: Content;
|
|
100
|
+
} | {
|
|
96
101
|
type: "run.started";
|
|
97
102
|
runId: string;
|
|
98
103
|
input: Content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/session/entry.ts"],"names":[],"mappings":"","sourcesContent":["import type { Content } from \"../content.js\";\nimport type { Failure } from \"../result.js\";\nimport type { JsonValue } from \"../json.js\";\n\n/** A model's request to invoke a tool. `arguments` is unparsed JSON as the provider sent it. */\nexport interface ToolCall {\n callId: string;\n name: string;\n arguments: string;\n}\n\nexport interface ToolResult {\n content: Content;\n /** Structured channel for the application and the UI. Never reaches the model. */\n details?: JsonValue;\n isError?: boolean;\n}\n\n/**\n * What a generation consumed.\n *\n * Absent stays absent — a count nobody reported is not a zero. This package\n * holds no rates and computes no money from tokens. Where an adapter does\n * arithmetic it is reconciling its wire's encoding to the meanings below:\n * normalization, which is an adapter's job, and never a new fact.\n *\n * That is why `costUsd` belongs here and a rate table does not. A cost the\n * provider *states* is an observation like the counts beside it, and dropping\n * it was the same mistake as dropping the model that served the request: an\n * application was left reconstructing, from a table it maintains by hand, a\n * number the wire had already given it. For a router that is not even possible\n * — it picks an upstream provider per request and adds its own margin, so no\n * static table can say what was charged.\n */\nexport interface Usage {\n /**\n * Input tokens that were neither read from nor written to a cache.\n *\n * **The three input counts are disjoint.** The prompt's total size is\n * `inputTokens + cacheReadTokens + cacheWriteTokens`; no field here is a\n * subset of another, so a caller sums and never subtracts.\n *\n * The wires disagree about this and one of them has to be converted. What\n * Anthropic calls `input_tokens` is already this — \"tokens which were not\n * read from or used to create a cache\". What OpenAI calls `prompt_tokens` is\n * the whole prompt, with `cached_tokens` counted inside it, so that adapter\n * subtracts once and callers stop having to know which wire answered.\n *\n * Disjoint is the choice that survives absence, which is the rule the rest of\n * this type runs on. Summing the fields you were given is right whichever\n * ones are missing; subtracting a field you were not given is not. Under the\n * other convention a heavily cached Anthropic turn priced its fresh tokens at\n * zero — quietly, because the subtraction was clamped at zero rather than\n * being allowed to go negative where somebody would have seen it.\n */\n inputTokens?: number;\n outputTokens?: number;\n /** Input tokens served from a cache. Disjoint from `inputTokens`. */\n cacheReadTokens?: number;\n /** Input tokens written to a cache. Disjoint from `inputTokens`. */\n cacheWriteTokens?: number;\n /**\n * What the provider said this generation cost, in US dollars. Reported,\n * never derived: no adapter computes this from a rate, and one whose wire\n * does not carry a cost leaves it absent rather than estimating.\n */\n costUsd?: number;\n}\n\n/**\n * Who sent an arrival: what sort of sender, and which one.\n *\n * aglib mints exactly one kind — `\"session\"`, a delivery from another session —\n * and interprets no other. Every other kind is the application's word for one of\n * its own senders: a person, a channel, a schedule, a webhook. The vocabulary\n * belongs to whoever can close it, and that is never this package.\n *\n * Two fields because absence was carrying four facts. This used to be the\n * sending session's id alone, so an operator, a channel and a timer all said the\n * same thing by saying nothing, and a recipient could not tell a person typing\n * from a routine firing. Packing both into one string instead — `\"routine:x\"` —\n * would put the vocabulary in a convention nothing closes, which is how such a\n * field ends up with values that exist only by grep and a different reading on\n * every surface that renders it.\n */\nexport interface From {\n kind: string;\n id: string;\n}\n\n/**\n * The canonical vocabulary. This is the session's state, not a record of it:\n * the loop reads its context by projecting these and appends back to them, so\n * there is no second transcript that could disagree.\n *\n * `tool.started` carries only the call id — the assistant entry above it\n * already holds the call, and duplicating name and arguments would be a second\n * field for a value another field determines.\n */\nexport type Entry =\n | { type: \"run.started\"; runId: string; input: Content; from?: From }\n | {\n type: \"assistant\"; runId: string; content: Content;\n calls?: readonly ToolCall[]; usage?: Usage;\n /**\n * What produced this turn, when a model did: which model answered and the\n * span it took. `Stored.at` is when the entry was committed, which is a\n * different fact and not a substitute — anything projecting a generation\n * needs both ends of the call, and the commit is neither of them.\n */\n generation?: { model?: string; startedAt: string; endedAt: string };\n }\n | { type: \"tool.started\"; runId: string; callId: string }\n | { type: \"tool.finished\"; runId: string; callId: string; result: ToolResult }\n /** Compaction output. `replaces` is the seq up to which entries are folded; nothing is deleted. */\n | { type: \"summary\"; runId: string; content: string; replaces: number }\n | { type: \"run.finished\"; runId: string; outcome: \"completed\" | \"failed\" | \"cancelled\"; error?: Failure };\n\nexport type EntryType = Entry[\"type\"];\n\n/** An entry once the log has given it a position. */\nexport type Stored<T extends Entry = Entry> = T & { seq: number; at: string };\n\n/**\n * Input delivered to a session, committed with the sender's own entries.\n * Spawning a child, replying to a parent and messaging a peer are all this.\n */\nexport interface Delivery {\n /** The session it is delivered to. */\n sessionId: string;\n input: Content;\n /**\n * Who sent it. Absent means the application did not say — not that nobody\n * did. Recorded on the receiving `run.started`, so an application can tell a\n * peer's message from its user's, and can see that it already answered one\n * that arrives twice. It becomes text the model reads only where the\n * recipient's agent asks, with `attribution`.\n */\n from?: From;\n /**\n * Where in the recipient's loop this lands. Defaults to \"next\".\n *\n * Three places, and each is an outcome a sender can reason about rather than\n * a level of urgency a harness interprets:\n *\n * \"interrupt\" — the running activation ends, so the next one begins with\n * this. Its uncommitted work is lost; everything it had\n * already committed stays.\n * \"turn\" — folded into the activation already running, before its next\n * model call. Nothing in flight is lost. Immediately, if\n * nothing is running.\n * \"next\" — at the start of the recipient's next activation.\n *\n * This used to be `now | next | later`, and `now` meant either of the first\n * two depending on the harness — fold if it had a safe point, end the\n * activation if it did not. One word for \"your message arrives and the work\n * continues\" and \"your message arrives and a turn's work is destroyed\". The\n * doctrine was that a priority names the requirement and not the mechanism,\n * but those are not two mechanisms for one requirement: they are two\n * different things happening to somebody's work, and a runtime answer saying\n * which one you got was invented to paper over it. `later` named a fourth\n * thing that nothing implemented.\n *\n * **A harness that cannot honour one falls back to a later place, never an\n * earlier one.** A loop with no safe point cannot do \"turn\", so it does\n * \"next\" — the message waits. It does not end the activation instead, which\n * is what falling back through an ordered scale used to do: ask for the\n * gentlest useful thing and get the most destructive one.\n */\n priority?: \"interrupt\" | \"turn\" | \"next\";\n /**\n * The sender's key for this delivery. Two deliveries with the same id are the\n * same delivery, so a retried send does not arrive twice.\n */\n id?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/session/entry.ts"],"names":[],"mappings":"","sourcesContent":["import type { Content } from \"../content.js\";\nimport type { Failure } from \"../result.js\";\nimport type { JsonValue } from \"../json.js\";\n\n/** A model's request to invoke a tool. `arguments` is unparsed JSON as the provider sent it. */\nexport interface ToolCall {\n callId: string;\n name: string;\n arguments: string;\n}\n\nexport interface ToolResult {\n content: Content;\n /** Structured channel for the application and the UI. Never reaches the model. */\n details?: JsonValue;\n isError?: boolean;\n}\n\n/**\n * What a generation consumed.\n *\n * Absent stays absent — a count nobody reported is not a zero. This package\n * holds no rates and computes no money from tokens. Where an adapter does\n * arithmetic it is reconciling its wire's encoding to the meanings below:\n * normalization, which is an adapter's job, and never a new fact.\n *\n * That is why `costUsd` belongs here and a rate table does not. A cost the\n * provider *states* is an observation like the counts beside it, and dropping\n * it was the same mistake as dropping the model that served the request: an\n * application was left reconstructing, from a table it maintains by hand, a\n * number the wire had already given it. For a router that is not even possible\n * — it picks an upstream provider per request and adds its own margin, so no\n * static table can say what was charged.\n */\nexport interface Usage {\n /**\n * Input tokens that were neither read from nor written to a cache.\n *\n * **The three input counts are disjoint.** The prompt's total size is\n * `inputTokens + cacheReadTokens + cacheWriteTokens`; no field here is a\n * subset of another, so a caller sums and never subtracts.\n *\n * The wires disagree about this and one of them has to be converted. What\n * Anthropic calls `input_tokens` is already this — \"tokens which were not\n * read from or used to create a cache\". What OpenAI calls `prompt_tokens` is\n * the whole prompt, with `cached_tokens` counted inside it, so that adapter\n * subtracts once and callers stop having to know which wire answered.\n *\n * Disjoint is the choice that survives absence, which is the rule the rest of\n * this type runs on. Summing the fields you were given is right whichever\n * ones are missing; subtracting a field you were not given is not. Under the\n * other convention a heavily cached Anthropic turn priced its fresh tokens at\n * zero — quietly, because the subtraction was clamped at zero rather than\n * being allowed to go negative where somebody would have seen it.\n */\n inputTokens?: number;\n outputTokens?: number;\n /** Input tokens served from a cache. Disjoint from `inputTokens`. */\n cacheReadTokens?: number;\n /** Input tokens written to a cache. Disjoint from `inputTokens`. */\n cacheWriteTokens?: number;\n /**\n * What the provider said this generation cost, in US dollars. Reported,\n * never derived: no adapter computes this from a rate, and one whose wire\n * does not carry a cost leaves it absent rather than estimating.\n */\n costUsd?: number;\n}\n\n/**\n * Who sent an arrival: what sort of sender, and which one.\n *\n * aglib mints exactly one kind — `\"session\"`, a delivery from another session —\n * and interprets no other. Every other kind is the application's word for one of\n * its own senders: a person, a channel, a schedule, a webhook. The vocabulary\n * belongs to whoever can close it, and that is never this package.\n *\n * Two fields because absence was carrying four facts. This used to be the\n * sending session's id alone, so an operator, a channel and a timer all said the\n * same thing by saying nothing, and a recipient could not tell a person typing\n * from a routine firing. Packing both into one string instead — `\"routine:x\"` —\n * would put the vocabulary in a convention nothing closes, which is how such a\n * field ends up with values that exist only by grep and a different reading on\n * every surface that renders it.\n */\nexport interface From {\n kind: string;\n id: string;\n}\n\n/**\n * The canonical vocabulary. This is the session's state, not a record of it:\n * the loop reads its context by projecting these and appends back to them, so\n * there is no second transcript that could disagree.\n *\n * `tool.started` carries only the call id — the assistant entry above it\n * already holds the call, and duplicating name and arguments would be a second\n * field for a value another field determines.\n */\nexport type Entry =\n | { type: \"hook.input\"; runId: string; hook: string; input: Content }\n | { type: \"run.started\"; runId: string; input: Content; from?: From }\n | {\n type: \"assistant\"; runId: string; content: Content;\n calls?: readonly ToolCall[]; usage?: Usage;\n /**\n * What produced this turn, when a model did: which model answered and the\n * span it took. `Stored.at` is when the entry was committed, which is a\n * different fact and not a substitute — anything projecting a generation\n * needs both ends of the call, and the commit is neither of them.\n */\n generation?: { model?: string; startedAt: string; endedAt: string };\n }\n | { type: \"tool.started\"; runId: string; callId: string }\n | { type: \"tool.finished\"; runId: string; callId: string; result: ToolResult }\n /** Compaction output. `replaces` is the seq up to which entries are folded; nothing is deleted. */\n | { type: \"summary\"; runId: string; content: string; replaces: number }\n | { type: \"run.finished\"; runId: string; outcome: \"completed\" | \"failed\" | \"cancelled\"; error?: Failure };\n\nexport type EntryType = Entry[\"type\"];\n\n/** An entry once the log has given it a position. */\nexport type Stored<T extends Entry = Entry> = T & { seq: number; at: string };\n\n/**\n * Input delivered to a session, committed with the sender's own entries.\n * Spawning a child, replying to a parent and messaging a peer are all this.\n */\nexport interface Delivery {\n /** The session it is delivered to. */\n sessionId: string;\n input: Content;\n /**\n * Who sent it. Absent means the application did not say — not that nobody\n * did. Recorded on the receiving `run.started`, so an application can tell a\n * peer's message from its user's, and can see that it already answered one\n * that arrives twice. It becomes text the model reads only where the\n * recipient's agent asks, with `attribution`.\n */\n from?: From;\n /**\n * Where in the recipient's loop this lands. Defaults to \"next\".\n *\n * Three places, and each is an outcome a sender can reason about rather than\n * a level of urgency a harness interprets:\n *\n * \"interrupt\" — the running activation ends, so the next one begins with\n * this. Its uncommitted work is lost; everything it had\n * already committed stays.\n * \"turn\" — folded into the activation already running, before its next\n * model call. Nothing in flight is lost. Immediately, if\n * nothing is running.\n * \"next\" — at the start of the recipient's next activation.\n *\n * This used to be `now | next | later`, and `now` meant either of the first\n * two depending on the harness — fold if it had a safe point, end the\n * activation if it did not. One word for \"your message arrives and the work\n * continues\" and \"your message arrives and a turn's work is destroyed\". The\n * doctrine was that a priority names the requirement and not the mechanism,\n * but those are not two mechanisms for one requirement: they are two\n * different things happening to somebody's work, and a runtime answer saying\n * which one you got was invented to paper over it. `later` named a fourth\n * thing that nothing implemented.\n *\n * **A harness that cannot honour one falls back to a later place, never an\n * earlier one.** A loop with no safe point cannot do \"turn\", so it does\n * \"next\" — the message waits. It does not end the activation instead, which\n * is what falling back through an ordered scale used to do: ask for the\n * gentlest useful thing and get the most destructive one.\n */\n priority?: \"interrupt\" | \"turn\" | \"next\";\n /**\n * The sender's key for this delivery. Two deliveries with the same id are the\n * same delivery, so a retried send does not arrive twice.\n */\n id?: string;\n}\n"]}
|
package/dist/session/messages.js
CHANGED