feat(rag): replace LiteParse flows with LightRAG provider

This commit is contained in:
lix-2026
2026-06-07 01:10:31 +08:00
parent f46c2fb5d0
commit 1f25364374
40 changed files with 7232 additions and 2350 deletions
@@ -3,7 +3,7 @@ use crate::app::AppState;
use crate::context::RequestContext;
use crate::error::WebError;
use crate::hermes_tools::{
artifact, block, context_tools, doc, evidence, index, manifest, onlyoffice_live, page,
artifact, block, context_tools, doc, evidence, knowledge_rag, manifest, onlyoffice_live, page,
resource, skill, ToolCallInput,
};
use axum::extract::{Extension, Query, State};
@@ -362,14 +362,27 @@ pub(crate) async fn execute_mnote_tool_call(
"mnote.doc.find" => doc::doc_find(&state, &context, &input).await,
"docs_search" => evidence::legacy_docs_search(&state, &context, &input).await,
"docs_read" => evidence::legacy_docs_read(&state, &context, &input).await,
"mnote.evidence.search" => evidence::evidence_search(&state, &context, &input).await,
"mnote.evidence.read" => evidence::evidence_read(&state, &context, &input).await,
"mnote.evidence.open" => evidence::evidence_open(&state, &context, &input).await,
"mnote.index.status" => index::index_status(&state, &context, &input).await,
"mnote.index.refresh" => index::index_refresh(&state, &context, &input).await,
"mnote.index.update_settings" => {
index::index_update_settings(&state, &context, &input).await
"mnote.evidence.search" | "mnote.evidence.read" | "mnote.evidence.open" => {
Err(WebError::new(
StatusCode::GONE,
"mnote_evidence_tools_retired",
"旧 evidence / LiteParse tools 已退役;请使用 mnote.knowledge_rag.query/open_reference",
)
.with_context(&context))
}
"mnote.knowledge_rag.status" => knowledge_rag::status(&state, &context, &input).await,
"mnote.knowledge_rag.query" => knowledge_rag::query(&state, &context, &input).await,
"mnote.knowledge_rag.open_reference" => {
knowledge_rag::open_reference(&state, &context, &input).await
}
"mnote.index.status" | "mnote.index.refresh" | "mnote.index.update_settings" => Err(
WebError::new(
StatusCode::GONE,
"mnote_index_tools_retired",
"旧本地索引 tools 已退役;资料索引统一由 LightRAG provider 处理",
)
.with_context(&context),
),
"mnote.doc.plan_update" => doc::plan_update(&state, &context, &input).await,
"mnote.block.fetch" => block::block_fetch(&state, &context, &input).await,
"mnote.block.replace" => block::block_replace(&state, &context, &input).await,
@@ -709,6 +722,9 @@ fn is_read_tool(tool_name: &str) -> bool {
| "mnote.evidence.search"
| "mnote.evidence.read"
| "mnote.evidence.open"
| "mnote.knowledge_rag.status"
| "mnote.knowledge_rag.query"
| "mnote.knowledge_rag.open_reference"
| "mnote.index.status"
| "mnote.index.refresh"
| "mnote.block.fetch"
@@ -738,6 +754,9 @@ fn is_evidence_receipt_tool(tool_name: &str) -> bool {
| "mnote.evidence.search"
| "mnote.evidence.read"
| "mnote.evidence.open"
| "mnote.knowledge_rag.status"
| "mnote.knowledge_rag.query"
| "mnote.knowledge_rag.open_reference"
)
}
@@ -1604,23 +1623,29 @@ mod tests {
let payload: Value = serde_json::from_slice(&body).expect("json");
let manifest = &payload["manifest"];
let capabilities = manifest["capabilities"].as_array().expect("capabilities");
assert!(capabilities
assert!(!capabilities
.iter()
.any(|capability| capability["id"] == "mnote-local-index"));
assert!(capabilities
.iter()
.any(|capability| capability["id"] == "mnote-knowledge-rag"));
assert!(capabilities
.iter()
.any(|capability| capability["id"] == "mnote-onlyoffice-live"));
let tools = manifest["tools"].as_array().expect("tools");
let index_status = tools
assert!(!tools
.iter()
.find(|tool| tool["name"] == "mnote.index.status")
.expect("index status tool");
assert!(index_status["capabilityIds"]
.any(|tool| tool["name"] == "mnote.index.status"));
let knowledge_rag_query = tools
.iter()
.find(|tool| tool["name"] == "mnote.knowledge_rag.query")
.expect("knowledge rag query tool");
assert!(knowledge_rag_query["capabilityIds"]
.as_array()
.expect("index capability ids")
.expect("knowledge rag capability ids")
.iter()
.any(|id| id == "mnote-local-index"));
.any(|id| id == "mnote-knowledge-rag"));
let onlyoffice_batch_set = tools
.iter()
@@ -5573,7 +5598,7 @@ mod tests {
}
#[tokio::test]
async fn hermes_tools_local_index_update_and_status_manage_scope() {
async fn hermes_tools_local_index_tools_are_retired() {
let root = std::env::temp_dir().join(format!("mnote-index-tool-{}", std::process::id()));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(root.join(".mnote")).expect("metadata");
@@ -5583,11 +5608,7 @@ mod tests {
r#"{"workspaceId":"local-ws-index-tool","ownerId":"user_1","createdAt":"2026-06-04T00:00:00Z","capabilities":["local_files","search"]}"#,
)
.expect("manifest");
fs::write(
root.join("docs").join("indexed.md"),
"# Indexed\n\nindex-tool-token\n",
)
.expect("markdown");
fs::write(root.join("docs").join("indexed.md"), "# Indexed\n").expect("markdown");
let root_uri = format!("file://{}", root.display());
let app = app();
@@ -5625,18 +5646,16 @@ mod tests {
)
.await
.expect("update response");
assert_eq!(update_response.status(), StatusCode::OK);
assert_eq!(update_response.status(), StatusCode::GONE);
let update_body = to_bytes(update_response.into_body(), usize::MAX)
.await
.expect("update body");
let update_payload: Value = serde_json::from_slice(&update_body).expect("update json");
assert_eq!(
update_payload["result"]["settings"]["includePaths"][0],
"docs"
update_payload["code"].as_str(),
Some("mnote_index_tools_retired")
);
assert_eq!(update_payload["result"]["index"]["documentCount"], 1);
assert!(root.join(".mnote/index/search-index.json").exists());
assert!(root.join(".mnote/index/evidence.sqlite").exists());
assert!(!root.join(".mnote/index/search-index.json").exists());
let status_response = app
.oneshot(
@@ -5664,16 +5683,15 @@ mod tests {
)
.await
.expect("status response");
assert_eq!(status_response.status(), StatusCode::OK);
assert_eq!(status_response.status(), StatusCode::GONE);
let status_body = to_bytes(status_response.into_body(), usize::MAX)
.await
.expect("status body");
let status_payload: Value = serde_json::from_slice(&status_body).expect("status json");
assert_eq!(
status_payload["result"]["result"]["settings"]["includePaths"][0],
"docs"
status_payload["code"].as_str(),
Some("mnote_index_tools_retired")
);
assert_eq!(status_payload["audit"]["effect"], "read");
let _ = fs::remove_dir_all(&root);
}