mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
723cad24bb
* 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
47 lines
1.6 KiB
JSON
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"
|
|
}
|