Skip to content

Commit ee60009

Browse files
committed
memory doctor: route 'all' through shared repair pipeline
Co-Authored-By: GPT-5 Codex (OpenAI)
1 parent 4269791 commit ee60009

2 files changed

Lines changed: 74 additions & 9 deletions

File tree

src/ash/cli/commands/memory/__init__.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ async def _run_memory_action(
288288
await memory_compact(store, force)
289289
elif action == "doctor":
290290
from ash.cli.commands.memory.doctor import (
291+
memory_doctor_all,
291292
memory_doctor_attribution,
292293
memory_doctor_backfill_subjects,
293294
memory_doctor_contradictions,
@@ -357,15 +358,7 @@ async def _run_memory_action(
357358
elif subcommand == "contradictions":
358359
await memory_doctor_contradictions(store, config, force=force)
359360
elif subcommand == "all":
360-
await memory_doctor_self_facts(store, force=force)
361-
await memory_doctor_attribution(store, force=force)
362-
await memory_doctor_fix_names(store, force=force)
363-
await memory_doctor_quality(store, config, force=force)
364-
await memory_doctor_backfill_subjects(store, force=force, config=config)
365-
await memory_doctor_normalize_semantics(store, force=force)
366-
await memory_doctor_reclassify(store, config, force=force)
367-
await memory_doctor_dedup(store, config, force=force)
368-
await memory_doctor_contradictions(store, config, force=force)
361+
await memory_doctor_all(store, config, force=force)
369362
else:
370363
error(f"Unknown action: {action}")
371364
console.print(

src/ash/cli/commands/memory/doctor/__init__.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
"""Doctor command for memory diagnostics and repair."""
22

3+
from __future__ import annotations
4+
5+
from collections.abc import Awaitable, Callable
6+
from dataclasses import dataclass
7+
from typing import TYPE_CHECKING
8+
39
from ash.cli.commands.memory.doctor.attribution import memory_doctor_attribution
410
from ash.cli.commands.memory.doctor.backfill_subjects import (
511
memory_doctor_backfill_subjects,
@@ -19,7 +25,73 @@
1925
from ash.cli.commands.memory.doctor.reclassify import memory_doctor_reclassify
2026
from ash.cli.commands.memory.doctor.self_facts import memory_doctor_self_facts
2127

28+
if TYPE_CHECKING:
29+
from ash.config.models import AshConfig
30+
from ash.store.store import Store
31+
32+
33+
@dataclass(frozen=True)
34+
class DoctorPipelineStage:
35+
"""A single stage in the doctor-all repair pipeline."""
36+
37+
name: str
38+
run: Callable[[Store, AshConfig, bool], Awaitable[None]]
39+
40+
41+
def _doctor_repair_pipeline() -> list[DoctorPipelineStage]:
42+
"""Shared memory-doctor repair stages for the `all` command."""
43+
44+
async def _self_facts(store: Store, _config: AshConfig, force: bool) -> None:
45+
await memory_doctor_self_facts(store, force=force)
46+
47+
async def _attribution(store: Store, _config: AshConfig, force: bool) -> None:
48+
await memory_doctor_attribution(store, force=force)
49+
50+
async def _fix_names(store: Store, _config: AshConfig, force: bool) -> None:
51+
await memory_doctor_fix_names(store, force=force)
52+
53+
async def _quality(store: Store, config: AshConfig, force: bool) -> None:
54+
await memory_doctor_quality(store, config, force=force)
55+
56+
async def _backfill_subjects(store: Store, config: AshConfig, force: bool) -> None:
57+
await memory_doctor_backfill_subjects(store, force=force, config=config)
58+
59+
async def _normalize_semantics(
60+
store: Store, _config: AshConfig, force: bool
61+
) -> None:
62+
await memory_doctor_normalize_semantics(store, force=force)
63+
64+
async def _reclassify(store: Store, config: AshConfig, force: bool) -> None:
65+
await memory_doctor_reclassify(store, config, force=force)
66+
67+
async def _dedup(store: Store, config: AshConfig, force: bool) -> None:
68+
await memory_doctor_dedup(store, config, force=force)
69+
70+
async def _contradictions(store: Store, config: AshConfig, force: bool) -> None:
71+
await memory_doctor_contradictions(store, config, force=force)
72+
73+
return [
74+
DoctorPipelineStage(name="self-facts", run=_self_facts),
75+
DoctorPipelineStage(name="attribution", run=_attribution),
76+
DoctorPipelineStage(name="fix-names", run=_fix_names),
77+
DoctorPipelineStage(name="quality", run=_quality),
78+
DoctorPipelineStage(name="backfill-subjects", run=_backfill_subjects),
79+
DoctorPipelineStage(name="normalize-semantics", run=_normalize_semantics),
80+
DoctorPipelineStage(name="reclassify", run=_reclassify),
81+
DoctorPipelineStage(name="dedup", run=_dedup),
82+
DoctorPipelineStage(name="contradictions", run=_contradictions),
83+
]
84+
85+
86+
async def memory_doctor_all(store: Store, config: AshConfig, force: bool) -> None:
87+
"""Run the full repair pipeline with a shared stage ordering."""
88+
for stage in _doctor_repair_pipeline():
89+
await stage.run(store, config, force)
90+
91+
2292
__all__ = [
93+
"DoctorPipelineStage",
94+
"memory_doctor_all",
2395
"memory_doctor_attribution",
2496
"memory_doctor_backfill_subjects",
2597
"memory_doctor_contradictions",

0 commit comments

Comments
 (0)