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.
Files changed (49) hide show
  1. package/README.md +102 -195
  2. package/dist/AillomVox.d.ts +78 -19
  3. package/dist/AillomVox.js +345 -60
  4. package/dist/constants.d.ts +19 -0
  5. package/dist/constants.js +35 -0
  6. package/dist/gateway-url.d.ts +12 -0
  7. package/dist/gateway-url.js +74 -0
  8. package/dist/index.d.ts +3 -0
  9. package/dist/index.js +3 -0
  10. package/dist/pricing.d.ts +26 -0
  11. package/dist/pricing.js +20 -0
  12. package/dist/types.d.ts +168 -11
  13. package/package.json +18 -7
  14. package/docs/ASTERISK.md +0 -411
  15. package/docs/PROTOCOL.md +0 -156
  16. package/docs/PROVIDERS.md +0 -40
  17. package/docs/TOOLS.md +0 -314
  18. package/docs/TROUBLESHOOTING.md +0 -86
  19. package/docs/VOICES.md +0 -219
  20. package/docs/providers/AILLOMVOX.md +0 -185
  21. package/docs/providers/AWS.md +0 -32
  22. package/docs/providers/GEMINI.md +0 -33
  23. package/docs/providers/GROK.md +0 -25
  24. package/docs/providers/OPENAI.md +0 -39
  25. package/docs/providers/QWEN.md +0 -27
  26. package/docs/providers/ULTRAVOX.md +0 -29
  27. package/examples/01-basic/app.js +0 -196
  28. package/examples/01-basic/index.html +0 -27
  29. package/examples/02-advanced-dashboard/app.js +0 -465
  30. package/examples/02-advanced-dashboard/index.html +0 -200
  31. package/examples/02-advanced-dashboard/style.css +0 -501
  32. package/examples/03-smart-home/index.html +0 -377
  33. package/examples/04-customer-support/index.html +0 -474
  34. package/examples/sdk-usage.ts +0 -44
  35. package/integrations/n8n-nodes-aillomvox/README.md +0 -56
  36. package/integrations/n8n-nodes-aillomvox/credentials/AillomVoxApi.credentials.ts +0 -29
  37. package/integrations/n8n-nodes-aillomvox/dist/credentials/AillomVoxApi.credentials.js +0 -30
  38. package/integrations/n8n-nodes-aillomvox/dist/nodes/AillomVox/AillomVox.node.js +0 -219
  39. package/integrations/n8n-nodes-aillomvox/dist/nodes/AillomVox/aillomvox.svg +0 -6
  40. package/integrations/n8n-nodes-aillomvox/gulpfile.js +0 -10
  41. package/integrations/n8n-nodes-aillomvox/nodes/AillomVox/AillomVox.node.ts +0 -229
  42. package/integrations/n8n-nodes-aillomvox/nodes/AillomVox/aillomvox.svg +0 -6
  43. package/integrations/n8n-nodes-aillomvox/package-lock.json +0 -11741
  44. package/integrations/n8n-nodes-aillomvox/package.json +0 -56
  45. package/integrations/n8n-nodes-aillomvox/tsconfig.json +0 -32
  46. package/src/AillomVox.ts +0 -172
  47. package/src/index.ts +0 -2
  48. package/src/types.ts +0 -51
  49. package/tsconfig.json +0 -23
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VOX_PROVIDER_RATECARD = void 0;
4
+ exports.VOX_PROVIDER_RATECARD = [
5
+ {
6
+ label: 'AillomVox',
7
+ provider: 'aillomvox',
8
+ ttsEngineHint: 'inworld · xai · lmnt · soniox · rime · fish',
9
+ usdPerMinute: 0.04,
10
+ tier: 'Gateway',
11
+ modelSummary: 'Soniox STT · Groq Llama 3.3 70B · selectable TTS',
12
+ badge: 'Best Value',
13
+ },
14
+ { label: 'AWS Nova', provider: 'aws', usdPerMinute: 0.06, tier: 'S2S', modelSummary: 'nova-2-sonic' },
15
+ { label: 'Gemini', provider: 'gemini', usdPerMinute: 0.06, tier: 'S2S', modelSummary: 'gemini-3.1-flash-live-preview' },
16
+ { label: 'Qwen', provider: 'qwen', usdPerMinute: 0.06, tier: 'S2S', modelSummary: 'qwen3.5-omni-flash-realtime' },
17
+ { label: 'Grok', provider: 'grok', usdPerMinute: 0.1, tier: 'S2S', modelSummary: 'grok-voice-think-fast-1.0' },
18
+ { label: 'OpenAI', provider: 'openai', usdPerMinute: 0.1, tier: 'S2S', modelSummary: 'gpt-realtime-mini' },
19
+ { label: 'Ultravox', provider: 'ultravox', usdPerMinute: 0.1, tier: 'Premium', modelSummary: 'ultravox-70B' },
20
+ ];
package/dist/types.d.ts CHANGED
@@ -1,37 +1,194 @@
1
- export type ProviderType = 'aillomvox' | 'gemini' | 'openai' | 'aws' | 'qwen' | 'grok' | 'ultravox';
2
- export interface MicrophoneConfig {
3
- sampleRate?: 8000 | 16000 | 24000;
4
- inputSampleRate?: number;
5
- }
1
+ import type { AillomVoxTtsEngineId } from './constants';
2
+ /**
3
+ * Known stable provider ids. The gateway may accept additional strings and normalizes aliases
4
+ * (see product docs / `GET /api/providers`).
5
+ */
6
+ export type VoxProviderId = 'aillomvox' | 'openai' | 'gemini' | 'aws' | 'qwen' | 'grok' | 'ultravox' | (string & {});
6
7
  export interface ClientTool {
7
8
  name: string;
8
9
  description: string;
9
- parameters: Record<string, any>;
10
+ /** JSON Schema parameters for the function (OpenAI-style). */
11
+ parameters?: Record<string, unknown>;
12
+ /** Backward-compatible location used by some dashboard / n8n tool presets. */
13
+ config?: Record<string, unknown>;
14
+ /** Optional server-side endpoint metadata, including `aillom-connect://...` tools. */
15
+ url?: string;
16
+ endpoint_url?: string;
17
+ endpointUrl?: string;
18
+ [key: string]: unknown;
10
19
  }
20
+ export type VoxAuthMode = 'auto' | 'handshake' | 'header' | 'both';
11
21
  export interface AillomVoxConfig {
22
+ /**
23
+ * Gateway API key (`av_…`). **Secret** — treat like a password.
24
+ * In public web apps, anyone can extract a key shipped to the browser; prefer a
25
+ * server-issued short-lived token or a backend proxy that holds the real key.
26
+ */
12
27
  apiKey: string;
13
- provider?: ProviderType;
28
+ /**
29
+ * WebSocket auth strategy. Default `auto` sends `x-api-key` from Node.js and falls
30
+ * back to the config `apikey` field in browsers, where custom WebSocket headers are unavailable.
31
+ */
32
+ authMode?: VoxAuthMode;
33
+ /** Lowercase provider id, e.g. `aillomvox`, `openai`. Default: `aillomvox`. */
34
+ provider?: VoxProviderId;
14
35
  voice?: string;
15
36
  language?: string;
37
+ /** Optional workspace scope; requires an API key authorized for that workspace. */
38
+ workspaceId?: string;
39
+ /**
40
+ * Required for production sessions per gateway docs; defaults are applied only client-side for quick tests.
41
+ */
16
42
  systemPrompt?: string;
17
43
  sampleRate?: 8000 | 16000 | 24000;
44
+ /**
45
+ * When true, logs outbound config (with `apikey` redacted) and unknown inbound JSON.
46
+ * Disable in production; logs and the `raw` event may contain user speech text (PII).
47
+ */
18
48
  debug?: boolean;
19
49
  tools?: ClientTool[];
50
+ /** HTTPS(S) webhook for server-side session events (if enabled for your key). */
20
51
  webhookUrl?: string;
52
+ /** Session cap in seconds (`30`-`7200`; default gateway cap is 300). */
21
53
  maxDuration?: number;
54
+ /** Spoken right after the session is ready. */
55
+ firstMessage?: string;
56
+ /** Spoken before forced hangup when `max_duration` is reached (see protocol docs). */
57
+ farewellMessage?: string;
58
+ /**
59
+ * When `provider === "aillomvox"`, selects the TTS stack from `GET /api/providers`.
60
+ * Defaults to **`inworld`** when omitted (the SDK sets `tts_engine` in the handshake).
61
+ */
62
+ ttsEngine?: AillomVoxTtsEngineId | string;
63
+ /**
64
+ * @deprecated Session model overrides are ignored by the current gateway; model selection
65
+ * is controlled server-side. Use `AillomVox.fetchProviders()` to inspect active defaults.
66
+ */
67
+ model?: string;
68
+ qualityProfile?: string;
69
+ toolTimeout?: number;
70
+ ttsBufferMs?: number;
71
+ ttsEarlyStartMs?: number;
72
+ ttsMinChunkMs?: number;
73
+ streamLlmTextToTts?: boolean;
74
+ accumulatorMs?: number;
75
+ /** Advanced provider config passed through as `extra_config`. Do not put browser-visible secrets here. */
76
+ extraConfig?: Record<string, unknown>;
77
+ /**
78
+ * WebSocket URL or HTTPS API origin. Examples:
79
+ * - `wss://vox.aillom.com/ws` (default)
80
+ * - `https://vox.aillom.com` (normalized to the same WebSocket URL)
81
+ */
22
82
  gatewayUrl?: string;
23
83
  }
24
84
  export interface TranscriptEvent {
85
+ type?: 'transcript';
25
86
  role: 'user' | 'assistant';
26
87
  text: string;
27
88
  final: boolean;
28
89
  }
29
90
  export interface ToolCallEvent {
91
+ type?: 'tool_call';
30
92
  call_id: string;
31
93
  name: string;
32
- args: any;
94
+ args: Record<string, unknown>;
95
+ }
96
+ /** Agent state (Ultravox-oriented pipeline). */
97
+ export type VoxAgentState = 'listening' | 'thinking' | 'speaking';
98
+ export interface StateEvent {
99
+ type: 'state';
100
+ state: VoxAgentState;
101
+ }
102
+ /** Engine connection milestones from the gateway. */
103
+ export interface ControlEvent {
104
+ type: 'control';
105
+ action?: string;
106
+ provider?: string;
107
+ model?: string;
108
+ tts_model?: string;
109
+ [key: string]: unknown;
110
+ }
111
+ export interface ErrorEvent {
112
+ type?: 'error';
113
+ message?: string;
114
+ error?: string;
115
+ code?: string;
116
+ }
117
+ export type EventHandler<T = unknown> = (data: T) => void;
118
+ export interface ProvidersCatalogOptions {
119
+ /** Same base you use for `gatewayUrl` / clone API; defaults to production. */
120
+ baseUrl?: string;
121
+ /** When set, `x-api-key` must belong to that workspace (gateway returns 401/403 otherwise). */
122
+ workspaceId?: string;
123
+ /** Set false to skip nested voices in `/api/providers` for faster catalog loads. */
124
+ includeVoices?: boolean;
125
+ apiKey?: string;
126
+ }
127
+ export interface VoicesCatalogOptions {
128
+ /** Provider or TTS engine id, e.g. `inworld`, `fish`, `aws`, `qwen`. */
129
+ provider: string;
130
+ baseUrl?: string;
131
+ /** When set, `x-api-key` must belong to that workspace. */
132
+ workspaceId?: string;
133
+ apiKey?: string;
134
+ pageSize?: number;
135
+ pageNumber?: number;
136
+ maxPages?: number;
137
+ q?: string;
138
+ title?: string;
139
+ tag?: string;
140
+ language?: string;
141
+ titleLanguage?: string;
142
+ sortBy?: string;
143
+ preferredLanguage?: string;
144
+ type?: string;
145
+ scope?: string;
146
+ visibility?: string;
147
+ }
148
+ export interface VoicePreviewOptions {
149
+ provider: string;
150
+ voice: string;
151
+ baseUrl?: string;
152
+ }
153
+ export interface DeleteVoiceOptions {
154
+ provider?: string;
155
+ workspaceId?: string;
156
+ baseUrl?: string;
157
+ }
158
+ export interface CloneVoiceProviderResult {
159
+ status: 'ok' | 'skipped' | 'error' | string;
160
+ voice_id?: string;
161
+ name?: string;
162
+ error?: string;
163
+ [key: string]: unknown;
33
164
  }
34
- export interface AudioEvent {
35
- buffer: ArrayBuffer;
165
+ export interface CloneVoiceResult {
166
+ voice_id: string | null;
167
+ name?: string;
168
+ workspace_id?: string | null;
169
+ providers?: Record<string, CloneVoiceProviderResult>;
170
+ message?: string;
171
+ [key: string]: unknown;
172
+ }
173
+ export interface CloneVoiceOptions {
174
+ name?: string;
175
+ description?: string;
176
+ baseUrl?: string;
177
+ gatewayUrl?: string;
178
+ filename?: string;
179
+ workspaceId?: string;
180
+ /** Comma-separated internally by the SDK. Defaults to the server route defaults. */
181
+ providers?: string[];
182
+ /** BCP 47 locale, or `AUTO`. Helps providers that need language hints. */
183
+ language?: string;
184
+ /** Exact transcript of the audio sample; recommended for Inworld and Fish Audio. */
185
+ transcription?: string;
186
+ /** Alias accepted by the gateway. */
187
+ transcript?: string;
188
+ /** Optional xAI clone metadata. */
189
+ gender?: 'male' | 'female' | 'neutral';
190
+ accent?: string;
191
+ age?: 'young' | 'middle-aged' | 'old';
192
+ tone?: 'warm' | 'casual' | 'professional' | 'friendly' | 'authoritative' | 'expressive' | 'calm';
193
+ useCase?: 'conversational' | 'narration' | 'characters' | 'educational' | 'advertisement' | 'social_media' | 'entertainment';
36
194
  }
37
- export type EventHandler<T = any> = (data: T) => void;
package/package.json CHANGED
@@ -1,13 +1,23 @@
1
1
  {
2
2
  "name": "aillom-vox-client",
3
- "version": "1.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "Enterprise-Grade Voice AI SDK for Speech-to-Speech, Audio-to-Audio, and Realtime Multimodal applications.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc",
9
9
  "dev": "tsc --watch",
10
- "test": "echo \"Error: no test specified\" && exit 1"
10
+ "typecheck": "tsc --noEmit",
11
+ "prepack": "npm run build",
12
+ "test": "npm run typecheck"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "engines": {
20
+ "node": ">=18"
11
21
  },
12
22
  "dependencies": {
13
23
  "isomorphic-ws": "^5.0.0",
@@ -34,12 +44,13 @@
34
44
  "low-latency",
35
45
  "voice-gateway",
36
46
  "sip-trunking",
37
- "asterisk",
38
- "inworld-ai",
39
- "gpt-4o-realtime",
40
47
  "telephony",
41
48
  "ultravox",
42
- "nova-sonic"
49
+ "nova-sonic",
50
+ "grok-voice",
51
+ "fish-audio",
52
+ "rime-ai",
53
+ "inworld-tts"
43
54
  ],
44
55
  "author": "Aillom Technologies <contato@aillom.com.br>",
45
56
  "license": "ISC",
@@ -47,4 +58,4 @@
47
58
  "url": "https://github.com/aillom/aillom-vox-client/issues"
48
59
  },
49
60
  "homepage": "https://vox.aillom.com"
50
- }
61
+ }
package/docs/ASTERISK.md DELETED
@@ -1,411 +0,0 @@
1
- # 📞 Asterisk 23 Integration Guide - AillomVox
2
-
3
- Complete guide for integrating **Asterisk 23** with **AillomVox** for real-time Voice AI calls.
4
-
5
- ---
6
-
7
- ## 🎯 Overview
8
-
9
- AillomVox provides **two integration architectures** for Asterisk:
10
-
11
- ### 1. **Direct Mode** (Simple)
12
- ```
13
- Asterisk → AudioSocket → AillomVox Gateway → AI Provider
14
- ```
15
- ✅ Simple voice conversations
16
- ❌ No client tools (transfer, AMI control)
17
-
18
- ### 2. **Middleware Mode** (Advanced)
19
- ```
20
- Asterisk → AudioSocket → Node.js Middleware → AillomVox Gateway
21
- ↓ AMI/ARI
22
- ```
23
- ✅ Client tools enabled (transfer, hangup, dial)
24
- ✅ Full Asterisk control from AI
25
-
26
- ---
27
-
28
- ## 📋 Prerequisites
29
-
30
- ### Asterisk Requirements
31
- - **Asterisk 23** (or 18+)
32
- - **AudioSocket** module compiled and enabled
33
- - **API Key** for AillomVox gateway
34
-
35
- ### Verify AudioSocket Module
36
- ```bash
37
- asterisk -rx "module show like audiosocket"
38
- ```
39
-
40
- Expected output:
41
- ```
42
- Module Description
43
- res_audiosocket.so AudioSocket
44
- ```
45
-
46
- If not loaded:
47
- ```bash
48
- # Load module
49
- asterisk -rx "module load res_audiosocket"
50
-
51
- # Make it persistent
52
- echo "load = res_audiosocket.so" >> /etc/asterisk/modules.conf
53
- ```
54
-
55
- ---
56
-
57
- ## 🔐 Authentication
58
-
59
- AillomVox uses **API Key** authentication for security and usage tracking.
60
-
61
- ### Getting Your API Key
62
-
63
- Get your API key from the AillomVox dashboard or contact support.
64
-
65
- ### Storing API Key
66
-
67
- Store in `extensions.conf`:
68
-
69
- ```ini
70
- [globals]
71
- AILLOM_API_KEY=your-api-key-here
72
- ```
73
-
74
- ---
75
-
76
- ## 🏗️ Architecture 1: Direct Mode (Simple)
77
-
78
- ### When to Use
79
- - Simple AI voice conversations
80
- - No need to transfer calls or control Asterisk
81
- - Just want AI to answer and respond
82
-
83
- ### Dialplan Configuration
84
-
85
- ```ini
86
- [from-internal]
87
-
88
- ; Call extension 6000 to talk to AI
89
- exten => 6000,1,NoOp(AillomVox Direct Mode)
90
- same => n,Set(WS_URL=ws://vox.aillom.com/ws?apiKey=${AILLOM_API_KEY})
91
- same => n,Set(CONFIG={"provider":"aillomvox","voice":"Heitor","language":"pt-BR","system_prompt":"Você é um assistente. Seja conciso.","first_message":"Olá! Como posso ajudar?","sample_rate":8000})
92
- same => n,Answer()
93
- same => n,AudioSocket(${WS_URL},${CONFIG})
94
- same => n,Hangup()
95
- ```
96
-
97
- ### Configuration JSON
98
-
99
- ```json
100
- {
101
- "provider": "aillomvox",
102
- "voice": "Heitor",
103
- "language": "pt-BR",
104
- "system_prompt": "Você é um assistente virtual.",
105
- "first_message": "Olá! Como posso ajudar?",
106
- "farewell_message": "Obrigado por ligar. Até logo!",
107
- "sample_rate": 8000,
108
- "max_duration": 300
109
- }
110
- ```
111
-
112
- **Note**: No `tools` array needed in Direct Mode.
113
-
114
- ---
115
-
116
- ## 🏗️ Architecture 2: Middleware Mode (Advanced)
117
-
118
- ### When to Use
119
- - AI needs to **transfer** calls to extensions
120
- - AI needs to **hangup** via AMI (not just end conversation)
121
- - AI needs to **dial** external numbers
122
- - Advanced call control
123
-
124
- ### Architecture
125
- ```
126
- Asterisk → AudioSocket (port 9000) → Node.js Middleware
127
-
128
- AMI/ARI Control
129
-
130
- AillomVox Gateway
131
- ```
132
-
133
- ### Step 1: Install Dependencies
134
-
135
- ```bash
136
- npm install aillom-vox-client asterisk-manager
137
- ```
138
-
139
- ### Step 2: Create Middleware (`asterisk-bridge.js`)
140
-
141
- ```javascript
142
- const net = require('net');
143
- const AillomVoxClient = require('aillom-vox-client');
144
- const AMI = require('asterisk-manager');
145
-
146
- // AMI connection for Asterisk control
147
- const ami = new AMI(5038, 'localhost', 'admin', 'secret', true);
148
-
149
- ami.keepConnected();
150
-
151
- // AudioSocket server (receives from Asterisk)
152
- const server = net.createServer((socket) => {
153
- console.log('[Bridge] New call from Asterisk');
154
-
155
- // Connect to AillomVox
156
- const client = new AillomVoxClient({
157
- apiKey: process.env.AILLOM_API_KEY,
158
- url: 'wss://vox.aillom.com/ws'
159
- });
160
-
161
- // Register client tools
162
- client.connect({
163
- provider: 'aillomvox',
164
- voice: 'Heitor',
165
- language: 'pt-BR',
166
- system_prompt: 'Você é um assistente. Se o usuário pedir, transfira para ramal 100 ou desligue a ligação.',
167
- sample_rate: 8000,
168
- tools: [{
169
- name: 'hangup',
170
- description: 'End the call',
171
- parameters: { type: 'object', properties: {} }
172
- }, {
173
- name: 'transfer',
174
- description: 'Transfer call to extension',
175
- parameters: {
176
- type: 'object',
177
- properties: {
178
- extension: { type: 'string', description: 'Target extension' }
179
- },
180
- required: ['extension']
181
- }
182
- }]
183
- });
184
-
185
- // Handle tool calls from AI
186
- client.on('tool_call', async (tool) => {
187
- console.log(`[Tool] AI called: ${tool.name}`, tool.args);
188
-
189
- if (tool.name === 'hangup') {
190
- console.log('[Tool] Hanging up call');
191
- socket.end();
192
- client.disconnect();
193
- return 'Call ended';
194
- }
195
-
196
- if (tool.name === 'transfer') {
197
- const ext = tool.args.extension;
198
- console.log(`[Tool] Transferring to ${ext}`);
199
-
200
- // Use AMI to transfer (implement based on your channel tracking)
201
- ami.action({
202
- action: 'redirect',
203
- channel: 'PJSIP/1234-00000001', // Track this from call setup
204
- exten: ext,
205
- context: 'from-internal',
206
- priority: 1
207
- });
208
-
209
- return `Transferred to extension ${ext}`;
210
- }
211
- });
212
-
213
- // Pipe audio: Asterisk ↔ AillomVox
214
- socket.on('data', (data) => {
215
- // Parse AudioSocket protocol if needed, then send PCM
216
- client.sendAudio(data);
217
- });
218
-
219
- client.on('audio', (pcmData) => {
220
- socket.write(pcmData);
221
- });
222
-
223
- socket.on('end', () => {
224
- console.log('[Bridge] Asterisk closed connection');
225
- client.disconnect();
226
- });
227
- });
228
-
229
- server.listen(9000, '127.0.0.1', () => {
230
- console.log('[Bridge] Listening on 127.0.0.1:9000');
231
- });
232
- ```
233
-
234
- ### Step 3: Configure Asterisk
235
-
236
- ```ini
237
- [from-internal]
238
-
239
- ; Call extension 7000 using middleware (with client tools)
240
- exten => 7000,1,NoOp(AillomVox Middleware Mode)
241
- same => n,Set(CONFIG={"provider":"aillomvox"})
242
- same => n,Answer()
243
- same => n,AudioSocket(127.0.0.1:9000,${CONFIG})
244
- same => n,Hangup()
245
- ```
246
-
247
- ### Step 4: Run Middleware
248
-
249
- ```bash
250
- AILLOM_API_KEY=your-api-key node asterisk-bridge.js
251
- ```
252
-
253
- ### Step 5: Test
254
-
255
- Call extension 7000 and say:
256
- - "Transfer me to extension 100" → AI calls `transfer` tool
257
- - "Goodbye" → AI calls `hangup` tool
258
-
259
- ---
260
-
261
- ## 🎙️ Audio Format
262
-
263
- ### AudioSocket Protocol
264
- - **Format**: PCM 16-bit signed little-endian (`slin`)
265
- - **Sample Rate**: 8000 Hz (telephony standard)
266
- - **Channels**: 1 (mono)
267
- - **Encoding**: `pcm_s16le`
268
-
269
- ### Codec Conversion (ulaw/alaw → slin)
270
-
271
- **No Brasil e na maioria dos países**, trunks SIP usam:
272
- - **ulaw** (G.711μ) - Padrão nos EUA/Brasil
273
- - **alaw** (G.711a) - Padrão na Europa
274
-
275
- **Asterisk converte automaticamente**:
276
- ```
277
- Trunk SIP (ulaw/alaw) → Asterisk → slin → AudioSocket → AillomVox
278
- ```
279
-
280
- Não precisa configurar nada! Asterisk faz a conversão transparente.
281
-
282
- ### Forcing Codec (Optional)
283
-
284
- Se tiver problemas de áudio, force o codec:
285
-
286
- ```ini
287
- exten => 6000,1,Set(CHANNEL(audioreadformat)=slin)
288
- same => n,Set(CHANNEL(audiowriteformat)=slin)
289
- same => n,Answer()
290
- same => n,AudioSocket(...)
291
- ```
292
-
293
- Isso garante que Asterisk sempre entrega PCM 16-bit para o AudioSocket.
294
-
295
- ---
296
-
297
- ## 🌍 Multi-Provider Examples (Direct Mode)
298
-
299
- ### AillomVox (Best for Telephony)
300
-
301
- ```ini
302
- exten => 7001,1,Set(CONFIG={"provider":"aillomvox","voice":"Heitor","sample_rate":8000})
303
- same => n,AudioSocket(ws://vox.aillom.com/ws?apiKey=${AILLOM_API_KEY},${CONFIG})
304
- ```
305
-
306
- **Why?** Lowest latency, optimized for 8kHz, $0.03/min.
307
-
308
- ### Gemini 2.5 Flash
309
-
310
- ```ini
311
- exten => 7002,1,Set(CONFIG={"provider":"gemini","voice":"Puck","sample_rate":8000})
312
- same => n,AudioSocket(ws://vox.aillom.com/ws?apiKey=${AILLOM_API_KEY},${CONFIG})
313
- ```
314
-
315
- **Why?** Multimodal, fast, $0.06/min.
316
-
317
- ### OpenAI Realtime
318
-
319
- ```ini
320
- exten => 7003,1,Set(CONFIG={"provider":"openai","voice":"shimmer","sample_rate":8000})
321
- same => n,AudioSocket(ws://vox.aillom.com/ws?apiKey=${AILLOM_API_KEY},${CONFIG})
322
- ```
323
-
324
- **Why?** Best for complex reasoning, $0.10/min.
325
-
326
- ---
327
-
328
- ## ⚠️ Troubleshooting
329
-
330
- ### Problem: "Module audiosocket not loaded"
331
-
332
- ```bash
333
- asterisk -rx "module load res_audiosocket"
334
- echo "load = res_audiosocket.so" >> /etc/asterisk/modules.conf
335
- ```
336
-
337
- ### Problem: "Connection refused"
338
-
339
- **Direct Mode**: Check firewall, verify server is running
340
- **Middleware Mode**: Ensure middleware is running on `127.0.0.1:9000`
341
-
342
- ```bash
343
- # Test direct connection
344
- curl -I https://vox.aillom.com/health
345
-
346
- # Test middleware
347
- netstat -tuln | grep 9000
348
- ```
349
-
350
- ### Problem: "No audio"
351
-
352
- Force codec:
353
- ```ini
354
- exten => 6000,1,Set(CHANNEL(audioreadformat)=slin)
355
- same => n,Set(CHANNEL(audiowriteformat)=slin)
356
- same => n,AudioSocket(...)
357
- ```
358
-
359
- ---
360
-
361
- ## 📊 Configuration Options
362
-
363
- | Field | Type | Description | Default |
364
- |-------|------|-------------|---------|
365
- | `provider` | string | `aillomvox`, `gemini`, `openai`, `qwen`, `grok`, `aws`, `ultravox` | **Required** |
366
- | `voice` | string | Voice ID (provider-specific) | **Required** |
367
- | `language` | string | `pt-BR`, `en-US`, `es-ES`, etc | `en-US` |
368
- | `system_prompt` | string | Instructions for AI | **Required** |
369
- | `first_message` | string | Initial greeting | `null` |
370
- | `farewell_message` | string | Goodbye message | `null` |
371
- | `sample_rate` | number | `8000` (tel), `16000` (hd) | **Required** |
372
- | `max_duration` | number | Max seconds (120-3600) | `300` |
373
- | `tools` | array | Client tools (Middleware only) | `[]` |
374
-
375
- ---
376
-
377
- ## 🌐 Production Checklist
378
-
379
- - [ ] AudioSocket module loaded and persistent
380
- - [ ] API key stored securely in `[globals]`
381
- - [ ] Sample rate set to 8000 Hz
382
- - [ ] Max duration configured
383
- - [ ] If using Middleware: process manager (PM2, systemd)
384
- - [ ] If using Middleware: AMI credentials configured
385
- - [ ] Tested with real calls
386
- - [ ] Monitoring enabled
387
-
388
- ---
389
-
390
- ## 💡 Which Architecture Should I Use?
391
-
392
- | Feature | Direct Mode | Middleware Mode |
393
- |---------|-------------|-----------------|
394
- | Simple conversations | ✅ Yes | ✅ Yes |
395
- | Transfer calls | ❌ No | ✅ Yes |
396
- | Hangup via AMI | ❌ No | ✅ Yes |
397
- | Dial external numbers | ❌ No | ✅ Yes |
398
- | Complexity | Low | Medium |
399
- | Setup | 2 minutes | 10 minutes |
400
-
401
- **Recommendation**: Start with **Direct Mode**. Upgrade to **Middleware** when you need client tools.
402
-
403
- ---
404
-
405
- ## 📚 Additional Resources
406
-
407
- - [Client Tools Guide](TOOLS.md)
408
- - [AillomVox Protocol](PROTOCOL.md)
409
- - [Provider Comparison](PROVIDERS.md)
410
-
411
- Happy building! 🎉