[MEMPALACE][MP-3] Session scratchpad — ephemeral context that survives tool hops #370

Open
opened 2026-04-07 17:02:40 +00:00 by perplexity · 1 comment
Member

Part of epic #367 | Depends on #369

Why

Agents lose context between tool calls. When Timmy runs a search, processes results, then needs to act on them, the intermediate findings evaporate. The session scratchpad (L2 in the retrieval order) solves this by providing a lightweight, session-scoped scratch space that persists across tool hops but doesn't pollute the long-term palace.

This is how humans use working memory — you hold a phone number in your head long enough to dial it, then let it go.

Design

Scratchpad Structure

session_scratchpad/
  {session_id}.json

Each entry:

{
  "session_id": "abc-123",
  "created": "2025-01-15T10:00:00Z",
  "ttl": 3600,
  "entries": [
    {
      "key": "last_search_results",
      "value": "...",
      "tool_origin": "web_search",
      "timestamp": "2025-01-15T10:05:00Z"
    }
  ]
}

Lifecycle

  1. Created on first tool call of a session
  2. Entries appended after each tool return
  3. Queried at L2 in retrieval chain (after palace rooms, before artifact retrieval)
  4. Expired after TTL (default 1 hour) or explicit session end
  5. Never promoted to palace automatically — that's MP-4's job

Key Behaviors

  • Write-append only during session (no overwrites)
  • Read at L2 in retrieval order from #369
  • Auto-expire — no garbage collection needed
  • Selective promotion — agent can explicitly flag entries for palace storage

Acceptance Criteria

  • SessionScratchpad class with init/append/query/expire methods
  • Entries persist across tool calls within same session
  • L2 retrieval integration with enforcer from #369
  • TTL-based auto-expiration (configurable, default 1hr)
  • No automatic promotion to long-term palace
  • Unit tests: write → read → expire cycle
  • Integration test: multi-tool-hop scenario retains context
Part of epic #367 | Depends on #369 ## Why Agents lose context between tool calls. When Timmy runs a search, processes results, then needs to act on them, the intermediate findings evaporate. The session scratchpad (L2 in the retrieval order) solves this by providing a lightweight, session-scoped scratch space that persists across tool hops but doesn't pollute the long-term palace. This is how humans use working memory — you hold a phone number in your head long enough to dial it, then let it go. ## Design ### Scratchpad Structure ``` session_scratchpad/ {session_id}.json ``` Each entry: ```json { "session_id": "abc-123", "created": "2025-01-15T10:00:00Z", "ttl": 3600, "entries": [ { "key": "last_search_results", "value": "...", "tool_origin": "web_search", "timestamp": "2025-01-15T10:05:00Z" } ] } ``` ### Lifecycle 1. Created on first tool call of a session 2. Entries appended after each tool return 3. Queried at L2 in retrieval chain (after palace rooms, before artifact retrieval) 4. Expired after TTL (default 1 hour) or explicit session end 5. **Never** promoted to palace automatically — that's MP-4's job ### Key Behaviors - **Write-append only** during session (no overwrites) - **Read at L2** in retrieval order from #369 - **Auto-expire** — no garbage collection needed - **Selective promotion** — agent can explicitly flag entries for palace storage ## Acceptance Criteria - [ ] `SessionScratchpad` class with init/append/query/expire methods - [ ] Entries persist across tool calls within same session - [ ] L2 retrieval integration with enforcer from #369 - [ ] TTL-based auto-expiration (configurable, default 1hr) - [ ] No automatic promotion to long-term palace - [ ] Unit tests: write → read → expire cycle - [ ] Integration test: multi-tool-hop scenario retains context
Author
Member

PR #380 provides the sovereign backend that closes the scratchpad story.

The scratchpad code (scratchpad.py) already exists on main. Its promote_to_palace() function currently shells out to the mempalace CLI — which requires ONNX and a hardcoded binary path.

With sovereign_store.py (PR #380), the remaining wiring is:

# In scratchpad.py:promote_to_palace(), replace:
#   subprocess.run([bin_path, "store", room, drawer, content])
# With:
#   from .sovereign_store import SovereignStore
#   from .promotion import promote
#   store = SovereignStore()
#   result = promote(content, store, session_id, key, room=room)

This is a ~10-line change once PR #380 is merged.

PR #380 provides the sovereign backend that closes the scratchpad story. The scratchpad code (`scratchpad.py`) already exists on main. Its `promote_to_palace()` function currently shells out to the `mempalace` CLI — which requires ONNX and a hardcoded binary path. With `sovereign_store.py` (PR #380), the remaining wiring is: ```python # In scratchpad.py:promote_to_palace(), replace: # subprocess.run([bin_path, "store", room, drawer, content]) # With: # from .sovereign_store import SovereignStore # from .promotion import promote # store = SovereignStore() # result = promote(content, store, session_id, key, room=room) ``` This is a ~10-line change once PR #380 is merged.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Timmy_Foundation/timmy-config#370