Implement WARDEN-WP-0024 experiential memory and agent sessions.
Add phase-memory bridge, warden memory CLI, route/access/sign recording, memory-aware worker planning with OpenRouter skip, tests, wiki, and AGENTS.md orientation for Claude, Codex, Grok, and future agent sessions.
This commit is contained in:
parent
2f532699fa
commit
04929e7981
9 changed files with 568 additions and 14 deletions
|
|
@ -44,6 +44,11 @@ activity_app = typer.Typer(
|
|||
no_args_is_help=True,
|
||||
)
|
||||
app.add_typer(activity_app, name="activity")
|
||||
memory_app = typer.Typer(
|
||||
help="Cross-runtime experiential memory via phase-memory (WARDEN-WP-0024)",
|
||||
no_args_is_help=True,
|
||||
)
|
||||
app.add_typer(memory_app, name="memory")
|
||||
|
||||
console = Console()
|
||||
err = Console(stderr=True)
|
||||
|
|
@ -53,6 +58,30 @@ err = Console(stderr=True)
|
|||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _record_memory_episode(
|
||||
*,
|
||||
command: str,
|
||||
outcome: str,
|
||||
need: str = "",
|
||||
route_id: str = "",
|
||||
) -> None:
|
||||
try:
|
||||
from warden import memory as warden_memory
|
||||
except ImportError:
|
||||
return
|
||||
if not warden_memory.enabled() or not warden_memory.memory_available():
|
||||
return
|
||||
try:
|
||||
warden_memory.record_command_episode(
|
||||
command=command,
|
||||
outcome=outcome,
|
||||
need=need,
|
||||
route_id=route_id,
|
||||
)
|
||||
except RuntimeError:
|
||||
return
|
||||
|
||||
|
||||
def _load_cfg() -> WardenConfig:
|
||||
try:
|
||||
return load_config()
|
||||
|
|
@ -128,6 +157,12 @@ def sign(
|
|||
|
||||
# cert_command interface: write cert text to stdout only
|
||||
print(record.cert_path.read_text().strip())
|
||||
_record_memory_episode(
|
||||
command="sign",
|
||||
outcome="resolved",
|
||||
need=f"ssh cert {actor_name}",
|
||||
route_id="ops-warden-ssh-cert",
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -753,14 +788,30 @@ def route_find(
|
|||
|
||||
if output_json:
|
||||
print(json.dumps([_entry_summary(e) for e in matches], indent=2))
|
||||
if matches:
|
||||
_record_memory_episode(
|
||||
command="route find",
|
||||
outcome="resolved",
|
||||
need=query,
|
||||
route_id=matches[0].id,
|
||||
)
|
||||
else:
|
||||
_record_memory_episode(command="route find", outcome="skipped", need=query)
|
||||
return
|
||||
|
||||
if not matches:
|
||||
_record_memory_episode(command="route find", outcome="skipped", need=query)
|
||||
console.print(
|
||||
f"No routing match for {query!r}. "
|
||||
"Try `warden route list --all` to browse all scenarios."
|
||||
)
|
||||
return
|
||||
_record_memory_episode(
|
||||
command="route find",
|
||||
outcome="resolved",
|
||||
need=query,
|
||||
route_id=matches[0].id,
|
||||
)
|
||||
_print_entry_table(matches, f"Matches for {query!r}")
|
||||
|
||||
|
||||
|
|
@ -1003,8 +1054,20 @@ def access(
|
|||
|
||||
if output_json:
|
||||
print(json.dumps(_access_json(entry, expanded, gate, domain), indent=2))
|
||||
_record_memory_episode(
|
||||
command="access",
|
||||
outcome="resolved",
|
||||
need=need,
|
||||
route_id=entry.id,
|
||||
)
|
||||
return
|
||||
|
||||
_record_memory_episode(
|
||||
command="access",
|
||||
outcome="resolved",
|
||||
need=need,
|
||||
route_id=entry.id,
|
||||
)
|
||||
console.print(f"[bold]{entry.title}[/bold] ([cyan]{entry.id}[/cyan])")
|
||||
console.print(f" owner : {entry.owner_repo} ({entry.subsystem})")
|
||||
|
||||
|
|
@ -1305,3 +1368,58 @@ def worker_status_cmd() -> None:
|
|||
console.print(f"timer : {st or 'unknown'}")
|
||||
except Exception: # noqa: BLE001 — systemd may be absent (cron/other host)
|
||||
console.print("timer : (systemd not available)")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# warden memory — cross-runtime experiential memory (WARDEN-WP-0024)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@memory_app.command("status")
|
||||
def memory_status(
|
||||
output_json: Annotated[bool, typer.Option("--json", help="Output JSON")] = False,
|
||||
) -> None:
|
||||
"""Show canonical phase-memory store status (metadata only)."""
|
||||
from warden import memory as warden_memory
|
||||
|
||||
if not warden_memory.memory_available():
|
||||
err.print(f"[red]{warden_memory._PHASE_MEMORY_ERROR}[/red]")
|
||||
raise typer.Exit(2)
|
||||
try:
|
||||
payload = warden_memory.status()
|
||||
except RuntimeError as e:
|
||||
err.print(f"[red]{e}[/red]")
|
||||
raise typer.Exit(2)
|
||||
if output_json:
|
||||
print(json.dumps(payload, indent=2))
|
||||
return
|
||||
console.print(f"store_path : {payload.get('store_path', '')}")
|
||||
console.print(f"profile_id : {payload.get('profile_id', '')}")
|
||||
console.print(f"episode_count : {payload.get('episode_count', 0)}")
|
||||
console.print(f"session_kinds : {payload.get('episode_counts_by_session_kind', {})}")
|
||||
console.print(f"last_activation: {payload.get('last_activation_at') or '—'}")
|
||||
|
||||
|
||||
@memory_app.command("activate")
|
||||
def memory_activate(
|
||||
need: Annotated[str, typer.Option("--need", help="Optional routing need fingerprint source")] = "",
|
||||
agent: Annotated[
|
||||
Optional[str],
|
||||
typer.Option("--agent", help="Agent id for session_kind warden.agent.<id> (claude, codex, grok, …)"),
|
||||
] = None,
|
||||
output_json: Annotated[bool, typer.Option("--json", help="Output JSON")] = False,
|
||||
) -> None:
|
||||
"""Activate bounded coordination memory for worker, operator, or agent sessions."""
|
||||
from warden import memory as warden_memory
|
||||
|
||||
if not warden_memory.memory_available():
|
||||
err.print(f"[red]{warden_memory._PHASE_MEMORY_ERROR}[/red]")
|
||||
raise typer.Exit(2)
|
||||
try:
|
||||
payload = warden_memory.activate(need=need, agent=agent)
|
||||
except RuntimeError as e:
|
||||
err.print(f"[red]{e}[/red]")
|
||||
raise typer.Exit(2)
|
||||
if output_json:
|
||||
print(json.dumps(payload, indent=2))
|
||||
return
|
||||
console.print(warden_memory.format_activation_summary(payload))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue