@kody-ade/kody-engine 0.4.214 → 0.4.216
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/kody.js +24 -47
- package/package.json +1 -1
package/dist/bin/kody.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@kody-ade/kody-engine",
|
|
18
|
-
version: "0.4.
|
|
18
|
+
version: "0.4.216",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -4331,10 +4331,10 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
|
|
|
4331
4331
|
let child;
|
|
4332
4332
|
let logPath;
|
|
4333
4333
|
const spawnProxy = () => {
|
|
4334
|
-
const configPath = path17.join(os3.tmpdir(), `kody-litellm-${Date.now()}.yaml`);
|
|
4334
|
+
const configPath = path17.join(os3.tmpdir(), `kody-local-litellm-${Date.now()}.yaml`);
|
|
4335
4335
|
fs19.writeFileSync(configPath, generateLitellmConfigYaml(model));
|
|
4336
4336
|
const args = ["--config", configPath, "--port", port];
|
|
4337
|
-
const nextLogPath = path17.join(os3.tmpdir(), `kody-litellm-${Date.now()}.log`);
|
|
4337
|
+
const nextLogPath = path17.join(os3.tmpdir(), `kody-local-litellm-${Date.now()}.log`);
|
|
4338
4338
|
const outFd = fs19.openSync(nextLogPath, "w");
|
|
4339
4339
|
child = spawn3(cmd, args, { stdio: ["ignore", outFd, outFd], detached: true, env: childEnv });
|
|
4340
4340
|
fs19.closeSync(outFd);
|
|
@@ -17613,7 +17613,6 @@ init_executor();
|
|
|
17613
17613
|
init_registry();
|
|
17614
17614
|
|
|
17615
17615
|
// src/servers/pool-serve.ts
|
|
17616
|
-
import { spawn as spawn8 } from "child_process";
|
|
17617
17616
|
import { createServer as createServer4 } from "http";
|
|
17618
17617
|
|
|
17619
17618
|
// src/github-health.ts
|
|
@@ -17748,6 +17747,10 @@ var FlyClient = class {
|
|
|
17748
17747
|
}
|
|
17749
17748
|
/** Create + start a pooled machine in serve mode, tagged for `repoTag`. */
|
|
17750
17749
|
async createPooled(input) {
|
|
17750
|
+
const env = {
|
|
17751
|
+
RUNNER_API_KEY: input.runnerApiKey,
|
|
17752
|
+
PORT: String(input.port ?? 8080)
|
|
17753
|
+
};
|
|
17751
17754
|
const body = {
|
|
17752
17755
|
region: input.region,
|
|
17753
17756
|
config: {
|
|
@@ -17760,11 +17763,7 @@ var FlyClient = class {
|
|
|
17760
17763
|
[POOL_METADATA_KEY]: POOL_METADATA_VALUE,
|
|
17761
17764
|
[POOL_REPO_METADATA_KEY]: input.repoTag
|
|
17762
17765
|
},
|
|
17763
|
-
env
|
|
17764
|
-
RUNNER_API_KEY: input.runnerApiKey,
|
|
17765
|
-
KODY_LITELLM_URL: input.litellmUrl,
|
|
17766
|
-
PORT: String(input.port ?? 8080)
|
|
17767
|
-
}
|
|
17766
|
+
env
|
|
17768
17767
|
}
|
|
17769
17768
|
};
|
|
17770
17769
|
const m = await this.call(`/apps/${enc(this.opts.app)}/machines`, { method: "POST", body });
|
|
@@ -17981,7 +17980,6 @@ var PoolManager = class {
|
|
|
17981
17980
|
region: cfg.region,
|
|
17982
17981
|
guest: cfg.guest,
|
|
17983
17982
|
runnerApiKey: cfg.runnerApiKey,
|
|
17984
|
-
litellmUrl: cfg.litellmUrl,
|
|
17985
17983
|
repoTag: cfg.repoTag,
|
|
17986
17984
|
port: cfg.port
|
|
17987
17985
|
});
|
|
@@ -18204,10 +18202,19 @@ var PoolRegistry = class {
|
|
|
18204
18202
|
};
|
|
18205
18203
|
return pm.claim(job);
|
|
18206
18204
|
}
|
|
18207
|
-
/** Status for a single repo's pool
|
|
18205
|
+
/** Status for a single repo's pool already known to this owner. */
|
|
18208
18206
|
status(owner, repo) {
|
|
18209
18207
|
return this.pools.get(this.key(owner, repo))?.status() ?? null;
|
|
18210
18208
|
}
|
|
18209
|
+
/**
|
|
18210
|
+
* Status for a repo, creating/adopting its pool on first read when the repo
|
|
18211
|
+
* has pool credentials. This lets a restarted owner recover from existing
|
|
18212
|
+
* pooled machines without waiting for the next claim.
|
|
18213
|
+
*/
|
|
18214
|
+
async statusFor(owner, repo) {
|
|
18215
|
+
const pm = await this.getPool(owner, repo);
|
|
18216
|
+
return pm?.status() ?? null;
|
|
18217
|
+
}
|
|
18211
18218
|
/** Resync every active repo pool (periodic self-heal). Also re-reads each
|
|
18212
18219
|
* repo's POOL_MIN from its vault so a dashboard resize warms up/drains within
|
|
18213
18220
|
* one tick — no owner restart needed. */
|
|
@@ -18287,32 +18294,6 @@ function parseClaimRequest(body) {
|
|
|
18287
18294
|
if (typeof b.dashboardUrl === "string" && b.dashboardUrl.trim()) req.dashboardUrl = b.dashboardUrl.trim();
|
|
18288
18295
|
return { req };
|
|
18289
18296
|
}
|
|
18290
|
-
function superviseLitellm() {
|
|
18291
|
-
if (process.env.POOL_DISABLE_LITELLM === "1") return null;
|
|
18292
|
-
const port = String(envInt("LITELLM_PORT", 4e3));
|
|
18293
|
-
const config = process.env.LITELLM_CONFIG ?? "/app/config.yaml";
|
|
18294
|
-
const host = process.env.LITELLM_HOST ?? "::";
|
|
18295
|
-
let restarts = 0;
|
|
18296
|
-
const start = () => {
|
|
18297
|
-
log(`starting litellm child (port ${port}, host ${host})`);
|
|
18298
|
-
const child = spawn8("litellm", ["--config", config, "--port", port, "--host", host], {
|
|
18299
|
-
stdio: "inherit"
|
|
18300
|
-
});
|
|
18301
|
-
child.on("exit", (code) => {
|
|
18302
|
-
restarts++;
|
|
18303
|
-
if (restarts > 50) {
|
|
18304
|
-
process.stderr.write("[pool-serve] litellm restarted too many times \u2014 giving up\n");
|
|
18305
|
-
return;
|
|
18306
|
-
}
|
|
18307
|
-
log(`litellm exited (${code}) \u2014 restarting in 2s`);
|
|
18308
|
-
setTimeout(start, 2e3);
|
|
18309
|
-
});
|
|
18310
|
-
child.on("error", (err) => process.stderr.write(`[pool-serve] litellm spawn error: ${err.message}
|
|
18311
|
-
`));
|
|
18312
|
-
return child;
|
|
18313
|
-
};
|
|
18314
|
-
return start();
|
|
18315
|
-
}
|
|
18316
18297
|
async function poolServe() {
|
|
18317
18298
|
const masterRaw = process.env.KODY_MASTER_KEY?.trim();
|
|
18318
18299
|
if (!masterRaw) throw new Error("KODY_MASTER_KEY required for pool-serve");
|
|
@@ -18325,12 +18306,10 @@ async function poolServe() {
|
|
|
18325
18306
|
const region = process.env.POOL_REGION ?? "fra";
|
|
18326
18307
|
const perf = process.env.POOL_PERF ?? "medium";
|
|
18327
18308
|
const guest = PERF_GUEST[perf] ?? PERF_GUEST.medium;
|
|
18328
|
-
const litellmUrl = process.env.KODY_LITELLM_URL ?? "http://kody-litellm.internal:4000";
|
|
18329
18309
|
const min = envInt("POOL_MIN", 2);
|
|
18330
18310
|
const runnerPort = envInt("RUNNER_PORT", 8080);
|
|
18331
18311
|
const apiPort = envInt("POOL_API_PORT", 4100);
|
|
18332
18312
|
const healthTimeoutMs = envInt("POOL_HEALTH_TIMEOUT_MS", 12e4);
|
|
18333
|
-
const litellm = superviseLitellm();
|
|
18334
18313
|
const registry = new PoolRegistry({
|
|
18335
18314
|
githubToken,
|
|
18336
18315
|
masterKey: master,
|
|
@@ -18340,7 +18319,6 @@ async function poolServe() {
|
|
|
18340
18319
|
region,
|
|
18341
18320
|
guest,
|
|
18342
18321
|
runnerApiKey,
|
|
18343
|
-
litellmUrl,
|
|
18344
18322
|
port: runnerPort,
|
|
18345
18323
|
healthTimeoutMs,
|
|
18346
18324
|
app
|
|
@@ -18368,7 +18346,6 @@ async function poolServe() {
|
|
|
18368
18346
|
if (req.method === "GET" && url.pathname === "/healthz") {
|
|
18369
18347
|
return sendJson2(res, 200, {
|
|
18370
18348
|
ok: true,
|
|
18371
|
-
litellm: litellm ? "supervised" : "off",
|
|
18372
18349
|
repos: registry.activeRepos()
|
|
18373
18350
|
});
|
|
18374
18351
|
}
|
|
@@ -18382,7 +18359,7 @@ async function poolServe() {
|
|
|
18382
18359
|
const repoParam = (url.searchParams.get("repo") ?? "").trim();
|
|
18383
18360
|
const [owner, repo] = repoParam.split("/");
|
|
18384
18361
|
if (!owner || !repo) return sendJson2(res, 400, { error: "repo query (owner/name) required" });
|
|
18385
|
-
return sendJson2(res, 200, { status: registry.
|
|
18362
|
+
return sendJson2(res, 200, { status: await registry.statusFor(owner, repo) });
|
|
18386
18363
|
}
|
|
18387
18364
|
if (req.method === "POST" && url.pathname === "/pool/claim") {
|
|
18388
18365
|
let body;
|
|
@@ -18429,7 +18406,7 @@ async function poolServe() {
|
|
|
18429
18406
|
}
|
|
18430
18407
|
|
|
18431
18408
|
// src/servers/runner-serve.ts
|
|
18432
|
-
import { spawn as
|
|
18409
|
+
import { spawn as spawn8 } from "child_process";
|
|
18433
18410
|
import * as fs45 from "fs";
|
|
18434
18411
|
import { createServer as createServer5 } from "http";
|
|
18435
18412
|
var DEFAULT_PORT2 = 8080;
|
|
@@ -18541,7 +18518,7 @@ async function defaultRunJob(job) {
|
|
|
18541
18518
|
...interactive && job.hardCapMs ? { KODY_HARD_CAP_MS: String(job.hardCapMs) } : {}
|
|
18542
18519
|
};
|
|
18543
18520
|
const run = (cmd, args, cwd) => new Promise((resolve6) => {
|
|
18544
|
-
const child =
|
|
18521
|
+
const child = spawn8(cmd, args, { stdio: "inherit", env: childEnv, cwd });
|
|
18545
18522
|
child.on("exit", (code) => resolve6(code ?? 0));
|
|
18546
18523
|
child.on("error", (err) => {
|
|
18547
18524
|
process.stderr.write(`[runner-serve] ${cmd} failed: ${err.message}
|
|
@@ -18645,7 +18622,7 @@ async function runnerServe() {
|
|
|
18645
18622
|
// src/servers/serve.ts
|
|
18646
18623
|
init_config();
|
|
18647
18624
|
init_litellm();
|
|
18648
|
-
import { spawn as
|
|
18625
|
+
import { spawn as spawn9 } from "child_process";
|
|
18649
18626
|
function parseTarget(positional) {
|
|
18650
18627
|
if (!Array.isArray(positional) || positional.length === 0) return "none";
|
|
18651
18628
|
const first = String(positional[0]).toLowerCase();
|
|
@@ -18695,7 +18672,7 @@ async function serve(opts) {
|
|
|
18695
18672
|
if (usesProxy) process.stdout.write(` ANTHROPIC_BASE_URL=${url}
|
|
18696
18673
|
`);
|
|
18697
18674
|
const args = ["--dangerously-skip-permissions", "--model", model.model];
|
|
18698
|
-
const child =
|
|
18675
|
+
const child = spawn9("claude", args, { stdio: "inherit", env: editorEnv, cwd: opts.cwd });
|
|
18699
18676
|
const exitCode = await new Promise((resolve6) => {
|
|
18700
18677
|
child.on("exit", (code) => resolve6(code ?? 0));
|
|
18701
18678
|
child.on("error", (err) => {
|
|
@@ -18715,7 +18692,7 @@ async function serve(opts) {
|
|
|
18715
18692
|
if (usesProxy) process.stdout.write(` ANTHROPIC_BASE_URL=${url}
|
|
18716
18693
|
`);
|
|
18717
18694
|
try {
|
|
18718
|
-
const code =
|
|
18695
|
+
const code = spawn9("code", [opts.cwd], { stdio: "inherit", env: editorEnv, detached: true });
|
|
18719
18696
|
code.on("error", (err) => {
|
|
18720
18697
|
process.stderr.write(`[kody serve] failed to launch VS Code: ${err.message}
|
|
18721
18698
|
`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.216",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|