@relaymessenger/livekit 0.1.0-staging.3 → 0.1.0-staging.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -95
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/livekit.d.ts +39 -5
- package/dist/livekit.d.ts.map +1 -1
- package/dist/livekit.js +59 -9
- package/dist/livekit.js.map +1 -1
- package/package.json +7 -9
- package/dist/engine-werift.d.ts +0 -19
- package/dist/engine-werift.d.ts.map +0 -1
- package/dist/engine-werift.js +0 -309
- package/dist/engine-werift.js.map +0 -1
- package/dist/transport.d.ts +0 -170
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -705
- package/dist/transport.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# `@relaymessenger/livekit`
|
|
2
2
|
|
|
3
3
|
`@relaymessenger/livekit` connects Relay Calls to TypeScript LiveKit Agents.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
objects.
|
|
7
|
-
credentials.
|
|
4
|
+
It translates audio between the Relay SDK's call transport
|
|
5
|
+
(`RelayCallTransport` from `@relaymessenger/sdk/calls`) and LiveKit
|
|
6
|
+
`AudioFrame` objects. The transport owns the Node WebRTC peer, so application
|
|
7
|
+
code does not handle Cloudflare, SDP, ICE, or SFU credentials.
|
|
8
8
|
|
|
9
9
|
Install it next to the Relay SDK and the LiveKit Agents runtime:
|
|
10
10
|
|
|
@@ -39,105 +39,30 @@ async function answerCall(callId: string, session: AgentSession) {
|
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
`RelayLiveKitCall.connect()` does not resolve until the WebRTC media peer has
|
|
42
|
-
reached `connected`. `RelayAudioInput`
|
|
43
|
-
audio
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`
|
|
42
|
+
reached `connected`. `RelayAudioInput` hands the AgentSession the remote
|
|
43
|
+
participant's audio as 24 kHz mono PCM16 frames, the format of LiveKit's own
|
|
44
|
+
room input; the Opus decoder produces that format directly.
|
|
45
|
+
|
|
46
|
+
`RelayAudioOutput` has the shape of LiveKit's own `ParticipantAudioOutput`.
|
|
47
|
+
Like LiveKit's, it waits until the person is receiving the agent's audio: the
|
|
48
|
+
transport holds each frame until then, so a greeting that starts early is not
|
|
49
|
+
cut, sends silence meanwhile, and skips nothing. Then `captureFrame()` hands each
|
|
50
|
+
frame to the transport and returns at once, so the
|
|
47
51
|
AgentSession may push a whole reply faster than real time; the engine's 20 ms
|
|
48
52
|
pump paces the wire. `flush()` closes the segment and reports
|
|
49
53
|
`playbackFinished` only after the transport has drained. `clearBuffer()` drops
|
|
50
54
|
audio that has not reached the wire and reports the segment as interrupted at
|
|
51
55
|
the position that actually played.
|
|
52
56
|
|
|
53
|
-
On the transport, `writeAudio()` resolves once its 10 ms slices are queued,
|
|
54
|
-
`queuedAudioMs()` is what has not left yet, and `waitForPlayout()` resolves when
|
|
55
|
-
the queue is empty and the pump is idle (early on `clearAudio()`).
|
|
56
|
-
|
|
57
57
|
Use `setMuted(true)` to publish participant mute state, `end()` to end the Relay
|
|
58
58
|
Call, and `close()` for local cleanup. If the signaling connection is replaced,
|
|
59
59
|
`call.transport.reconnect()` keeps the existing media peer and replays the same
|
|
60
60
|
audio publication so Relay can return its cached answer.
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const room = relay.calls.room(callId);
|
|
71
|
-
const transport = new RelayCallTransport({ room });
|
|
72
|
-
|
|
73
|
-
transport.on("audio", ({ samples, sampleRate, channelCount }) => {
|
|
74
|
-
// Interleaved signed PCM16 from the remote Relay participant.
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
await transport.connect();
|
|
78
|
-
await transport.writeAudio({
|
|
79
|
-
samples,
|
|
80
|
-
sampleRate: 48_000,
|
|
81
|
-
channelCount: 1,
|
|
82
|
-
});
|
|
83
|
-
await transport.waitForPlayout();
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## ICE servers, TURN, and diagnostics
|
|
87
|
-
|
|
88
|
-
By default the peer gathers host candidates only and Cloudflare's SFU supplies
|
|
89
|
-
its own candidates in the answer. Inside a container or behind a firewall that
|
|
90
|
-
blocks outbound UDP, pass TURN servers in the standard `RTCIceServer` shape and,
|
|
91
|
-
if every path must go through TURN, `iceTransportPolicy: "relay"`. Both options
|
|
92
|
-
are accepted by `RelayLiveKitCall.connect()` and `RelayCallTransport`.
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
const call = await RelayLiveKitCall.connect({
|
|
96
|
-
relay,
|
|
97
|
-
callId,
|
|
98
|
-
iceServers: [
|
|
99
|
-
{
|
|
100
|
-
urls: [
|
|
101
|
-
"turn:turn.cloudflare.com:3478?transport=udp",
|
|
102
|
-
"turn:turn.cloudflare.com:3478?transport=tcp",
|
|
103
|
-
"turns:turn.cloudflare.com:5349?transport=tcp",
|
|
104
|
-
],
|
|
105
|
-
username: process.env.TURN_USERNAME!,
|
|
106
|
-
credential: process.env.TURN_CREDENTIAL!,
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
iceTransportPolicy: "all",
|
|
110
|
-
mediaConnectTimeoutMs: 15_000,
|
|
111
|
-
});
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
`mediaConnectTimeoutMs` bounds the wait for the media peer to reach
|
|
115
|
-
`connected` (15 seconds by default). When that wait expires, the error message
|
|
116
|
-
carries what ICE saw, for example
|
|
117
|
-
`Timed out connecting Relay WebRTC media (local: host 2, srflx 0, relay 0; remote: udp 1473; states: new→complete 0.2s, connecting 0.3s, no connected)`.
|
|
118
|
-
The same facts are available at any time from `call.diagnostics()` or
|
|
119
|
-
`transport.diagnostics()`: local candidate counts by type, the remote
|
|
120
|
-
candidates' transport and port (never their address), the ICE gathering, ICE
|
|
121
|
-
connection and peer connection state changes with their offsets from
|
|
122
|
-
`connect()`, packet counts in both directions (`inbound`: RTP received, Opus
|
|
123
|
-
decode failures, PCM frames delivered, first and last packet offsets, packets
|
|
124
|
-
in the last 5 s; `outbound`: PCM frames accepted, Opus packets, RTP written,
|
|
125
|
-
first and last packet offsets, packets in the last 5 s, paced queue size,
|
|
126
|
-
pacer state), the room frames seen (`roomState` count, pull `offer` count,
|
|
127
|
-
`ended` reason, `error` messages), and the one-line `summary`, for example
|
|
128
|
-
`…; in: 1234 rtp, 0 bad, 1234 frames, first 0.9s last 41.2s, 250/5s; out: 2050 frames, 2050 opus, 2050 rtp, first 1.1s last 41.0s, 250/5s, queue 0, pacer alive; room: 3 roomState, 1 offer`.
|
|
129
|
-
Packet counts come from the `werift` engine; `wrtc` reports zero packets and
|
|
130
|
-
`pacer n/a`.
|
|
131
|
-
|
|
132
|
-
`onWarning` is called once per call, with the summary, when outbound audio is
|
|
133
|
-
queued but no RTP packet has been written for 2 s while media is connected.
|
|
134
|
-
Nothing is restarted; the callback exists so the failing direction is named in
|
|
135
|
-
the agent's logs.
|
|
136
|
-
|
|
137
|
-
`RelayCallTransport` consumes the SDK's `CallRoom`; it does not duplicate the
|
|
138
|
-
room protocol. The default engine is `werift` (pure TypeScript WebRTC) with
|
|
139
|
-
`@evan/opus` (prebuilt Opus, WASM fallback), so no native WebRTC binding is
|
|
140
|
-
loaded. Pass `engine: "wrtc"` to use the optional `@roamhq/wrtc` binding
|
|
141
|
-
instead. The transport boundary remains provider-neutral for additional adapters. `@livekit/agents`
|
|
142
|
-
and `@livekit/rtc-node` are peer dependencies so the host agent process owns
|
|
143
|
-
those runtimes.
|
|
62
|
+
`RelayLiveKitCall.connect()` accepts the transport's `iceServers`,
|
|
63
|
+
`iceTransportPolicy` and `sessionConnectTimeoutMs`; `call.waitForPeerAudio()`
|
|
64
|
+
and `call.diagnostics()` read the transport. Video, ICE servers, restarts and
|
|
65
|
+
diagnostics are documented with the transport in the
|
|
66
|
+
[`@relaymessenger/sdk` README](https://github.com/RelayMessenger/Relay-SDK/tree/main/packages/sdk#join-a-call-as-the-agent).
|
|
67
|
+
`@livekit/agents` and `@livekit/rtc-node` are peer dependencies so the host
|
|
68
|
+
agent process owns those runtimes.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export { RelayAudioInput, RelayAudioOutput, RelayLiveKitCall, createRelayLiveKitAudio, type RelayLiveKitAudio, type RelayLiveKitAudioOptions, type RelayLiveKitConnectOptions, } from "./livekit.js";
|
|
2
|
-
export { RelayCallTransport, RelayCallTransportError, type RelayAudioFrame, type RelayCallEngine, type RelayCallIceDiagnostics, type RelayCallInboundDiagnostics, type RelayCallOutboundDiagnostics, type RelayCallRoomDiagnostics, type RelayCallTransportCloseEvent, type RelayCallTransportOptions, type RelayIceServer, type RelayIceTransportPolicy, } from "./transport.js";
|
|
3
|
-
export { createWeriftWebRTCFactory } from "./engine-werift.js";
|
|
1
|
+
export { RelayAudioInput, RelayAudioOutput, LIVEKIT_ROOM_INPUT_AUDIO, RelayLiveKitCall, createRelayLiveKitAudio, type RelayLiveKitAudio, type RelayLiveKitAudioOptions, type RelayLiveKitConnectOptions, } from "./livekit.js";
|
|
4
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,GAChC,MAAM,cAAc,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,GAChC,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export { RelayAudioInput, RelayAudioOutput, RelayLiveKitCall, createRelayLiveKitAudio, } from "./livekit.js";
|
|
2
|
-
export { RelayCallTransport, RelayCallTransportError, } from "./transport.js";
|
|
3
|
-
export { createWeriftWebRTCFactory } from "./engine-werift.js";
|
|
1
|
+
export { RelayAudioInput, RelayAudioOutput, LIVEKIT_ROOM_INPUT_AUDIO, RelayLiveKitCall, createRelayLiveKitAudio, } from "./livekit.js";
|
|
4
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,GAIxB,MAAM,cAAc,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,gBAAgB,EAChB,uBAAuB,GAIxB,MAAM,cAAc,CAAC"}
|
package/dist/livekit.d.ts
CHANGED
|
@@ -2,7 +2,18 @@ import { AudioInput, AudioOutput, type AgentSession } from "@livekit/agents";
|
|
|
2
2
|
import { AudioFrame } from "@livekit/rtc-node";
|
|
3
3
|
import type Relay from "@relaymessenger/sdk";
|
|
4
4
|
import type { CallRoomOptions } from "@relaymessenger/sdk";
|
|
5
|
-
import { RelayCallTransport, type RelayCallIceDiagnostics, type RelayIceServer, type RelayIceTransportPolicy } from "
|
|
5
|
+
import { RelayCallTransport, type RelayCallIceDiagnostics, type RelayIceServer, type RelayIceServersProvider, type RelayInboundAudioFormat, type RelayIceTransportPolicy } from "@relaymessenger/sdk/calls";
|
|
6
|
+
/**
|
|
7
|
+
* The format LiveKit's own room input hands an AgentSession:
|
|
8
|
+
* `@livekit/agents` dist/voice/room_io/room_io.js:46-48
|
|
9
|
+
* `DEFAULT_ROOM_INPUT_OPTIONS = { audioSampleRate: 24e3, audioNumChannels: 1 }`,
|
|
10
|
+
* passed to the participant `AudioStream` (room_io.js:373-374). Plugins
|
|
11
|
+
* resample assuming the channel count they construct with
|
|
12
|
+
* (`@livekit/agents-plugin-google` 1.9.0 realtime_api.js:1307-1329
|
|
13
|
+
* `new AudioResampler(frame.sampleRate, 16000, 1)`; rtc-node's resampler reads
|
|
14
|
+
* raw bytes and ignores `frame.channels`), so the session must receive mono.
|
|
15
|
+
*/
|
|
16
|
+
export declare const LIVEKIT_ROOM_INPUT_AUDIO: Readonly<RelayInboundAudioFormat>;
|
|
6
17
|
/** LiveKit Agents input backed by the remote Relay participant's WebRTC audio. */
|
|
7
18
|
export declare class RelayAudioInput extends AudioInput {
|
|
8
19
|
#private;
|
|
@@ -23,6 +34,12 @@ export declare class RelayAudioInput extends AudioInput {
|
|
|
23
34
|
export declare class RelayAudioOutput extends AudioOutput {
|
|
24
35
|
#private;
|
|
25
36
|
constructor(transport: RelayCallTransport, sampleRate?: number);
|
|
37
|
+
/**
|
|
38
|
+
* Hands the frame to the transport, which holds it until the person receives
|
|
39
|
+
* the agent's audio (PROTOCOL.md section 6b) and resolves once it is queued,
|
|
40
|
+
* so this waits as LiveKit's room audio output waits for the track's
|
|
41
|
+
* subscription. A frame dropped by `clearBuffer()` meanwhile is not counted.
|
|
42
|
+
*/
|
|
26
43
|
captureFrame(frame: AudioFrame): Promise<void>;
|
|
27
44
|
/** Mark the segment complete; `onPlaybackFinished` fires once the transport has drained. */
|
|
28
45
|
flush(): void;
|
|
@@ -42,14 +59,25 @@ export interface RelayLiveKitConnectOptions extends RelayLiveKitAudioOptions {
|
|
|
42
59
|
relay: Relay;
|
|
43
60
|
callId: string;
|
|
44
61
|
room?: CallRoomOptions;
|
|
45
|
-
/**
|
|
46
|
-
|
|
62
|
+
/**
|
|
63
|
+
* STUN and TURN servers for the agent's WebRTC peer. Defaults to the servers
|
|
64
|
+
* the Call room sends (Cloudflare STUN plus TURN credentials Relay mints). A
|
|
65
|
+
* function is called again before every restart, to mint fresh TURN credentials.
|
|
66
|
+
*/
|
|
67
|
+
iceServers?: RelayIceServer[] | RelayIceServersProvider;
|
|
47
68
|
/** `"relay"` forces TURN. Defaults to `"all"`. */
|
|
48
69
|
iceTransportPolicy?: RelayIceTransportPolicy;
|
|
49
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* How long one SFU session has to connect before the transport restarts onto
|
|
72
|
+
* a new one. Defaults to 5 seconds. `connect()` has no overall deadline.
|
|
73
|
+
*/
|
|
74
|
+
sessionConnectTimeoutMs?: number;
|
|
75
|
+
/** @deprecated Use `sessionConnectTimeoutMs`; now the per-session wait, not a `connect()` deadline. */
|
|
50
76
|
mediaConnectTimeoutMs?: number;
|
|
51
|
-
/** @deprecated Use `
|
|
77
|
+
/** @deprecated Use `sessionConnectTimeoutMs`. */
|
|
52
78
|
connectionTimeoutMs?: number;
|
|
79
|
+
/** Aborting stops `connect()` and closes the transport; the Call itself is not ended. */
|
|
80
|
+
signal?: AbortSignal;
|
|
53
81
|
}
|
|
54
82
|
type AgentSessionAudioTarget = Pick<AgentSession, "input" | "output">;
|
|
55
83
|
/**
|
|
@@ -66,6 +94,12 @@ export declare class RelayLiveKitCall {
|
|
|
66
94
|
static connect(options: RelayLiveKitConnectOptions): Promise<RelayLiveKitCall>;
|
|
67
95
|
attach(session: AgentSessionAudioTarget): void;
|
|
68
96
|
detach(): void;
|
|
97
|
+
/**
|
|
98
|
+
* Resolves once the person's audio has arrived and the room shows them
|
|
99
|
+
* connected (the transport's `peerAudio`). Await it before starting the
|
|
100
|
+
* AgentSession so the greeting is heard.
|
|
101
|
+
*/
|
|
102
|
+
waitForPeerAudio(timeoutMs: number): Promise<void>;
|
|
69
103
|
/** ICE candidates and state transitions for this call, with a one-line summary for logs. */
|
|
70
104
|
diagnostics(): RelayCallIceDiagnostics;
|
|
71
105
|
setMuted(muted: boolean): void;
|
package/dist/livekit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livekit.d.ts","sourceRoot":"","sources":["../src/livekit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAU,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EACL,kBAAkB,EAElB,KAAK,uBAAuB,EAE5B,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAE7B,MAAM,
|
|
1
|
+
{"version":3,"file":"livekit.d.ts","sourceRoot":"","sources":["../src/livekit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAU,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EACL,kBAAkB,EAElB,KAAK,uBAAuB,EAE5B,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAE7B,MAAM,2BAA2B,CAAC;AAEnC;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,uBAAuB,CAGrE,CAAC;AAEH,kFAAkF;AAClF,qBAAa,eAAgB,SAAQ,UAAU;;gBASjC,SAAS,EAAE,kBAAkB;IA4BhC,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAI9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQtC;AAED;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;;gBAanC,SAAS,EAAE,kBAAkB,EAAE,UAAU,SAAS;IAK9D;;;;;OAKG;IACY,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB7D,4FAA4F;IACnF,KAAK,IAAI,IAAI;IAWb,WAAW,IAAI,IAAI;IAU5B,KAAK,IAAI,IAAI;CAmBd;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,GAClC,WAAW,kBAAkB,EAC7B,UAAS,wBAA6B,KACrC,iBAGD,CAAC;AAEH,MAAM,WAAW,0BAA2B,SAAQ,wBAAwB;IAC1E,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,eAAe,CAAC;IAKvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,uBAAuB,CAAC;IACxD,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,uBAAuB,CAAC;IAG7C;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uGAAuG;IACvG,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yFAAyF;IACzF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,KAAK,uBAAuB,GAAG,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC;AAEtE;;;;GAIG;AACH,qBAAa,gBAAgB;;IAC3B,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAIlC,OAAO;WAMM,OAAO,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4BpF,MAAM,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI;IAQ9C,MAAM,IAAI,IAAI;IAOd;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,4FAA4F;IAC5F,WAAW,IAAI,uBAAuB;IAItC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAI9B,GAAG,IAAI,IAAI;IAIL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
|
package/dist/livekit.js
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
import { AudioInput, AudioOutput, Future } from "@livekit/agents";
|
|
2
2
|
import { AudioFrame } from "@livekit/rtc-node";
|
|
3
3
|
import { TransformStream } from "node:stream/web";
|
|
4
|
-
import { RelayCallTransport, } from "
|
|
4
|
+
import { RelayCallTransport, } from "@relaymessenger/sdk/calls";
|
|
5
|
+
/**
|
|
6
|
+
* The format LiveKit's own room input hands an AgentSession:
|
|
7
|
+
* `@livekit/agents` dist/voice/room_io/room_io.js:46-48
|
|
8
|
+
* `DEFAULT_ROOM_INPUT_OPTIONS = { audioSampleRate: 24e3, audioNumChannels: 1 }`,
|
|
9
|
+
* passed to the participant `AudioStream` (room_io.js:373-374). Plugins
|
|
10
|
+
* resample assuming the channel count they construct with
|
|
11
|
+
* (`@livekit/agents-plugin-google` 1.9.0 realtime_api.js:1307-1329
|
|
12
|
+
* `new AudioResampler(frame.sampleRate, 16000, 1)`; rtc-node's resampler reads
|
|
13
|
+
* raw bytes and ignores `frame.channels`), so the session must receive mono.
|
|
14
|
+
*/
|
|
15
|
+
export const LIVEKIT_ROOM_INPUT_AUDIO = Object.freeze({
|
|
16
|
+
sampleRate: 24_000,
|
|
17
|
+
channelCount: 1,
|
|
18
|
+
});
|
|
5
19
|
/** LiveKit Agents input backed by the remote Relay participant's WebRTC audio. */
|
|
6
20
|
export class RelayAudioInput extends AudioInput {
|
|
7
21
|
#transport;
|
|
8
22
|
#writer;
|
|
9
23
|
#onAudio;
|
|
24
|
+
/** Serial write chain: each frame waits for the writer, as `pipeTo` does in LiveKit's input. */
|
|
25
|
+
#writes = Promise.resolve();
|
|
10
26
|
#attached = false;
|
|
11
27
|
#closed = false;
|
|
12
28
|
constructor(transport) {
|
|
@@ -19,7 +35,16 @@ export class RelayAudioInput extends AudioInput {
|
|
|
19
35
|
if (this.#closed || !this.#attached)
|
|
20
36
|
return;
|
|
21
37
|
const audio = new AudioFrame(frame.samples, frame.sampleRate, frame.channelCount, frame.samples.length / frame.channelCount);
|
|
22
|
-
|
|
38
|
+
// LiveKit's ParticipantAudioInputStream pipes its AudioStream into the
|
|
39
|
+
// session with `pipeTo(output.writable)` (room_io/_input.js:161-162),
|
|
40
|
+
// which awaits the writer before each chunk. The transport pushes and
|
|
41
|
+
// cannot be paused, so the frames wait here in order instead.
|
|
42
|
+
this.#writes = this.#writes
|
|
43
|
+
.then(async () => {
|
|
44
|
+
await this.#writer.ready;
|
|
45
|
+
await this.#writer.write(audio);
|
|
46
|
+
})
|
|
47
|
+
.catch(() => undefined);
|
|
23
48
|
};
|
|
24
49
|
this.#transport.on("audio", this.#onAudio);
|
|
25
50
|
}
|
|
@@ -31,6 +56,7 @@ export class RelayAudioInput extends AudioInput {
|
|
|
31
56
|
return;
|
|
32
57
|
this.#closed = true;
|
|
33
58
|
this.#transport.off("audio", this.#onAudio);
|
|
59
|
+
await this.#writes;
|
|
34
60
|
await this.#writer.close().catch(() => undefined);
|
|
35
61
|
await super.close();
|
|
36
62
|
}
|
|
@@ -54,11 +80,19 @@ export class RelayAudioOutput extends AudioOutput {
|
|
|
54
80
|
#flushDone = true;
|
|
55
81
|
/** Resolved by `clearBuffer()` with the milliseconds still queued at that moment. */
|
|
56
82
|
#interruptedFuture = new Future();
|
|
83
|
+
/** Bumped by `clearBuffer()`; a frame the transport dropped across it is not counted (agents-js `interruptionGeneration`). */
|
|
84
|
+
#interruptionGeneration = 0;
|
|
57
85
|
#closed = false;
|
|
58
86
|
constructor(transport, sampleRate = 48_000) {
|
|
59
87
|
super(sampleRate, undefined, { pause: false });
|
|
60
88
|
this.#transport = transport;
|
|
61
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Hands the frame to the transport, which holds it until the person receives
|
|
92
|
+
* the agent's audio (PROTOCOL.md section 6b) and resolves once it is queued,
|
|
93
|
+
* so this waits as LiveKit's room audio output waits for the track's
|
|
94
|
+
* subscription. A frame dropped by `clearBuffer()` meanwhile is not counted.
|
|
95
|
+
*/
|
|
62
96
|
async captureFrame(frame) {
|
|
63
97
|
if (this.#closed)
|
|
64
98
|
throw new Error("Relay LiveKit audio output is closed.");
|
|
@@ -66,18 +100,21 @@ export class RelayAudioOutput extends AudioOutput {
|
|
|
66
100
|
this.logger.error("captureFrame called while flush is in progress");
|
|
67
101
|
await this.#flushTask;
|
|
68
102
|
}
|
|
69
|
-
|
|
70
|
-
if (!this.#firstFrameEmitted) {
|
|
71
|
-
this.#firstFrameEmitted = true;
|
|
72
|
-
this.onPlaybackStarted(Date.now());
|
|
73
|
-
}
|
|
74
|
-
this.#pushedDuration += frame.samplesPerChannel / frame.sampleRate;
|
|
103
|
+
const interruptionGeneration = this.#interruptionGeneration;
|
|
75
104
|
// Resolves once the slices are queued; the engine's pump paces the wire.
|
|
76
105
|
await this.#transport.writeAudio({
|
|
77
106
|
samples: frame.data,
|
|
78
107
|
sampleRate: frame.sampleRate,
|
|
79
108
|
channelCount: frame.channels,
|
|
80
109
|
});
|
|
110
|
+
if (interruptionGeneration !== this.#interruptionGeneration)
|
|
111
|
+
return;
|
|
112
|
+
await super.captureFrame(frame);
|
|
113
|
+
if (!this.#firstFrameEmitted) {
|
|
114
|
+
this.#firstFrameEmitted = true;
|
|
115
|
+
this.onPlaybackStarted(Date.now());
|
|
116
|
+
}
|
|
117
|
+
this.#pushedDuration += frame.samplesPerChannel / frame.sampleRate;
|
|
81
118
|
}
|
|
82
119
|
/** Mark the segment complete; `onPlaybackFinished` fires once the transport has drained. */
|
|
83
120
|
flush() {
|
|
@@ -93,6 +130,7 @@ export class RelayAudioOutput extends AudioOutput {
|
|
|
93
130
|
void this.#flushTask.catch(() => undefined);
|
|
94
131
|
}
|
|
95
132
|
clearBuffer() {
|
|
133
|
+
this.#interruptionGeneration += 1;
|
|
96
134
|
const queuedMs = this.#transport.queuedAudioMs();
|
|
97
135
|
this.#transport.clearAudio();
|
|
98
136
|
if (this.#interruptedFuture.done)
|
|
@@ -150,6 +188,7 @@ export class RelayLiveKitCall {
|
|
|
150
188
|
const transportOptions = {
|
|
151
189
|
relay: options.relay,
|
|
152
190
|
callId: options.callId,
|
|
191
|
+
inboundAudio: LIVEKIT_ROOM_INPUT_AUDIO,
|
|
153
192
|
...(options.room ? { room: options.room } : {}),
|
|
154
193
|
...(options.roomClient ? { roomClient: options.roomClient } : {}),
|
|
155
194
|
...(options.webRTC ? { webRTC: options.webRTC } : {}),
|
|
@@ -158,6 +197,9 @@ export class RelayLiveKitCall {
|
|
|
158
197
|
...(options.iceGatheringTimeoutMs === undefined
|
|
159
198
|
? {}
|
|
160
199
|
: { iceGatheringTimeoutMs: options.iceGatheringTimeoutMs }),
|
|
200
|
+
...(options.sessionConnectTimeoutMs === undefined
|
|
201
|
+
? {}
|
|
202
|
+
: { sessionConnectTimeoutMs: options.sessionConnectTimeoutMs }),
|
|
161
203
|
...(options.mediaConnectTimeoutMs === undefined
|
|
162
204
|
? {}
|
|
163
205
|
: { mediaConnectTimeoutMs: options.mediaConnectTimeoutMs }),
|
|
@@ -166,7 +208,7 @@ export class RelayLiveKitCall {
|
|
|
166
208
|
: { connectionTimeoutMs: options.connectionTimeoutMs }),
|
|
167
209
|
};
|
|
168
210
|
const transport = new RelayCallTransport(transportOptions);
|
|
169
|
-
await transport.connect();
|
|
211
|
+
await transport.connect(options.signal ? { signal: options.signal } : {});
|
|
170
212
|
return new RelayLiveKitCall(transport, createRelayLiveKitAudio(transport, options));
|
|
171
213
|
}
|
|
172
214
|
attach(session) {
|
|
@@ -187,6 +229,14 @@ export class RelayLiveKitCall {
|
|
|
187
229
|
this.#session.output.audio = null;
|
|
188
230
|
this.#session = undefined;
|
|
189
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Resolves once the person's audio has arrived and the room shows them
|
|
234
|
+
* connected (the transport's `peerAudio`). Await it before starting the
|
|
235
|
+
* AgentSession so the greeting is heard.
|
|
236
|
+
*/
|
|
237
|
+
waitForPeerAudio(timeoutMs) {
|
|
238
|
+
return this.transport.waitForPeerAudio(timeoutMs);
|
|
239
|
+
}
|
|
190
240
|
/** ICE candidates and state transitions for this call, with a one-line summary for logs. */
|
|
191
241
|
diagnostics() {
|
|
192
242
|
return this.transport.diagnostics();
|
package/dist/livekit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livekit.js","sourceRoot":"","sources":["../src/livekit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAqB,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAoC,MAAM,iBAAiB,CAAC;AAGpF,OAAO,EACL,kBAAkB,
|
|
1
|
+
{"version":3,"file":"livekit.js","sourceRoot":"","sources":["../src/livekit.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relaymessenger/livekit",
|
|
3
|
-
"version": "0.1.0-staging.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0-staging.31",
|
|
4
|
+
"description": "LiveKit Agents audio input and output for Relay Calls, over @relaymessenger/sdk/calls.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -12,11 +12,6 @@
|
|
|
12
12
|
"import": "./dist/index.js",
|
|
13
13
|
"default": "./dist/index.js"
|
|
14
14
|
},
|
|
15
|
-
"./transport": {
|
|
16
|
-
"types": "./dist/transport.d.ts",
|
|
17
|
-
"import": "./dist/transport.js",
|
|
18
|
-
"default": "./dist/transport.js"
|
|
19
|
-
},
|
|
20
15
|
"./package.json": "./package.json"
|
|
21
16
|
},
|
|
22
17
|
"files": [
|
|
@@ -38,11 +33,13 @@
|
|
|
38
33
|
"license": "MIT",
|
|
39
34
|
"dependencies": {
|
|
40
35
|
"@evan/opus": "1.0.3",
|
|
41
|
-
"@relaymessenger/sdk": "0.3.6-staging.
|
|
36
|
+
"@relaymessenger/sdk": "0.3.6-staging.41",
|
|
37
|
+
"rtp-packet": "0.4.2",
|
|
42
38
|
"werift": "0.24.4"
|
|
43
39
|
},
|
|
44
40
|
"optionalDependencies": {
|
|
45
|
-
"@roamhq/wrtc": "^0.10.0"
|
|
41
|
+
"@roamhq/wrtc": "^0.10.0",
|
|
42
|
+
"node-webcodecs": "1.3.0"
|
|
46
43
|
},
|
|
47
44
|
"peerDependencies": {
|
|
48
45
|
"@livekit/agents": "^1.9.0",
|
|
@@ -72,6 +69,7 @@
|
|
|
72
69
|
"livekit",
|
|
73
70
|
"webrtc",
|
|
74
71
|
"voice",
|
|
72
|
+
"video",
|
|
75
73
|
"agents"
|
|
76
74
|
]
|
|
77
75
|
}
|
package/dist/engine-werift.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { RTCPeerConnection } from "werift";
|
|
2
|
-
import type { RelayAudioSourceLike, RelayPeerConnectionConfig, RelayWebRTCFactory } from "./transport.js";
|
|
3
|
-
/** Opus on the wire is always 48 kHz; Relay sends stereo so callers may pass either channel count. */
|
|
4
|
-
export declare const WERIFT_SAMPLE_RATE = 48000;
|
|
5
|
-
export declare const WERIFT_CHANNEL_COUNT = 2;
|
|
6
|
-
/** One RTP packet carries 20 ms: 960 frames at 48 kHz, timestamp advances by 960. */
|
|
7
|
-
export declare const WERIFT_PACKET_MS = 20;
|
|
8
|
-
export type WeriftAudioSourceData = Parameters<RelayAudioSourceLike["onData"]>[0];
|
|
9
|
-
/** Packets counted for `diagnostics()`; the recent window is the last 5 s. */
|
|
10
|
-
export declare const STATS_WINDOW_MS = 5000;
|
|
11
|
-
/** Convert any PCM16 frame to interleaved 48 kHz stereo by linear interpolation. */
|
|
12
|
-
export declare const toWireFormat: (data: {
|
|
13
|
-
samples: Int16Array;
|
|
14
|
-
sampleRate: number;
|
|
15
|
-
channelCount: number;
|
|
16
|
-
}) => Int16Array;
|
|
17
|
-
export declare const createWeriftPeerConnection: (config?: RelayPeerConnectionConfig) => RTCPeerConnection;
|
|
18
|
-
export declare const createWeriftWebRTCFactory: () => RelayWebRTCFactory;
|
|
19
|
-
//# sourceMappingURL=engine-werift.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine-werift.d.ts","sourceRoot":"","sources":["../src/engine-werift.ts"],"names":[],"mappings":"AAiCA,OAAO,EAGL,iBAAiB,EAIlB,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAGV,oBAAoB,EAGpB,yBAAyB,EAEzB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAExB,sGAAsG;AACtG,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,qFAAqF;AACrF,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAMnC,MAAM,MAAM,qBAAqB,GAAG,UAAU,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAElF,8EAA8E;AAC9E,eAAO,MAAM,eAAe,OAAQ,CAAC;AA8BrC,oFAAoF;AACpF,eAAO,MAAM,YAAY,GAAI,MAAM;IACjC,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,KAAG,UAwBH,CAAC;AA0MF,eAAO,MAAM,0BAA0B,GACrC,SAAQ,yBAAyE,KAChF,iBAcC,CAAC;AAEL,eAAO,MAAM,yBAAyB,QAAO,kBAI3C,CAAC"}
|