palaia 2.4.dev2__tar.gz → 2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. {palaia-2.4.dev2/palaia.egg-info → palaia-2.5}/PKG-INFO +1 -1
  2. {palaia-2.4.dev2 → palaia-2.5}/SKILL.md +106 -5
  3. {palaia-2.4.dev2 → palaia-2.5}/palaia/SKILL.md +106 -5
  4. {palaia-2.4.dev2 → palaia-2.5}/palaia/__init__.py +1 -1
  5. {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/migrate.py +38 -2
  6. {palaia-2.4.dev2 → palaia-2.5}/palaia/cli.py +84 -17
  7. {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_args.py +8 -0
  8. {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_commands.py +74 -37
  9. {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_helpers.py +9 -5
  10. {palaia-2.4.dev2 → palaia-2.5}/palaia/doctor/checks.py +2 -0
  11. {palaia-2.4.dev2 → palaia-2.5}/palaia/doctor/fixes.py +18 -0
  12. palaia-2.5/palaia/doctor/report.py +66 -0
  13. {palaia-2.4.dev2 → palaia-2.5}/palaia/embed_server.py +2 -1
  14. {palaia-2.4.dev2 → palaia-2.5}/palaia/nudge.py +16 -0
  15. {palaia-2.4.dev2 → palaia-2.5}/palaia/priorities.py +29 -1
  16. {palaia-2.4.dev2 → palaia-2.5}/palaia/scope.py +20 -0
  17. {palaia-2.4.dev2 → palaia-2.5}/palaia/search.py +9 -4
  18. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/admin.py +17 -0
  19. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/misc.py +18 -1
  20. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/write.py +30 -0
  21. {palaia-2.4.dev2 → palaia-2.5}/palaia/store.py +78 -6
  22. palaia-2.5/palaia/ui.py +424 -0
  23. {palaia-2.4.dev2 → palaia-2.5/palaia.egg-info}/PKG-INFO +1 -1
  24. {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/SOURCES.txt +3 -0
  25. {palaia-2.4.dev2 → palaia-2.5}/pyproject.toml +1 -1
  26. palaia-2.5/tests/test_backup_restore.py +137 -0
  27. {palaia-2.4.dev2 → palaia-2.5}/tests/test_concurrent_writes.py +10 -1
  28. {palaia-2.4.dev2 → palaia-2.5}/tests/test_detect.py +1 -2
  29. {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor.py +1 -1
  30. {palaia-2.4.dev2 → palaia-2.5}/tests/test_init_no_agent.py +1 -1
  31. palaia-2.5/tests/test_isolation_nudges.py +172 -0
  32. {palaia-2.4.dev2 → palaia-2.5}/tests/test_priorities.py +118 -0
  33. palaia-2.5/tests/test_prune.py +131 -0
  34. palaia-2.5/tests/test_scope.py +106 -0
  35. {palaia-2.4.dev2 → palaia-2.5}/tests/test_search_cache.py +9 -9
  36. {palaia-2.4.dev2 → palaia-2.5}/tests/test_temporal_queries.py +0 -2
  37. palaia-2.4.dev2/palaia/doctor/report.py +0 -67
  38. palaia-2.4.dev2/palaia/ui.py +0 -297
  39. palaia-2.4.dev2/tests/test_scope.py +0 -62
  40. {palaia-2.4.dev2 → palaia-2.5}/CHANGELOG.md +0 -0
  41. {palaia-2.4.dev2 → palaia-2.5}/LICENSE +0 -0
  42. {palaia-2.4.dev2 → palaia-2.5}/MANIFEST.in +0 -0
  43. {palaia-2.4.dev2 → palaia-2.5}/README.md +0 -0
  44. {palaia-2.4.dev2 → palaia-2.5}/palaia/__main__.py +0 -0
  45. {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/__init__.py +0 -0
  46. {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/postgres.py +0 -0
  47. {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/protocol.py +0 -0
  48. {palaia-2.4.dev2 → palaia-2.5}/palaia/backends/sqlite.py +0 -0
  49. {palaia-2.4.dev2 → palaia-2.5}/palaia/bm25.py +0 -0
  50. {palaia-2.4.dev2 → palaia-2.5}/palaia/cli_nudge.py +0 -0
  51. {palaia-2.4.dev2 → palaia-2.5}/palaia/config.py +0 -0
  52. {palaia-2.4.dev2 → palaia-2.5}/palaia/curate.py +0 -0
  53. {palaia-2.4.dev2 → palaia-2.5}/palaia/decay.py +0 -0
  54. {palaia-2.4.dev2 → palaia-2.5}/palaia/doctor/__init__.py +0 -0
  55. {palaia-2.4.dev2 → palaia-2.5}/palaia/embed_client.py +0 -0
  56. {palaia-2.4.dev2 → palaia-2.5}/palaia/embeddings.py +0 -0
  57. {palaia-2.4.dev2 → palaia-2.5}/palaia/entry.py +0 -0
  58. {palaia-2.4.dev2 → palaia-2.5}/palaia/enums.py +0 -0
  59. {palaia-2.4.dev2 → palaia-2.5}/palaia/frontmatter.py +0 -0
  60. {palaia-2.4.dev2 → palaia-2.5}/palaia/index.py +0 -0
  61. {palaia-2.4.dev2 → palaia-2.5}/palaia/ingest.py +0 -0
  62. {palaia-2.4.dev2 → palaia-2.5}/palaia/lock.py +0 -0
  63. {palaia-2.4.dev2 → palaia-2.5}/palaia/locking.py +0 -0
  64. {palaia-2.4.dev2 → palaia-2.5}/palaia/mcp/__init__.py +0 -0
  65. {palaia-2.4.dev2 → palaia-2.5}/palaia/mcp/server.py +0 -0
  66. {palaia-2.4.dev2 → palaia-2.5}/palaia/memo.py +0 -0
  67. {palaia-2.4.dev2 → palaia-2.5}/palaia/metadata_index.py +0 -0
  68. {palaia-2.4.dev2 → palaia-2.5}/palaia/migrate.py +0 -0
  69. {palaia-2.4.dev2 → palaia-2.5}/palaia/packages.py +0 -0
  70. {palaia-2.4.dev2 → palaia-2.5}/palaia/process_runner.py +0 -0
  71. {palaia-2.4.dev2 → palaia-2.5}/palaia/project.py +0 -0
  72. {palaia-2.4.dev2 → palaia-2.5}/palaia/project_lock.py +0 -0
  73. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/__init__.py +0 -0
  74. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/curate.py +0 -0
  75. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/ingest.py +0 -0
  76. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/memo.py +0 -0
  77. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/package.py +0 -0
  78. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/priorities.py +0 -0
  79. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/process.py +0 -0
  80. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/project.py +0 -0
  81. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/query.py +0 -0
  82. {palaia-2.4.dev2 → palaia-2.5}/palaia/services/status.py +0 -0
  83. {palaia-2.4.dev2 → palaia-2.5}/palaia/significance.py +0 -0
  84. {palaia-2.4.dev2 → palaia-2.5}/palaia/sync.py +0 -0
  85. {palaia-2.4.dev2 → palaia-2.5}/palaia/wal.py +0 -0
  86. {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/dependency_links.txt +0 -0
  87. {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/entry_points.txt +0 -0
  88. {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/requires.txt +0 -0
  89. {palaia-2.4.dev2 → palaia-2.5}/palaia.egg-info/top_level.txt +0 -0
  90. {palaia-2.4.dev2 → palaia-2.5}/setup.cfg +0 -0
  91. {palaia-2.4.dev2 → palaia-2.5}/tests/test_agent_aliases.py +0 -0
  92. {palaia-2.4.dev2 → palaia-2.5}/tests/test_agent_flag.py +0 -0
  93. {palaia-2.4.dev2 → palaia-2.5}/tests/test_audit_fixes.py +0 -0
  94. {palaia-2.4.dev2 → palaia-2.5}/tests/test_auto_title.py +0 -0
  95. {palaia-2.4.dev2 → palaia-2.5}/tests/test_backend_migrate.py +0 -0
  96. {palaia-2.4.dev2 → palaia-2.5}/tests/test_backend_postgres.py +0 -0
  97. {palaia-2.4.dev2 → palaia-2.5}/tests/test_backend_sqlite.py +0 -0
  98. {palaia-2.4.dev2 → palaia-2.5}/tests/test_bm25.py +0 -0
  99. {palaia-2.4.dev2 → palaia-2.5}/tests/test_bounded_gc.py +0 -0
  100. {palaia-2.4.dev2 → palaia-2.5}/tests/test_capture_level.py +0 -0
  101. {palaia-2.4.dev2 → palaia-2.5}/tests/test_chain_cli.py +0 -0
  102. {palaia-2.4.dev2 → palaia-2.5}/tests/test_config.py +0 -0
  103. {palaia-2.4.dev2 → palaia-2.5}/tests/test_config_detection.py +0 -0
  104. {palaia-2.4.dev2 → palaia-2.5}/tests/test_cross_platform_lock.py +0 -0
  105. {palaia-2.4.dev2 → palaia-2.5}/tests/test_cross_project.py +0 -0
  106. {palaia-2.4.dev2 → palaia-2.5}/tests/test_curate.py +0 -0
  107. {palaia-2.4.dev2 → palaia-2.5}/tests/test_decay.py +0 -0
  108. {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_fix_chain.py +0 -0
  109. {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_memos.py +0 -0
  110. {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_staleness.py +0 -0
  111. {palaia-2.4.dev2 → palaia-2.5}/tests/test_doctor_version.py +0 -0
  112. {palaia-2.4.dev2 → palaia-2.5}/tests/test_embed_server.py +0 -0
  113. {palaia-2.4.dev2 → palaia-2.5}/tests/test_embed_server_socket.py +0 -0
  114. {palaia-2.4.dev2 → palaia-2.5}/tests/test_embeddings.py +0 -0
  115. {palaia-2.4.dev2 → palaia-2.5}/tests/test_entry_classes.py +0 -0
  116. {palaia-2.4.dev2 → palaia-2.5}/tests/test_frontmatter.py +0 -0
  117. {palaia-2.4.dev2 → palaia-2.5}/tests/test_gemini_embeddings.py +0 -0
  118. {palaia-2.4.dev2 → palaia-2.5}/tests/test_hit_decay.py +0 -0
  119. {palaia-2.4.dev2 → palaia-2.5}/tests/test_incremental_indexing.py +0 -0
  120. {palaia-2.4.dev2 → palaia-2.5}/tests/test_index.py +0 -0
  121. {palaia-2.4.dev2 → palaia-2.5}/tests/test_ingest.py +0 -0
  122. {palaia-2.4.dev2 → palaia-2.5}/tests/test_init_gatekeeper.py +0 -0
  123. {palaia-2.4.dev2 → palaia-2.5}/tests/test_list_filters.py +0 -0
  124. {palaia-2.4.dev2 → palaia-2.5}/tests/test_locking.py +0 -0
  125. {palaia-2.4.dev2 → palaia-2.5}/tests/test_mcp_server.py +0 -0
  126. {palaia-2.4.dev2 → palaia-2.5}/tests/test_memo.py +0 -0
  127. {palaia-2.4.dev2 → palaia-2.5}/tests/test_metadata_index.py +0 -0
  128. {palaia-2.4.dev2 → palaia-2.5}/tests/test_migrate.py +0 -0
  129. {palaia-2.4.dev2 → palaia-2.5}/tests/test_multi_agent.py +0 -0
  130. {palaia-2.4.dev2 → palaia-2.5}/tests/test_nudge_tracker.py +0 -0
  131. {palaia-2.4.dev2 → palaia-2.5}/tests/test_packages.py +0 -0
  132. {palaia-2.4.dev2 → palaia-2.5}/tests/test_plugin_defaults_upgrade.py +0 -0
  133. {palaia-2.4.dev2 → palaia-2.5}/tests/test_process_nudge.py +0 -0
  134. {palaia-2.4.dev2 → palaia-2.5}/tests/test_process_runner.py +0 -0
  135. {palaia-2.4.dev2 → palaia-2.5}/tests/test_project.py +0 -0
  136. {palaia-2.4.dev2 → palaia-2.5}/tests/test_project_owner.py +0 -0
  137. {palaia-2.4.dev2 → palaia-2.5}/tests/test_scope_enforcement.py +0 -0
  138. {palaia-2.4.dev2 → palaia-2.5}/tests/test_search.py +0 -0
  139. {palaia-2.4.dev2 → palaia-2.5}/tests/test_search_chain.py +0 -0
  140. {palaia-2.4.dev2 → palaia-2.5}/tests/test_significance.py +0 -0
  141. {palaia-2.4.dev2 → palaia-2.5}/tests/test_skill.py +0 -0
  142. {palaia-2.4.dev2 → palaia-2.5}/tests/test_ssrf.py +0 -0
  143. {palaia-2.4.dev2 → palaia-2.5}/tests/test_status_index_hint.py +0 -0
  144. {palaia-2.4.dev2 → palaia-2.5}/tests/test_store.py +0 -0
  145. {palaia-2.4.dev2 → palaia-2.5}/tests/test_sync.py +0 -0
  146. {palaia-2.4.dev2 → palaia-2.5}/tests/test_unicode.py +0 -0
  147. {palaia-2.4.dev2 → palaia-2.5}/tests/test_ux_improvements.py +0 -0
  148. {palaia-2.4.dev2 → palaia-2.5}/tests/test_wal.py +0 -0
  149. {palaia-2.4.dev2 → palaia-2.5}/tests/test_wal_corruption.py +0 -0
  150. {palaia-2.4.dev2 → palaia-2.5}/tests/test_warmup_reindex.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: palaia
3
- Version: 2.4.dev2
3
+ Version: 2.5
4
4
  Summary: Local, cloud-free memory for OpenClaw agents.
5
5
  Author-email: byte5 GmbH <hello@byte5.de>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: palaia
3
- version: "2.4.dev2"
3
+ version: "2.5"
4
4
  description: >
5
5
  Local, crash-safe persistent memory for OpenClaw agents.
6
6
  SQLite-backed by default. Semantic search, projects, scopes, auto-capture.
@@ -25,17 +25,18 @@ metadata:
25
25
  - command: "python3 -m pip install --upgrade 'palaia[fastembed]' && (npm install -g @byte5ai/palaia@latest 2>/dev/null || true) && palaia doctor --fix && palaia warmup"
26
26
  label: "Upgrade Palaia with semantic search (pip + npm plugin) and run health checks"
27
27
  postUpdateMessage: >
28
- Palaia has been updated to v2.2. New: SQLite default backend, injection priorities,
29
- knowledge curation, ContextEngine integration. Run `palaia doctor --fix` to upgrade.
28
+ Palaia has been updated to v2.4. New: session continuity (automatic briefings and
29
+ summaries), privacy markers, recency boost, progressive disclosure. Run `palaia doctor --fix` to upgrade.
30
30
  plugin:
31
31
  slot: memory
32
32
  package: "@byte5ai/palaia"
33
33
  ---
34
34
 
35
- # Palaia v2.2 — Agent Memory Skill
35
+ # Palaia v2.4 — Agent Memory Skill
36
36
 
37
37
  Palaia is the memory system for OpenClaw agents. It gives you persistent, searchable, crash-safe memory across sessions. You don't need to understand how it works — just use the commands below.
38
38
 
39
+ <!-- begin:install -->
39
40
  ## First-Time Setup
40
41
 
41
42
  When a user asks you to "set up palaia", "enable memory", or "remember things across sessions", run these steps:
@@ -136,6 +137,7 @@ npm install -g @byte5ai/palaia@latest
136
137
  ```
137
138
 
138
139
  After the manual update, `palaia upgrade` will be available for future updates.
140
+ <!-- end:install -->
139
141
 
140
142
  ## Auto-Check (run every time this skill is loaded)
141
143
 
@@ -290,6 +292,9 @@ palaia query "what's the rate limit"
290
292
  # Filter by type and status
291
293
  palaia query "tasks" --type task --status open
292
294
 
295
+ # Filter by tags
296
+ palaia query "session-summary" --tags session-summary
297
+
293
298
  # Search within a project
294
299
  palaia query "deploy steps" --project myapp
295
300
 
@@ -324,6 +329,9 @@ palaia list
324
329
  # Filter by tier, type, status
325
330
  palaia list --tier warm --type task --status open --priority high
326
331
 
332
+ # Limit results
333
+ palaia list --type task --status open --limit 5
334
+
327
335
  # Filter by project or assignee
328
336
  palaia list --project myapp --assignee Elliot
329
337
  ```
@@ -575,6 +583,66 @@ Distinguish sessions of the same agent:
575
583
  palaia instance set Claw-Main
576
584
  ```
577
585
 
586
+ ### Agent Isolation Mode
587
+
588
+ For focused agents (Sonnet/Codex) that should only see their own memories:
589
+
590
+ **1. Configure in `priorities.json`:**
591
+ ```json
592
+ {
593
+ "agents": {
594
+ "dev-worker": {
595
+ "scopeVisibility": ["private"],
596
+ "captureScope": "private",
597
+ "maxInjectedChars": 2000,
598
+ "recallMinScore": 0.85
599
+ }
600
+ }
601
+ }
602
+ ```
603
+ Or via CLI:
604
+ ```bash
605
+ palaia priorities set scopeVisibility private --agent dev-worker
606
+ palaia priorities set captureScope private --agent dev-worker
607
+ palaia priorities set maxInjectedChars 2000 --agent dev-worker
608
+ palaia priorities set recallMinScore 0.85 --agent dev-worker
609
+ ```
610
+
611
+ **2. Set agent identity:**
612
+ ```bash
613
+ export PALAIA_AGENT=dev-worker
614
+ ```
615
+
616
+ **3. Auto-capture stays on** (crash safety net). Cleanup happens after the work package.
617
+
618
+ **4. After accepting work:**
619
+ ```bash
620
+ palaia prune --agent dev-worker --tags auto-capture --protect-type process
621
+ ```
622
+ This removes session noise while preserving learned SOPs.
623
+
624
+ #### Pre-configured Agent Profiles
625
+
626
+ | Profile | scopeVisibility | captureScope | maxInjectedChars | recallMinScore | autoCapture |
627
+ |---------|----------------|--------------|-----------------|----------------|-------------|
628
+ | **Isolated Worker** | `["private"]` | `private` | 2000 | 0.85 | true |
629
+ | **Orchestrator** | `["private","team","public"]` | `team` | 4000 | 0.7 | true |
630
+ | **Lean Worker** | `["private"]` | `private` | 1000 | 0.9 | false |
631
+
632
+ #### Orchestrator Lifecycle (process template)
633
+
634
+ Save this as a process entry for the orchestrator to recall:
635
+ ```bash
636
+ palaia write "## Dev-Agent Lifecycle
637
+ 1. Create agent identity: export PALAIA_AGENT=dev-worker-{task-id}
638
+ 2. Configure isolation: palaia priorities set scopeVisibility private --agent dev-worker-{task-id}
639
+ 3. Configure capture: palaia priorities set captureScope private --agent dev-worker-{task-id}
640
+ 4. Assign work package via prompt
641
+ 5. After acceptance: palaia prune --agent dev-worker-{task-id} --tags auto-capture --protect-type process
642
+ 6. Verify: palaia list --agent dev-worker-{task-id} --type process
643
+ 7. Process knowledge persists for future tasks" --type process --tags workflow,orchestration --scope private
644
+ ```
645
+
578
646
  ---
579
647
 
580
648
  ## When to Use What
@@ -590,10 +658,11 @@ palaia instance set Claw-Main
590
658
  | Check system health | `palaia status` |
591
659
  | Something is wrong | `palaia doctor --fix` |
592
660
  | Clean up old entries | `palaia gc` |
661
+ | Clean up agent session noise | `palaia prune --agent NAME --tags auto-capture --protect-type process` |
593
662
  | Review accumulated knowledge | `palaia curate analyze` |
594
663
  | Share knowledge | `palaia sync export` or `palaia package export` |
595
664
  | Check for messages | `palaia memo inbox` |
596
- | Start of session | `palaia doctor` then `palaia query "active work"` then `palaia memo inbox` |
665
+ | Start of session | Session briefing is now automatic. Just run `palaia doctor` and check `palaia memo inbox`. |
597
666
 
598
667
  **Do NOT manually write:** facts, decisions, or preferences that came up in the current conversation. Auto-Capture handles these.
599
668
 
@@ -632,6 +701,33 @@ palaia init --capture-level <off|minimal|normal|aggressive>
632
701
 
633
702
  ---
634
703
 
704
+ ## Session Continuity (NEW in v2.4)
705
+
706
+ Session continuity gives agents automatic context restoration across sessions. These features work out of the box with the OpenClaw plugin -- no manual setup needed.
707
+
708
+ ### Session Briefings
709
+ On session start, Palaia automatically injects a briefing with the last session summary and any open tasks. This means agents resume work without needing to manually search for context.
710
+
711
+ ### Session Summaries
712
+ When a session ends or resets, Palaia auto-saves a summary of what happened. These are stored as entries with the `session-summary` tag and can be queried:
713
+ ```bash
714
+ palaia query "session-summary" --tags session-summary
715
+ ```
716
+
717
+ ### Privacy Markers
718
+ Wrap sensitive content in `<private>...</private>` blocks to exclude it from auto-capture. Private blocks are stripped before any extraction runs.
719
+
720
+ ### Recency Boost
721
+ Fresh memories are ranked higher in recall results. The boost factor is configurable via `recallRecencyBoost` (default `0.3`, set to `0` to disable).
722
+
723
+ ### Progressive Disclosure
724
+ When result sets exceed 100 entries, Palaia uses compact mode to keep context manageable. Use `--limit` to control result size explicitly:
725
+ ```bash
726
+ palaia list --type task --status open --limit 5
727
+ ```
728
+
729
+ ---
730
+
635
731
  ## Plugin Configuration (OpenClaw)
636
732
 
637
733
  Set in `openclaw.json` under `plugins.entries.palaia.config`:
@@ -649,6 +745,11 @@ Set in `openclaw.json` under `plugins.entries.palaia.config`:
649
745
  | `embeddingServer` | `true` | Keep embedding model loaded for fast queries |
650
746
  | `showMemorySources` | `true` | Show memory source footnotes |
651
747
  | `showCaptureConfirm` | `true` | Show capture confirmations |
748
+ | `sessionSummary` | `true` | Auto-save session summaries on end/reset |
749
+ | `sessionBriefing` | `true` | Load session context on session start |
750
+ | `sessionBriefingMaxChars` | `1500` | Max chars for session briefing injection |
751
+ | `captureToolObservations` | `true` | Track tool usage as session context |
752
+ | `recallRecencyBoost` | `0.3` | Boost factor for fresh memories (0=off) |
652
753
 
653
754
  ---
654
755
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: palaia
3
- version: "2.4.dev2"
3
+ version: "2.5"
4
4
  description: >
5
5
  Local, crash-safe persistent memory for OpenClaw agents.
6
6
  SQLite-backed by default. Semantic search, projects, scopes, auto-capture.
@@ -25,17 +25,18 @@ metadata:
25
25
  - command: "python3 -m pip install --upgrade 'palaia[fastembed]' && (npm install -g @byte5ai/palaia@latest 2>/dev/null || true) && palaia doctor --fix && palaia warmup"
26
26
  label: "Upgrade Palaia with semantic search (pip + npm plugin) and run health checks"
27
27
  postUpdateMessage: >
28
- Palaia has been updated to v2.2. New: SQLite default backend, injection priorities,
29
- knowledge curation, ContextEngine integration. Run `palaia doctor --fix` to upgrade.
28
+ Palaia has been updated to v2.4. New: session continuity (automatic briefings and
29
+ summaries), privacy markers, recency boost, progressive disclosure. Run `palaia doctor --fix` to upgrade.
30
30
  plugin:
31
31
  slot: memory
32
32
  package: "@byte5ai/palaia"
33
33
  ---
34
34
 
35
- # Palaia v2.2 — Agent Memory Skill
35
+ # Palaia v2.4 — Agent Memory Skill
36
36
 
37
37
  Palaia is the memory system for OpenClaw agents. It gives you persistent, searchable, crash-safe memory across sessions. You don't need to understand how it works — just use the commands below.
38
38
 
39
+ <!-- begin:install -->
39
40
  ## First-Time Setup
40
41
 
41
42
  When a user asks you to "set up palaia", "enable memory", or "remember things across sessions", run these steps:
@@ -136,6 +137,7 @@ npm install -g @byte5ai/palaia@latest
136
137
  ```
137
138
 
138
139
  After the manual update, `palaia upgrade` will be available for future updates.
140
+ <!-- end:install -->
139
141
 
140
142
  ## Auto-Check (run every time this skill is loaded)
141
143
 
@@ -290,6 +292,9 @@ palaia query "what's the rate limit"
290
292
  # Filter by type and status
291
293
  palaia query "tasks" --type task --status open
292
294
 
295
+ # Filter by tags
296
+ palaia query "session-summary" --tags session-summary
297
+
293
298
  # Search within a project
294
299
  palaia query "deploy steps" --project myapp
295
300
 
@@ -324,6 +329,9 @@ palaia list
324
329
  # Filter by tier, type, status
325
330
  palaia list --tier warm --type task --status open --priority high
326
331
 
332
+ # Limit results
333
+ palaia list --type task --status open --limit 5
334
+
327
335
  # Filter by project or assignee
328
336
  palaia list --project myapp --assignee Elliot
329
337
  ```
@@ -575,6 +583,66 @@ Distinguish sessions of the same agent:
575
583
  palaia instance set Claw-Main
576
584
  ```
577
585
 
586
+ ### Agent Isolation Mode
587
+
588
+ For focused agents (Sonnet/Codex) that should only see their own memories:
589
+
590
+ **1. Configure in `priorities.json`:**
591
+ ```json
592
+ {
593
+ "agents": {
594
+ "dev-worker": {
595
+ "scopeVisibility": ["private"],
596
+ "captureScope": "private",
597
+ "maxInjectedChars": 2000,
598
+ "recallMinScore": 0.85
599
+ }
600
+ }
601
+ }
602
+ ```
603
+ Or via CLI:
604
+ ```bash
605
+ palaia priorities set scopeVisibility private --agent dev-worker
606
+ palaia priorities set captureScope private --agent dev-worker
607
+ palaia priorities set maxInjectedChars 2000 --agent dev-worker
608
+ palaia priorities set recallMinScore 0.85 --agent dev-worker
609
+ ```
610
+
611
+ **2. Set agent identity:**
612
+ ```bash
613
+ export PALAIA_AGENT=dev-worker
614
+ ```
615
+
616
+ **3. Auto-capture stays on** (crash safety net). Cleanup happens after the work package.
617
+
618
+ **4. After accepting work:**
619
+ ```bash
620
+ palaia prune --agent dev-worker --tags auto-capture --protect-type process
621
+ ```
622
+ This removes session noise while preserving learned SOPs.
623
+
624
+ #### Pre-configured Agent Profiles
625
+
626
+ | Profile | scopeVisibility | captureScope | maxInjectedChars | recallMinScore | autoCapture |
627
+ |---------|----------------|--------------|-----------------|----------------|-------------|
628
+ | **Isolated Worker** | `["private"]` | `private` | 2000 | 0.85 | true |
629
+ | **Orchestrator** | `["private","team","public"]` | `team` | 4000 | 0.7 | true |
630
+ | **Lean Worker** | `["private"]` | `private` | 1000 | 0.9 | false |
631
+
632
+ #### Orchestrator Lifecycle (process template)
633
+
634
+ Save this as a process entry for the orchestrator to recall:
635
+ ```bash
636
+ palaia write "## Dev-Agent Lifecycle
637
+ 1. Create agent identity: export PALAIA_AGENT=dev-worker-{task-id}
638
+ 2. Configure isolation: palaia priorities set scopeVisibility private --agent dev-worker-{task-id}
639
+ 3. Configure capture: palaia priorities set captureScope private --agent dev-worker-{task-id}
640
+ 4. Assign work package via prompt
641
+ 5. After acceptance: palaia prune --agent dev-worker-{task-id} --tags auto-capture --protect-type process
642
+ 6. Verify: palaia list --agent dev-worker-{task-id} --type process
643
+ 7. Process knowledge persists for future tasks" --type process --tags workflow,orchestration --scope private
644
+ ```
645
+
578
646
  ---
579
647
 
580
648
  ## When to Use What
@@ -590,10 +658,11 @@ palaia instance set Claw-Main
590
658
  | Check system health | `palaia status` |
591
659
  | Something is wrong | `palaia doctor --fix` |
592
660
  | Clean up old entries | `palaia gc` |
661
+ | Clean up agent session noise | `palaia prune --agent NAME --tags auto-capture --protect-type process` |
593
662
  | Review accumulated knowledge | `palaia curate analyze` |
594
663
  | Share knowledge | `palaia sync export` or `palaia package export` |
595
664
  | Check for messages | `palaia memo inbox` |
596
- | Start of session | `palaia doctor` then `palaia query "active work"` then `palaia memo inbox` |
665
+ | Start of session | Session briefing is now automatic. Just run `palaia doctor` and check `palaia memo inbox`. |
597
666
 
598
667
  **Do NOT manually write:** facts, decisions, or preferences that came up in the current conversation. Auto-Capture handles these.
599
668
 
@@ -632,6 +701,33 @@ palaia init --capture-level <off|minimal|normal|aggressive>
632
701
 
633
702
  ---
634
703
 
704
+ ## Session Continuity (NEW in v2.4)
705
+
706
+ Session continuity gives agents automatic context restoration across sessions. These features work out of the box with the OpenClaw plugin -- no manual setup needed.
707
+
708
+ ### Session Briefings
709
+ On session start, Palaia automatically injects a briefing with the last session summary and any open tasks. This means agents resume work without needing to manually search for context.
710
+
711
+ ### Session Summaries
712
+ When a session ends or resets, Palaia auto-saves a summary of what happened. These are stored as entries with the `session-summary` tag and can be queried:
713
+ ```bash
714
+ palaia query "session-summary" --tags session-summary
715
+ ```
716
+
717
+ ### Privacy Markers
718
+ Wrap sensitive content in `<private>...</private>` blocks to exclude it from auto-capture. Private blocks are stripped before any extraction runs.
719
+
720
+ ### Recency Boost
721
+ Fresh memories are ranked higher in recall results. The boost factor is configurable via `recallRecencyBoost` (default `0.3`, set to `0` to disable).
722
+
723
+ ### Progressive Disclosure
724
+ When result sets exceed 100 entries, Palaia uses compact mode to keep context manageable. Use `--limit` to control result size explicitly:
725
+ ```bash
726
+ palaia list --type task --status open --limit 5
727
+ ```
728
+
729
+ ---
730
+
635
731
  ## Plugin Configuration (OpenClaw)
636
732
 
637
733
  Set in `openclaw.json` under `plugins.entries.palaia.config`:
@@ -649,6 +745,11 @@ Set in `openclaw.json` under `plugins.entries.palaia.config`:
649
745
  | `embeddingServer` | `true` | Keep embedding model loaded for fast queries |
650
746
  | `showMemorySources` | `true` | Show memory source footnotes |
651
747
  | `showCaptureConfirm` | `true` | Show capture confirmations |
748
+ | `sessionSummary` | `true` | Auto-save session summaries on end/reset |
749
+ | `sessionBriefing` | `true` | Load session context on session start |
750
+ | `sessionBriefingMaxChars` | `1500` | Max chars for session briefing injection |
751
+ | `captureToolObservations` | `true` | Track tool usage as session context |
752
+ | `recallRecencyBoost` | `0.3` | Boost factor for fresh memories (0=off) |
652
753
 
653
754
  ---
654
755
 
@@ -4,5 +4,5 @@ Palaia — Local, cloud-free memory for OpenClaw agents.
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- __version__ = "2.4.dev2"
7
+ __version__ = "2.5"
8
8
  __author__ = "byte5 GmbH"
@@ -51,7 +51,13 @@ def _should_rename(error_count: int, total_count: int) -> bool:
51
51
 
52
52
 
53
53
  def needs_migration(palaia_root: Path) -> bool:
54
- """Check if there are flat-file indexes that should be migrated."""
54
+ """Check if there are flat-file indexes that should be migrated.
55
+
56
+ Detects three scenarios:
57
+ 1. Old-style metadata.json / embeddings.json exist (pre-SQLite migration)
58
+ 2. WAL JSON files exist
59
+ 3. Entries on disk but 0 in the database (e.g. backup restore into hot/)
60
+ """
55
61
  metadata_json = palaia_root / "index" / "metadata.json"
56
62
  embeddings_json = palaia_root / "index" / "embeddings.json"
57
63
  wal_dir = palaia_root / "wal"
@@ -59,7 +65,37 @@ def needs_migration(palaia_root: Path) -> bool:
59
65
  has_json = metadata_json.exists() or embeddings_json.exists()
60
66
  has_wal_files = wal_dir.exists() and any(wal_dir.glob("*.json"))
61
67
 
62
- return has_json or has_wal_files
68
+ if has_json or has_wal_files:
69
+ return True
70
+
71
+ # Scenario 3: Disk entries exist but DB is empty (backup restore)
72
+ disk_count = 0
73
+ for tier in ("hot", "warm", "cold"):
74
+ tier_dir = palaia_root / tier
75
+ if tier_dir.exists():
76
+ try:
77
+ disk_count += sum(1 for _ in tier_dir.glob("*.md"))
78
+ except (PermissionError, OSError):
79
+ pass
80
+ if disk_count > 0:
81
+ break # At least one entry found, check DB
82
+
83
+ if disk_count > 0:
84
+ import sqlite3
85
+
86
+ db_path = palaia_root / "palaia.db"
87
+ if db_path.exists():
88
+ try:
89
+ conn = sqlite3.connect(str(db_path))
90
+ row = conn.execute("SELECT COUNT(*) FROM entries").fetchone()
91
+ db_count = row[0] if row else 0
92
+ conn.close()
93
+ if db_count == 0:
94
+ return True
95
+ except Exception:
96
+ pass
97
+
98
+ return False
63
99
 
64
100
 
65
101
  def migrate_to_backend(palaia_root: Path, backend: object) -> MigrationResult:
@@ -49,7 +49,17 @@ from palaia.config import ( # noqa: E402
49
49
  from palaia.doctor import apply_fixes, format_doctor_report, run_doctor # noqa: E402
50
50
  from palaia.migrate import format_result, migrate # noqa: E402
51
51
  from palaia.store import Store # noqa: E402
52
- from palaia.ui import print_header, section, table_multi # noqa: E402
52
+ from palaia.ui import ( # noqa: E402
53
+ bold,
54
+ dim,
55
+ error_msg,
56
+ print_header,
57
+ section,
58
+ success,
59
+ sym_arrow,
60
+ table_multi,
61
+ )
62
+
53
63
 
54
64
  # Commands that require a valid init (agent identity set)
55
65
  GATED_COMMANDS = frozenset(
@@ -60,6 +70,7 @@ GATED_COMMANDS = frozenset(
60
70
  "edit",
61
71
  "memo",
62
72
  "gc",
73
+ "prune",
63
74
  "export",
64
75
  "import",
65
76
  "ingest",
@@ -178,9 +189,9 @@ def cmd_init(args):
178
189
  args,
179
190
  ):
180
191
  return 0
181
- print(f"Initialized Palaia at {result['path']}")
192
+ print(success(f"Initialized at {dim(result['path'])}"))
182
193
  if result.get("used_default"):
183
- print("Initialized with agent: default (use --agent NAME to customize)")
194
+ print(f" Agent: default {dim('(use --agent NAME to customize)')}")
184
195
 
185
196
  # Print all messages from service (chain info, capture level, setup instructions)
186
197
  if not getattr(args, "json", False):
@@ -243,7 +254,10 @@ def cmd_write(args):
243
254
  ):
244
255
  return 0
245
256
 
246
- print(f"Written: {result['id']}")
257
+ short_id = result['id'][:12]
258
+ scope = result.get('scope', 'team')
259
+ tier = result.get('tier', 'hot')
260
+ print(success(f"Written {dim(short_id)} {sym_arrow()} {tier}/{scope}"))
247
261
 
248
262
  if significance_detected:
249
263
  tags_str = ", ".join(significance_detected)
@@ -294,7 +308,7 @@ def cmd_edit(args):
294
308
  if _json_out(result, args):
295
309
  return 0
296
310
 
297
- print(f"Updated: {result['id']}")
311
+ print(success(f"Updated {dim(result['id'][:12])}"))
298
312
  changes = []
299
313
  if body is not None:
300
314
  changes.append("content")
@@ -304,7 +318,7 @@ def cmd_edit(args):
304
318
  if getattr(args, field, None) is not None:
305
319
  changes.append(field)
306
320
  if changes:
307
- print(f" Changed: {', '.join(changes)}")
321
+ print(f" Changed: {', '.join(changes)}")
308
322
  return 0
309
323
 
310
324
 
@@ -506,17 +520,68 @@ def cmd_gc(args):
506
520
 
507
521
  skip_keys = {"wal_cleaned", "pruned", "pruned_entries"}
508
522
  total_moves = sum(v for k, v in result.items() if k not in skip_keys and isinstance(v, int))
509
- print("GC complete.")
510
523
  if total_moves:
524
+ print(success("GC complete"))
511
525
  for k, v in result.items():
512
526
  if v and k not in skip_keys and isinstance(v, int):
513
- print(f" {k}: {v}")
527
+ print(f" {k}: {v}")
514
528
  else:
515
- print(" No tier changes needed.")
529
+ print(success("GC complete — no tier changes needed"))
516
530
  if result.get("wal_cleaned"):
517
- print(f" WAL cleaned: {result['wal_cleaned']} old entries")
531
+ print(f" WAL cleaned: {result['wal_cleaned']} old entries")
518
532
  if result.get("pruned"):
519
- print(f" Pruned (budget): {result['pruned']} entries")
533
+ print(f" Pruned (budget): {result['pruned']} entries")
534
+ return 0
535
+
536
+
537
+ def cmd_prune(args):
538
+ """Selectively delete entries by agent + tags."""
539
+ from palaia.services.admin import run_prune
540
+
541
+ root = get_root()
542
+ agent = args.agent
543
+ tags = [t.strip() for t in args.tags.split(",") if t.strip()]
544
+ protect_types = None
545
+ if args.protect_type:
546
+ protect_types = [t.strip() for t in args.protect_type.split(",") if t.strip()]
547
+ dry_run = getattr(args, "dry_run", False)
548
+
549
+ result = run_prune(root, agent=agent, tags=tags, protect_types=protect_types, dry_run=dry_run)
550
+
551
+ if _json_out(result, args):
552
+ return 0
553
+
554
+ entries = result.get("entries", [])
555
+ count = result.get("pruned", 0)
556
+
557
+ if count == 0:
558
+ print("No matching entries found.")
559
+ return 0
560
+
561
+ if dry_run:
562
+ rows = [(e["id"], e["title"][:30], e["type"], e["tier"], ",".join(e.get("tags", []))) for e in entries]
563
+ print(
564
+ table_multi(
565
+ headers=("ID", "Title", "Type", "Tier", "Tags"),
566
+ rows=rows,
567
+ min_widths=(8, 30, 8, 4, 15),
568
+ )
569
+ )
570
+ print(f"\n{count} entries would be deleted (dry-run).")
571
+ else:
572
+ print(f"Pruned {count} entries for agent '{agent}'.")
573
+ for e in entries:
574
+ print(f" {e['id']} {e['title'][:40]}")
575
+
576
+ # Record prune success for prune_reminder graduation (#148)
577
+ try:
578
+ from palaia.nudge import NudgeTracker
579
+ caller = os.environ.get("PALAIA_AGENT") or "default"
580
+ tracker = NudgeTracker(root)
581
+ tracker.record_success("prune_reminder", caller)
582
+ except Exception:
583
+ pass
584
+
520
585
  return 0
521
586
 
522
587
 
@@ -541,9 +606,9 @@ def cmd_doctor(args):
541
606
  print(format_doctor_report(results, show_fix=show_fix))
542
607
 
543
608
  if fix_actions:
544
- print("\nFixes applied:")
609
+ print(f"\n {bold('Fixes applied:')}")
545
610
  for action in fix_actions:
546
- print(f" [ok] {action}")
611
+ print(success(action))
547
612
  print()
548
613
 
549
614
  return 0
@@ -742,17 +807,18 @@ def cmd_setup(args):
742
807
 
743
808
  # Print action details
744
809
  if not getattr(args, "json", False):
810
+ from palaia.ui import status_label
745
811
  for action in result.get("actions", []):
746
812
  label = action["action"]
747
813
  agent = action["agent"]
748
814
  if label == "skip":
749
- print(f" [skip] {agent}: {action.get('reason', '')}")
815
+ print(f" {status_label('skip')} {agent}: {dim(action.get('reason', ''))}")
750
816
  elif label == "plan":
751
- print(f" [plan] {agent}: would create .palaia -> {action.get('target', '')}")
817
+ print(f" {status_label('info')} {agent}: would create .palaia {sym_arrow()} {action.get('target', '')}")
752
818
  elif label == "ok":
753
- print(f" [ok] {agent}: .palaia -> {action.get('target', '')}")
819
+ print(success(f"{agent}: .palaia {sym_arrow()} {action.get('target', '')}"))
754
820
  elif label == "error":
755
- print(f" [error] {agent}: {action.get('error', '')}")
821
+ print(error_msg(f"{agent}: {action.get('error', '')}"))
756
822
 
757
823
  if _json_out(
758
824
  {
@@ -1372,6 +1438,7 @@ def main():
1372
1438
  "list": cmd_list,
1373
1439
  "status": cmd_status,
1374
1440
  "gc": cmd_gc,
1441
+ "prune": cmd_prune,
1375
1442
  "setup": cmd_setup,
1376
1443
  "doctor": cmd_doctor,
1377
1444
  "export": cmd_export,
@@ -169,6 +169,14 @@ def build_parser() -> argparse.ArgumentParser:
169
169
  p_gc.add_argument("--budget", action="store_true", help="Prune entries to meet configured budget limits")
170
170
  p_gc.add_argument("--json", action="store_true", help="Output as JSON")
171
171
 
172
+ # prune
173
+ p_prune = sub.add_parser("prune", help="Selectively delete entries by agent + tags")
174
+ p_prune.add_argument("--agent", required=True, help="Agent name to prune entries for (required)")
175
+ p_prune.add_argument("--tags", required=True, help="Comma-separated tags to match (required, e.g. auto-capture)")
176
+ p_prune.add_argument("--protect-type", default=None, help="Comma-separated types to preserve (e.g. process,task)")
177
+ p_prune.add_argument("--dry-run", action="store_true", help="Show what would be deleted without changing anything")
178
+ p_prune.add_argument("--json", action="store_true", help="Output as JSON")
179
+
172
180
  # project
173
181
  _add_project_subparser(sub)
174
182