@mikode13/harness 5.3.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +36 -3
  2. package/dist/agent/domain/agent.d.ts +15 -3
  3. package/dist/agent/domain/agent.js.map +1 -1
  4. package/dist/agent/domain/question.d.ts +35 -0
  5. package/dist/agent/domain/question.js +35 -0
  6. package/dist/agent/domain/question.js.map +1 -0
  7. package/dist/engines/domain/model/askUser.d.ts +14 -0
  8. package/dist/engines/domain/model/askUser.js +107 -0
  9. package/dist/engines/domain/model/askUser.js.map +1 -0
  10. package/dist/engines/domain/model/llmAgent.d.ts +5 -0
  11. package/dist/engines/domain/model/llmAgent.js +55 -7
  12. package/dist/engines/domain/model/llmAgent.js.map +1 -1
  13. package/dist/engines/domain/model/stepContext.d.ts +1 -1
  14. package/dist/engines/domain/model/stepContext.js +8 -1
  15. package/dist/engines/domain/model/stepContext.js.map +1 -1
  16. package/dist/factory/infrastructure/agentLLMFactory.d.ts +17 -2
  17. package/dist/factory/infrastructure/agentLLMFactory.js +57 -27
  18. package/dist/factory/infrastructure/agentLLMFactory.js.map +1 -1
  19. package/dist/index.d.ts +2 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/llm/domain/llm.d.ts +2 -2
  22. package/dist/llm/domain/llm.js.map +1 -1
  23. package/dist/llm/domain/message.d.ts +17 -1
  24. package/dist/llm/domain/message.js +14 -1
  25. package/dist/llm/domain/message.js.map +1 -1
  26. package/dist/llm/infrastructure/claudeLLMClient.d.ts +5 -2
  27. package/dist/llm/infrastructure/claudeLLMClient.js +61 -5
  28. package/dist/llm/infrastructure/claudeLLMClient.js.map +1 -1
  29. package/dist/llm/infrastructure/openAILLMClient.d.ts +5 -2
  30. package/dist/llm/infrastructure/openAILLMClient.js +25 -2
  31. package/dist/llm/infrastructure/openAILLMClient.js.map +1 -1
  32. package/dist/retry/domain/model/retryingAgent.js +11 -2
  33. package/dist/retry/domain/model/retryingAgent.js.map +1 -1
  34. package/dist/tools/infrastructure/workspaceTools.d.ts +1 -0
  35. package/dist/tools/infrastructure/workspaceTools.js +32 -10
  36. package/dist/tools/infrastructure/workspaceTools.js.map +1 -1
  37. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"agentLLMFactory.js","sourceRoot":"","sources":["../../../src/factory/infrastructure/agentLLMFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from 'node:path';\nimport type { Agent } from '#src/agent/domain/agent';\nimport type { HistoryReader } from '#src/engines/domain/model/historyFollower';\nimport { LLMAgent } from '#src/engines/domain/model/llmAgent';\nimport type { LLMClient } from '#src/llm/domain/llm';\nimport {\n\tClaudeLLMClient,\n\tclaudeLLMModels,\n\tclaudeLLMReasoningEfforts,\n} from '#src/llm/infrastructure/claudeLLMClient';\nimport {\n\tOpenAILLMClient,\n\topenAIModels,\n\topenAIReasoningEfforts,\n} from '#src/llm/infrastructure/openAILLMClient';\nimport {\n\texecutorInstructions,\n\texecutorInstructionsWithoutCommands,\n\tOrchestratorAgent,\n\tplannerInstructions,\n\treviewerInstructions,\n\treviewerInstructionsWithoutCommands,\n} from '#src/orchestration/domain/model/orchestratorAgent';\nimport { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';\nimport type { RecoveryStore } from '#src/recovery/domain/recoveryStore';\nimport { RetryingAgent } from '#src/retry/domain/model/retryingAgent';\nimport { InvalidAgentConfigError } from '#src/shared/domain/errors';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport { Logger } from '#src/shared/infrastructure/logger';\nimport type { WorkspaceRoot } from '#src/tools/domain/accessPolicy';\nimport {\n\ttype CommandRole,\n\ttype Commands,\n\tcommandsFor,\n\tvalidateCommands,\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 { 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 * Runs every tool call without asking, `destructive` ones included, for CI where no one can\n\t * answer. Without it, a `destructive` call goes to the run's `approve`, or is denied.\n\t */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n}\n\n/** A limit per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleSteps = Partial<Record<OrchestratorRole, number>>;\n\n// 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/**\n * Each role's step limit, from one number for all of them or a number per role.\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 stepsPerRole(maxSteps: unknown): Record<OrchestratorRole, number> {\n\tif (maxSteps === undefined) return defaultRoleSteps;\n\tif (typeof maxSteps === 'number') {\n\t\treturn { planner: maxSteps, executor: maxSteps, reviewer: maxSteps };\n\t}\n\t// Untyped input, such as the CLI's configuration file, can hold `null` or a list here.\n\tif (typeof maxSteps !== 'object' || maxSteps === null || Array.isArray(maxSteps)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t'maxSteps must be a number or an object of steps per role, such as { \"executor\": 120 }',\n\t\t);\n\t}\n\tconst unknown = Object.keys(maxSteps).filter(role => !(role in defaultRoleSteps));\n\tif (unknown.length > 0) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`maxSteps 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(maxSteps as Record<string, unknown>).filter(\n\t\t([, steps]) => steps !== undefined,\n\t);\n\treturn { ...defaultRoleSteps, ...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 * 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 summary of what the user undid, from the planner's provider's cheap model, for every\n\t * role. See `CreateLLMAgentOptions.summarizeUndone`. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n}\n\nconst defaultLLMAgentModels = {\n\tanthropic: 'sonnet',\n\topenai: 'gpt-5.6-luna',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\nfunction unknownProvider(provider: never): InvalidAgentConfigError {\n\treturn new InvalidAgentConfigError(\n\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t);\n}\n\nfunction llmClientFor(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\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\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\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\tautoApprove,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tsystemPrompt: string;\n\t\ttools: AgentTool[];\n\t\thistory?: HistoryReader;\n\t\tsummarizer?: LLMClient;\n\t\tmaxSteps?: number;\n\t\tautoApprove?: boolean;\n\t\tlogger: ILogger;\n\t},\n): Agent {\n\tconst llmClient = llmClientFor(provider, { model, reasoningEffort, systemPrompt, logger });\n\t// LLMAgent records nothing from a failed call, so the original prompt is the whole story.\n\treturn new RetryingAgent({\n\t\tinner: new LLMAgent({\n\t\t\tllmClient,\n\t\t\ttools,\n\t\t\tautoApprove,\n\t\t\tlogger,\n\t\t\t...(history ? { history } : {}),\n\t\t\t...(summarizer ? { summarizer } : {}),\n\t\t\t...(maxSteps === undefined ? {} : { maxSteps }),\n\t\t}),\n\t\tlogger,\n\t\tnoteFailures: false,\n\t});\n}\n\n/**\n * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in\n * the harness's retry policy. It needs the provider's API key and bills per token, where\n * `createAgent` uses the Agent SDK's login. Each tool judges the risk of each call; a\n * `destructive` one runs only when the run's `approve` allows it, or with `autoApprove`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a model or reasoning effort its\n * client does not support, or two tools that share a name.\n * @throws {UnrecoverableError} when the client cannot be set up, for example because\n * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing\n * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.\n */\nexport function createLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools = [],\n\t\tworkspace,\n\t\tsummarizeUndone = true,\n\t\tmaxSteps,\n\t\tautoApprove,\n\t\tlogger = new Logger(),\n\t}: CreateLLMAgentOptions,\n): Agent {\n\treturn buildLLMAgent(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt: workspace\n\t\t\t? withGuidance(systemPrompt, workspaceGuidance(workspace.roots))\n\t\t\t: systemPrompt,\n\t\t// A file tool is a harness tool under its public name.\n\t\ttools: tools as AgentTool[],\n\t\t...(workspace ? { history: historyOf(workspace) } : {}),\n\t\t...(workspace && summarizeUndone ? { summarizer: summarizerFor(provider, logger) } : {}),\n\t\tmaxSteps,\n\t\tautoApprove,\n\t\tlogger,\n\t});\n}\n\n/**\n * The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the\n * provider's own format:\n *\n * - OpenAI: `listFiles`, `searchText`, `readFile` and its native `apply_patch`;\n * - Anthropic: `listFiles`, `searchText`, its native text editor, whose `view` reads, and\n * `delete_file`.\n *\n * Every one goes through the workspace's access policy: a path outside the roots, a secret,\n * a file `.gitignore` excludes or the harness protects is refused. A change is made only in a\n * `write` root, only from a version the agent read, and is recorded in the workspace's history,\n * so it can be undone. Without a `write` root the tools only read. Give the agent the same\n * `workspace`, so it follows what the history undoes.\n *\n * With `commands`, they include `runCommand`, which runs one of them by name, with only the\n * parameters it declares and never through a shell. Each run asks the approver, showing the\n * program exactly as it will run, and gets a small environment without the provider keys. The\n * files of the `write` roots are captured before it and compared after, so what it changed is\n * in the history too. It is trusted execution, not a sandbox: a command can reach whatever\n * this user can. Not supported on Windows yet.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a workspace with no root, or an\n * invalid command, including one whose `cwd` is not in a `write` root, or any on 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{ logger = new Logger(), commands }: { logger?: ILogger; commands?: Commands } = {},\n): Promise<FileTool[]> {\n\t// Reachable from untyped input.\n\tif (!isAgentProvider(provider)) throw unknownProvider(provider);\n\tif (commands !== undefined) validateCommands(commands);\n\tconst opened = await openWorkspace(workspace, logger);\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/**\n * What the planner and the reviewer read with: no edits, the current task's changes, and the\n * commands given to their role.\n */\nasync function readingTools(\n\tworkspace: OpenedWorkspace,\n\trole: CommandRole,\n\tcommands: Commands | undefined,\n): Promise<AgentTool[]> {\n\tconst { read, policy, store } = workspace;\n\tconst finding = createWorkspaceTools(read).filter(tool => tool.name !== 'readFile');\n\tconst tools = [\n\t\t...finding,\n\t\tcreateTrackedReadFile(policy),\n\t\tcreateShowChangesTool({ store, policy }),\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\n// Sent after the workspace's roots, so it stays short: it only says how to find one's way\n// around the repository without reading all of it.\nconst repositoryGuidance =\n\t'Start with AGENTS.md and the architecture document it links to learn where things live, then read only the files your task needs. 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\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`, and\n * `showChanges`, the current task's changes as far as each may read them.\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 * - The executor is told to finish only once the tests and checks pass, and the reviewer that\n * they passed, when the executor has a command; without one, both are told the tests were\n * not run, and the reviewer judges from the code whether 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\tcommands,\n\tsummarizeUndone = true,\n\tlogger = new Logger(),\n}: CreateLLMOrchestratorOptions = {}): Promise<Agent> {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst steps = stepsPerRole(maxSteps);\n\tconst opened = await openWorkspace(workspace, logger);\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 = (own: string | undefined, instructions: string) =>\n\t\town === undefined\n\t\t\t? withGuidance(instructions, `${guidance}\\n${repositoryGuidance}`)\n\t\t\t: withGuidance(own, guidance);\n\t// Every command, checked once, before any role takes its share.\n\tif (commands !== undefined) validateCommands(commands);\n\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),\n\t\t\tmaxSteps: steps[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(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\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\tautoApprove,\n\t\t\t...shared,\n\t\t}),\n\t\treviewerAgent: await reader(\n\t\t\troles.reviewer,\n\t\t\t'reviewer',\n\t\t\tprompt(\n\t\t\t\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 { 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\tvalidateCommands,\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 { createShowChangesTool } from '#src/tools/infrastructure/showChangesTool';\nimport { createTrackedReadFile } from '#src/tools/infrastructure/trackedReadFile';\nimport { createWorkspaceTools } from '#src/tools/infrastructure/workspaceTools';\nimport { isAgentProvider, orchestratorRolesFor, type Role } from './agentFactory.ts';\nimport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './types.ts';\n\n/** The models each provider's model API accepts. */\nexport const llmModels = {\n\tanthropic: claudeLLMModels,\n\topenai: openAIModels,\n} as const satisfies Readonly<Record<AgentProvider, readonly AgentModel[]>>;\n\n/** The reasoning efforts each provider's model API accepts. */\nexport const llmReasoningEfforts = {\n\tanthropic: claudeLLMReasoningEfforts,\n\topenai: openAIReasoningEfforts,\n} as const satisfies Readonly<Record<AgentProvider, readonly ReasoningEffort[]>>;\n\n/** Narrows a model to one accepted by the selected provider's model API. */\nexport function isLLMModelOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmModels)[Provider][number] {\n\treturn isOneOf(llmModels[provider], value);\n}\n\n/** Narrows a reasoning effort to one accepted by the selected provider's model API. */\nexport function isLLMReasoningEffortOf<Provider extends AgentProvider>(\n\tprovider: Provider,\n\tvalue: string,\n): value is (typeof llmReasoningEfforts)[Provider][number] {\n\treturn isOneOf(llmReasoningEfforts[provider], value);\n}\n\nexport interface CreateLLMAgentOptions {\n\t/**\n\t * Defaults to `'sonnet'` on Anthropic and `'gpt-5.6-luna'` on OpenAI. The provider's client\n\t * rejects a model it does not support.\n\t */\n\tmodel?: AgentModel;\n\t/** Defaults to `'high'`. The provider's client rejects an effort it does not support. */\n\treasoningEffort?: ReasoningEffort;\n\t/** Sent as the model's instructions on every call. */\n\tsystemPrompt: string;\n\t/** The tools the model may call: the consumer's own, and those of `createFileTools`. Defaults to none. */\n\ttools?: (Tool | FileTool)[];\n\t/**\n\t * The folders the agent works on, the same as given to `createFileTools`. With it, the agent\n\t * follows the workspace's history: after the user undoes runs, its next run starts from the\n\t * conversation as it was, and is told what was undone. The system prompt is followed by the\n\t * roots and how to name a file in them.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * With `workspace`, a summary of what was undone, from the provider's cheap model, in place\n\t * of the undone prompts. That is Claude Haiku without thinking, or `gpt-5.6-luna` at high\n\t * effort, and the call is billed with the run's tokens. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n\t/**\n\t * How many calls to the model one run may make before it fails. Defaults to 65, with no upper\n\t * bound. A run that asks for exactly the same tool calls 5 times in a row fails before that.\n\t */\n\tmaxSteps?: number;\n\t/**\n\t * The input tokens at which the provider compacts the conversation on its side: it replaces\n\t * every turn before that call with its own summary, which only its model reads back. The\n\t * conversation keeps every original turn. Without it, the conversation is never compacted.\n\t * At least 50,000 on Anthropic, where Claude Haiku cannot compact.\n\t */\n\tcompactAt?: number;\n\t/**\n\t * Runs every tool call without asking, `destructive` ones included, for CI where no one can\n\t * answer. Without it, a `destructive` call goes to the run's `approve`, or is denied.\n\t */\n\tautoApprove?: boolean;\n\t/** Defaults to warnings on stderr. */\n\tlogger?: ILogger;\n}\n\n/** A limit per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleSteps = Partial<Record<OrchestratorRole, number>>;\n\n/** A number of tokens per role of `createLLMOrchestrator`; a role left out keeps its default. */\nexport type RoleTokens = Partial<Record<OrchestratorRole, number>>;\n\n// The same three roles a command can be given to.\ntype OrchestratorRole = CommandRole;\n\n// The executor reads, edits and checks, so it needs more calls than the roles that only read.\nconst defaultRoleSteps: Record<OrchestratorRole, number> = {\n\tplanner: 65,\n\texecutor: 80,\n\treviewer: 65,\n};\n\n// No role compacts unless asked to.\nconst defaultRoleCompaction: Record<OrchestratorRole, number | undefined> = {\n\tplanner: undefined,\n\texecutor: undefined,\n\treviewer: undefined,\n};\n\n/**\n * Each role's value of the option `name`, from one number for all of them or a number per role.\n * Each number is checked by whatever takes it.\n *\n * @throws {InvalidAgentConfigError} for a value that is neither, and for a role that does not\n * exist, which is a typo that would otherwise leave that role on its default without a word.\n */\nfunction perRole<T extends number | undefined>(\n\tname: string,\n\tvalue: unknown,\n\tdefaults: Record<OrchestratorRole, T>,\n\t{ unit, example }: { unit: string; example: string },\n): Record<OrchestratorRole, T | number> {\n\tif (value === undefined) return defaults;\n\tif (typeof value === 'number') return { planner: value, executor: value, reviewer: value };\n\t// Untyped input, such as the CLI's configuration file, can hold `null` or a list here.\n\tif (typeof value !== 'object' || value === null || Array.isArray(value)) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} must be a number or an object of ${unit} per role, such as ${example}`,\n\t\t);\n\t}\n\tconst unknown = Object.keys(value).filter(role => !(role in defaults));\n\tif (unknown.length > 0) {\n\t\tthrow new InvalidAgentConfigError(\n\t\t\t`${name} names roles that do not exist: ${unknown.join(', ')}; expected planner, executor or reviewer`,\n\t\t);\n\t}\n\t// A role given as `undefined`, which untyped input can do, keeps its default.\n\tconst given = Object.entries(value as Record<string, unknown>).filter(\n\t\t([, each]) => each !== undefined,\n\t);\n\treturn { ...defaults, ...Object.fromEntries(given) };\n}\n\nexport interface CreateLLMOrchestratorOptions extends CreateOrchestratorOptions {\n\t/**\n\t * The folders the agents work on. The executor changes files only in a `write` root, every\n\t * change recorded in the workspace's history. Defaults to the current working directory,\n\t * read only.\n\t */\n\tworkspace?: WorkspaceOptions;\n\t/**\n\t * How many calls to the model one run of each role may make: one number for every role, or a\n\t * number per role. Defaults to 80 for the executor and 65 for the planner and the reviewer,\n\t * with no upper bound. A run that asks for exactly the same tool calls 5 times in a row fails\n\t * before its limit.\n\t */\n\tmaxSteps?: number | RoleSteps;\n\t/**\n\t * The input tokens at which each role's provider compacts its conversation, as\n\t * `CreateLLMAgentOptions.compactAt`: one number for every role, or a number per role. Without\n\t * it, no role compacts.\n\t */\n\tcompactAt?: number | RoleTokens;\n\t/**\n\t * Commands the roles may run, such as the project's tests, through `runCommand`. Each goes to\n\t * the roles its `roles` names, the executor by default. See `createFileTools`. Each needs a\n\t * `write` root to run in.\n\t */\n\tcommands?: Commands;\n\t/**\n\t * A summary of what the user undid, from the planner's provider's cheap model, for every\n\t * role. See `CreateLLMAgentOptions.summarizeUndone`. Defaults to `true`.\n\t */\n\tsummarizeUndone?: boolean;\n}\n\nconst defaultLLMAgentModels = {\n\tanthropic: 'sonnet',\n\topenai: 'gpt-5.6-luna',\n} as const satisfies Record<AgentProvider, AgentModel>;\n\nfunction unknownProvider(provider: never): InvalidAgentConfigError {\n\treturn new InvalidAgentConfigError(\n\t\t`\"${String(provider)}\" is not an agent provider; expected one of: ${agentProviders.join(', ')}`,\n\t);\n}\n\nfunction llmClientFor(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tcompactAt?: number | undefined;\n\t\tsystemPrompt: string;\n\t\tlogger: ILogger;\n\t},\n): LLMClient {\n\tswitch (provider) {\n\t\tcase 'anthropic':\n\t\t\treturn new ClaudeLLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.anthropic,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tcase 'openai':\n\t\t\treturn new OpenAILLMClient({\n\t\t\t\tmodel: model ?? defaultLLMAgentModels.openai,\n\t\t\t\treasoningEffort,\n\t\t\t\tcompactAt,\n\t\t\t\tsystemPrompt,\n\t\t\t\tlogger,\n\t\t\t});\n\t\tdefault:\n\t\t\t// Reachable from untyped input.\n\t\t\tthrow unknownProvider(provider);\n\t}\n}\n\n/** The provider's cheap model, for the summary of what was undone. */\nfunction summarizerFor(provider: AgentProvider, logger: ILogger): LLMClient {\n\treturn provider === 'anthropic'\n\t\t? new ClaudeLLMClient({ model: 'haiku', systemPrompt: '', logger })\n\t\t: new OpenAILLMClient({\n\t\t\t\tmodel: 'gpt-5.6-luna',\n\t\t\t\treasoningEffort: 'high',\n\t\t\t\tsystemPrompt: '',\n\t\t\t\tlogger,\n\t\t\t});\n}\n\n/**\n * The workspace's history, opened on first use, so a factory that builds an agent stays\n * synchronous. Every agent and every file tool of one workspace reads the same files on disk.\n */\nfunction historyOf(workspace: WorkspaceOptions): HistoryReader {\n\t// Checked now: an agent with no root to follow is a setup error, not a first-run one.\n\tif (workspace.roots.length === 0) {\n\t\tthrow new InvalidAgentConfigError('A workspace needs at least one root');\n\t}\n\tlet store: Promise<RecoveryStore> | undefined;\n\tconst open = () => {\n\t\tstore ??= stateDirectoryOf(workspace)\n\t\t\t.then(directory => openStore(workspace, directory))\n\t\t\t.catch((error: unknown) => {\n\t\t\t\t// Not kept: the next run tries again, as one whose disk was full for a moment.\n\t\t\t\tstore = undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\treturn store;\n\t};\n\treturn {\n\t\tlistRuns: async () => (await open()).listRuns(),\n\t\tlistRevisions: async () => (await open()).listRevisions(),\n\t\treadRun: async runId => (await open()).readRun(runId),\n\t};\n}\n\n/**\n * What the model is told about the workspace after its instructions: the roots, which it may\n * change, and how to name a file. A host path in an error sends the model looking for it, so\n * the real root is given here once.\n */\nfunction workspaceGuidance(roots: WorkspaceRoot[]): string {\n\tconst [first, ...others] = roots.map(root => ({ ...root, path: resolve(root.path) }));\n\tif (!first) return '';\n\tconst described = [first, ...others].map(\n\t\t({ path, access }) => `- ${path}${access === 'write' ? '' : ' (read only)'}`,\n\t);\n\treturn [\n\t\t'The workspace:',\n\t\t...described,\n\t\t`Name a file by its path relative to ${first.path}, such as src/index.ts, and a file in another folder of the workspace by its full path. Read a file before you change it.`,\n\t].join('\\n');\n}\n\nfunction withGuidance(systemPrompt: string, guidance: string): string {\n\treturn guidance === '' ? systemPrompt : `${systemPrompt}\\n\\n${guidance}`;\n}\n\n/** An `LLMAgent` on `provider`, wrapped in the harness's retry policy. */\nfunction buildLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools,\n\t\thistory,\n\t\tsummarizer,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t}: {\n\t\tmodel?: AgentModel;\n\t\treasoningEffort?: ReasoningEffort;\n\t\tsystemPrompt: string;\n\t\ttools: AgentTool[];\n\t\thistory?: HistoryReader;\n\t\tsummarizer?: LLMClient;\n\t\tmaxSteps?: number;\n\t\tcompactAt?: number | undefined;\n\t\tautoApprove?: boolean;\n\t\tlogger: ILogger;\n\t},\n): Agent {\n\tconst llmClient = llmClientFor(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tcompactAt,\n\t\tsystemPrompt,\n\t\tlogger,\n\t});\n\t// LLMAgent records nothing from a failed call, so the original prompt is the whole story.\n\treturn new RetryingAgent({\n\t\tinner: new LLMAgent({\n\t\t\tllmClient,\n\t\t\ttools,\n\t\t\tautoApprove,\n\t\t\tlogger,\n\t\t\t...(history ? { history } : {}),\n\t\t\t...(summarizer ? { summarizer } : {}),\n\t\t\t...(maxSteps === undefined ? {} : { maxSteps }),\n\t\t}),\n\t\tlogger,\n\t\tnoteFailures: false,\n\t});\n}\n\n/**\n * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in\n * the harness's retry policy. It needs the provider's API key and bills per token, where\n * `createAgent` uses the Agent SDK's login. Each tool judges the risk of each call; a\n * `destructive` one runs only when the run's `approve` allows it, or with `autoApprove`.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a model or reasoning effort its\n * client does not support, or two tools that share a name.\n * @throws {UnrecoverableError} when the client cannot be set up, for example because\n * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing\n * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.\n */\nexport function createLLMAgent(\n\tprovider: AgentProvider,\n\t{\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt,\n\t\ttools = [],\n\t\tworkspace,\n\t\tsummarizeUndone = true,\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger = new Logger(),\n\t}: CreateLLMAgentOptions,\n): Agent {\n\treturn buildLLMAgent(provider, {\n\t\tmodel,\n\t\treasoningEffort,\n\t\tsystemPrompt: workspace\n\t\t\t? withGuidance(systemPrompt, workspaceGuidance(workspace.roots))\n\t\t\t: systemPrompt,\n\t\t// A file tool is a harness tool under its public name.\n\t\ttools: tools as AgentTool[],\n\t\t...(workspace ? { history: historyOf(workspace) } : {}),\n\t\t...(workspace && summarizeUndone ? { summarizer: summarizerFor(provider, logger) } : {}),\n\t\tmaxSteps,\n\t\tcompactAt,\n\t\tautoApprove,\n\t\tlogger,\n\t});\n}\n\n/**\n * The file tools for an agent from `createLLMAgent` on `provider`, over `workspace`, in the\n * provider's own format:\n *\n * - OpenAI: `listFiles`, `searchText`, `readFile` and its native `apply_patch`;\n * - Anthropic: `listFiles`, `searchText`, its native text editor, whose `view` reads, and\n * `delete_file`.\n *\n * Every one goes through the workspace's access policy: a path outside the roots, a secret,\n * a file `.gitignore` excludes or the harness protects is refused. A change is made only in a\n * `write` root, only from a version the agent read, and is recorded in the workspace's history,\n * so it can be undone. Without a `write` root the tools only read. Give the agent the same\n * `workspace`, so it follows what the history undoes.\n *\n * With `commands`, they include `runCommand`, which runs one of them by name, with only the\n * parameters it declares and never through a shell. Each run asks the approver, showing the\n * program exactly as it will run, and gets a small environment without the provider keys. The\n * files of the `write` roots are captured before it and compared after, so what it changed is\n * in the history too. It is trusted execution, not a sandbox: a command can reach whatever\n * this user can. Not supported on Windows yet.\n *\n * @throws {InvalidAgentConfigError} for an unknown provider, a workspace with no root, or an\n * invalid command, including one whose `cwd` is not in a `write` root, or any on 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{ logger = new Logger(), commands }: { logger?: ILogger; commands?: Commands } = {},\n): Promise<FileTool[]> {\n\t// Reachable from untyped input.\n\tif (!isAgentProvider(provider)) throw unknownProvider(provider);\n\tif (commands !== undefined) validateCommands(commands);\n\tconst opened = await openWorkspace(workspace, logger);\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/**\n * What the planner and the reviewer read with: no edits, the current task's changes, and the\n * commands given to their role.\n */\nasync function readingTools(\n\tworkspace: OpenedWorkspace,\n\trole: CommandRole,\n\tcommands: Commands | undefined,\n): Promise<AgentTool[]> {\n\tconst { read, policy, store } = workspace;\n\tconst finding = createWorkspaceTools(read).filter(tool => tool.name !== 'readFile');\n\tconst tools = [\n\t\t...finding,\n\t\tcreateTrackedReadFile(policy),\n\t\tcreateShowChangesTool({ store, policy }),\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\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. ${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. ${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`, and\n * `showChanges`, the current task's changes as far as each may read them.\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 * - The executor is told to finish only once the tests and checks pass, and the reviewer that\n * they passed, when the executor has a command; without one, both are told the tests were\n * not run, and the reviewer judges from the code whether 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\tsummarizeUndone = true,\n\tlogger = new Logger(),\n}: CreateLLMOrchestratorOptions = {}): Promise<Agent> {\n\tconst roles = orchestratorRolesFor(provider);\n\tconst steps = perRole('maxSteps', maxSteps, defaultRoleSteps, {\n\t\tunit: 'steps',\n\t\texample: '{ \"executor\": 120 }',\n\t});\n\tconst compaction = perRole('compactAt', compactAt, defaultRoleCompaction, {\n\t\tunit: 'tokens',\n\t\texample: '{ \"executor\": 200000 }',\n\t});\n\tconst opened = await openWorkspace(workspace, logger);\n\tconst guidance = workspaceGuidance(workspace.roots);\n\tconst summarizer = summarizeUndone ? summarizerFor(roles.planner.provider, logger) : undefined;\n\tconst shared = { history: opened.store, ...(summarizer ? { summarizer } : {}), logger };\n\t// A caller's own prompt replaces our instructions and guidance, not the workspace: the model\n\t// needs the roots to name a file, as `createLLMAgent` gives them.\n\tconst prompt = (role: CommandRole, own: string | undefined, instructions: string) =>\n\t\town === undefined\n\t\t\t? withGuidance(instructions, `${guidance}\\n${repositoryGuidance[role]}`)\n\t\t\t: withGuidance(own, guidance);\n\t// Every command, checked once, before any role takes its share.\n\tif (commands !== undefined) validateCommands(commands);\n\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),\n\t\t\tmaxSteps: steps[role],\n\t\t\tcompactAt: compaction[role],\n\t\t\t...shared,\n\t\t});\n\tconst { executor } = roles;\n\tconst executorToolset = await executorTools(\n\t\texecutor.provider,\n\t\topened,\n\t\tcommands && commandsFor(commands, 'executor'),\n\t);\n\t// The executor and the reviewer are told whether the tests were run, which only an executor\n\t// with a command can do.\n\tconst executorRuns = executorToolset.some(tool => tool.name === 'runCommand');\n\n\treturn new OrchestratorAgent({\n\t\tplannerAgent: await reader(\n\t\t\troles.planner,\n\t\t\t'planner',\n\t\t\tprompt('planner', systemPrompts.planner, plannerInstructions),\n\t\t),\n\t\texecutorAgent: buildLLMAgent(executor.provider, {\n\t\t\tmodel: executor.model,\n\t\t\treasoningEffort: executor.reasoningEffort,\n\t\t\tsystemPrompt: prompt(\n\t\t\t\t'executor',\n\t\t\t\tsystemPrompts.executor,\n\t\t\t\texecutorRuns ? executorInstructions : executorInstructionsWithoutCommands,\n\t\t\t),\n\t\t\ttools: executorToolset,\n\t\t\tmaxSteps: steps.executor,\n\t\t\tcompactAt: compaction.executor,\n\t\t\tautoApprove,\n\t\t\t...shared,\n\t\t}),\n\t\treviewerAgent: await reader(\n\t\t\troles.reviewer,\n\t\t\t'reviewer',\n\t\t\tprompt(\n\t\t\t\t'reviewer',\n\t\t\t\tsystemPrompts.reviewer,\n\t\t\t\texecutorRuns ? reviewerInstructions : reviewerInstructionsWithoutCommands,\n\t\t\t),\n\t\t),\n\t\treviewerDecisionValidator: new ReviewerDecisionValidator(),\n\t\tlogger,\n\t});\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export type { ILogger } from './shared/domain/logger.ts';
2
2
  export { createAgent, createOrchestrator, agentModels, agentReasoningEfforts, isAgentProvider, isModelOf, isReasoningEffortOf, type CreateAgentOptions, } from './factory/infrastructure/agentFactory.ts';
3
- export { createFileTools, createLLMAgent, createLLMOrchestrator, isLLMModelOf, isLLMReasoningEffortOf, llmModels, llmReasoningEfforts, type CreateLLMAgentOptions, type CreateLLMOrchestratorOptions, type RoleSteps, } from './factory/infrastructure/agentLLMFactory.ts';
3
+ export { createFileTools, createLLMAgent, createLLMOrchestrator, isLLMModelOf, isLLMReasoningEffortOf, llmModels, llmReasoningEfforts, type CreateLLMAgentOptions, type CreateLLMOrchestratorOptions, type RoleSteps, type RoleTokens, } from './factory/infrastructure/agentLLMFactory.ts';
4
4
  export type { FileTool, WorkspaceOptions } from './tools/infrastructure/fileTools.ts';
5
5
  export type { WorkspaceRoot } from './tools/domain/accessPolicy.ts';
6
6
  export type { CommandArgument, CommandDefinition, CommandParameter, CommandRole, Commands, } from './tools/domain/commands.ts';
@@ -11,6 +11,7 @@ export { InvalidAgentConfigError, RecoverableError, UnrecoverableError, } from '
11
11
  export { isAbortError } from './shared/domain/isAbortError.ts';
12
12
  export type { Tokens } from './shared/domain/tokens.ts';
13
13
  export { rememberApprovals, type ApprovalDecision, type ApprovalRequest, type Approver, type CommandLine, type RememberableDecision, type ToolRisk, } from './agent/domain/approval.ts';
14
+ export type { Asker, QuestionOption, UserQuestion } from './agent/domain/question.ts';
14
15
  export type { JSONSchema, ToolDefinition } from './llm/domain/tool.ts';
15
16
  export type { Tool, ToolSummarizer } from './tools/domain/tool.ts';
16
17
  export type { TextMatch, Workspace } from './tools/domain/workspace.ts';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,eAAe,EACf,SAAS,EACT,mBAAmB,GAEnB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACN,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,EACtB,SAAS,EACT,mBAAmB,GAInB,MAAM,6CAA6C,CAAC;AAWrD,OAAO,EACN,cAAc,GAKd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAQN,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EACN,iBAAiB,GAOjB,MAAM,4BAA4B,CAAC;AAIpC,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GAGnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["export type { ILogger } from './shared/domain/logger.ts';\nexport {\n\tcreateAgent,\n\tcreateOrchestrator,\n\tagentModels,\n\tagentReasoningEfforts,\n\tisAgentProvider,\n\tisModelOf,\n\tisReasoningEffortOf,\n\ttype CreateAgentOptions,\n} from './factory/infrastructure/agentFactory.ts';\nexport {\n\tcreateFileTools,\n\tcreateLLMAgent,\n\tcreateLLMOrchestrator,\n\tisLLMModelOf,\n\tisLLMReasoningEffortOf,\n\tllmModels,\n\tllmReasoningEfforts,\n\ttype CreateLLMAgentOptions,\n\ttype CreateLLMOrchestratorOptions,\n\ttype RoleSteps,\n} from './factory/infrastructure/agentLLMFactory.ts';\nexport type { FileTool, WorkspaceOptions } from './tools/infrastructure/fileTools.ts';\nexport type { WorkspaceRoot } from './tools/domain/accessPolicy.ts';\nexport type {\n\tCommandArgument,\n\tCommandDefinition,\n\tCommandParameter,\n\tCommandRole,\n\tCommands,\n} from './tools/domain/commands.ts';\nexport type { SecretRules } from './tools/infrastructure/rootsAccessPolicy.ts';\nexport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './factory/infrastructure/types.ts';\nexport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressAgent,\n\ttype ProgressEvent,\n\ttype StepContext,\n\ttype RunOptions,\n} from './agent/domain/agent.ts';\nexport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n} from './shared/domain/errors.ts';\nexport { isAbortError } from './shared/domain/isAbortError.ts';\nexport type { Tokens } from './shared/domain/tokens.ts';\nexport {\n\trememberApprovals,\n\ttype ApprovalDecision,\n\ttype ApprovalRequest,\n\ttype Approver,\n\ttype CommandLine,\n\ttype RememberableDecision,\n\ttype ToolRisk,\n} from './agent/domain/approval.ts';\nexport type { JSONSchema, ToolDefinition } from './llm/domain/tool.ts';\nexport type { Tool, ToolSummarizer } from './tools/domain/tool.ts';\nexport type { TextMatch, Workspace } from './tools/domain/workspace.ts';\nexport { defineTool } from './tools/infrastructure/defineTool.ts';\nexport { createWorkspace } from './tools/infrastructure/createWorkspace.ts';\nexport { createWorkspaceTools } from './tools/infrastructure/workspaceTools.ts';\nexport { createHistory } from './recovery/infrastructure/createHistory.ts';\nexport type { History, HistoryRun, Move } from './recovery/domain/history.ts';\nexport {\n\thistoryStart,\n\tNothingToMoveError,\n\tWorkspaceBusyError,\n\tWorkspaceMovedError,\n\ttype MoveOptions,\n\ttype RunStatus,\n} from './recovery/domain/recoveryStore.ts';\nexport { HistoryExpiredError, UnknownRunError } from './recovery/domain/runTree.ts';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,eAAe,EACf,SAAS,EACT,mBAAmB,GAEnB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACN,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,EACtB,SAAS,EACT,mBAAmB,GAKnB,MAAM,6CAA6C,CAAC;AAWrD,OAAO,EACN,cAAc,GAKd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAQN,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EACN,iBAAiB,GAOjB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GAGnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["export type { ILogger } from './shared/domain/logger.ts';\nexport {\n\tcreateAgent,\n\tcreateOrchestrator,\n\tagentModels,\n\tagentReasoningEfforts,\n\tisAgentProvider,\n\tisModelOf,\n\tisReasoningEffortOf,\n\ttype CreateAgentOptions,\n} from './factory/infrastructure/agentFactory.ts';\nexport {\n\tcreateFileTools,\n\tcreateLLMAgent,\n\tcreateLLMOrchestrator,\n\tisLLMModelOf,\n\tisLLMReasoningEffortOf,\n\tllmModels,\n\tllmReasoningEfforts,\n\ttype CreateLLMAgentOptions,\n\ttype CreateLLMOrchestratorOptions,\n\ttype RoleSteps,\n\ttype RoleTokens,\n} from './factory/infrastructure/agentLLMFactory.ts';\nexport type { FileTool, WorkspaceOptions } from './tools/infrastructure/fileTools.ts';\nexport type { WorkspaceRoot } from './tools/domain/accessPolicy.ts';\nexport type {\n\tCommandArgument,\n\tCommandDefinition,\n\tCommandParameter,\n\tCommandRole,\n\tCommands,\n} from './tools/domain/commands.ts';\nexport type { SecretRules } from './tools/infrastructure/rootsAccessPolicy.ts';\nexport {\n\tagentProviders,\n\ttype AgentModel,\n\ttype AgentProvider,\n\ttype CreateOrchestratorOptions,\n\ttype ReasoningEffort,\n} from './factory/infrastructure/types.ts';\nexport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressAgent,\n\ttype ProgressEvent,\n\ttype StepContext,\n\ttype RunOptions,\n} from './agent/domain/agent.ts';\nexport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n} from './shared/domain/errors.ts';\nexport { isAbortError } from './shared/domain/isAbortError.ts';\nexport type { Tokens } from './shared/domain/tokens.ts';\nexport {\n\trememberApprovals,\n\ttype ApprovalDecision,\n\ttype ApprovalRequest,\n\ttype Approver,\n\ttype CommandLine,\n\ttype RememberableDecision,\n\ttype ToolRisk,\n} from './agent/domain/approval.ts';\nexport type { Asker, QuestionOption, UserQuestion } from './agent/domain/question.ts';\nexport type { JSONSchema, ToolDefinition } from './llm/domain/tool.ts';\nexport type { Tool, ToolSummarizer } from './tools/domain/tool.ts';\nexport type { TextMatch, Workspace } from './tools/domain/workspace.ts';\nexport { defineTool } from './tools/infrastructure/defineTool.ts';\nexport { createWorkspace } from './tools/infrastructure/createWorkspace.ts';\nexport { createWorkspaceTools } from './tools/infrastructure/workspaceTools.ts';\nexport { createHistory } from './recovery/infrastructure/createHistory.ts';\nexport type { History, HistoryRun, Move } from './recovery/domain/history.ts';\nexport {\n\thistoryStart,\n\tNothingToMoveError,\n\tWorkspaceBusyError,\n\tWorkspaceMovedError,\n\ttype MoveOptions,\n\ttype RunStatus,\n} from './recovery/domain/recoveryStore.ts';\nexport { HistoryExpiredError, UnknownRunError } from './recovery/domain/runTree.ts';\n"]}
@@ -18,8 +18,8 @@ export interface LLMClient {
18
18
  /** The system prompt every call sends, for measuring what a call carries. */
19
19
  readonly systemPrompt?: string;
20
20
  /**
21
- * The `source` of the `providerData` this client sends back; it drops every other. For
22
- * measuring what a call carries.
21
+ * The `source` of the `providerData` and `compaction` parts this client sends back; it drops
22
+ * every other. For measuring what a call carries.
23
23
  */
24
24
  readonly providerDataSource?: string;
25
25
  /** Whether this client can declare a native tool. Missing means it declares none. */
@@ -1 +1 @@
1
- {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/llm/domain/llm.ts"],"names":[],"mappings":"","sourcesContent":["import type { Tokens } from '#src/shared/domain/tokens';\nimport type { Message } from './message.ts';\nimport type { NativeTool, ToolDefinition } from './tool.ts';\n\nexport type StopReason = 'completed' | 'truncated' | 'refused';\n\nexport interface LLMResponse {\n\tmessage: Message & { role: 'assistant' };\n\t/**\n\t * Missing when the provider did not report it. The call was made and may have been billed,\n\t * so the agent keeps the answer and only its tokens become unknown; a failure raised from\n\t * such a response is marked `usageUnreported`.\n\t */\n\tusage: Tokens | undefined;\n\tstopReason: StopReason;\n}\n\nexport interface LLMClient {\n\t/** The system prompt every call sends, for measuring what a call carries. */\n\treadonly systemPrompt?: string;\n\t/**\n\t * The `source` of the `providerData` this client sends back; it drops every other. For\n\t * measuring what a call carries.\n\t */\n\treadonly providerDataSource?: string;\n\t/** Whether this client can declare a native tool. Missing means it declares none. */\n\tsupportsNative?(tool: NativeTool): boolean;\n\tsend(\n\t\t{ context, tools }: { context: Message[]; tools: ToolDefinition[] },\n\t\tsignal: AbortSignal,\n\t): Promise<LLMResponse>;\n}\n"]}
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/llm/domain/llm.ts"],"names":[],"mappings":"","sourcesContent":["import type { Tokens } from '#src/shared/domain/tokens';\nimport type { Message } from './message.ts';\nimport type { NativeTool, ToolDefinition } from './tool.ts';\n\nexport type StopReason = 'completed' | 'truncated' | 'refused';\n\nexport interface LLMResponse {\n\tmessage: Message & { role: 'assistant' };\n\t/**\n\t * Missing when the provider did not report it. The call was made and may have been billed,\n\t * so the agent keeps the answer and only its tokens become unknown; a failure raised from\n\t * such a response is marked `usageUnreported`.\n\t */\n\tusage: Tokens | undefined;\n\tstopReason: StopReason;\n}\n\nexport interface LLMClient {\n\t/** The system prompt every call sends, for measuring what a call carries. */\n\treadonly systemPrompt?: string;\n\t/**\n\t * The `source` of the `providerData` and `compaction` parts this client sends back; it drops\n\t * every other. For measuring what a call carries.\n\t */\n\treadonly providerDataSource?: string;\n\t/** Whether this client can declare a native tool. Missing means it declares none. */\n\tsupportsNative?(tool: NativeTool): boolean;\n\tsend(\n\t\t{ context, tools }: { context: Message[]; tools: ToolDefinition[] },\n\t\tsignal: AbortSignal,\n\t): Promise<LLMResponse>;\n}\n"]}
@@ -1,4 +1,4 @@
1
- export type MessagePart = TextPart | ReasoningPart | ToolCallPart | ToolResultPart | ProviderDataPart;
1
+ export type MessagePart = TextPart | ReasoningPart | ToolCallPart | ToolResultPart | ProviderDataPart | CompactionPart;
2
2
  export interface TextPart {
3
3
  type: 'text';
4
4
  text: string;
@@ -31,7 +31,23 @@ export interface ProviderDataPart {
31
31
  source: string;
32
32
  data: unknown;
33
33
  }
34
+ /**
35
+ * A provider's own summary of everything before it, written when its context passed the
36
+ * client's `compactAt`. Like `ProviderDataPart`, only the client labelled `source` reads it
37
+ * back: that client sends the conversation from its latest compaction on, and every other client
38
+ * leaves the part out and sends the conversation whole, which the conversation still holds.
39
+ */
40
+ export interface CompactionPart {
41
+ type: 'compaction';
42
+ source: string;
43
+ data: unknown;
44
+ }
34
45
  export interface Message {
35
46
  role: 'user' | 'assistant' | 'tool';
36
47
  content: MessagePart[];
37
48
  }
49
+ /**
50
+ * What the client labelled `source` sends of `context`: everything from its latest compaction
51
+ * on, that compaction included, or the whole context when it has none.
52
+ */
53
+ export declare function sentContext(context: Message[], source: string | undefined): Message[];
@@ -1,2 +1,15 @@
1
- export {};
1
+ /**
2
+ * What the client labelled `source` sends of `context`: everything from its latest compaction
3
+ * on, that compaction included, or the whole context when it has none.
4
+ */
5
+ export function sentContext(context, source) {
6
+ for (let index = context.length - 1; index >= 0; index--) {
7
+ const message = context[index];
8
+ const at = message?.content.findLastIndex(part => part.type === 'compaction' && part.source === source) ?? -1;
9
+ if (message && at !== -1) {
10
+ return [{ ...message, content: message.content.slice(at) }, ...context.slice(index + 1)];
11
+ }
12
+ }
13
+ return context;
14
+ }
2
15
  //# sourceMappingURL=message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/llm/domain/message.ts"],"names":[],"mappings":"","sourcesContent":["export type MessagePart =\n\tTextPart | ReasoningPart | ToolCallPart | ToolResultPart | ProviderDataPart;\n\nexport interface TextPart {\n\ttype: 'text';\n\ttext: string;\n}\n\nexport interface ReasoningPart {\n\ttype: 'reasoning';\n\ttext: string;\n}\n\nexport interface ToolCallPart {\n\tid: string;\n\ttype: 'toolCall';\n\tname: string;\n\tinput: unknown;\n}\n\nexport interface ToolResultPart {\n\tcallId: string;\n\ttype: 'toolResult';\n\tname: string;\n\toutput: string;\n\tisError: boolean;\n}\n\n/**\n * A block only the client that produced it can read back, such as signed or encrypted\n * reasoning, kept whole so that client can send it again on the next call. `source` is the\n * client's own label and the domain gives it no meaning: every other client leaves the part out.\n * `data` must stay plain JSON, since the conversation is copied and will be persisted.\n */\nexport interface ProviderDataPart {\n\ttype: 'providerData';\n\tsource: string;\n\tdata: unknown;\n}\n\nexport interface Message {\n\trole: 'user' | 'assistant' | 'tool';\n\tcontent: MessagePart[];\n}\n"]}
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/llm/domain/message.ts"],"names":[],"mappings":"AAyDA;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAkB,EAAE,MAA0B;IACzE,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,EAAE,GACP,OAAO,EAAE,OAAO,CAAC,aAAa,CAC7B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAC5D,IAAI,CAAC,CAAC,CAAC;QACT,IAAI,OAAO,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1F,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["export type MessagePart =\n\tTextPart | ReasoningPart | ToolCallPart | ToolResultPart | ProviderDataPart | CompactionPart;\n\nexport interface TextPart {\n\ttype: 'text';\n\ttext: string;\n}\n\nexport interface ReasoningPart {\n\ttype: 'reasoning';\n\ttext: string;\n}\n\nexport interface ToolCallPart {\n\tid: string;\n\ttype: 'toolCall';\n\tname: string;\n\tinput: unknown;\n}\n\nexport interface ToolResultPart {\n\tcallId: string;\n\ttype: 'toolResult';\n\tname: string;\n\toutput: string;\n\tisError: boolean;\n}\n\n/**\n * A block only the client that produced it can read back, such as signed or encrypted\n * reasoning, kept whole so that client can send it again on the next call. `source` is the\n * client's own label and the domain gives it no meaning: every other client leaves the part out.\n * `data` must stay plain JSON, since the conversation is copied and will be persisted.\n */\nexport interface ProviderDataPart {\n\ttype: 'providerData';\n\tsource: string;\n\tdata: unknown;\n}\n\n/**\n * A provider's own summary of everything before it, written when its context passed the\n * client's `compactAt`. Like `ProviderDataPart`, only the client labelled `source` reads it\n * back: that client sends the conversation from its latest compaction on, and every other client\n * leaves the part out and sends the conversation whole, which the conversation still holds.\n */\nexport interface CompactionPart {\n\ttype: 'compaction';\n\tsource: string;\n\tdata: unknown;\n}\n\nexport interface Message {\n\trole: 'user' | 'assistant' | 'tool';\n\tcontent: MessagePart[];\n}\n\n/**\n * What the client labelled `source` sends of `context`: everything from its latest compaction\n * on, that compaction included, or the whole context when it has none.\n */\nexport function sentContext(context: Message[], source: string | undefined): Message[] {\n\tfor (let index = context.length - 1; index >= 0; index--) {\n\t\tconst message = context[index];\n\t\tconst at =\n\t\t\tmessage?.content.findLastIndex(\n\t\t\t\tpart => part.type === 'compaction' && part.source === source,\n\t\t\t) ?? -1;\n\t\tif (message && at !== -1) {\n\t\t\treturn [{ ...message, content: message.content.slice(at) }, ...context.slice(index + 1)];\n\t\t}\n\t}\n\treturn context;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { ILogger } from '#src/shared/domain/logger';
2
2
  import type { LLMClient, LLMResponse } from '../domain/llm.ts';
3
- import type { Message } from '../domain/message.ts';
3
+ import { type Message } from '../domain/message.ts';
4
4
  import { type NativeTool, type ToolDefinition } from '../domain/tool.ts';
5
5
  export declare const claudeLLMModels: readonly ["opus", "fable", "sonnet", "haiku"];
6
6
  export type ClaudeLLMModel = (typeof claudeLLMModels)[number];
@@ -14,12 +14,15 @@ export declare class ClaudeLLMClient implements LLMClient {
14
14
  private readonly client;
15
15
  private readonly model;
16
16
  private readonly reasoningEffort;
17
+ private readonly compactAt;
17
18
  readonly systemPrompt: string;
18
19
  readonly providerDataSource = "claude";
19
20
  private readonly logger;
20
- constructor({ model, reasoningEffort, systemPrompt, logger, }: {
21
+ constructor({ model, reasoningEffort, compactAt, systemPrompt, logger, }: {
21
22
  model: string;
22
23
  reasoningEffort?: string;
24
+ /** The input tokens at which Anthropic compacts the context on its side. Without it, never. */
25
+ compactAt?: number | undefined;
23
26
  systemPrompt: string;
24
27
  logger: ILogger;
25
28
  });
@@ -3,6 +3,7 @@ import { InvalidAgentConfigError, UnrecoverableError, withSpentTokens, } from '#
3
3
  import { classifyHostFailure, classifyLocalFailure, classifyProviderFailure, describeFailure, treatErrors, } from '#src/shared/domain/providerFailure';
4
4
  import { isOneOf } from '#src/shared/domain/isOneOf';
5
5
  import { MaxContextError } from "../domain/errors.js";
6
+ import { sentContext } from "../domain/message.js";
6
7
  import { nativeOf } from "../domain/tool.js";
7
8
  // The Messages API takes full model IDs. Callers name a model by the Agent SDK's alias, so both
8
9
  // paths share one vocabulary; this table pins the ID each alias means here, and moves by hand
@@ -32,6 +33,9 @@ const unrecoverableStatuses = [400, 401, 403, 404, 413, 422];
32
33
  const unrecoverableErrorTypes = ['billing_error', 'authentication_error', 'permission_error'];
33
34
  // This client's label on the thinking blocks it keeps for replay; see `ProviderDataPart`.
34
35
  const claudeSource = 'claude';
36
+ // Anthropic's compaction at a token threshold, and the least threshold it accepts.
37
+ const compactionBeta = 'compact-2026-01-12';
38
+ const minCompactAt = 50_000;
35
39
  /**
36
40
  * Anthropic rejects a `tool_use` whose input is not an object, with a 400 on every later call.
37
41
  * Another provider's call can hold anything else, such as OpenAI arguments that did not parse;
@@ -64,6 +68,9 @@ function toClaudeBlocks(part) {
64
68
  return part.source === claudeSource
65
69
  ? [part.data]
66
70
  : [];
71
+ case 'compaction':
72
+ // Another provider's summary means nothing here; this client sends the turns it replaced.
73
+ return part.source === claudeSource ? [part.data] : [];
67
74
  case 'reasoning':
68
75
  // Unsigned text cannot be replayed as thinking. The API accepts a turn without it.
69
76
  return [];
@@ -122,6 +129,15 @@ function describeBlock(block, logger) {
122
129
  }
123
130
  case 'tool_use':
124
131
  return [{ type: 'toolCall', id: block.id, name: block.name, input: block.input }];
132
+ case 'compaction': {
133
+ // Claude's summary of the context before it, readable, with what it alone reads back.
134
+ const compaction = {
135
+ type: 'compaction',
136
+ content: block.content,
137
+ encrypted_content: block.encrypted_content,
138
+ };
139
+ return [{ type: 'compaction', source: claudeSource, data: compaction }];
140
+ }
125
141
  default:
126
142
  // Server tools are never offered, so any other block is output this client does not expect.
127
143
  treatErrors(() => {
@@ -152,7 +168,10 @@ function toStopReason(response) {
152
168
  });
153
169
  }
154
170
  }
155
- /** Unlike OpenAI, Anthropic counts cache reads and writes apart from `input_tokens`. */
171
+ /**
172
+ * Unlike OpenAI, Anthropic counts cache reads and writes apart from `input_tokens`. A call that
173
+ * compacted leaves the compaction out of its totals, so with iterations their sum is the bill.
174
+ */
156
175
  function toTokens(usage, logger) {
157
176
  if (!usage) {
158
177
  // Zeros would report a call that may have been billed as free.
@@ -161,6 +180,14 @@ function toTokens(usage, logger) {
161
180
  }, classifyHostFailure, 'Claude client logger failed while reading usage');
162
181
  return undefined;
163
182
  }
183
+ if (usage.iterations && usage.iterations.length > 0) {
184
+ return usage.iterations.reduce((sum, iteration) => ({
185
+ inputTokens: sum.inputTokens + iteration.input_tokens,
186
+ readCacheTokens: sum.readCacheTokens + iteration.cache_read_input_tokens,
187
+ writtenCacheTokens: sum.writtenCacheTokens + iteration.cache_creation_input_tokens,
188
+ outputTokens: sum.outputTokens + iteration.output_tokens,
189
+ }), { inputTokens: 0, readCacheTokens: 0, writtenCacheTokens: 0, outputTokens: 0 });
190
+ }
164
191
  return {
165
192
  inputTokens: usage.input_tokens,
166
193
  readCacheTokens: usage.cache_read_input_tokens ?? 0,
@@ -231,12 +258,13 @@ export class ClaudeLLMClient {
231
258
  model;
232
259
  // Missing for Haiku, which runs without thinking.
233
260
  reasoningEffort;
261
+ compactAt;
234
262
  systemPrompt;
235
263
  providerDataSource = claudeSource;
236
264
  logger;
237
265
  // `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows
238
266
  // what Claude supports.
239
- constructor({ model, reasoningEffort, systemPrompt, logger, }) {
267
+ constructor({ model, reasoningEffort, compactAt, systemPrompt, logger, }) {
240
268
  if (!isOneOf(claudeLLMModels, model)) {
241
269
  throw new InvalidAgentConfigError(`"${model}" is not a Claude API model; expected one of: ${claudeLLMModels.join(', ')}`);
242
270
  }
@@ -247,6 +275,15 @@ export class ClaudeLLMClient {
247
275
  if (effort !== undefined && !isOneOf(claudeLLMReasoningEfforts, effort)) {
248
276
  throw new InvalidAgentConfigError(`"${effort}" is not a Claude API reasoning effort; expected one of: ${claudeLLMReasoningEfforts.join(', ')}`);
249
277
  }
278
+ if (compactAt !== undefined) {
279
+ // The alias names Claude Haiku 4.5, which Anthropic does not compact.
280
+ if (model === 'haiku') {
281
+ throw new InvalidAgentConfigError('Claude Haiku cannot compact: leave compactAt out');
282
+ }
283
+ if (!(Number.isInteger(compactAt) && compactAt >= minCompactAt)) {
284
+ throw new InvalidAgentConfigError(`compactAt must be a whole number of tokens of at least ${String(minCompactAt)} on Claude, not ${String(compactAt)}`);
285
+ }
286
+ }
250
287
  try {
251
288
  // The SDK's default retries stay on, as OpenAI's do. See "The provider SDKs keep their
252
289
  // transport retries under RetryingAgent" in decisions.md.
@@ -261,6 +298,7 @@ export class ClaudeLLMClient {
261
298
  }
262
299
  this.model = claudeLLMModelIds[model];
263
300
  this.reasoningEffort = effort;
301
+ this.compactAt = compactAt;
264
302
  this.systemPrompt = systemPrompt;
265
303
  this.logger = logger;
266
304
  }
@@ -270,11 +308,17 @@ export class ClaudeLLMClient {
270
308
  async send({ context, tools }, signal) {
271
309
  let response;
272
310
  try {
273
- response = await this.client.messages.create({
311
+ response = await this.client.beta.messages.create({
274
312
  model: this.model,
275
313
  max_tokens: maxOutputTokens,
276
- system: this.systemPrompt,
277
- messages: context.flatMap(toClaudeInput),
314
+ // A compaction changes the conversation's first block, so the cache would otherwise
315
+ // keep nothing: this keeps the system prompt cached across it. The API rejects an
316
+ // empty text block, and an empty prompt has nothing to cache.
317
+ system: this.compactAt === undefined || this.systemPrompt === ''
318
+ ? this.systemPrompt
319
+ : [{ type: 'text', text: this.systemPrompt, cache_control: { type: 'ephemeral' } }],
320
+ // The latest compaction carries everything before it, which Anthropic would only ignore.
321
+ messages: sentContext(context, claudeSource).flatMap(toClaudeInput),
278
322
  // Left out when empty, so a request without tools stays as it always was.
279
323
  ...(tools.length > 0 && { tools: tools.map(toClaudeTool) }),
280
324
  // Haiku has no adaptive thinking, and an effort is refused with a 400.
@@ -285,6 +329,18 @@ export class ClaudeLLMClient {
285
329
  // Anthropic caches only on request. This marks the last block, so the next call
286
330
  // reads everything before it from the cache instead of paying for it again.
287
331
  cache_control: { type: 'ephemeral' },
332
+ // Anthropic compacts inside the call that passes it, and answers with the compaction first.
333
+ ...(this.compactAt !== undefined && {
334
+ betas: [compactionBeta],
335
+ context_management: {
336
+ edits: [
337
+ {
338
+ type: 'compact_20260112',
339
+ trigger: { type: 'input_tokens', value: this.compactAt },
340
+ },
341
+ ],
342
+ },
343
+ }),
288
344
  }, { signal });
289
345
  }
290
346
  catch (error) {
@@ -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 {\n\tContentBlock,\n\tContentBlockParam,\n\tMessage as AnthropicMessage,\n\tMessageParam,\n\tOutputConfig,\n\tRedactedThinkingBlockParam,\n\tThinkingBlockParam,\n\tTool as ClaudeTool,\n\tToolTextEditor20250728,\n\tUsage,\n} from '@anthropic-ai/sdk/resources/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, MessagePart } 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. Above roughly 21,000 the SDK refuses a request\n// that is not streamed, because it could outlast its ten-minute timeout.\nconst maxOutputTokens = 16_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/**\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 '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\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/** Unlike OpenAI, Anthropic counts cache reads and writes apart from `input_tokens`. */\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\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\nfunction toLLMResponse(response: AnthropicMessage, logger: ILogger): 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 => describeBlock(block, logger)),\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. An `AnthropicError` that is not an `APIError` never\n * carries an answer from the API: on this client's path it is the SDK refusing to make the\n * call, such as an unresolved profile or a request too large to send without streaming.\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\nfunction classifyClaudeFailure(error: unknown): Error {\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\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\tsystemPrompt,\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\treasoningEffort?: string;\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\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.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\n\t\ttry {\n\t\t\tresponse = await this.client.messages.create(\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\tsystem: this.systemPrompt,\n\t\t\t\t\tmessages: context.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},\n\t\t\t\t{ signal },\n\t\t\t);\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\tthrow classifyClaudeFailure(error);\n\t\t}\n\n\t\treturn treatErrors(\n\t\t\t() => toLLMResponse(response, this.logger),\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":"AAAA,OAAO,SAAS,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAexE,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACN,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,WAAW,GACX,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAkC,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAmB,QAAQ,EAAuB,MAAM,mBAAmB,CAAC;AAEnF,gGAAgG;AAChG,8FAA8F;AAC9F,kGAAkG;AAClG,2FAA2F;AAC3F,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAU,CAAC;AAG7E,MAAM,iBAAiB,GAAG;IACzB,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,kBAAkB;IACzB,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE,kBAAkB;CACyB,CAAC;AAEpD,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACxC,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CAC6D,CAAC;AAGpE,gGAAgG;AAChG,yEAAyE;AACzE,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,kFAAkF;AAClF,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAE7D,yFAAyF;AACzF,kDAAkD;AAClD,MAAM,uBAAuB,GAAG,CAAC,eAAe,EAAE,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;AAE9F,0FAA0F;AAC1F,MAAM,YAAY,GAAG,QAAQ,CAAC;AAE9B,mFAAmF;AACnF,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAC5C,MAAM,YAAY,GAAG,MAAM,CAAC;AAE5B;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,0FAA0F;AAC1F,SAAS,cAAc,CAAC,IAAiB;IACxC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,MAAM;YACV,uCAAuC;YACvC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,KAAK,UAAU;YACd,OAAO;gBACN,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;aAC1F,CAAC;QACH,KAAK,YAAY;YAChB,OAAO;gBACN;oBACC,IAAI,EAAE,aAAa;oBACnB,WAAW,EAAE,IAAI,CAAC,MAAM;oBACxB,OAAO,EAAE,IAAI,CAAC,MAAM;oBACpB,QAAQ,EAAE,IAAI,CAAC,OAAO;iBACtB;aACD,CAAC;QACH,KAAK,cAAc;YAClB,8FAA8F;YAC9F,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY;gBAClC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAuD,CAAC;gBAChE,CAAC,CAAC,EAAE,CAAC;QACP,KAAK,YAAY;YAChB,0FAA0F;YAC1F,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAA4B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,KAAK,WAAW;YACf,mFAAmF;YACnF,OAAO,EAAE,CAAC;IACZ,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,OAAgB;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,qEAAqE;AACrE,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAErD;;;;GAIG;AACH,SAAS,YAAY,CAAC,UAA0B;IAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC7B,IAAI,UAAU,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACxC,MAAM,IAAI,uBAAuB,CAChC,uCAAuC,cAAc,WAAW,UAAU,CAAC,IAAI,GAAG,CAClF,CAAC;QACH,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;IAC/D,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,uBAAuB,CAAC,8BAA8B,MAAM,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC;IACtD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC;AAED,SAAS,aAAa,CAAC,KAAmB,EAAE,MAAe;IAC1D,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM;YACV,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,KAAK,UAAU,CAAC,CAAC,CAAC;YACjB,qEAAqE;YACrE,MAAM,MAAM,GAAuB;gBAClC,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,KAAK,CAAC,SAAS;aAC1B,CAAC;YACF,MAAM,MAAM,GAAgB,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACzF,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1F,CAAC;QACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YAC1B,mEAAmE;YACnE,MAAM,QAAQ,GAA+B,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7F,OAAO,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,KAAK,UAAU;YACd,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACnF,KAAK,YAAY,CAAC,CAAC,CAAC;YACnB,sFAAsF;YACtF,MAAM,UAAU,GAAyB;gBACxC,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;aAC1C,CAAC;YACF,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACzE,CAAC;QACD;YACC,4FAA4F;YAC5F,WAAW,CACV,GAAG,EAAE;gBACJ,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,yDAAyD,CAAC,CAAC;YAC/E,CAAC,EACD,mBAAmB,EACnB,sDAAsD,CACtD,CAAC;YACF,OAAO,EAAE,CAAC;IACZ,CAAC;AACF,CAAC;AAED,SAAS,YAAY,CAAC,QAA0B;IAC/C,QAAQ,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC9B,yFAAyF;QACzF,KAAK,UAAU,CAAC;QAChB,KAAK,UAAU;YACd,OAAO,WAAW,CAAC;QACpB,KAAK,YAAY;YAChB,OAAO,WAAW,CAAC;QACpB,KAAK,SAAS;YACb,OAAO,SAAS,CAAC;QAClB,KAAK,+BAA+B;YACnC,MAAM,IAAI,eAAe,CAAC,6CAA6C,EAAE;gBACxE,KAAK,EAAE,mDAAmD;aAC1D,CAAC,CAAC;QACJ;YACC,iFAAiF;YACjF,wBAAwB;YACxB,MAAM,IAAI,kBAAkB,CAAC,0CAA0C,EAAE;gBACxE,KAAK,EAAE,8BAA8B,QAAQ,CAAC,WAAW,IAAI,SAAS,IAAI;aAC1E,CAAC,CAAC;IACL,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,KAAwB,EAAE,MAAe;IAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,+DAA+D;QAC/D,WAAW,CACV,GAAG,EAAE;YACJ,MAAM,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACrF,CAAC,EACD,mBAAmB,EACnB,iDAAiD,CACjD,CAAC;QACF,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,CAC7B,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;YACpB,WAAW,EAAE,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,YAAY;YACrD,eAAe,EAAE,GAAG,CAAC,eAAe,GAAG,SAAS,CAAC,uBAAuB;YACxE,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,GAAG,SAAS,CAAC,2BAA2B;YAClF,YAAY,EAAE,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,aAAa;SACxD,CAAC,EACF,EAAE,WAAW,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAC9E,CAAC;IACH,CAAC;IACD,OAAO;QACN,WAAW,EAAE,KAAK,CAAC,YAAY;QAC/B,eAAe,EAAE,KAAK,CAAC,uBAAuB,IAAI,CAAC;QACnD,kBAAkB,EAAE,KAAK,CAAC,2BAA2B,IAAI,CAAC;QAC1D,YAAY,EAAE,KAAK,CAAC,aAAa;KACjC,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAA0B,EAAE,MAAe;IACjE,IAAI,KAAyB,CAAC;IAE9B,IAAI,CAAC;QACJ,sFAAsF;QACtF,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACzC,OAAO;YACN,OAAO,EAAE;gBACR,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;aACxE;YACD,KAAK;YACL,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC;SAClC,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,wFAAwF;QACxF,0DAA0D;QAC1D,MAAM,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,KAAc;IACxC,OAAO,CACN,CAAC,KAAK,YAAY,cAAc,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC,CAAC;QACjE,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,yCAAyC,CAAC,CAAC,CAC/F,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC5C,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,qEAAqE;QACrE,OAAO,IAAI,kBAAkB,CAAC,2CAA2C,EAAE;YAC1E,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC;SAC7B,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC/B,uFAAuF;QACvF,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC1E,OAAO,IAAI,eAAe,CAAC,6CAA6C,EAAE;gBACzE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC;aAC7B,CAAC,CAAC;QACJ,CAAC;QACD,IACC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;YACzD,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,EAC5D,CAAC;YACF,OAAO,IAAI,kBAAkB,CAAC,6BAA6B,EAAE;gBAC5D,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC;aAC7B,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,4FAA4F;IAC5F,OAAO,uBAAuB,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IACV,MAAM,CAAY;IAClB,KAAK,CAA6C;IACnE,kDAAkD;IACjC,eAAe,CAAuC;IACtD,SAAS,CAAqB;IACtC,YAAY,CAAS;IACrB,kBAAkB,GAAG,YAAY,CAAC;IAC1B,MAAM,CAAU;IAEjC,2FAA2F;IAC3F,wBAAwB;IACxB,YAAY,EACX,KAAK,EACL,eAAe,EACf,SAAS,EACT,YAAY,EACZ,MAAM,GAQN;QACA,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,uBAAuB,CAChC,IAAI,KAAK,iDAAiD,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtF,CAAC;QACH,CAAC;QACD,IAAI,KAAK,KAAK,OAAO,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YACxD,MAAM,IAAI,uBAAuB,CAChC,kEAAkE,CAClE,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,eAAe,IAAI,MAAM,CAAC,CAAC;QAC3E,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,MAAM,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,uBAAuB,CAChC,IAAI,MAAM,4DAA4D,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5G,CAAC;QACH,CAAC;QACD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,sEAAsE;YACtE,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;gBACvB,MAAM,IAAI,uBAAuB,CAAC,kDAAkD,CAAC,CAAC;YACvF,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,YAAY,CAAC,EAAE,CAAC;gBACjE,MAAM,IAAI,uBAAuB,CAChC,0DAA0D,MAAM,CAAC,YAAY,CAAC,mBAAmB,MAAM,CAAC,SAAS,CAAC,EAAE,CACpH,CAAC;YACH,CAAC;QACF,CAAC;QAED,IAAI,CAAC;YACJ,uFAAuF;YACvF,0DAA0D;YAC1D,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,oFAAoF;YACpF,iFAAiF;YACjF,MAAM,IAAI,kBAAkB,CAAC,uCAAuC,EAAE;gBACrE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC;aAC7B,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,cAAc,CAAC,IAAgB;QAC9B,OAAO,IAAI,KAAK,YAAY,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,IAAI,CACT,EAAE,OAAO,EAAE,KAAK,EAAmD,EACnE,MAAmB;QAEnB,IAAI,QAA0B,CAAC;QAE/B,IAAI,CAAC;YACJ,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAChD;gBACC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,eAAe;gBAC3B,oFAAoF;gBACpF,kFAAkF;gBAClF,8DAA8D;gBAC9D,MAAM,EACL,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,EAAE;oBACvD,CAAC,CAAC,IAAI,CAAC,YAAY;oBACnB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC;gBACrF,yFAAyF;gBACzF,QAAQ,EAAE,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBACnE,0EAA0E;gBAC1E,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC3D,uEAAuE;gBACvE,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI;oBACzC,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE;oBACrD,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE;iBAC/C,CAAC;gBACF,gFAAgF;gBAChF,4EAA4E;gBAC5E,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;gBACpC,4FAA4F;gBAC5F,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI;oBACnC,KAAK,EAAE,CAAC,cAAc,CAAC;oBACvB,kBAAkB,EAAE;wBACnB,KAAK,EAAE;4BACN;gCACC,IAAI,EAAE,kBAAkB;gCACxB,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE;6BACxD;yBACD;qBACD;iBACD,CAAC;aACF,EACD,EAAE,MAAM,EAAE,CACV,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,mFAAmF;YACnF,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,WAAW,CACjB,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAC1C,oBAAoB,EACpB,gCAAgC,CAChC,CAAC;IACH,CAAC;CACD","sourcesContent":["import Anthropic, { AnthropicError, APIError } from '@anthropic-ai/sdk';\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. Above roughly 21,000 the SDK refuses a request\n// that is not streamed, because it could outlast its ten-minute timeout.\nconst maxOutputTokens = 16_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// 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\nfunction toLLMResponse(response: AnthropicMessage, logger: ILogger): 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 => describeBlock(block, logger)),\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. An `AnthropicError` that is not an `APIError` never\n * carries an answer from the API: on this client's path it is the SDK refusing to make the\n * call, such as an unresolved profile or a request too large to send without streaming.\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\nfunction classifyClaudeFailure(error: unknown): Error {\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\n\t\ttry {\n\t\t\tresponse = await this.client.beta.messages.create(\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} 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\tthrow classifyClaudeFailure(error);\n\t\t}\n\n\t\treturn treatErrors(\n\t\t\t() => toLLMResponse(response, this.logger),\n\t\t\tclassifyLocalFailure,\n\t\t\t'Claude response mapping failed',\n\t\t);\n\t}\n}\n"]}