antechamber 1.0.25 → 1.0.26
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
CHANGED
|
@@ -7,6 +7,15 @@ and this project uses [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.26] - 2026-10-28
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Stop showing "Opencode failed to send message" for a provider error that OmO retries on its own, such as
|
|
15
|
+
Anthropic's 400 for a `web_search` tool use with no `web_search_tool_result`, which OmO retries without web search
|
|
16
|
+
replay data. The errored reply now waits for OmO's retry decision: a retried step completes without the error and
|
|
17
|
+
v2 no longer reports `session.step.failed`. An error that is not retried still fails the message, step and run.
|
|
18
|
+
|
|
10
19
|
## [1.0.25] - 2026-10-27
|
|
11
20
|
|
|
12
21
|
### Added
|
|
@@ -57,6 +57,11 @@ export declare class PiEventTranslator {
|
|
|
57
57
|
private services;
|
|
58
58
|
/** Ended assistant messages whose completion waits on their tools. */
|
|
59
59
|
private awaitingTools;
|
|
60
|
+
/**
|
|
61
|
+
* Errored assistant messages held open until agent_end says whether OmO retries them. OpenChamber prints a
|
|
62
|
+
* completed message's error as "failed to send message", and v2 cannot retract a `session.step.failed`.
|
|
63
|
+
*/
|
|
64
|
+
private heldFailures;
|
|
60
65
|
constructor(services: PiEventServices);
|
|
61
66
|
/** Close dead-runtime UI state before an error or idle event can reach the client. */
|
|
62
67
|
finishInterruptedRun(s: ManagedSession, error: NonNullable<OCAssistantMessage["error"]>): void;
|
|
@@ -93,6 +98,8 @@ export declare class PiEventTranslator {
|
|
|
93
98
|
private completeSettled;
|
|
94
99
|
/** Tool parts that never received a result (abort, crash) must not spin forever. */
|
|
95
100
|
private finalizeDanglingTools;
|
|
101
|
+
/** Complete held errored messages: with their error when the run failed, without it when OmO retries the step. */
|
|
102
|
+
private completeHeldFailures;
|
|
96
103
|
/** Complete every ended message of this session still waiting on its tools. */
|
|
97
104
|
private completeAwaitingTools;
|
|
98
105
|
}
|
|
@@ -168,6 +168,11 @@ export class PiEventTranslator {
|
|
|
168
168
|
services;
|
|
169
169
|
/** Ended assistant messages whose completion waits on their tools. */
|
|
170
170
|
awaitingTools = new WeakSet();
|
|
171
|
+
/**
|
|
172
|
+
* Errored assistant messages held open until agent_end says whether OmO retries them. OpenChamber prints a
|
|
173
|
+
* completed message's error as "failed to send message", and v2 cannot retract a `session.step.failed`.
|
|
174
|
+
*/
|
|
175
|
+
heldFailures = new WeakMap();
|
|
171
176
|
constructor(services) {
|
|
172
177
|
this.services = services;
|
|
173
178
|
}
|
|
@@ -394,8 +399,11 @@ export class PiEventTranslator {
|
|
|
394
399
|
this.setStatus(s, { type: "busy" });
|
|
395
400
|
return;
|
|
396
401
|
case "agent_end":
|
|
397
|
-
if (ev.willRetry === true)
|
|
398
|
-
|
|
402
|
+
if (ev.willRetry === true) {
|
|
403
|
+
// auto-retry keeps the session busy, and the failed step it retries is not a failure to report.
|
|
404
|
+
this.completeHeldFailures(s, false);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
399
407
|
if (s.interruptRequested)
|
|
400
408
|
this.finishInterruptedRun(s, { name: "MessageAbortedError", data: { message: "Cancelled" } });
|
|
401
409
|
s.approvals?.finishTurn();
|
|
@@ -599,15 +607,19 @@ export class PiEventTranslator {
|
|
|
599
607
|
s.streaming.message.modelID = s.model.modelID;
|
|
600
608
|
}
|
|
601
609
|
applyUsage(s.streaming.message, ended.usage);
|
|
602
|
-
|
|
610
|
+
const stop = piStopReason(ended.stopReason, ended.errorMessage);
|
|
611
|
+
if (ended.stopReason === "error")
|
|
612
|
+
this.heldFailures.set(s.streaming.message, stop);
|
|
613
|
+
else
|
|
614
|
+
Object.assign(s.streaming.message, stop);
|
|
603
615
|
// OpenCode completes an assistant message only after its tools settle, and
|
|
604
616
|
// OpenChamber marks active tools under a completed message as Interrupted.
|
|
605
617
|
// pi ends a toolUse message before executing its tool calls, so defer its
|
|
606
618
|
// completion to the last tool result (applyToolResults), the next step, or
|
|
607
|
-
// the run end. Errored/aborted messages never run their tools.
|
|
619
|
+
// the run end. Errored/aborted messages never run their tools; an errored one completes at agent_end.
|
|
608
620
|
if (ended.stopReason === "toolUse" && hasActiveTools(s, s.streaming.message.id))
|
|
609
621
|
this.awaitingTools.add(s.streaming.message);
|
|
610
|
-
else
|
|
622
|
+
else if (ended.stopReason !== "error")
|
|
611
623
|
s.streaming.message.time.completed = Date.now();
|
|
612
624
|
this.services.emit(s.info.directory, { type: "message.updated", properties: { info: s.streaming.message } });
|
|
613
625
|
this.finishStreaming(s);
|
|
@@ -968,8 +980,23 @@ export class PiEventTranslator {
|
|
|
968
980
|
s.toolByCallId.clear();
|
|
969
981
|
this.completeAwaitingTools(s); // the run is over
|
|
970
982
|
}
|
|
983
|
+
/** Complete held errored messages: with their error when the run failed, without it when OmO retries the step. */
|
|
984
|
+
completeHeldFailures(s, failed) {
|
|
985
|
+
const now = Date.now();
|
|
986
|
+
for (const { info } of s.messages ?? []) {
|
|
987
|
+
const stop = this.heldFailures.get(info);
|
|
988
|
+
if (stop === undefined || info.role !== "assistant")
|
|
989
|
+
continue;
|
|
990
|
+
this.heldFailures.delete(info);
|
|
991
|
+
if (failed)
|
|
992
|
+
Object.assign(info, stop);
|
|
993
|
+
info.time.completed = now;
|
|
994
|
+
this.services.emit(s.info.directory, { type: "message.updated", properties: { info } });
|
|
995
|
+
}
|
|
996
|
+
}
|
|
971
997
|
/** Complete every ended message of this session still waiting on its tools. */
|
|
972
998
|
completeAwaitingTools(s) {
|
|
999
|
+
this.completeHeldFailures(s, true);
|
|
973
1000
|
const now = Date.now();
|
|
974
1001
|
for (const { info } of s.messages ?? []) {
|
|
975
1002
|
if (!this.awaitingTools.has(info) || info.role !== "assistant")
|