@kody-ade/kody-engine-lite 0.1.90 → 0.1.92
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/dist/bin/cli.js +58 -2
- package/kody.config.schema.json +14 -0
- package/package.json +1 -1
- package/prompts/taskify.md +8 -0
package/dist/bin/cli.js
CHANGED
|
@@ -145,6 +145,22 @@ var init_agent_runner = __esm({
|
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
// src/definitions.ts
|
|
148
|
+
var definitions_exports = {};
|
|
149
|
+
__export(definitions_exports, {
|
|
150
|
+
STAGES: () => STAGES,
|
|
151
|
+
applyTimeoutOverrides: () => applyTimeoutOverrides,
|
|
152
|
+
getStage: () => getStage
|
|
153
|
+
});
|
|
154
|
+
function getStage(name) {
|
|
155
|
+
return STAGES.find((s) => s.name === name);
|
|
156
|
+
}
|
|
157
|
+
function applyTimeoutOverrides(overrides) {
|
|
158
|
+
for (const stage of STAGES) {
|
|
159
|
+
if (overrides[stage.name] != null) {
|
|
160
|
+
stage.timeout = overrides[stage.name] * 1e3;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
148
164
|
var STAGES;
|
|
149
165
|
var init_definitions = __esm({
|
|
150
166
|
"src/definitions.ts"() {
|
|
@@ -287,6 +303,7 @@ function getProjectConfig() {
|
|
|
287
303
|
...raw.agent,
|
|
288
304
|
modelMap: { ...DEFAULT_CONFIG.agent.modelMap, ...raw.agent?.modelMap }
|
|
289
305
|
},
|
|
306
|
+
timeouts: raw.timeouts ?? void 0,
|
|
290
307
|
contextTiers: raw.contextTiers ? { ...DEFAULT_CONFIG.contextTiers, ...raw.contextTiers } : DEFAULT_CONFIG.contextTiers,
|
|
291
308
|
mcp: raw.mcp ? { enabled: false, servers: {}, stages: ["build", "verify", "review", "review-fix"], ...raw.mcp } : void 0
|
|
292
309
|
};
|
|
@@ -1661,6 +1678,9 @@ async function executeAgentStage(ctx, def) {
|
|
|
1661
1678
|
}
|
|
1662
1679
|
const prompt = buildFullPrompt(def.name, ctx.taskId, ctx.taskDir, ctx.projectDir, ctx.input.feedback);
|
|
1663
1680
|
const model = resolveModel(def.modelTier, def.name);
|
|
1681
|
+
if (ctx.input.feedback && def.name === "build") {
|
|
1682
|
+
logger.info(` feedback: ${ctx.input.feedback.slice(0, 200)}${ctx.input.feedback.length > 200 ? "..." : ""}`);
|
|
1683
|
+
}
|
|
1664
1684
|
const config = getProjectConfig();
|
|
1665
1685
|
const runnerName = config.agent.stageRunners?.[def.name] ?? config.agent.defaultRunner ?? Object.keys(ctx.runners)[0] ?? "claude";
|
|
1666
1686
|
logger.info(` runner=${runnerName} model=${model} timeout=${def.timeout / 1e3}s`);
|
|
@@ -2512,7 +2532,9 @@ PR #${existingPr.number}
|
|
|
2512
2532
|
postComment(ctx.input.issueNumber, `\u{1F389} PR created: ${pr.url}`);
|
|
2513
2533
|
} catch {
|
|
2514
2534
|
}
|
|
2515
|
-
|
|
2535
|
+
if (ctx.input.issueNumber !== ctx.input.prNumber) {
|
|
2536
|
+
closeIssue(ctx.input.issueNumber);
|
|
2537
|
+
}
|
|
2516
2538
|
}
|
|
2517
2539
|
fs12.writeFileSync(shipPath, `# Ship
|
|
2518
2540
|
|
|
@@ -2651,7 +2673,18 @@ function checkQuestionsAfterStage(ctx, def, state) {
|
|
|
2651
2673
|
}
|
|
2652
2674
|
function autoDetectComplexity(ctx, def) {
|
|
2653
2675
|
if (def.name !== "taskify") return null;
|
|
2654
|
-
if (ctx.input.complexity)
|
|
2676
|
+
if (ctx.input.complexity) {
|
|
2677
|
+
const complexity = ctx.input.complexity;
|
|
2678
|
+
const activeStages = filterByComplexity(STAGES, complexity);
|
|
2679
|
+
logger.info(` Complexity override: ${complexity} (${activeStages.map((s) => s.name).join(" \u2192 ")})`);
|
|
2680
|
+
if (ctx.input.issueNumber && !ctx.input.local) {
|
|
2681
|
+
try {
|
|
2682
|
+
setLifecycleLabel(ctx.input.issueNumber, complexity);
|
|
2683
|
+
} catch {
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
return { complexity, activeStages };
|
|
2687
|
+
}
|
|
2655
2688
|
try {
|
|
2656
2689
|
const taskJsonPath = path14.join(ctx.taskDir, "task.json");
|
|
2657
2690
|
if (!fs14.existsSync(taskJsonPath)) return null;
|
|
@@ -3177,6 +3210,25 @@ async function runPipeline(ctx) {
|
|
|
3177
3210
|
acquireLock(ctx.taskDir);
|
|
3178
3211
|
try {
|
|
3179
3212
|
return await runPipelineInner(ctx);
|
|
3213
|
+
} catch (err) {
|
|
3214
|
+
try {
|
|
3215
|
+
const state = loadState(ctx.taskId, ctx.taskDir);
|
|
3216
|
+
if (state && state.state === "running") {
|
|
3217
|
+
state.state = "failed";
|
|
3218
|
+
for (const stage of STAGES) {
|
|
3219
|
+
if (state.stages[stage.name]?.state === "running") {
|
|
3220
|
+
state.stages[stage.name] = {
|
|
3221
|
+
...state.stages[stage.name],
|
|
3222
|
+
state: "failed",
|
|
3223
|
+
error: "Pipeline crashed unexpectedly"
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3227
|
+
writeState(state, ctx.taskDir);
|
|
3228
|
+
}
|
|
3229
|
+
} catch {
|
|
3230
|
+
}
|
|
3231
|
+
throw err;
|
|
3180
3232
|
} finally {
|
|
3181
3233
|
releaseLock(ctx.taskDir);
|
|
3182
3234
|
}
|
|
@@ -4113,6 +4165,10 @@ ${input.feedback}`);
|
|
|
4113
4165
|
}
|
|
4114
4166
|
}
|
|
4115
4167
|
const config = getProjectConfig();
|
|
4168
|
+
if (config.timeouts) {
|
|
4169
|
+
const { applyTimeoutOverrides: applyTimeoutOverrides2 } = await Promise.resolve().then(() => (init_definitions(), definitions_exports));
|
|
4170
|
+
applyTimeoutOverrides2(config.timeouts);
|
|
4171
|
+
}
|
|
4116
4172
|
let litellmProcess = await ensureLitellmProxy(config, projectDir);
|
|
4117
4173
|
await runModelHealthCheck(config);
|
|
4118
4174
|
const cleanupLitellm = () => {
|
package/kody.config.schema.json
CHANGED
|
@@ -63,6 +63,20 @@
|
|
|
63
63
|
},
|
|
64
64
|
"additionalProperties": false
|
|
65
65
|
},
|
|
66
|
+
"timeouts": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"description": "Per-stage timeout overrides in seconds. Defaults: taskify=600, plan=600, build=2400, verify=300, review=600, review-fix=1200, ship=240",
|
|
69
|
+
"properties": {
|
|
70
|
+
"taskify": { "type": "number", "description": "Taskify stage timeout in seconds", "default": 600 },
|
|
71
|
+
"plan": { "type": "number", "description": "Plan stage timeout in seconds", "default": 600 },
|
|
72
|
+
"build": { "type": "number", "description": "Build stage timeout in seconds", "default": 2400 },
|
|
73
|
+
"verify": { "type": "number", "description": "Verify stage timeout in seconds", "default": 300 },
|
|
74
|
+
"review": { "type": "number", "description": "Review stage timeout in seconds", "default": 600 },
|
|
75
|
+
"review-fix": { "type": "number", "description": "Review-fix stage timeout in seconds", "default": 1200 },
|
|
76
|
+
"ship": { "type": "number", "description": "Ship stage timeout in seconds", "default": 240 }
|
|
77
|
+
},
|
|
78
|
+
"additionalProperties": false
|
|
79
|
+
},
|
|
66
80
|
"agent": {
|
|
67
81
|
"type": "object",
|
|
68
82
|
"description": "Agent execution configuration",
|
package/package.json
CHANGED
package/prompts/taskify.md
CHANGED
|
@@ -42,6 +42,14 @@ Questions rules:
|
|
|
42
42
|
Good questions: "Should the search be case-sensitive?", "Which users should have access?", "Should this work offline?"
|
|
43
43
|
Bad questions: "What framework should I use?", "Where should I put the file?", "What's the project structure?"
|
|
44
44
|
|
|
45
|
+
If the task is already implemented (files exist, tests pass):
|
|
46
|
+
- Still output valid JSON — never output plain text
|
|
47
|
+
- Set task_type to "chore"
|
|
48
|
+
- Set risk_level to "low"
|
|
49
|
+
- Set title to "Verify existing implementation of <feature>"
|
|
50
|
+
- Set description to explain that the work already exists and what was verified
|
|
51
|
+
- Set scope to the existing file paths
|
|
52
|
+
|
|
45
53
|
Guidelines:
|
|
46
54
|
- scope must contain exact file paths (use Glob to discover them)
|
|
47
55
|
- title must be actionable ("Add X", "Fix Y", "Refactor Z")
|