opencastle 0.31.7 → 0.32.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/README.md +4 -1
- package/bin/cli.mjs +15 -0
- package/dist/cli/agents.d.ts.map +1 -1
- package/dist/cli/agents.js +19 -5
- package/dist/cli/agents.js.map +1 -1
- package/dist/cli/artifacts-cli.d.ts +3 -0
- package/dist/cli/artifacts-cli.d.ts.map +1 -0
- package/dist/cli/artifacts-cli.js +36 -0
- package/dist/cli/artifacts-cli.js.map +1 -0
- package/dist/cli/baselines.d.ts.map +1 -1
- package/dist/cli/baselines.js +11 -0
- package/dist/cli/baselines.js.map +1 -1
- package/dist/cli/convoy/artifacts.d.ts +25 -0
- package/dist/cli/convoy/artifacts.d.ts.map +1 -0
- package/dist/cli/convoy/artifacts.js +129 -0
- package/dist/cli/convoy/artifacts.js.map +1 -0
- package/dist/cli/convoy/artifacts.test.d.ts +2 -0
- package/dist/cli/convoy/artifacts.test.d.ts.map +1 -0
- package/dist/cli/convoy/artifacts.test.js +169 -0
- package/dist/cli/convoy/artifacts.test.js.map +1 -0
- package/dist/cli/convoy/compaction.d.ts +23 -0
- package/dist/cli/convoy/compaction.d.ts.map +1 -0
- package/dist/cli/convoy/compaction.js +117 -0
- package/dist/cli/convoy/compaction.js.map +1 -0
- package/dist/cli/convoy/compaction.test.d.ts +2 -0
- package/dist/cli/convoy/compaction.test.d.ts.map +1 -0
- package/dist/cli/convoy/compaction.test.js +205 -0
- package/dist/cli/convoy/compaction.test.js.map +1 -0
- package/dist/cli/convoy/contracts.d.ts +22 -0
- package/dist/cli/convoy/contracts.d.ts.map +1 -0
- package/dist/cli/convoy/contracts.js +254 -0
- package/dist/cli/convoy/contracts.js.map +1 -0
- package/dist/cli/convoy/contracts.test.d.ts +2 -0
- package/dist/cli/convoy/contracts.test.d.ts.map +1 -0
- package/dist/cli/convoy/contracts.test.js +239 -0
- package/dist/cli/convoy/contracts.test.js.map +1 -0
- package/dist/cli/convoy/dag-analysis.d.ts +40 -0
- package/dist/cli/convoy/dag-analysis.d.ts.map +1 -0
- package/dist/cli/convoy/dag-analysis.js +282 -0
- package/dist/cli/convoy/dag-analysis.js.map +1 -0
- package/dist/cli/convoy/dag-analysis.test.d.ts +2 -0
- package/dist/cli/convoy/dag-analysis.test.d.ts.map +1 -0
- package/dist/cli/convoy/dag-analysis.test.js +289 -0
- package/dist/cli/convoy/dag-analysis.test.js.map +1 -0
- package/dist/cli/convoy/effort-scaling.d.ts +20 -0
- package/dist/cli/convoy/effort-scaling.d.ts.map +1 -0
- package/dist/cli/convoy/effort-scaling.js +82 -0
- package/dist/cli/convoy/effort-scaling.js.map +1 -0
- package/dist/cli/convoy/effort-scaling.test.d.ts +2 -0
- package/dist/cli/convoy/effort-scaling.test.d.ts.map +1 -0
- package/dist/cli/convoy/effort-scaling.test.js +120 -0
- package/dist/cli/convoy/effort-scaling.test.js.map +1 -0
- package/dist/cli/convoy/engine.d.ts.map +1 -1
- package/dist/cli/convoy/engine.js +280 -6
- package/dist/cli/convoy/engine.js.map +1 -1
- package/dist/cli/convoy/engine.test.js +155 -18
- package/dist/cli/convoy/engine.test.js.map +1 -1
- package/dist/cli/convoy/event-schemas.d.ts.map +1 -1
- package/dist/cli/convoy/event-schemas.js +55 -0
- package/dist/cli/convoy/event-schemas.js.map +1 -1
- package/dist/cli/convoy/isolation.d.ts +27 -0
- package/dist/cli/convoy/isolation.d.ts.map +1 -0
- package/dist/cli/convoy/isolation.js +120 -0
- package/dist/cli/convoy/isolation.js.map +1 -0
- package/dist/cli/convoy/isolation.test.d.ts +2 -0
- package/dist/cli/convoy/isolation.test.d.ts.map +1 -0
- package/dist/cli/convoy/isolation.test.js +105 -0
- package/dist/cli/convoy/isolation.test.js.map +1 -0
- package/dist/cli/convoy/review-stages.d.ts +9 -0
- package/dist/cli/convoy/review-stages.d.ts.map +1 -0
- package/dist/cli/convoy/review-stages.js +134 -0
- package/dist/cli/convoy/review-stages.js.map +1 -0
- package/dist/cli/convoy/review-stages.test.d.ts +2 -0
- package/dist/cli/convoy/review-stages.test.d.ts.map +1 -0
- package/dist/cli/convoy/review-stages.test.js +197 -0
- package/dist/cli/convoy/review-stages.test.js.map +1 -0
- package/dist/cli/convoy/skill-refinement.d.ts +39 -0
- package/dist/cli/convoy/skill-refinement.d.ts.map +1 -0
- package/dist/cli/convoy/skill-refinement.js +239 -0
- package/dist/cli/convoy/skill-refinement.js.map +1 -0
- package/dist/cli/convoy/skill-refinement.test.d.ts +2 -0
- package/dist/cli/convoy/skill-refinement.test.d.ts.map +1 -0
- package/dist/cli/convoy/skill-refinement.test.js +230 -0
- package/dist/cli/convoy/skill-refinement.test.js.map +1 -0
- package/dist/cli/convoy/spec-builder.d.ts +1 -0
- package/dist/cli/convoy/spec-builder.d.ts.map +1 -1
- package/dist/cli/convoy/spec-builder.js +11 -0
- package/dist/cli/convoy/spec-builder.js.map +1 -1
- package/dist/cli/convoy/spec-builder.test.js +54 -0
- package/dist/cli/convoy/spec-builder.test.js.map +1 -1
- package/dist/cli/convoy/store.d.ts +3 -2
- package/dist/cli/convoy/store.d.ts.map +1 -1
- package/dist/cli/convoy/store.js +20 -2
- package/dist/cli/convoy/store.js.map +1 -1
- package/dist/cli/convoy/store.test.js +15 -15
- package/dist/cli/convoy/store.test.js.map +1 -1
- package/dist/cli/convoy/tdd-gate.d.ts +15 -0
- package/dist/cli/convoy/tdd-gate.d.ts.map +1 -0
- package/dist/cli/convoy/tdd-gate.js +119 -0
- package/dist/cli/convoy/tdd-gate.js.map +1 -0
- package/dist/cli/convoy/tdd-gate.test.d.ts +2 -0
- package/dist/cli/convoy/tdd-gate.test.d.ts.map +1 -0
- package/dist/cli/convoy/tdd-gate.test.js +227 -0
- package/dist/cli/convoy/tdd-gate.test.js.map +1 -0
- package/dist/cli/convoy/types.d.ts +91 -0
- package/dist/cli/convoy/types.d.ts.map +1 -1
- package/dist/cli/convoy/types.js +8 -0
- package/dist/cli/convoy/types.js.map +1 -1
- package/dist/cli/insights.d.ts +3 -0
- package/dist/cli/insights.d.ts.map +1 -0
- package/dist/cli/insights.js +94 -0
- package/dist/cli/insights.js.map +1 -0
- package/dist/cli/lesson.d.ts.map +1 -1
- package/dist/cli/lesson.js +7 -0
- package/dist/cli/lesson.js.map +1 -1
- package/dist/cli/log.d.ts.map +1 -1
- package/dist/cli/log.js +7 -0
- package/dist/cli/log.js.map +1 -1
- package/dist/cli/package-config.d.ts +12 -0
- package/dist/cli/package-config.d.ts.map +1 -0
- package/dist/cli/package-config.js +37 -0
- package/dist/cli/package-config.js.map +1 -0
- package/dist/cli/package.d.ts +23 -0
- package/dist/cli/package.d.ts.map +1 -0
- package/dist/cli/package.js +285 -0
- package/dist/cli/package.js.map +1 -0
- package/dist/cli/package.test.d.ts +2 -0
- package/dist/cli/package.test.d.ts.map +1 -0
- package/dist/cli/package.test.js +236 -0
- package/dist/cli/package.test.js.map +1 -0
- package/dist/cli/pipeline.d.ts +6 -0
- package/dist/cli/pipeline.d.ts.map +1 -1
- package/dist/cli/pipeline.js +15 -2
- package/dist/cli/pipeline.js.map +1 -1
- package/dist/cli/run/schema.d.ts.map +1 -1
- package/dist/cli/run/schema.js +32 -0
- package/dist/cli/run/schema.js.map +1 -1
- package/dist/cli/run/schema.test.js +51 -0
- package/dist/cli/run/schema.test.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/cli/skills.js +107 -0
- package/dist/cli/skills.js.map +1 -0
- package/dist/cli/types.d.ts +4 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/dashboard/scripts/etl.d.ts.map +1 -1
- package/dist/dashboard/scripts/etl.js +44 -11
- package/dist/dashboard/scripts/etl.js.map +1 -1
- package/package.json +2 -1
- package/src/cli/agents.ts +20 -5
- package/src/cli/artifacts-cli.ts +41 -0
- package/src/cli/baselines.ts +12 -0
- package/src/cli/convoy/artifacts.test.ts +201 -0
- package/src/cli/convoy/artifacts.ts +186 -0
- package/src/cli/convoy/compaction.test.ts +245 -0
- package/src/cli/convoy/compaction.ts +164 -0
- package/src/cli/convoy/contracts.test.ts +279 -0
- package/src/cli/convoy/contracts.ts +280 -0
- package/src/cli/convoy/dag-analysis.test.ts +349 -0
- package/src/cli/convoy/dag-analysis.ts +371 -0
- package/src/cli/convoy/effort-scaling.test.ts +140 -0
- package/src/cli/convoy/effort-scaling.ts +90 -0
- package/src/cli/convoy/engine.test.ts +175 -18
- package/src/cli/convoy/engine.ts +301 -7
- package/src/cli/convoy/event-schemas.ts +55 -0
- package/src/cli/convoy/isolation.test.ts +137 -0
- package/src/cli/convoy/isolation.ts +165 -0
- package/src/cli/convoy/review-stages.test.ts +235 -0
- package/src/cli/convoy/review-stages.ts +166 -0
- package/src/cli/convoy/skill-refinement.test.ts +277 -0
- package/src/cli/convoy/skill-refinement.ts +306 -0
- package/src/cli/convoy/spec-builder.test.ts +61 -0
- package/src/cli/convoy/spec-builder.ts +9 -0
- package/src/cli/convoy/store.test.ts +15 -15
- package/src/cli/convoy/store.ts +26 -4
- package/src/cli/convoy/tdd-gate.test.ts +281 -0
- package/src/cli/convoy/tdd-gate.ts +154 -0
- package/src/cli/convoy/types.ts +51 -0
- package/src/cli/insights.ts +99 -0
- package/src/cli/lesson.ts +8 -0
- package/src/cli/log.ts +8 -0
- package/src/cli/package-config.ts +48 -0
- package/src/cli/package.test.ts +276 -0
- package/src/cli/package.ts +329 -0
- package/src/cli/pipeline.ts +21 -2
- package/src/cli/run/schema.test.ts +58 -0
- package/src/cli/run/schema.ts +33 -0
- package/src/cli/skills.ts +121 -0
- package/src/cli/types.ts +4 -1
- package/src/dashboard/dist/_astro/index.D6quLrA6.css +1 -0
- package/src/dashboard/dist/data/convoy-list.json +21 -7
- package/src/dashboard/dist/data/convoys/demo-api-v2.json +3 -3
- package/src/dashboard/dist/data/convoys/demo-auth-revamp.json +5 -5
- package/src/dashboard/dist/data/convoys/demo-convoy-1.json +2 -2
- package/src/dashboard/dist/data/convoys/demo-convoy-2.json +1 -1
- package/src/dashboard/dist/data/convoys/demo-dashboard-ui.json +7 -7
- package/src/dashboard/dist/data/convoys/demo-data-pipeline.json +3 -3
- package/src/dashboard/dist/data/convoys/demo-deploy-ci.json +2 -2
- package/src/dashboard/dist/data/convoys/demo-docs-update.json +2 -2
- package/src/dashboard/dist/data/convoys/demo-perf-opt.json +4 -4
- package/src/dashboard/dist/index.html +306 -33
- package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
- package/src/dashboard/public/data/convoy-list.json +21 -7
- package/src/dashboard/public/data/convoys/demo-api-v2.json +3 -3
- package/src/dashboard/public/data/convoys/demo-auth-revamp.json +5 -5
- package/src/dashboard/public/data/convoys/demo-convoy-1.json +2 -2
- package/src/dashboard/public/data/convoys/demo-convoy-2.json +1 -1
- package/src/dashboard/public/data/convoys/demo-dashboard-ui.json +7 -7
- package/src/dashboard/public/data/convoys/demo-data-pipeline.json +3 -3
- package/src/dashboard/public/data/convoys/demo-deploy-ci.json +2 -2
- package/src/dashboard/public/data/convoys/demo-docs-update.json +2 -2
- package/src/dashboard/public/data/convoys/demo-perf-opt.json +4 -4
- package/src/dashboard/scripts/etl.test.ts +14 -0
- package/src/dashboard/scripts/etl.ts +48 -16
- package/src/dashboard/scripts/generate-demo-db.ts +18 -10
- package/src/dashboard/src/pages/index.astro +348 -45
- package/src/dashboard/src/styles/dashboard.css +56 -0
- package/src/orchestrator/prompts/assess-complexity.prompt.md +13 -0
- package/src/orchestrator/prompts/generate-convoy.prompt.md +19 -0
- package/src/dashboard/dist/_astro/index.BRDFmNzR.css +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface EffortProfile {
|
|
2
|
+
complexity: number;
|
|
3
|
+
tier: 'economy' | 'standard' | 'utility' | 'premium';
|
|
4
|
+
max_agents: number;
|
|
5
|
+
timeout: string;
|
|
6
|
+
max_retries: number;
|
|
7
|
+
review: 'none' | 'auto' | 'fast' | 'panel';
|
|
8
|
+
expected_tokens: number;
|
|
9
|
+
description: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const EFFORT_TABLE: EffortProfile[];
|
|
12
|
+
/**
|
|
13
|
+
* Returns the EffortProfile for a given complexity score.
|
|
14
|
+
* - Exact match: returns that profile
|
|
15
|
+
* - Between defined values: rounds up to the next profile
|
|
16
|
+
* - Below 1: returns the complexity-1 profile
|
|
17
|
+
* - Above 13: returns the complexity-13 profile
|
|
18
|
+
*/
|
|
19
|
+
export declare function getEffortProfile(complexity: number): EffortProfile;
|
|
20
|
+
//# sourceMappingURL=effort-scaling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effort-scaling.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/effort-scaling.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAA;IACpD,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;IAC1C,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,aAAa,EA6DvC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAQlE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export const EFFORT_TABLE = [
|
|
2
|
+
{
|
|
3
|
+
complexity: 1,
|
|
4
|
+
tier: 'economy',
|
|
5
|
+
max_agents: 1,
|
|
6
|
+
timeout: '5m',
|
|
7
|
+
max_retries: 1,
|
|
8
|
+
review: 'auto',
|
|
9
|
+
expected_tokens: 5_000,
|
|
10
|
+
description: 'Trivial — single file edit, copy change, config tweak',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
complexity: 2,
|
|
14
|
+
tier: 'economy',
|
|
15
|
+
max_agents: 1,
|
|
16
|
+
timeout: '10m',
|
|
17
|
+
max_retries: 1,
|
|
18
|
+
review: 'auto',
|
|
19
|
+
expected_tokens: 15_000,
|
|
20
|
+
description: 'Simple — small bug fix, add a test, update docs',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
complexity: 3,
|
|
24
|
+
tier: 'standard',
|
|
25
|
+
max_agents: 1,
|
|
26
|
+
timeout: '15m',
|
|
27
|
+
max_retries: 2,
|
|
28
|
+
review: 'fast',
|
|
29
|
+
expected_tokens: 30_000,
|
|
30
|
+
description: 'Moderate — new component, API endpoint, or utility',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
complexity: 5,
|
|
34
|
+
tier: 'standard',
|
|
35
|
+
max_agents: 2,
|
|
36
|
+
timeout: '20m',
|
|
37
|
+
max_retries: 2,
|
|
38
|
+
review: 'fast',
|
|
39
|
+
expected_tokens: 60_000,
|
|
40
|
+
description: 'Significant — multi-file feature, integration work',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
complexity: 8,
|
|
44
|
+
tier: 'standard',
|
|
45
|
+
max_agents: 3,
|
|
46
|
+
timeout: '30m',
|
|
47
|
+
max_retries: 2,
|
|
48
|
+
review: 'fast',
|
|
49
|
+
expected_tokens: 120_000,
|
|
50
|
+
description: 'Complex — cross-cutting feature, schema change + UI + tests',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
complexity: 13,
|
|
54
|
+
tier: 'premium',
|
|
55
|
+
max_agents: 5,
|
|
56
|
+
timeout: '45m',
|
|
57
|
+
max_retries: 3,
|
|
58
|
+
review: 'panel',
|
|
59
|
+
expected_tokens: 250_000,
|
|
60
|
+
description: 'Epic — architecture change, security overhaul, major refactor',
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
/**
|
|
64
|
+
* Returns the EffortProfile for a given complexity score.
|
|
65
|
+
* - Exact match: returns that profile
|
|
66
|
+
* - Between defined values: rounds up to the next profile
|
|
67
|
+
* - Below 1: returns the complexity-1 profile
|
|
68
|
+
* - Above 13: returns the complexity-13 profile
|
|
69
|
+
*/
|
|
70
|
+
export function getEffortProfile(complexity) {
|
|
71
|
+
if (complexity <= EFFORT_TABLE[0].complexity)
|
|
72
|
+
return EFFORT_TABLE[0];
|
|
73
|
+
const last = EFFORT_TABLE[EFFORT_TABLE.length - 1];
|
|
74
|
+
if (complexity >= last.complexity)
|
|
75
|
+
return last;
|
|
76
|
+
for (const profile of EFFORT_TABLE) {
|
|
77
|
+
if (complexity <= profile.complexity)
|
|
78
|
+
return profile;
|
|
79
|
+
}
|
|
80
|
+
return last;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=effort-scaling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effort-scaling.js","sourceRoot":"","sources":["../../../src/cli/convoy/effort-scaling.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,YAAY,GAAoB;IAC3C;QACE,UAAU,EAAE,CAAC;QACb,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,MAAM;QACd,eAAe,EAAE,KAAK;QACtB,WAAW,EAAE,uDAAuD;KACrE;IACD;QACE,UAAU,EAAE,CAAC;QACb,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,MAAM;QACd,eAAe,EAAE,MAAM;QACvB,WAAW,EAAE,iDAAiD;KAC/D;IACD;QACE,UAAU,EAAE,CAAC;QACb,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,MAAM;QACd,eAAe,EAAE,MAAM;QACvB,WAAW,EAAE,oDAAoD;KAClE;IACD;QACE,UAAU,EAAE,CAAC;QACb,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,MAAM;QACd,eAAe,EAAE,MAAM;QACvB,WAAW,EAAE,oDAAoD;KAClE;IACD;QACE,UAAU,EAAE,CAAC;QACb,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,MAAM;QACd,eAAe,EAAE,OAAO;QACxB,WAAW,EAAE,6DAA6D;KAC3E;IACD;QACE,UAAU,EAAE,EAAE;QACd,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,OAAO;QACf,eAAe,EAAE,OAAO;QACxB,WAAW,EAAE,+DAA+D;KAC7E;CACF,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,IAAI,UAAU,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU;QAAE,OAAO,YAAY,CAAC,CAAC,CAAC,CAAA;IACpE,MAAM,IAAI,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAClD,IAAI,UAAU,IAAI,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAA;IAC9C,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,UAAU,IAAI,OAAO,CAAC,UAAU;YAAE,OAAO,OAAO,CAAA;IACtD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effort-scaling.test.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/effort-scaling.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { getEffortProfile, EFFORT_TABLE } from './effort-scaling.js';
|
|
3
|
+
describe('getEffortProfile', () => {
|
|
4
|
+
it('returns complexity-1 profile for score 1', () => {
|
|
5
|
+
const p = getEffortProfile(1);
|
|
6
|
+
expect(p.complexity).toBe(1);
|
|
7
|
+
expect(p.tier).toBe('economy');
|
|
8
|
+
expect(p.timeout).toBe('5m');
|
|
9
|
+
expect(p.max_retries).toBe(1);
|
|
10
|
+
expect(p.review).toBe('auto');
|
|
11
|
+
expect(p.expected_tokens).toBe(5000);
|
|
12
|
+
});
|
|
13
|
+
it('returns complexity-2 profile for score 2', () => {
|
|
14
|
+
const p = getEffortProfile(2);
|
|
15
|
+
expect(p.complexity).toBe(2);
|
|
16
|
+
expect(p.tier).toBe('economy');
|
|
17
|
+
expect(p.timeout).toBe('10m');
|
|
18
|
+
expect(p.max_retries).toBe(1);
|
|
19
|
+
expect(p.review).toBe('auto');
|
|
20
|
+
expect(p.expected_tokens).toBe(15000);
|
|
21
|
+
});
|
|
22
|
+
it('returns complexity-3 profile for score 3', () => {
|
|
23
|
+
const p = getEffortProfile(3);
|
|
24
|
+
expect(p.complexity).toBe(3);
|
|
25
|
+
expect(p.tier).toBe('standard');
|
|
26
|
+
expect(p.timeout).toBe('15m');
|
|
27
|
+
expect(p.max_retries).toBe(2);
|
|
28
|
+
expect(p.review).toBe('fast');
|
|
29
|
+
expect(p.expected_tokens).toBe(30000);
|
|
30
|
+
});
|
|
31
|
+
it('returns complexity-5 profile for score 5', () => {
|
|
32
|
+
const p = getEffortProfile(5);
|
|
33
|
+
expect(p.complexity).toBe(5);
|
|
34
|
+
expect(p.tier).toBe('standard');
|
|
35
|
+
expect(p.timeout).toBe('20m');
|
|
36
|
+
expect(p.max_retries).toBe(2);
|
|
37
|
+
expect(p.review).toBe('fast');
|
|
38
|
+
expect(p.expected_tokens).toBe(60000);
|
|
39
|
+
});
|
|
40
|
+
it('returns complexity-8 profile for score 8', () => {
|
|
41
|
+
const p = getEffortProfile(8);
|
|
42
|
+
expect(p.complexity).toBe(8);
|
|
43
|
+
expect(p.tier).toBe('standard');
|
|
44
|
+
expect(p.timeout).toBe('30m');
|
|
45
|
+
expect(p.max_retries).toBe(2);
|
|
46
|
+
expect(p.review).toBe('fast');
|
|
47
|
+
expect(p.expected_tokens).toBe(120000);
|
|
48
|
+
});
|
|
49
|
+
it('returns complexity-13 profile for score 13', () => {
|
|
50
|
+
const p = getEffortProfile(13);
|
|
51
|
+
expect(p.complexity).toBe(13);
|
|
52
|
+
expect(p.tier).toBe('premium');
|
|
53
|
+
expect(p.timeout).toBe('45m');
|
|
54
|
+
expect(p.max_retries).toBe(3);
|
|
55
|
+
expect(p.review).toBe('panel');
|
|
56
|
+
expect(p.expected_tokens).toBe(250000);
|
|
57
|
+
});
|
|
58
|
+
it('rounds up score 4 to complexity-5 profile', () => {
|
|
59
|
+
const p = getEffortProfile(4);
|
|
60
|
+
expect(p.complexity).toBe(5);
|
|
61
|
+
});
|
|
62
|
+
it('rounds up score 6 to complexity-8 profile', () => {
|
|
63
|
+
const p = getEffortProfile(6);
|
|
64
|
+
expect(p.complexity).toBe(8);
|
|
65
|
+
});
|
|
66
|
+
it('rounds up score 7 to complexity-8 profile', () => {
|
|
67
|
+
const p = getEffortProfile(7);
|
|
68
|
+
expect(p.complexity).toBe(8);
|
|
69
|
+
});
|
|
70
|
+
it('rounds up score 9 to complexity-13 profile', () => {
|
|
71
|
+
const p = getEffortProfile(9);
|
|
72
|
+
expect(p.complexity).toBe(13);
|
|
73
|
+
});
|
|
74
|
+
it('rounds up score 10 to complexity-13 profile', () => {
|
|
75
|
+
const p = getEffortProfile(10);
|
|
76
|
+
expect(p.complexity).toBe(13);
|
|
77
|
+
});
|
|
78
|
+
it('rounds up score 12 to complexity-13 profile', () => {
|
|
79
|
+
const p = getEffortProfile(12);
|
|
80
|
+
expect(p.complexity).toBe(13);
|
|
81
|
+
});
|
|
82
|
+
it('clamps score 0 to complexity-1 profile', () => {
|
|
83
|
+
const p = getEffortProfile(0);
|
|
84
|
+
expect(p.complexity).toBe(1);
|
|
85
|
+
});
|
|
86
|
+
it('clamps negative score -5 to complexity-1 profile', () => {
|
|
87
|
+
const p = getEffortProfile(-5);
|
|
88
|
+
expect(p.complexity).toBe(1);
|
|
89
|
+
});
|
|
90
|
+
it('clamps large negative score -9999 to complexity-1 profile', () => {
|
|
91
|
+
const p = getEffortProfile(-9999);
|
|
92
|
+
expect(p.complexity).toBe(1);
|
|
93
|
+
});
|
|
94
|
+
it('clamps score 14 to complexity-13 profile', () => {
|
|
95
|
+
const p = getEffortProfile(14);
|
|
96
|
+
expect(p.complexity).toBe(13);
|
|
97
|
+
});
|
|
98
|
+
it('clamps score 100 to complexity-13 profile', () => {
|
|
99
|
+
const p = getEffortProfile(100);
|
|
100
|
+
expect(p.complexity).toBe(13);
|
|
101
|
+
});
|
|
102
|
+
it('clamps very large score 9999 to complexity-13 profile', () => {
|
|
103
|
+
const p = getEffortProfile(9999);
|
|
104
|
+
expect(p.complexity).toBe(13);
|
|
105
|
+
});
|
|
106
|
+
it('returns the same object reference from EFFORT_TABLE for exact matches', () => {
|
|
107
|
+
for (const entry of EFFORT_TABLE) {
|
|
108
|
+
expect(getEffortProfile(entry.complexity)).toBe(entry);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
it('EFFORT_TABLE has 6 entries', () => {
|
|
112
|
+
expect(EFFORT_TABLE).toHaveLength(6);
|
|
113
|
+
});
|
|
114
|
+
it('EFFORT_TABLE entries are ordered by ascending complexity', () => {
|
|
115
|
+
for (let i = 1; i < EFFORT_TABLE.length; i++) {
|
|
116
|
+
expect(EFFORT_TABLE[i].complexity).toBeGreaterThan(EFFORT_TABLE[i - 1].complexity);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=effort-scaling.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effort-scaling.test.js","sourceRoot":"","sources":["../../../src/cli/convoy/effort-scaling.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/engine.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAQ,QAAQ,EAAE,YAAY,EAAiB,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChG,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1F,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3E,OAAO,EAAwC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAElF,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAoB,WAAW,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,13 @@ import { readLessons, captureLessons, consolidateLessons } from './lessons.js';
|
|
|
20
20
|
import { updateExpertise, feedCircuitBreaker } from './expertise.js';
|
|
21
21
|
import { buildKnowledgeGraph } from './knowledge.js';
|
|
22
22
|
import { injectDiscoveredIssuesInstruction, checkDiscoveredIssues, consolidateIssues } from './issues.js';
|
|
23
|
+
import { validateOutput, buildContractInstruction, buildContractRetryPrompt } from './contracts.js';
|
|
24
|
+
import { runTwoStageReview } from './review-stages.js';
|
|
25
|
+
import { buildIsolationPreamble, resolveDependencyResults, detectPartitionViolations } from './isolation.js';
|
|
26
|
+
import { checkTDD, formatTDDFailure, DEFAULT_TDD_CONFIG } from './tdd-gate.js';
|
|
27
|
+
import { runSkillRefinementCheck } from './skill-refinement.js';
|
|
28
|
+
import { getArtifactDir, extractArtifactRefs } from './artifacts.js';
|
|
29
|
+
import { shouldCompact, parseCompactionSummary, saveCompaction, canCompact, getMaxCompactions, generateCompactionPrompt, buildContinuationPrompt } from './compaction.js';
|
|
23
30
|
const execFile = promisify(execFileCb);
|
|
24
31
|
export class CircuitBreakerManager {
|
|
25
32
|
states = new Map();
|
|
@@ -620,6 +627,7 @@ function pollInjectFile(convoyId, store, events, basePath) {
|
|
|
620
627
|
dispute_id: null,
|
|
621
628
|
drift_score: null,
|
|
622
629
|
drift_retried: 0,
|
|
630
|
+
compaction_count: 0,
|
|
623
631
|
outputs: null,
|
|
624
632
|
inputs: null,
|
|
625
633
|
discovered_issues: null,
|
|
@@ -995,6 +1003,33 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
995
1003
|
const specTask = (spec.tasks ?? []).find(t => t.id === taskRecord.id);
|
|
996
1004
|
const steps = specTask?.steps;
|
|
997
1005
|
const taskHooks = specTask?.hooks ?? [];
|
|
1006
|
+
// ── Context isolation preamble (Phase 41) ────────────────────────────
|
|
1007
|
+
try {
|
|
1008
|
+
const taskFiles = taskRecord.files ? JSON.parse(taskRecord.files) : [];
|
|
1009
|
+
const depIds = taskRecord.depends_on ? JSON.parse(taskRecord.depends_on) : [];
|
|
1010
|
+
const depResults = resolveDependencyResults(store, convoyId, depIds);
|
|
1011
|
+
const preamble = buildIsolationPreamble({ id: taskRecord.id, description: taskRecord.prompt.slice(0, 200), prompt: taskRecord.prompt, files: taskFiles, agent: taskRecord.agent }, depResults);
|
|
1012
|
+
task.prompt = preamble + '\n\n' + task.prompt;
|
|
1013
|
+
}
|
|
1014
|
+
catch { /* non-critical — isolation preamble is best-effort */ }
|
|
1015
|
+
// ── Artifact output instructions (Phase 43) ────────────────────────────
|
|
1016
|
+
try {
|
|
1017
|
+
const artifactDir = getArtifactDir(convoyId, taskRecord.id);
|
|
1018
|
+
const artifactInstructions = [
|
|
1019
|
+
'',
|
|
1020
|
+
'## Artifact Output (for large results)',
|
|
1021
|
+
'If your output includes large content (>100 lines of code, full reports, data dumps),',
|
|
1022
|
+
'write it to an artifact file instead of including it inline:',
|
|
1023
|
+
'',
|
|
1024
|
+
'1. Write the content to: ' + artifactDir + '{filename}',
|
|
1025
|
+
'2. In your response, reference it: `[ARTIFACT: {filename}] {1-line summary}`',
|
|
1026
|
+
'3. Keep your inline response focused on the summary and key decisions.',
|
|
1027
|
+
'',
|
|
1028
|
+
'Small outputs (< 100 lines) can remain inline.',
|
|
1029
|
+
].join('\n');
|
|
1030
|
+
task.prompt = task.prompt + '\n' + artifactInstructions;
|
|
1031
|
+
}
|
|
1032
|
+
catch { /* non-critical */ }
|
|
998
1033
|
// ── Intelligence: inject lessons (Phase 18.1) ─────────────────────────
|
|
999
1034
|
if (spec.defaults?.inject_lessons !== false) {
|
|
1000
1035
|
try {
|
|
@@ -1027,6 +1062,11 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1027
1062
|
if (spec.defaults?.track_discovered_issues) {
|
|
1028
1063
|
task.prompt = injectDiscoveredIssuesInstruction(task.prompt);
|
|
1029
1064
|
}
|
|
1065
|
+
// ── Output contract injection ─────────────────────────────────────────
|
|
1066
|
+
const contractInstruction = buildContractInstruction(taskRecord.agent);
|
|
1067
|
+
if (contractInstruction) {
|
|
1068
|
+
task.prompt = task.prompt + '\n\n' + contractInstruction;
|
|
1069
|
+
}
|
|
1030
1070
|
// ── pre_task hooks ────────────────────────────────────────────────────────
|
|
1031
1071
|
if (taskHooks.length > 0) {
|
|
1032
1072
|
const preResult = await runHooks(taskHooks, 'pre_task', {
|
|
@@ -1369,6 +1409,91 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1369
1409
|
return;
|
|
1370
1410
|
}
|
|
1371
1411
|
}
|
|
1412
|
+
// ── Partition violation check (Phase 41) ────────────────────────────
|
|
1413
|
+
if (changedFiles.length > 0) {
|
|
1414
|
+
try {
|
|
1415
|
+
const taskFiles = taskRecord.files ? JSON.parse(taskRecord.files) : [];
|
|
1416
|
+
if (taskFiles.length > 0) {
|
|
1417
|
+
const violation = detectPartitionViolations(taskRecord.id, taskFiles, changedFiles);
|
|
1418
|
+
if (violation) {
|
|
1419
|
+
events.emit('partition_violation', {
|
|
1420
|
+
task_id: taskRecord.id,
|
|
1421
|
+
allowed: violation.allowedFiles,
|
|
1422
|
+
actual: violation.actualFiles,
|
|
1423
|
+
violations: violation.violations,
|
|
1424
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
1425
|
+
process.stdout.write(` ${c.yellow('⚠')} ${c.bold(`[${taskRecord.id}]`)} partition violation: ${violation.violations.join(', ')}\n`);
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
catch { /* non-critical */ }
|
|
1430
|
+
}
|
|
1431
|
+
// ── TDD gate ──────────────────────────────────────────────────────────
|
|
1432
|
+
if (builtInGates.tdd_check && changedFiles.length > 0) {
|
|
1433
|
+
const tddConfig = typeof builtInGates.tdd_check === 'object'
|
|
1434
|
+
? { ...DEFAULT_TDD_CONFIG, ...builtInGates.tdd_check }
|
|
1435
|
+
: DEFAULT_TDD_CONFIG;
|
|
1436
|
+
const specTaskForTDD = (spec.tasks ?? []).find(t => t.id === taskRecord.id);
|
|
1437
|
+
const tddResult = checkTDD(changedFiles, changedFiles, tddConfig, specTaskForTDD?.agent ?? taskRecord.agent);
|
|
1438
|
+
if (tddResult.skipped) {
|
|
1439
|
+
events.emit('tdd_check_skipped', {
|
|
1440
|
+
task_id: taskRecord.id,
|
|
1441
|
+
reason: tddResult.skip_reason,
|
|
1442
|
+
agent: specTaskForTDD?.agent ?? taskRecord.agent,
|
|
1443
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
1444
|
+
}
|
|
1445
|
+
else if (tddResult.passed) {
|
|
1446
|
+
events.emit('tdd_check_passed', {
|
|
1447
|
+
task_id: taskRecord.id,
|
|
1448
|
+
new_source_files: tddResult.new_source_files.length,
|
|
1449
|
+
existing_test_files: tddResult.existing_test_files.length,
|
|
1450
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
1451
|
+
}
|
|
1452
|
+
else {
|
|
1453
|
+
const failureMsg = formatTDDFailure(tddResult);
|
|
1454
|
+
events.emit('tdd_check_failed', {
|
|
1455
|
+
task_id: taskRecord.id,
|
|
1456
|
+
missing_test_files: tddResult.missing_test_files,
|
|
1457
|
+
new_source_files: tddResult.new_source_files.length,
|
|
1458
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
1459
|
+
if (tddConfig.mode === 'block') {
|
|
1460
|
+
await removeWorktree();
|
|
1461
|
+
const freshRecord = store.getTask(taskRecord.id, convoyId);
|
|
1462
|
+
if (freshRecord.retries < freshRecord.max_retries && spec.on_failure !== 'stop') {
|
|
1463
|
+
store.updateTaskStatus(taskRecord.id, convoyId, 'pending', {
|
|
1464
|
+
retries: freshRecord.retries + 1,
|
|
1465
|
+
worker_id: null,
|
|
1466
|
+
worktree: null,
|
|
1467
|
+
started_at: null,
|
|
1468
|
+
finished_at: null,
|
|
1469
|
+
prompt: `TDD gate failed.\n${failureMsg}\n\nCreate the missing test files and try again.\n\n${taskRecord.prompt}`,
|
|
1470
|
+
});
|
|
1471
|
+
store.updateWorkerStatus(workerId, 'failed', { finished_at: finishedAt });
|
|
1472
|
+
process.stdout.write(` ${c.yellow('⟳')} ${c.bold(`[${taskRecord.id}]`)} TDD gate failed, retry ${freshRecord.retries + 1}/${freshRecord.max_retries}\n`);
|
|
1473
|
+
}
|
|
1474
|
+
else {
|
|
1475
|
+
store.withTransaction(() => {
|
|
1476
|
+
store.updateTaskStatus(taskRecord.id, convoyId, 'gate-failed', {
|
|
1477
|
+
finished_at: finishedAt,
|
|
1478
|
+
output: `Built-in gate (tdd_check) failed:\n${failureMsg}`,
|
|
1479
|
+
exit_code: 1,
|
|
1480
|
+
});
|
|
1481
|
+
store.updateWorkerStatus(workerId, 'failed', { finished_at: finishedAt });
|
|
1482
|
+
});
|
|
1483
|
+
completedCount++;
|
|
1484
|
+
process.stdout.write(` ${c.red('✗')} ${c.bold(`[${taskRecord.id}]`)} TDD gate failed ${elapsed} ${c.dim(`[${completedCount}/${totalTasks}]`)}\n`);
|
|
1485
|
+
events.emit('task_failed', { reason: 'gate-failed', gate: 'tdd_check', worker_id: workerId }, { convoy_id: convoyId, task_id: taskRecord.id, worker_id: workerId });
|
|
1486
|
+
handleExhaustion(freshRecord, 'tdd-check', failureMsg);
|
|
1487
|
+
}
|
|
1488
|
+
taskAdapterMap.delete(taskRecord.id);
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
else {
|
|
1492
|
+
// warn mode — log but continue
|
|
1493
|
+
process.stdout.write(` ${c.yellow('⚠')} ${c.bold(`[${taskRecord.id}]`)} TDD gate warning: ${tddResult.missing_test_files.length} source file(s) without tests\n`);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1372
1497
|
}
|
|
1373
1498
|
// ── Drift detection ──────────────────────────────────────────────────
|
|
1374
1499
|
const specTaskForDrift = (spec.tasks ?? []).find(t => t.id === taskRecord.id);
|
|
@@ -1478,7 +1603,20 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1478
1603
|
await reviewSemaphore.acquire();
|
|
1479
1604
|
let reviewResult;
|
|
1480
1605
|
try {
|
|
1481
|
-
if (reviewRunner) {
|
|
1606
|
+
if (reviewRunner && spec.defaults?.review_stages !== false) {
|
|
1607
|
+
// Two-stage review: spec compliance first, then code quality
|
|
1608
|
+
const twoStageResult = await runTwoStageReview(taskRecord, reviewRunner, reviewerModel);
|
|
1609
|
+
for (const stage of twoStageResult.stages) {
|
|
1610
|
+
events.emit('review_stage_completed', { stage: stage.stage, verdict: stage.verdict, tokens: stage.tokens_used, task_id: taskRecord.id, model: reviewerModel }, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
1611
|
+
}
|
|
1612
|
+
reviewResult = {
|
|
1613
|
+
verdict: twoStageResult.overall_verdict,
|
|
1614
|
+
feedback: twoStageResult.stages.flatMap(s => s.issues).join('\n'),
|
|
1615
|
+
tokens: twoStageResult.total_tokens,
|
|
1616
|
+
model: reviewerModel,
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
else if (reviewRunner) {
|
|
1482
1620
|
reviewResult = await reviewRunner(taskRecord, 'fast', reviewerModel);
|
|
1483
1621
|
}
|
|
1484
1622
|
else {
|
|
@@ -1541,11 +1679,33 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1541
1679
|
try {
|
|
1542
1680
|
const noopRunner = (_t, _l, m) => Promise.resolve({ verdict: 'pass', feedback: '', tokens: 0, model: m });
|
|
1543
1681
|
const runner = reviewRunner ?? noopRunner;
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1682
|
+
const twoStageEnabled = spec.defaults?.review_stages !== false;
|
|
1683
|
+
if (twoStageEnabled && reviewRunner) {
|
|
1684
|
+
// Each panel reviewer runs both stages; majority vote on overall_verdict
|
|
1685
|
+
const twoStageResults = await Promise.all([
|
|
1686
|
+
runTwoStageReview(taskRecord, runner, reviewerModel),
|
|
1687
|
+
runTwoStageReview(taskRecord, runner, reviewerModel),
|
|
1688
|
+
runTwoStageReview(taskRecord, runner, reviewerModel),
|
|
1689
|
+
]);
|
|
1690
|
+
for (const tsr of twoStageResults) {
|
|
1691
|
+
for (const stage of tsr.stages) {
|
|
1692
|
+
events.emit('review_stage_completed', { stage: stage.stage, verdict: stage.verdict, tokens: stage.tokens_used, task_id: taskRecord.id, model: reviewerModel }, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
panelResults = twoStageResults.map(tsr => ({
|
|
1696
|
+
verdict: tsr.overall_verdict,
|
|
1697
|
+
feedback: tsr.stages.flatMap(s => s.issues).join('\n'),
|
|
1698
|
+
tokens: tsr.total_tokens,
|
|
1699
|
+
model: reviewerModel,
|
|
1700
|
+
}));
|
|
1701
|
+
}
|
|
1702
|
+
else {
|
|
1703
|
+
panelResults = await Promise.all([
|
|
1704
|
+
runner(taskRecord, 'panel', reviewerModel),
|
|
1705
|
+
runner(taskRecord, 'panel', reviewerModel),
|
|
1706
|
+
runner(taskRecord, 'panel', reviewerModel),
|
|
1707
|
+
]);
|
|
1708
|
+
}
|
|
1549
1709
|
}
|
|
1550
1710
|
finally {
|
|
1551
1711
|
reviewSemaphore.release();
|
|
@@ -1770,6 +1930,7 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1770
1930
|
dispute_id: null,
|
|
1771
1931
|
drift_score: null,
|
|
1772
1932
|
drift_retried: 0,
|
|
1933
|
+
compaction_count: 0,
|
|
1773
1934
|
outputs: null,
|
|
1774
1935
|
inputs: null,
|
|
1775
1936
|
discovered_issues: null,
|
|
@@ -1815,6 +1976,64 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1815
1976
|
if (result.usage.total_tokens != null)
|
|
1816
1977
|
usageExtra.total_tokens = result.usage.total_tokens;
|
|
1817
1978
|
}
|
|
1979
|
+
// ── Context compaction check (Phase 44) ─────────────────────────────
|
|
1980
|
+
const compactionConfig = spec.defaults?.compaction;
|
|
1981
|
+
if (compactionConfig?.enabled && usageExtra.total_tokens != null && taskRecord.model) {
|
|
1982
|
+
if (shouldCompact(usageExtra.total_tokens, taskRecord.model, compactionConfig)) {
|
|
1983
|
+
if (canCompact(taskRecord.compaction_count)) {
|
|
1984
|
+
const newCount = taskRecord.compaction_count + 1;
|
|
1985
|
+
store.updateTaskCompaction(taskRecord.id, convoyId, newCount);
|
|
1986
|
+
const summaryFromOutput = parseCompactionSummary(result.output, taskRecord.id, convoyId);
|
|
1987
|
+
let summaryPath;
|
|
1988
|
+
if (summaryFromOutput) {
|
|
1989
|
+
try {
|
|
1990
|
+
summaryPath = saveCompaction(convoyId, taskRecord.id, summaryFromOutput, newCount);
|
|
1991
|
+
}
|
|
1992
|
+
catch { /* non-critical */ }
|
|
1993
|
+
}
|
|
1994
|
+
const compactionTaskFiles = taskRecord.files ? JSON.parse(taskRecord.files) : [];
|
|
1995
|
+
const compactionDepIds = taskRecord.depends_on ? JSON.parse(taskRecord.depends_on) : [];
|
|
1996
|
+
const compactionDepResults = resolveDependencyResults(store, convoyId, compactionDepIds);
|
|
1997
|
+
const compactionPreamble = buildIsolationPreamble({ id: taskRecord.id, description: taskRecord.prompt.slice(0, 200), prompt: taskRecord.prompt, files: compactionTaskFiles, agent: taskRecord.agent }, compactionDepResults);
|
|
1998
|
+
const continuationPrompt = summaryPath
|
|
1999
|
+
? buildContinuationPrompt(taskRecord.prompt, summaryPath, compactionPreamble)
|
|
2000
|
+
: compactionPreamble + '\n\n' + generateCompactionPrompt(taskRecord.id) + '\n\n' + taskRecord.prompt;
|
|
2001
|
+
store.updateTaskStatus(taskRecord.id, convoyId, 'pending', {
|
|
2002
|
+
worker_id: null,
|
|
2003
|
+
worktree: null,
|
|
2004
|
+
started_at: null,
|
|
2005
|
+
finished_at: null,
|
|
2006
|
+
prompt: continuationPrompt,
|
|
2007
|
+
});
|
|
2008
|
+
store.updateWorkerStatus(workerId, 'failed', { finished_at: finishedAt });
|
|
2009
|
+
events.emit('context_compacted', {
|
|
2010
|
+
task_id: taskRecord.id,
|
|
2011
|
+
compaction_count: newCount,
|
|
2012
|
+
summary_path: summaryPath ?? '',
|
|
2013
|
+
model: taskRecord.model,
|
|
2014
|
+
tokens_used: usageExtra.total_tokens,
|
|
2015
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
2016
|
+
taskAdapterMap.delete(taskRecord.id);
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
else {
|
|
2020
|
+
// Max compactions exceeded — fail the task
|
|
2021
|
+
const exhaustedAt = new Date().toISOString();
|
|
2022
|
+
store.updateTaskStatus(taskRecord.id, convoyId, 'failed', {
|
|
2023
|
+
finished_at: exhaustedAt,
|
|
2024
|
+
output: `Context exhausted: reached maximum ${getMaxCompactions()} compactions`,
|
|
2025
|
+
exit_code: 1,
|
|
2026
|
+
});
|
|
2027
|
+
store.updateWorkerStatus(workerId, 'failed', { finished_at: exhaustedAt });
|
|
2028
|
+
events.emit('task_failed', {
|
|
2029
|
+
reason: 'context_exhausted',
|
|
2030
|
+
worker_id: workerId,
|
|
2031
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
2032
|
+
taskAdapterMap.delete(taskRecord.id);
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
1818
2037
|
// ── Capture outputs as artifacts ────────────────────────────────────────
|
|
1819
2038
|
if (taskRecord.outputs) {
|
|
1820
2039
|
const outputs = JSON.parse(taskRecord.outputs);
|
|
@@ -1854,6 +2073,47 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1854
2073
|
}
|
|
1855
2074
|
}
|
|
1856
2075
|
}
|
|
2076
|
+
// ── Extract filesystem artifacts (Phase 43) ────────────────────────
|
|
2077
|
+
try {
|
|
2078
|
+
const fsArtifactRefs = extractArtifactRefs(taskRecord.id, convoyId, result.output);
|
|
2079
|
+
if (fsArtifactRefs.length > 0) {
|
|
2080
|
+
events.emit('artifacts_extracted', {
|
|
2081
|
+
task_id: taskRecord.id,
|
|
2082
|
+
count: fsArtifactRefs.length,
|
|
2083
|
+
artifacts: fsArtifactRefs.map(r => ({ filename: r.filename, summary: r.summary })),
|
|
2084
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
catch (err) {
|
|
2088
|
+
process.stderr.write(`[artifacts] Warning: extraction failed for task ${taskRecord.id}: ${err.message}\n`);
|
|
2089
|
+
}
|
|
2090
|
+
// ── Output contract validation ────────────────────────────────────────
|
|
2091
|
+
const contractResult = validateOutput(taskRecord.agent, result.output);
|
|
2092
|
+
if (!contractResult.valid) {
|
|
2093
|
+
const freshRecordForContract = store.getTask(taskRecord.id, convoyId);
|
|
2094
|
+
if (freshRecordForContract.retries < freshRecordForContract.max_retries) {
|
|
2095
|
+
const retryPrefix = buildContractRetryPrompt(contractResult) + '\n\n';
|
|
2096
|
+
store.updateTaskStatus(taskRecord.id, convoyId, 'pending', {
|
|
2097
|
+
retries: freshRecordForContract.retries + 1,
|
|
2098
|
+
worker_id: null,
|
|
2099
|
+
worktree: null,
|
|
2100
|
+
started_at: null,
|
|
2101
|
+
finished_at: null,
|
|
2102
|
+
prompt: retryPrefix + taskRecord.prompt,
|
|
2103
|
+
});
|
|
2104
|
+
store.updateWorkerStatus(workerId, 'failed', { finished_at: finishedAt });
|
|
2105
|
+
process.stdout.write(` ${c.yellow('⟳')} ${c.bold(`[${taskRecord.id}]`)} contract retry ${freshRecordForContract.retries + 1}/${freshRecordForContract.max_retries}\n`);
|
|
2106
|
+
taskAdapterMap.delete(taskRecord.id);
|
|
2107
|
+
return;
|
|
2108
|
+
}
|
|
2109
|
+
events.emit('contract_violation', {
|
|
2110
|
+
task_id: taskRecord.id,
|
|
2111
|
+
agent: taskRecord.agent,
|
|
2112
|
+
missing: contractResult.missing,
|
|
2113
|
+
warnings: contractResult.warnings,
|
|
2114
|
+
}, { convoy_id: convoyId, task_id: taskRecord.id });
|
|
2115
|
+
process.stdout.write(` ${c.yellow('⚠')} ${c.bold(`[${taskRecord.id}]`)} contract violation: missing ${contractResult.missing.join(', ')}\n`);
|
|
2116
|
+
}
|
|
1857
2117
|
// ── Intelligence: capture persistent agent identity (Phase 17.2) ─────
|
|
1858
2118
|
const specTaskForCapture = (spec.tasks ?? []).find(t => t.id === taskRecord.id);
|
|
1859
2119
|
if (specTaskForCapture?.persistent && result.output) {
|
|
@@ -1895,6 +2155,7 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1895
2155
|
output: result.output,
|
|
1896
2156
|
exit_code: result.exitCode,
|
|
1897
2157
|
...usageExtra,
|
|
2158
|
+
contract_result: JSON.stringify(contractResult),
|
|
1898
2159
|
});
|
|
1899
2160
|
store.updateWorkerStatus(workerId, 'done', { finished_at: finishedAt });
|
|
1900
2161
|
});
|
|
@@ -2175,6 +2436,18 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
2175
2436
|
}
|
|
2176
2437
|
catch { /* non-critical */ }
|
|
2177
2438
|
}
|
|
2439
|
+
// ── Intelligence: skill refinement check ───────────────────────────────
|
|
2440
|
+
try {
|
|
2441
|
+
const proposals = runSkillRefinementCheck(convoyId, basePath);
|
|
2442
|
+
for (const p of proposals) {
|
|
2443
|
+
events.emit('skill_refinement_proposed', {
|
|
2444
|
+
skill_name: p.skill,
|
|
2445
|
+
proposal_path: p.proposalPath,
|
|
2446
|
+
}, { convoy_id: convoyId });
|
|
2447
|
+
process.stdout.write(` ${c.yellow('◆')} Skill refinement proposed for "${p.skill}". Review at ${p.proposalPath}\n`);
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
catch { /* non-critical */ }
|
|
2178
2451
|
// ── Final status & summary ────────────────────────────────────────────────
|
|
2179
2452
|
const allTasksFinal = store.getTasksByConvoy(convoyId);
|
|
2180
2453
|
const summary = {
|
|
@@ -2590,6 +2863,7 @@ export function createConvoyEngine(options) {
|
|
|
2590
2863
|
dispute_id: null,
|
|
2591
2864
|
drift_score: null,
|
|
2592
2865
|
drift_retried: 0,
|
|
2866
|
+
compaction_count: 0,
|
|
2593
2867
|
outputs: null,
|
|
2594
2868
|
inputs: null,
|
|
2595
2869
|
discovered_issues: null,
|