@kybernesis/create 0.14.2 → 0.14.3
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/agent-limits.d.ts +30 -0
- package/dist/agent-limits.js +86 -0
- package/dist/doctor.d.ts +2 -0
- package/dist/doctor.js +30 -6
- package/dist/templates.js +2 -0
- package/dist/upgrade.d.ts +2 -0
- package/dist/upgrade.js +30 -1
- package/package.json +1 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Eve 0.49's root default when the compiled config omits the policy. */
|
|
2
|
+
export declare const CERTIFIED_INHERITED_MAX_INPUT_TOKENS_PER_SESSION = 40000000;
|
|
3
|
+
export type AgentInputLimit = {
|
|
4
|
+
kind: "explicit-numeric";
|
|
5
|
+
value: number;
|
|
6
|
+
} | {
|
|
7
|
+
kind: "explicit-uncapped";
|
|
8
|
+
} | {
|
|
9
|
+
kind: "inherited";
|
|
10
|
+
value: typeof CERTIFIED_INHERITED_MAX_INPUT_TOKENS_PER_SESSION;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "unresolved";
|
|
13
|
+
reason: string;
|
|
14
|
+
};
|
|
15
|
+
export interface EveInfoInspection {
|
|
16
|
+
diagnostics: {
|
|
17
|
+
errors: number;
|
|
18
|
+
warnings: number;
|
|
19
|
+
} | null;
|
|
20
|
+
status: string | null;
|
|
21
|
+
limit: AgentInputLimit;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Read the effective root policy from Eve's compiled artifact, never from
|
|
25
|
+
* authored TypeScript. The 40M fallback is certified only when that artifact
|
|
26
|
+
* truly omits maxInputTokensPerSession.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseEveInfoInspection(output: string, readText?: (path: string) => string): EveInfoInspection;
|
|
29
|
+
/** Compile once through Eve's structured info contract and inspect its artifact. */
|
|
30
|
+
export declare function inspectEveAgent(cwd: string, env?: Record<string, string>): EveInfoInspection | null;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { capture } from "./util.js";
|
|
3
|
+
/** Eve 0.49's root default when the compiled config omits the policy. */
|
|
4
|
+
export const CERTIFIED_INHERITED_MAX_INPUT_TOKENS_PER_SESSION = 40_000_000;
|
|
5
|
+
/**
|
|
6
|
+
* Read the effective root policy from Eve's compiled artifact, never from
|
|
7
|
+
* authored TypeScript. The 40M fallback is certified only when that artifact
|
|
8
|
+
* truly omits maxInputTokensPerSession.
|
|
9
|
+
*/
|
|
10
|
+
export function parseEveInfoInspection(output, readText = (path) => readFileSync(path, "utf8")) {
|
|
11
|
+
let info;
|
|
12
|
+
try {
|
|
13
|
+
info = JSON.parse(output);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return unresolved(`eve info --json was not valid JSON: ${error.message}`);
|
|
17
|
+
}
|
|
18
|
+
const diagnostics = parseDiagnostics(info.diagnostics);
|
|
19
|
+
const status = typeof info.status === "string" ? info.status : null;
|
|
20
|
+
const manifestPath = info.artifacts && typeof info.artifacts.compiledManifest === "string"
|
|
21
|
+
? info.artifacts.compiledManifest
|
|
22
|
+
: null;
|
|
23
|
+
if (!manifestPath) {
|
|
24
|
+
return { diagnostics, status, limit: { kind: "unresolved", reason: "compiled manifest path was unavailable" } };
|
|
25
|
+
}
|
|
26
|
+
let manifest;
|
|
27
|
+
try {
|
|
28
|
+
manifest = JSON.parse(readText(manifestPath));
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return {
|
|
32
|
+
diagnostics,
|
|
33
|
+
status,
|
|
34
|
+
limit: { kind: "unresolved", reason: `compiled manifest could not be read: ${error.message}` },
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (!isRecord(manifest) || !isRecord(manifest.config)) {
|
|
38
|
+
return { diagnostics, status, limit: { kind: "unresolved", reason: "compiled root config was unavailable" } };
|
|
39
|
+
}
|
|
40
|
+
const limits = manifest.config.limits;
|
|
41
|
+
if (limits === undefined) {
|
|
42
|
+
return inherited(diagnostics, status);
|
|
43
|
+
}
|
|
44
|
+
if (!isRecord(limits)) {
|
|
45
|
+
return { diagnostics, status, limit: { kind: "unresolved", reason: "compiled root limits were malformed" } };
|
|
46
|
+
}
|
|
47
|
+
if (!Object.hasOwn(limits, "maxInputTokensPerSession")) {
|
|
48
|
+
return inherited(diagnostics, status);
|
|
49
|
+
}
|
|
50
|
+
const value = limits.maxInputTokensPerSession;
|
|
51
|
+
if (value === false)
|
|
52
|
+
return { diagnostics, status, limit: { kind: "explicit-uncapped" } };
|
|
53
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
54
|
+
return { diagnostics, status, limit: { kind: "explicit-numeric", value } };
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
diagnostics,
|
|
58
|
+
status,
|
|
59
|
+
limit: { kind: "unresolved", reason: "compiled maxInputTokensPerSession was neither a positive number nor false" },
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** Compile once through Eve's structured info contract and inspect its artifact. */
|
|
63
|
+
export function inspectEveAgent(cwd, env) {
|
|
64
|
+
const output = capture("npx", ["eve", "info", "--json"], cwd, env);
|
|
65
|
+
return output === null ? null : parseEveInfoInspection(output);
|
|
66
|
+
}
|
|
67
|
+
function parseDiagnostics(value) {
|
|
68
|
+
if (!isRecord(value))
|
|
69
|
+
return null;
|
|
70
|
+
return typeof value.errors === "number" && typeof value.warnings === "number"
|
|
71
|
+
? { errors: value.errors, warnings: value.warnings }
|
|
72
|
+
: null;
|
|
73
|
+
}
|
|
74
|
+
function inherited(diagnostics, status) {
|
|
75
|
+
return {
|
|
76
|
+
diagnostics,
|
|
77
|
+
status,
|
|
78
|
+
limit: { kind: "inherited", value: CERTIFIED_INHERITED_MAX_INPUT_TOKENS_PER_SESSION },
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function unresolved(reason) {
|
|
82
|
+
return { diagnostics: null, status: null, limit: { kind: "unresolved", reason } };
|
|
83
|
+
}
|
|
84
|
+
function isRecord(value) {
|
|
85
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
86
|
+
}
|
package/dist/doctor.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AgentInputLimit } from "./agent-limits.js";
|
|
1
2
|
type Verdict = "pass" | "warn" | "fail";
|
|
2
3
|
export interface Check {
|
|
3
4
|
verdict: Verdict;
|
|
@@ -16,6 +17,7 @@ export interface DockerTemplateInspection {
|
|
|
16
17
|
}[];
|
|
17
18
|
}
|
|
18
19
|
export declare function dockerTemplateDoctorChecks(result: DockerTemplateInspection): Check[];
|
|
20
|
+
export declare function agentInputLimitDoctorCheck(limit: AgentInputLimit): Check;
|
|
19
21
|
/**
|
|
20
22
|
* The inspector lives in @kybernesis/exe, next to the runtime that owns the
|
|
21
23
|
* templates; create already resolves that package's scripts out of
|
package/dist/doctor.js
CHANGED
|
@@ -3,6 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { bold, capture, dim, green, parseEnv, red, yellow } from "./util.js";
|
|
5
5
|
import { diagnoseManageRestart, findMatchingAgentServiceUnit } from "./systemd.js";
|
|
6
|
+
import { inspectEveAgent } from "./agent-limits.js";
|
|
6
7
|
const MARK = {
|
|
7
8
|
pass: green("✓"),
|
|
8
9
|
warn: yellow("!"),
|
|
@@ -30,6 +31,26 @@ export function dockerTemplateDoctorChecks(result) {
|
|
|
30
31
|
detail: issue.detail,
|
|
31
32
|
}));
|
|
32
33
|
}
|
|
34
|
+
export function agentInputLimitDoctorCheck(limit) {
|
|
35
|
+
switch (limit.kind) {
|
|
36
|
+
case "explicit-numeric":
|
|
37
|
+
return { verdict: "pass", label: `Eve max input tokens/session: ${limit.value.toLocaleString("en-US")} (explicit)` };
|
|
38
|
+
case "explicit-uncapped":
|
|
39
|
+
return { verdict: "pass", label: "Eve max input tokens/session: uncapped (explicit)" };
|
|
40
|
+
case "inherited":
|
|
41
|
+
return {
|
|
42
|
+
verdict: "warn",
|
|
43
|
+
label: `Eve max input tokens/session: ${limit.value.toLocaleString("en-US")} (inherited default)`,
|
|
44
|
+
detail: "set limits.maxInputTokensPerSession explicitly in the root agent; use false only when the host policy intentionally permits an uncapped session",
|
|
45
|
+
};
|
|
46
|
+
case "unresolved":
|
|
47
|
+
return {
|
|
48
|
+
verdict: "warn",
|
|
49
|
+
label: "Eve max input tokens/session: unresolved",
|
|
50
|
+
detail: limit.reason,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
33
54
|
/**
|
|
34
55
|
* The inspector lives in @kybernesis/exe, next to the runtime that owns the
|
|
35
56
|
* templates; create already resolves that package's scripts out of
|
|
@@ -481,16 +502,19 @@ export async function doctor() {
|
|
|
481
502
|
* `env` here is the same merged view every other check reads: .env.local
|
|
482
503
|
* underneath, the real environment on top.
|
|
483
504
|
*/
|
|
484
|
-
const info =
|
|
505
|
+
const info = inspectEveAgent(cwd, env);
|
|
485
506
|
if (info === null) {
|
|
486
|
-
add("fail", "eve info failed", "run: set -a && . ./.env.local && set +a && npx eve info — the agent's own error is in that output");
|
|
507
|
+
add("fail", "eve info failed", "run: set -a && . ./.env.local && set +a && npx eve info --json — the agent's own error is in that output");
|
|
508
|
+
add("warn", "Eve max input tokens/session: unresolved", "eve info failed before the compiled root policy could be inspected");
|
|
487
509
|
}
|
|
488
510
|
else {
|
|
489
|
-
const diag =
|
|
490
|
-
if (diag && diag
|
|
491
|
-
add("pass", `eve discovery clean (${diag
|
|
511
|
+
const diag = info.diagnostics;
|
|
512
|
+
if (diag && diag.errors === 0)
|
|
513
|
+
add("pass", `eve discovery clean (${diag.warnings} warnings)`);
|
|
492
514
|
else
|
|
493
|
-
add("fail", `eve discovery: ${diag ? `${diag
|
|
515
|
+
add("fail", `eve discovery: ${diag ? `${diag.errors} errors` : "unparsed"}`, "npx eve info --json");
|
|
516
|
+
const limitCheck = agentInputLimitDoctorCheck(info.limit);
|
|
517
|
+
add(limitCheck.verdict, limitCheck.label, limitCheck.detail);
|
|
494
518
|
}
|
|
495
519
|
const portBusy = capture("lsof", ["-ti", ":2000"]);
|
|
496
520
|
if (portBusy && portBusy.trim())
|
package/dist/templates.js
CHANGED
|
@@ -366,6 +366,8 @@ import { exeModel } from "@kybernesis/exe";
|
|
|
366
366
|
export default defineAgent({
|
|
367
367
|
model: exeModel({ model: process.env.EXE_MODEL ?? ${JSON.stringify(model)}, createOpenAI }),
|
|
368
368
|
modelContextWindowTokens: 200_000,
|
|
369
|
+
// This long-lived self-hosted process has no metered platform session ceiling.
|
|
370
|
+
limits: { maxInputTokensPerSession: false },
|
|
369
371
|
});
|
|
370
372
|
`;
|
|
371
373
|
}
|
package/dist/upgrade.d.ts
CHANGED
package/dist/upgrade.js
CHANGED
|
@@ -5,7 +5,8 @@ import { reconcileHostArtifact } from "./host-artifacts.js";
|
|
|
5
5
|
import { repairManageRestart } from "./systemd.js";
|
|
6
6
|
import { repairTerminalSandboxCleanupHooks } from "./sandbox-cleanup.js";
|
|
7
7
|
import { repairRemovedDefaultTools as repairRemovedDefaultTools_ } from "./removed-default-tools.js";
|
|
8
|
-
import { EVE_VERSION, bold, capture, dim, green, red, run, yellow } from "./util.js";
|
|
8
|
+
import { EVE_VERSION, bold, capture, dim, green, parseEnv, red, run, yellow } from "./util.js";
|
|
9
|
+
import { inspectEveAgent } from "./agent-limits.js";
|
|
9
10
|
/**
|
|
10
11
|
* Which packages to upgrade: every `@kybernesis/*` this agent depends on.
|
|
11
12
|
*
|
|
@@ -61,6 +62,32 @@ function warnIfStale() {
|
|
|
61
62
|
`compiled into this tool, so an old kyb reports an old pin as current.`);
|
|
62
63
|
console.log(` ${dim("npm install -g @kybernesis/create@latest")}\n`);
|
|
63
64
|
}
|
|
65
|
+
export function agentInputLimitUpgradeMessage(limit) {
|
|
66
|
+
switch (limit.kind) {
|
|
67
|
+
case "explicit-numeric":
|
|
68
|
+
return `Eve max input tokens/session: ${limit.value.toLocaleString("en-US")} (explicit; unchanged)`;
|
|
69
|
+
case "explicit-uncapped":
|
|
70
|
+
return "Eve max input tokens/session: uncapped (explicit; unchanged)";
|
|
71
|
+
case "inherited":
|
|
72
|
+
return `Eve max input tokens/session: ${limit.value.toLocaleString("en-US")} inherited — set limits.maxInputTokensPerSession explicitly in agent/agent.ts; upgrade will not rewrite authored source`;
|
|
73
|
+
case "unresolved":
|
|
74
|
+
return `Eve max input tokens/session: unresolved (${limit.reason}); authored source was not changed`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function reportAgentInputLimit(cwd) {
|
|
78
|
+
const envPath = join(cwd, ".env.local");
|
|
79
|
+
const env = {
|
|
80
|
+
...(existsSync(envPath) ? parseEnv(readFileSync(envPath, "utf8")) : {}),
|
|
81
|
+
...process.env,
|
|
82
|
+
};
|
|
83
|
+
const inspection = inspectEveAgent(cwd, env);
|
|
84
|
+
const limit = inspection?.limit ?? {
|
|
85
|
+
kind: "unresolved",
|
|
86
|
+
reason: "eve info --json failed",
|
|
87
|
+
};
|
|
88
|
+
const marker = limit.kind === "inherited" || limit.kind === "unresolved" ? yellow("!") : green("✓");
|
|
89
|
+
console.log(` ${marker} ${agentInputLimitUpgradeMessage(limit)}`);
|
|
90
|
+
}
|
|
64
91
|
/**
|
|
65
92
|
* Raise the local queue's delivery timeouts on an agent that already exists.
|
|
66
93
|
*
|
|
@@ -309,6 +336,8 @@ export async function upgrade(skipEval) {
|
|
|
309
336
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
310
337
|
console.log(bold("\nkyb upgrade — checking @kybernesis/* and eve against npm\n"));
|
|
311
338
|
warnIfStale();
|
|
339
|
+
// Read-only: report the compiled effective policy, never rewrite agent/agent.ts.
|
|
340
|
+
reportAgentInputLimit(cwd);
|
|
312
341
|
// Env-only, so it is safe before anything is installed.
|
|
313
342
|
repairLocalQueueTimeouts(cwd, deps);
|
|
314
343
|
const toUpgrade = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kybernesis/create",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.3",
|
|
4
4
|
"description": "The Kybernesis agent scaffolder and FDE toolkit: one command to a governed, remembering, multiplayer, self-testing eve agent — plus doctor and upgrade.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|