style(tools, llm): 统一导入顺序与代码格式
This commit is contained in:
+32
-16
@@ -73,10 +73,7 @@ impl CompactState {
|
||||
|
||||
/// 粗略估计消息列表的 token 数(基于字符数,4 字符 ≈ 1 token)。
|
||||
pub fn estimate_message_tokens(messages: &[Message]) -> u32 {
|
||||
messages
|
||||
.iter()
|
||||
.map(estimate_single_message_tokens)
|
||||
.sum()
|
||||
messages.iter().map(estimate_single_message_tokens).sum()
|
||||
}
|
||||
|
||||
fn estimate_single_message_tokens(msg: &Message) -> u32 {
|
||||
@@ -99,9 +96,7 @@ fn estimate_block_tokens(block: &ContentBlock) -> u32 {
|
||||
match block {
|
||||
ContentBlock::Text { text } => estimate_text_tokens(text),
|
||||
ContentBlock::Thinking { text, .. } => estimate_text_tokens(text),
|
||||
ContentBlock::ToolUse { input, .. } => {
|
||||
estimate_text_tokens(&input.to_string())
|
||||
}
|
||||
ContentBlock::ToolUse { input, .. } => estimate_text_tokens(&input.to_string()),
|
||||
ContentBlock::ToolResult { content, .. } => estimate_content_blocks_tokens(content),
|
||||
// ponytail: Image / Audio / File / Extension 在 IR 中固定估算。
|
||||
// 无文本的视觉/音频 block 用兜底估算,避免 token 计数膨胀。
|
||||
@@ -148,14 +143,25 @@ pub fn microcompact(messages: &mut [Message], keep_recent: usize) -> u32 {
|
||||
|
||||
// 第一遍:计算可释放 token(仅非错误 ToolResult)
|
||||
for msg in &messages[..prune_start] {
|
||||
if matches!(msg, Message::ToolResult { is_error: false, .. }) {
|
||||
if matches!(
|
||||
msg,
|
||||
Message::ToolResult {
|
||||
is_error: false,
|
||||
..
|
||||
}
|
||||
) {
|
||||
freed_tokens += estimate_single_message_tokens(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// 第二遍:替换内容(仅非错误 ToolResult)
|
||||
for msg in &mut messages[..prune_start] {
|
||||
if let Message::ToolResult { content, is_error: false, .. } = msg {
|
||||
if let Message::ToolResult {
|
||||
content,
|
||||
is_error: false,
|
||||
..
|
||||
} = msg
|
||||
{
|
||||
*content = vec![ContentBlock::Text {
|
||||
text: "[pruned]".to_string(),
|
||||
}];
|
||||
@@ -177,13 +183,15 @@ mod tests {
|
||||
fn estimate_message_tokens_handles_all_variants() {
|
||||
let messages = vec![
|
||||
Message::System {
|
||||
content: vec![ContentBlock::Text {
|
||||
text: "sys".into(),
|
||||
}],
|
||||
content: vec![ContentBlock::Text { text: "sys".into() }],
|
||||
},
|
||||
Message::user_text("hi"),
|
||||
Message::assistant("ans"),
|
||||
Message::user_image("b64", "image/png", crate::llm::types::shared::ImageDetail::Auto),
|
||||
Message::user_image(
|
||||
"b64",
|
||||
"image/png",
|
||||
crate::llm::types::shared::ImageDetail::Auto,
|
||||
),
|
||||
Message::tool_result("call_1", "tool res", false),
|
||||
];
|
||||
let tokens = estimate_message_tokens(&messages);
|
||||
@@ -205,7 +213,10 @@ mod tests {
|
||||
assert!(freed > 0);
|
||||
assert_eq!(messages.len(), before_len); // 只改内容,不删消息
|
||||
// 索引 1 是被压缩的 ToolResult
|
||||
if let Message::ToolResult { content, is_error, .. } = &messages[1] {
|
||||
if let Message::ToolResult {
|
||||
content, is_error, ..
|
||||
} = &messages[1]
|
||||
{
|
||||
assert_eq!(content.len(), 1);
|
||||
assert!(matches!(&content[0], ContentBlock::Text { text } if text == "[pruned]"));
|
||||
assert!(!is_error);
|
||||
@@ -228,9 +239,14 @@ mod tests {
|
||||
assert_eq!(freed, 0); // 错误 ToolResult 不计入
|
||||
assert_eq!(messages.len(), before_len);
|
||||
// 错误信息保留完整
|
||||
if let Message::ToolResult { content, is_error, .. } = &messages[1] {
|
||||
if let Message::ToolResult {
|
||||
content, is_error, ..
|
||||
} = &messages[1]
|
||||
{
|
||||
assert!(is_error);
|
||||
assert!(matches!(&content[0], ContentBlock::Text { text } if text.contains("backend down")));
|
||||
assert!(
|
||||
matches!(&content[0], ContentBlock::Text { text } if text.contains("backend down"))
|
||||
);
|
||||
} else {
|
||||
panic!("expected ToolResult at index 1");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user