greentic_runner_host/engine/
builder.rs1use super::api::{RunFlowRequest, RunFlowResult, RunnerApi};
2use super::error::{GResult, RunnerError};
3use super::host::HostBundle;
4use super::policy::Policy;
5use super::registry::AdapterRegistry;
6use super::state_machine::{FlowDefinition, StateMachine};
7use async_trait::async_trait;
8use greentic_types::TenantCtx;
9use std::sync::Arc;
10
11#[derive(Default)]
12pub struct RunnerBuilder {
13 host: Option<HostBundle>,
14 adapters: Option<AdapterRegistry>,
15 policy: Option<Policy>,
16 flows: Vec<FlowDefinition>,
17}
18
19impl RunnerBuilder {
20 pub fn new() -> Self {
21 Self::default()
22 }
23
24 pub fn with_host(mut self, host: HostBundle) -> Self {
25 self.host = Some(host);
26 self
27 }
28
29 pub fn with_adapters(mut self, adapters: AdapterRegistry) -> Self {
30 self.adapters = Some(adapters);
31 self
32 }
33
34 pub fn with_policy(mut self, policy: Policy) -> Self {
35 self.policy = Some(policy);
36 self
37 }
38
39 pub fn with_flow(mut self, definition: FlowDefinition) -> Self {
40 self.flows.push(definition);
41 self
42 }
43
44 pub fn build(self) -> GResult<Runner> {
45 let host = self.host.ok_or_else(|| RunnerError::Policy {
46 reason: "host bundle missing".into(),
47 })?;
48 let adapters = self.adapters.unwrap_or_default();
49 let policy = self.policy.unwrap_or_default();
50 let state_machine = StateMachine::new(Arc::new(host), adapters, policy);
51 for flow in self.flows {
52 state_machine.register_flow(flow);
53 }
54 Ok(Runner { sm: state_machine })
55 }
56}
57
58pub struct Runner {
59 sm: StateMachine,
60}
61
62impl Runner {
63 pub fn state_machine(&self) -> &StateMachine {
64 &self.sm
65 }
66
67 pub fn state_machine_mut(&mut self) -> &mut StateMachine {
68 &mut self.sm
69 }
70
71 pub fn into_state_machine(self) -> StateMachine {
72 self.sm
73 }
74}
75
76#[async_trait]
77impl RunnerApi for Runner {
78 async fn list_flows(&self, _tenant: &TenantCtx) -> GResult<Vec<super::api::FlowSummary>> {
79 Ok(self.sm.list_flows())
80 }
81
82 async fn get_flow_schema(
83 &self,
84 _tenant: &TenantCtx,
85 flow_id: &str,
86 ) -> GResult<super::api::FlowSchema> {
87 self.sm.get_flow_schema(flow_id)
88 }
89
90 async fn run_flow(&self, req: RunFlowRequest) -> GResult<RunFlowResult> {
91 let outcome = self
92 .sm
93 .step(
94 &req.tenant,
95 &req.flow_id,
96 req.session_hint.clone(),
97 req.input.clone(),
98 )
99 .await?;
100 Ok(RunFlowResult { outcome })
101 }
102}