karajan-code 1.49.0 → 1.50.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/package.json +1 -1
- package/src/mcp/handlers/direct-handlers.js +393 -0
- package/src/mcp/handlers/hu-handlers.js +93 -0
- package/src/mcp/handlers/management-handlers.js +182 -0
- package/src/mcp/handlers/run-handler.js +283 -0
- package/src/mcp/server-handlers.js +40 -870
- package/src/orchestrator/iteration-stages.js +9 -890
- package/src/orchestrator/pre-loop-stages.js +8 -906
- package/src/orchestrator/stages/architect-stage.js +176 -0
- package/src/orchestrator/stages/coder-stage.js +307 -0
- package/src/orchestrator/stages/hu-reviewer-stage.js +467 -0
- package/src/orchestrator/stages/planner-stage.js +90 -0
- package/src/orchestrator/stages/research-stage.js +74 -0
- package/src/orchestrator/stages/reviewer-stage.js +350 -0
- package/src/orchestrator/stages/sonar-stage.js +267 -0
- package/src/orchestrator/stages/triage-stage.js +137 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triage stage logic.
|
|
3
|
+
* Extracted from pre-loop-stages.js for maintainability.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TriageRole } from "../../roles/triage-role.js";
|
|
7
|
+
import { addCheckpoint } from "../../session-store.js";
|
|
8
|
+
import { emitProgress, makeEvent } from "../../utils/events.js";
|
|
9
|
+
import { selectModelsForRoles } from "../../utils/model-selector.js";
|
|
10
|
+
import { createStallDetector } from "../../utils/stall-detector.js";
|
|
11
|
+
|
|
12
|
+
const ROLE_NAMES = ["planner", "researcher", "architect", "refactorer", "reviewer", "tester", "security", "impeccable"];
|
|
13
|
+
|
|
14
|
+
function buildRoleOverrides(recommendedRoles, pipelineConfig) {
|
|
15
|
+
const overrides = {};
|
|
16
|
+
for (const role of ROLE_NAMES) {
|
|
17
|
+
overrides[`${role}Enabled`] = recommendedRoles.has(role) || Boolean(pipelineConfig[role]?.enabled);
|
|
18
|
+
}
|
|
19
|
+
return overrides;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function applyModelSelection(triageOutput, config, emitter, eventBase) {
|
|
23
|
+
if (!triageOutput.ok || !config?.model_selection?.enabled) return null;
|
|
24
|
+
const level = triageOutput.result?.level;
|
|
25
|
+
if (!level) return null;
|
|
26
|
+
|
|
27
|
+
const { modelOverrides, reasoning } = selectModelsForRoles({ level, config });
|
|
28
|
+
for (const [role, model] of Object.entries(modelOverrides)) {
|
|
29
|
+
if (config.roles?.[role] && !config.roles[role].model) {
|
|
30
|
+
config.roles[role].model = model;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const modelSelection = { modelOverrides, reasoning };
|
|
34
|
+
emitProgress(
|
|
35
|
+
emitter,
|
|
36
|
+
makeEvent("model-selection:applied", { ...eventBase, stage: "triage" }, {
|
|
37
|
+
message: "Smart model selection applied",
|
|
38
|
+
detail: modelSelection
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
return modelSelection;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function runTriageStage({ config, logger, emitter, eventBase, session, coderRole, trackBudget }) {
|
|
45
|
+
logger.setContext({ iteration: 0, stage: "triage" });
|
|
46
|
+
|
|
47
|
+
const triageProvider = config?.roles?.triage?.provider || coderRole.provider;
|
|
48
|
+
emitProgress(
|
|
49
|
+
emitter,
|
|
50
|
+
makeEvent("triage:start", { ...eventBase, stage: "triage" }, {
|
|
51
|
+
message: "Triage classifying task complexity",
|
|
52
|
+
detail: { provider: triageProvider, executorType: "agent" }
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const triageOnOutput = ({ stream, line }) => {
|
|
57
|
+
emitProgress(emitter, makeEvent("agent:output", { ...eventBase, stage: "triage" }, {
|
|
58
|
+
message: line,
|
|
59
|
+
detail: { stream, agent: triageProvider }
|
|
60
|
+
}));
|
|
61
|
+
};
|
|
62
|
+
const triageStall = createStallDetector({
|
|
63
|
+
onOutput: triageOnOutput, emitter, eventBase, stage: "triage", provider: triageProvider
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const triage = new TriageRole({ config, logger, emitter });
|
|
67
|
+
await triage.init({ task: session.task, sessionId: session.id, iteration: 0 });
|
|
68
|
+
const triageStart = Date.now();
|
|
69
|
+
let triageOutput;
|
|
70
|
+
try {
|
|
71
|
+
triageOutput = await triage.run({ task: session.task, onOutput: triageStall.onOutput });
|
|
72
|
+
} catch (err) {
|
|
73
|
+
logger.warn(`Triage threw: ${err.message}`);
|
|
74
|
+
triageOutput = { ok: false, summary: `Triage error: ${err.message}`, result: { error: err.message } };
|
|
75
|
+
} finally {
|
|
76
|
+
triageStall.stop();
|
|
77
|
+
}
|
|
78
|
+
trackBudget({
|
|
79
|
+
role: "triage",
|
|
80
|
+
provider: config?.roles?.triage?.provider || coderRole.provider,
|
|
81
|
+
model: config?.roles?.triage?.model || coderRole.model,
|
|
82
|
+
result: triageOutput,
|
|
83
|
+
duration_ms: Date.now() - triageStart
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await addCheckpoint(session, {
|
|
87
|
+
stage: "triage",
|
|
88
|
+
iteration: 0,
|
|
89
|
+
ok: triageOutput.ok,
|
|
90
|
+
provider: config?.roles?.triage?.provider || coderRole.provider,
|
|
91
|
+
model: config?.roles?.triage?.model || coderRole.model || null
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const recommendedRoles = new Set(triageOutput.result?.roles || []);
|
|
95
|
+
const roleOverrides = triageOutput.ok
|
|
96
|
+
? buildRoleOverrides(recommendedRoles, config.pipeline || {})
|
|
97
|
+
: {};
|
|
98
|
+
|
|
99
|
+
const shouldDecompose = triageOutput.result?.shouldDecompose || false;
|
|
100
|
+
const subtasks = triageOutput.result?.subtasks || [];
|
|
101
|
+
|
|
102
|
+
const stageResult = {
|
|
103
|
+
ok: triageOutput.ok,
|
|
104
|
+
level: triageOutput.result?.level || null,
|
|
105
|
+
roles: Array.from(recommendedRoles),
|
|
106
|
+
reasoning: triageOutput.result?.reasoning || null,
|
|
107
|
+
taskType: triageOutput.result?.taskType || "sw",
|
|
108
|
+
shouldDecompose,
|
|
109
|
+
subtasks
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const modelSelection = applyModelSelection(triageOutput, config, emitter, eventBase);
|
|
113
|
+
if (modelSelection) {
|
|
114
|
+
stageResult.modelSelection = modelSelection;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (shouldDecompose && subtasks.length > 0) {
|
|
118
|
+
emitProgress(
|
|
119
|
+
emitter,
|
|
120
|
+
makeEvent("triage:decompose", { ...eventBase, stage: "triage" }, {
|
|
121
|
+
message: `Task decomposition recommended: ${subtasks.length} subtask${subtasks.length === 1 ? "" : "s"}`,
|
|
122
|
+
detail: { shouldDecompose, subtasks }
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
emitProgress(
|
|
128
|
+
emitter,
|
|
129
|
+
makeEvent("triage:end", { ...eventBase, stage: "triage" }, {
|
|
130
|
+
status: triageOutput.ok ? "ok" : "fail",
|
|
131
|
+
message: triageOutput.ok ? "Triage completed" : `Triage failed: ${triageOutput.summary}`,
|
|
132
|
+
detail: { ...stageResult, provider: triageProvider, executorType: "agent" }
|
|
133
|
+
})
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
return { roleOverrides, stageResult };
|
|
137
|
+
}
|