Files
OmniRoute/open-sse/mcp-server/tools/agentSkillTools.ts
Praveen K Palaniswamy 65e81158ab fix(ollama): route models by advertised capability (#11088)
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host.

Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean.

Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
2026-08-23 11:45:01 -03:00

93 lines
3.3 KiB
TypeScript

import { z } from "zod";
import {
getCatalog,
getSkillById,
filterCatalog,
computeCoverage,
fetchSkillMarkdown,
} from "@/lib/agentSkills/catalog";
import type { AgentSkill, SkillCoverage } from "@/lib/agentSkills/types";
// ── Input Schemas ────────────────────────────────────────────────────────────
export const AgentSkillsListSchema = z.object({
category: z
.enum(["api", "cli", "config"])
.optional()
.describe("Filter by category: 'api', 'cli', or 'config'"),
area: z.string().optional().describe("Filter by area (e.g. 'providers', 'models', 'cli-serve')"),
});
export const AgentSkillsGetSchema = z.object({
id: z.string().describe("Canonical skill ID (e.g. 'omni-providers', 'cli-serve')"),
});
export const AgentSkillsCoverageSchema = z.object({});
// ── Tool Definitions ─────────────────────────────────────────────────────────
export const agentSkillTools = {
omniroute_agent_skills_list: {
name: "omniroute_agent_skills_list",
description:
"List OmniRoute agent skills with optional filtering by category (api/cli/config) or area. Returns skill metadata including id, name, description, endpoints/commands, and URLs.",
inputSchema: AgentSkillsListSchema,
handler: async (args: z.infer<typeof AgentSkillsListSchema>) => {
const skills: AgentSkill[] =
args.category || args.area
? filterCatalog({ category: args.category, area: args.area })
: getCatalog();
return {
skills: skills.map((s) => ({
id: s.id,
name: s.name,
description: s.description,
category: s.category,
area: s.area,
endpoints: s.endpoints,
cliCommands: s.cliCommands,
icon: s.icon,
isEntry: s.isEntry,
isNew: s.isNew,
rawUrl: s.rawUrl,
githubUrl: s.githubUrl,
})),
count: skills.length,
coverage: computeCoverage(),
};
},
},
omniroute_agent_skills_get: {
name: "omniroute_agent_skills_get",
description:
"Get detailed metadata and SKILL.md markdown for a single agent skill by its canonical ID. Returns all skill fields plus the raw markdown content.",
inputSchema: AgentSkillsGetSchema,
handler: async (args: z.infer<typeof AgentSkillsGetSchema>) => {
const skill: AgentSkill | null = getSkillById(args.id);
if (!skill) {
throw new Error(`Skill not found: ${args.id}`);
}
const markdown = await fetchSkillMarkdown(args.id);
return {
...skill,
markdown,
};
},
},
omniroute_agent_skills_coverage: {
name: "omniroute_agent_skills_coverage",
description:
"Returns the current SKILL.md coverage stats: how many of the 23 API, 21 CLI, and 1 config skill have generated SKILL.md files on the filesystem vs the catalog total.",
inputSchema: AgentSkillsCoverageSchema,
handler: async (_args: z.infer<typeof AgentSkillsCoverageSchema>) => {
const coverage: SkillCoverage = computeCoverage();
return coverage;
},
},
};