Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
"""Compatibility helper for explicit agent stop producers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
from typing import Any
|
||||
|
||||
|
||||
def _accepts_keyword(callable_obj: Any, name: str) -> bool:
|
||||
"""Return whether a callable explicitly supports a keyword argument."""
|
||||
try:
|
||||
parameters = inspect.signature(callable_obj).parameters.values()
|
||||
except (TypeError, ValueError):
|
||||
return False
|
||||
return any(
|
||||
parameter.kind is inspect.Parameter.VAR_KEYWORD
|
||||
or (
|
||||
parameter.name == name
|
||||
and parameter.kind is not inspect.Parameter.POSITIONAL_ONLY
|
||||
)
|
||||
for parameter in parameters
|
||||
)
|
||||
|
||||
|
||||
def request_hard_interrupt(
|
||||
agent: Any,
|
||||
message: str | None = None,
|
||||
*,
|
||||
tool_reason: str | None = None,
|
||||
) -> bool:
|
||||
"""Request an explicit stop, falling back to the legacy interrupt ABI.
|
||||
|
||||
New agents expose ``hard_interrupt(message=None)``. Third-party agents and
|
||||
old test doubles may only expose ``interrupt(message=None)``; keep those
|
||||
usable without sending newer keyword arguments they do not know.
|
||||
|
||||
``message`` is diagnostic/control-plane text. ``tool_reason`` is a trusted,
|
||||
fixed category that may be exposed in model-visible tool cancellation
|
||||
output. It is only forwarded when the modern callable explicitly supports
|
||||
that channel.
|
||||
Returns ``False`` only when neither callable is available.
|
||||
"""
|
||||
# Avoid treating a dynamic ``__getattr__`` proxy (notably an unspecced
|
||||
# ``MagicMock`` or a third-party RPC facade) as if it genuinely implements
|
||||
# the new ABI. Static lookup proves the attribute exists on the instance or
|
||||
# its type before normal descriptor binding retrieves the callable.
|
||||
try:
|
||||
inspect.getattr_static(agent, "hard_interrupt")
|
||||
except AttributeError:
|
||||
interrupt = None
|
||||
else:
|
||||
interrupt = getattr(agent, "hard_interrupt", None)
|
||||
if not callable(interrupt):
|
||||
interrupt = getattr(agent, "interrupt", None)
|
||||
if not callable(interrupt):
|
||||
return False
|
||||
kwargs = {}
|
||||
if tool_reason is not None and _accepts_keyword(interrupt, "tool_reason"):
|
||||
kwargs["tool_reason"] = tool_reason
|
||||
if message is None:
|
||||
interrupt(**kwargs)
|
||||
else:
|
||||
interrupt(message, **kwargs)
|
||||
return True
|
||||
Reference in New Issue
Block a user