@kody-ade/kody-engine-lite 0.1.89 → 0.1.91
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 +55 -1
- package/kody.config.schema.json +14 -0
- package/package.json +1 -1
- package/prompts/taskify.md +8 -0
- package/templates/kody.yml +2 -1
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`);
|
|
@@ -2651,7 +2671,18 @@ function checkQuestionsAfterStage(ctx, def, state) {
|
|
|
2651
2671
|
}
|
|
2652
2672
|
function autoDetectComplexity(ctx, def) {
|
|
2653
2673
|
if (def.name !== "taskify") return null;
|
|
2654
|
-
if (ctx.input.complexity)
|
|
2674
|
+
if (ctx.input.complexity) {
|
|
2675
|
+
const complexity = ctx.input.complexity;
|
|
2676
|
+
const activeStages = filterByComplexity(STAGES, complexity);
|
|
2677
|
+
logger.info(` Complexity override: ${complexity} (${activeStages.map((s) => s.name).join(" \u2192 ")})`);
|
|
2678
|
+
if (ctx.input.issueNumber && !ctx.input.local) {
|
|
2679
|
+
try {
|
|
2680
|
+
setLifecycleLabel(ctx.input.issueNumber, complexity);
|
|
2681
|
+
} catch {
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
return { complexity, activeStages };
|
|
2685
|
+
}
|
|
2655
2686
|
try {
|
|
2656
2687
|
const taskJsonPath = path14.join(ctx.taskDir, "task.json");
|
|
2657
2688
|
if (!fs14.existsSync(taskJsonPath)) return null;
|
|
@@ -3177,6 +3208,25 @@ async function runPipeline(ctx) {
|
|
|
3177
3208
|
acquireLock(ctx.taskDir);
|
|
3178
3209
|
try {
|
|
3179
3210
|
return await runPipelineInner(ctx);
|
|
3211
|
+
} catch (err) {
|
|
3212
|
+
try {
|
|
3213
|
+
const state = loadState(ctx.taskId, ctx.taskDir);
|
|
3214
|
+
if (state && state.state === "running") {
|
|
3215
|
+
state.state = "failed";
|
|
3216
|
+
for (const stage of STAGES) {
|
|
3217
|
+
if (state.stages[stage.name]?.state === "running") {
|
|
3218
|
+
state.stages[stage.name] = {
|
|
3219
|
+
...state.stages[stage.name],
|
|
3220
|
+
state: "failed",
|
|
3221
|
+
error: "Pipeline crashed unexpectedly"
|
|
3222
|
+
};
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
writeState(state, ctx.taskDir);
|
|
3226
|
+
}
|
|
3227
|
+
} catch {
|
|
3228
|
+
}
|
|
3229
|
+
throw err;
|
|
3180
3230
|
} finally {
|
|
3181
3231
|
releaseLock(ctx.taskDir);
|
|
3182
3232
|
}
|
|
@@ -4113,6 +4163,10 @@ ${input.feedback}`);
|
|
|
4113
4163
|
}
|
|
4114
4164
|
}
|
|
4115
4165
|
const config = getProjectConfig();
|
|
4166
|
+
if (config.timeouts) {
|
|
4167
|
+
const { applyTimeoutOverrides: applyTimeoutOverrides2 } = await Promise.resolve().then(() => (init_definitions(), definitions_exports));
|
|
4168
|
+
applyTimeoutOverrides2(config.timeouts);
|
|
4169
|
+
}
|
|
4116
4170
|
let litellmProcess = await ensureLitellmProxy(config, projectDir);
|
|
4117
4171
|
await runModelHealthCheck(config);
|
|
4118
4172
|
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")
|
package/templates/kody.yml
CHANGED
|
@@ -99,8 +99,9 @@ jobs:
|
|
|
99
99
|
- name: Parse inputs
|
|
100
100
|
if: steps.safety.outputs.valid == 'true'
|
|
101
101
|
id: parse
|
|
102
|
+
env:
|
|
103
|
+
BODY: ${{ github.event.comment.body }}
|
|
102
104
|
run: |
|
|
103
|
-
BODY="${{ github.event.comment.body }}"
|
|
104
105
|
# Extract: @kody [mode] [task-id] [--from stage]
|
|
105
106
|
KODY_ARGS=$(echo "$BODY" | grep -oP '(?:@kody|/kody)\s+\K.*' || echo "")
|
|
106
107
|
MODE=$(echo "$KODY_ARGS" | awk '{print $1}')
|