Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📜 Recent review details⏰ Context from checks skipped due to timeout. (1)
🧰 Additional context used📓 Path-based instructions (2)**/*.go📄 CodeRabbit inference engine (CLAUDE.md)
Files:
relay/channel/**/*.go📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🔇 Additional comments (10)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR adds a generic task-billing estimator, expands task submit requests with top-level Seedance fields, updates request-body syncing and relay billing wiring, and extends the Doubao adaptor to validate and map the new fields. ChangesTask billing and Seedance field support
Sequence Diagram(s)sequenceDiagram
participant Client
participant RelayTaskSubmit
participant taskcommon.EstimateGenericTaskBilling
participant task_billing_setting
Client->>RelayTaskSubmit: submit task request
RelayTaskSubmit->>taskcommon.EstimateGenericTaskBilling: estimate billing
taskcommon.EstimateGenericTaskBilling->>task_billing_setting: match rate card and calculate
task_billing_setting-->>taskcommon.EstimateGenericTaskBilling: billing result
taskcommon.EstimateGenericTaskBilling-->>RelayTaskSubmit: quota and billing fields
RelayTaskSubmit-->>Client: continue task submission
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
relay/channel/task/taskcommon/request_body.go (1)
73-89: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueBody is stored before JSON unmarshal is confirmed to succeed.
StoreTaskSubmitRequestBody(line 77) runs right after the loosecommon.IsJsonObjectcheck but beforecommon.Unmarshal(lines 79-81) actually validates the payload. IfIsJsonObjectonly checks brace framing rather than full JSON validity, a structurally-broken body can still be stored in the context before the function returns an error. Given the current caller (relay_task.go) aborts the whole request on error, this has no observable effect today, but it's fragile: any future caller that tolerates the error (e.g. retries reusing the samegin.Context) would carry over a stale/invalid stored body into billing (EstimateGenericTaskBillingsilently swallows unmarshal errors on that stored body). Consider moving the store call after theUnmarshalsucceeds.♻️ Suggested reordering
func SyncTaskRequestContext(c *gin.Context, data []byte) error { if c == nil || c.Request == nil || len(bytes.TrimSpace(data)) == 0 || !common.IsJsonObject(string(data)) { return nil } - relaycommon.StoreTaskSubmitRequestBody(c, data) var raw map[string]any if err := common.Unmarshal(data, &raw); err != nil { return err } + relaycommon.StoreTaskSubmitRequestBody(c, data) req := relaycommon.TaskSubmitReq{}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@relay/channel/task/taskcommon/request_body.go` around lines 73 - 89, In SyncTaskRequestContext, the task body is being stored in the gin.Context before common.Unmarshal has validated that the payload is actually valid JSON, which can leave stale or invalid data behind. Move the relaycommon.StoreTaskSubmitRequestBody call to after the common.Unmarshal(data, &raw) check succeeds, and keep the mergeTaskSubmitReq / c.Set("task_request", req) flow unchanged so only confirmed-valid bodies are persisted.relay/channel/task/doubao/adaptor.go (1)
415-460: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPreserve image items when top-level content is present
convertToRequestPayloadappendsreq.Imagesfirst, thenapplyTopLevelSeedanceOptionsreplacesr.Contentwheneverreq.Contentis non-empty.TaskSubmitReqallowsimagesandcontentto coexist, so this drops user-provided image inputs. Merge the top-level content intor.Contentinstead of overwriting it.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@relay/channel/task/doubao/adaptor.go` around lines 415 - 460, `convertToRequestPayload` is losing image inputs because `applyTopLevelSeedanceOptions` replaces `r.Content` when `req.Content` is present. Update `applyTopLevelSeedanceOptions` (and its `topLevelContentItems` flow) so it merges the parsed top-level content into the existing `requestPayload.Content` instead of overwriting it, preserving any `image_url` items added from `req.Images`. Ensure the final `r.Content` keeps both images and text items when `TaskSubmitReq` provides both.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@relay/channel/task/doubao/adaptor.go`:
- Around line 549-556: The helper firstNonEmptyString in adaptor.go checks
emptiness with strings.TrimSpace but returns the original untrimmed value, so
callers like the r.Ratio assignment can receive padded input. Update
firstNonEmptyString to return the trimmed string for the first non-empty value,
keeping the existing empty check behavior but ensuring consistent normalized
output.
In `@relay/channel/task/taskcommon/path_config_test.go`:
- Around line 110-145: The test duplicates the same JSON payload in both the
task context and the SyncTaskRequestContext input, but the context body is not
used by SyncTaskRequestContext. Simplify
TestSyncTaskRequestContextReadsOfficialSeedanceFields by defining the JSON once
and reusing it for newJSONTaskContext and SyncTaskRequestContext, or by removing
the unused context payload entirely; keep the assertions on
relaycommon.GetTaskRequest and the request fields unchanged.
In `@relay/channel/task/taskcommon/request_body.go`:
- Around line 126-138: The request body parsing in the task common request
handling has a redundant duplicate mapping for generate_audio into both
req.WithAudio and req.GenerateAudio. Update the parsing logic in the request
body decoder to treat req.GenerateAudio as the canonical target and remove the
extra generate_audio assignment to req.WithAudio, keeping only the field used by
the Doubao adaptor’s fallback path.
In `@relay/common/relay_info.go`:
- Around line 699-722: The request struct in relay_info.go has several newly
added optional scalar fields defined as plain strings, which loses the
distinction between an omitted value and an explicitly provided empty string.
Change Ratio, CallbackURL, ServiceTier, and SafetyIdentifier in the relevant
request type to pointer strings with omitempty, then update the related
merge/copy path (including mergeTaskSubmitReq and any copyString helper usage)
and the Doubao adaptor checks so nil vs empty is handled correctly when
forwarding options like applyTopLevelSeedanceOptions.
---
Outside diff comments:
In `@relay/channel/task/doubao/adaptor.go`:
- Around line 415-460: `convertToRequestPayload` is losing image inputs because
`applyTopLevelSeedanceOptions` replaces `r.Content` when `req.Content` is
present. Update `applyTopLevelSeedanceOptions` (and its `topLevelContentItems`
flow) so it merges the parsed top-level content into the existing
`requestPayload.Content` instead of overwriting it, preserving any `image_url`
items added from `req.Images`. Ensure the final `r.Content` keeps both images
and text items when `TaskSubmitReq` provides both.
In `@relay/channel/task/taskcommon/request_body.go`:
- Around line 73-89: In SyncTaskRequestContext, the task body is being stored in
the gin.Context before common.Unmarshal has validated that the payload is
actually valid JSON, which can leave stale or invalid data behind. Move the
relaycommon.StoreTaskSubmitRequestBody call to after the common.Unmarshal(data,
&raw) check succeeds, and keep the mergeTaskSubmitReq / c.Set("task_request",
req) flow unchanged so only confirmed-valid bodies are persisted.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0fa69fa0-4b3f-4532-b4a2-5309de3eeca5
📒 Files selected for processing (9)
relay/channel/task/doubao/adaptor.gorelay/channel/task/doubao/adaptor_billing_test.gorelay/channel/task/taskcommon/generic_billing.gorelay/channel/task/taskcommon/generic_billing_test.gorelay/channel/task/taskcommon/path_config_test.gorelay/channel/task/taskcommon/request_body.gorelay/common/relay_info.gorelay/relay_task.gorelay/relay_task_test.go
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.go: All JSON marshal/unmarshal operations in Go business code must use the wrappers incommon/json.go(common.Marshal,common.Unmarshal,common.UnmarshalJsonStr,common.DecodeJson,common.GetJsonType) instead of directly callingencoding/json;encoding/jsontypes likejson.RawMessageandjson.Numbermay still be used as types.
All database code must be compatible with SQLite, MySQL 5.7.8+, and PostgreSQL 9.6+ simultaneously: prefer GORM methods over raw SQL, avoid directAUTO_INCREMENT/SERIAL, use cross-DB quoting/boolean helpers when raw SQL is unavoidable, avoid DB-specific functions/operators without fallbacks, and ensure migrations work on all three databases.
For request structs parsed from client JSON and later re-marshaled to upstream providers, especially in relay/convert paths, optional scalar fields must use pointer types withomitemptyso explicit zero/false values are preserved and omitted-only fields remainnil.
**/*.go: Usecommon.Marshal,common.Unmarshal,common.UnmarshalJsonStr,common.DecodeJson, andcommon.GetJsonTypefromcommon/json.gofor all JSON marshal/unmarshal operations; do not directly callencoding/jsonin business code.
Keep all database code fully compatible with SQLite, MySQL >= 5.7.8, and PostgreSQL >= 9.6; prefer GORM abstractions, avoid raw SQL unless cross-DB-safe, and use the provided DB-specific helpers/flags for quoting, booleans, and branching.
For request structs parsed from client JSON and re-marshaled to upstream providers, especially in relay/convert paths, use pointer types withomitemptyfor optional scalar fields so explicit zero/false values are preserved.
Files:
relay/channel/task/taskcommon/path_config_test.gorelay/common/relay_info.gorelay/relay_task.gorelay/channel/task/taskcommon/generic_billing_test.gorelay/channel/task/taskcommon/request_body.gorelay/relay_task_test.gorelay/channel/task/doubao/adaptor_billing_test.gorelay/channel/task/taskcommon/generic_billing.gorelay/channel/task/doubao/adaptor.go
relay/channel/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
When implementing a new relay channel, confirm whether the provider supports
StreamOptions; if it does, add that channel tostreamSupportedChannels.When implementing a new channel, confirm whether the provider supports
StreamOptions; if it does, add the channel tostreamSupportedChannels.
Files:
relay/channel/task/taskcommon/path_config_test.gorelay/channel/task/taskcommon/generic_billing_test.gorelay/channel/task/taskcommon/request_body.gorelay/channel/task/doubao/adaptor_billing_test.gorelay/channel/task/taskcommon/generic_billing.gorelay/channel/task/doubao/adaptor.go
🔇 Additional comments (15)
relay/channel/task/taskcommon/generic_billing.go (2)
14-60: LGTM!Also applies to: 70-436
61-69: 🎯 Functional Correctness
UpstreamModelNameis promoted from*ChannelMetaThe guard is fine here:RelayInfoembeds*ChannelMeta, andUpstreamModelNamelives onChannelMeta, so this reads the intended field.> Likely an incorrect or invalid review comment.relay/channel/task/taskcommon/generic_billing_test.go (1)
20-284: LGTM!relay/relay_task.go (1)
201-208: LGTM!Also applies to: 282-320
relay/relay_task_test.go (1)
10-46: LGTM!Also applies to: 93-190
relay/common/relay_info.go (1)
733-778: LGTM!relay/channel/task/taskcommon/request_body.go (2)
110-125: LGTM!Also applies to: 129-176
298-313: 🎯 Functional CorrectnessNo change needed for zero values
copyIntPtrandcopyBoolPtralready preserve0andfalseby decoding the raw map value directly, so these fields remain non-nil when present.> Likely an incorrect or invalid review comment.relay/channel/task/taskcommon/path_config_test.go (1)
136-144: LGTM!relay/channel/task/doubao/adaptor.go (2)
145-158: 🎯 Functional Correctness | ⚡ Quick winVerify omission of
reference_imagesnormalization in the JSON branch.The pass-through branch (Lines 134-136) maps
req.ReferenceImagesintoreq.Imageswhenimagesis empty, but this standard JSON branch only normalizesreq.Image(Lines 155-157). If a JSON request supplies onlyreference_images, those inputs won't be surfaced viareq.Images. Confirm this divergence is intentional.
226-252: LGTM!relay/channel/task/doubao/adaptor_billing_test.go (4)
40-47: LGTM!
228-294: LGTM!
326-409: LGTM!
466-493: LGTM!
Important
📝 变更描述 / Description
修复视频任务参数化计费的两个边界问题。
本次调整让 multipart 视频任务在经过
Param Override改写后,也会把最终上游 JSON 请求体同步到计费上下文,避免分辨率、时长、音频或模型等字段按改写前请求计费。同时修正通用任务计费中的图片数量统计,避免顶层image/images已从最终请求体计数后,又从同步后的TaskSubmitReq镜像字段重复累加。这些改动保证预扣费依据与实际上游请求保持一致,也让使用
image_count作为匹配条件或计量字段的 rate card 不会被重复计数放大费用。🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
✅ 提交前检查项 / Checklist
Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。📸 运行证明 / Proof of Work
本地验证通过: