@openclaw/gateway-protocol 0.0.0 → 2026.7.2-beta.5
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/CHANGELOG.md +144 -0
- package/LICENSE +21 -0
- package/README.md +157 -2
- package/dist/client-info.d.mts +94 -0
- package/dist/client-info.mjs +82 -0
- package/dist/connect-error-details.d.mts +114 -0
- package/dist/connect-error-details.mjs +296 -0
- package/dist/frame-guards.d.mts +7 -0
- package/dist/frame-guards.mjs +26 -0
- package/dist/frames-DEn_IEne.d.mts +341 -0
- package/dist/gateway-error-details-Btc09cgL.d.mts +51 -0
- package/dist/gateway-error-details.d.mts +2 -0
- package/dist/gateway-error-details.mjs +67 -0
- package/dist/index.d.mts +3418 -0
- package/dist/index.mjs +441 -0
- package/dist/schema-modules-DpxvZ_Jx.d.mts +13395 -0
- package/dist/schema.d.mts +9783 -0
- package/dist/schema.mjs +758 -0
- package/dist/startup-unavailable.d.mts +23 -0
- package/dist/startup-unavailable.mjs +34 -0
- package/dist/version-COV9CEyr.d.mts +11 -0
- package/dist/version.d.mts +2 -0
- package/dist/version.mjs +11 -0
- package/dist/worktrees-CI-UANnD.mjs +9367 -0
- package/package.json +88 -6
- package/protocol.schema.json +69308 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
//#region src/connect-error-details.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared gateway connect-error detail helpers.
|
|
4
|
+
*
|
|
5
|
+
* These details cross client/server boundaries, so readers normalize untrusted
|
|
6
|
+
* payloads before using them in reconnect decisions or user-facing messages.
|
|
7
|
+
*/
|
|
8
|
+
function normalizeOptionalString(value) {
|
|
9
|
+
if (typeof value !== "string") return;
|
|
10
|
+
return value.trim() || void 0;
|
|
11
|
+
}
|
|
12
|
+
function normalizeArrayBackedTrimmedStringList(value) {
|
|
13
|
+
if (!Array.isArray(value)) return;
|
|
14
|
+
const values = value.map((entry) => normalizeOptionalString(entry)).filter((entry) => Boolean(entry));
|
|
15
|
+
return values.length > 0 ? values : void 0;
|
|
16
|
+
}
|
|
17
|
+
/** Structured connect-error codes carried in gateway error `details.code`. */
|
|
18
|
+
const ConnectErrorDetailCodes = {
|
|
19
|
+
AUTH_REQUIRED: "AUTH_REQUIRED",
|
|
20
|
+
AUTH_UNAUTHORIZED: "AUTH_UNAUTHORIZED",
|
|
21
|
+
AUTH_TOKEN_MISSING: "AUTH_TOKEN_MISSING",
|
|
22
|
+
AUTH_TOKEN_MISMATCH: "AUTH_TOKEN_MISMATCH",
|
|
23
|
+
AUTH_TOKEN_NOT_CONFIGURED: "AUTH_TOKEN_NOT_CONFIGURED",
|
|
24
|
+
AUTH_PASSWORD_MISSING: "AUTH_PASSWORD_MISSING",
|
|
25
|
+
AUTH_PASSWORD_MISMATCH: "AUTH_PASSWORD_MISMATCH",
|
|
26
|
+
AUTH_PASSWORD_NOT_CONFIGURED: "AUTH_PASSWORD_NOT_CONFIGURED",
|
|
27
|
+
AUTH_BOOTSTRAP_TOKEN_INVALID: "AUTH_BOOTSTRAP_TOKEN_INVALID",
|
|
28
|
+
AUTH_DEVICE_TOKEN_MISMATCH: "AUTH_DEVICE_TOKEN_MISMATCH",
|
|
29
|
+
AUTH_SCOPE_MISMATCH: "AUTH_SCOPE_MISMATCH",
|
|
30
|
+
AUTH_RATE_LIMITED: "AUTH_RATE_LIMITED",
|
|
31
|
+
AUTH_TAILSCALE_IDENTITY_MISSING: "AUTH_TAILSCALE_IDENTITY_MISSING",
|
|
32
|
+
AUTH_TAILSCALE_PROXY_MISSING: "AUTH_TAILSCALE_PROXY_MISSING",
|
|
33
|
+
AUTH_TAILSCALE_WHOIS_FAILED: "AUTH_TAILSCALE_WHOIS_FAILED",
|
|
34
|
+
AUTH_TAILSCALE_IDENTITY_MISMATCH: "AUTH_TAILSCALE_IDENTITY_MISMATCH",
|
|
35
|
+
CONTROL_UI_ORIGIN_NOT_ALLOWED: "CONTROL_UI_ORIGIN_NOT_ALLOWED",
|
|
36
|
+
PROTOCOL_MISMATCH: "PROTOCOL_MISMATCH",
|
|
37
|
+
CONTROL_UI_DEVICE_IDENTITY_REQUIRED: "CONTROL_UI_DEVICE_IDENTITY_REQUIRED",
|
|
38
|
+
DEVICE_IDENTITY_REQUIRED: "DEVICE_IDENTITY_REQUIRED",
|
|
39
|
+
DEVICE_AUTH_INVALID: "DEVICE_AUTH_INVALID",
|
|
40
|
+
DEVICE_AUTH_DEVICE_ID_MISMATCH: "DEVICE_AUTH_DEVICE_ID_MISMATCH",
|
|
41
|
+
DEVICE_AUTH_SIGNATURE_EXPIRED: "DEVICE_AUTH_SIGNATURE_EXPIRED",
|
|
42
|
+
DEVICE_AUTH_NONCE_REQUIRED: "DEVICE_AUTH_NONCE_REQUIRED",
|
|
43
|
+
DEVICE_AUTH_NONCE_MISMATCH: "DEVICE_AUTH_NONCE_MISMATCH",
|
|
44
|
+
DEVICE_AUTH_SIGNATURE_INVALID: "DEVICE_AUTH_SIGNATURE_INVALID",
|
|
45
|
+
DEVICE_AUTH_PUBLIC_KEY_INVALID: "DEVICE_AUTH_PUBLIC_KEY_INVALID",
|
|
46
|
+
PAIRING_REQUIRED: "PAIRING_REQUIRED",
|
|
47
|
+
CLIENT_VERSION_MISMATCH: "CLIENT_VERSION_MISMATCH"
|
|
48
|
+
};
|
|
49
|
+
/** Pairing-specific reasons clients can display and use for reconnect policy. */
|
|
50
|
+
const ConnectPairingRequiredReasons = {
|
|
51
|
+
NOT_PAIRED: "not-paired",
|
|
52
|
+
ROLE_UPGRADE: "role-upgrade",
|
|
53
|
+
SCOPE_UPGRADE: "scope-upgrade",
|
|
54
|
+
METADATA_UPGRADE: "metadata-upgrade"
|
|
55
|
+
};
|
|
56
|
+
const CONNECT_RECOVERY_NEXT_STEP_VALUES = /* @__PURE__ */ new Set([
|
|
57
|
+
"retry_with_device_token",
|
|
58
|
+
"update_auth_configuration",
|
|
59
|
+
"update_auth_credentials",
|
|
60
|
+
"wait_then_retry",
|
|
61
|
+
"review_auth_configuration"
|
|
62
|
+
]);
|
|
63
|
+
const CONNECT_PAIRING_REQUIRED_REASON_VALUES = /* @__PURE__ */ new Set([
|
|
64
|
+
"not-paired",
|
|
65
|
+
"role-upgrade",
|
|
66
|
+
"scope-upgrade",
|
|
67
|
+
"metadata-upgrade"
|
|
68
|
+
]);
|
|
69
|
+
const PAIRING_CONNECT_REQUEST_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
70
|
+
const PAIRING_CONNECT_REASON_METADATA = {
|
|
71
|
+
"not-paired": {
|
|
72
|
+
requirement: "device is not approved yet",
|
|
73
|
+
remediationHint: "Approve this device from the pending pairing requests.",
|
|
74
|
+
recoveryTitle: "Gateway pairing approval required."
|
|
75
|
+
},
|
|
76
|
+
"role-upgrade": {
|
|
77
|
+
requirement: "device is asking for a higher role than currently approved",
|
|
78
|
+
remediationHint: "Review the requested role upgrade, then approve the pending request.",
|
|
79
|
+
recoveryTitle: "Gateway role upgrade approval required."
|
|
80
|
+
},
|
|
81
|
+
"scope-upgrade": {
|
|
82
|
+
requirement: "device is asking for more scopes than currently approved",
|
|
83
|
+
remediationHint: "Review the requested scopes, then approve the pending upgrade.",
|
|
84
|
+
recoveryTitle: "Gateway scope upgrade approval required."
|
|
85
|
+
},
|
|
86
|
+
"metadata-upgrade": {
|
|
87
|
+
requirement: "device identity changed and must be re-approved",
|
|
88
|
+
remediationHint: "Review the refreshed device details, then approve the pending request.",
|
|
89
|
+
recoveryTitle: "Gateway device refresh approval required."
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const CONNECT_PAIRING_REQUIRED_MESSAGE_BY_REASON = {
|
|
93
|
+
"not-paired": "device pairing required",
|
|
94
|
+
"role-upgrade": "role upgrade pending approval",
|
|
95
|
+
"scope-upgrade": "scope upgrade pending approval",
|
|
96
|
+
"metadata-upgrade": "device metadata change pending approval"
|
|
97
|
+
};
|
|
98
|
+
/** Maps internal auth failure reasons to public connect-error detail codes. */
|
|
99
|
+
function resolveAuthConnectErrorDetailCode(reason) {
|
|
100
|
+
switch (reason) {
|
|
101
|
+
case "token_missing": return ConnectErrorDetailCodes.AUTH_TOKEN_MISSING;
|
|
102
|
+
case "token_mismatch": return ConnectErrorDetailCodes.AUTH_TOKEN_MISMATCH;
|
|
103
|
+
case "token_missing_config": return ConnectErrorDetailCodes.AUTH_TOKEN_NOT_CONFIGURED;
|
|
104
|
+
case "password_missing": return ConnectErrorDetailCodes.AUTH_PASSWORD_MISSING;
|
|
105
|
+
case "password_mismatch": return ConnectErrorDetailCodes.AUTH_PASSWORD_MISMATCH;
|
|
106
|
+
case "password_missing_config": return ConnectErrorDetailCodes.AUTH_PASSWORD_NOT_CONFIGURED;
|
|
107
|
+
case "bootstrap_token_invalid": return ConnectErrorDetailCodes.AUTH_BOOTSTRAP_TOKEN_INVALID;
|
|
108
|
+
case "tailscale_user_missing": return ConnectErrorDetailCodes.AUTH_TAILSCALE_IDENTITY_MISSING;
|
|
109
|
+
case "tailscale_proxy_missing": return ConnectErrorDetailCodes.AUTH_TAILSCALE_PROXY_MISSING;
|
|
110
|
+
case "tailscale_whois_failed": return ConnectErrorDetailCodes.AUTH_TAILSCALE_WHOIS_FAILED;
|
|
111
|
+
case "tailscale_user_mismatch": return ConnectErrorDetailCodes.AUTH_TAILSCALE_IDENTITY_MISMATCH;
|
|
112
|
+
case "rate_limited": return ConnectErrorDetailCodes.AUTH_RATE_LIMITED;
|
|
113
|
+
case "device_token_mismatch": return ConnectErrorDetailCodes.AUTH_DEVICE_TOKEN_MISMATCH;
|
|
114
|
+
case "scope_mismatch": return ConnectErrorDetailCodes.AUTH_SCOPE_MISMATCH;
|
|
115
|
+
case void 0: return ConnectErrorDetailCodes.AUTH_REQUIRED;
|
|
116
|
+
default: return ConnectErrorDetailCodes.AUTH_UNAUTHORIZED;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Maps device-auth verifier reasons to public connect-error detail codes. */
|
|
120
|
+
function resolveDeviceAuthConnectErrorDetailCode(reason) {
|
|
121
|
+
switch (reason) {
|
|
122
|
+
case "device-id-mismatch": return ConnectErrorDetailCodes.DEVICE_AUTH_DEVICE_ID_MISMATCH;
|
|
123
|
+
case "device-signature-stale": return ConnectErrorDetailCodes.DEVICE_AUTH_SIGNATURE_EXPIRED;
|
|
124
|
+
case "device-nonce-missing": return ConnectErrorDetailCodes.DEVICE_AUTH_NONCE_REQUIRED;
|
|
125
|
+
case "device-nonce-mismatch": return ConnectErrorDetailCodes.DEVICE_AUTH_NONCE_MISMATCH;
|
|
126
|
+
case "device-signature": return ConnectErrorDetailCodes.DEVICE_AUTH_SIGNATURE_INVALID;
|
|
127
|
+
case "device-public-key": return ConnectErrorDetailCodes.DEVICE_AUTH_PUBLIC_KEY_INVALID;
|
|
128
|
+
default: return ConnectErrorDetailCodes.DEVICE_AUTH_INVALID;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** Reads a non-empty detail code from an untrusted error details payload. */
|
|
132
|
+
function readConnectErrorDetailCode(details) {
|
|
133
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) return null;
|
|
134
|
+
const code = details.code;
|
|
135
|
+
return typeof code === "string" && code.trim().length > 0 ? code.trim() : null;
|
|
136
|
+
}
|
|
137
|
+
/** Extracts normalized retry advice from untrusted connect-error details. */
|
|
138
|
+
function readConnectErrorRecoveryAdvice(details) {
|
|
139
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) return {};
|
|
140
|
+
const raw = details;
|
|
141
|
+
const canRetryWithDeviceToken = typeof raw.canRetryWithDeviceToken === "boolean" ? raw.canRetryWithDeviceToken : void 0;
|
|
142
|
+
const normalizedNextStep = normalizeOptionalString(raw.recommendedNextStep) ?? "";
|
|
143
|
+
return {
|
|
144
|
+
canRetryWithDeviceToken,
|
|
145
|
+
recommendedNextStep: CONNECT_RECOVERY_NEXT_STEP_VALUES.has(normalizedNextStep) ? normalizedNextStep : void 0
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function normalizePairingConnectReason(value) {
|
|
149
|
+
const normalized = normalizeOptionalString(value) ?? "";
|
|
150
|
+
return CONNECT_PAIRING_REQUIRED_REASON_VALUES.has(normalized) ? normalized : void 0;
|
|
151
|
+
}
|
|
152
|
+
/** Normalizes pairing request ids before echoing them in close reasons or UI text. */
|
|
153
|
+
function normalizePairingConnectRequestId(value) {
|
|
154
|
+
const normalized = normalizeOptionalString(value);
|
|
155
|
+
return normalized && PAIRING_CONNECT_REQUEST_ID_PATTERN.test(normalized) ? normalized : void 0;
|
|
156
|
+
}
|
|
157
|
+
function normalizeStringArray(value) {
|
|
158
|
+
return normalizeArrayBackedTrimmedStringList(value);
|
|
159
|
+
}
|
|
160
|
+
function createPairingConnectErrorDetails(params) {
|
|
161
|
+
return {
|
|
162
|
+
code: ConnectErrorDetailCodes.PAIRING_REQUIRED,
|
|
163
|
+
...params.reason ? { reason: params.reason } : {},
|
|
164
|
+
...params.requestId ? { requestId: params.requestId } : {},
|
|
165
|
+
...params.remediationHint ? { remediationHint: params.remediationHint } : {},
|
|
166
|
+
...params.recommendedNextStep ? { recommendedNextStep: params.recommendedNextStep } : {},
|
|
167
|
+
...params.retryable !== void 0 ? { retryable: params.retryable } : {},
|
|
168
|
+
...params.pauseReconnect !== void 0 ? { pauseReconnect: params.pauseReconnect } : {},
|
|
169
|
+
...params.deviceId ? { deviceId: params.deviceId } : {},
|
|
170
|
+
...params.requestedRole ? { requestedRole: params.requestedRole } : {},
|
|
171
|
+
...params.requestedScopes ? { requestedScopes: params.requestedScopes } : {},
|
|
172
|
+
...params.approvedRoles ? { approvedRoles: params.approvedRoles } : {},
|
|
173
|
+
...params.approvedScopes ? { approvedScopes: params.approvedScopes } : {}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/** Human-readable requirement summary for a pairing-required reason. */
|
|
177
|
+
function describePairingConnectRequirement(reason) {
|
|
178
|
+
return reason ? PAIRING_CONNECT_REASON_METADATA[reason].requirement : "device approval is required";
|
|
179
|
+
}
|
|
180
|
+
/** Builds the gateway close/error message for a pairing-required connect failure. */
|
|
181
|
+
function buildPairingConnectErrorMessage(reason) {
|
|
182
|
+
return reason ? `pairing required: ${describePairingConnectRequirement(reason)}` : "pairing required";
|
|
183
|
+
}
|
|
184
|
+
function buildPairingConnectRemediationHint(reason) {
|
|
185
|
+
return reason ? PAIRING_CONNECT_REASON_METADATA[reason].remediationHint : "Approve the pending device request before retrying.";
|
|
186
|
+
}
|
|
187
|
+
/** Short user-facing recovery title for pairing-required connect failures. */
|
|
188
|
+
function buildPairingConnectRecoveryTitle(reason) {
|
|
189
|
+
return reason ? PAIRING_CONNECT_REASON_METADATA[reason].recoveryTitle : "Gateway pairing approval required.";
|
|
190
|
+
}
|
|
191
|
+
/** Builds sanitized structured details for a pairing-required connect failure. */
|
|
192
|
+
function buildPairingConnectErrorDetails(params) {
|
|
193
|
+
const requestId = normalizePairingConnectRequestId(params.requestId);
|
|
194
|
+
const remediationHint = normalizeOptionalString(params.remediationHint) ?? buildPairingConnectRemediationHint(params.reason);
|
|
195
|
+
const deviceId = normalizeOptionalString(params.deviceId);
|
|
196
|
+
const requestedRole = normalizeOptionalString(params.requestedRole);
|
|
197
|
+
const requestedScopes = normalizeStringArray(params.requestedScopes);
|
|
198
|
+
const approvedRoles = normalizeStringArray(params.approvedRoles);
|
|
199
|
+
const approvedScopes = normalizeStringArray(params.approvedScopes);
|
|
200
|
+
return createPairingConnectErrorDetails({
|
|
201
|
+
reason: params.reason,
|
|
202
|
+
requestId,
|
|
203
|
+
remediationHint,
|
|
204
|
+
recommendedNextStep: params.recommendedNextStep,
|
|
205
|
+
retryable: params.retryable,
|
|
206
|
+
pauseReconnect: params.pauseReconnect,
|
|
207
|
+
deviceId,
|
|
208
|
+
requestedRole,
|
|
209
|
+
requestedScopes,
|
|
210
|
+
approvedRoles,
|
|
211
|
+
approvedScopes
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/** Builds a sanitized close reason string for WebSocket pairing rejections. */
|
|
215
|
+
function buildPairingConnectCloseReason(params) {
|
|
216
|
+
const requestId = normalizePairingConnectRequestId(params.requestId);
|
|
217
|
+
const message = buildPairingConnectErrorMessage(params.reason);
|
|
218
|
+
return requestId ? `${message} (requestId: ${requestId})` : message;
|
|
219
|
+
}
|
|
220
|
+
/** Reads and backfills pairing-required details from an untrusted details object. */
|
|
221
|
+
function readPairingConnectErrorDetails(details) {
|
|
222
|
+
if (readConnectErrorDetailCode(details) !== ConnectErrorDetailCodes.PAIRING_REQUIRED) return null;
|
|
223
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) return null;
|
|
224
|
+
const raw = details;
|
|
225
|
+
const reason = normalizePairingConnectReason(raw.reason);
|
|
226
|
+
const requestId = normalizePairingConnectRequestId(raw.requestId);
|
|
227
|
+
const remediationHint = normalizeOptionalString(raw.remediationHint) ?? buildPairingConnectRemediationHint(reason);
|
|
228
|
+
const normalizedNextStep = normalizeOptionalString(raw.recommendedNextStep) ?? "";
|
|
229
|
+
const recommendedNextStep = CONNECT_RECOVERY_NEXT_STEP_VALUES.has(normalizedNextStep) ? normalizedNextStep : void 0;
|
|
230
|
+
const deviceId = normalizeOptionalString(raw.deviceId);
|
|
231
|
+
const requestedRole = normalizeOptionalString(raw.requestedRole);
|
|
232
|
+
const requestedScopes = normalizeStringArray(raw.requestedScopes);
|
|
233
|
+
const approvedRoles = normalizeStringArray(raw.approvedRoles);
|
|
234
|
+
const approvedScopes = normalizeStringArray(raw.approvedScopes);
|
|
235
|
+
return createPairingConnectErrorDetails({
|
|
236
|
+
reason,
|
|
237
|
+
requestId,
|
|
238
|
+
remediationHint,
|
|
239
|
+
recommendedNextStep,
|
|
240
|
+
retryable: typeof raw.retryable === "boolean" ? raw.retryable : void 0,
|
|
241
|
+
pauseReconnect: typeof raw.pauseReconnect === "boolean" ? raw.pauseReconnect : void 0,
|
|
242
|
+
deviceId,
|
|
243
|
+
requestedRole,
|
|
244
|
+
requestedScopes,
|
|
245
|
+
approvedRoles,
|
|
246
|
+
approvedScopes
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/** Parses legacy/string-only pairing-required messages into structured details. */
|
|
250
|
+
function readConnectPairingRequiredMessage(message) {
|
|
251
|
+
const normalizedMessage = normalizeOptionalString(message);
|
|
252
|
+
if (!normalizedMessage) return null;
|
|
253
|
+
const normalized = normalizedMessage.trim().toLowerCase();
|
|
254
|
+
let reason;
|
|
255
|
+
for (const [candidate, prefix] of Object.entries(CONNECT_PAIRING_REQUIRED_MESSAGE_BY_REASON)) if (normalized.includes(prefix)) {
|
|
256
|
+
reason = candidate;
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
if (!reason && normalized.includes("pairing required")) reason = ConnectPairingRequiredReasons.NOT_PAIRED;
|
|
260
|
+
if (!reason) return null;
|
|
261
|
+
const requestId = normalizePairingConnectRequestId(normalizedMessage.match(/\(requestId:\s*([^\s)]+)\)/i)?.[1]);
|
|
262
|
+
return {
|
|
263
|
+
...requestId ? { requestId } : {},
|
|
264
|
+
reason
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/** Formats pairing-required details into the canonical user-facing message. */
|
|
268
|
+
function formatConnectPairingRequiredMessage(details) {
|
|
269
|
+
const pairing = readPairingConnectErrorDetails(details);
|
|
270
|
+
const base = CONNECT_PAIRING_REQUIRED_MESSAGE_BY_REASON[pairing?.reason ?? ConnectPairingRequiredReasons.NOT_PAIRED];
|
|
271
|
+
return pairing?.requestId ? `${base} (requestId: ${pairing.requestId})` : base;
|
|
272
|
+
}
|
|
273
|
+
/** Formats connect errors using structured details before falling back to raw messages. */
|
|
274
|
+
function formatConnectErrorMessage(params) {
|
|
275
|
+
if (readConnectErrorDetailCode(params.details) === ConnectErrorDetailCodes.PAIRING_REQUIRED) return formatConnectPairingRequiredMessage(params.details);
|
|
276
|
+
if (readConnectErrorDetailCode(params.details) === ConnectErrorDetailCodes.PROTOCOL_MISMATCH) return formatProtocolMismatchMessage(params.message, params.details);
|
|
277
|
+
return normalizeOptionalString(params.message) ?? "gateway request failed";
|
|
278
|
+
}
|
|
279
|
+
function formatProtocolMismatchMessage(message, details) {
|
|
280
|
+
const raw = details;
|
|
281
|
+
const clientMin = normalizeProtocolNumber(raw.clientMinProtocol);
|
|
282
|
+
const clientMax = normalizeProtocolNumber(raw.clientMaxProtocol);
|
|
283
|
+
const expected = normalizeProtocolNumber(raw.expectedProtocol);
|
|
284
|
+
const probeMin = normalizeProtocolNumber(raw.minimumProbeProtocol);
|
|
285
|
+
const parts = [];
|
|
286
|
+
if (clientMin !== void 0 && clientMax !== void 0) parts.push(clientMin === clientMax ? `Control UI v${clientMin}` : `Control UI v${clientMin}-v${clientMax}`);
|
|
287
|
+
if (expected !== void 0) parts.push(`Gateway v${expected}`);
|
|
288
|
+
if (probeMin !== void 0) parts.push(`probe min v${probeMin}`);
|
|
289
|
+
const normalized = normalizeOptionalString(message) ?? "protocol mismatch";
|
|
290
|
+
return parts.length > 0 ? `${normalized}: ${parts.join(", ")}` : normalized;
|
|
291
|
+
}
|
|
292
|
+
function normalizeProtocolNumber(value) {
|
|
293
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : void 0;
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
296
|
+
export { ConnectErrorDetailCodes, buildPairingConnectCloseReason, buildPairingConnectErrorDetails, buildPairingConnectErrorMessage, buildPairingConnectRecoveryTitle, describePairingConnectRequirement, formatConnectErrorMessage, formatConnectPairingRequiredMessage, normalizePairingConnectRequestId, readConnectErrorDetailCode, readConnectErrorRecoveryAdvice, readConnectPairingRequiredMessage, readPairingConnectErrorDetails, resolveAuthConnectErrorDetailCode, resolveDeviceAuthConnectErrorDetailCode };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { a as EventFrame, c as GatewayFrame, f as RequestFrame, m as ResponseFrame, r as ErrorShape, t as ConnectParams, u as HelloOk } from "./frames-DEn_IEne.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/frame-guards.d.ts
|
|
4
|
+
declare function isGatewayEventFrame(value: unknown): value is EventFrame;
|
|
5
|
+
declare function isGatewayResponseFrame(value: unknown): value is ResponseFrame;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { type ConnectParams, type ErrorShape, type EventFrame, type GatewayFrame, type HelloOk, type RequestFrame, type ResponseFrame, isGatewayEventFrame, isGatewayResponseFrame };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/frame-guards.ts
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function isNonEmptyString(value) {
|
|
6
|
+
return typeof value === "string" && value.length > 0;
|
|
7
|
+
}
|
|
8
|
+
function isNonNegativeInteger(value) {
|
|
9
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
10
|
+
}
|
|
11
|
+
function isGatewayErrorShape(value) {
|
|
12
|
+
if (!isRecord(value)) return false;
|
|
13
|
+
if (!isNonEmptyString(value.code) || !isNonEmptyString(value.message)) return false;
|
|
14
|
+
if (value.retryable !== void 0 && typeof value.retryable !== "boolean") return false;
|
|
15
|
+
return value.retryAfterMs === void 0 || isNonNegativeInteger(value.retryAfterMs);
|
|
16
|
+
}
|
|
17
|
+
function isGatewayEventFrame(value) {
|
|
18
|
+
if (!isRecord(value) || value.type !== "event" || !isNonEmptyString(value.event)) return false;
|
|
19
|
+
return value.seq === void 0 || isNonNegativeInteger(value.seq);
|
|
20
|
+
}
|
|
21
|
+
function isGatewayResponseFrame(value) {
|
|
22
|
+
if (!isRecord(value) || value.type !== "res" || !isNonEmptyString(value.id) || typeof value.ok !== "boolean") return false;
|
|
23
|
+
return value.error === void 0 || isGatewayErrorShape(value.error);
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { isGatewayEventFrame, isGatewayResponseFrame };
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { Static, Type } from "typebox";
|
|
2
|
+
|
|
3
|
+
//#region src/schema/frames.d.ts
|
|
4
|
+
declare const GATEWAY_SERVER_CAPS: {
|
|
5
|
+
readonly BOARD_WIDGET_PUT_CANVAS_DOC: "board-widget-put-canvas-doc";
|
|
6
|
+
readonly CHAT_SEND_ROUTING_CONTRACT: "chat-send-routing-contract";
|
|
7
|
+
readonly SYSTEM_AGENT_SETUP_MODEL_REF: "openclaw-setup-model-ref";
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Top-level gateway frame schemas.
|
|
11
|
+
*
|
|
12
|
+
* These are the WebSocket envelope contracts; method/event payload schemas live
|
|
13
|
+
* in feature-specific modules and are referenced by runtime validators.
|
|
14
|
+
*/
|
|
15
|
+
/** Periodic server heartbeat event payload. */
|
|
16
|
+
declare const TickEventSchema: Type.TObject<{
|
|
17
|
+
ts: Type.TInteger;
|
|
18
|
+
}>;
|
|
19
|
+
/** Server shutdown notice event payload. */
|
|
20
|
+
declare const ShutdownEventSchema: Type.TObject<{
|
|
21
|
+
reason: Type.TString;
|
|
22
|
+
restartExpectedMs: Type.TOptional<Type.TInteger>;
|
|
23
|
+
}>;
|
|
24
|
+
/** Initial client hello/connect payload sent before the gateway accepts frames. */
|
|
25
|
+
declare const ConnectParamsSchema: Type.TObject<{
|
|
26
|
+
minProtocol: Type.TInteger;
|
|
27
|
+
maxProtocol: Type.TInteger;
|
|
28
|
+
client: Type.TObject<{
|
|
29
|
+
id: Type.TEnum<["webchat-ui", "openclaw-control-ui", "openclaw-browser-copilot", "openclaw-tui", "webchat", "cli", "gateway-client", "openclaw-macos", "openclaw-linux", "openclaw-ios", "openclaw-watchos", "openclaw-android", "node-host", "openclaw-worker", "test", "fingerprint", "openclaw-probe"]>;
|
|
30
|
+
displayName: Type.TOptional<Type.TString>;
|
|
31
|
+
version: Type.TString;
|
|
32
|
+
platform: Type.TString;
|
|
33
|
+
deviceFamily: Type.TOptional<Type.TString>;
|
|
34
|
+
modelIdentifier: Type.TOptional<Type.TString>;
|
|
35
|
+
mode: Type.TEnum<["webchat", "cli", "worker", "test", "probe", "ui", "backend", "node"]>;
|
|
36
|
+
instanceId: Type.TOptional<Type.TString>;
|
|
37
|
+
}>;
|
|
38
|
+
caps: Type.TOptional<Type.TArray<Type.TString>>;
|
|
39
|
+
commands: Type.TOptional<Type.TArray<Type.TString>>;
|
|
40
|
+
permissions: Type.TOptional<Type.TRecord<"^.*$", Type.TBoolean>>;
|
|
41
|
+
pathEnv: Type.TOptional<Type.TString>;
|
|
42
|
+
role: Type.TOptional<Type.TString>;
|
|
43
|
+
scopes: Type.TOptional<Type.TArray<Type.TString>>;
|
|
44
|
+
device: Type.TOptional<Type.TObject<{
|
|
45
|
+
id: Type.TString;
|
|
46
|
+
publicKey: Type.TString;
|
|
47
|
+
signature: Type.TString;
|
|
48
|
+
signedAt: Type.TInteger;
|
|
49
|
+
nonce: Type.TString;
|
|
50
|
+
}>>;
|
|
51
|
+
auth: Type.TOptional<Type.TObject<{
|
|
52
|
+
token: Type.TOptional<Type.TString>;
|
|
53
|
+
bootstrapToken: Type.TOptional<Type.TString>;
|
|
54
|
+
deviceToken: Type.TOptional<Type.TString>;
|
|
55
|
+
password: Type.TOptional<Type.TString>;
|
|
56
|
+
approvalRuntimeToken: Type.TOptional<Type.TString>;
|
|
57
|
+
agentRuntimeIdentityToken: Type.TOptional<Type.TString>;
|
|
58
|
+
}>>;
|
|
59
|
+
locale: Type.TOptional<Type.TString>;
|
|
60
|
+
userAgent: Type.TOptional<Type.TString>;
|
|
61
|
+
}>;
|
|
62
|
+
/** Successful gateway hello response with negotiated protocol and initial state. */
|
|
63
|
+
declare const HelloOkSchema: Type.TObject<{
|
|
64
|
+
type: Type.TLiteral<"hello-ok">;
|
|
65
|
+
protocol: Type.TInteger;
|
|
66
|
+
server: Type.TObject<{
|
|
67
|
+
version: Type.TString;
|
|
68
|
+
connId: Type.TString;
|
|
69
|
+
}>;
|
|
70
|
+
features: Type.TObject<{
|
|
71
|
+
methods: Type.TArray<Type.TString>;
|
|
72
|
+
events: Type.TArray<Type.TString>;
|
|
73
|
+
capabilities: Type.TOptional<Type.TArray<Type.TString>>;
|
|
74
|
+
}>;
|
|
75
|
+
snapshot: Type.TObject<{
|
|
76
|
+
presence: Type.TArray<Type.TObject<{
|
|
77
|
+
host: Type.TOptional<Type.TString>;
|
|
78
|
+
ip: Type.TOptional<Type.TString>;
|
|
79
|
+
version: Type.TOptional<Type.TString>;
|
|
80
|
+
platform: Type.TOptional<Type.TString>;
|
|
81
|
+
deviceFamily: Type.TOptional<Type.TString>;
|
|
82
|
+
modelIdentifier: Type.TOptional<Type.TString>;
|
|
83
|
+
mode: Type.TOptional<Type.TString>;
|
|
84
|
+
lastInputSeconds: Type.TOptional<Type.TInteger>;
|
|
85
|
+
reason: Type.TOptional<Type.TString>;
|
|
86
|
+
tags: Type.TOptional<Type.TArray<Type.TString>>;
|
|
87
|
+
text: Type.TOptional<Type.TString>;
|
|
88
|
+
ts: Type.TInteger;
|
|
89
|
+
deviceId: Type.TOptional<Type.TString>;
|
|
90
|
+
roles: Type.TOptional<Type.TArray<Type.TString>>;
|
|
91
|
+
scopes: Type.TOptional<Type.TArray<Type.TString>>;
|
|
92
|
+
instanceId: Type.TOptional<Type.TString>;
|
|
93
|
+
user: Type.TOptional<Type.TObject<{
|
|
94
|
+
id: Type.TString;
|
|
95
|
+
email: Type.TOptional<Type.TString>;
|
|
96
|
+
name: Type.TOptional<Type.TString>;
|
|
97
|
+
avatarUrl: Type.TOptional<Type.TString>;
|
|
98
|
+
}>>;
|
|
99
|
+
watchedSessions: Type.TOptional<Type.TArray<Type.TString>>;
|
|
100
|
+
}>>;
|
|
101
|
+
health: Type.TObject<{
|
|
102
|
+
ok: Type.TOptional<Type.TLiteral<true>>;
|
|
103
|
+
ts: Type.TOptional<Type.TInteger>;
|
|
104
|
+
durationMs: Type.TOptional<Type.TInteger>;
|
|
105
|
+
eventLoop: Type.TOptional<Type.TObject<{
|
|
106
|
+
degraded: Type.TBoolean;
|
|
107
|
+
reasons: Type.TArray<Type.TUnion<[Type.TLiteral<"event_loop_delay">, Type.TLiteral<"event_loop_utilization">, Type.TLiteral<"cpu">]>>;
|
|
108
|
+
intervalMs: Type.TNumber;
|
|
109
|
+
delayP99Ms: Type.TNumber;
|
|
110
|
+
delayMaxMs: Type.TNumber;
|
|
111
|
+
utilization: Type.TNumber;
|
|
112
|
+
cpuCoreRatio: Type.TNumber;
|
|
113
|
+
}>>;
|
|
114
|
+
plugins: Type.TOptional<Type.TObject<{
|
|
115
|
+
loaded: Type.TArray<Type.TString>;
|
|
116
|
+
errors: Type.TArray<Type.TObject<{
|
|
117
|
+
id: Type.TString;
|
|
118
|
+
origin: Type.TString;
|
|
119
|
+
activated: Type.TBoolean;
|
|
120
|
+
activationSource: Type.TOptional<Type.TString>;
|
|
121
|
+
activationReason: Type.TOptional<Type.TString>;
|
|
122
|
+
failurePhase: Type.TOptional<Type.TString>;
|
|
123
|
+
error: Type.TString;
|
|
124
|
+
}>>;
|
|
125
|
+
unavailable: Type.TOptional<Type.TArray<Type.TObject<{
|
|
126
|
+
id: Type.TString;
|
|
127
|
+
state: Type.TLiteral<"configured-unavailable">;
|
|
128
|
+
diagnostic: Type.TObject<{
|
|
129
|
+
kind: Type.TLiteral<"plugin-verification">;
|
|
130
|
+
reason: Type.TString;
|
|
131
|
+
detail: Type.TString;
|
|
132
|
+
}>;
|
|
133
|
+
}>>>;
|
|
134
|
+
}>>;
|
|
135
|
+
contextEngines: Type.TOptional<Type.TObject<{
|
|
136
|
+
quarantined: Type.TArray<Type.TObject<{
|
|
137
|
+
engineId: Type.TString;
|
|
138
|
+
owner: Type.TOptional<Type.TString>;
|
|
139
|
+
operation: Type.TString;
|
|
140
|
+
reason: Type.TString;
|
|
141
|
+
failedAt: Type.TInteger;
|
|
142
|
+
}>>;
|
|
143
|
+
}>>;
|
|
144
|
+
deliveryQueues: Type.TOptional<Type.TObject<{
|
|
145
|
+
failed: Type.TArray<Type.TObject<{
|
|
146
|
+
queueName: Type.TString;
|
|
147
|
+
count: Type.TInteger;
|
|
148
|
+
oldestFailedAt: Type.TOptional<Type.TInteger>;
|
|
149
|
+
}>>;
|
|
150
|
+
}>>;
|
|
151
|
+
modelPricing: Type.TOptional<Type.TObject<{
|
|
152
|
+
state: Type.TUnion<[Type.TLiteral<"ok">, Type.TLiteral<"degraded">, Type.TLiteral<"disabled">]>;
|
|
153
|
+
sources: Type.TArray<Type.TObject<{
|
|
154
|
+
source: Type.TUnion<[Type.TLiteral<"openrouter">, Type.TLiteral<"litellm">, Type.TLiteral<"bootstrap">, Type.TLiteral<"refresh">]>;
|
|
155
|
+
state: Type.TUnion<[Type.TLiteral<"ok">, Type.TLiteral<"degraded">]>;
|
|
156
|
+
lastFailureAt: Type.TOptional<Type.TInteger>;
|
|
157
|
+
detail: Type.TOptional<Type.TString>;
|
|
158
|
+
}>>;
|
|
159
|
+
lastFailureAt: Type.TOptional<Type.TInteger>;
|
|
160
|
+
detail: Type.TOptional<Type.TString>;
|
|
161
|
+
}>>;
|
|
162
|
+
configReload: Type.TOptional<Type.TObject<{
|
|
163
|
+
hotReloadStatus: Type.TUnion<[Type.TLiteral<"active">, Type.TLiteral<"disabled">]>;
|
|
164
|
+
}>>;
|
|
165
|
+
channels: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
166
|
+
channelOrder: Type.TOptional<Type.TArray<Type.TString>>;
|
|
167
|
+
channelLabels: Type.TOptional<Type.TRecord<"^.*$", Type.TString>>;
|
|
168
|
+
heartbeatSeconds: Type.TOptional<Type.TInteger>;
|
|
169
|
+
defaultAgentId: Type.TOptional<Type.TString>;
|
|
170
|
+
agents: Type.TOptional<Type.TArray<Type.TObject<{
|
|
171
|
+
agentId: Type.TString;
|
|
172
|
+
name: Type.TOptional<Type.TString>;
|
|
173
|
+
isDefault: Type.TBoolean;
|
|
174
|
+
heartbeat: Type.TObject<{
|
|
175
|
+
enabled: Type.TBoolean;
|
|
176
|
+
every: Type.TString;
|
|
177
|
+
everyMs: Type.TUnion<[Type.TInteger, Type.TNull]>;
|
|
178
|
+
prompt: Type.TString;
|
|
179
|
+
target: Type.TString;
|
|
180
|
+
model: Type.TOptional<Type.TString>;
|
|
181
|
+
ackMaxChars: Type.TInteger;
|
|
182
|
+
}>;
|
|
183
|
+
sessions: Type.TObject<{
|
|
184
|
+
path: Type.TString;
|
|
185
|
+
count: Type.TInteger;
|
|
186
|
+
recent: Type.TArray<Type.TObject<{
|
|
187
|
+
key: Type.TString;
|
|
188
|
+
updatedAt: Type.TUnion<[Type.TInteger, Type.TNull]>;
|
|
189
|
+
age: Type.TUnion<[Type.TInteger, Type.TNull]>;
|
|
190
|
+
}>>;
|
|
191
|
+
}>;
|
|
192
|
+
}>>>;
|
|
193
|
+
sessions: Type.TOptional<Type.TObject<{
|
|
194
|
+
path: Type.TString;
|
|
195
|
+
count: Type.TInteger;
|
|
196
|
+
recent: Type.TArray<Type.TObject<{
|
|
197
|
+
key: Type.TString;
|
|
198
|
+
updatedAt: Type.TUnion<[Type.TInteger, Type.TNull]>;
|
|
199
|
+
age: Type.TUnion<[Type.TInteger, Type.TNull]>;
|
|
200
|
+
}>>;
|
|
201
|
+
}>>;
|
|
202
|
+
}>;
|
|
203
|
+
stateVersion: Type.TObject<{
|
|
204
|
+
presence: Type.TInteger;
|
|
205
|
+
health: Type.TInteger;
|
|
206
|
+
}>;
|
|
207
|
+
uptimeMs: Type.TInteger;
|
|
208
|
+
appliedConfigHash: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
209
|
+
configPath: Type.TOptional<Type.TString>;
|
|
210
|
+
stateDir: Type.TOptional<Type.TString>;
|
|
211
|
+
sessionDefaults: Type.TOptional<Type.TObject<{
|
|
212
|
+
defaultAgentId: Type.TString;
|
|
213
|
+
mainKey: Type.TString;
|
|
214
|
+
mainSessionKey: Type.TString;
|
|
215
|
+
scope: Type.TOptional<Type.TString>;
|
|
216
|
+
}>>;
|
|
217
|
+
authMode: Type.TOptional<Type.TUnion<[Type.TLiteral<"none">, Type.TLiteral<"token">, Type.TLiteral<"password">, Type.TLiteral<"trusted-proxy">]>>;
|
|
218
|
+
updateAvailable: Type.TOptional<Type.TObject<{
|
|
219
|
+
currentVersion: Type.TString;
|
|
220
|
+
latestVersion: Type.TString;
|
|
221
|
+
channel: Type.TString;
|
|
222
|
+
}>>;
|
|
223
|
+
}>;
|
|
224
|
+
controlUiTabs: Type.TOptional<Type.TArray<Type.TObject<{
|
|
225
|
+
pluginId: Type.TString;
|
|
226
|
+
id: Type.TString;
|
|
227
|
+
label: Type.TString;
|
|
228
|
+
description: Type.TOptional<Type.TString>;
|
|
229
|
+
icon: Type.TOptional<Type.TString>;
|
|
230
|
+
path: Type.TOptional<Type.TString>;
|
|
231
|
+
requiresGatewayAuth: Type.TOptional<Type.TBoolean>;
|
|
232
|
+
group: Type.TOptional<Type.TUnion<[Type.TLiteral<"control">, Type.TLiteral<"agent">]>>;
|
|
233
|
+
order: Type.TOptional<Type.TNumber>;
|
|
234
|
+
}>>>;
|
|
235
|
+
controlUiWidgetKinds: Type.TOptional<Type.TArray<Type.TObject<{
|
|
236
|
+
pluginId: Type.TString;
|
|
237
|
+
kind: Type.TString;
|
|
238
|
+
label: Type.TString;
|
|
239
|
+
}>>>;
|
|
240
|
+
pluginSurfaceUrls: Type.TOptional<Type.TRecord<"^.*$", Type.TString>>;
|
|
241
|
+
deviceAuthMigration: Type.TOptional<Type.TObject<{
|
|
242
|
+
pending: Type.TLiteral<true>;
|
|
243
|
+
}>>;
|
|
244
|
+
auth: Type.TObject<{
|
|
245
|
+
deviceToken: Type.TOptional<Type.TString>;
|
|
246
|
+
role: Type.TString;
|
|
247
|
+
scopes: Type.TArray<Type.TString>;
|
|
248
|
+
issuedAtMs: Type.TOptional<Type.TInteger>;
|
|
249
|
+
deviceTokens: Type.TOptional<Type.TArray<Type.TObject<{
|
|
250
|
+
deviceToken: Type.TString;
|
|
251
|
+
role: Type.TString;
|
|
252
|
+
scopes: Type.TArray<Type.TString>;
|
|
253
|
+
issuedAtMs: Type.TInteger;
|
|
254
|
+
}>>>;
|
|
255
|
+
}>;
|
|
256
|
+
policy: Type.TObject<{
|
|
257
|
+
maxPayload: Type.TInteger;
|
|
258
|
+
maxBufferedBytes: Type.TInteger;
|
|
259
|
+
tickIntervalMs: Type.TInteger;
|
|
260
|
+
allowedSessionVisibilities: Type.TOptional<Type.TArray<Type.TUnion<[Type.TLiteral<"shared">, Type.TLiteral<"read-only">, Type.TLiteral<"suggest">, Type.TLiteral<"draft">]>>>;
|
|
261
|
+
hasMultipleSessionSharingIdentities: Type.TOptional<Type.TBoolean>;
|
|
262
|
+
}>;
|
|
263
|
+
}>;
|
|
264
|
+
/** Standard structured error shape used in response frames and connect failures. */
|
|
265
|
+
declare const ErrorShapeSchema: Type.TObject<{
|
|
266
|
+
code: Type.TString;
|
|
267
|
+
message: Type.TString;
|
|
268
|
+
details: Type.TOptional<Type.TUnknown>;
|
|
269
|
+
retryable: Type.TOptional<Type.TBoolean>;
|
|
270
|
+
retryAfterMs: Type.TOptional<Type.TInteger>;
|
|
271
|
+
}>;
|
|
272
|
+
/** Client request frame envelope; `method` selects the payload validator. */
|
|
273
|
+
declare const RequestFrameSchema: Type.TObject<{
|
|
274
|
+
type: Type.TLiteral<"req">;
|
|
275
|
+
id: Type.TString;
|
|
276
|
+
method: Type.TString;
|
|
277
|
+
params: Type.TOptional<Type.TUnknown>;
|
|
278
|
+
}>;
|
|
279
|
+
/** Server response frame envelope paired with a prior request id. */
|
|
280
|
+
declare const ResponseFrameSchema: Type.TObject<{
|
|
281
|
+
type: Type.TLiteral<"res">;
|
|
282
|
+
id: Type.TString;
|
|
283
|
+
ok: Type.TBoolean;
|
|
284
|
+
payload: Type.TOptional<Type.TUnknown>;
|
|
285
|
+
error: Type.TOptional<Type.TObject<{
|
|
286
|
+
code: Type.TString;
|
|
287
|
+
message: Type.TString;
|
|
288
|
+
details: Type.TOptional<Type.TUnknown>;
|
|
289
|
+
retryable: Type.TOptional<Type.TBoolean>;
|
|
290
|
+
retryAfterMs: Type.TOptional<Type.TInteger>;
|
|
291
|
+
}>>;
|
|
292
|
+
}>;
|
|
293
|
+
/** Server event frame envelope; `event` selects the payload validator. */
|
|
294
|
+
declare const EventFrameSchema: Type.TObject<{
|
|
295
|
+
type: Type.TLiteral<"event">;
|
|
296
|
+
event: Type.TString;
|
|
297
|
+
payload: Type.TOptional<Type.TUnknown>;
|
|
298
|
+
seq: Type.TOptional<Type.TInteger>;
|
|
299
|
+
stateVersion: Type.TOptional<Type.TObject<{
|
|
300
|
+
presence: Type.TInteger;
|
|
301
|
+
health: Type.TInteger;
|
|
302
|
+
}>>;
|
|
303
|
+
}>;
|
|
304
|
+
declare const GatewayFrameSchema: Type.TUnion<[Type.TObject<{
|
|
305
|
+
type: Type.TLiteral<"req">;
|
|
306
|
+
id: Type.TString;
|
|
307
|
+
method: Type.TString;
|
|
308
|
+
params: Type.TOptional<Type.TUnknown>;
|
|
309
|
+
}>, Type.TObject<{
|
|
310
|
+
type: Type.TLiteral<"res">;
|
|
311
|
+
id: Type.TString;
|
|
312
|
+
ok: Type.TBoolean;
|
|
313
|
+
payload: Type.TOptional<Type.TUnknown>;
|
|
314
|
+
error: Type.TOptional<Type.TObject<{
|
|
315
|
+
code: Type.TString;
|
|
316
|
+
message: Type.TString;
|
|
317
|
+
details: Type.TOptional<Type.TUnknown>;
|
|
318
|
+
retryable: Type.TOptional<Type.TBoolean>;
|
|
319
|
+
retryAfterMs: Type.TOptional<Type.TInteger>;
|
|
320
|
+
}>>;
|
|
321
|
+
}>, Type.TObject<{
|
|
322
|
+
type: Type.TLiteral<"event">;
|
|
323
|
+
event: Type.TString;
|
|
324
|
+
payload: Type.TOptional<Type.TUnknown>;
|
|
325
|
+
seq: Type.TOptional<Type.TInteger>;
|
|
326
|
+
stateVersion: Type.TOptional<Type.TObject<{
|
|
327
|
+
presence: Type.TInteger;
|
|
328
|
+
health: Type.TInteger;
|
|
329
|
+
}>>;
|
|
330
|
+
}>]>;
|
|
331
|
+
type ConnectParams = Static<typeof ConnectParamsSchema>;
|
|
332
|
+
type HelloOk = Static<typeof HelloOkSchema>;
|
|
333
|
+
type ErrorShape = Static<typeof ErrorShapeSchema>;
|
|
334
|
+
type RequestFrame = Static<typeof RequestFrameSchema>;
|
|
335
|
+
type ResponseFrame = Static<typeof ResponseFrameSchema>;
|
|
336
|
+
type EventFrame = Static<typeof EventFrameSchema>;
|
|
337
|
+
type GatewayFrame = Static<typeof GatewayFrameSchema>;
|
|
338
|
+
type TickEvent = Static<typeof TickEventSchema>;
|
|
339
|
+
type ShutdownEvent = Static<typeof ShutdownEventSchema>;
|
|
340
|
+
//#endregion
|
|
341
|
+
export { ShutdownEventSchema as _, EventFrame as a, GatewayFrame as c, HelloOkSchema as d, RequestFrame as f, ShutdownEvent as g, ResponseFrameSchema as h, ErrorShapeSchema as i, GatewayFrameSchema as l, ResponseFrame as m, ConnectParamsSchema as n, EventFrameSchema as o, RequestFrameSchema as p, ErrorShape as r, GATEWAY_SERVER_CAPS as s, ConnectParams as t, HelloOk as u, TickEvent as v, TickEventSchema as y };
|