2026-03-19 04:32:29 -04:00
// MITM Tools — IDE tools intercepted via MITM proxy
export const MITM _TOOLS = {
2026-03-02 21:53:30 -05:00
antigravity : {
id : "antigravity" ,
name : "Antigravity" ,
image : "/providers/antigravity.png" ,
color : "#4285F4" ,
description : "Google Antigravity IDE with MITM" ,
configType : "mitm" ,
2026-03-04 23:25:03 -05:00
mitmDomain : "daily-cloudcode-pa.googleapis.com" ,
2026-03-02 21:53:30 -05:00
modelAliases : [ "claude-opus-4-6-thinking" , "claude-sonnet-4-6" , "gemini-3-flash" , "gpt-oss-120b-medium" , "gemini-3-pro-high" , "gemini-3-pro-low" ] ,
defaultModels : [
{ id : "gemini-3.1-pro-high" , name : "Gemini 3.1 Pro High" , alias : "gemini-3.1-pro-high" } ,
{ id : "gemini-3.1-pro-low" , name : "Gemini 3.1 Pro Low" , alias : "gemini-3.1-pro-low" } ,
2026-04-29 00:34:39 -04:00
{ id : "gemini-3-flash" , name : "Gemini 3 Flash / Default" , alias : "gemini-3-flash" } ,
2026-03-02 21:53:30 -05:00
{ id : "claude-sonnet-4-6" , name : "Claude Sonnet 4.6" , alias : "claude-sonnet-4-6" } ,
{ id : "claude-opus-4-6-thinking" , name : "Claude Opus 4.6 Thinking" , alias : "claude-opus-4-6-thinking" } ,
{ id : "gpt-oss-120b-medium" , name : "GPT OSS 120B Medium" , alias : "gpt-oss-120b-medium" } ,
] ,
} ,
2026-03-04 23:25:03 -05:00
copilot : {
id : "copilot" ,
name : "GitHub Copilot" ,
image : "/providers/copilot.png" ,
color : "#1F6FEB" ,
description : "GitHub Copilot IDE with MITM" ,
configType : "mitm" ,
mitmDomain : "api.individual.githubcopilot.com" ,
modelAliases : [ "gpt-4o-mini" , "claude-haiku-4.5" , "gpt-4o" , "gpt-5-mini" ] ,
defaultModels : [
{ id : "gpt-4o" , name : "GPT-4o" , alias : "gpt-4o" } ,
{ id : "gpt-4.1" , name : "GPT-4.1" , alias : "gpt-4.1" } ,
{ id : "claude-haiku-4.5" , name : "Claude Haiku 4.5" , alias : "claude-haiku-4.5" } ,
] ,
} ,
2026-03-17 05:12:25 -04:00
kiro : {
id : "kiro" ,
name : "Kiro" ,
image : "/providers/kiro.png" ,
color : "#FF6B00" ,
description : "Kiro IDE with MITM" ,
configType : "mitm" ,
mitmDomain : "q.us-east-1.amazonaws.com" ,
defaultModels : [
{ id : "claude-sonnet-4.5" , name : "Claude Sonnet 4.5" , alias : "claude-sonnet-4.5" } ,
{ id : "claude-sonnet-4" , name : "Claude Sonnet 4" , alias : "claude-sonnet-4" } ,
{ id : "claude-haiku-4.5" , name : "Claude Haiku 4.5" , alias : "claude-haiku-4.5" } ,
{ id : "deepseek-3.2" , name : "DeepSeek 3.2" , alias : "deepseek-3.2" } ,
{ id : "minimax-m2.1" , name : "MiniMax M2.1" , alias : "minimax-m2.1" } ,
{ id : "simple-task" , name : "Qwen3 Coder Next" , alias : "simple-task" } ,
] ,
} ,
2026-03-19 04:32:29 -04:00
// cursor: {
// id: "cursor",
// name: "Cursor",
// image: "/providers/cursor.png",
// color: "#000000",
// description: "Cursor IDE with MITM",
// configType: "mitm",
// mitmDomain: "api2.cursor.sh",
// defaultModels: [
// { id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5", alias: "claude-sonnet-4-5" },
// { id: "claude-opus-4", name: "Claude Opus 4", alias: "claude-opus-4" },
// { id: "gpt-4o", name: "GPT-4o", alias: "gpt-4o" },
// ],
// },
} ;
// CLI Tools configuration
export const CLI _TOOLS = {
claude : {
id : "claude" ,
name : "Claude Code" ,
icon : "terminal" ,
color : "#D97757" ,
description : "Anthropic Claude Code CLI" ,
configType : "env" ,
envVars : {
baseUrl : "ANTHROPIC_BASE_URL" ,
model : "ANTHROPIC_MODEL" ,
opusModel : "ANTHROPIC_DEFAULT_OPUS_MODEL" ,
sonnetModel : "ANTHROPIC_DEFAULT_SONNET_MODEL" ,
haikuModel : "ANTHROPIC_DEFAULT_HAIKU_MODEL" ,
} ,
modelAliases : [ "default" , "sonnet" , "opus" , "haiku" , "opusplan" ] ,
settingsFile : "~/.claude/settings.json" ,
defaultModels : [
{ id : "opus" , name : "Claude Opus" , alias : "opus" , envKey : "ANTHROPIC_DEFAULT_OPUS_MODEL" , defaultValue : "cc/claude-opus-4-6" } ,
{ id : "sonnet" , name : "Claude Sonnet" , alias : "sonnet" , envKey : "ANTHROPIC_DEFAULT_SONNET_MODEL" , defaultValue : "cc/claude-sonnet-4-6" } ,
{ id : "haiku" , name : "Claude Haiku" , alias : "haiku" , envKey : "ANTHROPIC_DEFAULT_HAIKU_MODEL" , defaultValue : "cc/claude-haiku-4-5-20251001" } ,
] ,
} ,
openclaw : {
id : "openclaw" ,
name : "Open Claw" ,
image : "/providers/openclaw.png" ,
color : "#FF6B35" ,
description : "Open Claw AI Assistant" ,
configType : "custom" ,
} ,
codex : {
id : "codex" ,
2026-05-08 22:53:06 -04:00
name : "OpenAI Codex CLI / App" ,
2026-03-19 04:32:29 -04:00
image : "/providers/codex.png" ,
color : "#10A37F" ,
description : "OpenAI Codex CLI" ,
configType : "custom" ,
} ,
opencode : {
id : "opencode" ,
name : "OpenCode" ,
image : "/providers/opencode.png" ,
color : "#E87040" ,
description : "OpenCode AI Terminal Assistant" ,
configType : "custom" ,
} ,
feat: add STT support, Gemini TTS, and expand usage tracking
- Speech-to-Text: full pipeline with sttCore handler, /v1/audio/transcriptions
endpoint, sttConfig for OpenAI, Gemini, Groq, Deepgram, AssemblyAI,
HuggingFace, NVIDIA Parakeet; new 9router-stt skill
- Gemini TTS: add gemini provider with 30 prebuilt voices and TTS_PROVIDER_CONFIG
- Usage: implement GLM (intl/cn) and MiniMax (intl/cn) quota fetchers; refactor
Gemini CLI usage to use retrieveUserQuota with per-model buckets
- Disabled models: lowdb-backed disabledModelsDb + /api/models/disabled route
- Header search: reusable Zustand store (headerSearchStore) wired into Header
- CLI tools: add Claude Cowork tool card and cowork-settings API
- Providers: introduce mediaPriority sorting in getProvidersByKind, add
Kimi K2.6, reorder hermes, drop qwen STT kind
- UI: expand media-providers/[kind]/[id] page (+314), enhance OAuthModal,
ModelSelectModal, ProviderTopology, ProxyPools, ProviderLimits
- Assets: refresh provider PNGs (alicode, byteplus, cloudflare-ai, nvidia,
ollama, vertex, volcengine-ark) and add aws-polly, fal-ai, jina-ai, recraft,
runwayml, stability-ai, topaz, black-forest-labs
2026-05-04 23:32:59 -04:00
cowork : {
id : "cowork" ,
name : "Claude Cowork" ,
image : "/providers/claude.png" ,
color : "#D97757" ,
description : "Claude Desktop Cowork (third-party inference)" ,
configType : "custom" ,
} ,
hermes : {
id : "hermes" ,
name : "Hermes Agent" ,
image : "/providers/hermes.png" ,
color : "#8B5CF6" ,
description : "Nous Research self-improving AI agent" ,
configType : "custom" ,
} ,
2026-02-06 08:53:20 -05:00
droid : {
id : "droid" ,
name : "Factory Droid" ,
image : "/providers/droid.png" ,
color : "#00D4FF" ,
description : "Factory Droid AI Assistant" ,
configType : "custom" ,
} ,
2026-01-04 21:58:59 -05:00
cursor : {
id : "cursor" ,
name : "Cursor" ,
image : "/providers/cursor.png" ,
color : "#000000" ,
description : "Cursor AI Code Editor" ,
configType : "guide" ,
2026-03-02 22:10:03 -05:00
requiresExternalUrl : true ,
2026-01-04 21:58:59 -05:00
notes : [
{ type : "warning" , text : "Requires Cursor Pro account to use this feature." } ,
2026-03-02 22:10:03 -05:00
{ type : "cloudCheck" , text : "Cursor routes requests through its own server, so local endpoint is not supported. Please enable Tunnel or Cloud Endpoint in Settings." } ,
2026-01-04 21:58:59 -05:00
] ,
guideSteps : [
{ step : 1 , title : "Open Settings" , desc : "Go to Settings → Models" } ,
{ step : 2 , title : "Enable OpenAI API" , desc : "Enable \"OpenAI API key\" option" } ,
2026-01-20 23:45:19 -05:00
{ step : 3 , title : "Base URL" , value : "{{baseUrl}}" , copyable : true } ,
2026-01-04 21:58:59 -05:00
{ step : 4 , title : "API Key" , type : "apiKeySelector" } ,
{ step : 5 , title : "Add Custom Model" , desc : "Click \"View All Model\" → \"Add Custom Model\"" } ,
{ step : 6 , title : "Select Model" , type : "modelSelector" } ,
] ,
} ,
cline : {
id : "cline" ,
2026-01-18 22:39:30 -05:00
name : "Cline" ,
2026-01-04 21:58:59 -05:00
image : "/providers/cline.png" ,
color : "#00D1B2" ,
2026-03-02 21:53:30 -05:00
description : "Cline AI Coding Assistant" ,
2026-05-10 10:54:54 -04:00
configType : "custom" ,
2026-03-02 21:53:30 -05:00
} ,
kilo : {
id : "kilo" ,
name : "Kilo Code" ,
image : "/providers/kilocode.png" ,
color : "#FF6B6B" ,
description : "Kilo Code AI Assistant" ,
2026-05-10 10:54:54 -04:00
configType : "custom" ,
2026-01-04 21:58:59 -05:00
} ,
roo : {
id : "roo" ,
name : "Roo" ,
image : "/providers/roo.png" ,
color : "#FF6B6B" ,
description : "Roo AI Assistant" ,
configType : "guide" ,
guideSteps : [
{ step : 1 , title : "Open Settings" , desc : "Go to Roo Settings panel" } ,
{ step : 2 , title : "Select Provider" , desc : "Choose API Provider → Ollama" } ,
{ step : 3 , title : "Base URL" , value : "{{baseUrl}}" , copyable : true } ,
{ step : 4 , title : "API Key" , type : "apiKeySelector" } ,
{ step : 5 , title : "Select Model" , type : "modelSelector" } ,
] ,
} ,
continue : {
id : "continue" ,
name : "Continue" ,
image : "/providers/continue.png" ,
color : "#7C3AED" ,
description : "Continue AI Assistant" ,
configType : "guide" ,
guideSteps : [
{ step : 1 , title : "Open Config" , desc : "Open Continue configuration file" } ,
{ step : 2 , title : "API Key" , type : "apiKeySelector" } ,
{ step : 3 , title : "Select Model" , type : "modelSelector" } ,
{ step : 4 , title : "Add Model Config" , desc : "Add the following configuration to your models array:" } ,
] ,
codeBlock : {
language : "json" ,
code : ` {
"apiBase" : "{{baseUrl}}" ,
"title" : "{{model}}" ,
"model" : "{{model}}" ,
"provider" : "openai" ,
"apiKey" : "{{apiKey}}"
2026-05-11 22:19:50 -04:00
} ` ,
} ,
} ,
amp : {
id : "amp" ,
name : "Amp CLI" ,
icon : "terminal" ,
color : "#F97316" ,
description : "Sourcegraph Amp coding assistant CLI" ,
docsUrl : "/docs?section=cli-tools&tool=amp" ,
configType : "guide" ,
defaultCommand : "amp" ,
modelAliases : [ "g25p" , "g25f" , "cs45" , "g54" ] ,
notes : [
{ type : "info" , text : "Use 9Router model aliases to keep Amp shorthand mappings stable across provider updates." } ,
{ type : "warning" , text : "Suggested shorthand examples: g25p → gemini/gemini-2.5-pro, g25f → gemini/gemini-2.5-flash, cs45 → cc/claude-sonnet-4-5-20250929." } ,
] ,
guideSteps : [
{ step : 1 , title : "Install Amp" , desc : "Install the Amp CLI using the package manager supported by your environment." } ,
{ step : 2 , title : "API Key" , type : "apiKeySelector" } ,
{ step : 3 , title : "Base URL" , value : "{{baseUrl}}" , copyable : true } ,
{ step : 4 , title : "Select Model" , type : "modelSelector" } ,
{ step : 5 , title : "Add Shorthands" , desc : "Map Amp shorthand names such as g25p or cs45 to 9Router aliases in your local config." } ,
] ,
codeBlock : {
language : "bash" ,
code : ` export OPENAI_API_KEY="{{apiKey}}"
export OPENAI _BASE _URL = "{{baseUrl}}"
amp -- model "{{model}}"
# Example shorthand aliases you can map locally :
# g25p - > gemini / gemini - 2.5 - pro
# cs45 - > cc / claude - sonnet - 4 - 5 - 20250929 ` ,
} ,
} ,
qwen : {
id : "qwen" ,
name : "Qwen Code" ,
icon : "psychology" ,
color : "#10B981" ,
description : "Alibaba Qwen Code CLI — supports OpenAI, Anthropic & Gemini providers via 9Router" ,
docsUrl : "https://qwenlm.github.io/qwen-code-docs/en/users/configuration/model-providers/" ,
configType : "guide" ,
defaultCommand : "qwen" ,
notes : [
{ type : "info" , text : "Qwen Code supports multiple provider types (openai, anthropic, gemini) via modelProviders in settings.json. 9Router works as an OpenAI-compatible endpoint." } ,
{ type : "info" , text : "Any model available in 9Router can be used — not just Qwen models. Select from Qwen, Claude, Gemini, GPT, and more." } ,
{ type : "warning" , text : "Config path: Linux/macOS ~/.qwen/settings.json • Windows %USERPROFILE%\\.qwen\\settings.json" } ,
{ type : "error" , text : "Qwen OAuth free tier was discontinued on 2026-04-15. Use 9Router with alicode/openrouter/anthropic/gemini providers instead." } ,
] ,
modelAliases : [ "coder-model" , "qwen3-coder-plus" , "qwen3-coder-flash" , "vision-model" , "claude-sonnet-4-6" , "claude-opus-4-6-thinking" , "gemini-3-flash" , "gemini-3.1-pro-high" ] ,
defaultModels : [
{ id : "coder-model" , name : "Coder Model (Qwen 3.6 Plus)" , alias : "coder-model" , envKey : "OPENAI_MODEL" , defaultValue : "coder-model" , isTopLevel : true } ,
{ id : "qwen3-coder-plus" , name : "Qwen 3 Coder Plus" , alias : "qwen3-coder-plus" , envKey : "OPENAI_MODEL" , defaultValue : "qwen3-coder-plus" } ,
{ id : "qwen3-coder-flash" , name : "Qwen 3 Coder Flash" , alias : "qwen3-coder-flash" , envKey : "OPENAI_MODEL" , defaultValue : "qwen3-coder-flash" } ,
{ id : "vision-model" , name : "Vision Model (Multimodal)" , alias : "vision-model" , envKey : "OPENAI_MODEL" , defaultValue : "vision-model" } ,
{ id : "claude-sonnet-4-6" , name : "Claude Sonnet 4.6" , alias : "claude-sonnet-4-6" , envKey : "OPENAI_MODEL" , defaultValue : "claude-sonnet-4-6" } ,
{ id : "claude-opus-4-6-thinking" , name : "Claude Opus 4.6 Thinking" , alias : "claude-opus-4-6-thinking" , envKey : "OPENAI_MODEL" , defaultValue : "claude-opus-4-6-thinking" } ,
{ id : "gemini-3.1-pro-high" , name : "Gemini 3.1 Pro High" , alias : "gemini-3.1-pro-high" , envKey : "OPENAI_MODEL" , defaultValue : "gemini-3.1-pro-high" } ,
{ id : "gemini-3-flash" , name : "Gemini 3 Flash" , alias : "gemini-3-flash" , envKey : "OPENAI_MODEL" , defaultValue : "gemini-3-flash" } ,
] ,
guideSteps : [
{ step : 1 , title : "Install Qwen Code" , desc : "npm install -g @qwen-code/qwen-code" } ,
{ step : 2 , title : "API Key" , type : "apiKeySelector" } ,
{ step : 3 , title : "Base URL" , value : "{{baseUrl}}" , copyable : true } ,
{ step : 4 , title : "Select Model" , type : "modelSelector" } ,
{ step : 5 , title : "Save Config" , desc : "Copy the JSON below to your ~/.qwen/settings.json file." } ,
] ,
codeBlock : {
language : "json" ,
code : ` {
"security" : {
"auth" : {
"selectedType" : "openai" ,
"apiKey" : "{{apiKey}}" ,
"baseUrl" : "{{baseUrl}}"
}
} ,
"model" : {
"name" : "{{model}}"
}
2026-01-04 21:58:59 -05:00
} ` ,
} ,
} ,
// HIDDEN: gemini-cli
// "gemini-cli": {
// id: "gemini-cli",
// name: "Gemini CLI",
// icon: "terminal",
// color: "#4285F4",
// description: "Google Gemini CLI",
// configType: "env",
// envVars: {
// baseUrl: "GEMINI_API_BASE_URL",
// model: "GEMINI_MODEL",
// },
// defaultModels: [
// { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", alias: "pro" },
// { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash", alias: "flash" },
// ],
// },
} ;
// Get all provider models for mapping dropdown
export const getProviderModelsForMapping = ( providers ) => {
const result = [ ] ;
providers . forEach ( conn => {
if ( conn . isActive && ( conn . testStatus === "active" || conn . testStatus === "success" ) ) {
result . push ( {
connectionId : conn . id ,
provider : conn . provider ,
name : conn . name ,
models : conn . models || [ ] ,
} ) ;
}
} ) ;
return result ;
} ;