@voybio/ace-swarm 2.4.0 → 2.4.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +1 -0
  3. package/assets/.agents/ACE/agent-qa/instructions.md +11 -0
  4. package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +43 -0
  5. package/assets/agent-state/runtime-tool-specs.json +70 -2
  6. package/assets/instructions/ACE_Coder.instructions.md +13 -0
  7. package/assets/instructions/ACE_UI.instructions.md +11 -0
  8. package/dist/ace-context.js +70 -11
  9. package/dist/ace-internal-tools.d.ts +3 -1
  10. package/dist/ace-internal-tools.js +10 -2
  11. package/dist/agent-runtime/role-adapters.d.ts +18 -1
  12. package/dist/agent-runtime/role-adapters.js +49 -5
  13. package/dist/astgrep-index.d.ts +48 -0
  14. package/dist/astgrep-index.js +126 -1
  15. package/dist/cli.js +205 -15
  16. package/dist/discovery-runtime-wrappers.d.ts +108 -0
  17. package/dist/discovery-runtime-wrappers.js +615 -0
  18. package/dist/helpers/bootstrap.js +1 -1
  19. package/dist/helpers/constants.d.ts +2 -2
  20. package/dist/helpers/constants.js +7 -0
  21. package/dist/helpers/path-utils.d.ts +8 -1
  22. package/dist/helpers/path-utils.js +27 -8
  23. package/dist/helpers/store-resolution.js +7 -3
  24. package/dist/job-scheduler.js +30 -4
  25. package/dist/json-sanitizer.d.ts +16 -0
  26. package/dist/json-sanitizer.js +26 -0
  27. package/dist/local-model-policy.d.ts +27 -0
  28. package/dist/local-model-policy.js +84 -0
  29. package/dist/local-model-runtime.d.ts +6 -0
  30. package/dist/local-model-runtime.js +21 -20
  31. package/dist/model-bridge.d.ts +6 -1
  32. package/dist/model-bridge.js +338 -21
  33. package/dist/orchestrator-supervisor.d.ts +42 -0
  34. package/dist/orchestrator-supervisor.js +110 -3
  35. package/dist/plan-proposal.d.ts +115 -0
  36. package/dist/plan-proposal.js +1073 -0
  37. package/dist/runtime-executor.d.ts +6 -1
  38. package/dist/runtime-executor.js +72 -5
  39. package/dist/runtime-tool-specs.d.ts +19 -1
  40. package/dist/runtime-tool-specs.js +67 -26
  41. package/dist/schemas.js +29 -1
  42. package/dist/server.js +51 -0
  43. package/dist/shared.d.ts +1 -0
  44. package/dist/shared.js +2 -0
  45. package/dist/store/bootstrap-store.d.ts +1 -0
  46. package/dist/store/bootstrap-store.js +8 -2
  47. package/dist/store/repositories/local-model-runtime-repository.d.ts +1 -1
  48. package/dist/store/repositories/local-model-runtime-repository.js +1 -1
  49. package/dist/store/repositories/vericify-repository.d.ts +1 -1
  50. package/dist/tools-agent.d.ts +20 -0
  51. package/dist/tools-agent.js +538 -28
  52. package/dist/tools-discovery.js +135 -0
  53. package/dist/tools-files.js +768 -66
  54. package/dist/tools-framework.js +80 -61
  55. package/dist/tui/index.js +10 -1
  56. package/dist/tui/ollama.d.ts +8 -1
  57. package/dist/tui/ollama.js +53 -12
  58. package/dist/tui/openai-compatible.d.ts +13 -0
  59. package/dist/tui/openai-compatible.js +305 -5
  60. package/dist/tui/provider-discovery.d.ts +1 -0
  61. package/dist/tui/provider-discovery.js +35 -11
  62. package/dist/vericify-bridge.d.ts +1 -1
  63. package/package.json +1 -1
@@ -213,9 +213,7 @@ export function amendTaskPlan(plan, amendment) {
213
213
  });
214
214
  }
215
215
  export function collectUpstreamOutputs(plan, step) {
216
- if (!step.depends_on || step.depends_on.length === 0)
217
- return [];
218
- return step.depends_on
216
+ const dependencyOutputs = (step.depends_on ?? [])
219
217
  .map((depId) => plan.steps.find((s) => s.step_id === depId))
220
218
  .filter((dep) => dep?.status === "done")
221
219
  .map((dep) => ({
@@ -223,6 +221,15 @@ export function collectUpstreamOutputs(plan, step) {
223
221
  result_summary: dep.result_summary ?? "",
224
222
  evidence_refs: dep.evidence_refs ?? [],
225
223
  }));
224
+ const carriedOutputs = (step.upstream_outputs ?? []).filter((output) => Boolean(output) &&
225
+ typeof output.step_id === "string" &&
226
+ typeof output.result_summary === "string" &&
227
+ Array.isArray(output.evidence_refs));
228
+ const merged = new Map();
229
+ for (const output of [...dependencyOutputs, ...carriedOutputs]) {
230
+ merged.set(output.step_id, output);
231
+ }
232
+ return [...merged.values()];
226
233
  }
227
234
  export async function applyBridgeResultToStepWithTransition(plan, stepId, result, repo) {
228
235
  const updated = applyBridgeResultToStep(plan, stepId, result);
@@ -335,6 +342,10 @@ export async function superviseTaskPlan(inputPlan, hooks) {
335
342
  });
336
343
  const handoffIds = [];
337
344
  const jobIds = [];
345
+ // Intent verification loop counters (Task 7)
346
+ let replanCount = 0;
347
+ const stepRetryCount = new Map();
348
+ let intentContract = undefined;
338
349
  if (!plan.vcx_cursor && hooks.getVericifyContext) {
339
350
  const contextPacket = await hooks.getVericifyContext(plan);
340
351
  const vcxCursor = extractVcxCursor(contextPacket);
@@ -400,6 +411,102 @@ export async function superviseTaskPlan(inputPlan, hooks) {
400
411
  };
401
412
  }
402
413
  }
414
+ // ── Intent verification loop (Task 7) ────────────────────────────────
415
+ if (hooks.verifyIntent) {
416
+ const verificationStep = plan.steps.find((s) => s.step_id === currentStep.step_id) ?? currentStep;
417
+ const verification = await hooks.verifyIntent({
418
+ plan,
419
+ step: verificationStep,
420
+ result,
421
+ intent_contract: intentContract,
422
+ vericify_delta: vericifyDelta,
423
+ });
424
+ if (verification.outcome === "revisit_step") {
425
+ const retries = stepRetryCount.get(currentStep.step_id) ?? 0;
426
+ if (retries < 1) {
427
+ stepRetryCount.set(currentStep.step_id, retries + 1);
428
+ await hooks.recordIntentVerificationFailure?.({
429
+ plan,
430
+ step: verificationStep,
431
+ result,
432
+ verification,
433
+ from: verificationStep.status,
434
+ to: "planned",
435
+ });
436
+ // Re-queue the step by resetting it to planned with failure context as upstream
437
+ const retryContext = {
438
+ step_id: `${currentStep.step_id}-retry-context`,
439
+ result_summary: `Intent verification requested revisit: ${verification.reason}`,
440
+ evidence_refs: verification.uncovered_clauses ?? [],
441
+ };
442
+ plan = amendTaskPlan(plan, {
443
+ update_steps: [{
444
+ step_id: currentStep.step_id,
445
+ patch: {
446
+ status: "planned",
447
+ result_summary: undefined,
448
+ upstream_outputs: [
449
+ ...(verificationStep.upstream_outputs ?? []),
450
+ retryContext,
451
+ ],
452
+ },
453
+ }],
454
+ });
455
+ // Do not call amendPlan this iteration — continue to next loop pass
456
+ continue;
457
+ }
458
+ else {
459
+ await hooks.recordIntentVerificationFailure?.({
460
+ plan,
461
+ step: verificationStep,
462
+ result,
463
+ verification,
464
+ from: verificationStep.status,
465
+ to: "blocked",
466
+ });
467
+ plan = amendTaskPlan(plan, {
468
+ update_steps: [{
469
+ step_id: currentStep.step_id,
470
+ patch: {
471
+ status: "blocked",
472
+ blocked_reason: verification.reason_code
473
+ ? `Intent verification failed (${verification.reason_code}): ${verification.reason}`
474
+ : `Intent verification failed: ${verification.reason}`,
475
+ },
476
+ }],
477
+ });
478
+ }
479
+ }
480
+ else if (verification.outcome === "replan_required") {
481
+ await hooks.recordIntentVerificationFailure?.({
482
+ plan,
483
+ step: verificationStep,
484
+ result,
485
+ verification,
486
+ from: verificationStep.status,
487
+ to: "planned",
488
+ });
489
+ if (replanCount >= 2) {
490
+ const blockedPlan = { ...plan, status: "blocked" };
491
+ return {
492
+ plan: withDerivedStatus(blockedPlan),
493
+ handoff_ids: handoffIds,
494
+ job_ids: jobIds,
495
+ circuit_opened: false,
496
+ blocked_reason: "intent_drift_unresolvable",
497
+ };
498
+ }
499
+ replanCount += 1;
500
+ const uncovered = verification.uncovered_clauses ?? [];
501
+ if (hooks.replanForClauses && uncovered.length > 0) {
502
+ const replanAmendment = await hooks.replanForClauses({ plan, uncovered_clauses: uncovered });
503
+ if (replanAmendment) {
504
+ plan = amendTaskPlan(plan, replanAmendment);
505
+ }
506
+ }
507
+ }
508
+ }
509
+ // ── End intent verification loop ─────────────────────────────────────
403
510
  const amended = await hooks.amendPlan?.({
404
511
  plan,
405
512
  step: plan.steps.find((step) => step.step_id === currentStep.step_id) ?? currentStep,
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Workstream J — Planner contract: propose_plan, validate_plan, loadAcceptanceTraceContract.
3
+ * Extracted to its own module so both tools-agent.ts and runtime-executor.ts can import without
4
+ * a circular dependency (tools-agent already imports from runtime-executor).
5
+ */
6
+ export type OrchestratorPlanSource = "explicit_steps" | "orchestrator_default_step" | "planner_model" | "deterministic_fallback";
7
+ export type ExpectedOutputClass = "plain_text_plan" | "tool_envelope" | "code_artifact" | "structural_edit_plan" | "qa_verdict";
8
+ export interface ContractArtifactExpectation {
9
+ path: string;
10
+ required?: boolean;
11
+ evidence_ref_kind?: "artifact" | "diff" | "hash" | "test" | "gate";
12
+ }
13
+ export interface PlanProposalStep {
14
+ role: string;
15
+ task: string;
16
+ depends_on?: string[];
17
+ tool_scope?: string[];
18
+ acceptance_criteria: string[];
19
+ stop_condition?: string[];
20
+ expected_output_class?: ExpectedOutputClass;
21
+ expected_artifacts?: ContractArtifactExpectation[];
22
+ allowed_tools?: string[];
23
+ forbidden_patterns?: string[];
24
+ required_evidence_refs?: string[];
25
+ structural_edit_plan_required?: boolean;
26
+ structural_edit_waiver?: {
27
+ reason: string;
28
+ evidence_ref: string;
29
+ };
30
+ }
31
+ export interface PlanProposal {
32
+ intent_summary: string;
33
+ success_criteria: string[];
34
+ steps: PlanProposalStep[];
35
+ }
36
+ export interface PlanValidationVerdict {
37
+ ok: boolean;
38
+ score: number;
39
+ blocking_findings: string[];
40
+ soft_findings: string[];
41
+ }
42
+ export interface ProposePlanResult {
43
+ plan_id: string;
44
+ status: "planning";
45
+ intent_summary: string;
46
+ success_criteria: string[];
47
+ steps: PlanProposalStep[];
48
+ plan_source: OrchestratorPlanSource;
49
+ }
50
+ export interface AcceptanceTraceContractStep {
51
+ step_id: string;
52
+ role: string;
53
+ task: string;
54
+ depends_on: string[];
55
+ tool_scope: string[];
56
+ verification_role: string | null;
57
+ acceptance_criteria?: string[];
58
+ stop_condition?: string[];
59
+ expected_output_class?: ExpectedOutputClass;
60
+ expected_artifacts?: ContractArtifactExpectation[];
61
+ allowed_tools?: string[];
62
+ forbidden_patterns?: string[];
63
+ required_evidence_refs?: string[];
64
+ structural_edit_plan_required?: boolean;
65
+ structural_edit_waiver?: {
66
+ reason: string;
67
+ evidence_ref: string;
68
+ };
69
+ }
70
+ export interface AcceptanceTraceContract {
71
+ version: number;
72
+ generated_at: string;
73
+ plan_id: string;
74
+ task: string;
75
+ plan_source: string;
76
+ intent_summary?: string;
77
+ success_criteria?: string[];
78
+ validation_verdict?: PlanValidationVerdict;
79
+ policies: {
80
+ inserted_research_before_spec: boolean;
81
+ ship_fanout_enabled: boolean;
82
+ };
83
+ steps: AcceptanceTraceContractStep[];
84
+ }
85
+ export declare function lookupProposal(plan_id: string): ProposePlanResult | undefined;
86
+ export declare function inferExpectedOutputClass(step: Pick<PlanProposalStep, "role" | "tool_scope">): ExpectedOutputClass;
87
+ /**
88
+ * Lightweight synchronous variant used in runtime preflights.
89
+ * Skips the model bridge call entirely and returns the deterministic goal scaffold.
90
+ * This keeps the preflight free of network I/O that could delay session startup.
91
+ */
92
+ export declare function proposePlanDeterministic(task: string): ProposePlanResult;
93
+ export declare function proposePlan(task: string, sessionId?: string): Promise<ProposePlanResult>;
94
+ export declare function validatePlan(input: {
95
+ plan_id?: string;
96
+ proposal?: ProposePlanResult;
97
+ sessionId?: string;
98
+ }): Promise<PlanValidationVerdict & {
99
+ plan_id: string;
100
+ }>;
101
+ export declare function loadAcceptanceTraceContract(plan_id: string): AcceptanceTraceContract | undefined;
102
+ export declare function persistAcceptanceTraceMapWithContract(input: {
103
+ plan_id: string;
104
+ task: string;
105
+ plan_source: string;
106
+ intent_summary?: string;
107
+ success_criteria?: string[];
108
+ validation_verdict?: PlanValidationVerdict;
109
+ policies: {
110
+ inserted_research_before_spec: boolean;
111
+ ship_fanout_enabled: boolean;
112
+ };
113
+ steps: AcceptanceTraceContractStep[];
114
+ }): Promise<string>;
115
+ //# sourceMappingURL=plan-proposal.d.ts.map