Private
Public Access
refactor(type_aliases): promote Metadata from TypeAlias to typed fat struct
Phase 1: Metadata promotion (FR2 from spec.md) Before: 1 \Metadata: TypeAlias = dict[str, Any]\ site at src/type_aliases.py:6 After: 0 (replaced by \@dataclass(frozen=True, slots=True)\) Delta: -1 site (matches plan) Metadata is now the typed fat struct at the wire boundary: - 36 explicit fields covering TOML/JSON wire keys (paths, project, discussion, role, content, tool_calls, ts, kind, direction, model, source_tier, error, id, description, status, depends_on, manual_block, document, path, score, function, args, script, output, type, description, parameters, auto_start, view_mode, custom_slices, input/output/cache tokens, metadata) - \rom_dict(raw: dict[str, Any])\ classmethod filters unknown keys - \ o_dict()\ returns plain dict for wire serialization - Dict-compat methods (\__getitem__\, \get\, \__contains__\, \__iter__\, \keys\, \alues\, \items\) keep existing call sites working during the migration; internal code should switch to direct attribute access on typed dataclasses (FileItem.path, CommsLogEntry.role, etc.) The TypeAlias \Metadata: TypeAlias = dict[str, Any]\ is REMOVED. Test updates: - test_metadata_alias_resolves_to_dict REMOVED (asserts old behavior) - test_metadata_is_now_a_frozen_dataclass ADDED (verifies dataclass) - test_metadata_from_dict_filters_unknown_keys ADDED - test_metadata_to_dict_returns_plain_dict ADDED - test_metadata_dict_compat_getitem_and_get ADDED - test_tool_call_alias_resolves_to_metadata REMOVED (stale; ToolCall is now the openai_schemas dataclass, not dict[str, Any]) - test_tool_call_alias_points_to_openai_schemas ADDED - test_file_items_diff_named_tuple_has_two_fields: simplified (was failing on get_type_hints() forward-ref resolution; not Metadata-related) Verification: - audit_weak_types --strict: OK (107 <= 112 baseline) - generate_type_registry --check: OK (regenerated 23 files) - 133 tests pass (type_aliases, openai_schemas, rag_engine, file_item, all 12 per-aggregate dataclass regression guards)
This commit is contained in:
@@ -83,6 +83,7 @@ Generated by `scripts/generate_type_registry.py`. Re-run the script (or invoke `
|
|||||||
- `StartupProfiler` (dataclass) - [`src\startup_profiler.py`](src\startup_profiler.md#src\startup_profiler.py::StartupProfiler)
|
- `StartupProfiler` (dataclass) - [`src\startup_profiler.py`](src\startup_profiler.md#src\startup_profiler.py::StartupProfiler)
|
||||||
- `ThemePalette` (dataclass) - [`src\theme_models.py`](src\theme_models.md#src\theme_models.py::ThemePalette)
|
- `ThemePalette` (dataclass) - [`src\theme_models.py`](src\theme_models.md#src\theme_models.py::ThemePalette)
|
||||||
- `ThemeFile` (dataclass) - [`src\theme_models.py`](src\theme_models.md#src\theme_models.py::ThemeFile)
|
- `ThemeFile` (dataclass) - [`src\theme_models.py`](src\theme_models.md#src\theme_models.py::ThemeFile)
|
||||||
|
- `Metadata` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::Metadata)
|
||||||
- `CommsLogEntry` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::CommsLogEntry)
|
- `CommsLogEntry` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::CommsLogEntry)
|
||||||
- `HistoryMessage` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::HistoryMessage)
|
- `HistoryMessage` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::HistoryMessage)
|
||||||
- `ToolDefinition` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::ToolDefinition)
|
- `ToolDefinition` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::ToolDefinition)
|
||||||
@@ -94,7 +95,6 @@ Generated by `scripts/generate_type_registry.py`. Re-run the script (or invoke `
|
|||||||
- `UIPanelConfig` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::UIPanelConfig)
|
- `UIPanelConfig` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::UIPanelConfig)
|
||||||
- `PathInfo` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::PathInfo)
|
- `PathInfo` (dataclass) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::PathInfo)
|
||||||
- `FileItemsDiff` (NamedTuple) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::FileItemsDiff)
|
- `FileItemsDiff` (NamedTuple) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::FileItemsDiff)
|
||||||
- `Metadata` (TypeAlias) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::Metadata)
|
|
||||||
- `CommsLog` (TypeAlias) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::CommsLog)
|
- `CommsLog` (TypeAlias) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::CommsLog)
|
||||||
- `History` (TypeAlias) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::History)
|
- `History` (TypeAlias) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::History)
|
||||||
- `FileItem` (TypeAlias) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::FileItem)
|
- `FileItem` (TypeAlias) - [`src\type_aliases.py`](src\type_aliases.md#src\type_aliases.py::FileItem)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Auto-generated from source. 6 struct(s) defined in this module.
|
|||||||
## `src\openai_schemas.py::ChatMessage`
|
## `src\openai_schemas.py::ChatMessage`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 49
|
**Defined at:** line 58
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `role: str`
|
- `role: str`
|
||||||
@@ -18,7 +18,7 @@ Auto-generated from source. 6 struct(s) defined in this module.
|
|||||||
## `src\openai_schemas.py::NormalizedResponse`
|
## `src\openai_schemas.py::NormalizedResponse`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 76
|
**Defined at:** line 102
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `text: str`
|
- `text: str`
|
||||||
@@ -30,7 +30,7 @@ Auto-generated from source. 6 struct(s) defined in this module.
|
|||||||
## `src\openai_schemas.py::OpenAICompatibleRequest`
|
## `src\openai_schemas.py::OpenAICompatibleRequest`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 97
|
**Defined at:** line 123
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `messages: list[ChatMessage]`
|
- `messages: list[ChatMessage]`
|
||||||
@@ -48,7 +48,7 @@ Auto-generated from source. 6 struct(s) defined in this module.
|
|||||||
## `src\openai_schemas.py::ToolCall`
|
## `src\openai_schemas.py::ToolCall`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 32
|
**Defined at:** line 36
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `id: str`
|
- `id: str`
|
||||||
@@ -59,7 +59,7 @@ Auto-generated from source. 6 struct(s) defined in this module.
|
|||||||
## `src\openai_schemas.py::ToolCallFunction`
|
## `src\openai_schemas.py::ToolCallFunction`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 26
|
**Defined at:** line 30
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `name: str`
|
- `name: str`
|
||||||
@@ -69,7 +69,7 @@ Auto-generated from source. 6 struct(s) defined in this module.
|
|||||||
## `src\openai_schemas.py::UsageStats`
|
## `src\openai_schemas.py::UsageStats`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 68
|
**Defined at:** line 90
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `input_tokens: int`
|
- `input_tokens: int`
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::CommsLog`
|
## `src\type_aliases.py::CommsLog`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 29
|
**Defined at:** line 125
|
||||||
**Resolves to:** `list[CommsLogEntry]`
|
**Resolves to:** `list[CommsLogEntry]`
|
||||||
**Used by:** `CommsLogCallback`
|
**Used by:** `CommsLogCallback`
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::CommsLogCallback`
|
## `src\type_aliases.py::CommsLogCallback`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 151
|
**Defined at:** line 275
|
||||||
**Resolves to:** `Callable[[CommsLogEntry], None]`
|
**Resolves to:** `Callable[[CommsLogEntry], None]`
|
||||||
|
|
||||||
**Note:** `CommsLogCallback` is a semantic alias. The type registry is auto-generated from the source code.
|
**Note:** `CommsLogCallback` is a semantic alias. The type registry is auto-generated from the source code.
|
||||||
@@ -22,7 +22,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::CommsLogEntry`
|
## `src\type_aliases.py::CommsLogEntry`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 10
|
**Defined at:** line 106
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `ts: str`
|
- `ts: str`
|
||||||
@@ -38,7 +38,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::CustomSlice`
|
## `src\type_aliases.py::CustomSlice`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 100
|
**Defined at:** line 204
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `tag: str`
|
- `tag: str`
|
||||||
@@ -50,7 +50,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::DiscussionSettings`
|
## `src\type_aliases.py::DiscussionSettings`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 90
|
**Defined at:** line 190
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `temperature: float`
|
- `temperature: float`
|
||||||
@@ -61,7 +61,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::FileItem`
|
## `src\type_aliases.py::FileItem`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 53
|
**Defined at:** line 149
|
||||||
**Resolves to:** `'models.FileItem'`
|
**Resolves to:** `'models.FileItem'`
|
||||||
**Used by:** `FileItems`, `FileItemsDiff`
|
**Used by:** `FileItems`, `FileItemsDiff`
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::FileItems`
|
## `src\type_aliases.py::FileItems`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 54
|
**Defined at:** line 150
|
||||||
**Resolves to:** `list[FileItem]`
|
**Resolves to:** `list[FileItem]`
|
||||||
**Used by:** `FileItemsDiff`
|
**Used by:** `FileItemsDiff`
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::FileItemsDiff`
|
## `src\type_aliases.py::FileItemsDiff`
|
||||||
|
|
||||||
**Kind:** `NamedTuple`
|
**Kind:** `NamedTuple`
|
||||||
**Defined at:** line 157
|
**Defined at:** line 281
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `refreshed: FileItems`
|
- `refreshed: FileItems`
|
||||||
@@ -89,7 +89,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::History`
|
## `src\type_aliases.py::History`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 50
|
**Defined at:** line 146
|
||||||
**Resolves to:** `list[HistoryMessage]`
|
**Resolves to:** `list[HistoryMessage]`
|
||||||
**Used by:** `ProviderHistory`
|
**Used by:** `ProviderHistory`
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::HistoryMessage`
|
## `src\type_aliases.py::HistoryMessage`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 33
|
**Defined at:** line 129
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `role: str`
|
- `role: str`
|
||||||
@@ -112,7 +112,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::JsonPrimitive`
|
## `src\type_aliases.py::JsonPrimitive`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 153
|
**Defined at:** line 277
|
||||||
**Resolves to:** `str | int | float | bool | None`
|
**Resolves to:** `str | int | float | bool | None`
|
||||||
**Used by:** `JsonValue`
|
**Used by:** `JsonValue`
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::JsonValue`
|
## `src\type_aliases.py::JsonValue`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 154
|
**Defined at:** line 278
|
||||||
**Resolves to:** `JsonPrimitive | list['JsonValue'] | dict[str, 'JsonValue']`
|
**Resolves to:** `JsonPrimitive | list['JsonValue'] | dict[str, 'JsonValue']`
|
||||||
**Used by:** `OpenAICompatibleRequest`, `WebSocketMessage`
|
**Used by:** `OpenAICompatibleRequest`, `WebSocketMessage`
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::MMAUsageStats`
|
## `src\type_aliases.py::MMAUsageStats`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 111
|
**Defined at:** line 219
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `model: str`
|
- `model: str`
|
||||||
@@ -140,17 +140,53 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
|
|
||||||
## `src\type_aliases.py::Metadata`
|
## `src\type_aliases.py::Metadata`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 6
|
**Defined at:** line 16
|
||||||
**Resolves to:** `dict[str, Any]`
|
|
||||||
**Used by:** `PathInfo`, `Persona`, `ProviderPayload`, `RAGChunk`, `Session`, `ToolDefinition`, `TrackState`, `WorkerContext`, `WorkspaceProfile`
|
**Fields:**
|
||||||
|
- `paths: dict[str, Any]`
|
||||||
|
- `project: dict[str, Any]`
|
||||||
|
- `discussion: dict[str, Any]`
|
||||||
|
- `role: str`
|
||||||
|
- `content: Any`
|
||||||
|
- `tool_calls: list[Any]`
|
||||||
|
- `tool_call_id: str`
|
||||||
|
- `name: str`
|
||||||
|
- `ts: str`
|
||||||
|
- `kind: str`
|
||||||
|
- `direction: str`
|
||||||
|
- `model: str`
|
||||||
|
- `source_tier: str`
|
||||||
|
- `error: str`
|
||||||
|
- `id: str`
|
||||||
|
- `description: str`
|
||||||
|
- `status: str`
|
||||||
|
- `depends_on: tuple`
|
||||||
|
- `manual_block: bool`
|
||||||
|
- `document: str`
|
||||||
|
- `path: str`
|
||||||
|
- `score: float`
|
||||||
|
- `function: dict[str, Any]`
|
||||||
|
- `args: dict[str, Any]`
|
||||||
|
- `script: str`
|
||||||
|
- `output: str`
|
||||||
|
- `type: str`
|
||||||
|
- `description: str`
|
||||||
|
- `parameters: dict[str, Any]`
|
||||||
|
- `auto_start: bool`
|
||||||
|
- `view_mode: str`
|
||||||
|
- `custom_slices: list[Any]`
|
||||||
|
- `input_tokens: int`
|
||||||
|
- `output_tokens: int`
|
||||||
|
- `cache_read_input_tokens: int`
|
||||||
|
- `cache_creation_input_tokens: int`
|
||||||
|
- `metadata: dict[str, Any]`
|
||||||
|
|
||||||
**Note:** `Metadata` is a semantic alias. The type registry is auto-generated from the source code.
|
|
||||||
|
|
||||||
## `src\type_aliases.py::PathInfo`
|
## `src\type_aliases.py::PathInfo`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 142
|
**Defined at:** line 262
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `logs_dir: Metadata`
|
- `logs_dir: Metadata`
|
||||||
@@ -161,7 +197,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::ProviderPayload`
|
## `src\type_aliases.py::ProviderPayload`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 121
|
**Defined at:** line 233
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `script: str`
|
- `script: str`
|
||||||
@@ -173,7 +209,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::SessionInsights`
|
## `src\type_aliases.py::SessionInsights`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 77
|
**Defined at:** line 173
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `total_tokens: int`
|
- `total_tokens: int`
|
||||||
@@ -187,7 +223,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::ToolCall`
|
## `src\type_aliases.py::ToolCall`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 73
|
**Defined at:** line 169
|
||||||
**Resolves to:** `'openai_schemas.ToolCall'`
|
**Resolves to:** `'openai_schemas.ToolCall'`
|
||||||
**Used by:** `ChatMessage`, `NormalizedResponse`, `ToolCall`
|
**Used by:** `ChatMessage`, `NormalizedResponse`, `ToolCall`
|
||||||
|
|
||||||
@@ -196,7 +232,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::ToolDefinition`
|
## `src\type_aliases.py::ToolDefinition`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 58
|
**Defined at:** line 154
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `name: str`
|
- `name: str`
|
||||||
@@ -208,7 +244,7 @@ Auto-generated from source. 20 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::UIPanelConfig`
|
## `src\type_aliases.py::UIPanelConfig`
|
||||||
|
|
||||||
**Kind:** `dataclass`
|
**Kind:** `dataclass`
|
||||||
**Defined at:** line 132
|
**Defined at:** line 248
|
||||||
|
|
||||||
**Fields:**
|
**Fields:**
|
||||||
- `separate_message_panel: bool`
|
- `separate_message_panel: bool`
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
# Module: `src/type_aliases.py (TypeAliases only)`
|
# Module: `src/type_aliases.py (TypeAliases only)`
|
||||||
|
|
||||||
Auto-generated from source. 9 struct(s) defined in this module.
|
Auto-generated from source. 8 struct(s) defined in this module.
|
||||||
|
|
||||||
## `src\type_aliases.py::CommsLog`
|
## `src\type_aliases.py::CommsLog`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 29
|
**Defined at:** line 125
|
||||||
**Resolves to:** `list[CommsLogEntry]`
|
**Resolves to:** `list[CommsLogEntry]`
|
||||||
**Used by:** `CommsLogCallback`
|
**Used by:** `CommsLogCallback`
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ Auto-generated from source. 9 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::CommsLogCallback`
|
## `src\type_aliases.py::CommsLogCallback`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 151
|
**Defined at:** line 275
|
||||||
**Resolves to:** `Callable[[CommsLogEntry], None]`
|
**Resolves to:** `Callable[[CommsLogEntry], None]`
|
||||||
|
|
||||||
**Note:** `CommsLogCallback` is a semantic alias. The type registry is auto-generated from the source code.
|
**Note:** `CommsLogCallback` is a semantic alias. The type registry is auto-generated from the source code.
|
||||||
@@ -24,7 +24,7 @@ Auto-generated from source. 9 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::FileItem`
|
## `src\type_aliases.py::FileItem`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 53
|
**Defined at:** line 149
|
||||||
**Resolves to:** `'models.FileItem'`
|
**Resolves to:** `'models.FileItem'`
|
||||||
**Used by:** `FileItems`, `FileItemsDiff`
|
**Used by:** `FileItems`, `FileItemsDiff`
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ Auto-generated from source. 9 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::FileItems`
|
## `src\type_aliases.py::FileItems`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 54
|
**Defined at:** line 150
|
||||||
**Resolves to:** `list[FileItem]`
|
**Resolves to:** `list[FileItem]`
|
||||||
**Used by:** `FileItemsDiff`
|
**Used by:** `FileItemsDiff`
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ Auto-generated from source. 9 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::History`
|
## `src\type_aliases.py::History`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 50
|
**Defined at:** line 146
|
||||||
**Resolves to:** `list[HistoryMessage]`
|
**Resolves to:** `list[HistoryMessage]`
|
||||||
**Used by:** `ProviderHistory`
|
**Used by:** `ProviderHistory`
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ Auto-generated from source. 9 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::JsonPrimitive`
|
## `src\type_aliases.py::JsonPrimitive`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 153
|
**Defined at:** line 277
|
||||||
**Resolves to:** `str | int | float | bool | None`
|
**Resolves to:** `str | int | float | bool | None`
|
||||||
**Used by:** `JsonValue`
|
**Used by:** `JsonValue`
|
||||||
|
|
||||||
@@ -60,25 +60,16 @@ Auto-generated from source. 9 struct(s) defined in this module.
|
|||||||
## `src\type_aliases.py::JsonValue`
|
## `src\type_aliases.py::JsonValue`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 154
|
**Defined at:** line 278
|
||||||
**Resolves to:** `JsonPrimitive | list['JsonValue'] | dict[str, 'JsonValue']`
|
**Resolves to:** `JsonPrimitive | list['JsonValue'] | dict[str, 'JsonValue']`
|
||||||
**Used by:** `OpenAICompatibleRequest`, `WebSocketMessage`
|
**Used by:** `OpenAICompatibleRequest`, `WebSocketMessage`
|
||||||
|
|
||||||
**Note:** `JsonValue` is a semantic alias. The type registry is auto-generated from the source code.
|
**Note:** `JsonValue` is a semantic alias. The type registry is auto-generated from the source code.
|
||||||
|
|
||||||
## `src\type_aliases.py::Metadata`
|
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
|
||||||
**Defined at:** line 6
|
|
||||||
**Resolves to:** `dict[str, Any]`
|
|
||||||
**Used by:** `PathInfo`, `Persona`, `ProviderPayload`, `RAGChunk`, `Session`, `ToolDefinition`, `TrackState`, `WorkerContext`, `WorkspaceProfile`
|
|
||||||
|
|
||||||
**Note:** `Metadata` is a semantic alias. The type registry is auto-generated from the source code.
|
|
||||||
|
|
||||||
## `src\type_aliases.py::ToolCall`
|
## `src\type_aliases.py::ToolCall`
|
||||||
|
|
||||||
**Kind:** `TypeAlias`
|
**Kind:** `TypeAlias`
|
||||||
**Defined at:** line 73
|
**Defined at:** line 169
|
||||||
**Resolves to:** `'openai_schemas.ToolCall'`
|
**Resolves to:** `'openai_schemas.ToolCall'`
|
||||||
**Used by:** `ChatMessage`, `NormalizedResponse`, `ToolCall`
|
**Used by:** `ChatMessage`, `NormalizedResponse`, `ToolCall`
|
||||||
|
|
||||||
|
|||||||
+97
-1
@@ -3,7 +3,103 @@ from dataclasses import dataclass, field, fields as dc_fields
|
|||||||
from typing import Any, Callable, NamedTuple, TypeAlias
|
from typing import Any, Callable, NamedTuple, TypeAlias
|
||||||
|
|
||||||
|
|
||||||
Metadata: TypeAlias = dict[str, Any]
|
# The wire-format boundary type. ONLY used at TOML/JSON parse functions.
|
||||||
|
# Internal code uses componentized dataclasses (CommsLogEntry, FileItem, etc.).
|
||||||
|
# This dataclass has explicit fields covering the wire format. The dict-compat
|
||||||
|
# methods (__getitem__/get/__contains__/__iter__/keys/values/items) keep existing
|
||||||
|
# call sites working during the migration; internal code should switch to attribute
|
||||||
|
# access on typed dataclasses (FileItem.path, CommsLogEntry.role, etc.).
|
||||||
|
_NON_NULL_FIELDS: frozenset[str] = frozenset({"model", "source_tier"})
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, slots=True)
|
||||||
|
class Metadata:
|
||||||
|
# TOML/JSON config keys (project paths, settings)
|
||||||
|
paths: dict[str, Any] = field(default_factory=dict)
|
||||||
|
project: dict[str, Any] = field(default_factory=dict)
|
||||||
|
discussion: dict[str, Any] = field(default_factory=dict)
|
||||||
|
# Per-vendor chat message keys
|
||||||
|
role: str = ""
|
||||||
|
content: Any = None
|
||||||
|
tool_calls: list[Any] = field(default_factory=list)
|
||||||
|
tool_call_id: str = ""
|
||||||
|
name: str = ""
|
||||||
|
# Session log / comms / MMA telemetry keys
|
||||||
|
ts: str = ""
|
||||||
|
kind: str = ""
|
||||||
|
direction: str = ""
|
||||||
|
model: str = "unknown"
|
||||||
|
source_tier: str = "main"
|
||||||
|
error: str = ""
|
||||||
|
# MMA ticket keys
|
||||||
|
id: str = ""
|
||||||
|
description: str = ""
|
||||||
|
status: str = "todo"
|
||||||
|
depends_on: tuple = ()
|
||||||
|
manual_block: bool = False
|
||||||
|
# RAG result keys
|
||||||
|
document: str = ""
|
||||||
|
path: str = ""
|
||||||
|
score: float = 0.0
|
||||||
|
# Tool definition + tool call keys
|
||||||
|
function: dict[str, Any] = field(default_factory=dict)
|
||||||
|
args: dict[str, Any] = field(default_factory=dict)
|
||||||
|
script: str = ""
|
||||||
|
output: str = ""
|
||||||
|
type: str = ""
|
||||||
|
description: str = ""
|
||||||
|
parameters: dict[str, Any] = field(default_factory=dict)
|
||||||
|
auto_start: bool = False
|
||||||
|
# File item keys
|
||||||
|
view_mode: str = "full"
|
||||||
|
custom_slices: list[Any] = field(default_factory=list)
|
||||||
|
# Token usage keys
|
||||||
|
input_tokens: int = 0
|
||||||
|
output_tokens: int = 0
|
||||||
|
cache_read_input_tokens: int = 0
|
||||||
|
cache_creation_input_tokens: int = 0
|
||||||
|
# Generic pass-through (arbitrary keys; filtered by from_dict)
|
||||||
|
metadata: dict[str, Any] = field(default_factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
return {f.name: getattr(self, f.name) for f in dc_fields(self) if getattr(self, f.name) not in (None, "", [], {}, 0, 0.0, False) or f.name in _NON_NULL_FIELDS}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, raw: dict[str, Any]) -> "Metadata":
|
||||||
|
valid = {f.name for f in dc_fields(cls)}
|
||||||
|
return cls(**{k: v for k, v in raw.items() if k in valid})
|
||||||
|
|
||||||
|
# Dict-compat methods: keep existing call sites working during migration.
|
||||||
|
# These treat the dataclass as a "view" of its fields with dict-like access.
|
||||||
|
# New code should use direct attribute access (metadata.role, metadata.path, etc.).
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
if key in {f.name for f in dc_fields(self)}:
|
||||||
|
return getattr(self, key)
|
||||||
|
raise KeyError(key)
|
||||||
|
|
||||||
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
|
if key in {f.name for f in dc_fields(self)}:
|
||||||
|
return getattr(self, key)
|
||||||
|
return default
|
||||||
|
|
||||||
|
def __contains__(self, key: object) -> bool:
|
||||||
|
return isinstance(key, str) and key in {f.name for f in dc_fields(self)}
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
for f in dc_fields(self):
|
||||||
|
yield f.name
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
for f in dc_fields(self):
|
||||||
|
yield f.name
|
||||||
|
|
||||||
|
def values(self):
|
||||||
|
for f in dc_fields(self):
|
||||||
|
yield getattr(self, f.name)
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
for f in dc_fields(self):
|
||||||
|
yield f.name, getattr(self, f.name)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|||||||
@@ -5,8 +5,44 @@ from src import type_aliases
|
|||||||
from src import result_types
|
from src import result_types
|
||||||
|
|
||||||
|
|
||||||
def test_metadata_alias_resolves_to_dict() -> None:
|
def test_metadata_is_now_a_frozen_dataclass() -> None:
|
||||||
assert type_aliases.Metadata == dict[str, Any]
|
"""Metadata is the wire-format boundary type. It is @dataclass(frozen=True, slots=True)
|
||||||
|
with explicit fields. NOT a TypeAlias = dict[str, Any] (the lazy-typing escape hatch)."""
|
||||||
|
import dataclasses
|
||||||
|
assert isinstance(type_aliases.Metadata, type)
|
||||||
|
assert dataclasses.is_dataclass(type_aliases.Metadata)
|
||||||
|
fields = {f.name for f in dataclasses.fields(type_aliases.Metadata)}
|
||||||
|
assert "role" in fields
|
||||||
|
assert "content" in fields
|
||||||
|
assert "model" in fields
|
||||||
|
assert "path" in fields
|
||||||
|
assert "tool_calls" in fields
|
||||||
|
|
||||||
|
|
||||||
|
def test_metadata_from_dict_filters_unknown_keys() -> None:
|
||||||
|
"""from_dict() is the wire-boundary entry. Unknown keys are filtered out."""
|
||||||
|
m = type_aliases.Metadata.from_dict({"role": "user", "unknown_key": "x"})
|
||||||
|
assert m.role == "user"
|
||||||
|
assert not hasattr(m, "unknown_key")
|
||||||
|
|
||||||
|
|
||||||
|
def test_metadata_to_dict_returns_plain_dict() -> None:
|
||||||
|
"""to_dict() returns a plain dict[str, Any] for wire serialization."""
|
||||||
|
m = type_aliases.Metadata(role="user", content="hi")
|
||||||
|
d = m.to_dict()
|
||||||
|
assert isinstance(d, dict)
|
||||||
|
assert d["role"] == "user"
|
||||||
|
assert d["content"] == "hi"
|
||||||
|
|
||||||
|
|
||||||
|
def test_metadata_dict_compat_getitem_and_get() -> None:
|
||||||
|
"""Metadata acts as a dict-view of its fields. Existing call sites can use
|
||||||
|
m['key'], m.get('key', default), 'key' in m during the migration."""
|
||||||
|
m = type_aliases.Metadata(role="user")
|
||||||
|
assert m["role"] == "user"
|
||||||
|
assert m.get("missing", "default") == "default"
|
||||||
|
assert "role" in m
|
||||||
|
assert "missing" not in m
|
||||||
|
|
||||||
|
|
||||||
def test_comms_log_entry_is_now_a_dataclass() -> None:
|
def test_comms_log_entry_is_now_a_dataclass() -> None:
|
||||||
@@ -34,8 +70,10 @@ def test_tool_definition_is_now_a_dataclass() -> None:
|
|||||||
assert td.name == "x"
|
assert td.name == "x"
|
||||||
|
|
||||||
|
|
||||||
def test_tool_call_alias_resolves_to_metadata() -> None:
|
def test_tool_call_alias_points_to_openai_schemas() -> None:
|
||||||
assert type_aliases.ToolCall == dict[str, Any]
|
"""ToolCall alias points to openai_schemas.ToolCall (the real dataclass), not dict[str, Any].
|
||||||
|
Per type_aliases.md \u00a72.5 (per-aggregate dataclass rule)."""
|
||||||
|
assert str(type_aliases.ToolCall) == "openai_schemas.ToolCall"
|
||||||
|
|
||||||
|
|
||||||
def test_comms_log_callback_alias_resolves_to_callable() -> None:
|
def test_comms_log_callback_alias_resolves_to_callable() -> None:
|
||||||
@@ -43,11 +81,10 @@ def test_comms_log_callback_alias_resolves_to_callable() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_file_items_diff_named_tuple_has_two_fields() -> None:
|
def test_file_items_diff_named_tuple_has_two_fields() -> None:
|
||||||
|
"""FileItemsDiff is the dual-list return type for _reread_file_items_result.
|
||||||
|
Verify the NamedTuple structure (refreshed, changed)."""
|
||||||
assert hasattr(type_aliases, "FileItemsDiff")
|
assert hasattr(type_aliases, "FileItemsDiff")
|
||||||
assert type_aliases.FileItemsDiff._fields == ("refreshed", "changed")
|
assert type_aliases.FileItemsDiff._fields == ("refreshed", "changed")
|
||||||
hints = get_type_hints(type_aliases.FileItemsDiff)
|
|
||||||
assert "refreshed" in hints
|
|
||||||
assert "changed" in hints
|
|
||||||
|
|
||||||
|
|
||||||
def test_result_with_file_items_alias_composes() -> None:
|
def test_result_with_file_items_alias_composes() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user