mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
### Description This PR fixes TypeError: cannot pickle '_thread.RLock' object which occurs when kernel.clone() is called while OpenTelemetry metrics are enabled. - Fixes: #12802 ### Motivation and Context When using features like `HandoffOrchestration`, the agent's `Kernel` is cloned. This process uses `copy.deepcopy`, which fails on the `KernelFunction`'s OpenTelemetry `Histogram` fields (`invocation_duration_histogram` and `streaming_duration_histogram`). These histogram objects contain thread locks, making them non-serializable. Previous solutions, like the one in **PR #9292**, used `Field(exclude=True, default_factory=...)`. While that was a necessary step, it was insufficient because `deepcopy` does not respect the `exclude` flag in the same way that Pydantic's serialization does. This bug blocks the use of certain agentic features in any application that has metrics-based observability enabled. ### Description of the change This solution introduces a custom __deepcopy__ method to the KernelFunction Pydantic model. This method correctly handles the deep-copying process for KernelFunction instances: 1. It intercepts the deepcopy call for KernelFunction objects. 2. It uses self.model_copy(deep=False) to create a new instance of the Pydantic model. Using deep=False allows the default_factory for the histogram fields to create new, clean instances on the copied object, while other fields are shallow-copied. 3. It then manually deep-copies all other attributes from the original object to the new one, ensuring that any other mutable objects (like metadata`) are correctly duplicated. The histogram fields are explicitly skipped in this step, as they have already been recreated by `model_copy. 4. Standard deepcopy memoization is used to prevent infinite recursion in the case of cyclic object graphs. This approach ensures that the non-serializable fields are re-initialized instead of copied, resolving the TypeError while maintaining the integrity of the cloned object. ### How has this been tested? The fix was validated using the reproduction steps outlined in the associated issue. Running an agent orchestration that triggers kernel.clone() with OpenTelemetry metrics enabled now completes successfully without any errors. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [X] The code builds clean without any errors or warnings - [X] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [X] All unit tests pass, and I have added new tests where possible - [X] I didn't break anyone 😄 --------- Co-authored-by: Evan Mattson <[email protected]>