PicoBot/src/topic_description.rs
oudecheng cda14360af chore: 建立工程化基线(rustfmt + clippy + CI + eslint + prettier)
配置:
- rustfmt.toml: 固化 max_width=100 / 4 空格缩进,cargo fmt 全量格式化
- Cargo.toml: 配置 [lints.rust] 与 [lints.clippy] 渐进式规则
- .github/workflows/ci.yml: Rust(fmt+clippy+test) + 前端(eslint+tsc+test) 双平台 CI
- Makefile: 新增 check/fmt/fix 目标,clippy 对齐 --all-targets --all-features
- web: eslint flat config + prettier 配置 + package.json 脚本与依赖
- src/main.rs: loop→while 修复 clippy::never_loop

对抗性审查发现并修复:
- eslint 缺 caughtErrorsIgnorePattern 导致 catch(_) 误报为 error
- 前端 lint 未接入 CI,现已补上 Lint 步骤
- Makefile 与 CI 的 clippy flags 不一致,已对齐
2026-08-03 23:24:02 +08:00

49 lines
1.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::providers::{ChatCompletionRequest, LLMProvider, Message};
pub async fn generate_topic_description(
provider: &dyn LLMProvider,
first_user_message: &str,
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
let system_prompt = "你是一个话题摘要助手。请根据用户的第一句话用简短的词语不超过15字描述这个对话的主题或意图。只输出描述内容不要任何解释、标点或前缀。";
let user_prompt = format!("用户消息:{}", first_user_message);
let request = ChatCompletionRequest {
messages: vec![Message::system(system_prompt), Message::user(user_prompt)],
temperature: Some(0.0),
max_tokens: Some(1024), // 给 reasoning 模型留足思考空间
tools: None,
};
let response = provider.chat(request).await?;
let description = response.content.trim().to_string();
if description.is_empty() {
// 回退reasoning 模型有时把所有 token 都消耗在推理上content 为空
// 此时尝试从 reasoning_content 中提取最后一行有意义的内容作为描述
if let Some(ref reasoning) = response.reasoning_content {
let fallback: String = reasoning
.lines()
.rev()
.find(|line| {
let trimmed = line.trim();
!trimmed.is_empty() && trimmed.len() <= 50
})
.unwrap_or("")
.trim()
.to_string();
if !fallback.is_empty() {
let truncated: String = fallback.chars().take(50).collect();
return Ok(truncated);
}
}
return Err("LLM returned empty description".into());
}
if description.len() > 50 {
Ok(description.chars().take(50).collect())
} else {
Ok(description)
}
}