| 6303 | } |
| 6304 | |
| 6305 | fn normalize_program_script_options( |
| 6306 | options: &Bound<'_, pyo3::types::PyDict>, |
| 6307 | ) -> PyResult<serde_json::Value> { |
| 6308 | let json_str = py_dict_to_json(options)?; |
| 6309 | let value: serde_json::Value = serde_json::from_str(&json_str) |
| 6310 | .map_err(|e| PyValueError::new_err(format!("Invalid program options: {e}")))?; |
| 6311 | let obj = value |
| 6312 | .as_object() |
| 6313 | .ok_or_else(|| PyValueError::new_err("program options must be a dict"))?; |
| 6314 | |
| 6315 | let mut args = serde_json::Map::new(); |
| 6316 | args.insert("type".to_string(), serde_json::json!("script")); |
| 6317 | args.insert("language".to_string(), serde_json::json!("javascript")); |
| 6318 | |
| 6319 | for key in ["source", "path", "inputs", "limits"] { |
| 6320 | if let Some(field) = obj.get(key) { |
| 6321 | args.insert(key.to_string(), field.clone()); |
| 6322 | } |
| 6323 | } |
| 6324 | |
| 6325 | if let Some(field) = obj.get("allowed_tools").or_else(|| obj.get("allowedTools")) { |
| 6326 | args.insert("allowed_tools".to_string(), field.clone()); |
| 6327 | } |
| 6328 | |
| 6329 | Ok(serde_json::Value::Object(args)) |
| 6330 | } |
| 6331 | |
| 6332 | fn timeout_ms_to_secs(timeout_ms: u64) -> u64 { |
| 6333 | timeout_ms.div_ceil(1000).max(1) |