@bivy/bivy 0.16.20-staging.4 → 0.16.20-staging.6
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.
|
@@ -313,13 +313,44 @@ export function claudeStreamJsonParser() {
|
|
|
313
313
|
* codex-cli 0.142): a thread with turns, each turn a stream of typed items.
|
|
314
314
|
* {"type":"thread.started","thread_id":…}
|
|
315
315
|
* {"type":"turn.started"} / {"type":"turn.completed"} / {"type":"turn.failed","error":{message}}
|
|
316
|
+
* {"type":"item.started","item":{…}} ← a shell/patch/MCP call begins (live card)
|
|
316
317
|
* {"type":"item.completed","item":{"id":…,"type":"agent_message"|"reasoning"|
|
|
317
|
-
* "command_execution"|"mcp_tool_call"|"file_change"|"error", …}}
|
|
318
|
+
* "command_execution"|"mcp_tool_call"|"file_change"|"error", "status":…, …}}
|
|
318
319
|
* {"type":"error","message":…} ← transient reconnect noise (non-fatal)
|
|
320
|
+
* A `file_change`/`command_execution` item carries a terminal `status`
|
|
321
|
+
* (`completed`|`failed`); a `failed` one is surfaced as an errored tool result
|
|
322
|
+
* rather than a silent success (mirrors the governed app-server shim).
|
|
319
323
|
*/
|
|
320
324
|
export function codexJsonParser() {
|
|
321
325
|
const acc = new TurnAccumulator({ provider: "codex", protocol: "structured-pipe" });
|
|
322
326
|
let sessionRef;
|
|
327
|
+
// Tool ids already surfaced as a running card, so `item.started` (live) and the
|
|
328
|
+
// later `item.completed` (terminal) render one card per call, not two.
|
|
329
|
+
const startedTools = new Set();
|
|
330
|
+
const ensureToolUse = (id, name, input, events) => {
|
|
331
|
+
if (id && startedTools.has(id))
|
|
332
|
+
return;
|
|
333
|
+
if (id)
|
|
334
|
+
startedTools.add(id);
|
|
335
|
+
acc.addToolUse(id, name, input, events);
|
|
336
|
+
};
|
|
337
|
+
// A tool item begins. Codex emits `item.started` for shell/patch/MCP calls
|
|
338
|
+
// before the matching `item.completed`, so surfacing it shows a long-running
|
|
339
|
+
// command or patch as a live "running" card instead of nothing until it ends.
|
|
340
|
+
const handleStarted = (item, events) => {
|
|
341
|
+
const id = String(item.id ?? "");
|
|
342
|
+
switch (String(item.type ?? "")) {
|
|
343
|
+
case "command_execution":
|
|
344
|
+
ensureToolUse(id, "shell", { command: item.command ?? "" }, events);
|
|
345
|
+
break;
|
|
346
|
+
case "file_change":
|
|
347
|
+
ensureToolUse(id, "apply_patch", { changes: item.changes ?? item }, events);
|
|
348
|
+
break;
|
|
349
|
+
case "mcp_tool_call":
|
|
350
|
+
ensureToolUse(id, String(item.tool ?? item.server ?? "mcp"), item.arguments ?? item.input, events);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
};
|
|
323
354
|
const handleItem = (item, events) => {
|
|
324
355
|
const id = String(item.id ?? "");
|
|
325
356
|
switch (String(item.type ?? "")) {
|
|
@@ -327,19 +358,27 @@ export function codexJsonParser() {
|
|
|
327
358
|
acc.appendText(String(item.text ?? ""), events);
|
|
328
359
|
break;
|
|
329
360
|
case "command_execution":
|
|
330
|
-
|
|
331
|
-
if (item.aggregated_output != null || item.exit_code != null) {
|
|
332
|
-
acc.addToolResult(id, "shell", { content: item.aggregated_output ?? "", exitCode: item.exit_code }, events, Number(item.exit_code) !== 0);
|
|
361
|
+
ensureToolUse(id, "shell", { command: item.command ?? "" }, events);
|
|
362
|
+
if (item.aggregated_output != null || item.exit_code != null || item.status != null) {
|
|
363
|
+
acc.addToolResult(id, "shell", { content: item.aggregated_output ?? "", exitCode: item.exit_code }, events, Number(item.exit_code) !== 0 || item.status === "failed");
|
|
333
364
|
}
|
|
334
365
|
break;
|
|
335
366
|
case "mcp_tool_call":
|
|
336
|
-
|
|
337
|
-
if (item.result != null)
|
|
338
|
-
acc.addToolResult(id, String(item.tool ?? "mcp"), item.result, events);
|
|
367
|
+
ensureToolUse(id, String(item.tool ?? item.server ?? "mcp"), item.arguments ?? item.input, events);
|
|
368
|
+
if (item.result != null || item.error != null || item.status != null) {
|
|
369
|
+
acc.addToolResult(id, String(item.tool ?? "mcp"), item.result ?? item.error ?? item.status, events, item.error != null || item.status === "failed");
|
|
370
|
+
}
|
|
339
371
|
break;
|
|
340
|
-
case "file_change":
|
|
341
|
-
|
|
372
|
+
case "file_change": {
|
|
373
|
+
ensureToolUse(id, "apply_patch", { changes: item.changes ?? item }, events);
|
|
374
|
+
// `file_change` is terminal in `exec --json` (no separate result event),
|
|
375
|
+
// so close the card with a result reflecting its status. Without this a
|
|
376
|
+
// completed patch hangs as "running" and — worse — a FAILED patch renders
|
|
377
|
+
// as a successful edit. Mirrors the app-server shim's handling.
|
|
378
|
+
const status = String(item.status ?? "completed");
|
|
379
|
+
acc.addToolResult(id, "apply_patch", status, events, status === "failed");
|
|
342
380
|
break;
|
|
381
|
+
}
|
|
343
382
|
case "reasoning": {
|
|
344
383
|
// Codex reasoning items carry either `text` or a `summary` (string or an
|
|
345
384
|
// array of {text}) — surface whichever is present as a thinking stream.
|
|
@@ -380,6 +419,10 @@ export function codexJsonParser() {
|
|
|
380
419
|
case "turn.started":
|
|
381
420
|
events.push({ type: "turn_start" });
|
|
382
421
|
break;
|
|
422
|
+
case "item.started":
|
|
423
|
+
if (msg.item && typeof msg.item === "object")
|
|
424
|
+
handleStarted(msg.item, events);
|
|
425
|
+
break;
|
|
383
426
|
case "item.completed":
|
|
384
427
|
if (msg.item && typeof msg.item === "object")
|
|
385
428
|
handleItem(msg.item, events);
|
|
@@ -116,13 +116,21 @@ export function mapToolCall(toolName, input, context = {}) {
|
|
|
116
116
|
}
|
|
117
117
|
if (inToolSet(EDIT, toolName, key)) {
|
|
118
118
|
let path = str(o, ...PATH_KEYS);
|
|
119
|
-
// Codex `apply_patch`/`file_change` carries a `changes`
|
|
119
|
+
// Codex `apply_patch`/`file_change` carries a `changes` collection. The
|
|
120
|
+
// app-server keys it by path (a map); `codex exec --json` sends an array of
|
|
121
|
+
// `{path, kind}` entries. Derive the first touched path from either shape so
|
|
122
|
+
// the patch renders as an edit card instead of an opaque blob.
|
|
120
123
|
if (!path) {
|
|
121
124
|
const changes = o.changes;
|
|
122
|
-
if (
|
|
123
|
-
const first =
|
|
125
|
+
if (Array.isArray(changes)) {
|
|
126
|
+
const first = changes.find((c) => !!c && typeof c === "object" && !Array.isArray(c));
|
|
124
127
|
if (first)
|
|
125
|
-
path = first;
|
|
128
|
+
path = str(first, ...PATH_KEYS);
|
|
129
|
+
}
|
|
130
|
+
else if (changes && typeof changes === "object") {
|
|
131
|
+
const firstKey = Object.keys(changes)[0];
|
|
132
|
+
if (firstKey)
|
|
133
|
+
path = firstKey;
|
|
126
134
|
}
|
|
127
135
|
}
|
|
128
136
|
if (!path)
|
package/package.json
CHANGED