@mikode13/harness 7.0.0 → 8.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 +9 -6
- package/dist/engines/claude/infrastructure/model/claudeAgent.js +10 -3
- package/dist/engines/claude/infrastructure/model/claudeAgent.js.map +1 -1
- package/dist/factory/infrastructure/agentFactory.js +1 -1
- package/dist/factory/infrastructure/agentFactory.js.map +1 -1
- package/dist/factory/infrastructure/agentLLMFactory.d.ts +3 -3
- package/dist/factory/infrastructure/agentLLMFactory.js +3 -4
- package/dist/factory/infrastructure/agentLLMFactory.js.map +1 -1
- package/dist/llm/infrastructure/claudeLLMClient.js +17 -33
- package/dist/llm/infrastructure/claudeLLMClient.js.map +1 -1
- package/dist/llm/infrastructure/claudeModelIds.d.ts +11 -0
- package/dist/llm/infrastructure/claudeModelIds.js +12 -0
- package/dist/llm/infrastructure/claudeModelIds.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,7 +156,8 @@ releases, so render the ones you know and ignore the rest. Swapping the agent fo
|
|
|
156
156
|
`createAgent('openai')`, or for `createOrchestrator()` and its planner → executor →
|
|
157
157
|
reviewer workflow, changes nothing else in the snippet above.
|
|
158
158
|
`createOrchestrator({ provider: 'anthropic' })` runs every role on one provider, for
|
|
159
|
-
example when the other one is out of quota.
|
|
159
|
+
example when the other one is out of quota. On Anthropic, Claude Opus 5.5 plans and reviews
|
|
160
|
+
and Claude Haiku 5.5 executes at `xhigh`, as `gpt-5.6-sol` and `gpt-5.6-luna` do on OpenAI.
|
|
160
161
|
|
|
161
162
|
The optional `agent` field on an event identifies the orchestrator role that produced
|
|
162
163
|
it (`planner`, `executor`, or `reviewer`). The optional `summary` on a `tool` event
|
|
@@ -333,8 +334,10 @@ if (useModelApi) {
|
|
|
333
334
|
```
|
|
334
335
|
|
|
335
336
|
These guards describe the provider-wide catalogs. A client can still impose a model-specific
|
|
336
|
-
constraint,
|
|
337
|
-
|
|
337
|
+
constraint, and the factory's client or engine validation remains the final boundary for values
|
|
338
|
+
that bypass the guards. On Anthropic, `opus`, `sonnet` and `haiku` name Claude Opus 5.5, Sonnet
|
|
339
|
+
5.5 and Haiku 5.5, and `fable` Claude Fable 5.1, through the Agent SDK and the Messages API
|
|
340
|
+
alike: the harness sends the model's ID, not the alias.
|
|
338
341
|
|
|
339
342
|
Every agent a factory returns already retries recoverable failures. A model or
|
|
340
343
|
reasoning effort the chosen provider does not support throws
|
|
@@ -501,8 +504,8 @@ model APIs:
|
|
|
501
504
|
|
|
502
505
|
- the planner and the reviewer read, with a `showChanges` tool that gives the current task's
|
|
503
506
|
changes as far as each may read them, and an `explore` tool that sends up to 4 read-only
|
|
504
|
-
explorers at once, one per question, on the role's provider's cheaper model
|
|
505
|
-
|
|
507
|
+
explorers at once, one per question, on the role's provider's cheaper model at `medium`:
|
|
508
|
+
Claude Haiku 5.5, or `gpt-5.6-luna`. Each starts from its question alone and reports what it
|
|
506
509
|
found, so the role reads the reports instead of filling its own context with files. Their
|
|
507
510
|
usage counts in the run's, and their narration arrives as `subagent` events;
|
|
508
511
|
- the executor gets its provider's file tools. `autoApprove` reaches only the executor;
|
|
@@ -528,7 +531,7 @@ summary, which only its model reads back; the conversation keeps every original
|
|
|
528
531
|
call that compacts can lose its cache, as it did on OpenAI, so set it well above what a task
|
|
529
532
|
needs. Like
|
|
530
533
|
`maxSteps`, it is one number for every role or per role, and `createLLMAgent` takes one. On
|
|
531
|
-
Anthropic it must be at least 50,000
|
|
534
|
+
Anthropic it must be at least 50,000:
|
|
532
535
|
|
|
533
536
|
```ts
|
|
534
537
|
createLLMOrchestrator({ workspace, compactAt: { executor: 200_000 } });
|
|
@@ -3,8 +3,15 @@ import { ignoreProgress, } from '#src/agent/domain/agent';
|
|
|
3
3
|
import { InvalidAgentConfigError, RecoverableError, UnrecoverableError, withSpentTokens, } from '#src/shared/domain/errors';
|
|
4
4
|
import { classifiedProviderStream, classifyHostFailure, classifyLocalFailure, classifyProviderFailure, treatErrors, } from '#src/shared/domain/providerFailure';
|
|
5
5
|
import { isOneOf } from '#src/shared/domain/isOneOf';
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { claudeModelIds } from '#src/llm/infrastructure/claudeModelIds';
|
|
7
|
+
// The SDK types `model` as a plain string, so this list is maintained by hand. Each is sent as
|
|
8
|
+
// the ID `claudeModelIds` pins, not as the alias, which the Agent SDK would resolve its own way.
|
|
9
|
+
export const claudeModels = [
|
|
10
|
+
'haiku',
|
|
11
|
+
'sonnet',
|
|
12
|
+
'opus',
|
|
13
|
+
'fable',
|
|
14
|
+
];
|
|
8
15
|
export const claudeReasoningEfforts = [
|
|
9
16
|
'low',
|
|
10
17
|
'medium',
|
|
@@ -136,7 +143,7 @@ export class ClaudeAgent {
|
|
|
136
143
|
prompt,
|
|
137
144
|
options: {
|
|
138
145
|
effort: this.reasoningEffort,
|
|
139
|
-
model: this.model,
|
|
146
|
+
model: claudeModelIds[this.model],
|
|
140
147
|
maxTurns: 3,
|
|
141
148
|
cwd: process.cwd(),
|
|
142
149
|
resume: this.sessionId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeAgent.js","sourceRoot":"","sources":["../../../../../src/engines/claude/infrastructure/model/claudeAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@anthropic-ai/claude-agent-sdk';\nimport type {\n\tNonNullableUsage,\n\tEffortLevel,\n\tQuery,\n\tSDKAssistantMessage,\n\tSDKMessage,\n\tSDKResultSuccess,\n\tSDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\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\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '#src/shared/domain/errors';\nimport {\n\tclassifiedProviderStream,\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\ttreatErrors,\n} from '#src/shared/domain/providerFailure';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport type { Tokens } from '#src/shared/domain/tokens';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\n\n// The SDK types `model` as a plain string, so this list is maintained by hand.\nexport const claudeModels = ['haiku', 'sonnet', 'opus', 'fable'] as const;\nexport type ClaudeModel = (typeof claudeModels)[number];\n\nexport const claudeReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n] as const satisfies readonly EffortLevel[];\nexport type ClaudeReasoningEffort = (typeof claudeReasoningEfforts)[number];\n\ntype SDKSystemMessage = Extract<SDKMessage, { type: 'system' }>;\n\ninterface PendingTool {\n\tname: string;\n\tinput: Record<string, unknown>;\n\tserver?: string;\n}\n\ninterface ToolResultBlock {\n\ttype: string;\n\ttool_use_id: string;\n\tis_error?: boolean;\n\tcontent?: unknown;\n}\n\n// Claude reports its cache counters apart from input_tokens already.\nfunction toTokens(usage: NonNullableUsage): Tokens {\n\treturn {\n\t\tinputTokens: usage.input_tokens,\n\t\treadCacheTokens: usage.cache_read_input_tokens,\n\t\twrittenCacheTokens: usage.cache_creation_input_tokens,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\nfunction emitProgress(callback: Callback, event: ProgressEvent): void {\n\ttry {\n\t\tcallback(event);\n\t} catch (error) {\n\t\tthrow classifyHostFailure(error, 'Claude progress callback failed');\n\t}\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n\treturn typeof value === 'string' ? value : undefined;\n}\n\nfunction toolResultBlock(value: unknown): ToolResultBlock | undefined {\n\tconst block = asRecord(value);\n\tif (!block || typeof block.type !== 'string' || typeof block.tool_use_id !== 'string') {\n\t\treturn undefined;\n\t}\n\n\treturn block as unknown as ToolResultBlock;\n}\n\nfunction toolResultId(value: unknown): string | undefined {\n\treturn toolResultBlock(value)?.tool_use_id;\n}\n\nfunction fileChange(\n\tname: 'Edit' | 'Write',\n\ttool: PendingTool,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tconst inputPath = stringValue(tool.input.file_path);\n\tconst outputPath = stringValue(asRecord(output)?.filePath);\n\tconst path = outputPath ?? inputPath;\n\tif (!path) return undefined;\n\n\tconst kind =\n\t\tname === 'Write' && stringValue(asRecord(output)?.type) === 'create' ? 'add' : 'update';\n\treturn { type: 'fileChange', changes: [{ path, kind }] };\n}\n\nfunction todoList(tool: PendingTool): ProgressEvent | undefined {\n\tif (!Array.isArray(tool.input.todos)) return undefined;\n\n\tconst items = tool.input.todos.flatMap(todo => {\n\t\tconst item = asRecord(todo);\n\t\tconst text = stringValue(item?.content);\n\t\tconst status = stringValue(item?.status);\n\t\treturn text && status ? [{ text, completed: status === 'completed' }] : [];\n\t});\n\n\treturn { type: 'todoList', items };\n}\n\nfunction mcpTool(tool: PendingTool, result: ToolResultBlock): ProgressEvent | undefined {\n\tconst server = tool.server;\n\tconst toolName = tool.name.startsWith('mcp__')\n\t\t? tool.name.slice('mcp__'.length).split('__').slice(1).join('__')\n\t\t: tool.name;\n\tif (!server || !toolName) return undefined;\n\n\treturn {\n\t\ttype: 'mcpTool',\n\t\tserver,\n\t\ttool: toolName,\n\t\tstatus: result.is_error ? 'failed' : 'completed',\n\t};\n}\n\n// Tools without narration (Read, Grep, Task, ...) are a presentation choice, not an unknown:\n// the tool set is open-ended, so warning here would only produce noise.\nfunction describeCompletedTool(\n\ttool: PendingTool,\n\tresult: ToolResultBlock,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tif (tool.name === 'Bash') {\n\t\tconst exitCode = asRecord(output)?.exitCode ?? asRecord(output)?.exit_code;\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: stringValue(tool.input.command) ?? '',\n\t\t\t...(typeof exitCode === 'number' ? { exitCode } : {}),\n\t\t};\n\t}\n\n\tif (tool.name === 'WebSearch') {\n\t\tconst query = stringValue(tool.input.query);\n\t\treturn query ? { type: 'search', query } : undefined;\n\t}\n\n\tif (tool.name === 'Edit' || tool.name === 'Write') {\n\t\treturn result.is_error ? undefined : fileChange(tool.name, tool, output);\n\t}\n\n\tif (tool.name === 'TodoWrite') {\n\t\treturn result.is_error ? undefined : todoList(tool);\n\t}\n\n\tif (tool.name.startsWith('mcp__') || tool.server) {\n\t\treturn mcpTool(tool, result);\n\t}\n\n\treturn undefined;\n}\n\nexport class ClaudeAgent implements Agent {\n\tprivate model: ClaudeModel;\n\tprivate autoApprove: boolean;\n\tprivate reasoningEffort: ClaudeReasoningEffort;\n\tprivate sessionId?: string;\n\tprivate logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Claude supports, so it validates them instead of trusting the caller.\n\tconstructor({\n\t\tmodel,\n\t\tautoApprove = false,\n\t\treasoningEffort = 'high',\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\tautoApprove?: boolean;\n\t\treasoningEffort?: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\tif (!isOneOf(claudeModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Claude model; expected one of: ${claudeModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (!isOneOf(claudeReasoningEfforts, reasoningEffort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${reasoningEffort}\" is not a Claude reasoning effort; expected one of: ${claudeReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.model = model;\n\t\tthis.autoApprove = autoApprove;\n\t\tthis.reasoningEffort = reasoningEffort;\n\t\tthis.logger = logger;\n\t}\n\n\tasync run(\n\t\tprompt: string,\n\t\t{ signal, onProgress: callback = ignoreProgress }: RunOptions,\n\t): Promise<AgentResponse> {\n\t\tsignal.throwIfAborted();\n\t\tconst start = Date.now();\n\n\t\tlet stream: Query;\n\n\t\ttry {\n\t\t\tstream = query({\n\t\t\t\tprompt,\n\t\t\t\toptions: {\n\t\t\t\t\teffort: this.reasoningEffort,\n\t\t\t\t\tmodel: this.model,\n\t\t\t\t\tmaxTurns: 3,\n\t\t\t\t\tcwd: process.cwd(),\n\t\t\t\t\tresume: this.sessionId,\n\t\t\t\t\t...(this.autoApprove\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tpermissionMode: 'bypassPermissions' as const,\n\t\t\t\t\t\t\t\tallowDangerouslySkipPermissions: true,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'Claude refused the request');\n\t\t}\n\n\t\tconst closeStream = () => {\n\t\t\tstream.close();\n\t\t};\n\t\tsignal.addEventListener('abort', closeStream, { once: true });\n\n\t\ttry {\n\t\t\treturn await this.parseResponse(stream, signal, callback, start);\n\t\t} finally {\n\t\t\tsignal.removeEventListener('abort', closeStream);\n\t\t}\n\t}\n\n\tprivate async parseResponse(\n\t\tstream: Query,\n\t\tsignal: AbortSignal,\n\t\tcallback: Callback,\n\t\tstart: number,\n\t): Promise<AgentResponse> {\n\t\tconst lines: string[] = [];\n\t\tlet resultMessage: SDKResultSuccess | undefined;\n\t\tconst pendingTools = new Map<string, PendingTool>();\n\n\t\t// Once Claude sent an assistant message, the provider answered: a failure after that\n\t\t// without usage leaves the run's count unknown, unlike one that never got an answer.\n\t\tlet answered = false;\n\n\t\ttry {\n\t\t\tconst messages = classifiedProviderStream(stream, 'Claude stream ended unexpectedly');\n\n\t\t\tfor await (const message of messages) {\n\t\t\t\tthis.sessionId ??= message.session_id;\n\n\t\t\t\ttry {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'assistant':\n\t\t\t\t\t\t\tanswered = true;\n\t\t\t\t\t\t\tthis.handleAssistantMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'user':\n\t\t\t\t\t\t\tthis.handleUserMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'result':\n\t\t\t\t\t\t\tif (message.subtype === 'success') {\n\t\t\t\t\t\t\t\tlines.push(message.result);\n\t\t\t\t\t\t\t\tresultMessage = message;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow new RecoverableError('Claude sdk error', {\n\t\t\t\t\t\t\t\t\tcause: [message.stop_reason, message.terminal_reason, ...message.errors].join(\n\t\t\t\t\t\t\t\t\t\t',',\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t// A failed result still reports what the turn spent.\n\t\t\t\t\t\t\t\t\ttokens: toTokens(message.usage),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'system':\n\t\t\t\t\t\t\tthis.handleSystemMessage(message);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// Known messages with nothing to narrate or report.\n\t\t\t\t\t\tcase 'stream_event':\n\t\t\t\t\t\tcase 'tool_progress':\n\t\t\t\t\t\tcase 'tool_use_summary':\n\t\t\t\t\t\tcase 'auth_status':\n\t\t\t\t\t\tcase 'rate_limit_event':\n\t\t\t\t\t\tcase 'prompt_suggestion':\n\t\t\t\t\t\tcase 'conversation_reset':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t// `never` breaks the build when an SDK upgrade adds a message type; the\n\t\t\t\t\t\t\t// warning covers a CLI binary that is newer than the types.\n\t\t\t\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude message type');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow classifyLocalFailure(error, 'Claude failed while mapping progress');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsignal.throwIfAborted();\n\n\t\t\tif (!resultMessage) {\n\t\t\t\t// The turn's work stands; only its accounting is missing.\n\t\t\t\tthis.warn('Claude ended a turn without a result message; its usage is unknown');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// A failed result reports the turn's usage itself.\n\t\t\tconst reported =\n\t\t\t\t(error instanceof RecoverableError || error instanceof UnrecoverableError) &&\n\t\t\t\terror.tokens !== undefined;\n\t\t\tthrow answered && !reported ? withSpentTokens(error, undefined, true) : error;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: lines.join('\\n'),\n\t\t\ttokens: resultMessage && toTokens(resultMessage.usage),\n\t\t\t// Measured here, like the other engines, so it exists even without a result message.\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n\n\tprivate handleSystemMessage(message: SDKSystemMessage): void {\n\t\tswitch (message.subtype) {\n\t\t\t// Failures the SDK handled without failing the turn: only a warning makes them visible.\n\t\t\tcase 'api_retry':\n\t\t\tcase 'model_refusal_fallback':\n\t\t\tcase 'model_refusal_no_fallback':\n\t\t\tcase 'permission_denied':\n\t\t\tcase 'mirror_error':\n\t\t\t\tthis.warn(message, 'Claude reported a failure without failing the turn');\n\t\t\t\treturn;\n\t\t\t// Known messages with nothing to narrate or report.\n\t\t\tcase 'init':\n\t\t\tcase 'compact_boundary':\n\t\t\tcase 'status':\n\t\t\tcase 'control_request_progress':\n\t\t\tcase 'local_command_output':\n\t\t\tcase 'hook_started':\n\t\t\tcase 'hook_progress':\n\t\t\tcase 'hook_response':\n\t\t\tcase 'plugin_install':\n\t\t\tcase 'task_notification':\n\t\t\tcase 'task_started':\n\t\t\tcase 'task_updated':\n\t\t\tcase 'task_progress':\n\t\t\tcase 'background_tasks_changed':\n\t\t\tcase 'thinking_tokens':\n\t\t\tcase 'session_state_changed':\n\t\t\tcase 'worker_shutting_down':\n\t\t\tcase 'commands_changed':\n\t\t\tcase 'notification':\n\t\t\tcase 'files_persisted':\n\t\t\tcase 'memory_recall':\n\t\t\tcase 'elicitation_complete':\n\t\t\tcase 'informational':\n\t\t\t\treturn;\n\t\t\tdefault: {\n\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude system message');\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleAssistantMessage(\n\t\tmessage: SDKAssistantMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tfor (const block of message.message.content) {\n\t\t\tswitch (block.type) {\n\t\t\t\tcase 'text':\n\t\t\t\t\temitProgress(callback, { type: 'agentMessage', message: block.text });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'thinking':\n\t\t\t\t\temitProgress(callback, { type: 'reasoning', message: block.thinking });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'tool_use':\n\t\t\t\tcase 'server_tool_use':\n\t\t\t\tcase 'mcp_tool_use': {\n\t\t\t\t\tconst input = asRecord(block.input);\n\t\t\t\t\tif (input) {\n\t\t\t\t\t\tpendingTools.set(block.id, {\n\t\t\t\t\t\t\tname: block.name === 'web_search' ? 'WebSearch' : block.name,\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t...('server_name' in block && typeof block.server_name === 'string'\n\t\t\t\t\t\t\t\t? { server: block.server_name }\n\t\t\t\t\t\t\t\t: parseMcpServer(block.name)),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'web_search_tool_result':\n\t\t\t\tcase 'web_fetch_tool_result':\n\t\t\t\tcase 'advisor_tool_result':\n\t\t\t\tcase 'code_execution_tool_result':\n\t\t\t\tcase 'bash_code_execution_tool_result':\n\t\t\t\tcase 'text_editor_code_execution_tool_result':\n\t\t\t\tcase 'tool_search_tool_result':\n\t\t\t\tcase 'mcp_tool_result':\n\t\t\t\t\tthis.handleCompletedTool(block, pendingTools, callback);\n\t\t\t\t\tbreak;\n\t\t\t\t// Known blocks with nothing to narrate.\n\t\t\t\tcase 'redacted_thinking':\n\t\t\t\tcase 'container_upload':\n\t\t\t\tcase 'compaction':\n\t\t\t\tcase 'fallback':\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {\n\t\t\t\t\tconst unknownBlock: never = block;\n\t\t\t\t\tthis.warn(unknownBlock, 'Unknown Claude content block');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleUserMessage(\n\t\tmessage: SDKUserMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tif (!Array.isArray(message.message.content)) return;\n\n\t\tfor (const block of message.message.content) {\n\t\t\tthis.handleCompletedTool(block, pendingTools, callback, message.tool_use_result);\n\t\t}\n\t}\n\n\tprivate handleCompletedTool(\n\t\tblock: unknown,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t\toutput?: unknown,\n\t): void {\n\t\tconst id = toolResultId(block);\n\t\tif (!id) return;\n\n\t\tconst tool = pendingTools.get(id);\n\t\tif (!tool) return;\n\n\t\tpendingTools.delete(id);\n\t\tconst result = toolResultBlock(block);\n\t\tif (!result) return;\n\n\t\tconst description = describeCompletedTool(tool, result, output ?? result.content);\n\t\tif (description) emitProgress(callback, description);\n\t}\n\n\tprivate warn(...args: unknown[]): void {\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tthis.logger.warn(...args);\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'Claude logger failed while reporting progress',\n\t\t);\n\t}\n}\n\nfunction parseMcpServer(name: string): { server: string } | undefined {\n\tif (!name.startsWith('mcp__')) return undefined;\n\n\tconst server = name.slice('mcp__'.length).split('__')[0];\n\treturn server ? { server } : undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"claudeAgent.js","sourceRoot":"","sources":["../../../../../src/engines/claude/infrastructure/model/claudeAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@anthropic-ai/claude-agent-sdk';\nimport type {\n\tNonNullableUsage,\n\tEffortLevel,\n\tQuery,\n\tSDKAssistantMessage,\n\tSDKMessage,\n\tSDKResultSuccess,\n\tSDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\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\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '#src/shared/domain/errors';\nimport {\n\tclassifiedProviderStream,\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\ttreatErrors,\n} from '#src/shared/domain/providerFailure';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport type { Tokens } from '#src/shared/domain/tokens';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport { claudeModelIds } from '#src/llm/infrastructure/claudeModelIds';\n\n// The SDK types `model` as a plain string, so this list is maintained by hand. Each is sent as\n// the ID `claudeModelIds` pins, not as the alias, which the Agent SDK would resolve its own way.\nexport const claudeModels = [\n\t'haiku',\n\t'sonnet',\n\t'opus',\n\t'fable',\n] as const satisfies readonly (keyof typeof claudeModelIds)[];\nexport type ClaudeModel = (typeof claudeModels)[number];\n\nexport const claudeReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n] as const satisfies readonly EffortLevel[];\nexport type ClaudeReasoningEffort = (typeof claudeReasoningEfforts)[number];\n\ntype SDKSystemMessage = Extract<SDKMessage, { type: 'system' }>;\n\ninterface PendingTool {\n\tname: string;\n\tinput: Record<string, unknown>;\n\tserver?: string;\n}\n\ninterface ToolResultBlock {\n\ttype: string;\n\ttool_use_id: string;\n\tis_error?: boolean;\n\tcontent?: unknown;\n}\n\n// Claude reports its cache counters apart from input_tokens already.\nfunction toTokens(usage: NonNullableUsage): Tokens {\n\treturn {\n\t\tinputTokens: usage.input_tokens,\n\t\treadCacheTokens: usage.cache_read_input_tokens,\n\t\twrittenCacheTokens: usage.cache_creation_input_tokens,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\nfunction emitProgress(callback: Callback, event: ProgressEvent): void {\n\ttry {\n\t\tcallback(event);\n\t} catch (error) {\n\t\tthrow classifyHostFailure(error, 'Claude progress callback failed');\n\t}\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n\treturn typeof value === 'string' ? value : undefined;\n}\n\nfunction toolResultBlock(value: unknown): ToolResultBlock | undefined {\n\tconst block = asRecord(value);\n\tif (!block || typeof block.type !== 'string' || typeof block.tool_use_id !== 'string') {\n\t\treturn undefined;\n\t}\n\n\treturn block as unknown as ToolResultBlock;\n}\n\nfunction toolResultId(value: unknown): string | undefined {\n\treturn toolResultBlock(value)?.tool_use_id;\n}\n\nfunction fileChange(\n\tname: 'Edit' | 'Write',\n\ttool: PendingTool,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tconst inputPath = stringValue(tool.input.file_path);\n\tconst outputPath = stringValue(asRecord(output)?.filePath);\n\tconst path = outputPath ?? inputPath;\n\tif (!path) return undefined;\n\n\tconst kind =\n\t\tname === 'Write' && stringValue(asRecord(output)?.type) === 'create' ? 'add' : 'update';\n\treturn { type: 'fileChange', changes: [{ path, kind }] };\n}\n\nfunction todoList(tool: PendingTool): ProgressEvent | undefined {\n\tif (!Array.isArray(tool.input.todos)) return undefined;\n\n\tconst items = tool.input.todos.flatMap(todo => {\n\t\tconst item = asRecord(todo);\n\t\tconst text = stringValue(item?.content);\n\t\tconst status = stringValue(item?.status);\n\t\treturn text && status ? [{ text, completed: status === 'completed' }] : [];\n\t});\n\n\treturn { type: 'todoList', items };\n}\n\nfunction mcpTool(tool: PendingTool, result: ToolResultBlock): ProgressEvent | undefined {\n\tconst server = tool.server;\n\tconst toolName = tool.name.startsWith('mcp__')\n\t\t? tool.name.slice('mcp__'.length).split('__').slice(1).join('__')\n\t\t: tool.name;\n\tif (!server || !toolName) return undefined;\n\n\treturn {\n\t\ttype: 'mcpTool',\n\t\tserver,\n\t\ttool: toolName,\n\t\tstatus: result.is_error ? 'failed' : 'completed',\n\t};\n}\n\n// Tools without narration (Read, Grep, Task, ...) are a presentation choice, not an unknown:\n// the tool set is open-ended, so warning here would only produce noise.\nfunction describeCompletedTool(\n\ttool: PendingTool,\n\tresult: ToolResultBlock,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tif (tool.name === 'Bash') {\n\t\tconst exitCode = asRecord(output)?.exitCode ?? asRecord(output)?.exit_code;\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: stringValue(tool.input.command) ?? '',\n\t\t\t...(typeof exitCode === 'number' ? { exitCode } : {}),\n\t\t};\n\t}\n\n\tif (tool.name === 'WebSearch') {\n\t\tconst query = stringValue(tool.input.query);\n\t\treturn query ? { type: 'search', query } : undefined;\n\t}\n\n\tif (tool.name === 'Edit' || tool.name === 'Write') {\n\t\treturn result.is_error ? undefined : fileChange(tool.name, tool, output);\n\t}\n\n\tif (tool.name === 'TodoWrite') {\n\t\treturn result.is_error ? undefined : todoList(tool);\n\t}\n\n\tif (tool.name.startsWith('mcp__') || tool.server) {\n\t\treturn mcpTool(tool, result);\n\t}\n\n\treturn undefined;\n}\n\nexport class ClaudeAgent implements Agent {\n\tprivate model: ClaudeModel;\n\tprivate autoApprove: boolean;\n\tprivate reasoningEffort: ClaudeReasoningEffort;\n\tprivate sessionId?: string;\n\tprivate logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Claude supports, so it validates them instead of trusting the caller.\n\tconstructor({\n\t\tmodel,\n\t\tautoApprove = false,\n\t\treasoningEffort = 'high',\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\tautoApprove?: boolean;\n\t\treasoningEffort?: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\tif (!isOneOf(claudeModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Claude model; expected one of: ${claudeModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (!isOneOf(claudeReasoningEfforts, reasoningEffort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${reasoningEffort}\" is not a Claude reasoning effort; expected one of: ${claudeReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.model = model;\n\t\tthis.autoApprove = autoApprove;\n\t\tthis.reasoningEffort = reasoningEffort;\n\t\tthis.logger = logger;\n\t}\n\n\tasync run(\n\t\tprompt: string,\n\t\t{ signal, onProgress: callback = ignoreProgress }: RunOptions,\n\t): Promise<AgentResponse> {\n\t\tsignal.throwIfAborted();\n\t\tconst start = Date.now();\n\n\t\tlet stream: Query;\n\n\t\ttry {\n\t\t\tstream = query({\n\t\t\t\tprompt,\n\t\t\t\toptions: {\n\t\t\t\t\teffort: this.reasoningEffort,\n\t\t\t\t\tmodel: claudeModelIds[this.model],\n\t\t\t\t\tmaxTurns: 3,\n\t\t\t\t\tcwd: process.cwd(),\n\t\t\t\t\tresume: this.sessionId,\n\t\t\t\t\t...(this.autoApprove\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tpermissionMode: 'bypassPermissions' as const,\n\t\t\t\t\t\t\t\tallowDangerouslySkipPermissions: true,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'Claude refused the request');\n\t\t}\n\n\t\tconst closeStream = () => {\n\t\t\tstream.close();\n\t\t};\n\t\tsignal.addEventListener('abort', closeStream, { once: true });\n\n\t\ttry {\n\t\t\treturn await this.parseResponse(stream, signal, callback, start);\n\t\t} finally {\n\t\t\tsignal.removeEventListener('abort', closeStream);\n\t\t}\n\t}\n\n\tprivate async parseResponse(\n\t\tstream: Query,\n\t\tsignal: AbortSignal,\n\t\tcallback: Callback,\n\t\tstart: number,\n\t): Promise<AgentResponse> {\n\t\tconst lines: string[] = [];\n\t\tlet resultMessage: SDKResultSuccess | undefined;\n\t\tconst pendingTools = new Map<string, PendingTool>();\n\n\t\t// Once Claude sent an assistant message, the provider answered: a failure after that\n\t\t// without usage leaves the run's count unknown, unlike one that never got an answer.\n\t\tlet answered = false;\n\n\t\ttry {\n\t\t\tconst messages = classifiedProviderStream(stream, 'Claude stream ended unexpectedly');\n\n\t\t\tfor await (const message of messages) {\n\t\t\t\tthis.sessionId ??= message.session_id;\n\n\t\t\t\ttry {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'assistant':\n\t\t\t\t\t\t\tanswered = true;\n\t\t\t\t\t\t\tthis.handleAssistantMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'user':\n\t\t\t\t\t\t\tthis.handleUserMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'result':\n\t\t\t\t\t\t\tif (message.subtype === 'success') {\n\t\t\t\t\t\t\t\tlines.push(message.result);\n\t\t\t\t\t\t\t\tresultMessage = message;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow new RecoverableError('Claude sdk error', {\n\t\t\t\t\t\t\t\t\tcause: [message.stop_reason, message.terminal_reason, ...message.errors].join(\n\t\t\t\t\t\t\t\t\t\t',',\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t// A failed result still reports what the turn spent.\n\t\t\t\t\t\t\t\t\ttokens: toTokens(message.usage),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'system':\n\t\t\t\t\t\t\tthis.handleSystemMessage(message);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// Known messages with nothing to narrate or report.\n\t\t\t\t\t\tcase 'stream_event':\n\t\t\t\t\t\tcase 'tool_progress':\n\t\t\t\t\t\tcase 'tool_use_summary':\n\t\t\t\t\t\tcase 'auth_status':\n\t\t\t\t\t\tcase 'rate_limit_event':\n\t\t\t\t\t\tcase 'prompt_suggestion':\n\t\t\t\t\t\tcase 'conversation_reset':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t// `never` breaks the build when an SDK upgrade adds a message type; the\n\t\t\t\t\t\t\t// warning covers a CLI binary that is newer than the types.\n\t\t\t\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude message type');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow classifyLocalFailure(error, 'Claude failed while mapping progress');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsignal.throwIfAborted();\n\n\t\t\tif (!resultMessage) {\n\t\t\t\t// The turn's work stands; only its accounting is missing.\n\t\t\t\tthis.warn('Claude ended a turn without a result message; its usage is unknown');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// A failed result reports the turn's usage itself.\n\t\t\tconst reported =\n\t\t\t\t(error instanceof RecoverableError || error instanceof UnrecoverableError) &&\n\t\t\t\terror.tokens !== undefined;\n\t\t\tthrow answered && !reported ? withSpentTokens(error, undefined, true) : error;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: lines.join('\\n'),\n\t\t\ttokens: resultMessage && toTokens(resultMessage.usage),\n\t\t\t// Measured here, like the other engines, so it exists even without a result message.\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n\n\tprivate handleSystemMessage(message: SDKSystemMessage): void {\n\t\tswitch (message.subtype) {\n\t\t\t// Failures the SDK handled without failing the turn: only a warning makes them visible.\n\t\t\tcase 'api_retry':\n\t\t\tcase 'model_refusal_fallback':\n\t\t\tcase 'model_refusal_no_fallback':\n\t\t\tcase 'permission_denied':\n\t\t\tcase 'mirror_error':\n\t\t\t\tthis.warn(message, 'Claude reported a failure without failing the turn');\n\t\t\t\treturn;\n\t\t\t// Known messages with nothing to narrate or report.\n\t\t\tcase 'init':\n\t\t\tcase 'compact_boundary':\n\t\t\tcase 'status':\n\t\t\tcase 'control_request_progress':\n\t\t\tcase 'local_command_output':\n\t\t\tcase 'hook_started':\n\t\t\tcase 'hook_progress':\n\t\t\tcase 'hook_response':\n\t\t\tcase 'plugin_install':\n\t\t\tcase 'task_notification':\n\t\t\tcase 'task_started':\n\t\t\tcase 'task_updated':\n\t\t\tcase 'task_progress':\n\t\t\tcase 'background_tasks_changed':\n\t\t\tcase 'thinking_tokens':\n\t\t\tcase 'session_state_changed':\n\t\t\tcase 'worker_shutting_down':\n\t\t\tcase 'commands_changed':\n\t\t\tcase 'notification':\n\t\t\tcase 'files_persisted':\n\t\t\tcase 'memory_recall':\n\t\t\tcase 'elicitation_complete':\n\t\t\tcase 'informational':\n\t\t\t\treturn;\n\t\t\tdefault: {\n\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude system message');\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleAssistantMessage(\n\t\tmessage: SDKAssistantMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tfor (const block of message.message.content) {\n\t\t\tswitch (block.type) {\n\t\t\t\tcase 'text':\n\t\t\t\t\temitProgress(callback, { type: 'agentMessage', message: block.text });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'thinking':\n\t\t\t\t\temitProgress(callback, { type: 'reasoning', message: block.thinking });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'tool_use':\n\t\t\t\tcase 'server_tool_use':\n\t\t\t\tcase 'mcp_tool_use': {\n\t\t\t\t\tconst input = asRecord(block.input);\n\t\t\t\t\tif (input) {\n\t\t\t\t\t\tpendingTools.set(block.id, {\n\t\t\t\t\t\t\tname: block.name === 'web_search' ? 'WebSearch' : block.name,\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t...('server_name' in block && typeof block.server_name === 'string'\n\t\t\t\t\t\t\t\t? { server: block.server_name }\n\t\t\t\t\t\t\t\t: parseMcpServer(block.name)),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'web_search_tool_result':\n\t\t\t\tcase 'web_fetch_tool_result':\n\t\t\t\tcase 'advisor_tool_result':\n\t\t\t\tcase 'code_execution_tool_result':\n\t\t\t\tcase 'bash_code_execution_tool_result':\n\t\t\t\tcase 'text_editor_code_execution_tool_result':\n\t\t\t\tcase 'tool_search_tool_result':\n\t\t\t\tcase 'mcp_tool_result':\n\t\t\t\t\tthis.handleCompletedTool(block, pendingTools, callback);\n\t\t\t\t\tbreak;\n\t\t\t\t// Known blocks with nothing to narrate.\n\t\t\t\tcase 'redacted_thinking':\n\t\t\t\tcase 'container_upload':\n\t\t\t\tcase 'compaction':\n\t\t\t\tcase 'fallback':\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {\n\t\t\t\t\tconst unknownBlock: never = block;\n\t\t\t\t\tthis.warn(unknownBlock, 'Unknown Claude content block');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleUserMessage(\n\t\tmessage: SDKUserMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tif (!Array.isArray(message.message.content)) return;\n\n\t\tfor (const block of message.message.content) {\n\t\t\tthis.handleCompletedTool(block, pendingTools, callback, message.tool_use_result);\n\t\t}\n\t}\n\n\tprivate handleCompletedTool(\n\t\tblock: unknown,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t\toutput?: unknown,\n\t): void {\n\t\tconst id = toolResultId(block);\n\t\tif (!id) return;\n\n\t\tconst tool = pendingTools.get(id);\n\t\tif (!tool) return;\n\n\t\tpendingTools.delete(id);\n\t\tconst result = toolResultBlock(block);\n\t\tif (!result) return;\n\n\t\tconst description = describeCompletedTool(tool, result, output ?? result.content);\n\t\tif (description) emitProgress(callback, description);\n\t}\n\n\tprivate warn(...args: unknown[]): void {\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tthis.logger.warn(...args);\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'Claude logger failed while reporting progress',\n\t\t);\n\t}\n}\n\nfunction parseMcpServer(name: string): { server: string } | undefined {\n\tif (!name.startsWith('mcp__')) return undefined;\n\n\tconst server = name.slice('mcp__'.length).split('__')[0];\n\treturn server ? { server } : undefined;\n}\n"]}
|
|
@@ -79,7 +79,7 @@ const orchestratorRoles = {
|
|
|
79
79
|
},
|
|
80
80
|
anthropic: {
|
|
81
81
|
planner: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },
|
|
82
|
-
executor: { provider: 'anthropic', model: '
|
|
82
|
+
executor: { provider: 'anthropic', model: 'haiku', reasoningEffort: 'xhigh' },
|
|
83
83
|
reviewer: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },
|
|
84
84
|
},
|
|
85
85
|
openai: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentFactory.js","sourceRoot":"","sources":["../../../src/factory/infrastructure/agentFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from '#src/agent/domain/agent';\nimport { InvalidAgentConfigError } from '#src/shared/domain/errors';\nimport {\n\tClaudeAgent,\n\tclaudeModels,\n\tclaudeReasoningEfforts,\n} from '#src/engines/claude/infrastructure/model/claudeAgent';\nimport {\n\tCodexAgent,\n\tcodexModels,\n\tcodexReasoningEfforts,\n} from '#src/engines/codex/infrastructure/model/codexAgent';\nimport { InstructedAgent } from '#src/orchestration/domain/model/instructedAgent';\nimport {\n\texecutorInstructions,\n\tOrchestratorAgent,\n\tplannerInstructions,\n\treviewerInstructions,\n} from '#src/orchestration/domain/model/orchestratorAgent';\nimport { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';\nimport { RetryingAgent } from '#src/retry/domain/model/retryingAgent';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { Logger } from '#src/shared/infrastructure/logger';\nimport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './types.ts';\n\nexport function isAgentProvider(value: string): value is AgentProvider {\n\treturn isOneOf(agentProviders, value);\n}\n\n/** The models each provider's Agent SDK accepts. */\nexport const agentModels = {\n\tanthropic: claudeModels,\n\topenai: codexModels,\n} as const satisfies Readonly<Record<AgentProvider, readonly AgentModel[]>>;\n\n/** The reasoning efforts each provider's Agent SDK accepts. */\nexport const agentReasoningEfforts = {\n\tanthropic: claudeReasoningEfforts,\n\topenai: codexReasoningEfforts,\n} as const satisfies Readonly<Record<AgentProvider, readonly ReasoningEffort[]>>;\n\n/** Narrows a model to one accepted by the selected provider's Agent SDK. */\nexport function isModelOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof agentModels)[Provider][number] {\n\treturn isOneOf(agentModels[provider], value);\n}\n\n/** Narrows a reasoning effort to one accepted by the selected provider's Agent SDK. */\nexport function isReasoningEffortOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof agentReasoningEfforts)[Provider][number] {\n\treturn isOneOf(agentReasoningEfforts[provider], value);\n}\n\nexport interface CreateAgentOptions {\n\t/** Defaults to `'opus'` on Anthropic and `'gpt-5.6-sol'` on OpenAI. */\n\tmodel?: AgentModel;\n\t/** Defaults to `'high'`. */\n\treasoningEffort?: ReasoningEffort;\n\t/** Maps to the provider's permission-bypass mode. Defaults to `false`. */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n}\n\nconst defaultModels = {\n\tanthropic: 'opus',\n\topenai: 'gpt-5.6-sol',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\n/**\n * Builds the agent for a provider on its Agent SDK — Claude Code for Anthropic, Codex for\n * OpenAI — already wrapped in the harness's retry policy.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, or a model or reasoning effort\n * the provider does not support.\n * @throws {UnrecoverableError} when Codex cannot be set up, for example because its CLI binary\n * is missing.\n */\nexport function createAgent(\n\tprovider: AgentProvider,\n\t{ model, reasoningEffort, autoApprove, logger = new Logger() }: CreateAgentOptions = {},\n): Agent {\n\tlet engine: Agent;\n\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\t\tengine = new ClaudeAgent({\n\t\t\t\tmodel: model ?? defaultModels.anthropic,\n\t\t\t\treasoningEffort,\n\t\t\t\tautoApprove,\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tbreak;\n\t\tcase 'openai':\n\t\t\tengine = new CodexAgent({\n\t\t\t\tmodel: model ?? defaultModels.openai,\n\t\t\t\treasoningEffort,\n\t\t\t\tautoApprove,\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\t// Reachable from untyped input that skipped `isAgentProvider`.\n\t\t\tconst unknownProvider: never = provider;\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${String(unknownProvider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn new RetryingAgent({ inner: engine, logger });\n}\n\nexport interface Role {\n\tprovider: AgentProvider;\n\tmodel: AgentModel;\n\treasoningEffort: ReasoningEffort;\n}\n\n// A stronger model plans and reviews; a cheaper one executes the plan. Every model and effort\n// here is one both the Agent SDKs and the model APIs accept, so either path can run a role.\nconst orchestratorRoles = {\n\tdefault: {\n\t\tplanner: { provider: 'openai', model: 'gpt-5.6-sol', reasoningEffort: 'high' },\n\t\texecutor: { provider: 'openai', model: 'gpt-5.6-luna', reasoningEffort: 'xhigh' },\n\t\treviewer: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },\n\t},\n\tanthropic: {\n\t\tplanner: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },\n\t\texecutor: { provider: 'anthropic', model: 'sonnet', reasoningEffort: 'xhigh' },\n\t\treviewer: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },\n\t},\n\topenai: {\n\t\tplanner: { provider: 'openai', model: 'gpt-5.6-sol', reasoningEffort: 'high' },\n\t\texecutor: { provider: 'openai', model: 'gpt-5.6-luna', reasoningEffort: 'xhigh' },\n\t\treviewer: { provider: 'openai', model: 'gpt-5.6-sol', reasoningEffort: 'high' },\n\t},\n} as const satisfies Record<\n\tAgentProvider | 'default',\n\tRecord<'planner' | 'executor' | 'reviewer', Role>\n>;\n\n/**\n * The roles for `provider`, or the default mix without one.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider.\n */\nexport function orchestratorRolesFor(\n\tprovider: AgentProvider | undefined,\n): Record<'planner' | 'executor' | 'reviewer', Role> {\n\tif (provider !== undefined && !isAgentProvider(provider)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t\t);\n\t}\n\n\treturn orchestratorRoles[provider ?? 'default'];\n}\n\n/**\n * Builds the planner → executor → reviewer workflow, each role an agent from `createAgent`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider.\n * @throws {UnrecoverableError} when an OpenAI role cannot be set up, for example because the\n * Codex CLI binary is missing.\n */\nexport function createOrchestrator({\n\tprovider,\n\tautoApprove,\n\tsystemPrompts = {},\n\tlogger = new Logger(),\n}: CreateOrchestratorOptions = {}): Agent {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst agentFor = ({ provider, model, reasoningEffort }: Role, instructions: string) =>\n\t\tnew InstructedAgent({\n\t\t\tinner: createAgent(provider, { model, reasoningEffort, autoApprove, logger }),\n\t\t\tinstructions,\n\t\t});\n\n\treturn new OrchestratorAgent({\n\t\tplannerAgent: agentFor(roles.planner, systemPrompts.planner ?? plannerInstructions),\n\t\texecutorAgent: agentFor(roles.executor, systemPrompts.executor ?? executorInstructions),\n\t\treviewerAgent: agentFor(roles.reviewer, systemPrompts.reviewer ?? reviewerInstructions),\n\t\treviewerDecisionValidator: new ReviewerDecisionValidator(),\n\t\tlogger,\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agentFactory.js","sourceRoot":"","sources":["../../../src/factory/infrastructure/agentFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from '#src/agent/domain/agent';\nimport { InvalidAgentConfigError } from '#src/shared/domain/errors';\nimport {\n\tClaudeAgent,\n\tclaudeModels,\n\tclaudeReasoningEfforts,\n} from '#src/engines/claude/infrastructure/model/claudeAgent';\nimport {\n\tCodexAgent,\n\tcodexModels,\n\tcodexReasoningEfforts,\n} from '#src/engines/codex/infrastructure/model/codexAgent';\nimport { InstructedAgent } from '#src/orchestration/domain/model/instructedAgent';\nimport {\n\texecutorInstructions,\n\tOrchestratorAgent,\n\tplannerInstructions,\n\treviewerInstructions,\n} from '#src/orchestration/domain/model/orchestratorAgent';\nimport { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';\nimport { RetryingAgent } from '#src/retry/domain/model/retryingAgent';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { Logger } from '#src/shared/infrastructure/logger';\nimport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './types.ts';\n\nexport function isAgentProvider(value: string): value is AgentProvider {\n\treturn isOneOf(agentProviders, value);\n}\n\n/** The models each provider's Agent SDK accepts. */\nexport const agentModels = {\n\tanthropic: claudeModels,\n\topenai: codexModels,\n} as const satisfies Readonly<Record<AgentProvider, readonly AgentModel[]>>;\n\n/** The reasoning efforts each provider's Agent SDK accepts. */\nexport const agentReasoningEfforts = {\n\tanthropic: claudeReasoningEfforts,\n\topenai: codexReasoningEfforts,\n} as const satisfies Readonly<Record<AgentProvider, readonly ReasoningEffort[]>>;\n\n/** Narrows a model to one accepted by the selected provider's Agent SDK. */\nexport function isModelOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof agentModels)[Provider][number] {\n\treturn isOneOf(agentModels[provider], value);\n}\n\n/** Narrows a reasoning effort to one accepted by the selected provider's Agent SDK. */\nexport function isReasoningEffortOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof agentReasoningEfforts)[Provider][number] {\n\treturn isOneOf(agentReasoningEfforts[provider], value);\n}\n\nexport interface CreateAgentOptions {\n\t/** Defaults to `'opus'` on Anthropic and `'gpt-5.6-sol'` on OpenAI. */\n\tmodel?: AgentModel;\n\t/** Defaults to `'high'`. */\n\treasoningEffort?: ReasoningEffort;\n\t/** Maps to the provider's permission-bypass mode. Defaults to `false`. */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n}\n\nconst defaultModels = {\n\tanthropic: 'opus',\n\topenai: 'gpt-5.6-sol',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\n/**\n * Builds the agent for a provider on its Agent SDK — Claude Code for Anthropic, Codex for\n * OpenAI — already wrapped in the harness's retry policy.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, or a model or reasoning effort\n * the provider does not support.\n * @throws {UnrecoverableError} when Codex cannot be set up, for example because its CLI binary\n * is missing.\n */\nexport function createAgent(\n\tprovider: AgentProvider,\n\t{ model, reasoningEffort, autoApprove, logger = new Logger() }: CreateAgentOptions = {},\n): Agent {\n\tlet engine: Agent;\n\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\t\tengine = new ClaudeAgent({\n\t\t\t\tmodel: model ?? defaultModels.anthropic,\n\t\t\t\treasoningEffort,\n\t\t\t\tautoApprove,\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tbreak;\n\t\tcase 'openai':\n\t\t\tengine = new CodexAgent({\n\t\t\t\tmodel: model ?? defaultModels.openai,\n\t\t\t\treasoningEffort,\n\t\t\t\tautoApprove,\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\t// Reachable from untyped input that skipped `isAgentProvider`.\n\t\t\tconst unknownProvider: never = provider;\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${String(unknownProvider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn new RetryingAgent({ inner: engine, logger });\n}\n\nexport interface Role {\n\tprovider: AgentProvider;\n\tmodel: AgentModel;\n\treasoningEffort: ReasoningEffort;\n}\n\n// A stronger model plans and reviews; a cheaper one executes the plan. Every model and effort\n// here is one both the Agent SDKs and the model APIs accept, so either path can run a role.\nconst orchestratorRoles = {\n\tdefault: {\n\t\tplanner: { provider: 'openai', model: 'gpt-5.6-sol', reasoningEffort: 'high' },\n\t\texecutor: { provider: 'openai', model: 'gpt-5.6-luna', reasoningEffort: 'xhigh' },\n\t\treviewer: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },\n\t},\n\tanthropic: {\n\t\tplanner: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },\n\t\texecutor: { provider: 'anthropic', model: 'haiku', reasoningEffort: 'xhigh' },\n\t\treviewer: { provider: 'anthropic', model: 'opus', reasoningEffort: 'high' },\n\t},\n\topenai: {\n\t\tplanner: { provider: 'openai', model: 'gpt-5.6-sol', reasoningEffort: 'high' },\n\t\texecutor: { provider: 'openai', model: 'gpt-5.6-luna', reasoningEffort: 'xhigh' },\n\t\treviewer: { provider: 'openai', model: 'gpt-5.6-sol', reasoningEffort: 'high' },\n\t},\n} as const satisfies Record<\n\tAgentProvider | 'default',\n\tRecord<'planner' | 'executor' | 'reviewer', Role>\n>;\n\n/**\n * The roles for `provider`, or the default mix without one.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider.\n */\nexport function orchestratorRolesFor(\n\tprovider: AgentProvider | undefined,\n): Record<'planner' | 'executor' | 'reviewer', Role> {\n\tif (provider !== undefined && !isAgentProvider(provider)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t\t);\n\t}\n\n\treturn orchestratorRoles[provider ?? 'default'];\n}\n\n/**\n * Builds the planner → executor → reviewer workflow, each role an agent from `createAgent`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider.\n * @throws {UnrecoverableError} when an OpenAI role cannot be set up, for example because the\n * Codex CLI binary is missing.\n */\nexport function createOrchestrator({\n\tprovider,\n\tautoApprove,\n\tsystemPrompts = {},\n\tlogger = new Logger(),\n}: CreateOrchestratorOptions = {}): Agent {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst agentFor = ({ provider, model, reasoningEffort }: Role, instructions: string) =>\n\t\tnew InstructedAgent({\n\t\t\tinner: createAgent(provider, { model, reasoningEffort, autoApprove, logger }),\n\t\t\tinstructions,\n\t\t});\n\n\treturn new OrchestratorAgent({\n\t\tplannerAgent: agentFor(roles.planner, systemPrompts.planner ?? plannerInstructions),\n\t\texecutorAgent: agentFor(roles.executor, systemPrompts.executor ?? executorInstructions),\n\t\treviewerAgent: agentFor(roles.reviewer, systemPrompts.reviewer ?? reviewerInstructions),\n\t\treviewerDecisionValidator: new ReviewerDecisionValidator(),\n\t\tlogger,\n\t});\n}\n"]}
|
|
@@ -40,8 +40,8 @@ export interface CreateLLMAgentOptions {
|
|
|
40
40
|
workspace?: WorkspaceOptions;
|
|
41
41
|
/**
|
|
42
42
|
* With `workspace`, a summary of what was undone, from the provider's cheap model, in place
|
|
43
|
-
* of the undone prompts. That is Claude Haiku
|
|
44
|
-
*
|
|
43
|
+
* of the undone prompts. That is Claude Haiku 5.5 or `gpt-5.6-luna`, at high effort, and the
|
|
44
|
+
* call is billed with the run's tokens. Defaults to `true`.
|
|
45
45
|
*/
|
|
46
46
|
summarizeUndone?: boolean;
|
|
47
47
|
/**
|
|
@@ -53,7 +53,7 @@ export interface CreateLLMAgentOptions {
|
|
|
53
53
|
* The input tokens at which the provider compacts the conversation on its side: it replaces
|
|
54
54
|
* every turn before that call with its own summary, which only its model reads back. The
|
|
55
55
|
* conversation keeps every original turn. Without it, the conversation is never compacted.
|
|
56
|
-
* At least 50,000 on Anthropic
|
|
56
|
+
* At least 50,000 on Anthropic.
|
|
57
57
|
*/
|
|
58
58
|
compactAt?: number;
|
|
59
59
|
/**
|
|
@@ -103,7 +103,7 @@ function llmClientFor(provider, { model, reasoningEffort, compactAt, systemPromp
|
|
|
103
103
|
/** The provider's cheap model, for the summary of what was undone. */
|
|
104
104
|
function summarizerFor(provider, logger) {
|
|
105
105
|
return provider === 'anthropic'
|
|
106
|
-
? new ClaudeLLMClient({ model: 'haiku', systemPrompt: '', logger })
|
|
106
|
+
? new ClaudeLLMClient({ model: 'haiku', reasoningEffort: 'high', systemPrompt: '', logger })
|
|
107
107
|
: new OpenAILLMClient({
|
|
108
108
|
model: 'gpt-5.6-luna',
|
|
109
109
|
reasoningEffort: 'high',
|
|
@@ -285,10 +285,9 @@ async function readingTools(workspace, role, commands, explorer) {
|
|
|
285
285
|
}
|
|
286
286
|
const batching = '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.';
|
|
287
287
|
const exploring = '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.';
|
|
288
|
-
// Each provider's cheaper model, which only finds and reads.
|
|
289
|
-
// takes no reasoning effort.
|
|
288
|
+
// Each provider's cheaper model, which only finds and reads.
|
|
290
289
|
const explorerRoles = {
|
|
291
|
-
anthropic: { model: 'haiku' },
|
|
290
|
+
anthropic: { model: 'haiku', reasoningEffort: 'medium' },
|
|
292
291
|
openai: { model: 'gpt-5.6-luna', reasoningEffort: 'medium' },
|
|
293
292
|
};
|
|
294
293
|
const explorerSteps = 30;
|
|
@@ -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 { 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"]}
|
|
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 5.5 or `gpt-5.6-luna`, at high effort, and the\n\t * 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.\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', reasoningEffort: 'high', 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.\nconst explorerRoles = {\n\tanthropic: { model: 'haiku', reasoningEffort: 'medium' },\n\topenai: { model: 'gpt-5.6-luna', reasoningEffort: 'medium' },\n} as const satisfies Record<AgentProvider, { model: AgentModel; reasoningEffort: ReasoningEffort }>;\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"]}
|
|
@@ -5,17 +5,14 @@ import { isOneOf } from '#src/shared/domain/isOneOf';
|
|
|
5
5
|
import { MaxContextError } from "../domain/errors.js";
|
|
6
6
|
import { sentContext } from "../domain/message.js";
|
|
7
7
|
import { nativeOf } from "../domain/tool.js";
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
sonnet: 'claude-sonnet-5',
|
|
17
|
-
haiku: 'claude-haiku-4-5',
|
|
18
|
-
};
|
|
8
|
+
import { claudeModelIds } from "./claudeModelIds.js";
|
|
9
|
+
// The Messages API takes full model IDs; `claudeModelIds` pins the one each alias names.
|
|
10
|
+
export const claudeLLMModels = [
|
|
11
|
+
'opus',
|
|
12
|
+
'fable',
|
|
13
|
+
'sonnet',
|
|
14
|
+
'haiku',
|
|
15
|
+
];
|
|
19
16
|
export const claudeLLMReasoningEfforts = [
|
|
20
17
|
'low',
|
|
21
18
|
'medium',
|
|
@@ -25,8 +22,8 @@ export const claudeLLMReasoningEfforts = [
|
|
|
25
22
|
];
|
|
26
23
|
// Adaptive thinking spends from this budget too, so a hard step at a high effort can need most
|
|
27
24
|
// of it. The request is streamed so it is not bound by the SDK's ten-minute timeout, which made
|
|
28
|
-
// it refuse more than about 21,000 without a stream.
|
|
29
|
-
//
|
|
25
|
+
// it refuse more than about 21,000 without a stream. A single answer here has not needed more
|
|
26
|
+
// than 64,000, which every model writes.
|
|
30
27
|
const maxOutputTokens = 64_000;
|
|
31
28
|
// The request itself is wrong or not allowed, so sending it again cannot succeed.
|
|
32
29
|
const unrecoverableStatuses = [400, 401, 403, 404, 413, 422];
|
|
@@ -282,7 +279,6 @@ function classifyClaudeFailure(error, connected) {
|
|
|
282
279
|
export class ClaudeLLMClient {
|
|
283
280
|
client;
|
|
284
281
|
model;
|
|
285
|
-
// Missing for Haiku, which runs without thinking.
|
|
286
282
|
reasoningEffort;
|
|
287
283
|
compactAt;
|
|
288
284
|
systemPrompt;
|
|
@@ -294,21 +290,12 @@ export class ClaudeLLMClient {
|
|
|
294
290
|
if (!isOneOf(claudeLLMModels, model)) {
|
|
295
291
|
throw new InvalidAgentConfigError(`"${model}" is not a Claude API model; expected one of: ${claudeLLMModels.join(', ')}`);
|
|
296
292
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
const effort = model === 'haiku' ? undefined : (reasoningEffort ?? 'high');
|
|
301
|
-
if (effort !== undefined && !isOneOf(claudeLLMReasoningEfforts, effort)) {
|
|
293
|
+
const effort = reasoningEffort ?? 'high';
|
|
294
|
+
if (!isOneOf(claudeLLMReasoningEfforts, effort)) {
|
|
302
295
|
throw new InvalidAgentConfigError(`"${effort}" is not a Claude API reasoning effort; expected one of: ${claudeLLMReasoningEfforts.join(', ')}`);
|
|
303
296
|
}
|
|
304
|
-
if (compactAt !== undefined) {
|
|
305
|
-
|
|
306
|
-
if (model === 'haiku') {
|
|
307
|
-
throw new InvalidAgentConfigError('Claude Haiku cannot compact: leave compactAt out');
|
|
308
|
-
}
|
|
309
|
-
if (!(Number.isInteger(compactAt) && compactAt >= minCompactAt)) {
|
|
310
|
-
throw new InvalidAgentConfigError(`compactAt must be a whole number of tokens of at least ${String(minCompactAt)} on Claude, not ${String(compactAt)}`);
|
|
311
|
-
}
|
|
297
|
+
if (compactAt !== undefined && !(Number.isInteger(compactAt) && compactAt >= minCompactAt)) {
|
|
298
|
+
throw new InvalidAgentConfigError(`compactAt must be a whole number of tokens of at least ${String(minCompactAt)} on Claude, not ${String(compactAt)}`);
|
|
312
299
|
}
|
|
313
300
|
try {
|
|
314
301
|
// The SDK's default retries stay on, as OpenAI's do. See "The provider SDKs keep their
|
|
@@ -322,7 +309,7 @@ export class ClaudeLLMClient {
|
|
|
322
309
|
cause: describeFailure(error),
|
|
323
310
|
});
|
|
324
311
|
}
|
|
325
|
-
this.model =
|
|
312
|
+
this.model = claudeModelIds[model];
|
|
326
313
|
this.reasoningEffort = effort;
|
|
327
314
|
this.compactAt = compactAt;
|
|
328
315
|
this.systemPrompt = systemPrompt;
|
|
@@ -351,11 +338,8 @@ export class ClaudeLLMClient {
|
|
|
351
338
|
messages: sentContext(context, claudeSource).flatMap(toClaudeInput),
|
|
352
339
|
// Left out when empty, so a request without tools stays as it always was.
|
|
353
340
|
...(tools.length > 0 && { tools: tools.map(toClaudeTool) }),
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
thinking: { type: 'adaptive', display: 'summarized' },
|
|
357
|
-
output_config: { effort: this.reasoningEffort },
|
|
358
|
-
}),
|
|
341
|
+
thinking: { type: 'adaptive', display: 'summarized' },
|
|
342
|
+
output_config: { effort: this.reasoningEffort },
|
|
359
343
|
// Anthropic caches only on request. This marks the last block, so the next call
|
|
360
344
|
// reads everything before it from the cache instead of paying for it again.
|
|
361
345
|
cache_control: { type: 'ephemeral' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeLLMClient.js","sourceRoot":"","sources":["../../../src/llm/infrastructure/claudeLLMClient.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic, { AnthropicError, APIError } from '@anthropic-ai/sdk';\nimport type { BetaMessageStream } from '@anthropic-ai/sdk/lib/BetaMessageStream';\n// The beta surface, for compaction: without its beta header, a request is the stable one.\nimport type {\n\tBetaCompactionBlockParam as CompactionBlockParam,\n\tBetaContentBlock as ContentBlock,\n\tBetaContentBlockParam as ContentBlockParam,\n\tBetaMessage as AnthropicMessage,\n\tBetaMessageParam as MessageParam,\n\tBetaOutputConfig as OutputConfig,\n\tBetaRedactedThinkingBlockParam as RedactedThinkingBlockParam,\n\tBetaThinkingBlockParam as ThinkingBlockParam,\n\tBetaTool as ClaudeTool,\n\tBetaToolTextEditor20250728 as ToolTextEditor20250728,\n\tBetaUsage as Usage,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages';\nimport {\n\tInvalidAgentConfigError,\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 { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport type { Tokens } from '#src/shared/domain/tokens';\nimport { MaxContextError } from '../domain/errors.ts';\nimport type { LLMClient, LLMResponse, StopReason } from '../domain/llm.ts';\nimport { type Message, type MessagePart, sentContext } from '../domain/message.ts';\nimport { type NativeTool, nativeOf, type ToolDefinition } from '../domain/tool.ts';\n\n// The Messages API takes full model IDs. Callers name a model by the Agent SDK's alias, so both\n// paths share one vocabulary; this table pins the ID each alias means here, and moves by hand\n// when Anthropic releases a newer model. Haiku runs without thinking: it has no adaptive thinking\n// and takes no reasoning effort, and it is here for short, simple calls such as a summary.\nexport const claudeLLMModels = ['opus', 'fable', 'sonnet', 'haiku'] as const;\nexport type ClaudeLLMModel = (typeof claudeLLMModels)[number];\n\nconst claudeLLMModelIds = {\n\topus: 'claude-opus-5-5',\n\tfable: 'claude-fable-5-1',\n\tsonnet: 'claude-sonnet-5',\n\thaiku: 'claude-haiku-4-5',\n} as const satisfies Record<ClaudeLLMModel, string>;\n\nexport const claudeLLMReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n] as const satisfies readonly NonNullable<OutputConfig['effort']>[];\nexport type ClaudeLLMReasoningEffort = (typeof claudeLLMReasoningEfforts)[number];\n\n// Adaptive thinking spends from this budget too, so a hard step at a high effort can need most\n// of it. The request is streamed so it is not bound by the SDK's ten-minute timeout, which made\n// it refuse more than about 21,000 without a stream. 64,000 is the most Haiku 4.5 writes; the\n// other models write up to 128,000, which a single answer here has not needed.\nconst maxOutputTokens = 64_000;\n\n// The request itself is wrong or not allowed, so sending it again cannot succeed.\nconst unrecoverableStatuses = [400, 401, 403, 404, 413, 422];\n\n// The account is out of credit, or its key cannot make the request. Resending cannot fix\n// either, whatever status the error arrives with.\nconst unrecoverableErrorTypes = ['billing_error', 'authentication_error', 'permission_error'];\n\n// This client's label on the thinking blocks it keeps for replay; see `ProviderDataPart`.\nconst claudeSource = 'claude';\n\n// Anthropic's compaction at a token threshold, and the least threshold it accepts.\nconst compactionBeta = 'compact-2026-01-12';\nconst minCompactAt = 50_000;\n\n/**\n * Anthropic rejects a `tool_use` whose input is not an object, with a 400 on every later call.\n * Another provider's call can hold anything else, such as OpenAI arguments that did not parse;\n * its result already told the model the call failed, so sending it as empty loses nothing.\n */\nfunction toClaudeInputObject(input: unknown): unknown {\n\treturn typeof input === 'object' && input !== null && !Array.isArray(input) ? input : {};\n}\n\n/** Thinking crosses back only as the signed block this client kept, never as its text. */\nfunction toClaudeBlocks(part: MessagePart): ContentBlockParam[] {\n\tswitch (part.type) {\n\t\tcase 'text':\n\t\t\t// The API rejects an empty text block.\n\t\t\treturn part.text ? [{ type: 'text', text: part.text }] : [];\n\t\tcase 'toolCall':\n\t\t\treturn [\n\t\t\t\t{ type: 'tool_use', id: part.id, name: part.name, input: toClaudeInputObject(part.input) },\n\t\t\t];\n\t\tcase 'toolResult':\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'tool_result',\n\t\t\t\t\ttool_use_id: part.callId,\n\t\t\t\t\tcontent: part.output,\n\t\t\t\t\tis_error: part.isError,\n\t\t\t\t},\n\t\t\t];\n\t\tcase 'providerData':\n\t\t\t// Another provider's block would be rejected; losing it only costs that provider's reasoning.\n\t\t\treturn part.source === claudeSource\n\t\t\t\t? [part.data as ThinkingBlockParam | RedactedThinkingBlockParam]\n\t\t\t\t: [];\n\t\tcase 'compaction':\n\t\t\t// Another provider's summary means nothing here; this client sends the turns it replaced.\n\t\t\treturn part.source === claudeSource ? [part.data as CompactionBlockParam] : [];\n\t\tcase 'reasoning':\n\t\t\t// Unsigned text cannot be replayed as thinking. The API accepts a turn without it.\n\t\t\treturn [];\n\t}\n}\n\n/**\n * Tool results travel in a user turn, as the API requires. A message left with no blocks is\n * left out whole; the API joins the consecutive user turns that leaves.\n */\nfunction toClaudeInput(message: Message): MessageParam[] {\n\tconst content = message.content.flatMap(toClaudeBlocks);\n\tif (content.length === 0) {\n\t\treturn [];\n\t}\n\n\treturn [{ role: message.role === 'tool' ? 'user' : message.role, content }];\n}\n\n// Anthropic fixes the text editor's name: its calls arrive under it.\nconst textEditorName = 'str_replace_based_edit_tool';\n\n/**\n * Strict: the API constrains the model to the schema, so its input always parses and matches.\n * A schema outside what strict mode supports fails the request with a 400. The native text\n * editor has Anthropic's own schema, and its calls and results are ordinary tool blocks.\n */\nfunction toClaudeTool(definition: ToolDefinition): ClaudeTool | ToolTextEditor20250728 {\n\tconst native = nativeOf(definition);\n\tif (native === 'textEditor') {\n\t\tif (definition.name !== textEditorName) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`Claude's text editor must be named \"${textEditorName}\", not \"${definition.name}\"`,\n\t\t\t);\n\t\t}\n\t\treturn { type: 'text_editor_20250728', name: textEditorName };\n\t}\n\tif (native !== undefined) {\n\t\tthrow new InvalidAgentConfigError(`Claude has no native tool \"${native}\"`);\n\t}\n\tconst { name, description, inputSchema } = definition;\n\treturn { name, description, input_schema: inputSchema, strict: true };\n}\n\nfunction describeBlock(block: ContentBlock, logger: ILogger): MessagePart[] {\n\tswitch (block.type) {\n\t\tcase 'text':\n\t\t\treturn [{ type: 'text', text: block.text }];\n\t\tcase 'thinking': {\n\t\t\t// Kept signed for replay; the summarized text is only for narration.\n\t\t\tconst signed: ThinkingBlockParam = {\n\t\t\t\ttype: 'thinking',\n\t\t\t\tthinking: block.thinking,\n\t\t\t\tsignature: block.signature,\n\t\t\t};\n\t\t\tconst replay: MessagePart = { type: 'providerData', source: claudeSource, data: signed };\n\t\t\treturn block.thinking ? [{ type: 'reasoning', text: block.thinking }, replay] : [replay];\n\t\t}\n\t\tcase 'redacted_thinking': {\n\t\t\t// Encrypted by design: nothing to narrate, but it still goes back.\n\t\t\tconst redacted: RedactedThinkingBlockParam = { type: 'redacted_thinking', data: block.data };\n\t\t\treturn [{ type: 'providerData', source: claudeSource, data: redacted }];\n\t\t}\n\t\tcase 'tool_use':\n\t\t\treturn [{ type: 'toolCall', id: block.id, name: block.name, input: block.input }];\n\t\tcase 'compaction': {\n\t\t\t// A compaction that failed, with no summary. Claude reads one sent back as if it were not\n\t\t\t// there, so it is left out: the context goes on whole, and Claude compacts again later.\n\t\t\tif (!block.content) {\n\t\t\t\ttreatErrors(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\t'Claude could not compact the conversation; it is sent whole until Claude compacts it',\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tclassifyHostFailure,\n\t\t\t\t\t'Claude client logger failed while mapping a response',\n\t\t\t\t);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\t// Claude's summary of the context before it, readable, with what it alone reads back.\n\t\t\tconst compaction: CompactionBlockParam = {\n\t\t\t\ttype: 'compaction',\n\t\t\t\tcontent: block.content,\n\t\t\t\tencrypted_content: block.encrypted_content,\n\t\t\t};\n\t\t\treturn [{ type: 'compaction', source: claudeSource, data: compaction }];\n\t\t}\n\t\tdefault:\n\t\t\t// Server tools are never offered, so any other block is output this client does not expect.\n\t\t\ttreatErrors(\n\t\t\t\t() => {\n\t\t\t\t\tlogger.warn(block, 'Claude returned a content block the client does not map');\n\t\t\t\t},\n\t\t\t\tclassifyHostFailure,\n\t\t\t\t'Claude client logger failed while mapping a response',\n\t\t\t);\n\t\t\treturn [];\n\t}\n}\n\nfunction toStopReason(response: AnthropicMessage): StopReason {\n\tswitch (response.stop_reason) {\n\t\t// `tool_use` is a complete answer that asks for tools: running them is the agent's call.\n\t\tcase 'end_turn':\n\t\tcase 'tool_use':\n\t\t\treturn 'completed';\n\t\tcase 'max_tokens':\n\t\t\treturn 'truncated';\n\t\tcase 'refusal':\n\t\t\treturn 'refused';\n\t\tcase 'model_context_window_exceeded':\n\t\t\tthrow new MaxContextError('The context no longer fits the Claude model', {\n\t\t\t\tcause: 'The response stopped at the model context window.',\n\t\t\t});\n\t\tdefault:\n\t\t\t// `pause_turn` and `stop_sequence` need server tools or stop sequences, and this\n\t\t\t// client sends neither.\n\t\t\tthrow new UnrecoverableError('The Claude response stopped unexpectedly', {\n\t\t\t\tcause: `The response stopped with \"${response.stop_reason ?? 'unknown'}\".`,\n\t\t\t});\n\t}\n}\n\n/**\n * Unlike OpenAI, Anthropic counts cache reads and writes apart from `input_tokens`. A call that\n * compacted leaves the compaction out of its totals, so with iterations their sum is the bill.\n */\nfunction toTokens(usage: Usage | undefined, logger: ILogger): Tokens | undefined {\n\tif (!usage) {\n\t\t// Zeros would report a call that may have been billed as free.\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tlogger.warn('Claude returned a response without usage; it cannot be accounted for');\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'Claude client logger failed while reading usage',\n\t\t);\n\t\treturn undefined;\n\t}\n\n\tif (usage.iterations && usage.iterations.length > 0) {\n\t\treturn usage.iterations.reduce<Tokens>(\n\t\t\t(sum, iteration) => ({\n\t\t\t\tinputTokens: sum.inputTokens + iteration.input_tokens,\n\t\t\t\treadCacheTokens: sum.readCacheTokens + iteration.cache_read_input_tokens,\n\t\t\t\twrittenCacheTokens: sum.writtenCacheTokens + iteration.cache_creation_input_tokens,\n\t\t\t\toutputTokens: sum.outputTokens + iteration.output_tokens,\n\t\t\t}),\n\t\t\t{ inputTokens: 0, readCacheTokens: 0, writtenCacheTokens: 0, outputTokens: 0 },\n\t\t);\n\t}\n\treturn {\n\t\tinputTokens: usage.input_tokens,\n\t\treadCacheTokens: usage.cache_read_input_tokens ?? 0,\n\t\twrittenCacheTokens: usage.cache_creation_input_tokens ?? 0,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\n/**\n * @param summaries each compaction's summary as it was streamed, by the index of its block. The\n * SDK joins a delta that carries none as the text \"null\", so the final message cannot tell.\n */\nfunction toLLMResponse(\n\tresponse: AnthropicMessage,\n\tlogger: ILogger,\n\tsummaries: ReadonlyMap<number, string>,\n): LLMResponse {\n\tlet usage: Tokens | undefined;\n\n\ttry {\n\t\t// Inside the try: it warns when the usage is missing, and that warning can throw too.\n\t\tusage = toTokens(response.usage, logger);\n\t\treturn {\n\t\t\tmessage: {\n\t\t\t\trole: 'assistant',\n\t\t\t\tcontent: response.content.flatMap((block, index) => {\n\t\t\t\t\tconst summary = summaries.get(index);\n\t\t\t\t\treturn describeBlock(\n\t\t\t\t\t\tblock.type === 'compaction' && summary !== undefined\n\t\t\t\t\t\t\t? { ...block, content: summary }\n\t\t\t\t\t\t\t: block,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t},\n\t\t\tusage,\n\t\t\tstopReason: toStopReason(response),\n\t\t};\n\t} catch (error) {\n\t\t// The call was billed whether the response failed or a logger did while mapping it, and\n\t\t// an answer without usage leaves the run's count unknown.\n\t\tthrow withSpentTokens(error, usage, !response.usage);\n\t}\n}\n\n/**\n * The SDK resolves credentials lazily, so a missing key surfaces on the first call, as a plain\n * `Error` the SDK gives no class of its own. Before the stream connects, an `AnthropicError` that\n * is not an `APIError` never carries an answer from the API: it is the SDK refusing to make the\n * call, such as an unresolved profile. Once it connects, the stream reports any failure as one,\n * such as a connection lost halfway; see `classifyClaudeFailure`.\n */\nfunction isLocalSDKFailure(error: unknown): boolean {\n\treturn (\n\t\t(error instanceof AnthropicError && !(error instanceof APIError)) ||\n\t\t(error instanceof Error && error.message.startsWith('Could not resolve authentication method'))\n\t);\n}\n\n/** `connected` is whether the stream had its response: a failure after that broke the stream off. */\nfunction classifyClaudeFailure(error: unknown, connected: boolean): Error {\n\tif (connected && !(error instanceof APIError)) {\n\t\t// The API was answering, so a later attempt can succeed. An error event the API sends\n\t\t// mid-stream, such as an overload, arrives as an `APIError` and is classified below.\n\t\treturn classifyProviderFailure(error, 'The Claude stream broke off');\n\t}\n\tif (isLocalSDKFailure(error)) {\n\t\t// The API never answered, and calling again would fail the same way.\n\t\treturn new UnrecoverableError('The Claude client cannot send the request', {\n\t\t\tcause: describeFailure(error),\n\t\t});\n\t}\n\tif (error instanceof APIError) {\n\t\t// Anthropic gives an overlong prompt no code of its own, only a 400 with this message.\n\t\tif (error.status === 400 && error.message.includes('prompt is too long')) {\n\t\t\treturn new MaxContextError('The context no longer fits the Claude model', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\t\tif (\n\t\t\tunrecoverableErrorTypes.some(type => type === error.type) ||\n\t\t\tunrecoverableStatuses.some(status => status === error.status)\n\t\t) {\n\t\t\treturn new UnrecoverableError('Claude rejected the request', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\t}\n\n\t// A rate limit, an overload (529), a 5xx or a network failure: a later attempt can succeed.\n\treturn classifyProviderFailure(error, 'The Claude request failed');\n}\n\n/**\n * A stateless `LLMClient` on the Anthropic Messages API, which keeps nothing between calls:\n * every call carries the whole context, so the conversation is MiKode's, not the provider's.\n */\nexport class ClaudeLLMClient implements LLMClient {\n\tprivate readonly client: Anthropic;\n\tprivate readonly model: (typeof claudeLLMModelIds)[ClaudeLLMModel];\n\t// Missing for Haiku, which runs without thinking.\n\tprivate readonly reasoningEffort: ClaudeLLMReasoningEffort | undefined;\n\tprivate readonly compactAt: number | undefined;\n\treadonly systemPrompt: string;\n\treadonly providerDataSource = claudeSource;\n\tprivate readonly logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Claude supports.\n\tconstructor({\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\treasoningEffort?: string;\n\t\t/** The input tokens at which Anthropic compacts the context on its side. Without it, never. */\n\t\tcompactAt?: number | undefined;\n\t\tsystemPrompt: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\tif (!isOneOf(claudeLLMModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Claude API model; expected one of: ${claudeLLMModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (model === 'haiku' && reasoningEffort !== undefined) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t'Claude Haiku takes no reasoning effort: it runs without thinking',\n\t\t\t);\n\t\t}\n\t\tconst effort = model === 'haiku' ? undefined : (reasoningEffort ?? 'high');\n\t\tif (effort !== undefined && !isOneOf(claudeLLMReasoningEfforts, effort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${effort}\" is not a Claude API reasoning effort; expected one of: ${claudeLLMReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (compactAt !== undefined) {\n\t\t\t// The alias names Claude Haiku 4.5, which Anthropic does not compact.\n\t\t\tif (model === 'haiku') {\n\t\t\t\tthrow new InvalidAgentConfigError('Claude Haiku cannot compact: leave compactAt out');\n\t\t\t}\n\t\t\tif (!(Number.isInteger(compactAt) && compactAt >= minCompactAt)) {\n\t\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t\t`compactAt must be a whole number of tokens of at least ${String(minCompactAt)} on Claude, not ${String(compactAt)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// The SDK's default retries stay on, as OpenAI's do. See \"The provider SDKs keep their\n\t\t\t// transport retries under RetryingAgent\" in decisions.md.\n\t\t\tthis.client = new Anthropic();\n\t\t} catch (error) {\n\t\t\t// Conflicting credential options, for example: building it again cannot fix them. A\n\t\t\t// missing key does not fail here but on the first call; see `isLocalSDKFailure`.\n\t\t\tthrow new UnrecoverableError('The Claude client could not be set up', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\n\t\tthis.model = claudeLLMModelIds[model];\n\t\tthis.reasoningEffort = effort;\n\t\tthis.compactAt = compactAt;\n\t\tthis.systemPrompt = systemPrompt;\n\t\tthis.logger = logger;\n\t}\n\n\tsupportsNative(tool: NativeTool): boolean {\n\t\treturn tool === 'textEditor';\n\t}\n\n\tasync send(\n\t\t{ context, tools }: { context: Message[]; tools: ToolDefinition[] },\n\t\tsignal: AbortSignal,\n\t): Promise<LLMResponse> {\n\t\tlet response: AnthropicMessage;\n\t\tlet stream: BetaMessageStream | undefined;\n\t\t// What each compaction streamed of its summary, by block index, its missing parts left out.\n\t\tconst summaries = new Map<number, string>();\n\n\t\ttry {\n\t\t\t// Streamed only to lift the timeout: the client still answers with the whole message.\n\t\t\tconst sent = this.client.beta.messages.stream(\n\t\t\t\t{\n\t\t\t\t\tmodel: this.model,\n\t\t\t\t\tmax_tokens: maxOutputTokens,\n\t\t\t\t\t// A compaction changes the conversation's first block, so the cache would otherwise\n\t\t\t\t\t// keep nothing: this keeps the system prompt cached across it. The API rejects an\n\t\t\t\t\t// empty text block, and an empty prompt has nothing to cache.\n\t\t\t\t\tsystem:\n\t\t\t\t\t\tthis.compactAt === undefined || this.systemPrompt === ''\n\t\t\t\t\t\t\t? this.systemPrompt\n\t\t\t\t\t\t\t: [{ type: 'text', text: this.systemPrompt, cache_control: { type: 'ephemeral' } }],\n\t\t\t\t\t// The latest compaction carries everything before it, which Anthropic would only ignore.\n\t\t\t\t\tmessages: sentContext(context, claudeSource).flatMap(toClaudeInput),\n\t\t\t\t\t// Left out when empty, so a request without tools stays as it always was.\n\t\t\t\t\t...(tools.length > 0 && { tools: tools.map(toClaudeTool) }),\n\t\t\t\t\t// Haiku has no adaptive thinking, and an effort is refused with a 400.\n\t\t\t\t\t...(this.reasoningEffort !== undefined && {\n\t\t\t\t\t\tthinking: { type: 'adaptive', display: 'summarized' },\n\t\t\t\t\t\toutput_config: { effort: this.reasoningEffort },\n\t\t\t\t\t}),\n\t\t\t\t\t// Anthropic caches only on request. This marks the last block, so the next call\n\t\t\t\t\t// reads everything before it from the cache instead of paying for it again.\n\t\t\t\t\tcache_control: { type: 'ephemeral' },\n\t\t\t\t\t// Anthropic compacts inside the call that passes it, and answers with the compaction first.\n\t\t\t\t\t...(this.compactAt !== undefined && {\n\t\t\t\t\t\tbetas: [compactionBeta],\n\t\t\t\t\t\tcontext_management: {\n\t\t\t\t\t\t\tedits: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'compact_20260112',\n\t\t\t\t\t\t\t\t\ttrigger: { type: 'input_tokens', value: this.compactAt },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{ signal },\n\t\t\t);\n\t\t\tstream = sent;\n\t\t\tsent.on('streamEvent', event => {\n\t\t\t\tif (event.type === 'content_block_start' && event.content_block.type === 'compaction') {\n\t\t\t\t\tsummaries.set(event.index, event.content_block.content ?? '');\n\t\t\t\t} else if (\n\t\t\t\t\tevent.type === 'content_block_delta' &&\n\t\t\t\t\tevent.delta.type === 'compaction_delta'\n\t\t\t\t) {\n\t\t\t\t\tsummaries.set(\n\t\t\t\t\t\tevent.index,\n\t\t\t\t\t\t(summaries.get(event.index) ?? '') + (event.delta.content ?? ''),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tresponse = await sent.finalMessage();\n\t\t} catch (error) {\n\t\t\t// The SDK's abort error is named 'Error', so it would pass for a provider failure.\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst connected = Boolean(stream?.response);\n\t\t\tconst failure = classifyClaudeFailure(error, connected);\n\t\t\t// Once the stream connected, Claude may have written, and billed, part of an answer it\n\t\t\t// never finished sending, so the run's count cannot be known.\n\t\t\tthrow connected ? withSpentTokens(failure, undefined, true) : failure;\n\t\t}\n\n\t\treturn treatErrors(\n\t\t\t() => toLLMResponse(response, this.logger, summaries),\n\t\t\tclassifyLocalFailure,\n\t\t\t'Claude response mapping failed',\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"claudeLLMClient.js","sourceRoot":"","sources":["../../../src/llm/infrastructure/claudeLLMClient.ts"],"names":[],"mappings":"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","sourcesContent":["import Anthropic, { AnthropicError, APIError } from '@anthropic-ai/sdk';\nimport type { BetaMessageStream } from '@anthropic-ai/sdk/lib/BetaMessageStream';\n// The beta surface, for compaction: without its beta header, a request is the stable one.\nimport type {\n\tBetaCompactionBlockParam as CompactionBlockParam,\n\tBetaContentBlock as ContentBlock,\n\tBetaContentBlockParam as ContentBlockParam,\n\tBetaMessage as AnthropicMessage,\n\tBetaMessageParam as MessageParam,\n\tBetaOutputConfig as OutputConfig,\n\tBetaRedactedThinkingBlockParam as RedactedThinkingBlockParam,\n\tBetaThinkingBlockParam as ThinkingBlockParam,\n\tBetaTool as ClaudeTool,\n\tBetaToolTextEditor20250728 as ToolTextEditor20250728,\n\tBetaUsage as Usage,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages';\nimport {\n\tInvalidAgentConfigError,\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 { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport type { Tokens } from '#src/shared/domain/tokens';\nimport { MaxContextError } from '../domain/errors.ts';\nimport type { LLMClient, LLMResponse, StopReason } from '../domain/llm.ts';\nimport { type Message, type MessagePart, sentContext } from '../domain/message.ts';\nimport { type NativeTool, nativeOf, type ToolDefinition } from '../domain/tool.ts';\nimport { claudeModelIds } from './claudeModelIds.ts';\n\n// The Messages API takes full model IDs; `claudeModelIds` pins the one each alias names.\nexport const claudeLLMModels = [\n\t'opus',\n\t'fable',\n\t'sonnet',\n\t'haiku',\n] as const satisfies readonly (keyof typeof claudeModelIds)[];\nexport type ClaudeLLMModel = (typeof claudeLLMModels)[number];\n\nexport const claudeLLMReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n] as const satisfies readonly NonNullable<OutputConfig['effort']>[];\nexport type ClaudeLLMReasoningEffort = (typeof claudeLLMReasoningEfforts)[number];\n\n// Adaptive thinking spends from this budget too, so a hard step at a high effort can need most\n// of it. The request is streamed so it is not bound by the SDK's ten-minute timeout, which made\n// it refuse more than about 21,000 without a stream. A single answer here has not needed more\n// than 64,000, which every model writes.\nconst maxOutputTokens = 64_000;\n\n// The request itself is wrong or not allowed, so sending it again cannot succeed.\nconst unrecoverableStatuses = [400, 401, 403, 404, 413, 422];\n\n// The account is out of credit, or its key cannot make the request. Resending cannot fix\n// either, whatever status the error arrives with.\nconst unrecoverableErrorTypes = ['billing_error', 'authentication_error', 'permission_error'];\n\n// This client's label on the thinking blocks it keeps for replay; see `ProviderDataPart`.\nconst claudeSource = 'claude';\n\n// Anthropic's compaction at a token threshold, and the least threshold it accepts.\nconst compactionBeta = 'compact-2026-01-12';\nconst minCompactAt = 50_000;\n\n/**\n * Anthropic rejects a `tool_use` whose input is not an object, with a 400 on every later call.\n * Another provider's call can hold anything else, such as OpenAI arguments that did not parse;\n * its result already told the model the call failed, so sending it as empty loses nothing.\n */\nfunction toClaudeInputObject(input: unknown): unknown {\n\treturn typeof input === 'object' && input !== null && !Array.isArray(input) ? input : {};\n}\n\n/** Thinking crosses back only as the signed block this client kept, never as its text. */\nfunction toClaudeBlocks(part: MessagePart): ContentBlockParam[] {\n\tswitch (part.type) {\n\t\tcase 'text':\n\t\t\t// The API rejects an empty text block.\n\t\t\treturn part.text ? [{ type: 'text', text: part.text }] : [];\n\t\tcase 'toolCall':\n\t\t\treturn [\n\t\t\t\t{ type: 'tool_use', id: part.id, name: part.name, input: toClaudeInputObject(part.input) },\n\t\t\t];\n\t\tcase 'toolResult':\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'tool_result',\n\t\t\t\t\ttool_use_id: part.callId,\n\t\t\t\t\tcontent: part.output,\n\t\t\t\t\tis_error: part.isError,\n\t\t\t\t},\n\t\t\t];\n\t\tcase 'providerData':\n\t\t\t// Another provider's block would be rejected; losing it only costs that provider's reasoning.\n\t\t\treturn part.source === claudeSource\n\t\t\t\t? [part.data as ThinkingBlockParam | RedactedThinkingBlockParam]\n\t\t\t\t: [];\n\t\tcase 'compaction':\n\t\t\t// Another provider's summary means nothing here; this client sends the turns it replaced.\n\t\t\treturn part.source === claudeSource ? [part.data as CompactionBlockParam] : [];\n\t\tcase 'reasoning':\n\t\t\t// Unsigned text cannot be replayed as thinking. The API accepts a turn without it.\n\t\t\treturn [];\n\t}\n}\n\n/**\n * Tool results travel in a user turn, as the API requires. A message left with no blocks is\n * left out whole; the API joins the consecutive user turns that leaves.\n */\nfunction toClaudeInput(message: Message): MessageParam[] {\n\tconst content = message.content.flatMap(toClaudeBlocks);\n\tif (content.length === 0) {\n\t\treturn [];\n\t}\n\n\treturn [{ role: message.role === 'tool' ? 'user' : message.role, content }];\n}\n\n// Anthropic fixes the text editor's name: its calls arrive under it.\nconst textEditorName = 'str_replace_based_edit_tool';\n\n/**\n * Strict: the API constrains the model to the schema, so its input always parses and matches.\n * A schema outside what strict mode supports fails the request with a 400. The native text\n * editor has Anthropic's own schema, and its calls and results are ordinary tool blocks.\n */\nfunction toClaudeTool(definition: ToolDefinition): ClaudeTool | ToolTextEditor20250728 {\n\tconst native = nativeOf(definition);\n\tif (native === 'textEditor') {\n\t\tif (definition.name !== textEditorName) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`Claude's text editor must be named \"${textEditorName}\", not \"${definition.name}\"`,\n\t\t\t);\n\t\t}\n\t\treturn { type: 'text_editor_20250728', name: textEditorName };\n\t}\n\tif (native !== undefined) {\n\t\tthrow new InvalidAgentConfigError(`Claude has no native tool \"${native}\"`);\n\t}\n\tconst { name, description, inputSchema } = definition;\n\treturn { name, description, input_schema: inputSchema, strict: true };\n}\n\nfunction describeBlock(block: ContentBlock, logger: ILogger): MessagePart[] {\n\tswitch (block.type) {\n\t\tcase 'text':\n\t\t\treturn [{ type: 'text', text: block.text }];\n\t\tcase 'thinking': {\n\t\t\t// Kept signed for replay; the summarized text is only for narration.\n\t\t\tconst signed: ThinkingBlockParam = {\n\t\t\t\ttype: 'thinking',\n\t\t\t\tthinking: block.thinking,\n\t\t\t\tsignature: block.signature,\n\t\t\t};\n\t\t\tconst replay: MessagePart = { type: 'providerData', source: claudeSource, data: signed };\n\t\t\treturn block.thinking ? [{ type: 'reasoning', text: block.thinking }, replay] : [replay];\n\t\t}\n\t\tcase 'redacted_thinking': {\n\t\t\t// Encrypted by design: nothing to narrate, but it still goes back.\n\t\t\tconst redacted: RedactedThinkingBlockParam = { type: 'redacted_thinking', data: block.data };\n\t\t\treturn [{ type: 'providerData', source: claudeSource, data: redacted }];\n\t\t}\n\t\tcase 'tool_use':\n\t\t\treturn [{ type: 'toolCall', id: block.id, name: block.name, input: block.input }];\n\t\tcase 'compaction': {\n\t\t\t// A compaction that failed, with no summary. Claude reads one sent back as if it were not\n\t\t\t// there, so it is left out: the context goes on whole, and Claude compacts again later.\n\t\t\tif (!block.content) {\n\t\t\t\ttreatErrors(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\t'Claude could not compact the conversation; it is sent whole until Claude compacts it',\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tclassifyHostFailure,\n\t\t\t\t\t'Claude client logger failed while mapping a response',\n\t\t\t\t);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\t// Claude's summary of the context before it, readable, with what it alone reads back.\n\t\t\tconst compaction: CompactionBlockParam = {\n\t\t\t\ttype: 'compaction',\n\t\t\t\tcontent: block.content,\n\t\t\t\tencrypted_content: block.encrypted_content,\n\t\t\t};\n\t\t\treturn [{ type: 'compaction', source: claudeSource, data: compaction }];\n\t\t}\n\t\tdefault:\n\t\t\t// Server tools are never offered, so any other block is output this client does not expect.\n\t\t\ttreatErrors(\n\t\t\t\t() => {\n\t\t\t\t\tlogger.warn(block, 'Claude returned a content block the client does not map');\n\t\t\t\t},\n\t\t\t\tclassifyHostFailure,\n\t\t\t\t'Claude client logger failed while mapping a response',\n\t\t\t);\n\t\t\treturn [];\n\t}\n}\n\nfunction toStopReason(response: AnthropicMessage): StopReason {\n\tswitch (response.stop_reason) {\n\t\t// `tool_use` is a complete answer that asks for tools: running them is the agent's call.\n\t\tcase 'end_turn':\n\t\tcase 'tool_use':\n\t\t\treturn 'completed';\n\t\tcase 'max_tokens':\n\t\t\treturn 'truncated';\n\t\tcase 'refusal':\n\t\t\treturn 'refused';\n\t\tcase 'model_context_window_exceeded':\n\t\t\tthrow new MaxContextError('The context no longer fits the Claude model', {\n\t\t\t\tcause: 'The response stopped at the model context window.',\n\t\t\t});\n\t\tdefault:\n\t\t\t// `pause_turn` and `stop_sequence` need server tools or stop sequences, and this\n\t\t\t// client sends neither.\n\t\t\tthrow new UnrecoverableError('The Claude response stopped unexpectedly', {\n\t\t\t\tcause: `The response stopped with \"${response.stop_reason ?? 'unknown'}\".`,\n\t\t\t});\n\t}\n}\n\n/**\n * Unlike OpenAI, Anthropic counts cache reads and writes apart from `input_tokens`. A call that\n * compacted leaves the compaction out of its totals, so with iterations their sum is the bill.\n */\nfunction toTokens(usage: Usage | undefined, logger: ILogger): Tokens | undefined {\n\tif (!usage) {\n\t\t// Zeros would report a call that may have been billed as free.\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tlogger.warn('Claude returned a response without usage; it cannot be accounted for');\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'Claude client logger failed while reading usage',\n\t\t);\n\t\treturn undefined;\n\t}\n\n\tif (usage.iterations && usage.iterations.length > 0) {\n\t\treturn usage.iterations.reduce<Tokens>(\n\t\t\t(sum, iteration) => ({\n\t\t\t\tinputTokens: sum.inputTokens + iteration.input_tokens,\n\t\t\t\treadCacheTokens: sum.readCacheTokens + iteration.cache_read_input_tokens,\n\t\t\t\twrittenCacheTokens: sum.writtenCacheTokens + iteration.cache_creation_input_tokens,\n\t\t\t\toutputTokens: sum.outputTokens + iteration.output_tokens,\n\t\t\t}),\n\t\t\t{ inputTokens: 0, readCacheTokens: 0, writtenCacheTokens: 0, outputTokens: 0 },\n\t\t);\n\t}\n\treturn {\n\t\tinputTokens: usage.input_tokens,\n\t\treadCacheTokens: usage.cache_read_input_tokens ?? 0,\n\t\twrittenCacheTokens: usage.cache_creation_input_tokens ?? 0,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\n/**\n * @param summaries each compaction's summary as it was streamed, by the index of its block. The\n * SDK joins a delta that carries none as the text \"null\", so the final message cannot tell.\n */\nfunction toLLMResponse(\n\tresponse: AnthropicMessage,\n\tlogger: ILogger,\n\tsummaries: ReadonlyMap<number, string>,\n): LLMResponse {\n\tlet usage: Tokens | undefined;\n\n\ttry {\n\t\t// Inside the try: it warns when the usage is missing, and that warning can throw too.\n\t\tusage = toTokens(response.usage, logger);\n\t\treturn {\n\t\t\tmessage: {\n\t\t\t\trole: 'assistant',\n\t\t\t\tcontent: response.content.flatMap((block, index) => {\n\t\t\t\t\tconst summary = summaries.get(index);\n\t\t\t\t\treturn describeBlock(\n\t\t\t\t\t\tblock.type === 'compaction' && summary !== undefined\n\t\t\t\t\t\t\t? { ...block, content: summary }\n\t\t\t\t\t\t\t: block,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t},\n\t\t\tusage,\n\t\t\tstopReason: toStopReason(response),\n\t\t};\n\t} catch (error) {\n\t\t// The call was billed whether the response failed or a logger did while mapping it, and\n\t\t// an answer without usage leaves the run's count unknown.\n\t\tthrow withSpentTokens(error, usage, !response.usage);\n\t}\n}\n\n/**\n * The SDK resolves credentials lazily, so a missing key surfaces on the first call, as a plain\n * `Error` the SDK gives no class of its own. Before the stream connects, an `AnthropicError` that\n * is not an `APIError` never carries an answer from the API: it is the SDK refusing to make the\n * call, such as an unresolved profile. Once it connects, the stream reports any failure as one,\n * such as a connection lost halfway; see `classifyClaudeFailure`.\n */\nfunction isLocalSDKFailure(error: unknown): boolean {\n\treturn (\n\t\t(error instanceof AnthropicError && !(error instanceof APIError)) ||\n\t\t(error instanceof Error && error.message.startsWith('Could not resolve authentication method'))\n\t);\n}\n\n/** `connected` is whether the stream had its response: a failure after that broke the stream off. */\nfunction classifyClaudeFailure(error: unknown, connected: boolean): Error {\n\tif (connected && !(error instanceof APIError)) {\n\t\t// The API was answering, so a later attempt can succeed. An error event the API sends\n\t\t// mid-stream, such as an overload, arrives as an `APIError` and is classified below.\n\t\treturn classifyProviderFailure(error, 'The Claude stream broke off');\n\t}\n\tif (isLocalSDKFailure(error)) {\n\t\t// The API never answered, and calling again would fail the same way.\n\t\treturn new UnrecoverableError('The Claude client cannot send the request', {\n\t\t\tcause: describeFailure(error),\n\t\t});\n\t}\n\tif (error instanceof APIError) {\n\t\t// Anthropic gives an overlong prompt no code of its own, only a 400 with this message.\n\t\tif (error.status === 400 && error.message.includes('prompt is too long')) {\n\t\t\treturn new MaxContextError('The context no longer fits the Claude model', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\t\tif (\n\t\t\tunrecoverableErrorTypes.some(type => type === error.type) ||\n\t\t\tunrecoverableStatuses.some(status => status === error.status)\n\t\t) {\n\t\t\treturn new UnrecoverableError('Claude rejected the request', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\t}\n\n\t// A rate limit, an overload (529), a 5xx or a network failure: a later attempt can succeed.\n\treturn classifyProviderFailure(error, 'The Claude request failed');\n}\n\n/**\n * A stateless `LLMClient` on the Anthropic Messages API, which keeps nothing between calls:\n * every call carries the whole context, so the conversation is MiKode's, not the provider's.\n */\nexport class ClaudeLLMClient implements LLMClient {\n\tprivate readonly client: Anthropic;\n\tprivate readonly model: (typeof claudeModelIds)[ClaudeLLMModel];\n\tprivate readonly reasoningEffort: ClaudeLLMReasoningEffort;\n\tprivate readonly compactAt: number | undefined;\n\treadonly systemPrompt: string;\n\treadonly providerDataSource = claudeSource;\n\tprivate readonly logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Claude supports.\n\tconstructor({\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\treasoningEffort?: string;\n\t\t/** The input tokens at which Anthropic compacts the context on its side. Without it, never. */\n\t\tcompactAt?: number | undefined;\n\t\tsystemPrompt: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\tif (!isOneOf(claudeLLMModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Claude API model; expected one of: ${claudeLLMModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tconst effort = reasoningEffort ?? 'high';\n\t\tif (!isOneOf(claudeLLMReasoningEfforts, effort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${effort}\" is not a Claude API reasoning effort; expected one of: ${claudeLLMReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (compactAt !== undefined && !(Number.isInteger(compactAt) && compactAt >= minCompactAt)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`compactAt must be a whole number of tokens of at least ${String(minCompactAt)} on Claude, not ${String(compactAt)}`,\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\t// The SDK's default retries stay on, as OpenAI's do. See \"The provider SDKs keep their\n\t\t\t// transport retries under RetryingAgent\" in decisions.md.\n\t\t\tthis.client = new Anthropic();\n\t\t} catch (error) {\n\t\t\t// Conflicting credential options, for example: building it again cannot fix them. A\n\t\t\t// missing key does not fail here but on the first call; see `isLocalSDKFailure`.\n\t\t\tthrow new UnrecoverableError('The Claude client could not be set up', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\n\t\tthis.model = claudeModelIds[model];\n\t\tthis.reasoningEffort = effort;\n\t\tthis.compactAt = compactAt;\n\t\tthis.systemPrompt = systemPrompt;\n\t\tthis.logger = logger;\n\t}\n\n\tsupportsNative(tool: NativeTool): boolean {\n\t\treturn tool === 'textEditor';\n\t}\n\n\tasync send(\n\t\t{ context, tools }: { context: Message[]; tools: ToolDefinition[] },\n\t\tsignal: AbortSignal,\n\t): Promise<LLMResponse> {\n\t\tlet response: AnthropicMessage;\n\t\tlet stream: BetaMessageStream | undefined;\n\t\t// What each compaction streamed of its summary, by block index, its missing parts left out.\n\t\tconst summaries = new Map<number, string>();\n\n\t\ttry {\n\t\t\t// Streamed only to lift the timeout: the client still answers with the whole message.\n\t\t\tconst sent = this.client.beta.messages.stream(\n\t\t\t\t{\n\t\t\t\t\tmodel: this.model,\n\t\t\t\t\tmax_tokens: maxOutputTokens,\n\t\t\t\t\t// A compaction changes the conversation's first block, so the cache would otherwise\n\t\t\t\t\t// keep nothing: this keeps the system prompt cached across it. The API rejects an\n\t\t\t\t\t// empty text block, and an empty prompt has nothing to cache.\n\t\t\t\t\tsystem:\n\t\t\t\t\t\tthis.compactAt === undefined || this.systemPrompt === ''\n\t\t\t\t\t\t\t? this.systemPrompt\n\t\t\t\t\t\t\t: [{ type: 'text', text: this.systemPrompt, cache_control: { type: 'ephemeral' } }],\n\t\t\t\t\t// The latest compaction carries everything before it, which Anthropic would only ignore.\n\t\t\t\t\tmessages: sentContext(context, claudeSource).flatMap(toClaudeInput),\n\t\t\t\t\t// Left out when empty, so a request without tools stays as it always was.\n\t\t\t\t\t...(tools.length > 0 && { tools: tools.map(toClaudeTool) }),\n\t\t\t\t\tthinking: { type: 'adaptive', display: 'summarized' },\n\t\t\t\t\toutput_config: { effort: this.reasoningEffort },\n\t\t\t\t\t// Anthropic caches only on request. This marks the last block, so the next call\n\t\t\t\t\t// reads everything before it from the cache instead of paying for it again.\n\t\t\t\t\tcache_control: { type: 'ephemeral' },\n\t\t\t\t\t// Anthropic compacts inside the call that passes it, and answers with the compaction first.\n\t\t\t\t\t...(this.compactAt !== undefined && {\n\t\t\t\t\t\tbetas: [compactionBeta],\n\t\t\t\t\t\tcontext_management: {\n\t\t\t\t\t\t\tedits: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'compact_20260112',\n\t\t\t\t\t\t\t\t\ttrigger: { type: 'input_tokens', value: this.compactAt },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{ signal },\n\t\t\t);\n\t\t\tstream = sent;\n\t\t\tsent.on('streamEvent', event => {\n\t\t\t\tif (event.type === 'content_block_start' && event.content_block.type === 'compaction') {\n\t\t\t\t\tsummaries.set(event.index, event.content_block.content ?? '');\n\t\t\t\t} else if (\n\t\t\t\t\tevent.type === 'content_block_delta' &&\n\t\t\t\t\tevent.delta.type === 'compaction_delta'\n\t\t\t\t) {\n\t\t\t\t\tsummaries.set(\n\t\t\t\t\t\tevent.index,\n\t\t\t\t\t\t(summaries.get(event.index) ?? '') + (event.delta.content ?? ''),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tresponse = await sent.finalMessage();\n\t\t} catch (error) {\n\t\t\t// The SDK's abort error is named 'Error', so it would pass for a provider failure.\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst connected = Boolean(stream?.response);\n\t\t\tconst failure = classifyClaudeFailure(error, connected);\n\t\t\t// Once the stream connected, Claude may have written, and billed, part of an answer it\n\t\t\t// never finished sending, so the run's count cannot be known.\n\t\t\tthrow connected ? withSpentTokens(failure, undefined, true) : failure;\n\t\t}\n\n\t\treturn treatErrors(\n\t\t\t() => toLLMResponse(response, this.logger, summaries),\n\t\t\tclassifyLocalFailure,\n\t\t\t'Claude response mapping failed',\n\t\t);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model each Claude alias names, on the Messages API and through the Agent SDK alike, so both
|
|
3
|
+
* paths run the same model for the same name. Callers name a model by alias; this table pins the
|
|
4
|
+
* ID, and moves by hand when Anthropic releases a newer model.
|
|
5
|
+
*/
|
|
6
|
+
export declare const claudeModelIds: {
|
|
7
|
+
readonly opus: "claude-opus-5-5";
|
|
8
|
+
readonly fable: "claude-fable-5-1";
|
|
9
|
+
readonly sonnet: "claude-sonnet-5-5";
|
|
10
|
+
readonly haiku: "claude-haiku-5-5";
|
|
11
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model each Claude alias names, on the Messages API and through the Agent SDK alike, so both
|
|
3
|
+
* paths run the same model for the same name. Callers name a model by alias; this table pins the
|
|
4
|
+
* ID, and moves by hand when Anthropic releases a newer model.
|
|
5
|
+
*/
|
|
6
|
+
export const claudeModelIds = {
|
|
7
|
+
opus: 'claude-opus-5-5',
|
|
8
|
+
fable: 'claude-fable-5-1',
|
|
9
|
+
sonnet: 'claude-sonnet-5-5',
|
|
10
|
+
haiku: 'claude-haiku-5-5',
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=claudeModelIds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeModelIds.js","sourceRoot":"","sources":["../../../src/llm/infrastructure/claudeModelIds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,kBAAkB;IACzB,MAAM,EAAE,mBAAmB;IAC3B,KAAK,EAAE,kBAAkB;CAChB,CAAC","sourcesContent":["/**\n * The model each Claude alias names, on the Messages API and through the Agent SDK alike, so both\n * paths run the same model for the same name. Callers name a model by alias; this table pins the\n * ID, and moves by hand when Anthropic releases a newer model.\n */\nexport const claudeModelIds = {\n\topus: 'claude-opus-5-5',\n\tfable: 'claude-fable-5-1',\n\tsonnet: 'claude-sonnet-5-5',\n\thaiku: 'claude-haiku-5-5',\n} as const;\n"]}
|