callkaro-cli-unofficial 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -0
- package/dist/commands/accounts.js +275 -0
- package/dist/commands/agentPhone.js +50 -0
- package/dist/commands/agentVersions.js +228 -0
- package/dist/commands/agents.js +455 -0
- package/dist/commands/analytics.js +77 -0
- package/dist/commands/analyzers.js +130 -0
- package/dist/commands/auditStrategies.js +178 -0
- package/dist/commands/batches.js +189 -0
- package/dist/commands/calls.js +193 -0
- package/dist/commands/chatAgents.js +251 -0
- package/dist/commands/jsonInput.js +56 -0
- package/dist/commands/kpi.js +681 -0
- package/dist/commands/models.js +99 -0
- package/dist/commands/numbers.js +154 -0
- package/dist/commands/ongoing.js +39 -0
- package/dist/commands/secrets.js +124 -0
- package/dist/commands/setJson.js +42 -0
- package/dist/commands/simulations.js +139 -0
- package/dist/commands/skills.js +318 -0
- package/dist/commands/transcribers.js +95 -0
- package/dist/commands/update.js +86 -0
- package/dist/commands/voices.js +211 -0
- package/dist/data/catalog.json +1978 -0
- package/dist/endpoints.json +8 -0
- package/dist/index.js +684 -0
- package/dist/lib/agentImport.js +60 -0
- package/dist/lib/agentUpdate.js +262 -0
- package/dist/lib/api.js +287 -0
- package/dist/lib/browserAuth.js +93 -0
- package/dist/lib/catalog.js +136 -0
- package/dist/lib/config.js +354 -0
- package/dist/lib/dashboardApi.js +197 -0
- package/dist/lib/dashboardAuth.js +339 -0
- package/dist/lib/dbFields.js +30 -0
- package/dist/lib/logQuery.js +140 -0
- package/dist/lib/looseJson.js +198 -0
- package/dist/lib/session.js +17 -0
- package/dist/lib/types.js +15 -0
- package/dist/lib/ui.js +91 -0
- package/dist/lib/versions.js +19 -0
- package/package.json +52 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCallQuery = buildCallQuery;
|
|
4
|
+
exports.callsListCommand = callsListCommand;
|
|
5
|
+
exports.callsGetCommand = callsGetCommand;
|
|
6
|
+
exports.callsLogsCommand = callsLogsCommand;
|
|
7
|
+
exports.callsMakeCommand = callsMakeCommand;
|
|
8
|
+
exports.callsExportCommand = callsExportCommand;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const session_1 = require("../lib/session");
|
|
11
|
+
const ui_1 = require("../lib/ui");
|
|
12
|
+
const versions_1 = require("../lib/versions");
|
|
13
|
+
const logQuery_1 = require("../lib/logQuery");
|
|
14
|
+
function fmtTime(v) {
|
|
15
|
+
if (!v)
|
|
16
|
+
return '';
|
|
17
|
+
const d = new Date(v);
|
|
18
|
+
return isNaN(d.getTime()) ? '' : d.toLocaleString('en-US');
|
|
19
|
+
}
|
|
20
|
+
function buildCallQuery(o) {
|
|
21
|
+
return {
|
|
22
|
+
name: o.type,
|
|
23
|
+
agent_id: o.agent,
|
|
24
|
+
version_ids: o.versions,
|
|
25
|
+
start_date: o.start,
|
|
26
|
+
end_date: o.end,
|
|
27
|
+
is_batch_call: o.batch,
|
|
28
|
+
hangup_reasons: o.hangup,
|
|
29
|
+
call_duration: o.duration,
|
|
30
|
+
to: o.to,
|
|
31
|
+
conversion_status: o.converted,
|
|
32
|
+
lead_id: o.lead,
|
|
33
|
+
buylead: o.buylead,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async function callsListCommand(opts) {
|
|
37
|
+
const api = (0, session_1.requireApi)();
|
|
38
|
+
try {
|
|
39
|
+
const res = await api.listCalls({
|
|
40
|
+
...buildCallQuery(opts),
|
|
41
|
+
pageSize: (0, ui_1.intFlag)(opts.limit, '--limit', 50),
|
|
42
|
+
page: 1,
|
|
43
|
+
});
|
|
44
|
+
const calls = res.calls || [];
|
|
45
|
+
if (opts.json)
|
|
46
|
+
return void console.log(JSON.stringify(calls, null, 2));
|
|
47
|
+
if (!calls.length)
|
|
48
|
+
return void (0, ui_1.info)('No calls found.');
|
|
49
|
+
(0, ui_1.table)(['TYPE', 'FROM', 'TO', 'AGENT', 'VERSION', 'DURATION', 'HANGUP', 'TIME'], calls.map((c) => [
|
|
50
|
+
c.name || '',
|
|
51
|
+
c.from || '',
|
|
52
|
+
c.to || '',
|
|
53
|
+
c.agent?.name || '',
|
|
54
|
+
c.versionId?.versionName || '',
|
|
55
|
+
c.call_duration ?? '',
|
|
56
|
+
c.hangup_reason || '',
|
|
57
|
+
fmtTime(c.createdAt || c.time),
|
|
58
|
+
]));
|
|
59
|
+
if (res.pagination)
|
|
60
|
+
(0, ui_1.info)(`\n${calls.length} of ${res.pagination.totalDocs} calls.`);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
(0, ui_1.handleError)(err);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function callsGetCommand(callId, opts) {
|
|
67
|
+
const api = (0, session_1.requireApi)();
|
|
68
|
+
try {
|
|
69
|
+
const res = await api.getCall(callId);
|
|
70
|
+
const call = (res.calls && res.calls[0]) || null;
|
|
71
|
+
if (!call)
|
|
72
|
+
return (0, ui_1.handleError)(new Error('Call not found'));
|
|
73
|
+
// Never surface the blob URL — `cku calls logs` fetches it internally.
|
|
74
|
+
const { logfile_url: _logfileUrl, ...safeCall } = call;
|
|
75
|
+
if (opts.json)
|
|
76
|
+
return void console.log(JSON.stringify(safeCall, null, 2));
|
|
77
|
+
(0, ui_1.keyValue)({
|
|
78
|
+
id: call._id,
|
|
79
|
+
type: call.name,
|
|
80
|
+
from: call.from,
|
|
81
|
+
to: call.to,
|
|
82
|
+
agent: call.agent?.name,
|
|
83
|
+
version: call.versionId?.versionName,
|
|
84
|
+
duration: call.call_duration,
|
|
85
|
+
hangupReason: call.hangup_reason,
|
|
86
|
+
disposition: call.disposition_reason,
|
|
87
|
+
credits: call.total_credits,
|
|
88
|
+
recording: call.recording?.recordingUrl,
|
|
89
|
+
time: fmtTime(call.createdAt || call.time),
|
|
90
|
+
});
|
|
91
|
+
if (call.recording?.transcription)
|
|
92
|
+
(0, ui_1.info)('\nUse --json to see the full transcript.');
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
(0, ui_1.handleError)(err);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const DEFAULT_LOG_QUERY = 'grep -v _trace.py /call.log | tail -100';
|
|
99
|
+
/**
|
|
100
|
+
* `cku calls logs <callId> [query]` — a shell-style query over the call's raw
|
|
101
|
+
* log. The log is downloaded fresh each run and never printed or written to
|
|
102
|
+
* disk; only the query's output is shown.
|
|
103
|
+
*/
|
|
104
|
+
async function callsLogsCommand(callId, query) {
|
|
105
|
+
const api = (0, session_1.requireApi)();
|
|
106
|
+
try {
|
|
107
|
+
const res = await api.getCall(callId);
|
|
108
|
+
const call = (res.calls && res.calls[0]) || null;
|
|
109
|
+
if (!call)
|
|
110
|
+
return (0, ui_1.handleError)(new Error('Call not found'));
|
|
111
|
+
let text;
|
|
112
|
+
try {
|
|
113
|
+
text = await (0, logQuery_1.getLogText)(call);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
if (err instanceof logQuery_1.LogNotFoundError)
|
|
117
|
+
return (0, ui_1.handleError)(new Error((0, logQuery_1.unavailableReason)(call)));
|
|
118
|
+
throw err;
|
|
119
|
+
}
|
|
120
|
+
const { result, truncated } = await (0, logQuery_1.runLogQuery)(text, query || DEFAULT_LOG_QUERY);
|
|
121
|
+
console.log(result);
|
|
122
|
+
if (truncated)
|
|
123
|
+
(0, ui_1.fail)('Output truncated — narrow the query (e.g. add | head, or a tighter grep).');
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
(0, ui_1.handleError)(err);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function callsMakeCommand(opts) {
|
|
130
|
+
const api = (0, session_1.requireApi)();
|
|
131
|
+
if (!opts.agent)
|
|
132
|
+
return (0, ui_1.handleError)(new Error('--agent <agentId> is required'));
|
|
133
|
+
if (!opts.to)
|
|
134
|
+
return (0, ui_1.handleError)(new Error('--to <phoneNumber> is required'));
|
|
135
|
+
// Metadata from --metadata JSON, overlaid with --var key=value pairs.
|
|
136
|
+
let metadata = {};
|
|
137
|
+
if (opts.metadata) {
|
|
138
|
+
try {
|
|
139
|
+
metadata = JSON.parse(opts.metadata);
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
return (0, ui_1.handleError)(new Error(`--metadata is not valid JSON: ${e.message}`));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
for (const pair of opts.var || []) {
|
|
146
|
+
const idx = pair.indexOf('=');
|
|
147
|
+
if (idx === -1)
|
|
148
|
+
return (0, ui_1.handleError)(new Error(`Bad --var "${pair}" — use key=value`));
|
|
149
|
+
metadata[pair.slice(0, idx)] = pair.slice(idx + 1);
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const res = await api.makeCall({
|
|
153
|
+
agentId: opts.agent,
|
|
154
|
+
to: opts.to,
|
|
155
|
+
metadata,
|
|
156
|
+
version: (0, versions_1.firstVersion)(opts.versions),
|
|
157
|
+
commit_id: opts.commit,
|
|
158
|
+
is_test_call: opts.test,
|
|
159
|
+
});
|
|
160
|
+
(0, ui_1.success)(res.msg || `Call placed to ${opts.to}.`);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
(0, ui_1.handleError)(err);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function callsExportCommand(opts) {
|
|
167
|
+
const api = (0, session_1.requireApi)();
|
|
168
|
+
try {
|
|
169
|
+
const res = await api.exportCalls({
|
|
170
|
+
...buildCallQuery(opts),
|
|
171
|
+
export_fields: opts.fields,
|
|
172
|
+
include_chat_history: opts.includeChat ? 'true' : undefined,
|
|
173
|
+
user_email: opts.email,
|
|
174
|
+
});
|
|
175
|
+
// Email path or "too large" → server responds JSON, not a file.
|
|
176
|
+
if (res.json) {
|
|
177
|
+
if (res.ok)
|
|
178
|
+
return void (0, ui_1.success)(res.json.msg || 'Export requested (check your email).');
|
|
179
|
+
if (res.status === 409) {
|
|
180
|
+
return (0, ui_1.handleError)(new Error('Export too large — re-run with --email <you@example.com> to receive it by email.'));
|
|
181
|
+
}
|
|
182
|
+
return (0, ui_1.handleError)(new Error(res.json.msg || `Export failed (${res.status})`));
|
|
183
|
+
}
|
|
184
|
+
if (!res.ok || !res.buffer)
|
|
185
|
+
return (0, ui_1.handleError)(new Error(`Export failed (${res.status})`));
|
|
186
|
+
const out = opts.file || `calls-export-${Date.now()}.csv`;
|
|
187
|
+
(0, fs_1.writeFileSync)(out, res.buffer);
|
|
188
|
+
(0, ui_1.success)(`Exported call history to ${out}`);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
(0, ui_1.handleError)(err);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.chatAgentsModelsCommand = chatAgentsModelsCommand;
|
|
37
|
+
exports.chatAgentsTemplatesCommand = chatAgentsTemplatesCommand;
|
|
38
|
+
exports.chatAgentsTemplateCommand = chatAgentsTemplateCommand;
|
|
39
|
+
exports.chatAgentsListCommand = chatAgentsListCommand;
|
|
40
|
+
exports.chatAgentsGetCommand = chatAgentsGetCommand;
|
|
41
|
+
exports.chatAgentsVersionsCommand = chatAgentsVersionsCommand;
|
|
42
|
+
exports.chatAgentsCreateCommand = chatAgentsCreateCommand;
|
|
43
|
+
exports.chatAgentsUpdateCommand = chatAgentsUpdateCommand;
|
|
44
|
+
exports.chatAgentsCreateVersionCommand = chatAgentsCreateVersionCommand;
|
|
45
|
+
exports.chatAgentsPublishCommand = chatAgentsPublishCommand;
|
|
46
|
+
const session_1 = require("../lib/session");
|
|
47
|
+
const dashboardAuth_1 = require("../lib/dashboardAuth");
|
|
48
|
+
const ui_1 = require("../lib/ui");
|
|
49
|
+
const versions_1 = require("../lib/versions");
|
|
50
|
+
const jsonInput_1 = require("./jsonInput");
|
|
51
|
+
const dbFields_1 = require("../lib/dbFields");
|
|
52
|
+
async function chatAgentsModelsCommand(opts) {
|
|
53
|
+
const api = (0, session_1.requireApi)();
|
|
54
|
+
try {
|
|
55
|
+
const res = await api.listChatAgentModels();
|
|
56
|
+
const rows = res.models || res.data || [];
|
|
57
|
+
if (opts.file) {
|
|
58
|
+
(await Promise.resolve().then(() => __importStar(require('fs')))).writeFileSync(opts.file, JSON.stringify(rows, null, 2));
|
|
59
|
+
return void (0, ui_1.success)(`Saved ${rows.length} model(s) to ${opts.file}`);
|
|
60
|
+
}
|
|
61
|
+
if (opts.json)
|
|
62
|
+
return void console.log(JSON.stringify(rows, null, 2));
|
|
63
|
+
if (!rows.length)
|
|
64
|
+
return void (0, ui_1.info)('No chat-agent models available.');
|
|
65
|
+
(0, ui_1.table)(['PROVIDER', 'MODEL'], rows.map((m) => [m.provider || '', m.name || m.id || m.model || '']));
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
(0, ui_1.handleError)(err);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function chatAgentsTemplatesCommand(opts) {
|
|
72
|
+
const api = (0, session_1.requireApi)();
|
|
73
|
+
try {
|
|
74
|
+
const res = await api.listChatAgentTemplates(opts.provider || 'meta');
|
|
75
|
+
const rows = res.templates || [];
|
|
76
|
+
if (opts.file) {
|
|
77
|
+
(await Promise.resolve().then(() => __importStar(require('fs')))).writeFileSync(opts.file, JSON.stringify(rows, null, 2));
|
|
78
|
+
return void (0, ui_1.success)(`Saved ${rows.length} template(s) to ${opts.file}`);
|
|
79
|
+
}
|
|
80
|
+
if (opts.json)
|
|
81
|
+
return void console.log(JSON.stringify(rows, null, 2));
|
|
82
|
+
if (!rows.length)
|
|
83
|
+
return void (0, ui_1.info)('No templates found.');
|
|
84
|
+
(0, ui_1.table)(['ID', 'NAME', 'LANGUAGE', 'CATEGORY', 'STATUS'], rows.map((t) => [t.id || '', t.name || '', t.language || '', t.category || '', t.status || '']));
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
(0, ui_1.handleError)(err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function chatAgentsTemplateCommand(templateId, opts) {
|
|
91
|
+
const api = (0, session_1.requireApi)();
|
|
92
|
+
try {
|
|
93
|
+
const res = await api.getChatAgentTemplate(templateId, opts.provider || 'meta');
|
|
94
|
+
if (opts.file) {
|
|
95
|
+
(await Promise.resolve().then(() => __importStar(require('fs')))).writeFileSync(opts.file, JSON.stringify(res.template, null, 2));
|
|
96
|
+
return void (0, ui_1.success)(`Saved template to ${opts.file}`);
|
|
97
|
+
}
|
|
98
|
+
if (opts.json)
|
|
99
|
+
return void console.log(JSON.stringify(res.template, null, 2));
|
|
100
|
+
const t = res.template;
|
|
101
|
+
for (const [k, v] of Object.entries(t)) {
|
|
102
|
+
if (v === undefined || v === null)
|
|
103
|
+
continue;
|
|
104
|
+
console.log(` ${String(k).padEnd(20)} ${typeof v === 'object' ? JSON.stringify(v) : v}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
(0, ui_1.handleError)(err);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function chatAgentsListCommand(opts) {
|
|
112
|
+
const api = (0, session_1.requireApi)();
|
|
113
|
+
try {
|
|
114
|
+
const res = await api.listChatAgents();
|
|
115
|
+
const list = res.chatAgents || res.agents || [];
|
|
116
|
+
if (opts.file) {
|
|
117
|
+
(await Promise.resolve().then(() => __importStar(require('fs')))).writeFileSync(opts.file, JSON.stringify(list, null, 2));
|
|
118
|
+
return void (0, ui_1.success)(`Saved ${list.length} chat agent(s) to ${opts.file}`);
|
|
119
|
+
}
|
|
120
|
+
if (opts.json)
|
|
121
|
+
return void console.log(JSON.stringify(list, null, 2));
|
|
122
|
+
if (!list.length)
|
|
123
|
+
return void (0, ui_1.info)('No chat agents yet.');
|
|
124
|
+
(0, ui_1.table)(['NAME', 'ID', 'STATUS', 'PUBLISHED'], list.map((a) => [a.name || '(unnamed)', a._id, a.agentStatus || '', a.publishedVersionId || '']));
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
(0, ui_1.handleError)(err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function chatAgentsGetCommand(agentId, opts) {
|
|
131
|
+
const api = (0, session_1.requireApi)();
|
|
132
|
+
try {
|
|
133
|
+
const res = await api.getChatAgent(agentId, (0, versions_1.firstVersion)(opts.versions));
|
|
134
|
+
const agent = res.agent || res.chatAgent || {};
|
|
135
|
+
if (opts.file) {
|
|
136
|
+
(await Promise.resolve().then(() => __importStar(require('fs')))).writeFileSync(opts.file, JSON.stringify(agent, null, 2));
|
|
137
|
+
return void (0, ui_1.success)(`Saved chat agent ${agentId} to ${opts.file}`);
|
|
138
|
+
}
|
|
139
|
+
if (opts.json)
|
|
140
|
+
return void console.log(JSON.stringify(agent, null, 2));
|
|
141
|
+
for (const [k, v] of Object.entries(agent)) {
|
|
142
|
+
if (v === undefined || v === null)
|
|
143
|
+
continue;
|
|
144
|
+
if (typeof v === 'object')
|
|
145
|
+
continue;
|
|
146
|
+
console.log(` ${String(k).padEnd(24)} ${v}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
(0, ui_1.handleError)(err);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function chatAgentsVersionsCommand(agentId, opts) {
|
|
154
|
+
const api = (0, session_1.requireApi)();
|
|
155
|
+
try {
|
|
156
|
+
const res = await api.listChatAgentVersions(agentId);
|
|
157
|
+
const versions = res.versions || res || [];
|
|
158
|
+
if (opts.file) {
|
|
159
|
+
(await Promise.resolve().then(() => __importStar(require('fs')))).writeFileSync(opts.file, JSON.stringify(versions, null, 2));
|
|
160
|
+
return void (0, ui_1.success)(`Saved ${versions.length} version(s) to ${opts.file}`);
|
|
161
|
+
}
|
|
162
|
+
if (opts.json)
|
|
163
|
+
return void console.log(JSON.stringify(versions, null, 2));
|
|
164
|
+
if (!versions.length)
|
|
165
|
+
return void (0, ui_1.info)('No versions yet.');
|
|
166
|
+
(0, ui_1.table)(['VERSION', 'ID', 'ACTIVE'], versions.map((v) => [v.versionName || '', v._id, v.is_active ? 'yes' : 'no']));
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
(0, ui_1.handleError)(err);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** Shared: resolve a JSON arg, reject db-managed fields, require `name`. */
|
|
173
|
+
async function readChatAgentJson(json, file, label) {
|
|
174
|
+
const resolved = await (0, jsonInput_1.resolveJsonInput)(json, file);
|
|
175
|
+
let obj;
|
|
176
|
+
try {
|
|
177
|
+
obj = (0, jsonInput_1.parseJsonInput)(resolved);
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
throw new Error(`Not valid JSON: ${e.message}${(0, jsonInput_1.jsonHelpTip)(resolved.raw, resolved.fromShell)}`);
|
|
181
|
+
}
|
|
182
|
+
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
|
|
183
|
+
throw new Error(`${label} must be a JSON object`);
|
|
184
|
+
}
|
|
185
|
+
const found = (0, dbFields_1.dbManagedFields)(obj);
|
|
186
|
+
if (found.length)
|
|
187
|
+
throw new Error((0, dbFields_1.dbManagedFieldsError)(found, label));
|
|
188
|
+
if (!obj.name || typeof obj.name !== 'string')
|
|
189
|
+
throw new Error('"name" is required');
|
|
190
|
+
return obj;
|
|
191
|
+
}
|
|
192
|
+
async function chatAgentsCreateCommand(json, opts) {
|
|
193
|
+
const api = (0, session_1.requireApi)();
|
|
194
|
+
try {
|
|
195
|
+
const obj = await readChatAgentJson(json, opts.file, 'chat-agent JSON');
|
|
196
|
+
const res = await api.createChatAgent(obj);
|
|
197
|
+
if (opts.json)
|
|
198
|
+
return void console.log(JSON.stringify(res, null, 2));
|
|
199
|
+
(0, ui_1.success)(res.msg || 'Chat agent created.');
|
|
200
|
+
if (res.agent?._id)
|
|
201
|
+
(0, ui_1.info)(` id: ${res.agent._id}`);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
(0, ui_1.handleError)(err);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async function chatAgentsUpdateCommand(agentId, opts) {
|
|
208
|
+
const api = (0, session_1.requireApi)();
|
|
209
|
+
try {
|
|
210
|
+
await (0, dashboardAuth_1.refreshModelCatalog)();
|
|
211
|
+
const patch = await readChatAgentJson(opts.set, undefined, '--set object');
|
|
212
|
+
const res = await api.updateChatAgent(agentId, (0, versions_1.firstVersion)(opts.versions), patch);
|
|
213
|
+
if (opts.json)
|
|
214
|
+
return void console.log(JSON.stringify(res, null, 2));
|
|
215
|
+
(0, ui_1.success)(res.msg || 'Chat agent updated.');
|
|
216
|
+
(0, ui_1.info)(` updated: ${Object.keys(patch).join(', ')}`);
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
(0, ui_1.handleError)(err);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function chatAgentsCreateVersionCommand(agentId, json, opts) {
|
|
223
|
+
const api = (0, session_1.requireApi)();
|
|
224
|
+
try {
|
|
225
|
+
const obj = await readChatAgentJson(json, opts.file, 'chat-agent version JSON');
|
|
226
|
+
const res = await api.createChatAgentVersion(agentId, obj);
|
|
227
|
+
if (opts.json)
|
|
228
|
+
return void console.log(JSON.stringify(res, null, 2));
|
|
229
|
+
(0, ui_1.success)(res.msg || 'Chat agent version created.');
|
|
230
|
+
if (res.version?._id)
|
|
231
|
+
(0, ui_1.info)(` id: ${res.version._id}`);
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
(0, ui_1.handleError)(err);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async function chatAgentsPublishCommand(agentId, opts) {
|
|
238
|
+
const api = (0, session_1.requireApi)();
|
|
239
|
+
const versionId = (0, versions_1.firstVersion)(opts.versions);
|
|
240
|
+
if (!versionId)
|
|
241
|
+
return (0, ui_1.handleError)(new Error('--versions <versionId> is required'));
|
|
242
|
+
try {
|
|
243
|
+
const res = await api.publishChatAgentVersion(agentId, versionId);
|
|
244
|
+
if (opts.json)
|
|
245
|
+
return void console.log(JSON.stringify(res, null, 2));
|
|
246
|
+
(0, ui_1.success)(res.msg || `Published version ${versionId}.`);
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
(0, ui_1.handleError)(err);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jsonHelpTip = jsonHelpTip;
|
|
4
|
+
exports.resolveJsonInput = resolveJsonInput;
|
|
5
|
+
exports.parseJsonInput = parseJsonInput;
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const looseJson_1 = require("../lib/looseJson");
|
|
8
|
+
async function readStdin() {
|
|
9
|
+
const chunks = [];
|
|
10
|
+
for await (const chunk of process.stdin)
|
|
11
|
+
chunks.push(Buffer.from(chunk));
|
|
12
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
13
|
+
}
|
|
14
|
+
/** The tip appended to a JSON parse error, pointing at the file-based escapes. */
|
|
15
|
+
function jsonHelpTip(raw, fromShell) {
|
|
16
|
+
if (!fromShell)
|
|
17
|
+
return '\n If this came from a file, that is a genuine JSON syntax error.';
|
|
18
|
+
return ('\n Your shell may have stripped the quotes. The file forms are quote-proof:\n' +
|
|
19
|
+
' --file agent.json\n' +
|
|
20
|
+
' @agent.json\n' +
|
|
21
|
+
' < agent.json');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve JSON from `--file <path>`, an `@file` argument, an inline argument,
|
|
25
|
+
* or stdin (when not a TTY). Exactly one inline path gets the lenient parser.
|
|
26
|
+
*/
|
|
27
|
+
async function resolveJsonInput(arg, file) {
|
|
28
|
+
if (file) {
|
|
29
|
+
if (!(0, fs_1.existsSync)(file))
|
|
30
|
+
throw new Error(`File not found: ${file}`);
|
|
31
|
+
return { raw: (0, looseJson_1.readJsonFile)(file), fromShell: false };
|
|
32
|
+
}
|
|
33
|
+
if (arg && arg.startsWith('@')) {
|
|
34
|
+
const path = arg.slice(1);
|
|
35
|
+
if (!(0, fs_1.existsSync)(path))
|
|
36
|
+
throw new Error(`File not found: ${path}`);
|
|
37
|
+
return { raw: (0, looseJson_1.readJsonFile)(path), fromShell: false };
|
|
38
|
+
}
|
|
39
|
+
if (arg !== undefined && arg !== '')
|
|
40
|
+
return { raw: arg, fromShell: true };
|
|
41
|
+
if (!process.stdin.isTTY) {
|
|
42
|
+
return { raw: (0, looseJson_1.stripBom)(await readStdin()), fromShell: false }; // piped/redirected
|
|
43
|
+
}
|
|
44
|
+
throw new Error('Provide the agent JSON. Because shells mangle embedded quotes, a file is most reliable:\n' +
|
|
45
|
+
' cku agents create --file agent.json\n' +
|
|
46
|
+
' cku agents create @agent.json\n' +
|
|
47
|
+
' cku agents create < agent.json');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse a resolved input using the parser its source calls for. This is the only
|
|
51
|
+
* place that decision is made — commands should not branch on `fromShell`
|
|
52
|
+
* themselves.
|
|
53
|
+
*/
|
|
54
|
+
function parseJsonInput({ raw, fromShell }) {
|
|
55
|
+
return fromShell ? (0, looseJson_1.parseLooseJson)(raw) : JSON.parse(raw);
|
|
56
|
+
}
|