From 4c88f4b91cab29759e0cdb33b645d23ccc70a167 Mon Sep 17 00:00:00 2001 From: Jeremy Dawes Date: Thu, 28 May 2026 02:45:48 +0800 Subject: [PATCH] feat(providers): add Alibaba (Qwen via DashScope) declarative provider (#9443) Signed-off-by: Jeremy Dawes --- .../src/providers/declarative/alibaba.json | 60 +++++++++++++++++++ crates/goose/src/providers/init.rs | 27 +++++++++ 2 files changed, 87 insertions(+) create mode 100644 crates/goose/src/providers/declarative/alibaba.json diff --git a/crates/goose/src/providers/declarative/alibaba.json b/crates/goose/src/providers/declarative/alibaba.json new file mode 100644 index 0000000000..d9867aec38 --- /dev/null +++ b/crates/goose/src/providers/declarative/alibaba.json @@ -0,0 +1,60 @@ +{ + "name": "alibaba", + "engine": "openai", + "display_name": "Alibaba (Qwen)", + "description": "Alibaba Qwen models via DashScope's OpenAI-compatible API.", + "api_key_env": "DASHSCOPE_API_KEY", + "base_url": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", + "catalog_provider_id": "alibaba", + "dynamic_models": true, + "models": [ + { + "name": "qwen3.7-max", + "context_limit": 262144 + }, + { + "name": "qwen3.7-max-preview", + "context_limit": 262144 + }, + { + "name": "qwen3.6-max-preview", + "context_limit": 262144 + }, + { + "name": "qwen3.6-plus", + "context_limit": 1000000 + }, + { + "name": "qwen3-max", + "context_limit": 262144 + }, + { + "name": "qwen-plus", + "context_limit": 1000000 + }, + { + "name": "qwen-turbo", + "context_limit": 1000000 + }, + { + "name": "qwen-flash", + "context_limit": 1000000 + }, + { + "name": "qwen3-coder-plus", + "context_limit": 1048576 + }, + { + "name": "qwen3-coder-flash", + "context_limit": 1000000 + } + ], + "preserves_thinking": true, + "supports_streaming": true, + "model_doc_link": "https://www.alibabacloud.com/help/en/model-studio/models", + "setup_steps": [ + "Sign in to https://modelstudio.console.alibabacloud.com (international) or https://bailian.console.aliyun.com (China)", + "Open API Keys in the left sidebar and create a new key", + "Copy the key and paste it above" + ] +} diff --git a/crates/goose/src/providers/init.rs b/crates/goose/src/providers/init.rs index cc4c20b6d2..3340f43847 100644 --- a/crates/goose/src/providers/init.rs +++ b/crates/goose/src/providers/init.rs @@ -314,6 +314,33 @@ mod tests { assert!(api_key.primary, "NEARAI_API_KEY should be primary"); } + #[tokio::test] + async fn test_alibaba_declarative_provider_registry_wiring() { + let alibaba = get_from_registry("alibaba") + .await + .expect("alibaba provider should be registered"); + let meta = alibaba.metadata(); + + assert_eq!(alibaba.provider_type(), ProviderType::Declarative); + assert!(alibaba.supports_inventory_refresh()); + assert_eq!(meta.display_name, "Alibaba (Qwen)"); + assert_eq!(meta.default_model, "qwen3.7-max"); + assert_eq!( + meta.model_doc_link, + "https://www.alibabacloud.com/help/en/model-studio/models" + ); + assert!(!meta.setup_steps.is_empty()); + + let api_key = meta + .config_keys + .iter() + .find(|k| k.name == "DASHSCOPE_API_KEY") + .expect("DASHSCOPE_API_KEY config key should exist"); + assert!(api_key.required, "DASHSCOPE_API_KEY should be required"); + assert!(api_key.secret, "DASHSCOPE_API_KEY should be secret"); + assert!(api_key.primary, "DASHSCOPE_API_KEY should be primary"); + } + #[tokio::test] async fn test_openai_compatible_providers_config_keys() { let providers_list = providers().await;