@autoscriber/core 0.1.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/README.md +147 -0
  2. package/dist/audio/audio-manager.d.ts +27 -0
  3. package/dist/audio/audio-manager.d.ts.map +1 -0
  4. package/dist/audio/permissions.d.ts +8 -0
  5. package/dist/audio/permissions.d.ts.map +1 -0
  6. package/dist/audio/resampler.d.ts +5 -0
  7. package/dist/audio/resampler.d.ts.map +1 -0
  8. package/dist/audio/silence-detector.d.ts +16 -0
  9. package/dist/audio/silence-detector.d.ts.map +1 -0
  10. package/dist/audio/wake-lock.d.ts +29 -0
  11. package/dist/audio/wake-lock.d.ts.map +1 -0
  12. package/dist/audio/worklets.d.ts +3 -0
  13. package/dist/audio/worklets.d.ts.map +1 -0
  14. package/dist/core/assistant-client.d.ts +78 -0
  15. package/dist/core/assistant-client.d.ts.map +1 -0
  16. package/dist/core/message-store.d.ts +28 -0
  17. package/dist/core/message-store.d.ts.map +1 -0
  18. package/dist/core/offline-queue.d.ts +9 -0
  19. package/dist/core/offline-queue.d.ts.map +1 -0
  20. package/dist/core/websocket-client.d.ts +31 -0
  21. package/dist/core/websocket-client.d.ts.map +1 -0
  22. package/dist/headless/create-assistant.d.ts +9 -0
  23. package/dist/headless/create-assistant.d.ts.map +1 -0
  24. package/dist/index.cjs +2005 -0
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +1977 -0
  28. package/dist/types/index.d.ts +103 -0
  29. package/dist/types/index.d.ts.map +1 -0
  30. package/dist/utils/base64.d.ts +3 -0
  31. package/dist/utils/base64.d.ts.map +1 -0
  32. package/dist/utils/event-bus.d.ts +11 -0
  33. package/dist/utils/event-bus.d.ts.map +1 -0
  34. package/dist/utils/i18n.d.ts +5 -0
  35. package/dist/utils/i18n.d.ts.map +1 -0
  36. package/dist/utils/id.d.ts +2 -0
  37. package/dist/utils/id.d.ts.map +1 -0
  38. package/dist/utils/logger.d.ts +8 -0
  39. package/dist/utils/logger.d.ts.map +1 -0
  40. package/dist/utils/token.d.ts +4 -0
  41. package/dist/utils/token.d.ts.map +1 -0
  42. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # @autoscriber/core
2
+
3
+ Headless SDK that powers the Autoscriber Assistant. It exposes the stateful controller used by any UI layer (React, vanilla, native) to embed chat, transcription, FHIR context and voice tooling into host applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @autoscriber/core
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```ts
14
+ import { createAssistant } from "@autoscriber/core";
15
+
16
+ const controller = createAssistant({
17
+ token: "<JWT>",
18
+ language: "en",
19
+ refreshToken: async (sessionId) => fetch(`/api/tokens/${sessionId}`).then((res) => res.text()),
20
+ websocketUrl: "wss://assistant.autoscriber.com/ws"
21
+ });
22
+
23
+ const unsubscribeSnapshot = controller.subscribe("snapshot", (snapshot) => {
24
+ console.log("assistant state", snapshot);
25
+ });
26
+
27
+ const unsubscribeFhir = controller.subscribe("fhir:data", (resource) => {
28
+ console.log("FHIR resource", resource);
29
+ });
30
+
31
+ controller.client.sendTextMessage("Hello there");
32
+
33
+ // later cleanup
34
+ unsubscribeSnapshot();
35
+ unsubscribeFhir();
36
+ ```
37
+
38
+ ## Configuration
39
+
40
+ `createAssistant` accepts the following options:
41
+
42
+ - `token` *(required)* – JWT used to authenticate websocket traffic.
43
+ - `language` – Preferred localisation (`"en"`, `"nl"`, `"de"`).
44
+ - `refreshToken(sessionId)` – Async callback invoked when the controller detects an expiring token.
45
+ - `debugMode` – Enables additional debug pills/transcripts in the snapshot.
46
+ - `logger` – Provide a console-like interface to capture SDK logs.
47
+ - `websocketUrl` – Override the websocket endpoint; defaults to the current origin.
48
+ - `websocketReconnectDelay` – Milliseconds between reconnect attempts (defaults to `3000`; lower if you prefer faster retries).
49
+
50
+ ## Architectural Choices
51
+
52
+ - **Controller + client split** – `createAssistant` returns a controller wrapper that exposes read-only helpers (`getSnapshot`, `subscribe`) and a `client` reference for effectful methods (sending messages, starting recordings). This keeps UI code focused on rendering state while actions remain encapsulated inside `AssistantClient`.
53
+ - **Typed event bus** – All state changes flow through a typed `EventBus`, so features can emit specific events such as `"snapshot"` or `"fhir:data"` without leaking implementation details. Consumers opt into just the events they need and can unsubscribe cleanly, making it easy to integrate with React hooks or other state stores.
54
+ - **Snapshot-first state** – The controller always reflects the latest aggregate state through `getSnapshot()`. The snapshot mirrors the legacy widget data model so existing analytics and UI bindings can migrate with minimal friction.
55
+ - **Event-first data flow** – All integrations consume state through typed events, so FHIR payloads, transcripts, microphone updates and errors are handled uniformly across UI frameworks.
56
+
57
+ ## Key APIs
58
+
59
+ - `client.sendTextMessage(text)` – send a chat message.
60
+ - `client.startTranscription(customId?)` / `client.pauseTranscription()` / `client.stopRecording()` – manage live transcription sessions.
61
+ - `client.startVoiceCommand()` – record a short voice command and stream the PCM blob to the backend with silence detection baked in.
62
+ - `client.setFhirContext(resource)` – push FHIR resources into context and receive status via interaction pills.
63
+ - `client.fillQuestionnaire(context?)` – invoke the fill questionnaire tool.
64
+ - `client.setLanguage(language)` – update the language preference dynamically (`"en"`, `"nl"`, or `"de"`). Updates the snapshot and emits a `language:changed` event.
65
+ - `client.refreshMicrophones()` / `client.setSelectedMicrophone(device)` – expose microphone discovery and selection to host apps.
66
+ - `controller.subscribe(event, listener)` – listen to `snapshot`, `messages:updated`, `interactions:updated`, `connection:changed`, `recording:changed`, `language:changed`, etc.
67
+
68
+ ## Events
69
+
70
+ `controller.subscribe(event, listener)` and `controller.client.on(event, listener)` are backed by the same typed bus. Supported event names include:
71
+
72
+ - `snapshot` – emits the full `AssistantSnapshot` whenever any tracked state mutates.
73
+ - `messages:updated` – releases the ordered list of `AssistantMessage` records.
74
+ - `interactions:updated` – tracks interaction pill lifecycle (success/error states for tools).
75
+ - `connection:changed`, `recording:changed`, `microphones:changed` – granular status updates for connection, recording and microphone state.
76
+ - `language:changed` – fires when the language is updated via `setLanguage()`, emits the new `SupportedLanguage` value.
77
+ - `voice:transcription` – delivers voice-command transcription results.
78
+ - `fhir:data` – fires when FHIR payloads arrive from the backend.
79
+ - `error` – surfaces recoverable errors (WebSocket, tool invocation, etc.).
80
+
81
+ All events are strongly typed via `AssistantEvents`, so TypeScript consumers get autocomplete and correct payload shapes out of the box.
82
+
83
+ ### Listen for FHIR Payloads
84
+
85
+ ```ts
86
+ const controller = createAssistant({ token: "<JWT>" });
87
+
88
+ controller.subscribe("fhir:data", (resource) => {
89
+ // Persist to your backend or hydrate UI
90
+ console.log("FHIR update", resource);
91
+ });
92
+ ```
93
+
94
+ ### Change Language Dynamically
95
+
96
+ ```ts
97
+ const controller = createAssistant({ token: "<JWT>", language: "en" });
98
+
99
+ // Update language at runtime
100
+ controller.client.setLanguage("nl");
101
+
102
+ // Listen for language changes
103
+ controller.subscribe("language:changed", (newLanguage) => {
104
+ console.log("Language changed to:", newLanguage);
105
+ });
106
+ ```
107
+
108
+ ## Snapshot Structure
109
+
110
+ The snapshot emitted through the event bus (and returned from `controller.getSnapshot()`) mirrors everything kept in the old widget:
111
+
112
+ ```ts
113
+ interface AssistantSnapshot {
114
+ language: "en" | "nl" | "de";
115
+ debugMode: boolean;
116
+ messages: AssistantMessage[];
117
+ interactions: InteractionPill[];
118
+ connection: {
119
+ websocketStatus: "idle" | "connecting" | "open" | "closing" | "closed";
120
+ online: boolean;
121
+ buffering: boolean;
122
+ reason?: "offline" | "manual" | "error" | "closed" | "reconnecting";
123
+ lastError?: string;
124
+ };
125
+ microphones: MicrophoneState;
126
+ recording: RecordingState;
127
+ offlineQueueLength: number;
128
+ lastUpdatedAt: number;
129
+ }
130
+ ```
131
+
132
+ - `connection.buffering` flips to `true` whenever messages or PCM chunks are queued locally (e.g. browser goes offline).
133
+ - `connection.reason` explains why the websocket is unavailable (`"offline"`, `"reconnecting"`, `"error"`, etc.), making it easy to render status banners identical to the legacy widget.
134
+
135
+ ## Browser Requirements
136
+
137
+ - Modern browsers with WebSocket, Web Audio (AudioWorklet), MediaDevices and Clipboard APIs.
138
+ - JWT refresh callback is optional but recommended; the client inspects token expiry and calls `refreshToken(sessionId)` when needed.
139
+
140
+ ## Migrating from `static/autoscriber-assistant.js`
141
+
142
+ - Everything previously exposed on `window.AutoscriberAssistant` is now available on `AssistantClient`.
143
+ - UI responsibilities have been removed; render your own interface (or install `@autoscriber/react`).
144
+ - Interaction pills, transcripts, FHIR payloads, offline buffering, and voice command safeguards are all maintained and surfaced through the snapshot or event bus.
145
+ - State mutation is event-driven, making it easy for host apps to sync local stores or analytics.
146
+
147
+ See `examples/vanilla` for a DOM-based integration that wires the core SDK into a minimal custom UI.
@@ -0,0 +1,27 @@
1
+ export interface AudioManagerOptions {
2
+ onRecorderData?: (pcm16: Uint8Array) => void;
3
+ outputSampleRate?: number;
4
+ inputSampleRate?: number;
5
+ deviceId?: string;
6
+ targetSampleRate?: number;
7
+ }
8
+ export declare class AudioManager {
9
+ private recorderContext;
10
+ private recorderNode;
11
+ private playerContext;
12
+ private playerNode;
13
+ private micStream;
14
+ private actualSampleRate;
15
+ private targetSampleRate;
16
+ init(options?: AudioManagerOptions): Promise<void>;
17
+ setupPlayer(options?: AudioManagerOptions): Promise<void>;
18
+ setupRecorder(options?: AudioManagerOptions): Promise<void>;
19
+ stop(): void;
20
+ stopRecorder(): void;
21
+ stopPlayer(): void;
22
+ teardown(): void;
23
+ playbackPcm(buffer: ArrayBuffer): void;
24
+ endOfAudio(): void;
25
+ private convertFloat32ToPCM;
26
+ }
27
+ //# sourceMappingURL=audio-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-manager.d.ts","sourceRoot":"","sources":["../../src/audio/audio-manager.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,eAAe,CAA6B;IAEpD,OAAO,CAAC,YAAY,CAAiC;IAErD,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,UAAU,CAAiC;IAEnD,OAAO,CAAC,SAAS,CAA4B;IAE7C,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,OAAO,CAAC,gBAAgB,CAAiB;IAEnC,IAAI,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAStD,WAAW,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B7D,aAAa,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDrE,IAAI,IAAI,IAAI;IAKZ,YAAY,IAAI,IAAI;IAepB,UAAU,IAAI,IAAI;IAWlB,QAAQ,IAAI,IAAI;IAIhB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAKtC,UAAU,IAAI,IAAI;IAIlB,OAAO,CAAC,mBAAmB;CAO5B"}
@@ -0,0 +1,8 @@
1
+ import type { MicrophoneInfo } from "../types";
2
+ export declare function checkMicrophonePermission(language?: string): Promise<{
3
+ granted: boolean;
4
+ state: PermissionState;
5
+ message?: string;
6
+ }>;
7
+ export declare function getAvailableMicrophones(language?: string): Promise<MicrophoneInfo[]>;
8
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/audio/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG/C,wBAAsB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAuDD;AAED,wBAAsB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAoB1F"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Resamples PCM16 audio from one sample rate to another using linear interpolation
3
+ */
4
+ export declare function resamplePCM16(inputBuffer: Uint8Array, inputSampleRate: number, outputSampleRate: number): Uint8Array;
5
+ //# sourceMappingURL=resampler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resampler.d.ts","sourceRoot":"","sources":["../../src/audio/resampler.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,UAAU,EACvB,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,GACvB,UAAU,CAyBZ"}
@@ -0,0 +1,16 @@
1
+ export interface SilenceDetectionResult {
2
+ isSilence: boolean;
3
+ amplitudeAnalysis?: {
4
+ silencePercentage: number;
5
+ totalSamples: number;
6
+ silentSamples: number;
7
+ };
8
+ energyAnalysis?: {
9
+ silencePercentage: number;
10
+ averageEnergy: number;
11
+ };
12
+ error?: string;
13
+ }
14
+ export declare function convertPCMToFloat32(pcmBuffer: Uint8Array): Float32Array;
15
+ export declare function detectSilence(pcmBuffer: Uint8Array): SilenceDetectionResult;
16
+ //# sourceMappingURL=silence-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"silence-detector.d.ts","sourceRoot":"","sources":["../../src/audio/silence-detector.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE;QAClB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,cAAc,CAAC,EAAE;QACf,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,UAAU,GAAG,YAAY,CAavE;AA+DD,wBAAgB,aAAa,CAAC,SAAS,EAAE,UAAU,GAAG,sBAAsB,CAuC3E"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Wake Lock manager to prevent screen from sleeping during audio recording
3
+ * Uses the Screen Wake Lock API: https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API
4
+ */
5
+ export declare class WakeLockManager {
6
+ private wakeLock;
7
+ /**
8
+ * Check if Wake Lock API is supported in the current browser
9
+ */
10
+ static isSupported(): boolean;
11
+ /**
12
+ * Request a wake lock to prevent the screen from sleeping
13
+ * @returns Promise that resolves when wake lock is acquired, or rejects if not supported/failed
14
+ */
15
+ request(): Promise<void>;
16
+ /**
17
+ * Release the wake lock if it's currently active
18
+ */
19
+ release(): Promise<void>;
20
+ /**
21
+ * Check if a wake lock is currently active
22
+ */
23
+ isActive(): boolean;
24
+ /**
25
+ * Clean up resources (release wake lock and remove listeners)
26
+ */
27
+ destroy(): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=wake-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wake-lock.d.ts","sourceRoot":"","sources":["../../src/audio/wake-lock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAiC;IAEjD;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,OAAO;IAI7B;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB9B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9B;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
@@ -0,0 +1,3 @@
1
+ export declare const PCM_PLAYER_PROCESSOR = "\n class PCMPlayerProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.bufferSize = 24000 * 180;\n this.buffer = new Float32Array(this.bufferSize);\n this.writeIndex = 0;\n this.readIndex = 0;\n this.port.onmessage = (event) => {\n if (event.data.command === 'endOfAudio') {\n this.readIndex = this.writeIndex;\n return;\n }\n const int16Samples = new Int16Array(event.data);\n this._enqueue(int16Samples);\n };\n }\n _enqueue(int16Samples) {\n for (let i = 0; i < int16Samples.length; i++) {\n const floatVal = int16Samples[i] / 32768;\n this.buffer[this.writeIndex] = floatVal;\n this.writeIndex = (this.writeIndex + 1) % this.bufferSize;\n if (this.writeIndex === this.readIndex) {\n this.readIndex = (this.readIndex + 1) % this.bufferSize;\n }\n }\n }\n process(inputs, outputs) {\n const output = outputs[0];\n const framesPerBlock = output[0].length;\n for (let frame = 0; frame < framesPerBlock; frame++) {\n output[0][frame] = this.buffer[this.readIndex];\n if (output.length > 1) {\n output[1][frame] = this.buffer[this.readIndex];\n }\n if (this.readIndex !== this.writeIndex) {\n this.readIndex = (this.readIndex + 1) % this.bufferSize;\n }\n }\n return true;\n }\n }\n registerProcessor('pcm-player-processor', PCMPlayerProcessor);\n";
2
+ export declare const PCM_RECORDER_PROCESSOR = "\n class PCMProcessor extends AudioWorkletProcessor {\n process(inputs) {\n if (inputs.length > 0 && inputs[0].length > 0) {\n const inputChannel = inputs[0][0];\n const inputCopy = new Float32Array(inputChannel);\n this.port.postMessage(inputCopy);\n }\n return true;\n }\n }\n registerProcessor(\"pcm-recorder-processor\", PCMProcessor);\n";
3
+ //# sourceMappingURL=worklets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worklets.d.ts","sourceRoot":"","sources":["../../src/audio/worklets.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,q+CA2ChC,CAAC;AAEF,eAAO,MAAM,sBAAsB,uYAYlC,CAAC"}
@@ -0,0 +1,78 @@
1
+ import type { AssistantEvents, AssistantOptions, AssistantSnapshot, AssistantMessage, MicrophoneInfo, SupportedLanguage } from "../types";
2
+ export declare class AssistantClient {
3
+ private readonly bus;
4
+ private readonly logger;
5
+ private readonly options;
6
+ private readonly messageStore;
7
+ private readonly offlineQueue;
8
+ private readonly websocket;
9
+ private readonly audioManager;
10
+ private readonly wakeLockManager;
11
+ private token;
12
+ private snapshot;
13
+ private bufferTimer;
14
+ private audioBuffer;
15
+ private voiceCommandBuffer;
16
+ private manualDisconnect;
17
+ private pendingRequests;
18
+ private reconnectTimer;
19
+ private lastTokenRefreshAttempt;
20
+ private tokenRefreshInFlight;
21
+ private hasConnected;
22
+ /**
23
+ * Internal structured logging helper for Datadog monitoring
24
+ * Formats logs as structured JSON for better parsing and filtering
25
+ */
26
+ private logStructured;
27
+ constructor(options: AssistantOptions);
28
+ on<K extends keyof AssistantEvents>(event: K, listener: (payload: AssistantEvents[K]) => void): () => void;
29
+ getSnapshot(): AssistantSnapshot;
30
+ setDebugMode(enabled: boolean): void;
31
+ setLanguage(language: SupportedLanguage): void;
32
+ destroy(): void;
33
+ /** Chat related methods */
34
+ sendTextMessage(text: string): AssistantMessage;
35
+ /** Recording controls */
36
+ startTranscription(customId?: string): Promise<string>;
37
+ pauseTranscription(): void;
38
+ stopRecording(): void;
39
+ startVoiceCommand(): Promise<void>;
40
+ /** FHIR context */
41
+ setFhirContext(resource: unknown): string;
42
+ fillQuestionnaire(context?: unknown): string;
43
+ /** Microphone controls */
44
+ refreshMicrophones(): Promise<void>;
45
+ setSelectedMicrophone(device: MicrophoneInfo): void;
46
+ /** Internal plumbing */
47
+ private registerWebsocketEvents;
48
+ private setupNetworkListeners;
49
+ private readonly handleBrowserOnline;
50
+ private readonly handleBrowserOffline;
51
+ private scheduleReconnectAttempt;
52
+ private initializeMicrophones;
53
+ private connectWebsocket;
54
+ private buildWebsocketUrl;
55
+ private sendMessage;
56
+ private flushOfflineQueue;
57
+ private emitSnapshot;
58
+ private emitMessages;
59
+ private emitInteractions;
60
+ private emitConnection;
61
+ private emitRecording;
62
+ private emitMicrophones;
63
+ private pushInteraction;
64
+ private updateMicrophonePermission;
65
+ private handleRecorderData;
66
+ private sendBufferedAudio;
67
+ private concatPcmChunks;
68
+ private resumeTranscriptionAfterVoiceCommand;
69
+ private sendVoiceCommandAudio;
70
+ private handleMessage;
71
+ private handleErrorResponse;
72
+ private handleResultResponse;
73
+ private updateInteractionFromResult;
74
+ private handlePartialResult;
75
+ private handleVoiceTranscription;
76
+ private resetRecordingState;
77
+ }
78
+ //# sourceMappingURL=assistant-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-client.d.ts","sourceRoot":"","sources":["../../src/core/assistant-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { AssistantMessage, InteractionPill, MessageResult } from "../types";
2
+ export interface CreateMessageInput {
3
+ id?: string;
4
+ request?: string | null;
5
+ type?: AssistantMessage["type"];
6
+ metadata?: Record<string, unknown>;
7
+ }
8
+ export declare class MessageStore {
9
+ private messages;
10
+ private interactions;
11
+ createMessage(input?: CreateMessageInput): AssistantMessage;
12
+ addMessage(message: AssistantMessage): void;
13
+ getMessageById(id: string): AssistantMessage | undefined;
14
+ setMessageResult(id: string, result: MessageResult): void;
15
+ setMessagePartialResult(id: string, payload: string, append?: boolean): void;
16
+ applyJsonPatch(id: string, patchOperations: Array<{
17
+ op: string;
18
+ path: string;
19
+ value: unknown;
20
+ }>): void;
21
+ setError(id: string, errorMessage: string, result?: MessageResult): void;
22
+ upsertInteraction(pill: InteractionPill): InteractionPill;
23
+ updateInteractionStatus(id: string, status: InteractionPill["status"], metadata?: Record<string, unknown>): void;
24
+ getInteractions(): InteractionPill[];
25
+ getMessages(): AssistantMessage[];
26
+ reset(): void;
27
+ }
28
+ //# sourceMappingURL=message-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-store.d.ts","sourceRoot":"","sources":["../../src/core/message-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EAEd,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAA0B;IAE1C,OAAO,CAAC,YAAY,CAAyB;IAE7C,aAAa,CAAC,KAAK,GAAE,kBAAuB,GAAG,gBAAgB;IAa/D,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAI3C,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIxD,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI;IAOzD,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAO,GAAG,IAAI;IAUzE,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAgC/F,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI;IASxE,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe;IAUzD,uBAAuB,CACrB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,EACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI;IASP,eAAe,IAAI,eAAe,EAAE;IAIpC,WAAW,IAAI,gBAAgB,EAAE;IAIjC,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,9 @@
1
+ export declare class OfflineQueue<T> {
2
+ private queue;
3
+ enqueue(item: T): void;
4
+ drain(): T[];
5
+ clear(): void;
6
+ get size(): number;
7
+ get items(): T[];
8
+ }
9
+ //# sourceMappingURL=offline-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-queue.d.ts","sourceRoot":"","sources":["../../src/core/offline-queue.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY,CAAC,CAAC;IACzB,OAAO,CAAC,KAAK,CAAW;IAExB,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAItB,KAAK,IAAI,CAAC,EAAE;IAMZ,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,KAAK,IAAI,CAAC,EAAE,CAEf;CACF"}
@@ -0,0 +1,31 @@
1
+ export interface WebSocketClientOptions {
2
+ reconnectDelay?: number;
3
+ autoReconnect?: boolean;
4
+ logger?: Partial<Console>;
5
+ }
6
+ export interface WebSocketEvents {
7
+ open: Event;
8
+ close: CloseEvent;
9
+ error: Event;
10
+ message: MessageEvent<string>;
11
+ reconnecting: number;
12
+ [event: string]: unknown;
13
+ }
14
+ export declare class WebSocketClient {
15
+ private socket;
16
+ private manualClose;
17
+ private reconnectAttempts;
18
+ private readonly reconnectDelay;
19
+ private readonly autoReconnect;
20
+ private readonly bus;
21
+ private readonly logger;
22
+ constructor(options?: WebSocketClientOptions);
23
+ on<K extends keyof WebSocketEvents>(event: K, listener: (payload: WebSocketEvents[K]) => void): () => void;
24
+ connect(url: string): Promise<void>;
25
+ private openSocket;
26
+ private scheduleReconnect;
27
+ send(payload: string): void;
28
+ close(code?: number, reason?: string): void;
29
+ get readyState(): number;
30
+ }
31
+ //# sourceMappingURL=websocket-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-client.d.ts","sourceRoot":"","sources":["../../src/core/websocket-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA0B;IAExC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,iBAAiB,CAAK;IAE9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IAExC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmC;IAEvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAErB,OAAO,GAAE,sBAA2B;IAShD,EAAE,CAAC,CAAC,SAAS,MAAM,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI;IAIvF,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWzC,OAAO,CAAC,UAAU;IAmElB,OAAO,CAAC,iBAAiB;IAiBzB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAO3B,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAM3C,IAAI,UAAU,IAAI,MAAM,CAEvB;CACF"}
@@ -0,0 +1,9 @@
1
+ import type { AssistantOptions, AssistantSnapshot, AssistantEvents } from "../types";
2
+ import { AssistantClient } from "../core/assistant-client";
3
+ export interface AssistantController {
4
+ client: AssistantClient;
5
+ getSnapshot: () => AssistantSnapshot;
6
+ subscribe: <K extends keyof AssistantEvents>(event: K, listener: (payload: AssistantEvents[K]) => void) => () => void;
7
+ }
8
+ export declare function createAssistant(options: AssistantOptions): AssistantController;
9
+ //# sourceMappingURL=create-assistant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-assistant.d.ts","sourceRoot":"","sources":["../../src/headless/create-assistant.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,MAAM,iBAAiB,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,SAAS,MAAM,eAAe,EACzC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,KAC5C,MAAM,IAAI,CAAC;CACjB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,mBAAmB,CAQ9E"}