Skip to main content

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}