@alexkroman1/aai-ui 0.12.3 → 0.13.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.
- package/README.md +257 -0
- package/dist/_colors-CpZO-88A.js +78 -0
- package/dist/_module-url-C13kAJ87.js +15 -0
- package/dist/_page-shell.d.ts +11 -0
- package/dist/_recover-run.d.ts +79 -0
- package/dist/_repeat-until.d.ts +30 -0
- package/dist/_run-controls.d.ts +33 -0
- package/dist/_submission-state.d.ts +92 -0
- package/dist/_tap-to-talk-state.d.ts +88 -0
- package/dist/_utils-Mi-SCFA1.js +47 -0
- package/dist/_utils.d.ts +26 -0
- package/dist/_web-storage.d.ts +43 -0
- package/dist/_workflow-api-ref.d.ts +37 -0
- package/dist/_workflow-files.d.ts +34 -0
- package/dist/_workflow-test-defs.d.ts +38 -0
- package/dist/aai-logo-D8pMVn9_.js +85 -0
- package/dist/agent-state-labels.d.ts +65 -0
- package/dist/agent-state.d.ts +108 -0
- package/dist/audio/capture.d.ts +44 -0
- package/dist/audio/index.d.ts +18 -0
- package/dist/audio/index.js +431 -0
- package/dist/audio/preconnect.d.ts +87 -0
- package/dist/audio/voice-io.d.ts +112 -0
- package/dist/build-default-client.d.ts +1 -0
- package/dist/chat-view-BCbI7gD4.js +396 -0
- package/dist/client-config-C7fQrioM.js +139 -0
- package/dist/client-config.d.ts +119 -0
- package/dist/client-dir.d.ts +44 -0
- package/dist/client-dir.js +58 -0
- package/dist/client-identity.d.ts +131 -0
- package/dist/client-tool.d.ts +51 -0
- package/dist/components/_colors.d.ts +73 -0
- package/dist/components/_form-readiness.d.ts +56 -0
- package/dist/components/_form-values.d.ts +19 -0
- package/dist/components/aai-logo.d.ts +12 -0
- package/dist/components/audio-result.d.ts +94 -0
- package/dist/components/auto-scroll.d.ts +74 -0
- package/dist/components/bullet-list.d.ts +74 -0
- package/dist/components/button.d.ts +29 -21
- package/dist/components/button.js +62 -23
- package/dist/components/chat-view.d.ts +24 -18
- package/dist/components/chat-view.js +2 -60
- package/dist/components/console-shell.d.ts +85 -0
- package/dist/components/controls.d.ts +21 -6
- package/dist/components/controls.js +31 -19
- package/dist/components/conversation-view.d.ts +130 -0
- package/dist/components/eyebrow.d.ts +12 -0
- package/dist/components/facts.d.ts +81 -0
- package/dist/components/form-fields.d.ts +142 -0
- package/dist/components/form-types.d.ts +73 -0
- package/dist/components/form.d.ts +96 -0
- package/dist/components/markdown.d.ts +57 -0
- package/dist/components/message-list.d.ts +34 -7
- package/dist/components/message-list.js +2 -75
- package/dist/components/session-controls.d.ts +125 -0
- package/dist/components/session-error-banner.d.ts +69 -0
- package/dist/components/session-state-dot.d.ts +111 -0
- package/dist/components/sidebar-layout.d.ts +31 -10
- package/dist/components/sidebar-layout.js +32 -12
- package/dist/components/start-screen.d.ts +17 -6
- package/dist/components/start-screen.js +34 -14
- package/dist/components/tool-call-block.d.ts +15 -14
- package/dist/components/tool-call-block.js +2 -117
- package/dist/components/tool-call-row.d.ts +75 -0
- package/dist/components/tool-config-context.d.ts +22 -0
- package/dist/components/upload-progress.d.ts +76 -0
- package/dist/components/url-chips.d.ts +29 -0
- package/dist/components/workflow-fields.d.ts +46 -0
- package/dist/components/workflow-pending-note.d.ts +81 -0
- package/dist/components/workflow-progress.d.ts +81 -0
- package/dist/components/workflow-run-error.d.ts +48 -0
- package/dist/components/workflow-run-panel.d.ts +79 -0
- package/dist/context.d.ts +288 -0
- package/dist/context.js +382 -0
- package/dist/conversation-log.d.ts +88 -0
- package/dist/default-client/assets/_module-url-BX0RuRU2.js +1 -0
- package/dist/default-client/assets/audio-cGFGID-2.js +1 -0
- package/dist/default-client/assets/capture-processor-BUABoo3_.js +90 -0
- package/dist/default-client/assets/index-8ihb1Urm.css +2 -0
- package/dist/default-client/assets/index-BQURVARl.js +126 -0
- package/dist/default-client/assets/playback-processor-ABOa11j0.js +314 -0
- package/dist/default-client/favicon.ico +0 -0
- package/dist/default-client/index.html +15 -0
- package/dist/default-client.d.ts +23 -0
- package/dist/define-client.d.ts +162 -26
- package/dist/define-client.js +201 -55
- package/dist/eyebrow-UfmSz9yy.js +27 -0
- package/dist/hooks-DN4gHYsj.js +182 -0
- package/dist/hooks.d.ts +172 -0
- package/dist/hooks.js +3 -0
- package/dist/hooks.test-d.d.ts +14 -0
- package/dist/inbox-protocol.d.ts +128 -0
- package/dist/inbox.d.ts +132 -0
- package/dist/index.d.ts +126 -29
- package/dist/index.js +5500 -15
- package/dist/internal.d.ts +43 -0
- package/dist/internal.js +8 -0
- package/dist/linked-client.d.ts +70 -0
- package/dist/message-list-DHZcLhRA.js +682 -0
- package/dist/notice-player.d.ts +70 -0
- package/dist/page.d.ts +114 -0
- package/dist/phone.d.ts +50 -0
- package/dist/route-fetch.d.ts +79 -0
- package/dist/session/audio-effects.d.ts +31 -0
- package/dist/session/audio-setup.d.ts +57 -0
- package/dist/session/audio-state.d.ts +157 -0
- package/dist/session/browser-session.d.ts +30 -0
- package/dist/session/close.d.ts +26 -0
- package/dist/session/dial.d.ts +65 -0
- package/dist/session/handshake.d.ts +60 -0
- package/dist/session/index.d.ts +17 -0
- package/dist/session/index.js +2 -0
- package/dist/session/messages.d.ts +63 -0
- package/dist/session/mic.d.ts +64 -0
- package/dist/session/preconnect.d.ts +48 -0
- package/dist/session/reconnect.d.ts +25 -0
- package/dist/session/resume-store.d.ts +57 -0
- package/dist/session/state.d.ts +146 -0
- package/dist/session/ticket.d.ts +44 -0
- package/dist/session/types.d.ts +476 -0
- package/dist/session/url.d.ts +17 -0
- package/dist/session/user-turn.d.ts +55 -0
- package/dist/session-CE0Ipsb3.js +2129 -0
- package/dist/stored-value.d.ts +103 -0
- package/dist/tool-call-block-uXtMOUWN.js +204 -0
- package/dist/tool-config-context-Es4YUzV2.js +19 -0
- package/dist/types.d.ts +272 -34
- package/dist/types.js +35 -4
- package/dist/upload/files.d.ts +83 -0
- package/dist/upload/index.d.ts +15 -0
- package/dist/upload/pause.d.ts +31 -0
- package/dist/upload/recall.d.ts +67 -0
- package/dist/upload/report.d.ts +26 -0
- package/dist/upload/session.d.ts +99 -0
- package/dist/url-chips-oyy_Eiqh.js +239 -0
- package/dist/use-client-runs.d.ts +87 -0
- package/dist/use-conversation-log.d.ts +86 -0
- package/dist/use-conversation.d.ts +131 -0
- package/dist/use-copy.d.ts +74 -0
- package/dist/use-download-url.d.ts +84 -0
- package/dist/use-flash.d.ts +61 -0
- package/dist/use-inbox.d.ts +101 -0
- package/dist/use-push-to-talk.d.ts +105 -0
- package/dist/use-route-mutation.d.ts +113 -0
- package/dist/use-route.d.ts +82 -0
- package/dist/use-run-key.d.ts +133 -0
- package/dist/use-session-controls.d.ts +69 -0
- package/dist/use-session-id.d.ts +57 -0
- package/dist/use-tap-to-talk.d.ts +138 -0
- package/dist/use-user-transcript-uyHhzy4d.js +73 -0
- package/dist/use-user-transcript.d.ts +75 -0
- package/dist/use-workflow-form.d.ts +285 -0
- package/dist/use-workflow-progress.d.ts +137 -0
- package/dist/use-workflow-run-DdhWmbx-.js +697 -0
- package/dist/use-workflow-run.d.ts +100 -0
- package/dist/use-workflow-runs.d.ts +71 -0
- package/dist/use-workflow-stream.d.ts +154 -0
- package/dist/use-workflows.d.ts +77 -0
- package/dist/workflow-client.d.ts +136 -0
- package/dist/workflow-def-types.d.ts +31 -0
- package/dist/workflow-events.d.ts +39 -0
- package/dist/workflow-field-kind.d.ts +95 -0
- package/dist/workflow-status-labels.d.ts +35 -0
- package/dist/worklets/_module-url.d.ts +10 -0
- package/dist/worklets/_playback-bench-harness.d.ts +181 -0
- package/dist/worklets/_playback-bench-host.d.ts +63 -0
- package/dist/worklets/_playback-bench-page.d.ts +65 -0
- package/dist/worklets/_tts-trace-harness.d.ts +142 -0
- package/dist/worklets/_worklet-test-utils.d.ts +27 -0
- package/dist/worklets/capture-processor.d.ts +4 -2
- package/dist/worklets/capture-processor.js +73 -33
- package/dist/worklets/playback-processor.d.ts +4 -2
- package/dist/worklets/playback-processor.js +258 -42
- package/package.json +57 -32
- package/styles.css +152 -30
- package/dist/audio.d.ts +0 -45
- package/dist/audio.js +0 -121
- package/dist/client-context.d.ts +0 -33
- package/dist/client-context.js +0 -15
- package/dist/client-handler.d.ts +0 -43
- package/dist/components/app.d.ts +0 -23
- package/dist/components/app.js +0 -41
- package/dist/components/error-banner.d.ts +0 -21
- package/dist/components/error-banner.js +0 -27
- package/dist/components/message-bubble.d.ts +0 -23
- package/dist/components/message-bubble.js +0 -35
- package/dist/components/state-indicator.d.ts +0 -29
- package/dist/components/state-indicator.js +0 -37
- package/dist/components/thinking-indicator.d.ts +0 -16
- package/dist/components/thinking-indicator.js +0 -34
- package/dist/components/tool-icons.d.ts +0 -17
- package/dist/components/tool-icons.js +0 -128
- package/dist/components/transcript.d.ts +0 -25
- package/dist/components/transcript.js +0 -35
- package/dist/session-CWB7vmqz.js +0 -429
- package/dist/session.d.ts +0 -69
- package/dist/session.js +0 -2
- package/dist/signals.d.ts +0 -120
- package/dist/signals.js +0 -161
- package/dist/tsdown.config.d.ts +0 -2
- package/dist/types.test-d.d.ts +0 -7
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the next connection attempt is DIALLED, and the resume identity it dials
|
|
3
|
+
* with.
|
|
4
|
+
*
|
|
5
|
+
* Split out of `session/browser-session.ts` at the 500-line cap, along the seam that file
|
|
6
|
+
* already established when it moved socket plumbing into
|
|
7
|
+
* `session/reconnect.ts`: the state machine there reads as protocol logic,
|
|
8
|
+
* and this is the address it sends it to. What makes it one module rather than
|
|
9
|
+
* three extracted functions is that the three pieces of mutable state involved —
|
|
10
|
+
* the session id, whether this connection has ever completed a handshake, and
|
|
11
|
+
* whether the server is a broker — are read by nothing else in the core, and
|
|
12
|
+
* every one of them is only meaningful in the sentence "the URL for the next
|
|
13
|
+
* attempt".
|
|
14
|
+
*/
|
|
15
|
+
import type { WebSocketConstructor } from "../types.ts";
|
|
16
|
+
import { type SessionTokenOption } from "./ticket.ts";
|
|
17
|
+
/** What the dialer needs from the session's options. */
|
|
18
|
+
export type DialOptions = {
|
|
19
|
+
platformUrl: string;
|
|
20
|
+
/** Tests inject one; it connects to the same-origin path and never reconnects. */
|
|
21
|
+
WebSocket?: WebSocketConstructor | undefined;
|
|
22
|
+
/** An id the caller manages itself — wins over what a previous load stored. */
|
|
23
|
+
resumeSessionId?: string | undefined;
|
|
24
|
+
/** Where the client is — see `VoiceSessionOptions.location`. Read per attempt. */
|
|
25
|
+
location?: string | (() => string | undefined) | undefined;
|
|
26
|
+
/** The owner's number — see `VoiceSessionOptions.phone`. Read per attempt. */
|
|
27
|
+
phone?: string | (() => string | undefined) | undefined;
|
|
28
|
+
/** This client's device id — see `VoiceSessionOptions.client`. Read per attempt. */
|
|
29
|
+
client?: string | (() => string | undefined) | undefined;
|
|
30
|
+
/** The session ticket — see `VoiceSessionOptions.token`. Asked per attempt. */
|
|
31
|
+
token?: SessionTokenOption;
|
|
32
|
+
};
|
|
33
|
+
export type Dialer = {
|
|
34
|
+
/** A socket for this attempt. */
|
|
35
|
+
open(): InstanceType<WebSocketConstructor>;
|
|
36
|
+
/**
|
|
37
|
+
* A completed handshake: adopt the server's session id and record that this
|
|
38
|
+
* connection has been established, so every later attempt resumes.
|
|
39
|
+
*/
|
|
40
|
+
configured(sid: string): void;
|
|
41
|
+
/** A ticket for another socket on this server — `SessionIdentity.ticket`. */
|
|
42
|
+
ticket(): string | undefined | Promise<string | undefined>;
|
|
43
|
+
/** Drop the resume identity, so the next connect is a NEW session. */
|
|
44
|
+
forget(): void;
|
|
45
|
+
/**
|
|
46
|
+
* The session id a `config` frame CONFIRMED — `session.identity.sessionId()`.
|
|
47
|
+
* Not the resume identity above: that one is seeded from storage and from
|
|
48
|
+
* `resume(id)` before any server has said the session exists, and a page
|
|
49
|
+
* keying its history off an id no server confirmed files it under a guess.
|
|
50
|
+
*/
|
|
51
|
+
sessionId(): string | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Make `sid` the resume identity — presented as `?sessionId=` by the next
|
|
54
|
+
* attempt and stored as a `config` frame's would be — so the next connect
|
|
55
|
+
* resumes THAT session. The caller has validated it.
|
|
56
|
+
*/
|
|
57
|
+
adopt(sid: string): void;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* @param onSessionId - Told whenever the CONFIRMED id changes (a `config` frame
|
|
61
|
+
* with a new id, `forget()`), so the session can notify `useSessionId()`
|
|
62
|
+
* even when no snapshot field moved with it.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
export declare function createDialer(options: DialOptions, onSessionId?: () => void): Dialer;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The deadline on a socket that opened but never became a session.
|
|
3
|
+
*
|
|
4
|
+
* A completed WebSocket handshake is not a session. The server builds the
|
|
5
|
+
* session synchronously from its own upgrade callback and sends `config` at
|
|
6
|
+
* zero RTT (`aai/host/ws-handler.ts`), so a socket that has been open for
|
|
7
|
+
* seconds with nothing on it is not slow — its peer is not a healthy agent
|
|
8
|
+
* server. That happens: a tunnel or proxy answers the `101` while the guest
|
|
9
|
+
* behind it is wedged, or the host dies between accepting and building the
|
|
10
|
+
* session.
|
|
11
|
+
*
|
|
12
|
+
* Nothing else catches it. partysocket's `connectionTimeout` covers only the
|
|
13
|
+
* handshake and is cleared the moment `open` fires, so the session reached
|
|
14
|
+
* `state: "ready"` — painted with the same live indicator the UI gives
|
|
15
|
+
* "listening" — and stayed there permanently: no `config` means
|
|
16
|
+
* `initAudioCapture` never runs, so there is no mic, no error, no retry, and
|
|
17
|
+
* nothing on screen to say so. Measured against a server that accepts and
|
|
18
|
+
* then says nothing: `ready` at 34ms, still `ready` and errorless when the
|
|
19
|
+
* probe gave up.
|
|
20
|
+
*/
|
|
21
|
+
import type { SessionError } from "../types.ts";
|
|
22
|
+
/** What the session reports once the budget below is spent. */
|
|
23
|
+
export declare const HANDSHAKE_ERROR: SessionError;
|
|
24
|
+
export type HandshakeGuard = {
|
|
25
|
+
/** Start the deadline for the attempt that just opened. */
|
|
26
|
+
arm(): void;
|
|
27
|
+
/** Stop it — this socket is closing, or the connection is being torn down. */
|
|
28
|
+
disarm(): void;
|
|
29
|
+
/**
|
|
30
|
+
* The `config` frame arrived: stop the deadline AND spend nothing.
|
|
31
|
+
*
|
|
32
|
+
* Separate from {@link HandshakeGuard.disarm} because the budget is
|
|
33
|
+
* CONSECUTIVE, and only a completed handshake proves the peer is healthy. One
|
|
34
|
+
* guard covers a whole `connect()`, partysocket's retries included, so with a
|
|
35
|
+
* plain disarm the count survived every successful session in between: an
|
|
36
|
+
* hour-long call whose socket dropped three times, each drop timing out once
|
|
37
|
+
* before the next attempt succeeded, surfaced the permanent
|
|
38
|
+
* "Agent did not complete the session handshake" error against a peer that
|
|
39
|
+
* had answered every time. A close must NOT reset it — a wedged peer closes
|
|
40
|
+
* and reopens on its own, and resetting there is the unbounded re-dial loop
|
|
41
|
+
* the budget exists to bound.
|
|
42
|
+
*/
|
|
43
|
+
succeeded(): void;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Watch one connection's handshake.
|
|
47
|
+
*
|
|
48
|
+
* `onRetry` fires when a timed-out attempt has been re-dialed (the sandbox
|
|
49
|
+
* behind the endpoint may have been replaced, and the URL provider re-brokers
|
|
50
|
+
* on the next attempt); `onExhausted` when the budget is spent, or when the
|
|
51
|
+
* socket has no reconnect machinery at all (an injected `options.WebSocket`).
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export declare function createHandshakeGuard(opts: {
|
|
56
|
+
socket: unknown;
|
|
57
|
+
signal: AbortSignal;
|
|
58
|
+
onRetry: () => void;
|
|
59
|
+
onExhausted: () => void;
|
|
60
|
+
}): HandshakeGuard;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser session core's import surface for the rest of the package.
|
|
3
|
+
*
|
|
4
|
+
* `createBrowserSession` and the types its handle is described by are what the
|
|
5
|
+
* package builds on; every other module in `session/` (the dialer, the
|
|
6
|
+
* reconnecting socket, the handshake guard, the two statecharts, the message
|
|
7
|
+
* handlers, the audio path's bring-up) is private to this directory. Private
|
|
8
|
+
* means NOT re-exported here: guard-invariants rule 37 fails an import from
|
|
9
|
+
* outside `session/` that names any module but this one.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
export { loadAudioModules } from "./audio-setup.ts";
|
|
14
|
+
export { createBrowserSession } from "./browser-session.ts";
|
|
15
|
+
export { CLEARED_SESSION_STATE } from "./messages.ts";
|
|
16
|
+
export { resolveSessionToken, resolveSessionTokenSync, ticketCarriage } from "./ticket.ts";
|
|
17
|
+
export type { AgentCustomEvent, AgentStateFrame, BrowserSession, browserSessionBrand, SendTextOptions, SessionSnapshot, ToolCallOutcome, UserTurnControls, } from "./types.ts";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as ticketCarriage, i as resolveSessionTokenSync, n as CLEARED_SESSION_STATE, o as loadAudioModules, r as resolveSessionToken, t as createBrowserSession } from "../session-CE0Ipsb3.js";
|
|
2
|
+
export { CLEARED_SESSION_STATE, createBrowserSession, loadAudioModules, resolveSessionToken, resolveSessionTokenSync, ticketCarriage };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AudioPath } from "./audio-state.ts";
|
|
2
|
+
import type { SessionStateMachine } from "./state.ts";
|
|
3
|
+
import { type ConnState, type SessionSnapshot } from "./types.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Snapshot fields cleared when a session's conversation state is wiped —
|
|
6
|
+
* shared by the initial snapshot, `resetState()`, and `session.reset`.
|
|
7
|
+
* The empty arrays are safe to share: snapshot collections are never mutated
|
|
8
|
+
* in place, only replaced.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CLEARED_SESSION_STATE: {
|
|
11
|
+
messages: never[];
|
|
12
|
+
toolCalls: never[];
|
|
13
|
+
customEvents: never[];
|
|
14
|
+
agentState: null;
|
|
15
|
+
userTranscript: null;
|
|
16
|
+
agentTranscript: null;
|
|
17
|
+
error: null;
|
|
18
|
+
};
|
|
19
|
+
/** Config payload extracted from a `config` server message. */
|
|
20
|
+
export type SessionConfigMessage = {
|
|
21
|
+
sampleRate: number;
|
|
22
|
+
ttsSampleRate: number;
|
|
23
|
+
sid: string;
|
|
24
|
+
};
|
|
25
|
+
/** Dependencies the message handlers need from the owning session core. */
|
|
26
|
+
type MessageHandlerDeps = {
|
|
27
|
+
getSnapshot: () => SessionSnapshot;
|
|
28
|
+
updateState: (partial: Partial<SessionSnapshot>) => void;
|
|
29
|
+
conn: ConnState;
|
|
30
|
+
/** The session's state and error, as one fact — see `session/state.ts`. */
|
|
31
|
+
agentState: SessionStateMachine;
|
|
32
|
+
/**
|
|
33
|
+
* The microphone and the playback queue — see
|
|
34
|
+
* `session/audio-state.ts`. Frames say what happened (`enqueue`,
|
|
35
|
+
* `done`, `teardown`); whether the path is up, and what to do with audio
|
|
36
|
+
* that arrives before it is, are the machine's answers rather than this
|
|
37
|
+
* module's.
|
|
38
|
+
*/
|
|
39
|
+
audio: AudioPath;
|
|
40
|
+
};
|
|
41
|
+
type MessageHandlers = {
|
|
42
|
+
/**
|
|
43
|
+
* Dispatch an incoming WebSocket message.
|
|
44
|
+
*
|
|
45
|
+
* Binary frames carry raw PCM16 audio chunks. Text frames are JSON-encoded
|
|
46
|
+
* {@link SessionEvent} values validated via Zod.
|
|
47
|
+
*
|
|
48
|
+
* Returns the parsed config if the message is a `config` message,
|
|
49
|
+
* otherwise `undefined`.
|
|
50
|
+
*/
|
|
51
|
+
handleMessage(data: unknown): SessionConfigMessage | undefined;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Create the server→client message handlers for one session core.
|
|
55
|
+
*
|
|
56
|
+
* Encapsulates the per-session dedup counters (`customEventSeq`,
|
|
57
|
+
* `messageSeq`, `toolCallSeq`) that previously lived as closure locals in
|
|
58
|
+
* `createBrowserSession`. The turn-boundary epoch is NOT one of them: it lives
|
|
59
|
+
* on `conn` because the session core bumps it on teardown too (see
|
|
60
|
+
* `ConnState.turn`).
|
|
61
|
+
*/
|
|
62
|
+
export declare function createMessageHandlers(deps: MessageHandlerDeps): MessageHandlers;
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The microphone's way onto the wire — backpressure, and the caller's MUTE.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `session/browser-session.ts` at the source-length cap, along the seam the
|
|
5
|
+
* two share: both decide what a captured frame becomes on the socket, and
|
|
6
|
+
* nothing else in the core reads either.
|
|
7
|
+
*
|
|
8
|
+
* ## A muted frame is SILENCE, not an absent frame
|
|
9
|
+
*
|
|
10
|
+
* `setMicMuted(true)` keeps sending every frame the capture worklet produces,
|
|
11
|
+
* at the same length and cadence, zero-filled. Sending nothing would look
|
|
12
|
+
* cheaper and is wrong on three counts:
|
|
13
|
+
*
|
|
14
|
+
* - **Endpointing.** Hold-to-talk over an agent with AUTOMATIC turn detection
|
|
15
|
+
* is mute-until-pressed, unmute, speak, mute on release. The transcriber
|
|
16
|
+
* ends the turn on a stretch of silence; a stream that simply stops gives it
|
|
17
|
+
* no silence to measure, so the last utterance is answered late or not at
|
|
18
|
+
* all.
|
|
19
|
+
* - **The stream clock.** The transcriber timestamps by samples received. The
|
|
20
|
+
* runtime's own push-to-talk silences the mic the same way, for the same
|
|
21
|
+
* reason (`aai-runtime/src/transports/pipeline/commands.ts`, "sent as SILENCE rather than
|
|
22
|
+
* withheld").
|
|
23
|
+
* - **Idle.** Nothing is gained on the server side by going quiet: the session
|
|
24
|
+
* idle deadline deliberately does not count user audio (`ServerSession.onAudio`
|
|
25
|
+
* in the runtime), so a muted caller is retired exactly as a silent one is —
|
|
26
|
+
* while a provider that closes a socket fed no audio at all would see a gap.
|
|
27
|
+
*
|
|
28
|
+
* ## It is UI state, not connection state
|
|
29
|
+
*
|
|
30
|
+
* The flag lives on the snapshot (`micMuted`) and nothing that tears a
|
|
31
|
+
* connection down touches it — not a reconnect, a resume, `disconnect()`,
|
|
32
|
+
* `reset()` or `end()` — and it can be set before the first `connect()`, so a
|
|
33
|
+
* UI can open a typed-only session already muted. Muting sends no command and
|
|
34
|
+
* interrupts nothing; it only changes what the next frame carries.
|
|
35
|
+
*
|
|
36
|
+
* It sits AFTER the capture worklet, so the worklet's own digital-silence
|
|
37
|
+
* probe (`onMicSilent`, `MIC_SILENCE_PROBE_MS` in `audio/voice-io.ts`) still measures
|
|
38
|
+
* the real input: zeros this module writes can never read as a dead mic.
|
|
39
|
+
*
|
|
40
|
+
* @module
|
|
41
|
+
*/
|
|
42
|
+
import type { ConnState, SessionSnapshot } from "./types.ts";
|
|
43
|
+
/** What the mic sender needs from the session around it. @internal */
|
|
44
|
+
export type MicDeps = {
|
|
45
|
+
conn: ConnState;
|
|
46
|
+
snapshot: () => SessionSnapshot;
|
|
47
|
+
updateState: (partial: Partial<SessionSnapshot>) => void;
|
|
48
|
+
};
|
|
49
|
+
/** The mic's wire half — see this module's doc. @internal */
|
|
50
|
+
export type MicSender = {
|
|
51
|
+
/** Send one captured PCM16 frame — as silence while muted. */
|
|
52
|
+
sendAudio(bytes: ArrayBuffer): void;
|
|
53
|
+
/**
|
|
54
|
+
* Send the pre-connect burst (`session/preconnect.ts`) — muted like
|
|
55
|
+
* any frame, but past the backpressure drop: those frames are the audio the
|
|
56
|
+
* burst exists to deliver, bounded by `PRE_CONNECT_MAX_SECONDS`, and a
|
|
57
|
+
* dropped one would splice the caller's opener mid-word.
|
|
58
|
+
*/
|
|
59
|
+
sendBuffered(chunks: ArrayBuffer[]): void;
|
|
60
|
+
/** Mute or unmute the caller. Idempotent, local, and connection-independent. */
|
|
61
|
+
setMicMuted(muted: boolean): void;
|
|
62
|
+
};
|
|
63
|
+
/** Build one session's mic sender. @internal */
|
|
64
|
+
export declare function createMicSender(deps: MicDeps): MicSender;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-connect audio: the microphone opens when the caller presses start, not
|
|
3
|
+
* when the server's `config` frame arrives, and what they say in between is
|
|
4
|
+
* sent ahead of the live stream.
|
|
5
|
+
*
|
|
6
|
+
* Without it the mic is requested only once `config` names the audio rates —
|
|
7
|
+
* a handshake after the press, plus a sandbox boot on the platform — so an
|
|
8
|
+
* eager "hi, I need to…" spoken while the agent is still joining never reaches
|
|
9
|
+
* the server. The capture runs at {@link PRE_CONNECT_SAMPLE_RATE}, a guess
|
|
10
|
+
* `createVoiceIO` adopts whole when right and resamples when not (`audio/preconnect.ts`).
|
|
11
|
+
*
|
|
12
|
+
* ## Who owns the microphone
|
|
13
|
+
*
|
|
14
|
+
* This holder, from `begin()` until `take()`; the audio path's bring-up after
|
|
15
|
+
* that (`session/audio-setup.ts`), which releases it if the bring-up is
|
|
16
|
+
* abandoned. A reconnect BEFORE `config` keeps the capture buffering — that is
|
|
17
|
+
* exactly the audio this exists for — so only the session's terminal paths
|
|
18
|
+
* call `release()`.
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import type { PreConnectCapture } from "../audio/index.ts";
|
|
23
|
+
/**
|
|
24
|
+
* The rate the capture guesses: the SDK's default STT rate
|
|
25
|
+
* (`DEFAULT_STT_SAMPLE_RATE`), which is also the only rate an AssemblyAI S2S
|
|
26
|
+
* agent accepts. A miss costs a resample of the buffer, not the audio.
|
|
27
|
+
*/
|
|
28
|
+
export declare const PRE_CONNECT_SAMPLE_RATE = 16000;
|
|
29
|
+
/**
|
|
30
|
+
* The most pre-connect audio held — the LATEST this many seconds. Bounds a
|
|
31
|
+
* cold sandbox boot or a stalled handshake; at 16 kHz it is 320 KB, well
|
|
32
|
+
* inside the server's pre-ready buffer (`MAX_WS_PAYLOAD_BYTES`).
|
|
33
|
+
*/
|
|
34
|
+
export declare const PRE_CONNECT_MAX_SECONDS = 10;
|
|
35
|
+
/** The session core's handle on its pre-connect capture. @internal */
|
|
36
|
+
export type PreConnectAudio = {
|
|
37
|
+
/**
|
|
38
|
+
* Prefetch the audio modules, then open the mic and start buffering unless
|
|
39
|
+
* a capture is already held (or the session opted out).
|
|
40
|
+
*/
|
|
41
|
+
begin(): void;
|
|
42
|
+
/** Hand the held capture to a bring-up, or `null` when none is held. */
|
|
43
|
+
take(): Promise<PreConnectCapture | null> | null;
|
|
44
|
+
/** Release a held capture: the session is over or starting afresh. */
|
|
45
|
+
release(): void;
|
|
46
|
+
};
|
|
47
|
+
/** Build one session's pre-connect capture holder. @internal */
|
|
48
|
+
export declare function createPreConnectAudio(enabled: boolean): PreConnectAudio;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { WebSocketConstructor } from "../types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Open partysocket's reconnecting WebSocket. The URL and the subprotocols are
|
|
4
|
+
* *providers*, re-evaluated on every attempt (async supported), so each retry
|
|
5
|
+
* picks up the current broker-named endpoint, resume URL and session ticket
|
|
6
|
+
* rather than the ones the session started with. partysocket calls the URL
|
|
7
|
+
* provider first and the protocols provider straight after it, in the same
|
|
8
|
+
* tick, for each attempt.
|
|
9
|
+
*/
|
|
10
|
+
export declare function openReconnectingSocket(urlProvider: () => Promise<string>, protocolsProvider?: () => Promise<string[] | null>): InstanceType<WebSocketConstructor>;
|
|
11
|
+
/**
|
|
12
|
+
* Force a fresh connection attempt on a reconnecting socket, reporting
|
|
13
|
+
* whether it was one. Used for a failure partysocket cannot see: a socket it
|
|
14
|
+
* considers open and healthy, whose peer never completed OUR handshake.
|
|
15
|
+
* Returns false for an injected `options.WebSocket` (tests), which has no
|
|
16
|
+
* reconnect machinery — the caller then treats the failure as terminal.
|
|
17
|
+
*/
|
|
18
|
+
export declare function forceReconnect(socket: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* True while `socket` is a reconnecting socket that will retry after the
|
|
21
|
+
* close event currently being handled. partysocket schedules the retry
|
|
22
|
+
* *before* dispatching `close`, so `retryCount` already names the attempt
|
|
23
|
+
* just scheduled — at `maxRetries` it has given up.
|
|
24
|
+
*/
|
|
25
|
+
export declare function reconnectPending(socket: unknown): boolean;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a session id survives a page RELOAD.
|
|
3
|
+
*
|
|
4
|
+
* The id is what `?sessionId=` presents on reconnect, and it is the key the
|
|
5
|
+
* agent's slot state and event log live under — so a reload that cannot produce
|
|
6
|
+
* it starts a brand-new session, and a UI driven by `useAgentState` comes back
|
|
7
|
+
* empty even though the agent still holds the cart. The server side of the
|
|
8
|
+
* reconstitution was already built (`pushStateSnapshot` force-pushes the
|
|
9
|
+
* projection after hydration on every start, `state.updated` lands in
|
|
10
|
+
* `agentState`); what was missing is that nothing in the browser remembered the
|
|
11
|
+
* id across a reload. `onSessionId`/`resumeSessionId` let a client wire it by
|
|
12
|
+
* hand and exactly one of fourteen templates did, which is the shape of a
|
|
13
|
+
* default in the wrong place.
|
|
14
|
+
*
|
|
15
|
+
* **`sessionStorage`, deliberately, and this is the opposite call from the
|
|
16
|
+
* studio's session token.** A reload and a same-tab navigation survive it; a new
|
|
17
|
+
* tab and a visit tomorrow do not, which is what we want here rather than a
|
|
18
|
+
* limitation: presenting a day-old id suppresses the greeting
|
|
19
|
+
* (`parseWsUpgradeParams` keys that off the id's mere presence) and rejoins a
|
|
20
|
+
* conversation whose context is long gone. The studio token is a credential
|
|
21
|
+
* whose value is not being asked to sign out; this is a pointer into a live call.
|
|
22
|
+
*
|
|
23
|
+
* Keyed by the agent's own URL, so two agents served from one origin — which is
|
|
24
|
+
* every deployed agent, at `/:slug/` — cannot inherit each other's session.
|
|
25
|
+
*
|
|
26
|
+
* Every access is guarded, and the guard lives in `_web-storage.ts`: a session
|
|
27
|
+
* that cannot be remembered must degrade to today's behaviour rather than
|
|
28
|
+
* failing to start.
|
|
29
|
+
*/
|
|
30
|
+
/** The stored session id for this agent, or undefined. @internal */
|
|
31
|
+
export declare function readStoredSessionId(platformUrl: string): string | undefined;
|
|
32
|
+
/** Remember this agent's session id for the next load. @internal */
|
|
33
|
+
export declare function writeStoredSessionId(platformUrl: string, sessionId: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Forget it, so the next load is a NEW session.
|
|
36
|
+
*
|
|
37
|
+
* Called from `end()`, which is the clear-and-forget the "New Conversation"
|
|
38
|
+
* button runs: leaving the id behind there would have the next load rejoin the
|
|
39
|
+
* conversation the user just discarded, greeting suppressed.
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export declare function clearStoredSessionId(platformUrl: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* The last session ticket this agent's `client-config` issued — beside the id
|
|
46
|
+
* and for its reason: on the managed platform a ticket is BOUND to its session,
|
|
47
|
+
* and presenting it (`SESSION_TICKET_HEADER`) is what makes the broker re-mint
|
|
48
|
+
* for that session rather than a new one, so a reload that lost it cannot
|
|
49
|
+
* resume. As sensitive as the id it stands beside, and stored the same way.
|
|
50
|
+
*
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
export declare function readStoredTicket(platformUrl: string): string | undefined;
|
|
54
|
+
/** Remember the last server-issued ticket. @internal */
|
|
55
|
+
export declare function writeStoredTicket(platformUrl: string, ticket: string): void;
|
|
56
|
+
/** Forget it, with the session it was for. @internal */
|
|
57
|
+
export declare function clearStoredTicket(platformUrl: string): void;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser session's {@link AgentState}, and the error beside it, as a
|
|
3
|
+
* statechart.
|
|
4
|
+
*
|
|
5
|
+
* These two were written independently from thirteen sites across
|
|
6
|
+
* `session/browser-session.ts`, `session/messages.ts` and
|
|
7
|
+
* `session/audio-setup.ts`, each one deciding for itself whether its write
|
|
8
|
+
* was legal by reading the snapshot back first. Three shipped bugs came out of
|
|
9
|
+
* that, and all three are the same shape — a transition nothing forbade:
|
|
10
|
+
*
|
|
11
|
+
* - **A straggler audio chunk flipped an errored session to `"speaking"`.**
|
|
12
|
+
* Guarded by hand at the call site
|
|
13
|
+
* (`if (snap.state === "error" || (snap.state === "disconnected" && …))`).
|
|
14
|
+
* Here `error` simply does not handle `SPEAK`.
|
|
15
|
+
* - **The frame that announced a session's death also wiped the banner
|
|
16
|
+
* reporting it.** Every fatal path in the host tears the transport down, and
|
|
17
|
+
* tearing down EMITS — so `reply.cancelled` arrived right behind the error and
|
|
18
|
+
* `toListening()` painted a live-mic state over it. A missing provider key is
|
|
19
|
+
* the case that made it visible: the one message that says exactly what to fix
|
|
20
|
+
* was on screen for a few hundred milliseconds and left a session that looked
|
|
21
|
+
* live and was deaf.
|
|
22
|
+
* - **A later frame RECOVERED the state.** `clearRecoveredError` reads a
|
|
23
|
+
* non-error frame as proof the session works, which is right for a
|
|
24
|
+
* turn-level failure and wrong for a server error that ended the call.
|
|
25
|
+
*
|
|
26
|
+
* The second and third were fixed with a `conn.fatalError` boolean that every
|
|
27
|
+
* writer had to remember to consult. It is the `fatal` region here, so
|
|
28
|
+
* forgetting is not available: `LISTEN` and `ACTIVITY` are declined in one
|
|
29
|
+
* place rather than at each of their five call sites.
|
|
30
|
+
*
|
|
31
|
+
* ## Two regions, because the fatal latch OUTLIVES the error state
|
|
32
|
+
*
|
|
33
|
+
* `fatal` is not a substate of `error`, tempting as that looks. It is cleared by
|
|
34
|
+
* exactly one thing — the next `config` frame, i.e. a completed handshake — and
|
|
35
|
+
* that is per CONNECTION rather than per session, so a reconnect that really
|
|
36
|
+
* works is not pinned to a dead session's banner. Between the error and that
|
|
37
|
+
* frame the phase runs `error → connecting → ready` while the latch stays set,
|
|
38
|
+
* which a substate cannot express.
|
|
39
|
+
*
|
|
40
|
+
* ## The published surface is unchanged
|
|
41
|
+
*
|
|
42
|
+
* {@link AgentState} is a public type in the versioned `aai-ui:session`
|
|
43
|
+
* capability, so {@link AgentStateSnapshot.state} is one of its seven names and
|
|
44
|
+
* nothing here widens it. The internal distinctions live in the second region
|
|
45
|
+
* and in context, not in the projection.
|
|
46
|
+
*/
|
|
47
|
+
import type { AgentState, SessionError } from "../types.ts";
|
|
48
|
+
/** What the session core folds into its snapshot after each transition. */
|
|
49
|
+
export type AgentStateSnapshot = {
|
|
50
|
+
state: AgentState;
|
|
51
|
+
error: SessionError | null;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Everything that moves the session's state.
|
|
55
|
+
*
|
|
56
|
+
* Named for what HAPPENED rather than for the state wanted, which is the point:
|
|
57
|
+
* `reply.cancelled` sends `LISTEN` and gets `"error"` back when the session is
|
|
58
|
+
* fatally over, and the caller neither knows nor needs to.
|
|
59
|
+
*/
|
|
60
|
+
export type AgentStateEvent =
|
|
61
|
+
/** A connect attempt started — including a reconnect or a handshake retry. */
|
|
62
|
+
{
|
|
63
|
+
type: "CONNECT";
|
|
64
|
+
}
|
|
65
|
+
/** The socket opened; the handshake has not completed yet. */
|
|
66
|
+
| {
|
|
67
|
+
type: "SOCKET_OPEN";
|
|
68
|
+
}
|
|
69
|
+
/** A completed handshake: a live session, whatever ended the last one. */
|
|
70
|
+
| {
|
|
71
|
+
type: "HANDSHAKE_COMPLETE";
|
|
72
|
+
}
|
|
73
|
+
/** A turn boundary, or the audio path coming up: back to the mic. */
|
|
74
|
+
| {
|
|
75
|
+
type: "LISTEN";
|
|
76
|
+
}
|
|
77
|
+
/** A reset: back to the mic AND the conversation cleared. */
|
|
78
|
+
| {
|
|
79
|
+
type: "RESET";
|
|
80
|
+
}
|
|
81
|
+
/** The agent is working. */
|
|
82
|
+
| {
|
|
83
|
+
type: "THINK";
|
|
84
|
+
}
|
|
85
|
+
/** Audio for this turn reached the client. */
|
|
86
|
+
| {
|
|
87
|
+
type: "SPEAK";
|
|
88
|
+
}
|
|
89
|
+
/** A non-error frame arrived, so the session demonstrably works. */
|
|
90
|
+
| {
|
|
91
|
+
type: "ACTIVITY";
|
|
92
|
+
}
|
|
93
|
+
/** A turn-level failure: a banner over a session that keeps running. */
|
|
94
|
+
| {
|
|
95
|
+
type: "TURN_ERROR";
|
|
96
|
+
error: SessionError;
|
|
97
|
+
}
|
|
98
|
+
/** The session is over. */
|
|
99
|
+
| {
|
|
100
|
+
type: "FATAL";
|
|
101
|
+
error: SessionError;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A failure that stops the session but might not be the end of it: the
|
|
105
|
+
* handshake exhausting its retries, a socket error close, or the audio path
|
|
106
|
+
* dying. The `fatal` latch stays clear, so a later non-error frame recovers
|
|
107
|
+
* — which is right for a client-side failure and is exactly what a FATAL
|
|
108
|
+
* server error must not get.
|
|
109
|
+
*/
|
|
110
|
+
| {
|
|
111
|
+
type: "FAILED";
|
|
112
|
+
error: SessionError;
|
|
113
|
+
}
|
|
114
|
+
/** The socket closed for good. */
|
|
115
|
+
| {
|
|
116
|
+
type: "CLOSED";
|
|
117
|
+
}
|
|
118
|
+
/** The caller hung up. */
|
|
119
|
+
| {
|
|
120
|
+
type: "DISCONNECT";
|
|
121
|
+
}
|
|
122
|
+
/** The caller ended the session and forgot it. */
|
|
123
|
+
| {
|
|
124
|
+
type: "END";
|
|
125
|
+
};
|
|
126
|
+
/** The session core's handle on its own state. */
|
|
127
|
+
export type SessionStateMachine = {
|
|
128
|
+
/** The published state and the error beside it. */
|
|
129
|
+
snapshot(): AgentStateSnapshot;
|
|
130
|
+
/**
|
|
131
|
+
* Apply `event` and return the resulting projection.
|
|
132
|
+
*
|
|
133
|
+
* Returns rather than writes so the caller folds it into ONE `updateState`
|
|
134
|
+
* call: a snapshot is published on every write, and splitting one transition
|
|
135
|
+
* into two would let a subscriber render half of it.
|
|
136
|
+
*/
|
|
137
|
+
apply(event: AgentStateEvent): AgentStateSnapshot;
|
|
138
|
+
/**
|
|
139
|
+
* Is the session fatally over? Asked by the one caller that has to clear the
|
|
140
|
+
* CONVERSATION and not merely the state — a `session.reset` on a dead session
|
|
141
|
+
* keeps its whole banner.
|
|
142
|
+
*/
|
|
143
|
+
fatal(): boolean;
|
|
144
|
+
};
|
|
145
|
+
/** Create the state machine for one browser session. */
|
|
146
|
+
export declare function createSessionStateMachine(): SessionStateMachine;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The session ticket one connection attempt presents — `VoiceSessionOptions.token`,
|
|
3
|
+
* else the `sessionToken` a server's `client-config` issued.
|
|
4
|
+
*
|
|
5
|
+
* A browser cannot set headers on a WebSocket, so the ticket rides the
|
|
6
|
+
* `Sec-WebSocket-Protocol` list as `aai.auth.<ticket>`, offered AFTER the plain
|
|
7
|
+
* `aai.session` protocol: a browser fails any handshake whose response selects
|
|
8
|
+
* none of its offers, and the server (`selectSessionProtocol` in
|
|
9
|
+
* `@alexkroman1/aai-runtime/auth`) selects the plain one so the ticket is never
|
|
10
|
+
* echoed back. A server older than tickets selects the first offer, which is
|
|
11
|
+
* the plain one too, so offering a ticket never fails a handshake.
|
|
12
|
+
*
|
|
13
|
+
* A value that is not a valid subprotocol token (RFC 6455 §4.1 — an HTTP
|
|
14
|
+
* token) would make `new WebSocket` throw, so it travels as `?token=` instead,
|
|
15
|
+
* the server's fallback. A minted ticket is base64url with one dot, and so is a
|
|
16
|
+
* JWT: neither takes that path.
|
|
17
|
+
*/
|
|
18
|
+
import type { VoiceSessionOptions } from "../types.ts";
|
|
19
|
+
/** The shape of `VoiceSessionOptions.token`. */
|
|
20
|
+
export type SessionTokenOption = VoiceSessionOptions["token"];
|
|
21
|
+
/** What the getter is told about the attempt it serves: the session it resumes. */
|
|
22
|
+
export type SessionTokenAttempt = {
|
|
23
|
+
readonly sessionId: string | undefined;
|
|
24
|
+
};
|
|
25
|
+
/** How one attempt carries its ticket: subprotocols, or the `?token=` fallback. */
|
|
26
|
+
export type TicketCarriage = {
|
|
27
|
+
protocols?: string[];
|
|
28
|
+
queryToken?: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Ask the `token` option for THIS attempt's ticket. A getter that throws or
|
|
32
|
+
* rejects yields none — the attempt still dials, and a server that requires a
|
|
33
|
+
* ticket refuses it with a reason the session reports, rather than the attempt
|
|
34
|
+
* failing before a socket exists (partysocket reports a provider failure as an
|
|
35
|
+
* `error` with no `close`, which would leave the session on "connecting").
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveSessionToken(option: SessionTokenOption, attempt: SessionTokenAttempt): Promise<string | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* The same, for an injected `WebSocket` constructor: that path opens its socket
|
|
40
|
+
* synchronously, so an asynchronous getter cannot be awaited there.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveSessionTokenSync(option: SessionTokenOption, attempt: SessionTokenAttempt): string | undefined;
|
|
43
|
+
/** How `token` travels on one attempt; nothing at all when there is no ticket. */
|
|
44
|
+
export declare function ticketCarriage(token: string | undefined): TicketCarriage;
|