@desplega.ai/agent-swarm 1.90.0 → 1.92.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 +2 -1
- package/openapi.json +803 -150
- package/package.json +5 -5
- package/src/artifact-sdk/server.ts +2 -1
- package/src/be/db.ts +337 -1
- package/src/be/memory/providers/sqlite-store.ts +6 -1
- package/src/be/memory/types.ts +1 -0
- package/src/be/migrations/083_script_workflows.sql +51 -0
- package/src/be/modelsdev-cache.json +42352 -38595
- package/src/be/scripts/typecheck.ts +181 -1
- package/src/be/seed-scripts/catalog/compound-insights.ts +398 -0
- package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +911 -0
- package/src/be/seed-scripts/catalog/schedule-health.ts +73 -0
- package/src/be/seed-scripts/catalog/smart-recall.ts +65 -0
- package/src/be/seed-scripts/catalog/task-context-gathering.ts +92 -0
- package/src/be/seed-scripts/catalog/tool-usage.ts +59 -0
- package/src/be/seed-scripts/index.ts +54 -0
- package/src/be/seed-skills/index.ts +7 -0
- package/src/be/swarm-config-guard.ts +17 -0
- package/src/commands/artifact.ts +3 -2
- package/src/commands/profile-sync.ts +310 -0
- package/src/commands/runner.ts +134 -3
- package/src/hooks/hook.ts +32 -9
- package/src/http/db-query.ts +20 -5
- package/src/http/index.ts +57 -0
- package/src/http/integrations.ts +6 -1
- package/src/http/mcp-bridge.ts +117 -0
- package/src/http/mcp-oauth.ts +97 -39
- package/src/http/memory.ts +5 -2
- package/src/http/openapi.ts +2 -2
- package/src/http/pages-public.ts +10 -11
- package/src/http/pages.ts +7 -11
- package/src/http/script-runs.ts +555 -0
- package/src/http/scripts.ts +24 -1
- package/src/http/utils.ts +11 -4
- package/src/jira/app.ts +2 -3
- package/src/jira/webhook-lifecycle.ts +2 -1
- package/src/linear/app.ts +2 -3
- package/src/prompts/session-templates.ts +24 -4
- package/src/providers/claude-adapter.ts +86 -13
- package/src/script-workflows/executor.ts +110 -0
- package/src/script-workflows/harness.ts +73 -0
- package/src/script-workflows/label-lint.ts +51 -0
- package/src/script-workflows/limits.ts +22 -0
- package/src/script-workflows/supervisor.ts +139 -0
- package/src/script-workflows/workflow-ctx.ts +205 -0
- package/src/scripts-runtime/executors/native.ts +1 -0
- package/src/scripts-runtime/sdk-allowlist.ts +124 -0
- package/src/scripts-runtime/swarm-sdk.ts +198 -3
- package/src/scripts-runtime/types/stdlib.d.ts +287 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +287 -0
- package/src/server.ts +2 -0
- package/src/slack/handlers.ts +11 -4
- package/src/slack/message-text.ts +98 -0
- package/src/slack/thread-buffer.ts +5 -3
- package/src/tests/claude-adapter-binary.test.ts +147 -4
- package/src/tests/claude-adapter-otel.test.ts +85 -1
- package/src/tests/db-query.test.ts +28 -0
- package/src/tests/error-tracker.test.ts +121 -0
- package/src/tests/harness-provider-resolution.test.ts +33 -0
- package/src/tests/hook-registration-nudge.test.ts +69 -0
- package/src/tests/mcp-oauth-manual-client.test.ts +213 -0
- package/src/tests/mcp-tools.test.ts +6 -0
- package/src/tests/pages-public-html.test.ts +41 -0
- package/src/tests/pages-public-json-redirect.test.ts +37 -2
- package/src/tests/profile-sync.test.ts +282 -0
- package/src/tests/prompt-template-session.test.ts +34 -5
- package/src/tests/script-runs-http.test.ts +278 -0
- package/src/tests/script-workflows-label-lint.test.ts +43 -0
- package/src/tests/script-workflows-runtime-e2e.test.ts +170 -0
- package/src/tests/scripts-mcp-e2e.test.ts +49 -2
- package/src/tests/scripts-runtime.test.ts +33 -0
- package/src/tests/seed-scripts.test.ts +347 -2
- package/src/tests/slack-message-text.test.ts +250 -0
- package/src/tests/system-default-skills.test.ts +40 -0
- package/src/tools/create-metric.ts +2 -3
- package/src/tools/create-page.ts +3 -6
- package/src/tools/db-query.ts +16 -6
- package/src/tools/memory-rate.ts +2 -1
- package/src/tools/memory-search.ts +1 -0
- package/src/tools/register-kapso-number.ts +2 -4
- package/src/tools/request-human-input.ts +2 -1
- package/src/tools/script-common.ts +2 -4
- package/src/tools/script-run.ts +7 -0
- package/src/tools/script-runs.ts +123 -0
- package/src/tools/slack-read.ts +12 -3
- package/src/tools/tool-config.ts +4 -1
- package/src/types.ts +52 -0
- package/src/utils/constants.ts +58 -8
- package/src/utils/error-tracker.ts +40 -1
- package/src/utils/internal-ai/complete-structured.ts +10 -4
- package/src/workflows/executors/raw-llm.ts +76 -59
- package/templates/skills/pages/content.md +205 -55
- package/templates/skills/script-workflows/config.json +14 -0
- package/templates/skills/script-workflows/content.md +68 -0
- package/templates/skills/swarm-scripts/content.md +45 -7
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const argsSchema = z.object({
|
|
4
|
+
days: z
|
|
5
|
+
.number()
|
|
6
|
+
.int()
|
|
7
|
+
.positive()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Look back this many days (default 7)"),
|
|
10
|
+
failureThreshold: z
|
|
11
|
+
.number()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Flag schedules with failure rate above this (0-1, default 0.2)"),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
/** Per-schedule health check: failure rates and flagging unhealthy schedules. */
|
|
17
|
+
export default async function scheduleHealth(args: any, ctx: any) {
|
|
18
|
+
const parsed = argsSchema.safeParse(args);
|
|
19
|
+
if (!parsed.success) return { error: "invalid args: " + parsed.error.message };
|
|
20
|
+
const days = parsed.data.days || 7;
|
|
21
|
+
const threshold = parsed.data.failureThreshold ?? 0.2;
|
|
22
|
+
const since = new Date(Date.now() - days * 86400000).toISOString();
|
|
23
|
+
|
|
24
|
+
// Get schedules
|
|
25
|
+
const schedRes: any = await ctx.swarm.schedule_list({});
|
|
26
|
+
const schedPayload = schedRes?.data ?? schedRes;
|
|
27
|
+
const schedules: any[] = schedPayload?.schedules ?? [];
|
|
28
|
+
|
|
29
|
+
if (!schedules.length) return { days, schedules: [], flagged: [] };
|
|
30
|
+
|
|
31
|
+
// Get recent tasks to correlate with schedules
|
|
32
|
+
const taskRes: any = await ctx.swarm.task_list({ createdAfter: since, limit: 2000 });
|
|
33
|
+
const taskPayload = taskRes?.data ?? taskRes;
|
|
34
|
+
const tasks: any[] = taskPayload?.tasks ?? [];
|
|
35
|
+
|
|
36
|
+
// Group by scheduleId
|
|
37
|
+
const bySchedule = new Map<string, { total: number; failed: number; completed: number }>();
|
|
38
|
+
for (const t of tasks) {
|
|
39
|
+
if (!t.scheduleId) continue;
|
|
40
|
+
const entry = bySchedule.get(t.scheduleId) ?? { total: 0, failed: 0, completed: 0 };
|
|
41
|
+
entry.total++;
|
|
42
|
+
if (t.status === "failed") entry.failed++;
|
|
43
|
+
if (t.status === "completed") entry.completed++;
|
|
44
|
+
bySchedule.set(t.scheduleId, entry);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const results = schedules.map((s: any) => {
|
|
48
|
+
const stats = bySchedule.get(s.id) ?? { total: 0, failed: 0, completed: 0 };
|
|
49
|
+
const failureRate = stats.total > 0 ? stats.failed / stats.total : 0;
|
|
50
|
+
return {
|
|
51
|
+
id: s.id,
|
|
52
|
+
name: s.name,
|
|
53
|
+
enabled: s.enabled,
|
|
54
|
+
targetAgentId: s.targetAgentId,
|
|
55
|
+
runs: stats.total,
|
|
56
|
+
failed: stats.failed,
|
|
57
|
+
completed: stats.completed,
|
|
58
|
+
failureRate: Math.round(failureRate * 1000) / 1000,
|
|
59
|
+
flagged: stats.total >= 3 && failureRate > threshold,
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const flagged = results.filter((r: any) => r.flagged);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
days,
|
|
67
|
+
threshold,
|
|
68
|
+
totalSchedules: schedules.length,
|
|
69
|
+
flaggedCount: flagged.length,
|
|
70
|
+
schedules: results.sort((a: any, b: any) => b.failureRate - a.failureRate),
|
|
71
|
+
flagged,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const argsSchema = z.object({
|
|
4
|
+
queries: z
|
|
5
|
+
.array(z.string())
|
|
6
|
+
.min(1)
|
|
7
|
+
.describe("One or more search queries to fan out against the memory store"),
|
|
8
|
+
scope: z
|
|
9
|
+
.enum(["all", "agent", "swarm"])
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Memory scope filter (default all)"),
|
|
12
|
+
limit: z
|
|
13
|
+
.number()
|
|
14
|
+
.int()
|
|
15
|
+
.positive()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Max results per query (default 10)"),
|
|
18
|
+
dedupThreshold: z
|
|
19
|
+
.number()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Similarity threshold for dedup — memories above this are merged (default 0.92)"),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/** Multi-query fan-out memory recall with dedup and composite reranking. */
|
|
25
|
+
export default async function smartRecall(args: any, ctx: any) {
|
|
26
|
+
const parsed = argsSchema.safeParse(args);
|
|
27
|
+
if (!parsed.success) return { error: "invalid args: " + parsed.error.message };
|
|
28
|
+
const { queries, scope = "all", limit = 10, dedupThreshold = 0.92 } = parsed.data;
|
|
29
|
+
|
|
30
|
+
const allResults: any[] = [];
|
|
31
|
+
for (const q of queries) {
|
|
32
|
+
const res: any = await ctx.swarm.memory_search({ query: q, limit, scope });
|
|
33
|
+
const payload = res?.data ?? res;
|
|
34
|
+
const results = payload?.results ?? [];
|
|
35
|
+
for (const r of results) {
|
|
36
|
+
allResults.push({ ...r, querySource: q });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Dedup by ID, keeping best similarity per memory
|
|
41
|
+
const seen = new Map<string, any>();
|
|
42
|
+
const hitCounts = new Map<string, number>();
|
|
43
|
+
for (const r of allResults) {
|
|
44
|
+
hitCounts.set(r.id, (hitCounts.get(r.id) ?? 0) + 1);
|
|
45
|
+
const existing = seen.get(r.id);
|
|
46
|
+
if (!existing || r.similarity > existing.similarity) {
|
|
47
|
+
seen.set(r.id, r);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Composite rerank: bestSimilarity + 0.05 * hitCount
|
|
52
|
+
const deduped = Array.from(seen.values()).map((r) => ({
|
|
53
|
+
...r,
|
|
54
|
+
hits: hitCounts.get(r.id) ?? 1,
|
|
55
|
+
compositeScore: r.similarity + 0.05 * (hitCounts.get(r.id) ?? 1),
|
|
56
|
+
}));
|
|
57
|
+
deduped.sort((a: any, b: any) => b.compositeScore - a.compositeScore);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
queriesRun: queries.length,
|
|
61
|
+
totalCandidates: allResults.length,
|
|
62
|
+
uniqueMemories: deduped.length,
|
|
63
|
+
memories: deduped.slice(0, limit * 2),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const argsSchema = z.object({
|
|
4
|
+
taskId: z.string().describe("Task ID to fetch details for"),
|
|
5
|
+
queries: z
|
|
6
|
+
.array(z.string())
|
|
7
|
+
.min(1)
|
|
8
|
+
.describe("Search queries from the task description — 2-4 recommended"),
|
|
9
|
+
scope: z
|
|
10
|
+
.enum(["all", "agent", "swarm"])
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Memory scope filter (default all)"),
|
|
13
|
+
memoryLimit: z
|
|
14
|
+
.number()
|
|
15
|
+
.int()
|
|
16
|
+
.positive()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Max memories per query before dedup (default 8)"),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
function slimTask(task: any) {
|
|
22
|
+
if (!task || typeof task !== "object") return null;
|
|
23
|
+
return {
|
|
24
|
+
id: task.id,
|
|
25
|
+
status: task.status,
|
|
26
|
+
description: task.task,
|
|
27
|
+
dependsOn: task.dependsOn,
|
|
28
|
+
slackChannelId: task.slackChannelId,
|
|
29
|
+
slackThreadTs: task.slackThreadTs,
|
|
30
|
+
createdAt: task.createdAt,
|
|
31
|
+
finishedAt: task.finishedAt,
|
|
32
|
+
agentId: task.agentId,
|
|
33
|
+
output: task.output,
|
|
34
|
+
failureReason: task.failureReason,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Fetch slim task details plus deduped multi-query memories for task onboarding. */
|
|
39
|
+
export default async function taskContextGathering(args: any, ctx: any) {
|
|
40
|
+
const parsed = argsSchema.safeParse(args);
|
|
41
|
+
if (!parsed.success) return { error: "invalid args: " + parsed.error.message };
|
|
42
|
+
const { taskId, queries, scope = "all", memoryLimit = 8 } = parsed.data;
|
|
43
|
+
|
|
44
|
+
const taskRes: any = await ctx.swarm.task_get({ taskId });
|
|
45
|
+
const taskPayload = taskRes?.data ?? taskRes;
|
|
46
|
+
if (taskPayload?.success === false) {
|
|
47
|
+
return { error: taskPayload.message ?? "task_get failed", taskId };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const allResults: any[] = [];
|
|
51
|
+
for (const query of queries) {
|
|
52
|
+
const res: any = await ctx.swarm.memory_search({ query, scope, limit: memoryLimit });
|
|
53
|
+
const payload = res?.data ?? res;
|
|
54
|
+
const results = payload?.results ?? [];
|
|
55
|
+
for (const memory of results) {
|
|
56
|
+
allResults.push({ ...memory, querySource: query });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const byId = new Map<string, any>();
|
|
61
|
+
const hitCounts = new Map<string, number>();
|
|
62
|
+
for (const memory of allResults) {
|
|
63
|
+
const id = typeof memory.id === "string" ? memory.id : JSON.stringify(memory);
|
|
64
|
+
hitCounts.set(id, (hitCounts.get(id) ?? 0) + 1);
|
|
65
|
+
const existing = byId.get(id);
|
|
66
|
+
const similarity = typeof memory.similarity === "number" ? memory.similarity : 0;
|
|
67
|
+
const existingSimilarity =
|
|
68
|
+
existing && typeof existing.similarity === "number" ? existing.similarity : -Infinity;
|
|
69
|
+
if (!existing || similarity > existingSimilarity) byId.set(id, memory);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const memories = Array.from(byId.entries()).map(([id, memory]) => {
|
|
73
|
+
const hits = hitCounts.get(id) ?? 1;
|
|
74
|
+
const similarity = typeof memory.similarity === "number" ? memory.similarity : 0;
|
|
75
|
+
return {
|
|
76
|
+
...memory,
|
|
77
|
+
hits,
|
|
78
|
+
compositeScore: similarity + 0.05 * hits,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
memories.sort((a: any, b: any) => b.compositeScore - a.compositeScore);
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
task: slimTask(taskPayload?.task),
|
|
85
|
+
requestedBy: taskPayload?.requestedBy,
|
|
86
|
+
attachments: taskPayload?.attachments ?? [],
|
|
87
|
+
queriesRun: queries.length,
|
|
88
|
+
totalCandidates: allResults.length,
|
|
89
|
+
uniqueMemories: memories.length,
|
|
90
|
+
memories: memories.slice(0, memoryLimit * 2),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const argsSchema = z.object({
|
|
4
|
+
days: z
|
|
5
|
+
.number()
|
|
6
|
+
.int()
|
|
7
|
+
.positive()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Look back this many days (default 7)"),
|
|
10
|
+
agentId: z.string().optional().describe("Filter by agent ID (default: all agents)"),
|
|
11
|
+
limit: z
|
|
12
|
+
.number()
|
|
13
|
+
.int()
|
|
14
|
+
.positive()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Top N tools to return (default 20)"),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
/** Tool usage histogram from session_logs — top tools by call count. */
|
|
20
|
+
export default async function toolUsage(args: any, ctx: any) {
|
|
21
|
+
const parsed = argsSchema.safeParse(args);
|
|
22
|
+
if (!parsed.success) return { error: "invalid args: " + parsed.error.message };
|
|
23
|
+
const days = parsed.data.days || 7;
|
|
24
|
+
const limit = parsed.data.limit || 20;
|
|
25
|
+
const agentId = parsed.data.agentId;
|
|
26
|
+
|
|
27
|
+
const agentFilter = agentId ? `AND agent_id = '${agentId}'` : "";
|
|
28
|
+
const sql = `
|
|
29
|
+
SELECT tool_name, count(*) as calls
|
|
30
|
+
FROM session_logs
|
|
31
|
+
WHERE tool_name IS NOT NULL
|
|
32
|
+
AND created_at > datetime('now', '-${days} days')
|
|
33
|
+
${agentFilter}
|
|
34
|
+
GROUP BY tool_name
|
|
35
|
+
ORDER BY calls DESC
|
|
36
|
+
LIMIT ${limit}
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const res: any = await ctx.swarm.db_query({ sql });
|
|
40
|
+
const payload = res?.data ?? res;
|
|
41
|
+
const columns: string[] = payload?.columns ?? [];
|
|
42
|
+
const rows: any[] = (payload?.rows ?? []).map((row: any[]) =>
|
|
43
|
+
Object.fromEntries(columns.map((column, index) => [column, row[index]])),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const totalCalls = rows.reduce((sum: number, r: any) => sum + (r.calls ?? 0), 0);
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
days,
|
|
50
|
+
agentId: agentId ?? "all",
|
|
51
|
+
totalDistinctTools: rows.length,
|
|
52
|
+
totalCalls,
|
|
53
|
+
tools: rows.map((r: any) => ({
|
|
54
|
+
tool: r.tool_name,
|
|
55
|
+
calls: r.calls,
|
|
56
|
+
pct: totalCalls > 0 ? Math.round((r.calls / totalCalls) * 1000) / 10 : 0,
|
|
57
|
+
})),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -22,6 +22,7 @@ import { getScript, upsertScriptByName } from "../scripts/db";
|
|
|
22
22
|
import { extractArgsJsonSchema } from "../scripts/extract-schema";
|
|
23
23
|
import { typecheckScript } from "../scripts/typecheck";
|
|
24
24
|
import type { Seeder, SeedItem } from "../seed/types";
|
|
25
|
+
import compoundInsightsSrc from "./catalog/compound-insights.ts" with { type: "text" };
|
|
25
26
|
import dateResolveSrc from "./catalog/date-resolve.ts" with { type: "text" };
|
|
26
27
|
import fetchReadableSrc from "./catalog/fetch-readable.ts" with { type: "text" };
|
|
27
28
|
import ghPrSnapshotSrc from "./catalog/gh-pr-snapshot.ts" with { type: "text" };
|
|
@@ -29,9 +30,14 @@ import groupCountSrc from "./catalog/group-count.ts" with { type: "text" };
|
|
|
29
30
|
import jsonQuerySrc from "./catalog/json-query.ts" with { type: "text" };
|
|
30
31
|
import linearIssueSrc from "./catalog/linear-issue.ts" with { type: "text" };
|
|
31
32
|
import memoryDedupCheckSrc from "./catalog/memory-dedup-check.ts" with { type: "text" };
|
|
33
|
+
import opsCatalogAuditSrc from "./catalog/ops-catalog-audit.ts" with { type: "text" };
|
|
34
|
+
import scheduleHealthSrc from "./catalog/schedule-health.ts" with { type: "text" };
|
|
32
35
|
import slackThreadFlattenSrc from "./catalog/slack-thread-flatten.ts" with { type: "text" };
|
|
36
|
+
import smartRecallSrc from "./catalog/smart-recall.ts" with { type: "text" };
|
|
37
|
+
import taskContextGatheringSrc from "./catalog/task-context-gathering.ts" with { type: "text" };
|
|
33
38
|
import taskFailureAuditSrc from "./catalog/task-failure-audit.ts" with { type: "text" };
|
|
34
39
|
import textDiffSrc from "./catalog/text-diff.ts" with { type: "text" };
|
|
40
|
+
import toolUsageSrc from "./catalog/tool-usage.ts" with { type: "text" };
|
|
35
41
|
|
|
36
42
|
export type SeedScript = {
|
|
37
43
|
name: string;
|
|
@@ -122,6 +128,54 @@ export const SEED_SCRIPTS: SeedScript[] = [
|
|
|
122
128
|
intent: "Turn a Slack thread into plain text for summarizing or as task context.",
|
|
123
129
|
source: asText(slackThreadFlattenSrc),
|
|
124
130
|
},
|
|
131
|
+
{
|
|
132
|
+
name: "smart-recall",
|
|
133
|
+
description:
|
|
134
|
+
"Multi-query fan-out memory search with dedup and composite reranking (bestSimilarity + 0.05 * hitCount). Returns unique memories across all queries.",
|
|
135
|
+
intent:
|
|
136
|
+
"Recall relevant memories using multiple search angles — better coverage than a single query. Use for task onboarding, context gathering, or before writing new memories.",
|
|
137
|
+
source: asText(smartRecallSrc),
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "task-context-gathering",
|
|
141
|
+
description:
|
|
142
|
+
"Get task details and recall relevant memories in one call — returns a slimmed task projection plus deduped and reranked memories from multi-query fan-out.",
|
|
143
|
+
intent:
|
|
144
|
+
"Task onboarding: one call instead of task_get plus multiple memory_search calls. Pass the task description split into 2-4 natural-language queries.",
|
|
145
|
+
source: asText(taskContextGatheringSrc),
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: "schedule-health",
|
|
149
|
+
description:
|
|
150
|
+
"Per-schedule failure rate check over recent tasks — flags schedules with failure rates above a configurable threshold.",
|
|
151
|
+
intent:
|
|
152
|
+
"Find unhealthy schedules that keep failing — for daily compounding, reliability reviews, or ops triage.",
|
|
153
|
+
source: asText(scheduleHealthSrc),
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "tool-usage",
|
|
157
|
+
description:
|
|
158
|
+
"Tool usage histogram from session_logs — top tools by call count over a time window, optionally filtered by agent.",
|
|
159
|
+
intent:
|
|
160
|
+
"See which MCP tools agents use most — for SDK gap analysis, optimization, or daily ops snapshots.",
|
|
161
|
+
source: asText(toolUsageSrc),
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "compound-insights",
|
|
165
|
+
description:
|
|
166
|
+
"All-in-one swarm-wide daily ops snapshot: task completion/failure summary, real failure clusters (excludes superseded/cancelled bookkeeping), schedule health flags, tool usage top-25, memory health/pollution stats, seed-script candidate tool triplets, and a per-agent breakdown. Aggregates across ALL agents via direct read-only SQL.",
|
|
167
|
+
intent:
|
|
168
|
+
"Single-call daily compounding Phase 0 helper — replaces ~25 raw tool roundtrips with one compressed JSON result covering every agent. For daily evolution, self-scripting candidates, ops reviews, or heartbeat context.",
|
|
169
|
+
source: asText(compoundInsightsSrc),
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: "ops-catalog-audit",
|
|
173
|
+
description:
|
|
174
|
+
"Audit-as-code catalog check for schedules, workflows, and prompt/template drift. Clusters actionable findings by goal and can publish an authed HTML report page.",
|
|
175
|
+
intent:
|
|
176
|
+
"Re-run the ops inventory audit in one call: duplicate/dead schedules, code-work routing risks, enabled workflow fixtures, structured-output gate gaps, prompt registry drift, stale hosts, and systemDefault skill duplicates.",
|
|
177
|
+
source: asText(opsCatalogAuditSrc),
|
|
178
|
+
},
|
|
125
179
|
];
|
|
126
180
|
|
|
127
181
|
/** A catalog entry resolved into a generic {@link SeedItem}. */
|
|
@@ -31,6 +31,12 @@ import scheduledTaskResilienceConfig from "../../../templates/skills/scheduled-t
|
|
|
31
31
|
import scheduledTaskResilienceContent from "../../../templates/skills/scheduled-task-resilience/content.md" with {
|
|
32
32
|
type: "text",
|
|
33
33
|
};
|
|
34
|
+
import scriptWorkflowsConfig from "../../../templates/skills/script-workflows/config.json" with {
|
|
35
|
+
type: "text",
|
|
36
|
+
};
|
|
37
|
+
import scriptWorkflowsContent from "../../../templates/skills/script-workflows/content.md" with {
|
|
38
|
+
type: "text",
|
|
39
|
+
};
|
|
34
40
|
import swarmScriptsConfig from "../../../templates/skills/swarm-scripts/config.json" with {
|
|
35
41
|
type: "text",
|
|
36
42
|
};
|
|
@@ -72,6 +78,7 @@ const BUILT_IN_SKILL_SOURCES = [
|
|
|
72
78
|
{ config: kvStorageConfig, body: kvStorageContent },
|
|
73
79
|
{ config: pagesConfig, body: pagesContent },
|
|
74
80
|
{ config: scheduledTaskResilienceConfig, body: scheduledTaskResilienceContent },
|
|
81
|
+
{ config: scriptWorkflowsConfig, body: scriptWorkflowsContent },
|
|
75
82
|
{ config: swarmScriptsConfig, body: swarmScriptsContent },
|
|
76
83
|
{ config: workflowIterateConfig, body: workflowIterateContent },
|
|
77
84
|
{ config: workflowStructuredOutputConfig, body: workflowStructuredOutputContent },
|
|
@@ -41,6 +41,23 @@ const VALIDATED_KEYS: Record<string, (value: unknown) => string | null> = {
|
|
|
41
41
|
if (parsed.success) return null;
|
|
42
42
|
return `Invalid HARNESS_PROVIDER value (must be one of: ${ProviderNameSchema.options.join(", ")})`;
|
|
43
43
|
},
|
|
44
|
+
// Codex credits-exhausted cooldown (ms). Permissive on range here (positive
|
|
45
|
+
// integer) — the worker clamps to [5m, 7d] via resolveCodexCreditsExhaustedCooldownMs.
|
|
46
|
+
CODEX_CREDITS_EXHAUSTED_COOLDOWN_MS: (value) => {
|
|
47
|
+
const str = String(value).trim();
|
|
48
|
+
if (!/^\d+$/.test(str) || Number(str) <= 0) {
|
|
49
|
+
return "Invalid CODEX_CREDITS_EXHAUSTED_COOLDOWN_MS (must be a positive integer of milliseconds)";
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
},
|
|
53
|
+
SWARM_USE_CLAUDE_BRIDGE: (value) => {
|
|
54
|
+
if (typeof value !== "string") {
|
|
55
|
+
return "Invalid SWARM_USE_CLAUDE_BRIDGE value (must be one of: true, false, 1, 0)";
|
|
56
|
+
}
|
|
57
|
+
const normalized = value.trim().toLowerCase();
|
|
58
|
+
if (["true", "false", "1", "0"].includes(normalized)) return null;
|
|
59
|
+
return "Invalid SWARM_USE_CLAUDE_BRIDGE value (must be one of: true, false, 1, 0)";
|
|
60
|
+
},
|
|
44
61
|
};
|
|
45
62
|
|
|
46
63
|
export function validateConfigValue(key: string, value: unknown): string | null {
|
package/src/commands/artifact.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import { createArtifactServer } from "../artifact-sdk";
|
|
3
3
|
import { getApiKey } from "../utils/api-key";
|
|
4
|
+
import { getMcpBaseUrl } from "../utils/constants";
|
|
4
5
|
|
|
5
6
|
interface ArtifactArgs {
|
|
6
7
|
additionalArgs: string[];
|
|
@@ -139,7 +140,7 @@ async function artifactServe(args: ArtifactArgs) {
|
|
|
139
140
|
|
|
140
141
|
async function artifactList() {
|
|
141
142
|
const apiKey = getApiKey();
|
|
142
|
-
const mcpBaseUrl =
|
|
143
|
+
const mcpBaseUrl = getMcpBaseUrl();
|
|
143
144
|
const agentId = process.env.AGENT_ID || "";
|
|
144
145
|
|
|
145
146
|
try {
|
|
@@ -197,7 +198,7 @@ async function artifactStop(args: ArtifactArgs) {
|
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
const apiKey = getApiKey();
|
|
200
|
-
const mcpBaseUrl =
|
|
201
|
+
const mcpBaseUrl = getMcpBaseUrl();
|
|
201
202
|
const agentId = process.env.AGENT_ID || "";
|
|
202
203
|
|
|
203
204
|
// 1. Try to stop PM2 process
|