import type { CallDetail } from "../api"; import { JsonEditor } from "./ui/JsonEditor"; import { Tabs, type TabItem } from "./ui/Tabs"; import styles from "./CallDetails.module.scss"; const show = (value: string | number | null) => value ?? "-"; const timing = (value: number | null) => value == null ? "-" : `${value} ms`; export function CallDetails({ detail }: { detail: CallDetail }) { const { call, request, response_chunks: chunks, cursor_trace: cursorTrace } = detail; const responseBody = chunks.map((chunk) => chunk.data).join(""); const responseBytes = chunks.reduce((total, chunk) => total + chunk.byte_count, 0); const fields: Array<[string, string | number]> = [ ["Call ID", call.call_id], [t("调用类型"), call.call_kind === "cursor_official" ? t("Cursor 官方") : "LLM"], [t("路由"), call.route === "cursor_official" ? t("Cursor 官方") : "BYOK"], ["Run ID", call.run_id], ["Conversation ID", call.conversation_id], [t("上游调用序号"), call.provider_call_index], ["Model Hash", show(call.model_hash)], [t("上游类型"), call.provider_type], [t("上游地址"), call.provider_url], [t("最终请求类型"), call.request_type], [t("最终请求地址"), call.request_url], ["Model ID", call.model_id], [t("显示名称"), call.display_name], [t("思考强度"), show(call.reasoning_effort)], ["Fast", call.fast == null ? "-" : call.fast ? t("是") : t("否")], [t("状态"), call.status], ["Finish Reason", show(call.finish_reason)], ["HTTP Status", show(call.http_status)], ["Created At", `${call.created_at_ms} · ${new Date(call.created_at_ms).toLocaleString()}`], [t("耗时"), timing(call.duration_ms)], ["TTFB", timing(call.ttfb_ms)], ["TTFT", timing(call.ttft_ms)], ["Input Token", show(call.input_tokens)], ["Output Token", show(call.output_tokens)], ["Total Token", show(call.total_tokens)], ["Cache Read Token", show(call.cache_read_tokens)], ["Cache Write Token", show(call.cache_write_tokens)], ["Reasoning Token", show(call.reasoning_tokens)], [t("消息数"), call.message_count], [t("工具数"), call.tool_count], [t("详细记录"), call.detailed ? t("是") : t("否")], ["Error Kind", show(call.error_kind)], ["Error Message", show(call.error_message)], ]; const tabs: TabItem[] = [ { value: "call", label: t("调用信息"), content:
{fields.map(([label, value]) =>
{label}
{value}
)}
}, { value: "request", label: t("请求"), content:
{request ? <>
{t("字节数")}:{request.byte_count}

{t("请求头")}

{t("请求体")}

:
{t("未记录请求内容,请开启详细记录后重试。")}
}
}, { value: "response", label: t("响应流"), content:
{chunks.length > 0 ? <>
{t("分块数")}:{chunks.length} · {t("字节数")}:{responseBytes}
:
{t("未记录响应内容,请开启详细记录后重试。")}
}
}, ]; if (cursorTrace) tabs.push({ value: "cursor-trace", label: t("Cursor 追踪"), content:
Request ID:{cursorTrace.trace.request_id} · {t("工件数")}:{cursorTrace.artifacts.length}
}); return
; }