@mikode13/harness 2.0.0 → 2.1.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 (38) hide show
  1. package/README.md +5 -0
  2. package/dist/agent/domain/agent.d.ts +1 -1
  3. package/dist/agent/domain/agent.js.map +1 -1
  4. package/dist/agent/domain/errors.d.ts +1 -1
  5. package/dist/agent/domain/errors.js +1 -1
  6. package/dist/agent/domain/errors.js.map +1 -1
  7. package/dist/agent/domain/providerFailure.js +1 -1
  8. package/dist/agent/domain/providerFailure.js.map +1 -1
  9. package/dist/engines/claude/infrastructure/model/claudeAgent.d.ts +2 -2
  10. package/dist/engines/claude/infrastructure/model/claudeAgent.js +3 -3
  11. package/dist/engines/claude/infrastructure/model/claudeAgent.js.map +1 -1
  12. package/dist/engines/codex/infrastructure/model/codexAgent.d.ts +2 -2
  13. package/dist/engines/codex/infrastructure/model/codexAgent.js +4 -4
  14. package/dist/engines/codex/infrastructure/model/codexAgent.js.map +1 -1
  15. package/dist/engines/domain/model/llmAgent.d.ts +3 -3
  16. package/dist/engines/domain/model/llmAgent.js +3 -3
  17. package/dist/engines/domain/model/llmAgent.js.map +1 -1
  18. package/dist/factory/infrastructure/agentFactory.d.ts +19 -13
  19. package/dist/factory/infrastructure/agentFactory.js +48 -23
  20. package/dist/factory/infrastructure/agentFactory.js.map +1 -1
  21. package/dist/llm/domain/errors.d.ts +1 -1
  22. package/dist/llm/domain/errors.js +1 -1
  23. package/dist/llm/domain/errors.js.map +1 -1
  24. package/dist/llm/domain/llm.d.ts +1 -1
  25. package/dist/llm/domain/llm.js.map +1 -1
  26. package/dist/llm/infrastructure/claudeLLMClient.d.ts +21 -0
  27. package/dist/llm/infrastructure/claudeLLMClient.js +189 -0
  28. package/dist/llm/infrastructure/claudeLLMClient.js.map +1 -0
  29. package/dist/llm/infrastructure/openAILLMClient.d.ts +1 -1
  30. package/dist/llm/infrastructure/openAILLMClient.js +4 -4
  31. package/dist/llm/infrastructure/openAILLMClient.js.map +1 -1
  32. package/dist/orchestration/domain/model/orchestratorAgent.d.ts +2 -2
  33. package/dist/orchestration/domain/model/orchestratorAgent.js +3 -3
  34. package/dist/orchestration/domain/model/orchestratorAgent.js.map +1 -1
  35. package/dist/retry/domain/model/retryingAgent.d.ts +2 -2
  36. package/dist/retry/domain/model/retryingAgent.js +4 -4
  37. package/dist/retry/domain/model/retryingAgent.js.map +1 -1
  38. package/package.json +8 -2
package/README.md CHANGED
@@ -99,6 +99,11 @@ comment on `Agent` in `src/agent/domain/agent.ts`.
99
99
  pnpm add @mikode13/harness
100
100
  ```
101
101
 
102
+ The package is ESM only and runs on Node.js 22 (22.13 or later) or 24. Its type declarations resolve
103
+ internal modules through the `imports` field of its `package.json`, so a TypeScript consumer
104
+ needs `moduleResolution` set to `node16`, `nodenext` or `bundler`; the legacy `node10`
105
+ resolution cannot read that field.
106
+
102
107
  An agent is built by a factory, then driven. The only output the package produces
103
108
  on its own is diagnostic warnings on stderr, from a default logger that both
104
109
  factories let you replace through their `logger` option:
@@ -1,4 +1,4 @@
1
- import type { Tokens } from '../../shared/domain/tokens.ts';
1
+ import type { Tokens } from '#src/shared/domain/tokens';
2
2
  /**
3
3
  * How a run ended when it did not fail. Every token a run spends travels with its end: here
4
4
  * when it finishes, in `RecoverableError.tokens` or `UnrecoverableError.tokens` when it fails.
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/agent/domain/agent.ts"],"names":[],"mappings":"","sourcesContent":["import type { Tokens } from '../../shared/domain/tokens.ts';\n\n/**\n * How a run ended when it did not fail. Every token a run spends travels with its end: here\n * when it finishes, in `RecoverableError.tokens` or `UnrecoverableError.tokens` when it fails.\n */\nexport interface AgentResponse {\n\t/** The final text. Empty when the run produced none, for example a turn that only edited files. */\n\tresponse: string;\n\t/**\n\t * Missing when any call in the run completed without reporting usage, which is not the same\n\t * as zero: a partial sum would look complete.\n\t */\n\ttokens?: Tokens;\n\t/** Wall-clock seconds the consumer waited for the run, retries and every role included. */\n\tduration: number;\n}\n\nexport type Callback = (item: ProgressEvent) => void;\n\n/**\n * Live activity during a run, for narration only: the result travels in `AgentResponse`.\n * New event types can arrive in a minor release, so render the types you know and ignore\n * the rest instead of switching over them exhaustively with a `never` check.\n */\nexport type ProgressEvent =\n\t| { type: 'command'; command: string; exitCode?: number }\n\t| { type: 'reasoning'; message: string }\n\t| { type: 'search'; query: string }\n\t| { type: 'fileChange'; changes: { path: string; kind: 'add' | 'update' | 'delete' }[] }\n\t| { type: 'mcpTool'; server: string; tool: string; status: string }\n\t| { type: 'agentMessage'; message: string }\n\t| { type: 'todoList'; items: { text: string; completed: boolean }[] }\n\t| { type: 'turnStarted' }\n\t| { type: 'turnEnded' };\n\n/**\n * The contract every engine (CodexAgent, ClaudeAgent, future providers) and every\n * decorator (RetryingAgent, OrchestratorAgent) is built against.\n *\n * Implementers MUST only ever reject with `RecoverableError` or `UnrecoverableError`\n * (see ./errors.ts) — never a raw SDK error, a plain `Error`, or anything else leaked\n * unclassified. Every consumer of `Agent` (RetryingAgent's retry decision,\n * OrchestratorAgent's failure handling) `instanceof`-checks against those two types to\n * decide what to do next; a leaked, unclassified error bypasses that decision\n * entirely — it gets retried when it shouldn't be, or crashes a run that a retry\n * would have recovered. Wrap every call into the underlying SDK so nothing escapes\n * unclassified, including failures the SDK itself doesn't model as a domain error\n * (network errors, malformed responses, etc.); `classifyProviderFailure` does this.\n *\n * Cancellation is the one exception: an `AbortError` must propagate unchanged, because\n * consumers check for it before either error type.\n */\nexport interface Agent {\n\trun(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse>;\n}\n"]}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/agent/domain/agent.ts"],"names":[],"mappings":"","sourcesContent":["import type { Tokens } from '#src/shared/domain/tokens';\n\n/**\n * How a run ended when it did not fail. Every token a run spends travels with its end: here\n * when it finishes, in `RecoverableError.tokens` or `UnrecoverableError.tokens` when it fails.\n */\nexport interface AgentResponse {\n\t/** The final text. Empty when the run produced none, for example a turn that only edited files. */\n\tresponse: string;\n\t/**\n\t * Missing when any call in the run completed without reporting usage, which is not the same\n\t * as zero: a partial sum would look complete.\n\t */\n\ttokens?: Tokens;\n\t/** Wall-clock seconds the consumer waited for the run, retries and every role included. */\n\tduration: number;\n}\n\nexport type Callback = (item: ProgressEvent) => void;\n\n/**\n * Live activity during a run, for narration only: the result travels in `AgentResponse`.\n * New event types can arrive in a minor release, so render the types you know and ignore\n * the rest instead of switching over them exhaustively with a `never` check.\n */\nexport type ProgressEvent =\n\t| { type: 'command'; command: string; exitCode?: number }\n\t| { type: 'reasoning'; message: string }\n\t| { type: 'search'; query: string }\n\t| { type: 'fileChange'; changes: { path: string; kind: 'add' | 'update' | 'delete' }[] }\n\t| { type: 'mcpTool'; server: string; tool: string; status: string }\n\t| { type: 'agentMessage'; message: string }\n\t| { type: 'todoList'; items: { text: string; completed: boolean }[] }\n\t| { type: 'turnStarted' }\n\t| { type: 'turnEnded' };\n\n/**\n * The contract every engine (CodexAgent, ClaudeAgent, future providers) and every\n * decorator (RetryingAgent, OrchestratorAgent) is built against.\n *\n * Implementers MUST only ever reject with `RecoverableError` or `UnrecoverableError`\n * (see ./errors.ts) — never a raw SDK error, a plain `Error`, or anything else leaked\n * unclassified. Every consumer of `Agent` (RetryingAgent's retry decision,\n * OrchestratorAgent's failure handling) `instanceof`-checks against those two types to\n * decide what to do next; a leaked, unclassified error bypasses that decision\n * entirely — it gets retried when it shouldn't be, or crashes a run that a retry\n * would have recovered. Wrap every call into the underlying SDK so nothing escapes\n * unclassified, including failures the SDK itself doesn't model as a domain error\n * (network errors, malformed responses, etc.); `classifyProviderFailure` does this.\n *\n * Cancellation is the one exception: an `AbortError` must propagate unchanged, because\n * consumers check for it before either error type.\n */\nexport interface Agent {\n\trun(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse>;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type Tokens } from '../../shared/domain/tokens.ts';
1
+ import { type Tokens } from '#src/shared/domain/tokens';
2
2
  interface ClassifiedErrorOptions {
3
3
  cause: string;
4
4
  /** What the run spent before it failed, as far as it was reported. */
@@ -1,4 +1,4 @@
1
- import { addTokens } from "../../shared/domain/tokens.js";
1
+ import { addTokens } from '#src/shared/domain/tokens';
2
2
  export class RecoverableError extends Error {
3
3
  cause;
4
4
  /** Missing when nothing was reported, and always missing when `usageUnreported` is set. */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/agent/domain/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,+BAA+B,CAAC;AAcvE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACjC,KAAK,CAAS;IACvB,2FAA2F;IAClF,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAElC,YAAY,OAAe,EAAE,OAA+B;QAC3D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;QACxD,gDAAgD;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACjE,CAAC;CACD;AACD,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACnC,KAAK,CAAS;IACvB,2FAA2F;IAClF,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAElC,YAAY,OAAe,EAAE,OAA+B;QAC3D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;QACxD,gDAAgD;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACjE,CAAC;CACD;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC9B,KAAc,EACd,KAAyB,EACzB,UAAU,GAAG,KAAK;IAElB,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,kBAAkB,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9F,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAExC,MAAM,UAAU,GAAG,KAAK,CAAC,WAGiB,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE;QAC1C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;QACtC,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,UAAU;KACpD,CAAC,CAAC;IACH,0FAA0F;IAC1F,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACzB,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;CAAG","sourcesContent":["import { addTokens, type Tokens } from '../../shared/domain/tokens.ts';\n\ninterface ClassifiedErrorOptions {\n\tcause: string;\n\t/** What the run spent before it failed, as far as it was reported. */\n\ttokens?: Tokens | undefined;\n\t/**\n\t * A provider answered at least one call of the run without reporting its usage, so\n\t * `tokens` would be a subtotal. A failure that never got an answer, such as a dropped\n\t * connection, leaves it unset: it adds nothing that could be missing.\n\t */\n\tusageUnreported?: boolean | undefined;\n}\n\nexport class RecoverableError extends Error {\n\toverride cause: string;\n\t/** Missing when nothing was reported, and always missing when `usageUnreported` is set. */\n\treadonly tokens: Tokens | undefined;\n\treadonly usageUnreported: boolean;\n\n\tconstructor(message: string, options: ClassifiedErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.cause = options.cause;\n\t\tthis.usageUnreported = options.usageUnreported ?? false;\n\t\t// A subtotal must not pass for the run's total.\n\t\tthis.tokens = this.usageUnreported ? undefined : options.tokens;\n\t}\n}\nexport class UnrecoverableError extends Error {\n\toverride cause: string;\n\t/** Missing when nothing was reported, and always missing when `usageUnreported` is set. */\n\treadonly tokens: Tokens | undefined;\n\treadonly usageUnreported: boolean;\n\n\tconstructor(message: string, options: ClassifiedErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.cause = options.cause;\n\t\tthis.usageUnreported = options.usageUnreported ?? false;\n\t\t// A subtotal must not pass for the run's total.\n\t\tthis.tokens = this.usageUnreported ? undefined : options.tokens;\n\t}\n}\n\n/**\n * The same failure, also carrying what an outer layer spent before the failure reached it,\n * such as earlier attempts or earlier roles, or the call the failure came from. `unreported`\n * says that some of it was answered without usage. It is a new instance of the same class, so\n * a subclass such as `MaxContextError` keeps its meaning. A cancellation or an unclassified\n * failure is returned unchanged: neither can carry tokens.\n */\nexport function withSpentTokens(\n\terror: unknown,\n\tspent: Tokens | undefined,\n\tunreported = false,\n): unknown {\n\tif (!(error instanceof RecoverableError || error instanceof UnrecoverableError)) return error;\n\tif (!spent && !unreported) return error;\n\n\tconst ErrorClass = error.constructor as new (\n\t\tmessage: string,\n\t\toptions: ClassifiedErrorOptions,\n\t) => RecoverableError | UnrecoverableError;\n\tconst copy = new ErrorClass(error.message, {\n\t\tcause: error.cause,\n\t\ttokens: addTokens(error.tokens, spent),\n\t\tusageUnreported: error.usageUnreported || unreported,\n\t});\n\t// The trace should point at where the failure happened, not at the layer that counted it.\n\tcopy.stack = error.stack;\n\treturn copy;\n}\n\n/**\n * An agent was requested with something its provider does not support, such as another\n * provider's model. Thrown while the agent is built, never by `run()`.\n */\nexport class InvalidAgentConfigError extends Error {}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/agent/domain/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,2BAA2B,CAAC;AAcnE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACjC,KAAK,CAAS;IACvB,2FAA2F;IAClF,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAElC,YAAY,OAAe,EAAE,OAA+B;QAC3D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;QACxD,gDAAgD;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACjE,CAAC;CACD;AACD,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACnC,KAAK,CAAS;IACvB,2FAA2F;IAClF,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAElC,YAAY,OAAe,EAAE,OAA+B;QAC3D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;QACxD,gDAAgD;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACjE,CAAC;CACD;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC9B,KAAc,EACd,KAAyB,EACzB,UAAU,GAAG,KAAK;IAElB,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,IAAI,KAAK,YAAY,kBAAkB,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9F,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAExC,MAAM,UAAU,GAAG,KAAK,CAAC,WAGiB,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE;QAC1C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;QACtC,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,UAAU;KACpD,CAAC,CAAC;IACH,0FAA0F;IAC1F,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACzB,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;CAAG","sourcesContent":["import { addTokens, type Tokens } from '#src/shared/domain/tokens';\n\ninterface ClassifiedErrorOptions {\n\tcause: string;\n\t/** What the run spent before it failed, as far as it was reported. */\n\ttokens?: Tokens | undefined;\n\t/**\n\t * A provider answered at least one call of the run without reporting its usage, so\n\t * `tokens` would be a subtotal. A failure that never got an answer, such as a dropped\n\t * connection, leaves it unset: it adds nothing that could be missing.\n\t */\n\tusageUnreported?: boolean | undefined;\n}\n\nexport class RecoverableError extends Error {\n\toverride cause: string;\n\t/** Missing when nothing was reported, and always missing when `usageUnreported` is set. */\n\treadonly tokens: Tokens | undefined;\n\treadonly usageUnreported: boolean;\n\n\tconstructor(message: string, options: ClassifiedErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.cause = options.cause;\n\t\tthis.usageUnreported = options.usageUnreported ?? false;\n\t\t// A subtotal must not pass for the run's total.\n\t\tthis.tokens = this.usageUnreported ? undefined : options.tokens;\n\t}\n}\nexport class UnrecoverableError extends Error {\n\toverride cause: string;\n\t/** Missing when nothing was reported, and always missing when `usageUnreported` is set. */\n\treadonly tokens: Tokens | undefined;\n\treadonly usageUnreported: boolean;\n\n\tconstructor(message: string, options: ClassifiedErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.cause = options.cause;\n\t\tthis.usageUnreported = options.usageUnreported ?? false;\n\t\t// A subtotal must not pass for the run's total.\n\t\tthis.tokens = this.usageUnreported ? undefined : options.tokens;\n\t}\n}\n\n/**\n * The same failure, also carrying what an outer layer spent before the failure reached it,\n * such as earlier attempts or earlier roles, or the call the failure came from. `unreported`\n * says that some of it was answered without usage. It is a new instance of the same class, so\n * a subclass such as `MaxContextError` keeps its meaning. A cancellation or an unclassified\n * failure is returned unchanged: neither can carry tokens.\n */\nexport function withSpentTokens(\n\terror: unknown,\n\tspent: Tokens | undefined,\n\tunreported = false,\n): unknown {\n\tif (!(error instanceof RecoverableError || error instanceof UnrecoverableError)) return error;\n\tif (!spent && !unreported) return error;\n\n\tconst ErrorClass = error.constructor as new (\n\t\tmessage: string,\n\t\toptions: ClassifiedErrorOptions,\n\t) => RecoverableError | UnrecoverableError;\n\tconst copy = new ErrorClass(error.message, {\n\t\tcause: error.cause,\n\t\ttokens: addTokens(error.tokens, spent),\n\t\tusageUnreported: error.usageUnreported || unreported,\n\t});\n\t// The trace should point at where the failure happened, not at the layer that counted it.\n\tcopy.stack = error.stack;\n\treturn copy;\n}\n\n/**\n * An agent was requested with something its provider does not support, such as another\n * provider's model. Thrown while the agent is built, never by `run()`.\n */\nexport class InvalidAgentConfigError extends Error {}\n"]}
@@ -1,4 +1,4 @@
1
- import { isAbortError } from "../../shared/domain/isAbortError.js";
1
+ import { isAbortError } from '#src/shared/domain/isAbortError';
2
2
  import { RecoverableError, UnrecoverableError } from "./errors.js";
3
3
  /**
4
4
  * Unclassified failures are transport-shaped, so recoverable is the useful default:
@@ -1 +1 @@
1
- {"version":3,"file":"providerFailure.js","sourceRoot":"","sources":["../../../src/agent/domain/providerFailure.ts"],"names":[],"mappings":"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","sourcesContent":["import { isAbortError } from '../../shared/domain/isAbortError.ts';\nimport { RecoverableError, UnrecoverableError } from './errors.ts';\n\n/**\n * Unclassified failures are transport-shaped, so recoverable is the useful default:\n * `RetryingAgent` turns a persistent one into an `UnrecoverableError` on exhaustion, while\n * the opposite default would make every transient blip fatal.\n */\nexport function classifyProviderFailure(error: unknown, context: string): Error {\n\tif (isAbortError(error)) return error;\n\tif (error instanceof RecoverableError || error instanceof UnrecoverableError) return error;\n\n\treturn new RecoverableError(context, { cause: describeFailure(error) });\n}\n\n/** A host failure cannot be retried safely because the provider turn may already have side effects. */\nexport function classifyHostFailure(error: unknown, context: string): Error {\n\tif (isAbortError(error)) return error;\n\tif (error instanceof UnrecoverableError) return error;\n\n\treturn new UnrecoverableError(context, { cause: describeFailure(error) });\n}\n\n/**\n * Runs host code — a logger, for example — and classifies whatever it throws with the\n * classifier the caller chooses. The host code stays unaware of classification, and the\n * failure cannot escape the `Agent` unclassified.\n */\nexport function treatErrors<T>(\n\toperation: () => T,\n\tclassify: (error: unknown, context: string) => Error,\n\tcontext: string,\n): T {\n\ttry {\n\t\treturn operation();\n\t} catch (error) {\n\t\tthrow classify(error, context);\n\t}\n}\n\n/** Preserves deliberate domain errors while making unexpected local failures fatal. */\nexport function classifyLocalFailure(error: unknown, context: string): Error {\n\tif (isAbortError(error)) return error;\n\tif (error instanceof RecoverableError || error instanceof UnrecoverableError) return error;\n\n\treturn new UnrecoverableError(context, { cause: describeFailure(error) });\n}\n\n/** The message alone: a stack or serialized object could expose unstable implementation details. */\nexport function describeFailure(error: unknown): string {\n\tif (error instanceof RecoverableError || error instanceof UnrecoverableError) return error.cause;\n\tif (error instanceof Error && error.message) return error.message;\n\tif (typeof error === 'string' && error) return error;\n\n\treturn 'The provider failed without a description.';\n}\n\n/**\n * Classifies the stream itself and nothing else. Consuming an SDK stream inside a\n * `try/catch` puts the loop body — item mapping, logging, the consumer callback — inside\n * the provider boundary too, so a host failure gets reported as a recoverable provider\n * failure and `RetryingAgent` replays a turn that already ran its side effects.\n */\nexport async function* classifiedProviderStream<T>(\n\tstream: AsyncIterable<T>,\n\tcontext: string,\n): AsyncGenerator<T> {\n\tlet events: AsyncIterator<T>;\n\n\ttry {\n\t\tevents = stream[Symbol.asyncIterator]();\n\t} catch (error) {\n\t\tthrow classifyProviderFailure(error, context);\n\t}\n\n\tlet completed = false;\n\n\ttry {\n\t\tfor (;;) {\n\t\t\tlet next: IteratorResult<T>;\n\n\t\t\ttry {\n\t\t\t\tnext = await events.next();\n\t\t\t} catch (error) {\n\t\t\t\tthrow classifyProviderFailure(error, context);\n\t\t\t}\n\n\t\t\tif (next.done) {\n\t\t\t\tcompleted = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tyield next.value;\n\t\t}\n\t} finally {\n\t\tif (!completed) {\n\t\t\ttry {\n\t\t\t\tawait events.return?.();\n\t\t\t} catch {\n\t\t\t\t// Cleanup is secondary to the failure that interrupted consumption. It must\n\t\t\t\t// never replace a classified provider error or an unrecoverable host error.\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"providerFailure.js","sourceRoot":"","sources":["../../../src/agent/domain/providerFailure.ts"],"names":[],"mappings":"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","sourcesContent":["import { isAbortError } from '#src/shared/domain/isAbortError';\nimport { RecoverableError, UnrecoverableError } from './errors.ts';\n\n/**\n * Unclassified failures are transport-shaped, so recoverable is the useful default:\n * `RetryingAgent` turns a persistent one into an `UnrecoverableError` on exhaustion, while\n * the opposite default would make every transient blip fatal.\n */\nexport function classifyProviderFailure(error: unknown, context: string): Error {\n\tif (isAbortError(error)) return error;\n\tif (error instanceof RecoverableError || error instanceof UnrecoverableError) return error;\n\n\treturn new RecoverableError(context, { cause: describeFailure(error) });\n}\n\n/** A host failure cannot be retried safely because the provider turn may already have side effects. */\nexport function classifyHostFailure(error: unknown, context: string): Error {\n\tif (isAbortError(error)) return error;\n\tif (error instanceof UnrecoverableError) return error;\n\n\treturn new UnrecoverableError(context, { cause: describeFailure(error) });\n}\n\n/**\n * Runs host code — a logger, for example — and classifies whatever it throws with the\n * classifier the caller chooses. The host code stays unaware of classification, and the\n * failure cannot escape the `Agent` unclassified.\n */\nexport function treatErrors<T>(\n\toperation: () => T,\n\tclassify: (error: unknown, context: string) => Error,\n\tcontext: string,\n): T {\n\ttry {\n\t\treturn operation();\n\t} catch (error) {\n\t\tthrow classify(error, context);\n\t}\n}\n\n/** Preserves deliberate domain errors while making unexpected local failures fatal. */\nexport function classifyLocalFailure(error: unknown, context: string): Error {\n\tif (isAbortError(error)) return error;\n\tif (error instanceof RecoverableError || error instanceof UnrecoverableError) return error;\n\n\treturn new UnrecoverableError(context, { cause: describeFailure(error) });\n}\n\n/** The message alone: a stack or serialized object could expose unstable implementation details. */\nexport function describeFailure(error: unknown): string {\n\tif (error instanceof RecoverableError || error instanceof UnrecoverableError) return error.cause;\n\tif (error instanceof Error && error.message) return error.message;\n\tif (typeof error === 'string' && error) return error;\n\n\treturn 'The provider failed without a description.';\n}\n\n/**\n * Classifies the stream itself and nothing else. Consuming an SDK stream inside a\n * `try/catch` puts the loop body — item mapping, logging, the consumer callback — inside\n * the provider boundary too, so a host failure gets reported as a recoverable provider\n * failure and `RetryingAgent` replays a turn that already ran its side effects.\n */\nexport async function* classifiedProviderStream<T>(\n\tstream: AsyncIterable<T>,\n\tcontext: string,\n): AsyncGenerator<T> {\n\tlet events: AsyncIterator<T>;\n\n\ttry {\n\t\tevents = stream[Symbol.asyncIterator]();\n\t} catch (error) {\n\t\tthrow classifyProviderFailure(error, context);\n\t}\n\n\tlet completed = false;\n\n\ttry {\n\t\tfor (;;) {\n\t\t\tlet next: IteratorResult<T>;\n\n\t\t\ttry {\n\t\t\t\tnext = await events.next();\n\t\t\t} catch (error) {\n\t\t\t\tthrow classifyProviderFailure(error, context);\n\t\t\t}\n\n\t\t\tif (next.done) {\n\t\t\t\tcompleted = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tyield next.value;\n\t\t}\n\t} finally {\n\t\tif (!completed) {\n\t\t\ttry {\n\t\t\t\tawait events.return?.();\n\t\t\t} catch {\n\t\t\t\t// Cleanup is secondary to the failure that interrupted consumption. It must\n\t\t\t\t// never replace a classified provider error or an unrecoverable host error.\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -1,5 +1,5 @@
1
- import type { Agent, AgentResponse, Callback } from '../../../../agent/domain/agent.ts';
2
- import type { ILogger } from '../../../../shared/domain/logger.ts';
1
+ import type { Agent, AgentResponse, Callback } from '#src/agent/domain/agent';
2
+ import type { ILogger } from '#src/shared/domain/logger';
3
3
  export declare const claudeModels: readonly ["haiku", "sonnet", "opus", "fable"];
4
4
  export type ClaudeModel = (typeof claudeModels)[number];
5
5
  export declare const claudeReasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max"];
@@ -1,7 +1,7 @@
1
1
  import { query } from '@anthropic-ai/claude-agent-sdk';
2
- import { InvalidAgentConfigError, RecoverableError, UnrecoverableError, withSpentTokens, } from "../../../../agent/domain/errors.js";
3
- import { classifiedProviderStream, classifyHostFailure, classifyLocalFailure, classifyProviderFailure, treatErrors, } from "../../../../agent/domain/providerFailure.js";
4
- import { isOneOf } from "../../../../shared/domain/isOneOf.js";
2
+ import { InvalidAgentConfigError, RecoverableError, UnrecoverableError, withSpentTokens, } from '#src/agent/domain/errors';
3
+ import { classifiedProviderStream, classifyHostFailure, classifyLocalFailure, classifyProviderFailure, treatErrors, } from '#src/agent/domain/providerFailure';
4
+ import { isOneOf } from '#src/shared/domain/isOneOf';
5
5
  // The SDK types `model` as a plain string, so this list is maintained by hand.
6
6
  export const claudeModels = ['haiku', 'sonnet', 'opus', 'fable'];
7
7
  export const claudeReasoningEfforts = [
@@ -1 +1 @@
1
- {"version":3,"file":"claudeAgent.js","sourceRoot":"","sources":["../../../../../src/engines/claude/infrastructure/model/claudeAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@anthropic-ai/claude-agent-sdk';\nimport type {\n\tNonNullableUsage,\n\tEffortLevel,\n\tQuery,\n\tSDKAssistantMessage,\n\tSDKMessage,\n\tSDKResultSuccess,\n\tSDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\nimport type {\n\tAgent,\n\tAgentResponse,\n\tCallback,\n\tProgressEvent,\n} from '../../../../agent/domain/agent.ts';\nimport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '../../../../agent/domain/errors.ts';\nimport {\n\tclassifiedProviderStream,\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\ttreatErrors,\n} from '../../../../agent/domain/providerFailure.ts';\nimport type { ILogger } from '../../../../shared/domain/logger.ts';\nimport type { Tokens } from '../../../../shared/domain/tokens.ts';\nimport { isOneOf } from '../../../../shared/domain/isOneOf.ts';\n\n// The SDK types `model` as a plain string, so this list is maintained by hand.\nexport const claudeModels = ['haiku', 'sonnet', 'opus', 'fable'] as const;\nexport type ClaudeModel = (typeof claudeModels)[number];\n\nexport const claudeReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n] as const satisfies readonly EffortLevel[];\nexport type ClaudeReasoningEffort = (typeof claudeReasoningEfforts)[number];\n\ntype SDKSystemMessage = Extract<SDKMessage, { type: 'system' }>;\n\ninterface PendingTool {\n\tname: string;\n\tinput: Record<string, unknown>;\n\tserver?: string;\n}\n\ninterface ToolResultBlock {\n\ttype: string;\n\ttool_use_id: string;\n\tis_error?: boolean;\n\tcontent?: unknown;\n}\n\n// Claude reports its cache counters apart from input_tokens already.\nfunction toTokens(usage: NonNullableUsage): Tokens {\n\treturn {\n\t\tinputTokens: usage.input_tokens,\n\t\treadCacheTokens: usage.cache_read_input_tokens,\n\t\twrittenCacheTokens: usage.cache_creation_input_tokens,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\nfunction emitProgress(callback: Callback, event: ProgressEvent): void {\n\ttry {\n\t\tcallback(event);\n\t} catch (error) {\n\t\tthrow classifyHostFailure(error, 'Claude progress callback failed');\n\t}\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n\treturn typeof value === 'string' ? value : undefined;\n}\n\nfunction toolResultBlock(value: unknown): ToolResultBlock | undefined {\n\tconst block = asRecord(value);\n\tif (!block || typeof block.type !== 'string' || typeof block.tool_use_id !== 'string') {\n\t\treturn undefined;\n\t}\n\n\treturn block as unknown as ToolResultBlock;\n}\n\nfunction toolResultId(value: unknown): string | undefined {\n\treturn toolResultBlock(value)?.tool_use_id;\n}\n\nfunction fileChange(\n\tname: 'Edit' | 'Write',\n\ttool: PendingTool,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tconst inputPath = stringValue(tool.input.file_path);\n\tconst outputPath = stringValue(asRecord(output)?.filePath);\n\tconst path = outputPath ?? inputPath;\n\tif (!path) return undefined;\n\n\tconst kind =\n\t\tname === 'Write' && stringValue(asRecord(output)?.type) === 'create' ? 'add' : 'update';\n\treturn { type: 'fileChange', changes: [{ path, kind }] };\n}\n\nfunction todoList(tool: PendingTool): ProgressEvent | undefined {\n\tif (!Array.isArray(tool.input.todos)) return undefined;\n\n\tconst items = tool.input.todos.flatMap(todo => {\n\t\tconst item = asRecord(todo);\n\t\tconst text = stringValue(item?.content);\n\t\tconst status = stringValue(item?.status);\n\t\treturn text && status ? [{ text, completed: status === 'completed' }] : [];\n\t});\n\n\treturn { type: 'todoList', items };\n}\n\nfunction mcpTool(tool: PendingTool, result: ToolResultBlock): ProgressEvent | undefined {\n\tconst server = tool.server;\n\tconst toolName = tool.name.startsWith('mcp__')\n\t\t? tool.name.slice('mcp__'.length).split('__').slice(1).join('__')\n\t\t: tool.name;\n\tif (!server || !toolName) return undefined;\n\n\treturn {\n\t\ttype: 'mcpTool',\n\t\tserver,\n\t\ttool: toolName,\n\t\tstatus: result.is_error ? 'failed' : 'completed',\n\t};\n}\n\n// Tools without narration (Read, Grep, Task, ...) are a presentation choice, not an unknown:\n// the tool set is open-ended, so warning here would only produce noise.\nfunction describeCompletedTool(\n\ttool: PendingTool,\n\tresult: ToolResultBlock,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tif (tool.name === 'Bash') {\n\t\tconst exitCode = asRecord(output)?.exitCode ?? asRecord(output)?.exit_code;\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: stringValue(tool.input.command) ?? '',\n\t\t\t...(typeof exitCode === 'number' ? { exitCode } : {}),\n\t\t};\n\t}\n\n\tif (tool.name === 'WebSearch') {\n\t\tconst query = stringValue(tool.input.query);\n\t\treturn query ? { type: 'search', query } : undefined;\n\t}\n\n\tif (tool.name === 'Edit' || tool.name === 'Write') {\n\t\treturn result.is_error ? undefined : fileChange(tool.name, tool, output);\n\t}\n\n\tif (tool.name === 'TodoWrite') {\n\t\treturn result.is_error ? undefined : todoList(tool);\n\t}\n\n\tif (tool.name.startsWith('mcp__') || tool.server) {\n\t\treturn mcpTool(tool, result);\n\t}\n\n\treturn undefined;\n}\n\nexport class ClaudeAgent implements Agent {\n\tprivate model: ClaudeModel;\n\tprivate autoApprove: boolean;\n\tprivate reasoningEffort: ClaudeReasoningEffort;\n\tprivate sessionId?: string;\n\tprivate logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Claude supports, so it validates them instead of trusting the caller.\n\tconstructor({\n\t\tmodel,\n\t\tautoApprove = false,\n\t\treasoningEffort = 'high',\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\tautoApprove?: boolean;\n\t\treasoningEffort?: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\tif (!isOneOf(claudeModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Claude model; expected one of: ${claudeModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (!isOneOf(claudeReasoningEfforts, reasoningEffort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${reasoningEffort}\" is not a Claude reasoning effort; expected one of: ${claudeReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.model = model;\n\t\tthis.autoApprove = autoApprove;\n\t\tthis.reasoningEffort = reasoningEffort;\n\t\tthis.logger = logger;\n\t}\n\n\tasync run(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse> {\n\t\tsignal.throwIfAborted();\n\t\tconst start = Date.now();\n\n\t\tlet stream: Query;\n\n\t\ttry {\n\t\t\tstream = query({\n\t\t\t\tprompt,\n\t\t\t\toptions: {\n\t\t\t\t\teffort: this.reasoningEffort,\n\t\t\t\t\tmodel: this.model,\n\t\t\t\t\tmaxTurns: 3,\n\t\t\t\t\tcwd: process.cwd(),\n\t\t\t\t\tresume: this.sessionId,\n\t\t\t\t\t...(this.autoApprove\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tpermissionMode: 'bypassPermissions' as const,\n\t\t\t\t\t\t\t\tallowDangerouslySkipPermissions: true,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'Claude refused the request');\n\t\t}\n\n\t\tconst closeStream = () => {\n\t\t\tstream.close();\n\t\t};\n\t\tsignal.addEventListener('abort', closeStream, { once: true });\n\n\t\ttry {\n\t\t\treturn await this.parseResponse(stream, signal, callback, start);\n\t\t} finally {\n\t\t\tsignal.removeEventListener('abort', closeStream);\n\t\t}\n\t}\n\n\tprivate async parseResponse(\n\t\tstream: Query,\n\t\tsignal: AbortSignal,\n\t\tcallback: Callback,\n\t\tstart: number,\n\t): Promise<AgentResponse> {\n\t\tconst lines: string[] = [];\n\t\tlet resultMessage: SDKResultSuccess | undefined;\n\t\tconst pendingTools = new Map<string, PendingTool>();\n\n\t\t// Once Claude sent an assistant message, the provider answered: a failure after that\n\t\t// without usage leaves the run's count unknown, unlike one that never got an answer.\n\t\tlet answered = false;\n\n\t\ttry {\n\t\t\tconst messages = classifiedProviderStream(stream, 'Claude stream ended unexpectedly');\n\n\t\t\tfor await (const message of messages) {\n\t\t\t\tthis.sessionId ??= message.session_id;\n\n\t\t\t\ttry {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'assistant':\n\t\t\t\t\t\t\tanswered = true;\n\t\t\t\t\t\t\tthis.handleAssistantMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'user':\n\t\t\t\t\t\t\tthis.handleUserMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'result':\n\t\t\t\t\t\t\tif (message.subtype === 'success') {\n\t\t\t\t\t\t\t\tlines.push(message.result);\n\t\t\t\t\t\t\t\tresultMessage = message;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow new RecoverableError('Claude sdk error', {\n\t\t\t\t\t\t\t\t\tcause: [message.stop_reason, message.terminal_reason, ...message.errors].join(\n\t\t\t\t\t\t\t\t\t\t',',\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t// A failed result still reports what the turn spent.\n\t\t\t\t\t\t\t\t\ttokens: toTokens(message.usage),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'system':\n\t\t\t\t\t\t\tthis.handleSystemMessage(message);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// Known messages with nothing to narrate or report.\n\t\t\t\t\t\tcase 'stream_event':\n\t\t\t\t\t\tcase 'tool_progress':\n\t\t\t\t\t\tcase 'tool_use_summary':\n\t\t\t\t\t\tcase 'auth_status':\n\t\t\t\t\t\tcase 'rate_limit_event':\n\t\t\t\t\t\tcase 'prompt_suggestion':\n\t\t\t\t\t\tcase 'conversation_reset':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t// `never` breaks the build when an SDK upgrade adds a message type; the\n\t\t\t\t\t\t\t// warning covers a CLI binary that is newer than the types.\n\t\t\t\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude message type');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow classifyLocalFailure(error, 'Claude failed while mapping progress');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsignal.throwIfAborted();\n\n\t\t\tif (!resultMessage) {\n\t\t\t\t// The turn's work stands; only its accounting is missing.\n\t\t\t\tthis.warn('Claude ended a turn without a result message; its usage is unknown');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// A failed result reports the turn's usage itself.\n\t\t\tconst reported =\n\t\t\t\t(error instanceof RecoverableError || error instanceof UnrecoverableError) &&\n\t\t\t\terror.tokens !== undefined;\n\t\t\tthrow answered && !reported ? withSpentTokens(error, undefined, true) : error;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: lines.join('\\n'),\n\t\t\ttokens: resultMessage && toTokens(resultMessage.usage),\n\t\t\t// Measured here, like the other engines, so it exists even without a result message.\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n\n\tprivate handleSystemMessage(message: SDKSystemMessage): void {\n\t\tswitch (message.subtype) {\n\t\t\t// Failures the SDK handled without failing the turn: only a warning makes them visible.\n\t\t\tcase 'api_retry':\n\t\t\tcase 'model_refusal_fallback':\n\t\t\tcase 'model_refusal_no_fallback':\n\t\t\tcase 'permission_denied':\n\t\t\tcase 'mirror_error':\n\t\t\t\tthis.warn(message, 'Claude reported a failure without failing the turn');\n\t\t\t\treturn;\n\t\t\t// Known messages with nothing to narrate or report.\n\t\t\tcase 'init':\n\t\t\tcase 'compact_boundary':\n\t\t\tcase 'status':\n\t\t\tcase 'control_request_progress':\n\t\t\tcase 'local_command_output':\n\t\t\tcase 'hook_started':\n\t\t\tcase 'hook_progress':\n\t\t\tcase 'hook_response':\n\t\t\tcase 'plugin_install':\n\t\t\tcase 'task_notification':\n\t\t\tcase 'task_started':\n\t\t\tcase 'task_updated':\n\t\t\tcase 'task_progress':\n\t\t\tcase 'background_tasks_changed':\n\t\t\tcase 'thinking_tokens':\n\t\t\tcase 'session_state_changed':\n\t\t\tcase 'worker_shutting_down':\n\t\t\tcase 'commands_changed':\n\t\t\tcase 'notification':\n\t\t\tcase 'files_persisted':\n\t\t\tcase 'memory_recall':\n\t\t\tcase 'elicitation_complete':\n\t\t\tcase 'informational':\n\t\t\t\treturn;\n\t\t\tdefault: {\n\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude system message');\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleAssistantMessage(\n\t\tmessage: SDKAssistantMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tfor (const block of message.message.content) {\n\t\t\tswitch (block.type) {\n\t\t\t\tcase 'text':\n\t\t\t\t\temitProgress(callback, { type: 'agentMessage', message: block.text });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'thinking':\n\t\t\t\t\temitProgress(callback, { type: 'reasoning', message: block.thinking });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'tool_use':\n\t\t\t\tcase 'server_tool_use':\n\t\t\t\tcase 'mcp_tool_use': {\n\t\t\t\t\tconst input = asRecord(block.input);\n\t\t\t\t\tif (input) {\n\t\t\t\t\t\tpendingTools.set(block.id, {\n\t\t\t\t\t\t\tname: block.name === 'web_search' ? 'WebSearch' : block.name,\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t...('server_name' in block && typeof block.server_name === 'string'\n\t\t\t\t\t\t\t\t? { server: block.server_name }\n\t\t\t\t\t\t\t\t: parseMcpServer(block.name)),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'web_search_tool_result':\n\t\t\t\tcase 'web_fetch_tool_result':\n\t\t\t\tcase 'advisor_tool_result':\n\t\t\t\tcase 'code_execution_tool_result':\n\t\t\t\tcase 'bash_code_execution_tool_result':\n\t\t\t\tcase 'text_editor_code_execution_tool_result':\n\t\t\t\tcase 'tool_search_tool_result':\n\t\t\t\tcase 'mcp_tool_result':\n\t\t\t\t\tthis.handleCompletedTool(block, pendingTools, callback);\n\t\t\t\t\tbreak;\n\t\t\t\t// Known blocks with nothing to narrate.\n\t\t\t\tcase 'redacted_thinking':\n\t\t\t\tcase 'container_upload':\n\t\t\t\tcase 'compaction':\n\t\t\t\tcase 'fallback':\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {\n\t\t\t\t\tconst unknownBlock: never = block;\n\t\t\t\t\tthis.warn(unknownBlock, 'Unknown Claude content block');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleUserMessage(\n\t\tmessage: SDKUserMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tif (!Array.isArray(message.message.content)) return;\n\n\t\tfor (const block of message.message.content) {\n\t\t\tthis.handleCompletedTool(block, pendingTools, callback, message.tool_use_result);\n\t\t}\n\t}\n\n\tprivate handleCompletedTool(\n\t\tblock: unknown,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t\toutput?: unknown,\n\t): void {\n\t\tconst id = toolResultId(block);\n\t\tif (!id) return;\n\n\t\tconst tool = pendingTools.get(id);\n\t\tif (!tool) return;\n\n\t\tpendingTools.delete(id);\n\t\tconst result = toolResultBlock(block);\n\t\tif (!result) return;\n\n\t\tconst description = describeCompletedTool(tool, result, output ?? result.content);\n\t\tif (description) emitProgress(callback, description);\n\t}\n\n\tprivate warn(...args: unknown[]): void {\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tthis.logger.warn(...args);\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'Claude logger failed while reporting progress',\n\t\t);\n\t}\n}\n\nfunction parseMcpServer(name: string): { server: string } | undefined {\n\tif (!name.startsWith('mcp__')) return undefined;\n\n\tconst server = name.slice('mcp__'.length).split('__')[0];\n\treturn server ? { server } : undefined;\n}\n"]}
1
+ {"version":3,"file":"claudeAgent.js","sourceRoot":"","sources":["../../../../../src/engines/claude/infrastructure/model/claudeAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@anthropic-ai/claude-agent-sdk';\nimport type {\n\tNonNullableUsage,\n\tEffortLevel,\n\tQuery,\n\tSDKAssistantMessage,\n\tSDKMessage,\n\tSDKResultSuccess,\n\tSDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk';\nimport type { Agent, AgentResponse, Callback, ProgressEvent } from '#src/agent/domain/agent';\nimport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '#src/agent/domain/errors';\nimport {\n\tclassifiedProviderStream,\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\ttreatErrors,\n} from '#src/agent/domain/providerFailure';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport type { Tokens } from '#src/shared/domain/tokens';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\n\n// The SDK types `model` as a plain string, so this list is maintained by hand.\nexport const claudeModels = ['haiku', 'sonnet', 'opus', 'fable'] as const;\nexport type ClaudeModel = (typeof claudeModels)[number];\n\nexport const claudeReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n] as const satisfies readonly EffortLevel[];\nexport type ClaudeReasoningEffort = (typeof claudeReasoningEfforts)[number];\n\ntype SDKSystemMessage = Extract<SDKMessage, { type: 'system' }>;\n\ninterface PendingTool {\n\tname: string;\n\tinput: Record<string, unknown>;\n\tserver?: string;\n}\n\ninterface ToolResultBlock {\n\ttype: string;\n\ttool_use_id: string;\n\tis_error?: boolean;\n\tcontent?: unknown;\n}\n\n// Claude reports its cache counters apart from input_tokens already.\nfunction toTokens(usage: NonNullableUsage): Tokens {\n\treturn {\n\t\tinputTokens: usage.input_tokens,\n\t\treadCacheTokens: usage.cache_read_input_tokens,\n\t\twrittenCacheTokens: usage.cache_creation_input_tokens,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\nfunction emitProgress(callback: Callback, event: ProgressEvent): void {\n\ttry {\n\t\tcallback(event);\n\t} catch (error) {\n\t\tthrow classifyHostFailure(error, 'Claude progress callback failed');\n\t}\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n\treturn typeof value === 'string' ? value : undefined;\n}\n\nfunction toolResultBlock(value: unknown): ToolResultBlock | undefined {\n\tconst block = asRecord(value);\n\tif (!block || typeof block.type !== 'string' || typeof block.tool_use_id !== 'string') {\n\t\treturn undefined;\n\t}\n\n\treturn block as unknown as ToolResultBlock;\n}\n\nfunction toolResultId(value: unknown): string | undefined {\n\treturn toolResultBlock(value)?.tool_use_id;\n}\n\nfunction fileChange(\n\tname: 'Edit' | 'Write',\n\ttool: PendingTool,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tconst inputPath = stringValue(tool.input.file_path);\n\tconst outputPath = stringValue(asRecord(output)?.filePath);\n\tconst path = outputPath ?? inputPath;\n\tif (!path) return undefined;\n\n\tconst kind =\n\t\tname === 'Write' && stringValue(asRecord(output)?.type) === 'create' ? 'add' : 'update';\n\treturn { type: 'fileChange', changes: [{ path, kind }] };\n}\n\nfunction todoList(tool: PendingTool): ProgressEvent | undefined {\n\tif (!Array.isArray(tool.input.todos)) return undefined;\n\n\tconst items = tool.input.todos.flatMap(todo => {\n\t\tconst item = asRecord(todo);\n\t\tconst text = stringValue(item?.content);\n\t\tconst status = stringValue(item?.status);\n\t\treturn text && status ? [{ text, completed: status === 'completed' }] : [];\n\t});\n\n\treturn { type: 'todoList', items };\n}\n\nfunction mcpTool(tool: PendingTool, result: ToolResultBlock): ProgressEvent | undefined {\n\tconst server = tool.server;\n\tconst toolName = tool.name.startsWith('mcp__')\n\t\t? tool.name.slice('mcp__'.length).split('__').slice(1).join('__')\n\t\t: tool.name;\n\tif (!server || !toolName) return undefined;\n\n\treturn {\n\t\ttype: 'mcpTool',\n\t\tserver,\n\t\ttool: toolName,\n\t\tstatus: result.is_error ? 'failed' : 'completed',\n\t};\n}\n\n// Tools without narration (Read, Grep, Task, ...) are a presentation choice, not an unknown:\n// the tool set is open-ended, so warning here would only produce noise.\nfunction describeCompletedTool(\n\ttool: PendingTool,\n\tresult: ToolResultBlock,\n\toutput: unknown,\n): ProgressEvent | undefined {\n\tif (tool.name === 'Bash') {\n\t\tconst exitCode = asRecord(output)?.exitCode ?? asRecord(output)?.exit_code;\n\t\treturn {\n\t\t\ttype: 'command',\n\t\t\tcommand: stringValue(tool.input.command) ?? '',\n\t\t\t...(typeof exitCode === 'number' ? { exitCode } : {}),\n\t\t};\n\t}\n\n\tif (tool.name === 'WebSearch') {\n\t\tconst query = stringValue(tool.input.query);\n\t\treturn query ? { type: 'search', query } : undefined;\n\t}\n\n\tif (tool.name === 'Edit' || tool.name === 'Write') {\n\t\treturn result.is_error ? undefined : fileChange(tool.name, tool, output);\n\t}\n\n\tif (tool.name === 'TodoWrite') {\n\t\treturn result.is_error ? undefined : todoList(tool);\n\t}\n\n\tif (tool.name.startsWith('mcp__') || tool.server) {\n\t\treturn mcpTool(tool, result);\n\t}\n\n\treturn undefined;\n}\n\nexport class ClaudeAgent implements Agent {\n\tprivate model: ClaudeModel;\n\tprivate autoApprove: boolean;\n\tprivate reasoningEffort: ClaudeReasoningEffort;\n\tprivate sessionId?: string;\n\tprivate logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Claude supports, so it validates them instead of trusting the caller.\n\tconstructor({\n\t\tmodel,\n\t\tautoApprove = false,\n\t\treasoningEffort = 'high',\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\tautoApprove?: boolean;\n\t\treasoningEffort?: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\tif (!isOneOf(claudeModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Claude model; expected one of: ${claudeModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (!isOneOf(claudeReasoningEfforts, reasoningEffort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${reasoningEffort}\" is not a Claude reasoning effort; expected one of: ${claudeReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\n\t\tthis.model = model;\n\t\tthis.autoApprove = autoApprove;\n\t\tthis.reasoningEffort = reasoningEffort;\n\t\tthis.logger = logger;\n\t}\n\n\tasync run(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse> {\n\t\tsignal.throwIfAborted();\n\t\tconst start = Date.now();\n\n\t\tlet stream: Query;\n\n\t\ttry {\n\t\t\tstream = query({\n\t\t\t\tprompt,\n\t\t\t\toptions: {\n\t\t\t\t\teffort: this.reasoningEffort,\n\t\t\t\t\tmodel: this.model,\n\t\t\t\t\tmaxTurns: 3,\n\t\t\t\t\tcwd: process.cwd(),\n\t\t\t\t\tresume: this.sessionId,\n\t\t\t\t\t...(this.autoApprove\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tpermissionMode: 'bypassPermissions' as const,\n\t\t\t\t\t\t\t\tallowDangerouslySkipPermissions: true,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'Claude refused the request');\n\t\t}\n\n\t\tconst closeStream = () => {\n\t\t\tstream.close();\n\t\t};\n\t\tsignal.addEventListener('abort', closeStream, { once: true });\n\n\t\ttry {\n\t\t\treturn await this.parseResponse(stream, signal, callback, start);\n\t\t} finally {\n\t\t\tsignal.removeEventListener('abort', closeStream);\n\t\t}\n\t}\n\n\tprivate async parseResponse(\n\t\tstream: Query,\n\t\tsignal: AbortSignal,\n\t\tcallback: Callback,\n\t\tstart: number,\n\t): Promise<AgentResponse> {\n\t\tconst lines: string[] = [];\n\t\tlet resultMessage: SDKResultSuccess | undefined;\n\t\tconst pendingTools = new Map<string, PendingTool>();\n\n\t\t// Once Claude sent an assistant message, the provider answered: a failure after that\n\t\t// without usage leaves the run's count unknown, unlike one that never got an answer.\n\t\tlet answered = false;\n\n\t\ttry {\n\t\t\tconst messages = classifiedProviderStream(stream, 'Claude stream ended unexpectedly');\n\n\t\t\tfor await (const message of messages) {\n\t\t\t\tthis.sessionId ??= message.session_id;\n\n\t\t\t\ttry {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'assistant':\n\t\t\t\t\t\t\tanswered = true;\n\t\t\t\t\t\t\tthis.handleAssistantMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'user':\n\t\t\t\t\t\t\tthis.handleUserMessage(message, pendingTools, callback);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'result':\n\t\t\t\t\t\t\tif (message.subtype === 'success') {\n\t\t\t\t\t\t\t\tlines.push(message.result);\n\t\t\t\t\t\t\t\tresultMessage = message;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow new RecoverableError('Claude sdk error', {\n\t\t\t\t\t\t\t\t\tcause: [message.stop_reason, message.terminal_reason, ...message.errors].join(\n\t\t\t\t\t\t\t\t\t\t',',\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t// A failed result still reports what the turn spent.\n\t\t\t\t\t\t\t\t\ttokens: toTokens(message.usage),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'system':\n\t\t\t\t\t\t\tthis.handleSystemMessage(message);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// Known messages with nothing to narrate or report.\n\t\t\t\t\t\tcase 'stream_event':\n\t\t\t\t\t\tcase 'tool_progress':\n\t\t\t\t\t\tcase 'tool_use_summary':\n\t\t\t\t\t\tcase 'auth_status':\n\t\t\t\t\t\tcase 'rate_limit_event':\n\t\t\t\t\t\tcase 'prompt_suggestion':\n\t\t\t\t\t\tcase 'conversation_reset':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t// `never` breaks the build when an SDK upgrade adds a message type; the\n\t\t\t\t\t\t\t// warning covers a CLI binary that is newer than the types.\n\t\t\t\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude message type');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow classifyLocalFailure(error, 'Claude failed while mapping progress');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsignal.throwIfAborted();\n\n\t\t\tif (!resultMessage) {\n\t\t\t\t// The turn's work stands; only its accounting is missing.\n\t\t\t\tthis.warn('Claude ended a turn without a result message; its usage is unknown');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// A failed result reports the turn's usage itself.\n\t\t\tconst reported =\n\t\t\t\t(error instanceof RecoverableError || error instanceof UnrecoverableError) &&\n\t\t\t\terror.tokens !== undefined;\n\t\t\tthrow answered && !reported ? withSpentTokens(error, undefined, true) : error;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: lines.join('\\n'),\n\t\t\ttokens: resultMessage && toTokens(resultMessage.usage),\n\t\t\t// Measured here, like the other engines, so it exists even without a result message.\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n\n\tprivate handleSystemMessage(message: SDKSystemMessage): void {\n\t\tswitch (message.subtype) {\n\t\t\t// Failures the SDK handled without failing the turn: only a warning makes them visible.\n\t\t\tcase 'api_retry':\n\t\t\tcase 'model_refusal_fallback':\n\t\t\tcase 'model_refusal_no_fallback':\n\t\t\tcase 'permission_denied':\n\t\t\tcase 'mirror_error':\n\t\t\t\tthis.warn(message, 'Claude reported a failure without failing the turn');\n\t\t\t\treturn;\n\t\t\t// Known messages with nothing to narrate or report.\n\t\t\tcase 'init':\n\t\t\tcase 'compact_boundary':\n\t\t\tcase 'status':\n\t\t\tcase 'control_request_progress':\n\t\t\tcase 'local_command_output':\n\t\t\tcase 'hook_started':\n\t\t\tcase 'hook_progress':\n\t\t\tcase 'hook_response':\n\t\t\tcase 'plugin_install':\n\t\t\tcase 'task_notification':\n\t\t\tcase 'task_started':\n\t\t\tcase 'task_updated':\n\t\t\tcase 'task_progress':\n\t\t\tcase 'background_tasks_changed':\n\t\t\tcase 'thinking_tokens':\n\t\t\tcase 'session_state_changed':\n\t\t\tcase 'worker_shutting_down':\n\t\t\tcase 'commands_changed':\n\t\t\tcase 'notification':\n\t\t\tcase 'files_persisted':\n\t\t\tcase 'memory_recall':\n\t\t\tcase 'elicitation_complete':\n\t\t\tcase 'informational':\n\t\t\t\treturn;\n\t\t\tdefault: {\n\t\t\t\tconst unknownMessage: never = message;\n\t\t\t\tthis.warn(unknownMessage, 'Unknown Claude system message');\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleAssistantMessage(\n\t\tmessage: SDKAssistantMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tfor (const block of message.message.content) {\n\t\t\tswitch (block.type) {\n\t\t\t\tcase 'text':\n\t\t\t\t\temitProgress(callback, { type: 'agentMessage', message: block.text });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'thinking':\n\t\t\t\t\temitProgress(callback, { type: 'reasoning', message: block.thinking });\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'tool_use':\n\t\t\t\tcase 'server_tool_use':\n\t\t\t\tcase 'mcp_tool_use': {\n\t\t\t\t\tconst input = asRecord(block.input);\n\t\t\t\t\tif (input) {\n\t\t\t\t\t\tpendingTools.set(block.id, {\n\t\t\t\t\t\t\tname: block.name === 'web_search' ? 'WebSearch' : block.name,\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t...('server_name' in block && typeof block.server_name === 'string'\n\t\t\t\t\t\t\t\t? { server: block.server_name }\n\t\t\t\t\t\t\t\t: parseMcpServer(block.name)),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'web_search_tool_result':\n\t\t\t\tcase 'web_fetch_tool_result':\n\t\t\t\tcase 'advisor_tool_result':\n\t\t\t\tcase 'code_execution_tool_result':\n\t\t\t\tcase 'bash_code_execution_tool_result':\n\t\t\t\tcase 'text_editor_code_execution_tool_result':\n\t\t\t\tcase 'tool_search_tool_result':\n\t\t\t\tcase 'mcp_tool_result':\n\t\t\t\t\tthis.handleCompletedTool(block, pendingTools, callback);\n\t\t\t\t\tbreak;\n\t\t\t\t// Known blocks with nothing to narrate.\n\t\t\t\tcase 'redacted_thinking':\n\t\t\t\tcase 'container_upload':\n\t\t\t\tcase 'compaction':\n\t\t\t\tcase 'fallback':\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {\n\t\t\t\t\tconst unknownBlock: never = block;\n\t\t\t\t\tthis.warn(unknownBlock, 'Unknown Claude content block');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleUserMessage(\n\t\tmessage: SDKUserMessage,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t): void {\n\t\tif (!Array.isArray(message.message.content)) return;\n\n\t\tfor (const block of message.message.content) {\n\t\t\tthis.handleCompletedTool(block, pendingTools, callback, message.tool_use_result);\n\t\t}\n\t}\n\n\tprivate handleCompletedTool(\n\t\tblock: unknown,\n\t\tpendingTools: Map<string, PendingTool>,\n\t\tcallback: Callback,\n\t\toutput?: unknown,\n\t): void {\n\t\tconst id = toolResultId(block);\n\t\tif (!id) return;\n\n\t\tconst tool = pendingTools.get(id);\n\t\tif (!tool) return;\n\n\t\tpendingTools.delete(id);\n\t\tconst result = toolResultBlock(block);\n\t\tif (!result) return;\n\n\t\tconst description = describeCompletedTool(tool, result, output ?? result.content);\n\t\tif (description) emitProgress(callback, description);\n\t}\n\n\tprivate warn(...args: unknown[]): void {\n\t\ttreatErrors(\n\t\t\t() => {\n\t\t\t\tthis.logger.warn(...args);\n\t\t\t},\n\t\t\tclassifyHostFailure,\n\t\t\t'Claude logger failed while reporting progress',\n\t\t);\n\t}\n}\n\nfunction parseMcpServer(name: string): { server: string } | undefined {\n\tif (!name.startsWith('mcp__')) return undefined;\n\n\tconst server = name.slice('mcp__'.length).split('__')[0];\n\treturn server ? { server } : undefined;\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { type Agent, type AgentResponse, type Callback } from '../../../../agent/domain/agent.ts';
2
- import type { ILogger } from '../../../../shared/domain/logger.ts';
1
+ import { type Agent, type AgentResponse, type Callback } from '#src/agent/domain/agent';
2
+ import type { ILogger } from '#src/shared/domain/logger';
3
3
  export declare const codexModels: readonly ["gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-luna", "gpt-5.6-terra"];
4
4
  export type CodexModel = (typeof codexModels)[number];
5
5
  export declare const codexReasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max", "ultra"];
@@ -1,8 +1,8 @@
1
1
  import { Codex, } from '@openai/codex-sdk';
2
- import {} from "../../../../agent/domain/agent.js";
3
- import { InvalidAgentConfigError, RecoverableError, UnrecoverableError, withSpentTokens, } from "../../../../agent/domain/errors.js";
4
- import { classifiedProviderStream, classifyHostFailure, classifyLocalFailure, classifyProviderFailure, describeFailure, treatErrors, } from "../../../../agent/domain/providerFailure.js";
5
- import { isOneOf } from "../../../../shared/domain/isOneOf.js";
2
+ import {} from '#src/agent/domain/agent';
3
+ import { InvalidAgentConfigError, RecoverableError, UnrecoverableError, withSpentTokens, } from '#src/agent/domain/errors';
4
+ import { classifiedProviderStream, classifyHostFailure, classifyLocalFailure, classifyProviderFailure, describeFailure, treatErrors, } from '#src/agent/domain/providerFailure';
5
+ import { isOneOf } from '#src/shared/domain/isOneOf';
6
6
  // The SDK types `model` as a plain string, so this list is maintained by hand.
7
7
  export const codexModels = ['gpt-6-astra', 'gpt-5.6-sol', 'gpt-5.6-luna', 'gpt-5.6-terra'];
8
8
  // The efforts Codex's model catalog lists; the SDK also types 'minimal' and 'persistent', which
@@ -1 +1 @@
1
- {"version":3,"file":"codexAgent.js","sourceRoot":"","sources":["../../../../../src/engines/codex/infrastructure/model/codexAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tCodex,\n\ttype ModelReasoningEffort,\n\ttype Thread,\n\ttype ThreadEvent,\n\ttype ThreadItem,\n\ttype Usage,\n} from '@openai/codex-sdk';\nimport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressEvent,\n} from '../../../../agent/domain/agent.ts';\nimport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '../../../../agent/domain/errors.ts';\nimport {\n\tclassifiedProviderStream,\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\tdescribeFailure,\n\ttreatErrors,\n} from '../../../../agent/domain/providerFailure.ts';\nimport type { ILogger } from '../../../../shared/domain/logger.ts';\nimport type { Tokens } from '../../../../shared/domain/tokens.ts';\nimport { isOneOf } from '../../../../shared/domain/isOneOf.ts';\n\n// The SDK types `model` as a plain string, so this list is maintained by hand.\nexport const codexModels = ['gpt-6-astra', 'gpt-5.6-sol', 'gpt-5.6-luna', 'gpt-5.6-terra'] as const;\nexport type CodexModel = (typeof codexModels)[number];\n\n// The efforts Codex's model catalog lists; the SDK also types 'minimal' and 'persistent', which\n// none of the models above supports. `satisfies` only proves this is a subset of the SDK's type,\n// so an SDK upgrade that adds an effort has to be reconciled here by hand.\nexport const codexReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n\t'ultra',\n] as const satisfies readonly ModelReasoningEffort[];\nexport type CodexReasoningEffort = (typeof codexReasoningEfforts)[number];\n\ninterface StreamedTurn {\n\tevents: AsyncGenerator<ThreadEvent>;\n}\n\nfunction convertEventToItem(event: ThreadEvent): ThreadItem | undefined {\n\tif (event.type === 'error')\n\t\tthrow new UnrecoverableError('Codex stream error', { cause: event.message });\n\n\tif (event.type === 'turn.failed')\n\t\tthrow new UnrecoverableError('Turn failed from codex sdk', { cause: event.error.message });\n\n\tif (event.type === 'item.completed') return event.item;\n\n\treturn undefined;\n}\n\nfunction describeItem(item: ThreadItem, logger: ILogger): ProgressEvent | undefined {\n\tswitch (item.type) {\n\t\tcase 'agent_message':\n\t\t\treturn { type: 'agentMessage', message: item.text };\n\t\tcase 'reasoning':\n\t\t\treturn { type: 'reasoning', message: item.text };\n\t\tcase 'command_execution':\n\t\t\treturn { type: 'command', command: item.command, exitCode: item.exit_code };\n\t\tcase 'web_search':\n\t\t\treturn { type: 'search', query: item.query };\n\t\tcase 'file_change':\n\t\t\treturn { type: 'fileChange', changes: item.changes };\n\t\tcase 'mcp_tool_call': {\n\t\t\tif (item.error) {\n\t\t\t\tthrow new RecoverableError('skill failed', { cause: item.error.message });\n\t\t\t}\n\t\t\treturn { type: 'mcpTool', server: item.server, tool: item.tool, status: item.status };\n\t\t}\n\t\tcase 'todo_list':\n\t\t\treturn { type: 'todoList', items: item.items };\n\t\tcase 'error':\n\t\t\tthrow new RecoverableError('error while using the codex tools', { cause: item.message });\n\t\tdefault:\n\t\t\ttreatErrors(\n\t\t\t\t() => {\n\t\t\t\t\tlogger.warn(item, 'new type');\n\t\t\t\t},\n\t\t\t\tclassifyHostFailure,\n\t\t\t\t'Codex logger failed while reporting progress',\n\t\t\t);\n\t\t\treturn undefined;\n\t}\n}\n\n// Codex counts cached tokens inside input_tokens; Tokens keeps them apart.\nfunction toTokens(usage: Usage): Tokens {\n\treturn {\n\t\tinputTokens: usage.input_tokens - usage.cached_input_tokens - usage.cache_write_input_tokens,\n\t\treadCacheTokens: usage.cached_input_tokens,\n\t\twrittenCacheTokens: usage.cache_write_input_tokens,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\nexport class CodexAgent implements Agent {\n\tprivate thread: Thread;\n\tprivate logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Codex supports, so it validates them instead of trusting the caller.\n\tconstructor({\n\t\tmodel,\n\t\tautoApprove = false,\n\t\treasoningEffort = 'high',\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\tautoApprove?: boolean;\n\t\treasoningEffort?: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\t// Checked before the SDK is involved: an unsupported value is the caller's mistake, not\n\t\t// a configuration Codex rejected.\n\t\tif (!isOneOf(codexModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Codex model; expected one of: ${codexModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (!isOneOf(codexReasoningEfforts, reasoningEffort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${reasoningEffort}\" is not a Codex reasoning effort; expected one of: ${codexReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\t// The one per-model gap in Codex's catalog.\n\t\tif (model === 'gpt-5.6-luna' && reasoningEffort === 'ultra') {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t'\"gpt-5.6-luna\" does not support the \"ultra\" reasoning effort',\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst sdk = new Codex();\n\t\t\tthis.thread = sdk.startThread({\n\t\t\t\tmodel,\n\t\t\t\tmodelReasoningEffort: reasoningEffort,\n\t\t\t\t...(autoApprove\n\t\t\t\t\t? { approvalPolicy: 'never' as const, sandboxMode: 'danger-full-access' as const }\n\t\t\t\t\t: {}),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t// Not recoverable, unlike a request: a thread the SDK refused to open at all is\n\t\t\t// rejected configuration, and running the same constructor again cannot fix it.\n\t\t\tthrow new UnrecoverableError('Codex rejected the thread configuration', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\n\t\tthis.logger = logger;\n\t}\n\n\tasync run(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse> {\n\t\tconst start = Date.now();\n\t\tlet turn: StreamedTurn;\n\n\t\ttry {\n\t\t\tturn = await this.thread.runStreamed(prompt, { signal });\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'Codex refused the request');\n\t\t}\n\n\t\treturn await this.parseResponse(turn, callback, start);\n\t}\n\n\tprivate async parseResponse(\n\t\tturn: StreamedTurn,\n\t\tcallback: Callback,\n\t\tstart: number,\n\t): Promise<AgentResponse> {\n\t\tconst lines: string[] = [];\n\t\tlet usage: Usage | undefined = undefined;\n\n\t\t// Once Codex produced an item, the provider answered: a failure after that without usage\n\t\t// leaves the run's count unknown, unlike one that never got an answer.\n\t\tlet answered = false;\n\n\t\ttry {\n\t\t\tconst events = classifiedProviderStream(turn.events, 'Codex stream ended unexpectedly');\n\n\t\t\tfor await (const event of events) {\n\t\t\t\t// A `turn.failed` alone may be a quota or authentication failure with no model work.\n\t\t\t\tif (event.type.startsWith('item.')) answered = true;\n\t\t\t\tif (event.type === 'turn.completed') {\n\t\t\t\t\tusage = event.usage;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst item = convertEventToItem(event);\n\n\t\t\t\tif (!item) continue;\n\n\t\t\t\tlet description: ProgressEvent | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tdescription = describeItem(item, this.logger);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow classifyLocalFailure(error, 'Codex failed while mapping progress');\n\t\t\t\t}\n\n\t\t\t\tif (description) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcallback(description);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthrow classifyHostFailure(error, 'Codex progress callback failed');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (description?.type === 'agentMessage') lines.push(description.message);\n\t\t\t}\n\n\t\t\tif (!usage) {\n\t\t\t\t// The turn's work stands; only its accounting is missing.\n\t\t\t\ttreatErrors(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.logger.warn('Codex ended a turn without reporting usage');\n\t\t\t\t\t},\n\t\t\t\t\tclassifyHostFailure,\n\t\t\t\t\t'Codex logger failed while reporting missing usage',\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (usage) throw withSpentTokens(error, toTokens(usage));\n\t\t\tthrow answered ? withSpentTokens(error, undefined, true) : error;\n\t\t}\n\n\t\treturn {\n\t\t\t// Empty when the turn only ran commands or edited files.\n\t\t\tresponse: lines.join('\\n'),\n\t\t\ttokens: usage && toTokens(usage),\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"codexAgent.js","sourceRoot":"","sources":["../../../../../src/engines/codex/infrastructure/model/codexAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tCodex,\n\ttype ModelReasoningEffort,\n\ttype Thread,\n\ttype ThreadEvent,\n\ttype ThreadItem,\n\ttype Usage,\n} from '@openai/codex-sdk';\nimport {\n\ttype Agent,\n\ttype AgentResponse,\n\ttype Callback,\n\ttype ProgressEvent,\n} from '#src/agent/domain/agent';\nimport {\n\tInvalidAgentConfigError,\n\tRecoverableError,\n\tUnrecoverableError,\n\twithSpentTokens,\n} from '#src/agent/domain/errors';\nimport {\n\tclassifiedProviderStream,\n\tclassifyHostFailure,\n\tclassifyLocalFailure,\n\tclassifyProviderFailure,\n\tdescribeFailure,\n\ttreatErrors,\n} from '#src/agent/domain/providerFailure';\nimport type { ILogger } from '#src/shared/domain/logger';\nimport type { Tokens } from '#src/shared/domain/tokens';\nimport { isOneOf } from '#src/shared/domain/isOneOf';\n\n// The SDK types `model` as a plain string, so this list is maintained by hand.\nexport const codexModels = ['gpt-6-astra', 'gpt-5.6-sol', 'gpt-5.6-luna', 'gpt-5.6-terra'] as const;\nexport type CodexModel = (typeof codexModels)[number];\n\n// The efforts Codex's model catalog lists; the SDK also types 'minimal' and 'persistent', which\n// none of the models above supports. `satisfies` only proves this is a subset of the SDK's type,\n// so an SDK upgrade that adds an effort has to be reconciled here by hand.\nexport const codexReasoningEfforts = [\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n\t'max',\n\t'ultra',\n] as const satisfies readonly ModelReasoningEffort[];\nexport type CodexReasoningEffort = (typeof codexReasoningEfforts)[number];\n\ninterface StreamedTurn {\n\tevents: AsyncGenerator<ThreadEvent>;\n}\n\nfunction convertEventToItem(event: ThreadEvent): ThreadItem | undefined {\n\tif (event.type === 'error')\n\t\tthrow new UnrecoverableError('Codex stream error', { cause: event.message });\n\n\tif (event.type === 'turn.failed')\n\t\tthrow new UnrecoverableError('Turn failed from codex sdk', { cause: event.error.message });\n\n\tif (event.type === 'item.completed') return event.item;\n\n\treturn undefined;\n}\n\nfunction describeItem(item: ThreadItem, logger: ILogger): ProgressEvent | undefined {\n\tswitch (item.type) {\n\t\tcase 'agent_message':\n\t\t\treturn { type: 'agentMessage', message: item.text };\n\t\tcase 'reasoning':\n\t\t\treturn { type: 'reasoning', message: item.text };\n\t\tcase 'command_execution':\n\t\t\treturn { type: 'command', command: item.command, exitCode: item.exit_code };\n\t\tcase 'web_search':\n\t\t\treturn { type: 'search', query: item.query };\n\t\tcase 'file_change':\n\t\t\treturn { type: 'fileChange', changes: item.changes };\n\t\tcase 'mcp_tool_call': {\n\t\t\tif (item.error) {\n\t\t\t\tthrow new RecoverableError('skill failed', { cause: item.error.message });\n\t\t\t}\n\t\t\treturn { type: 'mcpTool', server: item.server, tool: item.tool, status: item.status };\n\t\t}\n\t\tcase 'todo_list':\n\t\t\treturn { type: 'todoList', items: item.items };\n\t\tcase 'error':\n\t\t\tthrow new RecoverableError('error while using the codex tools', { cause: item.message });\n\t\tdefault:\n\t\t\ttreatErrors(\n\t\t\t\t() => {\n\t\t\t\t\tlogger.warn(item, 'new type');\n\t\t\t\t},\n\t\t\t\tclassifyHostFailure,\n\t\t\t\t'Codex logger failed while reporting progress',\n\t\t\t);\n\t\t\treturn undefined;\n\t}\n}\n\n// Codex counts cached tokens inside input_tokens; Tokens keeps them apart.\nfunction toTokens(usage: Usage): Tokens {\n\treturn {\n\t\tinputTokens: usage.input_tokens - usage.cached_input_tokens - usage.cache_write_input_tokens,\n\t\treadCacheTokens: usage.cached_input_tokens,\n\t\twrittenCacheTokens: usage.cache_write_input_tokens,\n\t\toutputTokens: usage.output_tokens,\n\t};\n}\n\nexport class CodexAgent implements Agent {\n\tprivate thread: Thread;\n\tprivate logger: ILogger;\n\n\t// `model` and `reasoningEffort` are untyped on purpose: this adapter is the one that knows\n\t// what Codex supports, so it validates them instead of trusting the caller.\n\tconstructor({\n\t\tmodel,\n\t\tautoApprove = false,\n\t\treasoningEffort = 'high',\n\t\tlogger,\n\t}: {\n\t\tmodel: string;\n\t\tautoApprove?: boolean;\n\t\treasoningEffort?: string;\n\t\tlogger: ILogger;\n\t}) {\n\t\t// Checked before the SDK is involved: an unsupported value is the caller's mistake, not\n\t\t// a configuration Codex rejected.\n\t\tif (!isOneOf(codexModels, model)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${model}\" is not a Codex model; expected one of: ${codexModels.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\tif (!isOneOf(codexReasoningEfforts, reasoningEffort)) {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t`\"${reasoningEffort}\" is not a Codex reasoning effort; expected one of: ${codexReasoningEfforts.join(', ')}`,\n\t\t\t);\n\t\t}\n\t\t// The one per-model gap in Codex's catalog.\n\t\tif (model === 'gpt-5.6-luna' && reasoningEffort === 'ultra') {\n\t\t\tthrow new InvalidAgentConfigError(\n\t\t\t\t'\"gpt-5.6-luna\" does not support the \"ultra\" reasoning effort',\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst sdk = new Codex();\n\t\t\tthis.thread = sdk.startThread({\n\t\t\t\tmodel,\n\t\t\t\tmodelReasoningEffort: reasoningEffort,\n\t\t\t\t...(autoApprove\n\t\t\t\t\t? { approvalPolicy: 'never' as const, sandboxMode: 'danger-full-access' as const }\n\t\t\t\t\t: {}),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t// Not recoverable, unlike a request: a thread the SDK refused to open at all is\n\t\t\t// rejected configuration, and running the same constructor again cannot fix it.\n\t\t\tthrow new UnrecoverableError('Codex rejected the thread configuration', {\n\t\t\t\tcause: describeFailure(error),\n\t\t\t});\n\t\t}\n\n\t\tthis.logger = logger;\n\t}\n\n\tasync run(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse> {\n\t\tconst start = Date.now();\n\t\tlet turn: StreamedTurn;\n\n\t\ttry {\n\t\t\tturn = await this.thread.runStreamed(prompt, { signal });\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'Codex refused the request');\n\t\t}\n\n\t\treturn await this.parseResponse(turn, callback, start);\n\t}\n\n\tprivate async parseResponse(\n\t\tturn: StreamedTurn,\n\t\tcallback: Callback,\n\t\tstart: number,\n\t): Promise<AgentResponse> {\n\t\tconst lines: string[] = [];\n\t\tlet usage: Usage | undefined = undefined;\n\n\t\t// Once Codex produced an item, the provider answered: a failure after that without usage\n\t\t// leaves the run's count unknown, unlike one that never got an answer.\n\t\tlet answered = false;\n\n\t\ttry {\n\t\t\tconst events = classifiedProviderStream(turn.events, 'Codex stream ended unexpectedly');\n\n\t\t\tfor await (const event of events) {\n\t\t\t\t// A `turn.failed` alone may be a quota or authentication failure with no model work.\n\t\t\t\tif (event.type.startsWith('item.')) answered = true;\n\t\t\t\tif (event.type === 'turn.completed') {\n\t\t\t\t\tusage = event.usage;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst item = convertEventToItem(event);\n\n\t\t\t\tif (!item) continue;\n\n\t\t\t\tlet description: ProgressEvent | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tdescription = describeItem(item, this.logger);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow classifyLocalFailure(error, 'Codex failed while mapping progress');\n\t\t\t\t}\n\n\t\t\t\tif (description) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcallback(description);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthrow classifyHostFailure(error, 'Codex progress callback failed');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (description?.type === 'agentMessage') lines.push(description.message);\n\t\t\t}\n\n\t\t\tif (!usage) {\n\t\t\t\t// The turn's work stands; only its accounting is missing.\n\t\t\t\ttreatErrors(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.logger.warn('Codex ended a turn without reporting usage');\n\t\t\t\t\t},\n\t\t\t\t\tclassifyHostFailure,\n\t\t\t\t\t'Codex logger failed while reporting missing usage',\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (usage) throw withSpentTokens(error, toTokens(usage));\n\t\t\tthrow answered ? withSpentTokens(error, undefined, true) : error;\n\t\t}\n\n\t\treturn {\n\t\t\t// Empty when the turn only ran commands or edited files.\n\t\t\tresponse: lines.join('\\n'),\n\t\t\ttokens: usage && toTokens(usage),\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n}\n"]}
@@ -1,6 +1,6 @@
1
- import type { Agent, AgentResponse, Callback } from '../../../agent/domain/agent.ts';
2
- import type { LLMClient } from '../../../llm/domain/llm.ts';
3
- import type { Message } from '../../../llm/domain/message.ts';
1
+ import type { Agent, AgentResponse, Callback } from '#src/agent/domain/agent';
2
+ import type { LLMClient } from '#src/llm/domain/llm';
3
+ import type { Message } from '#src/llm/domain/message';
4
4
  /**
5
5
  * An agent whose conversation is owned by MiKode: every run sends the whole context to a
6
6
  * stateless `LLMClient`. Turn boundaries are the consumer's to emit, as with the other
@@ -1,6 +1,6 @@
1
- import { UnrecoverableError, withSpentTokens } from "../../../agent/domain/errors.js";
2
- import { classifyHostFailure, classifyProviderFailure, treatErrors, } from "../../../agent/domain/providerFailure.js";
3
- import { Conversation } from "../../../llm/domain/conversation.js";
1
+ import { UnrecoverableError, withSpentTokens } from '#src/agent/domain/errors';
2
+ import { classifyHostFailure, classifyProviderFailure, treatErrors, } from '#src/agent/domain/providerFailure';
3
+ import { Conversation } from '#src/llm/domain/conversation';
4
4
  function describePart(part) {
5
5
  return part.type === 'text'
6
6
  ? { type: 'agentMessage', message: part.text }
@@ -1 +1 @@
1
- {"version":3,"file":"llmAgent.js","sourceRoot":"","sources":["../../../../src/engines/domain/model/llmAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, AgentResponse, Callback, ProgressEvent } from '../../../agent/domain/agent.ts';\nimport { UnrecoverableError, withSpentTokens } from '../../../agent/domain/errors.ts';\nimport {\n\tclassifyHostFailure,\n\tclassifyProviderFailure,\n\ttreatErrors,\n} from '../../../agent/domain/providerFailure.ts';\nimport { Conversation } from '../../../llm/domain/conversation.ts';\nimport type { LLMClient, LLMResponse } from '../../../llm/domain/llm.ts';\nimport type { Message, MessagePart } from '../../../llm/domain/message.ts';\n\nfunction describePart(part: MessagePart): ProgressEvent {\n\treturn part.type === 'text'\n\t\t? { type: 'agentMessage', message: part.text }\n\t\t: { type: 'reasoning', message: part.text };\n}\n\n/**\n * An agent whose conversation is owned by MiKode: every run sends the whole context to a\n * stateless `LLMClient`. Turn boundaries are the consumer's to emit, as with the other\n * engines; this agent only narrates what the model produced.\n */\nexport class LLMAgent implements Agent {\n\tprivate readonly llmClient: LLMClient;\n\tprivate readonly conversation: Conversation;\n\n\tconstructor({ llmClient, messages }: { llmClient: LLMClient; messages?: Message[] }) {\n\t\tthis.llmClient = llmClient;\n\t\tthis.conversation = new Conversation(messages);\n\t}\n\n\tasync run(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse> {\n\t\tconst start = Date.now();\n\t\tconst userMessage: Message = { role: 'user', content: [{ type: 'text', text: prompt }] };\n\n\t\tlet response: LLMResponse;\n\t\ttry {\n\t\t\t// The prompt is sent as a copy so the one recorded below is the one the agent built.\n\t\t\tresponse = await this.llmClient.send(\n\t\t\t\t[...this.conversation.getContext(), structuredClone(userMessage)],\n\t\t\t\tsignal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'The LLM call failed');\n\t\t}\n\n\t\tif (response.stopReason !== 'completed') {\n\t\t\tthrow new UnrecoverableError('The LLM stopped before completing its answer', {\n\t\t\t\tcause: `The model stopped with \"${response.stopReason}\".`,\n\t\t\t\t// The call was billed even though its answer is unusable.\n\t\t\t\ttokens: response.usage,\n\t\t\t\tusageUnreported: !response.usage,\n\t\t\t});\n\t\t}\n\n\t\tthis.conversation.addExchange(userMessage, response.message);\n\n\t\ttry {\n\t\t\tfor (const part of response.message.content) {\n\t\t\t\ttreatErrors(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tcallback(describePart(part));\n\t\t\t\t\t},\n\t\t\t\t\tclassifyHostFailure,\n\t\t\t\t\t'LLM agent progress callback failed',\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// The answer already arrived, so the run spent its tokens whatever the consumer did.\n\t\t\tthrow withSpentTokens(error, response.usage, !response.usage);\n\t\t}\n\n\t\tconst text = response.message.content\n\t\t\t.filter(part => part.type === 'text')\n\t\t\t.map(part => part.text)\n\t\t\t.join('\\n');\n\n\t\treturn {\n\t\t\tresponse: text,\n\t\t\ttokens: response.usage,\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"llmAgent.js","sourceRoot":"","sources":["../../../../src/engines/domain/model/llmAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, AgentResponse, Callback, ProgressEvent } from '#src/agent/domain/agent';\nimport { UnrecoverableError, withSpentTokens } from '#src/agent/domain/errors';\nimport {\n\tclassifyHostFailure,\n\tclassifyProviderFailure,\n\ttreatErrors,\n} from '#src/agent/domain/providerFailure';\nimport { Conversation } from '#src/llm/domain/conversation';\nimport type { LLMClient, LLMResponse } from '#src/llm/domain/llm';\nimport type { Message, MessagePart } from '#src/llm/domain/message';\n\nfunction describePart(part: MessagePart): ProgressEvent {\n\treturn part.type === 'text'\n\t\t? { type: 'agentMessage', message: part.text }\n\t\t: { type: 'reasoning', message: part.text };\n}\n\n/**\n * An agent whose conversation is owned by MiKode: every run sends the whole context to a\n * stateless `LLMClient`. Turn boundaries are the consumer's to emit, as with the other\n * engines; this agent only narrates what the model produced.\n */\nexport class LLMAgent implements Agent {\n\tprivate readonly llmClient: LLMClient;\n\tprivate readonly conversation: Conversation;\n\n\tconstructor({ llmClient, messages }: { llmClient: LLMClient; messages?: Message[] }) {\n\t\tthis.llmClient = llmClient;\n\t\tthis.conversation = new Conversation(messages);\n\t}\n\n\tasync run(prompt: string, signal: AbortSignal, callback: Callback): Promise<AgentResponse> {\n\t\tconst start = Date.now();\n\t\tconst userMessage: Message = { role: 'user', content: [{ type: 'text', text: prompt }] };\n\n\t\tlet response: LLMResponse;\n\t\ttry {\n\t\t\t// The prompt is sent as a copy so the one recorded below is the one the agent built.\n\t\t\tresponse = await this.llmClient.send(\n\t\t\t\t[...this.conversation.getContext(), structuredClone(userMessage)],\n\t\t\t\tsignal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow classifyProviderFailure(error, 'The LLM call failed');\n\t\t}\n\n\t\tif (response.stopReason !== 'completed') {\n\t\t\tthrow new UnrecoverableError('The LLM stopped before completing its answer', {\n\t\t\t\tcause: `The model stopped with \"${response.stopReason}\".`,\n\t\t\t\t// The call was billed even though its answer is unusable.\n\t\t\t\ttokens: response.usage,\n\t\t\t\tusageUnreported: !response.usage,\n\t\t\t});\n\t\t}\n\n\t\tthis.conversation.addExchange(userMessage, response.message);\n\n\t\ttry {\n\t\t\tfor (const part of response.message.content) {\n\t\t\t\ttreatErrors(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tcallback(describePart(part));\n\t\t\t\t\t},\n\t\t\t\t\tclassifyHostFailure,\n\t\t\t\t\t'LLM agent progress callback failed',\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// The answer already arrived, so the run spent its tokens whatever the consumer did.\n\t\t\tthrow withSpentTokens(error, response.usage, !response.usage);\n\t\t}\n\n\t\tconst text = response.message.content\n\t\t\t.filter(part => part.type === 'text')\n\t\t\t.map(part => part.text)\n\t\t\t.join('\\n');\n\n\t\treturn {\n\t\t\tresponse: text,\n\t\t\ttokens: response.usage,\n\t\t\tduration: (Date.now() - start) / 1000,\n\t\t};\n\t}\n}\n"]}
@@ -1,7 +1,7 @@
1
- import type { Agent } from '../../agent/domain/agent.ts';
2
- import { type ClaudeModel, type ClaudeReasoningEffort } from '../../engines/claude/infrastructure/model/claudeAgent.ts';
3
- import { type CodexModel, type CodexReasoningEffort } from '../../engines/codex/infrastructure/model/codexAgent.ts';
4
- import type { ILogger } from '../../shared/domain/logger.ts';
1
+ import type { Agent } from '#src/agent/domain/agent';
2
+ import { type ClaudeModel, type ClaudeReasoningEffort } from '#src/engines/claude/infrastructure/model/claudeAgent';
3
+ import { type CodexModel, type CodexReasoningEffort } from '#src/engines/codex/infrastructure/model/codexAgent';
4
+ import type { ILogger } from '#src/shared/domain/logger';
5
5
  export declare const agentProviders: readonly ["claude", "codex"];
6
6
  export type AgentProvider = (typeof agentProviders)[number];
7
7
  /** Any provider's model. The engine the provider selects rejects one it does not support. */
@@ -47,8 +47,13 @@ export interface CreateOrchestratorOptions {
47
47
  * binary is missing.
48
48
  */
49
49
  export declare function createOrchestrator({ provider, autoApprove, logger, }?: CreateOrchestratorOptions): Agent;
50
+ export declare const llmProviders: readonly ["claude", "openai"];
51
+ export type LLMProvider = (typeof llmProviders)[number];
50
52
  export interface CreateLLMAgentOptions {
51
- /** Defaults to `'gpt-5.6-luna'`. The OpenAI client rejects a model it does not support. */
53
+ /**
54
+ * Defaults to `'claude-sonnet-5'` on Claude and `'gpt-5.6-luna'` on OpenAI. The provider's
55
+ * client rejects a model it does not support.
56
+ */
52
57
  model?: string;
53
58
  /** Sent as the model's instructions on every call. */
54
59
  systemPrompt: string;
@@ -56,13 +61,14 @@ export interface CreateLLMAgentOptions {
56
61
  logger?: ILogger;
57
62
  }
58
63
  /**
59
- * Builds an agent whose conversation MiKode owns, on the OpenAI Responses API, already wrapped
60
- * in the harness's retry policy. Internal while #23 reaches parity with the Agent SDK engines:
61
- * it is not exported from `src/index.ts`, and it takes no provider because OpenAI is the only
62
- * `LLMClient` so far. It runs no tools, so it has no `autoApprove`.
64
+ * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in
65
+ * the harness's retry policy. Internal while #23 reaches parity with the Agent SDK engines: it
66
+ * is not exported from `src/index.ts`. It runs no tools, so it has no `autoApprove`.
63
67
  *
64
- * @throws {InvalidAgentConfigError} for a model the OpenAI client does not support.
65
- * @throws {UnrecoverableError} when the OpenAI client cannot be set up, for example because
66
- * `OPENAI_API_KEY` is missing.
68
+ * @throws {InvalidAgentConfigError} for an unknown provider, or a model its client does not
69
+ * support.
70
+ * @throws {UnrecoverableError} when the client cannot be set up, for example because
71
+ * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing
72
+ * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.
67
73
  */
68
- export declare function createLLMAgent({ model, systemPrompt, logger, }: CreateLLMAgentOptions): Agent;
74
+ export declare function createLLMAgent(provider: LLMProvider, { model, systemPrompt, logger }: CreateLLMAgentOptions): Agent;
@@ -1,13 +1,14 @@
1
- import { InvalidAgentConfigError } from "../../agent/domain/errors.js";
2
- import { ClaudeAgent, } from "../../engines/claude/infrastructure/model/claudeAgent.js";
3
- import { CodexAgent, } from "../../engines/codex/infrastructure/model/codexAgent.js";
4
- import { LLMAgent } from "../../engines/domain/model/llmAgent.js";
5
- import { OpenAILLMClient } from "../../llm/infrastructure/openAILLMClient.js";
6
- import { OrchestratorAgent } from "../../orchestration/domain/model/orchestratorAgent.js";
7
- import { ReviewerDecisionValidator } from "../../orchestration/infrastructure/model/reviewerDecisionValidator.js";
8
- import { RetryingAgent } from "../../retry/domain/model/retryingAgent.js";
9
- import { isOneOf } from "../../shared/domain/isOneOf.js";
10
- import { Logger } from "../../shared/infrastructure/logger.js";
1
+ import { InvalidAgentConfigError } from '#src/agent/domain/errors';
2
+ import { ClaudeAgent, } from '#src/engines/claude/infrastructure/model/claudeAgent';
3
+ import { CodexAgent, } from '#src/engines/codex/infrastructure/model/codexAgent';
4
+ import { LLMAgent } from '#src/engines/domain/model/llmAgent';
5
+ import { ClaudeLLMClient } from '#src/llm/infrastructure/claudeLLMClient';
6
+ import { OpenAILLMClient } from '#src/llm/infrastructure/openAILLMClient';
7
+ import { OrchestratorAgent } from '#src/orchestration/domain/model/orchestratorAgent';
8
+ import { ReviewerDecisionValidator } from '#src/orchestration/infrastructure/model/reviewerDecisionValidator';
9
+ import { RetryingAgent } from '#src/retry/domain/model/retryingAgent';
10
+ import { isOneOf } from '#src/shared/domain/isOneOf';
11
+ import { Logger } from '#src/shared/infrastructure/logger';
11
12
  export const agentProviders = ['claude', 'codex'];
12
13
  export function isAgentProvider(value) {
13
14
  return isOneOf(agentProviders, value);
@@ -90,22 +91,46 @@ export function createOrchestrator({ provider, autoApprove, logger = new Logger(
90
91
  logger,
91
92
  });
92
93
  }
93
- const defaultLLMAgentModel = 'gpt-5.6-luna';
94
+ export const llmProviders = ['claude', 'openai'];
95
+ const defaultLLMAgentModels = {
96
+ claude: 'claude-sonnet-5',
97
+ openai: 'gpt-5.6-luna',
98
+ };
94
99
  /**
95
- * Builds an agent whose conversation MiKode owns, on the OpenAI Responses API, already wrapped
96
- * in the harness's retry policy. Internal while #23 reaches parity with the Agent SDK engines:
97
- * it is not exported from `src/index.ts`, and it takes no provider because OpenAI is the only
98
- * `LLMClient` so far. It runs no tools, so it has no `autoApprove`.
100
+ * Builds an agent whose conversation MiKode owns, on a provider's model API, already wrapped in
101
+ * the harness's retry policy. Internal while #23 reaches parity with the Agent SDK engines: it
102
+ * is not exported from `src/index.ts`. It runs no tools, so it has no `autoApprove`.
99
103
  *
100
- * @throws {InvalidAgentConfigError} for a model the OpenAI client does not support.
101
- * @throws {UnrecoverableError} when the OpenAI client cannot be set up, for example because
102
- * `OPENAI_API_KEY` is missing.
104
+ * @throws {InvalidAgentConfigError} for an unknown provider, or a model its client does not
105
+ * support.
106
+ * @throws {UnrecoverableError} when the client cannot be set up, for example because
107
+ * `OPENAI_API_KEY` is missing. The Anthropic SDK resolves credentials lazily, so a missing
108
+ * `ANTHROPIC_API_KEY` fails the first run instead, with an `UnrecoverableError`.
103
109
  */
104
- export function createLLMAgent({ model = defaultLLMAgentModel, systemPrompt, logger = new Logger(), }) {
105
- const engine = new LLMAgent({
106
- llmClient: new OpenAILLMClient({ model, systemPrompt, logger }),
107
- });
110
+ export function createLLMAgent(provider, { model, systemPrompt, logger = new Logger() }) {
111
+ let llmClient;
112
+ switch (provider) {
113
+ case 'claude':
114
+ llmClient = new ClaudeLLMClient({
115
+ model: model ?? defaultLLMAgentModels.claude,
116
+ systemPrompt,
117
+ logger,
118
+ });
119
+ break;
120
+ case 'openai':
121
+ llmClient = new OpenAILLMClient({
122
+ model: model ?? defaultLLMAgentModels.openai,
123
+ systemPrompt,
124
+ logger,
125
+ });
126
+ break;
127
+ default: {
128
+ // Reachable from untyped input.
129
+ const unknownProvider = provider;
130
+ throw new InvalidAgentConfigError(`"${String(unknownProvider)}" is not an LLM provider; expected one of: ${llmProviders.join(', ')}`);
131
+ }
132
+ }
108
133
  // LLMAgent records nothing from a failed call, so the original prompt is the whole story.
109
- return new RetryingAgent({ inner: engine, logger, noteFailures: false });
134
+ return new RetryingAgent({ inner: new LLMAgent({ llmClient }), logger, noteFailures: false });
110
135
  }
111
136
  //# sourceMappingURL=agentFactory.js.map