Skip to content

包拆分与 provider 重构:RFC-0044、RFC-0046 实施进度 #328

Open

Description

@cunninghamcard-bit

核对基线:master d30f8343(10-28)。跟踪 RFC-0044(#279,crate 拆分与依赖反转)和 RFC-0046(#294,provider 协议的小重构与抽象设计)的实施。每个 PR 开出、合并时更新这里。两份 RFC 已于 10-21 合并,合并之后才发现的后续问题记在这里。

RFC 接受

RFC-0044 步骤(排在 RFC-0046 各厂商搬移合入之后,避免两边同时搬文件)

  • C0 aimux-stream 并入 provider-utils(删除前发最后一个版本)
  • C1 core 内部按层拆开混合文件
  • C2 新建 aimux-provider,先断三条往上的边
  • C3 Fetch 观察点和 DiagnosticScope(含 decide;scope 内容和 observers 的载体见 RFC-0044 §4.2,过渡期 core 的 Recorder 当观察者),provider-utils 不再依赖 core
  • C4 下载归一(连接策略、UA、错误映射三个参数,各路径保持现状,RFC-0044 §4.3)
  • C5 session、trace 在调用层接入(等后续观测 RFC)
  • C6 新建 aimux-devtools
  • C7 改名与发布顺序(provider → provider-utils → aimux → providers → ops → ffi;C4 之后即可,不等观测 RFC)

录制 schema 3 与传输回放(#270,RFC-0048 #325)排在 C6 之后。

RFC-0046 步骤

  • R1 provider-utils 补齐通用函数,删除死代码(with_user_agent_suffix_fn、without_trailing_slash_opt 是公开 API,CHANGELOG 登记破坏性变更)。按函数族拆成几个都基于 master 的 PR,每个只做一族;厂商改用的位置按上游调用这个函数的文件(经 layout.toml 对到 Rust 文件)定。上游测试移植到 aimux-provider-utils/src/tests/,每个 .test.ts 一个文件,随各自的函数进 PR。10 个 PR 已全部开出,6 个已合入;剩下 4 个都已批准,合上新 master 后重推,CI 通过后重新请 eric 审(推送会撤掉批准):
    • 删除两个没有调用方的函数:refactor: remove two dead provider-utils helpers #379(10-27 合入)
    • convert_base64_to_uint8_array、convert_uint8_array_to_base64、convert_to_base64、convert_image_model_file_to_data_uri、convert_inline_file_data_to_uint8_array:refactor: share base64 and file data helpers in provider-utils #380(解码与 AI SDK 的 atob 一致;10-28 合入 ab00ae4f)
    • create_language_model_response_metadata、resolve_provider_reference:refactor: share response metadata and provider reference helpers #381(删除公开的 xai::responses::resolve_provider_reference;10-27 合入 9f9f5ab4)
    • create_tool_name_mapping(ToolNameMapping 从 Anthropic 移出,OpenAI Responses、Google 改用)、strip_file_extension(Bedrock 改为从第一个点切,与上游一致):refactor: share tool name mapping and strip file extension #382(10-28 合入 e76ffeee)
    • map_reasoning_to_provider_effort、map_reasoning_to_provider_budget(9 个厂商改用;Open Responses 补上换算警告):refactor: share reasoning effort and budget mapping #383(10-28 合入 d30f8343)
    • create_provider_stream_error(取代公开的 stream_error_api_call,12 个厂商改用,各家只留状态码表;Bedrock 流内异常错误补上请求体脱敏;补 Google、Mistral、Codex 的流内错误断言):refactor: share provider stream error #384(按 eric 意见理顺 CHANGELOG 的 ### Fixed,head 1dfba34b,与 master d30f8343 无冲突,CI 绿,已重新请 eric 审)
    • parse_provider_options:refactor: share parse provider options #385(合上 d30f8343 推送 3f367135;已用 serde 结构体解析的 11 处改用;报错改为上游的 invalid <provider> provider options;Azure 转写和 OpenAI embedding 的显式 null 经共用的 optional_field 走同一报错,每处调用都断言了报错文字)
      • 后续:手写逐字段校验(34 处)和不校验直接读键(11 处)的位置改成 serde 结构体会改变校验范围和报错,按厂商各做一个 PR:Bedrock、Anthropic、Cohere、Google(embedding、image、language model、video)、Vertex(embedding、transcription、video)、Mistral(4 处)、OpenAI 兼容层(3 处)、OpenAI(chat、completion、image、files、speech、transcription、responses)、Hugging Face、Open Responses、xAI(5 处)
      • OpenAI chat 里的 parse_option_fields(Anthropic 也在用)移进 provider-utils,随 R2 的 internal PR 做
    • tool_result_to_content、tool_result_content_value(从 OpenAI chat 转换挪出,9 个厂商改用):refactor: share tool result to content #386(10-28 合入 e7c94a5a)
    • is_valid_hostname_part(移植上游测试)、base_url_setting:refactor: share hostname part check and base URL setting #387(合上 d30f8343 推送 ca937903)
    • Credential、AuthScheme、ProviderHeaders、UserAgentFetch、transport_user_agent(shared/mod.rs 只留 package_fetch):refactor: share provider credentials and user agent #388(合上 0bc182a9、d30f8343 推送 ef9050ea;refactor: give decision models a small endpoint interface #393 带进的 openai/tests/evaluation.rs 一并改为从 provider-utils 引入)
  • R2 解开七个环(两个 Anthropic 的环靠只有 endpoint 的 AnthropicConfig),加 internal 模块和 CI 检查。每个环一个基于 master 的 PR:
    • OpenAI ↔ Azure:UrlRules、BaseUrlInfo、set_query_param 移进 OpenAI 配置,Azure 只填值:refactor: move azure url rules into openai config #389(10-28 合入 542c9a4e)
    • Anthropic ↔ Google Vertex、Anthropic ↔ Anthropic AWS:AnthropicEndpoint::Resolved(Arc<dyn ResolveEndpoint>),Vertex 和 AWS 各自解析端点,AnthropicHeaders 删除:refactor: resolve anthropic host endpoints outside anthropic #390(AWS 显式 base URL 时 headers 改在请求体之前解析,与另外两条路径一致;10-28 合入 0f4d0087)
    • OpenAI ↔ OpenAI 兼容层:OpenAI 照上游有自己的 completion 模型,兼容层的 completion 去掉 Native 分支:refactor: give openai its own completion model #391(10-28 合入 5cc14b14;OpenAICompletionModel 从别名变成独立类型的 Breaking 条目随 refactor: resolve preset base urls in preset #392 补上)
    • OpenAI 兼容层 ↔ preset:preset 以 BaseUrl::Dynamic 交出自己的 PresetBaseUrl,BaseUrl::Preset 删除:refactor: resolve preset base urls in preset #392(10-28 合入 df82c77a)
    • OpenAI ↔ decision、OpenAI 兼容层 ↔ runtime_decision:DecisionConfig 改为 Arc<dyn DecisionEndpoint>,OpenAI 和兼容层在各自的模型配置上实现:refactor: give decision models a small endpoint interface #393(10-28 合入 9343012f)
    • internal 模块和 CI 检查:本地已写好,refactor: share parse provider options #385 合入后合上 master 开出。内容:OpenAI、Anthropic、Google、兼容层各一个 internal/mod.rs(对应上游 src/internal/index.ts,layout.toml 改指这里),Azure、Codex、Hugging Face、Anthropic AWS、Bedrock、Vertex、preset 只经它引用;AzureOpenAITools 移到 azure/openai_tools.rs(公开路径变为 azure::AzureOpenAITools,Breaking);OpenAI 测试的 azure.responses 模型、Google 语音测试的 google.vertex.speech 模型照上游从配置构造,不再经 Azure、Vertex 的 provider;边界脚本加第 11 条(只允许托管变体到基础厂商、只经 internal、crate 根的 re-export 也算),每条规则搜索的路径必须存在,规则 4c 不再允许兼容层引用 OpenAI 和 preset。例外:stream/chat_tool_calls_tests.rs 用四家厂商的流,R7 按 §5 第 7 条移到 crate 的 tests/
  • R3 托管变体改用 AnthropicConfig(§3.4、§3.5)。每项一个基于 master 的 PR:
    • AnthropicModelConfig 改名 AnthropicConfig,build_request_url(AnthropicRequestUrl)、body_rewrite(AnthropicBodyRewrite)、两个能力开关成为它的字段,Vertex 的 rawPredict URL 和信封挪进 anthropic/request_rewrite.rs:refactor: give anthropic hosts an anthropic config #394(10-28 合入 0bc182a9;与 §3.5 草图的出入:没有 AwsRegional,AWS 的区域主机就是它的端点解析出的 base URL,上游 createAnthropicAws 也不传 buildRequestUrl;没有 Bedrock 改写,Bedrock Converse 不经过 Anthropic 模型)
    • Anthropic AWS 和 Bedrock 的两个 SigV4 外层合成一个,放进 provider-utils;要用 refactor: share provider credentials and user agent #388 移进 provider-utils 的 transport_user_agent,refactor: share provider credentials and user agent #388 合入后开
    • 不做:§3.4 说 Bedrock 的能力表改为调用 Anthropic 的 get_model_capabilities,但上游 amazon-bedrock 5.0.100 仍有自己的 amazon-bedrock-anthropic-model-support.ts(两张模型表),aimux 照上游保留 bedrock/anthropic_model_support.rs
  • R4 Vertex Gemini 改用 Google 模型:fix: Vertex Gemini uses the Google model #291 已做(10-24 合入)。Vertex chat 用 GoogleModel + EndpointConfig + Namespace::Vertex,Vertex 专有的行为在 GoogleModel 里按 Namespace 分支,与上游按 isVertexProvider 分支相同,所以不再另设 GoogleConfig
  • R5 兼容层:Vertex 合作模型的两种改写挪到 body_rewrite:refactor: move vertex partner body rewrites into the compatible config #395(openai_compatible/request_rewrite.rs 的 CompatibleBodyRewrite { VertexMaas, VertexXai },先跑它再跑用户回调;请求不变;对齐文档 §5 登记“托管变体对协议包请求的改写写成枚举”,含 R3 的 Anthropic 两个枚举)
  • R6 模态与搜索厂商去重:未开始;生成结果下载那部分等 RFC-0044 C4
  • R7 目录、文件名、测试位置,layout.toml(下面按厂商列)

R1 到 R6 改的是搬移过的文件。有上游测试的 15 个厂商的搬移 10-27 全部合入,R1 从这里开始。

R7 各厂商搬移(每个搬移 PR 叠在 #278 下对应的测试 PR 上,不改断言、测试数前后相等;公开子模块路径的变化按 RFC-0046 §4.5 第 2 条,在 CHANGELOG Unreleased 的 Breaking 里列出本家旧路径和替代入口。10-25 eric 全部批准。合并顺序是厂商的 fix PR、测试 PR、搬移 PR。10-27 剩下的搬移 PR 每轮都合上测试分支的新头,测试数和测试 PR 相同,CI 全绿)

关联:#276(拆 crate、DiagnosticScope 两项)、#278(上游测试迁移)、#275(迁移中发现的行为偏差)。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:coreCore abstractions (aimux-core)area:providersProvider implementations (aimux-providers)enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions