2026-06-05 23:00:53 +08:00
|
|
|
|
use super::skill;
|
2026-05-14 15:10:33 +08:00
|
|
|
|
use serde_json::{json, Value};
|
|
|
|
|
|
|
|
|
|
|
|
pub const MANIFEST_SCHEMA_VERSION: &str = "mnote.hermes_tool_manifest.v1";
|
|
|
|
|
|
pub const TOOL_SCHEMA_VERSION: &str = "mnote.hermes_tool.v1";
|
|
|
|
|
|
|
|
|
|
|
|
pub fn manifest() -> Value {
|
2026-06-13 22:59:24 +08:00
|
|
|
|
let tools = annotate_tools_with_capabilities(assemble_all_tools());
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"schemaVersion": MANIFEST_SCHEMA_VERSION,
|
|
|
|
|
|
"plugin": {
|
|
|
|
|
|
"name": "mnote",
|
|
|
|
|
|
"description": "mnote 页面、树、artifact 与 edge 工具",
|
|
|
|
|
|
"runtimeOwner": "mnote-web",
|
|
|
|
|
|
"writeOwner": "rust-runtime-kernel"
|
|
|
|
|
|
},
|
|
|
|
|
|
"capabilities": skill::manifest_capabilities(),
|
|
|
|
|
|
"tools": tools
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── 按能力域分组的工具组装函数 ──
|
|
|
|
|
|
|
|
|
|
|
|
fn assemble_all_tools() -> Vec<Value> {
|
|
|
|
|
|
let mut tools = Vec::new();
|
|
|
|
|
|
tools.push(skill_read_tool());
|
|
|
|
|
|
tools.append(&mut context_tools());
|
|
|
|
|
|
tools.append(&mut doc_tools());
|
|
|
|
|
|
tools.append(&mut knowledge_rag_tools());
|
|
|
|
|
|
tools.append(&mut block_tools());
|
|
|
|
|
|
tools.append(&mut page_tools());
|
|
|
|
|
|
tools.append(&mut mindmap_tools());
|
|
|
|
|
|
tools.append(&mut office_tools());
|
|
|
|
|
|
tools.append(&mut onlyoffice_tools());
|
|
|
|
|
|
tools.append(&mut artifact_tools());
|
|
|
|
|
|
tools
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn context_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-05 23:00:53 +08:00
|
|
|
|
context_snapshot_tool(),
|
|
|
|
|
|
context_read_current_page_tool(),
|
|
|
|
|
|
context_resolve_target_tool(),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn doc_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-05 23:00:53 +08:00
|
|
|
|
doc_fetch_tool(),
|
|
|
|
|
|
doc_find_tool(),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
doc_markdown_edit_tool(),
|
|
|
|
|
|
doc_apply_block_ops_tool(),
|
|
|
|
|
|
doc_plan_update_tool(),
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn knowledge_rag_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-07 01:10:31 +08:00
|
|
|
|
knowledge_rag_status_tool(),
|
2026-06-26 20:01:02 +08:00
|
|
|
|
weknora_search_tool(),
|
|
|
|
|
|
weknora_list_sources_tool(),
|
|
|
|
|
|
weknora_get_source_status_tool(),
|
|
|
|
|
|
weknora_open_reference_tool(),
|
2026-06-07 01:10:31 +08:00
|
|
|
|
knowledge_rag_query_tool(),
|
2026-06-13 22:20:01 +08:00
|
|
|
|
knowledge_rag_section_context_tool(),
|
2026-06-07 01:10:31 +08:00
|
|
|
|
knowledge_rag_open_reference_tool(),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn block_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-05 23:00:53 +08:00
|
|
|
|
block_fetch_tool(),
|
|
|
|
|
|
block_replace_tool(),
|
|
|
|
|
|
block_insert_after_tool(),
|
|
|
|
|
|
block_delete_tool(),
|
|
|
|
|
|
block_move_after_tool(),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn page_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-05 23:00:53 +08:00
|
|
|
|
page_get_tool(),
|
|
|
|
|
|
page_save_tool(),
|
|
|
|
|
|
available_tool(
|
|
|
|
|
|
"mnote.page.update_title",
|
|
|
|
|
|
"更新当前页面标题",
|
|
|
|
|
|
["page.write"],
|
|
|
|
|
|
),
|
|
|
|
|
|
available_tool(
|
|
|
|
|
|
"mnote.page.update_options",
|
|
|
|
|
|
"更新当前页面设置",
|
|
|
|
|
|
["page.write"],
|
|
|
|
|
|
),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn mindmap_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-05 23:00:53 +08:00
|
|
|
|
mindmap_fetch_tool(),
|
|
|
|
|
|
mindmap_apply_ops_tool(),
|
|
|
|
|
|
mindmap_create_from_outline_tool(),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn office_tools() -> Vec<Value> {
|
2026-06-25 21:08:17 +08:00
|
|
|
|
vec![office_fetch_summary_tool(), office_propose_changes_tool()]
|
2026-06-13 22:59:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-05 23:00:53 +08:00
|
|
|
|
onlyoffice_session_current_tool(),
|
|
|
|
|
|
onlyoffice_capabilities_tool(),
|
|
|
|
|
|
onlyoffice_selection_get_tool(),
|
|
|
|
|
|
onlyoffice_document_insert_text_tool(),
|
|
|
|
|
|
onlyoffice_document_replace_selection_tool(),
|
|
|
|
|
|
onlyoffice_document_insert_html_tool(),
|
|
|
|
|
|
onlyoffice_document_export_tool(),
|
|
|
|
|
|
onlyoffice_document_search_replace_tool(),
|
|
|
|
|
|
onlyoffice_document_insert_table_tool(),
|
|
|
|
|
|
onlyoffice_document_get_comments_tool(),
|
|
|
|
|
|
onlyoffice_document_add_comment_tool(),
|
|
|
|
|
|
onlyoffice_sheet_get_sheets_tool(),
|
|
|
|
|
|
onlyoffice_sheet_add_sheet_tool(),
|
|
|
|
|
|
onlyoffice_sheet_rename_sheet_tool(),
|
|
|
|
|
|
onlyoffice_sheet_get_range_tool(),
|
|
|
|
|
|
onlyoffice_sheet_get_range_values_tool(),
|
|
|
|
|
|
onlyoffice_sheet_get_values_tool(),
|
|
|
|
|
|
onlyoffice_sheet_set_value_tool(),
|
|
|
|
|
|
onlyoffice_sheet_set_formula_tool(),
|
|
|
|
|
|
onlyoffice_sheet_batch_set_values_tool(),
|
|
|
|
|
|
onlyoffice_sheet_set_range_values_tool(),
|
|
|
|
|
|
onlyoffice_sheet_format_range_tool(),
|
|
|
|
|
|
onlyoffice_sheet_set_dimensions_tool(),
|
|
|
|
|
|
onlyoffice_sheet_sort_range_tool(),
|
|
|
|
|
|
onlyoffice_sheet_add_chart_tool(),
|
|
|
|
|
|
onlyoffice_presentation_get_slides_tool(),
|
|
|
|
|
|
onlyoffice_presentation_get_slide_texts_tool(),
|
|
|
|
|
|
onlyoffice_presentation_get_shapes_tool(),
|
|
|
|
|
|
onlyoffice_presentation_add_text_slide_tool(),
|
|
|
|
|
|
onlyoffice_presentation_replace_text_tool(),
|
|
|
|
|
|
onlyoffice_presentation_set_shape_text_tool(),
|
|
|
|
|
|
onlyoffice_presentation_delete_slide_tool(),
|
|
|
|
|
|
onlyoffice_presentation_add_table_tool(),
|
|
|
|
|
|
onlyoffice_presentation_clear_slide_tool(),
|
|
|
|
|
|
onlyoffice_presentation_add_shape_tool(),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn artifact_tools() -> Vec<Value> {
|
|
|
|
|
|
vec![
|
2026-06-05 23:00:53 +08:00
|
|
|
|
available_tool(
|
|
|
|
|
|
"mnote.artifact.create_summary",
|
|
|
|
|
|
"为当前页面创建或更新 AI Summary",
|
|
|
|
|
|
["artifact.write"],
|
|
|
|
|
|
),
|
|
|
|
|
|
available_tool(
|
|
|
|
|
|
"mnote.artifact.create_ai_note",
|
|
|
|
|
|
"基于当前页面创建新的 AI Note",
|
|
|
|
|
|
["artifact.write"],
|
|
|
|
|
|
),
|
2026-06-13 22:59:24 +08:00
|
|
|
|
]
|
2026-05-14 15:10:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-05 23:00:53 +08:00
|
|
|
|
fn annotate_tools_with_capabilities(tools: Vec<Value>) -> Vec<Value> {
|
|
|
|
|
|
tools
|
|
|
|
|
|
.into_iter()
|
|
|
|
|
|
.map(|mut tool| {
|
|
|
|
|
|
let name = tool.get("name").and_then(Value::as_str).unwrap_or_default();
|
|
|
|
|
|
let capability_ids = skill::capability_ids_for_tool(name);
|
|
|
|
|
|
if let Value::Object(map) = &mut tool {
|
|
|
|
|
|
if let Some(first) = capability_ids.first() {
|
|
|
|
|
|
map.insert("capabilityId".into(), json!(first));
|
|
|
|
|
|
}
|
|
|
|
|
|
if !capability_ids.is_empty() {
|
|
|
|
|
|
map.insert("capabilityIds".into(), json!(capability_ids));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
tool
|
|
|
|
|
|
})
|
|
|
|
|
|
.collect()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-29 21:57:29 +08:00
|
|
|
|
fn skill_read_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("skillId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("agentId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.skill.read",
|
|
|
|
|
|
"description": "按需读取 MNote skill 正文。默认 prompt 只列 skill 摘要,正文必须通过本工具懒加载。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["skill.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["skillId"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn context_snapshot_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"contextRefs".into(),
|
|
|
|
|
|
json!({ "type": "array", "items": { "type": ["string", "object"] } }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.context.snapshot",
|
|
|
|
|
|
"description": "返回本次 run 可用的 MNote 上下文摘要,不返回页面正文全文。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["context.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn context_read_current_page_tool() -> Value {
|
|
|
|
|
|
let mut tool = doc_fetch_tool();
|
|
|
|
|
|
if let Value::Object(map) = &mut tool {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"name".into(),
|
|
|
|
|
|
Value::String("mnote.context.read_current_page".into()),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"description".into(),
|
|
|
|
|
|
Value::String("在 current_page contextRef 被授权时读取当前 Markdown 页面。".into()),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"capabilityScope".into(),
|
|
|
|
|
|
json!(["context.read", "page.read"]),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
tool
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn context_resolve_target_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"contextRefs".into(),
|
|
|
|
|
|
json!({ "type": "array", "items": { "type": ["string", "object"] } }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("relativePath".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"fileVersion".into(),
|
|
|
|
|
|
json!({ "type": ["string", "object"] }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.context.resolve_target",
|
|
|
|
|
|
"description": "解析当前 Page AI run 的工作区、文档、rootUri、relativePath 与 file version。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["context.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 22:03:14 +08:00
|
|
|
|
fn base_identity_properties() -> Value {
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"workspaceId": { "type": "string" },
|
|
|
|
|
|
"documentId": { "type": "string" },
|
|
|
|
|
|
"sessionId": { "type": "string" },
|
|
|
|
|
|
"runId": { "type": "string" },
|
|
|
|
|
|
"toolCallId": { "type": "string" },
|
|
|
|
|
|
"traceId": { "type": "string" },
|
|
|
|
|
|
"actorId": { "type": "string" },
|
|
|
|
|
|
"actorType": { "type": "string" }
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn doc_fetch_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"scope".into(),
|
|
|
|
|
|
json!({ "type": "string", "default": "full" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"detail".into(),
|
|
|
|
|
|
json!({ "type": "string", "default": "with_ids" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"format".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["json", "markdown", "text", "page_xml"], "default": "json" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("blockId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"selectedBlockIds".into(),
|
|
|
|
|
|
json!({ "type": "array", "items": { "type": "string" } }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"allowedTargetBlockIds".into(),
|
|
|
|
|
|
json!({ "type": "array", "items": { "type": "string" } }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("query".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"maxBlocks".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 120 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.doc.fetch",
|
|
|
|
|
|
"description": "读取当前页面的 canonical block projection,支持 full/outline/block/keyword 范围",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["page.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "documentId", "sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn doc_find_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("query".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"match".into(),
|
|
|
|
|
|
json!({ "type": "string", "default": "text" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("limit".into(), json!({ "type": "integer", "default": 20 }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.doc.find",
|
|
|
|
|
|
"description": "在 Page Aggregate block projection 中按文本、类型或 blockId 查找块",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["page.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "documentId", "sessionId", "runId", "toolCallId", "traceId", "actorId", "query"],
|
|
|
|
|
|
"properties": properties
|
2026-06-04 18:51:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-07 01:10:31 +08:00
|
|
|
|
fn knowledge_rag_status_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.knowledge_rag.status",
|
2026-06-26 20:01:02 +08:00
|
|
|
|
"description": "查看当前资料库 provider 状态、dashboard 地址、source registry 和同步状态。默认 provider 是 WeKnora;LightRAG 仅作为 legacy fallback。",
|
2026-06-07 01:10:31 +08:00
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-26 20:01:02 +08:00
|
|
|
|
fn weknora_scope_properties() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("scope".into(), json!({ "type": "object" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"allowlist".into(),
|
|
|
|
|
|
json!({ "type": "array", "items": { "type": "string" } }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("allowedRoots".into(), json!({ "type": "array" }));
|
|
|
|
|
|
map.insert("aiAccessScope".into(), json!({ "type": "object" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"sourcePaths".into(),
|
|
|
|
|
|
json!({ "type": "array", "items": { "type": "string" } }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
properties
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn weknora_search_tool() -> Value {
|
|
|
|
|
|
let mut properties = weknora_scope_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("query".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("topK".into(), json!({ "type": "integer", "default": 10 }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"includeChunkContent".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": true }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.weknora.search",
|
|
|
|
|
|
"description": "只读调用 WeKnora 检索。必须带 rootUri 和 scope/allowlist,返回 provider ids、MNote source registry 映射以及 locatorDegraded;不要把 WeKnora filename/chunk id 当成本地 path。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri", "query"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn weknora_list_sources_tool() -> Value {
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.weknora.list_sources",
|
|
|
|
|
|
"description": "只读列出 MNote source registry 与 WeKnora provider 状态。必须带 rootUri 和 scope/allowlist。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri"],
|
|
|
|
|
|
"properties": weknora_scope_properties()
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn weknora_get_source_status_tool() -> Value {
|
|
|
|
|
|
let mut properties = weknora_scope_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("sourcePath".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("providerKnowledgeId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("providerSourceId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.weknora.get_source_status",
|
|
|
|
|
|
"description": "只读查询某个 MNote source 或 WeKnora provider knowledge id 的映射状态。必须带 rootUri 和 scope/allowlist。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn weknora_open_reference_tool() -> Value {
|
|
|
|
|
|
let mut properties = weknora_scope_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("reference".into(), json!({ "type": "object" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"providerKnowledgeBaseId".into(),
|
|
|
|
|
|
json!({ "type": "string" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("providerKnowledgeId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("providerChunkId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.weknora.open_reference",
|
|
|
|
|
|
"description": "只读把 WeKnora reference 映射为 MNote open action。provider ids 独立返回;未命中 source registry 时必须视为 locatorDegraded。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri", "reference"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-07 01:10:31 +08:00
|
|
|
|
fn knowledge_rag_query_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("query".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("question".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"mode".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["local", "global", "hybrid", "naive", "mix", "bypass"], "default": "mix" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("topK".into(), json!({ "type": "integer", "default": 40 }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"chunkTopK".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 20 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"includeChunkContent".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": true }),
|
|
|
|
|
|
);
|
2026-06-13 22:20:01 +08:00
|
|
|
|
map.insert(
|
|
|
|
|
|
"includeDocumentStructureIndex".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "boolean",
|
|
|
|
|
|
"default": false,
|
2026-06-26 20:01:02 +08:00
|
|
|
|
"description": "返回由 provider sidecar/headings 派生的 document_structure_index;适合大书/长文档问题做章节导航和上下文扩展,不替代 references 引用证据。"
|
2026-06-13 22:20:01 +08:00
|
|
|
|
}),
|
|
|
|
|
|
);
|
2026-06-07 01:10:31 +08:00
|
|
|
|
map.insert(
|
|
|
|
|
|
"sourcePaths".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "string" },
|
2026-06-26 20:01:02 +08:00
|
|
|
|
"description": "可选 MNote workspace 相对路径范围;可传文件或目录。当前语义是 provider 检索后,MNote 只过滤返回的 references;provider raw 仍可能是全局结果。"
|
2026-06-07 01:10:31 +08:00
|
|
|
|
}),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.knowledge_rag.query",
|
2026-06-26 20:01:02 +08:00
|
|
|
|
"description": "向当前资料库 provider 提问,返回 provider 原始结果和经 MNote registry 映射、sourcePaths 后过滤的 references/citations。默认 provider 是 WeKnora,LightRAG 仅 legacy fallback。用户要求链接、来源、引用或证据时优先调用;返回的 citationMarkdown 由 MNote 前端自动追加成可点击来源定位,agent 不应在最终回答中手写 /documents、mnote:// 或搜索引擎包装链接。",
|
2026-06-07 01:10:31 +08:00
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri", "query"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn knowledge_rag_open_reference_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("reference".into(), json!({ "type": "object" }));
|
|
|
|
|
|
map.insert("referenceId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("filePath".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("chunkId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.knowledge_rag.open_reference",
|
2026-06-26 20:01:02 +08:00
|
|
|
|
"description": "把 provider reference 映射为 MNote 可打开的本地 resource action;没有 registry 命中时明确返回定位降级。",
|
2026-06-07 01:10:31 +08:00
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri", "filePath"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-13 22:20:01 +08:00
|
|
|
|
fn knowledge_rag_section_context_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("sourcePath".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("sourceId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("lightRagDocId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("filePath".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("sectionId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("startBlockOrdinal".into(), json!({ "type": "integer" }));
|
|
|
|
|
|
map.insert("endBlockOrdinal".into(), json!({ "type": "integer" }));
|
|
|
|
|
|
map.insert("startParagraphOrdinal".into(), json!({ "type": "integer" }));
|
|
|
|
|
|
map.insert("endParagraphOrdinal".into(), json!({ "type": "integer" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"contextBefore".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"contextAfter".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"maxBlocks".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 24 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"maxChars".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 12000 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.knowledge_rag.section_context",
|
2026-06-26 20:01:02 +08:00
|
|
|
|
"description": "按 documentStructureIndex section 的 block/paragraph range,从 provider sidecar 拉取有限正文 blocks/chunks,供大书/长文档二次解读;不做检索、重排或 fallback。",
|
2026-06-13 22:20:01 +08:00
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["knowledge_rag.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-07 10:35:21 +08:00
|
|
|
|
// 旧 local index agent 工具仅保留为历史对照;当前 manifest() 不注册这些工具。
|
2026-06-07 01:10:31 +08:00
|
|
|
|
#[allow(dead_code)]
|
2026-06-05 23:00:53 +08:00
|
|
|
|
fn index_status_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.index.status",
|
|
|
|
|
|
"description": "查看本地索引范围、缓存文件、构建时间、文档数和 evidence block 数。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["index.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-07 01:10:31 +08:00
|
|
|
|
#[allow(dead_code)]
|
2026-06-05 23:00:53 +08:00
|
|
|
|
fn index_refresh_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.index.refresh",
|
|
|
|
|
|
"description": "按当前有效索引范围重建本地搜索/evidence 缓存,不修改 Markdown 正文。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["index.read", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, false, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-07 01:10:31 +08:00
|
|
|
|
#[allow(dead_code)]
|
2026-06-05 23:00:53 +08:00
|
|
|
|
fn index_update_settings_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"includePaths".into(),
|
|
|
|
|
|
json!({ "type": "array", "items": { "type": "string" } }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"scheduleMode".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["manual", "daily", "weekly", "monthly"] }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("scheduleTime".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("scheduleDate".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("runOnChange".into(), json!({ "type": "boolean" }));
|
|
|
|
|
|
map.insert("dryRun".into(), json!({ "type": "boolean" }));
|
|
|
|
|
|
map.insert("idempotencyKey".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.index.update_settings",
|
|
|
|
|
|
"description": "新增或删除本地索引范围;includePaths 为空表示删除当前用户索引范围并在无有效范围时清空索引文件。",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["index.write", "evidence.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(false, true, false, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "rootUri", "includePaths", "dryRun", "idempotencyKey"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 22:03:14 +08:00
|
|
|
|
fn block_fetch_tool() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("blockId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"includeChildren".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": true }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"contextBefore".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"contextAfter".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"format".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["json", "markdown", "text", "page_xml"], "default": "json" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.block.fetch",
|
|
|
|
|
|
"description": "读取单个块及同父级上下文",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["block.read", "page.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "documentId", "sessionId", "runId", "toolCallId", "traceId", "actorId", "blockId"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn doc_plan_update_tool() -> Value {
|
|
|
|
|
|
write_tool(
|
|
|
|
|
|
"mnote.doc.plan_update",
|
|
|
|
|
|
"生成页面块更新 dry-run 计划,不直接写入",
|
|
|
|
|
|
["page.write", "block.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"command": { "type": "string" },
|
|
|
|
|
|
"blockId": { "type": "string" },
|
|
|
|
|
|
"anchorBlockId": { "type": "string" },
|
|
|
|
|
|
"content": { "type": ["string", "object", "array"] },
|
|
|
|
|
|
"query": { "type": "string" },
|
|
|
|
|
|
"revision": { "type": ["number", "string"] },
|
|
|
|
|
|
"conflictDetectionKey": { "type": "string" }
|
|
|
|
|
|
}),
|
|
|
|
|
|
[],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn block_replace_tool() -> Value {
|
|
|
|
|
|
write_tool(
|
|
|
|
|
|
"mnote.block.replace",
|
2026-05-19 08:07:17 +08:00
|
|
|
|
"兼容块写工具:替换指定块内容;本地 Markdown 普通编辑优先使用 agent 原生 patch/diff,必要时再走 Rust page.body.write 兼容链路",
|
2026-05-16 22:03:14 +08:00
|
|
|
|
["block.write", "page.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"blockId": { "type": "string" },
|
|
|
|
|
|
"content": { "type": ["string", "object", "array"] },
|
|
|
|
|
|
"revision": { "type": ["number", "string"] },
|
|
|
|
|
|
"conflictDetectionKey": { "type": "string" },
|
2026-05-18 17:01:35 +08:00
|
|
|
|
"blockRevisionRef": { "type": "string" },
|
|
|
|
|
|
"allowedTargetBlockIds": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "string" }
|
|
|
|
|
|
}
|
2026-05-16 22:03:14 +08:00
|
|
|
|
}),
|
|
|
|
|
|
[
|
|
|
|
|
|
"blockId",
|
|
|
|
|
|
"content",
|
|
|
|
|
|
"revision",
|
|
|
|
|
|
"conflictDetectionKey",
|
|
|
|
|
|
"blockRevisionRef",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn block_insert_after_tool() -> Value {
|
2026-05-18 17:01:35 +08:00
|
|
|
|
let mut tool = write_tool(
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"mnote.block.insert_after",
|
|
|
|
|
|
"在指定块后插入新块;真实写入走 Rust page.body.save 链路",
|
|
|
|
|
|
["block.write", "page.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"anchorBlockId": { "type": "string" },
|
|
|
|
|
|
"content": { "type": ["string", "object", "array"] },
|
|
|
|
|
|
"block": { "type": "object" },
|
2026-05-18 17:01:35 +08:00
|
|
|
|
"blocks": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"minItems": 1,
|
|
|
|
|
|
"maxItems": 20,
|
|
|
|
|
|
"items": { "type": ["string", "object", "array"] }
|
|
|
|
|
|
},
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"revision": { "type": ["number", "string"] },
|
|
|
|
|
|
"conflictDetectionKey": { "type": "string" },
|
2026-05-18 17:01:35 +08:00
|
|
|
|
"anchorRevisionRef": { "type": "string" },
|
|
|
|
|
|
"allowedTargetBlockIds": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "string" }
|
|
|
|
|
|
}
|
2026-05-16 22:03:14 +08:00
|
|
|
|
}),
|
|
|
|
|
|
[
|
|
|
|
|
|
"anchorBlockId",
|
|
|
|
|
|
"revision",
|
|
|
|
|
|
"conflictDetectionKey",
|
|
|
|
|
|
"anchorRevisionRef",
|
|
|
|
|
|
],
|
2026-05-18 17:01:35 +08:00
|
|
|
|
);
|
|
|
|
|
|
if let Some(schema) = tool.get_mut("inputSchema").and_then(Value::as_object_mut) {
|
|
|
|
|
|
schema.insert(
|
|
|
|
|
|
"anyOf".into(),
|
|
|
|
|
|
json!([
|
|
|
|
|
|
{ "required": ["content"] },
|
|
|
|
|
|
{ "required": ["block"] },
|
|
|
|
|
|
{ "required": ["blocks"] }
|
|
|
|
|
|
]),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
tool
|
2026-05-16 22:03:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn block_move_after_tool() -> Value {
|
|
|
|
|
|
write_tool(
|
|
|
|
|
|
"mnote.block.move_after",
|
|
|
|
|
|
"受限同父级普通叶子块移动;真实写入走 Rust page.body.save 链路",
|
|
|
|
|
|
["block.write", "page.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"blockId": { "type": "string" },
|
|
|
|
|
|
"anchorBlockId": { "type": "string" },
|
|
|
|
|
|
"revision": { "type": ["number", "string"] },
|
|
|
|
|
|
"conflictDetectionKey": { "type": "string" },
|
|
|
|
|
|
"blockRevisionRef": { "type": "string" },
|
2026-05-18 17:01:35 +08:00
|
|
|
|
"anchorRevisionRef": { "type": "string" },
|
|
|
|
|
|
"allowedTargetBlockIds": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "string" }
|
|
|
|
|
|
}
|
2026-05-16 22:03:14 +08:00
|
|
|
|
}),
|
|
|
|
|
|
[
|
|
|
|
|
|
"blockId",
|
|
|
|
|
|
"anchorBlockId",
|
|
|
|
|
|
"revision",
|
|
|
|
|
|
"conflictDetectionKey",
|
|
|
|
|
|
"blockRevisionRef",
|
|
|
|
|
|
"anchorRevisionRef",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn block_delete_tool() -> Value {
|
|
|
|
|
|
write_tool(
|
|
|
|
|
|
"mnote.block.delete",
|
|
|
|
|
|
"删除指定无子块普通块;真实写入走 Rust page.body.save 链路",
|
|
|
|
|
|
["block.write", "page.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"blockId": { "type": "string" },
|
|
|
|
|
|
"revision": { "type": ["number", "string"] },
|
|
|
|
|
|
"conflictDetectionKey": { "type": "string" },
|
2026-05-18 17:01:35 +08:00
|
|
|
|
"blockRevisionRef": { "type": "string" },
|
|
|
|
|
|
"allowedTargetBlockIds": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "string" }
|
|
|
|
|
|
}
|
2026-05-16 22:03:14 +08:00
|
|
|
|
}),
|
|
|
|
|
|
[
|
|
|
|
|
|
"blockId",
|
|
|
|
|
|
"revision",
|
|
|
|
|
|
"conflictDetectionKey",
|
|
|
|
|
|
"blockRevisionRef",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn doc_apply_block_ops_tool() -> Value {
|
|
|
|
|
|
write_tool(
|
|
|
|
|
|
"mnote.doc.apply_block_ops",
|
|
|
|
|
|
"一次性应用多个块级操作;Rust 侧统一读取最新 projection、生成 canonical content 并一次保存,适合页面 AI 小段落增删改移动快路径",
|
|
|
|
|
|
["block.write", "page.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"operations": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": {
|
|
|
|
|
|
"op": { "type": "string" },
|
|
|
|
|
|
"blockId": { "type": "string" },
|
|
|
|
|
|
"anchorBlockId": { "type": "string" },
|
|
|
|
|
|
"matchText": { "type": "string" },
|
|
|
|
|
|
"anchorText": { "type": "string" },
|
|
|
|
|
|
"afterText": { "type": "string" },
|
|
|
|
|
|
"allowedTargetBlockIds": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "string" }
|
|
|
|
|
|
},
|
|
|
|
|
|
"content": { "type": ["string", "object", "array"] }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
["operations"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn write_tool(
|
|
|
|
|
|
name: &str,
|
|
|
|
|
|
description: &str,
|
|
|
|
|
|
scope: impl IntoIterator<Item = &'static str>,
|
|
|
|
|
|
extra_properties: Value,
|
|
|
|
|
|
extra_required: impl IntoIterator<Item = &'static str>,
|
|
|
|
|
|
) -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("dryRun".into(), json!({ "type": "boolean" }));
|
|
|
|
|
|
map.insert("idempotencyKey".into(), json!({ "type": "string" }));
|
|
|
|
|
|
if let Value::Object(extra) = extra_properties {
|
|
|
|
|
|
for (key, value) in extra {
|
|
|
|
|
|
map.insert(key, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
let mut required = vec![
|
|
|
|
|
|
"workspaceId",
|
|
|
|
|
|
"documentId",
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
];
|
|
|
|
|
|
required.extend(extra_required);
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": name,
|
|
|
|
|
|
"description": description,
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": scope.into_iter().collect::<Vec<_>>(),
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(false, false, false, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": required,
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-14 15:10:33 +08:00
|
|
|
|
fn page_get_tool() -> Value {
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.page.get",
|
|
|
|
|
|
"description": "读取当前页面 Page Aggregate 摘要",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["page.read"],
|
2026-05-21 23:53:39 +08:00
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
2026-05-14 15:10:33 +08:00
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"required": ["workspaceId", "documentId", "sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
2026-05-14 15:10:33 +08:00
|
|
|
|
"properties": {
|
|
|
|
|
|
"workspaceId": { "type": "string" },
|
|
|
|
|
|
"documentId": { "type": "string" },
|
|
|
|
|
|
"sessionId": { "type": "string" },
|
|
|
|
|
|
"runId": { "type": "string" },
|
|
|
|
|
|
"toolCallId": { "type": "string" },
|
|
|
|
|
|
"traceId": { "type": "string" },
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"actorId": { "type": "string" },
|
|
|
|
|
|
"actorType": { "type": "string" },
|
2026-05-14 15:10:33 +08:00
|
|
|
|
"includeBody": { "type": "boolean", "default": true },
|
|
|
|
|
|
"includeOptions": { "type": "boolean", "default": true },
|
|
|
|
|
|
"includeBlocks": { "type": "boolean", "default": true }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 12:34:48 +08:00
|
|
|
|
fn page_save_tool() -> Value {
|
2026-05-14 15:10:33 +08:00
|
|
|
|
json!({
|
2026-05-16 12:34:48 +08:00
|
|
|
|
"name": "mnote.page.save",
|
2026-06-07 01:10:31 +08:00
|
|
|
|
"description": "粗粒度 compat / cloud 兜底:保存当前页面正文;local-first 本地 Markdown 普通编辑禁止使用该工具,必须优先让 agent 原生 patch/diff 直接编辑授权文件;仅在用户明确要求整页覆盖/追加且其它工具无法表达时使用",
|
2026-05-14 15:10:33 +08:00
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
2026-05-16 12:34:48 +08:00
|
|
|
|
"capabilityScope": ["page.write"],
|
|
|
|
|
|
"status": "available",
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"annotations": tool_annotations(false, true, false, false),
|
2026-05-16 12:34:48 +08:00
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"required": ["workspaceId", "documentId", "sessionId", "runId", "toolCallId", "traceId", "actorId", "content", "dryRun", "idempotencyKey"],
|
2026-05-16 12:34:48 +08:00
|
|
|
|
"properties": {
|
|
|
|
|
|
"workspaceId": { "type": "string" },
|
|
|
|
|
|
"documentId": { "type": "string" },
|
|
|
|
|
|
"sessionId": { "type": "string" },
|
|
|
|
|
|
"runId": { "type": "string" },
|
|
|
|
|
|
"toolCallId": { "type": "string" },
|
|
|
|
|
|
"traceId": { "type": "string" },
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"actorId": { "type": "string" },
|
|
|
|
|
|
"actorType": { "type": "string" },
|
2026-05-16 12:34:48 +08:00
|
|
|
|
"content": {
|
|
|
|
|
|
"description": "要写入的正文块数组、{blocks:[...]}、TipTap content 数组或纯文本",
|
|
|
|
|
|
"type": ["array", "object", "string"]
|
|
|
|
|
|
},
|
|
|
|
|
|
"mode": {
|
|
|
|
|
|
"type": "string",
|
|
|
|
|
|
"enum": ["replace", "append", "prepend"],
|
|
|
|
|
|
"default": "replace"
|
|
|
|
|
|
},
|
|
|
|
|
|
"dryRun": { "type": "boolean" },
|
|
|
|
|
|
"idempotencyKey": { "type": "string" }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn available_tool(
|
|
|
|
|
|
name: &str,
|
|
|
|
|
|
description: &str,
|
|
|
|
|
|
scope: impl IntoIterator<Item = &'static str>,
|
|
|
|
|
|
) -> Value {
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": name,
|
|
|
|
|
|
"description": description,
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
2026-05-14 15:10:33 +08:00
|
|
|
|
"capabilityScope": scope.into_iter().collect::<Vec<_>>(),
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(false, false, false, false)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-17 12:58:27 +08:00
|
|
|
|
fn doc_markdown_edit_tool() -> Value {
|
2026-05-18 17:01:35 +08:00
|
|
|
|
let mut tool = write_tool(
|
|
|
|
|
|
"mnote.doc.markdown_edit",
|
2026-06-07 01:10:31 +08:00
|
|
|
|
"compat / remote / cloud fallback:通过文本级搜索替换编辑 markdown 内容。local-first 本地 workspace 的普通 Markdown 编辑禁止使用该工具,必须优先让 agent 原生 patch/diff 直接编辑授权文件;仅在远端代理、cloud/compat 或需要 MNote 结构校验时使用。",
|
2026-05-18 17:01:35 +08:00
|
|
|
|
["block.write", "page.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"operations": {
|
2026-05-17 12:58:27 +08:00
|
|
|
|
"type": "array",
|
|
|
|
|
|
"description": "搜索替换操作列表",
|
|
|
|
|
|
"items": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": {
|
|
|
|
|
|
"search": { "type": "string", "description": "要搜索的原文片段" },
|
|
|
|
|
|
"replace": { "type": "string", "description": "替换后的新文本" }
|
|
|
|
|
|
},
|
|
|
|
|
|
"required": ["search", "replace"]
|
|
|
|
|
|
}
|
2026-05-18 17:01:35 +08:00
|
|
|
|
},
|
|
|
|
|
|
"full_content": {
|
2026-05-17 12:58:27 +08:00
|
|
|
|
"type": "string",
|
|
|
|
|
|
"description": "完整修改后的 markdown 文本(替代 operations)"
|
2026-05-18 17:01:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
[],
|
|
|
|
|
|
);
|
|
|
|
|
|
if let Some(schema) = tool.get_mut("inputSchema").and_then(Value::as_object_mut) {
|
|
|
|
|
|
schema.insert(
|
|
|
|
|
|
"anyOf".into(),
|
|
|
|
|
|
json!([
|
|
|
|
|
|
{ "required": ["operations"] },
|
|
|
|
|
|
{ "required": ["full_content"] }
|
|
|
|
|
|
]),
|
2026-05-17 12:58:27 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
2026-05-18 17:01:35 +08:00
|
|
|
|
tool
|
2026-05-17 12:58:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-19 12:03:43 +08:00
|
|
|
|
fn resource_identity_properties(resource_id_name: &str) -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rootUri".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("sourceKind".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(resource_id_name.into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("resourcePath".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"aiAccessScope".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"properties": {
|
|
|
|
|
|
"permissionLevel": { "type": "string" },
|
|
|
|
|
|
"allowedResourceIds": { "type": "array", "items": { "type": "string" } },
|
|
|
|
|
|
"allowedRoots": { "type": "array" }
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
properties
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn mindmap_fetch_tool() -> Value {
|
|
|
|
|
|
let mut properties = resource_identity_properties("mindmapId");
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"scope".into(),
|
2026-06-01 09:29:12 +08:00
|
|
|
|
json!({ "type": "string", "enum": ["tree", "subtree", "markdown_summary", "full_envelope"], "default": "tree" }),
|
2026-05-19 12:03:43 +08:00
|
|
|
|
);
|
|
|
|
|
|
map.insert("nodeId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.mindmap.fetch",
|
|
|
|
|
|
"description": "读取授权 root 内的 mindmap resource 结构或 markdown summary",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["resource.read", "mindmap.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "documentId", "mindmapId", "sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn mindmap_apply_ops_tool() -> Value {
|
|
|
|
|
|
write_tool(
|
|
|
|
|
|
"mnote.mindmap.apply_ops",
|
|
|
|
|
|
"对授权 mindmap resource 生成或执行结构操作;本地 workspace 默认建议 agent 直接编辑授权文件,必要时才走该工具",
|
|
|
|
|
|
["resource.write", "mindmap.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"mindmapId": { "type": "string" },
|
|
|
|
|
|
"rootUri": { "type": "string" },
|
|
|
|
|
|
"sourceKind": { "type": "string" },
|
|
|
|
|
|
"resourcePath": { "type": "string" },
|
|
|
|
|
|
"expectedRevision": { "type": ["number", "string"] },
|
|
|
|
|
|
"ops": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "object" }
|
|
|
|
|
|
},
|
|
|
|
|
|
"aiAccessScope": { "type": "object" }
|
|
|
|
|
|
}),
|
|
|
|
|
|
["mindmapId", "ops"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-01 09:29:12 +08:00
|
|
|
|
fn mindmap_create_from_outline_tool() -> Value {
|
|
|
|
|
|
write_tool(
|
|
|
|
|
|
"mnote.mindmap.create_from_outline",
|
|
|
|
|
|
"从 PDF、Office、Markdown 或页面摘要生成新的 MNote mindmap resource envelope",
|
|
|
|
|
|
["resource.write", "mindmap.write"],
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"mindmapId": { "type": "string" },
|
|
|
|
|
|
"rootUri": { "type": "string" },
|
|
|
|
|
|
"sourceKind": { "type": "string" },
|
|
|
|
|
|
"resourcePath": { "type": "string" },
|
|
|
|
|
|
"title": { "type": "string" },
|
|
|
|
|
|
"outline": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "object" }
|
|
|
|
|
|
},
|
|
|
|
|
|
"sourceRefs": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "object" }
|
|
|
|
|
|
},
|
|
|
|
|
|
"embedIntoPage": { "type": "boolean", "default": true },
|
|
|
|
|
|
"aiAccessScope": { "type": "object" }
|
|
|
|
|
|
}),
|
|
|
|
|
|
["mindmapId", "outline"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-19 12:03:43 +08:00
|
|
|
|
fn office_fetch_summary_tool() -> Value {
|
|
|
|
|
|
let mut properties = resource_identity_properties("assetId");
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"extractMode".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["text", "outline", "metadata"], "default": "metadata" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.office.fetch_summary",
|
|
|
|
|
|
"description": "读取授权 Office resource 的元数据和轻量文本摘要;不直接写二进制文件",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["resource.read", "office.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "documentId", "assetId", "sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn office_propose_changes_tool() -> Value {
|
|
|
|
|
|
let mut properties = resource_identity_properties("assetId");
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("instructions".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"basisRevision".into(),
|
|
|
|
|
|
json!({ "type": ["number", "string"] }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": "mnote.office.propose_changes",
|
|
|
|
|
|
"description": "基于授权 Office resource 生成修改建议;真实写入仍由 OnlyOffice / officecli 完成",
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": ["resource.read", "office.read"],
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(true, false, true, false),
|
|
|
|
|
|
"inputSchema": {
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["workspaceId", "documentId", "assetId", "sessionId", "runId", "toolCallId", "traceId", "actorId", "instructions"],
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-01 09:29:12 +08:00
|
|
|
|
fn onlyoffice_base_properties() -> Value {
|
|
|
|
|
|
let mut properties = base_identity_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("onlyofficeSessionId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("bridgeSessionId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"aiAccessScope".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": ["allowedResourceIds"],
|
|
|
|
|
|
"properties": {
|
|
|
|
|
|
"permissionLevel": { "type": "string" },
|
|
|
|
|
|
"allowedResourceIds": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": { "type": "string" },
|
|
|
|
|
|
"minItems": 1
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"timeoutMs".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 25000 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
properties
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_session_current_tool() -> Value {
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.session.current",
|
|
|
|
|
|
"返回显式授权的 ONLYOFFICE live bridge session。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
onlyoffice_base_properties(),
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_capabilities_tool() -> Value {
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.capabilities",
|
|
|
|
|
|
"返回当前 MNote ONLYOFFICE bridge 支持的白名单 action 和编辑器能力矩阵。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
onlyoffice_base_properties(),
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_selection_get_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("options".into(), json!({ "type": "object" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.selection.get",
|
|
|
|
|
|
"读取当前 ONLYOFFICE 选区文本,支持文档、表格和演示。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_insert_text_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("text".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.insert_text",
|
|
|
|
|
|
"向当前 ONLYOFFICE 文档/选区插入纯文本。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"text",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_replace_selection_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("text".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.replace_selection",
|
|
|
|
|
|
"用纯文本替换当前 ONLYOFFICE 选区。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"text",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_insert_html_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("html".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.insert_html",
|
|
|
|
|
|
"向当前 ONLYOFFICE 文档插入 HTML 片段。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"html",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_export_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"format".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["markdown", "html"], "default": "markdown" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.export",
|
|
|
|
|
|
"把当前 ONLYOFFICE 文档导出为 Markdown 或 HTML 文本,适合 agent 读取全文后再提出修改。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_search_replace_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("search".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("replace".into(), json!({ "type": "string", "default": "" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"matchCase".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": false }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.search_replace",
|
|
|
|
|
|
"在当前 ONLYOFFICE Word 文档中执行文本查找替换。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"search",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_insert_table_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("rows".into(), json!({ "type": "integer", "minimum": 1 }));
|
|
|
|
|
|
map.insert("cols".into(), json!({ "type": "integer", "minimum": 1 }));
|
|
|
|
|
|
map.insert("columns".into(), json!({ "type": "integer", "minimum": 1 }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"data".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.insert_table",
|
|
|
|
|
|
"向当前 ONLYOFFICE Word 文档末尾插入表格,可用二维 data 填充单元格。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_get_comments_tool() -> Value {
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.get_comments",
|
|
|
|
|
|
"读取当前 ONLYOFFICE Word 文档中的评论列表、作者、正文和引用文本。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
onlyoffice_base_properties(),
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_document_add_comment_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("text".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"author".into(),
|
|
|
|
|
|
json!({ "type": "string", "default": "MNote AI" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"target".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["selection", "document_start"], "default": "selection" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.document.add_comment",
|
|
|
|
|
|
"给当前 ONLYOFFICE Word 文档选区或文档开头段落添加评论。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"text",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_get_sheets_tool() -> Value {
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.get_sheets",
|
|
|
|
|
|
"读取当前 ONLYOFFICE 表格工作簿的工作表列表。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
onlyoffice_base_properties(),
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_add_sheet_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("name".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.add_sheet",
|
|
|
|
|
|
"在当前 ONLYOFFICE 表格工作簿中新增工作表,并切换为活动工作表。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"name",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_rename_sheet_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("name".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"sheetIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("sheetName".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.rename_sheet",
|
|
|
|
|
|
"重命名当前或指定 ONLYOFFICE 表格工作表。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"name",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_get_range_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.get_range",
|
|
|
|
|
|
"读取当前 ONLYOFFICE 表格的指定单元格或区域;address 为空时读取当前选区。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_get_range_values_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("range".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.get_range_values",
|
|
|
|
|
|
"按 A1 地址读取当前 ONLYOFFICE 表格 range 的二维值、显示值和公式。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"address",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_get_values_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"startRow".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"startCol".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"rowCount".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"colCount".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.get_values",
|
|
|
|
|
|
"按零基行列坐标批量读取当前 ONLYOFFICE 表格单元格值、显示值和公式。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"rowCount",
|
|
|
|
|
|
"colCount",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_set_value_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("value".into(), json!({}));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.set_value",
|
|
|
|
|
|
"写入当前 ONLYOFFICE 表格的指定单元格或区域;address 为空时写入当前选区。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"value",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_set_formula_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("formula".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.set_formula",
|
|
|
|
|
|
"向当前 ONLYOFFICE 表格写入公式。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"formula",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_batch_set_values_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"startRow".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"startCol".into(),
|
|
|
|
|
|
json!({ "type": "integer", "default": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"values".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.batch_set_values",
|
|
|
|
|
|
"按零基行列坐标向当前 ONLYOFFICE 表格批量写入二维数组。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"values",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_set_range_values_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("range".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"values".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.set_range_values",
|
|
|
|
|
|
"按 A1 地址向当前 ONLYOFFICE 表格 range 写入二维数组。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"address",
|
|
|
|
|
|
"values",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_format_range_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("range".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("bold".into(), json!({ "type": "boolean" }));
|
|
|
|
|
|
map.insert("italic".into(), json!({ "type": "boolean" }));
|
|
|
|
|
|
map.insert("underline".into(), json!({ "type": "boolean" }));
|
|
|
|
|
|
map.insert("fillColor".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("fontColor".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("fontSize".into(), json!({ "type": "number", "minimum": 0 }));
|
|
|
|
|
|
map.insert("fontName".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"horizontalAlign".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["left", "center", "right", "justify"] }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"verticalAlign".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["top", "center", "bottom"] }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("numberFormat".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.format_range",
|
|
|
|
|
|
"按 A1 地址设置当前 ONLYOFFICE 表格 range 的字体、颜色、对齐和数字格式。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"address",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_set_dimensions_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"columnIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"columnWidth".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"rowIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"rowHeight".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.set_dimensions",
|
|
|
|
|
|
"设置当前 ONLYOFFICE 表格的列宽或行高;行列索引为零基。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_sort_range_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("range".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"keyColumn".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 1, "default": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"order".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["ascending", "descending", "asc", "desc"], "default": "ascending" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"header".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": true }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.sort_range",
|
|
|
|
|
|
"按 A1 range 对当前 ONLYOFFICE 表格区域排序;keyColumn 为 range 内从 1 开始的排序列。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"address",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_sheet_add_chart_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("address".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("range".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"chartType".into(),
|
|
|
|
|
|
json!({ "type": "string", "default": "bar" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"inColumns".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": true }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("style".into(), json!({ "type": "integer", "default": 2 }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"widthMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 120 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"heightMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 80 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"fromCol".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0, "default": 4 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"fromRow".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0, "default": 1 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"xOffsetMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"yOffsetMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.sheet.add_chart",
|
|
|
|
|
|
"基于当前 ONLYOFFICE 表格 A1 range 插入图表,默认生成柱状图。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"address",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_get_slides_tool() -> Value {
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.get_slides",
|
|
|
|
|
|
"读取当前 ONLYOFFICE 演示文稿的基础幻灯片信息。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
onlyoffice_base_properties(),
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_get_slide_texts_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.get_slide_texts",
|
|
|
|
|
|
"读取当前 ONLYOFFICE 演示文稿中每页文本框的纯文本。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_get_shapes_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.get_shapes",
|
|
|
|
|
|
"读取当前 ONLYOFFICE 演示文稿的 shape 列表、shapeId、shapeIndex 和文本。",
|
|
|
|
|
|
["office.read"],
|
|
|
|
|
|
true,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&["sessionId", "runId", "toolCallId", "traceId", "actorId"],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_add_text_slide_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("title".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("body".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.add_text_slide",
|
|
|
|
|
|
"向当前 ONLYOFFICE 演示文稿追加一个文本幻灯片。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_replace_text_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert("search".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("replace".into(), json!({ "type": "string", "default": "" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"matchCase".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": false }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"replaceAll".into(),
|
|
|
|
|
|
json!({ "type": "boolean", "default": true }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.replace_text",
|
|
|
|
|
|
"替换当前 ONLYOFFICE 演示文稿文本框中的纯文本;命中的文本框会按纯文本段落重建。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"search",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_set_shape_text_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"shapeIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("shapeId".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert("text".into(), json!({ "type": "string" }));
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.set_shape_text",
|
|
|
|
|
|
"用 slideIndex + shapeIndex/shapeId 精确设置 PPT 文本 shape 的纯文本。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"slideIndex",
|
|
|
|
|
|
"text",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_delete_slide_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.delete_slide",
|
|
|
|
|
|
"删除当前 ONLYOFFICE 演示文稿中的指定幻灯片。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"slideIndex",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_add_table_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("rows".into(), json!({ "type": "integer", "minimum": 1 }));
|
|
|
|
|
|
map.insert("cols".into(), json!({ "type": "integer", "minimum": 1 }));
|
|
|
|
|
|
map.insert("columns".into(), json!({ "type": "integer", "minimum": 1 }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"data".into(),
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {
|
|
|
|
|
|
"type": "array",
|
|
|
|
|
|
"items": {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("xMm".into(), json!({ "type": "number", "minimum": 0 }));
|
|
|
|
|
|
map.insert("yMm".into(), json!({ "type": "number", "minimum": 0 }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"widthMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 190 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"heightMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 90 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.add_table",
|
|
|
|
|
|
"向当前 ONLYOFFICE PPT 指定幻灯片插入表格,可用二维 data 填充单元格。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_clear_slide_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.clear_slide",
|
|
|
|
|
|
"清空当前 ONLYOFFICE PPT 指定幻灯片上的所有对象。调用前必须确认 slideIndex。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
"slideIndex",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_presentation_add_shape_tool() -> Value {
|
|
|
|
|
|
let mut properties = onlyoffice_base_properties();
|
|
|
|
|
|
if let Value::Object(map) = &mut properties {
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"slideIndex".into(),
|
|
|
|
|
|
json!({ "type": "integer", "minimum": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"shapeType".into(),
|
|
|
|
|
|
json!({ "type": "string", "enum": ["rect", "roundRect", "ellipse", "triangle", "diamond", "cube", "cloud", "flowChartMagneticTape"], "default": "rect" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("text".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"fillColor".into(),
|
|
|
|
|
|
json!({ "type": "string", "default": "#4F81BD" }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert("strokeColor".into(), json!({ "type": "string" }));
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"strokeWidthMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 0 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"xMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 20 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"yMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 35 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"widthMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 160 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
map.insert(
|
|
|
|
|
|
"heightMm".into(),
|
|
|
|
|
|
json!({ "type": "number", "minimum": 0, "default": 70 }),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
onlyoffice_tool(
|
|
|
|
|
|
"mnote.onlyoffice.presentation.add_shape",
|
|
|
|
|
|
"向当前 ONLYOFFICE PPT 指定幻灯片插入基础形状,可设置文字、填充色、位置和尺寸。",
|
|
|
|
|
|
["office.write"],
|
|
|
|
|
|
false,
|
|
|
|
|
|
properties,
|
|
|
|
|
|
&[
|
|
|
|
|
|
"sessionId",
|
|
|
|
|
|
"runId",
|
|
|
|
|
|
"toolCallId",
|
|
|
|
|
|
"traceId",
|
|
|
|
|
|
"actorId",
|
|
|
|
|
|
"idempotencyKey",
|
|
|
|
|
|
"dryRun",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn onlyoffice_tool(
|
|
|
|
|
|
name: &'static str,
|
|
|
|
|
|
description: &'static str,
|
|
|
|
|
|
capability_scope: impl IntoIterator<Item = &'static str>,
|
|
|
|
|
|
readonly: bool,
|
|
|
|
|
|
properties: Value,
|
|
|
|
|
|
required: &[&'static str],
|
|
|
|
|
|
) -> Value {
|
|
|
|
|
|
let mut required_fields = required.to_vec();
|
|
|
|
|
|
if name != "mnote.onlyoffice.capabilities" {
|
|
|
|
|
|
required_fields.push("aiAccessScope");
|
|
|
|
|
|
}
|
|
|
|
|
|
let mut input_schema = json!({
|
|
|
|
|
|
"type": "object",
|
|
|
|
|
|
"required": required_fields,
|
|
|
|
|
|
"properties": properties
|
|
|
|
|
|
});
|
|
|
|
|
|
if name != "mnote.onlyoffice.capabilities" {
|
|
|
|
|
|
input_schema["anyOf"] = json!([
|
|
|
|
|
|
{ "required": ["onlyofficeSessionId"] },
|
|
|
|
|
|
{ "required": ["bridgeSessionId"] }
|
|
|
|
|
|
]);
|
|
|
|
|
|
}
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"name": name,
|
|
|
|
|
|
"description": description,
|
|
|
|
|
|
"schemaVersion": TOOL_SCHEMA_VERSION,
|
|
|
|
|
|
"capabilityScope": capability_scope.into_iter().collect::<Vec<_>>(),
|
|
|
|
|
|
"status": "available",
|
|
|
|
|
|
"annotations": tool_annotations(readonly, false, readonly, false),
|
|
|
|
|
|
"inputSchema": input_schema
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-16 22:03:14 +08:00
|
|
|
|
fn tool_annotations(
|
|
|
|
|
|
readonly: bool,
|
|
|
|
|
|
destructive: bool,
|
|
|
|
|
|
idempotent: bool,
|
|
|
|
|
|
requires_approval: bool,
|
|
|
|
|
|
) -> Value {
|
|
|
|
|
|
json!({
|
|
|
|
|
|
"readonly": readonly,
|
|
|
|
|
|
"destructive": destructive,
|
|
|
|
|
|
"idempotent": idempotent,
|
2026-05-19 08:07:17 +08:00
|
|
|
|
"readOnly": readonly,
|
|
|
|
|
|
"requiresWritePermission": !readonly,
|
2026-05-16 22:03:14 +08:00
|
|
|
|
"requiresApproval": requires_approval,
|
|
|
|
|
|
"approvalMode": if requires_approval { "review" } else { "yolo" },
|
|
|
|
|
|
"runtimeOwner": "mnote-web",
|
|
|
|
|
|
"writeOwner": "rust-runtime-kernel",
|
|
|
|
|
|
"selectionEffect": if readonly { "preserve" } else { "may_change" }
|
2026-05-14 15:10:33 +08:00
|
|
|
|
})
|
|
|
|
|
|
}
|