mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-09-24 23:10:56 +08:00
fix(flow-monitor): 修复 Kiro 请求 Token 显示为 0 的问题 (#44)
- 在 CWParsedResponse 中添加 estimate_tokens() 方法 - 基于 context_usage_percentage 估算 input_tokens (100% = 200k tokens) - 基于响应内容长度估算 output_tokens (约 4 字符 = 1 token) - 修复 api.rs 中所有调用 build_llm_response 时传入 None 的位置 - 版本更新至 0.17.12
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "proxycast",
|
||||
"private": true,
|
||||
"version": "0.17.11",
|
||||
"version": "0.17.12",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Generated
+1
-1
@@ -3377,7 +3377,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proxycast"
|
||||
version = "0.17.11"
|
||||
version = "0.17.12"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "proxycast"
|
||||
version = "0.17.11"
|
||||
version = "0.17.12"
|
||||
description = "AI API Proxy Desktop App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1232,8 +1232,13 @@ pub async fn chat_completions(
|
||||
// 完成 Flow 捕获并检查响应拦截(重试成功)
|
||||
// **Validates: Requirements 2.1, 2.5**
|
||||
if let Some(fid) = &flow_id {
|
||||
let llm_response =
|
||||
build_llm_response(200, &parsed.content, None);
|
||||
let (est_input, est_output) =
|
||||
parsed.estimate_tokens();
|
||||
let llm_response = build_llm_response(
|
||||
200,
|
||||
&parsed.content,
|
||||
Some((est_input, est_output)),
|
||||
);
|
||||
|
||||
// 检查是否需要拦截响应
|
||||
if let Some(modified_response) =
|
||||
@@ -1896,7 +1901,12 @@ pub async fn anthropic_messages(
|
||||
// 完成 Flow 捕获并检查响应拦截(流式)
|
||||
// **Validates: Requirements 2.1, 2.5**
|
||||
if let Some(fid) = &flow_id {
|
||||
let llm_response = build_llm_response(200, &parsed.content, None);
|
||||
let (est_input, est_output) = parsed.estimate_tokens();
|
||||
let llm_response = build_llm_response(
|
||||
200,
|
||||
&parsed.content,
|
||||
Some((est_input, est_output)),
|
||||
);
|
||||
|
||||
// 检查是否需要拦截响应
|
||||
if let Some(modified_response) = check_response_intercept(
|
||||
@@ -1955,7 +1965,12 @@ pub async fn anthropic_messages(
|
||||
// 完成 Flow 捕获并检查响应拦截(非流式)
|
||||
// **Validates: Requirements 2.1, 2.5**
|
||||
if let Some(fid) = &flow_id {
|
||||
let llm_response = build_llm_response(200, &parsed.content, None);
|
||||
let (est_input, est_output) = parsed.estimate_tokens();
|
||||
let llm_response = build_llm_response(
|
||||
200,
|
||||
&parsed.content,
|
||||
Some((est_input, est_output)),
|
||||
);
|
||||
|
||||
// 检查是否需要拦截响应
|
||||
if let Some(modified_response) = check_response_intercept(
|
||||
@@ -2080,8 +2095,13 @@ pub async fn anthropic_messages(
|
||||
// 完成 Flow 捕获并检查响应拦截(重试成功)
|
||||
// **Validates: Requirements 2.1, 2.5**
|
||||
if let Some(fid) = &flow_id {
|
||||
let llm_response =
|
||||
build_llm_response(200, &parsed.content, None);
|
||||
let (est_input, est_output) =
|
||||
parsed.estimate_tokens();
|
||||
let llm_response = build_llm_response(
|
||||
200,
|
||||
&parsed.content,
|
||||
Some((est_input, est_output)),
|
||||
);
|
||||
|
||||
// 检查是否需要拦截响应
|
||||
if let Some(modified_response) =
|
||||
|
||||
@@ -21,6 +21,30 @@ pub struct CWParsedResponse {
|
||||
pub context_usage_percentage: f64,
|
||||
}
|
||||
|
||||
impl CWParsedResponse {
|
||||
/// 估算 Token 使用量
|
||||
///
|
||||
/// 基于响应内容长度和上下文使用百分比估算 Token 数量:
|
||||
/// - output_tokens: 基于响应内容长度(约 4 字符 = 1 token)
|
||||
/// - input_tokens: 基于 context_usage_percentage(假设 100% = 200k tokens)
|
||||
///
|
||||
/// # 返回
|
||||
/// (input_tokens, output_tokens) 元组
|
||||
pub fn estimate_tokens(&self) -> (u32, u32) {
|
||||
// 估算 output tokens: 基于响应内容长度 (约 4 字符 = 1 token)
|
||||
let mut output_tokens: u32 = (self.content.len() / 4) as u32;
|
||||
for tc in &self.tool_calls {
|
||||
output_tokens += (tc.function.arguments.len() / 4) as u32;
|
||||
}
|
||||
|
||||
// 从 context_usage_percentage 估算 input tokens
|
||||
// 假设 100% = 200k tokens (Claude 的上下文窗口)
|
||||
let input_tokens = ((self.context_usage_percentage / 100.0) * 200000.0) as u32;
|
||||
|
||||
(input_tokens, output_tokens)
|
||||
}
|
||||
}
|
||||
|
||||
/// 安全截断字符串到指定字符数,避免 UTF-8 边界问题
|
||||
pub fn safe_truncate(s: &str, max_chars: usize) -> String {
|
||||
let chars: Vec<char> = s.chars().collect();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "ProxyCast",
|
||||
"version": "0.17.11",
|
||||
"version": "0.17.12",
|
||||
"identifier": "com.proxycast.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
Reference in New Issue
Block a user