@amigo-ai/platform-sdk 0.23.0 → 0.25.0

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.
Files changed (42) hide show
  1. package/api.md +8 -2
  2. package/dist/core/errors.js +155 -9
  3. package/dist/core/errors.js.map +1 -1
  4. package/dist/core/reconnecting-websocket.js +371 -0
  5. package/dist/core/reconnecting-websocket.js.map +1 -0
  6. package/dist/index.cjs +1021 -17
  7. package/dist/index.cjs.map +4 -4
  8. package/dist/index.js +22 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +1021 -17
  11. package/dist/index.mjs.map +4 -4
  12. package/dist/resources/events.js +588 -0
  13. package/dist/resources/events.js.map +1 -0
  14. package/dist/resources/integrations.js +25 -0
  15. package/dist/resources/integrations.js.map +1 -1
  16. package/dist/resources/observers.js +238 -0
  17. package/dist/resources/observers.js.map +1 -0
  18. package/dist/resources/workspaces.js +4 -8
  19. package/dist/resources/workspaces.js.map +1 -1
  20. package/dist/types/core/errors.d.ts +93 -1
  21. package/dist/types/core/errors.d.ts.map +1 -1
  22. package/dist/types/core/reconnecting-websocket.d.ts +156 -0
  23. package/dist/types/core/reconnecting-websocket.d.ts.map +1 -0
  24. package/dist/types/generated/api.d.ts +628 -104
  25. package/dist/types/generated/api.d.ts.map +1 -1
  26. package/dist/types/index.d.cts +45 -2
  27. package/dist/types/index.d.cts.map +1 -1
  28. package/dist/types/index.d.ts +45 -2
  29. package/dist/types/index.d.ts.map +1 -1
  30. package/dist/types/resources/events.d.ts +193 -0
  31. package/dist/types/resources/events.d.ts.map +1 -0
  32. package/dist/types/resources/functions.d.ts.map +1 -1
  33. package/dist/types/resources/integrations.d.ts +33 -0
  34. package/dist/types/resources/integrations.d.ts.map +1 -1
  35. package/dist/types/resources/metrics.d.ts.map +1 -1
  36. package/dist/types/resources/observers.d.ts +148 -0
  37. package/dist/types/resources/observers.d.ts.map +1 -0
  38. package/dist/types/resources/operators.d.ts.map +1 -1
  39. package/dist/types/resources/settings.d.ts.map +1 -1
  40. package/dist/types/resources/workspaces.d.ts +4 -15
  41. package/dist/types/resources/workspaces.d.ts.map +1 -1
  42. package/package.json +1 -1
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Voice-call observer real-time stream.
3
+ *
4
+ * The voice agent ("agent-engine") exposes a per-call WebSocket that emits
5
+ * the live timeline of a call: transcripts (user + agent), emotion / empathy
6
+ * frames, latency markers, tool invocations, navigation timing, and lifecycle
7
+ * events (start / end / participant join / leave).
8
+ *
9
+ * This resource is the canonical SDK consumer for that stream. Before it
10
+ * existed, every developer-console-style app re-implemented the loop by hand
11
+ * — different idle thresholds, missing close-code handling for the long list
12
+ * of voice-specific 4xxx codes (4001 unauthorized, 4003 forbidden, 4029 rate
13
+ * limit, 4100 token expired), and inconsistent reconnect backoff.
14
+ *
15
+ * The implementation composes {@link createReconnectingWebSocket} with a
16
+ * lightweight ``ObserverSSEEvent`` parser. Frames that don't deserialize or
17
+ * lack a recognized ``type`` discriminator are dropped — the stream remains
18
+ * forward-compatible with new event types added on the server before the SDK
19
+ * spec snapshot picks them up.
20
+ *
21
+ * @see ConversationsResource.subscribeTextStream for the analogous text-stream
22
+ * helper.
23
+ */
24
+ import { ConfigurationError } from '../core/errors.js';
25
+ import { createReconnectingWebSocket, } from '../core/reconnecting-websocket.js';
26
+ import { WorkspaceScopedResource } from './base.js';
27
+ /** Token grammar accepted in WebSocket subprotocols (RFC 6455). */
28
+ const WEB_SOCKET_PROTOCOL_TOKEN_RE = /^[!#$%&'*+\-.^_`|~A-Za-z0-9]+$/;
29
+ const MAX_AUTH_TOKEN_CHARS = 4096;
30
+ /**
31
+ * Build browser WebSocket subprotocols for the observer stream.
32
+ *
33
+ * Identical wire format to the text-stream subprotocol pair —
34
+ * ``Sec-WebSocket-Protocol: auth, <token>`` — but exposed as its own
35
+ * function so consumers do not have to reason about cross-resource sharing
36
+ * and so the SDK can evolve the auth scheme independently per stream.
37
+ *
38
+ * @security The returned tuple contains the raw bearer token. Do not log,
39
+ * persist, serialize, or otherwise expose this value.
40
+ */
41
+ export function observerAuthProtocols(token) {
42
+ if (!token) {
43
+ throw new ConfigurationError('observerAuthProtocols requires a non-empty token');
44
+ }
45
+ if (token.length > MAX_AUTH_TOKEN_CHARS) {
46
+ throw new ConfigurationError(`observer token exceeds the ${MAX_AUTH_TOKEN_CHARS}-character WebSocket subprotocol limit`);
47
+ }
48
+ if (!WEB_SOCKET_PROTOCOL_TOKEN_RE.test(token)) {
49
+ throw new ConfigurationError('observer token contains characters browsers reject in WebSocket subprotocols');
50
+ }
51
+ return ['auth', token];
52
+ }
53
+ /**
54
+ * Voice-call observer resource.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const handle = client.observers.subscribe({
59
+ * callSid: 'CAxxx',
60
+ * token: bearerToken,
61
+ * onEvent: (event) => {
62
+ * switch (event.type) {
63
+ * case 'agent_transcript_delta':
64
+ * renderAgentDelta(event.text)
65
+ * break
66
+ * case 'user_transcript':
67
+ * renderUserTurn(event.text)
68
+ * break
69
+ * case 'session_end':
70
+ * showSummary(event)
71
+ * break
72
+ * }
73
+ * },
74
+ * onError: (err) => console.error('observer terminal:', err.reason),
75
+ * })
76
+ *
77
+ * // Later, to stop:
78
+ * handle.close()
79
+ * await handle.done
80
+ * ```
81
+ */
82
+ export class ObserversResource extends WorkspaceScopedResource {
83
+ agentBaseUrl;
84
+ constructor(client, workspaceId, agentBaseUrl) {
85
+ super(client, workspaceId);
86
+ this.agentBaseUrl = agentBaseUrl;
87
+ }
88
+ /**
89
+ * Subscribe to the live observer stream for a call.
90
+ *
91
+ * Returns a {@link ReconnectingWebSocketHandle} that resolves
92
+ * ``handle.done`` when the stream terminates (consumer-aborted, terminal
93
+ * close code, or reconnect budget exhausted). Errors are surfaced through
94
+ * ``onError``; the promise never rejects.
95
+ */
96
+ subscribe(options) {
97
+ const url = buildObserverUrl({
98
+ baseUrl: this.agentBaseUrl ?? this.platformBaseUrl,
99
+ workspaceId: this.workspaceId,
100
+ callSid: options.callSid,
101
+ observerUrl: options.observerUrl,
102
+ });
103
+ const protocols = observerAuthProtocols(options.token);
104
+ return createReconnectingWebSocket({
105
+ url,
106
+ protocols: [...protocols],
107
+ onMessage: (ev) => {
108
+ const parsed = parseObserverFrame(ev.data);
109
+ if (parsed) {
110
+ try {
111
+ options.onEvent(parsed);
112
+ }
113
+ catch {
114
+ // Consumer threw in onEvent — do not let it kill the loop.
115
+ }
116
+ }
117
+ },
118
+ onStateChange: options.onStateChange,
119
+ onReconnect: options.onReconnect,
120
+ onError: options.onError,
121
+ signal: options.signal,
122
+ idleTimeoutMs: options.idleTimeoutMs ?? 60_000,
123
+ initialDelayMs: options.initialDelayMs ?? 1_000,
124
+ maxDelayMs: options.maxDelayMs ?? 30_000,
125
+ maxReconnects: options.maxReconnects ?? 10,
126
+ webSocketFactory: options.webSocketFactory,
127
+ });
128
+ }
129
+ }
130
+ const CALL_SID_RE = /^CA[a-zA-Z0-9]{32}$/;
131
+ function buildObserverUrl(args) {
132
+ if (!args.workspaceId) {
133
+ throw new ConfigurationError('workspaceId is required to build the observer URL');
134
+ }
135
+ if (!args.callSid) {
136
+ throw new ConfigurationError('callSid is required to subscribe to the observer stream');
137
+ }
138
+ if (args.observerUrl) {
139
+ // Override path — the consumer has already constructed the full URL
140
+ // (e.g. via a custom voice-agent gateway helper). Skip the Twilio CA
141
+ // SID grammar check; the override owns the URL shape.
142
+ return parseOverride(args.observerUrl).toString();
143
+ }
144
+ // Default path — derive ``/v1/{ws}/observers/{callSid}/ws`` and validate
145
+ // the CA SID grammar so a typo fails at the function boundary instead of
146
+ // mid-reconnect-loop with an opaque 4001.
147
+ if (!CALL_SID_RE.test(args.callSid)) {
148
+ throw new ConfigurationError(`callSid does not match Twilio CA SID format (CA + 32 hex chars): ${args.callSid}`);
149
+ }
150
+ return deriveFromBase(args.baseUrl, args.workspaceId, args.callSid).toString();
151
+ }
152
+ function parseOverride(observerUrl) {
153
+ let url;
154
+ try {
155
+ url = new URL(observerUrl);
156
+ }
157
+ catch (cause) {
158
+ throw new ConfigurationError(`observerUrl must be an absolute URL: ${String(cause)}`);
159
+ }
160
+ if (url.protocol !== 'ws:' && url.protocol !== 'wss:') {
161
+ throw new ConfigurationError('observerUrl overrides must use ws: or wss: URLs');
162
+ }
163
+ if (url.search || url.hash) {
164
+ throw new ConfigurationError('observerUrl overrides must not include query parameters or fragments');
165
+ }
166
+ return url;
167
+ }
168
+ function deriveFromBase(baseUrl, workspaceId, callSid) {
169
+ let parsed;
170
+ try {
171
+ parsed = new URL(baseUrl);
172
+ }
173
+ catch (cause) {
174
+ throw new ConfigurationError(`observerUrl cannot be derived from baseUrl: ${String(cause)}`);
175
+ }
176
+ // Map http(s) to ws(s) — the agent-engine ALB serves both on the same host.
177
+ let scheme;
178
+ if (parsed.protocol === 'https:' || parsed.protocol === 'wss:')
179
+ scheme = 'wss:';
180
+ else if (parsed.protocol === 'http:' || parsed.protocol === 'ws:')
181
+ scheme = 'ws:';
182
+ else {
183
+ throw new ConfigurationError(`observerUrl can only be derived from an http, https, ws, or wss baseUrl: ${baseUrl}`);
184
+ }
185
+ // The pathname must be '/' — observer paths are owned by this helper,
186
+ // not the consumer's baseUrl gateway.
187
+ if (parsed.pathname !== '/' && parsed.pathname !== '') {
188
+ throw new ConfigurationError('observerUrl can only be derived from an origin-only baseUrl; pass observerUrl explicitly when using path-prefixed gateways');
189
+ }
190
+ const out = new URL(`${scheme}//${parsed.host}/v1/${encodeURIComponent(workspaceId)}/observers/${encodeURIComponent(callSid)}/ws`);
191
+ return out;
192
+ }
193
+ // ---------------------------------------------------------------------------
194
+ // Frame parser
195
+ // ---------------------------------------------------------------------------
196
+ /**
197
+ * Parse a raw WebSocket frame into a typed {@link ObserverSSEEvent}.
198
+ *
199
+ * Drift-tolerant: returns ``null`` on JSON decode errors, non-object
200
+ * payloads, missing ``type`` discriminator, or unknown discriminator
201
+ * values. The static type of ``ObserverSSEEvent`` is the contract — the
202
+ * server may add new event types ahead of an SDK release and the consumer's
203
+ * exhaustive ``switch`` will simply not match them, leaving the unknown
204
+ * frame on the floor.
205
+ */
206
+ function parseObserverFrame(data) {
207
+ let text;
208
+ if (typeof data === 'string') {
209
+ text = data;
210
+ }
211
+ else if (data instanceof ArrayBuffer) {
212
+ text = new TextDecoder().decode(data);
213
+ }
214
+ else if (ArrayBuffer.isView(data)) {
215
+ // ``data`` is some TypedArray; @types/node TextDecoder.decode wants
216
+ // ``BufferSource``. Pass through as ``Uint8Array`` over the underlying
217
+ // buffer so every TypedArray variant decodes consistently.
218
+ const view = data;
219
+ text = new TextDecoder().decode(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
220
+ }
221
+ else {
222
+ return null;
223
+ }
224
+ let payload;
225
+ try {
226
+ payload = JSON.parse(text);
227
+ }
228
+ catch {
229
+ return null;
230
+ }
231
+ if (typeof payload !== 'object' || payload === null || Array.isArray(payload))
232
+ return null;
233
+ const obj = payload;
234
+ if (typeof obj['type'] !== 'string')
235
+ return null;
236
+ return obj;
237
+ }
238
+ //# sourceMappingURL=observers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observers.js","sourceRoot":"","sources":["../../src/resources/observers.ts"],"names":[],"mappings":"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"}
@@ -3,16 +3,12 @@ import { WorkspaceScopedResource, extractData } from './base.js';
3
3
  * Manage Amigo Platform workspaces.
4
4
  * Workspaces are the top-level tenancy boundary for all resources.
5
5
  *
6
- * Note: list and create operate at account level (/v1/workspaces),
7
- * while get, update, and archive operate on a specific workspace.
6
+ * Note: list operates at account level (/v1/workspaces); creation goes
7
+ * through the authenticated self-service flow. The unauthenticated
8
+ * ``POST /v1/workspaces`` was removed in platform-api PR #2378 (orphan-
9
+ * maker). Get/update/archive/provision operate on a specific workspace.
8
10
  */
9
11
  export class WorkspacesResource extends WorkspaceScopedResource {
10
- /** Create a new workspace (unauthenticated — no owner membership created) */
11
- async create(body) {
12
- return extractData(await this.client.POST('/v1/workspaces', {
13
- body,
14
- }));
15
- }
16
12
  /** Create a workspace for the authenticated user and attach owner access */
17
13
  async createSelfService(body) {
18
14
  return extractData(await this.client.POST('/v1/workspaces/self-service', {
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../src/resources/workspaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../src/resources/workspaces.ts"],"names":[],"mappings":"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"}
@@ -2,20 +2,74 @@
2
2
  * Error hierarchy for the Amigo Platform SDK.
3
3
  * All errors extend AmigoError which can be caught with a single catch.
4
4
  */
5
+ import type { components } from '../generated/api.js';
5
6
  export interface ErrorContext {
6
7
  statusCode?: number;
7
8
  errorCode?: string;
8
9
  requestId?: string;
9
10
  detail?: string;
10
11
  context?: Record<string, unknown>;
12
+ /** Parsed error body (typed when recognized) */
13
+ errorBody?: PlatformErrorBody;
14
+ /** Raw body string for diagnostic logging — populated even on parse failure */
15
+ rawBody?: string;
11
16
  }
17
+ /**
18
+ * FastAPI 422 validation-error body.
19
+ * Surfaces from openapi-typescript so consumers can read field-level errors.
20
+ */
21
+ export type HttpValidationErrorBody = components['schemas']['HTTPValidationError'];
22
+ /**
23
+ * Default FastAPI HTTPException shape (`raise HTTPException(status_code, detail=...)`).
24
+ *
25
+ * Most platform-api routes that don't define an explicit error model return
26
+ * this shape. `detail` may be a free-form string or a JSON-serializable object.
27
+ */
28
+ export interface HttpExceptionBody {
29
+ detail: string | Record<string, unknown> | unknown[];
30
+ /** Populated by request-id middleware on bounded routes */
31
+ request_id?: string;
32
+ /** Populated by typed error responses (e.g. Surface lifecycle errors) */
33
+ error_code?: string;
34
+ }
35
+ /**
36
+ * Fallback shape used when the response body fails to parse or is empty.
37
+ * `rawBody` is the verbatim text (truncated to 8 KB to avoid log bloat).
38
+ */
39
+ export interface UnparseableErrorBody {
40
+ detail: string;
41
+ raw_body: string;
42
+ }
43
+ /**
44
+ * Discriminated union of all error body shapes the platform API emits.
45
+ *
46
+ * Consumers should use the type guards (`isHttpException`,
47
+ * `isHttpValidationError`, `isUnparseableErrorBody`) rather than checking
48
+ * fields directly — both `HttpExceptionBody` and `HttpValidationErrorBody`
49
+ * have a `detail` field but it is shaped differently.
50
+ */
51
+ export type PlatformErrorBody = HttpExceptionBody | HttpValidationErrorBody | UnparseableErrorBody;
12
52
  /** Base class for all Amigo Platform SDK errors */
13
- export declare class AmigoError extends Error {
53
+ export declare class AmigoError<TBody extends PlatformErrorBody = PlatformErrorBody> extends Error {
14
54
  readonly statusCode?: number;
15
55
  readonly errorCode?: string;
16
56
  readonly requestId?: string;
17
57
  readonly detail?: string;
18
58
  readonly context?: Record<string, unknown>;
59
+ /**
60
+ * Typed body of the error response, when one was returned and successfully
61
+ * parsed. Use the `isHttpException` / `isHttpValidationError` /
62
+ * `isUnparseableErrorBody` type guards to narrow the discriminated union.
63
+ *
64
+ * Named `errorBody` (not `body`) to avoid colliding with the legacy
65
+ * `ParseError.body: string` field.
66
+ */
67
+ readonly errorBody?: TBody;
68
+ /**
69
+ * Raw response body (truncated to 8 KB). Populated even when parsing fails,
70
+ * so callers always have something to log when debugging server errors.
71
+ */
72
+ readonly rawBody?: string;
19
73
  constructor(message: string, ctx?: ErrorContext);
20
74
  toJSON(): Record<string, unknown>;
21
75
  }
@@ -82,4 +136,42 @@ export declare function isNotFoundError(err: unknown): err is NotFoundError;
82
136
  export declare function isRateLimitError(err: unknown): err is RateLimitError;
83
137
  export declare function isAuthenticationError(err: unknown): err is AuthenticationError;
84
138
  export declare function isRequestTimeoutError(err: unknown): err is RequestTimeoutError;
139
+ export declare function isPermissionError(err: unknown): err is PermissionError;
140
+ export declare function isConflictError(err: unknown): err is ConflictError;
141
+ export declare function isValidationError(err: unknown): err is ValidationError;
142
+ export declare function isServerError(err: unknown): err is ServerError;
143
+ export declare function isNetworkError(err: unknown): err is NetworkError;
144
+ /**
145
+ * Narrowed AmigoError where `errorBody` is guaranteed non-undefined.
146
+ * Used as the return-type for body type guards so consumers don't need to
147
+ * re-assert `errorBody !== undefined` after the guard.
148
+ */
149
+ export type AmigoErrorWithBody<TBody extends PlatformErrorBody> = AmigoError<TBody> & {
150
+ readonly errorBody: TBody;
151
+ };
152
+ /**
153
+ * True when `err.errorBody` is the FastAPI 422 validation-error shape (an
154
+ * object with `detail: ValidationError[]`). Lets consumers iterate
155
+ * field-level errors without `as any`:
156
+ *
157
+ * ```ts
158
+ * if (isHttpValidationError(err)) {
159
+ * for (const issue of err.errorBody.detail ?? []) {
160
+ * console.log(issue.loc, issue.msg)
161
+ * }
162
+ * }
163
+ * ```
164
+ */
165
+ export declare function isHttpValidationError(err: unknown): err is AmigoErrorWithBody<HttpValidationErrorBody>;
166
+ /**
167
+ * True when `err.errorBody` is the default FastAPI HTTPException shape
168
+ * (`{ detail: string | object | array }`, possibly with `error_code` /
169
+ * `request_id`). This is the most common error body across platform-api.
170
+ */
171
+ export declare function isHttpException(err: unknown): err is AmigoErrorWithBody<HttpExceptionBody>;
172
+ /**
173
+ * True when the response body could not be parsed as JSON (or was empty).
174
+ * `err.errorBody.raw_body` is the verbatim text (truncated to 8 KB).
175
+ */
176
+ export declare function isUnparseableErrorBody(err: unknown): err is AmigoErrorWithBody<UnparseableErrorBody>;
85
177
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Reconnecting WebSocket primitive shared by the SDK's WS-based realtime
3
+ * helpers (text-stream, session-connect, observer).
4
+ *
5
+ * The platform exposes three workspace-scoped WebSocket surfaces with similar
6
+ * lifecycle requirements:
7
+ *
8
+ * * Resume on transient drops with exponential backoff + full jitter
9
+ * * Treat 4001 (client error) and 4403 (auth) close codes as terminal
10
+ * * Treat 4029 (rate limit / cap) as terminal-but-retryable on a slow timer
11
+ * * Watchdog the connection: if no message arrives within an idle window,
12
+ * the upstream is dead even if the TCP socket has not closed; force a
13
+ * reconnect
14
+ * * Surface every typed message through ``onMessage`` and every state
15
+ * transition through ``onStateChange``
16
+ *
17
+ * Before this primitive existed, every consumer (developer-console
18
+ * useStreamSession, useCallObserver, agent-engineering scripts) re-implemented
19
+ * the loop with subtle bugs (different idle thresholds, missing retry budget,
20
+ * no terminal-code handling). This module is the single canonical
21
+ * implementation; resource helpers compose it with their own message parsers
22
+ * and protocol details.
23
+ *
24
+ * @see ReconnectingWebSocket
25
+ * @see EventsResource for the analogous SSE-based helper
26
+ */
27
+ /** Lifecycle states reported via {@link ReconnectingWebSocketOptions.onStateChange}. */
28
+ export type ReconnectingWebSocketState = 'connecting' | 'open' | 'closing' | 'closed' | 'reconnecting' | 'terminal';
29
+ /** Reasons surfaced to {@link ReconnectingWebSocketOptions.onError} on a terminal close. */
30
+ export type ReconnectingWebSocketErrorReason = 'auth' | 'rate_limited' | 'client_error' | 'server_error' | 'reconnect_budget_exhausted' | 'aborted' | 'idle_watchdog' | 'open_failed' | 'unknown';
31
+ /** Structured terminal error surfaced to consumers. */
32
+ export declare class ReconnectingWebSocketError extends Error {
33
+ readonly reason: ReconnectingWebSocketErrorReason;
34
+ readonly closeCode: number | undefined;
35
+ readonly closeReason: string | undefined;
36
+ readonly attempts: number;
37
+ constructor(message: string, reason: ReconnectingWebSocketErrorReason, closeCode: number | undefined, closeReason: string | undefined, attempts: number);
38
+ }
39
+ /**
40
+ * Constructor for the underlying WebSocket. Defaults to the global
41
+ * ``WebSocket`` (browsers, Bun, Deno, Node 22+ via global) if available.
42
+ *
43
+ * Pass an explicit factory in environments without a global (older Node) or
44
+ * for tests that swap in a mock.
45
+ */
46
+ export type WebSocketFactory = (url: string, protocols?: string | string[]) => WebSocket;
47
+ /** Options for {@link ReconnectingWebSocket}. */
48
+ export interface ReconnectingWebSocketOptions {
49
+ /** Target ws:// or wss:// URL. */
50
+ url: string;
51
+ /**
52
+ * Optional WebSocket subprotocols. The platform's auth scheme passes the
53
+ * bearer token here (``['auth', token]``) so it never appears in the URL.
54
+ */
55
+ protocols?: string | string[];
56
+ /**
57
+ * Initial backoff delay (ms). Doubles with full jitter on each successive
58
+ * failure up to ``maxDelayMs``. Default ``1_000``.
59
+ */
60
+ initialDelayMs?: number;
61
+ /** Cap on the reconnect backoff delay (ms). Default ``30_000``. */
62
+ maxDelayMs?: number;
63
+ /**
64
+ * Maximum number of reconnect attempts before giving up. Default ``10``.
65
+ * Set to ``Infinity`` to retry forever (rely on AbortSignal for shutdown).
66
+ */
67
+ maxReconnects?: number;
68
+ /**
69
+ * Idle watchdog (ms). If no message arrives within this window the
70
+ * connection is considered dead and is force-closed; the reconnect loop
71
+ * then handles the rebuild. Default ``45_000`` (matches the longest
72
+ * platform endpoint heartbeat). Set to ``0`` to disable.
73
+ */
74
+ idleTimeoutMs?: number;
75
+ /**
76
+ * Cancellation signal. Aborting the signal closes the underlying socket
77
+ * and stops the reconnect loop. The ``done`` promise resolves once the
78
+ * teardown completes.
79
+ */
80
+ signal?: AbortSignal;
81
+ /**
82
+ * Optional WebSocket factory. Defaults to ``globalThis.WebSocket`` if
83
+ * available; throws at first connect attempt otherwise.
84
+ */
85
+ webSocketFactory?: WebSocketFactory;
86
+ /**
87
+ * Invoked when the underlying socket transitions states. Mostly useful
88
+ * for surfacing reconnects to the UI (e.g., "Reconnecting…" banner).
89
+ */
90
+ onStateChange?: (state: ReconnectingWebSocketState) => void;
91
+ /**
92
+ * Invoked once per inbound frame. ``MessageEvent.data`` is delivered raw
93
+ * — consumers parse JSON / binary themselves.
94
+ */
95
+ onMessage: (event: MessageEvent) => void;
96
+ /**
97
+ * Invoked just before each reconnect attempt with the 1-based attempt
98
+ * number, the planned delay (ms), and the close code that triggered the
99
+ * reconnect.
100
+ */
101
+ onReconnect?: (info: {
102
+ attempt: number;
103
+ delayMs: number;
104
+ closeCode: number | undefined;
105
+ }) => void;
106
+ /**
107
+ * Invoked exactly once per ``ReconnectingWebSocket`` instance on a
108
+ * terminal failure (consumer-aborted, reconnect budget exhausted, or a
109
+ * close code in the terminal set: 4001 / 4003 / 4403 / 4100 / 1008).
110
+ */
111
+ onError?: (error: ReconnectingWebSocketError) => void;
112
+ }
113
+ /** Handle returned by {@link createReconnectingWebSocket}. */
114
+ export interface ReconnectingWebSocketHandle {
115
+ /**
116
+ * Resolves when the loop has fully stopped (post-abort cleanup complete).
117
+ * Never rejects; consume errors via ``onError``.
118
+ */
119
+ done: Promise<void>;
120
+ /**
121
+ * Send a frame on the currently open socket. Throws if no socket is
122
+ * currently open. Use ``onStateChange`` to gate sends, or buffer in
123
+ * caller code.
124
+ */
125
+ send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
126
+ /**
127
+ * Close the connection and stop reconnecting. Equivalent to aborting the
128
+ * caller-supplied signal. Idempotent.
129
+ */
130
+ close(code?: number, reason?: string): void;
131
+ /** Latest known lifecycle state. */
132
+ readonly state: ReconnectingWebSocketState;
133
+ }
134
+ /**
135
+ * Build a managed reconnecting WebSocket.
136
+ *
137
+ * The returned handle is the only public surface; the underlying
138
+ * ``WebSocket`` is held privately so consumers cannot bypass the lifecycle
139
+ * machinery (which would defeat the watchdog and reconnect loop).
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const handle = createReconnectingWebSocket({
144
+ * url: client.conversations.sessionConnectUrl({ serviceId, entityId }),
145
+ * protocols: sessionConnectAuthProtocols(apiKey),
146
+ * onMessage: (e) => console.log('frame', e.data),
147
+ * onStateChange: (s) => console.log('state', s),
148
+ * onError: (err) => console.error('terminal:', err.reason, err.closeCode),
149
+ * });
150
+ *
151
+ * handle.send(JSON.stringify({ type: 'user_text', text: 'hi' }));
152
+ * await handle.done; // resolves after handle.close() or terminal error
153
+ * ```
154
+ */
155
+ export declare function createReconnectingWebSocket(options: ReconnectingWebSocketOptions): ReconnectingWebSocketHandle;
156
+ //# sourceMappingURL=reconnecting-websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnecting-websocket.d.ts","sourceRoot":"","sources":["../../../src/core/reconnecting-websocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,wFAAwF;AACxF,MAAM,MAAM,0BAA0B,GAClC,YAAY,GACZ,MAAM,GACN,SAAS,GACT,QAAQ,GACR,cAAc,GACd,UAAU,CAAA;AAEd,4FAA4F;AAC5F,MAAM,MAAM,gCAAgC,GACxC,MAAM,GACN,cAAc,GACd,cAAc,GACd,cAAc,GACd,4BAA4B,GAC5B,SAAS,GACT,eAAe,GACf,aAAa,GACb,SAAS,CAAA;AAEb,uDAAuD;AACvD,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,MAAM,EAAE,gCAAgC,CAAA;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBAGvB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gCAAgC,EACxC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,QAAQ,EAAE,MAAM;CASnB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,SAAS,CAAA;AAExF,iDAAiD;AACjD,MAAM,WAAW,4BAA4B;IAC3C,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAA;IAEX;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAE7B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IAEpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAA;IAE3D;;;OAGG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAExC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,CAAA;IAEjG;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,CAAA;CACtD;AAED,8DAA8D;AAC9D,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAEnB;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,GAAG,eAAe,GAAG,IAAI,CAAA;IAEnE;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAE3C,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,0BAA0B,CAAA;CAC3C;AA8BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,2BAA2B,CAiF7B"}