@arbidocs/sdk 0.3.75 → 0.3.77

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.
@@ -445,6 +445,16 @@ declare const consumeSSEStream: typeof streamSSE;
445
445
  * Authenticates via SDK helpers, routes typed messages to the consumer.
446
446
  */
447
447
 
448
+ /**
449
+ * Thrown when a WebSocket connection is rejected for authentication reasons
450
+ * (the server returned `auth_result { success: false }`, or no token was
451
+ * available to send). The reconnect loop uses this to decide whether to
452
+ * re-authenticate before the next attempt, versus treating the failure as a
453
+ * transient network drop.
454
+ */
455
+ declare class WebSocketAuthError extends Error {
456
+ constructor(reason: string);
457
+ }
448
458
  interface WsConnection {
449
459
  close: () => void;
450
460
  }
@@ -455,8 +465,28 @@ interface ConnectOptions {
455
465
  onClose?: (code: number, reason: string) => void;
456
466
  }
457
467
  interface ReconnectOptions extends ConnectOptions {
468
+ /**
469
+ * Max consecutive reconnect attempts after a drop before giving up and
470
+ * calling `onReconnectFailed`. Pass `Infinity` for an unattended daemon that
471
+ * must keep trying indefinitely (backoff still caps at {@link MAX_BACKOFF_MS}).
472
+ * Default 10.
473
+ */
458
474
  maxRetries?: number;
459
475
  initialDelayMs?: number;
476
+ /**
477
+ * Resolve the access token before each (re)connect attempt. Defaults to the
478
+ * static `accessToken`. Provide this so a token refreshed elsewhere (e.g. by
479
+ * auto-relogin on a REST 401) is picked up on reconnect instead of reusing a
480
+ * stale token captured when the listener first started.
481
+ */
482
+ getAccessToken?: () => string | null | Promise<string | null>;
483
+ /**
484
+ * Re-authenticate when a reconnect attempt is rejected for auth reasons
485
+ * (expired/invalid token — see {@link WebSocketAuthError}). Should refresh the
486
+ * token in whatever store `getAccessToken` reads from; the return value is
487
+ * ignored. Best-effort: errors are swallowed and normal backoff continues.
488
+ */
489
+ refreshAuth?: () => Promise<string | null>;
460
490
  onReconnecting?: (attempt: number, maxRetries: number) => void;
461
491
  onReconnected?: () => void;
462
492
  onReconnectFailed?: () => void;
@@ -475,7 +505,15 @@ declare function connectWebSocket(options: ConnectOptions): Promise<WsConnection
475
505
  * Connect WebSocket with automatic reconnection on disconnect.
476
506
  *
477
507
  * Initial connection throws on failure (same as connectWebSocket).
478
- * After successful auth, disconnects trigger exponential backoff reconnection.
508
+ * After successful auth, disconnects trigger exponential backoff reconnection:
509
+ * - a fresh token is resolved before every attempt (see `getAccessToken`), so a
510
+ * token rotated elsewhere is picked up rather than reusing a stale one;
511
+ * - an attempt rejected for auth reasons triggers `refreshAuth` (re-login) so
512
+ * the next attempt uses a new token;
513
+ * - retries continue up to `maxRetries` (pass `Infinity` for a daemon that must
514
+ * never give up). Only after exhausting a finite limit is `onReconnectFailed`
515
+ * called.
516
+ *
479
517
  * Call close() on the returned handle to stop reconnection attempts.
480
518
  */
481
519
  declare function connectWithReconnect(options: ReconnectOptions): Promise<ReconnectableWsConnection>;
@@ -2615,6 +2653,7 @@ declare class Arbi {
2615
2653
  show_agent_sessions: boolean;
2616
2654
  show_mcp_connectors: boolean;
2617
2655
  show_hints: boolean;
2656
+ show_chronology: boolean;
2618
2657
  use_s3_direct_upload: boolean;
2619
2658
  hide_online_status: boolean;
2620
2659
  muted_users: string[];
@@ -3951,6 +3990,7 @@ declare function getSettings(arbi: ArbiClient): Promise<{
3951
3990
  show_agent_sessions: boolean;
3952
3991
  show_mcp_connectors: boolean;
3953
3992
  show_hints: boolean;
3993
+ show_chronology: boolean;
3954
3994
  use_s3_direct_upload: boolean;
3955
3995
  hide_online_status: boolean;
3956
3996
  muted_users: string[];
@@ -4364,4 +4404,4 @@ declare namespace responses {
4364
4404
  export { type responses_SubmitBackgroundQueryOptions as SubmitBackgroundQueryOptions, responses_extractResponseText as extractResponseText, responses_getResponse as getResponse, responses_submitBackgroundQuery as submitBackgroundQuery };
4365
4405
  }
4366
4406
 
4367
- export { type UploadOptions as $, type AgentStepEvent as A, type ResponseCreatedEvent as B, type ChatSession as C, DOC_TERMINAL_STATUSES as D, type ResponseFailedEvent as E, type FormattedWsMessage as F, type ResponseOutputItemAddedEvent as G, type ResponseOutputItemDoneEvent as H, type ResponseOutputTextDeltaEvent as I, type ResponseOutputTextDoneEvent as J, type ResponseUsage as K, type ListAllOptions as L, type MessageLevel as M, type SSEStreamCallbacks as N, type OutputTokensDetails as O, type ParsedSlashCommand as P, type QueryOptions as Q, type ReconnectOptions as R, type SSEEvent as S, type SSEStreamResult as T, type SSEStreamStartData as U, SUPPORTED_EXTENSIONS as V, type SkillSummary as W, type SkippedFile as X, type UploadBatchResult as Y, type UploadDirectOptions as Z, type UploadDirectResult as _, Arbi as a, type UploadResult as a0, type UserInfo as a1, type UserInputRequestEvent as a2, type UserMessageEvent as a3, type WorkspaceContext as a4, type WsConnection as a5, agentconfig as a6, assistant as a7, authenticatedFetch as a8, buildRetrievalChunkTool as a9, health as aA, parseSSEEvents as aB, parseSlashCommand as aC, parseSlashTokenInProgress as aD, performPasswordLogin as aE, performSigningKeyLogin as aF, performSsoDeviceFlowLogin as aG, requireData as aH, requireOk as aI, resolveAuth as aJ, resolveCitations as aK, resolveWorkspace as aL, responses as aM, selectWorkspace as aN, selectWorkspaceById as aO, settings as aP, streamSSE as aQ, stripCitationMarkdown as aR, summarizeCitations as aS, tags as aT, workspaces as aU, buildRetrievalFullContextTool as aa, buildRetrievalTocTool as ab, connectWebSocket as ac, connectWithReconnect as ad, consumeSSEStream as ae, contacts as af, conversations as ag, countCitations as ah, createAuthenticatedClient as ai, createDocumentWaiter as aj, dm as ak, doctags as al, documents as am, files as an, filterSkills as ao, formatAgentStepLabel as ap, formatFileSize as aq, formatStreamSummary as ar, formatUserName as as, formatWorkspaceChoices as at, formatWsMessage as au, generateEncryptedWorkspaceKey as av, generateNewWorkspaceKey as aw, getErrorCode as ax, getErrorMessage as ay, getRawWorkspaceKey as az, ArbiApiError as b, ArbiError as c, type ArbiErrorEvent as d, type ArbiOptions as e, type ArtifactEvent as f, type AuthContext as g, type AuthHeaders as h, type AuthenticatedClient as i, type CitationSummary as j, type CliConfig as k, type CliCredentials as l, type ConfigStore as m, type ConnectOptions as n, type DmCryptoContext as o, type DocumentListFields as p, type DocumentListOrder as q, type DocumentWaiter as r, type DocumentWaiterOptions as s, type ListPaginatedOptions as t, type MessageMetadataPayload$1 as u, type MessageQueuedEvent as v, type ReconnectableWsConnection as w, type ResolvedCitation as x, type ResponseCompletedEvent as y, type ResponseContentPartAddedEvent as z };
4407
+ export { type UploadOptions as $, type AgentStepEvent as A, type ResponseCreatedEvent as B, type ChatSession as C, DOC_TERMINAL_STATUSES as D, type ResponseFailedEvent as E, type FormattedWsMessage as F, type ResponseOutputItemAddedEvent as G, type ResponseOutputItemDoneEvent as H, type ResponseOutputTextDeltaEvent as I, type ResponseOutputTextDoneEvent as J, type ResponseUsage as K, type ListAllOptions as L, type MessageLevel as M, type SSEStreamCallbacks as N, type OutputTokensDetails as O, type ParsedSlashCommand as P, type QueryOptions as Q, type ReconnectOptions as R, type SSEEvent as S, type SSEStreamResult as T, type SSEStreamStartData as U, SUPPORTED_EXTENSIONS as V, type SkillSummary as W, type SkippedFile as X, type UploadBatchResult as Y, type UploadDirectOptions as Z, type UploadDirectResult as _, Arbi as a, type UploadResult as a0, type UserInfo as a1, type UserInputRequestEvent as a2, type UserMessageEvent as a3, WebSocketAuthError as a4, type WorkspaceContext as a5, type WsConnection as a6, agentconfig as a7, assistant as a8, authenticatedFetch as a9, getRawWorkspaceKey as aA, health as aB, parseSSEEvents as aC, parseSlashCommand as aD, parseSlashTokenInProgress as aE, performPasswordLogin as aF, performSigningKeyLogin as aG, performSsoDeviceFlowLogin as aH, requireData as aI, requireOk as aJ, resolveAuth as aK, resolveCitations as aL, resolveWorkspace as aM, responses as aN, selectWorkspace as aO, selectWorkspaceById as aP, settings as aQ, streamSSE as aR, stripCitationMarkdown as aS, summarizeCitations as aT, tags as aU, workspaces as aV, buildRetrievalChunkTool as aa, buildRetrievalFullContextTool as ab, buildRetrievalTocTool as ac, connectWebSocket as ad, connectWithReconnect as ae, consumeSSEStream as af, contacts as ag, conversations as ah, countCitations as ai, createAuthenticatedClient as aj, createDocumentWaiter as ak, dm as al, doctags as am, documents as an, files as ao, filterSkills as ap, formatAgentStepLabel as aq, formatFileSize as ar, formatStreamSummary as as, formatUserName as at, formatWorkspaceChoices as au, formatWsMessage as av, generateEncryptedWorkspaceKey as aw, generateNewWorkspaceKey as ax, getErrorCode as ay, getErrorMessage as az, ArbiApiError as b, ArbiError as c, type ArbiErrorEvent as d, type ArbiOptions as e, type ArtifactEvent as f, type AuthContext as g, type AuthHeaders as h, type AuthenticatedClient as i, type CitationSummary as j, type CliConfig as k, type CliCredentials as l, type ConfigStore as m, type ConnectOptions as n, type DmCryptoContext as o, type DocumentListFields as p, type DocumentListOrder as q, type DocumentWaiter as r, type DocumentWaiterOptions as s, type ListPaginatedOptions as t, type MessageMetadataPayload$1 as u, type MessageQueuedEvent as v, type ReconnectableWsConnection as w, type ResolvedCitation as x, type ResponseCompletedEvent as y, type ResponseContentPartAddedEvent as z };
@@ -445,6 +445,16 @@ declare const consumeSSEStream: typeof streamSSE;
445
445
  * Authenticates via SDK helpers, routes typed messages to the consumer.
446
446
  */
447
447
 
448
+ /**
449
+ * Thrown when a WebSocket connection is rejected for authentication reasons
450
+ * (the server returned `auth_result { success: false }`, or no token was
451
+ * available to send). The reconnect loop uses this to decide whether to
452
+ * re-authenticate before the next attempt, versus treating the failure as a
453
+ * transient network drop.
454
+ */
455
+ declare class WebSocketAuthError extends Error {
456
+ constructor(reason: string);
457
+ }
448
458
  interface WsConnection {
449
459
  close: () => void;
450
460
  }
@@ -455,8 +465,28 @@ interface ConnectOptions {
455
465
  onClose?: (code: number, reason: string) => void;
456
466
  }
457
467
  interface ReconnectOptions extends ConnectOptions {
468
+ /**
469
+ * Max consecutive reconnect attempts after a drop before giving up and
470
+ * calling `onReconnectFailed`. Pass `Infinity` for an unattended daemon that
471
+ * must keep trying indefinitely (backoff still caps at {@link MAX_BACKOFF_MS}).
472
+ * Default 10.
473
+ */
458
474
  maxRetries?: number;
459
475
  initialDelayMs?: number;
476
+ /**
477
+ * Resolve the access token before each (re)connect attempt. Defaults to the
478
+ * static `accessToken`. Provide this so a token refreshed elsewhere (e.g. by
479
+ * auto-relogin on a REST 401) is picked up on reconnect instead of reusing a
480
+ * stale token captured when the listener first started.
481
+ */
482
+ getAccessToken?: () => string | null | Promise<string | null>;
483
+ /**
484
+ * Re-authenticate when a reconnect attempt is rejected for auth reasons
485
+ * (expired/invalid token — see {@link WebSocketAuthError}). Should refresh the
486
+ * token in whatever store `getAccessToken` reads from; the return value is
487
+ * ignored. Best-effort: errors are swallowed and normal backoff continues.
488
+ */
489
+ refreshAuth?: () => Promise<string | null>;
460
490
  onReconnecting?: (attempt: number, maxRetries: number) => void;
461
491
  onReconnected?: () => void;
462
492
  onReconnectFailed?: () => void;
@@ -475,7 +505,15 @@ declare function connectWebSocket(options: ConnectOptions): Promise<WsConnection
475
505
  * Connect WebSocket with automatic reconnection on disconnect.
476
506
  *
477
507
  * Initial connection throws on failure (same as connectWebSocket).
478
- * After successful auth, disconnects trigger exponential backoff reconnection.
508
+ * After successful auth, disconnects trigger exponential backoff reconnection:
509
+ * - a fresh token is resolved before every attempt (see `getAccessToken`), so a
510
+ * token rotated elsewhere is picked up rather than reusing a stale one;
511
+ * - an attempt rejected for auth reasons triggers `refreshAuth` (re-login) so
512
+ * the next attempt uses a new token;
513
+ * - retries continue up to `maxRetries` (pass `Infinity` for a daemon that must
514
+ * never give up). Only after exhausting a finite limit is `onReconnectFailed`
515
+ * called.
516
+ *
479
517
  * Call close() on the returned handle to stop reconnection attempts.
480
518
  */
481
519
  declare function connectWithReconnect(options: ReconnectOptions): Promise<ReconnectableWsConnection>;
@@ -2615,6 +2653,7 @@ declare class Arbi {
2615
2653
  show_agent_sessions: boolean;
2616
2654
  show_mcp_connectors: boolean;
2617
2655
  show_hints: boolean;
2656
+ show_chronology: boolean;
2618
2657
  use_s3_direct_upload: boolean;
2619
2658
  hide_online_status: boolean;
2620
2659
  muted_users: string[];
@@ -3951,6 +3990,7 @@ declare function getSettings(arbi: ArbiClient): Promise<{
3951
3990
  show_agent_sessions: boolean;
3952
3991
  show_mcp_connectors: boolean;
3953
3992
  show_hints: boolean;
3993
+ show_chronology: boolean;
3954
3994
  use_s3_direct_upload: boolean;
3955
3995
  hide_online_status: boolean;
3956
3996
  muted_users: string[];
@@ -4364,4 +4404,4 @@ declare namespace responses {
4364
4404
  export { type responses_SubmitBackgroundQueryOptions as SubmitBackgroundQueryOptions, responses_extractResponseText as extractResponseText, responses_getResponse as getResponse, responses_submitBackgroundQuery as submitBackgroundQuery };
4365
4405
  }
4366
4406
 
4367
- export { type UploadOptions as $, type AgentStepEvent as A, type ResponseCreatedEvent as B, type ChatSession as C, DOC_TERMINAL_STATUSES as D, type ResponseFailedEvent as E, type FormattedWsMessage as F, type ResponseOutputItemAddedEvent as G, type ResponseOutputItemDoneEvent as H, type ResponseOutputTextDeltaEvent as I, type ResponseOutputTextDoneEvent as J, type ResponseUsage as K, type ListAllOptions as L, type MessageLevel as M, type SSEStreamCallbacks as N, type OutputTokensDetails as O, type ParsedSlashCommand as P, type QueryOptions as Q, type ReconnectOptions as R, type SSEEvent as S, type SSEStreamResult as T, type SSEStreamStartData as U, SUPPORTED_EXTENSIONS as V, type SkillSummary as W, type SkippedFile as X, type UploadBatchResult as Y, type UploadDirectOptions as Z, type UploadDirectResult as _, Arbi as a, type UploadResult as a0, type UserInfo as a1, type UserInputRequestEvent as a2, type UserMessageEvent as a3, type WorkspaceContext as a4, type WsConnection as a5, agentconfig as a6, assistant as a7, authenticatedFetch as a8, buildRetrievalChunkTool as a9, health as aA, parseSSEEvents as aB, parseSlashCommand as aC, parseSlashTokenInProgress as aD, performPasswordLogin as aE, performSigningKeyLogin as aF, performSsoDeviceFlowLogin as aG, requireData as aH, requireOk as aI, resolveAuth as aJ, resolveCitations as aK, resolveWorkspace as aL, responses as aM, selectWorkspace as aN, selectWorkspaceById as aO, settings as aP, streamSSE as aQ, stripCitationMarkdown as aR, summarizeCitations as aS, tags as aT, workspaces as aU, buildRetrievalFullContextTool as aa, buildRetrievalTocTool as ab, connectWebSocket as ac, connectWithReconnect as ad, consumeSSEStream as ae, contacts as af, conversations as ag, countCitations as ah, createAuthenticatedClient as ai, createDocumentWaiter as aj, dm as ak, doctags as al, documents as am, files as an, filterSkills as ao, formatAgentStepLabel as ap, formatFileSize as aq, formatStreamSummary as ar, formatUserName as as, formatWorkspaceChoices as at, formatWsMessage as au, generateEncryptedWorkspaceKey as av, generateNewWorkspaceKey as aw, getErrorCode as ax, getErrorMessage as ay, getRawWorkspaceKey as az, ArbiApiError as b, ArbiError as c, type ArbiErrorEvent as d, type ArbiOptions as e, type ArtifactEvent as f, type AuthContext as g, type AuthHeaders as h, type AuthenticatedClient as i, type CitationSummary as j, type CliConfig as k, type CliCredentials as l, type ConfigStore as m, type ConnectOptions as n, type DmCryptoContext as o, type DocumentListFields as p, type DocumentListOrder as q, type DocumentWaiter as r, type DocumentWaiterOptions as s, type ListPaginatedOptions as t, type MessageMetadataPayload$1 as u, type MessageQueuedEvent as v, type ReconnectableWsConnection as w, type ResolvedCitation as x, type ResponseCompletedEvent as y, type ResponseContentPartAddedEvent as z };
4407
+ export { type UploadOptions as $, type AgentStepEvent as A, type ResponseCreatedEvent as B, type ChatSession as C, DOC_TERMINAL_STATUSES as D, type ResponseFailedEvent as E, type FormattedWsMessage as F, type ResponseOutputItemAddedEvent as G, type ResponseOutputItemDoneEvent as H, type ResponseOutputTextDeltaEvent as I, type ResponseOutputTextDoneEvent as J, type ResponseUsage as K, type ListAllOptions as L, type MessageLevel as M, type SSEStreamCallbacks as N, type OutputTokensDetails as O, type ParsedSlashCommand as P, type QueryOptions as Q, type ReconnectOptions as R, type SSEEvent as S, type SSEStreamResult as T, type SSEStreamStartData as U, SUPPORTED_EXTENSIONS as V, type SkillSummary as W, type SkippedFile as X, type UploadBatchResult as Y, type UploadDirectOptions as Z, type UploadDirectResult as _, Arbi as a, type UploadResult as a0, type UserInfo as a1, type UserInputRequestEvent as a2, type UserMessageEvent as a3, WebSocketAuthError as a4, type WorkspaceContext as a5, type WsConnection as a6, agentconfig as a7, assistant as a8, authenticatedFetch as a9, getRawWorkspaceKey as aA, health as aB, parseSSEEvents as aC, parseSlashCommand as aD, parseSlashTokenInProgress as aE, performPasswordLogin as aF, performSigningKeyLogin as aG, performSsoDeviceFlowLogin as aH, requireData as aI, requireOk as aJ, resolveAuth as aK, resolveCitations as aL, resolveWorkspace as aM, responses as aN, selectWorkspace as aO, selectWorkspaceById as aP, settings as aQ, streamSSE as aR, stripCitationMarkdown as aS, summarizeCitations as aT, tags as aU, workspaces as aV, buildRetrievalChunkTool as aa, buildRetrievalFullContextTool as ab, buildRetrievalTocTool as ac, connectWebSocket as ad, connectWithReconnect as ae, consumeSSEStream as af, contacts as ag, conversations as ah, countCitations as ai, createAuthenticatedClient as aj, createDocumentWaiter as ak, dm as al, doctags as am, documents as an, files as ao, filterSkills as ap, formatAgentStepLabel as aq, formatFileSize as ar, formatStreamSummary as as, formatUserName as at, formatWorkspaceChoices as au, formatWsMessage as av, generateEncryptedWorkspaceKey as aw, generateNewWorkspaceKey as ax, getErrorCode as ay, getErrorMessage as az, ArbiApiError as b, ArbiError as c, type ArbiErrorEvent as d, type ArbiOptions as e, type ArtifactEvent as f, type AuthContext as g, type AuthHeaders as h, type AuthenticatedClient as i, type CitationSummary as j, type CliConfig as k, type CliCredentials as l, type ConfigStore as m, type ConnectOptions as n, type DmCryptoContext as o, type DocumentListFields as p, type DocumentListOrder as q, type DocumentWaiter as r, type DocumentWaiterOptions as s, type ListPaginatedOptions as t, type MessageMetadataPayload$1 as u, type MessageQueuedEvent as v, type ReconnectableWsConnection as w, type ResolvedCitation as x, type ResponseCompletedEvent as y, type ResponseContentPartAddedEvent as z };
package/dist/browser.cjs CHANGED
@@ -3986,6 +3986,12 @@ async function streamSSE(response, callbacks = {}) {
3986
3986
  var consumeSSEStream = streamSSE;
3987
3987
  var AUTH_TIMEOUT_MS = 1e4;
3988
3988
  var MAX_BACKOFF_MS = 3e4;
3989
+ var WebSocketAuthError = class extends Error {
3990
+ constructor(reason) {
3991
+ super(`WebSocket auth failed: ${reason}`);
3992
+ this.name = "WebSocketAuthError";
3993
+ }
3994
+ };
3989
3995
  function connectWebSocket(options) {
3990
3996
  const { baseUrl, accessToken, onMessage, onClose } = options;
3991
3997
  const url = client.buildWebSocketUrl(baseUrl);
@@ -4013,7 +4019,7 @@ function connectWebSocket(options) {
4013
4019
  resolve({ close: () => ws.close() });
4014
4020
  } else {
4015
4021
  ws.close();
4016
- reject(new Error(`WebSocket auth failed: ${msg.reason || "unknown"}`));
4022
+ reject(new WebSocketAuthError(msg.reason || "unknown"));
4017
4023
  }
4018
4024
  }
4019
4025
  return;
@@ -4036,52 +4042,66 @@ async function connectWithReconnect(options) {
4036
4042
  const {
4037
4043
  maxRetries = 10,
4038
4044
  initialDelayMs = 1e3,
4045
+ getAccessToken,
4046
+ refreshAuth,
4039
4047
  onReconnecting,
4040
4048
  onReconnected,
4041
4049
  onReconnectFailed,
4042
4050
  onClose,
4043
- ...connectOpts
4051
+ onMessage,
4052
+ baseUrl,
4053
+ accessToken
4044
4054
  } = options;
4055
+ const resolveToken = getAccessToken ?? (() => accessToken);
4045
4056
  let closed = false;
4046
- let reconnectTimer = null;
4057
+ let cancelDelay = null;
4047
4058
  let currentConnection = null;
4059
+ const connectOnce = async () => {
4060
+ const token = await resolveToken();
4061
+ if (!token) throw new WebSocketAuthError("no access token available");
4062
+ return connectWebSocket({
4063
+ baseUrl,
4064
+ accessToken: token,
4065
+ onMessage,
4066
+ onClose: (code, reason) => {
4067
+ currentConnection = null;
4068
+ onClose?.(code, reason);
4069
+ if (!closed) void scheduleReconnect();
4070
+ }
4071
+ });
4072
+ };
4048
4073
  const scheduleReconnect = async () => {
4049
4074
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
4050
4075
  if (closed) return;
4051
4076
  const delay = Math.min(initialDelayMs * Math.pow(2, attempt - 1), MAX_BACKOFF_MS);
4052
4077
  onReconnecting?.(attempt, maxRetries);
4053
4078
  await new Promise((resolve) => {
4054
- reconnectTimer = setTimeout(resolve, delay);
4079
+ const timer = setTimeout(resolve, delay);
4080
+ cancelDelay = () => {
4081
+ clearTimeout(timer);
4082
+ resolve();
4083
+ };
4055
4084
  });
4085
+ cancelDelay = null;
4056
4086
  if (closed) return;
4057
4087
  try {
4058
- currentConnection = await connectWebSocket({
4059
- ...connectOpts,
4060
- onClose: (code, reason) => {
4061
- currentConnection = null;
4062
- onClose?.(code, reason);
4063
- if (!closed) scheduleReconnect();
4064
- }
4065
- });
4088
+ currentConnection = await connectOnce();
4066
4089
  onReconnected?.();
4067
4090
  return;
4068
- } catch {
4091
+ } catch (err) {
4092
+ if (err instanceof WebSocketAuthError && refreshAuth) {
4093
+ await refreshAuth().catch(() => {
4094
+ });
4095
+ }
4069
4096
  }
4070
4097
  }
4071
4098
  if (!closed) onReconnectFailed?.();
4072
4099
  };
4073
- currentConnection = await connectWebSocket({
4074
- ...connectOpts,
4075
- onClose: (code, reason) => {
4076
- currentConnection = null;
4077
- onClose?.(code, reason);
4078
- if (!closed) scheduleReconnect();
4079
- }
4080
- });
4100
+ currentConnection = await connectOnce();
4081
4101
  return {
4082
4102
  close: () => {
4083
4103
  closed = true;
4084
- if (reconnectTimer) clearTimeout(reconnectTimer);
4104
+ cancelDelay?.();
4085
4105
  currentConnection?.close();
4086
4106
  currentConnection = null;
4087
4107
  }
@@ -5630,6 +5650,7 @@ function extractResponseText(response) {
5630
5650
  exports.Arbi = Arbi;
5631
5651
  exports.ArbiApiError = ArbiApiError;
5632
5652
  exports.ArbiError = ArbiError;
5653
+ exports.WebSocketAuthError = WebSocketAuthError;
5633
5654
  exports.agentconfig = agentconfig_exports;
5634
5655
  exports.assistant = assistant_exports;
5635
5656
  exports.authenticatedFetch = authenticatedFetch;