Skip to content

feat(runtime): adopt Open Responses extension codecs for DeepSeek tools - #5350

Closed
Lxr-max wants to merge 16 commits into
apache:mainfrom
Lxr-max:feat/deepseek-open-responses-codecs
Closed

Lxr-max wants to merge 16 commits into
apache:mainfrom
Lxr-max:feat/deepseek-open-responses-codecs

Conversation

@Lxr-max

@Lxr-max Lxr-max commented Sep 15, 2026 •

Copy link
Copy Markdown

Summary

Fixes #4107

Rebased onto current apache/maka main (0cb4fc32b). DeepSeek Open Responses codecs stay registered at the createOpenResponses construction boundary; after the openResponsesSdkModel() helper extraction on main, the wrap and experimental_extensions now live in that helper so both Open Responses call sites stay aligned.

@ai-sdk/open-responses is already at 2.0.44 on main (newer than the issue’s 2.0.35), so this PR does not bump the package. It registers DeepSeek hosted web_search extension codecs:

  • Encode { type: "web_search" } (DeepSeek ignores search_context_size / user_location)
  • Decode web_search_call into provider-executed WebSearch call/result pairs
  • Stream response.web_search_call.in_progress|searching|completed without entering the client tool loop
  • Replay the original item, including opaque fields, exactly once
  • Drop those hosted pairs when the target adapter cannot recognize the exchange (DeepSeek chat / Anthropic web_search), so mid-session model switch does not emit dangling tool_calls or invalid server_tool_use
  • Treat a provider-executed hosted-search answer as end_turn when Open Responses reports finishReason: tool-calls and the step has no client call left to run. maxSteps no longer records that successful turn as step_limit / failed.

Until vercel/ai#19939 (allowBareTypes) ships a parser-safe change, @ai-sdk/open-responses@2.0.44 only accepts namespaced <implementor>:<type> registrations. This PR keeps namespaced registration plus the DeepSeek-only discriminator wrap. The unreachable bare allowBareTypes branch is deleted so a flag-only upstream cannot silently stop decoding.

Hosted-search product routing remains implemented: false (sibling #3689). Tavily and Anthropic-compatible DeepSeek paths are unchanged. apply_patch / custom_tool_call is out of scope.

Verification

  • Rebased cleanly onto 0cb4fc32b (main is an ancestor of head fa1d82da7; no overlapping files with the intervening main commits)
  • Remaining Astro-Han nits: usesDeepSeekOpenResponsesExtensions takes ProviderType; the tool-result providerExecuted cast is documented
  • npm --workspace @maka/{core,storage,runtime} run build
  • npx biome check on the touched runtime files — clean
  • synthesizes a DeepSeek hosted tool call when replay metadata is missing fails if retargeted to Alibaba-style drop (searchCalls.length === 0) and passes with synthesis expectations (web_search_call present, tool-result dropped, grounded text retained)
  • DeepSeek replay/switch + Alibaba mixed-tool + hosted-search end_turn — 5 pass
  • deepseek-open-responses-extensions.test.js — 16 pass
  • model-adapter.test.js — 41 pass
  • Did not run the full workspace npm test suite

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Cursor Cloud Agent (Grok 4.6 / 4.7) implemented the codecs, discriminator wrap, mid-session replay gate, hosted-search end_turn guard, tests, rebase onto current main, and this PR.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — DeepSeek Open Responses now encodes/decodes the registered hosted-search codec instead of dropping it. Product hosted-search routing is still fail-closed until feat(runtime): restore DeepSeek native WebSearch on Open Responses #3689. Mid-session switches off the Responses wire degrade hosted pairs instead of emitting a malformed request. A hosted-search answer whose provider finish reason is tool-calls, with no pending client call, completes as end_turn rather than step_limit.
  • No

@Lxr-max
Lxr-max marked this pull request as ready for review September 15, 2026 12:27
@github-actions github-actions Bot added the effort/XL Under 2500 readable lines label Sep 15, 2026

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

Reviewed exact head 1877b4ae4b37654a3aa77ac4aed9e5e17e26b641.

This adds a DeepSeek-only Open Responses extension codec plus a fetch-layer discriminator adapter for web_search, web_search_call, and related SSE events. Product routing remains disabled.

I found two correctness gaps in the codec lifecycle; both are included as inline P2 comments. The main issue is that the exact-once replay test exercises an SDK-local carrier that Maka does not persist, so the claimed replay behavior does not survive the production event/history boundary.

Checks run on this head: core/storage/runtime builds; 74 focused tests passed; Biome on all four touched files; ASF header audit; git diff --check; clean merge-tree with current main 6105ae726079b456f63ebe17f624bf76f4d45bff. The full workspace typecheck was not conclusive because downstream packages were invoked before all referenced workspace dist exports were built. Hosted checks currently contain only the label job, not a test gate.

Not ready to merge until the inline findings are resolved.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

): Experimental_OpenResponsesExtensionItem | undefined {
const part = options.part;
if (part.type !== 'tool-call') return undefined;
const stored =

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.

[P2] Preserve the replay carrier across the durable runtime boundary

storedReplayItem cannot recover the original item from the shape Maka actually persists. The Open Responses SDK puts the full opaque item on a separate custom replay carrier; the tool-call metadata contains only { id, itemId }. Maka drops custom stream chunks in model-adapter.ts and persists only that reference metadata on the tool call. I reproduced a second request from this persisted shape: the request contained no web_search_call item and emitted unsupported: provider-defined tool openai.web_search tool-result history. The current exact-once test passes only because it feeds first.content directly back before the runtime boundary. Please persist/reconstruct the full carrier and add a RuntimeEvent -> ModelMessage -> request regression test.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed on later commits (ed77ed1 and following). The opaque Open Responses item is now merged onto the provider-executed tool-call providerOptions so it survives RuntimeEvent persistence. deepseek-open-responses-extensions.test.ts covers RuntimeEvent → ModelMessage → request replay of the original web_search_call (including opaque fields). Please re-review when you have a moment.

providerExecuted: true,
},
];
if (item.status === 'completed' || item.status === 'failed' || options.mode === 'generate') {

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.

[P2] Propagate failed search status as an error result

This branch emits the same ordinary tool-result for status: "failed" as for a completed search, without isError: true. Maka only marks provider results as failures when the SDK chunk is tool-error or carries isError, so a failed hosted search is persisted and displayed as a successful tool result. A focused doGenerate probe with a failed web_search_call produced a provider-executed result containing status: "failed" but no error flag. Please mark failed items as errors and cover the runtime mapping.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed on later commits. Failed web_search_call items now emit isError: true on the provider-executed tool-result, and model-adapter maps that through as an error result. Covered by marks a failed hosted search item as an error result and marks failed provider-executed tool results as errors.

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

Reviewed exact head 59cd3256ad498e58a360ff46cc520138c952a7f7.

This follow-up fixes both previously reported issues: the opaque Open Responses extension item now survives the RuntimeEvent/history boundary, and failed hosted searches are marked as error results. The durable replay test exercises the persisted event shape and sends the reconstructed item through the provider request path.

I found one remaining concurrency/lifecycle correctness issue in the new carrier state, included as an inline P2 comment. The ModelAdapter is shared by concurrent turns, but the pending replay map is shared across every physical stream.

Checks run on this head: clean npm ci; core/storage/runtime builds; 292 focused Runtime tests passed; changed-file Biome; ASF header audit; git diff --check; and a clean merge-tree with fetched main ec59d42f6021a4b40e18f10dad184a1821e6f0c4. GitHub reports MERGEABLE / BLOCKED, REVIEW_REQUIRED, and no hosted status checks for this head. The PR API still reports base OID 6105ae726079b456f63ebe17f624bf76f4d45bff, while the live main ref is newer. I did not call the real DeepSeek API.

Not ready to merge until the inline finding is resolved.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

Comment thread packages/runtime/src/model-adapter.ts Outdated
private readonly runtime: ResolvedModelRuntime;
private readonly openAiChatReasoningTransportState: OpenAiChatReasoningTransportState;
private readonly openAiResponsesTransportState: OpenAiResponsesTransportState;
private readonly pendingOpenResponsesExtensionReplay = new Map<string, ProviderOptions>();

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.

[P2] Scope replay carriers to one physical stream

This map lives on the session-wide ModelAdapter, although AiSdkBackend explicitly permits multiple concurrent send() calls and routes every stream through the same translateChunk(). I reproduced the production startStream() path with two simultaneous streams using the same provider-controlled item id: after carrier A, carrier B, then tool-call A, A persisted B's opaque provider_trace; tool-call B then had no item at all. Entries also have no finish/error/dispose cleanup, so an interrupted stream can leave stale state behind. Keep this association inside toModelStreamResult() (one map per physical request, cleared in finally) and add a concurrent-stream/aborted-stream regression.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed on later commits. The pending replay map now lives inside toModelStreamResult() (one map per physical stream) and is cleared on every iterator termination path. Concurrent same-id streams and aborted-then-later-request regressions are in model-adapter.test.ts.

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

Reviewed exact head bf65b76940b4e4ec40a0e2e2934676379cf0990c.

This follow-up resolves the previously reported concurrency/lifecycle issue. toModelStreamResult now owns the pending Open Responses replay-carrier map per physical provider stream (packages/runtime/src/model-adapter.ts:350-372) and clears it on every iterator termination path (:408-415). The regressions exercise concurrent streams using the same provider item id and an aborted stream followed by a later request (packages/runtime/src/__tests__/model-adapter.test.ts:806-900). I found no remaining P0-P3 issue in the current diff.

Validation on this head: clean Node 24.18.1 install; build:test; full workspace typecheck; Runtime 3495 passed / 13 skipped; focused 294/294; lint; format; ASF headers; and git diff --check. The merge tree with current main 4410c3a2d19d20cfdc6b7815bdd2d72d33a7460f is clean. Its focused run had one sandbox retry-count failure, which reproduces unchanged on pure current main and is not attributable to this PR. GitHub reports MERGEABLE / BLOCKED, REVIEW_REQUIRED, and no hosted status checks. I did not call the real DeepSeek API.

No technical blocker found on this head; final merge readiness still depends on repository review policy and live gates.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

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

Review

Scope: codec correctness / round-trip fidelity, not a line-by-line pass. Most of the risk here is in how the codec lines up with the SDK's extension seam, so I cross-checked the diff against the pinned @ai-sdk/open-responses@2.0.44 and @ai-sdk/provider@4.0.14 in this checkout (node_modules/@ai-sdk/open-responses/dist/index.js / index.d.ts) rather than only against the patch.

Verified

  1. Registration shape is valid for the pinned SDK. createOpenResponsesExtensionRegistry throws unless toolType+encodeTool, itemTypes+decodeItem and eventTypes+decodeEvent are provided in pairs, and assertNamespacedType requires the namespace to match the extension id. deepseek-open-responses-extensions.ts:221 registers all three pairs under openai.web_search with openai:* types — consistent in both the bare and namespaced branches.

  2. The extension id is the real provider-tool id in production, not just in tests. compileProviderTool('openai-web-search') returns openai.tools.webSearch(...) (model-adapter.ts:1255), i.e. provider-tool id openai.web_search, which is exactly DEEPSEEK_OPEN_RESPONSES_WEB_SEARCH_EXTENSION_ID. So the extension binds to the tool Maka actually lowers, and the wrap maps it to DeepSeek's bare web_search.

  3. Content-part shapes are V4-correct. The tool-result part uses result + isError (LanguageModelV4ToolResult, @ai-sdk/provider d.ts:556), not the prompt-side output. providerExecuted: true on that part is load-bearing: Maka drops tool-result chunks unless providerExecuted === true (model-adapter.ts:1126) and reads chunk.output ?? chunk.result (:1140). The as Experimental_OpenResponsesExtensionContentPart cast is therefore justified (the type omits providerExecuted on tool-results) — a one-line comment would stop it reading as a type escape hatch.

  4. Carrier contract matches what the SDK emits — kind open-responses.extension-replay, payload providerMetadata[<provider name>].openResponsesExtension = { id, item } (dist:1451). Scanning all provider keys instead of assuming deepseek (deepseek-open-responses-extensions.ts:137) is the right call, since runtimeProviderName() returns the connection slug for openai-compatible connections (provider-runtime-policy.ts:81).

  5. No duplicate decode in streaming. decodeItem is invoked only from the non-streaming path (dist:1058) and response.output_item.done (dist:1256); output_item.added for extension items is ignored, so the in_progress item in the stream fixture cannot produce a second tool-call.

  6. Ordering works because the SDK emits the carrier first. decodeExtensionItem returns [carrier, ...decoded] (dist:1414), so pendingOpenResponsesExtensionReplay is populated before the matching tool-call chunk. The per-request map (model-adapter.ts:366, cleared at :414) plus the concurrency/abort tests (model-adapter.test.ts:806, :860) cover the shared-state risk properly.

  7. Exactly-once history replay. The SDK pushes an item carrying the full item once (dedup on type:id) and silently skips parts carrying only {id, itemId} (dist:344-360). The projection's split — carrier keeps the item, tool-call/tool-result keep the reference (ai-sdk-message-projection.ts:419-441) — is exactly what that encoder expects, and the durable test (deepseek-open-responses-extensions.test.ts:473) asserts a single web_search_call with the opaque fields on the wire.

  8. Persistence round-trip closes. tool_start persists providerOptions into function_call content (session-event-runtime-mapper.ts:268), the core schema allows it (runtime-event.ts:1097), and buildRuntimeEventModelReplayPlan carries it onto the tool_call item (model-history.ts:870).

  9. Feature detection is tight. Only providerType === 'deepseek' gets the wrap and extensions, so Anthropic-compatible and OpenAI-compatible DeepSeek endpoints are untouched; unregistered provider tools still warn and drop (…extensions.test.ts:256); createRequestCustomizationFetch returns upstream unchanged when there is nothing to customize (request-customization-fetch.ts:40), so the model-factory.ts:174 change adds no wrapper in the no-customization case.

  10. The providerExecutedTools flip is scoped. With the short-circuit at model-adapter.ts:177, non-Responses DeepSeek adapters were already true via the kind !== 'responses' clause, so the only behavior change is DeepSeek + open-responses. streamText filters providerExecuted out of clientToolCalls and skips execution for it, so the "no client tool loop" claim holds.

The one item I'd like addressed

DeepSeek's hosted-pair replay degradation lost its only test (ai-sdk-backend.test.ts:3346, :3425). Those two tests were the regression guard for "Open Responses cannot round-trip a provider-executed pair → drop it, keep the grounded text". Because providerExecutedTools is now true for DeepSeek, they were re-pointed at alibaba-token-plan-cn instead of being updated, so:

  • nothing asserts what DeepSeek now does with a persisted provider-executed pair without carrier providerOptions — i.e. history written before this change, or any turn where the carrier merge didn't happen. That path takes encodeInputItem's synthesis branch (deepseek-open-responses-extensions.ts:375) and the SDK then warns provider-defined tool openai.web_search tool-result history while dropping the result. Maka consumes no SDK warnings anywhere in the model path, so that signal is invisible.
  • the test name ("Open Responses cannot replay a hosted tool pair") no longer describes the fixture provider.

Latent today (routing stays implemented: false, so no such history can exist in product), but it becomes load-bearing when #3689 flips the flag. Cheapest fix: keep one of the two tests on DeepSeek with updated expectations (synthesized web_search_call item present, result dropped, grounded text retained).

Nits

  • Dead code: OUTGOING_EVENT_TYPES (deepseek-open-responses-extensions.ts:81) is never read — events only flow inbound. Neither gate catches it: biome.jsonc is an explicit allowlist (preset: "none") without noUnusedVariables, and tsconfig.base.json sets no noUnusedLocals.
  • The allowBareTypes branch is unreachable and untested (:221; the rewrite tests early-return when the probe is true, …extensions.test.ts:139/:191). Note the SDK's own guards require a : in the type for items and events (dist:167-180), so if upstream ships allowBareTypes without relaxing those, this branch would register successfully and then silently stop decoding. A comment or a unit test constructing the bare variant directly would pin the assumption.
  • decodeEvent no-ops on searching/completed (:403): the call/result materialize only from output_item.done. Fine for DeepSeek's documented sequence, but if output_item.done is ever omitted, the turn ends with a tool-input-start and no call/result.
  • generate vs stream parity (:362): mode === 'generate' emits the tool-result even for a non-terminal status (in_progress), which streaming deliberately does not. Intentional? A comment would help.
  • Body handling (:262, :492): every DeepSeek JSON request body is buffered and re-serialized even when no type matches OUTGOING_TOOL_TYPES (rewriteDeepSeekOpenResponsesOutgoingBody always returns a fresh object, so the no-op case isn't detectable). With a request customization configured the body is serialized twice per request. Cheap win: return undefined when nothing changed.
  • translateChunk's new third parameter defaults to a fresh Map (model-adapter.ts:526), so a future caller that forgets it silently loses carriers with no error. Consider making it required.
  • usesDeepSeekOpenResponsesExtensions(providerType: string) (:125) accepts a plain string; the repo has a ProviderType union and both callers pass it.
  • The streaming test bypasses streamText (…extensions.test.ts:670 drives model.doStream directly). Maka's runtime always goes through streamText, where parseToolCall validates against the provider tool's (absent → empty-object) schema. The carrier path is covered at the startStream level with hand-crafted chunks, but no test drives an SDK-generated carrier through startStream/AiSdkBackend; worth adding alongside #3689.
  • Durable payload size: the opaque item is now persisted inside every provider-executed function_call event's providerOptions, so it also flows through the history-compaction/recap paths that clone providerOptions. Bounded by web_search_call.action today — flagging for whoever owns compaction.

@cursor
cursor Bot force-pushed the feat/deepseek-open-responses-codecs branch from ae646fb to ac9bd40 Compare September 18, 2026 04:50
@Lxr-max

Lxr-max commented Sep 18, 2026

Copy link
Copy Markdown
Author

Following up on @Astro-Han's review (DeepSeek hosted-pair replay degradation coverage + nits).

Addressed on the latest head (ec176e2 and parents after rebase onto current main):

  • Restored/tightened DeepSeek coverage for the no-carrier synthesis path (synthesized web_search_call present, result dropped, grounded text retained); Alibaba keeps its own degradation case
  • Removed unused OUTGOING_EVENT_TYPES; no-op body rewrite returns undefined; comments for generate vs stream parity and allowBareTypes
  • Rebased cleanly (only model-factory.ts conflict — DeepSeek wrap now lives in openResponsesSdkModel())

Would appreciate a re-review when you have a moment. Thanks!

@cursor
cursor Bot force-pushed the feat/deepseek-open-responses-codecs branch from ec176e2 to 60476fc Compare September 20, 2026 14:20
@Lxr-max

Lxr-max commented Sep 20, 2026

Copy link
Copy Markdown
Author

@Astro-Han @hqhq1025 — re-review request after the DeepSeek hosted-pair follow-up and a rebase onto current main (205a06efb). Head is 60476fcef on Lxr-max:feat/deepseek-open-responses-codecs (same PR, no new branch).

Astro-Han must-fix: DeepSeek no-carrier replay coverage is back in ai-sdk-backend.test.ts as synthesizes a DeepSeek hosted tool call when replay metadata is missing. Persisted provider-executed pair without carrier providerOptions now asserts:

  • synthesized web_search_call present (encodeInputItem synthesis)
  • tool-result dropped (function_call_output / web_search_result / tool-result absent)
  • grounded text retained (Maka shipped the feature.)
  • test name matches the DeepSeek fixture

Alibaba keeps keeps unrelated client tool history when degrading a hosted tool pair. Product routing is still implemented: false (#3689 untouched).

Cheap nits: unused OUTGOING_EVENT_TYPES removed; no-op body rewrite returns undefined; comments pin generate vs stream result parity and the allowBareTypes parser assumption. Larger nits (streamText carrier, compaction) left for #3689.

hqhq1025 threads: carrier persistence, failed-search isError, and per-stream carrier scoping are in place on later commits; replied on those threads.

Focused checks on this head:

  • npm --workspace @maka/{core,storage,runtime} run build
  • npx biome check on the touched files — clean
  • synthesizes a DeepSeek hosted tool call when replay metadata is missing + Alibaba mixed-tool test — 2 pass
  • deepseek-open-responses-extensions.test.js — 15 pass
  • model-adapter Open Responses / failed-result / abort-isolation tests — pass

Would appreciate a re-review. Thanks!

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

The codec work itself is solid — verified clean on the trust boundary that mattered most: the discriminator wrap is exact Map.get membership both directions (no prefix/substring leaks), scoped to providerType === 'deepseek' only, content-length deleted on rewrite, non-JSON/SSE bytes pass through untouched; replay consumes the carrier per physical stream with item.id === toolCallId matching; provider-executed calls never reach returnedToolCalls so no phantom client tool calls; history degradation is honest (unmatched calls dropped with diagnostics, grounded text preserved); encode emits exactly {type:'web_search'} with search_context_size/user_location never reaching the wire; implemented:false scope holds and Tavily/Anthropic paths are untouched.

One P1 and one P2 below — both are consequences of DeepSeek becoming a producer of provider-executed exchanges, which the surrounding machinery wasn't built for.

P2 — provider-executed web_search exchanges replay malformed on non-Responses wires. emitStep (ai-sdk-message-projection.ts:407-432) emits provider-executed call/result parts into any admitted plan with no origin-provider check, and providerExecutedTools now admits them for deepseek on every wire. Two concrete breakages on mid-session model switch (②):

  • DeepSeek → deepseek-chat/deepseek-reasoner (same connection, chat wire): convert-to-openai-compatible-chat-messages emits every tool-call part as assistant tool_calls ignoring providerExecuted, while the carrier and tool-result parts drop silently — the wire gets tool_calls:[{name:'WebSearch'}] with no matching tool message, which OpenAI-compatible endpoints reject → every subsequent request fails until history compacts past the step.
  • DeepSeek → Anthropic with hosted web_search offered: the call becomes server_tool_use{name:'web_search', input:<deepseek action>} and the result fails webSearch_20250305OutputSchema validation → prompt conversion throws every turn.

Verified safe directions: native OpenAI Responses drops the pair cleanly; generic open-responses providers stay fail-closed; Anthropic without the tool offered warns and drops. The defect class predates the PR, but this creates the first routine producer of provider-executed calls for deepseek — worth fixing before sibling #3689 flips implemented. Minimal fix: gate provider-executed exchange emission on the target adapter recognizing the exchange's replay state, or at minimum drop them on openai-chat-plaintext wires instead of emitting as client tool_calls.

P3s:

  • ai-sdk-message-projection.ts:431 — replayReference propagates the call's providerOptions onto the result for all providers, not just extension ones: an Anthropic provider-executed result now inherits {anthropic:…} caller options where main attached none. Possibly benign, possibly a latent fix, but a behavior change outside stated scope — have openResponsesExtensionReplayReferenceOptions return undefined unless it actually projected an extension reference.
  • openResponsesSupportsBareExtensionTypes() probes by construction — a flag-only upstream release (accepts allowBareTypes, parsers still require :) flips registration to bare types and silently stops decoding; the file's own comment notes this. Simplest fix is deleting the bare branch — the namespaced registration + discriminator wrap already emits the correct bare wire regardless; alternatively make the probe exercise a real decode path.
  • Replay dedup assumes provider item ids are unique across the whole request history (${type}:${id}) — if DeepSeek reuses web_search_call ids per response, a later genuinely-different search is silently deduped. Unverifiable without DeepSeek's id scheme; worth pinning in the test plan.

// replay is open for its hosted items; other Open Responses providers
// stay fail-closed.
providerExecutedTools:
usesDeepSeekOpenResponsesExtensions(this.input.connection.providerType) ||

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.

P1 — provider-executed web_search_call ends the turn as tool-calls → step_limit → recorded failed. With this extension, @ai-sdk/open-responses counts provider-executed parts in hasToolCalls with no providerExecuted exclusion (open-responses-language-model.ts:459,620-622 — contrast @ai-sdk/openai's hasFunctionCall, which deliberately counts only client calls). So a DeepSeek response carrying web_search_call + a final answer maps to finishReason:'tool-calls'; ai-sdk-turn.ts:2447-2451 then reports step_limit whenever maxSteps is defined — which is always for handoff continuations, child executions, and eval budgets (the repo's own deepseek eval fixtures set maxSteps). mapCompleteStopReason('step_limit') → failed → tool_step_cap_reached. A turn that successfully answered via hosted search records as failed on the exact model this PR targets. Decode is live today even with implemented:false (a web_search_call in any response decodes regardless of whether the tool was offered), and it becomes ① the moment #3689 flips. Minimal fix: only label step_limit when client work was actually pending — finishReason === 'tool-calls' && returnedToolCalls.length > 0 — or suppress when the step's only tool activity was provider-executed (attemptSawToolActivity is already tracked). The upstream fix belongs in @ai-sdk/open-responses (match hasFunctionCall semantics), but Maka needs the guard regardless until that lands.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed on 3e851daa8.

step_limit is now only used when maxSteps is set, the provider finish reason is tool-calls, and the last settled step still has client tool calls (lastCompletedStepHadToolResult). A provider-executed hosted search that already includes the final answer completes as end_turn via mapFinishReason('tool-calls').

Regression: records a hosted-search answer as end_turn when the provider finish reason is tool-calls (DeepSeek connection, maxSteps: 4, one stream, grounded text kept, no error). The existing client-tool step-limit test still expects step_limit.

Chat-wire replay still drops the pair: wire === 'openai-chat' already covers openai-chat-plaintext, so the redundant kind comparison was removed to satisfy the narrowed ResolvedModelRuntime union after the rebase onto 0052f1cfd.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Follow-up: main moved to 30c406c9e (context-recovery output cap) while this was in review. Rebased again; the same step_limit guard is now head c44cfdf08. Focused runtime build and the hosted-search / model-adapter suites still pass on that head.

toolCallId: result.toolCallId,
toolName: result.toolName,
output: await materializeReplayToolResult(result, call.toolName),
...(replayReference !== undefined ? { providerOptions: replayReference } : {}),

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.

P3 — replayReference now propagates the call's providerOptions onto results for all providers. openResponsesExtensionReplayReferenceOptions returns the options unchanged when there's no openResponsesExtension inside, so a non-extension provider-executed result (e.g. Anthropic web_search_tool_result) now inherits the call's provider options where main attached none — getAnthropicCaller/getCacheControl then read them downstream. Return undefined from the helper unless it actually projected an extension reference.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed on later commits (current head fa1d82da7).

openResponsesExtensionReplayReferenceOptions returns undefined unless it actually projected an extension {id, itemId} reference. Non-extension provider-executed results (for example Anthropic web_search_tool_result) no longer inherit the call's providerOptions. Covered by merges the opaque replay item onto tool-call provider options.

@cursor
cursor Bot force-pushed the feat/deepseek-open-responses-codecs branch from 60476fc to 194e438 Compare September 21, 2026 00:17
@Lxr-max

Lxr-max commented Sep 21, 2026

Copy link
Copy Markdown
Author

@Astro-Han — follow-up on your 2026-09-20 re-review (5261344309). Same PR, head 55346a9fb on Lxr-max:feat/deepseek-open-responses-codecs, rebased onto current main (feb9cf22f).

P2. Provider-executed hosted web_search is now gated on the target adapter recognizing the exchange (ModelAdapter.canReplayProviderExecutedExchange, used from canReplayProviderNative / dropUnsupportedReplayItems / emitStep):

  • DeepSeek → deepseek-chat (openai-chat-plaintext): pair dropped, grounded text kept, no dangling tool_calls / missing tool message
  • DeepSeek → Anthropic with hosted web_search offered: pair dropped, no server_tool_use + webSearch_20250305OutputSchema throw
  • Anthropic-shaped hosted search still replays on Anthropic (judged on the whole call/result exchange)
  • DeepSeek Open Responses synthesis path unchanged

Regressions: drops DeepSeek hosted search when replaying onto deepseek-chat and drops DeepSeek hosted search when replaying onto Anthropic web_search.

P3.

  1. openResponsesExtensionReplayReferenceOptions returns undefined unless it actually projected an extension reference (Anthropic caller options no longer copy onto results)
  2. Deleted the unreachable allowBareTypes bare-registration branch; namespaced registration + discriminator wrap stay
  3. Pinned SDK ${type}:${id} dedup in a comment + replays distinct hosted search items when ids differ (DeepSeek same-id reuse across responses still unverified)

Focused checks: core/storage/runtime build; Biome clean; hosted-pair / switch tests 6/6; extension suite 16/16; model-adapter replay-gate / carrier / abort tests pass. #3689 routing still implemented: false.

Would appreciate another look. Thanks!

@github-actions github-actions Bot added effort/XXL Over 2500 readable lines and removed effort/XL Under 2500 readable lines labels Sep 21, 2026
@cursor
cursor Bot force-pushed the feat/deepseek-open-responses-codecs branch from 55346a9 to 95e6a41 Compare September 22, 2026 14:23
@Lxr-max

Lxr-max commented Sep 22, 2026

Copy link
Copy Markdown
Author

@Astro-Han @hqhq1025 — re-review request. Same PR, head 3e851daa8 on Lxr-max:feat/deepseek-open-responses-codecs, rebased onto current main (0052f1cfd).

P1 (discussion_r4057692452). A provider-executed hosted search whose finish reason is tool-calls no longer becomes step_limit when maxSteps is set. step_limit now also requires the last settled step to still have client tool calls. The answer is recorded as end_turn. Regression: records a hosted-search answer as end_turn when the provider finish reason is tool-calls. Client-tool step-limit behavior is unchanged.

Earlier threads (carrier persistence, failed-search isError, per-stream carrier scope, unrecognized-wire drop, replay-reference options, deleted bare allowBareTypes branch) remain on this head.

Checks on this head: core/storage/runtime build; Biome clean on the touched files; hosted-search end_turn + client step_limit; DeepSeek replay/switch tests 4/4; extension suite 16/16; model-adapter 40/40. Product routing is still implemented: false (#3689).

Hosted CI on the previous head was action_required (fork workflow approval), so there is still no green required check until a maintainer approves the workflow. Would appreciate another look. Thanks!

@cursor
cursor Bot force-pushed the feat/deepseek-open-responses-codecs branch 2 times, most recently from c44cfdf to fa1d82d Compare September 23, 2026 10:23
@Lxr-max

Lxr-max commented Sep 23, 2026

Copy link
Copy Markdown
Author

@Astro-Han @hqhq1025 — re-review request. Same PR, head fa1d82da7 on Lxr-max:feat/deepseek-open-responses-codecs, rebased onto current main (0cb4fc32b). No overlapping files with the 11 intervening main commits.

This follow-up

  • Remaining cheap nits: usesDeepSeekOpenResponsesExtensions now takes ProviderType; documented the tool-result providerExecuted assertion (the extension content-part union omits that flag)
  • Replied on the P3 replayReference thread (returns undefined unless an extension {id, itemId} reference was projected)

Earlier threads remain on this head: durable carrier, failed-search isError, per-stream carrier scope, unrecognized-wire drop, deleted bare allowBareTypes branch, hosted-search end_turn vs client step_limit.

Checks on this head

  • npm --workspace @maka/{core,storage,runtime} run build
  • Biome clean on the touched files
  • synthesizes a DeepSeek hosted tool call when replay metadata is missing fails under Alibaba-style drop expectations and passes with synthesis (web_search_call present, result dropped, grounded text retained)
  • DeepSeek replay/switch + Alibaba mixed-tool + hosted-search end_turn — 5 pass
  • extension suite 16/16; model-adapter 41/41

Product routing is still implemented: false (#3689). Hosted CI on a fork PR still needs maintainer workflow approval. Would appreciate another look. Thanks!

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

Reviewed exact head fa1d82da7565652ec99996d06fc95908ba7d3e0a.

The new DeepSeek Open Responses codec, per-stream carrier isolation, cross-wire degradation, and hosted-search step-limit handling are otherwise coherent in the inspected paths. One replay-identity bug remains, so this head is not ready to merge.

Validation completed on Node 22.22.1: npm ci, npm run build:test, full workspace npm run typecheck, 301 focused Runtime tests, Biome lint/format checks for all changed files, ASF header audit, and git diff --check. The merge tree against current main (c7d205a42dc32073edbb74f0954489e9388568c1) is clean. GitHub reports no hosted status checks for this head. I could not validate the live DeepSeek endpoint without provider credentials.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

const call =
item.kind === 'tool_call'
? item
: items.find((entry) => entry.kind === 'tool_call' && entry.toolCallId === item.toolCallId);

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.

[P2] Pair replay items with the invocation-scoped identity

These searches match only toolCallId, but the history authority immediately downstream defines a tool exchange by invocationId + toolCallId and explicitly permits a provider-local id to be reused in a later invocation (model-history.ts:409-413, 424, 470, 505-506). When an older DeepSeek hosted-search exchange and a later valid Anthropic hosted-search exchange reuse the same id, the later call is checked against the older DeepSeek result and the later result against the older DeepSeek call, so dropUnsupportedReplayItems() removes the entire valid Anthropic pair. A current-head probe retained the pair when the ids differed, but returned [] for the same two exchanges when both used search-reused. Please pair on invocationId as well (or reuse the chronology authority's paired exchange) and add a cross-invocation reused-id regression.

@Lxr-max

Lxr-max commented Sep 23, 2026

Copy link
Copy Markdown
Author

Addressed the remaining pairing note: #5350 (comment)

dropUnsupportedReplayItems and canReplayProviderNative now judge a provider-executed item against the exchange buildRuntimeEventReplayTimeline already formed. That chronology keys the pair by invocation id plus the provider-local tool call id, so a later invocation can reuse an id without borrowing the earlier call or result.

Regression: keeps a later Anthropic hosted search when an older DeepSeek exchange reused its id in packages/runtime/src/__tests__/deepseek-open-responses-extensions.test.ts.

  • Distinct ids (search-deepseek / search-anthropic) stay on the Anthropic pair.
  • Shared id search-reused returned [] before the change (the later Anthropic call was checked against the older DeepSeek result). After the change it keeps invocation-anthropic:tool_call:search-reused and invocation-anthropic:tool_result:search-reused.

Published on feat/deepseek-open-responses-codecs (this PR head is 8af2b4118):

  • bf0346808 restores packages/runtime/src/ai-sdk-message-projection.ts, blob d7ac32578cfa5dc91b862c94ab52646aee12e29c
  • 8af2b4118 adds the regression, blob 94fc9f845919a9ded4114c264004b5783fa51854

DeepSeek hosted-search product routing is still { adapter: 'openai-responses', implemented: false } for #3689. packages/core/src/model-web-search.ts was not edited.

Local checks against that tree, before this push. I did not run the full workspace npm test suite, and this comment does not claim CI:

  • npm --workspace @maka/core run build
  • npm --workspace @maka/storage run build
  • npm --workspace @maka/runtime run build
  • biome check on the two touched files, clean
  • deepseek-open-responses-extensions.test.js — 17 pass. The new case failed first with actual [] against the expected Anthropic search-reused pair, then passed after the pairing change. The distinct-id assertion passed on both runs.
  • model-adapter.test.js — 41 pass
  • model-history-timeline.test.js — 7 pass
  • ai-sdk-backend name filter hosted search|hosted-search|provider-executed web search|provider-executed CC web search|degrading a hosted — 6 pass: replays CC web search encrypted; replays web search before grounded text; drops DeepSeek hosted search onto deepseek-chat; drops DeepSeek hosted search onto Anthropic web_search; keeps unrelated client tool history when degrading a hosted tool pair; records a hosted-search answer as end_turn when the finish reason is tool-calls

A rebase onto current apache/maka main (9082cf144) is clean locally: apache/main is an ancestor of 4707f1b6b, and the six main commits do not touch this PR's files. git push --force-with-lease of that history was rejected with Invalid username or token, so the published head stays on the previous base 0cb4fc32b plus these commits.

History note: a6dbb2f52, 756a2c97e, and 4aa0ec33e wrote incomplete contents for ai-sdk-message-projection.ts. bf0346808 replaces that file with the full source whose blob is above. Please review the tip (8af2b4118), not those three commits.

@Lxr-max

Lxr-max commented Sep 23, 2026

Copy link
Copy Markdown
Author

Rebase publish is still blocked. The linear rebase is ready locally and was not pushed.

  • Local rebased head: 4707f1b6ba45232f505fa22a3932c3c586668d2e
  • Current apache/maka main (re-fetched): 9082cf144bc1d7ff912fc5a4f5fd0e0abaf559d7. It is an ancestor of the local head. The branch is 12 commits ahead of that main, and the replay-identity fix plus the earlier DeepSeek Open Responses commits are on it.
  • Published PR head remains 8af2b41188254870993e774168f0486871da82af
  • Published PR base remains 0cb4fc32bdff3587bd5cc609fbe0eb28efa4233f

git push --force-with-lease=refs/heads/feat/deepseek-open-responses-codecs:8af2b41188254870993e774168f0486871da82af origin HEAD:feat/deepseek-open-responses-codecs failed again:

remote: Invalid username or token. Password authentication is not supported for Git operations.
fatal: Authentication failed for 'https://github.com/Lxr-max/maka/'

Exit code 128. The only Git credential in this environment is the Cursor-managed GitHub App token. GET /user with that token returns HTTP 403: This GitHub App installation is currently suspended. gh auth status reports the same token as invalid for account cursor. No other GitHub token is available here, and none was created.

SSH push of the same lease, with the HTTPS rewrite disabled, also failed:

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Focused checks re-run on local 4707f1b6b (not CI, not the full workspace npm test):

  • npm --workspace @maka/core run build
  • npm --workspace @maka/storage run build
  • npm --workspace @maka/runtime run build
  • biome check on packages/runtime/src/ai-sdk-message-projection.ts and packages/runtime/src/__tests__/deepseek-open-responses-extensions.test.ts — checked 2 files, clean
  • deepseek-open-responses-extensions.test.js — 17 pass
  • model-adapter.test.js — 41 pass
  • model-history-timeline.test.js — 7 pass
  • ai-sdk-backend hosted-search name filter — 6 pass

DeepSeek hosted-search product routing on this commit is still { adapter: 'openai-responses', implemented: false } for #3689.

@Astro-Han

Copy link
Copy Markdown
Contributor

Working on new round of reviewing! Would you like to join wechat group so we can communicate more timely? Cheers!

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

Reviewed exact head 8af2b41188254870993e774168f0486871da82af.

This follow-up resolves the previously reported replay-identity bug. AiSdkMessageProjection now derives call/result associations from the existing replay chronology authority, which pairs by invocationId + toolCallId and by durable occurrence. Both the native-replay gate and per-item degradation therefore evaluate one coherent exchange instead of borrowing a same-id call or result from another invocation. The new regression constructs persisted DeepSeek and Anthropic hosted-search exchanges that reuse the same provider-local id and confirms that only the unsupported DeepSeek pair is dropped. I found no remaining P0-P3 issue in the current diff.

Validation on Node 24.18.1: clean npm ci; npm run build:test; full workspace typecheck; Runtime 3535 passed / 13 skipped; 309 focused Runtime tests; full Biome lint and format checks; ASF header audit; and git diff --check. The merge tree with current main (9082cf144bc1d7ff912fc5a4f5fd0e0abaf559d7) is clean; a synthetic merge passed build:test and the same 309 focused tests. The hosted test check is successful. I did not call the live DeepSeek endpoint.

No technical blocker found on this head. Final merge readiness remains a human decision and depends on the live repository gates.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

Register DeepSeek hosted web_search codecs on createOpenResponses. The
runtime already pins @ai-sdk/open-responses@2.0.44; until vercel/ai#19939
ships allowBareTypes, map only DeepSeek's documented bare discriminators
at the network boundary. Hosted search stays fail-closed.

Generated-by: Cursor Cloud Agent (Grok 4.6)
…tatus

Merge the Open Responses custom replay carrier onto provider-executed
tool-call metadata so the opaque web_search_call item survives RuntimeEvent
persistence, reconstruct it on replay, and mark failed hosted searches as
errors. Keep product hosted-search routing fail-closed.

Generated-by: Cursor Cloud Agent (Grok 4.6)
Keep Open Responses extension-replay pending items on the per-request
stream in toModelStreamResult instead of the session-wide ModelAdapter, and
clear the map on success, error, and abort so concurrent send() calls with
the same provider item id cannot mix opaque carriers.

Generated-by: Cursor Cloud Agent (Grok 4.6)
Drop the unused outgoing event map, return undefined from the fetch-layer
rewrite when no allowlisted discriminator changed, and document generate
vs stream result parity plus the allowBareTypes parser assumption.

Generated-by: Cursor Cloud Agent (Grok 4.6)
A no-op discriminator wrap must not hand the upstream fetch an
ArrayBuffer; request mocks and JSON.parse(String(body)) still expect
the original text payload.

Generated-by: Cursor Cloud Agent (Grok 4.6)
Gate provider-executed WebSearch emission on the target adapter recognizing
the exchange. Chat Completions no longer emit dangling tool_calls, and
Anthropic no longer coerces DeepSeek search into server_tool_use. Also
return undefined from replay-reference projection unless an extension
reference was produced, delete the unreachable allowBareTypes branch, and
pin SDK ${type}:${id} replay dedup.

Generated-by: Cursor Cloud Agent (Grok 4.6)
Provider-executed calls often carry no origin metadata; the matching
tool-result does. Gate both items from the paired exchange so Anthropic
hosted search still replays when only the result is schema-shaped.

Generated-by: Cursor Cloud Agent (Grok 4.6)
Open Responses reports finishReason tool-calls for a provider-executed
web search that already includes the final answer. When maxSteps is set,
that turn was recorded as step_limit and failed. Only spend the step
limit when the last settled step still has client tool calls to continue.

Generated-by: Cursor Cloud Agent (Grok 4.7)

Co-authored-by: Xuanrui Li <xuanrui.li@se24.qmul.ac.uk>
openai-chat already covers openai-chat-plaintext replay, so the extra
kind comparison is unreachable under ResolvedModelRuntime. The hosted
search step-limit regression casts provider-executed tool results the
same way as the existing stream fixtures.

Generated-by: Cursor Cloud Agent (Grok 4.7)
Accept ProviderType instead of string, and comment the tool-result
providerExecuted assertion so it is not read as a type escape hatch.

Generated-by: Cursor Cloud Agent (Grok 4.6)

Co-authored-by: Xuanrui Li <xuanrui.li@se24.qmul.ac.uk>
dropUnsupportedReplayItems matched a provider-executed exchange on
toolCallId alone. A later Anthropic hosted search that reused an older
DeepSeek id was judged against that earlier exchange and dropped.
Pair through the chronology authority (invocationId + toolCallId).

Generated-by: Cursor Cloud Agent (Grok 4.7)
dropUnsupportedReplayItems matched a provider-executed exchange on
toolCallId alone. A later Anthropic hosted search that reused an older
DeepSeek id was judged against that earlier exchange and dropped.
Pair through the chronology authority (invocationId + toolCallId).

Generated-by: Cursor Cloud Agent (Grok 4.7)
dropUnsupportedReplayItems matched a provider-executed exchange on
toolCallId alone. A later Anthropic hosted search that reused an older
DeepSeek id was judged against that earlier exchange and dropped.
Pair through the chronology authority (invocationId + toolCallId).

Generated-by: Cursor Cloud Agent (Grok 4.7)
A later Anthropic hosted search that reuses an older DeepSeek tool call id
must stay paired with its own invocation. The regression fails with an empty
replay when both exchanges use search-reused and passes once pairing uses
invocationId plus toolCallId.

Generated-by: Cursor Cloud Agent (Grok 4.7)
@Lxr-max
Lxr-max force-pushed the feat/deepseek-open-responses-codecs branch from 8af2b41 to e5191c3 Compare September 24, 2026 13:20
@Lxr-max

Lxr-max commented Sep 24, 2026

Copy link
Copy Markdown
Author

Published the rebase from a local machine (Cursor GitHub App is still suspended in cloud agents, so force-push went through my personal gh session).

  • New head: e5191c3c6e1dc7afa24c4fe521cdc8a01116fc80
  • Base: current apache/maka main acaa29e4091812f29149fd7ed3800bc65326b7de (ancestor of head)
  • Kept DeepSeek Open Responses codecs + hosted-search replay-identity pairing (invocationId + tool call id) and the cross-invocation regression test
  • Resolved one rebase conflict in packages/runtime/src/model-factory.ts imports (runtimeProviderName is gone on main; Open Responses still uses connection.providerType)

Note: tip history still contains earlier API-only intermediate commits (placeholder / truncated projection restore). Net tree on the tip is complete; happy to squash those if reviewers prefer a cleaner stack.

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

Reviewed exact head e5191c3c6e1dc7afa24c4fe521cdc8a01116fc80.

This rebased head still contains the invocation-scoped replay fix, but it does not pass the repository build or formatting gates. I found two independent rebase regressions, included as inline P1 comments.

Validation attempted with Node 24.18.1 after clean npm ci: npm run build:test fails in the Runtime TypeScript build; full Biome lint and format checks fail while reading model-factory.ts; ASF headers and git diff --check pass. The exact base acaa29e4091812f29149fd7ed3800bc65326b7de has valid UTF-8 and the same workspace built successfully during the adjacent current-base review. Current main is f1f259b67119fd355b7f7cbbf9d3c359240ba05e; the PR is 16 ahead / 1 behind and its merge tree is clean. GitHub reports no hosted checks for this head.

Not ready to merge until both inline findings are fixed and the blocked Runtime regression suite can run.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

settings: { enabled: true, defaultProvider: 'model' },
connection: {
slug: 'anthropic-compatible',
providerType: 'anthropic-compatible',

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.

[P1] Use a current ProviderType in this rebased fixture

anthropic-compatible no longer exists in the provider registry after the custom-connection unification on the new base. On this exact head, clean npm run build:test stops here with TS2322 before the Runtime tests can execute. The current representation is a custom connection with apiProtocol: "anthropic-messages"; please update this fixture (and preserve the intended routing assertion) so the package compiles again.

}
// Anthropic-protocol: effort enum models send `effort`; toggle/budget
// models send `thinking.disabled` for off. No budget-token mapping — the
// models send `thinking.disabled` for off. No budget-token mapping �?the

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.

[P1] Restore valid UTF-8 in the rebased source

This comment contains the invalid byte sequence e2 80 3f instead of a complete UTF-8 em dash; the file has seven such sequences. On this exact head, both npm run lint and npm run format:check stop with Biome internalError/io: stream did not contain valid UTF-8. The exact base passes an UTF-8 decode check. Please replace all corrupted sequences in this file, not only the one on this line.

@Astro-Han

Copy link
Copy Markdown
Contributor

Thank you for this contribution, and sorry to close it on process grounds rather than on its merits.

The PR's generative-tooling disclosure says Grok was used. SpaceXAI recently changed Grok's Acceptable Use Policy to bar using Grok or its output to develop, or assist anyone in developing, products or services that compete with SpaceXAI, directly or indirectly. That is a field-of-use restriction, and under the ASF's draft generative tooling criteria it would likely place Grok in Category X. It is being discussed on legal-discuss now, and until that is settled the project has been asked not to accept Grok-generated contributions. Code merged here ships under the Apache License to everyone, so the restriction matters even though Maka itself is not the concern.

This is not a judgement on the change itself. If you would like to continue, please re-create it with a different tool (or by hand) and open a new PR, noting the tool in the disclosure as usual. We will review it normally.

Automated notice: This comment was posted by an automated agent operated by Astro-Han, at the maintainer's direction.

@Astro-Han Astro-Han closed this Sep 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/XXL Over 2500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(runtime): adopt Open Responses extension codecs for DeepSeek tools

3 participants