@bivy/bivy 0.16.25-staging.21 → 0.16.25-staging.23
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/bin/acp-shim.mjs +7 -0
- package/bin/codex-app-server-shim.mjs +10 -0
- package/dist/runtime/protocol.js +32 -2
- package/package.json +1 -1
package/bin/acp-shim.mjs
CHANGED
|
@@ -313,6 +313,13 @@ function onSessionUpdate(params) {
|
|
|
313
313
|
if (!content) return "";
|
|
314
314
|
if (typeof content === "string") return content;
|
|
315
315
|
if (Array.isArray(content)) return content.map(textOf).join("");
|
|
316
|
+
// ACP's ToolCallContent wraps a ContentBlock: `{ type: "content", content:
|
|
317
|
+
// { type: "text", text } }`. Unwrap it (recursively) so a tool's real output
|
|
318
|
+
// — a command's stdout, a fetched document, a read's text — isn't dropped,
|
|
319
|
+
// which collapsed the tool_result to the bare status ("completed"). opencode
|
|
320
|
+
// and most spec-compliant ACP agents deliver tool output in this wrapped
|
|
321
|
+
// shape, so reading only the bare `{type:"text"}` form lost it in production.
|
|
322
|
+
if (content.type === "content" && content.content != null) return textOf(content.content);
|
|
316
323
|
if (content.type === "text" && typeof content.text === "string") return content.text;
|
|
317
324
|
if (typeof content.text === "string") return content.text;
|
|
318
325
|
return "";
|
|
@@ -415,6 +415,16 @@ function onNotification(m) {
|
|
|
415
415
|
bivy({ type: "session.status", status: "working" });
|
|
416
416
|
return;
|
|
417
417
|
case "turn/completed": {
|
|
418
|
+
// The completion event is authoritative about a terminal failure: a turn
|
|
419
|
+
// that hit a usage limit (or any provider error) arrives here as
|
|
420
|
+
// `status: "failed"` carrying `turn.error`. Capture it directly instead of
|
|
421
|
+
// depending on a separate `error` notification landing first — otherwise a
|
|
422
|
+
// completion that omits that notification seals as session.done and the
|
|
423
|
+
// user sees a silent empty turn (fail loud, never swallow the error).
|
|
424
|
+
const turnError =
|
|
425
|
+
params?.turn?.error?.message ||
|
|
426
|
+
(params?.turn?.status === "failed" ? params?.error?.message || params?.message || "Codex turn failed" : undefined);
|
|
427
|
+
if (turnError && !sawError) sawError = turnError;
|
|
418
428
|
// Codex 0.147 can publish turn/completed just before the final
|
|
419
429
|
// collabAgentToolCall item/completed notification. Sealing immediately
|
|
420
430
|
// leaves the sub-agent card running forever and drops its persisted
|
package/dist/runtime/protocol.js
CHANGED
|
@@ -711,14 +711,41 @@ class ProtocolSession {
|
|
|
711
711
|
return;
|
|
712
712
|
}
|
|
713
713
|
if (type === "session.error") {
|
|
714
|
+
const errorText = String(msg.error || "Protocol agent error");
|
|
715
|
+
// Preserve whatever the failed turn already streamed — a partial assistant
|
|
716
|
+
// reply and its tool calls/results — persisted exactly as session.done
|
|
717
|
+
// persists a clean turn. The old handler wiped turnContent here, so a mid-
|
|
718
|
+
// turn failure dropped all of that work from the reopened transcript.
|
|
719
|
+
const hadTools = this.turnContent.length > 0 || this.turnToolResults.length > 0;
|
|
720
|
+
if (hadTools) {
|
|
721
|
+
this.flushPendingTurnText();
|
|
722
|
+
if (this.turnContent.length)
|
|
723
|
+
this.messages.push({ role: "assistant", content: this.turnContent, timestamp: Date.now() });
|
|
724
|
+
if (this.turnToolResults.length)
|
|
725
|
+
this.messages.push({ role: "user", content: this.turnToolResults, timestamp: Date.now() });
|
|
726
|
+
}
|
|
727
|
+
else if (this.assistantText) {
|
|
728
|
+
this.messages.push({ role: "assistant", content: this.assistantText, timestamp: Date.now() });
|
|
729
|
+
}
|
|
730
|
+
// Append a terminal error marker in the shape store-render + terminalTurnError
|
|
731
|
+
// recognize (stopReason "error" + errorMessage), so the failure itself
|
|
732
|
+
// survives a reload as an inline error instead of the turn reopening blank
|
|
733
|
+
// ("looks done, no reply"). Matches the live session.error emitted just below.
|
|
734
|
+
const errored = { role: "assistant", content: "", stopReason: "error", errorMessage: errorText, timestamp: Date.now() };
|
|
735
|
+
this.messages.push(errored);
|
|
714
736
|
this.streaming = false;
|
|
737
|
+
this.assistantText = "";
|
|
738
|
+
this.assistantItemBoundary = false;
|
|
715
739
|
this.reasoningText = "";
|
|
716
740
|
this.turnContent = [];
|
|
717
741
|
this.turnTextFlushed = "";
|
|
718
742
|
this.turnToolResults = [];
|
|
719
743
|
this.toolDetailsByCallId.clear();
|
|
720
744
|
this.openToolIds = [];
|
|
721
|
-
|
|
745
|
+
// message_end drives the daemon's base-transcript snapshot (agent_end does
|
|
746
|
+
// not), so the preserved content + error marker are durably persisted.
|
|
747
|
+
this.emit({ type: "message_end", message: errored });
|
|
748
|
+
this.emit({ type: "session.error", error: errorText });
|
|
722
749
|
this.emit({ type: "agent_end" });
|
|
723
750
|
return;
|
|
724
751
|
}
|
|
@@ -872,7 +899,10 @@ class ProtocolSession {
|
|
|
872
899
|
const preflightError = await this.preparePreflight();
|
|
873
900
|
if (preflightError) {
|
|
874
901
|
this.streaming = false;
|
|
875
|
-
|
|
902
|
+
// stopReason "error" is what store-render keys on to re-render this as an
|
|
903
|
+
// inline error on reload (without it the turn reopened blank); it also
|
|
904
|
+
// matches the terminal-error message shape every other failure path uses.
|
|
905
|
+
const message = { role: "assistant", content: "", stopReason: "error", errorMessage: preflightError };
|
|
876
906
|
this.messages.push(message);
|
|
877
907
|
this.emit({ type: "message_start", message: { role: "assistant", content: "" } });
|
|
878
908
|
this.emit({ type: "session.error", error: preflightError });
|
package/package.json
CHANGED