feat(providers): add StepFun provider with onboarding and docs parity
This commit is contained in:
parent
37b19365c8
commit
2630486ca8
16
AGENTS.md
16
AGENTS.md
@ -3,6 +3,22 @@
|
||||
This file defines the default working protocol for coding agents in this repository.
|
||||
Scope: entire repository.
|
||||
|
||||
## 0) Session Default Target (Mandatory)
|
||||
|
||||
- When operator intent does not explicitly specify another repository/path, treat the active coding target as this repository (`/home/ubuntu/zeroclaw`).
|
||||
- Do not switch to or implement in other repositories unless the operator explicitly requests that scope in the current conversation.
|
||||
- Ambiguous wording (for example "这个仓库", "当前项目", "the repo") is resolved to `/home/ubuntu/zeroclaw` by default.
|
||||
- Context mentioning external repositories does not authorize cross-repo edits; explicit current-turn override is required.
|
||||
- Before any repo-affecting action, verify target lock (`pwd` + git root) to prevent accidental execution in sibling repositories.
|
||||
|
||||
## 0.1) Clean Worktree First Gate (Mandatory)
|
||||
|
||||
- Before handling any repository content (analysis, debugging, coding, tests, docs, CI), create a **new clean dedicated git worktree** for the active task.
|
||||
- Do not perform substantive task work in a dirty workspace.
|
||||
- Do not reuse a previously dirty worktree for a new task track.
|
||||
- If the current location is dirty, stop and bootstrap a clean worktree/branch first.
|
||||
- If worktree bootstrap fails, stop and report the blocker; do not continue in-place.
|
||||
|
||||
## 1) Project Snapshot (Read First)
|
||||
|
||||
ZeroClaw is a Rust-first autonomous agent runtime optimized for:
|
||||
|
||||
@ -20,3 +20,21 @@ Source anglaise:
|
||||
## Notes de mise à jour
|
||||
|
||||
- Ajout d'un réglage `provider.reasoning_level` pour le niveau de raisonnement OpenAI Codex. Voir la source anglaise pour les détails.
|
||||
- 2026-03-01: ajout de la prise en charge du provider StepFun (`stepfun`, alias `step`, `step-ai`, `step_ai`).
|
||||
|
||||
## StepFun (Résumé)
|
||||
|
||||
- Provider ID: `stepfun`
|
||||
- Aliases: `step`, `step-ai`, `step_ai`
|
||||
- Base API URL: `https://api.stepfun.com/v1`
|
||||
- Endpoints: `POST /v1/chat/completions`, `GET /v1/models`
|
||||
- Auth env var: `STEP_API_KEY` (fallback: `STEPFUN_API_KEY`)
|
||||
- Modèle par défaut: `step-3.5-flash`
|
||||
|
||||
Validation rapide:
|
||||
|
||||
```bash
|
||||
export STEP_API_KEY="your-stepfun-api-key"
|
||||
zeroclaw models refresh --provider stepfun
|
||||
zeroclaw agent --provider stepfun --model step-3.5-flash -m "ping"
|
||||
```
|
||||
|
||||
@ -16,3 +16,24 @@
|
||||
|
||||
- Provider ID と環境変数名は英語のまま保持します。
|
||||
- 正式な仕様は英語版原文を優先します。
|
||||
|
||||
## 更新ノート
|
||||
|
||||
- 2026-03-01: StepFun provider 対応を追加(`stepfun`、alias: `step` / `step-ai` / `step_ai`)。
|
||||
|
||||
## StepFun クイックガイド
|
||||
|
||||
- Provider ID: `stepfun`
|
||||
- Aliases: `step`, `step-ai`, `step_ai`
|
||||
- Base API URL: `https://api.stepfun.com/v1`
|
||||
- Endpoints: `POST /v1/chat/completions`, `GET /v1/models`
|
||||
- 認証 env var: `STEP_API_KEY`(fallback: `STEPFUN_API_KEY`)
|
||||
- 既定モデル: `step-3.5-flash`
|
||||
|
||||
クイック検証:
|
||||
|
||||
```bash
|
||||
export STEP_API_KEY="your-stepfun-api-key"
|
||||
zeroclaw models refresh --provider stepfun
|
||||
zeroclaw agent --provider stepfun --model step-3.5-flash -m "ping"
|
||||
```
|
||||
|
||||
@ -16,3 +16,24 @@
|
||||
|
||||
- Provider ID и имена env переменных не переводятся.
|
||||
- Нормативное описание поведения — в английском оригинале.
|
||||
|
||||
## Обновления
|
||||
|
||||
- 2026-03-01: добавлена поддержка провайдера StepFun (`stepfun`, алиасы `step`, `step-ai`, `step_ai`).
|
||||
|
||||
## StepFun (Кратко)
|
||||
|
||||
- Provider ID: `stepfun`
|
||||
- Алиасы: `step`, `step-ai`, `step_ai`
|
||||
- Base API URL: `https://api.stepfun.com/v1`
|
||||
- Эндпоинты: `POST /v1/chat/completions`, `GET /v1/models`
|
||||
- Переменная авторизации: `STEP_API_KEY` (fallback: `STEPFUN_API_KEY`)
|
||||
- Модель по умолчанию: `step-3.5-flash`
|
||||
|
||||
Быстрая проверка:
|
||||
|
||||
```bash
|
||||
export STEP_API_KEY="your-stepfun-api-key"
|
||||
zeroclaw models refresh --provider stepfun
|
||||
zeroclaw agent --provider stepfun --model step-3.5-flash -m "ping"
|
||||
```
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
Tài liệu này liệt kê các provider ID, alias và biến môi trường chứa thông tin xác thực.
|
||||
|
||||
Cập nhật lần cuối: **2026-02-28**.
|
||||
Cập nhật lần cuối: **2026-03-01**.
|
||||
|
||||
## Cách liệt kê các Provider
|
||||
|
||||
@ -33,6 +33,7 @@ Với chuỗi provider dự phòng (`reliability.fallback_providers`), mỗi pro
|
||||
| `vercel` | `vercel-ai` | Không | `VERCEL_API_KEY` |
|
||||
| `cloudflare` | `cloudflare-ai` | Không | `CLOUDFLARE_API_KEY` |
|
||||
| `moonshot` | `kimi` | Không | `MOONSHOT_API_KEY` |
|
||||
| `stepfun` | `step`, `step-ai`, `step_ai` | Không | `STEP_API_KEY`, `STEPFUN_API_KEY` |
|
||||
| `kimi-code` | `kimi_coding`, `kimi_for_coding` | Không | `KIMI_CODE_API_KEY`, `MOONSHOT_API_KEY` |
|
||||
| `synthetic` | — | Không | `SYNTHETIC_API_KEY` |
|
||||
| `opencode` | `opencode-zen` | Không | `OPENCODE_API_KEY` |
|
||||
@ -87,6 +88,29 @@ zeroclaw models refresh --provider volcengine
|
||||
zeroclaw agent --provider volcengine --model doubao-1-5-pro-32k-250115 -m "ping"
|
||||
```
|
||||
|
||||
### Ghi chú về StepFun
|
||||
|
||||
- Provider ID: `stepfun` (alias: `step`, `step-ai`, `step_ai`)
|
||||
- Base API URL: `https://api.stepfun.com/v1`
|
||||
- Chat endpoint: `/chat/completions`
|
||||
- Model discovery endpoint: `/models`
|
||||
- Xác thực: `STEP_API_KEY` (fallback: `STEPFUN_API_KEY`)
|
||||
- Model mặc định: `step-3.5-flash`
|
||||
|
||||
Ví dụ thiết lập nhanh:
|
||||
|
||||
```bash
|
||||
export STEP_API_KEY="your-stepfun-api-key"
|
||||
zeroclaw onboard --provider stepfun --api-key "$STEP_API_KEY" --model step-3.5-flash --force
|
||||
```
|
||||
|
||||
Kiểm tra nhanh:
|
||||
|
||||
```bash
|
||||
zeroclaw models refresh --provider stepfun
|
||||
zeroclaw agent --provider stepfun --model step-3.5-flash -m "ping"
|
||||
```
|
||||
|
||||
### Ghi chú về SiliconFlow
|
||||
|
||||
- Provider ID: `siliconflow` (alias: `silicon-cloud`, `siliconcloud`)
|
||||
|
||||
@ -16,3 +16,25 @@
|
||||
|
||||
- Provider ID 与环境变量名称保持英文。
|
||||
- 规范与行为说明以英文原文为准。
|
||||
|
||||
## 更新记录
|
||||
|
||||
- 2026-03-01:新增 StepFun provider 对齐信息(`stepfun` / `step` / `step-ai` / `step_ai`)。
|
||||
|
||||
## StepFun 快速说明
|
||||
|
||||
- Provider ID:`stepfun`
|
||||
- 别名:`step`、`step-ai`、`step_ai`
|
||||
- Base API URL:`https://api.stepfun.com/v1`
|
||||
- 模型列表端点:`GET /v1/models`
|
||||
- 对话端点:`POST /v1/chat/completions`
|
||||
- 鉴权变量:`STEP_API_KEY`(回退:`STEPFUN_API_KEY`)
|
||||
- 默认模型:`step-3.5-flash`
|
||||
|
||||
快速验证:
|
||||
|
||||
```bash
|
||||
export STEP_API_KEY="your-stepfun-api-key"
|
||||
zeroclaw models refresh --provider stepfun
|
||||
zeroclaw agent --provider stepfun --model step-3.5-flash -m "ping"
|
||||
```
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
This document maps provider IDs, aliases, and credential environment variables.
|
||||
|
||||
Last verified: **February 28, 2026**.
|
||||
Last verified: **March 1, 2026**.
|
||||
|
||||
## How to List Providers
|
||||
|
||||
@ -35,6 +35,7 @@ credential is not reused for fallback providers.
|
||||
| `vercel` | `vercel-ai` | No | `VERCEL_API_KEY` |
|
||||
| `cloudflare` | `cloudflare-ai` | No | `CLOUDFLARE_API_KEY` |
|
||||
| `moonshot` | `kimi` | No | `MOONSHOT_API_KEY` |
|
||||
| `stepfun` | `step`, `step-ai`, `step_ai` | No | `STEP_API_KEY`, `STEPFUN_API_KEY` |
|
||||
| `kimi-code` | `kimi_coding`, `kimi_for_coding` | No | `KIMI_CODE_API_KEY`, `MOONSHOT_API_KEY` |
|
||||
| `synthetic` | — | No | `SYNTHETIC_API_KEY` |
|
||||
| `opencode` | `opencode-zen` | No | `OPENCODE_API_KEY` |
|
||||
@ -137,6 +138,33 @@ zeroclaw models refresh --provider volcengine
|
||||
zeroclaw agent --provider volcengine --model doubao-1-5-pro-32k-250115 -m "ping"
|
||||
```
|
||||
|
||||
### StepFun Notes
|
||||
|
||||
- Provider ID: `stepfun` (aliases: `step`, `step-ai`, `step_ai`)
|
||||
- Base API URL: `https://api.stepfun.com/v1`
|
||||
- Chat endpoint: `/chat/completions`
|
||||
- Model discovery endpoint: `/models`
|
||||
- Authentication: `STEP_API_KEY` (fallback: `STEPFUN_API_KEY`)
|
||||
- Default model preset: `step-3.5-flash`
|
||||
- Official docs:
|
||||
- Chat Completions: <https://platform.stepfun.com/docs/zh/api-reference/chat/chat-completion-create>
|
||||
- Models List: <https://platform.stepfun.com/docs/api-reference/models/list>
|
||||
- OpenAI migration guide: <https://platform.stepfun.com/docs/guide/openai>
|
||||
|
||||
Minimal setup example:
|
||||
|
||||
```bash
|
||||
export STEP_API_KEY="your-stepfun-api-key"
|
||||
zeroclaw onboard --provider stepfun --api-key "$STEP_API_KEY" --model step-3.5-flash --force
|
||||
```
|
||||
|
||||
Quick validation:
|
||||
|
||||
```bash
|
||||
zeroclaw models refresh --provider stepfun
|
||||
zeroclaw agent --provider stepfun --model step-3.5-flash -m "ping"
|
||||
```
|
||||
|
||||
### SiliconFlow Notes
|
||||
|
||||
- Provider ID: `siliconflow` (aliases: `silicon-cloud`, `siliconcloud`)
|
||||
|
||||
@ -77,6 +77,7 @@ pub fn default_model_fallback_for_provider(provider_name: Option<&str>) -> &'sta
|
||||
"together-ai" => "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
||||
"cohere" => "command-a-03-2025",
|
||||
"moonshot" => "kimi-k2.5",
|
||||
"stepfun" => "step-3.5-flash",
|
||||
"hunyuan" => "hunyuan-t1-latest",
|
||||
"glm" | "zai" => "glm-5",
|
||||
"minimax" => "MiniMax-M2.5",
|
||||
@ -11817,6 +11818,9 @@ provider_api = "not-a-real-mode"
|
||||
let openai = resolve_default_model_id(None, Some("openai"));
|
||||
assert_eq!(openai, "gpt-5.2");
|
||||
|
||||
let stepfun = resolve_default_model_id(None, Some("stepfun"));
|
||||
assert_eq!(stepfun, "step-3.5-flash");
|
||||
|
||||
let bedrock = resolve_default_model_id(None, Some("aws-bedrock"));
|
||||
assert_eq!(bedrock, "anthropic.claude-sonnet-4-5-20250929-v1:0");
|
||||
}
|
||||
@ -11828,6 +11832,12 @@ provider_api = "not-a-real-mode"
|
||||
|
||||
let google_alias = resolve_default_model_id(None, Some("google-gemini"));
|
||||
assert_eq!(google_alias, "gemini-2.5-pro");
|
||||
|
||||
let step_alias = resolve_default_model_id(None, Some("step"));
|
||||
assert_eq!(step_alias, "step-3.5-flash");
|
||||
|
||||
let step_ai_alias = resolve_default_model_id(None, Some("step-ai"));
|
||||
assert_eq!(step_ai_alias, "step-3.5-flash");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use super::{IntegrationCategory, IntegrationEntry, IntegrationStatus};
|
||||
use crate::providers::{
|
||||
is_doubao_alias, is_glm_alias, is_minimax_alias, is_moonshot_alias, is_qianfan_alias,
|
||||
is_qwen_alias, is_siliconflow_alias, is_zai_alias,
|
||||
is_qwen_alias, is_siliconflow_alias, is_stepfun_alias, is_zai_alias,
|
||||
};
|
||||
|
||||
/// Returns the full catalog of integrations
|
||||
@ -352,6 +352,18 @@ pub fn all_integrations() -> Vec<IntegrationEntry> {
|
||||
}
|
||||
},
|
||||
},
|
||||
IntegrationEntry {
|
||||
name: "StepFun",
|
||||
description: "Step 3, Step 3.5 Flash, and vision models",
|
||||
category: IntegrationCategory::AiModel,
|
||||
status_fn: |c| {
|
||||
if c.default_provider.as_deref().is_some_and(is_stepfun_alias) {
|
||||
IntegrationStatus::Active
|
||||
} else {
|
||||
IntegrationStatus::Available
|
||||
}
|
||||
},
|
||||
},
|
||||
IntegrationEntry {
|
||||
name: "Synthetic",
|
||||
description: "Synthetic-1 and synthetic family models",
|
||||
@ -1020,6 +1032,13 @@ mod tests {
|
||||
IntegrationStatus::Active
|
||||
));
|
||||
|
||||
config.default_provider = Some("step-ai".to_string());
|
||||
let stepfun = entries.iter().find(|e| e.name == "StepFun").unwrap();
|
||||
assert!(matches!(
|
||||
(stepfun.status_fn)(&config),
|
||||
IntegrationStatus::Active
|
||||
));
|
||||
|
||||
config.default_provider = Some("qwen-intl".to_string());
|
||||
let qwen = entries.iter().find(|e| e.name == "Qwen").unwrap();
|
||||
assert!(matches!(
|
||||
|
||||
@ -25,7 +25,7 @@ use crate::migration::{
|
||||
use crate::providers::{
|
||||
canonical_china_provider_name, is_doubao_alias, is_glm_alias, is_glm_cn_alias,
|
||||
is_minimax_alias, is_moonshot_alias, is_qianfan_alias, is_qwen_alias, is_qwen_oauth_alias,
|
||||
is_siliconflow_alias, is_zai_alias, is_zai_cn_alias,
|
||||
is_siliconflow_alias, is_stepfun_alias, is_zai_alias, is_zai_cn_alias,
|
||||
};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use console::style;
|
||||
@ -966,6 +966,7 @@ fn default_model_for_provider(provider: &str) -> String {
|
||||
"together-ai" => "meta-llama/Llama-3.3-70B-Instruct-Turbo".into(),
|
||||
"cohere" => "command-a-03-2025".into(),
|
||||
"moonshot" => "kimi-k2.5".into(),
|
||||
"stepfun" => "step-3.5-flash".into(),
|
||||
"hunyuan" => "hunyuan-t1-latest".into(),
|
||||
"glm" | "zai" => "glm-5".into(),
|
||||
"minimax" => "MiniMax-M2.5".into(),
|
||||
@ -1246,6 +1247,24 @@ fn curated_models_for_provider(provider_name: &str) -> Vec<(String, String)> {
|
||||
"Kimi K2 0905 Preview (strong coding)".to_string(),
|
||||
),
|
||||
],
|
||||
"stepfun" => vec![
|
||||
(
|
||||
"step-3.5-flash".to_string(),
|
||||
"Step 3.5 Flash (recommended default)".to_string(),
|
||||
),
|
||||
(
|
||||
"step-3".to_string(),
|
||||
"Step 3 (flagship reasoning)".to_string(),
|
||||
),
|
||||
(
|
||||
"step-2-mini".to_string(),
|
||||
"Step 2 Mini (balanced and fast)".to_string(),
|
||||
),
|
||||
(
|
||||
"step-1o-turbo-vision".to_string(),
|
||||
"Step 1o Turbo Vision (multimodal)".to_string(),
|
||||
),
|
||||
],
|
||||
"glm" | "zai" => vec![
|
||||
("glm-5".to_string(), "GLM-5 (high reasoning)".to_string()),
|
||||
(
|
||||
@ -1483,6 +1502,7 @@ fn supports_live_model_fetch(provider_name: &str) -> bool {
|
||||
| "novita"
|
||||
| "cohere"
|
||||
| "moonshot"
|
||||
| "stepfun"
|
||||
| "glm"
|
||||
| "zai"
|
||||
| "qwen"
|
||||
@ -1515,6 +1535,7 @@ fn models_endpoint_for_provider(provider_name: &str) -> Option<&'static str> {
|
||||
"novita" => Some("https://api.novita.ai/openai/v1/models"),
|
||||
"cohere" => Some("https://api.cohere.com/compatibility/v1/models"),
|
||||
"moonshot" => Some("https://api.moonshot.ai/v1/models"),
|
||||
"stepfun" => Some("https://api.stepfun.com/v1/models"),
|
||||
"glm" => Some("https://api.z.ai/api/paas/v4/models"),
|
||||
"zai" => Some("https://api.z.ai/api/coding/paas/v4/models"),
|
||||
"qwen" => Some("https://dashscope.aliyuncs.com/compatible-mode/v1/models"),
|
||||
@ -2515,6 +2536,7 @@ async fn setup_provider(workspace_dir: &Path) -> Result<(String, String, String,
|
||||
"moonshot-intl",
|
||||
"Moonshot — Kimi API (international endpoint)",
|
||||
),
|
||||
("stepfun", "StepFun — Step AI OpenAI-compatible endpoint"),
|
||||
("glm", "GLM — ChatGLM / Zhipu (international endpoint)"),
|
||||
("glm-cn", "GLM — ChatGLM / Zhipu (China endpoint)"),
|
||||
(
|
||||
@ -2934,6 +2956,8 @@ async fn setup_provider(workspace_dir: &Path) -> Result<(String, String, String,
|
||||
"https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey"
|
||||
} else if is_siliconflow_alias(provider_name) {
|
||||
"https://cloud.siliconflow.cn/account/ak"
|
||||
} else if is_stepfun_alias(provider_name) {
|
||||
"https://platform.stepfun.com/interface-key"
|
||||
} else {
|
||||
match provider_name {
|
||||
"openrouter" => "https://openrouter.ai/keys",
|
||||
@ -3239,6 +3263,7 @@ fn provider_env_var(name: &str) -> &'static str {
|
||||
"cohere" => "COHERE_API_KEY",
|
||||
"kimi-code" => "KIMI_CODE_API_KEY",
|
||||
"moonshot" => "MOONSHOT_API_KEY",
|
||||
"stepfun" => "STEP_API_KEY",
|
||||
"glm" => "GLM_API_KEY",
|
||||
"minimax" => "MINIMAX_API_KEY",
|
||||
"qwen" => "DASHSCOPE_API_KEY",
|
||||
@ -7817,6 +7842,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(default_model_for_provider("venice"), "zai-org-glm-5");
|
||||
assert_eq!(default_model_for_provider("moonshot"), "kimi-k2.5");
|
||||
assert_eq!(default_model_for_provider("stepfun"), "step-3.5-flash");
|
||||
assert_eq!(default_model_for_provider("hunyuan"), "hunyuan-t1-latest");
|
||||
assert_eq!(default_model_for_provider("tencent"), "hunyuan-t1-latest");
|
||||
assert_eq!(
|
||||
@ -7858,6 +7884,9 @@ mod tests {
|
||||
assert_eq!(canonical_provider_name("openai_codex"), "openai-codex");
|
||||
assert_eq!(canonical_provider_name("moonshot-intl"), "moonshot");
|
||||
assert_eq!(canonical_provider_name("kimi-cn"), "moonshot");
|
||||
assert_eq!(canonical_provider_name("step"), "stepfun");
|
||||
assert_eq!(canonical_provider_name("step-ai"), "stepfun");
|
||||
assert_eq!(canonical_provider_name("step_ai"), "stepfun");
|
||||
assert_eq!(canonical_provider_name("kimi_coding"), "kimi-code");
|
||||
assert_eq!(canonical_provider_name("kimi_for_coding"), "kimi-code");
|
||||
assert_eq!(canonical_provider_name("glm-cn"), "glm");
|
||||
@ -7959,6 +7988,19 @@ mod tests {
|
||||
assert!(!ids.contains(&"kimi-thinking-preview".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn curated_models_for_stepfun_include_expected_defaults() {
|
||||
let ids: Vec<String> = curated_models_for_provider("stepfun")
|
||||
.into_iter()
|
||||
.map(|(id, _)| id)
|
||||
.collect();
|
||||
|
||||
assert!(ids.contains(&"step-3.5-flash".to_string()));
|
||||
assert!(ids.contains(&"step-3".to_string()));
|
||||
assert!(ids.contains(&"step-2-mini".to_string()));
|
||||
assert!(ids.contains(&"step-1o-turbo-vision".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allows_unauthenticated_model_fetch_for_public_catalogs() {
|
||||
assert!(allows_unauthenticated_model_fetch("openrouter"));
|
||||
@ -8046,6 +8088,9 @@ mod tests {
|
||||
assert!(supports_live_model_fetch("vllm"));
|
||||
assert!(supports_live_model_fetch("astrai"));
|
||||
assert!(supports_live_model_fetch("venice"));
|
||||
assert!(supports_live_model_fetch("stepfun"));
|
||||
assert!(supports_live_model_fetch("step"));
|
||||
assert!(supports_live_model_fetch("step-ai"));
|
||||
assert!(supports_live_model_fetch("glm-cn"));
|
||||
assert!(supports_live_model_fetch("qwen-intl"));
|
||||
assert!(supports_live_model_fetch("qwen-coding-plan"));
|
||||
@ -8120,6 +8165,14 @@ mod tests {
|
||||
curated_models_for_provider("volcengine"),
|
||||
curated_models_for_provider("ark")
|
||||
);
|
||||
assert_eq!(
|
||||
curated_models_for_provider("stepfun"),
|
||||
curated_models_for_provider("step")
|
||||
);
|
||||
assert_eq!(
|
||||
curated_models_for_provider("stepfun"),
|
||||
curated_models_for_provider("step-ai")
|
||||
);
|
||||
assert_eq!(
|
||||
curated_models_for_provider("siliconflow"),
|
||||
curated_models_for_provider("silicon-cloud")
|
||||
@ -8192,6 +8245,18 @@ mod tests {
|
||||
models_endpoint_for_provider("moonshot"),
|
||||
Some("https://api.moonshot.ai/v1/models")
|
||||
);
|
||||
assert_eq!(
|
||||
models_endpoint_for_provider("stepfun"),
|
||||
Some("https://api.stepfun.com/v1/models")
|
||||
);
|
||||
assert_eq!(
|
||||
models_endpoint_for_provider("step"),
|
||||
Some("https://api.stepfun.com/v1/models")
|
||||
);
|
||||
assert_eq!(
|
||||
models_endpoint_for_provider("step-ai"),
|
||||
Some("https://api.stepfun.com/v1/models")
|
||||
);
|
||||
assert_eq!(
|
||||
models_endpoint_for_provider("siliconflow"),
|
||||
Some("https://api.siliconflow.cn/v1/models")
|
||||
@ -8497,6 +8562,9 @@ mod tests {
|
||||
assert_eq!(provider_env_var("minimax-oauth"), "MINIMAX_API_KEY");
|
||||
assert_eq!(provider_env_var("minimax-oauth-cn"), "MINIMAX_API_KEY");
|
||||
assert_eq!(provider_env_var("moonshot-intl"), "MOONSHOT_API_KEY");
|
||||
assert_eq!(provider_env_var("stepfun"), "STEP_API_KEY");
|
||||
assert_eq!(provider_env_var("step"), "STEP_API_KEY");
|
||||
assert_eq!(provider_env_var("step-ai"), "STEP_API_KEY");
|
||||
assert_eq!(provider_env_var("zai-cn"), "ZAI_API_KEY");
|
||||
assert_eq!(provider_env_var("doubao"), "ARK_API_KEY");
|
||||
assert_eq!(provider_env_var("volcengine"), "ARK_API_KEY");
|
||||
|
||||
@ -83,6 +83,7 @@ const QWEN_OAUTH_CREDENTIAL_FILE: &str = ".qwen/oauth_creds.json";
|
||||
const ZAI_GLOBAL_BASE_URL: &str = "https://api.z.ai/api/coding/paas/v4";
|
||||
const ZAI_CN_BASE_URL: &str = "https://open.bigmodel.cn/api/coding/paas/v4";
|
||||
const SILICONFLOW_BASE_URL: &str = "https://api.siliconflow.cn/v1";
|
||||
const STEPFUN_BASE_URL: &str = "https://api.stepfun.com/v1";
|
||||
const VERCEL_AI_GATEWAY_BASE_URL: &str = "https://ai-gateway.vercel.sh/v1";
|
||||
|
||||
pub(crate) fn is_minimax_intl_alias(name: &str) -> bool {
|
||||
@ -192,6 +193,10 @@ pub(crate) fn is_siliconflow_alias(name: &str) -> bool {
|
||||
matches!(name, "siliconflow" | "silicon-cloud" | "siliconcloud")
|
||||
}
|
||||
|
||||
pub(crate) fn is_stepfun_alias(name: &str) -> bool {
|
||||
matches!(name, "stepfun" | "step" | "step-ai" | "step_ai")
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum MinimaxOauthRegion {
|
||||
Global,
|
||||
@ -633,6 +638,8 @@ pub(crate) fn canonical_china_provider_name(name: &str) -> Option<&'static str>
|
||||
Some("doubao")
|
||||
} else if is_siliconflow_alias(name) {
|
||||
Some("siliconflow")
|
||||
} else if is_stepfun_alias(name) {
|
||||
Some("stepfun")
|
||||
} else if matches!(name, "hunyuan" | "tencent") {
|
||||
Some("hunyuan")
|
||||
} else {
|
||||
@ -694,6 +701,14 @@ fn zai_base_url(name: &str) -> Option<&'static str> {
|
||||
}
|
||||
}
|
||||
|
||||
fn stepfun_base_url(name: &str) -> Option<&'static str> {
|
||||
if is_stepfun_alias(name) {
|
||||
Some(STEPFUN_BASE_URL)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProviderRuntimeOptions {
|
||||
pub auth_profile_override: Option<String>,
|
||||
@ -943,6 +958,7 @@ fn resolve_provider_credential(name: &str, credential_override: Option<&str>) ->
|
||||
name if is_siliconflow_alias(name) => vec!["SILICONFLOW_API_KEY"],
|
||||
name if is_qwen_alias(name) => vec!["DASHSCOPE_API_KEY"],
|
||||
name if is_zai_alias(name) => vec!["ZAI_API_KEY"],
|
||||
name if is_stepfun_alias(name) => vec!["STEP_API_KEY", "STEPFUN_API_KEY"],
|
||||
"nvidia" | "nvidia-nim" | "build.nvidia.com" => vec!["NVIDIA_API_KEY"],
|
||||
"synthetic" => vec!["SYNTHETIC_API_KEY"],
|
||||
"opencode" | "opencode-zen" => vec!["OPENCODE_API_KEY"],
|
||||
@ -1274,6 +1290,12 @@ fn create_provider_with_url_and_options(
|
||||
true,
|
||||
)))
|
||||
}
|
||||
name if stepfun_base_url(name).is_some() => Ok(Box::new(OpenAiCompatibleProvider::new(
|
||||
"StepFun",
|
||||
stepfun_base_url(name).expect("checked in guard"),
|
||||
key,
|
||||
AuthStyle::Bearer,
|
||||
))),
|
||||
name if qwen_base_url(name).is_some() => {
|
||||
Ok(Box::new(OpenAiCompatibleProvider::new_with_vision(
|
||||
"Qwen",
|
||||
@ -1831,6 +1853,12 @@ pub fn list_providers() -> Vec<ProviderInfo> {
|
||||
aliases: &["kimi"],
|
||||
local: false,
|
||||
},
|
||||
ProviderInfo {
|
||||
name: "stepfun",
|
||||
display_name: "StepFun",
|
||||
aliases: &["step", "step-ai", "step_ai"],
|
||||
local: false,
|
||||
},
|
||||
ProviderInfo {
|
||||
name: "kimi-code",
|
||||
display_name: "Kimi Code",
|
||||
@ -2273,6 +2301,10 @@ mod tests {
|
||||
assert!(is_siliconflow_alias("siliconflow"));
|
||||
assert!(is_siliconflow_alias("silicon-cloud"));
|
||||
assert!(is_siliconflow_alias("siliconcloud"));
|
||||
assert!(is_stepfun_alias("stepfun"));
|
||||
assert!(is_stepfun_alias("step"));
|
||||
assert!(is_stepfun_alias("step-ai"));
|
||||
assert!(is_stepfun_alias("step_ai"));
|
||||
|
||||
assert!(!is_moonshot_alias("openrouter"));
|
||||
assert!(!is_glm_alias("openai"));
|
||||
@ -2281,6 +2313,7 @@ mod tests {
|
||||
assert!(!is_qianfan_alias("cohere"));
|
||||
assert!(!is_doubao_alias("deepseek"));
|
||||
assert!(!is_siliconflow_alias("volcengine"));
|
||||
assert!(!is_stepfun_alias("moonshot"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -2312,6 +2345,9 @@ mod tests {
|
||||
canonical_china_provider_name("silicon-cloud"),
|
||||
Some("siliconflow")
|
||||
);
|
||||
assert_eq!(canonical_china_provider_name("stepfun"), Some("stepfun"));
|
||||
assert_eq!(canonical_china_provider_name("step"), Some("stepfun"));
|
||||
assert_eq!(canonical_china_provider_name("step-ai"), Some("stepfun"));
|
||||
assert_eq!(canonical_china_provider_name("hunyuan"), Some("hunyuan"));
|
||||
assert_eq!(canonical_china_provider_name("tencent"), Some("hunyuan"));
|
||||
assert_eq!(canonical_china_provider_name("openai"), None);
|
||||
@ -2352,6 +2388,10 @@ mod tests {
|
||||
assert_eq!(zai_base_url("z.ai-global"), Some(ZAI_GLOBAL_BASE_URL));
|
||||
assert_eq!(zai_base_url("zai-cn"), Some(ZAI_CN_BASE_URL));
|
||||
assert_eq!(zai_base_url("z.ai-cn"), Some(ZAI_CN_BASE_URL));
|
||||
|
||||
assert_eq!(stepfun_base_url("stepfun"), Some(STEPFUN_BASE_URL));
|
||||
assert_eq!(stepfun_base_url("step"), Some(STEPFUN_BASE_URL));
|
||||
assert_eq!(stepfun_base_url("step-ai"), Some(STEPFUN_BASE_URL));
|
||||
}
|
||||
|
||||
// ── Primary providers ────────────────────────────────────
|
||||
@ -2438,6 +2478,13 @@ mod tests {
|
||||
assert!(create_provider("kimi-cn", Some("key")).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_stepfun() {
|
||||
assert!(create_provider("stepfun", Some("key")).is_ok());
|
||||
assert!(create_provider("step", Some("key")).is_ok());
|
||||
assert!(create_provider("step-ai", Some("key")).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_kimi_code() {
|
||||
assert!(create_provider("kimi-code", Some("key")).is_ok());
|
||||
@ -2990,6 +3037,9 @@ mod tests {
|
||||
"kimi-code",
|
||||
"moonshot-cn",
|
||||
"kimi-code",
|
||||
"stepfun",
|
||||
"step",
|
||||
"step-ai",
|
||||
"synthetic",
|
||||
"opencode",
|
||||
"zai",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user