When working with concurrency (threads/async), ensure code is safe under parallel invocations and does not block or re-enter running event loops.

Rules: 1) Eliminate shared mutable state across requests/threads

2) Be event-loop safe

3) Provide and test async behavior

4) Keep async detection consistent

Example patterns:

# 1) Immutability / no post-init mutation
class ConditionalModelSettingsMiddleware(AgentMiddleware):
    def __init__(self, conditions: list[tuple[Callable, dict[str, Any]]]):
        super().__init__()
        self._conditions = list(conditions)  # don’t mutate after init
# 2) Offload blocking work from async contexts
async def abefore_agent(self, state, runtime):
    return await run_in_executor(None, self.before_agent, state, runtime)
# 3) Don’t use asyncio.run() inside possibly-running event loops
# Prefer: make the validation async, or detect running loop and schedule appropriately.
async def _avalidate(...):
    ...
# then in async contexts: await _avalidate(...)
# 4) Prefer inspect for coroutine-function checks
import inspect
if ignore_condition_name is None or not getattr(handler, ignore_condition_name):
    event = getattr(handler, event_name)
    if inspect.iscoroutinefunction(event):
        ...

Adopting these practices prevents race conditions, avoids event-loop reentrancy problems, and ensures concurrency-heavy logic is correct under real async/parallel workloads.