@neta-art/cohub 1.21.0 → 1.22.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,32 @@
1
+ //#region src/environment.d.ts
2
+ type CohubEnvironment = "prod" | "dev";
3
+ declare const COHUB_ENVIRONMENTS: {
4
+ readonly prod: {
5
+ readonly apiBaseUrl: "https://api.cohub.run";
6
+ readonly websocketUrl: "wss://gateway.cohub.run/ws";
7
+ readonly voiceInputWebsocketUrl: "wss://gateway.cohub.run/asr/ws";
8
+ };
9
+ readonly dev: {
10
+ readonly apiBaseUrl: "https://api-dev.cohub.run";
11
+ readonly websocketUrl: "wss://gateway-dev.cohub.run/ws";
12
+ readonly voiceInputWebsocketUrl: "wss://gateway-dev.cohub.run/asr/ws";
13
+ };
14
+ };
15
+ declare const resolveCohubEnvironment: (env?: CohubEnvironment) => CohubEnvironment;
16
+ declare const normalizeBaseUrl: (url: string) => string;
17
+ declare const normalizeWebsocketUrl: (input: string) => string;
18
+ declare const normalizeVoiceInputWebsocketUrl: (input: string) => string;
19
+ declare const resolveApiBaseUrl: (options?: {
20
+ baseUrl?: string;
21
+ env?: CohubEnvironment;
22
+ }) => string;
23
+ declare const resolveWebsocketUrl: (options?: {
24
+ url?: string;
25
+ env?: CohubEnvironment;
26
+ }) => string;
27
+ declare const resolveVoiceInputWebsocketUrl: (options?: {
28
+ url?: string;
29
+ env?: CohubEnvironment;
30
+ }) => string;
31
+ //#endregion
32
+ export { normalizeWebsocketUrl as a, resolveVoiceInputWebsocketUrl as c, normalizeVoiceInputWebsocketUrl as i, resolveWebsocketUrl as l, CohubEnvironment as n, resolveApiBaseUrl as o, normalizeBaseUrl as r, resolveCohubEnvironment as s, COHUB_ENVIRONMENTS as t };
@@ -2,11 +2,13 @@
2
2
  const COHUB_ENVIRONMENTS = {
3
3
  prod: {
4
4
  apiBaseUrl: "https://api.cohub.run",
5
- websocketUrl: "wss://gateway.cohub.run/ws"
5
+ websocketUrl: "wss://gateway.cohub.run/ws",
6
+ voiceInputWebsocketUrl: "wss://gateway.cohub.run/asr/ws"
6
7
  },
7
8
  dev: {
8
9
  apiBaseUrl: "https://api-dev.cohub.run",
9
- websocketUrl: "wss://gateway-dev.cohub.run/ws"
10
+ websocketUrl: "wss://gateway-dev.cohub.run/ws",
11
+ voiceInputWebsocketUrl: "wss://gateway-dev.cohub.run/asr/ws"
10
12
  }
11
13
  };
12
14
  const readRuntimeEnv = () => {
@@ -17,10 +19,16 @@ const resolveCohubEnvironment = (env) => {
17
19
  return readRuntimeEnv() === "dev" ? "dev" : "prod";
18
20
  };
19
21
  const normalizeBaseUrl = (url) => url.trim().replace(/\/+$/, "");
20
- const normalizeWebsocketUrl = (input) => {
21
- const withProtocol = normalizeBaseUrl(input).replace(/^http:/, "ws:").replace(/^https:/, "wss:");
22
- return withProtocol.endsWith("/ws") ? withProtocol : `${withProtocol}/ws`;
22
+ const normalizeWebsocketPath = (input, path, replacePaths = []) => {
23
+ let withProtocol = normalizeBaseUrl(input).replace(/^http:/, "ws:").replace(/^https:/, "wss:");
24
+ for (const replacePath of replacePaths) if (withProtocol.endsWith(replacePath)) {
25
+ withProtocol = withProtocol.slice(0, -replacePath.length);
26
+ break;
27
+ }
28
+ return withProtocol.endsWith(path) ? withProtocol : `${withProtocol}${path}`;
23
29
  };
30
+ const normalizeWebsocketUrl = (input) => normalizeWebsocketPath(input, "/ws", ["/asr/ws"]);
31
+ const normalizeVoiceInputWebsocketUrl = (input) => normalizeWebsocketPath(input, "/asr/ws", ["/ws"]);
24
32
  const resolveApiBaseUrl = (options = {}) => {
25
33
  if (options.baseUrl) return normalizeBaseUrl(options.baseUrl);
26
34
  return COHUB_ENVIRONMENTS[resolveCohubEnvironment(options.env)].apiBaseUrl;
@@ -29,5 +37,9 @@ const resolveWebsocketUrl = (options = {}) => {
29
37
  if (options.url) return normalizeWebsocketUrl(options.url);
30
38
  return COHUB_ENVIRONMENTS[resolveCohubEnvironment(options.env)].websocketUrl;
31
39
  };
40
+ const resolveVoiceInputWebsocketUrl = (options = {}) => {
41
+ if (options.url) return normalizeVoiceInputWebsocketUrl(options.url);
42
+ return COHUB_ENVIRONMENTS[resolveCohubEnvironment(options.env)].voiceInputWebsocketUrl;
43
+ };
32
44
  //#endregion
33
- export { resolveCohubEnvironment as a, resolveApiBaseUrl as i, normalizeBaseUrl as n, resolveWebsocketUrl as o, normalizeWebsocketUrl as r, COHUB_ENVIRONMENTS as t };
45
+ export { resolveApiBaseUrl as a, resolveWebsocketUrl as c, normalizeWebsocketUrl as i, normalizeBaseUrl as n, resolveCohubEnvironment as o, normalizeVoiceInputWebsocketUrl as r, resolveVoiceInputWebsocketUrl as s, COHUB_ENVIRONMENTS as t };
@@ -1,4 +1,6 @@
1
- import { S as CohubEnvironment, _ as SessionTurnIndexItem, a as WebsocketClientOptions, b as ContentBlock, d as SpacePublicEndpoints, f as MessageRecord, h as SessionRecord$1, l as RealtimePatchOperation, m as SessionForkRecord, p as SessionBindingRecord$1, r as WebsocketClient, s as WebsocketEventPayload, u as SessionTurnPatchEvent, v as SessionTurnRecord, y as Usage } from "./websocket.js";
1
+ import { n as CohubEnvironment } from "./environment.js";
2
+ import { C as ContentBlock, S as Usage, _ as SessionForkRecord, a as WebsocketClientOptions, b as SessionTurnIndexItem, d as RealtimePatchOperation, g as SessionBindingRecord$1, h as MessageRecord, m as SpacePublicEndpoints, p as SessionTurnPatchEvent, r as WebsocketClient, s as WebsocketEventPayload, v as SessionRecord$1, x as SessionTurnRecord } from "./websocket.js";
3
+ import { a as VoiceInputCreateOptions } from "./voice-input.js";
2
4
 
3
5
  //#region src/transport.d.ts
4
6
  type Fetch = typeof globalThis.fetch;
@@ -23,6 +25,7 @@ type CohubClientOptions = {
23
25
  clearStoredAuthToken?: () => void;
24
26
  fetch?: Fetch;
25
27
  websocket?: WebsocketClientOptions;
28
+ voice?: VoiceInputCreateOptions;
26
29
  };
27
30
  declare class HttpError extends Error {
28
31
  readonly status: number;
@@ -1,4 +1,4 @@
1
- import { i as resolveApiBaseUrl } from "./environment.js";
1
+ import { a as resolveApiBaseUrl } from "./environment.js";
2
2
  //#region src/apis/channels.ts
3
3
  var ChannelsApi = class {
4
4
  transport;
@@ -0,0 +1,94 @@
1
+ import { n as CohubEnvironment } from "./environment.js";
2
+
3
+ //#region src/voice-input.d.ts
4
+ type VoiceInputEvent = {
5
+ type: string;
6
+ payload?: Record<string, unknown>;
7
+ };
8
+ type VoiceInputCallbacks = {
9
+ onPartial?: (text: string) => void;
10
+ onFinal?: (text: string) => void;
11
+ onError?: (message: string) => void;
12
+ onDone?: () => void;
13
+ };
14
+ type VoiceInputClientOptions = {
15
+ env?: CohubEnvironment;
16
+ url?: string;
17
+ getAccessToken?: (options?: {
18
+ forceRefresh?: boolean;
19
+ }) => Promise<string | null> | string | null;
20
+ WebSocketImpl?: WebSocketConstructor;
21
+ connectionTimeoutMs?: number;
22
+ idleConnectionTimeoutMs?: number;
23
+ callbacks?: VoiceInputCallbacks;
24
+ };
25
+ type VoiceInputCreateOptions = Omit<VoiceInputClientOptions, "callbacks">;
26
+ type WebSocketLike = {
27
+ readonly readyState: number;
28
+ onopen: ((event: Event) => void) | null;
29
+ onmessage: ((event: MessageEvent) => void) | null;
30
+ onerror: ((event: Event) => void) | null;
31
+ onclose: ((event: CloseEvent) => void) | null;
32
+ send(data: string): void;
33
+ close(code?: number, reason?: string): void;
34
+ };
35
+ type WebSocketConstructor = new (url: string) => WebSocketLike;
36
+ declare class VoiceInputClient {
37
+ private readonly url;
38
+ private readonly getAccessToken?;
39
+ private readonly WebSocketImpl;
40
+ private readonly connectionTimeoutMs;
41
+ private readonly idleConnectionTimeoutMs;
42
+ private readonly callbacks;
43
+ private socket;
44
+ private stream;
45
+ private audioContext;
46
+ private processor;
47
+ private source;
48
+ private pendingSamples;
49
+ private pendingAudio;
50
+ private started;
51
+ private asrStarted;
52
+ private authenticated;
53
+ private intentionalClose;
54
+ private startPromise;
55
+ private socketOpenPromise;
56
+ private idleCloseTimer;
57
+ private authWaiter;
58
+ private asrStartWaiter;
59
+ constructor(options?: VoiceInputClientOptions);
60
+ start(): Promise<void>;
61
+ stop(): void;
62
+ cancel(): void;
63
+ close(): void;
64
+ private startInternal;
65
+ private withConnectionTimeout;
66
+ private ensureAuthenticatedSocket;
67
+ private ensureSocketOpen;
68
+ private authenticate;
69
+ private startAsrSession;
70
+ private createAuthWaiter;
71
+ private resolveAuthWaiter;
72
+ private rejectAuthWaiter;
73
+ private createAsrStartWaiter;
74
+ private resolveAsrStartWaiter;
75
+ private rejectAsrStartWaiter;
76
+ private closeWithError;
77
+ private setupAudio;
78
+ private sendAudio;
79
+ private flushPendingAudio;
80
+ private send;
81
+ private handleMessage;
82
+ private cleanupAudio;
83
+ private scheduleIdleClose;
84
+ private clearIdleCloseTimer;
85
+ private closeSocket;
86
+ }
87
+ declare class VoiceApi {
88
+ private readonly defaults;
89
+ constructor(defaults?: VoiceInputCreateOptions);
90
+ createInputClient(callbacks?: VoiceInputCallbacks, options?: VoiceInputCreateOptions): VoiceInputClient;
91
+ }
92
+ declare const createVoiceInputClient: (options?: VoiceInputClientOptions) => VoiceInputClient;
93
+ //#endregion
94
+ export { VoiceInputCreateOptions as a, WebSocketLike as c, VoiceInputClientOptions as i, createVoiceInputClient as l, VoiceInputCallbacks as n, VoiceInputEvent as o, VoiceInputClient as r, WebSocketConstructor as s, VoiceApi as t };
@@ -1,27 +1,5 @@
1
- //#region src/environment.d.ts
2
- type CohubEnvironment = "prod" | "dev";
3
- declare const COHUB_ENVIRONMENTS: {
4
- readonly prod: {
5
- readonly apiBaseUrl: "https://api.cohub.run";
6
- readonly websocketUrl: "wss://gateway.cohub.run/ws";
7
- };
8
- readonly dev: {
9
- readonly apiBaseUrl: "https://api-dev.cohub.run";
10
- readonly websocketUrl: "wss://gateway-dev.cohub.run/ws";
11
- };
12
- };
13
- declare const resolveCohubEnvironment: (env?: CohubEnvironment) => CohubEnvironment;
14
- declare const normalizeBaseUrl: (url: string) => string;
15
- declare const normalizeWebsocketUrl: (input: string) => string;
16
- declare const resolveApiBaseUrl: (options?: {
17
- baseUrl?: string;
18
- env?: CohubEnvironment;
19
- }) => string;
20
- declare const resolveWebsocketUrl: (options?: {
21
- url?: string;
22
- env?: CohubEnvironment;
23
- }) => string;
24
- //#endregion
1
+ import { n as CohubEnvironment } from "./environment.js";
2
+
25
3
  //#region ../protocol/src/core/content.d.ts
26
4
  type ContentBlockMeta = Record<string, unknown>;
27
5
  type ContentBlock = {
@@ -254,8 +232,41 @@ type MessageRecord = {
254
232
  createdAt: string;
255
233
  };
256
234
  //#endregion
235
+ //#region ../protocol/src/task/index.d.ts
236
+ type TaskRunStatus = "pending" | "running" | "completed" | "failed";
237
+ //#endregion
238
+ //#region ../protocol/src/fs/index.d.ts
239
+ type SpaceFsChange = {
240
+ path?: string;
241
+ oldPath?: string;
242
+ kind: "create" | "modify" | "delete" | "rename";
243
+ nodeType?: "file" | "dir" | "unknown";
244
+ mtimeMs?: number;
245
+ size?: number;
246
+ };
247
+ type SpaceFsChangedPayload = {
248
+ source: "sandbox-inotify" | "api-fs" | "bootstrap" | "sandbox-watch-started";
249
+ seq?: number;
250
+ resync?: boolean;
251
+ changes: SpaceFsChange[];
252
+ };
253
+ //#endregion
257
254
  //#region ../protocol/src/ports/index.d.ts
255
+ declare const SANDBOX_PUBLIC_PORTS: readonly [3000, 5173];
256
+ type SandboxPublicPort = (typeof SANDBOX_PUBLIC_PORTS)[number];
258
257
  type SpacePortStatus = "listening" | "closed";
258
+ type SpacePortChange = {
259
+ port: SandboxPublicPort | number;
260
+ protocol: "tcp";
261
+ status: SpacePortStatus;
262
+ observedAt: number;
263
+ };
264
+ type SpacePortsChangedPayload = {
265
+ source: "sandbox-port-watch" | "sandbox-port-watch-started";
266
+ seq?: number;
267
+ resync?: boolean;
268
+ ports: SpacePortChange[];
269
+ };
259
270
  type SpacePublicEndpoint = {
260
271
  url: string;
261
272
  status?: SpacePortStatus | "unknown";
@@ -267,7 +278,7 @@ type SpacePublicEndpoints = Record<string, SpacePublicEndpoint>;
267
278
  type RealtimeEnvelope = {
268
279
  id: string;
269
280
  timestamp: number;
270
- domain: "system" | "session" | "space";
281
+ domain: "system" | "session" | "space" | "label";
271
282
  type: string;
272
283
  requestId?: string | null;
273
284
  spaceId?: string | null;
@@ -275,6 +286,121 @@ type RealtimeEnvelope = {
275
286
  payload: Record<string, unknown>;
276
287
  };
277
288
  type ChannelEnvelope = RealtimeEnvelope;
289
+ type SystemReadyEvent = {
290
+ id: string;
291
+ timestamp: number;
292
+ domain: "system";
293
+ type: "system.ready";
294
+ requestId?: string | null;
295
+ spaceId?: string | null;
296
+ sessionId?: string | null;
297
+ payload: {
298
+ connectionId: string;
299
+ };
300
+ };
301
+ type SystemAuthOkEvent = {
302
+ id: string;
303
+ timestamp: number;
304
+ domain: "system";
305
+ type: "system.auth.ok";
306
+ requestId?: string | null;
307
+ spaceId?: string | null;
308
+ sessionId?: string | null;
309
+ payload: {
310
+ connectionId: string;
311
+ user: Record<string, unknown>;
312
+ };
313
+ };
314
+ type SystemRequestErrorEvent = {
315
+ id: string;
316
+ timestamp: number;
317
+ domain: "system";
318
+ type: "system.request.error";
319
+ requestId?: string | null;
320
+ spaceId?: string | null;
321
+ sessionId?: string | null;
322
+ payload: {
323
+ code?: string;
324
+ message: string;
325
+ };
326
+ };
327
+ type SystemPongEvent = {
328
+ id: string;
329
+ timestamp: number;
330
+ domain: "system";
331
+ type: "system.pong";
332
+ requestId?: string | null;
333
+ spaceId?: string | null;
334
+ sessionId?: string | null;
335
+ payload: Record<string, unknown>;
336
+ };
337
+ type SystemAckOkEvent = {
338
+ id: string;
339
+ timestamp: number;
340
+ domain: "system";
341
+ type: "system.ack.ok";
342
+ requestId?: string | null;
343
+ spaceId?: string | null;
344
+ sessionId?: string | null;
345
+ payload: {
346
+ eventId?: string;
347
+ };
348
+ };
349
+ type RealtimeSessionRecord = Pick<SessionRecord, "id" | "spaceId" | "userUuid" | "title" | "source" | "status" | "externalSessionId" | "latestMessageText" | "lastMessageAt" | "lastMessageId" | "createdAt" | "updatedAt">;
350
+ type SessionCreatedEvent = {
351
+ id: string;
352
+ timestamp: number;
353
+ domain: "session";
354
+ type: "session.created";
355
+ requestId?: string | null;
356
+ spaceId: string;
357
+ sessionId: string;
358
+ payload: {
359
+ session: RealtimeSessionRecord;
360
+ };
361
+ };
362
+ type SessionUpdatedEvent = {
363
+ id: string;
364
+ timestamp: number;
365
+ domain: "session";
366
+ type: "session.updated";
367
+ requestId?: string | null;
368
+ spaceId: string;
369
+ sessionId: string;
370
+ payload: {
371
+ session: RealtimeSessionRecord;
372
+ changed: string[];
373
+ };
374
+ };
375
+ type SessionRequestAcceptedEvent = {
376
+ id: string;
377
+ timestamp: number;
378
+ domain: "session";
379
+ type: "session.request.accepted";
380
+ requestId?: string | null;
381
+ spaceId: string;
382
+ sessionId: string;
383
+ payload: {
384
+ clientMessageId?: string | null;
385
+ turnId?: string | null;
386
+ userMessageId?: string | null;
387
+ traceId?: string | null;
388
+ };
389
+ };
390
+ type SessionRequestErrorEvent = {
391
+ id: string;
392
+ timestamp: number;
393
+ domain: "session";
394
+ type: "session.request.error";
395
+ requestId?: string | null;
396
+ spaceId?: string | null;
397
+ sessionId?: string | null;
398
+ payload: {
399
+ code?: string;
400
+ message: string;
401
+ clientMessageId?: string | null;
402
+ };
403
+ };
278
404
  type RealtimePatchOperation = {
279
405
  o: "append";
280
406
  p: string;
@@ -318,6 +444,151 @@ type SessionTurnPatchEvent = {
318
444
  ops: RealtimePatchOperation[];
319
445
  };
320
446
  };
447
+ type SessionTurnErrorEvent = {
448
+ id: string;
449
+ timestamp: number;
450
+ domain: "session";
451
+ type: "session.turn.error";
452
+ requestId?: string | null;
453
+ spaceId: string;
454
+ sessionId: string;
455
+ payload: {
456
+ turnId?: string | null;
457
+ anchorUserMessageId: string | null;
458
+ error: string;
459
+ };
460
+ };
461
+ type RealtimeTurnRecord = Partial<Pick<SessionTurnRecord, "id" | "sessionId" | "sequence" | "status" | "intent" | "userUuid" | "authorProfile" | "userContent" | "userText" | "assistantContent" | "assistantText" | "provider" | "model" | "stopReason" | "errorMessage" | "finalUsage" | "totalUsage" | "summary" | "intermediateIndex" | "intermediateSummary" | "meta" | "startedAt" | "completedAt" | "durationMs" | "createdAt" | "updatedAt">>;
462
+ type RealtimeMessageRecord = Pick<MessageRecord, "id" | "sessionId" | "role" | "content" | "text" | "sequence" | "provider" | "model" | "stopReason" | "errorMessage" | "usage" | "meta" | "startedAt" | "completedAt" | "durationMs" | "createdAt">;
463
+ type SessionTurnCreatedEvent = {
464
+ id: string;
465
+ timestamp: number;
466
+ domain: "session";
467
+ type: "session.turn.created";
468
+ requestId?: string | null;
469
+ spaceId: string;
470
+ sessionId: string;
471
+ payload: {
472
+ turn: RealtimeTurnRecord;
473
+ };
474
+ };
475
+ type SessionTurnUpdatedEvent = {
476
+ id: string;
477
+ timestamp: number;
478
+ domain: "session";
479
+ type: "session.turn.updated";
480
+ requestId?: string | null;
481
+ spaceId: string;
482
+ sessionId: string;
483
+ payload: {
484
+ turn: RealtimeTurnRecord;
485
+ };
486
+ };
487
+ type SessionTurnFinalizedEvent = {
488
+ id: string;
489
+ timestamp: number;
490
+ domain: "session";
491
+ type: "session.turn.finalized";
492
+ requestId?: string | null;
493
+ spaceId: string;
494
+ sessionId: string;
495
+ payload: {
496
+ turn: RealtimeTurnRecord;
497
+ };
498
+ };
499
+ type SessionMessagePersistedEvent = {
500
+ id: string;
501
+ timestamp: number;
502
+ domain: "session";
503
+ type: "session.message.persisted";
504
+ requestId?: string | null;
505
+ spaceId: string;
506
+ sessionId: string;
507
+ payload: {
508
+ message: RealtimeMessageRecord;
509
+ };
510
+ };
511
+ type SpaceFsChangedEvent = {
512
+ id: string;
513
+ timestamp: number;
514
+ domain: "space";
515
+ type: "space.fs.changed";
516
+ requestId?: string | null;
517
+ spaceId: string;
518
+ sessionId?: string | null;
519
+ payload: SpaceFsChangedPayload;
520
+ };
521
+ type SpacePortsChangedEvent = {
522
+ id: string;
523
+ timestamp: number;
524
+ domain: "space";
525
+ type: "space.ports.changed";
526
+ requestId?: string | null;
527
+ spaceId: string;
528
+ sessionId?: string | null;
529
+ payload: SpacePortsChangedPayload;
530
+ };
531
+ type RealtimeTaskRecord = {
532
+ id: string;
533
+ type: string;
534
+ status: TaskRunStatus;
535
+ jobId: string;
536
+ cronJobId: string | null;
537
+ spaceId: string | null;
538
+ sessionId: string | null;
539
+ turnId: string | null;
540
+ userId: string | null;
541
+ attemptCount: number;
542
+ scheduledAt: string | null;
543
+ startedAt: string | null;
544
+ finishedAt: string | null;
545
+ errorMessage: string | null;
546
+ createdAt: string;
547
+ updatedAt: string;
548
+ };
549
+ type TaskCreatedEvent = {
550
+ id: string;
551
+ timestamp: number;
552
+ domain: "space";
553
+ type: "task.created";
554
+ requestId?: string | null;
555
+ spaceId?: string | null;
556
+ sessionId?: string | null;
557
+ payload: {
558
+ task: RealtimeTaskRecord;
559
+ };
560
+ };
561
+ type TaskUpdatedEvent = {
562
+ id: string;
563
+ timestamp: number;
564
+ domain: "space";
565
+ type: "task.updated";
566
+ requestId?: string | null;
567
+ spaceId?: string | null;
568
+ sessionId?: string | null;
569
+ payload: {
570
+ task: RealtimeTaskRecord;
571
+ changed: string[];
572
+ };
573
+ };
574
+ type LabelAssignmentsUpdatedEvent = {
575
+ id: string;
576
+ timestamp: number;
577
+ domain: "label";
578
+ type: "label.assignments.updated";
579
+ requestId?: string | null;
580
+ spaceId: string;
581
+ sessionId?: string | null;
582
+ payload: {
583
+ resourceType: "session" | "checkpoint" | "file";
584
+ resourceRef: string;
585
+ labels: unknown[];
586
+ assignments: unknown[];
587
+ items?: unknown[];
588
+ affectedLabelIds: string[];
589
+ };
590
+ };
591
+ type RealtimeServerEvent = SystemReadyEvent | SystemAuthOkEvent | SystemRequestErrorEvent | SystemPongEvent | SystemAckOkEvent | SessionCreatedEvent | SessionUpdatedEvent | SessionRequestAcceptedEvent | SessionRequestErrorEvent | SessionTurnCreatedEvent | SessionTurnPatchEvent | SessionTurnErrorEvent | SessionTurnUpdatedEvent | SessionTurnFinalizedEvent | SessionMessagePersistedEvent | SpaceFsChangedEvent | SpacePortsChangedEvent | TaskCreatedEvent | TaskUpdatedEvent | LabelAssignmentsUpdatedEvent;
321
592
  //#endregion
322
593
  //#region src/websocket.d.ts
323
594
  type WebsocketEventPayload = ChannelEnvelope;
@@ -461,4 +732,4 @@ declare class WebsocketClient {
461
732
  }
462
733
  declare const createWebsocketClient: (options?: WebsocketClientOptions) => WebsocketClient;
463
734
  //#endregion
464
- export { normalizeBaseUrl as C, resolveWebsocketUrl as D, resolveCohubEnvironment as E, CohubEnvironment as S, resolveApiBaseUrl as T, SessionTurnIndexItem as _, WebsocketClientOptions as a, ContentBlock as b, createWebsocketClient as c, SpacePublicEndpoints as d, MessageRecord as f, SessionTurnSegmentRecord as g, SessionRecord as h, WebsocketClientEvents as i, RealtimePatchOperation as l, SessionForkRecord as m, WebSocketLike as n, WebsocketClientState as o, SessionBindingRecord as p, WebsocketClient as r, WebsocketEventPayload as s, WebSocketConstructor as t, SessionTurnPatchEvent as u, SessionTurnRecord as v, normalizeWebsocketUrl as w, COHUB_ENVIRONMENTS as x, Usage as y };
735
+ export { ContentBlock as C, Usage as S, SessionForkRecord as _, WebsocketClientOptions as a, SessionTurnIndexItem as b, createWebsocketClient as c, RealtimePatchOperation as d, RealtimeServerEvent as f, SessionBindingRecord as g, MessageRecord as h, WebsocketClientEvents as i, ChannelEnvelope as l, SpacePublicEndpoints as m, WebSocketLike as n, WebsocketClientState as o, SessionTurnPatchEvent as p, WebsocketClient as r, WebsocketEventPayload as s, WebSocketConstructor as t, LabelAssignmentsUpdatedEvent as u, SessionRecord as v, SessionTurnRecord as x, SessionTurnSegmentRecord as y };
@@ -1,4 +1,4 @@
1
- import { o as resolveWebsocketUrl } from "./environment.js";
1
+ import { c as resolveWebsocketUrl } from "./environment.js";
2
2
  //#region ../protocol/src/realtime/types.ts
3
3
  const WS_COMPACT_STREAM_CAPABILITY = "session.compact_stream.v1";
4
4
  const getNonEmptyString = (value) => typeof value === "string" && value.trim() ? value : null;
@@ -60,7 +60,7 @@ const isRealtimeEnvelope = (value) => {
60
60
  if (!isRecord(value)) return false;
61
61
  if (typeof value.id !== "string") return false;
62
62
  if (typeof value.timestamp !== "number") return false;
63
- if (value.domain !== "system" && value.domain !== "session" && value.domain !== "space") return false;
63
+ if (value.domain !== "system" && value.domain !== "session" && value.domain !== "space" && value.domain !== "label") return false;
64
64
  if (typeof value.type !== "string") return false;
65
65
  if (!isRecord(value.payload)) return false;
66
66
  return true;
package/dist/http.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { _ as SessionTurnIndexItem, b as ContentBlock, f as MessageRecord, g as SessionTurnSegmentRecord, m as SessionForkRecord, v as SessionTurnRecord } from "./chunks/websocket.js";
1
+ import { C as ContentBlock, _ as SessionForkRecord, b as SessionTurnIndexItem, h as MessageRecord, x as SessionTurnRecord, y as SessionTurnSegmentRecord } from "./chunks/websocket.js";
2
2
  import { $ as BillingOpenOverageStatus, $n as CreateGenerationTaskRequest, $t as SessionTurnSignedUrlsResponse, An as SpaceFsUploadPlanEntry, At as JsonValue, Bn as SpacePublicProfile, Bt as ModelCatalogEntry, Cn as SpaceFsReadFilesError, Ct as ExploreSpacesResponse, Dn as SpaceFsUploadDestination, Dt as InvitationDetail, En as SpaceFsTreeResponse, Et as GlobalSearchType, Fn as SpaceInvitation, Ft as LabelRecord, G as BillingCatalog, Gn as SpaceSessionsResponse, Gt as ResourceLabelsResponse, Hn as SpaceRole, Ht as PromptAccessMode, In as SpaceListItem, It as LabelResourceType, J as BillingCreditExpiryGroup, Jn as SpaceUsageSummary, Jt as SessionMessagesPaginatedResponse, K as BillingCatalogProduct, Kn as SpaceUsageHourlyStat, Kt as SessionBindingRecord, Ln as SpaceMember, Lt as LabelScopeType, Mn as SpaceFsUploadProgress, Mt as LabelAssignmentPageInfo, Nn as SpaceFsUploadResponse, Nt as LabelAssignmentRecord, On as SpaceFsUploadEntry, Ot as JsonObject, Pn as SpaceFsWriteFileInput, Pt as LabelListItem, Q as BillingOpenOverageList, Qn as UserRulesResponse, Qt as SessionTurnResponse, Rn as SpaceMeta, Rt as LabelSource, Sn as SpaceFsPreparingFile, Sr as HttpTransport, St as ExploreSpaceItem, Tn as SpaceFsReadFilesResponse, Tt as GlobalSearchResult, U as AcceptInvitationResponse, Un as SpaceSandboxAutoDestroyPolicy, Ut as PromptTemplateCatalogEntry, Vn as SpaceRecord, Vt as Permission, W as ApiError, Wn as SpaceSandboxConfig, Wt as PromptTemplateCatalogResponse, X as BillingCreditStatus, Xn as TaskRunRecord, Xt as SessionRecord, Y as BillingCreditGrantStatus, Yn as TaskRunDetailResponse, Yt as SessionMessagesResponse, Z as BillingCreditUnit, Zn as UserProfile, Zt as SessionTurnIndexResponse, _n as SpaceFsEncoding, _r as ChannelConfig, _t as CreateSpacePromptInput, an as SpaceBootstrapSource, at as BillingProductKind, bn as SpaceFsFileResponse, br as Fetch, bt as CronJobRecord, cn as SpaceConfig, ct as BillingSubscriptionSummary, dn as SpaceCreateResponse, dt as Channel, en as SessionTurnStreamSnapshotResponse, er as CreateGenerationTaskResponse, et as BillingPaymentStatus, fn as SpaceEnvInput, ft as CheckpointRecord, gn as SpaceFsCreateUploadResponse, gr as GenerationContentBlock, gt as CreateSpaceModInput, hn as SpaceFsCreateUploadInput, ht as CreateSpaceInput, in as SpaceAccessPolicy, it as BillingProductDisplay, jn as SpaceFsUploadPlanEntryInput, jt as LabelAssignmentListItem, kn as SpaceFsUploadError, kt as JsonPrimitive, ln as SpaceConfigInput, lt as BillingUsageRecordList, mn as SpaceFsCompleteUploadResponse, mt as CreateInvitationResponse, n as createHttpClient, nn as SessionTurnsPaginatedResponse, nr as ListGenerationModelsResponse, nt as BillingProductBillingInterval, on as SpaceChannelBindingInput, or as GenerationPolicy, ot as BillingProductPricing, pn as SpaceFsCompleteUploadInput, pt as CreateInvitationInput, q as BillingCheckoutResult, qn as SpaceUsageResponse, qt as SessionMessageResponse, rn as SpaceAccess, rr as PublicGenerationDeclaration, rt as BillingProductCreditBenefit, sn as SpaceCheckpointDetailResponse, st as BillingRedemptionResult, t as CohubHttpClient, tn as SessionTurnWindowResponse, tr as GenerationTaskResult, tt as BillingPluginStatus, un as SpaceConfigResponse, ut as BillingUsageRecordStatus, vn as SpaceFsEntry, vr as DiscordChannelConfig, vt as CreateSpacePromptResponse, wn as SpaceFsReadFilesInput, wt as GlobalSearchResponse, xn as SpaceFsMoveInput, xr as HttpError, xt as ExploreSection, yn as SpaceFsFileKind, yr as CohubClientOptions, yt as CreateSpaceSessionInput, zn as SpaceModListItem, zt as MeResponse } from "./chunks/http.js";
3
3
  export { AcceptInvitationResponse, ApiError, BillingCatalog, BillingCatalogProduct, BillingCheckoutResult, BillingCreditExpiryGroup, BillingCreditGrantStatus, BillingCreditStatus, BillingCreditUnit, BillingOpenOverageList, BillingOpenOverageStatus, BillingPaymentStatus, BillingPluginStatus, BillingProductBillingInterval, BillingProductCreditBenefit, BillingProductDisplay, BillingProductKind, BillingProductPricing, BillingRedemptionResult, BillingSubscriptionSummary, BillingUsageRecordList, BillingUsageRecordStatus, Channel, type ChannelConfig, CheckpointRecord, type CohubClientOptions, CohubHttpClient, type ContentBlock, type CreateGenerationTaskRequest, type CreateGenerationTaskResponse, CreateInvitationInput, CreateInvitationResponse, CreateSpaceInput, CreateSpaceModInput, CreateSpacePromptInput, CreateSpacePromptResponse, CreateSpaceSessionInput, CronJobRecord, type DiscordChannelConfig, ExploreSection, ExploreSpaceItem, ExploreSpacesResponse, type Fetch, type GenerationContentBlock, type GenerationPolicy, type GenerationTaskResult, GlobalSearchResponse, GlobalSearchResult, GlobalSearchType, HttpError, HttpTransport, InvitationDetail, JsonObject, JsonPrimitive, JsonValue, LabelAssignmentListItem, LabelAssignmentPageInfo, LabelAssignmentRecord, LabelListItem, LabelRecord, LabelResourceType, LabelScopeType, LabelSource, type ListGenerationModelsResponse, MeResponse, type MessageRecord, ModelCatalogEntry, Permission, PromptAccessMode, PromptTemplateCatalogEntry, PromptTemplateCatalogResponse, type PublicGenerationDeclaration, ResourceLabelsResponse, SessionBindingRecord, type SessionForkRecord, SessionMessageResponse, SessionMessagesPaginatedResponse, SessionMessagesResponse, SessionRecord, type SessionTurnIndexItem, SessionTurnIndexResponse, type SessionTurnRecord, SessionTurnResponse, type SessionTurnSegmentRecord, SessionTurnSignedUrlsResponse, SessionTurnStreamSnapshotResponse, SessionTurnWindowResponse, SessionTurnsPaginatedResponse, SpaceAccess, SpaceAccessPolicy, SpaceBootstrapSource, SpaceChannelBindingInput, SpaceCheckpointDetailResponse, SpaceConfig, SpaceConfigInput, SpaceConfigResponse, SpaceCreateResponse, SpaceEnvInput, SpaceFsCompleteUploadInput, SpaceFsCompleteUploadResponse, SpaceFsCreateUploadInput, SpaceFsCreateUploadResponse, SpaceFsEncoding, SpaceFsEntry, SpaceFsFileKind, SpaceFsFileResponse, SpaceFsMoveInput, SpaceFsPreparingFile, SpaceFsReadFilesError, SpaceFsReadFilesInput, SpaceFsReadFilesResponse, SpaceFsTreeResponse, SpaceFsUploadDestination, SpaceFsUploadEntry, SpaceFsUploadError, SpaceFsUploadPlanEntry, SpaceFsUploadPlanEntryInput, SpaceFsUploadProgress, SpaceFsUploadResponse, SpaceFsWriteFileInput, SpaceInvitation, SpaceListItem, SpaceMember, SpaceMeta, SpaceModListItem, SpacePublicProfile, SpaceRecord, SpaceRole, SpaceSandboxAutoDestroyPolicy, SpaceSandboxConfig, SpaceSessionsResponse, SpaceUsageHourlyStat, SpaceUsageResponse, SpaceUsageSummary, TaskRunDetailResponse, TaskRunRecord, UserProfile, UserRulesResponse, createHttpClient };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import { C as normalizeBaseUrl, D as resolveWebsocketUrl, E as resolveCohubEnvironment, S as CohubEnvironment, T as resolveApiBaseUrl, _ as SessionTurnIndexItem, b as ContentBlock, c as createWebsocketClient, f as MessageRecord, g as SessionTurnSegmentRecord, m as SessionForkRecord, r as WebsocketClient, v as SessionTurnRecord, w as normalizeWebsocketUrl, x as COHUB_ENVIRONMENTS } from "./chunks/websocket.js";
1
+ import { a as normalizeWebsocketUrl, c as resolveVoiceInputWebsocketUrl, i as normalizeVoiceInputWebsocketUrl, l as resolveWebsocketUrl, n as CohubEnvironment, o as resolveApiBaseUrl, r as normalizeBaseUrl, s as resolveCohubEnvironment, t as COHUB_ENVIRONMENTS } from "./chunks/environment.js";
2
+ import { C as ContentBlock, _ as SessionForkRecord, b as SessionTurnIndexItem, c as createWebsocketClient, f as RealtimeServerEvent, h as MessageRecord, l as ChannelEnvelope, r as WebsocketClient, u as LabelAssignmentsUpdatedEvent, x as SessionTurnRecord, y as SessionTurnSegmentRecord } from "./chunks/websocket.js";
3
+ import { a as VoiceInputCreateOptions, i as VoiceInputClientOptions, l as createVoiceInputClient, n as VoiceInputCallbacks, o as VoiceInputEvent, r as VoiceInputClient, t as VoiceApi } from "./chunks/voice-input.js";
2
4
  import { $ as BillingOpenOverageStatus, $n as CreateGenerationTaskRequest, $t as SessionTurnSignedUrlsResponse, A as SessionPatchStatus, An as SpaceFsUploadPlanEntry, At as JsonValue, B as GenerationsApi, Bn as SpacePublicProfile, Bt as ModelCatalogEntry, C as SessionGenerationStreamClient, Cn as SpaceFsReadFilesError, Cr as RawHttpResponse, Ct as ExploreSpacesResponse, D as SessionPatchApplyResult, Dn as SpaceFsUploadDestination, Dt as InvitationDetail, E as SessionPatchApplyInput, En as SpaceFsTreeResponse, Et as GlobalSearchType, F as CreatePublicAssetUploadResponse, Fn as SpaceInvitation, Ft as LabelRecord, G as BillingCatalog, Gn as SpaceSessionsResponse, Gt as ResourceLabelsResponse, H as ChannelsApi, Hn as SpaceRole, Ht as PromptAccessMode, I as PublicAssetPurpose, In as SpaceListItem, It as LabelResourceType, J as BillingCreditExpiryGroup, Jn as SpaceUsageSummary, Jt as SessionMessagesPaginatedResponse, K as BillingCatalogProduct, Kn as SpaceUsageHourlyStat, Kt as SessionBindingRecord, L as PublicAssetsApi, Ln as SpaceMember, Lt as LabelScopeType, M as SessionAccessApi, Mn as SpaceFsUploadProgress, Mt as LabelAssignmentPageInfo, N as SearchApi, Nn as SpaceFsUploadResponse, Nt as LabelAssignmentRecord, O as SessionPatchReducer, On as SpaceFsUploadEntry, Ot as JsonObject, P as CreatePublicAssetUploadInput, Pn as SpaceFsWriteFileInput, Pt as LabelListItem, Q as BillingOpenOverageList, Qn as UserRulesResponse, Qt as SessionTurnResponse, R as PromptsApi, Rn as SpaceMeta, Rt as LabelSource, S as GenerationStreamTurnUpdatedEvent, Sn as SpaceFsPreparingFile, Sr as HttpTransport, St as ExploreSpaceItem, T as parseAssistantMessageCommit, Tn as SpaceFsReadFilesResponse, Tt as GlobalSearchResult, U as AcceptInvitationResponse, Un as SpaceSandboxAutoDestroyPolicy, Ut as PromptTemplateCatalogEntry, V as CronJobsApi, Vn as SpaceRecord, Vt as Permission, W as ApiError, Wn as SpaceSandboxConfig, Wt as PromptTemplateCatalogResponse, X as BillingCreditStatus, Xn as TaskRunRecord, Xt as SessionRecord, Y as BillingCreditGrantStatus, Yn as TaskRunDetailResponse, Yt as SessionMessagesResponse, Z as BillingCreditUnit, Zn as UserProfile, Zt as SessionTurnIndexResponse, _ as GenerationStreamFinalizedEvent, _n as SpaceFsEncoding, _r as ChannelConfig, _t as CreateSpacePromptInput, a as SessionEventName, an as SpaceBootstrapSource, ar as GenerationParameterConstraint, at as BillingProductKind, b as GenerationStreamStateEvent, bn as SpaceFsFileResponse, br as Fetch, bt as CronJobRecord, c as SpaceClient, cn as SpaceConfig, cr as assertGenerationRequestAllowedByPolicy, ct as BillingSubscriptionSummary, d as WebSocketConnectionState, dn as SpaceCreateResponse, dr as filterGenerationDeclarationsByPolicy, dt as Channel, en as SessionTurnStreamSnapshotResponse, er as CreateGenerationTaskResponse, et as BillingPaymentStatus, f as PublicInviteApi, fn as SpaceEnvInput, fr as findGenerationModelPolicy, ft as CheckpointRecord, g as GenerationStreamEvent, gn as SpaceFsCreateUploadResponse, gr as GenerationContentBlock, gt as CreateSpaceModInput, h as GenerationStreamErrorEvent, hn as SpaceFsCreateUploadInput, hr as parseGenerationPolicyFromEnv, ht as CreateSpaceInput, i as TasksApi, in as SpaceAccessPolicy, ir as GenerationModelPolicy, it as BillingProductDisplay, j as createSessionPatchReducer, jn as SpaceFsUploadPlanEntryInput, jt as LabelAssignmentListItem, k as SessionPatchState, kn as SpaceFsUploadError, kt as JsonPrimitive, l as SpaceEventName, ln as SpaceConfigInput, lr as decodeGenerationPolicy, lt as BillingUsageRecordList, m as GenerationStreamCommitEvent, mn as SpaceFsCompleteUploadResponse, mr as normalizeGenerationPolicy, mt as CreateInvitationResponse, n as createHttpClient, nn as SessionTurnsPaginatedResponse, nr as ListGenerationModelsResponse, nt as BillingProductBillingInterval, o as SessionSubscriptionHandlers, on as SpaceChannelBindingInput, or as GenerationPolicy, ot as BillingProductPricing, p as AssistantMessageCommit, pn as SpaceFsCompleteUploadInput, pr as getAllowedGenerationModelIds, pt as CreateInvitationInput, q as BillingCheckoutResult, qn as SpaceUsageResponse, qt as SessionMessageResponse, r as UserApi, rn as SpaceAccess, rr as PublicGenerationDeclaration, rt as BillingProductCreditBenefit, s as SpaceChannelBindingRecord, sn as SpaceCheckpointDetailResponse, sr as GenerationPolicyError, st as BillingRedemptionResult, t as CohubHttpClient, tn as SessionTurnWindowResponse, tr as GenerationTaskResult, tt as BillingPluginStatus, u as SpacesApi, un as SpaceConfigResponse, ur as encodeGenerationPolicy, ut as BillingUsageRecordStatus, v as GenerationStreamIntermediateMessage, vn as SpaceFsEntry, vr as DiscordChannelConfig, vt as CreateSpacePromptResponse, w as createSessionGenerationStreamClient, wn as SpaceFsReadFilesInput, wt as GlobalSearchResponse, x as GenerationStreamSubscriptionHandlers, xn as SpaceFsMoveInput, xr as HttpError, xt as ExploreSection, y as GenerationStreamOutOfSyncEvent, yn as SpaceFsFileKind, yr as CohubClientOptions, yt as CreateSpaceSessionInput, z as ModelsApi, zn as SpaceModListItem, zt as MeResponse } from "./chunks/http.js";
3
5
 
4
6
  //#region src/apis/billing.d.ts
@@ -67,6 +69,7 @@ declare class CohubClient {
67
69
  readonly cronJobs: CronJobsApi;
68
70
  readonly explore: ExploreApi;
69
71
  readonly invite: PublicInviteApi;
72
+ readonly voice: VoiceApi;
70
73
  private readonly transport;
71
74
  private readonly websocketClient;
72
75
  constructor(options?: CohubClientOptions);
@@ -75,4 +78,4 @@ declare class CohubClient {
75
78
  }
76
79
  declare const createCohubClient: (options?: CohubClientOptions) => CohubClient;
77
80
  //#endregion
78
- export { AcceptInvitationResponse, ApiError, type AssistantMessageCommit, BillingApi, BillingCatalog, BillingCatalogProduct, BillingCheckoutResult, BillingCreditExpiryGroup, BillingCreditGrantStatus, BillingCreditStatus, BillingCreditUnit, BillingOpenOverageList, BillingOpenOverageStatus, BillingPaymentStatus, BillingPluginStatus, BillingProductBillingInterval, BillingProductCreditBenefit, BillingProductDisplay, BillingProductKind, BillingProductPricing, BillingRedemptionResult, BillingSubscriptionSummary, BillingUsageRecordList, BillingUsageRecordStatus, COHUB_ENVIRONMENTS, Channel, type ChannelConfig, CheckpointRecord, CohubClient, type CohubClientOptions, type CohubEnvironment, CohubHttpClient, type ContentBlock, type CreateGenerationTaskRequest, type CreateGenerationTaskResponse, CreateInvitationInput, CreateInvitationResponse, type CreatePublicAssetUploadInput, type CreatePublicAssetUploadResponse, CreateSpaceInput, CreateSpaceModInput, CreateSpacePromptInput, CreateSpacePromptResponse, CreateSpaceSessionInput, CronJobRecord, type DiscordChannelConfig, ExploreSection, ExploreSpaceItem, ExploreSpacesResponse, type Fetch, type GenerationContentBlock, type GenerationModelPolicy, type GenerationParameterConstraint, type GenerationPolicy, GenerationPolicyError, type GenerationStreamCommitEvent, type GenerationStreamErrorEvent, type GenerationStreamEvent, type GenerationStreamFinalizedEvent, type GenerationStreamIntermediateMessage, type GenerationStreamOutOfSyncEvent, type GenerationStreamStateEvent, type GenerationStreamSubscriptionHandlers, type GenerationStreamTurnUpdatedEvent, type GenerationTaskResult, GlobalSearchResponse, GlobalSearchResult, GlobalSearchType, HttpError, InvitationDetail, JsonObject, JsonPrimitive, JsonValue, LabelAssignmentListItem, LabelAssignmentPageInfo, LabelAssignmentRecord, LabelListItem, LabelRecord, LabelResourceType, LabelScopeType, LabelSource, type ListGenerationModelsResponse, MeResponse, type MessageRecord, ModelCatalogEntry, Permission, PromptAccessMode, PromptTemplateCatalogEntry, PromptTemplateCatalogResponse, type PublicAssetPurpose, type PublicGenerationDeclaration, type RawHttpResponse, ResourceLabelsResponse, SessionBindingRecord, type SessionEventName, type SessionForkRecord, SessionGenerationStreamClient, SessionMessageResponse, SessionMessagesPaginatedResponse, SessionMessagesResponse, type SessionPatchApplyInput, type SessionPatchApplyResult, SessionPatchReducer, type SessionPatchState, type SessionPatchStatus, SessionRecord, type SessionSubscriptionHandlers, type SessionTurnIndexItem, SessionTurnIndexResponse, type SessionTurnRecord, SessionTurnResponse, type SessionTurnSegmentRecord, SessionTurnSignedUrlsResponse, SessionTurnStreamSnapshotResponse, SessionTurnWindowResponse, SessionTurnsPaginatedResponse, SpaceAccess, SpaceAccessPolicy, SpaceBootstrapSource, SpaceChannelBindingInput, type SpaceChannelBindingRecord, SpaceCheckpointDetailResponse, SpaceConfig, SpaceConfigInput, SpaceConfigResponse, SpaceCreateResponse, SpaceEnvInput, type SpaceEventName, SpaceFsCompleteUploadInput, SpaceFsCompleteUploadResponse, SpaceFsCreateUploadInput, SpaceFsCreateUploadResponse, SpaceFsEncoding, SpaceFsEntry, SpaceFsFileKind, SpaceFsFileResponse, SpaceFsMoveInput, SpaceFsPreparingFile, SpaceFsReadFilesError, SpaceFsReadFilesInput, SpaceFsReadFilesResponse, SpaceFsTreeResponse, SpaceFsUploadDestination, SpaceFsUploadEntry, SpaceFsUploadError, SpaceFsUploadPlanEntry, SpaceFsUploadPlanEntryInput, SpaceFsUploadProgress, SpaceFsUploadResponse, SpaceFsWriteFileInput, SpaceInvitation, SpaceListItem, SpaceMember, SpaceMeta, SpaceModListItem, SpacePublicProfile, SpaceRecord, SpaceRole, SpaceSandboxAutoDestroyPolicy, SpaceSandboxConfig, SpaceSessionsResponse, SpaceUsageHourlyStat, SpaceUsageResponse, SpaceUsageSummary, TaskRunDetailResponse, TaskRunRecord, UserProfile, UserRulesResponse, type WebSocketConnectionState, WebsocketClient, assertGenerationRequestAllowedByPolicy, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createWebsocketClient, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, normalizeBaseUrl, normalizeGenerationPolicy, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveWebsocketUrl };
81
+ export { AcceptInvitationResponse, ApiError, type AssistantMessageCommit, BillingApi, BillingCatalog, BillingCatalogProduct, BillingCheckoutResult, BillingCreditExpiryGroup, BillingCreditGrantStatus, BillingCreditStatus, BillingCreditUnit, BillingOpenOverageList, BillingOpenOverageStatus, BillingPaymentStatus, BillingPluginStatus, BillingProductBillingInterval, BillingProductCreditBenefit, BillingProductDisplay, BillingProductKind, BillingProductPricing, BillingRedemptionResult, BillingSubscriptionSummary, BillingUsageRecordList, BillingUsageRecordStatus, COHUB_ENVIRONMENTS, Channel, type ChannelConfig, type ChannelEnvelope, CheckpointRecord, CohubClient, type CohubClientOptions, type CohubEnvironment, CohubHttpClient, type ContentBlock, type CreateGenerationTaskRequest, type CreateGenerationTaskResponse, CreateInvitationInput, CreateInvitationResponse, type CreatePublicAssetUploadInput, type CreatePublicAssetUploadResponse, CreateSpaceInput, CreateSpaceModInput, CreateSpacePromptInput, CreateSpacePromptResponse, CreateSpaceSessionInput, CronJobRecord, type DiscordChannelConfig, ExploreSection, ExploreSpaceItem, ExploreSpacesResponse, type Fetch, type GenerationContentBlock, type GenerationModelPolicy, type GenerationParameterConstraint, type GenerationPolicy, GenerationPolicyError, type GenerationStreamCommitEvent, type GenerationStreamErrorEvent, type GenerationStreamEvent, type GenerationStreamFinalizedEvent, type GenerationStreamIntermediateMessage, type GenerationStreamOutOfSyncEvent, type GenerationStreamStateEvent, type GenerationStreamSubscriptionHandlers, type GenerationStreamTurnUpdatedEvent, type GenerationTaskResult, GlobalSearchResponse, GlobalSearchResult, GlobalSearchType, HttpError, InvitationDetail, JsonObject, JsonPrimitive, JsonValue, LabelAssignmentListItem, LabelAssignmentPageInfo, LabelAssignmentRecord, type LabelAssignmentsUpdatedEvent, LabelListItem, LabelRecord, LabelResourceType, LabelScopeType, LabelSource, type ListGenerationModelsResponse, MeResponse, type MessageRecord, ModelCatalogEntry, Permission, PromptAccessMode, PromptTemplateCatalogEntry, PromptTemplateCatalogResponse, type PublicAssetPurpose, type PublicGenerationDeclaration, type RawHttpResponse, type RealtimeServerEvent, ResourceLabelsResponse, SessionBindingRecord, type SessionEventName, type SessionForkRecord, SessionGenerationStreamClient, SessionMessageResponse, SessionMessagesPaginatedResponse, SessionMessagesResponse, type SessionPatchApplyInput, type SessionPatchApplyResult, SessionPatchReducer, type SessionPatchState, type SessionPatchStatus, SessionRecord, type SessionSubscriptionHandlers, type SessionTurnIndexItem, SessionTurnIndexResponse, type SessionTurnRecord, SessionTurnResponse, type SessionTurnSegmentRecord, SessionTurnSignedUrlsResponse, SessionTurnStreamSnapshotResponse, SessionTurnWindowResponse, SessionTurnsPaginatedResponse, SpaceAccess, SpaceAccessPolicy, SpaceBootstrapSource, SpaceChannelBindingInput, type SpaceChannelBindingRecord, SpaceCheckpointDetailResponse, SpaceConfig, SpaceConfigInput, SpaceConfigResponse, SpaceCreateResponse, SpaceEnvInput, type SpaceEventName, SpaceFsCompleteUploadInput, SpaceFsCompleteUploadResponse, SpaceFsCreateUploadInput, SpaceFsCreateUploadResponse, SpaceFsEncoding, SpaceFsEntry, SpaceFsFileKind, SpaceFsFileResponse, SpaceFsMoveInput, SpaceFsPreparingFile, SpaceFsReadFilesError, SpaceFsReadFilesInput, SpaceFsReadFilesResponse, SpaceFsTreeResponse, SpaceFsUploadDestination, SpaceFsUploadEntry, SpaceFsUploadError, SpaceFsUploadPlanEntry, SpaceFsUploadPlanEntryInput, SpaceFsUploadProgress, SpaceFsUploadResponse, SpaceFsWriteFileInput, SpaceInvitation, SpaceListItem, SpaceMember, SpaceMeta, SpaceModListItem, SpacePublicProfile, SpaceRecord, SpaceRole, SpaceSandboxAutoDestroyPolicy, SpaceSandboxConfig, SpaceSessionsResponse, SpaceUsageHourlyStat, SpaceUsageResponse, SpaceUsageSummary, TaskRunDetailResponse, TaskRunRecord, UserProfile, UserRulesResponse, VoiceApi, type VoiceInputCallbacks, VoiceInputClient, type VoiceInputClientOptions, type VoiceInputCreateOptions, type VoiceInputEvent, type WebSocketConnectionState, WebsocketClient, assertGenerationRequestAllowedByPolicy, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createVoiceInputClient, createWebsocketClient, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, normalizeBaseUrl, normalizeGenerationPolicy, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { S as ChannelsApi, _ as PublicAssetsApi, a as SpaceClient, b as GenerationsApi, c as SessionGenerationStreamClient, d as SessionPatchReducer, f as createSessionPatchReducer, g as SearchApi, h as SessionAccessApi, i as TasksApi, l as createSessionGenerationStreamClient, m as HttpTransport, n as createHttpClient, o as SpacesApi, p as HttpError, r as UserApi, s as PublicInviteApi, t as CohubHttpClient, u as parseAssistantMessageCommit, v as PromptsApi, x as CronJobsApi, y as ModelsApi } from "./chunks/http.js";
2
- import { a as resolveCohubEnvironment, i as resolveApiBaseUrl, n as normalizeBaseUrl, o as resolveWebsocketUrl, r as normalizeWebsocketUrl, t as COHUB_ENVIRONMENTS } from "./chunks/environment.js";
2
+ import { a as resolveApiBaseUrl, c as resolveWebsocketUrl, i as normalizeWebsocketUrl, n as normalizeBaseUrl, o as resolveCohubEnvironment, r as normalizeVoiceInputWebsocketUrl, s as resolveVoiceInputWebsocketUrl, t as COHUB_ENVIRONMENTS } from "./chunks/environment.js";
3
3
  import { n as createWebsocketClient, t as WebsocketClient } from "./chunks/websocket.js";
4
+ import { VoiceApi, VoiceInputClient, createVoiceInputClient } from "./voice-input.js";
4
5
  //#region src/apis/billing.ts
5
6
  var BillingApi = class {
6
7
  transport;
@@ -77,6 +78,7 @@ var CohubClient = class {
77
78
  cronJobs;
78
79
  explore;
79
80
  invite;
81
+ voice;
80
82
  transport;
81
83
  websocketClient;
82
84
  constructor(options = {}) {
@@ -88,7 +90,15 @@ var CohubClient = class {
88
90
  url: options.websocket?.url
89
91
  }),
90
92
  ...options.websocket,
91
- getAccessToken: options.getAccessToken
93
+ getAccessToken: options.websocket?.getAccessToken ?? options.getAccessToken
94
+ });
95
+ this.voice = new VoiceApi({
96
+ env: options.voice?.env ?? options.env,
97
+ url: options.voice?.url,
98
+ getAccessToken: options.voice?.getAccessToken ?? options.getAccessToken,
99
+ WebSocketImpl: options.voice?.WebSocketImpl,
100
+ connectionTimeoutMs: options.voice?.connectionTimeoutMs,
101
+ idleConnectionTimeoutMs: options.voice?.idleConnectionTimeoutMs
92
102
  });
93
103
  this.spaces = new SpacesApi(this.transport);
94
104
  this.channels = new ChannelsApi(this.transport);
@@ -386,4 +396,4 @@ function filterGenerationDeclarationsByPolicy(declarations, policy) {
386
396
  });
387
397
  }
388
398
  //#endregion
389
- export { BillingApi, COHUB_ENVIRONMENTS, CohubClient, CohubHttpClient, GenerationPolicyError, HttpError, SessionGenerationStreamClient, SessionPatchReducer, WebsocketClient, assertGenerationRequestAllowedByPolicy, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createWebsocketClient, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, normalizeBaseUrl, normalizeGenerationPolicy, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveWebsocketUrl };
399
+ export { BillingApi, COHUB_ENVIRONMENTS, CohubClient, CohubHttpClient, GenerationPolicyError, HttpError, SessionGenerationStreamClient, SessionPatchReducer, VoiceApi, VoiceInputClient, WebsocketClient, assertGenerationRequestAllowedByPolicy, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createVoiceInputClient, createWebsocketClient, decodeGenerationPolicy, encodeGenerationPolicy, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, getAllowedGenerationModelIds, normalizeBaseUrl, normalizeGenerationPolicy, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseGenerationPolicyFromEnv, resolveApiBaseUrl, resolveCohubEnvironment, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl };
@@ -0,0 +1,2 @@
1
+ import { a as VoiceInputCreateOptions, c as WebSocketLike, i as VoiceInputClientOptions, l as createVoiceInputClient, n as VoiceInputCallbacks, o as VoiceInputEvent, r as VoiceInputClient, s as WebSocketConstructor, t as VoiceApi } from "./chunks/voice-input.js";
2
+ export { VoiceApi, VoiceInputCallbacks, VoiceInputClient, VoiceInputClientOptions, VoiceInputCreateOptions, VoiceInputEvent, WebSocketConstructor, WebSocketLike, createVoiceInputClient };
@@ -0,0 +1,394 @@
1
+ import { s as resolveVoiceInputWebsocketUrl } from "./chunks/environment.js";
2
+ //#region src/voice-input.ts
3
+ const TARGET_SAMPLE_RATE = 16e3;
4
+ const CHUNK_SAMPLES = TARGET_SAMPLE_RATE * 200 / 1e3;
5
+ const DEFAULT_CONNECTION_TIMEOUT_MS = 1e4;
6
+ const DEFAULT_IDLE_CONNECTION_TIMEOUT_MS = 30 * 6e4;
7
+ const WEBSOCKET_OPEN = 1;
8
+ const getDefaultWebSocket = () => {
9
+ const WebSocketImpl = globalThis.WebSocket;
10
+ if (!WebSocketImpl) throw new Error("WebSocket is not available in this environment");
11
+ return WebSocketImpl;
12
+ };
13
+ const getDefaultAudioContext = () => {
14
+ const context = globalThis;
15
+ return context.AudioContext ?? context.webkitAudioContext;
16
+ };
17
+ const encodeBase64 = (bytes) => {
18
+ if (typeof btoa === "function") {
19
+ let binary = "";
20
+ for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i] ?? 0);
21
+ return btoa(binary);
22
+ }
23
+ const maybeBuffer = globalThis.Buffer;
24
+ if (maybeBuffer) return maybeBuffer.from(bytes).toString("base64");
25
+ throw new Error("Base64 encoding is not available in this environment");
26
+ };
27
+ const floatToPcm16 = (samples) => {
28
+ const buffer = /* @__PURE__ */ new ArrayBuffer(samples.length * 2);
29
+ const view = new DataView(buffer);
30
+ for (let i = 0; i < samples.length; i += 1) {
31
+ const sample = Math.max(-1, Math.min(1, samples[i] ?? 0));
32
+ view.setInt16(i * 2, sample < 0 ? sample * 32768 : sample * 32767, true);
33
+ }
34
+ return new Uint8Array(buffer);
35
+ };
36
+ const resampleTo16k = (input, inputSampleRate) => {
37
+ if (inputSampleRate === TARGET_SAMPLE_RATE) return input;
38
+ const ratio = inputSampleRate / TARGET_SAMPLE_RATE;
39
+ const length = Math.floor(input.length / ratio);
40
+ const output = new Float32Array(length);
41
+ for (let i = 0; i < length; i += 1) {
42
+ const index = i * ratio;
43
+ const left = Math.floor(index);
44
+ const right = Math.min(left + 1, input.length - 1);
45
+ const weight = index - left;
46
+ output[i] = (input[left] ?? 0) * (1 - weight) + (input[right] ?? 0) * weight;
47
+ }
48
+ return output;
49
+ };
50
+ const getErrorCode = (event) => {
51
+ const code = event.payload?.code;
52
+ return typeof code === "string" ? code : null;
53
+ };
54
+ const getErrorMessage = (event) => {
55
+ const message = event.payload?.message;
56
+ return typeof message === "string" ? message : "Voice input failed";
57
+ };
58
+ var VoiceInputClient = class {
59
+ url;
60
+ getAccessToken;
61
+ WebSocketImpl;
62
+ connectionTimeoutMs;
63
+ idleConnectionTimeoutMs;
64
+ callbacks;
65
+ socket = null;
66
+ stream = null;
67
+ audioContext = null;
68
+ processor = null;
69
+ source = null;
70
+ pendingSamples = [];
71
+ pendingAudio = [];
72
+ started = false;
73
+ asrStarted = false;
74
+ authenticated = false;
75
+ intentionalClose = false;
76
+ startPromise = null;
77
+ socketOpenPromise = null;
78
+ idleCloseTimer = null;
79
+ authWaiter = null;
80
+ asrStartWaiter = null;
81
+ constructor(options = {}) {
82
+ this.url = resolveVoiceInputWebsocketUrl({
83
+ env: options.env,
84
+ url: options.url
85
+ });
86
+ this.getAccessToken = options.getAccessToken;
87
+ this.WebSocketImpl = options.WebSocketImpl ?? getDefaultWebSocket();
88
+ this.connectionTimeoutMs = options.connectionTimeoutMs ?? DEFAULT_CONNECTION_TIMEOUT_MS;
89
+ this.idleConnectionTimeoutMs = options.idleConnectionTimeoutMs ?? DEFAULT_IDLE_CONNECTION_TIMEOUT_MS;
90
+ this.callbacks = options.callbacks ?? {};
91
+ }
92
+ async start() {
93
+ if (this.startPromise) return this.startPromise;
94
+ if (this.started) return;
95
+ this.startPromise = this.startInternal().finally(() => {
96
+ this.startPromise = null;
97
+ });
98
+ return this.startPromise;
99
+ }
100
+ stop() {
101
+ if (this.pendingSamples.length > 0) this.sendAudio(new Float32Array(this.pendingSamples.splice(0)));
102
+ this.flushPendingAudio();
103
+ if (this.asrStarted) this.send({ type: "asr.stop" });
104
+ this.cleanupAudio();
105
+ this.started = false;
106
+ this.scheduleIdleClose();
107
+ }
108
+ cancel() {
109
+ if (this.asrStarted) this.send({ type: "asr.cancel" });
110
+ this.cleanupAudio();
111
+ this.started = false;
112
+ this.scheduleIdleClose();
113
+ }
114
+ close() {
115
+ this.intentionalClose = true;
116
+ this.clearIdleCloseTimer();
117
+ this.cleanupAudio();
118
+ this.closeSocket();
119
+ this.started = false;
120
+ }
121
+ async startInternal() {
122
+ this.clearIdleCloseTimer();
123
+ this.started = true;
124
+ this.asrStarted = false;
125
+ this.pendingAudio = [];
126
+ this.intentionalClose = false;
127
+ try {
128
+ await this.withConnectionTimeout(Promise.all([this.setupAudio(), this.ensureAuthenticatedSocket()]));
129
+ await this.withConnectionTimeout(this.startAsrSession());
130
+ } catch (error) {
131
+ this.cleanupAudio();
132
+ this.started = false;
133
+ this.scheduleIdleClose();
134
+ throw error;
135
+ }
136
+ }
137
+ async withConnectionTimeout(promise) {
138
+ let timeout = null;
139
+ try {
140
+ return await Promise.race([promise, new Promise((_, reject) => {
141
+ timeout = globalThis.setTimeout(() => reject(/* @__PURE__ */ new Error("Voice connection timed out")), this.connectionTimeoutMs);
142
+ })]);
143
+ } finally {
144
+ if (timeout) globalThis.clearTimeout(timeout);
145
+ }
146
+ }
147
+ async ensureAuthenticatedSocket() {
148
+ if (this.socket?.readyState === WEBSOCKET_OPEN && this.authenticated) return;
149
+ await this.ensureSocketOpen();
150
+ if (this.authenticated) return;
151
+ try {
152
+ await this.authenticate(false);
153
+ } catch (error) {
154
+ if (!(error instanceof Error) || error.message !== "UNAUTHORIZED") throw error;
155
+ await this.authenticate(true);
156
+ }
157
+ }
158
+ async ensureSocketOpen() {
159
+ if (this.socket?.readyState === WEBSOCKET_OPEN) return;
160
+ if (this.socketOpenPromise) return this.socketOpenPromise;
161
+ this.authenticated = false;
162
+ this.intentionalClose = false;
163
+ this.socket = new this.WebSocketImpl(this.url);
164
+ this.socketOpenPromise = new Promise((resolve, reject) => {
165
+ const socket = this.socket;
166
+ if (!socket) return reject(/* @__PURE__ */ new Error("Voice service unavailable"));
167
+ socket.onopen = () => resolve();
168
+ socket.onerror = () => reject(/* @__PURE__ */ new Error("Voice service unavailable"));
169
+ socket.onclose = (event) => {
170
+ this.authenticated = false;
171
+ this.socketOpenPromise = null;
172
+ this.rejectAuthWaiter(/* @__PURE__ */ new Error("Voice connection closed"));
173
+ this.rejectAsrStartWaiter(/* @__PURE__ */ new Error("Voice connection closed"));
174
+ if (this.socket === socket) this.socket = null;
175
+ if (!this.intentionalClose && this.started) {
176
+ this.cleanupAudio();
177
+ this.started = false;
178
+ this.callbacks.onError?.("Voice connection closed. Try again.");
179
+ this.callbacks.onDone?.();
180
+ }
181
+ if (socket.readyState !== WEBSOCKET_OPEN) reject(new Error(event.reason || "Voice connection closed"));
182
+ };
183
+ socket.onmessage = (event) => {
184
+ try {
185
+ this.handleMessage(event);
186
+ } catch {
187
+ this.closeWithError("Voice service sent invalid data. Try again.");
188
+ }
189
+ };
190
+ }).finally(() => {
191
+ this.socketOpenPromise = null;
192
+ });
193
+ return this.socketOpenPromise;
194
+ }
195
+ async authenticate(forceRefresh) {
196
+ const token = await this.getAccessToken?.({ forceRefresh });
197
+ if (!token) throw new Error("Sign in to use voice input");
198
+ const waiter = this.createAuthWaiter();
199
+ this.send({
200
+ type: "auth",
201
+ payload: { token }
202
+ });
203
+ await waiter.promise;
204
+ }
205
+ async startAsrSession() {
206
+ const waiter = this.createAsrStartWaiter();
207
+ this.send({ type: "asr.start" });
208
+ await waiter.promise;
209
+ }
210
+ createAuthWaiter() {
211
+ this.rejectAuthWaiter(/* @__PURE__ */ new Error("superseded auth waiter"));
212
+ let resolve;
213
+ let reject;
214
+ const promise = new Promise((res, rej) => {
215
+ resolve = res;
216
+ reject = rej;
217
+ });
218
+ this.authWaiter = {
219
+ promise,
220
+ resolve,
221
+ reject
222
+ };
223
+ return this.authWaiter;
224
+ }
225
+ resolveAuthWaiter() {
226
+ if (!this.authWaiter) return;
227
+ this.authWaiter.resolve();
228
+ this.authWaiter = null;
229
+ }
230
+ rejectAuthWaiter(error) {
231
+ if (!this.authWaiter) return;
232
+ this.authWaiter.reject(error);
233
+ this.authWaiter = null;
234
+ }
235
+ createAsrStartWaiter() {
236
+ this.rejectAsrStartWaiter(/* @__PURE__ */ new Error("superseded asr start waiter"));
237
+ let resolve;
238
+ let reject;
239
+ const promise = new Promise((res, rej) => {
240
+ resolve = res;
241
+ reject = rej;
242
+ });
243
+ this.asrStartWaiter = {
244
+ promise,
245
+ resolve,
246
+ reject
247
+ };
248
+ return this.asrStartWaiter;
249
+ }
250
+ resolveAsrStartWaiter() {
251
+ if (!this.asrStartWaiter) return;
252
+ this.asrStartWaiter.resolve();
253
+ this.asrStartWaiter = null;
254
+ }
255
+ rejectAsrStartWaiter(error) {
256
+ if (!this.asrStartWaiter) return;
257
+ this.asrStartWaiter.reject(error);
258
+ this.asrStartWaiter = null;
259
+ }
260
+ closeWithError(message) {
261
+ this.callbacks.onError?.(message);
262
+ this.close();
263
+ this.callbacks.onDone?.();
264
+ }
265
+ async setupAudio() {
266
+ const mediaDevices = globalThis.navigator?.mediaDevices;
267
+ if (!mediaDevices) throw new Error("Microphone input is not available in this environment");
268
+ const AudioContextImpl = getDefaultAudioContext();
269
+ if (!AudioContextImpl) throw new Error("AudioContext is not available in this environment");
270
+ this.stream = await mediaDevices.getUserMedia({ audio: true });
271
+ this.audioContext = new AudioContextImpl();
272
+ await this.audioContext.resume().catch(() => void 0);
273
+ this.source = this.audioContext.createMediaStreamSource(this.stream);
274
+ this.processor = this.audioContext.createScriptProcessor(4096, 1, 1);
275
+ this.processor.onaudioprocess = (event) => {
276
+ const resampled = resampleTo16k(event.inputBuffer.getChannelData(0), this.audioContext?.sampleRate ?? TARGET_SAMPLE_RATE);
277
+ for (const sample of resampled) this.pendingSamples.push(sample);
278
+ while (this.pendingSamples.length >= CHUNK_SAMPLES) {
279
+ const chunk = this.pendingSamples.splice(0, CHUNK_SAMPLES);
280
+ this.sendAudio(new Float32Array(chunk));
281
+ }
282
+ };
283
+ this.source.connect(this.processor);
284
+ this.processor.connect(this.audioContext.destination);
285
+ }
286
+ sendAudio(samples) {
287
+ const audio = encodeBase64(floatToPcm16(samples));
288
+ if (!this.asrStarted) {
289
+ this.pendingAudio.push(audio);
290
+ return;
291
+ }
292
+ this.send({
293
+ type: "asr.audio",
294
+ payload: { audio }
295
+ });
296
+ }
297
+ flushPendingAudio() {
298
+ if (!this.asrStarted) return;
299
+ for (const audio of this.pendingAudio.splice(0)) this.send({
300
+ type: "asr.audio",
301
+ payload: { audio }
302
+ });
303
+ }
304
+ send(message) {
305
+ if (this.socket?.readyState === WEBSOCKET_OPEN) this.socket.send(JSON.stringify(message));
306
+ }
307
+ handleMessage(event) {
308
+ const data = JSON.parse(String(event.data));
309
+ const text = typeof data.payload?.text === "string" ? data.payload.text : "";
310
+ if (data.type === "system.auth.ok") {
311
+ this.authenticated = true;
312
+ this.resolveAuthWaiter();
313
+ return data;
314
+ }
315
+ if (data.type === "asr.started") {
316
+ this.asrStarted = true;
317
+ this.flushPendingAudio();
318
+ this.resolveAsrStartWaiter();
319
+ return data;
320
+ }
321
+ if (data.type === "asr.error") {
322
+ const message = getErrorMessage(data);
323
+ if (getErrorCode(data) === "UNAUTHORIZED") {
324
+ this.authenticated = false;
325
+ this.rejectAuthWaiter(/* @__PURE__ */ new Error("UNAUTHORIZED"));
326
+ }
327
+ this.rejectAsrStartWaiter(new Error(message));
328
+ this.callbacks.onError?.(message);
329
+ return data;
330
+ }
331
+ if (data.type === "asr.partial") this.callbacks.onPartial?.(text);
332
+ if (data.type === "asr.final") this.callbacks.onFinal?.(text);
333
+ if (data.type === "asr.done") {
334
+ this.asrStarted = false;
335
+ this.started = false;
336
+ this.scheduleIdleClose();
337
+ this.callbacks.onDone?.();
338
+ }
339
+ return data;
340
+ }
341
+ cleanupAudio() {
342
+ this.processor?.disconnect();
343
+ if (this.processor) this.processor.onaudioprocess = null;
344
+ this.source?.disconnect();
345
+ this.stream?.getTracks().forEach((track) => {
346
+ track.stop();
347
+ });
348
+ this.audioContext?.close().catch(() => void 0);
349
+ this.processor = null;
350
+ this.source = null;
351
+ this.stream = null;
352
+ this.audioContext = null;
353
+ this.pendingSamples = [];
354
+ this.pendingAudio = [];
355
+ this.asrStarted = false;
356
+ }
357
+ scheduleIdleClose() {
358
+ this.clearIdleCloseTimer();
359
+ if (!this.socket || this.idleConnectionTimeoutMs <= 0) return;
360
+ this.idleCloseTimer = globalThis.setTimeout(() => {
361
+ this.intentionalClose = true;
362
+ this.closeSocket();
363
+ }, this.idleConnectionTimeoutMs);
364
+ }
365
+ clearIdleCloseTimer() {
366
+ if (!this.idleCloseTimer) return;
367
+ globalThis.clearTimeout(this.idleCloseTimer);
368
+ this.idleCloseTimer = null;
369
+ }
370
+ closeSocket() {
371
+ this.rejectAuthWaiter(/* @__PURE__ */ new Error("Voice connection closed"));
372
+ this.rejectAsrStartWaiter(/* @__PURE__ */ new Error("Voice connection closed"));
373
+ this.authenticated = false;
374
+ this.socketOpenPromise = null;
375
+ this.socket?.close();
376
+ this.socket = null;
377
+ }
378
+ };
379
+ var VoiceApi = class {
380
+ defaults;
381
+ constructor(defaults = {}) {
382
+ this.defaults = defaults;
383
+ }
384
+ createInputClient(callbacks = {}, options = {}) {
385
+ return new VoiceInputClient({
386
+ ...this.defaults,
387
+ ...options,
388
+ callbacks
389
+ });
390
+ }
391
+ };
392
+ const createVoiceInputClient = (options) => new VoiceInputClient(options);
393
+ //#endregion
394
+ export { VoiceApi, VoiceInputClient, createVoiceInputClient };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "Cohub SDK for spaces, sessions, checkpoints, and realtime agent collaboration.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -37,6 +37,10 @@
37
37
  "types": "./dist/websocket.d.ts",
38
38
  "import": "./dist/websocket.js"
39
39
  },
40
+ "./voice-input": {
41
+ "types": "./dist/voice-input.d.ts",
42
+ "import": "./dist/voice-input.js"
43
+ },
40
44
  "./debugger": {
41
45
  "types": "./dist/debugger.d.ts",
42
46
  "import": "./dist/debugger.js"