Skip to main content

ai_agents_runtime/orchestration/
mod.rs

1//! Multi-agent orchestration functions.
2//! Coordination patterns built on top of AgentRegistry primitives.
3
4pub mod aggregation;
5pub mod concurrent;
6pub mod context;
7pub mod group_chat;
8pub mod handoff;
9pub mod pipeline;
10pub mod route;
11pub mod tools;
12pub mod types;
13
14pub use concurrent::{concurrent, concurrent_with_llms};
15pub use group_chat::{group_chat, group_chat_with_llms};
16pub use handoff::handoff;
17pub use pipeline::pipeline;
18pub use route::route;
19pub use types::*;
20
21/// Borrowed providers for independent aggregation responsibilities.
22#[derive(Clone, Copy)]
23pub struct AggregationLLMs<'a> {
24    pub synthesis: Option<&'a dyn ai_agents_llm::LLMProvider>,
25    pub vote: Option<&'a dyn ai_agents_llm::LLMProvider>,
26    pub tiebreak: Option<&'a dyn ai_agents_llm::LLMProvider>,
27}
28
29impl<'a> AggregationLLMs<'a> {
30    /// Keeps the historical one-provider aggregation contract.
31    pub fn shared(provider: Option<&'a dyn ai_agents_llm::LLMProvider>) -> Self {
32        Self {
33            synthesis: provider,
34            vote: provider,
35            tiebreak: provider,
36        }
37    }
38}
39
40/// Borrowed providers for framework-directed group decisions, not participant turns.
41#[derive(Clone, Copy)]
42pub struct GroupLLMs<'a> {
43    pub speaker: Option<&'a dyn ai_agents_llm::LLMProvider>,
44    pub consensus: Option<&'a dyn ai_agents_llm::LLMProvider>,
45}
46
47impl<'a> GroupLLMs<'a> {
48    /// Keeps the historical one-provider group contract.
49    pub fn shared(provider: Option<&'a dyn ai_agents_llm::LLMProvider>) -> Self {
50        Self {
51            speaker: provider,
52            consensus: provider,
53        }
54    }
55}
56
57// Literal router lookup is retained only for legacy orchestration consumers.
58pub(crate) fn role_provider(
59    registry: &ai_agents_llm::LLMRegistry,
60    role: ai_agents_llm::LLMRole,
61    local: Option<&str>,
62) -> ai_agents_core::Result<Option<std::sync::Arc<dyn ai_agents_llm::LLMProvider>>> {
63    Ok(
64        match registry
65            .resolve_role_override(role, local)
66            .map_err(|e| ai_agents_core::AgentError::Config(e.to_string()))?
67        {
68            Some(resolved) => Some(resolved.provider),
69            None => registry.get(local.unwrap_or("router")).ok(),
70        },
71    )
72}
73
74pub(crate) struct AggregationProviders {
75    synthesis: Option<std::sync::Arc<dyn ai_agents_llm::LLMProvider>>,
76    vote: Option<std::sync::Arc<dyn ai_agents_llm::LLMProvider>>,
77    tiebreak: Option<std::sync::Arc<dyn ai_agents_llm::LLMProvider>>,
78}
79
80impl AggregationProviders {
81    // Capture one agent's resolved handles before participant execution begins.
82    pub(crate) fn resolve(
83        registry: &ai_agents_llm::LLMRegistry,
84        local: Option<&str>,
85    ) -> ai_agents_core::Result<Self> {
86        use ai_agents_llm::LLMRole;
87        Ok(Self {
88            synthesis: role_provider(registry, LLMRole::OrchestrationSynthesis, local)?,
89            vote: role_provider(registry, LLMRole::OrchestrationVote, local)?,
90            tiebreak: role_provider(registry, LLMRole::OrchestrationTiebreak, local)?,
91        })
92    }
93
94    // Borrow captured handles without rebuilding clients or bypassing wrappers.
95    pub(crate) fn as_refs(&self) -> AggregationLLMs<'_> {
96        AggregationLLMs {
97            synthesis: self.synthesis.as_deref(),
98            vote: self.vote.as_deref(),
99            tiebreak: self.tiebreak.as_deref(),
100        }
101    }
102}