feat: 完成 rust cutover phase 8 收口
This commit is contained in:
@@ -44,6 +44,44 @@ pub struct UpdatePageTitle {
|
||||
pub title: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct CreateDocumentPage {
|
||||
pub page_id: String,
|
||||
pub parent_page_id: Option<String>,
|
||||
pub title: String,
|
||||
pub workspace_seed_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MoveDocumentPage {
|
||||
pub page_id: String,
|
||||
pub parent_page_id: Option<String>,
|
||||
pub sort_order: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DeleteDocumentPage {
|
||||
pub page_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct RestoreDocumentPage {
|
||||
pub page_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DuplicateDocumentPage {
|
||||
pub source_page_id: String,
|
||||
pub new_page_id: String,
|
||||
pub title: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct CopyTreeDocumentPages {
|
||||
pub items_json: String,
|
||||
pub target_parent_page_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct UpdatePageStats {
|
||||
pub page_id: String,
|
||||
@@ -87,6 +125,16 @@ pub struct SavePageContent {
|
||||
pub conflict_detection_key: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct PatchBlock {
|
||||
pub page_id: String,
|
||||
pub block_id: String,
|
||||
pub workspace_id: Option<String>,
|
||||
pub revision: Option<u64>,
|
||||
pub block_snapshot_json: String,
|
||||
pub conflict_detection_key: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct PatchPageBlock {
|
||||
pub page_id: String,
|
||||
@@ -97,6 +145,14 @@ pub struct PatchPageBlock {
|
||||
pub conflict_detection_key: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct PutMindmap {
|
||||
pub document_id: String,
|
||||
pub mindmap_id: String,
|
||||
pub data_json: String,
|
||||
pub create_only: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct InsertBlock {
|
||||
pub page_id: String,
|
||||
@@ -120,6 +176,14 @@ pub struct MoveBlock {
|
||||
pub prev_block_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct EmbedBlock {
|
||||
pub source_document_id: String,
|
||||
pub source_block_id: String,
|
||||
pub target_document_id: String,
|
||||
pub target_block_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DeleteBlock {
|
||||
pub block_id: String,
|
||||
|
||||
@@ -1,23 +1,43 @@
|
||||
pub mod command;
|
||||
pub mod common;
|
||||
pub mod governance;
|
||||
pub mod mindmap;
|
||||
pub mod query;
|
||||
pub mod tool;
|
||||
|
||||
pub use command::{
|
||||
CommandEnvelope, CreatePage, CreateWorkspace, DeleteBlock, InsertBlock, MoveBlock,
|
||||
PatchPageBlock, ReplaceMediaAssetStorage, SavePageContent, UpdateBlock, UpdatePageOptions,
|
||||
UpdatePageStats, UpdatePageTitle,
|
||||
CommandEnvelope, CopyTreeDocumentPages, CreateDocumentPage, CreatePage, CreateWorkspace,
|
||||
DeleteBlock, DeleteDocumentPage, DuplicateDocumentPage, EmbedBlock, InsertBlock, MoveBlock,
|
||||
MoveDocumentPage, PatchBlock, PatchPageBlock, PutMindmap, ReplaceMediaAssetStorage,
|
||||
RestoreDocumentPage, SavePageContent, UpdateBlock, UpdatePageOptions, UpdatePageStats,
|
||||
UpdatePageTitle,
|
||||
};
|
||||
pub use common::{
|
||||
ActorPayload, AffectedObject, ErrorDetail, ErrorPayload, OkPayload, RequestMeta, ResponseMeta,
|
||||
SourcePayload, TargetRef,
|
||||
};
|
||||
pub use mindmap::{
|
||||
MindmapNodeData, MindmapNodeInput, MindmapNodeRef, MindmapOp, MindmapTreeNode,
|
||||
};
|
||||
pub use query::{
|
||||
GetPage, GetPageContent, GetPageMeta, ListPageBlocks, ListSidebarDataset, QueryEnvelope,
|
||||
SearchBlocks, SearchPages,
|
||||
GetBlock, GetBridgeCommand, GetBridgeRequest, GetBridgeTrace, GetMindmap, GetPage,
|
||||
GetPageContent, GetPageMeta, ListBridgeWorkspaceOverview, ListPageBlocks,
|
||||
ListSidebarDataset, QueryEnvelope, SearchBlocks, SearchDocuments, SearchPages, SearchRecent,
|
||||
};
|
||||
pub use tool::{
|
||||
default_tool_registry, invocation_kind_label, tool_effect_label, tool_mode_label,
|
||||
InvocationKind, ToolEffect, ToolExecutionMode, ToolInvocation, ToolRegistry, ToolSetSpec,
|
||||
ToolSpec, BRIDGE_TOOL_COMMAND_GET, BRIDGE_TOOL_REQUEST_GET, BRIDGE_TOOL_TRACE_GET,
|
||||
DOC_TOOL_FIND, DOC_TOOL_GET, DOC_TOOL_INSERT_BLOCKS, DOC_TOOL_REPLACE_RANGE,
|
||||
DOC_TOOLSET_READ, DOC_TOOLSET_WRITE, INDEX_TOOL_REBUILD, MINDMAP_TOOL_APPLY_OPS,
|
||||
MINDMAP_TOOL_EMPTY_TRASH, MINDMAP_TOOL_EXPAND_NODE, MINDMAP_TOOL_GET,
|
||||
MINDMAP_TOOL_GET_SUBTREE,
|
||||
MINDMAP_TOOL_OUTLINE_TO_MINDMAP, MINDMAP_TOOL_PUT, MINDMAP_TOOLSET_READ,
|
||||
MINDMAP_TOOLSET_WRITE, OBSERVE_TOOLSET_READ, ONLYOFFICE_TOOL_PREPARE_CALLBACK,
|
||||
ONLYOFFICE_TOOL_PREPARE_FORCESAVE, ONLYOFFICE_TOOL_PREPARE_PROXY,
|
||||
ONLYOFFICE_TOOL_SESSION_RESOLVE, ONLYOFFICE_TOOL_SIGN, ONLYOFFICE_TOOLSET_SERVICE,
|
||||
RECOVERY_TOOLSET_JOB, REPLAY_TOOL_EVENTS,
|
||||
};
|
||||
pub use tool::{InvocationKind, ToolInvocation};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -51,4 +71,124 @@ mod tests {
|
||||
|
||||
assert!(envelope.validate_only);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_tool_registry_exposes_doc_tools() {
|
||||
let registry = default_tool_registry();
|
||||
assert_eq!(
|
||||
registry.tool_names(),
|
||||
vec![
|
||||
"search_web",
|
||||
"doc_get",
|
||||
"doc_find",
|
||||
"image_read",
|
||||
"doc_insert_blocks",
|
||||
"doc_replace_range",
|
||||
"slash_run",
|
||||
"mindmap_get",
|
||||
"mindmap_get_subtree",
|
||||
"mindmap_put",
|
||||
"mindmap_apply_ops",
|
||||
"mindmap_expand_node",
|
||||
"mindmap_empty_trash",
|
||||
"mindmap_outline_to_mindmap",
|
||||
"bridge_request_get",
|
||||
"bridge_trace_get",
|
||||
"bridge_command_get",
|
||||
"event_replay",
|
||||
"index_rebuild",
|
||||
"onlyoffice_session_resolve",
|
||||
"onlyoffice_sign",
|
||||
"onlyoffice_prepare_proxy",
|
||||
"onlyoffice_prepare_callback",
|
||||
"onlyoffice_prepare_forcesave",
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
registry
|
||||
.tool("search_web")
|
||||
.expect("search_web should exist")
|
||||
.toolset_id,
|
||||
"toolset.readonly"
|
||||
);
|
||||
assert_eq!(
|
||||
registry
|
||||
.tool("image_read")
|
||||
.expect("image_read should exist")
|
||||
.toolset_id,
|
||||
"toolset.media_read"
|
||||
);
|
||||
assert_eq!(
|
||||
registry
|
||||
.tool("slash_run")
|
||||
.expect("slash_run should exist")
|
||||
.toolset_id,
|
||||
"toolset.slash_write"
|
||||
);
|
||||
let readonly = registry
|
||||
.toolset("toolset.readonly")
|
||||
.expect("readonly toolset should exist");
|
||||
assert!(!readonly.write_toolset);
|
||||
assert_eq!(readonly.tool_names, &["search_web"]);
|
||||
let media = registry
|
||||
.toolset("toolset.media_read")
|
||||
.expect("media toolset should exist");
|
||||
assert!(!media.write_toolset);
|
||||
assert_eq!(media.tool_names, &["image_read"]);
|
||||
let slash = registry
|
||||
.toolset("toolset.slash_write")
|
||||
.expect("slash toolset should exist");
|
||||
assert!(slash.write_toolset);
|
||||
assert_eq!(slash.tool_names, &["slash_run"]);
|
||||
let doc_write = registry
|
||||
.toolset("toolset.doc_write")
|
||||
.expect("doc_write toolset should exist");
|
||||
assert!(doc_write.write_toolset);
|
||||
assert_eq!(doc_write.tool_names, &["doc_insert_blocks", "doc_replace_range"]);
|
||||
assert_eq!(
|
||||
registry.tool("doc_get").expect("doc_get should exist").toolset_id,
|
||||
"toolset.doc_read"
|
||||
);
|
||||
let mindmap_write = registry
|
||||
.toolset("toolset.mindmap_write")
|
||||
.expect("mindmap_write toolset should exist");
|
||||
assert!(mindmap_write.write_toolset);
|
||||
assert_eq!(
|
||||
mindmap_write.tool_names,
|
||||
&[
|
||||
"mindmap_put",
|
||||
"mindmap_apply_ops",
|
||||
"mindmap_expand_node",
|
||||
"mindmap_empty_trash",
|
||||
"mindmap_outline_to_mindmap",
|
||||
]
|
||||
);
|
||||
let onlyoffice_service = registry
|
||||
.toolset("toolset.onlyoffice_service")
|
||||
.expect("onlyoffice service toolset should exist");
|
||||
assert!(onlyoffice_service.write_toolset);
|
||||
assert_eq!(
|
||||
onlyoffice_service.tool_names,
|
||||
&[
|
||||
"onlyoffice_session_resolve",
|
||||
"onlyoffice_sign",
|
||||
"onlyoffice_prepare_proxy",
|
||||
"onlyoffice_prepare_callback",
|
||||
"onlyoffice_prepare_forcesave",
|
||||
]
|
||||
);
|
||||
let observe = registry
|
||||
.toolset("toolset.observe_read")
|
||||
.expect("observe toolset should exist");
|
||||
assert!(!observe.write_toolset);
|
||||
assert_eq!(
|
||||
observe.tool_names,
|
||||
&["bridge_request_get", "bridge_trace_get", "bridge_command_get"]
|
||||
);
|
||||
let recovery = registry
|
||||
.toolset("toolset.recovery_job")
|
||||
.expect("recovery toolset should exist");
|
||||
assert!(recovery.write_toolset);
|
||||
assert_eq!(recovery.tool_names, &["event_replay", "index_rebuild"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MindmapNodeRef {
|
||||
pub kind: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub asset_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub file_url: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub page: Option<u32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub slide: Option<u32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub title: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub snippet: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MindmapNodeData {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub uid: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub text: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub hyperlink: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub note: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub refs: Option<Vec<MindmapNodeRef>>,
|
||||
#[serde(flatten, default)]
|
||||
pub extra: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct MindmapTreeNode {
|
||||
pub data: MindmapNodeData,
|
||||
#[serde(default)]
|
||||
pub children: Vec<MindmapTreeNode>,
|
||||
#[serde(flatten, default)]
|
||||
pub extra: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MindmapNodeInput {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub uid: Option<String>,
|
||||
pub text: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub hyperlink: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub note: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub refs: Option<Vec<MindmapNodeRef>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "op", rename_all = "camelCase")]
|
||||
pub enum MindmapOp {
|
||||
#[serde(alias = "add_child")]
|
||||
AddChild {
|
||||
#[serde(rename = "parentUid")]
|
||||
#[serde(alias = "parent_uid")]
|
||||
parent_uid: String,
|
||||
node: MindmapNodeInput,
|
||||
},
|
||||
#[serde(alias = "add_sibling_after")]
|
||||
AddSiblingAfter {
|
||||
#[serde(rename = "targetUid")]
|
||||
#[serde(alias = "target_uid")]
|
||||
target_uid: String,
|
||||
node: MindmapNodeInput,
|
||||
},
|
||||
#[serde(alias = "update_node", alias = "updateNode")]
|
||||
UpdateText {
|
||||
uid: String,
|
||||
#[serde(alias = "value")]
|
||||
text: String,
|
||||
},
|
||||
#[serde(alias = "set_link", alias = "set_hyperlink")]
|
||||
SetHyperlink {
|
||||
#[serde(alias = "id")]
|
||||
uid: String,
|
||||
#[serde(alias = "url")]
|
||||
hyperlink: Option<String>,
|
||||
},
|
||||
#[serde(alias = "set_refs")]
|
||||
SetRefs {
|
||||
#[serde(alias = "id")]
|
||||
uid: String,
|
||||
refs: Vec<MindmapNodeRef>,
|
||||
},
|
||||
#[serde(alias = "append_note")]
|
||||
AppendNote {
|
||||
#[serde(alias = "id")]
|
||||
uid: String,
|
||||
#[serde(alias = "note")]
|
||||
markdown: String,
|
||||
},
|
||||
#[serde(alias = "delete_node")]
|
||||
DeleteNode {
|
||||
#[serde(alias = "id")]
|
||||
uid: String,
|
||||
},
|
||||
}
|
||||
@@ -27,6 +27,18 @@ pub struct GetPageContent {
|
||||
pub workspace_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct GetBlock {
|
||||
pub block_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct GetMindmap {
|
||||
pub document_id: String,
|
||||
pub mindmap_id: String,
|
||||
pub workspace_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ListSidebarDataset {
|
||||
pub workspace_id: String,
|
||||
@@ -45,9 +57,62 @@ pub struct SearchPages {
|
||||
pub pagination: Pagination,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct SearchDocuments {
|
||||
pub query: String,
|
||||
pub workspace_id: String,
|
||||
pub page_id: Option<String>,
|
||||
pub pagination: Pagination,
|
||||
pub title_only: bool,
|
||||
pub exact: bool,
|
||||
pub include_ocr: bool,
|
||||
pub time_range: String,
|
||||
pub time_field: String,
|
||||
pub custom_range_from: Option<String>,
|
||||
pub custom_range_to: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct SearchRecent {
|
||||
pub workspace_id: String,
|
||||
pub pagination: Pagination,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct SearchBlocks {
|
||||
pub query: String,
|
||||
pub page_id: Option<String>,
|
||||
pub pagination: Pagination,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct GetBridgeRequest {
|
||||
pub workspace_id: String,
|
||||
pub request_id: String,
|
||||
pub command_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct GetBridgeTrace {
|
||||
pub workspace_id: String,
|
||||
pub trace_id: String,
|
||||
pub command_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct GetBridgeCommand {
|
||||
pub workspace_id: String,
|
||||
pub command_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ListBridgeWorkspaceOverview {
|
||||
pub workspace_id: String,
|
||||
pub pagination: Pagination,
|
||||
pub command_status: Option<String>,
|
||||
pub event_status: Option<String>,
|
||||
pub target_page_id: Option<String>,
|
||||
pub target_block_id: Option<String>,
|
||||
pub aggregate_type: Option<String>,
|
||||
pub aggregate_id: Option<String>,
|
||||
}
|
||||
|
||||
@@ -1,13 +1,534 @@
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum InvocationKind {
|
||||
Command,
|
||||
Query,
|
||||
Job,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ToolExecutionMode {
|
||||
Plan,
|
||||
Result,
|
||||
ExplainPlan,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ToolInvocation {
|
||||
pub tool: String,
|
||||
pub kind: InvocationKind,
|
||||
pub mode: ToolExecutionMode,
|
||||
pub args_json: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ToolEffect {
|
||||
Read,
|
||||
Write,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct ToolSpec {
|
||||
pub name: &'static str,
|
||||
pub display_name: &'static str,
|
||||
pub description: &'static str,
|
||||
pub toolset_id: &'static str,
|
||||
pub invocation_kind: InvocationKind,
|
||||
pub effect: ToolEffect,
|
||||
pub requires_confirmation: bool,
|
||||
pub input_schema_json: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct ToolSetSpec {
|
||||
pub id: &'static str,
|
||||
pub display_name: &'static str,
|
||||
pub description: &'static str,
|
||||
pub write_toolset: bool,
|
||||
pub tool_names: &'static [&'static str],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct ToolRegistry {
|
||||
pub toolsets: &'static [ToolSetSpec],
|
||||
pub tools: &'static [ToolSpec],
|
||||
}
|
||||
|
||||
impl ToolRegistry {
|
||||
pub const fn new(toolsets: &'static [ToolSetSpec], tools: &'static [ToolSpec]) -> Self {
|
||||
Self { toolsets, tools }
|
||||
}
|
||||
|
||||
pub fn tool(&self, name: &str) -> Option<&'static ToolSpec> {
|
||||
self.tools.iter().find(|spec| spec.name == name)
|
||||
}
|
||||
|
||||
pub fn toolset(&self, id: &str) -> Option<&'static ToolSetSpec> {
|
||||
self.toolsets.iter().find(|spec| spec.id == id)
|
||||
}
|
||||
|
||||
pub fn tool_names(&self) -> Vec<&'static str> {
|
||||
self.tools.iter().map(|spec| spec.name).collect()
|
||||
}
|
||||
|
||||
pub fn tool_names_in_set(&self, id: &str) -> Option<Vec<&'static str>> {
|
||||
self.toolset(id)
|
||||
.map(|toolset| toolset.tool_names.to_vec())
|
||||
}
|
||||
|
||||
pub fn tools_in_set(&self, id: &str) -> Option<Vec<&'static ToolSpec>> {
|
||||
self.toolset(id).map(|toolset| {
|
||||
toolset
|
||||
.tool_names
|
||||
.iter()
|
||||
.filter_map(|tool_name| self.tool(tool_name))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub const DOC_TOOL_GET: ToolSpec = ToolSpec {
|
||||
name: "doc_get",
|
||||
display_name: "文档读取",
|
||||
description: "读取当前文档快照,用于查看页面内容和结构。",
|
||||
toolset_id: "toolset.doc_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json: r#"{"type":"object","properties":{"maxBlocks":{"type":"integer","minimum":10,"maximum":240}}}"#,
|
||||
};
|
||||
|
||||
pub const SEARCH_WEB_TOOL: ToolSpec = ToolSpec {
|
||||
name: "search_web",
|
||||
display_name: "联网检索",
|
||||
description: "使用 SearxNG 进行联网检索,返回标题、URL 与摘要。",
|
||||
toolset_id: "toolset.readonly",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["query"],"properties":{"query":{"type":"string"},"count":{"type":"integer","minimum":1,"maximum":10}}}"#,
|
||||
};
|
||||
|
||||
pub const DOC_TOOL_FIND: ToolSpec = ToolSpec {
|
||||
name: "doc_find",
|
||||
display_name: "文档查找",
|
||||
description: "在当前文档范围内查找片段、标题或结构信息。",
|
||||
toolset_id: "toolset.doc_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["query"],"properties":{"query":{"type":"string"},"maxResults":{"type":"integer","minimum":1,"maximum":30}}}"#,
|
||||
};
|
||||
|
||||
pub const IMAGE_READ_TOOL: ToolSpec = ToolSpec {
|
||||
name: "image_read",
|
||||
display_name: "读取图片",
|
||||
description: "读取图片/附件 OCR 信息并返回归一化结果。",
|
||||
toolset_id: "toolset.media_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","properties":{"assetId":{"type":"string"},"fileUrl":{"type":"string"},"attachmentRef":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const DOC_TOOL_INSERT_BLOCKS: ToolSpec = ToolSpec {
|
||||
name: "doc_insert_blocks",
|
||||
display_name: "插入块",
|
||||
description: "在文档中插入一个或多个块,是写入类操作。",
|
||||
toolset_id: "toolset.doc_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["blocks"],"properties":{"afterBlockId":{"type":"string"},"beforeBlockId":{"type":"string"},"blocks":{"type":"array","minItems":1,"maxItems":20}}}"#,
|
||||
};
|
||||
|
||||
pub const DOC_TOOL_REPLACE_RANGE: ToolSpec = ToolSpec {
|
||||
name: "doc_replace_range",
|
||||
display_name: "替换范围",
|
||||
description: "替换文档中的块范围,是写入类操作。",
|
||||
toolset_id: "toolset.doc_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["blockId","text"],"properties":{"blockId":{"type":"string"},"text":{"type":"string"},"mode":{"enum":["replace","append","prepend"]}}}"#,
|
||||
};
|
||||
|
||||
pub const SLASH_RUN_TOOL: ToolSpec = ToolSpec {
|
||||
name: "slash_run",
|
||||
display_name: "斜杠命令",
|
||||
description: "解析并规范化斜杠命令,用于创建或重命名页面。",
|
||||
toolset_id: "toolset.slash_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","properties":{"text":{"type":"string"},"command":{"enum":["new_doc","rename_doc"]},"params":{"type":"object"},"reason":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOL_GET: ToolSpec = ToolSpec {
|
||||
name: "mindmap_get",
|
||||
display_name: "导图读取",
|
||||
description: "读取当前思维导图的节点摘要,用于定位节点和规划改动。",
|
||||
toolset_id: "toolset.mindmap_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","properties":{"maxNodes":{"type":"integer","minimum":10,"maximum":300}}}"#,
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOL_GET_SUBTREE: ToolSpec = ToolSpec {
|
||||
name: "mindmap_get_subtree",
|
||||
display_name: "导图子树读取",
|
||||
description: "读取指定节点 uid 的子树摘要,供 AI 精确查看局部结构。",
|
||||
toolset_id: "toolset.mindmap_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["uid"],"properties":{"uid":{"type":"string"},"depth":{"type":"integer","minimum":0,"maximum":6},"maxNodes":{"type":"integer","minimum":5,"maximum":200}}}"#,
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOL_PUT: ToolSpec = ToolSpec {
|
||||
name: "mindmap_put",
|
||||
display_name: "导图覆盖写入",
|
||||
description: "使用完整思维导图树覆盖当前导图,适合 CLI 或 AI 在拿到完整快照后直接写回。",
|
||||
toolset_id: "toolset.mindmap_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["data"],"properties":{"data":{"type":"object"},"createOnly":{"type":"boolean"}}}"#,
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOL_APPLY_OPS: ToolSpec = ToolSpec {
|
||||
name: "mindmap_apply_ops",
|
||||
display_name: "导图增量写入",
|
||||
description: "对思维导图应用增量 ops,并返回新的整棵树快照。",
|
||||
toolset_id: "toolset.mindmap_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["ops"],"properties":{"ops":{"type":"array","minItems":1,"maxItems":80},"reason":{"type":"string"},"targetUid":{"type":"string"},"searchResults":{"type":"array"}}}"#,
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOL_EXPAND_NODE: ToolSpec = ToolSpec {
|
||||
name: "mindmap_expand_node",
|
||||
display_name: "补完思维导图节点",
|
||||
description: "对 AI 生成的补完候选做统一归一化,再应用到当前思维导图并返回新树。",
|
||||
toolset_id: "toolset.mindmap_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["targetUid"],"properties":{"targetUid":{"type":"string"},"instruction":{"type":"string"},"ops":{"type":"array","maxItems":80},"searchResults":{"type":"array"},"reason":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOL_EMPTY_TRASH: ToolSpec = ToolSpec {
|
||||
name: "mindmap_empty_trash",
|
||||
display_name: "清空导图回收站",
|
||||
description: "校验并标准化清空导图回收站所需的工作区对象,供 route 继续执行实际写入。",
|
||||
toolset_id: "toolset.mindmap_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["workspaceId"],"properties":{"workspaceId":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOL_OUTLINE_TO_MINDMAP: ToolSpec = ToolSpec {
|
||||
name: "mindmap_outline_to_mindmap",
|
||||
display_name: "大纲转导图",
|
||||
description: "把结构化大纲转换为标准思维导图树,统一 uid、refs 与 page 链接生成规则。",
|
||||
toolset_id: "toolset.mindmap_write",
|
||||
invocation_kind: InvocationKind::Command,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["rootTitle","pageLinkPattern","outline"],"properties":{"rootTitle":{"type":"string"},"pageLinkPattern":{"type":"string"},"outline":{"type":"array","items":{"type":"object","required":["title","level","page"],"properties":{"title":{"type":"string"},"level":{"type":"integer","minimum":1,"maximum":6},"page":{"type":"integer","minimum":1}}}}}}"#,
|
||||
};
|
||||
|
||||
pub const BRIDGE_TOOL_REQUEST_GET: ToolSpec = ToolSpec {
|
||||
name: "bridge_request_get",
|
||||
display_name: "请求回查",
|
||||
description: "按 request_id 查询统一 command log 与 domain event 视图。",
|
||||
toolset_id: "toolset.observe_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["workspaceId","requestId"],"properties":{"workspaceId":{"type":"string"},"requestId":{"type":"string"},"commandId":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const BRIDGE_TOOL_TRACE_GET: ToolSpec = ToolSpec {
|
||||
name: "bridge_trace_get",
|
||||
display_name: "链路回查",
|
||||
description: "按 trace_id 查询统一 command log 与 domain event 视图。",
|
||||
toolset_id: "toolset.observe_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["workspaceId","traceId"],"properties":{"workspaceId":{"type":"string"},"traceId":{"type":"string"},"commandId":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const BRIDGE_TOOL_COMMAND_GET: ToolSpec = ToolSpec {
|
||||
name: "bridge_command_get",
|
||||
display_name: "命令回查",
|
||||
description: "按 command_id 查询统一 command log 与 domain event 视图。",
|
||||
toolset_id: "toolset.observe_read",
|
||||
invocation_kind: InvocationKind::Query,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["workspaceId","commandId"],"properties":{"workspaceId":{"type":"string"},"commandId":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const REPLAY_TOOL_EVENTS: ToolSpec = ToolSpec {
|
||||
name: "event_replay",
|
||||
display_name: "事件回放",
|
||||
description: "基于统一事件流做回放预演,输出将被追平的 event 与派生批次摘要。",
|
||||
toolset_id: "toolset.recovery_job",
|
||||
invocation_kind: InvocationKind::Job,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["workspaceId"],"properties":{"workspaceId":{"type":"string"},"lastProcessedEventId":{"type":"string"},"lastProcessedAt":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const INDEX_TOOL_REBUILD: ToolSpec = ToolSpec {
|
||||
name: "index_rebuild",
|
||||
display_name: "索引重建",
|
||||
description: "根据事件流重建全文索引游标与派生批次,作为回放和恢复前置命令。",
|
||||
toolset_id: "toolset.recovery_job",
|
||||
invocation_kind: InvocationKind::Job,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: true,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["workspaceId"],"properties":{"workspaceId":{"type":"string"},"lastProcessedEventId":{"type":"string"},"lastProcessedAt":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const ONLYOFFICE_TOOL_SESSION_RESOLVE: ToolSpec = ToolSpec {
|
||||
name: "onlyoffice_session_resolve",
|
||||
display_name: "OnlyOffice 会话解析",
|
||||
description: "解析 OnlyOffice 的附件/页面/用户上下文,返回统一 session 与 asset 边界。",
|
||||
toolset_id: "toolset.onlyoffice_service",
|
||||
invocation_kind: InvocationKind::Job,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["assetId"],"properties":{"assetId":{"type":"string"},"workspaceId":{"type":"string"},"documentId":{"type":"string"},"userId":{"type":"string"},"sessionId":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const ONLYOFFICE_TOOL_SIGN: ToolSpec = ToolSpec {
|
||||
name: "onlyoffice_sign",
|
||||
display_name: "OnlyOffice 签名",
|
||||
description: "为 OnlyOffice config/document/editorConfig 生成 JWT 签名。",
|
||||
toolset_id: "toolset.onlyoffice_service",
|
||||
invocation_kind: InvocationKind::Job,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","properties":{"config":{"type":"object"},"secret":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const ONLYOFFICE_TOOL_PREPARE_PROXY: ToolSpec = ToolSpec {
|
||||
name: "onlyoffice_prepare_proxy",
|
||||
display_name: "OnlyOffice 代理预处理",
|
||||
description: "校验 proxy 回源目标并返回同源回源所需的上游 URL 与请求头。",
|
||||
toolset_id: "toolset.onlyoffice_service",
|
||||
invocation_kind: InvocationKind::Job,
|
||||
effect: ToolEffect::Read,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["encodedUrl"],"properties":{"encodedUrl":{"type":"string"},"method":{"enum":["GET","HEAD"]},"range":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const ONLYOFFICE_TOOL_PREPARE_CALLBACK: ToolSpec = ToolSpec {
|
||||
name: "onlyoffice_prepare_callback",
|
||||
display_name: "OnlyOffice callback 预处理",
|
||||
description: "解析 callback 状态、下载地址和 session 边界,供写回链继续执行。",
|
||||
toolset_id: "toolset.onlyoffice_service",
|
||||
invocation_kind: InvocationKind::Job,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["assetId","status","onlyofficeInternalUrl"],"properties":{"assetId":{"type":"string"},"documentId":{"type":"string"},"workspaceId":{"type":"string"},"userId":{"type":"string"},"sessionId":{"type":"string"},"status":{"type":"integer"},"url":{"type":"string"},"key":{"type":"string"},"onlyofficeInternalUrl":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const ONLYOFFICE_TOOL_PREPARE_FORCESAVE: ToolSpec = ToolSpec {
|
||||
name: "onlyoffice_prepare_forcesave",
|
||||
display_name: "OnlyOffice forcesave 预处理",
|
||||
description: "生成触发 forcesave 所需的请求序列与 JWT 负载。",
|
||||
toolset_id: "toolset.onlyoffice_service",
|
||||
invocation_kind: InvocationKind::Job,
|
||||
effect: ToolEffect::Write,
|
||||
requires_confirmation: false,
|
||||
input_schema_json:
|
||||
r#"{"type":"object","required":["assetId","key","onlyofficeInternalUrl"],"properties":{"assetId":{"type":"string"},"key":{"type":"string"},"onlyofficeInternalUrl":{"type":"string"},"secret":{"type":"string"}}}"#,
|
||||
};
|
||||
|
||||
pub const DOC_TOOLSET_READ: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.doc_read",
|
||||
display_name: "文档读取",
|
||||
description: "只读文档工具集合。",
|
||||
write_toolset: false,
|
||||
tool_names: &["doc_get", "doc_find"],
|
||||
};
|
||||
|
||||
pub const READONLY_TOOLSET: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.readonly",
|
||||
display_name: "只读工具",
|
||||
description: "Rust 只读工具集合。",
|
||||
write_toolset: false,
|
||||
tool_names: &["search_web"],
|
||||
};
|
||||
|
||||
pub const MEDIA_TOOLSET: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.media_read",
|
||||
display_name: "媒体读取",
|
||||
description: "Rust 媒体读取工具集合。",
|
||||
write_toolset: false,
|
||||
tool_names: &["image_read"],
|
||||
};
|
||||
|
||||
pub const DOC_TOOLSET_WRITE: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.doc_write",
|
||||
display_name: "文档写入",
|
||||
description: "写入文档工具集合。",
|
||||
write_toolset: true,
|
||||
tool_names: &["doc_insert_blocks", "doc_replace_range"],
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOLSET_READ: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.mindmap_read",
|
||||
display_name: "导图读取",
|
||||
description: "只读思维导图工具集合。",
|
||||
write_toolset: false,
|
||||
tool_names: &["mindmap_get", "mindmap_get_subtree"],
|
||||
};
|
||||
|
||||
pub const MINDMAP_TOOLSET_WRITE: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.mindmap_write",
|
||||
display_name: "导图写入",
|
||||
description: "写入思维导图的工具集合。",
|
||||
write_toolset: true,
|
||||
tool_names: &[
|
||||
"mindmap_put",
|
||||
"mindmap_apply_ops",
|
||||
"mindmap_expand_node",
|
||||
"mindmap_empty_trash",
|
||||
"mindmap_outline_to_mindmap",
|
||||
],
|
||||
};
|
||||
|
||||
pub const OBSERVE_TOOLSET_READ: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.observe_read",
|
||||
display_name: "统一观测",
|
||||
description: "按 request、trace、command 回查统一日志与事件视图。",
|
||||
write_toolset: false,
|
||||
tool_names: &["bridge_request_get", "bridge_trace_get", "bridge_command_get"],
|
||||
};
|
||||
|
||||
pub const RECOVERY_TOOLSET_JOB: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.recovery_job",
|
||||
display_name: "恢复与重建",
|
||||
description: "统一事件回放、索引重建与恢复类任务集合。",
|
||||
write_toolset: true,
|
||||
tool_names: &["event_replay", "index_rebuild"],
|
||||
};
|
||||
|
||||
pub const ONLYOFFICE_TOOLSET_SERVICE: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.onlyoffice_service",
|
||||
display_name: "OnlyOffice 服务边界",
|
||||
description: "供 Web route / CLI / AI 共享的 OnlyOffice 对象适配工具集合。",
|
||||
write_toolset: true,
|
||||
tool_names: &[
|
||||
"onlyoffice_session_resolve",
|
||||
"onlyoffice_sign",
|
||||
"onlyoffice_prepare_proxy",
|
||||
"onlyoffice_prepare_callback",
|
||||
"onlyoffice_prepare_forcesave",
|
||||
],
|
||||
};
|
||||
|
||||
pub const SLASH_TOOLSET_WRITE: ToolSetSpec = ToolSetSpec {
|
||||
id: "toolset.slash_write",
|
||||
display_name: "斜杠命令",
|
||||
description: "Rust 斜杠命令工具集合。",
|
||||
write_toolset: true,
|
||||
tool_names: &["slash_run"],
|
||||
};
|
||||
|
||||
pub const DOC_TOOL_REGISTRY: ToolRegistry = ToolRegistry::new(
|
||||
&[
|
||||
READONLY_TOOLSET,
|
||||
MEDIA_TOOLSET,
|
||||
SLASH_TOOLSET_WRITE,
|
||||
DOC_TOOLSET_READ,
|
||||
DOC_TOOLSET_WRITE,
|
||||
MINDMAP_TOOLSET_READ,
|
||||
MINDMAP_TOOLSET_WRITE,
|
||||
OBSERVE_TOOLSET_READ,
|
||||
RECOVERY_TOOLSET_JOB,
|
||||
ONLYOFFICE_TOOLSET_SERVICE,
|
||||
],
|
||||
&[
|
||||
SEARCH_WEB_TOOL,
|
||||
DOC_TOOL_GET,
|
||||
DOC_TOOL_FIND,
|
||||
IMAGE_READ_TOOL,
|
||||
DOC_TOOL_INSERT_BLOCKS,
|
||||
DOC_TOOL_REPLACE_RANGE,
|
||||
SLASH_RUN_TOOL,
|
||||
MINDMAP_TOOL_GET,
|
||||
MINDMAP_TOOL_GET_SUBTREE,
|
||||
MINDMAP_TOOL_PUT,
|
||||
MINDMAP_TOOL_APPLY_OPS,
|
||||
MINDMAP_TOOL_EXPAND_NODE,
|
||||
MINDMAP_TOOL_EMPTY_TRASH,
|
||||
MINDMAP_TOOL_OUTLINE_TO_MINDMAP,
|
||||
BRIDGE_TOOL_REQUEST_GET,
|
||||
BRIDGE_TOOL_TRACE_GET,
|
||||
BRIDGE_TOOL_COMMAND_GET,
|
||||
REPLAY_TOOL_EVENTS,
|
||||
INDEX_TOOL_REBUILD,
|
||||
ONLYOFFICE_TOOL_SESSION_RESOLVE,
|
||||
ONLYOFFICE_TOOL_SIGN,
|
||||
ONLYOFFICE_TOOL_PREPARE_PROXY,
|
||||
ONLYOFFICE_TOOL_PREPARE_CALLBACK,
|
||||
ONLYOFFICE_TOOL_PREPARE_FORCESAVE,
|
||||
],
|
||||
);
|
||||
|
||||
pub fn default_tool_registry() -> &'static ToolRegistry {
|
||||
&DOC_TOOL_REGISTRY
|
||||
}
|
||||
|
||||
pub fn tool_mode_label(mode: &ToolExecutionMode) -> &'static str {
|
||||
match mode {
|
||||
ToolExecutionMode::Plan => "plan",
|
||||
ToolExecutionMode::Result => "result",
|
||||
ToolExecutionMode::ExplainPlan => "explain-plan",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn invocation_kind_label(kind: &InvocationKind) -> &'static str {
|
||||
match kind {
|
||||
InvocationKind::Command => "command",
|
||||
InvocationKind::Query => "query",
|
||||
InvocationKind::Job => "job",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tool_effect_label(effect: &ToolEffect) -> &'static str {
|
||||
match effect {
|
||||
ToolEffect::Read => "read",
|
||||
ToolEffect::Write => "write",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user