"""Analysis base class. An Analysis is a self-contained mini-agent. It owns its reasoning pattern (CoT, ReAct, plan-and-execute) and exposes a uniform external contract: `run(args, question) -> Finding`. The runtime composes Analyses; it doesn't know how each one thinks internally. Public surface is framework-free — no langgraph types leak out. """ from __future__ import annotations from typing import Any, ClassVar from api.analyses.types import Finding class Analysis: """Subclass and set `name`, `description`, `args_schema`; then implement run().""" name: ClassVar[str] = "" description: ClassVar[str] = "" # JSON-schema-ish description of the args dict — the planner reads this. args_schema: ClassVar[dict[str, Any]] = {} async def run(self, args: dict[str, Any], question: str) -> Finding: raise NotImplementedError