mirror of
https://github.com/musistudio/claude-code-router.git
synced 2026-07-09 17:18:24 +00:00
189 lines
4.9 KiB
TypeScript
189 lines
4.9 KiB
TypeScript
import type {
|
|
ProviderAccountSnapshot,
|
|
UsageComparisonRow,
|
|
UsageStatsRange,
|
|
UsageStatsSnapshot,
|
|
UsageTotals
|
|
} from "../../packages/core/src/contracts/app.ts";
|
|
|
|
export function installBrowserGlobals() {
|
|
const localStorage = {
|
|
getItem: () => null,
|
|
removeItem: () => undefined,
|
|
setItem: () => undefined
|
|
};
|
|
const windowMock = {
|
|
addEventListener: () => undefined,
|
|
cancelAnimationFrame: () => undefined,
|
|
ccr: {
|
|
closeTray: () => undefined,
|
|
quitApp: () => undefined,
|
|
setTrayDetailOpen: () => undefined,
|
|
showMainWindow: () => undefined
|
|
},
|
|
clearInterval: () => undefined,
|
|
localStorage,
|
|
matchMedia: () => ({
|
|
addEventListener: () => undefined,
|
|
matches: false,
|
|
removeEventListener: () => undefined
|
|
}),
|
|
removeEventListener: () => undefined,
|
|
requestAnimationFrame: () => 0,
|
|
setInterval: () => 0
|
|
};
|
|
|
|
Object.defineProperty(globalThis, "window", {
|
|
configurable: true,
|
|
value: windowMock
|
|
});
|
|
Object.defineProperty(globalThis, "document", {
|
|
configurable: true,
|
|
value: {
|
|
body: {
|
|
classList: {
|
|
add: () => undefined,
|
|
remove: () => undefined
|
|
},
|
|
style: {}
|
|
},
|
|
documentElement: {
|
|
lang: "en"
|
|
}
|
|
}
|
|
});
|
|
Object.defineProperty(globalThis, "navigator", {
|
|
configurable: true,
|
|
value: {
|
|
language: "en-US",
|
|
languages: ["en-US"]
|
|
}
|
|
});
|
|
}
|
|
|
|
export function usageTotals(patch: Partial<UsageTotals> = {}): UsageTotals {
|
|
return {
|
|
avgDurationMs: 842,
|
|
cacheRatio: 0.24,
|
|
cacheTokens: 2400,
|
|
costUsd: 1.23,
|
|
errorCount: 2,
|
|
inputTokens: 6200,
|
|
outputTokens: 3400,
|
|
requestCount: 128,
|
|
successRate: 0.984,
|
|
totalTokens: 12000,
|
|
...patch
|
|
};
|
|
}
|
|
|
|
export function usageRow(key: string, label: string, patch: Partial<UsageComparisonRow> = {}): UsageComparisonRow {
|
|
return {
|
|
...usageTotals(),
|
|
caption: "Test usage row",
|
|
key,
|
|
label,
|
|
maxShare: 0.5,
|
|
...patch
|
|
};
|
|
}
|
|
|
|
export function usageStats(range: UsageStatsRange = "30d", patch: Partial<UsageStatsSnapshot> = {}): UsageStatsSnapshot {
|
|
const series = Array.from({ length: 8 }, (_, index) => {
|
|
const totalTokens = 1000 + index * 250;
|
|
const requestCount = 8 + index;
|
|
return {
|
|
...usageTotals({
|
|
cacheRatio: 0.1 + index * 0.02,
|
|
cacheTokens: 120 + index * 30,
|
|
errorCount: index % 4 === 0 ? 1 : 0,
|
|
inputTokens: 560 + index * 120,
|
|
outputTokens: 320 + index * 80,
|
|
requestCount,
|
|
successRate: index % 4 === 0 ? 0.92 : 1,
|
|
totalTokens
|
|
}),
|
|
bucket: `2026-06-${String(20 + index).padStart(2, "0")}T00:00:00.000Z`,
|
|
label: `6/${20 + index}`
|
|
};
|
|
});
|
|
const models = [
|
|
usageRow("model:gpt-4.1", "gpt-4.1", { maxShare: 0.62, model: "gpt-4.1", provider: "openai", totalTokens: 7200 }),
|
|
usageRow("model:claude-sonnet", "claude-sonnet", { maxShare: 0.38, model: "claude-sonnet", provider: "anthropic", totalTokens: 4800 })
|
|
];
|
|
|
|
return {
|
|
clientModels: [
|
|
usageRow("client:claude-code", "Claude Code", { client: "claude-code", model: "gpt-4.1", provider: "openai", totalTokens: 6800 }),
|
|
usageRow("client:codex", "Codex", { client: "codex", model: "claude-sonnet", provider: "anthropic", totalTokens: 5200 })
|
|
],
|
|
generatedAt: "2026-06-30T00:00:00.000Z",
|
|
models,
|
|
providerModels: [
|
|
usageRow("provider:openai", "OpenAI", { credentialId: "primary", model: "gpt-4.1", provider: "openai", totalTokens: 7200 }),
|
|
usageRow("provider:anthropic", "Anthropic", { credentialId: "secondary", model: "claude-sonnet", provider: "anthropic", totalTokens: 4800 })
|
|
],
|
|
range,
|
|
recentRequests: [],
|
|
series,
|
|
totals: usageTotals(),
|
|
...patch
|
|
};
|
|
}
|
|
|
|
export function accountSnapshots(): ProviderAccountSnapshot[] {
|
|
return [
|
|
{
|
|
credentialId: "primary",
|
|
credentialLabel: "Primary Key",
|
|
meters: [
|
|
{
|
|
id: "5h",
|
|
kind: "quota",
|
|
label: "5h quota",
|
|
limit: 100,
|
|
remaining: 42,
|
|
unit: "requests",
|
|
window: "5h"
|
|
},
|
|
{
|
|
id: "weekly",
|
|
kind: "quota",
|
|
label: "Weekly quota",
|
|
limit: 500,
|
|
remaining: 310,
|
|
unit: "requests",
|
|
window: "weekly"
|
|
},
|
|
{
|
|
id: "balance",
|
|
kind: "balance",
|
|
label: "Cash balance",
|
|
remaining: 12.34,
|
|
unit: "USD"
|
|
}
|
|
],
|
|
provider: "openai",
|
|
source: "standard",
|
|
status: "warning",
|
|
updatedAt: "2026-06-30T00:00:00.000Z"
|
|
},
|
|
{
|
|
credentialId: "secondary",
|
|
credentialLabel: "Secondary Key",
|
|
meters: [
|
|
{
|
|
id: "balance",
|
|
kind: "balance",
|
|
label: "Credit balance",
|
|
remaining: 88,
|
|
unit: "USD"
|
|
}
|
|
],
|
|
provider: "anthropic",
|
|
source: "standard",
|
|
status: "ok",
|
|
updatedAt: "2026-06-30T00:00:00.000Z"
|
|
}
|
|
];
|
|
}
|