opencastle 0.31.7 → 0.32.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/README.md +4 -0
- 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/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/node_modules/.vite/deps/_metadata.json +6 -6
- package/src/orchestrator/prompts/assess-complexity.prompt.md +13 -0
- package/src/orchestrator/prompts/generate-convoy.prompt.md +19 -0
|
@@ -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,
|