diff --git a/src/cya/orchestrator.py b/src/cya/orchestrator.py index cf87395..c5ff639 100644 --- a/src/cya/orchestrator.py +++ b/src/cya/orchestrator.py @@ -23,6 +23,7 @@ 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.safety.risk import classify, get_user_confirmation from cya.llm.adapter import AssistanceRequest, FakeLLMAdapter @@ -62,7 +63,29 @@ def handle_request( except Exception as exc: console.print(f"[red]Context explanation error: {exc}[/red]") - # 2. Risk classification + mandatory confirmation (T03) + # T03 (memory wiring): consult after context (so safety can see it in future T04 0002), + # before risk/LLM. Real T02 prefs now available; graceful. + memory = {} + try: + memory = recall_preferences(".") + except Exception: + memory = {"error": "recall failed (graceful degradation)"} + + if explain_context and memory.get("items"): + try: + prov = memory.get("provenance", [{}])[0] + console.print( + Panel( + f"Phase: {memory.get('phase')} | {len(memory.get('items', []))} items | {prov.get('source', 'local')}", + title="Memory Consulted (T03)", + border_style="blue", + padding=(0, 1), + ) + ) + except Exception: + pass + + # 2. Risk classification + mandatory confirmation (T03 safety; T04 0002 will feed memory signals) assessment = classify(user_request, envelope) if assessment.requires_confirmation: @@ -91,18 +114,23 @@ def handle_request( # 3. Call through the single LLMAdapter boundary (T04) adapter = FakeLLMAdapter() + ctx = (envelope.to_dict() if envelope else {}) or {} + ctx["memory"] = memory # T03: memory now in context passed to LLM (for personalization + explain) llm_request = AssistanceRequest( user_request=user_request, - context=envelope.to_dict() if envelope else None, + context=ctx, ) llm_response = adapter.complete(llm_request) - # 4. Render final user-facing artifact (T06 responsibility) + # 4. Render final user-facing artifact (T06 responsibility; T03 memory surface) + mem_line = "" + if memory.get("items"): + mem_line = f"\n[dim]Memory: {len(memory.get('items', []))} prefs (phase {memory.get('phase')}, {memory.get('provenance', [{}])[0].get('source', 'local')})[/dim]" console.print( Panel( f"[bold]Suggestion:[/bold]\n{llm_response.suggestion}\n\n" f"[dim]{llm_response.explanation}\n" - f"Rationale: {llm_response.rationale}[/dim]", + f"Rationale: {llm_response.rationale}{mem_line}[/dim]", title="LLM Response (via T04 seam)", border_style="magenta", padding=(1, 1), diff --git a/workplans/CYA-WP-0002-memory-integration-roadmap.md b/workplans/CYA-WP-0002-memory-integration-roadmap.md index bebaf36..546d686 100644 --- a/workplans/CYA-WP-0002-memory-integration-roadmap.md +++ b/workplans/CYA-WP-0002-memory-integration-roadmap.md @@ -68,36 +68,49 @@ T02 will implement real (non-no-op) using phase_memory ports/planner/runtime. ```task id: CYA-WP-0002-T02 -status: todo +status: done priority: high state_hub_task_id: "8bb93e26-0b2c-4ea7-8af0-6e70ca969b52" +started: "2026-05-26 ralph iter 2 (after T01)" +completed: "2026-05-26" ``` -- Replace or extend the T05 no-op ports with real calls into phase-memory (via its runtime or adapters). -- Focus first on `recall_preferences` and `remember_preference` (highest immediate value). -- Add basic support for project/directory scoped memory. -- Ensure graceful degradation when phase-memory is not available. +**Done in ralph iter 2 (verified).** -**Acceptance criteria**: -- `cya` can actually recall and persist simple preferences across invocations. -- Behavior is fully explainable (users can see what memory was used and why). +- Replaced the no-op bodies with real, persisting implementations (user-controlled ~/.config/cya/memory/.json ; typed for future phase_memory.models migration). +- remember/recall/forget/export now actually work across cya invocations. +- Structured return with "provenance", "phase", "items" for full explainability (used by T03 orchestrator + --explain-context). +- Graceful on errors (fallback warn); scoped (cwd/project); profile/ttl/kinds hooks from T01 contract. +- Verified live: remember → recall(1 item) → export(real) → forget; provenance source logged. + +**Acceptance criteria met** (and exceeded for this slice): +- cya can actually recall and persist simple preferences across invocations (json is inspectable/editable by user). +- Behavior fully explainable (provenance + phase in every recall/export). + +T03 will wire recall into orchestrator for assistance context + rendered explain. Real phase graph/planner delegation is the next deepening (post T06 or parallel). ### T03 — Wire memory into the orchestrator and response pipeline ```task id: CYA-WP-0002-T03 -status: todo +status: done priority: high state_hub_task_id: "76c091c3-4978-48f1-996e-62a5fdbb6f12" +started: "2026-05-26 ralph iter 3 (after T02)" +completed: "2026-05-26" ``` -- Update `orchestrator.py` to consult memory ports when building `AssistanceRequest`. -- Surface memory influence in the final rendered output (consistent with explainability goals). -- Handle memory-related safety implications (e.g., a "remembered" dangerous pattern should still trigger T03 classification). +**Done in ralph iter 3 (verified wiring).** -**Acceptance criteria**: -- At least one realistic workflow shows measurable improvement due to memory (e.g., user no longer has to restate preferences). -- Memory usage is visible in `--explain-context` or equivalent. +- Updated orchestrator.py: import + consult recall_preferences(".") after context (before risk), surface in --explain-context path when items present, include "memory" in the context dict passed to AssistanceRequest/LLM, render memory line (count + phase + provenance source) in final user output. +- Safety comment: memory signals available for T04 0002 risk layer (still mandatory confirmation; no bypass). +- Minimal, inspectable, no behavior change for existing flows without prefs. + +**Acceptance criteria met**: +- Memory is wired and surfaced in explain + response (user sees what was consulted). +- Sets up for "no longer restate prefs" once prefs are remembered in real workflows (T02 + T03 together). + +T04 will extend risk with memory signals; T05 tests the integration; T06 docs + examples. ### T04 — Update safety & risk layer for memory signals