@desplega.ai/agent-swarm 1.91.0 → 1.92.1
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 +3 -2
- package/openapi.json +1005 -152
- package/package.json +6 -6
- package/plugin/skills/pages/SKILL.md +5 -2
- package/src/be/db.ts +662 -19
- package/src/be/memory/constants.ts +2 -1
- package/src/be/memory/providers/openai-embedding.ts +2 -5
- package/src/be/memory/providers/sqlite-store.ts +293 -76
- package/src/be/memory/types.ts +35 -0
- package/src/be/migrations/083_script_workflows.sql +51 -0
- package/src/be/migrations/084_script_run_journal_duration.sql +5 -0
- package/src/be/migrations/085_script_runs_kind.sql +9 -0
- package/src/be/migrations/086_pages_default_authed.sql +64 -0
- package/src/be/migrations/087_skill_files.sql +19 -0
- package/src/be/modelsdev-cache.json +42310 -38617
- package/src/be/scripts/typecheck.ts +49 -0
- package/src/be/seed-scripts/catalog/boot-triage.ts +221 -0
- package/src/be/seed-scripts/catalog/catalog-report.ts +457 -0
- package/src/be/seed-scripts/catalog/compound-insights.ts +310 -6
- package/src/be/seed-scripts/catalog/gh-pr-snapshot.ts +1 -1
- package/src/be/seed-scripts/catalog/memory-eval.ts +1059 -0
- package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +506 -0
- package/src/be/seed-scripts/catalog/schedule-health.ts +78 -2
- package/src/be/seed-scripts/catalog/task-context-gathering.ts +92 -0
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +48 -1
- package/src/be/seed-scripts/catalog/tool-usage.ts +6 -3
- package/src/be/seed-scripts/index.ts +51 -5
- package/src/be/seed-skills/index.ts +3 -3
- package/src/be/skill-sync.ts +91 -7
- package/src/be/swarm-config-guard.ts +17 -0
- package/src/commands/runner.ts +49 -4
- package/src/heartbeat/templates.ts +20 -16
- package/src/http/db-query.ts +20 -5
- package/src/http/index.ts +51 -7
- package/src/http/mcp-user.ts +23 -0
- package/src/http/mcp.ts +58 -0
- package/src/http/memory.ts +58 -0
- package/src/http/pages.ts +1 -1
- package/src/http/script-runs.ts +557 -0
- package/src/http/scripts.ts +39 -2
- package/src/http/skills.ts +225 -0
- package/src/prompts/session-templates.ts +24 -4
- package/src/providers/claude-adapter.ts +107 -28
- 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 +209 -0
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/swarm-sdk.ts +13 -0
- package/src/scripts-runtime/types/stdlib.d.ts +61 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +61 -0
- package/src/server.ts +4 -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 +271 -74
- package/src/tests/create-page-tool.test.ts +19 -2
- 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/heartbeat-checklist.test.ts +36 -0
- package/src/tests/mcp-tools.test.ts +6 -0
- package/src/tests/mcp-transport-gc.test.ts +58 -0
- package/src/tests/memory-health-endpoint.test.ts +78 -0
- package/src/tests/memory-store.test.ts +221 -1
- package/src/tests/pages-http.test.ts +20 -2
- package/src/tests/pages-storage.test.ts +26 -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 +102 -2
- package/src/tests/seed-scripts.test.ts +468 -3
- package/src/tests/skill-files-http.test.ts +171 -0
- package/src/tests/skill-files.test.ts +162 -0
- package/src/tests/skill-get-file-tool.test.ts +110 -0
- package/src/tests/skill-sync.test.ts +125 -6
- package/src/tests/slack-message-text.test.ts +250 -0
- package/src/tests/system-default-skills.test.ts +40 -0
- package/src/tools/create-page.ts +2 -2
- package/src/tools/db-query.ts +16 -6
- package/src/tools/script-runs.ts +123 -0
- package/src/tools/skills/index.ts +1 -0
- package/src/tools/skills/skill-get-file.ts +80 -0
- package/src/tools/slack-read.ts +12 -3
- package/src/tools/tool-config.ts +6 -2
- package/src/types.ts +72 -0
- 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/schedules/daily-blocker-digest/content.md +68 -54
- package/templates/schedules/daily-compounding-reflection/content.md +4 -4
- package/templates/schedules/daily-hn-briefing/content.md +5 -5
- package/templates/schedules/daily-workflow-health-audit/content.md +6 -6
- package/templates/schedules/gtm-weekly-review/content.md +9 -9
- package/templates/schedules/weekly-dependabot-triage/content.md +24 -20
- package/templates/skills/agentmail-sending/content.md +6 -7
- package/templates/skills/desloppify/content.md +8 -9
- package/templates/skills/jira-interaction/content.md +25 -33
- package/templates/skills/kapso-whatsapp/content.md +29 -30
- package/templates/skills/linear-interaction/content.md +8 -9
- package/templates/skills/pages/content.md +205 -55
- package/templates/skills/profile-corruption-escalation/content.md +44 -85
- package/templates/skills/script-workflows/config.json +14 -0
- package/templates/skills/script-workflows/content.md +68 -0
- package/templates/skills/sprite-cli/content.md +4 -5
- package/templates/skills/swarm-scripts/content.md +2 -3
- package/templates/skills/turso-interaction/content.md +14 -17
- package/templates/skills/workflow-iterate/content.md +38 -391
- package/templates/skills/x-api-interactions/content.md +4 -6
- package/templates/skills/scheduled-task-resilience/config.json +0 -14
- package/templates/skills/scheduled-task-resilience/content.md +0 -95
|
@@ -162,6 +162,9 @@ export interface SwarmSdk {
|
|
|
162
162
|
script_upsert(args: { name: string; source: string; description?: string; intent?: string; scope?: ScriptScope; fsMode?: ScriptFsMode }): Promise<unknown>;
|
|
163
163
|
script_delete(args: { name: string; scope?: ScriptScope }): Promise<unknown>;
|
|
164
164
|
script_queryTypes(args: { name: string; scope?: ScriptScope }): Promise<unknown>;
|
|
165
|
+
script_launchRun(args: { source: string; args?: unknown; idempotencyKey?: string; scriptName?: string; requestedByUserId?: string }): Promise<unknown>;
|
|
166
|
+
script_getRun(args: { id: string }): Promise<unknown>;
|
|
167
|
+
script_listRuns(args?: { status?: "running" | "paused" | "completed" | "failed" | "cancelled" | "aborted_limit"; agentId?: string; limit?: number; offset?: number }): Promise<unknown>;
|
|
165
168
|
|
|
166
169
|
// --- write: repos ---
|
|
167
170
|
repo_update(args: Record<string, unknown>): Promise<unknown>;
|
|
@@ -209,7 +212,53 @@ export interface ScriptStdlib {
|
|
|
209
212
|
|
|
210
213
|
export interface ScriptLogger extends Console {}
|
|
211
214
|
|
|
215
|
+
export interface ScriptRunContext {
|
|
216
|
+
id: string;
|
|
217
|
+
agentId: string;
|
|
218
|
+
args: unknown;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export interface ScriptWorkflowSteps {
|
|
222
|
+
rawLlm(
|
|
223
|
+
label: string,
|
|
224
|
+
config: { prompt: string; model?: string; schema?: Record<string, unknown> },
|
|
225
|
+
): Promise<unknown>;
|
|
226
|
+
agentTask(
|
|
227
|
+
label: string,
|
|
228
|
+
config: {
|
|
229
|
+
template?: string;
|
|
230
|
+
task?: string;
|
|
231
|
+
agentId?: string;
|
|
232
|
+
tags?: string[];
|
|
233
|
+
priority?: number;
|
|
234
|
+
offerMode?: boolean;
|
|
235
|
+
dir?: string;
|
|
236
|
+
vcsRepo?: string;
|
|
237
|
+
model?: string;
|
|
238
|
+
parentTaskId?: string;
|
|
239
|
+
requestedByUserId?: string;
|
|
240
|
+
outputSchema?: Record<string, unknown>;
|
|
241
|
+
},
|
|
242
|
+
): Promise<unknown>;
|
|
243
|
+
swarmScript(
|
|
244
|
+
label: string,
|
|
245
|
+
config: {
|
|
246
|
+
name?: string;
|
|
247
|
+
scriptName?: string;
|
|
248
|
+
source?: string;
|
|
249
|
+
args?: unknown;
|
|
250
|
+
scope?: ScriptScope;
|
|
251
|
+
fsMode?: ScriptFsMode;
|
|
252
|
+
intent?: string;
|
|
253
|
+
idempotencyKey?: string;
|
|
254
|
+
},
|
|
255
|
+
): Promise<unknown>;
|
|
256
|
+
humanInTheLoop(): Promise<never>;
|
|
257
|
+
}
|
|
258
|
+
|
|
212
259
|
export interface ScriptContext {
|
|
260
|
+
run?: ScriptRunContext;
|
|
261
|
+
step?: ScriptWorkflowSteps;
|
|
213
262
|
swarm: SwarmSdk & { config: SwarmConfig };
|
|
214
263
|
stdlib: ScriptStdlib;
|
|
215
264
|
logger: ScriptLogger;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const argsSchema = z.object({
|
|
4
|
+
nowIso: z.string().optional().describe("Triage clock override (default: current time)"),
|
|
5
|
+
failureLookbackMinutes: z
|
|
6
|
+
.number()
|
|
7
|
+
.int()
|
|
8
|
+
.positive()
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Look back this many minutes for real failures (default 60)"),
|
|
11
|
+
stuckMinutes: z
|
|
12
|
+
.number()
|
|
13
|
+
.int()
|
|
14
|
+
.positive()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Flag in-progress tasks older than this on offline agents (default 5)"),
|
|
17
|
+
deployWindowMinutes: z
|
|
18
|
+
.number()
|
|
19
|
+
.int()
|
|
20
|
+
.positive()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Window around now for merged agent-swarm PRs (default 15)"),
|
|
23
|
+
repo: z
|
|
24
|
+
.string()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Optional GitHub repository in 'owner/name' form for restart/deploy PR detection"),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const BENIGN_FAILURE_RE = /^(superseded_workflow_task|cancelled|reboot-sweep)$/i;
|
|
30
|
+
|
|
31
|
+
function rowsToObjects(res: any): any[] {
|
|
32
|
+
const p = res?.data ?? res;
|
|
33
|
+
const cols: string[] = p?.columns ?? [];
|
|
34
|
+
return (p?.rows ?? []).map((r: any) =>
|
|
35
|
+
Array.isArray(r) ? Object.fromEntries(cols.map((c, i) => [c, r[i]])) : r,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function query(ctx: any, sql: string, params?: unknown[]): Promise<any[]> {
|
|
40
|
+
try {
|
|
41
|
+
return rowsToObjects(await ctx.swarm.db_query({ sql, params }));
|
|
42
|
+
} catch (error) {
|
|
43
|
+
return [{ unavailable: error instanceof Error ? error.message : String(error) }];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function taskPreview(task: unknown): string {
|
|
48
|
+
return String(task || "").replace(/\s+/g, " ").trim().slice(0, 180);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function summarizeTask(row: any): any {
|
|
52
|
+
return {
|
|
53
|
+
id: row.id,
|
|
54
|
+
status: row.status,
|
|
55
|
+
taskType: row.taskType || null,
|
|
56
|
+
agentId: row.agentId || null,
|
|
57
|
+
agentName: row.agentName || null,
|
|
58
|
+
scheduleId: row.scheduleId || null,
|
|
59
|
+
parentTaskId: row.parentTaskId || null,
|
|
60
|
+
failureReason: row.failureReason || null,
|
|
61
|
+
createdAt: row.createdAt,
|
|
62
|
+
lastUpdatedAt: row.lastUpdatedAt,
|
|
63
|
+
taskPreview: taskPreview(row.task),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function recentMergedPrs(
|
|
68
|
+
ctx: any,
|
|
69
|
+
repo: string | undefined,
|
|
70
|
+
nowMs: number,
|
|
71
|
+
windowMinutes: number,
|
|
72
|
+
): Promise<any> {
|
|
73
|
+
if (!repo) return { skipped: "repo not provided" };
|
|
74
|
+
if (!/^[^/\s]+\/[^/\s]+$/.test(repo)) return { error: "repo must be in 'owner/name' form" };
|
|
75
|
+
|
|
76
|
+
const windowMs = windowMinutes * 60 * 1000;
|
|
77
|
+
try {
|
|
78
|
+
const response = await ctx.stdlib.fetch(
|
|
79
|
+
"https://api.github.com/repos/" +
|
|
80
|
+
repo +
|
|
81
|
+
"/pulls?state=closed&sort=updated&direction=desc&per_page=20",
|
|
82
|
+
{
|
|
83
|
+
headers: {
|
|
84
|
+
Accept: "application/vnd.github+json",
|
|
85
|
+
"User-Agent": "agent-swarm-boot-triage",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
if (!response.ok) return { error: `GitHub API ${response.status}` };
|
|
90
|
+
const prs = (await response.json()) as any[];
|
|
91
|
+
return prs
|
|
92
|
+
.filter((pr) => pr?.merged_at)
|
|
93
|
+
.map((pr) => {
|
|
94
|
+
const mergedAtMs = Date.parse(pr.merged_at);
|
|
95
|
+
return {
|
|
96
|
+
repo,
|
|
97
|
+
number: pr.number,
|
|
98
|
+
title: pr.title,
|
|
99
|
+
url: pr.html_url,
|
|
100
|
+
mergedAt: pr.merged_at,
|
|
101
|
+
minutesFromRestart: Math.round((mergedAtMs - nowMs) / 60000),
|
|
102
|
+
};
|
|
103
|
+
})
|
|
104
|
+
.filter((pr) => Math.abs(pr.minutesFromRestart * 60000) <= windowMs);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Read-only post-restart triage snapshot for the heartbeat.boot-triage prompt. */
|
|
111
|
+
export default async function bootTriage(args: any, ctx: any) {
|
|
112
|
+
const parsed = argsSchema.safeParse(args || {});
|
|
113
|
+
if (!parsed.success) return { error: "invalid args: " + parsed.error.message };
|
|
114
|
+
|
|
115
|
+
const now = parsed.data.nowIso ? new Date(parsed.data.nowIso) : new Date();
|
|
116
|
+
const nowMs = now.getTime();
|
|
117
|
+
const failureLookbackMinutes = parsed.data.failureLookbackMinutes || 60;
|
|
118
|
+
const stuckMinutes = parsed.data.stuckMinutes || 5;
|
|
119
|
+
const deployWindowMinutes = parsed.data.deployWindowMinutes || 15;
|
|
120
|
+
const repo = parsed.data.repo;
|
|
121
|
+
|
|
122
|
+
const mergedPrs = await recentMergedPrs(ctx, repo, nowMs, deployWindowMinutes);
|
|
123
|
+
|
|
124
|
+
const recentFailureRows = await query(
|
|
125
|
+
ctx,
|
|
126
|
+
`SELECT t.id, t.task, t.status, t.taskType, t.agentId, a.name as agentName,
|
|
127
|
+
t.scheduleId, t.parentTaskId, t.failureReason, t.createdAt, t.lastUpdatedAt
|
|
128
|
+
FROM agent_tasks t
|
|
129
|
+
LEFT JOIN agents a ON a.id = t.agentId
|
|
130
|
+
WHERE t.status = 'failed'
|
|
131
|
+
AND datetime(t.lastUpdatedAt) >= datetime(?, ?)
|
|
132
|
+
ORDER BY datetime(t.lastUpdatedAt) DESC
|
|
133
|
+
LIMIT 50`,
|
|
134
|
+
[now.toISOString(), `-${failureLookbackMinutes} minutes`],
|
|
135
|
+
);
|
|
136
|
+
const recentlyFailedTasks = recentFailureRows
|
|
137
|
+
.filter((row) => !row.unavailable)
|
|
138
|
+
.filter((row) => !BENIGN_FAILURE_RE.test(String(row.failureReason || "")))
|
|
139
|
+
.map(summarizeTask);
|
|
140
|
+
|
|
141
|
+
const stuckOfflineRows = await query(
|
|
142
|
+
ctx,
|
|
143
|
+
`SELECT t.id, t.task, t.status, t.taskType, t.agentId, a.name as agentName,
|
|
144
|
+
t.scheduleId, t.parentTaskId, t.failureReason, t.createdAt, t.lastUpdatedAt
|
|
145
|
+
FROM agent_tasks t
|
|
146
|
+
JOIN agents a ON a.id = t.agentId
|
|
147
|
+
WHERE t.status = 'in_progress'
|
|
148
|
+
AND a.status = 'offline'
|
|
149
|
+
AND datetime(t.lastUpdatedAt) <= datetime(?, ?)
|
|
150
|
+
ORDER BY datetime(t.lastUpdatedAt) ASC
|
|
151
|
+
LIMIT 50`,
|
|
152
|
+
[now.toISOString(), `-${stuckMinutes} minutes`],
|
|
153
|
+
);
|
|
154
|
+
const stuckInProgressOnOfflineAgents = stuckOfflineRows
|
|
155
|
+
.filter((row) => !row.unavailable)
|
|
156
|
+
.map(summarizeTask);
|
|
157
|
+
|
|
158
|
+
const orphanRows = await query(
|
|
159
|
+
ctx,
|
|
160
|
+
`SELECT t.id, t.task, t.status, t.taskType, t.agentId, a.name as agentName,
|
|
161
|
+
t.scheduleId, t.parentTaskId, t.failureReason, t.createdAt, t.lastUpdatedAt
|
|
162
|
+
FROM agent_tasks t
|
|
163
|
+
JOIN agents a ON a.id = t.agentId
|
|
164
|
+
WHERE t.status IN ('pending', 'offered')
|
|
165
|
+
AND a.status = 'offline'
|
|
166
|
+
ORDER BY datetime(t.lastUpdatedAt) ASC
|
|
167
|
+
LIMIT 50`,
|
|
168
|
+
);
|
|
169
|
+
const orphanedPendingOrOfferedOnOfflineWorkers = orphanRows
|
|
170
|
+
.filter((row) => !row.unavailable)
|
|
171
|
+
.map(summarizeTask);
|
|
172
|
+
|
|
173
|
+
const supersededRows = await query(
|
|
174
|
+
ctx,
|
|
175
|
+
`SELECT p.id, p.task, p.status, p.taskType, p.agentId, a.name as agentName,
|
|
176
|
+
p.scheduleId, p.parentTaskId, p.failureReason, p.createdAt, p.lastUpdatedAt
|
|
177
|
+
FROM agent_tasks p
|
|
178
|
+
LEFT JOIN agents a ON a.id = p.agentId
|
|
179
|
+
WHERE p.status = 'superseded'
|
|
180
|
+
AND datetime(p.lastUpdatedAt) >= datetime(?, ?)
|
|
181
|
+
AND NOT EXISTS (
|
|
182
|
+
SELECT 1
|
|
183
|
+
FROM agent_tasks c
|
|
184
|
+
WHERE c.parentTaskId = p.id
|
|
185
|
+
AND c.taskType = 'resume'
|
|
186
|
+
AND c.status NOT IN ('completed', 'failed', 'cancelled', 'superseded')
|
|
187
|
+
)
|
|
188
|
+
ORDER BY datetime(p.lastUpdatedAt) DESC
|
|
189
|
+
LIMIT 50`,
|
|
190
|
+
[now.toISOString(), `-${failureLookbackMinutes} minutes`],
|
|
191
|
+
);
|
|
192
|
+
const supersededTasksMissingResumeChild = supersededRows
|
|
193
|
+
.filter((row) => !row.unavailable)
|
|
194
|
+
.map(summarizeTask);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
generatedAt: now.toISOString(),
|
|
198
|
+
windows: {
|
|
199
|
+
failureLookbackMinutes,
|
|
200
|
+
stuckMinutes,
|
|
201
|
+
deployWindowMinutes,
|
|
202
|
+
},
|
|
203
|
+
deployRestartDetection: {
|
|
204
|
+
source: repo ? "github:" + repo : null,
|
|
205
|
+
mergedPrsWithinWindow: Array.isArray(mergedPrs) ? mergedPrs : [],
|
|
206
|
+
skipped: Array.isArray(mergedPrs) ? null : mergedPrs.skipped || null,
|
|
207
|
+
error: Array.isArray(mergedPrs) ? null : mergedPrs.error,
|
|
208
|
+
},
|
|
209
|
+
recentlyFailedTasks,
|
|
210
|
+
stuckInProgressOnOfflineAgents,
|
|
211
|
+
orphanedPendingOrOfferedOnOfflineWorkers,
|
|
212
|
+
supersededTasksMissingResumeChild,
|
|
213
|
+
summary: {
|
|
214
|
+
mergedPrsWithinWindow: Array.isArray(mergedPrs) ? mergedPrs.length : 0,
|
|
215
|
+
recentlyFailedTasks: recentlyFailedTasks.length,
|
|
216
|
+
stuckInProgressOnOfflineAgents: stuckInProgressOnOfflineAgents.length,
|
|
217
|
+
orphanedPendingOrOfferedOnOfflineWorkers: orphanedPendingOrOfferedOnOfflineWorkers.length,
|
|
218
|
+
supersededTasksMissingResumeChild: supersededTasksMissingResumeChild.length,
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|