@bivy/bivy 0.18.9-staging.5 → 0.18.9-staging.7

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.
@@ -298,6 +298,9 @@ function extractText(message) {
298
298
  * handled separately (see INTERRUPT_MARKER) because — unlike these — they carry
299
299
  * meaning a human wants to see. */
300
300
  const DROP_META_TEXT = /^\s*<(?:task-notification|system-reminder)[\s>/]/;
301
+ /** Re-drives a self-woken turn after a credential reload (see recoverFromAuthError).
302
+ * Wrapped as a system-reminder so DROP_META_TEXT keeps it out of the chat. */
303
+ const AUTH_RECOVERY_CONTINUE = "<system-reminder>Your last request failed because the sign-in expired; it has been refreshed. Continue exactly where you left off.</system-reminder>";
301
304
  /** The CLI writes this synthetic user-role marker whenever a turn is aborted —
302
305
  * by a real user Stop OR by any teardown of the streaming query (our shutdown,
303
306
  * a mid-flight credential reload, a TUI refresh). We don't drop it: we surface
@@ -1073,15 +1076,19 @@ class ClaudeSession {
1073
1076
  /** Recover a provider 401 regardless of whether the SDK throws it, emits it as
1074
1077
  * assistant text, or puts it in an error result. The latter is how revoked
1075
1078
  * OAuth tokens commonly arrive, so only handling consume()'s catch would leave
1076
- * the turn stopped until the user sent another message. */
1079
+ * the turn stopped until the user sent another message.
1080
+ *
1081
+ * A turn the agent woke into on its own (a background task's notification,
1082
+ * with no user prompt in flight) recovers too: its trigger lived in the torn-down
1083
+ * query, so the resumed one is nudged with a hidden continuation instead. */
1077
1084
  async recoverFromAuthError(raw) {
1078
- if (!isAnthropicAuthError(raw) || this.reloadedThisTurn || this.inFlightPrompt === undefined)
1085
+ if (!isAnthropicAuthError(raw) || this.reloadedThisTurn)
1079
1086
  return false;
1080
1087
  this.reloadedThisTurn = true;
1081
1088
  if (!(await this.restartWithFreshCredential(this.spawnedToken)))
1082
1089
  return false;
1083
1090
  this.streaming = true;
1084
- this.input.push({ type: "user", message: { role: "user", content: this.inFlightPrompt }, parent_tool_use_id: null });
1091
+ this.input.push({ type: "user", message: { role: "user", content: this.inFlightPrompt ?? AUTH_RECOVERY_CONTINUE }, parent_tool_use_id: null });
1085
1092
  return true;
1086
1093
  }
1087
1094
  beginMessage() {
@@ -1270,6 +1277,11 @@ class ClaudeSession {
1270
1277
  // Turn completed — the prompt is on disk now, so drop the copy kept for a
1271
1278
  // mid-flight reload re-drive (see inFlightPrompt / consume's catch).
1272
1279
  this.inFlightPrompt = undefined;
1280
+ // Re-arm the one-reload-per-turn guard only after a clean turn, so the
1281
+ // next (possibly self-woken) turn can recover, while a failed turn that
1282
+ // already reloaded surfaces its error instead of looping.
1283
+ if (!resultError)
1284
+ this.reloadedThisTurn = false;
1273
1285
  if (message.subtype && message.subtype !== "success") {
1274
1286
  this.emit({ type: "tool_result", error: message.subtype, message: message.result });
1275
1287
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.18.9-staging.5",
3
+ "version": "0.18.9-staging.7",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",
@@ -51,7 +51,7 @@
51
51
  "zod": "^4.6.5"
52
52
  },
53
53
  "overrides": {
54
- "fast-uri": "3.1.6",
54
+ "fast-uri": "3.1.8",
55
55
  "hono": "4.13.5",
56
56
  "qs": "6.16.0",
57
57
  "@hono/node-server": "2.0.12",