mcp-codex-worker 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/app.d.ts +9 -0
- package/dist/src/app.js +368 -2
- package/dist/src/app.js.map +1 -1
- package/dist/src/execution/codex-adapter.d.ts +2 -1
- package/dist/src/execution/codex-adapter.js +73 -2
- package/dist/src/execution/codex-adapter.js.map +1 -1
- package/dist/src/index.js +13 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/tool-definitions.js +10 -4
- package/dist/src/mcp/tool-definitions.js.map +1 -1
- package/package.json +1 -1
- package/src/app.ts +435 -2
- package/src/execution/codex-adapter.ts +95 -5
- package/src/index.ts +15 -0
- package/src/mcp/tool-definitions.ts +10 -4
|
@@ -12,7 +12,10 @@ import {
|
|
|
12
12
|
type ProviderSpawnOptions,
|
|
13
13
|
type AvailabilityResult,
|
|
14
14
|
} from './base-adapter.js';
|
|
15
|
-
import
|
|
15
|
+
import { CodexRuntime } from '../services/codex-runtime.js';
|
|
16
|
+
import type { AppServerClient } from '../services/app-server-client.js';
|
|
17
|
+
import { attachPauseFlow } from './codex-pause-flow.js';
|
|
18
|
+
import { REQUEST_TIMEOUT_MS } from '../config/defaults.js';
|
|
16
19
|
|
|
17
20
|
// ---------------------------------------------------------------------------
|
|
18
21
|
// Options
|
|
@@ -52,16 +55,103 @@ export class CodexAdapter extends BaseProviderAdapter {
|
|
|
52
55
|
return {};
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
// -------------------------------------------------------------------------
|
|
59
|
+
// Core session lifecycle
|
|
60
|
+
// -------------------------------------------------------------------------
|
|
61
|
+
|
|
55
62
|
protected async executeSession(
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
handle: TaskHandle,
|
|
64
|
+
prompt: string,
|
|
58
65
|
_signal: AbortSignal,
|
|
59
|
-
|
|
66
|
+
options: ProviderSpawnOptions,
|
|
60
67
|
): Promise<void> {
|
|
61
|
-
|
|
68
|
+
const runtime = this.getRuntime();
|
|
69
|
+
let detachPauseFlow: (() => void) | undefined;
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
// 1. Create a new thread
|
|
73
|
+
const { params: threadParams } = await runtime.buildThreadStartParams({
|
|
74
|
+
model: options.model,
|
|
75
|
+
cwd: options.cwd,
|
|
76
|
+
});
|
|
77
|
+
const threadResult = await runtime.request('thread/start', threadParams) as {
|
|
78
|
+
thread?: { id?: string };
|
|
79
|
+
};
|
|
80
|
+
const threadId = threadResult?.thread?.id;
|
|
81
|
+
if (!threadId) {
|
|
82
|
+
throw new Error('thread/start did not return a thread ID');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 2. Mark running with the thread ID as session identifier
|
|
86
|
+
handle.markRunning(threadId);
|
|
87
|
+
|
|
88
|
+
// 3. Attach pause-flow: translate server-requests → PendingQuestions
|
|
89
|
+
// getCurrentClient() is private on CodexRuntime; access via cast.
|
|
90
|
+
// Safe after a successful request() call guarantees the client exists.
|
|
91
|
+
const client = (runtime as unknown as { getCurrentClient(): AppServerClient })
|
|
92
|
+
.getCurrentClient();
|
|
93
|
+
detachPauseFlow = attachPauseFlow(client, handle, threadId);
|
|
94
|
+
|
|
95
|
+
// 4. Build turn params and start the turn via bridged request
|
|
96
|
+
const { params: turnParams } = await runtime.buildTurnStartParams({
|
|
97
|
+
threadId,
|
|
98
|
+
userInput: prompt,
|
|
99
|
+
model: options.model,
|
|
100
|
+
});
|
|
101
|
+
const bridgeResult = await runtime.requestWithBridge(
|
|
102
|
+
'turn/start',
|
|
103
|
+
turnParams,
|
|
104
|
+
{ threadId },
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// 5. Handle bridge result
|
|
108
|
+
if (bridgeResult.status === 'pending_request') {
|
|
109
|
+
// Pause flow already queued the question on the handle and
|
|
110
|
+
// markInputRequired was called. Nothing more to do here —
|
|
111
|
+
// the wait-task / answer-task handlers drive the rest.
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (bridgeResult.status === 'completed') {
|
|
116
|
+
handle.markCompleted();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// status === 'running' — the bridge timed out before completion;
|
|
121
|
+
// poll until the operation settles.
|
|
122
|
+
const timeoutMs = options.timeout > 0 ? options.timeout : REQUEST_TIMEOUT_MS;
|
|
123
|
+
const op = await runtime.waitForOperation(
|
|
124
|
+
bridgeResult.operationId,
|
|
125
|
+
timeoutMs,
|
|
126
|
+
500,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
if (op.status === 'completed') {
|
|
130
|
+
handle.markCompleted();
|
|
131
|
+
} else {
|
|
132
|
+
handle.markFailed(op.error ?? 'Turn failed');
|
|
133
|
+
}
|
|
134
|
+
} finally {
|
|
135
|
+
detachPauseFlow?.();
|
|
136
|
+
}
|
|
62
137
|
}
|
|
63
138
|
|
|
64
139
|
async shutdown(): Promise<void> {
|
|
65
140
|
await this.runtime?.shutdown();
|
|
66
141
|
}
|
|
142
|
+
|
|
143
|
+
// -------------------------------------------------------------------------
|
|
144
|
+
// Internal
|
|
145
|
+
// -------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
private getRuntime(): CodexRuntime {
|
|
148
|
+
if (!this.runtime) {
|
|
149
|
+
this.runtime = new CodexRuntime({
|
|
150
|
+
command: this.options.command,
|
|
151
|
+
args: this.options.args,
|
|
152
|
+
env: this.options.env,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return this.runtime;
|
|
156
|
+
}
|
|
67
157
|
}
|
package/src/index.ts
CHANGED
|
@@ -64,6 +64,21 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
64
64
|
|
|
65
65
|
async function main(): Promise<void> {
|
|
66
66
|
await app.initialize();
|
|
67
|
+
|
|
68
|
+
// Wire state-change notifications: when any task status changes,
|
|
69
|
+
// notify MCP clients that the scoreboard and task detail resources are updated.
|
|
70
|
+
const taskManager = app.getTaskManager();
|
|
71
|
+
taskManager.onStatusChange((task) => {
|
|
72
|
+
server.notification({
|
|
73
|
+
method: 'notifications/resources/updated',
|
|
74
|
+
params: { uri: 'task:///all' },
|
|
75
|
+
}).catch(() => {});
|
|
76
|
+
server.notification({
|
|
77
|
+
method: 'notifications/resources/updated',
|
|
78
|
+
params: { uri: `task:///${task.id}` },
|
|
79
|
+
}).catch(() => {});
|
|
80
|
+
});
|
|
81
|
+
|
|
67
82
|
const transport = new StdioServerTransport();
|
|
68
83
|
await server.connect(transport);
|
|
69
84
|
process.stdin.resume();
|
|
@@ -164,6 +164,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
164
164
|
{
|
|
165
165
|
name: 'codex-thread-start',
|
|
166
166
|
description: [
|
|
167
|
+
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
167
168
|
'Launch a new Codex agent as a background thread.',
|
|
168
169
|
'',
|
|
169
170
|
'PARALLEL EXECUTION: Launch multiple threads simultaneously — each thread is an independent agent workspace with its own context and conversation history.',
|
|
@@ -192,7 +193,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
192
193
|
},
|
|
193
194
|
{
|
|
194
195
|
name: 'codex-thread-resume',
|
|
195
|
-
description: '
|
|
196
|
+
description: '⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n\nResume a previously started Codex thread. Reloads context and reconnects the agent. Use to continue work on an existing thread after a pause, or to send follow-up instructions to a completed thread.',
|
|
196
197
|
inputSchema: objectSchema({
|
|
197
198
|
thread_id: { type: 'string', minLength: 1, description: 'ID of the thread to resume.' },
|
|
198
199
|
model: {
|
|
@@ -208,6 +209,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
208
209
|
{
|
|
209
210
|
name: 'codex-thread-read',
|
|
210
211
|
description: [
|
|
212
|
+
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
211
213
|
'Read thread status and conversation history. Use to check what an agent has done, inspect its output, or verify task completion. Set include_turns=true for full turn details including tool calls and file changes.',
|
|
212
214
|
threadBanner,
|
|
213
215
|
].filter(Boolean).join('\n\n'),
|
|
@@ -219,7 +221,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
219
221
|
},
|
|
220
222
|
{
|
|
221
223
|
name: 'codex-thread-list',
|
|
222
|
-
description: '
|
|
224
|
+
description: '⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n\nList recent Codex threads across all sessions. Use to discover existing threads before starting new ones, or to find a thread ID you need to resume.',
|
|
223
225
|
inputSchema: objectSchema({
|
|
224
226
|
limit: { type: 'integer', minimum: 1, maximum: 100, description: 'Max threads to return. Default 50.' },
|
|
225
227
|
cursor: { type: 'string', description: 'Pagination cursor from a previous response.' },
|
|
@@ -230,6 +232,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
230
232
|
name: 'codex-turn-start',
|
|
231
233
|
description: [
|
|
232
234
|
[
|
|
235
|
+
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
233
236
|
'Send a task to an active Codex thread, starting an autonomous agent turn.',
|
|
234
237
|
'',
|
|
235
238
|
'The agent executes independently — it reads files, writes code, runs commands, and commits changes.',
|
|
@@ -255,7 +258,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
255
258
|
{
|
|
256
259
|
name: 'codex-turn-steer',
|
|
257
260
|
description: [
|
|
258
|
-
'
|
|
261
|
+
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n\nRedirect an in-progress turn with new instructions. The agent adjusts course without losing prior context. Use when you see the agent heading in the wrong direction via codex-thread-read or codex-request-list.',
|
|
259
262
|
threadBanner,
|
|
260
263
|
].filter(Boolean).join('\n\n'),
|
|
261
264
|
inputSchema: objectSchema({
|
|
@@ -267,7 +270,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
267
270
|
},
|
|
268
271
|
{
|
|
269
272
|
name: 'codex-turn-interrupt',
|
|
270
|
-
description: '
|
|
273
|
+
description: '⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n\nStop an active turn immediately. Use when the agent is heading in the wrong direction and steering is not enough, or when you need to cancel work in progress.',
|
|
271
274
|
inputSchema: objectSchema({
|
|
272
275
|
thread_id: { type: 'string', minLength: 1, description: 'Thread containing the turn.' },
|
|
273
276
|
turn_id: { type: 'string', minLength: 1, description: 'Turn ID to interrupt.' },
|
|
@@ -278,6 +281,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
278
281
|
name: 'codex-request-list',
|
|
279
282
|
description: [
|
|
280
283
|
[
|
|
284
|
+
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
281
285
|
'List pending approval requests from Codex agents (command execution, file changes, permissions).',
|
|
282
286
|
'',
|
|
283
287
|
'CRITICAL: Check this after every codex-turn-start — agents frequently pause and wait for approval before executing shell commands or writing files.',
|
|
@@ -295,6 +299,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
295
299
|
name: 'codex-request-respond',
|
|
296
300
|
description: [
|
|
297
301
|
[
|
|
302
|
+
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
298
303
|
'Approve or decline a pending Codex agent request (command execution, file changes, permissions, user input).',
|
|
299
304
|
'',
|
|
300
305
|
'Common patterns:',
|
|
@@ -323,6 +328,7 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
323
328
|
{
|
|
324
329
|
name: 'codex-wait',
|
|
325
330
|
description: [
|
|
331
|
+
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
326
332
|
'Block until a Codex turn completes or a pending approval request appears.',
|
|
327
333
|
'',
|
|
328
334
|
'Use after codex-turn-start to wait for the agent to finish or ask for permission.',
|