@kody-ade/kody-engine 0.4.308 → 0.4.310
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 +208 -22
- 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.310",
|
|
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",
|
|
@@ -6009,27 +6009,30 @@ function resolveLitellmTimeoutMs() {
|
|
|
6009
6009
|
function generateLitellmConfigYaml(model) {
|
|
6010
6010
|
const apiKeyVar = model.apiKeyEnvVar ?? providerApiKeyEnvVar(model.provider);
|
|
6011
6011
|
const litellmProvider = model.litellmProvider ?? model.provider;
|
|
6012
|
-
const
|
|
6012
|
+
const modelGroups = litellmModelGroups(model);
|
|
6013
6013
|
const providerParams = model.baseURL ? [["api_base", model.baseURL]] : [];
|
|
6014
|
-
|
|
6015
|
-
"model_list:",
|
|
6014
|
+
const modelEntries = modelGroups.flatMap((modelGroup) => [
|
|
6016
6015
|
` - model_name: ${modelGroup}`,
|
|
6017
6016
|
` litellm_params:`,
|
|
6018
6017
|
` model: ${litellmProvider}/${model.model}`,
|
|
6019
6018
|
` api_key: os.environ/${apiKeyVar}`,
|
|
6020
|
-
...providerParams.map(([key, value]) => ` ${key}: ${value}`)
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
" drop_params: true",
|
|
6024
|
-
""
|
|
6025
|
-
].join("\n");
|
|
6019
|
+
...providerParams.map(([key, value]) => ` ${key}: ${value}`)
|
|
6020
|
+
]);
|
|
6021
|
+
return ["model_list:", ...modelEntries, "", "litellm_settings:", " drop_params: true", ""].join("\n");
|
|
6026
6022
|
}
|
|
6027
|
-
|
|
6023
|
+
function litellmModelGroups(model) {
|
|
6024
|
+
const primary = litellmModelGroup(model);
|
|
6025
|
+
return Array.from(/* @__PURE__ */ new Set([primary, ...CLAUDE_CODE_PROXY_MODEL_ALIASES]));
|
|
6026
|
+
}
|
|
6027
|
+
async function litellmServesModels(url, modelGroups) {
|
|
6028
6028
|
try {
|
|
6029
6029
|
const response = await fetch(`${url.replace(/\/+$/, "")}/v1/models`, { signal: AbortSignal.timeout(3e3) });
|
|
6030
6030
|
if (!response.ok) return false;
|
|
6031
6031
|
const payload = await response.json();
|
|
6032
|
-
|
|
6032
|
+
const served = new Set(
|
|
6033
|
+
(payload.data ?? []).map((entry) => entry.id).filter((id) => typeof id === "string")
|
|
6034
|
+
);
|
|
6035
|
+
return modelGroups.every((modelGroup) => served.has(modelGroup));
|
|
6033
6036
|
} catch {
|
|
6034
6037
|
return false;
|
|
6035
6038
|
}
|
|
@@ -6086,7 +6089,7 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
|
|
|
6086
6089
|
if (!needsLitellmProxy(model)) return null;
|
|
6087
6090
|
const cmd = resolveLitellmCommand();
|
|
6088
6091
|
let activeUrl = url.replace(/\/+$/, "");
|
|
6089
|
-
const
|
|
6092
|
+
const modelGroups = litellmModelGroups(model);
|
|
6090
6093
|
const childEnv = stripBlockingEnv({ ...process.env, ...readDotenvApiKeys(projectDir) });
|
|
6091
6094
|
let child;
|
|
6092
6095
|
let logPath;
|
|
@@ -6150,13 +6153,13 @@ ${tail}
|
|
|
6150
6153
|
};
|
|
6151
6154
|
const isHealthy = () => checkLitellmHealth(activeUrl);
|
|
6152
6155
|
if (await checkLitellmHealth(activeUrl)) {
|
|
6153
|
-
if (await
|
|
6156
|
+
if (await litellmServesModels(activeUrl, modelGroups)) {
|
|
6154
6157
|
return { url: activeUrl, kill: killChild, isHealthy, ensureHealthy };
|
|
6155
6158
|
}
|
|
6156
6159
|
const staleUrl = activeUrl;
|
|
6157
6160
|
activeUrl = await nextAvailableLitellmUrl(activeUrl);
|
|
6158
6161
|
process.stderr.write(
|
|
6159
|
-
`[kody litellm] existing proxy at ${staleUrl} does not serve ${
|
|
6162
|
+
`[kody litellm] existing proxy at ${staleUrl} does not serve ${modelGroups.join(", ")}; starting a separate proxy at ${activeUrl}
|
|
6160
6163
|
`
|
|
6161
6164
|
);
|
|
6162
6165
|
}
|
|
@@ -6220,13 +6223,14 @@ function stripBlockingEnv(env) {
|
|
|
6220
6223
|
delete out.AI_BASE_URL;
|
|
6221
6224
|
return out;
|
|
6222
6225
|
}
|
|
6223
|
-
var DEFAULT_LITELLM_STARTUP_TIMEOUT_SEC, LITELLM_HEALTH_POLL_INTERVAL_MS;
|
|
6226
|
+
var DEFAULT_LITELLM_STARTUP_TIMEOUT_SEC, LITELLM_HEALTH_POLL_INTERVAL_MS, CLAUDE_CODE_PROXY_MODEL_ALIASES;
|
|
6224
6227
|
var init_litellm = __esm({
|
|
6225
6228
|
"src/litellm.ts"() {
|
|
6226
6229
|
"use strict";
|
|
6227
6230
|
init_config();
|
|
6228
6231
|
DEFAULT_LITELLM_STARTUP_TIMEOUT_SEC = 150;
|
|
6229
6232
|
LITELLM_HEALTH_POLL_INTERVAL_MS = 2e3;
|
|
6233
|
+
CLAUDE_CODE_PROXY_MODEL_ALIASES = ["claude-haiku-4-5-20251001", "haiku"];
|
|
6230
6234
|
}
|
|
6231
6235
|
});
|
|
6232
6236
|
|
|
@@ -7052,16 +7056,76 @@ function enrichGoalRunLogEvent(config, data, logPath, event) {
|
|
|
7052
7056
|
const stateRepo = stateRepoContext(config, event.goalId, logPath);
|
|
7053
7057
|
const trigger = event.trigger ?? triggerContext();
|
|
7054
7058
|
const job = event.job ?? jobContext(data);
|
|
7055
|
-
|
|
7059
|
+
const run = event.run ?? runContext(data);
|
|
7060
|
+
const links = event.links ?? linkContext(stateRepo);
|
|
7061
|
+
const enriched = pruneUndefined({
|
|
7056
7062
|
...event,
|
|
7057
|
-
run
|
|
7063
|
+
run,
|
|
7058
7064
|
repo: event.repo ?? repoContext(config),
|
|
7059
7065
|
stateRepo: event.stateRepo ?? stateRepo,
|
|
7060
7066
|
trigger,
|
|
7061
7067
|
job,
|
|
7062
7068
|
dispatchContext: event.dispatchContext ?? dispatchContext(event, trigger, job),
|
|
7063
|
-
links
|
|
7069
|
+
links
|
|
7070
|
+
});
|
|
7071
|
+
enriched.trace = event.trace ?? goalRunTrace(enriched);
|
|
7072
|
+
return enriched;
|
|
7073
|
+
}
|
|
7074
|
+
function goalRunTrace(event) {
|
|
7075
|
+
const run = recordValue2(event.run);
|
|
7076
|
+
const trigger = recordValue2(event.trigger);
|
|
7077
|
+
const goal = recordValue2(event.goal);
|
|
7078
|
+
const inspection = recordValue2(event.inspection);
|
|
7079
|
+
const capabilityOutput = recordValue2(inspection?.capabilityOutput);
|
|
7080
|
+
return pruneUndefined({
|
|
7081
|
+
version: 1,
|
|
7082
|
+
runId: stringValue2(run?.id) ?? void 0,
|
|
7083
|
+
workflowRunId: stringValue2(run?.githubRunId) ?? void 0,
|
|
7084
|
+
triggerKind: stringValue2(trigger?.kind) ?? void 0,
|
|
7085
|
+
source: event.source,
|
|
7086
|
+
event: event.event,
|
|
7087
|
+
goal: pruneUndefined({
|
|
7088
|
+
id: event.goalId,
|
|
7089
|
+
type: event.goalType ?? stringValue2(goal?.type) ?? void 0,
|
|
7090
|
+
state: event.goalState ?? stringValue2(goal?.state) ?? void 0,
|
|
7091
|
+
stage: event.stage ?? stringValue2(goal?.stage) ?? void 0
|
|
7092
|
+
}),
|
|
7093
|
+
evidence: goalTraceEvidence(event, goal, inspection),
|
|
7094
|
+
capability: event.dispatch ?? capabilityDispatchFromOutput(capabilityOutput),
|
|
7095
|
+
result: goalTraceResult(event, capabilityOutput),
|
|
7096
|
+
change: event.change,
|
|
7097
|
+
links: event.links
|
|
7098
|
+
});
|
|
7099
|
+
}
|
|
7100
|
+
function goalTraceEvidence(event, goal, inspection) {
|
|
7101
|
+
const expectedEvidence = recordValue2(inspection?.expectedEvidence);
|
|
7102
|
+
const out = pruneUndefined({
|
|
7103
|
+
current: event.evidence,
|
|
7104
|
+
required: stringArrayValue(goal?.requiredEvidence) ?? stringArrayValue(inspection?.requiredEvidence) ?? void 0,
|
|
7105
|
+
satisfied: stringArrayValue(goal?.satisfiedEvidence) ?? stringArrayValue(inspection?.satisfiedEvidence) ?? void 0,
|
|
7106
|
+
missing: stringArrayValue(goal?.missingEvidence) ?? stringArrayValue(inspection?.missingEvidence) ?? stringArrayValue(expectedEvidence?.missingBefore) ?? void 0,
|
|
7107
|
+
pending: stringValue2(goal?.pendingEvidence) ?? stringValue2(inspection?.pendingEvidence) ?? stringValue2(expectedEvidence?.pendingBefore) ?? void 0,
|
|
7108
|
+
values: event.evidenceValues
|
|
7109
|
+
});
|
|
7110
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
7111
|
+
}
|
|
7112
|
+
function capabilityDispatchFromOutput(output) {
|
|
7113
|
+
if (!output) return void 0;
|
|
7114
|
+
const dispatch2 = pruneUndefined({
|
|
7115
|
+
capability: stringValue2(output.capability) ?? void 0,
|
|
7116
|
+
executable: stringValue2(output.executable) ?? void 0,
|
|
7117
|
+
action: stringValue2(output.action) ?? void 0
|
|
7064
7118
|
});
|
|
7119
|
+
return Object.keys(dispatch2).length > 0 ? dispatch2 : void 0;
|
|
7120
|
+
}
|
|
7121
|
+
function goalTraceResult(event, capabilityOutput) {
|
|
7122
|
+
const result = pruneUndefined({
|
|
7123
|
+
status: event.status ?? stringValue2(capabilityOutput?.status) ?? void 0,
|
|
7124
|
+
summary: event.reason ?? stringValue2(capabilityOutput?.summary) ?? void 0,
|
|
7125
|
+
blockers: event.inspection ? stringArrayValue(capabilityOutput?.blockers) ?? void 0 : void 0,
|
|
7126
|
+
artifacts: event.artifacts
|
|
7127
|
+
});
|
|
7128
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
7065
7129
|
}
|
|
7066
7130
|
function runContext(data) {
|
|
7067
7131
|
const runId = process.env.GITHUB_RUN_ID?.trim();
|
|
@@ -12218,6 +12282,126 @@ var init_ensurePr = __esm({
|
|
|
12218
12282
|
}
|
|
12219
12283
|
});
|
|
12220
12284
|
|
|
12285
|
+
// src/agencyBoundaryEval.ts
|
|
12286
|
+
function evaluateAgencyBoundaries(input) {
|
|
12287
|
+
const findings = [];
|
|
12288
|
+
const results = input.results ?? [];
|
|
12289
|
+
findings.push(evaluateObserveBoundary(input.capabilityKind, results));
|
|
12290
|
+
findings.push(evaluateVerifyBoundary(input.capabilityKind, results));
|
|
12291
|
+
findings.push(evaluateGoalOwnershipBoundary(results));
|
|
12292
|
+
return {
|
|
12293
|
+
version: 1,
|
|
12294
|
+
status: findings.some((finding) => finding.status === "fail") ? "fail" : "pass",
|
|
12295
|
+
...input.capability ? { capability: input.capability } : {},
|
|
12296
|
+
...input.capabilityKind ? { capabilityKind: input.capabilityKind } : {},
|
|
12297
|
+
findings
|
|
12298
|
+
};
|
|
12299
|
+
}
|
|
12300
|
+
function evaluateObserveBoundary(capabilityKind, results) {
|
|
12301
|
+
if (capabilityKind !== "observe") {
|
|
12302
|
+
return pass("observe-does-not-act", "capability is not observe", { capabilityKind });
|
|
12303
|
+
}
|
|
12304
|
+
const actionResults = results.filter(resultLooksLikeAction);
|
|
12305
|
+
if (actionResults.length === 0) {
|
|
12306
|
+
return pass("observe-does-not-act", "observe capability reported facts without action output", {
|
|
12307
|
+
resultCount: results.length
|
|
12308
|
+
});
|
|
12309
|
+
}
|
|
12310
|
+
return fail2("observe-does-not-act", "observe capability returned action-shaped output", {
|
|
12311
|
+
resultCount: results.length,
|
|
12312
|
+
actionResults: actionResults.map(resultSummary)
|
|
12313
|
+
});
|
|
12314
|
+
}
|
|
12315
|
+
function evaluateVerifyBoundary(capabilityKind, results) {
|
|
12316
|
+
if (capabilityKind !== "verify") {
|
|
12317
|
+
return pass("verify-does-not-fix", "capability is not verify", { capabilityKind });
|
|
12318
|
+
}
|
|
12319
|
+
const actionResults = results.filter(resultLooksLikeAction);
|
|
12320
|
+
if (actionResults.length === 0) {
|
|
12321
|
+
return pass("verify-does-not-fix", "verify capability returned verdict evidence without action output", {
|
|
12322
|
+
resultCount: results.length
|
|
12323
|
+
});
|
|
12324
|
+
}
|
|
12325
|
+
return fail2("verify-does-not-fix", "verify capability returned fix/change output", {
|
|
12326
|
+
resultCount: results.length,
|
|
12327
|
+
actionResults: actionResults.map(resultSummary)
|
|
12328
|
+
});
|
|
12329
|
+
}
|
|
12330
|
+
function evaluateGoalOwnershipBoundary(results) {
|
|
12331
|
+
const targetBearing = results.filter((result) => result.target?.type === "goal");
|
|
12332
|
+
if (targetBearing.length === 0) {
|
|
12333
|
+
return pass("capability-does-not-own-goal-progress", "capability output is parent-neutral", {
|
|
12334
|
+
resultCount: results.length
|
|
12335
|
+
});
|
|
12336
|
+
}
|
|
12337
|
+
return fail2("capability-does-not-own-goal-progress", "capability output names a goal target", {
|
|
12338
|
+
resultCount: results.length,
|
|
12339
|
+
targetBearingResults: targetBearing.map(resultSummary)
|
|
12340
|
+
});
|
|
12341
|
+
}
|
|
12342
|
+
function resultLooksLikeAction(result) {
|
|
12343
|
+
if (result.status === "changed") return true;
|
|
12344
|
+
return Object.keys(result.facts).some((key) => ACTION_FACT_KEYS.has(key));
|
|
12345
|
+
}
|
|
12346
|
+
function resultSummary(result) {
|
|
12347
|
+
return {
|
|
12348
|
+
status: result.status,
|
|
12349
|
+
summary: result.summary,
|
|
12350
|
+
target: result.target,
|
|
12351
|
+
actionFactKeys: Object.keys(result.facts).filter((key) => ACTION_FACT_KEYS.has(key))
|
|
12352
|
+
};
|
|
12353
|
+
}
|
|
12354
|
+
function pass(rule, message, evidence) {
|
|
12355
|
+
return { rule, status: "pass", message, evidence };
|
|
12356
|
+
}
|
|
12357
|
+
function fail2(rule, message, evidence) {
|
|
12358
|
+
return { rule, status: "fail", message, evidence };
|
|
12359
|
+
}
|
|
12360
|
+
var ACTION_FACT_KEYS;
|
|
12361
|
+
var init_agencyBoundaryEval = __esm({
|
|
12362
|
+
"src/agencyBoundaryEval.ts"() {
|
|
12363
|
+
"use strict";
|
|
12364
|
+
ACTION_FACT_KEYS = /* @__PURE__ */ new Set(["changedResources", "createdResources", "actionResult"]);
|
|
12365
|
+
}
|
|
12366
|
+
});
|
|
12367
|
+
|
|
12368
|
+
// src/scripts/evaluateAgencyBoundaries.ts
|
|
12369
|
+
function collectResults2(raw, agentResult) {
|
|
12370
|
+
const out = [];
|
|
12371
|
+
if (Array.isArray(raw)) {
|
|
12372
|
+
for (const item of raw) {
|
|
12373
|
+
const parsed = parseCapabilityResult(item);
|
|
12374
|
+
if (parsed) out.push(parsed);
|
|
12375
|
+
}
|
|
12376
|
+
}
|
|
12377
|
+
if (agentResult?.finalText) out.push(...parseCapabilityResultsFromText(agentResult.finalText));
|
|
12378
|
+
return out;
|
|
12379
|
+
}
|
|
12380
|
+
var evaluateAgencyBoundariesScript;
|
|
12381
|
+
var init_evaluateAgencyBoundaries = __esm({
|
|
12382
|
+
"src/scripts/evaluateAgencyBoundaries.ts"() {
|
|
12383
|
+
"use strict";
|
|
12384
|
+
init_agencyBoundaryEval();
|
|
12385
|
+
init_capabilityResult();
|
|
12386
|
+
evaluateAgencyBoundariesScript = async (ctx, profile, agentResult) => {
|
|
12387
|
+
const results = collectResults2(ctx.data.capabilityResults ?? ctx.data.dutyResults, agentResult);
|
|
12388
|
+
const evalResult = evaluateAgencyBoundaries({
|
|
12389
|
+
capability: profile.name,
|
|
12390
|
+
capabilityKind: profile.capabilityKind,
|
|
12391
|
+
results
|
|
12392
|
+
});
|
|
12393
|
+
ctx.data.agencyBoundaryEval = evalResult;
|
|
12394
|
+
process.stdout.write(`KODY_AGENCY_BOUNDARY_EVAL=${JSON.stringify(evalResult)}
|
|
12395
|
+
`);
|
|
12396
|
+
if (evalResult.status === "fail") {
|
|
12397
|
+
const failed = evalResult.findings.filter((finding) => finding.status === "fail").map((finding) => finding.rule);
|
|
12398
|
+
ctx.output.exitCode = ctx.output.exitCode === 0 ? 99 : ctx.output.exitCode;
|
|
12399
|
+
ctx.output.reason = ctx.output.reason ? `${ctx.output.reason}; agency boundary eval failed: ${failed.join(", ")}` : `agency boundary eval failed: ${failed.join(", ")}`;
|
|
12400
|
+
}
|
|
12401
|
+
};
|
|
12402
|
+
}
|
|
12403
|
+
});
|
|
12404
|
+
|
|
12221
12405
|
// src/scripts/failOnceTaskJob.ts
|
|
12222
12406
|
var failOnceTaskJob;
|
|
12223
12407
|
var init_failOnceTaskJob = __esm({
|
|
@@ -14088,7 +14272,7 @@ var init_markFlowSuccess = __esm({
|
|
|
14088
14272
|
});
|
|
14089
14273
|
|
|
14090
14274
|
// src/goal/operations.ts
|
|
14091
|
-
function
|
|
14275
|
+
function fail3(err) {
|
|
14092
14276
|
if (err instanceof Error) {
|
|
14093
14277
|
const lines = err.message.split("\n").filter(Boolean);
|
|
14094
14278
|
return { ok: false, error: lines[0] ?? err.message };
|
|
@@ -14100,7 +14284,7 @@ function commentOnIssue(issueNumber, body, cwd) {
|
|
|
14100
14284
|
gh(["issue", "comment", String(issueNumber), "--body", body], { cwd });
|
|
14101
14285
|
return { ok: true };
|
|
14102
14286
|
} catch (err) {
|
|
14103
|
-
return
|
|
14287
|
+
return fail3(err);
|
|
14104
14288
|
}
|
|
14105
14289
|
}
|
|
14106
14290
|
function mergePrSquash(prNumber, cwd) {
|
|
@@ -14108,7 +14292,7 @@ function mergePrSquash(prNumber, cwd) {
|
|
|
14108
14292
|
gh(["pr", "merge", String(prNumber), "--squash", "--delete-branch"], { cwd });
|
|
14109
14293
|
return { ok: true };
|
|
14110
14294
|
} catch (err) {
|
|
14111
|
-
return
|
|
14295
|
+
return fail3(err);
|
|
14112
14296
|
}
|
|
14113
14297
|
}
|
|
14114
14298
|
var init_operations = __esm({
|
|
@@ -17988,6 +18172,7 @@ var init_scripts = __esm({
|
|
|
17988
18172
|
init_dispatchClassified();
|
|
17989
18173
|
init_dispatchNextTaskJob();
|
|
17990
18174
|
init_ensurePr();
|
|
18175
|
+
init_evaluateAgencyBoundaries();
|
|
17991
18176
|
init_failOnceTaskJob();
|
|
17992
18177
|
init_finalizeTerminal();
|
|
17993
18178
|
init_finishFlow();
|
|
@@ -18132,6 +18317,7 @@ var init_scripts = __esm({
|
|
|
18132
18317
|
stageMergeConflicts,
|
|
18133
18318
|
commitAndPush: commitAndPush2,
|
|
18134
18319
|
ensurePr: ensurePr2,
|
|
18320
|
+
evaluateAgencyBoundaries: evaluateAgencyBoundariesScript,
|
|
18135
18321
|
postAgentComment,
|
|
18136
18322
|
postIssueComment: postIssueComment2,
|
|
18137
18323
|
postPlanComment,
|
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.310",
|
|
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",
|