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.
8.9 KiB
src/models.py — Legacy Re-Export Shim
Top | Architecture | MMA | App Controller
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_20260627Phase 5 (reduce to Pydantic proxies)post_module_taxonomy_de_cruft_20260627Phases 2-4 (de-cruft removals)
Remaining content:
- The legacy
Metadata = TrackMetadataalias — tests that importfrom src.models import Metadataexpecting the dataclass still resolve to the same object. TheMetadataTYPE ALIAS (fromsrc.type_aliases) is the boundary wire type; legacy consumers wanting the dataclass should migrate tofrom src.mma import TrackMetadata. - The
PROVIDERSlazy__getattr__(loads fromsrc.ai_clienton first access; required to break a startup-speedup circular import).
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) |
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 for FileItem, 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_capabilitiesfrom 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 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.
Adding a new model
- 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 insrc/mcp_tool_specs.py). Do NOT add it tosrc/models.py— that file is a shim only. - If the model is a typed boundary/aggregate shape, add it to
src/type_aliases.pyinstead. - Add
to_dict()/from_dict()if the model is persisted. - Add a docstring with
[C: ...](callers) and[M: ...](mutators) SDM tags. - Add tests in the relevant
tests/test_<system>.py. - If the model warrants a GUI surface, add a rendering helper in
src/gui_2.py(module-levelrender_<thing>(app: App)). - Update the relevant
docs/guide_<system>.mdto 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).
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 — How models flow through the system
- guide_app_controller.md —
AppStateand controller-owned models - guide_mma.md —
Ticket,Track,WorkerContext,TrackMetadatainsrc/mma.py - guide_ai_client.md —
VendorCapabilities,PROVIDERS,_VENDOR_REGISTRYinsrc/ai_client.py - guide_personas.md —
Personamodel in detail - guide_workspace_profiles.md —
WorkspaceProfilemodel in detail - guide_rag.md —
RAGConfig,RAGChunk,RAGResultmodels - guide_context_aggregation.md — How the
FileItemandContextPresetschemas flow through theaggregate.pypipeline - guide_discussions.md — The entry dict shape consumed by
parse_history_entries src/type_aliases.py— The typed boundary + per-aggregate dataclassessrc/mcp_tool_specs.py— The typedToolSpecregistry (45 tools)src/result_types.py—Result[T],ErrorInfo,ErrorKindfor data-oriented error handling- conductor/tracks/nagent_review_20260608/report.md §6 — Deep-dive on the
FileItemschema as Manual Slop's strongest curation dimension