openmausbot 0.1.87 → 0.1.89
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-BwaMaZEm.js} +1 -1
- package/dist/assets/{arc-C88Blc2v.js → arc-Be-8GKxd.js} +1 -1
- package/dist/assets/{architectureDiagram-NJMV4G6O-BZsJIZrb.js → architectureDiagram-NJMV4G6O-Dp_U2Kv1.js} +1 -1
- package/dist/assets/{blockDiagram-BEXU5L5S-CVeMe9Ah.js → blockDiagram-BEXU5L5S-DQjUjYUk.js} +1 -1
- package/dist/assets/{c4Diagram-YGBWAQC7-Cedk3Bhx.js → c4Diagram-YGBWAQC7-Bd3aE4Kc.js} +1 -1
- package/dist/assets/channel-DqY_gMLg.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-D-VRqzTB.js → chunk-2Q5K7J3B-BijjTBeJ.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-BChov01Y.js → chunk-3FUC2YCW-CMGdwvzW.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-C-TfwvHy.js → chunk-5VM5RSS4-0G09BfsZ.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-Db7CGj5Y.js → chunk-GTNCS2PH-FOp3vSHe.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-CNvIfqKT.js → chunk-GWA4HPMP-Dv-20VIn.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-C_bEp5tq.js → chunk-JWPE2WC7-CRgrdFcz.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-Coi4BOls.js → chunk-NETBCI7D-3hP4f7QB.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-CzylEuL3.js → chunk-WEXAMYUT-CG98IjlG.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-m7p7ztaD.js → chunk-XXDRQBXY-BrSTC9xG.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-BMy6o9x2.js → classDiagram-v2-NBCMYWYE-rpQQQDFX.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-BDQ__0_J.js → cose-bilkent-JH36ORCC-G6RSafHA.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-Djv4ghUb.js → cynefin-OW5HDTMX-CXjv-IM2.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-BULrlGYH.js → cynefinDiagram-VND7K2PF-Dw07MR9f.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-D-jrT_hU.js → dagre-6A5THRUB-BwPnlTg2.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-p2UhQmfL.js → diagram-22UHCM2B-Cm6xcMiz.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-DHvGWZ7q.js → diagram-3UASUU5V-CDpogPbE.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-ChhKDot-.js → diagram-ATOU4E4O-BV8z3Pnc.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-B-T7A43R.js → diagram-CDSNMT55-CKCQhOOC.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-CJm8ENNY.js → diagram-MLGK6HIB-FGvJg69C.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-510tlza8.js → diagram-MPIPVDR6-CwATvgnS.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-PkvRPHel.js → ebnfDiagram-ZINNZB2B-CH_c3SSC.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-BVBVPoX3.js → elk-276RUBZZ-3guZi71R.js} +1 -1
- package/dist/assets/{erDiagram-OPXOYQCR-BgYMVm7L.js → erDiagram-OPXOYQCR-BMHphR2n.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-BGqsnc_3.js → flowDiagram-KWPJA3E3-Vm5DkW5x.js} +1 -1
- package/dist/assets/{ganttDiagram-FUAMR5RP-D_-UeReH.js → ganttDiagram-FUAMR5RP-DO-1ct07.js} +1 -1
- package/dist/assets/{gitGraphDiagram-X574FWY7-D0uooONx.js → gitGraphDiagram-X574FWY7-nxeksEIN.js} +1 -1
- package/dist/assets/index-BIMdIbaw.css +1 -0
- package/dist/assets/index-BVPdbq2r.js +583 -0
- package/dist/assets/{index-zRsJERGJ.js → index-Oxk9x45i.js} +1 -1
- package/dist/assets/{infoDiagram-VRGFBTTK-B9e1z77f.js → infoDiagram-VRGFBTTK-Dkcvr0p7.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-BB4vNwvD.js → ishikawaDiagram-OU5B5YK6-BwVibkoO.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-DpkosOTB.js → journeyDiagram-ZHPQQLJL-ByiBZqgG.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-DbDP4kUu.js → kanban-definition-PNTS6WVX-qqjgXBF3.js} +1 -1
- package/dist/assets/{linear-DBJGPmjT.js → linear-CtJnKe6A.js} +1 -1
- package/dist/assets/{mermaid.core-DWPRi-ue.js → mermaid.core-BEiDklrY.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-nszBbJmx.js → mindmap-definition-NLK3R4M7-DfIYHia9.js} +1 -1
- package/dist/assets/{pegDiagram-GJSIUBJH-CWykJWu_.js → pegDiagram-GJSIUBJH-CYyRqa1a.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-g3Da-Vnv.js → pieDiagram-5QR66LMP-hOToy_zH.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-Wzrlpzgh.js → quadrantDiagram-O4NWA36T-DKAsNN9I.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-moHTFMC0.js → railroadDiagram-XR7U4H2S-BSA-d8JU.js} +1 -1
- package/dist/assets/{requirementDiagram-PLB6GJNP-CwfXdFH8.js → requirementDiagram-PLB6GJNP-CSmlvb-p.js} +1 -1
- package/dist/assets/{sankeyDiagram-IPEJSGJF-3ZROYvnq.js → sankeyDiagram-IPEJSGJF-CD5F6fnG.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-E1TBebP8.js → sequenceDiagram-PO4LG4MO-JUq5sx6d.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-DHKEU5pu.js → sizeCapture-INFHLROL-BjIS-Stk.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-BguEj09D.js → stateDiagram-v2-GCMORJYK-DklkUxOg.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-C7IDYnhd.js → swimlanes-2SLR337P-CsjIU6be.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-Bk14M0_B.js +8 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-DCW-F5PW.js → timeline-definition-EJHVYXUP-BkFqK7AB.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-xBMFtWYV.js → usecaseDiagram-POWQR4AR-70gJB1EU.js} +1 -1
- package/dist/assets/{vennDiagram-UO4OBE2U-B5nIkuH8.js → vennDiagram-UO4OBE2U-83Tm62dN.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-DYFAhdbr.js → wardleyDiagram-VNRHLVJA-tTmseoX9.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-DeXwX6Cz.js → xychartDiagram-PMCCYNJV-R1LBA55a.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 +11 -1
- package/dist-server/drivers/agents-proxy.js +277 -22
- package/dist-server/index.js +23722 -20272
- 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 +755 -404
- package/dist-server/pair-cli.js +755 -404
- 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/automatic-recovery.js +15 -0
- package/dist-server/server/bot-attachment.js +107 -0
- package/dist-server/server/bot-overview.js +19 -0
- package/dist-server/server/composio.js +297 -1
- package/dist-server/server/config.js +34 -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 +70 -0
- package/dist-server/server/contracts.js +32 -0
- package/dist-server/server/drivers/acp/core.js +148 -23
- 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 +12 -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 +3 -17
- 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 +31 -3
- 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 +61 -0
- package/dist-server/server/index.js +1173 -262
- 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 +37 -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/webhooks.js +21 -3
- 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 +42 -3
- package/dist-server/vps-container-mcp.js +11 -1
- package/dist-server/workspace-backup.worker.js +19482 -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
|
@@ -17791,10 +17791,26 @@ 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
|
-
|
|
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
|
+
}
|
|
17802
|
+
var TurnNotStartedError, eventCounter, newEventId, newId;
|
|
17795
17803
|
var init_contracts = __esm({
|
|
17796
17804
|
"server/contracts.ts"() {
|
|
17797
17805
|
"use strict";
|
|
17806
|
+
TurnNotStartedError = class extends Error {
|
|
17807
|
+
turnId;
|
|
17808
|
+
constructor(turnId, message2) {
|
|
17809
|
+
super(message2);
|
|
17810
|
+
this.name = "TurnNotStartedError";
|
|
17811
|
+
this.turnId = turnId;
|
|
17812
|
+
}
|
|
17813
|
+
};
|
|
17798
17814
|
eventCounter = 0;
|
|
17799
17815
|
newEventId = () => `ev-${Date.now().toString(36)}-${(eventCounter++).toString(36)}`;
|
|
17800
17816
|
newId = () => crypto.randomUUID();
|
|
@@ -18923,7 +18939,16 @@ function loadConfig() {
|
|
|
18923
18939
|
let cfg = {};
|
|
18924
18940
|
try {
|
|
18925
18941
|
cfg = parseStoredConfig(parseJson(readFileSync3(join9(DATA_DIR, "config.json"), "utf8")));
|
|
18926
|
-
|
|
18942
|
+
lastIgnoredConfigWarning = "";
|
|
18943
|
+
} catch (error51) {
|
|
18944
|
+
if (error51?.code !== "ENOENT") {
|
|
18945
|
+
const reason = error51 instanceof SyntaxError ? "invalid JSON" : error51 instanceof Error ? error51.message : "unable to read configuration";
|
|
18946
|
+
const warning = `config: ignoring ${join9(DATA_DIR, "config.json")} and using defaults: ${reason}`;
|
|
18947
|
+
if (warning !== lastIgnoredConfigWarning) console.warn(warning);
|
|
18948
|
+
lastIgnoredConfigWarning = warning;
|
|
18949
|
+
} else {
|
|
18950
|
+
lastIgnoredConfigWarning = "";
|
|
18951
|
+
}
|
|
18927
18952
|
}
|
|
18928
18953
|
cfg.mistral = { ...cfg.mistral };
|
|
18929
18954
|
if (process.env.MISTRAL_API_KEY !== void 0) cfg.mistral.key = process.env.MISTRAL_API_KEY;
|
|
@@ -18995,6 +19020,7 @@ function saveConfig(patch, options = {}) {
|
|
|
18995
19020
|
if (checkedPatch.language !== void 0) disk.language = checkedPatch.language;
|
|
18996
19021
|
if (checkedPatch.customDomain !== void 0) disk.customDomain = checkedPatch.customDomain;
|
|
18997
19022
|
if (checkedPatch.signIn !== void 0) disk.signIn = checkedPatch.signIn;
|
|
19023
|
+
if (checkedPatch.automaticRecovery !== void 0) disk.automaticRecovery = checkedPatch.automaticRecovery;
|
|
18998
19024
|
if (checkedPatch.defaultModelSelection !== void 0) {
|
|
18999
19025
|
disk.defaultModelSelection = checkedPatch.defaultModelSelection;
|
|
19000
19026
|
if (disk.newBotDefaults) {
|
|
@@ -19150,7 +19176,7 @@ function instanceConfigs(cfg) {
|
|
|
19150
19176
|
}
|
|
19151
19177
|
return map3;
|
|
19152
19178
|
}
|
|
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;
|
|
19179
|
+
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, automaticRecoverySchema, 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
19180
|
var init_config = __esm({
|
|
19155
19181
|
"server/config.ts"() {
|
|
19156
19182
|
"use strict";
|
|
@@ -19177,7 +19203,7 @@ var init_config = __esm({
|
|
|
19177
19203
|
MIN_THREAD_EVENT_LOG_BYTES = 256 * 1024;
|
|
19178
19204
|
MAX_THREAD_EVENT_LOG_BYTES = 4 * 1024 * 1024 * 1024;
|
|
19179
19205
|
MIN_LOCAL_VM_MAX_INSTANCES = 1;
|
|
19180
|
-
MAX_LOCAL_VM_MAX_INSTANCES =
|
|
19206
|
+
MAX_LOCAL_VM_MAX_INSTANCES = 8;
|
|
19181
19207
|
CDP_PORT = /^[0-9]{1,5}$/;
|
|
19182
19208
|
CDP_URL = /^(https?|wss?):\/\/\S+$/i;
|
|
19183
19209
|
vpsConfigSchema = external_exports.object({
|
|
@@ -19290,6 +19316,13 @@ var init_config = __esm({
|
|
|
19290
19316
|
(selection) => selection.variant === void 0 || selection.effort === void 0,
|
|
19291
19317
|
"choose either a model variant or an effort level"
|
|
19292
19318
|
);
|
|
19319
|
+
automaticRecoverySchema = external_exports.object({
|
|
19320
|
+
enabled: external_exports.boolean(),
|
|
19321
|
+
backup: defaultModelSelectionSchema.optional()
|
|
19322
|
+
}).strict().refine(
|
|
19323
|
+
(recovery) => !recovery.enabled || recovery.backup !== void 0,
|
|
19324
|
+
{ message: "Choose a backup model before enabling automatic recovery", path: ["backup"] }
|
|
19325
|
+
);
|
|
19293
19326
|
threadsConfigSchema = external_exports.object({
|
|
19294
19327
|
maxConcurrentPerBot: external_exports.number().int().min(1).max(MAX_CONCURRENT_BOT_THREADS),
|
|
19295
19328
|
/** Cap each per-thread events/ and native/ NDJSON log at this many
|
|
@@ -19318,6 +19351,7 @@ var init_config = __esm({
|
|
|
19318
19351
|
* addresses or `@domain` entries; admins get every scope, members chat only. */
|
|
19319
19352
|
signIn: external_exports.object({ admins: external_exports.array(external_exports.string().max(320)).max(500).optional(), members: external_exports.array(external_exports.string().max(320)).max(5e3).optional() }).optional(),
|
|
19320
19353
|
defaultModelSelection: defaultModelSelectionSchema.optional(),
|
|
19354
|
+
automaticRecovery: automaticRecoverySchema.optional(),
|
|
19321
19355
|
newBotDefaults: newBotDefaultsSchema.optional(),
|
|
19322
19356
|
newBots: newBotsConfigSchema.optional(),
|
|
19323
19357
|
/** CLI-only launch preferences. Never enable remote access implicitly. */
|
|
@@ -19432,6 +19466,7 @@ var init_config = __esm({
|
|
|
19432
19466
|
LEGACY_DATA_DIR = join9(homedir4(), ".opengrokbot");
|
|
19433
19467
|
EVENTS_DIR = join9(DATA_DIR, "events");
|
|
19434
19468
|
NATIVE_DIR = join9(DATA_DIR, "native");
|
|
19469
|
+
lastIgnoredConfigWarning = "";
|
|
19435
19470
|
WORKSPACE_CREDENTIAL_ENV = [
|
|
19436
19471
|
"XAI_API_KEY",
|
|
19437
19472
|
"MISTRAL_API_KEY",
|
|
@@ -19877,6 +19912,8 @@ function knownDirs() {
|
|
|
19877
19912
|
join11(home, ".volta", "bin"),
|
|
19878
19913
|
join11(home, ".bun", "bin"),
|
|
19879
19914
|
join11(home, ".asdf", "shims"),
|
|
19915
|
+
join11(home, ".local", "share", "mise", "shims"),
|
|
19916
|
+
// mise installer
|
|
19880
19917
|
join11(home, ".deno", "bin"),
|
|
19881
19918
|
join11(home, "bin"),
|
|
19882
19919
|
...nvmBinDirs()
|
|
@@ -19952,6 +19989,12 @@ function probeLoginShellPath() {
|
|
|
19952
19989
|
}
|
|
19953
19990
|
);
|
|
19954
19991
|
}
|
|
19992
|
+
function userHome(env = process.env) {
|
|
19993
|
+
return process.platform === "win32" ? env.USERPROFILE || env.HOME || homedir5() : env.HOME || env.USERPROFILE || homedir5();
|
|
19994
|
+
}
|
|
19995
|
+
function harnessHome(name, env = process.env) {
|
|
19996
|
+
return join11(userHome(env), `.${name}`);
|
|
19997
|
+
}
|
|
19955
19998
|
function findCliCandidates(name) {
|
|
19956
19999
|
if (!name || /[\n\r]/.test(name)) return [];
|
|
19957
20000
|
if (/[/\\]/.test(name) || /^[a-zA-Z]:/.test(name)) return [name];
|
|
@@ -20900,7 +20943,7 @@ var init_local_inject = __esm({
|
|
|
20900
20943
|
|
|
20901
20944
|
// server/drivers/prompt-split.ts
|
|
20902
20945
|
import { createHash as createHash3 } from "node:crypto";
|
|
20903
|
-
import { mkdirSync as mkdirSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
20946
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync7, rmSync as rmSync4 } from "node:fs";
|
|
20904
20947
|
import { join as join15 } from "node:path";
|
|
20905
20948
|
function promptHalves(turn) {
|
|
20906
20949
|
const { systemStable, systemVolatile } = turn;
|
|
@@ -20927,7 +20970,11 @@ function readPromptSplitReceipt(scope, key) {
|
|
|
20927
20970
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
20928
20971
|
const record3 = raw;
|
|
20929
20972
|
if (typeof record3.stable === "string" && typeof record3.volatile === "string") {
|
|
20930
|
-
return {
|
|
20973
|
+
return {
|
|
20974
|
+
stable: record3.stable,
|
|
20975
|
+
volatile: record3.volatile,
|
|
20976
|
+
...typeof record3.turnsSinceFull === "number" ? { turnsSinceFull: record3.turnsSinceFull } : {}
|
|
20977
|
+
};
|
|
20931
20978
|
}
|
|
20932
20979
|
}
|
|
20933
20980
|
} catch {
|
|
@@ -20938,13 +20985,21 @@ function writePromptSplitReceipt(scope, key, receipt) {
|
|
|
20938
20985
|
mkdirSync9(join15(DATA_DIR, "prompt-split"), { recursive: true });
|
|
20939
20986
|
writeFileAtomic(receiptPath(scope, key), JSON.stringify(receipt), { mode: 384 });
|
|
20940
20987
|
}
|
|
20941
|
-
function
|
|
20942
|
-
|
|
20943
|
-
|
|
20944
|
-
|
|
20988
|
+
function deletePromptSplitReceipt(scope, key) {
|
|
20989
|
+
try {
|
|
20990
|
+
rmSync4(receiptPath(scope, key));
|
|
20991
|
+
} catch {
|
|
20992
|
+
}
|
|
20993
|
+
}
|
|
20994
|
+
function splitSessionPrompt(stable, volatile, previous, fullSystem, text4, perTurnVolatile = false, reAnchorAfterTurns = 0) {
|
|
20995
|
+
const fingerprints = promptSplitFingerprints(stable, volatile);
|
|
20996
|
+
const turnsSinceFull = typeof previous?.turnsSinceFull === "number" ? previous.turnsSinceFull : 0;
|
|
20997
|
+
const reAnchor = reAnchorAfterTurns > 0 && previous !== null && turnsSinceFull >= reAnchorAfterTurns;
|
|
20998
|
+
if (previous === null || previous.stable !== fingerprints.stable || reAnchor) {
|
|
20999
|
+
return { text: fullSystem ? fullSystem + "\n\n" + text4 : text4, receipt: { ...fingerprints, turnsSinceFull: 0 } };
|
|
20945
21000
|
}
|
|
20946
|
-
const note = previous.volatile ===
|
|
20947
|
-
return { text: withContextNote(note, text4), receipt };
|
|
21001
|
+
const note = previous.volatile === fingerprints.volatile && !perTurnVolatile ? "" : volatileContextNote(volatile, previous.volatile !== EMPTY_FINGERPRINT);
|
|
21002
|
+
return { text: withContextNote(note, text4), receipt: { ...fingerprints, turnsSinceFull: turnsSinceFull + 1 } };
|
|
20948
21003
|
}
|
|
20949
21004
|
var VOLATILE_CONTEXT_NOTE_PREFIX, VOLATILE_CONTEXT_CLEARED_NOTE, digest, EMPTY_FINGERPRINT, receiptPath;
|
|
20950
21005
|
var init_prompt_split = __esm({
|
|
@@ -21051,6 +21106,19 @@ function stripOmbAskBlock(output) {
|
|
|
21051
21106
|
if (!OMB_ASK_FENCE.test(output)) return output;
|
|
21052
21107
|
return output.replace(OMB_ASK_FENCE_GLOBAL, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
21053
21108
|
}
|
|
21109
|
+
function ombAskProtocolPrompt() {
|
|
21110
|
+
return [
|
|
21111
|
+
"",
|
|
21112
|
+
"## Asking the person a question",
|
|
21113
|
+
"When a decision belongs to the person, end your reply with a fenced block exactly like this:",
|
|
21114
|
+
"",
|
|
21115
|
+
"```omb-ask",
|
|
21116
|
+
'{"questions":[{"question":"Ship the release now?","header":"Release","options":[{"label":"Ship now"},{"label":"Wait for the QA signoff"}]}]}',
|
|
21117
|
+
"```",
|
|
21118
|
+
"",
|
|
21119
|
+
`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.`
|
|
21120
|
+
].join("\n");
|
|
21121
|
+
}
|
|
21054
21122
|
function askQuestionSummary(questions) {
|
|
21055
21123
|
const first = questions[0]?.question ?? "";
|
|
21056
21124
|
const rest = questions.length - 1;
|
|
@@ -21199,7 +21267,7 @@ var init_ask_question = __esm({
|
|
|
21199
21267
|
});
|
|
21200
21268
|
|
|
21201
21269
|
// server/thread-log-rotation.ts
|
|
21202
|
-
import { closeSync as closeSync4, fstatSync, openSync as openSync4, readSync as readSync2, renameSync as renameSync5, rmSync as
|
|
21270
|
+
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
21271
|
function currentThreadLogCap() {
|
|
21204
21272
|
try {
|
|
21205
21273
|
return capProvider();
|
|
@@ -21251,7 +21319,7 @@ function trimToTail(file2, keepBytes) {
|
|
|
21251
21319
|
renameSync5(staging, file2);
|
|
21252
21320
|
} catch {
|
|
21253
21321
|
try {
|
|
21254
|
-
|
|
21322
|
+
rmSync5(staging, { force: true });
|
|
21255
21323
|
} catch {
|
|
21256
21324
|
}
|
|
21257
21325
|
}
|
|
@@ -21423,6 +21491,128 @@ var init_resume_recovery = __esm({
|
|
|
21423
21491
|
}
|
|
21424
21492
|
});
|
|
21425
21493
|
|
|
21494
|
+
// server/drivers/session-idle.ts
|
|
21495
|
+
function usableMilliseconds(raw) {
|
|
21496
|
+
const value = Number(raw);
|
|
21497
|
+
return Number.isFinite(value) && value > 0 && value <= MAX_TIMER_MS ? value : null;
|
|
21498
|
+
}
|
|
21499
|
+
function sessionIdlePolicy(driverPrefix, env = process.env) {
|
|
21500
|
+
const minimumMs = Math.max(
|
|
21501
|
+
MINIMUM_IDLE_MS,
|
|
21502
|
+
usableMilliseconds(
|
|
21503
|
+
env[`OMB_${driverPrefix}_SESSION_IDLE_MIN_MS`] ?? env.OMB_SESSION_IDLE_MIN_MS
|
|
21504
|
+
) ?? 0
|
|
21505
|
+
);
|
|
21506
|
+
const configured = usableMilliseconds(
|
|
21507
|
+
env[`OMB_${driverPrefix}_SESSION_IDLE_MS`] ?? env.OMB_SESSION_IDLE_MS
|
|
21508
|
+
) ?? DEFAULT_IDLE_MS;
|
|
21509
|
+
return { idleMs: Math.max(minimumMs, configured), minimumMs };
|
|
21510
|
+
}
|
|
21511
|
+
var DEFAULT_IDLE_MS, MINIMUM_IDLE_MS, MAX_TIMER_MS;
|
|
21512
|
+
var init_session_idle = __esm({
|
|
21513
|
+
"server/drivers/session-idle.ts"() {
|
|
21514
|
+
"use strict";
|
|
21515
|
+
DEFAULT_IDLE_MS = 10 * 6e4;
|
|
21516
|
+
MINIMUM_IDLE_MS = 1e4;
|
|
21517
|
+
MAX_TIMER_MS = 2147483647;
|
|
21518
|
+
}
|
|
21519
|
+
});
|
|
21520
|
+
|
|
21521
|
+
// shared/provider-safety.ts
|
|
21522
|
+
function isProviderSafetyBlock(message2) {
|
|
21523
|
+
return /\bblocked by (?:our|the provider['’]s) safety systems\b|\bsafety monitoring\b.{0,100}\b(?:paused|ended|blocked)\b|\b(?:safety_check_failed|safety_policy_violation)\b/i.test(message2);
|
|
21524
|
+
}
|
|
21525
|
+
var init_provider_safety = __esm({
|
|
21526
|
+
"shared/provider-safety.ts"() {
|
|
21527
|
+
"use strict";
|
|
21528
|
+
}
|
|
21529
|
+
});
|
|
21530
|
+
|
|
21531
|
+
// server/drivers/retry.ts
|
|
21532
|
+
function classifyError(err) {
|
|
21533
|
+
const text4 = messageOf(err);
|
|
21534
|
+
if (isProviderSafetyBlock(text4)) return { transient: false, reason: "provider_safety" };
|
|
21535
|
+
if (err && "exitCode" in err) {
|
|
21536
|
+
const { exitCode: code } = err;
|
|
21537
|
+
if (code !== null && code < 0) return { transient: false, reason: "interrupted" };
|
|
21538
|
+
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
21539
|
+
if (pattern.test(text4)) return { transient: true, reason };
|
|
21540
|
+
}
|
|
21541
|
+
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
21542
|
+
if (pattern.test(text4)) return { transient: false, reason };
|
|
21543
|
+
}
|
|
21544
|
+
return { transient: false, reason: "terminal_exit" };
|
|
21545
|
+
}
|
|
21546
|
+
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
21547
|
+
if (pattern.test(text4)) return { transient: false, reason };
|
|
21548
|
+
}
|
|
21549
|
+
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
21550
|
+
if (pattern.test(text4)) return { transient: true, reason };
|
|
21551
|
+
}
|
|
21552
|
+
return { transient: false, reason: "unknown" };
|
|
21553
|
+
}
|
|
21554
|
+
function computeBackoff(attempt, random = Math.random) {
|
|
21555
|
+
const base2 = BACKOFF_BASE_MS[Math.min(Math.max(attempt, 0), BACKOFF_BASE_MS.length - 1)];
|
|
21556
|
+
const jitter = base2 * 0.25;
|
|
21557
|
+
return Math.round(base2 - jitter + random() * jitter * 2);
|
|
21558
|
+
}
|
|
21559
|
+
function interruptibleDelay(ms, signal) {
|
|
21560
|
+
let timer = null;
|
|
21561
|
+
let onCancel = null;
|
|
21562
|
+
const promise2 = new Promise((resolve12) => {
|
|
21563
|
+
timer = setTimeout(() => resolve12("elapsed"), Math.max(1, ms));
|
|
21564
|
+
timer.unref?.();
|
|
21565
|
+
if (signal?.aborted) return resolve12("cancelled");
|
|
21566
|
+
onCancel = () => {
|
|
21567
|
+
clearTimeout(timer);
|
|
21568
|
+
resolve12("cancelled");
|
|
21569
|
+
};
|
|
21570
|
+
signal?.addEventListener("abort", onCancel, { once: true });
|
|
21571
|
+
});
|
|
21572
|
+
return {
|
|
21573
|
+
promise: promise2,
|
|
21574
|
+
cancel: () => onCancel?.()
|
|
21575
|
+
};
|
|
21576
|
+
}
|
|
21577
|
+
var RETRY_MAX_ATTEMPTS, BACKOFF_BASE_MS, TRANSIENT_PATTERNS, TERMINAL_PATTERNS, messageOf;
|
|
21578
|
+
var init_retry = __esm({
|
|
21579
|
+
"server/drivers/retry.ts"() {
|
|
21580
|
+
"use strict";
|
|
21581
|
+
init_provider_safety();
|
|
21582
|
+
RETRY_MAX_ATTEMPTS = 3;
|
|
21583
|
+
BACKOFF_BASE_MS = [1e3, 3e3, 8e3];
|
|
21584
|
+
TRANSIENT_PATTERNS = [
|
|
21585
|
+
{ pattern: /\b(?:429|rate.?limit|too many requests)\b/i, reason: "rate_limited" },
|
|
21586
|
+
{ pattern: /\boverloaded\b|\bcapacity\b/i, reason: "overloaded" },
|
|
21587
|
+
{ pattern: /\b5\d{2}\b|\binternal server error\b|\bbad gateway\b|\bservice unavailable\b/i, reason: "server_error" },
|
|
21588
|
+
{
|
|
21589
|
+
pattern: /\b(?:econnreset|econnrefused|epipe|etimedout|eai_again|connection reset|connection refused|socket hang up|network error|fetch failed)\b/i,
|
|
21590
|
+
reason: "connection_reset"
|
|
21591
|
+
},
|
|
21592
|
+
{ pattern: /\btimeout(ed)?\b|\btimed? out\b/i, reason: "timeout" }
|
|
21593
|
+
];
|
|
21594
|
+
TERMINAL_PATTERNS = [
|
|
21595
|
+
{
|
|
21596
|
+
pattern: /\b(?:40[13]|unauthorized|forbidden|invalid api key|missing bearer|authentication required|not logged in|logged out)\b/i,
|
|
21597
|
+
reason: "auth"
|
|
21598
|
+
},
|
|
21599
|
+
{ pattern: /\b402\b|\bquota\b|\bbilling\b|\bsubscription\b/i, reason: "quota" },
|
|
21600
|
+
{ pattern: /\bmodel not found\b|\bunknown model\b|\bdoes not exist for model\b|\bunsupported model\b/i, reason: "unknown_model" },
|
|
21601
|
+
{ pattern: /\b400\b|\b422\b|\binvalid request\b|\bmalformed\b|\bunexpected status\b/i, reason: "invalid_request" },
|
|
21602
|
+
{ pattern: /\b404\b|\bno such thread\b|\bthread gone\b/i, reason: "not_found" },
|
|
21603
|
+
// interrupt/cancel vocabulary from the drivers' own stop paths — a turn the
|
|
21604
|
+
// user stopped must never come back as an auto-retry
|
|
21605
|
+
{ pattern: /\b(?:interrupted|cancelled by user)\b/i, reason: "interrupted" }
|
|
21606
|
+
];
|
|
21607
|
+
messageOf = (err) => {
|
|
21608
|
+
if (!err) return "";
|
|
21609
|
+
if (err instanceof Error) return `${err.message}${err.cause ? ` ${String(err.cause)}` : ""}`;
|
|
21610
|
+
if ("text" in err) return err.text;
|
|
21611
|
+
return [err.stderr ?? "", ""].join(" ").trim();
|
|
21612
|
+
};
|
|
21613
|
+
}
|
|
21614
|
+
});
|
|
21615
|
+
|
|
21426
21616
|
// server/drivers/acp/core.ts
|
|
21427
21617
|
import { homedir as homedir7 } from "node:os";
|
|
21428
21618
|
import { lstat, mkdir as mkdir3, readFile, realpath, stat as stat2, writeFile } from "node:fs/promises";
|
|
@@ -21451,6 +21641,12 @@ function acpRpcError(value, method) {
|
|
|
21451
21641
|
acpSessionFailure: value?.code === -32603
|
|
21452
21642
|
});
|
|
21453
21643
|
}
|
|
21644
|
+
function trackRunningTool(current, update, defaultStatus) {
|
|
21645
|
+
if (typeof update.toolCallId !== "string" || !update.toolCallId) return;
|
|
21646
|
+
const status = update.status ?? defaultStatus;
|
|
21647
|
+
if (status === "completed" || status === "failed") current.runningTools.delete(update.toolCallId);
|
|
21648
|
+
else if (status === "pending" || status === "in_progress") current.runningTools.add(update.toolCallId);
|
|
21649
|
+
}
|
|
21454
21650
|
function acpVariantOption(result) {
|
|
21455
21651
|
const option = (Array.isArray(result?.configOptions) ? result.configOptions : []).find(
|
|
21456
21652
|
(entry) => entry?.type === "select" && typeof entry.id === "string" && (entry.id === "effort" || entry.category === "thought_level")
|
|
@@ -21542,6 +21738,17 @@ function versionFromProbe(stdout2, stderr) {
|
|
|
21542
21738
|
const err = (stderr ?? "").trim().split(/\r\n|\n|\r/, 1)[0]?.trim() ?? "";
|
|
21543
21739
|
return err || null;
|
|
21544
21740
|
}
|
|
21741
|
+
function parseVersionTriple(value) {
|
|
21742
|
+
const match = /(\d+)\.(\d+)\.(\d+)/.exec(value);
|
|
21743
|
+
if (!match) return null;
|
|
21744
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
21745
|
+
}
|
|
21746
|
+
function versionAtLeast(installed, floor) {
|
|
21747
|
+
for (let i2 = 0; i2 < 3; i2 += 1) {
|
|
21748
|
+
if (installed[i2] !== floor[i2]) return installed[i2] > floor[i2];
|
|
21749
|
+
}
|
|
21750
|
+
return true;
|
|
21751
|
+
}
|
|
21545
21752
|
function createAcpDriver(support11) {
|
|
21546
21753
|
const DRIVER_KIND8 = support11.driverKind;
|
|
21547
21754
|
const SOURCE = support11.nativeSource;
|
|
@@ -21587,9 +21794,19 @@ function createAcpDriver(support11) {
|
|
|
21587
21794
|
const listeners = /* @__PURE__ */ new Set();
|
|
21588
21795
|
const active = /* @__PURE__ */ new Map();
|
|
21589
21796
|
const sessions = /* @__PURE__ */ new Map();
|
|
21590
|
-
const
|
|
21591
|
-
const
|
|
21592
|
-
|
|
21797
|
+
const retiring = /* @__PURE__ */ new Map();
|
|
21798
|
+
const retireChild = async (threadId, child) => {
|
|
21799
|
+
let children = retiring.get(threadId);
|
|
21800
|
+
if (!children) retiring.set(threadId, children = /* @__PURE__ */ new Set());
|
|
21801
|
+
children.add(child);
|
|
21802
|
+
const stopped = await killCliTree(child);
|
|
21803
|
+
if (stopped) {
|
|
21804
|
+
children.delete(child);
|
|
21805
|
+
if (!children.size && retiring.get(threadId) === children) retiring.delete(threadId);
|
|
21806
|
+
}
|
|
21807
|
+
return stopped;
|
|
21808
|
+
};
|
|
21809
|
+
const { idleMs: SESSION_IDLE_MS } = sessionIdlePolicy("ACP");
|
|
21593
21810
|
const closeSession = (threadId, why) => {
|
|
21594
21811
|
const session = sessions.get(threadId);
|
|
21595
21812
|
if (!session || session.closing) return;
|
|
@@ -21602,10 +21819,13 @@ function createAcpDriver(support11) {
|
|
|
21602
21819
|
session.child.stdin.end();
|
|
21603
21820
|
} catch {
|
|
21604
21821
|
}
|
|
21605
|
-
|
|
21606
|
-
|
|
21607
|
-
|
|
21608
|
-
|
|
21822
|
+
if (support11.restartOnMcpChange) void retireChild(threadId, session.child);
|
|
21823
|
+
else {
|
|
21824
|
+
const kill = setTimeout(() => {
|
|
21825
|
+
void killCliTree(session.child);
|
|
21826
|
+
}, 5e3);
|
|
21827
|
+
kill.unref?.();
|
|
21828
|
+
}
|
|
21609
21829
|
};
|
|
21610
21830
|
const armIdle = (threadId) => {
|
|
21611
21831
|
const session = sessions.get(threadId);
|
|
@@ -21696,6 +21916,7 @@ function createAcpDriver(support11) {
|
|
|
21696
21916
|
const current = session.current;
|
|
21697
21917
|
if (!current || current.state.settled) return;
|
|
21698
21918
|
current.state.settled = true;
|
|
21919
|
+
current.acknowledge();
|
|
21699
21920
|
if (current.interruptTimer) clearTimeout(current.interruptTimer);
|
|
21700
21921
|
for (const finish of current.asks.values()) finish("cancel", "system");
|
|
21701
21922
|
session.acp.failAll(new Error("turn settled"));
|
|
@@ -21755,7 +21976,7 @@ function createAcpDriver(support11) {
|
|
|
21755
21976
|
if (!(idleMs && idleMs > 0)) return;
|
|
21756
21977
|
if (idleTimer) clearTimeout(idleTimer);
|
|
21757
21978
|
idleTimer = setTimeout(() => {
|
|
21758
|
-
if (session.current?.asks.size) {
|
|
21979
|
+
if (session.current?.asks.size || session.current?.runningTools.size) {
|
|
21759
21980
|
armIdle2();
|
|
21760
21981
|
return;
|
|
21761
21982
|
}
|
|
@@ -21869,6 +22090,7 @@ function createAcpDriver(support11) {
|
|
|
21869
22090
|
}
|
|
21870
22091
|
};
|
|
21871
22092
|
const handleServerRequest = (msg, current) => {
|
|
22093
|
+
current.state.startupActivity = true;
|
|
21872
22094
|
if (msg.method === "fs/read_text_file" || msg.method === "fs/write_text_file") {
|
|
21873
22095
|
void handleClientFileRequest(msg);
|
|
21874
22096
|
return;
|
|
@@ -21972,6 +22194,9 @@ function createAcpDriver(support11) {
|
|
|
21972
22194
|
if (current && !current.state.settled && session.sessionId && p2.sessionId === session.sessionId) current.receiveModelVariants(p2.update);
|
|
21973
22195
|
return;
|
|
21974
22196
|
}
|
|
22197
|
+
if (current && ["agent_message_chunk", "agent_thought_chunk", "tool_call", "tool_call_update"].includes(p2.update?.sessionUpdate)) {
|
|
22198
|
+
current.state.startupActivity = true;
|
|
22199
|
+
}
|
|
21975
22200
|
if (!current || !current.state.promptSent) return;
|
|
21976
22201
|
const u4 = p2.update ?? {};
|
|
21977
22202
|
switch (u4.sessionUpdate) {
|
|
@@ -22003,6 +22228,7 @@ function createAcpDriver(support11) {
|
|
|
22003
22228
|
}
|
|
22004
22229
|
case "tool_call": {
|
|
22005
22230
|
current.flushAssistantText();
|
|
22231
|
+
trackRunningTool(current, u4, "pending");
|
|
22006
22232
|
emit({
|
|
22007
22233
|
...base2(threadId, current.turnId),
|
|
22008
22234
|
type: "item.started",
|
|
@@ -22015,6 +22241,7 @@ function createAcpDriver(support11) {
|
|
|
22015
22241
|
break;
|
|
22016
22242
|
}
|
|
22017
22243
|
case "tool_call_update": {
|
|
22244
|
+
trackRunningTool(current, u4);
|
|
22018
22245
|
if (u4.status === "completed" || u4.status === "failed") {
|
|
22019
22246
|
current.state.producedItem = true;
|
|
22020
22247
|
emit({
|
|
@@ -22164,7 +22391,7 @@ function createAcpDriver(support11) {
|
|
|
22164
22391
|
}
|
|
22165
22392
|
const pooled = sessions.get(threadId);
|
|
22166
22393
|
let session;
|
|
22167
|
-
if (pooled && !pooled.dead && !pooled.closing && pooled.contractKey === contractKey) {
|
|
22394
|
+
if (pooled && !pooled.dead && !pooled.closing && pooled.contractKey === contractKey && (!support11.restartOnMcpChange || pooled.sessionKey === sessionKey)) {
|
|
22168
22395
|
if (pooled.idleTimer) clearTimeout(pooled.idleTimer);
|
|
22169
22396
|
pooled.idleTimer = null;
|
|
22170
22397
|
session = pooled;
|
|
@@ -22177,7 +22404,15 @@ function createAcpDriver(support11) {
|
|
|
22177
22404
|
sessions.set(threadId, session);
|
|
22178
22405
|
}
|
|
22179
22406
|
const request = (method, params, timeoutMs, receive, idleMs, idleMessage) => session.acp.request(method, params, timeoutMs, receive, idleMs, idleMessage);
|
|
22180
|
-
const state = { settled: false, promptSent: false, text: "", producedItem: false };
|
|
22407
|
+
const state = { settled: false, promptSent: false, text: "", producedItem: false, startupActivity: false, stopped: false };
|
|
22408
|
+
let acknowledge = () => {
|
|
22409
|
+
};
|
|
22410
|
+
let rejectStartup = (_error) => {
|
|
22411
|
+
};
|
|
22412
|
+
const startupAck = turn.startupRecovery ? new Promise((resolve12, reject) => {
|
|
22413
|
+
acknowledge = () => resolve12({ turnId });
|
|
22414
|
+
rejectStartup = reject;
|
|
22415
|
+
}) : null;
|
|
22181
22416
|
const asks = /* @__PURE__ */ new Map();
|
|
22182
22417
|
const modelOf = (result) => {
|
|
22183
22418
|
const option = (Array.isArray(result?.configOptions) ? result.configOptions : []).find(
|
|
@@ -22222,12 +22457,15 @@ function createAcpDriver(support11) {
|
|
|
22222
22457
|
turnConfig,
|
|
22223
22458
|
controlsHost,
|
|
22224
22459
|
state,
|
|
22460
|
+
acknowledge,
|
|
22225
22461
|
asks,
|
|
22462
|
+
runningTools: /* @__PURE__ */ new Set(),
|
|
22226
22463
|
interruptTimer: null,
|
|
22227
22464
|
flushAssistantText,
|
|
22228
22465
|
receiveModelVariants
|
|
22229
22466
|
};
|
|
22230
22467
|
const interrupt = () => {
|
|
22468
|
+
state.stopped = true;
|
|
22231
22469
|
if (session.sessionId) {
|
|
22232
22470
|
session.acp.send({ jsonrpc: "2.0", method: "session/cancel", params: { sessionId: session.sessionId } });
|
|
22233
22471
|
if (current.interruptTimer) clearTimeout(current.interruptTimer);
|
|
@@ -22240,12 +22478,24 @@ function createAcpDriver(support11) {
|
|
|
22240
22478
|
closeSession(threadId, "stop");
|
|
22241
22479
|
}
|
|
22242
22480
|
};
|
|
22243
|
-
active.set(threadId, { stop: () =>
|
|
22481
|
+
active.set(threadId, { stop: () => {
|
|
22482
|
+
state.stopped = true;
|
|
22483
|
+
closeSession(threadId, "stop");
|
|
22484
|
+
}, interrupt, turnId, asks });
|
|
22244
22485
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
22245
22486
|
session.current = current;
|
|
22246
22487
|
(async () => {
|
|
22247
22488
|
try {
|
|
22248
22489
|
const handshake = async () => {
|
|
22490
|
+
for (const child of retiring.get(threadId) ?? []) {
|
|
22491
|
+
const stopped = await retireChild(threadId, child);
|
|
22492
|
+
if (state.settled || session.closing) throw new Error("session closed");
|
|
22493
|
+
if (!stopped) {
|
|
22494
|
+
closeSession(threadId, "replace-failed");
|
|
22495
|
+
throw new Error(`${support11.displayName} could not close its previous tool session. Try again.`);
|
|
22496
|
+
}
|
|
22497
|
+
}
|
|
22498
|
+
if (state.settled || session.closing) throw new Error("session closed");
|
|
22249
22499
|
if (!session.initResult) {
|
|
22250
22500
|
session.initResult = await request(
|
|
22251
22501
|
"initialize",
|
|
@@ -22421,7 +22671,8 @@ function createAcpDriver(support11) {
|
|
|
22421
22671
|
readPromptSplitReceipt(DRIVER_KIND8, receiptKey),
|
|
22422
22672
|
promptTurn.system,
|
|
22423
22673
|
promptTurn.text,
|
|
22424
|
-
Boolean(turn.mentionTurn)
|
|
22674
|
+
Boolean(turn.mentionTurn),
|
|
22675
|
+
ACP_PROMPT_RE_ANCHOR_TURNS
|
|
22425
22676
|
);
|
|
22426
22677
|
promptInput = { ...promptTurn, system: "", text: composed.text };
|
|
22427
22678
|
pendingSplitReceipt = { key: receiptKey, receipt: composed.receipt };
|
|
@@ -22436,7 +22687,9 @@ ${promptInput.text}` : promptInput.text;
|
|
|
22436
22687
|
if (turn.variant !== void 0 && requestedVariantOption().currentValue !== turn.variant) {
|
|
22437
22688
|
throw new Error(`${support11.displayName} changed variant before the prompt`);
|
|
22438
22689
|
}
|
|
22690
|
+
if (state.settled || state.stopped || session.closing) throw new Error("turn stopped");
|
|
22439
22691
|
state.promptSent = true;
|
|
22692
|
+
acknowledge();
|
|
22440
22693
|
const promptIdleMs = promptIdleTimeoutMs();
|
|
22441
22694
|
const result = await request(
|
|
22442
22695
|
"session/prompt",
|
|
@@ -22444,7 +22697,7 @@ ${promptInput.text}` : promptInput.text;
|
|
|
22444
22697
|
void 0,
|
|
22445
22698
|
void 0,
|
|
22446
22699
|
promptIdleMs,
|
|
22447
|
-
`${DRIVER_KIND8}
|
|
22700
|
+
`${DRIVER_KIND8} sent nothing for ${Math.round(promptIdleMs / 1e3)} s with no tool running, so the turn was stopped as stuck. Send the message again to retry. On a self-hosted server, OPENMAUS_ACP_PROMPT_IDLE_TIMEOUT_MS sets this limit (0 turns it off).`
|
|
22448
22701
|
);
|
|
22449
22702
|
if (pendingSplitReceipt) {
|
|
22450
22703
|
writePromptSplitReceipt(DRIVER_KIND8, pendingSplitReceipt.key, pendingSplitReceipt.receipt);
|
|
@@ -22475,6 +22728,32 @@ ${promptInput.text}` : promptInput.text;
|
|
|
22475
22728
|
const message2 = e instanceof Error ? e.message : String(e);
|
|
22476
22729
|
const code = support11.classifyError?.(e);
|
|
22477
22730
|
const needsAuth = code === "invalid_credentials" || code === "inactive_subscription" || message2 === support11.loginNote;
|
|
22731
|
+
const failure = classifyError({ text: message2 });
|
|
22732
|
+
const transientStartup = failure.transient || failure.reason === "unknown" && code === "upstream_outage";
|
|
22733
|
+
const denied = /\b(?:(?:permission|access) denied|(?:approval|permission) (?:required|denied|rejected)|requires? (?:approval|permission)|policy (?:restriction|violation)|(?:blocked|denied|restricted) by (?:the )?policy)\b/i.test(message2);
|
|
22734
|
+
if (turn.startupRecovery && transientStartup && !needsAuth && !denied && (!code || code === "upstream_outage") && ![-32700, -32600, -32601, -32602].includes(e?.code) && !state.promptSent && !state.startupActivity && !state.producedItem && !state.text && !state.stopped && !session.closing && !asks.size && !current.runningTools.size) {
|
|
22735
|
+
state.settled = true;
|
|
22736
|
+
session.current = null;
|
|
22737
|
+
if (current.interruptTimer) clearTimeout(current.interruptTimer);
|
|
22738
|
+
closeSession(threadId, "startup-recovery");
|
|
22739
|
+
const stopped = await killCliTree(session.child).catch(() => false);
|
|
22740
|
+
if (current.interruptTimer) clearTimeout(current.interruptTimer);
|
|
22741
|
+
active.delete(threadId);
|
|
22742
|
+
if (stopped && !state.stopped) {
|
|
22743
|
+
rejectStartup(new TurnNotStartedError(turnId, message2));
|
|
22744
|
+
return;
|
|
22745
|
+
}
|
|
22746
|
+
acknowledge();
|
|
22747
|
+
if (!state.stopped) emit({ ...base2(threadId, turnId), type: "runtime.error", message: message2 });
|
|
22748
|
+
emit({
|
|
22749
|
+
...base2(threadId, turnId),
|
|
22750
|
+
type: "turn.completed",
|
|
22751
|
+
ok: state.stopped,
|
|
22752
|
+
stopReason: state.stopped ? "cancelled" : "rpc_error",
|
|
22753
|
+
cost: null
|
|
22754
|
+
});
|
|
22755
|
+
return;
|
|
22756
|
+
}
|
|
22478
22757
|
emit({
|
|
22479
22758
|
...base2(threadId, turnId),
|
|
22480
22759
|
type: "runtime.error",
|
|
@@ -22488,7 +22767,7 @@ ${promptInput.text}` : promptInput.text;
|
|
|
22488
22767
|
}
|
|
22489
22768
|
}
|
|
22490
22769
|
})();
|
|
22491
|
-
return { turnId };
|
|
22770
|
+
return startupAck ?? { turnId };
|
|
22492
22771
|
};
|
|
22493
22772
|
const snapshot = async () => {
|
|
22494
22773
|
const env = childEnv();
|
|
@@ -22544,6 +22823,9 @@ ${promptInput.text}` : promptInput.text;
|
|
|
22544
22823
|
stopAll: async () => {
|
|
22545
22824
|
for (const { stop } of active.values()) stop();
|
|
22546
22825
|
for (const threadId of Array.from(sessions.keys())) closeSession(threadId, "stopAll");
|
|
22826
|
+
for (const [threadId, children] of retiring) {
|
|
22827
|
+
for (const child of children) void retireChild(threadId, child);
|
|
22828
|
+
}
|
|
22547
22829
|
},
|
|
22548
22830
|
onEvent: (listener) => {
|
|
22549
22831
|
listeners.add(listener);
|
|
@@ -22553,13 +22835,16 @@ ${promptInput.text}` : promptInput.text;
|
|
|
22553
22835
|
dispose: async () => {
|
|
22554
22836
|
for (const { stop } of active.values()) stop();
|
|
22555
22837
|
for (const threadId of Array.from(sessions.keys())) closeSession(threadId, "dispose");
|
|
22838
|
+
for (const [threadId, children] of retiring) {
|
|
22839
|
+
for (const child of children) void retireChild(threadId, child);
|
|
22840
|
+
}
|
|
22556
22841
|
listeners.clear();
|
|
22557
22842
|
}
|
|
22558
22843
|
};
|
|
22559
22844
|
}
|
|
22560
22845
|
};
|
|
22561
22846
|
}
|
|
22562
|
-
var envOr, INIT_TIMEOUT, SESSION_CONFIG_TIMEOUT, NEW_SESSION_TIMEOUT, LOAD_SESSION_TIMEOUT, promptIdleTimeoutMs, CLIENT_FILE_MAX_BYTES, TOOL_LOG_TEXT_LIMIT;
|
|
22847
|
+
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
22848
|
var init_core3 = __esm({
|
|
22564
22849
|
"server/drivers/acp/core.ts"() {
|
|
22565
22850
|
"use strict";
|
|
@@ -22577,11 +22862,14 @@ var init_core3 = __esm({
|
|
|
22577
22862
|
init_mcp_tool_images();
|
|
22578
22863
|
init_redact2();
|
|
22579
22864
|
init_resume_recovery();
|
|
22865
|
+
init_session_idle();
|
|
22866
|
+
init_retry();
|
|
22580
22867
|
envOr = (key, fallback) => Number(process.env[key] ?? fallback);
|
|
22581
22868
|
INIT_TIMEOUT = envOr("OPENMAUS_ACP_INIT_TIMEOUT_MS", 3e5);
|
|
22582
22869
|
SESSION_CONFIG_TIMEOUT = envOr("OPENMAUS_ACP_SESSION_CONFIG_TIMEOUT_MS", 3e5);
|
|
22583
22870
|
NEW_SESSION_TIMEOUT = envOr("OPENMAUS_ACP_NEW_SESSION_TIMEOUT_MS", 3e5);
|
|
22584
22871
|
LOAD_SESSION_TIMEOUT = envOr("OPENMAUS_ACP_LOAD_SESSION_TIMEOUT_MS", 12e4);
|
|
22872
|
+
ACP_PROMPT_RE_ANCHOR_TURNS = 8;
|
|
22585
22873
|
promptIdleTimeoutMs = () => {
|
|
22586
22874
|
const raw = process.env.OPENMAUS_ACP_PROMPT_IDLE_TIMEOUT_MS;
|
|
22587
22875
|
if (raw === void 0) return 18e4;
|
|
@@ -23705,7 +23993,7 @@ function decodeConfig(raw) {
|
|
|
23705
23993
|
...typeof o.askTimeoutMs === "number" ? { askTimeoutMs: o.askTimeoutMs } : {}
|
|
23706
23994
|
};
|
|
23707
23995
|
}
|
|
23708
|
-
var DRIVER_KIND, BOX_API, MODELS,
|
|
23996
|
+
var DRIVER_KIND, BOX_API, MODELS, ASK_FENCE_ANY, catalog, providerFor, BoxAgentDriver;
|
|
23709
23997
|
var init_boxagent = __esm({
|
|
23710
23998
|
"server/drivers/boxagent.ts"() {
|
|
23711
23999
|
"use strict";
|
|
@@ -23722,17 +24010,6 @@ var init_boxagent = __esm({
|
|
|
23722
24010
|
{ id: "gpt-5.4", label: "GPT-5.4 (Codex) \xB7 on the box" }
|
|
23723
24011
|
]
|
|
23724
24012
|
};
|
|
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
24013
|
ASK_FENCE_ANY = /(^|\n)[ \t]{0,3}(`{3,}|~{3,})[ \t]*omb-ask\b/;
|
|
23737
24014
|
catalog = null;
|
|
23738
24015
|
providerFor = (model) => {
|
|
@@ -23793,7 +24070,7 @@ var init_boxagent = __esm({
|
|
|
23793
24070
|
const prompt = [
|
|
23794
24071
|
turn.system,
|
|
23795
24072
|
"You are working on the assigned cloud computer \u2014 use its desktop, Chrome, and shell within the access described above.",
|
|
23796
|
-
|
|
24073
|
+
ombAskProtocolPrompt(),
|
|
23797
24074
|
...correction ? [correction] : [],
|
|
23798
24075
|
"",
|
|
23799
24076
|
turn.text
|
|
@@ -23992,7 +24269,7 @@ var init_boxagent = __esm({
|
|
|
23992
24269
|
snapshot,
|
|
23993
24270
|
adapter: {
|
|
23994
24271
|
provider: DRIVER_KIND,
|
|
23995
|
-
capabilities: { sessionModelSwitch: "in-session" },
|
|
24272
|
+
capabilities: { sessionModelSwitch: "in-session", remoteAgent: true, usesCloudComputer: true },
|
|
23996
24273
|
sendTurn,
|
|
23997
24274
|
interruptTurn: async (threadId) => active.get(threadId)?.cancel(),
|
|
23998
24275
|
respondToRequest: async (threadId, requestId, decision) => {
|
|
@@ -24445,104 +24722,9 @@ var init_mcp_gate_config = __esm({
|
|
|
24445
24722
|
}
|
|
24446
24723
|
});
|
|
24447
24724
|
|
|
24448
|
-
// shared/provider-safety.ts
|
|
24449
|
-
function isProviderSafetyBlock(message2) {
|
|
24450
|
-
return /\bblocked by (?:our|the provider['’]s) safety systems\b|\bsafety monitoring\b.{0,100}\b(?:paused|ended|blocked)\b|\b(?:safety_check_failed|safety_policy_violation)\b/i.test(message2);
|
|
24451
|
-
}
|
|
24452
|
-
var init_provider_safety = __esm({
|
|
24453
|
-
"shared/provider-safety.ts"() {
|
|
24454
|
-
"use strict";
|
|
24455
|
-
}
|
|
24456
|
-
});
|
|
24457
|
-
|
|
24458
|
-
// server/drivers/retry.ts
|
|
24459
|
-
function classifyError(err) {
|
|
24460
|
-
const text4 = messageOf(err);
|
|
24461
|
-
if (isProviderSafetyBlock(text4)) return { transient: false, reason: "provider_safety" };
|
|
24462
|
-
if (err && "exitCode" in err) {
|
|
24463
|
-
const { exitCode: code } = err;
|
|
24464
|
-
if (code !== null && code < 0) return { transient: false, reason: "interrupted" };
|
|
24465
|
-
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
24466
|
-
if (pattern.test(text4)) return { transient: true, reason };
|
|
24467
|
-
}
|
|
24468
|
-
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
24469
|
-
if (pattern.test(text4)) return { transient: false, reason };
|
|
24470
|
-
}
|
|
24471
|
-
return { transient: false, reason: "terminal_exit" };
|
|
24472
|
-
}
|
|
24473
|
-
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
24474
|
-
if (pattern.test(text4)) return { transient: false, reason };
|
|
24475
|
-
}
|
|
24476
|
-
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
24477
|
-
if (pattern.test(text4)) return { transient: true, reason };
|
|
24478
|
-
}
|
|
24479
|
-
return { transient: false, reason: "unknown" };
|
|
24480
|
-
}
|
|
24481
|
-
function computeBackoff(attempt, random = Math.random) {
|
|
24482
|
-
const base2 = BACKOFF_BASE_MS[Math.min(Math.max(attempt, 0), BACKOFF_BASE_MS.length - 1)];
|
|
24483
|
-
const jitter = base2 * 0.25;
|
|
24484
|
-
return Math.round(base2 - jitter + random() * jitter * 2);
|
|
24485
|
-
}
|
|
24486
|
-
function interruptibleDelay(ms, signal) {
|
|
24487
|
-
let timer = null;
|
|
24488
|
-
let onCancel = null;
|
|
24489
|
-
const promise2 = new Promise((resolve12) => {
|
|
24490
|
-
timer = setTimeout(() => resolve12("elapsed"), Math.max(1, ms));
|
|
24491
|
-
timer.unref?.();
|
|
24492
|
-
if (signal?.aborted) return resolve12("cancelled");
|
|
24493
|
-
onCancel = () => {
|
|
24494
|
-
clearTimeout(timer);
|
|
24495
|
-
resolve12("cancelled");
|
|
24496
|
-
};
|
|
24497
|
-
signal?.addEventListener("abort", onCancel, { once: true });
|
|
24498
|
-
});
|
|
24499
|
-
return {
|
|
24500
|
-
promise: promise2,
|
|
24501
|
-
cancel: () => onCancel?.()
|
|
24502
|
-
};
|
|
24503
|
-
}
|
|
24504
|
-
var RETRY_MAX_ATTEMPTS, BACKOFF_BASE_MS, TRANSIENT_PATTERNS, TERMINAL_PATTERNS, messageOf;
|
|
24505
|
-
var init_retry = __esm({
|
|
24506
|
-
"server/drivers/retry.ts"() {
|
|
24507
|
-
"use strict";
|
|
24508
|
-
init_provider_safety();
|
|
24509
|
-
RETRY_MAX_ATTEMPTS = 3;
|
|
24510
|
-
BACKOFF_BASE_MS = [1e3, 3e3, 8e3];
|
|
24511
|
-
TRANSIENT_PATTERNS = [
|
|
24512
|
-
{ pattern: /\b(?:429|rate.?limit|too many requests)\b/i, reason: "rate_limited" },
|
|
24513
|
-
{ pattern: /\boverloaded\b|\bcapacity\b/i, reason: "overloaded" },
|
|
24514
|
-
{ pattern: /\b5\d{2}\b|\binternal server error\b|\bbad gateway\b|\bservice unavailable\b/i, reason: "server_error" },
|
|
24515
|
-
{
|
|
24516
|
-
pattern: /\b(?:econnreset|econnrefused|epipe|etimedout|eai_again|connection reset|connection refused|socket hang up|network error|fetch failed)\b/i,
|
|
24517
|
-
reason: "connection_reset"
|
|
24518
|
-
},
|
|
24519
|
-
{ pattern: /\btimeout(ed)?\b|\btimed? out\b/i, reason: "timeout" }
|
|
24520
|
-
];
|
|
24521
|
-
TERMINAL_PATTERNS = [
|
|
24522
|
-
{
|
|
24523
|
-
pattern: /\b(?:40[13]|unauthorized|forbidden|invalid api key|missing bearer|authentication required|not logged in|logged out)\b/i,
|
|
24524
|
-
reason: "auth"
|
|
24525
|
-
},
|
|
24526
|
-
{ pattern: /\b402\b|\bquota\b|\bbilling\b|\bsubscription\b/i, reason: "quota" },
|
|
24527
|
-
{ pattern: /\bmodel not found\b|\bunknown model\b|\bdoes not exist for model\b|\bunsupported model\b/i, reason: "unknown_model" },
|
|
24528
|
-
{ pattern: /\b400\b|\b422\b|\binvalid request\b|\bmalformed\b|\bunexpected status\b/i, reason: "invalid_request" },
|
|
24529
|
-
{ pattern: /\b404\b|\bno such thread\b|\bthread gone\b/i, reason: "not_found" },
|
|
24530
|
-
// interrupt/cancel vocabulary from the drivers' own stop paths — a turn the
|
|
24531
|
-
// user stopped must never come back as an auto-retry
|
|
24532
|
-
{ pattern: /\b(?:interrupted|cancelled by user)\b/i, reason: "interrupted" }
|
|
24533
|
-
];
|
|
24534
|
-
messageOf = (err) => {
|
|
24535
|
-
if (!err) return "";
|
|
24536
|
-
if (err instanceof Error) return `${err.message}${err.cause ? ` ${String(err.cause)}` : ""}`;
|
|
24537
|
-
if ("text" in err) return err.text;
|
|
24538
|
-
return [err.stderr ?? "", ""].join(" ").trim();
|
|
24539
|
-
};
|
|
24540
|
-
}
|
|
24541
|
-
});
|
|
24542
|
-
|
|
24543
24725
|
// server/drivers/claude.ts
|
|
24544
24726
|
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
|
|
24727
|
+
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
24728
|
import { createServer as createNetServer } from "node:net";
|
|
24547
24729
|
import { homedir as homedir9, tmpdir as tmpdir3 } from "node:os";
|
|
24548
24730
|
import { join as join21, dirname as dirname9, isAbsolute as isAbsolute5, normalize } from "node:path";
|
|
@@ -24584,6 +24766,10 @@ function claudeAuthFailure(frame, text4) {
|
|
|
24584
24766
|
if (frame.is_api_error_message !== true && typeof frame.error !== "string") return false;
|
|
24585
24767
|
return frame.error === "authentication_failed" || classifyError({ text: text4 }).reason === "auth";
|
|
24586
24768
|
}
|
|
24769
|
+
function claudeVersionTooOld(frame, text4) {
|
|
24770
|
+
if (frame.is_api_error_message !== true && typeof frame.error !== "string") return false;
|
|
24771
|
+
return /\bClaude Code v?\d+(?:\.\d+)+ does not support this model\b/i.test(text4);
|
|
24772
|
+
}
|
|
24587
24773
|
function claudeEnvironment(model, source = process.env, configDir, instanceEnvironment = {}) {
|
|
24588
24774
|
const env = { ...source, PATH: augmentedPath(), NPM_CONFIG_LOGLEVEL: "error" };
|
|
24589
24775
|
if (configDir?.trim()) {
|
|
@@ -24655,15 +24841,7 @@ function autoCompactWindow(env) {
|
|
|
24655
24841
|
return String(Math.min(1e6, Math.max(1e5, Math.floor(parsed))));
|
|
24656
24842
|
}
|
|
24657
24843
|
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;
|
|
24844
|
+
return parseVersionTriple(stdout2 ?? "");
|
|
24667
24845
|
}
|
|
24668
24846
|
function claudeCliSupports(version2, flag) {
|
|
24669
24847
|
return version2 === null || versionAtLeast(version2, CLAUDE_FLAG_FLOORS[flag]);
|
|
@@ -24731,7 +24909,7 @@ function readClaudeModelCatalog(env = process.env) {
|
|
|
24731
24909
|
function removePrivateTempDir(filePath) {
|
|
24732
24910
|
if (!filePath) return true;
|
|
24733
24911
|
try {
|
|
24734
|
-
|
|
24912
|
+
rmSync6(dirname9(filePath), { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
|
|
24735
24913
|
return true;
|
|
24736
24914
|
} catch {
|
|
24737
24915
|
return false;
|
|
@@ -25026,6 +25204,8 @@ var init_claude = __esm({
|
|
|
25026
25204
|
init_contracts();
|
|
25027
25205
|
init_tool_summary();
|
|
25028
25206
|
init_retry();
|
|
25207
|
+
init_session_idle();
|
|
25208
|
+
init_core3();
|
|
25029
25209
|
init_local_inject();
|
|
25030
25210
|
init_native();
|
|
25031
25211
|
init_permission_command();
|
|
@@ -25124,9 +25304,7 @@ var init_claude = __esm({
|
|
|
25124
25304
|
const listeners = /* @__PURE__ */ new Set();
|
|
25125
25305
|
const active = /* @__PURE__ */ new Map();
|
|
25126
25306
|
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);
|
|
25307
|
+
const { idleMs: SESSION_IDLE_MS } = sessionIdlePolicy("CLAUDE");
|
|
25130
25308
|
const stopSession = (session) => {
|
|
25131
25309
|
void killCliTree(session.child).then((stopped) => {
|
|
25132
25310
|
if (stopped) void session.finishClose?.();
|
|
@@ -25387,7 +25565,7 @@ var init_claude = __esm({
|
|
|
25387
25565
|
retryState.delete(threadId);
|
|
25388
25566
|
if (mcpConfigPath) {
|
|
25389
25567
|
try {
|
|
25390
|
-
|
|
25568
|
+
rmSync6(dirname9(mcpConfigPath), { recursive: true, force: true });
|
|
25391
25569
|
} catch {
|
|
25392
25570
|
}
|
|
25393
25571
|
}
|
|
@@ -25395,7 +25573,7 @@ var init_claude = __esm({
|
|
|
25395
25573
|
}
|
|
25396
25574
|
if (mcpConfigPath) {
|
|
25397
25575
|
try {
|
|
25398
|
-
|
|
25576
|
+
rmSync6(dirname9(mcpConfigPath), { recursive: true, force: true });
|
|
25399
25577
|
} catch {
|
|
25400
25578
|
}
|
|
25401
25579
|
}
|
|
@@ -25407,7 +25585,7 @@ var init_claude = __esm({
|
|
|
25407
25585
|
broker = void 0;
|
|
25408
25586
|
if (mcpConfigPath) {
|
|
25409
25587
|
try {
|
|
25410
|
-
|
|
25588
|
+
rmSync6(dirname9(mcpConfigPath), { recursive: true, force: true });
|
|
25411
25589
|
} catch {
|
|
25412
25590
|
}
|
|
25413
25591
|
mcpConfigPath = null;
|
|
@@ -25524,7 +25702,7 @@ var init_claude = __esm({
|
|
|
25524
25702
|
session.broker?.pause();
|
|
25525
25703
|
if (session.mcpConfigPath) {
|
|
25526
25704
|
try {
|
|
25527
|
-
|
|
25705
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25528
25706
|
} catch {
|
|
25529
25707
|
}
|
|
25530
25708
|
session.mcpConfigPath = null;
|
|
@@ -25535,6 +25713,7 @@ var init_claude = __esm({
|
|
|
25535
25713
|
active.delete(threadId);
|
|
25536
25714
|
session.turn = null;
|
|
25537
25715
|
retryState.delete(threadId);
|
|
25716
|
+
if (stopReason === "update_required") closeSession(threadId, "update required");
|
|
25538
25717
|
emit({ ...base2(threadId, t2.turnId), type: "turn.completed", ok, stopReason, cost, ...usage ? { usage } : {} });
|
|
25539
25718
|
if (session.child.exitCode === null && !session.closing) armIdle(threadId);
|
|
25540
25719
|
};
|
|
@@ -25580,6 +25759,11 @@ var init_claude = __esm({
|
|
|
25580
25759
|
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message: text4, setup: true });
|
|
25581
25760
|
break;
|
|
25582
25761
|
}
|
|
25762
|
+
if (claudeVersionTooOld(o, text4)) {
|
|
25763
|
+
if (session.turn) session.turn.updateRequired = true;
|
|
25764
|
+
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message: text4, setup: true, claudeUpdate: true });
|
|
25765
|
+
break;
|
|
25766
|
+
}
|
|
25583
25767
|
if (text4.trim()) {
|
|
25584
25768
|
const synthetic = o.is_api_error_message === true || typeof o.error === "string" ? { synthetic: true } : {};
|
|
25585
25769
|
if (!session.turn?.sawStreamDelta) {
|
|
@@ -25629,7 +25813,7 @@ var init_claude = __esm({
|
|
|
25629
25813
|
if (o.origin?.kind === "task-notification") break;
|
|
25630
25814
|
settle(
|
|
25631
25815
|
o.is_error !== true,
|
|
25632
|
-
session.turn?.authFailed ? "auth_required" : o.stop_reason ?? o.terminal_reason ?? null,
|
|
25816
|
+
session.turn?.authFailed ? "auth_required" : session.turn?.updateRequired ? "update_required" : o.stop_reason ?? o.terminal_reason ?? null,
|
|
25633
25817
|
o.total_cost_usd ?? null,
|
|
25634
25818
|
o.usage ? {
|
|
25635
25819
|
input: (o.usage.input_tokens || 0) + (o.usage.cache_read_input_tokens || 0) + (o.usage.cache_creation_input_tokens || 0),
|
|
@@ -25684,7 +25868,7 @@ var init_claude = __esm({
|
|
|
25684
25868
|
failedBroker?.close();
|
|
25685
25869
|
if (session.mcpConfigPath) {
|
|
25686
25870
|
try {
|
|
25687
|
-
|
|
25871
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25688
25872
|
} catch {
|
|
25689
25873
|
}
|
|
25690
25874
|
session.mcpConfigPath = null;
|
|
@@ -25762,7 +25946,7 @@ var init_claude = __esm({
|
|
|
25762
25946
|
session.broker = void 0;
|
|
25763
25947
|
if (session.mcpConfigPath) {
|
|
25764
25948
|
try {
|
|
25765
|
-
|
|
25949
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25766
25950
|
} catch {
|
|
25767
25951
|
}
|
|
25768
25952
|
session.mcpConfigPath = null;
|
|
@@ -25814,7 +25998,7 @@ var init_claude = __esm({
|
|
|
25814
25998
|
session.broker?.close();
|
|
25815
25999
|
if (session.mcpConfigPath) {
|
|
25816
26000
|
try {
|
|
25817
|
-
|
|
26001
|
+
rmSync6(dirname9(session.mcpConfigPath), { recursive: true, force: true });
|
|
25818
26002
|
} catch {
|
|
25819
26003
|
}
|
|
25820
26004
|
}
|
|
@@ -26028,9 +26212,9 @@ function mcpServerNamesInToml(toml) {
|
|
|
26028
26212
|
return names;
|
|
26029
26213
|
}
|
|
26030
26214
|
function codexConfigMcpServerNames(env) {
|
|
26031
|
-
const
|
|
26215
|
+
const codexHome2 = env.CODEX_HOME || join22(env.HOME || env.USERPROFILE || homedir10(), ".codex");
|
|
26032
26216
|
try {
|
|
26033
|
-
return mcpServerNamesInToml(readFileSync9(join22(
|
|
26217
|
+
return mcpServerNamesInToml(readFileSync9(join22(codexHome2, "config.toml"), "utf8"));
|
|
26034
26218
|
} catch {
|
|
26035
26219
|
return /* @__PURE__ */ new Set();
|
|
26036
26220
|
}
|
|
@@ -26049,10 +26233,124 @@ var init_codex_mcp_names = __esm({
|
|
|
26049
26233
|
}
|
|
26050
26234
|
});
|
|
26051
26235
|
|
|
26236
|
+
// server/drivers/codex-identity.ts
|
|
26237
|
+
import { homedir as homedir11 } from "node:os";
|
|
26238
|
+
import { isAbsolute as isAbsolute6, join as join23, resolve as resolve7 } from "node:path";
|
|
26239
|
+
function codexHome(env) {
|
|
26240
|
+
if (env.CODEX_HOME) return isAbsolute6(env.CODEX_HOME) ? resolve7(env.CODEX_HOME) : null;
|
|
26241
|
+
const home = userHome(env);
|
|
26242
|
+
return isAbsolute6(home) ? join23(home, ".codex") : null;
|
|
26243
|
+
}
|
|
26244
|
+
async function codexAccountEmail(cli, env, timeoutMs = 3e3) {
|
|
26245
|
+
const cwd = env.HOME || env.USERPROFILE || homedir11();
|
|
26246
|
+
if (!isAbsolute6(cwd) || !codexHome(env)) return null;
|
|
26247
|
+
return new Promise((resolveEmail) => {
|
|
26248
|
+
let child;
|
|
26249
|
+
try {
|
|
26250
|
+
child = spawnCli(cli, ["app-server"], { cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
26251
|
+
} catch {
|
|
26252
|
+
resolveEmail(null);
|
|
26253
|
+
return;
|
|
26254
|
+
}
|
|
26255
|
+
let finishing = false;
|
|
26256
|
+
let buffer = "";
|
|
26257
|
+
let outputBytes = 0;
|
|
26258
|
+
let initialized = false;
|
|
26259
|
+
const finish = async (email3) => {
|
|
26260
|
+
if (finishing) return;
|
|
26261
|
+
finishing = true;
|
|
26262
|
+
clearTimeout(timer);
|
|
26263
|
+
let stopped = await killCliTree(child, 1e3);
|
|
26264
|
+
if (!stopped && child.pid) {
|
|
26265
|
+
try {
|
|
26266
|
+
if (process.platform === "win32") child.kill("SIGKILL");
|
|
26267
|
+
else process.kill(-child.pid, "SIGKILL");
|
|
26268
|
+
} catch {
|
|
26269
|
+
try {
|
|
26270
|
+
child.kill("SIGKILL");
|
|
26271
|
+
} catch {
|
|
26272
|
+
}
|
|
26273
|
+
}
|
|
26274
|
+
stopped = await killCliTree(child, 1e3);
|
|
26275
|
+
}
|
|
26276
|
+
resolveEmail(stopped ? email3 : null);
|
|
26277
|
+
};
|
|
26278
|
+
const timer = setTimeout(() => {
|
|
26279
|
+
void finish(null);
|
|
26280
|
+
}, timeoutMs);
|
|
26281
|
+
timer.unref();
|
|
26282
|
+
const send = (message2) => {
|
|
26283
|
+
try {
|
|
26284
|
+
child.stdin.write(`${JSON.stringify(message2)}
|
|
26285
|
+
`);
|
|
26286
|
+
} catch {
|
|
26287
|
+
void finish(null);
|
|
26288
|
+
}
|
|
26289
|
+
};
|
|
26290
|
+
child.stdin.on("error", () => {
|
|
26291
|
+
void finish(null);
|
|
26292
|
+
});
|
|
26293
|
+
child.stderr.resume();
|
|
26294
|
+
child.on("error", () => {
|
|
26295
|
+
void finish(null);
|
|
26296
|
+
});
|
|
26297
|
+
child.on("close", () => {
|
|
26298
|
+
void finish(null);
|
|
26299
|
+
});
|
|
26300
|
+
child.stdout.setEncoding("utf8");
|
|
26301
|
+
child.stdout.on("data", (chunk) => {
|
|
26302
|
+
if (finishing) return;
|
|
26303
|
+
outputBytes += Buffer.byteLength(chunk);
|
|
26304
|
+
if (outputBytes > MAX_OUTPUT3) {
|
|
26305
|
+
void finish(null);
|
|
26306
|
+
return;
|
|
26307
|
+
}
|
|
26308
|
+
buffer += chunk;
|
|
26309
|
+
let newline;
|
|
26310
|
+
while (!finishing && (newline = buffer.indexOf("\n")) !== -1) {
|
|
26311
|
+
const line = buffer.slice(0, newline);
|
|
26312
|
+
buffer = buffer.slice(newline + 1);
|
|
26313
|
+
if (!line.trim()) continue;
|
|
26314
|
+
let message2;
|
|
26315
|
+
try {
|
|
26316
|
+
message2 = JSON.parse(line);
|
|
26317
|
+
} catch {
|
|
26318
|
+
void finish(null);
|
|
26319
|
+
return;
|
|
26320
|
+
}
|
|
26321
|
+
if (!initialized && message2?.id === 1) {
|
|
26322
|
+
if (message2.error || !message2.result) {
|
|
26323
|
+
void finish(null);
|
|
26324
|
+
return;
|
|
26325
|
+
}
|
|
26326
|
+
initialized = true;
|
|
26327
|
+
send({ method: "initialized", params: {} });
|
|
26328
|
+
send({ id: 2, method: "account/read", params: { refreshToken: false } });
|
|
26329
|
+
} else if (initialized && message2?.id === 2) {
|
|
26330
|
+
const account = message2.error ? null : message2.result?.account;
|
|
26331
|
+
const email3 = account?.type === "chatgpt" ? account.email : null;
|
|
26332
|
+
void finish(typeof email3 === "string" && email3.length <= 254 && EMAIL.test(email3) && !/[\p{Cc}\p{Cf}]/u.test(email3) ? email3 : null);
|
|
26333
|
+
}
|
|
26334
|
+
}
|
|
26335
|
+
});
|
|
26336
|
+
send({ id: 1, method: "initialize", params: { clientInfo: { name: "openmausbot", version: "1" } } });
|
|
26337
|
+
});
|
|
26338
|
+
}
|
|
26339
|
+
var MAX_OUTPUT3, EMAIL;
|
|
26340
|
+
var init_codex_identity = __esm({
|
|
26341
|
+
"server/drivers/codex-identity.ts"() {
|
|
26342
|
+
"use strict";
|
|
26343
|
+
init_env_path();
|
|
26344
|
+
init_procs();
|
|
26345
|
+
MAX_OUTPUT3 = 16384;
|
|
26346
|
+
EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
26347
|
+
}
|
|
26348
|
+
});
|
|
26349
|
+
|
|
26052
26350
|
// server/drivers/codex-catalog.ts
|
|
26053
26351
|
import { readdirSync as readdirSync2, readFileSync as readFileSync10 } from "node:fs";
|
|
26054
|
-
import { homedir as
|
|
26055
|
-
import { basename as basename7, join as
|
|
26352
|
+
import { homedir as homedir12 } from "node:os";
|
|
26353
|
+
import { basename as basename7, join as join24 } from "node:path";
|
|
26056
26354
|
function encodeCodexSelection(provider, model) {
|
|
26057
26355
|
return `${provider}${SEP}${model}`;
|
|
26058
26356
|
}
|
|
@@ -26067,7 +26365,7 @@ function decodeCodexSelection(id) {
|
|
|
26067
26365
|
function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
|
|
26068
26366
|
return new Promise((resolve12) => {
|
|
26069
26367
|
const child = spawnCli(cli, ["app-server"], {
|
|
26070
|
-
cwd:
|
|
26368
|
+
cwd: homedir12(),
|
|
26071
26369
|
env,
|
|
26072
26370
|
stdio: ["pipe", "pipe", "pipe"]
|
|
26073
26371
|
});
|
|
@@ -26166,10 +26464,6 @@ function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
|
|
|
26166
26464
|
request("initialize", { clientInfo: { name: "openmausbot", version: "1" } }, "initialize");
|
|
26167
26465
|
});
|
|
26168
26466
|
}
|
|
26169
|
-
function codexHome(env) {
|
|
26170
|
-
if (env.CODEX_HOME) return env.CODEX_HOME;
|
|
26171
|
-
return join23(env.HOME || env.USERPROFILE || homedir11(), ".codex");
|
|
26172
|
-
}
|
|
26173
26467
|
function unquote(raw) {
|
|
26174
26468
|
let value = raw.trim();
|
|
26175
26469
|
const hash2 = value.indexOf(" #");
|
|
@@ -26250,15 +26544,18 @@ function niceLabel(model, provider, known, named) {
|
|
|
26250
26544
|
const encoded = encodeCodexSelection(provider, model);
|
|
26251
26545
|
if (named.has(encoded)) return named.get(encoded);
|
|
26252
26546
|
const host = providerName(provider, known);
|
|
26253
|
-
return
|
|
26547
|
+
return qualifiedModelLabel(model, host, {
|
|
26548
|
+
redundantWhen: () => host === provider,
|
|
26549
|
+
decorate: (facet) => ` (${facet})`
|
|
26550
|
+
});
|
|
26254
26551
|
}
|
|
26255
26552
|
function collectCatalogNames(home) {
|
|
26256
26553
|
const named = /* @__PURE__ */ new Map();
|
|
26257
|
-
for (const file2 of listDir(
|
|
26554
|
+
for (const file2 of listDir(join24(home, "model-catalogs"))) {
|
|
26258
26555
|
if (!file2.endsWith(".json")) continue;
|
|
26259
26556
|
const provider = basename7(file2, ".json").replace(/-models$/, "");
|
|
26260
26557
|
if (!PROVIDER_ID.test(provider)) continue;
|
|
26261
|
-
const raw = readText(
|
|
26558
|
+
const raw = readText(join24(home, "model-catalogs", file2));
|
|
26262
26559
|
if (!raw) continue;
|
|
26263
26560
|
let parsed;
|
|
26264
26561
|
try {
|
|
@@ -26310,7 +26607,8 @@ async function probeProviderModels(provider, env, fetchImpl) {
|
|
|
26310
26607
|
async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli) {
|
|
26311
26608
|
const official = (cli ? await readCodexAppServerModelCatalog(cli, env) : null) ?? STATIC_CODEX_MODELS;
|
|
26312
26609
|
const home = codexHome(env);
|
|
26313
|
-
|
|
26610
|
+
if (!home) return mergeLocalInject(official, env, fetchImpl);
|
|
26611
|
+
const mainText = readText(join24(home, "config.toml"));
|
|
26314
26612
|
if (!mainText) return mergeLocalInject(official, env, fetchImpl);
|
|
26315
26613
|
const main2 = parseCodexToml(mainText);
|
|
26316
26614
|
const known = new Map(main2.providers.map((provider) => [provider.id, provider]));
|
|
@@ -26325,7 +26623,7 @@ async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli)
|
|
|
26325
26623
|
remember(main2.modelProvider, main2.model);
|
|
26326
26624
|
for (const file2 of listDir(home)) {
|
|
26327
26625
|
if (!file2.endsWith(".config.toml")) continue;
|
|
26328
|
-
const profile = parseCodexToml(readText(
|
|
26626
|
+
const profile = parseCodexToml(readText(join24(home, file2)) ?? "");
|
|
26329
26627
|
for (const provider of profile.providers) {
|
|
26330
26628
|
if (!known.has(provider.id)) known.set(provider.id, provider);
|
|
26331
26629
|
}
|
|
@@ -26368,11 +26666,17 @@ var STATIC_CODEX_MODELS, OFFICIAL_CODEX_PROVIDER, SEP, MODEL_ID2, PROVIDER_ID;
|
|
|
26368
26666
|
var init_codex_catalog = __esm({
|
|
26369
26667
|
"server/drivers/codex-catalog.ts"() {
|
|
26370
26668
|
"use strict";
|
|
26669
|
+
init_contracts();
|
|
26371
26670
|
init_procs();
|
|
26671
|
+
init_codex_identity();
|
|
26372
26672
|
init_local_inject();
|
|
26373
26673
|
STATIC_CODEX_MODELS = {
|
|
26374
26674
|
default: "gpt-5.6-sol",
|
|
26375
26675
|
options: [
|
|
26676
|
+
// Only used when live discovery fails; these rows do not establish account access.
|
|
26677
|
+
{ id: "gpt-6-astra", label: "GPT-6 Astra (availability unverified)" },
|
|
26678
|
+
{ id: "gpt-6-sol", label: "GPT-6 Sol (availability unverified)" },
|
|
26679
|
+
{ id: "gpt-6-luna", label: "GPT-6 Luna (availability unverified)" },
|
|
26376
26680
|
{ id: "gpt-5.6-sol", label: "GPT-5.6 Sol" },
|
|
26377
26681
|
{ id: "gpt-5.6-terra", label: "GPT-5.6 Terra" },
|
|
26378
26682
|
{ id: "gpt-5.6-luna", label: "GPT-5.6 Luna" },
|
|
@@ -26392,7 +26696,7 @@ var init_codex_catalog = __esm({
|
|
|
26392
26696
|
// server/drivers/codex-instructions.ts
|
|
26393
26697
|
import { createHash as createHash8 } from "node:crypto";
|
|
26394
26698
|
import { mkdirSync as mkdirSync11, readFileSync as readFileSync11 } from "node:fs";
|
|
26395
|
-
import { join as
|
|
26699
|
+
import { join as join25 } from "node:path";
|
|
26396
26700
|
function parseReceipt(raw) {
|
|
26397
26701
|
if (!raw) return null;
|
|
26398
26702
|
const trimmed = raw.trim();
|
|
@@ -26425,8 +26729,8 @@ function codexDeveloperInstructions(config2, botInstructions) {
|
|
|
26425
26729
|
${configured}` : botInstructions;
|
|
26426
26730
|
}
|
|
26427
26731
|
async function syncCodexInstructions(key, nativeThreadId, instructions, volatile, resumed, request, mentionTurn = false) {
|
|
26428
|
-
const directory =
|
|
26429
|
-
const path3 =
|
|
26732
|
+
const directory = join25(DATA_DIR, "codex-instructions");
|
|
26733
|
+
const path3 = join25(directory, `${digest2(JSON.stringify([key, nativeThreadId]))}.sha256`);
|
|
26430
26734
|
const fingerprint = digest2(instructions);
|
|
26431
26735
|
const volatileFingerprint = digest2(volatile);
|
|
26432
26736
|
let previous;
|
|
@@ -26482,15 +26786,15 @@ var init_codex_instructions = __esm({
|
|
|
26482
26786
|
// server/drivers/codex-device-auth.ts
|
|
26483
26787
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
26484
26788
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
26485
|
-
import { homedir as
|
|
26486
|
-
import { basename as basename8, dirname as dirname10, isAbsolute as
|
|
26789
|
+
import { homedir as homedir13 } from "node:os";
|
|
26790
|
+
import { basename as basename8, dirname as dirname10, isAbsolute as isAbsolute7, join as join26, resolve as resolve8 } from "node:path";
|
|
26487
26791
|
import { stripVTControlCharacters as stripVTControlCharacters5 } from "node:util";
|
|
26488
26792
|
function canonicalPath2(path3) {
|
|
26489
26793
|
try {
|
|
26490
26794
|
return realpathSync3(path3);
|
|
26491
26795
|
} catch {
|
|
26492
26796
|
const parent = dirname10(path3);
|
|
26493
|
-
return parent === path3 ? path3 :
|
|
26797
|
+
return parent === path3 ? path3 : join26(canonicalPath2(parent), basename8(path3));
|
|
26494
26798
|
}
|
|
26495
26799
|
}
|
|
26496
26800
|
function codexDevicePrompt(output) {
|
|
@@ -26512,13 +26816,13 @@ function loginFailure(output) {
|
|
|
26512
26816
|
}
|
|
26513
26817
|
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
26818
|
}
|
|
26515
|
-
var DEVICE_URL,
|
|
26819
|
+
var DEVICE_URL, MAX_OUTPUT4, authenticatingHomes2, CodexDeviceAuthController;
|
|
26516
26820
|
var init_codex_device_auth = __esm({
|
|
26517
26821
|
"server/drivers/codex-device-auth.ts"() {
|
|
26518
26822
|
"use strict";
|
|
26519
26823
|
init_procs();
|
|
26520
26824
|
DEVICE_URL = "https://auth.openai.com/codex/device";
|
|
26521
|
-
|
|
26825
|
+
MAX_OUTPUT4 = 16384;
|
|
26522
26826
|
authenticatingHomes2 = /* @__PURE__ */ new Set();
|
|
26523
26827
|
CodexDeviceAuthController = class {
|
|
26524
26828
|
flow = null;
|
|
@@ -26537,11 +26841,11 @@ var init_codex_device_auth = __esm({
|
|
|
26537
26841
|
await this.flow?.stopping;
|
|
26538
26842
|
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
26539
26843
|
const env = this.options.environment();
|
|
26540
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
26541
|
-
if (!
|
|
26844
|
+
const home = env.HOME || env.USERPROFILE || homedir13();
|
|
26845
|
+
if (!isAbsolute7(home) || env.CODEX_HOME && !isAbsolute7(env.CODEX_HOME)) {
|
|
26542
26846
|
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing in.");
|
|
26543
26847
|
}
|
|
26544
|
-
const homeKey = canonicalPath2(
|
|
26848
|
+
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join26(home, ".codex")));
|
|
26545
26849
|
if (authenticatingHomes2.has(homeKey)) {
|
|
26546
26850
|
throw new Error("A ChatGPT sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
26547
26851
|
}
|
|
@@ -26616,11 +26920,11 @@ var init_codex_device_auth = __esm({
|
|
|
26616
26920
|
await this.flow?.stopping;
|
|
26617
26921
|
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
26618
26922
|
const env = this.options.environment();
|
|
26619
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
26620
|
-
if (!
|
|
26923
|
+
const home = env.HOME || env.USERPROFILE || homedir13();
|
|
26924
|
+
if (!isAbsolute7(home) || env.CODEX_HOME && !isAbsolute7(env.CODEX_HOME)) {
|
|
26621
26925
|
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing out.");
|
|
26622
26926
|
}
|
|
26623
|
-
const homeKey = canonicalPath2(
|
|
26927
|
+
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join26(home, ".codex")));
|
|
26624
26928
|
if (authenticatingHomes2.has(homeKey)) {
|
|
26625
26929
|
throw new Error("A ChatGPT sign-in is running for this server account. Finish or cancel it before signing out.");
|
|
26626
26930
|
}
|
|
@@ -26663,7 +26967,7 @@ var init_codex_device_auth = __esm({
|
|
|
26663
26967
|
child.stdin.end();
|
|
26664
26968
|
let output = "";
|
|
26665
26969
|
const receive = (chunk) => {
|
|
26666
|
-
if (output.length <
|
|
26970
|
+
if (output.length < MAX_OUTPUT4) output += chunk.toString("utf8").slice(0, MAX_OUTPUT4 - output.length);
|
|
26667
26971
|
};
|
|
26668
26972
|
child.stdout.on("data", receive);
|
|
26669
26973
|
child.stderr.on("data", receive);
|
|
@@ -26698,7 +27002,7 @@ var init_codex_device_auth = __esm({
|
|
|
26698
27002
|
let output = "";
|
|
26699
27003
|
const receive = (chunk) => {
|
|
26700
27004
|
if (flow.status.phase !== "waiting") return;
|
|
26701
|
-
if (output.length + chunk.length >
|
|
27005
|
+
if (output.length + chunk.length > MAX_OUTPUT4) {
|
|
26702
27006
|
this.finish(flow, "failed", "Codex returned an unexpected sign-in response. Update the server's Codex CLI and try again.");
|
|
26703
27007
|
return;
|
|
26704
27008
|
}
|
|
@@ -26777,116 +27081,51 @@ var init_codex_device_auth = __esm({
|
|
|
26777
27081
|
}
|
|
26778
27082
|
});
|
|
26779
27083
|
|
|
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;
|
|
27084
|
+
// server/drivers/codex-release.ts
|
|
27085
|
+
function parseCodexReleaseVersion(value) {
|
|
27086
|
+
const match = /^(?:.*\bcodex-cli\s+)?v?(\d+)\.(\d+)\.(\d+)(-[0-9a-z.-]+)?(?:\+[0-9a-z.-]+)?$/i.exec(value.trim());
|
|
27087
|
+
return match ? { parts: match.slice(1, 4).map(Number), prerelease: Boolean(match[4]) } : null;
|
|
26787
27088
|
}
|
|
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) => {
|
|
27089
|
+
function codexVersionBehind(installed, latest) {
|
|
27090
|
+
const a2 = parseCodexReleaseVersion(installed);
|
|
27091
|
+
const b2 = parseCodexReleaseVersion(latest);
|
|
27092
|
+
if (!a2 || !b2 || b2.prerelease) return false;
|
|
27093
|
+
for (let i2 = 0; i2 < 3; i2++) {
|
|
27094
|
+
if (a2.parts[i2] !== b2.parts[i2]) return a2.parts[i2] < b2.parts[i2];
|
|
27095
|
+
}
|
|
27096
|
+
return a2.prerelease;
|
|
27097
|
+
}
|
|
27098
|
+
function createCodexReleaseReader(fetchImpl = fetch, now = Date.now) {
|
|
27099
|
+
let cached3;
|
|
27100
|
+
let expires = 0;
|
|
27101
|
+
return () => {
|
|
27102
|
+
if (cached3 && now() < expires) return cached3;
|
|
27103
|
+
expires = now() + 60 * 60 * 1e3;
|
|
27104
|
+
cached3 = (async () => {
|
|
26827
27105
|
try {
|
|
26828
|
-
|
|
26829
|
-
|
|
27106
|
+
const response = await fetchImpl("https://registry.npmjs.org/@openai/codex/latest", {
|
|
27107
|
+
signal: AbortSignal.timeout(3e3),
|
|
27108
|
+
headers: { Accept: "application/json" }
|
|
27109
|
+
});
|
|
27110
|
+
if (!response.ok) throw new Error("Release lookup failed");
|
|
27111
|
+
const payload = await response.json();
|
|
27112
|
+
const version2 = typeof payload.version === "string" ? payload.version : "";
|
|
27113
|
+
const parsed = parseCodexReleaseVersion(version2);
|
|
27114
|
+
if (!parsed || parsed.prerelease) throw new Error("Invalid stable release");
|
|
27115
|
+
return version2;
|
|
26830
27116
|
} 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
|
-
}
|
|
27117
|
+
expires = now() + 5 * 60 * 1e3;
|
|
27118
|
+
return null;
|
|
26878
27119
|
}
|
|
26879
|
-
});
|
|
26880
|
-
|
|
26881
|
-
}
|
|
27120
|
+
})();
|
|
27121
|
+
return cached3;
|
|
27122
|
+
};
|
|
26882
27123
|
}
|
|
26883
|
-
var
|
|
26884
|
-
var
|
|
26885
|
-
"server/drivers/codex-
|
|
27124
|
+
var readLatestCodexRelease;
|
|
27125
|
+
var init_codex_release = __esm({
|
|
27126
|
+
"server/drivers/codex-release.ts"() {
|
|
26886
27127
|
"use strict";
|
|
26887
|
-
|
|
26888
|
-
MAX_OUTPUT4 = 16384;
|
|
26889
|
-
EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
27128
|
+
readLatestCodexRelease = createCodexReleaseReader();
|
|
26890
27129
|
}
|
|
26891
27130
|
});
|
|
26892
27131
|
|
|
@@ -26896,18 +27135,6 @@ import { homedir as homedir14 } from "node:os";
|
|
|
26896
27135
|
function missingNativeCodexThread(error51, cursor3) {
|
|
26897
27136
|
return error51 instanceof CodexRpcError && error51.code === -32600 && error51.message === `no rollout found for thread id ${cursor3}`;
|
|
26898
27137
|
}
|
|
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
27138
|
function codexUpdateCommand(cli, platform = process.platform) {
|
|
26912
27139
|
if (cli === "codex") return "codex update";
|
|
26913
27140
|
const trimmed = cli.trim();
|
|
@@ -26916,13 +27143,12 @@ function codexUpdateCommand(cli, platform = process.platform) {
|
|
|
26916
27143
|
const command = (tokens.length > 0 ? tokens : [trimmed]).map(quote2).join(" ");
|
|
26917
27144
|
return platform === "win32" ? `& ${command} update` : `${command} update`;
|
|
26918
27145
|
}
|
|
26919
|
-
function
|
|
26920
|
-
|
|
26921
|
-
|
|
26922
|
-
}
|
|
27146
|
+
async function codexReleaseUpdate(version2, cli) {
|
|
27147
|
+
const latest = await readLatestCodexRelease();
|
|
27148
|
+
if (!latest || !codexVersionBehind(version2, latest)) return void 0;
|
|
26923
27149
|
return {
|
|
26924
|
-
title:
|
|
26925
|
-
message:
|
|
27150
|
+
title: `Update Codex to ${latest}`,
|
|
27151
|
+
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
27152
|
command: codexUpdateCommand(cli)
|
|
26927
27153
|
};
|
|
26928
27154
|
}
|
|
@@ -27224,7 +27450,7 @@ function mountMcpServer(appServerArgs, env, name, server, preApproved = true) {
|
|
|
27224
27450
|
appServerArgs.push("-c", `${prefix}.default_tools_approval_mode="auto"`);
|
|
27225
27451
|
}
|
|
27226
27452
|
}
|
|
27227
|
-
var DRIVER_KIND3,
|
|
27453
|
+
var DRIVER_KIND3, CodexRpcError, DENY_TIMEOUT_NOTE2, skippedSseServers, renamedMcpServers, plainRecord, containsControlCharacter, CodexDriver;
|
|
27228
27454
|
var init_codex = __esm({
|
|
27229
27455
|
"server/drivers/codex.ts"() {
|
|
27230
27456
|
"use strict";
|
|
@@ -27248,10 +27474,9 @@ var init_codex = __esm({
|
|
|
27248
27474
|
init_resume_recovery();
|
|
27249
27475
|
init_mcp_tool_images();
|
|
27250
27476
|
init_ask_question();
|
|
27477
|
+
init_codex_release();
|
|
27251
27478
|
init_codex_catalog();
|
|
27252
27479
|
DRIVER_KIND3 = "codex";
|
|
27253
|
-
ASTRA_MODEL_ID = "gpt-6-astra";
|
|
27254
|
-
ASTRA_MIN_CODEX_VERSION = [0, 153, 1];
|
|
27255
27480
|
CodexRpcError = class extends Error {
|
|
27256
27481
|
code;
|
|
27257
27482
|
constructor(error51) {
|
|
@@ -28090,7 +28315,7 @@ ${stderr ?? ""}`))
|
|
|
28090
28315
|
version: version2,
|
|
28091
28316
|
authenticated,
|
|
28092
28317
|
...email3 ? { account: { email: email3 } } : {},
|
|
28093
|
-
update:
|
|
28318
|
+
update: await codexReleaseUpdate(version2, config2.cli),
|
|
28094
28319
|
billing: "subscription"
|
|
28095
28320
|
};
|
|
28096
28321
|
};
|
|
@@ -37738,7 +37963,8 @@ function createOpenAIChatRuntime(options) {
|
|
|
37738
37963
|
const done = new Promise((resolve12) => {
|
|
37739
37964
|
resolveDone = resolve12;
|
|
37740
37965
|
});
|
|
37741
|
-
|
|
37966
|
+
const turnEntry = { abort, turnId, done, approval, asides: [] };
|
|
37967
|
+
active.set(turn.threadId, turnEntry);
|
|
37742
37968
|
emit({ ...base2(turn.threadId, turnId), type: "turn.started" });
|
|
37743
37969
|
emit({ ...base2(turn.threadId, turnId), type: "session.started", sessionId: null, model });
|
|
37744
37970
|
void (async () => {
|
|
@@ -37759,6 +37985,8 @@ function createOpenAIChatRuntime(options) {
|
|
|
37759
37985
|
}
|
|
37760
37986
|
for (let round = 0; round < 16; round++) {
|
|
37761
37987
|
abort.signal.throwIfAborted();
|
|
37988
|
+
const parked = turnEntry.asides.splice(0);
|
|
37989
|
+
if (parked.length) messages.push({ role: "user", content: parked.join("\n\n") });
|
|
37762
37990
|
native("out", options.nativeLog.outgoing(turn, messages, model));
|
|
37763
37991
|
let attempt = 0;
|
|
37764
37992
|
let completion;
|
|
@@ -37975,6 +38203,10 @@ function createOpenAIChatRuntime(options) {
|
|
|
37975
38203
|
capabilities: {
|
|
37976
38204
|
...options.computerUse ? {
|
|
37977
38205
|
computerMcp: options.tools !== false,
|
|
38206
|
+
// Same gate as cloudComputerMcp: with tools off the runtime cannot
|
|
38207
|
+
// mount the leased Box descriptor either. The fleet invariant test
|
|
38208
|
+
// pins usesCloudComputer === (remoteAgent || cloudComputerMcp).
|
|
38209
|
+
usesCloudComputer: options.tools !== false,
|
|
37978
38210
|
cloudComputerMcp: options.tools !== false,
|
|
37979
38211
|
localComputerMcp: options.tools !== false,
|
|
37980
38212
|
browserMcp: options.tools !== false,
|
|
@@ -37984,7 +38216,10 @@ function createOpenAIChatRuntime(options) {
|
|
|
37984
38216
|
sessionModelSwitch: "in-session",
|
|
37985
38217
|
customMcp: options.tools !== false,
|
|
37986
38218
|
agentsMcp: options.tools !== false,
|
|
37987
|
-
composioMcp: options.tools !== false
|
|
38219
|
+
composioMcp: options.tools !== false,
|
|
38220
|
+
// The runtime owns the whole tool loop, so it can always take a
|
|
38221
|
+
// user message mid-turn: park it, deliver before the next completion.
|
|
38222
|
+
queueing: true
|
|
37988
38223
|
},
|
|
37989
38224
|
sendTurn,
|
|
37990
38225
|
interruptTurn: async (threadId, turnId) => {
|
|
@@ -37994,6 +38229,12 @@ function createOpenAIChatRuntime(options) {
|
|
|
37994
38229
|
await turn.done;
|
|
37995
38230
|
},
|
|
37996
38231
|
respondToRequest: async (threadId, requestId, decision) => active.get(threadId)?.approval.answer(requestId, decision.behavior, decision.message) ?? "unavailable",
|
|
38232
|
+
steer: async (threadId, text4) => {
|
|
38233
|
+
const running2 = active.get(threadId);
|
|
38234
|
+
if (!running2) return "refused";
|
|
38235
|
+
running2.asides.push(text4);
|
|
38236
|
+
return "steered";
|
|
38237
|
+
},
|
|
37997
38238
|
hasSession: (threadId) => active.has(threadId),
|
|
37998
38239
|
stopAll: async () => {
|
|
37999
38240
|
const turns = [...active.values()];
|
|
@@ -38103,12 +38344,7 @@ var init_grok = __esm({
|
|
|
38103
38344
|
|
|
38104
38345
|
// server/drivers/acp/grok.ts
|
|
38105
38346
|
import { existsSync as existsSync11, readFileSync as readFileSync16, writeFileSync as writeFileSync9 } from "node:fs";
|
|
38106
|
-
import { homedir as homedir15 } from "node:os";
|
|
38107
38347
|
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
38348
|
function unquote2(raw) {
|
|
38113
38349
|
const value = raw.trim();
|
|
38114
38350
|
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
@@ -38117,7 +38353,7 @@ function unquote2(raw) {
|
|
|
38117
38353
|
return value;
|
|
38118
38354
|
}
|
|
38119
38355
|
function readGrokModelCatalog(env = process.env) {
|
|
38120
|
-
const path3 = join30(
|
|
38356
|
+
const path3 = join30(env.GROK_HOME || harnessHome("grok", env), "config.toml");
|
|
38121
38357
|
let text4 = "";
|
|
38122
38358
|
try {
|
|
38123
38359
|
text4 = readFileSync16(path3, "utf8");
|
|
@@ -38190,7 +38426,7 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
38190
38426
|
if (!inject) return modelId;
|
|
38191
38427
|
const host = localHost(inject.host);
|
|
38192
38428
|
if (!host) return modelId;
|
|
38193
|
-
const path3 = join30(
|
|
38429
|
+
const path3 = join30(env.GROK_HOME || harnessHome("grok", env), "config.toml");
|
|
38194
38430
|
let text4 = "";
|
|
38195
38431
|
try {
|
|
38196
38432
|
text4 = readFileSync16(path3, "utf8");
|
|
@@ -38257,6 +38493,7 @@ var STATIC_GROK_MODELS, SLUG, support2, GrokAgentDriver;
|
|
|
38257
38493
|
var init_grok2 = __esm({
|
|
38258
38494
|
"server/drivers/acp/grok.ts"() {
|
|
38259
38495
|
"use strict";
|
|
38496
|
+
init_env_path();
|
|
38260
38497
|
init_local_inject();
|
|
38261
38498
|
init_core3();
|
|
38262
38499
|
STATIC_GROK_MODELS = {
|
|
@@ -38337,7 +38574,7 @@ var init_grok2 = __esm({
|
|
|
38337
38574
|
// an unauthenticated CLI is a user action, not something to paper over.
|
|
38338
38575
|
pickAuthMethod: (methods) => methods.some((m2) => m2.id === "cached_token") ? "cached_token" : null,
|
|
38339
38576
|
authFailure: "fail",
|
|
38340
|
-
isAuthenticated: () => existsSync11(join30(
|
|
38577
|
+
isAuthenticated: (env) => existsSync11(join30(harnessHome("grok", env), "auth.json")),
|
|
38341
38578
|
// `--append-system-prompt`/`--rules` are accepted by the CLI but do NOT
|
|
38342
38579
|
// reach the agent-stdio system prompt (verified against 1.0.0), so the
|
|
38343
38580
|
// persona is prepended codex-style.
|
|
@@ -38351,11 +38588,10 @@ ${turn.text}` : turn.text
|
|
|
38351
38588
|
|
|
38352
38589
|
// server/drivers/acp/gemini.ts
|
|
38353
38590
|
import { existsSync as existsSync12, readFileSync as readFileSync17 } from "node:fs";
|
|
38354
|
-
import { homedir as homedir16 } from "node:os";
|
|
38355
38591
|
import { join as join31 } from "node:path";
|
|
38356
|
-
function liveOauthCredential() {
|
|
38592
|
+
function liveOauthCredential(env) {
|
|
38357
38593
|
try {
|
|
38358
|
-
const creds = JSON.parse(readFileSync17(join31(
|
|
38594
|
+
const creds = JSON.parse(readFileSync17(join31(userHome(env), ".gemini", "oauth_creds.json"), "utf8"));
|
|
38359
38595
|
if (typeof creds.access_token !== "string" || creds.access_token.trim().length === 0) return false;
|
|
38360
38596
|
const hasRefresh = typeof creds.refresh_token === "string" && creds.refresh_token.trim().length > 0;
|
|
38361
38597
|
if (creds.expiry_date !== void 0) {
|
|
@@ -38368,7 +38604,7 @@ function liveOauthCredential() {
|
|
|
38368
38604
|
}
|
|
38369
38605
|
}
|
|
38370
38606
|
function geminiIsAuthenticated(env) {
|
|
38371
|
-
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) || existsSync12(join31(
|
|
38607
|
+
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) || existsSync12(join31(userHome(env), ".gemini", "oauth_creds.json")) && liveOauthCredential(env);
|
|
38372
38608
|
}
|
|
38373
38609
|
function geminiApprovalArgs(fullAuto, approvalMode) {
|
|
38374
38610
|
if (fullAuto) return ["--yolo"];
|
|
@@ -38379,6 +38615,7 @@ var AUTH_PREFERENCE, nonBlank, support3, GeminiAgentDriver;
|
|
|
38379
38615
|
var init_gemini = __esm({
|
|
38380
38616
|
"server/drivers/acp/gemini.ts"() {
|
|
38381
38617
|
"use strict";
|
|
38618
|
+
init_env_path();
|
|
38382
38619
|
init_core3();
|
|
38383
38620
|
AUTH_PREFERENCE = ["gemini-api-key", "oauth-personal", "vertex-ai"];
|
|
38384
38621
|
nonBlank = (value) => Boolean(value?.trim());
|
|
@@ -38416,13 +38653,13 @@ ${turn.text}` : turn.text
|
|
|
38416
38653
|
|
|
38417
38654
|
// server/drivers/acp/kimi.ts
|
|
38418
38655
|
import { existsSync as existsSync13, mkdirSync as mkdirSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync10 } from "node:fs";
|
|
38419
|
-
import { homedir as
|
|
38656
|
+
import { homedir as homedir15 } from "node:os";
|
|
38420
38657
|
import { join as join32 } from "node:path";
|
|
38421
38658
|
function isLocalInjectAlias(slug) {
|
|
38422
38659
|
return LOCAL_PROVIDER_PREFIXES.some((prefix) => slug.startsWith(prefix));
|
|
38423
38660
|
}
|
|
38424
38661
|
function kimiDataRoot(env) {
|
|
38425
|
-
return env.KIMI_CODE_HOME || join32(env.HOME || env.USERPROFILE ||
|
|
38662
|
+
return env.KIMI_CODE_HOME || join32(env.HOME || env.USERPROFILE || homedir15(), ".kimi-code");
|
|
38426
38663
|
}
|
|
38427
38664
|
function credentialsPath(env) {
|
|
38428
38665
|
return join32(kimiDataRoot(env), "credentials", "kimi-code.json");
|
|
@@ -38898,26 +39135,22 @@ ${turn.text}` : turn.text
|
|
|
38898
39135
|
|
|
38899
39136
|
// server/drivers/acp/droid.ts
|
|
38900
39137
|
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
39138
|
import { join as join33 } from "node:path";
|
|
38903
39139
|
function authFilePaths(env) {
|
|
38904
|
-
const home = env.FACTORY_HOME_OVERRIDE || env
|
|
39140
|
+
const home = env.FACTORY_HOME_OVERRIDE || userHome(env);
|
|
38905
39141
|
return AUTH_FILES.map((name) => join33(home, ".factory", name));
|
|
38906
39142
|
}
|
|
38907
39143
|
function droidInjectId(host, model) {
|
|
38908
39144
|
const safe = `${host}-${model}`.replace(/[^a-zA-Z0-9._+-]+/g, "-").replace(/-+/g, "-");
|
|
38909
39145
|
return `${INJECT_ID_PREFIX}${safe}`;
|
|
38910
39146
|
}
|
|
38911
|
-
function factoryHome(env) {
|
|
38912
|
-
return env.FACTORY_HOME_OVERRIDE || env.HOME || env.USERPROFILE || homedir18();
|
|
38913
|
-
}
|
|
38914
39147
|
function ensureDroidInjectModel(modelId, env = process.env) {
|
|
38915
39148
|
const inject = decodeInjectId(modelId);
|
|
38916
39149
|
if (!inject) return modelId;
|
|
38917
39150
|
const host = localHost(inject.host);
|
|
38918
39151
|
if (!host) return modelId;
|
|
38919
39152
|
const id = droidInjectId(inject.host, inject.model);
|
|
38920
|
-
const dir = join33(
|
|
39153
|
+
const dir = join33(env.FACTORY_HOME_OVERRIDE || userHome(env), ".factory");
|
|
38921
39154
|
mkdirSync16(dir, { recursive: true });
|
|
38922
39155
|
const path3 = join33(dir, "settings.json");
|
|
38923
39156
|
let settings2 = {};
|
|
@@ -38959,7 +39192,7 @@ function applyDroidLocalAuthEnv(env, modelId) {
|
|
|
38959
39192
|
env.FACTORY_API_KEY = "openmausbot-local";
|
|
38960
39193
|
}
|
|
38961
39194
|
function readSettings(env) {
|
|
38962
|
-
return JSON.parse(readFileSync19(join33(
|
|
39195
|
+
return JSON.parse(readFileSync19(join33(env.FACTORY_HOME_OVERRIDE || userHome(env), ".factory", "settings.json"), "utf8"));
|
|
38963
39196
|
}
|
|
38964
39197
|
async function resolveModels(env) {
|
|
38965
39198
|
let catalog2 = MODELS3;
|
|
@@ -38997,6 +39230,7 @@ var AUTH_FILES, INJECT_ID_PREFIX, MODE_DEFAULT, MODE_FULL_AUTO, MODELS3, support
|
|
|
38997
39230
|
var init_droid = __esm({
|
|
38998
39231
|
"server/drivers/acp/droid.ts"() {
|
|
38999
39232
|
"use strict";
|
|
39233
|
+
init_env_path();
|
|
39000
39234
|
init_local_inject();
|
|
39001
39235
|
init_core3();
|
|
39002
39236
|
AUTH_FILES = ["auth.v2.file", "auth.v2.loginkeychain", "auth.v2.keyring"];
|
|
@@ -39110,8 +39344,8 @@ function asRecord(value) {
|
|
|
39110
39344
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
39111
39345
|
}
|
|
39112
39346
|
function labelFor(id, explicit) {
|
|
39113
|
-
|
|
39114
|
-
return id
|
|
39347
|
+
const trimmed = explicit?.trim();
|
|
39348
|
+
return trimmed || titleCaseModelId(id, /[-_./]+/);
|
|
39115
39349
|
}
|
|
39116
39350
|
function pushModel(options, seen, id, label, custom2 = false) {
|
|
39117
39351
|
if (!SLUG3.test(id) || seen.has(id)) return;
|
|
@@ -39277,6 +39511,7 @@ var STATIC_CURSOR_MODELS, SLUG3, EXEC_TIMEOUT_MS, nonBlank2, support6, CursorAge
|
|
|
39277
39511
|
var init_cursor = __esm({
|
|
39278
39512
|
"server/drivers/acp/cursor.ts"() {
|
|
39279
39513
|
"use strict";
|
|
39514
|
+
init_contracts();
|
|
39280
39515
|
init_procs();
|
|
39281
39516
|
init_core3();
|
|
39282
39517
|
STATIC_CURSOR_MODELS = {
|
|
@@ -39350,10 +39585,10 @@ ${turn.text}` : turn.text
|
|
|
39350
39585
|
|
|
39351
39586
|
// server/drivers/acp/opencode-go.ts
|
|
39352
39587
|
import { existsSync as existsSync15, mkdirSync as mkdirSync17, readFileSync as readFileSync20, writeFileSync as writeFileSync12 } from "node:fs";
|
|
39353
|
-
import { homedir as
|
|
39588
|
+
import { homedir as homedir16 } from "node:os";
|
|
39354
39589
|
import { join as join34 } from "node:path";
|
|
39355
39590
|
function labelForModel(id) {
|
|
39356
|
-
return id
|
|
39591
|
+
return titleCaseModelId(id, /[-_.]+/);
|
|
39357
39592
|
}
|
|
39358
39593
|
function providerLabel(id) {
|
|
39359
39594
|
if (id === "opencode") return "Zen";
|
|
@@ -39453,7 +39688,7 @@ async function discoverOpenCodeModels(environment, cli = "opencode") {
|
|
|
39453
39688
|
}
|
|
39454
39689
|
}
|
|
39455
39690
|
function opencodeConfigDir(env) {
|
|
39456
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
39691
|
+
const home = env.HOME || env.USERPROFILE || homedir16();
|
|
39457
39692
|
return join34(env.XDG_CONFIG_HOME || join34(home, ".config"), "opencode");
|
|
39458
39693
|
}
|
|
39459
39694
|
function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
@@ -39500,7 +39735,7 @@ function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
|
39500
39735
|
return native;
|
|
39501
39736
|
}
|
|
39502
39737
|
function storedAuthPaths(env) {
|
|
39503
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
39738
|
+
const home = env.HOME || env.USERPROFILE || homedir16();
|
|
39504
39739
|
const roots = [
|
|
39505
39740
|
env.XDG_DATA_HOME || join34(home, ".local", "share"),
|
|
39506
39741
|
process.platform === "darwin" ? join34(home, "Library", "Application Support") : process.platform === "win32" ? env.LOCALAPPDATA || join34(home, "AppData", "Local") : ""
|
|
@@ -39568,6 +39803,7 @@ var init_opencode_go = __esm({
|
|
|
39568
39803
|
"use strict";
|
|
39569
39804
|
init_local_inject();
|
|
39570
39805
|
init_core3();
|
|
39806
|
+
init_contracts();
|
|
39571
39807
|
init_procs();
|
|
39572
39808
|
STATIC_MODELS = {
|
|
39573
39809
|
default: "opencode/x-preview-f-free",
|
|
@@ -39660,23 +39896,14 @@ ${turn.text}` : turn.text
|
|
|
39660
39896
|
// server/drivers/acp/qwen.ts
|
|
39661
39897
|
import { chmodSync as chmodSync5, existsSync as existsSync16, mkdirSync as mkdirSync18, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "node:fs";
|
|
39662
39898
|
import { createHash as createHash12 } from "node:crypto";
|
|
39663
|
-
import { homedir as homedir20 } from "node:os";
|
|
39664
39899
|
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
39900
|
function isRecord3(value) {
|
|
39670
39901
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
39671
39902
|
}
|
|
39672
|
-
function qwenModelLabel(id, name) {
|
|
39673
|
-
if (!name || name.toLocaleLowerCase().endsWith(id.toLocaleLowerCase())) return id;
|
|
39674
|
-
return `${id} \u2014 ${name}`;
|
|
39675
|
-
}
|
|
39676
39903
|
function readQwenRoutes(env) {
|
|
39677
39904
|
let settings2;
|
|
39678
39905
|
try {
|
|
39679
|
-
settings2 = JSON.parse(readFileSync21(join35(
|
|
39906
|
+
settings2 = JSON.parse(readFileSync21(join35(harnessHome("qwen", env), "settings.json"), "utf8"));
|
|
39680
39907
|
} catch {
|
|
39681
39908
|
return [];
|
|
39682
39909
|
}
|
|
@@ -39744,7 +39971,9 @@ function readQwenRoutes(env) {
|
|
|
39744
39971
|
function readQwenModelCatalog(env = process.env) {
|
|
39745
39972
|
const options = readQwenRoutes(env).map(({ id, model, label, provider }) => ({
|
|
39746
39973
|
id,
|
|
39747
|
-
label:
|
|
39974
|
+
label: qualifiedModelLabel(model, label, {
|
|
39975
|
+
redundantWhen: (id2, name) => name.toLocaleLowerCase().endsWith(id2.toLocaleLowerCase())
|
|
39976
|
+
}),
|
|
39748
39977
|
custom: true,
|
|
39749
39978
|
provider
|
|
39750
39979
|
}));
|
|
@@ -39758,7 +39987,7 @@ function ensureQwenInjectModel(modelId, env = process.env) {
|
|
|
39758
39987
|
if (!inject) return modelId;
|
|
39759
39988
|
const host = localHost(inject.host);
|
|
39760
39989
|
if (!host) return modelId;
|
|
39761
|
-
const dir =
|
|
39990
|
+
const dir = harnessHome("qwen", env);
|
|
39762
39991
|
mkdirSync18(dir, { recursive: true });
|
|
39763
39992
|
const path3 = join35(dir, "settings.json");
|
|
39764
39993
|
let settings2 = {};
|
|
@@ -39840,6 +40069,8 @@ var EMPTY, PROTOCOLS, support8, QwenAgentDriver;
|
|
|
39840
40069
|
var init_qwen = __esm({
|
|
39841
40070
|
"server/drivers/acp/qwen.ts"() {
|
|
39842
40071
|
"use strict";
|
|
40072
|
+
init_contracts();
|
|
40073
|
+
init_env_path();
|
|
39843
40074
|
init_local_inject();
|
|
39844
40075
|
init_core3();
|
|
39845
40076
|
EMPTY = { default: "", options: [] };
|
|
@@ -39865,6 +40096,9 @@ var init_qwen = __esm({
|
|
|
39865
40096
|
// A raw -m only changes the model within the saved provider. ACP switches
|
|
39866
40097
|
// the complete route and confirms it before any prompt leaves OMB.
|
|
39867
40098
|
spawnArgs: (config2, turn) => ["--acp", ...qwenApprovalArgs(config2.fullAuto, turn.approvalMode)],
|
|
40099
|
+
// Qwen's live session/load returns its cached MCP clients, ignoring fresh
|
|
40100
|
+
// credentials. Cold-load the same conversation when those inputs change.
|
|
40101
|
+
restartOnMcpChange: true,
|
|
39868
40102
|
selectModel: { configId: "model" },
|
|
39869
40103
|
pickAuthMethod: () => null,
|
|
39870
40104
|
authFailure: "continue",
|
|
@@ -46766,7 +47000,7 @@ var init_browser = __esm({
|
|
|
46766
47000
|
// server/drivers/acp/hermes.ts
|
|
46767
47001
|
import { spawn as spawn6 } from "node:child_process";
|
|
46768
47002
|
import { mkdirSync as mkdirSync19, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
|
|
46769
|
-
import { homedir as
|
|
47003
|
+
import { homedir as homedir17 } from "node:os";
|
|
46770
47004
|
import { join as join36 } from "node:path";
|
|
46771
47005
|
function bindHermesScreenshotCompat(env, modelId) {
|
|
46772
47006
|
delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT];
|
|
@@ -46776,9 +47010,6 @@ function bindHermesScreenshotCompat(env, modelId) {
|
|
|
46776
47010
|
env[HERMES_OPENMAUS_SCREENSHOT_COMPAT] = "1";
|
|
46777
47011
|
env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL] = inject.model;
|
|
46778
47012
|
}
|
|
46779
|
-
function hermesHome(env) {
|
|
46780
|
-
return env.HERMES_HOME || join36(env.HOME || env.USERPROFILE || homedir21(), ".hermes");
|
|
46781
|
-
}
|
|
46782
47013
|
function quoteYaml(value) {
|
|
46783
47014
|
if (/^[\w./:+-]+$/.test(value)) return value;
|
|
46784
47015
|
return JSON.stringify(value);
|
|
@@ -46817,7 +47048,7 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
46817
47048
|
if (!inject) return modelId;
|
|
46818
47049
|
const host = localHost(inject.host);
|
|
46819
47050
|
if (!host) return modelId;
|
|
46820
|
-
const dir =
|
|
47051
|
+
const dir = env.HERMES_HOME || harnessHome("hermes", env);
|
|
46821
47052
|
mkdirSync19(dir, { recursive: true });
|
|
46822
47053
|
const path3 = join36(dir, "config.yaml");
|
|
46823
47054
|
let text4 = "";
|
|
@@ -46887,7 +47118,7 @@ function hermesConfigDefault(text4) {
|
|
|
46887
47118
|
return null;
|
|
46888
47119
|
}
|
|
46889
47120
|
function hermesConfiguredModel(env = process.env) {
|
|
46890
|
-
const dir =
|
|
47121
|
+
const dir = env.HERMES_HOME || harnessHome("hermes", env);
|
|
46891
47122
|
let secrets = "";
|
|
46892
47123
|
try {
|
|
46893
47124
|
secrets = readFileSync22(join36(dir, ".env"), "utf8");
|
|
@@ -46988,7 +47219,7 @@ async function fetchHermesAcpModels(cli, env) {
|
|
|
46988
47219
|
}
|
|
46989
47220
|
if (msg?.id === initId) {
|
|
46990
47221
|
if (!msg.result) return done([]);
|
|
46991
|
-
sessionId = send("session/new", { cwd: env.HOME || env.USERPROFILE ||
|
|
47222
|
+
sessionId = send("session/new", { cwd: env.HOME || env.USERPROFILE || homedir17(), mcpServers: [] });
|
|
46992
47223
|
} else if (sessionId && msg?.id === sessionId) {
|
|
46993
47224
|
const list = Array.isArray(msg.result?.models?.availableModels) ? msg.result.models.availableModels : [];
|
|
46994
47225
|
done(
|
|
@@ -47032,6 +47263,7 @@ var init_hermes = __esm({
|
|
|
47032
47263
|
"server/drivers/acp/hermes.ts"() {
|
|
47033
47264
|
"use strict";
|
|
47034
47265
|
init_browser();
|
|
47266
|
+
init_env_path();
|
|
47035
47267
|
init_procs();
|
|
47036
47268
|
init_local_inject();
|
|
47037
47269
|
init_core3();
|
|
@@ -47241,8 +47473,8 @@ var init_openai_compat = __esm({
|
|
|
47241
47473
|
});
|
|
47242
47474
|
|
|
47243
47475
|
// 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
|
|
47476
|
+
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";
|
|
47477
|
+
import { homedir as homedir18, tmpdir as tmpdir4 } from "node:os";
|
|
47246
47478
|
import { join as join37 } from "node:path";
|
|
47247
47479
|
function readPiPromptImages(turn) {
|
|
47248
47480
|
return (turn.images ?? []).map((image) => ({
|
|
@@ -47344,7 +47576,7 @@ async function applyPiLocalCatalog(catalog2, env = process.env, fetchImpl = fetc
|
|
|
47344
47576
|
return preferPiInjectRows(await mergeLocalInject(catalog2, env, fetchImpl));
|
|
47345
47577
|
}
|
|
47346
47578
|
function piAgentDir(env) {
|
|
47347
|
-
return join37(env.HOME || env.USERPROFILE ||
|
|
47579
|
+
return join37(env.HOME || env.USERPROFILE || homedir18(), ".pi", "agent");
|
|
47348
47580
|
}
|
|
47349
47581
|
function ensurePiInjectModel(modelId, env = process.env) {
|
|
47350
47582
|
const split = splitPiModel(modelId);
|
|
@@ -47409,7 +47641,7 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
47409
47641
|
return split;
|
|
47410
47642
|
}
|
|
47411
47643
|
function readPiDefaultModel(env) {
|
|
47412
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
47644
|
+
const home = env.HOME || env.USERPROFILE || homedir18();
|
|
47413
47645
|
try {
|
|
47414
47646
|
const s2 = JSON.parse(readFileSync23(`${home}/.pi/agent/settings.json`, "utf8"));
|
|
47415
47647
|
return s2.defaultProvider && s2.defaultModel ? `${s2.defaultProvider}/${s2.defaultModel}` : "";
|
|
@@ -47486,13 +47718,14 @@ function piEnvironment(source) {
|
|
|
47486
47718
|
for (const key of PROVIDER_CREDENTIAL_ENV) delete env[key];
|
|
47487
47719
|
return env;
|
|
47488
47720
|
}
|
|
47489
|
-
var DRIVER_KIND6, PI_ARGS, PI_MODEL_UPDATE_ARGS, NODE_ENV_FLAG2, EMPTY3, PiDriver;
|
|
47721
|
+
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
47722
|
var init_pi = __esm({
|
|
47491
47723
|
"server/drivers/pi.ts"() {
|
|
47492
47724
|
"use strict";
|
|
47493
47725
|
init_config();
|
|
47494
47726
|
init_env_path();
|
|
47495
47727
|
init_procs();
|
|
47728
|
+
init_prompt_split();
|
|
47496
47729
|
init_proxy_paths();
|
|
47497
47730
|
init_tool_summary();
|
|
47498
47731
|
init_wire();
|
|
@@ -47504,6 +47737,10 @@ var init_pi = __esm({
|
|
|
47504
47737
|
PI_ARGS = ["--mode", "rpc", "--no-session"];
|
|
47505
47738
|
PI_MODEL_UPDATE_ARGS = ["update", "--models", "--no-approve"];
|
|
47506
47739
|
NODE_ENV_FLAG2 = { ELECTRON_RUN_AS_NODE: "1" };
|
|
47740
|
+
PI_PROMPT_RE_ANCHOR_TURNS = 8;
|
|
47741
|
+
PI_AGENT_END_GRACE_MS = 6e4;
|
|
47742
|
+
PiRpcRefusalError = class extends Error {
|
|
47743
|
+
};
|
|
47507
47744
|
EMPTY3 = { default: "", options: [] };
|
|
47508
47745
|
PiDriver = {
|
|
47509
47746
|
driverKind: DRIVER_KIND6,
|
|
@@ -47568,6 +47805,10 @@ var init_pi = __esm({
|
|
|
47568
47805
|
const pending = /* @__PURE__ */ new Map();
|
|
47569
47806
|
const askTimers = /* @__PURE__ */ new Set();
|
|
47570
47807
|
let settled = false;
|
|
47808
|
+
let endStopReason;
|
|
47809
|
+
let endUsage;
|
|
47810
|
+
let endErrorMessage;
|
|
47811
|
+
let agentEndTimer = null;
|
|
47571
47812
|
const images = readPiPromptImages(turn);
|
|
47572
47813
|
if (typeof turn.model === "string" && turn.model) {
|
|
47573
47814
|
ensurePiInjectModel(turn.model, { ...process.env, ...input.environment });
|
|
@@ -47580,7 +47821,7 @@ var init_pi = __esm({
|
|
|
47580
47821
|
writeFileSync15(join37(mcpTempDir, "mcp.json"), JSON.stringify({ mcpServers }), { mode: 384 });
|
|
47581
47822
|
} catch (err) {
|
|
47582
47823
|
try {
|
|
47583
|
-
|
|
47824
|
+
rmSync7(mcpTempDir, { recursive: true, force: true });
|
|
47584
47825
|
} catch {
|
|
47585
47826
|
}
|
|
47586
47827
|
throw err;
|
|
@@ -47601,7 +47842,7 @@ var init_pi = __esm({
|
|
|
47601
47842
|
} catch (err) {
|
|
47602
47843
|
if (mcpTempDir) {
|
|
47603
47844
|
try {
|
|
47604
|
-
|
|
47845
|
+
rmSync7(mcpTempDir, { recursive: true, force: true });
|
|
47605
47846
|
} catch {
|
|
47606
47847
|
}
|
|
47607
47848
|
}
|
|
@@ -47610,7 +47851,9 @@ var init_pi = __esm({
|
|
|
47610
47851
|
})();
|
|
47611
47852
|
let buf = "";
|
|
47612
47853
|
let assistantText = "";
|
|
47854
|
+
let compactionObserved = false;
|
|
47613
47855
|
const responseWaiters = /* @__PURE__ */ new Map();
|
|
47856
|
+
let steerSeq = 0;
|
|
47614
47857
|
const rejectWaiters = (err) => {
|
|
47615
47858
|
for (const waiter of responseWaiters.values()) {
|
|
47616
47859
|
clearTimeout(waiter.timer);
|
|
@@ -47618,13 +47861,13 @@ var init_pi = __esm({
|
|
|
47618
47861
|
}
|
|
47619
47862
|
responseWaiters.clear();
|
|
47620
47863
|
};
|
|
47621
|
-
const awaitResponse = (command, timeoutMs = 2e4) => new Promise((resolve12, reject) => {
|
|
47864
|
+
const awaitResponse = (command, timeoutMs = 2e4, key = command) => new Promise((resolve12, reject) => {
|
|
47622
47865
|
const timer = setTimeout(() => {
|
|
47623
|
-
responseWaiters.delete(
|
|
47866
|
+
responseWaiters.delete(key);
|
|
47624
47867
|
reject(new Error(`pi ${command} timed out`));
|
|
47625
47868
|
}, timeoutMs);
|
|
47626
47869
|
timer.unref?.();
|
|
47627
|
-
responseWaiters.set(
|
|
47870
|
+
responseWaiters.set(key, { resolve: resolve12, reject, timer });
|
|
47628
47871
|
});
|
|
47629
47872
|
child.stdin.on("error", () => rejectWaiters(new Error("pi stdin closed")));
|
|
47630
47873
|
const send = (obj) => {
|
|
@@ -47640,6 +47883,10 @@ var init_pi = __esm({
|
|
|
47640
47883
|
const settle = (ok, stopReason, usage) => {
|
|
47641
47884
|
if (settled) return;
|
|
47642
47885
|
settled = true;
|
|
47886
|
+
if (agentEndTimer) {
|
|
47887
|
+
clearTimeout(agentEndTimer);
|
|
47888
|
+
agentEndTimer = null;
|
|
47889
|
+
}
|
|
47643
47890
|
for (const timer of askTimers) clearTimeout(timer);
|
|
47644
47891
|
askTimers.clear();
|
|
47645
47892
|
pending.clear();
|
|
@@ -47661,12 +47908,25 @@ var init_pi = __esm({
|
|
|
47661
47908
|
}
|
|
47662
47909
|
if (mcpTempDir) {
|
|
47663
47910
|
try {
|
|
47664
|
-
|
|
47911
|
+
rmSync7(mcpTempDir, { recursive: true, force: true });
|
|
47665
47912
|
} catch {
|
|
47666
47913
|
}
|
|
47667
47914
|
}
|
|
47668
47915
|
active.delete(threadId);
|
|
47669
47916
|
};
|
|
47917
|
+
const finishRun = () => {
|
|
47918
|
+
const sr = endStopReason;
|
|
47919
|
+
if (sr === "error" || sr === "failed") {
|
|
47920
|
+
emit({
|
|
47921
|
+
...base2(threadId, turnId),
|
|
47922
|
+
type: "runtime.error",
|
|
47923
|
+
message: String(endErrorMessage ?? "pi turn failed").slice(0, 2e3)
|
|
47924
|
+
});
|
|
47925
|
+
settle(false, "failed", endUsage);
|
|
47926
|
+
return;
|
|
47927
|
+
}
|
|
47928
|
+
settle(true, sr === "cancelled" || sr === "aborted" ? "cancelled" : "end_turn", endUsage);
|
|
47929
|
+
};
|
|
47670
47930
|
const stop = () => {
|
|
47671
47931
|
try {
|
|
47672
47932
|
send({ type: "abort" });
|
|
@@ -47678,17 +47938,35 @@ var init_pi = __esm({
|
|
|
47678
47938
|
}
|
|
47679
47939
|
settle(true, "cancelled");
|
|
47680
47940
|
};
|
|
47681
|
-
|
|
47941
|
+
const steerActiveTurn = async (text4) => {
|
|
47942
|
+
if (settled || child.exitCode !== null || child.signalCode !== null) return "refused";
|
|
47943
|
+
let ack;
|
|
47944
|
+
try {
|
|
47945
|
+
const id = `steer:${++steerSeq}`;
|
|
47946
|
+
ack = awaitResponse("steer", 2e4, id);
|
|
47947
|
+
send({ type: "steer", id, message: text4 });
|
|
47948
|
+
} catch {
|
|
47949
|
+
return "refused";
|
|
47950
|
+
}
|
|
47951
|
+
try {
|
|
47952
|
+
await ack;
|
|
47953
|
+
return "steered";
|
|
47954
|
+
} catch (error51) {
|
|
47955
|
+
return error51 instanceof PiRpcRefusalError ? "refused" : "indeterminate";
|
|
47956
|
+
}
|
|
47957
|
+
};
|
|
47958
|
+
active.set(threadId, { stop, turnId, pending, child, steer: steerActiveTurn });
|
|
47682
47959
|
const onEvent = (evt) => {
|
|
47683
47960
|
appendNative(threadId, { dir: "in", source: "pi.rpc", msg: evt });
|
|
47684
47961
|
switch (evt.type) {
|
|
47685
47962
|
case "response": {
|
|
47686
|
-
|
|
47687
|
-
|
|
47688
|
-
responseWaiters.
|
|
47963
|
+
const key = typeof evt.id === "string" && responseWaiters.has(evt.id) ? evt.id : evt.command;
|
|
47964
|
+
if (key && responseWaiters.has(key)) {
|
|
47965
|
+
const waiter = responseWaiters.get(key);
|
|
47966
|
+
responseWaiters.delete(key);
|
|
47689
47967
|
clearTimeout(waiter.timer);
|
|
47690
47968
|
if (evt.success) waiter.resolve(evt.data);
|
|
47691
|
-
else waiter.reject(new
|
|
47969
|
+
else waiter.reject(new PiRpcRefusalError(`pi ${evt.command} failed`));
|
|
47692
47970
|
}
|
|
47693
47971
|
return;
|
|
47694
47972
|
}
|
|
@@ -47779,21 +48057,43 @@ var init_pi = __esm({
|
|
|
47779
48057
|
}
|
|
47780
48058
|
return;
|
|
47781
48059
|
}
|
|
47782
|
-
case "
|
|
47783
|
-
case "
|
|
48060
|
+
case "compaction_start":
|
|
48061
|
+
case "compaction_end":
|
|
48062
|
+
case "auto_compaction_start":
|
|
48063
|
+
case "auto_compaction_end": {
|
|
48064
|
+
if (sessionReady && sessionFile) {
|
|
48065
|
+
compactionObserved = true;
|
|
48066
|
+
deletePromptSplitReceipt("pi", JSON.stringify([threadId, sessionFile]));
|
|
48067
|
+
}
|
|
48068
|
+
return;
|
|
48069
|
+
}
|
|
48070
|
+
case "turn_end": {
|
|
48071
|
+
if (settled) return;
|
|
47784
48072
|
const sr = evt.message?.stopReason;
|
|
47785
48073
|
if (sr === "toolUse" || sr === "tool_use" || sr === "tool_calls") return;
|
|
47786
|
-
|
|
47787
|
-
|
|
47788
|
-
|
|
47789
|
-
|
|
47790
|
-
|
|
47791
|
-
|
|
47792
|
-
|
|
47793
|
-
|
|
47794
|
-
|
|
48074
|
+
endStopReason = sr;
|
|
48075
|
+
endUsage = evt.usage ?? evt.message?.usage;
|
|
48076
|
+
endErrorMessage = evt.message?.errorMessage;
|
|
48077
|
+
if (agentEndTimer) clearTimeout(agentEndTimer);
|
|
48078
|
+
agentEndTimer = setTimeout(finishRun, PI_AGENT_END_GRACE_MS);
|
|
48079
|
+
agentEndTimer.unref?.();
|
|
48080
|
+
return;
|
|
48081
|
+
}
|
|
48082
|
+
case "agent_end": {
|
|
48083
|
+
if (evt.isTerminal === false || evt.willRetry === true) return;
|
|
48084
|
+
if (agentEndTimer) {
|
|
48085
|
+
clearTimeout(agentEndTimer);
|
|
48086
|
+
agentEndTimer = null;
|
|
47795
48087
|
}
|
|
47796
|
-
|
|
48088
|
+
finishRun();
|
|
48089
|
+
return;
|
|
48090
|
+
}
|
|
48091
|
+
case "agent_settled": {
|
|
48092
|
+
if (agentEndTimer) {
|
|
48093
|
+
clearTimeout(agentEndTimer);
|
|
48094
|
+
agentEndTimer = null;
|
|
48095
|
+
}
|
|
48096
|
+
finishRun();
|
|
47797
48097
|
return;
|
|
47798
48098
|
}
|
|
47799
48099
|
default:
|
|
@@ -47827,12 +48127,14 @@ var init_pi = __esm({
|
|
|
47827
48127
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
47828
48128
|
const sessionPath = typeof turn.resumeCursor === "string" ? turn.resumeCursor : null;
|
|
47829
48129
|
let sessionFile = sessionPath;
|
|
48130
|
+
let sessionReady = false;
|
|
47830
48131
|
try {
|
|
47831
48132
|
const command = sessionPath ? "switch_session" : "new_session";
|
|
47832
48133
|
const hsPromise = awaitResponse(command);
|
|
47833
48134
|
send(sessionPath ? { type: "switch_session", sessionPath } : { type: "new_session" });
|
|
47834
48135
|
const hs = await hsPromise;
|
|
47835
48136
|
if (hs?.sessionFile) sessionFile = hs.sessionFile;
|
|
48137
|
+
sessionReady = true;
|
|
47836
48138
|
emit({
|
|
47837
48139
|
...base2(threadId, turnId),
|
|
47838
48140
|
type: "session.started",
|
|
@@ -47858,12 +48160,54 @@ var init_pi = __esm({
|
|
|
47858
48160
|
} catch {
|
|
47859
48161
|
}
|
|
47860
48162
|
}
|
|
47861
|
-
const
|
|
48163
|
+
const halves = promptHalves(turn);
|
|
48164
|
+
let message2;
|
|
48165
|
+
let pendingReceipt = null;
|
|
48166
|
+
if (halves.stable !== null && sessionReady && sessionFile) {
|
|
48167
|
+
const receiptKey = JSON.stringify([threadId, sessionFile]);
|
|
48168
|
+
const composed = splitSessionPrompt(
|
|
48169
|
+
halves.stable,
|
|
48170
|
+
halves.volatile,
|
|
48171
|
+
readPromptSplitReceipt("pi", receiptKey),
|
|
48172
|
+
turn.system,
|
|
48173
|
+
turn.text,
|
|
48174
|
+
Boolean(turn.mentionTurn),
|
|
48175
|
+
PI_PROMPT_RE_ANCHOR_TURNS
|
|
48176
|
+
);
|
|
48177
|
+
message2 = composed.text;
|
|
48178
|
+
pendingReceipt = { key: receiptKey, receipt: composed.receipt };
|
|
48179
|
+
} else {
|
|
48180
|
+
message2 = turn.system ? `${turn.system}
|
|
47862
48181
|
|
|
47863
48182
|
${turn.text}` : turn.text;
|
|
48183
|
+
}
|
|
47864
48184
|
try {
|
|
48185
|
+
const accepted = awaitResponse("prompt", 12e4);
|
|
47865
48186
|
send({ type: "prompt", message: message2, ...images.length ? { images } : {} });
|
|
47866
|
-
|
|
48187
|
+
void accepted.then(
|
|
48188
|
+
() => {
|
|
48189
|
+
if (!pendingReceipt || compactionObserved) return;
|
|
48190
|
+
try {
|
|
48191
|
+
writePromptSplitReceipt("pi", pendingReceipt.key, pendingReceipt.receipt);
|
|
48192
|
+
} catch {
|
|
48193
|
+
}
|
|
48194
|
+
},
|
|
48195
|
+
(err) => {
|
|
48196
|
+
if (settled) return;
|
|
48197
|
+
emit({
|
|
48198
|
+
...base2(threadId, turnId),
|
|
48199
|
+
type: "runtime.error",
|
|
48200
|
+
message: String(err?.message ?? err).slice(0, 2e3)
|
|
48201
|
+
});
|
|
48202
|
+
settle(false);
|
|
48203
|
+
}
|
|
48204
|
+
);
|
|
48205
|
+
} catch (err) {
|
|
48206
|
+
emit({
|
|
48207
|
+
...base2(threadId, turnId),
|
|
48208
|
+
type: "runtime.error",
|
|
48209
|
+
message: String(err?.message ?? err).slice(0, 2e3)
|
|
48210
|
+
});
|
|
47867
48211
|
settle(false);
|
|
47868
48212
|
}
|
|
47869
48213
|
return { turnId };
|
|
@@ -47930,7 +48274,10 @@ ${turn.text}` : turn.text;
|
|
|
47930
48274
|
// Reasoning effort pins pi's thinking level per turn (none → off).
|
|
47931
48275
|
// xhigh/max only land on models that expose them; pi rejects an
|
|
47932
48276
|
// unsupported level and the turn keeps the engine default.
|
|
47933
|
-
effortLevels: EFFORT_LEVELS
|
|
48277
|
+
effortLevels: EFFORT_LEVELS,
|
|
48278
|
+
// pi's RPC mode takes a mid-turn steer frame the runtime queues
|
|
48279
|
+
// into the running agent without aborting the current step.
|
|
48280
|
+
queueing: true
|
|
47934
48281
|
},
|
|
47935
48282
|
sendTurn,
|
|
47936
48283
|
interruptTurn: async (threadId) => active.get(threadId)?.stop(),
|
|
@@ -47949,6 +48296,10 @@ ${turn.text}` : turn.text;
|
|
|
47949
48296
|
});
|
|
47950
48297
|
return decision.behavior === "allow" ? "allowed-once" : decision.behavior === "answer" ? "answered" : "rejected";
|
|
47951
48298
|
},
|
|
48299
|
+
steer: async (threadId, text4) => {
|
|
48300
|
+
const entry = active.get(threadId);
|
|
48301
|
+
return entry?.steer ? await entry.steer(text4) : "refused";
|
|
48302
|
+
},
|
|
47952
48303
|
hasSession: (threadId) => active.has(threadId),
|
|
47953
48304
|
stopAll: async () => {
|
|
47954
48305
|
for (const { stop } of active.values()) stop();
|
|
@@ -48092,13 +48443,13 @@ var init_mistral = __esm({
|
|
|
48092
48443
|
|
|
48093
48444
|
// server/drivers/minimax.ts
|
|
48094
48445
|
import { readFileSync as readFileSync24 } from "node:fs";
|
|
48095
|
-
import { homedir as
|
|
48446
|
+
import { homedir as homedir19 } from "node:os";
|
|
48096
48447
|
import { join as join38 } from "node:path";
|
|
48097
48448
|
function normalizedApiUrl(value) {
|
|
48098
48449
|
const root = value.trim().replace(/\/+$/, "");
|
|
48099
48450
|
return root.endsWith("/v1") ? root : `${root}/v1`;
|
|
48100
48451
|
}
|
|
48101
|
-
function loadLocalMiniMaxConfig(home =
|
|
48452
|
+
function loadLocalMiniMaxConfig(home = homedir19()) {
|
|
48102
48453
|
try {
|
|
48103
48454
|
const raw = localConfigSchema.parse(JSON.parse(readFileSync24(join38(home, ".mmx", "config.json"), "utf8")));
|
|
48104
48455
|
const configuredUrl = raw.base_url?.trim() ? raw.base_url : raw.region === "cn" ? CN_URL : DEFAULT_URL3;
|
|
@@ -48823,8 +49174,8 @@ __export(browser_engine_exports, {
|
|
|
48823
49174
|
});
|
|
48824
49175
|
import { spawn as spawn8 } from "node:child_process";
|
|
48825
49176
|
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
|
|
49177
|
+
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";
|
|
49178
|
+
import { homedir as homedir20, tmpdir as tmpdir5 } from "node:os";
|
|
48828
49179
|
import { delimiter as delimiter6, dirname as dirname12, join as join42, resolve as resolve10 } from "node:path";
|
|
48829
49180
|
function browserRestoreKey(session) {
|
|
48830
49181
|
if (!/^[A-Za-z0-9_.-]{1,96}$/.test(session)) throw new Error("Invalid browser session.");
|
|
@@ -48833,7 +49184,7 @@ function browserRestoreKey(session) {
|
|
|
48833
49184
|
function browserSessionsDirectory(env) {
|
|
48834
49185
|
const namespace = env.AGENT_BROWSER_NAMESPACE;
|
|
48835
49186
|
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) ||
|
|
49187
|
+
const home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir20();
|
|
48837
49188
|
const stateRoot = namespace ? join42(home, ".agent-browser", "namespaces", namespace, "state") : join42(home, ".agent-browser");
|
|
48838
49189
|
return join42(stateRoot, "sessions");
|
|
48839
49190
|
}
|
|
@@ -49215,7 +49566,7 @@ function agentBrowserFrame(input) {
|
|
|
49215
49566
|
} catch {
|
|
49216
49567
|
fail(new Error("the browser reported a picture it did not write"));
|
|
49217
49568
|
} finally {
|
|
49218
|
-
|
|
49569
|
+
rmSync8(file2, { force: true });
|
|
49219
49570
|
}
|
|
49220
49571
|
};
|
|
49221
49572
|
child.on("error", (error51) => done(error51 instanceof Error ? error51 : new Error(String(error51))));
|
|
@@ -49299,7 +49650,7 @@ var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
|
49299
49650
|
import { spawn as spawn9 } from "node:child_process";
|
|
49300
49651
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
49301
49652
|
import { closeSync as closeSync6, existsSync as existsSync19, mkdirSync as mkdirSync22, openSync as openSync6, readFileSync as readFileSync27 } from "node:fs";
|
|
49302
|
-
import { homedir as
|
|
49653
|
+
import { homedir as homedir21 } from "node:os";
|
|
49303
49654
|
import { dirname as dirname13, join as join43, resolve as resolve11 } from "node:path";
|
|
49304
49655
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
49305
49656
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -52793,7 +53144,7 @@ function parseArgs(argv, env = process.env) {
|
|
|
52793
53144
|
const options = {
|
|
52794
53145
|
command: command === "--help" || command === "-h" ? "help" : command,
|
|
52795
53146
|
port: Number(env.OMB_PORT || 8799),
|
|
52796
|
-
dataDir: env.OMB_DATA_DIR || join43(
|
|
53147
|
+
dataDir: env.OMB_DATA_DIR || join43(homedir21(), ".openmausbot"),
|
|
52797
53148
|
tailscale: false,
|
|
52798
53149
|
tunnel: false,
|
|
52799
53150
|
client: false,
|
|
@@ -53721,7 +54072,7 @@ async function runOnboardingCommand(options, io = defaultIo(), startServer = run
|
|
|
53721
54072
|
}
|
|
53722
54073
|
if (options.command === "setup") {
|
|
53723
54074
|
io.log("\nAll set. Start with: openmausbot (or npx openmausbot without a global install).");
|
|
53724
|
-
if (options.dataDir !== join43(
|
|
54075
|
+
if (options.dataDir !== join43(homedir21(), ".openmausbot") || options.port !== 8799) {
|
|
53725
54076
|
io.log(`Use the same --data-dir (${options.dataDir}) and --port (${options.port}) options when starting.`);
|
|
53726
54077
|
}
|
|
53727
54078
|
return 0;
|