@kybernesis/create 0.24.1 → 0.24.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/exe-claude-route.d.ts +19 -0
- package/dist/exe-claude-route.js +69 -0
- package/dist/upgrade.js +32 -1
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Give every `exeModel({ …, createOpenAI })` call in an agent the Anthropic
|
|
3
|
+
* factory too.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Claude on the exe gateway is served on its Messages API, not the OpenAI one.
|
|
7
|
+
* Older scaffolds wrote subagents such as the builder with only `createOpenAI`
|
|
8
|
+
* and a Claude default (`anthropic/claude-sonnet-5`). That never had a working
|
|
9
|
+
* route, and since exe 0.17 `exeModel` refuses it at load, so the agent's whole
|
|
10
|
+
* eval suite stops before the first case and an update is rolled back for a
|
|
11
|
+
* file nobody touched. Passing `createAnthropic` as well is harmless for a
|
|
12
|
+
* non-Claude id (exeModel only uses it for `anthropic/…`), so the repair is
|
|
13
|
+
* unconditional for any call that lacks it.
|
|
14
|
+
*
|
|
15
|
+
* Returns the agent-relative paths it changed.
|
|
16
|
+
*/
|
|
17
|
+
export declare function repairExeClaudeRoute(cwd: string): string[];
|
|
18
|
+
/** The source with `createAnthropic` passed to each exeModel call that has only `createOpenAI`, and imported. */
|
|
19
|
+
export declare function withAnthropicFactory(source: string): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Give every `exeModel({ …, createOpenAI })` call in an agent the Anthropic
|
|
5
|
+
* factory too.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Claude on the exe gateway is served on its Messages API, not the OpenAI one.
|
|
9
|
+
* Older scaffolds wrote subagents such as the builder with only `createOpenAI`
|
|
10
|
+
* and a Claude default (`anthropic/claude-sonnet-5`). That never had a working
|
|
11
|
+
* route, and since exe 0.17 `exeModel` refuses it at load, so the agent's whole
|
|
12
|
+
* eval suite stops before the first case and an update is rolled back for a
|
|
13
|
+
* file nobody touched. Passing `createAnthropic` as well is harmless for a
|
|
14
|
+
* non-Claude id (exeModel only uses it for `anthropic/…`), so the repair is
|
|
15
|
+
* unconditional for any call that lacks it.
|
|
16
|
+
*
|
|
17
|
+
* Returns the agent-relative paths it changed.
|
|
18
|
+
*/
|
|
19
|
+
export function repairExeClaudeRoute(cwd) {
|
|
20
|
+
const root = join(cwd, "agent");
|
|
21
|
+
if (!existsSync(root))
|
|
22
|
+
return [];
|
|
23
|
+
const changed = [];
|
|
24
|
+
for (const file of sourceFiles(root)) {
|
|
25
|
+
const source = readFileSync(file, "utf8");
|
|
26
|
+
const next = withAnthropicFactory(source);
|
|
27
|
+
if (next === source)
|
|
28
|
+
continue;
|
|
29
|
+
writeFileSync(file, next);
|
|
30
|
+
changed.push(relative(cwd, file));
|
|
31
|
+
}
|
|
32
|
+
return changed;
|
|
33
|
+
}
|
|
34
|
+
/** The source with `createAnthropic` passed to each exeModel call that has only `createOpenAI`, and imported. */
|
|
35
|
+
export function withAnthropicFactory(source) {
|
|
36
|
+
if (!/\bexeModel\s*\(/.test(source))
|
|
37
|
+
return source;
|
|
38
|
+
let touched = false;
|
|
39
|
+
const next = source.replace(/\bexeModel\s*\(\s*\{([^{}]*)\}\s*\)/g, (call, body) => {
|
|
40
|
+
if (!/\bcreateOpenAI\b/.test(body) || /\bcreateAnthropic\b/.test(body))
|
|
41
|
+
return call;
|
|
42
|
+
touched = true;
|
|
43
|
+
return call.replace(/\bcreateOpenAI\b/, "createOpenAI, createAnthropic");
|
|
44
|
+
});
|
|
45
|
+
if (!touched)
|
|
46
|
+
return source;
|
|
47
|
+
if (/\bimport\s*\{[^}]*\bcreateAnthropic\b[^}]*\}\s*from\s*["']@ai-sdk\/anthropic["']/.test(next))
|
|
48
|
+
return next;
|
|
49
|
+
const openaiImport = /^import\s*\{[^}]*\bcreateOpenAI\b[^}]*\}\s*from\s*["']@ai-sdk\/openai["'];?[^\n]*\n/m.exec(next);
|
|
50
|
+
const line = 'import { createAnthropic } from "@ai-sdk/anthropic";\n';
|
|
51
|
+
if (openaiImport) {
|
|
52
|
+
const at = openaiImport.index + openaiImport[0].length;
|
|
53
|
+
return next.slice(0, at) + line + next.slice(at);
|
|
54
|
+
}
|
|
55
|
+
return line + next;
|
|
56
|
+
}
|
|
57
|
+
function sourceFiles(dir) {
|
|
58
|
+
const out = [];
|
|
59
|
+
for (const entry of readdirSync(dir)) {
|
|
60
|
+
if (entry === "node_modules" || entry.startsWith("."))
|
|
61
|
+
continue;
|
|
62
|
+
const full = join(dir, entry);
|
|
63
|
+
if (statSync(full).isDirectory())
|
|
64
|
+
out.push(...sourceFiles(full));
|
|
65
|
+
else if (/\.(ts|mts|js|mjs)$/.test(entry))
|
|
66
|
+
out.push(full);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
package/dist/upgrade.js
CHANGED
|
@@ -11,6 +11,7 @@ import { dockerPruneCronArtifact } from "./docker-prune-cron.js";
|
|
|
11
11
|
import { newestOnLine } from "./on-line-version.js";
|
|
12
12
|
import { findMatchingAgentServiceUnit, repairManageRestart } from "./systemd.js";
|
|
13
13
|
import { repairTerminalSandboxCleanupHooks } from "./sandbox-cleanup.js";
|
|
14
|
+
import { repairExeClaudeRoute } from "./exe-claude-route.js";
|
|
14
15
|
import { repairOptInTools, repairRemovedDefaultTools as repairRemovedDefaultTools_ } from "./removed-default-tools.js";
|
|
15
16
|
import { EVE_VERSION, bold, capture, dim, green, parseEnv, red, run, yellow } from "./util.js";
|
|
16
17
|
import { inspectEveAgent } from "./agent-limits.js";
|
|
@@ -75,6 +76,25 @@ function repairLocalQueueTimeouts(cwd, deps) {
|
|
|
75
76
|
` ${dim("slower than 30s was redelivered and its steps re-run — the agent answered twice.")}\n` +
|
|
76
77
|
` ${dim("Takes effect on the next server restart.")}\n`);
|
|
77
78
|
}
|
|
79
|
+
/** Route Claude ids through the gateway's Messages API wherever an agent builds an exe model (see exe-claude-route.ts). */
|
|
80
|
+
function repairExeClaudeRoutes(cwd, deps) {
|
|
81
|
+
if (!deps["@kybernesis/exe"])
|
|
82
|
+
return;
|
|
83
|
+
const changed = repairExeClaudeRoute(cwd);
|
|
84
|
+
if (changed.length === 0)
|
|
85
|
+
return;
|
|
86
|
+
if (!deps["@ai-sdk/anthropic"]) {
|
|
87
|
+
const added = commandResult("npm", ["install", "@ai-sdk/anthropic"], cwd);
|
|
88
|
+
if (added.status !== 0) {
|
|
89
|
+
console.log(red(` ✗ could not install @ai-sdk/anthropic for the Claude route:\n${added.stderr.trim()}`));
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
console.log(` ${green("+")} passed createAnthropic to exeModel in ${changed.join(", ")}\n` +
|
|
95
|
+
` ${dim("Claude on the exe gateway is served on its Messages API; with only createOpenAI")}\n` +
|
|
96
|
+
` ${dim("a Claude id has no route, and exe 0.17+ refuses it when the agent loads.")}\n`);
|
|
97
|
+
}
|
|
78
98
|
/**
|
|
79
99
|
* Finish a Buzz install that a version bump alone leaves half-done.
|
|
80
100
|
*
|
|
@@ -582,7 +602,10 @@ function exeJudgeUrl(cwd, env) {
|
|
|
582
602
|
if (!judgeProvider)
|
|
583
603
|
return null;
|
|
584
604
|
const escaped = judgeProvider.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
585
|
-
|
|
605
|
+
// The provider may be made inline (`model: createAnthropic({ … }).evaluationModel(…)`)
|
|
606
|
+
// as well as bound to a name first; both carry the base URL in the same object.
|
|
607
|
+
const inline = /judge\s*:\s*\{[\s\S]*?model\s*:\s*create[A-Za-z]+\s*\(\s*\{([\s\S]*?)\}\s*\)/.exec(source)?.[1];
|
|
608
|
+
const providerBody = inline ?? new RegExp(`(?:const|let)\\s+${escaped}\\s*=\\s*create[A-Za-z]+\\s*\\(\\s*\\{([\\s\\S]*?)\\}\\s*\\)`).exec(source)?.[1];
|
|
586
609
|
if (!providerBody)
|
|
587
610
|
return /EXE_LLM_URL|llm\.int\.exe\.xyz/.test(source) ? undefined : null;
|
|
588
611
|
if (/EXE_LLM_URL/.test(providerBody))
|
|
@@ -785,6 +808,12 @@ function newestBuildForEve(name, eve) {
|
|
|
785
808
|
const candidates = [];
|
|
786
809
|
for (const version of ordered) {
|
|
787
810
|
const peer = targetEvePeer(name, version);
|
|
811
|
+
// A package whose newest build declares no eve peer at all (this CLI,
|
|
812
|
+
// @kybernesis/create) is not built per eve line: its newest is the answer.
|
|
813
|
+
// Without this, every agent that keeps kyb in its own package.json could
|
|
814
|
+
// never plan an upgrade (`kyb upgrade --check` reported it unresolved).
|
|
815
|
+
if (!peer && candidates.length === 0)
|
|
816
|
+
return version;
|
|
788
817
|
candidates.push({ version, ...(peer ? { peer } : {}) });
|
|
789
818
|
const hit = newestOnLine(candidates, eve);
|
|
790
819
|
if (hit)
|
|
@@ -1032,6 +1061,7 @@ export async function upgrade(options = {}) {
|
|
|
1032
1061
|
repairNotifySetup(cwd, deps);
|
|
1033
1062
|
repairReasoningSandboxes(cwd, deps);
|
|
1034
1063
|
repairManageRestart(cwd, deps);
|
|
1064
|
+
repairExeClaudeRoutes(cwd, deps);
|
|
1035
1065
|
return;
|
|
1036
1066
|
}
|
|
1037
1067
|
console.log(bold(`\nInstalling: ${changed.join(", ")}\n`));
|
|
@@ -1123,6 +1153,7 @@ export async function upgrade(options = {}) {
|
|
|
1123
1153
|
repairNotifySetup(cwd, deps);
|
|
1124
1154
|
repairReasoningSandboxes(cwd, deps);
|
|
1125
1155
|
repairManageRestart(cwd, deps);
|
|
1156
|
+
repairExeClaudeRoutes(cwd, deps);
|
|
1126
1157
|
run("npm", ["run", "typecheck"], { cwd });
|
|
1127
1158
|
if (eveChanged) {
|
|
1128
1159
|
const infoOk = run("npx", ["eve", "info"], { cwd, allowFail: true, quiet: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kybernesis/create",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.3",
|
|
4
4
|
"description": "The Kybernesis agent scaffolder and FDE toolkit: one command to a governed, remembering, multiplayer, self-testing eve agent \u2014 plus doctor and upgrade.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|