The taskdoubao adaptor expected snake_case JSON keys (video_url,
completion_tokens, total_tokens, framespersecond, service_tier,
created_at, updated_at) but Volcengine returns camelCase (videoUrl,
completionTokens, totalTokens, framesPerSecond, serviceTier,
createdAt, updatedAt). As a result the video URL was never parsed:
successful tasks fell back to the platform proxy URL
(BuildProxyURL) as result_url, which broke the video proxy in
containerized deployments (localhost:port not reachable inside the
container) and zeroed the usage tokens used for billing.
Align the responseTask JSON tags with the real Volcengine response
shape and add a regression test with the exact production payload.
Co-Authored-By: ZCode <noreply@anthropic.com>
The native /api/v3/contents/generations/tasks route was restricted to
the seedance asset channel family (58/60/61); official Volcengine Ark
channels (DoubaoVideo, type 54) could only be reached via the
standardized /v1/video/generations path. Allow type 54 on the native
route in both the distributor and the task retry channel selection,
while keeping it out of the seedance asset binding system.
The taskdoubao adaptor now reuses a pre-parsed task request from the
context (native path) instead of re-parsing the body as TaskSubmitReq,
whose prompt validation would reject the Volcengine-native format.
When req.Prompt is empty (native path), content text items from
metadata are preserved instead of being replaced with an empty prompt;
the standardized path behavior (prompt replaces metadata text) is
unchanged and covered by existing tests.
Co-Authored-By: ZCode <noreply@anthropic.com>
Add KlingAiping usage-token settlement from upstream final_unit_deduction and duration fallback handling.
Normalize model endpoint config persistence and convert model pricing values between stored USD and display currency in the editor.
Co-Authored-By: Codex <noreply@anthropic.com>
Use adaptive thinking for Claude requests and rewrite passthrough bodies that still contain the legacy enabled type.
Co-Authored-By: Codex <noreply@anthropic.com>
gpt-5.4 returns `arguments` as a JSON object for some tools (e.g.
apply_patch, tool_search), but ResponsesOutput.Arguments was typed as
string, causing json.Unmarshal to fail on every such SSE event.
The failure silently dropped all output_item events and the
response.completed event from the forwarded stream, so:
- the client never received tool call content
- usage/token counts could not be extracted (billed as 0)
- client reported "stream closed before response.completed"
Fix: change Arguments to json.RawMessage and add GetArguments() which
normalises both forms to a plain string (unescapes JSON strings,
returns raw bytes for objects).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DoApiRequest previously called io.ReadAll on every request body to apply
passthrough model mapping, even when the feature was disabled. This
caused unnecessary memory pressure for large request bodies (long
conversations, multipart image uploads).
Split the guard logic into needsPassthroughModelMapping() so that
ReadAll is only called when all conditions are met (feature enabled +
passthrough mode + model mapped). Non-passthrough requests now pass
the original io.Reader directly to http.NewRequest without buffering.
Rewrite tests to verify combined guard + modify behavior.