This repository was archived by the owner on Sep 22, 2026. It is now read-only.
Repository navigation
feature: token usage stats in tui and web - #4
Merged
Merged
Conversation
added 7 commits
August 2, 2026 03:27
New src-rust/usage.rs: extract_usage() probes Anthropic > OpenAI standard > DeepSeek cache fields in order, taking the first that exists; SseUsageParser incrementally parses OpenAI (usage frame before [DONE]) and Anthropic (message_start + message_delta) SSE streams at any chunk boundary, tolerating garbage and missing events without panicking. All pure functions, no I/O; 12 unit tests covering extraction, stream parsing, arbitrary chunk splits and CRLF framing (42 total green). Also commit webui/dist/.gitkeep so the rust-embed derive compiles on a fresh checkout.
Issue 01 prefactor: move the aggregation loop out of get_stats() into a pure aggregate(entries, circuit, cooldown_ms, now_ms) function, and extract parse_entries(text) from the file-reading parse_logs(). get_stats() now only reads files and calls aggregate. Behaviour is identical to before — no new stat fields — verified by diff review plus 7 new unit tests (empty/single/ multi-entry aggregation, malformed-line skipping, circuit state with injected time). 49 tests green.
- stream_response tees the upstream stream: every chunk is forwarded unchanged while being fed into the SSE usage parser; the log line is appended when the stream ends (normal end, error, or client cut) - log_request rows gain optional promptTokens/completionTokens/ cachedTokens/conversationId fields (null when unavailable), extracted pure build_log_entry/append_log_line helpers - conversation id: x-conversation-id header wins, body conversation_id falls back (ADR-0002) - non-streaming OpenAI->Anthropic conversion path extracts usage from the buffered response and logs it with the row - StreamTee wrapper with single-shot finish callback; conversation_id_of and build_log_entry unit tests
heihei0299
pushed a commit
to heihei0299/pi-switch
that referenced
this pull request
Sep 11, 2026
承接 9d4903a:UI 只读固定集,后端零改动、野生落盘保留。 - GatewayPanel: setBackendDiff 前过滤到固定集(applyPreview 与冲突分支), handleApplyToPi 复用 isFixedGatewayProvider,pending_count/conflicts 保持后端原值。 - gatewayDiff: 固定 provider 名单与各自 API 契约收敛为单一常量 FIXED_GATEWAY_PROVIDERS / FIXED_GATEWAY_API;新增 filterFixedGatewayDiff。 - filterFixedGatewayDiff 不再 split("/"):后端 DiffGateway 发裸 key,改为 精确/前缀匹配,避免复刻导致原始 "/" bug 的复合键假设,也不会误收 pi-switch-chat-evil/x 这类前缀撞名的野生键。 - GatewayPanel.test: oc/chat、sup/main provider fixture 迁固定键 (groups 的 supplier/channel 保持不动),补 cpa 端到端与状态栏野生过滤用例, legacy 测试改为断言野生键不进 UI(对应锁死决策 CallmeLins#1/CallmeLins#4)。 webui: 33 files / 274 tests 通过;仅 src 的 tsc --noEmit 通过。
heihei0299
pushed a commit
to heihei0299/pi-switch
that referenced
this pull request
Sep 11, 2026
上一轮 review 的 Spec CallmeLins#5、Standards CallmeLins#1/CallmeLins#2、Spec CallmeLins#4。 - Spec CallmeLins#5:推理面的框架默认响应也走 OpenAI 信封 - 新增 inferenceNoRoute:/v1 未匹配路由与错误方法返回 {"error":{"message":"not found: <path>","type":"invalid_request_error"}} - 两个 router 的 gin.Recovery() 换成 CustomRecovery:/v1 panic → 推理信封, /api panic → 管理面字符串信封(此前都是空 body) - Standards CallmeLins#1:新增 internal/server/error_envelope.go 作为两种信封的单一 owner (managementError / inferenceError / 两个 unauthorized / 两个 recovery / inferenceNoRoute);proxy 里 21 处内联嵌套信封、config loader、notImplemented、 failover 全部改走 helper,嵌套字面量只剩 inferenceError 内部一处 - Standards CallmeLins#2:basicAuthMiddleware 改为接收 func() gin.H,不再跨请求共享可变 map - Spec CallmeLins#4:恢复完整字段路径。ProviderProfile.UnmarshalJSON 在解码失败时回查 upstream 下标,ParseConfig 逐 profile 解码以带上 profile 名;happy path 只解析 一次,仅出错时重走。错误现在是 profiles.p: upstreams[1]: exposedModels must not be null - 测试:新增 404/panic 契约用例(推理面两个信封、管理面 panic 字符串), 并把 null 用例收紧为断言 profiles.p + upstreams[0] + exposedModels 未做(判断项):管理面既有的 ~60 处 `gin.H{"error": <string>}` 仍内联;形状平凡 且已全部合规,未做机械替换以免 churn。少数错误信息里的类型名会显示 providerProfileAlias/upstreamAlias(Go alias 惯用写法的代价),仅影响文案。 验证:gofmt -l / go vet 无输出;scripts/test-limited.sh go 全绿;契约用例 (/v1 404、/v1 panic、/api panic、/v1 401、/api 401、config 500)全部通过。 review-fixes-3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.