(
&self,
prev: Option<&RustStepOutcome>,
item: &serde_json::Value,
)
| 3485 | |
| 3486 | impl PythonPipelineStage { |
| 3487 | fn invoke( |
| 3488 | &self, |
| 3489 | prev: Option<&RustStepOutcome>, |
| 3490 | item: &serde_json::Value, |
| 3491 | ) -> Option<RustAgentStepSpec> { |
| 3492 | pyo3::Python::with_gil(|py| { |
| 3493 | let result = (|| -> PyResult<Option<RustAgentStepSpec>> { |
| 3494 | let json_mod = py.import("json")?; |
| 3495 | let previous = match prev { |
| 3496 | Some(o) => { |
| 3497 | let s = serde_json::to_string(o) |
| 3498 | .map_err(|e| PyValueError::new_err(e.to_string()))?; |
| 3499 | json_mod.call_method1("loads", (s,))? |
| 3500 | } |
| 3501 | None => py.None().into_bound(py), |
| 3502 | }; |
| 3503 | let item_str = serde_json::to_string(item) |
| 3504 | .map_err(|e| PyValueError::new_err(e.to_string()))?; |
| 3505 | let item_py = json_mod.call_method1("loads", (item_str,))?; |
| 3506 | let ctx = PyDict::new(py); |
| 3507 | ctx.set_item("previous", previous)?; |
| 3508 | ctx.set_item("item", item_py)?; |
| 3509 | let ret = self.callback.call1(py, (ctx,))?; |
| 3510 | let bound = ret.bind(py); |
| 3511 | if bound.is_none() { |
| 3512 | return Ok(None); |
| 3513 | } |
| 3514 | let spec_json: String = json_mod.call_method1("dumps", (bound,))?.extract()?; |
| 3515 | serde_json::from_str::<RustAgentStepSpec>(&spec_json) |
| 3516 | .map(Some) |
| 3517 | .map_err(|e| PyValueError::new_err(format!("invalid step spec: {e}"))) |
| 3518 | })(); |
| 3519 | // Fail-closed: any exception → stop this chain. |
| 3520 | result.unwrap_or(None) |
| 3521 | }) |
| 3522 | } |
| 3523 | } |
| 3524 | |
| 3525 | // ============================================================================ |
no outgoing calls