openmausbot 0.1.74 → 0.1.76
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/assets/index-BtT047dk.css +1 -0
- package/dist/assets/{index-CwoQdM0z.js → index-C6blGSq5.js} +1 -1
- package/dist/assets/index-fKXFpB_J.js +305 -0
- package/dist/index.html +2 -2
- package/dist-server/companion/src/routes.js +6 -2
- package/dist-server/drivers/agents-proxy.js +133 -11
- package/dist-server/index.js +3379 -1431
- package/dist-server/mcp-gate.js +28 -18
- package/dist-server/openmausbot.js +557 -325
- package/dist-server/pair-cli.js +557 -325
- package/dist-server/permission-proxy.js +119 -14
- package/dist-server/server/agent-tool-policy.js +1 -0
- package/dist-server/server/atomic.js +37 -1
- package/dist-server/server/auto-approve.js +15 -0
- package/dist-server/server/bot-overview.js +5 -1
- package/dist-server/server/chief-of-staff.js +17 -12
- package/dist-server/server/delegations.js +177 -63
- package/dist-server/server/drivers/acp/core.js +2 -1
- package/dist-server/server/drivers/acp/grok.js +12 -1
- package/dist-server/server/drivers/acp/hermes.js +21 -3
- package/dist-server/server/drivers/agents-proxy.js +113 -10
- package/dist-server/server/drivers/claude.js +91 -17
- package/dist-server/server/drivers/codex.js +15 -4
- package/dist-server/server/drivers/openai-chat.js +90 -67
- package/dist-server/server/drivers/openai-compat.js +9 -1
- package/dist-server/server/drivers/pi.js +18 -3
- package/dist-server/server/drivers/retry.js +4 -0
- package/dist-server/server/env-path.js +18 -17
- package/dist-server/server/index.js +1172 -302
- package/dist-server/server/message-db.js +21 -0
- package/dist-server/server/peer-roster.js +48 -9
- package/dist-server/server/permission-proxy.js +90 -15
- package/dist-server/server/procs.js +19 -3
- package/dist-server/server/room-handoffs.js +237 -0
- package/dist-server/server/section-context.js +64 -14
- package/dist-server/server/setup-mode.js +6 -7
- package/dist-server/server/store.js +266 -8
- package/dist-server/server/surface.js +16 -5
- package/dist-server/server/team-backup.js +17 -1
- package/dist-server/server/team-setup-requests.js +252 -0
- package/dist-server/server/thread-events.js +10 -1
- package/dist-server/server/turn-dispatch-guard.js +31 -3
- package/dist-server/server/workspace.js +13 -0
- package/dist-server/shared/approval-mode.js +7 -0
- package/dist-server/shared/ask-question.js +172 -0
- package/dist-server/shared/provider-safety.js +6 -0
- package/dist-server/shared/team-backup.js +1 -0
- package/dist-server/shared/team-setup.js +1 -0
- package/package.json +1 -1
- package/dist/assets/index-BRLHsQ5g.js +0 -298
- package/dist/assets/index-ByLQ7a3F.css +0 -1
|
@@ -1113,6 +1113,21 @@ var require_main = __commonJS({
|
|
|
1113
1113
|
// server/atomic.ts
|
|
1114
1114
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
1115
1115
|
import { closeSync, fsyncSync, openSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
1116
|
+
function sleepSync(ms) {
|
|
1117
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
1118
|
+
}
|
|
1119
|
+
function renameWithRetry(tmp, path3, rename2 = renameSync) {
|
|
1120
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
1121
|
+
try {
|
|
1122
|
+
rename2(tmp, path3);
|
|
1123
|
+
return;
|
|
1124
|
+
} catch (e) {
|
|
1125
|
+
const code = e.code;
|
|
1126
|
+
if (!code || !RETRYABLE_RENAME_CODES.has(code) || attempt >= RENAME_RETRY_DELAYS_MS.length) throw e;
|
|
1127
|
+
sleepSync(RENAME_RETRY_DELAYS_MS[attempt]);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1116
1131
|
function writeFileAtomic(path3, data, options = {}) {
|
|
1117
1132
|
const tmp = `${path3}.${process.pid}.${randomUUID3()}.tmp`;
|
|
1118
1133
|
let fd = null;
|
|
@@ -1122,7 +1137,7 @@ function writeFileAtomic(path3, data, options = {}) {
|
|
|
1122
1137
|
fsyncSync(fd);
|
|
1123
1138
|
closeSync(fd);
|
|
1124
1139
|
fd = null;
|
|
1125
|
-
|
|
1140
|
+
renameWithRetry(tmp, path3);
|
|
1126
1141
|
} catch (e) {
|
|
1127
1142
|
if (fd !== null) {
|
|
1128
1143
|
try {
|
|
@@ -1137,9 +1152,12 @@ function writeFileAtomic(path3, data, options = {}) {
|
|
|
1137
1152
|
throw e;
|
|
1138
1153
|
}
|
|
1139
1154
|
}
|
|
1155
|
+
var RENAME_RETRY_DELAYS_MS, RETRYABLE_RENAME_CODES;
|
|
1140
1156
|
var init_atomic = __esm({
|
|
1141
1157
|
"server/atomic.ts"() {
|
|
1142
1158
|
"use strict";
|
|
1159
|
+
RENAME_RETRY_DELAYS_MS = [5, 10, 20, 40, 80];
|
|
1160
|
+
RETRYABLE_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY"]);
|
|
1143
1161
|
}
|
|
1144
1162
|
});
|
|
1145
1163
|
|
|
@@ -9752,8 +9770,8 @@ var capitalizeFirstCharacter, error28;
|
|
|
9752
9770
|
var init_lt = __esm({
|
|
9753
9771
|
"node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/lt.js"() {
|
|
9754
9772
|
init_util();
|
|
9755
|
-
capitalizeFirstCharacter = (
|
|
9756
|
-
return
|
|
9773
|
+
capitalizeFirstCharacter = (text4) => {
|
|
9774
|
+
return text4.charAt(0).toUpperCase() + text4.slice(1);
|
|
9757
9775
|
};
|
|
9758
9776
|
error28 = () => {
|
|
9759
9777
|
const Sizable = {
|
|
@@ -17585,8 +17603,8 @@ var init_mcp_registry = __esm({
|
|
|
17585
17603
|
});
|
|
17586
17604
|
|
|
17587
17605
|
// server/schema.ts
|
|
17588
|
-
function parseJson(
|
|
17589
|
-
return JSON.parse(
|
|
17606
|
+
function parseJson(text4) {
|
|
17607
|
+
return JSON.parse(text4);
|
|
17590
17608
|
}
|
|
17591
17609
|
function schemaIssue(error51, fallback) {
|
|
17592
17610
|
const issue2 = error51.issues[0];
|
|
@@ -18609,45 +18627,46 @@ function isFile(p) {
|
|
|
18609
18627
|
return false;
|
|
18610
18628
|
}
|
|
18611
18629
|
}
|
|
18612
|
-
function whichWin(cli) {
|
|
18613
|
-
const exts = (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
|
|
18630
|
+
function whichWin(cli, env) {
|
|
18631
|
+
const exts = ((env ?? process.env).PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
|
|
18614
18632
|
const probe = (base2) => {
|
|
18615
18633
|
const order = extname(base2) ? [base2, ...exts.map((e) => base2 + e)] : [...exts.map((e) => base2 + e), base2];
|
|
18616
18634
|
return order.find(isFile) ?? null;
|
|
18617
18635
|
};
|
|
18618
18636
|
if (/[\\/]/.test(cli) || /^[a-zA-Z]:/.test(cli)) return probe(cli);
|
|
18619
|
-
|
|
18637
|
+
const path3 = env ? env.PATH ?? env.Path ?? "" : augmentedPath();
|
|
18638
|
+
for (const dir of path3.split(delimiter3)) {
|
|
18620
18639
|
if (!dir) continue;
|
|
18621
18640
|
const hit = probe(join9(dir, cli));
|
|
18622
18641
|
if (hit) return hit;
|
|
18623
18642
|
}
|
|
18624
18643
|
return null;
|
|
18625
18644
|
}
|
|
18626
|
-
function nodeExe(near) {
|
|
18645
|
+
function nodeExe(near, env) {
|
|
18627
18646
|
const local = join9(near, "node.exe");
|
|
18628
18647
|
if (isFile(local)) return local;
|
|
18629
|
-
const onPath2 = whichWin("node.exe");
|
|
18648
|
+
const onPath2 = whichWin("node.exe", env);
|
|
18630
18649
|
if (onPath2 && extname(onPath2).toLowerCase() === ".exe") return onPath2;
|
|
18631
18650
|
return process.versions.electron ? null : process.execPath;
|
|
18632
18651
|
}
|
|
18633
|
-
function parseCmdShim(shim) {
|
|
18634
|
-
let
|
|
18652
|
+
function parseCmdShim(shim, env) {
|
|
18653
|
+
let text4;
|
|
18635
18654
|
try {
|
|
18636
|
-
|
|
18655
|
+
text4 = readFileSync6(shim, "utf8");
|
|
18637
18656
|
} catch {
|
|
18638
18657
|
return null;
|
|
18639
18658
|
}
|
|
18640
18659
|
const dir = dirname4(shim);
|
|
18641
|
-
const targets = [...
|
|
18660
|
+
const targets = [...text4.matchAll(/"%~?dp0%?\\?([^"]+)"/g)].map((m) => join9(dir, m[1])).filter((p) => isFile(p) && basename2(p).toLowerCase() !== "node.exe");
|
|
18642
18661
|
const script = targets.find((p) => /\.[cm]?js$/i.test(p));
|
|
18643
18662
|
if (script) {
|
|
18644
|
-
const node = nodeExe(dir);
|
|
18663
|
+
const node = nodeExe(dir, env);
|
|
18645
18664
|
if (node) return { command: node, args: [script] };
|
|
18646
18665
|
}
|
|
18647
18666
|
const exe = targets.find((p) => extname(p).toLowerCase() === ".exe");
|
|
18648
18667
|
return exe ? { command: exe, args: [] } : null;
|
|
18649
18668
|
}
|
|
18650
|
-
function parseNodeShebang(file2) {
|
|
18669
|
+
function parseNodeShebang(file2, env) {
|
|
18651
18670
|
let head = "";
|
|
18652
18671
|
let fd = null;
|
|
18653
18672
|
try {
|
|
@@ -18666,32 +18685,32 @@ function parseNodeShebang(file2) {
|
|
|
18666
18685
|
}
|
|
18667
18686
|
}
|
|
18668
18687
|
if (!/^#!.*\bnode(\.exe)?\b/.test(head)) return null;
|
|
18669
|
-
const node = nodeExe(dirname4(file2));
|
|
18688
|
+
const node = nodeExe(dirname4(file2), env);
|
|
18670
18689
|
return node ? { command: node, args: [file2] } : null;
|
|
18671
18690
|
}
|
|
18672
|
-
function resolveWord(cli, args) {
|
|
18691
|
+
function resolveWord(cli, args, env) {
|
|
18673
18692
|
if (process.platform !== "win32") return { command: cli, args };
|
|
18674
|
-
const file2 = whichWin(cli);
|
|
18693
|
+
const file2 = whichWin(cli, env);
|
|
18675
18694
|
if (!file2) return { command: cli, args };
|
|
18676
18695
|
const ext = extname(file2).toLowerCase();
|
|
18677
18696
|
if (ext === ".cmd" || ext === ".bat") {
|
|
18678
|
-
const direct = parseCmdShim(file2);
|
|
18697
|
+
const direct = parseCmdShim(file2, env);
|
|
18679
18698
|
return direct ? { command: direct.command, args: [...direct.args, ...args] } : { command: file2, args };
|
|
18680
18699
|
}
|
|
18681
18700
|
if (ext === ".exe" || ext === ".com") return { command: file2, args };
|
|
18682
|
-
const viaNode = parseNodeShebang(file2);
|
|
18701
|
+
const viaNode = parseNodeShebang(file2, env);
|
|
18683
18702
|
return viaNode ? { command: viaNode.command, args: [...viaNode.args, ...args] } : { command: file2, args };
|
|
18684
18703
|
}
|
|
18685
|
-
function resolveCliSpawn(cli, args) {
|
|
18704
|
+
function resolveCliSpawn(cli, args, env) {
|
|
18686
18705
|
const trimmed = cli.trim();
|
|
18687
|
-
if (trimmed.includes(" ") && existsSync7(trimmed)) return resolveWord(trimmed, args);
|
|
18706
|
+
if (trimmed.includes(" ") && existsSync7(trimmed)) return resolveWord(trimmed, args, env);
|
|
18688
18707
|
const split = splitCliString(cli);
|
|
18689
18708
|
if (split.length > 1 || split[0] !== trimmed) {
|
|
18690
18709
|
const [head, ...fixed] = split;
|
|
18691
18710
|
if (!head) return { command: cli, args };
|
|
18692
|
-
return resolveWord(head, [...fixed, ...args]);
|
|
18711
|
+
return resolveWord(head, [...fixed, ...args], env);
|
|
18693
18712
|
}
|
|
18694
|
-
return resolveWord(cli, args);
|
|
18713
|
+
return resolveWord(cli, args, env);
|
|
18695
18714
|
}
|
|
18696
18715
|
var cached2, probed, loginShellPath, registeredDirs;
|
|
18697
18716
|
var init_env_path = __esm({
|
|
@@ -18710,8 +18729,8 @@ import {
|
|
|
18710
18729
|
execFile as execFile3
|
|
18711
18730
|
} from "node:child_process";
|
|
18712
18731
|
import { join as join10 } from "node:path";
|
|
18713
|
-
function resolveCli(cli, args = []) {
|
|
18714
|
-
return resolveCliSpawn(cli, args);
|
|
18732
|
+
function resolveCli(cli, args = [], env) {
|
|
18733
|
+
return resolveCliSpawn(cli, args, env);
|
|
18715
18734
|
}
|
|
18716
18735
|
function estimatedWindowsCommandLineChars(resolved) {
|
|
18717
18736
|
return [resolved.command, ...resolved.args].reduce(
|
|
@@ -18825,9 +18844,13 @@ async function stopCliTree(child, pid, timeoutMs) {
|
|
|
18825
18844
|
if (exited()) return true;
|
|
18826
18845
|
return new Promise((resolve13) => {
|
|
18827
18846
|
let timer;
|
|
18847
|
+
let finished = false;
|
|
18828
18848
|
const done = (stopped) => {
|
|
18849
|
+
if (finished) return;
|
|
18850
|
+
finished = true;
|
|
18829
18851
|
clearTimeout(timer);
|
|
18830
18852
|
child.off("close", closed);
|
|
18853
|
+
child.off("exit", closed);
|
|
18831
18854
|
resolve13(stopped);
|
|
18832
18855
|
};
|
|
18833
18856
|
const closed = () => done(true);
|
|
@@ -18835,7 +18858,12 @@ async function stopCliTree(child, pid, timeoutMs) {
|
|
|
18835
18858
|
timer = setTimeout(() => done(false), timeoutMs);
|
|
18836
18859
|
timer.unref?.();
|
|
18837
18860
|
execFile3("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true }, (err) => {
|
|
18838
|
-
if (
|
|
18861
|
+
if (finished) return;
|
|
18862
|
+
if (!err) {
|
|
18863
|
+
if (exited()) done(true);
|
|
18864
|
+
else child.once("exit", closed);
|
|
18865
|
+
return;
|
|
18866
|
+
}
|
|
18839
18867
|
try {
|
|
18840
18868
|
child.kill();
|
|
18841
18869
|
} catch {
|
|
@@ -19583,9 +19611,9 @@ function isSecretName(name) {
|
|
|
19583
19611
|
if (SECRET_KEY_PARTS.some((part) => lower.includes(part))) return true;
|
|
19584
19612
|
return /(^|[_.-])keys?$/.test(lower);
|
|
19585
19613
|
}
|
|
19586
|
-
function redactSecretsInText(
|
|
19587
|
-
if (!
|
|
19588
|
-
let out =
|
|
19614
|
+
function redactSecretsInText(text4) {
|
|
19615
|
+
if (!text4 || text4.length < 8) return text4;
|
|
19616
|
+
let out = text4;
|
|
19589
19617
|
out = out.replace(PEM_BLOCK, (_m, open2, body, close) => `${open2}
|
|
19590
19618
|
${mask(body.trim())}
|
|
19591
19619
|
${close}`);
|
|
@@ -19696,8 +19724,8 @@ function askInputSummary(input) {
|
|
|
19696
19724
|
if (typeof fields.question === "string") return cut(fields.question, QUESTION_LIMIT);
|
|
19697
19725
|
if (typeof fields.command === "string") return cut(fields.command, LIMIT);
|
|
19698
19726
|
if (typeof fields.url === "string") return cut(fields.url, LIMIT);
|
|
19699
|
-
const
|
|
19700
|
-
return
|
|
19727
|
+
const text4 = JSON.stringify(fields);
|
|
19728
|
+
return text4 === "{}" ? void 0 : cut(text4, LIMIT);
|
|
19701
19729
|
}
|
|
19702
19730
|
var QUESTION_LIMIT, LIMIT, cut;
|
|
19703
19731
|
var init_tool_summary = __esm({
|
|
@@ -19706,7 +19734,7 @@ var init_tool_summary = __esm({
|
|
|
19706
19734
|
init_redact();
|
|
19707
19735
|
QUESTION_LIMIT = 300;
|
|
19708
19736
|
LIMIT = 200;
|
|
19709
|
-
cut = (
|
|
19737
|
+
cut = (text4, limit) => redactSecretsInText(text4).trim().slice(0, limit);
|
|
19710
19738
|
}
|
|
19711
19739
|
});
|
|
19712
19740
|
|
|
@@ -19729,11 +19757,11 @@ function sanitizeToolLogValue(value, budget, depth = 0) {
|
|
|
19729
19757
|
if (typeof value === "string") {
|
|
19730
19758
|
if (/^data:image\//iu.test(value) || budget.text <= 0) return void 0;
|
|
19731
19759
|
const limit = Math.min(TOOL_LOG_TEXT_LIMIT, budget.text);
|
|
19732
|
-
const
|
|
19760
|
+
const text4 = value.length <= limit ? value : `[Earlier output truncated]
|
|
19733
19761
|
|
|
19734
19762
|
${value.slice(-limit)}`;
|
|
19735
|
-
budget.text -=
|
|
19736
|
-
return
|
|
19763
|
+
budget.text -= text4.length;
|
|
19764
|
+
return text4;
|
|
19737
19765
|
}
|
|
19738
19766
|
if (Array.isArray(value)) {
|
|
19739
19767
|
return value.flatMap((entry) => {
|
|
@@ -20040,10 +20068,10 @@ function createAcpDriver(support11) {
|
|
|
20040
20068
|
}
|
|
20041
20069
|
};
|
|
20042
20070
|
const flushAssistantText = () => {
|
|
20043
|
-
const
|
|
20071
|
+
const text4 = state.text;
|
|
20044
20072
|
state.text = "";
|
|
20045
|
-
if (!
|
|
20046
|
-
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text:
|
|
20073
|
+
if (!text4.trim()) return;
|
|
20074
|
+
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
20047
20075
|
};
|
|
20048
20076
|
const settle = (ok, stopReason) => {
|
|
20049
20077
|
if (state.settled) return;
|
|
@@ -20299,7 +20327,7 @@ function createAcpDriver(support11) {
|
|
|
20299
20327
|
}
|
|
20300
20328
|
}
|
|
20301
20329
|
const images = turn.images ?? [];
|
|
20302
|
-
const runtimeAcceptsImages = init?.agentCapabilities?.promptCapabilities?.image === true;
|
|
20330
|
+
const runtimeAcceptsImages = init?.agentCapabilities?.promptCapabilities?.image === true || support11.acceptsUnadvertisedImages?.(init) === true;
|
|
20303
20331
|
if (images.length && support11.images === true && !runtimeAcceptsImages) {
|
|
20304
20332
|
throw new Error(
|
|
20305
20333
|
`${support11.displayName} is configured for image attachments, but this installed runtime does not advertise ACP image input. Update the ${support11.displayName} CLI or send the message without an image.`
|
|
@@ -20372,13 +20400,13 @@ function createAcpDriver(support11) {
|
|
|
20372
20400
|
}
|
|
20373
20401
|
emitSessionStarted();
|
|
20374
20402
|
state.promptSent = true;
|
|
20375
|
-
const
|
|
20403
|
+
const text4 = support11.buildPromptText ? support11.buildPromptText(turn) : turn.system ? `${turn.system}
|
|
20376
20404
|
|
|
20377
20405
|
${turn.text}` : turn.text;
|
|
20378
20406
|
const imageBlocks = support11.images === true && runtimeAcceptsImages ? await readAcpImageBlocks(images) : [];
|
|
20379
20407
|
const result = await request("session/prompt", {
|
|
20380
20408
|
sessionId,
|
|
20381
|
-
prompt: [{ type: "text", text:
|
|
20409
|
+
prompt: [{ type: "text", text: text4 }, ...imageBlocks]
|
|
20382
20410
|
});
|
|
20383
20411
|
const usage = result?.usage ?? result?._meta ?? {};
|
|
20384
20412
|
if (typeof usage.inputTokens === "number" || typeof usage.outputTokens === "number") {
|
|
@@ -21706,14 +21734,14 @@ var init_boxagent = __esm({
|
|
|
21706
21734
|
let lastText = "";
|
|
21707
21735
|
let pendingText = "";
|
|
21708
21736
|
const flushAssistantText = () => {
|
|
21709
|
-
const
|
|
21737
|
+
const text4 = pendingText;
|
|
21710
21738
|
pendingText = "";
|
|
21711
|
-
if (!
|
|
21712
|
-
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text:
|
|
21739
|
+
if (!text4.trim()) return;
|
|
21740
|
+
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
21713
21741
|
};
|
|
21714
|
-
const ingest = (
|
|
21715
|
-
const delta =
|
|
21716
|
-
lastText =
|
|
21742
|
+
const ingest = (text4) => {
|
|
21743
|
+
const delta = text4.startsWith(lastText) ? text4.slice(lastText.length) : text4;
|
|
21744
|
+
lastText = text4;
|
|
21717
21745
|
if (!delta) return;
|
|
21718
21746
|
pendingText += delta;
|
|
21719
21747
|
emit({ ...base2(threadId, turnId), type: "content.delta", streamKind: "assistant_text", delta });
|
|
@@ -21730,9 +21758,9 @@ var init_boxagent = __esm({
|
|
|
21730
21758
|
seen.add(id);
|
|
21731
21759
|
appendNative(threadId, { dir: "in", source: "box.events", msg: ev });
|
|
21732
21760
|
const kind = String(ev.type ?? ev.kind ?? "");
|
|
21733
|
-
const
|
|
21734
|
-
if (/assistant|message|output|response/i.test(kind) && typeof
|
|
21735
|
-
ingest(
|
|
21761
|
+
const text4 = ev.text ?? ev.message ?? ev.data?.text ?? ev.data?.content ?? null;
|
|
21762
|
+
if (/assistant|message|output|response/i.test(kind) && typeof text4 === "string" && text4.trim()) {
|
|
21763
|
+
ingest(text4);
|
|
21736
21764
|
} else if (/tool|command|exec|browse/i.test(kind)) {
|
|
21737
21765
|
flushAssistantText();
|
|
21738
21766
|
emit({
|
|
@@ -22272,25 +22300,36 @@ var init_mcp_gate_config = __esm({
|
|
|
22272
22300
|
}
|
|
22273
22301
|
});
|
|
22274
22302
|
|
|
22303
|
+
// shared/provider-safety.ts
|
|
22304
|
+
function isProviderSafetyBlock(message2) {
|
|
22305
|
+
return /\bblocked by (?:our|the provider['’]s) safety systems\b|\bsafety monitoring\b.{0,100}\b(?:paused|ended|blocked)\b|\b(?:safety_check_failed|safety_policy_violation)\b/i.test(message2);
|
|
22306
|
+
}
|
|
22307
|
+
var init_provider_safety = __esm({
|
|
22308
|
+
"shared/provider-safety.ts"() {
|
|
22309
|
+
"use strict";
|
|
22310
|
+
}
|
|
22311
|
+
});
|
|
22312
|
+
|
|
22275
22313
|
// server/drivers/retry.ts
|
|
22276
22314
|
function classifyError(err) {
|
|
22277
|
-
const
|
|
22315
|
+
const text4 = messageOf(err);
|
|
22316
|
+
if (isProviderSafetyBlock(text4)) return { transient: false, reason: "provider_safety" };
|
|
22278
22317
|
if (err && "exitCode" in err) {
|
|
22279
22318
|
const { exitCode: code } = err;
|
|
22280
22319
|
if (code !== null && code < 0) return { transient: false, reason: "interrupted" };
|
|
22281
22320
|
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
22282
|
-
if (pattern.test(
|
|
22321
|
+
if (pattern.test(text4)) return { transient: true, reason };
|
|
22283
22322
|
}
|
|
22284
22323
|
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
22285
|
-
if (pattern.test(
|
|
22324
|
+
if (pattern.test(text4)) return { transient: false, reason };
|
|
22286
22325
|
}
|
|
22287
22326
|
return { transient: false, reason: "terminal_exit" };
|
|
22288
22327
|
}
|
|
22289
22328
|
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
22290
|
-
if (pattern.test(
|
|
22329
|
+
if (pattern.test(text4)) return { transient: false, reason };
|
|
22291
22330
|
}
|
|
22292
22331
|
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
22293
|
-
if (pattern.test(
|
|
22332
|
+
if (pattern.test(text4)) return { transient: true, reason };
|
|
22294
22333
|
}
|
|
22295
22334
|
return { transient: false, reason: "unknown" };
|
|
22296
22335
|
}
|
|
@@ -22321,6 +22360,7 @@ var RETRY_MAX_ATTEMPTS, BACKOFF_BASE_MS, TRANSIENT_PATTERNS, TERMINAL_PATTERNS,
|
|
|
22321
22360
|
var init_retry = __esm({
|
|
22322
22361
|
"server/drivers/retry.ts"() {
|
|
22323
22362
|
"use strict";
|
|
22363
|
+
init_provider_safety();
|
|
22324
22364
|
RETRY_MAX_ATTEMPTS = 3;
|
|
22325
22365
|
BACKOFF_BASE_MS = [1e3, 3e3, 8e3];
|
|
22326
22366
|
TRANSIENT_PATTERNS = [
|
|
@@ -22355,6 +22395,82 @@ var init_retry = __esm({
|
|
|
22355
22395
|
}
|
|
22356
22396
|
});
|
|
22357
22397
|
|
|
22398
|
+
// shared/ask-question.ts
|
|
22399
|
+
function text3(value, limit) {
|
|
22400
|
+
if (typeof value !== "string") return void 0;
|
|
22401
|
+
const trimmed = value.trim();
|
|
22402
|
+
return trimmed ? trimmed.slice(0, limit) : void 0;
|
|
22403
|
+
}
|
|
22404
|
+
function isRecord(value) {
|
|
22405
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22406
|
+
}
|
|
22407
|
+
function parseOption(value) {
|
|
22408
|
+
if (typeof value === "string") {
|
|
22409
|
+
const label2 = text3(value, MAX_LABEL);
|
|
22410
|
+
return label2 ? { label: label2 } : null;
|
|
22411
|
+
}
|
|
22412
|
+
if (!isRecord(value)) return null;
|
|
22413
|
+
const label = text3(value.label, MAX_LABEL);
|
|
22414
|
+
if (!label) return null;
|
|
22415
|
+
const description = text3(value.description, MAX_DESCRIPTION);
|
|
22416
|
+
return description ? { label, description } : { label };
|
|
22417
|
+
}
|
|
22418
|
+
function parseQuestion(value) {
|
|
22419
|
+
if (!isRecord(value)) return null;
|
|
22420
|
+
const question = text3(value.question, MAX_QUESTION_TEXT);
|
|
22421
|
+
if (!question) return null;
|
|
22422
|
+
const options = [];
|
|
22423
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22424
|
+
for (const raw of Array.isArray(value.options) ? value.options : []) {
|
|
22425
|
+
const option = parseOption(raw);
|
|
22426
|
+
if (!option || seen.has(option.label)) continue;
|
|
22427
|
+
seen.add(option.label);
|
|
22428
|
+
options.push(option);
|
|
22429
|
+
if (options.length === MAX_OPTIONS) break;
|
|
22430
|
+
}
|
|
22431
|
+
const header = text3(value.header, MAX_LABEL);
|
|
22432
|
+
return {
|
|
22433
|
+
question,
|
|
22434
|
+
...header ? { header } : {},
|
|
22435
|
+
...value.multiSelect === true ? { multiSelect: true } : {},
|
|
22436
|
+
options
|
|
22437
|
+
};
|
|
22438
|
+
}
|
|
22439
|
+
function parseAskQuestions(input) {
|
|
22440
|
+
if (!isRecord(input) || !Array.isArray(input.questions)) return null;
|
|
22441
|
+
const questions = [];
|
|
22442
|
+
for (const raw of input.questions) {
|
|
22443
|
+
const question = parseQuestion(raw);
|
|
22444
|
+
if (!question) continue;
|
|
22445
|
+
questions.push(question);
|
|
22446
|
+
if (questions.length === MAX_QUESTIONS) break;
|
|
22447
|
+
}
|
|
22448
|
+
return questions.length ? questions : null;
|
|
22449
|
+
}
|
|
22450
|
+
function askQuestionSummary(questions) {
|
|
22451
|
+
const first = questions[0]?.question ?? "";
|
|
22452
|
+
const rest = questions.length - 1;
|
|
22453
|
+
return rest > 0 ? `${first} (+${rest} more question${rest > 1 ? "s" : ""})` : first;
|
|
22454
|
+
}
|
|
22455
|
+
function questionChoices(questions) {
|
|
22456
|
+
if (questions.length !== 1) return void 0;
|
|
22457
|
+
const only = questions[0];
|
|
22458
|
+
if (only.multiSelect || only.options.length < 2) return void 0;
|
|
22459
|
+
return only.options.map((option) => option.label);
|
|
22460
|
+
}
|
|
22461
|
+
var ASK_USER_QUESTION_TOOL, MAX_QUESTIONS, MAX_OPTIONS, MAX_QUESTION_TEXT, MAX_LABEL, MAX_DESCRIPTION;
|
|
22462
|
+
var init_ask_question = __esm({
|
|
22463
|
+
"shared/ask-question.ts"() {
|
|
22464
|
+
"use strict";
|
|
22465
|
+
ASK_USER_QUESTION_TOOL = "AskUserQuestion";
|
|
22466
|
+
MAX_QUESTIONS = 6;
|
|
22467
|
+
MAX_OPTIONS = 12;
|
|
22468
|
+
MAX_QUESTION_TEXT = 400;
|
|
22469
|
+
MAX_LABEL = 120;
|
|
22470
|
+
MAX_DESCRIPTION = 400;
|
|
22471
|
+
}
|
|
22472
|
+
});
|
|
22473
|
+
|
|
22358
22474
|
// server/drivers/claude.ts
|
|
22359
22475
|
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
22360
22476
|
import { chmodSync as chmodSync4, mkdtempSync as mkdtempSync2, readFileSync as readFileSync8, rmSync as rmSync4, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
@@ -22395,9 +22511,9 @@ function resolveClaudeConfigDir(configDir, env = process.env) {
|
|
|
22395
22511
|
}
|
|
22396
22512
|
return normalize(expanded);
|
|
22397
22513
|
}
|
|
22398
|
-
function claudeAuthFailure(frame,
|
|
22514
|
+
function claudeAuthFailure(frame, text4) {
|
|
22399
22515
|
if (frame.is_api_error_message !== true && typeof frame.error !== "string") return false;
|
|
22400
|
-
return frame.error === "authentication_failed" || classifyError({ text:
|
|
22516
|
+
return frame.error === "authentication_failed" || classifyError({ text: text4 }).reason === "auth";
|
|
22401
22517
|
}
|
|
22402
22518
|
function claudeEnvironment(model, source = process.env, configDir, instanceEnvironment = {}) {
|
|
22403
22519
|
const env = { ...source, PATH: augmentedPath(), NPM_CONFIG_LOGLEVEL: "error" };
|
|
@@ -22421,6 +22537,24 @@ function claudeEnvironment(model, source = process.env, configDir, instanceEnvir
|
|
|
22421
22537
|
function inheritsUserConfig(env) {
|
|
22422
22538
|
return env.OMB_CLAUDE_INHERIT_USER_CONFIG === "1";
|
|
22423
22539
|
}
|
|
22540
|
+
function readClaudeAuthSettings(env, instanceEnvironment = {}) {
|
|
22541
|
+
if (CLAUDE_ACCOUNT_ENV_KEYS.some((key) => instanceEnvironment[key])) return {};
|
|
22542
|
+
try {
|
|
22543
|
+
const settings2 = JSON.parse(readFileSync8(join20(resolveClaudeConfigDir(void 0, env), "settings.json"), "utf8"));
|
|
22544
|
+
const authEnv = {};
|
|
22545
|
+
for (const key of CLAUDE_ACCOUNT_ENV_KEYS) {
|
|
22546
|
+
if (!key.endsWith("_FILE_DESCRIPTOR") && typeof settings2?.env?.[key] === "string") {
|
|
22547
|
+
authEnv[key] = settings2.env[key];
|
|
22548
|
+
}
|
|
22549
|
+
}
|
|
22550
|
+
return {
|
|
22551
|
+
...Object.keys(authEnv).length ? { env: authEnv } : {},
|
|
22552
|
+
...typeof settings2?.apiKeyHelper === "string" && settings2.apiKeyHelper.trim() ? { apiKeyHelper: settings2.apiKeyHelper } : {}
|
|
22553
|
+
};
|
|
22554
|
+
} catch {
|
|
22555
|
+
return {};
|
|
22556
|
+
}
|
|
22557
|
+
}
|
|
22424
22558
|
function projectMcpServers(cwd) {
|
|
22425
22559
|
let parsed;
|
|
22426
22560
|
try {
|
|
@@ -22525,18 +22659,24 @@ function removePrivateTempDir(filePath) {
|
|
|
22525
22659
|
function systemEndedReply(kind) {
|
|
22526
22660
|
return kind === "question" ? { behavior: "answer", message: "OpenMausBot: the turn is ending \u2014 wrap up." } : { behavior: "deny", message: "OpenMausBot: the turn ended" };
|
|
22527
22661
|
}
|
|
22662
|
+
function askQuestions(ask) {
|
|
22663
|
+
return ask.tool === ASK_USER_QUESTION_TOOL ? parseAskQuestions(ask.input) : null;
|
|
22664
|
+
}
|
|
22528
22665
|
function askSummary(ask) {
|
|
22666
|
+
const questions = askQuestions(ask);
|
|
22667
|
+
if (questions) return askQuestionSummary(questions).slice(0, 300);
|
|
22529
22668
|
return askInputSummary(ask.input) ?? ask.tool ?? "tool";
|
|
22530
22669
|
}
|
|
22531
|
-
function permissionSocketPath(threadId) {
|
|
22670
|
+
function permissionSocketPath(threadId, botId) {
|
|
22671
|
+
const key = botId ? `${botId}\0${threadId}` : threadId;
|
|
22532
22672
|
const prefix = threadId.replace(/[^\w-]/g, "").slice(0, 4);
|
|
22533
|
-
const digest2 = createHash5("sha256").update(
|
|
22673
|
+
const digest2 = createHash5("sha256").update(key).digest("hex").slice(0, 4);
|
|
22534
22674
|
return brokerSocketPath(DATA_DIR, `${prefix}${digest2}`);
|
|
22535
22675
|
}
|
|
22536
|
-
function brokerSocketCandidates(threadId) {
|
|
22537
|
-
const base2 = permissionSocketPath(threadId);
|
|
22676
|
+
function brokerSocketCandidates(threadId, botId) {
|
|
22677
|
+
const base2 = permissionSocketPath(threadId, botId);
|
|
22538
22678
|
if (process.platform !== "win32") {
|
|
22539
|
-
const scope = createHash5("sha256").update(`${DATA_DIR}\0${process.pid}\0${threadId}`).digest("hex").slice(0, 16);
|
|
22679
|
+
const scope = createHash5("sha256").update(`${DATA_DIR}\0${process.pid}\0${botId ?? ""}\0${threadId}`).digest("hex").slice(0, 16);
|
|
22540
22680
|
return [base2, join20(tmpdir3(), `omb-perm-${scope}.sock`)];
|
|
22541
22681
|
}
|
|
22542
22682
|
return [
|
|
@@ -22596,7 +22736,9 @@ async function createPermissionBroker(opts) {
|
|
|
22596
22736
|
if (!pending.delete(askId)) return;
|
|
22597
22737
|
clearTimeout(timer);
|
|
22598
22738
|
try {
|
|
22599
|
-
conn.write(
|
|
22739
|
+
conn.write(
|
|
22740
|
+
JSON.stringify({ t: "answer", id: askId, behavior, message: message2, source, ...always ? { always: true } : {} }) + "\n"
|
|
22741
|
+
);
|
|
22600
22742
|
} catch {
|
|
22601
22743
|
}
|
|
22602
22744
|
opts.onResolve({ ...ask, behavior, source });
|
|
@@ -22735,19 +22877,19 @@ function firstText(content) {
|
|
|
22735
22877
|
}
|
|
22736
22878
|
return "";
|
|
22737
22879
|
}
|
|
22738
|
-
function withVolatileNote(
|
|
22880
|
+
function withVolatileNote(text4, volatile) {
|
|
22739
22881
|
const body = volatile.trim() ? `This part of your instructions changed since this session started. It replaces the earlier copy:
|
|
22740
22882
|
|
|
22741
22883
|
${volatile.trim()}` : "The notes that were in your instructions when this session started have been cleared.";
|
|
22742
22884
|
const note = `<system-reminder>
|
|
22743
22885
|
${body}
|
|
22744
22886
|
</system-reminder>`;
|
|
22745
|
-
return
|
|
22887
|
+
return text4 ? `${note}
|
|
22746
22888
|
|
|
22747
|
-
${
|
|
22889
|
+
${text4}` : note;
|
|
22748
22890
|
}
|
|
22749
|
-
function claudeUserMessage(
|
|
22750
|
-
if (!images?.length) return { type: "user", message: { role: "user", content:
|
|
22891
|
+
function claudeUserMessage(text4, images) {
|
|
22892
|
+
if (!images?.length) return { type: "user", message: { role: "user", content: text4 } };
|
|
22751
22893
|
const content = images.map((image) => ({
|
|
22752
22894
|
type: "image",
|
|
22753
22895
|
source: {
|
|
@@ -22756,7 +22898,7 @@ function claudeUserMessage(text3, images) {
|
|
|
22756
22898
|
data: readFileSync8(image.path).toString("base64")
|
|
22757
22899
|
}
|
|
22758
22900
|
}));
|
|
22759
|
-
if (
|
|
22901
|
+
if (text4) content.push({ type: "text", text: text4 });
|
|
22760
22902
|
return { type: "user", message: { role: "user", content } };
|
|
22761
22903
|
}
|
|
22762
22904
|
function diagnosticClaudeUserMessage(message2) {
|
|
@@ -22794,6 +22936,7 @@ var init_claude = __esm({
|
|
|
22794
22936
|
init_local_inject();
|
|
22795
22937
|
init_native();
|
|
22796
22938
|
init_proxy_paths();
|
|
22939
|
+
init_ask_question();
|
|
22797
22940
|
CLAUDE_ACCOUNT_ENV_KEYS = [
|
|
22798
22941
|
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
22799
22942
|
"CLAUDE_CODE_OAUTH_REFRESH_TOKEN",
|
|
@@ -22931,8 +23074,8 @@ var init_claude = __esm({
|
|
|
22931
23074
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
22932
23075
|
});
|
|
22933
23076
|
const retryState = /* @__PURE__ */ new Map();
|
|
22934
|
-
const sendTurn = async (turn) => {
|
|
22935
|
-
const { threadId } = turn;
|
|
23077
|
+
const sendTurn = async (turn, logicalTurnId) => {
|
|
23078
|
+
const { threadId, botId } = turn;
|
|
22936
23079
|
if (active.has(threadId)) throw new Error("a turn is already running on this thread");
|
|
22937
23080
|
const permissionMode = turn.approvalMode === void 0 ? config2.permissionMode : turn.approvalMode === "full" ? "bypassPermissions" : turn.approvalMode === "auto" ? "auto" : turn.approvalMode === "edits" ? "acceptEdits" : "default";
|
|
22938
23081
|
const controlsHost = turn.integrations?.localComputer?.scope === "local-computer";
|
|
@@ -22940,7 +23083,7 @@ var init_claude = __esm({
|
|
|
22940
23083
|
throw new Error("local computer control requires the interactive approval broker");
|
|
22941
23084
|
}
|
|
22942
23085
|
const promptMsg = claudeUserMessage(turn.text, turn.images);
|
|
22943
|
-
const turnId = newId();
|
|
23086
|
+
const turnId = logicalTurnId ?? newId();
|
|
22944
23087
|
const retryAbort = new AbortController();
|
|
22945
23088
|
const retry = retryState.get(threadId) ?? { attempt: 0, cancelled: false };
|
|
22946
23089
|
retry.cancelled = false;
|
|
@@ -23045,7 +23188,7 @@ var init_claude = __esm({
|
|
|
23045
23188
|
if (gated) mcpServers[name] = gated;
|
|
23046
23189
|
}
|
|
23047
23190
|
let broker;
|
|
23048
|
-
const socketPath = permissionSocketPath(threadId);
|
|
23191
|
+
const socketPath = permissionSocketPath(threadId, botId);
|
|
23049
23192
|
if (permissionMode !== "bypassPermissions") {
|
|
23050
23193
|
args.push("--permission-prompt-tool", "mcp__ogb__approve");
|
|
23051
23194
|
}
|
|
@@ -23058,9 +23201,12 @@ var init_claude = __esm({
|
|
|
23058
23201
|
args.push("--allowedTools", allowed.join(","));
|
|
23059
23202
|
}
|
|
23060
23203
|
const env = environment(turnModel);
|
|
23204
|
+
const authSettings = isolated && !injected.injected ? readClaudeAuthSettings(env, input.environment) : {};
|
|
23205
|
+
const authSettingsPath = mcpConfigPath && Object.keys(authSettings).length ? join20(dirname9(mcpConfigPath), "auth-settings.json") : null;
|
|
23206
|
+
if (authSettingsPath) args.push("--settings", authSettingsPath);
|
|
23061
23207
|
env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS = "1";
|
|
23062
23208
|
const cwd = turn.cwd ?? homedir9();
|
|
23063
|
-
const privateFileFlags = /* @__PURE__ */ new Set(["--mcp-config"]);
|
|
23209
|
+
const privateFileFlags = /* @__PURE__ */ new Set(["--mcp-config", "--settings"]);
|
|
23064
23210
|
const keyArgs = args.filter((a2, i2) => !privateFileFlags.has(a2) && !privateFileFlags.has(args[i2 - 1] ?? ""));
|
|
23065
23211
|
const argsKey = JSON.stringify({
|
|
23066
23212
|
args: keyArgs,
|
|
@@ -23071,14 +23217,21 @@ var init_claude = __esm({
|
|
|
23071
23217
|
cwd,
|
|
23072
23218
|
model: injected.model ?? null,
|
|
23073
23219
|
base: env.ANTHROPIC_BASE_URL ?? null,
|
|
23074
|
-
configDir: env.CLAUDE_CONFIG_DIR ?? null
|
|
23220
|
+
configDir: env.CLAUDE_CONFIG_DIR ?? null,
|
|
23221
|
+
// Rotating an account's key/helper must not reuse the old process.
|
|
23222
|
+
auth: createHash5("sha256").update(JSON.stringify({
|
|
23223
|
+
settings: authSettings,
|
|
23224
|
+
env: Object.fromEntries(CLAUDE_ACCOUNT_ENV_KEYS.map((key) => [key, env[key]]))
|
|
23225
|
+
})).digest("hex")
|
|
23075
23226
|
});
|
|
23076
23227
|
const live = sessions.get(threadId);
|
|
23077
23228
|
if (live && !live.turn && !live.closing && live.child.exitCode === null && live.argsKey === argsKey && (!sessionId || sessionId === live.sessionId)) {
|
|
23078
23229
|
if (live.idleTimer) clearTimeout(live.idleTimer);
|
|
23079
|
-
live.turn = { turnId, settled: false, sawStreamDelta: false };
|
|
23230
|
+
live.turn = { turnId, input: turn, retryAbort, settled: false, sawStreamDelta: false };
|
|
23080
23231
|
active.set(threadId, { stop: () => {
|
|
23081
23232
|
closeSession(threadId, "interrupted");
|
|
23233
|
+
retry.cancelled = true;
|
|
23234
|
+
retryAbort.abort();
|
|
23082
23235
|
stopSession(live);
|
|
23083
23236
|
}, turnId, broker: live.broker });
|
|
23084
23237
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
@@ -23133,13 +23286,14 @@ var init_claude = __esm({
|
|
|
23133
23286
|
if (socketPath) {
|
|
23134
23287
|
const askTools = /* @__PURE__ */ new Map();
|
|
23135
23288
|
broker = await createPermissionBroker({
|
|
23136
|
-
socketPaths: brokerSocketCandidates(threadId),
|
|
23289
|
+
socketPaths: brokerSocketCandidates(threadId, botId),
|
|
23137
23290
|
isActive: () => Boolean(sessions.get(threadId)?.turn),
|
|
23138
23291
|
onAsk: (ask) => {
|
|
23139
23292
|
const eventTurnId = sessions.get(threadId)?.turn?.turnId ?? turnId;
|
|
23140
23293
|
askTools.set(ask.id, typeof ask.tool === "string" ? ask.tool : void 0);
|
|
23141
23294
|
const nativeMode = sessions.get(threadId)?.nativePermissionMode ?? null;
|
|
23142
23295
|
const nativeReview = permissionMode === "auto" && nativeMode !== null ? nativeMode === "auto" ? "active" : "inactive" : void 0;
|
|
23296
|
+
const questions = askQuestions(ask);
|
|
23143
23297
|
emit({
|
|
23144
23298
|
...base2(threadId, eventTurnId),
|
|
23145
23299
|
type: "request.opened",
|
|
@@ -23152,7 +23306,10 @@ var init_claude = __esm({
|
|
|
23152
23306
|
// host control stays one action at a time
|
|
23153
23307
|
allowSession: ask.kind === "permission" && !(controlsHost && typeof ask.tool === "string" && ask.tool.startsWith("mcp__computer")) ? true : void 0,
|
|
23154
23308
|
approvalScope: typeof ask.tool === "string" && controlsHost && ask.tool.startsWith("mcp__computer") ? "local-computer" : void 0,
|
|
23155
|
-
|
|
23309
|
+
questions: questions ?? void 0,
|
|
23310
|
+
// A structured ask still offers flat labels, for the phone
|
|
23311
|
+
// companions and any client that predates the question card.
|
|
23312
|
+
choices: questions ? questionChoices(questions) : Array.isArray(ask.input?.choices) ? ask.input.choices.slice(0, 5) : void 0
|
|
23156
23313
|
});
|
|
23157
23314
|
},
|
|
23158
23315
|
onResolve: (resolved) => {
|
|
@@ -23175,6 +23332,9 @@ var init_claude = __esm({
|
|
|
23175
23332
|
if (mcpConfigPath) {
|
|
23176
23333
|
writeFileSync6(mcpConfigPath, JSON.stringify({ mcpServers }), { mode: 384 });
|
|
23177
23334
|
}
|
|
23335
|
+
if (authSettingsPath) {
|
|
23336
|
+
writeFileSync6(authSettingsPath, JSON.stringify(authSettings), { mode: 384 });
|
|
23337
|
+
}
|
|
23178
23338
|
if (sessionId) args.push("--resume", sessionId);
|
|
23179
23339
|
else args.push("--session-id", newSessionId);
|
|
23180
23340
|
} catch (error51) {
|
|
@@ -23202,7 +23362,7 @@ var init_claude = __esm({
|
|
|
23202
23362
|
sessionId: sessionId ?? newSessionId,
|
|
23203
23363
|
sawInit: false,
|
|
23204
23364
|
nativePermissionMode: null,
|
|
23205
|
-
turn: { turnId, settled: false, sawStreamDelta: false },
|
|
23365
|
+
turn: { turnId, input: turn, retryAbort, settled: false, sawStreamDelta: false },
|
|
23206
23366
|
idleTimer: null,
|
|
23207
23367
|
closing: false,
|
|
23208
23368
|
stderr: ""
|
|
@@ -23265,18 +23425,18 @@ var init_claude = __esm({
|
|
|
23265
23425
|
}
|
|
23266
23426
|
case "assistant": {
|
|
23267
23427
|
const msg = o.message ?? {};
|
|
23268
|
-
const
|
|
23269
|
-
if (claudeAuthFailure(o,
|
|
23428
|
+
const text4 = firstText(msg.content);
|
|
23429
|
+
if (claudeAuthFailure(o, text4)) {
|
|
23270
23430
|
if (session.turn) session.turn.authFailed = true;
|
|
23271
|
-
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message:
|
|
23431
|
+
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message: text4, setup: true });
|
|
23272
23432
|
break;
|
|
23273
23433
|
}
|
|
23274
|
-
if (
|
|
23434
|
+
if (text4.trim()) {
|
|
23275
23435
|
if (!session.turn?.sawStreamDelta) {
|
|
23276
|
-
emit({ ...base2(threadId, currentTurnId()), type: "content.delta", streamKind: "assistant_text", delta:
|
|
23436
|
+
emit({ ...base2(threadId, currentTurnId()), type: "content.delta", streamKind: "assistant_text", delta: text4 });
|
|
23277
23437
|
}
|
|
23278
23438
|
if (session.turn) session.turn.sawStreamDelta = false;
|
|
23279
|
-
emit({ ...base2(threadId, currentTurnId()), type: "item.completed", itemType: "assistant_text", text:
|
|
23439
|
+
emit({ ...base2(threadId, currentTurnId()), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
23280
23440
|
}
|
|
23281
23441
|
for (const b of Array.isArray(msg.content) ? msg.content : []) {
|
|
23282
23442
|
if (b.type === "tool_use") {
|
|
@@ -23354,9 +23514,11 @@ var init_claude = __esm({
|
|
|
23354
23514
|
if (closeFinalized) return;
|
|
23355
23515
|
closeFinalized = true;
|
|
23356
23516
|
if (session.turn && !session.turn.settled) {
|
|
23517
|
+
const { turnId: turnId2, input: turn2, retryAbort: retryAbort2 } = session.turn;
|
|
23518
|
+
const retry2 = retryState.get(threadId) ?? { attempt: 0, cancelled: false };
|
|
23357
23519
|
const message2 = `claude exited ${code} before result${session.stderr ? `: ${session.stderr.trim().slice(-300)}` : ""}`;
|
|
23358
23520
|
const verdict = classifyError({ exitCode: code, stderr: message2 });
|
|
23359
|
-
if (!
|
|
23521
|
+
if (!retry2.cancelled && code !== 0 && verdict.transient && !session.turn.sawStreamDelta && retry2.attempt < RETRY_MAX_ATTEMPTS - 1) {
|
|
23360
23522
|
const failedBroker = session.broker;
|
|
23361
23523
|
session.broker = void 0;
|
|
23362
23524
|
failedBroker?.pause();
|
|
@@ -23374,23 +23536,23 @@ var init_claude = __esm({
|
|
|
23374
23536
|
}
|
|
23375
23537
|
sessions.delete(threadId);
|
|
23376
23538
|
session.turn = null;
|
|
23377
|
-
|
|
23378
|
-
const delayMs = computeBackoff(
|
|
23539
|
+
retry2.attempt++;
|
|
23540
|
+
const delayMs = computeBackoff(retry2.attempt - 1);
|
|
23379
23541
|
emit({
|
|
23380
|
-
...base2(threadId,
|
|
23542
|
+
...base2(threadId, turnId2),
|
|
23381
23543
|
type: "turn.retrying",
|
|
23382
|
-
attempt:
|
|
23544
|
+
attempt: retry2.attempt,
|
|
23383
23545
|
delayMs,
|
|
23384
23546
|
reason: verdict.reason
|
|
23385
23547
|
});
|
|
23386
23548
|
void (async () => {
|
|
23387
|
-
const wait2 = interruptibleDelay(delayMs * retryScale,
|
|
23549
|
+
const wait2 = interruptibleDelay(delayMs * retryScale, retryAbort2.signal);
|
|
23388
23550
|
await wait2.promise;
|
|
23389
|
-
if (
|
|
23551
|
+
if (retry2.cancelled) {
|
|
23390
23552
|
active.delete(threadId);
|
|
23391
23553
|
retryState.delete(threadId);
|
|
23392
23554
|
emit({
|
|
23393
|
-
...base2(threadId,
|
|
23555
|
+
...base2(threadId, turnId2),
|
|
23394
23556
|
type: "turn.completed",
|
|
23395
23557
|
ok: false,
|
|
23396
23558
|
stopReason: "interrupted",
|
|
@@ -23401,16 +23563,16 @@ var init_claude = __esm({
|
|
|
23401
23563
|
active.delete(threadId);
|
|
23402
23564
|
try {
|
|
23403
23565
|
const cursor3 = session.sessionId ?? sessionId ?? void 0;
|
|
23404
|
-
await sendTurn({ ...
|
|
23566
|
+
await sendTurn({ ...turn2, resumeCursor: cursor3 }, turnId2);
|
|
23405
23567
|
} catch (e) {
|
|
23406
23568
|
retryState.delete(threadId);
|
|
23407
23569
|
emit({
|
|
23408
|
-
...base2(threadId,
|
|
23570
|
+
...base2(threadId, turnId2),
|
|
23409
23571
|
type: "runtime.error",
|
|
23410
23572
|
message: e instanceof Error ? e.message : String(e)
|
|
23411
23573
|
});
|
|
23412
23574
|
emit({
|
|
23413
|
-
...base2(threadId,
|
|
23575
|
+
...base2(threadId, turnId2),
|
|
23414
23576
|
type: "turn.completed",
|
|
23415
23577
|
ok: false,
|
|
23416
23578
|
stopReason: "exit_before_result",
|
|
@@ -23426,10 +23588,10 @@ var init_claude = __esm({
|
|
|
23426
23588
|
promptSubmitted: session.sawInit,
|
|
23427
23589
|
producedOutput: session.turn.sawStreamDelta
|
|
23428
23590
|
});
|
|
23429
|
-
if (mayReplay(resumeFailure) && !
|
|
23591
|
+
if (mayReplay(resumeFailure) && !retry2.cancelled) {
|
|
23430
23592
|
const recovery = recoveryPromptFor({
|
|
23431
|
-
recoveryText:
|
|
23432
|
-
currentText:
|
|
23593
|
+
recoveryText: turn2.recoveryText,
|
|
23594
|
+
currentText: turn2.text,
|
|
23433
23595
|
failure: resumeFailure
|
|
23434
23596
|
});
|
|
23435
23597
|
session.broker?.close();
|
|
@@ -23449,23 +23611,23 @@ var init_claude = __esm({
|
|
|
23449
23611
|
session.turn = null;
|
|
23450
23612
|
active.delete(threadId);
|
|
23451
23613
|
emit({
|
|
23452
|
-
...base2(threadId,
|
|
23614
|
+
...base2(threadId, turnId2),
|
|
23453
23615
|
type: "turn.retrying",
|
|
23454
|
-
attempt:
|
|
23616
|
+
attempt: retry2.attempt + 1,
|
|
23455
23617
|
delayMs: 0,
|
|
23456
23618
|
reason: "resume_rejected"
|
|
23457
23619
|
});
|
|
23458
23620
|
void (async () => {
|
|
23459
23621
|
try {
|
|
23460
|
-
await sendTurn({ ...
|
|
23622
|
+
await sendTurn({ ...turn2, resumeCursor: void 0, recoveryText: void 0, text: recovery.text }, turnId2);
|
|
23461
23623
|
} catch (e) {
|
|
23462
23624
|
retryState.delete(threadId);
|
|
23463
23625
|
emit({
|
|
23464
|
-
...base2(threadId,
|
|
23626
|
+
...base2(threadId, turnId2),
|
|
23465
23627
|
type: "runtime.error",
|
|
23466
23628
|
message: e instanceof Error ? e.message : String(e)
|
|
23467
23629
|
});
|
|
23468
|
-
emit({ ...base2(threadId,
|
|
23630
|
+
emit({ ...base2(threadId, turnId2), type: "turn.completed", ok: false, stopReason: "exit_before_result", cost: null });
|
|
23469
23631
|
}
|
|
23470
23632
|
})();
|
|
23471
23633
|
return;
|
|
@@ -23507,10 +23669,10 @@ var init_claude = __esm({
|
|
|
23507
23669
|
}
|
|
23508
23670
|
return { turnId };
|
|
23509
23671
|
};
|
|
23510
|
-
const steer = async (threadId,
|
|
23672
|
+
const steer = async (threadId, text4) => {
|
|
23511
23673
|
const s = sessions.get(threadId);
|
|
23512
23674
|
if (!s || !s.turn || s.turn.settled || s.closing || s.child.exitCode !== null) return false;
|
|
23513
|
-
return writeUser(s, threadId, claudeUserMessage(
|
|
23675
|
+
return writeUser(s, threadId, claudeUserMessage(text4, void 0));
|
|
23514
23676
|
};
|
|
23515
23677
|
const login = new ClaudeLoginController({ cli: config2.cli, environment, onAuthenticated: async () => {
|
|
23516
23678
|
await refreshModels();
|
|
@@ -23788,7 +23950,7 @@ function unquote(raw) {
|
|
|
23788
23950
|
}
|
|
23789
23951
|
return value;
|
|
23790
23952
|
}
|
|
23791
|
-
function parseCodexToml(
|
|
23953
|
+
function parseCodexToml(text4) {
|
|
23792
23954
|
const result = { providers: [] };
|
|
23793
23955
|
const byId = /* @__PURE__ */ new Map();
|
|
23794
23956
|
let section = "root";
|
|
@@ -23801,7 +23963,7 @@ function parseCodexToml(text3) {
|
|
|
23801
23963
|
}
|
|
23802
23964
|
return provider;
|
|
23803
23965
|
};
|
|
23804
|
-
for (const line of
|
|
23966
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
23805
23967
|
const stripped = line.trim();
|
|
23806
23968
|
if (!stripped || stripped.startsWith("#")) continue;
|
|
23807
23969
|
if (stripped.startsWith("[") && stripped.endsWith("]")) {
|
|
@@ -24883,6 +25045,7 @@ var init_codex = __esm({
|
|
|
24883
25045
|
const earlyNotifications = [];
|
|
24884
25046
|
const state = {
|
|
24885
25047
|
settled: false,
|
|
25048
|
+
lastError: "",
|
|
24886
25049
|
lastText: "",
|
|
24887
25050
|
sawStreamDelta: false,
|
|
24888
25051
|
// codex reports token usage as a running THREAD total; the harness
|
|
@@ -25144,13 +25307,26 @@ var init_codex = __esm({
|
|
|
25144
25307
|
}
|
|
25145
25308
|
case "turn/completed": {
|
|
25146
25309
|
const t2 = p.turn ?? {};
|
|
25147
|
-
|
|
25310
|
+
const message2 = typeof t2.error?.message === "string" ? t2.error.message.slice(0, 400) : "";
|
|
25311
|
+
if (t2.status !== "completed" && message2 && message2 !== state.lastError) {
|
|
25312
|
+
state.lastError = message2;
|
|
25313
|
+
emit({
|
|
25314
|
+
...base2(threadId, turnId),
|
|
25315
|
+
type: "runtime.error",
|
|
25316
|
+
message: message2,
|
|
25317
|
+
...classifyError({ text: message2 }).reason === "auth" ? { setup: true } : {}
|
|
25318
|
+
});
|
|
25319
|
+
}
|
|
25320
|
+
void settle(t2.status === "completed", t2.status === "completed" ? null : classifyError({ text: message2 || state.lastError }).reason === "provider_safety" ? "provider_safety" : message2 || t2.status || "failed");
|
|
25148
25321
|
break;
|
|
25149
25322
|
}
|
|
25150
25323
|
case "error":
|
|
25151
25324
|
{
|
|
25152
25325
|
const message2 = p.message ?? p.error?.message;
|
|
25153
|
-
if (message2)
|
|
25326
|
+
if (message2) {
|
|
25327
|
+
state.lastError = String(message2).slice(0, 400);
|
|
25328
|
+
emit({ ...base2(threadId, turnId), type: "runtime.error", message: state.lastError });
|
|
25329
|
+
}
|
|
25154
25330
|
}
|
|
25155
25331
|
break;
|
|
25156
25332
|
}
|
|
@@ -25358,7 +25534,7 @@ var init_codex = __esm({
|
|
|
25358
25534
|
message: message2,
|
|
25359
25535
|
...needsAuth ? { setup: true } : {}
|
|
25360
25536
|
});
|
|
25361
|
-
await settle(false, needsAuth ? "auth_required" : "rpc_error");
|
|
25537
|
+
await settle(false, needsAuth ? "auth_required" : verdict.reason === "provider_safety" ? "provider_safety" : "rpc_error");
|
|
25362
25538
|
}
|
|
25363
25539
|
}
|
|
25364
25540
|
};
|
|
@@ -25472,72 +25648,89 @@ function createOpenAIChatRuntime(options) {
|
|
|
25472
25648
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
25473
25649
|
});
|
|
25474
25650
|
const complete = async (messages, model, stream, signal, onDelta) => {
|
|
25475
|
-
const
|
|
25476
|
-
|
|
25477
|
-
|
|
25478
|
-
|
|
25479
|
-
|
|
25480
|
-
|
|
25481
|
-
|
|
25482
|
-
|
|
25483
|
-
|
|
25484
|
-
throw new Error(`${options.httpErrorLabel} HTTP ${response.status}${body ? `: ${body.slice(0, 200)}` : ""}`);
|
|
25485
|
-
}
|
|
25486
|
-
if (!stream) {
|
|
25487
|
-
const json2 = await response.json();
|
|
25488
|
-
const message2 = json2.choices?.[0]?.message;
|
|
25489
|
-
return {
|
|
25490
|
-
text: typeof message2?.content === "string" ? message2.content : "",
|
|
25491
|
-
reasoning: options.reasoning && typeof message2?.reasoning_content === "string" ? message2.reasoning_content : "",
|
|
25492
|
-
usage: usageFrom(json2.usage)
|
|
25493
|
-
};
|
|
25494
|
-
}
|
|
25495
|
-
if (!response.body) {
|
|
25496
|
-
throw new Error(options.noBodyError ?? `${options.httpErrorLabel} returned no response body`);
|
|
25497
|
-
}
|
|
25498
|
-
let text3 = "";
|
|
25499
|
-
let reasoning = "";
|
|
25500
|
-
let usage = null;
|
|
25501
|
-
const reader = response.body.getReader();
|
|
25502
|
-
const decoder = new TextDecoder();
|
|
25503
|
-
let buffer = "";
|
|
25651
|
+
const timeoutController = new AbortController();
|
|
25652
|
+
let idleTimer = null;
|
|
25653
|
+
const resetIdleTimer = () => {
|
|
25654
|
+
if (idleTimer) clearTimeout(idleTimer);
|
|
25655
|
+
idleTimer = setTimeout(() => {
|
|
25656
|
+
timeoutController.abort(new DOMException("Streaming idle timeout elapsed", "AbortError"));
|
|
25657
|
+
}, options.timeoutMs);
|
|
25658
|
+
};
|
|
25659
|
+
resetIdleTimer();
|
|
25504
25660
|
try {
|
|
25505
|
-
|
|
25506
|
-
|
|
25507
|
-
|
|
25508
|
-
|
|
25509
|
-
|
|
25510
|
-
|
|
25511
|
-
|
|
25512
|
-
|
|
25513
|
-
|
|
25514
|
-
|
|
25515
|
-
|
|
25516
|
-
|
|
25517
|
-
|
|
25518
|
-
|
|
25519
|
-
|
|
25520
|
-
|
|
25521
|
-
|
|
25522
|
-
|
|
25523
|
-
|
|
25524
|
-
|
|
25525
|
-
|
|
25526
|
-
|
|
25527
|
-
|
|
25528
|
-
|
|
25529
|
-
|
|
25530
|
-
|
|
25531
|
-
|
|
25661
|
+
const activeSignal = signal ? AbortSignal.any([signal, timeoutController.signal]) : timeoutController.signal;
|
|
25662
|
+
const response = await fetch(`${options.apiUrl}/chat/completions`, {
|
|
25663
|
+
method: "POST",
|
|
25664
|
+
headers: { authorization: `Bearer ${options.apiKey}`, "content-type": "application/json" },
|
|
25665
|
+
body: JSON.stringify(options.requestBody(model, messages, stream)),
|
|
25666
|
+
signal: activeSignal
|
|
25667
|
+
});
|
|
25668
|
+
if (!response.ok) {
|
|
25669
|
+
const body = await response.text().catch(() => "");
|
|
25670
|
+
throw new Error(`${options.httpErrorLabel} HTTP ${response.status}${body ? `: ${body.slice(0, 200)}` : ""}`);
|
|
25671
|
+
}
|
|
25672
|
+
if (!stream) {
|
|
25673
|
+
const json2 = await response.json();
|
|
25674
|
+
const message2 = json2.choices?.[0]?.message;
|
|
25675
|
+
return {
|
|
25676
|
+
text: typeof message2?.content === "string" ? message2.content : "",
|
|
25677
|
+
reasoning: options.reasoning && typeof message2?.reasoning_content === "string" ? message2.reasoning_content : "",
|
|
25678
|
+
usage: usageFrom(json2.usage)
|
|
25679
|
+
};
|
|
25680
|
+
}
|
|
25681
|
+
if (!response.body) {
|
|
25682
|
+
throw new Error(options.noBodyError ?? `${options.httpErrorLabel} returned no response body`);
|
|
25683
|
+
}
|
|
25684
|
+
let text4 = "";
|
|
25685
|
+
let reasoning = "";
|
|
25686
|
+
let usage = null;
|
|
25687
|
+
const reader = response.body.getReader();
|
|
25688
|
+
const decoder = new TextDecoder();
|
|
25689
|
+
let buffer = "";
|
|
25690
|
+
try {
|
|
25691
|
+
readLoop: for (; ; ) {
|
|
25692
|
+
const { done, value } = await reader.read();
|
|
25693
|
+
if (done) {
|
|
25694
|
+
if (buffer.trim() === "data: [DONE]") break;
|
|
25695
|
+
throw new DOMException("Stream ended before completion", "AbortError");
|
|
25696
|
+
}
|
|
25697
|
+
resetIdleTimer();
|
|
25698
|
+
buffer += decoder.decode(value, { stream: true });
|
|
25699
|
+
let newline;
|
|
25700
|
+
while ((newline = buffer.indexOf("\n")) !== -1) {
|
|
25701
|
+
const line = buffer.slice(0, newline).trim();
|
|
25702
|
+
buffer = buffer.slice(newline + 1);
|
|
25703
|
+
if (!line.startsWith("data:")) continue;
|
|
25704
|
+
const data = line.slice(5).trim();
|
|
25705
|
+
if (data === "[DONE]") break readLoop;
|
|
25706
|
+
let chunk;
|
|
25707
|
+
try {
|
|
25708
|
+
chunk = JSON.parse(data);
|
|
25709
|
+
} catch {
|
|
25710
|
+
continue;
|
|
25711
|
+
}
|
|
25712
|
+
const delta = chunk.choices?.[0]?.delta;
|
|
25713
|
+
const reasoningDelta = options.reasoning && typeof delta?.reasoning_content === "string" ? delta.reasoning_content : "";
|
|
25714
|
+
const contentDelta = typeof delta?.content === "string" ? delta.content : "";
|
|
25715
|
+
if (reasoningDelta) {
|
|
25716
|
+
reasoning += reasoningDelta;
|
|
25717
|
+
onDelta?.(reasoningDelta, "reasoning_text");
|
|
25718
|
+
}
|
|
25719
|
+
if (contentDelta) {
|
|
25720
|
+
text4 += contentDelta;
|
|
25721
|
+
onDelta?.(contentDelta, "assistant_text");
|
|
25722
|
+
}
|
|
25723
|
+
if (chunk.usage) usage = usageFrom(chunk.usage);
|
|
25532
25724
|
}
|
|
25533
|
-
if (chunk.usage) usage = usageFrom(chunk.usage);
|
|
25534
25725
|
}
|
|
25726
|
+
} finally {
|
|
25727
|
+
await reader.cancel().catch(() => {
|
|
25728
|
+
});
|
|
25535
25729
|
}
|
|
25730
|
+
return { text: text4, reasoning, usage };
|
|
25536
25731
|
} finally {
|
|
25537
|
-
|
|
25538
|
-
});
|
|
25732
|
+
if (idleTimer) clearTimeout(idleTimer);
|
|
25539
25733
|
}
|
|
25540
|
-
return { text: text3, reasoning, usage };
|
|
25541
25734
|
};
|
|
25542
25735
|
const messagesFor = (turn) => [
|
|
25543
25736
|
...turn.system ? [{ role: "system", content: turn.system }] : [],
|
|
@@ -25654,8 +25847,8 @@ function createOpenAIChatRuntime(options) {
|
|
|
25654
25847
|
},
|
|
25655
25848
|
generateText: async (prompt) => {
|
|
25656
25849
|
const model = options.generateModel?.() ?? options.models().default;
|
|
25657
|
-
const { text:
|
|
25658
|
-
return
|
|
25850
|
+
const { text: text4, reasoning } = await complete([{ role: "user", content: prompt }], model, false);
|
|
25851
|
+
return text4.trim() ? text4 : reasoning;
|
|
25659
25852
|
},
|
|
25660
25853
|
dispose: async () => {
|
|
25661
25854
|
for (const abort of active.values()) abort.abort();
|
|
@@ -25723,7 +25916,7 @@ var init_grok = __esm({
|
|
|
25723
25916
|
nativeLog: {
|
|
25724
25917
|
source: "xai.chat.completions",
|
|
25725
25918
|
outgoing: (_turn, messages, model) => ({ model, messages }),
|
|
25726
|
-
incoming: ({ text:
|
|
25919
|
+
incoming: ({ text: text4, usage }) => ({ text: text4, usage })
|
|
25727
25920
|
}
|
|
25728
25921
|
});
|
|
25729
25922
|
}
|
|
@@ -25748,9 +25941,9 @@ function unquote2(raw) {
|
|
|
25748
25941
|
}
|
|
25749
25942
|
function readGrokModelCatalog(env = process.env) {
|
|
25750
25943
|
const path3 = join25(grokHome(env), "config.toml");
|
|
25751
|
-
let
|
|
25944
|
+
let text4 = "";
|
|
25752
25945
|
try {
|
|
25753
|
-
|
|
25946
|
+
text4 = readFileSync11(path3, "utf8");
|
|
25754
25947
|
} catch {
|
|
25755
25948
|
return STATIC_GROK_MODELS;
|
|
25756
25949
|
}
|
|
@@ -25768,7 +25961,7 @@ function readGrokModelCatalog(env = process.env) {
|
|
|
25768
25961
|
options.push({ id: current.slug, label: current.name || current.slug, custom: true });
|
|
25769
25962
|
current = null;
|
|
25770
25963
|
};
|
|
25771
|
-
for (const line of
|
|
25964
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
25772
25965
|
const stripped = line.trim();
|
|
25773
25966
|
if (stripped === "[models]") {
|
|
25774
25967
|
flush();
|
|
@@ -25821,11 +26014,11 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
25821
26014
|
const host = localHost(inject.host);
|
|
25822
26015
|
if (!host) return modelId;
|
|
25823
26016
|
const path3 = join25(grokHome(env), "config.toml");
|
|
25824
|
-
let
|
|
26017
|
+
let text4 = "";
|
|
25825
26018
|
try {
|
|
25826
|
-
|
|
26019
|
+
text4 = readFileSync11(path3, "utf8");
|
|
25827
26020
|
} catch {
|
|
25828
|
-
|
|
26021
|
+
text4 = "";
|
|
25829
26022
|
}
|
|
25830
26023
|
const taken = new Set(STATIC_GROK_MODELS.options.map((option) => option.id));
|
|
25831
26024
|
let current = null;
|
|
@@ -25838,7 +26031,7 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
25838
26031
|
current = null;
|
|
25839
26032
|
};
|
|
25840
26033
|
let found = null;
|
|
25841
|
-
for (const line of
|
|
26034
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
25842
26035
|
const stripped = line.trim();
|
|
25843
26036
|
if (stripped.startsWith("[model.") && stripped.endsWith("]")) {
|
|
25844
26037
|
flush();
|
|
@@ -25871,12 +26064,18 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
25871
26064
|
`api_key = ${quoteToml(hostApiKey(host, env))}`,
|
|
25872
26065
|
""
|
|
25873
26066
|
].join("\n");
|
|
25874
|
-
const next =
|
|
26067
|
+
const next = text4 && !text4.endsWith("\n") ? `${text4}
|
|
25875
26068
|
|
|
25876
|
-
${block2}` : `${
|
|
26069
|
+
${block2}` : `${text4}${text4 ? "\n" : ""}${block2}`;
|
|
25877
26070
|
writeFileSync7(path3, next);
|
|
25878
26071
|
return slug;
|
|
25879
26072
|
}
|
|
26073
|
+
function grokAcceptsUnadvertisedImages(init) {
|
|
26074
|
+
const meta3 = init?._meta;
|
|
26075
|
+
if (meta3?.grokShell !== true || typeof meta3.agentVersion !== "string") return false;
|
|
26076
|
+
const version2 = /^1\.0\.(\d+)$/.exec(meta3.agentVersion);
|
|
26077
|
+
return Boolean(version2 && Number(version2[1]) >= 25);
|
|
26078
|
+
}
|
|
25880
26079
|
var STATIC_GROK_MODELS, SLUG, support2, GrokAgentDriver;
|
|
25881
26080
|
var init_grok2 = __esm({
|
|
25882
26081
|
"server/drivers/acp/grok.ts"() {
|
|
@@ -25894,7 +26093,8 @@ var init_grok2 = __esm({
|
|
|
25894
26093
|
support2 = {
|
|
25895
26094
|
driverKind: "grokAgent",
|
|
25896
26095
|
displayName: "Grok",
|
|
25897
|
-
images:
|
|
26096
|
+
images: true,
|
|
26097
|
+
acceptsUnadvertisedImages: grokAcceptsUnadvertisedImages,
|
|
25898
26098
|
models: STATIC_GROK_MODELS,
|
|
25899
26099
|
resolveModels: (env) => mergeLocalInject(readGrokModelCatalog(env), env),
|
|
25900
26100
|
// Grok's accepted levels vary by model and the CLI validates lazily — a
|
|
@@ -26068,18 +26268,18 @@ function stripTomlLineComment(line) {
|
|
|
26068
26268
|
}
|
|
26069
26269
|
return line;
|
|
26070
26270
|
}
|
|
26071
|
-
function takeTomlBasicEscape(
|
|
26072
|
-
const code =
|
|
26271
|
+
function takeTomlBasicEscape(text4, i2) {
|
|
26272
|
+
const code = text4[i2 + 1];
|
|
26073
26273
|
if (code === void 0) return { ok: false };
|
|
26074
26274
|
if (code === "u") {
|
|
26075
|
-
const hex3 =
|
|
26275
|
+
const hex3 = text4.slice(i2 + 2, i2 + 6);
|
|
26076
26276
|
if (!/^[0-9a-fA-F]{4}$/.test(hex3)) return { ok: false };
|
|
26077
26277
|
const point = parseInt(hex3, 16);
|
|
26078
26278
|
if (point >= 55296 && point <= 57343) return { ok: false };
|
|
26079
26279
|
return { ok: true, value: String.fromCharCode(point), next: i2 + 6 };
|
|
26080
26280
|
}
|
|
26081
26281
|
if (code === "U") {
|
|
26082
|
-
const hex3 =
|
|
26282
|
+
const hex3 = text4.slice(i2 + 2, i2 + 10);
|
|
26083
26283
|
if (!/^[0-9a-fA-F]{8}$/.test(hex3)) return { ok: false };
|
|
26084
26284
|
const point = parseInt(hex3, 16);
|
|
26085
26285
|
if (point > 1114111 || point >= 55296 && point <= 57343) return { ok: false };
|
|
@@ -26151,14 +26351,14 @@ function tomlRowKey(row) {
|
|
|
26151
26351
|
const eq = row.indexOf("=");
|
|
26152
26352
|
return unquoteTomlKey(eq < 0 ? row : row.slice(0, eq));
|
|
26153
26353
|
}
|
|
26154
|
-
function tomlTables(
|
|
26354
|
+
function tomlTables(text4) {
|
|
26155
26355
|
const headings = [];
|
|
26156
26356
|
let mode = "out";
|
|
26157
26357
|
let i2 = 0;
|
|
26158
|
-
const atLineStart = (idx) => idx === 0 ||
|
|
26159
|
-
while (i2 <
|
|
26358
|
+
const atLineStart = (idx) => idx === 0 || text4[idx - 1] === "\n";
|
|
26359
|
+
while (i2 < text4.length) {
|
|
26160
26360
|
if (mode === "mlbasic") {
|
|
26161
|
-
if (
|
|
26361
|
+
if (text4.startsWith('"""', i2)) {
|
|
26162
26362
|
mode = "out";
|
|
26163
26363
|
i2 += 3;
|
|
26164
26364
|
continue;
|
|
@@ -26167,7 +26367,7 @@ function tomlTables(text3) {
|
|
|
26167
26367
|
continue;
|
|
26168
26368
|
}
|
|
26169
26369
|
if (mode === "mllit") {
|
|
26170
|
-
if (
|
|
26370
|
+
if (text4.startsWith("'''", i2)) {
|
|
26171
26371
|
mode = "out";
|
|
26172
26372
|
i2 += 3;
|
|
26173
26373
|
continue;
|
|
@@ -26176,61 +26376,61 @@ function tomlTables(text3) {
|
|
|
26176
26376
|
continue;
|
|
26177
26377
|
}
|
|
26178
26378
|
if (mode === "basic") {
|
|
26179
|
-
if (
|
|
26379
|
+
if (text4[i2] === "\n") {
|
|
26180
26380
|
mode = "out";
|
|
26181
26381
|
i2 += 1;
|
|
26182
26382
|
continue;
|
|
26183
26383
|
}
|
|
26184
|
-
if (
|
|
26384
|
+
if (text4[i2] === "\\") {
|
|
26185
26385
|
i2 += 2;
|
|
26186
26386
|
continue;
|
|
26187
26387
|
}
|
|
26188
|
-
if (
|
|
26388
|
+
if (text4[i2] === '"') mode = "out";
|
|
26189
26389
|
i2 += 1;
|
|
26190
26390
|
continue;
|
|
26191
26391
|
}
|
|
26192
26392
|
if (mode === "literal") {
|
|
26193
|
-
if (
|
|
26393
|
+
if (text4[i2] === "\n") {
|
|
26194
26394
|
mode = "out";
|
|
26195
26395
|
i2 += 1;
|
|
26196
26396
|
continue;
|
|
26197
26397
|
}
|
|
26198
|
-
if (
|
|
26398
|
+
if (text4[i2] === "'") mode = "out";
|
|
26199
26399
|
i2 += 1;
|
|
26200
26400
|
continue;
|
|
26201
26401
|
}
|
|
26202
|
-
if (
|
|
26402
|
+
if (text4.startsWith('"""', i2)) {
|
|
26203
26403
|
mode = "mlbasic";
|
|
26204
26404
|
i2 += 3;
|
|
26205
26405
|
continue;
|
|
26206
26406
|
}
|
|
26207
|
-
if (
|
|
26407
|
+
if (text4.startsWith("'''", i2)) {
|
|
26208
26408
|
mode = "mllit";
|
|
26209
26409
|
i2 += 3;
|
|
26210
26410
|
continue;
|
|
26211
26411
|
}
|
|
26212
|
-
if (
|
|
26412
|
+
if (text4[i2] === '"') {
|
|
26213
26413
|
mode = "basic";
|
|
26214
26414
|
i2 += 1;
|
|
26215
26415
|
continue;
|
|
26216
26416
|
}
|
|
26217
|
-
if (
|
|
26417
|
+
if (text4[i2] === "'") {
|
|
26218
26418
|
mode = "literal";
|
|
26219
26419
|
i2 += 1;
|
|
26220
26420
|
continue;
|
|
26221
26421
|
}
|
|
26222
|
-
if (
|
|
26223
|
-
const nl =
|
|
26224
|
-
i2 = nl < 0 ?
|
|
26422
|
+
if (text4[i2] === "#") {
|
|
26423
|
+
const nl = text4.indexOf("\n", i2);
|
|
26424
|
+
i2 = nl < 0 ? text4.length : nl + 1;
|
|
26225
26425
|
continue;
|
|
26226
26426
|
}
|
|
26227
26427
|
if (atLineStart(i2)) {
|
|
26228
26428
|
let j = i2;
|
|
26229
|
-
while (j <
|
|
26230
|
-
if (
|
|
26231
|
-
const nl =
|
|
26232
|
-
const lineEnd = nl < 0 ?
|
|
26233
|
-
const raw =
|
|
26429
|
+
while (j < text4.length && (text4[j] === " " || text4[j] === " ")) j += 1;
|
|
26430
|
+
if (text4[j] === "[") {
|
|
26431
|
+
const nl = text4.indexOf("\n", j);
|
|
26432
|
+
const lineEnd = nl < 0 ? text4.length : nl;
|
|
26433
|
+
const raw = text4.slice(j, lineEnd).replace(/\r$/, "");
|
|
26234
26434
|
const stripped = stripTomlLineComment(raw).trim();
|
|
26235
26435
|
const array2 = stripped.startsWith("[[");
|
|
26236
26436
|
const name = array2 ? canonicalizeTomlHeading(`[${stripped.replace(/^\s*\[\[/, "").replace(/\]\]\s*$/, "")}]`) : canonicalizeTomlHeading(raw);
|
|
@@ -26243,11 +26443,11 @@ function tomlTables(text3) {
|
|
|
26243
26443
|
}
|
|
26244
26444
|
return headings.map((heading, index) => ({
|
|
26245
26445
|
heading,
|
|
26246
|
-
end: index + 1 < headings.length ? headings[index + 1].lineStart :
|
|
26446
|
+
end: index + 1 < headings.length ? headings[index + 1].lineStart : text4.length
|
|
26247
26447
|
})).filter((entry) => entry.heading.patchable && entry.heading.name).map((entry) => ({
|
|
26248
26448
|
name: entry.heading.name,
|
|
26249
26449
|
headingStart: entry.heading.lineStart,
|
|
26250
|
-
bodyStart: entry.heading.lineEnd + (
|
|
26450
|
+
bodyStart: entry.heading.lineEnd + (text4[entry.heading.lineEnd] === "\n" ? 1 : 0),
|
|
26251
26451
|
end: entry.end
|
|
26252
26452
|
}));
|
|
26253
26453
|
}
|
|
@@ -26303,22 +26503,22 @@ function tomlKeys(block2) {
|
|
|
26303
26503
|
take(block2.length);
|
|
26304
26504
|
return keys;
|
|
26305
26505
|
}
|
|
26306
|
-
function hasTomlTable(
|
|
26506
|
+
function hasTomlTable(text4, heading) {
|
|
26307
26507
|
const name = canonicalizeTomlHeading(heading);
|
|
26308
|
-
return name !== null && tomlTables(
|
|
26508
|
+
return name !== null && tomlTables(text4).some((table) => table.name === name);
|
|
26309
26509
|
}
|
|
26310
|
-
function patchTomlTable(
|
|
26510
|
+
function patchTomlTable(text4, heading, rows) {
|
|
26311
26511
|
const name = canonicalizeTomlHeading(heading);
|
|
26312
|
-
if (!name) return
|
|
26313
|
-
const table = tomlTables(
|
|
26314
|
-
if (!table) return
|
|
26315
|
-
const keys = tomlKeys(
|
|
26512
|
+
if (!name) return text4;
|
|
26513
|
+
const table = tomlTables(text4).find((entry) => entry.name === name);
|
|
26514
|
+
if (!table) return text4;
|
|
26515
|
+
const keys = tomlKeys(text4.slice(table.bodyStart, table.end));
|
|
26316
26516
|
const missing = rows.filter((row) => !keys.has(tomlRowKey(row)));
|
|
26317
|
-
if (!missing.length) return
|
|
26517
|
+
if (!missing.length) return text4;
|
|
26318
26518
|
let insertAt = table.end;
|
|
26319
|
-
while (insertAt > table.bodyStart && (
|
|
26320
|
-
const before =
|
|
26321
|
-
const after =
|
|
26519
|
+
while (insertAt > table.bodyStart && (text4[insertAt - 1] === "\n" || text4[insertAt - 1] === "\r")) insertAt -= 1;
|
|
26520
|
+
const before = text4.slice(0, insertAt);
|
|
26521
|
+
const after = text4.slice(insertAt);
|
|
26322
26522
|
const pad = before.endsWith("\n") || before.length === 0 ? "" : "\n";
|
|
26323
26523
|
return `${before}${pad}${missing.join("\n")}${after.startsWith("\n") ? "" : "\n"}${after}`;
|
|
26324
26524
|
}
|
|
@@ -26331,17 +26531,17 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
26331
26531
|
const dataRoot = kimiDataRoot(env);
|
|
26332
26532
|
mkdirSync10(dataRoot, { recursive: true });
|
|
26333
26533
|
const path3 = join27(dataRoot, "config.toml");
|
|
26334
|
-
let
|
|
26534
|
+
let text4 = "";
|
|
26335
26535
|
try {
|
|
26336
|
-
|
|
26536
|
+
text4 = readFileSync13(path3, "utf8");
|
|
26337
26537
|
} catch {
|
|
26338
|
-
|
|
26538
|
+
text4 = "";
|
|
26339
26539
|
}
|
|
26340
|
-
const original =
|
|
26540
|
+
const original = text4;
|
|
26341
26541
|
const providerHeading = `[providers.${inject.host}]`;
|
|
26342
26542
|
const modelHeading = `[models.${quoteTomlKey(alias)}]`;
|
|
26343
26543
|
const blocks = [];
|
|
26344
|
-
if (!hasTomlTable(
|
|
26544
|
+
if (!hasTomlTable(text4, providerHeading)) {
|
|
26345
26545
|
blocks.push(
|
|
26346
26546
|
[
|
|
26347
26547
|
providerHeading,
|
|
@@ -26352,8 +26552,8 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
26352
26552
|
].join("\n")
|
|
26353
26553
|
);
|
|
26354
26554
|
}
|
|
26355
|
-
if (hasTomlTable(
|
|
26356
|
-
|
|
26555
|
+
if (hasTomlTable(text4, modelHeading)) {
|
|
26556
|
+
text4 = patchTomlTable(text4, modelHeading, [`protocol = "openai"`, `max_context_size = 262144`]);
|
|
26357
26557
|
} else {
|
|
26358
26558
|
blocks.push(
|
|
26359
26559
|
[
|
|
@@ -26367,13 +26567,13 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
26367
26567
|
);
|
|
26368
26568
|
}
|
|
26369
26569
|
if (blocks.length) {
|
|
26370
|
-
const prefix =
|
|
26570
|
+
const prefix = text4 && !text4.endsWith("\n") ? `${text4}
|
|
26371
26571
|
|
|
26372
|
-
` :
|
|
26572
|
+
` : text4 ? `${text4}
|
|
26373
26573
|
` : "";
|
|
26374
26574
|
writeFileSync8(path3, `${prefix}${blocks.join("\n")}`);
|
|
26375
|
-
} else if (
|
|
26376
|
-
writeFileSync8(path3,
|
|
26575
|
+
} else if (text4 !== original) {
|
|
26576
|
+
writeFileSync8(path3, text4);
|
|
26377
26577
|
}
|
|
26378
26578
|
return alias;
|
|
26379
26579
|
}
|
|
@@ -26393,9 +26593,9 @@ function stripKimiModelEnv(env) {
|
|
|
26393
26593
|
}
|
|
26394
26594
|
function readKimiModelCatalog(env) {
|
|
26395
26595
|
const dataRoot = kimiDataRoot(env);
|
|
26396
|
-
let
|
|
26596
|
+
let text4 = "";
|
|
26397
26597
|
try {
|
|
26398
|
-
|
|
26598
|
+
text4 = readFileSync13(join27(dataRoot, "config.toml"), "utf8");
|
|
26399
26599
|
} catch {
|
|
26400
26600
|
return STATIC_KIMI_MODELS;
|
|
26401
26601
|
}
|
|
@@ -26411,7 +26611,7 @@ function readKimiModelCatalog(env) {
|
|
|
26411
26611
|
options.push({ id: current.slug, label: current.name || current.slug, custom: true });
|
|
26412
26612
|
current = null;
|
|
26413
26613
|
};
|
|
26414
|
-
for (const line of
|
|
26614
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
26415
26615
|
const stripped = line.trim();
|
|
26416
26616
|
if ((stripped.startsWith("[model.") || stripped.startsWith("[models.")) && stripped.endsWith("]")) {
|
|
26417
26617
|
flush();
|
|
@@ -26704,8 +26904,8 @@ function resolveCursorAcpModelId(available, wanted) {
|
|
|
26704
26904
|
}
|
|
26705
26905
|
return null;
|
|
26706
26906
|
}
|
|
26707
|
-
function firstJsonValue(
|
|
26708
|
-
const trimmed =
|
|
26907
|
+
function firstJsonValue(text4) {
|
|
26908
|
+
const trimmed = text4.trim();
|
|
26709
26909
|
if (!trimmed) return null;
|
|
26710
26910
|
try {
|
|
26711
26911
|
return JSON.parse(trimmed);
|
|
@@ -26779,12 +26979,12 @@ function stripModelMarkers(label) {
|
|
|
26779
26979
|
}
|
|
26780
26980
|
return { label: cleaned, isDefault, isCurrent };
|
|
26781
26981
|
}
|
|
26782
|
-
function decodeCursorModelText(
|
|
26982
|
+
function decodeCursorModelText(text4) {
|
|
26783
26983
|
const options = [];
|
|
26784
26984
|
const seen = /* @__PURE__ */ new Set();
|
|
26785
26985
|
let markedDefault;
|
|
26786
26986
|
let markedCurrent;
|
|
26787
|
-
for (const raw of
|
|
26987
|
+
for (const raw of text4.split(/\r?\n/)) {
|
|
26788
26988
|
const line = raw.trim();
|
|
26789
26989
|
if (!line || line.startsWith("#") || /^available\s+models?\b/i.test(line) || /^models?\b/i.test(line)) continue;
|
|
26790
26990
|
const stripped = line.replace(/^[\s*•-]+\s*/, "");
|
|
@@ -26837,8 +27037,8 @@ function decodeCursorAuthStatus(payload) {
|
|
|
26837
27037
|
}
|
|
26838
27038
|
return null;
|
|
26839
27039
|
}
|
|
26840
|
-
function decodeCursorAuthText(
|
|
26841
|
-
const normalized =
|
|
27040
|
+
function decodeCursorAuthText(text4) {
|
|
27041
|
+
const normalized = text4.trim().toLowerCase();
|
|
26842
27042
|
if (!normalized) return null;
|
|
26843
27043
|
if (/not (?:logged|signed) in|not authenticated|unauthenticated|logged out/.test(normalized)) return false;
|
|
26844
27044
|
if (/login successful|logged in|signed in|authenticated/.test(normalized)) return true;
|
|
@@ -27258,7 +27458,7 @@ function qwenHome(env) {
|
|
|
27258
27458
|
const home = process.platform === "win32" ? env.USERPROFILE || env.HOME || homedir19() : env.HOME || env.USERPROFILE || homedir19();
|
|
27259
27459
|
return join30(home, ".qwen");
|
|
27260
27460
|
}
|
|
27261
|
-
function
|
|
27461
|
+
function isRecord2(value) {
|
|
27262
27462
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
27263
27463
|
}
|
|
27264
27464
|
function qwenModelLabel(id, name) {
|
|
@@ -27272,15 +27472,15 @@ function readQwenRoutes(env) {
|
|
|
27272
27472
|
} catch {
|
|
27273
27473
|
return [];
|
|
27274
27474
|
}
|
|
27275
|
-
if (!
|
|
27475
|
+
if (!isRecord2(settings2) || !isRecord2(settings2.modelProviders)) return [];
|
|
27276
27476
|
const routes = [];
|
|
27277
27477
|
const seen = /* @__PURE__ */ new Set();
|
|
27278
|
-
const mappings =
|
|
27478
|
+
const mappings = isRecord2(settings2.providerProtocol) ? settings2.providerProtocol : {};
|
|
27279
27479
|
for (const [provider, rows] of Object.entries(settings2.modelProviders)) {
|
|
27280
27480
|
const protocol = Object.hasOwn(mappings, provider) ? mappings[provider] : provider;
|
|
27281
27481
|
if (typeof protocol !== "string" || !PROTOCOLS.has(protocol) || !Array.isArray(rows)) continue;
|
|
27282
27482
|
for (const row of rows) {
|
|
27283
|
-
if (!
|
|
27483
|
+
if (!isRecord2(row) || typeof row.id !== "string") continue;
|
|
27284
27484
|
const model = row.id;
|
|
27285
27485
|
if (!model.trim()) continue;
|
|
27286
27486
|
if (row.baseUrl !== void 0 && typeof row.baseUrl !== "string") continue;
|
|
@@ -28426,14 +28626,14 @@ var init_stringifyComment = __esm({
|
|
|
28426
28626
|
});
|
|
28427
28627
|
|
|
28428
28628
|
// node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/foldFlowLines.js
|
|
28429
|
-
function foldFlowLines(
|
|
28629
|
+
function foldFlowLines(text4, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
|
|
28430
28630
|
if (!lineWidth || lineWidth < 0)
|
|
28431
|
-
return
|
|
28631
|
+
return text4;
|
|
28432
28632
|
if (lineWidth < minContentWidth)
|
|
28433
28633
|
minContentWidth = 0;
|
|
28434
28634
|
const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
|
|
28435
|
-
if (
|
|
28436
|
-
return
|
|
28635
|
+
if (text4.length <= endStep)
|
|
28636
|
+
return text4;
|
|
28437
28637
|
const folds = [];
|
|
28438
28638
|
const escapedFolds = {};
|
|
28439
28639
|
let end = lineWidth - indent.length;
|
|
@@ -28450,14 +28650,14 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28450
28650
|
let escStart = -1;
|
|
28451
28651
|
let escEnd = -1;
|
|
28452
28652
|
if (mode === FOLD_BLOCK) {
|
|
28453
|
-
i2 = consumeMoreIndentedLines(
|
|
28653
|
+
i2 = consumeMoreIndentedLines(text4, i2, indent.length);
|
|
28454
28654
|
if (i2 !== -1)
|
|
28455
28655
|
end = i2 + endStep;
|
|
28456
28656
|
}
|
|
28457
|
-
for (let ch; ch =
|
|
28657
|
+
for (let ch; ch = text4[i2 += 1]; ) {
|
|
28458
28658
|
if (mode === FOLD_QUOTED && ch === "\\") {
|
|
28459
28659
|
escStart = i2;
|
|
28460
|
-
switch (
|
|
28660
|
+
switch (text4[i2 + 1]) {
|
|
28461
28661
|
case "x":
|
|
28462
28662
|
i2 += 3;
|
|
28463
28663
|
break;
|
|
@@ -28474,12 +28674,12 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28474
28674
|
}
|
|
28475
28675
|
if (ch === "\n") {
|
|
28476
28676
|
if (mode === FOLD_BLOCK)
|
|
28477
|
-
i2 = consumeMoreIndentedLines(
|
|
28677
|
+
i2 = consumeMoreIndentedLines(text4, i2, indent.length);
|
|
28478
28678
|
end = i2 + indent.length + endStep;
|
|
28479
28679
|
split = void 0;
|
|
28480
28680
|
} else {
|
|
28481
28681
|
if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
|
|
28482
|
-
const next =
|
|
28682
|
+
const next = text4[i2 + 1];
|
|
28483
28683
|
if (next && next !== " " && next !== "\n" && next !== " ")
|
|
28484
28684
|
split = i2;
|
|
28485
28685
|
}
|
|
@@ -28491,12 +28691,12 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28491
28691
|
} else if (mode === FOLD_QUOTED) {
|
|
28492
28692
|
while (prev === " " || prev === " ") {
|
|
28493
28693
|
prev = ch;
|
|
28494
|
-
ch =
|
|
28694
|
+
ch = text4[i2 += 1];
|
|
28495
28695
|
overflow = true;
|
|
28496
28696
|
}
|
|
28497
28697
|
const j = i2 > escEnd + 1 ? i2 - 2 : escStart - 1;
|
|
28498
28698
|
if (escapedFolds[j])
|
|
28499
|
-
return
|
|
28699
|
+
return text4;
|
|
28500
28700
|
folds.push(j);
|
|
28501
28701
|
escapedFolds[j] = true;
|
|
28502
28702
|
end = j + endStep;
|
|
@@ -28511,39 +28711,39 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28511
28711
|
if (overflow && onOverflow)
|
|
28512
28712
|
onOverflow();
|
|
28513
28713
|
if (folds.length === 0)
|
|
28514
|
-
return
|
|
28714
|
+
return text4;
|
|
28515
28715
|
if (onFold)
|
|
28516
28716
|
onFold();
|
|
28517
|
-
let res =
|
|
28717
|
+
let res = text4.slice(0, folds[0]);
|
|
28518
28718
|
for (let i3 = 0; i3 < folds.length; ++i3) {
|
|
28519
28719
|
const fold = folds[i3];
|
|
28520
|
-
const end2 = folds[i3 + 1] ||
|
|
28720
|
+
const end2 = folds[i3 + 1] || text4.length;
|
|
28521
28721
|
if (fold === 0)
|
|
28522
28722
|
res = `
|
|
28523
|
-
${indent}${
|
|
28723
|
+
${indent}${text4.slice(0, end2)}`;
|
|
28524
28724
|
else {
|
|
28525
28725
|
if (mode === FOLD_QUOTED && escapedFolds[fold])
|
|
28526
|
-
res += `${
|
|
28726
|
+
res += `${text4[fold]}\\`;
|
|
28527
28727
|
res += `
|
|
28528
|
-
${indent}${
|
|
28728
|
+
${indent}${text4.slice(fold + 1, end2)}`;
|
|
28529
28729
|
}
|
|
28530
28730
|
}
|
|
28531
28731
|
return res;
|
|
28532
28732
|
}
|
|
28533
|
-
function consumeMoreIndentedLines(
|
|
28733
|
+
function consumeMoreIndentedLines(text4, i2, indent) {
|
|
28534
28734
|
let end = i2;
|
|
28535
28735
|
let start = i2 + 1;
|
|
28536
|
-
let ch =
|
|
28736
|
+
let ch = text4[start];
|
|
28537
28737
|
while (ch === " " || ch === " ") {
|
|
28538
28738
|
if (i2 < start + indent) {
|
|
28539
|
-
ch =
|
|
28739
|
+
ch = text4[++i2];
|
|
28540
28740
|
} else {
|
|
28541
28741
|
do {
|
|
28542
|
-
ch =
|
|
28742
|
+
ch = text4[++i2];
|
|
28543
28743
|
} while (ch && ch !== "\n");
|
|
28544
28744
|
end = i2;
|
|
28545
28745
|
start = i2 + 1;
|
|
28546
|
-
ch =
|
|
28746
|
+
ch = text4[start];
|
|
28547
28747
|
}
|
|
28548
28748
|
}
|
|
28549
28749
|
return end;
|
|
@@ -34369,24 +34569,24 @@ function quoteYaml(value) {
|
|
|
34369
34569
|
if (/^[\w./:+-]+$/.test(value)) return value;
|
|
34370
34570
|
return JSON.stringify(value);
|
|
34371
34571
|
}
|
|
34372
|
-
function upsertHermesProvider(
|
|
34572
|
+
function upsertHermesProvider(text4, hostId, baseUrl, apiKey) {
|
|
34373
34573
|
const block2 = [` ${hostId}:`, ` base_url: ${quoteYaml(baseUrl)}`, ` api_key: ${quoteYaml(apiKey)}`, ""].join(
|
|
34374
34574
|
"\n"
|
|
34375
34575
|
);
|
|
34376
|
-
if (/^providers:\s*$/m.test(
|
|
34377
|
-
const replaced = replaceHermesHostBlock(
|
|
34576
|
+
if (/^providers:\s*$/m.test(text4)) {
|
|
34577
|
+
const replaced = replaceHermesHostBlock(text4, hostId, block2);
|
|
34378
34578
|
if (replaced !== null) return replaced;
|
|
34379
|
-
return
|
|
34579
|
+
return text4.replace(/^providers:\s*$/m, `providers:
|
|
34380
34580
|
${block2.trimEnd()}`);
|
|
34381
34581
|
}
|
|
34382
|
-
const prefix =
|
|
34383
|
-
` :
|
|
34582
|
+
const prefix = text4 && !text4.endsWith("\n") ? `${text4}
|
|
34583
|
+
` : text4;
|
|
34384
34584
|
return `${prefix}
|
|
34385
34585
|
providers:
|
|
34386
34586
|
${block2}`;
|
|
34387
34587
|
}
|
|
34388
|
-
function replaceHermesHostBlock(
|
|
34389
|
-
const lines =
|
|
34588
|
+
function replaceHermesHostBlock(text4, hostId, block2) {
|
|
34589
|
+
const lines = text4.split("\n");
|
|
34390
34590
|
const start = lines.findIndex((line) => line === ` ${hostId}:`);
|
|
34391
34591
|
if (start < 0) return null;
|
|
34392
34592
|
let end = start + 1;
|
|
@@ -34406,14 +34606,14 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
34406
34606
|
const dir = hermesHome(env);
|
|
34407
34607
|
mkdirSync14(dir, { recursive: true });
|
|
34408
34608
|
const path3 = join31(dir, "config.yaml");
|
|
34409
|
-
let
|
|
34609
|
+
let text4 = "";
|
|
34410
34610
|
try {
|
|
34411
|
-
|
|
34611
|
+
text4 = readFileSync17(path3, "utf8");
|
|
34412
34612
|
} catch {
|
|
34413
|
-
|
|
34613
|
+
text4 = "";
|
|
34414
34614
|
}
|
|
34415
|
-
const next = upsertHermesProvider(
|
|
34416
|
-
if (next !==
|
|
34615
|
+
const next = upsertHermesProvider(text4, inject.host, host.baseUrl, hostApiKey(host, env));
|
|
34616
|
+
if (next !== text4) writeFileSync12(path3, next);
|
|
34417
34617
|
return hermesAcpModelId(modelId) ?? modelId;
|
|
34418
34618
|
}
|
|
34419
34619
|
function hermesAcpModelId(modelId) {
|
|
@@ -34423,8 +34623,8 @@ function hermesAcpModelId(modelId) {
|
|
|
34423
34623
|
if (native && !native.includes(INJECT_SEP) && /^[a-z0-9_-]+:[\w./:-]+$/i.test(native)) return native;
|
|
34424
34624
|
return null;
|
|
34425
34625
|
}
|
|
34426
|
-
function nonEmptyDotenvValue(
|
|
34427
|
-
const match = new RegExp(`^[ \\t]*(?:export[ \\t]+)?${name}[ \\t]*=[ \\t]*([^\\r\\n]*)$`, "m").exec(
|
|
34626
|
+
function nonEmptyDotenvValue(text4, name) {
|
|
34627
|
+
const match = new RegExp(`^[ \\t]*(?:export[ \\t]+)?${name}[ \\t]*=[ \\t]*([^\\r\\n]*)$`, "m").exec(text4);
|
|
34428
34628
|
if (!match) return null;
|
|
34429
34629
|
const raw = match[1].trim();
|
|
34430
34630
|
if (!raw || raw.startsWith("#")) return null;
|
|
@@ -34441,10 +34641,10 @@ function nonEmptyDotenvValue(text3, name) {
|
|
|
34441
34641
|
function yamlString(value) {
|
|
34442
34642
|
return typeof value === "string" ? value.trim() : "";
|
|
34443
34643
|
}
|
|
34444
|
-
function hermesConfigDefault(
|
|
34644
|
+
function hermesConfigDefault(text4) {
|
|
34445
34645
|
let raw;
|
|
34446
34646
|
try {
|
|
34447
|
-
raw = parse3(
|
|
34647
|
+
raw = parse3(text4);
|
|
34448
34648
|
} catch {
|
|
34449
34649
|
return null;
|
|
34450
34650
|
}
|
|
@@ -34497,11 +34697,18 @@ function hermesConfiguredModel(env = process.env) {
|
|
|
34497
34697
|
custom: true
|
|
34498
34698
|
};
|
|
34499
34699
|
}
|
|
34700
|
+
function hermesAcpModelsTimeoutMs(env) {
|
|
34701
|
+
const raw = env[HERMES_ACP_MODELS_TIMEOUT_ENV];
|
|
34702
|
+
if (raw === void 0) return HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS;
|
|
34703
|
+
const parsed = Number(raw);
|
|
34704
|
+
return Number.isInteger(parsed) && parsed > 0 && parsed <= 2147483647 ? parsed : HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS;
|
|
34705
|
+
}
|
|
34500
34706
|
async function fetchHermesAcpModels(cli, env) {
|
|
34501
34707
|
return await new Promise((resolve13) => {
|
|
34502
34708
|
let child;
|
|
34503
34709
|
try {
|
|
34504
|
-
|
|
34710
|
+
const resolved = resolveCli(cli, ["acp"], env);
|
|
34711
|
+
child = spawn6(resolved.command, resolved.args, { stdio: ["pipe", "pipe", "ignore"], env, windowsHide: true });
|
|
34505
34712
|
} catch {
|
|
34506
34713
|
return resolve13([]);
|
|
34507
34714
|
}
|
|
@@ -34526,7 +34733,7 @@ async function fetchHermesAcpModels(cli, env) {
|
|
|
34526
34733
|
}
|
|
34527
34734
|
resolve13(out);
|
|
34528
34735
|
};
|
|
34529
|
-
timer = setTimeout(() => done([]),
|
|
34736
|
+
timer = setTimeout(() => done([]), hermesAcpModelsTimeoutMs(env));
|
|
34530
34737
|
child.once("error", () => done([]));
|
|
34531
34738
|
child.once("close", () => {
|
|
34532
34739
|
if (hardKillTimer) clearTimeout(hardKillTimer);
|
|
@@ -34606,11 +34813,12 @@ async function applySetting2(request, method, params, what) {
|
|
|
34606
34813
|
throw new Error(`Hermes rejected ${what} via ${method}: ${e.message}`);
|
|
34607
34814
|
}
|
|
34608
34815
|
}
|
|
34609
|
-
var EMPTY2, HERMES_OPENMAUS_SCREENSHOT_COMPAT, HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL, HERMES_CONFIG_MODEL_ID, HERMES_HOSTED_PROVIDER_KEYS, HERMES_LOCAL_CONFIG_PROVIDERS, support10, HermesAgentDriver;
|
|
34816
|
+
var EMPTY2, HERMES_OPENMAUS_SCREENSHOT_COMPAT, HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL, HERMES_CONFIG_MODEL_ID, HERMES_HOSTED_PROVIDER_KEYS, HERMES_LOCAL_CONFIG_PROVIDERS, HERMES_ACP_MODELS_TIMEOUT_ENV, HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS, support10, HermesAgentDriver;
|
|
34610
34817
|
var init_hermes = __esm({
|
|
34611
34818
|
"server/drivers/acp/hermes.ts"() {
|
|
34612
34819
|
"use strict";
|
|
34613
34820
|
init_browser();
|
|
34821
|
+
init_procs();
|
|
34614
34822
|
init_local_inject();
|
|
34615
34823
|
init_core3();
|
|
34616
34824
|
EMPTY2 = { default: "", options: [] };
|
|
@@ -34624,6 +34832,8 @@ var init_hermes = __esm({
|
|
|
34624
34832
|
"Z_AI_API_KEY"
|
|
34625
34833
|
];
|
|
34626
34834
|
HERMES_LOCAL_CONFIG_PROVIDERS = /* @__PURE__ */ new Set(["custom", "lmstudio", "ollama", "vllm", "llamacpp"]);
|
|
34835
|
+
HERMES_ACP_MODELS_TIMEOUT_ENV = "HERMES_ACP_MODELS_TIMEOUT_MS";
|
|
34836
|
+
HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS = 15e3;
|
|
34627
34837
|
support10 = {
|
|
34628
34838
|
driverKind: "hermesAgent",
|
|
34629
34839
|
displayName: "Hermes",
|
|
@@ -34696,12 +34906,19 @@ function decodeConfig5(raw) {
|
|
|
34696
34906
|
provider: typeof config2.provider === "string" ? config2.provider || void 0 : process.env.OPENAI_COMPAT_PROVIDER || void 0
|
|
34697
34907
|
};
|
|
34698
34908
|
}
|
|
34699
|
-
var DRIVER_KIND5, DEFAULT_MODELS, OpenAICompatDriver;
|
|
34909
|
+
var DRIVER_KIND5, DEFAULT_IDLE_TIMEOUT_MS, idleTimeoutMs, DEFAULT_MODELS, OpenAICompatDriver;
|
|
34700
34910
|
var init_openai_compat = __esm({
|
|
34701
34911
|
"server/drivers/openai-compat.ts"() {
|
|
34702
34912
|
"use strict";
|
|
34703
34913
|
init_openai_chat();
|
|
34704
34914
|
DRIVER_KIND5 = "openai-compat";
|
|
34915
|
+
DEFAULT_IDLE_TIMEOUT_MS = 18e4;
|
|
34916
|
+
idleTimeoutMs = () => {
|
|
34917
|
+
const raw = process.env.OPENMAUS_OPENAI_COMPAT_IDLE_TIMEOUT_MS;
|
|
34918
|
+
if (!raw) return DEFAULT_IDLE_TIMEOUT_MS;
|
|
34919
|
+
const value = Number(raw);
|
|
34920
|
+
return Number.isSafeInteger(value) && value >= 1e3 && value <= 2147483647 ? value : DEFAULT_IDLE_TIMEOUT_MS;
|
|
34921
|
+
};
|
|
34705
34922
|
DEFAULT_MODELS = {
|
|
34706
34923
|
default: "meta-llama/llama-3.3-70b-instruct",
|
|
34707
34924
|
options: [
|
|
@@ -34782,15 +34999,15 @@ var init_openai_compat = __esm({
|
|
|
34782
34999
|
httpErrorLabel: "upstream",
|
|
34783
35000
|
missingKeyError: `no API key \u2014 set ${config2.apiKeyEnv} or add it to the instance config`,
|
|
34784
35001
|
unavailableReason: `no API key \u2014 set ${config2.apiKeyEnv} or add it to the instance config`,
|
|
34785
|
-
timeoutMs:
|
|
35002
|
+
timeoutMs: idleTimeoutMs(),
|
|
34786
35003
|
reasoning: true,
|
|
34787
35004
|
billing: "metered",
|
|
34788
35005
|
includeUsageInCompleted: true,
|
|
34789
35006
|
nativeLog: {
|
|
34790
35007
|
source: "openai-compat.chat.completions",
|
|
34791
35008
|
outgoing: (_turn, messages, model) => ({ model, messageCount: messages.length }),
|
|
34792
|
-
incoming: ({ text:
|
|
34793
|
-
textLength:
|
|
35009
|
+
incoming: ({ text: text4, reasoning, usage }) => ({
|
|
35010
|
+
textLength: text4.length,
|
|
34794
35011
|
reasoningLength: reasoning.length,
|
|
34795
35012
|
usage
|
|
34796
35013
|
})
|
|
@@ -35026,6 +35243,16 @@ async function fetchPiModels(cli, env) {
|
|
|
35026
35243
|
}
|
|
35027
35244
|
});
|
|
35028
35245
|
}
|
|
35246
|
+
async function updatePiModelCatalog(cli, env) {
|
|
35247
|
+
return new Promise((resolve13) => {
|
|
35248
|
+
execCli(
|
|
35249
|
+
cli,
|
|
35250
|
+
PI_MODEL_UPDATE_ARGS,
|
|
35251
|
+
{ env, timeout: 6e4, maxBuffer: 1024 * 1024 },
|
|
35252
|
+
(error51) => resolve13(!error51)
|
|
35253
|
+
);
|
|
35254
|
+
});
|
|
35255
|
+
}
|
|
35029
35256
|
function decodeConfig6(raw) {
|
|
35030
35257
|
if (raw === null || raw === void 0) return { cli: "pi", fullAuto: false };
|
|
35031
35258
|
if (typeof raw !== "object") throw new Error("pi config must be an object");
|
|
@@ -35043,7 +35270,7 @@ function piEnvironment(source) {
|
|
|
35043
35270
|
for (const key of PROVIDER_CREDENTIAL_ENV) delete env[key];
|
|
35044
35271
|
return env;
|
|
35045
35272
|
}
|
|
35046
|
-
var DRIVER_KIND6, PI_ARGS, NODE_ENV_FLAG2, EMPTY3, PiDriver;
|
|
35273
|
+
var DRIVER_KIND6, PI_ARGS, PI_MODEL_UPDATE_ARGS, NODE_ENV_FLAG2, EMPTY3, PiDriver;
|
|
35047
35274
|
var init_pi = __esm({
|
|
35048
35275
|
"server/drivers/pi.ts"() {
|
|
35049
35276
|
"use strict";
|
|
@@ -35057,6 +35284,7 @@ var init_pi = __esm({
|
|
|
35057
35284
|
init_native();
|
|
35058
35285
|
DRIVER_KIND6 = "piAgent";
|
|
35059
35286
|
PI_ARGS = ["--mode", "rpc", "--no-session"];
|
|
35287
|
+
PI_MODEL_UPDATE_ARGS = ["update", "--models", "--no-approve"];
|
|
35060
35288
|
NODE_ENV_FLAG2 = { ELECTRON_RUN_AS_NODE: "1" };
|
|
35061
35289
|
EMPTY3 = { default: "", options: [] };
|
|
35062
35290
|
PiDriver = {
|
|
@@ -35078,7 +35306,7 @@ var init_pi = __esm({
|
|
|
35078
35306
|
const { instanceId, config: config2 } = input;
|
|
35079
35307
|
const catalogEnv = piEnvironment({ ...process.env, ...input.environment });
|
|
35080
35308
|
let models = EMPTY3;
|
|
35081
|
-
const
|
|
35309
|
+
const readModels = async () => {
|
|
35082
35310
|
let base3 = models;
|
|
35083
35311
|
try {
|
|
35084
35312
|
const resolved = await fetchPiModels(config2.cli, catalogEnv);
|
|
@@ -35092,7 +35320,11 @@ var init_pi = __esm({
|
|
|
35092
35320
|
if (base3.options.length) models = base3;
|
|
35093
35321
|
}
|
|
35094
35322
|
};
|
|
35095
|
-
|
|
35323
|
+
const refreshModels = async () => {
|
|
35324
|
+
await updatePiModelCatalog(config2.cli, catalogEnv);
|
|
35325
|
+
await readModels();
|
|
35326
|
+
};
|
|
35327
|
+
await readModels();
|
|
35096
35328
|
const listeners = /* @__PURE__ */ new Set();
|
|
35097
35329
|
const active = /* @__PURE__ */ new Map();
|
|
35098
35330
|
const emit = (event) => {
|
|
@@ -35181,10 +35413,10 @@ var init_pi = __esm({
|
|
|
35181
35413
|
child.stdin.write(JSON.stringify(obj) + "\n");
|
|
35182
35414
|
};
|
|
35183
35415
|
const flushAssistantText = () => {
|
|
35184
|
-
const
|
|
35416
|
+
const text4 = assistantText;
|
|
35185
35417
|
assistantText = "";
|
|
35186
|
-
if (!
|
|
35187
|
-
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text:
|
|
35418
|
+
if (!text4.trim()) return;
|
|
35419
|
+
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
35188
35420
|
};
|
|
35189
35421
|
const settle = (ok, stopReason, usage) => {
|
|
35190
35422
|
if (settled) return;
|
|
@@ -35577,7 +35809,7 @@ var init_minimax = __esm({
|
|
|
35577
35809
|
nativeLog: {
|
|
35578
35810
|
source: "minimax.chat.completions",
|
|
35579
35811
|
outgoing: (_turn, messages, model) => ({ model, messageCount: messages.length }),
|
|
35580
|
-
incoming: ({ text:
|
|
35812
|
+
incoming: ({ text: text4, usage }) => ({ textLength: text4.length, usage })
|
|
35581
35813
|
}
|
|
35582
35814
|
});
|
|
35583
35815
|
}
|
|
@@ -37244,10 +37476,10 @@ async function verifyHostedEndpoint(endpoint, { fetchImpl, timeoutSignal, timeou
|
|
|
37244
37476
|
signal: cancellationSignal ? AbortSignal.any([requestSignal, cancellationSignal]) : requestSignal
|
|
37245
37477
|
});
|
|
37246
37478
|
if (!response.ok) return false;
|
|
37247
|
-
const
|
|
37248
|
-
if (Buffer.byteLength(
|
|
37479
|
+
const text4 = await response.text();
|
|
37480
|
+
if (Buffer.byteLength(text4) > 4096) return false;
|
|
37249
37481
|
try {
|
|
37250
|
-
return JSON.parse(
|
|
37482
|
+
return JSON.parse(text4)?.app === "openmausbot";
|
|
37251
37483
|
} catch {
|
|
37252
37484
|
return false;
|
|
37253
37485
|
}
|
|
@@ -38168,9 +38400,9 @@ async function startCaddy(options) {
|
|
|
38168
38400
|
});
|
|
38169
38401
|
let output = "";
|
|
38170
38402
|
const receive = (chunk) => {
|
|
38171
|
-
const
|
|
38172
|
-
if (output.length < 16384) output +=
|
|
38173
|
-
for (const line of
|
|
38403
|
+
const text4 = chunk.toString("utf8");
|
|
38404
|
+
if (output.length < 16384) output += text4;
|
|
38405
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
38174
38406
|
if (!line.trim()) continue;
|
|
38175
38407
|
if (/"level":"(warn|error)"/.test(line) || /^\S+\s+(WARN|ERROR)/.test(line) || !line.startsWith("{")) options.log?.(`caddy: ${line.slice(0, 400)}`);
|
|
38176
38408
|
}
|
|
@@ -38437,8 +38669,8 @@ function agentUnit(spec) {
|
|
|
38437
38669
|
function emptyRegistry(domain2) {
|
|
38438
38670
|
return { version: 1, domain: domain2, nextPort: FLEET_FIRST_PORT, workspaces: {} };
|
|
38439
38671
|
}
|
|
38440
|
-
function parseRegistry(
|
|
38441
|
-
const value = JSON.parse(
|
|
38672
|
+
function parseRegistry(text4) {
|
|
38673
|
+
const value = JSON.parse(text4);
|
|
38442
38674
|
const record3 = value && typeof value === "object" ? value : null;
|
|
38443
38675
|
if (!record3 || record3.version !== 1 || typeof record3.domain !== "string" || typeof record3.nextPort !== "number" || !record3.workspaces || typeof record3.workspaces !== "object") {
|
|
38444
38676
|
throw new Error("fleet.json is not a fleet registry this version understands");
|
|
@@ -38862,9 +39094,9 @@ function failed(io, what, output) {
|
|
|
38862
39094
|
return 1;
|
|
38863
39095
|
}
|
|
38864
39096
|
function loadRegistry(layout, deps) {
|
|
38865
|
-
const
|
|
38866
|
-
if (
|
|
38867
|
-
return parseRegistry(
|
|
39097
|
+
const text4 = deps.readText(layout.registryFile);
|
|
39098
|
+
if (text4 === null) throw new Error(`no fleet on this server yet: run \`openmausbot fleet init --domain your.domain\` first`);
|
|
39099
|
+
return parseRegistry(text4);
|
|
38868
39100
|
}
|
|
38869
39101
|
function planFleetAction(input, deps) {
|
|
38870
39102
|
const layout = fleetLayout(input.root ?? "/");
|
|
@@ -39011,13 +39243,13 @@ function readUsage(dataDir, range) {
|
|
|
39011
39243
|
const from = range.from.getTime();
|
|
39012
39244
|
const to = range.to.getTime();
|
|
39013
39245
|
for (const key of monthsBetween(range.from, range.to)) {
|
|
39014
|
-
let
|
|
39246
|
+
let text4;
|
|
39015
39247
|
try {
|
|
39016
|
-
|
|
39248
|
+
text4 = readFileSync2(join4(dataDir, DIR, `${key}.jsonl`), "utf8");
|
|
39017
39249
|
} catch {
|
|
39018
39250
|
continue;
|
|
39019
39251
|
}
|
|
39020
|
-
for (const line of
|
|
39252
|
+
for (const line of text4.split("\n")) {
|
|
39021
39253
|
if (!line) continue;
|
|
39022
39254
|
try {
|
|
39023
39255
|
const value = JSON.parse(line);
|
|
@@ -39111,15 +39343,15 @@ function summarizeUsage(rows, groupBy, prices = null) {
|
|
|
39111
39343
|
var MAX_BODY = 256 * 1024;
|
|
39112
39344
|
function readBody(req) {
|
|
39113
39345
|
return new Promise((resolve13, reject) => {
|
|
39114
|
-
let
|
|
39346
|
+
let text4 = "";
|
|
39115
39347
|
req.on("data", (chunk) => {
|
|
39116
|
-
|
|
39117
|
-
if (
|
|
39348
|
+
text4 += chunk.toString("utf8");
|
|
39349
|
+
if (text4.length > MAX_BODY) reject(Object.assign(new Error("request too large"), { status: 413 }));
|
|
39118
39350
|
});
|
|
39119
39351
|
req.on("end", () => {
|
|
39120
|
-
if (!
|
|
39352
|
+
if (!text4.trim()) return resolve13({});
|
|
39121
39353
|
try {
|
|
39122
|
-
const value = JSON.parse(
|
|
39354
|
+
const value = JSON.parse(text4);
|
|
39123
39355
|
resolve13(value && typeof value === "object" && !Array.isArray(value) ? value : {});
|
|
39124
39356
|
} catch {
|
|
39125
39357
|
reject(Object.assign(new Error("body must be JSON"), { status: 400 }));
|
|
@@ -39290,8 +39522,8 @@ var tailscaleEnvironment = () => ({
|
|
|
39290
39522
|
});
|
|
39291
39523
|
|
|
39292
39524
|
// server/tailscale.ts
|
|
39293
|
-
function classifyTailscaleStderr(
|
|
39294
|
-
const t2 =
|
|
39525
|
+
function classifyTailscaleStderr(text4) {
|
|
39526
|
+
const t2 = text4.toLowerCase();
|
|
39295
39527
|
if (/not logged in|logged out|needs login|please log in/.test(t2)) return "not-logged-in";
|
|
39296
39528
|
if (/is tailscale running|tailscaled is not running|connection refused|failed to connect to local tailscaled/.test(t2)) return "not-running";
|
|
39297
39529
|
if (/access denied|permission denied|operator|must be root|not permitted/.test(t2)) return "needs-operator";
|
|
@@ -40022,9 +40254,9 @@ function pairingBlock(input) {
|
|
|
40022
40254
|
}
|
|
40023
40255
|
return lines.join("\n");
|
|
40024
40256
|
}
|
|
40025
|
-
function qrToString(
|
|
40257
|
+
function qrToString(text4) {
|
|
40026
40258
|
let out = "";
|
|
40027
|
-
import_qrcode_terminal.default.generate(
|
|
40259
|
+
import_qrcode_terminal.default.generate(text4, { small: true }, (rendered) => {
|
|
40028
40260
|
out = rendered;
|
|
40029
40261
|
});
|
|
40030
40262
|
return out;
|