Add input + output tokens for anthropic message type
This commit is contained in:
parent
84c507bc14
commit
277be4c50e
@ -113,6 +113,35 @@ describe("LogDetailContent", () => {
|
||||
expect(screen.getAllByText("$0.00200000").length).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it("should show Input Tokens and Output Tokens for anthropic_messages when uncached text_tokens exist", () => {
|
||||
render(
|
||||
<LogDetailContent
|
||||
logEntry={createLogEntry({
|
||||
call_type: "anthropic_messages",
|
||||
prompt_tokens: 34548,
|
||||
completion_tokens: 28,
|
||||
total_tokens: 34576,
|
||||
spend: 0.01107885,
|
||||
metadata: {
|
||||
status: "success",
|
||||
additional_usage_values: {
|
||||
prompt_tokens_details: { text_tokens: 3 },
|
||||
cache_read_input_tokens: 34462,
|
||||
cache_creation_input_tokens: 83,
|
||||
},
|
||||
},
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Input Tokens")).toBeInTheDocument();
|
||||
expect(screen.getByText("Output Tokens")).toBeInTheDocument();
|
||||
expect(screen.getByText("3")).toBeInTheDocument();
|
||||
expect(screen.getByText("28")).toBeInTheDocument();
|
||||
// Combined TokenFlow line should not appear (would include "prompt tokens")
|
||||
expect(screen.queryByText(/prompt tokens \+ .* completion tokens/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should display ConfigInfoMessage when no messages, response, or error and not loading", () => {
|
||||
render(
|
||||
<LogDetailContent
|
||||
|
||||
@ -260,6 +260,19 @@ function GuardrailLabel({ label, maskedCount }: { label: string; maskedCount: nu
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uncached input token count (billable non-cache prompt text), aligned with Cost Breakdown "Input".
|
||||
* Same sources as CostBreakdownViewer rawInputTokens.
|
||||
*/
|
||||
function getUncachedInputTextTokens(metadata: Record<string, any>): number | undefined {
|
||||
const raw =
|
||||
metadata?.additional_usage_values?.prompt_tokens_details?.text_tokens ??
|
||||
metadata?.usage_object?.prompt_tokens_details?.text_tokens;
|
||||
if (raw === undefined || raw === null) return undefined;
|
||||
const n = Number(raw);
|
||||
return Number.isFinite(n) ? n : undefined;
|
||||
}
|
||||
|
||||
function MetricsSection({ logEntry, metadata }: { logEntry: LogEntry; metadata: Record<string, any> }) {
|
||||
const completionStartTime = logEntry.completionStartTime;
|
||||
const ttftMs =
|
||||
@ -280,17 +293,32 @@ function MetricsSection({ logEntry, metadata }: { logEntry: LogEntry; metadata:
|
||||
? "red"
|
||||
: "default";
|
||||
|
||||
const uncachedInputTokens = getUncachedInputTextTokens(metadata);
|
||||
const showAnthropicMessagesInputOutput =
|
||||
logEntry.call_type === "anthropic_messages" && uncachedInputTokens !== undefined;
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg shadow w-full max-w-full overflow-hidden mb-6">
|
||||
<Card title="Metrics" size="small" style={{ marginBottom: 0 }}>
|
||||
<Descriptions column={2} size="small">
|
||||
<Descriptions.Item label="Tokens">
|
||||
<TokenFlow
|
||||
prompt={logEntry.prompt_tokens}
|
||||
completion={logEntry.completion_tokens}
|
||||
total={logEntry.total_tokens}
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
{showAnthropicMessagesInputOutput ? (
|
||||
<>
|
||||
<Descriptions.Item label="Input Tokens">
|
||||
{formatNumberWithCommas(uncachedInputTokens)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Output Tokens">
|
||||
{formatNumberWithCommas(logEntry.completion_tokens)}
|
||||
</Descriptions.Item>
|
||||
</>
|
||||
) : (
|
||||
<Descriptions.Item label="Tokens">
|
||||
<TokenFlow
|
||||
prompt={logEntry.prompt_tokens}
|
||||
completion={logEntry.completion_tokens}
|
||||
total={logEntry.total_tokens}
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
)}
|
||||
<Descriptions.Item label="Cost">${formatNumberWithCommas(logEntry.spend || 0, 8)}</Descriptions.Item>
|
||||
<Descriptions.Item label="Duration">{logEntry.request_duration_ms != null ? (logEntry.request_duration_ms / 1000).toFixed(3) : "-"} s</Descriptions.Item>
|
||||
{ttftMs != null && ttftMs > 0 && (
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user