()
| 7485 | |
| 7486 | #[test] |
| 7487 | fn step_outcome_to_py_uses_snake_case_keys() { |
| 7488 | pyo3::prepare_freethreaded_python(); |
| 7489 | Python::with_gil(|py| { |
| 7490 | let outcome = RustStepOutcome { |
| 7491 | task_id: "t1".into(), |
| 7492 | session_id: "task-run-t1".into(), |
| 7493 | agent: "explore".into(), |
| 7494 | output: "o".into(), |
| 7495 | success: true, |
| 7496 | structured: Some(serde_json::json!({ "k": 1 })), |
| 7497 | }; |
| 7498 | let obj = step_outcome_to_py(py, &outcome).unwrap(); |
| 7499 | let bound = obj.bind(py); |
| 7500 | let dict = bound.downcast::<PyDict>().unwrap(); |
| 7501 | // snake_case keys — the casing the pipeline `ctx['previous']` relies on. |
| 7502 | assert_eq!( |
| 7503 | dict.get_item("task_id") |
| 7504 | .unwrap() |
| 7505 | .unwrap() |
| 7506 | .extract::<String>() |
| 7507 | .unwrap(), |
| 7508 | "t1" |
| 7509 | ); |
| 7510 | assert_eq!( |
| 7511 | dict.get_item("session_id") |
| 7512 | .unwrap() |
| 7513 | .unwrap() |
| 7514 | .extract::<String>() |
| 7515 | .unwrap(), |
| 7516 | "task-run-t1" |
| 7517 | ); |
| 7518 | assert!(dict |
| 7519 | .get_item("success") |
| 7520 | .unwrap() |
| 7521 | .unwrap() |
| 7522 | .extract::<bool>() |
| 7523 | .unwrap()); |
| 7524 | assert!(dict.get_item("structured").unwrap().is_some()); |
| 7525 | }); |
| 7526 | } |
| 7527 | |
| 7528 | #[test] |
| 7529 | fn python_pipeline_stage_none_raise_and_spec() { |
nothing calls this directly
no test coverage detected