Conversation
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 focuses on restoring the continuous integration (CI) baseline by addressing several critical issues that were causing build and unit test failures. The changes are minimal and specifically target these identified problems, ensuring that the project's foundational tests and build processes are stable and green. This restoration is crucial for enabling independent reviewability of subsequent pull requests and streamlining the development workflow. Highlights
Changelog
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
|
📝 WalkthroughWalkthrough本次改动新增多语言“multi”价格徽章键,重构 Chart Tooltip 的载荷键/标签归一化与类型定义,调整成本计算测试以采用长上下文整体计价规则,并将响应处理测试从 ProxyResponseHandler.dispatch 迁移为 finalizeRequestStats 并扩展会话模拟。 Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 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.
Code Review
此拉取请求主要致力于修复持续集成(CI)流水线,以恢复构建和单元测试的基线。主要变更包括: * 修复 latency-chart.tsx 和 chart.tsx 中图表工具提示的类型定义,解决了构建失败的问题。 * 在 prices.json 文件中为多种语言添加了缺失的翻译。 * 更新成本计算的单元测试(cost-calculation-breakdown.test.ts),使其与新的长上下文请求定价逻辑保持一致。 * 重构租约递减测试(response-handler-lease-decrement.test.ts),以匹配响应处理器中更新后的成本追踪逻辑。 总体而言,这些更改清晰、必要,并有效地实现了让 CI 恢复绿色的目标。代码质量良好,我没有发现任何问题。
There was a problem hiding this comment.
Code Review Summary
This PR addresses CI build and test failures through targeted fixes in four areas: tooltip type safety, i18n completeness, and test alignment with current pricing/billing logic. The changes are appropriately scoped for a CI recovery PR.
PR Size: M
- Lines changed: 280 (161 additions, 119 deletions)
- Files changed: 7
Issues Found
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Logic/Bugs | 0 | 0 | 0 | 0 |
| Security | 0 | 0 | 0 | 0 |
| Error Handling | 0 | 0 | 0 | 0 |
| Types | 0 | 0 | 0 | 0 |
| Comments/Docs | 0 | 0 | 0 | 0 |
| Tests | 0 | 0 | 1 | 0 |
| Simplification | 0 | 0 | 0 | 0 |
Medium Priority Issues (Should Consider)
[TEST-BRITTLE] Manual ProxySession construction in tests
- File: tests/unit/proxy/response-handler-lease-decrement.test.ts
- Issue: The session mock uses Object.create(ProxySession.prototype) with manual property assignment, which bypasses TypeScript constructor validation and creates a brittle test that will break when ProxySession changes.
- Suggestion: Consider creating a test factory helper or using vi.mock() for proper type-safe mocking in future refactors.
Review Coverage
- Logic and correctness - All fixes are correct
- Security (OWASP Top 10) - No security concerns
- Error handling - Proper type normalization prevents runtime errors
- Type safety - Type fixes are appropriate
- Documentation accuracy - Comments match implementation
- Test coverage - Tests updated to match current pricing semantics
- Code clarity - Well-structured changes
Verification Notes
-
Tooltip Type Fix: The normalizeTooltipKey helper correctly handles dataKey types from Recharts.
-
i18n Completeness: prices.badges.multi translations properly added for ja, ru, zh-TW locales.
-
Pricing Test Update: Expectations correctly updated to reflect long-context whole request pricing.
-
Response Handler Test: Correctly updated to use finalizeRequestStats.
Automated review by Claude AI
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/ui/chart.tsx`:
- Line 148: The code uses logical OR fallbacks when computing the payload key
which incorrectly treats valid falsy values as missing; update the expression
that sets key (currently using labelKey || item?.dataKey || item?.name with
normalizePayloadKey) to use nullish coalescing (labelKey ?? item?.dataKey ??
item?.name) so normalizePayloadKey receives legitimate 0/"" values; apply the
same change to the other occurrence mentioned (the second chained fallback) to
use ?? consistently.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 595eb969-6c68-468f-93bf-930d83753d9f
📒 Files selected for processing (7)
messages/ja/settings/prices.jsonmessages/ru/settings/prices.jsonmessages/zh-TW/settings/prices.jsonsrc/app/[locale]/dashboard/availability/_components/provider/latency-chart.tsxsrc/components/ui/chart.tsxtests/unit/lib/cost-calculation-breakdown.test.tstests/unit/proxy/response-handler-lease-decrement.test.ts
|
|
||
| const [item] = payload; | ||
| const key = `${labelKey || item?.dataKey || item?.name || "value"}`; | ||
| const key = normalizePayloadKey(labelKey || item?.dataKey || item?.name, "value"); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cd /repo && find . -name "chart.tsx" -type f | head -5Repository: ding113/claude-code-hub
Length of output: 122
🏁 Script executed:
cat -n src/components/ui/chart.tsx | sed -n '140,210p'Repository: ding113/claude-code-hub
Length of output: 3117
🏁 Script executed:
ast-grep --pattern 'function normalizePayloadKey($$$) {
$$$
}'Repository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
rg "normalizePayloadKey" src/components/ui/chart.tsx -B 2 -A 10Repository: ding113/claude-code-hub
Length of output: 1767
🏁 Script executed:
rg "function normalizePayloadKey|const normalizePayloadKey" src/ -A 10Repository: ding113/claude-code-hub
Length of output: 616
🏁 Script executed:
cat -n src/components/ui/chart.tsx | sed -n '1,50p'Repository: ding113/claude-code-hub
Length of output: 1620
🏁 Script executed:
cat -n src/components/ui/chart.tsx | sed -n '145,160p'Repository: ding113/claude-code-hub
Length of output: 688
🏁 Script executed:
rg "typeof value|dataKey|item\.name" src/components/ui/chart.tsx -B 1 -A 1 | head -50Repository: ding113/claude-code-hub
Length of output: 1214
将 || 改为 ??,以支持合法的 falsy 键值。
Line 156 和 Line 195 在使用 || 进行链式回退时,会跳过合法的 falsy 值(如数字 0 和空字符串 "")。由于 normalizePayloadKey 函数明确支持 string 和 number 类型,应使用 ??(nullish coalescing)仅在 null/undefined 时回退。
建议修改
- const key = normalizePayloadKey(labelKey || item?.dataKey || item?.name, "value");
+ const key = normalizePayloadKey(labelKey ?? item?.dataKey ?? item?.name, "value");- const key = normalizePayloadKey(nameKey || item.name || item.dataKey, "value");
+ const key = normalizePayloadKey(nameKey ?? item.name ?? item.dataKey, "value");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const key = normalizePayloadKey(labelKey || item?.dataKey || item?.name, "value"); | |
| const key = normalizePayloadKey(labelKey ?? item?.dataKey ?? item?.name, "value"); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/ui/chart.tsx` at line 148, The code uses logical OR fallbacks
when computing the payload key which incorrectly treats valid falsy values as
missing; update the expression that sets key (currently using labelKey ||
item?.dataKey || item?.name with normalizePayloadKey) to use nullish coalescing
(labelKey ?? item?.dataKey ?? item?.name) so normalizePayloadKey receives
legitimate 0/"" values; apply the same change to the other occurrence mentioned
(the second chained fallback) to use ?? consistently.
| indicator === "dot" && "items-center" | ||
| )} | ||
| > | ||
| {tooltipFormatter && item?.value !== undefined && item.name !== undefined ? ( |
There was a problem hiding this comment.
Formatter condition broadened to include empty-string names
Changing the condition from item.name (truthy) to item.name !== undefined means items whose name is an empty string "" will now invoke the tooltipFormatter, whereas previously they would have fallen through to the default rendering block.
In practice recharts usually provides a non-empty name, but any series registered with an empty string key will silently change rendering behaviour. Consider being explicit about the intent:
| {tooltipFormatter && item?.value !== undefined && item.name !== undefined ? ( | |
| {tooltipFormatter && item?.value !== undefined && !!item.name ? ( |
This preserves the previous truthy-check semantics while keeping the cleaner variable name.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/ui/chart.tsx
Line: 209
Comment:
**Formatter condition broadened to include empty-string names**
Changing the condition from `item.name` (truthy) to `item.name !== undefined` means items whose `name` is an empty string `""` will now invoke the `tooltipFormatter`, whereas previously they would have fallen through to the default rendering block.
In practice recharts usually provides a non-empty name, but any series registered with an empty string key will silently change rendering behaviour. Consider being explicit about the intent:
```suggestion
{tooltipFormatter && item?.value !== undefined && !!item.name ? (
```
This preserves the previous truthy-check semantics while keeping the cleaner variable name.
How can I resolve this? If you propose a fix, please make it concise.| {item.value !== undefined && item.value !== null && ( | ||
| <span className="text-foreground font-mono font-medium tabular-nums"> | ||
| {item.value.toLocaleString()} | ||
| </span> | ||
| )} |
There was a problem hiding this comment.
toLocaleString() called on a potentially array-typed value
item.value is now typed as ChartTooltipValue = number | string | ReadonlyArray<number | string>. When item.value is a ReadonlyArray, Array.prototype.toLocaleString() returns a comma-joined string (e.g. "12,345" for [12, 345]), which would be visually indistinguishable from a plain number but semantically incorrect.
Range/area-band chart configurations can surface array values in the payload. Consider narrowing the display branch:
| {item.value !== undefined && item.value !== null && ( | |
| <span className="text-foreground font-mono font-medium tabular-nums"> | |
| {item.value.toLocaleString()} | |
| </span> | |
| )} | |
| {item.value !== undefined && item.value !== null && !Array.isArray(item.value) && ( | |
| <span className="text-foreground font-mono font-medium tabular-nums"> | |
| {item.value.toLocaleString()} | |
| </span> | |
| )} |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/ui/chart.tsx
Line: 255-259
Comment:
**`toLocaleString()` called on a potentially array-typed value**
`item.value` is now typed as `ChartTooltipValue = number | string | ReadonlyArray<number | string>`. When `item.value` is a `ReadonlyArray`, `Array.prototype.toLocaleString()` returns a comma-joined string (e.g. `"12,345"` for `[12, 345]`), which would be visually indistinguishable from a plain number but semantically incorrect.
Range/area-band chart configurations can surface array values in the payload. Consider narrowing the display branch:
```suggestion
{item.value !== undefined && item.value !== null && !Array.isArray(item.value) && (
<span className="text-foreground font-mono font-medium tabular-nums">
{item.value.toLocaleString()}
</span>
)}
```
How can I resolve this? If you propose a fix, please make it concise.| function normalizeTooltipKey( | ||
| value: TooltipPayloadEntry["dataKey"] | string | undefined, | ||
| fallback: string | ||
| ) { | ||
| if (typeof value === "string" || typeof value === "number") { | ||
| return String(value); | ||
| } | ||
|
|
||
| return fallback; | ||
| } |
There was a problem hiding this comment.
Duplicate helper – consider extracting to a shared utility
normalizeTooltipKey here is functionally identical to normalizePayloadKey introduced in src/components/ui/chart.tsx in this same PR. Having two copies means any future edge-case fix must be applied twice.
A small shared helper (e.g. in src/lib/utils/chart.ts) would eliminate the drift risk. Alternatively, normalizePayloadKey could be exported from chart.tsx and imported here.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/[locale]/dashboard/availability/_components/provider/latency-chart.tsx
Line: 33-42
Comment:
**Duplicate helper – consider extracting to a shared utility**
`normalizeTooltipKey` here is functionally identical to `normalizePayloadKey` introduced in `src/components/ui/chart.tsx` in this same PR. Having two copies means any future edge-case fix must be applied twice.
A small shared helper (e.g. in `src/lib/utils/chart.ts`) would eliminate the drift risk. Alternatively, `normalizePayloadKey` could be exported from `chart.tsx` and imported here.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/components/ui/chart.tsx (2)
156-156:⚠️ Potential issue | 🟡 Minor建议使用
??替代||以支持合法的 falsy 值
labelKey || item?.dataKey || item?.name使用逻辑或运算符会跳过合法的 falsy 值(如数字0或空字符串"")。由于normalizePayloadKey明确支持number类型,应使用 nullish coalescing??仅在null/undefined时回退。建议修改
- const key = normalizePayloadKey(labelKey || item?.dataKey || item?.name, "value"); + const key = normalizePayloadKey(labelKey ?? item?.dataKey ?? item?.name, "value");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/ui/chart.tsx` at line 156, The expression using logical OR in the key computation can incorrectly skip valid falsy values; replace the fallback chain `labelKey || item?.dataKey || item?.name` with nullish coalescing so `normalizePayloadKey` receives 0 or "" when valid — update the assignment that produces `key` (the call to normalizePayloadKey) to use `labelKey ?? item?.dataKey ?? item?.name` ensuring only null/undefined trigger the next fallback.
193-199:⚠️ Potential issue | 🟡 Minor建议 Line 195 同样使用
??替代||与 Line 156 相同的问题,
nameKey || item.name || item.dataKey会跳过 falsy 但合法的值。建议修改
- const key = normalizePayloadKey(nameKey || item.name || item.dataKey, "value"); + const key = normalizePayloadKey(nameKey ?? item.name ?? item.dataKey, "value");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/ui/chart.tsx` around lines 193 - 199, Replace the nullish-handling that uses logical OR with nullish coalescing in the tooltip payload mapping: in the expression that builds key (currently using nameKey || item.name || item.dataKey) switch to using ?? to avoid skipping valid falsy values; also update any similar uses in this block (e.g., where item.name || item.dataKey is used to build itemName) so normalizePayloadKey receives the first non-null/undefined value; locate these in the map callback that calls normalizePayloadKey, getPayloadConfigFromPayload, and assigns itemKey/itemName.
🧹 Nitpick comments (1)
src/components/ui/chart.tsx (1)
209-216: formatter 调用前的前置条件检查可以更宽松当前仅在
item.name !== undefined时才调用 formatter,但某些场景下 payload 项可能没有name属性但有dataKey。考虑是否需要放宽条件或使用itemName(已通过normalizePayloadKey处理过的值)作为判断依据。可选优化
- {tooltipFormatter && item?.value !== undefined && item.name !== undefined ? ( + {tooltipFormatter && item?.value !== undefined ? ( tooltipFormatter( item.value, itemName, item, index, payload as ReadonlyArray<TooltipPayloadEntry> )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/ui/chart.tsx` around lines 209 - 216, The current conditional only calls tooltipFormatter when item?.value !== undefined and item.name !== undefined, which prevents formatting for payload entries that lack name but have a dataKey or normalized key; update the check in the render branch that calls tooltipFormatter (where tooltipFormatter, item, itemName and TooltipPayloadEntry are used) to allow calling the formatter when itemName (the result from normalizePayloadKey) is truthy or when item.dataKey is present, i.e. replace the strict item.name check with a check that uses itemName || item.dataKey so the formatter is invoked for entries that have a usable identifier even if item.name is undefined.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/ui/chart.tsx`:
- Line 181: The cast to TooltipFormatter masks Recharts v3's Formatter which can
return a tuple; update the TooltipFormatter type to return "[React.ReactNode,
string] | React.ReactNode" (or union with the original TName) and then handle
the tuple when using tooltipFormatter in the render path (where tooltipFormatter
is invoked) by checking if the result is an array and extracting the display
value (first element) or label (second element) before embedding in JSX; change
the declaration "const tooltipFormatter = formatter as TooltipFormatter |
undefined" to reflect the updated type and adjust the rendering logic that
consumes tooltipFormatter to safely handle both tuple and single-node returns.
---
Duplicate comments:
In `@src/components/ui/chart.tsx`:
- Line 156: The expression using logical OR in the key computation can
incorrectly skip valid falsy values; replace the fallback chain `labelKey ||
item?.dataKey || item?.name` with nullish coalescing so `normalizePayloadKey`
receives 0 or "" when valid — update the assignment that produces `key` (the
call to normalizePayloadKey) to use `labelKey ?? item?.dataKey ?? item?.name`
ensuring only null/undefined trigger the next fallback.
- Around line 193-199: Replace the nullish-handling that uses logical OR with
nullish coalescing in the tooltip payload mapping: in the expression that builds
key (currently using nameKey || item.name || item.dataKey) switch to using ?? to
avoid skipping valid falsy values; also update any similar uses in this block
(e.g., where item.name || item.dataKey is used to build itemName) so
normalizePayloadKey receives the first non-null/undefined value; locate these in
the map callback that calls normalizePayloadKey, getPayloadConfigFromPayload,
and assigns itemKey/itemName.
---
Nitpick comments:
In `@src/components/ui/chart.tsx`:
- Around line 209-216: The current conditional only calls tooltipFormatter when
item?.value !== undefined and item.name !== undefined, which prevents formatting
for payload entries that lack name but have a dataKey or normalized key; update
the check in the render branch that calls tooltipFormatter (where
tooltipFormatter, item, itemName and TooltipPayloadEntry are used) to allow
calling the formatter when itemName (the result from normalizePayloadKey) is
truthy or when item.dataKey is present, i.e. replace the strict item.name check
with a check that uses itemName || item.dataKey so the formatter is invoked for
entries that have a usable identifier even if item.name is undefined.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ce8a927a-bcb6-4e8a-b940-ca89fcb3dee7
📒 Files selected for processing (1)
src/components/ui/chart.tsx
| } | ||
|
|
||
| const nestLabel = payload.length === 1 && indicator !== "dot"; | ||
| const tooltipFormatter = formatter as TooltipFormatter | undefined; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Recharts v3 TooltipContentProps formatter signature
💡 Result:
In Recharts v3, TooltipContentProps extends TooltipProps, and the formatter prop comes from DefaultTooltipContentProps as Formatter<TValue, TName>. Its TypeScript signature is:
export type Formatter<TValue extends ValueType, TName extends NameType> = (
value: TValue | undefined,
name: TName | undefined,
item: Payload<TValue, TName>,
index: number,
payload: ReadonlyArray<Payload<TValue, TName>>
) => [React.ReactNode, TName] | React.ReactNode;Source: Recharts v3 type definitions for DefaultTooltipContent / Formatter and TooltipContentProps / TooltipProps. (app.unpkg.com)
Citations:
🏁 Script executed:
# First, let's find and examine the chart.tsx file around line 181
wc -l src/components/ui/chart.tsxRepository: ding113/claude-code-hub
Length of output: 98
🏁 Script executed:
# Read the area around line 181 to see the context
sed -n '170,190p' src/components/ui/chart.tsxRepository: ding113/claude-code-hub
Length of output: 695
🏁 Script executed:
# Search for TooltipFormatter type definition in the file
rg "type TooltipFormatter" src/components/ui/chart.tsx -A 5Repository: ding113/claude-code-hub
Length of output: 240
🏁 Script executed:
# Also check for interface TooltipFormatter definition
rg "interface TooltipFormatter" src/components/ui/chart.tsx -A 5Repository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
# Search in the entire src directory for TooltipFormatter
rg "TooltipFormatter" src/ -B 2 -A 2Repository: ding113/claude-code-hub
Length of output: 650
🏁 Script executed:
# Get the complete TooltipFormatter type definition
sed -n '1,363p' src/components/ui/chart.tsx | grep -A 10 "type TooltipFormatter"Repository: ding113/claude-code-hub
Length of output: 426
🏁 Script executed:
# Also check for ChartTooltipValue and TooltipPayloadEntry types
rg "type ChartTooltipValue|interface ChartTooltipValue" src/components/ui/chart.tsx -A 2Repository: ding113/claude-code-hub
Length of output: 241
🏁 Script executed:
# Check TooltipPayloadEntry definition
rg "type TooltipPayloadEntry|interface TooltipPayloadEntry" src/components/ui/chart.tsx -A 3Repository: ding113/claude-code-hub
Length of output: 203
🏁 Script executed:
# Get the full context of where formatter comes from (the function parameters)
sed -n '150,175p' src/components/ui/chart.tsxRepository: ding113/claude-code-hub
Length of output: 882
🏁 Script executed:
# Check how tooltipFormatter is used after line 181
sed -n '181,250p' src/components/ui/chart.tsxRepository: ding113/claude-code-hub
Length of output: 3095
🏁 Script executed:
# Also check the function signature to see where formatter comes from
sed -n '120,160p' src/components/ui/chart.tsxRepository: ding113/claude-code-hub
Length of output: 1034
修复 TooltipFormatter 的返回类型以与 Recharts v3 兼容
Recharts v3 的 Formatter 类型返回值为 [React.ReactNode, TName] | React.ReactNode(可以返回元组或单个节点),但此处的自定义 TooltipFormatter 类型仅声明返回 React.ReactNode。此类型转换会掩盖不兼容性,当 Recharts 实际返回元组时,直接在 JSX 中渲染(第 197-202 行)会导致运行时错误。需要修改 TooltipFormatter 的返回类型为 [React.ReactNode, string] | React.ReactNode 或在使用时处理元组情况。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/ui/chart.tsx` at line 181, The cast to TooltipFormatter masks
Recharts v3's Formatter which can return a tuple; update the TooltipFormatter
type to return "[React.ReactNode, string] | React.ReactNode" (or union with the
original TName) and then handle the tuple when using tooltipFormatter in the
render path (where tooltipFormatter is invoked) by checking if the result is an
array and extracting the display value (first element) or label (second element)
before embedding in JSX; change the declaration "const tooltipFormatter =
formatter as TooltipFormatter | undefined" to reflect the updated type and
adjust the rendering logic that consumes tooltipFormatter to safely handle both
tuple and single-node returns.
This PR only contains:
src/app/[locale]/dashboard/availability/_components/provider/latency-chart.tsx与src/components/ui/chart.tsx的 tooltip 类型假设,恢复typecheck/buildmessages/zh-TW/settings/prices.json、messages/ja/settings/prices.json、messages/ru/settings/prices.json中缺失的prices.badges.multitests/unit/lib/cost-calculation-breakdown.test.ts与当前 long-context 整单计价语义tests/unit/proxy/response-handler-lease-decrement.test.ts的夹具与入口,使其匹配当前 response-handler 的成本追踪路径This PR intentionally excludes:
Why split this way:
How to verify:
bun run typecheckbun run buildbun run test -- tests/unit/ --passWithNoTestsnode /home/opus/projects/claude-code-hub/node_modules/vitest/vitest.mjs run tests/unit/i18n/settings-split-guards.test.tsnode /home/opus/projects/claude-code-hub/node_modules/vitest/vitest.mjs run tests/unit/lib/cost-calculation-breakdown.test.tsnode /home/opus/projects/claude-code-hub/node_modules/vitest/vitest.mjs run tests/unit/proxy/response-handler-lease-decrement.test.tsnode /home/opus/projects/claude-code-hub/node_modules/vitest/vitest.mjs run tests/unit/dashboard/availability/latency-chart.test.tsxGreptile Summary
This PR restores CI green by addressing four independent failure categories: TypeScript tooltip type errors in the chart components, missing
badges.multii18n keys in three locales, misaligned cost-calculation test expectations (now reflecting the "whole-request" long-context pricing semantics), and an outdated response-handler test fixture/entry-point that no longer matched the currentfinalizeRequestStatsAPI shape.Key changes:
src/components/ui/chart.tsx— introducesChartTooltipValue,TooltipPayloadEntry, andnormalizePayloadKeyhelpers to eliminate unsafe type assertions in the tooltip render pipeline; also fixes zero-value display (item.value && …→item.value !== undefined && item.value !== null)src/app/[locale]/dashboard/availability/_components/provider/latency-chart.tsx— importsTooltipContentPropsand adds a localnormalizeTooltipKeyhelper for safe key derivationmessages/{ja,ru,zh-TW}/settings/prices.json— backfills the missingprices.badges.multikey that was causing i18n guard test failurestests/unit/lib/cost-calculation-breakdown.test.ts— updates two tiered-pricing assertions to match the current "charge all tokens at the premium rate once threshold is exceeded" implementation (verified: 300k × $0.000003 × 2.0 = $1.80 input; 100 × $0.000015 × 1.5 = $0.00225 output)tests/unit/proxy/response-handler-lease-decrement.test.ts— replacesProxyResponseHandler.dispatchwith the exportedfinalizeRequestStatsfunction and extends the session fixture withresolvedPricingCache,getResolvedPricingByBillingSource, andbypassResponseRectifierto match the currentProxySessioninterfaceConfidence Score: 4/5
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["ChartTooltip payload item"] --> B{item.value\n!== undefined\n&& !== null?} B -- No --> C[Skip rendering value span] B -- Yes --> D{tooltipFormatter\n&& item.name\n!== undefined?} D -- Yes --> E["tooltipFormatter(value, itemName, item, index, payload)"] D -- No --> F{item.value\nis array?} F -- Yes --> G["item.value.toLocaleString()\n→ comma-joined string ⚠️"] F -- No --> H["item.value.toLocaleString()\n→ formatted number/string ✅"] E --> I[Custom formatter output] G --> J[Rendered span] H --> JLast reviewed commit: 825a444