refactor: scrub migration scars, dead code, and unused helpers
- Strip PLAYBOOK / AUDIT / Phase-N / C-numbered references from module docstrings across 16 files; rename ``_PHASE1_PARALLEL_DEFAULT`` → ``_PARALLEL_TOOL_CALLS_DEFAULT``. - Delete unused exception classes: ``SandboxInitializationError``, ``ImplementedInClientSideOnlyError``. - Delete the no-op ``on_handoff`` hook (we don't use SDK handoffs). - Delete the unreachable backward-compat tab-delimited fallback in ``_parse_git_diff_output``. - Delete orphaned ``strix/tools/load_skill/`` (dir contained only a pycache) and stale pycache files. - Rewrite ``strix/skills/__init__.py``: 168 → 56 LoC. Drop seven helper functions (``get_available_skills``, ``get_all_skill_names``, ``validate_skill_names``, ``parse_skill_list``, ``validate_requested_skills``, ``generate_skills_description``, ``_get_all_categories``) — none had external callers; only ``load_skills`` is used. - Drop the stale ``strix/agents/sdk_factory.py`` per-file ruff ignore (file no longer exists). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,13 +17,7 @@ from .finish import * # noqa: F403
|
||||
from .notes import * # noqa: F403
|
||||
from .proxy import * # noqa: F403
|
||||
from .python import * # noqa: F403
|
||||
from .registry import (
|
||||
ImplementedInClientSideOnlyError,
|
||||
get_tool_by_name,
|
||||
get_tool_names,
|
||||
register_tool,
|
||||
tools,
|
||||
)
|
||||
from .registry import get_tool_by_name, get_tool_names, register_tool, tools
|
||||
from .reporting import * # noqa: F403
|
||||
from .terminal import * # noqa: F403
|
||||
from .thinking import * # noqa: F403
|
||||
@@ -32,7 +26,6 @@ from .web_search import * # noqa: F403
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ImplementedInClientSideOnlyError",
|
||||
"get_tool_by_name",
|
||||
"get_tool_names",
|
||||
"register_tool",
|
||||
|
||||
+12
-28
@@ -1,24 +1,15 @@
|
||||
"""strix_tool — function_tool factory with Strix defaults.
|
||||
"""``strix_tool`` — ``function_tool`` factory with Strix defaults.
|
||||
|
||||
Every tool in the migrated harness should be decorated with ``@strix_tool``
|
||||
instead of bare ``@function_tool`` so the team's defaults stay consistent
|
||||
without per-tool boilerplate. Override per call when needed.
|
||||
Every tool uses ``@strix_tool`` instead of bare ``@function_tool`` so
|
||||
defaults stay consistent across the suite. Override per call when
|
||||
needed.
|
||||
|
||||
Defaults:
|
||||
- ``timeout``: 120s (matches the legacy tool server's
|
||||
``STRIX_SANDBOX_EXECUTION_TIMEOUT``).
|
||||
- ``timeout``: 120s.
|
||||
- ``timeout_behavior``: ``"error_as_result"`` for idempotent tools.
|
||||
Critical sandbox tools (terminal, browser, python) should pass
|
||||
``timeout_behavior="raise_exception"`` explicitly so the SDK can fail
|
||||
the run rather than letting the model retry the same hung call (C20).
|
||||
|
||||
The SDK auto-threads sync function bodies via ``asyncio.to_thread``
|
||||
(``tool.py:1820-1829``), so libtmux / IPython / blocking httpx code can be
|
||||
written as plain ``def`` and the decorator will not block the event loop.
|
||||
|
||||
References:
|
||||
- PLAYBOOK.md §2.6
|
||||
- AUDIT_R3.md C20 (per-tool timeout_behavior discrimination)
|
||||
Critical sandbox tools (terminal, browser, python) opt into
|
||||
``timeout_behavior="raise_exception"`` explicitly so the SDK
|
||||
fails the run rather than letting the model retry a hung call.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -44,17 +35,10 @@ def strix_tool(
|
||||
) -> Callable[[_ToolFn], FunctionTool]:
|
||||
"""Wrap ``agents.function_tool`` with Strix defaults.
|
||||
|
||||
The SDK's ``FunctionTool`` requires ``async def`` for ``timeout_seconds``
|
||||
to apply (sync handlers cannot be cleanly cancelled). All Strix tools are
|
||||
``async def``; sync libraries (libtmux, IPython) get wrapped in
|
||||
``asyncio.to_thread`` inside the async tool body.
|
||||
|
||||
The SDK enforces ``strict_mode=True`` by default, which forbids
|
||||
free-form ``dict[str, X]`` parameters (the strict JSON schema needs
|
||||
``additionalProperties: false``). A handful of legacy tools
|
||||
(``send_request``, ``repeat_request``) take arbitrary header /
|
||||
modification dicts whose keys can't be enumerated, so they must
|
||||
opt out of strict mode to preserve parity with the XML schema.
|
||||
Strict mode is on by default (forbids free-form ``dict[str, X]``
|
||||
parameters because the strict JSON schema needs
|
||||
``additionalProperties: false``). A few tools that take arbitrary
|
||||
header / modification dicts opt out via ``strict_mode=False``.
|
||||
|
||||
Usage::
|
||||
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
"""post_to_sandbox — host-to-container HTTP transport for sandbox tools.
|
||||
"""``post_to_sandbox`` — host-to-container HTTP transport for sandbox tools.
|
||||
|
||||
Every Strix tool that runs inside the Kali container (browser, terminal,
|
||||
python, the seven Caido tools) has the same wire shape: POST a JSON body
|
||||
to ``http://localhost:{tool_server_host_port}/execute`` with a Bearer
|
||||
token header and ``{"agent_id", "tool_name", "kwargs"}`` as the body.
|
||||
Every Strix tool that runs inside the Kali container (browser,
|
||||
terminal, python, file_edit, the seven Caido tools) has the same wire
|
||||
shape: POST JSON to ``http://localhost:{tool_server_host_port}/execute``
|
||||
with a Bearer token and ``{"agent_id", "tool_name", "kwargs"}`` body.
|
||||
|
||||
This helper centralizes that transport so:
|
||||
|
||||
- Every sandbox tool gets the same timeout policy
|
||||
(``connect=10s`` / ``read=150s``).
|
||||
- Every sandbox tool inherits the same response-size cap (50 MB) so a
|
||||
runaway tool body cannot OOM the host (C18).
|
||||
- Auth/transport errors surface as predictable error strings instead of
|
||||
exceptions, so the model can retry / pick a different tool without the
|
||||
run dying.
|
||||
|
||||
References:
|
||||
- PLAYBOOK.md §3.4
|
||||
- AUDIT_R3.md C18 (sandbox response size cap)
|
||||
- HARNESS_WIKI.md §7.2 (legacy executor.py wire format we mirror)
|
||||
The helper centralizes timeouts (``connect=10s`` / ``read=150s``), a
|
||||
50 MB response-size cap so a runaway tool can't OOM the host, and
|
||||
predictable error-string shaping so transport failures don't tear
|
||||
down the run.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -36,14 +26,9 @@ if TYPE_CHECKING:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Connect: how long to wait for the TCP handshake to complete.
|
||||
# Read: how long the tool may spend executing before we abandon the call.
|
||||
# Mirrors the legacy executor.py (``SANDBOX_EXECUTION_TIMEOUT = 120 + 30``).
|
||||
_SANDBOX_TIMEOUT = httpx.Timeout(connect=10.0, read=150.0, write=150.0, pool=150.0)
|
||||
|
||||
#: Cap on response body size from the tool server. Anything bigger is
|
||||
#: replaced by an error string so the model sees something coherent and
|
||||
#: the host doesn't OOM trying to allocate the buffer (C18).
|
||||
# Cap so a runaway tool body never blows up the host heap.
|
||||
_MAX_RESPONSE_BYTES = 50 * 1024 * 1024 # 50 MB
|
||||
|
||||
|
||||
|
||||
@@ -1,29 +1,16 @@
|
||||
"""SDK function-tool wrappers for the multi-agent graph tools.
|
||||
"""Multi-agent graph tools — read/write the :class:`AgentMessageBus`.
|
||||
|
||||
Six tools that read/write the :class:`AgentMessageBus` (built in Phase 0,
|
||||
``strix.orchestration.bus``):
|
||||
|
||||
- ``view_agent_graph``: render the parent/child tree from ``bus.parent_of``.
|
||||
- ``view_agent_graph``: render the parent/child tree.
|
||||
- ``agent_status``: per-agent status + pending message count.
|
||||
- ``send_message_to_agent``: peer-to-peer message into a child/sibling inbox.
|
||||
- ``wait_for_message``: poll our own inbox until a message arrives or the
|
||||
timeout expires (the legacy harness's "I'm idle, wake me on inbox").
|
||||
- ``create_agent``: spawn a child via ``asyncio.create_task(Runner.run(...))``;
|
||||
registers the child with the bus and stores its task handle so root cancels
|
||||
cascade (C9, ``bus.cancel_descendants``).
|
||||
- ``agent_finish``: subagents only — flips ``agent_finish_called`` so the
|
||||
on_agent_end hook records "completed" rather than "crashed" (C8), and
|
||||
posts a structured completion report to the parent's inbox.
|
||||
|
||||
The legacy ``strix.tools.agents_graph.agents_graph_actions`` is left
|
||||
untouched — it still drives the legacy harness. These wrappers only
|
||||
target the bus and don't touch the legacy ``_agent_graph`` dict.
|
||||
|
||||
References:
|
||||
- PLAYBOOK.md §4.3
|
||||
- AUDIT_R2.md §1.4 (cancel_descendants — Runner.run task handle stored
|
||||
in bus.tasks so a root cancel walks the tree)
|
||||
- AUDIT_R3.md C8 (crash detection via on_agent_end + agent_finish_called)
|
||||
- ``send_message_to_agent``: queue a message in another agent's inbox.
|
||||
- ``wait_for_message``: pause this agent until a message arrives or
|
||||
``timeout_seconds`` elapses.
|
||||
- ``create_agent``: spawn a child via
|
||||
``asyncio.create_task(Runner.run(...))``; the task handle is stored
|
||||
so a root-level cancel cascades to descendants.
|
||||
- ``agent_finish``: subagents only — flips ``agent_finish_called`` so
|
||||
the ``on_agent_end`` hook records "completed" rather than "crashed",
|
||||
and posts a structured completion report to the parent's inbox.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -223,8 +210,7 @@ async def send_message_to_agent(
|
||||
)
|
||||
|
||||
|
||||
# Polling cadence for ``wait_for_message``. 1s matches the PLAYBOOK
|
||||
# skeleton; tighter would burn CPU, slacker would feel laggy when a sibling
|
||||
# Tighter would burn CPU; slacker would feel laggy when a sibling
|
||||
# delivers a message right after the wait starts.
|
||||
_WAIT_POLL_SECONDS = 1.0
|
||||
|
||||
|
||||
+4
-15
@@ -1,14 +1,14 @@
|
||||
"""Minimal in-container tool registry.
|
||||
|
||||
Used inside the sandbox container by ``strix.runtime.tool_server`` to
|
||||
look up `@register_tool`-decorated functions by name. Sandbox-bound
|
||||
tools (browser, terminal, python, file_edit, proxy) live as legacy
|
||||
look up ``@register_tool``-decorated functions by name. Sandbox-bound
|
||||
tools (browser, terminal, python, file_edit, proxy) live as
|
||||
``*_actions.py`` modules with this decoration; the host POSTs to
|
||||
:func:`tool_server.execute_tool` which dispatches via
|
||||
:func:`get_tool_by_name`.
|
||||
|
||||
Host-side tools are pure SDK function tools wired through
|
||||
:mod:`strix.agents.factory` and don't touch this registry at all.
|
||||
Host-side SDK function tools are wired through
|
||||
:mod:`strix.agents.factory` and don't touch this registry.
|
||||
"""
|
||||
|
||||
import logging
|
||||
@@ -25,17 +25,6 @@ tools: list[dict[str, Any]] = []
|
||||
_tools_by_name: dict[str, Callable[..., Any]] = {}
|
||||
|
||||
|
||||
class ImplementedInClientSideOnlyError(Exception):
|
||||
"""Raised by sandbox-side stubs whose real implementation lives host-side."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str = "This tool is implemented in the client side only",
|
||||
) -> None:
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
|
||||
def _is_sandbox_mode() -> bool:
|
||||
return os.getenv("STRIX_SANDBOX_MODE", "false").lower() == "true"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user