import { readdirSync } from "node:fs"; import { join } from "node:path"; import type { FastifyInstance } from "fastify"; import { isPrincipalContext, requirePermission } from "../auth/authorization.js"; import type { RuntimeModelCatalog } from "../models/runtime-model-catalog.js"; /** * List YAML workspace configs found in /workspaces/*.yaml. * Returns [{name, file}] — no database credentials or secrets. */ export function listWorkspaces(harnessDir: string): { name: string; file: string }[] { const dir = join(harnessDir, "workspaces"); let entries: string[]; try { entries = readdirSync(dir); } catch { return []; } return entries .filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")) .map((f) => ({ name: f.replace(/\.ya?ml$/, ""), file: f })); } export function metaRoutes( app: FastifyInstance, deps: { harnessDir: string; modelCatalog: RuntimeModelCatalog }, ): void { app.get("/models", async (request, reply) => { if (!isPrincipalContext(requirePermission(request, reply, "session.use"))) return reply; return { models: deps.modelCatalog.sessionModels().map((entry) => ({ provider: entry.provider, id: entry.model, name: entry.label, reasoning: entry.session?.reasoning ?? false, })), }; }); }