Repository navigation
test: port the upstream OpenAI tests - #369
Merged
Merged
Conversation
… never started @ai-sdk/openai 4.0.83 starts the stream's `responseId` at `null` (openai-responses-language-model.ts:1587) and only `response.created` sets it, so a stream without that event finishes with `responseId: null`. aimux wrote an empty string. The generate path already writes `null`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 puts the reasoning item's id on every `reasoning-delta` as `providerMetadata.<key>.itemId` (openai-responses-language-model.ts:2735-2749). aimux sent the deltas without provider metadata, while its reasoning start and end parts already carried it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 takes `maxNumResults` as a JS number and sends it as is (openai-responses-prepare-tools.ts:219), so `5` reaches the API's integer field as `5`. aimux typed the field `Option<f64>`, so the typed factory sent `5.0`. It is an `Option<u32>` now; the other number fields of the tool arguments that count things (`partial_images`, `output_compression`) are integers already. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 maps each computer action with mapComputerAction (openai-responses-language-model.ts:128): it keeps the fields of the action's type, renames the scroll offsets, and adds `keys` only when it is not null. aimux copied the wire action and only renamed the scroll offsets, so `"keys":null` (and any extra field) reached the tool input. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
… names
@ai-sdk/openai 4.0.83 builds its tool name mapping from a fixed
providerToolNames table (openai-responses-language-model.ts:378): code
interpreter, computer, file search, image generation, local shell, shell,
web search (and preview), MCP, apply patch, tool search and programmatic
tool calling. aimux mapped the name of any `openai.*` provider tool, so
`toCustomToolName('computer_use')` (line 1358) returned the caller's name
for an `openai.computer_use` tool instead of `computer_use`.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 parses annotations with one zod object per type (openai-responses-api.ts:1500-1535 for responses, 1366-1395 for the annotation.added chunk), which drops unknown keys, and puts the parsed annotations in the text part's provider metadata (openai-responses-language-model.ts:1072). aimux copied the wire annotation, so a container_file_citation kept an `index` field. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
… order
@ai-sdk/openai 4.0.83 parses an apply_patch_call operation as {type, path,
diff} (openai-responses-api.ts:1698) and JSON.stringifies the parsed
operation into the tool input (openai-responses-language-model.ts:1443,
and the delete_file delta in the stream at line 1857), so the keys follow
the schema order. aimux stringified the wire object, keeping the order the
API sent.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 parses a local_shell_call action as {type, command,
timeout_ms, user, working_directory, env} (openai-responses-api.ts:147) and
stringifies the parsed action into the generated tool input
(openai-responses-language-model.ts:998); the stream writes {type, command,
timeoutMs, user, workingDirectory, env} (line 2435). aimux stringified the
wire action, and in the stream moved the renamed keys to the end.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 lets a message's content hold only output_text parts
(openai-responses-api.ts:1486), so a refusal part fails the response schema
and createJsonResponseHandler rejects the call with an APICallError
("Invalid JSON response"); openai-evaluation.test.ts expects doEvaluate to
reject with APICallError for it. aimux skipped non-output_text parts and
returned a result without them. The stream schema does not validate message
content (openai-responses-api.ts:1098), so streaming is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 parses Responses logprobs as {token, logprob,
top_logprobs: [{token, logprob}]} (openai-responses-api.ts:875 chunk,
:1490 response), dropping other keys, and pushes the parsed value into
providerMetadata.openai.logprobs (openai-responses-language-model.ts:1065
generate, :2685 stream). aimux pushed the wire value, `bytes` included.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…ut-end
@ai-sdk/openai 4.0.83 enqueues the tool-input-end of a streamed
function_call with providerMetadata { namespace } when the item has one
(openai-responses-language-model.ts:1986). aimux sent the tool-input-end
without provider metadata and put the namespace only on the tool-call.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…m id only
@ai-sdk/openai 4.0.83 ends a summary part concluded when the next part is
added (openai-responses-language-model.ts:2709) or on
reasoning_summary_part.done with store (:2762) with providerMetadata
{ itemId }; only the ends sent on output_item.done (:2523) carry
reasoningEncryptedContent. aimux added reasoningEncryptedContent to the
early ends as well.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
… index @ai-sdk/openai 4.0.83 records the id each output item started with by output_index (openai-responses-language-model.ts:1633-1644, set at :1905 for reasoning) and resolves reasoning_summary_part.added (:2688), reasoning_summary_text.delta (:2736), reasoning_summary_part.done (:2751) and the reasoning output_item.done (:2503) through it. aimux did this only for messages, so rotated reasoning item ids split one reasoning part into several. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 sends an error part and finishes with error for a chunk that fails the Responses schema (openai-responses-language-model.ts:1664-1680); when the chunk looks like a Chat Completions chunk (a choices array and no string type, :2962) the error is an APICallError explaining that the endpoint speaks Chat Completions (:2972). aimux ignored the chunk as an unknown event. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…rrors @ai-sdk/openai 4.0.83 parses each stream chunk with openaiResponsesChunkSchema (openai-responses-api.ts:869-1443); a modeled event that fails its schema is not matched by the unknown-chunk fallback (:1433-1441), so doStream sends the TypeValidationError as an error part and finishes with error (openai-responses-language-model.ts:1664-1680). aimux read events as loose JSON: a missing output_index defaulted to 0, a missing item was skipped. This checks the envelope fields of each modeled event (type, output_index, item and its type, item_id, the delta/arguments/code/diff string, summary_index, the response object); item internals stay unchecked. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
@ai-sdk/openai 4.0.83 passes the Responses event stream through throwIfOpenAIStreamErrorBeforeOutput (openai-stream-error.ts:39, called at openai-responses-language-model.ts:1552): it reads events until the first output event (isResponseOutputChunk, :3112), throws an APICallError for an error frame or a response.failed with an error, stops at a chunk that fails parsing, and after response.in_progress races each read against 50 ms. aimux only checked the first event, so an error after response.created became an error part of a resolved stream. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…name and the GPT-6 requirement Upstream resolveAsyncToolOption (src/responses/openai-responses-prepare-tools.ts:684-688) warns with feature `async tool calling for "<name>"` and details "Async tool calling is only supported by GPT-6 and later models.". aimux left the name unquoted and said "Async tool calling is not supported by this model." Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…ream reasons
Upstream prepareResponsesTools (src/responses/openai-responses-prepare-tools.ts:183-202,
:454-504, :654-660) warns with feature `allowedTools entry "<name>"` and
separate reasons for a namespaced tool ("tools inside an OpenAI tool
namespace are not visible ..."), a deferred tool ("deferred tools are not
visible ..."), an unlistable provider tool ("OpenAI does not support
<type> tools in tool_choice.allowed_tools") and an ambiguous provider tool
name. aimux left the name unquoted, merged the namespace and deferred
reasons, and worded the tool_search and ambiguity details differently.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…be expressed Upstream prepareResponsesTools (src/responses/openai-responses-prepare-tools.ts:509-515) throws UnsupportedFunctionalityError "allowedTools with only tools that cannot be allow-listed (<dropped names joined by ", ">)". aimux threw the message without the list. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…scriptions error Upstream prepareResponsesTools (src/responses/openai-responses-prepare-tools.ts:174-178) throws UnsupportedFunctionalityError `conflicting descriptions for OpenAI tool namespace "<name>"`. aimux left the name unquoted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…ill reference has no openai entry Upstream resolves file references (src/responses/convert-to-openai-responses-input.ts:142-145, :548-551) and shell skill references (src/responses/openai-responses-prepare-tools.ts:780-783) with resolveProviderReference, whose NoSuchProviderReferenceError says "No provider reference found for provider '<provider>'. Available providers: <keys>", as the chat conversion in aimux already does. The Responses code said "No file reference for openai" and "No skill reference for openai". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…is not supported by the model Upstream (src/responses/openai-responses-language-model.ts:455-492) warns about a request-level reasoningEffortUpdate outside the model's supported efforts with "<model> only supports the following reasoning efforts: <efforts joined by ", ">". aimux said "<model> does not support reasoning effort <effort>". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…n full without response storage Upstream convertToOpenAIResponsesInput (src/responses/convert-to-openai-responses-input.ts:780-842) handles tool search and programmatic tool calls before the providerExecuted check: with store false they are rebuilt as tool_search_call / program items. aimux applied the provider-executed rule first and dropped them (only shell calls were rebuilt). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…tput Upstream convertToOpenAIResponsesInput (src/responses/convert-to-openai-responses-input.ts:1646-1683) maps the caller provider option of a tool result with mapToolCaller and adds it to the function_call_output item. aimux mapped the caller only on function_call items. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
… error A streamed SSE event whose data is not JSON yielded `JsonParse` with only the parser's message. The AI SDK's `parseJsonEventStream` reads each event with `safeParseJSON`, whose `JSONParseError` reads `JSON parsing failed: Text: <text>.\nError message: <message>` (`@ai-sdk/provider` src/errors/json-parse-error.ts:16-19). Found while porting the `@ai-sdk/openai-compatible` 3.0.62 tests (`doStream › should handle unparsable stream parts`, chat and completion); every stream read through `create_event_source_response_handler` now reports it the same way. Well-formed JSON of the wrong shape stays `InvalidResponseData`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
Upstream chat/openai-chat-language-model.ts:235-245 drops prompt_cache_retention for models with supportedReasoningEfforts and warns "promptCacheRetention is not supported by GPT-6 and later models; use promptCacheOptions instead". aimux dropped the field but said "sixth-generation and later models". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
Upstream embedding/openai-embedding-model.ts:94 passes openaiOptions.dimensions through unchanged, so 64 is serialized as 64. aimux parsed it into an f64 and sent 64.0. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
Upstream src/openai-evaluation.test.ts:72-89 expects the Responses request of provider.evaluationModel() to carry text.format.name "evaluation" (EvaluationLanguageModel from provider-utils; its own test, evaluation-language-model.test.ts:87, expects responseFormat.name "evaluation"). aimux's shared DecisionLanguageModel sent "decision", for OpenAI, Anthropic and Google alike. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
Upstream image/openai-image-model.ts:61-92 returns supportsFileInputs true for dall-e-2 and its listed gpt-image/chatgpt-image ids, false for dall-e-3, undefined otherwise, and supportsMaskInputs follows it; Azure passes imageInputCapabilities with undefined values (azure-openai-provider.ts:372-376). aimux used the trait default (unknown) for every model. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
Upstream normalize-openai-json-schema.ts:176-246 rewrites a schema whose
allOf is exactly [{ $ref }] to a direct $ref, and at the root expands a
local #/definitions or #/$defs reference into the root object (keeping the
root's other keys). aimux's normalize_json_schema left the allOf in place.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
Adds the [openai] table: every source file of @ai-sdk/openai 4.0.83 with its Rust file, the modules aimux does not have (live, realtime, batch, skills, speech translation, parallel tool call expansion) as missing under #275, and each case that is not ported with its reason. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
This was referenced Oct 24, 2026
…erver OpenAI realtime transcription now offers the `realtime` subprotocol (with the key as `openai-insecure-api-key.<token>`), and a WebSocket client fails when its offer gets no answer, as the realtime API's own server answers it. The fixture server in ops_fixtures.py sent no Sec-WebSocket-Protocol, so test_gil_release's operation_next case failed with "Server sent no subprotocol". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…iour-match-the-ai-sdk' into test/port-the-upstream-openai-tests
cunninghamcard-bit
marked this pull request as ready for review
October 24, 2026 12:21
This was referenced Oct 24, 2026
The reasoning delta now resolves its item id through output_index (commit "correlate rotated Responses reasoning item ids by output index"), so its test sends rotated ids on the summary events and expects the id the item started with, as asked on #323. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…er Breaking FileSearchArgs::max_num_results changed from Option<f64> to Option<u32>, a change to a public type, so its entry belongs under Breaking rather than Fixed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…s-chat-transcription-and-image-behaviour-match-the-ai-sdk # Conflicts: # CHANGELOG.md
…iour-match-the-ai-sdk' of https://github.com/arcships/aimux into test/port-the-upstream-openai-tests
…as it #354 merged the same entry that commit 25 carried. The master merge kept this branch's copy at its old place, so the diff against master moved it; it now sits where master has it and the diff no longer touches it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
…ription-and-image-behaviour-match-the-ai-sdk' into test/port-the-upstream-openai-tests
cunninghamcard-bit
changed the base branch from
fix/openai-responses-chat-transcription-and-image-behaviour-match-the-ai-sdk
to
master
October 25, 2026 11:15
…eam-openai-tests # Conflicts: # aimux-providers/layout.toml # aimux-providers/tests/openai_embedding_test.rs # aimux-providers/tests/openai_image_test.rs # aimux-providers/tests/openai_transcription_test.rs # aimux-providers/tests/openai_upstream_e2e_test.rs
…eam-openai-tests # Conflicts: # aimux-providers/layout.toml
…eam-openai-tests # Conflicts: # aimux-providers/layout.toml
…eam-openai-tests # Conflicts: # aimux-providers/layout.toml
…eam-openai-tests # Conflicts: # aimux-providers/layout.toml
eric8810
approved these changes
Oct 27, 2026
eric8810
left a comment
Contributor
There was a problem hiding this comment.
Rebase is content-preserving: only master/parent merges and CHANGELOG/layout conflict resolution; tests and CI unchanged. Re-approving current head.
…eam-openai-tests # Conflicts: # aimux-providers/layout.toml
eric8810
approved these changes
Oct 27, 2026
eric8810
left a comment
Contributor
There was a problem hiding this comment.
Rebase verified content-preserving: only master/parent merges and CHANGELOG/layout conflict resolution; CI 16/16. Re-approving current head.
…eam-openai-tests # Conflicts: # aimux-providers/layout.toml
eric8810
approved these changes
Oct 27, 2026
eric8810
left a comment
Contributor
There was a problem hiding this comment.
Rebase verified content-preserving: only master/parent merges and conflict resolution; CI 16/16. Re-approving current head.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
按 RFC-0045(#281)把
@ai-sdk/openai@4.0.83的上游测试迁完,按厂商分批的最后一个(Mistral #295、Cohere #296、DeepSeek #299、Groq #301、Hugging Face #303、xAI #312、Anthropic AWS #319、Azure #324、Open Responses #347、Google Vertex #352、OpenAI-compatible #355、Amazon Bedrock #358、Anthropic #361、Google #363)。上游 34 个测试文件,其中 25 个对应 aimux 已有的功能,共 780 个用例:
src/openai/tests/,一个上游测试文件对应一个 Rust 文件。/// upstream:标记,函数名和函数体不变;另有 49 处旧测试只覆盖一部分,加了/// partial: …指向完整用例。layout.toml:sub-feature(Provider 构造与配置:迁移后遗留缺口 #275):Files 没有 get/download/delete 和流式上传(13 个),没有通用的throwIfOpenAIStreamErrorBeforeOutput帮助函数(7 个,同样的规则在 Responses 的do_stream里实现并由 doStream 用例覆盖),prompt 里的工具调用和结果 part 没有provider_metadata(4 个),没有parallel包装调用的展开(5 个,另有expand-parallel-tool-call.ts整个文件 3 个),UnsupportedFunctionality只带功能名、比不了上游的 message(2 个),嵌入模型没有单次输入字节上限、转写结果没有usage、没有supportsWebSearchSourcesInclude设置、allowedTools没有任意工具名映射(各 1 个)。ts-only:8 个expectTypeOf比较 zod 推出来的 TypeScript 类型,undefined 的工具输入和 undefined 的 header 值 Rust 表达不了,图片下载用的全局fetch在 Rust 里注入不了。missing的responses/expand-parallel-tool-call.ts。另外 9 个上游测试文件(
live/3 个、realtime/3 个、openai-batch、skills/openai-skills、speech-translation/)测的是 aimux 没有的模块,源文件条目是missing,挂 #275,用例不迁。迁移中发现 36 处行为差异,修在 #368 里,一处一个提交,各带一个在 master 上失败的测试;其中 3 处是 #323 的同一改动,1 处是 #354 的同一改动,带上它们是为了这里的用例单独就能过。#368 已合入 master。四个用例按 aimux 已有的约定改了比法,见下面 harness 一节,也登记在 #276。
一、体系概览:OpenAI 的测试现在怎么跑(#368 分支
68ce701f)上游
packages/openai/src/的 25 个已迁测试文件(用例数):二、本 PR 的改动
六个提交,按内容分组:
src/openai/tests/的用例跟着cargo test -p aimux-providers --lib跑,读调用:共享进程状态:
provider.rs里 4 个用例改OPENAI_BASE_URL,#[serial]并在结束时恢复;lib 测试二进制里另有一个用例把它设成"not a url",所以所有新用例都显式传base_url。其余用例不读也不改环境变量,不换进程默认 transport,没有全局计数器,不写临时文件,每个用例用自己的MockFetch/MockWebSocket。layout.toml的[openai]openai-evaluation、openai-forward-compatible-defaults、responses/openai-responses-computer、responses/openai-responses-reasoning-effort-update、responses/convert-to-openai-responses-input-tool-search没有同名源文件,它们的排除写在所测的源文件下面。harness 上的差别(期望值都没改,除了下面写明的比法):
new OpenAIResponsesLanguageModel(...);这里用create_openai加api_key、base_url、fetch建,generateId能注入的地方用 provider 设置注入。10.0等于10);流里的错误 part 按上游形状比,上游 provider stream error 多出的type字段在 aimux 只留在data.type里,比的时候去掉。\nError message:之前的部分,后面是 JS 运行时JSON.parse自己的文字。UnsupportedFunctionality、InvalidArgument只带一个字符串,上游的argument等字段查不了,只比错误类型和消息。chat › doStream › should set .modelId for model-router request:aimux 的Usage.raw原样保留响应里的 usage(RFC-0016),上游快照是 zod 解析后的,少了audio_tokens;改成快照里的字段是原始 usage 的子集,其余部分照旧全等。doStream › late response.failed:错误 part 通过ApiCallError比,providerCode对上游的code;上游的type表达不了。openai-provider › rejects an empty OPENAI_BASE_URL during provider creation:aimux 文档写明环境变量里的坏 base URL 在每次调用时报错而不是建 provider 时,改成建成功、第一次调用报baseURL must be a non-empty string.且不发请求。transcription › doStream › should cancel the audio stream when the WebSocket constructor throws:aimux 的 WebSocket 转写在do_stream返回前就连上(RFC-0028),所以构造失败从do_stream本身返回;两处都接受,并照旧要求音频流被取消。Type of change
Checklist
cargo +1.99 fmt --all -- --checkpassescargo +1.99 clippy -p aimux-providers -p aimux-provider-utils -p aimux-ops --lib --tests --all-features -- -D warningspassescargo +1.99 test -p aimux-providers -p aimux-provider-utils -p aimux-ops --all-features:167 个测试二进制,3568 个测试通过(比 fix: OpenAI Responses, chat, transcription and image behaviour match the AI SDK #368 多 704 个)scripts/check_provider_boundaries.shpassesNotes for reviewers
src/test_support/mod.rs、aimux-providers/layout.toml;这几处在各 PR 里内容相同,后合入的只需合并layout.toml的厂商表。layout.toml的 tests 表里,3 个属于missing的源文件。上游有一个用例名以空格结尾(should extract response id metadata),Rust 的标记行去掉了这个尾随空格。e79ddd01,master 209be26);四个 OpenAI 测试文件的冲突取本 PR 的版本(master 上的版本和 fix: OpenAI Responses, chat, transcription and image behaviour match the AI SDK #368 分支头完全相同),layout.toml是 master 的原文后接 openai 表。Generated by Claude Code