mirror of
https://github.com/decolua/9router.git
synced 2026-05-08 12:01:28 +00:00
Feat : Skills
This commit is contained in:
71
skills/9router-chat/SKILL.md
Normal file
71
skills/9router-chat/SKILL.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
name: 9router-chat
|
||||
description: Chat / code generation via 9Router using OpenAI /v1/chat/completions or Anthropic /v1/messages format with streaming + auto-fallback combos. Use when the user wants to ask an LLM, generate code, summarize text, or run prompts through 9Router.
|
||||
---
|
||||
|
||||
# 9Router — Chat
|
||||
|
||||
Requires `NINEROUTER_URL` (and `NINEROUTER_KEY` if auth enabled). See https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md for setup.
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `POST $NINEROUTER_URL/v1/chat/completions` — OpenAI format
|
||||
- `POST $NINEROUTER_URL/v1/messages` — Anthropic format
|
||||
|
||||
## Discover models
|
||||
|
||||
```bash
|
||||
curl $NINEROUTER_URL/v1/models | jq '.data[].id'
|
||||
```
|
||||
|
||||
Combos (e.g. `vip`, `mycodex`) auto-fallback through multiple providers.
|
||||
|
||||
## OpenAI format
|
||||
|
||||
```bash
|
||||
curl -X POST $NINEROUTER_URL/v1/chat/completions \
|
||||
-H "Authorization: Bearer $NINEROUTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"openai/gpt-5","messages":[{"role":"user","content":"Hi"}],"stream":false}'
|
||||
```
|
||||
|
||||
JS (OpenAI SDK):
|
||||
|
||||
```js
|
||||
import OpenAI from "openai";
|
||||
const client = new OpenAI({ baseURL: `${process.env.NINEROUTER_URL}/v1`, apiKey: process.env.NINEROUTER_KEY });
|
||||
const res = await client.chat.completions.create({
|
||||
model: "openai/gpt-5",
|
||||
messages: [{ role: "user", content: "Hi" }],
|
||||
stream: true,
|
||||
});
|
||||
for await (const chunk of res) process.stdout.write(chunk.choices[0]?.delta?.content || "");
|
||||
```
|
||||
|
||||
## Anthropic format
|
||||
|
||||
```bash
|
||||
curl -X POST $NINEROUTER_URL/v1/messages \
|
||||
-H "Authorization: Bearer $NINEROUTER_KEY" \
|
||||
-H "anthropic-version: 2023-06-01" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"cc/claude-opus-4-7","max_tokens":1024,"messages":[{"role":"user","content":"Hi"}]}'
|
||||
```
|
||||
|
||||
## Response shape
|
||||
|
||||
OpenAI (`/v1/chat/completions`):
|
||||
```json
|
||||
{ "id": "chatcmpl-...", "object": "chat.completion", "model": "openai/gpt-5",
|
||||
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "Hello!" }, "finish_reason": "stop" }],
|
||||
"usage": { "prompt_tokens": 8, "completion_tokens": 2, "total_tokens": 10 } }
|
||||
```
|
||||
|
||||
Streaming (`stream:true`) emits SSE: `data: {choices:[{delta:{content:"..."}}]}\n\n` ... `data: [DONE]\n\n`.
|
||||
|
||||
Anthropic (`/v1/messages`):
|
||||
```json
|
||||
{ "id": "msg_...", "type": "message", "role": "assistant", "model": "cc/claude-opus-4-7",
|
||||
"content": [{ "type": "text", "text": "Hello!" }],
|
||||
"stop_reason": "end_turn", "usage": { "input_tokens": 8, "output_tokens": 2 } }
|
||||
```
|
||||
67
skills/9router-embeddings/SKILL.md
Normal file
67
skills/9router-embeddings/SKILL.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
name: 9router-embeddings
|
||||
description: Generate vector embeddings via 9Router /v1/embeddings using OpenAI / Gemini / Mistral / Voyage / Nvidia / GitHub embedding models for RAG, semantic search, similarity. Use when the user wants embeddings, vectors, RAG, semantic search, or to embed text.
|
||||
---
|
||||
|
||||
# 9Router — Embeddings
|
||||
|
||||
Requires `NINEROUTER_URL` (and `NINEROUTER_KEY` if auth enabled). See https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md for setup.
|
||||
|
||||
## Discover models
|
||||
|
||||
```bash
|
||||
curl $NINEROUTER_URL/v1/models/embedding | jq '.data[].id'
|
||||
```
|
||||
|
||||
## Endpoint
|
||||
|
||||
`POST $NINEROUTER_URL/v1/embeddings`
|
||||
|
||||
| Field | Required | Notes |
|
||||
|---|---|---|
|
||||
| `model` | yes | from `/v1/models/embedding` |
|
||||
| `input` | yes | string OR array of strings |
|
||||
| `encoding_format` | no | `float` (default) / `base64` |
|
||||
| `dimensions` | no | OpenAI v3 only |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
curl -X POST $NINEROUTER_URL/v1/embeddings \
|
||||
-H "Authorization: Bearer $NINEROUTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"openai/text-embedding-3-small","input":["hello","world"]}'
|
||||
```
|
||||
|
||||
JS:
|
||||
|
||||
```js
|
||||
const r = await fetch(`${process.env.NINEROUTER_URL}/v1/embeddings`, {
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${process.env.NINEROUTER_KEY}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ model: "gemini/text-embedding-004", input: "RAG chunk text" }),
|
||||
});
|
||||
const { data } = await r.json();
|
||||
console.log(data[0].embedding.length); // dimension
|
||||
```
|
||||
|
||||
## Response shape
|
||||
|
||||
```json
|
||||
{ "object": "list", "model": "openai/text-embedding-3-small",
|
||||
"data": [
|
||||
{ "object": "embedding", "index": 0, "embedding": [0.0123, -0.045, ...] },
|
||||
{ "object": "embedding", "index": 1, "embedding": [...] }
|
||||
],
|
||||
"usage": { "prompt_tokens": 5, "total_tokens": 5 } }
|
||||
```
|
||||
|
||||
## Provider quirks
|
||||
|
||||
| Provider | Notes |
|
||||
|---|---|
|
||||
| `openai`, `openrouter`, `mistral`, `voyage-ai`, `fireworks`, `together`, `nebius`, `github`, `nvidia`, `jina-ai` | Native OpenAI shape — `dimensions` works only on OpenAI v3 (`text-embedding-3-*`) |
|
||||
| `gemini`, `google_ai_studio` | Server auto-converts to `embedContent`/`batchEmbedContents` — send OpenAI shape |
|
||||
| `openai-compatible-*`, `custom-embedding-*` | Custom `baseUrl` from credentials |
|
||||
|
||||
Batch (`input` as array) is faster; some providers cap batch size.
|
||||
84
skills/9router-image/SKILL.md
Normal file
84
skills/9router-image/SKILL.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
name: 9router-image
|
||||
description: Generate images via 9Router /v1/images/generations using OpenAI / Gemini Imagen / DALL-E / FLUX / MiniMax / SDWebUI / ComfyUI / Codex models. Use when the user wants to create, generate, draw, or render an image, picture, or text-to-image (txt2img).
|
||||
---
|
||||
|
||||
# 9Router — Image Generation
|
||||
|
||||
Requires `NINEROUTER_URL` (and `NINEROUTER_KEY` if auth enabled). See https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md for setup.
|
||||
|
||||
## Discover models
|
||||
|
||||
```bash
|
||||
curl $NINEROUTER_URL/v1/models/image | jq '.data[].id'
|
||||
```
|
||||
|
||||
## Endpoint
|
||||
|
||||
`POST $NINEROUTER_URL/v1/images/generations`
|
||||
|
||||
| Field | Required | Notes |
|
||||
|---|---|---|
|
||||
| `model` | yes | from `/v1/models/image` |
|
||||
| `prompt` | yes | image description |
|
||||
| `n` | no | count (provider-dependent) |
|
||||
| `size` | no | `1024x1024`, `1792x1024`, ... |
|
||||
| `quality` | no | `standard` / `hd` (OpenAI) |
|
||||
| `response_format` | no | `url` (default) or `b64_json` |
|
||||
|
||||
Add query `?response_format=binary` to receive raw image bytes (handy for saving file).
|
||||
|
||||
## Examples
|
||||
|
||||
Save to file (binary):
|
||||
|
||||
```bash
|
||||
curl -X POST "$NINEROUTER_URL/v1/images/generations?response_format=binary" \
|
||||
-H "Authorization: Bearer $NINEROUTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"gemini/gemini-3-pro-image-preview","prompt":"watercolor mountains at sunrise","size":"1024x1024"}' \
|
||||
--output out.png
|
||||
```
|
||||
|
||||
JS (URL response):
|
||||
|
||||
```js
|
||||
const r = await fetch(`${process.env.NINEROUTER_URL}/v1/images/generations`, {
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${process.env.NINEROUTER_KEY}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ model: "gemini/gemini-3-pro-image-preview", prompt: "neon city", size: "1024x1024" }),
|
||||
});
|
||||
const { data } = await r.json();
|
||||
console.log(data[0].url || data[0].b64_json.slice(0, 40));
|
||||
```
|
||||
|
||||
## Response shape
|
||||
|
||||
JSON (default `response_format=url`):
|
||||
```json
|
||||
{ "created": 1735000000, "data": [{ "url": "https://..." }] }
|
||||
```
|
||||
|
||||
`response_format=b64_json`:
|
||||
```json
|
||||
{ "created": 1735000000, "data": [{ "b64_json": "iVBORw0KGgo..." }] }
|
||||
```
|
||||
|
||||
Query `?response_format=binary` returns raw image bytes (Content-Type `image/png` or `image/jpeg`).
|
||||
|
||||
## Provider quirks
|
||||
|
||||
Common fields above work everywhere. These add/override:
|
||||
|
||||
| Provider | Extra/changed fields | Notes |
|
||||
|---|---|---|
|
||||
| `openai`, `minimax`, `openrouter`, `recraft` | `quality`, `style`, `response_format` | Standard OpenAI shape |
|
||||
| `gemini` (nano-banana) | — | Only `prompt`; ignores `size`/`n` |
|
||||
| `codex` (gpt-5.4-image) | `image`, `images[]`, `image_detail`, `output_format`, `background` | SSE stream; **ChatGPT Plus/Pro required** |
|
||||
| `huggingface` | — | Only `prompt`; returns single image |
|
||||
| `nanobanana` | `image`, `images[]` (edit mode) | `size` → aspect ratio; async polling |
|
||||
| `fal-ai` | `image` (img2img) | `n` → `num_images`; `size` → ratio; async |
|
||||
| `stability-ai` | `style` (preset), `output_format` | `size` → `aspect_ratio` |
|
||||
| `black-forest-labs` (FLUX) | `image` (ref) | `size` → exact `width`/`height`; async |
|
||||
| `runwayml` | `image` (ref) | `size` → ratio; async; video models exist |
|
||||
| `sdwebui`, `comfyui` | — | Localhost noAuth (`:7860` / `:8188`) |
|
||||
75
skills/9router-tts/SKILL.md
Normal file
75
skills/9router-tts/SKILL.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: 9router-tts
|
||||
description: Text-to-speech via 9Router /v1/audio/speech using OpenAI / ElevenLabs / Deepgram / Edge TTS / Google TTS / Hyperbolic / Inworld voices. Use when the user wants to convert text to speech, generate audio, voiceover, narrate, or read text aloud.
|
||||
---
|
||||
|
||||
# 9Router — Text-to-Speech
|
||||
|
||||
Requires `NINEROUTER_URL` (and `NINEROUTER_KEY` if auth enabled). See https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md for setup.
|
||||
|
||||
## Discover voices
|
||||
|
||||
```bash
|
||||
curl $NINEROUTER_URL/v1/models/tts | jq '.data[].id'
|
||||
```
|
||||
|
||||
`model` = voice ID (e.g. `openai/tts-1`, `el/eleven_multilingual_v2`, `edge-tts/en-US-AriaNeural`).
|
||||
|
||||
## Endpoint
|
||||
|
||||
`POST $NINEROUTER_URL/v1/audio/speech`
|
||||
|
||||
| Field | Required | Notes |
|
||||
|---|---|---|
|
||||
| `model` | yes | voice ID from `/v1/models/tts` |
|
||||
| `input` | yes | text to speak |
|
||||
|
||||
Query `?response_format=mp3` (default, raw bytes) or `?response_format=json` (`{audio: base64, format}`).
|
||||
|
||||
## Examples
|
||||
|
||||
Save MP3:
|
||||
|
||||
```bash
|
||||
curl -X POST "$NINEROUTER_URL/v1/audio/speech" \
|
||||
-H "Authorization: Bearer $NINEROUTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"openai/tts-1","input":"Hello world"}' \
|
||||
--output speech.mp3
|
||||
```
|
||||
|
||||
JS (save file):
|
||||
|
||||
```js
|
||||
import { writeFile } from "node:fs/promises";
|
||||
const r = await fetch(`${process.env.NINEROUTER_URL}/v1/audio/speech`, {
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${process.env.NINEROUTER_KEY}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ model: "el/eleven_multilingual_v2", input: "Xin chào" }),
|
||||
});
|
||||
await writeFile("speech.mp3", Buffer.from(await r.arrayBuffer()));
|
||||
```
|
||||
|
||||
## Response shape
|
||||
|
||||
Default → raw audio bytes (Content-Type `audio/mp3`).
|
||||
|
||||
`?response_format=json`:
|
||||
```json
|
||||
{ "audio": "SUQzBAAAA...", "format": "mp3" }
|
||||
```
|
||||
|
||||
## Provider quirks (model format)
|
||||
|
||||
| Provider | `model` format | Notes |
|
||||
|---|---|---|
|
||||
| `openai` | `tts-1/alloy` (model/voice) or just voice | Default model `gpt-4o-mini-tts` |
|
||||
| `elevenlabs` | `<model_id>/<voice_id>` or `<voice_id>` | Default model `eleven_flash_v2_5`; list voices in Dashboard |
|
||||
| `openrouter` | `openai/gpt-4o-mini-tts/alloy` | Streamed via chat-completions audio modality |
|
||||
| `edge-tts` | voice id e.g. `vi-VN-HoaiMyNeural` | **noAuth**; default `vi-VN-HoaiMyNeural` |
|
||||
| `google-tts` | language code e.g. `en`, `vi` | **noAuth** |
|
||||
| `local-device` | OS voice name (`say -v ?` / SAPI) | **noAuth**; needs `ffmpeg` |
|
||||
| `deepgram` | `aura-asteria-en` etc | Token auth |
|
||||
| `nvidia`, `inworld`, `cartesia`, `playht` | `model/voice` | Provider-specific auth header |
|
||||
| `coqui`, `tortoise` | speaker / voice id | Localhost noAuth |
|
||||
| `hyperbolic` | model id | Body = `{text}` only |
|
||||
71
skills/9router-web-fetch/SKILL.md
Normal file
71
skills/9router-web-fetch/SKILL.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
name: 9router-web-fetch
|
||||
description: Fetch URL → markdown / text / HTML via 9Router /v1/web/fetch using Firecrawl / Jina Reader / Tavily Extract / Exa Contents. Use when the user wants to scrape a webpage, extract URL content, read article, or convert a URL to markdown.
|
||||
---
|
||||
|
||||
# 9Router — Web Fetch
|
||||
|
||||
Requires `NINEROUTER_URL` (and `NINEROUTER_KEY` if auth enabled). See https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md for setup.
|
||||
|
||||
## Discover providers
|
||||
|
||||
```bash
|
||||
curl $NINEROUTER_URL/v1/models/web | jq '.data[] | select(.kind=="webFetch") | .id'
|
||||
```
|
||||
|
||||
IDs end in `/fetch` (e.g. `firecrawl/fetch`, `jina/fetch`). `fetch-combo` chains providers with auto-fallback.
|
||||
|
||||
## Endpoint
|
||||
|
||||
`POST $NINEROUTER_URL/v1/web/fetch`
|
||||
|
||||
| Field | Required | Notes |
|
||||
|---|---|---|
|
||||
| `model` (or `provider`) | yes | from `/v1/models/web` (`firecrawl/fetch` or `firecrawl`) |
|
||||
| `url` | yes | URL to extract |
|
||||
| `format` | no | `markdown` (default) / `text` / `html` |
|
||||
| `max_characters` | no | truncate output |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
curl -X POST $NINEROUTER_URL/v1/web/fetch \
|
||||
-H "Authorization: Bearer $NINEROUTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"jina/fetch","url":"https://9router.com","format":"markdown"}'
|
||||
```
|
||||
|
||||
JS:
|
||||
|
||||
```js
|
||||
const r = await fetch(`${process.env.NINEROUTER_URL}/v1/web/fetch`, {
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${process.env.NINEROUTER_KEY}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ model: "fetch-combo", url: "https://example.com", format: "markdown", max_characters: 5000 }),
|
||||
});
|
||||
const { data } = await r.json();
|
||||
console.log(data.title, data.content.length);
|
||||
```
|
||||
|
||||
## Response shape
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "jina-reader",
|
||||
"url": "...",
|
||||
"title": "...",
|
||||
"content": { "format": "markdown", "text": "...", "length": 1234 },
|
||||
"metadata": { "author": null, "published_at": null, "language": null },
|
||||
"usage": { "fetch_cost_usd": 0 },
|
||||
"metrics": { "response_time_ms": 850, "upstream_latency_ms": 700 }
|
||||
}
|
||||
```
|
||||
|
||||
## Provider quirks
|
||||
|
||||
| Provider | Auth | Best for |
|
||||
|---|---|---|
|
||||
| `firecrawl` | Bearer | JS-rendered pages, `format=markdown/html` |
|
||||
| `jina-reader` | Bearer (optional) | Free tier (~1M chars/mo); fastest plain markdown |
|
||||
| `tavily` | Bearer | Bulk extract; returns `raw_content` |
|
||||
| `exa` | `x-api-key` | Pre-indexed pages; fast text extraction |
|
||||
89
skills/9router-web-search/SKILL.md
Normal file
89
skills/9router-web-search/SKILL.md
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
name: 9router-web-search
|
||||
description: Web search via 9Router /v1/search using Tavily / Exa / Brave / Serper / SearXNG / Google PSE / Linkup / SearchAPI / You.com / Perplexity. Use when the user wants to search the web, look up information, find articles, or query a search engine.
|
||||
---
|
||||
|
||||
# 9Router — Web Search
|
||||
|
||||
Requires `NINEROUTER_URL` (and `NINEROUTER_KEY` if auth enabled). See https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md for setup.
|
||||
|
||||
## Discover providers
|
||||
|
||||
```bash
|
||||
curl $NINEROUTER_URL/v1/models/web | jq '.data[] | select(.kind=="webSearch") | .id'
|
||||
```
|
||||
|
||||
IDs end in `/search` (e.g. `tavily/search`). Combos (`owned_by:"combo"`) chain providers with auto-fallback.
|
||||
|
||||
## Endpoint
|
||||
|
||||
`POST $NINEROUTER_URL/v1/search`
|
||||
|
||||
| Field | Required | Notes |
|
||||
|---|---|---|
|
||||
| `model` (or `provider`) | yes | from `/v1/models/web` (e.g. `tavily/search` or just `tavily`) |
|
||||
| `query` | yes | search query |
|
||||
| `max_results` | no | default 5 |
|
||||
| `search_type` | no | `web` (default) / `news` |
|
||||
| `country`, `language`, `time_range`, `domain_filter` | no | provider-dependent |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
curl -X POST $NINEROUTER_URL/v1/search \
|
||||
-H "Authorization: Bearer $NINEROUTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"tavily/search","query":"9Router open source","max_results":5}'
|
||||
```
|
||||
|
||||
JS:
|
||||
|
||||
```js
|
||||
const r = await fetch(`${process.env.NINEROUTER_URL}/v1/search`, {
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${process.env.NINEROUTER_KEY}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ model: "search-combo", query: "latest LLM benchmarks", max_results: 10 }),
|
||||
});
|
||||
console.log(await r.json());
|
||||
```
|
||||
|
||||
## Response shape
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "tavily",
|
||||
"query": "9Router open source",
|
||||
"results": [
|
||||
{
|
||||
"title": "...", "url": "https://...", "display_url": "github.com/...",
|
||||
"snippet": "...", "position": 1, "score": 0.92,
|
||||
"published_at": null, "favicon_url": null, "content": null,
|
||||
"metadata": { "author": null, "language": null, "source_type": null, "image_url": null },
|
||||
"citation": { "provider": "tavily", "retrieved_at": "2026-...", "rank": 1 }
|
||||
}
|
||||
],
|
||||
"answer": null,
|
||||
"usage": { "queries_used": 1, "search_cost_usd": 0.008 },
|
||||
"metrics": { "response_time_ms": 850, "upstream_latency_ms": 700, "total_results_available": 12 },
|
||||
"errors": []
|
||||
}
|
||||
```
|
||||
|
||||
## Provider quirks
|
||||
|
||||
All accept `query` + `max_results`. Optional fields vary:
|
||||
|
||||
| Provider | Supports | Required extras |
|
||||
|---|---|---|
|
||||
| `tavily` | country, domain_filter, news topic | — |
|
||||
| `exa` | domain_filter (incl/excl), news category | — |
|
||||
| `brave-search` | country, language | — |
|
||||
| `serper` | country, language, news endpoint | — |
|
||||
| `perplexity` | country, language, domain_filter | — |
|
||||
| `linkup` | domain_filter, time_range | `depth: fast/standard/deep` (option) |
|
||||
| `google-pse` | country, language, time_range, offset | **`cx` required** (providerOptions) |
|
||||
| `searchapi` | country, language, pagination | — |
|
||||
| `youcom` | country, language, time_range, domain_filter, full_page | — |
|
||||
| `searxng` | language, time_range | Self-hosted, **noAuth** |
|
||||
|
||||
Provider IS the model — `"provider":"tavily"` ≡ `"model":"tavily/search"`.
|
||||
60
skills/9router/SKILL.md
Normal file
60
skills/9router/SKILL.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
name: 9router
|
||||
description: Entry point for 9Router — local/remote AI gateway with OpenAI-compatible REST for chat, image, TTS, embeddings, web search, web fetch. Use when the user mentions 9Router, NINEROUTER_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.
|
||||
---
|
||||
|
||||
# 9Router
|
||||
|
||||
Local/remote AI gateway exposing OpenAI-compatible REST. One key, many providers, auto-fallback.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
export NINEROUTER_URL="http://localhost:20128" # or VPS / tunnel URL
|
||||
export NINEROUTER_KEY="sk-..." # from Dashboard → Keys (only if requireApiKey=true)
|
||||
```
|
||||
|
||||
All requests: `${NINEROUTER_URL}/v1/...` with header `Authorization: Bearer ${NINEROUTER_KEY}` (omit if auth disabled).
|
||||
|
||||
Verify: `curl $NINEROUTER_URL/api/health` → `{"ok":true}`
|
||||
|
||||
## Discover models
|
||||
|
||||
```bash
|
||||
curl $NINEROUTER_URL/v1/models # chat/LLM (default)
|
||||
curl $NINEROUTER_URL/v1/models/image # image-gen
|
||||
curl $NINEROUTER_URL/v1/models/tts # text-to-speech
|
||||
curl $NINEROUTER_URL/v1/models/embedding # embeddings
|
||||
curl $NINEROUTER_URL/v1/models/web # web search + fetch (entries have `kind` field)
|
||||
curl $NINEROUTER_URL/v1/models/stt # speech-to-text
|
||||
curl $NINEROUTER_URL/v1/models/image-to-text # vision
|
||||
```
|
||||
|
||||
Use `data[].id` as `model` field in requests. Combos appear with `owned_by:"combo"`.
|
||||
|
||||
Response shape:
|
||||
```json
|
||||
{ "object": "list", "data": [
|
||||
{ "id": "openai/gpt-5", "object": "model", "owned_by": "openai", "created": 1735000000 },
|
||||
{ "id": "tavily/search", "object": "model", "kind": "webSearch", "owned_by": "tavily", "created": 1735000000 }
|
||||
]}
|
||||
```
|
||||
|
||||
## Capability skills
|
||||
|
||||
When the user needs a specific capability, fetch that skill's `SKILL.md` from its raw URL:
|
||||
|
||||
| Capability | Raw URL |
|
||||
|---|---|
|
||||
| Chat / code-gen | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-chat/SKILL.md |
|
||||
| Image generation | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-image/SKILL.md |
|
||||
| Text-to-speech | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-tts/SKILL.md |
|
||||
| Embeddings | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-embeddings/SKILL.md |
|
||||
| Web search | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-web-search/SKILL.md |
|
||||
| Web fetch (URL → markdown) | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-web-fetch/SKILL.md |
|
||||
|
||||
## Errors
|
||||
|
||||
- 401 → set/refresh `NINEROUTER_KEY` (Dashboard → Keys)
|
||||
- 400 `Invalid model format` → check `model` exists in `/v1/models/<kind>`
|
||||
- 503 `All accounts unavailable` → wait `retry-after` or add another provider account
|
||||
41
skills/README.md
Normal file
41
skills/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# 9Router — Agent Skills
|
||||
|
||||
Drop-in skills for any AI agent (Claude, Cursor, ChatGPT, custom SDK). Just **copy a link** below and paste it to your AI — it will fetch the skill and use 9Router for you.
|
||||
|
||||
> Tip: start with the **9router** entry skill — it covers setup and links to all capability skills.
|
||||
|
||||
## Skills
|
||||
|
||||
| Capability | Copy link below and paste to your AI |
|
||||
|---|---|
|
||||
| **Entry / Setup** (start here) | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md |
|
||||
| Chat / code-gen | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-chat/SKILL.md |
|
||||
| Image generation | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-image/SKILL.md |
|
||||
| Text-to-speech | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-tts/SKILL.md |
|
||||
| Embeddings | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-embeddings/SKILL.md |
|
||||
| Web search | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-web-search/SKILL.md |
|
||||
| Web fetch (URL → markdown) | https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router-web-fetch/SKILL.md |
|
||||
|
||||
## How to use
|
||||
|
||||
Paste to your AI (Claude, Cursor, ChatGPT, …):
|
||||
|
||||
```
|
||||
Read this skill and use it: https://raw.githubusercontent.com/decolua/9router/main/app/skills/9router/SKILL.md
|
||||
```
|
||||
|
||||
Then ask normally — *"generate an image of a cat"*, *"transcribe this URL"*, etc.
|
||||
|
||||
## Configure your shell once
|
||||
|
||||
```bash
|
||||
export NINEROUTER_URL="http://localhost:20128" # local default, or your VPS / tunnel URL
|
||||
export NINEROUTER_KEY="sk-..." # from Dashboard → Keys (only if requireApiKey=true)
|
||||
```
|
||||
|
||||
Verify: `curl $NINEROUTER_URL/api/health` → `{"ok":true}`.
|
||||
|
||||
## Links
|
||||
|
||||
- Source: https://github.com/decolua/9router
|
||||
- Dashboard: https://9router.com
|
||||
Reference in New Issue
Block a user