fix(providers): remove ~anthropic, skip ~ prefixes in sync script (#69)
* fix(providers): remove ~anthropic, skip ~ prefixes in sync script
OpenRouter uses ~ prefixes for internal auto-routing aliases (e.g. ~anthropic).
These are not real providers — they already route through openrouter.toml.
The generated ~anthropic.toml was confusing (looked like a stale backup)
and redundant with the existing openrouter provider.
- Delete providers/~anthropic.toml
- Skip provider IDs starting with ~ in sync-pricing.py --create-missing
* fix(providers): remove morph, aider, kwaipilot
- morph: specialized code-editing/patching tool, not a general LLM provider
- aider: CLI meta-tool wrapper (base_url empty), redundant with claude-code/codex-cli/gemini-cli/qwen-code
- kwaipilot: Kwai internal coding assistant routed via OpenRouter, niche
* fix(sync): add morph/aider/kwaipilot to SKIP_PROVIDERS to prevent re-creation
* feat(sync): merge OpenRouter-only providers into openrouter.toml
Instead of generating standalone .toml files that just wrap the OpenRouter
endpoint, merge their models directly into openrouter.toml with the
standard 'openrouter/{provider}/{model}' ID convention.
- Add _build_model_fields() and _model_lines() helpers to deduplicate
model rendering between standalone and merged paths
- Add merge_into_openrouter() that appends new models idempotently
- generate_provider_toml() now only runs for providers in PROVIDER_API
- --create-missing routes OpenRouter-only providers to merge_into_openrouter
* fix(providers): remove 14 OpenRouter-only standalone files
These providers have no direct public API and all route through
openrouter.ai/api/v1. Per the new sync-pricing.py policy, their models
will be merged into openrouter.toml on the next CI run instead of
living in separate files that just wrap the OpenRouter endpoint.
Removed: allenai, deepcogito, essentialai, inclusionai, inflection,
liquid, meituan, nex-agi, nousresearch, prime-intellect, relace,
switchpoint, tngtech, writer
* fix(providers): remove 7 niche providers with no driver support
No dedicated LLM driver code exists for these providers — they rely
purely on OpenAI-compatible passthrough with no special handling.
Removing them reduces registry noise; users can still reach them via
openrouter.toml if needed.
Removed: microsoft, ibm-granite, xiaomi, upstage, inception, aion-labs, arcee-ai
* fix(providers): remove ai21, chutes, venice
All three use ApiFormat::OpenAI with no special handling — pure passthrough.
No registry entry needed; users can reach them via openrouter.toml or by
adding a custom provider.
* docs(providers): rewrite README with full provider catalog and inclusion criteria
- List all 46 providers grouped by category with descriptions
- Document why each provider exists (direct API, unique endpoint, dedicated driver, local, CLI)
- Add inclusion criteria section explaining when to create standalone files vs merging into openrouter.toml
- Document sync script routing logic
- Update model counts: 49→46 providers, 339→232 models
* docs: add comprehensive READMEs for all registry sections + deepinfra provider
- agents/README.md: 32 agents across 7 categories with capability field reference
- channels/README.md: 44 channels across 5 categories with protocol reference table
- hands/README.md: 18 hands across 5 categories with HAND.toml format guide
- mcp/README.md: 33 MCP servers across 5 categories with transport/auth format
- plugins/README.md: 12 plugins with hook protocol documentation
- skills/README.md: 60 skills across 9 categories with SKILL.md format guide
- providers/deepinfra.toml: add DeepInfra serverless inference (5 models)
This commit is contained in:
38 files changed
+1146
-1215
No files matched your search
@@ -11,8 +11,8 @@ This repository is the **single source of truth** for all installable content de
|
||||
| [Hands](#hands) | 14 | User-facing "apps" — agent + tools + settings + dashboard |
|
||||
| [Agents](#agents) | 32 | Autonomous agent definitions with model config and tools |
|
||||
| [MCP Servers](#mcp-servers) | 25 | MCP server connections (GitHub, Slack, DBs, etc.) |
|
||||
| [Providers](#providers) | 49 | LLM provider & model metadata with pricing |
|
||||
| [Models](#providers) | 339 | Individual model definitions across all providers |
|
||||
| [Providers](#providers) | 46 | LLM provider & model metadata with pricing |
|
||||
| [Models](#providers) | 232 | Individual model definitions across all providers |
|
||||
| [Aliases](#aliases) | 70 | Short names mapped to canonical model IDs |
|
||||
| [Plugins](#plugins) | 10 | Memory, guardrails, and conversation plugins |
|
||||
| [Skills](#skills) | 2 | Reusable prompt templates and Python scripts |
|
||||
@@ -44,7 +44,7 @@ librefang-registry/
|
||||
├── providers/ # LLM provider & model metadata
|
||||
│ ├── anthropic.toml
|
||||
│ ├── openai.toml
|
||||
│ └── ... (49 providers, 339 models)
|
||||
│ └── ... (46 providers, 232 models)
|
||||
├── plugins/ # Memory, guardrails, and utility plugins
|
||||
│ ├── episodic-memory/
|
||||
│ ├── guardrails/
|
||||
|
||||
+152
-37
@@ -1,63 +1,178 @@
|
||||
# Agents
|
||||
# Agents Registry
|
||||
|
||||
Autonomous agent definitions for LibreFang. Each agent is a directory containing an `agent.toml` manifest.
|
||||
Agent templates for LibreFang. Each entry is a ready-to-install agent definition with a pre-configured system prompt, model settings, capability declarations, and routing aliases.
|
||||
|
||||
## Structure
|
||||
These are the reference agents shipped with the registry. You can install them as-is, override individual fields (model, system_prompt, tools) after installation, or use them as `base` templates inside a Hand.
|
||||
|
||||
## File Format
|
||||
|
||||
Each agent lives in its own subdirectory containing a single `agent.toml`:
|
||||
|
||||
```
|
||||
agents/
|
||||
├── hello-world/agent.toml
|
||||
├── researcher/agent.toml
|
||||
├── coder/agent.toml
|
||||
├── coder/
|
||||
│ └── agent.toml
|
||||
├── orchestrator/
|
||||
│ └── agent.toml
|
||||
└── ...
|
||||
```
|
||||
|
||||
## agent.toml Format
|
||||
### agent.toml format
|
||||
|
||||
```toml
|
||||
name = "agent-name" # Must match directory name
|
||||
version = "0.1.0"
|
||||
description = "What this agent does"
|
||||
author = "author-name"
|
||||
module = "builtin:chat" # Runtime module
|
||||
|
||||
[model]
|
||||
provider = "default"
|
||||
model = "default"
|
||||
max_tokens = 4096
|
||||
temperature = 0.7
|
||||
system_prompt = """Behavioral instructions for the agent."""
|
||||
name = "coder" # must match directory name
|
||||
version = "0.4.3-beta3-20260314"
|
||||
description = "Expert software engineer. Reads, writes, and analyzes code."
|
||||
author = "librefang"
|
||||
module = "builtin:chat" # runtime module — builtin:chat for all current agents
|
||||
|
||||
[metadata.routing]
|
||||
aliases = ["exact match phrases"]
|
||||
weak_aliases = ["keyword hints"]
|
||||
aliases = ["write code", "fix bug", "implement feature"] # exact activation phrases
|
||||
weak_aliases = ["refactor", "patch", "code change"] # keyword hints
|
||||
|
||||
[model]
|
||||
provider = "default" # default = use LibreFang's configured primary provider
|
||||
model = "default"
|
||||
api_key_env = "GEMINI_API_KEY" # optional override: use this key env var
|
||||
max_tokens = 8192
|
||||
temperature = 0.3
|
||||
system_prompt = """You are Coder, an expert software engineer..."""
|
||||
|
||||
[[fallback_models]] # optional: try these providers on failure
|
||||
provider = "default"
|
||||
model = "default"
|
||||
api_key_env = "GROQ_API_KEY"
|
||||
|
||||
[schedule] # optional: continuous or cron activation
|
||||
continuous = { check_interval_secs = 120 }
|
||||
|
||||
[resources]
|
||||
max_llm_tokens_per_hour = 100000
|
||||
max_llm_tokens_per_hour = 200000
|
||||
max_concurrent_tools = 10
|
||||
|
||||
[capabilities]
|
||||
tools = ["web_search", "file_read"]
|
||||
network = ["*"]
|
||||
tools = ["file_read", "file_write", "file_list", "shell_exec", "web_search", "web_fetch",
|
||||
"memory_store", "memory_recall"]
|
||||
network = ["*"] # "*" = all, or list specific domains
|
||||
memory_read = ["*"]
|
||||
memory_write = ["self.*"]
|
||||
memory_write = ["self.*"] # "self.*" = own namespace only
|
||||
shell = ["cargo *", "rustc *", "git *", "npm *", "python *"] # shell command allowlist
|
||||
agent_spawn = false
|
||||
agent_message = [] # agents this agent may message
|
||||
|
||||
[i18n.zh]
|
||||
name = "编码工程师"
|
||||
description = "资深软件工程师:阅读、编写与分析代码。"
|
||||
```
|
||||
|
||||
## Current Agents (33)
|
||||
## Installing and Using Agents
|
||||
|
||||
| Agent | Description |
|
||||
|-------|-------------|
|
||||
| assistant | Default conversational assistant |
|
||||
| researcher | Deep research with web search |
|
||||
| coder | Code generation and editing |
|
||||
| hello-world | Friendly greeting agent for new users |
|
||||
| ... | See each directory for details |
|
||||
```bash
|
||||
# List all available agent templates
|
||||
librefang catalog agents
|
||||
|
||||
# Install an agent from the registry
|
||||
librefang agent install coder
|
||||
|
||||
# Install with a custom name
|
||||
librefang agent install coder --name my-coder
|
||||
|
||||
# List installed agents
|
||||
librefang agent list
|
||||
|
||||
# Send a message to an installed agent
|
||||
librefang agent message coder "Implement a binary search function in Rust"
|
||||
|
||||
# Remove an agent
|
||||
librefang agent remove my-coder
|
||||
```
|
||||
|
||||
Agents can also be used as base templates in a Hand by setting `base = "coder"` in `HAND.toml`.
|
||||
|
||||
## All Agents (33 total)
|
||||
|
||||
### Development
|
||||
|
||||
| Name | Description | Key Tools |
|
||||
|------|-------------|-----------|
|
||||
| architect | System architect. Designs software architectures, evaluates trade-offs, creates technical specifications. | file_read, file_write, web_search, web_fetch |
|
||||
| code-reviewer | Senior code reviewer. Reviews PRs, identifies issues, suggests improvements with production standards. | file_read, shell_exec, web_search |
|
||||
| coder | Expert software engineer. Reads, writes, and analyzes code. | file_read, file_write, shell_exec, web_search |
|
||||
| debugger | Expert debugger. Traces bugs, analyzes stack traces, performs root cause analysis. | file_read, shell_exec, web_search |
|
||||
| devops-lead | DevOps lead. Manages CI/CD, infrastructure, deployments, monitoring, and incident response. | shell_exec, file_read, web_search |
|
||||
| ops | DevOps agent. Monitors systems, runs diagnostics, manages deployments. | shell_exec, file_read, web_search |
|
||||
| test-engineer | Quality assurance engineer. Designs test strategies, writes tests, validates correctness. | file_read, file_write, shell_exec |
|
||||
|
||||
### Research and Analysis
|
||||
|
||||
| Name | Description | Key Tools |
|
||||
|------|-------------|-----------|
|
||||
| academic-researcher | Academic research agent. Searches scholarly papers, summarizes findings, and generates literature reviews. | web_search, web_fetch, file_write |
|
||||
| analyst | Data analyst. Processes data, generates insights, creates reports. | file_read, web_search, web_fetch |
|
||||
| data-scientist | Data scientist. Analyzes datasets, builds models, creates visualizations, performs statistical analysis. | file_read, file_write, shell_exec |
|
||||
| researcher | Research agent. Fetches web content and synthesizes information. | web_search, web_fetch, memory_store |
|
||||
|
||||
### Writing and Documentation
|
||||
|
||||
| Name | Description | Key Tools |
|
||||
|------|-------------|-----------|
|
||||
| doc-writer | Technical writer. Creates documentation, README files, API docs, tutorials, and architecture guides. | file_read, file_write, web_fetch |
|
||||
| writer | Content writer. Creates documentation, articles, and technical writing. | file_read, file_write, web_search |
|
||||
|
||||
### Orchestration
|
||||
|
||||
| Name | Description | Key Capabilities |
|
||||
|------|-------------|-----------------|
|
||||
| orchestrator | Meta-agent that decomposes complex tasks, delegates to specialist agents, and synthesizes results. | agent_spawn, agent_send, agent_list, agent_kill |
|
||||
| planner | Project planner. Creates project plans, breaks down epics, estimates effort, identifies risks and dependencies. | file_read, file_write, web_search |
|
||||
|
||||
### Business and Operations
|
||||
|
||||
| Name | Description | Key Tools |
|
||||
|------|-------------|-----------|
|
||||
| customer-support | Customer support agent for ticket handling, issue resolution, and customer communication. | memory_store, memory_recall, web_search |
|
||||
| email-assistant | Email triage, drafting, scheduling, and inbox management agent. | memory_store, memory_recall, file_write |
|
||||
| legal-assistant | Legal assistant agent for contract review, legal research, compliance checking, and document drafting. | file_read, file_write, web_search |
|
||||
| meeting-assistant | Meeting notes, action items, agenda preparation, and follow-up tracking agent. | memory_store, memory_recall, file_write |
|
||||
| recruiter | Recruiting agent for resume screening, candidate outreach, job description writing, and hiring pipeline management. | web_search, file_read, memory_store |
|
||||
| sales-assistant | Sales assistant agent for CRM updates, outreach drafting, pipeline management, and deal tracking. | memory_store, memory_recall, web_search |
|
||||
| security-auditor | Security specialist. Reviews code for vulnerabilities, checks configurations, performs threat modeling. | file_read, shell_exec, web_search |
|
||||
|
||||
### Personal Productivity
|
||||
|
||||
| Name | Description | Key Tools |
|
||||
|------|-------------|-----------|
|
||||
| assistant | General-purpose assistant agent. The default agent for everyday tasks, questions, and conversations. | file_read, file_write, web_search, memory_store |
|
||||
| health-tracker | Wellness tracking agent for health metrics, medication reminders, fitness goals, and lifestyle habits. | memory_store, memory_recall, file_write |
|
||||
| hello-world | A friendly greeting agent that can read files, search the web, and answer everyday questions. | file_read, web_search, web_fetch |
|
||||
| home-automation | Smart home control agent for IoT device management, automation rules, and home monitoring. | shell_exec, memory_store, web_fetch |
|
||||
| personal-finance | Personal finance agent for budget tracking, expense analysis, savings goals, and financial planning. | file_read, memory_store, web_search |
|
||||
| recipe-assistant | Cooking assistant that helps with recipes, meal plans, ingredient substitutions, and portion adjustments. | web_search, memory_recall, file_write |
|
||||
| social-media | Social media content creation, scheduling, and engagement strategy agent. | web_fetch, web_search, file_write |
|
||||
| translator | Multi-language translation agent for document translation, localization, and cross-cultural communication. | file_read, file_write, web_fetch |
|
||||
| travel-planner | Trip planning agent for itinerary creation, booking research, budget estimation, and travel logistics. | web_search, web_fetch, memory_store |
|
||||
| tutor | Teaching and explanation agent for learning, tutoring, and educational content creation. | web_search, memory_recall, file_write |
|
||||
|
||||
## Capability Reference
|
||||
|
||||
| Capability field | Values | Effect |
|
||||
|-----------------|--------|--------|
|
||||
| `tools` | list of tool names | Which built-in tools the agent may invoke |
|
||||
| `network` | `["*"]` or domain list | Outbound HTTP domain allowlist |
|
||||
| `memory_read` | `["*"]` or namespace list | Which memory namespaces the agent can read |
|
||||
| `memory_write` | `["self.*"]` or `["*"]` | Which memory namespaces the agent can write |
|
||||
| `shell` | glob patterns | Shell command allowlist (e.g. `"cargo *"`) |
|
||||
| `agent_spawn` | `true` / `false` | Whether the agent can spawn child agents |
|
||||
| `agent_message` | `["*"]` or agent name list | Which agents this agent may send messages to |
|
||||
|
||||
## Adding a New Agent
|
||||
|
||||
1. Create `agents/<name>/agent.toml`
|
||||
2. Ensure `name` matches the directory name
|
||||
3. Run `python scripts/validate.py`
|
||||
4. Submit a PR
|
||||
1. Create `agents/<name>/agent.toml` — `name` must match the directory name.
|
||||
2. Set `module = "builtin:chat"` unless you have a custom runtime module.
|
||||
3. Write a focused `system_prompt` — clear role definition, methodology, and constraints.
|
||||
4. Declare only the tools and capabilities the agent actually needs.
|
||||
5. Add `[metadata.routing]` aliases so the router can activate the agent by intent.
|
||||
6. Run `python scripts/validate.py`.
|
||||
7. Submit a PR.
|
||||
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide.
|
||||
+142
-3
@@ -1,7 +1,146 @@
|
||||
# Channel Adapters Registry
|
||||
|
||||
This directory contains TOML metadata files for all supported LibreFang channel adapters.
|
||||
Channel adapters connect LibreFang agents to external messaging platforms. Each adapter in this directory is a flat `.toml` file describing the platform, its communication protocol, and any credentials required to operate.
|
||||
|
||||
Each `.toml` file describes a single channel adapter including its name, description, category, protocol, and relevant links. These files are used by the LibreFang registry to discover and display available channel integrations.
|
||||
Once a channel is configured, agents can receive messages from and send messages to that platform without any code changes — the adapter handles protocol translation.
|
||||
|
||||
See `../templates/channel.toml` for the file format template.
|
||||
## File Format
|
||||
|
||||
Each channel is a single `.toml` file. The filename (without `.toml`) must match the `id` field.
|
||||
|
||||
```toml
|
||||
id = "telegram"
|
||||
name = "Telegram"
|
||||
description = "Telegram Bot API adapter for sending and receiving messages"
|
||||
category = "messaging" # messaging | enterprise | social | developer | iot
|
||||
tags = ["popular"]
|
||||
icon = "lucide:smartphone"
|
||||
protocol = "bot-api" # see Protocol Reference below
|
||||
|
||||
[i18n.zh]
|
||||
name = "Telegram"
|
||||
description = "Telegram Bot API 适配器,收发消息"
|
||||
|
||||
[metadata]
|
||||
url = "https://telegram.org"
|
||||
docs = "https://core.telegram.org/bots/api"
|
||||
```
|
||||
|
||||
## Protocol Reference
|
||||
|
||||
| Protocol | Description |
|
||||
|----------|-------------|
|
||||
| `bot-api` | Platform-specific bot HTTP API (e.g. Telegram Bot API) |
|
||||
| `websocket` | Long-lived WebSocket connection (e.g. Slack RTM, Discord Gateway) |
|
||||
| `webhook` | Agent receives POST requests from the platform |
|
||||
| `rest-api` | Polling or push via generic HTTP REST |
|
||||
| `imap` | Email protocols (IMAP for receive, SMTP for send) |
|
||||
| `irc` | Internet Relay Chat protocol |
|
||||
| `matrix` | Matrix client-server API |
|
||||
| `mqtt` | MQTT pub/sub protocol for IoT messaging |
|
||||
| `xmpp` | Extensible Messaging and Presence Protocol |
|
||||
|
||||
## Configuring a Channel
|
||||
|
||||
```bash
|
||||
# List all available channel adapters
|
||||
librefang catalog channels
|
||||
|
||||
# Install a channel adapter
|
||||
librefang channel install telegram
|
||||
|
||||
# Configure credentials for a channel
|
||||
librefang channel configure telegram
|
||||
|
||||
# Attach a channel to an agent
|
||||
librefang channel attach telegram --agent assistant
|
||||
|
||||
# List configured channels
|
||||
librefang channel list
|
||||
|
||||
# Remove a channel
|
||||
librefang channel remove telegram
|
||||
```
|
||||
|
||||
## All Channel Adapters (45 total)
|
||||
|
||||
### Messaging
|
||||
|
||||
| ID | Name | Protocol | Description |
|
||||
|----|------|----------|-------------|
|
||||
| discord | Discord | websocket | Discord bot adapter for sending and receiving messages in Discord servers and channels |
|
||||
| email | Email | imap | Email adapter for sending and receiving messages via SMTP and IMAP protocols |
|
||||
| irc | IRC | irc | IRC adapter for connecting to Internet Relay Chat networks and channels |
|
||||
| keybase | Keybase | rest-api | Keybase adapter for encrypted messaging via the Keybase chat API |
|
||||
| line | LINE | webhook | LINE Messaging API adapter for sending and receiving messages on the LINE platform |
|
||||
| matrix | Matrix | matrix | Matrix adapter for decentralized messaging via the Matrix client-server API |
|
||||
| messenger | Facebook Messenger | webhook | Facebook Messenger adapter for sending and receiving messages via the Messenger Platform |
|
||||
| nostr | Nostr | websocket | Nostr adapter for publishing and reading events on the Nostr decentralized protocol |
|
||||
| qq | QQ | websocket | QQ bot adapter for messaging within Tencent QQ groups and channels |
|
||||
| signal | Signal | rest-api | Signal adapter for secure end-to-end encrypted messaging via Signal CLI |
|
||||
| telegram | Telegram | bot-api | Telegram Bot API adapter for sending and receiving messages |
|
||||
| threema | Threema | rest-api | Threema Gateway adapter for secure messaging via the Threema platform |
|
||||
| viber | Viber | webhook | Viber bot adapter for sending and receiving messages via the Viber Bot API |
|
||||
| wechat | WeChat | rest-api | WeChat Official Account adapter for messaging on the WeChat platform |
|
||||
| whatsapp | WhatsApp | rest-api | WhatsApp Business API adapter for sending and receiving messages on WhatsApp |
|
||||
| xmpp | XMPP | xmpp | XMPP adapter for messaging via the Extensible Messaging and Presence Protocol |
|
||||
|
||||
### Enterprise
|
||||
|
||||
| ID | Name | Protocol | Description |
|
||||
|----|------|----------|-------------|
|
||||
| dingtalk | DingTalk | webhook | DingTalk bot adapter for sending messages to DingTalk groups and conversations |
|
||||
| feishu | Feishu (Lark) | webhook | Feishu (Lark) bot adapter for messaging within the Feishu collaboration platform |
|
||||
| flock | Flock | webhook | Flock bot adapter for team messaging and notifications in Flock workspaces |
|
||||
| google_chat | Google Chat | webhook | Google Chat adapter for sending messages and cards to Google Workspace conversations |
|
||||
| guilded | Guilded | websocket | Guilded bot adapter for messaging in Guilded servers and channels |
|
||||
| mattermost | Mattermost | websocket | Mattermost adapter for team messaging and notifications in Mattermost workspaces |
|
||||
| pumble | Pumble | webhook | Pumble adapter for team messaging and notifications in Pumble workspaces |
|
||||
| rocketchat | Rocket.Chat | rest-api | Rocket.Chat adapter for messaging in self-hosted Rocket.Chat instances |
|
||||
| slack | Slack | websocket | Slack bot adapter for sending and receiving messages in Slack workspaces |
|
||||
| teams | Microsoft Teams | webhook | Microsoft Teams adapter for messaging and notifications in Teams channels |
|
||||
| twist | Twist | rest-api | Twist adapter for async team communication in Twist workspaces |
|
||||
| webex | Cisco Webex | webhook | Cisco Webex adapter for messaging and notifications in Webex spaces |
|
||||
| wecom | WeCom (WeChat Work) | webhook | WeCom (WeChat Work) adapter for enterprise messaging within WeCom organizations |
|
||||
| zulip | Zulip | rest-api | Zulip adapter for topic-based team messaging in Zulip organizations |
|
||||
|
||||
### Social
|
||||
|
||||
| ID | Name | Protocol | Description |
|
||||
|----|------|----------|-------------|
|
||||
| bluesky | Bluesky | rest-api | Bluesky AT Protocol adapter for posting and reading from the decentralized social network |
|
||||
| linkedin | LinkedIn | rest-api | LinkedIn adapter for posting updates and messages via the LinkedIn API |
|
||||
| mastodon | Mastodon | rest-api | Mastodon adapter for posting toots and reading timelines on Mastodon instances |
|
||||
| reddit | Reddit | rest-api | Reddit adapter for posting and reading content via the Reddit API |
|
||||
| twitch | Twitch | irc | Twitch adapter for reading and sending messages in Twitch stream chats |
|
||||
|
||||
### Developer
|
||||
|
||||
| ID | Name | Protocol | Description |
|
||||
|----|------|----------|-------------|
|
||||
| discourse | Discourse | rest-api | Discourse forum adapter for posting topics and replies via the Discourse API |
|
||||
| gitter | Gitter | rest-api | Gitter adapter for developer chat rooms linked to GitHub repositories |
|
||||
| revolt | Revolt | websocket | Revolt adapter for messaging in the open-source Revolt chat platform |
|
||||
| webhook | Webhook | webhook | Generic webhook adapter for sending and receiving messages via HTTP callbacks |
|
||||
|
||||
### IoT / Self-Hosted
|
||||
|
||||
| ID | Name | Protocol | Description |
|
||||
|----|------|----------|-------------|
|
||||
| gotify | Gotify | rest-api | Gotify adapter for sending push notifications to a self-hosted Gotify server |
|
||||
| mqtt | MQTT | mqtt | MQTT adapter for publishing and subscribing to messages on MQTT brokers |
|
||||
| mumble | Mumble | websocket | Mumble adapter for text messaging in Mumble voice communication servers |
|
||||
| nextcloud | Nextcloud Talk | rest-api | Nextcloud Talk adapter for messaging within self-hosted Nextcloud instances |
|
||||
| ntfy | ntfy | rest-api | ntfy adapter for sending push notifications via the ntfy pub-sub service |
|
||||
|
||||
## Adding a New Channel Adapter
|
||||
|
||||
1. Create `channels/<name>.toml` — the filename must match the `id` field.
|
||||
2. Set `category` to one of: `messaging`, `enterprise`, `social`, `developer`, `iot`.
|
||||
3. Set `protocol` to the appropriate value from the Protocol Reference table above.
|
||||
4. Add `[metadata]` with `url` and `docs` links.
|
||||
5. Add `[i18n.*]` blocks for supported locales.
|
||||
6. Run `python scripts/validate.py`.
|
||||
7. Submit a PR.
|
||||
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide.
|
||||
+164
-97
@@ -1,130 +1,197 @@
|
||||
# Hands
|
||||
# Hands Registry
|
||||
|
||||
Hand definitions for LibreFang. Hands are pre-packaged capability bundles that compose **agents**, **tools**, **skills**, **MCP servers**, **workflows**, and **plugins** into a working application.
|
||||
Hands are pre-packaged capability bundles that compose agents, tools, skills, MCP servers, and plugins into a working application. Installing a hand gives you a complete, ready-to-use workflow — not just a single agent.
|
||||
|
||||
> "You have many hands helping you."
|
||||
|
||||
## Structure
|
||||
A hand can contain one agent (single-agent) or multiple coordinated agents (multi-agent). Each agent in a multi-agent hand can have its own role-specific skills, model config, and capability restrictions.
|
||||
|
||||
## File Format
|
||||
|
||||
Each hand lives in its own subdirectory:
|
||||
|
||||
```
|
||||
hands/
|
||||
├── researcher/
|
||||
│ ├── HAND.toml # required: hand definition
|
||||
│ └── SKILL.md # optional: shared reference knowledge for all agents
|
||||
├── devteam/
|
||||
│ ├── HAND.toml # Hand definition
|
||||
│ ├── SKILL-pm.md # Per-agent reference knowledge (PM)
|
||||
│ ├── SKILL-engineer.md # Per-agent reference knowledge (Engineer)
|
||||
│ └── SKILL-qa.md # Per-agent reference knowledge (QA)
|
||||
├── browser/
|
||||
│ ├── HAND.toml
|
||||
│ └── SKILL.md # Shared reference knowledge (all agents)
|
||||
└── ...
|
||||
│ ├── SKILL-pm.md # optional: role-specific knowledge for PM agent
|
||||
│ ├── SKILL-engineer.md # optional: role-specific knowledge for Engineer agent
|
||||
│ └── SKILL-qa.md # optional: role-specific knowledge for QA agent
|
||||
```
|
||||
|
||||
## Composition Model
|
||||
|
||||
A hand composes registry resources — it doesn't reinvent them:
|
||||
|
||||
| Resource | How to compose | Example |
|
||||
|----------|----------------|---------|
|
||||
| **Agent templates** | `base = "coder"` on `[agents.*]` | Inherit prompt, model config, fallbacks from `agents/coder/agent.toml` |
|
||||
| **Tools** | `tools = [...]` at hand level | All agents get these built-in tools |
|
||||
| **Skills** | `skills = [...]` at hand level | Skill allowlist (empty = all) |
|
||||
| **MCP servers** | `mcp_servers = [...]` at hand level | Agent interacts via MCP tools, not hardcoded API calls |
|
||||
| **Workflows** | `workflow_run` tool in agent prompts | Agent calls `workflow_run bug-triage` at runtime |
|
||||
| **Plugins** | `allowed_plugins = [...]` at hand level | Plugin allowlist (empty = all) |
|
||||
| **Per-agent skills** | `SKILL-{role}.md` files | Different reference knowledge per agent role |
|
||||
| **Per-agent capabilities** | `[agents.*.capabilities]` | Fine-grained shell/network/memory per agent |
|
||||
|
||||
## HAND.toml Format
|
||||
### HAND.toml format
|
||||
|
||||
```toml
|
||||
id = "hand-id"
|
||||
name = "Hand Name"
|
||||
description = "What this hand does"
|
||||
category = "development"
|
||||
icon = "🔧"
|
||||
id = "researcher"
|
||||
version = "1.1.1"
|
||||
name = "Researcher Hand"
|
||||
description = "Autonomous deep researcher — exhaustive investigation, cross-referencing, fact-checking, and structured reports"
|
||||
category = "productivity" # productivity | development | data | content | communication
|
||||
icon = "lucide:flask-conical"
|
||||
|
||||
# ─── Resource composition ────────────────────────────────────
|
||||
tools = ["shell_exec", "file_read", "web_fetch", "workflow_run"]
|
||||
mcp_servers = ["github", "sentry"]
|
||||
skills = [] # empty = all
|
||||
allowed_plugins = ["todo-tracker"]
|
||||
# Tools available to all agents in this hand
|
||||
tools = [
|
||||
"shell_exec", "file_read", "file_write", "web_fetch", "web_search",
|
||||
"memory_store", "memory_recall", "knowledge_query", "event_publish",
|
||||
]
|
||||
|
||||
# ─── Requirements ────────────────────────────────────────────
|
||||
[[requires]]
|
||||
key = "git"
|
||||
requirement_type = "binary"
|
||||
check_value = "git"
|
||||
# MCP servers all agents can use
|
||||
mcp_servers = ["github"]
|
||||
|
||||
# ─── Settings ────────────────────────────────────────────────
|
||||
[[settings]]
|
||||
key = "repo_url"
|
||||
setting_type = "text"
|
||||
default = ""
|
||||
# Skills allowlist (empty = all available)
|
||||
skills = []
|
||||
|
||||
# ─── Agents ──────────────────────────────────────────────────
|
||||
# Plugin allowlist
|
||||
allowed_plugins = ["todo-tracker", "auto-summarizer"]
|
||||
|
||||
# Multi-agent with base template inheritance:
|
||||
[agents.main]
|
||||
coordinator = true
|
||||
base = "planner" # inherits from agents/planner/agent.toml
|
||||
invoke_hint = "Task coordination"
|
||||
|
||||
[agents.main.model]
|
||||
system_prompt = """Custom prompt for this hand..."""
|
||||
|
||||
[agents.main.capabilities]
|
||||
shell = ["gh *", "git *"] # preserved by kernel (not overwritten)
|
||||
|
||||
# Single-agent (legacy):
|
||||
# [agent]
|
||||
# name = "my-agent"
|
||||
# system_prompt = """..."""
|
||||
|
||||
# ─── Routing ─────────────────────────────────────────────────
|
||||
# ─── Routing ──────────────────────────────────────────────────────────────────
|
||||
[routing]
|
||||
aliases = ["activate phrases"]
|
||||
weak_aliases = ["keyword hints"]
|
||||
aliases = ["deep research", "investigate", "fact check"] # exact activation phrases
|
||||
weak_aliases = ["research", "look into"] # keyword hints
|
||||
|
||||
# ─── Dashboard ───────────────────────────────────────────────
|
||||
# ─── Configurable settings ────────────────────────────────────────────────────
|
||||
[[settings]]
|
||||
key = "research_depth"
|
||||
label = "Research Depth"
|
||||
description = "How exhaustive each investigation should be"
|
||||
setting_type = "select" # select | toggle | text
|
||||
default = "thorough"
|
||||
|
||||
[[settings.options]]
|
||||
value = "quick"
|
||||
label = "Quick (5-10 sources, 1 pass)"
|
||||
|
||||
[[settings.options]]
|
||||
value = "thorough"
|
||||
label = "Thorough (20-30 sources, cross-referenced)"
|
||||
|
||||
# ─── Single-agent definition ──────────────────────────────────────────────────
|
||||
[agent]
|
||||
name = "researcher"
|
||||
base = "researcher" # inherits from agents/researcher/agent.toml
|
||||
|
||||
[agent.model]
|
||||
system_prompt = """Custom prompt override..."""
|
||||
|
||||
# ─── Multi-agent definition (alternative to [agent]) ─────────────────────────
|
||||
[agents.pm]
|
||||
coordinator = true
|
||||
base = "planner" # inherits from agents/planner/agent.toml
|
||||
invoke_hint = "Task coordination and issue triage"
|
||||
|
||||
[agents.engineer]
|
||||
base = "coder"
|
||||
invoke_hint = "Implementation"
|
||||
|
||||
[agents.qa]
|
||||
base = "test-engineer"
|
||||
invoke_hint = "Quality assurance and validation"
|
||||
|
||||
# ─── Dashboard metrics ────────────────────────────────────────────────────────
|
||||
[dashboard]
|
||||
[[dashboard.metrics]]
|
||||
label = "Tasks Done"
|
||||
memory_key = "metric_key"
|
||||
label = "Reports Written"
|
||||
memory_key = "metric_reports_written"
|
||||
format = "number"
|
||||
|
||||
# ─── i18n ────────────────────────────────────────────────────
|
||||
# ─── i18n ─────────────────────────────────────────────────────────────────────
|
||||
[i18n.zh]
|
||||
name = "中文名"
|
||||
description = "中文描述"
|
||||
name = "研究员"
|
||||
description = "自主深度研究员 — 详尽调查、交叉核实、事实核查与结构化报告"
|
||||
```
|
||||
|
||||
## Current Hands (15)
|
||||
## Installing and Using Hands
|
||||
|
||||
| Hand | Category | Agents | Description |
|
||||
|------|----------|--------|-------------|
|
||||
| analytics | data | multi | Data analytics, visualization, and automated reporting |
|
||||
| apitester | development | single | API testing, endpoint discovery, and load testing |
|
||||
| browser | productivity | single | Web navigation, form filling, and multi-step web tasks |
|
||||
| clip | content | multi | Long-form video to short clips with captions |
|
||||
| collector | data | multi | Intelligence collection and change detection |
|
||||
| **devteam** | **development** | **multi** | **Autonomous dev team — PM + Engineer + QA with base templates** |
|
||||
| devops | development | multi | CI/CD management, monitoring, and incident response |
|
||||
| lead | data | multi | Lead generation, enrichment, and scoring |
|
||||
| linkedin | communication | multi | LinkedIn content creation and networking |
|
||||
| predictor | data | single | Signal collection and calibrated predictions |
|
||||
| reddit | communication | multi | Subreddit monitoring and content posting |
|
||||
| researcher | productivity | multi | Deep research, fact-checking, and reports |
|
||||
| strategist | productivity | multi | Market research and competitive analysis |
|
||||
| trader | data | multi | Market intelligence and risk management |
|
||||
| twitter | communication | multi | Twitter/X content creation and scheduling |
|
||||
```bash
|
||||
# List all available hands
|
||||
librefang catalog hands
|
||||
|
||||
# Install a hand
|
||||
librefang hand install researcher
|
||||
|
||||
# Install with a specific agent name
|
||||
librefang hand install researcher --name my-researcher
|
||||
|
||||
# List installed hands
|
||||
librefang hand list
|
||||
|
||||
# Remove a hand
|
||||
librefang hand remove my-researcher
|
||||
```
|
||||
|
||||
## All Hands (18 total)
|
||||
|
||||
### Productivity
|
||||
|
||||
| ID | Name | Category | Description |
|
||||
|----|------|----------|-------------|
|
||||
| researcher | Researcher Hand | productivity | Autonomous deep researcher — exhaustive investigation, cross-referencing, fact-checking, and structured reports |
|
||||
| strategist | Strategist Hand | productivity | Autonomous strategy analyst — market research, competitive analysis, business planning, and strategic recommendations |
|
||||
| wiki | Wiki Hand | productivity | LLM-maintained personal knowledge base — builds an Obsidian-compatible wiki from raw sources with provenance tracking |
|
||||
| browser | Browser Hand | productivity | Autonomous web browser — navigates sites, fills forms, clicks buttons, and completes multi-step web tasks |
|
||||
|
||||
### Development
|
||||
|
||||
| ID | Name | Category | Description |
|
||||
|----|------|----------|-------------|
|
||||
| devteam | Dev Team | development | Autonomous software development team — PM triages issues, Engineer implements, QA validates |
|
||||
| devops | DevOps Hand | development | Autonomous DevOps engineer — CI/CD management, infrastructure monitoring, deployment automation, and incident response |
|
||||
| apitester | API Tester Hand | development | Autonomous API testing agent — endpoint discovery, request validation, load testing, and regression detection |
|
||||
|
||||
### Data
|
||||
|
||||
| ID | Name | Category | Description |
|
||||
|----|------|----------|-------------|
|
||||
| analytics | Analytics Hand | data | Autonomous data analytics agent — data collection, analysis, visualization, dashboards, and automated reporting |
|
||||
| collector | Collector Hand | data | Autonomous intelligence collector — monitors any target continuously with change detection and knowledge graphs |
|
||||
| lead | Lead Hand | data | Autonomous lead generation — discovers, enriches, and delivers qualified leads on a schedule |
|
||||
| predictor | Predictor Hand | data | Autonomous future predictor — collects signals, builds reasoning chains, makes calibrated predictions, and tracks accuracy |
|
||||
| trader | Trading Hand | data | Autonomous market intelligence and trading engine — multi-signal analysis, adversarial bull/bear reasoning, and strict risk management |
|
||||
|
||||
### Content
|
||||
|
||||
| ID | Name | Category | Description |
|
||||
|----|------|----------|-------------|
|
||||
| clip | Clip Hand | content | Turns long-form video into viral short clips with captions and thumbnails |
|
||||
| creator | Creator Hand | content | AI media studio — generates images, videos, music, and speech from text prompts |
|
||||
|
||||
### Communication
|
||||
|
||||
| ID | Name | Category | Description |
|
||||
|----|------|----------|-------------|
|
||||
| linkedin | LinkedIn Hand | communication | Autonomous LinkedIn manager — profile optimization, content creation, networking, and professional engagement |
|
||||
| reddit | Reddit Hand | communication | Autonomous Reddit manager — monitors subreddits, posts content, replies to threads, and tracks engagement |
|
||||
| twitter | Twitter Hand | communication | Autonomous Twitter/X manager — content creation, scheduled posting, engagement, and performance tracking |
|
||||
|
||||
### Data (additional)
|
||||
|
||||
| ID | Name | Category | Description |
|
||||
|----|------|----------|-------------|
|
||||
| clip | Clip Hand | content | Turns long-form video into viral short clips with captions and thumbnails |
|
||||
|
||||
## Resource Composition Summary
|
||||
|
||||
| Resource | How to compose | Notes |
|
||||
|----------|----------------|-------|
|
||||
| Agent templates | `base = "coder"` on `[agents.*]` | Inherits prompt, model config, fallbacks from `agents/coder/agent.toml` |
|
||||
| Tools | `tools = [...]` at hand level | All agents in the hand share these built-in tools |
|
||||
| Skills | `skills = [...]` at hand level | Empty list means all available skills are allowed |
|
||||
| MCP servers | `mcp_servers = [...]` at hand level | Agent interacts via MCP tools, not hardcoded API calls |
|
||||
| Plugins | `allowed_plugins = [...]` at hand level | Empty list means all installed plugins are allowed |
|
||||
| Per-agent knowledge | `SKILL-{role}.md` files | Different reference prompts per agent role |
|
||||
| Per-agent capabilities | `[agents.*.capabilities]` | Fine-grained shell / network / memory per agent |
|
||||
|
||||
## Adding a New Hand
|
||||
|
||||
1. Create `hands/<name>/HAND.toml`
|
||||
2. Add `SKILL.md` (shared) or `SKILL-{role}.md` (per-agent) for reference knowledge
|
||||
3. Use `base = "agent-name"` to inherit from existing agent templates in `agents/`
|
||||
4. Set `mcp_servers`, `skills`, `allowed_plugins` for resource composition
|
||||
5. Ensure `id` matches the directory name
|
||||
6. Submit a PR
|
||||
1. Create `hands/<name>/HAND.toml` with at least `id`, `name`, `description`, and `category`.
|
||||
2. Add `SKILL.md` (shared) or `SKILL-{role}.md` (per-agent) files for reference knowledge.
|
||||
3. Use `base = "agent-name"` in each `[agents.*]` block to inherit from existing agent templates.
|
||||
4. Specify `mcp_servers`, `skills`, and `allowed_plugins` for resource composition.
|
||||
5. Ensure `id` matches the directory name.
|
||||
6. Run `python scripts/validate.py`.
|
||||
7. Submit a PR.
|
||||
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide.
|
||||
+121
-43
@@ -1,70 +1,148 @@
|
||||
# MCP Servers
|
||||
# MCP Servers Registry
|
||||
|
||||
MCP (Model Context Protocol) server templates for LibreFang. Each entry connects LibreFang to an external service (GitHub, Slack, databases, etc.).
|
||||
MCP (Model Context Protocol) servers connect LibreFang agents to external services. Each entry in this directory is a single `.toml` file describing an MCP server: how to launch it, what credentials it requires, and which category of functionality it provides.
|
||||
|
||||
## Structure
|
||||
When an agent has an MCP server attached, the server's tools appear automatically in the agent's tool list alongside built-in tools like `file_read` and `web_search`.
|
||||
|
||||
```
|
||||
mcp/
|
||||
├── github.toml
|
||||
├── slack.toml
|
||||
├── postgresql.toml
|
||||
└── ...
|
||||
```
|
||||
## File Format
|
||||
|
||||
## MCP Server TOML Format
|
||||
Each MCP server is a flat `.toml` file. The filename (without `.toml`) must match the `id` field.
|
||||
|
||||
```toml
|
||||
id = "service-id" # Must match filename (without .toml)
|
||||
name = "Service Name"
|
||||
description = "What this MCP server provides"
|
||||
category = "devtools" # devtools | communication | storage | monitoring | data
|
||||
icon = "🐙"
|
||||
tags = ["relevant", "tags"]
|
||||
id = "github" # must match filename
|
||||
name = "GitHub"
|
||||
description = "Access GitHub repos, issues, PRs, and organizations"
|
||||
category = "devtools" # devtools | data | cloud | communication | productivity | ai
|
||||
icon = "lucide:github"
|
||||
tags = ["git", "vcs", "code"]
|
||||
|
||||
[transport] # MCP server transport config
|
||||
type = "stdio" # "stdio" or "sse"
|
||||
[transport]
|
||||
type = "stdio" # stdio | sse
|
||||
command = "npx"
|
||||
args = ["-y", "@pkg/mcp-server"]
|
||||
args = ["-y", "@modelcontextprotocol/server-github@2025.4.8"]
|
||||
|
||||
[[required_env]] # Required environment variables
|
||||
name = "SERVICE_API_KEY"
|
||||
label = "API Key"
|
||||
help = "How to obtain this key"
|
||||
[[required_env]] # repeat block for each required credential
|
||||
name = "GITHUB_PERSONAL_ACCESS_TOKEN"
|
||||
label = "GitHub Personal Access Token"
|
||||
help = "A fine-grained or classic PAT with repo and read:org scopes"
|
||||
is_secret = true
|
||||
get_url = "https://..."
|
||||
get_url = "https://github.com/settings/tokens"
|
||||
|
||||
[oauth] # Optional: OAuth config
|
||||
[oauth] # optional: OAuth flow config
|
||||
provider = "github"
|
||||
scopes = ["repo"]
|
||||
auth_url = "https://..."
|
||||
token_url = "https://..."
|
||||
scopes = ["repo", "read:org"]
|
||||
auth_url = "https://github.com/login/oauth/authorize"
|
||||
token_url = "https://github.com/login/oauth/access_token"
|
||||
|
||||
[health_check]
|
||||
interval_secs = 60
|
||||
unhealthy_threshold = 3
|
||||
|
||||
setup_instructions = """
|
||||
Step-by-step setup guide for users.
|
||||
1. Go to https://github.com/settings/tokens and create a Personal Access Token.
|
||||
2. Paste the token into the GITHUB_PERSONAL_ACCESS_TOKEN field.
|
||||
3. Alternatively, use the OAuth flow to authorize LibreFang directly.
|
||||
"""
|
||||
|
||||
[i18n.zh]
|
||||
name = "GitHub"
|
||||
description = "通过官方 MCP 服务器访问 GitHub 仓库、Issue、Pull Request 与组织。"
|
||||
```
|
||||
|
||||
## Current MCP Servers (25)
|
||||
## Installing an MCP Server
|
||||
|
||||
| MCP Server | Category | Service |
|
||||
|------------|----------|---------|
|
||||
| github | devtools | GitHub repos, issues, PRs |
|
||||
| slack | communication | Slack messaging |
|
||||
| notion | productivity | Notion pages and databases |
|
||||
| postgresql | storage | PostgreSQL database |
|
||||
| ... | | See each file for details |
|
||||
```bash
|
||||
# List all available MCP servers
|
||||
librefang catalog mcp
|
||||
|
||||
# Install an MCP server and attach it to an agent
|
||||
librefang mcp install github
|
||||
librefang mcp attach github --agent coder
|
||||
|
||||
# Or specify the agent when installing
|
||||
librefang mcp install github --agent coder
|
||||
|
||||
# Set required credentials
|
||||
librefang config set-env GITHUB_PERSONAL_ACCESS_TOKEN ghp_xxx
|
||||
|
||||
# List attached MCP servers for an agent
|
||||
librefang mcp list --agent coder
|
||||
|
||||
# Remove an MCP server from an agent
|
||||
librefang mcp detach github --agent coder
|
||||
```
|
||||
|
||||
## All MCP Servers (33 total)
|
||||
|
||||
### Development Tools (devtools)
|
||||
|
||||
| ID | Name | Transport | Credentials Required | Description |
|
||||
|----|------|-----------|---------------------|-------------|
|
||||
| bitbucket | Bitbucket | stdio (npx) | `BITBUCKET_*` | Access Bitbucket repositories, pull requests, and pipelines |
|
||||
| fetch | Fetch | stdio (npx) | none | Fetch any web URL and receive its content as clean Markdown |
|
||||
| filesystem | Filesystem | stdio (npx) | none | Read, write, search, and manage local files |
|
||||
| git | Git | stdio (npx) | none | Inspect local Git repos — commits, diffs, branches, blame |
|
||||
| github | GitHub | stdio (npx) | `GITHUB_PERSONAL_ACCESS_TOKEN` | Access GitHub repos, issues, PRs, and organizations |
|
||||
| gitlab | GitLab | stdio (npx) | `GITLAB_*` | Access GitLab projects, MRs, issues, and CI/CD pipelines |
|
||||
| jira | Jira | stdio (npx) | `JIRA_*` | Access Jira issues, projects, boards, and sprints |
|
||||
| linear | Linear | stdio (npx) | `LINEAR_API_KEY` | Manage Linear issues, projects, cycles, and teams |
|
||||
| puppeteer | Puppeteer | stdio (npx) | none | Control headless Chrome — navigate, screenshot, scrape |
|
||||
| sentry | Sentry | stdio (npx) | `SENTRY_AUTH_TOKEN` | Monitor Sentry error tracking, issues, and releases |
|
||||
|
||||
### Data
|
||||
|
||||
| ID | Name | Transport | Credentials Required | Description |
|
||||
|----|------|-----------|---------------------|-------------|
|
||||
| elasticsearch | Elasticsearch | stdio (npx) | `ELASTICSEARCH_*` | Search and manage Elasticsearch indices and documents |
|
||||
| google-maps | Google Maps | stdio (npx) | `GOOGLE_MAPS_API_KEY` | Geocoding, directions, distance matrix, and place search |
|
||||
| mongodb | MongoDB | stdio (npx) | `MONGODB_CONNECTION_STRING` | Query and manage MongoDB databases and collections |
|
||||
| postgresql | PostgreSQL | stdio (npx) | `POSTGRES_CONNECTION_STRING` | Query and manage PostgreSQL databases |
|
||||
| redis | Redis | stdio (npx) | `REDIS_URL` | Access and manage Redis key-value stores |
|
||||
| sqlite-mcp | SQLite | stdio (npx) | none | Query and manage local SQLite databases |
|
||||
|
||||
### Cloud
|
||||
|
||||
| ID | Name | Transport | Credentials Required | Description |
|
||||
|----|------|-----------|---------------------|-------------|
|
||||
| aws | AWS | stdio (npx) | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` | Manage S3, EC2, Lambda, and other AWS resources |
|
||||
| azure-mcp | Azure | stdio (npx) | `AZURE_*` | Manage Azure VMs, Storage, and App Services |
|
||||
| gcp-mcp | GCP | stdio (npx) | `GOOGLE_APPLICATION_CREDENTIALS` | Manage GCP Compute, Cloud Storage, and BigQuery |
|
||||
|
||||
### Communication
|
||||
|
||||
| ID | Name | Transport | Credentials Required | Description |
|
||||
|----|------|-----------|---------------------|-------------|
|
||||
| discord-mcp | Discord | stdio (npx) | `DISCORD_TOKEN` | Access Discord servers, channels, and messages |
|
||||
| slack | Slack | stdio (npx) | `SLACK_BOT_TOKEN` | Access Slack channels, messages, and users |
|
||||
| teams-mcp | Microsoft Teams | stdio (npx) | `TEAMS_*` | Access Teams channels, chats, and messages |
|
||||
|
||||
### Productivity
|
||||
|
||||
| ID | Name | Transport | Credentials Required | Description |
|
||||
|----|------|-----------|---------------------|-------------|
|
||||
| dropbox | Dropbox | stdio (npx) | `DROPBOX_ACCESS_TOKEN` | Access and manage Dropbox files and folders |
|
||||
| gmail | Gmail | stdio (npx) | `GMAIL_*` | Read, send, and manage Gmail messages and drafts |
|
||||
| google-calendar | Google Calendar | stdio (npx) | `GOOGLE_*` | Manage Google Calendar events and availability |
|
||||
| google-drive | Google Drive | stdio (npx) | `GOOGLE_*` | Browse, search, and read files from Google Drive |
|
||||
| notion | Notion | stdio (npx) | `NOTION_API_KEY` | Access and manage Notion pages, databases, and blocks |
|
||||
| time | Time | stdio (npx) | none | Get current time, convert timezones, calculate differences |
|
||||
| todoist | Todoist | stdio (npx) | `TODOIST_API_TOKEN` | Manage Todoist tasks, projects, and labels |
|
||||
|
||||
### AI
|
||||
|
||||
| ID | Name | Transport | Credentials Required | Description |
|
||||
|----|------|-----------|---------------------|-------------|
|
||||
| brave-search | Brave Search | stdio (npx) | `BRAVE_API_KEY` | Perform web searches using the Brave Search API |
|
||||
| exa-search | Exa Search | stdio (npx) | `EXA_API_KEY` | AI-powered neural search and web content retrieval |
|
||||
| memory | Memory | stdio (npx) | none | Persistent knowledge graph for facts and relationships across sessions |
|
||||
| sequential-thinking | Sequential Thinking | stdio (npx) | none | Structured multi-step reasoning with revisable thought chains |
|
||||
|
||||
## Adding a New MCP Server
|
||||
|
||||
1. Create `mcp/<name>.toml`
|
||||
2. Ensure `id` matches the filename
|
||||
3. Test the MCP server command locally
|
||||
4. Run `python scripts/validate.py`
|
||||
5. Submit a PR
|
||||
1. Create `mcp/<name>.toml` — the filename must match the `id` field.
|
||||
2. Test the transport command locally: run `npx -y <package>` and verify it starts without errors.
|
||||
3. List all `[[required_env]]` entries so the UI can prompt users for credentials.
|
||||
4. Run `python scripts/validate.py`.
|
||||
5. Submit a PR.
|
||||
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide.
|
||||
+78
-35
@@ -1,71 +1,114 @@
|
||||
# Plugins
|
||||
# Plugins Registry
|
||||
|
||||
Plugin packages for LibreFang. Plugins extend agent behavior through lifecycle hooks -- they can inject memories, modify context, or perform side effects during conversations.
|
||||
Plugins extend agent behavior through lifecycle hooks. They can inject memories into context before a turn, perform side-effect processing after a turn, or do both. Unlike skills (which add knowledge) or MCP servers (which add tools), plugins run as Python scripts that intercept the agent loop.
|
||||
|
||||
## Structure
|
||||
## File Format
|
||||
|
||||
Each plugin lives in its own subdirectory:
|
||||
|
||||
```
|
||||
plugins/
|
||||
└── <plugin-name>/
|
||||
├── plugin.toml # Plugin manifest
|
||||
├── plugin.toml # required: plugin manifest
|
||||
├── hooks/
|
||||
│ ├── ingest.py # Called on user message
|
||||
│ └── after_turn.py # Called after each turn
|
||||
└── requirements.txt # Python dependencies
|
||||
│ ├── ingest.py # called on each incoming user message
|
||||
│ └── after_turn.py # called after each completed agent turn
|
||||
└── requirements.txt # Python dependencies (prefer stdlib-only)
|
||||
```
|
||||
|
||||
## plugin.toml Format
|
||||
### plugin.toml format
|
||||
|
||||
```toml
|
||||
name = "plugin-name" # Must match directory name
|
||||
name = "episodic-memory" # must match directory name
|
||||
version = "0.1.0"
|
||||
description = "What this plugin does"
|
||||
author = "author-name"
|
||||
description = "Episode-based memory segmentation and recall for cross-conversation context continuity"
|
||||
author = "librefang"
|
||||
|
||||
[hooks]
|
||||
ingest = "hooks/ingest.py" # Receives user message, can return memories
|
||||
after_turn = "hooks/after_turn.py" # Post-turn processing
|
||||
ingest = "hooks/ingest.py" # optional
|
||||
after_turn = "hooks/after_turn.py" # optional
|
||||
|
||||
[i18n.zh]
|
||||
name = "情景记忆"
|
||||
description = "基于情景的记忆分段与召回,实现跨会话的上下文延续。"
|
||||
```
|
||||
|
||||
## Hook Protocol
|
||||
|
||||
Hooks communicate via stdin/stdout JSON:
|
||||
Hooks communicate with the agent runtime via stdin/stdout JSON lines.
|
||||
|
||||
### ingest hook
|
||||
|
||||
Receives the incoming user message and returns zero or more memory objects to inject into the agent's context for this turn:
|
||||
|
||||
```
|
||||
stdin: {"type": "ingest", "agent_id": "...", "message": "user message"}
|
||||
stdout: {"type": "ingest_result", "memories": [{"content": "..."}]}
|
||||
stdin: {"type": "ingest", "agent_id": "abc123", "session_id": "...", "message": "user message text"}
|
||||
stdout: {"type": "ingest_result", "memories": [{"content": "Relevant fact from earlier session"}]}
|
||||
```
|
||||
|
||||
### after_turn hook
|
||||
|
||||
Receives the full turn transcript after the agent responds. Used for persistence (saving summaries, updating profiles, appending logs):
|
||||
|
||||
```
|
||||
stdin: {"type": "after_turn", "agent_id": "...", "messages": [...]}
|
||||
stdin: {"type": "after_turn", "agent_id": "abc123", "session_id": "...", "messages": [...]}
|
||||
stdout: {"type": "ok"}
|
||||
```
|
||||
|
||||
## Current Plugins (10)
|
||||
## Installing and Using Plugins
|
||||
|
||||
| Plugin | Hooks | Description |
|
||||
|--------|-------|-------------|
|
||||
| auto-summarizer | ingest, after_turn | Running conversation summary for long context compression |
|
||||
| context-decay | ingest, after_turn | Time-based memory decay with relevance scoring for natural forgetting |
|
||||
| conversation-logger | after_turn | Logs conversations to JSONL files for auditing and analytics |
|
||||
| episodic-memory | ingest, after_turn | Episode-based conversation segmentation and cross-session recall |
|
||||
| guardrails | ingest | Safety filter detecting PII, prompt injection, and credential exposure |
|
||||
| keyword-memory | ingest | Extracts keywords and named entities as contextual memories |
|
||||
| sentiment-tracker | ingest | Analyzes user sentiment and injects emotional context |
|
||||
| todo-tracker | ingest, after_turn | Detects, persists, and recalls action items from conversations |
|
||||
| topic-memory | ingest, after_turn | Topic-aware keyword clustering with cross-conversation context recall |
|
||||
| user-profile | ingest, after_turn | Persistent user profiling from conversation patterns for personalization |
|
||||
```bash
|
||||
# List all available plugins
|
||||
librefang catalog plugins
|
||||
|
||||
# Install a plugin globally
|
||||
librefang plugin install episodic-memory
|
||||
|
||||
# Enable a plugin for a specific agent
|
||||
librefang plugin enable episodic-memory --agent coder
|
||||
|
||||
# Disable a plugin for an agent
|
||||
librefang plugin disable episodic-memory --agent coder
|
||||
|
||||
# List plugins active for an agent
|
||||
librefang plugin list --agent coder
|
||||
```
|
||||
|
||||
Hands can also declare an `allowed_plugins` list in `HAND.toml`, which restricts which installed plugins are active within that hand.
|
||||
|
||||
## All Plugins (12 total)
|
||||
|
||||
| Name | Version | Hooks | Description |
|
||||
|------|---------|-------|-------------|
|
||||
| auto-summarizer | 0.1.0 | ingest, after_turn | Maintains a running conversation summary to help agents handle long conversations without losing context |
|
||||
| context-decay | 0.1.0 | ingest, after_turn | Time-based memory decay with relevance scoring for natural context forgetting |
|
||||
| conversation-logger | 0.1.0 | after_turn | Logs all conversations to JSONL files for auditing, analytics, and debugging |
|
||||
| episodic-memory | 0.1.0 | ingest, after_turn | Episode-based memory segmentation and recall for cross-conversation context continuity |
|
||||
| guardrails | 0.1.0 | ingest | Safety filter that detects potentially harmful content patterns and injects warnings into agent context |
|
||||
| keyword-memory | 0.1.0 | ingest | Extracts keywords and named entities from user messages and returns them as contextual memories |
|
||||
| mempalace-indexer | 0.3.0 | ingest, after_turn | Auto-indexes conversations into MemPalace and recalls relevant memories — no API keys, no cloud |
|
||||
| sentiment-tracker | 0.1.0 | ingest | Analyzes user message sentiment and injects emotional context so agents can respond with appropriate tone |
|
||||
| todo-tracker | 0.1.0 | ingest, after_turn | Detects action items and tasks mentioned in conversations, persists them, and recalls them as context |
|
||||
| topic-memory | 0.1.0 | ingest, after_turn | Topic-aware memory recall with keyword clustering for cross-conversation context |
|
||||
| user-profile | 0.1.0 | ingest, after_turn | Persistent user profiling from conversation patterns for personalized agent responses |
|
||||
|
||||
Note: the `guardrails` and `mempalace-indexer` plugins have no `after_turn` hook; `conversation-logger` has no `ingest` hook.
|
||||
|
||||
## Hook Execution Order
|
||||
|
||||
For each agent turn, the runtime executes hooks in this order:
|
||||
|
||||
1. All `ingest` hooks run (in plugin installation order) — memories are collected and merged
|
||||
2. Agent turn executes with the injected context
|
||||
3. All `after_turn` hooks run (in plugin installation order)
|
||||
|
||||
## Adding a New Plugin
|
||||
|
||||
1. Create `plugins/<name>/plugin.toml`
|
||||
2. Add hook scripts in `hooks/`
|
||||
3. List dependencies in `requirements.txt` (prefer stdlib-only)
|
||||
4. Run `python scripts/validate.py`
|
||||
5. Submit a PR
|
||||
1. Create `plugins/<name>/plugin.toml` with `name`, `version`, `description`, and `[hooks]`.
|
||||
2. Add hook scripts under `hooks/` for each declared hook.
|
||||
3. Keep hooks fast (under 500 ms) — they run synchronously on every turn.
|
||||
4. List Python dependencies in `requirements.txt`; prefer standard library where possible.
|
||||
5. Run `python scripts/validate.py`.
|
||||
6. Submit a PR.
|
||||
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide.
|
||||
+150
-17
@@ -1,16 +1,123 @@
|
||||
# Providers
|
||||
|
||||
LLM provider and model metadata for LibreFang. Each provider file defines the provider's API configuration and all available models with pricing, context windows, and capability flags.
|
||||
LLM provider and model metadata for LibreFang. Each `.toml` file defines one provider's API configuration and all its available models with pricing, context windows, and capability flags.
|
||||
|
||||
## Structure
|
||||
**Current state: 46 providers, 232+ models**
|
||||
|
||||
```
|
||||
providers/
|
||||
├── anthropic.toml
|
||||
├── openai.toml
|
||||
├── groq.toml
|
||||
└── ... (46 providers, 220+ models)
|
||||
```
|
||||
---
|
||||
|
||||
## Provider Categories
|
||||
|
||||
### Frontier / Major Cloud APIs
|
||||
|
||||
| ID | Display Name | Base URL | API Key Env | Models | Description |
|
||||
|----|-------------|----------|-------------|--------|-------------|
|
||||
| `anthropic` | Anthropic | `https://api.anthropic.com` | `ANTHROPIC_API_KEY` | 7 | Claude family (Haiku / Sonnet / Opus); native Anthropic wire protocol, not OpenAI-compatible |
|
||||
| `openai` | OpenAI | `https://api.openai.com/v1` | `OPENAI_API_KEY` | 15 | GPT-4.x, o-series reasoning, image generation, TTS; also the fallback for codex-cli |
|
||||
| `gemini` | Google Gemini | `https://generativelanguage.googleapis.com` | `GEMINI_API_KEY` | 6 | Gemini 2.x family; native Google GenerativeLanguage protocol |
|
||||
| `xai` | xAI | `https://api.x.ai/v1` | `XAI_API_KEY` | 7 | Grok-3 family from Elon Musk's xAI |
|
||||
| `mistral` | Mistral AI | `https://api.mistral.ai/v1` | `MISTRAL_API_KEY` | 3 | Mistral Large / Small / Codestral; European frontier models |
|
||||
| `cohere` | Cohere | `https://api.cohere.com/v2` | `COHERE_API_KEY` | 4 | Command R+ family; strong RAG and tool-use models |
|
||||
| `deepseek` | DeepSeek | `https://api.deepseek.com/v1` | `DEEPSEEK_API_KEY` | 2 | DeepSeek-V3 (chat) + R1 (reasoning); extremely cost-effective |
|
||||
| `meta-llama` | Meta Llama | `https://api.llama.com/v1` | `LLAMA_API_KEY` | 4 | Official Meta Llama API — direct access to Llama 3.x |
|
||||
| `perplexity` | Perplexity AI | `https://api.perplexity.ai` | `PERPLEXITY_API_KEY` | 4 | Sonar family with live web search built in |
|
||||
|
||||
### Fast Inference / Compute Clouds
|
||||
|
||||
| ID | Display Name | Base URL | API Key Env | Models | Description |
|
||||
|----|-------------|----------|-------------|--------|-------------|
|
||||
| `groq` | Groq | `https://api.groq.com/openai/v1` | `GROQ_API_KEY` | 3 | GroqChip hardware; ~10× faster than GPU inference for supported models |
|
||||
| `cerebras` | Cerebras | `https://api.cerebras.ai/v1` | `CEREBRAS_API_KEY` | 4 | Wafer-scale chip inference; best-in-class throughput for Llama |
|
||||
| `sambanova` | SambaNova | `https://api.sambanova.ai/v1` | `SAMBANOVA_API_KEY` | 3 | Reconfigurable Dataflow Unit (RDU) inference; fast Llama variants |
|
||||
| `fireworks` | Fireworks AI | `https://api.fireworks.ai/inference/v1` | `FIREWORKS_API_KEY` | 5 | Serverless open-model hosting; fast cold-start |
|
||||
| `together` | Together AI | `https://api.together.xyz/v1` | `TOGETHER_API_KEY` | 8 | Open-model hosting (Llama, Qwen, Mistral) + fine-tuning API |
|
||||
| `nvidia-nim` | NVIDIA NIM | `https://integrate.api.nvidia.com/v1` | `NVIDIA_API_KEY` | 26 | NVIDIA NIM microservices; largest model selection in registry |
|
||||
| `replicate` | Replicate | `https://api.replicate.com/v1` | `REPLICATE_API_TOKEN` | 3 | Run any model as a serverless API; image + video + LLM |
|
||||
| `huggingface` | Hugging Face | `https://api-inference.huggingface.co/v1` | `HF_API_KEY` | 3 | HF Serverless Inference API for hosted open models |
|
||||
|
||||
### Cloud Platform / Enterprise
|
||||
|
||||
| ID | Display Name | Base URL | API Key Env | Models | Description |
|
||||
|----|-------------|----------|-------------|--------|-------------|
|
||||
| `bedrock` | AWS Bedrock | `https://bedrock-runtime.us-east-1.amazonaws.com` | `AWS_ACCESS_KEY_ID` | 11 | AWS-managed models (Claude, Llama, Mistral, Nova); IAM auth |
|
||||
| `vertex-ai` | Google Cloud Vertex AI | `https://us-central1-aiplatform.googleapis.com` | `GOOGLE_APPLICATION_CREDENTIALS` | 6 | GCP-hosted Gemini + third-party models; service account JSON auth |
|
||||
| `github-copilot` | GitHub Copilot | `https://api.githubcopilot.com` | `GITHUB_TOKEN` | 1 | Uses `ApiFormat::Copilot` — proprietary protocol, not OpenAI-compatible; requires GitHub PAT with Copilot access |
|
||||
|
||||
### Aggregators / Routers
|
||||
|
||||
| ID | Display Name | Base URL | API Key Env | Models | Description |
|
||||
|----|-------------|----------|-------------|--------|-------------|
|
||||
| `openrouter` | OpenRouter | `https://openrouter.ai/api/v1` | `OPENROUTER_API_KEY` | 18+ | Meta-provider routing to 300+ models; also receives models from OpenRouter-only providers via sync script |
|
||||
| `siliconflow` | SiliconFlow | `https://api.siliconflow.cn/v1` | `SILICONFLOW_API_KEY` | dynamic | 硅基流动 — Chinese open-model hosting; models discovered at runtime, not hardcoded in TOML |
|
||||
|
||||
### Chinese Providers
|
||||
|
||||
| ID | Display Name | Base URL | API Key Env | Models | Description |
|
||||
|----|-------------|----------|-------------|--------|-------------|
|
||||
| `qwen` | Qwen (Alibaba) | `https://dashscope.aliyuncs.com/compatible-mode/v1` | `DASHSCOPE_API_KEY` | 9 | Qwen3 family by Alibaba; multi-region support (`intl` / `us`) via `[provider.regions]` |
|
||||
| `moonshot` | Moonshot (Kimi) | `https://api.moonshot.ai/v1` | `MOONSHOT_API_KEY` | 5 | Kimi general chat models (moonshot-v1-8k/32k/128k) |
|
||||
| `minimax` | MiniMax | `https://api.minimax.io/v1` | `MINIMAX_API_KEY` | 8 | MiniMax M-series; strong Chinese + multilingual models |
|
||||
| `zhipu` | Zhipu AI (GLM) | `https://open.bigmodel.cn/api/paas/v4` | `ZHIPU_API_KEY` | 6 | GLM-4 family by Zhipu AI (智谱); general chat + vision |
|
||||
| `zai` | Z.AI | `https://api.z.ai/api/paas/v4` | `ZHIPU_API_KEY` | 2 | Z.AI general models; shares API key with zhipu |
|
||||
| `baichuan` | Baichuan (百川) | `https://api.baichuan-ai.com/v1` | `BAICHUAN_API_KEY` | 2 | Baichuan4 family; strong Chinese-language performance |
|
||||
| `volcengine` | Volcano Engine (Doubao) | `https://ark.cn-beijing.volces.com/api/v3` | `VOLCENGINE_API_KEY` | 8 | ByteDance Doubao models; Ark platform |
|
||||
| `stepfun` | Stepfun (阶跃星辰) | `https://api.stepfun.com/v1` | `STEPFUN_API_KEY` | 4 | Step-2 family; strong long-context and reasoning |
|
||||
| `tencent` | Tencent | `https://api.hunyuan.cloud.tencent.com/v1` | `HUNYUAN_API_KEY` | 1 | Hunyuan models by Tencent |
|
||||
| `qianfan` | Baidu Qianfan | `https://qianfan.baidubce.com/v2` | `QIANFAN_API_KEY` | 3 | ERNIE family by Baidu; Qianfan platform |
|
||||
|
||||
### Coding-Specific Endpoints
|
||||
|
||||
Separate `base_url` for coding workloads — not just model aliases. Same API key as the general counterpart.
|
||||
|
||||
| ID | Display Name | Base URL | API Key Env | Models | vs. General |
|
||||
|----|-------------|----------|-------------|--------|-------------|
|
||||
| `kimi_coding` | Kimi for Code | `https://api.kimi.com/coding` | `KIMI_API_KEY` | 1 | vs `moonshot`: `api.moonshot.ai/v1` |
|
||||
| `alibaba-coding-plan` | Alibaba Coding Plan (Intl) | `https://coding-intl.dashscope.aliyuncs.com/v1` | `ALIBABA_CODING_PLAN_API_KEY` | 9 | vs `qwen`: `dashscope.aliyuncs.com`; aggregates models from multiple vendors (MiniMax, GLM, Kimi) |
|
||||
| `volcengine_coding` | Volcano Engine Coding Plan | `https://ark.cn-beijing.volces.com/api/coding/v3` | `VOLCENGINE_API_KEY` | dynamic | vs `volcengine`: `/api/v3`; models discovered at runtime |
|
||||
| `zhipu_coding` | Zhipu Coding (CodeGeeX) | `https://open.bigmodel.cn/api/coding/paas/v4` | `ZHIPU_API_KEY` | 1 | vs `zhipu`: `/api/paas/v4`; CodeGeeX-4 coding model |
|
||||
| `zai_coding` | Z.AI Coding | `https://api.z.ai/api/coding/paas/v4` | `ZHIPU_API_KEY` | 2 | vs `zai`: `/api/paas/v4`; GLM coding variants |
|
||||
|
||||
### CLI-Based Providers (No API Key)
|
||||
|
||||
Route through a locally-installed CLI tool. `key_required = false`, `base_url` is empty. Cost is $0.
|
||||
|
||||
| ID | Display Name | CLI Binary | Models | ApiFormat | Description |
|
||||
|----|-------------|-----------|--------|-----------|-------------|
|
||||
| `claude-code` | Claude Code | `claude` | 3 | `ClaudeCode` | Anthropic's official CLI; routes through Claude API with OAuth |
|
||||
| `codex-cli` | Codex CLI | `codex` | 6 | `CodexCli` | OpenAI Codex CLI; also serves as fallback for `openai` provider |
|
||||
| `gemini-cli` | Gemini CLI | `gemini` | 2 | `GeminiCli` | Google Gemini CLI; also serves as fallback for `gemini` provider |
|
||||
| `qwen-code` | Qwen Code | `qwen-code` | 3 | `QwenCode` | Alibaba Qwen coding CLI |
|
||||
|
||||
### Local / Self-Hosted
|
||||
|
||||
| ID | Display Name | Default Base URL | API Key Env | Notes |
|
||||
|----|-------------|-----------------|-------------|-------|
|
||||
| `ollama` | Ollama | `http://localhost:11434/v1` | `OLLAMA_API_KEY` | No key required; models discovered dynamically at runtime via `/api/tags` |
|
||||
| `lmstudio` | LM Studio | `http://localhost:1234/v1` | `LMSTUDIO_API_KEY` | No key required; GUI app for running GGUF models locally |
|
||||
| `vllm` | vLLM | `http://localhost:8000/v1` | `VLLM_API_KEY` | No key required; high-throughput inference server for production self-hosting |
|
||||
|
||||
### Special / Niche
|
||||
|
||||
| ID | Display Name | Base URL | API Key Env | Notes |
|
||||
|----|-------------|----------|-------------|-------|
|
||||
| `chatgpt` | ChatGPT (Session Auth) | `https://chatgpt.com/backend-api` | `CHATGPT_SESSION_TOKEN` | Session cookie auth, not an API key. Exposes GPT-5.x Codex models (gpt-5.1-codex etc.) that are unavailable via the standard OpenAI API |
|
||||
| `elevenlabs` | ElevenLabs | `https://api.elevenlabs.io/v1` | `ELEVENLABS_API_KEY` | TTS / voice generation only — has a dedicated `elevenlabs.rs` driver in librefang-runtime. No chat models; appears in the provider list for media capability routing |
|
||||
|
||||
---
|
||||
|
||||
## Inclusion Criteria
|
||||
|
||||
A provider gets its own `.toml` file when it meets **at least one** of:
|
||||
|
||||
1. Has a **direct public API** not accessible via OpenRouter
|
||||
2. Has a **unique endpoint** for a specific workload (e.g. coding plan endpoints)
|
||||
3. Has a **dedicated driver** (`ApiFormat` beyond generic `OpenAI`)
|
||||
4. Is a **local/self-hosted** runtime
|
||||
5. Is a **CLI-based** provider
|
||||
|
||||
Providers that only route through `openrouter.ai/api/v1` with `OPENROUTER_API_KEY` are **not** given standalone files — their models are merged into `openrouter.toml` by the sync script. See [scripts/sync-pricing.py](../scripts/sync-pricing.py).
|
||||
|
||||
---
|
||||
|
||||
## Provider TOML Format
|
||||
|
||||
@@ -39,26 +146,52 @@ aliases = ["short-name"]
|
||||
## Tier Definitions
|
||||
|
||||
| Tier | Description | Examples |
|
||||
|------|-------------|----------|
|
||||
|------|-------------|---------|
|
||||
| `frontier` | Most capable, cutting-edge | Claude Opus, GPT-4.1 |
|
||||
| `smart` | Smart, cost-effective | Claude Sonnet, Gemini 2.5 Flash |
|
||||
| `balanced` | Balanced speed/cost | GPT-4.1 Mini, Llama 3.3 70B |
|
||||
| `fast` | Fastest, cheapest | GPT-4o Mini, Claude Haiku |
|
||||
| `local` | Local models, zero cost | Ollama, vLLM, LM Studio |
|
||||
|
||||
---
|
||||
|
||||
## Sync Script
|
||||
|
||||
`scripts/sync-pricing.py` runs daily via CI to keep model pricing current.
|
||||
|
||||
```bash
|
||||
python scripts/sync-pricing.py # Update prices only
|
||||
python scripts/sync-pricing.py --create-missing # Also add new providers
|
||||
python scripts/sync-pricing.py --dry-run --create-missing # Preview changes
|
||||
```
|
||||
|
||||
**`--create-missing` routing logic:**
|
||||
|
||||
| Condition | Action |
|
||||
|-----------|--------|
|
||||
| Provider in `PROVIDER_API` map (has direct API) | Create standalone `.toml` |
|
||||
| Provider not in `PROVIDER_API` (OpenRouter-only) | Merge into `openrouter.toml` with `openrouter/{provider}/{model}` IDs |
|
||||
| Provider in `SKIP_PROVIDERS` (morph, aider, kwaipilot, …) | Skip entirely |
|
||||
| Provider ID starts with `~` (OpenRouter internal routing alias) | Skip entirely |
|
||||
|
||||
---
|
||||
|
||||
## Validation
|
||||
|
||||
```bash
|
||||
python scripts/validate.py
|
||||
python scripts/validate.py # Warn on issues
|
||||
python scripts/validate.py --strict # Treat warnings as errors
|
||||
```
|
||||
|
||||
Checks: required fields, valid tiers, non-negative costs, no duplicate model IDs.
|
||||
|
||||
## Adding or Updating a Model
|
||||
## Adding or Updating a Provider
|
||||
|
||||
1. Edit or create the provider file in `providers/`
|
||||
2. Use exact API model IDs and verify pricing from official sources
|
||||
3. Run `python scripts/validate.py`
|
||||
4. Submit a PR
|
||||
1. Check inclusion criteria above — if OpenRouter-only, don't create a new file
|
||||
2. Create or edit the `.toml` in `providers/`
|
||||
3. Use exact API model IDs; verify pricing from official sources
|
||||
4. Run `python scripts/validate.py`
|
||||
5. Update the table in this README
|
||||
6. Submit a PR
|
||||
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide and pricing source links.
|
||||
See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full guide.
|
||||
@@ -1,48 +0,0 @@
|
||||
# AI21 Labs — https://ai21.com
|
||||
# Models: 3
|
||||
|
||||
[provider]
|
||||
id = "ai21"
|
||||
display_name = "AI21 Labs"
|
||||
api_key_env = "AI21_API_KEY"
|
||||
base_url = "https://api.ai21.com/studio/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "jamba-1.5-large"
|
||||
display_name = "Jamba 1.5 Large"
|
||||
tier = "smart"
|
||||
context_window = 256000
|
||||
max_output_tokens = 4096
|
||||
input_cost_per_m = 2.0
|
||||
output_cost_per_m = 8.0
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = ["jamba"]
|
||||
|
||||
[[models]]
|
||||
id = "jamba-1.5-mini"
|
||||
display_name = "Jamba 1.5 Mini"
|
||||
tier = "fast"
|
||||
context_window = 256000
|
||||
max_output_tokens = 4096
|
||||
input_cost_per_m = 0.20
|
||||
output_cost_per_m = 0.40
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = []
|
||||
|
||||
[[models]]
|
||||
id = "jamba-instruct"
|
||||
display_name = "Jamba Instruct"
|
||||
tier = "balanced"
|
||||
context_window = 256000
|
||||
max_output_tokens = 4096
|
||||
input_cost_per_m = 0.50
|
||||
output_cost_per_m = 0.70
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = []
|
||||
@@ -1,35 +0,0 @@
|
||||
[provider]
|
||||
id = "aider"
|
||||
display_name = "Aider"
|
||||
api_key_env = ""
|
||||
base_url = ""
|
||||
key_required = false
|
||||
|
||||
[[models]]
|
||||
id = "aider/sonnet"
|
||||
display_name = "Claude Sonnet via Aider"
|
||||
provider = "aider"
|
||||
tier = "smart"
|
||||
context_window = 200000
|
||||
max_output_tokens = 64000
|
||||
input_cost_per_m = 0.0
|
||||
output_cost_per_m = 0.0
|
||||
supports_tools = false
|
||||
supports_vision = false
|
||||
supports_streaming = false
|
||||
supports_thinking = true
|
||||
aliases = ["aider-sonnet"]
|
||||
|
||||
[[models]]
|
||||
id = "aider/gpt-4o"
|
||||
display_name = "GPT-4o via Aider"
|
||||
provider = "aider"
|
||||
tier = "smart"
|
||||
context_window = 128000
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.0
|
||||
output_cost_per_m = 0.0
|
||||
supports_tools = false
|
||||
supports_vision = false
|
||||
supports_streaming = false
|
||||
aliases = ["aider-gpt-4o"]
|
||||
@@ -1,48 +0,0 @@
|
||||
# aion-labs — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "aion-labs"
|
||||
display_name = "Aion Labs"
|
||||
api_key_env = "AION_LABS_API_KEY"
|
||||
base_url = "https://api.aionlabs.ai/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "aion-1.0"
|
||||
display_name = "AionLabs: Aion-1.0"
|
||||
tier = "frontier"
|
||||
context_window = 131072
|
||||
max_output_tokens = 32768
|
||||
input_cost_per_m = 4.0
|
||||
output_cost_per_m = 8.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "aion-1.0-mini"
|
||||
display_name = "AionLabs: Aion-1.0-Mini"
|
||||
tier = "smart"
|
||||
context_window = 131072
|
||||
max_output_tokens = 32768
|
||||
input_cost_per_m = 0.7
|
||||
output_cost_per_m = 1.4
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "aion-2.0"
|
||||
display_name = "AionLabs: Aion-2.0"
|
||||
tier = "smart"
|
||||
context_window = 131072
|
||||
max_output_tokens = 32768
|
||||
input_cost_per_m = 0.8
|
||||
output_cost_per_m = 1.6
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "aion-rp-llama-3.1-8b"
|
||||
display_name = "AionLabs: Aion-RP 1.0 (8B)"
|
||||
tier = "smart"
|
||||
context_window = 32768
|
||||
max_output_tokens = 32768
|
||||
input_cost_per_m = 0.8
|
||||
output_cost_per_m = 1.6
|
||||
supports_streaming = true
|
||||
@@ -1,50 +0,0 @@
|
||||
# allenai — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "allenai"
|
||||
display_name = "Allenai"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "olmo-2-0325-32b-instruct"
|
||||
display_name = "AllenAI: Olmo 2 32B Instruct"
|
||||
tier = "fast"
|
||||
context_window = 128000
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.05
|
||||
output_cost_per_m = 0.2
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "olmo-3-32b-think"
|
||||
display_name = "AllenAI: Olmo 3 32B Think"
|
||||
tier = "fast"
|
||||
context_window = 65536
|
||||
max_output_tokens = 65536
|
||||
input_cost_per_m = 0.15
|
||||
output_cost_per_m = 0.5
|
||||
supports_streaming = true
|
||||
supports_thinking = true
|
||||
|
||||
[[models]]
|
||||
id = "olmo-3.1-32b-instruct"
|
||||
display_name = "AllenAI: Olmo 3.1 32B Instruct"
|
||||
tier = "fast"
|
||||
context_window = 65536
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.2
|
||||
output_cost_per_m = 0.6
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "olmo-3.1-32b-think"
|
||||
display_name = "AllenAI: Olmo 3.1 32B Think"
|
||||
tier = "fast"
|
||||
context_window = 65536
|
||||
max_output_tokens = 65536
|
||||
input_cost_per_m = 0.15
|
||||
output_cost_per_m = 0.5
|
||||
supports_streaming = true
|
||||
supports_thinking = true
|
||||
@@ -1,78 +0,0 @@
|
||||
# arcee-ai — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "arcee-ai"
|
||||
display_name = "Arcee Ai"
|
||||
api_key_env = "ARCEE_API_KEY"
|
||||
base_url = "https://api.arcee.ai/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "coder-large"
|
||||
display_name = "Arcee AI: Coder Large"
|
||||
tier = "smart"
|
||||
context_window = 32768
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.5
|
||||
output_cost_per_m = 0.8
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "maestro-reasoning"
|
||||
display_name = "Arcee AI: Maestro Reasoning"
|
||||
tier = "smart"
|
||||
context_window = 131072
|
||||
max_output_tokens = 32000
|
||||
input_cost_per_m = 0.9
|
||||
output_cost_per_m = 3.3
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "spotlight"
|
||||
display_name = "Arcee AI: Spotlight"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 65537
|
||||
input_cost_per_m = 0.18
|
||||
output_cost_per_m = 0.18
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "trinity-large-preview:free"
|
||||
display_name = "Arcee AI: Trinity Large Preview (free)"
|
||||
tier = "fast"
|
||||
context_window = 131000
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.0
|
||||
output_cost_per_m = 0.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "trinity-large-thinking"
|
||||
display_name = "Arcee AI: Trinity Large Thinking"
|
||||
tier = "fast"
|
||||
context_window = 262144
|
||||
max_output_tokens = 262144
|
||||
input_cost_per_m = 0.22
|
||||
output_cost_per_m = 0.85
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "trinity-mini"
|
||||
display_name = "Arcee AI: Trinity Mini"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 131072
|
||||
input_cost_per_m = 0.045
|
||||
output_cost_per_m = 0.15
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "virtuoso-large"
|
||||
display_name = "Arcee AI: Virtuoso Large"
|
||||
tier = "smart"
|
||||
context_window = 131072
|
||||
max_output_tokens = 64000
|
||||
input_cost_per_m = 0.75
|
||||
output_cost_per_m = 1.2
|
||||
supports_streaming = true
|
||||
@@ -1,76 +0,0 @@
|
||||
# Chutes.ai — https://chutes.ai
|
||||
# Models: 5
|
||||
|
||||
[provider]
|
||||
id = "chutes"
|
||||
display_name = "Chutes.ai"
|
||||
api_key_env = "CHUTES_API_KEY"
|
||||
base_url = "https://llm.chutes.ai/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "chutes/deepseek-ai/DeepSeek-V3"
|
||||
display_name = "DeepSeek V3 (Chutes)"
|
||||
tier = "smart"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.25
|
||||
output_cost_per_m = 0.35
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = ["chutes-deepseek-v3"]
|
||||
|
||||
[[models]]
|
||||
id = "chutes/deepseek-ai/DeepSeek-R1"
|
||||
display_name = "DeepSeek R1 (Chutes)"
|
||||
tier = "smart"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.55
|
||||
output_cost_per_m = 2.19
|
||||
supports_tools = false
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
supports_thinking = true
|
||||
aliases = ["chutes-deepseek-r1"]
|
||||
|
||||
[[models]]
|
||||
id = "chutes/meta-llama/Llama-4-Maverick-17B-128E-Instruct"
|
||||
display_name = "Llama 4 Maverick (Chutes)"
|
||||
tier = "balanced"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.20
|
||||
output_cost_per_m = 0.30
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = ["chutes-llama-maverick"]
|
||||
|
||||
[[models]]
|
||||
id = "chutes/Qwen/Qwen3-235B-A22B"
|
||||
display_name = "Qwen3 235B (Chutes)"
|
||||
tier = "smart"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.25
|
||||
output_cost_per_m = 0.35
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
supports_thinking = true
|
||||
aliases = ["chutes-qwen3"]
|
||||
|
||||
[[models]]
|
||||
id = "chutes/meta-llama/Llama-3.3-70B-Instruct"
|
||||
display_name = "Llama 3.3 70B (Chutes)"
|
||||
tier = "balanced"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.10
|
||||
output_cost_per_m = 0.15
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = ["chutes-llama-70b"]
|
||||
@@ -1,18 +0,0 @@
|
||||
# deepcogito — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "deepcogito"
|
||||
display_name = "Deepcogito"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "cogito-v2.1-671b"
|
||||
display_name = "Deep Cogito: Cogito v2.1 671B"
|
||||
tier = "smart"
|
||||
context_window = 128000
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 1.25
|
||||
output_cost_per_m = 1.25
|
||||
supports_streaming = true
|
||||
@@ -0,0 +1,69 @@
|
||||
# DeepInfra — https://deepinfra.com
|
||||
# Serverless open-model inference (Llama, Mistral, Qwen, etc.)
|
||||
|
||||
[provider]
|
||||
id = "deepinfra"
|
||||
display_name = "DeepInfra"
|
||||
api_key_env = "DEEPINFRA_API_KEY"
|
||||
base_url = "https://api.deepinfra.com/v1/openai"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "meta-llama/Meta-Llama-3.1-8B-Instruct"
|
||||
display_name = "Llama 3.1 8B Instruct"
|
||||
tier = "fast"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.06
|
||||
output_cost_per_m = 0.06
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "meta-llama/Meta-Llama-3.1-70B-Instruct"
|
||||
display_name = "Llama 3.1 70B Instruct"
|
||||
tier = "balanced"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.35
|
||||
output_cost_per_m = 0.4
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "meta-llama/Meta-Llama-3.1-405B-Instruct"
|
||||
display_name = "Llama 3.1 405B Instruct"
|
||||
tier = "smart"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.8
|
||||
output_cost_per_m = 0.8
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "mistralai/Mistral-7B-Instruct-v0.3"
|
||||
display_name = "Mistral 7B Instruct v0.3"
|
||||
tier = "fast"
|
||||
context_window = 32768
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.07
|
||||
output_cost_per_m = 0.07
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "Qwen/Qwen2.5-72B-Instruct"
|
||||
display_name = "Qwen 2.5 72B Instruct"
|
||||
tier = "balanced"
|
||||
context_window = 32768
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.35
|
||||
output_cost_per_m = 0.4
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# essentialai — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "essentialai"
|
||||
display_name = "Essentialai"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "rnj-1-instruct"
|
||||
display_name = "EssentialAI: Rnj 1 Instruct"
|
||||
tier = "fast"
|
||||
context_window = 32768
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.15
|
||||
output_cost_per_m = 0.15
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# ibm-granite — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "ibm-granite"
|
||||
display_name = "Ibm Granite"
|
||||
api_key_env = "WATSONX_API_KEY"
|
||||
base_url = "https://us-south.ml.cloud.ibm.com/ml/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "granite-4.0-h-micro"
|
||||
display_name = "IBM: Granite 4.0 Micro"
|
||||
tier = "fast"
|
||||
context_window = 131000
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.017
|
||||
output_cost_per_m = 0.11
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# inception — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "inception"
|
||||
display_name = "Inception"
|
||||
api_key_env = "INCEPTION_API_KEY"
|
||||
base_url = "https://api.inceptionlabs.ai/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "mercury-2"
|
||||
display_name = "Inception: Mercury 2"
|
||||
tier = "fast"
|
||||
context_window = 128000
|
||||
max_output_tokens = 50000
|
||||
input_cost_per_m = 0.25
|
||||
output_cost_per_m = 0.75
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# inclusionai — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "inclusionai"
|
||||
display_name = "Inclusionai"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "ling-2.6-flash:free"
|
||||
display_name = "inclusionAI: Ling-2.6-flash (free)"
|
||||
tier = "fast"
|
||||
context_window = 262144
|
||||
max_output_tokens = 32768
|
||||
input_cost_per_m = 0.0
|
||||
output_cost_per_m = 0.0
|
||||
supports_streaming = true
|
||||
@@ -1,28 +0,0 @@
|
||||
# inflection — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "inflection"
|
||||
display_name = "Inflection"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "inflection-3-pi"
|
||||
display_name = "Inflection: Inflection 3 Pi"
|
||||
tier = "smart"
|
||||
context_window = 8000
|
||||
max_output_tokens = 1024
|
||||
input_cost_per_m = 2.5
|
||||
output_cost_per_m = 10.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "inflection-3-productivity"
|
||||
display_name = "Inflection: Inflection 3 Productivity"
|
||||
tier = "smart"
|
||||
context_window = 8000
|
||||
max_output_tokens = 1024
|
||||
input_cost_per_m = 2.5
|
||||
output_cost_per_m = 10.0
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# kwaipilot — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "kwaipilot"
|
||||
display_name = "Kwaipilot"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "kat-coder-pro-v2"
|
||||
display_name = "Kwaipilot: KAT-Coder-Pro V2"
|
||||
tier = "fast"
|
||||
context_window = 256000
|
||||
max_output_tokens = 80000
|
||||
input_cost_per_m = 0.3
|
||||
output_cost_per_m = 1.2
|
||||
supports_streaming = true
|
||||
@@ -1,38 +0,0 @@
|
||||
# liquid — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "liquid"
|
||||
display_name = "Liquid"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "lfm-2-24b-a2b"
|
||||
display_name = "LiquidAI: LFM2-24B-A2B"
|
||||
tier = "fast"
|
||||
context_window = 32768
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.03
|
||||
output_cost_per_m = 0.12
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "lfm-2.5-1.2b-instruct:free"
|
||||
display_name = "LiquidAI: LFM2.5-1.2B-Instruct (free)"
|
||||
tier = "fast"
|
||||
context_window = 32768
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.0
|
||||
output_cost_per_m = 0.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "lfm-2.5-1.2b-thinking:free"
|
||||
display_name = "LiquidAI: LFM2.5-1.2B-Thinking (free)"
|
||||
tier = "fast"
|
||||
context_window = 32768
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.0
|
||||
output_cost_per_m = 0.0
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# meituan — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "meituan"
|
||||
display_name = "Meituan"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "longcat-flash-chat"
|
||||
display_name = "Meituan: LongCat Flash Chat"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 131072
|
||||
input_cost_per_m = 0.2
|
||||
output_cost_per_m = 0.8
|
||||
supports_streaming = true
|
||||
@@ -1,28 +0,0 @@
|
||||
# microsoft — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "microsoft"
|
||||
display_name = "Microsoft"
|
||||
api_key_env = "GITHUB_TOKEN"
|
||||
base_url = "https://models.inference.ai.azure.com"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "phi-4"
|
||||
display_name = "Microsoft: Phi 4"
|
||||
tier = "fast"
|
||||
context_window = 16384
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.065
|
||||
output_cost_per_m = 0.14
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "wizardlm-2-8x22b"
|
||||
display_name = "WizardLM-2 8x22B"
|
||||
tier = "smart"
|
||||
context_window = 65535
|
||||
max_output_tokens = 8000
|
||||
input_cost_per_m = 0.62
|
||||
output_cost_per_m = 0.62
|
||||
supports_streaming = true
|
||||
@@ -1,28 +0,0 @@
|
||||
# morph — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "morph"
|
||||
display_name = "Morph"
|
||||
api_key_env = "MORPH_API_KEY"
|
||||
base_url = "https://api.morphllm.com/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "morph-v3-fast"
|
||||
display_name = "Morph: Morph V3 Fast"
|
||||
tier = "smart"
|
||||
context_window = 81920
|
||||
max_output_tokens = 38000
|
||||
input_cost_per_m = 0.8
|
||||
output_cost_per_m = 1.2
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "morph-v3-large"
|
||||
display_name = "Morph: Morph V3 Large"
|
||||
tier = "smart"
|
||||
context_window = 262144
|
||||
max_output_tokens = 131072
|
||||
input_cost_per_m = 0.9
|
||||
output_cost_per_m = 1.9
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# nex-agi — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "nex-agi"
|
||||
display_name = "Nex Agi"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "deepseek-v3.1-nex-n1"
|
||||
display_name = "Nex AGI: DeepSeek V3.1 Nex N1"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 163840
|
||||
input_cost_per_m = 0.135
|
||||
output_cost_per_m = 0.5
|
||||
supports_streaming = true
|
||||
@@ -1,68 +0,0 @@
|
||||
# nousresearch — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "nousresearch"
|
||||
display_name = "Nousresearch"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "hermes-2-pro-llama-3-8b"
|
||||
display_name = "NousResearch: Hermes 2 Pro - Llama-3 8B"
|
||||
tier = "fast"
|
||||
context_window = 8192
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.14
|
||||
output_cost_per_m = 0.14
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "hermes-3-llama-3.1-405b"
|
||||
display_name = "Nous: Hermes 3 405B Instruct"
|
||||
tier = "smart"
|
||||
context_window = 131072
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 1.0
|
||||
output_cost_per_m = 1.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "hermes-3-llama-3.1-405b:free"
|
||||
display_name = "Nous: Hermes 3 405B Instruct (free)"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.0
|
||||
output_cost_per_m = 0.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "hermes-3-llama-3.1-70b"
|
||||
display_name = "Nous: Hermes 3 70B Instruct"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.3
|
||||
output_cost_per_m = 0.3
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "hermes-4-405b"
|
||||
display_name = "Nous: Hermes 4 405B"
|
||||
tier = "smart"
|
||||
context_window = 131072
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 1.0
|
||||
output_cost_per_m = 3.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "hermes-4-70b"
|
||||
display_name = "Nous: Hermes 4 70B"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.13
|
||||
output_cost_per_m = 0.4
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# prime-intellect — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "prime-intellect"
|
||||
display_name = "Prime Intellect"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "intellect-3"
|
||||
display_name = "Prime Intellect: INTELLECT-3"
|
||||
tier = "fast"
|
||||
context_window = 131072
|
||||
max_output_tokens = 131072
|
||||
input_cost_per_m = 0.2
|
||||
output_cost_per_m = 1.1
|
||||
supports_streaming = true
|
||||
@@ -1,28 +0,0 @@
|
||||
# relace — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "relace"
|
||||
display_name = "Relace"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "relace-apply-3"
|
||||
display_name = "Relace: Relace Apply 3"
|
||||
tier = "smart"
|
||||
context_window = 256000
|
||||
max_output_tokens = 128000
|
||||
input_cost_per_m = 0.85
|
||||
output_cost_per_m = 1.25
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "relace-search"
|
||||
display_name = "Relace: Relace Search"
|
||||
tier = "smart"
|
||||
context_window = 256000
|
||||
max_output_tokens = 128000
|
||||
input_cost_per_m = 1.0
|
||||
output_cost_per_m = 3.0
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# switchpoint — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "switchpoint"
|
||||
display_name = "Switchpoint"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "router"
|
||||
display_name = "Switchpoint Router"
|
||||
tier = "smart"
|
||||
context_window = 131072
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.85
|
||||
output_cost_per_m = 3.4
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# tngtech — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "tngtech"
|
||||
display_name = "Tngtech"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "deepseek-r1t2-chimera"
|
||||
display_name = "TNG: DeepSeek R1T2 Chimera"
|
||||
tier = "fast"
|
||||
context_window = 163840
|
||||
max_output_tokens = 163840
|
||||
input_cost_per_m = 0.3
|
||||
output_cost_per_m = 1.1
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# upstage — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "upstage"
|
||||
display_name = "Upstage"
|
||||
api_key_env = "UPSTAGE_API_KEY"
|
||||
base_url = "https://api.upstage.ai/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "solar-pro-3"
|
||||
display_name = "Upstage: Solar Pro 3"
|
||||
tier = "fast"
|
||||
context_window = 128000
|
||||
max_output_tokens = 16384
|
||||
input_cost_per_m = 0.15
|
||||
output_cost_per_m = 0.6
|
||||
supports_streaming = true
|
||||
@@ -1,49 +0,0 @@
|
||||
# Venice.ai — https://venice.ai
|
||||
# Models: 3
|
||||
|
||||
[provider]
|
||||
id = "venice"
|
||||
display_name = "Venice.ai"
|
||||
api_key_env = "VENICE_API_KEY"
|
||||
base_url = "https://api.venice.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "venice-uncensored"
|
||||
display_name = "Venice Uncensored"
|
||||
tier = "fast"
|
||||
context_window = 32000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.20
|
||||
output_cost_per_m = 0.90
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = ["venice"]
|
||||
|
||||
[[models]]
|
||||
id = "llama-3.3-70b"
|
||||
display_name = "Llama 3.3 70B (Venice)"
|
||||
tier = "balanced"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.1
|
||||
output_cost_per_m = 0.32
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
aliases = []
|
||||
|
||||
[[models]]
|
||||
id = "qwen3-235b-a22b-instruct-2507"
|
||||
display_name = "Qwen3 235B A22B (Venice)"
|
||||
tier = "smart"
|
||||
context_window = 128000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.20
|
||||
output_cost_per_m = 0.90
|
||||
supports_tools = true
|
||||
supports_vision = false
|
||||
supports_streaming = true
|
||||
supports_thinking = true
|
||||
aliases = []
|
||||
@@ -1,18 +0,0 @@
|
||||
# writer — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "writer"
|
||||
display_name = "Writer"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "palmyra-x5"
|
||||
display_name = "Writer: Palmyra X5"
|
||||
tier = "smart"
|
||||
context_window = 1040000
|
||||
max_output_tokens = 8192
|
||||
input_cost_per_m = 0.6
|
||||
output_cost_per_m = 6.0
|
||||
supports_streaming = true
|
||||
@@ -1,38 +0,0 @@
|
||||
# xiaomi — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "xiaomi"
|
||||
display_name = "Xiaomi"
|
||||
api_key_env = "XIAOMI_ACCESS_KEY_ID"
|
||||
base_url = "https://cnbj3-cloud-ml.api.xiaomi.net"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "mimo-v2-flash"
|
||||
display_name = "Xiaomi: MiMo-V2-Flash"
|
||||
tier = "fast"
|
||||
context_window = 262144
|
||||
max_output_tokens = 65536
|
||||
input_cost_per_m = 0.09
|
||||
output_cost_per_m = 0.29
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "mimo-v2-omni"
|
||||
display_name = "Xiaomi: MiMo-V2-Omni"
|
||||
tier = "fast"
|
||||
context_window = 262144
|
||||
max_output_tokens = 65536
|
||||
input_cost_per_m = 0.4
|
||||
output_cost_per_m = 2.0
|
||||
supports_streaming = true
|
||||
|
||||
[[models]]
|
||||
id = "mimo-v2-pro"
|
||||
display_name = "Xiaomi: MiMo-V2-Pro"
|
||||
tier = "smart"
|
||||
context_window = 1048576
|
||||
max_output_tokens = 131072
|
||||
input_cost_per_m = 1.0
|
||||
output_cost_per_m = 3.0
|
||||
supports_streaming = true
|
||||
@@ -1,18 +0,0 @@
|
||||
# ~anthropic — auto-generated from OpenRouter API
|
||||
|
||||
[provider]
|
||||
id = "~anthropic"
|
||||
display_name = "~Anthropic"
|
||||
api_key_env = "OPENROUTER_API_KEY"
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
key_required = true
|
||||
|
||||
[[models]]
|
||||
id = "claude-opus-latest"
|
||||
display_name = "Anthropic: Claude Opus Latest"
|
||||
tier = "frontier"
|
||||
context_window = 1000000
|
||||
max_output_tokens = 128000
|
||||
input_cost_per_m = 5.0
|
||||
output_cost_per_m = 25.0
|
||||
supports_streaming = true
|
||||
+118
-48
@@ -34,6 +34,8 @@ PROVIDER_ALIAS = {
|
||||
SKIP_PROVIDERS = {
|
||||
"sao10k", "thedrummer", "undi95", "gryphe", "cognitivecomputations",
|
||||
"anthracite-org", "alpindale", "alfredpros", "mancer",
|
||||
# Specialized coding tools / CLI wrappers — not general LLM providers
|
||||
"morph", "aider", "kwaipilot",
|
||||
}
|
||||
|
||||
# Skip creating NEW provider files for these — they overlap with hand-written
|
||||
@@ -139,8 +141,102 @@ def update_toml_prices(toml_path, models_by_id, dry_run=False):
|
||||
return updated
|
||||
|
||||
|
||||
def _build_model_fields(provider_id, m, model_id_prefix=""):
|
||||
"""Extract and normalise fields for a single OpenRouter model entry.
|
||||
|
||||
Returns a dict of fields, or None if pricing is missing.
|
||||
The caller supplies *model_id_prefix* (e.g. "openrouter/kwaipilot/") so
|
||||
the same helper works for both standalone files and openrouter.toml merges.
|
||||
"""
|
||||
raw_id = m["id"].split("/")[-1] if "/" in m["id"] else m["id"]
|
||||
model_id = f"{model_id_prefix}{raw_id}"
|
||||
display = m.get("name", raw_id)
|
||||
ctx = m.get("context_length", 0)
|
||||
max_out = m.get("top_provider", {}).get("max_completion_tokens", 0)
|
||||
inp, outp = parse_pricing(m)
|
||||
if inp is None:
|
||||
return None
|
||||
|
||||
supports_tools = "tool_use" in str(m.get("supported_parameters", []))
|
||||
supports_vision = "vision" in str(m.get("architecture", {}).get("modality", ""))
|
||||
|
||||
if inp == 0 and outp == 0:
|
||||
tier = "fast"
|
||||
elif inp < 0.5:
|
||||
tier = "fast"
|
||||
elif inp < 3.0:
|
||||
tier = "smart"
|
||||
else:
|
||||
tier = "frontier"
|
||||
|
||||
if not max_out:
|
||||
max_out = min(ctx // 4, 16384) if ctx > 0 else 4096
|
||||
|
||||
return dict(
|
||||
model_id=model_id, display=display, tier=tier,
|
||||
ctx=ctx, max_out=max_out, inp=inp, outp=outp,
|
||||
supports_tools=supports_tools, supports_vision=supports_vision,
|
||||
)
|
||||
|
||||
|
||||
def _model_lines(f):
|
||||
"""Render a model-fields dict as TOML [[models]] lines."""
|
||||
lines = [
|
||||
"[[models]]",
|
||||
f'id = "{f["model_id"]}"',
|
||||
f'display_name = "{f["display"]}"',
|
||||
f'tier = "{f["tier"]}"',
|
||||
f'context_window = {f["ctx"]}',
|
||||
f'max_output_tokens = {f["max_out"]}',
|
||||
f'input_cost_per_m = {f["inp"]}',
|
||||
f'output_cost_per_m = {f["outp"]}',
|
||||
]
|
||||
if f["supports_tools"]:
|
||||
lines.append("supports_tools = true")
|
||||
if f["supports_vision"]:
|
||||
lines.append("supports_vision = true")
|
||||
lines.append("supports_streaming = true")
|
||||
lines.append("")
|
||||
return lines
|
||||
|
||||
|
||||
def merge_into_openrouter(provider_id, models, dry_run=False):
|
||||
"""Append models from an OpenRouter-only provider into openrouter.toml.
|
||||
|
||||
Model IDs get the prefix "openrouter/{provider_id}/" so they stay
|
||||
unambiguous and match the existing openrouter.toml convention.
|
||||
Already-present IDs are skipped to keep the operation idempotent.
|
||||
"""
|
||||
openrouter_path = PROVIDERS_DIR / "openrouter.toml"
|
||||
if not openrouter_path.exists():
|
||||
return 0
|
||||
|
||||
existing = openrouter_path.read_text()
|
||||
existing_ids = set(re.findall(r'^id\s*=\s*"([^"]+)"', existing, re.MULTILINE))
|
||||
|
||||
new_lines = []
|
||||
for m in sorted(models, key=lambda x: x.get("id", "")):
|
||||
prefix = f"openrouter/{provider_id}/"
|
||||
f = _build_model_fields(provider_id, m, model_id_prefix=prefix)
|
||||
if f is None or f["model_id"] in existing_ids:
|
||||
continue
|
||||
# Append provider name to display so provenance is clear in the UI
|
||||
f["display"] = f'{f["display"]} (OpenRouter)'
|
||||
new_lines.extend(_model_lines(f))
|
||||
|
||||
if not new_lines:
|
||||
return 0
|
||||
|
||||
count = sum(1 for l in new_lines if l == "[[models]]")
|
||||
print(f" openrouter.toml: +{count} models from {provider_id}")
|
||||
if not dry_run:
|
||||
with open(openrouter_path, "a") as fh:
|
||||
fh.write("\n" + "\n".join(new_lines))
|
||||
return count
|
||||
|
||||
|
||||
def generate_provider_toml(provider_id, models, dry_run=False):
|
||||
"""Generate a new provider TOML file from OpenRouter data."""
|
||||
"""Generate a new standalone provider TOML file (direct-API providers only)."""
|
||||
our_name = PROVIDER_ALIAS.get(provider_id, provider_id)
|
||||
toml_path = PROVIDERS_DIR / f"{our_name}.toml"
|
||||
|
||||
@@ -150,13 +246,11 @@ def generate_provider_toml(provider_id, models, dry_run=False):
|
||||
if our_name in SKIP_DUPLICATES:
|
||||
return 0
|
||||
|
||||
# Check if provider has a known public API
|
||||
if our_name in PROVIDER_API:
|
||||
base_url, env_key = PROVIDER_API[our_name]
|
||||
else:
|
||||
# No known public API — route through OpenRouter
|
||||
base_url = "https://openrouter.ai/api/v1"
|
||||
env_key = "OPENROUTER_API_KEY"
|
||||
if our_name not in PROVIDER_API:
|
||||
# No direct public API — caller should use merge_into_openrouter instead.
|
||||
return 0
|
||||
|
||||
base_url, env_key = PROVIDER_API[our_name]
|
||||
key_required = "true"
|
||||
|
||||
lines = [
|
||||
@@ -173,45 +267,10 @@ def generate_provider_toml(provider_id, models, dry_run=False):
|
||||
|
||||
count = 0
|
||||
for m in sorted(models, key=lambda x: x.get("id", "")):
|
||||
model_id = m["id"].split("/")[-1] if "/" in m["id"] else m["id"]
|
||||
display = m.get("name", model_id)
|
||||
ctx = m.get("context_length", 0)
|
||||
max_out = m.get("top_provider", {}).get("max_completion_tokens", 0)
|
||||
inp, outp = parse_pricing(m)
|
||||
if inp is None:
|
||||
f = _build_model_fields(provider_id, m)
|
||||
if f is None:
|
||||
continue
|
||||
|
||||
supports_tools = "tool_use" in str(m.get("supported_parameters", []))
|
||||
supports_vision = "vision" in str(m.get("architecture", {}).get("modality", ""))
|
||||
|
||||
# Infer tier from pricing
|
||||
if inp == 0 and outp == 0:
|
||||
tier = "fast"
|
||||
elif inp < 0.5:
|
||||
tier = "fast"
|
||||
elif inp < 3.0:
|
||||
tier = "smart"
|
||||
else:
|
||||
tier = "frontier"
|
||||
|
||||
# Default max_output_tokens if not provided
|
||||
if not max_out:
|
||||
max_out = min(ctx // 4, 16384) if ctx > 0 else 4096
|
||||
|
||||
lines.append("[[models]]")
|
||||
lines.append(f'id = "{model_id}"')
|
||||
lines.append(f'display_name = "{display}"')
|
||||
lines.append(f'tier = "{tier}"')
|
||||
lines.append(f"context_window = {ctx}")
|
||||
lines.append(f"max_output_tokens = {max_out}")
|
||||
lines.append(f"input_cost_per_m = {inp}")
|
||||
lines.append(f"output_cost_per_m = {outp}")
|
||||
if supports_tools:
|
||||
lines.append("supports_tools = true")
|
||||
if supports_vision:
|
||||
lines.append("supports_vision = true")
|
||||
lines.append("supports_streaming = true")
|
||||
lines.append("")
|
||||
lines.extend(_model_lines(f))
|
||||
count += 1
|
||||
|
||||
if count == 0:
|
||||
@@ -257,10 +316,21 @@ def main():
|
||||
for provider_id, models in sorted(by_provider.items()):
|
||||
if provider_id in SKIP_PROVIDERS:
|
||||
continue
|
||||
# Skip OpenRouter internal auto-routing aliases (e.g. "~anthropic")
|
||||
# These are not real providers — they map to openrouter.toml.
|
||||
if provider_id.startswith("~"):
|
||||
continue
|
||||
our_name = PROVIDER_ALIAS.get(provider_id, provider_id)
|
||||
if not (PROVIDERS_DIR / f"{our_name}.toml").exists():
|
||||
if (PROVIDERS_DIR / f"{our_name}.toml").exists():
|
||||
continue
|
||||
if our_name in PROVIDER_API:
|
||||
# Provider has a known direct API — create a standalone file.
|
||||
count = generate_provider_toml(provider_id, models, dry_run=dry_run)
|
||||
total_created += count
|
||||
else:
|
||||
# No direct API — merge models into openrouter.toml instead of
|
||||
# creating a new file that just wraps the OpenRouter endpoint.
|
||||
count = merge_into_openrouter(provider_id, models, dry_run=dry_run)
|
||||
total_created += count
|
||||
|
||||
action = "Would" if dry_run else "Done:"
|
||||
print(f"\n{action} updated {total_updated} prices, created {total_created} new model entries")
|
||||
|
||||
+149
-40
@@ -1,52 +1,41 @@
|
||||
# Skills
|
||||
# Skills Registry
|
||||
|
||||
Reusable skill definitions for LibreFang agents. A skill is either a prompt
|
||||
template or a code script that an agent can invoke to perform a specific task.
|
||||
Skills are reusable expertise modules that can be attached to any agent. Each skill carries a system prompt that injects domain knowledge, best practices, and behavioral guidelines into an agent's context at conversation time. Skills are composable — a single agent can load multiple skills simultaneously.
|
||||
|
||||
## File Convention
|
||||
## File Format
|
||||
|
||||
Every skill directory **must** contain a `SKILL.md` (the entry point).
|
||||
A `skill.toml` is **optional** and only needed for structured metadata that
|
||||
does not fit in Markdown frontmatter (runtime, input schema, version, tags).
|
||||
A skill lives in its own subdirectory. The only required file is `SKILL.md`. An optional `skill.toml` provides structured metadata when `[runtime]`, `[input]` schema, or explicit versioning is needed.
|
||||
|
||||
```
|
||||
skills/
|
||||
├── docker/
|
||||
│ └── SKILL.md # Prompt-only expert — no skill.toml needed
|
||||
├── custom-skill-prompt/
|
||||
│ ├── SKILL.md # Prompt body + name/description
|
||||
│ └── skill.toml # Runtime + input schema
|
||||
└── custom-skill-python/
|
||||
├── SKILL.md # Overview (prompt body unused)
|
||||
├── skill.toml # Runtime = python, entry = main.py
|
||||
├── rust-expert/
|
||||
│ └── SKILL.md # required: frontmatter + prompt body
|
||||
├── meeting-agenda/
|
||||
│ ├── SKILL.md # required: frontmatter + prompt body
|
||||
│ └── skill.toml # optional: runtime type, input schema, version
|
||||
└── code-runner/
|
||||
├── SKILL.md # overview (prompt body unused for script skills)
|
||||
├── skill.toml # runtime = python, entry = main.py
|
||||
└── main.py
|
||||
```
|
||||
|
||||
### `SKILL.md` (required)
|
||||
|
||||
The source of truth for the skill's prompt and identity. Must start with YAML
|
||||
frontmatter containing at least `name` and `description`:
|
||||
### SKILL.md format
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: docker
|
||||
description: Docker expert for containers, Compose, and Dockerfiles.
|
||||
name: rust-expert
|
||||
description: "Rust programming expert for ownership, lifetimes, async/await, traits, and unsafe code"
|
||||
---
|
||||
# Rust Programming Expertise
|
||||
|
||||
You are a Docker specialist. You help users build, run, debug, and optimize
|
||||
containers...
|
||||
You are an expert Rust developer with deep understanding of the ownership system...
|
||||
```
|
||||
|
||||
This format is compatible with Claude Code skills, so a `SKILL.md` authored
|
||||
here can be dropped into other tools without modification.
|
||||
The frontmatter must contain `name` and `description`. The Markdown body becomes the injected prompt.
|
||||
|
||||
### `skill.toml` (optional)
|
||||
### skill.toml format (optional)
|
||||
|
||||
Add one only when you need to declare any of:
|
||||
|
||||
- `[runtime]` — `promptonly` / `python` / `node` / `shell` (default is `promptonly`)
|
||||
- `[input]` — typed input parameter schema
|
||||
- `version`, `author`, `tags` — structured metadata
|
||||
Only required when you need `[runtime]`, `[input]` schema, or structured metadata beyond what frontmatter supports:
|
||||
|
||||
```toml
|
||||
[skill]
|
||||
@@ -56,27 +45,147 @@ description = "Generate a structured meeting agenda from a topic and duration."
|
||||
tags = ["meeting", "productivity"]
|
||||
|
||||
[runtime]
|
||||
type = "promptonly"
|
||||
type = "promptonly" # promptonly | python | node | shell
|
||||
|
||||
[input]
|
||||
topic = { type = "string", description = "The meeting topic", required = true }
|
||||
duration_minutes = { type = "string", description = "Duration in minutes", required = true }
|
||||
```
|
||||
|
||||
**Consistency rule:** if both files exist, `skill.name` and `skill.description`
|
||||
in `skill.toml` must match the `name` and `description` in `SKILL.md`'s
|
||||
frontmatter. The validator enforces this to prevent drift.
|
||||
If both files exist, `skill.name` and `skill.description` in `skill.toml` must match the frontmatter in `SKILL.md`. The validator enforces this to prevent drift.
|
||||
|
||||
**Do not duplicate the prompt body in TOML.** The prompt lives in `SKILL.md`;
|
||||
`skill.toml` is for metadata the prompt cannot express.
|
||||
|
||||
## Testing Skills Locally
|
||||
## Installing and Using Skills
|
||||
|
||||
```bash
|
||||
librefang skill test ./skills/custom-skill-prompt \
|
||||
# List all available skills in the registry
|
||||
librefang catalog skills
|
||||
|
||||
# Attach a skill to an agent
|
||||
librefang skill attach <agent-name> rust-expert
|
||||
|
||||
# Attach multiple skills
|
||||
librefang skill attach <agent-name> rust-expert security-audit
|
||||
|
||||
# Detach a skill
|
||||
librefang skill detach <agent-name> rust-expert
|
||||
|
||||
# Test a skill locally with sample input
|
||||
librefang skill test ./skills/meeting-agenda \
|
||||
--input '{"topic": "Q1 planning", "duration_minutes": "30"}'
|
||||
```
|
||||
|
||||
## All Skills (61 total)
|
||||
|
||||
### Programming Languages
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| css-expert | CSS expert for flexbox, grid, animations, responsive design, and modern layout techniques |
|
||||
| golang-expert | Go programming expert for goroutines, channels, interfaces, modules, and concurrency patterns |
|
||||
| python-expert | Python expert for stdlib, packaging, type hints, async/await, and performance optimization |
|
||||
| rust-expert | Rust programming expert for ownership, lifetimes, async/await, traits, and unsafe code |
|
||||
| typescript-expert | TypeScript expert for type system, generics, utility types, and strict mode patterns |
|
||||
| wasm-expert | WebAssembly expert for WASI, component model, Rust/C compilation, and browser integration |
|
||||
|
||||
### Web Frameworks and APIs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| graphql-expert | GraphQL expert for schema design, resolvers, subscriptions, and performance optimization |
|
||||
| nextjs-expert | Next.js expert for App Router, SSR/SSG, API routes, middleware, and deployment |
|
||||
| oauth-expert | OAuth 2.0 and OpenID Connect expert for authorization flows, PKCE, and token management |
|
||||
| openapi-expert | OpenAPI/Swagger expert for API specification design, validation, and code generation |
|
||||
| react-expert | React expert for hooks, state management, Server Components, and performance optimization |
|
||||
|
||||
### Databases
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| elasticsearch | Elasticsearch expert for queries, mappings, aggregations, index management, and cluster operations |
|
||||
| mongodb | MongoDB operations expert for queries, aggregation pipelines, indexes, and schema design |
|
||||
| postgres-expert | PostgreSQL expert for query optimization, indexing, extensions, and database administration |
|
||||
| redis-expert | Redis expert for data structures, caching patterns, Lua scripting, and cluster operations |
|
||||
| sql-analyst | SQL query expert for optimization, schema design, and data analysis |
|
||||
| sqlite-expert | SQLite expert for WAL mode, query optimization, embedded patterns, and advanced features |
|
||||
| vector-db | Vector database expert for embeddings, similarity search, RAG patterns, and indexing strategies |
|
||||
|
||||
### Cloud and Infrastructure
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| ansible | Ansible automation expert for playbooks, roles, inventories, and infrastructure management |
|
||||
| aws | AWS cloud services expert for EC2, S3, Lambda, IAM, and AWS CLI |
|
||||
| azure | Microsoft Azure expert for az CLI, AKS, App Service, and cloud infrastructure |
|
||||
| docker | Docker expert for containers, Compose, Dockerfiles, and debugging |
|
||||
| gcp | Google Cloud Platform expert for gcloud CLI, GKE, Cloud Run, and managed services |
|
||||
| helm | Helm chart expert for Kubernetes package management, templating, and dependency management |
|
||||
| kubernetes | Kubernetes operations expert for kubectl, pods, deployments, and debugging |
|
||||
| nginx | Nginx configuration expert for reverse proxy, load balancing, TLS, and performance tuning |
|
||||
| terraform | Terraform IaC expert for providers, modules, state management, and planning |
|
||||
|
||||
### DevOps and CI/CD
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| ci-cd | CI/CD pipeline expert for GitHub Actions, GitLab CI, Jenkins, and deployment automation |
|
||||
| git-expert | Git operations expert for branching, rebasing, conflicts, and workflows |
|
||||
| github | GitHub operations expert for PRs, issues, code review, Actions, and gh CLI |
|
||||
| linux-networking | Linux networking expert for iptables, nftables, routing, DNS, and network troubleshooting |
|
||||
| prometheus | Prometheus monitoring expert for PromQL, alerting rules, Grafana dashboards, and observability |
|
||||
| sentry | Sentry error tracking and debugging specialist |
|
||||
| shell-scripting | Shell scripting expert for Bash, POSIX compliance, error handling, and automation |
|
||||
| sysadmin | System administration expert for Linux, macOS, Windows, services, and monitoring |
|
||||
|
||||
### Security
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| compliance | Compliance expert for SOC 2, GDPR, HIPAA, PCI-DSS, and security frameworks |
|
||||
| crypto-expert | Cryptography expert for TLS, symmetric/asymmetric encryption, hashing, and key management |
|
||||
| security-audit | Security audit expert for OWASP Top 10, CVE analysis, code review, and penetration testing methodology |
|
||||
|
||||
### AI and Machine Learning
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| llm-finetuning | LLM fine-tuning expert for LoRA, QLoRA, dataset preparation, and training optimization |
|
||||
| ml-engineer | Machine learning engineer expert for PyTorch, scikit-learn, model evaluation, and MLOps |
|
||||
| prompt-engineer | Prompt engineering expert for chain-of-thought, few-shot learning, evaluation, and LLM optimization |
|
||||
| web-search | Web search and research specialist for finding and synthesizing information |
|
||||
|
||||
### Productivity Tools
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| confluence | Confluence wiki expert for page structure, spaces, macros, and content organization |
|
||||
| figma-expert | Figma design expert for components, auto-layout, design systems, and developer handoff |
|
||||
| jira | Jira project management expert for issues, sprints, workflows, and reporting |
|
||||
| linear-tools | Linear project management expert for issues, cycles, projects, and workflow automation |
|
||||
| notion | Notion workspace management and content creation specialist |
|
||||
| pdf-reader | PDF content extraction and analysis specialist |
|
||||
| slack-tools | Slack workspace management and automation specialist |
|
||||
|
||||
### Writing and Communication
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| email-writer | Professional email writing expert for tone, structure, clarity, and business communication |
|
||||
| presentation | Presentation expert for slide structure, storytelling, visual design, and audience engagement |
|
||||
| technical-writer | Technical writing expert for API docs, READMEs, ADRs, and developer documentation |
|
||||
| writing-coach | Writing improvement specialist for grammar, style, clarity, and structure |
|
||||
|
||||
### Engineering Practice
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| api-tester | API testing expert for curl, REST, GraphQL, authentication, and debugging |
|
||||
| code-reviewer | Code review specialist focused on patterns, bugs, security, and performance |
|
||||
| data-analyst | Data analysis expert for statistics, visualization, pandas, and exploration |
|
||||
| data-pipeline | Data pipeline expert for ETL, Apache Spark, Airflow, dbt, and data quality |
|
||||
| interview-prep | Technical interview preparation expert for algorithms, system design, and behavioral questions |
|
||||
| project-manager | Project management expert for Agile, estimation, risk management, and stakeholder communication |
|
||||
| regex-expert | Regular expression expert for crafting, debugging, and explaining patterns |
|
||||
|
||||
## Adding a New Skill
|
||||
|
||||
1. Create `skills/<name>/SKILL.md` with frontmatter (`name`, `description`) and the prompt body.
|
||||
|
||||
Reference in new issue
Block a user