opencode-swarm-plugin 0.42.6 → 0.42.8
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/.changeset/swarm-insights-data-layer.md +63 -0
- package/.hive/issues.jsonl +11 -0
- package/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +51 -0
- package/README.md +147 -0
- package/bin/swarm.ts +4 -4
- package/dist/swarm-insights.d.ts +80 -3
- package/dist/swarm-insights.d.ts.map +1 -1
- package/examples/plugin-wrapper-template.ts +30 -0
- package/package.json +1 -1
- package/src/swarm-insights.ts +116 -3
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
"opencode-swarm-plugin": minor
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## 🧠 Swarm Insights: Data-Driven Decomposition
|
|
6
|
+
|
|
7
|
+
> "It should allow the learner both to reflect on the quality of found solutions so that more effective cognitive schemata can be induced (including discriminations and generalizations) or further elaborated."
|
|
8
|
+
>
|
|
9
|
+
> — *Training Complex Cognitive Skills: A Four-Component Instructional Design Model for Technical Training*
|
|
10
|
+
|
|
11
|
+
**What changed:**
|
|
12
|
+
|
|
13
|
+
New data layer (`swarm-insights.ts`) aggregates learnings from swarm coordination events to inform future decompositions. Coordinators and workers now get concise, context-efficient summaries injected into their prompts.
|
|
14
|
+
|
|
15
|
+
**Key exports:**
|
|
16
|
+
|
|
17
|
+
- `getStrategyInsights(swarmMail, task)` - Strategy success rates and recommendations
|
|
18
|
+
- Queries `subtask_outcome` events, calculates win/loss ratios
|
|
19
|
+
- Returns: `{ strategy, successRate, totalAttempts, recommendation }`
|
|
20
|
+
- Powers coordinator strategy selection with empirical data
|
|
21
|
+
|
|
22
|
+
- `getFileInsights(swarmMail, files)` - File-specific gotchas from past failures
|
|
23
|
+
- Identifies files with high failure rates
|
|
24
|
+
- Returns: `{ file, failureCount, lastFailure, gotchas[] }`
|
|
25
|
+
- Workers see warnings about tricky files before touching them
|
|
26
|
+
|
|
27
|
+
- `getPatternInsights(swarmMail)` - Common failure patterns and anti-patterns
|
|
28
|
+
- Detects recurring error types (type_error, timeout, conflict, test_failure)
|
|
29
|
+
- Returns: `{ pattern, frequency, recommendation }`
|
|
30
|
+
- Surfaces systemic issues for proactive prevention
|
|
31
|
+
|
|
32
|
+
- `formatInsightsForPrompt(bundle, options)` - Context-aware formatting
|
|
33
|
+
- Token budget enforcement (default 500 tokens, ~2000 chars)
|
|
34
|
+
- Prioritizes top 3 strategies, 5 files, 3 patterns
|
|
35
|
+
- Clean markdown output for prompt injection
|
|
36
|
+
|
|
37
|
+
- `getCachedInsights(swarmMail, cacheKey, computeFn)` - 5-minute TTL caching
|
|
38
|
+
- Prevents redundant queries during active swarms
|
|
39
|
+
- Transparent cache miss fallback
|
|
40
|
+
|
|
41
|
+
**Why it matters:**
|
|
42
|
+
|
|
43
|
+
Before this, coordinators decomposed tasks blind to past failures. "Split by file type" might have failed 8 times, but the coordinator would try it again. Workers would touch `auth/tokens.ts` without knowing it caused 3 prior failures.
|
|
44
|
+
|
|
45
|
+
Now:
|
|
46
|
+
- **Better decomposition**: Coordinator prompts show strategy success rates (e.g., "file-based: 85% success, feature-based: 40% - avoid")
|
|
47
|
+
- **Fewer repeated mistakes**: Workers see file-specific warnings before editing
|
|
48
|
+
- **Compounding learning**: Each swarm completion feeds the insights engine, improving future decompositions
|
|
49
|
+
- **Context-efficient**: Hard token caps prevent insights from dominating prompt budgets
|
|
50
|
+
|
|
51
|
+
The swarm now learns from its mistakes, not just records them.
|
|
52
|
+
|
|
53
|
+
**Data sources:**
|
|
54
|
+
- Event store: `subtask_outcome`, `eval_finalized` events
|
|
55
|
+
- Semantic memory: File-specific learnings (TODO: full integration)
|
|
56
|
+
- Anti-pattern registry: Detection and inversion rules
|
|
57
|
+
|
|
58
|
+
**Integration points:**
|
|
59
|
+
- Coordinator prompts: Inject strategy insights during decomposition
|
|
60
|
+
- Worker prompts: Inject file insights when subtasks are spawned
|
|
61
|
+
- Learning layer: Confidence decay, pattern maturity, implicit feedback scoring
|
|
62
|
+
|
|
63
|
+
This is the foundation for adaptive swarm intelligence - decomposition that gets smarter with every task completed.
|
package/.hive/issues.jsonl
CHANGED
|
@@ -111,3 +111,14 @@
|
|
|
111
111
|
{"id":"opencode-swarm-plugin--ys7z8-mjm7elm2poh","title":"Create swarm-insights data layer","description":"Create a data layer that aggregates insights for prompt injection.\n\nFile: src/swarm-insights.ts (NEW)\n\nImplementation:\n1. getStrategyInsights(task) - success rates by strategy for similar tasks\n2. getFileInsights(files) - past issues, gotchas for specific files\n3. getPatternInsights() - common failure patterns, anti-patterns\n4. Cache results to avoid repeated queries\n5. Add tests in swarm-insights.test.ts","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-26T01:39:28.874Z","updated_at":"2025-12-26T01:57:17.504Z","closed_at":"2025-12-26T01:57:17.504Z","dependencies":[],"labels":[],"comments":[]}
|
|
112
112
|
{"id":"opencode-swarm-plugin--ys7z8-mjm7eo34l57","title":"Inject insights into coordinator prompts","description":"Inject aggregated insights into coordinator prompts before decomposition.\n\nFile: src/swarm-prompts.ts\n\nImplementation:\n1. Call getStrategyInsights() in swarm_plan_prompt\n2. Add \"## Historical Insights\" section to prompt\n3. Include: strategy success rates, common pitfalls, recommendations\n4. Keep injection concise (<500 tokens)\n5. Add tests verifying injection","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-26T01:39:32.080Z","updated_at":"2025-12-26T02:03:27.468Z","closed_at":"2025-12-26T02:03:27.468Z","dependencies":[],"labels":[],"comments":[]}
|
|
113
113
|
{"id":"opencode-swarm-plugin--ys7z8-mjm7eq8o1oq","title":"Inject insights into worker prompts","description":"Inject file-specific insights into worker prompts.\n\nFile: src/swarm-prompts.ts\n\nImplementation:\n1. Call getFileInsights(files) in swarm_spawn_subtask\n2. Add \"## File-Specific Gotchas\" section to worker prompt\n3. Include: past bugs in these files, known issues, patterns\n4. Query semantic-memory for relevant learnings\n5. Keep injection concise (<300 tokens per file)\n6. Add tests verifying injection","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-26T01:39:34.872Z","updated_at":"2025-12-26T02:08:10.131Z","closed_at":"2025-12-26T02:08:10.131Z","dependencies":[],"labels":[],"comments":[]}
|
|
114
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmadcpu98d","title":"Document swarm-insights layer + CLI help + plugin template","description":"Full documentation for the new swarm-insights data layer:\n- README.md: Add swarm-insights architecture section\n- CLI help: Update swarm stats/history descriptions\n- Plugin template: Add swarm-insights tool descriptions\n- AGENTS.md: Document insights tools for agents\n- JSDoc: Ensure swarm-insights.ts has complete docs\n- Changeset: Document the new feature for release","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-26T03:02:29.538Z","updated_at":"2025-12-26T03:02:29.538Z","dependencies":[],"labels":[],"comments":[]}
|
|
115
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmadcq6aib","title":"Update CLI help text for stats/history commands","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-26T03:02:29.550Z","updated_at":"2025-12-26T03:02:29.550Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmadcpu98d","dependencies":[],"labels":[],"comments":[]}
|
|
116
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmadcq85et","title":"Add swarm-insights tools to plugin-wrapper-template.ts","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-26T03:02:29.552Z","updated_at":"2025-12-26T03:02:29.552Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmadcpu98d","dependencies":[],"labels":[],"comments":[]}
|
|
117
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmadcqag0y","title":"Ensure swarm-insights.ts has complete JSDoc","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-26T03:02:29.554Z","updated_at":"2025-12-26T03:02:29.554Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmadcpu98d","dependencies":[],"labels":[],"comments":[]}
|
|
118
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmadcqcklk","title":"Create changeset for swarm-insights feature","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-26T03:02:29.556Z","updated_at":"2025-12-26T03:02:29.556Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmadcpu98d","dependencies":[],"labels":[],"comments":[]}
|
|
119
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmadcq2s4l","title":"Update README.md with swarm-insights architecture","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-26T03:02:29.546Z","updated_at":"2025-12-26T03:12:28.691Z","closed_at":"2025-12-26T03:12:28.691Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmadcpu98d","dependencies":[],"labels":[],"comments":[]}
|
|
120
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmavq7f31x","title":"ADR-010: CASS Inhousing Feasibility Study","description":"Deep dive into CASS (coding_agent_session_search) to determine if we should bring cross-agent session search in-house, eliminating the Python dependency.\n\n**Deliverables:**\n1. Full architecture analysis of CASS\n2. Gap analysis vs our semantic-memory\n3. Agent session format survey\n4. ADR-010 with TDD implementation plan, docs, and observability\n\n**Success Criteria:**\n- Clear recommendation: inhouse vs keep vs hybrid\n- If inhouse: schema design, TDD test plan, effort estimate\n- Observability hooks designed (aligns with ADR-005)\n- Migration path documented","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-12-26T03:16:46.827Z","updated_at":"2025-12-26T03:29:01.651Z","closed_at":"2025-12-26T03:29:01.651Z","dependencies":[],"labels":[],"comments":[]}
|
|
121
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmavq7m7od","title":"T1: CASS Architecture Deep Dive","status":"closed","priority":0,"issue_type":"task","created_at":"2025-12-26T03:16:46.834Z","updated_at":"2025-12-26T03:22:05.154Z","closed_at":"2025-12-26T03:22:05.154Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmavq7f31x","dependencies":[],"labels":[],"comments":[]}
|
|
122
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmavq7pz17","title":"T2: Semantic Memory Gap Analysis","status":"closed","priority":0,"issue_type":"task","created_at":"2025-12-26T03:16:46.837Z","updated_at":"2025-12-26T03:22:06.745Z","closed_at":"2025-12-26T03:22:06.745Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmavq7f31x","dependencies":[],"labels":[],"comments":[]}
|
|
123
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmavq7rt9z","title":"T3: Agent Session Format Survey","status":"closed","priority":0,"issue_type":"task","created_at":"2025-12-26T03:16:46.839Z","updated_at":"2025-12-26T03:22:08.486Z","closed_at":"2025-12-26T03:22:08.486Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmavq7f31x","dependencies":[],"labels":[],"comments":[]}
|
|
124
|
+
{"id":"opencode-swarm-plugin--ys7z8-mjmavq7va7b","title":"T4: Write ADR-010 with TDD Plan","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-26T03:16:46.843Z","updated_at":"2025-12-26T03:28:59.753Z","closed_at":"2025-12-26T03:28:59.753Z","parent_id":"opencode-swarm-plugin--ys7z8-mjmavq7f31x","dependencies":[],"labels":[],"comments":[]}
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
$ bun build ./src/index.ts --outdir ./dist --target node --external @electric-sql/pglite --external swarm-mail --external vitest --external @vitest/ui --external lightningcss && bun build ./src/plugin.ts --outfile ./dist/plugin.js --target node --external @electric-sql/pglite --external swarm-mail --external vitest --external @vitest/ui --external lightningcss && tsc
|
|
2
|
-
Bundled 1349 modules in
|
|
2
|
+
Bundled 1349 modules in 204ms
|
|
3
3
|
|
|
4
4
|
index.js 4.34 MB (entry point)
|
|
5
5
|
|
|
6
|
-
Bundled 1350 modules in
|
|
6
|
+
Bundled 1350 modules in 235ms
|
|
7
7
|
|
|
8
8
|
plugin.js 4.31 MB (entry point)
|
|
9
9
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# opencode-swarm-plugin
|
|
2
2
|
|
|
3
|
+
## 0.42.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`a797bea`](https://github.com/joelhooks/swarm-tools/commit/a797bea871e5d698ebb38b41f47ff07faa7c108b) Thanks [@joelhooks](https://github.com/joelhooks)! - ## 🔗 Tweets Now Link to the Right PR
|
|
8
|
+
|
|
9
|
+
Release tweets were linking to the wrong PR. The old logic grabbed "most recent merged PR that isn't a version bump" - but with the new `release:` prefix on version PRs, it was picking up stale PRs.
|
|
10
|
+
|
|
11
|
+
**Fixed:** Now uses `github.sha` to find the exact PR that triggered the workflow. No more guessing.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
BEFORE: gh pr list --limit 5 --jq 'filter...' → wrong PR
|
|
15
|
+
AFTER: gh pr list --search "${{ github.sha }}" → triggering PR
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 0.42.7
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- [`7a6a4a3`](https://github.com/joelhooks/swarm-tools/commit/7a6a4a37c4ea753de359dac5062d11186ee98ccd) Thanks [@joelhooks](https://github.com/joelhooks)! - ## 📐 Swarm Insights Gets Its Blueprint
|
|
23
|
+
|
|
24
|
+
> _"The major documentation tool for information architecture... diagrams."_
|
|
25
|
+
> — Jesse James Garrett, The Elements of User Experience
|
|
26
|
+
|
|
27
|
+
The README now shows you how the swarm learns, not just that it does.
|
|
28
|
+
|
|
29
|
+
**Added:**
|
|
30
|
+
|
|
31
|
+
- ASCII diagram of the swarm learning loop (task → decompose → execute → complete → insights → repeat)
|
|
32
|
+
- Data flow architecture showing Event Store → Insights Aggregation → Agents
|
|
33
|
+
- Full API reference with TypeScript examples for coordinators and workers
|
|
34
|
+
- Token budget table (500 for coordinators, 300 for workers)
|
|
35
|
+
- Recommendation threshold table (≥80% = good, <40% = AVOID)
|
|
36
|
+
- Data sources table (Event Store, Semantic Memory, Anti-Pattern Registry)
|
|
37
|
+
|
|
38
|
+
**Why it matters:**
|
|
39
|
+
Diagrams > prose for architecture. Now you can see the feedback loop at a glance instead of reading paragraphs. The API examples are copy-pasteable.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
43
|
+
│ TASK │───▶│ INSIGHTS │───▶│ BETTER │
|
|
44
|
+
│ │ │ LAYER │ │ SWARMS │
|
|
45
|
+
└──────────┘ └──────────┘ └──────────┘
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- [`0ad79d5`](https://github.com/joelhooks/swarm-tools/commit/0ad79d57cd119517a8e04d0e74b4909f20a7f0be) Thanks [@joelhooks](https://github.com/joelhooks)! - ## Release Tweets Link to Source, PR Titles Get Smart
|
|
49
|
+
|
|
50
|
+
- Tweets now include link to the feature PR (or commit if pushed direct to main)
|
|
51
|
+
- Version bump PRs get AI-generated titles from changeset content via Opus
|
|
52
|
+
- No more "chore: update versions" - titles describe what actually shipped
|
|
53
|
+
|
|
3
54
|
## 0.42.6
|
|
4
55
|
|
|
5
56
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -49,6 +49,152 @@ Done. You're swarming.
|
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
|
+
## How Swarms Get Smarter Over Time
|
|
53
|
+
|
|
54
|
+
Swarms learn from outcomes. Every completed subtask records what worked and what failed - then injects that wisdom into future prompts.
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
58
|
+
│ SWARM LEARNING LOOP │
|
|
59
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
60
|
+
│ │
|
|
61
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
62
|
+
│ │ TASK │───▶│ DECOMPOSE│───▶│ EXECUTE │───▶│ COMPLETE │ │
|
|
63
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
64
|
+
│ ▲ │ │ │ │
|
|
65
|
+
│ │ ▼ ▼ ▼ │
|
|
66
|
+
│ │ ┌─────────────────────────────────────────┐ │
|
|
67
|
+
│ │ │ EVENT STORE │ │
|
|
68
|
+
│ │ │ subtask_outcome, eval_finalized, ... │ │
|
|
69
|
+
│ │ └─────────────────────────────────────────┘ │
|
|
70
|
+
│ │ │ │
|
|
71
|
+
│ │ ▼ │
|
|
72
|
+
│ │ ┌─────────────────────────────────────────┐ │
|
|
73
|
+
│ │ │ INSIGHTS LAYER │ │
|
|
74
|
+
│ │ │ Strategy | File | Pattern insights │ │
|
|
75
|
+
│ │ └─────────────────────────────────────────┘ │
|
|
76
|
+
│ │ │ │
|
|
77
|
+
│ └───────────────────────────┘ │
|
|
78
|
+
│ (injected into next decomposition) │
|
|
79
|
+
│ │
|
|
80
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### The Insights Layer
|
|
84
|
+
|
|
85
|
+
**swarm-insights** (`src/swarm-insights.ts`) is the data aggregation layer that queries historical outcomes and semantic memory to provide context-efficient summaries for coordinator and worker agents.
|
|
86
|
+
|
|
87
|
+
**Three insight types:**
|
|
88
|
+
|
|
89
|
+
| Type | What It Tracks | Used By |
|
|
90
|
+
|------|----------------|---------|
|
|
91
|
+
| **StrategyInsight** | Success rates by decomposition strategy (file-based, feature-based, risk-based) | Coordinators |
|
|
92
|
+
| **FileInsight** | File-specific failure patterns and gotchas from past subtasks | Workers |
|
|
93
|
+
| **PatternInsight** | Common failure patterns across all subtasks (type errors, timeouts, conflicts) | Coordinators |
|
|
94
|
+
|
|
95
|
+
### Architecture
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
99
|
+
│ DATA FLOW │
|
|
100
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
101
|
+
│ │
|
|
102
|
+
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
103
|
+
│ │ Event Store │ │ Semantic Memory │ │ Anti-Patterns │ │
|
|
104
|
+
│ │ (libSQL) │ │ (Ollama/FTS) │ │ (Registry) │ │
|
|
105
|
+
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
|
|
106
|
+
│ │ │ │ │
|
|
107
|
+
│ ▼ ▼ ▼ │
|
|
108
|
+
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
|
109
|
+
│ │ INSIGHTS AGGREGATION │ │
|
|
110
|
+
│ │ │ │
|
|
111
|
+
│ │ getStrategyInsights() getFileInsights() getPatternInsights() │ │
|
|
112
|
+
│ │ │ │ │ │ │
|
|
113
|
+
│ │ └──────────────────────┼────────────────────┘ │ │
|
|
114
|
+
│ │ ▼ │ │
|
|
115
|
+
│ │ formatInsightsForPrompt() │ │
|
|
116
|
+
│ │ (token-budgeted output) │ │
|
|
117
|
+
│ └─────────────────────────────────────────────────────────────────┘ │
|
|
118
|
+
│ │ │
|
|
119
|
+
│ ┌───────────────────────┼───────────────────────┐ │
|
|
120
|
+
│ ▼ ▼ ▼ │
|
|
121
|
+
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
122
|
+
│ │ Coordinator │ │ Worker │ │ Worker │ │
|
|
123
|
+
│ │ (strategy + │ │ (file-specific │ │ (file-specific │ │
|
|
124
|
+
│ │ patterns) │ │ gotchas) │ │ gotchas) │ │
|
|
125
|
+
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
126
|
+
│ │
|
|
127
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### API Reference
|
|
131
|
+
|
|
132
|
+
**For coordinators** (strategy selection):
|
|
133
|
+
```typescript
|
|
134
|
+
import { getStrategyInsights, getPatternInsights, formatInsightsForPrompt } from "opencode-swarm-plugin";
|
|
135
|
+
|
|
136
|
+
const strategies = await getStrategyInsights(swarmMail, task);
|
|
137
|
+
// Returns: [{ strategy: "file-based", successRate: 85.5, totalAttempts: 12, recommendation: "..." }]
|
|
138
|
+
|
|
139
|
+
const patterns = await getPatternInsights(swarmMail);
|
|
140
|
+
// Returns: [{ pattern: "type_error", frequency: 5, recommendation: "Add type annotations" }]
|
|
141
|
+
|
|
142
|
+
const summary = formatInsightsForPrompt({ strategies, patterns }, { maxTokens: 500 });
|
|
143
|
+
// Injected into decomposition prompt
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**For workers** (file-specific context):
|
|
147
|
+
```typescript
|
|
148
|
+
import { getFileInsights, formatInsightsForPrompt } from "opencode-swarm-plugin";
|
|
149
|
+
|
|
150
|
+
const fileInsights = await getFileInsights(swarmMail, ["src/auth.ts", "src/db.ts"]);
|
|
151
|
+
// Returns: [{ file: "src/auth.ts", failureCount: 3, lastFailure: "2025-12-20T...", gotchas: [...] }]
|
|
152
|
+
|
|
153
|
+
const summary = formatInsightsForPrompt({ files: fileInsights }, { maxTokens: 300 });
|
|
154
|
+
// Injected into worker prompt
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Caching** (5-minute TTL):
|
|
158
|
+
```typescript
|
|
159
|
+
import { getCachedInsights, clearInsightsCache } from "opencode-swarm-plugin";
|
|
160
|
+
|
|
161
|
+
const insights = await getCachedInsights(swarmMail, "strategies:auth-task", async () => ({
|
|
162
|
+
strategies: await getStrategyInsights(swarmMail, "add auth"),
|
|
163
|
+
}));
|
|
164
|
+
|
|
165
|
+
clearInsightsCache(); // Force fresh computation
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Token Budgets
|
|
169
|
+
|
|
170
|
+
| Agent Type | Max Tokens | What's Included |
|
|
171
|
+
|------------|------------|-----------------|
|
|
172
|
+
| Coordinator | 500 | Top 3 strategies + top 3 patterns |
|
|
173
|
+
| Worker | 300 | Top 5 files with gotchas |
|
|
174
|
+
|
|
175
|
+
### Recommendation Thresholds
|
|
176
|
+
|
|
177
|
+
Strategy success rates map to recommendations:
|
|
178
|
+
|
|
179
|
+
| Success Rate | Recommendation |
|
|
180
|
+
|--------------|----------------|
|
|
181
|
+
| ≥80% | "performing well" |
|
|
182
|
+
| 60-79% | "moderate - monitor for issues" |
|
|
183
|
+
| 40-59% | "low success - consider alternatives" |
|
|
184
|
+
| <40% | "AVOID - high failure rate" |
|
|
185
|
+
|
|
186
|
+
### Data Sources
|
|
187
|
+
|
|
188
|
+
| Source | What It Provides | Query Pattern |
|
|
189
|
+
|--------|------------------|---------------|
|
|
190
|
+
| Event Store | `subtask_outcome` events with strategy, success, files_touched, error_type | SQL aggregation |
|
|
191
|
+
| Semantic Memory | File-specific learnings from past debugging | Semantic search (TODO) |
|
|
192
|
+
| Anti-Pattern Registry | Patterns with >60% failure rate | Direct lookup |
|
|
193
|
+
|
|
194
|
+
**See [swarmtools.ai/docs/insights](https://swarmtools.ai/docs) for full details.**
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
52
198
|
## Optional But Recommended
|
|
53
199
|
|
|
54
200
|
### Semantic Memory (for pattern learning)
|
|
@@ -209,6 +355,7 @@ src/
|
|
|
209
355
|
├── swarm-mail.ts # Agent coordination tools
|
|
210
356
|
├── swarm-orchestrate.ts # Coordinator logic (spawns workers)
|
|
211
357
|
├── swarm-decompose.ts # Task decomposition strategies
|
|
358
|
+
├── swarm-insights.ts # Historical insights aggregation (strategy/file/pattern)
|
|
212
359
|
├── swarm-review.ts # Review gate for completed work
|
|
213
360
|
├── skills.ts # Knowledge injection system
|
|
214
361
|
├── learning.ts # Pattern maturity, outcomes
|
package/bin/swarm.ts
CHANGED
|
@@ -2522,8 +2522,8 @@ ${cyan("Commands:")}
|
|
|
2522
2522
|
--port <n> Port to listen on (default: 3001)
|
|
2523
2523
|
swarm cells List or get cells from database (replaces 'swarm tool hive_query')
|
|
2524
2524
|
swarm log View swarm logs with filtering
|
|
2525
|
-
swarm stats Show swarm health metrics
|
|
2526
|
-
swarm history Show recent swarm activity timeline
|
|
2525
|
+
swarm stats Show swarm health metrics powered by swarm-insights (strategy success rates, patterns)
|
|
2526
|
+
swarm history Show recent swarm activity timeline with insights data
|
|
2527
2527
|
swarm eval Eval-driven development commands
|
|
2528
2528
|
swarm update Update to latest version
|
|
2529
2529
|
swarm version Show version and banner
|
|
@@ -2559,10 +2559,10 @@ ${cyan("Log Viewing:")}
|
|
|
2559
2559
|
swarm log sessions --json Raw JSON output for jq
|
|
2560
2560
|
|
|
2561
2561
|
${cyan("Stats & History:")}
|
|
2562
|
-
swarm stats Show swarm health metrics (last 7 days)
|
|
2562
|
+
swarm stats Show swarm health metrics powered by swarm-insights (last 7 days)
|
|
2563
2563
|
swarm stats --since 24h Show stats for custom time period
|
|
2564
2564
|
swarm stats --json Output as JSON for scripting
|
|
2565
|
-
swarm history Show recent
|
|
2565
|
+
swarm history Show recent swarm activity timeline with insights data (last 10)
|
|
2566
2566
|
swarm history --limit 20 Show more swarms
|
|
2567
2567
|
swarm history --status success Filter by success/failed/in_progress
|
|
2568
2568
|
swarm history --strategy file-based Filter by decomposition strategy
|
package/dist/swarm-insights.d.ts
CHANGED
|
@@ -40,6 +40,19 @@ export interface FormatOptions {
|
|
|
40
40
|
*
|
|
41
41
|
* Queries the event store for subtask_outcome events and calculates
|
|
42
42
|
* success rates by strategy. Returns recommendations based on historical data.
|
|
43
|
+
*
|
|
44
|
+
* @param swarmMail - SwarmMail adapter for database access
|
|
45
|
+
* @param _task - Task description (currently unused, reserved for future filtering)
|
|
46
|
+
* @returns Promise resolving to array of strategy insights with success rates and recommendations
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const insights = await getStrategyInsights(swarmMail, "Add authentication");
|
|
51
|
+
* // Returns: [
|
|
52
|
+
* // { strategy: "file-based", successRate: 85.5, totalAttempts: 12, recommendation: "..." },
|
|
53
|
+
* // { strategy: "feature-based", successRate: 65.0, totalAttempts: 8, recommendation: "..." }
|
|
54
|
+
* // ]
|
|
55
|
+
* ```
|
|
43
56
|
*/
|
|
44
57
|
export declare function getStrategyInsights(swarmMail: SwarmMailAdapter, _task: string): Promise<StrategyInsight[]>;
|
|
45
58
|
/**
|
|
@@ -47,6 +60,18 @@ export declare function getStrategyInsights(swarmMail: SwarmMailAdapter, _task:
|
|
|
47
60
|
*
|
|
48
61
|
* Queries the event store for failures involving these files and
|
|
49
62
|
* semantic memory for file-specific gotchas.
|
|
63
|
+
*
|
|
64
|
+
* @param swarmMail - SwarmMail adapter for database access
|
|
65
|
+
* @param files - Array of file paths to analyze
|
|
66
|
+
* @returns Promise resolving to array of file-specific insights including failure counts and gotchas
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const insights = await getFileInsights(swarmMail, ["src/auth.ts", "src/db.ts"]);
|
|
71
|
+
* // Returns: [
|
|
72
|
+
* // { file: "src/auth.ts", failureCount: 3, lastFailure: "2025-12-20T10:30:00Z", gotchas: [...] }
|
|
73
|
+
* // ]
|
|
74
|
+
* ```
|
|
50
75
|
*/
|
|
51
76
|
export declare function getFileInsights(swarmMail: SwarmMailAdapter, files: string[]): Promise<FileInsight[]>;
|
|
52
77
|
/**
|
|
@@ -54,6 +79,18 @@ export declare function getFileInsights(swarmMail: SwarmMailAdapter, files: stri
|
|
|
54
79
|
*
|
|
55
80
|
* Analyzes event store for recurring failure patterns and
|
|
56
81
|
* queries the anti-pattern registry.
|
|
82
|
+
*
|
|
83
|
+
* @param swarmMail - SwarmMail adapter for database access
|
|
84
|
+
* @returns Promise resolving to array of pattern insights with frequency and recommendations
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const patterns = await getPatternInsights(swarmMail);
|
|
89
|
+
* // Returns: [
|
|
90
|
+
* // { pattern: "type_error", frequency: 5, recommendation: "Add explicit type annotations and null checks" },
|
|
91
|
+
* // { pattern: "timeout", frequency: 3, recommendation: "Consider breaking into smaller tasks" }
|
|
92
|
+
* // ]
|
|
93
|
+
* ```
|
|
57
94
|
*/
|
|
58
95
|
export declare function getPatternInsights(swarmMail: SwarmMailAdapter): Promise<PatternInsight[]>;
|
|
59
96
|
/**
|
|
@@ -62,17 +99,57 @@ export declare function getPatternInsights(swarmMail: SwarmMailAdapter): Promise
|
|
|
62
99
|
* Produces a concise, context-efficient summary suitable for
|
|
63
100
|
* inclusion in coordinator or worker prompts.
|
|
64
101
|
*
|
|
65
|
-
* @param bundle - Insights
|
|
66
|
-
* @param options - Formatting options (maxTokens)
|
|
67
|
-
* @returns Formatted string for prompt injection
|
|
102
|
+
* @param bundle - Insights bundle containing strategies, files, and patterns
|
|
103
|
+
* @param options - Formatting options (maxTokens defaults to 500)
|
|
104
|
+
* @returns Formatted markdown string for prompt injection, or empty string if no insights
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const bundle = {
|
|
109
|
+
* strategies: [{ strategy: "file-based", successRate: 85.5, totalAttempts: 12, recommendation: "..." }],
|
|
110
|
+
* files: [{ file: "src/auth.ts", failureCount: 2, lastFailure: null, gotchas: [] }],
|
|
111
|
+
* patterns: [{ pattern: "type_error", frequency: 3, recommendation: "Add type checks" }]
|
|
112
|
+
* };
|
|
113
|
+
* const formatted = formatInsightsForPrompt(bundle, { maxTokens: 300 });
|
|
114
|
+
* // Returns formatted markdown with top 3 strategies, top 5 files, top 3 patterns
|
|
115
|
+
* ```
|
|
68
116
|
*/
|
|
69
117
|
export declare function formatInsightsForPrompt(bundle: InsightsBundle, options?: FormatOptions): string;
|
|
70
118
|
/**
|
|
71
119
|
* Get cached insights or compute fresh ones.
|
|
120
|
+
*
|
|
121
|
+
* Simple in-memory cache with 5-minute TTL to avoid redundant database queries.
|
|
122
|
+
*
|
|
123
|
+
* @param _swarmMail - SwarmMail adapter (currently unused, reserved for future cache invalidation)
|
|
124
|
+
* @param cacheKey - Unique key for caching (e.g., "strategies:task-name" or "files:src/auth.ts")
|
|
125
|
+
* @param computeFn - Function to compute fresh insights if cache miss
|
|
126
|
+
* @returns Promise resolving to cached or freshly computed insights bundle
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const insights = await getCachedInsights(
|
|
131
|
+
* swarmMail,
|
|
132
|
+
* "strategies:add-auth",
|
|
133
|
+
* async () => ({
|
|
134
|
+
* strategies: await getStrategyInsights(swarmMail, "add auth"),
|
|
135
|
+
* })
|
|
136
|
+
* );
|
|
137
|
+
* // First call: computes and caches. Subsequent calls within 5min: returns cached.
|
|
138
|
+
* ```
|
|
72
139
|
*/
|
|
73
140
|
export declare function getCachedInsights(_swarmMail: SwarmMailAdapter, cacheKey: string, computeFn: () => Promise<InsightsBundle>): Promise<InsightsBundle>;
|
|
74
141
|
/**
|
|
75
142
|
* Clear the insights cache.
|
|
143
|
+
*
|
|
144
|
+
* Useful for testing or forcing fresh insights computation.
|
|
145
|
+
*
|
|
146
|
+
* @returns void
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* clearInsightsCache();
|
|
151
|
+
* // All cached insights invalidated, next getCachedInsights() will recompute
|
|
152
|
+
* ```
|
|
76
153
|
*/
|
|
77
154
|
export declare function clearInsightsCache(): void;
|
|
78
155
|
//# sourceMappingURL=swarm-insights.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swarm-insights.d.ts","sourceRoot":"","sources":["../src/swarm-insights.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnD,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC9B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD
|
|
1
|
+
{"version":3,"file":"swarm-insights.d.ts","sourceRoot":"","sources":["../src/swarm-insights.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnD,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC9B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,mBAAmB,CACxC,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,EAAE,CAAC,CA+B5B;AAmCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,eAAe,CACpC,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,WAAW,EAAE,CAAC,CAsCxB;AAiCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,kBAAkB,CACvC,SAAS,EAAE,gBAAgB,GACzB,OAAO,CAAC,cAAc,EAAE,CAAC,CAkC3B;AAiCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,aAAkB,GACzB,MAAM,CA8CR;AAaD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,GACtC,OAAO,CAAC,cAAc,CAAC,CAazB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -1002,6 +1002,32 @@ const skills_execute = tool({
|
|
|
1002
1002
|
execute: (args, ctx) => execTool("skills_execute", args, ctx),
|
|
1003
1003
|
});
|
|
1004
1004
|
|
|
1005
|
+
// =============================================================================
|
|
1006
|
+
// Swarm Insights Tools
|
|
1007
|
+
// =============================================================================
|
|
1008
|
+
|
|
1009
|
+
const swarm_get_strategy_insights = tool({
|
|
1010
|
+
description: "Get strategy success rates for decomposition planning. Use this when planning task decomposition to see which strategies (file-based, feature-based, risk-based) have historically succeeded or failed. Returns success rates and recommendations based on past swarm outcomes.",
|
|
1011
|
+
args: {
|
|
1012
|
+
task: tool.schema.string().describe("Task description to analyze for strategy recommendation"),
|
|
1013
|
+
},
|
|
1014
|
+
execute: (args, ctx) => execTool("swarm_get_strategy_insights", args, ctx),
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
const swarm_get_file_insights = tool({
|
|
1018
|
+
description: "Get file-specific gotchas for worker context. Use this when assigning files to workers to warn them about historical failure patterns. Queries past outcomes and semantic memory for file-specific learnings (edge cases, common bugs, performance traps).",
|
|
1019
|
+
args: {
|
|
1020
|
+
files: tool.schema.array(tool.schema.string()).describe("File paths to get insights for"),
|
|
1021
|
+
},
|
|
1022
|
+
execute: (args, ctx) => execTool("swarm_get_file_insights", args, ctx),
|
|
1023
|
+
});
|
|
1024
|
+
|
|
1025
|
+
const swarm_get_pattern_insights = tool({
|
|
1026
|
+
description: "Get common failure patterns across swarms. Use this during planning or when debugging stuck swarms to see recurring anti-patterns (type errors, timeouts, conflicts, test failures). Returns top 5 most frequent failure patterns with recommendations.",
|
|
1027
|
+
args: {},
|
|
1028
|
+
execute: (args, ctx) => execTool("swarm_get_pattern_insights", args, ctx),
|
|
1029
|
+
});
|
|
1030
|
+
|
|
1005
1031
|
// =============================================================================
|
|
1006
1032
|
// Plugin Export
|
|
1007
1033
|
// =============================================================================
|
|
@@ -2034,6 +2060,10 @@ const SwarmPlugin: Plugin = async (
|
|
|
2034
2060
|
skills_init,
|
|
2035
2061
|
skills_add_script,
|
|
2036
2062
|
skills_execute,
|
|
2063
|
+
// Swarm Insights
|
|
2064
|
+
swarm_get_strategy_insights,
|
|
2065
|
+
swarm_get_file_insights,
|
|
2066
|
+
swarm_get_pattern_insights,
|
|
2037
2067
|
},
|
|
2038
2068
|
|
|
2039
2069
|
// Swarm-aware compaction hook with LLM-powered continuation prompts
|
package/package.json
CHANGED
package/src/swarm-insights.ts
CHANGED
|
@@ -55,6 +55,19 @@ export interface FormatOptions {
|
|
|
55
55
|
*
|
|
56
56
|
* Queries the event store for subtask_outcome events and calculates
|
|
57
57
|
* success rates by strategy. Returns recommendations based on historical data.
|
|
58
|
+
*
|
|
59
|
+
* @param swarmMail - SwarmMail adapter for database access
|
|
60
|
+
* @param _task - Task description (currently unused, reserved for future filtering)
|
|
61
|
+
* @returns Promise resolving to array of strategy insights with success rates and recommendations
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const insights = await getStrategyInsights(swarmMail, "Add authentication");
|
|
66
|
+
* // Returns: [
|
|
67
|
+
* // { strategy: "file-based", successRate: 85.5, totalAttempts: 12, recommendation: "..." },
|
|
68
|
+
* // { strategy: "feature-based", successRate: 65.0, totalAttempts: 8, recommendation: "..." }
|
|
69
|
+
* // ]
|
|
70
|
+
* ```
|
|
58
71
|
*/
|
|
59
72
|
export async function getStrategyInsights(
|
|
60
73
|
swarmMail: SwarmMailAdapter,
|
|
@@ -94,6 +107,19 @@ export async function getStrategyInsights(
|
|
|
94
107
|
|
|
95
108
|
/**
|
|
96
109
|
* Generate recommendation based on strategy and success rate.
|
|
110
|
+
*
|
|
111
|
+
* @param strategy - Strategy name (e.g., "file-based", "feature-based")
|
|
112
|
+
* @param successRate - Success rate percentage (0-100)
|
|
113
|
+
* @returns Recommendation string based on performance thresholds
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* getStrategyRecommendation("file-based", 85);
|
|
118
|
+
* // Returns: "file-based is performing well (85% success)"
|
|
119
|
+
*
|
|
120
|
+
* getStrategyRecommendation("feature-based", 35);
|
|
121
|
+
* // Returns: "AVOID feature-based - high failure rate (35%)"
|
|
122
|
+
* ```
|
|
97
123
|
*/
|
|
98
124
|
function getStrategyRecommendation(strategy: string, successRate: number): string {
|
|
99
125
|
if (successRate >= 80) {
|
|
@@ -117,6 +143,18 @@ function getStrategyRecommendation(strategy: string, successRate: number): strin
|
|
|
117
143
|
*
|
|
118
144
|
* Queries the event store for failures involving these files and
|
|
119
145
|
* semantic memory for file-specific gotchas.
|
|
146
|
+
*
|
|
147
|
+
* @param swarmMail - SwarmMail adapter for database access
|
|
148
|
+
* @param files - Array of file paths to analyze
|
|
149
|
+
* @returns Promise resolving to array of file-specific insights including failure counts and gotchas
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const insights = await getFileInsights(swarmMail, ["src/auth.ts", "src/db.ts"]);
|
|
154
|
+
* // Returns: [
|
|
155
|
+
* // { file: "src/auth.ts", failureCount: 3, lastFailure: "2025-12-20T10:30:00Z", gotchas: [...] }
|
|
156
|
+
* // ]
|
|
157
|
+
* ```
|
|
120
158
|
*/
|
|
121
159
|
export async function getFileInsights(
|
|
122
160
|
swarmMail: SwarmMailAdapter,
|
|
@@ -166,6 +204,17 @@ export async function getFileInsights(
|
|
|
166
204
|
*
|
|
167
205
|
* In a full implementation, this would query the semantic memory
|
|
168
206
|
* for file-specific learnings. For now, returns empty array.
|
|
207
|
+
*
|
|
208
|
+
* @param _swarmMail - SwarmMail adapter (currently unused)
|
|
209
|
+
* @param _file - File path to query learnings for
|
|
210
|
+
* @returns Promise resolving to array of gotcha strings (currently empty, TODO)
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const gotchas = await getFileGotchas(swarmMail, "src/auth.ts");
|
|
215
|
+
* // TODO: Will return semantic memory learnings like:
|
|
216
|
+
* // ["OAuth tokens need 5min buffer", "Always validate refresh token expiry"]
|
|
217
|
+
* ```
|
|
169
218
|
*/
|
|
170
219
|
async function getFileGotchas(
|
|
171
220
|
_swarmMail: SwarmMailAdapter,
|
|
@@ -186,6 +235,18 @@ async function getFileGotchas(
|
|
|
186
235
|
*
|
|
187
236
|
* Analyzes event store for recurring failure patterns and
|
|
188
237
|
* queries the anti-pattern registry.
|
|
238
|
+
*
|
|
239
|
+
* @param swarmMail - SwarmMail adapter for database access
|
|
240
|
+
* @returns Promise resolving to array of pattern insights with frequency and recommendations
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* const patterns = await getPatternInsights(swarmMail);
|
|
245
|
+
* // Returns: [
|
|
246
|
+
* // { pattern: "type_error", frequency: 5, recommendation: "Add explicit type annotations and null checks" },
|
|
247
|
+
* // { pattern: "timeout", frequency: 3, recommendation: "Consider breaking into smaller tasks" }
|
|
248
|
+
* // ]
|
|
249
|
+
* ```
|
|
189
250
|
*/
|
|
190
251
|
export async function getPatternInsights(
|
|
191
252
|
swarmMail: SwarmMailAdapter,
|
|
@@ -227,6 +288,18 @@ export async function getPatternInsights(
|
|
|
227
288
|
|
|
228
289
|
/**
|
|
229
290
|
* Generate recommendation for a failure pattern.
|
|
291
|
+
*
|
|
292
|
+
* @param errorType - Type of error pattern (e.g., "type_error", "timeout", "conflict")
|
|
293
|
+
* @returns Recommendation string for addressing the pattern
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* getPatternRecommendation("type_error");
|
|
298
|
+
* // Returns: "Add explicit type annotations and null checks"
|
|
299
|
+
*
|
|
300
|
+
* getPatternRecommendation("unknown_error");
|
|
301
|
+
* // Returns: "Address unknown_error issues"
|
|
302
|
+
* ```
|
|
230
303
|
*/
|
|
231
304
|
function getPatternRecommendation(errorType: string): string {
|
|
232
305
|
// Common patterns and their recommendations
|
|
@@ -250,9 +323,20 @@ function getPatternRecommendation(errorType: string): string {
|
|
|
250
323
|
* Produces a concise, context-efficient summary suitable for
|
|
251
324
|
* inclusion in coordinator or worker prompts.
|
|
252
325
|
*
|
|
253
|
-
* @param bundle - Insights
|
|
254
|
-
* @param options - Formatting options (maxTokens)
|
|
255
|
-
* @returns Formatted string for prompt injection
|
|
326
|
+
* @param bundle - Insights bundle containing strategies, files, and patterns
|
|
327
|
+
* @param options - Formatting options (maxTokens defaults to 500)
|
|
328
|
+
* @returns Formatted markdown string for prompt injection, or empty string if no insights
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```typescript
|
|
332
|
+
* const bundle = {
|
|
333
|
+
* strategies: [{ strategy: "file-based", successRate: 85.5, totalAttempts: 12, recommendation: "..." }],
|
|
334
|
+
* files: [{ file: "src/auth.ts", failureCount: 2, lastFailure: null, gotchas: [] }],
|
|
335
|
+
* patterns: [{ pattern: "type_error", frequency: 3, recommendation: "Add type checks" }]
|
|
336
|
+
* };
|
|
337
|
+
* const formatted = formatInsightsForPrompt(bundle, { maxTokens: 300 });
|
|
338
|
+
* // Returns formatted markdown with top 3 strategies, top 5 files, top 3 patterns
|
|
339
|
+
* ```
|
|
256
340
|
*/
|
|
257
341
|
export function formatInsightsForPrompt(
|
|
258
342
|
bundle: InsightsBundle,
|
|
@@ -318,6 +402,25 @@ const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
|
318
402
|
|
|
319
403
|
/**
|
|
320
404
|
* Get cached insights or compute fresh ones.
|
|
405
|
+
*
|
|
406
|
+
* Simple in-memory cache with 5-minute TTL to avoid redundant database queries.
|
|
407
|
+
*
|
|
408
|
+
* @param _swarmMail - SwarmMail adapter (currently unused, reserved for future cache invalidation)
|
|
409
|
+
* @param cacheKey - Unique key for caching (e.g., "strategies:task-name" or "files:src/auth.ts")
|
|
410
|
+
* @param computeFn - Function to compute fresh insights if cache miss
|
|
411
|
+
* @returns Promise resolving to cached or freshly computed insights bundle
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```typescript
|
|
415
|
+
* const insights = await getCachedInsights(
|
|
416
|
+
* swarmMail,
|
|
417
|
+
* "strategies:add-auth",
|
|
418
|
+
* async () => ({
|
|
419
|
+
* strategies: await getStrategyInsights(swarmMail, "add auth"),
|
|
420
|
+
* })
|
|
421
|
+
* );
|
|
422
|
+
* // First call: computes and caches. Subsequent calls within 5min: returns cached.
|
|
423
|
+
* ```
|
|
321
424
|
*/
|
|
322
425
|
export async function getCachedInsights(
|
|
323
426
|
_swarmMail: SwarmMailAdapter,
|
|
@@ -340,6 +443,16 @@ export async function getCachedInsights(
|
|
|
340
443
|
|
|
341
444
|
/**
|
|
342
445
|
* Clear the insights cache.
|
|
446
|
+
*
|
|
447
|
+
* Useful for testing or forcing fresh insights computation.
|
|
448
|
+
*
|
|
449
|
+
* @returns void
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```typescript
|
|
453
|
+
* clearInsightsCache();
|
|
454
|
+
* // All cached insights invalidated, next getCachedInsights() will recompute
|
|
455
|
+
* ```
|
|
343
456
|
*/
|
|
344
457
|
export function clearInsightsCache(): void {
|
|
345
458
|
insightsCache.clear();
|