@ariaflowagents/gemini-native-audio 0.9.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 +104 -0
- package/dist/CallWorker.d.ts +56 -0
- package/dist/CallWorker.d.ts.map +1 -0
- package/dist/CallWorker.js +172 -0
- package/dist/CallWorker.js.map +1 -0
- package/dist/CapabilityCallWorker.d.ts +46 -0
- package/dist/CapabilityCallWorker.d.ts.map +1 -0
- package/dist/CapabilityCallWorker.js +319 -0
- package/dist/CapabilityCallWorker.js.map +1 -0
- package/dist/GeminiLiveSession.d.ts +86 -0
- package/dist/GeminiLiveSession.d.ts.map +1 -0
- package/dist/GeminiLiveSession.js +297 -0
- package/dist/GeminiLiveSession.js.map +1 -0
- package/dist/RealtimeCallWorker.d.ts +47 -0
- package/dist/RealtimeCallWorker.d.ts.map +1 -0
- package/dist/RealtimeCallWorker.js +55 -0
- package/dist/RealtimeCallWorker.js.map +1 -0
- package/dist/VoiceEngine.d.ts +67 -0
- package/dist/VoiceEngine.d.ts.map +1 -0
- package/dist/VoiceEngine.js +156 -0
- package/dist/VoiceEngine.js.map +1 -0
- package/dist/factories.d.ts +32 -0
- package/dist/factories.d.ts.map +1 -0
- package/dist/factories.js +43 -0
- package/dist/factories.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/openai/OpenAIRealtimeClient.d.ts +51 -0
- package/dist/openai/OpenAIRealtimeClient.d.ts.map +1 -0
- package/dist/openai/OpenAIRealtimeClient.js +327 -0
- package/dist/openai/OpenAIRealtimeClient.js.map +1 -0
- package/dist/openai/index.d.ts +3 -0
- package/dist/openai/index.d.ts.map +1 -0
- package/dist/openai/index.js +2 -0
- package/dist/openai/index.js.map +1 -0
- package/dist/schema-bridge.d.ts +14 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/schema-bridge.js +20 -0
- package/dist/schema-bridge.js.map +1 -0
- package/dist/types.d.ts +150 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# @ariaflowagents/gemini-native-audio
|
|
2
|
+
|
|
3
|
+
Gemini Live Native Audio integration for AriaFlow. Uses Google's Gemini Live API for **speech-to-speech** voice agents — the model handles STT and TTS natively, so you don't need separate Deepgram/Cartesia/etc. services.
|
|
4
|
+
|
|
5
|
+
## What This Does
|
|
6
|
+
|
|
7
|
+
Unlike traditional voice pipelines (STT → LLM → TTS), Gemini Live accepts raw audio input and produces raw audio output in a single model call. This package wraps that capability for AriaFlow agents:
|
|
8
|
+
|
|
9
|
+
- **`VoiceEngine`** — Call acceptor. Accepts incoming audio connections and creates per-call workers.
|
|
10
|
+
- **`CallWorker`** — Per-call lifecycle manager. Bridges your audio transport (WebSocket, LiveKit, etc.) to a Gemini Live session. Handles tool calls, session state, and event logging using AriaFlow's Foundation primitives.
|
|
11
|
+
- **`GeminiLiveSession`** — Thin wrapper around `@google/genai` `ai.live.connect()`. Manages the WebSocket connection to Gemini, audio encoding (base64 PCM ↔ Uint8Array), tool dispatch, and session resumption.
|
|
12
|
+
- **`toolSetToGeminiDeclarations`** — Converts AriaFlow/AI SDK tool definitions (Zod schemas) to Gemini's FunctionDeclaration format.
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
┌─────────────┐ ┌─────────────┐ ┌────────────────────┐
|
|
18
|
+
│ Client │────>│ CallWorker │────>│ GeminiLiveSession │
|
|
19
|
+
│ (WebSocket) │ │ │ │ │
|
|
20
|
+
│ │<────│ audio + │<────│ Gemini Live API │
|
|
21
|
+
│ audio in/out│ │ tool calls │ │ (native audio) │
|
|
22
|
+
└─────────────┘ └─────────────┘ └────────────────────┘
|
|
23
|
+
│
|
|
24
|
+
├── ToolExecutor (runs AriaFlow tools)
|
|
25
|
+
├── ConversationState (persists transcripts)
|
|
26
|
+
└── ConversationEventLog (records events)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { VoiceEngine } from '@ariaflowagents/gemini-native-audio';
|
|
33
|
+
import { createFoundation } from '@ariaflowagents/core/foundation';
|
|
34
|
+
|
|
35
|
+
const foundation = createFoundation({ /* ... */ });
|
|
36
|
+
|
|
37
|
+
const engine = new VoiceEngine({
|
|
38
|
+
foundation,
|
|
39
|
+
agents: [
|
|
40
|
+
{
|
|
41
|
+
id: 'receptionist',
|
|
42
|
+
name: 'Hospital Receptionist',
|
|
43
|
+
prompt: 'You are a hospital receptionist. Help patients schedule appointments.',
|
|
44
|
+
voice: 'Charon', // Gemini voice preset
|
|
45
|
+
tools: { /* AriaFlow tools */ },
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
defaultAgentId: 'receptionist',
|
|
49
|
+
gemini: {
|
|
50
|
+
apiKey: process.env.GOOGLE_API_KEY!,
|
|
51
|
+
model: 'gemini-2.5-flash-native-audio-preview', // default
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Accept a call from any audio transport
|
|
56
|
+
const worker = await engine.acceptCall({
|
|
57
|
+
callId: crypto.randomUUID(),
|
|
58
|
+
transport: myWebSocketTransport, // implements TransportSession
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
await worker.start();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## TransportSession Interface
|
|
65
|
+
|
|
66
|
+
Implement this to connect any audio source/sink:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface TransportSession {
|
|
70
|
+
sendAudio(data: Uint8Array): void; // Send audio to client
|
|
71
|
+
onAudio(handler: (data: Uint8Array) => void): void; // Receive audio from client
|
|
72
|
+
onClose(handler: () => void): void; // Handle disconnect
|
|
73
|
+
close(): void; // Close the transport
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Events
|
|
78
|
+
|
|
79
|
+
`GeminiLiveSession` emits `RealtimeEvent`s:
|
|
80
|
+
|
|
81
|
+
| Event | Description |
|
|
82
|
+
|-------|-------------|
|
|
83
|
+
| `audio` | Raw PCM audio from Gemini (send to client) |
|
|
84
|
+
| `transcript` | Text transcript (user or assistant) |
|
|
85
|
+
| `tool-call` | Gemini wants to call a tool |
|
|
86
|
+
| `tool-result` | Tool execution result |
|
|
87
|
+
| `turn-complete` | Model finished speaking |
|
|
88
|
+
| `interrupted` | User interrupted the model |
|
|
89
|
+
| `session-resumed` | Session resumption handle updated |
|
|
90
|
+
| `error` | Error from Gemini |
|
|
91
|
+
|
|
92
|
+
## Key Details
|
|
93
|
+
|
|
94
|
+
- **Audio format**: 16-bit PCM at 24kHz
|
|
95
|
+
- **Default model**: `gemini-2.5-flash-native-audio-preview`
|
|
96
|
+
- **Session resumption**: Automatic — `GeminiLiveSession` tracks resumption handles
|
|
97
|
+
- **Tool execution**: Uses AriaFlow's `ToolExecutor` with timeout support
|
|
98
|
+
- **State persistence**: Transcripts are saved to session via `ConversationState`
|
|
99
|
+
|
|
100
|
+
## Peer Dependencies
|
|
101
|
+
|
|
102
|
+
- `@ariaflowagents/core` — Foundation primitives (ToolExecutor, ConversationState, etc.)
|
|
103
|
+
- `ai` (v6+) — Vercel AI SDK
|
|
104
|
+
- `zod` — Schema definitions for tools
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ToolExecutor, ConversationState, ConversationEventLog, AgentStateController } from '@ariaflowagents/core/foundation';
|
|
2
|
+
import type { LivePromptAssembler } from '@ariaflowagents/core/capabilities';
|
|
3
|
+
import type { MemoryService } from '@ariaflowagents/core/memory';
|
|
4
|
+
import type { VoiceAgentConfig, TransportSession, GeminiConfig } from './types.js';
|
|
5
|
+
export interface CallWorkerConfig {
|
|
6
|
+
callId: string;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
userId?: string;
|
|
9
|
+
agent: VoiceAgentConfig;
|
|
10
|
+
transport: TransportSession;
|
|
11
|
+
gemini: GeminiConfig;
|
|
12
|
+
toolExecutor: ToolExecutor;
|
|
13
|
+
conversationState: ConversationState;
|
|
14
|
+
eventLog: ConversationEventLog;
|
|
15
|
+
agentState: AgentStateController;
|
|
16
|
+
/**
|
|
17
|
+
* Optional LivePromptAssembler for building audio-optimized system prompts.
|
|
18
|
+
* Used by CapabilityCallWorker to inject voice rules, working memory,
|
|
19
|
+
* long-term memory, and policy injections into the Gemini Live prompt.
|
|
20
|
+
*/
|
|
21
|
+
promptAssembler?: LivePromptAssembler;
|
|
22
|
+
/**
|
|
23
|
+
* Optional MemoryService for cross-session long-term memory.
|
|
24
|
+
* When provided, the LivePromptAssembler can preload relevant memories
|
|
25
|
+
* into the system prompt on each reconfigure.
|
|
26
|
+
*/
|
|
27
|
+
memoryService?: MemoryService;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Per-call owner that manages the lifecycle of a single voice call.
|
|
31
|
+
*
|
|
32
|
+
* Responsibilities:
|
|
33
|
+
* - Audio routing between transport (client) and Gemini Live (LLM)
|
|
34
|
+
* - Tool call dispatch using the shared ToolExecutor
|
|
35
|
+
* - Session state persistence via ConversationState
|
|
36
|
+
* - Event logging via ConversationEventLog
|
|
37
|
+
*/
|
|
38
|
+
export declare class CallWorker {
|
|
39
|
+
private config;
|
|
40
|
+
private geminiSession;
|
|
41
|
+
private session;
|
|
42
|
+
private abortController;
|
|
43
|
+
constructor(config: CallWorkerConfig);
|
|
44
|
+
get callId(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Start the call: load session, connect to Gemini, wire audio.
|
|
47
|
+
*/
|
|
48
|
+
start(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Stop the call: disconnect Gemini, save session, close transport.
|
|
51
|
+
*/
|
|
52
|
+
stop(): Promise<void>;
|
|
53
|
+
private handleGeminiEvent;
|
|
54
|
+
private handleToolCall;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=CallWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallWorker.d.ts","sourceRoot":"","sources":["../src/CallWorker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EAEb,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,gBAAgB,CAAC;IACxB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,oBAAoB,CAAC;IACjC;;;;OAIG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,eAAe,CAAyB;gBAEpC,MAAM,EAAE,gBAAgB;IASpC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,OAAO,CAAC,iBAAiB;YAqCX,cAAc;CAiF7B"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { GeminiLiveSession } from './GeminiLiveSession.js';
|
|
2
|
+
/**
|
|
3
|
+
* Per-call owner that manages the lifecycle of a single voice call.
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - Audio routing between transport (client) and Gemini Live (LLM)
|
|
7
|
+
* - Tool call dispatch using the shared ToolExecutor
|
|
8
|
+
* - Session state persistence via ConversationState
|
|
9
|
+
* - Event logging via ConversationEventLog
|
|
10
|
+
*/
|
|
11
|
+
export class CallWorker {
|
|
12
|
+
config;
|
|
13
|
+
geminiSession;
|
|
14
|
+
session = null;
|
|
15
|
+
abortController = new AbortController();
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
this.geminiSession = new GeminiLiveSession({
|
|
19
|
+
gemini: config.gemini,
|
|
20
|
+
agent: config.agent,
|
|
21
|
+
onEvent: (event) => this.handleGeminiEvent(event),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
get callId() {
|
|
25
|
+
return this.config.callId;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start the call: load session, connect to Gemini, wire audio.
|
|
29
|
+
*/
|
|
30
|
+
async start() {
|
|
31
|
+
const { conversationState, sessionId, userId, agentState, agent, transport } = this.config;
|
|
32
|
+
// Load or create session
|
|
33
|
+
this.session = await conversationState.load(sessionId, userId);
|
|
34
|
+
agentState.setActiveAgent(this.session, agent.id);
|
|
35
|
+
conversationState.bumpSessionTurn(this.session);
|
|
36
|
+
// Connect to Gemini Live
|
|
37
|
+
await this.geminiSession.connect();
|
|
38
|
+
// Wire transport audio → Gemini
|
|
39
|
+
transport.onAudio((data) => {
|
|
40
|
+
if (this.abortController.signal.aborted)
|
|
41
|
+
return;
|
|
42
|
+
this.geminiSession.sendAudio(data);
|
|
43
|
+
});
|
|
44
|
+
// Wire transport close → cleanup
|
|
45
|
+
transport.onClose(() => {
|
|
46
|
+
this.stop();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Stop the call: disconnect Gemini, save session, close transport.
|
|
51
|
+
*/
|
|
52
|
+
async stop() {
|
|
53
|
+
this.abortController.abort();
|
|
54
|
+
await this.geminiSession.disconnect();
|
|
55
|
+
if (this.session) {
|
|
56
|
+
this.config.eventLog.cleanup(this.session);
|
|
57
|
+
await this.config.conversationState.save(this.session);
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
this.config.transport.close();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Ignore transport close errors
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// --- Private: Gemini event handling ---
|
|
67
|
+
handleGeminiEvent(event) {
|
|
68
|
+
switch (event.type) {
|
|
69
|
+
case 'audio':
|
|
70
|
+
this.config.transport.sendAudio(event.data);
|
|
71
|
+
break;
|
|
72
|
+
case 'transcript':
|
|
73
|
+
if (this.session && event.role === 'user') {
|
|
74
|
+
this.config.conversationState.appendUserMessage(this.session, event.text);
|
|
75
|
+
}
|
|
76
|
+
else if (this.session && event.role === 'assistant') {
|
|
77
|
+
this.config.conversationState.appendAssistantMessage(this.session, event.text);
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
case 'tool-call':
|
|
81
|
+
this.handleToolCall(event.id, event.name, event.args).catch((err) => {
|
|
82
|
+
console.error(`[CallWorker] Tool call error for ${event.name}:`, err);
|
|
83
|
+
});
|
|
84
|
+
break;
|
|
85
|
+
case 'turn-complete':
|
|
86
|
+
if (this.session) {
|
|
87
|
+
this.config.conversationState.save(this.session).catch((err) => {
|
|
88
|
+
console.error('[CallWorker] Failed to save session on turn-complete:', err);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
case 'error':
|
|
93
|
+
console.error(`[CallWorker] Gemini error: ${event.error}`);
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async handleToolCall(id, name, args) {
|
|
100
|
+
if (!this.session)
|
|
101
|
+
return;
|
|
102
|
+
const { toolExecutor, conversationState, eventLog, agent } = this.config;
|
|
103
|
+
const tool = agent.tools?.[name];
|
|
104
|
+
if (!tool || !tool.execute) {
|
|
105
|
+
console.warn(`[CallWorker] Unknown or non-executable tool: ${name}`);
|
|
106
|
+
this.geminiSession.sendToolResponse([{
|
|
107
|
+
id,
|
|
108
|
+
name,
|
|
109
|
+
output: { error: `Unknown tool: ${name}` },
|
|
110
|
+
}]);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// Build a minimal RunContext for event logging
|
|
114
|
+
const ctx = {
|
|
115
|
+
session: this.session,
|
|
116
|
+
agentId: agent.id,
|
|
117
|
+
stepCount: 0,
|
|
118
|
+
totalTokens: 0,
|
|
119
|
+
handoffStack: [],
|
|
120
|
+
startTime: Date.now(),
|
|
121
|
+
consecutiveErrors: 0,
|
|
122
|
+
toolCallHistory: [],
|
|
123
|
+
};
|
|
124
|
+
// Record tool call event
|
|
125
|
+
eventLog.record(ctx, {
|
|
126
|
+
type: 'tool-call',
|
|
127
|
+
toolCallId: id,
|
|
128
|
+
toolName: name,
|
|
129
|
+
args,
|
|
130
|
+
});
|
|
131
|
+
// Build an ExecutableTool from the AI SDK Tool (execute is confirmed present above)
|
|
132
|
+
const executableTool = { execute: tool.execute, description: tool.description };
|
|
133
|
+
try {
|
|
134
|
+
const result = await toolExecutor.execute({
|
|
135
|
+
session: this.session,
|
|
136
|
+
userId: this.config.userId,
|
|
137
|
+
agentId: agent.id,
|
|
138
|
+
toolName: name,
|
|
139
|
+
tool: executableTool,
|
|
140
|
+
input: args,
|
|
141
|
+
toolCallId: id,
|
|
142
|
+
abortSignal: this.abortController.signal,
|
|
143
|
+
});
|
|
144
|
+
// Record result
|
|
145
|
+
eventLog.record(ctx, {
|
|
146
|
+
type: 'tool-result',
|
|
147
|
+
toolCallId: id,
|
|
148
|
+
toolName: name,
|
|
149
|
+
result,
|
|
150
|
+
});
|
|
151
|
+
// Save session
|
|
152
|
+
await conversationState.save(this.session);
|
|
153
|
+
// Send result back to Gemini Live
|
|
154
|
+
this.geminiSession.sendToolResponse([{ id, name, output: result }]);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
158
|
+
eventLog.record(ctx, {
|
|
159
|
+
type: 'tool-error',
|
|
160
|
+
toolCallId: id,
|
|
161
|
+
toolName: name,
|
|
162
|
+
error: errorMsg,
|
|
163
|
+
});
|
|
164
|
+
this.geminiSession.sendToolResponse([{
|
|
165
|
+
id,
|
|
166
|
+
name,
|
|
167
|
+
output: { error: errorMsg },
|
|
168
|
+
}]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=CallWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallWorker.js","sourceRoot":"","sources":["../src/CallWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CallWorkerConfig } from './CallWorker.js';
|
|
2
|
+
/**
|
|
3
|
+
* Flow-aware variant of CallWorker.
|
|
4
|
+
*
|
|
5
|
+
* Builds a `CapabilityHost` from the agent config and routes every tool result
|
|
6
|
+
* through `host.processToolResult()`. This enables:
|
|
7
|
+
* - Flow node transitions → Gemini session reconfigure with updated prompt/tools
|
|
8
|
+
* - Handoffs → call stop + upstream notification
|
|
9
|
+
* - End signals → call stop
|
|
10
|
+
* - Extraction → data merge, continue conversation
|
|
11
|
+
*
|
|
12
|
+
* Use when `VoiceAgentConfig.flow` is set. For flat tool-only agents, the
|
|
13
|
+
* regular `CallWorker` is lighter and equivalent.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CapabilityCallWorker {
|
|
16
|
+
private config;
|
|
17
|
+
private geminiSession;
|
|
18
|
+
private host;
|
|
19
|
+
private promptAssembler;
|
|
20
|
+
private session;
|
|
21
|
+
private abortController;
|
|
22
|
+
constructor(config: CallWorkerConfig);
|
|
23
|
+
get callId(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Start the call: load session, connect to Gemini with capability config, wire audio.
|
|
26
|
+
*/
|
|
27
|
+
start(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Stop the call: disconnect Gemini, save session, close transport.
|
|
30
|
+
*/
|
|
31
|
+
stop(): Promise<void>;
|
|
32
|
+
private handleGeminiEvent;
|
|
33
|
+
private handleToolCall;
|
|
34
|
+
/**
|
|
35
|
+
* Rebuild Gemini Live session config from the current capability host state.
|
|
36
|
+
* Called after a flow transition so the model receives the updated node
|
|
37
|
+
* system prompt and tool set.
|
|
38
|
+
*
|
|
39
|
+
* Uses the LivePromptAssembler to build a prompt that includes runtime
|
|
40
|
+
* context (working memory, long-term memory, policy injections) alongside
|
|
41
|
+
* capability sections — matching the richness of ContextAssembleStage.
|
|
42
|
+
*/
|
|
43
|
+
private reconfigureSession;
|
|
44
|
+
private buildHost;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=CapabilityCallWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CapabilityCallWorker.d.ts","sourceRoot":"","sources":["../src/CapabilityCallWorker.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKxD;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,eAAe,CAAyB;gBAEpC,MAAM,EAAE,gBAAgB;IA8BpC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,OAAO,CAAC,iBAAiB;YAqCX,cAAc;IA4H5B;;;;;;;;OAQG;YACW,kBAAkB;IAiBhC,OAAO,CAAC,SAAS;CAoBlB"}
|