openmausbot 0.1.85 → 0.1.87
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 -2
- package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/assets/abnfDiagram-O67JEVCF-BTiuL79F.js +1 -0
- package/dist/assets/arc-C88Blc2v.js +1 -0
- package/dist/assets/architectureDiagram-NJMV4G6O-BZsJIZrb.js +36 -0
- package/dist/assets/blockDiagram-BEXU5L5S-CVeMe9Ah.js +140 -0
- package/dist/assets/c4Diagram-YGBWAQC7-Cedk3Bhx.js +38 -0
- package/dist/assets/channel-taCNRlUU.js +1 -0
- package/dist/assets/chunk-2Q5K7J3B-D-VRqzTB.js +1 -0
- package/dist/assets/chunk-3FUC2YCW-BChov01Y.js +2 -0
- package/dist/assets/chunk-5VM5RSS4-C-TfwvHy.js +15 -0
- package/dist/assets/chunk-GTNCS2PH-Db7CGj5Y.js +88 -0
- package/dist/assets/chunk-GWA4HPMP-CNvIfqKT.js +1 -0
- package/dist/assets/chunk-JWPE2WC7-C_bEp5tq.js +1 -0
- package/dist/assets/chunk-NETBCI7D-Coi4BOls.js +1 -0
- package/dist/assets/chunk-WEXAMYUT-CzylEuL3.js +1 -0
- package/dist/assets/chunk-XXDRQBXY-m7p7ztaD.js +1 -0
- package/dist/assets/classDiagram-v2-NBCMYWYE-BMy6o9x2.js +217 -0
- package/dist/assets/cose-bilkent-JH36ORCC-BDQ__0_J.js +1 -0
- package/dist/assets/cynefin-OW5HDTMX-Djv4ghUb.js +166 -0
- package/dist/assets/cynefinDiagram-VND7K2PF-BULrlGYH.js +62 -0
- package/dist/assets/cytoscape.esm-BB4DxJjf.js +321 -0
- package/dist/assets/dagre-6A5THRUB-D-jrT_hU.js +4 -0
- package/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/assets/diagram-22UHCM2B-p2UhQmfL.js +200 -0
- package/dist/assets/diagram-3UASUU5V-DHvGWZ7q.js +24 -0
- package/dist/assets/diagram-ATOU4E4O-ChhKDot-.js +3 -0
- package/dist/assets/diagram-CDSNMT55-B-T7A43R.js +30 -0
- package/dist/assets/diagram-MLGK6HIB-CJm8ENNY.js +24 -0
- package/dist/assets/diagram-MPIPVDR6-510tlza8.js +41 -0
- package/dist/assets/ebnfDiagram-ZINNZB2B-PkvRPHel.js +1 -0
- package/dist/assets/elk-276RUBZZ-BVBVPoX3.js +27 -0
- package/dist/assets/erDiagram-OPXOYQCR-BgYMVm7L.js +99 -0
- package/dist/assets/flowDiagram-KWPJA3E3-BGqsnc_3.js +213 -0
- package/dist/assets/ganttDiagram-FUAMR5RP-D_-UeReH.js +292 -0
- package/dist/assets/gitGraphDiagram-X574FWY7-D0uooONx.js +106 -0
- package/dist/assets/graph-D8UmR1vK.js +1 -0
- package/dist/assets/index-BwdMAQ6p.css +1 -0
- package/dist/assets/index-ByJennr7.js +581 -0
- package/dist/assets/{index-CTNNoqSJ.js → index-zRsJERGJ.js} +1 -1
- package/dist/assets/infoDiagram-VRGFBTTK-B9e1z77f.js +2 -0
- package/dist/assets/init-Gi6I4Gst.js +1 -0
- package/dist/assets/ishikawaDiagram-OU5B5YK6-BB4vNwvD.js +70 -0
- package/dist/assets/journeyDiagram-ZHPQQLJL-DpkosOTB.js +139 -0
- package/dist/assets/kanban-definition-PNTS6WVX-DbDP4kUu.js +89 -0
- package/dist/assets/linear-DBJGPmjT.js +1 -0
- package/dist/assets/mermaid.core-DWPRi-ue.js +311 -0
- package/dist/assets/mindmap-definition-NLK3R4M7-nszBbJmx.js +96 -0
- package/dist/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/assets/pegDiagram-GJSIUBJH-CWykJWu_.js +1 -0
- package/dist/assets/pieDiagram-5QR66LMP-g3Da-Vnv.js +39 -0
- package/dist/assets/quadrantDiagram-O4NWA36T-Wzrlpzgh.js +7 -0
- package/dist/assets/railroadDiagram-XR7U4H2S-moHTFMC0.js +1 -0
- package/dist/assets/requirementDiagram-PLB6GJNP-CwfXdFH8.js +84 -0
- package/dist/assets/sankeyDiagram-IPEJSGJF-3ZROYvnq.js +40 -0
- package/dist/assets/sequenceDiagram-PO4LG4MO-E1TBebP8.js +169 -0
- package/dist/assets/sizeCapture-INFHLROL-DHKEU5pu.js +1 -0
- package/dist/assets/stateDiagram-v2-GCMORJYK-BguEj09D.js +291 -0
- package/dist/assets/swimlanes-2SLR337P-C7IDYnhd.js +1 -0
- package/dist/assets/swimlanesDiagram-TC7HE7FX-BpEdoB2e.js +8 -0
- package/dist/assets/timeline-definition-EJHVYXUP-DCW-F5PW.js +120 -0
- package/dist/assets/usecaseDiagram-POWQR4AR-xBMFtWYV.js +370 -0
- package/dist/assets/vennDiagram-UO4OBE2U-B5nIkuH8.js +34 -0
- package/dist/assets/wardleyDiagram-VNRHLVJA-DYFAhdbr.js +78 -0
- package/dist/assets/xychartDiagram-PMCCYNJV-DeXwX6Cz.js +7 -0
- package/dist/index.html +2 -2
- package/dist-server/browser-proxy.js +2 -1
- package/dist-server/container-mcp.js +1047 -173
- package/dist-server/drivers/agents-proxy.js +16121 -1504
- package/dist-server/drivers/phone-proxy.js +33 -2
- package/dist-server/enterprise/LICENSE +32 -0
- package/dist-server/enterprise/server/index.js +5 -5
- package/dist-server/index.js +16134 -7446
- package/dist-server/local-computer-proxy.js +3 -3
- package/dist-server/local-computer.js +53 -17
- package/dist-server/mcp-server.js +3 -1
- package/dist-server/openmausbot.js +9353 -6124
- package/dist-server/pair-cli.js +9353 -6124
- package/dist-server/permission-proxy.js +29 -9
- package/dist-server/server/admin-activity.js +410 -0
- package/dist-server/server/attachments.js +55 -0
- package/dist-server/server/auto-approve.js +4 -3
- package/dist-server/server/auto-vm-claims.js +1 -0
- package/dist-server/server/bot-package.js +18 -292
- package/dist-server/server/bot-profile.js +5 -17
- package/dist-server/server/bot-visibility.js +462 -0
- package/dist-server/server/box-create-idempotency.js +3 -3
- package/dist-server/server/box.js +59 -56
- package/dist-server/server/browser-proxy.js +3 -2
- package/dist-server/server/browser-runtime.js +38 -2
- package/dist-server/server/channel-queue.js +2 -0
- package/dist-server/server/cli-prompts.js +24 -2
- package/dist-server/server/cli.js +81 -12
- package/dist-server/server/command-allowlist.js +154 -0
- package/dist-server/server/composio.js +49 -11
- package/dist-server/server/computer-wait.js +22 -9
- package/dist-server/server/config.js +133 -17
- package/dist-server/server/connector-verdict.js +141 -0
- package/dist-server/server/container-computer.js +1 -1
- package/dist-server/server/decision-log.js +209 -48
- package/dist-server/server/default-model-selection.js +29 -3
- package/dist-server/server/delegations.js +97 -44
- package/dist-server/server/drivers/acp/core.js +163 -33
- package/dist-server/server/drivers/acp/grok.js +4 -3
- package/dist-server/server/drivers/agents-call.js +1162 -0
- package/dist-server/server/drivers/agents-catalog.js +689 -0
- package/dist-server/server/drivers/agents-client.js +28 -0
- package/dist-server/server/drivers/agents-proxy.js +18 -1722
- package/dist-server/server/drivers/boxagent.js +174 -36
- package/dist-server/server/drivers/builtIn.js +2 -0
- package/dist-server/server/drivers/chat-box-tools.js +90 -0
- package/dist-server/server/drivers/chat-images.js +54 -0
- package/dist-server/server/drivers/chat-mcp-tools.js +55 -10
- package/dist-server/server/drivers/chat-tool-approval.js +70 -18
- package/dist-server/server/drivers/claude.js +28 -8
- package/dist-server/server/drivers/codex-instructions.js +48 -6
- package/dist-server/server/drivers/codex-mcp-names.js +44 -0
- package/dist-server/server/drivers/codex-tool-surface.js +20 -0
- package/dist-server/server/drivers/codex.js +121 -34
- package/dist-server/server/drivers/grok.js +2 -1
- package/dist-server/server/drivers/mistral.js +115 -0
- package/dist-server/server/drivers/openai-chat.js +155 -32
- package/dist-server/server/drivers/openai-compat.js +16 -8
- package/dist-server/server/drivers/permission-command.js +35 -0
- package/dist-server/server/drivers/phone-proxy.js +47 -2
- package/dist-server/server/drivers/pi.js +75 -4
- package/dist-server/server/drivers/prompt-split.js +87 -0
- package/dist-server/server/enterprise.js +97 -16
- package/dist-server/server/external-runtime.js +83 -0
- package/dist-server/server/fleet.js +1 -1
- package/dist-server/server/group-thread-usage.js +103 -0
- package/dist-server/server/guarded-requests.js +60 -0
- package/dist-server/server/harness/http.js +61 -0
- package/dist-server/server/harness/registry.js +1 -0
- package/dist-server/server/hosted-models.js +151 -0
- package/dist-server/server/hosted-slack.js +11 -0
- package/dist-server/server/index.js +3091 -658
- package/dist-server/server/local-computer.js +72 -23
- package/dist-server/server/managed-desktop.js +79 -14
- package/dist-server/server/managed-policy.js +153 -0
- package/dist-server/server/mcp-bridge.js +6 -6
- package/dist-server/server/message-db.js +28 -0
- package/dist-server/server/model-context-window.js +7 -0
- package/dist-server/server/model-prices.js +121 -0
- package/dist-server/server/new-bot-defaults.js +115 -0
- package/dist-server/server/notify.js +10 -1
- package/dist-server/server/org-library.js +1051 -0
- package/dist-server/server/package-export.js +627 -39
- package/dist-server/server/package-import.js +458 -0
- package/dist-server/server/package-parts.js +87 -0
- package/dist-server/server/peer-approval.js +16 -7
- package/dist-server/server/peer-roster.js +23 -2
- package/dist-server/server/presets.js +492 -0
- package/dist-server/server/provider-key-check.js +3 -2
- package/dist-server/server/published-teams.js +80 -0
- package/dist-server/server/recent-work.js +15 -0
- package/dist-server/server/request-auth.js +96 -0
- package/dist-server/server/room-handoffs.js +44 -14
- package/dist-server/server/routes/bot-presets.js +25 -0
- package/dist-server/server/routes/hosted-slack.js +20 -0
- package/dist-server/server/routes/table.js +14 -0
- package/dist-server/server/routine-requests.js +6 -3
- package/dist-server/server/routines.js +63 -1
- package/dist-server/server/section-context.js +10 -0
- package/dist-server/server/skills.js +34 -61
- package/dist-server/server/spend.js +111 -16
- package/dist-server/server/steer-queue.js +9 -3
- package/dist-server/server/store.js +550 -35
- package/dist-server/server/surface.js +10 -4
- package/dist-server/server/system-prompt.js +12 -4
- package/dist-server/server/team-backup.js +16 -3
- package/dist-server/server/team-computers.js +10 -0
- package/dist-server/server/team-library.js +6 -2
- package/dist-server/server/team-manifest.js +4 -3
- package/dist-server/server/team-setup-requests.js +16 -5
- package/dist-server/server/thread-events.js +17 -1
- package/dist-server/server/thread-starters.js +53 -0
- package/dist-server/server/turn-context.js +2 -0
- package/dist-server/server/turn-watchdog.js +12 -3
- package/dist-server/server/usage-ledger.js +43 -9
- package/dist-server/server/vps-computer.js +139 -51
- package/dist-server/server/vps-container-mcp.js +7 -0
- package/dist-server/server/vps-ssh.js +36 -7
- package/dist-server/server/workspace-backup-policy.js +21 -2
- package/dist-server/server/workspace-backup.js +7 -4
- package/dist-server/server/workspace.js +1 -1
- package/dist-server/shared/approval-mode.js +1 -1
- package/dist-server/shared/ask-question.js +188 -12
- package/dist-server/shared/bot-profile.js +15 -0
- package/dist-server/shared/command-allowlist.js +1 -0
- package/dist-server/shared/credential-request.js +1 -1
- package/dist-server/shared/mention-boundary.js +15 -0
- package/dist-server/shared/package-format.js +967 -0
- package/dist-server/shared/routines.js +7 -1
- package/dist-server/shared/skill-md.js +64 -0
- package/dist-server/shared/team-backup.js +9 -0
- package/dist-server/shared/wire.js +4 -0
- package/dist-server/src/lib/composer-attachments.js +16 -0
- package/dist-server/vps-container-mcp.js +1147 -179
- package/enterprise/README.md +33 -12
- package/enterprise/server/index.js +5 -5
- package/package.json +1 -1
- package/dist/assets/index-Ba9G44HI.js +0 -310
- package/dist/assets/index-CkRNp7wX.css +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { codexToolSurfaceArgs } from "./codex-tool-surface.js";
|
|
1
2
|
// Codex driver — upstream CodexDriver skeleton over agentcal's
|
|
2
3
|
// drivers/codex.js runtime: the official `codex` CLI headless over its
|
|
3
4
|
// app-server JSON-RPC protocol (newline-delimited JSON on stdio).
|
|
@@ -11,6 +12,7 @@
|
|
|
11
12
|
// and preserves that history or reports a failed resume.
|
|
12
13
|
import { existsSync } from "node:fs";
|
|
13
14
|
import { homedir } from "node:os";
|
|
15
|
+
import { codexConfigMcpServerNames, mountedMcpServerName } from "./codex-mcp-names.js";
|
|
14
16
|
import { stripWorkspaceCredentialEnv } from "../config.js";
|
|
15
17
|
import { describeSpawnFailure, execCli, killCliTree, spawnCli } from "../procs.js";
|
|
16
18
|
import { isHarnessOwnedMcpEnvName } from "../mcp-registry.js";
|
|
@@ -20,12 +22,15 @@ import { codexLocalProviderArgs } from "./local-inject.js";
|
|
|
20
22
|
import { augmentedPath, splitCliString } from "../env-path.js";
|
|
21
23
|
import { classifyError, computeBackoff, interruptibleDelay, RETRY_MAX_ATTEMPTS } from "./retry.js";
|
|
22
24
|
import { appendNative } from "./native.js";
|
|
25
|
+
import { permissionCommand, permissionLaunchCwd } from "./permission-command.js";
|
|
23
26
|
import { commandSummary, toolDetailPreview } from "../tool-summary.js";
|
|
24
27
|
import { codexDeveloperInstructions, syncCodexInstructions } from "./codex-instructions.js";
|
|
28
|
+
import { volatileContextNote, withContextNote } from "./prompt-split.js";
|
|
25
29
|
import { CodexDeviceAuthController } from "./codex-device-auth.js";
|
|
26
30
|
import { codexAccountEmail } from "./codex-identity.js";
|
|
27
31
|
import { classifyResumeFailure, mayReplay, recoveryPromptFor } from "../resume-recovery.js";
|
|
28
32
|
import { extractMcpImages } from "../mcp-tool-images.js";
|
|
33
|
+
import { parseProtocolAskQuestions, questionAnswersById, questionChoices } from "../../shared/ask-question.js";
|
|
29
34
|
export { decodeCodexSelection, readCodexModelCatalog, STATIC_CODEX_MODELS } from "./codex-catalog.js";
|
|
30
35
|
const DRIVER_KIND = "codex";
|
|
31
36
|
const ASTRA_MODEL_ID = "gpt-6-astra";
|
|
@@ -125,9 +130,16 @@ export function managedCodexArgs(config) {
|
|
|
125
130
|
"-c", "shell_environment_policy.ignore_default_excludes=false",
|
|
126
131
|
];
|
|
127
132
|
}
|
|
128
|
-
const QUESTION_TIMEOUT_NOTE = "No answer was given — use your best judgment.";
|
|
129
133
|
const DENY_TIMEOUT_NOTE = "OpenMausBot: nobody answered this permission request in time. Skip this action and finish what you can without it.";
|
|
130
134
|
const skippedSseServers = new Set();
|
|
135
|
+
const renamedMcpServers = new Set();
|
|
136
|
+
/** Logged once per name: the rename is deliberate, not a lost server. */
|
|
137
|
+
function noteRenamedMcpServer(name, mountName) {
|
|
138
|
+
if (renamedMcpServers.has(name))
|
|
139
|
+
return;
|
|
140
|
+
renamedMcpServers.add(name);
|
|
141
|
+
console.error(`codex: MCP server ${JSON.stringify(name)} is also declared in Codex's own config.toml — mounted as ${JSON.stringify(mountName)} for this bot so the two do not merge`);
|
|
142
|
+
}
|
|
131
143
|
function noteSkippedSseServer(name) {
|
|
132
144
|
if (skippedSseServers.has(name))
|
|
133
145
|
return;
|
|
@@ -266,6 +278,21 @@ function namedApprovalParams(mode) {
|
|
|
266
278
|
},
|
|
267
279
|
};
|
|
268
280
|
}
|
|
281
|
+
/** Keep the turn on the complete sandbox resolved by native start/resume. */
|
|
282
|
+
function withResolvedSandbox(params, session) {
|
|
283
|
+
const requested = plainRecord(params.turn.sandboxPolicy);
|
|
284
|
+
// Named permission profiles own their policy; do not mix both selectors.
|
|
285
|
+
if (!requested)
|
|
286
|
+
return params;
|
|
287
|
+
const sandbox = plainRecord(plainRecord(session)?.sandbox);
|
|
288
|
+
if (!sandbox || typeof sandbox.type !== "string") {
|
|
289
|
+
throw new Error("Codex did not return its resolved sandbox policy. Update Codex, then retry; the turn was not started because its permissions could not be verified.");
|
|
290
|
+
}
|
|
291
|
+
if (sandbox.type !== requested.type) {
|
|
292
|
+
throw new Error("Codex did not apply the requested sandbox mode; cannot safely start the turn.");
|
|
293
|
+
}
|
|
294
|
+
return { ...params, turn: { ...params.turn, sandboxPolicy: sandbox } };
|
|
295
|
+
}
|
|
269
296
|
function effectiveApprovalPolicy(value) {
|
|
270
297
|
if (value === "untrusted" || value === "on-request" || value === "never")
|
|
271
298
|
return value;
|
|
@@ -578,7 +605,7 @@ export const CodexDriver = {
|
|
|
578
605
|
const retryScale = Number(process.env.FAKE_CODEX_RETRY_SCALE ?? "1");
|
|
579
606
|
const launchAttempt = async (attempt) => {
|
|
580
607
|
const env = childEnv();
|
|
581
|
-
const appServerArgs = ["app-server", ...(config.managed ? managedCodexArgs(config.managed) : codexLocalProviderArgs(env, turn.model))];
|
|
608
|
+
const appServerArgs = ["app-server", ...(config.managed ? managedCodexArgs(config.managed) : codexLocalProviderArgs(env, turn.model)), ...codexToolSurfaceArgs()];
|
|
582
609
|
if (turn.integrations?.composio) {
|
|
583
610
|
mountMcpServer(appServerArgs, env, "openmausbot_connectors", turn.integrations.composio);
|
|
584
611
|
}
|
|
@@ -593,6 +620,11 @@ export const CodexDriver = {
|
|
|
593
620
|
if (turn.integrations?.browser) {
|
|
594
621
|
mountMcpServer(appServerArgs, env, "browser", turn.integrations.browser);
|
|
595
622
|
}
|
|
623
|
+
// A custom server named like one in the user's own config.toml would
|
|
624
|
+
// be merged with it by the `-c` override — a stdio command over a
|
|
625
|
+
// remote url is "invalid configuration" and kills the turn before the
|
|
626
|
+
// model is asked. Such a server mounts under a name of its own.
|
|
627
|
+
const declaredInCodexConfig = codexConfigMcpServerNames(env);
|
|
596
628
|
for (const [name, server] of Object.entries(turn.integrations?.custom ?? {})) {
|
|
597
629
|
// codex speaks streamable HTTP to a remote server, not the older
|
|
598
630
|
// SSE transport: such an entry still reaches Claude bots, and is
|
|
@@ -601,7 +633,10 @@ export const CodexDriver = {
|
|
|
601
633
|
noteSkippedSseServer(name);
|
|
602
634
|
continue;
|
|
603
635
|
}
|
|
604
|
-
|
|
636
|
+
const mountName = mountedMcpServerName(name, declaredInCodexConfig);
|
|
637
|
+
if (mountName !== name)
|
|
638
|
+
noteRenamedMcpServer(name, mountName);
|
|
639
|
+
mountMcpServer(appServerArgs, env, mountName, server, false);
|
|
605
640
|
}
|
|
606
641
|
if (turn.integrations?.phone) {
|
|
607
642
|
const bridge = turn.integrations.phone;
|
|
@@ -609,6 +644,7 @@ export const CodexDriver = {
|
|
|
609
644
|
const prefix = "mcp_servers.openmausbot_phone";
|
|
610
645
|
appServerArgs.push("-c", `${prefix}.command=${JSON.stringify(bridge.command)}`, "-c", `${prefix}.args=${JSON.stringify(bridge.args)}`, "-c", `${prefix}.env_vars=${JSON.stringify(Object.keys(bridge.env))}`, "-c", `${prefix}.default_tools_approval_mode="auto"`);
|
|
611
646
|
}
|
|
647
|
+
const commandCwd = permissionLaunchCwd(turn.cwd ?? homedir());
|
|
612
648
|
const child = spawnCli(config.cli, appServerArgs, {
|
|
613
649
|
cwd: turn.cwd ?? homedir(),
|
|
614
650
|
env,
|
|
@@ -821,23 +857,22 @@ export const CodexDriver = {
|
|
|
821
857
|
}
|
|
822
858
|
return;
|
|
823
859
|
}
|
|
824
|
-
//
|
|
825
|
-
//
|
|
826
|
-
//
|
|
827
|
-
//
|
|
828
|
-
//
|
|
829
|
-
|
|
830
|
-
|
|
860
|
+
// The whole set rides one card, answered per id: the protocol pairs
|
|
861
|
+
// each question with its own id, and the card's single reply is
|
|
862
|
+
// mapped back block by block (or as the flat single-question
|
|
863
|
+
// fallback). The only refusal left is an ask with nothing answerable
|
|
864
|
+
// — #1237 is closed: a bundle no longer copies one answer into
|
|
865
|
+
// every id.
|
|
866
|
+
const protocolQuestions = isQuestion ? parseProtocolAskQuestions(params.questions) : null;
|
|
867
|
+
if (isQuestion && !protocolQuestions) {
|
|
831
868
|
send({
|
|
832
869
|
jsonrpc: "2.0",
|
|
833
870
|
id: msg.id,
|
|
834
871
|
error: {
|
|
835
872
|
code: -32602,
|
|
836
|
-
message:
|
|
837
|
-
?
|
|
838
|
-
:
|
|
839
|
-
? "ask supports one question per call; this request sent none."
|
|
840
|
-
: "ask supports one question per call; params.questions must be an array with exactly one question.",
|
|
873
|
+
message: Array.isArray(params.questions)
|
|
874
|
+
? "ask needs at least one answerable question — a string id and question text each; this request sent none."
|
|
875
|
+
: "ask needs params.questions to be an array of questions, each with a string id and question text.",
|
|
841
876
|
},
|
|
842
877
|
});
|
|
843
878
|
return;
|
|
@@ -877,23 +912,36 @@ export const CodexDriver = {
|
|
|
877
912
|
? (mcpAppApproval?.summary ?? (typeof params.message === "string" ? params.message : "MCP access requested"))
|
|
878
913
|
: typeof params.command === "string"
|
|
879
914
|
? params.command
|
|
880
|
-
:
|
|
881
|
-
?
|
|
882
|
-
:
|
|
883
|
-
? params.
|
|
884
|
-
:
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
915
|
+
: protocolQuestions
|
|
916
|
+
? protocolQuestions.map(({ question }) => question.question).join(" · ")
|
|
917
|
+
: Array.isArray(params.questions)
|
|
918
|
+
? params.questions.map((q) => q.question ?? q.header).filter(Boolean).join(" · ")
|
|
919
|
+
: typeof params.reason === "string"
|
|
920
|
+
? params.reason
|
|
921
|
+
: tool;
|
|
922
|
+
// Flat choices only when one non-multiselect question can actually
|
|
923
|
+
// be answered by a bare reply; a bundle's first-question buttons
|
|
924
|
+
// would be an unusable lie for flat clients.
|
|
925
|
+
const choices = isQuestion && protocolQuestions ? questionChoices(protocolQuestions.map(({ question }) => question)) : undefined;
|
|
888
926
|
const finish = (behavior, message, source = "user") => {
|
|
889
927
|
if (!asks.delete(requestId))
|
|
890
928
|
return;
|
|
891
929
|
clearTimeout(timer);
|
|
892
930
|
if (isQuestion) {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
931
|
+
// Only the person's reply is filed: Q:/A: blocks mapped to the
|
|
932
|
+
// id that asked them, or the flat fallback for a single
|
|
933
|
+
// question. Timeout and turn teardown send empty answers so
|
|
934
|
+
// every id reads unanswered — system notes never occupy the
|
|
935
|
+
// slot the model reads as the person's words (the rule
|
|
936
|
+
// permission-proxy already follows).
|
|
937
|
+
const mapped = behavior === "answer" && source === "user" && typeof message === "string"
|
|
938
|
+
? questionAnswersById(message, protocolQuestions ?? [])
|
|
939
|
+
: {};
|
|
940
|
+
// Null prototype so an opaque id like __proto__ becomes a real
|
|
941
|
+
// answer key instead of hitting the inherited setter.
|
|
942
|
+
const answers = Object.create(null);
|
|
943
|
+
for (const [id, answer] of Object.entries(mapped))
|
|
944
|
+
answers[id] = { answers: [answer] };
|
|
897
945
|
send({ jsonrpc: "2.0", id: msg.id, result: { answers } });
|
|
898
946
|
}
|
|
899
947
|
else {
|
|
@@ -905,7 +953,11 @@ export const CodexDriver = {
|
|
|
905
953
|
}
|
|
906
954
|
emit({ ...base(threadId, turnId), type: "request.resolved", requestId, behavior, source });
|
|
907
955
|
};
|
|
908
|
-
const timer = setTimeout(
|
|
956
|
+
const timer = setTimeout(
|
|
957
|
+
// A timed-out question resolves as denied, not answered: the card
|
|
958
|
+
// closes with no reply (answers stay empty either way), and the
|
|
959
|
+
// resolve event must not claim an answer that never happened.
|
|
960
|
+
() => finish("deny", isQuestion ? undefined : DENY_TIMEOUT_NOTE, "timeout"), 15 * 60_000);
|
|
909
961
|
timer.unref?.();
|
|
910
962
|
asks.set(requestId, finish);
|
|
911
963
|
emit({
|
|
@@ -915,9 +967,15 @@ export const CodexDriver = {
|
|
|
915
967
|
requestType: isQuestion ? "question" : "permission",
|
|
916
968
|
tool,
|
|
917
969
|
summary,
|
|
970
|
+
command: method === "execCommandApproval" || method === "item/commandExecution/requestApproval"
|
|
971
|
+
? permissionCommand(params.command, params.cwd ?? (
|
|
972
|
+
// Helpers may have a different workspace from their parent.
|
|
973
|
+
!params.threadId || params.threadId === codexThreadId ? commandCwd : undefined)) : undefined,
|
|
918
974
|
choices,
|
|
975
|
+
...(protocolQuestions ? { questions: protocolQuestions.map((pair) => pair.question) } : {}),
|
|
919
976
|
approvalScope: controlsHost ? "local-computer" : undefined,
|
|
920
|
-
requiresExplicitApproval: isAdditionalPermission ||
|
|
977
|
+
requiresExplicitApproval: isAdditionalPermission || ((method === "execCommandApproval" || method === "item/commandExecution/requestApproval") &&
|
|
978
|
+
(params.additionalPermissions != null || params.networkApprovalContext != null)) || undefined,
|
|
921
979
|
});
|
|
922
980
|
};
|
|
923
981
|
const handleNotification = (msg) => {
|
|
@@ -1288,12 +1346,28 @@ export const CodexDriver = {
|
|
|
1288
1346
|
});
|
|
1289
1347
|
effectiveConfig = configured?.config;
|
|
1290
1348
|
}
|
|
1291
|
-
catch {
|
|
1349
|
+
catch (error) {
|
|
1292
1350
|
// Do not expose a possibly secret-bearing native config error or
|
|
1293
|
-
// overwrite unknown instructions with an empty fallback.
|
|
1294
|
-
|
|
1351
|
+
// overwrite unknown instructions with an empty fallback. A config
|
|
1352
|
+
// codex itself rejected is the one case worth naming: the person
|
|
1353
|
+
// can act on it, and the message carries no credential.
|
|
1354
|
+
const invalid = error instanceof CodexRpcError && /^invalid configuration\b/i.test(error.message);
|
|
1355
|
+
throw new Error(invalid
|
|
1356
|
+
? "Codex rejected its configuration as invalid. Check ~/.codex/config.toml (or CODEX_HOME) for a broken entry, then retry."
|
|
1357
|
+
: "Could not read Codex configuration; cannot safely update bot instructions. Retry after checking Codex.");
|
|
1295
1358
|
}
|
|
1296
|
-
|
|
1359
|
+
// Only the stable half of the prompt belongs in the developer slot:
|
|
1360
|
+
// it is the part that must survive compaction unchanged, and any
|
|
1361
|
+
// change to it invalidates the provider's cached prefix. The volatile
|
|
1362
|
+
// half (memory, mentions, outstanding teammate work) is delivered
|
|
1363
|
+
// inside the turn that changed it, after the cached prefix, the same
|
|
1364
|
+
// contract SendTurnInput.systemStable documents. Without the split
|
|
1365
|
+
// the driver keeps the previous single-block behaviour.
|
|
1366
|
+
const stableInstructions = typeof turn.systemStable === "string" && typeof turn.systemVolatile === "string"
|
|
1367
|
+
? turn.systemStable
|
|
1368
|
+
: null;
|
|
1369
|
+
const promptSplit = stableInstructions !== null;
|
|
1370
|
+
const developerInstructions = codexDeveloperInstructions(effectiveConfig, stableInstructions ?? turn.system ?? "");
|
|
1297
1371
|
let approvalParams;
|
|
1298
1372
|
if (approvalMode === "custom") {
|
|
1299
1373
|
// config/read returns the effective global + project config for this
|
|
@@ -1336,6 +1410,7 @@ export const CodexDriver = {
|
|
|
1336
1410
|
approvalParams = approvalParams.fallback;
|
|
1337
1411
|
resumed = await resumeThread();
|
|
1338
1412
|
}
|
|
1413
|
+
approvalParams = withResolvedSandbox(approvalParams, resumed);
|
|
1339
1414
|
codexThreadId = resumed?.thread?.id ?? cursor;
|
|
1340
1415
|
resumedNativeThread = true;
|
|
1341
1416
|
}
|
|
@@ -1381,12 +1456,20 @@ export const CodexDriver = {
|
|
|
1381
1456
|
approvalParams = approvalParams.fallback;
|
|
1382
1457
|
started = await startThread();
|
|
1383
1458
|
}
|
|
1459
|
+
approvalParams = withResolvedSandbox(approvalParams, started);
|
|
1384
1460
|
codexThreadId = started?.thread?.id ?? null;
|
|
1385
1461
|
startedModel = started?.model ?? null;
|
|
1386
1462
|
}
|
|
1387
1463
|
if (!codexThreadId)
|
|
1388
1464
|
throw new Error("Codex did not return a native thread id");
|
|
1389
|
-
await syncCodexInstructions(threadId, codexThreadId, developerInstructions, resumedNativeThread, request);
|
|
1465
|
+
const { deliverVolatile, hadVolatile, commitVolatile } = await syncCodexInstructions(threadId, codexThreadId, developerInstructions, promptSplit ? turn.systemVolatile ?? "" : "", resumedNativeThread, request, Boolean(turn.mentionTurn));
|
|
1466
|
+
// A changed volatile half rides the next user input as a labelled
|
|
1467
|
+
// context block. It never touches the developer slot, so an
|
|
1468
|
+
// ordinary memory write or roster change neither appends a second
|
|
1469
|
+
// copy of the prompt to history nor re-uploads the conversation.
|
|
1470
|
+
if (deliverVolatile) {
|
|
1471
|
+
promptText = withContextNote(volatileContextNote(promptSplit ? turn.systemVolatile ?? "" : "", hadVolatile), promptText);
|
|
1472
|
+
}
|
|
1390
1473
|
emit({ ...base(threadId, turnId), type: "session.started", sessionId: codexThreadId, model: startedModel ?? turn.model ?? null, ...(rebuiltFromReplay ? { rebuilt: true } : {}) });
|
|
1391
1474
|
const turnInput = [
|
|
1392
1475
|
...(promptText ? [{ type: "text", text: promptText }] : []),
|
|
@@ -1420,6 +1503,10 @@ export const CodexDriver = {
|
|
|
1420
1503
|
approvalParams = approvalParams.fallback;
|
|
1421
1504
|
await startTurn();
|
|
1422
1505
|
}
|
|
1506
|
+
// turn/start accepted the input: only now may the receipt claim the
|
|
1507
|
+
// volatile half was delivered, so a rejected turn redelivers on retry.
|
|
1508
|
+
if (commitVolatile)
|
|
1509
|
+
commitVolatile();
|
|
1423
1510
|
}
|
|
1424
1511
|
catch (e) {
|
|
1425
1512
|
const failure = e instanceof Error ? e : { text: String(e) };
|
|
@@ -2,8 +2,9 @@ import { createOpenAIChatRuntime } from "./openai-chat.js";
|
|
|
2
2
|
const DRIVER_KIND = "grok";
|
|
3
3
|
const DEFAULT_URL = "https://api.x.ai/v1";
|
|
4
4
|
const MODELS = {
|
|
5
|
-
default: "grok-4",
|
|
5
|
+
default: "grok-4.7",
|
|
6
6
|
options: [
|
|
7
|
+
{ id: "grok-4.7", label: "Grok 4.7", contextWindow: 500_000 },
|
|
7
8
|
{ id: "grok-4", label: "Grok 4" },
|
|
8
9
|
{ id: "grok-4-fast", label: "Grok 4 Fast" },
|
|
9
10
|
{ id: "grok-3-mini", label: "Grok 3 Mini" },
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createOpenAIChatRuntime } from "./openai-chat.js";
|
|
3
|
+
const DEFAULT_URL = "https://api.mistral.ai/v1";
|
|
4
|
+
const DEFAULT_MODELS = {
|
|
5
|
+
default: "mistral-large-latest",
|
|
6
|
+
options: [
|
|
7
|
+
{ id: "mistral-large-latest", label: "Mistral Large (latest)" },
|
|
8
|
+
{ id: "mistral-small-latest", label: "Mistral Small (latest)" },
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
const configSchema = z.object({
|
|
12
|
+
url: z.string().trim().url().default(DEFAULT_URL),
|
|
13
|
+
model: z.string().trim().min(1).optional(),
|
|
14
|
+
tools: z.boolean().optional(),
|
|
15
|
+
});
|
|
16
|
+
function decodeConfig(raw) {
|
|
17
|
+
const config = configSchema.parse(raw ?? {});
|
|
18
|
+
config.url = config.url.replace(/\/+$/, "");
|
|
19
|
+
const url = new URL(config.url);
|
|
20
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" &&
|
|
21
|
+
["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) {
|
|
22
|
+
throw new Error("Mistral requires HTTPS, except for a local test endpoint.");
|
|
23
|
+
}
|
|
24
|
+
return config;
|
|
25
|
+
}
|
|
26
|
+
const modelCard = z.object({
|
|
27
|
+
id: z.string().min(1),
|
|
28
|
+
name: z.string().nullable().optional(),
|
|
29
|
+
aliases: z.array(z.string()).optional(),
|
|
30
|
+
archived: z.boolean().optional(),
|
|
31
|
+
capabilities: z.object({ completion_chat: z.boolean().optional() }).optional(),
|
|
32
|
+
max_context_length: z.number().int().positive().optional(),
|
|
33
|
+
});
|
|
34
|
+
/** Mistral can return plain text or a list of typed content chunks. */
|
|
35
|
+
function contentText(content) {
|
|
36
|
+
if (typeof content === "string")
|
|
37
|
+
return content;
|
|
38
|
+
if (!Array.isArray(content))
|
|
39
|
+
return "";
|
|
40
|
+
return content.map((chunk) => chunk?.type === "text" && typeof chunk.text === "string" ? chunk.text : "").join("");
|
|
41
|
+
}
|
|
42
|
+
export const MistralDriver = {
|
|
43
|
+
driverKind: "mistral",
|
|
44
|
+
metadata: { displayName: "Mistral (API)", supportsMultipleInstances: true, access: "api" },
|
|
45
|
+
models: DEFAULT_MODELS,
|
|
46
|
+
install: {
|
|
47
|
+
docsUrl: "https://console.mistral.ai/api-keys",
|
|
48
|
+
signInCommand: "Save a Mistral API key in Settings → Connections, or set MISTRAL_API_KEY on the server.",
|
|
49
|
+
},
|
|
50
|
+
decodeConfig,
|
|
51
|
+
defaultConfig: () => decodeConfig({}),
|
|
52
|
+
async create(input) {
|
|
53
|
+
const { config } = input;
|
|
54
|
+
const apiKey = (input.environment.MISTRAL_API_KEY ?? process.env.MISTRAL_API_KEY ?? "").trim();
|
|
55
|
+
const withConfiguredModel = (options) => {
|
|
56
|
+
const preferred = config.model ?? DEFAULT_MODELS.default;
|
|
57
|
+
if (config.model && !options.some((option) => option.id === config.model)) {
|
|
58
|
+
options = [{ id: config.model, label: config.model }, ...options];
|
|
59
|
+
}
|
|
60
|
+
return { default: options.some((option) => option.id === preferred) ? preferred : options[0].id, options };
|
|
61
|
+
};
|
|
62
|
+
let catalog = withConfiguredModel(DEFAULT_MODELS.options);
|
|
63
|
+
const refreshModels = async () => {
|
|
64
|
+
if (!apiKey)
|
|
65
|
+
return;
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(`${config.url}/models`, {
|
|
68
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
69
|
+
redirect: "error",
|
|
70
|
+
signal: AbortSignal.timeout(8_000),
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok)
|
|
73
|
+
return;
|
|
74
|
+
const json = await response.json();
|
|
75
|
+
const rows = Array.isArray(json) ? json : z.object({ data: z.array(z.unknown()) }).parse(json).data;
|
|
76
|
+
const options = [];
|
|
77
|
+
const seen = new Set();
|
|
78
|
+
for (const row of rows) {
|
|
79
|
+
const parsed = modelCard.safeParse(row);
|
|
80
|
+
if (!parsed.success || parsed.data.archived || parsed.data.capabilities?.completion_chat === false)
|
|
81
|
+
continue;
|
|
82
|
+
const card = parsed.data;
|
|
83
|
+
for (const id of [card.id, ...(card.aliases ?? [])]) {
|
|
84
|
+
if (!id.trim() || seen.has(id))
|
|
85
|
+
continue;
|
|
86
|
+
seen.add(id);
|
|
87
|
+
options.push({ id, label: id === card.id ? card.name?.trim() || id : id,
|
|
88
|
+
...(card.max_context_length ? { contextWindow: card.max_context_length } : {}) });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (options.length)
|
|
92
|
+
catalog = withConfiguredModel(options);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// A failed refresh keeps the last usable catalog, including custom models.
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
if (apiKey)
|
|
99
|
+
void refreshModels();
|
|
100
|
+
return createOpenAIChatRuntime({
|
|
101
|
+
input, driverKind: "mistral", apiKey, apiUrl: config.url,
|
|
102
|
+
tools: config.tools, models: () => catalog, refreshModels, contentText,
|
|
103
|
+
requestBody: (model, messages, stream) => ({ model, messages, stream }),
|
|
104
|
+
httpErrorLabel: "Mistral",
|
|
105
|
+
missingKeyError: "Save a Mistral API key in Settings → Connections, or set MISTRAL_API_KEY.",
|
|
106
|
+
unavailableReason: "No Mistral API key — open Settings → Connections.",
|
|
107
|
+
timeoutMs: 180_000, billing: "metered", includeUsageInCompleted: true,
|
|
108
|
+
nativeLog: {
|
|
109
|
+
source: "mistral.chat.completions",
|
|
110
|
+
outgoing: (_turn, messages, model) => ({ model, messageCount: messages.length }),
|
|
111
|
+
incoming: ({ text, usage }) => ({ textLength: text.length, usage }),
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
};
|