diff --git a/README.md b/README.md index a10c123e..bbbdfc49 100644 --- a/README.md +++ b/README.md @@ -544,12 +544,14 @@ curl -O https://raw.githubusercontent.com/HKUDS/DeepCode/main/mcp_agent.secrets. # - openai: api_key, base_url (for OpenAI/custom endpoints) # - anthropic: api_key (for Claude models) # - google: api_key (for Gemini models) +# - openrouter: api_key (for unified access to multiple LLM providers) # 🤖 Select your preferred LLM provider (optional) # Edit mcp_agent.config.yaml to choose your LLM (line ~106): # - llm_provider: "google" # Use Google Gemini models # - llm_provider: "anthropic" # Use Anthropic Claude models # - llm_provider: "openai" # Use OpenAI/compatible models +# - llm_provider: "openrouter" # Use OpenRouter (single key for multiple providers) # Note: If not set or unavailable, will automatically fallback to first available provider # 🔑 Configure search API keys for web search (optional) @@ -915,4 +917,4 @@ If you find DeepCode useful in your research or applications, please kindly cite Visitors - + \ No newline at end of file diff --git a/mcp_agent.config.yaml b/mcp_agent.config.yaml index fd8a6e93..0ac741a8 100644 --- a/mcp_agent.config.yaml +++ b/mcp_agent.config.yaml @@ -1,5 +1,4 @@ $schema: ./schema/mcp-agent.config.schema.json -anthropic: null default_search_server: brave document_segmentation: enabled: false @@ -101,9 +100,9 @@ mcp: env: PYTHONPATH: . # LLM Provider Priority (选择使用哪个LLM / Choose which LLM to use) -# Options: "anthropic", "google", "openai" +# Options: "anthropic", "google", "openai", "openrouter" # If not set or provider unavailable, will fallback to first available provider -llm_provider: "google" # 设置为 "google", "anthropic", 或 "openai" +llm_provider: "google" # 设置为 "google", "anthropic", "openai", 或 "openrouter" openai: base_max_tokens: 40000 @@ -123,4 +122,12 @@ google: anthropic: default_model: "claude-sonnet-4.5" -planning_mode: traditional +# Configuration for OpenRouter (unified LLM gateway) +openrouter: + base_url: "https://openrouter.ai/api/v1" + default_model: "anthropic/claude-sonnet-4" # Use provider/model format + base_max_tokens: 40000 + max_tokens_policy: adaptive + retry_max_tokens: 32768 + +planning_mode: traditional \ No newline at end of file diff --git a/mcp_agent.secrets.yaml b/mcp_agent.secrets.yaml index 6c797f1f..ed4c0943 100644 --- a/mcp_agent.secrets.yaml +++ b/mcp_agent.secrets.yaml @@ -5,3 +5,5 @@ anthropic: api_key: "" google: api_key: "" +openrouter: + api_key: "" \ No newline at end of file diff --git a/schema/mcp-agent.config.schema.json b/schema/mcp-agent.config.schema.json index 3bf5d908..d8c3c4a1 100644 --- a/schema/mcp-agent.config.schema.json +++ b/schema/mcp-agent.config.schema.json @@ -456,6 +456,36 @@ "title": "OpenAISettings", "type": "object" }, + "OpenRouterSettings": { + "additionalProperties": true, + "description": "Settings for using OpenRouter as a unified LLM gateway.", + "properties": { + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Api Key" + }, + "base_url": { + "default": "https://openrouter.ai/api/v1", + "title": "Base Url", + "type": "string" + }, + "default_model": { + "default": "anthropic/claude-sonnet-4", + "title": "Default Model", + "type": "string" + } + }, + "title": "OpenRouterSettings", + "type": "object" + }, "AzureSettings": { "additionalProperties": true, "description": "Settings for using Azure models in the MCP Agent application.", @@ -744,6 +774,37 @@ "default": null, "description": "Settings for using OpenAI models in the MCP Agent application" }, + "openrouter": { + "anyOf": [ + { + "$ref": "#/$defs/OpenRouterSettings" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Settings for using OpenRouter as a unified LLM gateway" + }, + "llm_provider": { + "anyOf": [ + { + "enum": [ + "anthropic", + "google", + "openai", + "openrouter" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "LLM Provider", + "description": "Preferred LLM provider to use. Options: anthropic, google, openai, openrouter" + }, "azure": { "anyOf": [ { @@ -817,4 +878,4 @@ "title": "MCP Agent Configuration Schema", "type": "object", "$schema": "http://json-schema.org/draft-07/schema#" -} +} \ No newline at end of file diff --git a/utils/llm_utils.py b/utils/llm_utils.py index f8bbccdd..737358ec 100644 --- a/utils/llm_utils.py +++ b/utils/llm_utils.py @@ -43,6 +43,7 @@ def get_preferred_llm_class(config_path: str = "mcp_agent.secrets.yaml") -> Type anthropic_key = secrets.get("anthropic", {}).get("api_key", "").strip() google_key = secrets.get("google", {}).get("api_key", "").strip() openai_key = secrets.get("openai", {}).get("api_key", "").strip() + openrouter_key = secrets.get("openrouter", {}).get("api_key", "").strip() # Read user preference from main config main_config_path = "mcp_agent.config.yaml" @@ -61,6 +62,7 @@ def get_preferred_llm_class(config_path: str = "mcp_agent.secrets.yaml") -> Type ), "google": (GoogleAugmentedLLM, google_key, "GoogleAugmentedLLM"), "openai": (OpenAIAugmentedLLM, openai_key, "OpenAIAugmentedLLM"), + "openrouter": (OpenAIAugmentedLLM, openrouter_key, "OpenAIAugmentedLLM (OpenRouter)"), } # Try user's preferred provider first @@ -149,17 +151,20 @@ def get_default_models(config_path: str = "mcp_agent.config.yaml"): anthropic_config = config.get("anthropic") or {} openai_config = config.get("openai") or {} google_config = config.get("google") or {} + openrouter_config = config.get("openrouter") or {} anthropic_model = anthropic_config.get( "default_model", "claude-sonnet-4-20250514" ) openai_model = openai_config.get("default_model", "o3-mini") google_model = google_config.get("default_model", "gemini-2.0-flash") + openrouter_model = openrouter_config.get("default_model", "anthropic/claude-sonnet-4") return { "anthropic": anthropic_model, "openai": openai_model, "google": google_model, + "openrouter": openrouter_model, } else: print(f"Config file {config_path} not found, using default models")