aillom-vox-client 1.0.2 → 2.1.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 +102 -195
- package/dist/AillomVox.d.ts +78 -19
- package/dist/AillomVox.js +345 -60
- package/dist/constants.d.ts +19 -0
- package/dist/constants.js +35 -0
- package/dist/gateway-url.d.ts +12 -0
- package/dist/gateway-url.js +74 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/pricing.d.ts +26 -0
- package/dist/pricing.js +20 -0
- package/dist/types.d.ts +168 -11
- package/package.json +18 -7
- package/docs/ASTERISK.md +0 -411
- package/docs/PROTOCOL.md +0 -156
- package/docs/PROVIDERS.md +0 -40
- package/docs/TOOLS.md +0 -314
- package/docs/TROUBLESHOOTING.md +0 -86
- package/docs/VOICES.md +0 -219
- package/docs/providers/AILLOMVOX.md +0 -185
- package/docs/providers/AWS.md +0 -32
- package/docs/providers/GEMINI.md +0 -33
- package/docs/providers/GROK.md +0 -25
- package/docs/providers/OPENAI.md +0 -39
- package/docs/providers/QWEN.md +0 -27
- package/docs/providers/ULTRAVOX.md +0 -29
- package/examples/01-basic/app.js +0 -196
- package/examples/01-basic/index.html +0 -27
- package/examples/02-advanced-dashboard/app.js +0 -465
- package/examples/02-advanced-dashboard/index.html +0 -200
- package/examples/02-advanced-dashboard/style.css +0 -501
- package/examples/03-smart-home/index.html +0 -377
- package/examples/04-customer-support/index.html +0 -474
- package/examples/sdk-usage.ts +0 -44
- package/integrations/n8n-nodes-aillomvox/README.md +0 -56
- package/integrations/n8n-nodes-aillomvox/credentials/AillomVoxApi.credentials.ts +0 -29
- package/integrations/n8n-nodes-aillomvox/dist/credentials/AillomVoxApi.credentials.js +0 -30
- package/integrations/n8n-nodes-aillomvox/dist/nodes/AillomVox/AillomVox.node.js +0 -219
- package/integrations/n8n-nodes-aillomvox/dist/nodes/AillomVox/aillomvox.svg +0 -6
- package/integrations/n8n-nodes-aillomvox/gulpfile.js +0 -10
- package/integrations/n8n-nodes-aillomvox/nodes/AillomVox/AillomVox.node.ts +0 -229
- package/integrations/n8n-nodes-aillomvox/nodes/AillomVox/aillomvox.svg +0 -6
- package/integrations/n8n-nodes-aillomvox/package-lock.json +0 -11741
- package/integrations/n8n-nodes-aillomvox/package.json +0 -56
- package/integrations/n8n-nodes-aillomvox/tsconfig.json +0 -32
- package/src/AillomVox.ts +0 -172
- package/src/index.ts +0 -2
- package/src/types.ts +0 -51
- package/tsconfig.json +0 -23
package/docs/PROTOCOL.md
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# WebSocket Protocol
|
|
2
|
-
|
|
3
|
-
The AillomVox Gateway uses a WebSocket protocol for full-duplex audio streaming and control messaging.
|
|
4
|
-
|
|
5
|
-
## Connection
|
|
6
|
-
|
|
7
|
-
**Endpoint**: `wss://vox.aillom.com/ws`
|
|
8
|
-
|
|
9
|
-
> **Note**: Authentication is performed in-band (inside the first message), not via HTTP headers or query params.
|
|
10
|
-
|
|
11
|
-
## Message Flow
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
Client Server
|
|
15
|
-
| |
|
|
16
|
-
|--- WebSocket Connect (GET /ws) --->|
|
|
17
|
-
|<--- 101 Switching Protocols -------|
|
|
18
|
-
| |
|
|
19
|
-
|--- JSON Config (type: "config") -->| ← MUST be first message
|
|
20
|
-
| | (Auth + Billing + Provider init)
|
|
21
|
-
| ~500ms stabilization~ |
|
|
22
|
-
| |
|
|
23
|
-
|--- Binary PCM Audio Chunks ------->| ← 16-bit LE Mono
|
|
24
|
-
|<--- Binary PCM Audio Chunks -------| ← AI response audio
|
|
25
|
-
|<--- JSON Events (transcript, etc) -|
|
|
26
|
-
| |
|
|
27
|
-
|--- JSON { type: "hangup" } ------->| ← or server-initiated
|
|
28
|
-
|<--- WebSocket Close ----------------|
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## 1. Handshake (Client → Server)
|
|
32
|
-
|
|
33
|
-
The **first message** must be a flat JSON config object. Sending binary data before this message results in connection termination (code `1008`).
|
|
34
|
-
|
|
35
|
-
```json
|
|
36
|
-
{
|
|
37
|
-
"type": "config",
|
|
38
|
-
"apikey": "av_your_api_key_here",
|
|
39
|
-
"provider": "aillomvox",
|
|
40
|
-
"voice": "Edward",
|
|
41
|
-
"language": "en-US",
|
|
42
|
-
"sample_rate": 16000,
|
|
43
|
-
"system_prompt": "You are a helpful assistant.",
|
|
44
|
-
"first_message": "Hello! How can I help you?",
|
|
45
|
-
"farewell_message": "Thank you for calling. Goodbye!",
|
|
46
|
-
"max_duration": 300,
|
|
47
|
-
"tools": [
|
|
48
|
-
{
|
|
49
|
-
"name": "hangup",
|
|
50
|
-
"description": "End the call when user says goodbye.",
|
|
51
|
-
"parameters": { "type": "object", "properties": {} }
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
| Field | Required | Type | Description |
|
|
58
|
-
| :--- | :--- | :--- | :--- |
|
|
59
|
-
| `type` | ✅ | string | Must be `"config"` |
|
|
60
|
-
| `apikey` | ✅ | string | Your AillomVox API key |
|
|
61
|
-
| `provider` | ✅ | string | `aillomvox`, `openai`, `gemini`, `aws`, `ultravox`, `grok`, `qwen` |
|
|
62
|
-
| `sample_rate` | ✅ | number | `8000`, `16000`, or `24000` Hz |
|
|
63
|
-
| `system_prompt` | ✅ | string | AI persona instructions |
|
|
64
|
-
| `voice` | | string | Provider-specific voice ID |
|
|
65
|
-
| `language` | | string | Locale code (e.g., `en-US`, `pt-BR`) |
|
|
66
|
-
| `first_message` | | string | Greeting spoken on connect |
|
|
67
|
-
| `farewell_message` | | string | Message before session close |
|
|
68
|
-
| `max_duration` | | number | Session limit in seconds (60–3600) |
|
|
69
|
-
| `tools` | | array | Client-side tool definitions |
|
|
70
|
-
|
|
71
|
-
## 2. Audio (Binary Messages)
|
|
72
|
-
|
|
73
|
-
After the handshake, audio flows as raw binary WebSocket messages in both directions.
|
|
74
|
-
|
|
75
|
-
- **Format**: PCM 16-bit Signed Integer, Little Endian
|
|
76
|
-
- **Channels**: Mono (1 channel)
|
|
77
|
-
- **Rate**: Must match `sample_rate` from the handshake
|
|
78
|
-
- **Direction**: Full duplex (bidirectional)
|
|
79
|
-
|
|
80
|
-
> There is no JSON wrapper for audio. If the WebSocket message is binary, it is a raw audio chunk.
|
|
81
|
-
|
|
82
|
-
## 3. Server → Client Events
|
|
83
|
-
|
|
84
|
-
### Transcript
|
|
85
|
-
```json
|
|
86
|
-
{
|
|
87
|
-
"type": "transcript",
|
|
88
|
-
"role": "user",
|
|
89
|
-
"text": "Hello world",
|
|
90
|
-
"final": true
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
- `role`: `"user"` or `"assistant"`
|
|
94
|
-
- `final`: `true` when the sentence is complete. Only render `final: true` transcripts to avoid UI flickering.
|
|
95
|
-
|
|
96
|
-
### Tool Call
|
|
97
|
-
```json
|
|
98
|
-
{
|
|
99
|
-
"type": "tool_call",
|
|
100
|
-
"call_id": "abc123",
|
|
101
|
-
"name": "hangup",
|
|
102
|
-
"args": {}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
Client must respond with a `tool_result` within 15 seconds (see below).
|
|
106
|
-
|
|
107
|
-
### Playback Clear Buffer
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"type": "playback_clear_buffer"
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
Sent when the user interrupts the AI. Client **must** immediately flush its audio playback queue.
|
|
114
|
-
|
|
115
|
-
### Hangup
|
|
116
|
-
```json
|
|
117
|
-
{
|
|
118
|
-
"type": "hangup"
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
Server-initiated session end. Client should stop audio, close socket, and reset UI.
|
|
122
|
-
|
|
123
|
-
### Error
|
|
124
|
-
```json
|
|
125
|
-
{
|
|
126
|
-
"type": "error",
|
|
127
|
-
"message": "Invalid API Key"
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
Error codes: `unauthorized`, `insufficient_balance`, `max_duration_reached`.
|
|
131
|
-
|
|
132
|
-
## 4. Client → Server Events
|
|
133
|
-
|
|
134
|
-
### Tool Result
|
|
135
|
-
```json
|
|
136
|
-
{
|
|
137
|
-
"type": "tool_result",
|
|
138
|
-
"call_id": "abc123",
|
|
139
|
-
"result": "Order status: shipped"
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
**Mandatory** response after receiving a `tool_call`. The AI pauses execution until it receives this. Timeout: 15 seconds.
|
|
143
|
-
|
|
144
|
-
### Hangup
|
|
145
|
-
```json
|
|
146
|
-
{
|
|
147
|
-
"type": "hangup"
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
Client-initiated session end.
|
|
151
|
-
|
|
152
|
-
## 5. Session Governance
|
|
153
|
-
|
|
154
|
-
- **Max Duration**: 60–3600 seconds (default: 300)
|
|
155
|
-
- **Farewell Warning**: At 15 seconds remaining, the AI speaks the `farewell_message`
|
|
156
|
-
- **Force Close**: At 0 seconds, connection closes with `max_duration_reached`
|
package/docs/PROVIDERS.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Supported AI Providers
|
|
2
|
-
|
|
3
|
-
AillomVox aggregates top-tier Voice AI providers. Click on a provider to see detailed configuration and examples.
|
|
4
|
-
|
|
5
|
-
## Provider Index
|
|
6
|
-
|
|
7
|
-
| Provider | Model | Voices | Best For | Documentation |
|
|
8
|
-
| :--- | :--- | :--- | :--- | :--- |
|
|
9
|
-
| **AillomVox** | *Groq + Inworld TTS* | 65 voices | **Speed & Telephony**. Lowest latency, 8kHz native. | [Docs](providers/AILLOMVOX.md) |
|
|
10
|
-
| **OpenAI** | `gpt-realtime-mini` | 6 voices | **Complex Logic**. Math, coding, strict reasoning. | [Docs](providers/OPENAI.md) |
|
|
11
|
-
| **Gemini** | `gemini-2.5-flash` | 5 voices | **Long Context**. Massive memory, complex prompts. | [Docs](providers/GEMINI.md) |
|
|
12
|
-
| **AWS** | `nova-2-sonic` | 3 voices | **Enterprise**. High reliability, AWS compliance. | [Docs](providers/AWS.md) |
|
|
13
|
-
| **UltraVox** | `ultravox-v0.7` | 2 voices | **Emotion**. High emotional intelligence. | [Docs](providers/ULTRAVOX.md) |
|
|
14
|
-
| **Grok** | `grok-beta` | Model-dependent | **Casual/Fun**. Witty, less robotic interactions. | [Docs](providers/GROK.md) |
|
|
15
|
-
| **Qwen** | `qwen3-omni` | Model-dependent | **Cost & Asia**. High performance at lower cost. | [Docs](providers/QWEN.md) |
|
|
16
|
-
|
|
17
|
-
See the complete [Voice Catalog](VOICES.md) for all voices across providers.
|
|
18
|
-
|
|
19
|
-
## Quick Config Example
|
|
20
|
-
|
|
21
|
-
```javascript
|
|
22
|
-
// Connect to AillomVox
|
|
23
|
-
ws.send(JSON.stringify({
|
|
24
|
-
type: "config",
|
|
25
|
-
apikey: "YOUR_API_KEY",
|
|
26
|
-
provider: "aillomvox",
|
|
27
|
-
voice: "Edward",
|
|
28
|
-
language: "en-US",
|
|
29
|
-
sample_rate: 16000,
|
|
30
|
-
system_prompt: "You are a helpful assistant."
|
|
31
|
-
}));
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## ⚠️ Known Limitations
|
|
37
|
-
|
|
38
|
-
| Provider | Limitation | Workaround |
|
|
39
|
-
| :--- | :--- | :--- |
|
|
40
|
-
| **Qwen** (`qwen3-omni-flash-realtime`) | **Function calling / Client Tools not supported** in WebSocket Realtime mode. The model will respond with text instead of emitting tool calls. | Use **AWS**, **OpenAI**, or **Gemini** for scenarios requiring tools (e.g., `hangup`, `transfer`). |
|
package/docs/TOOLS.md
DELETED
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
# 🛠️ Client Tools Guide
|
|
2
|
-
|
|
3
|
-
Client Tools allow the AI to interact with your application's UI. When the AI determines that a specific action is needed (like ending a call or showing an alert), it calls a tool, and your application executes it.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 📋 Architecture
|
|
8
|
-
|
|
9
|
-
### CLIENT-side Tools
|
|
10
|
-
Executed **locally** in your application (browser, mobile app, CLI):
|
|
11
|
-
- Control UI elements
|
|
12
|
-
- Handle navigation
|
|
13
|
-
- Manage connections
|
|
14
|
-
- Display notifications
|
|
15
|
-
|
|
16
|
-
### SERVER-side Tools
|
|
17
|
-
Executed on **AillomVox servers** (you cannot register these):
|
|
18
|
-
- Access databases
|
|
19
|
-
- Call external APIs
|
|
20
|
-
- Query RAG systems
|
|
21
|
-
- Server-side logic
|
|
22
|
-
|
|
23
|
-
> **Rule**: If it controls **your app's UI**, it's a CLIENT tool. If it accesses **server resources**, it's a SERVER tool.
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## 🚀 Quick Start
|
|
28
|
-
|
|
29
|
-
### 1. Register Tools
|
|
30
|
-
|
|
31
|
-
```javascript
|
|
32
|
-
await client.connect({
|
|
33
|
-
provider: 'gemini',
|
|
34
|
-
voice: 'Puck',
|
|
35
|
-
tools: [
|
|
36
|
-
{
|
|
37
|
-
name: 'hangup',
|
|
38
|
-
description: 'End the current call',
|
|
39
|
-
parameters: {
|
|
40
|
-
type: 'object',
|
|
41
|
-
properties: {},
|
|
42
|
-
required: []
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
});
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 2. Handle Tool Calls
|
|
50
|
-
|
|
51
|
-
```javascript
|
|
52
|
-
client.on('tool_call', async (tool) => {
|
|
53
|
-
console.log(`AI requested: ${tool.name}`, tool.args);
|
|
54
|
-
|
|
55
|
-
if (tool.name === 'hangup') {
|
|
56
|
-
await client.disconnect();
|
|
57
|
-
return 'Call ended successfully';
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### 3. Send Result Back
|
|
63
|
-
|
|
64
|
-
The return value from your handler is automatically sent back to the AI, allowing it to continue the conversation.
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## 📦 Tool Definition Format
|
|
69
|
-
|
|
70
|
-
```javascript
|
|
71
|
-
{
|
|
72
|
-
name: 'tool_name', // Unique identifier (match in handler)
|
|
73
|
-
description: 'What it does', // AI uses this to decide when to call
|
|
74
|
-
parameters: { // JSON Schema for arguments
|
|
75
|
-
type: 'object',
|
|
76
|
-
properties: {
|
|
77
|
-
arg1: {
|
|
78
|
-
type: 'string',
|
|
79
|
-
description: 'First argument'
|
|
80
|
-
},
|
|
81
|
-
arg2: {
|
|
82
|
-
type: 'number',
|
|
83
|
-
description: 'Second argument'
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
required: ['arg1'] // Mandatory arguments
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## 🎯 Common Tools
|
|
94
|
-
|
|
95
|
-
### 1. Hangup (End Call)
|
|
96
|
-
|
|
97
|
-
```javascript
|
|
98
|
-
{
|
|
99
|
-
name: 'hangup',
|
|
100
|
-
description: 'End the call when user says goodbye',
|
|
101
|
-
parameters: { type: 'object', properties: {} }
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Handler
|
|
105
|
-
client.on('tool_call', async (tool) => {
|
|
106
|
-
if (tool.name === 'hangup') {
|
|
107
|
-
await client.disconnect();
|
|
108
|
-
return 'Call ended';
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### 2. Show Alert
|
|
114
|
-
|
|
115
|
-
```javascript
|
|
116
|
-
{
|
|
117
|
-
name: 'show_alert',
|
|
118
|
-
description: 'Display important message to user',
|
|
119
|
-
parameters: {
|
|
120
|
-
type: 'object',
|
|
121
|
-
properties: {
|
|
122
|
-
message: {
|
|
123
|
-
type: 'string',
|
|
124
|
-
description: 'Alert message'
|
|
125
|
-
},
|
|
126
|
-
severity: {
|
|
127
|
-
type: 'string',
|
|
128
|
-
enum: ['info', 'warning', 'error'],
|
|
129
|
-
description: 'Alert type'
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
required: ['message']
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Handler
|
|
137
|
-
client.on('tool_call', async (tool) => {
|
|
138
|
-
if (tool.name === 'show_alert') {
|
|
139
|
-
alert(`[${tool.args.severity}] ${tool.args.message}`);
|
|
140
|
-
return 'Alert displayed';
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### 3. Navigate to Page
|
|
146
|
-
|
|
147
|
-
```javascript
|
|
148
|
-
{
|
|
149
|
-
name: 'navigate_to_page',
|
|
150
|
-
description: 'Navigate user to a specific page',
|
|
151
|
-
parameters: {
|
|
152
|
-
type: 'object',
|
|
153
|
-
properties: {
|
|
154
|
-
url: {
|
|
155
|
-
type: 'string',
|
|
156
|
-
description: 'Target URL'
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
required: ['url']
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Handler
|
|
164
|
-
client.on('tool_call', async (tool) => {
|
|
165
|
-
if (tool.name === 'navigate_to_page') {
|
|
166
|
-
window.location.href = tool.args.url;
|
|
167
|
-
return 'Navigating';
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### 4. Update UI Element
|
|
173
|
-
|
|
174
|
-
```javascript
|
|
175
|
-
{
|
|
176
|
-
name: 'highlight_element',
|
|
177
|
-
description: 'Highlight UI element to draw user attention',
|
|
178
|
-
parameters: {
|
|
179
|
-
type: 'object',
|
|
180
|
-
properties: {
|
|
181
|
-
element_id: { type: 'string', description: 'DOM element ID' },
|
|
182
|
-
color: { type: 'string', description: 'Highlight color' }
|
|
183
|
-
},
|
|
184
|
-
required: ['element_id']
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Handler
|
|
189
|
-
client.on('tool_call', async (tool) => {
|
|
190
|
-
if (tool.name === 'highlight_element') {
|
|
191
|
-
const el = document.getElementById(tool.args.element_id);
|
|
192
|
-
el.style.border = `3px solid ${tool.args.color || 'yellow'}`;
|
|
193
|
-
return 'Element highlighted';
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
## 🧪 Testing Tools
|
|
201
|
-
|
|
202
|
-
### Manual Testing
|
|
203
|
-
|
|
204
|
-
```javascript
|
|
205
|
-
// Simulate AI calling a tool
|
|
206
|
-
client.emit('tool_call', {
|
|
207
|
-
name: 'show_alert',
|
|
208
|
-
args: { message: 'Test alert', severity: 'info' }
|
|
209
|
-
});
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Debugging
|
|
213
|
-
|
|
214
|
-
```javascript
|
|
215
|
-
client.on('tool_call', async (tool) => {
|
|
216
|
-
console.log('=== TOOL CALL ===');
|
|
217
|
-
console.log('Name:', tool.name);
|
|
218
|
-
console.log('Args:', tool.args);
|
|
219
|
-
console.log('ID:', tool.call_id);
|
|
220
|
-
|
|
221
|
-
// Your handler logic here
|
|
222
|
-
const result = await handleTool(tool);
|
|
223
|
-
|
|
224
|
-
console.log('Result:', result);
|
|
225
|
-
return result;
|
|
226
|
-
});
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
---
|
|
230
|
-
|
|
231
|
-
## ⚠️ Best Practices
|
|
232
|
-
|
|
233
|
-
### 1. Clear Descriptions
|
|
234
|
-
```javascript
|
|
235
|
-
// ❌ Bad
|
|
236
|
-
description: 'Does something'
|
|
237
|
-
|
|
238
|
-
// ✅ Good
|
|
239
|
-
description: 'End the call when user says goodbye or wants to finish'
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### 2. Validate Arguments
|
|
243
|
-
```javascript
|
|
244
|
-
client.on('tool_call', async (tool) => {
|
|
245
|
-
if (tool.name === 'navigate_to_page') {
|
|
246
|
-
// Validate
|
|
247
|
-
if (!tool.args.url || !tool.args.url.startsWith('http')) {
|
|
248
|
-
return 'Error: Invalid URL';
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
window.location.href = tool.args.url;
|
|
252
|
-
return 'Navigating to ' + tool.args.url;
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### 3. Return Meaningful Results
|
|
258
|
-
```javascript
|
|
259
|
-
// ❌ Bad
|
|
260
|
-
return 'ok';
|
|
261
|
-
|
|
262
|
-
// ✅ Good
|
|
263
|
-
return 'Alert shown successfully with message: "' + tool.args.message + '"';
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
This helps the AI understand what happened and continue the conversation naturally.
|
|
267
|
-
|
|
268
|
-
---
|
|
269
|
-
|
|
270
|
-
## 🔒 Security
|
|
271
|
-
|
|
272
|
-
### Client Tools are Safe
|
|
273
|
-
- Executed in **your app**, not on our servers
|
|
274
|
-
- You have **full control** over what they do
|
|
275
|
-
- No sensitive data is sent to the server
|
|
276
|
-
|
|
277
|
-
### Never Trust User Input
|
|
278
|
-
```javascript
|
|
279
|
-
// ❌ Dangerous
|
|
280
|
-
client.on('tool_call', async (tool) => {
|
|
281
|
-
eval(tool.args.code); // NEVER DO THIS
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
// ✅ Safe
|
|
285
|
-
client.on('tool_call', async (tool) => {
|
|
286
|
-
const allowedUrls = ['https://myapp.com/dashboard', 'https://myapp.com/profile'];
|
|
287
|
-
if (allowedUrls.includes(tool.args.url)) {
|
|
288
|
-
window.location.href = tool.args.url;
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
## 📚 Examples
|
|
296
|
-
|
|
297
|
-
See complete working examples in:
|
|
298
|
-
- [Browser Example](../examples/browser/) - Full UI with tools
|
|
299
|
-
- [Node.js CLI](../examples/nodejs/) - CLI bot with hangup
|
|
300
|
-
- [Python Example](../examples/python/) - Python integration
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## 💡 Tips
|
|
305
|
-
|
|
306
|
-
1. **Start Simple**: Begin with just `hangup`, then add more
|
|
307
|
-
2. **Test Locally**: Use manual emit to test without calling the AI
|
|
308
|
-
3. **Return Clear Messages**: AI uses return value to continue conversation
|
|
309
|
-
4. **Validate Everything**: Never trust arguments blindly
|
|
310
|
-
5. **Keep it Fast**: Tool execution should be instant (< 100ms)
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
Happy building! 🎉
|
package/docs/TROUBLESHOOTING.md
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# Troubleshooting Guide
|
|
2
|
-
|
|
3
|
-
Common issues and how to resolve them when using AillomVox.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Authentication Errors
|
|
8
|
-
|
|
9
|
-
### `401 Unauthorized` / `error: unauthorized`
|
|
10
|
-
- **Cause**: API Key is missing, invalid, or expired.
|
|
11
|
-
- **Fix**: Check that you're sending `apikey` in your config handshake. Ensure you are copying the key exactly as provided in your dashboard.
|
|
12
|
-
|
|
13
|
-
### `error: insufficient_balance`
|
|
14
|
-
- **Cause**: Your account balance is $0.00 or below.
|
|
15
|
-
- **Fix**: Add credits via the [Billing page](https://vox.aillom.com/billing).
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Connection Issues
|
|
20
|
-
|
|
21
|
-
### `Connection Refused` / `Socket Hang Up`
|
|
22
|
-
- **Cause**: Server unreachable or firewall blocking outbound port 443 (WSS).
|
|
23
|
-
- **Fix**: Ensure you can reach `https://vox.aillom.com/health`. Check your network settings.
|
|
24
|
-
|
|
25
|
-
### `1008 Policy Violation`
|
|
26
|
-
- **Cause**: Sent binary data before the config handshake.
|
|
27
|
-
- **Fix**: The **first message** must be a JSON config. Wait for it to be acknowledged before sending audio.
|
|
28
|
-
|
|
29
|
-
### `1006 Abnormal Closure`
|
|
30
|
-
- **Cause**: Generic WebSocket error. Often caused by:
|
|
31
|
-
- Sending malformed JSON
|
|
32
|
-
- Sending audio in wrong format (e.g., MP3 instead of PCM)
|
|
33
|
-
- Network timeout (keep-alive)
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Audio Problems
|
|
38
|
-
|
|
39
|
-
### "Static" or "Noise" instead of Voice
|
|
40
|
-
- **Cause**: Wrong encoding or endianness.
|
|
41
|
-
- **Fix**: AillomVox expects **PCM 16-bit Signed Little Endian**.
|
|
42
|
-
- If you send Float32 (Web Audio API default), you get static. Convert to Int16 first.
|
|
43
|
-
- If you send Big Endian, you get static. Use `true` for little-endian in `DataView.setInt16()`.
|
|
44
|
-
|
|
45
|
-
### High Latency
|
|
46
|
-
- **Cause**: Buffering too much audio before sending.
|
|
47
|
-
- **Fix**: Send small chunks (20ms–50ms) as soon as recorded. Do not batch 1 second of audio.
|
|
48
|
-
|
|
49
|
-
### "Choppy" Audio Output
|
|
50
|
-
- **Cause**: Network jitter or empty buffer underruns.
|
|
51
|
-
- **Fix**: Implement a jitter buffer — wait for 2–3 chunks before starting playback.
|
|
52
|
-
|
|
53
|
-
### No Audio Received
|
|
54
|
-
- **Cause**: `sample_rate` mismatch or missing `system_prompt`.
|
|
55
|
-
- **Fix**: Ensure `sample_rate` is `8000`, `16000`, or `24000`. The `system_prompt` field is mandatory.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Tool Call Issues
|
|
60
|
-
|
|
61
|
-
### AI Hangs After Tool Call
|
|
62
|
-
- **Cause**: Missing `tool_result` response.
|
|
63
|
-
- **Fix**: Always respond to `tool_call` events with a `tool_result` within 15 seconds:
|
|
64
|
-
```javascript
|
|
65
|
-
ws.send(JSON.stringify({
|
|
66
|
-
type: "tool_result",
|
|
67
|
-
call_id: msg.call_id,
|
|
68
|
-
result: "Success"
|
|
69
|
-
}));
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Tools Not Triggering
|
|
73
|
-
- **Cause**: Vague tool descriptions or wrong provider.
|
|
74
|
-
- **Fix**: Use clear, specific descriptions. Note: Qwen does not support tools — use AillomVox, OpenAI, Gemini, or AWS.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Session Issues
|
|
79
|
-
|
|
80
|
-
### `max_duration_reached`
|
|
81
|
-
- **Cause**: Session exceeded the `max_duration` limit.
|
|
82
|
-
- **Fix**: Increase `max_duration` (up to 3600) or handle the farewell message gracefully.
|
|
83
|
-
|
|
84
|
-
### Multiple Connections Rejected
|
|
85
|
-
- **Cause**: Exceeded concurrent connection limit (3 per user, 2 per API key).
|
|
86
|
-
- **Fix**: Close unused connections before opening new ones.
|