convoai 1.7.0 → 1.8.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 +38 -2
- package/dist/src/api/types.d.ts +6 -0
- package/dist/src/commands/completion.js +1 -1
- package/dist/src/commands/completion.js.map +1 -1
- package/dist/src/commands/phone/_dashboard.d.ts +31 -0
- package/dist/src/commands/phone/_dashboard.js +127 -0
- package/dist/src/commands/phone/_dashboard.js.map +1 -0
- package/dist/src/commands/phone/_helpers.d.ts +18 -0
- package/dist/src/commands/phone/_helpers.js +35 -0
- package/dist/src/commands/phone/_helpers.js.map +1 -1
- package/dist/src/commands/phone/_modes/agent.d.ts +22 -0
- package/dist/src/commands/phone/_modes/agent.js +59 -0
- package/dist/src/commands/phone/_modes/agent.js.map +1 -0
- package/dist/src/commands/phone/_modes/free.d.ts +29 -0
- package/dist/src/commands/phone/_modes/free.js +44 -0
- package/dist/src/commands/phone/_modes/free.js.map +1 -0
- package/dist/src/commands/phone/_modes/translate.d.ts +30 -0
- package/dist/src/commands/phone/_modes/translate.js +89 -0
- package/dist/src/commands/phone/_modes/translate.js.map +1 -0
- package/dist/src/commands/phone/go.d.ts +2 -0
- package/dist/src/commands/phone/go.js +235 -0
- package/dist/src/commands/phone/go.js.map +1 -0
- package/dist/src/commands/phone/send.js +13 -21
- package/dist/src/commands/phone/send.js.map +1 -1
- package/dist/src/config/schema.d.ts +23 -0
- package/dist/src/config/schema.js +6 -0
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
- package/src/web/phone-dashboard.html +180 -0
package/README.md
CHANGED
|
@@ -28,8 +28,9 @@ Start, manage, and monitor conversational AI agents from your terminal. One comm
|
|
|
28
28
|
- **Real-time agent monitoring** -- live status, latency, and conversation turns in the runtime panel
|
|
29
29
|
- **Built-in presets** -- start with OpenAI, Anthropic, Gemini, or Realtime in one flag
|
|
30
30
|
- **Profile management** -- switch between dev, staging, and prod with a single option
|
|
31
|
+
- **Phone calls** -- `convoai phone send` makes outbound calls with SIP, `--wait` shows live status
|
|
32
|
+
- **Number management** -- import, list, update, remove phone numbers (Twilio or BYO SIP)
|
|
31
33
|
- **Shell completions** -- tab-complete commands in bash, zsh, and fish
|
|
32
|
-
- **Telephony support (beta)** -- initiate and manage phone calls through ConvoAI
|
|
33
34
|
|
|
34
35
|
---
|
|
35
36
|
|
|
@@ -47,6 +48,9 @@ convoai dev
|
|
|
47
48
|
# Or instant voice chat — zero setup
|
|
48
49
|
convoai go
|
|
49
50
|
|
|
51
|
+
# Or make a phone call
|
|
52
|
+
convoai phone send
|
|
53
|
+
|
|
50
54
|
# Override the model on the fly
|
|
51
55
|
convoai go --model gpt-4o
|
|
52
56
|
|
|
@@ -93,6 +97,37 @@ my-app/
|
|
|
93
97
|
|
|
94
98
|
---
|
|
95
99
|
|
|
100
|
+
## Phone Go (v1.8.0)
|
|
101
|
+
|
|
102
|
+
One-command phone experience — translate calls, agent outbound, or free calls with a live dashboard:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Interactive — choose mode, fill in details
|
|
106
|
+
convoai phone go
|
|
107
|
+
|
|
108
|
+
# Translate call — each side speaks their own language
|
|
109
|
+
convoai phone go --mode translate --lang zh:ja --to +81312345678
|
|
110
|
+
|
|
111
|
+
# Agent outbound — AI completes a task autonomously
|
|
112
|
+
convoai phone go --mode agent --task "Book dinner for 2 at 7pm" --task-lang ja --to +81312345678
|
|
113
|
+
|
|
114
|
+
# Free call — quick dial with optional AI assistance
|
|
115
|
+
convoai phone go --mode free --to +15559876543
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Live browser dashboard shows call status, translation text, and a hang-up button.
|
|
119
|
+
|
|
120
|
+
**Phone calls & number management:**
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
convoai phone send # Make an outbound call (flag mode)
|
|
124
|
+
convoai phone import # Import a number (Twilio or BYO SIP)
|
|
125
|
+
convoai phone numbers # List your numbers
|
|
126
|
+
convoai phone remove <num> # Remove a number
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
96
131
|
## Installation
|
|
97
132
|
|
|
98
133
|
### npm (recommended)
|
|
@@ -187,8 +222,9 @@ Commands are organized into scenario groups:
|
|
|
187
222
|
|---|---|
|
|
188
223
|
| **Start** | `go`, `quickstart` |
|
|
189
224
|
| **Agent** | `agent start`, `agent stop`, `agent status`, `agent list`, `agent update`, `agent speak`, `agent interrupt`, `agent history`, `agent turns`, `agent join` |
|
|
225
|
+
| **Phone** | `phone go`, `phone send`, `phone numbers`, `phone import`, `phone number`, `phone update`, `phone remove`, `phone hangup`, `phone status`, `phone history` |
|
|
190
226
|
| **Config** | `config init`, `config set`, `config get`, `config show`, `config path`, `auth login`, `auth logout`, `auth status` |
|
|
191
|
-
| **More** | `preset list`, `preset use`, `template save/list/show/delete/use`, `
|
|
227
|
+
| **More** | `preset list`, `preset use`, `template save/list/show/delete/use`, `token`, `completion` |
|
|
192
228
|
|
|
193
229
|
---
|
|
194
230
|
|
package/dist/src/api/types.d.ts
CHANGED
|
@@ -191,6 +191,11 @@ export interface ApiErrorResponse {
|
|
|
191
191
|
detail: string;
|
|
192
192
|
reason: string;
|
|
193
193
|
}
|
|
194
|
+
export interface VoiceProfile {
|
|
195
|
+
id?: string;
|
|
196
|
+
provider?: string;
|
|
197
|
+
voice_id?: string;
|
|
198
|
+
}
|
|
194
199
|
export interface ConvoAIConfig {
|
|
195
200
|
app_id?: string;
|
|
196
201
|
app_certificate?: string;
|
|
@@ -200,6 +205,7 @@ export interface ConvoAIConfig {
|
|
|
200
205
|
region?: 'global' | 'cn';
|
|
201
206
|
default_profile?: string;
|
|
202
207
|
profiles?: Record<string, ProfileConfig>;
|
|
208
|
+
voice_profile?: VoiceProfile;
|
|
203
209
|
}
|
|
204
210
|
export interface ProfileConfig {
|
|
205
211
|
app_id?: string;
|
|
@@ -6,7 +6,7 @@ import { handleError } from '../utils/errors.js';
|
|
|
6
6
|
// ─── Completion Data ──────────────────────────────────────────────────────
|
|
7
7
|
const TOP_LEVEL_COMMANDS = ['go', 'init', 'dev', 'quickstart', 'openclaw', 'phone', 'auth', 'agent', 'call', 'config', 'preset', 'template', 'token', 'completion'];
|
|
8
8
|
const SUBCOMMANDS = {
|
|
9
|
-
phone: ['send', 'numbers', 'import', 'number', 'update', 'remove', 'hangup', 'status', 'history'],
|
|
9
|
+
phone: ['go', 'send', 'numbers', 'import', 'number', 'update', 'remove', 'hangup', 'status', 'history'],
|
|
10
10
|
agent: ['start', 'stop', 'status', 'list', 'update', 'speak', 'interrupt', 'history', 'turns', 'join', 'chat', 'panel'],
|
|
11
11
|
auth: ['login', 'logout', 'status'],
|
|
12
12
|
call: ['initiate', 'hangup', 'status'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/commands/completion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7F,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,6EAA6E;AAE7E,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;AAEpK,MAAM,WAAW,GAA6B;IAC5C,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/commands/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CallAPI } from '../../api/calls.js';
|
|
2
|
+
/** Format a Server-Sent Event message. */
|
|
3
|
+
export declare function formatSSE(event: string, data: unknown): string;
|
|
4
|
+
/** Find first available port in range [start, start+9]. */
|
|
5
|
+
export declare function findAvailablePort(start: number): Promise<number>;
|
|
6
|
+
export interface DashboardOptions {
|
|
7
|
+
mode: string;
|
|
8
|
+
label: string;
|
|
9
|
+
agentId: string;
|
|
10
|
+
callApi: CallAPI;
|
|
11
|
+
config?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export declare class PhoneDashboard {
|
|
14
|
+
private readonly opts;
|
|
15
|
+
private server;
|
|
16
|
+
private sseClients;
|
|
17
|
+
private pollTimer;
|
|
18
|
+
private startTime;
|
|
19
|
+
private port;
|
|
20
|
+
constructor(opts: DashboardOptions);
|
|
21
|
+
/** Start the dashboard server and begin polling call status. */
|
|
22
|
+
start(): Promise<number>;
|
|
23
|
+
/** Stop the dashboard server and clean up. */
|
|
24
|
+
stop(): Promise<void>;
|
|
25
|
+
/** Broadcast an SSE event to all connected clients. */
|
|
26
|
+
private broadcast;
|
|
27
|
+
/** Poll call status from Agora API and broadcast updates. */
|
|
28
|
+
private pollStatus;
|
|
29
|
+
private handleRequest;
|
|
30
|
+
private loadHTML;
|
|
31
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import net from 'node:net';
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
/** Format a Server-Sent Event message. */
|
|
8
|
+
export function formatSSE(event, data) {
|
|
9
|
+
return `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
10
|
+
}
|
|
11
|
+
/** Find first available port in range [start, start+9]. */
|
|
12
|
+
export async function findAvailablePort(start) {
|
|
13
|
+
for (let port = start; port <= start + 9; port++) {
|
|
14
|
+
const available = await new Promise((resolve) => {
|
|
15
|
+
const server = net.createServer();
|
|
16
|
+
server.once('error', () => resolve(false));
|
|
17
|
+
server.once('listening', () => { server.close(); resolve(true); });
|
|
18
|
+
server.listen(port);
|
|
19
|
+
});
|
|
20
|
+
if (available)
|
|
21
|
+
return port;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`No available port in range ${start}–${start + 9}`);
|
|
24
|
+
}
|
|
25
|
+
export class PhoneDashboard {
|
|
26
|
+
opts;
|
|
27
|
+
server = null;
|
|
28
|
+
sseClients = new Set();
|
|
29
|
+
pollTimer = null;
|
|
30
|
+
startTime = Date.now();
|
|
31
|
+
port = 3211;
|
|
32
|
+
constructor(opts) {
|
|
33
|
+
this.opts = opts;
|
|
34
|
+
}
|
|
35
|
+
/** Start the dashboard server and begin polling call status. */
|
|
36
|
+
async start() {
|
|
37
|
+
this.port = await findAvailablePort(3211);
|
|
38
|
+
const html = this.loadHTML();
|
|
39
|
+
this.server = createServer((req, res) => this.handleRequest(req, res, html));
|
|
40
|
+
await new Promise((resolve) => this.server.listen(this.port, '127.0.0.1', resolve));
|
|
41
|
+
// Start polling call status
|
|
42
|
+
this.pollTimer = setInterval(() => this.pollStatus(), 2000);
|
|
43
|
+
return this.port;
|
|
44
|
+
}
|
|
45
|
+
/** Stop the dashboard server and clean up. */
|
|
46
|
+
async stop() {
|
|
47
|
+
if (this.pollTimer)
|
|
48
|
+
clearInterval(this.pollTimer);
|
|
49
|
+
for (const client of this.sseClients) {
|
|
50
|
+
client.end();
|
|
51
|
+
}
|
|
52
|
+
this.sseClients.clear();
|
|
53
|
+
if (this.server) {
|
|
54
|
+
await new Promise((resolve) => this.server.close(() => resolve()));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Broadcast an SSE event to all connected clients. */
|
|
58
|
+
broadcast(event, data) {
|
|
59
|
+
const msg = formatSSE(event, data);
|
|
60
|
+
for (const client of this.sseClients) {
|
|
61
|
+
client.write(msg);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Poll call status from Agora API and broadcast updates. */
|
|
65
|
+
async pollStatus() {
|
|
66
|
+
try {
|
|
67
|
+
const status = await this.opts.callApi.status(this.opts.agentId);
|
|
68
|
+
const elapsed = Math.floor((Date.now() - this.startTime) / 1000);
|
|
69
|
+
this.broadcast('status', {
|
|
70
|
+
status: status.status,
|
|
71
|
+
duration: elapsed,
|
|
72
|
+
channel: status.channel,
|
|
73
|
+
message: status.message,
|
|
74
|
+
});
|
|
75
|
+
if (status.status === 'STOPPED' || status.status === 'FAILED') {
|
|
76
|
+
this.broadcast('ended', { status: status.status, duration: elapsed });
|
|
77
|
+
if (this.pollTimer)
|
|
78
|
+
clearInterval(this.pollTimer);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Ignore poll errors — dashboard stays alive
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
handleRequest(req, res, html) {
|
|
86
|
+
const pathname = (req.url || '/').split('?')[0];
|
|
87
|
+
if (pathname === '/events' && req.method === 'GET') {
|
|
88
|
+
// SSE endpoint
|
|
89
|
+
res.writeHead(200, {
|
|
90
|
+
'Content-Type': 'text/event-stream',
|
|
91
|
+
'Cache-Control': 'no-cache',
|
|
92
|
+
Connection: 'keep-alive',
|
|
93
|
+
'Access-Control-Allow-Origin': '*',
|
|
94
|
+
});
|
|
95
|
+
this.sseClients.add(res);
|
|
96
|
+
req.on('close', () => this.sseClients.delete(res));
|
|
97
|
+
// Send current state immediately
|
|
98
|
+
res.write(formatSSE('init', {
|
|
99
|
+
mode: this.opts.mode,
|
|
100
|
+
label: this.opts.label,
|
|
101
|
+
agentId: this.opts.agentId,
|
|
102
|
+
config: this.opts.config ?? {},
|
|
103
|
+
}));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (pathname === '/hangup' && req.method === 'POST') {
|
|
107
|
+
this.opts.callApi.hangup(this.opts.agentId)
|
|
108
|
+
.then(() => {
|
|
109
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
110
|
+
res.end(JSON.stringify({ ok: true }));
|
|
111
|
+
})
|
|
112
|
+
.catch((err) => {
|
|
113
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
114
|
+
res.end(JSON.stringify({ error: String(err) }));
|
|
115
|
+
});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Serve dashboard HTML
|
|
119
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
120
|
+
res.end(html);
|
|
121
|
+
}
|
|
122
|
+
loadHTML() {
|
|
123
|
+
const htmlPath = join(__dirname, '../../web/phone-dashboard.html');
|
|
124
|
+
return readFileSync(htmlPath, 'utf-8');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=_dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_dashboard.js","sourceRoot":"","sources":["../../../../src/commands/phone/_dashboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { CallAPI } from '../../api/calls.js';
|
|
2
2
|
import { NumberAPI } from '../../api/numbers.js';
|
|
3
3
|
import type { PhoneNumber } from '../../api/numbers.js';
|
|
4
|
+
import type { SendCallRequest } from '../../api/calls.js';
|
|
5
|
+
import type { VoiceProfile, TTSConfig } from '../../api/types.js';
|
|
4
6
|
export declare function isE164(phone: string): boolean;
|
|
5
7
|
export declare function validateE164(phone: string): string;
|
|
6
8
|
/** Create a project-scoped CallAPI (baseURL includes /projects/{appId}). */
|
|
@@ -10,3 +12,19 @@ export declare function getNumberAPI(profileName?: string): NumberAPI;
|
|
|
10
12
|
/** Get resolved config. */
|
|
11
13
|
export declare function getConfig(profileName?: string): import("../../api/types.js").ProfileConfig;
|
|
12
14
|
export declare function pickOutboundNumber(numbers: PhoneNumber[]): Promise<PhoneNumber>;
|
|
15
|
+
/** Generate a unique channel name for phone calls. */
|
|
16
|
+
export declare function buildChannelName(): string;
|
|
17
|
+
/** Build a SendCallRequest from resolved parameters. */
|
|
18
|
+
export declare function buildCallRequest(params: {
|
|
19
|
+
fromNumber: string;
|
|
20
|
+
toNumber: string;
|
|
21
|
+
channelName: string;
|
|
22
|
+
agentToken: string;
|
|
23
|
+
sipToken: string;
|
|
24
|
+
llm: Record<string, unknown>;
|
|
25
|
+
tts: Record<string, unknown>;
|
|
26
|
+
asr: Record<string, unknown>;
|
|
27
|
+
idleTimeout?: number;
|
|
28
|
+
}): SendCallRequest;
|
|
29
|
+
/** Build TTS config, optionally applying a voice profile override. */
|
|
30
|
+
export declare function buildTTSConfig(baseTTS: Partial<TTSConfig>, voiceProfile?: VoiceProfile): Partial<TTSConfig>;
|
|
@@ -95,4 +95,39 @@ export async function pickOutboundNumber(numbers) {
|
|
|
95
95
|
}]);
|
|
96
96
|
return outbound.find(n => n.phone_number === selected);
|
|
97
97
|
}
|
|
98
|
+
// ─── Shared Call-Building Helpers ───────────────────────────────────────────
|
|
99
|
+
/** Generate a unique channel name for phone calls. */
|
|
100
|
+
export function buildChannelName() {
|
|
101
|
+
return `call-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`;
|
|
102
|
+
}
|
|
103
|
+
/** Build a SendCallRequest from resolved parameters. */
|
|
104
|
+
export function buildCallRequest(params) {
|
|
105
|
+
return {
|
|
106
|
+
name: `call-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
107
|
+
sip: {
|
|
108
|
+
to_number: params.toNumber,
|
|
109
|
+
from_number: params.fromNumber,
|
|
110
|
+
rtc_uid: '1',
|
|
111
|
+
rtc_token: params.sipToken,
|
|
112
|
+
},
|
|
113
|
+
properties: {
|
|
114
|
+
channel: params.channelName,
|
|
115
|
+
token: params.agentToken,
|
|
116
|
+
agent_rtc_uid: '0',
|
|
117
|
+
remote_rtc_uids: ['1'],
|
|
118
|
+
idle_timeout: params.idleTimeout ?? 600,
|
|
119
|
+
llm: params.llm,
|
|
120
|
+
tts: params.tts,
|
|
121
|
+
asr: params.asr,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Build TTS config, optionally applying a voice profile override. */
|
|
126
|
+
export function buildTTSConfig(baseTTS, voiceProfile) {
|
|
127
|
+
const tts = { ...baseTTS, params: { ...baseTTS.params } };
|
|
128
|
+
if (voiceProfile?.voice_id) {
|
|
129
|
+
tts.params = { ...tts.params, voice: voiceProfile.voice_id };
|
|
130
|
+
}
|
|
131
|
+
return tts;
|
|
132
|
+
}
|
|
98
133
|
//# sourceMappingURL=_helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../../src/commands/phone/_helpers.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../../src/commands/phone/_helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LLMConfig, TTSConfig, ASRConfig } from '../../../api/types.js';
|
|
2
|
+
import type { CallConfig } from './free.js';
|
|
3
|
+
export interface AgentCallParams {
|
|
4
|
+
toNumber: string;
|
|
5
|
+
fromNumber: string;
|
|
6
|
+
task: string;
|
|
7
|
+
taskLang: string;
|
|
8
|
+
llm: Partial<LLMConfig>;
|
|
9
|
+
tts: Partial<TTSConfig>;
|
|
10
|
+
asr: Partial<ASRConfig>;
|
|
11
|
+
}
|
|
12
|
+
export declare function buildAgentCallConfig(params: AgentCallParams): CallConfig;
|
|
13
|
+
/** Interactive parameter collection for agent mode. */
|
|
14
|
+
export declare function collectAgentParams(opts: {
|
|
15
|
+
to?: string;
|
|
16
|
+
task?: string;
|
|
17
|
+
taskLang?: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
toNumber: string;
|
|
20
|
+
task: string;
|
|
21
|
+
taskLang: string;
|
|
22
|
+
}>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SUPPORTED_LANGUAGES } from './translate.js';
|
|
2
|
+
export function buildAgentCallConfig(params) {
|
|
3
|
+
const agentPrompt = `You are an AI phone agent. Your task: ${params.task}\n\n` +
|
|
4
|
+
`Speak in ${params.taskLang}. Be polite and professional. ` +
|
|
5
|
+
`Introduce yourself, state your purpose clearly, and work toward completing the task. ` +
|
|
6
|
+
`If you successfully complete the task, confirm the details. ` +
|
|
7
|
+
`If the task cannot be completed, politely end the conversation.`;
|
|
8
|
+
return {
|
|
9
|
+
mode: 'agent',
|
|
10
|
+
toNumber: params.toNumber,
|
|
11
|
+
fromNumber: params.fromNumber,
|
|
12
|
+
llm: {
|
|
13
|
+
...params.llm,
|
|
14
|
+
system_messages: [{ role: 'system', content: agentPrompt }],
|
|
15
|
+
},
|
|
16
|
+
tts: { ...params.tts },
|
|
17
|
+
asr: { ...params.asr, language: params.taskLang },
|
|
18
|
+
idleTimeout: 900,
|
|
19
|
+
label: `🤖 Agent → ${params.toNumber}`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Interactive parameter collection for agent mode. */
|
|
23
|
+
export async function collectAgentParams(opts) {
|
|
24
|
+
const { default: inquirer } = await import('inquirer');
|
|
25
|
+
const { validateE164 } = await import('../_helpers.js');
|
|
26
|
+
let task = opts.task;
|
|
27
|
+
if (!task) {
|
|
28
|
+
const ans = await inquirer.prompt([{
|
|
29
|
+
type: 'input',
|
|
30
|
+
name: 'task',
|
|
31
|
+
message: 'Describe the task:',
|
|
32
|
+
validate: (v) => v.trim().length > 0 || 'Task description is required',
|
|
33
|
+
}]);
|
|
34
|
+
task = ans.task;
|
|
35
|
+
}
|
|
36
|
+
let toNumber = opts.to;
|
|
37
|
+
if (!toNumber) {
|
|
38
|
+
const ans = await inquirer.prompt([{
|
|
39
|
+
type: 'input',
|
|
40
|
+
name: 'to',
|
|
41
|
+
message: 'Phone number to call (E.164):',
|
|
42
|
+
validate: (v) => /^\+[1-9]\d{1,14}$/.test(v.trim()) || 'Invalid E.164 format',
|
|
43
|
+
}]);
|
|
44
|
+
toNumber = ans.to;
|
|
45
|
+
}
|
|
46
|
+
toNumber = validateE164(toNumber);
|
|
47
|
+
let taskLang = opts.taskLang;
|
|
48
|
+
if (!taskLang) {
|
|
49
|
+
const ans = await inquirer.prompt([{
|
|
50
|
+
type: 'list',
|
|
51
|
+
name: 'lang',
|
|
52
|
+
message: 'Language to speak:',
|
|
53
|
+
choices: SUPPORTED_LANGUAGES,
|
|
54
|
+
}]);
|
|
55
|
+
taskLang = ans.lang;
|
|
56
|
+
}
|
|
57
|
+
return { toNumber, task: task, taskLang: taskLang };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../../src/commands/phone/_modes/agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAYrD,MAAM,UAAU,oBAAoB,CAAC,MAAuB;IAC1D,MAAM,WAAW,GACf,yCAAyC,MAAM,CAAC,IAAI,MAAM;QAC1D,YAAY,MAAM,CAAC,QAAQ,gCAAgC;QAC3D,uFAAuF;QACvF,8DAA8D;QAC9D,iEAAiE,CAAC;IAEpE,OAAO;QACL,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,EAAE;YACH,GAAG,MAAM,CAAC,GAAG;YACb,eAAe,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;SAC5D;QACD,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE;QACjD,WAAW,EAAE,GAAG;QAChB,KAAK,EAAE,cAAc,MAAM,CAAC,QAAQ,EAAE;KACvC,CAAC;AACJ,CAAC;AAED,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAIxC;IACC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAExD,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,oBAAoB;gBAC7B,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,8BAA8B;aAC/E,CAAC,CAAC,CAAC;QACJ,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,+BAA+B;gBACxC,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,sBAAsB;aACtF,CAAC,CAAC,CAAC;QACJ,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,QAAQ,GAAG,YAAY,CAAC,QAAS,CAAC,CAAC;IAEnC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC7B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,oBAAoB;gBAC7B,OAAO,EAAE,mBAAmB;aAC7B,CAAC,CAAC,CAAC;QACJ,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAK,EAAE,QAAQ,EAAE,QAAS,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { LLMConfig, TTSConfig, ASRConfig } from '../../../api/types.js';
|
|
2
|
+
export interface CallConfig {
|
|
3
|
+
mode: 'free' | 'translate' | 'agent';
|
|
4
|
+
toNumber: string;
|
|
5
|
+
fromNumber: string;
|
|
6
|
+
llm: Record<string, unknown>;
|
|
7
|
+
tts: Record<string, unknown>;
|
|
8
|
+
asr: Record<string, unknown>;
|
|
9
|
+
idleTimeout: number;
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
12
|
+
export interface FreeCallParams {
|
|
13
|
+
toNumber: string;
|
|
14
|
+
fromNumber: string;
|
|
15
|
+
task?: string;
|
|
16
|
+
llm: Partial<LLMConfig>;
|
|
17
|
+
tts: Partial<TTSConfig>;
|
|
18
|
+
asr: Partial<ASRConfig>;
|
|
19
|
+
}
|
|
20
|
+
export declare function buildFreeCallConfig(params: FreeCallParams): CallConfig;
|
|
21
|
+
/** Interactive parameter collection for free call mode. */
|
|
22
|
+
export declare function collectFreeParams(opts: {
|
|
23
|
+
to?: string;
|
|
24
|
+
from?: string;
|
|
25
|
+
task?: string;
|
|
26
|
+
}): Promise<{
|
|
27
|
+
toNumber: string;
|
|
28
|
+
task?: string;
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const DEFAULT_PROMPT = 'You are a helpful voice assistant. Keep responses concise and conversational.';
|
|
2
|
+
export function buildFreeCallConfig(params) {
|
|
3
|
+
const systemMessage = params.task || DEFAULT_PROMPT;
|
|
4
|
+
return {
|
|
5
|
+
mode: 'free',
|
|
6
|
+
toNumber: params.toNumber,
|
|
7
|
+
fromNumber: params.fromNumber,
|
|
8
|
+
llm: {
|
|
9
|
+
...params.llm,
|
|
10
|
+
system_messages: [{ role: 'system', content: systemMessage }],
|
|
11
|
+
},
|
|
12
|
+
tts: { ...params.tts },
|
|
13
|
+
asr: { ...params.asr },
|
|
14
|
+
idleTimeout: 600,
|
|
15
|
+
label: `📱 Free Call → ${params.toNumber}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Interactive parameter collection for free call mode. */
|
|
19
|
+
export async function collectFreeParams(opts) {
|
|
20
|
+
const { default: inquirer } = await import('inquirer');
|
|
21
|
+
const { validateE164 } = await import('../_helpers.js');
|
|
22
|
+
let toNumber = opts.to;
|
|
23
|
+
if (!toNumber) {
|
|
24
|
+
const ans = await inquirer.prompt([{
|
|
25
|
+
type: 'input',
|
|
26
|
+
name: 'to',
|
|
27
|
+
message: 'Phone number to call (E.164):',
|
|
28
|
+
validate: (v) => /^\+[1-9]\d{1,14}$/.test(v.trim()) || 'Invalid E.164 format',
|
|
29
|
+
}]);
|
|
30
|
+
toNumber = ans.to;
|
|
31
|
+
}
|
|
32
|
+
toNumber = validateE164(toNumber);
|
|
33
|
+
let task = opts.task;
|
|
34
|
+
if (task === undefined) {
|
|
35
|
+
const ans = await inquirer.prompt([{
|
|
36
|
+
type: 'input',
|
|
37
|
+
name: 'task',
|
|
38
|
+
message: 'Anything to tell the agent? (optional):',
|
|
39
|
+
}]);
|
|
40
|
+
task = ans.task || undefined;
|
|
41
|
+
}
|
|
42
|
+
return { toNumber, task }; // fromNumber resolved by caller
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=free.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"free.js","sourceRoot":"","sources":["../../../../../src/commands/phone/_modes/free.ts"],"names":[],"mappings":"AAsBA,MAAM,cAAc,GAAG,+EAA+E,CAAC;AAEvG,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,IAAI,cAAc,CAAC;IAEpD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,EAAE;YACH,GAAG,MAAM,CAAC,GAAG;YACb,eAAe,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;SAC9D;QACD,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,WAAW,EAAE,GAAG;QAChB,KAAK,EAAE,kBAAkB,MAAM,CAAC,QAAQ,EAAE;KAC3C,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAIvC;IACC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAExD,IAAI,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,+BAA+B;gBACxC,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,sBAAsB;aACtF,CAAC,CAAC,CAAC;QACJ,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,QAAQ,GAAG,YAAY,CAAC,QAAS,CAAC,CAAC;IAEnC,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACrB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,yCAAyC;aACnD,CAAC,CAAC,CAAC;QACJ,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,gCAAgC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LLMConfig, TTSConfig, ASRConfig } from '../../../api/types.js';
|
|
2
|
+
import type { CallConfig } from './free.js';
|
|
3
|
+
export declare const SUPPORTED_LANGUAGES: {
|
|
4
|
+
value: string;
|
|
5
|
+
name: string;
|
|
6
|
+
}[];
|
|
7
|
+
export interface TranslateCallParams {
|
|
8
|
+
toNumber: string;
|
|
9
|
+
fromNumber: string;
|
|
10
|
+
sourceLang: string;
|
|
11
|
+
targetLang: string;
|
|
12
|
+
llm: Partial<LLMConfig>;
|
|
13
|
+
tts: Partial<TTSConfig>;
|
|
14
|
+
asr: Partial<ASRConfig>;
|
|
15
|
+
}
|
|
16
|
+
/** Parse a "source:target" language pair string. */
|
|
17
|
+
export declare function parseLanguagePair(pair: string): {
|
|
18
|
+
source: string;
|
|
19
|
+
target: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function buildTranslateCallConfig(params: TranslateCallParams): CallConfig;
|
|
22
|
+
/** Interactive parameter collection for translate mode. */
|
|
23
|
+
export declare function collectTranslateParams(opts: {
|
|
24
|
+
to?: string;
|
|
25
|
+
lang?: string;
|
|
26
|
+
}): Promise<{
|
|
27
|
+
toNumber: string;
|
|
28
|
+
sourceLang: string;
|
|
29
|
+
targetLang: string;
|
|
30
|
+
}>;
|