refactor(project_manager,aggregate,api_hook_client): replace weak type sites with aliases
This commit is contained in:
+27
-14
@@ -17,6 +17,19 @@ from typing import Any, Optional, TYPE_CHECKING, Union
|
||||
|
||||
from src import paths
|
||||
|
||||
from src.type_aliases import (
|
||||
CommsLog,
|
||||
CommsLogCallback,
|
||||
CommsLogEntry,
|
||||
FileItem,
|
||||
FileItems,
|
||||
History,
|
||||
HistoryMessage,
|
||||
Metadata,
|
||||
ToolCall,
|
||||
ToolDefinition,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.models import TrackState
|
||||
|
||||
@@ -33,7 +46,7 @@ def parse_ts(s: str) -> Optional[datetime.datetime]:
|
||||
return None
|
||||
# ── entry serialisation ──────────────────────────────────────────────────────
|
||||
|
||||
def entry_to_str(entry: dict[str, Any]) -> str:
|
||||
def entry_to_str(entry: Metadata) -> str:
|
||||
"""
|
||||
Serialise a disc entry dict -> stored string.
|
||||
[C: tests/test_thinking_persistence.py:test_entry_to_str_with_thinking]
|
||||
@@ -53,13 +66,13 @@ def entry_to_str(entry: dict[str, Any]) -> str:
|
||||
return f"@{ts}\n{role}:\n{content}"
|
||||
return f"{role}:\n{content}"
|
||||
|
||||
def format_discussion(entries: list[dict[str, Any]]) -> str:
|
||||
def format_discussion(entries: list[Metadata]) -> str:
|
||||
"""
|
||||
Convert a list of discussion entry dicts into a single formatted string.
|
||||
"""
|
||||
return "\n\n".join([entry_to_str(e) for e in entries])
|
||||
|
||||
def str_to_entry(raw: str, roles: list[str]) -> dict[str, Any]:
|
||||
def str_to_entry(raw: str, roles: list[str]) -> Metadata:
|
||||
"""
|
||||
Parse a stored string back to a disc entry dict.
|
||||
[C: tests/test_thinking_persistence.py:test_str_to_entry_with_thinking]
|
||||
@@ -101,13 +114,13 @@ def get_git_commit(git_dir: str) -> str:
|
||||
|
||||
# ── default structures ───────────────────────────────────────────────────────
|
||||
|
||||
def default_discussion() -> dict[str, Any]:
|
||||
def default_discussion() -> Metadata:
|
||||
"""
|
||||
[C: tests/test_discussion_takes.py:TestDiscussionTakes.test_promote_take_renames_discussion]
|
||||
"""
|
||||
return {"git_commit": "", "last_updated": now_ts(), "history": []}
|
||||
|
||||
def default_project(name: str = "unnamed") -> dict[str, Any]:
|
||||
def default_project(name: str = "unnamed") -> Metadata:
|
||||
"""
|
||||
[C: tests/test_deepseek_infra.py:test_default_project_includes_reasoning_role, tests/test_discussion_takes.py:TestDiscussionTakes.setUp, tests/test_history_management.py:test_history_persistence_across_turns, tests/test_history_management.py:test_save_separation, tests/test_project_manager_modes.py:test_default_project_execution_mode, tests/test_project_manager_modes.py:test_load_save_execution_mode, tests/test_project_serialization.py:TestProjectSerialization.test_default_roles_include_context, tests/test_project_serialization.py:TestProjectSerialization.test_fileitem_roundtrip]
|
||||
"""
|
||||
@@ -170,7 +183,7 @@ def get_history_path(project_path: Union[str, Path]) -> Path:
|
||||
p = Path(project_path)
|
||||
return p.parent / f"{p.stem}_history.toml"
|
||||
|
||||
def load_project(path: Union[str, Path]) -> dict[str, Any]:
|
||||
def load_project(path: Union[str, Path]) -> Metadata:
|
||||
"""
|
||||
Load a project TOML file.
|
||||
Automatically migrates legacy 'discussion' keys to a sibling history file.
|
||||
@@ -193,7 +206,7 @@ def load_project(path: Union[str, Path]) -> dict[str, Any]:
|
||||
proj["discussion"] = load_history(path)
|
||||
return proj
|
||||
|
||||
def load_history(project_path: Union[str, Path]) -> dict[str, Any]:
|
||||
def load_history(project_path: Union[str, Path]) -> Metadata:
|
||||
"""
|
||||
Load the segregated discussion history from its dedicated TOML file.
|
||||
[C: tests/test_thinking_persistence.py:test_save_and_load_history_with_thinking_segments]
|
||||
@@ -213,7 +226,7 @@ def clean_nones(data: Any) -> Any:
|
||||
elif isinstance(data, list): return [clean_nones(v) for v in data if v is not None]
|
||||
return data
|
||||
|
||||
def save_project(proj: dict[str, Any], path: Union[str, Path], disc_data: Optional[dict[str, Any]] = None) -> None:
|
||||
def save_project(proj: Metadata, path: Union[str, Path], disc_data: Optional[Metadata] = None) -> None:
|
||||
"""
|
||||
Save the project TOML.
|
||||
If 'discussion' is present in proj, it is moved to the sibling history file.
|
||||
@@ -237,7 +250,7 @@ def save_project(proj: dict[str, Any], path: Union[str, Path], disc_data: Option
|
||||
tomli_w.dump(disc_data, f)
|
||||
# ── migration helper ─────────────────────────────────────────────────────────
|
||||
|
||||
def migrate_from_legacy_config(cfg: dict[str, Any]) -> dict[str, Any]:
|
||||
def migrate_from_legacy_config(cfg: Metadata) -> Metadata:
|
||||
"""Build a fresh project dict from a legacy flat config.toml. Does NOT save."""
|
||||
name = cfg.get("output", {}).get("namespace", "project")
|
||||
proj = default_project(name)
|
||||
@@ -251,7 +264,7 @@ def migrate_from_legacy_config(cfg: dict[str, Any]) -> dict[str, Any]:
|
||||
return proj
|
||||
# ── flat config for aggregate.run() ─────────────────────────────────────────
|
||||
|
||||
def flat_config(proj: dict[str, Any], disc_name: Optional[str] = None, track_id: Optional[str] = None) -> dict[str, Any]:
|
||||
def flat_config(proj: Metadata, disc_name: Optional[str] = None, track_id: Optional[str] = None) -> Metadata:
|
||||
"""Return a flat config dict compatible with aggregate.run()."""
|
||||
disc_sec = proj.get("discussion", {})
|
||||
if track_id:
|
||||
@@ -326,7 +339,7 @@ def save_track_history(track_id: str, history: list[str], base_dir: Union[str, P
|
||||
state.discussion = entries
|
||||
save_track_state(track_id, state, base_dir)
|
||||
|
||||
def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[dict[str, Any]]:
|
||||
def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[Metadata]:
|
||||
"""
|
||||
Scans the conductor/tracks/ directory and returns a list of dictionaries
|
||||
containing track metadata: 'id', 'title', 'status', 'complete', 'total',
|
||||
@@ -343,13 +356,13 @@ def get_all_tracks(base_dir: Union[str, Path] = ".") -> list[dict[str, Any]]:
|
||||
if not tracks_dir.exists(): return []
|
||||
|
||||
from src.result_types import ErrorInfo, ErrorKind
|
||||
results: list[dict[str, Any]] = []
|
||||
results: list[Metadata] = []
|
||||
for entry in tracks_dir.iterdir():
|
||||
if not entry.is_dir(): continue
|
||||
|
||||
track_id = entry.name
|
||||
track_errors: list[dict[str, Any]] = []
|
||||
track_info: dict[str, Any] = {
|
||||
track_errors: list[Metadata] = []
|
||||
track_info: Metadata = {
|
||||
"id": track_id,
|
||||
"title": track_id,
|
||||
"status": "unknown",
|
||||
|
||||
Reference in New Issue
Block a user