469 lines · 15.6 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 Path from "effect/Path";import * as Schema from "effect/Schema";import { GrokSettings } from "@t3tools/contracts"; import {  buildGrokModelCapabilities,  buildGrokModelsFromSessionModelState,  buildInitialGrokProviderSnapshot,  checkGrokProviderStatus,  parseGrokModelsCliOutput,} from "./GrokProvider.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 path = yield* Path.Path;          const dir = yield* fs.makeTempDirectoryScoped({ prefix: "t3code-grok-version-" });          const grokPath = path.join(dir, "grok");          yield* fs.writeFileString(            grokPath,            ["#!/bin/sh", `printf "%s\\n" "${secretStderr}" >&2`, "exit 2", ""].join("\n"),          );          yield* fs.chmod(grokPath, 0o755);           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);    }),  );   // Single-quotes a path for /bin/sh. Temp dirs and execPath never contain quotes.  const shellQuote = (value: string) => `'${value.replaceAll("'", `'\\''`)}'`;   // A shell 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 path = yield* Path.Path;      const dir = yield* fs.makeTempDirectoryScoped({ prefix: "t3code-grok-probe-" });      const modelsPath = path.join(dir, "models.txt");      yield* fs.writeFileString(modelsPath, input.modelsOutput);      const grokPath = path.join(dir, "grok");      const mockAgentPath = path.resolve(__dirname, "../../../scripts/acp-mock-agent.ts");      yield* fs.writeFileString(        grokPath,        [          "#!/bin/sh",          'case "$1" in',          '  --version) printf "grok 1.0.13\\n"; exit 0;;',          `  models) cat ${shellQuote(modelsPath)}; exit 0;;`,          input.acp            ? `  agent) exec ${shellQuote(process.execPath)} ${shellQuote(mockAgentPath)};;`            : "  agent) exit 3;;",          "esac",          "exit 1",          "",        ].join("\n"),      );      yield* fs.chmod(grokPath, 0o755);      return grokPath;    });   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");    }),  );});