@bubblebrain-ai/bubble 0.0.39 → 0.0.40

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/dist/main.js CHANGED
@@ -834,7 +834,10 @@ async function readPipedStdin() {
834
834
  }
835
835
  main()
836
836
  .then(() => {
837
- void exitAfterFlush(0);
837
+ // Preserve an exit code set by a handled failure path (e.g. print-mode
838
+ // agent errors set exitCode = 1 and return normally) — exit(0) here
839
+ // would silently override it.
840
+ void exitAfterFlush(typeof process.exitCode === "number" ? process.exitCode : 0);
838
841
  })
839
842
  .catch((err) => {
840
843
  console.error(chalk.red(`Fatal error: ${err.message}`));
package/dist/provider.js CHANGED
@@ -15,6 +15,7 @@ import { createProviderProtocolArtifactFilter } from "./provider-artifacts.js";
15
15
  import { resolveProviderRequestConfig } from "./provider-transform.js";
16
16
  import { debugReasoningStream, summarizeDebugText } from "./reasoning-debug.js";
17
17
  import { RateLimitError } from "./network/errors.js";
18
+ import { ProviderStreamInterruptedError } from "./network/retry.js";
18
19
  // Diagnostic logger for tool-args byte-loss investigation. Activate with
19
20
  // BUBBLE_DEBUG_TOOL_ARGS=/path/to/log.jsonl (any writable path)
20
21
  // Each line is a JSON record describing a transition. When debugging is off,
@@ -188,13 +189,24 @@ export function createProviderInstance(options) {
188
189
  // surfaces a final 429 as a typed RateLimitError instead of a string.
189
190
  let stream;
190
191
  stream = (await createCompletion(body));
191
- yield* translateOpenAIStream(stream, {
192
- toolArgsMergeMode: resolveToolArgsMergeMode(options.providerId || "", options.baseURL),
193
- reasoningMergeMode: resolveReasoningMergeMode(options.providerId || "", options.baseURL),
194
- textMergeMode: resolveTextMergeMode(options.providerId || "", options.baseURL),
195
- debugProviderId: options.providerId || "",
196
- debugModelId: chatOptions.model,
197
- });
192
+ // A socket drop while iterating the SSE stream must surface as
193
+ // ProviderStreamInterruptedError so the agent loop re-issues the request;
194
+ // a raw network error here aborts the whole run (anthropic/codex/ai-sdk
195
+ // paths already wrap — this generic chat-completions path did not).
196
+ try {
197
+ yield* translateOpenAIStream(stream, {
198
+ toolArgsMergeMode: resolveToolArgsMergeMode(options.providerId || "", options.baseURL),
199
+ reasoningMergeMode: resolveReasoningMergeMode(options.providerId || "", options.baseURL),
200
+ textMergeMode: resolveTextMergeMode(options.providerId || "", options.baseURL),
201
+ debugProviderId: options.providerId || "",
202
+ debugModelId: chatOptions.model,
203
+ });
204
+ }
205
+ catch (error) {
206
+ if (chatOptions.abortSignal?.aborted)
207
+ throw error;
208
+ throw new ProviderStreamInterruptedError(`Provider stream interrupted: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
209
+ }
198
210
  yield { type: "done" };
199
211
  }
200
212
  async function complete(messages, chatOptions) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bubblebrain-ai/bubble",
3
- "version": "0.0.39",
3
+ "version": "0.0.40",
4
4
  "description": "A terminal coding agent",
5
5
  "type": "module",
6
6
  "engines": {