opencode-swarm-plugin 0.42.5 → 0.42.7

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.
@@ -1188,8 +1188,9 @@ export async function getPromptInsights(
1188
1188
  */
1189
1189
  async function getCoordinatorInsights(project_key?: string): Promise<string> {
1190
1190
  try {
1191
- // Import swarm-mail and analytics
1192
- const { createLibSQLAdapter, createSwarmMailAdapter, strategySuccessRates } = await import("swarm-mail");
1191
+ // Import swarm-mail and swarm-insights modules
1192
+ const { createLibSQLAdapter, createSwarmMailAdapter } = await import("swarm-mail");
1193
+ const { getStrategyInsights, getPatternInsights, formatInsightsForPrompt } = await import("./swarm-insights.js");
1193
1194
 
1194
1195
  // Create libSQL database adapter
1195
1196
  const dbAdapter = await createLibSQLAdapter({ url: "file:./.swarm-mail/streams.db" });
@@ -1197,48 +1198,32 @@ async function getCoordinatorInsights(project_key?: string): Promise<string> {
1197
1198
  // Create swarm-mail adapter with database
1198
1199
  const adapter = createSwarmMailAdapter(dbAdapter, project_key || "default");
1199
1200
 
1200
- // Get database for raw queries
1201
- const db = await adapter.getDatabase();
1201
+ // Query insights from the new data layer
1202
+ const [strategies, patterns] = await Promise.all([
1203
+ getStrategyInsights(adapter, ""),
1204
+ getPatternInsights(adapter),
1205
+ ]);
1202
1206
 
1203
- // Query strategy success rates
1204
- const query = strategySuccessRates({ project_key });
1205
- const result = await db.query(query.sql, Object.values(query.parameters || {}));
1207
+ // Bundle insights
1208
+ const bundle = {
1209
+ strategies,
1210
+ patterns,
1211
+ };
1212
+
1213
+ // Format for prompt injection (<500 tokens)
1214
+ const formatted = formatInsightsForPrompt(bundle, { maxTokens: 500 });
1206
1215
 
1207
- if (!result || !result.rows || result.rows.length === 0) {
1216
+ if (!formatted) {
1208
1217
  return "";
1209
1218
  }
1210
1219
 
1211
- // Format as markdown table
1212
- const rows = result.rows.map((r: any) => {
1213
- const strategy = r.strategy || "unknown";
1214
- const total = r.total_attempts || 0;
1215
- const successRate = r.success_rate || 0;
1216
- const emoji = successRate >= 80 ? "✅" : successRate >= 60 ? "⚠️" : "❌";
1217
-
1218
- return `| ${emoji} ${strategy} | ${successRate.toFixed(1)}% | ${total} |`;
1219
- });
1220
-
1221
- // Limit to top 5 strategies to prevent context bloat
1222
- const topRows = rows.slice(0, 5);
1223
-
1224
- // Add anti-pattern hints for low-success strategies
1225
- const antiPatterns = result.rows
1226
- .filter((r: any) => r.success_rate < 60)
1227
- .map((r: any) => `- AVOID: ${r.strategy} strategy (${r.success_rate.toFixed(1)}% success rate)`)
1228
- .slice(0, 3);
1229
-
1230
- const antiPatternsSection = antiPatterns.length > 0
1231
- ? `\n\n**Anti-Patterns:**\n${antiPatterns.join("\n")}`
1232
- : "";
1233
-
1220
+ // Add section header
1234
1221
  return `
1235
- ## 📊 Swarm Insights (Strategy Success Rates)
1222
+ ## 📊 Historical Insights
1236
1223
 
1237
- | Strategy | Success Rate | Total Attempts |
1238
- |----------|--------------|----------------|
1239
- ${topRows.join("\n")}
1224
+ ${formatted}
1240
1225
 
1241
- **Use these insights to select decomposition strategies.**${antiPatternsSection}
1226
+ **Use these learnings when selecting decomposition strategies and planning subtasks.**
1242
1227
  `;
1243
1228
  } catch (e) {
1244
1229
  console.warn("Failed to get coordinator insights:", e);
@@ -1254,7 +1239,10 @@ async function getWorkerInsights(
1254
1239
  domain?: string,
1255
1240
  ): Promise<string> {
1256
1241
  try {
1257
- const adapter = await getMemoryAdapter();
1242
+ // Import swarm-mail and swarm-insights modules
1243
+ const { createLibSQLAdapter, createSwarmMailAdapter } = await import("swarm-mail");
1244
+ const { getFileInsights, formatInsightsForPrompt } = await import("./swarm-insights.js");
1245
+ const memoryAdapter = await getMemoryAdapter();
1258
1246
 
1259
1247
  // Build query from files and domain
1260
1248
  let query = "";
@@ -1270,31 +1258,61 @@ async function getWorkerInsights(
1270
1258
  return ""; // No context to query
1271
1259
  }
1272
1260
 
1273
- // Query semantic memory for relevant learnings
1274
- const result = await adapter.find({
1275
- query: `${query} gotcha pitfall pattern bug`,
1276
- limit: 3,
1277
- });
1261
+ // Query BOTH event store (via swarm-insights) AND semantic memory
1262
+ const [fileInsights, memoryResult] = await Promise.all([
1263
+ // Get file-specific insights from event store
1264
+ (async () => {
1265
+ if (!files || files.length === 0) return [];
1266
+ try {
1267
+ const dbAdapter = await createLibSQLAdapter({ url: "file:./.swarm-mail/streams.db" });
1268
+ const swarmMail = createSwarmMailAdapter(dbAdapter, "default");
1269
+ return await getFileInsights(swarmMail, files);
1270
+ } catch (e) {
1271
+ console.warn("Failed to get file insights from event store:", e);
1272
+ return [];
1273
+ }
1274
+ })(),
1275
+
1276
+ // Get domain/file learnings from semantic memory
1277
+ memoryAdapter.find({
1278
+ query: `${query} gotcha pitfall pattern bug`,
1279
+ limit: 3,
1280
+ }),
1281
+ ]);
1278
1282
 
1279
- if (result.count === 0) {
1280
- return "";
1281
- }
1283
+ // Bundle insights for formatting
1284
+ const bundle = {
1285
+ files: fileInsights,
1286
+ };
1282
1287
 
1283
- // Format as bullet list
1284
- const learnings = result.results.map((r) => {
1285
- const content = r.content.length > 150
1286
- ? r.content.slice(0, 150) + "..."
1287
- : r.content;
1288
- return `- ${content}`;
1289
- });
1288
+ // Format file insights using swarm-insights formatter
1289
+ const formattedFileInsights = formatInsightsForPrompt(bundle, { maxTokens: 300 });
1290
1290
 
1291
- return `
1292
- ## 💡 Relevant Learnings (from past agents)
1291
+ // Format semantic memory learnings
1292
+ let formattedMemory = "";
1293
+ if (memoryResult.count > 0) {
1294
+ const learnings = memoryResult.results.map((r) => {
1295
+ const content = r.content.length > 150
1296
+ ? r.content.slice(0, 150) + "..."
1297
+ : r.content;
1298
+ return `- ${content}`;
1299
+ });
1300
+
1301
+ formattedMemory = `## 💡 Relevant Learnings (from past agents)
1293
1302
 
1294
1303
  ${learnings.join("\n")}
1295
1304
 
1296
- **Check semantic-memory for full details if needed.**
1297
- `;
1305
+ **Check semantic-memory for full details if needed.**`;
1306
+ }
1307
+
1308
+ // Combine both sources
1309
+ const sections = [formattedFileInsights, formattedMemory].filter(s => s.length > 0);
1310
+
1311
+ if (sections.length === 0) {
1312
+ return "";
1313
+ }
1314
+
1315
+ return sections.join("\n\n");
1298
1316
  } catch (e) {
1299
1317
  console.warn("Failed to get worker insights:", e);
1300
1318
  return "";