@zhixuan92/multi-model-agent-core 0.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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/dist/auth/claude-oauth.d.ts +6 -0
  4. package/dist/auth/claude-oauth.d.ts.map +1 -0
  5. package/dist/auth/claude-oauth.js +8 -0
  6. package/dist/auth/claude-oauth.js.map +1 -0
  7. package/dist/auth/codex-oauth.d.ts +6 -0
  8. package/dist/auth/codex-oauth.d.ts.map +1 -0
  9. package/dist/auth/codex-oauth.js +50 -0
  10. package/dist/auth/codex-oauth.js.map +1 -0
  11. package/dist/config/load.d.ts +8 -0
  12. package/dist/config/load.d.ts.map +1 -0
  13. package/dist/config/load.js +49 -0
  14. package/dist/config/load.js.map +1 -0
  15. package/dist/config/schema.d.ts +275 -0
  16. package/dist/config/schema.d.ts.map +1 -0
  17. package/dist/config/schema.js +62 -0
  18. package/dist/config/schema.js.map +1 -0
  19. package/dist/index.d.ts +11 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +14 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/model-profiles.json +34 -0
  24. package/dist/provider.d.ts +3 -0
  25. package/dist/provider.d.ts.map +1 -0
  26. package/dist/provider.js +50 -0
  27. package/dist/provider.js.map +1 -0
  28. package/dist/routing/capabilities.d.ts +3 -0
  29. package/dist/routing/capabilities.d.ts.map +1 -0
  30. package/dist/routing/capabilities.js +26 -0
  31. package/dist/routing/capabilities.js.map +1 -0
  32. package/dist/routing/get-provider-eligibility.d.ts +8 -0
  33. package/dist/routing/get-provider-eligibility.d.ts.map +1 -0
  34. package/dist/routing/get-provider-eligibility.js +53 -0
  35. package/dist/routing/get-provider-eligibility.js.map +1 -0
  36. package/dist/routing/model-profiles.d.ts +24 -0
  37. package/dist/routing/model-profiles.d.ts.map +1 -0
  38. package/dist/routing/model-profiles.js +41 -0
  39. package/dist/routing/model-profiles.js.map +1 -0
  40. package/dist/routing/resolve-task-capabilities.d.ts +7 -0
  41. package/dist/routing/resolve-task-capabilities.d.ts.map +1 -0
  42. package/dist/routing/resolve-task-capabilities.js +19 -0
  43. package/dist/routing/resolve-task-capabilities.js.map +1 -0
  44. package/dist/routing/select-provider-for-task.d.ts +18 -0
  45. package/dist/routing/select-provider-for-task.d.ts.map +1 -0
  46. package/dist/routing/select-provider-for-task.js +50 -0
  47. package/dist/routing/select-provider-for-task.js.map +1 -0
  48. package/dist/run-tasks.d.ts +7 -0
  49. package/dist/run-tasks.d.ts.map +1 -0
  50. package/dist/run-tasks.js +81 -0
  51. package/dist/run-tasks.js.map +1 -0
  52. package/dist/runners/claude-runner.d.ts +7 -0
  53. package/dist/runners/claude-runner.d.ts.map +1 -0
  54. package/dist/runners/claude-runner.js +118 -0
  55. package/dist/runners/claude-runner.js.map +1 -0
  56. package/dist/runners/codex-runner.d.ts +23 -0
  57. package/dist/runners/codex-runner.d.ts.map +1 -0
  58. package/dist/runners/codex-runner.js +403 -0
  59. package/dist/runners/codex-runner.js.map +1 -0
  60. package/dist/runners/openai-runner.d.ts +22 -0
  61. package/dist/runners/openai-runner.d.ts.map +1 -0
  62. package/dist/runners/openai-runner.js +92 -0
  63. package/dist/runners/openai-runner.js.map +1 -0
  64. package/dist/tools/claude-adapter.d.ts +4 -0
  65. package/dist/tools/claude-adapter.d.ts.map +1 -0
  66. package/dist/tools/claude-adapter.js +42 -0
  67. package/dist/tools/claude-adapter.js.map +1 -0
  68. package/dist/tools/definitions.d.ts +19 -0
  69. package/dist/tools/definitions.d.ts.map +1 -0
  70. package/dist/tools/definitions.js +147 -0
  71. package/dist/tools/definitions.js.map +1 -0
  72. package/dist/tools/openai-adapter.d.ts +13 -0
  73. package/dist/tools/openai-adapter.d.ts.map +1 -0
  74. package/dist/tools/openai-adapter.js +74 -0
  75. package/dist/tools/openai-adapter.js.map +1 -0
  76. package/dist/tools/tracker.d.ts +7 -0
  77. package/dist/tools/tracker.d.ts.map +1 -0
  78. package/dist/tools/tracker.js +13 -0
  79. package/dist/tools/tracker.js.map +1 -0
  80. package/dist/types.d.ts +106 -0
  81. package/dist/types.d.ts.map +1 -0
  82. package/dist/types.js +23 -0
  83. package/dist/types.js.map +1 -0
  84. package/package.json +97 -0
@@ -0,0 +1,118 @@
1
+ import { query } from '@anthropic-ai/claude-agent-sdk';
2
+ import { withTimeout } from '../types.js';
3
+ import { FileTracker } from '../tools/tracker.js';
4
+ import { createToolImplementations } from '../tools/definitions.js';
5
+ import { createClaudeToolServer } from '../tools/claude-adapter.js';
6
+ export async function runClaude(prompt, options, providerConfig, defaults) {
7
+ const maxTurns = options.maxTurns ?? providerConfig.maxTurns ?? defaults.maxTurns;
8
+ const timeoutMs = options.timeoutMs ?? providerConfig.timeoutMs ?? defaults.timeoutMs;
9
+ const toolMode = options.tools ?? defaults.tools;
10
+ const cwd = options.cwd ?? process.cwd();
11
+ const effort = options.effort ?? providerConfig.effort;
12
+ const sandboxPolicy = options.sandboxPolicy ?? providerConfig.sandboxPolicy ?? 'cwd-only';
13
+ const abortController = new AbortController();
14
+ const tracker = new FileTracker();
15
+ const toolImpls = createToolImplementations(tracker, cwd, sandboxPolicy, abortController.signal);
16
+ // Permission bypass is intentional for sub-agent use. File-system confinement
17
+ // is enforced by assertWithinCwd in tool definitions when sandboxPolicy is 'cwd-only'.
18
+ const queryOptions = {
19
+ model: providerConfig.model,
20
+ maxTurns,
21
+ cwd,
22
+ permissionMode: 'bypassPermissions',
23
+ allowDangerouslySkipPermissions: true,
24
+ persistSession: false,
25
+ abortController,
26
+ };
27
+ if (toolMode === 'full') {
28
+ const toolServer = createClaudeToolServer(toolImpls, sandboxPolicy);
29
+ queryOptions.mcpServers = { 'code-tools': toolServer };
30
+ // Enable Claude's built-in WebSearch and WebFetch alongside our MCP code
31
+ // tool server, so the capabilities matrix's claim that claude has
32
+ // web_search + web_fetch is actually true at runtime. Shell is NOT in
33
+ // this list — it stays behind the sandboxPolicy gate via our code-tools
34
+ // MCP server's runShell implementation.
35
+ queryOptions.tools = ['WebSearch', 'WebFetch'];
36
+ queryOptions.allowedTools = ['mcp__code-tools__*', 'WebSearch', 'WebFetch'];
37
+ }
38
+ else {
39
+ queryOptions.tools = [];
40
+ }
41
+ if (!effort || effort === 'none') {
42
+ queryOptions.thinking = { type: 'disabled' };
43
+ }
44
+ else {
45
+ queryOptions.thinking = { type: 'adaptive' };
46
+ // effort is typed as EffortLevel in Options; cast from string
47
+ queryOptions.effort = effort;
48
+ }
49
+ // Hoisted so the timeout callback can read partial progress
50
+ let inputTokens = 0;
51
+ let outputTokens = 0;
52
+ let costUSD = null;
53
+ let turns = 0;
54
+ const run = async () => {
55
+ let output = '';
56
+ let hitMaxTurns = false;
57
+ try {
58
+ for await (const msg of query({ prompt, options: queryOptions })) {
59
+ if (msg.type === 'assistant') {
60
+ turns++;
61
+ }
62
+ if (msg.type === 'result') {
63
+ if ('result' in msg) {
64
+ output = msg.result;
65
+ }
66
+ if ('subtype' in msg && msg.subtype === 'error_max_turns') {
67
+ hitMaxTurns = true;
68
+ }
69
+ // Extract usage from modelUsage or usage
70
+ if ('modelUsage' in msg && msg.modelUsage) {
71
+ for (const model of Object.values(msg.modelUsage)) {
72
+ inputTokens += model.inputTokens ?? 0;
73
+ outputTokens += model.outputTokens ?? 0;
74
+ }
75
+ }
76
+ else if ('usage' in msg && msg.usage) {
77
+ const u = msg.usage;
78
+ inputTokens = u['input_tokens'] ?? 0;
79
+ outputTokens = u['output_tokens'] ?? 0;
80
+ }
81
+ if ('total_cost_usd' in msg && typeof msg.total_cost_usd === 'number') {
82
+ costUSD = msg.total_cost_usd;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ catch (err) {
88
+ return {
89
+ output: `Sub-agent error: ${err instanceof Error ? err.message : String(err)}`,
90
+ status: 'error',
91
+ usage: { inputTokens, outputTokens, totalTokens: inputTokens + outputTokens, costUSD },
92
+ turns,
93
+ files: tracker.getFiles(),
94
+ error: err instanceof Error ? err.message : String(err),
95
+ };
96
+ }
97
+ return {
98
+ output: hitMaxTurns ? (output || `Agent exceeded max turns (${maxTurns}).`) : output,
99
+ status: hitMaxTurns ? 'max_turns' : 'ok',
100
+ usage: {
101
+ inputTokens,
102
+ outputTokens,
103
+ totalTokens: inputTokens + outputTokens,
104
+ costUSD,
105
+ },
106
+ turns,
107
+ files: tracker.getFiles(),
108
+ };
109
+ };
110
+ return withTimeout(run(), timeoutMs, () => ({
111
+ output: `Agent timed out after ${timeoutMs}ms.`,
112
+ status: 'timeout',
113
+ files: tracker.getFiles(),
114
+ usage: { inputTokens, outputTokens, totalTokens: inputTokens + outputTokens, costUSD },
115
+ turns,
116
+ }), abortController);
117
+ }
118
+ //# sourceMappingURL=claude-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-runner.js","sourceRoot":"","sources":["../../src/runners/claude-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import OpenAI from 'openai';
2
+ import { type RunResult, type RunOptions, type ProviderConfig } from '../types.js';
3
+ /**
4
+ * Holds the raw body text of the last HTTP response that returned a 4xx/5xx.
5
+ * The OpenAI SDK wraps errors into APIError but strips the body text when it
6
+ * can't be parsed as JSON, leaving "400 status code (no body)". We capture it
7
+ * ourselves via a custom fetch so we can surface actionable diagnostics.
8
+ */
9
+ export interface RawErrorCapture {
10
+ status: number;
11
+ bodyText: string;
12
+ url: string;
13
+ requestBodyPreview?: string;
14
+ }
15
+ export declare function createCodexClient(capture?: {
16
+ last?: RawErrorCapture;
17
+ }): OpenAI;
18
+ export declare function runCodex(prompt: string, options: RunOptions, providerConfig: ProviderConfig, defaults: {
19
+ maxTurns: number;
20
+ timeoutMs: number;
21
+ tools: 'none' | 'full';
22
+ }): Promise<RunResult>;
23
+ //# sourceMappingURL=codex-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-runner.d.ts","sourceRoot":"","sources":["../../src/runners/codex-runner.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAoBhG;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,eAAe,CAAA;CAAE,GAAG,MAAM,CAkD9E;AA0FD,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,UAAU,EACnB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GACxE,OAAO,CAAC,SAAS,CAAC,CAuQpB"}
@@ -0,0 +1,403 @@
1
+ import OpenAI from 'openai';
2
+ import { z } from 'zod';
3
+ import { getCodexAuth } from '../auth/codex-oauth.js';
4
+ import { withTimeout } from '../types.js';
5
+ import { FileTracker } from '../tools/tracker.js';
6
+ import { createToolImplementations } from '../tools/definitions.js';
7
+ // CODEX_DEBUG=1 causes the runner to log raw HTTP request/response bodies to
8
+ // stderr. Those bodies routinely include the user's prompt, file contents,
9
+ // tool arguments, and other sensitive data — fine for local debugging,
10
+ // dangerous in any deployment that ships logs anywhere. Surface a one-time
11
+ // warning at module load so an operator who flipped the env var without
12
+ // thinking sees it immediately.
13
+ if (process.env.CODEX_DEBUG === '1') {
14
+ // eslint-disable-next-line no-console
15
+ console.warn('[multi-model-agent] WARNING: CODEX_DEBUG=1 is set. Raw request/response ' +
16
+ 'bodies (including prompts and file contents) will be logged to stderr. ' +
17
+ 'Disable in any environment where logs may be retained or shared.');
18
+ }
19
+ export function createCodexClient(capture) {
20
+ const debug = process.env.CODEX_DEBUG === '1';
21
+ // A custom fetch that tees error-response bodies into `capture`.
22
+ const wrappedFetch = async (url, init) => {
23
+ const res = await fetch(url, init);
24
+ if (!res.ok && capture) {
25
+ const cloned = res.clone();
26
+ let bodyText = '';
27
+ try {
28
+ bodyText = await cloned.text();
29
+ }
30
+ catch { /* ignore */ }
31
+ capture.last = {
32
+ status: res.status,
33
+ bodyText,
34
+ url: String(url),
35
+ requestBodyPreview: typeof init?.body === 'string' ? init.body.slice(0, 2000) : undefined,
36
+ };
37
+ if (debug) {
38
+ // eslint-disable-next-line no-console
39
+ console.error('[codex-runner] HTTP', res.status, String(url));
40
+ // eslint-disable-next-line no-console
41
+ if (bodyText)
42
+ console.error('[codex-runner] body:', bodyText.slice(0, 1000));
43
+ // eslint-disable-next-line no-console
44
+ if (typeof init?.body === 'string')
45
+ console.error('[codex-runner] request:', init.body.slice(0, 1000));
46
+ }
47
+ }
48
+ return res;
49
+ };
50
+ // Try Codex OAuth first — route through chatgpt.com backend API
51
+ const auth = getCodexAuth();
52
+ if (auth) {
53
+ return new OpenAI({
54
+ apiKey: auth.accessToken,
55
+ baseURL: 'https://chatgpt.com/backend-api/codex',
56
+ defaultHeaders: {
57
+ 'chatgpt-account-id': auth.accountId,
58
+ },
59
+ fetch: wrappedFetch,
60
+ });
61
+ }
62
+ // Fall back to OPENAI_API_KEY env var — uses standard api.openai.com
63
+ const apiKey = process.env.OPENAI_API_KEY;
64
+ if (apiKey) {
65
+ return new OpenAI({ apiKey, fetch: wrappedFetch });
66
+ }
67
+ throw new Error('No Codex credentials found. Run `codex login` or set OPENAI_API_KEY environment variable.');
68
+ }
69
+ function buildCodexTools(impl, sandboxPolicy) {
70
+ const tools = [
71
+ {
72
+ name: 'read_file',
73
+ description: 'Read the contents of a file at the given path. Returns the full file content as a string.',
74
+ parameters: z.toJSONSchema(z.object({
75
+ path: z.string().describe('Absolute or relative file path'),
76
+ })),
77
+ execute: async (args) => impl.readFile(args.path),
78
+ },
79
+ {
80
+ name: 'write_file',
81
+ description: 'Write content to a file, creating parent directories if needed. Overwrites existing files.',
82
+ parameters: z.toJSONSchema(z.object({
83
+ path: z.string().describe('File path to write to'),
84
+ content: z.string().describe('Content to write'),
85
+ })),
86
+ execute: async (args) => {
87
+ await impl.writeFile(args.path, args.content);
88
+ return `File written: ${args.path}`;
89
+ },
90
+ },
91
+ {
92
+ name: 'glob',
93
+ description: 'Find files matching a glob pattern in the working directory.',
94
+ parameters: z.toJSONSchema(z.object({
95
+ pattern: z.string().describe('Glob pattern (e.g., "*.ts", "src/**/*.js")'),
96
+ })),
97
+ execute: async (args) => {
98
+ const files = await impl.glob(args.pattern);
99
+ return files.join('\n') || 'No files found.';
100
+ },
101
+ },
102
+ {
103
+ name: 'grep',
104
+ description: 'Search for a pattern in a file. Returns matching lines with line numbers.',
105
+ parameters: z.toJSONSchema(z.object({
106
+ pattern: z.string().describe('Search pattern (regex)'),
107
+ path: z.string().describe('File path to search in'),
108
+ })),
109
+ execute: async (args) => {
110
+ const result = await impl.grep(args.pattern, args.path);
111
+ return result || 'No matches found.';
112
+ },
113
+ },
114
+ {
115
+ name: 'list_files',
116
+ description: 'List files and directories at the given path. Directories have a trailing "/".',
117
+ parameters: z.toJSONSchema(z.object({
118
+ path: z.string().default('.').describe('Directory path to list'),
119
+ })),
120
+ execute: async (args) => {
121
+ const entries = await impl.listFiles(args.path ?? '.');
122
+ return entries.join('\n') || 'Empty directory.';
123
+ },
124
+ },
125
+ ];
126
+ if (sandboxPolicy !== 'cwd-only') {
127
+ tools.push({
128
+ name: 'run_shell',
129
+ description: 'Execute a shell command and return stdout, stderr, and exit code. Use for running tests, installing packages, etc.',
130
+ parameters: z.toJSONSchema(z.object({
131
+ command: z.string().describe('Shell command to execute'),
132
+ })),
133
+ execute: async (args) => {
134
+ const result = await impl.runShell(args.command);
135
+ return JSON.stringify(result);
136
+ },
137
+ });
138
+ }
139
+ return tools;
140
+ }
141
+ export async function runCodex(prompt, options, providerConfig, defaults) {
142
+ const maxTurns = options.maxTurns ?? providerConfig.maxTurns ?? defaults.maxTurns;
143
+ const timeoutMs = options.timeoutMs ?? providerConfig.timeoutMs ?? defaults.timeoutMs;
144
+ const toolMode = options.tools ?? defaults.tools;
145
+ const cwd = options.cwd ?? process.cwd();
146
+ const sandboxPolicy = options.sandboxPolicy ?? providerConfig.sandboxPolicy ?? 'cwd-only';
147
+ const effort = options.effort ?? providerConfig.effort;
148
+ const abortController = new AbortController();
149
+ const tracker = new FileTracker();
150
+ const toolImpls = createToolImplementations(tracker, cwd, sandboxPolicy, abortController.signal);
151
+ const codexTools = toolMode === 'full' ? buildCodexTools(toolImpls, sandboxPolicy) : [];
152
+ const toolsByName = new Map(codexTools.map(t => [t.name, t]));
153
+ const responsesTools = codexTools.map(t => ({
154
+ type: 'function',
155
+ name: t.name,
156
+ description: t.description,
157
+ parameters: t.parameters,
158
+ strict: false,
159
+ }));
160
+ // Auto-enable web_search for codex unless the user explicitly set hostedTools
161
+ // (including an explicit empty array to opt out). This keeps the capability
162
+ // matrix's claim that codex has web_search true at default settings — the
163
+ // user's guiding principle is to minimize required config.
164
+ const configuredHostedTools = providerConfig.hostedTools ?? ['web_search'];
165
+ const hostedTools = toolMode === 'full'
166
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
+ ? configuredHostedTools.map(t => ({ type: t }))
168
+ : [];
169
+ const allTools = [...responsesTools, ...hostedTools];
170
+ // Accumulated state (hoisted so the timeout callback can read partial progress)
171
+ let inputTokens = 0;
172
+ let outputTokens = 0;
173
+ let turns = 0;
174
+ const run = async () => {
175
+ const capture = {};
176
+ const client = createCodexClient(capture);
177
+ const input = [
178
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
179
+ { role: 'user', content: prompt },
180
+ ];
181
+ let output = '';
182
+ let lastResponseStatus = null;
183
+ try {
184
+ while (turns < maxTurns) {
185
+ turns++;
186
+ // Codex backend requires streaming. The Codex backend's
187
+ // `response.completed` event does NOT populate `response.output` —
188
+ // we must accumulate content from individual stream events.
189
+ // `instructions` is required (mirrors gumi-agent's proven shape).
190
+ const stream = await client.responses.create({
191
+ model: providerConfig.model,
192
+ instructions: prompt,
193
+ input,
194
+ stream: true,
195
+ store: false,
196
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
197
+ tools: allTools.length > 0 ? allTools : undefined,
198
+ // Honor `effort` when set and not 'none'. Codex backend accepts
199
+ // reasoning.effort for reasoning-capable models (gpt-5-codex, o3, etc.).
200
+ // 'none' skips the reasoning block entirely.
201
+ ...(effort && effort !== 'none' && {
202
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
203
+ reasoning: { effort },
204
+ }),
205
+ }, { signal: abortController.signal });
206
+ let textThisTurn = '';
207
+ const toolCalls = [];
208
+ const itemTypesSeen = [];
209
+ const completedItems = [];
210
+ let sawCompleted = false;
211
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
212
+ for await (const event of stream) {
213
+ const et = event?.type;
214
+ if (!et)
215
+ continue;
216
+ if (et === 'response.output_text.delta') {
217
+ textThisTurn += event.delta ?? '';
218
+ }
219
+ else if (et === 'response.output_item.added') {
220
+ if (event.item?.type)
221
+ itemTypesSeen.push(event.item.type);
222
+ }
223
+ else if (et === 'response.output_item.done') {
224
+ const item = event.item;
225
+ if (item) {
226
+ completedItems.push(item);
227
+ if (item.type === 'function_call') {
228
+ toolCalls.push({
229
+ call_id: item.call_id,
230
+ name: item.name,
231
+ arguments: item.arguments ?? '',
232
+ item,
233
+ });
234
+ }
235
+ }
236
+ }
237
+ else if (et === 'response.completed') {
238
+ sawCompleted = true;
239
+ const r = event.response;
240
+ if (r?.usage) {
241
+ inputTokens += r.usage.input_tokens ?? 0;
242
+ outputTokens += r.usage.output_tokens ?? 0;
243
+ }
244
+ if (r?.status)
245
+ lastResponseStatus = r.status;
246
+ }
247
+ }
248
+ if (process.env.CODEX_DEBUG === '1') {
249
+ // eslint-disable-next-line no-console
250
+ console.error('[codex-runner] item types streamed:', itemTypesSeen.join(', ') || '(none)');
251
+ // eslint-disable-next-line no-console
252
+ console.error('[codex-runner] text this turn:', JSON.stringify(textThisTurn));
253
+ // eslint-disable-next-line no-console
254
+ console.error('[codex-runner] tool calls:', toolCalls.length);
255
+ }
256
+ if (!sawCompleted) {
257
+ throw new Error('Codex stream ended without a response.completed event');
258
+ }
259
+ // Replay only function_call items into the next turn's input.
260
+ //
261
+ // We send `store: false` to the Responses API, which means the server
262
+ // does NOT persist any items it generates (reasoning items with `rs_`
263
+ // ids, message items with `msg_` ids, etc.). Replaying those items
264
+ // wholesale causes a 404 on the next turn:
265
+ // "Item with id 'rs_...' not found. Items are not persisted when
266
+ // `store` is set to false."
267
+ //
268
+ // function_call items are part of the tool-call protocol — the next
269
+ // turn needs them so each function_call_output we push can be paired
270
+ // with its originating call_id. We strip the server-generated `id`
271
+ // field and rebuild the item from its protocol fields only, so the
272
+ // server has nothing to look up against unpersisted state.
273
+ //
274
+ // Reasoning, message, and other server-generated items are dropped.
275
+ // The model still sees its previous tool calls + their outputs, which
276
+ // is enough to continue a multi-turn agent loop.
277
+ for (const item of completedItems) {
278
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
279
+ const it = item;
280
+ if (it?.type === 'function_call') {
281
+ input.push({
282
+ type: 'function_call',
283
+ call_id: it.call_id,
284
+ name: it.name,
285
+ arguments: it.arguments ?? '',
286
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
287
+ });
288
+ }
289
+ }
290
+ if (textThisTurn) {
291
+ output = textThisTurn;
292
+ }
293
+ else if (toolCalls.length === 0) {
294
+ output = `[codex returned no text — items streamed: ${itemTypesSeen.join(', ') || '(none)'}]`;
295
+ }
296
+ // If the model made no tool calls, it's done
297
+ if (toolCalls.length === 0) {
298
+ return {
299
+ output,
300
+ status: 'ok',
301
+ usage: {
302
+ inputTokens,
303
+ outputTokens,
304
+ totalTokens: inputTokens + outputTokens,
305
+ costUSD: null,
306
+ },
307
+ turns,
308
+ files: tracker.getFiles(),
309
+ };
310
+ }
311
+ // Execute tool calls and feed outputs back
312
+ for (const call of toolCalls) {
313
+ const tool = toolsByName.get(call.name);
314
+ let result;
315
+ if (!tool) {
316
+ result = `Error: unknown tool "${call.name}"`;
317
+ }
318
+ else {
319
+ try {
320
+ const args = call.arguments ? JSON.parse(call.arguments) : {};
321
+ result = await tool.execute(args);
322
+ }
323
+ catch (err) {
324
+ result = `Tool error: ${err instanceof Error ? err.message : String(err)}`;
325
+ }
326
+ }
327
+ input.push({
328
+ type: 'function_call_output',
329
+ call_id: call.call_id,
330
+ output: result,
331
+ });
332
+ }
333
+ }
334
+ // Max turns exhausted
335
+ return {
336
+ output: output || `Agent exceeded max turns (${maxTurns}).`,
337
+ status: 'max_turns',
338
+ usage: {
339
+ inputTokens,
340
+ outputTokens,
341
+ totalTokens: inputTokens + outputTokens,
342
+ costUSD: null,
343
+ },
344
+ turns,
345
+ files: tracker.getFiles(),
346
+ };
347
+ }
348
+ catch (err) {
349
+ // OpenAI SDK's APIError carries status/body/headers — surface them
350
+ // since the Codex backend returns 400 with no body on shape mismatches.
351
+ // We also consult `capture.last` which holds the raw HTTP body captured
352
+ // by our wrapped fetch (the SDK strips the body when it can't parse JSON).
353
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
354
+ const e = err;
355
+ const pieces = [];
356
+ if (err instanceof Error)
357
+ pieces.push(err.message);
358
+ if (e?.status)
359
+ pieces.push(`HTTP ${e.status}`);
360
+ if (e?.error) {
361
+ try {
362
+ pieces.push(`sdk_body=${JSON.stringify(e.error)}`);
363
+ }
364
+ catch { /* ignore */ }
365
+ }
366
+ if (capture.last) {
367
+ pieces.push(`raw_status=${capture.last.status}`);
368
+ // Only leak request/response body snippets when debug is explicitly enabled;
369
+ // they may contain sensitive content (prompt, tools, file contents).
370
+ if (process.env.CODEX_DEBUG === '1' && capture.last.bodyText)
371
+ pieces.push(`raw_body=${capture.last.bodyText.slice(0, 500)}`);
372
+ if (process.env.CODEX_DEBUG === '1' && capture.last.requestBodyPreview)
373
+ pieces.push(`req_body=${capture.last.requestBodyPreview.slice(0, 500)}`);
374
+ }
375
+ if (e?.requestID)
376
+ pieces.push(`req_id=${e.requestID}`);
377
+ if (lastResponseStatus)
378
+ pieces.push(`last response status: ${lastResponseStatus}`);
379
+ const detailed = pieces.join(' | ') || String(err);
380
+ return {
381
+ output: `Sub-agent error: ${detailed}`,
382
+ status: 'error',
383
+ usage: {
384
+ inputTokens,
385
+ outputTokens,
386
+ totalTokens: inputTokens + outputTokens,
387
+ costUSD: null,
388
+ },
389
+ turns,
390
+ files: tracker.getFiles(),
391
+ error: detailed,
392
+ };
393
+ }
394
+ };
395
+ return withTimeout(run(), timeoutMs, () => ({
396
+ output: `Agent timed out after ${timeoutMs}ms.`,
397
+ status: 'timeout',
398
+ files: tracker.getFiles(),
399
+ usage: { inputTokens, outputTokens, totalTokens: inputTokens + outputTokens, costUSD: null },
400
+ turns,
401
+ }), abortController);
402
+ }
403
+ //# sourceMappingURL=codex-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-runner.js","sourceRoot":"","sources":["../../src/runners/codex-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import OpenAI from 'openai';
2
+ import { type RunResult, type RunOptions, type ProviderConfig } from '../types.js';
3
+ /**
4
+ * Remove `<think>...</think>` reasoning blocks from model output.
5
+ *
6
+ * Several reasoning models (MiniMax, DeepSeek, Qwen variants) emit their
7
+ * chain-of-thought inline wrapped in `<think>...</think>` tags. These are
8
+ * scratch-pad content and should not surface to the caller. Stripping is
9
+ * non-greedy, multi-line, and handles multiple blocks.
10
+ */
11
+ export declare function stripThinkingTags(text: string): string;
12
+ export interface OpenAIRunnerOptions {
13
+ client: OpenAI;
14
+ providerConfig: ProviderConfig;
15
+ defaults: {
16
+ maxTurns: number;
17
+ timeoutMs: number;
18
+ tools: 'none' | 'full';
19
+ };
20
+ }
21
+ export declare function runOpenAI(prompt: string, options: RunOptions, runner: OpenAIRunnerOptions): Promise<RunResult>;
22
+ //# sourceMappingURL=openai-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-runner.d.ts","sourceRoot":"","sources":["../../src/runners/openai-runner.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAQhG;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,SAAS,CAAC,CA+EpB"}