mcp-codex-worker 0.1.18 → 0.1.21
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/README.md +142 -75
- package/dist/src/app.d.ts +0 -10
- package/dist/src/app.js +4 -397
- package/dist/src/app.js.map +1 -1
- package/dist/src/mcp/tool-definitions.d.ts +14 -178
- package/dist/src/mcp/tool-definitions.js +2 -241
- package/dist/src/mcp/tool-definitions.js.map +1 -1
- package/package.json +1 -1
- package/src/app.ts +5 -474
- package/src/mcp/tool-definitions.ts +2 -269
- package/dist/src/mcp/task-markdown.d.ts +0 -4
- package/dist/src/mcp/task-markdown.js +0 -107
- package/dist/src/mcp/task-markdown.js.map +0 -1
- package/dist/src/mcp/tool-banners.d.ts +0 -3
- package/dist/src/mcp/tool-banners.js +0 -44
- package/dist/src/mcp/tool-banners.js.map +0 -1
- package/src/mcp/task-markdown.ts +0 -136
- package/src/mcp/tool-banners.ts +0 -53
|
@@ -1,70 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
const threadStartSchema = z.object({
|
|
4
|
-
model: z.string().optional(),
|
|
5
|
-
cwd: z.string().optional(),
|
|
6
|
-
developer_instructions: z.string().optional(),
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
const threadResumeSchema = z.object({
|
|
10
|
-
thread_id: z.string().min(1),
|
|
11
|
-
model: z.string().optional(),
|
|
12
|
-
cwd: z.string().optional(),
|
|
13
|
-
developer_instructions: z.string().optional(),
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const threadReadSchema = z.object({
|
|
17
|
-
thread_id: z.string().min(1),
|
|
18
|
-
include_turns: z.boolean().optional(),
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
const threadListSchema = z.object({
|
|
22
|
-
limit: z.number().int().positive().max(100).optional(),
|
|
23
|
-
cursor: z.string().optional(),
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const turnStartSchema = z.object({
|
|
27
|
-
thread_id: z.string().min(1),
|
|
28
|
-
user_input: z.string().min(1),
|
|
29
|
-
model: z.string().optional(),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
const turnSteerSchema = z.object({
|
|
33
|
-
thread_id: z.string().min(1),
|
|
34
|
-
expected_turn_id: z.string().min(1),
|
|
35
|
-
user_input: z.string().min(1),
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
const turnInterruptSchema = z.object({
|
|
39
|
-
thread_id: z.string().min(1),
|
|
40
|
-
turn_id: z.string().min(1),
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const requestListSchema = z.object({
|
|
44
|
-
include_resolved: z.boolean().optional(),
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const requestRespondSchema = z.object({
|
|
48
|
-
request_id: z.union([z.string(), z.number()]),
|
|
49
|
-
payload: z.record(z.string(), z.unknown()).optional(),
|
|
50
|
-
decision: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
|
|
51
|
-
answers: z.record(z.string(), z.object({ answers: z.array(z.string()) })).optional(),
|
|
52
|
-
action: z.enum(['accept', 'decline', 'cancel']).optional(),
|
|
53
|
-
content: z.unknown().optional(),
|
|
54
|
-
meta: z.unknown().optional(),
|
|
55
|
-
scope: z.enum(['turn', 'session']).optional(),
|
|
56
|
-
permissions: z.record(z.string(), z.unknown()).optional(),
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const waitSchema = z.object({
|
|
60
|
-
operation_id: z.string().optional(),
|
|
61
|
-
thread_id: z.string().optional(),
|
|
62
|
-
timeout_ms: z.number().int().positive().max(300_000).optional(),
|
|
63
|
-
poll_interval_ms: z.number().int().positive().max(5_000).optional(),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
3
|
// ---------------------------------------------------------------------------
|
|
67
|
-
//
|
|
4
|
+
// Unified task tool schemas (provider-agnostic)
|
|
68
5
|
// ---------------------------------------------------------------------------
|
|
69
6
|
|
|
70
7
|
const spawnTaskSchema = z.object({
|
|
@@ -152,202 +89,8 @@ function objectSchema(
|
|
|
152
89
|
};
|
|
153
90
|
}
|
|
154
91
|
|
|
155
|
-
export
|
|
156
|
-
modelIds: string[];
|
|
157
|
-
threadBanner: string;
|
|
158
|
-
requestBanner: string;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDefinition[] {
|
|
162
|
-
const { modelIds, threadBanner, requestBanner } = input;
|
|
92
|
+
export function createToolDefinitions(): ToolDefinition[] {
|
|
163
93
|
return [
|
|
164
|
-
{
|
|
165
|
-
name: 'codex-thread-start',
|
|
166
|
-
description: [
|
|
167
|
-
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
168
|
-
'Launch a new Codex agent as a background thread.',
|
|
169
|
-
'',
|
|
170
|
-
'PARALLEL EXECUTION: Launch multiple threads simultaneously — each thread is an independent agent workspace with its own context and conversation history.',
|
|
171
|
-
'This is the primary way to dispatch coding and testing work to Codex.',
|
|
172
|
-
'',
|
|
173
|
-
'After creating a thread, use codex-turn-start to send the task prompt.',
|
|
174
|
-
'Use codex-wait to block until the agent finishes or asks for permission.',
|
|
175
|
-
'Check codex-request-list after starting turns — agents often need approval for commands or file changes.',
|
|
176
|
-
].join('\n'),
|
|
177
|
-
inputSchema: objectSchema({
|
|
178
|
-
model: {
|
|
179
|
-
type: 'string',
|
|
180
|
-
...(modelIds.length > 0 ? { enum: modelIds } : {}),
|
|
181
|
-
description: 'Model to use. Omit to use the server config default (usually gpt-5.4). Available models are listed in the enum.',
|
|
182
|
-
},
|
|
183
|
-
cwd: {
|
|
184
|
-
type: 'string',
|
|
185
|
-
description: 'Working directory for the agent. Defaults to server process cwd.',
|
|
186
|
-
},
|
|
187
|
-
developer_instructions: {
|
|
188
|
-
type: 'string',
|
|
189
|
-
description: 'System-level instructions injected before user messages. Use for constraints, coding style, acceptance criteria, or scope boundaries. Be specific — include file paths, function names, and expected behavior.',
|
|
190
|
-
},
|
|
191
|
-
}),
|
|
192
|
-
validate: (value) => threadStartSchema.parse(value),
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: 'codex-thread-resume',
|
|
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.',
|
|
197
|
-
inputSchema: objectSchema({
|
|
198
|
-
thread_id: { type: 'string', minLength: 1, description: 'ID of the thread to resume.' },
|
|
199
|
-
model: {
|
|
200
|
-
type: 'string',
|
|
201
|
-
...(modelIds.length > 0 ? { enum: modelIds } : {}),
|
|
202
|
-
description: 'Optionally switch model when resuming.',
|
|
203
|
-
},
|
|
204
|
-
cwd: { type: 'string', description: 'Override working directory for the resumed thread.' },
|
|
205
|
-
developer_instructions: { type: 'string', description: 'Update system instructions on resume.' },
|
|
206
|
-
}, ['thread_id']),
|
|
207
|
-
validate: (value) => threadResumeSchema.parse(value),
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
name: 'codex-thread-read',
|
|
211
|
-
description: [
|
|
212
|
-
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
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.',
|
|
214
|
-
threadBanner,
|
|
215
|
-
].filter(Boolean).join('\n\n'),
|
|
216
|
-
inputSchema: objectSchema({
|
|
217
|
-
thread_id: { type: 'string', minLength: 1, description: 'Thread to read.' },
|
|
218
|
-
include_turns: { type: 'boolean', description: 'Include full turn history with tool calls and outputs. Defaults to true.' },
|
|
219
|
-
}, ['thread_id']),
|
|
220
|
-
validate: (value) => threadReadSchema.parse(value),
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
name: 'codex-thread-list',
|
|
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.',
|
|
225
|
-
inputSchema: objectSchema({
|
|
226
|
-
limit: { type: 'integer', minimum: 1, maximum: 100, description: 'Max threads to return. Default 50.' },
|
|
227
|
-
cursor: { type: 'string', description: 'Pagination cursor from a previous response.' },
|
|
228
|
-
}),
|
|
229
|
-
validate: (value) => threadListSchema.parse(value),
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
name: 'codex-turn-start',
|
|
233
|
-
description: [
|
|
234
|
-
[
|
|
235
|
-
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
236
|
-
'Send a task to an active Codex thread, starting an autonomous agent turn.',
|
|
237
|
-
'',
|
|
238
|
-
'The agent executes independently — it reads files, writes code, runs commands, and commits changes.',
|
|
239
|
-
'Use codex-wait to block until the turn completes or a pending request appears.',
|
|
240
|
-
'Use codex-turn-steer to redirect the agent mid-execution if it goes off track.',
|
|
241
|
-
'',
|
|
242
|
-
'IMPORTANT: After starting a turn, check codex-request-list — the agent frequently needs approval for shell commands or file changes before it can proceed.',
|
|
243
|
-
'For parallel work, start turns on multiple threads simultaneously.',
|
|
244
|
-
].join('\n'),
|
|
245
|
-
threadBanner,
|
|
246
|
-
].filter(Boolean).join('\n\n'),
|
|
247
|
-
inputSchema: objectSchema({
|
|
248
|
-
thread_id: { type: 'string', minLength: 1, description: 'Thread to send the task to.' },
|
|
249
|
-
user_input: { type: 'string', minLength: 1, description: 'The task instruction. Be specific: include file paths, function names, acceptance criteria, and constraints.' },
|
|
250
|
-
model: {
|
|
251
|
-
type: 'string',
|
|
252
|
-
...(modelIds.length > 0 ? { enum: modelIds } : {}),
|
|
253
|
-
description: 'Override model for this turn only.',
|
|
254
|
-
},
|
|
255
|
-
}, ['thread_id', 'user_input']),
|
|
256
|
-
validate: (value) => turnStartSchema.parse(value),
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
name: 'codex-turn-steer',
|
|
260
|
-
description: [
|
|
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.',
|
|
262
|
-
threadBanner,
|
|
263
|
-
].filter(Boolean).join('\n\n'),
|
|
264
|
-
inputSchema: objectSchema({
|
|
265
|
-
thread_id: { type: 'string', minLength: 1, description: 'Thread containing the active turn.' },
|
|
266
|
-
expected_turn_id: { type: 'string', minLength: 1, description: 'Turn ID to steer. Must be the currently active turn.' },
|
|
267
|
-
user_input: { type: 'string', minLength: 1, description: 'New instructions to redirect the agent.' },
|
|
268
|
-
}, ['thread_id', 'expected_turn_id', 'user_input']),
|
|
269
|
-
validate: (value) => turnSteerSchema.parse(value),
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
name: 'codex-turn-interrupt',
|
|
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.',
|
|
274
|
-
inputSchema: objectSchema({
|
|
275
|
-
thread_id: { type: 'string', minLength: 1, description: 'Thread containing the turn.' },
|
|
276
|
-
turn_id: { type: 'string', minLength: 1, description: 'Turn ID to interrupt.' },
|
|
277
|
-
}, ['thread_id', 'turn_id']),
|
|
278
|
-
validate: (value) => turnInterruptSchema.parse(value),
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
name: 'codex-request-list',
|
|
282
|
-
description: [
|
|
283
|
-
[
|
|
284
|
-
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
285
|
-
'List pending approval requests from Codex agents (command execution, file changes, permissions).',
|
|
286
|
-
'',
|
|
287
|
-
'CRITICAL: Check this after every codex-turn-start — agents frequently pause and wait for approval before executing shell commands or writing files.',
|
|
288
|
-
'If an agent appears stuck, it is almost certainly waiting for a request to be approved.',
|
|
289
|
-
'Use codex-request-respond to approve or decline each request.',
|
|
290
|
-
].join('\n'),
|
|
291
|
-
requestBanner,
|
|
292
|
-
].filter(Boolean).join('\n\n'),
|
|
293
|
-
inputSchema: objectSchema({
|
|
294
|
-
include_resolved: { type: 'boolean', description: 'Include already-resolved requests. Default false.' },
|
|
295
|
-
}),
|
|
296
|
-
validate: (value) => requestListSchema.parse(value),
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
name: 'codex-request-respond',
|
|
300
|
-
description: [
|
|
301
|
-
[
|
|
302
|
-
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
303
|
-
'Approve or decline a pending Codex agent request (command execution, file changes, permissions, user input).',
|
|
304
|
-
'',
|
|
305
|
-
'Common patterns:',
|
|
306
|
-
'- Approve command/file change: decision="accept"',
|
|
307
|
-
'- Decline: decision="decline"',
|
|
308
|
-
'- Grant permissions: scope="session", permissions={...}',
|
|
309
|
-
'- Answer agent question: answers={ "key": { "answers": ["value"] } }',
|
|
310
|
-
'',
|
|
311
|
-
'The tool auto-builds the correct payload shape based on the request method.',
|
|
312
|
-
].join('\n'),
|
|
313
|
-
requestBanner,
|
|
314
|
-
].filter(Boolean).join('\n\n'),
|
|
315
|
-
inputSchema: objectSchema({
|
|
316
|
-
request_id: { type: ['string', 'number'], description: 'ID of the request to respond to.' },
|
|
317
|
-
payload: { type: 'object', description: 'Raw response payload. Overrides all other fields if provided.' },
|
|
318
|
-
decision: { type: ['string', 'object'], description: 'For approval requests: "accept", "decline", or a structured decision.' },
|
|
319
|
-
answers: { type: 'object', description: 'For user input requests: map of question keys to answer arrays.' },
|
|
320
|
-
action: { type: 'string', enum: ['accept', 'decline', 'cancel'], description: 'For elicitation requests.' },
|
|
321
|
-
content: { description: 'Content payload for elicitation responses.' },
|
|
322
|
-
meta: { description: 'Metadata for elicitation responses.' },
|
|
323
|
-
scope: { type: 'string', enum: ['turn', 'session'], description: 'Permission grant scope. Default "session".' },
|
|
324
|
-
permissions: { type: 'object', description: 'Permission map for permission approval requests.' },
|
|
325
|
-
}, ['request_id']),
|
|
326
|
-
validate: (value) => requestRespondSchema.parse(value),
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
name: 'codex-wait',
|
|
330
|
-
description: [
|
|
331
|
-
'⚠️ DEPRECATED — Use spawn-task/wait-task/respond-task instead. This tool will be removed in v2.0.\n',
|
|
332
|
-
'Block until a Codex turn completes or a pending approval request appears.',
|
|
333
|
-
'',
|
|
334
|
-
'Use after codex-turn-start to wait for the agent to finish or ask for permission.',
|
|
335
|
-
'Provide operation_id (from turn-start response) for precise tracking, or thread_id to poll thread status.',
|
|
336
|
-
'When it returns with a pending request, use codex-request-list + codex-request-respond to unblock the agent.',
|
|
337
|
-
].join('\n'),
|
|
338
|
-
inputSchema: objectSchema({
|
|
339
|
-
operation_id: { type: 'string', description: 'Operation ID to wait on (from a codex-turn-start response).' },
|
|
340
|
-
thread_id: { type: 'string', description: 'Thread ID to wait on — polls until thread status is no longer active.' },
|
|
341
|
-
timeout_ms: { type: 'integer', minimum: 1, maximum: 300000, description: 'Max wait time in ms. Default 120,000 (2 minutes).' },
|
|
342
|
-
poll_interval_ms: { type: 'integer', minimum: 1, maximum: 5000, description: 'Poll interval in ms. Default 250.' },
|
|
343
|
-
}),
|
|
344
|
-
validate: (value) => waitSchema.parse(value),
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
// -----------------------------------------------------------------
|
|
348
|
-
// New unified task tools (provider-agnostic)
|
|
349
|
-
// -----------------------------------------------------------------
|
|
350
|
-
|
|
351
94
|
{
|
|
352
95
|
name: 'spawn-task',
|
|
353
96
|
description: [
|
|
@@ -529,16 +272,6 @@ export function createToolDefinitions(input: CreateToolDefinitionsInput): ToolDe
|
|
|
529
272
|
];
|
|
530
273
|
}
|
|
531
274
|
|
|
532
|
-
export type ThreadStartInput = z.infer<typeof threadStartSchema>;
|
|
533
|
-
export type ThreadResumeInput = z.infer<typeof threadResumeSchema>;
|
|
534
|
-
export type ThreadReadInput = z.infer<typeof threadReadSchema>;
|
|
535
|
-
export type ThreadListInput = z.infer<typeof threadListSchema>;
|
|
536
|
-
export type TurnStartInput = z.infer<typeof turnStartSchema>;
|
|
537
|
-
export type TurnSteerInput = z.infer<typeof turnSteerSchema>;
|
|
538
|
-
export type TurnInterruptInput = z.infer<typeof turnInterruptSchema>;
|
|
539
|
-
export type RequestListInput = z.infer<typeof requestListSchema>;
|
|
540
|
-
export type RequestRespondInput = z.infer<typeof requestRespondSchema>;
|
|
541
|
-
export type WaitInput = z.infer<typeof waitSchema>;
|
|
542
275
|
export type SpawnTaskInput = z.infer<typeof spawnTaskSchema>;
|
|
543
276
|
export type WaitTaskInput = z.infer<typeof waitTaskSchema>;
|
|
544
277
|
export type RespondTaskInput = z.infer<typeof respondTaskSchema>;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { PendingServerRequest, RuntimeOperation } from '../types/codex.js';
|
|
2
|
-
export declare function renderThreadMarkdown(raw: unknown, operations: RuntimeOperation[], pendingRequests: PendingServerRequest[]): string;
|
|
3
|
-
export declare function renderThreadListMarkdown(rawThreads: unknown[], pendingRequests: PendingServerRequest[]): string;
|
|
4
|
-
export declare function renderRequestListMarkdown(requests: PendingServerRequest[]): string;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
function extractThread(raw) {
|
|
2
|
-
const obj = (raw ?? {});
|
|
3
|
-
const thread = (obj.thread ?? obj);
|
|
4
|
-
return {
|
|
5
|
-
id: typeof thread.id === 'string' ? thread.id : undefined,
|
|
6
|
-
status: thread.status,
|
|
7
|
-
model: typeof thread.model === 'string' ? thread.model : undefined,
|
|
8
|
-
createdAt: typeof thread.createdAt === 'string' ? thread.createdAt : undefined,
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
function requestsForThread(requests, threadId) {
|
|
12
|
-
if (!threadId)
|
|
13
|
-
return requests;
|
|
14
|
-
return requests.filter((r) => {
|
|
15
|
-
const params = r.params;
|
|
16
|
-
return params?.threadId === threadId;
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
export function renderThreadMarkdown(raw, operations, pendingRequests) {
|
|
20
|
-
const thread = extractThread(raw);
|
|
21
|
-
const threadId = thread.id ?? 'unknown';
|
|
22
|
-
const statusType = thread.status?.type ?? 'unknown';
|
|
23
|
-
const threadRequests = requestsForThread(pendingRequests, thread.id);
|
|
24
|
-
const lines = [
|
|
25
|
-
`# Thread: ${threadId}`,
|
|
26
|
-
'',
|
|
27
|
-
'| Field | Value |',
|
|
28
|
-
'|---|---|',
|
|
29
|
-
`| **Status** | \`${statusType}\` |`,
|
|
30
|
-
...(thread.model ? [`| **Model** | \`${thread.model}\` |`] : []),
|
|
31
|
-
...(thread.createdAt ? [`| **Created** | ${thread.createdAt} |`] : []),
|
|
32
|
-
'',
|
|
33
|
-
];
|
|
34
|
-
if (operations.length > 0) {
|
|
35
|
-
lines.push('## Operations', '');
|
|
36
|
-
for (const op of operations) {
|
|
37
|
-
const time = op.completedAt ?? op.startedAt;
|
|
38
|
-
lines.push(`- \`${op.operationId}\` [${op.status}] ${op.method} -- ${time}`);
|
|
39
|
-
}
|
|
40
|
-
lines.push('');
|
|
41
|
-
}
|
|
42
|
-
if (threadRequests.length > 0) {
|
|
43
|
-
lines.push(`## Pending Requests (${threadRequests.length})`, '');
|
|
44
|
-
for (const req of threadRequests) {
|
|
45
|
-
lines.push(`### ${String(req.id)} (${req.method})`);
|
|
46
|
-
lines.push(`Use \`codex-request-respond\` with \`request_id: "${String(req.id)}"\` and \`decision: "accept"\`.`);
|
|
47
|
-
lines.push('');
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
lines.push('## What to do next', '');
|
|
51
|
-
if (threadRequests.length > 0) {
|
|
52
|
-
lines.push(`**ACTION REQUIRED** -- ${threadRequests.length} pending request(s) need your response. Use \`codex-request-list\` to see details, then \`codex-request-respond\` to approve or decline.`);
|
|
53
|
-
}
|
|
54
|
-
else if (statusType === 'active') {
|
|
55
|
-
lines.push(`The agent is still working. Use \`codex-wait\` with \`thread_id: "${threadId}"\` to block until it finishes or needs approval.`);
|
|
56
|
-
}
|
|
57
|
-
else if (statusType === 'idle' || statusType === 'completed') {
|
|
58
|
-
lines.push(`Thread is idle. Use \`codex-turn-start\` to send a new task, or \`codex-thread-read\` with \`include_turns: true\` for full conversation history.`);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
lines.push(`Use \`codex-thread-resume\` to reload this thread before starting a turn.`);
|
|
62
|
-
}
|
|
63
|
-
return lines.join('\n');
|
|
64
|
-
}
|
|
65
|
-
export function renderThreadListMarkdown(rawThreads, pendingRequests) {
|
|
66
|
-
const threads = rawThreads.map(extractThread);
|
|
67
|
-
const lines = [
|
|
68
|
-
`# Threads (${threads.length} total)`,
|
|
69
|
-
'',
|
|
70
|
-
'| ID | Status |',
|
|
71
|
-
'|---|---|',
|
|
72
|
-
...threads.map((t) => `| ${t.id ?? 'unknown'} | ${t.status?.type ?? 'unknown'} |`),
|
|
73
|
-
];
|
|
74
|
-
const pending = pendingRequests.filter((r) => r.status === 'pending');
|
|
75
|
-
if (pending.length > 0) {
|
|
76
|
-
lines.push('', `## Pending Requests (${pending.length})`, '');
|
|
77
|
-
for (const req of pending) {
|
|
78
|
-
const params = req.params;
|
|
79
|
-
const tid = typeof params?.threadId === 'string' ? params.threadId : '?';
|
|
80
|
-
lines.push(`- ${tid} / ${String(req.id)}: ${req.method}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return lines.join('\n');
|
|
84
|
-
}
|
|
85
|
-
export function renderRequestListMarkdown(requests) {
|
|
86
|
-
const pending = requests.filter((r) => r.status === 'pending');
|
|
87
|
-
if (pending.length === 0) {
|
|
88
|
-
return [
|
|
89
|
-
'**No pending requests**',
|
|
90
|
-
'',
|
|
91
|
-
'All agents are running without needing approval.',
|
|
92
|
-
].join('\n');
|
|
93
|
-
}
|
|
94
|
-
const lines = [
|
|
95
|
-
`# Pending Requests (${pending.length})`,
|
|
96
|
-
'',
|
|
97
|
-
'| Request ID | Method | Created |',
|
|
98
|
-
'|---|---|---|',
|
|
99
|
-
...pending.map((r) => `| ${String(r.id)} | ${r.method} | ${r.createdAt} |`),
|
|
100
|
-
'',
|
|
101
|
-
'## How to respond',
|
|
102
|
-
'',
|
|
103
|
-
'Use `codex-request-respond` with the `request_id` and `decision: "accept"` to approve, or `decision: "decline"` to reject.',
|
|
104
|
-
];
|
|
105
|
-
return lines.join('\n');
|
|
106
|
-
}
|
|
107
|
-
//# sourceMappingURL=task-markdown.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"task-markdown.js","sourceRoot":"","sources":["../../../src/mcp/task-markdown.ts"],"names":[],"mappings":"AASA,SAAS,aAAa,CAAC,GAAY;IACjC,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAA4B,CAAC;IACnD,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAA4B,CAAC;IAC9D,OAAO;QACL,EAAE,EAAE,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;QACzD,MAAM,EAAE,MAAM,CAAC,MAA8B;QAC7C,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QAClE,SAAS,EAAE,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;KAC/E,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgC,EAAE,QAA4B;IACvF,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC/B,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,CAAC,CAAC,MAA6C,CAAC;QAC/D,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,GAAY,EACZ,UAA8B,EAC9B,eAAuC;IAEvC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,IAAI,SAAS,CAAC;IACxC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,SAAS,CAAC;IACpD,MAAM,cAAc,GAAG,iBAAiB,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAErE,MAAM,KAAK,GAAa;QACtB,aAAa,QAAQ,EAAE;QACvB,EAAE;QACF,mBAAmB;QACnB,WAAW;QACX,oBAAoB,UAAU,MAAM;QACpC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,EAAE;KACH,CAAC;IAEF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAChC,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,SAAS,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,WAAW,OAAO,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,OAAO,IAAI,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,wBAAwB,cAAc,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC;QACjE,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,qDAAqD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,iCAAiC,CAAC,CAAC;YACjH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IAErC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,0BAA0B,cAAc,CAAC,MAAM,0IAA0I,CAAC,CAAC;IACxM,CAAC;SAAM,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,qEAAqE,QAAQ,mDAAmD,CAAC,CAAC;IAC/I,CAAC;SAAM,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC/D,KAAK,CAAC,IAAI,CAAC,mJAAmJ,CAAC,CAAC;IAClK,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,UAAqB,EACrB,eAAuC;IAEvC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAE9C,MAAM,KAAK,GAAa;QACtB,cAAc,OAAO,CAAC,MAAM,SAAS;QACrC,EAAE;QACF,iBAAiB;QACjB,WAAW;QACX,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,SAAS,IAAI,CAAC;KACnF,CAAC;IAEF,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACtE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,wBAAwB,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9D,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,MAA6C,CAAC;YACjE,MAAM,GAAG,GAAG,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;YACzE,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,QAAgC;IAEhC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAE/D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,yBAAyB;YACzB,EAAE;YACF,kDAAkD;SACnD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAa;QACtB,uBAAuB,OAAO,CAAC,MAAM,GAAG;QACxC,EAAE;QACF,mCAAmC;QACnC,eAAe;QACf,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,SAAS,IAAI,CAAC;QAC3E,EAAE;QACF,mBAAmB;QACnB,EAAE;QACF,4HAA4H;KAC7H,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export function buildThreadBanner(runtime) {
|
|
2
|
-
const threadIds = runtime.listKnownThreadIds();
|
|
3
|
-
if (threadIds.length === 0) {
|
|
4
|
-
return '';
|
|
5
|
-
}
|
|
6
|
-
const operations = runtime.getAllOperations();
|
|
7
|
-
const requests = runtime.getPendingServerRequests(false);
|
|
8
|
-
const active = operations.filter((op) => op.status === 'running').length;
|
|
9
|
-
const pending = requests.length;
|
|
10
|
-
const lines = [
|
|
11
|
-
'---',
|
|
12
|
-
`AGENT STATUS: ${active} active | ${pending} pending requests`,
|
|
13
|
-
];
|
|
14
|
-
for (const threadId of threadIds.slice(-3)) {
|
|
15
|
-
const threadOps = operations.filter((op) => op.threadId === threadId);
|
|
16
|
-
const threadReqs = requests.filter((r) => {
|
|
17
|
-
const params = r.params;
|
|
18
|
-
return params?.threadId === threadId;
|
|
19
|
-
});
|
|
20
|
-
const status = threadOps.some((op) => op.status === 'running') ? 'active' : 'idle';
|
|
21
|
-
const reqNote = threadReqs.length > 0 ? ` -- ${threadReqs.length} pending requests` : '';
|
|
22
|
-
lines.push(`- ${threadId} [${status}]${reqNote}`);
|
|
23
|
-
}
|
|
24
|
-
lines.push('Read codex://threads for full details.');
|
|
25
|
-
return lines.join('\n');
|
|
26
|
-
}
|
|
27
|
-
export function buildRequestBanner(runtime) {
|
|
28
|
-
const requests = runtime.getPendingServerRequests(false);
|
|
29
|
-
if (requests.length === 0) {
|
|
30
|
-
return '';
|
|
31
|
-
}
|
|
32
|
-
const lines = [
|
|
33
|
-
'---',
|
|
34
|
-
`ACTION REQUIRED -- ${requests.length} request(s) waiting for your response:`,
|
|
35
|
-
];
|
|
36
|
-
for (const req of requests.slice(0, 5)) {
|
|
37
|
-
const params = req.params;
|
|
38
|
-
const threadId = typeof params?.threadId === 'string' ? params.threadId : '?';
|
|
39
|
-
lines.push(`- ${String(req.id)} (${threadId}): ${req.method}`);
|
|
40
|
-
}
|
|
41
|
-
lines.push('Use codex-request-respond { "request_id": "<id>", "decision": "accept" }');
|
|
42
|
-
return lines.join('\n');
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=tool-banners.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-banners.js","sourceRoot":"","sources":["../../../src/mcp/tool-banners.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,OAAqB;IACrD,MAAM,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAC/C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACzE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC;IAEhC,MAAM,KAAK,GAAG;QACZ,KAAK;QACL,iBAAiB,MAAM,aAAa,OAAO,mBAAmB;KAC/D,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACtE,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,CAAC,CAAC,MAA6C,CAAC;YAC/D,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QACnF,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,UAAU,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACzD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,KAAK;QACL,sBAAsB,QAAQ,CAAC,MAAM,wCAAwC;KAC9E,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,GAAG,CAAC,MAA6C,CAAC;QACjE,MAAM,QAAQ,GAAG,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9E,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,QAAQ,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;IACvF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/src/mcp/task-markdown.ts
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import type { PendingServerRequest, RuntimeOperation } from '../types/codex.js';
|
|
2
|
-
|
|
3
|
-
interface ThreadData {
|
|
4
|
-
id: string | undefined;
|
|
5
|
-
status: { type?: string } | undefined;
|
|
6
|
-
model: string | undefined;
|
|
7
|
-
createdAt: string | undefined;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function extractThread(raw: unknown): ThreadData {
|
|
11
|
-
const obj = (raw ?? {}) as Record<string, unknown>;
|
|
12
|
-
const thread = (obj.thread ?? obj) as Record<string, unknown>;
|
|
13
|
-
return {
|
|
14
|
-
id: typeof thread.id === 'string' ? thread.id : undefined,
|
|
15
|
-
status: thread.status as ThreadData['status'],
|
|
16
|
-
model: typeof thread.model === 'string' ? thread.model : undefined,
|
|
17
|
-
createdAt: typeof thread.createdAt === 'string' ? thread.createdAt : undefined,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function requestsForThread(requests: PendingServerRequest[], threadId: string | undefined): PendingServerRequest[] {
|
|
22
|
-
if (!threadId) return requests;
|
|
23
|
-
return requests.filter((r) => {
|
|
24
|
-
const params = r.params as Record<string, unknown> | undefined;
|
|
25
|
-
return params?.threadId === threadId;
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function renderThreadMarkdown(
|
|
30
|
-
raw: unknown,
|
|
31
|
-
operations: RuntimeOperation[],
|
|
32
|
-
pendingRequests: PendingServerRequest[],
|
|
33
|
-
): string {
|
|
34
|
-
const thread = extractThread(raw);
|
|
35
|
-
const threadId = thread.id ?? 'unknown';
|
|
36
|
-
const statusType = thread.status?.type ?? 'unknown';
|
|
37
|
-
const threadRequests = requestsForThread(pendingRequests, thread.id);
|
|
38
|
-
|
|
39
|
-
const lines: string[] = [
|
|
40
|
-
`# Thread: ${threadId}`,
|
|
41
|
-
'',
|
|
42
|
-
'| Field | Value |',
|
|
43
|
-
'|---|---|',
|
|
44
|
-
`| **Status** | \`${statusType}\` |`,
|
|
45
|
-
...(thread.model ? [`| **Model** | \`${thread.model}\` |`] : []),
|
|
46
|
-
...(thread.createdAt ? [`| **Created** | ${thread.createdAt} |`] : []),
|
|
47
|
-
'',
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
if (operations.length > 0) {
|
|
51
|
-
lines.push('## Operations', '');
|
|
52
|
-
for (const op of operations) {
|
|
53
|
-
const time = op.completedAt ?? op.startedAt;
|
|
54
|
-
lines.push(`- \`${op.operationId}\` [${op.status}] ${op.method} -- ${time}`);
|
|
55
|
-
}
|
|
56
|
-
lines.push('');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (threadRequests.length > 0) {
|
|
60
|
-
lines.push(`## Pending Requests (${threadRequests.length})`, '');
|
|
61
|
-
for (const req of threadRequests) {
|
|
62
|
-
lines.push(`### ${String(req.id)} (${req.method})`);
|
|
63
|
-
lines.push(`Use \`codex-request-respond\` with \`request_id: "${String(req.id)}"\` and \`decision: "accept"\`.`);
|
|
64
|
-
lines.push('');
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
lines.push('## What to do next', '');
|
|
69
|
-
|
|
70
|
-
if (threadRequests.length > 0) {
|
|
71
|
-
lines.push(`**ACTION REQUIRED** -- ${threadRequests.length} pending request(s) need your response. Use \`codex-request-list\` to see details, then \`codex-request-respond\` to approve or decline.`);
|
|
72
|
-
} else if (statusType === 'active') {
|
|
73
|
-
lines.push(`The agent is still working. Use \`codex-wait\` with \`thread_id: "${threadId}"\` to block until it finishes or needs approval.`);
|
|
74
|
-
} else if (statusType === 'idle' || statusType === 'completed') {
|
|
75
|
-
lines.push(`Thread is idle. Use \`codex-turn-start\` to send a new task, or \`codex-thread-read\` with \`include_turns: true\` for full conversation history.`);
|
|
76
|
-
} else {
|
|
77
|
-
lines.push(`Use \`codex-thread-resume\` to reload this thread before starting a turn.`);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return lines.join('\n');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function renderThreadListMarkdown(
|
|
84
|
-
rawThreads: unknown[],
|
|
85
|
-
pendingRequests: PendingServerRequest[],
|
|
86
|
-
): string {
|
|
87
|
-
const threads = rawThreads.map(extractThread);
|
|
88
|
-
|
|
89
|
-
const lines: string[] = [
|
|
90
|
-
`# Threads (${threads.length} total)`,
|
|
91
|
-
'',
|
|
92
|
-
'| ID | Status |',
|
|
93
|
-
'|---|---|',
|
|
94
|
-
...threads.map((t) => `| ${t.id ?? 'unknown'} | ${t.status?.type ?? 'unknown'} |`),
|
|
95
|
-
];
|
|
96
|
-
|
|
97
|
-
const pending = pendingRequests.filter((r) => r.status === 'pending');
|
|
98
|
-
if (pending.length > 0) {
|
|
99
|
-
lines.push('', `## Pending Requests (${pending.length})`, '');
|
|
100
|
-
for (const req of pending) {
|
|
101
|
-
const params = req.params as Record<string, unknown> | undefined;
|
|
102
|
-
const tid = typeof params?.threadId === 'string' ? params.threadId : '?';
|
|
103
|
-
lines.push(`- ${tid} / ${String(req.id)}: ${req.method}`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return lines.join('\n');
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function renderRequestListMarkdown(
|
|
111
|
-
requests: PendingServerRequest[],
|
|
112
|
-
): string {
|
|
113
|
-
const pending = requests.filter((r) => r.status === 'pending');
|
|
114
|
-
|
|
115
|
-
if (pending.length === 0) {
|
|
116
|
-
return [
|
|
117
|
-
'**No pending requests**',
|
|
118
|
-
'',
|
|
119
|
-
'All agents are running without needing approval.',
|
|
120
|
-
].join('\n');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const lines: string[] = [
|
|
124
|
-
`# Pending Requests (${pending.length})`,
|
|
125
|
-
'',
|
|
126
|
-
'| Request ID | Method | Created |',
|
|
127
|
-
'|---|---|---|',
|
|
128
|
-
...pending.map((r) => `| ${String(r.id)} | ${r.method} | ${r.createdAt} |`),
|
|
129
|
-
'',
|
|
130
|
-
'## How to respond',
|
|
131
|
-
'',
|
|
132
|
-
'Use `codex-request-respond` with the `request_id` and `decision: "accept"` to approve, or `decision: "decline"` to reject.',
|
|
133
|
-
];
|
|
134
|
-
|
|
135
|
-
return lines.join('\n');
|
|
136
|
-
}
|
package/src/mcp/tool-banners.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { CodexRuntime } from '../services/codex-runtime.js';
|
|
2
|
-
|
|
3
|
-
export function buildThreadBanner(runtime: CodexRuntime): string {
|
|
4
|
-
const threadIds = runtime.listKnownThreadIds();
|
|
5
|
-
if (threadIds.length === 0) {
|
|
6
|
-
return '';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const operations = runtime.getAllOperations();
|
|
10
|
-
const requests = runtime.getPendingServerRequests(false);
|
|
11
|
-
const active = operations.filter((op) => op.status === 'running').length;
|
|
12
|
-
const pending = requests.length;
|
|
13
|
-
|
|
14
|
-
const lines = [
|
|
15
|
-
'---',
|
|
16
|
-
`AGENT STATUS: ${active} active | ${pending} pending requests`,
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
for (const threadId of threadIds.slice(-3)) {
|
|
20
|
-
const threadOps = operations.filter((op) => op.threadId === threadId);
|
|
21
|
-
const threadReqs = requests.filter((r) => {
|
|
22
|
-
const params = r.params as Record<string, unknown> | undefined;
|
|
23
|
-
return params?.threadId === threadId;
|
|
24
|
-
});
|
|
25
|
-
const status = threadOps.some((op) => op.status === 'running') ? 'active' : 'idle';
|
|
26
|
-
const reqNote = threadReqs.length > 0 ? ` -- ${threadReqs.length} pending requests` : '';
|
|
27
|
-
lines.push(`- ${threadId} [${status}]${reqNote}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
lines.push('Read codex://threads for full details.');
|
|
31
|
-
return lines.join('\n');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function buildRequestBanner(runtime: CodexRuntime): string {
|
|
35
|
-
const requests = runtime.getPendingServerRequests(false);
|
|
36
|
-
if (requests.length === 0) {
|
|
37
|
-
return '';
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const lines = [
|
|
41
|
-
'---',
|
|
42
|
-
`ACTION REQUIRED -- ${requests.length} request(s) waiting for your response:`,
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
for (const req of requests.slice(0, 5)) {
|
|
46
|
-
const params = req.params as Record<string, unknown> | undefined;
|
|
47
|
-
const threadId = typeof params?.threadId === 'string' ? params.threadId : '?';
|
|
48
|
-
lines.push(`- ${String(req.id)} (${threadId}): ${req.method}`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
lines.push('Use codex-request-respond { "request_id": "<id>", "decision": "accept" }');
|
|
52
|
-
return lines.join('\n');
|
|
53
|
-
}
|