genaicode 2.3.0 → 2.4.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.
- package/CHANGELOG.md +25 -0
- package/README.md +59 -11
- package/dist/agents/cli-agent.d.ts +28 -0
- package/dist/agents/cli-agent.js +57 -0
- package/dist/agents/cli-agent.js.map +1 -0
- package/dist/agents/discovery.d.ts +10 -0
- package/dist/agents/discovery.js +31 -0
- package/dist/agents/discovery.js.map +1 -0
- package/dist/agents/drivers/claude.d.ts +25 -0
- package/dist/agents/drivers/claude.js +184 -0
- package/dist/agents/drivers/claude.js.map +1 -0
- package/dist/agents/drivers/codex-live.d.ts +17 -0
- package/dist/agents/drivers/codex-live.js +182 -0
- package/dist/agents/drivers/codex-live.js.map +1 -0
- package/dist/agents/drivers/codex.d.ts +27 -0
- package/dist/agents/drivers/codex.js +176 -0
- package/dist/agents/drivers/codex.js.map +1 -0
- package/dist/agents/drivers/copilot.d.ts +27 -0
- package/dist/agents/drivers/copilot.js +199 -0
- package/dist/agents/drivers/copilot.js.map +1 -0
- package/dist/agents/drivers/cursor.d.ts +23 -0
- package/dist/agents/drivers/cursor.js +174 -0
- package/dist/agents/drivers/cursor.js.map +1 -0
- package/dist/agents/drivers/gemini.d.ts +18 -0
- package/dist/agents/drivers/gemini.js +118 -0
- package/dist/agents/drivers/gemini.js.map +1 -0
- package/dist/agents/drivers/json.d.ts +6 -0
- package/dist/agents/drivers/json.js +20 -0
- package/dist/agents/drivers/json.js.map +1 -0
- package/dist/agents/drivers/muse-live.d.ts +17 -0
- package/dist/agents/drivers/muse-live.js +112 -0
- package/dist/agents/drivers/muse-live.js.map +1 -0
- package/dist/agents/drivers/muse.d.ts +12 -0
- package/dist/agents/drivers/muse.js +87 -0
- package/dist/agents/drivers/muse.js.map +1 -0
- package/dist/agents/drivers/opencode.d.ts +17 -0
- package/dist/agents/drivers/opencode.js +103 -0
- package/dist/agents/drivers/opencode.js.map +1 -0
- package/dist/agents/env.d.ts +16 -0
- package/dist/agents/env.js +46 -0
- package/dist/agents/env.js.map +1 -0
- package/dist/agents/event-queue.d.ts +44 -0
- package/dist/agents/event-queue.js +123 -0
- package/dist/agents/event-queue.js.map +1 -0
- package/dist/agents/hosted.d.ts +33 -0
- package/dist/agents/hosted.js +129 -0
- package/dist/agents/hosted.js.map +1 -0
- package/dist/agents/live-agent.d.ts +37 -0
- package/dist/agents/live-agent.js +142 -0
- package/dist/agents/live-agent.js.map +1 -0
- package/dist/agents/prepare.d.ts +33 -0
- package/dist/agents/prepare.js +52 -0
- package/dist/agents/prepare.js.map +1 -0
- package/dist/agents/process.d.ts +39 -0
- package/dist/agents/process.js +140 -0
- package/dist/agents/process.js.map +1 -0
- package/dist/agents/rpc.d.ts +29 -0
- package/dist/agents/rpc.js +101 -0
- package/dist/agents/rpc.js.map +1 -0
- package/dist/agents/runtime.d.ts +26 -0
- package/dist/agents/runtime.js +97 -0
- package/dist/agents/runtime.js.map +1 -0
- package/dist/agents/types.d.ts +158 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/agents/verify.d.ts +36 -0
- package/dist/agents/verify.js +43 -0
- package/dist/agents/verify.js.map +1 -0
- package/dist/agents.d.ts +36 -0
- package/dist/agents.js +19 -0
- package/dist/agents.js.map +1 -0
- package/dist/providers/google-converter.js +30 -14
- package/dist/providers/google-converter.js.map +1 -1
- package/dist/providers/google.d.ts +8 -0
- package/dist/providers/google.js.map +1 -1
- package/docs/agents.md +269 -0
- package/docs/pivot.md +4 -0
- package/docs/semver.md +5 -0
- package/package.json +5 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { liveAgent } from '../live-agent.js';
|
|
2
|
+
import { withCodexMcp } from './codex.js';
|
|
3
|
+
import { isObject, numberField, stringField } from './json.js';
|
|
4
|
+
/**
|
|
5
|
+
* Codex over its app server (`codex app-server`, JSON-RPC on stdio).
|
|
6
|
+
* Supports `steer()` and routes command and file-change approvals to `task.onApproval`.
|
|
7
|
+
*/
|
|
8
|
+
export function codexLive(options = {}) {
|
|
9
|
+
return liveAgent({
|
|
10
|
+
name: 'codex',
|
|
11
|
+
command: options.command ?? 'codex',
|
|
12
|
+
capabilities: { effort: ['minimal', 'low', 'medium', 'high', 'xhigh'], usage: true, approvals: true, mcp: true },
|
|
13
|
+
args: (task) => [...(task.extraArgs ?? []), 'app-server'],
|
|
14
|
+
prepare: (task) => withCodexMcp(task, [...(task.extraArgs ?? []), 'app-server']),
|
|
15
|
+
drive: (session) => driveCodex(session, options),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async function driveCodex(session, options) {
|
|
19
|
+
const { task, rpc } = session;
|
|
20
|
+
const timeout = options.requestTimeoutMs ?? 60_000;
|
|
21
|
+
// Filled in as the server replies; notifications before then are not ours.
|
|
22
|
+
const ids = {};
|
|
23
|
+
let finish = () => { };
|
|
24
|
+
const finished = new Promise((resolve) => {
|
|
25
|
+
finish = resolve;
|
|
26
|
+
});
|
|
27
|
+
const ours = (params) => ids.thread !== undefined && stringField(params, 'threadId') === ids.thread;
|
|
28
|
+
session.onNotification((method, params) => {
|
|
29
|
+
if (!ours(params))
|
|
30
|
+
return;
|
|
31
|
+
if (method === 'turn/completed') {
|
|
32
|
+
const turn = isObject(params) && isObject(params.turn) ? params.turn : undefined;
|
|
33
|
+
if (ids.turn && stringField(turn, 'id') && stringField(turn, 'id') !== ids.turn)
|
|
34
|
+
return;
|
|
35
|
+
const status = stringField(turn, 'status');
|
|
36
|
+
const error = stringField(turn?.error, 'message');
|
|
37
|
+
if (error)
|
|
38
|
+
session.emit({ type: 'error', message: error });
|
|
39
|
+
finish(status === 'completed' ? { ok: true } : { ok: false, error: error ?? `Codex turn ${status ?? 'ended'}.` });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
for (const event of codexNotification(method, params))
|
|
43
|
+
session.emit(event);
|
|
44
|
+
});
|
|
45
|
+
let approvals = 0;
|
|
46
|
+
session.onRequest(async (method, params) => {
|
|
47
|
+
const legacy = method === 'execCommandApproval' || method === 'applyPatchApproval';
|
|
48
|
+
const kind = method.includes('commandExecution') || method === 'execCommandApproval' ? 'command' : 'file-change';
|
|
49
|
+
if (!legacy && !method.endsWith('/requestApproval'))
|
|
50
|
+
throw new Error(`${method} is not supported.`);
|
|
51
|
+
const request = {
|
|
52
|
+
// One item can raise several approvals (e.g. per shell subcommand); `approvalId` tells them apart.
|
|
53
|
+
id: stringField(params, 'approvalId') ??
|
|
54
|
+
stringField(params, 'itemId') ??
|
|
55
|
+
stringField(params, 'callId') ??
|
|
56
|
+
`approval-${++approvals}`,
|
|
57
|
+
kind,
|
|
58
|
+
...summaryOf(params),
|
|
59
|
+
detail: params,
|
|
60
|
+
};
|
|
61
|
+
const decision = await session.approve(request);
|
|
62
|
+
if (legacy)
|
|
63
|
+
return { decision: decision === 'approve' ? 'approved' : 'denied' };
|
|
64
|
+
return { decision: decision === 'approve' ? 'accept' : 'decline' };
|
|
65
|
+
});
|
|
66
|
+
await rpc.request('initialize', { clientInfo: { name: 'genaicode', version: '2' } }, timeout);
|
|
67
|
+
rpc.notify('initialized');
|
|
68
|
+
const thread = await rpc.request('thread/start', {
|
|
69
|
+
cwd: task.cwd,
|
|
70
|
+
...(task.model ? { model: task.model } : {}),
|
|
71
|
+
sandbox: options.sandbox ?? 'workspace-write',
|
|
72
|
+
approvalPolicy: task.onApproval ? 'on-request' : 'never',
|
|
73
|
+
}, timeout);
|
|
74
|
+
const threadId = stringField(isObject(thread) ? thread.thread : undefined, 'id');
|
|
75
|
+
ids.thread = threadId;
|
|
76
|
+
if (!threadId)
|
|
77
|
+
throw new Error('Codex did not return a thread id.');
|
|
78
|
+
session.emit({ type: 'session', sessionId: threadId });
|
|
79
|
+
const input = (text) => [{ type: 'text', text }];
|
|
80
|
+
const started = await rpc.request('turn/start', { threadId, input: input(task.prompt), ...(task.effort ? { effort: task.effort } : {}) }, timeout);
|
|
81
|
+
const turnId = stringField(isObject(started) ? started.turn : undefined, 'id');
|
|
82
|
+
ids.turn = turnId;
|
|
83
|
+
if (!turnId)
|
|
84
|
+
throw new Error('Codex did not return a turn id.');
|
|
85
|
+
session.setSteer(async (text) => {
|
|
86
|
+
await rpc.request('turn/steer', { threadId, expectedTurnId: turnId, input: input(text) }, timeout);
|
|
87
|
+
});
|
|
88
|
+
return finished;
|
|
89
|
+
}
|
|
90
|
+
/** Map one app-server notification to agent events. */
|
|
91
|
+
export function codexNotification(method, params) {
|
|
92
|
+
if (!isObject(params))
|
|
93
|
+
return [];
|
|
94
|
+
const item = isObject(params.item) ? params.item : undefined;
|
|
95
|
+
const type = stringField(item, 'type');
|
|
96
|
+
const id = stringField(item, 'id');
|
|
97
|
+
const withId = id ? { id } : {};
|
|
98
|
+
switch (method) {
|
|
99
|
+
case 'item/agentMessage/delta': {
|
|
100
|
+
const delta = stringField(params, 'delta');
|
|
101
|
+
return delta ? [{ type: 'text-delta', text: delta }] : [];
|
|
102
|
+
}
|
|
103
|
+
case 'item/started':
|
|
104
|
+
if (type === 'commandExecution')
|
|
105
|
+
return [{ type: 'tool-start', ...withId, name: 'shell', input: { command: item.command } }];
|
|
106
|
+
if (type === 'mcpToolCall')
|
|
107
|
+
return [{ type: 'tool-start', ...withId, name: mcpName(item), input: item.arguments }];
|
|
108
|
+
return [];
|
|
109
|
+
case 'item/completed':
|
|
110
|
+
if (type === 'agentMessage') {
|
|
111
|
+
const text = stringField(item, 'text');
|
|
112
|
+
return text ? [{ type: 'message', text }] : [];
|
|
113
|
+
}
|
|
114
|
+
if (type === 'commandExecution') {
|
|
115
|
+
const exitCode = numberField(item, 'exitCode');
|
|
116
|
+
const output = stringField(item, 'aggregatedOutput');
|
|
117
|
+
return [
|
|
118
|
+
{
|
|
119
|
+
type: 'tool-end',
|
|
120
|
+
...withId,
|
|
121
|
+
name: 'shell',
|
|
122
|
+
isError: item.status === 'failed' || (exitCode !== undefined && exitCode !== 0),
|
|
123
|
+
...(output !== undefined ? { output } : {}),
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
if (type === 'mcpToolCall')
|
|
128
|
+
return [
|
|
129
|
+
{
|
|
130
|
+
type: 'tool-end',
|
|
131
|
+
...withId,
|
|
132
|
+
name: mcpName(item),
|
|
133
|
+
isError: item.status === 'failed' || (item.error !== undefined && item.error !== null),
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
if (type === 'fileChange') {
|
|
137
|
+
const paths = Array.isArray(item.changes)
|
|
138
|
+
? item.changes.map((change) => stringField(change, 'path')).filter((path) => !!path)
|
|
139
|
+
: [];
|
|
140
|
+
return paths.length ? [{ type: 'file-change', paths }] : [];
|
|
141
|
+
}
|
|
142
|
+
return [];
|
|
143
|
+
case 'thread/tokenUsage/updated': {
|
|
144
|
+
const usage = isObject(params.tokenUsage) ? params.tokenUsage : undefined;
|
|
145
|
+
const total = isObject(usage?.total) ? usage.total : usage;
|
|
146
|
+
const inputTokens = numberField(total, 'inputTokens');
|
|
147
|
+
const outputTokens = numberField(total, 'outputTokens');
|
|
148
|
+
const cachedInputTokens = numberField(total, 'cachedInputTokens');
|
|
149
|
+
if (inputTokens === undefined && outputTokens === undefined)
|
|
150
|
+
return [];
|
|
151
|
+
return [
|
|
152
|
+
{
|
|
153
|
+
type: 'usage',
|
|
154
|
+
usage: {
|
|
155
|
+
...(inputTokens !== undefined ? { inputTokens } : {}),
|
|
156
|
+
...(outputTokens !== undefined ? { outputTokens } : {}),
|
|
157
|
+
...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),
|
|
158
|
+
...(inputTokens !== undefined && outputTokens !== undefined
|
|
159
|
+
? { totalTokens: inputTokens + outputTokens }
|
|
160
|
+
: {}),
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
}
|
|
165
|
+
case 'error': {
|
|
166
|
+
const message = stringField(params.error, 'message') ?? stringField(params, 'message');
|
|
167
|
+
return message ? [{ type: 'error', message }] : [];
|
|
168
|
+
}
|
|
169
|
+
default:
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function summaryOf(params) {
|
|
174
|
+
const command = isObject(params) ? params.command : undefined;
|
|
175
|
+
const text = Array.isArray(command) ? command.join(' ') : typeof command === 'string' ? command : undefined;
|
|
176
|
+
const summary = text ?? stringField(params, 'reason');
|
|
177
|
+
return summary ? { summary } : {};
|
|
178
|
+
}
|
|
179
|
+
function mcpName(item) {
|
|
180
|
+
return [stringField(item, 'server'), stringField(item, 'tool')].filter(Boolean).join('/') || 'mcp';
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=codex-live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-live.js","sourceRoot":"","sources":["../../../src/agents/drivers/codex-live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAC;AAG/D,OAAO,EAAE,YAAY,EAAqB,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAmB,MAAM,WAAW,CAAC;AAWhF;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;IACtD,OAAO,SAAS,CAAC;QACf,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO;QACnC,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE;QAChH,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC;QACzD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;QAChF,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC;KACjD,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAoB,EAAE,OAAyB;IACvE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,IAAI,MAAM,CAAC;IACnD,2EAA2E;IAC3E,MAAM,GAAG,GAAuC,EAAE,CAAC;IACnD,IAAI,MAAM,GAAoC,GAAG,EAAE,GAAE,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,EAAE;QACrD,MAAM,GAAG,OAAO,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,MAAe,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC;IAE7G,OAAO,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO;QAC1B,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YACjF,IAAI,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI;gBAAE,OAAO;YACxF,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YAClD,IAAI,KAAK;gBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3D,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,cAAc,MAAM,IAAI,OAAO,GAAG,EAAE,CAAC,CAAC;YAClH,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,KAAK,qBAAqB,IAAI,MAAM,KAAK,oBAAoB,CAAC;QACnF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,MAAM,KAAK,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;QACjH,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,oBAAoB,CAAC,CAAC;QACpG,MAAM,OAAO,GAAoB;YAC/B,mGAAmG;YACnG,EAAE,EACA,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;gBACjC,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC;gBAC7B,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC;gBAC7B,YAAY,EAAE,SAAS,EAAE;YAC3B,IAAI;YACJ,GAAG,SAAS,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,MAAM;SACf,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,MAAM;YAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChF,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,MAAM,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAC9F,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAE1B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAC9B,cAAc,EACd;QACE,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,iBAAiB;QAC7C,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO;KACzD,EACD,OAAO,CACR,CAAC;IACF,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACjF,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC;IACtB,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACpE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEvD,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAC/B,YAAY,EACZ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EACxF,OAAO,CACR,CAAC;IACF,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/E,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC;IAClB,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAEhE,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC9B,MAAM,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACrG,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,MAAe;IAC/D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,yBAAyB,CAAC,CAAC,CAAC;YAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,CAAC;QACD,KAAK,cAAc;YACjB,IAAI,IAAI,KAAK,kBAAkB;gBAC7B,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC/F,IAAI,IAAI,KAAK,aAAa;gBACxB,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAK,CAAC,EAAE,KAAK,EAAE,IAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YAC3F,OAAO,EAAE,CAAC;QACZ,KAAK,gBAAgB;YACnB,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACvC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,CAAC;YACD,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAChC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;gBACrD,OAAO;oBACL;wBACE,IAAI,EAAE,UAAU;wBAChB,GAAG,MAAM;wBACT,IAAI,EAAE,OAAO;wBACb,OAAO,EAAE,IAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CAAC;wBAChF,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAC5C;iBACF,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,KAAK,aAAa;gBACxB,OAAO;oBACL;wBACE,IAAI,EAAE,UAAU;wBAChB,GAAG,MAAM;wBACT,IAAI,EAAE,OAAO,CAAC,IAAK,CAAC;wBACpB,OAAO,EAAE,IAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,IAAK,CAAC,KAAK,KAAK,SAAS,IAAI,IAAK,CAAC,KAAK,KAAK,IAAI,CAAC;qBAC1F;iBACF,CAAC;YACJ,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAK,CAAC,OAAO,CAAC;oBACxC,CAAC,CAAC,IAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;oBACrG,CAAC,CAAC,EAAE,CAAC;gBACP,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,KAAK,2BAA2B,CAAC,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1E,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;YAC3D,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YACxD,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;YAClE,IAAI,WAAW,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;gBAAE,OAAO,EAAE,CAAC;YACvE,OAAO;gBACL;oBACE,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACrD,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACvD,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACjE,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;4BACzD,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,GAAG,YAAY,EAAE;4BAC7C,CAAC,CAAC,EAAE,CAAC;qBACR;iBACF;aACF,CAAC;QACJ,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACvF,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,CAAC;QACD;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,MAAe;IAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,MAAM,OAAO,GAAG,IAAI,IAAI,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACpC,CAAC;AAED,SAAS,OAAO,CAAC,IAAgB;IAC/B,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;AACrG,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type AgentOutputParser } from '../cli-agent.js';
|
|
2
|
+
import { type PreparedRun } from '../prepare.js';
|
|
3
|
+
import type { AgentTask, CodingAgent, McpServer } from '../types.js';
|
|
4
|
+
export type CodexSandbox = 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
5
|
+
export interface CodexAgentOptions {
|
|
6
|
+
/** Executable name or path. Default `codex`. */
|
|
7
|
+
command?: string;
|
|
8
|
+
/** Default `workspace-write`: edits inside `cwd`, no network. */
|
|
9
|
+
sandbox?: CodexSandbox;
|
|
10
|
+
/** Allow running outside a git repository. Default true. */
|
|
11
|
+
skipGitRepoCheck?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** OpenAI Codex CLI in exec mode (`codex exec --json`). */
|
|
14
|
+
export declare function codex(options?: CodexAgentOptions): CodingAgent;
|
|
15
|
+
export declare function codexArgs(task: AgentTask, options?: CodexAgentOptions): string[];
|
|
16
|
+
/** Prefix `args` with the task's MCP servers as `-c mcp_servers.*` config overrides. */
|
|
17
|
+
export declare function withCodexMcp(task: AgentTask, args: string[]): PreparedRun;
|
|
18
|
+
/**
|
|
19
|
+
* Config overrides for Codex MCP servers. Secrets never go on the command line: HTTP
|
|
20
|
+
* header values travel in environment variables (`env_http_headers`), and a stdio
|
|
21
|
+
* server's `env` is set on Codex's environment and forwarded by name (`env_vars`).
|
|
22
|
+
*/
|
|
23
|
+
export declare function codexMcpOverrides(servers: readonly McpServer[]): {
|
|
24
|
+
args: string[];
|
|
25
|
+
env: Record<string, string>;
|
|
26
|
+
};
|
|
27
|
+
export declare function createCodexParser(): AgentOutputParser;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { cliAgent } from '../cli-agent.js';
|
|
2
|
+
import { isHttpServer } from '../prepare.js';
|
|
3
|
+
import { isObject, numberField, positionalPrompt, stringField } from './json.js';
|
|
4
|
+
/** OpenAI Codex CLI in exec mode (`codex exec --json`). */
|
|
5
|
+
export function codex(options = {}) {
|
|
6
|
+
return cliAgent({
|
|
7
|
+
name: 'codex',
|
|
8
|
+
command: options.command ?? 'codex',
|
|
9
|
+
capabilities: { effort: ['minimal', 'low', 'medium', 'high', 'xhigh'], usage: true, mcp: true },
|
|
10
|
+
args: (task) => codexArgs(task, options),
|
|
11
|
+
prepare: (task) => withCodexMcp(task, codexArgs(task, options)),
|
|
12
|
+
createParser: createCodexParser,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export function codexArgs(task, options = {}) {
|
|
16
|
+
const args = ['exec', '--json', '--sandbox', options.sandbox ?? 'workspace-write'];
|
|
17
|
+
if (options.skipGitRepoCheck ?? true)
|
|
18
|
+
args.push('--skip-git-repo-check');
|
|
19
|
+
if (task.model)
|
|
20
|
+
args.push('--model', task.model);
|
|
21
|
+
if (task.effort)
|
|
22
|
+
args.push('-c', `model_reasoning_effort=${JSON.stringify(task.effort)}`);
|
|
23
|
+
if (task.extraArgs)
|
|
24
|
+
args.push(...task.extraArgs);
|
|
25
|
+
return [...args, ...positionalPrompt(task.prompt)];
|
|
26
|
+
}
|
|
27
|
+
/** Prefix `args` with the task's MCP servers as `-c mcp_servers.*` config overrides. */
|
|
28
|
+
export function withCodexMcp(task, args) {
|
|
29
|
+
if (!task.mcpServers?.length)
|
|
30
|
+
return { args };
|
|
31
|
+
const mcp = codexMcpOverrides(task.mcpServers);
|
|
32
|
+
return { args: [...mcp.args, ...args], env: mcp.env };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Config overrides for Codex MCP servers. Secrets never go on the command line: HTTP
|
|
36
|
+
* header values travel in environment variables (`env_http_headers`), and a stdio
|
|
37
|
+
* server's `env` is set on Codex's environment and forwarded by name (`env_vars`).
|
|
38
|
+
*/
|
|
39
|
+
export function codexMcpOverrides(servers) {
|
|
40
|
+
const args = [];
|
|
41
|
+
const env = {};
|
|
42
|
+
const set = (key, value) => args.push('-c', `${key}=${value}`);
|
|
43
|
+
servers.forEach((server, index) => {
|
|
44
|
+
const key = `mcp_servers.${server.name}`;
|
|
45
|
+
if (isHttpServer(server)) {
|
|
46
|
+
set(`${key}.url`, JSON.stringify(server.url));
|
|
47
|
+
const headers = Object.entries(server.headers ?? {});
|
|
48
|
+
if (headers.length) {
|
|
49
|
+
const table = headers.map(([header, value], headerIndex) => {
|
|
50
|
+
const variable = `GENAICODE_MCP_${index}_HEADER_${headerIndex}`;
|
|
51
|
+
env[variable] = value;
|
|
52
|
+
return `${JSON.stringify(header)} = ${JSON.stringify(variable)}`;
|
|
53
|
+
});
|
|
54
|
+
set(`${key}.env_http_headers`, `{ ${table.join(', ')} }`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
set(`${key}.command`, JSON.stringify(server.command));
|
|
59
|
+
set(`${key}.args`, JSON.stringify(server.args ?? []));
|
|
60
|
+
// Values go into Codex's own environment and are forwarded by name (`env_vars`), so no
|
|
61
|
+
// server secret ever reaches argv.
|
|
62
|
+
const entries = Object.entries(server.env ?? {});
|
|
63
|
+
for (const [name, value] of entries) {
|
|
64
|
+
if (name in env && env[name] !== value) {
|
|
65
|
+
throw new Error(`MCP servers need different values for ${name}; Codex can forward only one.`);
|
|
66
|
+
}
|
|
67
|
+
env[name] = value;
|
|
68
|
+
}
|
|
69
|
+
if (entries.length)
|
|
70
|
+
set(`${key}.env_vars`, JSON.stringify(entries.map(([name]) => name)));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return { args, env };
|
|
74
|
+
}
|
|
75
|
+
export function createCodexParser() {
|
|
76
|
+
let outcome;
|
|
77
|
+
return {
|
|
78
|
+
outcome: () => outcome,
|
|
79
|
+
event(value) {
|
|
80
|
+
if (!isObject(value))
|
|
81
|
+
return [];
|
|
82
|
+
const events = [];
|
|
83
|
+
const type = stringField(value, 'type');
|
|
84
|
+
const item = isObject(value.item) ? value.item : undefined;
|
|
85
|
+
const itemType = stringField(item, 'type');
|
|
86
|
+
const id = stringField(item, 'id');
|
|
87
|
+
const withId = id ? { id } : {};
|
|
88
|
+
if (type === 'thread.started') {
|
|
89
|
+
const sessionId = stringField(value, 'thread_id');
|
|
90
|
+
if (sessionId)
|
|
91
|
+
events.push({ type: 'session', sessionId });
|
|
92
|
+
}
|
|
93
|
+
else if (type === 'item.started' && item) {
|
|
94
|
+
if (itemType === 'command_execution') {
|
|
95
|
+
events.push({ type: 'tool-start', ...withId, name: 'shell', input: { command: item.command } });
|
|
96
|
+
}
|
|
97
|
+
else if (itemType === 'mcp_tool_call') {
|
|
98
|
+
events.push({ type: 'tool-start', ...withId, name: mcpName(item), input: item.arguments });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else if (type === 'item.completed' && item) {
|
|
102
|
+
if (itemType === 'agent_message') {
|
|
103
|
+
const text = stringField(item, 'text');
|
|
104
|
+
if (text)
|
|
105
|
+
events.push({ type: 'message', text });
|
|
106
|
+
}
|
|
107
|
+
else if (itemType === 'command_execution') {
|
|
108
|
+
const output = stringField(item, 'aggregated_output');
|
|
109
|
+
const exitCode = numberField(item, 'exit_code');
|
|
110
|
+
events.push({
|
|
111
|
+
type: 'tool-end',
|
|
112
|
+
...withId,
|
|
113
|
+
name: 'shell',
|
|
114
|
+
isError: item.status === 'failed' || (exitCode !== undefined && exitCode !== 0),
|
|
115
|
+
...(output !== undefined ? { output } : {}),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else if (itemType === 'mcp_tool_call') {
|
|
119
|
+
events.push({
|
|
120
|
+
type: 'tool-end',
|
|
121
|
+
...withId,
|
|
122
|
+
name: mcpName(item),
|
|
123
|
+
isError: item.status === 'failed' || item.error !== undefined,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else if (itemType === 'file_change') {
|
|
127
|
+
const paths = Array.isArray(item.changes)
|
|
128
|
+
? item.changes.map((change) => stringField(change, 'path')).filter((path) => !!path)
|
|
129
|
+
: [];
|
|
130
|
+
if (paths.length)
|
|
131
|
+
events.push({ type: 'file-change', paths });
|
|
132
|
+
}
|
|
133
|
+
else if (itemType === 'error') {
|
|
134
|
+
const message = stringField(item, 'message');
|
|
135
|
+
if (message)
|
|
136
|
+
events.push({ type: 'error', message });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (type === 'turn.completed') {
|
|
140
|
+
outcome = { ok: true };
|
|
141
|
+
const usage = value.usage;
|
|
142
|
+
if (isObject(usage)) {
|
|
143
|
+
const inputTokens = numberField(usage, 'input_tokens');
|
|
144
|
+
const outputTokens = numberField(usage, 'output_tokens');
|
|
145
|
+
const cachedInputTokens = numberField(usage, 'cached_input_tokens');
|
|
146
|
+
events.push({
|
|
147
|
+
type: 'usage',
|
|
148
|
+
usage: {
|
|
149
|
+
...(inputTokens !== undefined ? { inputTokens } : {}),
|
|
150
|
+
...(outputTokens !== undefined ? { outputTokens } : {}),
|
|
151
|
+
...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),
|
|
152
|
+
...(inputTokens !== undefined && outputTokens !== undefined
|
|
153
|
+
? { totalTokens: inputTokens + outputTokens }
|
|
154
|
+
: {}),
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else if (type === 'turn.failed') {
|
|
160
|
+
const message = stringField(value.error, 'message') ?? 'Codex turn failed.';
|
|
161
|
+
outcome = { ok: false, error: message };
|
|
162
|
+
events.push({ type: 'error', message });
|
|
163
|
+
}
|
|
164
|
+
else if (type === 'error') {
|
|
165
|
+
const message = stringField(value, 'message');
|
|
166
|
+
if (message)
|
|
167
|
+
events.push({ type: 'error', message });
|
|
168
|
+
}
|
|
169
|
+
return events;
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function mcpName(item) {
|
|
174
|
+
return [stringField(item, 'server'), stringField(item, 'tool')].filter(Boolean).join('/') || 'mcp';
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/agents/drivers/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA6C,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAoB,MAAM,eAAe,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAajF,2DAA2D;AAC3D,MAAM,UAAU,KAAK,CAAC,UAA6B,EAAE;IACnD,OAAO,QAAQ,CAAC;QACd,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO;QACnC,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE;QAC/F,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC;QACxC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/D,YAAY,EAAE,iBAAiB;KAChC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAe,EAAE,UAA6B,EAAE;IACxE,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,IAAI,iBAAiB,CAAC,CAAC;IACnF,IAAI,OAAO,CAAC,gBAAgB,IAAI,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACzE,IAAI,IAAI,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1F,IAAI,IAAI,CAAC,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,YAAY,CAAC,IAAe,EAAE,IAAc;IAC1D,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9C,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA6B;IAC7D,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;IAC/E,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAChC,MAAM,GAAG,GAAG,eAAe,MAAM,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,GAAG,CAAC,GAAG,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YACrD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,EAAE,EAAE;oBACzD,MAAM,QAAQ,GAAG,iBAAiB,KAAK,WAAW,WAAW,EAAE,CAAC;oBAChE,GAAG,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;oBACtB,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnE,CAAC,CAAC,CAAC;gBACH,GAAG,CAAC,GAAG,GAAG,mBAAmB,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,GAAG,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YACtD,GAAG,CAAC,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YACtD,uFAAuF;YACvF,mCAAmC;YACnC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;YACjD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;gBACpC,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;oBACvC,MAAM,IAAI,KAAK,CAAC,yCAAyC,IAAI,+BAA+B,CAAC,CAAC;gBAChG,CAAC;gBACD,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YACpB,CAAC;YACD,IAAI,OAAO,CAAC,MAAM;gBAAE,GAAG,CAAC,GAAG,GAAG,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,IAAI,OAAiC,CAAC;IAEtC,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO;QACtB,KAAK,CAAC,KAAK;YACT,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAChC,MAAM,MAAM,GAAiB,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3D,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3C,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAEhC,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAC9B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;gBAClD,IAAI,SAAS;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;YAC7D,CAAC;iBAAM,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,EAAE,CAAC;gBAC3C,IAAI,QAAQ,KAAK,mBAAmB,EAAE,CAAC;oBACrC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAClG,CAAC;qBAAM,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;oBACxC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC7F,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,KAAK,gBAAgB,IAAI,IAAI,EAAE,CAAC;gBAC7C,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;oBACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;oBACvC,IAAI,IAAI;wBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnD,CAAC;qBAAM,IAAI,QAAQ,KAAK,mBAAmB,EAAE,CAAC;oBAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;oBACtD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBAChD,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,UAAU;wBAChB,GAAG,MAAM;wBACT,IAAI,EAAE,OAAO;wBACb,OAAO,EAAE,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CAAC;wBAC/E,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAC5C,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;oBACxC,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,UAAU;wBAChB,GAAG,MAAM;wBACT,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;wBACnB,OAAO,EAAE,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;qBAC9D,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;oBACtC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;wBACvC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;wBACpG,CAAC,CAAC,EAAE,CAAC;oBACP,IAAI,KAAK,CAAC,MAAM;wBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;gBAChE,CAAC;qBAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;oBAChC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;oBAC7C,IAAI,OAAO;wBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACrC,OAAO,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;gBAC1B,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACpB,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;oBACvD,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;oBACzD,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;oBACpE,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE;4BACL,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BACrD,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BACvD,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BACjE,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;gCACzD,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,GAAG,YAAY,EAAE;gCAC7C,CAAC,CAAC,EAAE,CAAC;yBACR;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;gBAClC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,oBAAoB,CAAC;gBAC5E,OAAO,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1C,CAAC;iBAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBAC9C,IAAI,OAAO;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,IAA6B;IAC5C,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;AACrG,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type AgentOutputParser } from '../cli-agent.js';
|
|
2
|
+
import type { AgentTask, CodingAgent, McpServer } from '../types.js';
|
|
3
|
+
export interface CopilotAgentOptions {
|
|
4
|
+
/** Executable name or path. Default `copilot`. */
|
|
5
|
+
command?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Pass `--allow-all-tools`. Default true: without it a headless run cannot approve a tool.
|
|
8
|
+
* `denyTools` still wins over it.
|
|
9
|
+
*/
|
|
10
|
+
allowAllTools?: boolean;
|
|
11
|
+
/** Permission patterns passed as `--allow-tool`, e.g. `shell(git:*)` or `write`. */
|
|
12
|
+
allowTools?: readonly string[];
|
|
13
|
+
/** Permission patterns passed as `--deny-tool`, e.g. `shell` or `shell(rm)`. */
|
|
14
|
+
denyTools?: readonly string[];
|
|
15
|
+
/** Keep the `ask_user` tool. Default false (`--no-ask-user`): a headless run has nobody to ask. */
|
|
16
|
+
askUser?: boolean;
|
|
17
|
+
/** With `task.mcpServers` and `allowAllTools: false`: pre-allow every tool of those servers. Default true. */
|
|
18
|
+
allowMcpTools?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** GitHub Copilot CLI in prompt mode (`copilot --prompt=… --output-format json`). */
|
|
21
|
+
export declare function copilot(options?: CopilotAgentOptions): CodingAgent;
|
|
22
|
+
/** The `--additional-mcp-config` document for a set of servers. */
|
|
23
|
+
export declare function copilotMcpConfig(servers: readonly McpServer[]): {
|
|
24
|
+
mcpServers: Record<string, unknown>;
|
|
25
|
+
};
|
|
26
|
+
export declare function copilotArgs(task: AgentTask, options?: CopilotAgentOptions, mcpConfigPath?: string): string[];
|
|
27
|
+
export declare function createCopilotParser(): AgentOutputParser;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { cliAgent } from '../cli-agent.js';
|
|
5
|
+
import { isHttpServer } from '../prepare.js';
|
|
6
|
+
import { isObject, numberField, stringField } from './json.js';
|
|
7
|
+
const EDIT_TOOLS = new Set(['edit', 'create', 'str_replace_editor']);
|
|
8
|
+
/** GitHub Copilot CLI in prompt mode (`copilot --prompt=… --output-format json`). */
|
|
9
|
+
export function copilot(options = {}) {
|
|
10
|
+
return cliAgent({
|
|
11
|
+
name: 'copilot',
|
|
12
|
+
command: options.command ?? 'copilot',
|
|
13
|
+
capabilities: {
|
|
14
|
+
effort: ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'],
|
|
15
|
+
usage: true,
|
|
16
|
+
mcp: true,
|
|
17
|
+
},
|
|
18
|
+
args: (task) => copilotArgs(task, options),
|
|
19
|
+
prepare: (task) => prepareCopilot(task, options),
|
|
20
|
+
createParser: createCopilotParser,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** Write the task's MCP servers to a private temp file, so header secrets stay out of argv. */
|
|
24
|
+
function prepareCopilot(task, options) {
|
|
25
|
+
if (!task.mcpServers?.length)
|
|
26
|
+
return { args: copilotArgs(task, options) };
|
|
27
|
+
const dir = mkdtempSync(join(tmpdir(), 'genaicode-copilot-mcp-'));
|
|
28
|
+
const file = join(dir, 'mcp.json');
|
|
29
|
+
writeFileSync(file, JSON.stringify(copilotMcpConfig(task.mcpServers)), { mode: 0o600 });
|
|
30
|
+
return {
|
|
31
|
+
args: copilotArgs(task, options, file),
|
|
32
|
+
cleanup: () => rmSync(dir, { recursive: true, force: true }),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** The `--additional-mcp-config` document for a set of servers. */
|
|
36
|
+
export function copilotMcpConfig(servers) {
|
|
37
|
+
const mcpServers = {};
|
|
38
|
+
for (const server of servers) {
|
|
39
|
+
mcpServers[server.name] = isHttpServer(server)
|
|
40
|
+
? { type: 'http', url: server.url, tools: ['*'], ...(server.headers ? { headers: server.headers } : {}) }
|
|
41
|
+
: {
|
|
42
|
+
type: 'local',
|
|
43
|
+
command: server.command,
|
|
44
|
+
args: [...(server.args ?? [])],
|
|
45
|
+
tools: ['*'],
|
|
46
|
+
...(server.env ? { env: server.env } : {}),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return { mcpServers };
|
|
50
|
+
}
|
|
51
|
+
export function copilotArgs(task, options = {}, mcpConfigPath) {
|
|
52
|
+
const args = ['--output-format', 'json'];
|
|
53
|
+
if (options.allowAllTools ?? true)
|
|
54
|
+
args.push('--allow-all-tools');
|
|
55
|
+
// `--allow-tool` and `--deny-tool` take several values; the `=` form keeps each one to a single value.
|
|
56
|
+
const allowed = [
|
|
57
|
+
...(options.allowTools ?? []),
|
|
58
|
+
...(mcpConfigPath && !(options.allowAllTools ?? true) && (options.allowMcpTools ?? true)
|
|
59
|
+
? (task.mcpServers ?? []).map((server) => server.name)
|
|
60
|
+
: []),
|
|
61
|
+
];
|
|
62
|
+
for (const tool of allowed)
|
|
63
|
+
args.push(`--allow-tool=${tool}`);
|
|
64
|
+
for (const tool of options.denyTools ?? [])
|
|
65
|
+
args.push(`--deny-tool=${tool}`);
|
|
66
|
+
if (!options.askUser)
|
|
67
|
+
args.push('--no-ask-user');
|
|
68
|
+
if (mcpConfigPath)
|
|
69
|
+
args.push('--additional-mcp-config', `@${mcpConfigPath}`);
|
|
70
|
+
if (task.model)
|
|
71
|
+
args.push('--model', task.model);
|
|
72
|
+
if (task.effort)
|
|
73
|
+
args.push('--reasoning-effort', task.effort);
|
|
74
|
+
if (task.extraArgs)
|
|
75
|
+
args.push(...task.extraArgs);
|
|
76
|
+
// `--prompt=<text>` keeps a prompt that starts with a dash from reading as a flag.
|
|
77
|
+
return [...args, `--prompt=${task.prompt}`];
|
|
78
|
+
}
|
|
79
|
+
export function createCopilotParser() {
|
|
80
|
+
const toolCalls = new Map();
|
|
81
|
+
const changed = new Set();
|
|
82
|
+
const usage = { outputTokens: 0, reported: false };
|
|
83
|
+
let outcome;
|
|
84
|
+
let sessionSent = false;
|
|
85
|
+
let lastError;
|
|
86
|
+
const session = (sessionId, model) => {
|
|
87
|
+
if (!sessionId || sessionSent)
|
|
88
|
+
return [];
|
|
89
|
+
sessionSent = true;
|
|
90
|
+
return [{ type: 'session', sessionId, ...(model ? { model } : {}) }];
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
outcome: () => outcome,
|
|
94
|
+
event(value) {
|
|
95
|
+
if (!isObject(value))
|
|
96
|
+
return [];
|
|
97
|
+
const data = isObject(value.data) ? value.data : {};
|
|
98
|
+
// Sub-agent traffic carries an envelope `agentId` (older CLIs: `data.parentToolCallId`);
|
|
99
|
+
// the parent's own events cover it.
|
|
100
|
+
const nested = stringField(value, 'agentId') !== undefined || stringField(data, 'parentToolCallId') !== undefined;
|
|
101
|
+
const events = [];
|
|
102
|
+
switch (value.type) {
|
|
103
|
+
case 'session.start':
|
|
104
|
+
case 'session.resume':
|
|
105
|
+
events.push(...session(stringField(data, 'sessionId'), stringField(data, 'selectedModel')));
|
|
106
|
+
break;
|
|
107
|
+
case 'assistant.message_delta': {
|
|
108
|
+
const text = stringField(data, 'deltaContent');
|
|
109
|
+
if (!nested && text)
|
|
110
|
+
events.push({ type: 'text-delta', text });
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case 'assistant.message': {
|
|
114
|
+
const text = stringField(data, 'content');
|
|
115
|
+
if (!nested && text?.trim())
|
|
116
|
+
events.push({ type: 'message', text });
|
|
117
|
+
// JSON output drops `assistant.usage`; each message still carries its output tokens.
|
|
118
|
+
const outputTokens = numberField(data, 'outputTokens');
|
|
119
|
+
if (outputTokens !== undefined) {
|
|
120
|
+
usage.reported = true;
|
|
121
|
+
usage.outputTokens += outputTokens;
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case 'tool.execution_start': {
|
|
126
|
+
const id = stringField(data, 'toolCallId');
|
|
127
|
+
const server = stringField(data, 'mcpServerName');
|
|
128
|
+
const tool = stringField(data, 'mcpToolName');
|
|
129
|
+
const name = server && tool ? `${server}/${tool}` : (stringField(data, 'toolName') ?? 'tool');
|
|
130
|
+
const path = EDIT_TOOLS.has(name) ? stringField(data.arguments, 'path') : undefined;
|
|
131
|
+
if (id)
|
|
132
|
+
toolCalls.set(id, { name, ...(path ? { path } : {}) });
|
|
133
|
+
if (!nested)
|
|
134
|
+
events.push({ type: 'tool-start', ...(id ? { id } : {}), name, input: data.arguments });
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case 'tool.execution_complete': {
|
|
138
|
+
const id = stringField(data, 'toolCallId');
|
|
139
|
+
const call = id ? toolCalls.get(id) : undefined;
|
|
140
|
+
const exitCode = numberField(data.shellExecution, 'exitCode');
|
|
141
|
+
const isError = data.success !== true || (exitCode !== undefined && exitCode !== 0);
|
|
142
|
+
const output = stringField(data.result, 'content') ?? stringField(data.error, 'message');
|
|
143
|
+
if (!nested) {
|
|
144
|
+
events.push({
|
|
145
|
+
type: 'tool-end',
|
|
146
|
+
...(id ? { id } : {}),
|
|
147
|
+
...(call ? { name: call.name } : {}),
|
|
148
|
+
isError,
|
|
149
|
+
...(output !== undefined ? { output } : {}),
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (!isError && call?.path && !changed.has(call.path)) {
|
|
153
|
+
changed.add(call.path);
|
|
154
|
+
events.push({ type: 'file-change', paths: [call.path] });
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case 'session.error': {
|
|
159
|
+
const message = stringField(data, 'message');
|
|
160
|
+
if (message) {
|
|
161
|
+
lastError = message;
|
|
162
|
+
events.push({ type: 'error', message });
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case 'result': {
|
|
167
|
+
events.push(...session(stringField(value, 'sessionId')));
|
|
168
|
+
// Shell commands and patches can modify files no edit tool reported.
|
|
169
|
+
const modified = isObject(value.usage) && isObject(value.usage.codeChanges) ? value.usage.codeChanges : {};
|
|
170
|
+
const paths = Array.isArray(modified.filesModified)
|
|
171
|
+
? modified.filesModified.filter((path) => typeof path === 'string' && !changed.has(path))
|
|
172
|
+
: [];
|
|
173
|
+
if (paths.length) {
|
|
174
|
+
paths.forEach((path) => changed.add(path));
|
|
175
|
+
events.push({ type: 'file-change', paths });
|
|
176
|
+
}
|
|
177
|
+
if (usage.reported)
|
|
178
|
+
events.push({ type: 'usage', usage: { outputTokens: usage.outputTokens } });
|
|
179
|
+
const exitCode = numberField(value, 'exitCode');
|
|
180
|
+
const blocker = stringField(value, 'blocker');
|
|
181
|
+
if (exitCode === 0 && value.outcome !== 'blocked') {
|
|
182
|
+
outcome = { ok: true };
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
const error = (value.outcome === 'blocked' ? `Copilot is blocked${blocker ? `: ${blocker}` : '.'}` : undefined) ??
|
|
186
|
+
lastError ??
|
|
187
|
+
`Copilot exited with code ${exitCode ?? 'unknown'}.`;
|
|
188
|
+
outcome = { ok: false, error };
|
|
189
|
+
if (error !== lastError)
|
|
190
|
+
events.push({ type: 'error', message: error });
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return events;
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=copilot.js.map
|