Critical fixes:
- ``StrixOrchestrationHooks.on_agent_start`` now finds the
``CaidoCapability`` via ``ctx.context['caido_capability']`` instead
of ``agent.capabilities`` (we use plain ``Agent``, not
``SandboxAgent``, so the latter never existed). The session
manager's bundle already exposes the capability; ``run_strix_scan``
threads it through ``make_agent_context`` and ``create_agent``
forwards it to children.
- ``run_strix_scan`` registers the ``StrixTracingProcessor`` with the
SDK's tracing provider via ``add_trace_processor`` so SDK trace
spans hit ``run_dir/events.jsonl`` (was previously a parallel stream
the SDK ignored).
- ``on_llm_end`` now writes to ``Tracer.record_llm_usage`` in
addition to ``bus.record_usage`` so the CLI/TUI stats panel sees
real numbers instead of zeros.
- ``run_strix_scan`` accepts an externally-built ``AgentMessageBus``
+ an explicit ``model`` arg. The TUI pre-creates the bus so its
stop and chat-input handlers can submit ``bus.send`` /
``bus.cancel_descendants`` coroutines onto the scan thread's loop
via ``asyncio.run_coroutine_threadsafe`` — replacing the
TODO-stub no-ops.
- ``model`` config now propagates root → context → child agents in
``create_agent`` (was hardcoded fallback).
Dead-code removal:
- Deleted the ``load_skill`` tool entirely (host module, sandbox
module, TUI renderer, tests). The legacy implementation reached
into a global ``_agent_instances`` registry that no longer exists;
the post-migration stub returned ``success=True`` without
injecting anything — pure theater. Skills are still preloaded via
the system prompt at scan-bring-up.
- Dropped ``tenacity`` and ``xmltodict`` from
``[project.dependencies]`` — neither is imported anywhere
post-migration.
- Stripped the system prompt's "use the load_skill tool" lines.
Tests: 278/278 passing. Removed two ``load_skill`` test cases and a
``test_tool_registration_modes::test_load_skill_import_...`` assertion
that exercised the deleted module.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The SDK harness is the only path now; legacy host-side code is gone.
File names no longer carry the ``sdk_`` distinction.
Deleted legacy host-side modules:
- strix/agents/StrixAgent/ (template moved to strix/agents/prompts/)
- strix/agents/base_agent.py, state.py
- strix/llm/llm.py, config.py
- strix/runtime/docker_runtime.py, runtime.py
- strix/tools/executor.py, agents_graph/agents_graph_actions.py
- strix/interface/sdk_dispatch.py + the env-flag dispatch in cli.py
Renamed (drop ``sdk_`` prefix):
- strix/sdk_entry.py → strix/entry.py
- strix/agents/sdk_factory.py → strix/agents/factory.py
- strix/agents/sdk_prompt.py → strix/agents/prompt.py
- strix/tools/<x>/<x>_sdk_tool[s].py → strix/tools/<x>/tool[s].py
- strix/tools/_legacy_adapter.py → strix/tools/_state_adapter.py
- ``_legacy`` aliases inside the wrappers → ``_impl``
CLI + TUI now call ``run_strix_scan`` directly — they build the
sandbox image / sources_path locally and rely on
``session_manager.cleanup`` (called inside ``run_strix_scan``'s finally)
for teardown. Three TUI handlers that reached into legacy multi-agent
globals (``_agent_instances``, ``send_user_message_to_agent``,
``stop_agent``) are now no-ops with a TODO; reconnecting them to the
``AgentMessageBus`` is a follow-up.
Tracer.get_total_llm_stats no longer reaches into the deleted
``agents_graph_actions`` globals — the orchestration hooks now feed the
tracer via ``Tracer.record_llm_usage`` (live + completed buckets).
finish_scan's ``_check_active_agents`` and load_skill's runtime
``_agent_instances`` reach-in are no-op stubs; the
``AgentMessageBus`` is the source of truth post-migration.
llm/utils.py rewritten to keep only the streaming-parser helpers
(``normalize_tool_format``, ``parse_tool_invocations``,
``fix_incomplete_tool_call``, ``format_tool_call``, ``clean_content``).
``STRIX_MODEL_MAP`` moved to ``llm/multi_provider_setup.py`` (its only
remaining caller).
Per-file ruff ignores added for legacy interface modules (TUI / main /
CLI / utils / streaming_parser / tool_components) and tracer.py —
pre-existing PLC0415/BLE001/PLR0915 patterns are out of scope.
Tests: 287/287 passing. Renamed test files to drop ``sdk_`` prefix.
``test_tracer.py::test_get_total_llm_stats_aggregates_live_and_completed``
rewritten to feed ``Tracer.record_llm_usage`` instead of legacy globals.
Test file annotations added so pre-commit's strict mypy passes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three new modules that wire Phases 0-4 into a runnable Strix scan:
- strix/agents/sdk_prompt.py: standalone Jinja-based system prompt
renderer. Reuses the existing strix/agents/StrixAgent/system_prompt.
jinja template (508 lines, the actual production prompt) so behavior
parity with the legacy LLM._load_system_prompt is byte-identical.
Skill resolution mirrors LLM._get_skills_to_load (caller skills →
scan_modes/<mode> → whitebox pair, deduped). Fail-soft: template
errors return empty string and log; agent construction must never
blow up on prompt load.
- strix/agents/sdk_factory.py: build_strix_agent(name, skills, is_root)
assembles an agents.Agent. Root carries finish_scan and stops there;
child carries agent_finish and stops there (C4). Caido tools come
from CaidoCapability automatically — we don't include them in
_BASE_TOOLS to avoid double-registration when the SDK runtime merges
capability tools. model=None so RunConfig drives the model alias
through MultiProvider rather than the SDK default. make_child_factory
returns a closure over scan-level config (scan_mode, is_whitebox,
interactive, scope context) for ctx.context['agent_factory'] — the
Phase 3 create_agent tool calls it with (name, skills) per child.
- strix/sdk_entry.py: run_strix_scan() — the top-level coroutine.
Builds the bus, brings up (or reuses) a sandbox session via
session_manager, builds the root Agent and the child factory, builds
the per-agent context dict, registers the root in the bus, builds
the RunConfig, calls Runner.run, and cleans up the session in a
finally. Cancels descendants before re-raising any exception (C9).
cleanup_on_exit toggle preserves the cached session for resume
scenarios. _build_root_task and _build_scope_context preserve the
legacy StrixAgent.execute_scan task formatting + scope context shape
so the prompt template sees identical inputs.
Tests: 21 new tests (10 for factory + prompt, 11 for entry point).
Factory: root vs child tool list parity, finish_scan/agent_finish
placement, tool_use_behavior dict shape, Caido absence (capability-
provided), make_child_factory closure semantics. Entry point (all
mocked, no real Docker/LLM): wiring shape verification — context dict
carries every field downstream consumers read, session manager called
with correct scan_id, cleanup runs even on Runner.run failure,
cleanup skipped when disabled, scan_id auto-generation, scan-level
config (scan_mode, is_whitebox) flows into the factory. Task and scope
builders verified against the same shape as legacy.
Per-file ruff ignores added: TC002 on sdk_factory (Tool used at
runtime in _BASE_TOOLS tuple), TC003 + PLR0912 on sdk_entry (Path
runtime-imported; _build_root_task's per-target-type branches are
intentional and well-bounded).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>