Files
turnstone/turnstone/tools/memory.json
T
Patrick Buckley 723cad24bb feat: structured memory system — typed/scoped memories with BM25 rele… (#53)
* feat: structured memory system — typed/scoped memories with BM25 relevance and metacognitive prompting

Replace flat key-value memories table with structured_memories (migration 014).
Four memory types (user/project/feedback/reference), three scopes
(global/workstream/user). Consolidate remember/recall/forget into two tools:
memory (action-based: save/search/delete/list) and recall (conversation
history only).

BM25 relevance scoring (extracted to turnstone/core/bm25.py) selects top-5
memories for system message injection based on conversation context.
Metacognitive prompting injects ephemeral nudges after corrections, tool
denials, workstream resume, and completion signals.

Scope isolation enforced: system message injection and nudge counts filtered
to visible memories only (global + current workstream + authenticated user).
User scope requires authentication. Content capped at 32KB. ILIKE/LIKE
metacharacters escaped in both backends.

113 new tests (2053 total).

* fix: CI failure + copilot review feedback

- Fix time.monotonic() cooldown: use None sentinel instead of 0.0
  default (monotonic clock starts at boot, not epoch — fresh CI
  runners have uptime < 300s so cooldown check always triggered)
- Catch sa.exc.IntegrityError specifically in upsert instead of
  broad Exception (copilot review)
- Preserve existing description/type on upsert when caller doesn't
  explicitly set them (copilot review)
- Add last_accessed + access_count columns to schema/migration for
  future LRU/LFU eviction support
2026-03-13 21:21:09 -07:00

47 lines
1.6 KiB
JSON

{
"name": "memory",
"description": "Persistent memory across sessions. Actions: 'save' stores a memory, 'search' finds memories by query, 'delete' removes a memory, 'list' shows all memories. Memories have a type (user/project/feedback/reference) and scope (global/workstream/user).",
"parameters": {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["save", "search", "delete", "list"],
"description": "Action to perform."
},
"name": {
"type": "string",
"description": "Memory identifier (required for 'save' and 'delete'). Short snake_case key."
},
"content": {
"type": "string",
"description": "Memory content (required for 'save')."
},
"description": {
"type": "string",
"description": "Short description for relevance matching (recommended for 'save')."
},
"type": {
"type": "string",
"enum": ["user", "project", "feedback", "reference"],
"description": "Memory type. Default: 'project'."
},
"scope": {
"type": "string",
"enum": ["global", "workstream", "user"],
"description": "Memory scope. Default: 'global'. Use 'workstream' for context private to this workstream, 'user' for context that follows the user across workstreams."
},
"query": {
"type": "string",
"description": "Search query (for 'search' action)."
},
"limit": {
"type": "integer",
"description": "Max results for 'search' or 'list'. Default: 20."
}
},
"required": ["action"]
},
"primary_key": "name"
}