@hachej/boring-agent 0.1.38 → 0.1.39

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.
@@ -314,6 +314,7 @@ interface RemotePiSessionOptions {
314
314
  };
315
315
  setTimeoutFn?: typeof globalThis.setTimeout;
316
316
  clearTimeoutFn?: typeof globalThis.clearTimeout;
317
+ requestTimeoutMs?: number;
317
318
  }
318
319
  interface RemotePiSessionLargeStateWarning {
319
320
  type: 'large-state';
@@ -358,6 +359,7 @@ declare class RemotePiSession {
358
359
  private readonly storageScope;
359
360
  private readonly setTimeoutFn;
360
361
  private readonly clearTimeoutFn;
362
+ private readonly requestTimeoutMs;
361
363
  private generation;
362
364
  private streamRunId;
363
365
  private reconnectAttempt;
@@ -4441,6 +4441,7 @@ function schedulePiChatReconnect({
4441
4441
  var SUPPORTED_PROTOCOL_VERSION = 1;
4442
4442
  var DEFAULT_RECONNECT_BASE_MS = 1e3;
4443
4443
  var DEFAULT_RECONNECT_MAX_MS = 3e4;
4444
+ var DEFAULT_REQUEST_TIMEOUT_MS = 15e3;
4444
4445
  var DEFAULT_LARGE_STATE_WARNING_BYTES = 5 * 1024 * 1024;
4445
4446
  var DEFAULT_LARGE_STATE_WARNING_MESSAGES = 300;
4446
4447
  var EVENT_TYPE_RING_LIMIT = 20;
@@ -4456,6 +4457,7 @@ var RemotePiSession = class {
4456
4457
  this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
4457
4458
  this.setTimeoutFn = options.setTimeoutFn ?? globalThis.setTimeout;
4458
4459
  this.clearTimeoutFn = options.clearTimeoutFn ?? globalThis.clearTimeout;
4460
+ this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
4459
4461
  this.store = createPiChatStore(createInitialPiChatState({
4460
4462
  sessionId: options.sessionId,
4461
4463
  workspaceId: options.workspaceId,
@@ -4471,6 +4473,7 @@ var RemotePiSession = class {
4471
4473
  storageScope;
4472
4474
  setTimeoutFn;
4473
4475
  clearTimeoutFn;
4476
+ requestTimeoutMs;
4474
4477
  generation = 0;
4475
4478
  streamRunId = 0;
4476
4479
  reconnectAttempt = 0;
@@ -4631,9 +4634,21 @@ var RemotePiSession = class {
4631
4634
  opened = true;
4632
4635
  onOpen?.();
4633
4636
  };
4637
+ let connectTimedOut = false;
4638
+ let connectTimer = globalThis.setTimeout(() => {
4639
+ connectTimedOut = true;
4640
+ controller.abort();
4641
+ }, this.requestTimeoutMs);
4642
+ const clearConnectTimer = () => {
4643
+ if (connectTimer !== void 0) {
4644
+ globalThis.clearTimeout(connectTimer);
4645
+ connectTimer = void 0;
4646
+ }
4647
+ };
4634
4648
  try {
4635
4649
  const headers = await this.requestHeaders();
4636
4650
  if (!this.isStreamActive(generation, runId)) {
4651
+ clearConnectTimer();
4637
4652
  markOpen();
4638
4653
  return;
4639
4654
  }
@@ -4642,6 +4657,7 @@ var RemotePiSession = class {
4642
4657
  headers,
4643
4658
  signal: controller.signal
4644
4659
  });
4660
+ clearConnectTimer();
4645
4661
  if (!this.isStreamActive(generation, runId)) {
4646
4662
  markOpen();
4647
4663
  return;
@@ -4699,10 +4715,14 @@ var RemotePiSession = class {
4699
4715
  this.scheduleReconnect(generation);
4700
4716
  }
4701
4717
  } catch (error) {
4718
+ clearConnectTimer();
4702
4719
  markOpen();
4703
- if (!this.isStreamActive(generation, runId) || shouldIgnoreStreamClose(error, controller)) return;
4704
- this.dispatchProtocolError(errorMessage(error, "Pi chat event stream disconnected."));
4720
+ if (!this.isStreamActive(generation, runId)) return;
4721
+ if (!connectTimedOut && shouldIgnoreStreamClose(error, controller)) return;
4722
+ this.dispatchProtocolError(connectTimedOut ? `Pi chat event stream timed out after ${this.requestTimeoutMs}ms.` : errorMessage(error, "Pi chat event stream disconnected."));
4705
4723
  this.scheduleReconnect(generation);
4724
+ } finally {
4725
+ clearConnectTimer();
4706
4726
  }
4707
4727
  }
4708
4728
  rehydrateAfterStreamReset(generation, options = {}) {
@@ -4755,12 +4775,21 @@ var RemotePiSession = class {
4755
4775
  async fetchJson(url, init) {
4756
4776
  const controller = new AbortController();
4757
4777
  this.fetchControllers.add(controller);
4778
+ let timedOut = false;
4779
+ const timer = globalThis.setTimeout(() => {
4780
+ timedOut = true;
4781
+ controller.abort();
4782
+ }, this.requestTimeoutMs);
4758
4783
  try {
4759
4784
  const response = await this.fetchImpl(url, { ...init, signal: controller.signal });
4760
4785
  const body = await safeReadJson(response);
4761
4786
  if (!response.ok) throw new RemotePiSessionHttpError(response.status, routeErrorMessage(body, `HTTP ${response.status}`), body);
4762
4787
  return body;
4788
+ } catch (error) {
4789
+ if (timedOut) throw new Error(`Request to ${url} timed out after ${this.requestTimeoutMs}ms.`);
4790
+ throw error;
4763
4791
  } finally {
4792
+ globalThis.clearTimeout(timer);
4764
4793
  this.fetchControllers.delete(controller);
4765
4794
  }
4766
4795
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-agent",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Pane-embeddable coding agent. Ships direct/local/vercel-sandbox execution modes behind one interface.",
@@ -74,7 +74,7 @@
74
74
  "use-stick-to-bottom": "^1.1.3",
75
75
  "yaml": "^2.8.3",
76
76
  "zod": "^3.25.76",
77
- "@hachej/boring-ui-kit": "0.1.38"
77
+ "@hachej/boring-ui-kit": "0.1.39"
78
78
  },
79
79
  "devDependencies": {
80
80
  "@antithesishq/bombadil": "0.5.0",