Skip to repository content112 lines · 3.4 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T02:36:48.831Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
go_to_definition_tool.rs
1use std::fmt::Write;
2use std::sync::Arc;
3
4use super::symbol_locator::{LocationDisplay, SymbolLocator};
5use crate::{AgentTool, ToolCallEventStream, ToolInput};
6use agent_client_protocol::schema::v1 as acp;
7use gpui::{App, Entity, SharedString, Task};
8use project::Project;
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12/// Jumps to the definition of a symbol using the language server.
13///
14/// Returns the file path and line number of the symbol's definition, along with a snippet of the source code at that location.
15///
16/// Before using this tool, use read_file or grep to find the exact symbol name and line number of a usage you want to navigate from.
17#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
18pub struct GoToDefinitionToolInput {
19 /// The symbol to find the definition of.
20 pub symbol: SymbolLocator,
21}
22
23pub struct GoToDefinitionTool {
24 project: Entity<Project>,
25}
26
27impl GoToDefinitionTool {
28 pub fn new(project: Entity<Project>) -> Self {
29 Self { project }
30 }
31}
32
33impl AgentTool for GoToDefinitionTool {
34 type Input = GoToDefinitionToolInput;
35 type Output = String;
36
37 const NAME: &'static str = "go_to_definition";
38
39 fn kind() -> acp::ToolKind {
40 acp::ToolKind::Search
41 }
42
43 fn initial_title(
44 &self,
45 input: Result<Self::Input, serde_json::Value>,
46 _cx: &mut App,
47 ) -> SharedString {
48 if let Ok(input) = input {
49 format!("Go to definition of `{}`", input.symbol.symbol_name).into()
50 } else {
51 "Go to definition".into()
52 }
53 }
54
55 fn run(
56 self: Arc<Self>,
57 input: ToolInput<Self::Input>,
58 _event_stream: ToolCallEventStream,
59 cx: &mut App,
60 ) -> Task<Result<String, String>> {
61 let project = self.project.clone();
62 cx.spawn(async move |cx| {
63 let input = input
64 .recv()
65 .await
66 .map_err(|e| format!("Failed to receive tool input: {e}"))?;
67
68 let resolved = input.symbol.resolve(&project, cx).await?;
69
70 let definitions_task = project.update(cx, |project, cx| {
71 project.definitions(&resolved.buffer, resolved.position, cx)
72 });
73
74 let definitions = definitions_task
75 .await
76 .map_err(|e| format!("Go to definition failed: {e}"))?
77 .unwrap_or_default();
78
79 if definitions.is_empty() {
80 return Ok(format!(
81 "No definition found for '{}'.",
82 input.symbol.symbol_name
83 ));
84 }
85
86 let mut output = String::new();
87
88 if definitions.len() == 1 {
89 write!(output, "Definition of `{}`:\n", input.symbol.symbol_name).ok();
90 } else {
91 write!(
92 output,
93 "Found {} definitions of `{}`:\n",
94 definitions.len(),
95 input.symbol.symbol_name
96 )
97 .ok();
98 }
99
100 for link in &definitions {
101 let display = link
102 .target
103 .buffer
104 .read_with(cx, |_, cx| LocationDisplay::from_location(&link.target, cx));
105 write!(output, "\n## {display}\n").ok();
106 }
107
108 Ok(output)
109 })
110 }
111}
112