flow-agent-bridge 0.30.0 → 0.32.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/README.md +26 -2
- package/dist/api.d.ts +5 -1
- package/dist/api.js +10 -0
- package/dist/api.js.map +1 -1
- package/dist/bridge.d.ts +7 -1
- package/dist/bridge.js +80 -3
- package/dist/bridge.js.map +1 -1
- package/dist/config.d.ts +21 -1
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -1
- package/dist/huddle-voice.d.ts +104 -0
- package/dist/huddle-voice.js +449 -0
- package/dist/huddle-voice.js.map +1 -0
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.js +7 -5
- package/dist/runtime.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { WebSocket } from 'ws';
|
|
2
|
+
import type { HuddleInviteData, HuddleJoinDTO, HuddleUpdatedData, MessageDTO } from '@flow/shared';
|
|
3
|
+
import type { VoiceConfig } from './config.js';
|
|
4
|
+
export interface HuddleVoiceApi {
|
|
5
|
+
acceptHuddleInvite(inviteId: string): Promise<HuddleJoinDTO>;
|
|
6
|
+
declineHuddleInvite(inviteId: string): Promise<unknown>;
|
|
7
|
+
leaveHuddle(channelId: string): Promise<unknown>;
|
|
8
|
+
sendMessage(channelId: string, body: string): Promise<MessageDTO>;
|
|
9
|
+
}
|
|
10
|
+
export interface LiveVoiceSession {
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export interface LiveVoiceSessionOptions {
|
|
14
|
+
url: string;
|
|
15
|
+
token: string;
|
|
16
|
+
callerId: string;
|
|
17
|
+
callerName: string;
|
|
18
|
+
agentName: string;
|
|
19
|
+
instructions: string;
|
|
20
|
+
inferenceToken: string;
|
|
21
|
+
config: VoiceConfig;
|
|
22
|
+
runTurn(options: VoiceRuntimeTurnOptions): Promise<VoiceRuntimeTurnResult>;
|
|
23
|
+
onEnded(): void;
|
|
24
|
+
log(message: string): void;
|
|
25
|
+
}
|
|
26
|
+
export interface VoiceRuntimeTurnOptions {
|
|
27
|
+
/** Latest caller utterance, used by resumable runtimes such as Claude. */
|
|
28
|
+
prompt: string;
|
|
29
|
+
/** Complete in-call transcript, used by stateless runtimes such as Codex. */
|
|
30
|
+
transcript: string;
|
|
31
|
+
signal: AbortSignal;
|
|
32
|
+
onText(text: string): void;
|
|
33
|
+
}
|
|
34
|
+
export interface VoiceRuntimeTurnResult {
|
|
35
|
+
ok: boolean;
|
|
36
|
+
text: string;
|
|
37
|
+
error?: string;
|
|
38
|
+
interrupted?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface VoiceTranscriptMessage {
|
|
41
|
+
role: 'developer' | 'system' | 'user' | 'assistant';
|
|
42
|
+
text: string;
|
|
43
|
+
}
|
|
44
|
+
/** Convert LiveKit's call history into inputs for resumable and stateless CLIs. */
|
|
45
|
+
export declare function buildVoiceRuntimeInput(messages: readonly VoiceTranscriptMessage[], callerName: string, agentName: string): {
|
|
46
|
+
prompt: string;
|
|
47
|
+
transcript: string;
|
|
48
|
+
} | null;
|
|
49
|
+
export type LiveVoiceSessionFactory = (options: LiveVoiceSessionOptions) => Promise<LiveVoiceSession>;
|
|
50
|
+
export interface HuddleVoiceManagerOptions {
|
|
51
|
+
api: HuddleVoiceApi;
|
|
52
|
+
agentId: string;
|
|
53
|
+
agentName: string;
|
|
54
|
+
config: VoiceConfig;
|
|
55
|
+
callerName(userId: string): string;
|
|
56
|
+
isOneToOneDm(channelId: string): Promise<boolean>;
|
|
57
|
+
buildInstructions(channelId: string, callerId: string): Promise<string>;
|
|
58
|
+
runTurn(options: VoiceRuntimeTurnOptions & {
|
|
59
|
+
sessionId: string;
|
|
60
|
+
resume: boolean;
|
|
61
|
+
systemPrompt: string;
|
|
62
|
+
}): Promise<VoiceRuntimeTurnResult & {
|
|
63
|
+
sawSession?: boolean;
|
|
64
|
+
}>;
|
|
65
|
+
log(message: string): void;
|
|
66
|
+
sessionFactory?: LiveVoiceSessionFactory | undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Turns the existing DM ring into a real bot call. The server remains the
|
|
70
|
+
* source of truth for invite and roster state; this class just performs the
|
|
71
|
+
* same accept / join / leave operations as a human client, then attaches a
|
|
72
|
+
* realtime audio participant to the minted LiveKit room token. Speech uses a
|
|
73
|
+
* short-lived inference grant from Flow; reasoning uses the bridge's existing
|
|
74
|
+
* Claude/Codex runtime login.
|
|
75
|
+
*/
|
|
76
|
+
export declare class HuddleVoiceManager {
|
|
77
|
+
private readonly options;
|
|
78
|
+
private active;
|
|
79
|
+
private acceptingInviteId;
|
|
80
|
+
private stopping;
|
|
81
|
+
private readonly terminalInvites;
|
|
82
|
+
private readonly handledInvites;
|
|
83
|
+
private readonly sessionFactory;
|
|
84
|
+
constructor(options: HuddleVoiceManagerOptions);
|
|
85
|
+
get activeChannelId(): string | null;
|
|
86
|
+
handleInvite(data: HuddleInviteData): Promise<void>;
|
|
87
|
+
handleRoster(data: HuddleUpdatedData): Promise<void>;
|
|
88
|
+
stop(): Promise<void>;
|
|
89
|
+
private declineWithMessage;
|
|
90
|
+
private sessionEnded;
|
|
91
|
+
private endActive;
|
|
92
|
+
private leaveQuietly;
|
|
93
|
+
private rememberHandled;
|
|
94
|
+
private rememberTerminal;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Production session adapter. Imports are deliberately lazy: a text-only
|
|
98
|
+
* bridge can start without loading LiveKit's native RTC binding. Audio uses
|
|
99
|
+
* LiveKit Inference with a short-lived server-minted grant; the LLM below is
|
|
100
|
+
* the bridge's already-authenticated Claude/Codex CLI runtime.
|
|
101
|
+
*/
|
|
102
|
+
export declare function createLiveKitVoiceSession(options: LiveVoiceSessionOptions): Promise<LiveVoiceSession>;
|
|
103
|
+
/** Connect to LiveKit Inference without ever holding the project API secret. */
|
|
104
|
+
export declare function connectInferenceWebSocket(baseUrl: string, path: '/stt' | '/tts', token: string, timeout: number, session: Record<string, unknown>): Promise<WebSocket>;
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { WebSocket } from 'ws';
|
|
3
|
+
const TERMINAL_INVITE_STATES = new Set(['ended', 'declined', 'missed', 'cancelled']);
|
|
4
|
+
let liveKitLoggerInitialized = false;
|
|
5
|
+
/** Convert LiveKit's call history into inputs for resumable and stateless CLIs. */
|
|
6
|
+
export function buildVoiceRuntimeInput(messages, callerName, agentName) {
|
|
7
|
+
const conversational = messages.filter((message) => (message.role === 'user' || message.role === 'assistant') && message.text.trim().length > 0);
|
|
8
|
+
const latestUser = [...conversational]
|
|
9
|
+
.reverse()
|
|
10
|
+
.find((message) => message.role === 'user')
|
|
11
|
+
?.text.trim();
|
|
12
|
+
if (!latestUser)
|
|
13
|
+
return null;
|
|
14
|
+
return {
|
|
15
|
+
prompt: latestUser,
|
|
16
|
+
transcript: conversational
|
|
17
|
+
.map((message) => `${message.role === 'user' ? callerName : agentName}: ${message.text.trim()}`)
|
|
18
|
+
.join('\n'),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Turns the existing DM ring into a real bot call. The server remains the
|
|
23
|
+
* source of truth for invite and roster state; this class just performs the
|
|
24
|
+
* same accept / join / leave operations as a human client, then attaches a
|
|
25
|
+
* realtime audio participant to the minted LiveKit room token. Speech uses a
|
|
26
|
+
* short-lived inference grant from Flow; reasoning uses the bridge's existing
|
|
27
|
+
* Claude/Codex runtime login.
|
|
28
|
+
*/
|
|
29
|
+
export class HuddleVoiceManager {
|
|
30
|
+
options;
|
|
31
|
+
active = null;
|
|
32
|
+
acceptingInviteId = null;
|
|
33
|
+
stopping = false;
|
|
34
|
+
terminalInvites = new Set();
|
|
35
|
+
handledInvites = new Set();
|
|
36
|
+
sessionFactory;
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.options = options;
|
|
39
|
+
this.sessionFactory = options.sessionFactory ?? createLiveKitVoiceSession;
|
|
40
|
+
}
|
|
41
|
+
get activeChannelId() {
|
|
42
|
+
return this.active?.channelId ?? null;
|
|
43
|
+
}
|
|
44
|
+
async handleInvite(data) {
|
|
45
|
+
if (this.stopping)
|
|
46
|
+
return;
|
|
47
|
+
const { invite } = data;
|
|
48
|
+
const target = invite.targets.find((row) => row.userId === this.options.agentId);
|
|
49
|
+
if (!target || invite.startedBy === this.options.agentId)
|
|
50
|
+
return;
|
|
51
|
+
if (TERMINAL_INVITE_STATES.has(invite.status)) {
|
|
52
|
+
this.rememberTerminal(invite.id);
|
|
53
|
+
if (this.active?.inviteId === invite.id)
|
|
54
|
+
await this.endActive(`invite ${invite.status}`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// The active update after our accept has target=accepted; it is state
|
|
58
|
+
// confirmation, not a second ring.
|
|
59
|
+
if (invite.status !== 'ringing' || target.status !== 'ringing')
|
|
60
|
+
return;
|
|
61
|
+
if (this.handledInvites.has(invite.id))
|
|
62
|
+
return;
|
|
63
|
+
this.rememberHandled(invite.id);
|
|
64
|
+
if (this.acceptingInviteId || this.active) {
|
|
65
|
+
await this.declineWithMessage(invite.id, invite.channelId, `📞 I’m already in another huddle. Try calling me again after it ends.`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (!this.options.config.enabled) {
|
|
69
|
+
await this.declineWithMessage(invite.id, invite.channelId, `📞 Voice huddles are turned off for me. Set \`voice.enabled\` to \`true\` in my bridge config and restart me.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Reserve the one call slot before the asynchronous directory lookup. Two
|
|
73
|
+
// different rings can arrive on the socket in the same event-loop turn.
|
|
74
|
+
this.acceptingInviteId = invite.id;
|
|
75
|
+
let joined = false;
|
|
76
|
+
try {
|
|
77
|
+
if (!(await this.options.isOneToOneDm(invite.channelId))) {
|
|
78
|
+
await this.declineWithMessage(invite.id, invite.channelId, `📞 I can answer one-to-one Huddles right now, but not group calls yet. Open a DM with me and call from there.`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (this.stopping || this.terminalInvites.has(invite.id))
|
|
82
|
+
return;
|
|
83
|
+
// Accept first so the caller stops hearing a ring immediately. Context
|
|
84
|
+
// loading and model connection happen while both users are in the room.
|
|
85
|
+
const room = await this.options.api.acceptHuddleInvite(invite.id);
|
|
86
|
+
joined = true;
|
|
87
|
+
if (this.stopping || this.terminalInvites.has(invite.id)) {
|
|
88
|
+
await this.leaveQuietly(invite.channelId);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const instructions = await this.options.buildInstructions(invite.channelId, invite.startedBy);
|
|
92
|
+
if (this.stopping || this.terminalInvites.has(invite.id)) {
|
|
93
|
+
await this.leaveQuietly(invite.channelId);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!room.inferenceToken?.trim()) {
|
|
97
|
+
throw new Error('Flow server did not provide an agent inference token; update the server and bridge together');
|
|
98
|
+
}
|
|
99
|
+
const runtimeSessionId = randomUUID();
|
|
100
|
+
let runtimeStarted = false;
|
|
101
|
+
let endedDuringStart = false;
|
|
102
|
+
const session = await this.sessionFactory({
|
|
103
|
+
url: room.url,
|
|
104
|
+
token: room.token,
|
|
105
|
+
callerId: invite.startedBy,
|
|
106
|
+
callerName: this.options.callerName(invite.startedBy),
|
|
107
|
+
agentName: this.options.agentName,
|
|
108
|
+
instructions,
|
|
109
|
+
inferenceToken: room.inferenceToken,
|
|
110
|
+
config: this.options.config,
|
|
111
|
+
runTurn: async (turn) => {
|
|
112
|
+
const result = await this.options.runTurn({
|
|
113
|
+
...turn,
|
|
114
|
+
sessionId: runtimeSessionId,
|
|
115
|
+
resume: runtimeStarted,
|
|
116
|
+
systemPrompt: instructions,
|
|
117
|
+
});
|
|
118
|
+
if (result.ok || result.sawSession)
|
|
119
|
+
runtimeStarted = true;
|
|
120
|
+
return result;
|
|
121
|
+
},
|
|
122
|
+
onEnded: () => {
|
|
123
|
+
endedDuringStart = true;
|
|
124
|
+
void this.sessionEnded(invite.id);
|
|
125
|
+
},
|
|
126
|
+
log: this.options.log,
|
|
127
|
+
});
|
|
128
|
+
if (endedDuringStart || this.stopping || this.terminalInvites.has(invite.id)) {
|
|
129
|
+
await session.close().catch(() => undefined);
|
|
130
|
+
await this.leaveQuietly(invite.channelId);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this.active = {
|
|
134
|
+
inviteId: invite.id,
|
|
135
|
+
channelId: invite.channelId,
|
|
136
|
+
callerId: invite.startedBy,
|
|
137
|
+
session,
|
|
138
|
+
};
|
|
139
|
+
this.options.log(`answered huddle from ${this.options.callerName(invite.startedBy)}`);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
this.options.log(`could not start huddle voice: ${errorText(error)}`);
|
|
143
|
+
if (joined)
|
|
144
|
+
await this.leaveQuietly(invite.channelId);
|
|
145
|
+
if (joined && !this.stopping && !this.terminalInvites.has(invite.id)) {
|
|
146
|
+
await this.options.api
|
|
147
|
+
.sendMessage(invite.channelId, `📞 I answered, but my voice connection couldn’t start. Check the bridge voice configuration and logs, then call me again.`)
|
|
148
|
+
.catch((sendError) => this.options.log(`could not post voice failure: ${errorText(sendError)}`));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
if (this.acceptingInviteId === invite.id)
|
|
153
|
+
this.acceptingInviteId = null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async handleRoster(data) {
|
|
157
|
+
const active = this.active;
|
|
158
|
+
if (!active || active.channelId !== data.channelId)
|
|
159
|
+
return;
|
|
160
|
+
const ids = new Set(data.participants.map((participant) => participant.userId));
|
|
161
|
+
if (!ids.has(this.options.agentId) || !ids.has(active.callerId)) {
|
|
162
|
+
await this.endActive(!ids.has(active.callerId) ? 'caller left' : 'agent left');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async stop() {
|
|
166
|
+
this.stopping = true;
|
|
167
|
+
await this.endActive('bridge stopping');
|
|
168
|
+
}
|
|
169
|
+
async declineWithMessage(inviteId, channelId, message) {
|
|
170
|
+
await this.options.api
|
|
171
|
+
.declineHuddleInvite(inviteId)
|
|
172
|
+
.catch((error) => this.options.log(`could not decline huddle: ${errorText(error)}`));
|
|
173
|
+
await this.options.api
|
|
174
|
+
.sendMessage(channelId, message)
|
|
175
|
+
.catch((error) => this.options.log(`could not post huddle status: ${errorText(error)}`));
|
|
176
|
+
}
|
|
177
|
+
async sessionEnded(inviteId) {
|
|
178
|
+
const active = this.active;
|
|
179
|
+
if (!active || active.inviteId !== inviteId)
|
|
180
|
+
return;
|
|
181
|
+
this.active = null;
|
|
182
|
+
await this.leaveQuietly(active.channelId);
|
|
183
|
+
this.options.log('huddle voice session ended');
|
|
184
|
+
}
|
|
185
|
+
async endActive(reason) {
|
|
186
|
+
const active = this.active;
|
|
187
|
+
if (!active)
|
|
188
|
+
return;
|
|
189
|
+
this.active = null;
|
|
190
|
+
this.options.log(`ending huddle voice (${reason})`);
|
|
191
|
+
await active.session.close().catch((error) => this.options.log(`voice close failed: ${errorText(error)}`));
|
|
192
|
+
await this.leaveQuietly(active.channelId);
|
|
193
|
+
}
|
|
194
|
+
async leaveQuietly(channelId) {
|
|
195
|
+
await this.options.api
|
|
196
|
+
.leaveHuddle(channelId)
|
|
197
|
+
.catch((error) => this.options.log(`could not leave huddle: ${errorText(error)}`));
|
|
198
|
+
}
|
|
199
|
+
rememberHandled(inviteId) {
|
|
200
|
+
this.handledInvites.add(inviteId);
|
|
201
|
+
if (this.handledInvites.size <= 256)
|
|
202
|
+
return;
|
|
203
|
+
const oldest = this.handledInvites.values().next().value;
|
|
204
|
+
if (oldest)
|
|
205
|
+
this.handledInvites.delete(oldest);
|
|
206
|
+
}
|
|
207
|
+
rememberTerminal(inviteId) {
|
|
208
|
+
this.terminalInvites.add(inviteId);
|
|
209
|
+
if (this.terminalInvites.size <= 256)
|
|
210
|
+
return;
|
|
211
|
+
const oldest = this.terminalInvites.values().next().value;
|
|
212
|
+
if (oldest)
|
|
213
|
+
this.terminalInvites.delete(oldest);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Production session adapter. Imports are deliberately lazy: a text-only
|
|
218
|
+
* bridge can start without loading LiveKit's native RTC binding. Audio uses
|
|
219
|
+
* LiveKit Inference with a short-lived server-minted grant; the LLM below is
|
|
220
|
+
* the bridge's already-authenticated Claude/Codex CLI runtime.
|
|
221
|
+
*/
|
|
222
|
+
export async function createLiveKitVoiceSession(options) {
|
|
223
|
+
const [{ Room, RoomEvent }, agents] = await Promise.all([
|
|
224
|
+
import('@livekit/rtc-node'),
|
|
225
|
+
import('@livekit/agents'),
|
|
226
|
+
]);
|
|
227
|
+
const { inference, llm, voice } = agents;
|
|
228
|
+
if (!liveKitLoggerInitialized) {
|
|
229
|
+
agents.initializeLogger({ pretty: false, level: 'warn' });
|
|
230
|
+
liveKitLoggerInitialized = true;
|
|
231
|
+
}
|
|
232
|
+
/** Adapt the bridge's ordinary runtime contract to LiveKit's streaming LLM. */
|
|
233
|
+
class RuntimeLLM extends llm.LLM {
|
|
234
|
+
label() {
|
|
235
|
+
return 'flow.bridge-runtime';
|
|
236
|
+
}
|
|
237
|
+
get provider() {
|
|
238
|
+
return 'flow';
|
|
239
|
+
}
|
|
240
|
+
get model() {
|
|
241
|
+
return 'agent-bridge';
|
|
242
|
+
}
|
|
243
|
+
chat(args) {
|
|
244
|
+
return new RuntimeLLMStream(this, {
|
|
245
|
+
chatCtx: args.chatCtx,
|
|
246
|
+
...(args.toolCtx ? { toolCtx: args.toolCtx } : {}),
|
|
247
|
+
connOptions: args.connOptions ?? agents.DEFAULT_API_CONNECT_OPTIONS,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
class RuntimeLLMStream extends llm.LLMStream {
|
|
252
|
+
async run() {
|
|
253
|
+
const messages = this.chatCtx.items.filter((item) => item.type === 'message');
|
|
254
|
+
const input = buildVoiceRuntimeInput(messages.map((message) => ({ role: message.role, text: message.textContent ?? '' })), options.callerName, options.agentName);
|
|
255
|
+
if (!input)
|
|
256
|
+
return;
|
|
257
|
+
const responseId = `bridge-${randomUUID()}`;
|
|
258
|
+
let emitted = false;
|
|
259
|
+
let previous = '';
|
|
260
|
+
const emit = (text) => {
|
|
261
|
+
const clean = text.trim();
|
|
262
|
+
if (!clean || clean === previous || this.abortController.signal.aborted)
|
|
263
|
+
return;
|
|
264
|
+
previous = clean;
|
|
265
|
+
emitted = true;
|
|
266
|
+
this.queue.put({ id: responseId, delta: { role: 'assistant', content: `${clean} ` } });
|
|
267
|
+
};
|
|
268
|
+
const result = await options.runTurn({
|
|
269
|
+
prompt: input.prompt,
|
|
270
|
+
transcript: input.transcript,
|
|
271
|
+
signal: this.abortController.signal,
|
|
272
|
+
onText: emit,
|
|
273
|
+
});
|
|
274
|
+
if (this.abortController.signal.aborted || result.interrupted)
|
|
275
|
+
return;
|
|
276
|
+
if (!emitted && result.text.trim())
|
|
277
|
+
emit(result.text);
|
|
278
|
+
if (!result.ok) {
|
|
279
|
+
options.log(`voice runtime error: ${result.error ?? 'unknown'}`);
|
|
280
|
+
}
|
|
281
|
+
if (!emitted && !result.ok) {
|
|
282
|
+
emit('I hit a problem while working on that. Please try asking me again.');
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const baseUrl = options.config.inferenceUrl.replace(/\/+$/, '');
|
|
287
|
+
const connect = (path, timeout, session) => connectInferenceWebSocket(baseUrl, path, options.inferenceToken, timeout, session);
|
|
288
|
+
// The SDK normally mints an inference token from LIVEKIT_API_SECRET. Flow
|
|
289
|
+
// must never place that project secret on a bot host, so construct the
|
|
290
|
+
// stock streaming codecs and replace only their public WebSocket connector
|
|
291
|
+
// with one authenticated by the narrow, short-lived token from the server.
|
|
292
|
+
const speechToText = new inference.STT({
|
|
293
|
+
model: options.config.sttModel,
|
|
294
|
+
baseURL: baseUrl,
|
|
295
|
+
sampleRate: 16_000,
|
|
296
|
+
encoding: 'pcm_s16le',
|
|
297
|
+
apiKey: 'server-minted-token',
|
|
298
|
+
apiSecret: 'not-used-by-flow-bridge',
|
|
299
|
+
});
|
|
300
|
+
speechToText.connectWs = (timeout) => connect('/stt', timeout, {
|
|
301
|
+
type: 'session.create',
|
|
302
|
+
model: options.config.sttModel,
|
|
303
|
+
settings: { sample_rate: '16000', encoding: 'pcm_s16le', extra: {} },
|
|
304
|
+
connection: { timeout: timeout / 1000, retries: 3 },
|
|
305
|
+
});
|
|
306
|
+
const textToSpeech = new inference.TTS({
|
|
307
|
+
model: options.config.ttsModel,
|
|
308
|
+
voice: options.config.ttsVoice,
|
|
309
|
+
language: 'en',
|
|
310
|
+
baseURL: baseUrl,
|
|
311
|
+
sampleRate: 16_000,
|
|
312
|
+
encoding: 'pcm_s16le',
|
|
313
|
+
apiKey: 'server-minted-token',
|
|
314
|
+
apiSecret: 'not-used-by-flow-bridge',
|
|
315
|
+
});
|
|
316
|
+
textToSpeech.connectWs = (timeout) => connect('/tts', timeout, {
|
|
317
|
+
type: 'session.create',
|
|
318
|
+
model: options.config.ttsModel,
|
|
319
|
+
voice: options.config.ttsVoice,
|
|
320
|
+
language: 'en',
|
|
321
|
+
sample_rate: '16000',
|
|
322
|
+
encoding: 'pcm_s16le',
|
|
323
|
+
extra: {},
|
|
324
|
+
connection: { timeout: timeout / 1000, retries: 3 },
|
|
325
|
+
});
|
|
326
|
+
const room = new Room();
|
|
327
|
+
let closing = false;
|
|
328
|
+
let ended = false;
|
|
329
|
+
let limitTimer;
|
|
330
|
+
const emitEnded = () => {
|
|
331
|
+
if (ended)
|
|
332
|
+
return;
|
|
333
|
+
ended = true;
|
|
334
|
+
if (limitTimer)
|
|
335
|
+
clearTimeout(limitTimer);
|
|
336
|
+
options.onEnded();
|
|
337
|
+
};
|
|
338
|
+
await room.connect(options.url, options.token, { autoSubscribe: true, dynacast: true });
|
|
339
|
+
room.on(RoomEvent.Disconnected, emitEnded);
|
|
340
|
+
const session = new voice.AgentSession({
|
|
341
|
+
stt: speechToText,
|
|
342
|
+
llm: new RuntimeLLM(),
|
|
343
|
+
tts: textToSpeech,
|
|
344
|
+
vad: null,
|
|
345
|
+
userAwayTimeout: null,
|
|
346
|
+
turnHandling: {
|
|
347
|
+
turnDetection: 'stt',
|
|
348
|
+
interruption: { enabled: true },
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
session.on(voice.AgentSessionEventTypes.Error, (event) => {
|
|
352
|
+
options.log(`huddle voice error: ${errorText(event.error)}`);
|
|
353
|
+
});
|
|
354
|
+
session.on(voice.AgentSessionEventTypes.UserInputTranscribed, (event) => {
|
|
355
|
+
if (event.isFinal && event.transcript.trim())
|
|
356
|
+
options.log('heard final voice turn');
|
|
357
|
+
});
|
|
358
|
+
session.on(voice.AgentSessionEventTypes.Close, emitEnded);
|
|
359
|
+
try {
|
|
360
|
+
await session.start({
|
|
361
|
+
room,
|
|
362
|
+
agent: voice.Agent.create({ instructions: options.instructions }),
|
|
363
|
+
inputOptions: {
|
|
364
|
+
participantIdentity: options.callerId,
|
|
365
|
+
audioEnabled: true,
|
|
366
|
+
videoEnabled: false,
|
|
367
|
+
textEnabled: false,
|
|
368
|
+
closeOnDisconnect: true,
|
|
369
|
+
deleteRoomOnClose: false,
|
|
370
|
+
},
|
|
371
|
+
outputOptions: {
|
|
372
|
+
audioEnabled: true,
|
|
373
|
+
transcriptionEnabled: false,
|
|
374
|
+
},
|
|
375
|
+
// Flow promises that Huddles are not recorded. Keep LiveKit Agents'
|
|
376
|
+
// optional audio, trace, log, and transcript upload disabled as well.
|
|
377
|
+
record: false,
|
|
378
|
+
});
|
|
379
|
+
session.say(`Hey ${options.callerName}, I’m here.`, {
|
|
380
|
+
allowInterruptions: true,
|
|
381
|
+
addToChatCtx: true,
|
|
382
|
+
});
|
|
383
|
+
limitTimer = setTimeout(() => {
|
|
384
|
+
options.log(`ending huddle after ${options.config.maxSessionMinutes} minute limit`);
|
|
385
|
+
void session.close();
|
|
386
|
+
}, options.config.maxSessionMinutes * 60_000);
|
|
387
|
+
limitTimer.unref();
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
if (limitTimer)
|
|
391
|
+
clearTimeout(limitTimer);
|
|
392
|
+
await session.close().catch(() => undefined);
|
|
393
|
+
await room.disconnect().catch(() => undefined);
|
|
394
|
+
throw error;
|
|
395
|
+
}
|
|
396
|
+
return {
|
|
397
|
+
close: async () => {
|
|
398
|
+
if (closing)
|
|
399
|
+
return;
|
|
400
|
+
closing = true;
|
|
401
|
+
if (limitTimer)
|
|
402
|
+
clearTimeout(limitTimer);
|
|
403
|
+
await session.close().catch((error) => options.log(`agent session close failed: ${errorText(error)}`));
|
|
404
|
+
if (room.isConnected) {
|
|
405
|
+
await room.disconnect().catch((error) => options.log(`LiveKit disconnect failed: ${errorText(error)}`));
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
/** Connect to LiveKit Inference without ever holding the project API secret. */
|
|
411
|
+
export function connectInferenceWebSocket(baseUrl, path, token, timeout, session) {
|
|
412
|
+
const websocketUrl = `${baseUrl.replace(/^http/, 'ws')}${path}`;
|
|
413
|
+
return new Promise((resolve, reject) => {
|
|
414
|
+
const socket = new WebSocket(websocketUrl, { headers: { Authorization: `Bearer ${token}` } });
|
|
415
|
+
const timer = setTimeout(() => {
|
|
416
|
+
cleanup();
|
|
417
|
+
socket.terminate();
|
|
418
|
+
reject(new Error(`LiveKit inference ${path.slice(1)} connection timed out`));
|
|
419
|
+
}, timeout);
|
|
420
|
+
const cleanup = () => {
|
|
421
|
+
clearTimeout(timer);
|
|
422
|
+
socket.off('open', onOpen);
|
|
423
|
+
socket.off('error', onError);
|
|
424
|
+
};
|
|
425
|
+
const onOpen = () => {
|
|
426
|
+
cleanup();
|
|
427
|
+
try {
|
|
428
|
+
socket.send(JSON.stringify(session));
|
|
429
|
+
resolve(socket);
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
socket.terminate();
|
|
433
|
+
reject(error);
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
const onError = (error) => {
|
|
437
|
+
cleanup();
|
|
438
|
+
reject(error);
|
|
439
|
+
};
|
|
440
|
+
socket.once('open', onOpen);
|
|
441
|
+
socket.once('error', onError);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
function errorText(error) {
|
|
445
|
+
if (error instanceof Error)
|
|
446
|
+
return error.message;
|
|
447
|
+
return String(error);
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=huddle-voice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"huddle-voice.js","sourceRoot":"","sources":["../src/huddle-voice.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -82,9 +82,18 @@ async function startDaemon(configPath) {
|
|
|
82
82
|
const cfg = loadConfig(configPath);
|
|
83
83
|
const bridge = new AgentBridge(cfg);
|
|
84
84
|
await bridge.start();
|
|
85
|
+
let shuttingDown = false;
|
|
85
86
|
const shutdown = () => {
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
if (shuttingDown)
|
|
88
|
+
return;
|
|
89
|
+
shuttingDown = true;
|
|
90
|
+
// A failed network leave must not trap the supervisor during shutdown.
|
|
91
|
+
const forceExit = setTimeout(() => process.exit(0), 2_000);
|
|
92
|
+
forceExit.unref();
|
|
93
|
+
void bridge.stop().finally(() => {
|
|
94
|
+
clearTimeout(forceExit);
|
|
95
|
+
process.exit(0);
|
|
96
|
+
});
|
|
88
97
|
};
|
|
89
98
|
process.on('SIGINT', shutdown);
|
|
90
99
|
process.on('SIGTERM', shutdown);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ export declare class StreamJsonParser {
|
|
|
77
77
|
private handleLine;
|
|
78
78
|
}
|
|
79
79
|
export declare function buildClaudeArgs(cfg: RuntimeConfig, opts: RunOpts): string[];
|
|
80
|
+
export declare function buildCodexArgs(cfg: RuntimeConfig, opts: RunOpts): string[];
|
|
80
81
|
/** Demo mode: static canned reply, no CLI spawn. */
|
|
81
82
|
export declare const DEMO_REPLY = "Your message was received";
|
|
82
83
|
/**
|
package/dist/runtime.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// Claude runtime (primary): `claude -p --output-format stream-json --verbose`
|
|
4
4
|
// with `--session-id <uuid>` on the first turn and `--resume <uuid>` after.
|
|
5
5
|
// Tool calls stream by as stream-json events → surfaced as thinking steps.
|
|
6
|
-
// Codex runtime:
|
|
7
|
-
//
|
|
6
|
+
// Codex runtime: baseline "prompt in, stdout out" contract, no session resume
|
|
7
|
+
// or thinking steps yet. The system prompt is folded into each invocation.
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
/** One line per tool call, latest step shown: "Bash: pnpm test". */
|
|
@@ -146,9 +146,11 @@ export function buildClaudeArgs(cfg, opts) {
|
|
|
146
146
|
args.push(opts.prompt);
|
|
147
147
|
return args;
|
|
148
148
|
}
|
|
149
|
-
function buildCodexArgs(cfg, opts) {
|
|
150
|
-
//
|
|
151
|
-
|
|
149
|
+
export function buildCodexArgs(cfg, opts) {
|
|
150
|
+
// Baseline contract only (stdout = reply). No session resume, so callers
|
|
151
|
+
// that need continuity include the transcript in opts.prompt.
|
|
152
|
+
const prompt = `${opts.systemPrompt}\n\n${opts.prompt}`;
|
|
153
|
+
return ['exec', '--skip-git-repo-check', ...cfg.extraArgs, prompt];
|
|
152
154
|
}
|
|
153
155
|
/** Demo mode: static canned reply, no CLI spawn. */
|
|
154
156
|
export const DEMO_REPLY = 'Your message was received';
|