Skip to content

docs: Document cross-session conversation recall — session_search graduated from stub (PraisonAI PR #2187) #813

Description

@MervinPraison

Context

PraisonAI PR #2187 was merged into main (head SHA 69bbe908e7eaa467a1672c5c3ac1dfc79d4e75fc), fixing issue #2184.

It graduates session_search from a non-functional stub to a real cross-session conversation recall feature — a long-lived agent can now search its own past conversation transcripts ("what did we decide about the billing migration?"). Previously only distilled memory/knowledge was searchable; raw session transcripts in ~/.praisonai/sessions/*.json had no search.

Important

Per AGENTS.md folder-placement rules, the new page below MUST be created under docs/features/, never docs/concepts/ (concepts is human-approved only). docs.json entries go under the Features group.


Summary of SDK Changes (PR #2187)

Area SDK File Change
Session protocol src/praisonai-agents/praisonaiagents/session/protocols.py NEWSearchableSessionStoreProtocol, SessionHit, SessionSummary dataclasses
Default store src/praisonai-agents/praisonaiagents/session/store.py UPDATEDDefaultSessionStore.search(), .window(), .recent() implementations
Session tools src/praisonai-agents/praisonaiagents/tools/session_tools.py UPDATED — wired stub to real store with discovery / scroll / browse modes
Tool registry src/praisonai-agents/praisonaiagents/tools/__init__.py UPDATED — exports session_search, SessionTools, create_session_tools
Session module src/praisonai-agents/praisonaiagents/session/__init__.py UPDATED — exports new protocol/dataclasses

Notable details:

  • Dependency-free substring/keyword scan over stored JSON sessions — no new deps.
  • Backward compatible — existing SessionStoreProtocol is unchanged; SearchableSessionStoreProtocol is a separate runtime-checkable protocol.
  • Architecture note: a heavy FTS5/SQLite-backed store is a wrapper concern, left as a follow-up.

Documentation Plan

1. NEW — docs/features/cross-session-recall.mdx

Why: This is a brand-new user-facing capability with zero documentation. The existing docs/features/bot-default-tools.mdx still describes session_search as a "Placeholder only" (see Update #2 below).

Frontmatter:

---
title: "Cross-Session Recall"
sidebarTitle: "Session Search"
description: "Let agents search their own past conversations across sessions"
icon: "magnifying-glass-clock"
---

Agent-centric opening (Quick Start Step 1):

from praisonaiagents import Agent

agent = Agent(
    name="Gateway Assistant",
    instructions="Recall past conversations when the user asks 'what did we decide about X?'",
    tools=["session_search"]
)

agent.start("What did we decide about the billing migration?")

Quick Start Step 2 — Three shapes in one tool:

from praisonaiagents.tools import session_search

# 1. Discovery — find matching sessions with context around each hit
session_search(query="billing migration")

# 2. Scroll — read +/- N messages around an anchor message
session_search(session_id="abc-123", around_message_id="42", window=10)

# 3. Browse — most recent sessions ("what was I working on?")
session_search()

Hero Mermaid diagram (use standard palette):

graph LR
    subgraph "Cross-Session Recall"
        Q[💬 Agent Query] --> M{🔍 Mode?}
        M -->|query=...| D[📚 Discovery]
        M -->|session_id+anchor| S[📖 Scroll]
        M -->|no args| B[🗂️ Browse]
        D --> R[✅ Sessions + Context]
        S --> R
        B --> R
    end
    classDef query fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef mode fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef shape fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff
    class Q query
    class M mode
    class D,S,B shape
    class R result
Loading

Mode-decision diagram (help users pick a shape):

graph TD
    Q1["What do you want?"]
    Q1 -->|"Find a past discussion"| DISC["session_search(query='...')"]
    Q1 -->|"Read more around a hit"| SCRO["session_search(session_id, around_message_id)"]
    Q1 -->|"List recent sessions"| BROW["session_search()"]
    classDef q fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef a fill:#10B981,stroke:#7C90A0,color:#fff
    class Q1 q
    class DISC,SCRO,BROW a
Loading

User interaction flow (sequence diagram):

sequenceDiagram
    participant U as 👤 User
    participant A as 🤖 Agent
    participant T as 🔧 session_search
    participant S as 📁 Session Store
    U->>A: "What did we decide about billing?"
    A->>T: session_search(query="billing migration")
    T->>S: scan ~/.praisonai/sessions/*.json
    S-->>T: matching messages + score
    T-->>A: SessionHits with context windows
    A->>T: session_search(session_id="abc", around_message_id="42")
    T->>S: read session "abc"
    S-->>T: ±5 surrounding messages
    T-->>A: scrollable window
    A-->>U: "On 2026-06-10 we decided to migrate Stripe → ..."
Loading

session_search parameters table (extract verbatim from praisonaiagents/tools/session_tools.py):

Parameter Type Default Description
query str "" Free-text query for discovery mode
session_id str "" Session to read in scroll mode
around_message_id str "" Anchor message index (as string) for scroll mode
limit int 5 Maximum sessions/results to return
window int 5 Messages to include around a hit/anchor

Return shape — the tool returns a JSON string with one of three modes.

Discovery (query set):

{
  "success": true,
  "mode": "discovery",
  "query": "billing migration",
  "total_found": 2,
  "results": [
    {
      "session_id": "abc-123",
      "title": "Assistant",
      "when": "2026-06-10T14:32:00Z",
      "snippet": "…we agreed to migrate billing from Stripe…",
      "score": 4.0,
      "anchor_index": 12,
      "messages": [
        {"index": 7, "role": "user", "content": "...", "timestamp": "..."},
        {"index": 8, "role": "assistant", "content": "...", "timestamp": "..."}
      ]
    }
  ]
}

Scroll (session_id set, no query):

{
  "success": true,
  "mode": "scroll",
  "session_id": "abc-123",
  "around_message_id": "42",
  "messages": [
    {"index": 37, "role": "user", "content": "...", "timestamp": "..."}
  ]
}

Browse (no args):

{
  "success": true,
  "mode": "browse",
  "total_found": 3,
  "results": [
    {"session_id": "abc-123", "title": "Assistant", "when": "2026-06-22T18:00:00Z", "message_count": 24}
  ]
}

Underlying dataclasses (from praisonaiagents/session/protocols.py):

SessionHit:

Field Type Default Description
session_id str required The session that matched
title str "" Human-friendly title (agent name or first user message snippet)
when Optional[str] None updated_at or created_at timestamp
snippet str "" Short snippet centred on the first query match
score float 0.0 Match score (higher = better)
anchor_index int -1 Index of the best-matching message
messages List[Dict] [] Context window around the hit

SessionSummary:

Field Type Default Description
session_id str required Session identifier
title str "" Agent name or session id
when Optional[str] None Last update timestamp
message_count int 0 Number of messages in the session

SearchableSessionStoreProtocol (advanced — for users implementing custom stores):

Method Signature Description
search search(query, *, limit=5, window=5) -> List[SessionHit] Full-text search across stored sessions
window window(session_id, around_message_id=None, *, window=5) -> List[Dict] ±N messages around an anchor (most recent if anchor omitted/invalid)
recent recent(*, limit=10) -> List[SessionSummary] Most recently updated sessions

The protocol is runtime_checkable:

from praisonaiagents.session import (
    DefaultSessionStore,
    SearchableSessionStoreProtocol,
)

store = DefaultSessionStore()
assert isinstance(store, SearchableSessionStoreProtocol)

Must cover (page body):

  • What it does in one sentence: lets an agent search its own past conversation transcripts.
  • Three shapes of session_search: discovery / scroll / browse — with one short example each.
  • Where sessions live: ~/.praisonai/sessions/*.json (one JSON file per session).
  • Scoring (substring match = +2, per-term match = +1; ties broken by recency).
  • Snippet is centred on the first match and trimmed to ~120 chars with ellipses.
  • Backward compatibility: SessionStoreProtocol is unchanged; SearchableSessionStoreProtocol is a separate protocol implemented by the default store.
  • Limits / scale: the default scan is dependency-free; for very large session corpora, a wrapper FTS5/SQLite-backed store is the planned upgrade path (mention it as a follow-up; do not document a feature that doesn't exist).
  • Tools-registry usage: both tools=["session_search"] (string form for bots) and from praisonaiagents.tools import session_search (function form) are supported.

Common patterns:

  1. Gateway assistant recalling decisionssession_search(query="decision X") then scroll for context.
  2. "What was I working on?"session_search() (browse mode) at the start of a new session.
  3. Programmatic access from a custom store — direct calls to store.search(...), store.window(...), store.recent(...).

Best practices accordions (suggested):

  • Use small window (3–10) for fast scans; widen only when you need more context.
  • Treat scores as relative — they are heuristic, not probability-calibrated.
  • For multi-user deployments, scope sessions by session_id prefix (the search is per-store, not per-user out of the box).
  • A heavy FTS-backed store is the right answer at scale — swap it in via the protocol.

Related cards:

  • Memory (concepts) — distilled long-term memory (different from raw transcripts)
  • Bot Default Tools — where session_search fits in the opt-in tool list
  • Knowledge (concepts) — RAG over documents (also different from session recall)

2. UPDATE — docs/features/bot-default-tools.mdx

Why: This page currently lists session_search as a "Placeholder only" / "Stub implementation" in the Intentionally Excluded Tools section. After PR #2187 it is a real working tool — but it is still opt-in (not auto-injected). The wording must change so users aren't told it's a placeholder.

Existing problematic block (verbatim from the current file):

### Intentionally Excluded Tools

These tools are **NOT** auto-injected and require explicit opt-in:

| Tool | Reason | How to Enable |
|------|--------|---------------|
| `delegate_task` | Stub implementation | Add to `default_tools` manually |
| `session_search` | Placeholder only | Add to `default_tools` manually |

Replacement block to apply:

### Opt-In Tools (not auto-injected)

These tools are functional but require explicit opt-in:

| Tool | Reason | How to Enable |
|------|--------|---------------|
| `delegate_task` | Stub implementation | Add to `default_tools` manually |
| `session_search` | Cross-session conversation recall — opt in per bot | Add to `default_tools` manually, e.g. `default_tools=[..., "session_search"]`. See [Cross-Session Recall](/docs/features/cross-session-recall). |

Also add a brief mention of session_search to the "Tool Categories by Use Case" code block, e.g.:

# Gateway / long-lived assistant
config = BotConfig(default_tools=[
    "store_memory", "search_memory",
    "session_search",  # NEW — recall past conversations
])

Verify the section title change ("Intentionally Excluded" → "Opt-In Tools") reads naturally with the surrounding prose; tweak transitions accordingly.


3. UPDATE — docs.json

Register the new page under the Features group (never under Concepts). Expected entry:

"features/cross-session-recall"

Place it near the existing features/bot-default-tools entry so related tooling pages group together. Verify docs.json stays valid JSON after editing.


Writing Rules Recap (from AGENTS.md)

For the new page, the implementing agent must:

  • Open with a short (one-line) description; no filler intros
  • Agent-centric code example at the very top of Quick Start
  • Hero Mermaid diagram using the standard palette: #8B0000, #189AB4, #10B981, #F59E0B, #6366F1, white text (#fff), stroke #7C90A0
  • Simple imports only (from praisonaiagents import Agent, from praisonaiagents.tools import session_search) — no deep subpaths
  • <Steps> in Quick Start, <AccordionGroup> in Best Practices, <CardGroup> in Related
  • Configuration tables extracted verbatim from the SDK files listed below
  • Show a mode-decision diagram (three shapes can confuse first-time users)
  • Show a user-interaction sequence diagram
  • No forbidden phrases ("As you can see…", "It's important to note…", "Let's take a look at…")
  • Page lives under docs/features/never docs/concepts/
  • Register the page in docs.json under the Features group
  • Do not invent FTS5/SQLite-backed behaviour — only the default substring scan exists today

References

Exact SDK source files to read (in MervinPraison/PraisonAI at PR head)

  • src/praisonai-agents/praisonaiagents/session/protocols.pySearchableSessionStoreProtocol, SessionHit, SessionSummary
  • src/praisonai-agents/praisonaiagents/session/store.pyDefaultSessionStore.search / .window / .recent (around the "Cross-Session Recall (Issue #2184)" comment)
  • src/praisonai-agents/praisonaiagents/tools/session_tools.pysession_search function + SessionTools class
  • src/praisonai-agents/praisonaiagents/tools/__init__.py — exports
  • src/praisonai-agents/praisonaiagents/session/__init__.py — exports

Mirrored paths inside this docs repo (synced daily via update_repos.sh)

  • praisonaiagents/tools/session_tools.py — currently still on the old stub SHA b5188f7392ecbf3257ea0c17b503c8fc1d5e375b; will sync to the new implementation after the next update_repos.sh run. Verify against the source repo if the mirrored copy looks stale.

Existing docs that reference session_search (for context, must not contradict the new page)

  • docs/features/bot-default-tools.mdxUPDATE as described in section 2 above.

Reminder: only the default dependency-free scan exists today. A wrapper FTS5/SQLite-backed SessionStore is a planned follow-up — mention it as future work, do not document behaviour it doesn't have.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claudeTrigger Claude Code analysisdocumentationImprovements or additions to documentationenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions