feat(providers): add Alibaba Token Plan Responses compatibility - #3255
Conversation
|
@Astro-Han Could you review the compatibility architecture when convenient? Current main owns parsing/serialization through @ai-sdk/open-responses; Maka adds typed request policies and bounded durable summary identity for Alibaba while keeping DeepSeek content-only. The automated contract and negative-path coverage is in place. A protected Token Plan rerun with retained evidence and the requested real TUI screenshot are still pending. |
|
Review follow-up complete on final head 41a1047. Four independently identified boundaries are now covered: header-only request customization cannot bypass store:false/tool-choice policy; legacy and foreign-profile reasoning degrades without blocking; multiple and empty reasoning items retain identity and summary-part boundaries; and streamed reasoning must equal the provider's final summary before durable metadata is attached. A mismatch flushes visible partial text without makaResponses and a later Turn remains usable. DeepSeek is explicitly unchanged from #2972: content-only replay, no new item ID or durable state. Three independent subagent reviews now report no remaining P0-P2. Local evidence: Core 557 passed, focused Runtime 263 passed, provider matrix/thinking 168 passed, root build passed; full Runtime recorded 2,962 passed / 12 skipped with one unrelated PTY 10-second timeout reproduced in isolation. The PR and #3162 descriptions have been updated to match the final behavior. |
|
@Astro-Han The final review follow-ups are now on head 41a1047. DeepSeek has been restored exactly to main's content-only behavior, while Alibaba's request policy, profile-isolated durable replay, multi/empty item handling, and failure-safe summary verification now have focused regression coverage. Could you review this final architecture when convenient? GitHub still requires maintainer authorization before the external-fork Actions can start. |
|
Reviewing! Thanks for asking~ |
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for the final architecture update. I re-reviewed this exact head and found one P2 in the reasoning-item failure path, added inline below.
The provider routing, final store: false override, profile isolation, durable summary validation, and AI provenance otherwise look sound. Approval also needs one author-provided screenshot from the actual user-facing surface: please attach a real terminal or Desktop capture showing qwen3.8-max reasoning followed by a Maka-owned tool continuation. Text-only live verification is not enough for this UI/UX gate.
The remaining exact-head CI gates are still pending, so this is not merge-ready yet.
AI-assisted review disclosure: OpenAI Codex performed the exact-head architecture, failure-recovery, provenance, UI-evidence, and CI analysis; I verified the reproduction, severity, smallest fix, and live GitHub state before posting.
中文说明
当前有一个 P2:第二个 reasoning item 的非法 ID 会让它的无 ID delta 追加到已完成的第一个 item,最终把持久化 summary 状态写坏,导致下一轮在发请求前失败。另请作者提供一张真实 terminal 或 Desktop 截图,展示 qwen3.8-max reasoning 后继续执行 Maka-owned tool;文字说明不能替代 UI/UX 截图。CI 也仍需全绿。
|
Addressed Astro-Han’s P2 inline finding on head 34bed03. The finalized item can no longer be corrupted by deltas from a following unsafe-ID item, and the new restart/recovery regression proves the failed partial Turn does not brick the next request. The remaining reviewer request is the author-provided real Terminal/Desktop screenshot; code-side focused verification is green. |
|
Correction to this correction: the credential owner has clarified that the supplied key is a Token Plan key; the brief Coding Plan classification was incorrect. The earlier temporary run still retained no raw HTTP artifact or request ID, so it remains withdrawn as merge evidence until the reproducible Token Plan probe and requested TUI screenshot complete. |
|
Protected credential/routing probe completed on 2026-08-20 through the branch model factory. Coding Plan Chat returned HTTP 401 ( |
|
Real Maka TUI verification on head 34bed03 using Alibaba Token Plan China with qwen3.8-max: streamed reasoning, a Maka-owned Read tool continuation, and the final answer completed successfully. |
|
@Astro-Han The P2 reasoning-item isolation finding is fixed on head |
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed at 34bed03f. This does not work as written, and the reason is a single unverified assumption about the wire contract.
provider-registry.ts declares reasoningReplay: 'plaintext-summary' for the Alibaba Token Plan provider, which commits the adapter to receiving reasoning as a summary-channel event. The vendored @ai-sdk/open-responses@2.0.28 in this tree only handles response.reasoning_text.delta — the content channel — and emits nothing on the summary channel at all. Because ai-sdk-backend.ts:2394 checks the carrier with strict equality and throws on mismatch, every turn that produces reasoning ends in an error rather than a degraded rendering. That is a P0: the feature's primary path is the path that fails. The fix is either to declare the carrier the vendored SDK actually produces, or to verify against a live endpoint that the summary channel is emitted and pin the SDK version that does so.
Architecturally, the PR builds three things that already exist one seam over: a second provider-options key resolver alongside openAiCompatibleProviderName, a second body-rewriting fetch alongside request-customization-fetch.ts, and a STATE_VERSION that does not match the one sessions were written with. The first two are duplication that will drift; the third silently strands existing sessions. None of them is hard to fold back into the existing seam, and doing so now is much cheaper than after this ships.
Reviewed with Claude Opus as an analysis assistant. The carrier finding is confirmed by reading both this head and the vendored SDK source; it is not reproduced against a live Alibaba endpoint, and that verification is exactly what I am asking for. Reproduction status is stated per finding.
|
@Astro-Han Thanks for the exact-head review. I rechecked The P0 premise does not match the pinned adapter's two-stage stream mapping:
In this PR, The real Maka TUI run on this exact head completed streamed reasoning, a Maka-owned Read continuation, and the final answer. That path cannot complete if the final summary metadata is absent or differs from the streamed text. Both On the three architecture points:
Given the green exact-head CI, approval, pinned adapter, and live strict-summary evidence, I do not see a code change required for these findings. If you have a concrete Review assistance disclosure: OpenAI Codex rechecked the exact head, pinned npm tarball, and PR commit history; I reviewed and approved this response. |
|
Architecture follow-up before the next head update: the new Alibaba Token Plan wire selection, plaintext-summary replay contract, and request compatibility modules ( |
|
Follow-up completed locally for the next head update: (1) the conformance matrix now resolves reasoning replay through the effective Runtime adapter and binds both |
Astro-Han
left a comment
There was a problem hiding this comment.
COMMENT. My earlier P1 and P3 are properly fixed; the P0 has moved rather than been answered, and the way it moved introduces a new architecture problem that I think is the most important thing in this round.
Fixed, and well:
- P1, the throw on a metadata-less
reasoning-end.isUnfinalizedPlaintextSummaryReasoningEnd(model-adapter.ts:869-879) now detects exactly the SDK'sflush()trailer and:364-372defers the decision to the terminal outcome, so an existing provider failure wins while a clean stream still fails closed rather than silently losing replay state. That is a more precise fix than the one I asked for, and the comment explains why. - P3, the unreachable
reject-forced-tool-choicebranch. It is now reachable —ALIBABA_TOKEN_PLAN_RESPONSES.compatibilitylists it.
Still open from the previous head, and unchanged by this one: the second fetch wrapper in open-responses-compatibility.ts (parseJsonBody plus a wrapping fetch) rather than routing the body rewrite through request-customization-fetch.ts, and the duplicate provider-to-key resolver in model-runtime.ts alongside openAiCompatibleProviderName. Both are P2 and both are now more clearly worth doing, because the new provider-runtime-policy.ts makes three separate places where this provider's special-casing lives. On the STATE_VERSION P2 I will hold rather than restate it — the durable state moved into a new responses-reasoning-state.ts at version 1 and I could not re-derive at this head whether any previously written session reads back under a different version. Please say either way in the PR body.
Two P1s inline. To be explicit about what would move me: for the second one, a captured qwen3.8-max Responses body showing the reasoning on the reasoningSummary channel would close it outright and is probably ten minutes of work. For the first one, putting the contract back in the registry — verified — closes it too, so the two are really one decision.
AI disclosure: this review was assisted by Claude (Opus) for code search and cross-checking. Everything above I re-derived myself against the source at b625a699c.
|
Final review/fix loop update on pushed head |
|
@Astro-Han I updated the PR body with direct provider evidence for the two remaining architecture/carrier questions. Alibaba official Responses documentation defines reasoning items with required |
|
Occam/razor cleanup pushed on |
Astro-Han
left a comment
There was a problem hiding this comment.
Re-reviewed at b0d4362fe. I started this round on fc20601c0, the head moved while I was verifying, and I re-derived every finding against the new head rather than carrying anything forward. I dispatched four scoped sub-reviews — security, correctness and resource bounds, integration, simplification and test quality — and used them as leads only; everything published below I confirmed myself by reading this head.
Four things are fixed, two of them the way I would have asked for.
The second fetch wrapper is gone. open-responses-compatibility.ts is now a fourteen-line body finalizer plugged into the existing request-customization-fetch.ts seam instead of a parallel wrapper with its own request reconstruction — that is exactly the right shape, and it removes the behavioural divergence I was about to file (the old copy hard-threw on GET/HEAD/null-body/non-JSON requests where the established wrapper passes them through). The carrier dimension is also gone: plaintext-summary no longer carries a carrier discriminant, which deletes a union arm no code path could produce. The reasoning-end-without-metadata throw is replaced by a deferral, and the yield in the finally does deliver the deferred error because the generator body completes normally there. reject-forced-tool-choice is now genuinely declared.
I have to correct my own P1 about the declaration split. Two of the three things I offered as evidence do not hold, and I would rather retract them than have you refute them one at a time:
- I said the deleted core routing test was not moved. It was, and it is stronger than what it replaced:
__tests__/responses-wire-contract.test.tsasserts both Token Plan providers routeqwen3.8-maxto Responses, thatqwen3.7-maxstays on chat, and that an account-declaredapiProtocoloverride wins. The rule is covered at the layer it now lives in. - I said settings and capability display would see a contract the runtime does not use. There is no such consumer. Outside
provider-registry.tsitself andpackages/runtime/, nothing in the repo readsruntimeAdapter— not desktop, not the CLI. The divergence is latent, not observable today.
What survives is one thing, and I still think it matters: one fact has two declaration sites, and the core side states the opposite of the truth rather than a stale version of it. packages/core/src/provider-registry.ts gives both Alibaba Token Plan providers a runtimeAdapter with no responses at all, and ProviderResponsesContract has no plaintext-summary member, so core's declared position is "this provider does not support Responses" while the runtime routes it there. Relatedly, the docstring at packages/core/src/model-metadata.ts:94-98 now asserts two things that are false at this head — it calls itself the single declared source of the protocol split, and names the runtime model factory and the conformance matrix as its consumers, both of which have moved to defaultOpenAiApiProtocol. Whichever way the layering decision goes, that paragraph has to change.
The architectural question I would like a maintainer to settle, because it outlives this PR: are we adopting "core declares catalog facts, runtime declares execution policy, and runtime policy may add capabilities core says are absent" as a layering? Today it is neither documented nor annotated at runtimeAdapter. A smaller instance of the same question: model-protocol.ts adds reasoningItemId and reasoningSummaryText to the generic thinking event, filled only by the plaintext-summary path. Extending our own protocol is legitimate, but it sets the precedent that every new provider carrier adds fields to the shared event, and that is worth accepting or declining explicitly rather than by default.
For the record on the Runtime Host boundary: this PR does not touch packages/runtime-host at all, and settleModelStepOutcome decides a model step's terminal state, a kind already produced on main. The P2 below is intent bundling, not an authority violation.
One open thread I re-confirmed rather than re-filed, with a sharper mechanism than I first gave: the STATE_VERSION trap is worse than described. The profile is parsed before the version check, so a same-profile version mismatch decodes as malformed with a matching profile, misses the graceful return undefined in materializeRuntimeReplayPlan, and falls through to the throw. A future version bump therefore bricks every session written at version 1. It should degrade the way a profile mismatch already does — that is a two-line change and it is the difference between a migration and a data loss.
Carrying a P1 → COMMENT, not approval.
AI disclosure: reviewed with Claude Code, including four scoped sub-reviews used as leads. Every finding published here I re-derived at b0d4362fe myself — I read the pinned @ai-sdk/open-responses@2.0.28 stream mapping, the decode and replay paths, and the finish-classification diff, and I ran the repo-wide enumeration that retracts my two earlier evidence claims. Sub-review findings I could not confirm at this head are not included.
|
@Astro-Han @jackwener Exact-head follow-up is pushed at The latest review findings are addressed:
The earlier invalid-ID isolation, metadata-less trailer settlement, shared request-customization seam, single Runtime provider-name authority, forced-tool-choice declaration, and real TUI evidence remain intact. Core still has zero diff. Runtime now explicitly documents that its provider policy is layered over Core's catalog-level adapter default and that account Current-main integration also exposed three stale legacy Verification on the pushed tree: root |
|
Hi — this PR conflicts with current I tested a rebase onto current
These are real source conflicts, so they need your judgement rather than a mechanical rebase — please rebase onto current Thanks for the contribution — happy to help if any conflict is unclear. AI-assisted maintenance note, not a review. It does not count as the required human review under |
d84bfc9 to
41427b5
Compare
|
@Astro-Han @jackwener Rebase requested in the maintenance note is complete on head The three conflicts were resolved semantically:
Core and Runtime Host both have zero diff. Verification on the rebased tree: root The new exact-head Actions run again needs external-fork authorization: https://github.com/apache/maka/actions/runs/32645781601. Once it is green, this head is ready for the promised review pickup. |
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for this. test is green on e88e07c2, and the 25 changed files all serve the Token Plan work — I checked each one against the merge base and found nothing riding along.
Two things in the request finalizer are worth another look before this lands; both are inline. They share a shape: the finalizer makes a claim about what the provider supports or does, and the tests assert the claim rather than the provider's behaviour.
One housekeeping note: the verification and live-probe comments in the description still refer to 850ae74a9, an earlier head. They cannot stand as evidence for e88e07c2 — worth refreshing so a later reader does not mistake them for current.
中文
感谢。e88e07c2 上 test 已绿;25 个改动文件我对着 merge-base 逐个过了,都服务于 Token Plan 这条主题,没有夹带。
请求 finalizer 里有两处建议再看一下,都在行内。它们形状相同:finalizer 对供应商的支持范围或行为下了断言,而测试验证的是这个断言本身,不是供应商的实际行为。
另外一件小事:描述里的验证与 live probe 说明仍然指向更早的 head 850ae74a9,不能作为 e88e07c2 的证据,建议更新,免得后来的人误当成当前状态。
Astro-Han
left a comment
There was a problem hiding this comment.
I reviewed this head and found a blocking issue.
[P1] Official Alibaba reasoning stream is treated as a mismatch and fails the turn
The official Responses API uses response.reasoning_summary_text.delta/.done, but the pinned SDK does not convert these to reasoning deltas and instead emits reasoning-end with a final summary. With zero reasoning deltas, the backend's nextPartText === '' vs non-empty summary check throws Streamed plaintext Responses reasoning does not match final provider summary.
Existing tests use DeepSeek's reasoning_text extension fixture and non-streaming overrides, so they do not cover the official event shape. The fix should preserve reasoning_summary_text deltas or treat the completed summary as canonical when no delta is available, and cover official SSE persistence/replay.
The separate provider-profile authority check (B-line) is GO — no competing authority.
Checks on 424619b351 are test: success.
简体中文
存在官方推理流误判导致转轮失败的阻断。424619b to
54dbb8c
Compare
|
@Astro-Han @zhiiw The official Alibaba reasoning-stream P1 is confirmed and fixed on exact head I did not patch
Product-level evidence now drives official raw SSE through the pristine pinned SDK, ModelAdapter, AiSdkBackend, SessionEvent → RuntimeEvent, and a second real Responses request. That second wire request is asserted to contain the exact reasoning IDs and summary boundaries. Separate real-raw regressions cover final mismatch teardown, abrupt transport error, unsafe IDs, and late same-ID recovery. Exact-head gates:
Protected Token Plan China live smoke on the exact code tree completed two production ModelAdapter requests: Three independent review passes report no remaining P0–P2 and score the current implementation 97–98/100. The only outstanding evidence boundary is the requested Windows exact-head re-run; the real raw mismatch test retains the Could you re-review |
Astro-Han
left a comment
There was a problem hiding this comment.
The P1 is genuinely fixed on 54dbb8c4d — I verified the include.rawChunks seam and the gating myself, and the implementation is careful. My objection is to where it lives, not whether it is correct.
The size is the problem. Production diff is +1161. In this repo, #3329 (add the Alibaba China provider) was +44 lines of production code, and #2972 (route DeepSeek reasoning through Open Responses, with tool fallbacks — the closest precedent) was +277 / −292, a net reduction. This PR is 4.2× that precedent.
The provider work is not what grew. provider-runtime-policy.ts +92, open-responses-compatibility.ts +52, request-customization-fetch.ts +34 — 178 lines, right in line with precedent. But 805 of the 1,161 lines sit in open-responses-reasoning-stream.ts +328, model-adapter.ts +288, and responses-reasoning-state.ts +189, rebuilding provider-SSE-to-reasoning mapping inside Maka.
All of that exists because @ai-sdk/open-responses maps response.reasoning_text.delta (dist/index.js:803) and has no reasoning_summary_text branch anywhere — I checked the pinned 2.0.29. That is a small upstream gap, answered here with a permanent in-tree module that suppresses the SDK's own reasoning chunks.
Please go upstream instead. We have filed eight issues against vercel/ai, five against @ai-sdk/open-responses specifically. Median close time is 10 hours; five of seven closed within 34 hours. The two reasoning-related ones were slowest (#18513 at 5.4 days, #18511 at 13.5 days) — still far cheaper than carrying 328 lines indefinitely.
What I am asking:
- File the missing
reasoning_summary_textmapping upstream. Same shape as #18872 and #18870, both closed in about two hours. - If Token Plan must work before that lands, use
patches/.@ai-sdk/provider-utilsis the precedent, andpatches/README.mdalready carries the retirement rule — "Delete when that guard passes against an unpatched package." A patch has an exit condition; a Runtime module does not. - Split the PR. The ~178 lines of provider onboarding stand on their own merits and can land.
The rot is specific: suppressMappedChunk drops the SDK's reasoning/reasoning-delta chunks once any raw reasoning event appears. When upstream adds the mapping, Maka keeps hiding the SDK's now-correct output and keeps running its own normalizer, with nothing to signal the workaround is obsolete.
Three minor points I would not hold anything for: the evidence cites @ai-sdk/open-responses@2.0.28 while packages/runtime/package.json:132 pins 2.0.29 and this PR changes no manifest; output_item.done throws on an unsafe item id while reasoning_summary_text.delta degrades gracefully for the same input, contradicting the stated "visible but permanently undurable" contract; and per AGENTS.md, AI review passes are not independent human review, so their scores should not stand as review evidence.
Not approving on this head — the ask is structural, not a defect.
简体中文
P1 在 54dbb8c4d 上确实修好了,机制我自己验过,实现也扎实。我反对的是它放在哪里,不是它对不对。
问题是体量。 生产代码 +1161 行。仓库内对比:#3329 加 Alibaba China 服务商是 +44 行生产代码;#2972 把 DeepSeek reasoning 走 Open Responses(还含 tool fallback,最近似的先例)是 +277 / −292,净减。本 PR 是该先例的 4.2 倍。
膨胀的不是接服务商那部分——provider-runtime-policy.ts +92、open-responses-compatibility.ts +52、request-customization-fetch.ts +34,共 178 行,量级正常。但 1161 行里有 805 行在三个文件:open-responses-reasoning-stream.ts +328、model-adapter.ts +288、responses-reasoning-state.ts +189,是在 Maka 内部重建 provider SSE → reasoning 的映射。
这些之所以存在,只因为 @ai-sdk/open-responses 只映射 response.reasoning_text.delta(dist/index.js:803),全包没有 reasoning_summary_text 分支——我对着 pinned 的 2.0.29 核实过。一个很小的上游缺口,这里用一个常驻的自建模块绕过去,还把 SDK 自己的 reasoning chunk 压掉了。
请改走上游。 我们向 vercel/ai 提过 8 个 issue,其中 5 个正是 @ai-sdk/open-responses。关闭耗时中位数 10 小时,7 个已关的里 5 个在 34 小时内。最慢的两个恰好是 reasoning 相关(#18513 5.4 天、#18511 13.5 天)——即便如此,也远比永久背 328 行便宜。
具体请求:
- 把缺失的
reasoning_summary_text映射报到上游。形状与 #18872、#18870 相同,那两个都是约两小时关闭。 - 如果 Token Plan 必须在上游落地前可用,走
patches/。@ai-sdk/provider-utils有现成先例,patches/README.md也已写明退出规则——"Delete when that guard passes against an unpatched package"。patch 有退出条件,Runtime 模块没有。 - 拆分 PR。那约 178 行的服务商接入本身站得住,可以单独合。
腐烂点很具体:suppressMappedChunk 一旦见到 raw reasoning 事件就丢掉 SDK 的 reasoning/reasoning-delta。等上游补上映射,Maka 会继续压制 SDK 已经正确的输出、继续跑自建 normalizer,而没有任何信号提示这个 workaround 该删了。
三条不阻塞的小点:证据仍写 @ai-sdk/open-responses@2.0.28,但 packages/runtime/package.json:132 pin 的是 2.0.29 且本 PR 不动任何 manifest;output_item.done 对不合法 item id 直接 throw,而 reasoning_summary_text.delta 对同样输入是优雅降级,与自述的 "visible but permanently undurable" 契约矛盾;另按 AGENTS.md,AI review 不算独立人类审查,其评分不宜作为审查证据。
本 head 不 approve——请求是结构性的,不是缺陷。
AI use: drafted with Claude Code (Opus 5); I verified the size comparison, the upstream SDK source, and the issue turnaround data myself before posting.
|
Filed the upstream gap for you: vercel/ai#19659 It covers exactly the defect this PR works around — Please watch that issue. For calibration on how long this usually takes: of the eight issues we have filed against Once it lands, 简体中文已代为提交上游 issue:vercel/ai#19659 覆盖的正是本 PR 绕过的那个缺陷: 请盯一下这个 issue。参考节奏:我们向 上游落地后, |
ab303c6 to
9e8e8ae
Compare
9e8e8ae to
879e4f4
Compare
|
@Astro-Han The upstream path you requested is complete on head
Local gates are green: fresh |
Generated-by: OpenAI Codex
A consumer that stops the adapter mid-stream (the reasoning-mismatch throw, a user stop) leaves the SDK without a finish chunk, so teardown rejects every result promise. usage and finishReason were already consumed, but response was only read on the completed continuation path — its rejection could surface as an unhandled rejection after the turn unwound, scheduler-timing owned (observed post-test on Windows, where Node makes it a crash). Sink it unconditionally in the teardown finally, and pin the property with an unhandledRejection trap in the mismatch test so every event loop proves the path leaves none behind.
Permit documented required and allowed_tools choices when they select exactly one tool, while keeping provider-owned store:false finalization and rejecting unsupported forced shapes.\n\nGenerated-by: OpenAI Codex
Consume both published Alibaba plaintext reasoning carriers through the AI SDK raw-chunk seam, validate their item and summary boundaries, and preserve durable replay across official, compatibility, error, and migration stream shapes. Generated-by: OpenAI Codex
Upgrade @ai-sdk/open-responses to 2.0.34, which maps both official and regional Alibaba reasoning carriers, and remove the temporary raw-event normalizer while retaining durable summary validation and replay. Generated-by: OpenAI Codex
Record the exact Apache-2.0 override for provider-utils 5.0.32, whose published tarball omits its LICENSE, and regenerate the Desktop and CLI dependency notices for the 2.0.34 dependency graph. Generated-by: OpenAI Codex
Keep the replay and reasoning comments bound to the 2.0.34 version now pinned after the upstream fix. Generated-by: OpenAI Codex
6eddb57 to
66d74c3
Compare
|
@Astro-Han #3255 is now rebased onto current The four conflicts were resolved by retaining both sides' behavior:
Exact-head local gates are green: fresh The protected Token Plan China smoke was also repeated on this rebased tree through production |
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for staying with this through several rounds of review. I re-reviewed exact head 66d74c356.
The size is less alarming once separated: roughly 805 production additions, 2,137 test additions, and 466 generated dependency/license lines. More importantly, moving the carrier mapping upstream to @ai-sdk/open-responses@2.0.34 already removed Maka’s 328-line raw-event normalizer.
I found no remaining P0/P1 issue. The earlier carrier, late-delta, finish-reason, missing-metadata, and provider-authority concerns are either fixed on this head or no longer supported by the current evidence. CI is green, so I’m approving.
I do think a final simplification pass would improve the change before merge:
- remove the test-only
RUNTIME_PROVIDER_PROFILE_IDSexport and its redundant bijection assertion; - remove the direct serialization test already covered more strongly by the two-provider contract-matrix tool-continuation test;
- reuse the existing request customization fetch when no provider finalizer exists, instead of wrapping it again;
- drop the resolved adapter’s original
runtimeProfilefield once it has been converted into the concreteresponsescontract; - remove the redundant unsupported-version fixture.
These are non-blocking, but they are concrete deletions with no capability loss, and I would prefer to land them in this PR. I would not remove the durable reasoning codec, summary boundaries, or the seven backend integration scenarios: those protect different stream, persistence, replay, and recovery boundaries.
OpenAI Codex and delegated @reviewer agents assisted with the code-path and simplification analysis. Astro-Han reviewed the evidence and made the final approval decision.
中文对照
谢谢你耐心跟进这么多轮审查。我重新检查了当前 head 66d74c356。
拆开看以后,这个 PR 的规模没有表面上那么夸张:大约 805 行生产代码、2,137 行测试,以及 466 行自动生成的依赖与许可证内容。更重要的是,carrier mapping 上移到 @ai-sdk/open-responses@2.0.34 后,Maka 自己维护的 328 行 raw-event normalizer 已经删除。
当前没有剩余 P0/P1。之前关于 carrier、late delta、finish reason、缺少 metadata 和 provider authority 的意见,要么已经修复,要么已不再被当前证据支持。CI 全绿,因此我批准这个 PR。
合并前仍建议做一次明确的简化:删除只供测试使用的 profile ID 列表及重复契约测试、删除已被更强端到端测试覆盖的直序列化测试、没有 finalizer 时复用现有 request fetch、解析 profile 后不再保留重复表示,并删除一条重复的 future-version fixture。
这些不阻塞批准,但都属于不损失能力的确定删除项,最好在本 PR 内完成。durable reasoning codec、summary boundaries 和七个 backend 集成场景分别保护真实的流式、持久化、重放与恢复边界,不建议为了缩行数删除。
Apply the approved cleanup pass by dropping redundant profile state and tests, and reuse the existing request customization fetch when no provider finalizer is required. Generated-by: OpenAI Codex
|
@Astro-Han Implemented all five non-blocking simplifications on head
Net result: 13 insertions / 98 deletions. The durable reasoning codec, summary-boundary validation, and seven backend integration/recovery scenarios remain unchanged. Exact-head gates: workspace typecheck, format, lint, ASF headers, Runtime 3,101 passed / 13 skipped / 0 failed, focused cross-surface 493/493, and release contracts 110/110. The PR description is refreshed; new CI is running. |

Summary
Adds Alibaba Token Plan Responses support for
qwen3.8-maxwhile keeping the other Token Plan models on Chat Completions.Core owns only protocol facts and explicit delegation:
openAiAdapterApiProtocoldeclares the Alibaba Token Planqwen3.8-max → openai-responseswire;alibaba-token-planRuntime profile;responsescontract and a Runtime profile.Runtime owns the concrete execution profile:
@ai-sdk/open-responses@2.0.34;store: false, so continuation never depends on a provider-stored response ID;requiredand single-toolallowed_toolschoices while rejecting unsupported forced shapes;reasoning_summary_textand regionalreasoning_textcarriers through the upstream SDK mapping;output_item.done.item.summaryas the durable identity and summary-boundary authority;Fixes #3162
Upstream resolution
The temporary Maka raw-event normalizer is no longer needed:
reasoning_summary_text.deltaand the regionalreasoning_text.deltacarrier;@ai-sdk/open-responses@2.0.34.This head upgrades to 2.0.34 and deletes the workaround, including the 328-line production normalizer and its 241-line dedicated test. The functional cleanup commit is 65 insertions and 633 deletions; the follow-up commit refreshes the generated Desktop/CLI legal notices for the new dependency graph.
Verification
Exact head
bac63a56b, rebased ontomainata956b1ae0:npm cicompleted, reapplied repository patches, and reported 0 vulnerabilities;build:testand full workspace typecheck passed;npm run format:check,npm run lint,npm run check:asf-headers, andgit diff --checkpassed;npm run check:releasecontract, including regenerated third-party notices, passed (110 release tests);tool_searchname isolation and OpenAI/Claude reasoning-summary behavior alongside Alibaba replay;GitHub CI and the independent Windows recovery job are expected to rerun on this new head.
Provider and live evidence
response.reasoning_summary_text.delta/.done: https://www.alibabacloud.com/help/en/model-studio/qwen-api-via-openai-responsesresponse.reasoning_text.delta/.done; both shapes end atoutput_item.done.item.summary: https://help.aliyun.com/en/model-studio/qwen-api-via-openai-responsesstore: falseas not storing the response and making it unavailable toprevious_response_id.A protected live smoke on exact code tree
66d74c356used productionAiSdkBackend + ModelAdapter + getAIModel, the configured Token Plan China connection, andqwen3.8-max. The credential was read only in process and was never printed, placed in command arguments, persisted, or attached.store:false, no replay input, 54 live compatibility-carrier deltas, and one durable reasoning item;store:false, one replayed reasoning item and 34 live compatibility-carrier deltas;end_turn, and both final answers matched their probe sentinels.Historical UI evidence remains available: a real Maka TUI run completed streamed reasoning, a Maka-owned Read continuation, and the final answer: #3255 (comment)
Review focus
output_item.done.item.summaryremains the final durable identity and summary-part authority.ModelInfo.apiProtocolstill overrides the catalog default.AI use
OpenAI Codex assisted with protocol research, implementation, automated tests, live verification, and PR drafting. The human contributor reviewed the scope and remains responsible for the contribution. The commits carry a
Generated-by: OpenAI Codextrailer.Checklist
Does this PR entail a change in behavior?