From 8d8ea26cb21803a1a156bf62626c7bd74986726c Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 15 Aug 2026 05:58:36 -0700 Subject: [PATCH] FN-9094: omit unsupported Grok auto-update flag Align Grok ACP expectations with the released CLI contract. - Update runtime routing and adapter assertions to omit --no-auto-update by default. - Cover explicit false and default argument behavior in ACP settings tests. - Document the released CLI incompatibility and opt-in escape hatch. Files changed: docs/grok-cli-contract.md | 7 ++++--- packages/engine/src/__tests__/grok-runtime-routing.test.ts | 14 +++++++++----- .../src/__tests__/acp-settings.test.ts | 2 ++ .../src/__tests__/runtime-adapter.test.ts | 14 ++++++++++---- 4 files changed, 25 insertions(+), 12 deletions(-) Fusion-Task-Id: FN-9094 Fusion-Task-Lineage: f776e401-8473-45b2-a8b2-8d8251b4713e Co-authored-by: Fusion (runfusion.ai) --- docs/grok-cli-contract.md | 7 ++++--- .../src/__tests__/grok-runtime-routing.test.ts | 14 +++++++++----- .../src/__tests__/acp-settings.test.ts | 2 ++ .../src/__tests__/runtime-adapter.test.ts | 14 ++++++++++---- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/docs/grok-cli-contract.md b/docs/grok-cli-contract.md index c1b4f1befc..76a0055c17 100644 --- a/docs/grok-cli-contract.md +++ b/docs/grok-cli-contract.md @@ -32,12 +32,13 @@ The previously documented https://github.com/superagent-ai/grok-cli contract is Fusion's `GrokRuntimeAdapter` drives Grok as an ACP (Agent Client Protocol) agent over JSON-RPC/stdio, following [xAI Headless & Scripting](https://docs.x.ai/build/cli/headless-scripting#acp): ```bash -# Official automation shape (docs.x.ai): suppress update checks in CI/scripts -grok --no-auto-update agent stdio +grok agent stdio # with optional model + session skills plugin: -grok --no-auto-update agent --plugin-dir -m grok-4.6 stdio +grok agent --plugin-dir -m grok-4.6 stdio ``` +xAI's [Headless & Scripting docs](https://docs.x.ai/build/cli/headless-scripting#acp) suggest `--no-auto-update`, but released Grok CLI v1.0.0 exits with "unexpected argument" when it is passed. Fusion therefore defaults it OFF and exposes it only as the opt-in `buildGrokAcpArgs({ noAutoUpdate: true })` argument, which prepends the flag before `agent`. + ACP session lifecycle (official contract): 1. `initialize` (protocolVersion 1) diff --git a/packages/engine/src/__tests__/grok-runtime-routing.test.ts b/packages/engine/src/__tests__/grok-runtime-routing.test.ts index 5ce2248995..bcc51384ac 100644 --- a/packages/engine/src/__tests__/grok-runtime-routing.test.ts +++ b/packages/engine/src/__tests__/grok-runtime-routing.test.ts @@ -230,12 +230,16 @@ describe("Grok CLI runtime routing (FN-7725)", () => { expect(result.runtimeId).toBe("grok"); expect(result.wasConfigured).toBe(true); expect(mockCreateFnAgent).not.toHaveBeenCalled(); - // FNXC:GrokAcp 2026-07-11-14:00 / 15:00: ACP args include --no-auto-update - // (official headless scripting docs), session-scoped --plugin-dir for Fusion - // skills, then stdio (optional -m when a model is set). + /* + FNXC:GrokAcp 2026-08-15-12:41: + Default ACP argv omits `--no-auto-update` because released Grok CLI v1.0.0 + rejects it as an unexpected argument. The flag remains an explicit opt-in; + session argv starts with agent, scopes Fusion skills by --plugin-dir, may add + -m, and ends with stdio. + */ const acpArgs = settingsOut[0]?.acpArgs as string[]; - expect(acpArgs).toContain("--no-auto-update"); - expect(acpArgs).toContain("agent"); + expect(acpArgs).not.toContain("--no-auto-update"); + expect(acpArgs[0]).toBe("agent"); expect(acpArgs).toContain("--plugin-dir"); expect(acpArgs.at(-1)).toBe("stdio"); diff --git a/plugins/fusion-plugin-grok-runtime/src/__tests__/acp-settings.test.ts b/plugins/fusion-plugin-grok-runtime/src/__tests__/acp-settings.test.ts index 587a63ec22..a938f0d4bc 100644 --- a/plugins/fusion-plugin-grok-runtime/src/__tests__/acp-settings.test.ts +++ b/plugins/fusion-plugin-grok-runtime/src/__tests__/acp-settings.test.ts @@ -13,6 +13,7 @@ describe("acp-settings", () => { // --no-auto-update is opt-in only; the released Grok CLI does not support it. expect(buildGrokAcpArgs()).toEqual(["agent", "stdio"]); expect(buildGrokAcpArgs({})).toEqual(["agent", "stdio"]); + expect(buildGrokAcpArgs({ noAutoUpdate: false })).toEqual(["agent", "stdio"]); expect(buildGrokAcpArgs({ noAutoUpdate: true })).toEqual(["--no-auto-update", "agent", "stdio"]); }); @@ -58,6 +59,7 @@ describe("acp-settings", () => { const settings = buildGrokAcpRuntimeSettings({ binary: "/usr/local/bin/grok", model: "grok-cli/grok-4.5" }); expect(settings.acpBinaryPath).toBe("/usr/local/bin/grok"); expect(settings.acpArgs).toEqual(["agent", "-m", "grok-4.5", "stdio"]); + expect(settings.acpArgs).not.toContain("--no-auto-update"); expect(settings.acpEnvAllowList).toEqual([...GROK_ACP_ENV_ALLOWLIST]); expect(settings.acpFsRead).toBe(false); expect(settings.acpFsWrite).toBe(false); diff --git a/plugins/fusion-plugin-grok-runtime/src/__tests__/runtime-adapter.test.ts b/plugins/fusion-plugin-grok-runtime/src/__tests__/runtime-adapter.test.ts index 0763b8e777..1a035befee 100644 --- a/plugins/fusion-plugin-grok-runtime/src/__tests__/runtime-adapter.test.ts +++ b/plugins/fusion-plugin-grok-runtime/src/__tests__/runtime-adapter.test.ts @@ -64,6 +64,11 @@ function makeFakeAcpAdapter(overrides?: { } describe("GrokRuntimeAdapter (ACP)", () => { + /* + FNXC:GrokAcp 2026-08-15-12:41: + Grok CLI v1.0.0 rejects `--no-auto-update`, so default ACP sessions must + omit it. The low-level argv builder retains the flag as an explicit opt-in. + */ it("creates a session with default model fallback", async () => { const settingsOut: Record[] = []; const adapter = new GrokRuntimeAdapter({ createAcpAdapter: makeFakeAcpAdapter({ settingsOut }) }); @@ -71,7 +76,7 @@ describe("GrokRuntimeAdapter (ACP)", () => { expect(result.session.model).toBe("grok/default"); expect(result.session.systemPrompt).toBe("sys"); const args = settingsOut[0]?.acpArgs as string[]; - expect(args).toContain("--no-auto-update"); + expect(args).not.toContain("--no-auto-update"); expect(args).toContain("agent"); expect(args).toContain("--plugin-dir"); expect(args.at(-1)).toBe("stdio"); @@ -85,12 +90,13 @@ describe("GrokRuntimeAdapter (ACP)", () => { expect(session.model).toBe("grok-4.5"); expect(settingsOut[0]?.acpBinaryPath).toBe("grok"); const args = settingsOut[0]?.acpArgs as string[]; - expect(args).toContain("--no-auto-update"); + expect(args).not.toContain("--no-auto-update"); expect(args).toContain("--plugin-dir"); expect(args).toEqual(expect.arrayContaining(["-m", "grok-4.5", "stdio"])); - // plugin-dir precedes model flag; no-auto-update precedes agent - expect(args.indexOf("--no-auto-update")).toBeLessThan(args.indexOf("agent")); + // Agent leads the argv; plugin-dir precedes the selected model. + expect(args[0]).toBe("agent"); expect(args.indexOf("--plugin-dir")).toBeLessThan(args.indexOf("-m")); + expect(args.at(-1)).toBe("stdio"); }); it("forwards operator MCP servers and Fusion custom tools into createSession", async () => {