Fix remaining agent server integration tests (#35222)

Release Notes:

- N/A
This commit is contained in:
Agus Zubiaga 2025-07-29 09:40:59 -03:00 committed by GitHub
parent 8f952f1b58
commit 9353ba7887
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 33 additions and 20 deletions

View file

@ -1597,6 +1597,7 @@ mod tests {
name: "test", name: "test",
connection, connection,
child_status: io_task, child_status: io_task,
current_thread: thread_rc,
}; };
AcpThread::new( AcpThread::new(

View file

@ -7,6 +7,7 @@ use gpui::{AppContext as _, AsyncApp, Entity, Task, WeakEntity};
use project::Project; use project::Project;
use std::{cell::RefCell, error::Error, fmt, path::Path, rc::Rc}; use std::{cell::RefCell, error::Error, fmt, path::Path, rc::Rc};
use ui::App; use ui::App;
use util::ResultExt as _;
use crate::{AcpThread, AgentConnection}; use crate::{AcpThread, AgentConnection};
@ -46,7 +47,7 @@ impl acp_old::Client for OldAcpClientDelegate {
thread.push_assistant_content_block(thought.into(), true, cx) thread.push_assistant_content_block(thought.into(), true, cx)
} }
}) })
.ok(); .log_err();
})?; })?;
Ok(()) Ok(())
@ -364,6 +365,7 @@ pub struct OldAcpAgentConnection {
pub name: &'static str, pub name: &'static str,
pub connection: acp_old::AgentConnection, pub connection: acp_old::AgentConnection,
pub child_status: Task<Result<()>>, pub child_status: Task<Result<()>>,
pub current_thread: Rc<RefCell<WeakEntity<AcpThread>>>,
} }
impl AgentConnection for OldAcpAgentConnection { impl AgentConnection for OldAcpAgentConnection {
@ -383,6 +385,7 @@ impl AgentConnection for OldAcpAgentConnection {
} }
.into_any(), .into_any(),
); );
let current_thread = self.current_thread.clone();
cx.spawn(async move |cx| { cx.spawn(async move |cx| {
let result = task.await?; let result = task.await?;
let result = acp_old::InitializeParams::response_from_any(result)?; let result = acp_old::InitializeParams::response_from_any(result)?;
@ -396,6 +399,7 @@ impl AgentConnection for OldAcpAgentConnection {
let session_id = acp::SessionId("acp-old-no-id".into()); let session_id = acp::SessionId("acp-old-no-id".into());
AcpThread::new(self.clone(), project, session_id, cx) AcpThread::new(self.clone(), project, session_id, cx)
}); });
current_thread.replace(thread.downgrade());
thread thread
}) })
}) })

View file

@ -310,7 +310,7 @@ pub(crate) mod tests {
AgentServerCommand { AgentServerCommand {
path: cli_path, path: cli_path,
args: vec!["mcp".into()], args: vec![],
env: None, env: None,
} }
} }

View file

@ -12,7 +12,6 @@ use futures::{FutureExt, StreamExt, channel::mpsc, select};
use gpui::{Entity, TestAppContext}; use gpui::{Entity, TestAppContext};
use indoc::indoc; use indoc::indoc;
use project::{FakeFs, Project}; use project::{FakeFs, Project};
use serde_json::json;
use settings::{Settings, SettingsStore}; use settings::{Settings, SettingsStore};
use util::path; use util::path;
@ -27,7 +26,11 @@ pub async fn test_basic(server: impl AgentServer + 'static, cx: &mut TestAppCont
.unwrap(); .unwrap();
thread.read_with(cx, |thread, _| { thread.read_with(cx, |thread, _| {
assert_eq!(thread.entries().len(), 2); assert!(
thread.entries().len() >= 2,
"Expected at least 2 entries. Got: {:?}",
thread.entries()
);
assert!(matches!( assert!(matches!(
thread.entries()[0], thread.entries()[0],
AgentThreadEntry::UserMessage(_) AgentThreadEntry::UserMessage(_)
@ -108,19 +111,19 @@ pub async fn test_path_mentions(server: impl AgentServer + 'static, cx: &mut Tes
} }
pub async fn test_tool_call(server: impl AgentServer + 'static, cx: &mut TestAppContext) { pub async fn test_tool_call(server: impl AgentServer + 'static, cx: &mut TestAppContext) {
let fs = init_test(cx).await; let _fs = init_test(cx).await;
fs.insert_tree(
path!("/private/tmp"), let tempdir = tempfile::tempdir().unwrap();
json!({"foo": "Lorem ipsum dolor", "bar": "bar", "baz": "baz"}), let foo_path = tempdir.path().join("foo");
) std::fs::write(&foo_path, "Lorem ipsum dolor").expect("failed to write file");
.await;
let project = Project::test(fs, [path!("/private/tmp").as_ref()], cx).await; let project = Project::example([tempdir.path()], &mut cx.to_async()).await;
let thread = new_test_thread(server, project.clone(), "/private/tmp", cx).await; let thread = new_test_thread(server, project.clone(), "/private/tmp", cx).await;
thread thread
.update(cx, |thread, cx| { .update(cx, |thread, cx| {
thread.send_raw( thread.send_raw(
"Read the '/private/tmp/foo' file and tell me what you see.", &format!("Read {} and tell me what you see.", foo_path.display()),
cx, cx,
) )
}) })
@ -143,6 +146,8 @@ pub async fn test_tool_call(server: impl AgentServer + 'static, cx: &mut TestApp
.any(|entry| { matches!(entry, AgentThreadEntry::AssistantMessage(_)) }) .any(|entry| { matches!(entry, AgentThreadEntry::AssistantMessage(_)) })
); );
}); });
drop(tempdir);
} }
pub async fn test_tool_call_with_confirmation( pub async fn test_tool_call_with_confirmation(
@ -155,7 +160,7 @@ pub async fn test_tool_call_with_confirmation(
let thread = new_test_thread(server, project.clone(), "/private/tmp", cx).await; let thread = new_test_thread(server, project.clone(), "/private/tmp", cx).await;
let full_turn = thread.update(cx, |thread, cx| { let full_turn = thread.update(cx, |thread, cx| {
thread.send_raw( thread.send_raw(
r#"Run `touch hello.txt && echo "Hello, world!" | tee hello.txt`"#, r#"Run exactly `touch hello.txt && echo "Hello, world!" | tee hello.txt` in the terminal."#,
cx, cx,
) )
}); });
@ -175,10 +180,10 @@ pub async fn test_tool_call_with_confirmation(
) )
.await; .await;
let tool_call_id = thread.read_with(cx, |thread, _cx| { let tool_call_id = thread.read_with(cx, |thread, cx| {
let AgentThreadEntry::ToolCall(ToolCall { let AgentThreadEntry::ToolCall(ToolCall {
id, id,
content, label,
status: ToolCallStatus::WaitingForConfirmation { .. }, status: ToolCallStatus::WaitingForConfirmation { .. },
.. ..
}) = &thread }) = &thread
@ -190,7 +195,8 @@ pub async fn test_tool_call_with_confirmation(
panic!(); panic!();
}; };
assert!(content.iter().any(|c| c.to_markdown(_cx).contains("touch"))); let label = label.read(cx).source();
assert!(label.contains("touch"), "Got: {}", label);
id.clone() id.clone()
}); });
@ -242,7 +248,7 @@ pub async fn test_cancel(server: impl AgentServer + 'static, cx: &mut TestAppCon
let thread = new_test_thread(server, project.clone(), "/private/tmp", cx).await; let thread = new_test_thread(server, project.clone(), "/private/tmp", cx).await;
let full_turn = thread.update(cx, |thread, cx| { let full_turn = thread.update(cx, |thread, cx| {
thread.send_raw( thread.send_raw(
r#"Run `touch hello.txt && echo "Hello, world!" >> hello.txt`"#, r#"Run exactly `touch hello.txt && echo "Hello, world!" | tee hello.txt` in the terminal."#,
cx, cx,
) )
}); });
@ -262,10 +268,10 @@ pub async fn test_cancel(server: impl AgentServer + 'static, cx: &mut TestAppCon
) )
.await; .await;
thread.read_with(cx, |thread, _cx| { thread.read_with(cx, |thread, cx| {
let AgentThreadEntry::ToolCall(ToolCall { let AgentThreadEntry::ToolCall(ToolCall {
id, id,
content, label,
status: ToolCallStatus::WaitingForConfirmation { .. }, status: ToolCallStatus::WaitingForConfirmation { .. },
.. ..
}) = &thread.entries()[first_tool_call_ix] }) = &thread.entries()[first_tool_call_ix]
@ -273,7 +279,8 @@ pub async fn test_cancel(server: impl AgentServer + 'static, cx: &mut TestAppCon
panic!("{:?}", thread.entries()[1]); panic!("{:?}", thread.entries()[1]);
}; };
assert!(content.iter().any(|c| c.to_markdown(_cx).contains("touch"))); let label = label.read(cx).source();
assert!(label.contains("touch"), "Got: {}", label);
id.clone() id.clone()
}); });

View file

@ -107,6 +107,7 @@ impl AgentServer for Gemini {
name, name,
connection, connection,
child_status, child_status,
current_thread: thread_rc,
}); });
Ok(connection) Ok(connection)