Skip to repository content117 lines · 3.8 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:34:39.731Z 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
get_code_actions_tool.rs
1use std::fmt::Write;
2use std::sync::Arc;
3
4use agent_client_protocol::schema::v1 as acp;
5use gpui::{App, Entity, SharedString, Task};
6use project::Project;
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9
10use super::symbol_locator::{CodeActionStore, PendingCodeActions, SymbolLocator};
11use crate::{AgentTool, ToolCallEventStream, ToolInput};
12
13/// Gets the list of available code actions at a symbol location from the language server.
14///
15/// Code actions include quick fixes, refactorings, and other automated transformations suggested by the language server (e.g. "Add missing import", "Extract to function").
16///
17/// Returns a numbered list of available actions. Use apply_code_action with the corresponding number to apply one.
18///
19/// Before using this tool, use read_file or grep to find the exact symbol name and line number.
20#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
21pub struct GetCodeActionsToolInput {
22 /// The symbol to get code actions for.
23 pub symbol: SymbolLocator,
24}
25
26pub struct GetCodeActionsTool {
27 project: Entity<Project>,
28 code_action_store: CodeActionStore,
29}
30
31impl GetCodeActionsTool {
32 pub fn new(project: Entity<Project>, code_action_store: CodeActionStore) -> Self {
33 Self {
34 project,
35 code_action_store,
36 }
37 }
38}
39
40impl AgentTool for GetCodeActionsTool {
41 type Input = GetCodeActionsToolInput;
42 type Output = String;
43
44 const NAME: &'static str = "get_code_actions";
45
46 fn kind() -> acp::ToolKind {
47 acp::ToolKind::Search
48 }
49
50 fn initial_title(
51 &self,
52 input: Result<Self::Input, serde_json::Value>,
53 _cx: &mut App,
54 ) -> SharedString {
55 if let Ok(input) = input {
56 format!("Get code actions for `{}`", input.symbol.symbol_name).into()
57 } else {
58 "Get code actions".into()
59 }
60 }
61
62 fn run(
63 self: Arc<Self>,
64 input: ToolInput<Self::Input>,
65 _event_stream: ToolCallEventStream,
66 cx: &mut App,
67 ) -> Task<Result<String, String>> {
68 let project = self.project.clone();
69 let store = self.code_action_store.clone();
70 cx.spawn(async move |cx| {
71 let input = input
72 .recv()
73 .await
74 .map_err(|e| format!("Failed to receive tool input: {e}"))?;
75
76 let resolved = input.symbol.resolve(&project, cx).await?;
77
78 let actions_task = project.update(cx, |project, cx| {
79 let range = resolved.position..resolved.position;
80 project.code_actions(&resolved.buffer, range, None, cx)
81 });
82
83 let actions = actions_task
84 .await
85 .map_err(|e| format!("Failed to get code actions: {e}"))?
86 .unwrap_or_default();
87
88 if actions.is_empty() {
89 store.update(cx, |store, _cx| *store = None);
90 return Ok(format!(
91 "No code actions available for '{}' at this location.",
92 input.symbol.symbol_name
93 ));
94 }
95
96 let mut output = format!("Found {} code action(s):\n", actions.len());
97 for (i, action) in actions.iter().enumerate() {
98 writeln!(output, "{}. {}", i + 1, action.lsp_action.title()).ok();
99 }
100 write!(
101 output,
102 "\nUse apply_code_action with the number of the action you want to apply."
103 )
104 .ok();
105
106 store.update(cx, |store, _cx| {
107 *store = Some(PendingCodeActions {
108 actions,
109 buffer: resolved.buffer,
110 });
111 });
112
113 Ok(output)
114 })
115 }
116}
117