收口 MNote P0 P1 P2 审查尾项
- 归档 OnlyOffice live bridge、Page AI、mindmap、design governance 与相关 bug 条目 - 补齐 MinerU OCR 后端 runtime 合同与 smoke/test 基线 - 收口 ChatOnly/Doubao、ObjectIdentity、Page Aggregate compat 与 runtime owner 文档口径 验证: - cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1 - cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1 - git diff --check - git diff --cached --check - codegraph index . --force && codegraph status . - codegraph sync . && codegraph status .
This commit is contained in:
@@ -41,6 +41,68 @@ const SKILLS: &[MnoteSkill] = &[
|
||||
tool_names: &["mnote.context.snapshot", "mnote.context.resolve_target"],
|
||||
content: include_str!("../../../../../skills/mnote-local-file/SKILL.md"),
|
||||
},
|
||||
MnoteSkill {
|
||||
id: "mnote-onlyoffice-live",
|
||||
title: "MNote ONLYOFFICE live bridge",
|
||||
description: "Operate the currently open ONLYOFFICE editor session for Word, Excel, and PPT.",
|
||||
agent_ids: &["hermes", "reasonix"],
|
||||
read_only: false,
|
||||
requires_context_refs: &["onlyoffice"],
|
||||
tool_names: &[
|
||||
"mnote.onlyoffice.session.current",
|
||||
"mnote.onlyoffice.capabilities",
|
||||
"mnote.onlyoffice.selection.get",
|
||||
"mnote.onlyoffice.document.insert_text",
|
||||
"mnote.onlyoffice.document.replace_selection",
|
||||
"mnote.onlyoffice.document.insert_html",
|
||||
"mnote.onlyoffice.document.export",
|
||||
"mnote.onlyoffice.document.search_replace",
|
||||
"mnote.onlyoffice.document.insert_table",
|
||||
"mnote.onlyoffice.document.get_comments",
|
||||
"mnote.onlyoffice.document.add_comment",
|
||||
"mnote.onlyoffice.sheet.get_sheets",
|
||||
"mnote.onlyoffice.sheet.add_sheet",
|
||||
"mnote.onlyoffice.sheet.rename_sheet",
|
||||
"mnote.onlyoffice.sheet.get_range",
|
||||
"mnote.onlyoffice.sheet.get_range_values",
|
||||
"mnote.onlyoffice.sheet.get_values",
|
||||
"mnote.onlyoffice.sheet.set_value",
|
||||
"mnote.onlyoffice.sheet.set_formula",
|
||||
"mnote.onlyoffice.sheet.batch_set_values",
|
||||
"mnote.onlyoffice.sheet.set_range_values",
|
||||
"mnote.onlyoffice.sheet.format_range",
|
||||
"mnote.onlyoffice.sheet.set_dimensions",
|
||||
"mnote.onlyoffice.sheet.sort_range",
|
||||
"mnote.onlyoffice.sheet.add_chart",
|
||||
"mnote.onlyoffice.presentation.get_slides",
|
||||
"mnote.onlyoffice.presentation.get_slide_texts",
|
||||
"mnote.onlyoffice.presentation.get_shapes",
|
||||
"mnote.onlyoffice.presentation.add_text_slide",
|
||||
"mnote.onlyoffice.presentation.replace_text",
|
||||
"mnote.onlyoffice.presentation.set_shape_text",
|
||||
"mnote.onlyoffice.presentation.delete_slide",
|
||||
"mnote.onlyoffice.presentation.add_table",
|
||||
"mnote.onlyoffice.presentation.clear_slide",
|
||||
"mnote.onlyoffice.presentation.add_shape",
|
||||
],
|
||||
content: include_str!("../../../../../skills/mnote-onlyoffice-live/SKILL.md"),
|
||||
},
|
||||
MnoteSkill {
|
||||
id: "mnote-mindmap",
|
||||
title: "MNote mindmap editing",
|
||||
description: "Read, update, summarize, or create MNote mindmap resources, including generating a new mindmap from PDF or document outlines.",
|
||||
agent_ids: &["hermes", "reasonix"],
|
||||
read_only: false,
|
||||
requires_context_refs: &["current_page", "file", "folder", "resource"],
|
||||
tool_names: &[
|
||||
"mnote.context.snapshot",
|
||||
"mnote.context.resolve_target",
|
||||
"mnote.mindmap.fetch",
|
||||
"mnote.mindmap.apply_ops",
|
||||
"mnote.mindmap.create_from_outline",
|
||||
],
|
||||
content: include_str!("../../../../../skills/mnote-mindmap/SKILL.md"),
|
||||
},
|
||||
MnoteSkill {
|
||||
id: "mnote-chat-only",
|
||||
title: "MNote chat only",
|
||||
@@ -146,4 +208,108 @@ mod tests {
|
||||
assert!(find_skill("mnote-local-file", Some("chat_only")).is_none());
|
||||
assert!(find_skill("missing", Some("reasonix")).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skill_registry_exposes_onlyoffice_live_skill_to_agents() {
|
||||
let reasonix_skills = skill_summaries_for_agent(Some("reasonix"));
|
||||
let skill = reasonix_skills
|
||||
.iter()
|
||||
.find(|skill| skill["id"] == "mnote-onlyoffice-live")
|
||||
.expect("reasonix should see live ONLYOFFICE skill");
|
||||
assert_eq!(skill["readOnly"], false);
|
||||
assert_eq!(
|
||||
skill["toolNames"]
|
||||
.as_array()
|
||||
.expect("tool names")
|
||||
.iter()
|
||||
.any(|name| name == "mnote.onlyoffice.session.current"),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
skill["toolNames"]
|
||||
.as_array()
|
||||
.expect("tool names")
|
||||
.iter()
|
||||
.any(|name| name == "mnote.onlyoffice.sheet.batch_set_values"),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
skill["toolNames"]
|
||||
.as_array()
|
||||
.expect("tool names")
|
||||
.iter()
|
||||
.any(|name| name == "mnote.onlyoffice.sheet.add_chart"),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
skill["toolNames"]
|
||||
.as_array()
|
||||
.expect("tool names")
|
||||
.iter()
|
||||
.any(|name| name == "mnote.onlyoffice.presentation.add_shape"),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
skill["toolNames"]
|
||||
.as_array()
|
||||
.expect("tool names")
|
||||
.iter()
|
||||
.any(|name| name == "mnote.onlyoffice.presentation.replace_text"),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skill_registry_exposes_mindmap_skill_to_agents() {
|
||||
let reasonix_skills = skill_summaries_for_agent(Some("reasonix"));
|
||||
let skill = reasonix_skills
|
||||
.iter()
|
||||
.find(|skill| skill["id"] == "mnote-mindmap")
|
||||
.expect("reasonix should see mindmap skill");
|
||||
assert_eq!(skill["readOnly"], false);
|
||||
assert!(skill["requiresContextRefs"]
|
||||
.as_array()
|
||||
.expect("context refs")
|
||||
.iter()
|
||||
.any(|value| value == "resource"));
|
||||
assert!(skill["toolNames"]
|
||||
.as_array()
|
||||
.expect("tool names")
|
||||
.iter()
|
||||
.any(|name| name == "mnote.mindmap.create_from_outline"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn skill_read_returns_mindmap_skill_content() {
|
||||
let context = RequestContext::from_http_parts(
|
||||
&axum::http::Method::POST,
|
||||
&"/api/hermes/tools/execute".parse().expect("uri"),
|
||||
&axum::http::HeaderMap::new(),
|
||||
);
|
||||
let input: ToolCallInput = serde_json::from_value(json!({
|
||||
"toolName": "mnote.skill.read",
|
||||
"args": {
|
||||
"skillId": "mnote-mindmap",
|
||||
"agentId": "reasonix"
|
||||
}
|
||||
}))
|
||||
.expect("input");
|
||||
|
||||
let payload = skill_read(&context, &input).await.expect("skill read");
|
||||
|
||||
assert_eq!(payload["skill"]["id"], "mnote-mindmap");
|
||||
assert!(payload["content"]
|
||||
.as_str()
|
||||
.unwrap_or_default()
|
||||
.contains("mnote.mindmap.create_from_outline"));
|
||||
let content = payload["content"].as_str().unwrap_or_default();
|
||||
assert!(content.contains("Mindmap outline format"));
|
||||
assert!(content.contains("Use concise keywords or short phrases"));
|
||||
assert!(content.contains("Avoid long paragraphs"));
|
||||
assert!(payload["tools"]
|
||||
.as_array()
|
||||
.expect("tools")
|
||||
.iter()
|
||||
.any(|tool| tool == "mnote.mindmap.create_from_outline"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user