@mikode13/harness 6.3.2 → 7.0.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/README.md CHANGED
@@ -161,8 +161,10 @@ example when the other one is out of quota.
161
161
  The optional `agent` field on an event identifies the orchestrator role that produced
162
162
  it (`planner`, `executor`, or `reviewer`). The optional `summary` on a `tool` event
163
163
  is narration only: it describes the model's call and is not the tool result. A failed
164
- configured command may also carry its optional `exitCode`; its output and changes
165
- still arrive in the tool result. A role label is applied by the orchestrator,
164
+ configured command may also carry its optional `exitCode`, and a failed call on the
165
+ model APIs its optional `error`: what the model was told went wrong, such as a patch
166
+ that did not apply. Both are narration; the command's output and changes still
167
+ arrive in the tool result. A role label is applied by the orchestrator,
166
168
  including retries and later rounds, so a nested agent cannot accidentally attribute
167
169
  its events to another role. Consumers should continue to handle events without these
168
170
  optional fields.
@@ -486,8 +488,15 @@ from the provider's cheap model, Claude Haiku or `gpt-5.6-luna`, billed with the
486
488
  run in `AgentResponse.runId`. Progress reports each change as a unified `diff` on the tool's
487
489
  `completed` event.
488
490
 
491
+ For debugging, `onTranscript` receives what the model saw in each run once the run ended,
492
+ completed, failed or cancelled. A `Transcript` has the run's `outcome`, the role it was of in
493
+ `createLLMOrchestrator`, or `explorer`, and a `content` of plain JSON: the instructions, the tool
494
+ definitions, the run's messages with what the tools returned, and the error a run that did not
495
+ complete ended with. `content` has no stable shape; read it, but do not build on it. A callback
496
+ that fails is logged, and the run stays as it ended.
497
+
489
498
  `createLLMOrchestrator()` takes the options of `createOrchestrator()` plus `workspace`,
490
- `maxSteps`, `compactAt`, `commands`, `formatter` and `summarizeUndone`, and returns a promise. Every role runs on the
499
+ `maxSteps`, `compactAt`, `commands`, `formatter`, `summarizeUndone` and `onTranscript`, and returns a promise. Every role runs on the
491
500
  model APIs:
492
501
 
493
502
  - the planner and the reviewer read, with a `showChanges` tool that gives the current task's
@@ -726,7 +735,12 @@ updates the spinner rather than printing a second line, and cancelling a turn cl
726
735
  its pending spinner state. Pass `--steps <file>` to append one JSON line per call to the
727
736
  model to that file: the call's tokens and what its context held, by origin, for measuring
728
737
  what a run spends. An explorer's call is written as the `subagent` event that carries it,
729
- which names the role that sent the explorer and its number.
738
+ which names the role that sent the explorer and its number. Pass `--debug <folder>` to keep,
739
+ in a folder for the session under it, every progress event in `events.jsonl` and, with
740
+ `--llm`, the transcript of every run of every agent, one numbered file each, such as
741
+ `003-executor-failed.json`. A failed tool call's event says what the model was told, in
742
+ `error`. They hold what the model read and what the commands printed, so only your user can
743
+ read them.
730
744
 
731
745
  `cli/cli.ts` currently enables `autoApprove` for its Agent SDK agents, not for `--llm`.
732
746
  This maps to each provider's permission-bypass mode and grants those processes
@@ -98,6 +98,11 @@ export type ProgressEvent = {
98
98
  summary?: string;
99
99
  /** The exit code of a configured command that ended with an error. Narration only. */
100
100
  exitCode?: number;
101
+ /**
102
+ * On `error`, for an agent on the model APIs: what the model was told went wrong, such
103
+ * as a patch that did not apply or a failed command's output. Narration only.
104
+ */
105
+ error?: string;
101
106
  /**
102
107
  * `in_progress` only once the call is about to run, after any approval. `denied` when
103
108
  * it never ran because no one allowed it, with no `in_progress` before it.
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/agent/domain/agent.ts"],"names":[],"mappings":"AAwDA,gDAAgD;AAChD,MAAM,CAAC,MAAM,cAAc,GAAa,GAAG,EAAE,CAAC,SAAS,CAAC","sourcesContent":["import type { Tokens } from '#src/shared/domain/tokens';\nimport type { Approver } from './approval.ts';\nimport type { Asker } from './question.ts';\n\n/**\n * How a run ended when it did not fail. Every token a run spends travels with its end: here\n * when it finishes, in `RecoverableError.tokens` or `UnrecoverableError.tokens` when it fails.\n */\nexport interface AgentResponse {\n\t/** The final text. Empty when the run produced none, for example a turn that only edited files. */\n\tresponse: string;\n\t/**\n\t * Missing when any call in the run completed without reporting usage, which is not the same\n\t * as zero: a partial sum would look complete.\n\t */\n\ttokens?: Tokens;\n\t/** Wall-clock seconds the consumer waited for the run, retries and every role included. */\n\tduration: number;\n\t/**\n\t * The run the workspace's history recorded, when this run wrote through the harness's write\n\t * tools. Absent for a run that wrote nothing, and from the Agent SDK engines, whose changes\n\t * the history does not record.\n\t */\n\trunId?: string;\n}\n\nexport type Callback = (item: ProgressEvent) => void;\n\n/**\n * What a run needs besides its prompt. InstructedAgent passes it on whole. OrchestratorAgent\n * copies its own enumerable fields and replaces only `onProgress` per role; RetryingAgent does\n * the same for a run with `ask`, replacing only `ask`. A field must therefore be an own\n * enumerable one to reach every agent.\n */\nexport interface RunOptions {\n\t/**\n\t * Cancels the run, which then rejects with the signal's reason: an `AbortError`, or a\n\t * `TimeoutError` from `AbortSignal.timeout`. `isAbortError` recognizes both.\n\t */\n\tsignal: AbortSignal;\n\t/** Receives the run's live activity. Without it, the run is silent. */\n\tonProgress?: Callback | undefined;\n\t/**\n\t * Asked before a model-backed agent runs a `destructive` tool call. Without it, such a call\n\t * is denied. An agent built with `autoApprove` never asks, and the Agent SDK engines ignore\n\t * it: their own permission systems decide.\n\t */\n\tapprove?: Approver | undefined;\n\t/**\n\t * Answers what a model-backed agent asks the user, through its `askUser` tool, when a\n\t * decision is the user's to make. Without it the agent has no such tool. The Agent SDK\n\t * engines ignore it.\n\t */\n\task?: Asker | undefined;\n}\n\n/** The `onProgress` of a run that gave none. */\nexport const ignoreProgress: Callback = () => undefined;\n\n/**\n * Live activity during a run, for narration only: the result travels in `AgentResponse`.\n * New event types can arrive in a minor release, so render the types you know and ignore\n * the rest instead of switching over them exhaustively with a `never` check.\n */\nexport type ProgressEvent =\n\t| { type: 'command'; command: string; exitCode?: number; agent?: ProgressAgent }\n\t| { type: 'reasoning'; message: string; agent?: ProgressAgent }\n\t| { type: 'search'; query: string; agent?: ProgressAgent }\n\t| {\n\t\t\ttype: 'fileChange';\n\t\t\tchanges: { path: string; kind: 'add' | 'update' | 'delete' }[];\n\t\t\tagent?: ProgressAgent;\n\t }\n\t| { type: 'mcpTool'; server: string; tool: string; status: string; agent?: ProgressAgent }\n\t| { type: 'agentMessage'; message: string; agent?: ProgressAgent }\n\t/** `id` pairs a call's end with its start when one step calls the same tool more than once. */\n\t| {\n\t\t\ttype: 'tool';\n\t\t\tid: string;\n\t\t\tname: string;\n\t\t\tagent?: ProgressAgent;\n\t\t\t/** A short, tool-owned description of the call. Narration only. */\n\t\t\tsummary?: string;\n\t\t\t/** The exit code of a configured command that ended with an error. Narration only. */\n\t\t\texitCode?: number;\n\t\t\t/**\n\t\t\t * `in_progress` only once the call is about to run, after any approval. `denied` when\n\t\t\t * it never ran because no one allowed it, with no `in_progress` before it.\n\t\t\t */\n\t\t\tstatus: 'in_progress' | 'completed' | 'error' | 'denied';\n\t\t\t/**\n\t\t\t * On `completed`, for a call that changed a file through the harness's write tools: the\n\t\t\t * change as a unified diff, for the person watching. Narration only; the run's whole\n\t\t\t * record is the history's `changes`.\n\t\t\t */\n\t\t\tdiff?: string;\n\t }\n\t| { type: 'todoList'; items: { text: string; completed: boolean }[]; agent?: ProgressAgent }\n\t| { type: 'turnStarted'; agent?: ProgressAgent }\n\t| { type: 'turnEnded'; agent?: ProgressAgent }\n\t/**\n\t * One billed call to the model by an agent on the model APIs, including one the model\n\t * stopped early or the client turned into an error: what the call sent and what it cost.\n\t * Narration only: the run's total is `AgentResponse.tokens`, or the failure's `tokens`.\n\t */\n\t| {\n\t\t\ttype: 'step';\n\t\t\t/** 1 for the first call of the run. */\n\t\t\tstep: number;\n\t\t\t/** Missing when the provider did not report this call's usage. */\n\t\t\ttokens?: Tokens;\n\t\t\tcontext: StepContext;\n\t\t\tagent?: ProgressAgent;\n\t }\n\t/**\n\t * A workflow's stage asks its agent for an answer; `attempt` is 2 or more when the previous\n\t * answer was invalid. Stages run one at a time, so the events that follow, until the next\n\t * workflow event, are this stage's agent's.\n\t */\n\t| { type: 'workflowStage'; stage: string; attempt: number; agent?: ProgressAgent }\n\t/** The transition a stage's valid answer selected, and the stage it leads to. */\n\t| {\n\t\t\ttype: 'workflowTransition';\n\t\t\tstage: string;\n\t\t\ttransition: 'go' | 'stop' | 'complete';\n\t\t\t/** Absent after `stop` or `complete`. */\n\t\t\tnextStage?: string;\n\t\t\tagent?: ProgressAgent;\n\t }\n\t/**\n\t * An event of a subagent that a tool call started, such as one of the explorers an `explore`\n\t * call runs at once. `callId` is the `id` of that call's `tool` events, and `subagent`\n\t * numbers its subagents from 1, so the events of agents running in parallel stay apart.\n\t */\n\t| {\n\t\t\ttype: 'subagent';\n\t\t\tcallId: string;\n\t\t\tsubagent: number;\n\t\t\t/** What the subagent was asked. */\n\t\t\ttask: string;\n\t\t\tevent: ProgressEvent;\n\t\t\tagent?: ProgressAgent;\n\t };\n\n/**\n * What one call to the model sent, in characters by where it came from: an estimate of size\n * for finding what fills a context, not a token count.\n */\nexport interface StepContext {\n\t/** The system prompt. */\n\tinstructions: number;\n\t/** The tool definitions. */\n\ttools: number;\n\t/**\n\t * The text of the user's prompts and the model's answers, and the provider's summary of the\n\t * turns before it once it has compacted them: only what the call sent.\n\t */\n\tmessages: number;\n\t/** Reasoning the model produced earlier and is sent back: its provider's own signed or encrypted blocks. */\n\treasoning: number;\n\t/** The input of every tool call so far. */\n\ttoolCalls: number;\n\t/** Every tool result so far, by tool, largest first. */\n\ttoolResults: { tool: string; characters: number; calls: number }[];\n\t/** The largest single results, each with its call's summary when the tool gives one. */\n\tlargestResults: { tool: string; characters: number; summary?: string }[];\n}\n\n/** A role in the fixed planner → executor → reviewer workflow. */\nexport type ProgressAgent = 'planner' | 'executor' | 'reviewer';\n\n/**\n * The contract every engine (CodexAgent, ClaudeAgent, future providers) and every\n * decorator (RetryingAgent, OrchestratorAgent) is built against.\n *\n * Implementers MUST only ever reject with `RecoverableError` or `UnrecoverableError`\n * (see src/shared/domain/errors.ts) — never a raw SDK error, a plain `Error`, or anything else leaked\n * unclassified. Every consumer of `Agent` (RetryingAgent's retry decision,\n * OrchestratorAgent's failure handling) `instanceof`-checks against those two types to\n * decide what to do next; a leaked, unclassified error bypasses that decision\n * entirely — it gets retried when it shouldn't be, or crashes a run that a retry\n * would have recovered. Wrap every call into the underlying SDK so nothing escapes\n * unclassified, including failures the SDK itself doesn't model as a domain error\n * (network errors, malformed responses, etc.); `classifyProviderFailure` does this.\n *\n * Cancellation is the one exception: an `AbortError`, or the `TimeoutError` of\n * `AbortSignal.timeout`, must propagate unchanged, because\n * consumers check for it before either error type.\n */\nexport interface Agent {\n\trun(prompt: string, options: RunOptions): Promise<AgentResponse>;\n}\n"]}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/agent/domain/agent.ts"],"names":[],"mappings":"AAwDA,gDAAgD;AAChD,MAAM,CAAC,MAAM,cAAc,GAAa,GAAG,EAAE,CAAC,SAAS,CAAC","sourcesContent":["import type { Tokens } from '#src/shared/domain/tokens';\nimport type { Approver } from './approval.ts';\nimport type { Asker } from './question.ts';\n\n/**\n * How a run ended when it did not fail. Every token a run spends travels with its end: here\n * when it finishes, in `RecoverableError.tokens` or `UnrecoverableError.tokens` when it fails.\n */\nexport interface AgentResponse {\n\t/** The final text. Empty when the run produced none, for example a turn that only edited files. */\n\tresponse: string;\n\t/**\n\t * Missing when any call in the run completed without reporting usage, which is not the same\n\t * as zero: a partial sum would look complete.\n\t */\n\ttokens?: Tokens;\n\t/** Wall-clock seconds the consumer waited for the run, retries and every role included. */\n\tduration: number;\n\t/**\n\t * The run the workspace's history recorded, when this run wrote through the harness's write\n\t * tools. Absent for a run that wrote nothing, and from the Agent SDK engines, whose changes\n\t * the history does not record.\n\t */\n\trunId?: string;\n}\n\nexport type Callback = (item: ProgressEvent) => void;\n\n/**\n * What a run needs besides its prompt. InstructedAgent passes it on whole. OrchestratorAgent\n * copies its own enumerable fields and replaces only `onProgress` per role; RetryingAgent does\n * the same for a run with `ask`, replacing only `ask`. A field must therefore be an own\n * enumerable one to reach every agent.\n */\nexport interface RunOptions {\n\t/**\n\t * Cancels the run, which then rejects with the signal's reason: an `AbortError`, or a\n\t * `TimeoutError` from `AbortSignal.timeout`. `isAbortError` recognizes both.\n\t */\n\tsignal: AbortSignal;\n\t/** Receives the run's live activity. Without it, the run is silent. */\n\tonProgress?: Callback | undefined;\n\t/**\n\t * Asked before a model-backed agent runs a `destructive` tool call. Without it, such a call\n\t * is denied. An agent built with `autoApprove` never asks, and the Agent SDK engines ignore\n\t * it: their own permission systems decide.\n\t */\n\tapprove?: Approver | undefined;\n\t/**\n\t * Answers what a model-backed agent asks the user, through its `askUser` tool, when a\n\t * decision is the user's to make. Without it the agent has no such tool. The Agent SDK\n\t * engines ignore it.\n\t */\n\task?: Asker | undefined;\n}\n\n/** The `onProgress` of a run that gave none. */\nexport const ignoreProgress: Callback = () => undefined;\n\n/**\n * Live activity during a run, for narration only: the result travels in `AgentResponse`.\n * New event types can arrive in a minor release, so render the types you know and ignore\n * the rest instead of switching over them exhaustively with a `never` check.\n */\nexport type ProgressEvent =\n\t| { type: 'command'; command: string; exitCode?: number; agent?: ProgressAgent }\n\t| { type: 'reasoning'; message: string; agent?: ProgressAgent }\n\t| { type: 'search'; query: string; agent?: ProgressAgent }\n\t| {\n\t\t\ttype: 'fileChange';\n\t\t\tchanges: { path: string; kind: 'add' | 'update' | 'delete' }[];\n\t\t\tagent?: ProgressAgent;\n\t }\n\t| { type: 'mcpTool'; server: string; tool: string; status: string; agent?: ProgressAgent }\n\t| { type: 'agentMessage'; message: string; agent?: ProgressAgent }\n\t/** `id` pairs a call's end with its start when one step calls the same tool more than once. */\n\t| {\n\t\t\ttype: 'tool';\n\t\t\tid: string;\n\t\t\tname: string;\n\t\t\tagent?: ProgressAgent;\n\t\t\t/** A short, tool-owned description of the call. Narration only. */\n\t\t\tsummary?: string;\n\t\t\t/** The exit code of a configured command that ended with an error. Narration only. */\n\t\t\texitCode?: number;\n\t\t\t/**\n\t\t\t * On `error`, for an agent on the model APIs: what the model was told went wrong, such\n\t\t\t * as a patch that did not apply or a failed command's output. Narration only.\n\t\t\t */\n\t\t\terror?: string;\n\t\t\t/**\n\t\t\t * `in_progress` only once the call is about to run, after any approval. `denied` when\n\t\t\t * it never ran because no one allowed it, with no `in_progress` before it.\n\t\t\t */\n\t\t\tstatus: 'in_progress' | 'completed' | 'error' | 'denied';\n\t\t\t/**\n\t\t\t * On `completed`, for a call that changed a file through the harness's write tools: the\n\t\t\t * change as a unified diff, for the person watching. Narration only; the run's whole\n\t\t\t * record is the history's `changes`.\n\t\t\t */\n\t\t\tdiff?: string;\n\t }\n\t| { type: 'todoList'; items: { text: string; completed: boolean }[]; agent?: ProgressAgent }\n\t| { type: 'turnStarted'; agent?: ProgressAgent }\n\t| { type: 'turnEnded'; agent?: ProgressAgent }\n\t/**\n\t * One billed call to the model by an agent on the model APIs, including one the model\n\t * stopped early or the client turned into an error: what the call sent and what it cost.\n\t * Narration only: the run's total is `AgentResponse.tokens`, or the failure's `tokens`.\n\t */\n\t| {\n\t\t\ttype: 'step';\n\t\t\t/** 1 for the first call of the run. */\n\t\t\tstep: number;\n\t\t\t/** Missing when the provider did not report this call's usage. */\n\t\t\ttokens?: Tokens;\n\t\t\tcontext: StepContext;\n\t\t\tagent?: ProgressAgent;\n\t }\n\t/**\n\t * A workflow's stage asks its agent for an answer; `attempt` is 2 or more when the previous\n\t * answer was invalid. Stages run one at a time, so the events that follow, until the next\n\t * workflow event, are this stage's agent's.\n\t */\n\t| { type: 'workflowStage'; stage: string; attempt: number; agent?: ProgressAgent }\n\t/** The transition a stage's valid answer selected, and the stage it leads to. */\n\t| {\n\t\t\ttype: 'workflowTransition';\n\t\t\tstage: string;\n\t\t\ttransition: 'go' | 'stop' | 'complete';\n\t\t\t/** Absent after `stop` or `complete`. */\n\t\t\tnextStage?: string;\n\t\t\tagent?: ProgressAgent;\n\t }\n\t/**\n\t * An event of a subagent that a tool call started, such as one of the explorers an `explore`\n\t * call runs at once. `callId` is the `id` of that call's `tool` events, and `subagent`\n\t * numbers its subagents from 1, so the events of agents running in parallel stay apart.\n\t */\n\t| {\n\t\t\ttype: 'subagent';\n\t\t\tcallId: string;\n\t\t\tsubagent: number;\n\t\t\t/** What the subagent was asked. */\n\t\t\ttask: string;\n\t\t\tevent: ProgressEvent;\n\t\t\tagent?: ProgressAgent;\n\t };\n\n/**\n * What one call to the model sent, in characters by where it came from: an estimate of size\n * for finding what fills a context, not a token count.\n */\nexport interface StepContext {\n\t/** The system prompt. */\n\tinstructions: number;\n\t/** The tool definitions. */\n\ttools: number;\n\t/**\n\t * The text of the user's prompts and the model's answers, and the provider's summary of the\n\t * turns before it once it has compacted them: only what the call sent.\n\t */\n\tmessages: number;\n\t/** Reasoning the model produced earlier and is sent back: its provider's own signed or encrypted blocks. */\n\treasoning: number;\n\t/** The input of every tool call so far. */\n\ttoolCalls: number;\n\t/** Every tool result so far, by tool, largest first. */\n\ttoolResults: { tool: string; characters: number; calls: number }[];\n\t/** The largest single results, each with its call's summary when the tool gives one. */\n\tlargestResults: { tool: string; characters: number; summary?: string }[];\n}\n\n/** A role in the fixed planner → executor → reviewer workflow. */\nexport type ProgressAgent = 'planner' | 'executor' | 'reviewer';\n\n/**\n * The contract every engine (CodexAgent, ClaudeAgent, future providers) and every\n * decorator (RetryingAgent, OrchestratorAgent) is built against.\n *\n * Implementers MUST only ever reject with `RecoverableError` or `UnrecoverableError`\n * (see src/shared/domain/errors.ts) — never a raw SDK error, a plain `Error`, or anything else leaked\n * unclassified. Every consumer of `Agent` (RetryingAgent's retry decision,\n * OrchestratorAgent's failure handling) `instanceof`-checks against those two types to\n * decide what to do next; a leaked, unclassified error bypasses that decision\n * entirely — it gets retried when it shouldn't be, or crashes a run that a retry\n * would have recovered. Wrap every call into the underlying SDK so nothing escapes\n * unclassified, including failures the SDK itself doesn't model as a domain error\n * (network errors, malformed responses, etc.); `classifyProviderFailure` does this.\n *\n * Cancellation is the one exception: an `AbortError`, or the `TimeoutError` of\n * `AbortSignal.timeout`, must propagate unchanged, because\n * consumers check for it before either error type.\n */\nexport interface Agent {\n\trun(prompt: string, options: RunOptions): Promise<AgentResponse>;\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import type { ProgressAgent } from './agent.ts';
2
+ /**
3
+ * What the model of one run saw, for a person debugging a run that went wrong. Only agents on
4
+ * the model APIs produce one.
5
+ */
6
+ export interface Transcript {
7
+ /**
8
+ * In `createLLMOrchestrator`, the role the run was of, or `explorer` for an explorer a role
9
+ * sent. Missing for an agent from `createLLMAgent`.
10
+ */
11
+ agent?: ProgressAgent | 'explorer';
12
+ /** How the run ended. A failed run may be retried, and each attempt has its own transcript. */
13
+ outcome: 'completed' | 'failed' | 'cancelled';
14
+ /**
15
+ * Plain JSON for a person to read: the instructions, the tool definitions, every message of
16
+ * the run's context with the model's last answer and what the tools returned, and the error
17
+ * a run that did not complete ended with. Unstable: its shape can change in any release, so
18
+ * read it, but do not build on it.
19
+ */
20
+ content: unknown;
21
+ }
22
+ /**
23
+ * Receives each run's transcript once the run ended, however it ended. A failure here is
24
+ * logged, never the run's: debugging must not change what it observes.
25
+ */
26
+ export type TranscriptCallback = (transcript: Transcript) => void | Promise<void>;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../../src/agent/domain/transcript.ts"],"names":[],"mappings":"","sourcesContent":["import type { ProgressAgent } from './agent.ts';\n\n/**\n * What the model of one run saw, for a person debugging a run that went wrong. Only agents on\n * the model APIs produce one.\n */\nexport interface Transcript {\n\t/**\n\t * In `createLLMOrchestrator`, the role the run was of, or `explorer` for an explorer a role\n\t * sent. Missing for an agent from `createLLMAgent`.\n\t */\n\tagent?: ProgressAgent | 'explorer';\n\t/** How the run ended. A failed run may be retried, and each attempt has its own transcript. */\n\toutcome: 'completed' | 'failed' | 'cancelled';\n\t/**\n\t * Plain JSON for a person to read: the instructions, the tool definitions, every message of\n\t * the run's context with the model's last answer and what the tools returned, and the error\n\t * a run that did not complete ended with. Unstable: its shape can change in any release, so\n\t * read it, but do not build on it.\n\t */\n\tcontent: unknown;\n}\n\n/**\n * Receives each run's transcript once the run ended, however it ended. A failure here is\n * logged, never the run's: debugging must not change what it observes.\n */\nexport type TranscriptCallback = (transcript: Transcript) => void | Promise<void>;\n"]}
@@ -1,6 +1,7 @@
1
1
  import { type Agent, type AgentResponse, type RunOptions } from '#src/agent/domain/agent';
2
2
  import type { LLMClient } from '#src/llm/domain/llm';
3
3
  import type { Message } from '#src/llm/domain/message';
4
+ import type { TranscriptCallback } from '#src/agent/domain/transcript';
4
5
  import { type AgentTool } from '#src/tools/domain/preparedCall';
5
6
  import type { ILogger } from '#src/shared/domain/logger';
6
7
  import { type HistoryReader } from './historyFollower.ts';
@@ -22,9 +23,10 @@ export declare class LLMAgent implements Agent {
22
23
  private readonly logger;
23
24
  private readonly history;
24
25
  private readonly summarizer;
26
+ private readonly onTranscript;
25
27
  private seenRevision;
26
28
  private readonly reads;
27
- constructor({ llmClient, messages, tools, maxSteps, autoApprove, logger, history, summarizer, }: {
29
+ constructor({ llmClient, messages, tools, maxSteps, autoApprove, logger, history, summarizer, onTranscript, }: {
28
30
  llmClient: LLMClient;
29
31
  messages?: Message[];
30
32
  tools?: AgentTool[];
@@ -45,6 +47,8 @@ export declare class LLMAgent implements Agent {
45
47
  * one, the model is told what those turns asked, word for word.
46
48
  */
47
49
  summarizer?: LLMClient;
50
+ /** Receives what the model saw in each run, once the run ended. */
51
+ onTranscript?: TranscriptCallback;
48
52
  });
49
53
  private followHistory;
50
54
  /**
@@ -86,4 +90,7 @@ export declare class LLMAgent implements Agent {
86
90
  */
87
91
  private finishContext;
88
92
  private runSteps;
93
+ /** Hands the run's transcript to the consumer, whose failure is logged, not the run's. */
94
+ private transcribe;
95
+ private takeSteps;
89
96
  }
@@ -27,6 +27,7 @@ function describePart(part) {
27
27
  id: part.callId,
28
28
  name: part.name,
29
29
  status: part.isError ? 'error' : 'completed',
30
+ ...(part.isError ? { error: part.output } : {}),
30
31
  };
31
32
  case 'providerData':
32
33
  // Opaque by design: its readable side, if any, arrives as a reasoning part.
@@ -121,11 +122,12 @@ export class LLMAgent {
121
122
  logger;
122
123
  history;
123
124
  summarizer;
125
+ onTranscript;
124
126
  // The latest move through the history this conversation has followed.
125
127
  seenRevision = 0;
126
128
  // What this conversation has seen of each file, so an edit starts from a version it read.
127
129
  reads = new ReadRegistry();
128
- constructor({ llmClient, messages, tools = [], maxSteps = 65, autoApprove = false, logger, history, summarizer, }) {
130
+ constructor({ llmClient, messages, tools = [], maxSteps = 65, autoApprove = false, logger, history, summarizer, onTranscript, }) {
129
131
  if (!Number.isInteger(maxSteps) || maxSteps < 1) {
130
132
  throw new InvalidAgentConfigError(`maxSteps must be a positive integer; got ${String(maxSteps)}`);
131
133
  }
@@ -136,6 +138,7 @@ export class LLMAgent {
136
138
  this.logger = logger;
137
139
  this.history = history;
138
140
  this.summarizer = summarizer;
141
+ this.onTranscript = onTranscript;
139
142
  this.tools = new Map(tools.map(tool => [tool.name, tool]));
140
143
  if (this.tools.size !== tools.length) {
141
144
  // The model calls tools by name, so a second one with the same name could never run.
@@ -518,6 +521,43 @@ export class LLMAgent {
518
521
  }
519
522
  }
520
523
  async runSteps(prompt, options, context) {
524
+ const seen = { messages: () => [], tools: this.toolDefinitions };
525
+ let response;
526
+ try {
527
+ response = await this.takeSteps(prompt, options, context, seen);
528
+ }
529
+ catch (error) {
530
+ await this.transcribe(seen, isAbortError(error) ? 'cancelled' : 'failed', error);
531
+ throw error;
532
+ }
533
+ await this.transcribe(seen, 'completed');
534
+ return response;
535
+ }
536
+ /** Hands the run's transcript to the consumer, whose failure is logged, not the run's. */
537
+ async transcribe(seen, outcome, error) {
538
+ if (!this.onTranscript)
539
+ return;
540
+ try {
541
+ // A copy, so a consumer that changes it cannot change the agent's tools or conversation.
542
+ const content = structuredClone({
543
+ instructions: this.llmClient.systemPrompt,
544
+ tools: seen.tools.map(({ name, description, inputSchema }) => ({
545
+ name,
546
+ description,
547
+ inputSchema,
548
+ })),
549
+ messages: seen.messages(),
550
+ ...(outcome === 'completed' ? {} : { error: describeFailure(error) }),
551
+ });
552
+ await this.onTranscript({ outcome, content });
553
+ }
554
+ catch (failure) {
555
+ treatErrors(() => {
556
+ this.logger?.warn(`The run's transcript could not be handed over: ${describeFailure(failure)}`);
557
+ }, classifyHostFailure, 'LLM agent logger failed');
558
+ }
559
+ }
560
+ async takeSteps(prompt, options, context, seen) {
521
561
  const { signal, onProgress: callback = ignoreProgress } = options;
522
562
  const start = Date.now();
523
563
  const runMessages = [{ role: 'user', content: [{ type: 'text', text: prompt }] }];
@@ -529,6 +569,8 @@ export class LLMAgent {
529
569
  // The turn this one follows: the last recorded, unless the workspace moved since.
530
570
  let after = this.conversation.currentTurn;
531
571
  let followed;
572
+ // What the model has seen so far, whichever turn the run ends up following.
573
+ seen.messages = () => [...this.conversation.contextAfter(after), ...runMessages];
532
574
  try {
533
575
  if (this.history) {
534
576
  followed = await this.followHistory(this.history);
@@ -582,6 +624,7 @@ export class LLMAgent {
582
624
  // a consumer's tool of that name, which the consumer gave first and which stays theirs.
583
625
  const offersAsk = options.ask !== undefined && !this.tools.has(askUserName);
584
626
  const tools = offersAsk ? [...this.toolDefinitions, askUserDefinition] : this.toolDefinitions;
627
+ seen.tools = tools;
585
628
  for (let step = 1; step <= this.maxSteps; step++) {
586
629
  const { response, context: sent } = await this.llmCall(runMessages, after, {
587
630
  signal,
@@ -1 +1 @@
1
- {"version":3,"file":"llmAgent.js","sourceRoot":"","sources":["../../../../src/engines/domain/model/llmAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ApprovalDecision,\n\ttype ApprovalRequest,\n\ttype Approver,\n\treadDecision,\n} from '#src/agent/domain/approval';\nimport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressEvent,\n\ttype RunOptions,\n\tignoreProgress,\n} from '#src/agent/domain/agent';\nimport {\n\ttype RunEnd,\n\tRunContext,\n\trunContextOf,\n\twithRunContext,\n} from '#src/agent/domain/runContext';\nimport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '#src/shared/domain/errors';\nimport {\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\tdescribeFailure,\n\ttreatErrors,\n} from '#src/shared/domain/providerFailure';\nimport { Conversation } from '#src/llm/domain/conversation';\nimport type { LLMClient, LLMResponse } from '#src/llm/domain/llm';\nimport type { Message, MessagePart, ToolCallPart, ToolResultPart } from '#src/llm/domain/message';\nimport { asNative, nativeOf, type ToolDefinition } from '#src/llm/domain/tool';\nimport type { Asker } from '#src/agent/domain/question';\nimport {\n\ttype AgentTool,\n\ttype PreparedCall,\n\tprepareCall,\n\tToolExecutionError,\n} from '#src/tools/domain/preparedCall';\nimport { ReadRegistry, type ToolCallContext } from '#src/tools/domain/readRegistry';\n\n/** What every tool call of one batch shares; each call adds its own id. */\ntype RunToolContext = Omit<ToolCallContext, 'callId'>;\nimport { InvalidToolInputError } from '#src/tools/domain/tool';\nimport { isAbortError } from '#src/shared/domain/isAbortError';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { addTokens, type Tokens } from '#src/shared/domain/tokens';\nimport { measureContext } from './stepContext.ts';\nimport {\n\taskUserDefinition,\n\taskUserName,\n\tdescribeAnswers,\n\treadAnswers,\n\treadQuestions,\n\tsummarizeQuestions,\n} from './askUser.ts';\nimport {\n\ttype Followed,\n\tfollowHistory,\n\ttype HistoryReader,\n\ttranscriptOf,\n\tundoNote,\n} from './historyFollower.ts';\n\nfunction describePart(part: MessagePart): ProgressEvent | undefined {\n\tswitch (part.type) {\n\t\tcase 'text':\n\t\t\treturn { type: 'agentMessage', message: part.text };\n\t\tcase 'reasoning':\n\t\t\treturn { type: 'reasoning', message: part.text };\n\t\tcase 'toolCall':\n\t\t\treturn { type: 'tool', id: part.id, name: part.name, status: 'in_progress' };\n\t\tcase 'toolResult':\n\t\t\treturn {\n\t\t\t\ttype: 'tool',\n\t\t\t\tid: part.callId,\n\t\t\t\tname: part.name,\n\t\t\t\tstatus: part.isError ? 'error' : 'completed',\n\t\t\t};\n\t\tcase 'providerData':\n\t\t\t// Opaque by design: its readable side, if any, arrives as a reasoning part.\n\t\t\treturn undefined;\n\t\tcase 'compaction':\n\t\t\t// The provider's, for its client to send back; the step's context shows its effect.\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Whether a run reached a tool's `execute`. A missing tool or a denied call never does, so it\n * has no effect a retry could repeat.\n */\ninterface RunEffects {\n\ttoolRan: boolean;\n}\n\nfunction narrate(part: MessagePart, callback: Callback, summary?: string, exitCode?: number): void {\n\tconst event = describePart(part);\n\tif (!event) return;\n\tif (event.type === 'tool') {\n\t\tif (summary !== undefined) event.summary = summary;\n\t\tif (exitCode !== undefined) event.exitCode = exitCode;\n\t}\n\temit(event, callback);\n}\n\nfunction emit(event: ProgressEvent, callback: Callback): void {\n\ttreatErrors(\n\t\t() => {\n\t\t\tcallback(event);\n\t\t},\n\t\tclassifyHostFailure,\n\t\t'LLM agent progress callback failed',\n\t);\n}\n\n/** `value` with the keys of every object sorted, so equal inputs serialize alike. */\nfunction canonical(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(canonical);\n\tif (typeof value !== 'object' || value === null) return value;\n\treturn Object.fromEntries(\n\t\tObject.entries(value)\n\t\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n\t\t\t.map(([key, inner]) => [key, canonical(inner)]),\n\t);\n}\n\n// A model that asks for exactly the same calls this many times in a row is stuck: it already\n// has what they return, and running them again changes nothing.\nconst maxRepeatedSteps = 5;\n\n/** How many steps in a row have asked for exactly the same tool calls, with the same input. */\nclass RepeatedCalls {\n\tprivate last: string | undefined;\n\tprivate times = 0;\n\n\tcount(calls: readonly ToolCallPart[]): number {\n\t\t// Keys sorted at every level: the same input with its properties in another order is the\n\t\t// same call. Arrays, and the order of the calls, keep theirs.\n\t\tconst key = JSON.stringify(calls.map(call => [call.name, canonical(call.input)]));\n\t\tthis.times = key === this.last ? this.times + 1 : 1;\n\t\tthis.last = key;\n\t\treturn this.times;\n\t}\n}\n\n// A command that ends exactly as it did the last times, in output too, this many times in a row\n// means the model's changes in between are not reaching what the command checks.\nconst maxRepeatedEndings = 5;\n\n/**\n * How many times in a row each command call, by tool and input, has ended exactly the same way.\n * Calls in between to other tools, or to other commands, do not break the count.\n */\nclass RepeatedEndings {\n\tprivate readonly last = new Map<string, { ending: string; times: number }>();\n\n\tcount(call: ToolCallPart, ending: string | undefined): number {\n\t\tconst key = JSON.stringify([call.name, canonical(call.input)]);\n\t\t// A call that never ran a command, such as one denied, says nothing of how it ends.\n\t\tif (ending === undefined) {\n\t\t\tthis.last.delete(key);\n\t\t\treturn 0;\n\t\t}\n\t\tconst previous = this.last.get(key);\n\t\tconst times = previous?.ending === ending ? previous.times + 1 : 1;\n\t\tthis.last.set(key, { ending, times });\n\t\treturn times;\n\t}\n}\n\n/**\n * An agent whose conversation is owned by MiKode: every run sends the whole context to a\n * stateless `LLMClient`. Within a run the model may call the agent's tools; the agent runs them\n * and sends their results back until the model answers without calling one. Turn boundaries\n * are the consumer's to emit, as with the other engines; this agent only narrates what the\n * model produced and what its tools did.\n */\nexport class LLMAgent implements Agent {\n\tprivate readonly llmClient: LLMClient;\n\tprivate readonly conversation: Conversation;\n\tprivate readonly tools: Map<string, AgentTool>;\n\tprivate readonly toolDefinitions: ToolDefinition[];\n\t// Each call's summary, as its tool gave it when the call ran, so measuring a step that\n\t// resends the call never runs a consumer's summarizer again.\n\tprivate readonly callSummaries = new Map<string, string>();\n\tprivate readonly maxSteps: number;\n\tprivate readonly autoApprove: boolean;\n\tprivate readonly logger: ILogger | undefined;\n\tprivate readonly history: HistoryReader | undefined;\n\tprivate readonly summarizer: LLMClient | undefined;\n\t// The latest move through the history this conversation has followed.\n\tprivate seenRevision = 0;\n\t// What this conversation has seen of each file, so an edit starts from a version it read.\n\tprivate readonly reads = new ReadRegistry();\n\n\tconstructor({\n\t\tllmClient,\n\t\tmessages,\n\t\ttools = [],\n\t\tmaxSteps = 65,\n\t\tautoApprove = false,\n\t\tlogger,\n\t\thistory,\n\t\tsummarizer,\n\t}: {\n\t\tllmClient: LLMClient;\n\t\tmessages?: Message[];\n\t\ttools?: AgentTool[];\n\t\t/** How many calls to the model one run may make before it fails. Defaults to 65. */\n\t\tmaxSteps?: number;\n\t\t/** Runs every tool call without asking, `destructive` ones included. Meant for CI. */\n\t\tautoApprove?: boolean;\n\t\t/** Where a failure the agent absorbs is reported. The factories always pass one. */\n\t\tlogger?: ILogger;\n\t\t/**\n\t\t * The history of the workspace this agent writes to. With it, each run first follows the\n\t\t * moves the user made through that history: the conversation goes back with the\n\t\t * workspace, and the model is told what was undone.\n\t\t */\n\t\thistory?: HistoryReader;\n\t\t/**\n\t\t * A cheap model that summarizes what the undone turns tried and what went wrong. Without\n\t\t * one, the model is told what those turns asked, word for word.\n\t\t */\n\t\tsummarizer?: LLMClient;\n\t}) {\n\t\tif (!Number.isInteger(maxSteps) || maxSteps < 1) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`maxSteps must be a positive integer; got ${String(maxSteps)}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.llmClient = llmClient;\n\t\tthis.conversation = new Conversation(messages);\n\t\tthis.maxSteps = maxSteps;\n\t\tthis.autoApprove = autoApprove;\n\t\tthis.logger = logger;\n\t\tthis.history = history;\n\t\tthis.summarizer = summarizer;\n\t\tthis.tools = new Map(tools.map(tool => [tool.name, tool]));\n\t\tif (this.tools.size !== tools.length) {\n\t\t\t// The model calls tools by name, so a second one with the same name could never run.\n\t\t\tthrow new InvalidAgentConfigError('Two tools share a name; each name must be unique');\n\t\t}\n\t\t// The client only describes the tools to the model; running them stays with the agent.\n\t\tthis.toolDefinitions = tools.map(tool => {\n\t\t\tconst definition = {\n\t\t\t\tname: tool.name,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tinputSchema: tool.inputSchema,\n\t\t\t};\n\t\t\tconst native = nativeOf(tool);\n\t\t\tif (native === undefined) return definition;\n\t\t\t// Checked now, not on the first call: an agent its client cannot serve is a setup error.\n\t\t\tif (llmClient.supportsNative?.(native) !== true) {\n\t\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t\t`The tool \"${tool.name}\" is the native \"${native}\" tool, which this model client cannot declare`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn asNative(definition, native);\n\t\t});\n\t}\n\n\tprivate async followHistory(history: HistoryReader): Promise<Followed> {\n\t\ttry {\n\t\t\treturn await followHistory(this.conversation, history, this.seenRevision);\n\t\t} catch (error) {\n\t\t\tthrow classifyLocalFailure(error, 'The workspace history could not be read');\n\t\t}\n\t}\n\n\t/**\n\t * Asks the summarizer what the undone turns tried and what went wrong. A summary is a help,\n\t * not a need: one that fails is reported and the plain note is used instead.\n\t */\n\tprivate async summarizeUndone(\n\t\tfollowed: Followed,\n\t\tsignal: AbortSignal,\n\t): Promise<{ text?: string; usage?: Tokens; called: boolean }> {\n\t\tif (!this.summarizer) return { called: false };\n\t\tconst reasons = followed.revisions.flatMap(revision =>\n\t\t\trevision.reason ? [revision.reason] : [],\n\t\t);\n\t\tconst prompt = [\n\t\t\t'The user undid the work in the conversation below and moved the workspace back to before it.',\n\t\t\treasons.length > 0 ? `Their reason: ${reasons.map(reason => `«${reason}»`).join(' ')}` : '',\n\t\t\t'In at most five short lines, say what was tried, why it went wrong or why the user went back, and what could be done better. Plain text, no preamble.',\n\t\t\t'',\n\t\t\ttranscriptOf(this.conversation, followed.undone),\n\t\t].join('\\n');\n\n\t\tlet response: LLMResponse;\n\t\ttry {\n\t\t\tresponse = await this.summarizer.send(\n\t\t\t\t{ context: [{ role: 'user', content: [{ type: 'text', text: prompt }] }], tools: [] },\n\t\t\t\tsignal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (isAbortError(error)) throw error;\n\t\t\tthis.warnSummaryFailed(describeFailure(error));\n\t\t\treturn { called: true };\n\t\t}\n\n\t\tconst usage = response.usage ? { usage: response.usage } : {};\n\t\t// A refused or cut summary is not one: the model would read it as what was tried.\n\t\tif (response.stopReason !== 'completed') {\n\t\t\tthis.warnSummaryFailed(`the model stopped with \"${response.stopReason}\"`);\n\t\t\treturn { ...usage, called: true };\n\t\t}\n\t\tconst text = response.message.content\n\t\t\t.filter(part => part.type === 'text')\n\t\t\t.map(part => part.text)\n\t\t\t.join('\\n')\n\t\t\t.trim();\n\t\treturn { ...(text ? { text } : {}), ...usage, called: true };\n\t}\n\n\tprivate warnSummaryFailed(why: string): void {\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tthis.logger?.warn(`The summary of the undone turns failed: ${why}`);\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'LLM agent logger failed',\n\t\t);\n\t}\n\n\tprivate async llmCall(\n\t\trunMessages: Message[],\n\t\tafter: number | undefined,\n\t\t{\n\t\t\tsignal,\n\t\t\tstep,\n\t\t\tcallback,\n\t\t\ttools,\n\t\t}: { signal: AbortSignal; step: number; callback: Callback; tools: ToolDefinition[] },\n\t): Promise<{ response: LLMResponse; context: Message[] }> {\n\t\t// Sent as a copy, so what the run records is what the agent built, whatever the client does.\n\t\tconst context = [...this.conversation.contextAfter(after), ...structuredClone(runMessages)];\n\t\tlet response: LLMResponse;\n\t\ttry {\n\t\t\tresponse = await this.llmClient.send({ context, tools }, signal);\n\t\t} catch (error) {\n\t\t\tconst failure = classifyProviderFailure(error, 'The LLM call failed');\n\t\t\t// A client turns some answers into errors, such as a stop at the context window. The\n\t\t\t// call was billed, and the failure carries what it spent: it is still a step.\n\t\t\tif (\n\t\t\t\t(failure instanceof RecoverableError || failure instanceof UnrecoverableError) &&\n\t\t\t\t(failure.tokens !== undefined || failure.usageUnreported)\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.narrateStep(step, failure.tokens, { context, tools }, callback);\n\t\t\t\t} catch (hostFailure) {\n\t\t\t\t\t// The callback's failure ends the run, and must carry this call's tokens too.\n\t\t\t\t\tthrow withSpentTokens(hostFailure, failure.tokens, failure.usageUnreported);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow failure;\n\t\t}\n\n\t\treturn { response, context };\n\t}\n\n\tprivate narrateStep(\n\t\tstep: number,\n\t\ttokens: Tokens | undefined,\n\t\tsent: { context: Message[]; tools: ToolDefinition[] },\n\t\tcallback: Callback,\n\t) {\n\t\temit(\n\t\t\t{\n\t\t\t\ttype: 'step',\n\t\t\t\tstep,\n\t\t\t\t...(tokens ? { tokens } : {}),\n\t\t\t\tcontext: measureContext({\n\t\t\t\t\tinstructions: this.llmClient.systemPrompt,\n\t\t\t\t\tproviderDataSource: this.llmClient.providerDataSource,\n\t\t\t\t\ttools: sent.tools,\n\t\t\t\t\tcontext: sent.context,\n\t\t\t\t\tsummarize: call => this.callSummaries.get(call.id),\n\t\t\t\t}),\n\t\t\t},\n\t\t\tcallback,\n\t\t);\n\t}\n\n\t/**\n\t * Undefined when the call may run; otherwise why it may not, which the model receives in its\n\t * place. Only a `destructive` call is asked about: git can undo a `mutating` one. A throwing\n\t * approver ends the run, as any host callback does.\n\t */\n\tprivate async denial(\n\t\tcall: ToolCallPart,\n\t\t{ risk, command }: PreparedCall,\n\t\tsignal: AbortSignal,\n\t\tapprove: Approver | undefined,\n\t): Promise<string | undefined> {\n\t\tif (this.autoApprove || risk !== 'destructive') return undefined;\n\n\t\tconst retry = 'Do not retry the same call; choose another way, or ask the user.';\n\t\tif (!approve) {\n\t\t\treturn `The call to \"${call.name}\" was denied: it is destructive, and no one was asked to allow it. ${retry}`;\n\t\t}\n\n\t\tlet decision: ApprovalDecision;\n\t\ttry {\n\t\t\t// A copy, so what runs and what the conversation keeps is exactly what was approved.\n\t\t\tconst input: unknown = structuredClone(call.input);\n\t\t\t// Read inside the boundary: an untyped approver can answer anything, and a bad answer\n\t\t\t// is its failure, which must carry the run's tokens like any other.\n\t\t\tconst request: ApprovalRequest = {\n\t\t\t\ttool: call.name,\n\t\t\t\tinput,\n\t\t\t\trisk,\n\t\t\t\t// A copy too: the approver must not be able to change what runs.\n\t\t\t\t...(command ? { command: structuredClone(command) } : {}),\n\t\t\t};\n\t\t\tdecision = readDecision(await approve(request, signal));\n\t\t} catch (error) {\n\t\t\t// An approver that gives up on a cancellation, whatever it throws, did not fail.\n\t\t\tsignal.throwIfAborted();\n\t\t\tthrow classifyHostFailure(error, 'The tool call approver failed');\n\t\t}\n\t\t// The user may cancel the run while they are being asked.\n\t\tsignal.throwIfAborted();\n\t\tif (decision.approved) return undefined;\n\n\t\tconst reason = decision.reason ? ` Their reason: ${decision.reason}` : '';\n\t\treturn `The user denied the call to \"${call.name}\".${reason} ${retry}`;\n\t}\n\n\t/**\n\t * Always answers the call: a missing tool, a denied call or a failing one becomes an error\n\t * result, so the model can correct itself. Only a cancellation, or a failing approver,\n\t * escapes, whatever error the tool turned it into.\n\t */\n\tprivate async runTool(\n\t\tcall: ToolCallPart,\n\t\t{ signal, onProgress: callback = ignoreProgress, approve, ask }: RunOptions,\n\t\teffects: RunEffects,\n\t\ttoolCall: RunToolContext,\n\t): Promise<{\n\t\tresult: ToolResultPart;\n\t\tdenied: boolean;\n\t\tdiff?: string;\n\t\tsummary?: string;\n\t\texitCode?: number;\n\t\tending?: string;\n\t}> {\n\t\tconst result = { type: 'toolResult' as const, callId: call.id, name: call.name };\n\t\tsignal.throwIfAborted();\n\t\tif (call.name === askUserName && ask && !this.tools.has(askUserName)) {\n\t\t\treturn this.askUser(call, ask, signal, callback);\n\t\t}\n\t\tconst tool = this.tools.get(call.name);\n\t\tif (!tool) {\n\t\t\treturn {\n\t\t\t\tresult: {\n\t\t\t\t\t...result,\n\t\t\t\t\toutput: `There is no tool named \"${call.name}\". Available tools: ${[...this.tools.keys()].join(', ') || 'none'}.`,\n\t\t\t\t\tisError: true,\n\t\t\t\t},\n\t\t\t\tdenied: false,\n\t\t\t};\n\t\t}\n\n\t\tlet summary: string | undefined;\n\t\ttry {\n\t\t\t// This is deliberately before preparation and approval. A consumer-supplied\n\t\t\t// summarizer is host code, and a failed one must never leave an ambiguous call that\n\t\t\t// could be replayed by RetryingAgent.\n\t\t\tsummary = tool.summarize?.(call.input);\n\t\t\tif (summary !== undefined) this.callSummaries.set(call.id, summary);\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tif (error instanceof InvalidToolInputError) {\n\t\t\t\treturn {\n\t\t\t\t\tresult: { ...result, output: describeFailure(error), isError: true },\n\t\t\t\t\tdenied: false,\n\t\t\t\t};\n\t\t\t}\n\t\t\tthrow classifyHostFailure(error, 'The tool call summarizer failed');\n\t\t}\n\n\t\tlet prepared: PreparedCall;\n\t\ttry {\n\t\t\tprepared = await prepareCall(tool, call.input, signal, { ...toolCall, callId: call.id });\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\t// A call that cannot be prepared, or whose tool cannot judge it, does not run; the\n\t\t\t// model reads why, such as a refused path, and can correct itself.\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output: describeFailure(error), isError: true },\n\t\t\t\tdenied: false,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t};\n\t\t}\n\n\t\t// Preparing may have finished after a cancellation it did not notice; nobody is asked to\n\t\t// approve a call in a run that has already stopped.\n\t\tsignal.throwIfAborted();\n\t\tconst denial = await this.denial(call, prepared, signal, approve);\n\t\tif (denial !== undefined) {\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output: denial, isError: true },\n\t\t\t\tdenied: true,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t};\n\t\t}\n\n\t\t// Deciding took at least one await, and the run may have been cancelled meanwhile.\n\t\tsignal.throwIfAborted();\n\t\t// Announced only once it will run: a missing, failing-to-judge or denied call never is.\n\t\temit(\n\t\t\t{\n\t\t\t\ttype: 'tool',\n\t\t\t\tid: call.id,\n\t\t\t\tname: call.name,\n\t\t\t\tstatus: 'in_progress',\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t},\n\t\t\tcallback,\n\t\t);\n\t\t// Checked again at the last moment: the consumer may cancel on the announcement itself.\n\t\tsignal.throwIfAborted();\n\t\t// Set before `execute`, so a tool that fails halfway still counts: it may have had effects.\n\t\teffects.toolRan = true;\n\t\ttry {\n\t\t\tconst output = await prepared.run(signal);\n\t\t\tconst ending = prepared.ending?.();\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output, isError: false },\n\t\t\t\tdenied: false,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t...(prepared.diff === undefined ? {} : { diff: prepared.diff }),\n\t\t\t\t...(ending === undefined ? {} : { ending }),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst ending = prepared.ending?.();\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output: describeFailure(error), isError: true },\n\t\t\t\tdenied: false,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t...(error instanceof ToolExecutionError && error.exitCode !== undefined\n\t\t\t\t\t? { exitCode: error.exitCode }\n\t\t\t\t\t: {}),\n\t\t\t\t...(ending === undefined ? {} : { ending }),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Asks the user through the run's `ask`. Questions the model wrote wrong go back to it, to\n\t * correct; an asker that fails or answers wrongly is host code, and ends the run.\n\t */\n\tprivate async askUser(\n\t\tcall: ToolCallPart,\n\t\task: Asker,\n\t\tsignal: AbortSignal,\n\t\tcallback: Callback,\n\t): Promise<{ result: ToolResultPart; denied: boolean; summary?: string }> {\n\t\tconst result = { type: 'toolResult' as const, callId: call.id, name: call.name };\n\t\tconst questions = readQuestions(call.input);\n\t\tif (typeof questions === 'string') {\n\t\t\treturn { result: { ...result, output: questions, isError: true }, denied: false };\n\t\t}\n\t\tconst summary = summarizeQuestions(questions);\n\t\tthis.callSummaries.set(call.id, summary);\n\t\temit({ type: 'tool', id: call.id, name: call.name, status: 'in_progress', summary }, callback);\n\t\tsignal.throwIfAborted();\n\n\t\tlet answers: unknown;\n\t\ttry {\n\t\t\tanswers = await ask(questions, signal);\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tthrow classifyHostFailure(error, 'The asker failed');\n\t\t}\n\t\t// An answer that arrives after a cancellation is not given to the model.\n\t\tsignal.throwIfAborted();\n\t\tconst read = readAnswers(answers, questions);\n\t\tif (!read) {\n\t\t\tthrow new UnrecoverableError('The asker failed', {\n\t\t\t\tcause: `It must answer each of the ${String(questions.length)} questions with some text, in order.`,\n\t\t\t});\n\t\t}\n\t\treturn {\n\t\t\tresult: { ...result, output: describeAnswers(questions, read), isError: false },\n\t\t\tdenied: false,\n\t\t\tsummary,\n\t\t};\n\t}\n\n\t/** One at a time and in order, so their effects and their narration never interleave. */\n\tprivate async runTools(\n\t\tcalls: ToolCallPart[],\n\t\toptions: RunOptions,\n\t\teffects: RunEffects,\n\t\ttoolCall: RunToolContext,\n\t\t// Throws the failure of a progress callback a call narrated through.\n\t\tthrowIfProgressFailed: () => void,\n\t\tendings: RepeatedEndings,\n\t): Promise<Message> {\n\t\tconst { signal, onProgress: callback = ignoreProgress } = options;\n\t\tconst results: MessagePart[] = [];\n\t\tfor (const call of calls) {\n\t\t\t// A call before this one may have ignored the cancellation; this one must not start,\n\t\t\t// nor be announced as running.\n\t\t\tsignal.throwIfAborted();\n\t\t\t// `runTool` announces the call only once it is allowed to run, so a consumer never\n\t\t\t// shows a call as running early, nor while the user is still being asked.\n\t\t\tconst { result, denied, diff, summary, exitCode, ending } = await this.runTool(\n\t\t\t\tcall,\n\t\t\t\toptions,\n\t\t\t\teffects,\n\t\t\t\ttoolCall,\n\t\t\t);\n\t\t\t// A call that failed to narrate ends the run before the next one can start.\n\t\t\tthrowIfProgressFailed();\n\t\t\tif (denied) {\n\t\t\t\temit(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'tool',\n\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\tstatus: 'denied',\n\t\t\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t\t},\n\t\t\t\t\tcallback,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The diff of a change it made, for the person watching; only once it was made.\n\t\t\telse if (diff !== undefined) {\n\t\t\t\temit(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'tool',\n\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\tstatus: 'completed',\n\t\t\t\t\t\tdiff,\n\t\t\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t\t},\n\t\t\t\t\tcallback,\n\t\t\t\t);\n\t\t\t} else narrate(result, callback, summary, exitCode);\n\t\t\tresults.push(result);\n\t\t\t// After its result is narrated, so the consumer sees the ending that stopped the run.\n\t\t\tif (endings.count(call, ending) >= maxRepeatedEndings) {\n\t\t\t\tthrow new UnrecoverableError('The LLM kept getting the same result from a command', {\n\t\t\t\t\tcause: `${summary === undefined ? `\"${call.name}\"` : `\"${summary}\"`} ended the same way, with the same output, ${String(maxRepeatedEndings)} times in a row.`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn { role: 'tool', content: results };\n\t}\n\n\t/**\n\t * Runs inside the context of the run that reached it, or in one of its own that it ends with\n\t * the run: completed, failed or cancelled. Only a run that owns its context names the history\n\t * run it recorded, since the run is over only when that context ends.\n\t */\n\tasync run(prompt: string, options: RunOptions): Promise<AgentResponse> {\n\t\tconst inherited = runContextOf(options);\n\t\tif (inherited) return this.runSteps(prompt, options, inherited);\n\n\t\tconst context = new RunContext();\n\t\tlet end: RunEnd = 'failed';\n\t\tlet response: AgentResponse;\n\t\ttry {\n\t\t\tresponse = await this.runSteps(prompt, withRunContext(options, context), context);\n\t\t\tend = 'completed';\n\t\t} catch (error) {\n\t\t\tif (isAbortError(error)) end = 'cancelled';\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tawait this.finishContext(context, end);\n\t\t}\n\t\t// Read once the run ended: a run that changed nothing left the history then.\n\t\tconst { runId } = context.historyRun;\n\t\treturn runId ? { ...response, runId } : response;\n\t}\n\n\t/**\n\t * What the run started ends here, but its result stands: the changes it recorded are already\n\t * on disk, so a record that could not be closed is reported, not turned into a failure.\n\t */\n\tprivate async finishContext(context: RunContext, end: RunEnd): Promise<void> {\n\t\ttry {\n\t\t\tawait context.finish(end);\n\t\t} catch (error) {\n\t\t\ttreatErrors(\n\t\t\t\t() => {\n\t\t\t\t\tthis.logger?.warn(`The run could not close its records: ${describeFailure(error)}`);\n\t\t\t\t},\n\t\t\t\tclassifyHostFailure,\n\t\t\t\t'LLM agent logger failed',\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async runSteps(\n\t\tprompt: string,\n\t\toptions: RunOptions,\n\t\tcontext: RunContext,\n\t): Promise<AgentResponse> {\n\t\tconst { signal, onProgress: callback = ignoreProgress } = options;\n\t\tconst start = Date.now();\n\t\tconst runMessages: Message[] = [{ role: 'user', content: [{ type: 'text', text: prompt }] }];\n\t\tlet tokens: Tokens | undefined;\n\t\t// Once one call went unreported the run's total is unknown, however many report later.\n\t\tlet unreported = false;\n\t\t// Per run, not per instance: what one run executed says nothing about another.\n\t\tconst effects: RunEffects = { toolRan: false };\n\t\t// The turn this one follows: the last recorded, unless the workspace moved since.\n\t\tlet after = this.conversation.currentTurn;\n\t\tlet followed: Followed | undefined;\n\n\t\ttry {\n\t\t\tif (this.history) {\n\t\t\t\tfollowed = await this.followHistory(this.history);\n\t\t\t\tafter = followed.turn;\n\t\t\t\t// The files may no longer hold what the conversation saw of them.\n\t\t\t\tif (followed.revisions.length > 0) this.reads.clear();\n\t\t\t\tif (followed.undone.length > 0) {\n\t\t\t\t\tconst summary = await this.summarizeUndone(followed, signal);\n\t\t\t\t\ttokens = addTokens(tokens, summary.usage);\n\t\t\t\t\tunreported ||= summary.called && !summary.usage;\n\t\t\t\t\tconst note = await undoNote({\n\t\t\t\t\t\tconversation: this.conversation,\n\t\t\t\t\t\thistory: this.history,\n\t\t\t\t\t\tfollowed,\n\t\t\t\t\t\t...(summary.text ? { summary: summary.text } : {}),\n\t\t\t\t\t}).catch((error: unknown) => {\n\t\t\t\t\t\tthrow classifyLocalFailure(error, 'The workspace history could not be read');\n\t\t\t\t\t});\n\t\t\t\t\trunMessages[0]?.content.unshift({ type: 'text', text: note });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// After following the history, which may have made every earlier read stale.\n\t\t\tconst reads = this.reads.begin();\n\t\t\tconst repeats = new RepeatedCalls();\n\t\t\tconst endings = new RepeatedEndings();\n\t\t\t// A tool that does its own work on the model, such as running subagents, counts it here.\n\t\t\tconst spend = (spent: Tokens | undefined, unreportedCall: boolean) => {\n\t\t\t\ttokens = addTokens(tokens, spent);\n\t\t\t\tunreported ||= unreportedCall;\n\t\t\t};\n\t\t\t// A tool narrates through this without ever failing: a failing callback would reach\n\t\t\t// only the tool, which turns any failure into a result for the model. The run ends on\n\t\t\t// it once that tool returns.\n\t\t\tlet progressFailure: { error: unknown } | undefined;\n\t\t\tconst onProgress = (event: ProgressEvent) => {\n\t\t\t\tif (progressFailure) return;\n\t\t\t\ttry {\n\t\t\t\t\temit(event, callback);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tprogressFailure = { error };\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst throwIfProgressFailed = () => {\n\t\t\t\tif (progressFailure) throw progressFailure.error;\n\t\t\t};\n\t\t\t// The agent's own `askUser` exists only for a run someone can answer, and never beside\n\t\t\t// a consumer's tool of that name, which the consumer gave first and which stays theirs.\n\t\t\tconst offersAsk = options.ask !== undefined && !this.tools.has(askUserName);\n\t\t\tconst tools = offersAsk ? [...this.toolDefinitions, askUserDefinition] : this.toolDefinitions;\n\t\t\tfor (let step = 1; step <= this.maxSteps; step++) {\n\t\t\t\tconst { response, context: sent } = await this.llmCall(runMessages, after, {\n\t\t\t\t\tsignal,\n\t\t\t\t\tstep,\n\t\t\t\t\tcallback,\n\t\t\t\t\ttools,\n\t\t\t\t});\n\t\t\t\ttokens = addTokens(tokens, response.usage);\n\t\t\t\tunreported ||= !response.usage;\n\t\t\t\t// After the tokens are counted, so a throwing callback still reports them, and for an\n\t\t\t\t// unusable answer too: the call was sent, and billed.\n\t\t\t\tthis.narrateStep(step, response.usage, { context: sent, tools }, callback);\n\t\t\t\tif (response.stopReason !== 'completed') {\n\t\t\t\t\t// Its tokens are already counted with the run's, which the failure carries.\n\t\t\t\t\tthrow new UnrecoverableError('The LLM stopped before completing its answer', {\n\t\t\t\t\t\tcause: `The model stopped with \"${response.stopReason}\".`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\trunMessages.push(response.message);\n\n\t\t\t\t// Tool calls are narrated as they start, in `runTools`, and never if they do not run.\n\t\t\t\tfor (const part of response.message.content) {\n\t\t\t\t\tif (part.type !== 'toolCall') narrate(part, callback);\n\t\t\t\t}\n\n\t\t\t\tconst calls = response.message.content.filter(part => part.type === 'toolCall');\n\t\t\t\tif (calls.length === 0) {\n\t\t\t\t\t// Recorded only now, so a failed run leaves no tool call without its result, and a\n\t\t\t\t\t// note about what was undone is given again to the next run.\n\t\t\t\t\tthis.conversation.addRunAfter(after, runMessages, context.historyRun);\n\t\t\t\t\t// With the turns that read them, and only then: a failed run is not remembered.\n\t\t\t\t\treads.commit();\n\t\t\t\t\tif (followed) this.seenRevision = followed.latestRevision;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\t// Only the final answer: text from earlier steps was narrated as it came.\n\t\t\t\t\t\tresponse: response.message.content\n\t\t\t\t\t\t\t.filter(part => part.type === 'text')\n\t\t\t\t\t\t\t.map(part => part.text)\n\t\t\t\t\t\t\t.join('\\n'),\n\t\t\t\t\t\ttokens: unreported ? undefined : tokens,\n\t\t\t\t\t\tduration: (Date.now() - start) / 1000,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Before running them again: the model has already seen what they return.\n\t\t\t\tif (repeats.count(calls) >= maxRepeatedSteps) {\n\t\t\t\t\tthrow new UnrecoverableError('The LLM repeated the same tool calls', {\n\t\t\t\t\t\tcause: `The model asked for the same tool calls ${String(maxRepeatedSteps)} times in a row.`,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// On the last step no call is left to send the results to, so the tools do not run.\n\t\t\t\tif (step < this.maxSteps) {\n\t\t\t\t\tconst results = await this.runTools(\n\t\t\t\t\t\tcalls,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\teffects,\n\t\t\t\t\t\t{ run: context, reads, onProgress, spend },\n\t\t\t\t\t\tthrowIfProgressFailed,\n\t\t\t\t\t\tendings,\n\t\t\t\t\t);\n\t\t\t\t\trunMessages.push(results);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow new UnrecoverableError('The LLM did not finish within its step limit', {\n\t\t\t\tcause: `The model was still calling tools after ${String(this.maxSteps)} steps.`,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlet failure = error;\n\t\t\tif (effects.toolRan && error instanceof RecoverableError) {\n\t\t\t\t// RetryingAgent would run the whole prompt again, and with it every tool this run\n\t\t\t\t// already executed, so a failure after one ran must not invite a retry.\n\t\t\t\tconst unrecoverable = new UnrecoverableError(error.message, {\n\t\t\t\t\tcause: error.cause,\n\t\t\t\t\ttokens: error.tokens,\n\t\t\t\t\tusageUnreported: error.usageUnreported,\n\t\t\t\t});\n\t\t\t\tunrecoverable.stack = error.stack;\n\t\t\t\tfailure = unrecoverable;\n\t\t\t}\n\n\t\t\t// The run spent the tokens of every step before the one that failed.\n\t\t\tthrow withSpentTokens(failure, tokens, unreported);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"llmAgent.js","sourceRoot":"","sources":["../../../../src/engines/domain/model/llmAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ApprovalDecision,\n\ttype ApprovalRequest,\n\ttype Approver,\n\treadDecision,\n} from '#src/agent/domain/approval';\nimport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressEvent,\n\ttype RunOptions,\n\tignoreProgress,\n} from '#src/agent/domain/agent';\nimport {\n\ttype RunEnd,\n\tRunContext,\n\trunContextOf,\n\twithRunContext,\n} from '#src/agent/domain/runContext';\nimport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '#src/shared/domain/errors';\nimport {\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\tdescribeFailure,\n\ttreatErrors,\n} from '#src/shared/domain/providerFailure';\nimport { Conversation } from '#src/llm/domain/conversation';\nimport type { LLMClient, LLMResponse } from '#src/llm/domain/llm';\nimport type { Message, MessagePart, ToolCallPart, ToolResultPart } from '#src/llm/domain/message';\nimport { asNative, nativeOf, type ToolDefinition } from '#src/llm/domain/tool';\nimport type { Asker } from '#src/agent/domain/question';\nimport type { Transcript, TranscriptCallback } from '#src/agent/domain/transcript';\nimport {\n\ttype AgentTool,\n\ttype PreparedCall,\n\tprepareCall,\n\tToolExecutionError,\n} from '#src/tools/domain/preparedCall';\nimport { ReadRegistry, type ToolCallContext } from '#src/tools/domain/readRegistry';\n\n/** What every tool call of one batch shares; each call adds its own id. */\ntype RunToolContext = Omit<ToolCallContext, 'callId'>;\nimport { InvalidToolInputError } from '#src/tools/domain/tool';\nimport { isAbortError } from '#src/shared/domain/isAbortError';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { addTokens, type Tokens } from '#src/shared/domain/tokens';\nimport { measureContext } from './stepContext.ts';\nimport {\n\taskUserDefinition,\n\taskUserName,\n\tdescribeAnswers,\n\treadAnswers,\n\treadQuestions,\n\tsummarizeQuestions,\n} from './askUser.ts';\nimport {\n\ttype Followed,\n\tfollowHistory,\n\ttype HistoryReader,\n\ttranscriptOf,\n\tundoNote,\n} from './historyFollower.ts';\n\nfunction describePart(part: MessagePart): ProgressEvent | undefined {\n\tswitch (part.type) {\n\t\tcase 'text':\n\t\t\treturn { type: 'agentMessage', message: part.text };\n\t\tcase 'reasoning':\n\t\t\treturn { type: 'reasoning', message: part.text };\n\t\tcase 'toolCall':\n\t\t\treturn { type: 'tool', id: part.id, name: part.name, status: 'in_progress' };\n\t\tcase 'toolResult':\n\t\t\treturn {\n\t\t\t\ttype: 'tool',\n\t\t\t\tid: part.callId,\n\t\t\t\tname: part.name,\n\t\t\t\tstatus: part.isError ? 'error' : 'completed',\n\t\t\t\t...(part.isError ? { error: part.output } : {}),\n\t\t\t};\n\t\tcase 'providerData':\n\t\t\t// Opaque by design: its readable side, if any, arrives as a reasoning part.\n\t\t\treturn undefined;\n\t\tcase 'compaction':\n\t\t\t// The provider's, for its client to send back; the step's context shows its effect.\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Whether a run reached a tool's `execute`. A missing tool or a denied call never does, so it\n * has no effect a retry could repeat.\n */\ninterface RunEffects {\n\ttoolRan: boolean;\n}\n\n/** What a run has shown the model, for its transcript. */\ninterface Seen {\n\tmessages: () => Message[];\n\ttools: ToolDefinition[];\n}\n\nfunction narrate(part: MessagePart, callback: Callback, summary?: string, exitCode?: number): void {\n\tconst event = describePart(part);\n\tif (!event) return;\n\tif (event.type === 'tool') {\n\t\tif (summary !== undefined) event.summary = summary;\n\t\tif (exitCode !== undefined) event.exitCode = exitCode;\n\t}\n\temit(event, callback);\n}\n\nfunction emit(event: ProgressEvent, callback: Callback): void {\n\ttreatErrors(\n\t\t() => {\n\t\t\tcallback(event);\n\t\t},\n\t\tclassifyHostFailure,\n\t\t'LLM agent progress callback failed',\n\t);\n}\n\n/** `value` with the keys of every object sorted, so equal inputs serialize alike. */\nfunction canonical(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(canonical);\n\tif (typeof value !== 'object' || value === null) return value;\n\treturn Object.fromEntries(\n\t\tObject.entries(value)\n\t\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n\t\t\t.map(([key, inner]) => [key, canonical(inner)]),\n\t);\n}\n\n// A model that asks for exactly the same calls this many times in a row is stuck: it already\n// has what they return, and running them again changes nothing.\nconst maxRepeatedSteps = 5;\n\n/** How many steps in a row have asked for exactly the same tool calls, with the same input. */\nclass RepeatedCalls {\n\tprivate last: string | undefined;\n\tprivate times = 0;\n\n\tcount(calls: readonly ToolCallPart[]): number {\n\t\t// Keys sorted at every level: the same input with its properties in another order is the\n\t\t// same call. Arrays, and the order of the calls, keep theirs.\n\t\tconst key = JSON.stringify(calls.map(call => [call.name, canonical(call.input)]));\n\t\tthis.times = key === this.last ? this.times + 1 : 1;\n\t\tthis.last = key;\n\t\treturn this.times;\n\t}\n}\n\n// A command that ends exactly as it did the last times, in output too, this many times in a row\n// means the model's changes in between are not reaching what the command checks.\nconst maxRepeatedEndings = 5;\n\n/**\n * How many times in a row each command call, by tool and input, has ended exactly the same way.\n * Calls in between to other tools, or to other commands, do not break the count.\n */\nclass RepeatedEndings {\n\tprivate readonly last = new Map<string, { ending: string; times: number }>();\n\n\tcount(call: ToolCallPart, ending: string | undefined): number {\n\t\tconst key = JSON.stringify([call.name, canonical(call.input)]);\n\t\t// A call that never ran a command, such as one denied, says nothing of how it ends.\n\t\tif (ending === undefined) {\n\t\t\tthis.last.delete(key);\n\t\t\treturn 0;\n\t\t}\n\t\tconst previous = this.last.get(key);\n\t\tconst times = previous?.ending === ending ? previous.times + 1 : 1;\n\t\tthis.last.set(key, { ending, times });\n\t\treturn times;\n\t}\n}\n\n/**\n * An agent whose conversation is owned by MiKode: every run sends the whole context to a\n * stateless `LLMClient`. Within a run the model may call the agent's tools; the agent runs them\n * and sends their results back until the model answers without calling one. Turn boundaries\n * are the consumer's to emit, as with the other engines; this agent only narrates what the\n * model produced and what its tools did.\n */\nexport class LLMAgent implements Agent {\n\tprivate readonly llmClient: LLMClient;\n\tprivate readonly conversation: Conversation;\n\tprivate readonly tools: Map<string, AgentTool>;\n\tprivate readonly toolDefinitions: ToolDefinition[];\n\t// Each call's summary, as its tool gave it when the call ran, so measuring a step that\n\t// resends the call never runs a consumer's summarizer again.\n\tprivate readonly callSummaries = new Map<string, string>();\n\tprivate readonly maxSteps: number;\n\tprivate readonly autoApprove: boolean;\n\tprivate readonly logger: ILogger | undefined;\n\tprivate readonly history: HistoryReader | undefined;\n\tprivate readonly summarizer: LLMClient | undefined;\n\tprivate readonly onTranscript: TranscriptCallback | undefined;\n\t// The latest move through the history this conversation has followed.\n\tprivate seenRevision = 0;\n\t// What this conversation has seen of each file, so an edit starts from a version it read.\n\tprivate readonly reads = new ReadRegistry();\n\n\tconstructor({\n\t\tllmClient,\n\t\tmessages,\n\t\ttools = [],\n\t\tmaxSteps = 65,\n\t\tautoApprove = false,\n\t\tlogger,\n\t\thistory,\n\t\tsummarizer,\n\t\tonTranscript,\n\t}: {\n\t\tllmClient: LLMClient;\n\t\tmessages?: Message[];\n\t\ttools?: AgentTool[];\n\t\t/** How many calls to the model one run may make before it fails. Defaults to 65. */\n\t\tmaxSteps?: number;\n\t\t/** Runs every tool call without asking, `destructive` ones included. Meant for CI. */\n\t\tautoApprove?: boolean;\n\t\t/** Where a failure the agent absorbs is reported. The factories always pass one. */\n\t\tlogger?: ILogger;\n\t\t/**\n\t\t * The history of the workspace this agent writes to. With it, each run first follows the\n\t\t * moves the user made through that history: the conversation goes back with the\n\t\t * workspace, and the model is told what was undone.\n\t\t */\n\t\thistory?: HistoryReader;\n\t\t/**\n\t\t * A cheap model that summarizes what the undone turns tried and what went wrong. Without\n\t\t * one, the model is told what those turns asked, word for word.\n\t\t */\n\t\tsummarizer?: LLMClient;\n\t\t/** Receives what the model saw in each run, once the run ended. */\n\t\tonTranscript?: TranscriptCallback;\n\t}) {\n\t\tif (!Number.isInteger(maxSteps) || maxSteps < 1) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`maxSteps must be a positive integer; got ${String(maxSteps)}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.llmClient = llmClient;\n\t\tthis.conversation = new Conversation(messages);\n\t\tthis.maxSteps = maxSteps;\n\t\tthis.autoApprove = autoApprove;\n\t\tthis.logger = logger;\n\t\tthis.history = history;\n\t\tthis.summarizer = summarizer;\n\t\tthis.onTranscript = onTranscript;\n\t\tthis.tools = new Map(tools.map(tool => [tool.name, tool]));\n\t\tif (this.tools.size !== tools.length) {\n\t\t\t// The model calls tools by name, so a second one with the same name could never run.\n\t\t\tthrow new InvalidAgentConfigError('Two tools share a name; each name must be unique');\n\t\t}\n\t\t// The client only describes the tools to the model; running them stays with the agent.\n\t\tthis.toolDefinitions = tools.map(tool => {\n\t\t\tconst definition = {\n\t\t\t\tname: tool.name,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tinputSchema: tool.inputSchema,\n\t\t\t};\n\t\t\tconst native = nativeOf(tool);\n\t\t\tif (native === undefined) return definition;\n\t\t\t// Checked now, not on the first call: an agent its client cannot serve is a setup error.\n\t\t\tif (llmClient.supportsNative?.(native) !== true) {\n\t\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t\t`The tool \"${tool.name}\" is the native \"${native}\" tool, which this model client cannot declare`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn asNative(definition, native);\n\t\t});\n\t}\n\n\tprivate async followHistory(history: HistoryReader): Promise<Followed> {\n\t\ttry {\n\t\t\treturn await followHistory(this.conversation, history, this.seenRevision);\n\t\t} catch (error) {\n\t\t\tthrow classifyLocalFailure(error, 'The workspace history could not be read');\n\t\t}\n\t}\n\n\t/**\n\t * Asks the summarizer what the undone turns tried and what went wrong. A summary is a help,\n\t * not a need: one that fails is reported and the plain note is used instead.\n\t */\n\tprivate async summarizeUndone(\n\t\tfollowed: Followed,\n\t\tsignal: AbortSignal,\n\t): Promise<{ text?: string; usage?: Tokens; called: boolean }> {\n\t\tif (!this.summarizer) return { called: false };\n\t\tconst reasons = followed.revisions.flatMap(revision =>\n\t\t\trevision.reason ? [revision.reason] : [],\n\t\t);\n\t\tconst prompt = [\n\t\t\t'The user undid the work in the conversation below and moved the workspace back to before it.',\n\t\t\treasons.length > 0 ? `Their reason: ${reasons.map(reason => `«${reason}»`).join(' ')}` : '',\n\t\t\t'In at most five short lines, say what was tried, why it went wrong or why the user went back, and what could be done better. Plain text, no preamble.',\n\t\t\t'',\n\t\t\ttranscriptOf(this.conversation, followed.undone),\n\t\t].join('\\n');\n\n\t\tlet response: LLMResponse;\n\t\ttry {\n\t\t\tresponse = await this.summarizer.send(\n\t\t\t\t{ context: [{ role: 'user', content: [{ type: 'text', text: prompt }] }], tools: [] },\n\t\t\t\tsignal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (isAbortError(error)) throw error;\n\t\t\tthis.warnSummaryFailed(describeFailure(error));\n\t\t\treturn { called: true };\n\t\t}\n\n\t\tconst usage = response.usage ? { usage: response.usage } : {};\n\t\t// A refused or cut summary is not one: the model would read it as what was tried.\n\t\tif (response.stopReason !== 'completed') {\n\t\t\tthis.warnSummaryFailed(`the model stopped with \"${response.stopReason}\"`);\n\t\t\treturn { ...usage, called: true };\n\t\t}\n\t\tconst text = response.message.content\n\t\t\t.filter(part => part.type === 'text')\n\t\t\t.map(part => part.text)\n\t\t\t.join('\\n')\n\t\t\t.trim();\n\t\treturn { ...(text ? { text } : {}), ...usage, called: true };\n\t}\n\n\tprivate warnSummaryFailed(why: string): void {\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tthis.logger?.warn(`The summary of the undone turns failed: ${why}`);\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'LLM agent logger failed',\n\t\t);\n\t}\n\n\tprivate async llmCall(\n\t\trunMessages: Message[],\n\t\tafter: number | undefined,\n\t\t{\n\t\t\tsignal,\n\t\t\tstep,\n\t\t\tcallback,\n\t\t\ttools,\n\t\t}: { signal: AbortSignal; step: number; callback: Callback; tools: ToolDefinition[] },\n\t): Promise<{ response: LLMResponse; context: Message[] }> {\n\t\t// Sent as a copy, so what the run records is what the agent built, whatever the client does.\n\t\tconst context = [...this.conversation.contextAfter(after), ...structuredClone(runMessages)];\n\t\tlet response: LLMResponse;\n\t\ttry {\n\t\t\tresponse = await this.llmClient.send({ context, tools }, signal);\n\t\t} catch (error) {\n\t\t\tconst failure = classifyProviderFailure(error, 'The LLM call failed');\n\t\t\t// A client turns some answers into errors, such as a stop at the context window. The\n\t\t\t// call was billed, and the failure carries what it spent: it is still a step.\n\t\t\tif (\n\t\t\t\t(failure instanceof RecoverableError || failure instanceof UnrecoverableError) &&\n\t\t\t\t(failure.tokens !== undefined || failure.usageUnreported)\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.narrateStep(step, failure.tokens, { context, tools }, callback);\n\t\t\t\t} catch (hostFailure) {\n\t\t\t\t\t// The callback's failure ends the run, and must carry this call's tokens too.\n\t\t\t\t\tthrow withSpentTokens(hostFailure, failure.tokens, failure.usageUnreported);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow failure;\n\t\t}\n\n\t\treturn { response, context };\n\t}\n\n\tprivate narrateStep(\n\t\tstep: number,\n\t\ttokens: Tokens | undefined,\n\t\tsent: { context: Message[]; tools: ToolDefinition[] },\n\t\tcallback: Callback,\n\t) {\n\t\temit(\n\t\t\t{\n\t\t\t\ttype: 'step',\n\t\t\t\tstep,\n\t\t\t\t...(tokens ? { tokens } : {}),\n\t\t\t\tcontext: measureContext({\n\t\t\t\t\tinstructions: this.llmClient.systemPrompt,\n\t\t\t\t\tproviderDataSource: this.llmClient.providerDataSource,\n\t\t\t\t\ttools: sent.tools,\n\t\t\t\t\tcontext: sent.context,\n\t\t\t\t\tsummarize: call => this.callSummaries.get(call.id),\n\t\t\t\t}),\n\t\t\t},\n\t\t\tcallback,\n\t\t);\n\t}\n\n\t/**\n\t * Undefined when the call may run; otherwise why it may not, which the model receives in its\n\t * place. Only a `destructive` call is asked about: git can undo a `mutating` one. A throwing\n\t * approver ends the run, as any host callback does.\n\t */\n\tprivate async denial(\n\t\tcall: ToolCallPart,\n\t\t{ risk, command }: PreparedCall,\n\t\tsignal: AbortSignal,\n\t\tapprove: Approver | undefined,\n\t): Promise<string | undefined> {\n\t\tif (this.autoApprove || risk !== 'destructive') return undefined;\n\n\t\tconst retry = 'Do not retry the same call; choose another way, or ask the user.';\n\t\tif (!approve) {\n\t\t\treturn `The call to \"${call.name}\" was denied: it is destructive, and no one was asked to allow it. ${retry}`;\n\t\t}\n\n\t\tlet decision: ApprovalDecision;\n\t\ttry {\n\t\t\t// A copy, so what runs and what the conversation keeps is exactly what was approved.\n\t\t\tconst input: unknown = structuredClone(call.input);\n\t\t\t// Read inside the boundary: an untyped approver can answer anything, and a bad answer\n\t\t\t// is its failure, which must carry the run's tokens like any other.\n\t\t\tconst request: ApprovalRequest = {\n\t\t\t\ttool: call.name,\n\t\t\t\tinput,\n\t\t\t\trisk,\n\t\t\t\t// A copy too: the approver must not be able to change what runs.\n\t\t\t\t...(command ? { command: structuredClone(command) } : {}),\n\t\t\t};\n\t\t\tdecision = readDecision(await approve(request, signal));\n\t\t} catch (error) {\n\t\t\t// An approver that gives up on a cancellation, whatever it throws, did not fail.\n\t\t\tsignal.throwIfAborted();\n\t\t\tthrow classifyHostFailure(error, 'The tool call approver failed');\n\t\t}\n\t\t// The user may cancel the run while they are being asked.\n\t\tsignal.throwIfAborted();\n\t\tif (decision.approved) return undefined;\n\n\t\tconst reason = decision.reason ? ` Their reason: ${decision.reason}` : '';\n\t\treturn `The user denied the call to \"${call.name}\".${reason} ${retry}`;\n\t}\n\n\t/**\n\t * Always answers the call: a missing tool, a denied call or a failing one becomes an error\n\t * result, so the model can correct itself. Only a cancellation, or a failing approver,\n\t * escapes, whatever error the tool turned it into.\n\t */\n\tprivate async runTool(\n\t\tcall: ToolCallPart,\n\t\t{ signal, onProgress: callback = ignoreProgress, approve, ask }: RunOptions,\n\t\teffects: RunEffects,\n\t\ttoolCall: RunToolContext,\n\t): Promise<{\n\t\tresult: ToolResultPart;\n\t\tdenied: boolean;\n\t\tdiff?: string;\n\t\tsummary?: string;\n\t\texitCode?: number;\n\t\tending?: string;\n\t}> {\n\t\tconst result = { type: 'toolResult' as const, callId: call.id, name: call.name };\n\t\tsignal.throwIfAborted();\n\t\tif (call.name === askUserName && ask && !this.tools.has(askUserName)) {\n\t\t\treturn this.askUser(call, ask, signal, callback);\n\t\t}\n\t\tconst tool = this.tools.get(call.name);\n\t\tif (!tool) {\n\t\t\treturn {\n\t\t\t\tresult: {\n\t\t\t\t\t...result,\n\t\t\t\t\toutput: `There is no tool named \"${call.name}\". Available tools: ${[...this.tools.keys()].join(', ') || 'none'}.`,\n\t\t\t\t\tisError: true,\n\t\t\t\t},\n\t\t\t\tdenied: false,\n\t\t\t};\n\t\t}\n\n\t\tlet summary: string | undefined;\n\t\ttry {\n\t\t\t// This is deliberately before preparation and approval. A consumer-supplied\n\t\t\t// summarizer is host code, and a failed one must never leave an ambiguous call that\n\t\t\t// could be replayed by RetryingAgent.\n\t\t\tsummary = tool.summarize?.(call.input);\n\t\t\tif (summary !== undefined) this.callSummaries.set(call.id, summary);\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tif (error instanceof InvalidToolInputError) {\n\t\t\t\treturn {\n\t\t\t\t\tresult: { ...result, output: describeFailure(error), isError: true },\n\t\t\t\t\tdenied: false,\n\t\t\t\t};\n\t\t\t}\n\t\t\tthrow classifyHostFailure(error, 'The tool call summarizer failed');\n\t\t}\n\n\t\tlet prepared: PreparedCall;\n\t\ttry {\n\t\t\tprepared = await prepareCall(tool, call.input, signal, { ...toolCall, callId: call.id });\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\t// A call that cannot be prepared, or whose tool cannot judge it, does not run; the\n\t\t\t// model reads why, such as a refused path, and can correct itself.\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output: describeFailure(error), isError: true },\n\t\t\t\tdenied: false,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t};\n\t\t}\n\n\t\t// Preparing may have finished after a cancellation it did not notice; nobody is asked to\n\t\t// approve a call in a run that has already stopped.\n\t\tsignal.throwIfAborted();\n\t\tconst denial = await this.denial(call, prepared, signal, approve);\n\t\tif (denial !== undefined) {\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output: denial, isError: true },\n\t\t\t\tdenied: true,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t};\n\t\t}\n\n\t\t// Deciding took at least one await, and the run may have been cancelled meanwhile.\n\t\tsignal.throwIfAborted();\n\t\t// Announced only once it will run: a missing, failing-to-judge or denied call never is.\n\t\temit(\n\t\t\t{\n\t\t\t\ttype: 'tool',\n\t\t\t\tid: call.id,\n\t\t\t\tname: call.name,\n\t\t\t\tstatus: 'in_progress',\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t},\n\t\t\tcallback,\n\t\t);\n\t\t// Checked again at the last moment: the consumer may cancel on the announcement itself.\n\t\tsignal.throwIfAborted();\n\t\t// Set before `execute`, so a tool that fails halfway still counts: it may have had effects.\n\t\teffects.toolRan = true;\n\t\ttry {\n\t\t\tconst output = await prepared.run(signal);\n\t\t\tconst ending = prepared.ending?.();\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output, isError: false },\n\t\t\t\tdenied: false,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t...(prepared.diff === undefined ? {} : { diff: prepared.diff }),\n\t\t\t\t...(ending === undefined ? {} : { ending }),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst ending = prepared.ending?.();\n\t\t\treturn {\n\t\t\t\tresult: { ...result, output: describeFailure(error), isError: true },\n\t\t\t\tdenied: false,\n\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t...(error instanceof ToolExecutionError && error.exitCode !== undefined\n\t\t\t\t\t? { exitCode: error.exitCode }\n\t\t\t\t\t: {}),\n\t\t\t\t...(ending === undefined ? {} : { ending }),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Asks the user through the run's `ask`. Questions the model wrote wrong go back to it, to\n\t * correct; an asker that fails or answers wrongly is host code, and ends the run.\n\t */\n\tprivate async askUser(\n\t\tcall: ToolCallPart,\n\t\task: Asker,\n\t\tsignal: AbortSignal,\n\t\tcallback: Callback,\n\t): Promise<{ result: ToolResultPart; denied: boolean; summary?: string }> {\n\t\tconst result = { type: 'toolResult' as const, callId: call.id, name: call.name };\n\t\tconst questions = readQuestions(call.input);\n\t\tif (typeof questions === 'string') {\n\t\t\treturn { result: { ...result, output: questions, isError: true }, denied: false };\n\t\t}\n\t\tconst summary = summarizeQuestions(questions);\n\t\tthis.callSummaries.set(call.id, summary);\n\t\temit({ type: 'tool', id: call.id, name: call.name, status: 'in_progress', summary }, callback);\n\t\tsignal.throwIfAborted();\n\n\t\tlet answers: unknown;\n\t\ttry {\n\t\t\tanswers = await ask(questions, signal);\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tthrow classifyHostFailure(error, 'The asker failed');\n\t\t}\n\t\t// An answer that arrives after a cancellation is not given to the model.\n\t\tsignal.throwIfAborted();\n\t\tconst read = readAnswers(answers, questions);\n\t\tif (!read) {\n\t\t\tthrow new UnrecoverableError('The asker failed', {\n\t\t\t\tcause: `It must answer each of the ${String(questions.length)} questions with some text, in order.`,\n\t\t\t});\n\t\t}\n\t\treturn {\n\t\t\tresult: { ...result, output: describeAnswers(questions, read), isError: false },\n\t\t\tdenied: false,\n\t\t\tsummary,\n\t\t};\n\t}\n\n\t/** One at a time and in order, so their effects and their narration never interleave. */\n\tprivate async runTools(\n\t\tcalls: ToolCallPart[],\n\t\toptions: RunOptions,\n\t\teffects: RunEffects,\n\t\ttoolCall: RunToolContext,\n\t\t// Throws the failure of a progress callback a call narrated through.\n\t\tthrowIfProgressFailed: () => void,\n\t\tendings: RepeatedEndings,\n\t): Promise<Message> {\n\t\tconst { signal, onProgress: callback = ignoreProgress } = options;\n\t\tconst results: MessagePart[] = [];\n\t\tfor (const call of calls) {\n\t\t\t// A call before this one may have ignored the cancellation; this one must not start,\n\t\t\t// nor be announced as running.\n\t\t\tsignal.throwIfAborted();\n\t\t\t// `runTool` announces the call only once it is allowed to run, so a consumer never\n\t\t\t// shows a call as running early, nor while the user is still being asked.\n\t\t\tconst { result, denied, diff, summary, exitCode, ending } = await this.runTool(\n\t\t\t\tcall,\n\t\t\t\toptions,\n\t\t\t\teffects,\n\t\t\t\ttoolCall,\n\t\t\t);\n\t\t\t// A call that failed to narrate ends the run before the next one can start.\n\t\t\tthrowIfProgressFailed();\n\t\t\tif (denied) {\n\t\t\t\temit(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'tool',\n\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\tstatus: 'denied',\n\t\t\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t\t},\n\t\t\t\t\tcallback,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The diff of a change it made, for the person watching; only once it was made.\n\t\t\telse if (diff !== undefined) {\n\t\t\t\temit(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'tool',\n\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\tstatus: 'completed',\n\t\t\t\t\t\tdiff,\n\t\t\t\t\t\t...(summary === undefined ? {} : { summary }),\n\t\t\t\t\t},\n\t\t\t\t\tcallback,\n\t\t\t\t);\n\t\t\t} else narrate(result, callback, summary, exitCode);\n\t\t\tresults.push(result);\n\t\t\t// After its result is narrated, so the consumer sees the ending that stopped the run.\n\t\t\tif (endings.count(call, ending) >= maxRepeatedEndings) {\n\t\t\t\tthrow new UnrecoverableError('The LLM kept getting the same result from a command', {\n\t\t\t\t\tcause: `${summary === undefined ? `\"${call.name}\"` : `\"${summary}\"`} ended the same way, with the same output, ${String(maxRepeatedEndings)} times in a row.`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn { role: 'tool', content: results };\n\t}\n\n\t/**\n\t * Runs inside the context of the run that reached it, or in one of its own that it ends with\n\t * the run: completed, failed or cancelled. Only a run that owns its context names the history\n\t * run it recorded, since the run is over only when that context ends.\n\t */\n\tasync run(prompt: string, options: RunOptions): Promise<AgentResponse> {\n\t\tconst inherited = runContextOf(options);\n\t\tif (inherited) return this.runSteps(prompt, options, inherited);\n\n\t\tconst context = new RunContext();\n\t\tlet end: RunEnd = 'failed';\n\t\tlet response: AgentResponse;\n\t\ttry {\n\t\t\tresponse = await this.runSteps(prompt, withRunContext(options, context), context);\n\t\t\tend = 'completed';\n\t\t} catch (error) {\n\t\t\tif (isAbortError(error)) end = 'cancelled';\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tawait this.finishContext(context, end);\n\t\t}\n\t\t// Read once the run ended: a run that changed nothing left the history then.\n\t\tconst { runId } = context.historyRun;\n\t\treturn runId ? { ...response, runId } : response;\n\t}\n\n\t/**\n\t * What the run started ends here, but its result stands: the changes it recorded are already\n\t * on disk, so a record that could not be closed is reported, not turned into a failure.\n\t */\n\tprivate async finishContext(context: RunContext, end: RunEnd): Promise<void> {\n\t\ttry {\n\t\t\tawait context.finish(end);\n\t\t} catch (error) {\n\t\t\ttreatErrors(\n\t\t\t\t() => {\n\t\t\t\t\tthis.logger?.warn(`The run could not close its records: ${describeFailure(error)}`);\n\t\t\t\t},\n\t\t\t\tclassifyHostFailure,\n\t\t\t\t'LLM agent logger failed',\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async runSteps(\n\t\tprompt: string,\n\t\toptions: RunOptions,\n\t\tcontext: RunContext,\n\t): Promise<AgentResponse> {\n\t\tconst seen: Seen = { messages: () => [], tools: this.toolDefinitions };\n\t\tlet response: AgentResponse;\n\t\ttry {\n\t\t\tresponse = await this.takeSteps(prompt, options, context, seen);\n\t\t} catch (error) {\n\t\t\tawait this.transcribe(seen, isAbortError(error) ? 'cancelled' : 'failed', error);\n\t\t\tthrow error;\n\t\t}\n\t\tawait this.transcribe(seen, 'completed');\n\t\treturn response;\n\t}\n\n\t/** Hands the run's transcript to the consumer, whose failure is logged, not the run's. */\n\tprivate async transcribe(\n\t\tseen: Seen,\n\t\toutcome: Transcript['outcome'],\n\t\terror?: unknown,\n\t): Promise<void> {\n\t\tif (!this.onTranscript) return;\n\t\ttry {\n\t\t\t// A copy, so a consumer that changes it cannot change the agent's tools or conversation.\n\t\t\tconst content: unknown = structuredClone({\n\t\t\t\tinstructions: this.llmClient.systemPrompt,\n\t\t\t\ttools: seen.tools.map(({ name, description, inputSchema }) => ({\n\t\t\t\t\tname,\n\t\t\t\t\tdescription,\n\t\t\t\t\tinputSchema,\n\t\t\t\t})),\n\t\t\t\tmessages: seen.messages(),\n\t\t\t\t...(outcome === 'completed' ? {} : { error: describeFailure(error) }),\n\t\t\t});\n\t\t\tawait this.onTranscript({ outcome, content });\n\t\t} catch (failure) {\n\t\t\ttreatErrors(\n\t\t\t\t() => {\n\t\t\t\t\tthis.logger?.warn(\n\t\t\t\t\t\t`The run's transcript could not be handed over: ${describeFailure(failure)}`,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tclassifyHostFailure,\n\t\t\t\t'LLM agent logger failed',\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async takeSteps(\n\t\tprompt: string,\n\t\toptions: RunOptions,\n\t\tcontext: RunContext,\n\t\tseen: Seen,\n\t): Promise<AgentResponse> {\n\t\tconst { signal, onProgress: callback = ignoreProgress } = options;\n\t\tconst start = Date.now();\n\t\tconst runMessages: Message[] = [{ role: 'user', content: [{ type: 'text', text: prompt }] }];\n\t\tlet tokens: Tokens | undefined;\n\t\t// Once one call went unreported the run's total is unknown, however many report later.\n\t\tlet unreported = false;\n\t\t// Per run, not per instance: what one run executed says nothing about another.\n\t\tconst effects: RunEffects = { toolRan: false };\n\t\t// The turn this one follows: the last recorded, unless the workspace moved since.\n\t\tlet after = this.conversation.currentTurn;\n\t\tlet followed: Followed | undefined;\n\t\t// What the model has seen so far, whichever turn the run ends up following.\n\t\tseen.messages = () => [...this.conversation.contextAfter(after), ...runMessages];\n\n\t\ttry {\n\t\t\tif (this.history) {\n\t\t\t\tfollowed = await this.followHistory(this.history);\n\t\t\t\tafter = followed.turn;\n\t\t\t\t// The files may no longer hold what the conversation saw of them.\n\t\t\t\tif (followed.revisions.length > 0) this.reads.clear();\n\t\t\t\tif (followed.undone.length > 0) {\n\t\t\t\t\tconst summary = await this.summarizeUndone(followed, signal);\n\t\t\t\t\ttokens = addTokens(tokens, summary.usage);\n\t\t\t\t\tunreported ||= summary.called && !summary.usage;\n\t\t\t\t\tconst note = await undoNote({\n\t\t\t\t\t\tconversation: this.conversation,\n\t\t\t\t\t\thistory: this.history,\n\t\t\t\t\t\tfollowed,\n\t\t\t\t\t\t...(summary.text ? { summary: summary.text } : {}),\n\t\t\t\t\t}).catch((error: unknown) => {\n\t\t\t\t\t\tthrow classifyLocalFailure(error, 'The workspace history could not be read');\n\t\t\t\t\t});\n\t\t\t\t\trunMessages[0]?.content.unshift({ type: 'text', text: note });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// After following the history, which may have made every earlier read stale.\n\t\t\tconst reads = this.reads.begin();\n\t\t\tconst repeats = new RepeatedCalls();\n\t\t\tconst endings = new RepeatedEndings();\n\t\t\t// A tool that does its own work on the model, such as running subagents, counts it here.\n\t\t\tconst spend = (spent: Tokens | undefined, unreportedCall: boolean) => {\n\t\t\t\ttokens = addTokens(tokens, spent);\n\t\t\t\tunreported ||= unreportedCall;\n\t\t\t};\n\t\t\t// A tool narrates through this without ever failing: a failing callback would reach\n\t\t\t// only the tool, which turns any failure into a result for the model. The run ends on\n\t\t\t// it once that tool returns.\n\t\t\tlet progressFailure: { error: unknown } | undefined;\n\t\t\tconst onProgress = (event: ProgressEvent) => {\n\t\t\t\tif (progressFailure) return;\n\t\t\t\ttry {\n\t\t\t\t\temit(event, callback);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tprogressFailure = { error };\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst throwIfProgressFailed = () => {\n\t\t\t\tif (progressFailure) throw progressFailure.error;\n\t\t\t};\n\t\t\t// The agent's own `askUser` exists only for a run someone can answer, and never beside\n\t\t\t// a consumer's tool of that name, which the consumer gave first and which stays theirs.\n\t\t\tconst offersAsk = options.ask !== undefined && !this.tools.has(askUserName);\n\t\t\tconst tools = offersAsk ? [...this.toolDefinitions, askUserDefinition] : this.toolDefinitions;\n\t\t\tseen.tools = tools;\n\t\t\tfor (let step = 1; step <= this.maxSteps; step++) {\n\t\t\t\tconst { response, context: sent } = await this.llmCall(runMessages, after, {\n\t\t\t\t\tsignal,\n\t\t\t\t\tstep,\n\t\t\t\t\tcallback,\n\t\t\t\t\ttools,\n\t\t\t\t});\n\t\t\t\ttokens = addTokens(tokens, response.usage);\n\t\t\t\tunreported ||= !response.usage;\n\t\t\t\t// After the tokens are counted, so a throwing callback still reports them, and for an\n\t\t\t\t// unusable answer too: the call was sent, and billed.\n\t\t\t\tthis.narrateStep(step, response.usage, { context: sent, tools }, callback);\n\t\t\t\tif (response.stopReason !== 'completed') {\n\t\t\t\t\t// Its tokens are already counted with the run's, which the failure carries.\n\t\t\t\t\tthrow new UnrecoverableError('The LLM stopped before completing its answer', {\n\t\t\t\t\t\tcause: `The model stopped with \"${response.stopReason}\".`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\trunMessages.push(response.message);\n\n\t\t\t\t// Tool calls are narrated as they start, in `runTools`, and never if they do not run.\n\t\t\t\tfor (const part of response.message.content) {\n\t\t\t\t\tif (part.type !== 'toolCall') narrate(part, callback);\n\t\t\t\t}\n\n\t\t\t\tconst calls = response.message.content.filter(part => part.type === 'toolCall');\n\t\t\t\tif (calls.length === 0) {\n\t\t\t\t\t// Recorded only now, so a failed run leaves no tool call without its result, and a\n\t\t\t\t\t// note about what was undone is given again to the next run.\n\t\t\t\t\tthis.conversation.addRunAfter(after, runMessages, context.historyRun);\n\t\t\t\t\t// With the turns that read them, and only then: a failed run is not remembered.\n\t\t\t\t\treads.commit();\n\t\t\t\t\tif (followed) this.seenRevision = followed.latestRevision;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\t// Only the final answer: text from earlier steps was narrated as it came.\n\t\t\t\t\t\tresponse: response.message.content\n\t\t\t\t\t\t\t.filter(part => part.type === 'text')\n\t\t\t\t\t\t\t.map(part => part.text)\n\t\t\t\t\t\t\t.join('\\n'),\n\t\t\t\t\t\ttokens: unreported ? undefined : tokens,\n\t\t\t\t\t\tduration: (Date.now() - start) / 1000,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Before running them again: the model has already seen what they return.\n\t\t\t\tif (repeats.count(calls) >= maxRepeatedSteps) {\n\t\t\t\t\tthrow new UnrecoverableError('The LLM repeated the same tool calls', {\n\t\t\t\t\t\tcause: `The model asked for the same tool calls ${String(maxRepeatedSteps)} times in a row.`,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// On the last step no call is left to send the results to, so the tools do not run.\n\t\t\t\tif (step < this.maxSteps) {\n\t\t\t\t\tconst results = await this.runTools(\n\t\t\t\t\t\tcalls,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\teffects,\n\t\t\t\t\t\t{ run: context, reads, onProgress, spend },\n\t\t\t\t\t\tthrowIfProgressFailed,\n\t\t\t\t\t\tendings,\n\t\t\t\t\t);\n\t\t\t\t\trunMessages.push(results);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow new UnrecoverableError('The LLM did not finish within its step limit', {\n\t\t\t\tcause: `The model was still calling tools after ${String(this.maxSteps)} steps.`,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlet failure = error;\n\t\t\tif (effects.toolRan && error instanceof RecoverableError) {\n\t\t\t\t// RetryingAgent would run the whole prompt again, and with it every tool this run\n\t\t\t\t// already executed, so a failure after one ran must not invite a retry.\n\t\t\t\tconst unrecoverable = new UnrecoverableError(error.message, {\n\t\t\t\t\tcause: error.cause,\n\t\t\t\t\ttokens: error.tokens,\n\t\t\t\t\tusageUnreported: error.usageUnreported,\n\t\t\t\t});\n\t\t\t\tunrecoverable.stack = error.stack;\n\t\t\t\tfailure = unrecoverable;\n\t\t\t}\n\n\t\t\t// The run spent the tokens of every step before the one that failed.\n\t\t\tthrow withSpentTokens(failure, tokens, unreported);\n\t\t}\n\t}\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { Agent } from '#src/agent/domain/agent';
2
+ import type { TranscriptCallback } from '#src/agent/domain/transcript';
2
3
  import type { ILogger } from '#src/shared/domain/logger';
3
4
  import { type CommandRole, type Commands, type Formatter } from '#src/tools/domain/commands';
4
5
  import type { Tool } from '#src/tools/domain/tool';
@@ -62,6 +63,11 @@ export interface CreateLLMAgentOptions {
62
63
  autoApprove?: boolean;
63
64
  /** Defaults to warnings on stderr. */
64
65
  logger?: ILogger;
66
+ /**
67
+ * Receives what the model saw in each run once the run ended, completed, failed or
68
+ * cancelled, for debugging. See `Transcript`. Without it, nothing is kept.
69
+ */
70
+ onTranscript?: TranscriptCallback;
65
71
  }
66
72
  /** A limit per role of `createLLMOrchestrator`; a role left out keeps its default. */
67
73
  export type RoleSteps = Partial<Record<OrchestratorRole, number>>;
@@ -104,6 +110,11 @@ export interface CreateLLMOrchestratorOptions extends CreateOrchestratorOptions
104
110
  * role. See `CreateLLMAgentOptions.summarizeUndone`. Defaults to `true`.
105
111
  */
106
112
  summarizeUndone?: boolean;
113
+ /**
114
+ * Receives what the model saw in each run of each role and each explorer, once the run
115
+ * ended, for debugging. Each transcript names its role. See `Transcript`.
116
+ */
117
+ onTranscript?: TranscriptCallback;
107
118
  }
108
119
  /**
109
120
  * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in
@@ -117,7 +128,7 @@ export interface CreateLLMOrchestratorOptions extends CreateOrchestratorOptions
117
128
  * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing
118
129
  * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.
119
130
  */
120
- export declare function createLLMAgent(provider: AgentProvider, { model, reasoningEffort, systemPrompt, tools, workspace, summarizeUndone, maxSteps, compactAt, autoApprove, logger, }: CreateLLMAgentOptions): Agent;
131
+ export declare function createLLMAgent(provider: AgentProvider, { model, reasoningEffort, systemPrompt, tools, workspace, summarizeUndone, maxSteps, compactAt, autoApprove, logger, onTranscript, }: CreateLLMAgentOptions): Agent;
121
132
  /**
122
133
  * The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the
123
134
  * provider's own format:
@@ -183,5 +194,5 @@ export declare function createFileTools(provider: AgentProvider, workspace: Work
183
194
  * @throws {UnrecoverableError} when a role cannot be set up, for example because
184
195
  * `OPENAI_API_KEY` is missing, or when no program can read the repository.
185
196
  */
186
- export declare function createLLMOrchestrator({ provider, autoApprove, systemPrompts, workspace, maxSteps, compactAt, commands, formatter, summarizeUndone, logger, }?: CreateLLMOrchestratorOptions): Promise<Agent>;
197
+ export declare function createLLMOrchestrator({ provider, autoApprove, systemPrompts, workspace, maxSteps, compactAt, commands, formatter, summarizeUndone, logger, onTranscript, }?: CreateLLMOrchestratorOptions): Promise<Agent>;
187
198
  export {};
@@ -157,7 +157,7 @@ function withGuidance(systemPrompt, guidance) {
157
157
  return guidance === '' ? systemPrompt : `${systemPrompt}\n\n${guidance}`;
158
158
  }
159
159
  /** An `LLMAgent` on `provider`, wrapped in the harness's retry policy. */
160
- function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools, history, summarizer, maxSteps, compactAt, autoApprove, logger, }) {
160
+ function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools, history, summarizer, maxSteps, compactAt, autoApprove, logger, onTranscript, }) {
161
161
  const llmClient = llmClientFor(provider, {
162
162
  model,
163
163
  reasoningEffort,
@@ -175,6 +175,7 @@ function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools,
175
175
  ...(history ? { history } : {}),
176
176
  ...(summarizer ? { summarizer } : {}),
177
177
  ...(maxSteps === undefined ? {} : { maxSteps }),
178
+ ...(onTranscript ? { onTranscript } : {}),
178
179
  }),
179
180
  logger,
180
181
  noteFailures: false,
@@ -192,7 +193,7 @@ function buildLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools,
192
193
  * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing
193
194
  * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.
194
195
  */
195
- export function createLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools = [], workspace, summarizeUndone = true, maxSteps, compactAt, autoApprove, logger = new Logger(), }) {
196
+ export function createLLMAgent(provider, { model, reasoningEffort, systemPrompt, tools = [], workspace, summarizeUndone = true, maxSteps, compactAt, autoApprove, logger = new Logger(), onTranscript, }) {
196
197
  return buildLLMAgent(provider, {
197
198
  model,
198
199
  reasoningEffort,
@@ -207,6 +208,7 @@ export function createLLMAgent(provider, { model, reasoningEffort, systemPrompt,
207
208
  compactAt,
208
209
  autoApprove,
209
210
  logger,
211
+ onTranscript,
210
212
  });
211
213
  }
212
214
  /**
@@ -327,7 +329,7 @@ const repositoryGuidance = {
327
329
  * @throws {UnrecoverableError} when a role cannot be set up, for example because
328
330
  * `OPENAI_API_KEY` is missing, or when no program can read the repository.
329
331
  */
330
- export async function createLLMOrchestrator({ provider, autoApprove, systemPrompts = {}, workspace = { roots: [{ path: process.cwd(), access: 'read' }] }, maxSteps, compactAt, commands, formatter, summarizeUndone = true, logger = new Logger(), } = {}) {
332
+ export async function createLLMOrchestrator({ provider, autoApprove, systemPrompts = {}, workspace = { roots: [{ path: process.cwd(), access: 'read' }] }, maxSteps, compactAt, commands, formatter, summarizeUndone = true, logger = new Logger(), onTranscript, } = {}) {
331
333
  const roles = orchestratorRolesFor(provider);
332
334
  const steps = perRole('maxSteps', maxSteps, defaultRoleSteps, {
333
335
  unit: 'steps',
@@ -348,6 +350,8 @@ export async function createLLMOrchestrator({ provider, autoApprove, systemPromp
348
350
  const prompt = (role, own, instructions) => own === undefined
349
351
  ? withGuidance(instructions, `${guidance}\n${repositoryGuidance[role]}`)
350
352
  : withGuidance(own, guidance);
353
+ // Each transcript names the agent it is of.
354
+ const transcriptsOf = (agent) => onTranscript && ((transcript) => onTranscript({ ...transcript, agent }));
351
355
  // Every command, checked once, before any role takes its share.
352
356
  if (commands !== undefined)
353
357
  validateCommands(commands);
@@ -359,6 +363,7 @@ export async function createLLMOrchestrator({ provider, autoApprove, systemPromp
359
363
  tools: explorerToolset,
360
364
  maxSteps: explorerSteps,
361
365
  logger,
366
+ onTranscript: transcriptsOf('explorer'),
362
367
  });
363
368
  const reader = async ({ provider, model, reasoningEffort }, role, systemPrompt) => buildLLMAgent(provider, {
364
369
  model,
@@ -367,6 +372,7 @@ export async function createLLMOrchestrator({ provider, autoApprove, systemPromp
367
372
  tools: await readingTools(opened, role, commands, explorer(provider)),
368
373
  maxSteps: steps[role],
369
374
  compactAt: compaction[role],
375
+ onTranscript: transcriptsOf(role),
370
376
  ...shared,
371
377
  });
372
378
  const { executor } = roles;
@@ -384,6 +390,7 @@ export async function createLLMOrchestrator({ provider, autoApprove, systemPromp
384
390
  maxSteps: steps.executor,
385
391
  compactAt: compaction.executor,
386
392
  autoApprove,
393
+ onTranscript: transcriptsOf('executor'),
387
394
  ...shared,
388
395
  }),
389
396
  reviewerAgent: await reader(roles.reviewer, 'reviewer', prompt('reviewer', systemPrompts.reviewer, executorRuns ? reviewerInstructions : reviewerInstructionsWithoutCommands)),
@@ -1 +1 @@
1
- {"version":3,"file":"agentLLMFactory.js","sourceRoot":"","sources":["../../../src/factory/infrastructure/agentLLMFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from 'node:path';\nimport type { Agent } from '#src/agent/domain/agent';\nimport type { HistoryReader } from '#src/engines/domain/model/historyFollower';\nimport { LLMAgent } from '#src/engines/domain/model/llmAgent';\nimport type { LLMClient } from '#src/llm/domain/llm';\nimport {\n\tClaudeLLMClient,\n\tclaudeLLMModels,\n\tclaudeLLMReasoningEfforts,\n} from '#src/llm/infrastructure/claudeLLMClient';\nimport {\n\tOpenAILLMClient,\n\topenAIModels,\n\topenAIReasoningEfforts,\n} from '#src/llm/infrastructure/openAILLMClient';\nimport {\n\texecutorInstructions,\n\texecutorInstructionsWithoutCommands,\n\tOrchestratorAgent,\n\tplannerInstructions,\n\treviewerInstructions,\n\treviewerInstructionsWithoutCommands,\n} from '#src/orchestration/domain/model/orchestratorAgent';\nimport { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';\nimport type { RecoveryStore } from '#src/recovery/domain/recoveryStore';\nimport { RetryingAgent } from '#src/retry/domain/model/retryingAgent';\nimport { InvalidAgentConfigError } from '#src/shared/domain/errors';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { Logger } from '#src/shared/infrastructure/logger';\nimport type { WorkspaceRoot } from '#src/tools/domain/accessPolicy';\nimport {\n\ttype CommandRole,\n\ttype Commands,\n\tcommandsFor,\n\ttype Formatter,\n\tvalidateCommands,\n\tvalidateFormatter,\n} from '#src/tools/domain/commands';\nimport type { AgentTool } from '#src/tools/domain/preparedCall';\nimport type { Tool } from '#src/tools/domain/tool';\nimport {\n\tcommandToolFor,\n\ttype FileTool,\n\tfileToolsFor,\n\ttype OpenedWorkspace,\n\topenStore,\n\topenWorkspace,\n\tstateDirectoryOf,\n\ttype WorkspaceOptions,\n} from '#src/tools/infrastructure/fileTools';\nimport { createExploreTool } from '#src/tools/infrastructure/exploreTool';\nimport { createShowChangesTool } from '#src/tools/infrastructure/showChangesTool';\nimport { createTrackedReadFile } from '#src/tools/infrastructure/trackedReadFile';\nimport { createWorkspaceTools } from '#src/tools/infrastructure/workspaceTools';\nimport { isAgentProvider, orchestratorRolesFor, type Role } from './agentFactory.ts';\nimport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './types.ts';\n\n/** The models each provider's model API accepts. */\nexport const llmModels = {\n\tanthropic: claudeLLMModels,\n\topenai: openAIModels,\n} as const satisfies Readonly<Record<AgentProvider, readonly AgentModel[]>>;\n\n/** The reasoning efforts each provider's model API accepts. */\nexport const llmReasoningEfforts = {\n\tanthropic: claudeLLMReasoningEfforts,\n\topenai: openAIReasoningEfforts,\n} as const satisfies Readonly<Record<AgentProvider, readonly ReasoningEffort[]>>;\n\n/** Narrows a model to one accepted by the selected provider's model API. */\nexport function isLLMModelOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmModels)[Provider][number] {\n\treturn isOneOf(llmModels[provider], value);\n}\n\n/** Narrows a reasoning effort to one accepted by the selected provider's model API. */\nexport function isLLMReasoningEffortOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmReasoningEfforts)[Provider][number] {\n\treturn isOneOf(llmReasoningEfforts[provider], value);\n}\n\nexport interface CreateLLMAgentOptions {\n\t/**\n\t * Defaults to `'sonnet'` on Anthropic and `'gpt-5.6-luna'` on OpenAI. The provider's client\n\t * rejects a model it does not support.\n\t */\n\tmodel?: AgentModel;\n\t/** Defaults to `'high'`. The provider's client rejects an effort it does not support. */\n\treasoningEffort?: ReasoningEffort;\n\t/** Sent as the model's instructions on every call. */\n\tsystemPrompt: string;\n\t/** The tools the model may call: the consumer's own, and those of `createFileTools`. Defaults to none. */\n\ttools?: (Tool | FileTool)[];\n\t/**\n\t * The folders the agent works on, the same as given to `createFileTools`. With it, the agent\n\t * follows the workspace's history: after the user undoes runs, its next run starts from the\n\t * conversation as it was, and is told what was undone. The system prompt is followed by the\n\t * roots and how to name a file in them.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * With `workspace`, a summary of what was undone, from the provider's cheap model, in place\n\t * of the undone prompts. That is Claude Haiku without thinking, or `gpt-5.6-luna` at high\n\t * effort, and the call is billed with the run's tokens. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * How many calls to the model one run may make before it fails. Defaults to 65, with no upper\n\t * bound. A run that asks for exactly the same tool calls 5 times in a row fails before that.\n\t */\n\tmaxSteps?: number;\n\t/**\n\t * The input tokens at which the provider compacts the conversation on its side: it replaces\n\t * every turn before that call with its own summary, which only its model reads back. The\n\t * conversation keeps every original turn. Without it, the conversation is never compacted.\n\t * At least 50,000 on Anthropic, where Claude Haiku cannot compact.\n\t */\n\tcompactAt?: number;\n\t/**\n\t * Runs every tool call without asking, `destructive` ones included, for CI where no one can\n\t * answer. Without it, a `destructive` call goes to the run's `approve`, or is denied.\n\t */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n}\n\n/** A limit per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleSteps = Partial<Record<OrchestratorRole, number>>;\n\n/** A number of tokens per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleTokens = Partial<Record<OrchestratorRole, number>>;\n\n// The same three roles a command can be given to.\ntype OrchestratorRole = CommandRole;\n\n// The executor reads, edits and checks, so it needs more calls than the roles that only read.\nconst defaultRoleSteps: Record<OrchestratorRole, number> = {\n\tplanner: 65,\n\texecutor: 80,\n\treviewer: 65,\n};\n\n// No role compacts unless asked to.\nconst defaultRoleCompaction: Record<OrchestratorRole, number | undefined> = {\n\tplanner: undefined,\n\texecutor: undefined,\n\treviewer: undefined,\n};\n\n/**\n * Each role's value of the option `name`, from one number for all of them or a number per role.\n * Each number is checked by whatever takes it.\n *\n * @throws {InvalidAgentConfigError} for a value that is neither, and for a role that does not\n * exist, which is a typo that would otherwise leave that role on its default without a word.\n */\nfunction perRole<T extends number | undefined>(\n\tname: string,\n\tvalue: unknown,\n\tdefaults: Record<OrchestratorRole, T>,\n\t{ unit, example }: { unit: string; example: string },\n): Record<OrchestratorRole, T | number> {\n\tif (value === undefined) return defaults;\n\tif (typeof value === 'number') return { planner: value, executor: value, reviewer: value };\n\t// Untyped input, such as the CLI's configuration file, can hold `null` or a list here.\n\tif (typeof value !== 'object' || value === null || Array.isArray(value)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} must be a number or an object of ${unit} per role, such as ${example}`,\n\t\t);\n\t}\n\tconst unknown = Object.keys(value).filter(role => !(role in defaults));\n\tif (unknown.length > 0) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} names roles that do not exist: ${unknown.join(', ')}; expected planner, executor or reviewer`,\n\t\t);\n\t}\n\t// A role given as `undefined`, which untyped input can do, keeps its default.\n\tconst given = Object.entries(value as Record<string, unknown>).filter(\n\t\t([, each]) => each !== undefined,\n\t);\n\treturn { ...defaults, ...Object.fromEntries(given) };\n}\n\nexport interface CreateLLMOrchestratorOptions extends CreateOrchestratorOptions {\n\t/**\n\t * The folders the agents work on. The executor changes files only in a `write` root, every\n\t * change recorded in the workspace's history. Defaults to the current working directory,\n\t * read only.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * How many calls to the model one run of each role may make: one number for every role, or a\n\t * number per role. Defaults to 80 for the executor and 65 for the planner and the reviewer,\n\t * with no upper bound. A run that asks for exactly the same tool calls 5 times in a row fails\n\t * before its limit.\n\t */\n\tmaxSteps?: number | RoleSteps;\n\t/**\n\t * The input tokens at which each role's provider compacts its conversation, as\n\t * `CreateLLMAgentOptions.compactAt`: one number for every role, or a number per role. Without\n\t * it, no role compacts.\n\t */\n\tcompactAt?: number | RoleTokens;\n\t/**\n\t * Commands the roles may run, such as the project's tests, through `runCommand`. Each goes to\n\t * the roles its `roles` names, the executor by default. See `createFileTools`. Each needs a\n\t * `write` root to run in.\n\t */\n\tcommands?: Commands;\n\t/**\n\t * A program the executor's edits run on each file they create or change, such as the\n\t * project's formatter. See `createFileTools`. It needs a `write` root to run in.\n\t */\n\tformatter?: Formatter;\n\t/**\n\t * A summary of what the user undid, from the planner's provider's cheap model, for every\n\t * role. See `CreateLLMAgentOptions.summarizeUndone`. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n}\n\nconst defaultLLMAgentModels = {\n\tanthropic: 'sonnet',\n\topenai: 'gpt-5.6-luna',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\nfunction unknownProvider(provider: never): InvalidAgentConfigError {\n\treturn new InvalidAgentConfigError(\n\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t);\n}\n\nfunction llmClientFor(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tcompactAt?: number | undefined;\n\t\tsystemPrompt: string;\n\t\tlogger: ILogger;\n\t},\n): LLMClient {\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\t\treturn new ClaudeLLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.anthropic,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tcase 'openai':\n\t\t\treturn new OpenAILLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.openai,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tdefault:\n\t\t\t// Reachable from untyped input.\n\t\t\tthrow unknownProvider(provider);\n\t}\n}\n\n/** The provider's cheap model, for the summary of what was undone. */\nfunction summarizerFor(provider: AgentProvider, logger: ILogger): LLMClient {\n\treturn provider === 'anthropic'\n\t\t? new ClaudeLLMClient({ model: 'haiku', systemPrompt: '', logger })\n\t\t: new OpenAILLMClient({\n\t\t\t\tmodel: 'gpt-5.6-luna',\n\t\t\t\treasoningEffort: 'high',\n\t\t\t\tsystemPrompt: '',\n\t\t\t\tlogger,\n\t\t\t});\n}\n\n/**\n * The workspace's history, opened on first use, so a factory that builds an agent stays\n * synchronous. Every agent and every file tool of one workspace reads the same files on disk.\n */\nfunction historyOf(workspace: WorkspaceOptions): HistoryReader {\n\t// Checked now: an agent with no root to follow is a setup error, not a first-run one.\n\tif (workspace.roots.length === 0) {\n\t\tthrow new InvalidAgentConfigError('A workspace needs at least one root');\n\t}\n\tlet store: Promise<RecoveryStore> | undefined;\n\tconst open = () => {\n\t\tstore ??= stateDirectoryOf(workspace)\n\t\t\t.then(directory => openStore(workspace, directory))\n\t\t\t.catch((error: unknown) => {\n\t\t\t\t// Not kept: the next run tries again, as one whose disk was full for a moment.\n\t\t\t\tstore = undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\treturn store;\n\t};\n\treturn {\n\t\tlistRuns: async () => (await open()).listRuns(),\n\t\tlistRevisions: async () => (await open()).listRevisions(),\n\t\treadRun: async runId => (await open()).readRun(runId),\n\t};\n}\n\n/**\n * What the model is told about the workspace after its instructions: the roots, which it may\n * change, and how to name a file. A host path in an error sends the model looking for it, so\n * the real root is given here once.\n */\nfunction workspaceGuidance(roots: WorkspaceRoot[]): string {\n\tconst [first, ...others] = roots.map(root => ({ ...root, path: resolve(root.path) }));\n\tif (!first) return '';\n\tconst described = [first, ...others].map(\n\t\t({ path, access }) => `- ${path}${access === 'write' ? '' : ' (read only)'}`,\n\t);\n\treturn [\n\t\t'The workspace:',\n\t\t...described,\n\t\t`Name a file by its path relative to ${first.path}, such as src/index.ts, and a file in another folder of the workspace by its full path. Read a file before you change it.`,\n\t].join('\\n');\n}\n\nfunction withGuidance(systemPrompt: string, guidance: string): string {\n\treturn guidance === '' ? systemPrompt : `${systemPrompt}\\n\\n${guidance}`;\n}\n\n/** An `LLMAgent` on `provider`, wrapped in the harness's retry policy. */\nfunction buildLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools,\n\t\thistory,\n\t\tsummarizer,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tsystemPrompt: string;\n\t\ttools: AgentTool[];\n\t\thistory?: HistoryReader;\n\t\tsummarizer?: LLMClient;\n\t\tmaxSteps?: number;\n\t\tcompactAt?: number | undefined;\n\t\tautoApprove?: boolean;\n\t\tlogger: ILogger;\n\t},\n): Agent {\n\tconst llmClient = llmClientFor(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t});\n\t// LLMAgent records nothing from a failed call, so the original prompt is the whole story.\n\treturn new RetryingAgent({\n\t\tinner: new LLMAgent({\n\t\t\tllmClient,\n\t\t\ttools,\n\t\t\tautoApprove,\n\t\t\tlogger,\n\t\t\t...(history ? { history } : {}),\n\t\t\t...(summarizer ? { summarizer } : {}),\n\t\t\t...(maxSteps === undefined ? {} : { maxSteps }),\n\t\t}),\n\t\tlogger,\n\t\tnoteFailures: false,\n\t});\n}\n\n/**\n * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in\n * the harness's retry policy. It needs the provider's API key and bills per token, where\n * `createAgent` uses the Agent SDK's login. Each tool judges the risk of each call; a\n * `destructive` one runs only when the run's `approve` allows it, or with `autoApprove`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a model or reasoning effort its\n * client does not support, or two tools that share a name.\n * @throws {UnrecoverableError} when the client cannot be set up, for example because\n * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing\n * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.\n */\nexport function createLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools = [],\n\t\tworkspace,\n\t\tsummarizeUndone = true,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger = new Logger(),\n\t}: CreateLLMAgentOptions,\n): Agent {\n\treturn buildLLMAgent(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt: workspace\n\t\t\t? withGuidance(systemPrompt, workspaceGuidance(workspace.roots))\n\t\t\t: systemPrompt,\n\t\t// A file tool is a harness tool under its public name.\n\t\ttools: tools as AgentTool[],\n\t\t...(workspace ? { history: historyOf(workspace) } : {}),\n\t\t...(workspace && summarizeUndone ? { summarizer: summarizerFor(provider, logger) } : {}),\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t});\n}\n\n/**\n * The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the\n * provider's own format:\n *\n * - OpenAI: `listFiles`, `searchText`, `readFile` and its native `apply_patch`;\n * - Anthropic: `listFiles`, `searchText`, its native text editor, whose `view` reads, and\n * `delete_file`.\n *\n * Every one goes through the workspace's access policy: a path outside the roots, a secret,\n * a file `.gitignore` excludes or the harness protects is refused. A change is made only in a\n * `write` root, only from a version the agent read, and is recorded in the workspace's history,\n * so it can be undone. Without a `write` root the tools only read. Give the agent the same\n * `workspace`, so it follows what the history undoes.\n *\n * With `commands`, they include `runCommand`, which runs one of them by name, with only the\n * parameters it declares and never through a shell. Each run asks the approver, showing the\n * program exactly as it will run, and gets a small environment without the provider keys. The\n * files of the `write` roots are captured before it and compared after, so what it changed is\n * in the history too. It is trusted execution, not a sandbox: a command can reach whatever\n * this user can. Not supported on Windows yet.\n *\n * With `formatter`, every file an edit creates or changes is formatted right after, its path\n * the formatter's last argument, and the edit returns the file as the formatter left it. Like a\n * command it runs without a shell, in a small environment, and what it changes in that file is\n * in the history. When it fails, the file stays as the edit wrote it, and the model is told\n * why. Not supported on Windows yet.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a workspace with no root, or an\n * invalid command or formatter, including one whose `cwd` is not in a `write` root, or any on\n * Windows.\n * @throws {UnrecoverableError} when no program can read the first root.\n */\nexport async function createFileTools(\n\tprovider: AgentProvider,\n\tworkspace: WorkspaceOptions,\n\t{\n\t\tlogger = new Logger(),\n\t\tcommands,\n\t\tformatter,\n\t}: { logger?: ILogger; commands?: Commands; formatter?: Formatter } = {},\n): Promise<FileTool[]> {\n\t// Reachable from untyped input.\n\tif (!isAgentProvider(provider)) throw unknownProvider(provider);\n\tif (commands !== undefined) validateCommands(commands);\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\treturn (await executorTools(provider, opened, commands)) as unknown as FileTool[];\n}\n\n/** The executor's file tools, and `runCommand` when there are commands. */\nasync function executorTools(\n\tprovider: AgentProvider,\n\tworkspace: OpenedWorkspace,\n\tcommands: Commands | undefined,\n): Promise<AgentTool[]> {\n\tconst tools = fileToolsFor(provider, workspace);\n\t// Every command may belong to other roles, leaving none for this one.\n\tif (commands === undefined || Object.keys(commands).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, commands)];\n}\n\n/** What an explorer finds and reads with: no edits, no changes, no commands. */\nfunction explorerTools({ read, policy }: OpenedWorkspace): AgentTool[] {\n\tconst finding = createWorkspaceTools(read).filter(tool => tool.name !== 'readFile');\n\treturn [...finding, createTrackedReadFile(policy)];\n}\n\n/**\n * What the planner and the reviewer read with: no edits, the current task's changes, `explore`\n * with `explorer`, and the commands given to their role.\n */\nasync function readingTools(\n\tworkspace: OpenedWorkspace,\n\trole: CommandRole,\n\tcommands: Commands | undefined,\n\texplorer: () => Agent,\n): Promise<AgentTool[]> {\n\tconst { policy, store } = workspace;\n\tconst tools = [\n\t\t...explorerTools(workspace),\n\t\tcreateShowChangesTool({ store, policy }),\n\t\tcreateExploreTool(explorer),\n\t];\n\tconst own = commands && commandsFor(commands, role);\n\tif (!own || Object.keys(own).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, own)];\n}\n\nconst batching =\n\t'When you know you need several files, or several searches, ask for all of them in one answer rather than one at a time: each answer is a step, and steps are limited.';\n\nconst exploring =\n\t'To learn an area of the repository, send explorers: ask `explore` the independent questions you have in one call, and read yourself only what you must see exactly.';\n\n// Each provider's cheaper model, which only finds and reads. Haiku, which names Claude Haiku 4.5,\n// takes no reasoning effort.\nconst explorerRoles = {\n\tanthropic: { model: 'haiku' },\n\topenai: { model: 'gpt-5.6-luna', reasoningEffort: 'medium' },\n} as const satisfies Record<\n\tAgentProvider,\n\t{ model: AgentModel; reasoningEffort?: ReasoningEffort }\n>;\n\nconst explorerSteps = 30;\n\nconst explorerInstructions = `You explore a repository for another agent, which is planning or reviewing a change and asked you one question. Find what it asks with listFiles, searchText and readFile, reading only what the question needs. Answer with what you found: the files and line numbers, what that code does, and short excerpts where the exact text matters. Say what you looked for and could not find. Do not propose changes or a plan, and do not copy whole files. ${batching}`;\n\n// How each role finds its way, sent after the workspace's roots, so it stays short. Only the\n// planner learns the repository; the executor and the reviewer work from its plan, so a plan\n// that leaves them guessing is the planner's to fix, not theirs to make up for.\nconst repositoryGuidance: Record<CommandRole, string> = {\n\tplanner: `Start with AGENTS.md, which says where the architecture and the decisions are, and read only the parts your task needs. Name in the plan every file to change and what to change in it, so the executor needs nothing else. ${exploring} ${batching}`,\n\texecutor: `Work from the plan: read the files it names, and only what you need to change them. Do not study the repository's architecture or decisions; the plan already applied them. ${batching}`,\n\treviewer: `Work from the plan and the changes: read what they touch, and only what you need to judge them. ${exploring} ${batching}`,\n};\n\n/**\n * Builds the planner → executor → reviewer workflow with every role on the model APIs, each\n * holding its role's instructions, or `systemPrompts`, as its system prompt, followed by the\n * workspace's roots.\n *\n * - The planner and the reviewer read: `listFiles`, `searchText`, `readFile`, `showChanges`,\n * the current task's changes as far as each may read them, and `explore`, which sends up to 4\n * read-only explorers at once on the role's provider's cheaper model, each a new agent that\n * starts from its question.\n * - The executor gets its provider's file tools (see `createFileTools`), and changes files only\n * in a `write` root; `autoApprove` reaches only it.\n * - Each role has its own step limit: `maxSteps`, 80 for the executor and 65 for the others by\n * default.\n * - Each role gets `runCommand` with the `commands` whose `roles` name it, the executor by\n * default. A command asks the approver in any role, and its files are captured around it.\n * - When the executor has a command, it is told to finish only once the tests and checks pass,\n * or to say which fail, and the reviewer takes from its response whether they pass. Without\n * one, both are told the tests were not run, and the reviewer judges from the code whether\n * they would pass.\n *\n * One run of the orchestrator is one run of the workspace's history, every round and retry\n * included, and its `AgentResponse` names it. Every role follows what the user undoes.\n * Asynchronous because opening the workspace is.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, or a workspace with no root.\n * @throws {UnrecoverableError} when a role cannot be set up, for example because\n * `OPENAI_API_KEY` is missing, or when no program can read the repository.\n */\nexport async function createLLMOrchestrator({\n\tprovider,\n\tautoApprove,\n\tsystemPrompts = {},\n\tworkspace = { roots: [{ path: process.cwd(), access: 'read' }] },\n\tmaxSteps,\n\tcompactAt,\n\tcommands,\n\tformatter,\n\tsummarizeUndone = true,\n\tlogger = new Logger(),\n}: CreateLLMOrchestratorOptions = {}): Promise<Agent> {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst steps = perRole('maxSteps', maxSteps, defaultRoleSteps, {\n\t\tunit: 'steps',\n\t\texample: '{ \"executor\": 120 }',\n\t});\n\tconst compaction = perRole('compactAt', compactAt, defaultRoleCompaction, {\n\t\tunit: 'tokens',\n\t\texample: '{ \"executor\": 200000 }',\n\t});\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\tconst guidance = workspaceGuidance(workspace.roots);\n\tconst summarizer = summarizeUndone ? summarizerFor(roles.planner.provider, logger) : undefined;\n\tconst shared = { history: opened.store, ...(summarizer ? { summarizer } : {}), logger };\n\t// A caller's own prompt replaces our instructions and guidance, not the workspace: the model\n\t// needs the roots to name a file, as `createLLMAgent` gives them.\n\tconst prompt = (role: CommandRole, own: string | undefined, instructions: string) =>\n\t\town === undefined\n\t\t\t? withGuidance(instructions, `${guidance}\\n${repositoryGuidance[role]}`)\n\t\t\t: withGuidance(own, guidance);\n\t// Every command, checked once, before any role takes its share.\n\tif (commands !== undefined) validateCommands(commands);\n\t// A new explorer for each question, on the role's provider: it starts from the question alone.\n\tconst explorerToolset = explorerTools(opened);\n\tconst explorer = (provider: AgentProvider) => () =>\n\t\tbuildLLMAgent(provider, {\n\t\t\t...explorerRoles[provider],\n\t\t\tsystemPrompt: withGuidance(explorerInstructions, guidance),\n\t\t\ttools: explorerToolset,\n\t\t\tmaxSteps: explorerSteps,\n\t\t\tlogger,\n\t\t});\n\tconst reader = async (\n\t\t{ provider, model, reasoningEffort }: Role,\n\t\trole: CommandRole,\n\t\tsystemPrompt: string,\n\t) =>\n\t\tbuildLLMAgent(provider, {\n\t\t\tmodel,\n\t\t\treasoningEffort,\n\t\t\tsystemPrompt,\n\t\t\ttools: await readingTools(opened, role, commands, explorer(provider)),\n\t\t\tmaxSteps: steps[role],\n\t\t\tcompactAt: compaction[role],\n\t\t\t...shared,\n\t\t});\n\tconst { executor } = roles;\n\tconst executorToolset = await executorTools(\n\t\texecutor.provider,\n\t\topened,\n\t\tcommands && commandsFor(commands, 'executor'),\n\t);\n\t// The executor and the reviewer are told whether the tests were run, which only an executor\n\t// with a command can do.\n\tconst executorRuns = executorToolset.some(tool => tool.name === 'runCommand');\n\n\treturn new OrchestratorAgent({\n\t\tplannerAgent: await reader(\n\t\t\troles.planner,\n\t\t\t'planner',\n\t\t\tprompt('planner', systemPrompts.planner, plannerInstructions),\n\t\t),\n\t\texecutorAgent: buildLLMAgent(executor.provider, {\n\t\t\tmodel: executor.model,\n\t\t\treasoningEffort: executor.reasoningEffort,\n\t\t\tsystemPrompt: prompt(\n\t\t\t\t'executor',\n\t\t\t\tsystemPrompts.executor,\n\t\t\t\texecutorRuns ? executorInstructions : executorInstructionsWithoutCommands,\n\t\t\t),\n\t\t\ttools: executorToolset,\n\t\t\tmaxSteps: steps.executor,\n\t\t\tcompactAt: compaction.executor,\n\t\t\tautoApprove,\n\t\t\t...shared,\n\t\t}),\n\t\treviewerAgent: await reader(\n\t\t\troles.reviewer,\n\t\t\t'reviewer',\n\t\t\tprompt(\n\t\t\t\t'reviewer',\n\t\t\t\tsystemPrompts.reviewer,\n\t\t\t\texecutorRuns ? reviewerInstructions : reviewerInstructionsWithoutCommands,\n\t\t\t),\n\t\t),\n\t\treviewerDecisionValidator: new ReviewerDecisionValidator(),\n\t\tlogger,\n\t});\n}\n"]}
1
+ {"version":3,"file":"agentLLMFactory.js","sourceRoot":"","sources":["../../../src/factory/infrastructure/agentLLMFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from 'node:path';\nimport type { Agent } from '#src/agent/domain/agent';\nimport type { Transcript, TranscriptCallback } from '#src/agent/domain/transcript';\nimport type { HistoryReader } from '#src/engines/domain/model/historyFollower';\nimport { LLMAgent } from '#src/engines/domain/model/llmAgent';\nimport type { LLMClient } from '#src/llm/domain/llm';\nimport {\n\tClaudeLLMClient,\n\tclaudeLLMModels,\n\tclaudeLLMReasoningEfforts,\n} from '#src/llm/infrastructure/claudeLLMClient';\nimport {\n\tOpenAILLMClient,\n\topenAIModels,\n\topenAIReasoningEfforts,\n} from '#src/llm/infrastructure/openAILLMClient';\nimport {\n\texecutorInstructions,\n\texecutorInstructionsWithoutCommands,\n\tOrchestratorAgent,\n\tplannerInstructions,\n\treviewerInstructions,\n\treviewerInstructionsWithoutCommands,\n} from '#src/orchestration/domain/model/orchestratorAgent';\nimport { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';\nimport type { RecoveryStore } from '#src/recovery/domain/recoveryStore';\nimport { RetryingAgent } from '#src/retry/domain/model/retryingAgent';\nimport { InvalidAgentConfigError } from '#src/shared/domain/errors';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { Logger } from '#src/shared/infrastructure/logger';\nimport type { WorkspaceRoot } from '#src/tools/domain/accessPolicy';\nimport {\n\ttype CommandRole,\n\ttype Commands,\n\tcommandsFor,\n\ttype Formatter,\n\tvalidateCommands,\n\tvalidateFormatter,\n} from '#src/tools/domain/commands';\nimport type { AgentTool } from '#src/tools/domain/preparedCall';\nimport type { Tool } from '#src/tools/domain/tool';\nimport {\n\tcommandToolFor,\n\ttype FileTool,\n\tfileToolsFor,\n\ttype OpenedWorkspace,\n\topenStore,\n\topenWorkspace,\n\tstateDirectoryOf,\n\ttype WorkspaceOptions,\n} from '#src/tools/infrastructure/fileTools';\nimport { createExploreTool } from '#src/tools/infrastructure/exploreTool';\nimport { createShowChangesTool } from '#src/tools/infrastructure/showChangesTool';\nimport { createTrackedReadFile } from '#src/tools/infrastructure/trackedReadFile';\nimport { createWorkspaceTools } from '#src/tools/infrastructure/workspaceTools';\nimport { isAgentProvider, orchestratorRolesFor, type Role } from './agentFactory.ts';\nimport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './types.ts';\n\n/** The models each provider's model API accepts. */\nexport const llmModels = {\n\tanthropic: claudeLLMModels,\n\topenai: openAIModels,\n} as const satisfies Readonly<Record<AgentProvider, readonly AgentModel[]>>;\n\n/** The reasoning efforts each provider's model API accepts. */\nexport const llmReasoningEfforts = {\n\tanthropic: claudeLLMReasoningEfforts,\n\topenai: openAIReasoningEfforts,\n} as const satisfies Readonly<Record<AgentProvider, readonly ReasoningEffort[]>>;\n\n/** Narrows a model to one accepted by the selected provider's model API. */\nexport function isLLMModelOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmModels)[Provider][number] {\n\treturn isOneOf(llmModels[provider], value);\n}\n\n/** Narrows a reasoning effort to one accepted by the selected provider's model API. */\nexport function isLLMReasoningEffortOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmReasoningEfforts)[Provider][number] {\n\treturn isOneOf(llmReasoningEfforts[provider], value);\n}\n\nexport interface CreateLLMAgentOptions {\n\t/**\n\t * Defaults to `'sonnet'` on Anthropic and `'gpt-5.6-luna'` on OpenAI. The provider's client\n\t * rejects a model it does not support.\n\t */\n\tmodel?: AgentModel;\n\t/** Defaults to `'high'`. The provider's client rejects an effort it does not support. */\n\treasoningEffort?: ReasoningEffort;\n\t/** Sent as the model's instructions on every call. */\n\tsystemPrompt: string;\n\t/** The tools the model may call: the consumer's own, and those of `createFileTools`. Defaults to none. */\n\ttools?: (Tool | FileTool)[];\n\t/**\n\t * The folders the agent works on, the same as given to `createFileTools`. With it, the agent\n\t * follows the workspace's history: after the user undoes runs, its next run starts from the\n\t * conversation as it was, and is told what was undone. The system prompt is followed by the\n\t * roots and how to name a file in them.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * With `workspace`, a summary of what was undone, from the provider's cheap model, in place\n\t * of the undone prompts. That is Claude Haiku without thinking, or `gpt-5.6-luna` at high\n\t * effort, and the call is billed with the run's tokens. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * How many calls to the model one run may make before it fails. Defaults to 65, with no upper\n\t * bound. A run that asks for exactly the same tool calls 5 times in a row fails before that.\n\t */\n\tmaxSteps?: number;\n\t/**\n\t * The input tokens at which the provider compacts the conversation on its side: it replaces\n\t * every turn before that call with its own summary, which only its model reads back. The\n\t * conversation keeps every original turn. Without it, the conversation is never compacted.\n\t * At least 50,000 on Anthropic, where Claude Haiku cannot compact.\n\t */\n\tcompactAt?: number;\n\t/**\n\t * Runs every tool call without asking, `destructive` ones included, for CI where no one can\n\t * answer. Without it, a `destructive` call goes to the run's `approve`, or is denied.\n\t */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n\t/**\n\t * Receives what the model saw in each run once the run ended, completed, failed or\n\t * cancelled, for debugging. See `Transcript`. Without it, nothing is kept.\n\t */\n\tonTranscript?: TranscriptCallback;\n}\n\n/** A limit per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleSteps = Partial<Record<OrchestratorRole, number>>;\n\n/** A number of tokens per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleTokens = Partial<Record<OrchestratorRole, number>>;\n\n// The same three roles a command can be given to.\ntype OrchestratorRole = CommandRole;\n\n// The executor reads, edits and checks, so it needs more calls than the roles that only read.\nconst defaultRoleSteps: Record<OrchestratorRole, number> = {\n\tplanner: 65,\n\texecutor: 80,\n\treviewer: 65,\n};\n\n// No role compacts unless asked to.\nconst defaultRoleCompaction: Record<OrchestratorRole, number | undefined> = {\n\tplanner: undefined,\n\texecutor: undefined,\n\treviewer: undefined,\n};\n\n/**\n * Each role's value of the option `name`, from one number for all of them or a number per role.\n * Each number is checked by whatever takes it.\n *\n * @throws {InvalidAgentConfigError} for a value that is neither, and for a role that does not\n * exist, which is a typo that would otherwise leave that role on its default without a word.\n */\nfunction perRole<T extends number | undefined>(\n\tname: string,\n\tvalue: unknown,\n\tdefaults: Record<OrchestratorRole, T>,\n\t{ unit, example }: { unit: string; example: string },\n): Record<OrchestratorRole, T | number> {\n\tif (value === undefined) return defaults;\n\tif (typeof value === 'number') return { planner: value, executor: value, reviewer: value };\n\t// Untyped input, such as the CLI's configuration file, can hold `null` or a list here.\n\tif (typeof value !== 'object' || value === null || Array.isArray(value)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} must be a number or an object of ${unit} per role, such as ${example}`,\n\t\t);\n\t}\n\tconst unknown = Object.keys(value).filter(role => !(role in defaults));\n\tif (unknown.length > 0) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} names roles that do not exist: ${unknown.join(', ')}; expected planner, executor or reviewer`,\n\t\t);\n\t}\n\t// A role given as `undefined`, which untyped input can do, keeps its default.\n\tconst given = Object.entries(value as Record<string, unknown>).filter(\n\t\t([, each]) => each !== undefined,\n\t);\n\treturn { ...defaults, ...Object.fromEntries(given) };\n}\n\nexport interface CreateLLMOrchestratorOptions extends CreateOrchestratorOptions {\n\t/**\n\t * The folders the agents work on. The executor changes files only in a `write` root, every\n\t * change recorded in the workspace's history. Defaults to the current working directory,\n\t * read only.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * How many calls to the model one run of each role may make: one number for every role, or a\n\t * number per role. Defaults to 80 for the executor and 65 for the planner and the reviewer,\n\t * with no upper bound. A run that asks for exactly the same tool calls 5 times in a row fails\n\t * before its limit.\n\t */\n\tmaxSteps?: number | RoleSteps;\n\t/**\n\t * The input tokens at which each role's provider compacts its conversation, as\n\t * `CreateLLMAgentOptions.compactAt`: one number for every role, or a number per role. Without\n\t * it, no role compacts.\n\t */\n\tcompactAt?: number | RoleTokens;\n\t/**\n\t * Commands the roles may run, such as the project's tests, through `runCommand`. Each goes to\n\t * the roles its `roles` names, the executor by default. See `createFileTools`. Each needs a\n\t * `write` root to run in.\n\t */\n\tcommands?: Commands;\n\t/**\n\t * A program the executor's edits run on each file they create or change, such as the\n\t * project's formatter. See `createFileTools`. It needs a `write` root to run in.\n\t */\n\tformatter?: Formatter;\n\t/**\n\t * A summary of what the user undid, from the planner's provider's cheap model, for every\n\t * role. See `CreateLLMAgentOptions.summarizeUndone`. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * Receives what the model saw in each run of each role and each explorer, once the run\n\t * ended, for debugging. Each transcript names its role. See `Transcript`.\n\t */\n\tonTranscript?: TranscriptCallback;\n}\n\nconst defaultLLMAgentModels = {\n\tanthropic: 'sonnet',\n\topenai: 'gpt-5.6-luna',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\nfunction unknownProvider(provider: never): InvalidAgentConfigError {\n\treturn new InvalidAgentConfigError(\n\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t);\n}\n\nfunction llmClientFor(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tcompactAt?: number | undefined;\n\t\tsystemPrompt: string;\n\t\tlogger: ILogger;\n\t},\n): LLMClient {\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\t\treturn new ClaudeLLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.anthropic,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tcase 'openai':\n\t\t\treturn new OpenAILLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.openai,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tdefault:\n\t\t\t// Reachable from untyped input.\n\t\t\tthrow unknownProvider(provider);\n\t}\n}\n\n/** The provider's cheap model, for the summary of what was undone. */\nfunction summarizerFor(provider: AgentProvider, logger: ILogger): LLMClient {\n\treturn provider === 'anthropic'\n\t\t? new ClaudeLLMClient({ model: 'haiku', systemPrompt: '', logger })\n\t\t: new OpenAILLMClient({\n\t\t\t\tmodel: 'gpt-5.6-luna',\n\t\t\t\treasoningEffort: 'high',\n\t\t\t\tsystemPrompt: '',\n\t\t\t\tlogger,\n\t\t\t});\n}\n\n/**\n * The workspace's history, opened on first use, so a factory that builds an agent stays\n * synchronous. Every agent and every file tool of one workspace reads the same files on disk.\n */\nfunction historyOf(workspace: WorkspaceOptions): HistoryReader {\n\t// Checked now: an agent with no root to follow is a setup error, not a first-run one.\n\tif (workspace.roots.length === 0) {\n\t\tthrow new InvalidAgentConfigError('A workspace needs at least one root');\n\t}\n\tlet store: Promise<RecoveryStore> | undefined;\n\tconst open = () => {\n\t\tstore ??= stateDirectoryOf(workspace)\n\t\t\t.then(directory => openStore(workspace, directory))\n\t\t\t.catch((error: unknown) => {\n\t\t\t\t// Not kept: the next run tries again, as one whose disk was full for a moment.\n\t\t\t\tstore = undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\treturn store;\n\t};\n\treturn {\n\t\tlistRuns: async () => (await open()).listRuns(),\n\t\tlistRevisions: async () => (await open()).listRevisions(),\n\t\treadRun: async runId => (await open()).readRun(runId),\n\t};\n}\n\n/**\n * What the model is told about the workspace after its instructions: the roots, which it may\n * change, and how to name a file. A host path in an error sends the model looking for it, so\n * the real root is given here once.\n */\nfunction workspaceGuidance(roots: WorkspaceRoot[]): string {\n\tconst [first, ...others] = roots.map(root => ({ ...root, path: resolve(root.path) }));\n\tif (!first) return '';\n\tconst described = [first, ...others].map(\n\t\t({ path, access }) => `- ${path}${access === 'write' ? '' : ' (read only)'}`,\n\t);\n\treturn [\n\t\t'The workspace:',\n\t\t...described,\n\t\t`Name a file by its path relative to ${first.path}, such as src/index.ts, and a file in another folder of the workspace by its full path. Read a file before you change it.`,\n\t].join('\\n');\n}\n\nfunction withGuidance(systemPrompt: string, guidance: string): string {\n\treturn guidance === '' ? systemPrompt : `${systemPrompt}\\n\\n${guidance}`;\n}\n\n/** An `LLMAgent` on `provider`, wrapped in the harness's retry policy. */\nfunction buildLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools,\n\t\thistory,\n\t\tsummarizer,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t\tonTranscript,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tsystemPrompt: string;\n\t\ttools: AgentTool[];\n\t\thistory?: HistoryReader;\n\t\tsummarizer?: LLMClient;\n\t\tmaxSteps?: number;\n\t\tcompactAt?: number | undefined;\n\t\tautoApprove?: boolean;\n\t\tlogger: ILogger;\n\t\tonTranscript?: TranscriptCallback | undefined;\n\t},\n): Agent {\n\tconst llmClient = llmClientFor(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t});\n\t// LLMAgent records nothing from a failed call, so the original prompt is the whole story.\n\treturn new RetryingAgent({\n\t\tinner: new LLMAgent({\n\t\t\tllmClient,\n\t\t\ttools,\n\t\t\tautoApprove,\n\t\t\tlogger,\n\t\t\t...(history ? { history } : {}),\n\t\t\t...(summarizer ? { summarizer } : {}),\n\t\t\t...(maxSteps === undefined ? {} : { maxSteps }),\n\t\t\t...(onTranscript ? { onTranscript } : {}),\n\t\t}),\n\t\tlogger,\n\t\tnoteFailures: false,\n\t});\n}\n\n/**\n * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in\n * the harness's retry policy. It needs the provider's API key and bills per token, where\n * `createAgent` uses the Agent SDK's login. Each tool judges the risk of each call; a\n * `destructive` one runs only when the run's `approve` allows it, or with `autoApprove`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a model or reasoning effort its\n * client does not support, or two tools that share a name.\n * @throws {UnrecoverableError} when the client cannot be set up, for example because\n * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing\n * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.\n */\nexport function createLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools = [],\n\t\tworkspace,\n\t\tsummarizeUndone = true,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger = new Logger(),\n\t\tonTranscript,\n\t}: CreateLLMAgentOptions,\n): Agent {\n\treturn buildLLMAgent(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt: workspace\n\t\t\t? withGuidance(systemPrompt, workspaceGuidance(workspace.roots))\n\t\t\t: systemPrompt,\n\t\t// A file tool is a harness tool under its public name.\n\t\ttools: tools as AgentTool[],\n\t\t...(workspace ? { history: historyOf(workspace) } : {}),\n\t\t...(workspace && summarizeUndone ? { summarizer: summarizerFor(provider, logger) } : {}),\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t\tonTranscript,\n\t});\n}\n\n/**\n * The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the\n * provider's own format:\n *\n * - OpenAI: `listFiles`, `searchText`, `readFile` and its native `apply_patch`;\n * - Anthropic: `listFiles`, `searchText`, its native text editor, whose `view` reads, and\n * `delete_file`.\n *\n * Every one goes through the workspace's access policy: a path outside the roots, a secret,\n * a file `.gitignore` excludes or the harness protects is refused. A change is made only in a\n * `write` root, only from a version the agent read, and is recorded in the workspace's history,\n * so it can be undone. Without a `write` root the tools only read. Give the agent the same\n * `workspace`, so it follows what the history undoes.\n *\n * With `commands`, they include `runCommand`, which runs one of them by name, with only the\n * parameters it declares and never through a shell. Each run asks the approver, showing the\n * program exactly as it will run, and gets a small environment without the provider keys. The\n * files of the `write` roots are captured before it and compared after, so what it changed is\n * in the history too. It is trusted execution, not a sandbox: a command can reach whatever\n * this user can. Not supported on Windows yet.\n *\n * With `formatter`, every file an edit creates or changes is formatted right after, its path\n * the formatter's last argument, and the edit returns the file as the formatter left it. Like a\n * command it runs without a shell, in a small environment, and what it changes in that file is\n * in the history. When it fails, the file stays as the edit wrote it, and the model is told\n * why. Not supported on Windows yet.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a workspace with no root, or an\n * invalid command or formatter, including one whose `cwd` is not in a `write` root, or any on\n * Windows.\n * @throws {UnrecoverableError} when no program can read the first root.\n */\nexport async function createFileTools(\n\tprovider: AgentProvider,\n\tworkspace: WorkspaceOptions,\n\t{\n\t\tlogger = new Logger(),\n\t\tcommands,\n\t\tformatter,\n\t}: { logger?: ILogger; commands?: Commands; formatter?: Formatter } = {},\n): Promise<FileTool[]> {\n\t// Reachable from untyped input.\n\tif (!isAgentProvider(provider)) throw unknownProvider(provider);\n\tif (commands !== undefined) validateCommands(commands);\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\treturn (await executorTools(provider, opened, commands)) as unknown as FileTool[];\n}\n\n/** The executor's file tools, and `runCommand` when there are commands. */\nasync function executorTools(\n\tprovider: AgentProvider,\n\tworkspace: OpenedWorkspace,\n\tcommands: Commands | undefined,\n): Promise<AgentTool[]> {\n\tconst tools = fileToolsFor(provider, workspace);\n\t// Every command may belong to other roles, leaving none for this one.\n\tif (commands === undefined || Object.keys(commands).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, commands)];\n}\n\n/** What an explorer finds and reads with: no edits, no changes, no commands. */\nfunction explorerTools({ read, policy }: OpenedWorkspace): AgentTool[] {\n\tconst finding = createWorkspaceTools(read).filter(tool => tool.name !== 'readFile');\n\treturn [...finding, createTrackedReadFile(policy)];\n}\n\n/**\n * What the planner and the reviewer read with: no edits, the current task's changes, `explore`\n * with `explorer`, and the commands given to their role.\n */\nasync function readingTools(\n\tworkspace: OpenedWorkspace,\n\trole: CommandRole,\n\tcommands: Commands | undefined,\n\texplorer: () => Agent,\n): Promise<AgentTool[]> {\n\tconst { policy, store } = workspace;\n\tconst tools = [\n\t\t...explorerTools(workspace),\n\t\tcreateShowChangesTool({ store, policy }),\n\t\tcreateExploreTool(explorer),\n\t];\n\tconst own = commands && commandsFor(commands, role);\n\tif (!own || Object.keys(own).length === 0) return tools;\n\treturn [...tools, await commandToolFor(workspace, own)];\n}\n\nconst batching =\n\t'When you know you need several files, or several searches, ask for all of them in one answer rather than one at a time: each answer is a step, and steps are limited.';\n\nconst exploring =\n\t'To learn an area of the repository, send explorers: ask `explore` the independent questions you have in one call, and read yourself only what you must see exactly.';\n\n// Each provider's cheaper model, which only finds and reads. Haiku, which names Claude Haiku 4.5,\n// takes no reasoning effort.\nconst explorerRoles = {\n\tanthropic: { model: 'haiku' },\n\topenai: { model: 'gpt-5.6-luna', reasoningEffort: 'medium' },\n} as const satisfies Record<\n\tAgentProvider,\n\t{ model: AgentModel; reasoningEffort?: ReasoningEffort }\n>;\n\nconst explorerSteps = 30;\n\nconst explorerInstructions = `You explore a repository for another agent, which is planning or reviewing a change and asked you one question. Find what it asks with listFiles, searchText and readFile, reading only what the question needs. Answer with what you found: the files and line numbers, what that code does, and short excerpts where the exact text matters. Say what you looked for and could not find. Do not propose changes or a plan, and do not copy whole files. ${batching}`;\n\n// How each role finds its way, sent after the workspace's roots, so it stays short. Only the\n// planner learns the repository; the executor and the reviewer work from its plan, so a plan\n// that leaves them guessing is the planner's to fix, not theirs to make up for.\nconst repositoryGuidance: Record<CommandRole, string> = {\n\tplanner: `Start with AGENTS.md, which says where the architecture and the decisions are, and read only the parts your task needs. Name in the plan every file to change and what to change in it, so the executor needs nothing else. ${exploring} ${batching}`,\n\texecutor: `Work from the plan: read the files it names, and only what you need to change them. Do not study the repository's architecture or decisions; the plan already applied them. ${batching}`,\n\treviewer: `Work from the plan and the changes: read what they touch, and only what you need to judge them. ${exploring} ${batching}`,\n};\n\n/**\n * Builds the planner → executor → reviewer workflow with every role on the model APIs, each\n * holding its role's instructions, or `systemPrompts`, as its system prompt, followed by the\n * workspace's roots.\n *\n * - The planner and the reviewer read: `listFiles`, `searchText`, `readFile`, `showChanges`,\n * the current task's changes as far as each may read them, and `explore`, which sends up to 4\n * read-only explorers at once on the role's provider's cheaper model, each a new agent that\n * starts from its question.\n * - The executor gets its provider's file tools (see `createFileTools`), and changes files only\n * in a `write` root; `autoApprove` reaches only it.\n * - Each role has its own step limit: `maxSteps`, 80 for the executor and 65 for the others by\n * default.\n * - Each role gets `runCommand` with the `commands` whose `roles` name it, the executor by\n * default. A command asks the approver in any role, and its files are captured around it.\n * - When the executor has a command, it is told to finish only once the tests and checks pass,\n * or to say which fail, and the reviewer takes from its response whether they pass. Without\n * one, both are told the tests were not run, and the reviewer judges from the code whether\n * they would pass.\n *\n * One run of the orchestrator is one run of the workspace's history, every round and retry\n * included, and its `AgentResponse` names it. Every role follows what the user undoes.\n * Asynchronous because opening the workspace is.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, or a workspace with no root.\n * @throws {UnrecoverableError} when a role cannot be set up, for example because\n * `OPENAI_API_KEY` is missing, or when no program can read the repository.\n */\nexport async function createLLMOrchestrator({\n\tprovider,\n\tautoApprove,\n\tsystemPrompts = {},\n\tworkspace = { roots: [{ path: process.cwd(), access: 'read' }] },\n\tmaxSteps,\n\tcompactAt,\n\tcommands,\n\tformatter,\n\tsummarizeUndone = true,\n\tlogger = new Logger(),\n\tonTranscript,\n}: CreateLLMOrchestratorOptions = {}): Promise<Agent> {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst steps = perRole('maxSteps', maxSteps, defaultRoleSteps, {\n\t\tunit: 'steps',\n\t\texample: '{ \"executor\": 120 }',\n\t});\n\tconst compaction = perRole('compactAt', compactAt, defaultRoleCompaction, {\n\t\tunit: 'tokens',\n\t\texample: '{ \"executor\": 200000 }',\n\t});\n\tif (formatter !== undefined) validateFormatter(formatter);\n\tconst opened = await openWorkspace(workspace, logger, formatter ? { formatter } : {});\n\tconst guidance = workspaceGuidance(workspace.roots);\n\tconst summarizer = summarizeUndone ? summarizerFor(roles.planner.provider, logger) : undefined;\n\tconst shared = { history: opened.store, ...(summarizer ? { summarizer } : {}), logger };\n\t// A caller's own prompt replaces our instructions and guidance, not the workspace: the model\n\t// needs the roots to name a file, as `createLLMAgent` gives them.\n\tconst prompt = (role: CommandRole, own: string | undefined, instructions: string) =>\n\t\town === undefined\n\t\t\t? withGuidance(instructions, `${guidance}\\n${repositoryGuidance[role]}`)\n\t\t\t: withGuidance(own, guidance);\n\t// Each transcript names the agent it is of.\n\tconst transcriptsOf = (agent: Transcript['agent']) =>\n\t\tonTranscript && ((transcript: Transcript) => onTranscript({ ...transcript, agent }));\n\t// Every command, checked once, before any role takes its share.\n\tif (commands !== undefined) validateCommands(commands);\n\t// A new explorer for each question, on the role's provider: it starts from the question alone.\n\tconst explorerToolset = explorerTools(opened);\n\tconst explorer = (provider: AgentProvider) => () =>\n\t\tbuildLLMAgent(provider, {\n\t\t\t...explorerRoles[provider],\n\t\t\tsystemPrompt: withGuidance(explorerInstructions, guidance),\n\t\t\ttools: explorerToolset,\n\t\t\tmaxSteps: explorerSteps,\n\t\t\tlogger,\n\t\t\tonTranscript: transcriptsOf('explorer'),\n\t\t});\n\tconst reader = async (\n\t\t{ provider, model, reasoningEffort }: Role,\n\t\trole: CommandRole,\n\t\tsystemPrompt: string,\n\t) =>\n\t\tbuildLLMAgent(provider, {\n\t\t\tmodel,\n\t\t\treasoningEffort,\n\t\t\tsystemPrompt,\n\t\t\ttools: await readingTools(opened, role, commands, explorer(provider)),\n\t\t\tmaxSteps: steps[role],\n\t\t\tcompactAt: compaction[role],\n\t\t\tonTranscript: transcriptsOf(role),\n\t\t\t...shared,\n\t\t});\n\tconst { executor } = roles;\n\tconst executorToolset = await executorTools(\n\t\texecutor.provider,\n\t\topened,\n\t\tcommands && commandsFor(commands, 'executor'),\n\t);\n\t// The executor and the reviewer are told whether the tests were run, which only an executor\n\t// with a command can do.\n\tconst executorRuns = executorToolset.some(tool => tool.name === 'runCommand');\n\n\treturn new OrchestratorAgent({\n\t\tplannerAgent: await reader(\n\t\t\troles.planner,\n\t\t\t'planner',\n\t\t\tprompt('planner', systemPrompts.planner, plannerInstructions),\n\t\t),\n\t\texecutorAgent: buildLLMAgent(executor.provider, {\n\t\t\tmodel: executor.model,\n\t\t\treasoningEffort: executor.reasoningEffort,\n\t\t\tsystemPrompt: prompt(\n\t\t\t\t'executor',\n\t\t\t\tsystemPrompts.executor,\n\t\t\t\texecutorRuns ? executorInstructions : executorInstructionsWithoutCommands,\n\t\t\t),\n\t\t\ttools: executorToolset,\n\t\t\tmaxSteps: steps.executor,\n\t\t\tcompactAt: compaction.executor,\n\t\t\tautoApprove,\n\t\t\tonTranscript: transcriptsOf('executor'),\n\t\t\t...shared,\n\t\t}),\n\t\treviewerAgent: await reader(\n\t\t\troles.reviewer,\n\t\t\t'reviewer',\n\t\t\tprompt(\n\t\t\t\t'reviewer',\n\t\t\t\tsystemPrompts.reviewer,\n\t\t\t\texecutorRuns ? reviewerInstructions : reviewerInstructionsWithoutCommands,\n\t\t\t),\n\t\t),\n\t\treviewerDecisionValidator: new ReviewerDecisionValidator(),\n\t\tlogger,\n\t});\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export type { CommandArgument, CommandDefinition, CommandParameter, CommandRole,
7
7
  export type { SecretRules } from './tools/infrastructure/rootsAccessPolicy.ts';
8
8
  export { agentProviders, type AgentModel, type AgentProvider, type CreateOrchestratorOptions, type ReasoningEffort, } from './factory/infrastructure/types.ts';
9
9
  export { type Agent, type AgentResponse, type Callback, type ProgressAgent, type ProgressEvent, type StepContext, type RunOptions, } from './agent/domain/agent.ts';
10
+ export type { Transcript, TranscriptCallback } from './agent/domain/transcript.ts';
10
11
  export { InvalidAgentConfigError, RecoverableError, UnrecoverableError, } from './shared/domain/errors.ts';
11
12
  export { isAbortError } from './shared/domain/isAbortError.ts';
12
13
  export type { Tokens } from './shared/domain/tokens.ts';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,eAAe,EACf,SAAS,EACT,mBAAmB,GAEnB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACN,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,EACtB,SAAS,EACT,mBAAmB,GAKnB,MAAM,6CAA6C,CAAC;AAYrD,OAAO,EACN,cAAc,GAKd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAQN,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EACN,iBAAiB,GAOjB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GAGnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,OAAO,EACN,oBAAoB,GASpB,MAAM,+BAA+B,CAAC","sourcesContent":["export type { ILogger } from './shared/domain/logger.ts';\nexport {\n\tcreateAgent,\n\tcreateOrchestrator,\n\tagentModels,\n\tagentReasoningEfforts,\n\tisAgentProvider,\n\tisModelOf,\n\tisReasoningEffortOf,\n\ttype CreateAgentOptions,\n} from './factory/infrastructure/agentFactory.ts';\nexport {\n\tcreateFileTools,\n\tcreateLLMAgent,\n\tcreateLLMOrchestrator,\n\tisLLMModelOf,\n\tisLLMReasoningEffortOf,\n\tllmModels,\n\tllmReasoningEfforts,\n\ttype CreateLLMAgentOptions,\n\ttype CreateLLMOrchestratorOptions,\n\ttype RoleSteps,\n\ttype RoleTokens,\n} from './factory/infrastructure/agentLLMFactory.ts';\nexport type { FileTool, WorkspaceOptions } from './tools/infrastructure/fileTools.ts';\nexport type { WorkspaceRoot } from './tools/domain/accessPolicy.ts';\nexport type {\n\tCommandArgument,\n\tCommandDefinition,\n\tCommandParameter,\n\tCommandRole,\n\tCommands,\n\tFormatter,\n} from './tools/domain/commands.ts';\nexport type { SecretRules } from './tools/infrastructure/rootsAccessPolicy.ts';\nexport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './factory/infrastructure/types.ts';\nexport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressAgent,\n\ttype ProgressEvent,\n\ttype StepContext,\n\ttype RunOptions,\n} from './agent/domain/agent.ts';\nexport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n} from './shared/domain/errors.ts';\nexport { isAbortError } from './shared/domain/isAbortError.ts';\nexport type { Tokens } from './shared/domain/tokens.ts';\nexport {\n\trememberApprovals,\n\ttype ApprovalDecision,\n\ttype ApprovalRequest,\n\ttype Approver,\n\ttype CommandLine,\n\ttype RememberableDecision,\n\ttype ToolRisk,\n} from './agent/domain/approval.ts';\nexport type { Asker, QuestionOption, UserQuestion } from './agent/domain/question.ts';\nexport type { JSONSchema, ToolDefinition } from './llm/domain/tool.ts';\nexport type { Tool, ToolSummarizer } from './tools/domain/tool.ts';\nexport type { TextMatch, Workspace } from './tools/domain/workspace.ts';\nexport { defineTool } from './tools/infrastructure/defineTool.ts';\nexport { createWorkspace } from './tools/infrastructure/createWorkspace.ts';\nexport { createWorkspaceTools } from './tools/infrastructure/workspaceTools.ts';\nexport { createHistory } from './recovery/infrastructure/createHistory.ts';\nexport type { History, HistoryRun, Move } from './recovery/domain/history.ts';\nexport {\n\thistoryStart,\n\tNothingToMoveError,\n\tWorkspaceBusyError,\n\tWorkspaceMovedError,\n\ttype MoveOptions,\n\ttype RunStatus,\n} from './recovery/domain/recoveryStore.ts';\nexport { HistoryExpiredError, UnknownRunError } from './recovery/domain/runTree.ts';\nexport { createWorkflow } from './factory/infrastructure/workflowFactory.ts';\nexport {\n\tdefineWorkflowStages,\n\ttype CreateWorkflowOptions,\n\ttype Workflow,\n\ttype WorkflowResult,\n\ttype WorkflowStage,\n\ttype WorkflowStageDefinition,\n\ttype WorkflowStageName,\n\ttype WorkflowStageReport,\n\ttype WorkflowTransition,\n} from './workflow/domain/workflow.ts';\nexport type { Validator } from './shared/domain/validator.ts';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,eAAe,EACf,SAAS,EACT,mBAAmB,GAEnB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACN,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,EACtB,SAAS,EACT,mBAAmB,GAKnB,MAAM,6CAA6C,CAAC;AAYrD,OAAO,EACN,cAAc,GAKd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAQN,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EACN,iBAAiB,GAOjB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GAGnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,OAAO,EACN,oBAAoB,GASpB,MAAM,+BAA+B,CAAC","sourcesContent":["export type { ILogger } from './shared/domain/logger.ts';\nexport {\n\tcreateAgent,\n\tcreateOrchestrator,\n\tagentModels,\n\tagentReasoningEfforts,\n\tisAgentProvider,\n\tisModelOf,\n\tisReasoningEffortOf,\n\ttype CreateAgentOptions,\n} from './factory/infrastructure/agentFactory.ts';\nexport {\n\tcreateFileTools,\n\tcreateLLMAgent,\n\tcreateLLMOrchestrator,\n\tisLLMModelOf,\n\tisLLMReasoningEffortOf,\n\tllmModels,\n\tllmReasoningEfforts,\n\ttype CreateLLMAgentOptions,\n\ttype CreateLLMOrchestratorOptions,\n\ttype RoleSteps,\n\ttype RoleTokens,\n} from './factory/infrastructure/agentLLMFactory.ts';\nexport type { FileTool, WorkspaceOptions } from './tools/infrastructure/fileTools.ts';\nexport type { WorkspaceRoot } from './tools/domain/accessPolicy.ts';\nexport type {\n\tCommandArgument,\n\tCommandDefinition,\n\tCommandParameter,\n\tCommandRole,\n\tCommands,\n\tFormatter,\n} from './tools/domain/commands.ts';\nexport type { SecretRules } from './tools/infrastructure/rootsAccessPolicy.ts';\nexport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './factory/infrastructure/types.ts';\nexport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressAgent,\n\ttype ProgressEvent,\n\ttype StepContext,\n\ttype RunOptions,\n} from './agent/domain/agent.ts';\nexport type { Transcript, TranscriptCallback } from './agent/domain/transcript.ts';\nexport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n} from './shared/domain/errors.ts';\nexport { isAbortError } from './shared/domain/isAbortError.ts';\nexport type { Tokens } from './shared/domain/tokens.ts';\nexport {\n\trememberApprovals,\n\ttype ApprovalDecision,\n\ttype ApprovalRequest,\n\ttype Approver,\n\ttype CommandLine,\n\ttype RememberableDecision,\n\ttype ToolRisk,\n} from './agent/domain/approval.ts';\nexport type { Asker, QuestionOption, UserQuestion } from './agent/domain/question.ts';\nexport type { JSONSchema, ToolDefinition } from './llm/domain/tool.ts';\nexport type { Tool, ToolSummarizer } from './tools/domain/tool.ts';\nexport type { TextMatch, Workspace } from './tools/domain/workspace.ts';\nexport { defineTool } from './tools/infrastructure/defineTool.ts';\nexport { createWorkspace } from './tools/infrastructure/createWorkspace.ts';\nexport { createWorkspaceTools } from './tools/infrastructure/workspaceTools.ts';\nexport { createHistory } from './recovery/infrastructure/createHistory.ts';\nexport type { History, HistoryRun, Move } from './recovery/domain/history.ts';\nexport {\n\thistoryStart,\n\tNothingToMoveError,\n\tWorkspaceBusyError,\n\tWorkspaceMovedError,\n\ttype MoveOptions,\n\ttype RunStatus,\n} from './recovery/domain/recoveryStore.ts';\nexport { HistoryExpiredError, UnknownRunError } from './recovery/domain/runTree.ts';\nexport { createWorkflow } from './factory/infrastructure/workflowFactory.ts';\nexport {\n\tdefineWorkflowStages,\n\ttype CreateWorkflowOptions,\n\ttype Workflow,\n\ttype WorkflowResult,\n\ttype WorkflowStage,\n\ttype WorkflowStageDefinition,\n\ttype WorkflowStageName,\n\ttype WorkflowStageReport,\n\ttype WorkflowTransition,\n} from './workflow/domain/workflow.ts';\nexport type { Validator } from './shared/domain/validator.ts';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikode13/harness",
3
- "version": "6.3.2",
3
+ "version": "7.0.0",
4
4
  "description": "Test/agent harness utility",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",