Skip to main content
An agent can now search its own past conversation transcripts — asking “what did we decide about the billing migration?” across every stored session.

Quick Start

1

Add session_search to an agent

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?")
2

Call the three shapes directly

from praisonaiagents.tools import session_search

# 1. Discovery — find sessions matching a keyword
session_search(query="billing migration")

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

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

How It Works

Sessions live at ~/.praisonai/sessions/*.json — one JSON file per session. The default search is a dependency-free substring/keyword scan with no extra setup required. Picking the right shape:

Configuration Options

session_search Parameters

ParameterTypeDefaultDescription
querystr""Free-text query for discovery mode
session_idstr""Session to read in scroll mode
around_message_idstr""Anchor message index (as string) for scroll mode
limitint5Maximum sessions/results to return
windowint5Messages to include around a hit/anchor

Return Shapes

Returned when query is 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": "..."}
      ]
    }
  ]
}

Scoring

Discovery mode scores hits using keyword matching:
Match typeScore added
Exact substring match+2 per message
Per-term keyword match+1 per term per message
Ties are broken by recency (updated_at descending). Scores are heuristic — treat them as relative rankings, not probabilities. Snippets are centred on the first match and trimmed to ~120 characters with ellipses.

Common Patterns

Gateway assistant recalling a past decision

from praisonaiagents.tools import session_search
import json

# Step 1: find the session
result = json.loads(session_search(query="billing migration"))
if result["success"] and result["results"]:
    hit = result["results"][0]
    anchor = str(hit["anchor_index"])
    session_id = hit["session_id"]

    # Step 2: read more context around the hit
    context = json.loads(session_search(
        session_id=session_id,
        around_message_id=anchor,
        window=10
    ))
    print(context["messages"])

”What was I working on?” at the start of a new session

from praisonaiagents import Agent

agent = Agent(
    name="Daily Assistant",
    instructions="Start each session by reviewing what was worked on recently.",
    tools=["session_search"]
)

agent.start("Give me a quick summary of what I worked on yesterday.")

Programmatic access via the store directly

from praisonaiagents.session.store import get_default_session_store
from praisonaiagents.session import SearchableSessionStoreProtocol

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

# Discovery
hits = store.search("billing migration", limit=5, window=5)
for hit in hits:
    print(hit.session_id, hit.snippet)

# Scroll
messages = store.window("abc-123", around_message_id="42", window=5)

# Browse
summaries = store.recent(limit=10)
for s in summaries:
    print(s.session_id, s.message_count)

Best Practices

Use window=3 to window=5 for discovery. Widen only when you need more surrounding context after finding a hit — use scroll mode for that.
Scores are heuristic keyword counts, not probability-calibrated relevance scores. A score of 4.0 beats 2.0 but says nothing absolute. Always let the agent reason about the returned snippets.
The default search is per-store, not per-user. In multi-user deployments, prefix session_id values with a user identifier (e.g. user_42_session_xyz) and search within those sessions explicitly.
The default dependency-free substring scan works well for personal agents with hundreds of sessions. For large deployments, a wrapper FTS5/SQLite-backed store implementing SearchableSessionStoreProtocol is the planned upgrade path — swap it in without changing agent code.

Advanced: SearchableSessionStoreProtocol

The default store implements SearchableSessionStoreProtocol, a separate runtime_checkable protocol that adds search to any session store backend.
from praisonaiagents.session import SearchableSessionStoreProtocol
from praisonaiagents.session.store import get_default_session_store

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

Protocol Methods

MethodSignatureDescription
searchsearch(query, *, limit=5, window=5) -> List[SessionHit]Keyword scan across all stored sessions
windowwindow(session_id, around_message_id=None, *, window=5) -> List[Dict]±N messages around an anchor; uses most recent if anchor omitted
recentrecent(*, limit=10) -> List[SessionSummary]Most recently updated sessions

SessionHit Fields

FieldTypeDefaultDescription
session_idstrrequiredThe session that matched
titlestr""Agent name or first user message snippet
whenOptional[str]Noneupdated_at or created_at timestamp
snippetstr""Short snippet centred on the first match
scorefloat0.0Match score (higher = better)
anchor_indexint-1Index of the best-matching message
messagesList[Dict][]Context window around the hit

SessionSummary Fields

FieldTypeDefaultDescription
session_idstrrequiredSession identifier
titlestr""Agent name or session id
whenOptional[str]NoneLast update timestamp
message_countint0Number of messages in the session
SessionStoreProtocol (the core persistence contract) is unchanged and backward compatible. SearchableSessionStoreProtocol is an additive, separately runtime-checkable protocol.

Bot Default Tools

Where session_search fits in the opt-in tool list for bots

Session Store

How sessions are persisted in ~/.praisonai/sessions/

Memory

Distilled long-term memory (different from raw session transcripts)

Knowledge

RAG over documents (also different from session recall)