agent-bober 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/.claude-plugin/plugin.json +9 -0
- package/LICENSE +21 -0
- package/README.md +495 -0
- package/agents/bober-evaluator.md +323 -0
- package/agents/bober-generator.md +245 -0
- package/agents/bober-planner.md +248 -0
- package/dist/cli/commands/eval.d.ts +6 -0
- package/dist/cli/commands/eval.d.ts.map +1 -0
- package/dist/cli/commands/eval.js +129 -0
- package/dist/cli/commands/eval.js.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +547 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +5 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +87 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/run.d.ts +5 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +120 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/sprint.d.ts +6 -0
- package/dist/cli/commands/sprint.d.ts.map +1 -0
- package/dist/cli/commands/sprint.js +206 -0
- package/dist/cli/commands/sprint.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +124 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/defaults.d.ts +15 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +226 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +18 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +189 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +904 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +181 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/contracts/eval-result.d.ts +205 -0
- package/dist/contracts/eval-result.d.ts.map +1 -0
- package/dist/contracts/eval-result.js +87 -0
- package/dist/contracts/eval-result.js.map +1 -0
- package/dist/contracts/index.d.ts +4 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +16 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/spec.d.ts +101 -0
- package/dist/contracts/spec.d.ts.map +1 -0
- package/dist/contracts/spec.js +51 -0
- package/dist/contracts/spec.js.map +1 -0
- package/dist/contracts/sprint-contract.d.ts +141 -0
- package/dist/contracts/sprint-contract.d.ts.map +1 -0
- package/dist/contracts/sprint-contract.js +80 -0
- package/dist/contracts/sprint-contract.js.map +1 -0
- package/dist/evaluators/builtin/api-check.d.ts +13 -0
- package/dist/evaluators/builtin/api-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/api-check.js +152 -0
- package/dist/evaluators/builtin/api-check.js.map +1 -0
- package/dist/evaluators/builtin/build-check.d.ts +17 -0
- package/dist/evaluators/builtin/build-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/build-check.js +155 -0
- package/dist/evaluators/builtin/build-check.js.map +1 -0
- package/dist/evaluators/builtin/command-runner.d.ts +26 -0
- package/dist/evaluators/builtin/command-runner.d.ts.map +1 -0
- package/dist/evaluators/builtin/command-runner.js +114 -0
- package/dist/evaluators/builtin/command-runner.js.map +1 -0
- package/dist/evaluators/builtin/lint.d.ts +17 -0
- package/dist/evaluators/builtin/lint.d.ts.map +1 -0
- package/dist/evaluators/builtin/lint.js +264 -0
- package/dist/evaluators/builtin/lint.js.map +1 -0
- package/dist/evaluators/builtin/playwright.d.ts +16 -0
- package/dist/evaluators/builtin/playwright.d.ts.map +1 -0
- package/dist/evaluators/builtin/playwright.js +238 -0
- package/dist/evaluators/builtin/playwright.js.map +1 -0
- package/dist/evaluators/builtin/typescript-check.d.ts +12 -0
- package/dist/evaluators/builtin/typescript-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/typescript-check.js +155 -0
- package/dist/evaluators/builtin/typescript-check.js.map +1 -0
- package/dist/evaluators/builtin/unit-test.d.ts +18 -0
- package/dist/evaluators/builtin/unit-test.d.ts.map +1 -0
- package/dist/evaluators/builtin/unit-test.js +279 -0
- package/dist/evaluators/builtin/unit-test.js.map +1 -0
- package/dist/evaluators/index.d.ts +11 -0
- package/dist/evaluators/index.d.ts.map +1 -0
- package/dist/evaluators/index.js +13 -0
- package/dist/evaluators/index.js.map +1 -0
- package/dist/evaluators/plugin-interface.d.ts +50 -0
- package/dist/evaluators/plugin-interface.d.ts.map +1 -0
- package/dist/evaluators/plugin-interface.js +2 -0
- package/dist/evaluators/plugin-interface.js.map +1 -0
- package/dist/evaluators/plugin-loader.d.ts +18 -0
- package/dist/evaluators/plugin-loader.d.ts.map +1 -0
- package/dist/evaluators/plugin-loader.js +107 -0
- package/dist/evaluators/plugin-loader.js.map +1 -0
- package/dist/evaluators/registry.d.ts +78 -0
- package/dist/evaluators/registry.d.ts.map +1 -0
- package/dist/evaluators/registry.js +238 -0
- package/dist/evaluators/registry.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/context-handoff.d.ts +543 -0
- package/dist/orchestrator/context-handoff.d.ts.map +1 -0
- package/dist/orchestrator/context-handoff.js +133 -0
- package/dist/orchestrator/context-handoff.js.map +1 -0
- package/dist/orchestrator/evaluator-agent.d.ts +15 -0
- package/dist/orchestrator/evaluator-agent.d.ts.map +1 -0
- package/dist/orchestrator/evaluator-agent.js +233 -0
- package/dist/orchestrator/evaluator-agent.js.map +1 -0
- package/dist/orchestrator/generator-agent.d.ts +16 -0
- package/dist/orchestrator/generator-agent.d.ts.map +1 -0
- package/dist/orchestrator/generator-agent.js +147 -0
- package/dist/orchestrator/generator-agent.js.map +1 -0
- package/dist/orchestrator/pipeline.d.ts +24 -0
- package/dist/orchestrator/pipeline.d.ts.map +1 -0
- package/dist/orchestrator/pipeline.js +290 -0
- package/dist/orchestrator/pipeline.js.map +1 -0
- package/dist/orchestrator/planner-agent.d.ts +10 -0
- package/dist/orchestrator/planner-agent.d.ts.map +1 -0
- package/dist/orchestrator/planner-agent.js +187 -0
- package/dist/orchestrator/planner-agent.js.map +1 -0
- package/dist/state/helpers.d.ts +5 -0
- package/dist/state/helpers.d.ts.map +1 -0
- package/dist/state/helpers.js +8 -0
- package/dist/state/helpers.js.map +1 -0
- package/dist/state/history.d.ts +39 -0
- package/dist/state/history.d.ts.map +1 -0
- package/dist/state/history.js +162 -0
- package/dist/state/history.js.map +1 -0
- package/dist/state/index.d.ts +8 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +22 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/plan-state.d.ts +21 -0
- package/dist/state/plan-state.d.ts.map +1 -0
- package/dist/state/plan-state.js +108 -0
- package/dist/state/plan-state.js.map +1 -0
- package/dist/state/sprint-state.d.ts +20 -0
- package/dist/state/sprint-state.d.ts.map +1 -0
- package/dist/state/sprint-state.js +98 -0
- package/dist/state/sprint-state.js.map +1 -0
- package/dist/utils/fs.d.ts +31 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +67 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/git.d.ts +35 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +84 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +73 -0
- package/dist/utils/logger.js.map +1 -0
- package/hooks/hooks.json +10 -0
- package/package.json +67 -0
- package/scripts/detect-stack.sh +287 -0
- package/scripts/init-project.sh +206 -0
- package/scripts/run-eval.sh +175 -0
- package/skills/bober.anchor/SKILL.md +365 -0
- package/skills/bober.anchor/references/anchor-guide.md +567 -0
- package/skills/bober.brownfield/SKILL.md +422 -0
- package/skills/bober.brownfield/references/codebase-analysis.md +304 -0
- package/skills/bober.eval/SKILL.md +235 -0
- package/skills/bober.eval/references/eval-strategies.md +407 -0
- package/skills/bober.eval/references/feedback-format.md +182 -0
- package/skills/bober.plan/SKILL.md +244 -0
- package/skills/bober.plan/references/clarification-guide.md +124 -0
- package/skills/bober.plan/references/spec-schema.md +253 -0
- package/skills/bober.react/SKILL.md +330 -0
- package/skills/bober.react/references/react-scaffold.md +344 -0
- package/skills/bober.run/SKILL.md +303 -0
- package/skills/bober.solidity/SKILL.md +416 -0
- package/skills/bober.solidity/references/solidity-guide.md +487 -0
- package/skills/bober.sprint/SKILL.md +280 -0
- package/skills/bober.sprint/references/contract-schema.md +251 -0
- package/templates/base/CLAUDE.md +20 -0
- package/templates/base/bober.config.json +35 -0
- package/templates/brownfield/CLAUDE.md +34 -0
- package/templates/brownfield/bober.config.json +37 -0
- package/templates/presets/anchor/CLAUDE.md +163 -0
- package/templates/presets/anchor/bober.config.json +9 -0
- package/templates/presets/api-node/CLAUDE.md +153 -0
- package/templates/presets/api-node/bober.config.json +10 -0
- package/templates/presets/nextjs/CLAUDE.md +82 -0
- package/templates/presets/nextjs/bober.config.json +14 -0
- package/templates/presets/python-api/CLAUDE.md +202 -0
- package/templates/presets/python-api/bober.config.json +9 -0
- package/templates/presets/react-vite/CLAUDE.md +71 -0
- package/templates/presets/react-vite/bober.config.json +53 -0
- package/templates/presets/react-vite/scaffold/package.json +45 -0
- package/templates/presets/react-vite/scaffold/server/index.ts +38 -0
- package/templates/presets/react-vite/scaffold/server/tsconfig.json +24 -0
- package/templates/presets/react-vite/scaffold/src/App.tsx +37 -0
- package/templates/presets/react-vite/scaffold/src/index.html +12 -0
- package/templates/presets/react-vite/scaffold/src/main.tsx +12 -0
- package/templates/presets/react-vite/scaffold/tsconfig.json +27 -0
- package/templates/presets/react-vite/scaffold/vite.config.ts +34 -0
- package/templates/presets/solidity/CLAUDE.md +106 -0
- package/templates/presets/solidity/bober.config.json +9 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BoberConfig } from "../config/schema.js";
|
|
2
|
+
import type { ContextHandoff } from "./context-handoff.js";
|
|
3
|
+
import type { EvaluationRunResult } from "../evaluators/registry.js";
|
|
4
|
+
export type { EvaluationRunResult } from "../evaluators/registry.js";
|
|
5
|
+
/**
|
|
6
|
+
* Run the evaluator agent, combining programmatic evaluation (plugins)
|
|
7
|
+
* with agent-based qualitative evaluation.
|
|
8
|
+
*
|
|
9
|
+
* @param handoff Context handoff for the current sprint.
|
|
10
|
+
* @param projectRoot Absolute path to the project.
|
|
11
|
+
* @param config The resolved bober configuration.
|
|
12
|
+
* @returns A combined EvaluationRunResult.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runEvaluatorAgent(handoff: ContextHandoff, projectRoot: string, config: BoberConfig): Promise<EvaluationRunResult>;
|
|
15
|
+
//# sourceMappingURL=evaluator-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator-agent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/evaluator-agent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAO3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAIrE,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAwDrE;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,mBAAmB,CAAC,CA0E9B"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
import { serializeHandoff } from "./context-handoff.js";
|
|
3
|
+
import { createDefaultRegistry, runEvaluation, } from "../evaluators/registry.js";
|
|
4
|
+
import { getChangedFiles } from "../utils/git.js";
|
|
5
|
+
import { logger } from "../utils/logger.js";
|
|
6
|
+
// ── Model mapping ──────────────────────────────────────────────────
|
|
7
|
+
function resolveModel(choice) {
|
|
8
|
+
switch (choice) {
|
|
9
|
+
case "opus":
|
|
10
|
+
return "claude-sonnet-4-20250514";
|
|
11
|
+
case "sonnet":
|
|
12
|
+
return "claude-sonnet-4-20250514";
|
|
13
|
+
case "haiku":
|
|
14
|
+
return "claude-haiku-4-20250414";
|
|
15
|
+
default:
|
|
16
|
+
return "claude-sonnet-4-20250514";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// ── Agent Evaluation System Prompt ─────────────────────────────────
|
|
20
|
+
const EVALUATOR_SYSTEM_PROMPT = `You are the Bober Evaluator agent. Your job is to qualitatively assess whether a sprint's implementation meets its contract criteria.
|
|
21
|
+
|
|
22
|
+
You will receive:
|
|
23
|
+
- The sprint contract with success criteria
|
|
24
|
+
- The context handoff with implementation notes
|
|
25
|
+
- Results from automated checks (typecheck, lint, tests, etc.)
|
|
26
|
+
|
|
27
|
+
For each success criterion that cannot be automatically verified, assess whether it has been met based on the implementation description and changed files.
|
|
28
|
+
|
|
29
|
+
Output format — respond with a JSON object:
|
|
30
|
+
{
|
|
31
|
+
"evaluator": "Agent Evaluation",
|
|
32
|
+
"passed": true/false,
|
|
33
|
+
"score": 0-100,
|
|
34
|
+
"details": [
|
|
35
|
+
{
|
|
36
|
+
"criterion": "criterion id or description",
|
|
37
|
+
"passed": true/false,
|
|
38
|
+
"message": "explanation",
|
|
39
|
+
"severity": "error" | "warning" | "info"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"summary": "Overall assessment",
|
|
43
|
+
"feedback": "Actionable feedback for the generator if anything needs fixing",
|
|
44
|
+
"timestamp": "<ISO datetime>"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Guidelines:
|
|
48
|
+
- Be thorough but fair. If the implementation reasonably meets a criterion, mark it as passed.
|
|
49
|
+
- If automated checks already cover a criterion, you can defer to their results.
|
|
50
|
+
- Focus on criteria that require human-like judgment: code quality, architectural decisions, completeness.
|
|
51
|
+
- Provide specific, actionable feedback when something fails.
|
|
52
|
+
|
|
53
|
+
Output ONLY the JSON object. No markdown fences, no explanation.`;
|
|
54
|
+
// ── Main ───────────────────────────────────────────────────────────
|
|
55
|
+
/**
|
|
56
|
+
* Run the evaluator agent, combining programmatic evaluation (plugins)
|
|
57
|
+
* with agent-based qualitative evaluation.
|
|
58
|
+
*
|
|
59
|
+
* @param handoff Context handoff for the current sprint.
|
|
60
|
+
* @param projectRoot Absolute path to the project.
|
|
61
|
+
* @param config The resolved bober configuration.
|
|
62
|
+
* @returns A combined EvaluationRunResult.
|
|
63
|
+
*/
|
|
64
|
+
export async function runEvaluatorAgent(handoff, projectRoot, config) {
|
|
65
|
+
const contract = handoff.currentContract;
|
|
66
|
+
if (!contract) {
|
|
67
|
+
throw new Error("No current contract in handoff for evaluation.");
|
|
68
|
+
}
|
|
69
|
+
const sprintId = contract.id;
|
|
70
|
+
logger.sprint(sprintId, `Evaluating: ${contract.feature}`);
|
|
71
|
+
// 1. Programmatic evaluation — run registered evaluator plugins
|
|
72
|
+
logger.info("Running programmatic evaluations...");
|
|
73
|
+
const registry = await createDefaultRegistry(config);
|
|
74
|
+
let changedFiles;
|
|
75
|
+
try {
|
|
76
|
+
changedFiles = handoff.changedFiles.length > 0
|
|
77
|
+
? handoff.changedFiles
|
|
78
|
+
: await getChangedFiles(projectRoot);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
changedFiles = handoff.changedFiles;
|
|
82
|
+
}
|
|
83
|
+
const programmaticEval = await runEvaluation(registry, projectRoot, config, contract, changedFiles);
|
|
84
|
+
for (const result of programmaticEval.results) {
|
|
85
|
+
const icon = result.passed ? "PASS" : "FAIL";
|
|
86
|
+
logger.debug(` [${icon}] ${result.evaluator}: ${result.summary}`);
|
|
87
|
+
}
|
|
88
|
+
// 2. Agent evaluation — qualitative assessment via Claude
|
|
89
|
+
logger.info("Running agent evaluation...");
|
|
90
|
+
const agentResult = await runAgentEvaluation(handoff, programmaticEval.results, config);
|
|
91
|
+
// 3. Combine results: merge the agent result into the programmatic evaluation
|
|
92
|
+
const allResults = [...programmaticEval.results, agentResult];
|
|
93
|
+
const scoredResults = allResults.filter((r) => r.score !== undefined);
|
|
94
|
+
const avgScore = scoredResults.length > 0
|
|
95
|
+
? Math.round(scoredResults.reduce((sum, r) => sum + (r.score ?? 0), 0) /
|
|
96
|
+
scoredResults.length)
|
|
97
|
+
: 0;
|
|
98
|
+
const passedCount = allResults.filter((r) => r.passed).length;
|
|
99
|
+
const summaryParts = [
|
|
100
|
+
`Evaluation complete: ${passedCount}/${allResults.length} evaluators passed`,
|
|
101
|
+
`Score: ${avgScore}/100`,
|
|
102
|
+
];
|
|
103
|
+
const evaluation = {
|
|
104
|
+
passed: programmaticEval.passed && agentResult.passed,
|
|
105
|
+
score: avgScore,
|
|
106
|
+
results: allResults,
|
|
107
|
+
summary: summaryParts.join(". "),
|
|
108
|
+
timestamp: new Date().toISOString(),
|
|
109
|
+
};
|
|
110
|
+
const statusLabel = evaluation.passed ? "PASSED" : "FAILED";
|
|
111
|
+
logger.sprint(sprintId, `Evaluation ${statusLabel}`);
|
|
112
|
+
return evaluation;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Run the agent-based qualitative evaluation.
|
|
116
|
+
*/
|
|
117
|
+
async function runAgentEvaluation(handoff, programmaticResults, config) {
|
|
118
|
+
const model = resolveModel(config.evaluator.model);
|
|
119
|
+
const client = new Anthropic();
|
|
120
|
+
const timestamp = new Date().toISOString();
|
|
121
|
+
const handoffJson = serializeHandoff(handoff);
|
|
122
|
+
const programmaticSummary = programmaticResults
|
|
123
|
+
.map((r) => `[${r.passed ? "PASS" : "FAIL"}] ${r.evaluator}: ${r.summary}`)
|
|
124
|
+
.join("\n");
|
|
125
|
+
const userMessage = `# Context Handoff
|
|
126
|
+
${handoffJson}
|
|
127
|
+
|
|
128
|
+
# Automated Check Results
|
|
129
|
+
${programmaticSummary}
|
|
130
|
+
|
|
131
|
+
Evaluate whether the sprint contract criteria have been met. Focus on criteria that automated checks cannot verify.
|
|
132
|
+
|
|
133
|
+
Output ONLY a JSON object matching the EvalResult schema. No markdown fences.`;
|
|
134
|
+
try {
|
|
135
|
+
const response = await client.messages.create({
|
|
136
|
+
model,
|
|
137
|
+
max_tokens: 4096,
|
|
138
|
+
system: EVALUATOR_SYSTEM_PROMPT,
|
|
139
|
+
messages: [
|
|
140
|
+
{
|
|
141
|
+
role: "user",
|
|
142
|
+
content: userMessage,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
});
|
|
146
|
+
let responseText = "";
|
|
147
|
+
for (const block of response.content) {
|
|
148
|
+
if (block.type === "text") {
|
|
149
|
+
responseText += block.text;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return parseEvalResult(responseText, timestamp);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
logger.warn(`Agent evaluation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
156
|
+
return {
|
|
157
|
+
evaluator: "Agent Evaluation",
|
|
158
|
+
passed: true, // Don't block on agent eval failure
|
|
159
|
+
score: undefined,
|
|
160
|
+
details: [],
|
|
161
|
+
summary: "Agent evaluation could not be performed.",
|
|
162
|
+
feedback: `Agent evaluation error: ${err instanceof Error ? err.message : String(err)}`,
|
|
163
|
+
timestamp,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Parse the evaluator agent's response into an EvalResult.
|
|
169
|
+
*/
|
|
170
|
+
function parseEvalResult(text, fallbackTimestamp) {
|
|
171
|
+
let parsed;
|
|
172
|
+
try {
|
|
173
|
+
parsed = JSON.parse(text.trim());
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
const fenceMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/.exec(text);
|
|
177
|
+
if (fenceMatch) {
|
|
178
|
+
try {
|
|
179
|
+
parsed = JSON.parse(fenceMatch[1].trim());
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// Fall through
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!parsed) {
|
|
186
|
+
const braceStart = text.indexOf("{");
|
|
187
|
+
const braceEnd = text.lastIndexOf("}");
|
|
188
|
+
if (braceStart !== -1 && braceEnd > braceStart) {
|
|
189
|
+
try {
|
|
190
|
+
parsed = JSON.parse(text.slice(braceStart, braceEnd + 1));
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// Fall through
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (parsed && typeof parsed === "object" && parsed !== null) {
|
|
199
|
+
const obj = parsed;
|
|
200
|
+
const details = Array.isArray(obj.details)
|
|
201
|
+
? obj.details
|
|
202
|
+
.filter((d) => typeof d === "object" && d !== null)
|
|
203
|
+
.map((d) => ({
|
|
204
|
+
criterion: String(d.criterion ?? "unknown"),
|
|
205
|
+
passed: Boolean(d.passed),
|
|
206
|
+
message: String(d.message ?? ""),
|
|
207
|
+
severity: (["error", "warning", "info"].includes(String(d.severity))
|
|
208
|
+
? String(d.severity)
|
|
209
|
+
: "info"),
|
|
210
|
+
...(typeof d.file === "string" ? { file: d.file } : {}),
|
|
211
|
+
...(typeof d.line === "number" ? { line: d.line } : {}),
|
|
212
|
+
}))
|
|
213
|
+
: [];
|
|
214
|
+
return {
|
|
215
|
+
evaluator: String(obj.evaluator ?? "Agent Evaluation"),
|
|
216
|
+
passed: Boolean(obj.passed),
|
|
217
|
+
score: typeof obj.score === "number" ? obj.score : undefined,
|
|
218
|
+
details,
|
|
219
|
+
summary: String(obj.summary ?? "No summary provided."),
|
|
220
|
+
feedback: String(obj.feedback ?? "No feedback provided."),
|
|
221
|
+
timestamp: typeof obj.timestamp === "string" ? obj.timestamp : fallbackTimestamp,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
evaluator: "Agent Evaluation",
|
|
226
|
+
passed: false,
|
|
227
|
+
details: [],
|
|
228
|
+
summary: "Failed to parse agent evaluation response.",
|
|
229
|
+
feedback: `Raw response:\n${text.slice(0, 500)}`,
|
|
230
|
+
timestamp: fallbackTimestamp,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=evaluator-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator-agent.js","sourceRoot":"","sources":["../../src/orchestrator/evaluator-agent.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAI1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EACL,qBAAqB,EACrB,aAAa,GACd,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAI5C,sEAAsE;AAEtE,SAAS,YAAY,CAAC,MAAc;IAClC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,0BAA0B,CAAC;QACpC,KAAK,QAAQ;YACX,OAAO,0BAA0B,CAAC;QACpC,KAAK,OAAO;YACV,OAAO,yBAAyB,CAAC;QACnC;YACE,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC;AAED,sEAAsE;AAEtE,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iEAiCiC,CAAC;AAElE,sEAAsE;AAEtE;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAuB,EACvB,WAAmB,EACnB,MAAmB;IAEnB,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC;IACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC;IAE7B,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,eAAe,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAE3D,gEAAgE;IAChE,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAErD,IAAI,YAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;YAC5C,CAAC,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IACtC,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,aAAa,CAC1C,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,YAAY,CACb,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,0DAA0D;IAC1D,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAC1C,OAAO,EACP,gBAAgB,CAAC,OAAO,EACxB,MAAM,CACP,CAAC;IAEF,8EAA8E;IAC9E,MAAM,UAAU,GAAG,CAAC,GAAG,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAE9D,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IACtE,MAAM,QAAQ,GACZ,aAAa,CAAC,MAAM,GAAG,CAAC;QACtB,CAAC,CAAC,IAAI,CAAC,KAAK,CACR,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;YACvD,aAAa,CAAC,MAAM,CACvB;QACH,CAAC,CAAC,CAAC,CAAC;IAER,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAC9D,MAAM,YAAY,GAAG;QACnB,wBAAwB,WAAW,IAAI,UAAU,CAAC,MAAM,oBAAoB;QAC5E,UAAU,QAAQ,MAAM;KACzB,CAAC;IAEF,MAAM,UAAU,GAAwB;QACtC,MAAM,EAAE,gBAAgB,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM;QACrD,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,UAAU;QACnB,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC5D,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,WAAW,EAAE,CAAC,CAAC;IAErD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,kBAAkB,CAC/B,OAAuB,EACvB,mBAAiC,EACjC,MAAmB;IAEnB,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE3C,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE9C,MAAM,mBAAmB,GAAG,mBAAmB;SAC5C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;SAC1E,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,WAAW,GAAG;EACpB,WAAW;;;EAGX,mBAAmB;;;;8EAIyD,CAAC;IAE7E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC5C,KAAK;YACL,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,uBAAuB;YAC/B,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,WAAW;iBACrB;aACF;SACF,CAAC,CAAC;QAEH,IAAI,YAAY,GAAG,EAAE,CAAC;QACtB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,OAAO,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CACT,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC/E,CAAC;QAEF,OAAO;YACL,SAAS,EAAE,kBAAkB;YAC7B,MAAM,EAAE,IAAI,EAAE,oCAAoC;YAClD,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,0CAA0C;YACnD,QAAQ,EAAE,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;YACvF,SAAS;SACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY,EAAE,iBAAyB;IAC9D,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,UAAU,GAAG,uCAAuC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;gBAC/C,IAAI,CAAC;oBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC5D,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAC5D,MAAM,GAAG,GAAG,MAAiC,CAAC;QAE9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACxC,CAAC,CAAE,GAAG,CAAC,OAAqB;iBACvB,MAAM,CACL,CAAC,CAAC,EAAgC,EAAE,CAClC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CACtC;iBACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACX,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC;gBAC3C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;gBACzB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;gBAChC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,QAAQ,CAC9C,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CACnB;oBACC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;oBACpB,CAAC,CAAC,MAAM,CAAiC;gBAC3C,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxD,CAAC,CAAC;YACP,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,IAAI,kBAAkB,CAAC;YACtD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YAC5D,OAAO;YACP,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,sBAAsB,CAAC;YACtD,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,IAAI,uBAAuB,CAAC;YACzD,SAAS,EACP,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB;SACxE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS,EAAE,kBAAkB;QAC7B,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,4CAA4C;QACrD,QAAQ,EAAE,kBAAkB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;QAChD,SAAS,EAAE,iBAAiB;KAC7B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BoberConfig } from "../config/schema.js";
|
|
2
|
+
import type { ContextHandoff } from "./context-handoff.js";
|
|
3
|
+
export interface GeneratorResult {
|
|
4
|
+
success: boolean;
|
|
5
|
+
notes: string;
|
|
6
|
+
filesChanged: string[];
|
|
7
|
+
commitHash?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Run the generator agent to implement changes for a sprint.
|
|
11
|
+
*
|
|
12
|
+
* Each invocation is a FRESH call (context reset). The handoff
|
|
13
|
+
* document carries all necessary context from previous phases.
|
|
14
|
+
*/
|
|
15
|
+
export declare function runGenerator(handoff: ContextHandoff, projectRoot: string, config: BoberConfig): Promise<GeneratorResult>;
|
|
16
|
+
//# sourceMappingURL=generator-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator-agent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/generator-agent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAM3D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmDD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,CAAC,CA8C1B"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
import { serializeHandoff } from "./context-handoff.js";
|
|
3
|
+
import { logger } from "../utils/logger.js";
|
|
4
|
+
// ── Model mapping ──────────────────────────────────────────────────
|
|
5
|
+
function resolveModel(choice) {
|
|
6
|
+
switch (choice) {
|
|
7
|
+
case "opus":
|
|
8
|
+
return "claude-sonnet-4-20250514";
|
|
9
|
+
case "sonnet":
|
|
10
|
+
return "claude-sonnet-4-20250514";
|
|
11
|
+
case "haiku":
|
|
12
|
+
return "claude-haiku-4-20250414";
|
|
13
|
+
default:
|
|
14
|
+
return "claude-sonnet-4-20250514";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// ── System prompt ──────────────────────────────────────────────────
|
|
18
|
+
const GENERATOR_SYSTEM_PROMPT = `You are the Bober Generator agent. Your job is to implement code changes according to a sprint contract.
|
|
19
|
+
|
|
20
|
+
You will receive a context handoff document containing:
|
|
21
|
+
- The overall plan specification
|
|
22
|
+
- The current sprint contract with success criteria
|
|
23
|
+
- History of completed sprints
|
|
24
|
+
- Any feedback from prior evaluation rounds
|
|
25
|
+
|
|
26
|
+
Your responsibilities:
|
|
27
|
+
1. Implement the changes described in the sprint contract.
|
|
28
|
+
2. Follow the success criteria exactly — each criterion must be met.
|
|
29
|
+
3. Work incrementally: make small, testable changes.
|
|
30
|
+
4. Self-verify before reporting completion.
|
|
31
|
+
5. If you received evaluation feedback, address every issue mentioned.
|
|
32
|
+
|
|
33
|
+
Output format — respond with a JSON object:
|
|
34
|
+
{
|
|
35
|
+
"success": true/false,
|
|
36
|
+
"notes": "Description of what was implemented and any issues encountered",
|
|
37
|
+
"filesChanged": ["list", "of", "changed", "file", "paths"]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Guidelines:
|
|
41
|
+
- Follow existing code style and conventions in the project.
|
|
42
|
+
- Do not break existing functionality.
|
|
43
|
+
- If a task cannot be completed, set success to false and explain why in notes.
|
|
44
|
+
- List ALL files that were created, modified, or deleted.
|
|
45
|
+
|
|
46
|
+
Output ONLY the JSON object. No markdown fences, no explanation.`;
|
|
47
|
+
// ── Main ───────────────────────────────────────────────────────────
|
|
48
|
+
/**
|
|
49
|
+
* Run the generator agent to implement changes for a sprint.
|
|
50
|
+
*
|
|
51
|
+
* Each invocation is a FRESH call (context reset). The handoff
|
|
52
|
+
* document carries all necessary context from previous phases.
|
|
53
|
+
*/
|
|
54
|
+
export async function runGenerator(handoff, projectRoot, config) {
|
|
55
|
+
const contractId = handoff.currentContract?.id ?? "unknown";
|
|
56
|
+
const feature = handoff.currentContract?.feature ?? "unknown";
|
|
57
|
+
logger.sprint(contractId, `Generating: ${feature}`);
|
|
58
|
+
const model = resolveModel(config.generator.model);
|
|
59
|
+
const client = new Anthropic();
|
|
60
|
+
const handoffJson = serializeHandoff(handoff);
|
|
61
|
+
const userMessage = `# Context Handoff
|
|
62
|
+
${handoffJson}
|
|
63
|
+
|
|
64
|
+
# Project Root
|
|
65
|
+
${projectRoot}
|
|
66
|
+
|
|
67
|
+
Implement the changes described in the sprint contract. Follow every success criterion.
|
|
68
|
+
${handoff.issues.length > 0 ? `\n# Previous Issues to Fix\n${handoff.issues.join("\n")}` : ""}
|
|
69
|
+
|
|
70
|
+
Output ONLY a JSON object with { success, notes, filesChanged }. No markdown fences.`;
|
|
71
|
+
logger.debug(`Calling generator model (${config.generator.model})...`);
|
|
72
|
+
const response = await client.messages.create({
|
|
73
|
+
model,
|
|
74
|
+
max_tokens: 8192,
|
|
75
|
+
system: GENERATOR_SYSTEM_PROMPT,
|
|
76
|
+
messages: [
|
|
77
|
+
{
|
|
78
|
+
role: "user",
|
|
79
|
+
content: userMessage,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
let responseText = "";
|
|
84
|
+
for (const block of response.content) {
|
|
85
|
+
if (block.type === "text") {
|
|
86
|
+
responseText += block.text;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
logger.debug("Generator response received, parsing...");
|
|
90
|
+
return parseGeneratorResult(responseText);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Parse the generator response text into a GeneratorResult.
|
|
94
|
+
*/
|
|
95
|
+
function parseGeneratorResult(text) {
|
|
96
|
+
let parsed;
|
|
97
|
+
// Try direct parse
|
|
98
|
+
try {
|
|
99
|
+
parsed = JSON.parse(text.trim());
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Try extracting from markdown fences
|
|
103
|
+
const fenceMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/.exec(text);
|
|
104
|
+
if (fenceMatch) {
|
|
105
|
+
try {
|
|
106
|
+
parsed = JSON.parse(fenceMatch[1].trim());
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Fall through
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Try finding { ... }
|
|
113
|
+
if (!parsed) {
|
|
114
|
+
const braceStart = text.indexOf("{");
|
|
115
|
+
const braceEnd = text.lastIndexOf("}");
|
|
116
|
+
if (braceStart !== -1 && braceEnd > braceStart) {
|
|
117
|
+
try {
|
|
118
|
+
parsed = JSON.parse(text.slice(braceStart, braceEnd + 1));
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Fall through to default
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (parsed &&
|
|
127
|
+
typeof parsed === "object" &&
|
|
128
|
+
parsed !== null &&
|
|
129
|
+
"success" in parsed) {
|
|
130
|
+
const obj = parsed;
|
|
131
|
+
return {
|
|
132
|
+
success: Boolean(obj.success),
|
|
133
|
+
notes: typeof obj.notes === "string" ? obj.notes : "No notes provided.",
|
|
134
|
+
filesChanged: Array.isArray(obj.filesChanged)
|
|
135
|
+
? obj.filesChanged.filter((f) => typeof f === "string")
|
|
136
|
+
: [],
|
|
137
|
+
commitHash: typeof obj.commitHash === "string" ? obj.commitHash : undefined,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// If parsing failed entirely, return a failure result
|
|
141
|
+
return {
|
|
142
|
+
success: false,
|
|
143
|
+
notes: `Failed to parse generator response. Raw output:\n${text.slice(0, 500)}`,
|
|
144
|
+
filesChanged: [],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=generator-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator-agent.js","sourceRoot":"","sources":["../../src/orchestrator/generator-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { BoberConfig } from "../config/schema.js";
|
|
2
|
+
import type { PlanSpec } from "../contracts/spec.js";
|
|
3
|
+
import type { SprintContract } from "../contracts/sprint-contract.js";
|
|
4
|
+
export interface PipelineResult {
|
|
5
|
+
success: boolean;
|
|
6
|
+
spec: PlanSpec;
|
|
7
|
+
completedSprints: SprintContract[];
|
|
8
|
+
failedSprints: SprintContract[];
|
|
9
|
+
totalCost?: number;
|
|
10
|
+
duration: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Run the complete orchestration pipeline:
|
|
14
|
+
*
|
|
15
|
+
* 1. **Plan** — Call the planner agent to produce a PlanSpec
|
|
16
|
+
* 2. **Sprint loop** — For each feature, create sprint contracts and
|
|
17
|
+
* run the generate-evaluate-iterate cycle
|
|
18
|
+
* 3. **Result** — Return aggregated results
|
|
19
|
+
*
|
|
20
|
+
* Each agent invocation is a FRESH call (new message thread). Context
|
|
21
|
+
* is carried via the ContextHandoff document.
|
|
22
|
+
*/
|
|
23
|
+
export declare function runPipeline(userPrompt: string, projectRoot: string, config: BoberConfig): Promise<PipelineResult>;
|
|
24
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/orchestrator/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AA0BtE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,aAAa,EAAE,cAAc,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA+PD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,cAAc,CAAC,CAuHzB"}
|