opencode-swarm-plugin 0.33.0 → 0.35.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/.hive/issues.jsonl +12 -0
- package/.hive/memories.jsonl +255 -1
- package/.turbo/turbo-build.log +4 -4
- package/.turbo/turbo-test.log +289 -289
- package/CHANGELOG.md +133 -0
- package/README.md +29 -1
- package/bin/swarm.test.ts +342 -1
- package/bin/swarm.ts +351 -4
- package/dist/compaction-hook.d.ts +1 -1
- package/dist/compaction-hook.d.ts.map +1 -1
- package/dist/index.d.ts +95 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11848 -124
- package/dist/logger.d.ts +34 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/plugin.js +11722 -112
- package/dist/swarm-orchestrate.d.ts +105 -0
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts +54 -2
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-research.d.ts +127 -0
- package/dist/swarm-research.d.ts.map +1 -0
- package/dist/swarm-review.d.ts.map +1 -1
- package/dist/swarm.d.ts +56 -1
- package/dist/swarm.d.ts.map +1 -1
- package/evals/compaction-resumption.eval.ts +289 -0
- package/evals/coordinator-behavior.eval.ts +307 -0
- package/evals/fixtures/compaction-cases.ts +350 -0
- package/evals/scorers/compaction-scorers.ts +305 -0
- package/evals/scorers/index.ts +12 -0
- package/package.json +5 -2
- package/src/compaction-hook.test.ts +639 -1
- package/src/compaction-hook.ts +488 -18
- package/src/index.ts +29 -0
- package/src/logger.test.ts +189 -0
- package/src/logger.ts +135 -0
- package/src/swarm-decompose.ts +0 -7
- package/src/swarm-prompts.test.ts +164 -1
- package/src/swarm-prompts.ts +179 -12
- package/src/swarm-review.test.ts +177 -0
- package/src/swarm-review.ts +12 -47
package/src/swarm-prompts.ts
CHANGED
|
@@ -743,10 +743,32 @@ swarm_review_feedback(
|
|
|
743
743
|
)
|
|
744
744
|
\`\`\`
|
|
745
745
|
|
|
746
|
-
### Step 5:
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
-
|
|
746
|
+
### Step 5: Take Action Based on Review
|
|
747
|
+
|
|
748
|
+
**If APPROVED:**
|
|
749
|
+
- Close the cell with hive_close
|
|
750
|
+
- Spawn next worker (if any) using swarm_spawn_subtask
|
|
751
|
+
|
|
752
|
+
**If NEEDS_CHANGES:**
|
|
753
|
+
- Generate retry prompt:
|
|
754
|
+
\`\`\`
|
|
755
|
+
swarm_spawn_retry(
|
|
756
|
+
bead_id="{task_id}",
|
|
757
|
+
epic_id="{epic_id}",
|
|
758
|
+
original_prompt="<original prompt>",
|
|
759
|
+
attempt=<current_attempt>,
|
|
760
|
+
issues="<JSON from swarm_review_feedback>",
|
|
761
|
+
diff="<git diff of previous changes>",
|
|
762
|
+
files=[{files_touched}],
|
|
763
|
+
project_path="{project_key}"
|
|
764
|
+
)
|
|
765
|
+
\`\`\`
|
|
766
|
+
- Spawn new worker with Task() using the retry prompt
|
|
767
|
+
- Increment attempt counter (max 3 attempts)
|
|
768
|
+
|
|
769
|
+
**If 3 FAILURES:**
|
|
770
|
+
- Mark task as blocked: \`hive_update(id="{task_id}", status="blocked")\`
|
|
771
|
+
- Escalate to human - likely an architectural problem, not execution issue
|
|
750
772
|
|
|
751
773
|
**⚠️ DO NOT spawn the next worker until review is complete.**
|
|
752
774
|
`;
|
|
@@ -1164,6 +1186,157 @@ export const swarm_spawn_researcher = tool({
|
|
|
1164
1186
|
},
|
|
1165
1187
|
});
|
|
1166
1188
|
|
|
1189
|
+
/**
|
|
1190
|
+
* Generate retry prompt for a worker that needs to fix issues from review feedback
|
|
1191
|
+
*
|
|
1192
|
+
* Coordinators use this when swarm_review_feedback returns "needs_changes".
|
|
1193
|
+
* Creates a new worker spawn with context about what went wrong and what to fix.
|
|
1194
|
+
*/
|
|
1195
|
+
export const swarm_spawn_retry = tool({
|
|
1196
|
+
description:
|
|
1197
|
+
"Generate retry prompt for a worker that failed review. Includes issues from previous attempt, diff if provided, and standard worker contract.",
|
|
1198
|
+
args: {
|
|
1199
|
+
bead_id: tool.schema.string().describe("Original subtask bead ID"),
|
|
1200
|
+
epic_id: tool.schema.string().describe("Parent epic bead ID"),
|
|
1201
|
+
original_prompt: tool.schema.string().describe("The prompt given to failed worker"),
|
|
1202
|
+
attempt: tool.schema.number().int().min(1).max(3).describe("Current attempt number (1, 2, or 3)"),
|
|
1203
|
+
issues: tool.schema.string().describe("JSON array of ReviewIssue objects from swarm_review_feedback"),
|
|
1204
|
+
diff: tool.schema
|
|
1205
|
+
.string()
|
|
1206
|
+
.optional()
|
|
1207
|
+
.describe("Git diff of previous changes"),
|
|
1208
|
+
files: tool.schema
|
|
1209
|
+
.array(tool.schema.string())
|
|
1210
|
+
.describe("Files to modify (from original subtask)"),
|
|
1211
|
+
project_path: tool.schema
|
|
1212
|
+
.string()
|
|
1213
|
+
.optional()
|
|
1214
|
+
.describe("Absolute project path for swarmmail_init"),
|
|
1215
|
+
},
|
|
1216
|
+
async execute(args) {
|
|
1217
|
+
// Validate attempt number
|
|
1218
|
+
if (args.attempt > 3) {
|
|
1219
|
+
throw new Error(
|
|
1220
|
+
`Retry attempt ${args.attempt} exceeds maximum of 3. After 3 failures, task should be marked blocked.`,
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// Parse issues
|
|
1225
|
+
let issuesArray: Array<{
|
|
1226
|
+
file: string;
|
|
1227
|
+
line: number;
|
|
1228
|
+
issue: string;
|
|
1229
|
+
suggestion: string;
|
|
1230
|
+
}> = [];
|
|
1231
|
+
try {
|
|
1232
|
+
issuesArray = JSON.parse(args.issues);
|
|
1233
|
+
} catch (e) {
|
|
1234
|
+
// If issues is not valid JSON, treat as empty array
|
|
1235
|
+
issuesArray = [];
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// Format issues section
|
|
1239
|
+
const issuesSection = issuesArray.length > 0
|
|
1240
|
+
? `## ISSUES FROM PREVIOUS ATTEMPT
|
|
1241
|
+
|
|
1242
|
+
The previous attempt had the following issues that need to be fixed:
|
|
1243
|
+
|
|
1244
|
+
${issuesArray
|
|
1245
|
+
.map(
|
|
1246
|
+
(issue, idx) =>
|
|
1247
|
+
`**${idx + 1}. ${issue.file}:${issue.line}**
|
|
1248
|
+
- **Issue**: ${issue.issue}
|
|
1249
|
+
- **Suggestion**: ${issue.suggestion}`,
|
|
1250
|
+
)
|
|
1251
|
+
.join("\n\n")}
|
|
1252
|
+
|
|
1253
|
+
**Critical**: Fix these issues while preserving any working changes from the previous attempt.`
|
|
1254
|
+
: "";
|
|
1255
|
+
|
|
1256
|
+
// Format diff section
|
|
1257
|
+
const diffSection = args.diff
|
|
1258
|
+
? `## PREVIOUS ATTEMPT
|
|
1259
|
+
|
|
1260
|
+
Here's what was tried in the previous attempt:
|
|
1261
|
+
|
|
1262
|
+
\`\`\`diff
|
|
1263
|
+
${args.diff}
|
|
1264
|
+
\`\`\`
|
|
1265
|
+
|
|
1266
|
+
Review this carefully - some changes may be correct and should be preserved.`
|
|
1267
|
+
: "";
|
|
1268
|
+
|
|
1269
|
+
// Build the retry prompt
|
|
1270
|
+
const retryPrompt = `⚠️ **RETRY ATTEMPT ${args.attempt}/3**
|
|
1271
|
+
|
|
1272
|
+
This is a retry of a previously attempted subtask. The coordinator reviewed the previous attempt and found issues that need to be fixed.
|
|
1273
|
+
|
|
1274
|
+
${issuesSection}
|
|
1275
|
+
|
|
1276
|
+
${diffSection}
|
|
1277
|
+
|
|
1278
|
+
## ORIGINAL TASK
|
|
1279
|
+
|
|
1280
|
+
${args.original_prompt}
|
|
1281
|
+
|
|
1282
|
+
## YOUR MISSION
|
|
1283
|
+
|
|
1284
|
+
1. **Understand what went wrong** - Read the issues carefully
|
|
1285
|
+
2. **Fix the specific problems** - Address each issue listed above
|
|
1286
|
+
3. **Preserve working code** - Don't throw away correct changes from previous attempt
|
|
1287
|
+
4. **Follow the standard worker contract** - See below
|
|
1288
|
+
|
|
1289
|
+
## MANDATORY WORKER CONTRACT
|
|
1290
|
+
|
|
1291
|
+
### Step 1: Initialize (REQUIRED FIRST)
|
|
1292
|
+
\`\`\`
|
|
1293
|
+
swarmmail_init(project_path="${args.project_path || "$PWD"}", task_description="${args.bead_id}: Retry ${args.attempt}/3")
|
|
1294
|
+
\`\`\`
|
|
1295
|
+
|
|
1296
|
+
### Step 2: Reserve Files
|
|
1297
|
+
\`\`\`
|
|
1298
|
+
swarmmail_reserve(
|
|
1299
|
+
paths=${JSON.stringify(args.files)},
|
|
1300
|
+
reason="${args.bead_id}: Retry attempt ${args.attempt}",
|
|
1301
|
+
exclusive=true
|
|
1302
|
+
)
|
|
1303
|
+
\`\`\`
|
|
1304
|
+
|
|
1305
|
+
### Step 3: Fix the Issues
|
|
1306
|
+
- Address each issue listed above
|
|
1307
|
+
- Run tests to verify fixes
|
|
1308
|
+
- Don't introduce new bugs
|
|
1309
|
+
|
|
1310
|
+
### Step 4: Complete
|
|
1311
|
+
\`\`\`
|
|
1312
|
+
swarm_complete(
|
|
1313
|
+
project_key="${args.project_path || "$PWD"}",
|
|
1314
|
+
agent_name="<your-agent-name>",
|
|
1315
|
+
bead_id="${args.bead_id}",
|
|
1316
|
+
summary="Fixed issues from review: <brief summary>",
|
|
1317
|
+
files_touched=[<files you modified>]
|
|
1318
|
+
)
|
|
1319
|
+
\`\`\`
|
|
1320
|
+
|
|
1321
|
+
**Remember**: This is attempt ${args.attempt} of 3. If this fails review again, there may be an architectural problem that needs human intervention.
|
|
1322
|
+
|
|
1323
|
+
Begin work now.`;
|
|
1324
|
+
|
|
1325
|
+
return JSON.stringify(
|
|
1326
|
+
{
|
|
1327
|
+
prompt: retryPrompt,
|
|
1328
|
+
bead_id: args.bead_id,
|
|
1329
|
+
attempt: args.attempt,
|
|
1330
|
+
max_attempts: 3,
|
|
1331
|
+
files: args.files,
|
|
1332
|
+
issues_count: issuesArray.length,
|
|
1333
|
+
},
|
|
1334
|
+
null,
|
|
1335
|
+
2,
|
|
1336
|
+
);
|
|
1337
|
+
},
|
|
1338
|
+
});
|
|
1339
|
+
|
|
1167
1340
|
/**
|
|
1168
1341
|
* Generate self-evaluation prompt
|
|
1169
1342
|
*/
|
|
@@ -1220,12 +1393,6 @@ export const swarm_plan_prompt = tool({
|
|
|
1220
1393
|
.enum(["file-based", "feature-based", "risk-based", "auto"])
|
|
1221
1394
|
.optional()
|
|
1222
1395
|
.describe("Decomposition strategy (default: auto-detect)"),
|
|
1223
|
-
max_subtasks: tool.schema
|
|
1224
|
-
.number()
|
|
1225
|
-
.int()
|
|
1226
|
-
.min(1)
|
|
1227
|
-
.optional()
|
|
1228
|
-
.describe("Suggested max subtasks (optional - LLM decides if not specified)"),
|
|
1229
1396
|
context: tool.schema
|
|
1230
1397
|
.string()
|
|
1231
1398
|
.optional()
|
|
@@ -1309,8 +1476,7 @@ export const swarm_plan_prompt = tool({
|
|
|
1309
1476
|
.replace("{strategy_guidelines}", strategyGuidelines)
|
|
1310
1477
|
.replace("{context_section}", contextSection)
|
|
1311
1478
|
.replace("{cass_history}", "") // Empty for now
|
|
1312
|
-
.replace("{skills_context}", skillsContext || "")
|
|
1313
|
-
.replace("{max_subtasks}", (args.max_subtasks ?? 5).toString());
|
|
1479
|
+
.replace("{skills_context}", skillsContext || "");
|
|
1314
1480
|
|
|
1315
1481
|
return JSON.stringify(
|
|
1316
1482
|
{
|
|
@@ -1353,6 +1519,7 @@ export const promptTools = {
|
|
|
1353
1519
|
swarm_subtask_prompt,
|
|
1354
1520
|
swarm_spawn_subtask,
|
|
1355
1521
|
swarm_spawn_researcher,
|
|
1522
|
+
swarm_spawn_retry,
|
|
1356
1523
|
swarm_evaluation_prompt,
|
|
1357
1524
|
swarm_plan_prompt,
|
|
1358
1525
|
};
|
package/src/swarm-review.test.ts
CHANGED
|
@@ -700,3 +700,180 @@ describe("edge cases", () => {
|
|
|
700
700
|
expect(prompt).toContain(longDiff);
|
|
701
701
|
});
|
|
702
702
|
});
|
|
703
|
+
|
|
704
|
+
// ============================================================================
|
|
705
|
+
// Coordinator-Driven Retry: swarm_review_feedback returns retry_context
|
|
706
|
+
// ============================================================================
|
|
707
|
+
|
|
708
|
+
describe("swarm_review_feedback retry_context", () => {
|
|
709
|
+
beforeEach(() => {
|
|
710
|
+
clearReviewStatus("bd-retry-test");
|
|
711
|
+
vi.clearAllMocks();
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
it("returns retry_context when status is needs_changes", async () => {
|
|
715
|
+
const issues = JSON.stringify([
|
|
716
|
+
{ file: "src/auth.ts", line: 42, issue: "Missing null check", suggestion: "Add null check" }
|
|
717
|
+
]);
|
|
718
|
+
|
|
719
|
+
const result = await swarm_review_feedback.execute(
|
|
720
|
+
{
|
|
721
|
+
project_key: "/tmp/test-project",
|
|
722
|
+
task_id: "bd-retry-test",
|
|
723
|
+
worker_id: "worker-test",
|
|
724
|
+
status: "needs_changes",
|
|
725
|
+
issues,
|
|
726
|
+
},
|
|
727
|
+
mockContext
|
|
728
|
+
);
|
|
729
|
+
|
|
730
|
+
const parsed = JSON.parse(result);
|
|
731
|
+
expect(parsed.success).toBe(true);
|
|
732
|
+
expect(parsed.status).toBe("needs_changes");
|
|
733
|
+
// NEW: Should include retry_context for coordinator
|
|
734
|
+
expect(parsed).toHaveProperty("retry_context");
|
|
735
|
+
expect(parsed.retry_context).toHaveProperty("task_id", "bd-retry-test");
|
|
736
|
+
expect(parsed.retry_context).toHaveProperty("attempt", 1);
|
|
737
|
+
expect(parsed.retry_context).toHaveProperty("issues");
|
|
738
|
+
expect(parsed.retry_context.issues).toHaveLength(1);
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
it("retry_context includes issues in structured format", async () => {
|
|
742
|
+
const issues = [
|
|
743
|
+
{ file: "src/a.ts", line: 10, issue: "Bug A", suggestion: "Fix A" },
|
|
744
|
+
{ file: "src/b.ts", line: 20, issue: "Bug B", suggestion: "Fix B" },
|
|
745
|
+
];
|
|
746
|
+
|
|
747
|
+
const result = await swarm_review_feedback.execute(
|
|
748
|
+
{
|
|
749
|
+
project_key: "/tmp/test-project",
|
|
750
|
+
task_id: "bd-retry-test",
|
|
751
|
+
worker_id: "worker-test",
|
|
752
|
+
status: "needs_changes",
|
|
753
|
+
issues: JSON.stringify(issues),
|
|
754
|
+
},
|
|
755
|
+
mockContext
|
|
756
|
+
);
|
|
757
|
+
|
|
758
|
+
const parsed = JSON.parse(result);
|
|
759
|
+
expect(parsed.retry_context.issues).toEqual(issues);
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
it("retry_context includes next_action hint for coordinator", async () => {
|
|
763
|
+
const issues = JSON.stringify([{ file: "x.ts", issue: "bug" }]);
|
|
764
|
+
|
|
765
|
+
const result = await swarm_review_feedback.execute(
|
|
766
|
+
{
|
|
767
|
+
project_key: "/tmp/test-project",
|
|
768
|
+
task_id: "bd-retry-test",
|
|
769
|
+
worker_id: "worker-test",
|
|
770
|
+
status: "needs_changes",
|
|
771
|
+
issues,
|
|
772
|
+
},
|
|
773
|
+
mockContext
|
|
774
|
+
);
|
|
775
|
+
|
|
776
|
+
const parsed = JSON.parse(result);
|
|
777
|
+
// Should tell coordinator what to do next
|
|
778
|
+
expect(parsed.retry_context).toHaveProperty("next_action");
|
|
779
|
+
expect(parsed.retry_context.next_action).toContain("swarm_spawn_retry");
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
it("does NOT include retry_context when approved", async () => {
|
|
783
|
+
const result = await swarm_review_feedback.execute(
|
|
784
|
+
{
|
|
785
|
+
project_key: "/tmp/test-project",
|
|
786
|
+
task_id: "bd-retry-test",
|
|
787
|
+
worker_id: "worker-test",
|
|
788
|
+
status: "approved",
|
|
789
|
+
summary: "Looks good!",
|
|
790
|
+
},
|
|
791
|
+
mockContext
|
|
792
|
+
);
|
|
793
|
+
|
|
794
|
+
const parsed = JSON.parse(result);
|
|
795
|
+
expect(parsed.success).toBe(true);
|
|
796
|
+
expect(parsed.status).toBe("approved");
|
|
797
|
+
expect(parsed).not.toHaveProperty("retry_context");
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
it("does NOT include retry_context when task fails (3 attempts)", async () => {
|
|
801
|
+
const issues = JSON.stringify([{ file: "x.ts", issue: "still broken" }]);
|
|
802
|
+
|
|
803
|
+
// Exhaust all attempts
|
|
804
|
+
let result: string = "";
|
|
805
|
+
for (let i = 0; i < 3; i++) {
|
|
806
|
+
result = await swarm_review_feedback.execute(
|
|
807
|
+
{
|
|
808
|
+
project_key: "/tmp/test-project",
|
|
809
|
+
task_id: "bd-retry-test",
|
|
810
|
+
worker_id: "worker-test",
|
|
811
|
+
status: "needs_changes",
|
|
812
|
+
issues,
|
|
813
|
+
},
|
|
814
|
+
mockContext
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
const parsed = JSON.parse(result);
|
|
819
|
+
expect(parsed.task_failed).toBe(true);
|
|
820
|
+
// No retry_context when task is failed - nothing more to retry
|
|
821
|
+
expect(parsed).not.toHaveProperty("retry_context");
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
it("retry_context includes max_attempts for coordinator awareness", async () => {
|
|
825
|
+
const issues = JSON.stringify([{ file: "x.ts", issue: "bug" }]);
|
|
826
|
+
|
|
827
|
+
const result = await swarm_review_feedback.execute(
|
|
828
|
+
{
|
|
829
|
+
project_key: "/tmp/test-project",
|
|
830
|
+
task_id: "bd-retry-test",
|
|
831
|
+
worker_id: "worker-test",
|
|
832
|
+
status: "needs_changes",
|
|
833
|
+
issues,
|
|
834
|
+
},
|
|
835
|
+
mockContext
|
|
836
|
+
);
|
|
837
|
+
|
|
838
|
+
const parsed = JSON.parse(result);
|
|
839
|
+
expect(parsed.retry_context).toHaveProperty("max_attempts", 3);
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
it("does NOT send message to dead worker for needs_changes", async () => {
|
|
843
|
+
const { sendSwarmMessage } = await import("swarm-mail");
|
|
844
|
+
const issues = JSON.stringify([{ file: "x.ts", issue: "bug" }]);
|
|
845
|
+
|
|
846
|
+
await swarm_review_feedback.execute(
|
|
847
|
+
{
|
|
848
|
+
project_key: "/tmp/test-project",
|
|
849
|
+
task_id: "bd-retry-test",
|
|
850
|
+
worker_id: "worker-test",
|
|
851
|
+
status: "needs_changes",
|
|
852
|
+
issues,
|
|
853
|
+
},
|
|
854
|
+
mockContext
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
// Should NOT call sendSwarmMessage for needs_changes
|
|
858
|
+
// Workers are dead - they can't read messages
|
|
859
|
+
expect(sendSwarmMessage).not.toHaveBeenCalled();
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
it("DOES send message for approved status (audit trail)", async () => {
|
|
863
|
+
const { sendSwarmMessage } = await import("swarm-mail");
|
|
864
|
+
|
|
865
|
+
await swarm_review_feedback.execute(
|
|
866
|
+
{
|
|
867
|
+
project_key: "/tmp/test-project",
|
|
868
|
+
task_id: "bd-retry-test",
|
|
869
|
+
worker_id: "worker-test",
|
|
870
|
+
status: "approved",
|
|
871
|
+
summary: "Good work!",
|
|
872
|
+
},
|
|
873
|
+
mockContext
|
|
874
|
+
);
|
|
875
|
+
|
|
876
|
+
// Approved messages are still sent for audit trail
|
|
877
|
+
expect(sendSwarmMessage).toHaveBeenCalled();
|
|
878
|
+
});
|
|
879
|
+
});
|
package/src/swarm-review.ts
CHANGED
|
@@ -551,23 +551,8 @@ You may now complete the task with \`swarm_complete\`.`,
|
|
|
551
551
|
}
|
|
552
552
|
}
|
|
553
553
|
|
|
554
|
-
//
|
|
555
|
-
|
|
556
|
-
projectPath: args.project_key,
|
|
557
|
-
fromAgent: "coordinator",
|
|
558
|
-
toAgents: [args.worker_id],
|
|
559
|
-
subject: `FAILED: ${args.task_id} - max review attempts reached`,
|
|
560
|
-
body: `## Task Failed ✗
|
|
561
|
-
|
|
562
|
-
Maximum review attempts (${MAX_REVIEW_ATTEMPTS}) reached.
|
|
563
|
-
|
|
564
|
-
**Last Issues:**
|
|
565
|
-
${parsedIssues.map((i: ReviewIssue) => `- ${i.file}${i.line ? `:${i.line}` : ""}: ${i.issue}`).join("\n")}
|
|
566
|
-
|
|
567
|
-
The task has been marked as blocked. A human or different approach is needed.`,
|
|
568
|
-
threadId: epicId,
|
|
569
|
-
importance: "urgent",
|
|
570
|
-
});
|
|
554
|
+
// NO sendSwarmMessage - worker is dead, can't read it
|
|
555
|
+
// Coordinator handles retry or escalation
|
|
571
556
|
|
|
572
557
|
return JSON.stringify(
|
|
573
558
|
{
|
|
@@ -584,35 +569,8 @@ The task has been marked as blocked. A human or different approach is needed.`,
|
|
|
584
569
|
);
|
|
585
570
|
}
|
|
586
571
|
|
|
587
|
-
//
|
|
588
|
-
|
|
589
|
-
.map((i: ReviewIssue) => {
|
|
590
|
-
let line = `- **${i.file}**`;
|
|
591
|
-
if (i.line) line += `:${i.line}`;
|
|
592
|
-
line += `: ${i.issue}`;
|
|
593
|
-
if (i.suggestion) line += `\n → ${i.suggestion}`;
|
|
594
|
-
return line;
|
|
595
|
-
})
|
|
596
|
-
.join("\n");
|
|
597
|
-
|
|
598
|
-
await sendSwarmMessage({
|
|
599
|
-
projectPath: args.project_key,
|
|
600
|
-
fromAgent: "coordinator",
|
|
601
|
-
toAgents: [args.worker_id],
|
|
602
|
-
subject: `NEEDS CHANGES: ${args.task_id} (attempt ${attemptNumber}/${MAX_REVIEW_ATTEMPTS})`,
|
|
603
|
-
body: `## Review: Changes Needed
|
|
604
|
-
|
|
605
|
-
${args.summary || "Please address the following issues:"}
|
|
606
|
-
|
|
607
|
-
**Issues:**
|
|
608
|
-
${issuesList}
|
|
609
|
-
|
|
610
|
-
**Remaining attempts:** ${remaining}
|
|
611
|
-
|
|
612
|
-
Please fix these issues and request another review.`,
|
|
613
|
-
threadId: epicId,
|
|
614
|
-
importance: "high",
|
|
615
|
-
});
|
|
572
|
+
// NO sendSwarmMessage for needs_changes - worker is dead
|
|
573
|
+
// Instead, return retry_context for coordinator to use with swarm_spawn_retry
|
|
616
574
|
|
|
617
575
|
return JSON.stringify(
|
|
618
576
|
{
|
|
@@ -622,7 +580,14 @@ Please fix these issues and request another review.`,
|
|
|
622
580
|
attempt: attemptNumber,
|
|
623
581
|
remaining_attempts: remaining,
|
|
624
582
|
issues: parsedIssues,
|
|
625
|
-
message: `
|
|
583
|
+
message: `Review feedback ready. ${remaining} attempt(s) remaining.`,
|
|
584
|
+
retry_context: {
|
|
585
|
+
task_id: args.task_id,
|
|
586
|
+
attempt: attemptNumber,
|
|
587
|
+
max_attempts: MAX_REVIEW_ATTEMPTS,
|
|
588
|
+
issues: parsedIssues,
|
|
589
|
+
next_action: "Use swarm_spawn_retry to spawn new worker with these issues",
|
|
590
|
+
},
|
|
626
591
|
},
|
|
627
592
|
null,
|
|
628
593
|
2
|