@byfriends/sdk 0.3.0 → 0.3.1
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/index.mjs
CHANGED
|
@@ -3,23 +3,23 @@ import { dirname as __cjsShimDirname } from 'node:path';
|
|
|
3
3
|
const __filename = __cjsShimFileURLToPath(import.meta.url);
|
|
4
4
|
const __dirname = __cjsShimDirname(__filename);
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
|
+
import * as fs$8 from "node:fs";
|
|
7
|
+
import Vt, { appendFileSync, chmodSync, closeSync, constants, createReadStream, createWriteStream, existsSync, fsyncSync, mkdirSync, openSync, promises, readFileSync, renameSync, statSync, unlinkSync, writeSync } from "node:fs";
|
|
8
|
+
import jn, { access, appendFile, chmod, copyFile, cp, lstat, mkdir, mkdtemp, open, readFile, readdir, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
6
9
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
10
|
import * as path$8 from "node:path";
|
|
8
11
|
import path, { basename, dirname, isAbsolute, join, normalize, posix, relative, resolve, win32 } from "node:path";
|
|
9
|
-
import I, { createWriteStream } from "fs";
|
|
12
|
+
import I, { createWriteStream as createWriteStream$1 } from "fs";
|
|
10
13
|
import Kr, { EventEmitter } from "events";
|
|
11
14
|
import * as path$1$1 from "path";
|
|
12
15
|
import $s, { dirname as dirname$1, parse } from "path";
|
|
13
16
|
import { Buffer as Buffer$1 } from "buffer";
|
|
14
17
|
import * as fs$9 from "fs/promises";
|
|
15
|
-
import { writeFile } from "fs/promises";
|
|
18
|
+
import { writeFile as writeFile$1 } from "fs/promises";
|
|
16
19
|
import Ns, { PassThrough, Readable } from "node:stream";
|
|
17
20
|
import { finished, pipeline as pipeline$1 } from "node:stream/promises";
|
|
18
21
|
import * as ks from "zlib";
|
|
19
22
|
import qr from "zlib";
|
|
20
|
-
import * as fs$8 from "node:fs";
|
|
21
|
-
import Vt, { appendFileSync, chmodSync, closeSync, constants, createReadStream, createWriteStream as createWriteStream$1, existsSync, fsyncSync, mkdirSync, openSync, promises, readFileSync, renameSync, statSync, unlinkSync, writeSync } from "node:fs";
|
|
22
|
-
import jn, { access, appendFile, chmod, cp, lstat, mkdir, mkdtemp, open, readFile, readdir, rename, rm, stat, unlink, writeFile as writeFile$1 } from "node:fs/promises";
|
|
23
23
|
import { z } from "zod";
|
|
24
24
|
import * as posixPath from "node:path/posix";
|
|
25
25
|
import * as win32Path from "node:path/win32";
|
|
@@ -10288,7 +10288,7 @@ var require_gaxios = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
10288
10288
|
}
|
|
10289
10289
|
static async #getFetch() {
|
|
10290
10290
|
const hasWindow = typeof window !== "undefined" && !!window;
|
|
10291
|
-
this.#fetch ||= hasWindow ? window.fetch : (await import("./src-
|
|
10291
|
+
this.#fetch ||= hasWindow ? window.fetch : (await import("./src-u7agTn5O.mjs")).default;
|
|
10292
10292
|
return this.#fetch;
|
|
10293
10293
|
}
|
|
10294
10294
|
/**
|
|
@@ -36078,11 +36078,11 @@ var NodeDownloader = class {
|
|
|
36078
36078
|
if (params.downloadPath) {
|
|
36079
36079
|
const response = await downloadFile(params, apiClient);
|
|
36080
36080
|
if (response instanceof HttpResponse) {
|
|
36081
|
-
const writer = createWriteStream(params.downloadPath);
|
|
36081
|
+
const writer = createWriteStream$1(params.downloadPath);
|
|
36082
36082
|
Readable.fromWeb(response.responseInternal.body).pipe(writer);
|
|
36083
36083
|
await finished(writer);
|
|
36084
36084
|
} else try {
|
|
36085
|
-
await writeFile(params.downloadPath, response, { encoding: "base64" });
|
|
36085
|
+
await writeFile$1(params.downloadPath, response, { encoding: "base64" });
|
|
36086
36086
|
} catch (error) {
|
|
36087
36087
|
throw new Error(`Failed to write file to ${params.downloadPath}: ${error}`);
|
|
36088
36088
|
}
|
|
@@ -38110,7 +38110,7 @@ function normalizeOpenAICompatToolSchema(schema) {
|
|
|
38110
38110
|
}
|
|
38111
38111
|
function ensureOpenAICompatPropertyTypes(schema) {
|
|
38112
38112
|
const normalized = cloneJsonValue(schema);
|
|
38113
|
-
if (!isRecord$
|
|
38113
|
+
if (!isRecord$6(normalized)) throw new Error("JSON Schema root must normalize to an object.");
|
|
38114
38114
|
recurseSchema(normalized);
|
|
38115
38115
|
return normalized;
|
|
38116
38116
|
}
|
|
@@ -38171,7 +38171,7 @@ function resolveLocalJsonPointer(root, ref) {
|
|
|
38171
38171
|
let current = root;
|
|
38172
38172
|
for (const rawPart of ref.slice(2).split("/")) {
|
|
38173
38173
|
const part = unescapeJsonPointerPart(rawPart);
|
|
38174
|
-
if (isRecord$
|
|
38174
|
+
if (isRecord$6(current)) {
|
|
38175
38175
|
if (!hasOwn$1(current, part)) return { found: false };
|
|
38176
38176
|
current = current[part];
|
|
38177
38177
|
} else if (Array.isArray(current)) {
|
|
@@ -38193,20 +38193,20 @@ function parseJsonPointerArrayIndex(part) {
|
|
|
38193
38193
|
return Number(part);
|
|
38194
38194
|
}
|
|
38195
38195
|
function recurseSchema(node) {
|
|
38196
|
-
if (!isRecord$
|
|
38196
|
+
if (!isRecord$6(node)) return;
|
|
38197
38197
|
visitChildSchemas(node, normalizeProperty);
|
|
38198
38198
|
}
|
|
38199
38199
|
function visitChildSchemas(node, visit) {
|
|
38200
38200
|
for (const { key, kind } of CHILD_SCHEMA_SLOTS) {
|
|
38201
38201
|
const value = node[key];
|
|
38202
38202
|
if (kind === "single") {
|
|
38203
|
-
if (isRecord$
|
|
38203
|
+
if (isRecord$6(value)) visit(value);
|
|
38204
38204
|
} else if (kind === "array") {
|
|
38205
38205
|
if (Array.isArray(value)) for (const item of value) visit(item);
|
|
38206
38206
|
} else if (kind === "map") {
|
|
38207
|
-
if (isRecord$
|
|
38207
|
+
if (isRecord$6(value)) for (const item of Object.values(value)) visit(item);
|
|
38208
38208
|
} else if (kind === "schema-or-array") {
|
|
38209
|
-
if (isRecord$
|
|
38209
|
+
if (isRecord$6(value)) visit(value);
|
|
38210
38210
|
else if (Array.isArray(value)) for (const item of value) visit(item);
|
|
38211
38211
|
}
|
|
38212
38212
|
}
|
|
@@ -38218,7 +38218,7 @@ function childSchemaKeysForParentType(parentType) {
|
|
|
38218
38218
|
});
|
|
38219
38219
|
}
|
|
38220
38220
|
function normalizeProperty(node) {
|
|
38221
|
-
if (!isRecord$
|
|
38221
|
+
if (!isRecord$6(node)) return;
|
|
38222
38222
|
if (!hasOwn$1(node, "type") && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) {
|
|
38223
38223
|
const enumValues = node["enum"];
|
|
38224
38224
|
if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
|
|
@@ -38282,14 +38282,14 @@ function hasAnyKey(obj, keys) {
|
|
|
38282
38282
|
}
|
|
38283
38283
|
function cloneJsonValue(value) {
|
|
38284
38284
|
if (Array.isArray(value)) return value.map((item) => cloneJsonValue(item));
|
|
38285
|
-
if (isRecord$
|
|
38285
|
+
if (isRecord$6(value)) {
|
|
38286
38286
|
const cloned = {};
|
|
38287
38287
|
for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue(child);
|
|
38288
38288
|
return cloned;
|
|
38289
38289
|
}
|
|
38290
38290
|
return value;
|
|
38291
38291
|
}
|
|
38292
|
-
function isRecord$
|
|
38292
|
+
function isRecord$6(value) {
|
|
38293
38293
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
38294
38294
|
}
|
|
38295
38295
|
function hasOwn$1(obj, key) {
|
|
@@ -46352,7 +46352,7 @@ var OpenAIResponsesChatProvider = class OpenAIResponsesChatProvider extends Base
|
|
|
46352
46352
|
};
|
|
46353
46353
|
//#endregion
|
|
46354
46354
|
//#region ../kosong/src/providers/index.ts
|
|
46355
|
-
function createProvider(config) {
|
|
46355
|
+
function createProvider$1(config) {
|
|
46356
46356
|
switch (config.type) {
|
|
46357
46357
|
case "anthropic": return new AnthropicChatProvider(config);
|
|
46358
46358
|
case "openai-completions": return new OpenAICompletionsChatProvider(config);
|
|
@@ -54783,7 +54783,7 @@ function isAbortError(err) {
|
|
|
54783
54783
|
if (err instanceof Error) return err.name === "AbortError";
|
|
54784
54784
|
return false;
|
|
54785
54785
|
}
|
|
54786
|
-
function errorMessage$
|
|
54786
|
+
function errorMessage$3(err) {
|
|
54787
54787
|
if (err instanceof Error) return err.message;
|
|
54788
54788
|
return String(err);
|
|
54789
54789
|
}
|
|
@@ -58027,7 +58027,7 @@ function parseSkillText(options) {
|
|
|
58027
58027
|
throw error;
|
|
58028
58028
|
}
|
|
58029
58029
|
const frontmatter = parsed.data ?? {};
|
|
58030
|
-
if (!isRecord$
|
|
58030
|
+
if (!isRecord$5(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
|
|
58031
58031
|
const metadata = normalizeMetadata(frontmatter);
|
|
58032
58032
|
if (!isSupportedSkillType(metadata.type)) throw new UnsupportedSkillTypeError(metadata.type ?? String(frontmatter["type"]));
|
|
58033
58033
|
const name = nonEmptyString$3(metadata.name);
|
|
@@ -58140,7 +58140,7 @@ function tokenizeArgs(raw) {
|
|
|
58140
58140
|
function nonEmptyString$3(value) {
|
|
58141
58141
|
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
58142
58142
|
}
|
|
58143
|
-
function isRecord$
|
|
58143
|
+
function isRecord$5(value) {
|
|
58144
58144
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
58145
58145
|
}
|
|
58146
58146
|
//#endregion
|
|
@@ -58961,12 +58961,12 @@ function joinPath(parent, child, pathClass) {
|
|
|
58961
58961
|
}
|
|
58962
58962
|
//#endregion
|
|
58963
58963
|
//#region ../agent-core/src/tools/builtin/file/glob.md
|
|
58964
|
-
var glob_default = "Find files (and optionally directories) by glob pattern, sorted by modification time (most recent first).\n\
|
|
58964
|
+
var glob_default = "Find files (and optionally directories) by glob pattern, sorted by modification time (most recent first).\n\nREJECTED patterns (no literal anchor — will be rejected):\n- **Pure wildcards**: `**`, `**/*`, `*/*` — no literal anchor bounds the result. Add an extension or subdirectory to give the walk a concrete target.\n- **`**/` prefix**: Anything starting with `**/` (e.g. `**/*.py`, `**/main/*.ts`). The leading `**/` has no literal anchor in front of it. Anchor it with a top-level subdirectory like `src/**/*.ts`.\n- **Brace expansion**: `*.{ts,tsx}` is not supported. Split it into separate calls: `*.ts` and `*.tsx`.\n\nGood patterns:\n- `*.ts` — files in the current directory matching an extension\n- `src/**/*.ts` — recursive with a subdirectory anchor and extension\n- `test_*.py` — files whose name starts with a literal prefix\n\nLarge-directory warning — avoid recursing into dependency/build output even with an anchor:\n- `node_modules/**/*.js`, `.venv/**/*.py`, `__pycache__/**`, `target/**` match technically but typically produce thousands of results that truncate at the match cap. Prefer specific subpaths like `node_modules/react/src/**/*.js`.\n\nWhen you need to search the entire project, first use Glob to explore the top-level directory structure, then use an anchored pattern like `src/**/*.ts` or `packages/**/*.ts` to narrow the search.\n";
|
|
58965
58965
|
//#endregion
|
|
58966
58966
|
//#region ../agent-core/src/tools/builtin/file/glob.ts
|
|
58967
58967
|
const GlobInputSchema = z.object({
|
|
58968
|
-
pattern: z.string().describe("Glob pattern to match files/directories."),
|
|
58969
|
-
path: z.string().optional().describe("Absolute path to the directory to search in. Defaults to the current working directory."),
|
|
58968
|
+
pattern: z.string().describe("Glob pattern to match files/directories. IMPORTANT: pattern MUST contain a literal anchor like a file extension (.ts) or a subdirectory name (src/). Patterns starting with **/ (e.g. **/*.py, **/main/*.ts), pure wildcards (**, **/*, */*, *), and brace expansion (*.{ts,tsx}) are REJECTED. Example: src/**/*.ts searches all .ts files under src/."),
|
|
58969
|
+
path: z.string().optional().describe("Absolute path to the directory to search in. Defaults to the current working directory. Explicit absolute paths outside the workspace are allowed (e.g. to search a dependency installed elsewhere); relative paths are resolved against the working directory and rejected if they escape it."),
|
|
58970
58970
|
include_dirs: z.boolean().default(true).optional().describe("Whether to include directories in results. Defaults to true. Set false to return only files.")
|
|
58971
58971
|
});
|
|
58972
58972
|
const MAX_MATCHES = 1e3;
|
|
@@ -59008,7 +59008,7 @@ var GlobTool = class {
|
|
|
59008
59008
|
workspace: this.workspace,
|
|
59009
59009
|
operation: "search",
|
|
59010
59010
|
policy: {
|
|
59011
|
-
guardMode: "
|
|
59011
|
+
guardMode: "absolute-outside-allowed",
|
|
59012
59012
|
checkSensitive: false
|
|
59013
59013
|
}
|
|
59014
59014
|
});
|
|
@@ -59042,7 +59042,7 @@ var GlobTool = class {
|
|
|
59042
59042
|
}
|
|
59043
59043
|
return {
|
|
59044
59044
|
isError: true,
|
|
59045
|
-
output: `Pattern "${args.pattern}" is a pure wildcard (only \`*\`, \`?\`, \`**\`, \`/\`) and would enumerate every file under the search root — with no literal anchor to bound the result set, this typically exhausts your context on large trees. Add an extension ("${args.pattern === "**" || args.pattern === "**/*" ? "**/*.ts" : "**/*.md"}") or a subdirectory ("src/**/*.ts") to constrain the walk.\n\
|
|
59045
|
+
output: `Pattern "${args.pattern}" is a pure wildcard (only \`*\`, \`?\`, \`**\`, \`/\`) and would enumerate every file under the search root — with no literal anchor to bound the result set, this typically exhausts your context on large trees. Add an extension ("${args.pattern === "**" || args.pattern === "**/*" ? "**/*.ts" : "**/*.md"}") or a subdirectory ("src/**/*.ts") to constrain the walk.\n\nWorkspace roots:\n${rootList}\n\nTop of ${this.workspace.workspaceDir}:\n${tree}`
|
|
59046
59046
|
};
|
|
59047
59047
|
}
|
|
59048
59048
|
if (containsBraceExpansion(args.pattern)) return {
|
|
@@ -59070,6 +59070,8 @@ var GlobTool = class {
|
|
|
59070
59070
|
try {
|
|
59071
59071
|
const seen = /* @__PURE__ */ new Set();
|
|
59072
59072
|
const entries = [];
|
|
59073
|
+
const pathClass = this.kaos.pathClass();
|
|
59074
|
+
const filteredSensitive = [];
|
|
59073
59075
|
const YIELD_SAFETY_CAP = MAX_MATCHES * 2;
|
|
59074
59076
|
let yielded = 0;
|
|
59075
59077
|
let truncated = false;
|
|
@@ -59085,6 +59087,10 @@ var GlobTool = class {
|
|
|
59085
59087
|
break outer;
|
|
59086
59088
|
}
|
|
59087
59089
|
seen.add(filePath);
|
|
59090
|
+
if (isSensitiveFile(filePath, pathClass)) {
|
|
59091
|
+
filteredSensitive.push(filePath);
|
|
59092
|
+
continue;
|
|
59093
|
+
}
|
|
59088
59094
|
let mtime = 0;
|
|
59089
59095
|
let isDir = false;
|
|
59090
59096
|
try {
|
|
@@ -59100,10 +59106,10 @@ var GlobTool = class {
|
|
|
59100
59106
|
}
|
|
59101
59107
|
entries.sort((a, b) => b.mtime - a.mtime);
|
|
59102
59108
|
const paths = entries.map((e) => e.path);
|
|
59103
|
-
const pathClass = this.kaos.pathClass();
|
|
59104
59109
|
const relBase = searchRoots[0] ?? this.workspace.workspaceDir;
|
|
59105
59110
|
const displayLines = paths.map((p) => relativizeIfUnder$1(p, relBase, pathClass));
|
|
59106
|
-
|
|
59111
|
+
const filteredSome = filteredSensitive.length > 0;
|
|
59112
|
+
if (entries.length === 0 && !truncated) return { output: filteredSome ? `No non-sensitive matches found (filtered ${String(filteredSensitive.length)} sensitive file(s))` : "No matches found" };
|
|
59107
59113
|
const lines = [];
|
|
59108
59114
|
if (truncated) {
|
|
59109
59115
|
lines.push(`[Truncated at ${String(MAX_MATCHES)} matches — use a more specific pattern]`);
|
|
@@ -59111,6 +59117,10 @@ var GlobTool = class {
|
|
|
59111
59117
|
}
|
|
59112
59118
|
lines.push(...displayLines);
|
|
59113
59119
|
if (!truncated && entries.length === 1e3) lines.push(`Found ${String(entries.length)} matches`);
|
|
59120
|
+
if (filteredSome) {
|
|
59121
|
+
const displayedFiltered = filteredSensitive.map((p) => relativizeIfUnder$1(p, relBase, pathClass));
|
|
59122
|
+
lines.push(`Filtered ${String(filteredSensitive.length)} sensitive file(s): ${displayedFiltered.join(", ")}`);
|
|
59123
|
+
}
|
|
59114
59124
|
return { output: lines.join("\n") };
|
|
59115
59125
|
} catch (error) {
|
|
59116
59126
|
if (error !== null && typeof error === "object" && "code" in error) {
|
|
@@ -63458,7 +63468,7 @@ async function downloadAndInstallRg(shareDir) {
|
|
|
63458
63468
|
clearTimeout(timeoutHandle);
|
|
63459
63469
|
}
|
|
63460
63470
|
if (!resp.ok || resp.body === null) throw new Error(`Failed to download ripgrep: HTTP ${String(resp.status)} ${resp.statusText}`);
|
|
63461
|
-
const write = createWriteStream
|
|
63471
|
+
const write = createWriteStream(archivePath);
|
|
63462
63472
|
await pipeline$1(Readable.fromWeb(resp.body), write);
|
|
63463
63473
|
await verifyArchiveChecksum(archivePath, archiveName, expectedSha256);
|
|
63464
63474
|
if (isWindows) await extractRgFromZip(archivePath, destination);
|
|
@@ -63519,7 +63529,7 @@ async function extractRgFromZip(archivePath, destination) {
|
|
|
63519
63529
|
zipfile.close();
|
|
63520
63530
|
return;
|
|
63521
63531
|
}
|
|
63522
|
-
const out = createWriteStream
|
|
63532
|
+
const out = createWriteStream(destination);
|
|
63523
63533
|
(async () => {
|
|
63524
63534
|
try {
|
|
63525
63535
|
await pipeline$1(stream, out);
|
|
@@ -65435,7 +65445,7 @@ function rewriteWindowsNullRedirect$1(command) {
|
|
|
65435
65445
|
}
|
|
65436
65446
|
//#endregion
|
|
65437
65447
|
//#region ../agent-core/src/tools/builtin/state/todo-list.md
|
|
65438
|
-
var todo_list_default = "Use this tool to maintain a structured TODO list as you work through a multi-step task.\n\nUse for multi-step tasks, tracking investigation progress, or planning a sequence of edits. Do not use for single-shot answers or trivial requests.\n\n**
|
|
65448
|
+
var todo_list_default = "Use this tool to maintain a structured TODO list as you work through a multi-step task.\n\nUse for multi-step tasks, tracking investigation progress, or planning a sequence of edits. Do not use for single-shot answers or trivial requests.\n\n**Update discipline:**\n- Update status immediately when you start or complete a subtask: mark it `in_progress` when you begin working on it, and `done` when finished.\n- Do not skip the `in_progress` state — the user should always see what you are currently working on.\n- Avoid redundant calls: do not re-call this tool when nothing meaningful has changed since the last call.\n- When unsure of the current state, call query mode first (omit `todos`) to check the list before deciding what to update.\n- If no available tool can move any task forward, tell the user where you are stuck instead of repeatedly re-ordering the same todos.\n\n**How to use:**\n- Call with `todos: [...]` to replace the full list. Statuses: pending / in_progress / done.\n- Call with no arguments to query the current list.\n- Call with `todos: []` to clear the list.\n- Keep titles short and actionable.\n- Update statuses as you make progress — mark one item in_progress at a time.\n";
|
|
65439
65449
|
//#endregion
|
|
65440
65450
|
//#region ../agent-core/src/tools/builtin/state/todo-list.ts
|
|
65441
65451
|
/**
|
|
@@ -66810,7 +66820,7 @@ var ConfigState = class {
|
|
|
66810
66820
|
return provider;
|
|
66811
66821
|
}
|
|
66812
66822
|
get provider() {
|
|
66813
|
-
return createProvider(this.providerConfig);
|
|
66823
|
+
return createProvider$1(this.providerConfig);
|
|
66814
66824
|
}
|
|
66815
66825
|
get model() {
|
|
66816
66826
|
if (this._modelAlias === void 0) throw new Error("Model not set");
|
|
@@ -67337,7 +67347,7 @@ const OptionalStringSchema = z.preprocess((value) => {
|
|
|
67337
67347
|
if (typeof value === "string") return value;
|
|
67338
67348
|
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
|
|
67339
67349
|
}, z.string().optional());
|
|
67340
|
-
const HookSpecificOutputSchema = z.preprocess((value) => isRecord$
|
|
67350
|
+
const HookSpecificOutputSchema = z.preprocess((value) => isRecord$4(value) ? value : void 0, z.looseObject({
|
|
67341
67351
|
message: OptionalStringSchema,
|
|
67342
67352
|
permissionDecision: z.unknown().optional(),
|
|
67343
67353
|
permissionDecisionReason: OptionalStringSchema
|
|
@@ -67356,7 +67366,7 @@ async function runHook(command, input, options) {
|
|
|
67356
67366
|
detached: process.platform !== "win32"
|
|
67357
67367
|
});
|
|
67358
67368
|
} catch (error) {
|
|
67359
|
-
return allowResult({ stderr: errorMessage$
|
|
67369
|
+
return allowResult({ stderr: errorMessage$2(error) });
|
|
67360
67370
|
}
|
|
67361
67371
|
return new Promise((resolve) => {
|
|
67362
67372
|
let stdout = "";
|
|
@@ -67404,7 +67414,7 @@ async function runHook(command, input, options) {
|
|
|
67404
67414
|
child.on("error", (error) => {
|
|
67405
67415
|
settle(allowResult({
|
|
67406
67416
|
stdout,
|
|
67407
|
-
stderr: stderr + errorMessage$
|
|
67417
|
+
stderr: stderr + errorMessage$2(error)
|
|
67408
67418
|
}));
|
|
67409
67419
|
});
|
|
67410
67420
|
child.on("close", (code) => {
|
|
@@ -67497,10 +67507,10 @@ function tryKillProcess(child, signal) {
|
|
|
67497
67507
|
} catch {}
|
|
67498
67508
|
}
|
|
67499
67509
|
}
|
|
67500
|
-
function isRecord$
|
|
67510
|
+
function isRecord$4(value) {
|
|
67501
67511
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
67502
67512
|
}
|
|
67503
|
-
function errorMessage$
|
|
67513
|
+
function errorMessage$2(error) {
|
|
67504
67514
|
return error instanceof Error ? error.message : String(error);
|
|
67505
67515
|
}
|
|
67506
67516
|
//#endregion
|
|
@@ -70432,8 +70442,8 @@ function approvalTelemetryMode(mode) {
|
|
|
70432
70442
|
//#endregion
|
|
70433
70443
|
//#region ../agent-core/src/agent/records/migration/v1.1.ts
|
|
70434
70444
|
function isLegacyToolCall(v) {
|
|
70435
|
-
if (!isRecord$
|
|
70436
|
-
return v["type"] === "function" && typeof v["id"] === "string" && isRecord$
|
|
70445
|
+
if (!isRecord$3(v)) return false;
|
|
70446
|
+
return v["type"] === "function" && typeof v["id"] === "string" && isRecord$3(v["function"]);
|
|
70437
70447
|
}
|
|
70438
70448
|
function migrateToolCall(v) {
|
|
70439
70449
|
const { function: fn, ...rest } = v;
|
|
@@ -70443,7 +70453,7 @@ function migrateToolCall(v) {
|
|
|
70443
70453
|
arguments: fn.arguments
|
|
70444
70454
|
};
|
|
70445
70455
|
}
|
|
70446
|
-
function isRecord$
|
|
70456
|
+
function isRecord$3(value) {
|
|
70447
70457
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70448
70458
|
}
|
|
70449
70459
|
const MIGRATIONS = [{
|
|
@@ -70672,8 +70682,7 @@ var AgentRecords = class {
|
|
|
70672
70682
|
tools: "tools",
|
|
70673
70683
|
usage: "usage",
|
|
70674
70684
|
background: "background",
|
|
70675
|
-
full_compaction: "fullCompaction"
|
|
70676
|
-
plan_mode: "planMode"
|
|
70685
|
+
full_compaction: "fullCompaction"
|
|
70677
70686
|
}[recordType.split(".")[0]] ?? null;
|
|
70678
70687
|
}
|
|
70679
70688
|
async replay() {
|
|
@@ -78256,7 +78265,7 @@ function parseToolCallArguments(raw) {
|
|
|
78256
78265
|
} catch (error) {
|
|
78257
78266
|
return {
|
|
78258
78267
|
success: false,
|
|
78259
|
-
error: errorMessage$
|
|
78268
|
+
error: errorMessage$3(error)
|
|
78260
78269
|
};
|
|
78261
78270
|
}
|
|
78262
78271
|
}
|
|
@@ -78308,7 +78317,7 @@ async function prepareToolCall(step, call) {
|
|
|
78308
78317
|
toolCallId: call.toolCall.id,
|
|
78309
78318
|
error
|
|
78310
78319
|
});
|
|
78311
|
-
const output = error instanceof PathSecurityError ? error.message : `Tool "${call.toolName}" failed to resolve execution: ${errorMessage$
|
|
78320
|
+
const output = error instanceof PathSecurityError ? error.message : `Tool "${call.toolName}" failed to resolve execution: ${errorMessage$3(error)}`;
|
|
78312
78321
|
await dispatchToolCall(step, call, effectiveArgs);
|
|
78313
78322
|
return { task: makeResolvedToolCallTask(makeErrorToolResult(call, effectiveArgs, output)) };
|
|
78314
78323
|
}
|
|
@@ -78368,7 +78377,7 @@ async function runPrepareToolExecutionHook(step, call) {
|
|
|
78368
78377
|
return {
|
|
78369
78378
|
kind: "hookFailed",
|
|
78370
78379
|
args,
|
|
78371
|
-
output: `prepareToolExecution hook failed for "${call.toolName}": ${errorMessage$
|
|
78380
|
+
output: `prepareToolExecution hook failed for "${call.toolName}": ${errorMessage$3(error)}`
|
|
78372
78381
|
};
|
|
78373
78382
|
}
|
|
78374
78383
|
const effectiveArgs = hookResult?.updatedArgs ?? args;
|
|
@@ -78412,7 +78421,7 @@ async function runRunnableToolCall(step, call, effectiveArgs, metadata, executio
|
|
|
78412
78421
|
toolCallId: toolCall.id,
|
|
78413
78422
|
error
|
|
78414
78423
|
});
|
|
78415
|
-
return makeErrorToolResult(call, effectiveArgs, aborted ? `Tool "${toolName}" was aborted` : `Tool "${toolName}" failed: ${errorMessage$
|
|
78424
|
+
return makeErrorToolResult(call, effectiveArgs, aborted ? `Tool "${toolName}" was aborted` : `Tool "${toolName}" failed: ${errorMessage$3(error)}`);
|
|
78416
78425
|
}
|
|
78417
78426
|
return makeToolResult(call, effectiveArgs, toolResult);
|
|
78418
78427
|
}
|
|
@@ -78444,7 +78453,7 @@ async function finalizePendingToolResult(step, pendingResult) {
|
|
|
78444
78453
|
toolCallId: pendingResult.toolCall.id,
|
|
78445
78454
|
error
|
|
78446
78455
|
});
|
|
78447
|
-
const output = aborted ? `Tool "${pendingResult.toolName}" aborted during finalizeToolResult hook.` : `finalizeToolResult hook failed for "${pendingResult.toolName}": ${errorMessage$
|
|
78456
|
+
const output = aborted ? `Tool "${pendingResult.toolName}" aborted during finalizeToolResult hook.` : `finalizeToolResult hook failed for "${pendingResult.toolName}": ${errorMessage$3(error)}`;
|
|
78448
78457
|
return {
|
|
78449
78458
|
...pendingResult,
|
|
78450
78459
|
stopTurn: pendingResult.stopTurn,
|
|
@@ -78806,7 +78815,7 @@ async function runTurn(input) {
|
|
|
78806
78815
|
usage
|
|
78807
78816
|
};
|
|
78808
78817
|
}
|
|
78809
|
-
dispatchEvent(makeInterruptedEvent(isMaxStepsExceededError(error) ? "max_steps" : "error", steps, activeStep, errorMessage$
|
|
78818
|
+
dispatchEvent(makeInterruptedEvent(isMaxStepsExceededError(error) ? "max_steps" : "error", steps, activeStep, errorMessage$3(error)));
|
|
78810
78819
|
throw error;
|
|
78811
78820
|
}
|
|
78812
78821
|
return {
|
|
@@ -82939,8 +82948,8 @@ var ToolManager = class {
|
|
|
82939
82948
|
return (input) => withProviderRequestAuth(resolveAuth, (auth) => uploadVideo(input, { auth }));
|
|
82940
82949
|
}
|
|
82941
82950
|
get loopTools() {
|
|
82942
|
-
const builtinNames = [...this.builtinTools.keys()].filter((name) => this.enabledTools.has(name)).
|
|
82943
|
-
const userNames = [...this.userTools.keys()].filter((name) => this.enabledTools.has(name)).
|
|
82951
|
+
const builtinNames = [...this.builtinTools.keys()].filter((name) => this.enabledTools.has(name)).toSorted();
|
|
82952
|
+
const userNames = [...this.userTools.keys()].filter((name) => this.enabledTools.has(name)).toSorted();
|
|
82944
82953
|
const mcpNames = [...this.mcpTools.keys()].filter((name) => this.isMcpToolEnabled(name));
|
|
82945
82954
|
return [
|
|
82946
82955
|
...builtinNames.map((name) => this.builtinTools.get(name)),
|
|
@@ -83116,7 +83125,7 @@ function findImplicitBoundaries(prompt) {
|
|
|
83116
83125
|
const index = prompt.indexOf(header);
|
|
83117
83126
|
if (index !== -1) boundaries.push(index);
|
|
83118
83127
|
}
|
|
83119
|
-
return boundaries.
|
|
83128
|
+
return boundaries.toSorted((a, b) => a - b);
|
|
83120
83129
|
}
|
|
83121
83130
|
/**
|
|
83122
83131
|
* Split prompt by implicit boundaries into blocks.
|
|
@@ -84541,15 +84550,6 @@ var Agent = class {
|
|
|
84541
84550
|
getModel: () => {
|
|
84542
84551
|
return this.config.modelAlias ?? "";
|
|
84543
84552
|
},
|
|
84544
|
-
enterPlan: async () => {
|
|
84545
|
-
throw new ByfError(ErrorCodes.NOT_IMPLEMENTED, "Plan mode has been removed");
|
|
84546
|
-
},
|
|
84547
|
-
cancelPlan: async () => {
|
|
84548
|
-
throw new ByfError(ErrorCodes.NOT_IMPLEMENTED, "Plan mode has been removed");
|
|
84549
|
-
},
|
|
84550
|
-
clearPlan: async () => {
|
|
84551
|
-
throw new ByfError(ErrorCodes.NOT_IMPLEMENTED, "Plan mode has been removed");
|
|
84552
|
-
},
|
|
84553
84553
|
beginCompaction: (payload) => {
|
|
84554
84554
|
this.fullCompaction.begin({
|
|
84555
84555
|
source: "manual",
|
|
@@ -84584,7 +84584,6 @@ var Agent = class {
|
|
|
84584
84584
|
getContext: () => this.context.data(),
|
|
84585
84585
|
getConfig: () => this.config.data(),
|
|
84586
84586
|
getPermission: () => this.permission.data(),
|
|
84587
|
-
getPlan: async () => null,
|
|
84588
84587
|
getUsage: () => this.usage.data(),
|
|
84589
84588
|
getTools: () => this.tools.data(),
|
|
84590
84589
|
getBackground: (payload) => this.background.list(payload.activeOnly ?? false, payload.limit)
|
|
@@ -84717,6 +84716,21 @@ function proxyWithExtraPayload(methods, extraPayload) {
|
|
|
84717
84716
|
}, ...args);
|
|
84718
84717
|
} });
|
|
84719
84718
|
}
|
|
84719
|
+
/** The Zod `z.enum` literal inferred from registry keys. */
|
|
84720
|
+
const PROVIDER_TYPE_VALUES = Object.keys({
|
|
84721
|
+
exa: { defaultBaseUrl: "https://api.exa.ai/search" },
|
|
84722
|
+
brave: { defaultBaseUrl: "https://api.search.brave.com/res/v1/web/search" },
|
|
84723
|
+
firecrawl: { defaultBaseUrl: "https://api.firecrawl.dev/v2/search" }
|
|
84724
|
+
});
|
|
84725
|
+
const providerClassMap = /* @__PURE__ */ new Map();
|
|
84726
|
+
function registerProvider(type, cls) {
|
|
84727
|
+
providerClassMap.set(type, cls);
|
|
84728
|
+
}
|
|
84729
|
+
function createProvider(type, options) {
|
|
84730
|
+
const cls = providerClassMap.get(type);
|
|
84731
|
+
if (cls === void 0) throw new Error(`WebSearch provider type "${type}" is not registered. Did you import the provider module?`);
|
|
84732
|
+
return new cls(options);
|
|
84733
|
+
}
|
|
84720
84734
|
//#endregion
|
|
84721
84735
|
//#region ../agent-core/src/config/schema.ts
|
|
84722
84736
|
const ProviderTypeSchema = z.enum([
|
|
@@ -84816,9 +84830,18 @@ const ByfServiceConfigSchema = z.object({
|
|
|
84816
84830
|
oauth: OAuthRefSchema.optional(),
|
|
84817
84831
|
customHeaders: StringRecordSchema.optional()
|
|
84818
84832
|
});
|
|
84833
|
+
/** Provider type enum derived from webSearchProviderRegistry keys. */
|
|
84834
|
+
const WebSearchProviderTypeSchema = z.enum(PROVIDER_TYPE_VALUES);
|
|
84835
|
+
const WebSearchProviderConfigSchema = z.object({
|
|
84836
|
+
type: WebSearchProviderTypeSchema,
|
|
84837
|
+
apiKeys: z.array(z.string().min(1)).nonempty(),
|
|
84838
|
+
baseUrl: z.string().optional(),
|
|
84839
|
+
priority: z.number().int().positive()
|
|
84840
|
+
});
|
|
84841
|
+
const WebSearchConfigSchema = z.object({ providers: z.array(WebSearchProviderConfigSchema).nonempty() });
|
|
84819
84842
|
const ServicesConfigSchema = z.object({
|
|
84820
|
-
|
|
84821
|
-
|
|
84843
|
+
webSearch: WebSearchConfigSchema.optional(),
|
|
84844
|
+
fetchUrl: ByfServiceConfigSchema.optional()
|
|
84822
84845
|
});
|
|
84823
84846
|
const McpServerCommonFields = {
|
|
84824
84847
|
enabled: z.boolean().optional(),
|
|
@@ -84884,8 +84907,8 @@ const LoopControlPatchSchema = LoopControlSchema.partial();
|
|
|
84884
84907
|
const BackgroundConfigPatchSchema = BackgroundConfigSchema.partial();
|
|
84885
84908
|
const ByfServiceConfigPatchSchema = ByfServiceConfigSchema.partial();
|
|
84886
84909
|
const ServicesConfigPatchSchema = z.object({
|
|
84887
|
-
|
|
84888
|
-
|
|
84910
|
+
webSearch: WebSearchConfigSchema.optional(),
|
|
84911
|
+
fetchUrl: ByfServiceConfigPatchSchema.optional()
|
|
84889
84912
|
});
|
|
84890
84913
|
const ByfConfigPatchSchema = z.object({
|
|
84891
84914
|
providers: z.record(z.string(), ProviderConfigPatchSchema).optional(),
|
|
@@ -85133,10 +85156,15 @@ function transformServiceData(data) {
|
|
|
85133
85156
|
const targetKey = snakeToCamel(key);
|
|
85134
85157
|
if (targetKey === "oauth") out[targetKey] = isPlainObject$1(value) ? transformPlainObject(value) : value;
|
|
85135
85158
|
else if (targetKey === "customHeaders") out[targetKey] = cloneObjectValue(value);
|
|
85159
|
+
else if (Array.isArray(value)) out[targetKey] = value.map((item) => isPlainObject$1(item) ? transformRecord(item, identity, snakeToCamel) : item);
|
|
85160
|
+
else if (isPlainObject$1(value)) out[targetKey] = transformPlainObject(value);
|
|
85136
85161
|
else out[targetKey] = value;
|
|
85137
85162
|
}
|
|
85138
85163
|
return out;
|
|
85139
85164
|
}
|
|
85165
|
+
function identity(v) {
|
|
85166
|
+
return v;
|
|
85167
|
+
}
|
|
85140
85168
|
function transformLoopControlData(data) {
|
|
85141
85169
|
const out = transformPlainObject(data);
|
|
85142
85170
|
if (out["maxStepsPerTurn"] === void 0 && out["maxStepsPerRun"] !== void 0) out["maxStepsPerTurn"] = out["maxStepsPerRun"];
|
|
@@ -85156,11 +85184,11 @@ function configToTomlData(config) {
|
|
|
85156
85184
|
delete out["default_yolo"];
|
|
85157
85185
|
delete out["defaultYolo"];
|
|
85158
85186
|
delete out["defaultPermissionMode"];
|
|
85187
|
+
delete out["default_thinking"];
|
|
85159
85188
|
for (const key of [
|
|
85160
85189
|
"defaultProvider",
|
|
85161
85190
|
"defaultModel",
|
|
85162
85191
|
"yolo",
|
|
85163
|
-
"defaultThinking",
|
|
85164
85192
|
"defaultPermissionMode",
|
|
85165
85193
|
"mergeAllAvailableSkills",
|
|
85166
85194
|
"extraSkillDirs"
|
|
@@ -85229,10 +85257,17 @@ function permissionRuleToToml(rule) {
|
|
|
85229
85257
|
}
|
|
85230
85258
|
function servicesToToml(services, rawServices) {
|
|
85231
85259
|
const out = cloneRecord(rawServices);
|
|
85232
|
-
if (services.
|
|
85233
|
-
|
|
85234
|
-
|
|
85235
|
-
|
|
85260
|
+
if (services.webSearch !== void 0 && services.webSearch.providers.length > 0) {
|
|
85261
|
+
const providersToml = services.webSearch.providers.map((p) => {
|
|
85262
|
+
const providerOut = {};
|
|
85263
|
+
for (const [key, value] of Object.entries(p)) setDefined(providerOut, camelToSnake(key), value);
|
|
85264
|
+
return providerOut;
|
|
85265
|
+
});
|
|
85266
|
+
out["web_search"] = out["web_search"] ?? {};
|
|
85267
|
+
out["web_search"]["providers"] = providersToml;
|
|
85268
|
+
} else delete out["web_search"];
|
|
85269
|
+
if (services.fetchUrl !== void 0) out["fetch_url"] = serviceToToml(services.fetchUrl);
|
|
85270
|
+
else delete out["fetch_url"];
|
|
85236
85271
|
return out;
|
|
85237
85272
|
}
|
|
85238
85273
|
function serviceToToml(service) {
|
|
@@ -85290,6 +85325,595 @@ function isFileExistsError(error) {
|
|
|
85290
85325
|
return typeof error === "object" && error !== null && error.code === "EEXIST";
|
|
85291
85326
|
}
|
|
85292
85327
|
//#endregion
|
|
85328
|
+
//#region ../agent-core/src/config/update-rules.ts
|
|
85329
|
+
const REMOVED_RULES = [
|
|
85330
|
+
{
|
|
85331
|
+
path: "default_yolo",
|
|
85332
|
+
pathParts: ["default_yolo"],
|
|
85333
|
+
kind: "removed",
|
|
85334
|
+
detail: "Top-level field default_yolo is removed. Use yolo instead.",
|
|
85335
|
+
deprecatedSince: "pre-0.1.0"
|
|
85336
|
+
},
|
|
85337
|
+
{
|
|
85338
|
+
path: "defaultYolo",
|
|
85339
|
+
pathParts: ["defaultYolo"],
|
|
85340
|
+
kind: "removed",
|
|
85341
|
+
detail: "Top-level field defaultYolo is removed. Use yolo instead.",
|
|
85342
|
+
deprecatedSince: "pre-0.1.0"
|
|
85343
|
+
},
|
|
85344
|
+
{
|
|
85345
|
+
path: "services.byf_search",
|
|
85346
|
+
pathParts: ["services", "byf_search"],
|
|
85347
|
+
kind: "removed",
|
|
85348
|
+
detail: "Deprecated service byf_search is removed.",
|
|
85349
|
+
deprecatedSince: "pre-0.1.0"
|
|
85350
|
+
},
|
|
85351
|
+
{
|
|
85352
|
+
path: "services.byf_fetch",
|
|
85353
|
+
pathParts: ["services", "byf_fetch"],
|
|
85354
|
+
kind: "removed",
|
|
85355
|
+
detail: "Deprecated service byf_fetch is removed. Use services.fetch_url instead.",
|
|
85356
|
+
deprecatedSince: "pre-0.1.0"
|
|
85357
|
+
}
|
|
85358
|
+
];
|
|
85359
|
+
const RENAMED_RULES = [{
|
|
85360
|
+
path: "loop_control.max_steps_per_run",
|
|
85361
|
+
pathParts: ["loop_control", "max_steps_per_run"],
|
|
85362
|
+
kind: "renamed",
|
|
85363
|
+
detail: "Renamed to max_steps_per_turn.",
|
|
85364
|
+
deprecatedSince: "pre-0.1.0"
|
|
85365
|
+
}];
|
|
85366
|
+
const MIGRATED_RULES = [{
|
|
85367
|
+
path: "default_thinking",
|
|
85368
|
+
pathParts: ["default_thinking"],
|
|
85369
|
+
kind: "migrated",
|
|
85370
|
+
detail: "Migrate default_thinking to [thinking] block.",
|
|
85371
|
+
deprecatedSince: "pre-0.1.0"
|
|
85372
|
+
}];
|
|
85373
|
+
/**
|
|
85374
|
+
* Combined list of all deprecated-field rules.
|
|
85375
|
+
*
|
|
85376
|
+
* Order within the list does not affect correctness (the CLI groups by kind
|
|
85377
|
+
* at display time), but a stable order helps test expectations.
|
|
85378
|
+
*/
|
|
85379
|
+
const DEPRECATED_FIELD_RULES = [
|
|
85380
|
+
...REMOVED_RULES,
|
|
85381
|
+
...RENAMED_RULES,
|
|
85382
|
+
...MIGRATED_RULES
|
|
85383
|
+
];
|
|
85384
|
+
//#endregion
|
|
85385
|
+
//#region ../agent-core/src/providers/runtime-provider.ts
|
|
85386
|
+
function resolveRuntimeProvider(input) {
|
|
85387
|
+
const modelName = input.model ?? input.config.defaultModel;
|
|
85388
|
+
if (modelName === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, "No model is selected. Set default_model in config.toml or pass a configured model alias.");
|
|
85389
|
+
const alias = input.config.models?.[modelName];
|
|
85390
|
+
if (alias === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Model "${modelName}" is not configured in config.toml. Add a [models."${modelName}"] entry with max_context_size.`);
|
|
85391
|
+
const resolvedModel = alias.model;
|
|
85392
|
+
const providerName = alias.provider ?? input.config.defaultProvider;
|
|
85393
|
+
const providerConfig = providerName === void 0 ? void 0 : input.config.providers[providerName];
|
|
85394
|
+
if (providerName === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Model "${modelName}" must define a provider in config.toml.`);
|
|
85395
|
+
if (providerConfig === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" for model "${modelName}" is not configured.`);
|
|
85396
|
+
if (!Number.isInteger(alias.maxContextSize) || alias.maxContextSize <= 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Model "${modelName}" must define a positive max_context_size in config.toml.`);
|
|
85397
|
+
if (input.validateCredentials !== false && providerConfig.type !== "vertexai" && providerConfig.oauth === void 0 && providerApiKey(providerConfig) === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" has no credentials configured. Set apiKey, oauth, or a provider env API key in config.toml.`);
|
|
85398
|
+
const provider = toKosongProviderConfig(providerConfig, resolvedModel, input.byfRequestHeaders, alias.maxOutputSize, alias.reasoningKey, input.promptCacheKey);
|
|
85399
|
+
return {
|
|
85400
|
+
modelName,
|
|
85401
|
+
providerName,
|
|
85402
|
+
modelCapabilities: resolveModelCapabilities(alias, provider),
|
|
85403
|
+
provider
|
|
85404
|
+
};
|
|
85405
|
+
}
|
|
85406
|
+
async function resolveRuntimeProviderWithOAuth(input) {
|
|
85407
|
+
const resolved = resolveRuntimeProvider(input);
|
|
85408
|
+
const resolveAuth = createRuntimeProviderAuthResolver(input, resolved);
|
|
85409
|
+
if (resolveAuth === void 0) return resolved;
|
|
85410
|
+
await resolveAuth();
|
|
85411
|
+
return {
|
|
85412
|
+
...resolved,
|
|
85413
|
+
resolveAuth
|
|
85414
|
+
};
|
|
85415
|
+
}
|
|
85416
|
+
function createRuntimeProviderAuthResolver(input, resolved = resolveRuntimeProvider(input)) {
|
|
85417
|
+
const providerName = resolved.providerName;
|
|
85418
|
+
if (providerName === void 0) return void 0;
|
|
85419
|
+
const providerConfig = input.config.providers[providerName];
|
|
85420
|
+
if (providerConfig?.oauth === void 0) return void 0;
|
|
85421
|
+
if (providerApiKey(providerConfig) !== void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" has both apiKey and oauth set in config.toml — they are mutually exclusive. Remove one.`);
|
|
85422
|
+
const tokenProvider = input.resolveOAuthTokenProvider?.(providerName, providerConfig.oauth);
|
|
85423
|
+
if (tokenProvider === void 0) return async () => {
|
|
85424
|
+
throw new ByfError(ErrorCodes.AUTH_LOGIN_REQUIRED, `OAuth provider "${providerName}" requires login before it can be used.`);
|
|
85425
|
+
};
|
|
85426
|
+
return async (options) => {
|
|
85427
|
+
let apiKey;
|
|
85428
|
+
try {
|
|
85429
|
+
apiKey = await tokenProvider.getAccessToken(options?.forceRefresh === true ? { force: true } : void 0);
|
|
85430
|
+
} catch (error) {
|
|
85431
|
+
if (!isAuthLoginRequired(error)) (input.log ?? log).warn("oauth token fetch failed", {
|
|
85432
|
+
providerName,
|
|
85433
|
+
error
|
|
85434
|
+
});
|
|
85435
|
+
throw new ByfError(ErrorCodes.AUTH_LOGIN_REQUIRED, `OAuth provider "${providerName}" requires login before it can be used.`, { cause: error });
|
|
85436
|
+
}
|
|
85437
|
+
if (apiKey.trim().length === 0) throw new ByfError(ErrorCodes.AUTH_LOGIN_REQUIRED, `OAuth provider "${providerName}" requires login before it can be used.`);
|
|
85438
|
+
return { apiKey };
|
|
85439
|
+
};
|
|
85440
|
+
}
|
|
85441
|
+
function isAuthLoginRequired(error) {
|
|
85442
|
+
return isByfError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED;
|
|
85443
|
+
}
|
|
85444
|
+
const CAPABILITY_DEFINITIONS = [
|
|
85445
|
+
{
|
|
85446
|
+
name: "image_in",
|
|
85447
|
+
returnKey: "image_in"
|
|
85448
|
+
},
|
|
85449
|
+
{
|
|
85450
|
+
name: "video_in",
|
|
85451
|
+
returnKey: "video_in"
|
|
85452
|
+
},
|
|
85453
|
+
{
|
|
85454
|
+
name: "audio_in",
|
|
85455
|
+
returnKey: "audio_in"
|
|
85456
|
+
},
|
|
85457
|
+
{
|
|
85458
|
+
name: "thinking",
|
|
85459
|
+
returnKey: "thinking"
|
|
85460
|
+
},
|
|
85461
|
+
{
|
|
85462
|
+
name: "always_thinking",
|
|
85463
|
+
returnKey: "thinking"
|
|
85464
|
+
},
|
|
85465
|
+
{
|
|
85466
|
+
name: "tool_use",
|
|
85467
|
+
returnKey: "tool_use"
|
|
85468
|
+
},
|
|
85469
|
+
{
|
|
85470
|
+
name: "thinking_effort",
|
|
85471
|
+
returnKey: "thinking_effort"
|
|
85472
|
+
},
|
|
85473
|
+
{
|
|
85474
|
+
name: "thinking_xhigh",
|
|
85475
|
+
returnKey: "thinking_xhigh"
|
|
85476
|
+
},
|
|
85477
|
+
{
|
|
85478
|
+
name: "thinking_max",
|
|
85479
|
+
returnKey: "thinking_max"
|
|
85480
|
+
}
|
|
85481
|
+
];
|
|
85482
|
+
/**
|
|
85483
|
+
* The list of every valid capability name that can appear in a model
|
|
85484
|
+
* alias's `capabilities` array.
|
|
85485
|
+
*
|
|
85486
|
+
* Derives directly from {@link CAPABILITY_DEFINITIONS} so that adding a
|
|
85487
|
+
* new capability in one place automatically keeps both the validation
|
|
85488
|
+
* gate (`update-config`) and the runtime resolver in sync.
|
|
85489
|
+
*/
|
|
85490
|
+
const VALID_CAPABILITIES = CAPABILITY_DEFINITIONS.map((d) => d.name);
|
|
85491
|
+
function resolveModelCapabilities(alias, provider) {
|
|
85492
|
+
const capabilities = new Set((alias.capabilities ?? []).map((capability) => capability.trim().toLowerCase()));
|
|
85493
|
+
const has = (capability) => capabilities.has(capability);
|
|
85494
|
+
const providerCapability = createProvider$1(providerForCapabilityProbe(provider)).getCapability?.(provider.model) ?? UNKNOWN_CAPABILITY;
|
|
85495
|
+
const returnKeyToNames = /* @__PURE__ */ new Map();
|
|
85496
|
+
for (const def of CAPABILITY_DEFINITIONS) {
|
|
85497
|
+
const names = returnKeyToNames.get(def.returnKey) ?? [];
|
|
85498
|
+
names.push(def.name);
|
|
85499
|
+
returnKeyToNames.set(def.returnKey, names);
|
|
85500
|
+
}
|
|
85501
|
+
const resolved = {};
|
|
85502
|
+
for (const [returnKey, names] of returnKeyToNames) resolved[returnKey] = names.some((n) => has(n)) || Boolean(providerCapability[returnKey]);
|
|
85503
|
+
return {
|
|
85504
|
+
...resolved,
|
|
85505
|
+
max_context_tokens: alias.maxContextSize
|
|
85506
|
+
};
|
|
85507
|
+
}
|
|
85508
|
+
function toKosongProviderConfig(provider, model, byfRequestHeaders, maxOutputSize, reasoningKey, promptCacheKey) {
|
|
85509
|
+
switch (provider.type) {
|
|
85510
|
+
case "anthropic": return {
|
|
85511
|
+
type: "anthropic",
|
|
85512
|
+
model,
|
|
85513
|
+
baseUrl: providerValue(provider.baseUrl, provider.env, "ANTHROPIC_BASE_URL"),
|
|
85514
|
+
apiKey: providerApiKey(provider),
|
|
85515
|
+
...maxOutputSize !== void 0 ? { defaultMaxTokens: maxOutputSize } : {},
|
|
85516
|
+
...defaultHeadersField(provider.customHeaders)
|
|
85517
|
+
};
|
|
85518
|
+
case "openai-completions": {
|
|
85519
|
+
const defaultHeaders = {
|
|
85520
|
+
...byfRequestHeaders,
|
|
85521
|
+
...provider.customHeaders
|
|
85522
|
+
};
|
|
85523
|
+
const generationKwargs = {
|
|
85524
|
+
prompt_cache_key: promptCacheKey,
|
|
85525
|
+
extra_body: provider.extraBody
|
|
85526
|
+
};
|
|
85527
|
+
if (Object.keys(defaultHeaders).length === 0) return {
|
|
85528
|
+
type: "openai-completions",
|
|
85529
|
+
model,
|
|
85530
|
+
baseUrl: providerValue(provider.baseUrl, provider.env, "BYF_BASE_URL"),
|
|
85531
|
+
reasoningKey,
|
|
85532
|
+
thinkingEffortKey: provider.thinkingEffortKey,
|
|
85533
|
+
generationKwargs,
|
|
85534
|
+
apiKey: providerApiKey(provider)
|
|
85535
|
+
};
|
|
85536
|
+
return {
|
|
85537
|
+
type: "openai-completions",
|
|
85538
|
+
model,
|
|
85539
|
+
baseUrl: providerValue(provider.baseUrl, provider.env, "BYF_BASE_URL"),
|
|
85540
|
+
reasoningKey,
|
|
85541
|
+
thinkingEffortKey: provider.thinkingEffortKey,
|
|
85542
|
+
generationKwargs,
|
|
85543
|
+
defaultHeaders,
|
|
85544
|
+
apiKey: providerApiKey(provider)
|
|
85545
|
+
};
|
|
85546
|
+
}
|
|
85547
|
+
case "google-genai": return {
|
|
85548
|
+
type: "google-genai",
|
|
85549
|
+
model,
|
|
85550
|
+
apiKey: providerApiKey(provider)
|
|
85551
|
+
};
|
|
85552
|
+
case "openai_responses": return {
|
|
85553
|
+
type: "openai_responses",
|
|
85554
|
+
model,
|
|
85555
|
+
baseUrl: providerValue(provider.baseUrl, provider.env, "OPENAI_BASE_URL"),
|
|
85556
|
+
apiKey: providerApiKey(provider),
|
|
85557
|
+
...defaultHeadersField(provider.customHeaders)
|
|
85558
|
+
};
|
|
85559
|
+
case "vertexai": return {
|
|
85560
|
+
type: "vertexai",
|
|
85561
|
+
model,
|
|
85562
|
+
vertexai: hasVertexAIServiceEnv(provider),
|
|
85563
|
+
apiKey: hasVertexAIServiceEnv(provider) ? void 0 : providerApiKey(provider),
|
|
85564
|
+
project: vertexAIProject(provider),
|
|
85565
|
+
location: vertexAILocation(provider)
|
|
85566
|
+
};
|
|
85567
|
+
default: {
|
|
85568
|
+
const exhaustive = provider.type;
|
|
85569
|
+
throw new ByfError(ErrorCodes.MODEL_CONFIG_INVALID, `Unsupported provider type: ${String(exhaustive)}`);
|
|
85570
|
+
}
|
|
85571
|
+
}
|
|
85572
|
+
}
|
|
85573
|
+
function defaultHeadersField(headers) {
|
|
85574
|
+
if (headers === void 0 || Object.keys(headers).length === 0) return {};
|
|
85575
|
+
return { defaultHeaders: { ...headers } };
|
|
85576
|
+
}
|
|
85577
|
+
function providerForCapabilityProbe(provider) {
|
|
85578
|
+
if (provider.type === "vertexai") return {
|
|
85579
|
+
...provider,
|
|
85580
|
+
vertexai: false,
|
|
85581
|
+
project: void 0,
|
|
85582
|
+
location: void 0,
|
|
85583
|
+
apiKey: provider.apiKey === void 0 || provider.apiKey.length === 0 ? "capability-probe" : provider.apiKey
|
|
85584
|
+
};
|
|
85585
|
+
if (provider.apiKey !== void 0 && provider.apiKey.length > 0) return provider;
|
|
85586
|
+
return {
|
|
85587
|
+
...provider,
|
|
85588
|
+
apiKey: "capability-probe"
|
|
85589
|
+
};
|
|
85590
|
+
}
|
|
85591
|
+
function providerApiKey(provider) {
|
|
85592
|
+
switch (provider.type) {
|
|
85593
|
+
case "anthropic": return providerValue(provider.apiKey, provider.env, "ANTHROPIC_API_KEY");
|
|
85594
|
+
case "openai_responses": return providerValue(provider.apiKey, provider.env, "OPENAI_API_KEY");
|
|
85595
|
+
case "openai-completions": return providerValue(provider.apiKey, provider.env, "BYF_API_KEY");
|
|
85596
|
+
case "google-genai": return providerValue(provider.apiKey, provider.env, "GOOGLE_API_KEY");
|
|
85597
|
+
case "vertexai": return nonEmptyString$2(provider.apiKey) ?? envValue(provider.env, "VERTEXAI_API_KEY") ?? envValue(provider.env, "GOOGLE_API_KEY");
|
|
85598
|
+
default: {
|
|
85599
|
+
const exhaustive = provider.type;
|
|
85600
|
+
throw new ByfError(ErrorCodes.MODEL_CONFIG_INVALID, `Unsupported provider type: ${String(exhaustive)}`);
|
|
85601
|
+
}
|
|
85602
|
+
}
|
|
85603
|
+
}
|
|
85604
|
+
function hasVertexAIServiceEnv(provider) {
|
|
85605
|
+
return vertexAIProject(provider) !== void 0 && vertexAILocation(provider) !== void 0;
|
|
85606
|
+
}
|
|
85607
|
+
function vertexAIProject(provider) {
|
|
85608
|
+
return envValue(provider.env, "GOOGLE_CLOUD_PROJECT");
|
|
85609
|
+
}
|
|
85610
|
+
function vertexAILocation(provider) {
|
|
85611
|
+
return envValue(provider.env, "GOOGLE_CLOUD_LOCATION") ?? locationFromVertexAIBaseUrl(provider.baseUrl);
|
|
85612
|
+
}
|
|
85613
|
+
function providerValue(configured, env, envKey) {
|
|
85614
|
+
return nonEmptyString$2(configured) ?? envValue(env, envKey);
|
|
85615
|
+
}
|
|
85616
|
+
function envValue(env, key) {
|
|
85617
|
+
return nonEmptyString$2(env?.[key]);
|
|
85618
|
+
}
|
|
85619
|
+
function nonEmptyString$2(value) {
|
|
85620
|
+
const trimmed = value?.trim();
|
|
85621
|
+
return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
|
|
85622
|
+
}
|
|
85623
|
+
function locationFromVertexAIBaseUrl(baseUrl) {
|
|
85624
|
+
const url = nonEmptyString$2(baseUrl);
|
|
85625
|
+
if (url === void 0) return void 0;
|
|
85626
|
+
try {
|
|
85627
|
+
const host = new URL(url).hostname;
|
|
85628
|
+
return host.endsWith("-aiplatform.googleapis.com") ? nonEmptyString$2(host.slice(0, -26)) : void 0;
|
|
85629
|
+
} catch {
|
|
85630
|
+
return;
|
|
85631
|
+
}
|
|
85632
|
+
}
|
|
85633
|
+
//#endregion
|
|
85634
|
+
//#region ../agent-core/src/config/update.ts
|
|
85635
|
+
/**
|
|
85636
|
+
* Scan a parsed config (including `config.raw`) and return all Findings
|
|
85637
|
+
* for deprecated / renamed / migrated / dangling / unknown / invalid-value
|
|
85638
|
+
* fields.
|
|
85639
|
+
*
|
|
85640
|
+
* This is a **pure** function — no file I/O, no side effects.
|
|
85641
|
+
*
|
|
85642
|
+
* Detection is based on `config.raw` (the clone of the original TOML data),
|
|
85643
|
+
* not on the parsed camelCase schema. This matches the PRD's observation
|
|
85644
|
+
* that `raw` is both the protection layer (preserving unknown fields) and
|
|
85645
|
+
* the blind spot (retaining stale keys through read→write cycles).
|
|
85646
|
+
*/
|
|
85647
|
+
function analyzeConfig(config) {
|
|
85648
|
+
const raw = config.raw;
|
|
85649
|
+
const findings = [];
|
|
85650
|
+
if (isRecord$2(raw)) {
|
|
85651
|
+
for (const rule of DEPRECATED_FIELD_RULES) if (pathExistsInRaw(raw, rule.pathParts)) findings.push({
|
|
85652
|
+
kind: rule.kind,
|
|
85653
|
+
path: rule.path,
|
|
85654
|
+
detail: rule.detail,
|
|
85655
|
+
deprecatedSince: rule.deprecatedSince
|
|
85656
|
+
});
|
|
85657
|
+
const defaultThinkingFinding = findings.find((f) => f.path === "default_thinking");
|
|
85658
|
+
if (defaultThinkingFinding) {
|
|
85659
|
+
const thinking = config.thinking;
|
|
85660
|
+
if (thinking && (thinking.mode !== void 0 || thinking.effort !== void 0)) {
|
|
85661
|
+
defaultThinkingFinding.kind = "removed";
|
|
85662
|
+
defaultThinkingFinding.detail = "Already superseded by [thinking] block.";
|
|
85663
|
+
}
|
|
85664
|
+
}
|
|
85665
|
+
const UNKNOWN_SKIP_PATHS = new Set(DEPRECATED_FIELD_RULES.map((r) => r.pathParts.join(".")));
|
|
85666
|
+
const byfShapeKeys = /* @__PURE__ */ new Set();
|
|
85667
|
+
for (const key of Object.keys(ByfConfigSchema.shape)) {
|
|
85668
|
+
byfShapeKeys.add(key);
|
|
85669
|
+
byfShapeKeys.add(camelToSnakeStatic(key));
|
|
85670
|
+
}
|
|
85671
|
+
for (const rawKey of Object.keys(raw)) {
|
|
85672
|
+
if (rawKey === "raw") continue;
|
|
85673
|
+
if (UNKNOWN_SKIP_PATHS.has(rawKey)) continue;
|
|
85674
|
+
const camelKey = snakeToCamelStatic(rawKey);
|
|
85675
|
+
if (!byfShapeKeys.has(camelKey) && !byfShapeKeys.has(rawKey)) findings.push({
|
|
85676
|
+
kind: "unknown",
|
|
85677
|
+
path: rawKey,
|
|
85678
|
+
detail: `Field "${rawKey}" is not recognized by the current schema. Its value has been ignored. This may be a typo or a field from a previous version.`
|
|
85679
|
+
});
|
|
85680
|
+
}
|
|
85681
|
+
const nestedFindings = scanNestedUnknowns(raw, UNKNOWN_SKIP_PATHS);
|
|
85682
|
+
findings.push(...nestedFindings);
|
|
85683
|
+
}
|
|
85684
|
+
if (config.models) {
|
|
85685
|
+
const validCapsLower = new Set(VALID_CAPABILITIES.map((c) => c.toLowerCase()));
|
|
85686
|
+
for (const [alias, modelConfig] of Object.entries(config.models)) if (modelConfig.capabilities) for (let i = 0; i < modelConfig.capabilities.length; i++) {
|
|
85687
|
+
const cap = modelConfig.capabilities[i];
|
|
85688
|
+
if (cap === void 0) continue;
|
|
85689
|
+
if (!validCapsLower.has(cap.toLowerCase())) findings.push({
|
|
85690
|
+
kind: "invalid-value",
|
|
85691
|
+
path: `models.${alias}.capabilities[${i}]`,
|
|
85692
|
+
detail: `"${cap}" is not a valid capability. Valid values: ${VALID_CAPABILITIES.join(", ")}.`
|
|
85693
|
+
});
|
|
85694
|
+
}
|
|
85695
|
+
}
|
|
85696
|
+
const providerKeys = Object.keys(config.providers ?? {});
|
|
85697
|
+
if (config.models) {
|
|
85698
|
+
for (const [alias, modelConfig] of Object.entries(config.models)) if (!providerKeys.includes(modelConfig.provider)) findings.push({
|
|
85699
|
+
kind: "dangling",
|
|
85700
|
+
path: `models.${alias}.provider`,
|
|
85701
|
+
detail: `Model alias "${alias}" references provider "${modelConfig.provider}", which does not exist in [providers].`
|
|
85702
|
+
});
|
|
85703
|
+
}
|
|
85704
|
+
if (config.defaultProvider !== void 0 && !providerKeys.includes(config.defaultProvider)) findings.push({
|
|
85705
|
+
kind: "dangling",
|
|
85706
|
+
path: "default_provider",
|
|
85707
|
+
detail: `Default provider "${config.defaultProvider}" does not exist in [providers].`
|
|
85708
|
+
});
|
|
85709
|
+
const modelKeys = Object.keys(config.models ?? {});
|
|
85710
|
+
if (config.defaultModel !== void 0 && !modelKeys.includes(config.defaultModel)) findings.push({
|
|
85711
|
+
kind: "dangling",
|
|
85712
|
+
path: "default_model",
|
|
85713
|
+
detail: `Default model "${config.defaultModel}" does not exist in [models].`
|
|
85714
|
+
});
|
|
85715
|
+
return findings;
|
|
85716
|
+
}
|
|
85717
|
+
/**
|
|
85718
|
+
* Apply automatic fixes to a `ByfConfig` by deleting every path registered in
|
|
85719
|
+
* `DEPRECATED_FIELD_RULES` from `config.raw`.
|
|
85720
|
+
*
|
|
85721
|
+
* The `_findings` parameter is intentionally **not consulted** — deletion is
|
|
85722
|
+
* driven exclusively by the whitelist in `DEPRECATED_FIELD_RULES`. This ensures
|
|
85723
|
+
* that a call to `applyFixes` always produces a clean config regardless of
|
|
85724
|
+
* what analysis step previously ran.
|
|
85725
|
+
*
|
|
85726
|
+
* This is a **pure** function — it returns a new config object without
|
|
85727
|
+
* mutating the input.
|
|
85728
|
+
*/
|
|
85729
|
+
function applyFixes(config, findings) {
|
|
85730
|
+
const newRaw = rawShallowClone(config.raw);
|
|
85731
|
+
for (const rule of DEPRECATED_FIELD_RULES) deletePath(newRaw, rule.pathParts);
|
|
85732
|
+
let newConfig = {
|
|
85733
|
+
...config,
|
|
85734
|
+
raw: newRaw
|
|
85735
|
+
};
|
|
85736
|
+
if (findings.find((f) => f.kind === "migrated" && f.path === "default_thinking")) {
|
|
85737
|
+
const rawValue = config.raw?.["default_thinking"];
|
|
85738
|
+
const isTruthy = rawValue === true || rawValue === "true" || rawValue === 1;
|
|
85739
|
+
newConfig = {
|
|
85740
|
+
...newConfig,
|
|
85741
|
+
thinking: isTruthy ? {
|
|
85742
|
+
mode: "on",
|
|
85743
|
+
effort: "high"
|
|
85744
|
+
} : { mode: "off" }
|
|
85745
|
+
};
|
|
85746
|
+
}
|
|
85747
|
+
return newConfig;
|
|
85748
|
+
}
|
|
85749
|
+
/** Convert snake_case to camelCase (static helper for unknown detection). */
|
|
85750
|
+
function snakeToCamelStatic(str) {
|
|
85751
|
+
return str.replaceAll(/_([a-z])/g, (_, ch) => ch.toUpperCase());
|
|
85752
|
+
}
|
|
85753
|
+
/** Convert camelCase to snake_case (static helper for unknown detection). */
|
|
85754
|
+
function camelToSnakeStatic(str) {
|
|
85755
|
+
return str.replaceAll(/[A-Z]/g, (ch) => `_${ch.toLowerCase()}`);
|
|
85756
|
+
}
|
|
85757
|
+
/** True when `value` is a non-null, non-array object. */
|
|
85758
|
+
function isRecord$2(value) {
|
|
85759
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
85760
|
+
}
|
|
85761
|
+
/**
|
|
85762
|
+
* Walk `root` along `pathParts` checking that **every** segment exists.
|
|
85763
|
+
*
|
|
85764
|
+
* Returns `true` iff all parts exist as own keys (or inherited keys — TOML
|
|
85765
|
+
* parse results are plain objects so the distinction doesn't matter here).
|
|
85766
|
+
*/
|
|
85767
|
+
function pathExistsInRaw(root, pathParts) {
|
|
85768
|
+
let current = root;
|
|
85769
|
+
for (const part of pathParts) {
|
|
85770
|
+
if (!isRecord$2(current) || !(part in current)) return false;
|
|
85771
|
+
current = current[part];
|
|
85772
|
+
}
|
|
85773
|
+
return true;
|
|
85774
|
+
}
|
|
85775
|
+
/**
|
|
85776
|
+
* Delete a leaf (or entire sub-tree) from `root` following `pathParts`.
|
|
85777
|
+
*
|
|
85778
|
+
* If the parent after deletion becomes empty it is cleaned up as well
|
|
85779
|
+
* (recursive upward), so that a service table cleared of all deprecated
|
|
85780
|
+
* keys does not leave behind an empty `{}`.
|
|
85781
|
+
*/
|
|
85782
|
+
function deletePath(root, pathParts) {
|
|
85783
|
+
if (pathParts.length === 0) return;
|
|
85784
|
+
const parentParts = pathParts.slice(0, -1);
|
|
85785
|
+
const leafKey = pathParts.at(-1);
|
|
85786
|
+
let current;
|
|
85787
|
+
if (parentParts.length === 0) current = root;
|
|
85788
|
+
else current = traverseTo(root, parentParts);
|
|
85789
|
+
if (current === void 0) return;
|
|
85790
|
+
const keyExisted = leafKey in current;
|
|
85791
|
+
delete current[leafKey];
|
|
85792
|
+
if (keyExisted && parentParts.length > 0 && Object.keys(current).length === 0) deletePath(root, parentParts);
|
|
85793
|
+
}
|
|
85794
|
+
/**
|
|
85795
|
+
* Walk `root` along `pathParts` returning the penultimate record, or
|
|
85796
|
+
* `undefined` if any segment is missing.
|
|
85797
|
+
*/
|
|
85798
|
+
function traverseTo(root, pathParts) {
|
|
85799
|
+
let current = root;
|
|
85800
|
+
for (const part of pathParts) {
|
|
85801
|
+
if (!isRecord$2(current) || !(part in current)) return void 0;
|
|
85802
|
+
current = current[part];
|
|
85803
|
+
}
|
|
85804
|
+
return isRecord$2(current) ? current : void 0;
|
|
85805
|
+
}
|
|
85806
|
+
/**
|
|
85807
|
+
* Shallow-clone `raw`: each nested record is also shallow-cloned so that
|
|
85808
|
+
* mutations in `applyFixes` do not affect the original object.
|
|
85809
|
+
*/
|
|
85810
|
+
function rawShallowClone(raw) {
|
|
85811
|
+
if (!isRecord$2(raw)) return {};
|
|
85812
|
+
const clone = {};
|
|
85813
|
+
for (const [key, value] of Object.entries(raw)) clone[key] = isRecord$2(value) ? { ...value } : value;
|
|
85814
|
+
return clone;
|
|
85815
|
+
}
|
|
85816
|
+
/**
|
|
85817
|
+
* Build a set of all valid keys (camelCase + snake_case) from a zod
|
|
85818
|
+
* object schema's `.shape`.
|
|
85819
|
+
*/
|
|
85820
|
+
function getShapeKeySet(schema) {
|
|
85821
|
+
const keys = /* @__PURE__ */ new Set();
|
|
85822
|
+
for (const key of Object.keys(schema.shape)) {
|
|
85823
|
+
keys.add(key);
|
|
85824
|
+
keys.add(camelToSnakeStatic(key));
|
|
85825
|
+
}
|
|
85826
|
+
return keys;
|
|
85827
|
+
}
|
|
85828
|
+
/**
|
|
85829
|
+
* Scan known container keys in `raw` for sub-keys that don't match the
|
|
85830
|
+
* corresponding schema shape. Unknown paths that overlap with
|
|
85831
|
+
* `skipPaths` (e.g. already reported deprecated fields) are skipped.
|
|
85832
|
+
*
|
|
85833
|
+
* Detects e.g. `models.gpt4.max_context_tokns` (typo) or
|
|
85834
|
+
* `providers.anthropic.api_kei` (typo).
|
|
85835
|
+
*/
|
|
85836
|
+
function scanNestedUnknowns(raw, skipPaths) {
|
|
85837
|
+
const findings = [];
|
|
85838
|
+
const containers = [
|
|
85839
|
+
{
|
|
85840
|
+
rawKey: "models",
|
|
85841
|
+
isRecord: true,
|
|
85842
|
+
schema: ModelAliasSchema
|
|
85843
|
+
},
|
|
85844
|
+
{
|
|
85845
|
+
rawKey: "providers",
|
|
85846
|
+
isRecord: true,
|
|
85847
|
+
schema: ProviderConfigSchema
|
|
85848
|
+
},
|
|
85849
|
+
{
|
|
85850
|
+
rawKey: "services",
|
|
85851
|
+
isRecord: false,
|
|
85852
|
+
schema: ServicesConfigSchema
|
|
85853
|
+
},
|
|
85854
|
+
{
|
|
85855
|
+
rawKey: "background",
|
|
85856
|
+
isRecord: false,
|
|
85857
|
+
schema: BackgroundConfigSchema
|
|
85858
|
+
},
|
|
85859
|
+
{
|
|
85860
|
+
rawKey: "loop_control",
|
|
85861
|
+
isRecord: false,
|
|
85862
|
+
schema: LoopControlSchema
|
|
85863
|
+
},
|
|
85864
|
+
{
|
|
85865
|
+
rawKey: "thinking",
|
|
85866
|
+
isRecord: false,
|
|
85867
|
+
schema: ThinkingConfigSchema
|
|
85868
|
+
},
|
|
85869
|
+
{
|
|
85870
|
+
rawKey: "permission",
|
|
85871
|
+
isRecord: false,
|
|
85872
|
+
schema: PermissionConfigSchema,
|
|
85873
|
+
legacyKeys: [
|
|
85874
|
+
"deny",
|
|
85875
|
+
"allow",
|
|
85876
|
+
"ask"
|
|
85877
|
+
]
|
|
85878
|
+
}
|
|
85879
|
+
];
|
|
85880
|
+
const schemaKeySets = /* @__PURE__ */ new Map();
|
|
85881
|
+
containers.forEach((entry, index) => {
|
|
85882
|
+
const base = getShapeKeySet(entry.schema);
|
|
85883
|
+
if (entry.legacyKeys) for (const k of entry.legacyKeys) base.add(k);
|
|
85884
|
+
schemaKeySets.set(index, base);
|
|
85885
|
+
});
|
|
85886
|
+
for (const [entryIndex, entry] of containers.entries()) {
|
|
85887
|
+
if (!(entry.rawKey in raw)) continue;
|
|
85888
|
+
const rawValue = raw[entry.rawKey];
|
|
85889
|
+
if (!isRecord$2(rawValue)) continue;
|
|
85890
|
+
if (entry.isRecord) for (const [itemKey, itemValue] of Object.entries(rawValue)) {
|
|
85891
|
+
if (!isRecord$2(itemValue)) continue;
|
|
85892
|
+
const validKeys = schemaKeySets.get(entryIndex);
|
|
85893
|
+
for (const subKey of Object.keys(itemValue)) if (!validKeys.has(subKey)) {
|
|
85894
|
+
const path = `${entry.rawKey}.${itemKey}.${subKey}`;
|
|
85895
|
+
if (!skipPaths.has(path)) findings.push({
|
|
85896
|
+
kind: "unknown",
|
|
85897
|
+
path,
|
|
85898
|
+
detail: `Field "${subKey}" is not recognized in ${entry.rawKey}.${itemKey}. This may be a typo or a field from a previous version.`
|
|
85899
|
+
});
|
|
85900
|
+
}
|
|
85901
|
+
}
|
|
85902
|
+
else {
|
|
85903
|
+
const validKeys = schemaKeySets.get(entryIndex);
|
|
85904
|
+
for (const subKey of Object.keys(rawValue)) if (!validKeys.has(subKey)) {
|
|
85905
|
+
const path = `${entry.rawKey}.${subKey}`;
|
|
85906
|
+
if (!skipPaths.has(path)) findings.push({
|
|
85907
|
+
kind: "unknown",
|
|
85908
|
+
path,
|
|
85909
|
+
detail: `Field "${subKey}" is not recognized in [${entry.rawKey}]. This may be a typo or a field from a previous version.`
|
|
85910
|
+
});
|
|
85911
|
+
}
|
|
85912
|
+
}
|
|
85913
|
+
}
|
|
85914
|
+
return findings;
|
|
85915
|
+
}
|
|
85916
|
+
//#endregion
|
|
85293
85917
|
//#region ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
85294
85918
|
function isZ4Schema(s) {
|
|
85295
85919
|
return !!s._zod;
|
|
@@ -90026,14 +90650,14 @@ var LocalKaos = class {
|
|
|
90026
90650
|
}
|
|
90027
90651
|
}
|
|
90028
90652
|
async writeBytes(path, data) {
|
|
90029
|
-
await writeFile
|
|
90653
|
+
await writeFile(this._resolvePath(path), data);
|
|
90030
90654
|
return data.length;
|
|
90031
90655
|
}
|
|
90032
90656
|
async writeText(path, data, options) {
|
|
90033
90657
|
const resolved = this._resolvePath(path);
|
|
90034
90658
|
const encoding = options?.encoding ?? "utf-8";
|
|
90035
90659
|
if ((options?.mode ?? "w") === "a") await appendFile(resolved, data, encoding);
|
|
90036
|
-
else await writeFile
|
|
90660
|
+
else await writeFile(resolved, data, encoding);
|
|
90037
90661
|
return data.length;
|
|
90038
90662
|
}
|
|
90039
90663
|
async mkdir(path, options) {
|
|
@@ -125212,11 +125836,15 @@ function createProxiedFetch(deps) {
|
|
|
125212
125836
|
const proxyUrl = getProxyForUrl(url, envLookup, sysProxy);
|
|
125213
125837
|
const noProxyMatch = noProxy !== void 0 && isNoProxyHost(hostname, noProxy);
|
|
125214
125838
|
const controller = new AbortController();
|
|
125215
|
-
const timeoutId = setTimeout(() =>
|
|
125839
|
+
const timeoutId = setTimeout(() => {
|
|
125840
|
+
controller.abort();
|
|
125841
|
+
}, REQUEST_TIMEOUT_MS);
|
|
125216
125842
|
if (init?.signal) if (init.signal.aborted) {
|
|
125217
125843
|
clearTimeout(timeoutId);
|
|
125218
125844
|
controller.abort();
|
|
125219
|
-
} else init.signal.addEventListener("abort", () =>
|
|
125845
|
+
} else init.signal.addEventListener("abort", () => {
|
|
125846
|
+
controller.abort();
|
|
125847
|
+
}, { once: true });
|
|
125220
125848
|
const mergedInit = {
|
|
125221
125849
|
...init,
|
|
125222
125850
|
signal: controller.signal
|
|
@@ -125228,7 +125856,7 @@ function createProxiedFetch(deps) {
|
|
|
125228
125856
|
return response;
|
|
125229
125857
|
} catch (error) {
|
|
125230
125858
|
clearTimeout(timeoutId);
|
|
125231
|
-
if (isRetryableError(error) && proxyUrl && !noProxyMatch) return
|
|
125859
|
+
if (isRetryableError(error) && proxyUrl && !noProxyMatch) return retryViaProxy(input, init, proxyUrl, innerFetch);
|
|
125232
125860
|
throw error;
|
|
125233
125861
|
}
|
|
125234
125862
|
};
|
|
@@ -125236,11 +125864,15 @@ function createProxiedFetch(deps) {
|
|
|
125236
125864
|
}
|
|
125237
125865
|
async function retryViaProxy(input, init, proxyUrl, innerFetch) {
|
|
125238
125866
|
const controller = new AbortController();
|
|
125239
|
-
const timeoutId = setTimeout(() =>
|
|
125867
|
+
const timeoutId = setTimeout(() => {
|
|
125868
|
+
controller.abort();
|
|
125869
|
+
}, REQUEST_TIMEOUT_MS);
|
|
125240
125870
|
if (init?.signal) if (init.signal.aborted) {
|
|
125241
125871
|
clearTimeout(timeoutId);
|
|
125242
125872
|
controller.abort();
|
|
125243
|
-
} else init.signal.addEventListener("abort", () =>
|
|
125873
|
+
} else init.signal.addEventListener("abort", () => {
|
|
125874
|
+
controller.abort();
|
|
125875
|
+
}, { once: true });
|
|
125244
125876
|
const dispatcher = new import_undici.ProxyAgent(proxyUrl);
|
|
125245
125877
|
const retryInit = {
|
|
125246
125878
|
...init,
|
|
@@ -125390,82 +126022,188 @@ var RemoteFetchURLProvider = class {
|
|
|
125390
126022
|
}
|
|
125391
126023
|
};
|
|
125392
126024
|
//#endregion
|
|
125393
|
-
//#region ../agent-core/src/tools/providers/
|
|
125394
|
-
var
|
|
125395
|
-
|
|
125396
|
-
|
|
126025
|
+
//#region ../agent-core/src/tools/providers/router.ts
|
|
126026
|
+
var AllProvidersFailedError = class extends Error {
|
|
126027
|
+
lastError;
|
|
126028
|
+
constructor(lastError) {
|
|
126029
|
+
super(`All search providers failed. Last error: ${lastError ?? "unknown"}`);
|
|
126030
|
+
this.lastError = lastError;
|
|
126031
|
+
this.name = "AllProvidersFailedError";
|
|
126032
|
+
}
|
|
126033
|
+
};
|
|
126034
|
+
var PriorityRouter = class {
|
|
126035
|
+
providers;
|
|
126036
|
+
constructor(providers) {
|
|
126037
|
+
this.providers = providers;
|
|
126038
|
+
}
|
|
126039
|
+
async search(query, options) {
|
|
126040
|
+
let lastError;
|
|
126041
|
+
for (const provider of this.providers) try {
|
|
126042
|
+
return await provider.search(query, options);
|
|
126043
|
+
} catch (error) {
|
|
126044
|
+
lastError = error instanceof Error ? error.message : String(error);
|
|
126045
|
+
}
|
|
126046
|
+
throw new AllProvidersFailedError(lastError);
|
|
126047
|
+
}
|
|
126048
|
+
};
|
|
126049
|
+
//#endregion
|
|
126050
|
+
//#region ../agent-core/src/tools/providers/exa.ts
|
|
126051
|
+
var ExaWebSearchProvider = class {
|
|
126052
|
+
apiKeys;
|
|
125397
126053
|
baseUrl;
|
|
125398
|
-
defaultHeaders;
|
|
125399
|
-
customHeaders;
|
|
125400
126054
|
fetchImpl;
|
|
125401
126055
|
constructor(options) {
|
|
125402
|
-
this.
|
|
125403
|
-
this.
|
|
125404
|
-
this.baseUrl = options.baseUrl;
|
|
125405
|
-
this.defaultHeaders = options.defaultHeaders ?? {};
|
|
125406
|
-
this.customHeaders = options.customHeaders ?? {};
|
|
126056
|
+
this.apiKeys = options.apiKeys;
|
|
126057
|
+
this.baseUrl = options.baseUrl ?? "https://api.exa.ai/search";
|
|
125407
126058
|
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
125408
126059
|
}
|
|
125409
126060
|
async search(query, options) {
|
|
125410
|
-
const
|
|
125411
|
-
|
|
125412
|
-
|
|
125413
|
-
|
|
125414
|
-
|
|
126061
|
+
const limit = options?.limit ?? 5;
|
|
126062
|
+
const includeContent = options?.includeContent ?? false;
|
|
126063
|
+
const contents = {};
|
|
126064
|
+
if (includeContent) contents.text = { maxCharacters: 1e4 };
|
|
126065
|
+
else contents.highlights = {
|
|
126066
|
+
query,
|
|
126067
|
+
maxCharacters: 300
|
|
125415
126068
|
};
|
|
125416
|
-
const
|
|
125417
|
-
|
|
125418
|
-
|
|
125419
|
-
|
|
125420
|
-
throw new Error(`Remote search request failed: HTTP 401 (auth/unauthorized). ${detail}`.trim());
|
|
125421
|
-
}
|
|
125422
|
-
if (response.status !== 200) {
|
|
125423
|
-
const detail = await safeReadText(response);
|
|
125424
|
-
throw new Error(`Remote search request failed: HTTP ${String(response.status)}. ${detail}`.trim());
|
|
125425
|
-
}
|
|
125426
|
-
const json = await response.json();
|
|
125427
|
-
return (Array.isArray(json.search_results) ? json.search_results : []).map((r) => {
|
|
125428
|
-
const out = {
|
|
125429
|
-
title: r.title ?? "",
|
|
125430
|
-
url: r.url ?? "",
|
|
125431
|
-
snippet: r.snippet ?? ""
|
|
125432
|
-
};
|
|
125433
|
-
if (typeof r.date === "string" && r.date.length > 0) out.date = r.date;
|
|
125434
|
-
if (typeof r.content === "string" && r.content.length > 0) out.content = r.content;
|
|
125435
|
-
return out;
|
|
126069
|
+
const body = JSON.stringify({
|
|
126070
|
+
query,
|
|
126071
|
+
numResults: limit,
|
|
126072
|
+
contents
|
|
125436
126073
|
});
|
|
126074
|
+
let lastError;
|
|
126075
|
+
for (const apiKey of this.apiKeys) try {
|
|
126076
|
+
const response = await this.fetchImpl(this.baseUrl, {
|
|
126077
|
+
method: "POST",
|
|
126078
|
+
headers: {
|
|
126079
|
+
Authorization: `Bearer ${apiKey}`,
|
|
126080
|
+
"Content-Type": "application/json"
|
|
126081
|
+
},
|
|
126082
|
+
body
|
|
126083
|
+
});
|
|
126084
|
+
if (!response.ok) {
|
|
126085
|
+
const detail = (await response.text().catch(() => "")).slice(0, 200);
|
|
126086
|
+
throw new Error(`Exa search failed: HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
|
|
126087
|
+
}
|
|
126088
|
+
const json = await response.json();
|
|
126089
|
+
return (Array.isArray(json.results) ? json.results : []).map((r) => {
|
|
126090
|
+
const out = {
|
|
126091
|
+
title: r.title ?? "",
|
|
126092
|
+
url: r.url ?? "",
|
|
126093
|
+
snippet: ""
|
|
126094
|
+
};
|
|
126095
|
+
if (includeContent && typeof r.text === "string") {
|
|
126096
|
+
out.snippet = r.text.slice(0, 300);
|
|
126097
|
+
if (r.text.length > 0) out.content = r.text;
|
|
126098
|
+
} else if (Array.isArray(r.highlights) && r.highlights.length > 0) out.snippet = r.highlights[0].slice(0, 300);
|
|
126099
|
+
if (typeof r.publishedDate === "string" && r.publishedDate.length > 0) out.date = r.publishedDate;
|
|
126100
|
+
return out;
|
|
126101
|
+
});
|
|
126102
|
+
} catch (error) {
|
|
126103
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
126104
|
+
}
|
|
126105
|
+
throw lastError ?? /* @__PURE__ */ new Error("Exa search failed: no API keys configured");
|
|
125437
126106
|
}
|
|
125438
|
-
|
|
125439
|
-
|
|
125440
|
-
|
|
125441
|
-
|
|
125442
|
-
|
|
125443
|
-
|
|
125444
|
-
|
|
125445
|
-
|
|
125446
|
-
|
|
125447
|
-
|
|
125448
|
-
|
|
125449
|
-
|
|
126107
|
+
};
|
|
126108
|
+
registerProvider("exa", ExaWebSearchProvider);
|
|
126109
|
+
//#endregion
|
|
126110
|
+
//#region ../agent-core/src/tools/providers/brave.ts
|
|
126111
|
+
var BraveWebSearchProvider = class {
|
|
126112
|
+
apiKeys;
|
|
126113
|
+
baseUrl;
|
|
126114
|
+
fetchImpl;
|
|
126115
|
+
constructor(options) {
|
|
126116
|
+
this.apiKeys = options.apiKeys;
|
|
126117
|
+
this.baseUrl = options.baseUrl ?? "https://api.search.brave.com/res/v1/web/search";
|
|
126118
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
125450
126119
|
}
|
|
125451
|
-
async
|
|
125452
|
-
|
|
125453
|
-
|
|
126120
|
+
async search(query, options) {
|
|
126121
|
+
const limit = options?.limit ?? 5;
|
|
126122
|
+
const url = new URL(this.baseUrl);
|
|
126123
|
+
url.searchParams.set("q", query);
|
|
126124
|
+
url.searchParams.set("count", String(limit));
|
|
126125
|
+
let lastError;
|
|
126126
|
+
for (const apiKey of this.apiKeys) try {
|
|
126127
|
+
const response = await this.fetchImpl(url.toString(), {
|
|
126128
|
+
method: "GET",
|
|
126129
|
+
headers: {
|
|
126130
|
+
"Accept": "application/json",
|
|
126131
|
+
"Accept-Encoding": "gzip",
|
|
126132
|
+
"X-Subscription-Token": apiKey
|
|
126133
|
+
}
|
|
126134
|
+
});
|
|
126135
|
+
if (!response.ok) {
|
|
126136
|
+
const detail = (await response.text().catch(() => "")).slice(0, 200);
|
|
126137
|
+
throw new Error(`Brave search failed: HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
|
|
126138
|
+
}
|
|
126139
|
+
const json = await response.json();
|
|
126140
|
+
return (Array.isArray(json.web?.results) ? json.web.results : []).map((r) => {
|
|
126141
|
+
const out = {
|
|
126142
|
+
title: r.title ?? "",
|
|
126143
|
+
url: r.url ?? "",
|
|
126144
|
+
snippet: r.description ?? ""
|
|
126145
|
+
};
|
|
126146
|
+
if (typeof r.age === "string" && r.age.length > 0) out.date = r.age;
|
|
126147
|
+
return out;
|
|
126148
|
+
});
|
|
125454
126149
|
} catch (error) {
|
|
125455
|
-
|
|
125456
|
-
throw error;
|
|
126150
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
125457
126151
|
}
|
|
125458
|
-
|
|
125459
|
-
throw new Error("Remote search service is not configured: missing API key or token provider.");
|
|
126152
|
+
throw lastError ?? /* @__PURE__ */ new Error("Brave search failed: no API keys configured");
|
|
125460
126153
|
}
|
|
125461
126154
|
};
|
|
125462
|
-
|
|
125463
|
-
|
|
125464
|
-
|
|
125465
|
-
|
|
125466
|
-
|
|
126155
|
+
registerProvider("brave", BraveWebSearchProvider);
|
|
126156
|
+
//#endregion
|
|
126157
|
+
//#region ../agent-core/src/tools/providers/firecrawl.ts
|
|
126158
|
+
var FirecrawlWebSearchProvider = class {
|
|
126159
|
+
apiKeys;
|
|
126160
|
+
baseUrl;
|
|
126161
|
+
fetchImpl;
|
|
126162
|
+
constructor(options) {
|
|
126163
|
+
this.apiKeys = options.apiKeys;
|
|
126164
|
+
this.baseUrl = options.baseUrl ?? "https://api.firecrawl.dev/v2/search";
|
|
126165
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
125467
126166
|
}
|
|
125468
|
-
|
|
126167
|
+
async search(query, options) {
|
|
126168
|
+
const limit = options?.limit ?? 5;
|
|
126169
|
+
const includeContent = options?.includeContent ?? false;
|
|
126170
|
+
const requestBody = {
|
|
126171
|
+
query,
|
|
126172
|
+
limit
|
|
126173
|
+
};
|
|
126174
|
+
if (includeContent) requestBody.scrapeOptions = { formats: ["markdown"] };
|
|
126175
|
+
const body = JSON.stringify(requestBody);
|
|
126176
|
+
let lastError;
|
|
126177
|
+
for (const apiKey of this.apiKeys) try {
|
|
126178
|
+
const response = await this.fetchImpl(this.baseUrl, {
|
|
126179
|
+
method: "POST",
|
|
126180
|
+
headers: {
|
|
126181
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
126182
|
+
"Content-Type": "application/json"
|
|
126183
|
+
},
|
|
126184
|
+
body
|
|
126185
|
+
});
|
|
126186
|
+
if (!response.ok) {
|
|
126187
|
+
const detail = (await response.text().catch(() => "")).slice(0, 200);
|
|
126188
|
+
throw new Error(`Firecrawl search failed: HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
|
|
126189
|
+
}
|
|
126190
|
+
const json = await response.json();
|
|
126191
|
+
return (Array.isArray(json.data?.web) ? json.data.web : []).map((r) => {
|
|
126192
|
+
const out = {
|
|
126193
|
+
title: r.title ?? "",
|
|
126194
|
+
url: r.url ?? "",
|
|
126195
|
+
snippet: r.description ?? ""
|
|
126196
|
+
};
|
|
126197
|
+
if (includeContent && typeof r.markdown === "string" && r.markdown.length > 0) out.content = r.markdown;
|
|
126198
|
+
return out;
|
|
126199
|
+
});
|
|
126200
|
+
} catch (error) {
|
|
126201
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
126202
|
+
}
|
|
126203
|
+
throw lastError ?? /* @__PURE__ */ new Error("Firecrawl search failed: no API keys configured");
|
|
126204
|
+
}
|
|
126205
|
+
};
|
|
126206
|
+
registerProvider("firecrawl", FirecrawlWebSearchProvider);
|
|
125469
126207
|
//#endregion
|
|
125470
126208
|
//#region ../agent-core/src/utils/environment.ts
|
|
125471
126209
|
/**
|
|
@@ -125727,15 +126465,6 @@ var SessionAPIImpl = class {
|
|
|
125727
126465
|
getModel({ agentId, ...payload }) {
|
|
125728
126466
|
return this.getAgent(agentId).getModel(payload);
|
|
125729
126467
|
}
|
|
125730
|
-
enterPlan({ agentId, ...payload }) {
|
|
125731
|
-
return this.getAgent(agentId).enterPlan(payload);
|
|
125732
|
-
}
|
|
125733
|
-
cancelPlan({ agentId, ...payload }) {
|
|
125734
|
-
return this.getAgent(agentId).cancelPlan(payload);
|
|
125735
|
-
}
|
|
125736
|
-
clearPlan({ agentId, ...payload }) {
|
|
125737
|
-
return this.getAgent(agentId).clearPlan(payload);
|
|
125738
|
-
}
|
|
125739
126468
|
beginCompaction({ agentId, ...payload }) {
|
|
125740
126469
|
return this.getAgent(agentId).beginCompaction(payload);
|
|
125741
126470
|
}
|
|
@@ -125776,9 +126505,6 @@ var SessionAPIImpl = class {
|
|
|
125776
126505
|
getPermission({ agentId, ...payload }) {
|
|
125777
126506
|
return this.getAgent(agentId).getPermission(payload);
|
|
125778
126507
|
}
|
|
125779
|
-
getPlan({ agentId, ...payload }) {
|
|
125780
|
-
return this.getAgent(agentId).getPlan(payload);
|
|
125781
|
-
}
|
|
125782
126508
|
getUsage({ agentId, ...payload }) {
|
|
125783
126509
|
return this.getAgent(agentId).getUsage(payload);
|
|
125784
126510
|
}
|
|
@@ -125998,7 +126724,7 @@ async function writeExportZip(args) {
|
|
|
125998
126724
|
entries.push(extra.target);
|
|
125999
126725
|
} catch {}
|
|
126000
126726
|
zip.end();
|
|
126001
|
-
await pipeline$1(zip.outputStream, createWriteStream
|
|
126727
|
+
await pipeline$1(zip.outputStream, createWriteStream(args.outputPath));
|
|
126002
126728
|
return entries;
|
|
126003
126729
|
}
|
|
126004
126730
|
//#endregion
|
|
@@ -126057,207 +126783,6 @@ async function readOptionalFile(path) {
|
|
|
126057
126783
|
}
|
|
126058
126784
|
}
|
|
126059
126785
|
//#endregion
|
|
126060
|
-
//#region ../agent-core/src/providers/runtime-provider.ts
|
|
126061
|
-
function resolveRuntimeProvider(input) {
|
|
126062
|
-
const modelName = input.model ?? input.config.defaultModel;
|
|
126063
|
-
if (modelName === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, "No model is selected. Set default_model in config.toml or pass a configured model alias.");
|
|
126064
|
-
const alias = input.config.models?.[modelName];
|
|
126065
|
-
if (alias === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Model "${modelName}" is not configured in config.toml. Add a [models."${modelName}"] entry with max_context_size.`);
|
|
126066
|
-
const resolvedModel = alias.model;
|
|
126067
|
-
const providerName = alias.provider ?? input.config.defaultProvider;
|
|
126068
|
-
const providerConfig = providerName === void 0 ? void 0 : input.config.providers[providerName];
|
|
126069
|
-
if (providerName === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Model "${modelName}" must define a provider in config.toml.`);
|
|
126070
|
-
if (providerConfig === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" for model "${modelName}" is not configured.`);
|
|
126071
|
-
if (!Number.isInteger(alias.maxContextSize) || alias.maxContextSize <= 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Model "${modelName}" must define a positive max_context_size in config.toml.`);
|
|
126072
|
-
if (input.validateCredentials !== false && providerConfig.type !== "vertexai" && providerConfig.oauth === void 0 && providerApiKey(providerConfig) === void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" has no credentials configured. Set apiKey, oauth, or a provider env API key in config.toml.`);
|
|
126073
|
-
const provider = toKosongProviderConfig(providerConfig, resolvedModel, input.byfRequestHeaders, alias.maxOutputSize, alias.reasoningKey, input.promptCacheKey);
|
|
126074
|
-
return {
|
|
126075
|
-
modelName,
|
|
126076
|
-
providerName,
|
|
126077
|
-
modelCapabilities: resolveModelCapabilities(alias, provider),
|
|
126078
|
-
provider
|
|
126079
|
-
};
|
|
126080
|
-
}
|
|
126081
|
-
async function resolveRuntimeProviderWithOAuth(input) {
|
|
126082
|
-
const resolved = resolveRuntimeProvider(input);
|
|
126083
|
-
const resolveAuth = createRuntimeProviderAuthResolver(input, resolved);
|
|
126084
|
-
if (resolveAuth === void 0) return resolved;
|
|
126085
|
-
await resolveAuth();
|
|
126086
|
-
return {
|
|
126087
|
-
...resolved,
|
|
126088
|
-
resolveAuth
|
|
126089
|
-
};
|
|
126090
|
-
}
|
|
126091
|
-
function createRuntimeProviderAuthResolver(input, resolved = resolveRuntimeProvider(input)) {
|
|
126092
|
-
const providerName = resolved.providerName;
|
|
126093
|
-
if (providerName === void 0) return void 0;
|
|
126094
|
-
const providerConfig = input.config.providers[providerName];
|
|
126095
|
-
if (providerConfig?.oauth === void 0) return void 0;
|
|
126096
|
-
if (providerApiKey(providerConfig) !== void 0) throw new ByfError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" has both apiKey and oauth set in config.toml — they are mutually exclusive. Remove one.`);
|
|
126097
|
-
const tokenProvider = input.resolveOAuthTokenProvider?.(providerName, providerConfig.oauth);
|
|
126098
|
-
if (tokenProvider === void 0) return async () => {
|
|
126099
|
-
throw new ByfError(ErrorCodes.AUTH_LOGIN_REQUIRED, `OAuth provider "${providerName}" requires login before it can be used.`);
|
|
126100
|
-
};
|
|
126101
|
-
return async (options) => {
|
|
126102
|
-
let apiKey;
|
|
126103
|
-
try {
|
|
126104
|
-
apiKey = await tokenProvider.getAccessToken(options?.forceRefresh === true ? { force: true } : void 0);
|
|
126105
|
-
} catch (error) {
|
|
126106
|
-
if (!isAuthLoginRequired(error)) (input.log ?? log).warn("oauth token fetch failed", {
|
|
126107
|
-
providerName,
|
|
126108
|
-
error
|
|
126109
|
-
});
|
|
126110
|
-
throw new ByfError(ErrorCodes.AUTH_LOGIN_REQUIRED, `OAuth provider "${providerName}" requires login before it can be used.`, { cause: error });
|
|
126111
|
-
}
|
|
126112
|
-
if (apiKey.trim().length === 0) throw new ByfError(ErrorCodes.AUTH_LOGIN_REQUIRED, `OAuth provider "${providerName}" requires login before it can be used.`);
|
|
126113
|
-
return { apiKey };
|
|
126114
|
-
};
|
|
126115
|
-
}
|
|
126116
|
-
function isAuthLoginRequired(error) {
|
|
126117
|
-
return isByfError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED;
|
|
126118
|
-
}
|
|
126119
|
-
function resolveModelCapabilities(alias, provider) {
|
|
126120
|
-
const capabilities = new Set((alias.capabilities ?? []).map((capability) => capability.trim().toLowerCase()));
|
|
126121
|
-
const has = (capability) => capabilities.has(capability);
|
|
126122
|
-
const providerCapability = createProvider(providerForCapabilityProbe(provider)).getCapability?.(provider.model) ?? UNKNOWN_CAPABILITY;
|
|
126123
|
-
return {
|
|
126124
|
-
image_in: has("image_in") || providerCapability.image_in,
|
|
126125
|
-
video_in: has("video_in") || providerCapability.video_in,
|
|
126126
|
-
audio_in: has("audio_in") || providerCapability.audio_in,
|
|
126127
|
-
thinking: has("thinking") || has("always_thinking") || providerCapability.thinking,
|
|
126128
|
-
tool_use: has("tool_use") || providerCapability.tool_use,
|
|
126129
|
-
thinking_effort: has("thinking_effort") || providerCapability.thinking_effort,
|
|
126130
|
-
thinking_xhigh: has("thinking_xhigh") || providerCapability.thinking_xhigh,
|
|
126131
|
-
thinking_max: has("thinking_max") || providerCapability.thinking_max,
|
|
126132
|
-
max_context_tokens: alias.maxContextSize
|
|
126133
|
-
};
|
|
126134
|
-
}
|
|
126135
|
-
function toKosongProviderConfig(provider, model, byfRequestHeaders, maxOutputSize, reasoningKey, promptCacheKey) {
|
|
126136
|
-
switch (provider.type) {
|
|
126137
|
-
case "anthropic": return {
|
|
126138
|
-
type: "anthropic",
|
|
126139
|
-
model,
|
|
126140
|
-
baseUrl: providerValue(provider.baseUrl, provider.env, "ANTHROPIC_BASE_URL"),
|
|
126141
|
-
apiKey: providerApiKey(provider),
|
|
126142
|
-
...maxOutputSize !== void 0 ? { defaultMaxTokens: maxOutputSize } : {},
|
|
126143
|
-
...defaultHeadersField(provider.customHeaders)
|
|
126144
|
-
};
|
|
126145
|
-
case "openai-completions": {
|
|
126146
|
-
const defaultHeaders = {
|
|
126147
|
-
...byfRequestHeaders,
|
|
126148
|
-
...provider.customHeaders
|
|
126149
|
-
};
|
|
126150
|
-
const generationKwargs = {
|
|
126151
|
-
prompt_cache_key: promptCacheKey,
|
|
126152
|
-
extra_body: provider.extraBody
|
|
126153
|
-
};
|
|
126154
|
-
if (Object.keys(defaultHeaders).length === 0) return {
|
|
126155
|
-
type: "openai-completions",
|
|
126156
|
-
model,
|
|
126157
|
-
baseUrl: providerValue(provider.baseUrl, provider.env, "BYF_BASE_URL"),
|
|
126158
|
-
reasoningKey,
|
|
126159
|
-
thinkingEffortKey: provider.thinkingEffortKey,
|
|
126160
|
-
generationKwargs,
|
|
126161
|
-
apiKey: providerApiKey(provider)
|
|
126162
|
-
};
|
|
126163
|
-
return {
|
|
126164
|
-
type: "openai-completions",
|
|
126165
|
-
model,
|
|
126166
|
-
baseUrl: providerValue(provider.baseUrl, provider.env, "BYF_BASE_URL"),
|
|
126167
|
-
reasoningKey,
|
|
126168
|
-
thinkingEffortKey: provider.thinkingEffortKey,
|
|
126169
|
-
generationKwargs,
|
|
126170
|
-
defaultHeaders,
|
|
126171
|
-
apiKey: providerApiKey(provider)
|
|
126172
|
-
};
|
|
126173
|
-
}
|
|
126174
|
-
case "google-genai": return {
|
|
126175
|
-
type: "google-genai",
|
|
126176
|
-
model,
|
|
126177
|
-
apiKey: providerApiKey(provider)
|
|
126178
|
-
};
|
|
126179
|
-
case "openai_responses": return {
|
|
126180
|
-
type: "openai_responses",
|
|
126181
|
-
model,
|
|
126182
|
-
baseUrl: providerValue(provider.baseUrl, provider.env, "OPENAI_BASE_URL"),
|
|
126183
|
-
apiKey: providerApiKey(provider),
|
|
126184
|
-
...defaultHeadersField(provider.customHeaders)
|
|
126185
|
-
};
|
|
126186
|
-
case "vertexai": return {
|
|
126187
|
-
type: "vertexai",
|
|
126188
|
-
model,
|
|
126189
|
-
vertexai: hasVertexAIServiceEnv(provider),
|
|
126190
|
-
apiKey: hasVertexAIServiceEnv(provider) ? void 0 : providerApiKey(provider),
|
|
126191
|
-
project: vertexAIProject(provider),
|
|
126192
|
-
location: vertexAILocation(provider)
|
|
126193
|
-
};
|
|
126194
|
-
default: {
|
|
126195
|
-
const exhaustive = provider.type;
|
|
126196
|
-
throw new ByfError(ErrorCodes.MODEL_CONFIG_INVALID, `Unsupported provider type: ${String(exhaustive)}`);
|
|
126197
|
-
}
|
|
126198
|
-
}
|
|
126199
|
-
}
|
|
126200
|
-
function defaultHeadersField(headers) {
|
|
126201
|
-
if (headers === void 0 || Object.keys(headers).length === 0) return {};
|
|
126202
|
-
return { defaultHeaders: { ...headers } };
|
|
126203
|
-
}
|
|
126204
|
-
function providerForCapabilityProbe(provider) {
|
|
126205
|
-
if (provider.type === "vertexai") return {
|
|
126206
|
-
...provider,
|
|
126207
|
-
vertexai: false,
|
|
126208
|
-
project: void 0,
|
|
126209
|
-
location: void 0,
|
|
126210
|
-
apiKey: provider.apiKey === void 0 || provider.apiKey.length === 0 ? "capability-probe" : provider.apiKey
|
|
126211
|
-
};
|
|
126212
|
-
if (provider.apiKey !== void 0 && provider.apiKey.length > 0) return provider;
|
|
126213
|
-
return {
|
|
126214
|
-
...provider,
|
|
126215
|
-
apiKey: "capability-probe"
|
|
126216
|
-
};
|
|
126217
|
-
}
|
|
126218
|
-
function providerApiKey(provider) {
|
|
126219
|
-
switch (provider.type) {
|
|
126220
|
-
case "anthropic": return providerValue(provider.apiKey, provider.env, "ANTHROPIC_API_KEY");
|
|
126221
|
-
case "openai_responses": return providerValue(provider.apiKey, provider.env, "OPENAI_API_KEY");
|
|
126222
|
-
case "openai-completions": return providerValue(provider.apiKey, provider.env, "BYF_API_KEY");
|
|
126223
|
-
case "google-genai": return providerValue(provider.apiKey, provider.env, "GOOGLE_API_KEY");
|
|
126224
|
-
case "vertexai": return nonEmptyString$2(provider.apiKey) ?? envValue(provider.env, "VERTEXAI_API_KEY") ?? envValue(provider.env, "GOOGLE_API_KEY");
|
|
126225
|
-
default: {
|
|
126226
|
-
const exhaustive = provider.type;
|
|
126227
|
-
throw new ByfError(ErrorCodes.MODEL_CONFIG_INVALID, `Unsupported provider type: ${String(exhaustive)}`);
|
|
126228
|
-
}
|
|
126229
|
-
}
|
|
126230
|
-
}
|
|
126231
|
-
function hasVertexAIServiceEnv(provider) {
|
|
126232
|
-
return vertexAIProject(provider) !== void 0 && vertexAILocation(provider) !== void 0;
|
|
126233
|
-
}
|
|
126234
|
-
function vertexAIProject(provider) {
|
|
126235
|
-
return envValue(provider.env, "GOOGLE_CLOUD_PROJECT");
|
|
126236
|
-
}
|
|
126237
|
-
function vertexAILocation(provider) {
|
|
126238
|
-
return envValue(provider.env, "GOOGLE_CLOUD_LOCATION") ?? locationFromVertexAIBaseUrl(provider.baseUrl);
|
|
126239
|
-
}
|
|
126240
|
-
function providerValue(configured, env, envKey) {
|
|
126241
|
-
return nonEmptyString$2(configured) ?? envValue(env, envKey);
|
|
126242
|
-
}
|
|
126243
|
-
function envValue(env, key) {
|
|
126244
|
-
return nonEmptyString$2(env?.[key]);
|
|
126245
|
-
}
|
|
126246
|
-
function nonEmptyString$2(value) {
|
|
126247
|
-
const trimmed = value?.trim();
|
|
126248
|
-
return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
|
|
126249
|
-
}
|
|
126250
|
-
function locationFromVertexAIBaseUrl(baseUrl) {
|
|
126251
|
-
const url = nonEmptyString$2(baseUrl);
|
|
126252
|
-
if (url === void 0) return void 0;
|
|
126253
|
-
try {
|
|
126254
|
-
const host = new URL(url).hostname;
|
|
126255
|
-
return host.endsWith("-aiplatform.googleapis.com") ? nonEmptyString$2(host.slice(0, -26)) : void 0;
|
|
126256
|
-
} catch {
|
|
126257
|
-
return;
|
|
126258
|
-
}
|
|
126259
|
-
}
|
|
126260
|
-
//#endregion
|
|
126261
126786
|
//#region ../agent-core/src/providers/provider-manager.ts
|
|
126262
126787
|
var ProviderManager = class ProviderManager {
|
|
126263
126788
|
options;
|
|
@@ -126518,7 +127043,7 @@ var SessionStore = class {
|
|
|
126518
127043
|
title: normalized,
|
|
126519
127044
|
isCustomTitle: true
|
|
126520
127045
|
};
|
|
126521
|
-
await writeFile
|
|
127046
|
+
await writeFile(statePath, `${JSON.stringify(next, null, 2)}\n`, "utf-8");
|
|
126522
127047
|
}
|
|
126523
127048
|
async list(options) {
|
|
126524
127049
|
const workDir = normalizeWorkDir(options.workDir);
|
|
@@ -126573,7 +127098,7 @@ var SessionStore = class {
|
|
|
126573
127098
|
agents: rewriteAgentHomedirs(parsed["agents"], sourceDir, targetDir),
|
|
126574
127099
|
custom: Object.assign({}, isRecord$1(parsed["custom"]) ? parsed["custom"] : {}, input.metadata)
|
|
126575
127100
|
};
|
|
126576
|
-
await writeFile
|
|
127101
|
+
await writeFile(statePath, `${JSON.stringify(next, null, 2)}\n`, "utf-8");
|
|
126577
127102
|
}
|
|
126578
127103
|
async summaryFromDir(id, sessionDir, workDir) {
|
|
126579
127104
|
const dirStat = await stat(sessionDir);
|
|
@@ -126936,15 +127461,6 @@ var ByfCore = class {
|
|
|
126936
127461
|
getModel({ sessionId, ...payload }) {
|
|
126937
127462
|
return this.sessionApi(sessionId).getModel(payload);
|
|
126938
127463
|
}
|
|
126939
|
-
enterPlan({ sessionId, ...payload }) {
|
|
126940
|
-
return this.sessionApi(sessionId).enterPlan(payload);
|
|
126941
|
-
}
|
|
126942
|
-
cancelPlan({ sessionId, ...payload }) {
|
|
126943
|
-
return this.sessionApi(sessionId).cancelPlan(payload);
|
|
126944
|
-
}
|
|
126945
|
-
clearPlan({ sessionId, ...payload }) {
|
|
126946
|
-
return this.sessionApi(sessionId).clearPlan(payload);
|
|
126947
|
-
}
|
|
126948
127464
|
beginCompaction({ sessionId, ...payload }) {
|
|
126949
127465
|
return this.sessionApi(sessionId).beginCompaction(payload);
|
|
126950
127466
|
}
|
|
@@ -126984,9 +127500,6 @@ var ByfCore = class {
|
|
|
126984
127500
|
getPermission({ sessionId, ...payload }) {
|
|
126985
127501
|
return this.sessionApi(sessionId).getPermission(payload);
|
|
126986
127502
|
}
|
|
126987
|
-
getPlan({ sessionId, ...payload }) {
|
|
126988
|
-
return this.sessionApi(sessionId).getPlan(payload);
|
|
126989
|
-
}
|
|
126990
127503
|
getUsage({ sessionId, ...payload }) {
|
|
126991
127504
|
return this.sessionApi(sessionId).getUsage(payload);
|
|
126992
127505
|
}
|
|
@@ -127074,8 +127587,8 @@ async function createRuntimeConfig(input) {
|
|
|
127074
127587
|
systemProxy: () => detectSystemProxy()
|
|
127075
127588
|
});
|
|
127076
127589
|
const localFetcher = new LocalFetchURLProvider({ fetchImpl: proxiedFetch });
|
|
127077
|
-
const
|
|
127078
|
-
const
|
|
127590
|
+
const fetchService = input.config.services?.fetchUrl;
|
|
127591
|
+
const webSearchConfig = input.config.services?.webSearch;
|
|
127079
127592
|
return {
|
|
127080
127593
|
kaos: localKaos,
|
|
127081
127594
|
osEnv: await detectEnvironmentFromNode(),
|
|
@@ -127087,12 +127600,11 @@ async function createRuntimeConfig(input) {
|
|
|
127087
127600
|
fetchImpl: proxiedFetch,
|
|
127088
127601
|
...serviceCredentials(fetchService, input.resolveOAuthTokenProvider)
|
|
127089
127602
|
}),
|
|
127090
|
-
webSearcher:
|
|
127091
|
-
|
|
127092
|
-
|
|
127093
|
-
fetchImpl: proxiedFetch
|
|
127094
|
-
|
|
127095
|
-
})
|
|
127603
|
+
webSearcher: webSearchConfig === void 0 ? void 0 : new PriorityRouter([...webSearchConfig.providers].toSorted((a, b) => a.priority - b.priority).map((p) => createProvider(p.type, {
|
|
127604
|
+
apiKeys: p.apiKeys,
|
|
127605
|
+
baseUrl: p.baseUrl,
|
|
127606
|
+
fetchImpl: proxiedFetch
|
|
127607
|
+
})))
|
|
127096
127608
|
};
|
|
127097
127609
|
}
|
|
127098
127610
|
function serviceCredentials(service, resolveOAuthTokenProvider) {
|
|
@@ -127127,7 +127639,6 @@ async function resumeSessionResult(summary, session, warning) {
|
|
|
127127
127639
|
context,
|
|
127128
127640
|
replay: agent.replayBuilder.buildResult(),
|
|
127129
127641
|
permission,
|
|
127130
|
-
plan: null,
|
|
127131
127642
|
usage,
|
|
127132
127643
|
tools: await api.getTools({ agentId }),
|
|
127133
127644
|
toolStore: agent.tools.storeData(),
|
|
@@ -127228,7 +127739,8 @@ var SDKRpcClient = class {
|
|
|
127228
127739
|
this.core = new ByfCore(coreRpc, {
|
|
127229
127740
|
homeDir: options.homeDir,
|
|
127230
127741
|
configPath: options.configPath,
|
|
127231
|
-
skillDirs: options.skillDirs
|
|
127742
|
+
skillDirs: options.skillDirs,
|
|
127743
|
+
runtime: options.runtime
|
|
127232
127744
|
});
|
|
127233
127745
|
this.ready = sdkRpc(new ClientAPI(this)).then((rpc) => {
|
|
127234
127746
|
this.rpc = rpc;
|
|
@@ -127327,18 +127839,6 @@ var SDKRpcClient = class {
|
|
|
127327
127839
|
mode: input.mode
|
|
127328
127840
|
});
|
|
127329
127841
|
}
|
|
127330
|
-
async getPlan(input) {
|
|
127331
|
-
return (await this.getRpc()).getPlan({
|
|
127332
|
-
sessionId: input.sessionId,
|
|
127333
|
-
agentId: this.interactiveAgentId
|
|
127334
|
-
});
|
|
127335
|
-
}
|
|
127336
|
-
async clearPlan(input) {
|
|
127337
|
-
await (await this.getRpc()).clearPlan({
|
|
127338
|
-
sessionId: input.sessionId,
|
|
127339
|
-
agentId: this.interactiveAgentId
|
|
127340
|
-
});
|
|
127341
|
-
}
|
|
127342
127842
|
async compact(input) {
|
|
127343
127843
|
return (await this.getRpc()).beginCompaction({
|
|
127344
127844
|
sessionId: input.sessionId,
|
|
@@ -127495,7 +127995,7 @@ var SDKRpcClient = class {
|
|
|
127495
127995
|
type: "error",
|
|
127496
127996
|
sessionId: request.sessionId,
|
|
127497
127997
|
agentId: request.agentId,
|
|
127498
|
-
...makeErrorPayload(ErrorCodes.SESSION_APPROVAL_HANDLER_ERROR, errorMessage(error))
|
|
127998
|
+
...makeErrorPayload(ErrorCodes.SESSION_APPROVAL_HANDLER_ERROR, errorMessage$1(error))
|
|
127499
127999
|
});
|
|
127500
128000
|
return {
|
|
127501
128001
|
decision: "cancelled",
|
|
@@ -127513,7 +128013,7 @@ var SDKRpcClient = class {
|
|
|
127513
128013
|
type: "error",
|
|
127514
128014
|
sessionId: request.sessionId,
|
|
127515
128015
|
agentId: request.agentId,
|
|
127516
|
-
...makeErrorPayload(ErrorCodes.SESSION_QUESTION_HANDLER_ERROR, errorMessage(error))
|
|
128016
|
+
...makeErrorPayload(ErrorCodes.SESSION_QUESTION_HANDLER_ERROR, errorMessage$1(error))
|
|
127517
128017
|
});
|
|
127518
128018
|
return null;
|
|
127519
128019
|
}
|
|
@@ -127548,7 +128048,7 @@ var ClientAPI = class {
|
|
|
127548
128048
|
return this.client.toolCall(request);
|
|
127549
128049
|
}
|
|
127550
128050
|
};
|
|
127551
|
-
function errorMessage(error) {
|
|
128051
|
+
function errorMessage$1(error) {
|
|
127552
128052
|
return error instanceof Error ? error.message : String(error);
|
|
127553
128053
|
}
|
|
127554
128054
|
//#endregion
|
|
@@ -127644,13 +128144,6 @@ var Session = class {
|
|
|
127644
128144
|
mode
|
|
127645
128145
|
});
|
|
127646
128146
|
}
|
|
127647
|
-
async getPlan() {
|
|
127648
|
-
this.ensureOpen();
|
|
127649
|
-
return null;
|
|
127650
|
-
}
|
|
127651
|
-
async clearPlan() {
|
|
127652
|
-
this.ensureOpen();
|
|
127653
|
-
}
|
|
127654
128147
|
async compact(options = {}) {
|
|
127655
128148
|
this.ensureOpen();
|
|
127656
128149
|
const instruction = normalizeOptionalString(options.instruction);
|
|
@@ -127857,7 +128350,8 @@ var ByfHarness = class {
|
|
|
127857
128350
|
this.rpc = new SDKRpcClient({
|
|
127858
128351
|
homeDir: options.homeDir,
|
|
127859
128352
|
configPath: this.configPath,
|
|
127860
|
-
skillDirs: options.skillDirs
|
|
128353
|
+
skillDirs: options.skillDirs,
|
|
128354
|
+
runtime: options.runtime
|
|
127861
128355
|
});
|
|
127862
128356
|
}
|
|
127863
128357
|
configureLogging() {
|
|
@@ -127872,7 +128366,7 @@ var ByfHarness = class {
|
|
|
127872
128366
|
set interactiveAgentId(agentId) {
|
|
127873
128367
|
this.rpc.interactiveAgentId = agentId;
|
|
127874
128368
|
}
|
|
127875
|
-
track(
|
|
128369
|
+
track(_event, _properties) {}
|
|
127876
128370
|
async createSession(options) {
|
|
127877
128371
|
const summary = await this.rpc.createSession(options);
|
|
127878
128372
|
const session = new Session({
|
|
@@ -127954,6 +128448,38 @@ var ByfHarness = class {
|
|
|
127954
128448
|
async removeProvider(providerId) {
|
|
127955
128449
|
return this.rpc.removeProvider(providerId);
|
|
127956
128450
|
}
|
|
128451
|
+
async updateConfig(input = {}) {
|
|
128452
|
+
const configPath = input.configPath ?? this.configPath;
|
|
128453
|
+
if (!existsSync(configPath)) return {
|
|
128454
|
+
findings: [],
|
|
128455
|
+
fixed: false
|
|
128456
|
+
};
|
|
128457
|
+
const config = readConfigFile(configPath);
|
|
128458
|
+
const findings = analyzeConfig(config);
|
|
128459
|
+
if (!input.fix || findings.length === 0) return {
|
|
128460
|
+
findings,
|
|
128461
|
+
fixed: false
|
|
128462
|
+
};
|
|
128463
|
+
const backupPath = `${configPath}.bak.${(/* @__PURE__ */ new Date()).toISOString().replaceAll(/[:.]/g, "-")}`;
|
|
128464
|
+
await copyFile(configPath, backupPath);
|
|
128465
|
+
await chmod(backupPath, 384);
|
|
128466
|
+
try {
|
|
128467
|
+
await writeConfigFile(configPath, applyFixes(config, findings));
|
|
128468
|
+
readConfigFile(configPath);
|
|
128469
|
+
return {
|
|
128470
|
+
findings,
|
|
128471
|
+
fixed: true,
|
|
128472
|
+
backupPath
|
|
128473
|
+
};
|
|
128474
|
+
} catch (error) {
|
|
128475
|
+
try {
|
|
128476
|
+
await copyFile(backupPath, configPath);
|
|
128477
|
+
} catch (rollbackError) {
|
|
128478
|
+
throw new Error(`[update-config] Rollback failed: could not restore backup at ${backupPath}. Original error: ${errorMessage(error)}. Rollback error: ${errorMessage(rollbackError)}.`, { cause: rollbackError });
|
|
128479
|
+
}
|
|
128480
|
+
throw error;
|
|
128481
|
+
}
|
|
128482
|
+
}
|
|
127957
128483
|
async shellExec(command, options = {}) {
|
|
127958
128484
|
const normalizedCommand = command.trim();
|
|
127959
128485
|
if (normalizedCommand.length === 0) throw new ByfError(ErrorCodes.REQUEST_INVALID, "Shell command cannot be empty.");
|
|
@@ -127984,6 +128510,9 @@ function normalizeSessionId(value) {
|
|
|
127984
128510
|
if (normalized.length === 0) throw new ByfError(ErrorCodes.SESSION_ID_EMPTY, "Session id cannot be empty.");
|
|
127985
128511
|
return normalized;
|
|
127986
128512
|
}
|
|
128513
|
+
function errorMessage(error) {
|
|
128514
|
+
return error instanceof Error ? error.message : String(error);
|
|
128515
|
+
}
|
|
127987
128516
|
//#endregion
|
|
127988
128517
|
//#region src/catalog.ts
|
|
127989
128518
|
const DEFAULT_CATALOG_URL = "https://models.dev/api.json";
|