feat(skills): add 5 CLI skills + AgentSkills / OmniSkills dashboard pages (#2284)

feat(skills): add 5 CLI skills + AgentSkills / OmniSkills dashboard pages

Integrated into release/v3.8.0
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-05-15 12:48:54 -03:00
committed by GitHub
parent bb0ec76f24
commit 0edf90bb5a
12 changed files with 983 additions and 173 deletions

View File

@@ -15,21 +15,26 @@ 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 (37 tools) | [omniroute-mcp/SKILL.md](omniroute-mcp/SKILL.md) |
| A2A protocol | [omniroute-a2a/SKILL.md](omniroute-a2a/SKILL.md) |
| Routing & combos | [omniroute-routing/SKILL.md](omniroute-routing/SKILL.md) |
| Token compression | [omniroute-compression/SKILL.md](omniroute-compression/SKILL.md) |
| Monitoring & health | [omniroute-monitoring/SKILL.md](omniroute-monitoring/SKILL.md) |
| 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 (37 tools) | [omniroute-mcp/SKILL.md](omniroute-mcp/SKILL.md) |
| A2A protocol | [omniroute-a2a/SKILL.md](omniroute-a2a/SKILL.md) |
| Routing & combos | [omniroute-routing/SKILL.md](omniroute-routing/SKILL.md) |
| Token compression | [omniroute-compression/SKILL.md](omniroute-compression/SKILL.md) |
| Monitoring & health | [omniroute-monitoring/SKILL.md](omniroute-monitoring/SKILL.md) |
| CLI entry point | [omniroute-cli/SKILL.md](omniroute-cli/SKILL.md) |
| CLI admin & lifecycle | [omniroute-cli-admin/SKILL.md](omniroute-cli-admin/SKILL.md) |
| CLI providers & keys | [omniroute-cli-providers/SKILL.md](omniroute-cli-providers/SKILL.md) |
| CLI cloud agents | [omniroute-cli-cloud/SKILL.md](omniroute-cli-cloud/SKILL.md) |
| CLI evals & benchmarks | [omniroute-cli-eval/SKILL.md](omniroute-cli-eval/SKILL.md) |
## Format

View File

@@ -0,0 +1,145 @@
---
name: omniroute-cli-admin
description: Manage the OmniRoute server lifecycle via CLI — start/stop/restart, non-interactive setup, diagnostics (omniroute doctor), backup/restore, autostart, and tunnel management. Use when the user wants to operate the OmniRoute server, automate provisioning, or troubleshoot the runtime.
---
# OmniRoute — CLI Admin
Requires the `omniroute` CLI. See [CLI entry-point skill](https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli/SKILL.md) for install + global flags.
## Server lifecycle
```bash
omniroute # Start server (default port 20128)
omniroute serve # Explicit alias
omniroute --port 3000 # Override port
omniroute --no-open # Don't auto-open browser
omniroute --mcp # Start as MCP server (stdio transport)
omniroute stop # Stop the running server
omniroute restart # Restart the server
omniroute dashboard # Open dashboard in browser
omniroute open # Alias for dashboard
omniroute status # Runtime status (uptime, requests, providers)
```
## Setup & provisioning
### Interactive wizard
```bash
omniroute setup # Step-by-step interactive setup
```
### Non-interactive (CI / Docker)
```bash
omniroute setup --non-interactive \
--password 'admin-password' \
--add-provider \
--provider openai \
--api-key 'sk-...' \
--test-provider
```
Environment variables for non-interactive setup:
| Variable | Purpose |
| ----------------------------- | -------------------------------------------- |
| `OMNIROUTE_SETUP_PASSWORD` | Admin password (≥8 chars) |
| `OMNIROUTE_PROVIDER` | Provider id (e.g. `openai`, `anthropic`) |
| `OMNIROUTE_PROVIDER_NAME` | Display name for the connection |
| `OMNIROUTE_PROVIDER_BASE_URL` | Optional OpenAI-compatible base URL override |
| `OMNIROUTE_API_KEY` | Provider API key |
| `OMNIROUTE_DEFAULT_MODEL` | Optional default model |
| `DATA_DIR` | Override OmniRoute data directory |
## Diagnostics
```bash
omniroute doctor # Full health check
omniroute doctor --json # Machine-readable JSON
omniroute doctor --no-liveness # Skip HTTP health probe
omniroute doctor --host 0.0.0.0 # Override liveness host
omniroute doctor --liveness-url <url> # Full URL override
```
Checks performed: Config, Database, Storage/encryption, Port, Node runtime, Native binary (better-sqlite3), Memory, Server liveness.
Exit code is non-zero if any check fails — useful in CI:
```bash
omniroute doctor --json | jq '.checks[] | select(.status=="fail")'
```
## Backup & restore
```bash
omniroute backup # Snapshot config + SQLite DB to ~/.omniroute/backups/
omniroute restore # Restore from a previous snapshot (interactive picker)
```
## Autostart (system tray / startup)
```bash
omniroute autostart enable # Register OmniRoute as a system startup item
omniroute autostart disable # Remove startup registration
omniroute autostart status # Show current autostart state
```
On Linux: creates a systemd user unit. On macOS: LaunchAgent plist. On Windows: registry startup entry.
## Tunnels (public URL)
Expose a local OmniRoute instance via a secure tunnel:
```bash
omniroute tunnel list # List active tunnels
omniroute tunnel create cloudflare # Start a Cloudflare Tunnel (free)
omniroute tunnel create tailscale # Start a Tailscale funnel
omniroute tunnel create ngrok # Start an ngrok tunnel
omniroute tunnel stop <id> # Stop a running tunnel
```
The tunnel URL is printed and can be used as `OMNIROUTE_BASE_URL` from remote machines.
## Config & environment
```bash
omniroute config show # Display current effective configuration
omniroute env show # List all OmniRoute environment variables
omniroute env get <KEY> # Get a single env var value
omniroute env set <KEY> <value> # Set an env var (temporary — until restart)
```
## Recovery
```bash
omniroute reset-password # Reset the admin password interactively
omniroute reset-encrypted-columns # Dry-run: show encrypted credential columns
omniroute reset-encrypted-columns --force # Null out encrypted credentials in SQLite
```
Use `reset-encrypted-columns --force` only if `STORAGE_ENCRYPTION_KEY` was lost and you need to re-enter all provider API keys.
## Logs
```bash
omniroute logs # Stream live request logs
omniroute logs --json # JSON log entries
omniroute logs --search <term> # Filter by term
omniroute logs --follow # Tail mode (keep streaming)
```
## Update
```bash
omniroute update # Check for a newer version and prompt to update
```
## Errors
- `doctor` shows `STORAGE_ENCRYPTION_KEY missing` → set the key in `.env` or run `reset-encrypted-columns --force` to wipe and re-enter credentials
- `doctor` reports native binary fail → `npm rebuild better-sqlite3` in the OmniRoute app directory
- `tunnel create cloudflare` hangs → ensure `cloudflared` is installed: `brew install cloudflare/cloudflare/cloudflared`

View File

@@ -0,0 +1,120 @@
---
name: omniroute-cli-cloud
description: Control OmniRoute cloud agents (OpenAI Codex, Devin, Jules) from the CLI — create tasks, track status, approve plans, send messages, and manage sources. Use when the user wants to automate cloud coding agent workflows via the terminal.
---
# OmniRoute — CLI Cloud Agents
Requires the `omniroute` CLI. See [CLI entry-point skill](https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli/SKILL.md) for install + global flags.
## Supported agents
| Agent | ID | Auth required |
| -------------- | ------- | -------------- |
| OpenAI Codex | `codex` | OpenAI API key |
| Devin | `devin` | Devin API key |
| Jules (Google) | `jules` | Google OAuth |
## Authenticate an agent
```bash
omniroute cloud codex auth # Set / refresh Codex API key
omniroute cloud devin auth # Set / refresh Devin API key
omniroute cloud jules auth # OAuth login for Jules (opens browser)
```
## List all agents
```bash
omniroute cloud agents # Show all configured cloud agents + status
omniroute cloud agents --json
```
## Create a task
```bash
omniroute cloud codex task create \
--title "Add OAuth to the auth module" \
--prompt "Implement Google OAuth 2.0 login in src/auth/oauth.ts"
omniroute cloud codex task create \
--title "Fix test failures" \
--prompt-file ./task-description.md # Read prompt from a file
```
Same syntax for `devin` and `jules`:
```bash
omniroute cloud devin task create --title "..." --prompt "..."
omniroute cloud jules task create --title "..." --prompt "..."
```
## List tasks
```bash
omniroute cloud codex task list # All Codex tasks (table)
omniroute cloud codex task list --json # JSON output
```
## Get task details
```bash
omniroute cloud codex task get <taskId> # Full task record
omniroute cloud codex task status <taskId> # Status + progress only
```
Task status values: `running`, `completed`, `failed`, `cancelled`.
## Approve a plan
Devin and Jules may pause for plan approval before writing code:
```bash
omniroute cloud devin task approve <taskId> # Approve the proposed plan
omniroute cloud jules task approve <taskId>
```
## Send a message to a running task
```bash
omniroute cloud codex task message <taskId> "Focus on the backend only, skip the UI"
```
## List task sources (files touched)
```bash
omniroute cloud codex task sources <taskId> # Files changed / created by the task
```
## Cancel a task
```bash
omniroute cloud codex task cancel <taskId>
omniroute cloud devin task cancel <taskId>
```
## Typical workflow
```bash
# 1. Authenticate
omniroute cloud codex auth
# 2. Create a task
TASK_ID=$(omniroute cloud codex task create \
--title "Refactor auth module" \
--prompt "Extract JWT logic to src/auth/jwt.ts" \
--output json | jq -r '.id')
# 3. Poll status
omniroute cloud codex task status $TASK_ID
# 4. View touched files when complete
omniroute cloud codex task sources $TASK_ID
```
## Errors
- `auth required` → run `omniroute cloud <agent> auth` before any task commands
- `task create` fails with 402 → agent billing limit reached; check your Codex/Devin/Jules account
- `task approve` fails with 404 → task does not have a pending plan; check status first
- `jules auth` browser flow fails → ensure Google account has Jules access; try `omniroute cloud jules auth` again

View File

@@ -0,0 +1,113 @@
---
name: omniroute-cli-eval
description: Run and manage OmniRoute eval suites from the CLI — create suites, run benchmarks, watch live results, view scorecards, and compare model performance. Use when the user wants to benchmark models, validate quality regressions, or automate LLM evals in CI.
---
# OmniRoute — CLI Evals
Requires the `omniroute` CLI. See [CLI entry-point skill](https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli/SKILL.md) for install + global flags.
## What are evals?
Evals are automated test suites that score LLM outputs against expected answers or rubrics. OmniRoute stores suites and run results in its local database.
## Eval suites
```bash
omniroute eval suites list # List all eval suites
omniroute eval suites list --json # JSON output
omniroute eval suites get <suiteId> # Full suite definition
```
### Create a suite
```bash
omniroute eval suites create \
--name "code-quality" \
--rubric "exact-match" \
--samples-file ./samples.jsonl # JSONL: {input, expected_output}
```
Rubric options: `exact-match`, `contains`, `llm-judge`, `regex`.
`--samples-file` format (one JSON object per line):
```jsonl
{"input": "What is 2+2?", "expected_output": "4"}
{"input": "Translate 'hello' to Spanish", "expected_output": "hola"}
```
## Run an eval
```bash
omniroute eval suites run <suiteId> \
--model claude-sonnet-4-6 # Run suite against a specific model
omniroute eval suites run <suiteId> \
--model gpt-4o \
--watch # Live TUI progress (EvalWatch)
```
The run is asynchronous. Use `--watch` for a live terminal dashboard or poll manually:
```bash
RUN_ID=$(omniroute eval suites run <suiteId> --model claude-sonnet-4-6 --output json | jq -r '.id')
omniroute eval get $RUN_ID
```
## Manage runs
```bash
omniroute eval list # List all eval runs
omniroute eval list --json
omniroute eval get <runId> # Run details (status, model, score)
omniroute eval results <runId> # Per-sample results
omniroute eval scorecard <runId> # Full scorecard with pass/fail per sample
omniroute eval cancel <runId> # Cancel a running eval
```
## Scorecard output
```bash
omniroute eval scorecard <runId> --output json
```
Response fields per sample:
```json
{
"id": "sample-1",
"score": 0.95,
"passed": true,
"input": "What is 2+2?",
"output": "4",
"expected": "4"
}
```
## Comparing models
Run the same suite against multiple models and compare:
```bash
for MODEL in claude-sonnet-4-6 gpt-4o gemini-2.0-flash; do
omniroute eval suites run $SUITE_ID --model $MODEL --output json | jq '{model: .model, score: .score}'
done
```
## CI integration
```bash
# Run and fail CI if score drops below threshold
SCORE=$(omniroute eval suites run $SUITE_ID --model claude-sonnet-4-6 --output json | jq -r '.score')
python3 -c "import sys; score=float('$SCORE'); sys.exit(0 if score >= 0.90 else 1)"
```
## Errors
- `suites create` fails with `invalid rubric` → use one of: `exact-match`, `contains`, `llm-judge`, `regex`
- `suites run` returns `model not found` → verify model ID with `omniroute models --search <name>`
- `eval get` shows `status: failed` → check `omniroute logs --search eval` for error details
- `scorecard` returns empty results → the run may still be `running`; poll `omniroute eval get <runId>` until `status` is `completed`

View File

@@ -0,0 +1,145 @@
---
name: omniroute-cli-providers
description: Manage OmniRoute provider connections, API keys, and routing combos via CLI — add/list/test/remove providers, rotate keys, run OAuth flows, list models, and create/switch combos. Use when the user wants to configure providers, manage credentials, or set up routing from the terminal.
---
# OmniRoute — CLI Providers & Keys
Requires the `omniroute` CLI. See [CLI entry-point skill](https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli/SKILL.md) for install + global flags.
## Provider catalog (available providers)
```bash
omniroute providers available # Full OmniRoute provider catalog
omniroute providers available --search openai # Filter by id, name, alias
omniroute providers available --category api-key # Filter by category
omniroute providers available --json # Machine-readable JSON
```
Categories: `api-key`, `oauth`, `free`, `local`, `combo`.
## Configured provider connections
```bash
omniroute providers list # Connections in your DB
omniroute providers list --json
```
## Testing connections
```bash
omniroute providers test <id|name> # Test one configured connection
omniroute providers test-all # Test every active connection (TUI progress)
omniroute providers validate # Local-only structural validation (no HTTP)
```
`test-all` opens an interactive TUI that shows live pass/fail per connection. Use `--json` to get a machine-readable result:
```bash
omniroute providers test-all --json
```
## API key management (OmniRoute keys)
These manage the OmniRoute API keys issued under **API Manager** — not provider credentials.
```bash
omniroute keys list # List all OmniRoute API keys
omniroute keys add <provider> [apiKey] # Add an API key for a provider
omniroute keys remove <provider> # Remove an API key
omniroute keys regenerate <id> # Regenerate (rotate) a key
omniroute keys revoke <id> # Revoke a key (disables it)
omniroute keys reveal <id> # Show the full key value
omniroute keys usage <id> # Show usage stats for a key
omniroute keys rotate <id> # Rotate + revoke old key atomically
omniroute keys expiration list # List key expiration times
```
### Key policies
```bash
omniroute keys policy show <id> # Show rate-limit / permission policy
omniroute keys policy set <id> \
--rate-limit 100 \
--rate-window minute \
--permissions chat,models # Set policy on a key
```
## Models
```bash
omniroute models # List all models (all providers)
omniroute models openai # Filter by provider
omniroute models --search gpt # Search by name
omniroute models --json # JSON output
```
## OAuth providers
```bash
omniroute oauth list # List OAuth-configured providers
omniroute oauth login <provider> # Start browser-based OAuth flow
omniroute oauth logout <provider> # Revoke OAuth token
omniroute oauth status <provider> # Show token state + expiry
omniroute oauth refresh <provider> # Force token refresh
```
For OAuth providers (Gemini, Windsurf, Antigravity, etc.) the `login` command opens the OmniRoute dashboard OAuth flow in your browser.
## Provider nodes (multi-account routing)
Provider nodes let you attach multiple API keys / accounts to one logical provider for round-robin or failover.
```bash
omniroute nodes list <provider> # List nodes for a provider
omniroute nodes add <provider> --api-key <key> # Add a node
omniroute nodes remove <provider> <nodeId> # Remove a node
omniroute nodes test <provider> <nodeId> # Test one node
```
## Routing combos (CLI)
Create and manage routing combos from the terminal:
```bash
omniroute combo list # List all combos
omniroute combo create <name> \
--strategy priority \
--targets anthropic/claude-opus-4-7,openai/gpt-4o # Create combo
omniroute combo switch <name> # Activate a combo as default
omniroute combo delete <name> # Delete a combo
omniroute combo suggest --task "code review" # Ask OmniRoute to recommend a combo
```
For the full REST API for combos see [omniroute-routing skill](https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-routing/SKILL.md).
## Quota & usage
```bash
omniroute quota # Provider quota usage + reset times
omniroute usage # Request + token usage summary
omniroute cost # Cost breakdown (by provider/model)
```
## Compression (CLI)
```bash
omniroute compression status # Current compression mode + savings stats
omniroute compression set --mode rtk # Enable RTK compression
omniroute compression set --mode stacked # Enable stacked (RTK + Caveman)
omniroute compression set --mode off # Disable compression
omniroute compression preview --mode rtk --text "..." # Preview savings for sample text
```
## Health
```bash
omniroute health # Detailed health: circuit breakers, cache, memory
```
## Errors
- `providers test <id>` fails with 401 → API key stored for that provider is wrong; use `keys remove` + `keys add` to reset it
- `oauth login` opens but doesn't complete → the OAuth token endpoint may be firewalled; use API key auth instead
- `combo create` fails with `strategy unknown` → use one of: `priority`, `weighted`, `round-robin`, `fill-first`, `least-used`, `cost-optimized`, `auto`, `random`, `strict-random`, `p2c`, `reset-aware`, `lkgp`, `context-optimized`, `context-relay`

View File

@@ -0,0 +1,104 @@
---
name: omniroute-cli
description: Entry point for the OmniRoute CLI (omniroute binary) — install, global flags, output formats, environment variables, and index of CLI capability skills. Use when the user wants to control OmniRoute from the terminal, automate workflows, or integrate with CI/CD.
---
# OmniRoute — CLI (Entry Point)
The `omniroute` binary ships with the OmniRoute server. It is both the server launcher and a full management CLI with 250+ commands across 39 groups.
## Install
```bash
npm install -g omniroute # npm registry
# or: use the binary bundled with the desktop app
```
Requires Node.js ≥20.20.2, ≥22.22.2, or ≥24.
Verify:
```bash
omniroute --version # prints installed version
omniroute --help # full command tree
```
## Connection
Every CLI command that talks to the server reads two values:
| Source | Variable / Flag |
| -------- | ------------------------------------ |
| Base URL | `OMNIROUTE_BASE_URL` or `--base-url` |
| API key | `OMNIROUTE_API_KEY` or `--api-key` |
Default base URL: `http://localhost:20128`
```bash
export OMNIROUTE_BASE_URL="http://localhost:20128"
export OMNIROUTE_API_KEY="sk-..." # from Dashboard → API Manager
```
For a remote server:
```bash
export OMNIROUTE_BASE_URL="https://your-server.com"
```
## Global flags
| Flag | Description |
| ------------------- | -------------------------------------------------------- |
| `--base-url <url>` | Override server URL for this invocation |
| `--api-key <key>` | Override API key for this invocation |
| `--output <format>` | Output format: `table` (default), `json`, `jsonl`, `csv` |
| `--json` | Shorthand for `--output json` |
| `--non-interactive` | Disable prompts — for CI / shell scripts |
| `--no-open` | Don't auto-open the browser on start |
| `--port <n>` | Override default port 20128 |
| `--help`, `-h` | Show help for the current command |
| `--version`, `-v` | Print the installed version |
## Output formats
All listing commands support `--output`:
```bash
omniroute combo list # human-readable table
omniroute combo list --output json # JSON array
omniroute combo list --output jsonl # one JSON object per line
omniroute combo list --output csv # CSV with header row
```
## Quick start: one-shot server + provider setup
```bash
# 1. Start server
omniroute
# 2. (First run) interactive setup wizard
omniroute setup
# 3. Verify everything is healthy
omniroute doctor
```
## CLI capability skills
| Capability | Skill |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| Server admin + backup | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-admin/SKILL.md |
| Provider & key management | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-providers/SKILL.md |
| Cloud agents (Codex / Devin / Jules) | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-cloud/SKILL.md |
| Evals & benchmarking | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-eval/SKILL.md |
## API skills (REST)
For direct HTTP usage instead of the CLI, see the [OmniRoute entry-point skill](https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute/SKILL.md).
## Errors
- `Connection refused` → server not running; run `omniroute` or `omniroute serve`
- `401 Unauthorized` → wrong or missing API key
- `command not found: omniroute` → not in PATH; check `npm root -g` or re-install
- `doctor` reports SQLite incompatible → `npm rebuild better-sqlite3` in the app directory

View File

@@ -49,6 +49,16 @@ Use `data[].id` as `model` field in requests. Combos appear with `owned_by:"comb
| Token compression | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-compression/SKILL.md |
| Monitoring & health | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-monitoring/SKILL.md |
## CLI skills (omniroute binary)
| Capability | Raw URL |
| ---------------------- | ----------------------------------------------------------------------------------------------------- |
| CLI entry point | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli/SKILL.md |
| CLI admin & lifecycle | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-admin/SKILL.md |
| CLI providers & keys | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-providers/SKILL.md |
| CLI cloud agents | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-cloud/SKILL.md |
| CLI evals & benchmarks | https://raw.githubusercontent.com/diegosouzapw/OmniRoute/main/skills/omniroute-cli-eval/SKILL.md |
## Errors
- `401` → set/refresh `OMNIROUTE_KEY` (Dashboard → API Keys)

View File

@@ -0,0 +1,248 @@
"use client";
import {
AGENT_SKILLS,
AGENT_SKILLS_REPO_URL,
getAgentSkillRawUrl,
getAgentSkillBlobUrl,
type AgentSkill,
} from "@/shared/constants/agentSkills";
import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard";
function CopyButton({ url }: { url: string }) {
const { copied, copy } = useCopyToClipboard();
const isCopied = copied === url;
return (
<button
onClick={() => void copy(url, url)}
className="flex items-center gap-1 rounded px-2 py-1 text-xs font-medium transition-colors"
style={{
background: isCopied
? "var(--color-success-bg, #d1fae5)"
: "var(--color-surface-2, #f3f4f6)",
color: isCopied ? "var(--color-success, #065f46)" : "var(--color-text-2, #6b7280)",
}}
title="Copy raw URL to clipboard"
>
<span className="material-symbols-outlined" style={{ fontSize: 14 }}>
{isCopied ? "check" : "content_copy"}
</span>
{isCopied ? "Copied!" : "Copy URL"}
</button>
);
}
function SkillRow({ skill }: { skill: AgentSkill }) {
const rawUrl = getAgentSkillRawUrl(skill.id);
const blobUrl = getAgentSkillBlobUrl(skill.id);
return (
<div
className="flex items-start gap-3 rounded-lg border p-3 transition-colors hover:bg-[var(--color-surface-hover,#f9fafb)]"
style={{ borderColor: "var(--color-border, #e5e7eb)" }}
>
<div
className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg"
style={{ background: "var(--color-surface-2, #f3f4f6)" }}
>
<span
className="material-symbols-outlined"
style={{ fontSize: 18, color: "var(--color-text-2, #6b7280)" }}
>
{skill.icon}
</span>
</div>
<div className="min-w-0 flex-1">
<div className="mb-0.5 flex flex-wrap items-center gap-1.5">
<span className="text-sm font-semibold" style={{ color: "var(--color-text, #111827)" }}>
{skill.name}
</span>
{skill.isEntry && (
<span
className="rounded-full px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wide"
style={{
background: "var(--color-primary-bg, #eff6ff)",
color: "var(--color-primary, #2563eb)",
}}
>
Start Here
</span>
)}
{skill.isNew && (
<span
className="rounded-full px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wide"
style={{
background: "var(--color-warning-bg, #fef3c7)",
color: "var(--color-warning, #92400e)",
}}
>
New
</span>
)}
{skill.endpoint && (
<code
className="rounded px-1.5 py-0.5 text-[10px]"
style={{
background: "var(--color-surface-2, #f3f4f6)",
color: "var(--color-text-2, #6b7280)",
fontFamily: "monospace",
}}
>
{skill.endpoint}
</code>
)}
</div>
<p className="text-xs leading-relaxed" style={{ color: "var(--color-text-2, #6b7280)" }}>
{skill.description}
</p>
</div>
<div className="flex shrink-0 items-center gap-1">
<a
href={blobUrl}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-1 rounded px-2 py-1 text-xs font-medium transition-colors hover:bg-[var(--color-surface-2,#f3f4f6)]"
style={{ color: "var(--color-text-3, #9ca3af)" }}
title="View on GitHub"
>
<span className="material-symbols-outlined" style={{ fontSize: 14 }}>
open_in_new
</span>
</a>
<CopyButton url={rawUrl} />
</div>
</div>
);
}
function SkillSection({
title,
subtitle,
icon,
skills,
}: {
title: string;
subtitle: string;
icon: string;
skills: AgentSkill[];
}) {
return (
<section>
<div className="mb-3 flex items-center gap-2">
<span
className="material-symbols-outlined"
style={{ fontSize: 20, color: "var(--color-text-2, #6b7280)" }}
>
{icon}
</span>
<div>
<h2 className="text-sm font-semibold" style={{ color: "var(--color-text, #111827)" }}>
{title}
</h2>
<p className="text-xs" style={{ color: "var(--color-text-3, #9ca3af)" }}>
{subtitle}
</p>
</div>
</div>
<div className="flex flex-col gap-2">
{skills.map((skill) => (
<SkillRow key={skill.id} skill={skill} />
))}
</div>
</section>
);
}
export default function AgentSkillsPage() {
const apiSkills = AGENT_SKILLS.filter((s) => s.category === "api");
const cliSkills = AGENT_SKILLS.filter((s) => s.category === "cli");
return (
<div className="mx-auto max-w-3xl space-y-8 p-6">
{/* Header */}
<div>
<h1 className="text-xl font-bold" style={{ color: "var(--color-text, #111827)" }}>
AgentSkills
</h1>
<p className="mt-1 text-sm" style={{ color: "var(--color-text-2, #6b7280)" }}>
SKILL.md manifests for AI agents paste a URL into Claude, Cursor, Cline, or any agent to
give it full knowledge of OmniRoute.
</p>
</div>
{/* How to use */}
<div
className="rounded-lg border p-4"
style={{
borderColor: "var(--color-border, #e5e7eb)",
background: "var(--color-surface-2, #f9fafb)",
}}
>
<div className="mb-2 flex items-center gap-2">
<span
className="material-symbols-outlined"
style={{ fontSize: 18, color: "var(--color-primary, #2563eb)" }}
>
info
</span>
<span className="text-sm font-semibold" style={{ color: "var(--color-text, #111827)" }}>
How to use
</span>
</div>
<ol className="space-y-1 text-xs" style={{ color: "var(--color-text-2, #6b7280)" }}>
<li>
1. Click <strong>Copy URL</strong> on the skill you want your agent to know about.
</li>
<li>
2. In your AI agent (Claude, Cursor, Cline), say:
<br />
<code
className="mt-1 block rounded px-2 py-1 font-mono text-[11px]"
style={{
background: "var(--color-surface, #fff)",
border: "1px solid var(--color-border, #e5e7eb)",
}}
>
Use the skill at &lt;pasted-url&gt;
</code>
</li>
<li>
3. The agent fetches the SKILL.md and learns OmniRoute&apos;s API or CLI no manual
docs needed.
</li>
</ol>
<a
href={AGENT_SKILLS_REPO_URL}
target="_blank"
rel="noopener noreferrer"
className="mt-3 inline-flex items-center gap-1 text-xs font-medium"
style={{ color: "var(--color-primary, #2563eb)" }}
>
<span className="material-symbols-outlined" style={{ fontSize: 14 }}>
open_in_new
</span>
Browse all skills on GitHub
</a>
</div>
{/* API Skills */}
<SkillSection
title="API Skills"
subtitle={`${apiSkills.length} skills — control OmniRoute via REST / HTTP`}
icon="api"
skills={apiSkills}
/>
{/* CLI Skills */}
<SkillSection
title="CLI Skills"
subtitle={`${cliSkills.length} skills — control OmniRoute via the omniroute terminal binary`}
icon="terminal"
skills={cliSkills}
/>
</div>
);
}

View File

@@ -4,13 +4,6 @@ import { useState, useEffect, useRef } from "react";
import { Card } from "@/shared/components";
import { useTranslations } from "next-intl";
import type { SkillsProvider } from "@/lib/skills/providerSettings";
import {
AGENT_SKILLS,
AGENT_SKILLS_REPO_URL,
getAgentSkillRawUrl,
getAgentSkillBlobUrl,
type AgentSkill,
} from "@/shared/constants/agentSkills";
interface Skill {
id: string;
@@ -34,93 +27,6 @@ interface Execution {
createdAt: string;
}
function AgentSkillCopyButton({ value, label = "Copy link" }: { value: string; label?: string }) {
const [copied, setCopied] = useState(false);
const copy = async () => {
try {
await navigator.clipboard.writeText(value);
} catch {
// Fallback for HTTP contexts or older browsers
const ta = document.createElement("textarea");
ta.value = value;
ta.style.position = "fixed";
ta.style.opacity = "0";
document.body.appendChild(ta);
ta.select();
document.execCommand("copy");
document.body.removeChild(ta);
}
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<button
onClick={copy}
className="px-2 py-1 rounded-md bg-primary text-white text-[11px] font-medium hover:bg-primary/90 transition-colors cursor-pointer shrink-0 inline-flex items-center gap-1"
title={value}
>
<span className="material-symbols-outlined text-[12px]">
{copied ? "check" : "content_copy"}
</span>
{copied ? "Copied!" : label}
</button>
);
}
function AgentSkillRow({ skill }: { skill: AgentSkill }) {
const url = getAgentSkillRawUrl(skill.id);
return (
<div
className={`flex items-start gap-3 p-4 rounded-[14px] border shadow-[var(--shadow-soft)] transition-colors ${
skill.isEntry
? "border-brand-500/40 bg-brand-500/5"
: "border-border-subtle bg-surface hover:bg-surface-2"
}`}
>
<div
className={`size-9 rounded-lg flex items-center justify-center shrink-0 ${
skill.isEntry ? "bg-primary text-white" : "bg-primary/10 text-primary"
}`}
>
<span className="material-symbols-outlined text-[18px]">{skill.icon}</span>
</div>
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2 flex-wrap">
<h3 className="font-semibold text-sm text-text-main">{skill.name}</h3>
{skill.isEntry && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-primary/10 text-primary font-medium">
START HERE
</span>
)}
{skill.isNew && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-emerald-500/10 text-emerald-400 font-medium">
NEW
</span>
)}
{skill.endpoint && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-surface-2 text-text-muted font-mono">
{skill.endpoint}
</span>
)}
</div>
<p className="text-xs text-text-muted mt-0.5">{skill.description}</p>
<a
href={getAgentSkillBlobUrl(skill.id)}
target="_blank"
rel="noreferrer"
className="text-[11px] text-text-muted hover:text-primary mt-1 inline-flex items-center gap-1 break-all"
>
{url}
<span className="material-symbols-outlined text-[12px]">open_in_new</span>
</a>
</div>
<AgentSkillCopyButton value={url} />
</div>
);
}
export default function SkillsPage() {
const [skills, setSkills] = useState<Skill[]>([]);
const [executions, setExecutions] = useState<Execution[]>([]);
@@ -136,9 +42,9 @@ export default function SkillsPage() {
const [execTotal, setExecTotal] = useState(0);
const [execTotalPages, setExecTotalPages] = useState(1);
const [activeTab, setActiveTab] = useState<
"skills" | "executions" | "sandbox" | "marketplace" | "agent-skills"
>("skills");
const [activeTab, setActiveTab] = useState<"skills" | "executions" | "sandbox" | "marketplace">(
"skills"
);
const [showInstallModal, setShowInstallModal] = useState(false);
const [installJson, setInstallJson] = useState("");
const [installStatus, setInstallStatus] = useState<{
@@ -408,7 +314,7 @@ export default function SkillsPage() {
<div className="flex flex-col gap-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold">{t("title")}</h1>
<h1 className="text-2xl font-bold">OmniSkills</h1>
<p className="text-text-muted mt-1">{t("description")}</p>
</div>
<button
@@ -460,16 +366,6 @@ export default function SkillsPage() {
>
Marketplace
</button>
<button
onClick={() => setActiveTab("agent-skills")}
className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
activeTab === "agent-skills"
? "border-violet-500 text-violet-400"
: "border-transparent text-text-muted hover:text-text-main"
}`}
>
{t("agentSkillsTab")}
</button>
</div>
{activeTab === "skills" && (
@@ -879,54 +775,6 @@ export default function SkillsPage() {
</div>
)}
{activeTab === "agent-skills" && (
<div className="max-w-4xl mx-auto space-y-4">
<Card padding="md">
<div className="text-xs text-text-muted mb-2">Paste this to your AI agent:</div>
<div className="flex items-center gap-2">
<code className="flex-1 px-3 py-2 rounded bg-surface-2 font-mono text-[12px] text-text-main break-all">
Read this skill and use it: {getAgentSkillRawUrl("omniroute")}
</code>
<AgentSkillCopyButton
value={`Read this skill and use it: ${getAgentSkillRawUrl("omniroute")}`}
label="Copy"
/>
</div>
<p className="text-xs text-text-muted mt-3">
Your agent fetches the SKILL.md, reads the setup instructions, and follows the links
to any capability it needs. Works with Claude, Cursor, ChatGPT, Cline, and any AI that
can fetch URLs.
</p>
</Card>
<div className="space-y-2">
{AGENT_SKILLS.map((skill) => (
<AgentSkillRow key={skill.id} skill={skill} />
))}
</div>
<Card padding="md">
<div className="flex items-center justify-between gap-3 flex-wrap">
<div>
<h2 className="text-sm font-semibold text-text-main">Browse on GitHub</h2>
<p className="text-xs text-text-muted mt-0.5">
Source, README, and raw links for all 13 skills.
</p>
</div>
<a
href={`${AGENT_SKILLS_REPO_URL}/tree/main/skills`}
target="_blank"
rel="noreferrer"
className="text-sm text-primary hover:underline inline-flex items-center gap-1"
>
<span className="material-symbols-outlined text-[16px]">open_in_new</span>
View on GitHub
</a>
</div>
</Card>
</div>
)}
{showInstallModal && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
<div className="bg-surface border border-border rounded-xl p-6 w-full max-w-lg mx-4">

View File

@@ -672,6 +672,8 @@
"cloudAgents": "Cloud Agents",
"memory": "Memory",
"skills": "Skills",
"omniSkills": "OmniSkills",
"agentSkills": "AgentSkills",
"docs": "Docs",
"issues": "Issues",
"endpoints": "Endpoints",

View File

@@ -1,4 +1,4 @@
// Agent Skills metadata — single source of truth for /dashboard/skills → "AI Skills" tab.
// Agent Skills metadata — single source of truth for /dashboard/agent-skills.
// Each skill = 1 raw GitHub URL the user copies and pastes to any AI agent.
const REPO = "diegosouzapw/OmniRoute";
@@ -15,11 +15,13 @@ export interface AgentSkill {
description: string;
endpoint: string | null;
icon: string;
category: "api" | "cli";
isEntry?: boolean;
isNew?: boolean;
}
export const AGENT_SKILLS: AgentSkill[] = [
// ── API Skills ──────────────────────────────────────────────────────────────
{
id: "omniroute",
name: "OmniRoute (Entry)",
@@ -27,6 +29,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
"Setup + index of all capabilities. Start here — covers base URL, auth, model discovery, and links to every capability skill.",
endpoint: null,
icon: "hub",
category: "api",
isEntry: true,
},
{
@@ -35,6 +38,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
description: "Chat / code-gen via OpenAI or Anthropic format with streaming and reasoning.",
endpoint: "/v1/chat/completions",
icon: "chat",
category: "api",
},
{
id: "omniroute-image",
@@ -42,6 +46,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
description: "Text-to-image via DALL-E, Imagen, FLUX, MiniMax, SDWebUI, and more.",
endpoint: "/v1/images/generations",
icon: "image",
category: "api",
},
{
id: "omniroute-tts",
@@ -49,6 +54,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
description: "OpenAI / ElevenLabs / Edge / Google / Deepgram voices.",
endpoint: "/v1/audio/speech",
icon: "record_voice_over",
category: "api",
},
{
id: "omniroute-stt",
@@ -57,6 +63,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
"Transcribe audio via OpenAI Whisper, Groq, Gemini, Deepgram, AssemblyAI, and more.",
endpoint: "/v1/audio/transcriptions",
icon: "mic",
category: "api",
},
{
id: "omniroute-embeddings",
@@ -64,6 +71,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
description: "Vectors for RAG / semantic search via OpenAI, Gemini, Mistral, and more.",
endpoint: "/v1/embeddings",
icon: "scatter_plot",
category: "api",
},
{
id: "omniroute-web-search",
@@ -71,6 +79,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
description: "Tavily / Exa / Brave / Serper / SearXNG / Google PSE / You.com.",
endpoint: "/v1/search",
icon: "search",
category: "api",
},
{
id: "omniroute-web-fetch",
@@ -78,6 +87,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
description: "URL → markdown / text / HTML via Firecrawl, Jina, Tavily, Exa.",
endpoint: "/v1/web/fetch",
icon: "language",
category: "api",
},
{
id: "omniroute-mcp",
@@ -86,6 +96,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
"37 tools over SSE/stdio/HTTP: routing, cache, compression, memory, skills, providers, audit.",
endpoint: "/api/mcp/sse",
icon: "electrical_services",
category: "api",
},
{
id: "omniroute-a2a",
@@ -94,6 +105,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
"JSON-RPC 2.0 agent-to-agent server with 5 built-in skills: smart-routing, quota, discovery, cost, health.",
endpoint: "/a2a",
icon: "device_hub",
category: "api",
},
{
id: "omniroute-routing",
@@ -102,6 +114,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
"Create and configure routing combos, 14 strategies, Auto-combo scoring, and fallback chains.",
endpoint: "/api/combos",
icon: "route",
category: "api",
isNew: true,
},
{
@@ -111,6 +124,7 @@ export const AGENT_SKILLS: AgentSkill[] = [
"RTK (command output), Caveman (prose), stacked mode, and MCP accessibility-tree filter. Save 6090% tokens.",
endpoint: "/api/settings/compression",
icon: "compress",
category: "api",
isNew: true,
},
{
@@ -120,6 +134,60 @@ export const AGENT_SKILLS: AgentSkill[] = [
"Health endpoints, circuit breakers, provider metrics (p50/p95/p99), budget guard, and MCP monitoring tools.",
endpoint: "/api/monitoring/health",
icon: "monitor_heart",
category: "api",
isNew: true,
},
// ── CLI Skills ───────────────────────────────────────────────────────────────
{
id: "omniroute-cli",
name: "CLI (Entry)",
description:
"Install, global flags (--output, --base-url, --api-key), environment variables, and index of all CLI capability skills.",
endpoint: null,
icon: "terminal",
category: "cli",
isEntry: true,
isNew: true,
},
{
id: "omniroute-cli-admin",
name: "CLI Admin",
description:
"Server lifecycle (start/stop/restart), non-interactive setup, doctor diagnostics, backup/restore, autostart, and tunnels.",
endpoint: null,
icon: "manage_accounts",
category: "cli",
isNew: true,
},
{
id: "omniroute-cli-providers",
name: "CLI Providers & Keys",
description:
"Add/test/remove provider connections, manage API keys, rotate credentials, OAuth flows, list models, and manage combos.",
endpoint: null,
icon: "key",
category: "cli",
isNew: true,
},
{
id: "omniroute-cli-cloud",
name: "CLI Cloud Agents",
description:
"Control Codex, Devin, and Jules cloud agents — create tasks, track status, approve plans, send messages, and view sources.",
endpoint: null,
icon: "cloud_sync",
category: "cli",
isNew: true,
},
{
id: "omniroute-cli-eval",
name: "CLI Evals",
description:
"Create and run eval suites, watch live benchmark progress, view scorecards, compare models, and integrate with CI.",
endpoint: null,
icon: "science",
category: "cli",
isNew: true,
},
];

View File

@@ -17,6 +17,7 @@ export const HIDEABLE_SIDEBAR_ITEM_IDS = [
"cloud-agents",
"memory",
"skills",
"agent-skills",
"translator",
"playground",
"media",
@@ -72,7 +73,8 @@ const CLI_SIDEBAR_ITEMS: readonly SidebarItemDefinition[] = [
{ id: "agents", href: "/dashboard/agents", i18nKey: "agents", icon: "smart_toy" },
{ id: "cloud-agents", href: "/dashboard/cloud-agents", i18nKey: "cloudAgents", icon: "cloud" },
{ id: "memory", href: "/dashboard/memory", i18nKey: "memory", icon: "psychology" },
{ id: "skills", href: "/dashboard/skills", i18nKey: "skills", icon: "auto_fix_high" },
{ id: "skills", href: "/dashboard/skills", i18nKey: "omniSkills", icon: "auto_fix_high" },
{ id: "agent-skills", href: "/dashboard/agent-skills", i18nKey: "agentSkills", icon: "share" },
];
const CONTEXT_SIDEBAR_ITEMS: readonly SidebarItemDefinition[] = [