Files
fathah--hermes-desktop/tests/provider-registry.test.ts
2026-07-13 13:36:53 +08:00

115 lines
4.0 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
PROVIDER_BASE_URLS,
canonicalProviderBaseUrl,
} from "../src/main/provider-registry";
describe("provider-registry", () => {
describe("canonicalProviderBaseUrl", () => {
it("returns the canonical URL for built-in OpenAI-compatible providers", () => {
expect(canonicalProviderBaseUrl("deepseek")).toBe(
"https://api.deepseek.com/v1",
);
expect(canonicalProviderBaseUrl("groq")).toBe(
"https://api.groq.com/openai/v1",
);
expect(canonicalProviderBaseUrl("mistral")).toBe(
"https://api.mistral.ai/v1",
);
expect(canonicalProviderBaseUrl("xiaomi")).toBe(
"https://api.xiaomimimo.com/v1",
);
expect(canonicalProviderBaseUrl("aimlapi")).toBe(
"https://api.aimlapi.com/v1",
);
expect(canonicalProviderBaseUrl("together")).toBe(
"https://api.together.xyz/v1",
);
expect(canonicalProviderBaseUrl("fireworks")).toBe(
"https://api.fireworks.ai/inference/v1",
);
expect(canonicalProviderBaseUrl("cerebras")).toBe(
"https://api.cerebras.ai/v1",
);
// Must stay the agent's own default (international) — a CN value here
// would be written into every empty-base_url alibaba config on save.
expect(canonicalProviderBaseUrl("alibaba")).toBe(
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
);
});
it("returns the canonical URL for the Big3 (openai / anthropic / openrouter)", () => {
expect(canonicalProviderBaseUrl("openai")).toBe(
"https://api.openai.com/v1",
);
expect(canonicalProviderBaseUrl("anthropic")).toBe(
"https://api.anthropic.com/v1",
);
expect(canonicalProviderBaseUrl("openrouter")).toBe(
"https://openrouter.ai/api/v1",
);
expect(canonicalProviderBaseUrl("ollama-cloud")).toBe(
"https://ollama.com/v1",
);
});
it("returns default URLs for local OpenAI-compatible providers", () => {
expect(canonicalProviderBaseUrl("lmstudio")).toBe(
"http://localhost:1234/v1",
);
expect(canonicalProviderBaseUrl("atomicchat")).toBe(
"http://localhost:1337/v1",
);
expect(canonicalProviderBaseUrl("ollama")).toBe(
"http://localhost:11434/v1",
);
expect(canonicalProviderBaseUrl("vllm")).toBe("http://localhost:8000/v1");
expect(canonicalProviderBaseUrl("llamacpp")).toBe(
"http://localhost:8080/v1",
);
});
it("is case-insensitive on the provider id", () => {
expect(canonicalProviderBaseUrl("DeepSeek")).toBe(
"https://api.deepseek.com/v1",
);
expect(canonicalProviderBaseUrl("MISTRAL")).toBe(
"https://api.mistral.ai/v1",
);
});
it("returns null for providers that don't have a canonical URL", () => {
// `custom` and `auto` are intentionally not in the registry — the
// user must supply their own baseUrl.
expect(canonicalProviderBaseUrl("custom")).toBeNull();
expect(canonicalProviderBaseUrl("auto")).toBeNull();
// Unknown/user-defined provider ids.
expect(canonicalProviderBaseUrl("my-private-llm")).toBeNull();
expect(canonicalProviderBaseUrl("")).toBeNull();
});
it("the registry covers every built-in remote OpenAI-compat provider", () => {
// These are the provider ids that hermes-desktop's renderer
// exposes as built-in "remote" presets (constants.ts:LOCAL_PRESETS,
// group: "remote"). They MUST have canonical URLs here — otherwise
// setModelConfig would silently leave `base_url:` empty when the
// user picks them, which is the regression this module exists to
// prevent.
const requiredBuiltins = [
"groq",
"aimlapi",
"deepseek",
"together",
"fireworks",
"cerebras",
"mistral",
"xiaomi",
"ollama-cloud",
];
for (const provider of requiredBuiltins) {
expect(PROVIDER_BASE_URLS[provider]).toBeTruthy();
}
});
});
});