@openclaw/gateway-client 2026.10.5 → 2026.10.10-beta.2

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/README.md CHANGED
@@ -31,7 +31,7 @@ Use the verified stable release with exact pins:
31
31
  npm install --save-exact @openclaw/gateway-client@2026.8.1 @openclaw/gateway-protocol@2026.8.1
32
32
  ```
33
33
 
34
- See the canonical [installation guide](https://docs.openclaw.ai/gateway/clients#install-the-packages)
34
+ See the [installation guide](https://docs.openclaw.ai/gateway/clients#install-the-packages)
35
35
  for package/wire-version rules and recovery from reserved `0.0.0` artifacts.
36
36
  Test it with the Gateway version you deploy; the root `openclaw` CLI has its own
37
37
  package versions and dist-tags.
@@ -162,7 +162,7 @@ transport timeouts return `false`. Both entries use the same implementation.
162
162
 
163
163
  ## Defaults and reconnect behavior
164
164
 
165
- The Node client starts with a 30 second request timeout, a 15 second
165
+ The Node client starts with a 30 second request timeout, a 30 second
166
166
  connect-challenge timeout, and exponential reconnect backoff from 1 second to 30
167
167
  seconds with a multiplier of 2. Reconnects use randomized delays: the first waits
168
168
  1–1.2 seconds, and sustained failures spread retries across 25–30 seconds.
@@ -181,7 +181,14 @@ first so its authoritative outcome can settle the run. Other gapped frames and
181
181
  subsequent frames from that socket are not delivered. Reconnect restores a fresh live-text baseline; applications should
182
182
  also refresh durable state and restore their session subscriptions.
183
183
 
184
- The canonical defaults table and the server policy fields that can replace
184
+ Session subscription requests time out without compensating RPCs. If the Gateway
185
+ applied a subscribe or unsubscribe but its acknowledgment was lost, observation
186
+ may remain stale until a fresh subscription or reconnect. In particular, a
187
+ retained handle may miss updates after an unacknowledged unsubscribe. The caller
188
+ still receives the timeout; ordinary acknowledged leases and release retries
189
+ retain their ownership and ordering.
190
+
191
+ The defaults table and the server policy fields that can replace
185
192
  pre-handshake values are documented in the
186
193
  [Gateway protocol specification](https://docs.openclaw.ai/gateway/protocol#client-constants).
187
194
 
@@ -1,7 +1,7 @@
1
1
  import { A as normalizeSessionProjectionRunId, C as reduceSessionProjectionRunEvent, D as SessionMessageIdentity, E as SessionMessageEnvelope, F as gatewayOriginScope, I as mergeChatStreamMessage, L as buildDeviceAuthPayload, M as readSessionMessageIdentity, N as readSessionMessageSequence, O as SessionProjectionEntry, P as gatewayCredentialScope, R as buildDeviceAuthPayloadV3, S as SessionProjectionRunTransition, T as readSessionProjectionFinalMessageIdentity, _ as reconcileSessionProjectionSnapshot, a as GatewaySessionMessageSubscriptionOptions, b as projectSessionTerminalReplyMessage, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionRunStatus, f as SessionProjectionScope, g as projectLiveSessionMessage, h as createSessionProjection, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as readAssistantStreamSegmentIdentity, k as isLocallyOptimisticSessionMessage, l as SessionProjectionEvent, m as SessionProjectionState, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionSnapshotOptions, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionRun, v as reduceSessionProjection, w as hasSessionProjectionAcceptedFinal, x as SessionProjectionGatewayRunEvent, y as isSessionProjectionErrorMessage, z as normalizeDeviceMetadataForAuth } from "./session-subscriptions-Bcq6_wtR.mjs";
2
2
  import { a as GatewayBrowserDeviceTokenStore, c as resolveGatewayConnectScopes, i as GatewayBrowserDeviceTokenRecord, l as selectGatewayConnectAuth, n as GatewayBrowserDeviceAuthPlan, o as GatewayConnectAuthSelection, r as GatewayBrowserDeviceIdentity, s as buildGatewayConnectAuth, t as GatewayBrowserDeviceAuthLifecycle, u as shouldRetryGatewayWithDeviceToken } from "./browser-device-auth-_UweR4aN.mjs";
3
3
  import { i as isGatewayProtocolResponseError, n as GatewayProtocolRequestOptions, r as GatewayProtocolRequestTimeoutError, t as GatewayProtocolRequestError } from "./protocol-request-CtVhe3Bj.mjs";
4
- import { a as GatewayProtocolConnectAuthority, c as GatewayProtocolTiming, i as GatewayProtocolCloseContext, l as GatewayProtocolRequestTiming, o as GatewayProtocolSocket, s as GatewayProtocolSocketHandlers, t as GatewayProtocolClient } from "./protocol-client-Dg5tIB1S.mjs";
4
+ import { a as GatewayProtocolConnectAuthority, c as GatewayProtocolTiming, i as GatewayProtocolCloseContext, l as GatewayProtocolRequestTiming, o as GatewayProtocolSocket, s as GatewayProtocolSocketHandlers, t as GatewayProtocolClient } from "./protocol-client-CKMLpN-S.mjs";
5
5
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
6
6
  import { ConnectParams as ConnectParams$1, GATEWAY_SERVER_CAPS } from "@openclaw/gateway-protocol/frame-guards";
7
7
  import { ChannelsStatusResult, ConnectParams, ErrorShape, EventFrame, HelloOk, QuestionRecord } from "@openclaw/gateway-protocol";
package/dist/browser.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { A as buildGatewayConnectAuth, B as normalizeDeviceMetadataForAuth, C as isGatewayProtocolResponseError, D as gatewayCredentialScope, E as resolveModelCatalogConnect, F as asNullableRecord, M as selectGatewayConnectAuth, N as shouldRetryGatewayWithDeviceToken, O as gatewayOriginScope, P as mergeChatStreamMessage, R as buildDeviceAuthPayload, S as GatewayProtocolRequestTimeoutError, _ as isSessionProjectionErrorMessage, a as createSessionProjection, b as GatewayProtocolClient, c as reduceSessionProjection, d as readSessionProjectionFinalMessageIdentity, f as isLocallyOptimisticSessionMessage, g as readSessionMessageSequence, h as readSessionMessageIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as resolveGatewayConnectScopes, k as GatewayBrowserDeviceAuthLifecycle, l as reduceSessionProjectionRunEvent, m as readAssistantStreamSegmentIdentity, n as getGatewaySessionMessageSubscriptionCoordinator, o as projectLiveSessionMessage, p as normalizeSessionProjectionRunId, r as releaseGatewaySessionMessageSubscription, s as reconcileSessionProjectionSnapshot, t as GatewaySessionMessageSubscriptionCoordinator, u as hasSessionProjectionAcceptedFinal, v as projectSessionTerminalReplyMessage, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect, z as buildDeviceAuthPayloadV3 } from "./session-subscriptions-gJDR7_QJ.mjs";
2
- import { n as DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, p as resolveSafeTimeoutDelayMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS } from "./timeouts-CQTCye5U.mjs";
1
+ import { A as buildGatewayConnectAuth, B as normalizeDeviceMetadataForAuth, C as isGatewayProtocolResponseError, D as gatewayCredentialScope, E as resolveModelCatalogConnect, F as asNullableRecord, M as selectGatewayConnectAuth, N as shouldRetryGatewayWithDeviceToken, O as gatewayOriginScope, P as mergeChatStreamMessage, R as buildDeviceAuthPayload, S as GatewayProtocolRequestTimeoutError, _ as isSessionProjectionErrorMessage, a as createSessionProjection, b as GatewayProtocolClient, c as reduceSessionProjection, d as readSessionProjectionFinalMessageIdentity, f as isLocallyOptimisticSessionMessage, g as readSessionMessageSequence, h as readSessionMessageIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as resolveGatewayConnectScopes, k as GatewayBrowserDeviceAuthLifecycle, l as reduceSessionProjectionRunEvent, m as readAssistantStreamSegmentIdentity, n as getGatewaySessionMessageSubscriptionCoordinator, o as projectLiveSessionMessage, p as normalizeSessionProjectionRunId, r as releaseGatewaySessionMessageSubscription, s as reconcileSessionProjectionSnapshot, t as GatewaySessionMessageSubscriptionCoordinator, u as hasSessionProjectionAcceptedFinal, v as projectSessionTerminalReplyMessage, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect, z as buildDeviceAuthPayloadV3 } from "./session-subscriptions-hOI4k496.mjs";
2
+ import { n as DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, p as resolveSafeTimeoutDelayMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS } from "./timeouts-F2UKsnjG.mjs";
3
3
  import { GATEWAY_SERVER_CAPS } from "@openclaw/gateway-protocol/frame-guards";
4
4
  export * from "@openclaw/gateway-protocol/connect-error-details";
5
5
  export * from "@openclaw/gateway-protocol/gateway-error-details";
package/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { A as normalizeSessionProjectionRunId, C as reduceSessionProjectionRunEvent, D as SessionMessageIdentity, E as SessionMessageEnvelope, F as gatewayOriginScope, I as mergeChatStreamMessage, L as buildDeviceAuthPayload, M as readSessionMessageIdentity, N as readSessionMessageSequence, O as SessionProjectionEntry, P as gatewayCredentialScope, R as buildDeviceAuthPayloadV3, S as SessionProjectionRunTransition, T as readSessionProjectionFinalMessageIdentity, _ as reconcileSessionProjectionSnapshot, a as GatewaySessionMessageSubscriptionOptions, b as projectSessionTerminalReplyMessage, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionRunStatus, f as SessionProjectionScope, g as projectLiveSessionMessage, h as createSessionProjection, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as readAssistantStreamSegmentIdentity, k as isLocallyOptimisticSessionMessage, l as SessionProjectionEvent, m as SessionProjectionState, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionSnapshotOptions, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionRun, v as reduceSessionProjection, w as hasSessionProjectionAcceptedFinal, x as SessionProjectionGatewayRunEvent, y as isSessionProjectionErrorMessage, z as normalizeDeviceMetadataForAuth } from "./session-subscriptions-Bcq6_wtR.mjs";
2
2
  import { a as GatewayBrowserDeviceTokenStore, c as resolveGatewayConnectScopes, i as GatewayBrowserDeviceTokenRecord, l as selectGatewayConnectAuth, n as GatewayBrowserDeviceAuthPlan, o as GatewayConnectAuthSelection, r as GatewayBrowserDeviceIdentity, s as buildGatewayConnectAuth, t as GatewayBrowserDeviceAuthLifecycle, u as shouldRetryGatewayWithDeviceToken } from "./browser-device-auth-_UweR4aN.mjs";
3
3
  import { i as isGatewayProtocolResponseError } from "./protocol-request-CtVhe3Bj.mjs";
4
- import { n as GatewayClientCloseInfo, r as GatewayClientConnectionMetadata } from "./protocol-client-Dg5tIB1S.mjs";
4
+ import { n as GatewayClientCloseInfo, r as GatewayClientConnectionMetadata } from "./protocol-client-CKMLpN-S.mjs";
5
5
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout } from "./timeouts.mjs";
6
- import { _ as isGatewayConnectAssemblyError, a as startGatewayClientWithReadinessWait, c as waitForEventLoopReady, d as GatewayClientHostDeps, f as GatewayClientOptions, g as GatewayClientRequestError, h as GatewayReconnectPausedInfo, i as startGatewayClientWhenEventLoopReady, l as DeviceIdentity, m as GatewayClientRequestTimeoutError, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientRequestOptions, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as GatewayClient, v as DeviceAuthTokenRecord } from "./readiness-CkF8_J-1.mjs";
6
+ import { _ as isGatewayConnectAssemblyError, a as startGatewayClientWithReadinessWait, c as waitForEventLoopReady, d as GatewayClientHostDeps, f as GatewayClientOptions, g as GatewayClientRequestError, h as GatewayReconnectPausedInfo, i as startGatewayClientWhenEventLoopReady, l as DeviceIdentity, m as GatewayClientRequestTimeoutError, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientRequestOptions, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as GatewayClient, v as DeviceAuthTokenRecord } from "./readiness-BbuB7IzG.mjs";
7
7
  import { GatewayScopeUpgrade, ScopeUpgradeBinding, ScopeUpgradeOptions, ScopeUpgradeOutcome } from "./scope-upgrade.mjs";
8
8
  //#region packages/gateway-client/src/run-recovery-text.d.ts
9
9
  export type RecoveryRequest = (method: string, params: Record<string, unknown>, signal: AbortSignal) => Promise<unknown>;
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { A as buildGatewayConnectAuth, B as normalizeDeviceMetadataForAuth, C as isGatewayProtocolResponseError, D as gatewayCredentialScope, E as resolveModelCatalogConnect, I as asRecord, L as isRecord, M as selectGatewayConnectAuth, N as shouldRetryGatewayWithDeviceToken, O as gatewayOriginScope, P as mergeChatStreamMessage, R as buildDeviceAuthPayload, S as GatewayProtocolRequestTimeoutError, T as raceWithTimeout, _ as isSessionProjectionErrorMessage, a as createSessionProjection, b as GatewayProtocolClient, c as reduceSessionProjection, d as readSessionProjectionFinalMessageIdentity, f as isLocallyOptimisticSessionMessage, g as readSessionMessageSequence, h as readSessionMessageIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as resolveGatewayConnectScopes, k as GatewayBrowserDeviceAuthLifecycle, l as reduceSessionProjectionRunEvent, m as readAssistantStreamSegmentIdentity, n as getGatewaySessionMessageSubscriptionCoordinator, o as projectLiveSessionMessage, p as normalizeSessionProjectionRunId, r as releaseGatewaySessionMessageSubscription, s as reconcileSessionProjectionSnapshot, t as GatewaySessionMessageSubscriptionCoordinator, u as hasSessionProjectionAcceptedFinal, v as projectSessionTerminalReplyMessage, w as createAbortError, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect, z as buildDeviceAuthPayloadV3 } from "./session-subscriptions-gJDR7_QJ.mjs";
2
- import { _ as normalizeOptionalString, a as MIN_CONNECT_CHALLENGE_TIMEOUT_MS, c as clearGatewayConnectTimeout, d as resolveFiniteTimeoutDelayMs, f as resolvePreauthHandshakeTimeoutMs, h as normalizeLowercaseStringOrEmpty, i as MAX_SAFE_TIMEOUT_DELAY_MS, l as getConnectChallengeTimeoutMsFromEnv, m as startGatewayConnectTimeout, n as DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, o as addSafeTimeoutDelayGraceMs, p as resolveSafeTimeoutDelayMs, r as MAX_CONNECT_CHALLENGE_TIMEOUT_MS, s as clampConnectChallengeTimeoutMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, u as resolveConnectChallengeTimeoutMs } from "./timeouts-CQTCye5U.mjs";
1
+ import { A as buildGatewayConnectAuth, B as normalizeDeviceMetadataForAuth, C as isGatewayProtocolResponseError, D as gatewayCredentialScope, E as resolveModelCatalogConnect, I as asRecord, L as isRecord, M as selectGatewayConnectAuth, N as shouldRetryGatewayWithDeviceToken, O as gatewayOriginScope, P as mergeChatStreamMessage, R as buildDeviceAuthPayload, S as GatewayProtocolRequestTimeoutError, T as raceWithTimeout, _ as isSessionProjectionErrorMessage, a as createSessionProjection, b as GatewayProtocolClient, c as reduceSessionProjection, d as readSessionProjectionFinalMessageIdentity, f as isLocallyOptimisticSessionMessage, g as readSessionMessageSequence, h as readSessionMessageIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as resolveGatewayConnectScopes, k as GatewayBrowserDeviceAuthLifecycle, l as reduceSessionProjectionRunEvent, m as readAssistantStreamSegmentIdentity, n as getGatewaySessionMessageSubscriptionCoordinator, o as projectLiveSessionMessage, p as normalizeSessionProjectionRunId, r as releaseGatewaySessionMessageSubscription, s as reconcileSessionProjectionSnapshot, t as GatewaySessionMessageSubscriptionCoordinator, u as hasSessionProjectionAcceptedFinal, v as projectSessionTerminalReplyMessage, w as createAbortError, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect, z as buildDeviceAuthPayloadV3 } from "./session-subscriptions-hOI4k496.mjs";
2
+ import { _ as normalizeOptionalString, a as MIN_CONNECT_CHALLENGE_TIMEOUT_MS, c as clearGatewayConnectTimeout, d as resolveFiniteTimeoutDelayMs, f as resolvePreauthHandshakeTimeoutMs, h as normalizeLowercaseStringOrEmpty, i as MAX_SAFE_TIMEOUT_DELAY_MS, l as getConnectChallengeTimeoutMsFromEnv, m as startGatewayConnectTimeout, n as DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, o as addSafeTimeoutDelayGraceMs, p as resolveSafeTimeoutDelayMs, r as MAX_CONNECT_CHALLENGE_TIMEOUT_MS, s as clampConnectChallengeTimeoutMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, u as resolveConnectChallengeTimeoutMs } from "./timeouts-F2UKsnjG.mjs";
3
3
  import { rawDataToString } from "./websocket-data.mjs";
4
- import { n as startGatewayClientWithReadinessWait, r as waitForEventLoopReady, t as startGatewayClientWhenEventLoopReady } from "./readiness-rG6_5Ynk.mjs";
4
+ import { n as startGatewayClientWithReadinessWait, r as waitForEventLoopReady, t as startGatewayClientWhenEventLoopReady } from "./readiness-CwRz4ZX8.mjs";
5
5
  import { GatewayScopeUpgrade } from "./scope-upgrade.mjs";
6
6
  import { createRequire } from "node:module";
7
7
  import { ConnectErrorDetailCodes, formatConnectErrorMessage, readConnectErrorDetailCode } from "@openclaw/gateway-protocol/connect-error-details";
@@ -168,8 +168,6 @@ declare class GatewayProtocolClient<TPlan> {
168
168
  get connected(): boolean;
169
169
  get hasPendingRequests(): boolean;
170
170
  get connecting(): boolean;
171
- /** A transport upgrade is in flight; the socket adapter bounds how long it may stay open. */
172
- get opening(): boolean;
173
171
  get hasUnboundedPendingRequests(): boolean;
174
172
  start(): void;
175
173
  stop(): void;
@@ -1,5 +1,5 @@
1
1
  import { n as GatewayProtocolRequestOptions, r as GatewayProtocolRequestTimeoutError, t as GatewayProtocolRequestError } from "./protocol-request-CtVhe3Bj.mjs";
2
- import { l as GatewayProtocolRequestTiming, n as GatewayClientCloseInfo, r as GatewayClientConnectionMetadata } from "./protocol-client-Dg5tIB1S.mjs";
2
+ import { l as GatewayProtocolRequestTiming, n as GatewayClientCloseInfo, r as GatewayClientConnectionMetadata } from "./protocol-client-CKMLpN-S.mjs";
3
3
  import { ConnectParams, ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol/frame-guards";
4
4
  import { GatewayClientMode, GatewayClientName } from "@openclaw/gateway-protocol/client-info";
5
5
  import "ws";
@@ -1,4 +1,4 @@
1
- import { d as resolveFiniteTimeoutDelayMs, u as resolveConnectChallengeTimeoutMs } from "./timeouts-CQTCye5U.mjs";
1
+ import { d as resolveFiniteTimeoutDelayMs, u as resolveConnectChallengeTimeoutMs } from "./timeouts-F2UKsnjG.mjs";
2
2
  //#region packages/gateway-client/src/event-loop-ready.ts
3
3
  const DEFAULT_MAX_WAIT_MS = 1e4;
4
4
  const DEFAULT_INTERVAL_MS = 1;
@@ -19,11 +19,8 @@ async function waitForEventLoopReady(options = {}) {
19
19
  let checks = 0;
20
20
  let maxDriftMs = 0;
21
21
  return await new Promise((resolve) => {
22
- let settled = false;
23
22
  let timer = null;
24
23
  const finish = (ready, aborted = false) => {
25
- if (settled) return;
26
- settled = true;
27
24
  if (timer) {
28
25
  clearTimeout(timer);
29
26
  timer = null;
@@ -46,10 +43,6 @@ async function waitForEventLoopReady(options = {}) {
46
43
  }
47
44
  signal?.addEventListener("abort", onAbort, { once: true });
48
45
  const scheduleNext = () => {
49
- if (signal?.aborted) {
50
- finish(false, true);
51
- return;
52
- }
53
46
  const elapsedMs = Math.max(0, Date.now() - startedAt);
54
47
  const remainingMs = maxWaitMs - elapsedMs;
55
48
  if (remainingMs <= 0) {
@@ -1,2 +1,2 @@
1
- import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-CkF8_J-1.mjs";
1
+ import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-BbuB7IzG.mjs";
2
2
  export { EventLoopReadyWaiter, GatewayClientStartReadinessOptions, GatewayClientStartable, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait };
@@ -1,2 +1,2 @@
1
- import { n as startGatewayClientWithReadinessWait, t as startGatewayClientWhenEventLoopReady } from "./readiness-rG6_5Ynk.mjs";
1
+ import { n as startGatewayClientWithReadinessWait, t as startGatewayClientWhenEventLoopReady } from "./readiness-CwRz4ZX8.mjs";
2
2
  export { startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait };
@@ -1,4 +1,4 @@
1
- import { _ as normalizeOptionalString, c as clearGatewayConnectTimeout, g as normalizeNullableString, m as startGatewayConnectTimeout, p as resolveSafeTimeoutDelayMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS } from "./timeouts-CQTCye5U.mjs";
1
+ import { _ as normalizeOptionalString, c as clearGatewayConnectTimeout, g as normalizeNullableString, m as startGatewayConnectTimeout, p as resolveSafeTimeoutDelayMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS } from "./timeouts-F2UKsnjG.mjs";
2
2
  import { ConnectErrorDetailCodes, readConnectErrorDetailCode, readConnectErrorRecoveryAdvice, readPairingConnectErrorDetails } from "@openclaw/gateway-protocol/connect-error-details";
3
3
  import { isGatewayEventFrame, isGatewayResponseFrame } from "@openclaw/gateway-protocol/frame-guards";
4
4
  import { GATEWAY_SUSPEND_IDENTITY_RETRY_AFTER_MS, isGatewayRestartUnavailableError, isGatewaySuspendUnavailableError } from "@openclaw/gateway-protocol/restart-unavailable";
@@ -333,14 +333,13 @@ async function sleepWithAbort(ms, abortSignal, options = {}) {
333
333
  const delayMs = resolveSleepDelayMs(ms);
334
334
  if (delayMs === 0) return;
335
335
  await new Promise((resolve, reject) => {
336
- let settled = false;
337
- let timer = null;
338
336
  const cleanup = () => abortSignal?.removeEventListener("abort", onAbort);
337
+ const timer = setTimeout(() => {
338
+ cleanup();
339
+ resolve();
340
+ }, delayMs);
339
341
  const onAbort = () => {
340
- if (settled) return;
341
- settled = true;
342
- if (timer) clearTimeout(timer);
343
- timer = null;
342
+ clearTimeout(timer);
344
343
  cleanup();
345
344
  reject(createAbortError("aborted", { cause: abortSignal?.reason ?? /* @__PURE__ */ new Error("aborted") }));
346
345
  };
@@ -349,14 +348,7 @@ async function sleepWithAbort(ms, abortSignal, options = {}) {
349
348
  onAbort();
350
349
  return;
351
350
  }
352
- timer = setTimeout(() => {
353
- settled = true;
354
- cleanup();
355
- timer = null;
356
- resolve();
357
- }, delayMs);
358
351
  if (options.ref === false) timer.unref?.();
359
- if (abortSignal?.aborted) onAbort();
360
352
  });
361
353
  }
362
354
  var RetrySupervisor = class {
@@ -818,10 +810,6 @@ var GatewayProtocolClient = class {
818
810
  get connecting() {
819
811
  return this.connectSent && !this.helloReceived;
820
812
  }
821
- /** A transport upgrade is in flight; the socket adapter bounds how long it may stay open. */
822
- get opening() {
823
- return this.socket !== null && !this.socketOpened;
824
- }
825
813
  get hasUnboundedPendingRequests() {
826
814
  return this.requests.hasUnboundedPending;
827
815
  }
@@ -1601,6 +1589,39 @@ function isUnsequencedLiveTerminal(current, run) {
1601
1589
  return Boolean(current.live && current.identity?.role === "assistant" && !current.identity.id && current.identity.sequence === null && run && run.status !== "streaming" && readFinalContentIdentity(current.message) === readFinalContentIdentity(run.message));
1602
1590
  }
1603
1591
  //#endregion
1592
+ //#region packages/gateway-client/src/session-projection-order.ts
1593
+ function insertSessionProjectionEntry(entries, incoming, runs) {
1594
+ const sequence = incoming.identity?.sequence;
1595
+ let nextIndex = sequence === void 0 || sequence === null ? -1 : entries.findIndex((entry) => {
1596
+ const candidate = entry.identity?.sequence;
1597
+ return candidate !== void 0 && candidate !== null && candidate > sequence;
1598
+ });
1599
+ if (sequence !== void 0 && sequence !== null && nextIndex < 0) nextIndex = entries.length;
1600
+ if (incoming.identity?.role === "user" && incoming.identity.runId) {
1601
+ const runId = incoming.identity.runId;
1602
+ const terminalMessage = runs?.[runId]?.message;
1603
+ const belongsToRun = (entry) => entry.identity?.role === "assistant" && (entry.identity.runId === runId || entry.message === terminalMessage) || entry.pending && entry.identity?.role === "user" && !entry.identity.isImported && asNullableRecord(asNullableRecord(entry.message)?.["__openclaw"])?.steerTargetRunId === runId;
1604
+ if (sequence !== void 0 && sequence !== null) {
1605
+ const before = [];
1606
+ const dependents = [];
1607
+ for (const entry of entries.slice(0, nextIndex)) (entry.identity?.sequence === null && belongsToRun(entry) ? dependents : before).push(entry);
1608
+ return [
1609
+ ...before,
1610
+ incoming,
1611
+ ...dependents,
1612
+ ...entries.slice(nextIndex)
1613
+ ];
1614
+ }
1615
+ const terminalIndex = entries.findIndex(belongsToRun);
1616
+ if (terminalIndex >= 0 && (nextIndex < 0 || terminalIndex < nextIndex)) nextIndex = terminalIndex;
1617
+ }
1618
+ return nextIndex < 0 ? [...entries, incoming] : [
1619
+ ...entries.slice(0, nextIndex),
1620
+ incoming,
1621
+ ...entries.slice(nextIndex)
1622
+ ];
1623
+ }
1624
+ //#endregion
1604
1625
  //#region packages/gateway-client/src/session-projection-run-retention.ts
1605
1626
  /** Bounded retention for completed and active session projection runs. */
1606
1627
  const MAX_TRACKED_SESSION_RUNS = 200;
@@ -1725,37 +1746,6 @@ function withEntries(state, entries) {
1725
1746
  messages: entries.map((entry) => entry.message)
1726
1747
  };
1727
1748
  }
1728
- function insertEntry(entries, incoming, runs) {
1729
- const sequence = incoming.identity?.sequence;
1730
- let nextIndex = sequence === void 0 || sequence === null ? -1 : entries.findIndex((entry) => {
1731
- const candidate = entry.identity?.sequence;
1732
- return candidate !== void 0 && candidate !== null && candidate > sequence;
1733
- });
1734
- if (sequence !== void 0 && sequence !== null && nextIndex < 0) nextIndex = entries.length;
1735
- if (incoming.identity?.role === "user" && incoming.identity.runId) {
1736
- const runId = incoming.identity.runId;
1737
- const terminalMessage = runs?.[runId]?.message;
1738
- const belongsToRun = (entry) => entry.identity?.role === "assistant" && (entry.identity.runId === runId || entry.message === terminalMessage);
1739
- if (sequence !== void 0 && sequence !== null) {
1740
- const before = [];
1741
- const replies = [];
1742
- for (const entry of entries.slice(0, nextIndex)) (entry.identity?.sequence === null && belongsToRun(entry) ? replies : before).push(entry);
1743
- return [
1744
- ...before,
1745
- incoming,
1746
- ...replies,
1747
- ...entries.slice(nextIndex)
1748
- ];
1749
- }
1750
- const terminalIndex = entries.findIndex(belongsToRun);
1751
- if (terminalIndex >= 0 && (nextIndex < 0 || terminalIndex < nextIndex)) nextIndex = terminalIndex;
1752
- }
1753
- return nextIndex < 0 ? [...entries, incoming] : [
1754
- ...entries.slice(0, nextIndex),
1755
- incoming,
1756
- ...entries.slice(nextIndex)
1757
- ];
1758
- }
1759
1749
  function projectLiveSessionMessage(initialState, message, envelope, scope = {}) {
1760
1750
  let state = initialState;
1761
1751
  if (!scopesMatch(state.scope, scope)) return state;
@@ -1771,11 +1761,11 @@ function projectLiveSessionMessage(initialState, message, envelope, scope = {})
1771
1761
  const provisional = durable === existing ? incoming : existing;
1772
1762
  if (durable && isToolUsePersistedFinalRow(durable.message)) {
1773
1763
  const history = state.entries.filter((entry) => entry !== provisional);
1774
- const snapshot = durable === incoming ? insertEntry(history, durable) : history;
1764
+ const snapshot = durable === incoming ? insertSessionProjectionEntry(history, durable) : history;
1775
1765
  const runId = provisional.identity?.runId;
1776
1766
  const run = runId ? state.runs[runId] : void 0;
1777
1767
  const terminalMatch = findUniqueSnapshotTerminalMatch(provisional, [durable], run, snapshot);
1778
- if (!terminalMatch) return withEntries(state, insertEntry(state.entries, incoming, state.runs));
1768
+ if (!terminalMatch) return withEntries(state, insertSessionProjectionEntry(state.entries, incoming, state.runs));
1779
1769
  if (terminalMatch.inferred && durable.identity && runId && run) {
1780
1770
  const inferredSnapshotTerminal = {
1781
1771
  entry: provisional,
@@ -1794,14 +1784,14 @@ function projectLiveSessionMessage(initialState, message, envelope, scope = {})
1794
1784
  }
1795
1785
  }
1796
1786
  }
1797
- if (!existing) return withEntries(state, insertEntry(state.entries, incoming, state.runs));
1787
+ if (!existing) return withEntries(state, insertSessionProjectionEntry(state.entries, incoming, state.runs));
1798
1788
  const existingIndex = state.entries.indexOf(existing);
1799
1789
  if (existing.message === message && existing.live && !existing.pending) return state;
1800
1790
  if (!existing.pending && existing.identity?.id && !incoming.identity.id) return state;
1801
1791
  if (incoming.identity.sequence !== null && (existing.pending || existing.identity?.sequence === null)) {
1802
1792
  const sequence = incoming.identity.sequence;
1803
1793
  const violatesOrder = state.entries.some(({ identity }, index) => identity?.sequence != null && (index < existingIndex ? identity.sequence > sequence : identity.sequence < sequence));
1804
- return withEntries(state, violatesOrder ? insertEntry(state.entries.filter((_, index) => index !== existingIndex), incoming, state.runs) : state.entries.toSpliced(existingIndex, 1, incoming));
1794
+ return withEntries(state, violatesOrder ? insertSessionProjectionEntry(state.entries.filter((_, index) => index !== existingIndex), incoming, state.runs) : state.entries.toSpliced(existingIndex, 1, incoming));
1805
1795
  }
1806
1796
  return withEntries(state, state.entries.toSpliced(existingIndex, 1, incoming));
1807
1797
  }
@@ -1827,7 +1817,7 @@ function reconcileSessionProjectionSnapshot(state, messages, scope = {}, options
1827
1817
  };
1828
1818
  continue;
1829
1819
  }
1830
- entries = insertEntry(entries, current, runs);
1820
+ entries = insertSessionProjectionEntry(entries, current, runs);
1831
1821
  }
1832
1822
  for (const [runId, run] of Object.entries(runs)) {
1833
1823
  const inferred = run.inferredSnapshotTerminal;
@@ -1837,7 +1827,7 @@ function reconcileSessionProjectionSnapshot(state, messages, scope = {}, options
1837
1827
  const matches = entries.filter((entry) => entryMatches(entry, inferred.entry, true));
1838
1828
  const terminalMatch = findUniqueSnapshotTerminalMatch(inferred.entry, matches, run, entries);
1839
1829
  if (candidateRemains && visible && terminalMatch?.inferred) continue;
1840
- if (candidateRemains && visible && !terminalMatch) entries = insertEntry(entries, inferred.entry, runs);
1830
+ if (candidateRemains && visible && !terminalMatch) entries = insertSessionProjectionEntry(entries, inferred.entry, runs);
1841
1831
  const { inferredSnapshotTerminal: _inferred, ...settledRun } = run;
1842
1832
  runs[runId] = settledRun;
1843
1833
  }
@@ -1935,7 +1925,7 @@ function reduceSessionProjection(state, event) {
1935
1925
  pending: true,
1936
1926
  pendingRunId
1937
1927
  } : entry));
1938
- return seed || state.entries.some((entry) => entryMatches(entry, incoming)) ? state : withEntries(state, insertEntry(state.entries, incoming, state.runs));
1928
+ return seed || state.entries.some((entry) => entryMatches(entry, incoming)) ? state : withEntries(state, insertSessionProjectionEntry(state.entries, incoming, state.runs));
1939
1929
  }
1940
1930
  case "sendAcknowledged": {
1941
1931
  const runId = normalizeSessionProjectionRunId(event.idempotencyKey ?? event.runId);
@@ -2099,16 +2089,6 @@ var GatewaySessionMessageSubscriptionCoordinator = class {
2099
2089
  if (includeApprovals) entry.ready = this.#trackApprovalRequest(entry, entry.ready);
2100
2090
  entry.ready.catch(() => void 0);
2101
2091
  }
2102
- if (entry.refreshRequired) {
2103
- entry.refreshRequired = false;
2104
- entry.plainFallback = null;
2105
- entry.approvalRequest = null;
2106
- const retainedApprovals = [...entry.handles].some((handle) => handle.includeApprovals);
2107
- entry.ready = this.#requestSubscribe(entry, retainedApprovals).catch((error) => {
2108
- entry.refreshRequired = true;
2109
- throw error;
2110
- });
2111
- }
2112
2092
  const result = await this.#acquireCapability(entry, includeApprovals);
2113
2093
  if (!narration && entry.mode === "narration") await this.#requestSubscribe(entry, false, "full");
2114
2094
  if (this.#retired) throw new Error("Session message subscription completed on a replaced Gateway connection");
@@ -2157,10 +2137,7 @@ var GatewaySessionMessageSubscriptionCoordinator = class {
2157
2137
  return tracked;
2158
2138
  }
2159
2139
  const removeEntry = entry.handles.size === 1;
2160
- const tracked = (removeEntry ? this.#requestMessages(entry).catch((error) => {
2161
- if (error instanceof GatewayProtocolRequestTimeoutError && error.requestSent) entry.refreshRequired = true;
2162
- throw error;
2163
- }) : this.#requestSubscribe(entry, false, "narration")).then(() => this.#finishRelease(subscription, owner, removeEntry)).finally(() => {
2140
+ const tracked = (removeEntry ? this.#requestMessages(entry) : this.#requestSubscribe(entry, false, "narration")).then(() => this.#finishRelease(subscription, owner, removeEntry)).finally(() => {
2164
2141
  if (entry.release === tracked) entry.release = null;
2165
2142
  });
2166
2143
  entry.release = tracked;
@@ -2190,7 +2167,6 @@ var GatewaySessionMessageSubscriptionCoordinator = class {
2190
2167
  wireRequest: null,
2191
2168
  includeApprovals: false,
2192
2169
  canonicalSettled: false,
2193
- refreshRequired: false,
2194
2170
  handles: /* @__PURE__ */ new Set(),
2195
2171
  pendingOwners: 0,
2196
2172
  pendingFullOwners: 0,
@@ -2252,21 +2228,6 @@ var GatewaySessionMessageSubscriptionCoordinator = class {
2252
2228
  const result = await this.#requestMessages(entry, {
2253
2229
  mode,
2254
2230
  includeApprovals
2255
- }).catch(async (error) => {
2256
- if (!(error instanceof GatewayProtocolRequestTimeoutError) || !error.requestSent || this.#retired) throw error;
2257
- try {
2258
- const retainedApprovals = [...entry.handles].some((handle) => handle.includeApprovals);
2259
- const retainedMode = entry.handles.size > 0 && [...entry.handles].every((handle) => handle.mode === "narration") ? "narration" : void 0;
2260
- await this.#requestMessages(entry, entry.handles.size > 0 ? {
2261
- mode: retainedMode,
2262
- includeApprovals: retainedApprovals
2263
- } : void 0);
2264
- entry.mode = retainedMode;
2265
- entry.includeApprovals = retainedApprovals;
2266
- } catch (recoveryError) {
2267
- if (!this.#retired) throw new AggregateError([error, recoveryError], "session message subscription recovery failed", { cause: recoveryError });
2268
- }
2269
- throw error;
2270
2231
  });
2271
2232
  const response = result && typeof result === "object" ? result : null;
2272
2233
  const responseKey = response && "key" in response ? response.key : void 0;
@@ -39,7 +39,7 @@ function isTestRuntimeEnv(env) {
39
39
  /** Maximum delay Node timers can represent without overflow warnings. */
40
40
  const MAX_SAFE_TIMEOUT_DELAY_MS = 2147483647;
41
41
  /** Default server-side window for gateway preauth handshakes. */
42
- const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 15e3;
42
+ const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 3e4;
43
43
  /** Starts the browser-safe deadline that covers Gateway connect preparation and hello. */
44
44
  function startGatewayConnectTimeout(onTimeout) {
45
45
  const timer = setTimeout(onTimeout, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS);
@@ -2,7 +2,7 @@
2
2
  /** Maximum delay Node timers can represent without overflow warnings. */
3
3
  export declare const MAX_SAFE_TIMEOUT_DELAY_MS = 2147483647;
4
4
  /** Default server-side window for gateway preauth handshakes. */
5
- export declare const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 15000;
5
+ export declare const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 30000;
6
6
  /** Starts the browser-safe deadline that covers Gateway connect preparation and hello. */
7
7
  export declare function startGatewayConnectTimeout(onTimeout: () => void): ReturnType<typeof setTimeout>;
8
8
  /** Clears either pending Gateway handshake phase without retaining its timer. */
@@ -12,7 +12,7 @@ export declare const DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS = 30000;
12
12
  /** Minimum client watchdog delay for connect challenge setup. */
13
13
  export declare const MIN_CONNECT_CHALLENGE_TIMEOUT_MS = 250;
14
14
  /** Default maximum client watchdog delay, aligned with the preauth server timeout. */
15
- export declare const MAX_CONNECT_CHALLENGE_TIMEOUT_MS = 15000;
15
+ export declare const MAX_CONNECT_CHALLENGE_TIMEOUT_MS = 30000;
16
16
  /** Clamps arbitrary timer delays to Node's safe range and an optional floor. */
17
17
  export declare function resolveSafeTimeoutDelayMs(delayMs: number, opts?: {
18
18
  minMs?: number;
package/dist/timeouts.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as MIN_CONNECT_CHALLENGE_TIMEOUT_MS, c as clearGatewayConnectTimeout, d as resolveFiniteTimeoutDelayMs, f as resolvePreauthHandshakeTimeoutMs, i as MAX_SAFE_TIMEOUT_DELAY_MS, l as getConnectChallengeTimeoutMsFromEnv, m as startGatewayConnectTimeout, n as DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, o as addSafeTimeoutDelayGraceMs, p as resolveSafeTimeoutDelayMs, r as MAX_CONNECT_CHALLENGE_TIMEOUT_MS, s as clampConnectChallengeTimeoutMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, u as resolveConnectChallengeTimeoutMs } from "./timeouts-CQTCye5U.mjs";
1
+ import { a as MIN_CONNECT_CHALLENGE_TIMEOUT_MS, c as clearGatewayConnectTimeout, d as resolveFiniteTimeoutDelayMs, f as resolvePreauthHandshakeTimeoutMs, i as MAX_SAFE_TIMEOUT_DELAY_MS, l as getConnectChallengeTimeoutMsFromEnv, m as startGatewayConnectTimeout, n as DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, o as addSafeTimeoutDelayGraceMs, p as resolveSafeTimeoutDelayMs, r as MAX_CONNECT_CHALLENGE_TIMEOUT_MS, s as clampConnectChallengeTimeoutMs, t as DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, u as resolveConnectChallengeTimeoutMs } from "./timeouts-F2UKsnjG.mjs";
2
2
  export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/gateway-client",
3
- "version": "2026.10.5",
3
+ "version": "2026.10.10-beta.2",
4
4
  "description": "Reference WebSocket client for the OpenClaw Gateway protocol",
5
5
  "keywords": [
6
6
  "client",
@@ -62,7 +62,7 @@
62
62
  }
63
63
  },
64
64
  "dependencies": {
65
- "@openclaw/gateway-protocol": "2026.10.5",
65
+ "@openclaw/gateway-protocol": "2026.10.10-beta.2",
66
66
  "ipaddr.js": "2.5.0",
67
67
  "ws": "8.22.0"
68
68
  },