@zhixuan92/multi-model-agent-core 0.1.0 → 0.2.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 (82) hide show
  1. package/README.md +0 -6
  2. package/dist/config/schema.d.ts +27 -0
  3. package/dist/config/schema.d.ts.map +1 -1
  4. package/dist/config/schema.js +13 -0
  5. package/dist/config/schema.js.map +1 -1
  6. package/dist/context/context-block-store.d.ts +75 -0
  7. package/dist/context/context-block-store.d.ts.map +1 -0
  8. package/dist/context/context-block-store.js +82 -0
  9. package/dist/context/context-block-store.js.map +1 -0
  10. package/dist/context/expand-context-blocks.d.ts +20 -0
  11. package/dist/context/expand-context-blocks.d.ts.map +1 -0
  12. package/dist/context/expand-context-blocks.js +46 -0
  13. package/dist/context/expand-context-blocks.js.map +1 -0
  14. package/dist/delegate-with-escalation.d.ts +34 -0
  15. package/dist/delegate-with-escalation.d.ts.map +1 -0
  16. package/dist/delegate-with-escalation.js +168 -0
  17. package/dist/delegate-with-escalation.js.map +1 -0
  18. package/dist/index.d.ts +4 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +3 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/model-profiles.json +8 -4
  23. package/dist/provider.d.ts.map +1 -1
  24. package/dist/provider.js +7 -1
  25. package/dist/provider.js.map +1 -1
  26. package/dist/routing/model-profiles.d.ts +1 -0
  27. package/dist/routing/model-profiles.d.ts.map +1 -1
  28. package/dist/routing/model-profiles.js +4 -0
  29. package/dist/routing/model-profiles.js.map +1 -1
  30. package/dist/run-tasks.d.ts +26 -2
  31. package/dist/run-tasks.d.ts.map +1 -1
  32. package/dist/run-tasks.js +61 -19
  33. package/dist/run-tasks.js.map +1 -1
  34. package/dist/runners/claude-runner.d.ts.map +1 -1
  35. package/dist/runners/claude-runner.js +643 -32
  36. package/dist/runners/claude-runner.js.map +1 -1
  37. package/dist/runners/codex-runner.d.ts.map +1 -1
  38. package/dist/runners/codex-runner.js +473 -48
  39. package/dist/runners/codex-runner.js.map +1 -1
  40. package/dist/runners/error-classification.d.ts +30 -0
  41. package/dist/runners/error-classification.d.ts.map +1 -0
  42. package/dist/runners/error-classification.js +72 -0
  43. package/dist/runners/error-classification.js.map +1 -0
  44. package/dist/runners/injection-type.d.ts +17 -0
  45. package/dist/runners/injection-type.d.ts.map +1 -0
  46. package/dist/runners/injection-type.js +27 -0
  47. package/dist/runners/injection-type.js.map +1 -0
  48. package/dist/runners/openai-runner.d.ts +5 -0
  49. package/dist/runners/openai-runner.d.ts.map +1 -1
  50. package/dist/runners/openai-runner.js +508 -36
  51. package/dist/runners/openai-runner.js.map +1 -1
  52. package/dist/runners/prevention.d.ts +41 -0
  53. package/dist/runners/prevention.d.ts.map +1 -0
  54. package/dist/runners/prevention.js +68 -0
  55. package/dist/runners/prevention.js.map +1 -0
  56. package/dist/runners/supervision.d.ts +130 -0
  57. package/dist/runners/supervision.d.ts.map +1 -0
  58. package/dist/runners/supervision.js +238 -0
  59. package/dist/runners/supervision.js.map +1 -0
  60. package/dist/tools/claude-adapter.d.ts.map +1 -1
  61. package/dist/tools/claude-adapter.js +6 -3
  62. package/dist/tools/claude-adapter.js.map +1 -1
  63. package/dist/tools/definitions.d.ts +3 -1
  64. package/dist/tools/definitions.d.ts.map +1 -1
  65. package/dist/tools/definitions.js +56 -5
  66. package/dist/tools/definitions.js.map +1 -1
  67. package/dist/tools/openai-adapter.d.ts.map +1 -1
  68. package/dist/tools/openai-adapter.js +6 -3
  69. package/dist/tools/openai-adapter.js.map +1 -1
  70. package/dist/tools/scratchpad.d.ts +28 -0
  71. package/dist/tools/scratchpad.d.ts.map +1 -0
  72. package/dist/tools/scratchpad.js +49 -0
  73. package/dist/tools/scratchpad.js.map +1 -0
  74. package/dist/tools/tracker.d.ts +38 -2
  75. package/dist/tools/tracker.d.ts.map +1 -1
  76. package/dist/tools/tracker.js +54 -5
  77. package/dist/tools/tracker.js.map +1 -1
  78. package/dist/types.d.ts +184 -2
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/types.js +17 -1
  81. package/dist/types.js.map +1 -1
  82. package/package.json +9 -15
package/dist/types.d.ts CHANGED
@@ -1,10 +1,11 @@
1
+ import type { ContextBlockStore } from './context/context-block-store.js';
1
2
  export type Tier = 'trivial' | 'standard' | 'reasoning';
2
3
  export type Capability = 'file_read' | 'file_write' | 'grep' | 'glob' | 'shell' | 'web_search' | 'web_fetch';
3
4
  export type ToolMode = 'none' | 'full';
4
5
  export type SandboxPolicy = 'none' | 'cwd-only';
5
6
  export type Effort = 'none' | 'low' | 'medium' | 'high';
6
7
  export type CostTier = 'free' | 'low' | 'medium' | 'high';
7
- export type RunStatus = 'ok' | 'error' | 'timeout' | 'max_turns';
8
+ export type RunStatus = 'ok' | 'incomplete' | 'max_turns' | 'timeout' | 'api_aborted' | 'api_error' | 'network_error' | 'error';
8
9
  export interface TaskSpec {
9
10
  prompt: string;
10
11
  /** Provider name. If omitted, core auto-selects. */
@@ -17,6 +18,12 @@ export interface TaskSpec {
17
18
  cwd?: string;
18
19
  effort?: Effort;
19
20
  sandboxPolicy?: SandboxPolicy;
21
+ /** Optional context block ids to expand into the prompt before dispatch.
22
+ * Each id is resolved against `RunTasksRuntime.contextBlockStore` in
23
+ * order and its content is prepended to `prompt` separated by
24
+ * '\n\n---\n\n'. The field is stripped from the task that reaches the
25
+ * provider so runners never see it. See `expandContextBlocks`. */
26
+ contextBlockIds?: string[];
20
27
  }
21
28
  export interface CodexProviderConfig {
22
29
  type: 'codex';
@@ -27,6 +34,14 @@ export interface CodexProviderConfig {
27
34
  sandboxPolicy?: SandboxPolicy;
28
35
  hostedTools?: ('web_search' | 'image_generation' | 'code_interpreter')[];
29
36
  costTier?: CostTier;
37
+ /** Optional pricing in USD per million input tokens. Used to compute RunResult.usage.costUSD. */
38
+ inputCostPerMTok?: number;
39
+ /** Optional pricing in USD per million output tokens. Used to compute RunResult.usage.costUSD. */
40
+ outputCostPerMTok?: number;
41
+ /** Optional override for the per-provider input token soft limit
42
+ * used by the watchdog. When unset, falls back to the model profile
43
+ * default, then to a hardcoded 100_000 fallback. See spec A.1.4. */
44
+ inputTokenSoftLimit?: number;
30
45
  }
31
46
  export interface ClaudeProviderConfig {
32
47
  type: 'claude';
@@ -37,6 +52,13 @@ export interface ClaudeProviderConfig {
37
52
  sandboxPolicy?: SandboxPolicy;
38
53
  hostedTools?: ('web_search' | 'image_generation' | 'code_interpreter')[];
39
54
  costTier?: CostTier;
55
+ /** Optional pricing override; if set, recomputes costUSD from token usage instead of trusting the SDK. */
56
+ inputCostPerMTok?: number;
57
+ outputCostPerMTok?: number;
58
+ /** Optional override for the per-provider input token soft limit
59
+ * used by the watchdog. When unset, falls back to the model profile
60
+ * default, then to a hardcoded 100_000 fallback. See spec A.1.4. */
61
+ inputTokenSoftLimit?: number;
40
62
  }
41
63
  export interface OpenAICompatibleProviderConfig {
42
64
  type: 'openai-compatible';
@@ -51,6 +73,14 @@ export interface OpenAICompatibleProviderConfig {
51
73
  sandboxPolicy?: SandboxPolicy;
52
74
  hostedTools?: ('web_search' | 'image_generation' | 'code_interpreter')[];
53
75
  costTier?: CostTier;
76
+ /** Optional pricing in USD per million input tokens. Used to compute RunResult.usage.costUSD. */
77
+ inputCostPerMTok?: number;
78
+ /** Optional pricing in USD per million output tokens. Used to compute RunResult.usage.costUSD. */
79
+ outputCostPerMTok?: number;
80
+ /** Optional override for the per-provider input token soft limit
81
+ * used by the watchdog. When unset, falls back to the model profile
82
+ * default, then to a hardcoded 100_000 fallback. See spec A.1.4. */
83
+ inputTokenSoftLimit?: number;
54
84
  }
55
85
  /** Discriminated union — each provider type has distinct required fields. */
56
86
  export type ProviderConfig = CodexProviderConfig | ClaudeProviderConfig | OpenAICompatibleProviderConfig;
@@ -73,9 +103,71 @@ export interface RunResult {
73
103
  status: RunStatus;
74
104
  usage: TokenUsage;
75
105
  turns: number;
76
- files: string[];
106
+ /** Files whose contents the worker read (via readFile/grep/listFiles). */
107
+ filesRead: string[];
108
+ /** Files the worker wrote (via writeFile). */
109
+ filesWritten: string[];
110
+ /** Compact one-line summaries of every tool the worker invoked, in order. */
111
+ toolCalls: string[];
112
+ /** `true` when `output` is a runner-synthesized diagnostic template
113
+ * (`"Sub-agent error: …"`, `"Agent timed out after …"`, the incomplete
114
+ * template from `buildXxxIncompleteDiagnostic`, etc.) because the
115
+ * scratchpad was empty at termination. `false` when `output` contains
116
+ * real model-produced content — either a clean final answer on the
117
+ * `ok` path, or `scratchpad.latest()` on any salvage path where the
118
+ * scratchpad had buffered text.
119
+ *
120
+ * Used by the escalation orchestrator's all-fail fallback to prefer
121
+ * real content over diagnostic templates regardless of status or
122
+ * length (otherwise a long `"Sub-agent error: <stack trace>"` string
123
+ * could beat a shorter genuine partial answer from an earlier
124
+ * attempt). */
125
+ outputIsDiagnostic: boolean;
126
+ /** One entry per provider attempt within this dispatch. Length === 1
127
+ * for tasks that succeeded on the first try; longer when escalation
128
+ * occurred. Runners initialize this to `[]`; the escalation
129
+ * orchestrator populates it on each return path. */
130
+ escalationLog: AttemptRecord[];
77
131
  error?: string;
78
132
  }
133
+ /**
134
+ * Single provider-attempt record inside an escalation chain. The orchestrator
135
+ * (`delegateWithEscalation`) pushes one entry per `provider.run(...)` call.
136
+ */
137
+ export interface AttemptRecord {
138
+ provider: string;
139
+ status: RunStatus;
140
+ turns: number;
141
+ inputTokens: number;
142
+ outputTokens: number;
143
+ costUSD: number | null;
144
+ /** Character count of the canonical orchestrator-side initial brief for
145
+ * this attempt — the exact string
146
+ * `${buildSystemPrompt()}\n\n${buildBudgetHint(...)}\n\n${prompt}`
147
+ * (as assembled before any runner-specific wrapping). Populated by the
148
+ * escalation orchestrator via the `RunOptions.onInitialRequest` callback
149
+ * the runner invokes exactly once per attempt.
150
+ *
151
+ * NOTE: This is a canonical identifier, NOT a wire-level checksum. The
152
+ * provider's SDK may wrap or transform this string before sending (e.g.
153
+ * the Anthropic SDK prepends its `claude_code` preset to the system
154
+ * prompt via `{ type: 'preset', preset: 'claude_code', append: ... }`;
155
+ * the OpenAI SDKs wrap it in a `messages` array). All three runners use
156
+ * the same canonical form so the hash is cross-runner stable: identical
157
+ * briefs produce identical hashes regardless of which runner executed
158
+ * them. Use this to verify "did the orchestrator send the same brief
159
+ * across retries?", not "were the literal bytes on the wire identical?".
160
+ *
161
+ * Defaults to 0 if the runner never invoked the callback. */
162
+ initialPromptLengthChars: number;
163
+ /** sha256 hex of the canonical orchestrator-side initial brief. See the
164
+ * comment on `initialPromptLengthChars` above for the exact hashed
165
+ * string and the wire-level caveat. Defaults to the empty string if the
166
+ * runner never invoked the callback. */
167
+ initialPromptHash: string;
168
+ /** Why this attempt was abandoned, if it was. Empty if status === 'ok'. */
169
+ reason?: string;
170
+ }
79
171
  export interface Provider {
80
172
  name: string;
81
173
  config: ProviderConfig;
@@ -88,7 +180,89 @@ export interface RunOptions {
88
180
  cwd?: string;
89
181
  effort?: Effort;
90
182
  sandboxPolicy?: SandboxPolicy;
183
+ /** Optional callback invoked by runners and the escalation orchestrator to
184
+ * stream in-flight progress events. See `ProgressEvent` for the full set
185
+ * of variants. Runners receive this via `provider.run(..., { onProgress })`
186
+ * and call it synchronously from their loop; the callback MUST NOT throw
187
+ * and should return quickly. Wired in Task 8 (interface + plumbing);
188
+ * runners emit events in Tasks 9-11. */
189
+ onProgress?: (event: ProgressEvent) => void;
190
+ /** Called exactly once per attempt, when the runner has assembled the
191
+ * canonical orchestrator-side initial brief — the string
192
+ * `${buildSystemPrompt()}\n\n${buildBudgetHint(...)}\n\n${prompt}`,
193
+ * after prevention scaffolding has been produced but before any tool
194
+ * cycles, re-grounding, supervision, or watchdog injections happen.
195
+ * The escalation orchestrator passes a closure here to capture the
196
+ * metadata into the `AttemptRecord` it builds.
197
+ *
198
+ * This is a canonical identifier, NOT a wire-level checksum: each
199
+ * runner computes it from the same canonical string so the hash is
200
+ * cross-runner stable, even though the SDK underneath may wrap the
201
+ * inputs before sending (Claude prepends its `claude_code` preset to
202
+ * the system prompt; OpenAI/Codex wrap inputs in structured message
203
+ * arrays). See `AttemptRecord.initialPromptHash` for the full caveat.
204
+ *
205
+ * If a runner is re-invoked by escalation, the callback fires again
206
+ * for the new attempt because the orchestrator resets its per-attempt
207
+ * closure. Passing nothing keeps existing behaviour (no-op). */
208
+ onInitialRequest?: (meta: {
209
+ lengthChars: number;
210
+ sha256: string;
211
+ }) => void;
91
212
  }
213
+ /**
214
+ * Runtime dependencies for `runTasks`. Kept separate from static `MultiModelConfig`
215
+ * because these are per-session objects (today: the context-block store) the
216
+ * caller owns and passes in explicitly, not config loaded from disk.
217
+ */
218
+ export interface RunTasksRuntime {
219
+ /** Optional store of registered context blocks. When provided, each task's
220
+ * `contextBlockIds` are resolved against this store before dispatch; when
221
+ * omitted, tasks with `contextBlockIds` are passed through unchanged. */
222
+ contextBlockStore?: ContextBlockStore;
223
+ }
224
+ /**
225
+ * In-flight progress signal emitted by runners and the escalation
226
+ * orchestrator. Consumers (today: the MCP cli bridge) translate these into
227
+ * transport-level notifications so callers can observe a sub-agent's work
228
+ * without polling. One `ProgressEvent` per meaningful state transition.
229
+ *
230
+ * Variants mirror spec Part B.1. Runner emission lives in Tasks 9-11; the
231
+ * escalation `escalation_start` hop is emitted by `delegateWithEscalation`
232
+ * itself in Task 8.
233
+ */
234
+ export type ProgressEvent = {
235
+ kind: 'turn_start';
236
+ turn: number;
237
+ provider: string;
238
+ } | {
239
+ kind: 'tool_call';
240
+ turn: number;
241
+ toolSummary: string;
242
+ } | {
243
+ kind: 'text_emission';
244
+ turn: number;
245
+ chars: number;
246
+ preview: string;
247
+ } | {
248
+ kind: 'turn_complete';
249
+ turn: number;
250
+ cumulativeInputTokens: number;
251
+ cumulativeOutputTokens: number;
252
+ } | {
253
+ kind: 'injection';
254
+ injectionType: 'reground' | 'supervise_empty' | 'supervise_thinking' | 'supervise_fragment' | 'watchdog_warning' | 'watchdog_force_salvage';
255
+ turn: number;
256
+ contentLengthChars: number;
257
+ } | {
258
+ kind: 'escalation_start';
259
+ previousProvider: string;
260
+ previousReason: string;
261
+ nextProvider: string;
262
+ } | {
263
+ kind: 'done';
264
+ status: RunStatus;
265
+ };
92
266
  export type EligibilityFailureCheck = 'capability' | 'tier' | 'tool_mode' | 'provider_not_found' | 'unsupported_provider_type' | 'missing_required_field' | string;
93
267
  export interface EligibilityFailure {
94
268
  check: EligibilityFailureCheck;
@@ -102,5 +276,13 @@ export interface ProviderEligibility {
102
276
  /** Reasons only present when eligible === false. */
103
277
  reasons: EligibilityFailure[];
104
278
  }
279
+ /**
280
+ * Compute USD cost from token usage and the provider config's optional
281
+ * per-million-token rates. Returns null when either rate is missing — that
282
+ * way the caller can distinguish "we know the cost is zero" (free provider
283
+ * with both rates set to 0) from "we don't know the cost" (rates not
284
+ * configured). Negative or non-finite rates are treated as missing.
285
+ */
286
+ export declare function computeCostUSD(inputTokens: number, outputTokens: number, config: ProviderConfig): number | null;
105
287
  export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, onTimeout: () => T, abort?: AbortController): Promise<T>;
106
288
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,5 +1,21 @@
1
- // === Tier & Capability ===
2
1
  // === Utilities ===
2
+ /**
3
+ * Compute USD cost from token usage and the provider config's optional
4
+ * per-million-token rates. Returns null when either rate is missing — that
5
+ * way the caller can distinguish "we know the cost is zero" (free provider
6
+ * with both rates set to 0) from "we don't know the cost" (rates not
7
+ * configured). Negative or non-finite rates are treated as missing.
8
+ */
9
+ export function computeCostUSD(inputTokens, outputTokens, config) {
10
+ const inRate = config.inputCostPerMTok;
11
+ const outRate = config.outputCostPerMTok;
12
+ if (inRate === undefined || outRate === undefined ||
13
+ !Number.isFinite(inRate) || !Number.isFinite(outRate) ||
14
+ inRate < 0 || outRate < 0) {
15
+ return null;
16
+ }
17
+ return (inputTokens * inRate + outputTokens * outRate) / 1_000_000;
18
+ }
3
19
  export function withTimeout(promise, timeoutMs, onTimeout, abort) {
4
20
  let timeoutId;
5
21
  const timeoutPromise = new Promise((resolve) => {
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4BAA4B;AA8I5B,oBAAoB;AAEpB,MAAM,UAAU,WAAW,CACzB,OAAmB,EACnB,SAAiB,EACjB,SAAkB,EAClB,KAAuB;IAEvB,IAAI,SAAoD,CAAC;IAEzD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE;QAChD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,KAAK,EAAE,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACvB,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO;SACX,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,IAAI,SAAS,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,SAAS,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkUA,oBAAoB;AAEpB;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAmB,EACnB,YAAoB,EACpB,MAAsB;IAEtB,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACzC,IACE,MAAM,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS;QAC7C,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QACrD,MAAM,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,EACzB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,WAAW,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,OAAmB,EACnB,SAAiB,EACjB,SAAkB,EAClB,KAAuB;IAEvB,IAAI,SAAoD,CAAC;IAEzD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE;QAChD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,KAAK,EAAE,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACvB,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO;SACX,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,IAAI,SAAS,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,SAAS,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACP,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhixuan92/multi-model-agent-core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Core library for multi-model-agent: provider runners (Claude, Codex, OpenAI-compatible), routing logic, config schema, and tool/sandbox primitives.",
@@ -22,7 +22,9 @@
22
22
  },
23
23
  "homepage": "https://github.com/zhixuan312/multi-model-agent#readme",
24
24
  "bugs": "https://github.com/zhixuan312/multi-model-agent/issues",
25
- "files": ["dist"],
25
+ "files": [
26
+ "dist"
27
+ ],
26
28
  "main": "./dist/index.js",
27
29
  "types": "./dist/index.d.ts",
28
30
  "exports": {
@@ -74,22 +76,14 @@
74
76
  "scripts": {
75
77
  "build": "tsc"
76
78
  },
77
- "engines": { "node": ">=22.0.0" },
79
+ "engines": {
80
+ "node": ">=22.0.0"
81
+ },
78
82
  "dependencies": {
79
83
  "@anthropic-ai/claude-agent-sdk": "^0.2.98",
80
- "zod": "^4.0.0"
81
- },
82
- "peerDependencies": {
83
84
  "@openai/agents": "^0.8.0",
84
- "openai": "^6.0.0"
85
- },
86
- "peerDependenciesMeta": {
87
- "@openai/agents": {
88
- "optional": true
89
- },
90
- "openai": {
91
- "optional": true
92
- }
85
+ "openai": "^6.0.0",
86
+ "zod": "^4.0.0"
93
87
  },
94
88
  "overrides": {
95
89
  "@anthropic-ai/sdk": "0.81.0"