@moxxy/cli 0.0.11 → 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 +278 -112
- package/bin/moxxy +10 -0
- package/package.json +36 -53
- package/src/api-client.js +286 -0
- package/src/cli.js +341 -0
- package/src/commands/agent.js +413 -0
- package/src/commands/auth.js +326 -0
- package/src/commands/channel.js +285 -0
- package/src/commands/doctor.js +261 -0
- package/src/commands/events.js +80 -0
- package/src/commands/gateway.js +428 -0
- package/src/commands/heartbeat.js +145 -0
- package/src/commands/init.js +767 -0
- package/src/commands/mcp.js +278 -0
- package/src/commands/plugin.js +583 -0
- package/src/commands/provider.js +1934 -0
- package/src/commands/skill.js +125 -0
- package/src/commands/template.js +237 -0
- package/src/commands/uninstall.js +196 -0
- package/src/commands/update.js +406 -0
- package/src/commands/vault.js +219 -0
- package/src/help.js +368 -0
- package/src/lib/plugin-registry.js +98 -0
- package/src/platform.js +40 -0
- package/src/sse-client.js +79 -0
- package/src/tui/action-wizards.js +130 -0
- package/src/tui/app.jsx +859 -0
- package/src/tui/components/action-picker.jsx +86 -0
- package/src/tui/components/chat-panel.jsx +120 -0
- package/src/tui/components/footer.jsx +13 -0
- package/src/tui/components/header.jsx +45 -0
- package/src/tui/components/input-area.jsx +384 -0
- package/src/tui/components/messages/ask-message.jsx +13 -0
- package/src/tui/components/messages/assistant-message.jsx +165 -0
- package/src/tui/components/messages/channel-message.jsx +18 -0
- package/src/tui/components/messages/event-message.jsx +22 -0
- package/src/tui/components/messages/hive-status.jsx +34 -0
- package/src/tui/components/messages/skill-message.jsx +31 -0
- package/src/tui/components/messages/system-message.jsx +12 -0
- package/src/tui/components/messages/thinking.jsx +25 -0
- package/src/tui/components/messages/tool-group.jsx +62 -0
- package/src/tui/components/messages/tool-message.jsx +66 -0
- package/src/tui/components/messages/user-message.jsx +12 -0
- package/src/tui/components/model-picker.jsx +138 -0
- package/src/tui/components/multiline-input.jsx +72 -0
- package/src/tui/events-handler.js +730 -0
- package/src/tui/helpers.js +59 -0
- package/src/tui/hooks/use-command-handler.js +451 -0
- package/src/tui/index.jsx +55 -0
- package/src/tui/input-utils.js +26 -0
- package/src/tui/markdown-renderer.js +66 -0
- package/src/tui/mcp-wizard.js +136 -0
- package/src/tui/model-picker.js +174 -0
- package/src/tui/slash-commands.js +26 -0
- package/src/tui/store.js +12 -0
- package/src/tui/theme.js +17 -0
- package/src/ui.js +109 -0
- package/bin/moxxy.js +0 -2
- package/dist/chunk-23LZYKQ6.mjs +0 -1131
- package/dist/chunk-2FZEA3NG.mjs +0 -457
- package/dist/chunk-3KDPLS22.mjs +0 -1131
- package/dist/chunk-3QRJTRBT.mjs +0 -1102
- package/dist/chunk-6DZX6EAA.mjs +0 -37
- package/dist/chunk-A4WRDUNY.mjs +0 -1242
- package/dist/chunk-C46NSEKG.mjs +0 -211
- package/dist/chunk-CAUXONEF.mjs +0 -1131
- package/dist/chunk-CPL5V56X.mjs +0 -1131
- package/dist/chunk-CTBVTTBG.mjs +0 -440
- package/dist/chunk-FHHLXTEZ.mjs +0 -1121
- package/dist/chunk-FXY3GPVA.mjs +0 -1126
- package/dist/chunk-GSNMMI3H.mjs +0 -530
- package/dist/chunk-HHOAOGUS.mjs +0 -1242
- package/dist/chunk-N5JTPB6U.mjs +0 -820
- package/dist/chunk-NGVL4Q5C.mjs +0 -1102
- package/dist/chunk-Q2OCMNYI.mjs +0 -1131
- package/dist/chunk-QDVRLN6D.mjs +0 -1121
- package/dist/chunk-QO2JONHP.mjs +0 -1131
- package/dist/chunk-RVAPILHA.mjs +0 -1242
- package/dist/chunk-S7YBOV7E.mjs +0 -1131
- package/dist/chunk-SHIG6Y5L.mjs +0 -1074
- package/dist/chunk-SOFST2PV.mjs +0 -1242
- package/dist/chunk-TMZWETMH.mjs +0 -1242
- package/dist/chunk-TYD7NMMI.mjs +0 -581
- package/dist/chunk-TYQ3YS42.mjs +0 -1068
- package/dist/chunk-UALWCJ7F.mjs +0 -1131
- package/dist/chunk-UQZKODNW.mjs +0 -1124
- package/dist/chunk-USC6R2ON.mjs +0 -1242
- package/dist/chunk-W32EQCVC.mjs +0 -823
- package/dist/chunk-WMB5ENMC.mjs +0 -1242
- package/dist/chunk-WNHA5JAP.mjs +0 -1242
- package/dist/cli-2AIWTL6F.mjs +0 -8
- package/dist/cli-2QKJ5UUL.mjs +0 -8
- package/dist/cli-4RIS6DQX.mjs +0 -8
- package/dist/cli-5RH4VBBL.mjs +0 -7
- package/dist/cli-7MK4YGOP.mjs +0 -7
- package/dist/cli-B4KH6MZI.mjs +0 -8
- package/dist/cli-CGO2LZ6Z.mjs +0 -8
- package/dist/cli-CVP26EL2.mjs +0 -8
- package/dist/cli-DDRVVNAV.mjs +0 -8
- package/dist/cli-E7U56QVQ.mjs +0 -8
- package/dist/cli-EQNRMLL3.mjs +0 -8
- package/dist/cli-F5RUHHH4.mjs +0 -8
- package/dist/cli-LX6FFSEF.mjs +0 -8
- package/dist/cli-LY74GWKR.mjs +0 -6
- package/dist/cli-MAT3ZJHI.mjs +0 -8
- package/dist/cli-NJXXTQYF.mjs +0 -8
- package/dist/cli-O4ZGFAZG.mjs +0 -8
- package/dist/cli-ORVLI3UQ.mjs +0 -8
- package/dist/cli-PV43ZVKA.mjs +0 -8
- package/dist/cli-REVD6ISM.mjs +0 -8
- package/dist/cli-TBX76KQX.mjs +0 -8
- package/dist/cli-TLX5ENVM.mjs +0 -8
- package/dist/cli-TNJHCBQA.mjs +0 -6
- package/dist/cli-TUX22CZP.mjs +0 -8
- package/dist/cli-XJVH7EEP.mjs +0 -8
- package/dist/cli-XXOW4VXJ.mjs +0 -8
- package/dist/cli-XZ5RESNB.mjs +0 -6
- package/dist/cli-YCBYZ76Q.mjs +0 -8
- package/dist/cli-ZLMQCU7X.mjs +0 -8
- package/dist/dist-2VGKJRBH.mjs +0 -6820
- package/dist/dist-37BNX4QG.mjs +0 -7081
- package/dist/dist-7LTHRYKA.mjs +0 -11569
- package/dist/dist-7XJPQW5C.mjs +0 -6950
- package/dist/dist-AYMVOW7T.mjs +0 -7123
- package/dist/dist-FAXRJMEN.mjs +0 -6812
- package/dist/dist-HQGANM3P.mjs +0 -6976
- package/dist/dist-KATLOZQV.mjs +0 -7054
- package/dist/dist-KLSB6YHV.mjs +0 -6964
- package/dist/dist-LKIOZQ42.mjs +0 -17
- package/dist/dist-UYA4RJUH.mjs +0 -2792
- package/dist/dist-ZYHCBILM.mjs +0 -6993
- package/dist/index.d.mts +0 -23
- package/dist/index.d.ts +0 -23
- package/dist/index.js +0 -25512
- package/dist/index.mjs +0 -18
- package/dist/src-APP5P3UD.mjs +0 -1386
- package/dist/src-D5HMDDVE.mjs +0 -1324
- package/dist/src-EK3WD4AU.mjs +0 -1327
- package/dist/src-LSZFLMFN.mjs +0 -1400
- package/dist/src-WIOCZRAC.mjs +0 -1397
- package/dist/src-YK6CHCMW.mjs +0 -1400
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent commands: create/run/stop/status.
|
|
3
|
+
*/
|
|
4
|
+
import { parseFlags } from './auth.js';
|
|
5
|
+
import { isInteractive, handleCancel, withSpinner, showResult, pickAgent, pickProvider, pickModel, p } from '../ui.js';
|
|
6
|
+
|
|
7
|
+
function firstModel(flag) {
|
|
8
|
+
if (Array.isArray(flag)) return flag[0];
|
|
9
|
+
return flag;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function parseAgentCommand(args) {
|
|
13
|
+
const [action, ...rest] = args;
|
|
14
|
+
const flags = parseFlags(rest);
|
|
15
|
+
|
|
16
|
+
switch (action) {
|
|
17
|
+
case 'create':
|
|
18
|
+
return {
|
|
19
|
+
action: 'create',
|
|
20
|
+
provider_id: flags.provider,
|
|
21
|
+
model_id: firstModel(flags.model),
|
|
22
|
+
name: flags.name,
|
|
23
|
+
persona: flags.persona,
|
|
24
|
+
temperature: flags.temperature ? parseFloat(flags.temperature) : undefined,
|
|
25
|
+
policy_profile: flags.policy,
|
|
26
|
+
json: flags.json === true || flags.json === 'true',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
case 'run':
|
|
30
|
+
return {
|
|
31
|
+
action: 'run',
|
|
32
|
+
id: flags.id,
|
|
33
|
+
task: flags.task,
|
|
34
|
+
json: flags.json === true || flags.json === 'true',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
case 'stop':
|
|
38
|
+
return {
|
|
39
|
+
action: 'stop',
|
|
40
|
+
id: flags.id,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
case 'status':
|
|
44
|
+
return {
|
|
45
|
+
action: 'status',
|
|
46
|
+
id: flags.id,
|
|
47
|
+
json: flags.json === true || flags.json === 'true',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
case 'update':
|
|
51
|
+
return {
|
|
52
|
+
action: 'update',
|
|
53
|
+
id: flags.id,
|
|
54
|
+
provider_id: flags.provider,
|
|
55
|
+
model_id: firstModel(flags.model),
|
|
56
|
+
temperature: flags.temperature ? parseFloat(flags.temperature) : undefined,
|
|
57
|
+
json: flags.json === true || flags.json === 'true',
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
case 'delete':
|
|
61
|
+
return {
|
|
62
|
+
action: 'delete',
|
|
63
|
+
id: flags.id,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
default:
|
|
67
|
+
return { action };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function agentCreate(client, args) {
|
|
72
|
+
const flags = parseFlags(args);
|
|
73
|
+
if (!flags.provider || !flags.model || !flags.name) {
|
|
74
|
+
throw new Error('Required: --provider, --model, --name');
|
|
75
|
+
}
|
|
76
|
+
const body = {
|
|
77
|
+
provider_id: flags.provider,
|
|
78
|
+
model_id: firstModel(flags.model),
|
|
79
|
+
name: flags.name,
|
|
80
|
+
};
|
|
81
|
+
if (flags.temperature) body.temperature = parseFloat(flags.temperature);
|
|
82
|
+
if (flags.policy) body.policy_profile = flags.policy;
|
|
83
|
+
if (flags.persona) body.persona = flags.persona;
|
|
84
|
+
|
|
85
|
+
const result = await client.request('/v1/agents', 'POST', body);
|
|
86
|
+
if (flags.json === 'true' || flags.json === true) {
|
|
87
|
+
console.log(JSON.stringify(result, null, 2));
|
|
88
|
+
} else {
|
|
89
|
+
console.log(`Agent created: ${result.name}`);
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function agentUpdate(client, args) {
|
|
95
|
+
const flags = parseFlags(args);
|
|
96
|
+
if (!flags.id) {
|
|
97
|
+
throw new Error('Required: --id');
|
|
98
|
+
}
|
|
99
|
+
const body = {};
|
|
100
|
+
if (flags.provider) body.provider_id = flags.provider;
|
|
101
|
+
if (flags.model) body.model_id = firstModel(flags.model);
|
|
102
|
+
if (flags.temperature) body.temperature = parseFloat(flags.temperature);
|
|
103
|
+
|
|
104
|
+
if (Object.keys(body).length === 0) {
|
|
105
|
+
throw new Error('Nothing to update. Provide --provider, --model, or --temperature');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const result = await client.request(`/v1/agents/${encodeURIComponent(flags.id)}`, 'PATCH', body);
|
|
109
|
+
if (flags.json === 'true' || flags.json === true) {
|
|
110
|
+
console.log(JSON.stringify(result, null, 2));
|
|
111
|
+
} else {
|
|
112
|
+
console.log(`Agent ${flags.id} updated.`);
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function agentStatus(client, id, opts = {}) {
|
|
118
|
+
if (!id) throw new Error('Required: agent ID');
|
|
119
|
+
const result = await client.request(`/v1/agents/${encodeURIComponent(id)}`, 'GET');
|
|
120
|
+
if (opts.json) {
|
|
121
|
+
console.log(JSON.stringify(result, null, 2));
|
|
122
|
+
} else {
|
|
123
|
+
console.log(`Agent: ${result.name}`);
|
|
124
|
+
console.log(` Status: ${result.status}`);
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function runAgent(client, args) {
|
|
130
|
+
const parsed = parseAgentCommand(args);
|
|
131
|
+
|
|
132
|
+
// Interactive sub-menu when no valid action
|
|
133
|
+
if (!['create', 'run', 'stop', 'status', 'update', 'delete'].includes(parsed.action) && isInteractive()) {
|
|
134
|
+
const action = await p.select({
|
|
135
|
+
message: 'Agent action',
|
|
136
|
+
options: [
|
|
137
|
+
{ value: 'create', label: 'Create agent', hint: 'provision a new agent' },
|
|
138
|
+
{ value: 'update', label: 'Update agent', hint: 'change provider, model, or temperature' },
|
|
139
|
+
{ value: 'run', label: 'Start run', hint: 'run a task on an agent' },
|
|
140
|
+
{ value: 'stop', label: 'Stop agent', hint: 'stop a running agent' },
|
|
141
|
+
{ value: 'status', label: 'Agent status', hint: 'check agent status' },
|
|
142
|
+
{ value: 'delete', label: 'Delete agent', hint: 'permanently remove an agent' },
|
|
143
|
+
],
|
|
144
|
+
});
|
|
145
|
+
handleCancel(action);
|
|
146
|
+
parsed.action = action;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
switch (parsed.action) {
|
|
150
|
+
case 'create': {
|
|
151
|
+
// Interactive wizard when missing required flags
|
|
152
|
+
if ((!parsed.provider_id || !parsed.model_id) && isInteractive()) {
|
|
153
|
+
p.intro('Create Agent');
|
|
154
|
+
|
|
155
|
+
const nameInput = await p.text({
|
|
156
|
+
message: 'Agent name',
|
|
157
|
+
placeholder: 'my-agent',
|
|
158
|
+
initialValue: parsed.name || '',
|
|
159
|
+
validate: (val) => {
|
|
160
|
+
if (!val) return 'Name is required';
|
|
161
|
+
if (val.length > 64) return 'Name must be 64 chars or fewer';
|
|
162
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(val)) return 'Lowercase alphanumeric + hyphens, starting with alphanumeric';
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
handleCancel(nameInput);
|
|
166
|
+
|
|
167
|
+
const providerId = parsed.provider_id || await pickProvider(client);
|
|
168
|
+
const modelId = parsed.model_id || await pickModel(client, providerId);
|
|
169
|
+
|
|
170
|
+
const personaInput = await p.text({
|
|
171
|
+
message: 'Agent persona (optional)',
|
|
172
|
+
placeholder: 'You are a helpful coding assistant...',
|
|
173
|
+
initialValue: parsed.persona || '',
|
|
174
|
+
});
|
|
175
|
+
handleCancel(personaInput);
|
|
176
|
+
|
|
177
|
+
// Optional template selection
|
|
178
|
+
let templateSlug = null;
|
|
179
|
+
try {
|
|
180
|
+
const templates = await client.listTemplates();
|
|
181
|
+
if (templates && templates.length > 0) {
|
|
182
|
+
const templateOptions = [
|
|
183
|
+
{ value: '__none__', label: 'None', hint: 'no template' },
|
|
184
|
+
...templates.map(t => ({
|
|
185
|
+
value: t.slug,
|
|
186
|
+
label: t.name,
|
|
187
|
+
hint: t.description,
|
|
188
|
+
})),
|
|
189
|
+
];
|
|
190
|
+
const templateChoice = await p.select({
|
|
191
|
+
message: 'Assign a template? (optional)',
|
|
192
|
+
options: templateOptions,
|
|
193
|
+
});
|
|
194
|
+
handleCancel(templateChoice);
|
|
195
|
+
if (templateChoice !== '__none__') {
|
|
196
|
+
templateSlug = templateChoice;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
} catch { /* templates not available, skip */ }
|
|
200
|
+
|
|
201
|
+
const tempInput = await p.text({
|
|
202
|
+
message: 'Temperature',
|
|
203
|
+
placeholder: '0.7',
|
|
204
|
+
initialValue: parsed.temperature !== undefined ? String(parsed.temperature) : '0.7',
|
|
205
|
+
});
|
|
206
|
+
handleCancel(tempInput);
|
|
207
|
+
const temperature = tempInput ? parseFloat(tempInput) : 0.7;
|
|
208
|
+
|
|
209
|
+
const body = {
|
|
210
|
+
name: nameInput,
|
|
211
|
+
provider_id: providerId,
|
|
212
|
+
model_id: modelId,
|
|
213
|
+
temperature,
|
|
214
|
+
};
|
|
215
|
+
if (personaInput) body.persona = personaInput;
|
|
216
|
+
if (templateSlug) body.template = templateSlug;
|
|
217
|
+
|
|
218
|
+
const result = await withSpinner('Creating agent...', () =>
|
|
219
|
+
client.request('/v1/agents', 'POST', body), 'Agent created.');
|
|
220
|
+
|
|
221
|
+
showResult('Agent Created', {
|
|
222
|
+
Name: result.name,
|
|
223
|
+
Provider: providerId,
|
|
224
|
+
Model: modelId,
|
|
225
|
+
Status: result.status,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const startRun = await p.confirm({
|
|
229
|
+
message: 'Start a run?',
|
|
230
|
+
initialValue: false,
|
|
231
|
+
});
|
|
232
|
+
handleCancel(startRun);
|
|
233
|
+
|
|
234
|
+
if (startRun) {
|
|
235
|
+
const task = await p.text({
|
|
236
|
+
message: 'Task description',
|
|
237
|
+
placeholder: 'Describe the task...',
|
|
238
|
+
});
|
|
239
|
+
handleCancel(task);
|
|
240
|
+
|
|
241
|
+
await withSpinner('Starting run...', () =>
|
|
242
|
+
client.request(`/v1/agents/${encodeURIComponent(result.name)}/runs`, 'POST', { task }), 'Run started.');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return agentCreate(client, args.slice(1));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
case 'run': {
|
|
252
|
+
// Interactive wizard when missing id or task
|
|
253
|
+
if ((!parsed.id || !parsed.task) && isInteractive()) {
|
|
254
|
+
const agentId = parsed.id || await pickAgent(client, 'Select agent to run');
|
|
255
|
+
|
|
256
|
+
const task = parsed.task || handleCancel(await p.text({
|
|
257
|
+
message: 'Task description',
|
|
258
|
+
placeholder: 'Describe the task...',
|
|
259
|
+
validate: (val) => { if (!val) return 'Task is required'; },
|
|
260
|
+
}));
|
|
261
|
+
|
|
262
|
+
const result = await withSpinner('Starting run...', () =>
|
|
263
|
+
client.request(`/v1/agents/${encodeURIComponent(agentId)}/runs`, 'POST', { task }), 'Run started.');
|
|
264
|
+
|
|
265
|
+
showResult('Run Started', {
|
|
266
|
+
Agent: agentId,
|
|
267
|
+
'Run ID': result.run_id || result.id,
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const tailEvents = await p.confirm({
|
|
271
|
+
message: 'Tail events?',
|
|
272
|
+
initialValue: false,
|
|
273
|
+
});
|
|
274
|
+
handleCancel(tailEvents);
|
|
275
|
+
|
|
276
|
+
if (tailEvents) {
|
|
277
|
+
const { runEvents } = await import('./events.js');
|
|
278
|
+
await runEvents(client, ['tail', '--agent', agentId]);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!parsed.id || !parsed.task) {
|
|
285
|
+
throw new Error('Required: --id, --task');
|
|
286
|
+
}
|
|
287
|
+
const result = await client.request(`/v1/agents/${encodeURIComponent(parsed.id)}/runs`, 'POST', { task: parsed.task });
|
|
288
|
+
if (parsed.json) {
|
|
289
|
+
console.log(JSON.stringify(result, null, 2));
|
|
290
|
+
} else {
|
|
291
|
+
console.log(`Run started for agent ${parsed.id}`);
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
case 'stop': {
|
|
297
|
+
let id = parsed.id;
|
|
298
|
+
|
|
299
|
+
if (!id && isInteractive()) {
|
|
300
|
+
id = await pickAgent(client, 'Select agent to stop');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!id) throw new Error('Required: --id');
|
|
304
|
+
|
|
305
|
+
if (isInteractive()) {
|
|
306
|
+
await withSpinner('Stopping agent...', () =>
|
|
307
|
+
client.request(`/v1/agents/${encodeURIComponent(id)}/stop`, 'POST'), 'Agent stopped.');
|
|
308
|
+
} else {
|
|
309
|
+
await client.request(`/v1/agents/${encodeURIComponent(id)}/stop`, 'POST');
|
|
310
|
+
console.log(`Agent ${id} stopped.`);
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
case 'status': {
|
|
316
|
+
let id = parsed.id;
|
|
317
|
+
|
|
318
|
+
if (!id && isInteractive()) {
|
|
319
|
+
id = await pickAgent(client, 'Select agent to check');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (!id) throw new Error('Required: --id');
|
|
323
|
+
|
|
324
|
+
if (isInteractive()) {
|
|
325
|
+
const result = await withSpinner('Fetching status...', () =>
|
|
326
|
+
client.request(`/v1/agents/${encodeURIComponent(id)}`, 'GET'), 'Status loaded.');
|
|
327
|
+
|
|
328
|
+
showResult('Agent Status', {
|
|
329
|
+
Name: result.name,
|
|
330
|
+
Status: result.status,
|
|
331
|
+
Provider: result.provider_id,
|
|
332
|
+
Model: result.model_id,
|
|
333
|
+
});
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return agentStatus(client, id, { json: parsed.json });
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
case 'update': {
|
|
341
|
+
// Interactive wizard when missing id
|
|
342
|
+
if (!parsed.id && isInteractive()) {
|
|
343
|
+
p.intro('Update Agent');
|
|
344
|
+
|
|
345
|
+
const agentId = await pickAgent(client, 'Select agent to update');
|
|
346
|
+
const current = await client.request(`/v1/agents/${encodeURIComponent(agentId)}`, 'GET');
|
|
347
|
+
|
|
348
|
+
p.log.info(`Current: ${current.provider_id}/${current.model_id} (temp=${current.temperature ?? 0.7})`);
|
|
349
|
+
|
|
350
|
+
const providerId = await pickProvider(client);
|
|
351
|
+
const modelId = await pickModel(client, providerId);
|
|
352
|
+
|
|
353
|
+
const tempInput = await p.text({
|
|
354
|
+
message: 'Temperature',
|
|
355
|
+
placeholder: '0.7',
|
|
356
|
+
initialValue: String(current.temperature ?? 0.7),
|
|
357
|
+
});
|
|
358
|
+
handleCancel(tempInput);
|
|
359
|
+
const temperature = tempInput ? parseFloat(tempInput) : 0.7;
|
|
360
|
+
|
|
361
|
+
const body = { provider_id: providerId, model_id: modelId, temperature };
|
|
362
|
+
const result = await withSpinner('Updating agent...', () =>
|
|
363
|
+
client.request(`/v1/agents/${encodeURIComponent(agentId)}`, 'PATCH', body), 'Agent updated.');
|
|
364
|
+
|
|
365
|
+
showResult('Agent Updated', {
|
|
366
|
+
ID: agentId,
|
|
367
|
+
Provider: providerId,
|
|
368
|
+
Model: modelId,
|
|
369
|
+
Temperature: temperature,
|
|
370
|
+
Status: result.status,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return agentUpdate(client, args.slice(1));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
case 'delete': {
|
|
380
|
+
let id = parsed.id;
|
|
381
|
+
|
|
382
|
+
if (!id && isInteractive()) {
|
|
383
|
+
id = await pickAgent(client, 'Select agent to delete');
|
|
384
|
+
|
|
385
|
+
const confirmed = await p.confirm({
|
|
386
|
+
message: 'Permanently delete this agent and all its data?',
|
|
387
|
+
initialValue: false,
|
|
388
|
+
});
|
|
389
|
+
handleCancel(confirmed);
|
|
390
|
+
if (!confirmed) {
|
|
391
|
+
p.log.info('Cancelled.');
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (!id) throw new Error('Required: --id');
|
|
397
|
+
|
|
398
|
+
await client.deleteAgent(id);
|
|
399
|
+
if (isInteractive()) {
|
|
400
|
+
p.log.success(`Agent ${id} deleted.`);
|
|
401
|
+
} else {
|
|
402
|
+
console.log(`Agent ${id} deleted.`);
|
|
403
|
+
}
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
default: {
|
|
408
|
+
const { showHelp } = await import('../help.js');
|
|
409
|
+
showHelp('agent', p);
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|