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
|
@@ -29,8 +29,9 @@ import { homedir } from "node:os";
|
|
|
29
29
|
import { lstat, mkdir, readFile, realpath, stat, writeFile } from "node:fs/promises";
|
|
30
30
|
import { basename, dirname, isAbsolute, relative, resolve } from "node:path";
|
|
31
31
|
import { createHash } from "node:crypto";
|
|
32
|
-
import { PROVIDER_CREDENTIAL_ENV, WORKSPACE_CREDENTIAL_ENV } from "../../config.js";
|
|
32
|
+
import { PROVIDER_CREDENTIAL_ENV, stripControlPlaneEnv, WORKSPACE_CREDENTIAL_ENV } from "../../config.js";
|
|
33
33
|
import { decodeInjectId } from "../local-inject.js";
|
|
34
|
+
import { promptHalves, readPromptSplitReceipt, splitSessionPrompt, writePromptSplitReceipt } from "../prompt-split.js";
|
|
34
35
|
import { describeSpawnFailure, execCli, killCliTree, spawnCli } from "../../procs.js";
|
|
35
36
|
/**
|
|
36
37
|
* A `host::model` pick talks to a loopback server with its own key.
|
|
@@ -42,9 +43,38 @@ export function skipSubscriptionAuthForLocalInject(model) {
|
|
|
42
43
|
import { newEventId, newId } from "../../contracts.js";
|
|
43
44
|
import { augmentedPath } from "../../env-path.js";
|
|
44
45
|
import { supportsApprovalMode } from "../../../shared/approval-mode.js";
|
|
46
|
+
import { parseAskQuestions, parseChoices, questionAnswersByQuestion } from "../../../shared/ask-question.js";
|
|
45
47
|
import { appendNative } from "../native.js";
|
|
48
|
+
import { acpPermissionCommand, permissionLaunchCwd } from "../permission-command.js";
|
|
46
49
|
import { commandSummary, toolDetailPreview } from "../../tool-summary.js";
|
|
47
50
|
import { extractMcpImages } from "../../mcp-tool-images.js";
|
|
51
|
+
import { redactSecretsInText } from "../../redact.js";
|
|
52
|
+
import { recoveryPromptFor } from "../../resume-recovery.js";
|
|
53
|
+
/** ACP vendors put the actionable cause in error.data while keeping the
|
|
54
|
+
* JSON-RPC message generic. Only surface known text fields, never a response
|
|
55
|
+
* body/config dump, and redact before bounding the displayed diagnostic. */
|
|
56
|
+
function acpRpcError(value, method) {
|
|
57
|
+
const message = typeof value?.message === "string" ? value.message : "ACP request failed";
|
|
58
|
+
const data = value?.data;
|
|
59
|
+
const detail = typeof data === "string" ? data
|
|
60
|
+
: typeof data?.details === "string" ? data.details
|
|
61
|
+
: typeof data?.message === "string" ? data.message
|
|
62
|
+
: typeof data?.error?.message === "string" ? data.error.message
|
|
63
|
+
: "";
|
|
64
|
+
const context = [
|
|
65
|
+
method,
|
|
66
|
+
typeof data?.service === "string" ? `service: ${data.service}` : "",
|
|
67
|
+
typeof data?.errorName === "string" ? data.errorName : "",
|
|
68
|
+
].filter(Boolean).join(", ");
|
|
69
|
+
const diagnostic = `${detail && detail !== message ? `${message}: ${detail}` : message} (${context})`;
|
|
70
|
+
const error = new Error(redactSecretsInText(diagnostic).slice(0, 1500));
|
|
71
|
+
return Object.assign(error, { code: value?.code, data,
|
|
72
|
+
// -32603 is JSON-RPC's internal error. Invalid params, unsupported
|
|
73
|
+
// methods and auth refusals are user/configuration issues, not evidence
|
|
74
|
+
// of a broken process. Preserve their session instead of retrying them.
|
|
75
|
+
acpSessionFailure: value?.code === -32603,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
48
78
|
const envOr = (key, fallback) => Number(process.env[key] ?? fallback);
|
|
49
79
|
const INIT_TIMEOUT = envOr("OPENMAUS_ACP_INIT_TIMEOUT_MS", 300_000);
|
|
50
80
|
const SESSION_CONFIG_TIMEOUT = envOr("OPENMAUS_ACP_SESSION_CONFIG_TIMEOUT_MS", 300_000); // configureSession's per-request default
|
|
@@ -171,6 +201,17 @@ function sessionOperationKey(toolCall) {
|
|
|
171
201
|
locations: toolCall?.locations,
|
|
172
202
|
}));
|
|
173
203
|
}
|
|
204
|
+
/** The banner an ACP CLI prints for `--version`. Hermes writes its whole banner
|
|
205
|
+
* to stderr with an empty stdout, so an stdout-only read reports a perfectly
|
|
206
|
+
* good install as "CLI not found". Prefer stdout; fall back to the first
|
|
207
|
+
* stderr line; null when both are empty. */
|
|
208
|
+
export function versionFromProbe(stdout, stderr) {
|
|
209
|
+
const out = (stdout ?? "").trim();
|
|
210
|
+
if (out)
|
|
211
|
+
return out;
|
|
212
|
+
const err = (stderr ?? "").trim().split(/\r\n|\n|\r/, 1)[0]?.trim() ?? "";
|
|
213
|
+
return err || null;
|
|
214
|
+
}
|
|
174
215
|
export function createAcpDriver(support) {
|
|
175
216
|
const DRIVER_KIND = support.driverKind;
|
|
176
217
|
const SOURCE = support.nativeSource;
|
|
@@ -205,6 +246,8 @@ export function createAcpDriver(support) {
|
|
|
205
246
|
if (!allowedCredentials.has(key))
|
|
206
247
|
delete env[key];
|
|
207
248
|
}
|
|
249
|
+
// The operator's own secrets are outside any driver's allowlist.
|
|
250
|
+
stripControlPlaneEnv(env);
|
|
208
251
|
support.transformEnv?.(env, activeConfig, instanceId);
|
|
209
252
|
return env;
|
|
210
253
|
};
|
|
@@ -385,7 +428,25 @@ export function createAcpDriver(support) {
|
|
|
385
428
|
session.current = null;
|
|
386
429
|
active.delete(threadId);
|
|
387
430
|
current.flushAssistantText();
|
|
388
|
-
|
|
431
|
+
// `end_turn` with nothing to show for it — no reply, no image, no
|
|
432
|
+
// tool result — is a lost turn, not a success. An engine can report
|
|
433
|
+
// exactly that (a provider may cut a reasoning-only stream and
|
|
434
|
+
// still answer end_turn), and ok:true would end the thread quietly
|
|
435
|
+
// while the person's message went unanswered. Keep the completion,
|
|
436
|
+
// but report it as a failure so terminal chips, incidents and
|
|
437
|
+
// follow-ups see what happened.
|
|
438
|
+
let finalOk = ok;
|
|
439
|
+
let finalStopReason = stopReason;
|
|
440
|
+
if (finalOk && finalStopReason === null && !current.state.producedItem) {
|
|
441
|
+
finalOk = false;
|
|
442
|
+
finalStopReason = "empty_turn";
|
|
443
|
+
emit({
|
|
444
|
+
...base(threadId, current.turnId),
|
|
445
|
+
type: "runtime.error",
|
|
446
|
+
message: `${DRIVER_KIND} ended the turn with no reply, image, or tool result`,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
emit({ ...base(threadId, current.turnId), type: "turn.completed", ok: finalOk, stopReason: finalStopReason, cost: null });
|
|
389
450
|
if (session.child.exitCode === null && !session.closing && !session.dead) {
|
|
390
451
|
armIdle(threadId);
|
|
391
452
|
}
|
|
@@ -400,6 +461,7 @@ export function createAcpDriver(support) {
|
|
|
400
461
|
* session.current, so a request that lands between turns is answered
|
|
401
462
|
* (never brokered) instead of left hanging. */
|
|
402
463
|
const openSession = (threadId, launch, argv, env, cwd, contractKey) => {
|
|
464
|
+
const commandCwd = permissionLaunchCwd(cwd);
|
|
403
465
|
const child = spawnCli(launch.command, argv, {
|
|
404
466
|
cwd,
|
|
405
467
|
env,
|
|
@@ -426,7 +488,7 @@ export function createAcpDriver(support) {
|
|
|
426
488
|
if (timeoutMs) {
|
|
427
489
|
timer = setTimeout(() => {
|
|
428
490
|
rpcPending.delete(id);
|
|
429
|
-
reject(new Error(`${method} timed out`));
|
|
491
|
+
reject(Object.assign(new Error(`${method} timed out`), { acpSessionFailure: true }));
|
|
430
492
|
}, timeoutMs);
|
|
431
493
|
timer.unref?.();
|
|
432
494
|
}
|
|
@@ -455,6 +517,7 @@ export function createAcpDriver(support) {
|
|
|
455
517
|
};
|
|
456
518
|
armIdle();
|
|
457
519
|
rpcPending.set(id, {
|
|
520
|
+
method,
|
|
458
521
|
// Consume configuration in wire order: an update following this
|
|
459
522
|
// response may arrive before the awaiting continuation resumes.
|
|
460
523
|
resolve: (result) => { receive?.(result); resolve(result); },
|
|
@@ -601,16 +664,34 @@ export function createAcpDriver(support) {
|
|
|
601
664
|
}
|
|
602
665
|
}
|
|
603
666
|
const tool = kind === "execute" ? "shell" : kind === "edit" ? "edit" : kind || "tool";
|
|
667
|
+
const isShellCommand = !isQuestion && kind === "execute" && !/^mcp(?:__|[.:])/i.test(String(toolCall.title ?? ""));
|
|
604
668
|
const summary = String(toolCall.rawInput?.command ?? toolCall.title ?? tool).slice(0, 200);
|
|
669
|
+
// One structured question beside the flat choices: the richer card
|
|
670
|
+
// renders from it while older clients keep answering through
|
|
671
|
+
// `choices`. Built once here so the emit and the answer path can
|
|
672
|
+
// never disagree. parseAskQuestions enforces the shared caps.
|
|
673
|
+
const questionChoices = isQuestion
|
|
674
|
+
? options.flatMap((option) => typeof option.name === "string" && option.name.trim() ? [option.name.trim()] : [])
|
|
675
|
+
: [];
|
|
676
|
+
const askQuestions = isQuestion && questionChoices.length
|
|
677
|
+
? parseAskQuestions({ questions: [{ question: summary, options: questionChoices }] }) ?? undefined
|
|
678
|
+
: undefined;
|
|
605
679
|
const requestId = newId();
|
|
606
680
|
const finish = (behavior, source = "user", message, always) => {
|
|
607
681
|
if (!current.asks.delete(requestId))
|
|
608
|
-
return;
|
|
682
|
+
return "unavailable";
|
|
609
683
|
clearTimeout(timer);
|
|
610
684
|
const want = behavior === "allow" ? "allow" : "reject";
|
|
611
685
|
const forSession = want === "allow" && always === true && !isQuestion && !current.controlsHost;
|
|
686
|
+
// A structured card replies in the Q:/A: block format; recover the
|
|
687
|
+
// picked label from it so exact-match keeps working. Flat clients
|
|
688
|
+
// send the bare label, which the single-question fallback inside
|
|
689
|
+
// questionAnswersByQuestion already returns unchanged.
|
|
690
|
+
const picked = askQuestions
|
|
691
|
+
? questionAnswersByQuestion(message ?? "", askQuestions)[askQuestions[0].question] ?? message
|
|
692
|
+
: message;
|
|
612
693
|
const named = isQuestion && behavior === "answer"
|
|
613
|
-
? options.filter((option) => option.optionId ===
|
|
694
|
+
? options.filter((option) => option.optionId === picked || parseChoices([option.name], 1)?.[0] === picked)
|
|
614
695
|
: [];
|
|
615
696
|
const optionId = behavior === "cancel"
|
|
616
697
|
? null
|
|
@@ -641,6 +722,7 @@ export function createAcpDriver(support) {
|
|
|
641
722
|
source: optionId ? source : "system",
|
|
642
723
|
approvalScope: current.controlsHost ? "local-computer" : undefined,
|
|
643
724
|
});
|
|
725
|
+
return !optionId ? "rejected" : isQuestion ? "answered" : behavior === "allow" ? "allowed-once" : "rejected";
|
|
644
726
|
};
|
|
645
727
|
const timer = setTimeout(() => {
|
|
646
728
|
emit({ ...base(threadId, current.turnId), type: "runtime.error", message: DENY_TIMEOUT_NOTE });
|
|
@@ -655,9 +737,10 @@ export function createAcpDriver(support) {
|
|
|
655
737
|
requestType: isQuestion ? "question" : "permission",
|
|
656
738
|
tool,
|
|
657
739
|
summary,
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
740
|
+
command: isShellCommand ? acpPermissionCommand(toolCall.rawInput, commandCwd) : undefined,
|
|
741
|
+
requiresExplicitApproval: isShellCommand && (toolCall.rawInput?.dangerouslyDisableSandbox === true || toolCall.rawInput?.sandbox_permissions === "require_escalated") || undefined,
|
|
742
|
+
choices: askQuestions?.[0]?.options.map(option => option.label) ?? (isQuestion ? questionChoices : undefined),
|
|
743
|
+
...(askQuestions ? { questions: askQuestions } : {}),
|
|
661
744
|
approvalScope: current.controlsHost ? "local-computer" : undefined,
|
|
662
745
|
// the driver can honor a session-wide allow either way
|
|
663
746
|
allowSession: !isQuestion && !current.controlsHost ? true : undefined,
|
|
@@ -686,6 +769,7 @@ export function createAcpDriver(support) {
|
|
|
686
769
|
const delta = content?.text;
|
|
687
770
|
if (content?.type === "image" && typeof content.data === "string" && content.data) {
|
|
688
771
|
current.flushAssistantText();
|
|
772
|
+
current.state.producedItem = true;
|
|
689
773
|
emit({
|
|
690
774
|
...base(threadId, current.turnId),
|
|
691
775
|
type: "item.completed",
|
|
@@ -722,6 +806,7 @@ export function createAcpDriver(support) {
|
|
|
722
806
|
}
|
|
723
807
|
case "tool_call_update": {
|
|
724
808
|
if (u.status === "completed" || u.status === "failed") {
|
|
809
|
+
current.state.producedItem = true;
|
|
725
810
|
emit({
|
|
726
811
|
...base(threadId, current.turnId),
|
|
727
812
|
type: "item.completed",
|
|
@@ -788,9 +873,7 @@ export function createAcpDriver(support) {
|
|
|
788
873
|
if (pend.idleTimer)
|
|
789
874
|
clearTimeout(pend.idleTimer);
|
|
790
875
|
if (msg.error) {
|
|
791
|
-
|
|
792
|
-
Object.assign(error, { code: msg.error.code, data: msg.error.data });
|
|
793
|
-
pend.reject(error);
|
|
876
|
+
pend.reject(acpRpcError(msg.error, pend.method));
|
|
794
877
|
}
|
|
795
878
|
else {
|
|
796
879
|
pend.resolve(msg.result);
|
|
@@ -923,6 +1006,10 @@ export function createAcpDriver(support) {
|
|
|
923
1006
|
const envFingerprint = createHash("sha256").update(JSON.stringify(spawnEnv)).digest("hex").slice(0, 16);
|
|
924
1007
|
const contractKey = JSON.stringify([launch.command, launch.args ?? [], spawnArgs, cwd, turnConfig.fullAuto === true, envFingerprint]);
|
|
925
1008
|
const sessionKey = JSON.stringify(mcpServers);
|
|
1009
|
+
if (turn.sessionReset) {
|
|
1010
|
+
closeSession(threadId, "reset");
|
|
1011
|
+
sessionAllows.delete(threadId);
|
|
1012
|
+
}
|
|
926
1013
|
const pooled = sessions.get(threadId);
|
|
927
1014
|
let session;
|
|
928
1015
|
if (pooled && !pooled.dead && !pooled.closing && pooled.contractKey === contractKey) {
|
|
@@ -948,7 +1035,7 @@ export function createAcpDriver(support) {
|
|
|
948
1035
|
// respawns the child, every wire call must reach the live record, so
|
|
949
1036
|
// nothing captures the connection off it.
|
|
950
1037
|
const request = (method, params, timeoutMs, receive, idleMs, idleMessage) => session.acp.request(method, params, timeoutMs, receive, idleMs, idleMessage);
|
|
951
|
-
const state = { settled: false, promptSent: false, text: "" };
|
|
1038
|
+
const state = { settled: false, promptSent: false, text: "", producedItem: false };
|
|
952
1039
|
const asks = new Map();
|
|
953
1040
|
const modelOf = (result) => {
|
|
954
1041
|
const option = (Array.isArray(result?.configOptions) ? result.configOptions : []).find((entry) => entry?.id === (support.selectModel?.configId ?? "model"));
|
|
@@ -987,6 +1074,7 @@ export function createAcpDriver(support) {
|
|
|
987
1074
|
state.text = "";
|
|
988
1075
|
if (!text.trim())
|
|
989
1076
|
return;
|
|
1077
|
+
state.producedItem = true;
|
|
990
1078
|
emit({ ...base(threadId, turnId), type: "item.completed", itemType: "assistant_text", text });
|
|
991
1079
|
};
|
|
992
1080
|
const current = {
|
|
@@ -1073,8 +1161,10 @@ export function createAcpDriver(support) {
|
|
|
1073
1161
|
};
|
|
1074
1162
|
let runtimeAcceptsImages = await handshake();
|
|
1075
1163
|
let init = session.initResult;
|
|
1076
|
-
const cursor = typeof turn.resumeCursor === "string" ? turn.resumeCursor : null;
|
|
1164
|
+
const cursor = !turn.sessionReset && typeof turn.resumeCursor === "string" ? turn.resumeCursor : null;
|
|
1077
1165
|
let sessionResult = null;
|
|
1166
|
+
let promptTurn = turn;
|
|
1167
|
+
let rebuiltFromReplay = false;
|
|
1078
1168
|
for (;;) {
|
|
1079
1169
|
const liveSessionId = session.sessionId;
|
|
1080
1170
|
if (liveSessionId !== null && session.sessionKey === sessionKey && (cursor === null || cursor === liveSessionId)) {
|
|
@@ -1100,7 +1190,17 @@ export function createAcpDriver(support) {
|
|
|
1100
1190
|
}
|
|
1101
1191
|
});
|
|
1102
1192
|
}
|
|
1103
|
-
catch {
|
|
1193
|
+
catch (error) {
|
|
1194
|
+
const classification = support.classifyError?.(error);
|
|
1195
|
+
// OpenCode encodes ACPSessionNotFoundError as invalidParams
|
|
1196
|
+
// with just the rejected sessionId. Other invalidParams
|
|
1197
|
+
// responses (model/config errors) must not erase history.
|
|
1198
|
+
const data = error?.data;
|
|
1199
|
+
const missingSession = data && typeof data === "object" && !Array.isArray(data)
|
|
1200
|
+
&& data.sessionId === cursor && Object.keys(data).length === 1;
|
|
1201
|
+
if (classification === "invalid_credentials" || classification === "inactive_subscription"
|
|
1202
|
+
|| (error?.code === -32602 && !missingSession))
|
|
1203
|
+
throw error;
|
|
1104
1204
|
/* session gone, load unsupported, or too slow — the
|
|
1105
1205
|
* fallbacks below choose between one fresh process and a
|
|
1106
1206
|
* genuinely new session */
|
|
@@ -1127,8 +1227,16 @@ export function createAcpDriver(support) {
|
|
|
1127
1227
|
}
|
|
1128
1228
|
// a genuinely fresh native session forgets what the previous
|
|
1129
1229
|
// one allowed
|
|
1130
|
-
|
|
1131
|
-
|
|
1230
|
+
sessionAllows.delete(threadId);
|
|
1231
|
+
if (cursor) {
|
|
1232
|
+
const recovery = recoveryPromptFor({
|
|
1233
|
+
recoveryText: turn.recoveryText,
|
|
1234
|
+
currentText: turn.text,
|
|
1235
|
+
failure: "before-accept",
|
|
1236
|
+
});
|
|
1237
|
+
promptTurn = { ...turn, text: recovery.text };
|
|
1238
|
+
rebuiltFromReplay = recovery.replayed;
|
|
1239
|
+
}
|
|
1132
1240
|
sessionResult = await request("session/new", { cwd, mcpServers: sessionServers }, NEW_SESSION_TIMEOUT, (result) => {
|
|
1133
1241
|
session.sessionId = typeof result?.sessionId === "string" ? result.sessionId : null;
|
|
1134
1242
|
session.sessionKey = sessionKey;
|
|
@@ -1151,6 +1259,7 @@ export function createAcpDriver(support) {
|
|
|
1151
1259
|
type: "session.started",
|
|
1152
1260
|
sessionId,
|
|
1153
1261
|
model: selectedModel ?? init?._meta?.modelState?.currentModelId ?? cliTurn.model ?? null,
|
|
1262
|
+
...(rebuiltFromReplay ? { rebuilt: true } : {}),
|
|
1154
1263
|
});
|
|
1155
1264
|
};
|
|
1156
1265
|
try {
|
|
@@ -1177,7 +1286,7 @@ export function createAcpDriver(support) {
|
|
|
1177
1286
|
? sessionResult.models.availableModels
|
|
1178
1287
|
: [],
|
|
1179
1288
|
});
|
|
1180
|
-
// initialize's currentModelId is the CLI default
|
|
1289
|
+
// initialize's currentModelId is the CLI default,
|
|
1181
1290
|
// not the model this turn asked for. After a successful pin,
|
|
1182
1291
|
// report the slug we set so the UI does not claim otherwise.
|
|
1183
1292
|
if (!selectedModel && cliTurn.model)
|
|
@@ -1198,11 +1307,28 @@ export function createAcpDriver(support) {
|
|
|
1198
1307
|
throw error;
|
|
1199
1308
|
}
|
|
1200
1309
|
emitSessionStarted();
|
|
1310
|
+
// The stable/volatile split: the full prompt rides only the turn
|
|
1311
|
+
// that establishes - or re-instructs, after a soul edit - this
|
|
1312
|
+
// native session. Later turns go through bare unless the volatile
|
|
1313
|
+
// half changed, so a memory edit neither appends a second copy of
|
|
1314
|
+
// the prompt to the agent's session history nor re-prices the
|
|
1315
|
+
// prefix its provider cached. Receipts are durable because the
|
|
1316
|
+
// native session outlives this process; an un-split turn (a direct
|
|
1317
|
+
// adapter call) keeps the legacy full-prompt shape.
|
|
1318
|
+
const halves = promptHalves(turn);
|
|
1319
|
+
let promptInput = promptTurn;
|
|
1320
|
+
let pendingSplitReceipt = null;
|
|
1321
|
+
if (halves.stable !== null) {
|
|
1322
|
+
const receiptKey = JSON.stringify([threadId, sessionId]);
|
|
1323
|
+
const composed = splitSessionPrompt(halves.stable, halves.volatile, readPromptSplitReceipt(DRIVER_KIND, receiptKey), promptTurn.system, promptTurn.text, Boolean(turn.mentionTurn));
|
|
1324
|
+
promptInput = { ...promptTurn, system: "", text: composed.text };
|
|
1325
|
+
pendingSplitReceipt = { key: receiptKey, receipt: composed.receipt };
|
|
1326
|
+
}
|
|
1201
1327
|
const text = support.buildPromptText
|
|
1202
|
-
? support.buildPromptText(
|
|
1203
|
-
:
|
|
1204
|
-
? `${
|
|
1205
|
-
:
|
|
1328
|
+
? support.buildPromptText(promptInput)
|
|
1329
|
+
: promptInput.system
|
|
1330
|
+
? `${promptInput.system}\n\n${promptInput.text}`
|
|
1331
|
+
: promptInput.text;
|
|
1206
1332
|
const imageBlocks = support.images === true && runtimeAcceptsImages
|
|
1207
1333
|
? await readAcpImageBlocks(turn.images ?? [])
|
|
1208
1334
|
: [];
|
|
@@ -1216,6 +1342,12 @@ export function createAcpDriver(support) {
|
|
|
1216
1342
|
const promptIdleMs = promptIdleTimeoutMs();
|
|
1217
1343
|
const result = await request("session/prompt", { sessionId, prompt: [{ type: "text", text }, ...imageBlocks] }, undefined, undefined, promptIdleMs, `${DRIVER_KIND} went fully silent ${Math.round(promptIdleMs / 1000)} s after the message and the turn was stopped. ` +
|
|
1218
1344
|
"Raise OPENMAUS_ACP_PROMPT_IDLE_TIMEOUT_MS if this model legitimately takes longer to answer.");
|
|
1345
|
+
if (pendingSplitReceipt) {
|
|
1346
|
+
// session/prompt resolving is the acceptance boundary: a
|
|
1347
|
+
// rejected prompt leaves the receipt unwritten, so the next
|
|
1348
|
+
// turn redelivers what this one never received.
|
|
1349
|
+
writePromptSplitReceipt(DRIVER_KIND, pendingSplitReceipt.key, pendingSplitReceipt.receipt);
|
|
1350
|
+
}
|
|
1219
1351
|
// opencode 1.18.18 reports usage at the result root; grok and
|
|
1220
1352
|
// gemini put it under _meta. Read both rather than lose the count.
|
|
1221
1353
|
const usage = result?.usage ?? result?._meta ?? {};
|
|
@@ -1261,11 +1393,14 @@ export function createAcpDriver(support) {
|
|
|
1261
1393
|
message,
|
|
1262
1394
|
...(needsAuth ? { setup: true } : {}),
|
|
1263
1395
|
});
|
|
1264
|
-
//
|
|
1265
|
-
//
|
|
1266
|
-
//
|
|
1267
|
-
|
|
1268
|
-
|
|
1396
|
+
// Internal RPC failures can leave a live child poisoned just
|
|
1397
|
+
// like a silent prompt. Evict before completion listeners can
|
|
1398
|
+
// start the next turn. Never replay this accepted prompt: it
|
|
1399
|
+
// may already have executed tools. The next explicit turn can
|
|
1400
|
+
// resume the recorded session on a fresh process.
|
|
1401
|
+
if (!needsAuth && (e?.acpPromptStall === true || e?.acpSessionFailure === true
|
|
1402
|
+
|| code === "upstream_outage") && session.child.exitCode === null && !session.closing) {
|
|
1403
|
+
closeSession(threadId, e?.acpPromptStall === true ? "prompt-stall" : "rpc-failure");
|
|
1269
1404
|
}
|
|
1270
1405
|
settle(threadId, session, false, needsAuth ? "auth_required" : "rpc_error");
|
|
1271
1406
|
}
|
|
@@ -1278,7 +1413,7 @@ export function createAcpDriver(support) {
|
|
|
1278
1413
|
if (support.snapshot)
|
|
1279
1414
|
return support.snapshot(env, config, instanceId);
|
|
1280
1415
|
const version = await new Promise((resolve) => {
|
|
1281
|
-
execCli(config.cli, ["--version"], { timeout: 8000, env }, (err, stdout) => resolve(err ? null : stdout
|
|
1416
|
+
execCli(config.cli, ["--version"], { timeout: 8000, env }, (err, stdout, stderr) => resolve(err ? null : versionFromProbe(stdout, stderr)));
|
|
1282
1417
|
});
|
|
1283
1418
|
if (!version)
|
|
1284
1419
|
return { state: "unavailable", reason: `\`${config.cli}\` CLI not found` };
|
|
@@ -1319,12 +1454,7 @@ export function createAcpDriver(support) {
|
|
|
1319
1454
|
const finish = turn?.asks.get(requestId);
|
|
1320
1455
|
if (!finish)
|
|
1321
1456
|
return "unavailable"; // settled, timed out, or turn gone
|
|
1322
|
-
finish(decision.behavior, "user", decision.message, decision.always === true);
|
|
1323
|
-
return decision.behavior === "allow"
|
|
1324
|
-
? "allowed-once"
|
|
1325
|
-
: decision.behavior === "answer"
|
|
1326
|
-
? "answered"
|
|
1327
|
-
: "rejected";
|
|
1457
|
+
return finish(decision.behavior, "user", decision.message, decision.always === true);
|
|
1328
1458
|
},
|
|
1329
1459
|
hasSession: (threadId) => active.has(threadId),
|
|
1330
1460
|
stopAll: async () => {
|
|
@@ -9,8 +9,9 @@ import { join } from "node:path";
|
|
|
9
9
|
import { decodeInjectId, hostApiKey, localHost, mergeLocalInject } from "../local-inject.js";
|
|
10
10
|
import { createAcpDriver } from "./core.js";
|
|
11
11
|
export const STATIC_GROK_MODELS = {
|
|
12
|
-
default: "grok-4.
|
|
12
|
+
default: "grok-4.7",
|
|
13
13
|
options: [
|
|
14
|
+
{ id: "grok-4.7", label: "Grok 4.7", contextWindow: 500_000 },
|
|
14
15
|
{ id: "grok-4.6", label: "Grok 4.6" },
|
|
15
16
|
{ id: "grok-4.5", label: "Grok 4.5" },
|
|
16
17
|
],
|
|
@@ -28,7 +29,7 @@ function unquote(raw) {
|
|
|
28
29
|
}
|
|
29
30
|
return value;
|
|
30
31
|
}
|
|
31
|
-
/** Local slugs from ~/.grok/config.toml, plus the
|
|
32
|
+
/** Local slugs from ~/.grok/config.toml, plus the cloud defaults.
|
|
32
33
|
* `grok -m <slug>` already accepts these; the picker just didn't list them. */
|
|
33
34
|
export function readGrokModelCatalog(env = process.env) {
|
|
34
35
|
const path = join(grokHome(env), "config.toml");
|
|
@@ -218,7 +219,7 @@ const support = {
|
|
|
218
219
|
// agent flags: Grok 1.0.6 only applies them when they sit AFTER `agent`
|
|
219
220
|
// and BEFORE `stdio` (`grok agent -m slug stdio`). Putting -m first is
|
|
220
221
|
// accepted as a TUI option and then ignored, so ACP session/new keeps
|
|
221
|
-
// [models].default (grok-4.
|
|
222
|
+
// [models].default (currently grok-4.7) and oMLX never sees a request.
|
|
222
223
|
// Auto selects Grok's native classifier; if its feature gate is disabled,
|
|
223
224
|
// residual requests still ask. Never replace it with bypassPermissions.
|
|
224
225
|
// Verified: grok 1.0.3 --help and xai-org/grok-build@37949780,
|