openmausbot 0.1.79 → 0.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-Cu8BkIfo.js +305 -0
- package/dist/assets/{index-C2Je5jdF.js → index-D6RZKWks.js} +1 -1
- package/dist/assets/index-tfpeJAIG.css +1 -0
- package/dist/index.html +2 -2
- package/dist-server/drivers/agents-proxy.js +21 -6
- package/dist-server/index.js +988 -544
- package/dist-server/openmausbot.js +170 -85
- package/dist-server/pair-cli.js +170 -85
- package/dist-server/server/drivers/agents-proxy.js +27 -2
- package/dist-server/server/drivers/claude.js +55 -62
- package/dist-server/server/drivers/codex.js +158 -46
- package/dist-server/server/harness/registry.js +2 -2
- package/dist-server/server/index.js +203 -12
- package/dist-server/server/managed-desktop.js +205 -0
- package/dist-server/server/model-context-window.js +20 -0
- package/dist-server/server/redact.js +1 -0
- package/dist-server/server/room-handoffs.js +16 -6
- package/dist-server/server/store.js +13 -1
- package/package.json +1 -1
- package/dist/assets/index-D_TFZLlo.js +0 -305
- package/dist/assets/index-Pbb6Ao0s.css +0 -1
|
@@ -19049,7 +19049,7 @@ var init_registry = __esm({
|
|
|
19049
19049
|
this.npmPresent = options.npmAvailable ?? npmAvailable;
|
|
19050
19050
|
this.driversByKind = new Map(drivers.map((d) => [d.driverKind, d]));
|
|
19051
19051
|
}
|
|
19052
|
-
async load(configs) {
|
|
19052
|
+
async load(configs, decorate) {
|
|
19053
19053
|
for (const [instanceId, entry] of Object.entries(configs)) {
|
|
19054
19054
|
await this.dispose(instanceId);
|
|
19055
19055
|
const driver = this.driversByKind.get(entry.driver);
|
|
@@ -19078,7 +19078,7 @@ var init_registry = __esm({
|
|
|
19078
19078
|
enabled: entry.enabled ?? true,
|
|
19079
19079
|
config: config2
|
|
19080
19080
|
});
|
|
19081
|
-
this.byId.set(instanceId, { instanceId, live });
|
|
19081
|
+
this.byId.set(instanceId, { instanceId, live: decorate ? decorate(live) : live });
|
|
19082
19082
|
} catch (e) {
|
|
19083
19083
|
this.byId.set(instanceId, {
|
|
19084
19084
|
instanceId,
|
|
@@ -19600,6 +19600,8 @@ var init_redact = __esm({
|
|
|
19600
19600
|
REDACTION_MARKER = /^«redacted \d+ chars»$/;
|
|
19601
19601
|
mask = (value) => REDACTION_MARKER.test(value) ? value : `\xABredacted ${value.length} chars\xBB`;
|
|
19602
19602
|
KEY_PREFIXES = [
|
|
19603
|
+
/\bom[dg]_[A-Za-z0-9_-]{43}(?![A-Za-z0-9_-])/g,
|
|
19604
|
+
// desktop device and model-only credentials
|
|
19603
19605
|
/\bsk-(?:ant-|proj-|live-|test-)?[A-Za-z0-9_-]{16,}/g,
|
|
19604
19606
|
// anthropic / openai / stripe
|
|
19605
19607
|
/\bxai-[A-Za-z0-9_-]{20,}/g,
|
|
@@ -22637,21 +22639,17 @@ function claudeCliUpdate(version2, cli) {
|
|
|
22637
22639
|
if (!parsed || versionAtLeast(parsed, CLAUDE_CONTEXT_CONTROL_MIN_VERSION)) return void 0;
|
|
22638
22640
|
const floor = CLAUDE_CONTEXT_CONTROL_MIN_VERSION.join(".");
|
|
22639
22641
|
const missing = Object.keys(CLAUDE_FLAG_FLOORS).filter((flag) => !claudeCliSupports(parsed, flag));
|
|
22642
|
+
const effects = [
|
|
22643
|
+
...missing.includes("--autocompact") ? ["no compaction window picked by OpenMausBot"] : [],
|
|
22644
|
+
...missing.includes("--setting-sources") ? ["bots still see this machine's own Claude Code setup"] : [],
|
|
22645
|
+
...missing.includes("--system-prompt-snapshot") ? ["coordinated resumed turns cannot refresh stale system prompts"] : []
|
|
22646
|
+
];
|
|
22640
22647
|
return {
|
|
22641
22648
|
title: "Update Claude Code for context controls",
|
|
22642
|
-
message: `Claude Code ${parsed.join(".")} predates ${floor}, so bots run without ${missing.join(", ")}:
|
|
22649
|
+
message: `Claude Code ${parsed.join(".")} predates ${floor}, so bots run without ${missing.join(", ")}: ${effects.join("; ")}. Update it, then refresh Engines.`,
|
|
22643
22650
|
command: cli === "claude" ? "claude update" : `${cli} update`
|
|
22644
22651
|
};
|
|
22645
22652
|
}
|
|
22646
|
-
function claudeCliHelpSupportsFlag(help, flag) {
|
|
22647
|
-
if (!help) return false;
|
|
22648
|
-
const escaped = flag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
22649
|
-
return new RegExp(`^\\s*${escaped}\\b`, "m").test(help);
|
|
22650
|
-
}
|
|
22651
|
-
function claudeAutoCompactSupported(version2, help) {
|
|
22652
|
-
if (help !== null) return claudeCliHelpSupportsFlag(help, "--autocompact");
|
|
22653
|
-
return claudeCliSupports(version2, "--autocompact");
|
|
22654
|
-
}
|
|
22655
22653
|
async function resolveClaudeTurnModel(model, env) {
|
|
22656
22654
|
if (!model || decodeInjectId(model) || STATIC_CLAUDE_MODELS.options.some((option) => option.id === model)) {
|
|
22657
22655
|
return model;
|
|
@@ -22914,6 +22912,7 @@ function decodeConfig2(raw) {
|
|
|
22914
22912
|
return {
|
|
22915
22913
|
cli: typeof o.cli === "string" ? o.cli : "claude",
|
|
22916
22914
|
...configDir ? { configDir } : {},
|
|
22915
|
+
...o.managed === true ? { managed: true } : {},
|
|
22917
22916
|
permissionMode: mode ?? "acceptEdits",
|
|
22918
22917
|
...tools !== void 0 ? { tools } : {},
|
|
22919
22918
|
...disallowedTools !== void 0 ? { disallowedTools } : {}
|
|
@@ -23003,9 +23002,12 @@ var init_claude = __esm({
|
|
|
23003
23002
|
CLAUDE_FLAG_FLOORS = {
|
|
23004
23003
|
"--strict-mcp-config": [1, 0, 60],
|
|
23005
23004
|
"--setting-sources": [1, 0, 122],
|
|
23006
|
-
"--autocompact": [2, 1, 122]
|
|
23005
|
+
"--autocompact": [2, 1, 122],
|
|
23006
|
+
// 2.1.267 is the first CLI that accepts it; below that the recorded prompt
|
|
23007
|
+
// simply is not refreshed, which is the pre-existing behaviour.
|
|
23008
|
+
"--system-prompt-snapshot": [2, 1, 267]
|
|
23007
23009
|
};
|
|
23008
|
-
CLAUDE_CONTEXT_CONTROL_MIN_VERSION = CLAUDE_FLAG_FLOORS["--
|
|
23010
|
+
CLAUDE_CONTEXT_CONTROL_MIN_VERSION = CLAUDE_FLAG_FLOORS["--system-prompt-snapshot"];
|
|
23009
23011
|
DRIVER_KIND2 = "claudeAgent";
|
|
23010
23012
|
STATIC_CLAUDE_MODELS = {
|
|
23011
23013
|
default: "claude-sonnet-5",
|
|
@@ -23044,10 +23046,11 @@ var init_claude = __esm({
|
|
|
23044
23046
|
defaultConfig: () => decodeConfig2({}),
|
|
23045
23047
|
async create(input) {
|
|
23046
23048
|
const { instanceId, config: config2 } = input;
|
|
23047
|
-
const environment = (model) => claudeEnvironment(model, { ...process.env, ...input.environment }, config2.configDir, input.environment);
|
|
23049
|
+
const environment = (model) => claudeEnvironment(config2.managed ? void 0 : model, { ...process.env, ...input.environment }, config2.configDir, input.environment);
|
|
23048
23050
|
const catalogEnv = environment();
|
|
23049
23051
|
let models2 = STATIC_CLAUDE_MODELS;
|
|
23050
23052
|
const refreshModels = async () => {
|
|
23053
|
+
if (config2.managed) return;
|
|
23051
23054
|
try {
|
|
23052
23055
|
const resolved = await mergeLocalInject(readClaudeModelCatalog(catalogEnv), catalogEnv);
|
|
23053
23056
|
if (resolved.options.length) models2 = resolved;
|
|
@@ -23056,8 +23059,15 @@ var init_claude = __esm({
|
|
|
23056
23059
|
};
|
|
23057
23060
|
await refreshModels();
|
|
23058
23061
|
let cliVersion = null;
|
|
23059
|
-
let
|
|
23060
|
-
|
|
23062
|
+
let cliVersionChecked = false;
|
|
23063
|
+
const readCliVersion = (env) => new Promise((resolve12) => {
|
|
23064
|
+
execCli(
|
|
23065
|
+
config2.cli,
|
|
23066
|
+
["--version"],
|
|
23067
|
+
{ timeout: 8e3, env },
|
|
23068
|
+
(err, stdout2) => resolve12(err ? null : stdout2.trim() || null)
|
|
23069
|
+
);
|
|
23070
|
+
});
|
|
23061
23071
|
const listeners = /* @__PURE__ */ new Set();
|
|
23062
23072
|
const active = /* @__PURE__ */ new Map();
|
|
23063
23073
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -23124,6 +23134,9 @@ var init_claude = __esm({
|
|
|
23124
23134
|
});
|
|
23125
23135
|
const retryState = /* @__PURE__ */ new Map();
|
|
23126
23136
|
const sendTurn = async (turn, logicalTurnId) => {
|
|
23137
|
+
if (config2.managed && (!turn.model || turn.model.includes("::") || !config2.configDir || !input.environment.ANTHROPIC_API_KEY || !input.environment.ANTHROPIC_BASE_URL)) {
|
|
23138
|
+
throw new Error("Company model access is unavailable. Reconnect your organization; personal billing will not be used.");
|
|
23139
|
+
}
|
|
23127
23140
|
const { threadId, botId } = turn;
|
|
23128
23141
|
const relaunch = logicalTurnId !== void 0;
|
|
23129
23142
|
if (active.has(threadId) && !relaunch) throw new Error("a turn is already running on this thread");
|
|
@@ -23160,17 +23173,27 @@ var init_claude = __esm({
|
|
|
23160
23173
|
args.push("--disallowedTools", config2.disallowedTools.join(","));
|
|
23161
23174
|
}
|
|
23162
23175
|
const turnEnvironment = environment();
|
|
23176
|
+
if (turn.refreshSystemPrompt && !cliVersionChecked) {
|
|
23177
|
+
const version2 = await readCliVersion(turnEnvironment);
|
|
23178
|
+
if (version2) {
|
|
23179
|
+
cliVersion = parseClaudeCliVersion(version2);
|
|
23180
|
+
cliVersionChecked = true;
|
|
23181
|
+
}
|
|
23182
|
+
}
|
|
23163
23183
|
const isolated = !inheritsUserConfig(turnEnvironment);
|
|
23164
23184
|
if (isolated) {
|
|
23165
23185
|
if (claudeCliSupports(cliVersion, "--strict-mcp-config")) args.push("--strict-mcp-config");
|
|
23166
23186
|
if (claudeCliSupports(cliVersion, "--setting-sources")) args.push("--setting-sources", "project");
|
|
23167
23187
|
}
|
|
23168
23188
|
const compactWindow = autoCompactWindow(turnEnvironment);
|
|
23169
|
-
if (compactWindow &&
|
|
23189
|
+
if (compactWindow && claudeCliSupports(cliVersion, "--autocompact")) {
|
|
23170
23190
|
args.push("--autocompact", compactWindow);
|
|
23171
23191
|
}
|
|
23172
|
-
|
|
23173
|
-
|
|
23192
|
+
if (turn.refreshSystemPrompt && cliVersionChecked && claudeCliSupports(cliVersion, "--system-prompt-snapshot")) {
|
|
23193
|
+
args.push("--system-prompt-snapshot", "off");
|
|
23194
|
+
}
|
|
23195
|
+
const turnModel = config2.managed ? turn.model : await resolveClaudeTurnModel(turn.model, turnEnvironment);
|
|
23196
|
+
const injected = config2.managed ? { model: turnModel ?? null, injected: false } : applyClaudeInject({ ...turnEnvironment }, turnModel);
|
|
23174
23197
|
if (injected.model) args.push("--model", injected.model);
|
|
23175
23198
|
if (turn.effort) args.push("--effort", turn.effort);
|
|
23176
23199
|
let systemPromptPath = null;
|
|
@@ -23506,7 +23529,10 @@ var init_claude = __esm({
|
|
|
23506
23529
|
type: "thread.token-usage.updated",
|
|
23507
23530
|
input: (msg.usage.input_tokens || 0) + (msg.usage.cache_read_input_tokens || 0),
|
|
23508
23531
|
output: msg.usage.output_tokens || 0,
|
|
23509
|
-
...typeof msg.usage.cache_read_input_tokens === "number" ? { cachedInput: msg.usage.cache_read_input_tokens } : {}
|
|
23532
|
+
...typeof msg.usage.cache_read_input_tokens === "number" ? { cachedInput: msg.usage.cache_read_input_tokens } : {},
|
|
23533
|
+
// one assistant message = one model call, and its prompt is
|
|
23534
|
+
// everything in the window: fresh text, cache reads and writes
|
|
23535
|
+
contextTokens: (msg.usage.input_tokens || 0) + (msg.usage.cache_read_input_tokens || 0) + (msg.usage.cache_creation_input_tokens || 0)
|
|
23510
23536
|
});
|
|
23511
23537
|
}
|
|
23512
23538
|
break;
|
|
@@ -23739,38 +23765,13 @@ var init_claude = __esm({
|
|
|
23739
23765
|
} });
|
|
23740
23766
|
const snapshot = async () => {
|
|
23741
23767
|
const env = environment();
|
|
23742
|
-
const version2 = await
|
|
23743
|
-
execCli(
|
|
23744
|
-
config2.cli,
|
|
23745
|
-
["--version"],
|
|
23746
|
-
{ timeout: 8e3, env },
|
|
23747
|
-
(err, stdout2) => resolve12(err ? null : stdout2.trim())
|
|
23748
|
-
);
|
|
23749
|
-
});
|
|
23768
|
+
const version2 = await readCliVersion(env);
|
|
23750
23769
|
if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
|
|
23751
23770
|
cliVersion = parseClaudeCliVersion(version2);
|
|
23752
|
-
|
|
23753
|
-
cliHelp = await new Promise((resolve12) => {
|
|
23754
|
-
execCli(
|
|
23755
|
-
config2.cli,
|
|
23756
|
-
["--help"],
|
|
23757
|
-
{ timeout: 8e3, env },
|
|
23758
|
-
(err, stdout2) => resolve12(err ? null : stdout2)
|
|
23759
|
-
);
|
|
23760
|
-
});
|
|
23761
|
-
cliHelpVersion = version2;
|
|
23762
|
-
}
|
|
23763
|
-
const features = cliHelp !== null ? { autocompact: claudeCliHelpSupportsFlag(cliHelp, "--autocompact") } : void 0;
|
|
23771
|
+
cliVersionChecked = true;
|
|
23764
23772
|
const auth = await claudeAuthStatus(config2.cli, env);
|
|
23765
23773
|
const update = claudeCliUpdate(version2, config2.cli);
|
|
23766
|
-
return {
|
|
23767
|
-
state: "available",
|
|
23768
|
-
version: version2,
|
|
23769
|
-
...auth,
|
|
23770
|
-
...update ? { update } : {},
|
|
23771
|
-
...features ? { features } : {},
|
|
23772
|
-
billing: "subscription"
|
|
23773
|
-
};
|
|
23774
|
+
return { state: "available", version: version2, ...auth, ...update ? { update } : {}, billing: "subscription" };
|
|
23774
23775
|
};
|
|
23775
23776
|
const generateReview = (prompt, signal) => new Promise((resolve12, reject) => {
|
|
23776
23777
|
const child = spawnCli(
|
|
@@ -24709,6 +24710,9 @@ var init_codex_identity = __esm({
|
|
|
24709
24710
|
// server/drivers/codex.ts
|
|
24710
24711
|
import { existsSync as existsSync10 } from "node:fs";
|
|
24711
24712
|
import { homedir as homedir13 } from "node:os";
|
|
24713
|
+
function missingNativeCodexThread(error51, cursor3) {
|
|
24714
|
+
return error51 instanceof CodexRpcError && error51.code === -32600 && error51.message === `no rollout found for thread id ${cursor3}`;
|
|
24715
|
+
}
|
|
24712
24716
|
function codexPredatesAstra(version2) {
|
|
24713
24717
|
const value = version2.trim();
|
|
24714
24718
|
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);
|
|
@@ -24743,9 +24747,39 @@ function decodeConfig3(raw) {
|
|
|
24743
24747
|
const o = raw ?? {};
|
|
24744
24748
|
return {
|
|
24745
24749
|
cli: typeof o.cli === "string" ? o.cli : "codex",
|
|
24746
|
-
fullAuto: o.fullAuto === true
|
|
24750
|
+
fullAuto: o.fullAuto === true,
|
|
24751
|
+
...o.managed && typeof o.managed === "object" ? { managed: decodeManagedCodex(o.managed) } : {}
|
|
24747
24752
|
};
|
|
24748
24753
|
}
|
|
24754
|
+
function decodeManagedCodex(raw) {
|
|
24755
|
+
const value = raw;
|
|
24756
|
+
if (typeof value.url !== "string" || !Array.isArray(value.models) || !value.models.length || value.models.some((model) => typeof model !== "string" || !/^[\w][\w./+-]*$/.test(model))) {
|
|
24757
|
+
throw new Error("Invalid Company Codex configuration.");
|
|
24758
|
+
}
|
|
24759
|
+
const url2 = new URL(value.url);
|
|
24760
|
+
if (url2.username || url2.password || url2.search || url2.hash || !["https:", "http:"].includes(url2.protocol)) throw new Error("Invalid Company Codex endpoint.");
|
|
24761
|
+
return { url: url2.href.replace(/\/$/, ""), models: value.models };
|
|
24762
|
+
}
|
|
24763
|
+
function managedCodexArgs(config2) {
|
|
24764
|
+
return [
|
|
24765
|
+
"-c",
|
|
24766
|
+
'model_provider="openmaus_company"',
|
|
24767
|
+
"-c",
|
|
24768
|
+
'model_providers.openmaus_company.name="Company"',
|
|
24769
|
+
"-c",
|
|
24770
|
+
`model_providers.openmaus_company.base_url=${JSON.stringify(config2.url)}`,
|
|
24771
|
+
"-c",
|
|
24772
|
+
'model_providers.openmaus_company.env_key="OPENMAUSBOT_COMPANY_API_KEY"',
|
|
24773
|
+
"-c",
|
|
24774
|
+
'model_providers.openmaus_company.wire_api="responses"',
|
|
24775
|
+
"-c",
|
|
24776
|
+
"model_providers.openmaus_company.requires_openai_auth=false",
|
|
24777
|
+
"-c",
|
|
24778
|
+
'cli_auth_credentials_store="ephemeral"',
|
|
24779
|
+
"-c",
|
|
24780
|
+
"shell_environment_policy.ignore_default_excludes=false"
|
|
24781
|
+
];
|
|
24782
|
+
}
|
|
24749
24783
|
function grantedPermissions(raw) {
|
|
24750
24784
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
24751
24785
|
return Object.fromEntries(
|
|
@@ -24961,7 +24995,7 @@ function mountMcpServer(appServerArgs, env, name, server, preApproved = true) {
|
|
|
24961
24995
|
appServerArgs.push("-c", `${prefix}.default_tools_approval_mode="auto"`);
|
|
24962
24996
|
}
|
|
24963
24997
|
}
|
|
24964
|
-
var DRIVER_KIND3, ASTRA_MODEL_ID, ASTRA_MIN_CODEX_VERSION, QUESTION_TIMEOUT_NOTE2, DENY_TIMEOUT_NOTE2, plainRecord, containsControlCharacter, CodexDriver;
|
|
24998
|
+
var DRIVER_KIND3, ASTRA_MODEL_ID, ASTRA_MIN_CODEX_VERSION, CodexRpcError, QUESTION_TIMEOUT_NOTE2, DENY_TIMEOUT_NOTE2, plainRecord, containsControlCharacter, CodexDriver;
|
|
24965
24999
|
var init_codex = __esm({
|
|
24966
25000
|
"server/drivers/codex.ts"() {
|
|
24967
25001
|
"use strict";
|
|
@@ -24978,10 +25012,18 @@ var init_codex = __esm({
|
|
|
24978
25012
|
init_codex_instructions();
|
|
24979
25013
|
init_codex_device_auth();
|
|
24980
25014
|
init_codex_identity();
|
|
25015
|
+
init_resume_recovery();
|
|
24981
25016
|
init_codex_catalog();
|
|
24982
25017
|
DRIVER_KIND3 = "codex";
|
|
24983
25018
|
ASTRA_MODEL_ID = "gpt-6-astra";
|
|
24984
25019
|
ASTRA_MIN_CODEX_VERSION = [0, 153, 1];
|
|
25020
|
+
CodexRpcError = class extends Error {
|
|
25021
|
+
code;
|
|
25022
|
+
constructor(error51) {
|
|
25023
|
+
super(error51.message ?? JSON.stringify(error51));
|
|
25024
|
+
this.code = error51.code;
|
|
25025
|
+
}
|
|
25026
|
+
};
|
|
24985
25027
|
QUESTION_TIMEOUT_NOTE2 = "No answer was given \u2014 use your best judgment.";
|
|
24986
25028
|
DENY_TIMEOUT_NOTE2 = "OpenMausBot: nobody answered this permission request in time. Skip this action and finish what you can without it.";
|
|
24987
25029
|
plainRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -25022,8 +25064,9 @@ var init_codex = __esm({
|
|
|
25022
25064
|
return env;
|
|
25023
25065
|
};
|
|
25024
25066
|
const catalogEnv = childEnv();
|
|
25025
|
-
let models2 = STATIC_CODEX_MODELS;
|
|
25067
|
+
let models2 = config2.managed ? { default: config2.managed.models[0], options: config2.managed.models.map((id) => ({ id, label: id })) } : STATIC_CODEX_MODELS;
|
|
25026
25068
|
const refreshModels = async () => {
|
|
25069
|
+
if (config2.managed) return;
|
|
25027
25070
|
try {
|
|
25028
25071
|
const resolved = await readCodexModelCatalog(catalogEnv, fetch, config2.cli);
|
|
25029
25072
|
if (resolved.options.length) models2 = resolved;
|
|
@@ -25049,7 +25092,12 @@ var init_codex = __esm({
|
|
|
25049
25092
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
25050
25093
|
});
|
|
25051
25094
|
const sendTurn = async (turn) => {
|
|
25095
|
+
if (config2.managed && (!turn.model || !config2.managed.models.includes(turn.model) || !input.environment.OPENMAUSBOT_COMPANY_API_KEY || !input.environment.CODEX_HOME)) {
|
|
25096
|
+
throw new Error("Company model access is unavailable. Reconnect your organization; personal billing will not be used.");
|
|
25097
|
+
}
|
|
25052
25098
|
let stopRequested = false;
|
|
25099
|
+
let promptSubmitted = false;
|
|
25100
|
+
let recoveredMissingSession = false;
|
|
25053
25101
|
const stopSignal = new AbortController();
|
|
25054
25102
|
const { threadId } = turn;
|
|
25055
25103
|
const approvalMode = turn.approvalMode ?? (config2.fullAuto ? "full" : "ask");
|
|
@@ -25065,7 +25113,7 @@ var init_codex = __esm({
|
|
|
25065
25113
|
const retryScale = Number(process.env.FAKE_CODEX_RETRY_SCALE ?? "1");
|
|
25066
25114
|
const launchAttempt = async (attempt) => {
|
|
25067
25115
|
const env = childEnv();
|
|
25068
|
-
const appServerArgs = ["app-server", ...codexLocalProviderArgs(env, turn.model)];
|
|
25116
|
+
const appServerArgs = ["app-server", ...config2.managed ? managedCodexArgs(config2.managed) : codexLocalProviderArgs(env, turn.model)];
|
|
25069
25117
|
if (turn.integrations?.composio) {
|
|
25070
25118
|
mountMcpServer(appServerArgs, env, "openmausbot_connectors", turn.integrations.composio);
|
|
25071
25119
|
}
|
|
@@ -25111,9 +25159,12 @@ var init_codex = __esm({
|
|
|
25111
25159
|
lastError: "",
|
|
25112
25160
|
lastText: "",
|
|
25113
25161
|
sawStreamDelta: false,
|
|
25114
|
-
// codex reports token usage as a running
|
|
25115
|
-
// wants this turn's figure
|
|
25116
|
-
|
|
25162
|
+
// codex reports token usage as a running total for this app-server
|
|
25163
|
+
// process. The harness wants this turn's figure: the total minus
|
|
25164
|
+
// whatever the process already carried before turn/start (a resumed
|
|
25165
|
+
// thread may restore earlier usage), banked on settle.
|
|
25166
|
+
usage: void 0,
|
|
25167
|
+
usageBaseline: void 0
|
|
25117
25168
|
};
|
|
25118
25169
|
const asks = /* @__PURE__ */ new Map();
|
|
25119
25170
|
let nextId = 1;
|
|
@@ -25140,6 +25191,12 @@ var init_codex = __esm({
|
|
|
25140
25191
|
rpcPending.set(id, {
|
|
25141
25192
|
resolve: (v) => {
|
|
25142
25193
|
clearTimeout(timer);
|
|
25194
|
+
if (method === "thread/start" || method === "thread/resume") {
|
|
25195
|
+
const returnedId = v?.thread?.id;
|
|
25196
|
+
const requestedId = method === "thread/resume" && params && typeof params === "object" && "threadId" in params ? params.threadId : null;
|
|
25197
|
+
if (typeof returnedId === "string" && returnedId) codexThreadId = returnedId;
|
|
25198
|
+
else if (typeof requestedId === "string" && requestedId) codexThreadId = requestedId;
|
|
25199
|
+
}
|
|
25143
25200
|
if (method === "turn/start") {
|
|
25144
25201
|
if (typeof v?.turn?.id !== "string" || !v.turn.id) {
|
|
25145
25202
|
reject(new Error("Codex did not return a native turn id"));
|
|
@@ -25268,6 +25325,11 @@ var init_codex = __esm({
|
|
|
25268
25325
|
const connectionError = msg.method === "error" && !("threadId" in p) && !("turnId" in p);
|
|
25269
25326
|
if (!connectionError) {
|
|
25270
25327
|
if (!codexThreadId || p.threadId !== codexThreadId) return;
|
|
25328
|
+
if (!codexTurnId && msg.method === "thread/tokenUsage/updated" && p.tokenUsage?.total) {
|
|
25329
|
+
const t2 = p.tokenUsage.total;
|
|
25330
|
+
state.usageBaseline = { input: t2.inputTokens ?? 0, output: t2.outputTokens ?? 0, cachedInput: t2.cachedInputTokens ?? 0 };
|
|
25331
|
+
return;
|
|
25332
|
+
}
|
|
25271
25333
|
if (!codexTurnId) {
|
|
25272
25334
|
if (startingNativeTurn) {
|
|
25273
25335
|
if (earlyNotifications.length >= 1024) {
|
|
@@ -25351,22 +25413,35 @@ var init_codex = __esm({
|
|
|
25351
25413
|
break;
|
|
25352
25414
|
}
|
|
25353
25415
|
case "thread/tokenUsage/updated": {
|
|
25354
|
-
const
|
|
25355
|
-
|
|
25416
|
+
const t2 = p.tokenUsage?.total;
|
|
25417
|
+
const last = p.tokenUsage?.last;
|
|
25418
|
+
const shape = (u4) => ({
|
|
25419
|
+
input: u4.inputTokens ?? 0,
|
|
25420
|
+
output: u4.outputTokens ?? 0,
|
|
25421
|
+
cachedInput: u4.cachedInputTokens ?? 0
|
|
25422
|
+
});
|
|
25423
|
+
if (t2) {
|
|
25424
|
+
const b = state.usageBaseline ?? { input: 0, output: 0, cachedInput: 0 };
|
|
25425
|
+
const now = shape(t2);
|
|
25356
25426
|
state.usage = {
|
|
25357
|
-
input:
|
|
25358
|
-
output:
|
|
25359
|
-
...typeof
|
|
25427
|
+
input: Math.max(0, now.input - b.input),
|
|
25428
|
+
output: Math.max(0, now.output - b.output),
|
|
25429
|
+
...typeof t2.cachedInputTokens === "number" ? { cachedInput: Math.max(0, now.cachedInput - b.cachedInput) } : {}
|
|
25360
25430
|
};
|
|
25431
|
+
} else if (last) {
|
|
25432
|
+
state.usage = { input: last.inputTokens ?? 0, output: last.outputTokens ?? 0, ...typeof last.cachedInputTokens === "number" ? { cachedInput: last.cachedInputTokens } : {} };
|
|
25361
25433
|
}
|
|
25362
|
-
const t2 = p.tokenUsage?.total;
|
|
25363
25434
|
if (t2) {
|
|
25435
|
+
const window = p.tokenUsage?.modelContextWindow;
|
|
25364
25436
|
emit({
|
|
25365
25437
|
...base2(threadId, turnId),
|
|
25366
25438
|
type: "thread.token-usage.updated",
|
|
25367
25439
|
input: t2.inputTokens ?? 0,
|
|
25368
25440
|
output: t2.outputTokens ?? 0,
|
|
25369
|
-
...typeof t2.cachedInputTokens === "number" ? { cachedInput: t2.cachedInputTokens } : {}
|
|
25441
|
+
...typeof t2.cachedInputTokens === "number" ? { cachedInput: t2.cachedInputTokens } : {},
|
|
25442
|
+
// the last call's prompt is what fills the window
|
|
25443
|
+
...last && typeof last.inputTokens === "number" ? { contextTokens: last.inputTokens } : {},
|
|
25444
|
+
...typeof window === "number" && window > 0 ? { contextWindow: window } : {}
|
|
25370
25445
|
});
|
|
25371
25446
|
}
|
|
25372
25447
|
break;
|
|
@@ -25420,7 +25495,7 @@ var init_codex = __esm({
|
|
|
25420
25495
|
const pend = rpcPending.get(msg.id);
|
|
25421
25496
|
if (pend) {
|
|
25422
25497
|
rpcPending.delete(msg.id);
|
|
25423
|
-
if (msg.error) pend.reject(new
|
|
25498
|
+
if (msg.error) pend.reject(new CodexRpcError(msg.error));
|
|
25424
25499
|
else pend.resolve(msg.result);
|
|
25425
25500
|
}
|
|
25426
25501
|
} else if (msg.id !== void 0 && msg.method) {
|
|
@@ -25451,7 +25526,7 @@ var init_codex = __esm({
|
|
|
25451
25526
|
}
|
|
25452
25527
|
const recentStderr = stderrSinceOutput.trim();
|
|
25453
25528
|
const hadStreamedOutput = codexTurnId !== null || state.sawStreamDelta;
|
|
25454
|
-
const verdict = classifyError({ exitCode: code, stderr: recentStderr
|
|
25529
|
+
const verdict = signal !== null ? { transient: false, reason: "interrupted" } : classifyError({ exitCode: code, stderr: recentStderr });
|
|
25455
25530
|
if (!stopRequested && codexTurnId === null && earlyNotifications.length === 0 && verdict.transient && attempt < RETRY_MAX_ATTEMPTS - 1) {
|
|
25456
25531
|
const delayMs = computeBackoff(attempt);
|
|
25457
25532
|
attempt++;
|
|
@@ -25518,30 +25593,39 @@ var init_codex = __esm({
|
|
|
25518
25593
|
autoAcceptPermissions = approvalMode === "full";
|
|
25519
25594
|
const cursor3 = typeof turn.resumeCursor === "string" ? turn.resumeCursor : null;
|
|
25520
25595
|
let startedModel = null;
|
|
25596
|
+
let resumedNativeThread = false;
|
|
25597
|
+
let promptText = turn.text;
|
|
25521
25598
|
if (cursor3) {
|
|
25599
|
+
const resumeThread = () => request("thread/resume", {
|
|
25600
|
+
threadId: cursor3,
|
|
25601
|
+
developerInstructions,
|
|
25602
|
+
...approvalParams.thread
|
|
25603
|
+
});
|
|
25522
25604
|
try {
|
|
25523
|
-
|
|
25524
|
-
|
|
25525
|
-
|
|
25526
|
-
|
|
25527
|
-
|
|
25528
|
-
codexThreadId = resumed?.thread?.id ?? cursor3;
|
|
25529
|
-
} catch (error51) {
|
|
25530
|
-
if (approvalParams.fallback && permissionProfileUnsupported(error51)) {
|
|
25605
|
+
let resumed;
|
|
25606
|
+
try {
|
|
25607
|
+
resumed = await resumeThread();
|
|
25608
|
+
} catch (error51) {
|
|
25609
|
+
if (!approvalParams.fallback || !permissionProfileUnsupported(error51)) throw error51;
|
|
25531
25610
|
approvalParams = approvalParams.fallback;
|
|
25532
|
-
|
|
25533
|
-
threadId: cursor3,
|
|
25534
|
-
developerInstructions,
|
|
25535
|
-
...approvalParams.thread
|
|
25536
|
-
});
|
|
25537
|
-
codexThreadId = resumed?.thread?.id ?? cursor3;
|
|
25538
|
-
} else {
|
|
25539
|
-
throw error51;
|
|
25611
|
+
resumed = await resumeThread();
|
|
25540
25612
|
}
|
|
25613
|
+
codexThreadId = resumed?.thread?.id ?? cursor3;
|
|
25614
|
+
resumedNativeThread = true;
|
|
25615
|
+
} catch (error51) {
|
|
25616
|
+
const failure = classifyResumeFailure({
|
|
25617
|
+
attempted: true,
|
|
25618
|
+
rejected: error51 instanceof CodexRpcError,
|
|
25619
|
+
promptSubmitted,
|
|
25620
|
+
producedOutput: state.sawStreamDelta
|
|
25621
|
+
});
|
|
25622
|
+
if (!config2.managed || recoveredMissingSession || stopRequested || state.settled || !turn.recoveryText?.trim() || !missingNativeCodexThread(error51, cursor3) || !mayReplay(failure)) throw error51;
|
|
25623
|
+
recoveredMissingSession = true;
|
|
25624
|
+
promptText = recoveryPromptFor({ recoveryText: turn.recoveryText, currentText: turn.text, failure }).text;
|
|
25541
25625
|
}
|
|
25542
25626
|
}
|
|
25543
25627
|
if (!codexThreadId) {
|
|
25544
|
-
const selection = decodeCodexSelection(turn.model);
|
|
25628
|
+
const selection = config2.managed ? { model: turn.model, modelProvider: "openmaus_company" } : decodeCodexSelection(turn.model);
|
|
25545
25629
|
const startThread = () => request("thread/start", {
|
|
25546
25630
|
developerInstructions,
|
|
25547
25631
|
cwd: turn.cwd ?? homedir13(),
|
|
@@ -25562,14 +25646,14 @@ var init_codex = __esm({
|
|
|
25562
25646
|
startedModel = started?.model ?? null;
|
|
25563
25647
|
}
|
|
25564
25648
|
if (!codexThreadId) throw new Error("Codex did not return a native thread id");
|
|
25565
|
-
await syncCodexInstructions(threadId, codexThreadId, developerInstructions,
|
|
25649
|
+
await syncCodexInstructions(threadId, codexThreadId, developerInstructions, resumedNativeThread, request);
|
|
25566
25650
|
emit({ ...base2(threadId, turnId), type: "session.started", sessionId: codexThreadId, model: startedModel ?? turn.model ?? null });
|
|
25567
|
-
const promptText = turn.text;
|
|
25568
25651
|
const turnInput = [
|
|
25569
25652
|
...promptText ? [{ type: "text", text: promptText }] : [],
|
|
25570
25653
|
...(turn.images ?? []).map((image) => ({ type: "localImage", path: image.path }))
|
|
25571
25654
|
];
|
|
25572
25655
|
const startTurn = () => {
|
|
25656
|
+
promptSubmitted = true;
|
|
25573
25657
|
startingNativeTurn = true;
|
|
25574
25658
|
return request("turn/start", {
|
|
25575
25659
|
threadId: codexThreadId,
|
|
@@ -25599,7 +25683,7 @@ var init_codex = __esm({
|
|
|
25599
25683
|
const message2 = e instanceof Error ? e.message : String(e);
|
|
25600
25684
|
const needsAuth = /(?:\b401\b|unauthorized|missing bearer|authentication required)/i.test(message2);
|
|
25601
25685
|
const verdict = classifyError(failure);
|
|
25602
|
-
if (!state.settled && !abandoned && !needsAuth && verdict.transient && attempt < RETRY_MAX_ATTEMPTS - 1 && state.sawStreamDelta === false) {
|
|
25686
|
+
if (!state.settled && !abandoned && !recoveredMissingSession && !stopRequested && !needsAuth && verdict.transient && attempt < RETRY_MAX_ATTEMPTS - 1 && state.sawStreamDelta === false) {
|
|
25603
25687
|
const delayMs = computeBackoff(attempt);
|
|
25604
25688
|
attempt++;
|
|
25605
25689
|
emit({
|
|
@@ -25649,6 +25733,7 @@ var init_codex = __esm({
|
|
|
25649
25733
|
);
|
|
25650
25734
|
});
|
|
25651
25735
|
if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
|
|
25736
|
+
if (config2.managed) return { state: "available", version: version2, authenticated: Boolean(input.environment.OPENMAUSBOT_COMPANY_API_KEY && input.environment.CODEX_HOME), billing: "metered" };
|
|
25652
25737
|
const authenticated = await new Promise((resolve12) => {
|
|
25653
25738
|
execCli(
|
|
25654
25739
|
config2.cli,
|