Files
oh-my-pi/packages/catalog/test/umans-provider.test.ts
T
2026-06-15 04:33:05 -07:00

143 lines
4.1 KiB
TypeScript

import { describe, expect, it } from "bun:test";
import {
MODELS_DEV_PROVIDER_DESCRIPTORS,
mapModelsDevToModels,
umansModelManagerOptions,
} from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
import type { FetchImpl } from "@oh-my-pi/pi-catalog/types";
import modelsJson from "../src/models.json";
interface BundledModel {
api: string;
provider: string;
baseUrl: string;
reasoning: boolean;
input: string[];
contextWindow: number | null;
maxTokens: number | null;
thinking?: {
defaultLevel?: string;
requiresEffort?: boolean;
};
}
describe("umans provider catalog", () => {
it("discovers Anthropic-route models from the public models info endpoint", async () => {
const requestedUrls: string[] = [];
const fetchImpl: FetchImpl = async input => {
requestedUrls.push(String(input));
return new Response(
JSON.stringify({
"umans-coder": {
display_name: "Umans Coder",
capabilities: {
context_window: 262_144,
max_completion_tokens: 262_144,
supports_vision: true,
supports_tools: true,
reasoning: { supported: true, can_disable: true, default_level: "medium" },
},
},
"umans-kimi-k2.7": {
display_name: "Umans Kimi K2.7 Code",
capabilities: {
context_window: 262_144,
max_completion_tokens: 262_144,
supports_vision: true,
supports_tools: true,
reasoning: { supported: true, can_disable: false, default_level: "medium" },
},
},
}),
{ status: 200, headers: { "Content-Type": "application/json" } },
);
};
const options = umansModelManagerOptions({ fetch: fetchImpl });
const fetchDynamicModels = options.fetchDynamicModels;
if (!fetchDynamicModels) throw new Error("Umans dynamic discovery is not configured");
const models = await fetchDynamicModels();
expect(requestedUrls).toEqual(["https://api.code.umans.ai/v1/models/info"]);
expect(models).not.toBeNull();
const model = models?.find(item => item.id === "umans-coder");
expect(model).toMatchObject({
id: "umans-coder",
name: "Umans Coder",
api: "anthropic-messages",
provider: "umans",
baseUrl: "https://api.code.umans.ai",
reasoning: true,
input: ["text", "image"],
contextWindow: 262_144,
maxTokens: 262_144,
thinking: { defaultLevel: "medium" },
});
const mandatoryReasoningModel = models?.find(item => item.id === "umans-kimi-k2.7");
expect(mandatoryReasoningModel).toMatchObject({
id: "umans-kimi-k2.7",
reasoning: true,
thinking: { defaultLevel: "medium", requiresEffort: true },
});
});
it("maps the models.dev Umans provider to the Anthropic endpoint", () => {
const models = mapModelsDevToModels(
{
"umans-ai-coding-plan": {
models: {
"umans-coder": {
name: "Umans Coder",
tool_call: true,
reasoning: true,
modalities: { input: ["text", "image"] },
limit: { context: 262_144, output: 262_144 },
cost: { input: 0, output: 0, cache_read: 0, cache_write: 0 },
},
},
},
},
MODELS_DEV_PROVIDER_DESCRIPTORS,
).filter(model => model.provider === "umans");
expect(models).toHaveLength(1);
expect(models[0]).toMatchObject({
id: "umans-coder",
api: "anthropic-messages",
provider: "umans",
baseUrl: "https://api.code.umans.ai",
reasoning: true,
input: ["text", "image"],
contextWindow: 262_144,
maxTokens: 262_144,
});
});
it("bundles the default Umans coding model", () => {
const providers = modelsJson as Record<string, Record<string, BundledModel>>;
const model = providers.umans?.["umans-coder"];
expect(model).toBeDefined();
expect(model).toMatchObject({
api: "anthropic-messages",
provider: "umans",
baseUrl: "https://api.code.umans.ai",
reasoning: true,
input: ["text", "image"],
contextWindow: 262_144,
maxTokens: 262_144,
});
});
it("bundles Umans mandatory reasoning metadata", () => {
const providers = modelsJson as Record<string, Record<string, BundledModel>>;
const model = providers.umans?.["umans-kimi-k2.7"];
expect(model).toBeDefined();
expect(model.thinking).toMatchObject({
requiresEffort: true,
});
});
});