配置: - 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 不一致,已对齐
49 lines
1.9 KiB
Rust
49 lines
1.9 KiB
Rust
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)
|
||
}
|
||
}
|