feat(providers): integrate audited free-tier gateways (#9210)

* feat(providers): add Zylo UnoRouter and Poolside registries

* feat(providers): integrate audited free-tier gateways

* feat: add wave2 free-tier provider registries

* feat(providers): add Mixlayer Speka and TokenReply registries

* feat: add wave 2 free-tier provider registries

* fix: align meganova provider slug

* feat(providers): integrate wave2 free-tier gateways

* feat(providers): add Wave 3-A free-tier registries

* feat(providers): add HelyxAI Auriko and Poixe registries

* feat(providers): add Naga AI and Chat Oripe registries

* feat(providers): integrate wave3 free-tier gateways

* feat(providers): add FreeInference registry

* feat(providers): add Free.ai registry

* feat(providers): integrate wave4 free-tier gateways

* docs: synchronize provider and free-tier inventories

* refactor(providers): split audited gateway catalog

* feat(providers): add audited Void AI and HelixMind gateways

* feat(providers): finalize audited free-tier integration

* test(providers): update APIKEY split count to 229 after rebase onto release/v3.8.50

The rebase merged the release catalog (201 APIKEY providers) with the PR's
28 free-tier additions, yielding 229 total. Correct the characterization
count so the partition assertion reflects the true merged state.

---------

Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: backryun <bakryun0718@proton.me>
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-08-12 16:19:25 -03:00
committed by GitHub
parent f6ccd3cf9f
commit ecc89eef14
345 changed files with 9108 additions and 9012 deletions

View File

@@ -38,6 +38,10 @@ function CoverageBarSkeleton(): JSX.Element {
<div className="h-2 w-16 rounded bg-bg-subtle" />
<div className="flex-1 h-2 rounded bg-bg-subtle" />
</div>
<div className="flex gap-2">
<div className="h-2 w-16 rounded bg-bg-subtle" />
<div className="flex-1 h-2 rounded bg-bg-subtle" />
</div>
</div>
);
}
@@ -189,8 +193,12 @@ export function AgentSkillsPageClient(): JSX.Element {
});
const selectedMarkdown = selectedId ? (markdownCache.get(selectedId) ?? null) : null;
const coverageTotal = coverage !== null ? coverage.api.have + coverage.cli.have : null;
const showGenerateButton = coverageTotal !== null && coverageTotal < 42;
const coverageTotal =
coverage !== null ? coverage.api.have + coverage.cli.have + coverage.config.have : null;
const catalogTotal =
coverage !== null ? coverage.api.total + coverage.cli.total + coverage.config.total : null;
const showGenerateButton =
coverageTotal !== null && catalogTotal !== null && coverageTotal < catalogTotal;
return (
<div className="flex flex-col gap-4">

View File

@@ -23,7 +23,7 @@ function trackColor(have: number, total: number): string {
export function CoverageBar({ coverage }: CoverageBarProps): JSX.Element {
const t = useTranslations("agentSkills");
const { api, cli } = coverage;
const { api, cli, config } = coverage;
return (
<div className="flex flex-col gap-2 text-xs" data-testid="coverage-bar">
@@ -49,6 +49,28 @@ export function CoverageBar({ coverage }: CoverageBarProps): JSX.Element {
</span>
</div>
<div className="flex items-center justify-between gap-2">
<span className="font-medium text-text-muted shrink-0">
{t("categoryConfig")} {config.have}/{config.total}
</span>
<div
className={`flex-1 h-2 rounded-full overflow-hidden ${trackColor(config.have, config.total)}`}
>
<div
role="progressbar"
aria-valuenow={config.have}
aria-valuemin={0}
aria-valuemax={config.total}
aria-label={`${t("categoryConfig")} ${config.have}/${config.total}`}
className={`h-full rounded-full transition-all duration-500 ${barColor(config.have, config.total)}`}
style={{ width: `${config.total > 0 ? (config.have / config.total) * 100 : 0}%` }}
/>
</div>
<span className="shrink-0 text-text-muted w-12 text-right">
{config.total > 0 ? Math.round((config.have / config.total) * 100) : 0}%
</span>
</div>
<div className="flex items-center justify-between gap-2">
<span className="font-medium text-text-muted shrink-0">
{t("categoryCli")} {cli.have}/{cli.total}

View File

@@ -1,7 +1,7 @@
/**
* A2A Skill: List Capabilities
*
* Returns the full catalog of OmniRoute agent skills (22 API + 20 CLI + config)
* Returns the full catalog of OmniRoute agent skills (23 API + 21 CLI + 1 config)
* as a markdown table with raw SKILL.md URLs for orchestrating agents.
*/
@@ -14,7 +14,8 @@ export interface ListCapabilitiesResult {
metadata: {
coverage: {
api: { have: number; total: 23 };
cli: { have: number; total: 20 };
cli: { have: number; total: 21 };
config: { have: number; total: 1 };
};
totalSkills: number;
generatedAt: string;
@@ -47,7 +48,7 @@ export async function executeListCapabilities(_task: A2ATask): Promise<ListCapab
const content = [
`# OmniRoute Agent Skills Catalog`,
``,
`Total: ${catalog.length} skills (${coverage.api.total} API + ${coverage.cli.total} CLI)`,
`Total: ${catalog.length} skills (${coverage.api.total} API + ${coverage.cli.total} CLI + ${coverage.config.total} config)`,
``,
table,
].join("\n");
@@ -62,7 +63,8 @@ export async function executeListCapabilities(_task: A2ATask): Promise<ListCapab
metadata: {
coverage: {
api: { have: coverage.api.have, total: 23 },
cli: { have: coverage.cli.have, total: 20 },
cli: { have: coverage.cli.have, total: 21 },
config: { have: coverage.config.have, total: 1 },
},
totalSkills: catalog.length,
generatedAt: coverage.generatedAt,

View File

@@ -1,5 +1,5 @@
/**
* catalog.ts — single source of truth for the 43-entry Agent Skills catalog.
* catalog.ts — single source of truth for the 45-entry Agent Skills catalog.
*
* Consumers: REST routes (/api/agent-skills/*), MCP tools, A2A skill, Generator.
* Do NOT import this from UI components directly — use the REST API instead.
@@ -16,7 +16,7 @@ import {
// ── Canonical ID lists (D28) ────────────────────────────────────────────────
/** 22 canonical API skill IDs, in spec order. */
/** 23 canonical API skill IDs, in spec order. */
export const API_SKILL_IDS: readonly string[] = [
"omni-auth",
"omni-providers",
@@ -46,7 +46,7 @@ export const API_SKILL_IDS: readonly string[] = [
/** Config skill IDs. */
export const CONFIG_SKILL_IDS: readonly string[] = ["config-codex-cli"] as const;
/** 20 canonical CLI skill IDs, in spec order. */
/** 21 canonical CLI skill IDs, in spec order. */
export const CLI_SKILL_IDS: readonly string[] = [
"cli-serve",
"cli-health",
@@ -94,7 +94,7 @@ function deriveCatalog(): AgentSkill[] {
// ── Public API ───────────────────────────────────────────────────────────────
/**
* Returns the full catalog (43 entries). Cached in module scope after first call.
* Returns the full catalog (45 entries). Cached in module scope after first call.
* Safe to call multiple times — re-derives only after `refreshCatalog()`.
*/
export function getCatalog(): AgentSkill[] {
@@ -110,7 +110,10 @@ export function getSkillById(id: string): AgentSkill | null {
}
/** Filters catalog by category and/or area. */
export function filterCatalog(opts: { category?: "api" | "cli"; area?: string }): AgentSkill[] {
export function filterCatalog(opts: {
category?: "api" | "cli" | "config";
area?: string;
}): AgentSkill[] {
let skills = getCatalog();
if (opts.category) {
skills = skills.filter((s) => s.category === opts.category);
@@ -122,7 +125,7 @@ export function filterCatalog(opts: { category?: "api" | "cli"; area?: string })
}
/**
* Computes coverage stats: filesystem has SKILL.md vs catalog declares 42.
* Computes coverage stats: filesystem has SKILL.md vs the 45-entry catalog.
* Reads `skills/` relative to the project root (CWD).
*/
export function computeCoverage(): SkillCoverage {
@@ -149,8 +152,8 @@ export function computeCoverage(): SkillCoverage {
const configHave = catalog.filter((s) => s.category === "config" && presentIds.has(s.id)).length;
return {
// Totals derive from the id lists — hardcoded 23/20 went stale the first
// time the catalog grew (cli-skill-collector registration, 2026-07-15).
// Totals derive from the canonical id lists so catalog additions cannot
// leave the coverage contract behind.
api: { have: apiHave, total: API_SKILL_IDS.length },
cli: { have: cliHave, total: CLI_SKILL_IDS.length },
config: { have: configHave, total: configTotal },

View File

@@ -1,5 +1,5 @@
/**
* generator.ts — idempotent SKILL.md generator for all 42 agent skills.
* generator.ts — idempotent SKILL.md generator for all 45 agent skills.
*
* Usage (library):
* import { generateAgentSkills, buildSkillMarkdown } from "@/lib/agentSkills/generator";

View File

@@ -1,6 +1,6 @@
import { z } from "zod";
export const SkillCategorySchema = z.enum(["api", "cli"]);
export const SkillCategorySchema = z.enum(["api", "cli", "config"]);
export const AgentSkillSchema = z.object({
id: z.string().regex(/^[a-z][a-z0-9-]*$/),
@@ -19,7 +19,8 @@ export const AgentSkillSchema = z.object({
export const SkillCoverageSchema = z.object({
api: z.object({ have: z.number().int().nonnegative(), total: z.literal(23) }),
cli: z.object({ have: z.number().int().nonnegative(), total: z.literal(20) }),
cli: z.object({ have: z.number().int().nonnegative(), total: z.literal(21) }),
config: z.object({ have: z.number().int().nonnegative(), total: z.literal(1) }),
totalSkills: z.number().int().nonnegative(),
generatedAt: z.string().datetime(),
});

View File

@@ -1,7 +1,7 @@
export type SkillCategory = "api" | "cli" | "config" | "external";
export type SkillArea =
// API areas (22)
// API areas (23)
| "auth"
| "providers"
| "models"
@@ -28,7 +28,7 @@ export type SkillArea =
| "github-skills"
// Config skills
| "config-codex-cli"
// CLI families (20)
// CLI families (21)
| "cli-serve"
| "cli-health"
| "cli-providers"

View File

@@ -35,11 +35,11 @@ export interface CuratedSkillEntry {
isNew?: boolean;
}
// ── Canonical 42-entry curated list (D28) ────────────────────────────────────
// ── Canonical 45-entry curated list (D28) ────────────────────────────────────
/** Curated metadata for all 42 agent skills. Source-of-truth for the catalog. */
/** Curated metadata for all 45 agent skills. Source-of-truth for the catalog. */
export const CURATED_SKILLS: CuratedSkillEntry[] = [
// ── API Skills (22) ─────────────────────────────────────────────────────────
// ── API Skills (23) ─────────────────────────────────────────────────────────
{
id: "omni-auth",
@@ -55,7 +55,7 @@ export const CURATED_SKILLS: CuratedSkillEntry[] = [
id: "omni-providers",
name: "Providers",
description:
"Manage provider connections, API keys, OAuth flows, and connection tests via the REST API. List, add, update, remove, and test AI provider integrations (OpenAI, Anthropic, Gemini, and 160+).",
"Manage provider connections, API keys, OAuth flows, and connection tests via the REST API. List, add, update, remove, and test AI provider integrations across OmniRoute's 327-provider catalog.",
category: "api",
area: "providers",
icon: "key",
@@ -73,7 +73,7 @@ export const CURATED_SKILLS: CuratedSkillEntry[] = [
id: "omni-combos-routing",
name: "Combos & Routing",
description:
"Create and manage routing combos with 14 strategies (priority, weighted, round-robin, Auto-combo, etc.). Configure fallback chains, test routing outcomes, and retrieve combo metrics.",
"Create and manage routing combos with 19 strategies (priority, weighted, round-robin, Auto-combo, and more). Configure fallback chains, test routing outcomes, and retrieve combo metrics.",
category: "api",
area: "combos-routing",
icon: "route",
@@ -212,7 +212,7 @@ export const CURATED_SKILLS: CuratedSkillEntry[] = [
id: "omni-mcp",
name: "MCP Server",
description:
"Connect to the OmniRoute MCP server (37 tools, 3 transports: SSE/stdio/HTTP). Covers routing, cache, compression, memory, skills, providers, and audit tools across 16 permission scopes.",
"Connect to the OmniRoute MCP server (107 tools, 3 transports: SSE/stdio/HTTP). Covers routing, cache, compression, memory, skills, providers, and audit tools across 32 permission scopes.",
category: "api",
area: "mcp",
icon: "electrical_services",
@@ -245,7 +245,7 @@ export const CURATED_SKILLS: CuratedSkillEntry[] = [
icon: "hub",
},
// ── CLI Skills (20) ──────────────────────────────────────────────────────────
// ── CLI Skills (21) ──────────────────────────────────────────────────────────
{
id: "cli-serve",
@@ -457,7 +457,7 @@ export const CURATED_SKILLS: CuratedSkillEntry[] = [
id: "omni-github-skills",
name: "GitHub Skill Discovery",
description:
"Search, score, scan, and import agent skills from GitHub repositories that contain SKILL.md, CLAUDE.md, .cursorrules, and similar agent skill files. Discover community skills across 160+ provider categories, evaluate relevance with heuristic scoring, check for malware or hardcoded secrets, and install into Hermes, Claude Code, Gemini CLI, or OpenCode agent directories.",
"Search, score, scan, and import agent skills from GitHub repositories that contain SKILL.md, CLAUDE.md, .cursorrules, and similar agent skill files. Discover community skills across many tool and provider categories, evaluate relevance with heuristic scoring, check for malware or hardcoded secrets, and install into Hermes, Claude Code, Gemini CLI, or OpenCode agent directories.",
category: "api",
area: "github-skills",
icon: "explore",

View File

@@ -34,6 +34,8 @@ export const PROVIDER_ENDPOINTS = {
"chat-oripe": "https://api.oriper.com/v1/chat/completions",
freeinference: "https://freeinference.org/v1/chat/completions",
"free-ai": "https://api.free.ai/v1/chat/",
"void-ai": "https://api.voidai.app/v1/chat/completions",
helixmind: "https://helixmind.online/v1/chat/completions",
glm: "https://api.z.ai/api/anthropic/v1/messages",
glmt: "https://api.z.ai/api/anthropic/v1/messages",
"bailian-coding-plan": "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1/messages",

View File

@@ -120,6 +120,8 @@ export const AGGREGATOR_PROVIDER_IDS = new Set([
"chat-oripe",
"freeinference",
"free-ai",
"void-ai",
"helixmind",
]);;

View File

@@ -63,7 +63,7 @@ export const APIKEY_PROVIDERS_FRONTIER = {
website: "https://aistudio.google.com",
hasFree: true,
freeNote:
"Free forever: 1,500 req/day for Gemini 2.5 Flash — no credit card, get key at aistudio.google.com",
"Free tier available through Google AI Studio; current per-model quotas and regional limits apply",
},
groq: {
id: "groq",
@@ -85,7 +85,8 @@ export const APIKEY_PROVIDERS_FRONTIER = {
textIcon: "BB",
website: "https://blackbox.ai",
hasFree: true,
freeNote: "Free tier: unlimited basic chat plus Minimax-M2.5, no credit card required",
freeNote:
"Limited free access is available through Blackbox; model availability and account limits apply",
},
xai: {
id: "xai",

View File

@@ -1215,4 +1215,34 @@ export const APIKEY_PROVIDERS_GATEWAYS = {
authHint:
"Get API key at naga.ac — Google/GitHub/Discord signup available.",
},
"void-ai": {
id: "void-ai",
alias: "void-ai",
name: "Void AI",
icon: "science",
color: "#111827",
textIcon: "VA",
passthroughModels: true,
website: "https://voidai.app",
hasFree: true,
freeNote:
"The public model catalog marks some models with a free plan requirement, but access is conditional and no numeric quota is confirmed.",
apiHint:
"Use https://api.voidai.app/v1 only after confirming authentication, account eligibility and terms. Treat this integration as experimental until the blocked documentation becomes public.",
},
helixmind: {
id: "helixmind",
alias: "helixmind",
name: "HelixMind",
icon: "hub",
color: "#4F46E5",
textIcon: "HM",
passthroughModels: true,
website: "https://helixmind.online",
hasFree: false,
freeNote:
"Previously circulated 3 RPM/50 RPD and no-card claims were not confirmed during the 2026-08-02 audit; current quota and billing require account verification.",
apiHint:
"Create a helix- key and use https://helixmind.online/v1. OpenAI requests use Bearer authentication; the Anthropic-compatible messages endpoint accepts x-api-key.",
},
};

View File

@@ -127,7 +127,8 @@ export const APIKEY_PROVIDERS_INFERENCE = {
textIcon: "SF",
website: "https://cloud.siliconflow.com",
hasFree: true,
freeNote: "$1 free credits plus permanently free models after identity verification",
freeNote:
"$1 free credits plus currently listed $0 models after identity verification; availability and limits may change",
},
hyperbolic: {
id: "hyperbolic",