@openclaw/gateway-client 2026.9.3 → 2026.9.4

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.
@@ -1,4 +1,4 @@
1
- import { A as readAssistantStreamSegmentIdentity, C as isSessionProjectionErrorMessage, D as SessionMessageEnvelope, E as reduceSessionProjectionRunEvent, F as buildDeviceAuthPayload, I as buildDeviceAuthPayloadV3, L as normalizeDeviceMetadataForAuth, M as readSessionMessageSequence, N as gatewayCredentialScope, O as SessionMessageIdentity, P as gatewayOriginScope, S as reduceSessionProjection, T as SessionProjectionRunTransition, _ as hasSessionProjectionAcceptedFinal, a as GatewaySessionMessageSubscriptionOptions, b as readSessionProjectionFinalMessageIdentity, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionRun, f as SessionProjectionRunStatus, g as createSessionProjection, h as SessionProjectionState, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as readSessionMessageIdentity, k as normalizeSessionProjectionRunId, l as SessionProjectionEntry, m as SessionProjectionSnapshotOptions, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionScope, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as isLocallyOptimisticSessionMessage, w as SessionProjectionGatewayRunEvent, x as reconcileSessionProjectionSnapshot, y as projectLiveSessionMessage } from "./session-subscriptions-C3M4jnCd.mjs";
1
+ import { A as readAssistantStreamSegmentIdentity, C as SessionProjectionRunTransition, D as SessionMessageEnvelope, E as readSessionProjectionFinalMessageIdentity, F as buildDeviceAuthPayload, I as buildDeviceAuthPayloadV3, L as normalizeDeviceMetadataForAuth, M as readSessionMessageSequence, N as gatewayCredentialScope, O as SessionMessageIdentity, P as gatewayOriginScope, S as SessionProjectionGatewayRunEvent, T as hasSessionProjectionAcceptedFinal, _ as isLocallyOptimisticSessionMessage, a as GatewaySessionMessageSubscriptionOptions, b as reduceSessionProjection, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionRun, f as SessionProjectionRunStatus, g as createSessionProjection, h as SessionProjectionState, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as readSessionMessageIdentity, k as normalizeSessionProjectionRunId, l as SessionProjectionEntry, m as SessionProjectionSnapshotOptions, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionScope, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as projectLiveSessionMessage, w as reduceSessionProjectionRunEvent, x as isSessionProjectionErrorMessage, y as reconcileSessionProjectionSnapshot } from "./session-subscriptions-BSQIANvX.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-DoPo-sPB.mjs";
3
3
  import { n as GatewayProtocolRequestOptions, r as GatewayProtocolRequestTimeoutError, t as GatewayProtocolRequestError } from "./protocol-request-B5gBmLgq.mjs";
4
4
  import { a as GatewayProtocolTiming, i as GatewayProtocolSocketHandlers, n as GatewayProtocolCloseContext, o as GatewayProtocolRequestTiming, r as GatewayProtocolSocket, t as GatewayProtocolClient } from "./protocol-client-DbX7wQED.mjs";
package/dist/browser.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as shouldRetryGatewayWithDeviceToken, D as buildGatewayConnectAuth, E as GatewayBrowserDeviceAuthLifecycle, M as buildDeviceAuthPayloadV3, N as normalizeDeviceMetadataForAuth, O as resolveGatewayConnectScopes, S as GatewayProtocolRequestTimeoutError, T as gatewayOriginScope, _ as readSessionMessageSequence, a as createSessionProjection, b as GatewayProtocolClient, c as projectLiveSessionMessage, d as reduceSessionProjection, f as reduceSessionProjectionRunEvent, g as readSessionMessageIdentity, h as readAssistantStreamSegmentIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as buildDeviceAuthPayload, k as selectGatewayConnectAuth, l as readSessionProjectionFinalMessageIdentity, m as normalizeSessionProjectionRunId, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as isSessionProjectionErrorMessage, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reconcileSessionProjectionSnapshot, w as gatewayCredentialScope, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect } from "./session-subscriptions-DwU8T0CH.mjs";
1
+ import { A as shouldRetryGatewayWithDeviceToken, D as buildGatewayConnectAuth, E as GatewayBrowserDeviceAuthLifecycle, M as buildDeviceAuthPayloadV3, N as normalizeDeviceMetadataForAuth, O as resolveGatewayConnectScopes, S as GatewayProtocolRequestTimeoutError, T as gatewayOriginScope, _ as readSessionMessageSequence, a as createSessionProjection, b as GatewayProtocolClient, c as reconcileSessionProjectionSnapshot, d as hasSessionProjectionAcceptedFinal, f as readSessionProjectionFinalMessageIdentity, g as readSessionMessageIdentity, h as readAssistantStreamSegmentIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as buildDeviceAuthPayload, k as selectGatewayConnectAuth, l as reduceSessionProjection, m as normalizeSessionProjectionRunId, n as getGatewaySessionMessageSubscriptionCoordinator, o as isLocallyOptimisticSessionMessage, p as isSessionProjectionErrorMessage, r as releaseGatewaySessionMessageSubscription, s as projectLiveSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reduceSessionProjectionRunEvent, w as gatewayCredentialScope, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect } from "./session-subscriptions-DIcpqS8A.mjs";
2
2
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
3
3
  export * from "@openclaw/gateway-protocol/connect-error-details";
4
4
  export * from "@openclaw/gateway-protocol/gateway-error-details";
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { A as readAssistantStreamSegmentIdentity, C as isSessionProjectionErrorMessage, D as SessionMessageEnvelope, E as reduceSessionProjectionRunEvent, F as buildDeviceAuthPayload, I as buildDeviceAuthPayloadV3, L as normalizeDeviceMetadataForAuth, M as readSessionMessageSequence, N as gatewayCredentialScope, O as SessionMessageIdentity, P as gatewayOriginScope, S as reduceSessionProjection, T as SessionProjectionRunTransition, _ as hasSessionProjectionAcceptedFinal, a as GatewaySessionMessageSubscriptionOptions, b as readSessionProjectionFinalMessageIdentity, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionRun, f as SessionProjectionRunStatus, g as createSessionProjection, h as SessionProjectionState, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as readSessionMessageIdentity, k as normalizeSessionProjectionRunId, l as SessionProjectionEntry, m as SessionProjectionSnapshotOptions, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionScope, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as isLocallyOptimisticSessionMessage, w as SessionProjectionGatewayRunEvent, x as reconcileSessionProjectionSnapshot, y as projectLiveSessionMessage } from "./session-subscriptions-C3M4jnCd.mjs";
1
+ import { A as readAssistantStreamSegmentIdentity, C as SessionProjectionRunTransition, D as SessionMessageEnvelope, E as readSessionProjectionFinalMessageIdentity, F as buildDeviceAuthPayload, I as buildDeviceAuthPayloadV3, L as normalizeDeviceMetadataForAuth, M as readSessionMessageSequence, N as gatewayCredentialScope, O as SessionMessageIdentity, P as gatewayOriginScope, S as SessionProjectionGatewayRunEvent, T as hasSessionProjectionAcceptedFinal, _ as isLocallyOptimisticSessionMessage, a as GatewaySessionMessageSubscriptionOptions, b as reduceSessionProjection, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionRun, f as SessionProjectionRunStatus, g as createSessionProjection, h as SessionProjectionState, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as readSessionMessageIdentity, k as normalizeSessionProjectionRunId, l as SessionProjectionEntry, m as SessionProjectionSnapshotOptions, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionScope, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as projectLiveSessionMessage, w as reduceSessionProjectionRunEvent, x as isSessionProjectionErrorMessage, y as reconcileSessionProjectionSnapshot } from "./session-subscriptions-BSQIANvX.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-DoPo-sPB.mjs";
3
3
  import { i as isGatewayProtocolResponseError } from "./protocol-request-B5gBmLgq.mjs";
4
4
  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";
5
- import { _ as GatewayClientRequestTimeoutError, a as startGatewayClientWithReadinessWait, b as GatewayClientRequestError, c as waitForEventLoopReady, d as GatewayClient, f as GatewayClientCloseInfo, g as GatewayClientRequestOptions, h as GatewayClientOptions, i as startGatewayClientWhenEventLoopReady, l as DeviceAuthTokenRecord, m as GatewayClientHostDeps, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientConnectionMetadata, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as DeviceIdentity, v as GatewayReconnectPausedInfo, y as isGatewayConnectAssemblyError } from "./readiness-uQKoJkl5.mjs";
5
+ import { _ as GatewayClientRequestTimeoutError, a as startGatewayClientWithReadinessWait, b as GatewayClientRequestError, c as waitForEventLoopReady, d as GatewayClient, f as GatewayClientCloseInfo, g as GatewayClientRequestOptions, h as GatewayClientOptions, i as startGatewayClientWhenEventLoopReady, l as DeviceAuthTokenRecord, m as GatewayClientHostDeps, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientConnectionMetadata, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as DeviceIdentity, v as GatewayReconnectPausedInfo, y as isGatewayConnectAssemblyError } from "./readiness-DabX0O0A.mjs";
6
6
  import { GatewayScopeUpgrade, ScopeUpgradeBinding, ScopeUpgradeOptions, ScopeUpgradeOutcome } from "./scope-upgrade.mjs";
7
7
  //#region packages/gateway-client/src/cloudflare-access.d.ts
8
8
  export declare const CF_ACCESS_CLIENT_ID_HEADER = "CF-Access-Client-Id";
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as shouldRetryGatewayWithDeviceToken, C as isGatewayProtocolResponseError, D as buildGatewayConnectAuth, E as GatewayBrowserDeviceAuthLifecycle, M as buildDeviceAuthPayloadV3, N as normalizeDeviceMetadataForAuth, O as resolveGatewayConnectScopes, S as GatewayProtocolRequestTimeoutError, T as gatewayOriginScope, _ as readSessionMessageSequence, a as createSessionProjection, b as GatewayProtocolClient, c as projectLiveSessionMessage, d as reduceSessionProjection, f as reduceSessionProjectionRunEvent, g as readSessionMessageIdentity, h as readAssistantStreamSegmentIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as buildDeviceAuthPayload, k as selectGatewayConnectAuth, l as readSessionProjectionFinalMessageIdentity, m as normalizeSessionProjectionRunId, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as isSessionProjectionErrorMessage, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reconcileSessionProjectionSnapshot, v as isRecord, w as gatewayCredentialScope, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect } from "./session-subscriptions-DwU8T0CH.mjs";
1
+ import { A as shouldRetryGatewayWithDeviceToken, C as isGatewayProtocolResponseError, D as buildGatewayConnectAuth, E as GatewayBrowserDeviceAuthLifecycle, M as buildDeviceAuthPayloadV3, N as normalizeDeviceMetadataForAuth, O as resolveGatewayConnectScopes, S as GatewayProtocolRequestTimeoutError, T as gatewayOriginScope, _ as readSessionMessageSequence, a as createSessionProjection, b as GatewayProtocolClient, c as reconcileSessionProjectionSnapshot, d as hasSessionProjectionAcceptedFinal, f as readSessionProjectionFinalMessageIdentity, g as readSessionMessageIdentity, h as readAssistantStreamSegmentIdentity, i as resetGatewaySessionMessageSubscriptionCoordinator, j as buildDeviceAuthPayload, k as selectGatewayConnectAuth, l as reduceSessionProjection, m as normalizeSessionProjectionRunId, n as getGatewaySessionMessageSubscriptionCoordinator, o as isLocallyOptimisticSessionMessage, p as isSessionProjectionErrorMessage, r as releaseGatewaySessionMessageSubscription, s as projectLiveSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reduceSessionProjectionRunEvent, v as isRecord, w as gatewayCredentialScope, x as GatewayProtocolRequestError, y as shouldPauseGatewayReconnect } from "./session-subscriptions-DIcpqS8A.mjs";
2
2
  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";
3
3
  import { rawDataToString } from "./websocket-data.mjs";
4
4
  import { n as startGatewayClientWithReadinessWait, r as waitForEventLoopReady, t as startGatewayClientWhenEventLoopReady } from "./readiness-CrWxd4TI.mjs";
@@ -744,6 +744,11 @@ var GatewayClient = class {
744
744
  rethrowSocketFactoryError: (error) => error instanceof GatewayClientTransportPolicyError
745
745
  });
746
746
  }
747
+ /** Current transport state, including CLOSING before the close callback fires.
748
+ * This is not authentication or readiness evidence on its own. */
749
+ get connected() {
750
+ return !this.stopped && this.protocol.connected;
751
+ }
747
752
  getConnectionMetadata() {
748
753
  return {
749
754
  clientName: this.opts.clientName,
@@ -152,6 +152,9 @@ declare class GatewayClient {
152
152
  private transportValidated;
153
153
  private suppressedTransientPreHelloCleanCloses;
154
154
  constructor(opts: GatewayClientOptions);
155
+ /** Current transport state, including CLOSING before the close callback fires.
156
+ * This is not authentication or readiness evidence on its own. */
157
+ get connected(): boolean;
155
158
  getConnectionMetadata(): GatewayClientConnectionMetadata;
156
159
  updateNodeManifest(manifest: {
157
160
  caps: string[];
@@ -1,2 +1,2 @@
1
- import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-uQKoJkl5.mjs";
1
+ import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-DabX0O0A.mjs";
2
2
  export { EventLoopReadyWaiter, GatewayClientStartReadinessOptions, GatewayClientStartable, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait };
@@ -57,6 +57,17 @@ declare function readAssistantStreamSegmentIdentity(message: unknown): {
57
57
  runId?: string;
58
58
  } | undefined;
59
59
  //#endregion
60
+ //#region packages/gateway-client/src/session-projection-final-identity.d.ts
61
+ type TerminalProjectionRun = {
62
+ message?: unknown;
63
+ status: string;
64
+ acceptedFinalMessageIdentities?: readonly string[];
65
+ };
66
+ /** Read stable persisted identity first, falling back to canonical display content. */
67
+ declare function readSessionProjectionFinalMessageIdentity(message: unknown): string | null;
68
+ /** Check whether a run has already accepted the same terminal reply. */
69
+ declare function hasSessionProjectionAcceptedFinal(run: TerminalProjectionRun | undefined, message: unknown): boolean;
70
+ //#endregion
60
71
  //#region packages/gateway-client/src/session-projection-run-event.d.ts
61
72
  type SessionProjectionGatewayRunEvent = {
62
73
  state?: unknown;
@@ -93,6 +104,10 @@ type SessionProjectionRun = {
93
104
  status: SessionProjectionRunStatus;
94
105
  message?: unknown;
95
106
  acceptedFinalMessageIdentities?: readonly string[];
107
+ inferredSnapshotTerminal?: {
108
+ entry: SessionProjectionEntry;
109
+ matchedIdentity: SessionMessageIdentity;
110
+ };
96
111
  stopReason?: string;
97
112
  errorKind?: string;
98
113
  errorMessage?: string;
@@ -157,9 +172,6 @@ declare function createSessionProjection(scope?: SessionProjectionScope, message
157
172
  declare function projectLiveSessionMessage(state: SessionProjectionState, message: unknown, envelope?: SessionMessageEnvelope, scope?: SessionProjectionScope): SessionProjectionState;
158
173
  /** Only observed live events and this client's pending turns may survive an older snapshot. */
159
174
  declare function reconcileSessionProjectionSnapshot(state: SessionProjectionState, messages: readonly unknown[], scope?: SessionProjectionScope, options?: SessionProjectionSnapshotOptions): SessionProjectionState;
160
- declare function readSessionProjectionFinalMessageIdentity(message: unknown): string | null;
161
- /** Replayed finals are recognized against this run's bounded canonical terminal history. */
162
- declare function hasSessionProjectionAcceptedFinal(run: SessionProjectionRun | undefined, message: unknown): boolean;
163
175
  /** Reduces durable events, snapshots, and transport lifecycle without client-specific policy. */
164
176
  declare function reduceSessionProjection(state: SessionProjectionState, event: SessionProjectionEvent): SessionProjectionState;
165
177
  //#endregion
@@ -197,4 +209,4 @@ declare function getGatewaySessionMessageSubscriptionCoordinator(client: Gateway
197
209
  declare function resetGatewaySessionMessageSubscriptionCoordinator(client: GatewaySessionMessageRequestClient): void;
198
210
  declare function releaseGatewaySessionMessageSubscription(subscription: GatewaySessionMessageSubscription): Promise<void>;
199
211
  //#endregion
200
- export { readAssistantStreamSegmentIdentity as A, isSessionProjectionErrorMessage as C, SessionMessageEnvelope as D, reduceSessionProjectionRunEvent as E, buildDeviceAuthPayload as F, buildDeviceAuthPayloadV3 as I, normalizeDeviceMetadataForAuth as L, readSessionMessageSequence as M, gatewayCredentialScope as N, SessionMessageIdentity as O, gatewayOriginScope as P, reduceSessionProjection as S, SessionProjectionRunTransition as T, hasSessionProjectionAcceptedFinal as _, GatewaySessionMessageSubscriptionOptions as a, readSessionProjectionFinalMessageIdentity as b, resetGatewaySessionMessageSubscriptionCoordinator as c, SessionProjectionRun as d, SessionProjectionRunStatus as f, createSessionProjection as g, SessionProjectionState as h, GatewaySessionMessageSubscriptionCoordinatorOptions as i, readSessionMessageIdentity as j, normalizeSessionProjectionRunId as k, SessionProjectionEntry as l, SessionProjectionSnapshotOptions as m, GatewaySessionMessageSubscription as n, getGatewaySessionMessageSubscriptionCoordinator as o, SessionProjectionScope as p, GatewaySessionMessageSubscriptionCoordinator as r, releaseGatewaySessionMessageSubscription as s, GatewaySessionMessageRequestClient as t, SessionProjectionEvent as u, isLocallyOptimisticSessionMessage as v, SessionProjectionGatewayRunEvent as w, reconcileSessionProjectionSnapshot as x, projectLiveSessionMessage as y };
212
+ export { readAssistantStreamSegmentIdentity as A, SessionProjectionRunTransition as C, SessionMessageEnvelope as D, readSessionProjectionFinalMessageIdentity as E, buildDeviceAuthPayload as F, buildDeviceAuthPayloadV3 as I, normalizeDeviceMetadataForAuth as L, readSessionMessageSequence as M, gatewayCredentialScope as N, SessionMessageIdentity as O, gatewayOriginScope as P, SessionProjectionGatewayRunEvent as S, hasSessionProjectionAcceptedFinal as T, isLocallyOptimisticSessionMessage as _, GatewaySessionMessageSubscriptionOptions as a, reduceSessionProjection as b, resetGatewaySessionMessageSubscriptionCoordinator as c, SessionProjectionRun as d, SessionProjectionRunStatus as f, createSessionProjection as g, SessionProjectionState as h, GatewaySessionMessageSubscriptionCoordinatorOptions as i, readSessionMessageIdentity as j, normalizeSessionProjectionRunId as k, SessionProjectionEntry as l, SessionProjectionSnapshotOptions as m, GatewaySessionMessageSubscription as n, getGatewaySessionMessageSubscriptionCoordinator as o, SessionProjectionScope as p, GatewaySessionMessageSubscriptionCoordinator as r, releaseGatewaySessionMessageSubscription as s, GatewaySessionMessageRequestClient as t, SessionProjectionEvent as u, projectLiveSessionMessage as v, reduceSessionProjectionRunEvent as w, isSessionProjectionErrorMessage as x, reconcileSessionProjectionSnapshot as y };
@@ -1032,6 +1032,66 @@ function asNullableRecord(value) {
1032
1032
  return isRecord(value) ? value : null;
1033
1033
  }
1034
1034
  //#endregion
1035
+ //#region packages/normalization-core/src/stable-stringify.ts
1036
+ const preserveString = (value) => value;
1037
+ /** Deterministically stringifies values, optionally normalizing strings before key ordering. */
1038
+ function stableStringify(value, normalizeString = preserveString) {
1039
+ return stringifyStableValue(value, /* @__PURE__ */ new WeakSet(), normalizeString);
1040
+ }
1041
+ function stringifyStableValue(value, stack, normalizeString) {
1042
+ if (value === null || value === void 0) return String(value);
1043
+ if (typeof value === "number" && !Number.isFinite(value)) return JSON.stringify(String(value));
1044
+ if (typeof value === "bigint") return JSON.stringify(value.toString());
1045
+ if (typeof value === "string") return JSON.stringify(normalizeString(value));
1046
+ if (typeof value !== "object") return JSON.stringify(value) ?? "null";
1047
+ if (stack.has(value)) return JSON.stringify("[Circular]");
1048
+ stack.add(value);
1049
+ try {
1050
+ return stringifyObjectValue(value, stack, normalizeString);
1051
+ } finally {
1052
+ stack.delete(value);
1053
+ }
1054
+ }
1055
+ function stringifyObjectValue(value, stack, normalizeString) {
1056
+ if (value instanceof Error) return stringifyStableValue({
1057
+ name: value.name,
1058
+ message: value.message,
1059
+ stack: value.stack
1060
+ }, stack, normalizeString);
1061
+ if (value instanceof Uint8Array) return stringifyStableValue({
1062
+ type: "Uint8Array",
1063
+ data: encodeBase64(value)
1064
+ }, stack, normalizeString);
1065
+ if (Array.isArray(value)) {
1066
+ const serializedEntries = [];
1067
+ for (const entry of value) serializedEntries.push(stringifyStableValue(entry, stack, normalizeString));
1068
+ return `[${serializedEntries.join(",")}]`;
1069
+ }
1070
+ const record = value;
1071
+ if (normalizeString === preserveString) {
1072
+ const fields = [];
1073
+ for (const key of Object.keys(record).toSorted()) fields.push(`${JSON.stringify(key)}:${stringifyStableValue(record[key], stack, normalizeString)}`);
1074
+ return `{${fields.join(",")}}`;
1075
+ }
1076
+ const entries = Object.keys(record).map((key) => ({
1077
+ key,
1078
+ normalizedKey: normalizeString(key)
1079
+ })).toSorted((left, right) => {
1080
+ return compareStableStrings(left.normalizedKey, right.normalizedKey) || compareStableStrings(left.key, right.key);
1081
+ });
1082
+ const serializedFields = [];
1083
+ for (const { key, normalizedKey } of entries) serializedFields.push(`${JSON.stringify(normalizedKey)}:${stringifyStableValue(record[key], stack, normalizeString)}`);
1084
+ return `{${serializedFields.join(",")}}`;
1085
+ }
1086
+ function encodeBase64(value) {
1087
+ let binary = "";
1088
+ for (const byte of value) binary += String.fromCharCode(byte);
1089
+ return btoa(binary);
1090
+ }
1091
+ function compareStableStrings(left, right) {
1092
+ return left < right ? -1 : left > right ? 1 : 0;
1093
+ }
1094
+ //#endregion
1035
1095
  //#region packages/gateway-client/src/session-projection-message-identity.ts
1036
1096
  function readSessionProjectionString(value) {
1037
1097
  return typeof value === "string" ? value.trim() || null : null;
@@ -1057,6 +1117,9 @@ function readSessionMessageIdentity(message, envelope) {
1057
1117
  const importedFrom = readSessionProjectionString(metadata?.importedFrom);
1058
1118
  const cliSessionId = readSessionProjectionString(metadata?.cliSessionId);
1059
1119
  const externalId = readSessionProjectionString(metadata?.externalId);
1120
+ const position = asNullableRecord(metadata?.transcriptPosition);
1121
+ const positionSource = readSessionProjectionString(position?.source);
1122
+ const isImported = !(positionSource !== null && positionSource.length <= 128 && typeof position?.rawSeq === "number" && Number.isSafeInteger(position.rawSeq) && position.rawSeq >= 0) && Boolean(importedFrom || cliSessionId || externalId);
1060
1123
  const idempotencyKey = readSessionProjectionString(metadata?.idempotencyKey) ?? readSessionProjectionString(record.idempotencyKey) ?? readSessionProjectionString(envelope?.idempotencyKey) ?? readSessionProjectionString(envelope?.clientRunId);
1061
1124
  const persistedRunId = normalizeSessionProjectionRunId(idempotencyKey);
1062
1125
  const envelopeRunId = normalizeSessionProjectionRunId(envelope?.runId);
@@ -1073,8 +1136,8 @@ function readSessionMessageIdentity(message, envelope) {
1073
1136
  idempotencyKey,
1074
1137
  sendId: role === "user" ? persistedRunId ?? runId : null,
1075
1138
  runId,
1076
- isImported: Boolean(importedFrom || cliSessionId || externalId),
1077
- externalSource: importedFrom && cliSessionId && externalId ? JSON.stringify([
1139
+ isImported,
1140
+ externalSource: isImported && importedFrom && cliSessionId && externalId ? JSON.stringify([
1078
1141
  importedFrom,
1079
1142
  cliSessionId,
1080
1143
  externalId
@@ -1117,6 +1180,11 @@ function readSessionMessageDisplayContent(message) {
1117
1180
  usesFallbackText: fallback !== null
1118
1181
  };
1119
1182
  }
1183
+ /** Check whether a projected message has text or another displayable block. */
1184
+ function hasDisplayableSessionMessage(message) {
1185
+ const { text, hasNonText } = readSessionMessageDisplayContent(message);
1186
+ return Boolean(text) || hasNonText;
1187
+ }
1120
1188
  function normalizeChatErrorComparisonText(text) {
1121
1189
  return text.trim().replace(/^⚠️\s*/u, "").replace(/^Error:\s*/iu, "").replace(/\s+/gu, " ").trim();
1122
1190
  }
@@ -1129,6 +1197,111 @@ function isSessionProjectionErrorMessage(message, errorMessage) {
1129
1197
  return !hasNonText && (!normalizedText || normalizedText === "[assistant turn failed before producing content]" || normalizedText === GATEWAY_ASSISTANT_ERROR_FALLBACK_TEXT || normalizedText === normalizeChatErrorComparisonText(errorMessage ?? ""));
1130
1198
  }
1131
1199
  //#endregion
1200
+ //#region packages/gateway-client/src/session-projection-final-identity.ts
1201
+ /** Terminal identity rules used to reconcile live and durable assistant projections. */
1202
+ function readPersistedFinalIdentity(message) {
1203
+ const identity = readSessionMessageIdentity(message);
1204
+ if (identity?.externalSource) return `import:${identity.role}:${identity.externalSource}`;
1205
+ if (identity?.id && !identity.isImported) return `id:${identity.role}:${identity.id}`;
1206
+ if (identity?.sequence !== null && identity?.sequence !== void 0) return `seq:${identity.role}:${identity.sequence}`;
1207
+ return null;
1208
+ }
1209
+ function hasCompatiblePersistedFinalIdentity(currentMessage, incomingMessage) {
1210
+ const current = readSessionMessageIdentity(currentMessage);
1211
+ const incoming = readSessionMessageIdentity(incomingMessage);
1212
+ if (!current || !incoming || current.role !== incoming.role) return false;
1213
+ if (current.isImported || incoming.isImported) {
1214
+ if (!current.isImported || !incoming.isImported) return false;
1215
+ if (current.externalSource && incoming.externalSource) return current.externalSource === incoming.externalSource;
1216
+ return current.sequence !== null && incoming.sequence !== null && current.sequence === incoming.sequence;
1217
+ }
1218
+ if (current.id && incoming.id) return current.id === incoming.id;
1219
+ return current.sequence !== null && incoming.sequence !== null && current.sequence === incoming.sequence;
1220
+ }
1221
+ function readFinalContentIdentity(message) {
1222
+ const display = readSessionMessageDisplayContent(message);
1223
+ if (!display.text && !display.hasNonText) return null;
1224
+ const identity = readSessionMessageIdentity(message);
1225
+ const record = asNullableRecord(message);
1226
+ const metadata = asNullableRecord(record?.["__openclaw"]);
1227
+ try {
1228
+ return `content:${stableStringify([
1229
+ identity?.role ?? "assistant",
1230
+ display.text,
1231
+ display.hasNonText ? record?.content ?? null : null,
1232
+ metadata?.media ?? null,
1233
+ identity?.isImported ? [
1234
+ metadata?.importedFrom ?? null,
1235
+ metadata?.cliSessionId ?? null,
1236
+ metadata?.externalId ?? null
1237
+ ] : null
1238
+ ])}`;
1239
+ } catch {
1240
+ return null;
1241
+ }
1242
+ }
1243
+ function hasTerminalStopReason(message) {
1244
+ const stopReason = asNullableRecord(message)?.stopReason;
1245
+ return stopReason === "stop" || stopReason === "length" || stopReason === "error" || stopReason === "aborted" || stopReason === "end_turn";
1246
+ }
1247
+ function hasCompletedRunSnapshotContext(entry, snapshot, runId) {
1248
+ if (!runId || entry.identity?.runId !== runId) return false;
1249
+ const entryIndex = snapshot.indexOf(entry);
1250
+ if (entryIndex < 0) return false;
1251
+ const hasEarlierUser = snapshot.slice(0, entryIndex).some((candidate) => candidate.identity?.role === "user" && candidate.identity.runId === runId);
1252
+ const hasLaterAssistant = snapshot.slice(entryIndex + 1).some((candidate) => candidate.identity?.role === "assistant" && candidate.identity.runId === runId);
1253
+ return hasEarlierUser && !hasLaterAssistant;
1254
+ }
1255
+ /** Read stable persisted identity first, falling back to canonical display content. */
1256
+ function readSessionProjectionFinalMessageIdentity(message) {
1257
+ if (!hasDisplayableSessionMessage(message)) return null;
1258
+ return readPersistedFinalIdentity(message) ?? readFinalContentIdentity(message);
1259
+ }
1260
+ /** Check whether a displayable terminal may recover a prior empty terminal. */
1261
+ function canRecoverSessionProjectionFinal(currentMessage, incomingMessage) {
1262
+ if (hasDisplayableSessionMessage(currentMessage)) return false;
1263
+ return readPersistedFinalIdentity(currentMessage) === null || hasCompatiblePersistedFinalIdentity(currentMessage, incomingMessage);
1264
+ }
1265
+ /** Check whether a run has already accepted the same terminal reply. */
1266
+ function hasSessionProjectionAcceptedFinal(run, message) {
1267
+ const identity = readSessionProjectionFinalMessageIdentity(message);
1268
+ return Boolean(identity && run && (run.acceptedFinalMessageIdentities?.includes(identity) || readSessionProjectionFinalMessageIdentity(run.message) === identity));
1269
+ }
1270
+ /** Match an unsequenced live terminal to exactly one durable same-run terminal row. */
1271
+ function findUniqueSnapshotTerminalMatch(current, matches, run, snapshot) {
1272
+ if (!current.live || current.identity?.role !== "assistant" || current.identity.id || current.identity.sequence !== null || !run || run.status === "streaming") return null;
1273
+ const terminalContent = readFinalContentIdentity(current.message);
1274
+ if (!terminalContent || readFinalContentIdentity(run.message) !== terminalContent) return null;
1275
+ const durableTerminalMatches = matches.filter((entry) => {
1276
+ return (asNullableRecord(asNullableRecord(entry.message)?.["__openclaw"])?.runTerminal === true || entry.identity?.runId === current.identity?.runId && hasTerminalStopReason(entry.message) || hasCompletedRunSnapshotContext(entry, snapshot, current.identity?.runId ?? null)) && readFinalContentIdentity(entry.message) === terminalContent;
1277
+ });
1278
+ const entry = durableTerminalMatches.length === 1 ? durableTerminalMatches[0] : void 0;
1279
+ if (!entry) return null;
1280
+ return {
1281
+ entry,
1282
+ inferred: asNullableRecord(asNullableRecord(entry.message)?.["__openclaw"])?.runTerminal !== true && !hasTerminalStopReason(entry.message)
1283
+ };
1284
+ }
1285
+ /** Check whether ordinary single-match promotion needs terminal-content verification. */
1286
+ function isUnsequencedLiveTerminal(current, run) {
1287
+ 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));
1288
+ }
1289
+ //#endregion
1290
+ //#region packages/gateway-client/src/session-projection-run-retention.ts
1291
+ /** Bounded retention for completed and active session projection runs. */
1292
+ const MAX_TRACKED_SESSION_RUNS = 200;
1293
+ const RETAINED_SESSION_RUNS = 150;
1294
+ /** Retain every active run and the newest completed runs within the projection bound. */
1295
+ function retainSessionProjectionRuns(runs) {
1296
+ const entries = Object.entries(runs);
1297
+ if (entries.length <= MAX_TRACKED_SESSION_RUNS) return runs;
1298
+ const active = entries.filter(([, run]) => run.status === "streaming");
1299
+ const terminal = entries.filter(([, run]) => run.status !== "streaming");
1300
+ const terminalLimit = Math.max(0, RETAINED_SESSION_RUNS - active.length);
1301
+ const retainedTerminal = terminalLimit > 0 ? terminal.slice(-terminalLimit) : [];
1302
+ return Object.fromEntries([...active, ...retainedTerminal]);
1303
+ }
1304
+ //#endregion
1132
1305
  //#region packages/gateway-client/src/session-projection-run-event.ts
1133
1306
  function readNonemptyString(value) {
1134
1307
  return typeof value === "string" ? value.trim() || null : null;
@@ -1172,8 +1345,6 @@ function reduceSessionProjectionRunEvent(projection, event, scope = {}) {
1172
1345
  //#endregion
1173
1346
  //#region packages/gateway-client/src/session-projection.ts
1174
1347
  /** Browser-safe identity and replay rules shared by Gateway conversation clients. */
1175
- const MAX_TRACKED_SESSION_RUNS = 200;
1176
- const RETAINED_SESSION_RUNS = 150;
1177
1348
  const SESSION_PROJECTION_SCOPE_KEYS = [
1178
1349
  "sessionKey",
1179
1350
  "sessionId",
@@ -1327,12 +1498,39 @@ function reconcileSessionProjectionSnapshot(state, messages, scope = {}, options
1327
1498
  const visibleMessages = options.shouldIncludeMessage ? messages.filter(options.shouldIncludeMessage) : messages;
1328
1499
  if (!scopesMatch(state.scope, scope)) return createSessionProjection(scope, visibleMessages);
1329
1500
  let entries = createProjectionEntries(visibleMessages);
1501
+ const runs = { ...state.runs };
1330
1502
  for (const current of state.entries) {
1331
- if (!current.live && !current.pending || options.shouldIncludeMessage?.(current.message) === false || entries.filter((entry) => entryMatches(entry, current, true)).length === 1) continue;
1332
- entries = insertEntry(entries, current, state.runs);
1503
+ if (!current.live && !current.pending || options.shouldIncludeMessage?.(current.message) === false) continue;
1504
+ const matches = entries.filter((entry) => entryMatches(entry, current, true));
1505
+ const run = current.identity?.runId ? runs[current.identity.runId] : void 0;
1506
+ const terminalMatch = findUniqueSnapshotTerminalMatch(current, matches, run, entries);
1507
+ if (matches.length === 1 && !isUnsequencedLiveTerminal(current, run) || terminalMatch) {
1508
+ if (terminalMatch?.inferred && terminalMatch.entry.identity && current.identity?.runId && run) runs[current.identity.runId] = {
1509
+ ...run,
1510
+ inferredSnapshotTerminal: {
1511
+ entry: current,
1512
+ matchedIdentity: terminalMatch.entry.identity
1513
+ }
1514
+ };
1515
+ continue;
1516
+ }
1517
+ entries = insertEntry(entries, current, runs);
1518
+ }
1519
+ for (const [runId, run] of Object.entries(runs)) {
1520
+ const inferred = run.inferredSnapshotTerminal;
1521
+ if (!inferred) continue;
1522
+ const candidateRemains = entries.some((entry) => sameTranscriptIdentity(entry.identity, inferred.matchedIdentity));
1523
+ const visible = options.shouldIncludeMessage?.(inferred.entry.message) !== false;
1524
+ const matches = entries.filter((entry) => entryMatches(entry, inferred.entry, true));
1525
+ const terminalMatch = findUniqueSnapshotTerminalMatch(inferred.entry, matches, run, entries);
1526
+ if (candidateRemains && visible && terminalMatch?.inferred) continue;
1527
+ if (candidateRemains && visible && !terminalMatch) entries = insertEntry(entries, inferred.entry, runs);
1528
+ const { inferredSnapshotTerminal: _inferred, ...settledRun } = run;
1529
+ runs[runId] = settledRun;
1333
1530
  }
1334
1531
  return {
1335
1532
  ...withEntries(state, entries),
1533
+ runs,
1336
1534
  scope: {
1337
1535
  ...state.scope,
1338
1536
  ...scope
@@ -1340,49 +1538,6 @@ function reconcileSessionProjectionSnapshot(state, messages, scope = {}, options
1340
1538
  hasTransportGap: false
1341
1539
  };
1342
1540
  }
1343
- function hasDisplayableSessionMessage(message) {
1344
- const { text, hasNonText } = readSessionMessageDisplayContent(message);
1345
- return Boolean(text) || hasNonText;
1346
- }
1347
- function readSessionProjectionFinalMessageIdentity(message) {
1348
- const display = readSessionMessageDisplayContent(message);
1349
- if (!display.text && !display.hasNonText) return null;
1350
- const identity = readSessionMessageIdentity(message);
1351
- if (identity?.externalSource) return `import:${identity.role}:${identity.externalSource}`;
1352
- if (identity?.id && !identity.isImported) return `id:${identity.role}:${identity.id}`;
1353
- if (identity?.sequence !== null && identity?.sequence !== void 0) return `seq:${identity.role}:${identity.sequence}`;
1354
- const record = asNullableRecord(message);
1355
- const metadata = asNullableRecord(record?.["__openclaw"]);
1356
- try {
1357
- return `content:${JSON.stringify([
1358
- identity?.role ?? "assistant",
1359
- typeof message === "string" ? message : record?.content ?? null,
1360
- metadata?.media ?? null,
1361
- identity?.isImported ? [
1362
- metadata?.importedFrom ?? null,
1363
- metadata?.cliSessionId ?? null,
1364
- metadata?.externalId ?? null
1365
- ] : null,
1366
- ...display.usesFallbackText ? [record?.text] : []
1367
- ])}`;
1368
- } catch {
1369
- return null;
1370
- }
1371
- }
1372
- /** Replayed finals are recognized against this run's bounded canonical terminal history. */
1373
- function hasSessionProjectionAcceptedFinal(run, message) {
1374
- const identity = readSessionProjectionFinalMessageIdentity(message);
1375
- return Boolean(identity && run && (run.acceptedFinalMessageIdentities?.includes(identity) || readSessionProjectionFinalMessageIdentity(run.message) === identity));
1376
- }
1377
- function retainSessionProjectionRuns(runs) {
1378
- const entries = Object.entries(runs);
1379
- if (entries.length <= MAX_TRACKED_SESSION_RUNS) return runs;
1380
- const active = entries.filter(([, run]) => run.status === "streaming");
1381
- const terminal = entries.filter(([, run]) => run.status !== "streaming");
1382
- const terminalLimit = Math.max(0, RETAINED_SESSION_RUNS - active.length);
1383
- const retainedTerminal = terminalLimit > 0 ? terminal.slice(-terminalLimit) : [];
1384
- return Object.fromEntries([...active, ...retainedTerminal]);
1385
- }
1386
1541
  function updateRun(state, incoming) {
1387
1542
  const incomingErrorMessage = readSessionProjectionString(incoming.errorMessage);
1388
1543
  const incomingSeq = typeof incoming.seq === "number" && Number.isSafeInteger(incoming.seq) && incoming.seq >= 0 ? incoming.seq : void 0;
@@ -1397,9 +1552,10 @@ function updateRun(state, incoming) {
1397
1552
  if (current && current.status !== "streaming" && !resumesErrorProjection) {
1398
1553
  const incomingFinalIdentity = readSessionProjectionFinalMessageIdentity(incoming.message);
1399
1554
  const incomingIsFinal = incoming.status === "completed" || incoming.status === "yielded";
1400
- const canRecoverFinal = !hasDisplayableSessionMessage(current.message) || (current.acceptedFinalMessageIdentities?.length ?? 0) > 0;
1401
- const acceptFinal = incomingIsFinal && (current.status === incoming.status || canRecoverFinal) && incomingFinalIdentity !== null && !hasSessionProjectionAcceptedFinal(current, incoming.message);
1402
- const recoverMessage = acceptFinal && !hasDisplayableSessionMessage(current.message);
1555
+ const currentHasDisplayableMessage = hasDisplayableSessionMessage(current.message);
1556
+ const canAcceptFinal = currentHasDisplayableMessage ? current.status === incoming.status || (current.acceptedFinalMessageIdentities?.length ?? 0) > 0 : canRecoverSessionProjectionFinal(current.message, incoming.message);
1557
+ const acceptFinal = incomingIsFinal && canAcceptFinal && incomingFinalIdentity !== null && !hasSessionProjectionAcceptedFinal(current, incoming.message);
1558
+ const recoverMessage = acceptFinal && !currentHasDisplayableMessage;
1403
1559
  const recoverError = readSessionProjectionString(current.errorMessage) === null && incomingErrorMessage !== null;
1404
1560
  const updateTerminalSequence = incoming.status !== "streaming" && (incomingSeq === void 0 ? current.seq !== void 0 : current.seq === void 0 || incomingSeq > current.seq);
1405
1561
  if (!acceptFinal && !recoverError && !updateTerminalSequence) return state;
@@ -1727,4 +1883,4 @@ function releaseGatewaySessionMessageSubscription(subscription) {
1727
1883
  return sessionMessageSubscriptionOwners.get(subscription)?.coordinator.release(subscription) ?? Promise.resolve();
1728
1884
  }
1729
1885
  //#endregion
1730
- export { shouldRetryGatewayWithDeviceToken as A, isGatewayProtocolResponseError as C, buildGatewayConnectAuth as D, GatewayBrowserDeviceAuthLifecycle as E, buildDeviceAuthPayloadV3 as M, normalizeDeviceMetadataForAuth as N, resolveGatewayConnectScopes as O, GatewayProtocolRequestTimeoutError as S, gatewayOriginScope as T, readSessionMessageSequence as _, createSessionProjection as a, GatewayProtocolClient as b, projectLiveSessionMessage as c, reduceSessionProjection as d, reduceSessionProjectionRunEvent as f, readSessionMessageIdentity as g, readAssistantStreamSegmentIdentity as h, resetGatewaySessionMessageSubscriptionCoordinator as i, buildDeviceAuthPayload as j, selectGatewayConnectAuth as k, readSessionProjectionFinalMessageIdentity as l, normalizeSessionProjectionRunId as m, getGatewaySessionMessageSubscriptionCoordinator as n, hasSessionProjectionAcceptedFinal as o, isSessionProjectionErrorMessage as p, releaseGatewaySessionMessageSubscription as r, isLocallyOptimisticSessionMessage as s, GatewaySessionMessageSubscriptionCoordinator as t, reconcileSessionProjectionSnapshot as u, isRecord as v, gatewayCredentialScope as w, GatewayProtocolRequestError as x, shouldPauseGatewayReconnect as y };
1886
+ export { shouldRetryGatewayWithDeviceToken as A, isGatewayProtocolResponseError as C, buildGatewayConnectAuth as D, GatewayBrowserDeviceAuthLifecycle as E, buildDeviceAuthPayloadV3 as M, normalizeDeviceMetadataForAuth as N, resolveGatewayConnectScopes as O, GatewayProtocolRequestTimeoutError as S, gatewayOriginScope as T, readSessionMessageSequence as _, createSessionProjection as a, GatewayProtocolClient as b, reconcileSessionProjectionSnapshot as c, hasSessionProjectionAcceptedFinal as d, readSessionProjectionFinalMessageIdentity as f, readSessionMessageIdentity as g, readAssistantStreamSegmentIdentity as h, resetGatewaySessionMessageSubscriptionCoordinator as i, buildDeviceAuthPayload as j, selectGatewayConnectAuth as k, reduceSessionProjection as l, normalizeSessionProjectionRunId as m, getGatewaySessionMessageSubscriptionCoordinator as n, isLocallyOptimisticSessionMessage as o, isSessionProjectionErrorMessage as p, releaseGatewaySessionMessageSubscription as r, projectLiveSessionMessage as s, GatewaySessionMessageSubscriptionCoordinator as t, reduceSessionProjectionRunEvent as u, isRecord as v, gatewayCredentialScope as w, GatewayProtocolRequestError as x, shouldPauseGatewayReconnect as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/gateway-client",
3
- "version": "2026.9.3",
3
+ "version": "2026.9.4",
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.9.3",
65
+ "@openclaw/gateway-protocol": "2026.9.4",
66
66
  "ipaddr.js": "2.5.0",
67
67
  "ws": "8.21.3"
68
68
  },