mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
docs(skills): publish 10 SKILL.md manifests for external AI agents
Adds /skills/omniroute*/SKILL.md following the Anthropic skill manifest spec (frontmatter name/description + self-contained body): chat, image, tts, stt, embeddings, web-search, web-fetch, mcp, a2a + entry point. External agents (Claude Desktop, ChatGPT, Cursor, Cline) can fetch one raw GitHub URL to learn how to call OmniRoute — zero-friction onboarding. OmniRoute-specific differentiators (mcp + a2a skills) extend the 9router pattern with 2 extra manifests not present in the reference. Adds structural lint test (tests/unit/docs/skillManifestsLint.test.ts) enforcing frontmatter, env-var references, and trigger-phrase quality. Adds "AI Agent Skills" section to README.md root. Ref: 9router/skills/ pattern (adapted).
This commit is contained in:
13
README.md
13
README.md
@@ -460,6 +460,19 @@ Alibaba · Amazon Q · AssemblyAI · Baidu Qianfan · Baseten · Black Forest La
|
||||
|
||||
---
|
||||
|
||||
## 🤖 AI Agent Skills
|
||||
|
||||
Drop-in markdown manifests that let any AI agent consume OmniRoute via one fetch.
|
||||
|
||||
Tell your agent (Claude Desktop, ChatGPT, Cursor, Cline, etc.):
|
||||
|
||||
> "Fetch this URL and use OmniRoute according to its instructions:
|
||||
> `https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md`"
|
||||
|
||||
10 skills available — see [skills/README.md](./skills/README.md).
|
||||
|
||||
---
|
||||
|
||||
## 🔄 How It Works
|
||||
|
||||
```
|
||||
|
||||
42
skills/README.md
Normal file
42
skills/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# OmniRoute AI Agent Skills
|
||||
|
||||
Drop-in skills that let any AI agent (Claude Desktop, ChatGPT, Cursor, Cline, Continue, etc.)
|
||||
consume OmniRoute via OpenAI-compatible REST in one fetch.
|
||||
|
||||
## How agents use these
|
||||
|
||||
```
|
||||
User to agent: "Use OmniRoute for code-gen. Fetch this URL and follow it:
|
||||
https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md"
|
||||
```
|
||||
|
||||
The agent retrieves the manifest, sees the setup + endpoints, and routes calls
|
||||
through `$OMNIROUTE_URL/v1/...` with `Authorization: Bearer $OMNIROUTE_KEY`.
|
||||
|
||||
## Skills index
|
||||
|
||||
| Capability | Manifest |
|
||||
| ------------------------ | -------------------------------------------------------------- |
|
||||
| Entry point + setup | [omniroute/SKILL.md](omniroute/SKILL.md) |
|
||||
| Chat / code-gen | [omniroute-chat/SKILL.md](omniroute-chat/SKILL.md) |
|
||||
| Image generation | [omniroute-image/SKILL.md](omniroute-image/SKILL.md) |
|
||||
| Text-to-speech | [omniroute-tts/SKILL.md](omniroute-tts/SKILL.md) |
|
||||
| Speech-to-text | [omniroute-stt/SKILL.md](omniroute-stt/SKILL.md) |
|
||||
| Embeddings | [omniroute-embeddings/SKILL.md](omniroute-embeddings/SKILL.md) |
|
||||
| Web search | [omniroute-web-search/SKILL.md](omniroute-web-search/SKILL.md) |
|
||||
| Web fetch (URL→markdown) | [omniroute-web-fetch/SKILL.md](omniroute-web-fetch/SKILL.md) |
|
||||
| MCP server | [omniroute-mcp/SKILL.md](omniroute-mcp/SKILL.md) |
|
||||
| A2A protocol | [omniroute-a2a/SKILL.md](omniroute-a2a/SKILL.md) |
|
||||
|
||||
## Format
|
||||
|
||||
Each `SKILL.md` follows the Anthropic skill manifest spec with YAML frontmatter
|
||||
(`name`, `description`) and a self-contained markdown body: setup, endpoints,
|
||||
examples, and error codes. Assume the reader is an agent with no prior context.
|
||||
|
||||
## Differences from 9router skills
|
||||
|
||||
OmniRoute extends the 9router pattern with two additional skills:
|
||||
|
||||
- `omniroute-mcp` — exposes 37 MCP tools (memory, skills, providers, routing) over SSE/stdio/HTTP
|
||||
- `omniroute-a2a` — exposes 5 A2A skills (smart-routing, quota, discovery, cost, health)
|
||||
71
skills/omniroute-a2a/SKILL.md
Normal file
71
skills/omniroute-a2a/SKILL.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
name: omniroute-a2a
|
||||
description: OmniRoute exposes an A2A (Agent-to-Agent) JSON-RPC 2.0 server with 5 skills (smart-routing, quota-management, provider-discovery, cost-analysis, health-report). Use when the user wants OmniRoute to act as an agent peer in an A2A network or multi-agent pipeline.
|
||||
---
|
||||
|
||||
# OmniRoute — A2A Protocol
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
OmniRoute publishes an Agent Card at `/.well-known/agent.json` and accepts
|
||||
JSON-RPC 2.0 calls at `/a2a`.
|
||||
|
||||
## Discovery
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/.well-known/agent.json
|
||||
```
|
||||
|
||||
Returns Agent Card with skills, endpoints, auth scheme.
|
||||
|
||||
## Available skills
|
||||
|
||||
| Skill | Purpose |
|
||||
| -------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `smart-routing` | Given a prompt, recommends best provider/model combo |
|
||||
| `quota-management` | Reports quota balance for given provider/account |
|
||||
| `provider-discovery` | Lists providers matching capability filters (vision, JSON mode, tools, max-context) |
|
||||
| `cost-analysis` | Estimates cost for a given request shape |
|
||||
| `health-report` | Returns system health (circuit states, latencies, errors) |
|
||||
|
||||
## Call example (JSON-RPC 2.0)
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/a2a \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "tasks/send",
|
||||
"params": {
|
||||
"skillId": "smart-routing",
|
||||
"input": { "prompt_length": 4000, "tools": true, "vision": false }
|
||||
},
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
|
||||
## Response shape
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"result": {
|
||||
"taskId": "...",
|
||||
"status": "completed",
|
||||
"output": { "recommended_combo": "...", "reasoning": "..." }
|
||||
},
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
- `-32600` → invalid request (bad JSON-RPC envelope)
|
||||
- `-32601` → method not found (check `method` field)
|
||||
- `-32602` → invalid params (check `skillId` against Agent Card)
|
||||
- `401` → missing/invalid `OMNIROUTE_KEY`
|
||||
|
||||
## Reference
|
||||
|
||||
Full docs: https://github.com/NomenAK/OmniRoute/blob/main/docs/frameworks/A2A-SERVER.md
|
||||
68
skills/omniroute-chat/SKILL.md
Normal file
68
skills/omniroute-chat/SKILL.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: omniroute-chat
|
||||
description: Chat / code generation via OmniRoute using OpenAI /v1/chat/completions or Anthropic /v1/messages format with SSE streaming, auto-fallback combos, RTK token saver, and 207+ providers. Use when the user wants to ask an LLM, generate code, summarize text, or run prompts through OmniRoute.
|
||||
---
|
||||
|
||||
# OmniRoute — Chat
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `POST $OMNIROUTE_URL/v1/chat/completions` — OpenAI format
|
||||
- `POST $OMNIROUTE_URL/v1/messages` — Anthropic Messages format
|
||||
- `POST $OMNIROUTE_URL/v1/responses` — OpenAI Responses API
|
||||
|
||||
## Discover
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models | jq '.data[].id'
|
||||
```
|
||||
|
||||
Combos (e.g. `auto`, `cost-optimized`, `subscription`) auto-fallback through multiple providers.
|
||||
|
||||
## OpenAI format example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/chat/completions \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "claude-opus-4-7",
|
||||
"messages": [{"role": "user", "content": "Refactor this function"}],
|
||||
"stream": true
|
||||
}'
|
||||
```
|
||||
|
||||
## Anthropic format example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/messages \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "anthropic-version: 2023-06-01" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "claude-opus-4-7",
|
||||
"max_tokens": 4096,
|
||||
"messages": [{"role": "user", "content": "Hi"}]
|
||||
}'
|
||||
```
|
||||
|
||||
## Tool use
|
||||
|
||||
Supports OpenAI `tools` array and Anthropic `tools` block. Tool results
|
||||
auto-compressed via RTK (47 filters: git-diff, grep, test-jest, terraform-plan,
|
||||
docker-logs, etc.) — 20-40% token savings. Disable per-request with
|
||||
`X-Omniroute-Rtk: off` header.
|
||||
|
||||
## Reasoning / thinking
|
||||
|
||||
Anthropic extended thinking and OpenAI Responses reasoning blocks are forwarded
|
||||
verbatim. Cached automatically via reasoning cache.
|
||||
|
||||
## Errors
|
||||
|
||||
- `401` → invalid API key
|
||||
- `400 invalid_model` → model not in registry; check `/v1/models`
|
||||
- `503 circuit_open` → provider circuit breaker tripped; retry later or use combo
|
||||
- `429 rate_limited` → honor `Retry-After`; consider using a combo for auto-fallback
|
||||
45
skills/omniroute-embeddings/SKILL.md
Normal file
45
skills/omniroute-embeddings/SKILL.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: omniroute-embeddings
|
||||
description: Embeddings via OmniRoute using OpenAI /v1/embeddings format with auto-fallback across text-embedding-3-large, Voyage, Cohere, Gemini embeddings, Jina. Use when the user needs vector embeddings for RAG, similarity search, or clustering.
|
||||
---
|
||||
|
||||
# OmniRoute — Embeddings
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Endpoint
|
||||
|
||||
- `POST $OMNIROUTE_URL/v1/embeddings`
|
||||
|
||||
## Discover
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models/embedding | jq '.data[]'
|
||||
```
|
||||
|
||||
Each entry: `{ id, owned_by, dimensions, max_input_tokens }`.
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/embeddings \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "text-embedding-3-large",
|
||||
"input": ["first text", "second text"],
|
||||
"encoding_format": "float"
|
||||
}'
|
||||
```
|
||||
|
||||
Response: `{ data:[{ embedding:[...], index }], usage:{ prompt_tokens, total_tokens } }`
|
||||
|
||||
## Batch input
|
||||
|
||||
`input` accepts a string or array of strings (up to provider batch limit, typically 2048 items).
|
||||
|
||||
## Errors
|
||||
|
||||
- `400 input_too_long` → input exceeds `max_input_tokens` for this model
|
||||
- `400 invalid_encoding_format` → use `float` or `base64`
|
||||
- `503` → provider unavailable; try another model in `/v1/models/embedding`
|
||||
45
skills/omniroute-image/SKILL.md
Normal file
45
skills/omniroute-image/SKILL.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: omniroute-image
|
||||
description: Image generation via OmniRoute using OpenAI /v1/images/generations format with auto-fallback across DALL-E, Stable Diffusion, Flux, Imagen providers. Use when the user wants to generate, edit, or vary images.
|
||||
---
|
||||
|
||||
# OmniRoute — Image Generation
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `POST $OMNIROUTE_URL/v1/images/generations` — Text-to-image
|
||||
- `POST $OMNIROUTE_URL/v1/images/edits` — Image edit (mask)
|
||||
- `POST $OMNIROUTE_URL/v1/images/variations` — Variations
|
||||
|
||||
## Discover
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models/image | jq '.data[]'
|
||||
```
|
||||
|
||||
Returns `{ id, owned_by, sizes:[...], capabilities:[...] }` per model.
|
||||
|
||||
## Generate example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/images/generations \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "dall-e-3",
|
||||
"prompt": "a red bicycle on a wet street, photoreal",
|
||||
"n": 1,
|
||||
"size": "1024x1024",
|
||||
"response_format": "b64_json"
|
||||
}'
|
||||
```
|
||||
|
||||
Response: `{ created, data: [{ url? or b64_json, revised_prompt }] }`
|
||||
|
||||
## Errors
|
||||
|
||||
- `400 invalid_size` → not supported by this model; check `/v1/models/image`
|
||||
- `400 content_policy_violation` → blocked by provider safety
|
||||
- `503` → provider unavailable; try another model in `/v1/models/image`
|
||||
71
skills/omniroute-mcp/SKILL.md
Normal file
71
skills/omniroute-mcp/SKILL.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
name: omniroute-mcp
|
||||
description: OmniRoute exposes a built-in MCP (Model Context Protocol) server with 37 tools (chat, embeddings, memory CRUD, skills, providers, routing, audit) over SSE/stdio/HTTP transports. Use when the user wants to add OmniRoute as an MCP server in Claude Desktop, Cursor, Cline, or any MCP-compatible client.
|
||||
---
|
||||
|
||||
# OmniRoute — MCP Server
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Transports
|
||||
|
||||
- **stdio** — local IPC, for Claude Desktop / VS Code extensions
|
||||
- **SSE** — `GET $OMNIROUTE_URL/api/mcp/sse`
|
||||
- **Streamable HTTP** — `POST $OMNIROUTE_URL/api/mcp/stream`
|
||||
|
||||
## Claude Desktop config
|
||||
|
||||
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"omniroute": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "omniroute", "--mcp"],
|
||||
"env": { "OMNIROUTE_KEY": "sk-..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Cursor / VS Code config
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp": {
|
||||
"servers": {
|
||||
"omniroute": {
|
||||
"url": "http://localhost:20128/api/mcp/sse",
|
||||
"headers": { "Authorization": "Bearer sk-..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Available tools (37 total)
|
||||
|
||||
| Scope | Tools |
|
||||
| --------- | -------------------------------------------------------------------------------------------------- |
|
||||
| health | `omniroute_get_health` |
|
||||
| combos | `omniroute_list_combos`, `omniroute_get_combo_metrics`, `omniroute_switch_combo` |
|
||||
| routing | `omniroute_simulate_route`, `omniroute_best_combo_for_task`, `omniroute_explain_route` |
|
||||
| providers | `omniroute_get_provider_metrics`, `omniroute_check_quota`, `omniroute_route_request` |
|
||||
| budget | `omniroute_set_budget_guard`, `omniroute_set_routing_strategy`, `omniroute_set_resilience_profile` |
|
||||
| testing | `omniroute_test_combo` |
|
||||
| memory | `memory_add`, `memory_search`, `memory_delete` |
|
||||
| skills | `skill_invoke`, `skill_list`, `skill_describe`, `skill_register` |
|
||||
| cache | `omniroute_cache_stats`, `omniroute_cache_flush` |
|
||||
| admin | `omniroute_db_health_check`, `omniroute_sync_pricing`, `omniroute_get_session_snapshot` |
|
||||
|
||||
Full list: `GET $OMNIROUTE_URL/api/mcp/tools`
|
||||
|
||||
## Scopes
|
||||
|
||||
Tools are grouped into 13 scopes (chat-only, memory-readonly, full-admin, etc.).
|
||||
Pass scope name as `--scope` arg or via `X-Omniroute-Scope` header.
|
||||
|
||||
## Reference
|
||||
|
||||
Full docs: https://github.com/NomenAK/OmniRoute/blob/main/docs/frameworks/MCP-SERVER.md
|
||||
42
skills/omniroute-stt/SKILL.md
Normal file
42
skills/omniroute-stt/SKILL.md
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: omniroute-stt
|
||||
description: Speech-to-text via OmniRoute using OpenAI /v1/audio/transcriptions format with auto-fallback across Whisper, AssemblyAI, Deepgram, Azure STT. Use when the user wants transcription of audio files or real-time speech recognition.
|
||||
---
|
||||
|
||||
# OmniRoute — Speech-to-Text
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `POST $OMNIROUTE_URL/v1/audio/transcriptions` — multipart upload, returns text
|
||||
- `POST $OMNIROUTE_URL/v1/audio/translations` — transcribe + translate to English
|
||||
|
||||
## Discover
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models/stt | jq '.data[]'
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/audio/transcriptions \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-F "file=@audio.mp3" \
|
||||
-F "model=whisper-1" \
|
||||
-F "response_format=verbose_json"
|
||||
```
|
||||
|
||||
Response: `{ text, language, duration, segments?:[{ start, end, text }] }`
|
||||
|
||||
## Supported formats
|
||||
|
||||
Audio: `mp3`, `mp4`, `mpeg`, `mpga`, `m4a`, `wav`, `webm`.
|
||||
Response formats: `json`, `text`, `srt`, `verbose_json`, `vtt`.
|
||||
|
||||
## Errors
|
||||
|
||||
- `400 invalid_file_format` → unsupported audio format
|
||||
- `400 file_too_large` → exceeds provider limit (usually 25MB)
|
||||
- `503` → provider unavailable; try another model in `/v1/models/stt`
|
||||
45
skills/omniroute-tts/SKILL.md
Normal file
45
skills/omniroute-tts/SKILL.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: omniroute-tts
|
||||
description: Text-to-speech via OmniRoute using OpenAI /v1/audio/speech format with auto-fallback across OpenAI TTS, ElevenLabs, Azure Neural, Google Cloud TTS. Use when the user wants spoken audio output from text.
|
||||
---
|
||||
|
||||
# OmniRoute — Text-to-Speech
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Endpoint
|
||||
|
||||
- `POST $OMNIROUTE_URL/v1/audio/speech` — returns binary audio (mp3/opus/wav/flac)
|
||||
|
||||
## Discover
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models/tts | jq '.data[]'
|
||||
```
|
||||
|
||||
Each entry includes `voices:[...]` for the available voice names per provider.
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/audio/speech \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "tts-1",
|
||||
"input": "Hello from OmniRoute.",
|
||||
"voice": "alloy",
|
||||
"response_format": "mp3"
|
||||
}' --output speech.mp3
|
||||
```
|
||||
|
||||
## Voices
|
||||
|
||||
Voice names vary by provider. Check `/v1/models/tts` — each entry has `voices:[...]`.
|
||||
Common OpenAI voices: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.
|
||||
|
||||
## Errors
|
||||
|
||||
- `400 invalid_voice` → voice not supported by this model
|
||||
- `400 input_too_long` → input exceeds model character limit
|
||||
- `503` → provider unavailable; try another model in `/v1/models/tts`
|
||||
47
skills/omniroute-web-fetch/SKILL.md
Normal file
47
skills/omniroute-web-fetch/SKILL.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
name: omniroute-web-fetch
|
||||
description: Fetch a URL and convert to clean markdown via OmniRoute proxying Jina Reader, Firecrawl, raw HTML strip. Use when the user wants to ingest a webpage as markdown for context in an LLM conversation.
|
||||
---
|
||||
|
||||
# OmniRoute — Web Fetch
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Endpoint
|
||||
|
||||
- `POST $OMNIROUTE_URL/v1/web/fetch`
|
||||
|
||||
## Discover
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models/web | jq '.data[] | select(.kind == "webFetch")'
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/web/fetch \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "jina/reader",
|
||||
"url": "https://anthropic.com",
|
||||
"format": "markdown"
|
||||
}'
|
||||
```
|
||||
|
||||
Response: `{ url, title, markdown, links?:[...], images?:[...] }`
|
||||
|
||||
## Parameters
|
||||
|
||||
| Field | Type | Description |
|
||||
| -------- | ------ | ----------------------------------------------------------------------- |
|
||||
| `model` | string | Provider from `/v1/models/web` (e.g. `jina/reader`, `firecrawl/scrape`) |
|
||||
| `url` | string | URL to fetch |
|
||||
| `format` | string | `markdown` (default), `html`, `text` |
|
||||
|
||||
## Errors
|
||||
|
||||
- `400 invalid_url` → URL must be http/https
|
||||
- `403 blocked` → provider blocked by target site; try a different model
|
||||
- `503` → provider unavailable; try another model in `/v1/models/web`
|
||||
49
skills/omniroute-web-search/SKILL.md
Normal file
49
skills/omniroute-web-search/SKILL.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
name: omniroute-web-search
|
||||
description: Web search via OmniRoute proxying Tavily, Brave Search, SerpAPI, Exa with auto-fallback. Use when the user wants live web search results, current news, or facts that may be beyond the LLM training cutoff.
|
||||
---
|
||||
|
||||
# OmniRoute — Web Search
|
||||
|
||||
Requires `OMNIROUTE_URL` and `OMNIROUTE_KEY`. See [entry-point SKILL](https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute/SKILL.md) for setup.
|
||||
|
||||
## Endpoint
|
||||
|
||||
- `POST $OMNIROUTE_URL/v1/web/search` — unified search format
|
||||
|
||||
## Discover
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models/web | jq '.data[] | select(.kind == "webSearch")'
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
curl -X POST $OMNIROUTE_URL/v1/web/search \
|
||||
-H "Authorization: Bearer $OMNIROUTE_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "tavily/search",
|
||||
"query": "OmniRoute github latest release",
|
||||
"max_results": 5,
|
||||
"include_answer": true
|
||||
}'
|
||||
```
|
||||
|
||||
Response: `{ answer?, results:[{ url, title, content, score }] }`
|
||||
|
||||
## Parameters
|
||||
|
||||
| Field | Type | Description |
|
||||
| ---------------- | ------- | ------------------------------------ |
|
||||
| `model` | string | Provider model from `/v1/models/web` |
|
||||
| `query` | string | Search query |
|
||||
| `max_results` | number | Max results (default: 5) |
|
||||
| `include_answer` | boolean | Include AI-synthesized answer |
|
||||
| `search_depth` | string | `basic` or `advanced` (Tavily) |
|
||||
|
||||
## Errors
|
||||
|
||||
- `400 query_too_long` → shorten the search query
|
||||
- `503` → provider unavailable; try another model in `/v1/models/web`
|
||||
63
skills/omniroute/SKILL.md
Normal file
63
skills/omniroute/SKILL.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
name: omniroute
|
||||
description: Entry point for OmniRoute — local/remote AI gateway with OpenAI-compatible REST for chat, image, TTS, STT, embeddings, web search, web fetch, MCP, A2A. Use when the user mentions OmniRoute, OMNIROUTE_URL, or wants AI without writing provider boilerplate. This skill covers setup + indexes capability skills; fetch the relevant capability SKILL.md from the URLs below when needed.
|
||||
---
|
||||
|
||||
# OmniRoute
|
||||
|
||||
Local/remote AI gateway exposing OpenAI-compatible REST. One key, 207+ providers,
|
||||
auto-fallback, RTK token saver, MCP server, A2A agents.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
export OMNIROUTE_URL="http://localhost:20128" # or VPS / tunnel URL
|
||||
export OMNIROUTE_KEY="sk-..." # from Dashboard → API Keys
|
||||
```
|
||||
|
||||
All requests: `${OMNIROUTE_URL}/v1/...` with `Authorization: Bearer ${OMNIROUTE_KEY}`.
|
||||
|
||||
Verify: `curl $OMNIROUTE_URL/api/health` → `{"ok":true}`
|
||||
|
||||
## Discover models
|
||||
|
||||
```bash
|
||||
curl $OMNIROUTE_URL/v1/models # chat/LLM (default)
|
||||
curl $OMNIROUTE_URL/v1/models/image # image-gen
|
||||
curl $OMNIROUTE_URL/v1/models/tts # text-to-speech
|
||||
curl $OMNIROUTE_URL/v1/models/embedding # embeddings
|
||||
curl $OMNIROUTE_URL/v1/models/web # web search + fetch
|
||||
curl $OMNIROUTE_URL/v1/models/stt # speech-to-text
|
||||
```
|
||||
|
||||
Use `data[].id` as `model` field in requests. Combos appear with `owned_by:"combo"`.
|
||||
|
||||
## Capability skills
|
||||
|
||||
| Capability | Raw URL |
|
||||
| ---------------- | --------------------------------------------------------------------------------------------- |
|
||||
| Chat / code-gen | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-chat/SKILL.md |
|
||||
| Image generation | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-image/SKILL.md |
|
||||
| Text-to-speech | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-tts/SKILL.md |
|
||||
| Speech-to-text | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-stt/SKILL.md |
|
||||
| Embeddings | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-embeddings/SKILL.md |
|
||||
| Web search | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-web-search/SKILL.md |
|
||||
| Web fetch | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-web-fetch/SKILL.md |
|
||||
| MCP server | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-mcp/SKILL.md |
|
||||
| A2A protocol | https://raw.githubusercontent.com/NomenAK/OmniRoute/main/skills/omniroute-a2a/SKILL.md |
|
||||
|
||||
## Errors
|
||||
|
||||
- `401` → set/refresh `OMNIROUTE_KEY` (Dashboard → API Keys)
|
||||
- `400 Invalid model format` → check `model` exists in `/v1/models/<kind>`
|
||||
- `503 Provider circuit open` → upstream provider down; retry after `Retry-After` seconds
|
||||
- `429` → rate limited; honor `Retry-After`
|
||||
|
||||
## Differentiators vs OpenAI direct
|
||||
|
||||
- **Auto-fallback** combos (14 strategies): never stop coding even if a provider rate-limits
|
||||
- **RTK token saver**: tool_result compressed via 47 specialized filters (git-diff, test-jest, terraform-plan, docker-logs…) — 20-40% token reduction
|
||||
- **Caveman mode**: optional terse system prompt injection (LITE/FULL/ULTRA) — 15-25% completion reduction
|
||||
- **MCP + A2A** servers built-in (this is the only AI router that exposes both protocols)
|
||||
- **Memory** with FTS5 + Qdrant for persistent agent context
|
||||
- **Guardrails** for PII masking, prompt injection detection, vision policies
|
||||
43
tests/unit/docs/skillManifestsLint.test.ts
Normal file
43
tests/unit/docs/skillManifestsLint.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { readdir, readFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
|
||||
const SKILLS_DIR = join(process.cwd(), "skills");
|
||||
const REQUIRED_FRONTMATTER = ["name:", "description:"];
|
||||
|
||||
async function listSkillDirs(): Promise<string[]> {
|
||||
const entries = await readdir(SKILLS_DIR, { withFileTypes: true });
|
||||
return entries
|
||||
.filter((e) => e.isDirectory() && e.name.startsWith("omniroute"))
|
||||
.map((e) => e.name);
|
||||
}
|
||||
|
||||
test("each skill dir has SKILL.md with frontmatter", async () => {
|
||||
const dirs = await listSkillDirs();
|
||||
assert.ok(dirs.length >= 9, `Expected ≥9 skill dirs, got ${dirs.length}`);
|
||||
for (const dir of dirs) {
|
||||
const path = join(SKILLS_DIR, dir, "SKILL.md");
|
||||
const content = await readFile(path, "utf-8");
|
||||
assert.ok(content.startsWith("---\n"), `${dir}: missing opening frontmatter`);
|
||||
for (const key of REQUIRED_FRONTMATTER) {
|
||||
assert.ok(content.includes(key), `${dir}: missing frontmatter key ${key}`);
|
||||
}
|
||||
assert.ok(
|
||||
content.includes("$OMNIROUTE_URL") || content.includes("OMNIROUTE_KEY"),
|
||||
`${dir}: missing env-var references`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("description field is meaningful (≥50 chars, has 'Use when')", async () => {
|
||||
const dirs = await listSkillDirs();
|
||||
for (const dir of dirs) {
|
||||
const content = await readFile(join(SKILLS_DIR, dir, "SKILL.md"), "utf-8");
|
||||
const match = content.match(/^description:\s*(.+?)$/m);
|
||||
assert.ok(match, `${dir}: no description field`);
|
||||
const desc = match![1];
|
||||
assert.ok(desc.length >= 50, `${dir}: description too short (${desc.length})`);
|
||||
assert.ok(/use when/i.test(desc), `${dir}: description missing "Use when" trigger phrase`);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user