Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface ErrorDetailsDialogProps {
// 计费详情
inputTokens?: number | null;
outputTokens?: number | null;
cacheCreationInputTokens?: number | null; // 缓存创建总量
cacheCreation5mInputTokens?: number | null;
cacheCreation1hInputTokens?: number | null;
cacheReadInputTokens?: number | null;
Expand Down Expand Up @@ -77,6 +78,7 @@ export function ErrorDetailsDialog({
billingModelSource = "original",
inputTokens,
outputTokens,
cacheCreationInputTokens,
cacheCreation5mInputTokens,
cacheCreation1hInputTokens,
cacheReadInputTokens,
Expand Down Expand Up @@ -421,25 +423,35 @@ export function ErrorDetailsDialog({
{formatTokenAmount(outputTokens)} tokens
</span>
</div>
{(cacheCreation5mInputTokens ?? 0) > 0 && (
{((cacheCreation5mInputTokens ?? 0) > 0 ||
((cacheCreationInputTokens ?? 0) > 0 && cacheTtlApplied !== "1h")) && (
<div className="flex justify-between">
<span className="text-muted-foreground">
{t("logs.billingDetails.cacheWrite5m")}:
</span>
<span className="font-mono">
{formatTokenAmount(cacheCreation5mInputTokens)} tokens{" "}
<span className="text-orange-600">(1.25x)</span>
{formatTokenAmount(
(cacheCreation5mInputTokens ?? 0) > 0
? cacheCreation5mInputTokens
: cacheCreationInputTokens
)}{" "}
tokens <span className="text-orange-600">(1.25x)</span>
</span>
</div>
)}
{(cacheCreation1hInputTokens ?? 0) > 0 && (
{((cacheCreation1hInputTokens ?? 0) > 0 ||
((cacheCreationInputTokens ?? 0) > 0 && cacheTtlApplied === "1h")) && (
<div className="flex justify-between">
<span className="text-muted-foreground">
{t("logs.billingDetails.cacheWrite1h")}:
</span>
<span className="font-mono">
{formatTokenAmount(cacheCreation1hInputTokens)} tokens{" "}
<span className="text-orange-600">(2x)</span>
{formatTokenAmount(
(cacheCreation1hInputTokens ?? 0) > 0
? cacheCreation1hInputTokens
: cacheCreationInputTokens
)}{" "}
tokens <span className="text-orange-600">(2x)</span>
</span>
</div>
)}
Comment on lines +426 to 457
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for displaying the 5m and 1h cache write tokens is duplicated and makes the component harder to read. To improve readability and maintainability, you can use a self-invoking function for each block. This encapsulates the logic, removes repetition, and makes the rendering logic cleaner.

                        {(() => {
                          const tokens =
                            (cacheCreation5mInputTokens ?? 0) > 0
                              ? cacheCreation5mInputTokens
                              : cacheTtlApplied !== "1h"
                                ? cacheCreationInputTokens
                                : null;
                          if ((tokens ?? 0) <= 0) return null;
                          return (
                            <div className="flex justify-between">
                              <span className="text-muted-foreground">
                                {t("logs.billingDetails.cacheWrite5m")}:
                              </span>
                              <span className="font-mono">
                                {formatTokenAmount(tokens)} tokens{" "}
                                <span className="text-orange-600">(1.25x)</span>
                              </span>
                            </div>
                          );
                        })()}
                        {(() => {
                          const tokens =
                            (cacheCreation1hInputTokens ?? 0) > 0
                              ? cacheCreation1hInputTokens
                              : cacheTtlApplied === "1h"
                                ? cacheCreationInputTokens
                                : null;
                          if ((tokens ?? 0) <= 0) return null;
                          return (
                            <div className="flex justify-between">
                              <span className="text-muted-foreground">
                                {t("logs.billingDetails.cacheWrite1h")}:
                              </span>
                              <span className="font-mono">
                                {formatTokenAmount(tokens)} tokens{" "}
                                <span className="text-orange-600">(2x)</span>
                              </span>
                            </div>
                          );
                        })()}

Expand Down
19 changes: 17 additions & 2 deletions src/app/[locale]/dashboard/logs/_components/usage-logs-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,24 @@ export function UsageLogsTable({
<TooltipContent align="end" className="text-xs space-y-1">
<div className="font-medium">{t("logs.columns.cacheWrite")}</div>
<div className="pl-2">
5m: {formatTokenAmount(log.cacheCreation5mInputTokens)}
5m:{" "}
{formatTokenAmount(
(log.cacheCreation5mInputTokens ?? 0) > 0
? log.cacheCreation5mInputTokens
: log.cacheTtlApplied !== "1h"
? log.cacheCreationInputTokens
: 0
)}
</div>
<div className="pl-2">
1h: {formatTokenAmount(log.cacheCreation1hInputTokens)}
1h:{" "}
{formatTokenAmount(
(log.cacheCreation1hInputTokens ?? 0) > 0
? log.cacheCreation1hInputTokens
: log.cacheTtlApplied === "1h"
? log.cacheCreationInputTokens
: 0
)}
Comment on lines +256 to +272
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic to determine the token amount for 5m and 1h cache writes uses nested ternary operators, which are difficult to read and maintain. This exact logic is also duplicated in src/app/[locale]/dashboard/logs/_components/virtualized-logs-table.tsx.

To improve code quality, I recommend extracting this logic into a shared helper function. For example, you could create a function in a utility file:

// in a utils file
export function getDisplayCacheTokens(log, type: '5m' | '1h') {
  if (type === '5m') {
    if ((log.cacheCreation5mInputTokens ?? 0) > 0) {
      return log.cacheCreation5mInputTokens;
    }
    return log.cacheTtlApplied !== '1h' ? log.cacheCreationInputTokens : 0;
  }
  // type === '1h'
  if ((log.cacheCreation1hInputTokens ?? 0) > 0) {
    return log.cacheCreation1hInputTokens;
  }
  return log.cacheTtlApplied === '1h' ? log.cacheCreationInputTokens : 0;
}

Using this helper would make the component code much cleaner and prevent logic duplication.

</div>
<div className="font-medium mt-1">{t("logs.columns.cacheRead")}</div>
<div className="pl-2">
Expand Down Expand Up @@ -425,6 +439,7 @@ export function UsageLogsTable({
billingModelSource={billingModelSource}
inputTokens={log.inputTokens}
outputTokens={log.outputTokens}
cacheCreationInputTokens={log.cacheCreationInputTokens}
cacheCreation5mInputTokens={log.cacheCreation5mInputTokens}
cacheCreation1hInputTokens={log.cacheCreation1hInputTokens}
cacheReadInputTokens={log.cacheReadInputTokens}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,24 @@ export function VirtualizedLogsTable({
<TooltipContent align="end" className="text-xs space-y-1">
<div className="font-medium">{t("logs.columns.cacheWrite")}</div>
<div className="pl-2">
5m: {formatTokenAmount(log.cacheCreation5mInputTokens)}
5m:{" "}
{formatTokenAmount(
(log.cacheCreation5mInputTokens ?? 0) > 0
? log.cacheCreation5mInputTokens
: log.cacheTtlApplied !== "1h"
? log.cacheCreationInputTokens
: 0
)}
</div>
<div className="pl-2">
1h: {formatTokenAmount(log.cacheCreation1hInputTokens)}
1h:{" "}
{formatTokenAmount(
(log.cacheCreation1hInputTokens ?? 0) > 0
? log.cacheCreation1hInputTokens
: log.cacheTtlApplied === "1h"
? log.cacheCreationInputTokens
: 0
)}
Comment on lines +432 to +448
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This component duplicates the complex logic for calculating cache token amounts from usage-logs-table.tsx. Using nested ternary operators here makes the code difficult to read. This is a good opportunity for refactoring. As mentioned in the review for usage-logs-table.tsx, please consider creating a single, shared helper function in a utility file to handle this calculation. This will improve maintainability and readability by centralizing the logic.

</div>
<div className="font-medium mt-1">{t("logs.columns.cacheRead")}</div>
<div className="pl-2">{formatTokenAmount(log.cacheReadInputTokens)}</div>
Expand Down Expand Up @@ -555,6 +569,7 @@ export function VirtualizedLogsTable({
billingModelSource={billingModelSource}
inputTokens={log.inputTokens}
outputTokens={log.outputTokens}
cacheCreationInputTokens={log.cacheCreationInputTokens}
cacheCreation5mInputTokens={log.cacheCreation5mInputTokens}
cacheCreation1hInputTokens={log.cacheCreation1hInputTokens}
cacheReadInputTokens={log.cacheReadInputTokens}
Expand Down
Loading