mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 21:30:17 +08:00
feat(usage): claude-desktop filter and pricing-model audit display
- add claude-desktop to AppType/KNOWN_APP_TYPES and the dashboard app filter; it was hidden because its rows looked like pure failure noise, which was the app_type attribution bug fixed on the backend - request detail panel now shows the requested model and the pricing model when they differ from the response model, making route-takeover bills auditable from the UI - locale keys added for zh/en/ja/zh-TW
This commit is contained in:
@@ -111,6 +111,28 @@ export function RequestDetailPanel({
|
||||
{t("usage.model", "模型")}
|
||||
</dt>
|
||||
<dd className="font-mono">{request.model}</dd>
|
||||
{request.requestModel &&
|
||||
request.requestModel !== request.model && (
|
||||
<>
|
||||
<dt className="mt-1 text-muted-foreground">
|
||||
{t("usage.requestModel", "请求模型")}
|
||||
</dt>
|
||||
<dd className="font-mono text-xs">
|
||||
{request.requestModel}
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
{request.pricingModel &&
|
||||
request.pricingModel !== request.model && (
|
||||
<>
|
||||
<dt className="mt-1 text-muted-foreground">
|
||||
{t("usage.pricingModel", "计价模型")}
|
||||
</dt>
|
||||
<dd className="font-mono text-xs">
|
||||
{request.pricingModel}
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-muted-foreground">
|
||||
|
||||
@@ -49,6 +49,11 @@ const TITLE_THEMES: Record<AppType | "all", TitleTheme> = {
|
||||
accent: "text-amber-600 dark:text-amber-400",
|
||||
iconBg: "bg-amber-500/10",
|
||||
},
|
||||
"claude-desktop": {
|
||||
// 与 Claude Code 同属 Anthropic 品牌,用更深的 orange 区分
|
||||
accent: "text-orange-600 dark:text-orange-400",
|
||||
iconBg: "bg-orange-500/10",
|
||||
},
|
||||
codex: {
|
||||
// OpenAI/Codex 走黑白单色调;中性灰在深浅模式都能透出方块底色,
|
||||
// 不像纯黑 bg-black/10 在深色背景下会糊掉。
|
||||
|
||||
@@ -1373,6 +1373,7 @@
|
||||
"appFilter": {
|
||||
"all": "All",
|
||||
"claude": "Claude Code",
|
||||
"claude-desktop": "Claude Desktop",
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini",
|
||||
"opencode": "OpenCode"
|
||||
@@ -1403,6 +1404,7 @@
|
||||
"modelPricingDesc": "Configure token costs for each model",
|
||||
"noPricingData": "No pricing data. Click \"Add\" to add model pricing configuration.",
|
||||
"model": "Model",
|
||||
"pricingModel": "Pricing Model",
|
||||
"displayName": "Display Name",
|
||||
"inputCost": "Input Cost",
|
||||
"outputCost": "Output Cost",
|
||||
|
||||
@@ -1373,6 +1373,7 @@
|
||||
"appFilter": {
|
||||
"all": "すべて",
|
||||
"claude": "Claude Code",
|
||||
"claude-desktop": "Claude Desktop",
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini",
|
||||
"opencode": "OpenCode"
|
||||
@@ -1403,6 +1404,7 @@
|
||||
"modelPricingDesc": "各モデルのトークンコストを設定",
|
||||
"noPricingData": "料金データがありません。「追加」をクリックしてモデル料金を設定してください。",
|
||||
"model": "モデル",
|
||||
"pricingModel": "課金モデル",
|
||||
"displayName": "表示名",
|
||||
"inputCost": "入力コスト",
|
||||
"outputCost": "出力コスト",
|
||||
|
||||
@@ -1318,6 +1318,7 @@
|
||||
"appFilter": {
|
||||
"all": "全部",
|
||||
"claude": "Claude Code",
|
||||
"claude-desktop": "Claude Desktop",
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini",
|
||||
"opencode": "OpenCode"
|
||||
@@ -1348,6 +1349,7 @@
|
||||
"modelPricingDesc": "設定各模型的 Token 成本",
|
||||
"noPricingData": "暫無定價資料。點擊「新增」加入模型定價設定。",
|
||||
"model": "模型",
|
||||
"pricingModel": "計價模型",
|
||||
"displayName": "顯示名稱",
|
||||
"inputCost": "輸入成本",
|
||||
"outputCost": "輸出成本",
|
||||
|
||||
@@ -1373,6 +1373,7 @@
|
||||
"appFilter": {
|
||||
"all": "全部",
|
||||
"claude": "Claude Code",
|
||||
"claude-desktop": "Claude Desktop",
|
||||
"codex": "Codex",
|
||||
"gemini": "Gemini",
|
||||
"opencode": "OpenCode"
|
||||
@@ -1403,6 +1404,7 @@
|
||||
"modelPricingDesc": "配置各模型的 Token 成本",
|
||||
"noPricingData": "暂无定价数据。点击\"新增\"添加模型定价配置。",
|
||||
"model": "模型",
|
||||
"pricingModel": "计价模型",
|
||||
"displayName": "显示名称",
|
||||
"inputCost": "输入成本",
|
||||
"outputCost": "输出成本",
|
||||
|
||||
+16
-5
@@ -14,6 +14,8 @@ export interface RequestLog {
|
||||
appType: string;
|
||||
model: string;
|
||||
requestModel?: string;
|
||||
/** 写入时实际用于计价的模型名;路由接管 + request 计价模式下可能与 model 不同 */
|
||||
pricingModel?: string;
|
||||
costMultiplier: string;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
@@ -141,17 +143,26 @@ export interface UsageRangeSelection {
|
||||
/**
|
||||
* App types whose token usage is reliably collected by the proxy.
|
||||
*
|
||||
* The proxy has handlers for `claude-desktop` too, but in practice those
|
||||
* requests overwhelmingly fail (500/503) and contribute near-zero tokens, so
|
||||
* it is hidden from the Dashboard. `opencode` / `openclaw` / `hermes` have
|
||||
* no proxy handler at all — they appear only as managed apps elsewhere.
|
||||
* `claude-desktop` was previously hidden because its rows looked like pure
|
||||
* failure noise — that was an accounting bug: streaming/transform usage of
|
||||
* the Desktop gateway was logged under app_type "claude", leaving only
|
||||
* edge-case rows under "claude-desktop". The backend now attributes all
|
||||
* Desktop traffic to "claude-desktop", so it is a first-class filter option.
|
||||
* `opencode` / `openclaw` / `hermes` have no proxy handler at all — they
|
||||
* appear only as managed apps elsewhere.
|
||||
*/
|
||||
export type AppType = "claude" | "codex" | "gemini" | "opencode";
|
||||
export type AppType =
|
||||
| "claude"
|
||||
| "claude-desktop"
|
||||
| "codex"
|
||||
| "gemini"
|
||||
| "opencode";
|
||||
|
||||
export type AppTypeFilter = "all" | AppType;
|
||||
|
||||
export const KNOWN_APP_TYPES: ReadonlyArray<AppType> = [
|
||||
"claude",
|
||||
"claude-desktop",
|
||||
"codex",
|
||||
"gemini",
|
||||
"opencode",
|
||||
|
||||
Reference in New Issue
Block a user