Skip to content

refactor: resolve preset base urls in preset - #392

Merged
eric8810 merged 4 commits into
masterfrom
refactor/resolve-preset-base-urls-in-preset
Oct 28, 2026
Merged

eric8810 merged 4 commits into
masterfrom
refactor/resolve-preset-base-urls-in-preset

Conversation

@cunninghamcard-bit

@cunninghamcard-bit cunninghamcard-bit commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Before:兼容层的 BaseUrl 有一个 Preset { descriptor: &'static PresetDescriptor, params } 分支,解析时调 crate::preset::resolve_base_url。兼容层因此 use crate::preset::PresetDescriptor,而 preset 本身建立在兼容层上,形成环(RFC-0046 §3.3 的兼容层 ↔ preset 环)。

After:BaseUrl::Preset 删除。preset 在自己的模块里实现兼容层已有的 ResolveBaseUrl(PresetBaseUrl),以 BaseUrl::Dynamic 交给兼容层;兼容层的生产代码不再认识 preset,依赖只剩 preset → 兼容层。每次请求解析一次、建 provider 时不读环境变量的时机不变,拼出的 URL 不变。

这是 RFC-0046 R2(拆环)的第四个 PR,跟踪在 #328;前面是 #389、#390、#391。另外按 eric 在 #391 的建议,在 CHANGELOG 的 Breaking 里补上 OpenAICompletionModel 从别名变成独立类型这一条。

一、体系现状(概览)

上游:AI SDK 没有 preset 注册表(这是 aimux 扩展,RFC-0036);createOpenAICompatible({ baseURL }) 只收一个字符串,包装它的包(例如 google-vertex 的 MaaS 合作模型)在自己那边算好 URL 再交进去,openai-compatible 不认识它们。

aimux(本 PR 之前):

preset::assemble(descriptor, settings)              preset.rs:403
  └─ BaseUrl::Preset { descriptor, params }        (模板或环境变量里的 URL)
       └─ CompatModelConfig.base_url.resolve()      openai_compatible/provider.rs
            └─ crate::preset::resolve_base_url(..)  ← 兼容层 → preset(环)
BaseUrl::Dynamic(Arc<dyn ResolveBaseUrl>)           Vertex 合作模型已经在用这条路

二、本 PR 改动(细节)

openai_compatible/provider.rs
  去掉 use crate::preset::PresetDescriptor
  :368  enum BaseUrl { Fixed(String), Dynamic(Arc<dyn ResolveBaseUrl>) }   (Preset 分支删除,文档改为两种来源都走 Dynamic)
  :375  fn resolve()  只剩两条分支

preset.rs
  :427  None => BaseUrl::Dynamic(Arc::new(PresetBaseUrl { descriptor, params }))   (在 assemble 里)
  :535  struct PresetBaseUrl { descriptor: &'static PresetDescriptor, params: HashMap<String, String> }
  :541  impl ResolveBaseUrl for PresetBaseUrl  -> resolve_base_url(descriptor, &params)
  :549  fn resolve_base_url()   不再被别的模块调用,pub(crate) 改为私有

openai_compatible/tests/chat/chat_language_model.rs
  :4678 a_lazy_base_url_is_evaluated_per_request_and_its_error_fails_the_request
        原来借一个手写的 PresetDescriptor 走 BaseUrl::Preset;现在用测试里自己的
        :4683 EnvBaseUrl(每次请求读一个环境变量)走 BaseUrl::Dynamic。断言不变:
        建 provider 不读环境,解析失败的请求报 InvalidArgument,下一次请求重新解析。

CHANGELOG.md  Unreleased / Breaking(Google 那条之后)
  `openai::OpenAICompletionModel` 是独立结构体,不再是
  `openai_compatible::OpenAICompatibleCompletionModel` 的别名(#391 的改动)

preset 这一侧的同一行为由 aimux-providers/tests/presets_test.rs:313 the_base_url_variable_is_read_per_request 覆盖(走真实的 preset 路径),本 PR 不改它。

测试

范围 结果
全仓 cargo test(aimux-providers lib) 全部通过(与 master 相同)
tests/presets_test.rs(preset 模板、环境变量、每次请求解析) 全部通过,未改动
兼容层的延迟 base URL 用例 通过;改用测试自己的 ResolveBaseUrl,断言不变

体积

文件 增 删
CHANGELOG.md 8 0
openai_compatible/provider.rs 5 14
openai_compatible/tests/chat/chat_language_model.rs 17 27
preset.rs 23 5
合计 4 个文件 +53 -46

公开 API 与行为

  • 本 PR 的代码改动不动公开 API:BaseUrl、ResolveBaseUrl、resolve_base_url 都是 crate 内部的。
  • 行为无变化。
  • CHANGELOG 补记的 OpenAICompletionModel 变化来自已合并的 refactor: give openai its own completion model #391,不是本 PR 的代码。

检查

已合上 master e76ffeee。cargo +1.99 fmt --check、cargo +1.99 clippy --workspace --all-targets --all-features -D warnings、cargo doc、scripts/check_provider_boundaries.sh、全量测试,均通过。

🤖 Generated with Claude Code

https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW

BaseUrl::Preset held a &'static PresetDescriptor and called
preset::resolve_base_url, so the OpenAI-compatible layer imported the
preset registry while presets build on the compatible layer, a cycle.
Presets now hand the compatible layer a BaseUrl::Dynamic resolver of
their own (PresetBaseUrl); the variant is gone and the compatible test
uses its own resolver (RFC-0046 §3.3, R2). URLs are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW
#391 replaced the alias of the compatible completion model with a struct of
its own; record that as a Breaking change, as review on #391 suggested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW
@cunninghamcard-bit
cunninghamcard-bit marked this pull request as ready for review October 28, 2026 03:27

@eric8810 eric8810 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PresetBaseUrl 把 preset 解析移回 preset,explicit/env/params/default 优先级与 lazy 时机不变,cycle 断开;CI 通过。Approve。

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.

3 participants