@desplega.ai/agent-swarm 1.87.0 → 1.88.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 +13 -1
- package/package.json +5 -5
- package/src/be/db.ts +49 -7
- package/src/be/migrations/080_skill_system_defaults.sql +8 -0
- package/src/be/modelsdev-cache.json +1123 -1034
- package/src/be/seed/registry.ts +3 -2
- package/src/be/seed-skills/index.ts +172 -0
- package/src/cli.tsx +33 -4
- package/src/commands/e2b-stack-wizard.tsx +394 -0
- package/src/commands/e2b.ts +1352 -53
- package/src/commands/onboard/dashboard-url.ts +29 -0
- package/src/commands/onboard/steps/post-dashboard.tsx +3 -1
- package/src/commands/onboard.tsx +3 -1
- package/src/commands/runner.ts +1 -0
- package/src/e2b/dispatch.ts +234 -18
- package/src/http/memory.ts +13 -1
- package/src/http/skills.ts +53 -0
- package/src/http/webhooks.ts +75 -0
- package/src/integrations/kapso/client.ts +82 -0
- package/src/memory/automatic-task-gate.ts +47 -0
- package/src/prompts/base-prompt.ts +16 -1
- package/src/prompts/session-templates.ts +51 -0
- package/src/providers/claude-adapter.ts +19 -0
- package/src/providers/codex-adapter.ts +22 -0
- package/src/providers/ctx-mode-env.ts +10 -0
- package/src/providers/opencode-adapter.ts +50 -1
- package/src/slack/blocks.ts +12 -4
- package/src/slack/watcher.ts +3 -3
- package/src/telemetry.ts +14 -1
- package/src/templates.d.ts +4 -0
- package/src/tests/base-prompt.test.ts +41 -0
- package/src/tests/claude-adapter.test.ts +86 -1
- package/src/tests/codex-adapter.test.ts +89 -0
- package/src/tests/e2b-dispatch.test.ts +603 -11
- package/src/tests/http-api-integration.test.ts +113 -0
- package/src/tests/kapso-client.test.ts +74 -1
- package/src/tests/kapso-inbound.test.ts +60 -2
- package/src/tests/opencode-adapter.test.ts +95 -0
- package/src/tests/prompt-template-session.test.ts +4 -2
- package/src/tests/self-improvement.test.ts +89 -0
- package/src/tests/skill-update-scope.test.ts +88 -1
- package/src/tests/slack-blocks.test.ts +15 -0
- package/src/tests/system-default-skills.test.ts +119 -0
- package/src/tests/telemetry-init.test.ts +86 -0
- package/src/tools/skills/skill-delete.ts +14 -0
- package/src/tools/skills/skill-update.ts +14 -0
- package/src/tools/store-progress.ts +19 -5
- package/src/types.ts +1 -0
- package/templates/skills/artifacts/config.json +1 -0
- package/templates/skills/kv-storage/config.json +1 -0
- package/templates/skills/pages/config.json +1 -0
- package/templates/skills/scheduled-task-resilience/config.json +1 -0
- package/templates/skills/swarm-scripts/SKILL.md +91 -0
- package/templates/skills/swarm-scripts/config.json +14 -0
- package/templates/skills/swarm-scripts/content.md +86 -0
- package/templates/skills/workflow-iterate/config.json +1 -0
- package/templates/skills/workflow-structured-output/config.json +1 -0
- package/tsconfig.json +2 -1
package/README.md
CHANGED
|
@@ -124,7 +124,7 @@ Check [our templates](https://templates.agent-swarm.dev) for a quick start.
|
|
|
124
124
|
- **Workflow engine with Human-in-the-Loop** — DAG-based automation with approval gates, retries, and structured I/O. [Workflows →](https://docs.agent-swarm.dev/docs/concepts/workflows)
|
|
125
125
|
- **Scheduled & recurring tasks** — cron-based automation for standing work. [Scheduling →](https://docs.agent-swarm.dev/docs/concepts/scheduling)
|
|
126
126
|
- **Harness & LLM agnostic** — run with Claude Code, OpenAI Codex, pi-mono, Devin, Claude Managed Agents, raw LLMs, or opencode. [Harness config →](https://docs.agent-swarm.dev/docs/guides/harness-configuration) · [Add a new provider →](https://docs.agent-swarm.dev/docs/guides/harness-providers)
|
|
127
|
-
- **Follow-up continuity across all harnesses** — child tasks inherit bounded prior-task context
|
|
127
|
+
- **Follow-up continuity across all harnesses** — child tasks inherit a bounded prior-task context preamble built from the task chain, so continuity survives restarts and works the same across every provider. [Task lifecycle →](https://docs.agent-swarm.dev/docs/concepts/task-lifecycle)
|
|
128
128
|
- **Skills & MCP servers** — reusable procedural knowledge and per-agent MCP servers with scope cascade. [MCP tools →](https://docs.agent-swarm.dev/docs/reference/mcp-tools)
|
|
129
129
|
- **DB-backed pages** — agents publish HTML or JSON pages (reports, dashboards, action specs) via the `create_page` MCP tool with public / authed / password modes, version history, view counters, diff helpers, and PDF export. [MCP tools → Pages](https://docs.agent-swarm.dev/docs/reference/mcp-tools#pages-tools)
|
|
130
130
|
- **KV store** — Redis-like namespaced key/value store with auto-scoped context (Slack thread / PR / Linear issue / page). [MCP tools → KV](https://docs.agent-swarm.dev/docs/reference/mcp-tools#kv-tools)
|
|
@@ -222,6 +222,7 @@ bunx @desplega.ai/agent-swarm <command>
|
|
|
222
222
|
| `api` | Start the API + MCP HTTP server |
|
|
223
223
|
| `worker` | Run a worker agent |
|
|
224
224
|
| `lead` | Run a lead agent |
|
|
225
|
+
| `e2b` | Build E2B templates and launch/manage grouped API + lead + worker swarms |
|
|
225
226
|
| `docs` | Open documentation (`--open` to launch in browser) |
|
|
226
227
|
|
|
227
228
|
## Deployment
|
package/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Agent Swarm API",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.88.0",
|
|
6
6
|
"description": "Multi-agent orchestration API for Claude Code, Codex, and Gemini CLI. Enables task distribution, agent communication, and service discovery.\n\nMCP tools are documented separately in [MCP.md](./MCP.md)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
@@ -4014,6 +4014,9 @@
|
|
|
4014
4014
|
"items": {
|
|
4015
4015
|
"type": "string"
|
|
4016
4016
|
}
|
|
4017
|
+
},
|
|
4018
|
+
"persistMemory": {
|
|
4019
|
+
"type": "boolean"
|
|
4017
4020
|
}
|
|
4018
4021
|
},
|
|
4019
4022
|
"required": [
|
|
@@ -7620,6 +7623,9 @@
|
|
|
7620
7623
|
},
|
|
7621
7624
|
"ownerAgentId": {
|
|
7622
7625
|
"type": "string"
|
|
7626
|
+
},
|
|
7627
|
+
"systemDefault": {
|
|
7628
|
+
"type": "boolean"
|
|
7623
7629
|
}
|
|
7624
7630
|
},
|
|
7625
7631
|
"required": [
|
|
@@ -7703,6 +7709,9 @@
|
|
|
7703
7709
|
"200": {
|
|
7704
7710
|
"description": "Skill updated"
|
|
7705
7711
|
},
|
|
7712
|
+
"403": {
|
|
7713
|
+
"description": "System-managed skills cannot be edited"
|
|
7714
|
+
},
|
|
7706
7715
|
"404": {
|
|
7707
7716
|
"description": "Skill not found"
|
|
7708
7717
|
}
|
|
@@ -7732,6 +7741,9 @@
|
|
|
7732
7741
|
"200": {
|
|
7733
7742
|
"description": "Skill deleted"
|
|
7734
7743
|
},
|
|
7744
|
+
"403": {
|
|
7745
|
+
"description": "System-managed skills cannot be deleted"
|
|
7746
|
+
},
|
|
7735
7747
|
"404": {
|
|
7736
7748
|
"description": "Skill not found"
|
|
7737
7749
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-swarm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.88.0",
|
|
4
4
|
"description": "Multi-agent orchestration for Claude Code, Codex, Gemini CLI, and other AI coding assistants",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "desplega.sh <contact@desplega.sh>",
|
|
@@ -111,12 +111,12 @@
|
|
|
111
111
|
"@desplega.ai/localtunnel": "^2.2.0",
|
|
112
112
|
"@inkjs/ui": "^2.0.0",
|
|
113
113
|
"@linear/sdk": "^77.0.0",
|
|
114
|
-
"@earendil-works/pi-agent-core": "^0.
|
|
115
|
-
"@earendil-works/pi-ai": "^0.
|
|
116
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
114
|
+
"@earendil-works/pi-agent-core": "^0.78.0",
|
|
115
|
+
"@earendil-works/pi-ai": "^0.78.0",
|
|
116
|
+
"@earendil-works/pi-coding-agent": "^0.78.0",
|
|
117
117
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
118
118
|
"@openai/codex-sdk": "^0.135.0",
|
|
119
|
-
"@opencode-ai/sdk": "^1.15.
|
|
119
|
+
"@opencode-ai/sdk": "^1.15.13",
|
|
120
120
|
"@openfort/openfort-node": "^0.9.1",
|
|
121
121
|
"@opentelemetry/api": "^1.9.1",
|
|
122
122
|
"@opentelemetry/exporter-trace-otlp-http": "^0.218.0",
|
package/src/be/db.ts
CHANGED
|
@@ -691,6 +691,14 @@ export function createAgent(
|
|
|
691
691
|
agent.harnessProvider ?? null,
|
|
692
692
|
);
|
|
693
693
|
if (!row) throw new Error("Failed to create agent");
|
|
694
|
+
try {
|
|
695
|
+
installSystemDefaultSkillsForAgent(id);
|
|
696
|
+
} catch (err) {
|
|
697
|
+
console.warn(
|
|
698
|
+
"[db] Failed to install system-default skills for new agent:",
|
|
699
|
+
(err as Error).message,
|
|
700
|
+
);
|
|
701
|
+
}
|
|
694
702
|
try {
|
|
695
703
|
createLogEntry({ eventType: "agent_joined", agentId: id, newValue: agent.status });
|
|
696
704
|
} catch {}
|
|
@@ -8247,6 +8255,7 @@ type SkillRow = {
|
|
|
8247
8255
|
userInvocable: number;
|
|
8248
8256
|
version: number;
|
|
8249
8257
|
isEnabled: number;
|
|
8258
|
+
systemDefault: number;
|
|
8250
8259
|
createdAt: string;
|
|
8251
8260
|
lastUpdatedAt: string;
|
|
8252
8261
|
lastFetchedAt: string | null;
|
|
@@ -8276,6 +8285,7 @@ function rowToSkill(row: SkillRow): Skill {
|
|
|
8276
8285
|
userInvocable: row.userInvocable === 1,
|
|
8277
8286
|
version: row.version,
|
|
8278
8287
|
isEnabled: row.isEnabled === 1,
|
|
8288
|
+
systemDefault: row.systemDefault === 1,
|
|
8279
8289
|
createdAt: row.createdAt,
|
|
8280
8290
|
lastUpdatedAt: row.lastUpdatedAt,
|
|
8281
8291
|
lastFetchedAt: row.lastFetchedAt,
|
|
@@ -8300,7 +8310,12 @@ function rowToAgentSkill(row: AgentSkillRow): AgentSkill {
|
|
|
8300
8310
|
};
|
|
8301
8311
|
}
|
|
8302
8312
|
|
|
8303
|
-
type SkillWithInstallRow = SkillRow & {
|
|
8313
|
+
type SkillWithInstallRow = SkillRow & {
|
|
8314
|
+
isActive: number;
|
|
8315
|
+
installedAt: string;
|
|
8316
|
+
sourceRank?: number;
|
|
8317
|
+
typeRank?: number;
|
|
8318
|
+
};
|
|
8304
8319
|
|
|
8305
8320
|
function rowToSkillWithInstall(row: SkillWithInstallRow): SkillWithInstallInfo {
|
|
8306
8321
|
return {
|
|
@@ -8330,6 +8345,7 @@ export interface SkillInsert {
|
|
|
8330
8345
|
agent?: string;
|
|
8331
8346
|
disableModelInvocation?: boolean;
|
|
8332
8347
|
userInvocable?: boolean;
|
|
8348
|
+
systemDefault?: boolean;
|
|
8333
8349
|
}
|
|
8334
8350
|
|
|
8335
8351
|
export function createSkill(data: SkillInsert): Skill {
|
|
@@ -8342,8 +8358,8 @@ export function createSkill(data: SkillInsert): Skill {
|
|
|
8342
8358
|
id, name, description, content, type, scope, ownerAgentId,
|
|
8343
8359
|
sourceUrl, sourceRepo, sourcePath, sourceBranch, sourceHash, isComplex,
|
|
8344
8360
|
allowedTools, model, effort, context, agent, disableModelInvocation, userInvocable,
|
|
8345
|
-
version, isEnabled, createdAt, lastUpdatedAt
|
|
8346
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 1, ?, ?) RETURNING *`,
|
|
8361
|
+
version, isEnabled, systemDefault, createdAt, lastUpdatedAt
|
|
8362
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 1, ?, ?, ?) RETURNING *`,
|
|
8347
8363
|
)
|
|
8348
8364
|
.get(
|
|
8349
8365
|
id,
|
|
@@ -8366,6 +8382,7 @@ export function createSkill(data: SkillInsert): Skill {
|
|
|
8366
8382
|
data.agent ?? null,
|
|
8367
8383
|
data.disableModelInvocation ? 1 : 0,
|
|
8368
8384
|
data.userInvocable === false ? 0 : 1,
|
|
8385
|
+
data.systemDefault ? 1 : 0,
|
|
8369
8386
|
now,
|
|
8370
8387
|
now,
|
|
8371
8388
|
);
|
|
@@ -8405,6 +8422,10 @@ export function updateSkill(
|
|
|
8405
8422
|
sets.push("isEnabled = ?");
|
|
8406
8423
|
params.push(updates.isEnabled ? 1 : 0);
|
|
8407
8424
|
}
|
|
8425
|
+
if (updates.systemDefault !== undefined) {
|
|
8426
|
+
sets.push("systemDefault = ?");
|
|
8427
|
+
params.push(updates.systemDefault ? 1 : 0);
|
|
8428
|
+
}
|
|
8408
8429
|
if (updates.allowedTools !== undefined) {
|
|
8409
8430
|
sets.push("allowedTools = ?");
|
|
8410
8431
|
params.push(updates.allowedTools ?? null);
|
|
@@ -8516,7 +8537,7 @@ export interface SkillFilters {
|
|
|
8516
8537
|
* which is replaced with an empty string so the row still satisfies `Skill`.
|
|
8517
8538
|
*/
|
|
8518
8539
|
const SKILL_SLIM_COLUMNS =
|
|
8519
|
-
"id, name, description, type, scope, ownerAgentId, sourceUrl, sourceRepo, sourcePath, sourceBranch, sourceHash, isComplex, allowedTools, model, effort, context, agent, disableModelInvocation, userInvocable, version, isEnabled, createdAt, lastUpdatedAt, lastFetchedAt, '' as content";
|
|
8540
|
+
"id, name, description, type, scope, ownerAgentId, sourceUrl, sourceRepo, sourcePath, sourceBranch, sourceHash, isComplex, allowedTools, model, effort, context, agent, disableModelInvocation, userInvocable, version, isEnabled, systemDefault, createdAt, lastUpdatedAt, lastFetchedAt, '' as content";
|
|
8520
8541
|
|
|
8521
8542
|
export function listSkills(filters?: SkillFilters): Skill[] {
|
|
8522
8543
|
const columns = filters?.includeContent === false ? SKILL_SLIM_COLUMNS : "*";
|
|
@@ -8586,6 +8607,19 @@ export function installSkill(agentId: string, skillId: string): AgentSkill {
|
|
|
8586
8607
|
return rowToAgentSkill(row);
|
|
8587
8608
|
}
|
|
8588
8609
|
|
|
8610
|
+
export function getSystemDefaultSkills(): Skill[] {
|
|
8611
|
+
return getDb()
|
|
8612
|
+
.prepare<SkillRow, []>(
|
|
8613
|
+
"SELECT * FROM skills WHERE systemDefault = 1 AND isEnabled = 1 ORDER BY name ASC",
|
|
8614
|
+
)
|
|
8615
|
+
.all()
|
|
8616
|
+
.map(rowToSkill);
|
|
8617
|
+
}
|
|
8618
|
+
|
|
8619
|
+
export function installSystemDefaultSkillsForAgent(agentId: string): AgentSkill[] {
|
|
8620
|
+
return getSystemDefaultSkills().map((skill) => installSkill(agentId, skill.id));
|
|
8621
|
+
}
|
|
8622
|
+
|
|
8589
8623
|
export function uninstallSkill(agentId: string, skillId: string): boolean {
|
|
8590
8624
|
const result = getDb()
|
|
8591
8625
|
.prepare("DELETE FROM agent_skills WHERE agentId = ? AND skillId = ?")
|
|
@@ -8595,15 +8629,23 @@ export function uninstallSkill(agentId: string, skillId: string): boolean {
|
|
|
8595
8629
|
|
|
8596
8630
|
export function getAgentSkills(agentId: string, activeOnly = true): SkillWithInstallInfo[] {
|
|
8597
8631
|
const query = `
|
|
8598
|
-
SELECT s.*, as2.isActive, as2.installedAt
|
|
8632
|
+
SELECT s.*, as2.isActive, as2.installedAt, 0 as sourceRank,
|
|
8633
|
+
CASE WHEN s.type = 'personal' THEN 0 ELSE 1 END as typeRank
|
|
8599
8634
|
FROM skills s
|
|
8600
8635
|
JOIN agent_skills as2 ON s.id = as2.skillId
|
|
8601
8636
|
WHERE as2.agentId = ?
|
|
8602
8637
|
${activeOnly ? "AND as2.isActive = 1" : ""}
|
|
8603
8638
|
AND s.isEnabled = 1
|
|
8639
|
+
UNION ALL
|
|
8640
|
+
SELECT s.*, 1 as isActive, s.createdAt as installedAt, 1 as sourceRank,
|
|
8641
|
+
CASE WHEN s.type = 'personal' THEN 0 ELSE 1 END as typeRank
|
|
8642
|
+
FROM skills s
|
|
8643
|
+
WHERE s.systemDefault = 1
|
|
8644
|
+
AND s.isEnabled = 1
|
|
8604
8645
|
ORDER BY
|
|
8605
|
-
|
|
8606
|
-
|
|
8646
|
+
sourceRank,
|
|
8647
|
+
typeRank,
|
|
8648
|
+
name
|
|
8607
8649
|
`;
|
|
8608
8650
|
|
|
8609
8651
|
const rows = getDb().prepare<SkillWithInstallRow, [string]>(query).all(agentId);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- 080_skill_system_defaults.sql
|
|
2
|
+
-- Adds a first-class marker for skills that are installed for every agent.
|
|
3
|
+
-- Forward migration: add nullable-safe column with default 0.
|
|
4
|
+
-- Reverse operation, if ever needed: ALTER TABLE skills DROP COLUMN systemDefault;
|
|
5
|
+
|
|
6
|
+
ALTER TABLE skills ADD COLUMN systemDefault INTEGER NOT NULL DEFAULT 0;
|
|
7
|
+
|
|
8
|
+
CREATE INDEX IF NOT EXISTS idx_skills_system_default ON skills(systemDefault);
|