@desplega.ai/agent-swarm 1.92.0 → 1.92.2
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 +1 -1
- package/openapi.json +276 -3
- package/package.json +6 -6
- package/plugin/skills/pages/SKILL.md +5 -2
- package/src/be/db.ts +416 -20
- package/src/be/memory/boot-reembed.ts +85 -0
- package/src/be/memory/constants.ts +44 -2
- package/src/be/memory/providers/openai-embedding.ts +15 -5
- package/src/be/memory/providers/sqlite-store.ts +325 -76
- package/src/be/memory/reranker.ts +35 -17
- package/src/be/memory/types.ts +43 -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 +5622 -2543
- 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 +465 -0
- 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 +34 -439
- package/src/be/seed-scripts/catalog/schedule-health.ts +78 -2
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +48 -1
- package/src/be/seed-scripts/index.ts +32 -4
- package/src/be/seed-skills/index.ts +0 -7
- package/src/be/skill-sync.ts +91 -7
- package/src/commands/runner.ts +6 -2
- package/src/heartbeat/templates.ts +20 -16
- package/src/http/index.ts +50 -7
- package/src/http/mcp-user.ts +23 -0
- package/src/http/mcp.ts +58 -0
- package/src/http/memory.ts +62 -0
- package/src/http/pages.ts +1 -1
- package/src/http/script-runs.ts +2 -0
- package/src/http/scripts.ts +39 -2
- package/src/http/skills.ts +225 -0
- package/src/providers/claude-adapter.ts +56 -24
- package/src/script-workflows/workflow-ctx.ts +7 -3
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/swarm-sdk.ts +13 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/server.ts +2 -0
- package/src/tasks/worker-follow-up.ts +12 -0
- package/src/tests/claude-adapter-binary.test.ts +135 -81
- package/src/tests/create-page-tool.test.ts +19 -2
- package/src/tests/heartbeat-checklist.test.ts +36 -0
- package/src/tests/mcp-transport-gc.test.ts +58 -0
- package/src/tests/memory-e2e.test.ts +6 -6
- package/src/tests/memory-health-endpoint.test.ts +78 -0
- package/src/tests/memory-rater-e2e.test.ts +4 -5
- package/src/tests/memory-reranker.test.ts +135 -124
- package/src/tests/memory-store.test.ts +221 -1
- package/src/tests/memory.test.ts +13 -12
- package/src/tests/pages-http.test.ts +20 -2
- package/src/tests/pages-storage.test.ts +26 -0
- package/src/tests/scripts-mcp-e2e.test.ts +53 -0
- package/src/tests/seed-scripts.test.ts +328 -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/task-cascade-fail.test.ts +304 -0
- package/src/tools/create-page.ts +2 -2
- package/src/tools/skills/index.ts +1 -0
- package/src/tools/skills/skill-get-file.ts +80 -0
- package/src/tools/tool-config.ts +2 -1
- package/src/types.ts +20 -0
- package/src/utils/internal-ai/complete-structured.ts +2 -2
- 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/profile-corruption-escalation/content.md +44 -85
- package/templates/skills/sprite-cli/content.md +4 -5
- 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/workflows/llm-safe-release-context/config.json +13 -0
- package/templates/workflows/llm-safe-release-context/content.md +69 -0
- package/templates/skills/scheduled-task-resilience/config.json +0 -14
- package/templates/skills/scheduled-task-resilience/content.md +0 -95
|
@@ -49,8 +49,8 @@ curl -s "https://api.x.com/2/tweets/{TWEET_ID}?tweet.fields=reply_settings" \
|
|
|
49
49
|
|
|
50
50
|
Response includes `reply_settings`:
|
|
51
51
|
- `everyone` — Anyone can reply
|
|
52
|
-
- `mentionedUsers` — Only mentioned users can reply
|
|
53
|
-
- `following` — Only followers can reply
|
|
52
|
+
- `mentionedUsers` — Only mentioned users can reply unless your account is mentioned
|
|
53
|
+
- `following` — Only followers can reply unless the author follows your account
|
|
54
54
|
|
|
55
55
|
**If reply_settings is NOT "everyone", do NOT attempt the reply.** Report back that the tweet has conversation restrictions. Quote tweets may also be restricted on such tweets.
|
|
56
56
|
|
|
@@ -85,7 +85,7 @@ curl -X POST "https://api.x.com/2/tweets" \
|
|
|
85
85
|
|
|
86
86
|
| Error | Cause | Fix |
|
|
87
87
|
|-------|-------|-----|
|
|
88
|
-
| **402 CreditsDepleted** | Monthly API credits exhausted | **STOP immediately.** Do NOT retry. Save generated content to agent-fs for later manual posting. Report to
|
|
88
|
+
| **402 CreditsDepleted** | Monthly API credits exhausted | **STOP immediately.** Do NOT retry. Save generated content to agent-fs for later manual posting. Report to the requester. Mark task as failed. An account owner must top up credits at developer.x.com. |
|
|
89
89
|
| 403 Forbidden on reply | Conversation restrictions | Pre-check reply_settings |
|
|
90
90
|
| 403 Forbidden on quote | Quote restrictions | Report back, don't retry |
|
|
91
91
|
| 401 Unauthorized | Bad OAuth signature | Verify credentials, check timestamp |
|
|
@@ -95,8 +95,7 @@ curl -X POST "https://api.x.com/2/tweets" \
|
|
|
95
95
|
|
|
96
96
|
## Account Info
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
- **User ID:** 2027510506601488384
|
|
98
|
+
Store your account handle and user ID in local config or notes for your deployment. Do not assume this template's operator account.
|
|
100
99
|
|
|
101
100
|
## Workflow
|
|
102
101
|
|
|
@@ -106,4 +105,3 @@ curl -X POST "https://api.x.com/2/tweets" \
|
|
|
106
105
|
4. POST the tweet/reply/quote
|
|
107
106
|
5. If 402, STOP — save content to agent-fs and report (credits depleted)
|
|
108
107
|
6. If 403, report the restriction — do NOT retry blindly
|
|
109
|
-
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "workflow",
|
|
3
|
+
"name": "llm-safe-release-context",
|
|
4
|
+
"displayName": "LLM-Safe Release Context",
|
|
5
|
+
"slug": "llm-safe-release-context",
|
|
6
|
+
"title": "LLM-Safe Release Context",
|
|
7
|
+
"description": "Pattern for release-note workflows that keep full audit context separate from slim prompt context.",
|
|
8
|
+
"version": "1.0.0",
|
|
9
|
+
"category": "workflows",
|
|
10
|
+
"placeholders": ["ORG_ID", "REPO_URL"],
|
|
11
|
+
"runAllSeedersCandidate": false,
|
|
12
|
+
"tags": ["workflow", "release-notes", "context"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# LLM-Safe Release Context
|
|
2
|
+
|
|
3
|
+
Use this pattern for release-note, changelog, and report workflows where one node gathers a large source artifact and later LLM nodes plan or write from it.
|
|
4
|
+
|
|
5
|
+
The key rule: keep the full artifact for audit/debugging, but pass a compact projection to every LLM prompt.
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"name": "LLM-safe release context",
|
|
10
|
+
"description": "Build full release context and a slim prompt-safe projection before downstream LLM nodes run.",
|
|
11
|
+
"nodes": [
|
|
12
|
+
{
|
|
13
|
+
"id": "context-builder",
|
|
14
|
+
"type": "agent-task",
|
|
15
|
+
"config": {
|
|
16
|
+
"template": "Build release context for {{REPO_URL}}. Write the full audit artifact to agent-fs at release-runs/{DATE}/context.json. Also write release-runs/{DATE}/context-slim.json with at most 150 commit objects containing only hash, shortHash, author, date, message, and changed file paths. Do not include patch bodies, diff hunks, raw git log --stat output, downloaded HTML, or other bulk text in context-slim.json. Return contextPath and contextSlimPath.",
|
|
17
|
+
"outputSchema": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"properties": {
|
|
20
|
+
"skip": { "type": "boolean" },
|
|
21
|
+
"reason": { "type": "string" },
|
|
22
|
+
"contextPath": { "type": "string" },
|
|
23
|
+
"contextSlimPath": { "type": "string" },
|
|
24
|
+
"itemCount": { "type": "number" }
|
|
25
|
+
},
|
|
26
|
+
"required": ["skip"]
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"next": "plan-release"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "plan-release",
|
|
33
|
+
"type": "agent-task",
|
|
34
|
+
"inputs": { "context": "context-builder" },
|
|
35
|
+
"config": {
|
|
36
|
+
"template": "Read the slim context only:\nagent-fs --org {{ORG_ID}} cat {{context.taskOutput.contextSlimPath}}\n\nDo not read {{context.taskOutput.contextPath}} unless a human explicitly asks for the full audit artifact. Plan the release from the slim context and return JSON.",
|
|
37
|
+
"outputSchema": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"properties": {
|
|
40
|
+
"planPath": { "type": "string" },
|
|
41
|
+
"heroChange": { "type": "string" },
|
|
42
|
+
"themes": { "type": "array", "items": { "type": "string" } }
|
|
43
|
+
},
|
|
44
|
+
"required": ["planPath", "heroChange"]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"next": "write-release"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "write-release",
|
|
51
|
+
"type": "agent-task",
|
|
52
|
+
"inputs": { "context": "context-builder", "plan": "plan-release" },
|
|
53
|
+
"config": {
|
|
54
|
+
"template": "Read the approved plan and slim context only:\nagent-fs --org {{ORG_ID}} cat {{plan.taskOutput.planPath}}\nagent-fs --org {{ORG_ID}} cat {{context.taskOutput.contextSlimPath}}\n\nDo not read {{context.taskOutput.contextPath}}. Write the release artifact and return JSON.",
|
|
55
|
+
"outputSchema": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"properties": {
|
|
58
|
+
"contentPath": { "type": "string" },
|
|
59
|
+
"title": { "type": "string" }
|
|
60
|
+
},
|
|
61
|
+
"required": ["contentPath", "title"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This avoids the common failure mode where a large `context.json` fills the model window and the workflow fails as "structured output required" before the agent has enough context left to call `store-progress`.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"kind": "skill",
|
|
3
|
-
"name": "scheduled-task-resilience",
|
|
4
|
-
"displayName": "Scheduled Task Resilience",
|
|
5
|
-
"slug": "scheduled-task-resilience",
|
|
6
|
-
"title": "Scheduled Task Resilience",
|
|
7
|
-
"description": "Guardrails for polling, scheduled jobs, and long-running external operations.",
|
|
8
|
-
"version": "1.0.0",
|
|
9
|
-
"category": "skills",
|
|
10
|
-
"placeholders": [],
|
|
11
|
-
"runAllSeedersCandidate": true,
|
|
12
|
-
"systemDefault": true,
|
|
13
|
-
"tags": ["schedules", "reliability", "polling"]
|
|
14
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# Scheduled Task Resilience
|
|
2
|
-
|
|
3
|
-
When writing, retrying, or running a scheduled/cron task that polls or waits on a long-running operation, follow these hard rules. Multiple confirmed heartbeat-kill incidents (Apr 24, Apr 25, May 1, May 3, May 26, 2026) prove they matter.
|
|
4
|
-
|
|
5
|
-
## Rule 1 — NEVER `ScheduleWakeup` with `delaySeconds >= 300`
|
|
6
|
-
|
|
7
|
-
**Why:** The runtime's heartbeat staleness threshold sits near the same window as the Anthropic prompt-cache TTL (~5 min). Sleeping 300s+ in `ScheduleWakeup` mode looks identical to a dead worker — the heartbeat sweep kills your task mid-poll.
|
|
8
|
-
|
|
9
|
-
**Confirmed incidents:**
|
|
10
|
-
- `e2892d4a` (daily-docs Apr 24 02:58 UTC) — polling CI for PR #366
|
|
11
|
-
- `c7790626` (daily HN briefing Apr 25 02:53 UTC) — polling browser scrape
|
|
12
|
-
|
|
13
|
-
**Do this instead:**
|
|
14
|
-
- For polls under 4 minutes, use `Bash` with a short `sleep` loop (≤270s per iteration), then re-check.
|
|
15
|
-
- For genuinely long waits (CI builds, releases, deploys), prefer the workflow scheduler (`patch-workflow`) over `ScheduleWakeup`.
|
|
16
|
-
- 270s is the sweet spot: it stays in the prompt cache *and* under the heartbeat ceiling.
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# Good — short sleep, frequent re-check
|
|
20
|
-
for i in 1 2 3 4 5; do
|
|
21
|
-
status=$(gh pr checks "$PR" --json state --jq '.[0].state')
|
|
22
|
-
[ "$status" = "SUCCESS" ] && break
|
|
23
|
-
sleep 240
|
|
24
|
-
done
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Rule 2 — Tag retry tasks with `reboot-retry`
|
|
28
|
-
|
|
29
|
-
**Why:** Apr 22 reboot-loss `f2260faa` (Zynap investigation) was re-delegated manually because it lacked the `reboot-retry` tag. Boot-sweep missed it. Cost: ~4h of investigation re-work.
|
|
30
|
-
|
|
31
|
-
**Do this:**
|
|
32
|
-
- Any task auto-retried after a session loss MUST have `reboot-retry` in its tags.
|
|
33
|
-
- If you re-create a lost task manually, add the tag yourself so the next boot-sweep treats it correctly.
|
|
34
|
-
|
|
35
|
-
## Rule 3 — Long polls must `store-progress` every 2-3 minutes
|
|
36
|
-
|
|
37
|
-
**Why:** The heartbeat sweep marks tasks "stale" after ~5 min without an update. Workers polling silently look like dead workers.
|
|
38
|
-
|
|
39
|
-
**Do this:**
|
|
40
|
-
- Inside any polling block, call `store-progress` with a status string like `"polling CI status (attempt 3/10)"`.
|
|
41
|
-
- Even if nothing has changed, the heartbeat update keeps the runtime confident.
|
|
42
|
-
|
|
43
|
-
## Rule 4 — When a scheduled task fails, check the failure mode before retrying
|
|
44
|
-
|
|
45
|
-
**Why:** Two instant failures with the same reason (`worker session heartbeat is stale`) = infrastructure problem, not transient. Don't re-create a 3rd instance — escalate.
|
|
46
|
-
|
|
47
|
-
**Do this:**
|
|
48
|
-
- Lead-level: if a scheduled task fails 2× with the same reason, post a #swarmillo escalation; do NOT re-create.
|
|
49
|
-
- Worker-level: if you see repeated heartbeat-kill on your own retries, swarm-chat the lead instead of re-spawning yourself.
|
|
50
|
-
|
|
51
|
-
## Rule 5 — Pre-flight check for duplicate scheduled posts
|
|
52
|
-
|
|
53
|
-
**Why:** Concurrent sessions sometimes pick up the same scheduled task. Without a check, you double-post to Slack/email.
|
|
54
|
-
|
|
55
|
-
**Do this:**
|
|
56
|
-
- Before posting any scheduled output (Slack, email, blog), call `get-tasks` and search Slack history for the same schedule tag in the last hour.
|
|
57
|
-
- If a recent completion already happened, abort with `store-progress` noting the duplicate detection.
|
|
58
|
-
|
|
59
|
-
## Rule 6 — Post-shipping: do NOT `ScheduleWakeup` after the deliverable lands. Complete and exit.
|
|
60
|
-
|
|
61
|
-
**Why:** Even at the safe ≤270s window, if your last meaningful work was a shipping verb ("📤 PR #N pushed", "✅ Committed", "📌 Review posted") and you `ScheduleWakeup` to "wait for CI" or "monitor merge", the heartbeat reaper still treats your suspended session as dead. The task auto-fails with `failureReason: "Auto-failed by heartbeat: worker session not found (no active session for task)"` even though your work shipped.
|
|
62
|
-
|
|
63
|
-
**Confirmed incidents (2026-05-03):**
|
|
64
|
-
- `aa8a8eb7` Picateclas (PR #415 db-query) — `📤 PR #415 pushed` at 11:20:53 UTC, reaped at 11:31:57 UTC after 4.5min wakeup. Task auto-failed; PR was already pushed, reviewed, merged.
|
|
65
|
-
- `48460149` and `6d684da4` (May 1, bump-pr workflow) — both reaped during ScheduleWakeup post-rebase poll.
|
|
66
|
-
- Reviewer review-pr tasks `8d1320a6`/`6a17ff00` — same reaper pattern, but legitimate (mid-review, not post-shipping).
|
|
67
|
-
|
|
68
|
-
**Do this instead — choose ONE based on context:**
|
|
69
|
-
|
|
70
|
-
1. **Workflow-driven tasks (workflowRunId is set):** Call `store-progress` with `status: "completed"` and the deliverable info, then exit. The workflow's next node will pick up CI/merge state on its own poll cadence. Do NOT keep the worker session alive to babysit it.
|
|
71
|
-
|
|
72
|
-
2. **Slack-driven tasks needing CI confirmation:** Reply to the Slack thread with the PR URL + "CI in flight, will update if red" and complete the task. Lead will spawn a follow-up if CI goes red. Do NOT wait in-process.
|
|
73
|
-
|
|
74
|
-
3. **If you genuinely must wait in-process** (rare): use `sleep 240` in Bash with `store-progress` every iteration, NOT `ScheduleWakeup`. ScheduleWakeup suspends the session; Bash sleep keeps it active.
|
|
75
|
-
|
|
76
|
-
**The mental model:** ScheduleWakeup is for "I'm in the middle of work and need to wait briefly." It is NOT for "I'm done shipping but want to confirm downstream state." Once you've shipped, exit.
|
|
77
|
-
|
|
78
|
-
**Memory reference:** `heartbeat-reaper-after-shipping-pattern-2026-05-04`.
|
|
79
|
-
|
|
80
|
-
## Rule 7 — External async-API jobs (Enginy actions, Browser-Use, large lead pulls): fire-then-followup, never block one session for 30+ min
|
|
81
|
-
|
|
82
|
-
**Why:** A worker session is not a durable job runner. Holding it open to poll a slow external async API for tens of minutes looks like a stalled worker — the heartbeat reaper kills it even when credits/work are in flight. This is the same reaper as Rules 1/3/6, but the trigger is a *regular* (often Slack/MCP-originated) task with a long foreground OR background poll loop, not a ScheduleWakeup.
|
|
83
|
-
|
|
84
|
-
**Confirmed incident (2026-05-26):** Enginy founder-pull (Researcher, `9a6e5e96`, source:mcp) auto-failed at ~41 min — `failureReason: "Auto-failed by heartbeat: worker session heartbeat is stale (likely crashed)"`. 15 credits spent, 369 companies queued across 3 actions, a "guarded background poll" running — but the session died before collect+filter+deliver, so the spend produced no delivered artifact. Two sibling Enginy pulls (`7e90ca44`, `19670e93`) died the same way the same day.
|
|
85
|
-
|
|
86
|
-
**Do this instead:**
|
|
87
|
-
1. Fire the async actions (Enginy `actions`, Browser-Use tasks, etc.).
|
|
88
|
-
2. `store-progress` the action/task IDs + destination list IDs + a one-line resume recipe.
|
|
89
|
-
3. Persist the same to agent-fs (or a memory file) so it survives a crash.
|
|
90
|
-
4. Complete, or let Lead schedule a follow-up that picks up the IDs and does the (cheap, idempotent) collect+filter+dedup+deliver in a fresh session. The collect/filter steps are free and re-runnable.
|
|
91
|
-
|
|
92
|
-
**Lead routing implication:** when delegating a task with a >20-min external poll, split it into a "fire" task + a "collect+deliver" follow-up, or instruct the worker to use fire-then-followup. Don't dispatch one long blocking task and expect a single session to survive the wait.
|
|
93
|
-
|
|
94
|
-
**Memory reference:** `long-running-external-poll-session-crash-2026-05-27`, `enginy-search-leads-no-keyword-filter-gotcha-2026-05-27`.
|
|
95
|
-
|