@kikimoradev/kcloud 1.0.3 → 1.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/dist/main.js +282 -37
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -781,9 +781,13 @@ const errorCodes = Object.keys({
|
|
|
781
781
|
"runtime.monitor_draining": "conflict",
|
|
782
782
|
"runtime.monitor_limited": "conflict",
|
|
783
783
|
"runtime.monitor_check_unsupported": "rule_violation",
|
|
784
|
+
"runtime.task_deletion_unsupported": "rule_violation",
|
|
785
|
+
"task.not_found": "not_found",
|
|
786
|
+
"task.not_finished": "conflict",
|
|
784
787
|
"node.not_found": "not_found",
|
|
785
788
|
"node.name_taken": "conflict",
|
|
786
789
|
"node.offline": "rule_violation",
|
|
790
|
+
"node.outdated": "rule_violation",
|
|
787
791
|
"node.not_registered": "rule_violation",
|
|
788
792
|
"node.registration_invalid": "unauthenticated",
|
|
789
793
|
"node.registration_used": "conflict",
|
|
@@ -1235,10 +1239,16 @@ const agentEventSummarySchema = z.object({
|
|
|
1235
1239
|
durationMs: z.int().nullable(),
|
|
1236
1240
|
payload: z.record(z.string(), z.unknown())
|
|
1237
1241
|
}).meta({ id: "AgentEventSummary" });
|
|
1242
|
+
const agentEventLimitSchema = z.coerce.number().int().min(1).max(500).default(200);
|
|
1238
1243
|
z.object({
|
|
1239
1244
|
since: z.string().max(64).optional(),
|
|
1240
|
-
limit:
|
|
1245
|
+
limit: agentEventLimitSchema
|
|
1241
1246
|
});
|
|
1247
|
+
z.object({
|
|
1248
|
+
before: z.string().max(64).optional(),
|
|
1249
|
+
limit: agentEventLimitSchema
|
|
1250
|
+
});
|
|
1251
|
+
pageSchema(agentEventSummarySchema).meta({ id: "LiveHistoryPage" });
|
|
1242
1252
|
const taskStatuses = [
|
|
1243
1253
|
"pending",
|
|
1244
1254
|
"in_progress",
|
|
@@ -1247,6 +1257,13 @@ const taskStatuses = [
|
|
|
1247
1257
|
"cancelled"
|
|
1248
1258
|
];
|
|
1249
1259
|
const taskStatusSchema = z.enum(taskStatuses);
|
|
1260
|
+
const finalTaskStatuses = [
|
|
1261
|
+
"done",
|
|
1262
|
+
"failed",
|
|
1263
|
+
"cancelled"
|
|
1264
|
+
];
|
|
1265
|
+
const finalTaskStatusSchema = z.enum(finalTaskStatuses);
|
|
1266
|
+
const taskDeletionKikimoraVersion = "0.14.0";
|
|
1250
1267
|
const maxTaskDescriptionLength = 4e3;
|
|
1251
1268
|
const agentTaskSchema = z.object({
|
|
1252
1269
|
id: z.string(),
|
|
@@ -1262,15 +1279,31 @@ const agentTaskSchema = z.object({
|
|
|
1262
1279
|
startedAt: z.iso.datetime().nullable(),
|
|
1263
1280
|
finishedAt: z.iso.datetime().nullable()
|
|
1264
1281
|
}).meta({ id: "AgentTask" });
|
|
1282
|
+
const agentTaskSourceSchema = z.enum(["worker", "projection"]);
|
|
1283
|
+
const agentTaskStaleReasonSchema = z.enum([
|
|
1284
|
+
"unreachable",
|
|
1285
|
+
"timeout",
|
|
1286
|
+
"stopped"
|
|
1287
|
+
]).nullable();
|
|
1288
|
+
const taskCountsSchema = z.object({
|
|
1289
|
+
pending: z.int().nonnegative(),
|
|
1290
|
+
in_progress: z.int().nonnegative(),
|
|
1291
|
+
done: z.int().nonnegative(),
|
|
1292
|
+
failed: z.int().nonnegative(),
|
|
1293
|
+
cancelled: z.int().nonnegative()
|
|
1294
|
+
}).meta({ id: "TaskCounts" });
|
|
1265
1295
|
z.object({
|
|
1266
1296
|
items: z.array(agentTaskSchema),
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
"stopped"
|
|
1272
|
-
]).nullable()
|
|
1297
|
+
nextCursor: z.string().nullable(),
|
|
1298
|
+
counts: taskCountsSchema.nullable(),
|
|
1299
|
+
source: agentTaskSourceSchema,
|
|
1300
|
+
staleReason: agentTaskStaleReasonSchema
|
|
1273
1301
|
}).meta({ id: "AgentTaskList" });
|
|
1302
|
+
z.object({
|
|
1303
|
+
task: agentTaskSchema,
|
|
1304
|
+
source: agentTaskSourceSchema,
|
|
1305
|
+
staleReason: agentTaskStaleReasonSchema
|
|
1306
|
+
}).meta({ id: "AgentTaskView" });
|
|
1274
1307
|
z.object({
|
|
1275
1308
|
title: z.string().trim().min(1).max(200).optional(),
|
|
1276
1309
|
description: z.string().trim().min(1).max(maxTaskDescriptionLength)
|
|
@@ -1279,7 +1312,9 @@ z.object({
|
|
|
1279
1312
|
state: z.enum(["requested", "running"]),
|
|
1280
1313
|
cycle: z.int().nonnegative().nullable()
|
|
1281
1314
|
}).meta({ id: "MonitorCheck" });
|
|
1282
|
-
|
|
1315
|
+
cursorQuerySchema.extend({ status: taskStatusSchema.optional() });
|
|
1316
|
+
z.object({ status: finalTaskStatusSchema });
|
|
1317
|
+
z.object({ deleted: z.array(z.string()) }).meta({ id: "AgentTasksDeleted" });
|
|
1283
1318
|
z.object({
|
|
1284
1319
|
id: idSchema,
|
|
1285
1320
|
taskId: z.string().min(1).max(128)
|
|
@@ -2030,6 +2065,7 @@ const auditActionSchema = z.enum([
|
|
|
2030
2065
|
"agent.action",
|
|
2031
2066
|
"agent.backup_requested",
|
|
2032
2067
|
"agent.restored",
|
|
2068
|
+
"agent.tasks_deleted",
|
|
2033
2069
|
"platform.settings_updated",
|
|
2034
2070
|
"runtime.sessions_updated",
|
|
2035
2071
|
"platform.upgrade_requested",
|
|
@@ -2687,6 +2723,7 @@ z.object({
|
|
|
2687
2723
|
//#endregion
|
|
2688
2724
|
//#region ../../packages/contracts/src/agent-backups.ts
|
|
2689
2725
|
const agentBackupTriggers = ["nightly", "manual"];
|
|
2726
|
+
const agentBackupUnavailableReasons = ["release_without_export"];
|
|
2690
2727
|
const agentBackupSchema = z.object({
|
|
2691
2728
|
id: idSchema,
|
|
2692
2729
|
agentId: idSchema,
|
|
@@ -2699,9 +2736,15 @@ const agentBackupSchema = z.object({
|
|
|
2699
2736
|
createdAt: z.iso.datetime(),
|
|
2700
2737
|
expiresAt: z.iso.datetime()
|
|
2701
2738
|
}).meta({ id: "AgentBackup" });
|
|
2739
|
+
const agentBackupUnavailableSchema = z.object({
|
|
2740
|
+
reason: z.enum(agentBackupUnavailableReasons),
|
|
2741
|
+
kikimoraVersion: z.string(),
|
|
2742
|
+
requiredVersion: z.string()
|
|
2743
|
+
}).meta({ id: "AgentBackupUnavailable" });
|
|
2702
2744
|
z.object({
|
|
2703
2745
|
items: z.array(agentBackupSchema),
|
|
2704
|
-
retentionDays: z.int().positive()
|
|
2746
|
+
retentionDays: z.int().positive(),
|
|
2747
|
+
unavailable: agentBackupUnavailableSchema.nullable()
|
|
2705
2748
|
}).meta({ id: "AgentBackupList" });
|
|
2706
2749
|
z.object({ state: z.literal("requested") }).meta({ id: "AgentBackupRequested" });
|
|
2707
2750
|
z.object({
|
|
@@ -2774,6 +2817,7 @@ const archiveSkipReasons = [
|
|
|
2774
2817
|
"special_file",
|
|
2775
2818
|
"unreadable"
|
|
2776
2819
|
];
|
|
2820
|
+
const omittedAgentReasons = ["remote_node", "unplaced"];
|
|
2777
2821
|
const maxBackupRetentionDays = 3650;
|
|
2778
2822
|
const maxPlatformSecretLength = 4096;
|
|
2779
2823
|
const maxHostOperationOutputLength = 4096;
|
|
@@ -2968,6 +3012,12 @@ const archivedAgentSchema = z.object({
|
|
|
2968
3012
|
message: "expected no more listed skipped files than skippedTotal",
|
|
2969
3013
|
path: ["skippedTotal"]
|
|
2970
3014
|
});
|
|
3015
|
+
const omittedAgentSchema = z.object({
|
|
3016
|
+
agentId: idSchema,
|
|
3017
|
+
slug: slugSchema,
|
|
3018
|
+
nodeId: idSchema.nullable(),
|
|
3019
|
+
reason: z.enum(omittedAgentReasons)
|
|
3020
|
+
});
|
|
2971
3021
|
z.object({
|
|
2972
3022
|
version: z.literal(1),
|
|
2973
3023
|
backupId: idSchema,
|
|
@@ -2980,7 +3030,8 @@ z.object({
|
|
|
2980
3030
|
cipher: z.literal(backupCipher),
|
|
2981
3031
|
parts: z.array(backupPartSchema).refine(everyPartOnce, { message: `expected exactly the parts ${backupPartNames.join(", ")}` }),
|
|
2982
3032
|
database: z.object({ pgVersion: z.string().min(1) }),
|
|
2983
|
-
agents: z.array(archivedAgentSchema)
|
|
3033
|
+
agents: z.array(archivedAgentSchema),
|
|
3034
|
+
omitted: z.array(omittedAgentSchema).default([])
|
|
2984
3035
|
});
|
|
2985
3036
|
const hostOperationSchema = z.object({
|
|
2986
3037
|
id: idSchema,
|
|
@@ -4247,7 +4298,9 @@ const restoredAgent = async (api, agentId, { backupId, name, node, slug }) => {
|
|
|
4247
4298
|
}), restoreHints);
|
|
4248
4299
|
};
|
|
4249
4300
|
const keptFor = (days) => `A backup is kept for ${String(days)} ${days === 1 ? "day" : "days"}.`;
|
|
4250
|
-
const
|
|
4301
|
+
const unavailableNote = ({ unavailable }) => unavailable?.reason === "release_without_export" ? [`Kikimora ${unavailable.kikimoraVersion} cannot export the memory of the agent, so its node backs nothing up. Backups need ${unavailable.requiredVersion} or newer: move the agent with kcloud agents set, then kcloud agents update.`] : [];
|
|
4302
|
+
const backupsTable = (list) => [...unavailableNote(list), backupListing(list)].join("\n");
|
|
4303
|
+
const backupListing = ({ items, retentionDays }) => items.length === 0 ? `The agent has no backup yet. ${keptFor(retentionDays)}` : [renderTable([
|
|
4251
4304
|
{ header: "CREATED" },
|
|
4252
4305
|
{ header: "TRIGGER" },
|
|
4253
4306
|
{ header: "NODE" },
|
|
@@ -5031,6 +5084,7 @@ const collect = async (page, { limit, all }) => {
|
|
|
5031
5084
|
cursor = next.nextCursor;
|
|
5032
5085
|
}
|
|
5033
5086
|
return {
|
|
5087
|
+
...first,
|
|
5034
5088
|
items,
|
|
5035
5089
|
nextCursor: null
|
|
5036
5090
|
};
|
|
@@ -5494,42 +5548,67 @@ const streamOptions = {
|
|
|
5494
5548
|
default: false
|
|
5495
5549
|
},
|
|
5496
5550
|
since: { type: "string" },
|
|
5551
|
+
before: { type: "string" },
|
|
5497
5552
|
limit: { type: "string" }
|
|
5498
5553
|
};
|
|
5499
5554
|
const streamUsage = [
|
|
5500
5555
|
...agentUsage,
|
|
5501
5556
|
["-f, --follow", "keep the stream open instead of leaving when the output stops"],
|
|
5502
5557
|
["--since <id>", "start after this event instead of at the start of the buffer"],
|
|
5503
|
-
["--limit <n>", "how many events to replay before the live ones"]
|
|
5558
|
+
["--limit <n>", "how many events to replay before the live ones, or the page size with --before"]
|
|
5504
5559
|
];
|
|
5505
|
-
const
|
|
5506
|
-
|
|
5507
|
-
if (
|
|
5560
|
+
const beforeUsage = ["--before <id>", "print the stored output before this event and leave, oldest first"];
|
|
5561
|
+
const linePrinter = (json) => (data) => {
|
|
5562
|
+
if (json) return JSON.stringify(data);
|
|
5563
|
+
const parsed = agentEventSummarySchema.safeParse(data);
|
|
5564
|
+
if (!parsed.success) return JSON.stringify(data);
|
|
5508
5565
|
const event = parsed.data;
|
|
5509
5566
|
const text = "text" in event.payload && typeof event.payload.text === "string" ? event.payload.text : JSON.stringify(event.payload);
|
|
5510
5567
|
return `${event.ts} ${event.level.padEnd(5)} ${event.agentRole ?? "-"} ${event.event} ${text}`;
|
|
5511
5568
|
};
|
|
5569
|
+
const earlierOutput = async (session, agentId, before, limit) => dataOf("read the earlier output of the agent", await session.api.GET("/agents/{id}/live/history", { params: {
|
|
5570
|
+
path: { id: agentId },
|
|
5571
|
+
query: {
|
|
5572
|
+
before,
|
|
5573
|
+
...limit === void 0 ? {} : { limit: Number(limit) }
|
|
5574
|
+
}
|
|
5575
|
+
} }), agentHints);
|
|
5576
|
+
const olderPageCommand = (reference, project, cursor, limit) => [
|
|
5577
|
+
"kcloud agents logs",
|
|
5578
|
+
reference,
|
|
5579
|
+
...project === void 0 ? [] : ["--project", project],
|
|
5580
|
+
"--before",
|
|
5581
|
+
cursor,
|
|
5582
|
+
...limit === void 0 ? [] : ["--limit", limit]
|
|
5583
|
+
].join(" ");
|
|
5512
5584
|
const streamCommands = (adaptersOf) => [{
|
|
5513
5585
|
name: "logs",
|
|
5514
5586
|
path: "/agents/{id}/live",
|
|
5515
5587
|
summary: "Print what the agent is writing, and keep printing with --follow.",
|
|
5516
|
-
resumable: false
|
|
5588
|
+
resumable: false,
|
|
5589
|
+
pagesBack: true
|
|
5517
5590
|
}, {
|
|
5518
5591
|
name: "events",
|
|
5519
5592
|
path: "/agents/{id}/events",
|
|
5520
5593
|
summary: "Print the stored events of the agent, and keep printing with --follow.",
|
|
5521
|
-
resumable: true
|
|
5522
|
-
|
|
5594
|
+
resumable: true,
|
|
5595
|
+
pagesBack: false
|
|
5596
|
+
}].map(({ name, path, summary, resumable, pagesBack }) => defineCommand({
|
|
5523
5597
|
name,
|
|
5524
5598
|
summary,
|
|
5525
|
-
usage: `agents ${name} <agent> [--project <name>] [--follow] [--since <id>] [--limit <n>]`,
|
|
5526
|
-
optionsUsage: streamUsage,
|
|
5599
|
+
usage: pagesBack ? `agents ${name} <agent> [--project <name>] [--follow] [--since <id>] [--before <id>] [--limit <n>]` : `agents ${name} <agent> [--project <name>] [--follow] [--since <id>] [--limit <n>]`,
|
|
5600
|
+
optionsUsage: pagesBack ? [...streamUsage, beforeUsage] : streamUsage,
|
|
5527
5601
|
options: streamOptions,
|
|
5528
5602
|
positionals: {
|
|
5529
5603
|
min: 1,
|
|
5530
5604
|
max: 1
|
|
5531
5605
|
},
|
|
5532
5606
|
run: async ({ values, positionals, settings, context }) => {
|
|
5607
|
+
const before = values.before;
|
|
5608
|
+
if (before !== void 0 && !pagesBack) throw new UsageError("--before reads the output of kcloud agents logs alone.");
|
|
5609
|
+
if (before !== void 0 && (values.follow || values.since !== void 0)) throw new UsageError("--before reads earlier output; leave out --follow and --since.");
|
|
5610
|
+
const limit = values.limit;
|
|
5611
|
+
if (limit !== void 0 && !/^[0-9]+$/u.test(limit)) throw new UsageError(`--limit ${limit} is not a whole number.`);
|
|
5533
5612
|
const adapters = adaptersOf(context);
|
|
5534
5613
|
const session = await openSession({
|
|
5535
5614
|
settings,
|
|
@@ -5538,8 +5617,17 @@ const streamCommands = (adaptersOf) => [{
|
|
|
5538
5617
|
});
|
|
5539
5618
|
const reference = positionals[0] ?? "";
|
|
5540
5619
|
const agentId = await resolveAgentId(session, reference, values.project);
|
|
5541
|
-
const
|
|
5542
|
-
if (
|
|
5620
|
+
const lineOf = linePrinter(settings.json);
|
|
5621
|
+
if (before !== void 0) {
|
|
5622
|
+
const page = await earlierOutput(session, agentId, before, limit);
|
|
5623
|
+
if (settings.json) {
|
|
5624
|
+
context.terminal.line(JSON.stringify(page));
|
|
5625
|
+
return exitCodes.ok;
|
|
5626
|
+
}
|
|
5627
|
+
for (const event of page.items) context.terminal.line(lineOf(event));
|
|
5628
|
+
context.terminal.error(context.terminal.errorStyles.dim(page.nextCursor === null ? "The stored output begins here." : `older: ${olderPageCommand(reference, values.project, page.nextCursor, limit)}`));
|
|
5629
|
+
return exitCodes.ok;
|
|
5630
|
+
}
|
|
5543
5631
|
await streamFrames({
|
|
5544
5632
|
origin: session.origin,
|
|
5545
5633
|
token: session.token,
|
|
@@ -5558,7 +5646,7 @@ const streamCommands = (adaptersOf) => [{
|
|
|
5558
5646
|
},
|
|
5559
5647
|
onFrame: (frame) => {
|
|
5560
5648
|
if (frame.event === "agent.state") return;
|
|
5561
|
-
context.terminal.line(
|
|
5649
|
+
context.terminal.line(lineOf(frame.data));
|
|
5562
5650
|
}
|
|
5563
5651
|
});
|
|
5564
5652
|
return exitCodes.ok;
|
|
@@ -5568,7 +5656,10 @@ const streamCommands = (adaptersOf) => [{
|
|
|
5568
5656
|
//#region src/commands/agents/tasks.ts
|
|
5569
5657
|
const taskHints = {
|
|
5570
5658
|
...agentHints,
|
|
5571
|
-
"runtime.control_unreachable": "The worker is not answering; kcloud agents show <agent> tells whether it runs."
|
|
5659
|
+
"runtime.control_unreachable": "The worker is not answering; kcloud agents show <agent> tells whether it runs.",
|
|
5660
|
+
"task.not_found": "kcloud agents tasks list <agent> shows the tasks of the agent.",
|
|
5661
|
+
"task.not_finished": "Only done, failed and cancelled tasks can be deleted; kcloud agents tasks cancel <agent> <task> cancels a pending one.",
|
|
5662
|
+
"runtime.task_deletion_unsupported": `Move the agent to Kikimora ${taskDeletionKikimoraVersion} or newer with kcloud agents set, then kcloud agents update.`
|
|
5572
5663
|
};
|
|
5573
5664
|
const tasksCommand = (adaptersOf) => defineGroup({
|
|
5574
5665
|
name: "tasks",
|
|
@@ -5578,11 +5669,21 @@ const tasksCommand = (adaptersOf) => defineGroup({
|
|
|
5578
5669
|
defineCommand({
|
|
5579
5670
|
name: "list",
|
|
5580
5671
|
summary: "List the tasks of an agent.",
|
|
5581
|
-
usage: "agents tasks list <agent> [--project <name>] [--status <status>]",
|
|
5582
|
-
optionsUsage: [
|
|
5672
|
+
usage: "agents tasks list <agent> [--project <name>] [--status <status>] [--limit <n>] [--all]",
|
|
5673
|
+
optionsUsage: [
|
|
5674
|
+
...agentUsage,
|
|
5675
|
+
["--status <status>", `one of ${taskStatuses.join(", ")}`],
|
|
5676
|
+
["--limit <n>", `how many tasks, newest first (default: 50)`],
|
|
5677
|
+
["--all", "follow the cursor to the end instead of one page"]
|
|
5678
|
+
],
|
|
5583
5679
|
options: {
|
|
5584
5680
|
...agentOption,
|
|
5585
|
-
status: { type: "string" }
|
|
5681
|
+
status: { type: "string" },
|
|
5682
|
+
limit: { type: "string" },
|
|
5683
|
+
all: {
|
|
5684
|
+
type: "boolean",
|
|
5685
|
+
default: false
|
|
5686
|
+
}
|
|
5586
5687
|
},
|
|
5587
5688
|
positionals: {
|
|
5588
5689
|
min: 1,
|
|
@@ -5594,10 +5695,14 @@ const tasksCommand = (adaptersOf) => defineGroup({
|
|
|
5594
5695
|
const given = invocation.values.status;
|
|
5595
5696
|
const status = taskStatuses.find((candidate) => candidate === given);
|
|
5596
5697
|
if (given !== void 0 && status === void 0) throw new UsageError(`--status ${given} is not a status of a task.`, `The statuses are ${taskStatuses.join(", ")}.`);
|
|
5597
|
-
const listed = dataOf("list the tasks of the agent", await run.api.GET("/agents/{id}/tasks", { params: {
|
|
5698
|
+
const listed = await collect(async (cursor, limit) => dataOf("list the tasks of the agent", await run.api.GET("/agents/{id}/tasks", { params: {
|
|
5598
5699
|
path: { id: agentId },
|
|
5599
|
-
|
|
5600
|
-
|
|
5700
|
+
query: {
|
|
5701
|
+
limit,
|
|
5702
|
+
...cursor === null ? {} : { cursor },
|
|
5703
|
+
...status === void 0 ? {} : { status }
|
|
5704
|
+
}
|
|
5705
|
+
} }), taskHints), windowOf(invocation.values.limit, invocation.values.all));
|
|
5601
5706
|
return printed(run, listed, (page) => page.items.length === 0 ? "The agent has no task in its queue." : renderTable([
|
|
5602
5707
|
{ header: "STATUS" },
|
|
5603
5708
|
{ header: "TITLE" },
|
|
@@ -5610,12 +5715,42 @@ const tasksCommand = (adaptersOf) => defineGroup({
|
|
|
5610
5715
|
], page.items.map((task) => [
|
|
5611
5716
|
task.status,
|
|
5612
5717
|
task.title,
|
|
5613
|
-
`${String(task.attempt)}/${String(task.maxAttempts)}`,
|
|
5718
|
+
task.attempt === null ? "-" : task.maxAttempts === null ? String(task.attempt) : `${String(task.attempt)}/${String(task.maxAttempts)}`,
|
|
5614
5719
|
task.costUsd === null ? "-" : task.costUsd.toFixed(2),
|
|
5615
5720
|
task.id
|
|
5616
5721
|
])));
|
|
5617
5722
|
}
|
|
5618
5723
|
}),
|
|
5724
|
+
defineCommand({
|
|
5725
|
+
name: "show",
|
|
5726
|
+
summary: "Show one task of an agent with its description and error.",
|
|
5727
|
+
usage: "agents tasks show <agent> <task> [--project <name>]",
|
|
5728
|
+
optionsUsage: agentUsage,
|
|
5729
|
+
options: agentOption,
|
|
5730
|
+
positionals: {
|
|
5731
|
+
min: 2,
|
|
5732
|
+
max: 2
|
|
5733
|
+
},
|
|
5734
|
+
run: async (invocation) => {
|
|
5735
|
+
const run = await runOf(adaptersOf, invocation);
|
|
5736
|
+
const agentId = await agentFrom(run, invocation.positionals[0], invocation.values.project);
|
|
5737
|
+
const taskId = invocation.positionals[1] ?? "";
|
|
5738
|
+
const view = dataOf("read the task", await run.api.GET("/agents/{id}/tasks/{taskId}", { params: { path: {
|
|
5739
|
+
id: agentId,
|
|
5740
|
+
taskId
|
|
5741
|
+
} } }), taskHints);
|
|
5742
|
+
return printed(run, view, ({ task }) => [
|
|
5743
|
+
`${task.title} (${task.id})`,
|
|
5744
|
+
`status ${task.status}`,
|
|
5745
|
+
`attempt ${task.attempt === null ? "-" : String(task.attempt)}${task.maxAttempts === null ? "" : `/${String(task.maxAttempts)}`}`,
|
|
5746
|
+
`created ${task.createdAt ?? "-"}`,
|
|
5747
|
+
`started ${task.startedAt ?? "-"}`,
|
|
5748
|
+
`finished ${task.finishedAt ?? "-"}`,
|
|
5749
|
+
...task.error === null ? [] : [`error ${task.error}`],
|
|
5750
|
+
...task.description === null ? [] : ["", task.description]
|
|
5751
|
+
].join("\n"));
|
|
5752
|
+
}
|
|
5753
|
+
}),
|
|
5619
5754
|
defineCommand({
|
|
5620
5755
|
name: "add",
|
|
5621
5756
|
summary: "Put a task in the queue of an agent.",
|
|
@@ -5695,9 +5830,50 @@ const tasksCommand = (adaptersOf) => defineGroup({
|
|
|
5695
5830
|
} } }), taskHints);
|
|
5696
5831
|
return said(run, `Cancelled the task ${taskId}.`);
|
|
5697
5832
|
}
|
|
5833
|
+
}),
|
|
5834
|
+
defineCommand({
|
|
5835
|
+
name: "delete",
|
|
5836
|
+
summary: "Delete a finished task, or every task of one final status.",
|
|
5837
|
+
usage: "agents tasks delete <agent> <task> [--project <name>] | agents tasks delete <agent> --status <status> [--project <name>]",
|
|
5838
|
+
optionsUsage: [...agentUsage, ["--status <status>", `one of ${finalTaskStatuses.join(", ")}`]],
|
|
5839
|
+
options: {
|
|
5840
|
+
...agentOption,
|
|
5841
|
+
status: { type: "string" }
|
|
5842
|
+
},
|
|
5843
|
+
positionals: {
|
|
5844
|
+
min: 1,
|
|
5845
|
+
max: 2
|
|
5846
|
+
},
|
|
5847
|
+
run: async (invocation) => {
|
|
5848
|
+
const taskId = invocation.positionals[1];
|
|
5849
|
+
const given = invocation.values.status;
|
|
5850
|
+
if (taskId === void 0 === (given === void 0)) throw new UsageError("agents tasks delete needs either a task or --status, not both.", "kcloud agents tasks delete <agent> <task> deletes one task.");
|
|
5851
|
+
const status = finalTaskStatuses.find((candidate) => candidate === given);
|
|
5852
|
+
if (given !== void 0 && status === void 0) throw new UsageError(`--status ${given} is not a final status of a task.`, `Only ${finalTaskStatuses.join(", ")} tasks can be deleted.`);
|
|
5853
|
+
const run = await runOf(adaptersOf, invocation);
|
|
5854
|
+
const agentId = await agentFrom(run, invocation.positionals[0], invocation.values.project);
|
|
5855
|
+
await confirmed({
|
|
5856
|
+
prompt: run.prompt,
|
|
5857
|
+
settings: run.settings,
|
|
5858
|
+
question: status === void 0 ? `Delete the task ${taskId ?? ""}?` : `Delete every ${status} task of the agent?${status === "done" ? " The monitor may report them again." : ""}`
|
|
5859
|
+
});
|
|
5860
|
+
const answer = dataOf("delete the tasks", status === void 0 ? await run.api.DELETE("/agents/{id}/tasks/{taskId}", { params: { path: {
|
|
5861
|
+
id: agentId,
|
|
5862
|
+
taskId: taskId ?? ""
|
|
5863
|
+
} } }) : await run.api.DELETE("/agents/{id}/tasks", { params: {
|
|
5864
|
+
path: { id: agentId },
|
|
5865
|
+
query: { status }
|
|
5866
|
+
} }), taskHints);
|
|
5867
|
+
return printed(run, answer, ({ deleted }) => deletedSummary(deleted.length, status ?? null, taskId ?? null));
|
|
5868
|
+
}
|
|
5698
5869
|
})
|
|
5699
5870
|
]
|
|
5700
5871
|
});
|
|
5872
|
+
const deletedSummary = (count, status, taskId) => {
|
|
5873
|
+
if (status === null) return `Deleted the task ${taskId ?? ""}.`;
|
|
5874
|
+
if (count === 0) return `The agent has no ${status} task.`;
|
|
5875
|
+
return `Deleted ${String(count)} ${status} ${count === 1 ? "task" : "tasks"}.`;
|
|
5876
|
+
};
|
|
5701
5877
|
const descriptionOf = async (run, given) => {
|
|
5702
5878
|
if (given === "-") {
|
|
5703
5879
|
const chunks = [];
|
|
@@ -6783,7 +6959,7 @@ const agentBackupTools = [
|
|
|
6783
6959
|
defineTool({
|
|
6784
6960
|
name: "agent_backups_list",
|
|
6785
6961
|
title: "List the backups of an agent",
|
|
6786
|
-
description: "List the backups of the memory of an agent, the newest first, with their trigger, node, Kikimora release, entries, size and expiry,
|
|
6962
|
+
description: "List the backups of the memory of an agent, the newest first, with their trigger, node, Kikimora release, entries, size and expiry, the days a backup is kept, and in unavailable why the node makes none, such as a Kikimora release that exports no memory.",
|
|
6787
6963
|
operations: ["listAgentBackups"],
|
|
6788
6964
|
safety: "read",
|
|
6789
6965
|
input: z.object(agentFields),
|
|
@@ -7203,6 +7379,25 @@ const observabilityTools = [
|
|
|
7203
7379
|
}
|
|
7204
7380
|
} }), agentHints)
|
|
7205
7381
|
}),
|
|
7382
|
+
defineTool({
|
|
7383
|
+
name: "agent_earlier_output",
|
|
7384
|
+
title: "Read the earlier output of an agent",
|
|
7385
|
+
description: "Read what an agent wrote before an event, oldest first: the newest page without before. Pass nextCursor as before to read the page before that; null means the stored output begins here.",
|
|
7386
|
+
operations: ["listAgentLiveHistory"],
|
|
7387
|
+
safety: "read",
|
|
7388
|
+
input: z.object({
|
|
7389
|
+
...agentFields,
|
|
7390
|
+
before: z.string().trim().min(1).max(64).optional().describe("End the page before this event id."),
|
|
7391
|
+
limit: z.int().min(1).max(500).optional().describe("How many events to read.")
|
|
7392
|
+
}),
|
|
7393
|
+
run: async ({ before, limit, ...reference }, run) => dataOf("read the earlier output of the agent", await run.api.GET("/agents/{id}/live/history", { params: {
|
|
7394
|
+
path: { id: await agentIdOf(run, reference) },
|
|
7395
|
+
query: {
|
|
7396
|
+
...before === void 0 ? {} : { before },
|
|
7397
|
+
...limit === void 0 ? {} : { limit }
|
|
7398
|
+
}
|
|
7399
|
+
} }), agentHints)
|
|
7400
|
+
}),
|
|
7206
7401
|
defineTool({
|
|
7207
7402
|
name: "agent_events",
|
|
7208
7403
|
title: "Read the events of an agent",
|
|
@@ -8902,17 +9097,40 @@ const taskTools = [
|
|
|
8902
9097
|
defineTool({
|
|
8903
9098
|
name: "agent_tasks_list",
|
|
8904
9099
|
title: "List the tasks of an agent",
|
|
8905
|
-
description: "List the task queue of an agent, with the status, attempts and cost of each task.",
|
|
9100
|
+
description: "List the task queue of an agent, newest first, with the status, attempts and cost of each task.",
|
|
8906
9101
|
operations: ["listAgentTasks"],
|
|
8907
9102
|
safety: "read",
|
|
8908
9103
|
input: z.object({
|
|
8909
9104
|
...agentFields,
|
|
9105
|
+
...pageFields,
|
|
8910
9106
|
status: z.enum(taskStatuses).optional()
|
|
8911
9107
|
}),
|
|
8912
|
-
run: async ({ status, ...reference }, run) =>
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
9108
|
+
run: async ({ status, limit, all, ...reference }, run) => {
|
|
9109
|
+
const agentId = await agentIdOf(run, reference);
|
|
9110
|
+
return collect(async (cursor, size) => dataOf("list the tasks of the agent", await run.api.GET("/agents/{id}/tasks", { params: {
|
|
9111
|
+
path: { id: agentId },
|
|
9112
|
+
query: {
|
|
9113
|
+
limit: size,
|
|
9114
|
+
...cursor === null ? {} : { cursor },
|
|
9115
|
+
...status === void 0 ? {} : { status }
|
|
9116
|
+
}
|
|
9117
|
+
} }), taskHints), windowOfPage({
|
|
9118
|
+
limit,
|
|
9119
|
+
all
|
|
9120
|
+
}));
|
|
9121
|
+
}
|
|
9122
|
+
}),
|
|
9123
|
+
defineTool({
|
|
9124
|
+
name: "agent_task_show",
|
|
9125
|
+
title: "Show a task",
|
|
9126
|
+
description: "Read one task of an agent with its description, status, attempts, cost and error.",
|
|
9127
|
+
operations: ["getAgentTask"],
|
|
9128
|
+
safety: "read",
|
|
9129
|
+
input: z.object(taskFields),
|
|
9130
|
+
run: async ({ task, ...reference }, run) => dataOf("read the task", await run.api.GET("/agents/{id}/tasks/{taskId}", { params: { path: {
|
|
9131
|
+
id: await agentIdOf(run, reference),
|
|
9132
|
+
taskId: task
|
|
9133
|
+
} } }), taskHints)
|
|
8916
9134
|
}),
|
|
8917
9135
|
defineTool({
|
|
8918
9136
|
name: "agent_task_add",
|
|
@@ -8962,6 +9180,33 @@ const taskTools = [
|
|
|
8962
9180
|
} } }), taskHints);
|
|
8963
9181
|
return { cancelled: task };
|
|
8964
9182
|
}
|
|
9183
|
+
}),
|
|
9184
|
+
defineTool({
|
|
9185
|
+
name: "agent_task_delete",
|
|
9186
|
+
title: "Delete a task",
|
|
9187
|
+
description: "Delete a done, failed or cancelled task of an agent. A monitor may report a deleted done task again.",
|
|
9188
|
+
operations: ["deleteAgentTask"],
|
|
9189
|
+
safety: "destructive",
|
|
9190
|
+
input: z.object(taskFields),
|
|
9191
|
+
run: async ({ task, ...reference }, run) => dataOf("delete the task", await run.api.DELETE("/agents/{id}/tasks/{taskId}", { params: { path: {
|
|
9192
|
+
id: await agentIdOf(run, reference),
|
|
9193
|
+
taskId: task
|
|
9194
|
+
} } }), taskHints)
|
|
9195
|
+
}),
|
|
9196
|
+
defineTool({
|
|
9197
|
+
name: "agent_tasks_delete",
|
|
9198
|
+
title: "Delete the tasks of a status",
|
|
9199
|
+
description: "Delete every task of an agent with one final status: done, failed or cancelled. A monitor may report a deleted done task again.",
|
|
9200
|
+
operations: ["deleteAgentTasks"],
|
|
9201
|
+
safety: "destructive",
|
|
9202
|
+
input: z.object({
|
|
9203
|
+
...agentFields,
|
|
9204
|
+
status: z.enum(finalTaskStatuses)
|
|
9205
|
+
}),
|
|
9206
|
+
run: async ({ status, ...reference }, run) => dataOf("delete the tasks", await run.api.DELETE("/agents/{id}/tasks", { params: {
|
|
9207
|
+
path: { id: await agentIdOf(run, reference) },
|
|
9208
|
+
query: { status }
|
|
9209
|
+
} }), taskHints)
|
|
8965
9210
|
})
|
|
8966
9211
|
];
|
|
8967
9212
|
//#endregion
|