refactor: collapse strix/io/, strix/run_config_factory.py, strix/entry.py
Three top-level files that didn't earn their place: - ``strix/io/scan_artifacts.py`` had a single consumer (the Tracer); collapsing it into ``strix/telemetry/`` puts it next to that consumer. ``strix/io/`` is gone. - ``strix/run_config_factory.py`` held two helpers that didn't earn the factoring. ``make_agent_context`` was a 17-line dict-spelling function whose argument names were identical to its dict keys — replaced with inline dict literals at the two call sites. ``make_run_config`` had enough RunConfig assembly logic to justify a helper, but with only two callers (root scan + ``create_agent``) inlining is cleaner than keeping a top-level file. ``DEFAULT_RETRY`` moves to ``strix/llm/retry.py`` next to its other LLM-policy peers; the dead ``STRIX_DEFAULT_MAX_TURNS`` constant is dropped. - ``strix/entry.py`` is a misnomer — it isn't *the* entry point (that's ``strix/interface/main.py`` for the CLI), it's the per-scan bring-up driver: build the bus, bring up the sandbox, build the root agent + child factory, format the scope-context block, register root in bus, open SQLiteSession, hand off to ``run_with_continuation``. That all lives next to its peers in ``strix/orchestration/`` now, renamed to ``scan.py`` so the role is obvious. No behavior change. Net -125 LoC. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -211,7 +211,7 @@ ignore = [
|
|||||||
"strix/runtime/backends.py" = ["PLC0415"]
|
"strix/runtime/backends.py" = ["PLC0415"]
|
||||||
# The vulnerability MD renderer is a long monolithic format function;
|
# The vulnerability MD renderer is a long monolithic format function;
|
||||||
# splitting per-section would obscure the structure without simplifying.
|
# splitting per-section would obscure the structure without simplifying.
|
||||||
"strix/io/scan_artifacts.py" = ["PLR0912", "PLR0915", "PERF401"]
|
"strix/telemetry/scan_artifacts.py" = ["PLR0912", "PLR0915", "PERF401"]
|
||||||
"strix/runtime/docker_client.py" = [
|
"strix/runtime/docker_client.py" = [
|
||||||
"TC002", # Manifest, Container imported for annotations
|
"TC002", # Manifest, Container imported for annotations
|
||||||
"TC003", # uuid imported for annotation
|
"TC003", # uuid imported for annotation
|
||||||
@@ -234,7 +234,7 @@ ignore = [
|
|||||||
# resolution past where mypy needs it. ``_build_root_task`` legitimately
|
# resolution past where mypy needs it. ``_build_root_task`` legitimately
|
||||||
# walks every supported target type — splitting it into per-type
|
# walks every supported target type — splitting it into per-type
|
||||||
# helpers would add indirection without simplifying anything.
|
# helpers would add indirection without simplifying anything.
|
||||||
"strix/entry.py" = ["TC003", "PLR0912"]
|
"strix/orchestration/scan.py" = ["TC003", "PLR0912"]
|
||||||
# Tracer carries a long event surface and a runtime ``Callable``
|
# Tracer carries a long event surface and a runtime ``Callable``
|
||||||
# annotation on ``vulnerability_found_callback``.
|
# annotation on ``vulnerability_found_callback``.
|
||||||
"strix/telemetry/tracer.py" = ["TC003", "PLR0912", "PLR0915", "E501"]
|
"strix/telemetry/tracer.py" = ["TC003", "PLR0912", "PLR0915", "E501"]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from rich.panel import Panel
|
|||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
|
|
||||||
from strix.config import load_settings
|
from strix.config import load_settings
|
||||||
from strix.entry import run_strix_scan
|
from strix.orchestration.scan import run_strix_scan
|
||||||
from strix.runtime import session_manager
|
from strix.runtime import session_manager
|
||||||
from strix.telemetry.tracer import Tracer, set_global_tracer
|
from strix.telemetry.tracer import Tracer, set_global_tracer
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ from textual.widgets import Button, Label, Static, TextArea, Tree
|
|||||||
from textual.widgets.tree import TreeNode
|
from textual.widgets.tree import TreeNode
|
||||||
|
|
||||||
from strix.config import load_settings
|
from strix.config import load_settings
|
||||||
from strix.entry import run_strix_scan
|
|
||||||
from strix.interface.tool_components.agent_message_renderer import AgentMessageRenderer
|
from strix.interface.tool_components.agent_message_renderer import AgentMessageRenderer
|
||||||
from strix.interface.tool_components.registry import get_tool_renderer
|
from strix.interface.tool_components.registry import get_tool_renderer
|
||||||
from strix.interface.tool_components.user_message_renderer import UserMessageRenderer
|
from strix.interface.tool_components.user_message_renderer import UserMessageRenderer
|
||||||
from strix.interface.utils import build_tui_stats_text
|
from strix.interface.utils import build_tui_stats_text
|
||||||
|
from strix.orchestration.scan import run_strix_scan
|
||||||
from strix.runtime import session_manager
|
from strix.runtime import session_manager
|
||||||
from strix.telemetry.tracer import Tracer, set_global_tracer
|
from strix.telemetry.tracer import Tracer, set_global_tracer
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
"""Strix I/O — disk artifact writers.
|
|
||||||
|
|
||||||
- :class:`ScanArtifactWriter` — writes vulnerability MD/CSV plus the
|
|
||||||
final penetration-test report under ``strix_runs/<run>/``. Used by
|
|
||||||
the tracer; could be used directly by post-run tooling.
|
|
||||||
"""
|
|
||||||
+1
-1
@@ -18,7 +18,7 @@ from openai.types.responses import ResponseOutputMessage
|
|||||||
|
|
||||||
from strix.config import load_settings
|
from strix.config import load_settings
|
||||||
from strix.llm.multi_provider_setup import build_multi_provider
|
from strix.llm.multi_provider_setup import build_multi_provider
|
||||||
from strix.run_config_factory import DEFAULT_RETRY
|
from strix.llm.retry import DEFAULT_RETRY
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
"""Shared model-retry policy used across every Strix LLM call."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from agents.retry import (
|
||||||
|
ModelRetryBackoffSettings,
|
||||||
|
ModelRetrySettings,
|
||||||
|
retry_policies,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Retry: 5 attempts with ``min(90, 2*2^n)`` backoff. 4xx auth/validation
|
||||||
|
# errors are excluded from the retryable status list — they can't be
|
||||||
|
# fixed by retrying and should fail fast. Used by every ``RunConfig``
|
||||||
|
# Strix builds, plus the dedupe path's one-shot LLM call outside
|
||||||
|
# ``Runner.run``.
|
||||||
|
DEFAULT_RETRY = ModelRetrySettings(
|
||||||
|
max_retries=5,
|
||||||
|
backoff=ModelRetryBackoffSettings(
|
||||||
|
initial_delay=2.0,
|
||||||
|
max_delay=90.0,
|
||||||
|
multiplier=2.0,
|
||||||
|
jitter=False,
|
||||||
|
),
|
||||||
|
policy=retry_policies.any(
|
||||||
|
retry_policies.provider_suggested(),
|
||||||
|
retry_policies.network_error(),
|
||||||
|
retry_policies.http_status((429, 500, 502, 503, 504)),
|
||||||
|
),
|
||||||
|
)
|
||||||
@@ -20,21 +20,27 @@ import uuid
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any, Literal
|
from typing import TYPE_CHECKING, Any, Literal
|
||||||
|
|
||||||
|
from agents import RunConfig
|
||||||
from agents.memory import SQLiteSession
|
from agents.memory import SQLiteSession
|
||||||
|
from agents.model_settings import ModelSettings
|
||||||
|
from agents.sandbox import SandboxRunConfig
|
||||||
|
from openai.types.shared import Reasoning
|
||||||
|
|
||||||
from strix.agents.factory import build_strix_agent, make_child_factory
|
from strix.agents.factory import build_strix_agent, make_child_factory
|
||||||
from strix.config import load_settings
|
from strix.config import load_settings
|
||||||
|
from strix.llm.multi_provider_setup import build_multi_provider
|
||||||
|
from strix.llm.retry import DEFAULT_RETRY
|
||||||
from strix.orchestration.bus import AgentMessageBus
|
from strix.orchestration.bus import AgentMessageBus
|
||||||
|
from strix.orchestration.filter import inject_messages_filter
|
||||||
from strix.orchestration.hooks import StrixOrchestrationHooks
|
from strix.orchestration.hooks import StrixOrchestrationHooks
|
||||||
from strix.orchestration.run_loop import run_with_continuation
|
from strix.orchestration.run_loop import run_with_continuation
|
||||||
from strix.run_config_factory import (
|
|
||||||
STRIX_DEFAULT_MAX_TURNS,
|
|
||||||
make_agent_context,
|
|
||||||
make_run_config,
|
|
||||||
)
|
|
||||||
from strix.runtime import session_manager
|
from strix.runtime import session_manager
|
||||||
|
|
||||||
|
|
||||||
|
#: Default ``max_turns`` budget passed to ``Runner.run``.
|
||||||
|
_MAX_TURNS = 300
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from agents.result import RunResultBase
|
from agents.result import RunResultBase
|
||||||
|
|
||||||
@@ -160,7 +166,7 @@ async def run_strix_scan(
|
|||||||
tracer: Any | None = None,
|
tracer: Any | None = None,
|
||||||
bus: AgentMessageBus | None = None,
|
bus: AgentMessageBus | None = None,
|
||||||
interactive: bool = False,
|
interactive: bool = False,
|
||||||
max_turns: int = STRIX_DEFAULT_MAX_TURNS,
|
max_turns: int = _MAX_TURNS,
|
||||||
model: str | None = None,
|
model: str | None = None,
|
||||||
cleanup_on_exit: bool = True,
|
cleanup_on_exit: bool = True,
|
||||||
) -> RunResultBase:
|
) -> RunResultBase:
|
||||||
@@ -215,7 +221,7 @@ async def run_strix_scan(
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Lazy: ``strix.interface`` pulls cli→tui→entry which would cycle.
|
# Lazy: ``strix.interface`` pulls cli→tui→scan which would cycle.
|
||||||
from strix.interface.utils import is_whitebox_scan
|
from strix.interface.utils import is_whitebox_scan
|
||||||
|
|
||||||
scan_mode = str(scan_config.get("scan_mode") or "deep")
|
scan_mode = str(scan_config.get("scan_mode") or "deep")
|
||||||
@@ -245,31 +251,45 @@ async def run_strix_scan(
|
|||||||
system_prompt_context=scope_context,
|
system_prompt_context=scope_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
context = make_agent_context(
|
context: dict[str, Any] = {
|
||||||
bus=bus,
|
"bus": bus,
|
||||||
sandbox_session=bundle["session"],
|
"sandbox_session": bundle["session"],
|
||||||
sandbox_client=bundle["client"],
|
"sandbox_client": bundle["client"],
|
||||||
caido_client=bundle["caido_client"],
|
"caido_client": bundle["caido_client"],
|
||||||
agent_id=root_id,
|
"agent_id": root_id,
|
||||||
parent_id=None,
|
"parent_id": None,
|
||||||
tracer=tracer,
|
"tracer": tracer,
|
||||||
model=resolved_model,
|
"model": resolved_model,
|
||||||
max_turns=max_turns,
|
"model_settings": None,
|
||||||
is_whitebox=is_whitebox,
|
"max_turns": max_turns,
|
||||||
interactive=interactive,
|
"agent_finish_called": False,
|
||||||
diff_scope=diff_scope,
|
"is_whitebox": is_whitebox,
|
||||||
run_id=run_id,
|
"interactive": interactive,
|
||||||
agent_factory=agent_factory,
|
"diff_scope": diff_scope,
|
||||||
)
|
"run_id": run_id,
|
||||||
|
"agent_factory": agent_factory,
|
||||||
|
}
|
||||||
|
|
||||||
reasoning_effort: Literal["low", "medium", "high"] | None = (
|
reasoning_effort: Literal["low", "medium", "high"] | None = (
|
||||||
load_settings().llm.reasoning_effort
|
load_settings().llm.reasoning_effort
|
||||||
)
|
)
|
||||||
run_config = make_run_config(
|
model_settings = ModelSettings(
|
||||||
sandbox_session=bundle["session"],
|
parallel_tool_calls=False,
|
||||||
sandbox_client=bundle["client"],
|
tool_choice="required",
|
||||||
|
retry=DEFAULT_RETRY,
|
||||||
|
)
|
||||||
|
if reasoning_effort is not None:
|
||||||
|
model_settings = model_settings.resolve(
|
||||||
|
ModelSettings(reasoning=Reasoning(effort=reasoning_effort)),
|
||||||
|
)
|
||||||
|
run_config = RunConfig(
|
||||||
model=resolved_model,
|
model=resolved_model,
|
||||||
reasoning_effort=reasoning_effort,
|
model_provider=build_multi_provider(),
|
||||||
|
model_settings=model_settings,
|
||||||
|
sandbox=SandboxRunConfig(client=bundle["client"], session=bundle["session"]),
|
||||||
|
call_model_input_filter=inject_messages_filter,
|
||||||
|
tracing_disabled=False,
|
||||||
|
trace_include_sensitive_data=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Native SDK session: persists conversation history to
|
# Native SDK session: persists conversation history to
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
"""``make_run_config`` — assemble a Strix-flavored ``RunConfig`` for ``Runner.run``.
|
|
||||||
|
|
||||||
Every scan goes through here so defaults apply uniformly. Per-call
|
|
||||||
overrides land via ``model_settings_override``.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, Literal
|
|
||||||
|
|
||||||
from agents import RunConfig
|
|
||||||
from agents.model_settings import ModelSettings
|
|
||||||
from agents.retry import (
|
|
||||||
ModelRetryBackoffSettings,
|
|
||||||
ModelRetrySettings,
|
|
||||||
retry_policies,
|
|
||||||
)
|
|
||||||
from agents.sandbox import SandboxRunConfig
|
|
||||||
from openai.types.shared import Reasoning
|
|
||||||
|
|
||||||
from strix.llm.multi_provider_setup import build_multi_provider
|
|
||||||
from strix.orchestration.filter import inject_messages_filter
|
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from agents.sandbox.session.base_sandbox_session import BaseSandboxSession
|
|
||||||
|
|
||||||
from strix.orchestration.bus import AgentMessageBus
|
|
||||||
|
|
||||||
|
|
||||||
#: Default ``max_turns`` callers should pass to ``Runner.run``.
|
|
||||||
STRIX_DEFAULT_MAX_TURNS = 300
|
|
||||||
|
|
||||||
# Retry: 5 attempts with ``min(90, 2*2^n)`` backoff. 4xx auth/validation
|
|
||||||
# errors are excluded from the retryable status list — they can't be
|
|
||||||
# fixed by retrying and should fail fast. Public so the dedupe path
|
|
||||||
# (and any other one-shot LLM call outside ``Runner.run``) reuses the
|
|
||||||
# same policy.
|
|
||||||
DEFAULT_RETRY = ModelRetrySettings(
|
|
||||||
max_retries=5,
|
|
||||||
backoff=ModelRetryBackoffSettings(
|
|
||||||
initial_delay=2.0,
|
|
||||||
max_delay=90.0,
|
|
||||||
multiplier=2.0,
|
|
||||||
jitter=False,
|
|
||||||
),
|
|
||||||
policy=retry_policies.any(
|
|
||||||
retry_policies.provider_suggested(),
|
|
||||||
retry_policies.network_error(),
|
|
||||||
retry_policies.http_status((429, 500, 502, 503, 504)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def make_run_config(
|
|
||||||
*,
|
|
||||||
sandbox_session: BaseSandboxSession | None,
|
|
||||||
model: str,
|
|
||||||
reasoning_effort: Literal["low", "medium", "high"] | None = None,
|
|
||||||
model_settings_override: ModelSettings | None = None,
|
|
||||||
sandbox_client: Any | None = None,
|
|
||||||
) -> RunConfig:
|
|
||||||
"""Build a ``RunConfig`` with Strix defaults.
|
|
||||||
|
|
||||||
Note: ``max_turns`` is not a ``RunConfig`` field — pass it directly
|
|
||||||
to ``Runner.run``. ``STRIX_DEFAULT_MAX_TURNS`` is the budget Strix
|
|
||||||
uses.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
sandbox_session: Live sandbox session shared by every agent in
|
|
||||||
this scan (one container per scan; see
|
|
||||||
:mod:`strix.runtime.session_manager`). ``None`` is allowed
|
|
||||||
for unit tests and dry runs.
|
|
||||||
model: Litellm model alias passed to ``MultiProvider``. Caller
|
|
||||||
resolves from :attr:`Settings.llm.model`.
|
|
||||||
reasoning_effort: ``"low" | "medium" | "high"``; routes to
|
|
||||||
``ModelSettings.reasoning``.
|
|
||||||
model_settings_override: Optional per-run ``ModelSettings``
|
|
||||||
merged over factory defaults.
|
|
||||||
sandbox_client: Optional pre-built sandbox client (Strix Docker
|
|
||||||
subclass). The SDK instantiates its built-in if a session is
|
|
||||||
supplied without a client.
|
|
||||||
"""
|
|
||||||
base_settings = ModelSettings(
|
|
||||||
parallel_tool_calls=False,
|
|
||||||
tool_choice="required",
|
|
||||||
retry=DEFAULT_RETRY,
|
|
||||||
)
|
|
||||||
if reasoning_effort is not None:
|
|
||||||
base_settings = base_settings.resolve(
|
|
||||||
ModelSettings(reasoning=Reasoning(effort=reasoning_effort)),
|
|
||||||
)
|
|
||||||
if model_settings_override is not None:
|
|
||||||
base_settings = base_settings.resolve(model_settings_override)
|
|
||||||
|
|
||||||
sandbox_config = (
|
|
||||||
SandboxRunConfig(client=sandbox_client, session=sandbox_session)
|
|
||||||
if sandbox_session is not None
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
|
|
||||||
return RunConfig(
|
|
||||||
model=model,
|
|
||||||
model_provider=build_multi_provider(),
|
|
||||||
model_settings=base_settings,
|
|
||||||
sandbox=sandbox_config,
|
|
||||||
call_model_input_filter=inject_messages_filter,
|
|
||||||
tracing_disabled=False,
|
|
||||||
trace_include_sensitive_data=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def make_agent_context(
|
|
||||||
*,
|
|
||||||
bus: AgentMessageBus,
|
|
||||||
sandbox_session: BaseSandboxSession | None,
|
|
||||||
agent_id: str,
|
|
||||||
parent_id: str | None,
|
|
||||||
tracer: Any | None,
|
|
||||||
model: str,
|
|
||||||
model_settings: ModelSettings | None = None,
|
|
||||||
max_turns: int = 300,
|
|
||||||
is_whitebox: bool = False,
|
|
||||||
interactive: bool = False,
|
|
||||||
diff_scope: dict[str, Any] | None = None,
|
|
||||||
run_id: str | None = None,
|
|
||||||
sandbox_client: Any | None = None,
|
|
||||||
agent_factory: Any | None = None,
|
|
||||||
caido_client: Any | None = None,
|
|
||||||
) -> dict[str, Any]:
|
|
||||||
"""Build the per-agent ``context`` dict passed to ``Runner.run(context=...)``.
|
|
||||||
|
|
||||||
The canonical place where bus, sandbox handles, identity, tracer
|
|
||||||
reference, and per-agent toggles live. Tools, hooks, and
|
|
||||||
``inject_messages_filter`` reach in via ``ctx.context.get(...)``.
|
|
||||||
|
|
||||||
``agent_factory`` is a callable ``(name, skills) -> agents.Agent`` —
|
|
||||||
the ``create_agent`` graph tool uses it to spin up children that
|
|
||||||
inherit the same wiring. ``sandbox_client`` is the host-side Docker
|
|
||||||
subclass, reused across child runs.
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
"bus": bus,
|
|
||||||
"sandbox_session": sandbox_session,
|
|
||||||
"sandbox_client": sandbox_client,
|
|
||||||
"caido_client": caido_client,
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"parent_id": parent_id,
|
|
||||||
"tracer": tracer,
|
|
||||||
"model": model,
|
|
||||||
"model_settings": model_settings,
|
|
||||||
"max_turns": max_turns,
|
|
||||||
"agent_finish_called": False,
|
|
||||||
"is_whitebox": is_whitebox,
|
|
||||||
"interactive": interactive,
|
|
||||||
"diff_scope": diff_scope,
|
|
||||||
"run_id": run_id,
|
|
||||||
"agent_factory": agent_factory,
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,8 @@ from pathlib import Path
|
|||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from strix.io.scan_artifacts import ScanArtifactWriter
|
|
||||||
from strix.telemetry import posthog
|
from strix.telemetry import posthog
|
||||||
|
from strix.telemetry.scan_artifacts import ScanArtifactWriter
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -22,12 +22,16 @@ import uuid
|
|||||||
from datetime import UTC, datetime
|
from datetime import UTC, datetime
|
||||||
from typing import TYPE_CHECKING, Any, Literal
|
from typing import TYPE_CHECKING, Any, Literal
|
||||||
|
|
||||||
from agents import RunContextWrapper, function_tool
|
from agents import RunConfig, RunContextWrapper, function_tool
|
||||||
from agents.items import TResponseInputItem
|
from agents.items import TResponseInputItem
|
||||||
|
from agents.model_settings import ModelSettings
|
||||||
|
from agents.sandbox import SandboxRunConfig
|
||||||
|
|
||||||
|
from strix.llm.multi_provider_setup import build_multi_provider
|
||||||
|
from strix.llm.retry import DEFAULT_RETRY
|
||||||
|
from strix.orchestration.filter import inject_messages_filter
|
||||||
from strix.orchestration.hooks import StrixOrchestrationHooks
|
from strix.orchestration.hooks import StrixOrchestrationHooks
|
||||||
from strix.orchestration.run_loop import run_with_continuation
|
from strix.orchestration.run_loop import run_with_continuation
|
||||||
from strix.run_config_factory import make_agent_context, make_run_config
|
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -428,7 +432,7 @@ async def create_agent(
|
|||||||
"success": False,
|
"success": False,
|
||||||
"error": (
|
"error": (
|
||||||
"No agent_factory in context. "
|
"No agent_factory in context. "
|
||||||
"The root assembly must inject one via make_agent_context."
|
"The root assembly must inject one when building the run context."
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
ensure_ascii=False,
|
ensure_ascii=False,
|
||||||
@@ -485,32 +489,48 @@ async def create_agent(
|
|||||||
)
|
)
|
||||||
initial_input.append({"role": "user", "content": task})
|
initial_input.append({"role": "user", "content": task})
|
||||||
|
|
||||||
child_ctx = make_agent_context(
|
child_ctx: dict[str, Any] = {
|
||||||
bus=bus,
|
"bus": bus,
|
||||||
sandbox_session=inner.get("sandbox_session"),
|
"sandbox_session": inner.get("sandbox_session"),
|
||||||
sandbox_client=inner.get("sandbox_client"),
|
"sandbox_client": inner.get("sandbox_client"),
|
||||||
caido_client=inner.get("caido_client"),
|
"caido_client": inner.get("caido_client"),
|
||||||
agent_id=child_id,
|
"agent_id": child_id,
|
||||||
parent_id=parent_id,
|
"parent_id": parent_id,
|
||||||
tracer=inner.get("tracer"),
|
"tracer": inner.get("tracer"),
|
||||||
model=inner["model"],
|
"model": inner["model"],
|
||||||
model_settings=inner.get("model_settings"),
|
"model_settings": inner.get("model_settings"),
|
||||||
max_turns=int(inner.get("max_turns", 300)),
|
"max_turns": int(inner.get("max_turns", 300)),
|
||||||
is_whitebox=bool(inner.get("is_whitebox", False)),
|
"agent_finish_called": False,
|
||||||
interactive=bool(inner.get("interactive", False)),
|
"is_whitebox": bool(inner.get("is_whitebox", False)),
|
||||||
diff_scope=inner.get("diff_scope"),
|
"interactive": bool(inner.get("interactive", False)),
|
||||||
run_id=inner.get("run_id"),
|
"diff_scope": inner.get("diff_scope"),
|
||||||
agent_factory=factory,
|
"run_id": inner.get("run_id"),
|
||||||
)
|
"agent_factory": factory,
|
||||||
# Stash the task string for ``agent_finish`` to echo back in its
|
# Stashed for ``agent_finish`` to echo back in its completion report.
|
||||||
# XML completion report.
|
"task": task,
|
||||||
child_ctx["task"] = task
|
}
|
||||||
|
|
||||||
child_run_config = make_run_config(
|
child_model_settings = ModelSettings(
|
||||||
sandbox_session=inner.get("sandbox_session"),
|
parallel_tool_calls=False,
|
||||||
sandbox_client=inner.get("sandbox_client"),
|
tool_choice="required",
|
||||||
|
retry=DEFAULT_RETRY,
|
||||||
|
)
|
||||||
|
override = inner.get("model_settings")
|
||||||
|
if override is not None:
|
||||||
|
child_model_settings = child_model_settings.resolve(override)
|
||||||
|
sandbox_session = inner.get("sandbox_session")
|
||||||
|
child_run_config = RunConfig(
|
||||||
model=inner["model"],
|
model=inner["model"],
|
||||||
model_settings_override=inner.get("model_settings"),
|
model_provider=build_multi_provider(),
|
||||||
|
model_settings=child_model_settings,
|
||||||
|
sandbox=(
|
||||||
|
SandboxRunConfig(client=inner.get("sandbox_client"), session=sandbox_session)
|
||||||
|
if sandbox_session is not None
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
call_model_input_filter=inject_messages_filter,
|
||||||
|
tracing_disabled=False,
|
||||||
|
trace_include_sensitive_data=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
task_handle = asyncio.create_task(
|
task_handle = asyncio.create_task(
|
||||||
|
|||||||
Reference in New Issue
Block a user