greentic_runner_host/engine/
builder.rs

1use 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}