Skip to content

refactor: give openai its own completion model - #391

Merged
eric8810 merged 1 commit into
masterfrom
refactor/give-openai-its-own-completion-model
Oct 28, 2026
Merged

eric8810 merged 1 commit into
masterfrom
refactor/give-openai-its-own-completion-model

Conversation

@cunninghamcard-bit

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

Copy link
Copy Markdown
Contributor

Before:OpenAICompletionModel 是 OpenAICompatibleCompletionModel 的类型别名。兼容层的 completion 模型为此带一个 CompletionConfig::Native(OpenAIModelConfig) 分支,里面用 OpenAI 的配置、openai_failed_response_handler 和 openai_stream_error;OpenAI 又把 completion 交给兼容层,两个目录互相引用(RFC-0046 §3.3 的 OpenAI ↔ 兼容层环)。

After:OpenAI 照上游 @ai-sdk/openai 有自己的 completion 模型(上游 src/completion/ 本来就是 openai 包自己的),写在 layout.toml 早已指定的 openai/completion/completion_language_model.rs。兼容层的 completion 模型去掉 Native 分支,只剩兼容层自己的逻辑。请求体、结果、流事件都不变。

这是 RFC-0046 R2(拆环)的第三个 PR,跟踪在 #328;前两个是 #389、#390。

一、体系现状(概览)

上游:两个包各有一份 completion 模型,互不引用。

@ai-sdk/openai@4.0.83 src/completion/
  openai-completion-language-model.ts       OpenAICompletionLanguageModel
    ├─ getArgs()  parseProviderOptions('openai') + providerOptionsName,logprobs true→0
    ├─ doGenerate  openaiFailedResponseHandler,providerMetadata.openai.logprobs
    └─ doStream    throwIfOpenAIStreamErrorBeforeOutput → createOpenAIProviderStreamError
  convert-to-openai-completion-prompt.ts / convert-openai-completion-usage.ts / map-openai-finish-reason.ts

@ai-sdk/openai-compatible@3.0.62 src/completion/
  openai-compatible-completion-language-model.ts   OpenAICompatibleCompletionLanguageModel(不认识 openai)

aimux(本 PR 之前):

openai::completion::OpenAICompletionModel = openai_compatible::completion::OpenAICompatibleCompletionModel   ← OpenAI → 兼容层
openai_compatible/completion/completion_language_model.rs
  enum CompletionConfig { Compatible(CompatModelConfig), Native(OpenAIModelConfig) }
    ├─ use crate::openai::config::OpenAIModelConfig                                   ← 兼容层 → OpenAI
    ├─ Native => crate::openai::openai_failed_response_handler()
    └─ Native => crate::openai::openai_stream_error(..)(流开头和流中两处)

二、本 PR 改动(细节)

openai/completion/completion_language_model.rs(新写,对应上游 7 个 completion 文件)
  :34   pub struct OpenAICompletionModel { model_id, config: OpenAIModelConfig }
  :40   from_config()
  :45   provider_options_name()           providerOptionsName
  :54   arguments()                       getArgs:openai 与 providerOptionsName 两个命名空间,logprobs true→0
  :146  request()                         config.url("/completions") + request_headers
  :165  completion_prompt()               convertToOpenAICompletionPrompt
  :213  usage()                           convertOpenAICompletionUsage(只留三个计数,缺的 total 为空)
  :247  metadata()                        getResponseMetadata
  :256  logprobs_metadata()               providerMetadata.openai.logprobs
  :284  parse_response()                  openaiCompletionResponseSchema / ChunkSchema(含 logprobs 校验)
  :349  do_generate()                     openai_failed_response_handler
  :391  do_stream()
  :407    throwIfOpenAIStreamErrorBeforeOutput:首个文本前的错误帧让调用本身失败
  :459  struct OpenAICompletionStream     流中错误帧 → openai_stream_error
  finish reason 用 OpenAI chat 已有的 map_finish_reason::parse_finish_reason(与上游同一张表)
openai/provider.rs
  :193  OpenAICompletionModel::from_config(..)   (原 from_native_config)

openai_compatible/completion/completion_language_model.rs
  CompletionConfig 枚举删除,:29 config: CompatModelConfig
  :77   命名空间固定为 [name, camelCase];删除 native 的 logprobs 处理、预读错误帧、openai 元数据
  :311  流中错误帧只走兼容层的 stream_error
openai_compatible/completion/convert_completion_usage.rs   usage() 去掉 native 参数
openai_compatible/completion/mod.rs                         去掉测试用的 CompletionConfig 导出
openai_compatible/tests/{provider.rs, completion/…}         直接读 model.config

兼容层里还剩一处引用 OpenAI:chat/convert_to_chat_messages.rs 用 crate::openai::convert::tool_result_to_content,#386 把它移到 provider-utils,合入后这个环就完全断开。

测试

范围 结果
全仓 cargo test(aimux-providers lib) 4380 通过,0 失败(与 master 相同)
OpenAI completion(上游 openai-completion-language-model.test.ts 移植) 18 个,全部通过,未改动
兼容层 completion 30 个,全部通过;两个测试 helper 去掉对 CompletionConfig 的匹配
新增用例 无:行为不变,现有用例已覆盖两条路径

体积

文件 增 删
openai/completion/completion_language_model.rs 532 4
openai/provider.rs 1 4
openai_compatible/completion/completion_language_model.rs 40 227
openai_compatible/completion/convert_completion_usage.rs 4 20
openai_compatible/completion/mod.rs 0 2
openai_compatible/tests/completion/completion_language_model.rs 2 5
openai_compatible/tests/provider.rs 2 5
合计 7 个文件 +581 -267

源码多出约 300 行,是上游两个包各有一份 completion 的代价(提示词转换约 50 行两边相同)。completion 是遗留接口,两份分开后各自跟上游走。

公开 API 与行为

  • aimux_providers::openai::OpenAICompletionModel 名字不变,从类型别名变成独立结构体,同样实现 LanguageModel。只有把它当成 OpenAICompatibleCompletionModel 用的代码会受影响;仓库里(各 crate 和各语言绑定)没有这样的用法。
  • 行为不变。

检查

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

OpenAICompletionModel was an alias of the OpenAI-compatible completion
model, which carried a Native branch with the OpenAI config, error
handler and stream errors, so OpenAI and the compatible layer formed a
cycle. OpenAI now has its own model, as @ai-sdk/openai does
(openai-completion-language-model.ts); the compatible model drops the
native branch (RFC-0046 §3.3, R2). Requests and results are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116HPMoqaLfFr1TyqDq1hrW

@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.

OpenAI native completion 分支是忠实搬移,compatible 路径未变,factory/default provider/exports 都接上了,OpenAI→compatible completion cycle 消失。Approve;建议补一条 CHANGELOG Breaking 记录 alias→distinct struct。

@eric8810
eric8810 merged commit 5cc14b1 into master Oct 28, 2026
16 checks passed
cunninghamcard-bit pushed a commit that referenced this pull request Oct 28, 2026
#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
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