Skip to main content

lellm_graph/node/
compiled_subgraph.rs

1//! CompiledSubgraph — 编译后的 Subgraph 描述符。
2//!
3//! # 设计理念
4//!
5//! ```text
6//! Builder 阶段:
7//!   SubgraphSpec<Outer, Inner, M, Lens>  (强类型)
8//!
9//! 编译阶段:
10//!   CompiledSubgraph<Outer>  (类型擦除 Inner/Lens/M)
11//!
12//! Engine 执行:
13//!   match node.kind {
14//!       NodeKind::Subgraph(spec) => self.execute_subgraph(spec).await,
15//!   }
16//! ```
17//!
18//! # 类型擦除
19//!
20//! SubgraphSpec 有 4 个泛型参数,NodeKind 只有 2 个。
21//! CompiledSubgraph 通过 `StateProjector` trait 擦除 Inner/Lens/M,
22//! 只保留 Outer(外层 State 类型)。
23//!
24//! # 与 SubgraphSpec 的区别
25//!
26//! - SubgraphSpec:Builder 阶段,强类型,包含 Graph + Lens
27//! - CompiledSubgraph:编译后,类型擦除,可存入 NodeKind
28
29use std::future::Future;
30use std::pin::Pin;
31use std::sync::Arc;
32
33use crate::error::GraphError;
34use crate::state::workflow_state::WorkflowState;
35use crate::stream_emitter::StreamSink;
36use tokio_util::sync::CancellationToken;
37
38// ─── StateProjector ────────────────────────────────────────────
39
40/// 状态投影器 — 类型擦除的 Outer → Inner 投影 + 执行。
41///
42/// 这是 Subgraph 执行的核心 trait。它擦除了 Inner、Lens、Merge 类型,
43/// 只暴露 Outer State 类型。
44///
45/// # 设计原则
46///
47/// - 最小接口:只有 `execute()` + 元数据方法
48/// - 类型擦除:Inner/Lens/M 全部隐藏在实现内部
49/// - 可 introspection:提供 `graph_name()` 和 `node_count()`
50pub trait StateProjector<S: WorkflowState>: Send + Sync {
51    /// 执行 Subgraph — 投影状态 + 递归执行内层 Graph。
52    fn execute<'a>(
53        &'a self,
54        outer: &'a mut S,
55        stream: Option<Arc<dyn StreamSink>>,
56        cancel: CancellationToken,
57    ) -> Pin<Box<dyn Future<Output = Result<(), GraphError>> + Send + 'a>>;
58
59    /// 内层 Graph 的名称。
60    fn graph_name(&self) -> &str;
61
62    /// 内层 Graph 的节点数(用于评估是否值得内联)。
63    fn node_count(&self) -> usize;
64}
65
66// ─── CompiledSubgraph ──────────────────────────────────────────
67
68/// 编译后的 Subgraph 描述符 — 可存入 NodeKind。
69///
70/// # 类型参数
71///
72/// - `S` — 外层 State 类型(与 NodeKind 一致)
73///
74/// # 内容
75///
76/// - `projector` — 类型擦除的执行器(包含 Graph + Lens + Merge)
77/// - `max_steps` — 最大执行步数
78///
79/// # 使用方式
80///
81/// ```text
82/// NodeKind::Subgraph(CompiledSubgraph {
83///     projector: Arc::new(spec),  // SubgraphSpec implements StateProjector
84///     max_steps: 1000,
85/// })
86/// ```
87#[derive(Clone)]
88pub struct CompiledSubgraph<S: WorkflowState> {
89    /// 类型擦除的执行器
90    pub projector: Arc<dyn StateProjector<S>>,
91    /// 最大执行步数
92    pub max_steps: usize,
93}
94
95impl<S: WorkflowState> CompiledSubgraph<S> {
96    /// 创建新的 CompiledSubgraph。
97    pub fn new(projector: Arc<dyn StateProjector<S>>, max_steps: usize) -> Self {
98        Self {
99            projector,
100            max_steps,
101        }
102    }
103
104    /// 执行 Subgraph。
105    pub async fn execute(
106        &self,
107        outer: &mut S,
108        stream: Option<Arc<dyn StreamSink>>,
109        cancel: CancellationToken,
110    ) -> Result<(), GraphError> {
111        self.projector.execute(outer, stream, cancel).await
112    }
113
114    /// 内层 Graph 的名称。
115    pub fn graph_name(&self) -> &str {
116        self.projector.graph_name()
117    }
118
119    /// 内层 Graph 的节点数。
120    pub fn node_count(&self) -> usize {
121        self.projector.node_count()
122    }
123}
124
125impl<S: WorkflowState> std::fmt::Debug for CompiledSubgraph<S> {
126    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127        f.debug_struct("CompiledSubgraph")
128            .field("graph_name", &self.projector.graph_name())
129            .field("node_count", &self.projector.node_count())
130            .field("max_steps", &self.max_steps)
131            .finish()
132    }
133}