Private
Public Access
0
0
Files
manual_slop/docs/guide_models.md
T
ed f463edf93d docs(guide_models): rewrite for src/models.py shim reality
The guide described models.py as a 132KB centralized registry with
Provider/ModelInfo enums, Ticket/Track classes, AGENT_TOOL_NAMES, and
parse_plan_md. None of that is in models.py anymore — it's a ~1.5KB
re-export shim (Metadata=TrackMetadata alias + PROVIDERS lazy
__getattr__). Dataclasses moved to per-system files (mma.py,
project_files.py, type_aliases.py, mcp_tool_specs.py, result_types.py).
VendorCapabilities moved from the deleted vendor_capabilities.py into
ai_client.py #region. Rewrote the guide to reflect the current
where-each-model-lives table.
2026-07-02 18:53:56 -04:00

135 lines
8.9 KiB
Markdown

# `src/models.py` — Legacy Re-Export Shim
[Top](../Readme.md) | [Architecture](guide_architecture.md) | [MMA](guide_mma.md) | [App Controller](guide_app_controller.md)
---
## Overview
`src/models.py` is now a **~1.5KB legacy re-export shim**. It is NOT a data model registry anymore.
The dataclass definitions, `DEFAULT_TOOL_CATEGORIES`, the `__getattr__` shim, and the Pydantic proxies were moved out per:
- `module_taxonomy_refactor_20260627` Phase 5 (reduce to Pydantic proxies)
- `post_module_taxonomy_de_cruft_20260627` Phases 2-4 (de-cruft removals)
**Remaining content:**
- The legacy `Metadata = TrackMetadata` alias — tests that import `from src.models import Metadata` expecting the dataclass still resolve to the same object. The `Metadata` TYPE ALIAS (from `src.type_aliases`) is the boundary wire type; legacy consumers wanting the dataclass should migrate to `from src.mma import TrackMetadata`.
- The `PROVIDERS` lazy `__getattr__` (loads from `src.ai_client` on first access; required to break a startup-speedup circular import).
```python
from src.mma import TrackMetadata
Metadata = TrackMetadata # legacy class name re-export
def __getattr__(name: str) -> Any:
if name == "PROVIDERS":
from src import ai_client
return ai_client.PROVIDERS
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
```
---
## Where the data models actually live now
The old "one registry to look at" goal is now achieved by **per-system files**. Each subsystem owns its own data models in its own file:
| Model(s) | Current location | Notes |
|---|---|---|
| `TrackMetadata` (formerly `Metadata` dataclass) | `src/mma.py` | The track/ticket data layer |
| `Ticket`, `Track`, `WorkerContext` | `src/mma.py` | MMA domain models |
| `VendorCapabilities`, `VendorMetric` | `src/ai_client.py` (`#region: Vendor Capabilities`) | Moved from the deleted `src/vendor_capabilities.py` |
| `FileItem`, `FileItems` | `src/project_files.py` | Per-file curation memory |
| `Result[T]`, `ErrorInfo`, `ErrorKind`, `NilPath` | `src/result_types.py` | Data-oriented error handling |
| `Metadata`, `CommsLogEntry`, `HistoryMessage`, `ToolDefinition`, `ToolCall`, `CommsLogCallback`, `SessionInsights`, `DiscussionSettings`, `CustomSlice`, `MMAUsageStats`, `ProviderPayload`, `UIPanelConfig`, `PathInfo`, `JsonPrimitive`, `JsonValue`, `FileItemsDiff` | `src/type_aliases.py` | The typed boundary + per-aggregate dataclasses (see [guide_context_aggregation.md](guide_context_aggregation.md)) |
| `ToolSpec`, `ToolParameter` | `src/mcp_tool_specs.py` | Typed tool-spec registry (replaces the legacy `MCP_TOOL_SPECS: list[dict[str, Any]]`) |
| `MCPServerConfig`, `MCPConfiguration`, `VectorStoreConfig`, `RAGConfig` | `src/mcp_client.py` | MCP subsystem data layer |
| `WorkspaceProfile` | `src/workspace_manager.py` | Layout profiles |
| `Persona`, `Preset`, `ContextPreset`, `ToolPreset`, `Tool`, `BiasProfile` | `src/personas.py`, `src/presets.py`, `src/context_presets.py`, `src/tool_presets.py` | Manager-owned config models |
| `TicketStatus`, `TicketPriority`, `TrackCheckpoint` | `src/mma.py` | MMA enums |
**Rule of thumb:** if you need to know what fields a type has, read the per-system guide (e.g., [guide_context_aggregation.md](guide_context_aggregation.md) for `FileItem`, [guide_mma.md](guide_mma.md) for `Ticket`/`Track`), or read the file directly with `py_get_skeleton`.
---
## Where the constants live now
| Constant | Current location | Notes |
|---|---|---|
| `PROVIDERS` | `src/ai_client.py` (re-exported by `src/models.py` via lazy `__getattr__`) | `List[str]` of 8 providers: `gemini`, `anthropic`, `gemini_cli`, `deepseek`, `minimax`, `qwen`, `grok`, `llama` |
| `DEFAULT_TOOL_CATEGORIES` | `src/ai_client.py` | The canonical grouping of the MCP tool registry for the UI's category filter |
| Tool names (formerly `AGENT_TOOL_NAMES`) | `src/mcp_tool_specs.py:_REGISTRY` + `mcp_tool_specs.tool_names()` | 45 tools. Re-exported as `mcp_client.TOOL_NAMES` for backward compat |
| `DEFAULT_TIER_PERSONAS` | `src/mma_prompts.py` | MMA tier → default persona mapping |
| `_VENDOR_REGISTRY` | `src/ai_client.py` | The `VendorCapabilities` registry, populated via `register()` at import time |
**Audit:** `scripts/audit_providers_source_of_truth.py` fails if `PROVIDERS` is declared as a literal in `src/models.py`.
---
## Why the shim exists at all
Backward compatibility. The refactor tracks moved the dataclasses out, but a long tail of tests and consumers still import `from src.models import Metadata` expecting the dataclass. The shim re-exports `TrackMetadata` under the legacy name so those imports keep resolving to the same object.
New code should import directly from the owning file:
- `from src.mma import TrackMetadata` (the dataclass)
- `from src.type_aliases import Metadata` (the boundary wire type — different thing)
- `from src.ai_client import PROVIDERS, VendorCapabilities, get_capabilities`
- `from src.mcp_tool_specs import tool_names, get_tool_spec`
---
## `parse_plan_md`
The plan-parsing utility was moved to `src/mma.py` alongside the `Track`/`Ticket` models it constructs. See [guide_mma.md](guide_mma.md) for the current signature and usage.
---
## `AppState`
`AppState` (the controller's runtime state aggregate) lives in `src/app_controller.py` as before. It was never in `src/models.py`; the old version of this guide was correct to note that. See [guide_app_controller.md](guide_app_controller.md).
---
## Adding a new model
1. Add the dataclass to the **owning system's file** (e.g., a new MMA model goes in `src/mma.py`; a new tool-spec shape goes in `src/mcp_tool_specs.py`). Do NOT add it to `src/models.py` — that file is a shim only.
2. If the model is a typed boundary/aggregate shape, add it to `src/type_aliases.py` instead.
3. Add `to_dict()` / `from_dict()` if the model is persisted.
4. Add a docstring with `[C: ...]` (callers) and `[M: ...]` (mutators) SDM tags.
5. Add tests in the relevant `tests/test_<system>.py`.
6. If the model warrants a GUI surface, add a rendering helper in `src/gui_2.py` (module-level `render_<thing>(app: App)`).
7. Update the relevant `docs/guide_<system>.md` to document the new model.
**Do NOT** add new `src/<thing>.py` files without explicit user authorization — see `AGENTS.md` "File Size and Naming Convention" HARD RULE.
---
## V2 Capability Matrix
`VendorCapabilities` is defined in `src/ai_client.py` under `#region: Vendor Capabilities (moved from src/vendor_capabilities.py)`. The dataclass has 12 v2 fields on top of the v1 fields:
**V1 fields:** `vision`, `tool_calling`, `caching`, `streaming`, `model_discovery`, `context_window`, `cost_tracking`
**V2 fields:** `local`, `reasoning`, `structured_output`, `code_execution`, `web_search`, `x_search`, `file_search`, `mcp_support`, `audio`, `video`, `grounding`, `computer_use`
All v2 fields default to `False`. The dataclass is `frozen=True`; per-vendor entries use `register()` at module-import time in `src/ai_client.py`. The GUI reads the matrix via `get_capabilities(vendor, model)` and adapts UI elements accordingly (see [guide_ai_client.md §V2 Capability Matrix](guide_ai_client.md#v2-capability-matrix-phase-4)).
**Adding a new v2 field:** the HARD RULE is that all AI-client code lives in `src/ai_client.py`. New v2 fields go in the `VendorCapabilities` dataclass in `src/ai_client.py` (the region that replaced the deleted `src/vendor_capabilities.py`) — NOT in a new `src/<v2_thing>.py` file. Update the dataclass, populate per-model in `_VENDOR_REGISTRY` via `register()`, add a small rendering helper in `src/gui_2.py` if the field warrants a UI badge.
---
## See Also
- **[guide_architecture.md](guide_architecture.md)** — How models flow through the system
- **[guide_app_controller.md](guide_app_controller.md)** — `AppState` and controller-owned models
- **[guide_mma.md](guide_mma.md)** — `Ticket`, `Track`, `WorkerContext`, `TrackMetadata` in `src/mma.py`
- **[guide_ai_client.md](guide_ai_client.md)** — `VendorCapabilities`, `PROVIDERS`, `_VENDOR_REGISTRY` in `src/ai_client.py`
- **[guide_personas.md](guide_personas.md)** — `Persona` model in detail
- **[guide_workspace_profiles.md](guide_workspace_profiles.md)** — `WorkspaceProfile` model in detail
- **[guide_rag.md](guide_rag.md)** — `RAGConfig`, `RAGChunk`, `RAGResult` models
- **[guide_context_aggregation.md](guide_context_aggregation.md)** — How the `FileItem` and `ContextPreset` schemas flow through the `aggregate.py` pipeline
- **[guide_discussions.md](guide_discussions.md)** — The entry dict shape consumed by `parse_history_entries`
- **`src/type_aliases.py`** — The typed boundary + per-aggregate dataclasses
- **`src/mcp_tool_specs.py`** — The typed `ToolSpec` registry (45 tools)
- **`src/result_types.py`** — `Result[T]`, `ErrorInfo`, `ErrorKind` for data-oriented error handling
- **[conductor/tracks/nagent_review_20260608/report.md §6](../conductor/tracks/nagent_review_20260608/report.md)** — Deep-dive on the `FileItem` schema as Manual Slop's strongest curation dimension