From 07c9f09947caf13b451f451450cce90e28304307 Mon Sep 17 00:00:00 2001 From: Felix <0xfelixli@gmail.com> Date: Mon, 29 Jun 2026 17:59:33 +0800 Subject: [PATCH] feat: add STRIX_DISABLE_FIX_AGENTS to skip dedicated fix subagents When set, the root coordinator is instructed not to spawn dedicated fix/remediation subagents; remediation still lands in each report's remediation_steps field. Off by default, so existing behavior is unchanged. Useful for cost-conscious scans where a separate fix-writing agent mostly burns tokens and concurrency. The directive is injected into the root agent's prompt only when the env var is set and only for the root agent, leaving child prompts and the shipped skill file untouched. Co-Authored-By: Claude Opus 4.8 (1M context) --- strix/agents/prompt.py | 17 +++++++++++++++++ strix/config/__init__.py | 8 +++++--- strix/config/settings.py | 10 ++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/strix/agents/prompt.py b/strix/agents/prompt.py index 5d902176..0626a069 100644 --- a/strix/agents/prompt.py +++ b/strix/agents/prompt.py @@ -7,6 +7,7 @@ from typing import Any from jinja2 import Environment, FileSystemLoader, select_autoescape +from strix.config import load_settings from strix.skills import get_available_skills, load_skills from strix.utils.resource_paths import get_strix_resource_path @@ -16,6 +17,16 @@ logger = logging.getLogger(__name__) _PROMPT_DIRNAME = "prompts" +# Appended to the root coordinator's skill when STRIX_DISABLE_FIX_AGENTS is +# set, overriding the "Fix agent provides remediation" delegation step. +_DISABLE_FIX_AGENTS_DIRECTIVE = ( + "\n\n## Fix Agents Disabled\n\n" + "Do NOT spawn dedicated fix or remediation subagents. Remediation is " + "captured inline in each report's `remediation_steps` field, which is " + "sufficient. A separate agent that only writes fixes wastes tokens and " + "concurrency, so skip that delegation step entirely." +) + def _resolve_skills( *, @@ -85,6 +96,12 @@ def render_system_prompt( is_root=is_root, ) skill_content = load_skills(skills_to_load) + if ( + is_root + and "root_agent" in skill_content + and load_settings().agents.disable_fix_agents + ): + skill_content["root_agent"] += _DISABLE_FIX_AGENTS_DIRECTIVE env.globals["get_skill"] = lambda name: skill_content.get(name, "") rendered = env.get_template("system_prompt.jinja").render( diff --git a/strix/config/__init__.py b/strix/config/__init__.py index fda68602..ca27b7de 100644 --- a/strix/config/__init__.py +++ b/strix/config/__init__.py @@ -3,9 +3,9 @@ Public surface: - :class:`Settings` — composite model. Get via :func:`load_settings`. -- :class:`LlmSettings`, :class:`RuntimeSettings`, :class:`TelemetrySettings`, - :class:`IntegrationSettings` — sub-models, attribute-accessed off - ``Settings``. +- :class:`LlmSettings`, :class:`RuntimeSettings`, :class:`AgentSettings`, + :class:`TelemetrySettings`, :class:`IntegrationSettings` — sub-models, + attribute-accessed off ``Settings``. - :func:`load_settings` — memoized resolve (env > JSON file > defaults). - :func:`apply_config_override` — switch the JSON source to a custom path. - :func:`persist_current` — write currently-set env vars to the active file. @@ -17,6 +17,7 @@ from strix.config.loader import ( persist_current, ) from strix.config.settings import ( + AgentSettings, IntegrationSettings, LlmSettings, RuntimeSettings, @@ -26,6 +27,7 @@ from strix.config.settings import ( __all__ = [ + "AgentSettings", "IntegrationSettings", "LlmSettings", "RuntimeSettings", diff --git a/strix/config/settings.py b/strix/config/settings.py index 91fbdef1..0b2d3159 100644 --- a/strix/config/settings.py +++ b/strix/config/settings.py @@ -54,6 +54,15 @@ class RuntimeSettings(BaseSettings): max_local_copy_mb: int = Field(default=1024, alias="STRIX_MAX_LOCAL_COPY_MB") +class AgentSettings(BaseSettings): + model_config = _BASE_CONFIG + + # When true, the root coordinator is instructed not to spawn dedicated + # fix/remediation subagents; remediation still lands in each report's + # ``remediation_steps``. Off by default (no behavior change for others). + disable_fix_agents: bool = Field(default=False, alias="STRIX_DISABLE_FIX_AGENTS") + + class TelemetrySettings(BaseSettings): model_config = _BASE_CONFIG @@ -71,5 +80,6 @@ class Settings(BaseSettings): llm: LlmSettings = Field(default_factory=LlmSettings) runtime: RuntimeSettings = Field(default_factory=RuntimeSettings) + agents: AgentSettings = Field(default_factory=AgentSettings) telemetry: TelemetrySettings = Field(default_factory=TelemetrySettings) integrations: IntegrationSettings = Field(default_factory=IntegrationSettings)