Skip to content

Commit 2d0aa6e

Browse files
authored
Eliminate UI polling (#32)
1 parent 207f7aa commit 2d0aa6e

File tree

16 files changed

+1503
-679
lines changed

16 files changed

+1503
-679
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/code_assistant/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ rand = "0.8.5"
5656

5757
# Diff visualization
5858
similar = { version = "2.5.0", features = ["inline"] }
59+
async-channel = "2.3.1"
5960

6061
[dev-dependencies]
6162
axum = "0.7"

crates/code_assistant/src/agent/runner.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::agent::tool_description_generator::generate_tool_documentation;
22
use crate::agent::types::{ToolExecution, ToolRequest};
33
use crate::config::ProjectManager;
44
use crate::persistence::StatePersistence;
5-
use crate::tools::core::{ToolContext, ToolRegistry, ToolScope};
5+
use crate::tools::core::{ResourcesTracker, ToolContext, ToolRegistry, ToolScope};
66
use crate::tools::{parse_tool_xml, TOOL_TAG_PREFIX};
77
use crate::types::*;
88
use crate::ui::{streaming::create_stream_processor, UIMessage, UserInterface};
@@ -112,8 +112,8 @@ impl Agent {
112112
Ok(())
113113
}
114114

115-
pub async fn get_input_from_ui(&self, prompt: &str) -> Result<String> {
116-
self.ui.get_input(prompt).await.map_err(|e| e.into())
115+
pub async fn get_input_from_ui(&self) -> Result<String> {
116+
self.ui.get_input().await.map_err(|e| e.into())
117117
}
118118

119119
/// Handles the interaction with the LLM to get the next assistant message.
@@ -160,7 +160,7 @@ impl Agent {
160160
/// Handles the case where no tool requests are made by the LLM.
161161
/// Prompts the user for input and adds it to the message history.
162162
async fn solicit_user_input(&mut self) -> Result<()> {
163-
let user_input = self.get_input_from_ui("").await?;
163+
let user_input = self.get_input_from_ui().await?;
164164
self.ui
165165
.display(UIMessage::UserInput(user_input.clone()))
166166
.await?;
@@ -730,7 +730,7 @@ impl Agent {
730730

731731
// Update status to Running before execution
732732
self.ui
733-
.update_tool_status(&tool_request.id, crate::ui::ToolStatus::Running, None)
733+
.update_tool_status(&tool_request.id, crate::ui::ToolStatus::Running, None, None)
734734
.await?;
735735

736736
// Get the tool - could fail with UnknownTool
@@ -764,9 +764,13 @@ impl Agent {
764764
// Generate status string from result
765765
let short_output = result.as_render().status();
766766

767+
// Generate isolated output from result
768+
let mut resources_tracker = ResourcesTracker::new();
769+
let output = result.as_render().render(&mut resources_tracker);
770+
767771
// Update tool status with result
768772
self.ui
769-
.update_tool_status(&tool_request.id, status, Some(short_output))
773+
.update_tool_status(&tool_request.id, status, Some(short_output), Some(output))
770774
.await?;
771775

772776
// Create and store the ToolExecution record

crates/code_assistant/src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,7 @@ fn run_agent_gpui(
378378
agent.start_with_task(task_str).await.unwrap();
379379
} else {
380380
// In GUI mode with no task, prompt the user for a task
381-
let task_prompt = "Please enter the task you want me to perform:";
382-
let task_from_ui = agent.get_input_from_ui(task_prompt).await.unwrap();
381+
let task_from_ui = agent.get_input_from_ui().await.unwrap();
383382
agent.start_with_task(task_from_ui).await.unwrap();
384383
}
385384
});

crates/code_assistant/src/tests/mocks.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl UserInterface for MockUI {
190190
Ok(())
191191
}
192192

193-
async fn get_input(&self, _prompt: &str) -> Result<String, UIError> {
193+
async fn get_input(&self) -> Result<String, UIError> {
194194
self.responses
195195
.lock()
196196
.unwrap()
@@ -234,6 +234,7 @@ impl UserInterface for MockUI {
234234
_tool_id: &str,
235235
_status: ToolStatus,
236236
_message: Option<String>,
237+
_output: Option<String>,
237238
) -> Result<(), UIError> {
238239
// Mock implementation does nothing with the tool status
239240
Ok(())

crates/code_assistant/src/tools/tests.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ use std::path::PathBuf;
1111
use crate::tools::impls::{ExecuteCommandTool, ReplaceInFileTool};
1212
use crate::utils::CommandOutput;
1313

14-
// Make the MockProjectManager public so it can be used by other tests
15-
1614
#[tokio::test]
1715
async fn test_read_files_tool() -> Result<()> {
1816
// Create a tool registry
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::ui::gpui::parameter_renderers::ParameterRenderer;
2+
use gpui::{div, px, rgba, Element, FontWeight, ParentElement, Styled};
3+
4+
/// Renderer for the "content" parameter of the "write_file" tool
5+
pub struct ContentRenderer;
6+
7+
impl ParameterRenderer for ContentRenderer {
8+
fn supported_parameters(&self) -> Vec<(String, String)> {
9+
vec![("write_file".to_string(), "content".to_string())]
10+
}
11+
12+
fn render(
13+
&self,
14+
_tool_name: &str,
15+
_param_name: &str,
16+
param_value: &str,
17+
theme: &gpui_component::theme::Theme,
18+
) -> gpui::AnyElement {
19+
// Container for the content - no parameter name shown
20+
div()
21+
.rounded_md()
22+
.bg(if theme.is_dark() {
23+
rgba(0x0A0A0AFF) // Darker background in Dark Mode
24+
} else {
25+
rgba(0xEAEAEAFF) // Lighter background in Light Mode
26+
})
27+
.p_2()
28+
.text_size(px(15.))
29+
.font_weight(FontWeight(500.0))
30+
.child(param_value.to_string())
31+
.into_any()
32+
}
33+
34+
fn is_full_width(&self, _tool_name: &str, _param_name: &str) -> bool {
35+
true // Content parameter is always full-width
36+
}
37+
}

0 commit comments

Comments
 (0)