From ef4fc4c4804f81fa80e14f602b6728784ad89ade Mon Sep 17 00:00:00 2001 From: 9qeklajc <9qeklajc> Date: Tue, 12 May 2026 21:33:01 +0200 Subject: [PATCH 1/6] (feat): add routstr as a declarative provider Signed-off-by: 9qeklajc <9qeklajc> --- .../goose/src/config/declarative_providers.rs | 27 ++++++++++++++++++ .../src/providers/declarative/routstr.json | 28 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 crates/goose/src/providers/declarative/routstr.json diff --git a/crates/goose/src/config/declarative_providers.rs b/crates/goose/src/config/declarative_providers.rs index 35314401bdf9..2d589f872e91 100644 --- a/crates/goose/src/config/declarative_providers.rs +++ b/crates/goose/src/config/declarative_providers.rs @@ -855,4 +855,31 @@ mod tests { let result = expand_env_vars("${TEST_EXPAND_OVERRIDE}/path", &env_vars).unwrap(); assert_eq!(result, "https://from-env.com/path"); } + + #[test] + fn test_routstr_json_deserializes() { + let json = include_str!("../providers/declarative/routstr.json"); + let config: DeclarativeProviderConfig = + serde_json::from_str(json).expect("routstr.json should parse"); + assert_eq!(config.name, "routstr"); + assert_eq!(config.display_name, "Routstr"); + assert!(matches!(config.engine, ProviderEngine::OpenAI)); + assert_eq!(config.api_key_env, "ROUTSTR_API_KEY"); + assert_eq!(config.base_url, "${ROUTSTR_HOST}/v1"); + assert_eq!(config.dynamic_models, Some(true)); + assert_eq!(config.supports_streaming, Some(true)); + assert!(config.skip_canonical_filtering); + assert!(config.models.is_empty()); + + let env_vars = config.env_vars.as_ref().expect("env_vars should be set"); + assert_eq!(env_vars.len(), 1); + assert_eq!(env_vars[0].name, "ROUTSTR_HOST"); + assert!(!env_vars[0].required); + assert!(!env_vars[0].secret); + assert_eq!(env_vars[0].primary, Some(true)); + assert_eq!( + env_vars[0].default, + Some("https://api.routstr.com".to_string()) + ); + } } diff --git a/crates/goose/src/providers/declarative/routstr.json b/crates/goose/src/providers/declarative/routstr.json new file mode 100644 index 000000000000..8c2c0ddf1c42 --- /dev/null +++ b/crates/goose/src/providers/declarative/routstr.json @@ -0,0 +1,28 @@ +{ + "name": "routstr", + "engine": "openai", + "display_name": "Routstr", + "description": "OpenAI-compatible aggregator that fronts dozens of upstream providers (OpenAI, Anthropic, Google, DeepSeek, Llama, …) behind a single API. Authenticate with an sk-... bearer issued by a Routstr instance — payment (e.g. Cashu top-up) is handled outside goose.", + "api_key_env": "ROUTSTR_API_KEY", + "base_url": "${ROUTSTR_HOST}/v1", + "env_vars": [ + { + "name": "ROUTSTR_HOST", + "required": false, + "secret": false, + "primary": true, + "default": "https://api.routstr.com", + "description": "Base URL of the Routstr proxy (default: https://api.routstr.com)" + } + ], + "dynamic_models": true, + "models": [], + "supports_streaming": true, + "skip_canonical_filtering": true, + "model_doc_link": "https://routstr.com/docs", + "setup_steps": [ + "Pick a Routstr instance (e.g. https://api.routstr.com) and obtain an sk-... API key from its payment flow.", + "Paste the key above as ROUTSTR_API_KEY.", + "Optionally override ROUTSTR_HOST to point at a different Routstr proxy." + ] +} From fa8ba3f1f3dd3a3618e850f592a2c612c66769c1 Mon Sep 17 00:00:00 2001 From: 9qeklajc <9qeklajc> Date: Tue, 12 May 2026 22:26:24 +0200 Subject: [PATCH 2/6] (doc): added doc --- .../docs/getting-started/providers.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/documentation/docs/getting-started/providers.md b/documentation/docs/getting-started/providers.md index dfa0632cd52b..d3c91eec0d0d 100644 --- a/documentation/docs/getting-started/providers.md +++ b/documentation/docs/getting-started/providers.md @@ -44,6 +44,7 @@ goose is compatible with a wide range of LLM providers, allowing you to choose a | [OpenRouter](https://openrouter.ai/) | API gateway for unified access to various models with features like rate-limiting management. | `OPENROUTER_API_KEY` | | [OVHcloud AI](https://www.ovhcloud.com/en/public-cloud/ai-endpoints/) | Provides access to open-source models including Qwen, Llama, Mistral, and DeepSeek through AI Endpoints service. | `OVHCLOUD_API_KEY` | | [Ramalama](https://ramalama.ai/) | Local model using native [OCI](https://opencontainers.org/) container runtimes, [CNCF](https://www.cncf.io/) tools, and supporting models as OCI artifacts. Ramalama API is a compatible alternative to Ollama and can be used with the goose Ollama provider. Supports Qwen, Llama, DeepSeek, and other open-source models. **Because this provider runs locally, you must first [download and run a model](#local-llms).** | `OLLAMA_HOST` | +| [Routstr](https://routstr.com/) | OpenAI-compatible aggregator that fronts dozens of upstream providers (Anthropic, OpenAI, Google, DeepSeek, Llama, …) behind a single API. Authenticate with an `sk-...` bearer issued by your Routstr instance — payment is handled outside goose. | `ROUTSTR_API_KEY`, `ROUTSTR_HOST` (optional, default `https://api.routstr.com`) | | [Snowflake](https://docs.snowflake.com/user-guide/snowflake-cortex/aisql#choosing-a-model) | Access the latest models using Snowflake Cortex services, including Claude models. **Requires a Snowflake account and programmatic access token (PAT)**. | `SNOWFLAKE_HOST`, `SNOWFLAKE_TOKEN` | | [VMware Tanzu Platform](https://techdocs.broadcom.com/us/en/vmware-tanzu/platform/ai-services/10-3/ai/index.html) | Enterprise-managed LLM access through AI Services on VMware Tanzu Platform. Models are fetched dynamically from the endpoint. | `TANZU_AI_API_KEY`, `TANZU_AI_ENDPOINT` | | [Tetrate Agent Router Service](https://router.tetrate.ai) | Unified API gateway for AI models including Claude, Gemini, GPT, open-weight models, and others. Supports PKCE authentication flow for secure API key generation. | `TETRATE_API_KEY`, `TETRATE_HOST` (optional) | @@ -733,6 +734,43 @@ To set up Novita AI with goose, follow these steps: +### Routstr +[Routstr](https://routstr.com/) is an OpenAI-compatible aggregator that fronts dozens of upstream providers behind a single API. Payment is handled by the Routstr instance itself, so all goose needs is the `sk-...` bearer that instance issues you. To use Routstr with goose, pick an instance (the default is `https://api.routstr.com`) and obtain an API key from its payment flow. + +Routstr aggregates models from many upstream providers, including: +- **anthropic/claude-opus-4.7** — Anthropic's Claude opus 4.7 +- **deepseek/deepseek-v4-pro** — DeepSeek V4 Pro +- **google/gemini-3.1-pro-preview** — google/gemini-3.1-pro-preview + +`/v1/models` is queried at configure time, so the full catalogue your Routstr instance exposes is available in the model picker. For the static defaults shipped with goose, see [routstr.json](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/providers/declarative/routstr.json). + +To set up Routstr with goose, follow these steps: + + + + **To update your LLM provider and API key:** + + 1. Click the button in the top-left to open the sidebar. + 2. Click the `Settings` button on the sidebar. + 3. Click the `Models` tab. + 4. Click `Configure Providers` + 5. Choose `Routstr` as provider from the list. + 6. Click `Configure`, enter your `ROUTSTR_API_KEY` (and optionally override `ROUTSTR_HOST` to point at a different Routstr instance), and click `Submit`. + 7. Select the Routstr model of your choice. + + + + 1. Run: + ```sh + goose configure + ``` + 2. Select `Configure Providers` from the menu. + 3. Follow the prompts to choose `Routstr` as the provider. + 4. Enter your API key when prompted (and optionally override `ROUTSTR_HOST`). + 5. Select the Routstr model of your choice. + + + ### Google Gemini Google Gemini provides a free tier. To start using the Gemini API with goose, you need an API Key from [Google AI studio](https://aistudio.google.com/app/apikey). From b431c3c783f5b29b80b6f25def9e4b4089980348 Mon Sep 17 00:00:00 2001 From: 9qeklajc <9qeklajc> Date: Tue, 12 May 2026 22:29:21 +0200 Subject: [PATCH 3/6] (feat): added default models --- crates/goose/src/providers/declarative/routstr.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/goose/src/providers/declarative/routstr.json b/crates/goose/src/providers/declarative/routstr.json index 8c2c0ddf1c42..41f85fe88dea 100644 --- a/crates/goose/src/providers/declarative/routstr.json +++ b/crates/goose/src/providers/declarative/routstr.json @@ -16,7 +16,14 @@ } ], "dynamic_models": true, - "models": [], + "models": [ + "claude-opus-4.7", + "gemini-3.1-pro-preview", + "gemini-3-flash-preview", + "deepseek-v4-pro", + "glm-5.1", + "minimax-m2.7" + ], "supports_streaming": true, "skip_canonical_filtering": true, "model_doc_link": "https://routstr.com/docs", From aa9c49c98ae4f052eb5a18cac47950767b1966b8 Mon Sep 17 00:00:00 2001 From: 9qeklajc <9qeklajc> Date: Tue, 12 May 2026 22:32:15 +0200 Subject: [PATCH 4/6] update test --- crates/goose/src/config/declarative_providers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/goose/src/config/declarative_providers.rs b/crates/goose/src/config/declarative_providers.rs index 2d589f872e91..e548d3f6a94e 100644 --- a/crates/goose/src/config/declarative_providers.rs +++ b/crates/goose/src/config/declarative_providers.rs @@ -869,7 +869,7 @@ mod tests { assert_eq!(config.dynamic_models, Some(true)); assert_eq!(config.supports_streaming, Some(true)); assert!(config.skip_canonical_filtering); - assert!(config.models.is_empty()); + assert_eq!(config.models.len(), 6); let env_vars = config.env_vars.as_ref().expect("env_vars should be set"); assert_eq!(env_vars.len(), 1); From 3279d0a6895922388599a6b8e0da3af0349b5b6a Mon Sep 17 00:00:00 2001 From: 9qeklajc <9qeklajc> Date: Tue, 12 May 2026 23:17:18 +0200 Subject: [PATCH 5/6] (fix) correct model structure --- crates/goose/src/providers/declarative/routstr.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/goose/src/providers/declarative/routstr.json b/crates/goose/src/providers/declarative/routstr.json index 41f85fe88dea..59022d438224 100644 --- a/crates/goose/src/providers/declarative/routstr.json +++ b/crates/goose/src/providers/declarative/routstr.json @@ -17,12 +17,12 @@ ], "dynamic_models": true, "models": [ - "claude-opus-4.7", - "gemini-3.1-pro-preview", - "gemini-3-flash-preview", - "deepseek-v4-pro", - "glm-5.1", - "minimax-m2.7" + { "name": "claude-opus-4.7", "context_limit": 1000000 }, + { "name": "gemini-3.1-pro-preview", "context_limit": 1048576 }, + { "name": "gemini-3-flash-preview", "context_limit": 1048576 }, + { "name": "deepseek-v4-pro", "context_limit": 1048576 }, + { "name": "glm-5.1", "context_limit": 202752 }, + { "name": "minimax-m2.7", "context_limit": 196608 } ], "supports_streaming": true, "skip_canonical_filtering": true, From df1b988f411afeaaca19fcf0d157588c1adcc26f Mon Sep 17 00:00:00 2001 From: 9qeklajc <9qeklajc> Date: Tue, 12 May 2026 23:22:00 +0200 Subject: [PATCH 6/6] update doc for consitency --- documentation/docs/getting-started/providers.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/docs/getting-started/providers.md b/documentation/docs/getting-started/providers.md index d3c91eec0d0d..ea4b1cfef050 100644 --- a/documentation/docs/getting-started/providers.md +++ b/documentation/docs/getting-started/providers.md @@ -738,9 +738,9 @@ To set up Novita AI with goose, follow these steps: [Routstr](https://routstr.com/) is an OpenAI-compatible aggregator that fronts dozens of upstream providers behind a single API. Payment is handled by the Routstr instance itself, so all goose needs is the `sk-...` bearer that instance issues you. To use Routstr with goose, pick an instance (the default is `https://api.routstr.com`) and obtain an API key from its payment flow. Routstr aggregates models from many upstream providers, including: -- **anthropic/claude-opus-4.7** — Anthropic's Claude opus 4.7 -- **deepseek/deepseek-v4-pro** — DeepSeek V4 Pro -- **google/gemini-3.1-pro-preview** — google/gemini-3.1-pro-preview +- **claude-opus-4.7** — Anthropic's Claude opus 4.7 +- **deepseek-v4-pro** — DeepSeek V4 Pro +- **gemini-3.1-pro-preview** — gemini-3.1 Pro Preview `/v1/models` is queried at configure time, so the full catalogue your Routstr instance exposes is available in the model picker. For the static defaults shipped with goose, see [routstr.json](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/providers/declarative/routstr.json).