feat(usage): add anthropic effort tracking and display. #900#901
feat(usage): add anthropic effort tracking and display. #900#901Hwwwww-dev wants to merge 2 commits intoding113:devfrom
Conversation
| "noLogs": "ログがありません", | ||
| "unknownModel": "不明なモデル", | ||
| "billingModel": "課金: {model}" | ||
| "billingModel": "課金: {model}", |
There was a problem hiding this comment.
anthropicEffort label not translated
The billingModel label is properly translated in all non-English locales (e.g. "課金: {model}" in Japanese, "Биллинг: {model}" in Russian, "计费:{model}" in Chinese), but anthropicEffort is left as "Effort: {effort}" across all non-English locales. For consistency, this label should be translated.
This same issue applies to:
messages/ja/myUsage.json:61—"Effort: {effort}"(should be e.g."エフォート: {effort}")messages/ru/myUsage.json:61—"Effort: {effort}"(should be e.g."Уровень сложности: {effort}")messages/zh-CN/myUsage.json:61—"Effort: {effort}"(should be e.g."思考强度: {effort}")messages/zh-TW/myUsage.json:61—"Effort: {effort}"(should be e.g."思考強度: {effort}")messages/ja/dashboard.json— same patternmessages/ru/dashboard.json— same patternmessages/zh-CN/dashboard.json— same patternmessages/zh-TW/dashboard.json— same pattern
Prompt To Fix With AI
This is a comment left during a code review.
Path: messages/ja/myUsage.json
Line: 61
Comment:
**`anthropicEffort` label not translated**
The `billingModel` label is properly translated in all non-English locales (e.g. `"課金: {model}"` in Japanese, `"Биллинг: {model}"` in Russian, `"计费:{model}"` in Chinese), but `anthropicEffort` is left as `"Effort: {effort}"` across all non-English locales. For consistency, this label should be translated.
This same issue applies to:
- `messages/ja/myUsage.json:61` — `"Effort: {effort}"` (should be e.g. `"エフォート: {effort}"`)
- `messages/ru/myUsage.json:61` — `"Effort: {effort}"` (should be e.g. `"Уровень сложности: {effort}"`)
- `messages/zh-CN/myUsage.json:61` — `"Effort: {effort}"` (should be e.g. `"思考强度: {effort}"`)
- `messages/zh-TW/myUsage.json:61` — `"Effort: {effort}"` (should be e.g. `"思考強度: {effort}"`)
- `messages/ja/dashboard.json` — same pattern
- `messages/ru/dashboard.json` — same pattern
- `messages/zh-CN/dashboard.json` — same pattern
- `messages/zh-TW/dashboard.json` — same pattern
How can I resolve this? If you propose a fix, please make it concise.
📝 WalkthroughWalkthrough此PR为系统添加了Anthropic Effort指标支持,包括多语言翻译条目、数据模型扩展、UI组件、工具函数、特殊设置类型定义和数据库层映射。 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/actions/my-usage.ts (1)
150-155: 统一anthropicEffort的空值语义。这里把字段声明成
?: string | null,但下面的映射已经稳定产出string | null。如果undefined没有独立语义,建议去掉可选标记,避免调用方再处理第三种状态。Based on learnings "In TypeScript interfaces, explicitly document and enforce distinct meanings for null and undefined. Example: for numeric limits like limitTotalUsd, use 'number | null | undefined' when null signifies explicitly unlimited (e.g., matches DB schema or special UI logic) and undefined signifies 'inherit default'. This pattern should be consistently reflected in type definitions across related fields to preserve semantic clarity between database constraints and UI behavior."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/actions/my-usage.ts` around lines 150 - 155, The MyUsageLogEntry type declares anthropicEffort as optional (anthropicEffort?: string | null) but your data mapping always yields string | null, so remove the optional marker and make the field strictly "anthropicEffort: string | null" in the MyUsageLogEntry interface (update any callers that currently check for undefined to only handle string or null); reference the MyUsageLogEntry interface and the anthropicEffort property when making this change to keep null/undefined semantics consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@messages/zh-CN/dashboard.json`:
- Line 161: The zh-CN translation for the key "anthropicEffort" contains an
untranslated English label; update the value for "anthropicEffort" in
messages/zh-CN/dashboard.json to a proper Chinese string (e.g., "努力程度:{effort}"
or "努力:{effort}") so it matches surrounding translated fields and follows i18n
rules.
In `@messages/zh-CN/myUsage.json`:
- Around line 61-62: The translation key "anthropicEffort" currently inserts the
raw {effort} value which leaves English levels visible; add discrete locale keys
for each level (e.g., "effort.low", "effort.medium", "effort.high") in the
messages/zh-CN/myUsage.json and change the rendering code that uses the
"anthropicEffort" key to first map the effort value to its localized string
(e.g. localizedEffort = t(`effort.${effort}`)) and then pass that
localizedEffort into t('anthropicEffort', { effort: localizedEffort }) instead
of injecting the raw 'low/medium/high'.
---
Nitpick comments:
In `@src/actions/my-usage.ts`:
- Around line 150-155: The MyUsageLogEntry type declares anthropicEffort as
optional (anthropicEffort?: string | null) but your data mapping always yields
string | null, so remove the optional marker and make the field strictly
"anthropicEffort: string | null" in the MyUsageLogEntry interface (update any
callers that currently check for undefined to only handle string or null);
reference the MyUsageLogEntry interface and the anthropicEffort property when
making this change to keep null/undefined semantics consistent.
🪄 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: CHILL
Plan: Pro
Run ID: c15e4a69-2579-4b77-99db-d6be9ae06e41
📒 Files selected for processing (21)
messages/en/dashboard.jsonmessages/en/myUsage.jsonmessages/ja/dashboard.jsonmessages/ja/myUsage.jsonmessages/ru/dashboard.jsonmessages/ru/myUsage.jsonmessages/zh-CN/dashboard.jsonmessages/zh-CN/myUsage.jsonmessages/zh-TW/dashboard.jsonmessages/zh-TW/myUsage.jsonsrc/actions/my-usage.tssrc/app/[locale]/dashboard/logs/_components/model-display-with-redirect.tsxsrc/app/[locale]/dashboard/logs/_components/usage-logs-table.tsxsrc/app/[locale]/dashboard/logs/_components/virtualized-logs-table.tsxsrc/app/[locale]/my-usage/_components/usage-logs-table.tsxsrc/app/v1/_lib/proxy/message-service.tssrc/components/customs/anthropic-effort-badge.tsxsrc/lib/utils/anthropic-effort.tssrc/lib/utils/special-settings.tssrc/repository/usage-logs.tssrc/types/special-settings.ts
| "nonBilling": "非计费", | ||
| "skipped": "已跳过", | ||
| "specialSettings": "特殊设置", | ||
| "anthropicEffort": "Effort: {effort}", |
There was a problem hiding this comment.
zh-CN 文案不要直接回退成英文。
这里会直接显示在中文界面里,Effort 没有本地化,会和周围已翻译字段不一致。请补上对应的中文文案。
As per coding guidelines "All user-facing strings must use i18n (5 languages supported: zh-CN, zh-TW, en, ja, ru). Never hardcode display text".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@messages/zh-CN/dashboard.json` at line 161, The zh-CN translation for the key
"anthropicEffort" contains an untranslated English label; update the value for
"anthropicEffort" in messages/zh-CN/dashboard.json to a proper Chinese string
(e.g., "努力程度:{effort}" or "努力:{effort}") so it matches surrounding translated
fields and follows i18n rules.
| "billingModel": "计费:{model}", | ||
| "anthropicEffort": "Effort: {effort}" |
There was a problem hiding this comment.
这里还没有真正完成本地化。
anthropicEffort 直接插入了 {effort},但当前新增文案没有提供 low / medium / high 的 locale 映射。这样中文界面大概率还是会显示英文等级。建议把 effort 等级拆成独立翻译键,再由渲染层按值映射后插入。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@messages/zh-CN/myUsage.json` around lines 61 - 62, The translation key
"anthropicEffort" currently inserts the raw {effort} value which leaves English
levels visible; add discrete locale keys for each level (e.g., "effort.low",
"effort.medium", "effort.high") in the messages/zh-CN/myUsage.json and change
the rendering code that uses the "anthropicEffort" key to first map the effort
value to its localized string (e.g. localizedEffort = t(`effort.${effort}`)) and
then pass that localizedEffort into t('anthropicEffort', { effort:
localizedEffort }) instead of injecting the raw 'low/medium/high'.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a significant enhancement by integrating Anthropic's Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request effectively adds tracking and display for Anthropic's effort parameter. The implementation is well-structured, with new types, utility functions, and UI components that are clean and robust. The changes to the data-access layer and proxy service are also solid.
My main feedback is related to internationalization. The new anthropicEffort i18n key has been added to all language files, but the values have not been translated for non-English locales. I've left specific suggestions for each language file to ensure a consistent user experience across all supported languages.
Note: Security Review did not run due to the size of the PR.
| "nonBilling": "非課金", | ||
| "skipped": "スキップ", | ||
| "specialSettings": "特殊設定", | ||
| "anthropicEffort": "Effort: {effort}", |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel, please provide a Japanese translation for "Effort: {effort}". A common translation would be エフォート: {effort}.
| "anthropicEffort": "Effort: {effort}", | |
| "anthropicEffort": "エフォート: {effort}", |
| "unknownModel": "不明なモデル", | ||
| "billingModel": "課金: {model}" | ||
| "billingModel": "課金: {model}", | ||
| "anthropicEffort": "Effort: {effort}" |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel, please provide a Japanese translation for "Effort: {effort}". A common translation would be エフォート: {effort}.
| "anthropicEffort": "Effort: {effort}" | |
| "anthropicEffort": "エフォート: {effort}" |
| "nonBilling": "Не тарифицируется", | ||
| "skipped": "Пропущено", | ||
| "specialSettings": "Особые", | ||
| "anthropicEffort": "Effort: {effort}", |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel, please provide a Russian translation for "Effort: {effort}". A possible translation is Усилие: {effort}.
| "anthropicEffort": "Effort: {effort}", | |
| "anthropicEffort": "Усилие: {effort}", |
| "unknownModel": "Неизвестная модель", | ||
| "billingModel": "Биллинг: {model}" | ||
| "billingModel": "Биллинг: {model}", | ||
| "anthropicEffort": "Effort: {effort}" |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel, please provide a Russian translation for "Effort: {effort}". A possible translation is Усилие: {effort}.
| "anthropicEffort": "Effort: {effort}" | |
| "anthropicEffort": "Усилие: {effort}" |
| "nonBilling": "非计费", | ||
| "skipped": "已跳过", | ||
| "specialSettings": "特殊设置", | ||
| "anthropicEffort": "Effort: {effort}", |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel ("计费:{model}"), please provide a Chinese (Simplified) translation for "Effort: {effort}". A possible translation could be "算力: {effort}".
| "anthropicEffort": "Effort: {effort}", | |
| "anthropicEffort": "算力: {effort}", |
| "unknownModel": "未知模型", | ||
| "billingModel": "计费:{model}" | ||
| "billingModel": "计费:{model}", | ||
| "anthropicEffort": "Effort: {effort}" |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel ("计费:{model}"), please provide a Chinese (Simplified) translation for "Effort: {effort}". A possible translation could be "算力: {effort}".
| "anthropicEffort": "Effort: {effort}" | |
| "anthropicEffort": "算力: {effort}" |
| "nonBilling": "非計費", | ||
| "skipped": "已跳過", | ||
| "specialSettings": "特殊設定", | ||
| "anthropicEffort": "Effort: {effort}", |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel ("計費:{model}"), please provide a Chinese (Traditional) translation for "Effort: {effort}". A possible translation could be "算力: {effort}".
| "anthropicEffort": "Effort: {effort}", | |
| "anthropicEffort": "算力: {effort}", |
| "unknownModel": "未知的模型", | ||
| "billingModel": "計費:{model}" | ||
| "billingModel": "計費:{model}", | ||
| "anthropicEffort": "Effort: {effort}" |
There was a problem hiding this comment.
The new i18n key anthropicEffort has been added, but its value is untranslated. For consistency with other translated keys like billingModel ("計費:{model}"), please provide a Chinese (Traditional) translation for "Effort: {effort}". A possible translation could be "算力: {effort}".
| "anthropicEffort": "Effort: {effort}" | |
| "anthropicEffort": "算力: {effort}" |
Summary
Add tracking and display of Anthropic's
effortparameter in usage logs. When requests includeoutput_config.effort, this value is now captured and displayed as a color-coded badge in the dashboard and my-usage pages.Problem
Usage logs did not display the Anthropic effort level configured in requests, making it difficult to identify which effort level was used for each request.
Fixes #900 - Add effort indicator to usage records
Solution
output_config.effortfrom request bodies for Anthropic providersanthropic_effortspecial setting typeChanges
Core Changes
AnthropicEffortSpecialSettingtype tosrc/types/special-settings.tsextractAnthropicEffortFromRequestBody()utility insrc/lib/utils/anthropic-effort.tsextractAnthropicEffortFromSpecialSettings()for retrievalProxyMessageServicefor Anthropic providersanthropicEffortfield to usage log data structuresUI Changes
AnthropicEffortBadgecomponent with effort-level-specific styling:auto- sky/cyan gradientlow- slatemedium- amberhigh- rosemax- redModelDisplayWithRedirectto show effort badgei18n
anthropicEffortkey to all 5 languages (en, ja, ru, zh-CN, zh-TW)Screenshots
Checklist
Description enhanced by Claude AI
Greptile Summary
This PR adds end-to-end tracking and display of the Anthropic
output_config.effortrequest parameter, surfacing it as a colour-coded badge in both the admin dashboard logs table and the user's personal usage view.Key changes:
AnthropicEffortSpecialSettingtype added to theSpecialSettingunion for audit/display purposes.extractAnthropicEffortFromRequestBody,extractAnthropicEffortFromSpecialSettings) safely extract effort from the raw request body and from persisted special settings with proper type guards.claude/claude-auth), with an idempotency guard to avoid duplicate entries on retry.findUsageLogsBatch,findUsageLogsForKeySlim,findUsageLogsWithDetails) derivesanthropicEffortfrom the unified special settings on every query path.AnthropicEffortBadgecomponent renders per-level colour coding (auto/low/medium/high/max) with a neutral default for unrecognised values."Effort: {effort}") untranslated, unlike the already-translatedbillingModelsibling key.Confidence Score: 4/5
billingModelkey), and the ledger-fallback path infindUsageLogsBatchomits an explicitanthropicEffort: nullassignment (safe due to optional typing but asymmetric).messages/ja,messages/ru,messages/zh-CN,messages/zh-TW) for the untranslated label, and the ledger fallback block insrc/repository/usage-logs.ts.Important Files Changed
AnthropicEffortSpecialSettingtype to theSpecialSettingunion; well-documented with JSDoc comment following the existing pattern.extractAnthropicEffortFromRequestBodysafely navigatesoutput_config.effortwith proper type guards, andextractAnthropicEffortFromSpecialSettingsiterates the settings array — both are well-guarded and clean.output_config.effortfrom the request body for Anthropic providers and records it as a special setting; the idempotency guard (!hasAnthropicEffortAudit) correctly prevents duplicate entries on retry.anthropicEffortextraction to three query paths (batch cursor, slim for key, and with-details); the ledger fallback infindUsageLogsBatchomitsanthropicEfforton returned rows (handled safely via the optional field, but inconsistent).anthropicEfforttoMyUsageLogEntryand passes it through from the slim row; straightforward addition with no issues.anthropicEffortkey but leaves the value untranslated ("Effort: {effort}"), inconsistent with howbillingModelis translated in each locale.Sequence Diagram
sequenceDiagram participant Client participant ProxyMessageService participant Session participant DB as Database (message_request) participant Repo as usage-logs.ts participant UI as Dashboard / MyUsage UI Client->>ProxyMessageService: POST /v1/messages (body includes output_config.effort) ProxyMessageService->>Session: getSpecialSettings() — check for existing anthropic_effort ProxyMessageService->>ProxyMessageService: extractAnthropicEffortFromRequestBody(body) ProxyMessageService->>Session: addSpecialSetting({ type: "anthropic_effort", effort, hit: true }) ProxyMessageService->>DB: createMessageRequest({ special_settings: [...anthropic_effort] }) Repo->>DB: SELECT specialSettings FROM message_request Repo->>Repo: buildUnifiedSpecialSettings(...) Repo->>Repo: extractAnthropicEffortFromSpecialSettings(unifiedSettings) Repo-->>UI: UsageLogRow { anthropicEffort: "high" } UI->>UI: AnthropicEffortBadge({ effort: "high", label: "Effort: high" })Comments Outside Diff (1)
src/repository/usage-logs.ts, line 388-389 (link)Missing
anthropicEffortin ledger fallback path offindUsageLogsBatchIn the ledger fallback path (lines ~349–390, building
fallbackLogsfromusageLedger), theanthropicEffortfield is never set on the returnedUsageLogRowobjects. SinceanthropicEffortis declared as optional (anthropicEffort?: string | null) onUsageLogRow, TypeScript will not flag this, and UI components handleundefinedas falsy — so no crash occurs. However, the omission is asymmetric with the non-fallback path whereanthropicEffortis always populated.For consistency and future-proofing, consider explicitly setting
anthropicEffort: nullinfallbackLogs:Prompt To Fix With AI
Last reviewed commit: e13f968