# `ai.agents` — Module Overview

> This document is partially auto-generated. Sections tagged `<!-- AUTO:id -->` are refreshed by the generator.
> Everything else is yours to edit freely and will never be overwritten.

<!-- AUTO:meta -->
## About This Document

This file is **partially auto-generated**. Sections wrapped in `<!-- AUTO:id -->` tags
are overwritten each time the generator runs. Everything else is yours to edit freely.

| Field | Value |
|-------|-------|
| Module | `matrx_ai/agents` |
| Last generated | 2026-04-07 11:38 |
| Output file | `matrx_ai/agents/MODULE_README.md` |
| Signature mode | `signatures` |

**To refresh auto-sections:**
```bash
python utils/code_context/generate_module_readme.py matrx_ai/agents --mode signatures
```

**To add permanent notes:** Write anywhere outside the `<!-- AUTO:... -->` blocks.
<!-- /AUTO:meta -->

<!-- HUMAN-EDITABLE: This section is yours. Agents & Humans can edit this section freely — it will not be overwritten. -->

## Architecture

> **Fill this in.** Describe the execution flow and layer map for this module.
> See `utils/code_context/MODULE_README_SPEC.md` for the recommended format.
>
> Suggested structure:
>
> ### Layers
> | File | Role |
> |------|------|
> | `entry.py` | Public entry point — receives requests, returns results |
> | `engine.py` | Core dispatch logic |
> | `models.py` | Shared data types |
>
> ### Call Flow (happy path)
> ```
> entry_function() → engine.dispatch() → implementation()
> ```


<!-- AUTO:tree -->
## Directory Tree

> Auto-generated. 14 files across 3 directories.

```
matrx_ai/agents/
├── DEPRECATED_prompts_manager.py
├── MODULE_README.md
├── __init__.py
├── cache.py
├── definition.py
├── resolver.py
├── response_parser.py
├── services/
│   ├── batch_categorize.py
│   ├── conversation_labeler.py
│   ├── prompt_categorizer.py
├── tests/
│   ├── new_agent_test.py
│   ├── test_categorization.py
├── types.py
├── variables.py
# excluded: 1 .md
```
<!-- /AUTO:tree -->

<!-- AUTO:signatures -->
## API Signatures

> Auto-generated via `output_mode="signatures"`. ~5-10% token cost vs full source.
> For full source, open the individual files directly.

```
---
Filepath: matrx_ai/agents/variables.py  [python]

  class AgentVariable(BaseModel):
      # fields: name: str, value: str | None = None, default_value: str | None = None, required: bool = False, help_text: str | None = None
      def get_value(self) -> str
      def from_dict(cls, var_def: dict[str, Any]) -> 'AgentVariable'
      def from_list(var_defs: list | None) -> dict[str, 'AgentVariable']
      def to_dict(self) -> dict[str, Any]


---
Filepath: matrx_ai/agents/DEPRECATED_prompts_manager.py  [python]

  PromptBuiltinsBase = get_base('PromptBuiltinsBase')
  PromptBuiltinVersionsBase = get_base('PromptBuiltinVersionsBase')
  PromptAppVersionsBase = get_base('PromptAppVersionsBase')
  PromptVersionsBase = get_base('PromptVersionsBase')
  PromptsBase = get_base('PromptsBase')
  PromptBuiltins = get_model('PromptBuiltins')
  PromptBuiltinVersions = get_model('PromptBuiltinVersions')
  PromptVersions = get_model('PromptVersions')
  class PromptType(StrEnum):
  class PromptsManager(PromptsBase):
      def __new__(cls, *args, **kwargs)
      def __init__(self)
      async def to_config(self, prompt_id: str) -> AgentConfig
  class PromptBuiltinsManager(PromptBuiltinsBase):
      def __new__(cls, *args, **kwargs)
      def __init__(self)
      async def to_config(self, builtin_id: str) -> AgentConfig
  class PromptVersionsManager(PromptVersionsBase):
      def __new__(cls, *args: Any, **kwargs: Any) -> PromptVersionsManager
      def __init__(self) -> None
      async def to_config(self, version_id: str) -> AgentConfig
  class PromptBuiltinVersionsManager(PromptBuiltinVersionsBase):
      def __new__(cls, *args: Any, **kwargs: Any) -> PromptBuiltinVersionsManager
      def __init__(self) -> None
      async def to_config(self, version_id: str) -> AgentConfig
  class PromptAppVersionsManager(PromptAppVersionsBase):
      def __new__(cls, *args: Any, **kwargs: Any) -> PromptAppVersionsManager
      def __init__(self) -> None
  class PromptManagers:
      def __new__(cls) -> PromptManagers
      def __init__(self) -> None
      def _cache(self, item_id: str, ptype: PromptType) -> None
      def get_type(self, prompt_id: str) -> PromptType | None
      def cache_size(self) -> int
      async def hydrate_builtins(self) -> int
      def hydrate_builtins_sync(self) -> int
      async def hydrate_builtin_versions(self) -> int
      async def get_config(self, prompt_id: str) -> AgentConfig
      async def get_prompt_config(self, prompt_id: str) -> AgentConfig
      async def get_builtin_config(self, builtin_id: str) -> AgentConfig
      async def _prompt_config(self, prompt_id: str) -> AgentConfig
      async def _builtin_config(self, builtin_id: str) -> AgentConfig
      async def _version_config(self, version_id: str) -> AgentConfig
      async def _builtin_version_config(self, version_id: str) -> AgentConfig
      async def get_version_config(self, version_id: str) -> AgentConfig
      async def get_builtin_version_config(self, version_id: str) -> AgentConfig
      async def get_config_by_source(self, agent_id: str, source: str | None = None) -> AgentConfig
      async def _dispatch_by_type(self, agent_id: str, ptype: PromptType) -> AgentConfig
      async def load_prompt(self, prompt_id: str) -> Prompts
      async def load_prompt_or_none(self, prompt_id: str) -> Prompts | None
      async def find_prompts(self, **kwargs: Any) -> list[Prompts]
      async def create_prompt(self, **data: Any) -> Prompts
      async def load_builtin(self, builtin_id: str) -> PromptBuiltins
      async def load_builtin_or_none(self, builtin_id: str) -> PromptBuiltins | None
      async def find_builtins(self, **kwargs: Any) -> list[PromptBuiltins]
      async def create_builtin(self, **data: Any) -> PromptBuiltins
      async def update_prompt(self, prompt_id: str, **updates: Any) -> Prompts
      async def update_builtin(self, builtin_id: str, **updates: Any) -> PromptBuiltins
      async def update_by_id(self, item_id: str, **updates: Any) -> Prompts | PromptBuiltins
      async def load_by_id(self, item_id: str) -> Prompts | PromptBuiltins
      async def load_without_cache(self, item_id: str) -> Prompts | PromptBuiltins
      async def load_by_id_or_none(self, item_id: str) -> Prompts | PromptBuiltins | None


---
Filepath: matrx_ai/agents/cache.py  [python]

  class AgentCache:
      def get(cls, conversation_id: str) -> Agent | None
      def set(cls, conversation_id: str, agent: Agent) -> None
      def set_warm(cls, conversation_id: str, agent: Agent) -> None
      def remove(cls, conversation_id: str) -> None
      def exists(cls, conversation_id: str) -> bool
      def clear(cls) -> None


---
Filepath: matrx_ai/agents/__init__.py  [python]

  def __getattr__(name: str)


---
Filepath: matrx_ai/agents/types.py  [python]

  class AgentConfig:


---
Filepath: matrx_ai/agents/resolver.py  [python]

  class ConversationResolver:
      async def from_conversation_id(conversation_id: str, user_input: str | list[dict[str, Any]] | None = None, config_overrides: LLMParams | None = None) -> UnifiedConfig
      async def warm(conversation_id: str) -> bool
  class AgentConfigResolver:
      async def from_id_with_metadata(agent_id: str) -> dict[str, Any]
      async def from_id(agent_id: str, variables: dict[str, Any] | None = None, overrides: LLMParams | dict[str, Any] | None = None, source: str | None = None) -> UnifiedConfig
      async def from_id_with_mandates(agent_id: str, variables: dict[str, Any] | None = None, overrides: LLMParams | dict[str, Any] | None = None, source: str | None = None) -> tuple[UnifiedConfig, list[dict[str, Any]]]
      async def warm(agent_id: str, source: str | None = None) -> bool


---
Filepath: matrx_ai/agents/definition.py  [python]

  class AgentExecuteResult:
  class Agent:
      def __init__(self, config: UnifiedConfig, variable_defaults: dict[str, AgentVariable] | None = None, name: str | None = None, context_policies: list[dict[str, Any]] | None = None)
      def clone(self) -> Agent
      def clone_with_variables(self, **variables) -> Agent
      def clone_with_overrides(self, **overrides: Any) -> Agent
      def clone_with(self, variables: dict[str, Any] | None = None, config_overrides: LLMParams | dict[str, Any] | None = None) -> Agent
      def set_variable(self, name: str, value: Any) -> Agent
      def set_variables(self, **variables) -> Agent
      def apply_variables(self, force: bool = False) -> Agent
      def with_variables(self, **variables) -> Agent
      def apply_config_overrides(self, overrides: LLMParams | None = None, **kwargs: Any) -> Agent
      def from_dict(cls, config_dict: dict[str, Any], variable_defaults: dict[str, AgentVariable] | None = None, variables: dict[str, Any] | None = None, config_overrides: LLMParams | dict[str, Any] | None = None) -> Agent
      def _build_from_config(cls, agent_config: AgentConfig, variables: dict[str, Any] | None = None, config_overrides: LLMParams | dict[str, Any] | None = None) -> Agent
      async def from_id(cls, prompt_id: str, variables: dict[str, Any] | None = None, config_overrides: LLMParams | dict[str, Any] | None = None, source: str | None = None) -> Agent
      async def from_prompt(cls, prompt_id: str, variables: dict[str, Any] | None = None, config_overrides: LLMParams | dict[str, Any] | None = None) -> Agent
      async def from_builtin(cls, builtin_id: str, variables: dict[str, Any] | None = None, config_overrides: LLMParams | dict[str, Any] | None = None) -> Agent
      def set_user_input(self, user_input: str | list[dict[str, Any]]) -> Agent
      async def execute(self, user_input: str | list[dict[str, Any]] | None = None) -> AgentExecuteResult
      def _clean_up_response(self, response: CompletedRequest) -> AgentExecuteResult
      def to_dict(self) -> dict[str, Any]


---
Filepath: matrx_ai/agents/response_parser.py  [python]

  def _strip_thinking(text: str) -> str
  def _try_parse(candidate: str) -> dict | list | None
  def extract_json(text: str) -> dict | list | None
  def extract_model(text: str, model_class: type[T]) -> T | None


---
Filepath: matrx_ai/agents/services/conversation_labeler.py  [python]

  class _UserTitleCache:
      def __init__(self) -> None
      def get(self, user_id: str) -> list[dict[str, str]] | None
      def set(self, user_id: str, titles: list[dict[str, str]]) -> None
      def invalidate(self, user_id: str) -> None
  async def _fetch_recent_titles(user_id: str) -> list[dict[str, str]]
  def _format_recent_titles(titles: list[dict[str, str]]) -> str
  async def _run_labeling(conversation_id: str, user_id: str, messages: list[dict[str, Any]], agent_name: str | None = None, agent_description: str | None = None, user_variables: dict[str, Any] | None = None, user_prompt: str | None = None) -> None
  def schedule_conversation_labeling(conversation_id: str, user_id: str, messages: list[dict[str, Any]], agent_name: str | None = None, agent_description: str | None = None, user_variables: dict[str, Any] | None = None, user_prompt: str | None = None) -> asyncio.Task[None] | None


---
Filepath: matrx_ai/agents/services/batch_categorize.py  [python]

  async def _log_progress(completed: int, total: int, outcome: ItemOutcome) -> None
  async def run_batch(prompt_ids: list[str], *, concurrency: int = 10, dry_run: bool = False, rate_limit_delay: float = 0.0, warmup: WarmupStrategy = WarmupStrategy.STAGED) -> BatchResult
  def _parse_args() -> argparse.Namespace
  async def _main(args: argparse.Namespace) -> None
  async def _categorize_worker(pid: str)


---
Filepath: matrx_ai/agents/services/prompt_categorizer.py  [python]

  CATEGORIZER_BUILTIN_ID = 'e58dc3fc-7cf0-42e4-a557-f326c517a78b'
  class CategorizationResult(BaseModel):
      # fields: id: str, category: str | None = None, tags: list[str] = list(), description: str | None = None
  class CategorizationOutcome(BaseModel):
      # fields: prompt_id: str, success: bool, result: CategorizationResult | None = None, error: str | None = None, raw_output: str | None = None
  async def categorize_prompt(prompt_id: str, *, dry_run: bool = False) -> CategorizationOutcome
  async def _fetch_prompt_data(prompt_id: str) -> dict[str, Any]
  async def _apply_categorization(prompt_id: str, result: CategorizationResult, existing_data: dict[str, Any]) -> None
  async def get_uncategorized_prompt_ids(limit: int | None = None) -> list[str]
  async def get_all_prompt_ids(limit: int | None = None) -> list[str]
```
<!-- /AUTO:signatures -->

<!-- AUTO:callers -->
## Upstream Callers

> Auto-discovered by scanning all project files that import from this module.
> Set `ENTRY_POINTS` in `generate_readme.py` to pin specific functions.

| Caller | Calls |
|--------|-------|
| `matrx_ai/agent_runners/podcast_generator.py` | `Agent()` |
| `matrx_ai/agent_runners/research.py` | `Agent()` |
| `matrx_ai/tests/prompts/agent_comparison.py` | `Agent()` |
| `matrx_ai/tools/agent_tool.py` | `Agent()` |
| `matrx_ai/tools/implementations/_summarize_helper.py` | `Agent()` |
| `matrx_ai/tools/implementations/ctx.py` | `Agent()` |
| `matrx_ai/db/agx_manager.py` | `AgentConfig()` |
| `matrx_ai/agent_runners/podcast_generator.py` | `AgentExecuteResult()` |
| `matrx_ai/db/agx_manager.py` | `AgentVariable()` |
| `matrx_ai/orchestrator/executor.py` | `schedule_conversation_labeling()` |
<!-- /AUTO:callers -->

<!-- AUTO:dependencies -->
## Dependencies

**External packages:** fastapi, matrx_connect, matrx_utils, pydantic
**Internal modules:** matrx_ai._ext, matrx_ai.agent_runners, matrx_ai.config, matrx_ai.context, matrx_ai.db, matrx_ai.orchestrator, matrx_ai.utils
<!-- /AUTO:dependencies -->

<!-- AUTO:config -->
## Generation Config

> Auto-managed. Contains the exact parameters used to generate this README.
> Used by parent modules to auto-refresh this file when it is stale.
> Do not edit manually — changes will be overwritten on the next run.

```json
{
  "subdirectory": "matrx_ai/agents",
  "mode": "signatures",
  "scope": null,
  "project_noise": null,
  "include_call_graph": false,
  "entry_points": null,
  "call_graph_exclude": [
    "tests"
  ],
  "signatures_exclude": [
    "tests",
    "db",
    "local_data",
    "docs"
  ]
}
```
<!-- /AUTO:config -->
