Skip to content

feat: task reconsume log add taskId and ratio - #2633

Closed
feitianbubu wants to merge 4956 commits into
QuantumNous:mainfrom
feitianbubu:pr/03a09ae83373eead3ee6fdd7da3a60be40452e3f
Closed

feat: task reconsume log add taskId and ratio#2633
feitianbubu wants to merge 4956 commits into
QuantumNous:mainfrom
feitianbubu:pr/03a09ae83373eead3ee6fdd7da3a60be40452e3f

Conversation

@feitianbubu

@feitianbubu feitianbubu commented Jan 10, 2026

Copy link
Copy Markdown
Member

优化视频补扣费和退款日志, 增加taskId和倍率等信息

Summary by CodeRabbit

  • Bug Fixes

    • Improved logging for task quota adjustments to include TaskID and clearer indication of consume vs. refund events.
  • New Features

    • Logs now capture richer context (model/group ratios, total tokens, pre‑consumed and actual quota) for better auditability of quota changes.

✏️ Tip: You can customize this high-level summary in your review settings.

Calcium-Ion and others added 30 commits November 25, 2025 15:31
…pro-image-preview-oai

OAI生图接口支持gemini 3 pro image preview
…ageConfig

fix: gemini image correct generationConfig
…ith i18n

- Add SSEViewer component for interactive SSE message inspection
  * Display SSE data stream with collapsible panels
  * Show parsed JSON with syntax highlighting
  * Display key information badges (content, tokens, finish reason)
  * Support copy individual or all SSE messages
  * Show error messages with detailed information

- Support Ctrl+V to paste images in chat input
  * Enable image paste in CustomInputRender component
  * Auto-detect and add pasted images to image list
  * Show toast notifications for paste results

- Add complete i18n support for 6 languages
  * Chinese (zh): Complete translations
  * English (en): Complete translations
  * Japanese (ja): Add 28 new translations
  * French (fr): Add 28 new translations
  * Russian (ru): Add 28 new translations
  * Vietnamese (vi): Add 32 new translations

- Update .gitignore to exclude data directory
…-i2v

Gemini Veo3.1[AI Studio]增加图生视频支持
Ensure image file is closed using defer after opening.
…edit

Gemini Image系列支持图像编辑
…d-oai

feat: 视频下载和界面预览统一使用OAI标准接口
…-err-code

fix(aws): extract HTTP status code from AWS SDK errors
…na-err

fix: nano-banana not compatible imageSize
…nce-playground-debugging

feat(playground): enhance SSE debugging and add image paste support with i18n
fix: nano banana pro 4k(StreamScannerMaxBufferMB env)
Seefs and others added 25 commits January 3, 2026 12:37
…QuantumNous#2556)

* fix: fix model deployment style issues, lint problems, and i18n gaps.

* fix: adjust the key not to be displayed on the frontend, tested via the backend.

* fix: adjust the sidebar configuration logic to use the default configuration items if they are not defined.
fix: 修复 gemini 文件类型不支持 image/jpg
…figuration && the AWS calling side did not apply the relay timeout.
fix: fix the proxyURL is empty, not using the default HTTP client configuration && the AWS calling side did not apply the relay timeout.
fix: add tips for model management and channel testing
问题描述:
- 使用 auto 分组的令牌调用 /v1/videos 等 Task 接口时,虽然任务能成功创建,
  但使用日志不显示记录,且不会扣费

根本原因:
- Distribute 中间件在选择渠道后,会将实际选中的分组存储在 ContextKeyAutoGroup 中
- 但 RelayTaskSubmit 函数没有从 context 中读取这个值来更新 info.UsingGroup
- 导致 info.UsingGroup 始终是 "auto" 而不是实际选中的分组(如 "sora2逆")
- 当 auto 分组的倍率配置为 0 时,quota 计算结果为 0
- 日志记录条件 "if quota != 0" 不满足,导致日志不记录、不扣费

修复方案:
- 在 RelayTaskSubmit 函数中计算分组倍率之前,添加从 ContextKeyAutoGroup
  获取实际分组的逻辑
- 使用安全的类型断言,避免潜在的 panic 风险

影响范围:
- 仅影响 Task Relay 流程(/v1/videos, /suno, /kling 等接口)
- 不影响使用具体分组令牌的调用
- 不影响其他 Relay 类型(chat/completions 等已有类似处理逻辑)
…task-logging

fix(task): 修复使用 auto 分组时 Task Relay 不记录日志和不扣费的问题
fix: 设置默认max req body 为128MB
Use the native Gemini Models API (/v1beta/models) instead of the OpenAI-compatible
path when listing models for Gemini channels, improving compatibility with
third-party Gemini-format providers that don't implement OpenAI routes.

- Add paginated model listing with timeout and optional proxy support
- Select an enabled key for multi-key Gemini channels
…etchModels

fix: remove Minimax from FETCHABLE channels
…tchModels

fix(gemini): fetch model list via native v1beta/models endpoint
@coderabbitai

ghost commented Jan 10, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Enhanced logging for video task quota reconciliation: two log calls in controller/task_video.go now include TaskID and invoke a new model.RecordReConsumeLog that records task metadata (model/group ratios, token counts, pre/actual quota) and persists a TypeConsume log.

Changes

Cohort / File(s) Summary
Video Task Logging Updates
controller/task_video.go
Replaced two RecordLog calls with RecordReConsumeLog(...); log messages now prefix 任务成功 [TaskID] ... for both "补扣费" and "退还" branches and pass richer arguments (task, modelRatio, finalGroupRatio, totalTokens, preConsumedQuota, actualQuota, content).
New Re-consume Log Function
model/log.go
Added RecordReConsumeLog(task *Task, modelRatio float64, groupRatio float64, totalTokens int, preConsumedQuota int, actualQuota int, content string) which builds a TypeConsume Log, computes quotaDelta, includes task-related metadata (ModelName, tokens, ratios), looks up username, sets timestamp, persists via LOG_DB, and optionally exports data asynchronously.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • seefs001
  • xyfacai

Poem

🐰 I hopped through logs with nimble feet,
TaskID shining, tidy and neat,
Ratios, tokens in a cheerful tune,
Quota balanced by the light of the moon,
Hooray — the ledger hums in sync! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding taskId and ratio information to the task reconsume logging functionality across both log functions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

ghost 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controller/task_video.go (1)

181-233: Critical: quota adjustment can be applied twice if task.Update() fails after charging/refunding.

You adjust user quota (and channel usage) and only later persist the new task.Quota via task.Update() (Line 197-203 vs Line 266). If task.Update() fails, the next polling run can recompute the same quotaDelta from the old persisted task.Quota and apply it again.

Suggested direction (pick one):

  • Persist the task’s Quota/status change atomically with the quota adjustment (single DB transaction if feasible), or
  • Add a reconciliation marker (e.g., “reconciled_at” / “reconciled_tokens”) and guard the adjustment on it, or
  • On task.Update() failure, immediately attempt to rollback the quota adjustment (best-effort) and log loudly.
🧹 Nitpick comments (1)
controller/task_video.go (1)

205-210: De-duplicate the reconsume/refund log formatting + pass/record the actual modelName.

Both branches build near-identical logContent and call RecordReConsumeLog. Consider extracting a small helper to avoid drift. Also, you compute modelRatio from modelName parsed from task.Data, but RecordReConsumeLog currently persists Log.ModelName from task.Properties.UpstreamModelName—these may not match, so either pass modelName into the log call or store it in Other.

Also applies to: 227-232

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a5c8f3 and 6deb76d.

📒 Files selected for processing (2)
  • controller/task_video.go
  • model/log.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-26T09:59:00.337Z
Learnt from: Sh1n3zZ
Repo: QuantumNous/new-api PR: 1659
File: relay/relay_task.go:285-305
Timestamp: 2025-08-26T09:59:00.337Z
Learning: In controller/task_video.go, the redactVideoResponseBody function sanitizes video task responses by removing bytesBase64Encoded fields and truncating base64 strings to 256 characters to prevent large binary data from being stored in task.Data.

Applied to files:

  • controller/task_video.go
🧬 Code graph analysis (2)
model/log.go (4)
model/user.go (1)
  • GetUsernameById (883-908)
common/utils.go (1)
  • GetTimestamp (261-263)
common/str.go (1)
  • MapToJsonStr (37-43)
model/main.go (1)
  • LOG_DB (66-66)
controller/task_video.go (2)
logger/logger.go (1)
  • LogQuota (99-124)
model/log.go (1)
  • RecordReConsumeLog (413-438)

Comment thread model/log.go
Comment on lines +412 to +438

func RecordReConsumeLog(task *Task, modelRatio float64, groupRatio float64, totalTokens int, preConsumedQuota int, actualQuota int, content string) {
username, _ := GetUsernameById(task.UserId, false)
quotaDelta := actualQuota - preConsumedQuota
other := map[string]interface{}{
"task_id": task.TaskID,
"model_ratio": modelRatio,
"group_ratio": groupRatio,
"total_tokens": totalTokens,
"pre_consumed": preConsumedQuota,
"actual_quota": actualQuota,
"quota_delta": quotaDelta,
}
log := &Log{
UserId: task.UserId,
Username: username,
CreatedAt: common.GetTimestamp(),
Type: LogTypeConsume,
Content: content,
ModelName: task.Properties.UpstreamModelName,
Quota: quotaDelta,
ChannelId: task.ChannelId,
Group: task.Group,
Other: common.MapToJsonStr(other),
}
LOG_DB.Create(log)
}

ghost Jan 10, 2026

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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "*.go" | grep -E "(model|log)" | head -20

Repository: QuantumNous/new-api

Length of output: 511


🏁 Script executed:

cd model && ls -la

Repository: QuantumNous/new-api

Length of output: 1950


🏁 Script executed:

cat -n log.go | sed -n '410,445p'

Repository: QuantumNous/new-api

Length of output: 101


🏁 Script executed:

# Search for RecordConsumeLog to compare implementation
rg "func RecordConsumeLog" -A 30 -B 2

Repository: QuantumNous/new-api

Length of output: 1578


🏁 Script executed:

# Check the Log struct definition
rg "type Log struct" -A 30

Repository: QuantumNous/new-api

Length of output: 1967


🏁 Script executed:

cat -n model/log.go | sed -n '405,445p'

Repository: QuantumNous/new-api

Length of output: 1228


🏁 Script executed:

# Check if LogTypeRefund is used in the codebase
rg "LogTypeRefund" -B 5 -A 5

Repository: QuantumNous/new-api

Length of output: 413


🏁 Script executed:

# Search for RecordReConsumeLog usage to understand call sites
rg "RecordReConsumeLog" -B 3 -A 3

Repository: QuantumNous/new-api

Length of output: 1593


🏁 Script executed:

# Check controller/task_video.go for model ratio context
fd task_video.go --exec cat {}

Repository: QuantumNous/new-api

Length of output: 10722


🏁 Script executed:

# Check how RecordConsumeLog uses the guard and error handling
cat -n model/log.go | sed -n '262,310p'

Repository: QuantumNous/new-api

Length of output: 1768


🏁 Script executed:

# Verify GetUsernameById behavior with nil task
rg "func GetUsernameById" -A 15

Repository: QuantumNous/new-api

Length of output: 773


🏁 Script executed:

# Check if LOG_DB.Create() result is ever used elsewhere
rg "LOG_DB\.Create\(" -B 2 -A 3 | head -40

Repository: QuantumNous/new-api

Length of output: 825


🏁 Script executed:

# Verify if quotaDelta being negative with LogTypeConsume is intentional
# Check if there are queries that sum Quota by LogTypeConsume
rg "SumUsedQuota\|Quota.*LogTypeConsume" -B 3 -A 3

Repository: QuantumNous/new-api

Length of output: 45


🏁 Script executed:

# Check if there's any documentation or comments about LogTypeConsume semantics
rg "LogTypeConsume" -B 2 -A 2 | head -50

Repository: QuantumNous/new-api

Length of output: 1301


🏁 Script executed:

# Check if there are any other consume log functions to see established patterns
rg "RecordLog\|RecordConsumeLog" -B 1 | grep "^model/log.go:func" | head -20

Repository: QuantumNous/new-api

Length of output: 45


Fix RecordReConsumeLog: add missing consume-log guard, nil-safety checks, DB error handling, and complete token logging.

Currently, this function lacks three defenses present in other log functions:

  • No common.LogConsumeEnabled guard (unlike RecordConsumeLog), so it logs even when logging is disabled
  • No nil checks before accessing task or task.Properties, risking panic
  • No error handling on LOG_DB.Create(log) (other log functions check and report errors)
  • CompletionTokens field is left at zero despite being available from totalTokens parameter

Additionally, the ModelName is sourced from task.Properties.UpstreamModelName, while modelRatio is computed from a different field (model in task.Data). When these diverge, the log becomes misleading.

Recommended fix
 func RecordReConsumeLog(task *Task, modelRatio float64, groupRatio float64, totalTokens int, preConsumedQuota int, actualQuota int, content string) {
+	if !common.LogConsumeEnabled {
+		return
+	}
+	if task == nil {
+		common.SysLog("RecordReConsumeLog: task is nil")
+		return
+	}
 	username, _ := GetUsernameById(task.UserId, false)
 	quotaDelta := actualQuota - preConsumedQuota
 	other := map[string]interface{}{
 		"task_id":      task.TaskID,
 		"model_ratio":  modelRatio,
 		"group_ratio":  groupRatio,
 		"total_tokens": totalTokens,
 		"pre_consumed": preConsumedQuota,
 		"actual_quota": actualQuota,
 		"quota_delta":  quotaDelta,
 	}
+
+	modelName := ""
+	if task.Properties != nil {
+		modelName = task.Properties.UpstreamModelName
+	}
 	log := &Log{
 		UserId:    task.UserId,
 		Username:  username,
 		CreatedAt: common.GetTimestamp(),
 		Type:      LogTypeConsume,
 		Content:   content,
-		ModelName: task.Properties.UpstreamModelName,
+		ModelName: modelName,
 		Quota:     quotaDelta,
 		ChannelId: task.ChannelId,
 		Group:     task.Group,
+		CompletionTokens: totalTokens,
 		Other:     common.MapToJsonStr(other),
 	}
-	LOG_DB.Create(log)
+	if err := LOG_DB.Create(log).Error; err != nil {
+		common.SysLog("failed to record reconsume log: " + err.Error())
+	}
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.