use agent_contracts::tool::ToolSpecView;
use agent_types::common::ids::{ToolId, ToolName};
use agent_types::tool::spec_types::{EffectProfile, InputSchemaRef, OutputContract};
#[derive(Debug, Clone)]
pub struct LspToolSpec {
id: ToolId,
name: ToolName,
description: String,
input_schema: InputSchemaRef,
output_contract: OutputContract,
effect_profile: EffectProfile,
}
impl LspToolSpec {
pub fn new() -> Self {
let schema = serde_json::json!({
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["diagnostics", "hover", "definition", "references", "symbols", "implementation", "prepare_call_hierarchy", "incoming_calls", "outgoing_calls"],
"description": "LSP action:\n- diagnostics: compiler errors/warnings for a file\n- hover: type info and docs at a position\n- definition: where a symbol is defined\n- references: all usages of a symbol\n- symbols: list symbols in a file, or search workspace symbols by query\n- implementation: concrete implementations of an interface or abstract method\n- prepare_call_hierarchy: call hierarchy item at position (name, kind, location)\n- incoming_calls: all callers of the function at position\n- outgoing_calls: all functions called by the function at position"
},
"file_path": {
"type": "string",
"description": "Absolute or workspace-relative path to the source file. Required for all actions."
},
"line": {
"type": "integer",
"description": "1-based line number. Required for: hover, definition, references."
},
"column": {
"type": "integer",
"description": "1-based column number. Required for: hover, definition, references."
},
"query": {
"type": "string",
"description": "Symbol name filter for 'symbols' action. Triggers workspace-wide search. Omit to list all symbols in file_path."
},
"include_declaration": {
"type": "boolean",
"description": "For 'references': include the declaration site in results. Default: true."
}
},
"required": ["action", "file_path"]
});
Self {
id: ToolId("builtin_lsp".to_string()),
name: ToolName("lsp".to_string()),
description: "Query language server (LSP) for code diagnostics, symbol info, navigation, and call hierarchy.".to_string(),
input_schema: InputSchemaRef { schema },
output_contract: OutputContract {
description: "LSP query result".to_string(),
},
effect_profile: EffectProfile {
reads_filesystem: true,
writes_filesystem: false,
network_access: false,
side_effects: false,
},
}
}
}
impl Default for LspToolSpec {
fn default() -> Self {
Self::new()
}
}
impl ToolSpecView for LspToolSpec {
fn id(&self) -> &ToolId {
&self.id
}
fn name(&self) -> &ToolName {
&self.name
}
fn description(&self) -> &str {
&self.description
}
fn input_schema(&self) -> &InputSchemaRef {
&self.input_schema
}
fn output_contract(&self) -> &OutputContract {
&self.output_contract
}
fn effect_profile(&self) -> &EffectProfile {
&self.effect_profile
}
}