@kernl-sdk/protocol 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +19 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +7 -0
- package/dist/realtime/model.d.ts +21 -11
- package/dist/realtime/model.d.ts.map +1 -1
- package/dist/realtime/types.d.ts +98 -13
- package/dist/realtime/types.d.ts.map +1 -1
- package/dist/realtime/types.js +13 -1
- package/package.json +2 -2
- package/src/constants.ts +9 -0
- package/src/realtime/model.ts +32 -16
- package/src/realtime/types.ts +120 -15
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @kernl/protocol
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f593374: Add realtime voice agents with multi-provider support.
|
|
8
|
+
- `RealtimeAgent` and `RealtimeSession` for voice-enabled AI agents
|
|
9
|
+
- OpenAI GPT-4o realtime with WebSocket streaming
|
|
10
|
+
- xAI Grok realtime with OpenAI-compatible protocol
|
|
11
|
+
- React hooks: `useRealtime`, `useBrowserAudio`, `LiveWaveform`
|
|
12
|
+
- Ephemeral credential pattern for secure browser connections
|
|
13
|
+
- Tool execution with client-side context support
|
|
14
|
+
|
|
15
|
+
## 0.3.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [25e46e7]
|
|
20
|
+
- @kernl-sdk/shared@0.3.1
|
|
21
|
+
|
|
3
22
|
## 0.3.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/dist/constants.d.ts
CHANGED
|
@@ -58,4 +58,8 @@ export declare const ZOMBIE = "zombie";
|
|
|
58
58
|
* Final cleanup in progress, about to be fully deleted.
|
|
59
59
|
*/
|
|
60
60
|
export declare const DEAD = "dead";
|
|
61
|
+
export declare const WS_CONNECTING = 0;
|
|
62
|
+
export declare const WS_OPEN = 1;
|
|
63
|
+
export declare const WS_CLOSING = 2;
|
|
64
|
+
export declare const WS_CLOSED = 3;
|
|
61
65
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,MAAM,WAAW,CAAC;AAM/B;;;;GAIG;AACH,eAAO,MAAM,OAAO,YAAY,CAAC;AAEjC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,YAAY,CAAC;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,WAAW,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,IAAI,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,MAAM,WAAW,CAAC;AAM/B;;;;GAIG;AACH,eAAO,MAAM,OAAO,YAAY,CAAC;AAEjC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,YAAY,CAAC;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,WAAW,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,IAAI,SAAS,CAAC;AAM3B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,SAAS,IAAI,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -64,3 +64,10 @@ export const ZOMBIE = "zombie";
|
|
|
64
64
|
* Final cleanup in progress, about to be fully deleted.
|
|
65
65
|
*/
|
|
66
66
|
export const DEAD = "dead";
|
|
67
|
+
// ----------------------------
|
|
68
|
+
// WebSocket ready states
|
|
69
|
+
// ----------------------------
|
|
70
|
+
export const WS_CONNECTING = 0;
|
|
71
|
+
export const WS_OPEN = 1;
|
|
72
|
+
export const WS_CLOSING = 2;
|
|
73
|
+
export const WS_CLOSED = 3;
|
package/dist/realtime/model.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
import { TypedEmitter } from "@kernl-sdk/shared";
|
|
1
2
|
import { SharedProviderMetadata } from "../provider/index.js";
|
|
2
3
|
import { RealtimeClientEvent, RealtimeServerEvent } from "./events.js";
|
|
3
|
-
import { RealtimeConnectOptions, TransportStatus } from "./types.js";
|
|
4
|
+
import { RealtimeConnectOptions, RealtimeAuthenticateOptions, TransportStatus, ClientCredential } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Events emitted by a realtime connection.
|
|
7
|
+
*/
|
|
8
|
+
export type RealtimeConnectionEvents = {
|
|
9
|
+
event: [event: RealtimeServerEvent];
|
|
10
|
+
status: [status: TransportStatus];
|
|
11
|
+
error: [error: Error];
|
|
12
|
+
interrupted: [];
|
|
13
|
+
};
|
|
4
14
|
/**
|
|
5
15
|
* A realtime model that can establish bidirectional streaming connections.
|
|
6
16
|
*
|
|
@@ -24,13 +34,22 @@ export interface RealtimeModel {
|
|
|
24
34
|
* Establish a connection and return a connection instance.
|
|
25
35
|
*/
|
|
26
36
|
connect(options?: RealtimeConnectOptions): Promise<RealtimeConnection>;
|
|
37
|
+
/**
|
|
38
|
+
* Create ephemeral credential for client-side connections.
|
|
39
|
+
*
|
|
40
|
+
* Call server-side where API key is available, pass result to client.
|
|
41
|
+
* Client then uses credential in connect() options.
|
|
42
|
+
*
|
|
43
|
+
* @param options - Provider-specific options (e.g., agentId for ElevenLabs)
|
|
44
|
+
*/
|
|
45
|
+
authenticate(options?: RealtimeAuthenticateOptions): Promise<ClientCredential>;
|
|
27
46
|
}
|
|
28
47
|
/**
|
|
29
48
|
* An active bidirectional connection to a realtime model.
|
|
30
49
|
*
|
|
31
50
|
* One connection per session. Providers implement this interface.
|
|
32
51
|
*/
|
|
33
|
-
export interface RealtimeConnection {
|
|
52
|
+
export interface RealtimeConnection extends TypedEmitter<RealtimeConnectionEvents> {
|
|
34
53
|
/**
|
|
35
54
|
* Current connection status.
|
|
36
55
|
*/
|
|
@@ -69,15 +88,6 @@ export interface RealtimeConnection {
|
|
|
69
88
|
* Convenience for sending response.cancel event.
|
|
70
89
|
*/
|
|
71
90
|
interrupt(): void;
|
|
72
|
-
on(event: "event", listener: (event: RealtimeServerEvent) => void): this;
|
|
73
|
-
on(event: "status", listener: (status: TransportStatus) => void): this;
|
|
74
|
-
on(event: "error", listener: (error: Error) => void): this;
|
|
75
|
-
off(event: "event", listener: (event: RealtimeServerEvent) => void): this;
|
|
76
|
-
off(event: "status", listener: (status: TransportStatus) => void): this;
|
|
77
|
-
off(event: "error", listener: (error: Error) => void): this;
|
|
78
|
-
once(event: "event", listener: (event: RealtimeServerEvent) => void): this;
|
|
79
|
-
once(event: "status", listener: (status: TransportStatus) => void): this;
|
|
80
|
-
once(event: "error", listener: (error: Error) => void): this;
|
|
81
91
|
}
|
|
82
92
|
/**
|
|
83
93
|
* A transport factory for custom connection mechanisms (e.g., WebRTC).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/realtime/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/realtime/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,eAAe,EACf,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IACpC,MAAM,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtB,WAAW,EAAE,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEvE;;;;;;;OAOG;IACH,YAAY,CACV,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,kBACf,SAAQ,YAAY,CAAC,wBAAwB,CAAC;IAC9C;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAE/B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAEnD;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAEvC;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;OAEG;IACH,MAAM,IAAI,IAAI,CAAC;IAEf;;;OAGG;IACH,SAAS,IAAI,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,OAAO,CACL,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAChC"}
|
package/dist/realtime/types.d.ts
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
|
+
import { TypedEmitter } from "@kernl-sdk/shared";
|
|
1
2
|
import { SharedProviderOptions } from "../provider/index.js";
|
|
2
3
|
import { LanguageModelTool } from "../language-model/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Events emitted by a realtime channel.
|
|
6
|
+
*/
|
|
7
|
+
export type RealtimeChannelEvents = {
|
|
8
|
+
audio: [audio: string];
|
|
9
|
+
commit: [];
|
|
10
|
+
interrupt: [];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Base interface for audio I/O channels.
|
|
14
|
+
*
|
|
15
|
+
* Channels bridge between audio sources (browser mic, Twilio, Discord)
|
|
16
|
+
* and the realtime session. They handle audio capture/playback and emit
|
|
17
|
+
* events that the session listens to.
|
|
18
|
+
*/
|
|
19
|
+
export interface RealtimeChannel extends TypedEmitter<RealtimeChannelEvents> {
|
|
20
|
+
/**
|
|
21
|
+
* Send audio to be played/transmitted by the channel.
|
|
22
|
+
* Called by session when audio is received from the model.
|
|
23
|
+
*/
|
|
24
|
+
sendAudio(audio: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Interrupt current audio playback.
|
|
27
|
+
* Called by session when response is cancelled.
|
|
28
|
+
*/
|
|
29
|
+
interrupt(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Clean up resources and close the channel.
|
|
32
|
+
*/
|
|
33
|
+
close(): void;
|
|
34
|
+
}
|
|
3
35
|
export interface RealtimeConnectOptions {
|
|
4
36
|
/**
|
|
5
37
|
* Initial session configuration.
|
|
@@ -17,6 +49,51 @@ export interface RealtimeConnectOptions {
|
|
|
17
49
|
* Provider-specific options.
|
|
18
50
|
*/
|
|
19
51
|
providerOptions?: SharedProviderOptions;
|
|
52
|
+
/**
|
|
53
|
+
* Ephemeral credential for client-side connections.
|
|
54
|
+
*
|
|
55
|
+
* Obtained from model.authenticate() on the server.
|
|
56
|
+
* When provided, used instead of the model's API key.
|
|
57
|
+
*/
|
|
58
|
+
credential?: ClientCredential;
|
|
59
|
+
/**
|
|
60
|
+
* WebSocket constructor for browser/Node compatibility.
|
|
61
|
+
*
|
|
62
|
+
* Defaults to globalThis.WebSocket (available in browsers and Node 22+).
|
|
63
|
+
* For Node.js <22, provide the 'ws' package.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* import WebSocket from 'ws';
|
|
68
|
+
* await model.connect({ websocket: WebSocket });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
websocket?: WebSocketConstructor;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Options for authenticating with a realtime provider.
|
|
75
|
+
*
|
|
76
|
+
* Provider-specific options can be added via extension.
|
|
77
|
+
*/
|
|
78
|
+
export interface RealtimeAuthenticateOptions {
|
|
79
|
+
/**
|
|
80
|
+
* Agent ID for providers that use pre-configured agents (e.g., ElevenLabs).
|
|
81
|
+
*/
|
|
82
|
+
agentId?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* WebSocket constructor type for cross-platform compatibility.
|
|
86
|
+
*/
|
|
87
|
+
export type WebSocketConstructor = new (url: string | URL, protocols?: string | string[]) => WebSocketLike;
|
|
88
|
+
/**
|
|
89
|
+
* Minimal WebSocket interface matching the standard WebSocket API.
|
|
90
|
+
*/
|
|
91
|
+
export interface WebSocketLike {
|
|
92
|
+
readonly readyState: number;
|
|
93
|
+
send(data: string | ArrayBuffer): void;
|
|
94
|
+
close(code?: number, reason?: string): void;
|
|
95
|
+
addEventListener(type: string, listener: (event: unknown) => void): void;
|
|
96
|
+
removeEventListener(type: string, listener: (event: unknown) => void): void;
|
|
20
97
|
}
|
|
21
98
|
/**
|
|
22
99
|
* Configuration for a realtime session.
|
|
@@ -187,19 +264,10 @@ export interface RealtimeSession {
|
|
|
187
264
|
/**
|
|
188
265
|
* Error from a realtime session.
|
|
189
266
|
*/
|
|
190
|
-
export
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
code: string;
|
|
195
|
-
/**
|
|
196
|
-
* Human-readable error message.
|
|
197
|
-
*/
|
|
198
|
-
message: string;
|
|
199
|
-
/**
|
|
200
|
-
* Additional error details.
|
|
201
|
-
*/
|
|
202
|
-
details?: Record<string, unknown>;
|
|
267
|
+
export declare class RealtimeError extends Error {
|
|
268
|
+
readonly code: string;
|
|
269
|
+
readonly details?: Record<string, unknown>;
|
|
270
|
+
constructor(code: string, message: string, details?: Record<string, unknown>);
|
|
203
271
|
}
|
|
204
272
|
/**
|
|
205
273
|
* Token usage information for a response.
|
|
@@ -226,4 +294,21 @@ export type ResponseStatus = "completed" | "interrupted" | "cancelled" | "failed
|
|
|
226
294
|
* Status of a realtime transport connection.
|
|
227
295
|
*/
|
|
228
296
|
export type TransportStatus = "disconnected" | "connecting" | "connected" | "reconnecting" | "closed";
|
|
297
|
+
/**
|
|
298
|
+
* A client credential for browser-based realtime connections.
|
|
299
|
+
*
|
|
300
|
+
* Created server-side via model.authenticate(), passed to client
|
|
301
|
+
* for secure connection without exposing API keys.
|
|
302
|
+
*/
|
|
303
|
+
export type ClientCredential = {
|
|
304
|
+
/** Ephemeral token for auth header (OpenAI style). */
|
|
305
|
+
readonly kind: "token";
|
|
306
|
+
token: string;
|
|
307
|
+
expiresAt: Date;
|
|
308
|
+
} | {
|
|
309
|
+
/** Signed URL to connect directly (ElevenLabs style). */
|
|
310
|
+
readonly kind: "url";
|
|
311
|
+
url: string;
|
|
312
|
+
expiresAt: Date;
|
|
313
|
+
};
|
|
229
314
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/realtime/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAC;IAEtC;;OAEG;IACH,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAE7B;;OAEG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;IAEpB;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/realtime/types.ts"],"names":[],"mappings":"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"}
|
package/dist/realtime/types.js
CHANGED
|
@@ -1 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Error from a realtime session.
|
|
3
|
+
*/
|
|
4
|
+
export class RealtimeError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
details;
|
|
7
|
+
constructor(code, message, details) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "RealtimeError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.details = details;
|
|
12
|
+
}
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kernl-sdk/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Protocol specification for kernl",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kernl",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@kernl-sdk/shared": "0.3.
|
|
33
|
+
"@kernl-sdk/shared": "0.3.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/json-schema": "^7.0.15",
|
package/src/constants.ts
CHANGED
|
@@ -73,3 +73,12 @@ export const ZOMBIE = "zombie";
|
|
|
73
73
|
* Final cleanup in progress, about to be fully deleted.
|
|
74
74
|
*/
|
|
75
75
|
export const DEAD = "dead";
|
|
76
|
+
|
|
77
|
+
// ----------------------------
|
|
78
|
+
// WebSocket ready states
|
|
79
|
+
// ----------------------------
|
|
80
|
+
|
|
81
|
+
export const WS_CONNECTING = 0;
|
|
82
|
+
export const WS_OPEN = 1;
|
|
83
|
+
export const WS_CLOSING = 2;
|
|
84
|
+
export const WS_CLOSED = 3;
|
package/src/realtime/model.ts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
import { TypedEmitter } from "@kernl-sdk/shared";
|
|
2
|
+
|
|
1
3
|
import { SharedProviderMetadata } from "@/provider";
|
|
2
4
|
import { RealtimeClientEvent, RealtimeServerEvent } from "./events";
|
|
3
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
RealtimeConnectOptions,
|
|
7
|
+
RealtimeAuthenticateOptions,
|
|
8
|
+
TransportStatus,
|
|
9
|
+
ClientCredential,
|
|
10
|
+
} from "./types";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Events emitted by a realtime connection.
|
|
14
|
+
*/
|
|
15
|
+
export type RealtimeConnectionEvents = {
|
|
16
|
+
event: [event: RealtimeServerEvent];
|
|
17
|
+
status: [status: TransportStatus];
|
|
18
|
+
error: [error: Error];
|
|
19
|
+
interrupted: [];
|
|
20
|
+
};
|
|
4
21
|
|
|
5
22
|
/**
|
|
6
23
|
* A realtime model that can establish bidirectional streaming connections.
|
|
@@ -28,6 +45,18 @@ export interface RealtimeModel {
|
|
|
28
45
|
* Establish a connection and return a connection instance.
|
|
29
46
|
*/
|
|
30
47
|
connect(options?: RealtimeConnectOptions): Promise<RealtimeConnection>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Create ephemeral credential for client-side connections.
|
|
51
|
+
*
|
|
52
|
+
* Call server-side where API key is available, pass result to client.
|
|
53
|
+
* Client then uses credential in connect() options.
|
|
54
|
+
*
|
|
55
|
+
* @param options - Provider-specific options (e.g., agentId for ElevenLabs)
|
|
56
|
+
*/
|
|
57
|
+
authenticate(
|
|
58
|
+
options?: RealtimeAuthenticateOptions,
|
|
59
|
+
): Promise<ClientCredential>;
|
|
31
60
|
}
|
|
32
61
|
|
|
33
62
|
/**
|
|
@@ -35,7 +64,8 @@ export interface RealtimeModel {
|
|
|
35
64
|
*
|
|
36
65
|
* One connection per session. Providers implement this interface.
|
|
37
66
|
*/
|
|
38
|
-
export interface RealtimeConnection
|
|
67
|
+
export interface RealtimeConnection
|
|
68
|
+
extends TypedEmitter<RealtimeConnectionEvents> {
|
|
39
69
|
/**
|
|
40
70
|
* Current connection status.
|
|
41
71
|
*/
|
|
@@ -82,20 +112,6 @@ export interface RealtimeConnection {
|
|
|
82
112
|
* Convenience for sending response.cancel event.
|
|
83
113
|
*/
|
|
84
114
|
interrupt(): void;
|
|
85
|
-
|
|
86
|
-
// --- event subscription ---
|
|
87
|
-
|
|
88
|
-
on(event: "event", listener: (event: RealtimeServerEvent) => void): this;
|
|
89
|
-
on(event: "status", listener: (status: TransportStatus) => void): this;
|
|
90
|
-
on(event: "error", listener: (error: Error) => void): this;
|
|
91
|
-
|
|
92
|
-
off(event: "event", listener: (event: RealtimeServerEvent) => void): this;
|
|
93
|
-
off(event: "status", listener: (status: TransportStatus) => void): this;
|
|
94
|
-
off(event: "error", listener: (error: Error) => void): this;
|
|
95
|
-
|
|
96
|
-
once(event: "event", listener: (event: RealtimeServerEvent) => void): this;
|
|
97
|
-
once(event: "status", listener: (status: TransportStatus) => void): this;
|
|
98
|
-
once(event: "error", listener: (error: Error) => void): this;
|
|
99
115
|
}
|
|
100
116
|
|
|
101
117
|
/**
|
package/src/realtime/types.ts
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
|
+
import { TypedEmitter } from "@kernl-sdk/shared";
|
|
1
2
|
import { SharedProviderOptions } from "@/provider";
|
|
2
3
|
import { LanguageModelTool } from "@/language-model";
|
|
3
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Events emitted by a realtime channel.
|
|
7
|
+
*/
|
|
8
|
+
export type RealtimeChannelEvents = {
|
|
9
|
+
audio: [audio: string];
|
|
10
|
+
commit: [];
|
|
11
|
+
interrupt: [];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Base interface for audio I/O channels.
|
|
16
|
+
*
|
|
17
|
+
* Channels bridge between audio sources (browser mic, Twilio, Discord)
|
|
18
|
+
* and the realtime session. They handle audio capture/playback and emit
|
|
19
|
+
* events that the session listens to.
|
|
20
|
+
*/
|
|
21
|
+
export interface RealtimeChannel extends TypedEmitter<RealtimeChannelEvents> {
|
|
22
|
+
/**
|
|
23
|
+
* Send audio to be played/transmitted by the channel.
|
|
24
|
+
* Called by session when audio is received from the model.
|
|
25
|
+
*/
|
|
26
|
+
sendAudio(audio: string): void;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Interrupt current audio playback.
|
|
30
|
+
* Called by session when response is cancelled.
|
|
31
|
+
*/
|
|
32
|
+
interrupt(): void;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Clean up resources and close the channel.
|
|
36
|
+
*/
|
|
37
|
+
close(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
4
40
|
export interface RealtimeConnectOptions {
|
|
5
41
|
/**
|
|
6
42
|
* Initial session configuration.
|
|
@@ -21,6 +57,59 @@ export interface RealtimeConnectOptions {
|
|
|
21
57
|
* Provider-specific options.
|
|
22
58
|
*/
|
|
23
59
|
providerOptions?: SharedProviderOptions;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Ephemeral credential for client-side connections.
|
|
63
|
+
*
|
|
64
|
+
* Obtained from model.authenticate() on the server.
|
|
65
|
+
* When provided, used instead of the model's API key.
|
|
66
|
+
*/
|
|
67
|
+
credential?: ClientCredential;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* WebSocket constructor for browser/Node compatibility.
|
|
71
|
+
*
|
|
72
|
+
* Defaults to globalThis.WebSocket (available in browsers and Node 22+).
|
|
73
|
+
* For Node.js <22, provide the 'ws' package.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* import WebSocket from 'ws';
|
|
78
|
+
* await model.connect({ websocket: WebSocket });
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
websocket?: WebSocketConstructor;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Options for authenticating with a realtime provider.
|
|
86
|
+
*
|
|
87
|
+
* Provider-specific options can be added via extension.
|
|
88
|
+
*/
|
|
89
|
+
export interface RealtimeAuthenticateOptions {
|
|
90
|
+
/**
|
|
91
|
+
* Agent ID for providers that use pre-configured agents (e.g., ElevenLabs).
|
|
92
|
+
*/
|
|
93
|
+
agentId?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* WebSocket constructor type for cross-platform compatibility.
|
|
98
|
+
*/
|
|
99
|
+
export type WebSocketConstructor = new (
|
|
100
|
+
url: string | URL,
|
|
101
|
+
protocols?: string | string[],
|
|
102
|
+
) => WebSocketLike;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Minimal WebSocket interface matching the standard WebSocket API.
|
|
106
|
+
*/
|
|
107
|
+
export interface WebSocketLike {
|
|
108
|
+
readonly readyState: number;
|
|
109
|
+
send(data: string | ArrayBuffer): void;
|
|
110
|
+
close(code?: number, reason?: string): void;
|
|
111
|
+
addEventListener(type: string, listener: (event: unknown) => void): void;
|
|
112
|
+
removeEventListener(type: string, listener: (event: unknown) => void): void;
|
|
24
113
|
}
|
|
25
114
|
|
|
26
115
|
/**
|
|
@@ -219,21 +308,16 @@ export interface RealtimeSession {
|
|
|
219
308
|
/**
|
|
220
309
|
* Error from a realtime session.
|
|
221
310
|
*/
|
|
222
|
-
export
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
code: string
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Additional error details.
|
|
235
|
-
*/
|
|
236
|
-
details?: Record<string, unknown>;
|
|
311
|
+
export class RealtimeError extends Error {
|
|
312
|
+
readonly code: string;
|
|
313
|
+
readonly details?: Record<string, unknown>;
|
|
314
|
+
|
|
315
|
+
constructor(code: string, message: string, details?: Record<string, unknown>) {
|
|
316
|
+
super(message);
|
|
317
|
+
this.name = "RealtimeError";
|
|
318
|
+
this.code = code;
|
|
319
|
+
this.details = details;
|
|
320
|
+
}
|
|
237
321
|
}
|
|
238
322
|
|
|
239
323
|
/**
|
|
@@ -274,3 +358,24 @@ export type TransportStatus =
|
|
|
274
358
|
| "connected"
|
|
275
359
|
| "reconnecting"
|
|
276
360
|
| "closed";
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* A client credential for browser-based realtime connections.
|
|
364
|
+
*
|
|
365
|
+
* Created server-side via model.authenticate(), passed to client
|
|
366
|
+
* for secure connection without exposing API keys.
|
|
367
|
+
*/
|
|
368
|
+
export type ClientCredential =
|
|
369
|
+
| {
|
|
370
|
+
/** Ephemeral token for auth header (OpenAI style). */
|
|
371
|
+
readonly kind: "token";
|
|
372
|
+
token: string;
|
|
373
|
+
expiresAt: Date;
|
|
374
|
+
}
|
|
375
|
+
| {
|
|
376
|
+
/** Signed URL to connect directly (ElevenLabs style). */
|
|
377
|
+
readonly kind: "url";
|
|
378
|
+
url: string;
|
|
379
|
+
expiresAt: Date;
|
|
380
|
+
};
|
|
381
|
+
|