openmausbot 0.1.87 → 0.1.88
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/README.md +2 -1
- package/dist/assets/{abnfDiagram-O67JEVCF-BTiuL79F.js → abnfDiagram-O67JEVCF-qd9VD3GV.js} +1 -1
- package/dist/assets/{arc-C88Blc2v.js → arc-3RwkUjRe.js} +1 -1
- package/dist/assets/{architectureDiagram-NJMV4G6O-BZsJIZrb.js → architectureDiagram-NJMV4G6O-CFKSJS7a.js} +1 -1
- package/dist/assets/{blockDiagram-BEXU5L5S-CVeMe9Ah.js → blockDiagram-BEXU5L5S-CG1rEfWD.js} +1 -1
- package/dist/assets/{c4Diagram-YGBWAQC7-Cedk3Bhx.js → c4Diagram-YGBWAQC7-CBW9N664.js} +1 -1
- package/dist/assets/channel-CnRnO3tF.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-D-VRqzTB.js → chunk-2Q5K7J3B-2mRfTksB.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-BChov01Y.js → chunk-3FUC2YCW-Cv1dpErj.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-C-TfwvHy.js → chunk-5VM5RSS4-B7IACJp-.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-Db7CGj5Y.js → chunk-GTNCS2PH-An0hZtYa.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-CNvIfqKT.js → chunk-GWA4HPMP-BcJB2nEm.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-C_bEp5tq.js → chunk-JWPE2WC7-CV_W7TN7.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-Coi4BOls.js → chunk-NETBCI7D-Bcs_kwnA.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-CzylEuL3.js → chunk-WEXAMYUT-lrx_DxFP.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-m7p7ztaD.js → chunk-XXDRQBXY-DabHlLGM.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-BMy6o9x2.js → classDiagram-v2-NBCMYWYE-BnHj6P7d.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-BDQ__0_J.js → cose-bilkent-JH36ORCC-CfLp6UDi.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-Djv4ghUb.js → cynefin-OW5HDTMX-Dm4dbVA1.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-BULrlGYH.js → cynefinDiagram-VND7K2PF-B9mH-PID.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-D-jrT_hU.js → dagre-6A5THRUB-DDc_NVQJ.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-p2UhQmfL.js → diagram-22UHCM2B-lwr8Ip8-.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-DHvGWZ7q.js → diagram-3UASUU5V-BLLe6dmI.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-ChhKDot-.js → diagram-ATOU4E4O-6eUIq4lz.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-B-T7A43R.js → diagram-CDSNMT55-O-pRN7VQ.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-CJm8ENNY.js → diagram-MLGK6HIB-BietvGAI.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-510tlza8.js → diagram-MPIPVDR6-Bd2Cl62X.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-PkvRPHel.js → ebnfDiagram-ZINNZB2B-B6iDy69W.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-BVBVPoX3.js → elk-276RUBZZ-DQVHfKe0.js} +1 -1
- package/dist/assets/{erDiagram-OPXOYQCR-BgYMVm7L.js → erDiagram-OPXOYQCR-BWdVp2tQ.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-BGqsnc_3.js → flowDiagram-KWPJA3E3-WLE6rKB4.js} +1 -1
- package/dist/assets/{ganttDiagram-FUAMR5RP-D_-UeReH.js → ganttDiagram-FUAMR5RP-BbjS-4gn.js} +1 -1
- package/dist/assets/{gitGraphDiagram-X574FWY7-D0uooONx.js → gitGraphDiagram-X574FWY7-Dpy2QSGq.js} +1 -1
- package/dist/assets/index-BIMdIbaw.css +1 -0
- package/dist/assets/index-CHnODCr2.js +583 -0
- package/dist/assets/{index-zRsJERGJ.js → index-CIaHn5NS.js} +1 -1
- package/dist/assets/{infoDiagram-VRGFBTTK-B9e1z77f.js → infoDiagram-VRGFBTTK-D_jKWlKe.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-BB4vNwvD.js → ishikawaDiagram-OU5B5YK6-DLJohSuK.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-DpkosOTB.js → journeyDiagram-ZHPQQLJL-DPOFj0qN.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-DbDP4kUu.js → kanban-definition-PNTS6WVX-BI7v-xpK.js} +1 -1
- package/dist/assets/{linear-DBJGPmjT.js → linear-C2pWPSxO.js} +1 -1
- package/dist/assets/{mermaid.core-DWPRi-ue.js → mermaid.core-CR-j5WQU.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-nszBbJmx.js → mindmap-definition-NLK3R4M7-lz9GvXRh.js} +1 -1
- package/dist/assets/{pegDiagram-GJSIUBJH-CWykJWu_.js → pegDiagram-GJSIUBJH-Dl4_ia61.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-g3Da-Vnv.js → pieDiagram-5QR66LMP-DWuT3n88.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-Wzrlpzgh.js → quadrantDiagram-O4NWA36T-DXWe9Jx7.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-moHTFMC0.js → railroadDiagram-XR7U4H2S-COY1IBVY.js} +1 -1
- package/dist/assets/{requirementDiagram-PLB6GJNP-CwfXdFH8.js → requirementDiagram-PLB6GJNP-DnyVuhsQ.js} +1 -1
- package/dist/assets/{sankeyDiagram-IPEJSGJF-3ZROYvnq.js → sankeyDiagram-IPEJSGJF-BSc4NdGK.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-E1TBebP8.js → sequenceDiagram-PO4LG4MO-kqEU2EGq.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-DHKEU5pu.js → sizeCapture-INFHLROL-BvB4bkWD.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-BguEj09D.js → stateDiagram-v2-GCMORJYK-BIrqNv7y.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-C7IDYnhd.js → swimlanes-2SLR337P-CFnalQUE.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-C4a8qNGj.js +8 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-DCW-F5PW.js → timeline-definition-EJHVYXUP-CsSWJnSQ.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-xBMFtWYV.js → usecaseDiagram-POWQR4AR-DkAmJ1EE.js} +1 -1
- package/dist/assets/{vennDiagram-UO4OBE2U-B5nIkuH8.js → vennDiagram-UO4OBE2U-C3vd9drL.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-DYFAhdbr.js → wardleyDiagram-VNRHLVJA-j26CM-pi.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-DeXwX6Cz.js → xychartDiagram-PMCCYNJV-BYu1Q_at.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-server/companion/src/routes.js +8 -1
- package/dist-server/connector-proxy.js +105 -1
- package/dist-server/container-mcp.js +3 -1
- package/dist-server/drivers/agents-proxy.js +277 -22
- package/dist-server/index.js +23150 -19947
- package/dist-server/local-computer-proxy.js +2 -0
- package/dist-server/mcp-gate.js +2 -0
- package/dist-server/mcp-server.js +5 -3
- package/dist-server/message-search.worker.js +52 -0
- package/dist-server/openmausbot.js +540 -298
- package/dist-server/pair-cli.js +540 -298
- package/dist-server/server/admission.js +81 -0
- package/dist-server/server/aside-queue.js +294 -0
- package/dist-server/server/attachments.js +43 -1
- package/dist-server/server/bot-attachment.js +107 -0
- package/dist-server/server/bot-overview.js +19 -0
- package/dist-server/server/cli-api-setup.js +1 -0
- package/dist-server/server/composio.js +297 -1
- package/dist-server/server/config.js +25 -3
- package/dist-server/server/connector-advertisement.js +165 -0
- package/dist-server/server/connector-proxy.js +14 -2
- package/dist-server/server/connector-verdict.js +31 -4
- package/dist-server/server/container-computer.js +60 -0
- package/dist-server/server/contracts.js +22 -0
- package/dist-server/server/drivers/acp/core.js +24 -6
- package/dist-server/server/drivers/acp/cursor.js +3 -7
- package/dist-server/server/drivers/acp/droid.js +4 -7
- package/dist-server/server/drivers/acp/gemini.js +4 -4
- package/dist-server/server/drivers/acp/grok.js +4 -9
- package/dist-server/server/drivers/acp/hermes.js +3 -5
- package/dist-server/server/drivers/acp/opencode-go.js +2 -5
- package/dist-server/server/drivers/acp/qwen.js +9 -15
- package/dist-server/server/drivers/agents-call.js +137 -10
- package/dist-server/server/drivers/agents-catalog.js +100 -6
- package/dist-server/server/drivers/boxagent.js +2 -16
- package/dist-server/server/drivers/claude.js +31 -17
- package/dist-server/server/drivers/codex-catalog.js +14 -6
- package/dist-server/server/drivers/codex-identity.js +2 -1
- package/dist-server/server/drivers/codex-release.js +48 -0
- package/dist-server/server/drivers/codex.js +7 -25
- package/dist-server/server/drivers/openai-chat.js +26 -2
- package/dist-server/server/drivers/pi.js +237 -30
- package/dist-server/server/drivers/prompt-split.js +32 -9
- package/dist-server/server/drivers/session-idle.js +29 -0
- package/dist-server/server/env-path.js +15 -0
- package/dist-server/server/guarded-requests.js +2 -2
- package/dist-server/server/harness-capabilities.js +46 -0
- package/dist-server/server/index.js +1037 -209
- package/dist-server/server/message-db.js +22 -42
- package/dist-server/server/message-file.js +9 -1
- package/dist-server/server/message-search-query.js +43 -0
- package/dist-server/server/message-search-worker.js +80 -0
- package/dist-server/server/message-search.worker.js +21 -0
- package/dist-server/server/model-requests.js +248 -0
- package/dist-server/server/options-card.js +21 -0
- package/dist-server/server/org-library.js +15 -1
- package/dist-server/server/peer-delivery.js +60 -0
- package/dist-server/server/peer-roster.js +57 -0
- package/dist-server/server/presets.js +32 -32
- package/dist-server/server/profile-requests.js +66 -39
- package/dist-server/server/profile-revision.js +9 -1
- package/dist-server/server/profile-versions.js +6 -3
- package/dist-server/server/routine-requests.js +29 -7
- package/dist-server/server/skill-fetch.js +72 -14
- package/dist-server/server/skills.js +1 -0
- package/dist-server/server/store.js +32 -2
- package/dist-server/server/system-prompt.js +26 -2
- package/dist-server/server/team-setup-requests.js +124 -23
- package/dist-server/server/thread-events.js +3 -1
- package/dist-server/server/tightening-requests.js +405 -0
- package/dist-server/server/tts/chatterbox.js +27 -5
- package/dist-server/server/usage-ledger.js +7 -1
- package/dist-server/server/workspace-backup.js +40 -3
- package/dist-server/server/workspace-backup.worker.js +10 -0
- package/dist-server/shared/ask-question.js +19 -0
- package/dist-server/shared/credential-request.js +5 -1
- package/dist-server/shared/line-diff.js +23 -0
- package/dist-server/shared/model-request.js +1 -0
- package/dist-server/shared/options-card.js +51 -0
- package/dist-server/shared/profile-request.js +5 -4
- package/dist-server/shared/tightening-request.js +87 -0
- package/dist-server/src/lib/composer-attachments.js +25 -3
- package/dist-server/vps-container-mcp.js +3 -1
- package/dist-server/workspace-backup.worker.js +19474 -0
- package/package.json +1 -1
- package/dist/assets/channel-taCNRlUU.js +0 -1
- package/dist/assets/index-BwdMAQ6p.css +0 -1
- package/dist/assets/index-ByJennr7.js +0 -581
- package/dist/assets/swimlanesDiagram-TC7HE7FX-BpEdoB2e.js +0 -8
package/dist-server/pair-cli.js
CHANGED
|
@@ -17791,6 +17791,14 @@ var init_wire = __esm({
|
|
|
17791
17791
|
function isModelVariant(value) {
|
|
17792
17792
|
return typeof value === "string" && value.length > 0 && value.length <= 256 && value.trim() === value && !new RegExp("\\p{Cc}", "u").test(value);
|
|
17793
17793
|
}
|
|
17794
|
+
function titleCaseModelId(id, wordBreaks) {
|
|
17795
|
+
return id.split(wordBreaks).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
17796
|
+
}
|
|
17797
|
+
function qualifiedModelLabel(id, qualifier, options = {}) {
|
|
17798
|
+
const { redundantWhen = () => false, decorate = (facet) => ` \u2014 ${facet}` } = options;
|
|
17799
|
+
if (!qualifier || redundantWhen(id, qualifier)) return id;
|
|
17800
|
+
return `${id}${decorate(qualifier)}`;
|
|
17801
|
+
}
|
|
17794
17802
|
var eventCounter, newEventId, newId;
|
|
17795
17803
|
var init_contracts = __esm({
|
|
17796
17804
|
"server/contracts.ts"() {
|
|
@@ -18923,7 +18931,16 @@ function loadConfig() {
|
|
|
18923
18931
|
let cfg = {};
|
|
18924
18932
|
try {
|
|
18925
18933
|
cfg = parseStoredConfig(parseJson(readFileSync3(join9(DATA_DIR, "config.json"), "utf8")));
|
|
18926
|
-
|
|
18934
|
+
lastIgnoredConfigWarning = "";
|
|
18935
|
+
} catch (error51) {
|
|
18936
|
+
if (error51?.code !== "ENOENT") {
|
|
18937
|
+
const reason = error51 instanceof SyntaxError ? "invalid JSON" : error51 instanceof Error ? error51.message : "unable to read configuration";
|
|
18938
|
+
const warning = `config: ignoring ${join9(DATA_DIR, "config.json")} and using defaults: ${reason}`;
|
|
18939
|
+
if (warning !== lastIgnoredConfigWarning) console.warn(warning);
|
|
18940
|
+
lastIgnoredConfigWarning = warning;
|
|
18941
|
+
} else {
|
|
18942
|
+
lastIgnoredConfigWarning = "";
|
|
18943
|
+
}
|
|
18927
18944
|
}
|
|
18928
18945
|
cfg.mistral = { ...cfg.mistral };
|
|
18929
18946
|
if (process.env.MISTRAL_API_KEY !== void 0) cfg.mistral.key = process.env.MISTRAL_API_KEY;
|
|
@@ -19150,7 +19167,7 @@ function instanceConfigs(cfg) {
|
|
|
19150
19167
|
}
|
|
19151
19168
|
return map3;
|
|
19152
19169
|
}
|
|
19153
|
-
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES, DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES, DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES, DEFAULT_MAX_CONCURRENT_BOT_THREADS, MAX_CONCURRENT_BOT_THREADS, MIN_THREAD_EVENT_LOG_BYTES, MAX_THREAD_EVENT_LOG_BYTES, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, CDP_PORT, CDP_URL, vpsConfigSchema, browserEngineConfigSchema, roomConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, onboardingConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, threadsConfigSchema, newBotsConfigSchema, newBotsPatchSchema, threadsPatchSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, WORKSPACE_CREDENTIAL_ENV, CONTROL_PLANE_ENV, CONTROL_PLANE_ENV_PREFIX, PROVIDER_CREDENTIAL_ENV, configSaveListeners;
|
|
19170
|
+
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES, DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES, DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES, DEFAULT_MAX_CONCURRENT_BOT_THREADS, MAX_CONCURRENT_BOT_THREADS, MIN_THREAD_EVENT_LOG_BYTES, MAX_THREAD_EVENT_LOG_BYTES, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, CDP_PORT, CDP_URL, vpsConfigSchema, browserEngineConfigSchema, roomConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, onboardingConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, threadsConfigSchema, newBotsConfigSchema, newBotsPatchSchema, threadsPatchSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, lastIgnoredConfigWarning, WORKSPACE_CREDENTIAL_ENV, CONTROL_PLANE_ENV, CONTROL_PLANE_ENV_PREFIX, PROVIDER_CREDENTIAL_ENV, configSaveListeners;
|
|
19154
19171
|
var init_config = __esm({
|
|
19155
19172
|
"server/config.ts"() {
|
|
19156
19173
|
"use strict";
|
|
@@ -19177,7 +19194,7 @@ var init_config = __esm({
|
|
|
19177
19194
|
MIN_THREAD_EVENT_LOG_BYTES = 256 * 1024;
|
|
19178
19195
|
MAX_THREAD_EVENT_LOG_BYTES = 4 * 1024 * 1024 * 1024;
|
|
19179
19196
|
MIN_LOCAL_VM_MAX_INSTANCES = 1;
|
|
19180
|
-
MAX_LOCAL_VM_MAX_INSTANCES =
|
|
19197
|
+
MAX_LOCAL_VM_MAX_INSTANCES = 8;
|
|
19181
19198
|
CDP_PORT = /^[0-9]{1,5}$/;
|
|
19182
19199
|
CDP_URL = /^(https?|wss?):\/\/\S+$/i;
|
|
19183
19200
|
vpsConfigSchema = external_exports.object({
|
|
@@ -19432,6 +19449,7 @@ var init_config = __esm({
|
|
|
19432
19449
|
LEGACY_DATA_DIR = join9(homedir4(), ".opengrokbot");
|
|
19433
19450
|
EVENTS_DIR = join9(DATA_DIR, "events");
|
|
19434
19451
|
NATIVE_DIR = join9(DATA_DIR, "native");
|
|
19452
|
+
lastIgnoredConfigWarning = "";
|
|
19435
19453
|
WORKSPACE_CREDENTIAL_ENV = [
|
|
19436
19454
|
"XAI_API_KEY",
|
|
19437
19455
|
"MISTRAL_API_KEY",
|
|
@@ -19877,6 +19895,8 @@ function knownDirs() {
|
|
|
19877
19895
|
join11(home, ".volta", "bin"),
|
|
19878
19896
|
join11(home, ".bun", "bin"),
|
|
19879
19897
|
join11(home, ".asdf", "shims"),
|
|
19898
|
+
join11(home, ".local", "share", "mise", "shims"),
|
|
19899
|
+
// mise installer
|
|
19880
19900
|
join11(home, ".deno", "bin"),
|
|
19881
19901
|
join11(home, "bin"),
|
|
19882
19902
|
...nvmBinDirs()
|
|
@@ -19952,6 +19972,12 @@ function probeLoginShellPath() {
|
|
|
19952
19972
|
}
|
|
19953
19973
|
);
|
|
19954
19974
|
}
|
|
19975
|
+
function userHome(env = process.env) {
|
|
19976
|
+
return process.platform === "win32" ? env.USERPROFILE || env.HOME || homedir5() : env.HOME || env.USERPROFILE || homedir5();
|
|
19977
|
+
}
|
|
19978
|
+
function harnessHome(name, env = process.env) {
|
|
19979
|
+
return join11(userHome(env), `.${name}`);
|
|
19980
|
+
}
|
|
19955
19981
|
function findCliCandidates(name) {
|
|
19956
19982
|
if (!name || /[\n\r]/.test(name)) return [];
|
|
19957
19983
|
if (/[/\\]/.test(name) || /^[a-zA-Z]:/.test(name)) return [name];
|
|
@@ -20900,7 +20926,7 @@ var init_local_inject = __esm({
|
|
|
20900
20926
|
|
|
20901
20927
|
// server/drivers/prompt-split.ts
|
|
20902
20928
|
import { createHash as createHash3 } from "node:crypto";
|
|
20903
|
-
import { mkdirSync as mkdirSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
20929
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync7, rmSync as rmSync4 } from "node:fs";
|
|
20904
20930
|
import { join as join15 } from "node:path";
|
|
20905
20931
|
function promptHalves(turn) {
|
|
20906
20932
|
const { systemStable, systemVolatile } = turn;
|
|
@@ -20927,7 +20953,11 @@ function readPromptSplitReceipt(scope, key) {
|
|
|
20927
20953
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
20928
20954
|
const record3 = raw;
|
|
20929
20955
|
if (typeof record3.stable === "string" && typeof record3.volatile === "string") {
|
|
20930
|
-
return {
|
|
20956
|
+
return {
|
|
20957
|
+
stable: record3.stable,
|
|
20958
|
+
volatile: record3.volatile,
|
|
20959
|
+
...typeof record3.turnsSinceFull === "number" ? { turnsSinceFull: record3.turnsSinceFull } : {}
|
|
20960
|
+
};
|
|
20931
20961
|
}
|
|
20932
20962
|
}
|
|
20933
20963
|
} catch {
|
|
@@ -20938,13 +20968,21 @@ function writePromptSplitReceipt(scope, key, receipt) {
|
|
|
20938
20968
|
mkdirSync9(join15(DATA_DIR, "prompt-split"), { recursive: true });
|
|
20939
20969
|
writeFileAtomic(receiptPath(scope, key), JSON.stringify(receipt), { mode: 384 });
|
|
20940
20970
|
}
|
|
20941
|
-
function
|
|
20942
|
-
|
|
20943
|
-
|
|
20944
|
-
|
|
20971
|
+
function deletePromptSplitReceipt(scope, key) {
|
|
20972
|
+
try {
|
|
20973
|
+
rmSync4(receiptPath(scope, key));
|
|
20974
|
+
} catch {
|
|
20975
|
+
}
|
|
20976
|
+
}
|
|
20977
|
+
function splitSessionPrompt(stable, volatile, previous, fullSystem, text4, perTurnVolatile = false, reAnchorAfterTurns = 0) {
|
|
20978
|
+
const fingerprints = promptSplitFingerprints(stable, volatile);
|
|
20979
|
+
const turnsSinceFull = typeof previous?.turnsSinceFull === "number" ? previous.turnsSinceFull : 0;
|
|
20980
|
+
const reAnchor = reAnchorAfterTurns > 0 && previous !== null && turnsSinceFull >= reAnchorAfterTurns;
|
|
20981
|
+
if (previous === null || previous.stable !== fingerprints.stable || reAnchor) {
|
|
20982
|
+
return { text: fullSystem ? fullSystem + "\n\n" + text4 : text4, receipt: { ...fingerprints, turnsSinceFull: 0 } };
|
|
20945
20983
|
}
|
|
20946
|
-
const note = previous.volatile ===
|
|
20947
|
-
return { text: withContextNote(note, text4), receipt };
|
|
20984
|
+
const note = previous.volatile === fingerprints.volatile && !perTurnVolatile ? "" : volatileContextNote(volatile, previous.volatile !== EMPTY_FINGERPRINT);
|
|
20985
|
+
return { text: withContextNote(note, text4), receipt: { ...fingerprints, turnsSinceFull: turnsSinceFull + 1 } };
|
|
20948
20986
|
}
|
|
20949
20987
|
var VOLATILE_CONTEXT_NOTE_PREFIX, VOLATILE_CONTEXT_CLEARED_NOTE, digest, EMPTY_FINGERPRINT, receiptPath;
|
|
20950
20988
|
var init_prompt_split = __esm({
|
|
@@ -21051,6 +21089,19 @@ function stripOmbAskBlock(output) {
|
|
|
21051
21089
|
if (!OMB_ASK_FENCE.test(output)) return output;
|
|
21052
21090
|
return output.replace(OMB_ASK_FENCE_GLOBAL, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
21053
21091
|
}
|
|
21092
|
+
function ombAskProtocolPrompt() {
|
|
21093
|
+
return [
|
|
21094
|
+
"",
|
|
21095
|
+
"## Asking the person a question",
|
|
21096
|
+
"When a decision belongs to the person, end your reply with a fenced block exactly like this:",
|
|
21097
|
+
"",
|
|
21098
|
+
"```omb-ask",
|
|
21099
|
+
'{"questions":[{"question":"Ship the release now?","header":"Release","options":[{"label":"Ship now"},{"label":"Wait for the QA signoff"}]}]}',
|
|
21100
|
+
"```",
|
|
21101
|
+
"",
|
|
21102
|
+
`The block must be the last thing in your reply. You may ask up to ${MAX_QUESTIONS} questions at once, each with up to ${MAX_OPTIONS} options; the person can always answer in their own words. Their answers arrive on your next prompt as \`Q:\`/\`A:\` lines \u2014 never invent them.`
|
|
21103
|
+
].join("\n");
|
|
21104
|
+
}
|
|
21054
21105
|
function askQuestionSummary(questions) {
|
|
21055
21106
|
const first = questions[0]?.question ?? "";
|
|
21056
21107
|
const rest = questions.length - 1;
|
|
@@ -21199,7 +21250,7 @@ var init_ask_question = __esm({
|
|
|
21199
21250
|
});
|
|
21200
21251
|
|
|
21201
21252
|
// server/thread-log-rotation.ts
|
|
21202
|
-
import { closeSync as closeSync4, fstatSync, openSync as openSync4, readSync as readSync2, renameSync as renameSync5, rmSync as
|
|
21253
|
+
import { closeSync as closeSync4, fstatSync, openSync as openSync4, readSync as readSync2, renameSync as renameSync5, rmSync as rmSync5, statSync as statSync3, writeSync } from "node:fs";
|
|
21203
21254
|
function currentThreadLogCap() {
|
|
21204
21255
|
try {
|
|
21205
21256
|
return capProvider();
|
|
@@ -21251,7 +21302,7 @@ function trimToTail(file2, keepBytes) {
|
|
|
21251
21302
|
renameSync5(staging, file2);
|
|
21252
21303
|
} catch {
|
|
21253
21304
|
try {
|
|
21254
|
-
|
|
21305
|
+
rmSync5(staging, { force: true });
|
|
21255
21306
|
} catch {
|
|
21256
21307
|
}
|
|
21257
21308
|
}
|
|
@@ -21423,6 +21474,33 @@ var init_resume_recovery = __esm({
|
|
|
21423
21474
|
}
|
|
21424
21475
|
});
|
|
21425
21476
|
|
|
21477
|
+
// server/drivers/session-idle.ts
|
|
21478
|
+
function usableMilliseconds(raw) {
|
|
21479
|
+
const value = Number(raw);
|
|
21480
|
+
return Number.isFinite(value) && value > 0 && value <= MAX_TIMER_MS ? value : null;
|
|
21481
|
+
}
|
|
21482
|
+
function sessionIdlePolicy(driverPrefix, env = process.env) {
|
|
21483
|
+
const minimumMs = Math.max(
|
|
21484
|
+
MINIMUM_IDLE_MS,
|
|
21485
|
+
usableMilliseconds(
|
|
21486
|
+
env[`OMB_${driverPrefix}_SESSION_IDLE_MIN_MS`] ?? env.OMB_SESSION_IDLE_MIN_MS
|
|
21487
|
+
) ?? 0
|
|
21488
|
+
);
|
|
21489
|
+
const configured = usableMilliseconds(
|
|
21490
|
+
env[`OMB_${driverPrefix}_SESSION_IDLE_MS`] ?? env.OMB_SESSION_IDLE_MS
|
|
21491
|
+
) ?? DEFAULT_IDLE_MS;
|
|
21492
|
+
return { idleMs: Math.max(minimumMs, configured), minimumMs };
|
|
21493
|
+
}
|
|
21494
|
+
var DEFAULT_IDLE_MS, MINIMUM_IDLE_MS, MAX_TIMER_MS;
|
|
21495
|
+
var init_session_idle = __esm({
|
|
21496
|
+
"server/drivers/session-idle.ts"() {
|
|
21497
|
+
"use strict";
|
|
21498
|
+
DEFAULT_IDLE_MS = 10 * 6e4;
|
|
21499
|
+
MINIMUM_IDLE_MS = 1e4;
|
|
21500
|
+
MAX_TIMER_MS = 2147483647;
|
|
21501
|
+
}
|
|
21502
|
+
});
|
|
21503
|
+
|
|
21426
21504
|
// server/drivers/acp/core.ts
|
|
21427
21505
|
import { homedir as homedir7 } from "node:os";
|
|
21428
21506
|
import { lstat, mkdir as mkdir3, readFile, realpath, stat as stat2, writeFile } from "node:fs/promises";
|
|
@@ -21542,6 +21620,17 @@ function versionFromProbe(stdout2, stderr) {
|
|
|
21542
21620
|
const err = (stderr ?? "").trim().split(/\r\n|\n|\r/, 1)[0]?.trim() ?? "";
|
|
21543
21621
|
return err || null;
|
|
21544
21622
|
}
|
|
21623
|
+
function parseVersionTriple(value) {
|
|
21624
|
+
const match = /(\d+)\.(\d+)\.(\d+)/.exec(value);
|
|
21625
|
+
if (!match) return null;
|
|
21626
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
21627
|
+
}
|
|
21628
|
+
function versionAtLeast(installed, floor) {
|
|
21629
|
+
for (let i2 = 0; i2 < 3; i2 += 1) {
|
|
21630
|
+
if (installed[i2] !== floor[i2]) return installed[i2] > floor[i2];
|
|
21631
|
+
}
|
|
21632
|
+
return true;
|
|
21633
|
+
}
|
|
21545
21634
|
function createAcpDriver(support11) {
|
|
21546
21635
|
const DRIVER_KIND8 = support11.driverKind;
|
|
21547
21636
|
const SOURCE = support11.nativeSource;
|
|
@@ -21587,9 +21676,7 @@ function createAcpDriver(support11) {
|
|
|
21587
21676
|
const listeners = /* @__PURE__ */ new Set();
|
|
21588
21677
|
const active = /* @__PURE__ */ new Map();
|
|
21589
21678
|
const sessions = /* @__PURE__ */ new Map();
|
|
21590
|
-
const
|
|
21591
|
-
const sessionIdleMinimum = Number.isFinite(configuredIdleMinimum) && configuredIdleMinimum > 0 ? configuredIdleMinimum : 1e4;
|
|
21592
|
-
const SESSION_IDLE_MS = Math.max(sessionIdleMinimum, Number(process.env.OMB_ACP_SESSION_IDLE_MS) || 10 * 6e4);
|
|
21679
|
+
const { idleMs: SESSION_IDLE_MS } = sessionIdlePolicy("ACP");
|
|
21593
21680
|
const closeSession = (threadId, why) => {
|
|
21594
21681
|
const session = sessions.get(threadId);
|
|
21595
21682
|
if (!session || session.closing) return;
|
|
@@ -22421,7 +22508,8 @@ function createAcpDriver(support11) {
|
|
|
22421
22508
|
readPromptSplitReceipt(DRIVER_KIND8, receiptKey),
|
|
22422
22509
|
promptTurn.system,
|
|
22423
22510
|
promptTurn.text,
|
|
22424
|
-
Boolean(turn.mentionTurn)
|
|
22511
|
+
Boolean(turn.mentionTurn),
|
|
22512
|
+
ACP_PROMPT_RE_ANCHOR_TURNS
|
|
22425
22513
|
);
|
|
22426
22514
|
promptInput = { ...promptTurn, system: "", text: composed.text };
|
|
22427
22515
|
pendingSplitReceipt = { key: receiptKey, receipt: composed.receipt };
|
|
@@ -22559,7 +22647,7 @@ ${promptInput.text}` : promptInput.text;
|
|
|
22559
22647
|
}
|
|
22560
22648
|
};
|
|
22561
22649
|
}
|
|
22562
|
-
var envOr, INIT_TIMEOUT, SESSION_CONFIG_TIMEOUT, NEW_SESSION_TIMEOUT, LOAD_SESSION_TIMEOUT, promptIdleTimeoutMs, CLIENT_FILE_MAX_BYTES, TOOL_LOG_TEXT_LIMIT;
|
|
22650
|
+
var envOr, INIT_TIMEOUT, SESSION_CONFIG_TIMEOUT, NEW_SESSION_TIMEOUT, LOAD_SESSION_TIMEOUT, ACP_PROMPT_RE_ANCHOR_TURNS, promptIdleTimeoutMs, CLIENT_FILE_MAX_BYTES, TOOL_LOG_TEXT_LIMIT;
|
|
22563
22651
|
var init_core3 = __esm({
|
|
22564
22652
|
"server/drivers/acp/core.ts"() {
|
|
22565
22653
|
"use strict";
|
|
@@ -22577,11 +22665,13 @@ var init_core3 = __esm({
|
|
|
22577
22665
|
init_mcp_tool_images();
|
|
22578
22666
|
init_redact2();
|
|
22579
22667
|
init_resume_recovery();
|
|
22668
|
+
init_session_idle();
|
|
22580
22669
|
envOr = (key, fallback) => Number(process.env[key] ?? fallback);
|
|
22581
22670
|
INIT_TIMEOUT = envOr("OPENMAUS_ACP_INIT_TIMEOUT_MS", 3e5);
|
|
22582
22671
|
SESSION_CONFIG_TIMEOUT = envOr("OPENMAUS_ACP_SESSION_CONFIG_TIMEOUT_MS", 3e5);
|
|
22583
22672
|
NEW_SESSION_TIMEOUT = envOr("OPENMAUS_ACP_NEW_SESSION_TIMEOUT_MS", 3e5);
|
|
22584
22673
|
LOAD_SESSION_TIMEOUT = envOr("OPENMAUS_ACP_LOAD_SESSION_TIMEOUT_MS", 12e4);
|
|
22674
|
+
ACP_PROMPT_RE_ANCHOR_TURNS = 8;
|
|
22585
22675
|
promptIdleTimeoutMs = () => {
|
|
22586
22676
|
const raw = process.env.OPENMAUS_ACP_PROMPT_IDLE_TIMEOUT_MS;
|
|
22587
22677
|
if (raw === void 0) return 18e4;
|
|
@@ -23705,7 +23795,7 @@ function decodeConfig(raw) {
|
|
|
23705
23795
|
...typeof o.askTimeoutMs === "number" ? { askTimeoutMs: o.askTimeoutMs } : {}
|
|
23706
23796
|
};
|
|
23707
23797
|
}
|
|
23708
|
-
var DRIVER_KIND, BOX_API, MODELS,
|
|
23798
|
+
var DRIVER_KIND, BOX_API, MODELS, ASK_FENCE_ANY, catalog, providerFor, BoxAgentDriver;
|
|
23709
23799
|
var init_boxagent = __esm({
|
|
23710
23800
|
"server/drivers/boxagent.ts"() {
|
|
23711
23801
|
"use strict";
|
|
@@ -23722,17 +23812,6 @@ var init_boxagent = __esm({
|
|
|
23722
23812
|
{ id: "gpt-5.4", label: "GPT-5.4 (Codex) \xB7 on the box" }
|
|
23723
23813
|
]
|
|
23724
23814
|
};
|
|
23725
|
-
ASK_PROTOCOL = [
|
|
23726
|
-
"",
|
|
23727
|
-
"## Asking the person a question",
|
|
23728
|
-
"When a decision belongs to the person, end your reply with a fenced block exactly like this:",
|
|
23729
|
-
"",
|
|
23730
|
-
"```omb-ask",
|
|
23731
|
-
'{"questions":[{"question":"Ship the release now?","header":"Release","options":[{"label":"Ship now"},{"label":"Wait for the QA signoff"}]}]}',
|
|
23732
|
-
"```",
|
|
23733
|
-
"",
|
|
23734
|
-
"The block must be the last thing in your reply. You may ask up to 6 questions at once, each with up to 12 options; the person can always answer in their own words. Their answers arrive on your next prompt as `Q:`/`A:` lines \u2014 never invent them."
|
|
23735
|
-
].join("\n");
|
|
23736
23815
|
ASK_FENCE_ANY = /(^|\n)[ \t]{0,3}(`{3,}|~{3,})[ \t]*omb-ask\b/;
|
|
23737
23816
|
catalog = null;
|
|
23738
23817
|
providerFor = (model) => {
|
|
@@ -23793,7 +23872,7 @@ var init_boxagent = __esm({
|
|
|
23793
23872
|
const prompt = [
|
|
23794
23873
|
turn.system,
|
|
23795
23874
|
"You are working on the assigned cloud computer \u2014 use its desktop, Chrome, and shell within the access described above.",
|
|
23796
|
-
|
|
23875
|
+
ombAskProtocolPrompt(),
|
|
23797
23876
|
...correction ? [correction] : [],
|
|
23798
23877
|
"",
|
|
23799
23878
|
turn.text
|
|
@@ -24542,7 +24621,7 @@ var init_retry = __esm({
|
|
|
24542
24621
|
|
|
24543
24622
|
// server/drivers/claude.ts
|
|
24544
24623
|
import { createHash as createHash7, randomBytes as randomBytes2 } from "node:crypto";
|
|
24545
|
-
import { chmodSync as chmodSync4, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync2, readFileSync as readFileSync8, rmSync as
|
|
24624
|
+
import { chmodSync as chmodSync4, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync2, readFileSync as readFileSync8, rmSync as rmSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
24546
24625
|
import { createServer as createNetServer } from "node:net";
|
|
24547
24626
|
import { homedir as homedir9, tmpdir as tmpdir3 } from "node:os";
|
|
24548
24627
|
import { join as join21, dirname as dirname9, isAbsolute as isAbsolute5, normalize } from "node:path";
|
|
@@ -24584,6 +24663,10 @@ function claudeAuthFailure(frame, text4) {
|
|
|
24584
24663
|
if (frame.is_api_error_message !== true && typeof frame.error !== "string") return false;
|
|
24585
24664
|
return frame.error === "authentication_failed" || classifyError({ text: text4 }).reason === "auth";
|
|
24586
24665
|
}
|
|
24666
|
+
function claudeVersionTooOld(frame, text4) {
|
|
24667
|
+
if (frame.is_api_error_message !== true && typeof frame.error !== "string") return false;
|
|
24668
|
+
return /\bClaude Code v?\d+(?:\.\d+)+ does not support this model\b/i.test(text4);
|
|
24669
|
+
}
|
|
24587
24670
|
function claudeEnvironment(model, source = process.env, configDir, instanceEnvironment = {}) {
|
|
24588
24671
|
const env = { ...source, PATH: augmentedPath(), NPM_CONFIG_LOGLEVEL: "error" };
|
|
24589
24672
|
if (configDir?.trim()) {
|
|
@@ -24655,15 +24738,7 @@ function autoCompactWindow(env) {
|
|
|
24655
24738
|
return String(Math.min(1e6, Math.max(1e5, Math.floor(parsed))));
|
|
24656
24739
|
}
|
|
24657
24740
|
function parseClaudeCliVersion(stdout2) {
|
|
24658
|
-
|
|
24659
|
-
if (!match) return null;
|
|
24660
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
24661
|
-
}
|
|
24662
|
-
function versionAtLeast(installed, floor) {
|
|
24663
|
-
for (let i2 = 0; i2 < 3; i2 += 1) {
|
|
24664
|
-
if (installed[i2] !== floor[i2]) return installed[i2] > floor[i2];
|
|
24665
|
-
}
|
|
24666
|
-
return true;
|
|
24741
|
+
return parseVersionTriple(stdout2 ?? "");
|
|
24667
24742
|
}
|
|
24668
24743
|
function claudeCliSupports(version2, flag) {
|
|
24669
24744
|
return version2 === null || versionAtLeast(version2, CLAUDE_FLAG_FLOORS[flag]);
|
|
@@ -24731,7 +24806,7 @@ function readClaudeModelCatalog(env = process.env) {
|
|
|
24731
24806
|
function removePrivateTempDir(filePath) {
|
|
24732
24807
|
if (!filePath) return true;
|
|
24733
24808
|
try {
|
|
24734
|
-
|
|
24809
|
+
rmSync6(dirname9(filePath), { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
|
|
24735
24810
|
return true;
|
|
24736
24811
|
} catch {
|
|
24737
24812
|
return false;
|
|
@@ -25026,6 +25101,8 @@ var init_claude = __esm({
|
|
|
25026
25101
|
init_contracts();
|
|
25027
25102
|
init_tool_summary();
|
|
25028
25103
|
init_retry();
|
|
25104
|
+
init_session_idle();
|
|
25105
|
+
init_core3();
|
|
25029
25106
|
init_local_inject();
|
|
25030
25107
|
init_native();
|
|
25031
25108
|
init_permission_command();
|
|
@@ -25124,9 +25201,7 @@ var init_claude = __esm({
|
|
|
25124
25201
|
const listeners = /* @__PURE__ */ new Set();
|
|
25125
25202
|
const active = /* @__PURE__ */ new Map();
|
|
25126
25203
|
const sessions = /* @__PURE__ */ new Map();
|
|
25127
|
-
const
|
|
25128
|
-
const sessionIdleMinimum = Number.isFinite(configuredIdleMinimum) && configuredIdleMinimum > 0 ? configuredIdleMinimum : 1e4;
|
|
25129
|
-
const SESSION_IDLE_MS = Math.max(sessionIdleMinimum, Number(process.env.OMB_CLAUDE_SESSION_IDLE_MS) || 10 * 6e4);
|
|
25204
|
+
const { idleMs: SESSION_IDLE_MS } = sessionIdlePolicy("CLAUDE");
|
|
25130
25205
|
const stopSession = (session) => {
|
|
25131
25206
|
void killCliTree(session.child).then((stopped) => {
|
|
25132
25207
|
if (stopped) void session.finishClose?.();
|
|
@@ -25387,7 +25462,7 @@ var init_claude = __esm({
|
|
|
25387
25462
|
retryState.delete(threadId);
|
|
25388
25463
|
if (mcpConfigPath) {
|
|
25389
25464
|
try {
|
|
25390
|
-
|
|
25465
|
+
rmSync6(dirname9(mcpConfigPath), { recursive: true, force: true });
|
|
25391
25466
|
} catch {
|
|
25392
25467
|
}
|
|
25393
25468
|
}
|
|
@@ -25395,7 +25470,7 @@ var init_claude = __esm({
|
|
|
25395
25470
|
}
|
|
25396
25471
|
if (mcpConfigPath) {
|
|
25397
25472
|
try {
|
|
25398
|
-
|
|
25473
|
+
rmSync6(dirname9(mcpConfigPath), { recursive: true, force: true });
|
|
25399
25474
|
} catch {
|
|
25400
25475
|
}
|
|
25401
25476
|
}
|
|
@@ -25407,7 +25482,7 @@ var init_claude = __esm({
|
|
|
25407
25482
|
broker = void 0;
|
|
25408
25483
|
if (mcpConfigPath) {
|
|
25409
25484
|
try {
|
|
25410
|
-
|
|
25485
|
+
rmSync6(dirname9(mcpConfigPath), { recursive: true, force: true });
|
|
25411
25486
|
} catch {
|
|
25412
25487
|
}
|
|
25413
25488
|
mcpConfigPath = null;
|
|
@@ -25524,7 +25599,7 @@ var init_claude = __esm({
|
|
|
25524
25599
|
session.broker?.pause();
|
|
25525
25600
|
if (session.mcpConfigPath) {
|
|
25526
25601
|
try {
|
|
25527
|
-
|
|
25602
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25528
25603
|
} catch {
|
|
25529
25604
|
}
|
|
25530
25605
|
session.mcpConfigPath = null;
|
|
@@ -25535,6 +25610,7 @@ var init_claude = __esm({
|
|
|
25535
25610
|
active.delete(threadId);
|
|
25536
25611
|
session.turn = null;
|
|
25537
25612
|
retryState.delete(threadId);
|
|
25613
|
+
if (stopReason === "update_required") closeSession(threadId, "update required");
|
|
25538
25614
|
emit({ ...base2(threadId, t2.turnId), type: "turn.completed", ok, stopReason, cost, ...usage ? { usage } : {} });
|
|
25539
25615
|
if (session.child.exitCode === null && !session.closing) armIdle(threadId);
|
|
25540
25616
|
};
|
|
@@ -25580,6 +25656,11 @@ var init_claude = __esm({
|
|
|
25580
25656
|
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message: text4, setup: true });
|
|
25581
25657
|
break;
|
|
25582
25658
|
}
|
|
25659
|
+
if (claudeVersionTooOld(o, text4)) {
|
|
25660
|
+
if (session.turn) session.turn.updateRequired = true;
|
|
25661
|
+
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message: text4, setup: true, claudeUpdate: true });
|
|
25662
|
+
break;
|
|
25663
|
+
}
|
|
25583
25664
|
if (text4.trim()) {
|
|
25584
25665
|
const synthetic = o.is_api_error_message === true || typeof o.error === "string" ? { synthetic: true } : {};
|
|
25585
25666
|
if (!session.turn?.sawStreamDelta) {
|
|
@@ -25629,7 +25710,7 @@ var init_claude = __esm({
|
|
|
25629
25710
|
if (o.origin?.kind === "task-notification") break;
|
|
25630
25711
|
settle(
|
|
25631
25712
|
o.is_error !== true,
|
|
25632
|
-
session.turn?.authFailed ? "auth_required" : o.stop_reason ?? o.terminal_reason ?? null,
|
|
25713
|
+
session.turn?.authFailed ? "auth_required" : session.turn?.updateRequired ? "update_required" : o.stop_reason ?? o.terminal_reason ?? null,
|
|
25633
25714
|
o.total_cost_usd ?? null,
|
|
25634
25715
|
o.usage ? {
|
|
25635
25716
|
input: (o.usage.input_tokens || 0) + (o.usage.cache_read_input_tokens || 0) + (o.usage.cache_creation_input_tokens || 0),
|
|
@@ -25684,7 +25765,7 @@ var init_claude = __esm({
|
|
|
25684
25765
|
failedBroker?.close();
|
|
25685
25766
|
if (session.mcpConfigPath) {
|
|
25686
25767
|
try {
|
|
25687
|
-
|
|
25768
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25688
25769
|
} catch {
|
|
25689
25770
|
}
|
|
25690
25771
|
session.mcpConfigPath = null;
|
|
@@ -25762,7 +25843,7 @@ var init_claude = __esm({
|
|
|
25762
25843
|
session.broker = void 0;
|
|
25763
25844
|
if (session.mcpConfigPath) {
|
|
25764
25845
|
try {
|
|
25765
|
-
|
|
25846
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25766
25847
|
} catch {
|
|
25767
25848
|
}
|
|
25768
25849
|
session.mcpConfigPath = null;
|
|
@@ -25814,7 +25895,7 @@ var init_claude = __esm({
|
|
|
25814
25895
|
session.broker?.close();
|
|
25815
25896
|
if (session.mcpConfigPath) {
|
|
25816
25897
|
try {
|
|
25817
|
-
|
|
25898
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25818
25899
|
} catch {
|
|
25819
25900
|
}
|
|
25820
25901
|
}
|
|
@@ -26028,9 +26109,9 @@ function mcpServerNamesInToml(toml) {
|
|
|
26028
26109
|
return names;
|
|
26029
26110
|
}
|
|
26030
26111
|
function codexConfigMcpServerNames(env) {
|
|
26031
|
-
const
|
|
26112
|
+
const codexHome2 = env.CODEX_HOME || join22(env.HOME || env.USERPROFILE || homedir10(), ".codex");
|
|
26032
26113
|
try {
|
|
26033
|
-
return mcpServerNamesInToml(readFileSync9(join22(
|
|
26114
|
+
return mcpServerNamesInToml(readFileSync9(join22(codexHome2, "config.toml"), "utf8"));
|
|
26034
26115
|
} catch {
|
|
26035
26116
|
return /* @__PURE__ */ new Set();
|
|
26036
26117
|
}
|
|
@@ -26049,10 +26130,124 @@ var init_codex_mcp_names = __esm({
|
|
|
26049
26130
|
}
|
|
26050
26131
|
});
|
|
26051
26132
|
|
|
26133
|
+
// server/drivers/codex-identity.ts
|
|
26134
|
+
import { homedir as homedir11 } from "node:os";
|
|
26135
|
+
import { isAbsolute as isAbsolute6, join as join23, resolve as resolve7 } from "node:path";
|
|
26136
|
+
function codexHome(env) {
|
|
26137
|
+
if (env.CODEX_HOME) return isAbsolute6(env.CODEX_HOME) ? resolve7(env.CODEX_HOME) : null;
|
|
26138
|
+
const home = userHome(env);
|
|
26139
|
+
return isAbsolute6(home) ? join23(home, ".codex") : null;
|
|
26140
|
+
}
|
|
26141
|
+
async function codexAccountEmail(cli, env, timeoutMs = 3e3) {
|
|
26142
|
+
const cwd = env.HOME || env.USERPROFILE || homedir11();
|
|
26143
|
+
if (!isAbsolute6(cwd) || !codexHome(env)) return null;
|
|
26144
|
+
return new Promise((resolveEmail) => {
|
|
26145
|
+
let child;
|
|
26146
|
+
try {
|
|
26147
|
+
child = spawnCli(cli, ["app-server"], { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
26148
|
+
} catch {
|
|
26149
|
+
resolveEmail(null);
|
|
26150
|
+
return;
|
|
26151
|
+
}
|
|
26152
|
+
let finishing = false;
|
|
26153
|
+
let buffer = "";
|
|
26154
|
+
let outputBytes = 0;
|
|
26155
|
+
let initialized = false;
|
|
26156
|
+
const finish = async (email3) => {
|
|
26157
|
+
if (finishing) return;
|
|
26158
|
+
finishing = true;
|
|
26159
|
+
clearTimeout(timer);
|
|
26160
|
+
let stopped = await killCliTree(child, 1e3);
|
|
26161
|
+
if (!stopped && child.pid) {
|
|
26162
|
+
try {
|
|
26163
|
+
if (process.platform === "win32") child.kill("SIGKILL");
|
|
26164
|
+
else process.kill(-child.pid, "SIGKILL");
|
|
26165
|
+
} catch {
|
|
26166
|
+
try {
|
|
26167
|
+
child.kill("SIGKILL");
|
|
26168
|
+
} catch {
|
|
26169
|
+
}
|
|
26170
|
+
}
|
|
26171
|
+
stopped = await killCliTree(child, 1e3);
|
|
26172
|
+
}
|
|
26173
|
+
resolveEmail(stopped ? email3 : null);
|
|
26174
|
+
};
|
|
26175
|
+
const timer = setTimeout(() => {
|
|
26176
|
+
void finish(null);
|
|
26177
|
+
}, timeoutMs);
|
|
26178
|
+
timer.unref();
|
|
26179
|
+
const send = (message2) => {
|
|
26180
|
+
try {
|
|
26181
|
+
child.stdin.write(`${JSON.stringify(message2)}
|
|
26182
|
+
`);
|
|
26183
|
+
} catch {
|
|
26184
|
+
void finish(null);
|
|
26185
|
+
}
|
|
26186
|
+
};
|
|
26187
|
+
child.stdin.on("error", () => {
|
|
26188
|
+
void finish(null);
|
|
26189
|
+
});
|
|
26190
|
+
child.stderr.resume();
|
|
26191
|
+
child.on("error", () => {
|
|
26192
|
+
void finish(null);
|
|
26193
|
+
});
|
|
26194
|
+
child.on("close", () => {
|
|
26195
|
+
void finish(null);
|
|
26196
|
+
});
|
|
26197
|
+
child.stdout.setEncoding("utf8");
|
|
26198
|
+
child.stdout.on("data", (chunk) => {
|
|
26199
|
+
if (finishing) return;
|
|
26200
|
+
outputBytes += Buffer.byteLength(chunk);
|
|
26201
|
+
if (outputBytes > MAX_OUTPUT3) {
|
|
26202
|
+
void finish(null);
|
|
26203
|
+
return;
|
|
26204
|
+
}
|
|
26205
|
+
buffer += chunk;
|
|
26206
|
+
let newline;
|
|
26207
|
+
while (!finishing && (newline = buffer.indexOf("\n")) !== -1) {
|
|
26208
|
+
const line = buffer.slice(0, newline);
|
|
26209
|
+
buffer = buffer.slice(newline + 1);
|
|
26210
|
+
if (!line.trim()) continue;
|
|
26211
|
+
let message2;
|
|
26212
|
+
try {
|
|
26213
|
+
message2 = JSON.parse(line);
|
|
26214
|
+
} catch {
|
|
26215
|
+
void finish(null);
|
|
26216
|
+
return;
|
|
26217
|
+
}
|
|
26218
|
+
if (!initialized && message2?.id === 1) {
|
|
26219
|
+
if (message2.error || !message2.result) {
|
|
26220
|
+
void finish(null);
|
|
26221
|
+
return;
|
|
26222
|
+
}
|
|
26223
|
+
initialized = true;
|
|
26224
|
+
send({ method: "initialized", params: {} });
|
|
26225
|
+
send({ id: 2, method: "account/read", params: { refreshToken: false } });
|
|
26226
|
+
} else if (initialized && message2?.id === 2) {
|
|
26227
|
+
const account = message2.error ? null : message2.result?.account;
|
|
26228
|
+
const email3 = account?.type === "chatgpt" ? account.email : null;
|
|
26229
|
+
void finish(typeof email3 === "string" && email3.length <= 254 && EMAIL.test(email3) && !/[\p{Cc}\p{Cf}]/u.test(email3) ? email3 : null);
|
|
26230
|
+
}
|
|
26231
|
+
}
|
|
26232
|
+
});
|
|
26233
|
+
send({ id: 1, method: "initialize", params: { clientInfo: { name: "openmausbot", version: "1" } } });
|
|
26234
|
+
});
|
|
26235
|
+
}
|
|
26236
|
+
var MAX_OUTPUT3, EMAIL;
|
|
26237
|
+
var init_codex_identity = __esm({
|
|
26238
|
+
"server/drivers/codex-identity.ts"() {
|
|
26239
|
+
"use strict";
|
|
26240
|
+
init_env_path();
|
|
26241
|
+
init_procs();
|
|
26242
|
+
MAX_OUTPUT3 = 16384;
|
|
26243
|
+
EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
26244
|
+
}
|
|
26245
|
+
});
|
|
26246
|
+
|
|
26052
26247
|
// server/drivers/codex-catalog.ts
|
|
26053
26248
|
import { readdirSync as readdirSync2, readFileSync as readFileSync10 } from "node:fs";
|
|
26054
|
-
import { homedir as
|
|
26055
|
-
import { basename as basename7, join as
|
|
26249
|
+
import { homedir as homedir12 } from "node:os";
|
|
26250
|
+
import { basename as basename7, join as join24 } from "node:path";
|
|
26056
26251
|
function encodeCodexSelection(provider, model) {
|
|
26057
26252
|
return `${provider}${SEP}${model}`;
|
|
26058
26253
|
}
|
|
@@ -26067,7 +26262,7 @@ function decodeCodexSelection(id) {
|
|
|
26067
26262
|
function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
|
|
26068
26263
|
return new Promise((resolve12) => {
|
|
26069
26264
|
const child = spawnCli(cli, ["app-server"], {
|
|
26070
|
-
cwd:
|
|
26265
|
+
cwd: homedir12(),
|
|
26071
26266
|
env,
|
|
26072
26267
|
stdio: ["pipe", "pipe", "pipe"]
|
|
26073
26268
|
});
|
|
@@ -26166,10 +26361,6 @@ function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
|
|
|
26166
26361
|
request("initialize", { clientInfo: { name: "openmausbot", version: "1" } }, "initialize");
|
|
26167
26362
|
});
|
|
26168
26363
|
}
|
|
26169
|
-
function codexHome(env) {
|
|
26170
|
-
if (env.CODEX_HOME) return env.CODEX_HOME;
|
|
26171
|
-
return join23(env.HOME || env.USERPROFILE || homedir11(), ".codex");
|
|
26172
|
-
}
|
|
26173
26364
|
function unquote(raw) {
|
|
26174
26365
|
let value = raw.trim();
|
|
26175
26366
|
const hash2 = value.indexOf(" #");
|
|
@@ -26250,15 +26441,18 @@ function niceLabel(model, provider, known, named) {
|
|
|
26250
26441
|
const encoded = encodeCodexSelection(provider, model);
|
|
26251
26442
|
if (named.has(encoded)) return named.get(encoded);
|
|
26252
26443
|
const host = providerName(provider, known);
|
|
26253
|
-
return
|
|
26444
|
+
return qualifiedModelLabel(model, host, {
|
|
26445
|
+
redundantWhen: () => host === provider,
|
|
26446
|
+
decorate: (facet) => ` (${facet})`
|
|
26447
|
+
});
|
|
26254
26448
|
}
|
|
26255
26449
|
function collectCatalogNames(home) {
|
|
26256
26450
|
const named = /* @__PURE__ */ new Map();
|
|
26257
|
-
for (const file2 of listDir(
|
|
26451
|
+
for (const file2 of listDir(join24(home, "model-catalogs"))) {
|
|
26258
26452
|
if (!file2.endsWith(".json")) continue;
|
|
26259
26453
|
const provider = basename7(file2, ".json").replace(/-models$/, "");
|
|
26260
26454
|
if (!PROVIDER_ID.test(provider)) continue;
|
|
26261
|
-
const raw = readText(
|
|
26455
|
+
const raw = readText(join24(home, "model-catalogs", file2));
|
|
26262
26456
|
if (!raw) continue;
|
|
26263
26457
|
let parsed;
|
|
26264
26458
|
try {
|
|
@@ -26310,7 +26504,8 @@ async function probeProviderModels(provider, env, fetchImpl) {
|
|
|
26310
26504
|
async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli) {
|
|
26311
26505
|
const official = (cli ? await readCodexAppServerModelCatalog(cli, env) : null) ?? STATIC_CODEX_MODELS;
|
|
26312
26506
|
const home = codexHome(env);
|
|
26313
|
-
|
|
26507
|
+
if (!home) return mergeLocalInject(official, env, fetchImpl);
|
|
26508
|
+
const mainText = readText(join24(home, "config.toml"));
|
|
26314
26509
|
if (!mainText) return mergeLocalInject(official, env, fetchImpl);
|
|
26315
26510
|
const main2 = parseCodexToml(mainText);
|
|
26316
26511
|
const known = new Map(main2.providers.map((provider) => [provider.id, provider]));
|
|
@@ -26325,7 +26520,7 @@ async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli)
|
|
|
26325
26520
|
remember(main2.modelProvider, main2.model);
|
|
26326
26521
|
for (const file2 of listDir(home)) {
|
|
26327
26522
|
if (!file2.endsWith(".config.toml")) continue;
|
|
26328
|
-
const profile = parseCodexToml(readText(
|
|
26523
|
+
const profile = parseCodexToml(readText(join24(home, file2)) ?? "");
|
|
26329
26524
|
for (const provider of profile.providers) {
|
|
26330
26525
|
if (!known.has(provider.id)) known.set(provider.id, provider);
|
|
26331
26526
|
}
|
|
@@ -26368,11 +26563,17 @@ var STATIC_CODEX_MODELS, OFFICIAL_CODEX_PROVIDER, SEP, MODEL_ID2, PROVIDER_ID;
|
|
|
26368
26563
|
var init_codex_catalog = __esm({
|
|
26369
26564
|
"server/drivers/codex-catalog.ts"() {
|
|
26370
26565
|
"use strict";
|
|
26566
|
+
init_contracts();
|
|
26371
26567
|
init_procs();
|
|
26568
|
+
init_codex_identity();
|
|
26372
26569
|
init_local_inject();
|
|
26373
26570
|
STATIC_CODEX_MODELS = {
|
|
26374
26571
|
default: "gpt-5.6-sol",
|
|
26375
26572
|
options: [
|
|
26573
|
+
// Only used when live discovery fails; these rows do not establish account access.
|
|
26574
|
+
{ id: "gpt-6-astra", label: "GPT-6 Astra (availability unverified)" },
|
|
26575
|
+
{ id: "gpt-6-sol", label: "GPT-6 Sol (availability unverified)" },
|
|
26576
|
+
{ id: "gpt-6-luna", label: "GPT-6 Luna (availability unverified)" },
|
|
26376
26577
|
{ id: "gpt-5.6-sol", label: "GPT-5.6 Sol" },
|
|
26377
26578
|
{ id: "gpt-5.6-terra", label: "GPT-5.6 Terra" },
|
|
26378
26579
|
{ id: "gpt-5.6-luna", label: "GPT-5.6 Luna" },
|
|
@@ -26392,7 +26593,7 @@ var init_codex_catalog = __esm({
|
|
|
26392
26593
|
// server/drivers/codex-instructions.ts
|
|
26393
26594
|
import { createHash as createHash8 } from "node:crypto";
|
|
26394
26595
|
import { mkdirSync as mkdirSync11, readFileSync as readFileSync11 } from "node:fs";
|
|
26395
|
-
import { join as
|
|
26596
|
+
import { join as join25 } from "node:path";
|
|
26396
26597
|
function parseReceipt(raw) {
|
|
26397
26598
|
if (!raw) return null;
|
|
26398
26599
|
const trimmed = raw.trim();
|
|
@@ -26425,8 +26626,8 @@ function codexDeveloperInstructions(config2, botInstructions) {
|
|
|
26425
26626
|
${configured}` : botInstructions;
|
|
26426
26627
|
}
|
|
26427
26628
|
async function syncCodexInstructions(key, nativeThreadId, instructions, volatile, resumed, request, mentionTurn = false) {
|
|
26428
|
-
const directory =
|
|
26429
|
-
const path3 =
|
|
26629
|
+
const directory = join25(DATA_DIR, "codex-instructions");
|
|
26630
|
+
const path3 = join25(directory, `${digest2(JSON.stringify([key, nativeThreadId]))}.sha256`);
|
|
26430
26631
|
const fingerprint = digest2(instructions);
|
|
26431
26632
|
const volatileFingerprint = digest2(volatile);
|
|
26432
26633
|
let previous;
|
|
@@ -26482,15 +26683,15 @@ var init_codex_instructions = __esm({
|
|
|
26482
26683
|
// server/drivers/codex-device-auth.ts
|
|
26483
26684
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
26484
26685
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
26485
|
-
import { homedir as
|
|
26486
|
-
import { basename as basename8, dirname as dirname10, isAbsolute as
|
|
26686
|
+
import { homedir as homedir13 } from "node:os";
|
|
26687
|
+
import { basename as basename8, dirname as dirname10, isAbsolute as isAbsolute7, join as join26, resolve as resolve8 } from "node:path";
|
|
26487
26688
|
import { stripVTControlCharacters as stripVTControlCharacters5 } from "node:util";
|
|
26488
26689
|
function canonicalPath2(path3) {
|
|
26489
26690
|
try {
|
|
26490
26691
|
return realpathSync3(path3);
|
|
26491
26692
|
} catch {
|
|
26492
26693
|
const parent = dirname10(path3);
|
|
26493
|
-
return parent === path3 ? path3 :
|
|
26694
|
+
return parent === path3 ? path3 : join26(canonicalPath2(parent), basename8(path3));
|
|
26494
26695
|
}
|
|
26495
26696
|
}
|
|
26496
26697
|
function codexDevicePrompt(output) {
|
|
@@ -26512,13 +26713,13 @@ function loginFailure(output) {
|
|
|
26512
26713
|
}
|
|
26513
26714
|
return "ChatGPT sign-in did not finish. Check the server's connection and that device-code login is enabled in ChatGPT, then try again.";
|
|
26514
26715
|
}
|
|
26515
|
-
var DEVICE_URL,
|
|
26716
|
+
var DEVICE_URL, MAX_OUTPUT4, authenticatingHomes2, CodexDeviceAuthController;
|
|
26516
26717
|
var init_codex_device_auth = __esm({
|
|
26517
26718
|
"server/drivers/codex-device-auth.ts"() {
|
|
26518
26719
|
"use strict";
|
|
26519
26720
|
init_procs();
|
|
26520
26721
|
DEVICE_URL = "https://auth.openai.com/codex/device";
|
|
26521
|
-
|
|
26722
|
+
MAX_OUTPUT4 = 16384;
|
|
26522
26723
|
authenticatingHomes2 = /* @__PURE__ */ new Set();
|
|
26523
26724
|
CodexDeviceAuthController = class {
|
|
26524
26725
|
flow = null;
|
|
@@ -26537,11 +26738,11 @@ var init_codex_device_auth = __esm({
|
|
|
26537
26738
|
await this.flow?.stopping;
|
|
26538
26739
|
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
26539
26740
|
const env = this.options.environment();
|
|
26540
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
26541
|
-
if (!
|
|
26741
|
+
const home = env.HOME || env.USERPROFILE || homedir13();
|
|
26742
|
+
if (!isAbsolute7(home) || env.CODEX_HOME && !isAbsolute7(env.CODEX_HOME)) {
|
|
26542
26743
|
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing in.");
|
|
26543
26744
|
}
|
|
26544
|
-
const homeKey = canonicalPath2(
|
|
26745
|
+
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join26(home, ".codex")));
|
|
26545
26746
|
if (authenticatingHomes2.has(homeKey)) {
|
|
26546
26747
|
throw new Error("A ChatGPT sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
26547
26748
|
}
|
|
@@ -26616,11 +26817,11 @@ var init_codex_device_auth = __esm({
|
|
|
26616
26817
|
await this.flow?.stopping;
|
|
26617
26818
|
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
26618
26819
|
const env = this.options.environment();
|
|
26619
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
26620
|
-
if (!
|
|
26820
|
+
const home = env.HOME || env.USERPROFILE || homedir13();
|
|
26821
|
+
if (!isAbsolute7(home) || env.CODEX_HOME && !isAbsolute7(env.CODEX_HOME)) {
|
|
26621
26822
|
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing out.");
|
|
26622
26823
|
}
|
|
26623
|
-
const homeKey = canonicalPath2(
|
|
26824
|
+
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join26(home, ".codex")));
|
|
26624
26825
|
if (authenticatingHomes2.has(homeKey)) {
|
|
26625
26826
|
throw new Error("A ChatGPT sign-in is running for this server account. Finish or cancel it before signing out.");
|
|
26626
26827
|
}
|
|
@@ -26663,7 +26864,7 @@ var init_codex_device_auth = __esm({
|
|
|
26663
26864
|
child.stdin.end();
|
|
26664
26865
|
let output = "";
|
|
26665
26866
|
const receive = (chunk) => {
|
|
26666
|
-
if (output.length <
|
|
26867
|
+
if (output.length < MAX_OUTPUT4) output += chunk.toString("utf8").slice(0, MAX_OUTPUT4 - output.length);
|
|
26667
26868
|
};
|
|
26668
26869
|
child.stdout.on("data", receive);
|
|
26669
26870
|
child.stderr.on("data", receive);
|
|
@@ -26698,7 +26899,7 @@ var init_codex_device_auth = __esm({
|
|
|
26698
26899
|
let output = "";
|
|
26699
26900
|
const receive = (chunk) => {
|
|
26700
26901
|
if (flow.status.phase !== "waiting") return;
|
|
26701
|
-
if (output.length + chunk.length >
|
|
26902
|
+
if (output.length + chunk.length > MAX_OUTPUT4) {
|
|
26702
26903
|
this.finish(flow, "failed", "Codex returned an unexpected sign-in response. Update the server's Codex CLI and try again.");
|
|
26703
26904
|
return;
|
|
26704
26905
|
}
|
|
@@ -26777,116 +26978,51 @@ var init_codex_device_auth = __esm({
|
|
|
26777
26978
|
}
|
|
26778
26979
|
});
|
|
26779
26980
|
|
|
26780
|
-
// server/drivers/codex-
|
|
26781
|
-
|
|
26782
|
-
|
|
26783
|
-
|
|
26784
|
-
if (env.CODEX_HOME) return isAbsolute7(env.CODEX_HOME) ? resolve8(env.CODEX_HOME) : null;
|
|
26785
|
-
const home = env.HOME || env.USERPROFILE || homedir13();
|
|
26786
|
-
return isAbsolute7(home) ? join26(home, ".codex") : null;
|
|
26981
|
+
// server/drivers/codex-release.ts
|
|
26982
|
+
function parseCodexReleaseVersion(value) {
|
|
26983
|
+
const match = /^(?:.*\bcodex-cli\s+)?v?(\d+)\.(\d+)\.(\d+)(-[0-9a-z.-]+)?(?:\+[0-9a-z.-]+)?$/i.exec(value.trim());
|
|
26984
|
+
return match ? { parts: match.slice(1, 4).map(Number), prerelease: Boolean(match[4]) } : null;
|
|
26787
26985
|
}
|
|
26788
|
-
|
|
26789
|
-
const
|
|
26790
|
-
|
|
26791
|
-
|
|
26792
|
-
|
|
26793
|
-
|
|
26794
|
-
|
|
26795
|
-
|
|
26796
|
-
|
|
26797
|
-
|
|
26798
|
-
|
|
26799
|
-
|
|
26800
|
-
|
|
26801
|
-
|
|
26802
|
-
|
|
26803
|
-
|
|
26804
|
-
if (finishing) return;
|
|
26805
|
-
finishing = true;
|
|
26806
|
-
clearTimeout(timer);
|
|
26807
|
-
let stopped = await killCliTree(child, 1e3);
|
|
26808
|
-
if (!stopped && child.pid) {
|
|
26809
|
-
try {
|
|
26810
|
-
if (process.platform === "win32") child.kill("SIGKILL");
|
|
26811
|
-
else process.kill(-child.pid, "SIGKILL");
|
|
26812
|
-
} catch {
|
|
26813
|
-
try {
|
|
26814
|
-
child.kill("SIGKILL");
|
|
26815
|
-
} catch {
|
|
26816
|
-
}
|
|
26817
|
-
}
|
|
26818
|
-
stopped = await killCliTree(child, 1e3);
|
|
26819
|
-
}
|
|
26820
|
-
resolveEmail(stopped ? email3 : null);
|
|
26821
|
-
};
|
|
26822
|
-
const timer = setTimeout(() => {
|
|
26823
|
-
void finish(null);
|
|
26824
|
-
}, timeoutMs);
|
|
26825
|
-
timer.unref();
|
|
26826
|
-
const send = (message2) => {
|
|
26986
|
+
function codexVersionBehind(installed, latest) {
|
|
26987
|
+
const a2 = parseCodexReleaseVersion(installed);
|
|
26988
|
+
const b2 = parseCodexReleaseVersion(latest);
|
|
26989
|
+
if (!a2 || !b2 || b2.prerelease) return false;
|
|
26990
|
+
for (let i2 = 0; i2 < 3; i2++) {
|
|
26991
|
+
if (a2.parts[i2] !== b2.parts[i2]) return a2.parts[i2] < b2.parts[i2];
|
|
26992
|
+
}
|
|
26993
|
+
return a2.prerelease;
|
|
26994
|
+
}
|
|
26995
|
+
function createCodexReleaseReader(fetchImpl = fetch, now = Date.now) {
|
|
26996
|
+
let cached3;
|
|
26997
|
+
let expires = 0;
|
|
26998
|
+
return () => {
|
|
26999
|
+
if (cached3 && now() < expires) return cached3;
|
|
27000
|
+
expires = now() + 60 * 60 * 1e3;
|
|
27001
|
+
cached3 = (async () => {
|
|
26827
27002
|
try {
|
|
26828
|
-
|
|
26829
|
-
|
|
27003
|
+
const response = await fetchImpl("https://registry.npmjs.org/@openai/codex/latest", {
|
|
27004
|
+
signal: AbortSignal.timeout(3e3),
|
|
27005
|
+
headers: { Accept: "application/json" }
|
|
27006
|
+
});
|
|
27007
|
+
if (!response.ok) throw new Error("Release lookup failed");
|
|
27008
|
+
const payload = await response.json();
|
|
27009
|
+
const version2 = typeof payload.version === "string" ? payload.version : "";
|
|
27010
|
+
const parsed = parseCodexReleaseVersion(version2);
|
|
27011
|
+
if (!parsed || parsed.prerelease) throw new Error("Invalid stable release");
|
|
27012
|
+
return version2;
|
|
26830
27013
|
} catch {
|
|
26831
|
-
|
|
26832
|
-
|
|
26833
|
-
};
|
|
26834
|
-
child.stdin.on("error", () => {
|
|
26835
|
-
void finish(null);
|
|
26836
|
-
});
|
|
26837
|
-
child.stderr.resume();
|
|
26838
|
-
child.on("error", () => {
|
|
26839
|
-
void finish(null);
|
|
26840
|
-
});
|
|
26841
|
-
child.on("close", () => {
|
|
26842
|
-
void finish(null);
|
|
26843
|
-
});
|
|
26844
|
-
child.stdout.setEncoding("utf8");
|
|
26845
|
-
child.stdout.on("data", (chunk) => {
|
|
26846
|
-
if (finishing) return;
|
|
26847
|
-
outputBytes += Buffer.byteLength(chunk);
|
|
26848
|
-
if (outputBytes > MAX_OUTPUT4) {
|
|
26849
|
-
void finish(null);
|
|
26850
|
-
return;
|
|
26851
|
-
}
|
|
26852
|
-
buffer += chunk;
|
|
26853
|
-
let newline;
|
|
26854
|
-
while (!finishing && (newline = buffer.indexOf("\n")) !== -1) {
|
|
26855
|
-
const line = buffer.slice(0, newline);
|
|
26856
|
-
buffer = buffer.slice(newline + 1);
|
|
26857
|
-
if (!line.trim()) continue;
|
|
26858
|
-
let message2;
|
|
26859
|
-
try {
|
|
26860
|
-
message2 = JSON.parse(line);
|
|
26861
|
-
} catch {
|
|
26862
|
-
void finish(null);
|
|
26863
|
-
return;
|
|
26864
|
-
}
|
|
26865
|
-
if (!initialized && message2?.id === 1) {
|
|
26866
|
-
if (message2.error || !message2.result) {
|
|
26867
|
-
void finish(null);
|
|
26868
|
-
return;
|
|
26869
|
-
}
|
|
26870
|
-
initialized = true;
|
|
26871
|
-
send({ method: "initialized", params: {} });
|
|
26872
|
-
send({ id: 2, method: "account/read", params: { refreshToken: false } });
|
|
26873
|
-
} else if (initialized && message2?.id === 2) {
|
|
26874
|
-
const account = message2.error ? null : message2.result?.account;
|
|
26875
|
-
const email3 = account?.type === "chatgpt" ? account.email : null;
|
|
26876
|
-
void finish(typeof email3 === "string" && email3.length <= 254 && EMAIL.test(email3) && !/[\p{Cc}\p{Cf}]/u.test(email3) ? email3 : null);
|
|
26877
|
-
}
|
|
27014
|
+
expires = now() + 5 * 60 * 1e3;
|
|
27015
|
+
return null;
|
|
26878
27016
|
}
|
|
26879
|
-
});
|
|
26880
|
-
|
|
26881
|
-
}
|
|
27017
|
+
})();
|
|
27018
|
+
return cached3;
|
|
27019
|
+
};
|
|
26882
27020
|
}
|
|
26883
|
-
var
|
|
26884
|
-
var
|
|
26885
|
-
"server/drivers/codex-
|
|
27021
|
+
var readLatestCodexRelease;
|
|
27022
|
+
var init_codex_release = __esm({
|
|
27023
|
+
"server/drivers/codex-release.ts"() {
|
|
26886
27024
|
"use strict";
|
|
26887
|
-
|
|
26888
|
-
MAX_OUTPUT4 = 16384;
|
|
26889
|
-
EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
27025
|
+
readLatestCodexRelease = createCodexReleaseReader();
|
|
26890
27026
|
}
|
|
26891
27027
|
});
|
|
26892
27028
|
|
|
@@ -26896,18 +27032,6 @@ import { homedir as homedir14 } from "node:os";
|
|
|
26896
27032
|
function missingNativeCodexThread(error51, cursor3) {
|
|
26897
27033
|
return error51 instanceof CodexRpcError && error51.code === -32600 && error51.message === `no rollout found for thread id ${cursor3}`;
|
|
26898
27034
|
}
|
|
26899
|
-
function codexPredatesAstra(version2) {
|
|
26900
|
-
const value = version2.trim();
|
|
26901
|
-
const match = /\bcodex-cli\s+v?(\d+)\.(\d+)\.(\d+)(?:[-+][0-9a-z.-]+)?(?![\d.])\b/i.exec(value) ?? /^v?(\d+)\.(\d+)\.(\d+)(?:[-+][0-9a-z.-]+)?$/i.exec(value);
|
|
26902
|
-
if (!match) return false;
|
|
26903
|
-
const installed = match.slice(1, 4).map(Number);
|
|
26904
|
-
for (let i2 = 0; i2 < ASTRA_MIN_CODEX_VERSION.length; i2 += 1) {
|
|
26905
|
-
if (installed[i2] !== ASTRA_MIN_CODEX_VERSION[i2]) {
|
|
26906
|
-
return installed[i2] < ASTRA_MIN_CODEX_VERSION[i2];
|
|
26907
|
-
}
|
|
26908
|
-
}
|
|
26909
|
-
return false;
|
|
26910
|
-
}
|
|
26911
27035
|
function codexUpdateCommand(cli, platform = process.platform) {
|
|
26912
27036
|
if (cli === "codex") return "codex update";
|
|
26913
27037
|
const trimmed = cli.trim();
|
|
@@ -26916,13 +27040,12 @@ function codexUpdateCommand(cli, platform = process.platform) {
|
|
|
26916
27040
|
const command = (tokens.length > 0 ? tokens : [trimmed]).map(quote2).join(" ");
|
|
26917
27041
|
return platform === "win32" ? `& ${command} update` : `${command} update`;
|
|
26918
27042
|
}
|
|
26919
|
-
function
|
|
26920
|
-
|
|
26921
|
-
|
|
26922
|
-
}
|
|
27043
|
+
async function codexReleaseUpdate(version2, cli) {
|
|
27044
|
+
const latest = await readLatestCodexRelease();
|
|
27045
|
+
if (!latest || !codexVersionBehind(version2, latest)) return void 0;
|
|
26923
27046
|
return {
|
|
26924
|
-
title:
|
|
26925
|
-
message:
|
|
27047
|
+
title: `Update Codex to ${latest}`,
|
|
27048
|
+
message: `A newer stable Codex CLI is available (installed: ${version2}). Update it, then refresh models. Model availability also depends on your signed-in account.`,
|
|
26926
27049
|
command: codexUpdateCommand(cli)
|
|
26927
27050
|
};
|
|
26928
27051
|
}
|
|
@@ -27224,7 +27347,7 @@ function mountMcpServer(appServerArgs, env, name, server, preApproved = true) {
|
|
|
27224
27347
|
appServerArgs.push("-c", `${prefix}.default_tools_approval_mode="auto"`);
|
|
27225
27348
|
}
|
|
27226
27349
|
}
|
|
27227
|
-
var DRIVER_KIND3,
|
|
27350
|
+
var DRIVER_KIND3, CodexRpcError, DENY_TIMEOUT_NOTE2, skippedSseServers, renamedMcpServers, plainRecord, containsControlCharacter, CodexDriver;
|
|
27228
27351
|
var init_codex = __esm({
|
|
27229
27352
|
"server/drivers/codex.ts"() {
|
|
27230
27353
|
"use strict";
|
|
@@ -27248,10 +27371,9 @@ var init_codex = __esm({
|
|
|
27248
27371
|
init_resume_recovery();
|
|
27249
27372
|
init_mcp_tool_images();
|
|
27250
27373
|
init_ask_question();
|
|
27374
|
+
init_codex_release();
|
|
27251
27375
|
init_codex_catalog();
|
|
27252
27376
|
DRIVER_KIND3 = "codex";
|
|
27253
|
-
ASTRA_MODEL_ID = "gpt-6-astra";
|
|
27254
|
-
ASTRA_MIN_CODEX_VERSION = [0, 153, 1];
|
|
27255
27377
|
CodexRpcError = class extends Error {
|
|
27256
27378
|
code;
|
|
27257
27379
|
constructor(error51) {
|
|
@@ -28090,7 +28212,7 @@ ${stderr ?? ""}`))
|
|
|
28090
28212
|
version: version2,
|
|
28091
28213
|
authenticated,
|
|
28092
28214
|
...email3 ? { account: { email: email3 } } : {},
|
|
28093
|
-
update:
|
|
28215
|
+
update: await codexReleaseUpdate(version2, config2.cli),
|
|
28094
28216
|
billing: "subscription"
|
|
28095
28217
|
};
|
|
28096
28218
|
};
|
|
@@ -37738,7 +37860,8 @@ function createOpenAIChatRuntime(options) {
|
|
|
37738
37860
|
const done = new Promise((resolve12) => {
|
|
37739
37861
|
resolveDone = resolve12;
|
|
37740
37862
|
});
|
|
37741
|
-
|
|
37863
|
+
const turnEntry = { abort, turnId, done, approval, asides: [] };
|
|
37864
|
+
active.set(turn.threadId, turnEntry);
|
|
37742
37865
|
emit({ ...base2(turn.threadId, turnId), type: "turn.started" });
|
|
37743
37866
|
emit({ ...base2(turn.threadId, turnId), type: "session.started", sessionId: null, model });
|
|
37744
37867
|
void (async () => {
|
|
@@ -37759,6 +37882,8 @@ function createOpenAIChatRuntime(options) {
|
|
|
37759
37882
|
}
|
|
37760
37883
|
for (let round = 0; round < 16; round++) {
|
|
37761
37884
|
abort.signal.throwIfAborted();
|
|
37885
|
+
const parked = turnEntry.asides.splice(0);
|
|
37886
|
+
if (parked.length) messages.push({ role: "user", content: parked.join("\n\n") });
|
|
37762
37887
|
native("out", options.nativeLog.outgoing(turn, messages, model));
|
|
37763
37888
|
let attempt = 0;
|
|
37764
37889
|
let completion;
|
|
@@ -37984,7 +38109,10 @@ function createOpenAIChatRuntime(options) {
|
|
|
37984
38109
|
sessionModelSwitch: "in-session",
|
|
37985
38110
|
customMcp: options.tools !== false,
|
|
37986
38111
|
agentsMcp: options.tools !== false,
|
|
37987
|
-
composioMcp: options.tools !== false
|
|
38112
|
+
composioMcp: options.tools !== false,
|
|
38113
|
+
// The runtime owns the whole tool loop, so it can always take a
|
|
38114
|
+
// user message mid-turn: park it, deliver before the next completion.
|
|
38115
|
+
queueing: true
|
|
37988
38116
|
},
|
|
37989
38117
|
sendTurn,
|
|
37990
38118
|
interruptTurn: async (threadId, turnId) => {
|
|
@@ -37994,6 +38122,12 @@ function createOpenAIChatRuntime(options) {
|
|
|
37994
38122
|
await turn.done;
|
|
37995
38123
|
},
|
|
37996
38124
|
respondToRequest: async (threadId, requestId, decision) => active.get(threadId)?.approval.answer(requestId, decision.behavior, decision.message) ?? "unavailable",
|
|
38125
|
+
steer: async (threadId, text4) => {
|
|
38126
|
+
const running2 = active.get(threadId);
|
|
38127
|
+
if (!running2) return "refused";
|
|
38128
|
+
running2.asides.push(text4);
|
|
38129
|
+
return "steered";
|
|
38130
|
+
},
|
|
37997
38131
|
hasSession: (threadId) => active.has(threadId),
|
|
37998
38132
|
stopAll: async () => {
|
|
37999
38133
|
const turns = [...active.values()];
|
|
@@ -38103,12 +38237,7 @@ var init_grok = __esm({
|
|
|
38103
38237
|
|
|
38104
38238
|
// server/drivers/acp/grok.ts
|
|
38105
38239
|
import { existsSync as existsSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync9 } from "node:fs";
|
|
38106
|
-
import { homedir as homedir15 } from "node:os";
|
|
38107
38240
|
import { join as join30 } from "node:path";
|
|
38108
|
-
function grokHome(env) {
|
|
38109
|
-
if (env.GROK_HOME) return env.GROK_HOME;
|
|
38110
|
-
return join30(env.HOME || env.USERPROFILE || homedir15(), ".grok");
|
|
38111
|
-
}
|
|
38112
38241
|
function unquote2(raw) {
|
|
38113
38242
|
const value = raw.trim();
|
|
38114
38243
|
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
@@ -38117,7 +38246,7 @@ function unquote2(raw) {
|
|
|
38117
38246
|
return value;
|
|
38118
38247
|
}
|
|
38119
38248
|
function readGrokModelCatalog(env = process.env) {
|
|
38120
|
-
const path3 = join30(
|
|
38249
|
+
const path3 = join30(env.GROK_HOME || harnessHome("grok", env), "config.toml");
|
|
38121
38250
|
let text4 = "";
|
|
38122
38251
|
try {
|
|
38123
38252
|
text4 = readFileSync16(path3, "utf8");
|
|
@@ -38190,7 +38319,7 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
38190
38319
|
if (!inject) return modelId;
|
|
38191
38320
|
const host = localHost(inject.host);
|
|
38192
38321
|
if (!host) return modelId;
|
|
38193
|
-
const path3 = join30(
|
|
38322
|
+
const path3 = join30(env.GROK_HOME || harnessHome("grok", env), "config.toml");
|
|
38194
38323
|
let text4 = "";
|
|
38195
38324
|
try {
|
|
38196
38325
|
text4 = readFileSync16(path3, "utf8");
|
|
@@ -38257,6 +38386,7 @@ var STATIC_GROK_MODELS, SLUG, support2, GrokAgentDriver;
|
|
|
38257
38386
|
var init_grok2 = __esm({
|
|
38258
38387
|
"server/drivers/acp/grok.ts"() {
|
|
38259
38388
|
"use strict";
|
|
38389
|
+
init_env_path();
|
|
38260
38390
|
init_local_inject();
|
|
38261
38391
|
init_core3();
|
|
38262
38392
|
STATIC_GROK_MODELS = {
|
|
@@ -38337,7 +38467,7 @@ var init_grok2 = __esm({
|
|
|
38337
38467
|
// an unauthenticated CLI is a user action, not something to paper over.
|
|
38338
38468
|
pickAuthMethod: (methods) => methods.some((m2) => m2.id === "cached_token") ? "cached_token" : null,
|
|
38339
38469
|
authFailure: "fail",
|
|
38340
|
-
isAuthenticated: () => existsSync11(join30(
|
|
38470
|
+
isAuthenticated: (env) => existsSync11(join30(harnessHome("grok", env), "auth.json")),
|
|
38341
38471
|
// `--append-system-prompt`/`--rules` are accepted by the CLI but do NOT
|
|
38342
38472
|
// reach the agent-stdio system prompt (verified against 1.0.0), so the
|
|
38343
38473
|
// persona is prepended codex-style.
|
|
@@ -38351,11 +38481,10 @@ ${turn.text}` : turn.text
|
|
|
38351
38481
|
|
|
38352
38482
|
// server/drivers/acp/gemini.ts
|
|
38353
38483
|
import { existsSync as existsSync12, readFileSync as readFileSync17 } from "node:fs";
|
|
38354
|
-
import { homedir as homedir16 } from "node:os";
|
|
38355
38484
|
import { join as join31 } from "node:path";
|
|
38356
|
-
function liveOauthCredential() {
|
|
38485
|
+
function liveOauthCredential(env) {
|
|
38357
38486
|
try {
|
|
38358
|
-
const creds = JSON.parse(readFileSync17(join31(
|
|
38487
|
+
const creds = JSON.parse(readFileSync17(join31(userHome(env), ".gemini", "oauth_creds.json"), "utf8"));
|
|
38359
38488
|
if (typeof creds.access_token !== "string" || creds.access_token.trim().length === 0) return false;
|
|
38360
38489
|
const hasRefresh = typeof creds.refresh_token === "string" && creds.refresh_token.trim().length > 0;
|
|
38361
38490
|
if (creds.expiry_date !== void 0) {
|
|
@@ -38368,7 +38497,7 @@ function liveOauthCredential() {
|
|
|
38368
38497
|
}
|
|
38369
38498
|
}
|
|
38370
38499
|
function geminiIsAuthenticated(env) {
|
|
38371
|
-
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) || existsSync12(join31(
|
|
38500
|
+
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) || existsSync12(join31(userHome(env), ".gemini", "oauth_creds.json")) && liveOauthCredential(env);
|
|
38372
38501
|
}
|
|
38373
38502
|
function geminiApprovalArgs(fullAuto, approvalMode) {
|
|
38374
38503
|
if (fullAuto) return ["--yolo"];
|
|
@@ -38379,6 +38508,7 @@ var AUTH_PREFERENCE, nonBlank, support3, GeminiAgentDriver;
|
|
|
38379
38508
|
var init_gemini = __esm({
|
|
38380
38509
|
"server/drivers/acp/gemini.ts"() {
|
|
38381
38510
|
"use strict";
|
|
38511
|
+
init_env_path();
|
|
38382
38512
|
init_core3();
|
|
38383
38513
|
AUTH_PREFERENCE = ["gemini-api-key", "oauth-personal", "vertex-ai"];
|
|
38384
38514
|
nonBlank = (value) => Boolean(value?.trim());
|
|
@@ -38416,13 +38546,13 @@ ${turn.text}` : turn.text
|
|
|
38416
38546
|
|
|
38417
38547
|
// server/drivers/acp/kimi.ts
|
|
38418
38548
|
import { existsSync as existsSync13, mkdirSync as mkdirSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync10 } from "node:fs";
|
|
38419
|
-
import { homedir as
|
|
38549
|
+
import { homedir as homedir15 } from "node:os";
|
|
38420
38550
|
import { join as join32 } from "node:path";
|
|
38421
38551
|
function isLocalInjectAlias(slug) {
|
|
38422
38552
|
return LOCAL_PROVIDER_PREFIXES.some((prefix) => slug.startsWith(prefix));
|
|
38423
38553
|
}
|
|
38424
38554
|
function kimiDataRoot(env) {
|
|
38425
|
-
return env.KIMI_CODE_HOME || join32(env.HOME || env.USERPROFILE ||
|
|
38555
|
+
return env.KIMI_CODE_HOME || join32(env.HOME || env.USERPROFILE || homedir15(), ".kimi-code");
|
|
38426
38556
|
}
|
|
38427
38557
|
function credentialsPath(env) {
|
|
38428
38558
|
return join32(kimiDataRoot(env), "credentials", "kimi-code.json");
|
|
@@ -38898,26 +39028,22 @@ ${turn.text}` : turn.text
|
|
|
38898
39028
|
|
|
38899
39029
|
// server/drivers/acp/droid.ts
|
|
38900
39030
|
import { existsSync as existsSync14, mkdirSync as mkdirSync16, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "node:fs";
|
|
38901
|
-
import { homedir as homedir18 } from "node:os";
|
|
38902
39031
|
import { join as join33 } from "node:path";
|
|
38903
39032
|
function authFilePaths(env) {
|
|
38904
|
-
const home = env.FACTORY_HOME_OVERRIDE || env
|
|
39033
|
+
const home = env.FACTORY_HOME_OVERRIDE || userHome(env);
|
|
38905
39034
|
return AUTH_FILES.map((name) => join33(home, ".factory", name));
|
|
38906
39035
|
}
|
|
38907
39036
|
function droidInjectId(host, model) {
|
|
38908
39037
|
const safe = `${host}-${model}`.replace(/[^a-zA-Z0-9._+-]+/g, "-").replace(/-+/g, "-");
|
|
38909
39038
|
return `${INJECT_ID_PREFIX}${safe}`;
|
|
38910
39039
|
}
|
|
38911
|
-
function factoryHome(env) {
|
|
38912
|
-
return env.FACTORY_HOME_OVERRIDE || env.HOME || env.USERPROFILE || homedir18();
|
|
38913
|
-
}
|
|
38914
39040
|
function ensureDroidInjectModel(modelId, env = process.env) {
|
|
38915
39041
|
const inject = decodeInjectId(modelId);
|
|
38916
39042
|
if (!inject) return modelId;
|
|
38917
39043
|
const host = localHost(inject.host);
|
|
38918
39044
|
if (!host) return modelId;
|
|
38919
39045
|
const id = droidInjectId(inject.host, inject.model);
|
|
38920
|
-
const dir = join33(
|
|
39046
|
+
const dir = join33(env.FACTORY_HOME_OVERRIDE || userHome(env), ".factory");
|
|
38921
39047
|
mkdirSync16(dir, { recursive: true });
|
|
38922
39048
|
const path3 = join33(dir, "settings.json");
|
|
38923
39049
|
let settings2 = {};
|
|
@@ -38959,7 +39085,7 @@ function applyDroidLocalAuthEnv(env, modelId) {
|
|
|
38959
39085
|
env.FACTORY_API_KEY = "openmausbot-local";
|
|
38960
39086
|
}
|
|
38961
39087
|
function readSettings(env) {
|
|
38962
|
-
return JSON.parse(readFileSync19(join33(
|
|
39088
|
+
return JSON.parse(readFileSync19(join33(env.FACTORY_HOME_OVERRIDE || userHome(env), ".factory", "settings.json"), "utf8"));
|
|
38963
39089
|
}
|
|
38964
39090
|
async function resolveModels(env) {
|
|
38965
39091
|
let catalog2 = MODELS3;
|
|
@@ -38997,6 +39123,7 @@ var AUTH_FILES, INJECT_ID_PREFIX, MODE_DEFAULT, MODE_FULL_AUTO, MODELS3, support
|
|
|
38997
39123
|
var init_droid = __esm({
|
|
38998
39124
|
"server/drivers/acp/droid.ts"() {
|
|
38999
39125
|
"use strict";
|
|
39126
|
+
init_env_path();
|
|
39000
39127
|
init_local_inject();
|
|
39001
39128
|
init_core3();
|
|
39002
39129
|
AUTH_FILES = ["auth.v2.file", "auth.v2.loginkeychain", "auth.v2.keyring"];
|
|
@@ -39110,8 +39237,8 @@ function asRecord(value) {
|
|
|
39110
39237
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
39111
39238
|
}
|
|
39112
39239
|
function labelFor(id, explicit) {
|
|
39113
|
-
|
|
39114
|
-
return id
|
|
39240
|
+
const trimmed = explicit?.trim();
|
|
39241
|
+
return trimmed || titleCaseModelId(id, /[-_./]+/);
|
|
39115
39242
|
}
|
|
39116
39243
|
function pushModel(options, seen, id, label, custom2 = false) {
|
|
39117
39244
|
if (!SLUG3.test(id) || seen.has(id)) return;
|
|
@@ -39277,6 +39404,7 @@ var STATIC_CURSOR_MODELS, SLUG3, EXEC_TIMEOUT_MS, nonBlank2, support6, CursorAge
|
|
|
39277
39404
|
var init_cursor = __esm({
|
|
39278
39405
|
"server/drivers/acp/cursor.ts"() {
|
|
39279
39406
|
"use strict";
|
|
39407
|
+
init_contracts();
|
|
39280
39408
|
init_procs();
|
|
39281
39409
|
init_core3();
|
|
39282
39410
|
STATIC_CURSOR_MODELS = {
|
|
@@ -39350,10 +39478,10 @@ ${turn.text}` : turn.text
|
|
|
39350
39478
|
|
|
39351
39479
|
// server/drivers/acp/opencode-go.ts
|
|
39352
39480
|
import { existsSync as existsSync15, mkdirSync as mkdirSync17, readFileSync as readFileSync20, writeFileSync as writeFileSync12 } from "node:fs";
|
|
39353
|
-
import { homedir as
|
|
39481
|
+
import { homedir as homedir16 } from "node:os";
|
|
39354
39482
|
import { join as join34 } from "node:path";
|
|
39355
39483
|
function labelForModel(id) {
|
|
39356
|
-
return id
|
|
39484
|
+
return titleCaseModelId(id, /[-_.]+/);
|
|
39357
39485
|
}
|
|
39358
39486
|
function providerLabel(id) {
|
|
39359
39487
|
if (id === "opencode") return "Zen";
|
|
@@ -39453,7 +39581,7 @@ async function discoverOpenCodeModels(environment, cli = "opencode") {
|
|
|
39453
39581
|
}
|
|
39454
39582
|
}
|
|
39455
39583
|
function opencodeConfigDir(env) {
|
|
39456
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
39584
|
+
const home = env.HOME || env.USERPROFILE || homedir16();
|
|
39457
39585
|
return join34(env.XDG_CONFIG_HOME || join34(home, ".config"), "opencode");
|
|
39458
39586
|
}
|
|
39459
39587
|
function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
@@ -39500,7 +39628,7 @@ function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
|
39500
39628
|
return native;
|
|
39501
39629
|
}
|
|
39502
39630
|
function storedAuthPaths(env) {
|
|
39503
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
39631
|
+
const home = env.HOME || env.USERPROFILE || homedir16();
|
|
39504
39632
|
const roots = [
|
|
39505
39633
|
env.XDG_DATA_HOME || join34(home, ".local", "share"),
|
|
39506
39634
|
process.platform === "darwin" ? join34(home, "Library", "Application Support") : process.platform === "win32" ? env.LOCALAPPDATA || join34(home, "AppData", "Local") : ""
|
|
@@ -39568,6 +39696,7 @@ var init_opencode_go = __esm({
|
|
|
39568
39696
|
"use strict";
|
|
39569
39697
|
init_local_inject();
|
|
39570
39698
|
init_core3();
|
|
39699
|
+
init_contracts();
|
|
39571
39700
|
init_procs();
|
|
39572
39701
|
STATIC_MODELS = {
|
|
39573
39702
|
default: "opencode/x-preview-f-free",
|
|
@@ -39660,23 +39789,14 @@ ${turn.text}` : turn.text
|
|
|
39660
39789
|
// server/drivers/acp/qwen.ts
|
|
39661
39790
|
import { chmodSync as chmodSync5, existsSync as existsSync16, mkdirSync as mkdirSync18, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "node:fs";
|
|
39662
39791
|
import { createHash as createHash12 } from "node:crypto";
|
|
39663
|
-
import { homedir as homedir20 } from "node:os";
|
|
39664
39792
|
import { join as join35 } from "node:path";
|
|
39665
|
-
function qwenHome(env) {
|
|
39666
|
-
const home = process.platform === "win32" ? env.USERPROFILE || env.HOME || homedir20() : env.HOME || env.USERPROFILE || homedir20();
|
|
39667
|
-
return join35(home, ".qwen");
|
|
39668
|
-
}
|
|
39669
39793
|
function isRecord3(value) {
|
|
39670
39794
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
39671
39795
|
}
|
|
39672
|
-
function qwenModelLabel(id, name) {
|
|
39673
|
-
if (!name || name.toLocaleLowerCase().endsWith(id.toLocaleLowerCase())) return id;
|
|
39674
|
-
return `${id} \u2014 ${name}`;
|
|
39675
|
-
}
|
|
39676
39796
|
function readQwenRoutes(env) {
|
|
39677
39797
|
let settings2;
|
|
39678
39798
|
try {
|
|
39679
|
-
settings2 = JSON.parse(readFileSync21(join35(
|
|
39799
|
+
settings2 = JSON.parse(readFileSync21(join35(harnessHome("qwen", env), "settings.json"), "utf8"));
|
|
39680
39800
|
} catch {
|
|
39681
39801
|
return [];
|
|
39682
39802
|
}
|
|
@@ -39744,7 +39864,9 @@ function readQwenRoutes(env) {
|
|
|
39744
39864
|
function readQwenModelCatalog(env = process.env) {
|
|
39745
39865
|
const options = readQwenRoutes(env).map(({ id, model, label, provider }) => ({
|
|
39746
39866
|
id,
|
|
39747
|
-
label:
|
|
39867
|
+
label: qualifiedModelLabel(model, label, {
|
|
39868
|
+
redundantWhen: (id2, name) => name.toLocaleLowerCase().endsWith(id2.toLocaleLowerCase())
|
|
39869
|
+
}),
|
|
39748
39870
|
custom: true,
|
|
39749
39871
|
provider
|
|
39750
39872
|
}));
|
|
@@ -39758,7 +39880,7 @@ function ensureQwenInjectModel(modelId, env = process.env) {
|
|
|
39758
39880
|
if (!inject) return modelId;
|
|
39759
39881
|
const host = localHost(inject.host);
|
|
39760
39882
|
if (!host) return modelId;
|
|
39761
|
-
const dir =
|
|
39883
|
+
const dir = harnessHome("qwen", env);
|
|
39762
39884
|
mkdirSync18(dir, { recursive: true });
|
|
39763
39885
|
const path3 = join35(dir, "settings.json");
|
|
39764
39886
|
let settings2 = {};
|
|
@@ -39840,6 +39962,8 @@ var EMPTY, PROTOCOLS, support8, QwenAgentDriver;
|
|
|
39840
39962
|
var init_qwen = __esm({
|
|
39841
39963
|
"server/drivers/acp/qwen.ts"() {
|
|
39842
39964
|
"use strict";
|
|
39965
|
+
init_contracts();
|
|
39966
|
+
init_env_path();
|
|
39843
39967
|
init_local_inject();
|
|
39844
39968
|
init_core3();
|
|
39845
39969
|
EMPTY = { default: "", options: [] };
|
|
@@ -46766,7 +46890,7 @@ var init_browser = __esm({
|
|
|
46766
46890
|
// server/drivers/acp/hermes.ts
|
|
46767
46891
|
import { spawn as spawn6 } from "node:child_process";
|
|
46768
46892
|
import { mkdirSync as mkdirSync19, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
|
|
46769
|
-
import { homedir as
|
|
46893
|
+
import { homedir as homedir17 } from "node:os";
|
|
46770
46894
|
import { join as join36 } from "node:path";
|
|
46771
46895
|
function bindHermesScreenshotCompat(env, modelId) {
|
|
46772
46896
|
delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT];
|
|
@@ -46776,9 +46900,6 @@ function bindHermesScreenshotCompat(env, modelId) {
|
|
|
46776
46900
|
env[HERMES_OPENMAUS_SCREENSHOT_COMPAT] = "1";
|
|
46777
46901
|
env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL] = inject.model;
|
|
46778
46902
|
}
|
|
46779
|
-
function hermesHome(env) {
|
|
46780
|
-
return env.HERMES_HOME || join36(env.HOME || env.USERPROFILE || homedir21(), ".hermes");
|
|
46781
|
-
}
|
|
46782
46903
|
function quoteYaml(value) {
|
|
46783
46904
|
if (/^[\w./:+-]+$/.test(value)) return value;
|
|
46784
46905
|
return JSON.stringify(value);
|
|
@@ -46817,7 +46938,7 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
46817
46938
|
if (!inject) return modelId;
|
|
46818
46939
|
const host = localHost(inject.host);
|
|
46819
46940
|
if (!host) return modelId;
|
|
46820
|
-
const dir =
|
|
46941
|
+
const dir = env.HERMES_HOME || harnessHome("hermes", env);
|
|
46821
46942
|
mkdirSync19(dir, { recursive: true });
|
|
46822
46943
|
const path3 = join36(dir, "config.yaml");
|
|
46823
46944
|
let text4 = "";
|
|
@@ -46887,7 +47008,7 @@ function hermesConfigDefault(text4) {
|
|
|
46887
47008
|
return null;
|
|
46888
47009
|
}
|
|
46889
47010
|
function hermesConfiguredModel(env = process.env) {
|
|
46890
|
-
const dir =
|
|
47011
|
+
const dir = env.HERMES_HOME || harnessHome("hermes", env);
|
|
46891
47012
|
let secrets = "";
|
|
46892
47013
|
try {
|
|
46893
47014
|
secrets = readFileSync22(join36(dir, ".env"), "utf8");
|
|
@@ -46988,7 +47109,7 @@ async function fetchHermesAcpModels(cli, env) {
|
|
|
46988
47109
|
}
|
|
46989
47110
|
if (msg?.id === initId) {
|
|
46990
47111
|
if (!msg.result) return done([]);
|
|
46991
|
-
sessionId = send("session/new", { cwd: env.HOME || env.USERPROFILE ||
|
|
47112
|
+
sessionId = send("session/new", { cwd: env.HOME || env.USERPROFILE || homedir17(), mcpServers: [] });
|
|
46992
47113
|
} else if (sessionId && msg?.id === sessionId) {
|
|
46993
47114
|
const list = Array.isArray(msg.result?.models?.availableModels) ? msg.result.models.availableModels : [];
|
|
46994
47115
|
done(
|
|
@@ -47032,6 +47153,7 @@ var init_hermes = __esm({
|
|
|
47032
47153
|
"server/drivers/acp/hermes.ts"() {
|
|
47033
47154
|
"use strict";
|
|
47034
47155
|
init_browser();
|
|
47156
|
+
init_env_path();
|
|
47035
47157
|
init_procs();
|
|
47036
47158
|
init_local_inject();
|
|
47037
47159
|
init_core3();
|
|
@@ -47241,8 +47363,8 @@ var init_openai_compat = __esm({
|
|
|
47241
47363
|
});
|
|
47242
47364
|
|
|
47243
47365
|
// server/drivers/pi.ts
|
|
47244
|
-
import { chmodSync as chmodSync6, existsSync as existsSync17, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync3, readFileSync as readFileSync23, rmSync as
|
|
47245
|
-
import { homedir as
|
|
47366
|
+
import { chmodSync as chmodSync6, existsSync as existsSync17, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync3, readFileSync as readFileSync23, rmSync as rmSync7, writeFileSync as writeFileSync15 } from "node:fs";
|
|
47367
|
+
import { homedir as homedir18, tmpdir as tmpdir4 } from "node:os";
|
|
47246
47368
|
import { join as join37 } from "node:path";
|
|
47247
47369
|
function readPiPromptImages(turn) {
|
|
47248
47370
|
return (turn.images ?? []).map((image) => ({
|
|
@@ -47344,7 +47466,7 @@ async function applyPiLocalCatalog(catalog2, env = process.env, fetchImpl = fetc
|
|
|
47344
47466
|
return preferPiInjectRows(await mergeLocalInject(catalog2, env, fetchImpl));
|
|
47345
47467
|
}
|
|
47346
47468
|
function piAgentDir(env) {
|
|
47347
|
-
return join37(env.HOME || env.USERPROFILE ||
|
|
47469
|
+
return join37(env.HOME || env.USERPROFILE || homedir18(), ".pi", "agent");
|
|
47348
47470
|
}
|
|
47349
47471
|
function ensurePiInjectModel(modelId, env = process.env) {
|
|
47350
47472
|
const split = splitPiModel(modelId);
|
|
@@ -47409,7 +47531,7 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
47409
47531
|
return split;
|
|
47410
47532
|
}
|
|
47411
47533
|
function readPiDefaultModel(env) {
|
|
47412
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
47534
|
+
const home = env.HOME || env.USERPROFILE || homedir18();
|
|
47413
47535
|
try {
|
|
47414
47536
|
const s2 = JSON.parse(readFileSync23(`${home}/.pi/agent/settings.json`, "utf8"));
|
|
47415
47537
|
return s2.defaultProvider && s2.defaultModel ? `${s2.defaultProvider}/${s2.defaultModel}` : "";
|
|
@@ -47486,13 +47608,14 @@ function piEnvironment(source) {
|
|
|
47486
47608
|
for (const key of PROVIDER_CREDENTIAL_ENV) delete env[key];
|
|
47487
47609
|
return env;
|
|
47488
47610
|
}
|
|
47489
|
-
var DRIVER_KIND6, PI_ARGS, PI_MODEL_UPDATE_ARGS, NODE_ENV_FLAG2, EMPTY3, PiDriver;
|
|
47611
|
+
var DRIVER_KIND6, PI_ARGS, PI_MODEL_UPDATE_ARGS, NODE_ENV_FLAG2, PI_PROMPT_RE_ANCHOR_TURNS, PI_AGENT_END_GRACE_MS, PiRpcRefusalError, EMPTY3, PiDriver;
|
|
47490
47612
|
var init_pi = __esm({
|
|
47491
47613
|
"server/drivers/pi.ts"() {
|
|
47492
47614
|
"use strict";
|
|
47493
47615
|
init_config();
|
|
47494
47616
|
init_env_path();
|
|
47495
47617
|
init_procs();
|
|
47618
|
+
init_prompt_split();
|
|
47496
47619
|
init_proxy_paths();
|
|
47497
47620
|
init_tool_summary();
|
|
47498
47621
|
init_wire();
|
|
@@ -47504,6 +47627,10 @@ var init_pi = __esm({
|
|
|
47504
47627
|
PI_ARGS = ["--mode", "rpc", "--no-session"];
|
|
47505
47628
|
PI_MODEL_UPDATE_ARGS = ["update", "--models", "--no-approve"];
|
|
47506
47629
|
NODE_ENV_FLAG2 = { ELECTRON_RUN_AS_NODE: "1" };
|
|
47630
|
+
PI_PROMPT_RE_ANCHOR_TURNS = 8;
|
|
47631
|
+
PI_AGENT_END_GRACE_MS = 6e4;
|
|
47632
|
+
PiRpcRefusalError = class extends Error {
|
|
47633
|
+
};
|
|
47507
47634
|
EMPTY3 = { default: "", options: [] };
|
|
47508
47635
|
PiDriver = {
|
|
47509
47636
|
driverKind: DRIVER_KIND6,
|
|
@@ -47568,6 +47695,10 @@ var init_pi = __esm({
|
|
|
47568
47695
|
const pending = /* @__PURE__ */ new Map();
|
|
47569
47696
|
const askTimers = /* @__PURE__ */ new Set();
|
|
47570
47697
|
let settled = false;
|
|
47698
|
+
let endStopReason;
|
|
47699
|
+
let endUsage;
|
|
47700
|
+
let endErrorMessage;
|
|
47701
|
+
let agentEndTimer = null;
|
|
47571
47702
|
const images = readPiPromptImages(turn);
|
|
47572
47703
|
if (typeof turn.model === "string" && turn.model) {
|
|
47573
47704
|
ensurePiInjectModel(turn.model, { ...process.env, ...input.environment });
|
|
@@ -47580,7 +47711,7 @@ var init_pi = __esm({
|
|
|
47580
47711
|
writeFileSync15(join37(mcpTempDir, "mcp.json"), JSON.stringify({ mcpServers }), { mode: 384 });
|
|
47581
47712
|
} catch (err) {
|
|
47582
47713
|
try {
|
|
47583
|
-
|
|
47714
|
+
rmSync7(mcpTempDir, { recursive: true, force: true });
|
|
47584
47715
|
} catch {
|
|
47585
47716
|
}
|
|
47586
47717
|
throw err;
|
|
@@ -47601,7 +47732,7 @@ var init_pi = __esm({
|
|
|
47601
47732
|
} catch (err) {
|
|
47602
47733
|
if (mcpTempDir) {
|
|
47603
47734
|
try {
|
|
47604
|
-
|
|
47735
|
+
rmSync7(mcpTempDir, { recursive: true, force: true });
|
|
47605
47736
|
} catch {
|
|
47606
47737
|
}
|
|
47607
47738
|
}
|
|
@@ -47610,7 +47741,9 @@ var init_pi = __esm({
|
|
|
47610
47741
|
})();
|
|
47611
47742
|
let buf = "";
|
|
47612
47743
|
let assistantText = "";
|
|
47744
|
+
let compactionObserved = false;
|
|
47613
47745
|
const responseWaiters = /* @__PURE__ */ new Map();
|
|
47746
|
+
let steerSeq = 0;
|
|
47614
47747
|
const rejectWaiters = (err) => {
|
|
47615
47748
|
for (const waiter of responseWaiters.values()) {
|
|
47616
47749
|
clearTimeout(waiter.timer);
|
|
@@ -47618,13 +47751,13 @@ var init_pi = __esm({
|
|
|
47618
47751
|
}
|
|
47619
47752
|
responseWaiters.clear();
|
|
47620
47753
|
};
|
|
47621
|
-
const awaitResponse = (command, timeoutMs = 2e4) => new Promise((resolve12, reject) => {
|
|
47754
|
+
const awaitResponse = (command, timeoutMs = 2e4, key = command) => new Promise((resolve12, reject) => {
|
|
47622
47755
|
const timer = setTimeout(() => {
|
|
47623
|
-
responseWaiters.delete(
|
|
47756
|
+
responseWaiters.delete(key);
|
|
47624
47757
|
reject(new Error(`pi ${command} timed out`));
|
|
47625
47758
|
}, timeoutMs);
|
|
47626
47759
|
timer.unref?.();
|
|
47627
|
-
responseWaiters.set(
|
|
47760
|
+
responseWaiters.set(key, { resolve: resolve12, reject, timer });
|
|
47628
47761
|
});
|
|
47629
47762
|
child.stdin.on("error", () => rejectWaiters(new Error("pi stdin closed")));
|
|
47630
47763
|
const send = (obj) => {
|
|
@@ -47640,6 +47773,10 @@ var init_pi = __esm({
|
|
|
47640
47773
|
const settle = (ok, stopReason, usage) => {
|
|
47641
47774
|
if (settled) return;
|
|
47642
47775
|
settled = true;
|
|
47776
|
+
if (agentEndTimer) {
|
|
47777
|
+
clearTimeout(agentEndTimer);
|
|
47778
|
+
agentEndTimer = null;
|
|
47779
|
+
}
|
|
47643
47780
|
for (const timer of askTimers) clearTimeout(timer);
|
|
47644
47781
|
askTimers.clear();
|
|
47645
47782
|
pending.clear();
|
|
@@ -47661,12 +47798,25 @@ var init_pi = __esm({
|
|
|
47661
47798
|
}
|
|
47662
47799
|
if (mcpTempDir) {
|
|
47663
47800
|
try {
|
|
47664
|
-
|
|
47801
|
+
rmSync7(mcpTempDir, { recursive: true, force: true });
|
|
47665
47802
|
} catch {
|
|
47666
47803
|
}
|
|
47667
47804
|
}
|
|
47668
47805
|
active.delete(threadId);
|
|
47669
47806
|
};
|
|
47807
|
+
const finishRun = () => {
|
|
47808
|
+
const sr = endStopReason;
|
|
47809
|
+
if (sr === "error" || sr === "failed") {
|
|
47810
|
+
emit({
|
|
47811
|
+
...base2(threadId, turnId),
|
|
47812
|
+
type: "runtime.error",
|
|
47813
|
+
message: String(endErrorMessage ?? "pi turn failed").slice(0, 2e3)
|
|
47814
|
+
});
|
|
47815
|
+
settle(false, "failed", endUsage);
|
|
47816
|
+
return;
|
|
47817
|
+
}
|
|
47818
|
+
settle(true, sr === "cancelled" || sr === "aborted" ? "cancelled" : "end_turn", endUsage);
|
|
47819
|
+
};
|
|
47670
47820
|
const stop = () => {
|
|
47671
47821
|
try {
|
|
47672
47822
|
send({ type: "abort" });
|
|
@@ -47678,17 +47828,35 @@ var init_pi = __esm({
|
|
|
47678
47828
|
}
|
|
47679
47829
|
settle(true, "cancelled");
|
|
47680
47830
|
};
|
|
47681
|
-
|
|
47831
|
+
const steerActiveTurn = async (text4) => {
|
|
47832
|
+
if (settled || child.exitCode !== null || child.signalCode !== null) return "refused";
|
|
47833
|
+
let ack;
|
|
47834
|
+
try {
|
|
47835
|
+
const id = `steer:${++steerSeq}`;
|
|
47836
|
+
ack = awaitResponse("steer", 2e4, id);
|
|
47837
|
+
send({ type: "steer", id, message: text4 });
|
|
47838
|
+
} catch {
|
|
47839
|
+
return "refused";
|
|
47840
|
+
}
|
|
47841
|
+
try {
|
|
47842
|
+
await ack;
|
|
47843
|
+
return "steered";
|
|
47844
|
+
} catch (error51) {
|
|
47845
|
+
return error51 instanceof PiRpcRefusalError ? "refused" : "indeterminate";
|
|
47846
|
+
}
|
|
47847
|
+
};
|
|
47848
|
+
active.set(threadId, { stop, turnId, pending, child, steer: steerActiveTurn });
|
|
47682
47849
|
const onEvent = (evt) => {
|
|
47683
47850
|
appendNative(threadId, { dir: "in", source: "pi.rpc", msg: evt });
|
|
47684
47851
|
switch (evt.type) {
|
|
47685
47852
|
case "response": {
|
|
47686
|
-
|
|
47687
|
-
|
|
47688
|
-
responseWaiters.
|
|
47853
|
+
const key = typeof evt.id === "string" && responseWaiters.has(evt.id) ? evt.id : evt.command;
|
|
47854
|
+
if (key && responseWaiters.has(key)) {
|
|
47855
|
+
const waiter = responseWaiters.get(key);
|
|
47856
|
+
responseWaiters.delete(key);
|
|
47689
47857
|
clearTimeout(waiter.timer);
|
|
47690
47858
|
if (evt.success) waiter.resolve(evt.data);
|
|
47691
|
-
else waiter.reject(new
|
|
47859
|
+
else waiter.reject(new PiRpcRefusalError(`pi ${evt.command} failed`));
|
|
47692
47860
|
}
|
|
47693
47861
|
return;
|
|
47694
47862
|
}
|
|
@@ -47779,21 +47947,43 @@ var init_pi = __esm({
|
|
|
47779
47947
|
}
|
|
47780
47948
|
return;
|
|
47781
47949
|
}
|
|
47782
|
-
case "
|
|
47783
|
-
case "
|
|
47950
|
+
case "compaction_start":
|
|
47951
|
+
case "compaction_end":
|
|
47952
|
+
case "auto_compaction_start":
|
|
47953
|
+
case "auto_compaction_end": {
|
|
47954
|
+
if (sessionReady && sessionFile) {
|
|
47955
|
+
compactionObserved = true;
|
|
47956
|
+
deletePromptSplitReceipt("pi", JSON.stringify([threadId, sessionFile]));
|
|
47957
|
+
}
|
|
47958
|
+
return;
|
|
47959
|
+
}
|
|
47960
|
+
case "turn_end": {
|
|
47961
|
+
if (settled) return;
|
|
47784
47962
|
const sr = evt.message?.stopReason;
|
|
47785
47963
|
if (sr === "toolUse" || sr === "tool_use" || sr === "tool_calls") return;
|
|
47786
|
-
|
|
47787
|
-
|
|
47788
|
-
|
|
47789
|
-
|
|
47790
|
-
|
|
47791
|
-
|
|
47792
|
-
|
|
47793
|
-
|
|
47794
|
-
|
|
47964
|
+
endStopReason = sr;
|
|
47965
|
+
endUsage = evt.usage ?? evt.message?.usage;
|
|
47966
|
+
endErrorMessage = evt.message?.errorMessage;
|
|
47967
|
+
if (agentEndTimer) clearTimeout(agentEndTimer);
|
|
47968
|
+
agentEndTimer = setTimeout(finishRun, PI_AGENT_END_GRACE_MS);
|
|
47969
|
+
agentEndTimer.unref?.();
|
|
47970
|
+
return;
|
|
47971
|
+
}
|
|
47972
|
+
case "agent_end": {
|
|
47973
|
+
if (evt.isTerminal === false || evt.willRetry === true) return;
|
|
47974
|
+
if (agentEndTimer) {
|
|
47975
|
+
clearTimeout(agentEndTimer);
|
|
47976
|
+
agentEndTimer = null;
|
|
47795
47977
|
}
|
|
47796
|
-
|
|
47978
|
+
finishRun();
|
|
47979
|
+
return;
|
|
47980
|
+
}
|
|
47981
|
+
case "agent_settled": {
|
|
47982
|
+
if (agentEndTimer) {
|
|
47983
|
+
clearTimeout(agentEndTimer);
|
|
47984
|
+
agentEndTimer = null;
|
|
47985
|
+
}
|
|
47986
|
+
finishRun();
|
|
47797
47987
|
return;
|
|
47798
47988
|
}
|
|
47799
47989
|
default:
|
|
@@ -47827,12 +48017,14 @@ var init_pi = __esm({
|
|
|
47827
48017
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
47828
48018
|
const sessionPath = typeof turn.resumeCursor === "string" ? turn.resumeCursor : null;
|
|
47829
48019
|
let sessionFile = sessionPath;
|
|
48020
|
+
let sessionReady = false;
|
|
47830
48021
|
try {
|
|
47831
48022
|
const command = sessionPath ? "switch_session" : "new_session";
|
|
47832
48023
|
const hsPromise = awaitResponse(command);
|
|
47833
48024
|
send(sessionPath ? { type: "switch_session", sessionPath } : { type: "new_session" });
|
|
47834
48025
|
const hs = await hsPromise;
|
|
47835
48026
|
if (hs?.sessionFile) sessionFile = hs.sessionFile;
|
|
48027
|
+
sessionReady = true;
|
|
47836
48028
|
emit({
|
|
47837
48029
|
...base2(threadId, turnId),
|
|
47838
48030
|
type: "session.started",
|
|
@@ -47858,12 +48050,54 @@ var init_pi = __esm({
|
|
|
47858
48050
|
} catch {
|
|
47859
48051
|
}
|
|
47860
48052
|
}
|
|
47861
|
-
const
|
|
48053
|
+
const halves = promptHalves(turn);
|
|
48054
|
+
let message2;
|
|
48055
|
+
let pendingReceipt = null;
|
|
48056
|
+
if (halves.stable !== null && sessionReady && sessionFile) {
|
|
48057
|
+
const receiptKey = JSON.stringify([threadId, sessionFile]);
|
|
48058
|
+
const composed = splitSessionPrompt(
|
|
48059
|
+
halves.stable,
|
|
48060
|
+
halves.volatile,
|
|
48061
|
+
readPromptSplitReceipt("pi", receiptKey),
|
|
48062
|
+
turn.system,
|
|
48063
|
+
turn.text,
|
|
48064
|
+
Boolean(turn.mentionTurn),
|
|
48065
|
+
PI_PROMPT_RE_ANCHOR_TURNS
|
|
48066
|
+
);
|
|
48067
|
+
message2 = composed.text;
|
|
48068
|
+
pendingReceipt = { key: receiptKey, receipt: composed.receipt };
|
|
48069
|
+
} else {
|
|
48070
|
+
message2 = turn.system ? `${turn.system}
|
|
47862
48071
|
|
|
47863
48072
|
${turn.text}` : turn.text;
|
|
48073
|
+
}
|
|
47864
48074
|
try {
|
|
48075
|
+
const accepted = awaitResponse("prompt", 12e4);
|
|
47865
48076
|
send({ type: "prompt", message: message2, ...images.length ? { images } : {} });
|
|
47866
|
-
|
|
48077
|
+
void accepted.then(
|
|
48078
|
+
() => {
|
|
48079
|
+
if (!pendingReceipt || compactionObserved) return;
|
|
48080
|
+
try {
|
|
48081
|
+
writePromptSplitReceipt("pi", pendingReceipt.key, pendingReceipt.receipt);
|
|
48082
|
+
} catch {
|
|
48083
|
+
}
|
|
48084
|
+
},
|
|
48085
|
+
(err) => {
|
|
48086
|
+
if (settled) return;
|
|
48087
|
+
emit({
|
|
48088
|
+
...base2(threadId, turnId),
|
|
48089
|
+
type: "runtime.error",
|
|
48090
|
+
message: String(err?.message ?? err).slice(0, 2e3)
|
|
48091
|
+
});
|
|
48092
|
+
settle(false);
|
|
48093
|
+
}
|
|
48094
|
+
);
|
|
48095
|
+
} catch (err) {
|
|
48096
|
+
emit({
|
|
48097
|
+
...base2(threadId, turnId),
|
|
48098
|
+
type: "runtime.error",
|
|
48099
|
+
message: String(err?.message ?? err).slice(0, 2e3)
|
|
48100
|
+
});
|
|
47867
48101
|
settle(false);
|
|
47868
48102
|
}
|
|
47869
48103
|
return { turnId };
|
|
@@ -47930,7 +48164,10 @@ ${turn.text}` : turn.text;
|
|
|
47930
48164
|
// Reasoning effort pins pi's thinking level per turn (none → off).
|
|
47931
48165
|
// xhigh/max only land on models that expose them; pi rejects an
|
|
47932
48166
|
// unsupported level and the turn keeps the engine default.
|
|
47933
|
-
effortLevels: EFFORT_LEVELS
|
|
48167
|
+
effortLevels: EFFORT_LEVELS,
|
|
48168
|
+
// pi's RPC mode takes a mid-turn steer frame the runtime queues
|
|
48169
|
+
// into the running agent without aborting the current step.
|
|
48170
|
+
queueing: true
|
|
47934
48171
|
},
|
|
47935
48172
|
sendTurn,
|
|
47936
48173
|
interruptTurn: async (threadId) => active.get(threadId)?.stop(),
|
|
@@ -47949,6 +48186,10 @@ ${turn.text}` : turn.text;
|
|
|
47949
48186
|
});
|
|
47950
48187
|
return decision.behavior === "allow" ? "allowed-once" : decision.behavior === "answer" ? "answered" : "rejected";
|
|
47951
48188
|
},
|
|
48189
|
+
steer: async (threadId, text4) => {
|
|
48190
|
+
const entry = active.get(threadId);
|
|
48191
|
+
return entry?.steer ? await entry.steer(text4) : "refused";
|
|
48192
|
+
},
|
|
47952
48193
|
hasSession: (threadId) => active.has(threadId),
|
|
47953
48194
|
stopAll: async () => {
|
|
47954
48195
|
for (const { stop } of active.values()) stop();
|
|
@@ -48092,13 +48333,13 @@ var init_mistral = __esm({
|
|
|
48092
48333
|
|
|
48093
48334
|
// server/drivers/minimax.ts
|
|
48094
48335
|
import { readFileSync as readFileSync24 } from "node:fs";
|
|
48095
|
-
import { homedir as
|
|
48336
|
+
import { homedir as homedir19 } from "node:os";
|
|
48096
48337
|
import { join as join38 } from "node:path";
|
|
48097
48338
|
function normalizedApiUrl(value) {
|
|
48098
48339
|
const root = value.trim().replace(/\/+$/, "");
|
|
48099
48340
|
return root.endsWith("/v1") ? root : `${root}/v1`;
|
|
48100
48341
|
}
|
|
48101
|
-
function loadLocalMiniMaxConfig(home =
|
|
48342
|
+
function loadLocalMiniMaxConfig(home = homedir19()) {
|
|
48102
48343
|
try {
|
|
48103
48344
|
const raw = localConfigSchema.parse(JSON.parse(readFileSync24(join38(home, ".mmx", "config.json"), "utf8")));
|
|
48104
48345
|
const configuredUrl = raw.base_url?.trim() ? raw.base_url : raw.region === "cn" ? CN_URL : DEFAULT_URL3;
|
|
@@ -48358,7 +48599,8 @@ var init_cli_api_setup = __esm({
|
|
|
48358
48599
|
API_ENDPOINTS = [
|
|
48359
48600
|
{ id: "openai", label: "OpenAI API", url: "https://api.openai.com/v1", keyUrl: "https://platform.openai.com/api-keys" },
|
|
48360
48601
|
{ id: "openrouter", label: "OpenRouter", url: "https://openrouter.ai/api/v1", keyUrl: "https://openrouter.ai/settings/keys" },
|
|
48361
|
-
{ id: "groq", label: "Groq", url: "https://api.groq.com/openai/v1", keyUrl: "https://console.groq.com/keys" }
|
|
48602
|
+
{ id: "groq", label: "Groq", url: "https://api.groq.com/openai/v1", keyUrl: "https://console.groq.com/keys" },
|
|
48603
|
+
{ id: "requesty", label: "Requesty", url: "https://router.requesty.ai/v1", keyUrl: "https://app.requesty.ai/api-keys" }
|
|
48362
48604
|
];
|
|
48363
48605
|
SetupApiError = class extends Error {
|
|
48364
48606
|
};
|
|
@@ -48823,8 +49065,8 @@ __export(browser_engine_exports, {
|
|
|
48823
49065
|
});
|
|
48824
49066
|
import { spawn as spawn8 } from "node:child_process";
|
|
48825
49067
|
import { createHash as createHash13, randomBytes as randomBytes3, randomUUID as randomUUID14 } from "node:crypto";
|
|
48826
|
-
import { chmodSync as chmodSync7, constants as constants2, copyFileSync, existsSync as existsSync18, mkdirSync as mkdirSync21, readFileSync as readFileSync26, readdirSync as readdirSync3, renameSync as renameSync6, rmSync as
|
|
48827
|
-
import { homedir as
|
|
49068
|
+
import { chmodSync as chmodSync7, constants as constants2, copyFileSync, existsSync as existsSync18, mkdirSync as mkdirSync21, readFileSync as readFileSync26, readdirSync as readdirSync3, renameSync as renameSync6, rmSync as rmSync8, statSync as statSync5, unlinkSync as unlinkSync7, writeFileSync as writeFileSync16 } from "node:fs";
|
|
49069
|
+
import { homedir as homedir20, tmpdir as tmpdir5 } from "node:os";
|
|
48828
49070
|
import { delimiter as delimiter6, dirname as dirname12, join as join42, resolve as resolve10 } from "node:path";
|
|
48829
49071
|
function browserRestoreKey(session) {
|
|
48830
49072
|
if (!/^[A-Za-z0-9_.-]{1,96}$/.test(session)) throw new Error("Invalid browser session.");
|
|
@@ -48833,7 +49075,7 @@ function browserRestoreKey(session) {
|
|
|
48833
49075
|
function browserSessionsDirectory(env) {
|
|
48834
49076
|
const namespace = env.AGENT_BROWSER_NAMESPACE;
|
|
48835
49077
|
if (namespace && !/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/.test(namespace)) throw new Error("Invalid browser namespace.");
|
|
48836
|
-
const home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) ||
|
|
49078
|
+
const home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir20();
|
|
48837
49079
|
const stateRoot = namespace ? join42(home, ".agent-browser", "namespaces", namespace, "state") : join42(home, ".agent-browser");
|
|
48838
49080
|
return join42(stateRoot, "sessions");
|
|
48839
49081
|
}
|
|
@@ -49215,7 +49457,7 @@ function agentBrowserFrame(input) {
|
|
|
49215
49457
|
} catch {
|
|
49216
49458
|
fail(new Error("the browser reported a picture it did not write"));
|
|
49217
49459
|
} finally {
|
|
49218
|
-
|
|
49460
|
+
rmSync8(file2, { force: true });
|
|
49219
49461
|
}
|
|
49220
49462
|
};
|
|
49221
49463
|
child.on("error", (error51) => done(error51 instanceof Error ? error51 : new Error(String(error51))));
|
|
@@ -49299,7 +49541,7 @@ var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
|
49299
49541
|
import { spawn as spawn9 } from "node:child_process";
|
|
49300
49542
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
49301
49543
|
import { closeSync as closeSync6, existsSync as existsSync19, mkdirSync as mkdirSync22, openSync as openSync6, readFileSync as readFileSync27 } from "node:fs";
|
|
49302
|
-
import { homedir as
|
|
49544
|
+
import { homedir as homedir21 } from "node:os";
|
|
49303
49545
|
import { dirname as dirname13, join as join43, resolve as resolve11 } from "node:path";
|
|
49304
49546
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
49305
49547
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -52793,7 +53035,7 @@ function parseArgs(argv, env = process.env) {
|
|
|
52793
53035
|
const options = {
|
|
52794
53036
|
command: command === "--help" || command === "-h" ? "help" : command,
|
|
52795
53037
|
port: Number(env.OMB_PORT || 8799),
|
|
52796
|
-
dataDir: env.OMB_DATA_DIR || join43(
|
|
53038
|
+
dataDir: env.OMB_DATA_DIR || join43(homedir21(), ".openmausbot"),
|
|
52797
53039
|
tailscale: false,
|
|
52798
53040
|
tunnel: false,
|
|
52799
53041
|
client: false,
|
|
@@ -53721,7 +53963,7 @@ async function runOnboardingCommand(options, io = defaultIo(), startServer = run
|
|
|
53721
53963
|
}
|
|
53722
53964
|
if (options.command === "setup") {
|
|
53723
53965
|
io.log("\nAll set. Start with: openmausbot (or npx openmausbot without a global install).");
|
|
53724
|
-
if (options.dataDir !== join43(
|
|
53966
|
+
if (options.dataDir !== join43(homedir21(), ".openmausbot") || options.port !== 8799) {
|
|
53725
53967
|
io.log(`Use the same --data-dir (${options.dataDir}) and --port (${options.port}) options when starting.`);
|
|
53726
53968
|
}
|
|
53727
53969
|
return 0;
|