Skip to content

feat(volcengine): add Volcano Engine (Doubao/Ark) provider support#895

Closed
dvrd wants to merge 18 commits intoRightNow-AI:mainfrom
dvrd:feat/volcengine-doubao-ark-provider
Closed

feat(volcengine): add Volcano Engine (Doubao/Ark) provider support#895
dvrd wants to merge 18 commits intoRightNow-AI:mainfrom
dvrd:feat/volcengine-doubao-ark-provider

Conversation

@dvrd
Copy link
Copy Markdown

@dvrd dvrd commented Mar 28, 2026

Summary

  • Adds volcengine and volcengine_coding providers backed by ByteDance's Ark API (ark.cn-beijing.volces.com)
  • Registers 4 Doubao chat models and 8 Ark marketplace models in the model catalog
  • Wires provider into TUI init wizard, settings wizard, launcher, and welcome screen
  • Reuses the existing OpenAI-compatible driver (no new driver needed)
  • Adds doubao as a provider alias routing to the volcengine Ark endpoint

Changes

Core

  • openfang-types: VOLCENGINE_BASE_URL, VOLCENGINE_CODING_BASE_URL, VOLCENGINE_PROVIDER_ID, VOLCENGINE_CODING_PROVIDER_ID, DOUBAO_PROVIDER_ID constants
  • openfang-runtime/drivers/mod.rs: provider defaults, known providers (40 total), auto-detect probe, doubao alias arm
  • openfang-runtime/model_catalog.rs: 12 models across two providers; ark/ namespace for Ark marketplace models to avoid ID collisions with native providers (minimax, zhipu, moonshot, deepseek)
  • openfang-runtime/agent_loop.rs: strip_provider_prefix strips ark/ catalog namespace before sending to Ark API; uses named constants for all three volcengine provider IDs

TUI / CLI

  • init_wizard.rs + wizard.rs: both providers added with hints and correct env var
  • launcher.rs + welcome.rs: VOLCENGINE_API_KEY detection
  • main.rs: provider list, key validation; volcengine_coding probe bypassed (shares key with volcengine, coding plan requires explicit selection)

Bug fixes caught during review

  • Duplicate model IDs resolved via ark/ canonical namespace
  • Empty env-var guard (!v.is_empty()) applied consistently in detect_auth
  • volcengine_coding removed from auto-detect probe
  • ark/ stripping gated to volcengine providers only (not unconditional)
  • Unknown-provider error message now lists all 40 known providers

Tests

  • test_provider_defaults_volcengine / test_provider_defaults_volcengine_coding
  • test_ark_alias_resolution — verifies ark/minimax-m2.5 etc. resolve correctly
  • test_doubao_dual_role_consistency — verifies doubao alias coherence
  • test_doubao_alias_driver_with_direct_key / test_doubao_alias_driver_no_key_errors
  • test_strip_ark_catalog_prefix_for_volcengine_coding + negative case for non-volcengine providers
  • 873 tests passing, zero clippy warnings

Closes #873

dvrd and others added 18 commits March 28, 2026 18:22
Adds full support for the Alibaba Coding Plan (International) API
endpoint (coding-intl.dashscope.aliyuncs.com/v1) as a new LLM provider.

## What's included

- 8 models: qwen3.5-plus, qwen3-max-2026-01-23, qwen3-coder-plus,
  qwen3-coder-next, glm-4.7, glm-5, kimi-k2.5, minimax-m2.5
- Subscription pricing ($0.00 input / $0.00 output) for all 8 models
- OpenAI-compatible driver wired via create_driver; prefix stripping
  handled upstream by strip_provider_prefix (underscore→hyphen
  normalization added for all providers)
- resolve_catalog_model_id helper ensuring metering always resolves to
  the canonical prefixed catalog ID on all 3 call sites (streaming,
  non-streaming, compact_session)
- detect_available_provider probe entry for auto-detection via
  ALIBABA_CODING_PLAN_API_KEY
- Aliases: "alibaba-coding-plan" → qwen3.5-plus,
  "qwen3-coder" → qwen3-coder-plus
- supports_vision: false for all 8 models (coding-specialized endpoint)
- supports_function_calling: true for all 8 models
- Provider accepts both "alibaba_coding_plan" and "alibaba-coding-plan"
  forms in config and create_driver
- Full test coverage: driver creation, missing key, env isolation,
  catalog entries, alias resolution, metering $0 for all 8 models,
  strip_provider_prefix regression tests
- docs/providers.md updated with model table, aliases, base URL,
  vision/function-calling flags

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(volcengine): 添加火山引擎(Doubao)和火山引擎编码计划支持

添加火山引擎(Doubao)和火山引擎编码计划作为新的AI提供商支持,包括:
- 在多个文件中添加VOLCENGINE_API_KEY环境变量配置
- 添加volcengine和volcengine_coding提供商信息
- 更新模型目录添加火山引擎相关模型

* feat(volcengine): 添加对火山引擎和豆包API的支持并更新模型目录

更新模型目录中的火山引擎编码计划模型,增加新模型并调整现有模型的参数

* feat(tui): 添加并调整火山引擎提供商配置

将火山引擎相关配置移至列表更靠前的位置,并确保其配置完整

* refactor(volcengine): standardize display name for Volcano Engine provider

Updated the display name for the Volcano Engine provider across multiple files to remove the "(Doubao)" suffix for consistency.

* fix(volcengine): resolve duplicate model ID and env var guard issues

- Rename doubao-seed-code under volcengine_coding provider to
  doubao-seed-code-ark to eliminate ambiguous model ID lookup
- Add comment marking third-party Ark marketplace models in catalog
- Guard empty env vars in launcher.rs and welcome.rs detect_provider()
  using .ok().filter(|v| !v.is_empty()).is_some() instead of .is_ok()
- Add volcengine and volcengine_coding to unknown-provider error message

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): resolve duplicate model IDs, clarify separators, add provider tests

- Prefix ark-marketplace models with "ark/" to avoid ID collision with
  native minimax, zhipu, and moonshot provider entries (FIX 1)
- Add comment explaining dot vs hyphen separator difference between
  volcengine_coding (coding/v3) and volcengine (v3) endpoints (FIX 2)
- Include "doubao" alias in unknown-provider error message (FIX 3)
- Add "volcengine" probe to detect_available_provider() (FIX 4)
- Add test_provider_defaults_volcengine, _doubao_alias, and
  _volcengine_coding tests (FIX 5)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): display names, ordering, and documentation comments

- Add display field to ProviderInfo in wizard.rs; all providers now show
  human-readable names (e.g. "Volcano Engine" / "Volcano Engine (Coding)")
  instead of raw identifiers
- Swap volcengine/volcengine_coding order to match init_wizard.rs and catalog
- Document "doubao" dual-alias intent in runtime model_catalog.rs
- Document cn-beijing regional hardcoding with base_url override note
- Document zero pricing for Ark-routed third-party models

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): correct provider probe order, display names, and alias comment

- Swap volcengine/volcengine_coding probe order in detect_available_provider so
  the general volcengine provider is auto-selected when VOLCENGINE_API_KEY is set
- Align volcengine_coding display name to "Volcano Engine (Coding Plan)" in both
  init_wizard.rs and wizard.rs
- Add sync-warning comment on the doubao alias in model_catalog.rs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): remove volcengine_coding from auto-detect probe list and add wizard hints

volcengine_coding shares the same VOLCENGINE_API_KEY as volcengine, making it
permanently unreachable in auto-detection. Remove it from PROBE_ORDER so only
volcengine is auto-detected; volcengine_coding remains selectable via the wizard.

Also add descriptive hints for both volcengine entries in the init wizard
("ByteDance Ark platform" / "ByteDance Ark — coding models").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): strip ark/ prefix from Ark marketplace model IDs and fix provider order

Move ark/ prefix to aliases so catalog lookups still resolve but the
bare model name is forwarded to the Ark API (which rejects the prefix).
Also reorder volcengine before volcengine_coding in provider_list().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): strip ark/ prefix before sending model id to Ark API

strip_provider_prefix now removes the ark/ prefix so that model IDs
like ark/minimax-m2.5 are sent as minimax-m2.5 to the Ark API.
Also extends test_ark_alias_resolution to cover find_model paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(runtime): gate ark/ prefix stripping to volcengine providers only

Previously strip_provider_prefix stripped the ark/ prefix for all
providers, which could corrupt model IDs from other providers. Now
the strip only fires when provider is "volcengine" or "volcengine_coding".

Also adds two unit tests verifying the guarded and unguarded cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): add doubao provider alias to ark/ strip guard and extend tests

- Add "doubao" to the ark/ prefix strip condition in agent_loop.rs so
  users with provider = "doubao" get correct model IDs sent to the API
- Add two new tests: volcengine and doubao ark/ stripping
- Update volcengine wizard hints with region info (cn-beijing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(model_catalog): resolve Ark marketplace model ID collisions

The four Ark marketplace models under volcengine_coding had bare IDs
(minimax-m2.5, glm-4.7, deepseek-v3.2, kimi-k2.5) that collided with
native provider entries. Since find_model does a linear scan returning
the first match, ark/ lookups were resolving to the wrong provider.

Fix: make ark/ the canonical ID for each colliding entry, keeping the
bare name as an alias only for deepseek-v3.2 (no collision exists there).
Update test_ark_alias_resolution to assert on the new canonical ark/ IDs
and verify native provider entries remain unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(volcengine): clarify ark/ catalog-vs-wire comment and rename test

---------

Co-authored-by: gaoyiman <gaoyiman@bytedance.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
添加火山引擎(Doubao)和火山引擎编码计划作为新的AI提供商支持,包括:
- 在多个文件中添加VOLCENGINE_API_KEY环境变量配置
- 添加volcengine和volcengine_coding提供商信息
- 更新模型目录添加火山引擎相关模型
更新模型目录中的火山引擎编码计划模型,增加新模型并调整现有模型的参数
将火山引擎相关配置移至列表更靠前的位置,并确保其配置完整
…vider

Updated the display name for the Volcano Engine provider across multiple files to remove the "(Doubao)" suffix for consistency.
… provider tests

- Prefix ark-marketplace models with "ark/" to avoid ID collision with
  native minimax, zhipu, and moonshot provider entries (FIX 1)
- Add comment explaining dot vs hyphen separator difference between
  volcengine_coding (coding/v3) and volcengine (v3) endpoints (FIX 2)
- Include "doubao" alias in unknown-provider error message (FIX 3)
- Add "volcengine" probe to detect_available_provider() (FIX 4)
- Add test_provider_defaults_volcengine, _doubao_alias, and
  _volcengine_coding tests (FIX 5)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add display field to ProviderInfo in wizard.rs; all providers now show
  human-readable names (e.g. "Volcano Engine" / "Volcano Engine (Coding)")
  instead of raw identifiers
- Swap volcengine/volcengine_coding order to match init_wizard.rs and catalog
- Document "doubao" dual-alias intent in runtime model_catalog.rs
- Document cn-beijing regional hardcoding with base_url override note
- Document zero pricing for Ark-routed third-party models

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…as comment

- Swap volcengine/volcengine_coding probe order in detect_available_provider so
  the general volcengine provider is auto-selected when VOLCENGINE_API_KEY is set
- Align volcengine_coding display name to "Volcano Engine (Coding Plan)" in both
  init_wizard.rs and wizard.rs
- Add sync-warning comment on the doubao alias in model_catalog.rs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… and add wizard hints

volcengine_coding shares the same VOLCENGINE_API_KEY as volcengine, making it
permanently unreachable in auto-detection. Remove it from PROBE_ORDER so only
volcengine is auto-detected; volcengine_coding remains selectable via the wizard.

Also add descriptive hints for both volcengine entries in the init wizard
("ByteDance Ark platform" / "ByteDance Ark — coding models").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… fix provider order

Move ark/ prefix to aliases so catalog lookups still resolve but the
bare model name is forwarded to the Ark API (which rejects the prefix).
Also reorder volcengine before volcengine_coding in provider_list().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
strip_provider_prefix now removes the ark/ prefix so that model IDs
like ark/minimax-m2.5 are sent as minimax-m2.5 to the Ark API.
Also extends test_ark_alias_resolution to cover find_model paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tend tests

- Add "doubao" to the ark/ prefix strip condition in agent_loop.rs so
  users with provider = "doubao" get correct model IDs sent to the API
- Add two new tests: volcengine and doubao ark/ stripping
- Update volcengine wizard hints with region info (cn-beijing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The four Ark marketplace models under volcengine_coding had bare IDs
(minimax-m2.5, glm-4.7, deepseek-v3.2, kimi-k2.5) that collided with
native provider entries. Since find_model does a linear scan returning
the first match, ark/ lookups were resolving to the wrong provider.

Fix: make ark/ the canonical ID for each colliding entry, keeping the
bare name as an alias only for deepseek-v3.2 (no collision exists there).
Update test_ark_alias_resolution to assert on the new canonical ark/ IDs
and verify native provider entries remain unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nd add constants

- FIX 1: detect_auth now filters empty strings via .ok().filter(|v| !v.is_empty()).is_some()
  for both primary key and gemini/codex fallbacks, preventing blank env vars from
  triggering AuthStatus::Configured
- FIX 2: volcengine_coding skips /models probe in test_api_key (coding endpoint does not
  expose a standard OpenAI-compatible models list); falls through to return true
- FIX 4: add test_doubao_dual_role_consistency asserting VOLCENGINE_BASE_URL contains
  volces.com and that catalog.find_model("doubao").provider == "volcengine"
- FIX 5: add VOLCENGINE_PROVIDER_ID and VOLCENGINE_CODING_PROVIDER_ID constants to
  openfang-types for use as single source of truth
- FIX 6: disambiguate display names — "Doubao Seed 2.0 Code (Coding Plan)" and
  "Doubao Seed Code (Standard Plan)" to avoid UI confusion between the two plans
- FIX 7: update volcengine_coding wizard hint to mention shared VOLCENGINE_API_KEY
  and Ark Coding endpoint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Provider count increased from 38 to 39 after rebasing onto main which
added alibaba_coding_plan. Update the hardcoded assertion to match.
- Add "doubao" to known_providers() and update count to 40
- Add create_driver smoke tests for "doubao" alias (direct key + no-key error path)
- Adopt VOLCENGINE_PROVIDER_ID / VOLCENGINE_CODING_PROVIDER_ID constants in
  strip_provider_prefix guard (eliminates dead-constant warning)
- Remove stray double blank line in model_catalog.rs
…r error message

- Add DOUBAO_PROVIDER_ID constant to openfang-types and use it in
  strip_provider_prefix guard (all three volcengine aliases now use
  named constants, eliminating bare string literals)
- Expand unknown-provider error message to list all known providers
  (qwen-code, kimi_coding, zhipu_coding, zai, zai_coding, qianfan,
  moonshot, lemonade were previously omitted)
@dvrd
Copy link
Copy Markdown
Author

dvrd commented Mar 28, 2026

Closing — changes will be merged into our fork first.

@dvrd dvrd closed this Mar 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant