AkurAI Build
Menu

popagent

public

Latest change 7cecf6a89b6f39dae8c5678f5b369014199aeb3c - Add self-hosted Mastra observability by AkurAI Build

import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { appLogger } from "./observability";
import type { ModelCatalog } from "./api-types";

const BASE_URL = process.env.NINEROUTER_URL ?? "http://127.0.0.1:20128/v1";
const API_KEY = process.env.NINEROUTER_API_KEY ?? "";

const ninerouter = createOpenAICompatible({
  name: "9router",
  baseURL: BASE_URL,
  apiKey: API_KEY,
});

/** Language model for one explicit 9Router model id. */
export function resolveModel(modelId: string) {
  return ninerouter.chatModel(modelId);
}


/** Selectable model ids and their context limits from the 9router gateway. */
export async function listModelCatalog(): Promise<ModelCatalog> {
  const res = await fetch(`${BASE_URL}/models`, {
    headers: { authorization: `Bearer ${API_KEY}` },
    signal: AbortSignal.timeout(5000),
  });
  if (!res.ok) throw new Error(`9router /models failed: ${res.status}`);
  const { data } = (await res.json()) as {
    data: {
      id: string;
      context_length?: number;
      max_input_tokens?: number;
      capabilities?: { contextWindow?: number };
    }[];
  };
  const contextWindows: Record<string, number> = {};
  for (const model of data) {
    const limit =
      model.context_length ??
      model.max_input_tokens ??
      model.capabilities?.contextWindow ??
      0;
    contextWindows[model.id] = Math.max(contextWindows[model.id] ?? 0, limit);
  }
  return {
    models: data.map((model) => model.id),
    contextWindows,
  };
}

let catalogCache: { catalog: ModelCatalog; expires: number } | undefined;
export async function isKnownModel(model: string): Promise<boolean> {
  if (catalogCache && catalogCache.expires > Date.now()) return catalogCache.catalog.models.includes(model);
  try {
    const catalog = await listModelCatalog();
    catalogCache = { catalog, expires: Date.now() + 60_000 };
    return catalog.models.includes(model);
  } catch (error) {
    appLogger().warn("model.catalog.unavailable", { error });
    return true;
  }
}