A desktop local AI gateway for protocol switching, fuzzy routing, quota monitoring, and cloud backup.
中文文档: docs/zh/README.md
- Keep one stable local endpoint while switching upstream providers.
- Route requests with fuzzy matching + longest-match algorithm.
- Track token usage and quota status per provider.
- Back up and restore configs with Remote Git.
- Auto-update the desktop app from GitHub Releases.
| Feature | Description | Where |
|---|---|---|
| Fuzzy routing | Match requests using fuzzy contains + longest-match | Service page |
| Protocol switching | Bridge OpenAI, Anthropic, Google request styles | Automatic |
| Quota monitoring | Show per-provider quota status (ok / low / empty) |
Provider cards |
| Token stats | Inspect per-request usage and aggregated trends | Logs page |
| Cloud backup (Git) | Upload/pull configs with conflict confirmation | Settings page |
| Auto updates | Check GitHub Releases and install automatically | Settings page |
Open the desktop app from your system launcher.
- Go to the Providers page.
- Add your API providers with protocol, token, and API endpoint.
- Test connectivity to ensure providers work.
- Open the Service page and create a group (e.g.,
alpha). - In the routing table, define rules:
default→ routes unmatched requestsclaude*→ routes Claude model requestsgpt-4*→ routes GPT-4 requests
- The group route prefix becomes
/oc/<groupId>/....
Use the integration panel to write the group config into your agent (Claude Code, Codex, or OpenCode).
Update the routing table in your group to point to a different provider.
Request matching uses a two-step algorithm:
- Fuzzy contains: Check if the request model contains any rule pattern (e.g.,
claude*matchesclaude-3-5-sonnet) - Longest match: If multiple patterns match, use the longest one
Example routing table:
default → OpenAI Main (gpt-4o)
claude* → Anthropic (claude-sonnet-4)
gemini* → Google AI (gemini-2.0-flash)
- Group path routing:
/oc/:groupId/... - Supported entry endpoints:
POST /oc/:groupId/chat/completionsPOST /oc/:groupId/responsesPOST /oc/:groupId/messages
POST /oc/:groupIdfalls back to chat-completions- Per request flow:
- Resolve
groupIdfrom path - Find matching route using fuzzy + longest-match
- Forward with target provider
- Translate payloads based on entry and provider protocols
- Resolve
Per-provider quota query supports:
endpoint,method,authHeader,authSchemeuseRuleToken/customTokenresponse.remaining,response.total,response.unit,response.resetAtlowThresholdPercent
Mapping examples:
{
"response": {
"remaining": "$.data.remaining_balance",
"unit": "$.data.currency",
"total": "$.data.total_balance",
"resetAt": "$.data.reset_at"
}
}Expressions support numeric literals, + - * /, parentheses, and JSONPath-style references.
- Real-time logs include status, protocol direction, upstream target, and token usage.
- Aggregated stats can be filtered by time range and provider.
- Log details support headers/bodies/errors (when
logging.captureBodyis enabled).
In Settings, configure repo URL + token + branch to:
- Upload local backup as
groups-rules-backup.json - Pull remote backup to local state
- Confirm before overwriting when timestamp conflicts are detected
In Settings, enable auto updates to:
- Check GitHub Releases for new versions
- Download and install updates in the background
- See release notes before installing
Usually no. In most cases, only the base URL changes to http://localhost:8899/oc/:groupId/....
The router checks if your request model contains any rule pattern. For example:
- Request model
claude-3-5-sonnet-20240620matches patternclaude* - If multiple patterns match, the longest pattern wins
Yes. Pull/import replaces current groups and providers, so export a local backup first.
From v0.2.15, when the app runs with HOME=/root, integration auto-detects root-level hidden config directories if the usual home path is missing:
/.claudewhen/root/.claudedoes not exist/.openclawwhen/root/.openclawdoes not exist/.codexwhen/root/.codexdoes not exist
If your config still lives somewhere else, you can add a custom integration target manually.
Provider tokens and Remote Git token are currently stored locally in plain text. Use minimum-scope credentials.
This can happen when the build is not notarized or signed with an Apple Developer ID. If you trust the source:
- Move the app to
~/Applicationsor/Applications. - In macOS, open
System Settings->Privacy & Security, then clickOpen Anywayfor AI Open Router. - If it still blocks, remove the quarantine flag and try again:
xattr -dr com.apple.quarantine "/Applications/AI Open Router.app"docs/dev-database.mddocs/release-process.mddocs/tauri-architecture.md
npm run check
npm run test
npm run cinpm run screenshots:mockGenerated files:
docs/assets/screenshots/service-page.pngdocs/assets/screenshots/providers-page.pngdocs/assets/screenshots/settings-page.pngdocs/assets/screenshots/logs-page.pngdocs/assets/screenshots/log-detail-page.png




