121 lines · 3.5 KB · TypeScript
RawDownload
import * as Effect from "effect/Effect";import type * as EffectAcpSchema from "effect-acp/schema";import { describe, expect, it } from "vitest"; import { applyCursorAcpModelSelection, buildCursorAcpSpawnInput } from "./CursorAcpSupport.ts"; const parameterizedGpt54ConfigOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption> = [  {    id: "model",    name: "Model",    category: "model",    type: "select",    currentValue: "gpt-5.4-medium-fast",    options: [{ value: "gpt-5.4-medium-fast", name: "GPT-5.4" }],  },  {    id: "reasoning",    name: "Reasoning",    category: "thought_level",    type: "select",    currentValue: "medium",    options: [      { value: "low", name: "Low" },      { value: "medium", name: "Medium" },      { value: "high", name: "High" },      { value: "extra-high", name: "Extra High" },    ],  },  {    id: "context",    name: "Context",    category: "model_config",    type: "select",    currentValue: "272k",    options: [      { value: "272k", name: "272K" },      { value: "1m", name: "1M" },    ],  },  {    id: "fast",    name: "Fast",    category: "model_config",    type: "select",    currentValue: "false",    options: [      { value: "false", name: "Off" },      { value: "true", name: "Fast" },    ],  },]; describe("buildCursorAcpSpawnInput", () => {  it("builds the default Cursor ACP command", () => {    expect(buildCursorAcpSpawnInput(undefined, "/tmp/project")).toEqual({      command: "agent",      args: ["acp"],      cwd: "/tmp/project",    });  });   it("includes the configured api endpoint when present", () => {    expect(      buildCursorAcpSpawnInput(        {          binaryPath: "/usr/local/bin/agent",          apiEndpoint: "http://localhost:3000",        },        "/tmp/project",      ),    ).toEqual({      command: "/usr/local/bin/agent",      args: ["-e", "http://localhost:3000", "acp"],      cwd: "/tmp/project",    });  });}); describe("applyCursorAcpModelSelection", () => {  it("sets the base model before applying separate config options", async () => {    const calls: Array<      | { readonly type: "model"; readonly value: string }      | { readonly type: "config"; readonly configId: string; readonly value: string | boolean }    > = [];     const runtime = {      getConfigOptions: Effect.succeed(parameterizedGpt54ConfigOptions),      setModel: (value: string) =>        Effect.sync(() => {          calls.push({ type: "model", value });        }),      setConfigOption: (configId: string, value: string | boolean) =>        Effect.sync(() => {          calls.push({ type: "config", configId, value });        }),    };     await Effect.runPromise(      applyCursorAcpModelSelection({        runtime,        model: "gpt-5.4-medium-fast[reasoning=medium,context=272k]",        selections: [          { id: "reasoning", value: "xhigh" },          { id: "contextWindow", value: "1m" },          { id: "fastMode", value: true },        ],        mapError: ({ step, configId, cause }) =>          step === "set-config-option"            ? `failed to set config option ${configId}: ${cause.message}`            : `failed to set model: ${cause.message}`,      }),    );     expect(calls).toEqual([      { type: "model", value: "gpt-5.4-medium-fast" },      { type: "config", configId: "reasoning", value: "extra-high" },      { type: "config", configId: "context", value: "1m" },      { type: "config", configId: "fast", value: "true" },    ]);  });});