@kody-ade/kody-engine-lite 0.1.22 → 0.1.24
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 +44 -4
- package/package.json +1 -1
- package/prompts/review.md +2 -0
package/dist/bin/cli.js
CHANGED
|
@@ -145,7 +145,7 @@ var init_definitions = __esm({
|
|
|
145
145
|
name: "taskify",
|
|
146
146
|
type: "agent",
|
|
147
147
|
modelTier: "cheap",
|
|
148
|
-
timeout:
|
|
148
|
+
timeout: 3e5,
|
|
149
149
|
maxRetries: 1,
|
|
150
150
|
outputFile: "task.json"
|
|
151
151
|
},
|
|
@@ -743,9 +743,12 @@ var init_context = __esm({
|
|
|
743
743
|
});
|
|
744
744
|
|
|
745
745
|
// src/validators.ts
|
|
746
|
+
function stripFences(content) {
|
|
747
|
+
return content.replace(/^```json\s*\n?/m, "").replace(/\n?```\s*$/m, "");
|
|
748
|
+
}
|
|
746
749
|
function validateTaskJson(content) {
|
|
747
750
|
try {
|
|
748
|
-
const parsed = JSON.parse(content);
|
|
751
|
+
const parsed = JSON.parse(stripFences(content));
|
|
749
752
|
for (const field of REQUIRED_TASK_FIELDS) {
|
|
750
753
|
if (!(field in parsed)) {
|
|
751
754
|
return { valid: false, error: `Missing field: ${field}` };
|
|
@@ -868,7 +871,26 @@ async function executeAgentStage(ctx, def) {
|
|
|
868
871
|
const content = fs5.readFileSync(outputPath, "utf-8");
|
|
869
872
|
const validation = validateStageOutput(def.name, content);
|
|
870
873
|
if (!validation.valid) {
|
|
871
|
-
|
|
874
|
+
if (def.name === "taskify") {
|
|
875
|
+
logger.warn(` taskify output invalid (${validation.error}), retrying...`);
|
|
876
|
+
const retryPrompt = prompt + "\n\nIMPORTANT: Your previous output was not valid JSON. Output ONLY the raw JSON object. No markdown, no fences, no explanation.";
|
|
877
|
+
const retryResult = await runner.run(def.name, retryPrompt, model, def.timeout, ctx.taskDir, {
|
|
878
|
+
cwd: ctx.projectDir,
|
|
879
|
+
env: extraEnv
|
|
880
|
+
});
|
|
881
|
+
if (retryResult.outcome === "completed" && retryResult.output) {
|
|
882
|
+
const stripped = stripFences(retryResult.output);
|
|
883
|
+
const retryValidation = validateTaskJson(stripped);
|
|
884
|
+
if (retryValidation.valid) {
|
|
885
|
+
fs5.writeFileSync(outputPath, retryResult.output);
|
|
886
|
+
logger.info(` taskify retry produced valid JSON`);
|
|
887
|
+
} else {
|
|
888
|
+
logger.warn(` taskify retry still invalid: ${retryValidation.error}`);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
} else {
|
|
892
|
+
logger.warn(` validation warning: ${validation.error}`);
|
|
893
|
+
}
|
|
872
894
|
}
|
|
873
895
|
}
|
|
874
896
|
}
|
|
@@ -2096,11 +2118,26 @@ async function tryStartLitellm(url, projectDir) {
|
|
|
2096
2118
|
cmd = "python3";
|
|
2097
2119
|
args2 = ["-m", "litellm", "--config", configPath, "--port", port];
|
|
2098
2120
|
}
|
|
2121
|
+
const dotenvPath = path14.join(projectDir, ".env");
|
|
2122
|
+
const dotenvVars = {};
|
|
2123
|
+
if (fs15.existsSync(dotenvPath)) {
|
|
2124
|
+
for (const line of fs15.readFileSync(dotenvPath, "utf-8").split("\n")) {
|
|
2125
|
+
const match = line.match(/^([A-Z_][A-Z0-9_]*_API_KEY)=(.*)$/);
|
|
2126
|
+
if (match) dotenvVars[match[1]] = match[2];
|
|
2127
|
+
}
|
|
2128
|
+
if (Object.keys(dotenvVars).length > 0) {
|
|
2129
|
+
logger.info(` Loaded API keys: ${Object.keys(dotenvVars).join(", ")}`);
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2099
2132
|
const { spawn: spawn2 } = await import("child_process");
|
|
2100
2133
|
const child = spawn2(cmd, args2, {
|
|
2101
2134
|
stdio: ["ignore", "pipe", "pipe"],
|
|
2102
2135
|
detached: true,
|
|
2103
|
-
env: process.env
|
|
2136
|
+
env: { ...process.env, ...dotenvVars }
|
|
2137
|
+
});
|
|
2138
|
+
let proxyStderr = "";
|
|
2139
|
+
child.stderr?.on("data", (chunk) => {
|
|
2140
|
+
proxyStderr += chunk.toString();
|
|
2104
2141
|
});
|
|
2105
2142
|
for (let i = 0; i < 30; i++) {
|
|
2106
2143
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
@@ -2109,6 +2146,9 @@ async function tryStartLitellm(url, projectDir) {
|
|
|
2109
2146
|
return child;
|
|
2110
2147
|
}
|
|
2111
2148
|
}
|
|
2149
|
+
if (proxyStderr) {
|
|
2150
|
+
logger.warn(`LiteLLM stderr: ${proxyStderr.slice(-1e3)}`);
|
|
2151
|
+
}
|
|
2112
2152
|
logger.warn("LiteLLM proxy failed to start within 60s");
|
|
2113
2153
|
child.kill();
|
|
2114
2154
|
return null;
|
package/package.json
CHANGED
package/prompts/review.md
CHANGED
|
@@ -9,6 +9,8 @@ You are a code review agent. Review all changes made for the task described belo
|
|
|
9
9
|
|
|
10
10
|
Use Bash to run `git diff` to see what changed. Use Read to examine modified files in full context.
|
|
11
11
|
|
|
12
|
+
CRITICAL: You MUST output a structured review in the EXACT format below. Do NOT output conversational text, status updates, or summaries. Your entire output must be the structured review markdown.
|
|
13
|
+
|
|
12
14
|
Output markdown with this EXACT structure:
|
|
13
15
|
|
|
14
16
|
## Verdict: PASS | FAIL
|