@hubtalk-ai/web-sdk 0.2.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.
@@ -0,0 +1,84 @@
1
+ import type { AgentState, ConnectionState, StartCallOptions, StartCallParams, VoiceClientEventHandler, VoiceClientEventName, VoiceClientOptions } from './types';
2
+ export declare class VoiceClient {
3
+ private readonly emitter;
4
+ private readonly audio;
5
+ private readonly log;
6
+ private readonly connectTimeoutMs?;
7
+ private connectionState;
8
+ private agentState;
9
+ private room;
10
+ private callId;
11
+ private playAudio;
12
+ private stoppingLocally;
13
+ private reconnectSeen;
14
+ private destroyed;
15
+ private roomCleanup;
16
+ constructor(options?: VoiceClientOptions);
17
+ getState(): ConnectionState;
18
+ getAgentState(): AgentState;
19
+ getCallId(): string | null;
20
+ on<E extends VoiceClientEventName>(event: E, handler: VoiceClientEventHandler<E>): void;
21
+ off<E extends VoiceClientEventName>(event: E, handler: VoiceClientEventHandler<E>): void;
22
+ once<E extends VoiceClientEventName>(event: E, handler: VoiceClientEventHandler<E>): void;
23
+ /**
24
+ * `options.audio === false` — chat-only call: микрофон не публикуется,
25
+ * аудио агента не подписывается (см. connectRoom). Текст в обе стороны
26
+ * идёт как обычно — `sendText` и событие `transcript`.
27
+ *
28
+ * Аудио агента при этом ПОДПИСЫВАЕТСЯ и просто не проигрывается — это не
29
+ * расточительность, а единственный работающий вариант с livekit-agents
30
+ * 1.6.4: `_ParticipantAudioOutput.capture_frame` ждёт `_subscribed_fut`
31
+ * (room_io/_output.py:92), который закрывается только по
32
+ * `publication.wait_for_subscription()`. Без подписчика первый же кадр
33
+ * TTS блокируется навсегда, а вместе с ним умирает и текст: транскрипт
34
+ * агента идёт через TranscriptSynchronizer, привязанный к тому же
35
+ * аудио-выходу (room_io.py:163-166). Наблюдалось как «агент мигает
36
+ * thinking -> listening и молчит», при том что эхо реплик посетителя
37
+ * приходило — у него своя, несинхронизированная ветка вывода.
38
+ *
39
+ * ponytail: платит трафиком и TTS за то, что никто не слышит. Убирается
40
+ * только на стороне платформы — RoomOutputOptions(audio_enabled=False) по
41
+ * флагу звонка, тогда текст пойдёт сразу и синтеза не будет вовсе.
42
+ */
43
+ startCall(params: StartCallParams, options?: StartCallOptions): Promise<void>;
44
+ private validateStartParams;
45
+ private connectRoom;
46
+ private abandonConnectingCall;
47
+ private publishMicrophone;
48
+ /**
49
+ * Отправляет текстовую реплику посетителя в разговор (VPT-108 §2.1).
50
+ * Своё сообщение в чат SDK не кладёт — его вернёт агент событием
51
+ * `transcript` с role: 'user' (§2.4): один источник правды и один порядок.
52
+ */
53
+ sendText(text: string): Promise<void>;
54
+ stopCall(): Promise<void>;
55
+ destroy(): void;
56
+ private wireRoomEvents;
57
+ /**
58
+ * Разбор одного сегмента транскрипта (VPT-108 §1.3). Роль определена
59
+ * вызывающим — сравнением identity потока с локальным участником.
60
+ *
61
+ * Одна реплика приходит несколькими потоками с общим `lk.segment_id`
62
+ * (тот же дефект-дубль, что закрывался в №50 §9), поэтому пузырь
63
+ * сшивается по нему, а не по потоку. Чанки копятся ВНУТРИ потока, а текст
64
+ * потока ЗАМЕНЯЕТ текст сегмента: у реплик посетителя каждый поток несёт
65
+ * полный текст на момент отправки, а не хвост (`_ParticipantTranscription
66
+ * Output(is_delta_stream=False)`), и дописывание удвоило бы реплику.
67
+ *
68
+ * `final` — из атрибута `lk.transcription_final`, а не из факта закрытия
69
+ * потока: дельта-поток закрывается штатно, будучи нефинальным. У потока
70
+ * агента `true` приходит в трейлере, и livekit-client домешивает атрибуты
71
+ * трейлера в `reader.info` перед закрытием — поэтому читаем атрибут ПОСЛЕ
72
+ * цикла чтения.
73
+ */
74
+ private readTranscriptSegment;
75
+ private applyLkConnectionState;
76
+ private handleDisconnected;
77
+ private teardownRoom;
78
+ private syncAgentState;
79
+ private setConnectionState;
80
+ private setAgentState;
81
+ /** Переводит ось соединения (если нужно), логирует и эмитит error (§1.4);
82
+ * возвращает VoiceCallError — вызывающий сам решает throw или нет. */
83
+ private raiseError;
84
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@hubtalk-ai/web-sdk",
3
+ "version": "0.2.0",
4
+ "description": "Browser SDK for WebRTC voice calls with a HubTalk Conversation Flow agent (thin wrapper over livekit-client + POST /v1/calls/web).",
5
+ "license": "UNLICENSED",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "type": "module",
10
+ "sideEffects": false,
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "main": "./dist/index.js",
15
+ "module": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ }
22
+ },
23
+ "scripts": {
24
+ "build": "vite build && vite build --config vite.bundle.config.ts && tsc -p tsconfig.build.json",
25
+ "prepublishOnly": "npm run build",
26
+ "lint": "eslint src",
27
+ "format": "prettier --write src",
28
+ "format:check": "prettier --check src"
29
+ },
30
+ "dependencies": {
31
+ "livekit-client": "^2.20.0"
32
+ },
33
+ "devDependencies": {
34
+ "eslint": "^10.7.0",
35
+ "prettier": "^3.9.6",
36
+ "typescript": "^5.5.4",
37
+ "typescript-eslint": "^8.65.0",
38
+ "vite": "^5.4.6"
39
+ }
40
+ }