mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 13:55:50 +00:00
feat: 添加 Provider Registry、StatusLine、Cache Stats 和其他增强
- providerRegistry: OpenAI 兼容 provider 切换(Cerebras/Groq/DeepSeek/Qwen) - StatusLine: 增强状态栏(缓存命中率、TTL 倒计时、自定义 shell 命令) - cacheStats: 缓存命中率和 token 签名追踪 - ultrareviewPreflight: 代码审查预检服务 - SkillsMenu/filterSkills: 技能菜单过滤增强 - MagicDocs/langfuse prompts: 提示词更新 - claude.ts: API 客户端更新 Co-Authored-By: glm-5-turbo <zai-org@claude-code-best.win>
This commit is contained in:
92
src/utils/cacheStatsState.ts
Normal file
92
src/utils/cacheStatsState.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* In-memory singleton that tracks cache hit-rate state for the current session.
|
||||
*
|
||||
* Call `onResponse(usage)` every time a new API response arrives.
|
||||
* The singleton compares the token signature of the new response against the
|
||||
* previously seen signature. When it changes (= a new API call completed),
|
||||
* it resets `lastResetAt` to Date.now() and asynchronously persists state so
|
||||
* that a future session can show the TTL countdown immediately on startup.
|
||||
*/
|
||||
|
||||
import type { CacheUsage, CacheStatsState } from './cacheStats.js'
|
||||
import {
|
||||
computeHitRate,
|
||||
tokenSignature,
|
||||
getStateFilePath,
|
||||
readState,
|
||||
writeStateAtomic,
|
||||
} from './cacheStats.js'
|
||||
|
||||
interface MemState {
|
||||
signature: string | null
|
||||
lastResetAt: number | null
|
||||
lastHitRate: number | null
|
||||
}
|
||||
|
||||
let memState: MemState = {
|
||||
signature: null,
|
||||
lastResetAt: null,
|
||||
lastHitRate: null,
|
||||
}
|
||||
|
||||
let sessionId: string | null = null
|
||||
|
||||
/**
|
||||
* Must be called once at session start so the singleton knows which state file
|
||||
* to persist to and can pre-load the last known state.
|
||||
*/
|
||||
export async function initCacheStatsState(sid: string): Promise<void> {
|
||||
sessionId = sid
|
||||
const filePath = getStateFilePath(sid)
|
||||
const persisted = await readState(filePath)
|
||||
// Pre-load persisted values so the UI can show fallback immediately
|
||||
memState = {
|
||||
signature: persisted.signature,
|
||||
lastResetAt: persisted.lastResetAt,
|
||||
lastHitRate: persisted.lastHitRate,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever a new assistant response is received with usage data.
|
||||
* Returns the updated in-memory state.
|
||||
*/
|
||||
export function onResponse(usage: CacheUsage): MemState {
|
||||
const sig = tokenSignature(usage)
|
||||
const hitRate = computeHitRate(usage)
|
||||
|
||||
if (sig !== memState.signature) {
|
||||
// New API response — reset the TTL clock
|
||||
memState = {
|
||||
signature: sig,
|
||||
lastResetAt: Date.now(),
|
||||
lastHitRate: hitRate,
|
||||
}
|
||||
// Persist asynchronously; intentionally fire-and-forget
|
||||
if (sessionId !== null) {
|
||||
const filePath = getStateFilePath(sessionId)
|
||||
const toWrite: CacheStatsState = {
|
||||
version: 1,
|
||||
signature: sig,
|
||||
lastResetAt: memState.lastResetAt,
|
||||
lastHitRate: hitRate,
|
||||
}
|
||||
void writeStateAtomic(filePath, toWrite)
|
||||
}
|
||||
}
|
||||
|
||||
return { ...memState }
|
||||
}
|
||||
|
||||
/** Read current in-memory state without triggering a response update. */
|
||||
export function getCacheStatsState(): MemState {
|
||||
return { ...memState }
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset singleton — used in tests to isolate test runs.
|
||||
*/
|
||||
export function _resetCacheStatsStateForTest(): void {
|
||||
memState = { signature: null, lastResetAt: null, lastHitRate: null }
|
||||
sessionId = null
|
||||
}
|
||||
Reference in New Issue
Block a user