openmausbot 0.1.75 → 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-BTlyRwLl.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 +2602 -869
- package/dist-server/mcp-gate.js +28 -18
- package/dist-server/openmausbot.js +202 -120
- package/dist-server/pair-cli.js +202 -120
- package/dist-server/server/agent-tool-policy.js +1 -0
- package/dist-server/server/atomic.js +37 -1
- 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/hermes.js +21 -3
- package/dist-server/server/drivers/agents-proxy.js +113 -10
- package/dist-server/server/drivers/claude.js +31 -14
- 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/env-path.js +18 -17
- package/dist-server/server/index.js +1112 -312
- package/dist-server/server/message-db.js +21 -0
- package/dist-server/server/peer-roster.js +48 -9
- 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/store.js +247 -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/turn-dispatch-guard.js +31 -3
- package/dist-server/shared/approval-mode.js +7 -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-CeMbvsgx.js +0 -305
- package/dist/assets/index-DH7Zax6L.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
|
|
|
@@ -18609,28 +18627,29 @@ 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) {
|
|
18652
|
+
function parseCmdShim(shim, env) {
|
|
18634
18653
|
let text4;
|
|
18635
18654
|
try {
|
|
18636
18655
|
text4 = readFileSync6(shim, "utf8");
|
|
@@ -18641,13 +18660,13 @@ function parseCmdShim(shim) {
|
|
|
18641
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 {
|
|
@@ -22639,15 +22667,16 @@ function askSummary(ask) {
|
|
|
22639
22667
|
if (questions) return askQuestionSummary(questions).slice(0, 300);
|
|
22640
22668
|
return askInputSummary(ask.input) ?? ask.tool ?? "tool";
|
|
22641
22669
|
}
|
|
22642
|
-
function permissionSocketPath(threadId) {
|
|
22670
|
+
function permissionSocketPath(threadId, botId) {
|
|
22671
|
+
const key = botId ? `${botId}\0${threadId}` : threadId;
|
|
22643
22672
|
const prefix = threadId.replace(/[^\w-]/g, "").slice(0, 4);
|
|
22644
|
-
const digest2 = createHash5("sha256").update(
|
|
22673
|
+
const digest2 = createHash5("sha256").update(key).digest("hex").slice(0, 4);
|
|
22645
22674
|
return brokerSocketPath(DATA_DIR, `${prefix}${digest2}`);
|
|
22646
22675
|
}
|
|
22647
|
-
function brokerSocketCandidates(threadId) {
|
|
22648
|
-
const base2 = permissionSocketPath(threadId);
|
|
22676
|
+
function brokerSocketCandidates(threadId, botId) {
|
|
22677
|
+
const base2 = permissionSocketPath(threadId, botId);
|
|
22649
22678
|
if (process.platform !== "win32") {
|
|
22650
|
-
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);
|
|
22651
22680
|
return [base2, join20(tmpdir3(), `omb-perm-${scope}.sock`)];
|
|
22652
22681
|
}
|
|
22653
22682
|
return [
|
|
@@ -23045,8 +23074,8 @@ var init_claude = __esm({
|
|
|
23045
23074
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23046
23075
|
});
|
|
23047
23076
|
const retryState = /* @__PURE__ */ new Map();
|
|
23048
|
-
const sendTurn = async (turn) => {
|
|
23049
|
-
const { threadId } = turn;
|
|
23077
|
+
const sendTurn = async (turn, logicalTurnId) => {
|
|
23078
|
+
const { threadId, botId } = turn;
|
|
23050
23079
|
if (active.has(threadId)) throw new Error("a turn is already running on this thread");
|
|
23051
23080
|
const permissionMode = turn.approvalMode === void 0 ? config2.permissionMode : turn.approvalMode === "full" ? "bypassPermissions" : turn.approvalMode === "auto" ? "auto" : turn.approvalMode === "edits" ? "acceptEdits" : "default";
|
|
23052
23081
|
const controlsHost = turn.integrations?.localComputer?.scope === "local-computer";
|
|
@@ -23054,7 +23083,7 @@ var init_claude = __esm({
|
|
|
23054
23083
|
throw new Error("local computer control requires the interactive approval broker");
|
|
23055
23084
|
}
|
|
23056
23085
|
const promptMsg = claudeUserMessage(turn.text, turn.images);
|
|
23057
|
-
const turnId = newId();
|
|
23086
|
+
const turnId = logicalTurnId ?? newId();
|
|
23058
23087
|
const retryAbort = new AbortController();
|
|
23059
23088
|
const retry = retryState.get(threadId) ?? { attempt: 0, cancelled: false };
|
|
23060
23089
|
retry.cancelled = false;
|
|
@@ -23159,7 +23188,7 @@ var init_claude = __esm({
|
|
|
23159
23188
|
if (gated) mcpServers[name] = gated;
|
|
23160
23189
|
}
|
|
23161
23190
|
let broker;
|
|
23162
|
-
const socketPath = permissionSocketPath(threadId);
|
|
23191
|
+
const socketPath = permissionSocketPath(threadId, botId);
|
|
23163
23192
|
if (permissionMode !== "bypassPermissions") {
|
|
23164
23193
|
args.push("--permission-prompt-tool", "mcp__ogb__approve");
|
|
23165
23194
|
}
|
|
@@ -23198,9 +23227,11 @@ var init_claude = __esm({
|
|
|
23198
23227
|
const live = sessions.get(threadId);
|
|
23199
23228
|
if (live && !live.turn && !live.closing && live.child.exitCode === null && live.argsKey === argsKey && (!sessionId || sessionId === live.sessionId)) {
|
|
23200
23229
|
if (live.idleTimer) clearTimeout(live.idleTimer);
|
|
23201
|
-
live.turn = { turnId, settled: false, sawStreamDelta: false };
|
|
23230
|
+
live.turn = { turnId, input: turn, retryAbort, settled: false, sawStreamDelta: false };
|
|
23202
23231
|
active.set(threadId, { stop: () => {
|
|
23203
23232
|
closeSession(threadId, "interrupted");
|
|
23233
|
+
retry.cancelled = true;
|
|
23234
|
+
retryAbort.abort();
|
|
23204
23235
|
stopSession(live);
|
|
23205
23236
|
}, turnId, broker: live.broker });
|
|
23206
23237
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
@@ -23255,7 +23286,7 @@ var init_claude = __esm({
|
|
|
23255
23286
|
if (socketPath) {
|
|
23256
23287
|
const askTools = /* @__PURE__ */ new Map();
|
|
23257
23288
|
broker = await createPermissionBroker({
|
|
23258
|
-
socketPaths: brokerSocketCandidates(threadId),
|
|
23289
|
+
socketPaths: brokerSocketCandidates(threadId, botId),
|
|
23259
23290
|
isActive: () => Boolean(sessions.get(threadId)?.turn),
|
|
23260
23291
|
onAsk: (ask) => {
|
|
23261
23292
|
const eventTurnId = sessions.get(threadId)?.turn?.turnId ?? turnId;
|
|
@@ -23331,7 +23362,7 @@ var init_claude = __esm({
|
|
|
23331
23362
|
sessionId: sessionId ?? newSessionId,
|
|
23332
23363
|
sawInit: false,
|
|
23333
23364
|
nativePermissionMode: null,
|
|
23334
|
-
turn: { turnId, settled: false, sawStreamDelta: false },
|
|
23365
|
+
turn: { turnId, input: turn, retryAbort, settled: false, sawStreamDelta: false },
|
|
23335
23366
|
idleTimer: null,
|
|
23336
23367
|
closing: false,
|
|
23337
23368
|
stderr: ""
|
|
@@ -23483,9 +23514,11 @@ var init_claude = __esm({
|
|
|
23483
23514
|
if (closeFinalized) return;
|
|
23484
23515
|
closeFinalized = true;
|
|
23485
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 };
|
|
23486
23519
|
const message2 = `claude exited ${code} before result${session.stderr ? `: ${session.stderr.trim().slice(-300)}` : ""}`;
|
|
23487
23520
|
const verdict = classifyError({ exitCode: code, stderr: message2 });
|
|
23488
|
-
if (!
|
|
23521
|
+
if (!retry2.cancelled && code !== 0 && verdict.transient && !session.turn.sawStreamDelta && retry2.attempt < RETRY_MAX_ATTEMPTS - 1) {
|
|
23489
23522
|
const failedBroker = session.broker;
|
|
23490
23523
|
session.broker = void 0;
|
|
23491
23524
|
failedBroker?.pause();
|
|
@@ -23503,23 +23536,23 @@ var init_claude = __esm({
|
|
|
23503
23536
|
}
|
|
23504
23537
|
sessions.delete(threadId);
|
|
23505
23538
|
session.turn = null;
|
|
23506
|
-
|
|
23507
|
-
const delayMs = computeBackoff(
|
|
23539
|
+
retry2.attempt++;
|
|
23540
|
+
const delayMs = computeBackoff(retry2.attempt - 1);
|
|
23508
23541
|
emit({
|
|
23509
|
-
...base2(threadId,
|
|
23542
|
+
...base2(threadId, turnId2),
|
|
23510
23543
|
type: "turn.retrying",
|
|
23511
|
-
attempt:
|
|
23544
|
+
attempt: retry2.attempt,
|
|
23512
23545
|
delayMs,
|
|
23513
23546
|
reason: verdict.reason
|
|
23514
23547
|
});
|
|
23515
23548
|
void (async () => {
|
|
23516
|
-
const wait2 = interruptibleDelay(delayMs * retryScale,
|
|
23549
|
+
const wait2 = interruptibleDelay(delayMs * retryScale, retryAbort2.signal);
|
|
23517
23550
|
await wait2.promise;
|
|
23518
|
-
if (
|
|
23551
|
+
if (retry2.cancelled) {
|
|
23519
23552
|
active.delete(threadId);
|
|
23520
23553
|
retryState.delete(threadId);
|
|
23521
23554
|
emit({
|
|
23522
|
-
...base2(threadId,
|
|
23555
|
+
...base2(threadId, turnId2),
|
|
23523
23556
|
type: "turn.completed",
|
|
23524
23557
|
ok: false,
|
|
23525
23558
|
stopReason: "interrupted",
|
|
@@ -23530,16 +23563,16 @@ var init_claude = __esm({
|
|
|
23530
23563
|
active.delete(threadId);
|
|
23531
23564
|
try {
|
|
23532
23565
|
const cursor3 = session.sessionId ?? sessionId ?? void 0;
|
|
23533
|
-
await sendTurn({ ...
|
|
23566
|
+
await sendTurn({ ...turn2, resumeCursor: cursor3 }, turnId2);
|
|
23534
23567
|
} catch (e) {
|
|
23535
23568
|
retryState.delete(threadId);
|
|
23536
23569
|
emit({
|
|
23537
|
-
...base2(threadId,
|
|
23570
|
+
...base2(threadId, turnId2),
|
|
23538
23571
|
type: "runtime.error",
|
|
23539
23572
|
message: e instanceof Error ? e.message : String(e)
|
|
23540
23573
|
});
|
|
23541
23574
|
emit({
|
|
23542
|
-
...base2(threadId,
|
|
23575
|
+
...base2(threadId, turnId2),
|
|
23543
23576
|
type: "turn.completed",
|
|
23544
23577
|
ok: false,
|
|
23545
23578
|
stopReason: "exit_before_result",
|
|
@@ -23555,10 +23588,10 @@ var init_claude = __esm({
|
|
|
23555
23588
|
promptSubmitted: session.sawInit,
|
|
23556
23589
|
producedOutput: session.turn.sawStreamDelta
|
|
23557
23590
|
});
|
|
23558
|
-
if (mayReplay(resumeFailure) && !
|
|
23591
|
+
if (mayReplay(resumeFailure) && !retry2.cancelled) {
|
|
23559
23592
|
const recovery = recoveryPromptFor({
|
|
23560
|
-
recoveryText:
|
|
23561
|
-
currentText:
|
|
23593
|
+
recoveryText: turn2.recoveryText,
|
|
23594
|
+
currentText: turn2.text,
|
|
23562
23595
|
failure: resumeFailure
|
|
23563
23596
|
});
|
|
23564
23597
|
session.broker?.close();
|
|
@@ -23578,23 +23611,23 @@ var init_claude = __esm({
|
|
|
23578
23611
|
session.turn = null;
|
|
23579
23612
|
active.delete(threadId);
|
|
23580
23613
|
emit({
|
|
23581
|
-
...base2(threadId,
|
|
23614
|
+
...base2(threadId, turnId2),
|
|
23582
23615
|
type: "turn.retrying",
|
|
23583
|
-
attempt:
|
|
23616
|
+
attempt: retry2.attempt + 1,
|
|
23584
23617
|
delayMs: 0,
|
|
23585
23618
|
reason: "resume_rejected"
|
|
23586
23619
|
});
|
|
23587
23620
|
void (async () => {
|
|
23588
23621
|
try {
|
|
23589
|
-
await sendTurn({ ...
|
|
23622
|
+
await sendTurn({ ...turn2, resumeCursor: void 0, recoveryText: void 0, text: recovery.text }, turnId2);
|
|
23590
23623
|
} catch (e) {
|
|
23591
23624
|
retryState.delete(threadId);
|
|
23592
23625
|
emit({
|
|
23593
|
-
...base2(threadId,
|
|
23626
|
+
...base2(threadId, turnId2),
|
|
23594
23627
|
type: "runtime.error",
|
|
23595
23628
|
message: e instanceof Error ? e.message : String(e)
|
|
23596
23629
|
});
|
|
23597
|
-
emit({ ...base2(threadId,
|
|
23630
|
+
emit({ ...base2(threadId, turnId2), type: "turn.completed", ok: false, stopReason: "exit_before_result", cost: null });
|
|
23598
23631
|
}
|
|
23599
23632
|
})();
|
|
23600
23633
|
return;
|
|
@@ -25615,72 +25648,89 @@ function createOpenAIChatRuntime(options) {
|
|
|
25615
25648
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
25616
25649
|
});
|
|
25617
25650
|
const complete = async (messages, model, stream, signal, onDelta) => {
|
|
25618
|
-
const
|
|
25619
|
-
|
|
25620
|
-
|
|
25621
|
-
|
|
25622
|
-
|
|
25623
|
-
|
|
25624
|
-
|
|
25625
|
-
|
|
25626
|
-
|
|
25627
|
-
throw new Error(`${options.httpErrorLabel} HTTP ${response.status}${body ? `: ${body.slice(0, 200)}` : ""}`);
|
|
25628
|
-
}
|
|
25629
|
-
if (!stream) {
|
|
25630
|
-
const json2 = await response.json();
|
|
25631
|
-
const message2 = json2.choices?.[0]?.message;
|
|
25632
|
-
return {
|
|
25633
|
-
text: typeof message2?.content === "string" ? message2.content : "",
|
|
25634
|
-
reasoning: options.reasoning && typeof message2?.reasoning_content === "string" ? message2.reasoning_content : "",
|
|
25635
|
-
usage: usageFrom(json2.usage)
|
|
25636
|
-
};
|
|
25637
|
-
}
|
|
25638
|
-
if (!response.body) {
|
|
25639
|
-
throw new Error(options.noBodyError ?? `${options.httpErrorLabel} returned no response body`);
|
|
25640
|
-
}
|
|
25641
|
-
let text4 = "";
|
|
25642
|
-
let reasoning = "";
|
|
25643
|
-
let usage = null;
|
|
25644
|
-
const reader = response.body.getReader();
|
|
25645
|
-
const decoder = new TextDecoder();
|
|
25646
|
-
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();
|
|
25647
25660
|
try {
|
|
25648
|
-
|
|
25649
|
-
|
|
25650
|
-
|
|
25651
|
-
|
|
25652
|
-
|
|
25653
|
-
|
|
25654
|
-
|
|
25655
|
-
|
|
25656
|
-
|
|
25657
|
-
|
|
25658
|
-
|
|
25659
|
-
|
|
25660
|
-
|
|
25661
|
-
|
|
25662
|
-
|
|
25663
|
-
|
|
25664
|
-
|
|
25665
|
-
|
|
25666
|
-
|
|
25667
|
-
|
|
25668
|
-
|
|
25669
|
-
|
|
25670
|
-
|
|
25671
|
-
|
|
25672
|
-
|
|
25673
|
-
|
|
25674
|
-
|
|
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);
|
|
25675
25724
|
}
|
|
25676
|
-
if (chunk.usage) usage = usageFrom(chunk.usage);
|
|
25677
25725
|
}
|
|
25726
|
+
} finally {
|
|
25727
|
+
await reader.cancel().catch(() => {
|
|
25728
|
+
});
|
|
25678
25729
|
}
|
|
25730
|
+
return { text: text4, reasoning, usage };
|
|
25679
25731
|
} finally {
|
|
25680
|
-
|
|
25681
|
-
});
|
|
25732
|
+
if (idleTimer) clearTimeout(idleTimer);
|
|
25682
25733
|
}
|
|
25683
|
-
return { text: text4, reasoning, usage };
|
|
25684
25734
|
};
|
|
25685
25735
|
const messagesFor = (turn) => [
|
|
25686
25736
|
...turn.system ? [{ role: "system", content: turn.system }] : [],
|
|
@@ -34647,11 +34697,18 @@ function hermesConfiguredModel(env = process.env) {
|
|
|
34647
34697
|
custom: true
|
|
34648
34698
|
};
|
|
34649
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
|
+
}
|
|
34650
34706
|
async function fetchHermesAcpModels(cli, env) {
|
|
34651
34707
|
return await new Promise((resolve13) => {
|
|
34652
34708
|
let child;
|
|
34653
34709
|
try {
|
|
34654
|
-
|
|
34710
|
+
const resolved = resolveCli(cli, ["acp"], env);
|
|
34711
|
+
child = spawn6(resolved.command, resolved.args, { stdio: ["pipe", "pipe", "ignore"], env, windowsHide: true });
|
|
34655
34712
|
} catch {
|
|
34656
34713
|
return resolve13([]);
|
|
34657
34714
|
}
|
|
@@ -34676,7 +34733,7 @@ async function fetchHermesAcpModels(cli, env) {
|
|
|
34676
34733
|
}
|
|
34677
34734
|
resolve13(out);
|
|
34678
34735
|
};
|
|
34679
|
-
timer = setTimeout(() => done([]),
|
|
34736
|
+
timer = setTimeout(() => done([]), hermesAcpModelsTimeoutMs(env));
|
|
34680
34737
|
child.once("error", () => done([]));
|
|
34681
34738
|
child.once("close", () => {
|
|
34682
34739
|
if (hardKillTimer) clearTimeout(hardKillTimer);
|
|
@@ -34756,11 +34813,12 @@ async function applySetting2(request, method, params, what) {
|
|
|
34756
34813
|
throw new Error(`Hermes rejected ${what} via ${method}: ${e.message}`);
|
|
34757
34814
|
}
|
|
34758
34815
|
}
|
|
34759
|
-
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;
|
|
34760
34817
|
var init_hermes = __esm({
|
|
34761
34818
|
"server/drivers/acp/hermes.ts"() {
|
|
34762
34819
|
"use strict";
|
|
34763
34820
|
init_browser();
|
|
34821
|
+
init_procs();
|
|
34764
34822
|
init_local_inject();
|
|
34765
34823
|
init_core3();
|
|
34766
34824
|
EMPTY2 = { default: "", options: [] };
|
|
@@ -34774,6 +34832,8 @@ var init_hermes = __esm({
|
|
|
34774
34832
|
"Z_AI_API_KEY"
|
|
34775
34833
|
];
|
|
34776
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;
|
|
34777
34837
|
support10 = {
|
|
34778
34838
|
driverKind: "hermesAgent",
|
|
34779
34839
|
displayName: "Hermes",
|
|
@@ -34846,12 +34906,19 @@ function decodeConfig5(raw) {
|
|
|
34846
34906
|
provider: typeof config2.provider === "string" ? config2.provider || void 0 : process.env.OPENAI_COMPAT_PROVIDER || void 0
|
|
34847
34907
|
};
|
|
34848
34908
|
}
|
|
34849
|
-
var DRIVER_KIND5, DEFAULT_MODELS, OpenAICompatDriver;
|
|
34909
|
+
var DRIVER_KIND5, DEFAULT_IDLE_TIMEOUT_MS, idleTimeoutMs, DEFAULT_MODELS, OpenAICompatDriver;
|
|
34850
34910
|
var init_openai_compat = __esm({
|
|
34851
34911
|
"server/drivers/openai-compat.ts"() {
|
|
34852
34912
|
"use strict";
|
|
34853
34913
|
init_openai_chat();
|
|
34854
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
|
+
};
|
|
34855
34922
|
DEFAULT_MODELS = {
|
|
34856
34923
|
default: "meta-llama/llama-3.3-70b-instruct",
|
|
34857
34924
|
options: [
|
|
@@ -34932,7 +34999,7 @@ var init_openai_compat = __esm({
|
|
|
34932
34999
|
httpErrorLabel: "upstream",
|
|
34933
35000
|
missingKeyError: `no API key \u2014 set ${config2.apiKeyEnv} or add it to the instance config`,
|
|
34934
35001
|
unavailableReason: `no API key \u2014 set ${config2.apiKeyEnv} or add it to the instance config`,
|
|
34935
|
-
timeoutMs:
|
|
35002
|
+
timeoutMs: idleTimeoutMs(),
|
|
34936
35003
|
reasoning: true,
|
|
34937
35004
|
billing: "metered",
|
|
34938
35005
|
includeUsageInCompleted: true,
|
|
@@ -35176,6 +35243,16 @@ async function fetchPiModels(cli, env) {
|
|
|
35176
35243
|
}
|
|
35177
35244
|
});
|
|
35178
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
|
+
}
|
|
35179
35256
|
function decodeConfig6(raw) {
|
|
35180
35257
|
if (raw === null || raw === void 0) return { cli: "pi", fullAuto: false };
|
|
35181
35258
|
if (typeof raw !== "object") throw new Error("pi config must be an object");
|
|
@@ -35193,7 +35270,7 @@ function piEnvironment(source) {
|
|
|
35193
35270
|
for (const key of PROVIDER_CREDENTIAL_ENV) delete env[key];
|
|
35194
35271
|
return env;
|
|
35195
35272
|
}
|
|
35196
|
-
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;
|
|
35197
35274
|
var init_pi = __esm({
|
|
35198
35275
|
"server/drivers/pi.ts"() {
|
|
35199
35276
|
"use strict";
|
|
@@ -35207,6 +35284,7 @@ var init_pi = __esm({
|
|
|
35207
35284
|
init_native();
|
|
35208
35285
|
DRIVER_KIND6 = "piAgent";
|
|
35209
35286
|
PI_ARGS = ["--mode", "rpc", "--no-session"];
|
|
35287
|
+
PI_MODEL_UPDATE_ARGS = ["update", "--models", "--no-approve"];
|
|
35210
35288
|
NODE_ENV_FLAG2 = { ELECTRON_RUN_AS_NODE: "1" };
|
|
35211
35289
|
EMPTY3 = { default: "", options: [] };
|
|
35212
35290
|
PiDriver = {
|
|
@@ -35228,7 +35306,7 @@ var init_pi = __esm({
|
|
|
35228
35306
|
const { instanceId, config: config2 } = input;
|
|
35229
35307
|
const catalogEnv = piEnvironment({ ...process.env, ...input.environment });
|
|
35230
35308
|
let models = EMPTY3;
|
|
35231
|
-
const
|
|
35309
|
+
const readModels = async () => {
|
|
35232
35310
|
let base3 = models;
|
|
35233
35311
|
try {
|
|
35234
35312
|
const resolved = await fetchPiModels(config2.cli, catalogEnv);
|
|
@@ -35242,7 +35320,11 @@ var init_pi = __esm({
|
|
|
35242
35320
|
if (base3.options.length) models = base3;
|
|
35243
35321
|
}
|
|
35244
35322
|
};
|
|
35245
|
-
|
|
35323
|
+
const refreshModels = async () => {
|
|
35324
|
+
await updatePiModelCatalog(config2.cli, catalogEnv);
|
|
35325
|
+
await readModels();
|
|
35326
|
+
};
|
|
35327
|
+
await readModels();
|
|
35246
35328
|
const listeners = /* @__PURE__ */ new Set();
|
|
35247
35329
|
const active = /* @__PURE__ */ new Map();
|
|
35248
35330
|
const emit = (event) => {
|