codetether_agent/tool/
lsp.rs1use super::{Tool, ToolResult};
4use anyhow::Result;
5use async_trait::async_trait;
6use serde_json::{Value, json};
7
8pub struct LspTool {
10 }
13
14impl LspTool {
15 pub fn new() -> Self {
16 Self {}
17 }
18}
19
20impl Default for LspTool {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26#[async_trait]
27impl Tool for LspTool {
28 fn id(&self) -> &str {
29 "lsp"
30 }
31
32 fn name(&self) -> &str {
33 "LSP Tool"
34 }
35
36 fn description(&self) -> &str {
37 "Perform Language Server Protocol (LSP) operations such as go-to-definition, find-references, hover, document-symbol, workspace-symbol, and more. This tool enables AI agents to query language servers for code intelligence features."
38 }
39
40 fn parameters(&self) -> Value {
41 json!({
42 "type": "object",
43 "properties": {
44 "action": {
45 "type": "string",
46 "description": "The LSP operation to perform",
47 "enum": [
48 "goToDefinition",
49 "findReferences",
50 "hover",
51 "documentSymbol",
52 "workspaceSymbol",
53 "goToImplementation",
54 "prepareCallHierarchy",
55 "incomingCalls",
56 "outgoingCalls"
57 ]
58 },
59 "file_path": {
60 "type": "string",
61 "description": "The absolute or relative path to the file"
62 },
63 "line": {
64 "type": "integer",
65 "description": "The line number (1-based, as shown in editors)",
66 "minimum": 1
67 },
68 "column": {
69 "type": "integer",
70 "description": "The character offset/column (1-based, as shown in editors)",
71 "minimum": 1
72 }
73 },
74 "required": ["action", "file_path"]
75 })
76 }
77
78 async fn execute(&self, args: Value) -> Result<ToolResult> {
79 let action = args["action"]
81 .as_str()
82 .ok_or_else(|| anyhow::anyhow!("action is required"))?;
83 let file_path = args["file_path"]
84 .as_str()
85 .ok_or_else(|| anyhow::anyhow!("file_path is required"))?;
86
87 let line = args["line"].as_u64().map(|n| n as usize);
89 let column = args["column"].as_u64().map(|n| n as usize);
90
91 let position_str = if line.is_some() && column.is_some() {
94 format!(" at line {}, column {}", line.unwrap(), column.unwrap())
95 } else {
96 "".to_string()
97 };
98
99 let output = format!(
100 "LSP operation '{}' for file '{}'{} would be executed here.\n\
101 Full implementation pending LSP client integration.",
102 action, file_path, position_str
103 );
104
105 Ok(ToolResult::success(output))
106 }
107}