优化: UI/UX遗留批(审计/AI命令层/前端组件,会话前基线收尾)
- AuditLog +298(筛选/详情/i18n)+ audit 后端 record/mod - AI 命令层:generate_image +81 / fetch_url / fetch_search / skills / tool_registry / tools/file / provider / conversation - 前端组件:AiChat/TopBar/ConversationSidebar/GitChanges/ApprovalPopup/Dashboard/ProjectDetail 等 30+ + composables + i18n - 诊断文档: aichat历史会话实证诊断-2026-08-04 + project_soft_delete 测试
This commit is contained in:
@@ -566,8 +566,18 @@ fn find_obscura() -> Option<String> {
|
||||
/// 从 markdown 启发式提取 title:首个 `# 一级标题` 或首个非空文本行(≤120 chars)。
|
||||
/// obscura dump markdown 无独立 title 字段,此为最佳近似(静态管线有 <title>,此函数仅 render 分支用)。
|
||||
fn extract_title_from_markdown(md: &str) -> Option<String> {
|
||||
// 代码块围栏状态:true=当前在 ``` 代码块内,块内行全部跳过(不当作标题)。
|
||||
// 修复:原实现只跳过 ``` 围栏行本身,块内容行(如 "code block")会被误当标题。
|
||||
let mut in_code_block = false;
|
||||
for line in md.lines() {
|
||||
let t = line.trim();
|
||||
if t.starts_with("```") {
|
||||
in_code_block = !in_code_block; // 切换围栏状态(``` 开或闭)
|
||||
continue;
|
||||
}
|
||||
if in_code_block {
|
||||
continue; // 代码块内:跳过
|
||||
}
|
||||
if t.is_empty() {
|
||||
continue;
|
||||
}
|
||||
@@ -579,10 +589,13 @@ fn extract_title_from_markdown(md: &str) -> Option<String> {
|
||||
}
|
||||
}
|
||||
// 否则取首个非空、非表格/代码块的行(去掉 markdown 强调前缀)
|
||||
if !t.starts_with('|') && !t.starts_with("```") {
|
||||
if !t.starts_with('|') {
|
||||
let cleaned: String = t.trim_start_matches(|c: char| c == '*' || c == '-').trim().to_string();
|
||||
if !cleaned.is_empty() && cleaned.chars().count() <= 120 {
|
||||
return Some(cleaned);
|
||||
// 超长行(>120)截断到 120 作标题(innerText 纯文本无结构时首行即正文,
|
||||
// 原实现整行 >120 直接跳过 → title 为 None;截断保留可读标题)。
|
||||
if !cleaned.is_empty() {
|
||||
let sliced: String = cleaned.chars().take(120).collect();
|
||||
return Some(sliced);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -815,8 +828,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_substantial_content_real_markdown_passes() {
|
||||
// 真实正文:600 chars,无空壳标记,应判有实质内容
|
||||
let md = "# 异步编程指南\n\n这是一篇关于 Rust 异步编程的详细指南。\n".repeat(15);
|
||||
// 真实正文:>500 chars(达到 has_substantial_content 的 500 字符下限阈值),
|
||||
// 无空壳标记,应判有实质内容。原测试 md 仅 494 chars(<500)被前置阈值拦截误判空壳。
|
||||
let md = "# 异步编程指南\n\n这是一篇关于 Rust 异步编程的详细指南。异步与同步的区别在于并发模型。\n".repeat(15);
|
||||
assert!(has_substantial_content(&md));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user