diff --git a/desktop/src/renderer/src/App.tsx b/desktop/src/renderer/src/App.tsx index b660d77..365f291 100644 --- a/desktop/src/renderer/src/App.tsx +++ b/desktop/src/renderer/src/App.tsx @@ -483,6 +483,9 @@ export function App() { if (provider?.model) { form.setValue("model", provider.model, { shouldValidate: true }); } + if (provider) { + form.setValue("apiBase", provider.apiBase, { shouldValidate: true }); + } return; } @@ -493,6 +496,9 @@ export function App() { if (provider?.model) { form.setValue("workerModel", provider.model, { shouldValidate: true }); } + if (provider) { + form.setValue("workerApiBase", provider.apiBase, { shouldValidate: true }); + } } function toggleSearchProvider(providerId: "brave" | "firecrawl") { diff --git a/desktop/src/renderer/src/lib/install.ts b/desktop/src/renderer/src/lib/install.ts index 4769365..c2ee1ab 100644 --- a/desktop/src/renderer/src/lib/install.ts +++ b/desktop/src/renderer/src/lib/install.ts @@ -7,15 +7,26 @@ export function isExistingSecret(value: string | undefined | null): boolean { } export const providers = [ - { id: "openrouter", label: "OpenRouter", model: "anthropic/claude-sonnet-4" }, - { id: "zai", label: "Z.AI", model: "glm-4.6" }, - { id: "openai", label: "OpenAI", model: "gpt-5.2" }, - { id: "anthropic", label: "Anthropic", model: "claude-sonnet-4-5" }, - { id: "google", label: "Google Gemini", model: "gemini-2.5-pro" }, - { id: "mistral", label: "Mistral", model: "mistral-large-latest" }, - { id: "together", label: "Together AI", model: "meta-llama/Llama-3.3-70B-Instruct-Turbo" }, - { id: "groq", label: "Groq", model: "llama-3.3-70b-versatile" }, - { id: "custom", label: "Custom LiteLLM", model: "" }, + { + id: "openrouter", + label: "OpenRouter", + model: "x-ai/grok-4.3", + apiBase: "https://openrouter.ai/api/v1", + }, + { id: "zai", label: "Z.AI", model: "glm-5.1", apiBase: "https://api.z.ai/api/coding/paas/v4" }, + { id: "openai", label: "OpenAI", model: "gpt-5.5", apiBase: "https://api.openai.com/v1" }, + { id: "anthropic", label: "Anthropic", model: "claude-opus-4-7", apiBase: "https://api.anthropic.com" }, + { id: "google", label: "Google Gemini", model: "gemini-3.1-pro-preview", apiBase: "" }, + { id: "mistral", label: "Mistral", model: "mistral-medium-3-5+1", apiBase: "https://api.mistral.ai/v1" }, + { + id: "together", + label: "Together AI", + model: "moonshotai/Kimi-K2.5", + apiBase: "https://api.together.xyz/v1", + }, + { id: "groq", label: "Groq", model: "openai/gpt-oss-120b", apiBase: "https://api.groq.com/openai/v1" }, + { id: "minimax", label: "Minimax", model: "MiniMax-M2.7", apiBase: "https://api.minimax.io/anthropic/v1" }, + { id: "custom", label: "Custom LiteLLM", model: "", apiBase: "" }, ] as const; export const searchProviders = [ @@ -151,12 +162,12 @@ export const defaultInstallValues: InstallForm = { whatsappMode: "separate", whatsappAllowedNumbers: "", providerId: "openrouter", - model: "anthropic/claude-sonnet-4", + model: "x-ai/grok-4.3", apiKey: "", apiBase: "", sameWorker: false, workerProviderId: "openrouter", - workerModel: "anthropic/claude-sonnet-4", + workerModel: "x-ai/grok-4.3", workerApiKey: "", workerApiBase: "", searchProvider: undefined, diff --git a/src/octopal/infrastructure/config/settings.py b/src/octopal/infrastructure/config/settings.py index 070c1c6..8333a76 100644 --- a/src/octopal/infrastructure/config/settings.py +++ b/src/octopal/infrastructure/config/settings.py @@ -48,7 +48,7 @@ class Settings(BaseSettings): # OpenRouter Settings (used via LiteLLM with openrouter/ model prefix) openrouter_api_key: str | None = Field(default=None, alias="OPENROUTER_API_KEY") openrouter_base_url: str = Field("https://openrouter.ai/api/v1", alias="OPENROUTER_BASE_URL") - openrouter_model: str = Field("anthropic/claude-sonnet-4", alias="OPENROUTER_MODEL") + openrouter_model: str = Field("x-ai/grok-4.3", alias="OPENROUTER_MODEL") openrouter_timeout: float = Field(120.0, alias="OPENROUTER_TIMEOUT") # Legacy ZAI Settings (used as defaults for LiteLLM) @@ -58,7 +58,7 @@ class Settings(BaseSettings): zai_timeout_seconds: float = Field(45.0, alias="ZAI_TIMEOUT_SECONDS") zai_connect_timeout_seconds: float = Field(15.0, alias="ZAI_CONNECT_TIMEOUT_SECONDS") zai_accept_language: str = Field("en-US,en", alias="ZAI_ACCEPT_LANGUAGE") - zai_model: str = Field("glm-5", alias="ZAI_MODEL") + zai_model: str = Field("glm-5.1", alias="ZAI_MODEL") minimax_api_key: str | None = Field(default=None, alias="MINIMAX_API_KEY") diff --git a/src/octopal/infrastructure/providers/catalog.py b/src/octopal/infrastructure/providers/catalog.py index 1eeac4a..b13cac4 100644 --- a/src/octopal/infrastructure/providers/catalog.py +++ b/src/octopal/infrastructure/providers/catalog.py @@ -26,7 +26,7 @@ class ProviderCatalogEntry: id="openrouter", label="OpenRouter", description="Hosted model router with OpenRouter model ids.", - default_model="anthropic/claude-sonnet-4", + default_model="x-ai/grok-4.3", model_prefix="openrouter", always_prefix_model=True, default_api_base="https://openrouter.ai/api/v1", @@ -38,7 +38,7 @@ class ProviderCatalogEntry: id="zai", label="Z.ai (Coding plan)", description="GLM and Coding Plan endpoints via OpenAI-compatible LiteLLM routing.", - default_model="glm-5", + default_model="glm-5.1", model_prefix="openai", default_api_base="https://api.z.ai/api/coding/paas/v4", api_key_label="Z.ai API key", @@ -49,7 +49,7 @@ class ProviderCatalogEntry: id="openai", label="OpenAI", description="Direct OpenAI API access through LiteLLM.", - default_model="gpt-4.1-mini", + default_model="gpt-5.5", model_prefix="openai", default_api_base="https://api.openai.com/v1", api_key_label="OpenAI API key", @@ -60,7 +60,7 @@ class ProviderCatalogEntry: id="anthropic", label="Anthropic", description="Direct Anthropic Messages API through LiteLLM.", - default_model="claude-sonnet-4-20250514", + default_model="claude-opus-4-7", model_prefix="anthropic", default_api_base="https://api.anthropic.com", api_key_label="Anthropic API key", @@ -71,7 +71,7 @@ class ProviderCatalogEntry: id="google", label="Google Gemini", description="Gemini API via LiteLLM.", - default_model="gemini-2.0-flash", + default_model="gemini-3.1-pro-preview", model_prefix="gemini", default_api_base=None, supports_custom_base_url=False, @@ -82,7 +82,7 @@ class ProviderCatalogEntry: id="mistral", label="Mistral AI", description="Hosted Mistral API.", - default_model="mistral-medium-latest", + default_model="mistral-medium-3-5+1", model_prefix="mistral", default_api_base="https://api.mistral.ai/v1", api_key_label="Mistral API key", @@ -93,7 +93,7 @@ class ProviderCatalogEntry: id="together", label="Together AI", description="Hosted open-model access through Together AI.", - default_model="meta-llama/Llama-3.3-70B-Instruct-Turbo", + default_model="moonshotai/Kimi-K2.5", model_prefix="together_ai", default_api_base="https://api.together.xyz/v1", api_key_label="Together API key", @@ -104,7 +104,7 @@ class ProviderCatalogEntry: id="groq", label="Groq", description="Fast hosted inference with OpenAI-compatible API surface.", - default_model="llama-3.3-70b-versatile", + default_model="openai/gpt-oss-120b", model_prefix="groq", default_api_base="https://api.groq.com/openai/v1", api_key_label="Groq API key", @@ -127,7 +127,7 @@ class ProviderCatalogEntry: id="minimax", label="Minimax (Token plan)", description="MiniMax API (M2.5, M2.7, etc.) via LiteLLM.", - default_model="minimax-m2.5", + default_model="MiniMax-M2.7", model_prefix="minimax", default_api_base="https://api.minimax.io/anthropic/v1", api_key_label="Minimax API key", @@ -138,7 +138,7 @@ class ProviderCatalogEntry: id="custom", label="Custom OpenAI-compatible", description="Any custom LiteLLM target with configurable base URL and model prefix.", - default_model="gpt-4.1-mini", + default_model="gpt-5.5", model_prefix="openai", default_api_base="http://localhost:8000/v1", requires_api_key=False, diff --git a/tests/test_configure_llm.py b/tests/test_configure_llm.py index ad4ebe8..e401f0d 100644 --- a/tests/test_configure_llm.py +++ b/tests/test_configure_llm.py @@ -15,7 +15,7 @@ def test_configure_llm_keeps_existing_custom_base_url_for_same_provider(monkeypa prompt_answers = iter( [ "router-key", - "anthropic/claude-sonnet-4", + "x-ai/grok-4.3", "https://custom.router/v1", ] ) @@ -49,7 +49,7 @@ def fake_prompt_ask(message: str, default: str | None = None, password: bool = F if message == "Minimax API key": return "mini-key" if message == "Minimax model": - return "minimax-m2.5" + return "MiniMax-M2.7" if message == "Minimax base URL": captured_defaults["base_url"] = default or "" return default or "" diff --git a/tests/test_litellm_profile_resolver.py b/tests/test_litellm_profile_resolver.py index 6d78f56..0c1c241 100644 --- a/tests/test_litellm_profile_resolver.py +++ b/tests/test_litellm_profile_resolver.py @@ -24,11 +24,11 @@ def _base_settings(**overrides) -> Settings: "litellm_rate_limit_base_delay_seconds": 1.0, "litellm_rate_limit_max_delay_seconds": 30.0, "openrouter_api_key": None, - "openrouter_model": "anthropic/claude-sonnet-4", + "openrouter_model": "x-ai/grok-4.3", "openrouter_base_url": "https://openrouter.ai/api/v1", "openrouter_timeout": 30.0, "zai_api_key": None, - "zai_model": "glm-5", + "zai_model": "glm-5.1", "zai_base_url": "https://api.z.ai/api/paas/v4/", "zai_chat_path": "/chat/completions", "zai_timeout_seconds": 45.0, @@ -69,7 +69,7 @@ def test_resolver_falls_back_to_legacy_openrouter_mode() -> None: assert profile.provider_id == "openrouter" assert profile.source == "legacy" - assert profile.model == "openrouter/anthropic/claude-sonnet-4" + assert profile.model == "openrouter/x-ai/grok-4.3" assert profile.api_key == "legacy-openrouter-key" @@ -92,12 +92,12 @@ def test_resolver_supports_local_ollama_without_api_key() -> None: def test_worker_override_does_not_inherit_octo_unified_api_key_for_other_provider() -> None: settings = _base_settings( litellm_provider_id="zai", - litellm_model="glm-5", + litellm_model="glm-5.1", litellm_api_key="octo-zai-key", openrouter_api_key=None, config_obj=OctopalConfig( - llm=LLMConfig(provider_id="zai", model="glm-5", api_key="octo-zai-key"), - worker_llm_default=LLMConfig(provider_id="openrouter", model="anthropic/claude-sonnet-4"), + llm=LLMConfig(provider_id="zai", model="glm-5.1", api_key="octo-zai-key"), + worker_llm_default=LLMConfig(provider_id="openrouter", model="x-ai/grok-4.3"), ), ) diff --git a/tests/test_litellm_provider_payload_hardening.py b/tests/test_litellm_provider_payload_hardening.py index 8568b05..a21d815 100644 --- a/tests/test_litellm_provider_payload_hardening.py +++ b/tests/test_litellm_provider_payload_hardening.py @@ -25,11 +25,11 @@ def _settings() -> Settings: litellm_drop_params=True, litellm_caching=False, openrouter_api_key=None, - openrouter_model="anthropic/claude-sonnet-4", + openrouter_model="x-ai/grok-4.3", openrouter_base_url="https://openrouter.ai/api/v1", openrouter_timeout=30.0, zai_api_key="z-test", - zai_model="glm-5", + zai_model="glm-5.1", zai_base_url="https://api.z.ai/api/paas/v4/", zai_chat_path="/chat/completions", zai_timeout_seconds=45.0, diff --git a/tests/test_openrouter_provider.py b/tests/test_openrouter_provider.py index 67edd42..891356c 100644 --- a/tests/test_openrouter_provider.py +++ b/tests/test_openrouter_provider.py @@ -25,11 +25,11 @@ def _settings(**overrides) -> Settings: "litellm_drop_params": True, "litellm_caching": False, "openrouter_api_key": "router-key", - "openrouter_model": "anthropic/claude-sonnet-4", + "openrouter_model": "x-ai/grok-4.3", "openrouter_base_url": "https://openrouter.ai/api/v1/", "openrouter_timeout": 30.0, "zai_api_key": None, - "zai_model": "glm-5", + "zai_model": "glm-5.1", "zai_base_url": "https://api.z.ai/api/paas/v4/", "zai_chat_path": "/chat/completions", "zai_timeout_seconds": 45.0, @@ -131,7 +131,7 @@ def test_complete_posts_expected_payload(monkeypatch) -> None: assert call["base_url"] == "https://openrouter.ai/api/v1" assert call["path"] == "/chat/completions" assert call["headers"]["Authorization"] == "Bearer router-key" - assert call["json"]["model"] == "anthropic/claude-sonnet-4" + assert call["json"]["model"] == "x-ai/grok-4.3" assert call["json"]["temperature"] == 0.7 assert call["json"]["messages"] == [{"role": "user", "content": "hello"}] diff --git a/tests/test_runtime_mcp_integration.py b/tests/test_runtime_mcp_integration.py index efd17bf..a30f6e3 100644 --- a/tests/test_runtime_mcp_integration.py +++ b/tests/test_runtime_mcp_integration.py @@ -769,8 +769,8 @@ def grant_capabilities(self, capabilities): settings = Settings( config_obj=OctopalConfig( - llm=LLMConfig(provider_id="zai", model="glm-5"), - worker_llm_default=LLMConfig(provider_id="openrouter", model="anthropic/claude-sonnet-4"), + llm=LLMConfig(provider_id="zai", model="glm-5.1"), + worker_llm_default=LLMConfig(provider_id="openrouter", model="x-ai/grok-4.3"), ) ) runtime = WorkerRuntime( @@ -794,7 +794,7 @@ async def _fake_run(spec, approval_requester=None): spec = captured["spec"] assert spec.model is None - assert spec.llm_config.model == "anthropic/claude-sonnet-4" + assert spec.llm_config.model == "x-ai/grok-4.3" def test_runtime_rejects_task_tool_override_that_widens_template(tmp_path: Path) -> None: diff --git a/tests/test_settings_config_sync.py b/tests/test_settings_config_sync.py index b520984..b633e07 100644 --- a/tests/test_settings_config_sync.py +++ b/tests/test_settings_config_sync.py @@ -49,7 +49,7 @@ def test_load_settings_prefers_config_json_telegram_values(tmp_path, monkeypatch }, "llm": { "provider_id": "zai", - "model": "glm-5", + "model": "glm-5.1", }, } ),