Skip to content

symfonic.diagnostics.checks.check_lazy_tooling_orphan

check_lazy_tooling_orphan

lazy_tooling=True orphan audit (v7.16, item 5, bonus from item 1).

Mirrors :meth:SymfonicAgent._validate_lazy_tooling_prerequisites but surfaces the same three failures as a hard ERROR in the audit report rather than the soft LazyToolingWarning the engine emits at construction time. Adopters who filter out UserWarning (or simply miss it in their startup logs) still get the actionable surface here.

Predicate (matches engine.py:5832-5881):

  • FrameworkConfig.lazy_tooling = True AND any of:
  • FrameworkConfig.enable_hms_prompt = False
  • MemoryLayer.PROCEDURAL not registered on the orchestrator
  • FrameworkConfig.domain.tool_manifest is empty

check_lazy_tooling_orphan async

check_lazy_tooling_orphan(
    agent: SymfonicAgent,
) -> list[CheckResult]

Flag lazy_tooling=True paired with missing prerequisites.

Source code in src/symfonic/diagnostics/checks/check_lazy_tooling_orphan.py
async def check_lazy_tooling_orphan(
    agent: SymfonicAgent,
) -> list[CheckResult]:
    """Flag ``lazy_tooling=True`` paired with missing prerequisites."""
    config = agent._config
    if not config.lazy_tooling:
        return []

    reasons: list[str] = []

    if not config.enable_hms_prompt:
        reasons.append(
            "enable_hms_prompt=False (HMS system-prompt pipeline is the "
            "only codepath that invokes _lazy_resolve_tools)",
        )

    procedural_layer = agent._orchestrator.get_layer(MemoryLayer.PROCEDURAL)
    if procedural_layer is None:
        reasons.append(
            "procedural memory layer is not registered "
            "(CapabilityRouter has no skills to route between)",
        )

    if not config.domain.tool_manifest:
        reasons.append(
            "DomainTemplate.tool_manifest is empty "
            "(CapabilityRouter has no tools to filter from)",
        )

    if not reasons:
        return []

    bullets = "\n    - ".join(reasons)
    return [
        CheckResult(
            name="lazy_tooling.orphan",
            severity=Severity.ERROR,
            message=(
                "lazy_tooling=True but prerequisites are missing -- the "
                "engine will send all tool schemas on every request "
                "(silent token bloat):\n    - " + bullets
            ),
            fix_hint=(
                "Either disable lazy_tooling=False or satisfy all three "
                "prerequisites.  See docs/guides/06-lazy-tooling.md."
            ),
        ),
    ]