466 lines · 15.5 KB · TypeScript
RawDownload
// @effect-diagnostics nodeBuiltinImport:off - resolves the mock ACP agent script path relative to this test file.import * as NodePath from "node:path";import * as NodeURL from "node:url"; import * as NodeServices from "@effect/platform-node/NodeServices";import { describe, expect, it } from "@effect/vitest";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Schema from "effect/Schema";import { GrokSettings } from "@t3tools/contracts"; import {  buildGrokModelCapabilities,  buildGrokModelsFromSessionModelState,  buildInitialGrokProviderSnapshot,  checkGrokProviderStatus,  parseGrokModelsCliOutput,} from "./GrokProvider.ts";import { execScriptSource, writeFakeCli } from "../../testUtils/fakeCli.ts"; const decodeGrokSettings = Schema.decodeSync(GrokSettings);const __dirname = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url)); const LOGGED_IN_MODELS_OUTPUT = [  "You are logged in with grok.com.",  "",  "Default model: grok-4.6",  "",  "Available models:",  "  * grok-4.6 (default)",  "  - grok-4.5",  "",].join("\n"); const LOGGED_OUT_MODELS_OUTPUT = LOGGED_IN_MODELS_OUTPUT.replace(  "You are logged in with grok.com.",  "You are not authenticated.",); describe("parseGrokModelsCliOutput", () => {  it("reads login state and model slugs, marking the default", () => {    const parsed = parseGrokModelsCliOutput(LOGGED_IN_MODELS_OUTPUT);    expect(parsed.authenticated).toBe(true);    expect(parsed.models.map((model) => [model.slug, model.isDefault ?? false])).toEqual([      ["grok-4.6", true],      ["grok-4.5", false],    ]);  });   it("detects a logged-out CLI even though it exits 0", () => {    expect(parseGrokModelsCliOutput(LOGGED_OUT_MODELS_OUTPUT).authenticated).toBe(false);  });   it("returns unknown auth for unrecognized output", () => {    expect(parseGrokModelsCliOutput("grok 9.9.9\n").authenticated).toBeNull();  });}); describe("buildGrokModelsFromSessionModelState", () => {  it("marks the agent's current model as default and keeps reasoning options", () => {    const models = buildGrokModelsFromSessionModelState({      currentModelId: "grok-4.6",      availableModels: [        {          modelId: "grok-4.6",          name: "Grok 4.6",          _meta: {            supportsReasoningEffort: true,            reasoningEffort: "high",            reasoningEfforts: [{ value: "high", label: "High", default: true }],          },        },        { modelId: "grok-4.5", name: "Grok 4.5" },      ],    });    expect(models.map((model) => [model.slug, model.isDefault ?? false])).toEqual([      ["grok-4.6", true],      ["grok-4.5", false],    ]);    expect(models[0]?.capabilities?.optionDescriptors).toHaveLength(1);  });}); describe("buildGrokModelCapabilities", () => {  it("preserves ACP-provided reasoning labels and the active default", () => {    const capabilities = buildGrokModelCapabilities({      modelId: "grok-4.6",      name: "Grok 4.6",      _meta: {        supportsReasoningEffort: true,        reasoningEffort: "xhigh",        reasoningEfforts: [          { value: "xhigh", label: "Extra High Effort", default: true },          { value: "high", label: "High Effort", default: true },          { value: "medium", label: "Medium Effort" },          { value: "low", label: "Low Effort" },        ],      },    });     expect(capabilities.optionDescriptors).toEqual([      {        id: "reasoningEffort",        label: "Reasoning",        type: "select",        currentValue: "xhigh",        options: [          { id: "xhigh", label: "Extra High Effort", isDefault: true },          { id: "high", label: "High Effort" },          { id: "medium", label: "Medium Effort" },          { id: "low", label: "Low Effort" },        ],      },    ]);  });   it("uses raw ACP values when option labels are omitted", () => {    const capabilities = buildGrokModelCapabilities({      modelId: "grok-4.6",      name: "Grok 4.6",      _meta: {        supportsReasoningEffort: true,        reasoningEffort: "xhigh",        reasoningEfforts: [{ value: "xhigh" }, { value: "medium" }],      },    });     expect(capabilities.optionDescriptors).toEqual([      {        id: "reasoningEffort",        label: "Reasoning",        type: "select",        currentValue: "xhigh",        options: [          { id: "xhigh", label: "xhigh" },          { id: "medium", label: "medium" },        ],      },    ]);  });   it("keeps ACP current effort separate from its collapsed advertised default", () => {    const capabilities = buildGrokModelCapabilities({      modelId: "grok-4.6",      name: "Grok 4.6",      _meta: {        supportsReasoningEffort: true,        reasoningEffort: "medium",        reasoningEfforts: [          { value: "xhigh", label: "Extra High Effort", default: true },          { value: "high", label: "High Effort", default: true },          { value: "medium", label: "Medium Effort" },        ],      },    });     expect(capabilities.optionDescriptors).toEqual([      {        id: "reasoningEffort",        label: "Reasoning",        type: "select",        currentValue: "medium",        options: [          { id: "xhigh", label: "Extra High Effort", isDefault: true },          { id: "high", label: "High Effort" },          { id: "medium", label: "Medium Effort" },        ],      },    ]);  });   it("preserves ACP descriptions and falls back from invalid values to valid ids", () => {    const capabilities = buildGrokModelCapabilities({      modelId: "grok-4.6",      name: "Grok 4.6",      _meta: {        supportsReasoningEffort: true,        reasoningEffort: "high",        reasoningEfforts: [          {            id: "high",            value: "not a token",            label: "High Effort",            description: "Higher implementation quality",            default: true,          },          { id: "bad id", value: "also invalid", label: "Invalid" },        ],      },    });     expect(capabilities.optionDescriptors).toEqual([      {        id: "reasoningEffort",        label: "Reasoning",        type: "select",        currentValue: "high",        options: [          {            id: "high",            label: "High Effort",            description: "Higher implementation quality",            isDefault: true,          },        ],      },    ]);  });   it("accepts an advertised ACP menu when the support flag is omitted", () => {    const capabilities = buildGrokModelCapabilities({      modelId: "grok-4.6",      name: "Grok 4.6",      _meta: {        reasoningEffort: "high",        reasoningEfforts: [{ value: "high", label: "High Effort", default: true }],      },    });     expect(capabilities.optionDescriptors).toHaveLength(1);  });   it("honors an explicit ACP opt-out even when a menu is present", () => {    const capabilities = buildGrokModelCapabilities({      modelId: "grok-4.6",      name: "Grok 4.6",      _meta: {        supportsReasoningEffort: false,        reasoningEfforts: [{ value: "high", label: "High Effort", default: true }],      },    });     expect(capabilities.optionDescriptors).toEqual([]);  });   it("does not synthesize a reasoning menu when ACP omits it", () => {    expect(      buildGrokModelCapabilities({        modelId: "grok-4.6",        name: "Grok 4.6",        _meta: { supportsReasoningEffort: true, reasoningEffort: "xhigh" },      }).optionDescriptors,    ).toEqual([]);  });   it("keeps non-reasoning Grok models free of reasoning controls", () => {    expect(      buildGrokModelCapabilities({ modelId: "grok-build", name: "Grok Build" }).optionDescriptors,    ).toEqual([]);  });}); describe("buildInitialGrokProviderSnapshot", () => {  it.effect("returns a disabled snapshot when settings.enabled is false", () =>    Effect.gen(function* () {      const snapshot = yield* buildInitialGrokProviderSnapshot(        decodeGrokSettings({ enabled: false }),      );      expect(snapshot.enabled).toBe(false);      expect(snapshot.status).toBe("disabled");      expect(snapshot.installed).toBe(false);      expect(snapshot.message).toContain("disabled");    }),  );   it.effect("returns a disabled snapshot by default — Grok is opt-in", () =>    Effect.gen(function* () {      const snapshot = yield* buildInitialGrokProviderSnapshot(decodeGrokSettings({}));      expect(snapshot.enabled).toBe(false);      expect(snapshot.status).toBe("disabled");    }),  );   it.effect("returns a pending snapshot when enabled", () =>    Effect.gen(function* () {      const snapshot = yield* buildInitialGrokProviderSnapshot(        decodeGrokSettings({ enabled: true }),      );      expect(snapshot.enabled).toBe(true);      expect(snapshot.installed).toBe(true);      expect(snapshot.status).toBe("warning");      expect(snapshot.version).toBeNull();      expect(snapshot.message).toContain("Checking Grok");      expect(snapshot.requiresNewThreadForModelChange).toBeUndefined();    }),  );}); it.layer(NodeServices.layer)("checkGrokProviderStatus", (it) => {  it.effect("reports the binary as missing when the binary path does not resolve", () =>    Effect.gen(function* () {      const snapshot = yield* checkGrokProviderStatus(        decodeGrokSettings({          enabled: true,          binaryPath: "/definitely/not/installed/grok-binary",        }),      );      expect(snapshot.enabled).toBe(true);      expect(snapshot.installed).toBe(false);      expect(snapshot.status).toBe("error");      expect(snapshot.message).toMatch(/not installed|not on PATH|Failed to execute/);    }),  );   it.effect("reports an installed CLI as unhealthy when --version exits non-zero", () =>    Effect.gen(function* () {      const secretStderr = "broken grok install: secret-token-value";      const snapshot = yield* Effect.scoped(        Effect.gen(function* () {          const fs = yield* FileSystem.FileSystem;          const dir = yield* fs.makeTempDirectoryScoped({ prefix: "t3code-grok-version-" });          const grokPath = writeFakeCli({            directory: dir,            name: "grok",            source: [              // @effect-diagnostics-next-line preferSchemaOverJson:off              `process.stderr.write(${JSON.stringify(`${secretStderr}\n`)});`,              "process.exit(2);",              "",            ].join("\n"),          });           return yield* checkGrokProviderStatus(            decodeGrokSettings({ enabled: true, binaryPath: grokPath }),          );        }),      );       expect(snapshot.enabled).toBe(true);      expect(snapshot.installed).toBe(true);      expect(snapshot.status).toBe("error");      expect(snapshot.message).toBe("Grok CLI is installed but failed to run.");      expect(snapshot.message).not.toContain(secretStderr);    }),  );   // A stand-in for the Grok CLI: `--version` and `models` print canned text,  // and `agent stdio` execs the mock ACP agent so `initialize` returns model metadata.  const writeFakeGrokCli = (input: { readonly modelsOutput: string; readonly acp: boolean }) =>    Effect.gen(function* () {      const fs = yield* FileSystem.FileSystem;      const dir = yield* fs.makeTempDirectoryScoped({ prefix: "t3code-grok-probe-" });      const mockAgentPath = NodePath.resolve(__dirname, "../../../scripts/acp-mock-agent.ts");      return writeFakeCli({        directory: dir,        name: "grok",        source: [          'if (process.argv[2] === "--version") {',          '  process.stdout.write("grok 1.0.13\\n");',          "  process.exit(0);",          "}",          'if (process.argv[2] === "models") {',          // @effect-diagnostics-next-line preferSchemaOverJson:off          `  process.stdout.write(${JSON.stringify(input.modelsOutput)});`,          "  process.exit(0);",          "}",          'if (process.argv[2] !== "agent") process.exit(1);',          ...(input.acp ? [execScriptSource({ scriptPath: mockAgentPath })] : ["process.exit(3);"]),          "",        ].join("\n"),      });    });   it.effect("reports ready with ACP-discovered models when logged in", () =>    Effect.gen(function* () {      const snapshot = yield* Effect.scoped(        Effect.gen(function* () {          const grokPath = yield* writeFakeGrokCli({            modelsOutput: LOGGED_IN_MODELS_OUTPUT,            acp: true,          });          return yield* checkGrokProviderStatus(            decodeGrokSettings({ enabled: true, binaryPath: grokPath }),            { ...process.env, XAI_API_KEY: "" },          );        }),      );       expect(snapshot.status).toBe("ready");      expect(snapshot.version).toBe("1.0.13");      expect(snapshot.auth).toEqual({        status: "authenticated",        type: "cached_token",        label: "Grok account",      });      // The mock agent advertises grok-4.6 with reasoning options in initialize._meta.      expect(snapshot.models.map((model) => model.slug)).toEqual(["grok-4.6", "grok-mock-alt"]);      expect(snapshot.models[0]?.isDefault).toBe(true);      expect(        snapshot.models[0]?.capabilities?.optionDescriptors?.map((option) => option.id) ?? [],      ).toEqual(["reasoningEffort"]);    }),  );   it.effect("reports unauthenticated from `grok models` without starting a session", () =>    Effect.gen(function* () {      const snapshot = yield* Effect.scoped(        Effect.gen(function* () {          const grokPath = yield* writeFakeGrokCli({            modelsOutput: LOGGED_OUT_MODELS_OUTPUT,            acp: true,          });          return yield* checkGrokProviderStatus(            decodeGrokSettings({ enabled: true, binaryPath: grokPath }),            { ...process.env, XAI_API_KEY: "" },          );        }),      );       expect(snapshot.status).toBe("error");      expect(snapshot.auth.status).toBe("unauthenticated");      expect(snapshot.message).toContain("grok login");      expect(snapshot.models.map((model) => model.slug)).toEqual(["grok-4.6", "grok-mock-alt"]);    }),  );   it.effect("falls back to CLI-listed models with a warning when ACP initialize fails", () =>    Effect.gen(function* () {      const snapshot = yield* Effect.scoped(        Effect.gen(function* () {          const grokPath = yield* writeFakeGrokCli({            modelsOutput: LOGGED_IN_MODELS_OUTPUT,            acp: false,          });          return yield* checkGrokProviderStatus(            decodeGrokSettings({ enabled: true, binaryPath: grokPath }),            { ...process.env, XAI_API_KEY: "" },          );        }),      );       expect(snapshot.status).toBe("warning");      expect(snapshot.installed).toBe(true);      expect(snapshot.auth.status).toBe("authenticated");      expect(snapshot.models.map((model) => [model.slug, model.isDefault ?? false])).toEqual([        ["grok-4.6", true],        ["grok-4.5", false],      ]);      expect(snapshot.message).toContain("ACP initialize failed");    }),  );   it.effect("treats XAI_API_KEY as authenticated regardless of CLI login state", () =>    Effect.gen(function* () {      const snapshot = yield* Effect.scoped(        Effect.gen(function* () {          const grokPath = yield* writeFakeGrokCli({            modelsOutput: LOGGED_OUT_MODELS_OUTPUT,            acp: false,          });          return yield* checkGrokProviderStatus(            decodeGrokSettings({ enabled: true, binaryPath: grokPath }),            { ...process.env, XAI_API_KEY: "xai-test-key" },          );        }),      );       expect(snapshot.auth).toEqual({        status: "authenticated",        type: "api_key",        label: "xAI API key",      });      expect(snapshot.status).toBe("warning");    }),  );});