diff --git a/src/cya/cli/main.py b/src/cya/cli/main.py index e3ba548..d41b8c5 100644 --- a/src/cya/cli/main.py +++ b/src/cya/cli/main.py @@ -108,6 +108,31 @@ def main( ) +@app.command() +def retrospect( + scope: str = typer.Option( + ".", + "--scope", + "-s", + help="Directory or scope to run retrospection on (default: current directory).", + ), + limit: int = typer.Option( + 8, + "--limit", + help="Number of recent memory items to review.", + ), +) -> None: + """Start a guided retrospection session. + + Review recent memory usage in this scope, reflect on what helped, + and explicitly record new preferences or interaction goals. + Outcomes are stored as first-class retrospection memory (T04 of 0003). + """ + from cya.orchestrator import run_retrospection + + run_retrospection(scope=scope, limit=limit) + + if __name__ == "__main__": app() diff --git a/src/cya/orchestrator.py b/src/cya/orchestrator.py index 5164213..825e2f0 100644 --- a/src/cya/orchestrator.py +++ b/src/cya/orchestrator.py @@ -25,7 +25,12 @@ from rich.console import Console from rich.panel import Panel from cya.context.collector import collect, render_explanation -from cya.memory import recall_preferences +from cya.memory import ( + recall_preferences, + remember_retrospection_outcome, + KIND_RETROSPECTION, + KIND_INTERACTION_GOAL, +) from cya.safety.risk import classify, get_user_confirmation from cya.llm.adapter import AssistanceRequest, FakeLLMAdapter @@ -157,4 +162,103 @@ def handle_request( ) -__all__ = ["handle_request"] +def run_retrospection(scope: str = ".", limit: int = 8) -> None: + """Guided retrospection session (T04 of CYA-WP-0003). + + Helps the user review recent memory usage in the given scope, + reflect, and record new interaction goals or preferences. + These are stored using the retrospection-aware memory helper. + """ + console.print( + Panel( + "[bold cyan]Retrospection Session[/bold cyan]\n\n" + f"Scope: [green]{scope}[/green]\n" + "We will look at recent memory items and help you reflect.\n" + "Your answers will be stored as durable retrospection memory.", + title="cya retrospect", + border_style="magenta", + padding=(1, 2), + ) + ) + + # Recall recent items, with bias toward retrospection kinds if present + try: + recent = recall_preferences( + scope, + limit=limit, + kinds=[KIND_RETROSPECTION, KIND_INTERACTION_GOAL, "preference"], + ) + items = recent.get("items", []) + except Exception as e: + console.print(f"[red]Could not load memory: {e}[/red]") + return + + if not items: + console.print( + "[yellow]No memory items found in this scope yet.[/yellow]\n" + "You can create some with normal usage or explicit remembers." + ) + return + + console.print( + Panel( + "\n".join( + f"• [bold]{item.get('key')}[/bold]: {item.get('value')}" + for item in items[:5] + ), + title=f"Recent Memory in {scope} (showing up to 5)", + border_style="blue", + ) + ) + + # Simple guided reflection + console.print("\n[bold]Reflection time[/bold]") + + what_worked = typer.prompt( + "What worked well in recent assistance? (short answer or 'skip')", + default="", + show_default=False, + ) + if what_worked and what_worked.lower() not in ("skip", "s", ""): + remember_retrospection_outcome( + "what_worked", what_worked, scope=scope + ) + console.print("[green]Recorded.[/green]") + + what_to_change = typer.prompt( + "What should change in future interactions? (e.g. 'be more concise', 'always show alternatives')", + default="", + show_default=False, + ) + if what_to_change and what_to_change.lower() not in ("skip", "s", ""): + remember_retrospection_outcome( + "interaction_goal", what_to_change, scope=scope + ) + console.print("[green]Recorded as interaction goal.[/green]") + + safety_note = typer.prompt( + "Any standing safety or preference rules for this project? (optional)", + default="", + show_default=False, + ) + if safety_note and safety_note.lower() not in ("skip", "s", ""): + remember_retrospection_outcome( + "safety_preference", safety_note, scope=scope + ) + console.print("[green]Recorded as safety preference.[/green]") + + console.print( + Panel( + "Thank you. Your reflections have been stored as retrospection memory.\n" + "They will be preferentially activated in future sessions in this scope.\n\n" + "You can review them anytime with:\n" + f" [bold]cya --explain-context \"...\"[/bold] (in this directory)\n" + f" or inspect the JSON files in [cyan]~/.config/cya/memory/[/cyan]", + title="Retrospection Complete", + border_style="green", + padding=(1, 2), + ) + ) + + +__all__ = ["handle_request", "run_retrospection"] diff --git a/workplans/CYA-WP-0003-contextual-memory-activation-and-retrospection.md b/workplans/CYA-WP-0003-contextual-memory-activation-and-retrospection.md index e153b33..13b53d7 100644 --- a/workplans/CYA-WP-0003-contextual-memory-activation-and-retrospection.md +++ b/workplans/CYA-WP-0003-contextual-memory-activation-and-retrospection.md @@ -121,21 +121,27 @@ completed: "2026-05-27" ```task id: CYA-WP-0003-T04 -status: todo +status: done priority: high state_hub_task_id: "fb63edc4-1e3f-4964-a2b6-19b29d00ffd8" +started: "2026-05-27 ralph continuation (after T03)" +completed: "2026-05-27" ``` -- Design and implement a retrospection mode or dedicated subcommand / prompt pattern. -- During retrospection, the agent helps the user: - - Review recent interactions and memory usage. - - Reflect on what helped or didn't. - - Explicitly set or refine goals, preferences, and "rules for future interactions." -- Store retrospection outputs as durable memory (stabilized phase where appropriate). +**Done** — implemented. -**Acceptance criteria**: -- A user can run a retrospection session and have its outcomes affect future assistance. -- The flow feels natural in a terminal and respects user control. +- Added `cya retrospect` subcommand in `src/cya/cli/main.py`. +- Implemented `run_retrospection()` in `src/cya/orchestrator.py`: + - Reviews recent memory in the given scope. + - Guides the user through reflection questions. + - Records outcomes using the T02 `remember_retrospection_outcome` helper (stored as retrospection / interaction_goal kinds). + - Uses rich panels for a pleasant terminal experience. +- The command is discoverable (`cya --help` shows the `retrospect` subcommand). +- Outcomes are stored in the same user-controlled memory store and will be activated in future normal sessions (per T03 activation logic). + +**Acceptance criteria met** (MVP): +- A user can run `cya retrospect` and capture goals/preferences that affect future assistance. +- The flow is natural, guided, and fully respects user control (they decide what to record). ### T05 — Close the continuous optimization loop