Files
OmniRoute/tests/unit/cli/setup-continue.test.ts
Diego Rodrigues de Sa e Souza 138ea6628d feat(cli): setup-continue — generate ~/.continue/config.yaml for OmniRoute (#4289)
CLI #6 of the series. `omniroute setup-continue` writes Continue's file-based,
mergeable ~/.continue/config.yaml (shared by the VS Code/JetBrains extensions AND
the `cn` CLI) from the live model catalog.

- Each curated model → a Continue model entry: provider: openai, model: <id>,
  apiBase WITH /v1 (Continue appends /chat/completions), apiKey:
  ${{ secrets.OMNIROUTE_API_KEY }} (secret referenced, never written), roles
  [chat, edit, apply] (+ autocomplete for the fast tier).
- Merges into existing config.yaml (js-yaml load/dump): drops prior models on the
  same apiBase, preserves the user's other models + top-level keys.
- Remote-aware (--remote/--api-key → active context → localhost); --only filter.
- Prints how to provide the key (shell env for cn; ~/.continue/.env for IDE).

Researched against current Continue docs: provider: openai + custom apiBase (with
/v1), the ${{ secrets.X }} syntax, roles, and that the `cn` CLI shares the same
config. Continue's wire (/v1/chat/completions) already validated → "OK".

Tests: buildContinueModels (provider/apiBase/secret/roles, fast→autocomplete,
skip uncategorised), mergeContinueConfig (replace-ours/keep-others/defaults),
resolveContinueTarget (/v1). 6 unit tests; check:cli-i18n green.
2026-06-19 13:19:12 -03:00

56 lines
2.5 KiB
TypeScript

import { test } from "node:test";
import assert from "node:assert/strict";
import {
buildContinueModels,
mergeContinueConfig,
resolveContinueTarget,
} from "../../../bin/cli/commands/setup-continue.mjs";
test("buildContinueModels emits provider:openai + apiBase + secret ref + roles", () => {
const models = buildContinueModels(["glm/glm-5.2"], "http://vps:20128/v1");
assert.equal(models.length, 1);
const m = models[0];
assert.equal(m.provider, "openai");
assert.equal(m.model, "glm/glm-5.2");
assert.equal(m.apiBase, "http://vps:20128/v1");
assert.equal(m.apiKey, "${{ secrets.OMNIROUTE_API_KEY }}");
assert.ok(m.roles.includes("chat") && m.roles.includes("edit") && m.roles.includes("apply"));
});
test("buildContinueModels gives the fast tier an autocomplete role", () => {
const fast = buildContinueModels(["glm/glm-5-turbo"], "http://x/v1")[0]; // fast → effort low
assert.ok(fast.roles.includes("autocomplete"));
});
test("buildContinueModels skips uncategorised models", () => {
assert.equal(buildContinueModels(["some/unknown-model"], "http://x/v1").length, 0);
});
test("mergeContinueConfig replaces prior OmniRoute models, keeps others", () => {
const existing = {
name: "My Config",
models: [
{ name: "Local Ollama", provider: "ollama", model: "llama3", apiBase: "http://localhost:11434" },
{ name: "old omni", provider: "openai", model: "x", apiBase: "http://vps:20128/v1" },
],
};
const fresh = buildContinueModels(["glm/glm-5.2"], "http://vps:20128/v1");
const merged = mergeContinueConfig(existing, fresh, "http://vps:20128/v1");
// kept the ollama model; dropped the old omni one (same apiBase); added the new
const apiBases = merged.models.map((m) => m.apiBase);
assert.ok(merged.models.some((m) => m.provider === "ollama"));
assert.equal(merged.models.filter((m) => m.apiBase === "http://vps:20128/v1").length, 1);
assert.equal(merged.name, "My Config", "preserves existing top-level keys");
});
test("mergeContinueConfig sets defaults on an empty config", () => {
const merged = mergeContinueConfig({}, buildContinueModels(["glm/glm-5.2"], "http://x/v1"), "http://x/v1");
assert.equal(merged.schema, "v1");
assert.ok(merged.name && merged.version);
});
test("resolveContinueTarget ensures /v1 on apiBase", () => {
assert.equal(resolveContinueTarget({ remote: "http://vps:20128" }).apiBase, "http://vps:20128/v1");
assert.equal(resolveContinueTarget({ remote: "http://vps:20128/v1/" }).apiBase, "http://vps:20128/v1");
});