@memberjunction/livekit-room-server 6.2.0-edge.2 → 6.2.0-edge.3
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 +85 -0
- package/dist/index.d.ts +17 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/livekit-agent-room-coordinator.d.ts +105 -8
- package/dist/livekit-agent-room-coordinator.d.ts.map +1 -1
- package/dist/livekit-agent-room-coordinator.js +125 -25
- package/dist/livekit-agent-room-coordinator.js.map +1 -1
- package/dist/livekit-egress-service.d.ts +7 -0
- package/dist/livekit-egress-service.d.ts.map +1 -1
- package/dist/livekit-egress-service.js +11 -0
- package/dist/livekit-egress-service.js.map +1 -1
- package/dist/livekit-native-module.d.ts +18 -0
- package/dist/livekit-native-module.d.ts.map +1 -0
- package/dist/livekit-native-module.js +20 -0
- package/dist/livekit-native-module.js.map +1 -0
- package/dist/livekit-sip-service.d.ts +141 -0
- package/dist/livekit-sip-service.d.ts.map +1 -0
- package/dist/livekit-sip-service.js +169 -0
- package/dist/livekit-sip-service.js.map +1 -0
- package/dist/livekit-token-service.d.ts +6 -0
- package/dist/livekit-token-service.d.ts.map +1 -1
- package/dist/livekit-token-service.js +8 -0
- package/dist/livekit-token-service.js.map +1 -1
- package/dist/livekit-webhook.d.ts +65 -0
- package/dist/livekit-webhook.d.ts.map +1 -0
- package/dist/livekit-webhook.js +65 -0
- package/dist/livekit-webhook.js.map +1 -0
- package/dist/meeting-dial-in-service.d.ts +75 -0
- package/dist/meeting-dial-in-service.d.ts.map +1 -0
- package/dist/meeting-dial-in-service.js +175 -0
- package/dist/meeting-dial-in-service.js.map +1 -0
- package/dist/room-audio/audio-decoder.d.ts +40 -0
- package/dist/room-audio/audio-decoder.d.ts.map +1 -0
- package/dist/room-audio/audio-decoder.js +205 -0
- package/dist/room-audio/audio-decoder.js.map +1 -0
- package/dist/room-audio/comfort-tone.d.ts +23 -0
- package/dist/room-audio/comfort-tone.d.ts.map +1 -0
- package/dist/room-audio/comfort-tone.js +70 -0
- package/dist/room-audio/comfort-tone.js.map +1 -0
- package/dist/room-audio/pcm-frame-pump.d.ts +134 -0
- package/dist/room-audio/pcm-frame-pump.d.ts.map +1 -0
- package/dist/room-audio/pcm-frame-pump.js +253 -0
- package/dist/room-audio/pcm-frame-pump.js.map +1 -0
- package/dist/room-audio/room-audio-decode-cache.d.ts +37 -0
- package/dist/room-audio/room-audio-decode-cache.d.ts.map +1 -0
- package/dist/room-audio/room-audio-decode-cache.js +75 -0
- package/dist/room-audio/room-audio-decode-cache.js.map +1 -0
- package/dist/room-audio/room-audio-player.d.ts +178 -0
- package/dist/room-audio/room-audio-player.d.ts.map +1 -0
- package/dist/room-audio/room-audio-player.js +404 -0
- package/dist/room-audio/room-audio-player.js.map +1 -0
- package/dist/room-audio/room-audio-sources.d.ts +47 -0
- package/dist/room-audio/room-audio-sources.d.ts.map +1 -0
- package/dist/room-audio/room-audio-sources.js +116 -0
- package/dist/room-audio/room-audio-sources.js.map +1 -0
- package/dist/room-audio/room-speech-synthesizer.d.ts +55 -0
- package/dist/room-audio/room-speech-synthesizer.d.ts.map +1 -0
- package/dist/room-audio/room-speech-synthesizer.js +56 -0
- package/dist/room-audio/room-speech-synthesizer.js.map +1 -0
- package/dist/room-authorization.d.ts +58 -0
- package/dist/room-authorization.d.ts.map +1 -0
- package/dist/room-authorization.js +212 -0
- package/dist/room-authorization.js.map +1 -0
- package/dist/room-handoff/handoff-offer-registry.d.ts +137 -0
- package/dist/room-handoff/handoff-offer-registry.d.ts.map +1 -0
- package/dist/room-handoff/handoff-offer-registry.js +521 -0
- package/dist/room-handoff/handoff-offer-registry.js.map +1 -0
- package/dist/room-handoff/handoff-types.d.ts +170 -0
- package/dist/room-handoff/handoff-types.d.ts.map +1 -0
- package/dist/room-handoff/handoff-types.js +16 -0
- package/dist/room-handoff/handoff-types.js.map +1 -0
- package/dist/room-handoff/room-handoff-engine.d.ts +141 -0
- package/dist/room-handoff/room-handoff-engine.d.ts.map +1 -0
- package/dist/room-handoff/room-handoff-engine.js +530 -0
- package/dist/room-handoff/room-handoff-engine.js.map +1 -0
- package/package.json +14 -9
package/README.md
CHANGED
|
@@ -114,6 +114,91 @@ and logs — the stop-recording mutation still succeeds. See
|
|
|
114
114
|
[REALTIME_SESSION_CAPTURE_GUIDE.md](../../guides/REALTIME_SESSION_CAPTURE_GUIDE.md#meeting-room-recording-livekit-egress--mjstorage)
|
|
115
115
|
for the full loop incl. Meet-app playback.
|
|
116
116
|
|
|
117
|
+
## Room audio player (hold music)
|
|
118
|
+
|
|
119
|
+
`RoomAudioPlayer` joins a room as a small **publish-only** bot and plays audio into it: contact-center hold
|
|
120
|
+
music, with spoken announcements ducked over the top. It reuses the agent bridge's plumbing: bot tokens from
|
|
121
|
+
`LiveKitTokenService` (the `LIVEKIT_*` env vars), the native room client at the same specifier the agent
|
|
122
|
+
coordinator uses (`LIVEKIT_NATIVE_MODULE`, default `@memberjunction/ai-bridge-livekit-native`), and the PCM16
|
|
123
|
+
resampler from `@memberjunction/ai-bridge-base`.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { RoomAudioPlayer } from '@memberjunction/livekit-room-server';
|
|
127
|
+
|
|
128
|
+
const hold = await RoomAudioPlayer.Instance.Start({
|
|
129
|
+
RoomName: callRoom,
|
|
130
|
+
Source: { Kind: 'File', FileID: queue.HoldMusicFileID }, // or { Kind: 'Url', Url }, { Kind: 'Pcm', Pcm, SampleRate }, { Kind: 'ComfortTone' }
|
|
131
|
+
ContextUser: contextUser,
|
|
132
|
+
// Loop: true (default), DisplayName: 'On hold' (default), Identity: 'hold-<playback id>' (default)
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
await hold.Announce({ Text: 'You are caller number three.' }); // music ducks, clip plays, music returns
|
|
136
|
+
hold.Pause(); hold.Resume();
|
|
137
|
+
await hold.Stop(); // idempotent; always disconnects the bot
|
|
138
|
+
|
|
139
|
+
RoomAudioPlayer.Instance.GetActive(callRoom); // live playbacks in a room
|
|
140
|
+
await RoomAudioPlayer.Instance.StopAllInRoom(callRoom); // e.g. when an agent picks up
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Sources.** An `MJ: Files` row (loaded as `ContextUser`, bytes read through `@memberjunction/storage`), an
|
|
144
|
+
**https** URL (plain http is refused; fetched with `SafeFetch`, so every redirect hop is checked against
|
|
145
|
+
private/reserved addresses; 20 s timeout; 25 MB cap), caller-supplied mono PCM16, or the built-in
|
|
146
|
+
**comfort tone** — a procedurally generated 10 s loop of soft chord pads (no asset, nothing to license).
|
|
147
|
+
|
|
148
|
+
**Formats.** WAV (integer PCM 8/16/24/32-bit, IEEE float 32/64-bit, `WAVE_FORMAT_EXTENSIBLE`, any channel count —
|
|
149
|
+
downmixed to mono) and MP3 (decoded by `mpg123-decoder`, a WebAssembly build of libmpg123: no native build step).
|
|
150
|
+
Anything else (Ogg, FLAC, AAC/M4A, …) is refused with an error naming the format. Audio is limited to
|
|
151
|
+
**15 minutes**; hold music loops, so a few minutes is plenty.
|
|
152
|
+
|
|
153
|
+
**Playback.** Audio is resampled to 48 kHz and paced into the room in 20 ms frames against a monotonic clock,
|
|
154
|
+
about 150 ms ahead of real time — the native client's own outbound queue never holds more than that. A blocked
|
|
155
|
+
event loop drops the missed audio instead of bursting it. Decodes are cached by source (8 entries, 256 MB of PCM),
|
|
156
|
+
and concurrent starts of the same file share one download, so a busy queue reads its hold file once. The cache is
|
|
157
|
+
keyed by source, not by user: only the first load checks the reading user's access to the file.
|
|
158
|
+
|
|
159
|
+
**Lifecycle.** A playback whose bot is disconnected by the server stops and deregisters itself, and a verified
|
|
160
|
+
`room_finished` webhook (`LiveKitWebhookParser.Parse`) stops every playback in that room. A non-looping playback
|
|
161
|
+
leaves the room when its audio ends — after the audio already sent ahead of real time (about 150 ms) has played
|
|
162
|
+
out, so the tail is not cut off.
|
|
163
|
+
|
|
164
|
+
**Knowing it finished.** Every handle has `Ended: Promise<RoomAudioEndReason>`, which resolves once the bot has
|
|
165
|
+
left the room, and `EndReason` (`null` while live). Only `'Completed'` means the whole clip reached the room;
|
|
166
|
+
`'Stopped'` (Stop / StopAllInRoom), `'Failed'` (the outbound sink broke) and `'Disconnected'` (the server dropped
|
|
167
|
+
the bot) all mean it was cut short. The first reason wins. Use it to gate anything that must follow a full play:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
const disclosure = await RoomAudioPlayer.Instance.Start({
|
|
171
|
+
RoomName: callRoom,
|
|
172
|
+
Source: { Kind: 'File', FileID: disclosureFileID },
|
|
173
|
+
Loop: false,
|
|
174
|
+
DisplayName: 'Recording notice',
|
|
175
|
+
ContextUser: contextUser,
|
|
176
|
+
});
|
|
177
|
+
if ((await disclosure.Ended) === 'Completed') {
|
|
178
|
+
await startRecording(); // the caller has heard the whole notice
|
|
179
|
+
} else {
|
|
180
|
+
// fail closed: do not record
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
A looping playback never completes on its own; its `Ended` resolves `'Stopped'` when it is stopped.
|
|
185
|
+
|
|
186
|
+
**Announcements and text-to-speech.** `Announce({ Pcm, SampleRate })` plays ready-made audio. `Announce({ Text })`
|
|
187
|
+
goes through the `IRoomSpeechSynthesizer` port, and **none is installed by default** — a voice is vendor-specific,
|
|
188
|
+
so the host chooses it. Without one, a text announcement returns `false` and the player logs the omission once.
|
|
189
|
+
To enable it, install the MJ-backed synthesizer (`AITextToSpeechRunner`: model selection, credentials, failover,
|
|
190
|
+
an `MJ: AI Prompt Runs` row) once at startup:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { MJRoomSpeechSynthesizer, RoomAudioPlayer } from '@memberjunction/livekit-room-server';
|
|
194
|
+
|
|
195
|
+
RoomAudioPlayer.Instance.SetSpeechSynthesizer(new MJRoomSpeechSynthesizer({ Voice: 'alloy', ModelID: ttsModelID }));
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The host needs an active TTS model whose vendor offers that voice (pin `ModelID` — voices belong to a vendor)
|
|
199
|
+
and the carrier prompt `Default Text To Speech` (or pass `PromptID`). Any other implementation of
|
|
200
|
+
`IRoomSpeechSynthesizer` works too.
|
|
201
|
+
|
|
117
202
|
## GraphQL surface
|
|
118
203
|
|
|
119
204
|
These are exposed to the browser via MJServer's `RealtimeBridgeResolver`:
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,22 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module @memberjunction/livekit-room-server
|
|
8
8
|
*/
|
|
9
|
-
export { LiveKitTokenService, type LiveKitServerConfig, type LiveKitTokenRole, type MintTokenParams, type MintedToken } from './livekit-token-service.js';
|
|
10
|
-
export { LiveKitAgentRoomCoordinator, LIVEKIT_BRIDGE_DRIVER_CLASS, type BridgeOps, type RealtimeSessionFactory, type RealtimeSessionStartContext, type StartAgentRoomSessionParams, type AgentRoomSession, } from './livekit-agent-room-coordinator.js';
|
|
9
|
+
export { LiveKitTokenService, LiveKitUserIdentity, type LiveKitServerConfig, type LiveKitTokenRole, type MintTokenParams, type MintedToken } from './livekit-token-service.js';
|
|
10
|
+
export { LiveKitAgentRoomCoordinator, LIVEKIT_BRIDGE_DRIVER_CLASS, type BridgeOps, type RealtimeSessionFactory, type RealtimeSessionStartContext, type AgentRoomHostOptions, type StartAgentRoomSessionParams, type AgentRoomSession, } from './livekit-agent-room-coordinator.js';
|
|
11
11
|
export { LiveKitEgressService, WsToHttpUrl, wsToHttpUrl, type EgressClientLike, type StartRecordingParams, type RecordingInfo } from './livekit-egress-service.js';
|
|
12
|
+
export { LiveKitSipService, LIVEKIT_PARTICIPANT_KIND_SIP, LIVEKIT_SIP_ATTRIBUTES, SIP_DIAL_REQUEST_TIMEOUT_SECONDS, SIP_DIAL_MAX_DURATION_SECONDS, type SipClientLike, type RoomServiceClientLike, type RoomParticipantSummary, type SipTrunkSummary, type DialSipParticipantParams, type EnsureInboundRoutingParams, type InboundRoutingResult, } from './livekit-sip-service.js';
|
|
13
|
+
export { LiveKitWebhookParser, type LiveKitRoomWebhookEvent, type WebhookReceiverLike } from './livekit-webhook.js';
|
|
14
|
+
export * from './room-handoff/handoff-types.js';
|
|
15
|
+
export * from './room-handoff/handoff-offer-registry.js';
|
|
16
|
+
export * from './room-handoff/room-handoff-engine.js';
|
|
17
|
+
export * from './room-authorization.js';
|
|
18
|
+
export * from './meeting-dial-in-service.js';
|
|
19
|
+
export { DEFAULT_LIVEKIT_NATIVE_MODULE, ResolveLiveKitNativeModuleSpecifier } from './livekit-native-module.js';
|
|
20
|
+
export * from './room-audio/audio-decoder.js';
|
|
21
|
+
export * from './room-audio/comfort-tone.js';
|
|
22
|
+
export * from './room-audio/pcm-frame-pump.js';
|
|
23
|
+
export * from './room-audio/room-audio-decode-cache.js';
|
|
24
|
+
export * from './room-audio/room-audio-sources.js';
|
|
25
|
+
export * from './room-audio/room-speech-synthesizer.js';
|
|
26
|
+
export * from './room-audio/room-audio-player.js';
|
|
12
27
|
//# 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;;;;;;;GAOG;AAWH,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE5K,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,KAAK,SAAS,EACd,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,gBAAgB,GACtB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEhK,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,sBAAsB,EACtB,gCAAgC,EAChC,6BAA6B,EAC7B,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,GAC1B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,oBAAoB,EAAE,KAAK,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEjH,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,oCAAoC,CAAC;AACnD,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAE1C,OAAO,EAAE,6BAA6B,EAAE,mCAAmC,EAAE,MAAM,yBAAyB,CAAC;AAG7G,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AACrD,cAAc,gCAAgC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,23 @@ import { LoadLiveKitBridge } from '@memberjunction/ai-bridge-livekit';
|
|
|
13
13
|
// MJServer does) registers the bridge. The no-op call is a tree-shake guard. Without this the room start
|
|
14
14
|
// fails with "No bridge driver registered for DriverClass 'LiveKitBridge'".
|
|
15
15
|
LoadLiveKitBridge();
|
|
16
|
-
export { LiveKitTokenService } from './livekit-token-service.js';
|
|
16
|
+
export { LiveKitTokenService, LiveKitUserIdentity } from './livekit-token-service.js';
|
|
17
17
|
export { LiveKitAgentRoomCoordinator, LIVEKIT_BRIDGE_DRIVER_CLASS, } from './livekit-agent-room-coordinator.js';
|
|
18
18
|
export { LiveKitEgressService, WsToHttpUrl, wsToHttpUrl } from './livekit-egress-service.js';
|
|
19
|
+
export { LiveKitSipService, LIVEKIT_PARTICIPANT_KIND_SIP, LIVEKIT_SIP_ATTRIBUTES, SIP_DIAL_REQUEST_TIMEOUT_SECONDS, SIP_DIAL_MAX_DURATION_SECONDS, } from './livekit-sip-service.js';
|
|
20
|
+
export { LiveKitWebhookParser } from './livekit-webhook.js';
|
|
21
|
+
export * from './room-handoff/handoff-types.js';
|
|
22
|
+
export * from './room-handoff/handoff-offer-registry.js';
|
|
23
|
+
export * from './room-handoff/room-handoff-engine.js';
|
|
24
|
+
export * from './room-authorization.js';
|
|
25
|
+
export * from './meeting-dial-in-service.js';
|
|
26
|
+
export { DEFAULT_LIVEKIT_NATIVE_MODULE, ResolveLiveKitNativeModuleSpecifier } from './livekit-native-module.js';
|
|
27
|
+
// Room audio player (contact-center hold music + ducked announcements).
|
|
28
|
+
export * from './room-audio/audio-decoder.js';
|
|
29
|
+
export * from './room-audio/comfort-tone.js';
|
|
30
|
+
export * from './room-audio/pcm-frame-pump.js';
|
|
31
|
+
export * from './room-audio/room-audio-decode-cache.js';
|
|
32
|
+
export * from './room-audio/room-audio-sources.js';
|
|
33
|
+
export * from './room-audio/room-speech-synthesizer.js';
|
|
34
|
+
export * from './room-audio/room-audio-player.js';
|
|
19
35
|
//# 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;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,+FAA+F;AAC/F,sGAAsG;AACtG,wGAAwG;AACxG,yGAAyG;AACzG,4EAA4E;AAC5E,iBAAiB,EAAE,CAAC;AAEpB,OAAO,EAAE,mBAAmB,EAA2F,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,+FAA+F;AAC/F,sGAAsG;AACtG,wGAAwG;AACxG,yGAAyG;AACzG,4EAA4E;AAC5E,iBAAiB,EAAE,CAAC;AAEpB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAA2F,MAAM,yBAAyB,CAAC;AAE5K,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,GAO5B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAwE,MAAM,0BAA0B,CAAC;AAEhK,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,sBAAsB,EACtB,gCAAgC,EAChC,6BAA6B,GAQ9B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,oBAAoB,EAA0D,MAAM,mBAAmB,CAAC;AAEjH,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,oCAAoC,CAAC;AACnD,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAE1C,OAAO,EAAE,6BAA6B,EAAE,mCAAmC,EAAE,MAAM,yBAAyB,CAAC;AAE7G,wEAAwE;AACxE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sCAAsC,CAAC;AACrD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AACrD,cAAc,gCAAgC,CAAC"}
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { BaseSingleton } from '@memberjunction/global';
|
|
16
16
|
import { type IMetadataProvider, type UserInfo } from '@memberjunction/core';
|
|
17
|
-
import type { IRealtimeSession } from '@memberjunction/ai';
|
|
18
|
-
import { type BridgeDisconnectReason, type BridgeTurnMode } from '@memberjunction/ai-bridge-base';
|
|
19
|
-
import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
|
|
17
|
+
import type { IRealtimeSession, RealtimeToolDefinition } from '@memberjunction/ai';
|
|
18
|
+
import { type BridgeDisconnectReason, type BridgeTurnMode, type TurnAddressingMode } from '@memberjunction/ai-bridge-base';
|
|
19
|
+
import { AIBridgeEngine, type BridgeTranscriptSink, type BridgeTurnTakingToolHandler, type RoomTurnSnapshot } from '@memberjunction/ai-bridge-server';
|
|
20
20
|
import { LiveKitTokenService } from './livekit-token-service.js';
|
|
21
21
|
/** The subset of {@link AIBridgeEngine} the coordinator drives — an injectable seam for unit testing. */
|
|
22
22
|
export type BridgeOps = Pick<AIBridgeEngine, 'Config' | 'ProviderByDriverClass' | 'StartBridgeSession' | 'StopBridgeSession' | 'ReconfigureSessionToMeeting'>;
|
|
@@ -49,7 +49,51 @@ export interface RealtimeSessionStartContext {
|
|
|
49
49
|
MeetingMode?: boolean;
|
|
50
50
|
/** The names the agent answers to (display name + aliases) — phrasing for the meeting prompt. */
|
|
51
51
|
SelfNames?: string[];
|
|
52
|
+
/** Tools the host declares and executes itself (call control, handoff). Added to the model's tool set. */
|
|
53
|
+
HostTools?: RealtimeToolDefinition[];
|
|
54
|
+
/** Host-authored instructions appended to the system prompt (for example the phone framing). */
|
|
55
|
+
HostFraming?: string;
|
|
56
|
+
/** Role-tagged transcript so far, framed into the prompt when a lost model session is re-opened mid-call. */
|
|
57
|
+
PriorTranscript?: string;
|
|
58
|
+
/** The `MJ: Conversations` row the session writes to — stamped on the co-agent observability run. */
|
|
59
|
+
ConversationID?: string;
|
|
52
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* What a HOST that owns the call (a phone call arriving in a room, a web room with handoff tools) adds to an agent's
|
|
63
|
+
* room session beyond the plain "join the room" the coordinator does for the Meet UI. All optional: a session started
|
|
64
|
+
* without it behaves exactly as before.
|
|
65
|
+
*/
|
|
66
|
+
export interface AgentRoomHostOptions {
|
|
67
|
+
/** Tools the host executes itself. */
|
|
68
|
+
HostTools?: RealtimeToolDefinition[];
|
|
69
|
+
/** Instructions appended to the agent's system prompt. */
|
|
70
|
+
HostFraming?: string;
|
|
71
|
+
/** The conversation the session's transcript belongs to. */
|
|
72
|
+
ConversationID?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Called with every model session opened for this agent (the first one, and any re-opened after a drop) so the host
|
|
75
|
+
* can attach its tool handler to each.
|
|
76
|
+
*/
|
|
77
|
+
OnModelSession?: (session: IRealtimeSession) => void;
|
|
78
|
+
/** Where this session's final transcript lines go (instead of the shared room transcript). */
|
|
79
|
+
TranscriptSink?: BridgeTranscriptSink;
|
|
80
|
+
/** The participant talked over the agent (a true barge-in). */
|
|
81
|
+
OnBargeIn?: () => void;
|
|
82
|
+
/** Re-open the model session once, with the conversation so far, if it drops mid-call. */
|
|
83
|
+
RecoverModelSession?: boolean;
|
|
84
|
+
/** Called once when the session has fully ended, for the host's own bookkeeping. */
|
|
85
|
+
OnSessionEnded?: (reason: BridgeDisconnectReason) => void | Promise<void>;
|
|
86
|
+
/** How the agent got into the room. Default `'OnDemand'`. */
|
|
87
|
+
JoinMethod?: 'InboundRoute' | 'OnDemand' | 'Invite';
|
|
88
|
+
/** Whether the agent was called into the room or placed the call. Default: not stated. */
|
|
89
|
+
Direction?: 'Inbound' | 'Outbound';
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Installs the engine's turn-taking tool handler on a model session — the seam that lets this package stay free
|
|
93
|
+
* of the agent runtime. Production binds it to `GetBridgeRealtimeRuntime(session)?.SetLocalToolHandler(handler)`
|
|
94
|
+
* (`@memberjunction/ai-agents`); a test binds a spy.
|
|
95
|
+
*/
|
|
96
|
+
export type TurnToolBinder = (session: IRealtimeSession, handler: BridgeTurnTakingToolHandler) => void;
|
|
53
97
|
/**
|
|
54
98
|
* Opens a realtime model session for the agent. Production binds this to the real model-resolution path;
|
|
55
99
|
* tests inject a stub. Defaults to a clear "not bound" error so misconfiguration fails loudly.
|
|
@@ -78,10 +122,27 @@ export interface StartAgentRoomSessionParams {
|
|
|
78
122
|
AgentAliases?: string[];
|
|
79
123
|
/** Turn-taking mode. Default: `'Passive'` (speak only when addressed). */
|
|
80
124
|
TurnMode?: BridgeTurnMode;
|
|
125
|
+
/**
|
|
126
|
+
* How the agent decides it was addressed. `'Auto'` (the default) uses the MODEL's own judgement when its model is
|
|
127
|
+
* full-duplex and falls back to name matching otherwise; `'ModelSide'` / `'Regex'` force one. A room in moderator
|
|
128
|
+
* mode (gated meeting) always uses `'Regex'`.
|
|
129
|
+
*/
|
|
130
|
+
TurnAddressing?: TurnAddressingMode;
|
|
81
131
|
/** The user the session runs as. */
|
|
82
132
|
ContextUser?: UserInfo;
|
|
83
133
|
/** The metadata provider for the session. */
|
|
84
134
|
MetadataProvider?: IMetadataProvider;
|
|
135
|
+
/** What a host that owns the call adds (tools, framing, transcript, recovery). Absent for a plain Meet room. */
|
|
136
|
+
Host?: AgentRoomHostOptions;
|
|
137
|
+
}
|
|
138
|
+
/** One agent's membership in a room's roster (for multi-agent meeting detection). */
|
|
139
|
+
export interface RoomAgentEntry {
|
|
140
|
+
/** The MJ agent-session id of this agent in the room. */
|
|
141
|
+
AgentSessionID: string;
|
|
142
|
+
/** The durable bridge row id — the key {@link LiveKitAgentRoomCoordinator.StopAgentRoomSession} removes by. */
|
|
143
|
+
SessionBridgeID: string;
|
|
144
|
+
/** The names this agent answers to (display name + aliases) — used to build its addressing matcher. */
|
|
145
|
+
Names: string[];
|
|
85
146
|
}
|
|
86
147
|
/** The result of starting an agent room session. */
|
|
87
148
|
export interface AgentRoomSession {
|
|
@@ -109,6 +170,8 @@ export declare class LiveKitAgentRoomCoordinator extends BaseSingleton<LiveKitAg
|
|
|
109
170
|
*/
|
|
110
171
|
private roomRosters;
|
|
111
172
|
private bridgeOps;
|
|
173
|
+
private turnToolBinder?;
|
|
174
|
+
private turnStateSource;
|
|
112
175
|
private sessionFactory;
|
|
113
176
|
/** BaseSingleton requires a protected constructor. */
|
|
114
177
|
protected constructor();
|
|
@@ -120,6 +183,29 @@ export declare class LiveKitAgentRoomCoordinator extends BaseSingleton<LiveKitAg
|
|
|
120
183
|
* @param factory The factory that opens an {@link IRealtimeSession} for an agent.
|
|
121
184
|
*/
|
|
122
185
|
SetSessionFactory(factory: RealtimeSessionFactory): void;
|
|
186
|
+
/**
|
|
187
|
+
* Binds the seam that installs the engine's turn-taking tool handler on a model session. Without it a
|
|
188
|
+
* full-duplex model's `i_am_addressed` / `yield_turn` calls cannot be executed (the room's floor gate still
|
|
189
|
+
* protects against overlap; the model just cannot reserve the floor or hand it to a named agent).
|
|
190
|
+
*
|
|
191
|
+
* @param binder The binder, or `undefined` to clear it.
|
|
192
|
+
*/
|
|
193
|
+
SetTurnToolBinder(binder: TurnToolBinder | undefined): void;
|
|
194
|
+
/**
|
|
195
|
+
* Overrides where a room's turn-taking snapshot comes from (an injectable seam for unit testing; production
|
|
196
|
+
* reads the process-wide {@link AIBridgeEngine}).
|
|
197
|
+
*
|
|
198
|
+
* @param source Returns the snapshot for a room key, or `null` when the room holds no agents.
|
|
199
|
+
*/
|
|
200
|
+
SetTurnStateSource(source: (roomKey: string) => RoomTurnSnapshot | null): void;
|
|
201
|
+
/**
|
|
202
|
+
* A room's live turn-taking state — floor holder, whether a person is speaking, any pending hand-off, the
|
|
203
|
+
* agent-to-agent loop-cap progress, the most recent floor events, and who is seated. Read-only.
|
|
204
|
+
*
|
|
205
|
+
* @param roomName The LiveKit room name (the bridge's room key).
|
|
206
|
+
* @returns The snapshot, or `null` when the room holds no agents.
|
|
207
|
+
*/
|
|
208
|
+
GetRoomTurnState(roomName: string): RoomTurnSnapshot | null;
|
|
123
209
|
/**
|
|
124
210
|
* Overrides the token service used to mint the bot token (e.g. to inject explicit credentials).
|
|
125
211
|
*
|
|
@@ -142,16 +228,16 @@ export declare class LiveKitAgentRoomCoordinator extends BaseSingleton<LiveKitAg
|
|
|
142
228
|
* @throws {Error} when the LiveKit provider is not configured/registered or the session factory is unbound.
|
|
143
229
|
*/
|
|
144
230
|
StartAgentRoomSession(params: StartAgentRoomSessionParams): Promise<AgentRoomSession>;
|
|
231
|
+
/** Installs the engine's turn-taking tool handler on the model session, when the session has one (a full-duplex model in a room). */
|
|
232
|
+
private bindTurnTools;
|
|
145
233
|
/** Appends an agent to a room's roster (creating the room's list on first join). */
|
|
146
234
|
private addToRoster;
|
|
147
235
|
/** Removes an agent from whatever room roster holds its bridge id; prunes the room when it empties. */
|
|
148
236
|
private removeFromRoster;
|
|
149
|
-
/** The default native room-client wrapper specifier — the @livekit/rtc-node package this repo ships. */
|
|
150
|
-
private static readonly DEFAULT_NATIVE_MODULE;
|
|
151
237
|
/**
|
|
152
|
-
* Resolves the native LiveKit room-client module specifier for the bridge session
|
|
153
|
-
*
|
|
154
|
-
*
|
|
238
|
+
* Resolves the native LiveKit room-client module specifier for the bridge session (see
|
|
239
|
+
* {@link ResolveLiveKitNativeModuleSpecifier}: the test override, else `LIVEKIT_NATIVE_MODULE`, else the default
|
|
240
|
+
* `@memberjunction/ai-bridge-livekit-native`). Overridable in tests via {@link SetNativeModuleSpecifier}.
|
|
155
241
|
*/
|
|
156
242
|
private resolveNativeModuleSpecifier;
|
|
157
243
|
/**
|
|
@@ -185,5 +271,16 @@ export declare class LiveKitAgentRoomCoordinator extends BaseSingleton<LiveKitAg
|
|
|
185
271
|
* @returns The number of agent sessions asked to stop (0 when the room held no agents).
|
|
186
272
|
*/
|
|
187
273
|
StopAllAgentsInRoom(roomName: string, reason?: BridgeDisconnectReason, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<number>;
|
|
274
|
+
/**
|
|
275
|
+
* Looks up the room name associated with a session bridge ID if present in the coordinator's active rosters.
|
|
276
|
+
*
|
|
277
|
+
* @param sessionBridgeID The `MJ: AI Agent Session Bridges` row id.
|
|
278
|
+
* @returns The room name, or `undefined` if not tracked in the active rosters.
|
|
279
|
+
*/
|
|
280
|
+
GetRoomForBridge(sessionBridgeID: string): string | undefined;
|
|
281
|
+
/**
|
|
282
|
+
* Returns the agent sessions currently active in the given room.
|
|
283
|
+
*/
|
|
284
|
+
GetAgentsInRoom(roomName: string): ReadonlyArray<RoomAgentEntry>;
|
|
188
285
|
}
|
|
189
286
|
//# sourceMappingURL=livekit-agent-room-coordinator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livekit-agent-room-coordinator.d.ts","sourceRoot":"","sources":["../src/livekit-agent-room-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAuB,KAAK,iBAAiB,EAAE,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"livekit-agent-room-coordinator.d.ts","sourceRoot":"","sources":["../src/livekit-agent-room-coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { BaseSingleton } from '@memberjunction/global';
|
|
16
16
|
import { LogError, LogStatus } from '@memberjunction/core';
|
|
17
|
-
import { AlwaysAddressedMatcher, RegexAddressedMatcher } from '@memberjunction/ai-bridge-base';
|
|
18
|
-
import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
|
|
17
|
+
import { AlwaysAddressedMatcher, RegexAddressedMatcher, TURN_TAKING_TOOL_DEFINITIONS, } from '@memberjunction/ai-bridge-base';
|
|
18
|
+
import { AIBridgeEngine, } from '@memberjunction/ai-bridge-server';
|
|
19
19
|
import { LiveKitTokenService } from './livekit-token-service.js';
|
|
20
|
+
import { ResolveLiveKitNativeModuleSpecifier } from './livekit-native-module.js';
|
|
20
21
|
/** The `DriverClass` the LiveKit bridge registers under (must match the `MJ: AI Bridge Providers` row). */
|
|
21
22
|
export const LIVEKIT_BRIDGE_DRIVER_CLASS = 'LiveKitBridge';
|
|
22
23
|
/**
|
|
@@ -39,6 +40,7 @@ export class LiveKitAgentRoomCoordinator extends BaseSingleton {
|
|
|
39
40
|
*/
|
|
40
41
|
this.roomRosters = new Map();
|
|
41
42
|
this.bridgeOps = AIBridgeEngine.Instance;
|
|
43
|
+
this.turnStateSource = (roomKey) => AIBridgeEngine.Instance.GetRoomTurnSnapshot(roomKey);
|
|
42
44
|
this.sessionFactory = () => {
|
|
43
45
|
throw new Error('LiveKitAgentRoomCoordinator has no realtime-session factory bound. Call SetSessionFactory(...) ' +
|
|
44
46
|
'with a factory that resolves a BaseRealtimeModel and returns an IRealtimeSession (see @memberjunction/ai-agents), ' +
|
|
@@ -57,6 +59,35 @@ export class LiveKitAgentRoomCoordinator extends BaseSingleton {
|
|
|
57
59
|
SetSessionFactory(factory) {
|
|
58
60
|
this.sessionFactory = factory;
|
|
59
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Binds the seam that installs the engine's turn-taking tool handler on a model session. Without it a
|
|
64
|
+
* full-duplex model's `i_am_addressed` / `yield_turn` calls cannot be executed (the room's floor gate still
|
|
65
|
+
* protects against overlap; the model just cannot reserve the floor or hand it to a named agent).
|
|
66
|
+
*
|
|
67
|
+
* @param binder The binder, or `undefined` to clear it.
|
|
68
|
+
*/
|
|
69
|
+
SetTurnToolBinder(binder) {
|
|
70
|
+
this.turnToolBinder = binder;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Overrides where a room's turn-taking snapshot comes from (an injectable seam for unit testing; production
|
|
74
|
+
* reads the process-wide {@link AIBridgeEngine}).
|
|
75
|
+
*
|
|
76
|
+
* @param source Returns the snapshot for a room key, or `null` when the room holds no agents.
|
|
77
|
+
*/
|
|
78
|
+
SetTurnStateSource(source) {
|
|
79
|
+
this.turnStateSource = source;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A room's live turn-taking state — floor holder, whether a person is speaking, any pending hand-off, the
|
|
83
|
+
* agent-to-agent loop-cap progress, the most recent floor events, and who is seated. Read-only.
|
|
84
|
+
*
|
|
85
|
+
* @param roomName The LiveKit room name (the bridge's room key).
|
|
86
|
+
* @returns The snapshot, or `null` when the room holds no agents.
|
|
87
|
+
*/
|
|
88
|
+
GetRoomTurnState(roomName) {
|
|
89
|
+
return this.turnStateSource(roomName.trim());
|
|
90
|
+
}
|
|
60
91
|
/**
|
|
61
92
|
* Overrides the token service used to mint the bot token (e.g. to inject explicit credentials).
|
|
62
93
|
*
|
|
@@ -106,28 +137,54 @@ export class LiveKitAgentRoomCoordinator extends BaseSingleton {
|
|
|
106
137
|
// (gated meeting mode + LLM router) for controlled scenarios (webinars, large rooms, weaker models).
|
|
107
138
|
const moderatorMode = process.env.MJ_REALTIME_MODERATOR_MODE === 'on';
|
|
108
139
|
const isMeeting = moderatorMode && existingAgents.length > 0;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
140
|
+
// A full-duplex model judges for itself whether it was addressed and uses the turn-taking tools; a gated
|
|
141
|
+
// meeting (moderator mode) decides addressing by name in the engine, so the tools would only confuse it.
|
|
142
|
+
const addressing = isMeeting ? 'Regex' : params.TurnAddressing ?? 'Auto';
|
|
143
|
+
const host = params.Host;
|
|
144
|
+
const turnTakingTools = addressing === 'Regex' ? [] : [...TURN_TAKING_TOOL_DEFINITIONS];
|
|
145
|
+
const combinedHostTools = (host?.HostTools?.length ?? 0) > 0 || turnTakingTools.length > 0
|
|
146
|
+
? [...(host?.HostTools ?? []), ...turnTakingTools]
|
|
147
|
+
: undefined;
|
|
148
|
+
let activeTurnHandler = undefined;
|
|
149
|
+
const openModelSession = async (priorTranscript) => {
|
|
150
|
+
const opened = await this.sessionFactory({
|
|
151
|
+
AgentID: params.AgentID,
|
|
152
|
+
AgentName: params.AgentName,
|
|
153
|
+
TargetAgentID: params.TargetAgentID,
|
|
154
|
+
RealtimeModelID: params.RealtimeModelID,
|
|
155
|
+
RealtimeVoice: params.RealtimeVoice,
|
|
156
|
+
RoomName: params.RoomName,
|
|
157
|
+
ContextUser: params.ContextUser,
|
|
158
|
+
MetadataProvider: params.MetadataProvider,
|
|
159
|
+
// So the co-agent observability run groups under THIS agent session (parity with native chat).
|
|
160
|
+
AgentSessionID: params.AgentSessionID,
|
|
161
|
+
MeetingMode: isMeeting || undefined,
|
|
162
|
+
SelfNames: isMeeting ? selfNames : undefined,
|
|
163
|
+
HostTools: combinedHostTools,
|
|
164
|
+
HostFraming: host?.HostFraming,
|
|
165
|
+
ConversationID: host?.ConversationID,
|
|
166
|
+
PriorTranscript: priorTranscript,
|
|
167
|
+
});
|
|
168
|
+
host?.OnModelSession?.(opened);
|
|
169
|
+
if (activeTurnHandler) {
|
|
170
|
+
this.bindTurnTools(opened, activeTurnHandler, botName);
|
|
171
|
+
}
|
|
172
|
+
return opened;
|
|
173
|
+
};
|
|
174
|
+
const session = await openModelSession();
|
|
175
|
+
// The bridge id is known only after the engine starts the session, but the end-of-session hook is registered at start,
|
|
176
|
+
// so it reaches the id through this holder.
|
|
177
|
+
const started = {};
|
|
123
178
|
const active = await this.bridgeOps.StartBridgeSession({
|
|
124
179
|
AgentSessionID: params.AgentSessionID,
|
|
125
180
|
AgentID: params.AgentID,
|
|
126
181
|
Provider: provider,
|
|
127
182
|
RealtimeSession: session,
|
|
128
183
|
Address: botToken.ServerUrl,
|
|
129
|
-
JoinMethod: 'OnDemand',
|
|
184
|
+
JoinMethod: host?.JoinMethod ?? 'OnDemand',
|
|
185
|
+
Direction: host?.Direction,
|
|
130
186
|
TurnMode: params.TurnMode ?? 'Passive',
|
|
187
|
+
TurnAddressing: addressing,
|
|
131
188
|
// Meeting: gate speech to ADDRESSED turns (RegexAddressedMatcher on the agent's names) AND tell the
|
|
132
189
|
// engine the model's auto-response is off so the bridge becomes the sole trigger. Solo 1:1: respond to
|
|
133
190
|
// ALL the user's speech (AlwaysAddressedMatcher) with the model's own auto-response — Passive's
|
|
@@ -153,8 +210,22 @@ export class LiveKitAgentRoomCoordinator extends BaseSingleton {
|
|
|
153
210
|
},
|
|
154
211
|
ContextUser: params.ContextUser,
|
|
155
212
|
MetadataProvider: params.MetadataProvider,
|
|
213
|
+
// Host-owned call: its own transcript, barge-in policy, model recovery and end-of-session bookkeeping.
|
|
214
|
+
TranscriptSink: host?.TranscriptSink,
|
|
215
|
+
OnBargeIn: host?.OnBargeIn,
|
|
216
|
+
RecoverRealtimeSession: host?.RecoverModelSession ? (request) => openModelSession(request.PriorTranscript) : undefined,
|
|
217
|
+
OnSessionEnded: async (reason) => {
|
|
218
|
+
// An agent that leaves on its own (every human gone, the model lost, a handoff) must drop off the room's roster too.
|
|
219
|
+
if (started.SessionBridgeID) {
|
|
220
|
+
this.removeFromRoster(started.SessionBridgeID);
|
|
221
|
+
}
|
|
222
|
+
await host?.OnSessionEnded?.(reason);
|
|
223
|
+
},
|
|
156
224
|
});
|
|
225
|
+
started.SessionBridgeID = active.SessionBridgeID;
|
|
157
226
|
this.addToRoster(roomKey, { AgentSessionID: params.AgentSessionID, SessionBridgeID: active.SessionBridgeID, Names: selfNames });
|
|
227
|
+
activeTurnHandler = active.TurnTakingToolHandler;
|
|
228
|
+
this.bindTurnTools(session, active.TurnTakingToolHandler, botName);
|
|
158
229
|
// The room just became (or stayed) multi-agent → retroactively re-gate the agents already in it into
|
|
159
230
|
// meeting mode so the whole room takes turns, not just the newcomers. Capability-gated in the engine:
|
|
160
231
|
// a provider that can't reconfigure a live session (e.g. Gemini) is left conversational, no dead call.
|
|
@@ -168,6 +239,18 @@ export class LiveKitAgentRoomCoordinator extends BaseSingleton {
|
|
|
168
239
|
`(bridge ${active.SessionBridgeID}, ${isMeeting ? 'MEETING — addressed-only' : 'solo 1:1'})`);
|
|
169
240
|
return { SessionBridgeID: active.SessionBridgeID, RoomName: params.RoomName, ServerUrl: botToken.ServerUrl };
|
|
170
241
|
}
|
|
242
|
+
/** Installs the engine's turn-taking tool handler on the model session, when the session has one (a full-duplex model in a room). */
|
|
243
|
+
bindTurnTools(session, handler, botName) {
|
|
244
|
+
if (!handler) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (!this.turnToolBinder) {
|
|
248
|
+
LogError(`[LiveKitAgentRoomCoordinator] ${botName} is full-duplex but no turn-tool binder is set (SetTurnToolBinder); ` +
|
|
249
|
+
'its i_am_addressed / yield_turn calls will not execute. The room floor gate still prevents overlap.');
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
this.turnToolBinder(session, handler);
|
|
253
|
+
}
|
|
171
254
|
/** Appends an agent to a room's roster (creating the room's list on first join). */
|
|
172
255
|
addToRoster(roomKey, entry) {
|
|
173
256
|
const roster = this.roomRosters.get(roomKey);
|
|
@@ -194,17 +277,13 @@ export class LiveKitAgentRoomCoordinator extends BaseSingleton {
|
|
|
194
277
|
return;
|
|
195
278
|
}
|
|
196
279
|
}
|
|
197
|
-
/** The default native room-client wrapper specifier — the @livekit/rtc-node package this repo ships. */
|
|
198
|
-
static { this.DEFAULT_NATIVE_MODULE = '@memberjunction/ai-bridge-livekit-native'; }
|
|
199
280
|
/**
|
|
200
|
-
* Resolves the native LiveKit room-client module specifier for the bridge session
|
|
201
|
-
*
|
|
202
|
-
*
|
|
281
|
+
* Resolves the native LiveKit room-client module specifier for the bridge session (see
|
|
282
|
+
* {@link ResolveLiveKitNativeModuleSpecifier}: the test override, else `LIVEKIT_NATIVE_MODULE`, else the default
|
|
283
|
+
* `@memberjunction/ai-bridge-livekit-native`). Overridable in tests via {@link SetNativeModuleSpecifier}.
|
|
203
284
|
*/
|
|
204
285
|
resolveNativeModuleSpecifier() {
|
|
205
|
-
return (this.nativeModuleSpecifierOverride
|
|
206
|
-
process.env.LIVEKIT_NATIVE_MODULE ??
|
|
207
|
-
LiveKitAgentRoomCoordinator.DEFAULT_NATIVE_MODULE);
|
|
286
|
+
return ResolveLiveKitNativeModuleSpecifier(this.nativeModuleSpecifierOverride);
|
|
208
287
|
}
|
|
209
288
|
/**
|
|
210
289
|
* Overrides the native room-client module specifier (primarily for unit testing — production resolves it
|
|
@@ -256,5 +335,26 @@ export class LiveKitAgentRoomCoordinator extends BaseSingleton {
|
|
|
256
335
|
await Promise.all(bridgeIDs.map((id) => this.StopAgentRoomSession(id, reason, contextUser, provider)));
|
|
257
336
|
return bridgeIDs.length;
|
|
258
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Looks up the room name associated with a session bridge ID if present in the coordinator's active rosters.
|
|
340
|
+
*
|
|
341
|
+
* @param sessionBridgeID The `MJ: AI Agent Session Bridges` row id.
|
|
342
|
+
* @returns The room name, or `undefined` if not tracked in the active rosters.
|
|
343
|
+
*/
|
|
344
|
+
GetRoomForBridge(sessionBridgeID) {
|
|
345
|
+
for (const [roomKey, roster] of this.roomRosters) {
|
|
346
|
+
if (roster.some((e) => e.SessionBridgeID === sessionBridgeID)) {
|
|
347
|
+
return roomKey;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return undefined;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Returns the agent sessions currently active in the given room.
|
|
354
|
+
*/
|
|
355
|
+
GetAgentsInRoom(roomName) {
|
|
356
|
+
const roomKey = roomName.trim().toLowerCase();
|
|
357
|
+
return this.roomRosters.get(roomKey) ?? [];
|
|
358
|
+
}
|
|
259
359
|
}
|
|
260
360
|
//# sourceMappingURL=livekit-agent-room-coordinator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livekit-agent-room-coordinator.js","sourceRoot":"","sources":["../src/livekit-agent-room-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAyC,MAAM,sBAAsB,CAAC;AAElG,OAAO,
|
|
1
|
+
{"version":3,"file":"livekit-agent-room-coordinator.js","sourceRoot":"","sources":["../src/livekit-agent-room-coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -76,6 +76,13 @@ export declare class LiveKitEgressService {
|
|
|
76
76
|
* @returns The active recordings.
|
|
77
77
|
*/
|
|
78
78
|
ListActiveRecordings(roomName: string): Promise<RecordingInfo[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Looks up the room name for an egress id.
|
|
81
|
+
*
|
|
82
|
+
* @param egressId The egress id to query.
|
|
83
|
+
* @returns The room name, or `undefined` if not found.
|
|
84
|
+
*/
|
|
85
|
+
GetRoomForEgress(egressId: string): Promise<string | undefined>;
|
|
79
86
|
/** Maps an SDK `EgressInfo` to the normalized {@link RecordingInfo}. */
|
|
80
87
|
private toRecordingInfo;
|
|
81
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livekit-egress-service.d.ts","sourceRoot":"","sources":["../src/livekit-egress-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAuD,MAAM,oBAAoB,CAAC;AACvG,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAExF,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mGAAmG;AACnG,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,0BAA0B,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;AAE5G,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qEAAqE;AACrE,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C;;;;;OAKG;gBACS,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB;IAM5E;;;;;OAKG;IACU,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;IAOrF;;;;;OAKG;IACU,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAKpE;;;;;OAKG;IACU,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAK7E,wEAAwE;IACxE,OAAO,CAAC,eAAe;CAuBxB"}
|
|
1
|
+
{"version":3,"file":"livekit-egress-service.d.ts","sourceRoot":"","sources":["../src/livekit-egress-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAuD,MAAM,oBAAoB,CAAC;AACvG,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAExF,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mGAAmG;AACnG,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,0BAA0B,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;AAE5G,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qEAAqE;AACrE,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C;;;;;OAKG;gBACS,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB;IAM5E;;;;;OAKG;IACU,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;IAOrF;;;;;OAKG;IACU,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAKpE;;;;;OAKG;IACU,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAK7E;;;;;OAKG;IACU,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAM5E,wEAAwE;IACxE,OAAO,CAAC,eAAe;CAuBxB"}
|