| 215 | text_signature = "(name: str, callback: object) -> None" |
| 216 | )] |
| 217 | fn register_subscriber(&self, name: &str, callback: Py<PyAny>) -> PyResult<()> { |
| 218 | let qualified_name = self.qualify_name(name); |
| 219 | register_subscriber(&qualified_name, wrap_py_event_subscriber(callback)) |
| 220 | .map_err(to_py_err)?; |
| 221 | |
| 222 | let name_owned = qualified_name; |
| 223 | let mut guard = self.registrations.lock().map_err(|e| { |
| 224 | pyo3::exceptions::PyRuntimeError::new_err(format!("plugin context lock poisoned: {e}")) |
| 225 | })?; |
| 226 | guard.push(PluginRegistration::new( |
| 227 | "plugin", |
| 228 | name_owned.clone(), |
| 229 | Box::new(move || { |
| 230 | deregister_subscriber(&name_owned).map(|_| ()).map_err(|e| { |
| 231 | PluginError::RegistrationFailed(format!( |
| 232 | "subscriber deregistration failed: {e}" |
| 233 | )) |
| 234 | }) |
| 235 | }), |
| 236 | )); |
| 237 | Ok(()) |
| 238 | } |
| 239 | |
| 240 | #[pyo3(signature = (name: "str", priority: "int", callback: "object") -> "None", text_signature = "(name: str, priority: int, callback: object) -> None")] |
| 241 | fn register_tool_sanitize_request_guardrail( |