convoai 1.0.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 (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +862 -0
  3. package/bin/convoai.ts +3 -0
  4. package/dist/bin/convoai.d.ts +2 -0
  5. package/dist/bin/convoai.js +4 -0
  6. package/dist/bin/convoai.js.map +1 -0
  7. package/dist/src/api/agents.d.ts +24 -0
  8. package/dist/src/api/agents.js +51 -0
  9. package/dist/src/api/agents.js.map +1 -0
  10. package/dist/src/api/calls.d.ts +53 -0
  11. package/dist/src/api/calls.js +22 -0
  12. package/dist/src/api/calls.js.map +1 -0
  13. package/dist/src/api/client.d.ts +10 -0
  14. package/dist/src/api/client.js +63 -0
  15. package/dist/src/api/client.js.map +1 -0
  16. package/dist/src/api/types.d.ts +207 -0
  17. package/dist/src/api/types.js +20 -0
  18. package/dist/src/api/types.js.map +1 -0
  19. package/dist/src/commands/agent/_helpers.d.ts +7 -0
  20. package/dist/src/commands/agent/_helpers.js +32 -0
  21. package/dist/src/commands/agent/_helpers.js.map +1 -0
  22. package/dist/src/commands/agent/history.d.ts +2 -0
  23. package/dist/src/commands/agent/history.js +78 -0
  24. package/dist/src/commands/agent/history.js.map +1 -0
  25. package/dist/src/commands/agent/interrupt.d.ts +2 -0
  26. package/dist/src/commands/agent/interrupt.js +32 -0
  27. package/dist/src/commands/agent/interrupt.js.map +1 -0
  28. package/dist/src/commands/agent/join.d.ts +2 -0
  29. package/dist/src/commands/agent/join.js +168 -0
  30. package/dist/src/commands/agent/join.js.map +1 -0
  31. package/dist/src/commands/agent/list.d.ts +2 -0
  32. package/dist/src/commands/agent/list.js +67 -0
  33. package/dist/src/commands/agent/list.js.map +1 -0
  34. package/dist/src/commands/agent/speak.d.ts +2 -0
  35. package/dist/src/commands/agent/speak.js +48 -0
  36. package/dist/src/commands/agent/speak.js.map +1 -0
  37. package/dist/src/commands/agent/start.d.ts +2 -0
  38. package/dist/src/commands/agent/start.js +212 -0
  39. package/dist/src/commands/agent/start.js.map +1 -0
  40. package/dist/src/commands/agent/status.d.ts +2 -0
  41. package/dist/src/commands/agent/status.js +42 -0
  42. package/dist/src/commands/agent/status.js.map +1 -0
  43. package/dist/src/commands/agent/stop.d.ts +2 -0
  44. package/dist/src/commands/agent/stop.js +107 -0
  45. package/dist/src/commands/agent/stop.js.map +1 -0
  46. package/dist/src/commands/agent/turns.d.ts +2 -0
  47. package/dist/src/commands/agent/turns.js +99 -0
  48. package/dist/src/commands/agent/turns.js.map +1 -0
  49. package/dist/src/commands/agent/update.d.ts +2 -0
  50. package/dist/src/commands/agent/update.js +74 -0
  51. package/dist/src/commands/agent/update.js.map +1 -0
  52. package/dist/src/commands/agent/watch.d.ts +2 -0
  53. package/dist/src/commands/agent/watch.js +291 -0
  54. package/dist/src/commands/agent/watch.js.map +1 -0
  55. package/dist/src/commands/auth/login.d.ts +2 -0
  56. package/dist/src/commands/auth/login.js +118 -0
  57. package/dist/src/commands/auth/login.js.map +1 -0
  58. package/dist/src/commands/auth/logout.d.ts +2 -0
  59. package/dist/src/commands/auth/logout.js +84 -0
  60. package/dist/src/commands/auth/logout.js.map +1 -0
  61. package/dist/src/commands/auth/status.d.ts +2 -0
  62. package/dist/src/commands/auth/status.js +114 -0
  63. package/dist/src/commands/auth/status.js.map +1 -0
  64. package/dist/src/commands/call/_helpers.d.ts +7 -0
  65. package/dist/src/commands/call/_helpers.js +32 -0
  66. package/dist/src/commands/call/_helpers.js.map +1 -0
  67. package/dist/src/commands/call/hangup.d.ts +2 -0
  68. package/dist/src/commands/call/hangup.js +29 -0
  69. package/dist/src/commands/call/hangup.js.map +1 -0
  70. package/dist/src/commands/call/initiate.d.ts +2 -0
  71. package/dist/src/commands/call/initiate.js +137 -0
  72. package/dist/src/commands/call/initiate.js.map +1 -0
  73. package/dist/src/commands/call/status.d.ts +2 -0
  74. package/dist/src/commands/call/status.js +50 -0
  75. package/dist/src/commands/call/status.js.map +1 -0
  76. package/dist/src/commands/completion.d.ts +2 -0
  77. package/dist/src/commands/completion.js +542 -0
  78. package/dist/src/commands/completion.js.map +1 -0
  79. package/dist/src/commands/config/get.d.ts +2 -0
  80. package/dist/src/commands/config/get.js +79 -0
  81. package/dist/src/commands/config/get.js.map +1 -0
  82. package/dist/src/commands/config/init.d.ts +2 -0
  83. package/dist/src/commands/config/init.js +176 -0
  84. package/dist/src/commands/config/init.js.map +1 -0
  85. package/dist/src/commands/config/path.d.ts +2 -0
  86. package/dist/src/commands/config/path.js +22 -0
  87. package/dist/src/commands/config/path.js.map +1 -0
  88. package/dist/src/commands/config/set.d.ts +2 -0
  89. package/dist/src/commands/config/set.js +115 -0
  90. package/dist/src/commands/config/set.js.map +1 -0
  91. package/dist/src/commands/config/show.d.ts +2 -0
  92. package/dist/src/commands/config/show.js +147 -0
  93. package/dist/src/commands/config/show.js.map +1 -0
  94. package/dist/src/commands/preset/list.d.ts +2 -0
  95. package/dist/src/commands/preset/list.js +39 -0
  96. package/dist/src/commands/preset/list.js.map +1 -0
  97. package/dist/src/commands/preset/use.d.ts +2 -0
  98. package/dist/src/commands/preset/use.js +89 -0
  99. package/dist/src/commands/preset/use.js.map +1 -0
  100. package/dist/src/commands/quickstart.d.ts +2 -0
  101. package/dist/src/commands/quickstart.js +595 -0
  102. package/dist/src/commands/quickstart.js.map +1 -0
  103. package/dist/src/commands/repl.d.ts +2 -0
  104. package/dist/src/commands/repl.js +391 -0
  105. package/dist/src/commands/repl.js.map +1 -0
  106. package/dist/src/commands/template/delete.d.ts +2 -0
  107. package/dist/src/commands/template/delete.js +54 -0
  108. package/dist/src/commands/template/delete.js.map +1 -0
  109. package/dist/src/commands/template/list.d.ts +2 -0
  110. package/dist/src/commands/template/list.js +48 -0
  111. package/dist/src/commands/template/list.js.map +1 -0
  112. package/dist/src/commands/template/save.d.ts +2 -0
  113. package/dist/src/commands/template/save.js +86 -0
  114. package/dist/src/commands/template/save.js.map +1 -0
  115. package/dist/src/commands/template/show.d.ts +2 -0
  116. package/dist/src/commands/template/show.js +98 -0
  117. package/dist/src/commands/template/show.js.map +1 -0
  118. package/dist/src/commands/template/use.d.ts +2 -0
  119. package/dist/src/commands/template/use.js +109 -0
  120. package/dist/src/commands/template/use.js.map +1 -0
  121. package/dist/src/commands/token.d.ts +2 -0
  122. package/dist/src/commands/token.js +75 -0
  123. package/dist/src/commands/token.js.map +1 -0
  124. package/dist/src/config/manager.d.ts +22 -0
  125. package/dist/src/config/manager.js +130 -0
  126. package/dist/src/config/manager.js.map +1 -0
  127. package/dist/src/config/paths.d.ts +9 -0
  128. package/dist/src/config/paths.js +28 -0
  129. package/dist/src/config/paths.js.map +1 -0
  130. package/dist/src/config/schema.d.ts +396 -0
  131. package/dist/src/config/schema.js +57 -0
  132. package/dist/src/config/schema.js.map +1 -0
  133. package/dist/src/index.d.ts +1 -0
  134. package/dist/src/index.js +157 -0
  135. package/dist/src/index.js.map +1 -0
  136. package/dist/src/presets/defaults.d.ts +20 -0
  137. package/dist/src/presets/defaults.js +195 -0
  138. package/dist/src/presets/defaults.js.map +1 -0
  139. package/dist/src/providers/catalog.d.ts +103 -0
  140. package/dist/src/providers/catalog.js +247 -0
  141. package/dist/src/providers/catalog.js.map +1 -0
  142. package/dist/src/templates/manager.d.ts +24 -0
  143. package/dist/src/templates/manager.js +77 -0
  144. package/dist/src/templates/manager.js.map +1 -0
  145. package/dist/src/ui/colors.d.ts +9 -0
  146. package/dist/src/ui/colors.js +36 -0
  147. package/dist/src/ui/colors.js.map +1 -0
  148. package/dist/src/ui/output.d.ts +17 -0
  149. package/dist/src/ui/output.js +27 -0
  150. package/dist/src/ui/output.js.map +1 -0
  151. package/dist/src/ui/spinner.d.ts +5 -0
  152. package/dist/src/ui/spinner.js +23 -0
  153. package/dist/src/ui/spinner.js.map +1 -0
  154. package/dist/src/ui/table.d.ts +8 -0
  155. package/dist/src/ui/table.js +38 -0
  156. package/dist/src/ui/table.js.map +1 -0
  157. package/dist/src/utils/errors.d.ts +11 -0
  158. package/dist/src/utils/errors.js +38 -0
  159. package/dist/src/utils/errors.js.map +1 -0
  160. package/dist/src/utils/format.d.ts +16 -0
  161. package/dist/src/utils/format.js +87 -0
  162. package/dist/src/utils/format.js.map +1 -0
  163. package/dist/src/utils/hints.d.ts +7 -0
  164. package/dist/src/utils/hints.js +22 -0
  165. package/dist/src/utils/hints.js.map +1 -0
  166. package/dist/src/utils/token.d.ts +6 -0
  167. package/dist/src/utils/token.js +26 -0
  168. package/dist/src/utils/token.js.map +1 -0
  169. package/package.json +65 -0
  170. package/src/web/client.html +136 -0
@@ -0,0 +1,118 @@
1
+ import { loadConfig, saveConfig } from '../../config/manager.js';
2
+ import { createClient } from '../../api/client.js';
3
+ import { AgentAPI } from '../../api/agents.js';
4
+ import { printSuccess, printError, printHint } from '../../ui/output.js';
5
+ import { withSpinner } from '../../ui/spinner.js';
6
+ import { handleError } from '../../utils/errors.js';
7
+ import { hintAfterLogin } from '../../utils/hints.js';
8
+ // ─── Command Registration ──────────────────────────────────────────────────
9
+ export function registerAuthLogin(program) {
10
+ program
11
+ .command('login')
12
+ .description('Authenticate with the Agora ConvoAI platform')
13
+ .option('--app-id <id>', 'Agora App ID')
14
+ .option('--customer-id <id>', 'Customer ID')
15
+ .option('--customer-secret <secret>', 'Customer Secret')
16
+ .option('--profile <name>', 'Save credentials under a named profile')
17
+ .action(async (opts) => {
18
+ try {
19
+ await loginAction(opts);
20
+ }
21
+ catch (error) {
22
+ handleError(error);
23
+ }
24
+ });
25
+ }
26
+ async function promptCredentials(opts) {
27
+ const { default: inquirer } = await import('inquirer');
28
+ const answers = await inquirer.prompt([
29
+ {
30
+ type: 'input',
31
+ name: 'appId',
32
+ message: 'Agora App ID:',
33
+ when: () => !opts.appId,
34
+ validate: (v) => (v.trim().length > 0 ? true : 'App ID is required'),
35
+ },
36
+ {
37
+ type: 'input',
38
+ name: 'customerId',
39
+ message: 'Customer ID:',
40
+ when: () => !opts.customerId,
41
+ validate: (v) => (v.trim().length > 0 ? true : 'Customer ID is required'),
42
+ },
43
+ {
44
+ type: 'password',
45
+ name: 'customerSecret',
46
+ message: 'Customer Secret:',
47
+ mask: '*',
48
+ when: () => !opts.customerSecret,
49
+ validate: (v) => (v.trim().length > 0 ? true : 'Customer Secret is required'),
50
+ },
51
+ {
52
+ type: 'list',
53
+ name: 'region',
54
+ message: 'Default region:',
55
+ choices: [
56
+ { name: 'Global', value: 'global' },
57
+ { name: 'China', value: 'cn' },
58
+ ],
59
+ default: 'global',
60
+ },
61
+ ]);
62
+ return {
63
+ appId: opts.appId ?? answers.appId,
64
+ customerId: opts.customerId ?? answers.customerId,
65
+ customerSecret: opts.customerSecret ?? answers.customerSecret,
66
+ region: answers.region,
67
+ };
68
+ }
69
+ async function verifyConnectivity(creds) {
70
+ const client = createClient({
71
+ appId: creds.appId,
72
+ customerId: creds.customerId,
73
+ customerSecret: creds.customerSecret,
74
+ region: creds.region,
75
+ });
76
+ const api = new AgentAPI(client);
77
+ try {
78
+ await withSpinner('Verifying credentials...', async () => {
79
+ await api.list({ limit: 1 });
80
+ });
81
+ return true;
82
+ }
83
+ catch {
84
+ printError('Could not verify credentials. They have been saved, but connectivity failed.');
85
+ printHint('Check that your App ID, Customer ID, and Customer Secret are correct.');
86
+ return false;
87
+ }
88
+ }
89
+ // ─── Action ────────────────────────────────────────────────────────────────
90
+ async function loginAction(opts) {
91
+ const creds = await promptCredentials(opts);
92
+ const config = loadConfig();
93
+ if (opts.profile) {
94
+ // Save under a named profile
95
+ if (!config.profiles) {
96
+ config.profiles = {};
97
+ }
98
+ const profile = config.profiles[opts.profile] ?? {};
99
+ profile.app_id = creds.appId;
100
+ profile.customer_id = creds.customerId;
101
+ profile.customer_secret = creds.customerSecret;
102
+ profile.region = creds.region;
103
+ config.profiles[opts.profile] = profile;
104
+ }
105
+ else {
106
+ // Save as top-level (default) credentials
107
+ config.app_id = creds.appId;
108
+ config.customer_id = creds.customerId;
109
+ config.customer_secret = creds.customerSecret;
110
+ config.region = creds.region;
111
+ }
112
+ saveConfig(config);
113
+ await verifyConnectivity(creds);
114
+ const target = opts.profile ? `profile "${opts.profile}"` : 'default profile';
115
+ printSuccess(`Credentials saved to ${target}.`);
116
+ printHint(hintAfterLogin());
117
+ }
118
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../../src/commands/auth/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerAuthLogout(program: Command): void;
@@ -0,0 +1,84 @@
1
+ import { loadConfig, saveConfig } from '../../config/manager.js';
2
+ import { printSuccess, printError } from '../../ui/output.js';
3
+ import { handleError } from '../../utils/errors.js';
4
+ // ─── Command Registration ──────────────────────────────────────────────────
5
+ export function registerAuthLogout(program) {
6
+ program
7
+ .command('logout')
8
+ .description('Remove stored credentials')
9
+ .option('--profile <name>', 'Remove a specific named profile')
10
+ .option('--force', 'Skip confirmation prompt')
11
+ .action(async (opts) => {
12
+ try {
13
+ await logoutAction(opts);
14
+ }
15
+ catch (error) {
16
+ handleError(error);
17
+ }
18
+ });
19
+ }
20
+ async function logoutAction(opts) {
21
+ const { default: inquirer } = await import('inquirer');
22
+ const config = loadConfig();
23
+ if (opts.profile) {
24
+ // Remove a specific profile
25
+ if (!config.profiles?.[opts.profile]) {
26
+ printError(`Profile "${opts.profile}" does not exist.`);
27
+ process.exit(1);
28
+ }
29
+ if (!opts.force) {
30
+ const { confirmed } = await inquirer.prompt([
31
+ {
32
+ type: 'confirm',
33
+ name: 'confirmed',
34
+ message: `Remove credentials for profile "${opts.profile}"?`,
35
+ default: false,
36
+ },
37
+ ]);
38
+ if (!confirmed) {
39
+ return;
40
+ }
41
+ }
42
+ delete config.profiles[opts.profile];
43
+ // Clean up empty profiles object
44
+ if (Object.keys(config.profiles).length === 0) {
45
+ delete config.profiles;
46
+ }
47
+ // If the deleted profile was the default, clear that reference
48
+ if (config.default_profile === opts.profile) {
49
+ delete config.default_profile;
50
+ }
51
+ saveConfig(config);
52
+ printSuccess(`Profile "${opts.profile}" has been removed.`);
53
+ }
54
+ else {
55
+ // Clear all credentials
56
+ if (!opts.force) {
57
+ const { confirmed } = await inquirer.prompt([
58
+ {
59
+ type: 'confirm',
60
+ name: 'confirmed',
61
+ message: 'Remove all stored credentials? This cannot be undone.',
62
+ default: false,
63
+ },
64
+ ]);
65
+ if (!confirmed) {
66
+ return;
67
+ }
68
+ }
69
+ clearAllCredentials(config);
70
+ saveConfig(config);
71
+ printSuccess('All credentials have been removed.');
72
+ }
73
+ }
74
+ // ─── Helpers ───────────────────────────────────────────────────────────────
75
+ function clearAllCredentials(config) {
76
+ delete config.app_id;
77
+ delete config.customer_id;
78
+ delete config.customer_secret;
79
+ delete config.region;
80
+ delete config.base_url;
81
+ delete config.default_profile;
82
+ delete config.profiles;
83
+ }
84
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../../src/commands/auth/logout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerAuthStatus(program: Command): void;
@@ -0,0 +1,114 @@
1
+ import chalk from 'chalk';
2
+ import { loadConfig, getActiveProfile } from '../../config/manager.js';
3
+ import { createClient } from '../../api/client.js';
4
+ import { AgentAPI } from '../../api/agents.js';
5
+ import { printError, printHint } from '../../ui/output.js';
6
+ import { printKeyValue } from '../../ui/table.js';
7
+ import { withSpinner } from '../../ui/spinner.js';
8
+ import { handleError } from '../../utils/errors.js';
9
+ // ─── Command Registration ──────────────────────────────────────────────────
10
+ export function registerAuthStatus(program) {
11
+ program
12
+ .command('status')
13
+ .description('Show current authentication status')
14
+ .option('--profile <name>', 'Show status for a named profile')
15
+ .option('--json', 'Output as JSON')
16
+ .action(async (opts) => {
17
+ try {
18
+ await statusAction(opts);
19
+ }
20
+ catch (error) {
21
+ handleError(error, { json: opts.json });
22
+ }
23
+ });
24
+ }
25
+ function maskSecret(secret) {
26
+ if (!secret)
27
+ return '(not set)';
28
+ if (secret.length <= 4)
29
+ return '****';
30
+ return secret.slice(0, 4) + '****';
31
+ }
32
+ async function testConnectivity(profile) {
33
+ if (!profile.app_id || !profile.customer_id || !profile.customer_secret) {
34
+ return false;
35
+ }
36
+ const client = createClient({
37
+ appId: profile.app_id,
38
+ customerId: profile.customer_id,
39
+ customerSecret: profile.customer_secret,
40
+ region: profile.region,
41
+ });
42
+ const api = new AgentAPI(client);
43
+ try {
44
+ await api.list({ limit: 1 });
45
+ return true;
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
51
+ // ─── Action ────────────────────────────────────────────────────────────────
52
+ async function statusAction(opts) {
53
+ const config = loadConfig();
54
+ let profile;
55
+ let profileName;
56
+ if (opts.profile) {
57
+ if (!config.profiles?.[opts.profile]) {
58
+ if (opts.json) {
59
+ console.log(JSON.stringify({ error: `Profile "${opts.profile}" not found` }));
60
+ }
61
+ else {
62
+ printError(`Profile "${opts.profile}" not found.`);
63
+ }
64
+ process.exit(1);
65
+ }
66
+ profile = config.profiles[opts.profile];
67
+ profileName = opts.profile;
68
+ }
69
+ else {
70
+ profile = getActiveProfile();
71
+ profileName = config.default_profile ?? 'default';
72
+ }
73
+ const hasCredentials = Boolean(profile.app_id && profile.customer_id && profile.customer_secret);
74
+ let connected = false;
75
+ if (hasCredentials) {
76
+ connected = await withSpinner('Testing connectivity...', () => testConnectivity(profile));
77
+ }
78
+ if (opts.json) {
79
+ outputJson(profile, profileName, hasCredentials, connected);
80
+ }
81
+ else {
82
+ outputFormatted(profile, profileName, hasCredentials, connected);
83
+ }
84
+ }
85
+ function outputJson(profile, profileName, hasCredentials, connected) {
86
+ console.log(JSON.stringify({
87
+ profile: profileName,
88
+ app_id: profile.app_id ?? null,
89
+ customer_id: profile.customer_id ?? null,
90
+ customer_secret: maskSecret(profile.customer_secret),
91
+ region: profile.region ?? 'global',
92
+ authenticated: hasCredentials,
93
+ connected,
94
+ }, null, 2));
95
+ }
96
+ function outputFormatted(profile, profileName, hasCredentials, connected) {
97
+ const connStatus = connected
98
+ ? chalk.green('\u2714 Connected')
99
+ : hasCredentials
100
+ ? chalk.red('\u2718 Connection failed')
101
+ : chalk.yellow('Not configured');
102
+ printKeyValue([
103
+ ['Profile', profileName],
104
+ ['App ID', profile.app_id ?? '(not set)'],
105
+ ['Customer ID', profile.customer_id ?? '(not set)'],
106
+ ['Customer Secret', maskSecret(profile.customer_secret)],
107
+ ['Region', profile.region ?? 'global'],
108
+ ['Status', connStatus],
109
+ ]);
110
+ if (!hasCredentials) {
111
+ printHint('Run `convoai auth login` to configure credentials.');
112
+ }
113
+ }
114
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/commands/auth/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { CallAPI } from '../../api/calls.js';
2
+ /**
3
+ * Resolve config for the given profile, create an authenticated HTTP client,
4
+ * and return a ready-to-use CallAPI instance.
5
+ */
6
+ export declare function getCallAPI(profileName?: string): CallAPI;
7
+ export { formatTimestamp, formatDuration } from '../../utils/format.js';
@@ -0,0 +1,32 @@
1
+ import { resolveConfig } from '../../config/manager.js';
2
+ import { createClient } from '../../api/client.js';
3
+ import { CallAPI } from '../../api/calls.js';
4
+ // ─── Call API Factory ─────────────────────────────────────────────────────
5
+ /**
6
+ * Resolve config for the given profile, create an authenticated HTTP client,
7
+ * and return a ready-to-use CallAPI instance.
8
+ */
9
+ export function getCallAPI(profileName) {
10
+ const config = resolveConfig(profileName);
11
+ if (!config.app_id || !config.customer_id || !config.customer_secret) {
12
+ const missing = [];
13
+ if (!config.app_id)
14
+ missing.push('app_id');
15
+ if (!config.customer_id)
16
+ missing.push('customer_id');
17
+ if (!config.customer_secret)
18
+ missing.push('customer_secret');
19
+ throw new Error(`Missing required credentials: ${missing.join(', ')}. Run "convoai auth login" to configure.`);
20
+ }
21
+ const client = createClient({
22
+ appId: config.app_id,
23
+ customerId: config.customer_id,
24
+ customerSecret: config.customer_secret,
25
+ baseUrl: config.base_url,
26
+ region: config.region,
27
+ });
28
+ return new CallAPI(client);
29
+ }
30
+ // ─── Timestamp / Duration Formatting (re-exported from shared utils) ──────
31
+ export { formatTimestamp, formatDuration } from '../../utils/format.js';
32
+ //# sourceMappingURL=_helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../../src/commands/call/_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,6EAA6E;AAE7E;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,WAAoB;IAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAE1C,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QACrE,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,CAAC,eAAe;YAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,iCAAiC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,0CAA0C,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC,MAAM;QACpB,UAAU,EAAE,MAAM,CAAC,WAAW;QAC9B,cAAc,EAAE,MAAM,CAAC,eAAe;QACtC,OAAO,EAAE,MAAM,CAAC,QAAQ;QACxB,MAAM,EAAE,MAAM,CAAC,MAAqC;KACrD,CAAC,CAAC;IACH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED,6EAA6E;AAE7E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerCallHangup(program: Command): void;
@@ -0,0 +1,29 @@
1
+ import { getCallAPI } from './_helpers.js';
2
+ import { withSpinner } from '../../ui/spinner.js';
3
+ import { printSuccess, printHint } from '../../ui/output.js';
4
+ import { handleError } from '../../utils/errors.js';
5
+ import { shortId } from '../../utils/hints.js';
6
+ // ─── Command Registration ──────────────────────────────────────────────────
7
+ export function registerCallHangup(program) {
8
+ program
9
+ .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')
13
+ .action(async (agentId, opts) => {
14
+ try {
15
+ 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.');
23
+ }
24
+ catch (error) {
25
+ handleError(error, { json: opts.json });
26
+ }
27
+ });
28
+ }
29
+ //# sourceMappingURL=hangup.js.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerCallInitiate(program: Command): void;
@@ -0,0 +1,137 @@
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';
5
+ import { printSuccess, printError, printHint } from '../../ui/output.js';
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 ──────────────────────────────────────────────────
81
+ export function registerCallInitiate(program) {
82
+ program
83
+ .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')
93
+ .action(async (opts) => {
94
+ 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();
99
+ }
100
+ if (!phone) {
101
+ printError('--phone is required. Provide it as a flag or run interactively in a TTY.');
102
+ process.exit(1);
103
+ }
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
113
+ if (opts.dryRun) {
114
+ console.log(JSON.stringify(request, null, 2));
115
+ return;
116
+ }
117
+ const api = getCallAPI(opts.profile);
118
+ const result = await withSpinner('Initiating call...', () => api.initiate(request));
119
+ if (opts.json) {
120
+ console.log(JSON.stringify(result, null, 2));
121
+ return;
122
+ }
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.`);
131
+ }
132
+ catch (error) {
133
+ handleError(error, { json: opts.json });
134
+ }
135
+ });
136
+ }
137
+ //# sourceMappingURL=initiate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initiate.js","sourceRoot":"","sources":["../../../../src/commands/call/initiate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerCallStatus(program: Command): void;
@@ -0,0 +1,50 @@
1
+ import { getCallAPI, formatTimestamp, formatDuration } from './_helpers.js';
2
+ import { withSpinner } from '../../ui/spinner.js';
3
+ import { printKeyValue } from '../../ui/table.js';
4
+ import { handleError } from '../../utils/errors.js';
5
+ // ─── Command Registration ──────────────────────────────────────────────────
6
+ export function registerCallStatus(program) {
7
+ program
8
+ .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')
12
+ .action(async (agentId, opts) => {
13
+ try {
14
+ const api = getCallAPI(opts.profile);
15
+ const result = await withSpinner('Fetching call status...', () => api.status(agentId));
16
+ if (opts.json) {
17
+ console.log(JSON.stringify(result, null, 2));
18
+ return;
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);
44
+ }
45
+ catch (error) {
46
+ handleError(error, { json: opts.json });
47
+ }
48
+ });
49
+ }
50
+ //# sourceMappingURL=status.js.map
@@ -0,0 +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"}