opencode-swarm-plugin 0.43.0 → 0.44.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/bin/cass.characterization.test.ts +422 -0
- package/bin/swarm.serve.test.ts +6 -4
- package/bin/swarm.test.ts +68 -0
- package/bin/swarm.ts +81 -8
- package/dist/compaction-prompt-scoring.js +139 -0
- package/dist/contributor-tools.d.ts +42 -0
- package/dist/contributor-tools.d.ts.map +1 -0
- package/dist/eval-capture.js +12811 -0
- package/dist/hive.d.ts.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7728 -62590
- package/dist/plugin.js +23833 -78695
- package/dist/sessions/agent-discovery.d.ts +59 -0
- package/dist/sessions/agent-discovery.d.ts.map +1 -0
- package/dist/sessions/index.d.ts +10 -0
- package/dist/sessions/index.d.ts.map +1 -0
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-review.d.ts.map +1 -1
- package/package.json +17 -5
- package/.changeset/swarm-insights-data-layer.md +0 -63
- package/.hive/analysis/eval-failure-analysis-2025-12-25.md +0 -331
- package/.hive/analysis/session-data-quality-audit.md +0 -320
- package/.hive/eval-results.json +0 -483
- package/.hive/issues.jsonl +0 -138
- package/.hive/memories.jsonl +0 -729
- package/.opencode/eval-history.jsonl +0 -327
- package/.turbo/turbo-build.log +0 -9
- package/CHANGELOG.md +0 -2255
- package/SCORER-ANALYSIS.md +0 -598
- package/docs/analysis/subagent-coordination-patterns.md +0 -902
- package/docs/analysis-socratic-planner-pattern.md +0 -504
- package/docs/planning/ADR-001-monorepo-structure.md +0 -171
- package/docs/planning/ADR-002-package-extraction.md +0 -393
- package/docs/planning/ADR-003-performance-improvements.md +0 -451
- package/docs/planning/ADR-004-message-queue-features.md +0 -187
- package/docs/planning/ADR-005-devtools-observability.md +0 -202
- package/docs/planning/ADR-007-swarm-enhancements-worktree-review.md +0 -168
- package/docs/planning/ADR-008-worker-handoff-protocol.md +0 -293
- package/docs/planning/ADR-009-oh-my-opencode-patterns.md +0 -353
- package/docs/planning/ROADMAP.md +0 -368
- package/docs/semantic-memory-cli-syntax.md +0 -123
- package/docs/swarm-mail-architecture.md +0 -1147
- package/docs/testing/context-recovery-test.md +0 -470
- package/evals/ARCHITECTURE.md +0 -1189
- package/evals/README.md +0 -768
- package/evals/compaction-prompt.eval.ts +0 -149
- package/evals/compaction-resumption.eval.ts +0 -289
- package/evals/coordinator-behavior.eval.ts +0 -307
- package/evals/coordinator-session.eval.ts +0 -154
- package/evals/evalite.config.ts.bak +0 -15
- package/evals/example.eval.ts +0 -31
- package/evals/fixtures/compaction-cases.ts +0 -350
- package/evals/fixtures/compaction-prompt-cases.ts +0 -311
- package/evals/fixtures/coordinator-sessions.ts +0 -328
- package/evals/fixtures/decomposition-cases.ts +0 -105
- package/evals/lib/compaction-loader.test.ts +0 -248
- package/evals/lib/compaction-loader.ts +0 -320
- package/evals/lib/data-loader.evalite-test.ts +0 -289
- package/evals/lib/data-loader.test.ts +0 -345
- package/evals/lib/data-loader.ts +0 -281
- package/evals/lib/llm.ts +0 -115
- package/evals/scorers/compaction-prompt-scorers.ts +0 -145
- package/evals/scorers/compaction-scorers.ts +0 -305
- package/evals/scorers/coordinator-discipline.evalite-test.ts +0 -539
- package/evals/scorers/coordinator-discipline.ts +0 -325
- package/evals/scorers/index.test.ts +0 -146
- package/evals/scorers/index.ts +0 -328
- package/evals/scorers/outcome-scorers.evalite-test.ts +0 -27
- package/evals/scorers/outcome-scorers.ts +0 -349
- package/evals/swarm-decomposition.eval.ts +0 -121
- package/examples/commands/swarm.md +0 -745
- package/examples/plugin-wrapper-template.ts +0 -2426
- package/examples/skills/hive-workflow/SKILL.md +0 -212
- package/examples/skills/skill-creator/SKILL.md +0 -223
- package/examples/skills/swarm-coordination/SKILL.md +0 -292
- package/global-skills/cli-builder/SKILL.md +0 -344
- package/global-skills/cli-builder/references/advanced-patterns.md +0 -244
- package/global-skills/learning-systems/SKILL.md +0 -644
- package/global-skills/skill-creator/LICENSE.txt +0 -202
- package/global-skills/skill-creator/SKILL.md +0 -352
- package/global-skills/skill-creator/references/output-patterns.md +0 -82
- package/global-skills/skill-creator/references/workflows.md +0 -28
- package/global-skills/swarm-coordination/SKILL.md +0 -995
- package/global-skills/swarm-coordination/references/coordinator-patterns.md +0 -235
- package/global-skills/swarm-coordination/references/strategies.md +0 -138
- package/global-skills/system-design/SKILL.md +0 -213
- package/global-skills/testing-patterns/SKILL.md +0 -430
- package/global-skills/testing-patterns/references/dependency-breaking-catalog.md +0 -586
- package/opencode-swarm-plugin-0.30.7.tgz +0 -0
- package/opencode-swarm-plugin-0.31.0.tgz +0 -0
- package/scripts/cleanup-test-memories.ts +0 -346
- package/scripts/init-skill.ts +0 -222
- package/scripts/migrate-unknown-sessions.ts +0 -349
- package/scripts/validate-skill.ts +0 -204
- package/src/agent-mail.ts +0 -1724
- package/src/anti-patterns.test.ts +0 -1167
- package/src/anti-patterns.ts +0 -448
- package/src/compaction-capture.integration.test.ts +0 -257
- package/src/compaction-hook.test.ts +0 -838
- package/src/compaction-hook.ts +0 -1204
- package/src/compaction-observability.integration.test.ts +0 -139
- package/src/compaction-observability.test.ts +0 -187
- package/src/compaction-observability.ts +0 -324
- package/src/compaction-prompt-scorers.test.ts +0 -475
- package/src/compaction-prompt-scoring.ts +0 -300
- package/src/dashboard.test.ts +0 -611
- package/src/dashboard.ts +0 -462
- package/src/error-enrichment.test.ts +0 -403
- package/src/error-enrichment.ts +0 -219
- package/src/eval-capture.test.ts +0 -1015
- package/src/eval-capture.ts +0 -929
- package/src/eval-gates.test.ts +0 -306
- package/src/eval-gates.ts +0 -218
- package/src/eval-history.test.ts +0 -508
- package/src/eval-history.ts +0 -214
- package/src/eval-learning.test.ts +0 -378
- package/src/eval-learning.ts +0 -360
- package/src/eval-runner.test.ts +0 -223
- package/src/eval-runner.ts +0 -402
- package/src/export-tools.test.ts +0 -476
- package/src/export-tools.ts +0 -257
- package/src/hive.integration.test.ts +0 -2241
- package/src/hive.ts +0 -1628
- package/src/index.ts +0 -935
- package/src/learning.integration.test.ts +0 -1815
- package/src/learning.ts +0 -1079
- package/src/logger.test.ts +0 -189
- package/src/logger.ts +0 -135
- package/src/mandate-promotion.test.ts +0 -473
- package/src/mandate-promotion.ts +0 -239
- package/src/mandate-storage.integration.test.ts +0 -601
- package/src/mandate-storage.test.ts +0 -578
- package/src/mandate-storage.ts +0 -794
- package/src/mandates.ts +0 -540
- package/src/memory-tools.test.ts +0 -195
- package/src/memory-tools.ts +0 -344
- package/src/memory.integration.test.ts +0 -334
- package/src/memory.test.ts +0 -158
- package/src/memory.ts +0 -527
- package/src/model-selection.test.ts +0 -188
- package/src/model-selection.ts +0 -68
- package/src/observability-tools.test.ts +0 -359
- package/src/observability-tools.ts +0 -871
- package/src/output-guardrails.test.ts +0 -438
- package/src/output-guardrails.ts +0 -381
- package/src/pattern-maturity.test.ts +0 -1160
- package/src/pattern-maturity.ts +0 -525
- package/src/planning-guardrails.test.ts +0 -491
- package/src/planning-guardrails.ts +0 -438
- package/src/plugin.ts +0 -23
- package/src/post-compaction-tracker.test.ts +0 -251
- package/src/post-compaction-tracker.ts +0 -237
- package/src/query-tools.test.ts +0 -636
- package/src/query-tools.ts +0 -324
- package/src/rate-limiter.integration.test.ts +0 -466
- package/src/rate-limiter.ts +0 -774
- package/src/replay-tools.test.ts +0 -496
- package/src/replay-tools.ts +0 -240
- package/src/repo-crawl.integration.test.ts +0 -441
- package/src/repo-crawl.ts +0 -610
- package/src/schemas/cell-events.test.ts +0 -347
- package/src/schemas/cell-events.ts +0 -807
- package/src/schemas/cell.ts +0 -257
- package/src/schemas/evaluation.ts +0 -166
- package/src/schemas/index.test.ts +0 -199
- package/src/schemas/index.ts +0 -286
- package/src/schemas/mandate.ts +0 -232
- package/src/schemas/swarm-context.ts +0 -115
- package/src/schemas/task.ts +0 -161
- package/src/schemas/worker-handoff.test.ts +0 -302
- package/src/schemas/worker-handoff.ts +0 -131
- package/src/skills.integration.test.ts +0 -1192
- package/src/skills.test.ts +0 -643
- package/src/skills.ts +0 -1549
- package/src/storage.integration.test.ts +0 -341
- package/src/storage.ts +0 -884
- package/src/structured.integration.test.ts +0 -817
- package/src/structured.test.ts +0 -1046
- package/src/structured.ts +0 -762
- package/src/swarm-decompose.test.ts +0 -188
- package/src/swarm-decompose.ts +0 -1302
- package/src/swarm-deferred.integration.test.ts +0 -157
- package/src/swarm-deferred.test.ts +0 -38
- package/src/swarm-insights.test.ts +0 -214
- package/src/swarm-insights.ts +0 -459
- package/src/swarm-mail.integration.test.ts +0 -970
- package/src/swarm-mail.ts +0 -739
- package/src/swarm-orchestrate.integration.test.ts +0 -282
- package/src/swarm-orchestrate.test.ts +0 -548
- package/src/swarm-orchestrate.ts +0 -3084
- package/src/swarm-prompts.test.ts +0 -1270
- package/src/swarm-prompts.ts +0 -2077
- package/src/swarm-research.integration.test.ts +0 -701
- package/src/swarm-research.test.ts +0 -698
- package/src/swarm-research.ts +0 -472
- package/src/swarm-review.integration.test.ts +0 -285
- package/src/swarm-review.test.ts +0 -879
- package/src/swarm-review.ts +0 -709
- package/src/swarm-strategies.ts +0 -407
- package/src/swarm-worktree.test.ts +0 -501
- package/src/swarm-worktree.ts +0 -575
- package/src/swarm.integration.test.ts +0 -2377
- package/src/swarm.ts +0 -38
- package/src/tool-adapter.integration.test.ts +0 -1221
- package/src/tool-availability.ts +0 -461
- package/tsconfig.json +0 -28
package/src/model-selection.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model Selection Module
|
|
3
|
-
*
|
|
4
|
-
* Determines which model a worker agent should use based on subtask
|
|
5
|
-
* characteristics like file types and complexity.
|
|
6
|
-
*
|
|
7
|
-
* Priority:
|
|
8
|
-
* 1. Explicit model field in subtask
|
|
9
|
-
* 2. File-type inference (docs/tests → lite model)
|
|
10
|
-
* 3. Default to primary model
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { DecomposedSubtask } from "./schemas/task";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Configuration interface for swarm models
|
|
17
|
-
*/
|
|
18
|
-
export interface SwarmConfig {
|
|
19
|
-
primaryModel: string;
|
|
20
|
-
liteModel?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Select the appropriate model for a worker agent based on subtask characteristics
|
|
25
|
-
*
|
|
26
|
-
* Priority order:
|
|
27
|
-
* 1. Explicit `model` field in subtask (if present)
|
|
28
|
-
* 2. File-type inference:
|
|
29
|
-
* - All .md/.mdx files → liteModel
|
|
30
|
-
* - All .test./.spec. files → liteModel
|
|
31
|
-
* 3. Mixed files or implementation → primaryModel
|
|
32
|
-
*
|
|
33
|
-
* @param subtask - The subtask to evaluate
|
|
34
|
-
* @param config - Swarm configuration with model preferences
|
|
35
|
-
* @returns Model identifier string
|
|
36
|
-
*/
|
|
37
|
-
export function selectWorkerModel(
|
|
38
|
-
subtask: DecomposedSubtask & { model?: string },
|
|
39
|
-
config: SwarmConfig,
|
|
40
|
-
): string {
|
|
41
|
-
// Priority 1: Explicit model in subtask
|
|
42
|
-
if (subtask.model) {
|
|
43
|
-
return subtask.model;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const files = subtask.files || [];
|
|
47
|
-
|
|
48
|
-
// Priority 2: File-type inference
|
|
49
|
-
if (files.length > 0) {
|
|
50
|
-
const allDocs = files.every((f) => {
|
|
51
|
-
const lower = f.toLowerCase();
|
|
52
|
-
return lower.endsWith(".md") || lower.endsWith(".mdx");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const allTests = files.every((f) => {
|
|
56
|
-
const lower = f.toLowerCase();
|
|
57
|
-
return lower.includes(".test.") || lower.includes(".spec.");
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
if (allDocs || allTests) {
|
|
61
|
-
// Use lite model if configured, otherwise fall back to primary
|
|
62
|
-
return config.liteModel || config.primaryModel || "anthropic/claude-haiku-4-5";
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Priority 3: Default to primary model
|
|
67
|
-
return config.primaryModel || "anthropic/claude-haiku-4-5";
|
|
68
|
-
}
|
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Observability Tools Tests
|
|
3
|
-
*
|
|
4
|
-
* TDD: Write tests first, then implement the tools.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, test, expect, beforeAll, afterAll } from "bun:test";
|
|
8
|
-
import {
|
|
9
|
-
observabilityTools,
|
|
10
|
-
type SwarmAnalyticsArgs,
|
|
11
|
-
type SwarmQueryArgs,
|
|
12
|
-
type SwarmDiagnoseArgs,
|
|
13
|
-
type SwarmInsightsArgs,
|
|
14
|
-
} from "./observability-tools";
|
|
15
|
-
import type { ToolContext } from "@opencode-ai/plugin";
|
|
16
|
-
import {
|
|
17
|
-
closeSwarmMailLibSQL,
|
|
18
|
-
createInMemorySwarmMailLibSQL,
|
|
19
|
-
initSwarmAgent,
|
|
20
|
-
reserveSwarmFiles,
|
|
21
|
-
sendSwarmMessage,
|
|
22
|
-
type SwarmMailAdapter,
|
|
23
|
-
} from "swarm-mail";
|
|
24
|
-
|
|
25
|
-
describe("observability-tools", () => {
|
|
26
|
-
let swarmMail: SwarmMailAdapter;
|
|
27
|
-
const projectPath = "/test/project";
|
|
28
|
-
const mockContext: ToolContext = { sessionID: "test-session" };
|
|
29
|
-
|
|
30
|
-
beforeAll(async () => {
|
|
31
|
-
// Create in-memory database with test data
|
|
32
|
-
swarmMail = await createInMemorySwarmMailLibSQL(projectPath);
|
|
33
|
-
|
|
34
|
-
// Populate with test events using high-level API
|
|
35
|
-
const agentName = "TestAgent";
|
|
36
|
-
|
|
37
|
-
// Register agent
|
|
38
|
-
await initSwarmAgent({
|
|
39
|
-
projectPath,
|
|
40
|
-
agentName,
|
|
41
|
-
taskDescription: "test-task",
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Reserve and release files (for lock contention analytics)
|
|
45
|
-
await reserveSwarmFiles({
|
|
46
|
-
projectPath,
|
|
47
|
-
agentName,
|
|
48
|
-
paths: ["src/test.ts"],
|
|
49
|
-
reason: "test-reason",
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Send a message (for message latency analytics)
|
|
53
|
-
await sendSwarmMessage({
|
|
54
|
-
projectPath,
|
|
55
|
-
fromAgent: agentName,
|
|
56
|
-
toAgents: ["Agent2"],
|
|
57
|
-
subject: "test-subject",
|
|
58
|
-
body: "test-body",
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// Note: subtask outcomes are recorded via a different API
|
|
62
|
-
// For now, we'll test with the events we have
|
|
63
|
-
// The important thing is that the tools can execute queries
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
afterAll(async () => {
|
|
67
|
-
await closeSwarmMailLibSQL(projectPath);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe("swarm_analytics", () => {
|
|
71
|
-
const tool = observabilityTools.swarm_analytics;
|
|
72
|
-
|
|
73
|
-
test("is defined with correct schema", () => {
|
|
74
|
-
expect(tool).toBeDefined();
|
|
75
|
-
expect(tool.description).toBeTruthy();
|
|
76
|
-
expect(tool.args).toBeDefined();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test("returns failed-decompositions data", async () => {
|
|
80
|
-
const args: SwarmAnalyticsArgs = {
|
|
81
|
-
query: "failed-decompositions",
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const result = await tool.execute(args, mockContext);
|
|
85
|
-
expect(result).toBeTruthy();
|
|
86
|
-
|
|
87
|
-
const parsed = JSON.parse(result);
|
|
88
|
-
expect(parsed).toHaveProperty("results");
|
|
89
|
-
expect(Array.isArray(parsed.results)).toBe(true);
|
|
90
|
-
// Empty data is fine - we're testing tool execution
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test("returns strategy-success-rates data", async () => {
|
|
94
|
-
const args: SwarmAnalyticsArgs = {
|
|
95
|
-
query: "strategy-success-rates",
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const result = await tool.execute(args, mockContext);
|
|
99
|
-
const parsed = JSON.parse(result);
|
|
100
|
-
expect(parsed).toHaveProperty("results");
|
|
101
|
-
expect(Array.isArray(parsed.results)).toBe(true);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
test("returns agent-activity data", async () => {
|
|
105
|
-
const args: SwarmAnalyticsArgs = {
|
|
106
|
-
query: "agent-activity",
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const result = await tool.execute(args, mockContext);
|
|
110
|
-
const parsed = JSON.parse(result);
|
|
111
|
-
expect(parsed).toHaveProperty("results");
|
|
112
|
-
expect(Array.isArray(parsed.results)).toBe(true);
|
|
113
|
-
// Should have at least our TestAgent
|
|
114
|
-
expect(parsed.results.length).toBeGreaterThanOrEqual(1);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
test("supports summary format", async () => {
|
|
118
|
-
const args: SwarmAnalyticsArgs = {
|
|
119
|
-
query: "agent-activity",
|
|
120
|
-
format: "summary",
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const result = await tool.execute(args, mockContext);
|
|
124
|
-
expect(result).toBeTruthy();
|
|
125
|
-
expect(typeof result).toBe("string");
|
|
126
|
-
// Summary should be concise (<500 chars)
|
|
127
|
-
expect(result.length).toBeLessThan(500);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
test("supports time filtering with since", async () => {
|
|
131
|
-
const args: SwarmAnalyticsArgs = {
|
|
132
|
-
query: "agent-activity",
|
|
133
|
-
since: "24h",
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const result = await tool.execute(args, mockContext);
|
|
137
|
-
const parsed = JSON.parse(result);
|
|
138
|
-
expect(parsed).toHaveProperty("results");
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
test("returns error for invalid query type", async () => {
|
|
142
|
-
const args = {
|
|
143
|
-
query: "invalid-query",
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
const result = await tool.execute(args as any, mockContext);
|
|
147
|
-
const parsed = JSON.parse(result);
|
|
148
|
-
expect(parsed).toHaveProperty("error");
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
describe("swarm_query", () => {
|
|
153
|
-
const tool = observabilityTools.swarm_query;
|
|
154
|
-
|
|
155
|
-
test("is defined with correct schema", () => {
|
|
156
|
-
expect(tool).toBeDefined();
|
|
157
|
-
expect(tool.description).toBeTruthy();
|
|
158
|
-
expect(tool.args).toBeDefined();
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test("executes raw SQL queries", async () => {
|
|
162
|
-
const args: SwarmQueryArgs = {
|
|
163
|
-
sql: "SELECT type, COUNT(*) as count FROM events GROUP BY type",
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const result = await tool.execute(args, mockContext);
|
|
167
|
-
expect(result).toBeTruthy();
|
|
168
|
-
|
|
169
|
-
const parsed = JSON.parse(result);
|
|
170
|
-
// May have errors in test environment - that's ok
|
|
171
|
-
if (!parsed.error) {
|
|
172
|
-
// Should have count and results even if empty
|
|
173
|
-
expect(parsed).toHaveProperty("count");
|
|
174
|
-
expect(parsed).toHaveProperty("results");
|
|
175
|
-
expect(Array.isArray(parsed.results)).toBe(true);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
test("limits results to max 50 rows", async () => {
|
|
180
|
-
const args: SwarmQueryArgs = {
|
|
181
|
-
sql: "SELECT * FROM events LIMIT 100", // Try to fetch 100
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const result = await tool.execute(args, mockContext);
|
|
185
|
-
const parsed = JSON.parse(result);
|
|
186
|
-
// Should be capped at 50 (or less if there's less data)
|
|
187
|
-
// May return error if database issues - that's ok for this test
|
|
188
|
-
if (parsed.error) {
|
|
189
|
-
expect(parsed).toHaveProperty("error");
|
|
190
|
-
} else {
|
|
191
|
-
expect(parsed).toHaveProperty("results");
|
|
192
|
-
expect(parsed.results.length).toBeLessThanOrEqual(50);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
test("supports table format", async () => {
|
|
197
|
-
const args: SwarmQueryArgs = {
|
|
198
|
-
sql: "SELECT type FROM events LIMIT 3",
|
|
199
|
-
format: "table",
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
const result = await tool.execute(args, mockContext);
|
|
203
|
-
expect(typeof result).toBe("string");
|
|
204
|
-
// Table format returns string (even if "No results" for empty data)
|
|
205
|
-
expect(result.length).toBeGreaterThan(0);
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
test("returns error for invalid SQL", async () => {
|
|
209
|
-
const args: SwarmQueryArgs = {
|
|
210
|
-
sql: "SELECT * FROM nonexistent_table",
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const result = await tool.execute(args, mockContext);
|
|
214
|
-
const parsed = JSON.parse(result);
|
|
215
|
-
expect(parsed).toHaveProperty("error");
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe("swarm_diagnose", () => {
|
|
220
|
-
const tool = observabilityTools.swarm_diagnose;
|
|
221
|
-
|
|
222
|
-
test("is defined with correct schema", () => {
|
|
223
|
-
expect(tool).toBeDefined();
|
|
224
|
-
expect(tool.description).toBeTruthy();
|
|
225
|
-
expect(tool.args).toBeDefined();
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
test("diagnoses issues for a specific epic", async () => {
|
|
229
|
-
const args: SwarmDiagnoseArgs = {
|
|
230
|
-
epic_id: "epic-123",
|
|
231
|
-
include: ["blockers", "errors"],
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const result = await tool.execute(args, mockContext);
|
|
235
|
-
expect(result).toBeTruthy();
|
|
236
|
-
|
|
237
|
-
const parsed = JSON.parse(result);
|
|
238
|
-
expect(parsed).toHaveProperty("epic_id");
|
|
239
|
-
expect(parsed).toHaveProperty("diagnosis");
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
test("returns structured diagnosis with suggestions", async () => {
|
|
243
|
-
const args: SwarmDiagnoseArgs = {
|
|
244
|
-
bead_id: "task-1",
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
const result = await tool.execute(args, mockContext);
|
|
248
|
-
const parsed = JSON.parse(result);
|
|
249
|
-
expect(parsed).toHaveProperty("diagnosis");
|
|
250
|
-
expect(Array.isArray(parsed.diagnosis)).toBe(true);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
test("includes timeline when requested", async () => {
|
|
254
|
-
const args: SwarmDiagnoseArgs = {
|
|
255
|
-
bead_id: "task-1",
|
|
256
|
-
include: ["timeline"],
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const result = await tool.execute(args, mockContext);
|
|
260
|
-
const parsed = JSON.parse(result);
|
|
261
|
-
expect(parsed).toHaveProperty("timeline");
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
describe("swarm_insights", () => {
|
|
266
|
-
const tool = observabilityTools.swarm_insights;
|
|
267
|
-
|
|
268
|
-
test("is defined with correct schema", () => {
|
|
269
|
-
expect(tool).toBeDefined();
|
|
270
|
-
expect(tool.description).toBeTruthy();
|
|
271
|
-
expect(tool.args).toBeDefined();
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
test("generates insights for recent activity", async () => {
|
|
275
|
-
const args: SwarmInsightsArgs = {
|
|
276
|
-
scope: "recent",
|
|
277
|
-
metrics: ["success_rate", "avg_duration"],
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
const result = await tool.execute(args, mockContext);
|
|
281
|
-
expect(result).toBeTruthy();
|
|
282
|
-
|
|
283
|
-
const parsed = JSON.parse(result);
|
|
284
|
-
expect(parsed).toHaveProperty("insights");
|
|
285
|
-
expect(Array.isArray(parsed.insights)).toBe(true);
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
test("generates insights for specific epic", async () => {
|
|
289
|
-
const args: SwarmInsightsArgs = {
|
|
290
|
-
scope: "epic",
|
|
291
|
-
epic_id: "epic-123",
|
|
292
|
-
metrics: ["conflict_rate", "retry_rate"],
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const result = await tool.execute(args, mockContext);
|
|
296
|
-
const parsed = JSON.parse(result);
|
|
297
|
-
expect(parsed).toHaveProperty("epic_id", "epic-123");
|
|
298
|
-
expect(parsed).toHaveProperty("insights");
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
test("returns error when epic_id missing for epic scope", async () => {
|
|
302
|
-
const args: SwarmInsightsArgs = {
|
|
303
|
-
scope: "epic",
|
|
304
|
-
metrics: ["success_rate"],
|
|
305
|
-
// Missing epic_id
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const result = await tool.execute(args, mockContext);
|
|
309
|
-
const parsed = JSON.parse(result);
|
|
310
|
-
expect(parsed).toHaveProperty("error");
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
describe("integration with swarm-mail analytics", () => {
|
|
315
|
-
test("all query types are supported", async () => {
|
|
316
|
-
const queryTypes = [
|
|
317
|
-
"failed-decompositions",
|
|
318
|
-
"strategy-success-rates",
|
|
319
|
-
"lock-contention",
|
|
320
|
-
"agent-activity",
|
|
321
|
-
"message-latency",
|
|
322
|
-
"scope-violations",
|
|
323
|
-
"task-duration",
|
|
324
|
-
"checkpoint-frequency",
|
|
325
|
-
"recovery-success",
|
|
326
|
-
"human-feedback",
|
|
327
|
-
];
|
|
328
|
-
|
|
329
|
-
for (const queryType of queryTypes) {
|
|
330
|
-
const tool = observabilityTools.swarm_analytics;
|
|
331
|
-
const args: SwarmAnalyticsArgs = {
|
|
332
|
-
query: queryType as SwarmAnalyticsArgs["query"],
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
const result = await tool.execute(args, mockContext);
|
|
336
|
-
const parsed = JSON.parse(result);
|
|
337
|
-
|
|
338
|
-
// Should return results property (even if empty array)
|
|
339
|
-
// May have errors in test environment - that's ok
|
|
340
|
-
if (!parsed.error) {
|
|
341
|
-
expect(parsed).toHaveProperty("results");
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
});
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
describe("CLI Stats Helpers", () => {
|
|
348
|
-
// These helpers will be exported for use in bin/swarm.ts
|
|
349
|
-
// They format analytics data for beautiful CLI output
|
|
350
|
-
|
|
351
|
-
describe("formatSwarmStatsBox", () => {
|
|
352
|
-
test("formats stats in a beautiful box", () => {
|
|
353
|
-
// This will be implemented in observability-tools.ts
|
|
354
|
-
// Just defining the test structure for now
|
|
355
|
-
expect(true).toBe(true);
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
});
|