opencode-swarm-plugin 0.21.0 → 0.22.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/.beads/issues.jsonl +13 -2
- package/README.md +316 -51
- package/dist/index.js +287 -150
- package/dist/plugin.js +272 -144
- package/docs/semantic-memory-cli-syntax.md +123 -0
- package/docs/swarm-mail-architecture.md +1147 -0
- package/package.json +1 -1
- package/scripts/cleanup-test-memories.ts +346 -0
- package/src/learning.integration.test.ts +19 -4
- package/src/storage.ts +117 -5
- package/src/swarm-orchestrate.ts +392 -239
- package/src/swarm.integration.test.ts +124 -0
- package/vitest.integration.config.ts +6 -0
- package/vitest.integration.setup.ts +48 -0
package/dist/index.js
CHANGED
|
@@ -35523,14 +35523,16 @@ var swarm_complete = tool({
|
|
|
35523
35523
|
retry_count: tool.schema.number().optional().describe("Number of retry attempts during task")
|
|
35524
35524
|
},
|
|
35525
35525
|
async execute(args) {
|
|
35526
|
-
const
|
|
35527
|
-
let agentRegistered = false;
|
|
35528
|
-
let registrationWarning = "";
|
|
35526
|
+
const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
35529
35527
|
try {
|
|
35530
|
-
const
|
|
35531
|
-
agentRegistered =
|
|
35532
|
-
|
|
35533
|
-
|
|
35528
|
+
const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
|
|
35529
|
+
let agentRegistered = false;
|
|
35530
|
+
let registrationWarning = "";
|
|
35531
|
+
try {
|
|
35532
|
+
const agent = await getAgent(projectKey, args.agent_name, args.project_key);
|
|
35533
|
+
agentRegistered = agent !== null;
|
|
35534
|
+
if (!agentRegistered) {
|
|
35535
|
+
registrationWarning = `⚠️ WARNING: Agent '${args.agent_name}' was NOT registered in swarm-mail for project '${projectKey}'.
|
|
35534
35536
|
|
|
35535
35537
|
This usually means you skipped the MANDATORY swarmmail_init step.
|
|
35536
35538
|
|
|
@@ -35543,150 +35545,176 @@ This usually means you skipped the MANDATORY swarmmail_init step.
|
|
|
35543
35545
|
**Next time:** Run swarmmail_init(project_path="${args.project_key}", task_description="<task>") FIRST, before any other work.
|
|
35544
35546
|
|
|
35545
35547
|
Continuing with completion, but this should be fixed for future subtasks.`;
|
|
35546
|
-
|
|
35548
|
+
console.warn(`[swarm_complete] ${registrationWarning}`);
|
|
35549
|
+
}
|
|
35550
|
+
} catch (error45) {
|
|
35551
|
+
console.warn(`[swarm_complete] Could not verify agent registration:`, error45);
|
|
35552
|
+
registrationWarning = `ℹ️ Could not verify swarm-mail registration (database may not be available). Consider running swarmmail_init next time.`;
|
|
35547
35553
|
}
|
|
35548
|
-
|
|
35549
|
-
|
|
35550
|
-
|
|
35551
|
-
|
|
35552
|
-
|
|
35553
|
-
|
|
35554
|
-
|
|
35555
|
-
|
|
35556
|
-
|
|
35557
|
-
|
|
35558
|
-
|
|
35559
|
-
|
|
35560
|
-
|
|
35561
|
-
|
|
35562
|
-
|
|
35563
|
-
|
|
35564
|
-
|
|
35565
|
-
|
|
35566
|
-
|
|
35567
|
-
|
|
35568
|
-
|
|
35569
|
-
|
|
35570
|
-
|
|
35571
|
-
hint: verificationResult.blockers.length > 0 ? `Fix these issues: ${verificationResult.blockers.map((b, i) => `${i + 1}. ${b}`).join(", ")}. Use skip_verification=true only as last resort.` : "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
35572
|
-
gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
|
|
35573
|
-
}, null, 2);
|
|
35554
|
+
let verificationResult = null;
|
|
35555
|
+
if (!args.skip_verification && args.files_touched?.length) {
|
|
35556
|
+
verificationResult = await runVerificationGate(args.files_touched, args.skip_ubs_scan ?? false);
|
|
35557
|
+
if (!verificationResult.passed) {
|
|
35558
|
+
return JSON.stringify({
|
|
35559
|
+
success: false,
|
|
35560
|
+
error: "Verification Gate FAILED - fix issues before completing",
|
|
35561
|
+
verification: {
|
|
35562
|
+
passed: false,
|
|
35563
|
+
summary: verificationResult.summary,
|
|
35564
|
+
blockers: verificationResult.blockers,
|
|
35565
|
+
steps: verificationResult.steps.map((s) => ({
|
|
35566
|
+
name: s.name,
|
|
35567
|
+
passed: s.passed,
|
|
35568
|
+
skipped: s.skipped,
|
|
35569
|
+
skipReason: s.skipReason,
|
|
35570
|
+
error: s.error?.slice(0, 200)
|
|
35571
|
+
}))
|
|
35572
|
+
},
|
|
35573
|
+
hint: verificationResult.blockers.length > 0 ? `Fix these issues: ${verificationResult.blockers.map((b, i) => `${i + 1}. ${b}`).join(", ")}. Use skip_verification=true only as last resort.` : "Fix the failing checks and try again. Use skip_verification=true only as last resort.",
|
|
35574
|
+
gate_function: "IDENTIFY → RUN → READ → VERIFY → CLAIM (you are at VERIFY, claim blocked)"
|
|
35575
|
+
}, null, 2);
|
|
35576
|
+
}
|
|
35574
35577
|
}
|
|
35575
|
-
|
|
35576
|
-
|
|
35577
|
-
|
|
35578
|
-
|
|
35579
|
-
|
|
35580
|
-
|
|
35581
|
-
|
|
35582
|
-
|
|
35583
|
-
|
|
35584
|
-
|
|
35585
|
-
|
|
35586
|
-
|
|
35587
|
-
|
|
35588
|
-
}
|
|
35578
|
+
let ubsResult = null;
|
|
35579
|
+
if (!args.skip_verification && !verificationResult && args.files_touched?.length && !args.skip_ubs_scan) {
|
|
35580
|
+
ubsResult = await runUbsScan(args.files_touched);
|
|
35581
|
+
if (ubsResult && ubsResult.summary.critical > 0) {
|
|
35582
|
+
return JSON.stringify({
|
|
35583
|
+
success: false,
|
|
35584
|
+
error: `UBS found ${ubsResult.summary.critical} critical bug(s) that must be fixed before completing`,
|
|
35585
|
+
ubs_scan: {
|
|
35586
|
+
critical_count: ubsResult.summary.critical,
|
|
35587
|
+
bugs: ubsResult.bugs.filter((b) => b.severity === "critical")
|
|
35588
|
+
},
|
|
35589
|
+
hint: `Fix these critical bugs: ${ubsResult.bugs.filter((b) => b.severity === "critical").map((b) => `${b.file}:${b.line} - ${b.message}`).slice(0, 3).join("; ")}. Try: Run 'ubs scan ${args.files_touched?.join(" ") || "."} --json' for full report, fix reported issues, or use skip_ubs_scan=true to bypass (not recommended).`
|
|
35590
|
+
}, null, 2);
|
|
35591
|
+
}
|
|
35592
|
+
}
|
|
35593
|
+
let parsedEvaluation;
|
|
35594
|
+
if (args.evaluation) {
|
|
35595
|
+
try {
|
|
35596
|
+
parsedEvaluation = EvaluationSchema.parse(JSON.parse(args.evaluation));
|
|
35597
|
+
} catch (error45) {
|
|
35598
|
+
return JSON.stringify({
|
|
35599
|
+
success: false,
|
|
35600
|
+
error: "Invalid evaluation format",
|
|
35601
|
+
details: error45 instanceof exports_external.ZodError ? error45.issues : String(error45)
|
|
35602
|
+
}, null, 2);
|
|
35603
|
+
}
|
|
35604
|
+
if (!parsedEvaluation.passed) {
|
|
35605
|
+
return JSON.stringify({
|
|
35606
|
+
success: false,
|
|
35607
|
+
error: "Self-evaluation failed",
|
|
35608
|
+
retry_suggestion: parsedEvaluation.retry_suggestion,
|
|
35609
|
+
feedback: parsedEvaluation.overall_feedback
|
|
35610
|
+
}, null, 2);
|
|
35611
|
+
}
|
|
35612
|
+
}
|
|
35613
|
+
const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
|
|
35614
|
+
if (closeResult.exitCode !== 0) {
|
|
35615
|
+
throw new Error(`Failed to close bead because bd close command failed: ${closeResult.stderr.toString()}. Try: Verify bead exists and is not already closed with 'bd show ${args.bead_id}', check if bead ID is correct with 'beads_query()', or use beads_close tool directly.`);
|
|
35589
35616
|
}
|
|
35590
|
-
}
|
|
35591
|
-
let parsedEvaluation;
|
|
35592
|
-
if (args.evaluation) {
|
|
35593
35617
|
try {
|
|
35594
|
-
|
|
35618
|
+
const epicId3 = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
35619
|
+
const durationMs2 = args.start_time ? Date.now() - args.start_time : 0;
|
|
35620
|
+
const event = createEvent("subtask_outcome", {
|
|
35621
|
+
project_key: args.project_key,
|
|
35622
|
+
epic_id: epicId3,
|
|
35623
|
+
bead_id: args.bead_id,
|
|
35624
|
+
planned_files: args.planned_files || [],
|
|
35625
|
+
actual_files: args.files_touched || [],
|
|
35626
|
+
duration_ms: durationMs2,
|
|
35627
|
+
error_count: args.error_count || 0,
|
|
35628
|
+
retry_count: args.retry_count || 0,
|
|
35629
|
+
success: true
|
|
35630
|
+
});
|
|
35631
|
+
await appendEvent(event, args.project_key);
|
|
35595
35632
|
} catch (error45) {
|
|
35596
|
-
|
|
35597
|
-
success: false,
|
|
35598
|
-
error: "Invalid evaluation format",
|
|
35599
|
-
details: error45 instanceof exports_external.ZodError ? error45.issues : String(error45)
|
|
35600
|
-
}, null, 2);
|
|
35633
|
+
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
35601
35634
|
}
|
|
35602
|
-
|
|
35603
|
-
|
|
35604
|
-
|
|
35605
|
-
|
|
35606
|
-
|
|
35607
|
-
|
|
35608
|
-
|
|
35635
|
+
let capturedStrategy;
|
|
35636
|
+
const durationMs = args.start_time ? Date.now() - args.start_time : 0;
|
|
35637
|
+
const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
|
|
35638
|
+
let memoryStored = false;
|
|
35639
|
+
let memoryError;
|
|
35640
|
+
try {
|
|
35641
|
+
const memoryAvailable = await isToolAvailable("semantic-memory");
|
|
35642
|
+
if (memoryAvailable) {
|
|
35643
|
+
const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
|
|
35644
|
+
if (storeResult.exitCode === 0) {
|
|
35645
|
+
memoryStored = true;
|
|
35646
|
+
console.log(`[swarm_complete] Stored learning for ${args.bead_id} in semantic-memory`);
|
|
35647
|
+
} else {
|
|
35648
|
+
memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
|
|
35649
|
+
console.warn(`[swarm_complete] ${memoryError}`);
|
|
35650
|
+
}
|
|
35651
|
+
} else {
|
|
35652
|
+
memoryError = "semantic-memory not available - learning stored in-memory only";
|
|
35653
|
+
warnMissingTool("semantic-memory");
|
|
35654
|
+
}
|
|
35655
|
+
} catch (error45) {
|
|
35656
|
+
memoryError = `Failed to store memory: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
35657
|
+
console.warn(`[swarm_complete] ${memoryError}`);
|
|
35658
|
+
}
|
|
35659
|
+
try {
|
|
35660
|
+
await releaseSwarmFiles({
|
|
35661
|
+
projectPath: args.project_key,
|
|
35662
|
+
agentName: args.agent_name
|
|
35663
|
+
});
|
|
35664
|
+
} catch (error45) {
|
|
35665
|
+
console.warn(`[swarm] Failed to release file reservations for ${args.agent_name}:`, error45);
|
|
35609
35666
|
}
|
|
35610
|
-
}
|
|
35611
|
-
const closeResult = await Bun.$`bd close ${args.bead_id} --reason ${args.summary} --json`.quiet().nothrow();
|
|
35612
|
-
if (closeResult.exitCode !== 0) {
|
|
35613
|
-
throw new Error(`Failed to close bead because bd close command failed: ${closeResult.stderr.toString()}. Try: Verify bead exists and is not already closed with 'bd show ${args.bead_id}', check if bead ID is correct with 'beads_query()', or use beads_close tool directly.`);
|
|
35614
|
-
}
|
|
35615
|
-
try {
|
|
35616
35667
|
const epicId2 = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
35617
|
-
const
|
|
35618
|
-
|
|
35619
|
-
|
|
35620
|
-
|
|
35621
|
-
|
|
35622
|
-
|
|
35623
|
-
|
|
35624
|
-
|
|
35625
|
-
|
|
35626
|
-
|
|
35627
|
-
|
|
35628
|
-
|
|
35629
|
-
await appendEvent(event, args.project_key);
|
|
35630
|
-
} catch (error45) {
|
|
35631
|
-
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
35632
|
-
}
|
|
35633
|
-
try {
|
|
35634
|
-
await releaseSwarmFiles({
|
|
35668
|
+
const completionBody = [
|
|
35669
|
+
`## Subtask Complete: ${args.bead_id}`,
|
|
35670
|
+
"",
|
|
35671
|
+
`**Summary**: ${args.summary}`,
|
|
35672
|
+
"",
|
|
35673
|
+
parsedEvaluation ? `**Self-Evaluation**: ${parsedEvaluation.passed ? "PASSED" : "FAILED"}` : "",
|
|
35674
|
+
parsedEvaluation?.overall_feedback ? `**Feedback**: ${parsedEvaluation.overall_feedback}` : "",
|
|
35675
|
+
"",
|
|
35676
|
+
`**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
|
|
35677
|
+
].filter(Boolean).join(`
|
|
35678
|
+
`);
|
|
35679
|
+
await sendSwarmMessage({
|
|
35635
35680
|
projectPath: args.project_key,
|
|
35636
|
-
|
|
35681
|
+
fromAgent: args.agent_name,
|
|
35682
|
+
toAgents: [],
|
|
35683
|
+
subject: `Complete: ${args.bead_id}`,
|
|
35684
|
+
body: completionBody,
|
|
35685
|
+
threadId: epicId2,
|
|
35686
|
+
importance: "normal"
|
|
35637
35687
|
});
|
|
35638
|
-
|
|
35639
|
-
|
|
35640
|
-
|
|
35641
|
-
|
|
35642
|
-
|
|
35643
|
-
|
|
35644
|
-
|
|
35645
|
-
|
|
35646
|
-
|
|
35647
|
-
|
|
35648
|
-
|
|
35649
|
-
|
|
35650
|
-
|
|
35651
|
-
|
|
35652
|
-
|
|
35653
|
-
|
|
35654
|
-
|
|
35655
|
-
|
|
35656
|
-
|
|
35657
|
-
|
|
35658
|
-
|
|
35659
|
-
|
|
35660
|
-
|
|
35661
|
-
|
|
35662
|
-
|
|
35663
|
-
|
|
35664
|
-
|
|
35665
|
-
|
|
35666
|
-
|
|
35667
|
-
|
|
35668
|
-
warning: registrationWarning || undefined
|
|
35669
|
-
},
|
|
35670
|
-
verification_gate: verificationResult ? {
|
|
35671
|
-
passed: true,
|
|
35672
|
-
summary: verificationResult.summary,
|
|
35673
|
-
steps: verificationResult.steps.map((s) => ({
|
|
35674
|
-
name: s.name,
|
|
35675
|
-
passed: s.passed,
|
|
35676
|
-
skipped: s.skipped,
|
|
35677
|
-
skipReason: s.skipReason
|
|
35678
|
-
}))
|
|
35679
|
-
} : args.skip_verification ? { skipped: true, reason: "skip_verification=true" } : { skipped: true, reason: "no files_touched provided" },
|
|
35680
|
-
ubs_scan: ubsResult ? {
|
|
35681
|
-
ran: true,
|
|
35682
|
-
bugs_found: ubsResult.summary.total,
|
|
35683
|
-
summary: ubsResult.summary,
|
|
35684
|
-
warnings: ubsResult.bugs.filter((b) => b.severity !== "critical")
|
|
35685
|
-
} : verificationResult ? { ran: true, included_in_verification_gate: true } : {
|
|
35686
|
-
ran: false,
|
|
35687
|
-
reason: args.skip_ubs_scan ? "skipped" : "no files or ubs unavailable"
|
|
35688
|
-
},
|
|
35689
|
-
learning_prompt: `## Reflection
|
|
35688
|
+
const response = {
|
|
35689
|
+
success: true,
|
|
35690
|
+
bead_id: args.bead_id,
|
|
35691
|
+
closed: true,
|
|
35692
|
+
reservations_released: true,
|
|
35693
|
+
message_sent: true,
|
|
35694
|
+
agent_registration: {
|
|
35695
|
+
verified: agentRegistered,
|
|
35696
|
+
warning: registrationWarning || undefined
|
|
35697
|
+
},
|
|
35698
|
+
verification_gate: verificationResult ? {
|
|
35699
|
+
passed: true,
|
|
35700
|
+
summary: verificationResult.summary,
|
|
35701
|
+
steps: verificationResult.steps.map((s) => ({
|
|
35702
|
+
name: s.name,
|
|
35703
|
+
passed: s.passed,
|
|
35704
|
+
skipped: s.skipped,
|
|
35705
|
+
skipReason: s.skipReason
|
|
35706
|
+
}))
|
|
35707
|
+
} : args.skip_verification ? { skipped: true, reason: "skip_verification=true" } : { skipped: true, reason: "no files_touched provided" },
|
|
35708
|
+
ubs_scan: ubsResult ? {
|
|
35709
|
+
ran: true,
|
|
35710
|
+
bugs_found: ubsResult.summary.total,
|
|
35711
|
+
summary: ubsResult.summary,
|
|
35712
|
+
warnings: ubsResult.bugs.filter((b) => b.severity !== "critical")
|
|
35713
|
+
} : verificationResult ? { ran: true, included_in_verification_gate: true } : {
|
|
35714
|
+
ran: false,
|
|
35715
|
+
reason: args.skip_ubs_scan ? "skipped" : "no files or ubs unavailable"
|
|
35716
|
+
},
|
|
35717
|
+
learning_prompt: `## Reflection
|
|
35690
35718
|
|
|
35691
35719
|
Did you learn anything reusable during this subtask? Consider:
|
|
35692
35720
|
|
|
@@ -35698,9 +35726,81 @@ Did you learn anything reusable during this subtask? Consider:
|
|
|
35698
35726
|
If you discovered something valuable, use \`swarm_learn\` or \`skills_create\` to preserve it as a skill for future swarms.
|
|
35699
35727
|
|
|
35700
35728
|
Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
|
|
35701
|
-
|
|
35702
|
-
|
|
35703
|
-
|
|
35729
|
+
memory_capture: {
|
|
35730
|
+
attempted: true,
|
|
35731
|
+
stored: memoryStored,
|
|
35732
|
+
error: memoryError,
|
|
35733
|
+
information: memoryInfo.information,
|
|
35734
|
+
metadata: memoryInfo.metadata,
|
|
35735
|
+
note: memoryStored ? "Learning automatically stored in semantic-memory" : `Failed to store: ${memoryError}. Learning lost unless semantic-memory is available.`
|
|
35736
|
+
}
|
|
35737
|
+
};
|
|
35738
|
+
return JSON.stringify(response, null, 2);
|
|
35739
|
+
} catch (error45) {
|
|
35740
|
+
const errorMessage = error45 instanceof Error ? error45.message : String(error45);
|
|
35741
|
+
const errorStack = error45 instanceof Error ? error45.stack : undefined;
|
|
35742
|
+
let failedStep = "unknown";
|
|
35743
|
+
if (errorMessage.includes("verification")) {
|
|
35744
|
+
failedStep = "Verification Gate (UBS/typecheck/tests)";
|
|
35745
|
+
} else if (errorMessage.includes("UBS") || errorMessage.includes("ubs")) {
|
|
35746
|
+
failedStep = "UBS scan";
|
|
35747
|
+
} else if (errorMessage.includes("evaluation")) {
|
|
35748
|
+
failedStep = "Self-evaluation parsing";
|
|
35749
|
+
} else if (errorMessage.includes("bead") || errorMessage.includes("close")) {
|
|
35750
|
+
failedStep = "Bead close";
|
|
35751
|
+
} else if (errorMessage.includes("memory") || errorMessage.includes("semantic")) {
|
|
35752
|
+
failedStep = "Memory storage (non-fatal)";
|
|
35753
|
+
} else if (errorMessage.includes("reservation") || errorMessage.includes("release")) {
|
|
35754
|
+
failedStep = "File reservation release";
|
|
35755
|
+
} else if (errorMessage.includes("message") || errorMessage.includes("mail")) {
|
|
35756
|
+
failedStep = "Swarm mail notification";
|
|
35757
|
+
}
|
|
35758
|
+
const errorBody = [
|
|
35759
|
+
`## ⚠️ SWARM_COMPLETE FAILED`,
|
|
35760
|
+
"",
|
|
35761
|
+
`**Bead**: ${args.bead_id}`,
|
|
35762
|
+
`**Agent**: ${args.agent_name}`,
|
|
35763
|
+
`**Failed Step**: ${failedStep}`,
|
|
35764
|
+
"",
|
|
35765
|
+
`### Error Message`,
|
|
35766
|
+
"```",
|
|
35767
|
+
errorMessage,
|
|
35768
|
+
"```",
|
|
35769
|
+
"",
|
|
35770
|
+
errorStack ? `### Stack Trace
|
|
35771
|
+
\`\`\`
|
|
35772
|
+
${errorStack.slice(0, 1000)}
|
|
35773
|
+
\`\`\`
|
|
35774
|
+
` : "",
|
|
35775
|
+
`### Context`,
|
|
35776
|
+
`- **Summary**: ${args.summary}`,
|
|
35777
|
+
`- **Files touched**: ${args.files_touched?.length ? args.files_touched.join(", ") : "none"}`,
|
|
35778
|
+
`- **Skip UBS**: ${args.skip_ubs_scan ?? false}`,
|
|
35779
|
+
`- **Skip verification**: ${args.skip_verification ?? false}`,
|
|
35780
|
+
"",
|
|
35781
|
+
`### Recovery Actions`,
|
|
35782
|
+
"1. Check error message for specific issue",
|
|
35783
|
+
"2. Review failed step (UBS scan, typecheck, bead close, etc.)",
|
|
35784
|
+
"3. Fix underlying issue or use skip flags if appropriate",
|
|
35785
|
+
"4. Retry swarm_complete after fixing"
|
|
35786
|
+
].filter(Boolean).join(`
|
|
35787
|
+
`);
|
|
35788
|
+
try {
|
|
35789
|
+
await sendSwarmMessage({
|
|
35790
|
+
projectPath: args.project_key,
|
|
35791
|
+
fromAgent: args.agent_name,
|
|
35792
|
+
toAgents: [],
|
|
35793
|
+
subject: `FAILED: swarm_complete for ${args.bead_id}`,
|
|
35794
|
+
body: errorBody,
|
|
35795
|
+
threadId: epicId,
|
|
35796
|
+
importance: "urgent"
|
|
35797
|
+
});
|
|
35798
|
+
} catch (mailError) {
|
|
35799
|
+
console.error(`[swarm_complete] CRITICAL: Failed to notify coordinator of failure for ${args.bead_id}:`, mailError);
|
|
35800
|
+
console.error(`[swarm_complete] Original error:`, error45);
|
|
35801
|
+
}
|
|
35802
|
+
throw error45;
|
|
35803
|
+
}
|
|
35704
35804
|
}
|
|
35705
35805
|
});
|
|
35706
35806
|
var swarm_record_outcome = tool({
|
|
@@ -37603,20 +37703,47 @@ async function execSemanticMemory2(args) {
|
|
|
37603
37703
|
};
|
|
37604
37704
|
}
|
|
37605
37705
|
}
|
|
37606
|
-
|
|
37607
|
-
|
|
37608
|
-
collections: {
|
|
37706
|
+
function getCollectionNames() {
|
|
37707
|
+
const base = {
|
|
37609
37708
|
feedback: "swarm-feedback",
|
|
37610
37709
|
patterns: "swarm-patterns",
|
|
37611
37710
|
maturity: "swarm-maturity"
|
|
37612
|
-
}
|
|
37711
|
+
};
|
|
37712
|
+
if (process.env.TEST_MEMORY_COLLECTIONS === "true") {
|
|
37713
|
+
return {
|
|
37714
|
+
feedback: `${base.feedback}-test`,
|
|
37715
|
+
patterns: `${base.patterns}-test`,
|
|
37716
|
+
maturity: `${base.maturity}-test`
|
|
37717
|
+
};
|
|
37718
|
+
}
|
|
37719
|
+
return base;
|
|
37720
|
+
}
|
|
37721
|
+
var DEFAULT_STORAGE_CONFIG = {
|
|
37722
|
+
backend: "semantic-memory",
|
|
37723
|
+
collections: getCollectionNames(),
|
|
37613
37724
|
useSemanticSearch: true
|
|
37614
37725
|
};
|
|
37615
|
-
|
|
37726
|
+
var sessionStats = {
|
|
37727
|
+
storesCount: 0,
|
|
37728
|
+
queriesCount: 0,
|
|
37729
|
+
sessionStart: Date.now(),
|
|
37730
|
+
lastAlertCheck: Date.now()
|
|
37731
|
+
};
|
|
37616
37732
|
class SemanticMemoryStorage {
|
|
37617
37733
|
config;
|
|
37618
37734
|
constructor(config2 = {}) {
|
|
37619
37735
|
this.config = { ...DEFAULT_STORAGE_CONFIG, ...config2 };
|
|
37736
|
+
console.log(`[storage] SemanticMemoryStorage initialized with collections:`, this.config.collections);
|
|
37737
|
+
}
|
|
37738
|
+
async checkLowUsageAlert() {
|
|
37739
|
+
const TEN_MINUTES = 10 * 60 * 1000;
|
|
37740
|
+
const now = Date.now();
|
|
37741
|
+
const sessionDuration = now - sessionStats.sessionStart;
|
|
37742
|
+
const timeSinceLastAlert = now - sessionStats.lastAlertCheck;
|
|
37743
|
+
if (sessionDuration >= TEN_MINUTES && sessionStats.storesCount < 1 && timeSinceLastAlert >= TEN_MINUTES) {
|
|
37744
|
+
console.warn(`[storage] LOW USAGE ALERT: ${sessionStats.storesCount} stores after ${Math.floor(sessionDuration / 60000)} minutes`);
|
|
37745
|
+
sessionStats.lastAlertCheck = now;
|
|
37746
|
+
}
|
|
37620
37747
|
}
|
|
37621
37748
|
async store(collection, data, metadata) {
|
|
37622
37749
|
const content = typeof data === "string" ? data : JSON.stringify(data);
|
|
@@ -37624,7 +37751,13 @@ class SemanticMemoryStorage {
|
|
|
37624
37751
|
if (metadata) {
|
|
37625
37752
|
args.push("--metadata", JSON.stringify(metadata));
|
|
37626
37753
|
}
|
|
37627
|
-
|
|
37754
|
+
console.log(`[storage] store() -> collection="${collection}"`);
|
|
37755
|
+
sessionStats.storesCount++;
|
|
37756
|
+
const result = await execSemanticMemory2(args);
|
|
37757
|
+
if (result.exitCode !== 0) {
|
|
37758
|
+
console.warn(`[storage] semantic-memory store() failed with exit code ${result.exitCode}: ${result.stderr.toString().trim()}`);
|
|
37759
|
+
}
|
|
37760
|
+
await this.checkLowUsageAlert();
|
|
37628
37761
|
}
|
|
37629
37762
|
async find(collection, query, limit = 10, useFts = false) {
|
|
37630
37763
|
const args = [
|
|
@@ -37639,6 +37772,8 @@ class SemanticMemoryStorage {
|
|
|
37639
37772
|
if (useFts) {
|
|
37640
37773
|
args.push("--fts");
|
|
37641
37774
|
}
|
|
37775
|
+
console.log(`[storage] find() -> collection="${collection}", query="${query.slice(0, 50)}${query.length > 50 ? "..." : ""}", limit=${limit}, fts=${useFts}`);
|
|
37776
|
+
sessionStats.queriesCount++;
|
|
37642
37777
|
const result = await execSemanticMemory2(args);
|
|
37643
37778
|
if (result.exitCode !== 0) {
|
|
37644
37779
|
console.warn(`[storage] semantic-memory find() failed with exit code ${result.exitCode}: ${result.stderr.toString().trim()}`);
|
|
@@ -37664,6 +37799,8 @@ class SemanticMemoryStorage {
|
|
|
37664
37799
|
}
|
|
37665
37800
|
}
|
|
37666
37801
|
async list(collection) {
|
|
37802
|
+
console.log(`[storage] list() -> collection="${collection}"`);
|
|
37803
|
+
sessionStats.queriesCount++;
|
|
37667
37804
|
const result = await execSemanticMemory2([
|
|
37668
37805
|
"list",
|
|
37669
37806
|
"--collection",
|