convoai 1.6.1 → 1.7.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 (57) hide show
  1. package/dist/src/api/calls.d.ts +33 -36
  2. package/dist/src/api/calls.js +12 -7
  3. package/dist/src/api/calls.js.map +1 -1
  4. package/dist/src/api/numbers.d.ts +63 -0
  5. package/dist/src/api/numbers.js +27 -0
  6. package/dist/src/api/numbers.js.map +1 -0
  7. package/dist/src/commands/call/hangup.js +9 -16
  8. package/dist/src/commands/call/hangup.js.map +1 -1
  9. package/dist/src/commands/call/initiate.js +69 -112
  10. package/dist/src/commands/call/initiate.js.map +1 -1
  11. package/dist/src/commands/call/status.js +14 -32
  12. package/dist/src/commands/call/status.js.map +1 -1
  13. package/dist/src/commands/completion.js +3 -2
  14. package/dist/src/commands/completion.js.map +1 -1
  15. package/dist/src/commands/go.js +76 -5
  16. package/dist/src/commands/go.js.map +1 -1
  17. package/dist/src/commands/phone/_helpers.d.ts +12 -0
  18. package/dist/src/commands/phone/_helpers.js +98 -0
  19. package/dist/src/commands/phone/_helpers.js.map +1 -0
  20. package/dist/src/commands/phone/get.d.ts +2 -0
  21. package/dist/src/commands/phone/get.js +34 -0
  22. package/dist/src/commands/phone/get.js.map +1 -0
  23. package/dist/src/commands/phone/hangup.d.ts +2 -0
  24. package/dist/src/commands/phone/hangup.js +20 -0
  25. package/dist/src/commands/phone/hangup.js.map +1 -0
  26. package/dist/src/commands/phone/history.d.ts +2 -0
  27. package/dist/src/commands/phone/history.js +56 -0
  28. package/dist/src/commands/phone/history.js.map +1 -0
  29. package/dist/src/commands/phone/import.d.ts +2 -0
  30. package/dist/src/commands/phone/import.js +88 -0
  31. package/dist/src/commands/phone/import.js.map +1 -0
  32. package/dist/src/commands/phone/numbers.d.ts +2 -0
  33. package/dist/src/commands/phone/numbers.js +34 -0
  34. package/dist/src/commands/phone/numbers.js.map +1 -0
  35. package/dist/src/commands/phone/remove.d.ts +2 -0
  36. package/dist/src/commands/phone/remove.js +31 -0
  37. package/dist/src/commands/phone/remove.js.map +1 -0
  38. package/dist/src/commands/phone/send.d.ts +2 -0
  39. package/dist/src/commands/phone/send.js +236 -0
  40. package/dist/src/commands/phone/send.js.map +1 -0
  41. package/dist/src/commands/phone/status.d.ts +2 -0
  42. package/dist/src/commands/phone/status.js +34 -0
  43. package/dist/src/commands/phone/status.js.map +1 -0
  44. package/dist/src/commands/phone/update.d.ts +2 -0
  45. package/dist/src/commands/phone/update.js +41 -0
  46. package/dist/src/commands/phone/update.js.map +1 -0
  47. package/dist/src/commands/quickstart.js +94 -22
  48. package/dist/src/commands/quickstart.js.map +1 -1
  49. package/dist/src/config/schema.d.ts +538 -314
  50. package/dist/src/config/schema.js +7 -7
  51. package/dist/src/config/schema.js.map +1 -1
  52. package/dist/src/index.js +40 -3
  53. package/dist/src/index.js.map +1 -1
  54. package/dist/src/utils/token.d.ts +2 -3
  55. package/dist/src/utils/token.js +4 -6
  56. package/dist/src/utils/token.js.map +1 -1
  57. package/package.json +1 -1
@@ -1,53 +1,50 @@
1
1
  import type { AxiosInstance } from 'axios';
2
- export interface InitiateCallRequest {
2
+ export interface SendCallRequest {
3
3
  name: string;
4
+ sip: {
5
+ to_number: string;
6
+ from_number: string;
7
+ rtc_uid: string;
8
+ rtc_token: string;
9
+ };
4
10
  properties: {
5
11
  channel: string;
6
- phone_number: string;
7
- agent_rtc_uid?: string;
12
+ token: string;
13
+ agent_rtc_uid: string;
14
+ remote_rtc_uids: string[];
8
15
  idle_timeout?: number;
9
- llm?: {
10
- url?: string;
11
- api_key?: string;
12
- system_messages?: Array<{
13
- role: string;
14
- content: string;
15
- }>;
16
- greeting_message?: string;
17
- params?: {
18
- model?: string;
19
- max_tokens?: number;
20
- temperature?: number;
21
- };
22
- };
23
- tts?: {
24
- vendor?: string;
25
- params?: Record<string, unknown>;
26
- };
27
- asr?: {
28
- language?: string;
29
- vendor?: string;
30
- };
16
+ llm?: Record<string, unknown>;
17
+ tts?: Record<string, unknown>;
18
+ asr?: Record<string, unknown>;
31
19
  };
32
20
  }
21
+ export interface SendCallResponse {
22
+ agent_id: string;
23
+ }
33
24
  export interface CallStatusResponse {
34
25
  agent_id: string;
35
26
  status: string;
36
- direction: 'inbound' | 'outbound';
37
- phone_number?: string;
38
27
  start_ts: number;
39
- end_ts?: number;
28
+ stop_ts?: number;
29
+ channel?: string;
30
+ message?: string;
40
31
  }
41
32
  export declare class CallAPI {
42
33
  private readonly client;
43
34
  constructor(client: AxiosInstance);
44
- /** Initiate an outbound phone call. */
45
- initiate(req: InitiateCallRequest): Promise<{
46
- agent_id: string;
47
- status: string;
48
- }>;
49
- /** Hang up an active call. */
50
- hangup(agentId: string): Promise<void>;
51
- /** Get the current status of a call. */
35
+ /** Initiate an outbound phone call via SIP. */
36
+ send(req: SendCallRequest): Promise<SendCallResponse>;
37
+ /** Get the current status of a call (reuses agent status endpoint). */
52
38
  status(agentId: string): Promise<CallStatusResponse>;
39
+ /** Hang up an active call (reuses agent leave endpoint). */
40
+ hangup(agentId: string): Promise<void>;
41
+ /** List calls (reuses agent list, caller can filter). */
42
+ list(params?: {
43
+ limit?: number;
44
+ state?: number;
45
+ }): Promise<{
46
+ data: {
47
+ list: CallStatusResponse[];
48
+ };
49
+ }>;
53
50
  }
@@ -4,18 +4,23 @@ export class CallAPI {
4
4
  constructor(client) {
5
5
  this.client = client;
6
6
  }
7
- /** Initiate an outbound phone call. */
8
- async initiate(req) {
7
+ /** Initiate an outbound phone call via SIP. */
8
+ async send(req) {
9
9
  const { data } = await this.client.post('/call', req);
10
10
  return data;
11
11
  }
12
- /** Hang up an active call. */
12
+ /** Get the current status of a call (reuses agent status endpoint). */
13
+ async status(agentId) {
14
+ const { data } = await this.client.get(`/agents/${agentId}`);
15
+ return data;
16
+ }
17
+ /** Hang up an active call (reuses agent leave endpoint). */
13
18
  async hangup(agentId) {
14
- await this.client.post(`/calls/${agentId}/hangup`);
19
+ await this.client.post(`/agents/${agentId}/leave`);
15
20
  }
16
- /** Get the current status of a call. */
17
- async status(agentId) {
18
- const { data } = await this.client.get(`/calls/${agentId}`);
21
+ /** List calls (reuses agent list, caller can filter). */
22
+ async list(params) {
23
+ const { data } = await this.client.get('/agents', { params });
19
24
  return data;
20
25
  }
21
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"calls.js","sourceRoot":"","sources":["../../../src/api/calls.ts"],"names":[],"mappings":"AAgCA,+EAA+E;AAE/E,MAAM,OAAO,OAAO;IACW;IAA7B,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAEtD,uCAAuC;IACvC,KAAK,CAAC,QAAQ,CAAC,GAAwB;QACrC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAuC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC5F,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8BAA8B;IAC9B,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,OAAO,SAAS,CAAC,CAAC;IACrD,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAqB,UAAU,OAAO,EAAE,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
1
+ {"version":3,"file":"calls.js","sourceRoot":"","sources":["../../../src/api/calls.ts"],"names":[],"mappings":"AAsCA,+EAA+E;AAE/E,MAAM,OAAO,OAAO;IACW;IAA7B,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAEtD,+CAA+C;IAC/C,KAAK,CAAC,IAAI,CAAC,GAAoB;QAC7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAmB,OAAO,EAAE,GAAG,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAqB,WAAW,OAAO,EAAE,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,IAAI,CAAC,MAA2C;QACpD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,63 @@
1
+ import type { AxiosInstance } from 'axios';
2
+ export interface PhoneNumber {
3
+ phone_number: string;
4
+ label: string;
5
+ provider: 'byo' | 'twilio';
6
+ inbound: boolean;
7
+ outbound: boolean;
8
+ associated_pipeline: {
9
+ pipeline_id: string;
10
+ pipeline_name: string;
11
+ } | null;
12
+ inbound_config: {
13
+ allowed_addresses?: string[];
14
+ } | null;
15
+ outbound_config: {
16
+ address?: string;
17
+ transport?: 'tls' | 'tcp' | 'udp';
18
+ prefix?: string;
19
+ user?: string;
20
+ password?: string;
21
+ } | null;
22
+ }
23
+ export interface ImportNumberRequest {
24
+ provider: 'byo' | 'twilio';
25
+ phone_number: string;
26
+ label: string;
27
+ inbound?: boolean;
28
+ outbound?: boolean;
29
+ inbound_config?: {
30
+ allowed_addresses?: string[];
31
+ };
32
+ outbound_config: {
33
+ address: string;
34
+ transport: 'tls' | 'tcp' | 'udp';
35
+ prefix?: string;
36
+ user?: string;
37
+ password?: string;
38
+ };
39
+ }
40
+ export interface UpdateNumberRequest {
41
+ label?: string;
42
+ inbound?: boolean;
43
+ outbound?: boolean;
44
+ inbound_config?: {
45
+ allowed_addresses?: string[];
46
+ };
47
+ outbound_config?: {
48
+ address?: string;
49
+ transport?: 'tls' | 'tcp' | 'udp';
50
+ prefix?: string;
51
+ user?: string;
52
+ password?: string;
53
+ };
54
+ }
55
+ export declare class NumberAPI {
56
+ private readonly client;
57
+ constructor(client: AxiosInstance);
58
+ list(): Promise<PhoneNumber[]>;
59
+ import(req: ImportNumberRequest): Promise<PhoneNumber>;
60
+ get(phoneNumber: string): Promise<PhoneNumber>;
61
+ update(phoneNumber: string, req: UpdateNumberRequest): Promise<PhoneNumber>;
62
+ delete(phoneNumber: string): Promise<void>;
63
+ }
@@ -0,0 +1,27 @@
1
+ // ─── Number API ─────────────────────────────────────────────────────────────
2
+ export class NumberAPI {
3
+ client;
4
+ constructor(client) {
5
+ this.client = client;
6
+ }
7
+ async list() {
8
+ const { data } = await this.client.get('/phone-numbers');
9
+ return data;
10
+ }
11
+ async import(req) {
12
+ const { data } = await this.client.post('/phone-numbers', req);
13
+ return data;
14
+ }
15
+ async get(phoneNumber) {
16
+ const { data } = await this.client.get(`/phone-numbers/${encodeURIComponent(phoneNumber)}`);
17
+ return data;
18
+ }
19
+ async update(phoneNumber, req) {
20
+ const { data } = await this.client.patch(`/phone-numbers/${encodeURIComponent(phoneNumber)}`, req);
21
+ return data;
22
+ }
23
+ async delete(phoneNumber) {
24
+ await this.client.delete(`/phone-numbers/${encodeURIComponent(phoneNumber)}`);
25
+ }
26
+ }
27
+ //# sourceMappingURL=numbers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numbers.js","sourceRoot":"","sources":["../../../src/api/numbers.ts"],"names":[],"mappings":"AAoDA,+EAA+E;AAE/E,MAAM,OAAO,SAAS;IACS;IAA7B,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAEtD,KAAK,CAAC,IAAI;QACR,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAgB,gBAAgB,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAwB;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAc,gBAAgB,EAAE,GAAG,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAmB;QAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAc,kBAAkB,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACzG,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,GAAwB;QACxD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAc,kBAAkB,kBAAkB,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,WAAmB;QAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;CACF"}
@@ -1,28 +1,21 @@
1
- import { getCallAPI } from './_helpers.js';
2
- import { withSpinner } from '../../ui/spinner.js';
3
- import { printSuccess, printHint } from '../../ui/output.js';
1
+ import chalk from 'chalk';
2
+ import { getCallAPI } from '../phone/_helpers.js';
3
+ import { printSuccess } from '../../ui/output.js';
4
4
  import { handleError } from '../../utils/errors.js';
5
- import { shortId } from '../../utils/hints.js';
6
- // ─── Command Registration ──────────────────────────────────────────────────
7
5
  export function registerCallHangup(program) {
8
6
  program
9
7
  .command('hangup <agent-id>')
10
- .description('Hang up an active call')
11
- .option('--profile <name>', 'Config profile to use')
12
- .option('--json', 'Output result as JSON')
8
+ .description('(deprecated) Use "phone hangup" instead')
9
+ .option('--profile <name>', 'Config profile')
13
10
  .action(async (agentId, opts) => {
11
+ console.log(chalk.yellow(' ⚠ "call hangup" is deprecated. Use "convoai phone hangup" instead.'));
14
12
  try {
15
13
  const api = getCallAPI(opts.profile);
16
- await withSpinner(`Hanging up call ${shortId(agentId)}...`, () => api.hangup(agentId));
17
- if (opts.json) {
18
- console.log(JSON.stringify({ agent_id: agentId, status: 'HUNG_UP' }, null, 2));
19
- return;
20
- }
21
- printSuccess(`Call ${shortId(agentId)} hung up.`);
22
- printHint('Run `convoai call initiate --phone <number>` to start a new call.');
14
+ await api.hangup(agentId);
15
+ printSuccess('Call ended');
23
16
  }
24
17
  catch (error) {
25
- handleError(error, { json: opts.json });
18
+ handleError(error);
26
19
  }
27
20
  });
28
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hangup.js","sourceRoot":"","sources":["../../../../src/commands/call/hangup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAc,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,8EAA8E;AAE9E,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;SACnD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAI,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM,WAAW,CAAC,mBAAmB,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAC/D,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CACpB,CAAC;YAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/E,OAAO;YACT,CAAC;YAED,YAAY,CAAC,QAAQ,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAClD,SAAS,CAAC,mEAAmE,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"hangup.js","sourceRoot":"","sources":["../../../../src/commands/call/hangup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAI,EAAE,EAAE;QACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sEAAsE,CAAC,CAAC,CAAC;QAClG,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC1B,YAAY,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,133 +1,90 @@
1
- import { resolveConfig } from '../../config/manager.js';
2
- import { getCallAPI } from './_helpers.js';
3
- import { withSpinner } from '../../ui/spinner.js';
4
- import { printKeyValue } from '../../ui/table.js';
1
+ import chalk from 'chalk';
2
+ import { getCallAPI, getNumberAPI, getConfig, validateE164, pickOutboundNumber } from '../phone/_helpers.js';
3
+ import { generateRtcToken } from '../../utils/token.js';
5
4
  import { printSuccess, printError, printHint } from '../../ui/output.js';
5
+ import { withSpinner } from '../../ui/spinner.js';
6
6
  import { handleError } from '../../utils/errors.js';
7
- import { shortId } from '../../utils/hints.js';
8
- // ─── Name Generation ───────────────────────────────────────────────────────
9
- function generateCallName() {
10
- const timestamp = Date.now();
11
- const random = Math.random().toString(36).substring(2, 6);
12
- return `call-${timestamp}-${random}`;
13
- }
14
- function generateChannelName() {
15
- const timestamp = Date.now();
16
- const random = Math.random().toString(36).substring(2, 6);
17
- return `call-ch-${timestamp}-${random}`;
18
- }
19
- // ─── Interactive Prompts ───────────────────────────────────────────────────
20
- async function promptForPhone() {
21
- const { default: inquirer } = await import('inquirer');
22
- const { phone } = await inquirer.prompt([
23
- {
24
- type: 'input',
25
- name: 'phone',
26
- message: 'Phone number (E.164 format, e.g. +15551234567):',
27
- },
28
- ]);
29
- return phone;
30
- }
31
- // ─── Request Builder ───────────────────────────────────────────────────────
32
- function buildRequest(opts) {
33
- const config = resolveConfig(opts.profile);
34
- const properties = {
35
- channel: opts.channel ?? generateChannelName(),
36
- phone_number: opts.phone,
37
- };
38
- // Build LLM config from CLI flags and config defaults
39
- const llm = {};
40
- let hasLlm = false;
41
- if (opts.model) {
42
- llm.params = { model: opts.model };
43
- hasLlm = true;
44
- }
45
- if (opts.systemMessage) {
46
- llm.system_messages = [{ role: 'system', content: opts.systemMessage }];
47
- hasLlm = true;
48
- }
49
- if (opts.greeting) {
50
- llm.greeting_message = opts.greeting;
51
- hasLlm = true;
52
- }
53
- // Apply config-level LLM defaults if present
54
- if (config.llm) {
55
- if (config.llm.url && !llm.params) {
56
- llm.url = config.llm.url;
57
- hasLlm = true;
58
- }
59
- if (config.llm.api_key) {
60
- llm.api_key = config.llm.api_key;
61
- hasLlm = true;
62
- }
63
- }
64
- if (hasLlm) {
65
- properties.llm = llm;
66
- }
67
- // Apply TTS from config
68
- if (config.tts) {
69
- properties.tts = config.tts;
70
- }
71
- // Apply ASR from config
72
- if (config.asr) {
73
- properties.asr = config.asr;
74
- }
75
- return {
76
- name: generateCallName(),
77
- properties,
78
- };
79
- }
80
- // ─── Command Registration ──────────────────────────────────────────────────
7
+ import { loadConfig } from '../../config/manager.js';
81
8
  export function registerCallInitiate(program) {
82
9
  program
83
10
  .command('initiate')
84
- .description('Initiate an outbound phone call')
85
- .option('--phone <number>', 'Phone number in E.164 format (required)')
86
- .option('-c, --channel <name>', 'Channel name (auto-generated if omitted)')
87
- .option('--model <model>', 'LLM model name (e.g. gpt-4o-mini)')
88
- .option('--system-message <msg>', 'System prompt for the LLM')
89
- .option('--greeting <msg>', 'Greeting message spoken on connect')
90
- .option('--profile <name>', 'Config profile to use')
91
- .option('--json', 'Output result as JSON')
92
- .option('--dry-run', 'Show the request payload without sending it')
11
+ .description('(deprecated) Use "phone send" instead')
12
+ .option('--phone <number>', 'Phone number (maps to --to)')
13
+ .option('--channel <name>', 'Channel name (ignored)')
14
+ .option('--model <model>', 'LLM model')
15
+ .option('--system-message <msg>', 'System prompt (maps to --task)')
16
+ .option('--greeting <msg>', 'Greeting message')
17
+ .option('--profile <name>', 'Config profile')
18
+ .option('--json', 'JSON output')
19
+ .option('--dry-run', 'Dry run')
93
20
  .action(async (opts) => {
21
+ console.log(chalk.yellow(' ⚠ "call initiate" is deprecated. Use "convoai phone send" instead.'));
94
22
  try {
95
- let phone = opts.phone;
96
- // Interactive prompt if running in a TTY and phone is missing
97
- if (!phone && process.stdin.isTTY) {
98
- phone = await promptForPhone();
23
+ const config = getConfig(opts.profile);
24
+ const numberApi = getNumberAPI(opts.profile);
25
+ const callApi = getCallAPI(opts.profile);
26
+ // Map old flags to new
27
+ let toNumber = opts.phone;
28
+ const task = opts.systemMessage;
29
+ // If no phone flag, try interactive
30
+ if (!toNumber && process.stdin.isTTY) {
31
+ const { default: inquirer } = await import('inquirer');
32
+ const ans = await inquirer.prompt([{
33
+ type: 'input', name: 'to', message: 'To number (E.164):',
34
+ validate: (v) => /^\+[1-9]\d{1,14}$/.test(v.trim()) || 'Invalid E.164',
35
+ }]);
36
+ toNumber = ans.to;
37
+ }
38
+ if (!toNumber) {
39
+ printError('--phone is required.');
40
+ process.exit(1);
99
41
  }
100
- if (!phone) {
101
- printError('--phone is required. Provide it as a flag or run interactively in a TTY.');
42
+ toNumber = validateE164(toNumber);
43
+ // Pick from number
44
+ const numbers = await numberApi.list();
45
+ if (numbers.length === 0) {
46
+ printError('No phone numbers. Run: convoai phone import');
102
47
  process.exit(1);
103
48
  }
104
- const request = buildRequest({
105
- phone,
106
- channel: opts.channel,
107
- model: opts.model,
108
- systemMessage: opts.systemMessage,
109
- greeting: opts.greeting,
110
- profile: opts.profile,
111
- });
112
- // Dry-run mode: print request and exit
49
+ const picked = await pickOutboundNumber(numbers);
50
+ const channelName = `call-${Date.now().toString(36)}`;
51
+ const configObj = loadConfig();
52
+ const appCert = process.env.AGORA_APP_CERTIFICATE ?? configObj.app_certificate;
53
+ const agentToken = await generateRtcToken(channelName, 0, 86400, config.app_id, appCert);
54
+ const sipToken = await generateRtcToken(channelName, 1, 86400, config.app_id, appCert);
55
+ if (!agentToken || !sipToken) {
56
+ printError('Token generation failed.');
57
+ process.exit(1);
58
+ }
59
+ const llm = { ...(config.llm ?? {}) };
60
+ if (task)
61
+ llm.system_messages = [{ role: 'system', content: task }];
62
+ if (opts.greeting)
63
+ llm.greeting_message = opts.greeting;
64
+ if (opts.model) {
65
+ if (!llm.params)
66
+ llm.params = {};
67
+ llm.params.model = opts.model;
68
+ }
69
+ const request = {
70
+ name: `call-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
71
+ sip: { to_number: toNumber, from_number: picked.phone_number, rtc_uid: '1', rtc_token: sipToken },
72
+ properties: {
73
+ channel: channelName, token: agentToken, agent_rtc_uid: '0', remote_rtc_uids: ['1'],
74
+ idle_timeout: 600, llm, tts: config.tts ?? {}, asr: config.asr ?? {},
75
+ },
76
+ };
113
77
  if (opts.dryRun) {
114
78
  console.log(JSON.stringify(request, null, 2));
115
79
  return;
116
80
  }
117
- const api = getCallAPI(opts.profile);
118
- const result = await withSpinner('Initiating call...', () => api.initiate(request));
81
+ const result = await withSpinner('Initiating call...', () => callApi.send(request));
119
82
  if (opts.json) {
120
83
  console.log(JSON.stringify(result, null, 2));
121
84
  return;
122
85
  }
123
- printSuccess('Call initiated successfully.');
124
- printKeyValue([
125
- ['Agent ID', result.agent_id],
126
- ['Status', result.status],
127
- ['Phone', phone],
128
- ['Channel', request.properties.channel],
129
- ]);
130
- printHint(`Run \`convoai call status ${shortId(result.agent_id)}\` to check call status.`);
86
+ printSuccess(`Call initiated (${result.agent_id})`);
87
+ printHint(`convoai phone status ${result.agent_id}`);
131
88
  }
132
89
  catch (error) {
133
90
  handleError(error, { json: opts.json });
@@ -1 +1 @@
1
- {"version":3,"file":"initiate.js","sourceRoot":"","sources":["../../../../src/commands/call/initiate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"initiate.js","sourceRoot":"","sources":["../../../../src/commands/call/initiate.ts"],"names":[],"mappings":"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"}
@@ -1,46 +1,28 @@
1
- import { getCallAPI, formatTimestamp, formatDuration } from './_helpers.js';
2
- import { withSpinner } from '../../ui/spinner.js';
1
+ import chalk from 'chalk';
2
+ import { getCallAPI } from '../phone/_helpers.js';
3
3
  import { printKeyValue } from '../../ui/table.js';
4
4
  import { handleError } from '../../utils/errors.js';
5
- // ─── Command Registration ──────────────────────────────────────────────────
6
5
  export function registerCallStatus(program) {
7
6
  program
8
7
  .command('status <agent-id>')
9
- .description('Get the status of a call')
10
- .option('--profile <name>', 'Config profile to use')
11
- .option('--json', 'Output result as JSON')
8
+ .description('(deprecated) Use "phone status" instead')
9
+ .option('--profile <name>', 'Config profile')
10
+ .option('--json', 'JSON output')
12
11
  .action(async (agentId, opts) => {
12
+ console.log(chalk.yellow(' ⚠ "call status" is deprecated. Use "convoai phone status" instead.'));
13
13
  try {
14
14
  const api = getCallAPI(opts.profile);
15
- const result = await withSpinner('Fetching call status...', () => api.status(agentId));
15
+ const status = await api.status(agentId);
16
16
  if (opts.json) {
17
- console.log(JSON.stringify(result, null, 2));
17
+ console.log(JSON.stringify(status, null, 2));
18
18
  return;
19
19
  }
20
- const pairs = [
21
- ['Agent ID', result.agent_id],
22
- ['Status', result.status],
23
- ['Direction', result.direction],
24
- ];
25
- if (result.phone_number) {
26
- pairs.push(['Phone', result.phone_number]);
27
- }
28
- pairs.push(['Started', formatTimestamp(result.start_ts)]);
29
- if (result.end_ts) {
30
- pairs.push(['Ended', formatTimestamp(result.end_ts)]);
31
- const duration = result.end_ts - result.start_ts;
32
- if (duration >= 0) {
33
- pairs.push(['Duration', formatDuration(duration)]);
34
- }
35
- }
36
- else {
37
- // Call is still active — show elapsed time
38
- const elapsed = Math.floor(Date.now() / 1000) - result.start_ts;
39
- if (elapsed >= 0) {
40
- pairs.push(['Elapsed', formatDuration(elapsed)]);
41
- }
42
- }
43
- printKeyValue(pairs);
20
+ console.log('');
21
+ printKeyValue([
22
+ ['Agent ID', status.agent_id],
23
+ ['Status', status.status],
24
+ ['Channel', status.channel ?? '-'],
25
+ ]);
44
26
  }
45
27
  catch (error) {
46
28
  handleError(error, { json: opts.json });
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/commands/call/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,8EAA8E;AAE9E,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,0BAA0B,CAAC;SACvC,MAAM,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;SACnD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAI,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAErC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAC/D,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CACpB,CAAC;YAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAA4B;gBACrC,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC;gBAC7B,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;gBACzB,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC;aAChC,CAAC;YAEF,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YAC7C,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAE1D,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;gBACjD,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;oBAClB,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;gBAChE,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;oBACjB,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAED,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/commands/call/status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;SAC/B,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAI,EAAE,EAAE;QACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sEAAsE,CAAC,CAAC,CAAC;QAClG,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YACxE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,aAAa,CAAC;gBACZ,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC;gBAC7B,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;gBACzB,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;aACnC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -4,9 +4,10 @@ import { join } from 'node:path';
4
4
  import { printSuccess, printError, printHint } from '../ui/output.js';
5
5
  import { handleError } from '../utils/errors.js';
6
6
  // ─── Completion Data ──────────────────────────────────────────────────────
7
- const TOP_LEVEL_COMMANDS = ['auth', 'agent', 'call', 'config', 'preset', 'template', 'completion', 'repl'];
7
+ const TOP_LEVEL_COMMANDS = ['go', 'init', 'dev', 'quickstart', 'openclaw', 'phone', 'auth', 'agent', 'call', 'config', 'preset', 'template', 'token', 'completion'];
8
8
  const SUBCOMMANDS = {
9
- agent: ['start', 'stop', 'status', 'list', 'update', 'speak', 'interrupt', 'history', 'turns', 'watch'],
9
+ phone: ['send', 'numbers', 'import', 'number', 'update', 'remove', 'hangup', 'status', 'history'],
10
+ agent: ['start', 'stop', 'status', 'list', 'update', 'speak', 'interrupt', 'history', 'turns', 'join', 'chat', 'panel'],
10
11
  auth: ['login', 'logout', 'status'],
11
12
  call: ['initiate', 'hangup', 'status'],
12
13
  config: ['init', 'set', 'get', 'show', 'path'],