@helmiq/crew 0.1.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/defaults/personas/architect.persona.yaml +72 -0
- package/defaults/personas/engineer.persona.yaml +137 -0
- package/defaults/personas/persona-spec.schema.yaml +149 -0
- package/defaults/personas/reviewer.persona.yaml +47 -0
- package/defaults/rubrics/adr.rubric.yaml +48 -0
- package/defaults/rubrics/code-review.rubric.yaml +39 -0
- package/defaults/rubrics/pull-request.rubric.yaml +40 -0
- package/dist/actions/actions.test.d.ts +2 -0
- package/dist/actions/actions.test.d.ts.map +1 -0
- package/dist/actions/actions.test.js +158 -0
- package/dist/actions/direct-dispatcher.d.ts +10 -0
- package/dist/actions/direct-dispatcher.d.ts.map +1 -0
- package/dist/actions/direct-dispatcher.js +27 -0
- package/dist/actions/dispatcher.d.ts +11 -0
- package/dist/actions/dispatcher.d.ts.map +1 -0
- package/dist/actions/dispatcher.js +1 -0
- package/dist/actions/index.d.ts +7 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +3 -0
- package/dist/actions/registry.d.ts +13 -0
- package/dist/actions/registry.d.ts.map +1 -0
- package/dist/actions/registry.js +40 -0
- package/dist/actions/resolver.d.ts +47 -0
- package/dist/actions/resolver.d.ts.map +1 -0
- package/dist/actions/resolver.js +43 -0
- package/dist/cli/cli.test.d.ts +2 -0
- package/dist/cli/cli.test.d.ts.map +1 -0
- package/dist/cli/cli.test.js +392 -0
- package/dist/cli/run.d.ts +45 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +236 -0
- package/dist/common/errors.d.ts +76 -0
- package/dist/common/errors.d.ts.map +1 -0
- package/dist/common/errors.js +74 -0
- package/dist/config/config.test.d.ts +2 -0
- package/dist/config/config.test.d.ts.map +1 -0
- package/dist/config/config.test.js +691 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/loader.d.ts +16 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +56 -0
- package/dist/config/model-resolver.d.ts +24 -0
- package/dist/config/model-resolver.d.ts.map +1 -0
- package/dist/config/model-resolver.js +39 -0
- package/dist/config/resolver.d.ts +22 -0
- package/dist/config/resolver.d.ts.map +1 -0
- package/dist/config/resolver.js +115 -0
- package/dist/config/schemas.d.ts +266 -0
- package/dist/config/schemas.d.ts.map +1 -0
- package/dist/config/schemas.js +115 -0
- package/dist/context/artifact-reader.d.ts +12 -0
- package/dist/context/artifact-reader.d.ts.map +1 -0
- package/dist/context/artifact-reader.js +92 -0
- package/dist/context/assembler.d.ts +22 -0
- package/dist/context/assembler.d.ts.map +1 -0
- package/dist/context/assembler.js +126 -0
- package/dist/context/code-reader.d.ts +14 -0
- package/dist/context/code-reader.d.ts.map +1 -0
- package/dist/context/code-reader.js +56 -0
- package/dist/context/context.test.d.ts +2 -0
- package/dist/context/context.test.d.ts.map +1 -0
- package/dist/context/context.test.js +260 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +5 -0
- package/dist/context/section-extractor.d.ts +9 -0
- package/dist/context/section-extractor.d.ts.map +1 -0
- package/dist/context/section-extractor.js +32 -0
- package/dist/context/token-budget.d.ts +11 -0
- package/dist/context/token-budget.d.ts.map +1 -0
- package/dist/context/token-budget.js +22 -0
- package/dist/control/control.test.d.ts +2 -0
- package/dist/control/control.test.d.ts.map +1 -0
- package/dist/control/control.test.js +137 -0
- package/dist/control/id-generator.d.ts +12 -0
- package/dist/control/id-generator.d.ts.map +1 -0
- package/dist/control/id-generator.js +20 -0
- package/dist/control/index.d.ts +5 -0
- package/dist/control/index.d.ts.map +1 -0
- package/dist/control/index.js +3 -0
- package/dist/control/lock-manager.d.ts +13 -0
- package/dist/control/lock-manager.d.ts.map +1 -0
- package/dist/control/lock-manager.js +72 -0
- package/dist/control/run-state.d.ts +16 -0
- package/dist/control/run-state.d.ts.map +1 -0
- package/dist/control/run-state.js +55 -0
- package/dist/engine/composite.d.ts +34 -0
- package/dist/engine/composite.d.ts.map +1 -0
- package/dist/engine/composite.js +192 -0
- package/dist/engine/composite.test.d.ts +2 -0
- package/dist/engine/composite.test.d.ts.map +1 -0
- package/dist/engine/composite.test.js +1947 -0
- package/dist/engine/engine.test.d.ts +2 -0
- package/dist/engine/engine.test.d.ts.map +1 -0
- package/dist/engine/engine.test.js +334 -0
- package/dist/engine/index.d.ts +10 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +5 -0
- package/dist/engine/llm-client.d.ts +27 -0
- package/dist/engine/llm-client.d.ts.map +1 -0
- package/dist/engine/llm-client.js +46 -0
- package/dist/engine/simple.d.ts +21 -0
- package/dist/engine/simple.d.ts.map +1 -0
- package/dist/engine/simple.js +59 -0
- package/dist/engine/tool-dispatch.d.ts +37 -0
- package/dist/engine/tool-dispatch.d.ts.map +1 -0
- package/dist/engine/tool-dispatch.js +146 -0
- package/dist/engine/tool-dispatch.test.d.ts +2 -0
- package/dist/engine/tool-dispatch.test.d.ts.map +1 -0
- package/dist/engine/tool-dispatch.test.js +348 -0
- package/dist/engine/tool-filter.d.ts +13 -0
- package/dist/engine/tool-filter.d.ts.map +1 -0
- package/dist/engine/tool-filter.js +25 -0
- package/dist/evaluation/evaluation.test.d.ts +2 -0
- package/dist/evaluation/evaluation.test.d.ts.map +1 -0
- package/dist/evaluation/evaluation.test.js +490 -0
- package/dist/evaluation/evaluator.d.ts +19 -0
- package/dist/evaluation/evaluator.d.ts.map +1 -0
- package/dist/evaluation/evaluator.js +78 -0
- package/dist/evaluation/index.d.ts +4 -0
- package/dist/evaluation/index.d.ts.map +1 -0
- package/dist/evaluation/index.js +2 -0
- package/dist/evaluation/scorer.d.ts +38 -0
- package/dist/evaluation/scorer.d.ts.map +1 -0
- package/dist/evaluation/scorer.js +94 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +1 -0
- package/dist/providers/provider-factory.d.ts +11 -0
- package/dist/providers/provider-factory.d.ts.map +1 -0
- package/dist/providers/provider-factory.js +30 -0
- package/dist/publication/frontmatter.d.ts +21 -0
- package/dist/publication/frontmatter.d.ts.map +1 -0
- package/dist/publication/frontmatter.js +15 -0
- package/dist/publication/git-ops.d.ts +18 -0
- package/dist/publication/git-ops.d.ts.map +1 -0
- package/dist/publication/git-ops.js +74 -0
- package/dist/publication/index.d.ts +9 -0
- package/dist/publication/index.d.ts.map +1 -0
- package/dist/publication/index.js +5 -0
- package/dist/publication/provenance-writer.d.ts +27 -0
- package/dist/publication/provenance-writer.d.ts.map +1 -0
- package/dist/publication/provenance-writer.js +21 -0
- package/dist/publication/publication.test.d.ts +2 -0
- package/dist/publication/publication.test.d.ts.map +1 -0
- package/dist/publication/publication.test.js +235 -0
- package/dist/publication/publisher.d.ts +32 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/publisher.js +113 -0
- package/dist/publication/secret-scanner.d.ts +6 -0
- package/dist/publication/secret-scanner.d.ts.map +1 -0
- package/dist/publication/secret-scanner.js +19 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/registry.d.ts +15 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +288 -0
- package/dist/tools/registry.test.d.ts +2 -0
- package/dist/tools/registry.test.d.ts.map +1 -0
- package/dist/tools/registry.test.js +131 -0
- package/dist/tools/tool-groups.d.ts +20 -0
- package/dist/tools/tool-groups.d.ts.map +1 -0
- package/dist/tools/tool-groups.js +48 -0
- package/dist/tools/tool-groups.test.d.ts +2 -0
- package/dist/tools/tool-groups.test.d.ts.map +1 -0
- package/dist/tools/tool-groups.test.js +127 -0
- package/dist/types/artifact-store.d.ts +33 -0
- package/dist/types/artifact-store.d.ts.map +1 -0
- package/dist/types/artifact-store.js +9 -0
- package/dist/types/evaluation-rubric.d.ts +18 -0
- package/dist/types/evaluation-rubric.d.ts.map +1 -0
- package/dist/types/evaluation-rubric.js +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/llm-provider.d.ts +47 -0
- package/dist/types/llm-provider.d.ts.map +1 -0
- package/dist/types/llm-provider.js +8 -0
- package/dist/types/persona-spec.d.ts +79 -0
- package/dist/types/persona-spec.d.ts.map +1 -0
- package/dist/types/persona-spec.js +1 -0
- package/dist/types/project-config.d.ts +28 -0
- package/dist/types/project-config.d.ts.map +1 -0
- package/dist/types/project-config.js +1 -0
- package/dist/types/provenance.d.ts +67 -0
- package/dist/types/provenance.d.ts.map +1 -0
- package/dist/types/provenance.js +1 -0
- package/dist/types/run-state.d.ts +11 -0
- package/dist/types/run-state.d.ts.map +1 -0
- package/dist/types/run-state.js +1 -0
- package/dist/types/tool-runtime.d.ts +43 -0
- package/dist/types/tool-runtime.d.ts.map +1 -0
- package/dist/types/tool-runtime.js +30 -0
- package/dist/workspace/detect.d.ts +11 -0
- package/dist/workspace/detect.d.ts.map +1 -0
- package/dist/workspace/detect.js +28 -0
- package/dist/workspace/detect.test.d.ts +2 -0
- package/dist/workspace/detect.test.d.ts.map +1 -0
- package/dist/workspace/detect.test.js +53 -0
- package/dist/workspace/index.d.ts +2 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RunStatus, RunRecord } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validate and apply a state transition on a RunRecord.
|
|
4
|
+
* Returns a new RunRecord with the updated status (and completed_at if terminal).
|
|
5
|
+
* Throws InvalidStateTransitionError if the transition is not allowed.
|
|
6
|
+
*/
|
|
7
|
+
export declare function transitionState(record: RunRecord, newStatus: RunStatus): RunRecord;
|
|
8
|
+
/**
|
|
9
|
+
* Persist the run state to `{runDir}/state.json`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function persistState(runDir: string, record: RunRecord): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Load run state from `{runDir}/state.json`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadState(runDir: string): Promise<RunRecord | null>;
|
|
16
|
+
//# sourceMappingURL=run-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../src/control/run-state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAe9D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,CAmBlF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAOzE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { writeFile, readFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { InvalidStateTransitionError } from '../common/errors.js';
|
|
4
|
+
const VALID_TRANSITIONS = {
|
|
5
|
+
queued: ['running'],
|
|
6
|
+
running: ['evaluating', 'failed'],
|
|
7
|
+
evaluating: ['publishing', 'failed'],
|
|
8
|
+
publishing: ['published', 'failed', 'awaiting_review'],
|
|
9
|
+
published: [],
|
|
10
|
+
failed: [],
|
|
11
|
+
awaiting_review: ['approved', 'rejected'],
|
|
12
|
+
approved: [],
|
|
13
|
+
rejected: [],
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Validate and apply a state transition on a RunRecord.
|
|
17
|
+
* Returns a new RunRecord with the updated status (and completed_at if terminal).
|
|
18
|
+
* Throws InvalidStateTransitionError if the transition is not allowed.
|
|
19
|
+
*/
|
|
20
|
+
export function transitionState(record, newStatus) {
|
|
21
|
+
const allowed = VALID_TRANSITIONS[record.status];
|
|
22
|
+
if (!allowed || !allowed.includes(newStatus)) {
|
|
23
|
+
throw new InvalidStateTransitionError(record.status, newStatus, {
|
|
24
|
+
runId: record.run_id,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const isTerminal = newStatus === 'published' ||
|
|
28
|
+
newStatus === 'failed' ||
|
|
29
|
+
newStatus === 'approved' ||
|
|
30
|
+
newStatus === 'rejected';
|
|
31
|
+
return {
|
|
32
|
+
...record,
|
|
33
|
+
status: newStatus,
|
|
34
|
+
completed_at: isTerminal ? new Date().toISOString() : record.completed_at,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Persist the run state to `{runDir}/state.json`.
|
|
39
|
+
*/
|
|
40
|
+
export async function persistState(runDir, record) {
|
|
41
|
+
await mkdir(runDir, { recursive: true });
|
|
42
|
+
await writeFile(join(runDir, 'state.json'), JSON.stringify(record, null, 2), 'utf-8');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Load run state from `{runDir}/state.json`.
|
|
46
|
+
*/
|
|
47
|
+
export async function loadState(runDir) {
|
|
48
|
+
try {
|
|
49
|
+
const raw = await readFile(join(runDir, 'state.json'), 'utf-8');
|
|
50
|
+
return JSON.parse(raw);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { PersonaSpec, CompositeTask, LlmProvider } from '../types/index.js';
|
|
2
|
+
import type { CrewToolSet, ToolExecutionContext, ToolExecutionRecord } from '../types/tool-runtime.js';
|
|
3
|
+
import type { ResolvedModel } from '../config/model-resolver.js';
|
|
4
|
+
import type { AssembledContext } from '../context/assembler.js';
|
|
5
|
+
import type { ResolvedSkills } from '../config/resolver.js';
|
|
6
|
+
import type { ToolDispatchResult } from './tool-dispatch.js';
|
|
7
|
+
import type { EngineResult } from './simple.js';
|
|
8
|
+
export interface CheckpointRecord {
|
|
9
|
+
step: number;
|
|
10
|
+
name: string;
|
|
11
|
+
path: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SubAgentRecord {
|
|
14
|
+
name: string;
|
|
15
|
+
result: ToolDispatchResult;
|
|
16
|
+
toolExecutions: ToolExecutionRecord[];
|
|
17
|
+
}
|
|
18
|
+
export interface CompositeResult extends EngineResult {
|
|
19
|
+
checkpoints: CheckpointRecord[];
|
|
20
|
+
subAgentResults: SubAgentRecord[];
|
|
21
|
+
toolExecutions: ToolExecutionRecord[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Execute a composite (sub-agent pipeline) persona task.
|
|
25
|
+
*
|
|
26
|
+
* Per ADR-0014, all sub-agents go through executeWithToolDispatch
|
|
27
|
+
* for uniform tool execution. Sub-agents with no tools get an empty
|
|
28
|
+
* CrewToolSet and the dispatch loop exits in one round.
|
|
29
|
+
*
|
|
30
|
+
* Per ADR-0016, working state remains Map<string, string>.
|
|
31
|
+
* ToolDispatchResult.text is stored as the working state value.
|
|
32
|
+
*/
|
|
33
|
+
export declare function executeCompositeTask(persona: PersonaSpec, task: CompositeTask, context: AssembledContext, model: ResolvedModel, provider: LlmProvider, availableTools: CrewToolSet, runDir: string, skills?: ResolvedSkills, toolContext?: ToolExecutionContext): Promise<CompositeResult>;
|
|
34
|
+
//# sourceMappingURL=composite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../../src/engine/composite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EAEb,WAAW,EAEZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,WAAW,EACX,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,kBAAkB,CAAC;IAC3B,cAAc,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,cAAc,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAwFD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,WAAW,EACrB,cAAc,EAAE,WAAW,EAC3B,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,cAAmB,EAC3B,WAAW,CAAC,EAAE,oBAAoB,GACjC,OAAO,CAAC,eAAe,CAAC,CA0I1B"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { writeFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { createNullToolContext } from '../types/tool-runtime.js';
|
|
4
|
+
import { callLlm } from './llm-client.js';
|
|
5
|
+
import { filterCrewTools } from './tool-dispatch.js';
|
|
6
|
+
import { executeWithToolDispatch } from './tool-dispatch.js';
|
|
7
|
+
function buildSubAgentPrompt(agent, workingState, initialContext, skills) {
|
|
8
|
+
const parts = [];
|
|
9
|
+
parts.push(`Sub-task: ${agent.produces}`);
|
|
10
|
+
const skillContent = skills[agent.skill];
|
|
11
|
+
if (skillContent) {
|
|
12
|
+
parts.push(`\nInstructions:\n${skillContent}`);
|
|
13
|
+
}
|
|
14
|
+
if (initialContext.blocks.length > 0) {
|
|
15
|
+
parts.push('\n--- Base Context ---');
|
|
16
|
+
for (const block of initialContext.blocks) {
|
|
17
|
+
const label = block.source.type + (block.source.path ? ` (${block.source.path})` : '');
|
|
18
|
+
parts.push(`\n[${label}]\n${block.content}`);
|
|
19
|
+
}
|
|
20
|
+
parts.push('--- End Base Context ---');
|
|
21
|
+
}
|
|
22
|
+
const relevantReads = agent.reads.filter((r) => workingState.has(r));
|
|
23
|
+
if (relevantReads.length > 0) {
|
|
24
|
+
parts.push('\n--- Working State ---');
|
|
25
|
+
for (const key of relevantReads) {
|
|
26
|
+
parts.push(`\n[${key}]\n${workingState.get(key)}`);
|
|
27
|
+
}
|
|
28
|
+
parts.push('--- End Working State ---');
|
|
29
|
+
}
|
|
30
|
+
return parts.join('\n');
|
|
31
|
+
}
|
|
32
|
+
async function checkpoint(runDir, step, name, content) {
|
|
33
|
+
const workDir = join(runDir, 'work');
|
|
34
|
+
await mkdir(workDir, { recursive: true });
|
|
35
|
+
const paddedStep = String(step + 1).padStart(2, '0');
|
|
36
|
+
const filePath = join(workDir, `${paddedStep}-${name}.md`);
|
|
37
|
+
await writeFile(filePath, content, 'utf-8');
|
|
38
|
+
return filePath;
|
|
39
|
+
}
|
|
40
|
+
async function evaluateGate(gateExpression, subAgentOutput, provider, model) {
|
|
41
|
+
const result = await callLlm({
|
|
42
|
+
provider,
|
|
43
|
+
model,
|
|
44
|
+
system: 'You are a gate evaluator. Assess whether the output meets the gate condition. Respond with exactly one JSON object: { "pass": true/false, "reason": "brief explanation" }. No other text.',
|
|
45
|
+
messages: [
|
|
46
|
+
{
|
|
47
|
+
role: 'user',
|
|
48
|
+
content: `Gate condition: ${gateExpression}\n\n--- Output to evaluate ---\n${subAgentOutput}\n--- End output ---`,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
maxRetries: 1,
|
|
52
|
+
});
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(result.text);
|
|
55
|
+
return {
|
|
56
|
+
pass: parsed.pass === true,
|
|
57
|
+
reason: parsed.reason ?? '',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return { pass: true, reason: 'Gate evaluation produced non-JSON output; defaulting to pass' };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Execute a composite (sub-agent pipeline) persona task.
|
|
66
|
+
*
|
|
67
|
+
* Per ADR-0014, all sub-agents go through executeWithToolDispatch
|
|
68
|
+
* for uniform tool execution. Sub-agents with no tools get an empty
|
|
69
|
+
* CrewToolSet and the dispatch loop exits in one round.
|
|
70
|
+
*
|
|
71
|
+
* Per ADR-0016, working state remains Map<string, string>.
|
|
72
|
+
* ToolDispatchResult.text is stored as the working state value.
|
|
73
|
+
*/
|
|
74
|
+
export async function executeCompositeTask(persona, task, context, model, provider, availableTools, runDir, skills = {}, toolContext) {
|
|
75
|
+
const workingState = new Map();
|
|
76
|
+
const checkpoints = [];
|
|
77
|
+
const subAgentResults = [];
|
|
78
|
+
const allToolExecutions = [];
|
|
79
|
+
const loopCounts = new Map();
|
|
80
|
+
let totalTokensIn = 0;
|
|
81
|
+
let totalTokensOut = 0;
|
|
82
|
+
const startMs = Date.now();
|
|
83
|
+
const systemPrompt = `You are a ${persona.persona.identity.role}.\n\nFollow your prompt instructions precisely. Produce the requested artifact.`;
|
|
84
|
+
const permittedSet = new Set(persona.persona.tools.permitted);
|
|
85
|
+
const deniedSet = new Set(persona.persona.tools.denied);
|
|
86
|
+
let i = 0;
|
|
87
|
+
while (i < task.sub_agents.length) {
|
|
88
|
+
const agent = task.sub_agents[i];
|
|
89
|
+
const filteredTools = filterCrewTools(availableTools, permittedSet, deniedSet, agent.tools);
|
|
90
|
+
const userPrompt = buildSubAgentPrompt(agent, workingState, context, skills);
|
|
91
|
+
let dispatchResult = null;
|
|
92
|
+
let succeeded = false;
|
|
93
|
+
const maxAttempts = agent.max_iterations ?? 1;
|
|
94
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
95
|
+
try {
|
|
96
|
+
dispatchResult = await executeWithToolDispatch({
|
|
97
|
+
callOptions: {
|
|
98
|
+
provider,
|
|
99
|
+
model,
|
|
100
|
+
system: systemPrompt,
|
|
101
|
+
messages: [{ role: 'user', content: userPrompt }],
|
|
102
|
+
},
|
|
103
|
+
tools: filteredTools,
|
|
104
|
+
context: toolContext ?? createNullToolContext(persona.persona.name, task.published_artifact),
|
|
105
|
+
maxRounds: 8,
|
|
106
|
+
});
|
|
107
|
+
succeeded = true;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
if (attempt === maxAttempts - 1) {
|
|
112
|
+
succeeded = false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!succeeded || !dispatchResult) {
|
|
117
|
+
return {
|
|
118
|
+
content: '',
|
|
119
|
+
toolCalls: [],
|
|
120
|
+
tokensIn: totalTokensIn,
|
|
121
|
+
tokensOut: totalTokensOut,
|
|
122
|
+
durationMs: Date.now() - startMs,
|
|
123
|
+
model: model.concreteModel,
|
|
124
|
+
checkpoints,
|
|
125
|
+
subAgentResults,
|
|
126
|
+
toolExecutions: allToolExecutions,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
totalTokensIn += dispatchResult.totalTokensIn;
|
|
130
|
+
totalTokensOut += dispatchResult.totalTokensOut;
|
|
131
|
+
allToolExecutions.push(...dispatchResult.toolExecutions);
|
|
132
|
+
subAgentResults.push({
|
|
133
|
+
name: agent.name,
|
|
134
|
+
result: dispatchResult,
|
|
135
|
+
toolExecutions: dispatchResult.toolExecutions,
|
|
136
|
+
});
|
|
137
|
+
const checkpointPath = await checkpoint(runDir, i, agent.name, dispatchResult.text);
|
|
138
|
+
checkpoints.push({ step: i, name: agent.name, path: checkpointPath });
|
|
139
|
+
workingState.set(agent.produces, dispatchResult.text);
|
|
140
|
+
if (agent.gate && agent.on_fail) {
|
|
141
|
+
const gateResult = await evaluateGate(agent.gate, dispatchResult.text, provider, model);
|
|
142
|
+
if (!gateResult.pass) {
|
|
143
|
+
const loopKey = agent.name;
|
|
144
|
+
const currentCount = (loopCounts.get(loopKey) ?? 0) + 1;
|
|
145
|
+
loopCounts.set(loopKey, currentCount);
|
|
146
|
+
if (currentCount >= (agent.max_loops ?? 1)) {
|
|
147
|
+
return {
|
|
148
|
+
content: '',
|
|
149
|
+
toolCalls: [],
|
|
150
|
+
tokensIn: totalTokensIn,
|
|
151
|
+
tokensOut: totalTokensOut,
|
|
152
|
+
durationMs: Date.now() - startMs,
|
|
153
|
+
model: model.concreteModel,
|
|
154
|
+
checkpoints,
|
|
155
|
+
subAgentResults,
|
|
156
|
+
toolExecutions: allToolExecutions,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const targetIndex = task.sub_agents.findIndex((a) => a.name === agent.on_fail);
|
|
160
|
+
if (targetIndex === -1) {
|
|
161
|
+
return {
|
|
162
|
+
content: '',
|
|
163
|
+
toolCalls: [],
|
|
164
|
+
tokensIn: totalTokensIn,
|
|
165
|
+
tokensOut: totalTokensOut,
|
|
166
|
+
durationMs: Date.now() - startMs,
|
|
167
|
+
model: model.concreteModel,
|
|
168
|
+
checkpoints,
|
|
169
|
+
subAgentResults,
|
|
170
|
+
toolExecutions: allToolExecutions,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
i = targetIndex;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
i++;
|
|
178
|
+
}
|
|
179
|
+
const finalResult = subAgentResults[subAgentResults.length - 1];
|
|
180
|
+
const finalToolCalls = [];
|
|
181
|
+
return {
|
|
182
|
+
content: finalResult?.result.text ?? '',
|
|
183
|
+
toolCalls: finalToolCalls,
|
|
184
|
+
tokensIn: totalTokensIn,
|
|
185
|
+
tokensOut: totalTokensOut,
|
|
186
|
+
durationMs: Date.now() - startMs,
|
|
187
|
+
model: model.concreteModel,
|
|
188
|
+
checkpoints,
|
|
189
|
+
subAgentResults,
|
|
190
|
+
toolExecutions: allToolExecutions,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite.test.d.ts","sourceRoot":"","sources":["../../src/engine/composite.test.ts"],"names":[],"mappings":""}
|