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) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-08-15 05:58:36 -07:00
parent 9fa8b386ee
commit 8d8ea26cb2
4 changed files with 25 additions and 12 deletions

View File

@@ -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 <session-plugin> -m grok-4.6 stdio
grok agent --plugin-dir <session-plugin> -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)

View File

@@ -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");

View File

@@ -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);

View File

@@ -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<string, unknown>[] = [];
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 () => {