feat(rag): harden post-LightRAG runtime

Retire legacy OCR/media/evidence fallbacks, add local-folder event bus and Page Aggregate guards, and archive completed design checklists.

Validation: cargo test -p mnote-web -- --test-threads=1; cargo test --workspace -- --test-threads=1; git diff --check; codegraph sync .; codegraph_status.
This commit is contained in:
lix-2026
2026-06-07 10:35:21 +08:00
parent 22a92edcda
commit 9551d4c1dc
59 changed files with 4053 additions and 5249 deletions
@@ -130,6 +130,8 @@ fn compact_query_result_for_agent(payload: Value) -> Value {
"references": references,
"citations": citations,
"sourceScope": payload.get("sourceScope").cloned().unwrap_or(Value::Array(Vec::new())),
"sourceScopeMode": payload.get("sourceScopeMode").cloned().unwrap_or_else(|| json!("post_filter_mapped_references")),
"rawScopeFiltered": payload.get("rawScopeFiltered").cloned().unwrap_or(Value::Bool(false)),
"rawStatus": payload.pointer("/raw/status").cloned().unwrap_or(Value::Null),
"rawMessage": payload.pointer("/raw/message").cloned().unwrap_or(Value::Null),
"rawMetadata": payload.pointer("/raw/metadata").cloned().unwrap_or(Value::Null),
@@ -155,3 +157,43 @@ fn compact_reference_for_agent(reference: &Value) -> Value {
"citationUrl": reference.get("citationUrl").cloned().unwrap_or(Value::Null),
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compact_query_result_marks_post_filter_scope_without_raw_chunks() {
let payload = json!({
"ok": true,
"provider": "lightrag",
"sourceScope": ["docs/a.md"],
"sourceScopeMode": "post_filter_mapped_references",
"rawScopeFiltered": false,
"raw": {
"status": "success",
"chunks": [{"content": "raw chunk must not be exposed to agent"}],
"metadata": {"count": 1}
},
"references": [{
"sourceRootRelativePath": "docs/a.md",
"quote": "scoped quote",
"locatorDegraded": true,
"citationMarkdown": "[来源定位降级:docs/a.md](/documents/local-md:docs~2Fa.md)"
}]
});
let compact = compact_query_result_for_agent(payload);
assert_eq!(
compact["sourceScopeMode"].as_str(),
Some("post_filter_mapped_references")
);
assert_eq!(compact["rawScopeFiltered"].as_bool(), Some(false));
assert!(compact.get("raw").is_none());
assert!(compact.get("chunks").is_none());
assert_eq!(
compact["references"][0]["sourceRootRelativePath"].as_str(),
Some("docs/a.md")
);
}
}
@@ -290,6 +290,7 @@ fn doc_find_tool() -> Value {
})
}
// 旧 evidence 工具仅保留为历史对照;当前 manifest() 不注册这些工具,资料库问答走 mnote.knowledge_rag.*。
#[allow(dead_code)]
fn evidence_search_tool() -> Value {
let mut properties = base_identity_properties();
@@ -434,13 +435,13 @@ fn knowledge_rag_query_tool() -> Value {
json!({
"type": "array",
"items": { "type": "string" },
"description": "可选 MNote workspace 相对路径范围;可传文件或目录返回 references 会限制在这些来源内"
"description": "可选 MNote workspace 相对路径范围;可传文件或目录。当前语义是 LightRAG provider 检索后,MNote 只过滤返回 referencesprovider raw 仍可能是全局结果"
}),
);
}
json!({
"name": "mnote.knowledge_rag.query",
"description": "向 LightRAG 资料库提问,返回 provider 原始结果和经 MNote registry 映射的引用。",
"description": "向 LightRAG 资料库提问,返回 provider 原始结果和经 MNote registry 映射、sourcePaths 后过滤的引用。",
"schemaVersion": TOOL_SCHEMA_VERSION,
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
"status": "available",
@@ -477,6 +478,7 @@ fn knowledge_rag_open_reference_tool() -> Value {
})
}
// 旧 local index agent 工具仅保留为历史对照;当前 manifest() 不注册这些工具。
#[allow(dead_code)]
fn index_status_tool() -> Value {
let mut properties = base_identity_properties();