use crate::engine::PyZenEvaluateOptions; use crate::loader::PyDecisionLoader; use crate::value::PyValue; use anyhow::Context; use pyo3::types::PyDict; use pyo3::{pyclass, pymethods, PyObject, PyResult, Python, ToPyObject}; use pythonize::depythonize; use std::sync::Arc; use zen_engine::{Decision, EvaluationOptions}; #[pyclass] #[pyo3(name = "ZenDecision")] pub struct PyZenDecision(pub(crate) Arc>); impl From> for PyZenDecision { fn from(value: Decision) -> Self { Self(value.into()) } } #[pymethods] impl PyZenDecision { pub fn evaluate(&self, py: Python, ctx: &PyDict, opts: Option<&PyDict>) -> PyResult { let context = depythonize(ctx).context("Failed to convert dict")?; let options: PyZenEvaluateOptions = if let Some(op) = opts { depythonize(op).context("Failed to convert dict")? } else { Default::default() }; let decision = self.0.clone(); let result = futures::executor::block_on(decision.evaluate_with_opts( &context, EvaluationOptions { max_depth: options.max_depth, trace: options.trace, }, )) .context("Failed to evaluate graph")?; let value = serde_json::to_value(&result).context("Fail")?; Ok(PyValue(value).to_object(py)) } }