Skip to content

Commit 9fa32bb

Browse files
authored
fix: Remove redundant Box::pin calls from async code (#106)
Yesterday, Clippy complained a lot about large futures. I couldn't figure out what the root cause was and just added them everywhere clippy complained. However, when adding to Zed I was getting stack overflows and was able to trace it to the Builder::into_connection_and_future where the futures with the connection were actually the root cause. Adding Box::pin there means we can remove them from all of the tests/examples/etc, which makes things look nice and beautiful again!
1 parent dda28f2 commit 9fa32bb

34 files changed

+1338
-1355
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ async-trait = "0.1"
7676
boxfnonce = "0.1.1"
7777
chrono = "0.4"
7878
derive_more = { version = "2", features = ["from"] }
79-
futures = "0.3.31"
79+
futures = "0.3.32"
8080
futures-concurrency = "7.6.3"
8181
fxhash = "0.2.1"
8282
jsonrpcmsg = "0.1.2"

src/agent-client-protocol-conductor/src/conductor/mcp_bridge/actor.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl McpBridgeConnectionActor {
4343
to_mcp_client_rx,
4444
} = self;
4545

46-
let client = mcp::Client
46+
let result = mcp::Client
4747
.builder()
4848
.name(format!("mpc-client-to-conductor({connection_id})"))
4949
// When we receive a message from the MCP client, forward it to the conductor
@@ -70,8 +70,8 @@ impl McpBridgeConnectionActor {
7070
mcp_connection_to_client.send_proxied_message(message)?;
7171
}
7272
Ok(())
73-
});
74-
let result = Box::pin(client).await;
73+
})
74+
.await;
7575

7676
conductor_tx
7777
.send(ConductorMessage::McpConnectionDisconnected {

src/agent-client-protocol-conductor/src/lib.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -319,12 +319,10 @@ impl ConductorArgs {
319319
(None, false) => (None, None),
320320
};
321321

322-
Box::pin(
323-
self.run(debug_logger.as_ref(), trace_writer)
324-
.instrument(tracing::info_span!("conductor", pid = %pid, cwd = %cwd)),
325-
)
326-
.await
327-
.map_err(|err| anyhow::anyhow!("{err}"))
322+
self.run(debug_logger.as_ref(), trace_writer)
323+
.instrument(tracing::info_span!("conductor", pid = %pid, cwd = %cwd))
324+
.await
325+
.map_err(|err| anyhow::anyhow!("{err}"))
328326
}
329327

330328
async fn run(
@@ -334,23 +332,23 @@ impl ConductorArgs {
334332
) -> Result<(), agent_client_protocol_core::Error> {
335333
match self.command {
336334
ConductorCommand::Agent { name, components } => {
337-
Box::pin(initialize_conductor(
335+
initialize_conductor(
338336
debug_logger,
339337
trace_writer,
340338
name,
341339
components,
342340
ConductorImpl::new_agent,
343-
))
341+
)
344342
.await
345343
}
346344
ConductorCommand::Proxy { name, proxies } => {
347-
Box::pin(initialize_conductor(
345+
initialize_conductor(
348346
debug_logger,
349347
trace_writer,
350348
name,
351349
proxies,
352350
ConductorImpl::new_proxy,
353-
))
351+
)
354352
.await
355353
}
356354
ConductorCommand::Mcp { port } => mcp_bridge::run_mcp_bridge(port).await,

src/agent-client-protocol-conductor/tests/arrow_proxy_eliza.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,27 @@ async fn test_conductor_with_arrow_proxy_and_test_agent()
2929

3030
// Spawn the conductor
3131
let conductor_handle = tokio::spawn(async move {
32-
Box::pin(
33-
ConductorImpl::new_agent(
34-
"conductor".to_string(),
35-
ProxiesAndAgent::new(test_agent).proxy(arrow_proxy_agent),
36-
McpBridgeMode::default(),
37-
)
38-
.run(agent_client_protocol_core::ByteStreams::new(
39-
conductor_write.compat_write(),
40-
conductor_read.compat(),
41-
)),
32+
ConductorImpl::new_agent(
33+
"conductor".to_string(),
34+
ProxiesAndAgent::new(test_agent).proxy(arrow_proxy_agent),
35+
McpBridgeMode::default(),
4236
)
37+
.run(agent_client_protocol_core::ByteStreams::new(
38+
conductor_write.compat_write(),
39+
conductor_read.compat(),
40+
))
4341
.await
4442
});
4543

4644
// Wait for editor to complete and get the result
4745
let result = tokio::time::timeout(std::time::Duration::from_secs(30), async move {
48-
let result = Box::pin(yopo::prompt(
46+
let result = yopo::prompt(
4947
agent_client_protocol_core::ByteStreams::new(
5048
editor_write.compat_write(),
5149
editor_read.compat(),
5250
),
5351
TestyCommand::Greet.to_prompt(),
54-
))
52+
)
5553
.await?;
5654

5755
tracing::debug!(?result, "Received response from arrow proxy chain");

src/agent-client-protocol-conductor/tests/empty_conductor_eliza.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,29 +54,27 @@ async fn test_conductor_with_empty_conductor_and_test_agent()
5454

5555
// Spawn the conductor
5656
let conductor_handle = tokio::spawn(async move {
57-
Box::pin(
58-
ConductorImpl::new_agent(
59-
"outer-conductor".to_string(),
60-
ProxiesAndAgent::new(Testy::new()).proxy(MockEmptyConductor),
61-
McpBridgeMode::default(),
62-
)
63-
.run(agent_client_protocol_core::ByteStreams::new(
64-
conductor_write.compat_write(),
65-
conductor_read.compat(),
66-
)),
57+
ConductorImpl::new_agent(
58+
"outer-conductor".to_string(),
59+
ProxiesAndAgent::new(Testy::new()).proxy(MockEmptyConductor),
60+
McpBridgeMode::default(),
6761
)
62+
.run(agent_client_protocol_core::ByteStreams::new(
63+
conductor_write.compat_write(),
64+
conductor_read.compat(),
65+
))
6866
.await
6967
});
7068

7169
// Wait for editor to complete and get the result
7270
let result = tokio::time::timeout(std::time::Duration::from_secs(30), async move {
73-
let result = Box::pin(yopo::prompt(
71+
let result = yopo::prompt(
7472
agent_client_protocol_core::ByteStreams::new(
7573
editor_write.compat_write(),
7674
editor_read.compat(),
7775
),
7876
TestyCommand::Greet.to_prompt(),
79-
))
77+
)
8078
.await?;
8179

8280
tracing::debug!(?result, "Received response from empty conductor chain");

src/agent-client-protocol-conductor/tests/initialization_sequence.rs

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,15 @@ async fn run_test_with_components(
134134
.builder()
135135
.name("editor-to-connector")
136136
.with_spawned(|_cx| async move {
137-
Box::pin(
138-
ConductorImpl::new_agent(
139-
"conductor".to_string(),
140-
ProxiesAndAgent::new(Testy::new()).proxies(proxies),
141-
McpBridgeMode::default(),
142-
)
143-
.run(agent_client_protocol_core::ByteStreams::new(
144-
conductor_out.compat_write(),
145-
conductor_in.compat(),
146-
)),
137+
ConductorImpl::new_agent(
138+
"conductor".to_string(),
139+
ProxiesAndAgent::new(Testy::new()).proxies(proxies),
140+
McpBridgeMode::default(),
147141
)
142+
.run(agent_client_protocol_core::ByteStreams::new(
143+
conductor_out.compat_write(),
144+
conductor_in.compat(),
145+
))
148146
.await
149147
})
150148
.connect_with(transport, editor_task)
@@ -156,22 +154,19 @@ async fn test_single_component_gets_initialize_request()
156154
-> Result<(), agent_client_protocol_core::Error> {
157155
// Single component (agent) should receive InitializeRequest - we use ElizaAgent
158156
// which properly handles InitializeRequest
159-
Box::pin(run_test_with_components(
160-
vec![],
161-
async |connection_to_editor| {
162-
let init_response = recv(
163-
connection_to_editor.send_request(InitializeRequest::new(ProtocolVersion::LATEST)),
164-
)
165-
.await;
166-
167-
assert!(
168-
init_response.is_ok(),
169-
"Initialize should succeed: {init_response:?}"
170-
);
171-
172-
Ok::<(), agent_client_protocol_core::Error>(())
173-
},
174-
))
157+
run_test_with_components(vec![], async |connection_to_editor| {
158+
let init_response = recv(
159+
connection_to_editor.send_request(InitializeRequest::new(ProtocolVersion::LATEST)),
160+
)
161+
.await;
162+
163+
assert!(
164+
init_response.is_ok(),
165+
"Initialize should succeed: {init_response:?}"
166+
);
167+
168+
Ok::<(), agent_client_protocol_core::Error>(())
169+
})
175170
.await?;
176171

177172
Ok(())
@@ -184,7 +179,7 @@ async fn test_two_components_proxy_gets_initialize_proxy()
184179
// Second component (agent, ElizaAgent) gets InitializeRequest
185180
let component1 = InitConfig::new();
186181

187-
Box::pin(run_test_with_components(
182+
run_test_with_components(
188183
vec![InitComponent::new(&component1)],
189184
async |connection_to_editor| {
190185
let init_response = recv(
@@ -199,7 +194,7 @@ async fn test_two_components_proxy_gets_initialize_proxy()
199194

200195
Ok::<(), agent_client_protocol_core::Error>(())
201196
},
202-
))
197+
)
203198
.await?;
204199

205200
// First component (proxy) should receive InitializeProxyRequest
@@ -222,7 +217,7 @@ async fn test_three_components_all_proxies_get_initialize_proxy()
222217
let component1 = InitConfig::new();
223218
let component2 = InitConfig::new();
224219

225-
Box::pin(run_test_with_components(
220+
run_test_with_components(
226221
vec![
227222
InitComponent::new(&component1),
228223
InitComponent::new(&component2),
@@ -240,7 +235,7 @@ async fn test_three_components_all_proxies_get_initialize_proxy()
240235

241236
Ok::<(), agent_client_protocol_core::Error>(())
242237
},
243-
))
238+
)
244239
.await?;
245240

246241
// First two components (proxies) should receive InitializeProxyRequest
@@ -307,17 +302,15 @@ async fn run_bad_proxy_test(
307302
.builder()
308303
.name("editor-to-connector")
309304
.with_spawned(|_cx| async move {
310-
Box::pin(
311-
ConductorImpl::new_agent(
312-
"conductor".to_string(),
313-
ProxiesAndAgent::new(agent).proxies(proxies),
314-
McpBridgeMode::default(),
315-
)
316-
.run(agent_client_protocol_core::ByteStreams::new(
317-
conductor_out.compat_write(),
318-
conductor_in.compat(),
319-
)),
305+
ConductorImpl::new_agent(
306+
"conductor".to_string(),
307+
ProxiesAndAgent::new(agent).proxies(proxies),
308+
McpBridgeMode::default(),
320309
)
310+
.run(agent_client_protocol_core::ByteStreams::new(
311+
conductor_out.compat_write(),
312+
conductor_in.compat(),
313+
))
321314
.await
322315
})
323316
.connect_with(transport, editor_task)
@@ -329,7 +322,7 @@ async fn test_conductor_rejects_initialize_proxy_forwarded_to_agent()
329322
-> Result<(), agent_client_protocol_core::Error> {
330323
// BadProxy incorrectly forwards InitializeProxyRequest to the agent.
331324
// The conductor should reject this with an error.
332-
let result = Box::pin(run_bad_proxy_test(
325+
let result = run_bad_proxy_test(
333326
vec![DynConnectTo::new(BadProxy)],
334327
DynConnectTo::new(Testy::new()),
335328
async |connection_to_editor| {
@@ -347,7 +340,7 @@ async fn test_conductor_rejects_initialize_proxy_forwarded_to_agent()
347340

348341
Ok::<(), agent_client_protocol_core::Error>(())
349342
},
350-
))
343+
)
351344
.await;
352345

353346
match result {
@@ -368,7 +361,7 @@ async fn test_conductor_rejects_initialize_proxy_forwarded_to_proxy()
368361
-> Result<(), agent_client_protocol_core::Error> {
369362
// BadProxy incorrectly forwards InitializeProxyRequest to another proxy.
370363
// The conductor should reject this with an error.
371-
let result = Box::pin(run_bad_proxy_test(
364+
let result = run_bad_proxy_test(
372365
vec![
373366
DynConnectTo::new(BadProxy),
374367
DynConnectTo::new(InitComponent::new(&InitConfig::new())), // This proxy will receive the bad request
@@ -390,7 +383,7 @@ async fn test_conductor_rejects_initialize_proxy_forwarded_to_proxy()
390383

391384
Ok::<(), agent_client_protocol_core::Error>(())
392385
},
393-
))
386+
)
394387
.await;
395388

396389
// The error might bubble up through run_test_with_components instead

0 commit comments

Comments
 (0)