zagens_core/engine/subagent_port.rs
1//! Sub-agent spawn outcome / error types (P2 tool_execution portization).
2//!
3//! M3 (Engine-struct strangler) replaced the original `SubAgentSpawnPort`
4//! trait with [`SubAgentHost`](crate::engine::hosts::SubAgentHost), which
5//! covers the same spawn / list surface plus `running_count` and uses the
6//! clearer `list_with_cleanup` method name. The old `SubAgentSpawnPort`
7//! trait is preserved as a deprecated re-export shim
8//! (`pub trait SubAgentSpawnPort = SubAgentHost;`-flavored, via blanket
9//! impl) for one release so existing imports keep building.
10
11use async_trait::async_trait;
12
13use crate::subagent::SubAgentResult;
14
15/// Outcome of spawning a background sub-agent from the engine op loop.
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct SubAgentSpawnOutcome {
18 pub agent_id: String,
19}
20
21/// Errors surfaced when sub-agent spawn cannot proceed.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum SubAgentSpawnError {
24 NoClient,
25 SpawnFailed(String),
26}
27
28impl std::fmt::Display for SubAgentSpawnError {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 Self::NoClient => write!(f, "API client not configured"),
32 Self::SpawnFailed(msg) => write!(f, "{msg}"),
33 }
34 }
35}
36
37impl std::error::Error for SubAgentSpawnError {}
38
39/// Deprecated alias for [`SubAgentHost`](crate::engine::hosts::SubAgentHost).
40///
41/// Kept for one release after the M3 rename
42/// (`SubAgentSpawnPort` → `SubAgentHost`). The new trait keeps the
43/// `spawn_general_subagent` / `list_subagents` methods so existing impls
44/// (e.g. `impl SubAgentSpawnPort for Engine` in tui) continue to compile
45/// without behavior change; new code should impl `SubAgentHost` directly
46/// and use `spawn_general` / `list_with_cleanup` / `running_count`.
47#[deprecated(
48 since = "0.8.16",
49 note = "use `zagens_core::engine::hosts::SubAgentHost` instead; \
50 this alias will be removed in the next release"
51)]
52#[async_trait]
53pub trait SubAgentSpawnPort: Send + Sync {
54 async fn spawn_general_subagent(
55 &self,
56 prompt: &str,
57 ) -> Result<SubAgentSpawnOutcome, SubAgentSpawnError>;
58
59 /// List all sub-agents held by the manager (includes prior-session entries).
60 async fn list_subagents(&self) -> Vec<SubAgentResult>;
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn subagent_spawn_error_display_messages() {
69 assert_eq!(
70 SubAgentSpawnError::NoClient.to_string(),
71 "API client not configured"
72 );
73 assert_eq!(
74 SubAgentSpawnError::SpawnFailed("depth limit".into()).to_string(),
75 "depth limit"
76 );
77 }
78}