Files
openrusrouter-mcp/test/helpers.ts
T
vasyanskandClaude Opus 5.5 d7d02267e2 Добавь HTTP-клиент, каталог моделей и шесть read-only инструментов MCP
Клиент — замороженный объект с семью методами GET, без универсального
запроса и тела; денежные поля проверяются на строковый тип (fail-closed).
Каталог джойнит /api/models и /v1/models: модальность и рубли из первого,
USD и доступность ключу из второго. Инструменты: list_models, pick_model,
estimate_cost, get_balance, get_usage, list_api_keys. Точка входа stdio
уводит console.log/info в stderr первым импортом.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:59:06 +07:00

41 lines
1.4 KiB
TypeScript

import { readFileSync } from "node:fs";
import { joinCatalog, type CatalogItem } from "../src/catalog.js";
import type { ApiModelsResponse, V1ModelsResponse } from "../src/client.js";
export function fixture<T = unknown>(name: string): T {
return JSON.parse(readFileSync(new URL(`./fixtures/${name}.json`, import.meta.url), "utf8")) as T;
}
export function fixtureCatalog(): CatalogItem[] {
const api = fixture<ApiModelsResponse>("api-models");
const v1 = fixture<V1ModelsResponse>("v1-models");
return joinCatalog(api.data, v1.data, () => undefined);
}
export function byId(items: readonly CatalogItem[], id: string): CatalogItem {
const it = items.find((m) => m.id === id);
if (it === undefined) throw new Error(`нет ${id} в фикстуре`);
return it;
}
/** Синтетическая текстовая модель для граничных случаев сравнения цен. */
export function synthetic(id: string, prompt: string | null, completion: string | null = prompt): CatalogItem {
return {
id,
name: id,
description: "",
vendor: id.split("/")[0] ?? id,
modality: "text",
input_modalities: ["text"],
context_length: 100_000,
is_free: false,
price_prompt_rub_1m: prompt,
price_completion_rub_1m: completion,
price_image_rub: null,
price_image_unit: null,
price_note: null,
usd: null,
allowed_for_this_key: true,
};
}