You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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/, neverdocs/concepts/ (concepts is human-approved only). docs.json entries go under the Features group.
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):
frompraisonaiagentsimportAgentagent=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:
frompraisonaiagents.toolsimportsession_search# 1. Discovery — find matching sessions with context around each hitsession_search(query="billing migration")
# 2. Scroll — read +/- N messages around an anchor messagesession_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.
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:
Gateway assistant recalling decisions — session_search(query="decision X") then scroll for context.
"What was I working on?" — session_search() (browse mode) at the start of a new session.
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 assistantconfig=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/ — neverdocs/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
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.mdx — UPDATE 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.
Context
PraisonAI PR #2187 was merged into
main(head SHA69bbe908e7eaa467a1672c5c3ac1dfc79d4e75fc), fixing issue #2184.It graduates
session_searchfrom 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/*.jsonhad no search.Important
Per
AGENTS.mdfolder-placement rules, the new page below MUST be created underdocs/features/, neverdocs/concepts/(concepts is human-approved only).docs.jsonentries go under the Features group.Summary of SDK Changes (PR #2187)
src/praisonai-agents/praisonaiagents/session/protocols.pySearchableSessionStoreProtocol,SessionHit,SessionSummarydataclassessrc/praisonai-agents/praisonaiagents/session/store.pyDefaultSessionStore.search(),.window(),.recent()implementationssrc/praisonai-agents/praisonaiagents/tools/session_tools.pysrc/praisonai-agents/praisonaiagents/tools/__init__.pysession_search,SessionTools,create_session_toolssrc/praisonai-agents/praisonaiagents/session/__init__.pyNotable details:
SessionStoreProtocolis unchanged;SearchableSessionStoreProtocolis a separate runtime-checkable protocol.Documentation Plan
1. NEW —
docs/features/cross-session-recall.mdxWhy: This is a brand-new user-facing capability with zero documentation. The existing
docs/features/bot-default-tools.mdxstill describessession_searchas a "Placeholder only" (see Update #2 below).Frontmatter:
Agent-centric opening (Quick Start Step 1):
Quick Start Step 2 — Three shapes in one tool:
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 resultMode-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 aUser 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 → ..."session_searchparameters table (extract verbatim frompraisonaiagents/tools/session_tools.py):querystr""session_idstr""around_message_idstr""limitint5windowint5Return shape — the tool returns a JSON string with one of three modes.
Discovery (
queryset):{ "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_idset, noquery):{ "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:session_idstrtitlestr""whenOptional[str]Noneupdated_atorcreated_attimestampsnippetstr""scorefloat0.0anchor_indexint-1messagesList[Dict][]SessionSummary:session_idstrtitlestr""whenOptional[str]Nonemessage_countint0SearchableSessionStoreProtocol(advanced — for users implementing custom stores):searchsearch(query, *, limit=5, window=5) -> List[SessionHit]windowwindow(session_id, around_message_id=None, *, window=5) -> List[Dict]recentrecent(*, limit=10) -> List[SessionSummary]The protocol is
runtime_checkable:Must cover (page body):
session_search: discovery / scroll / browse — with one short example each.~/.praisonai/sessions/*.json(one JSON file per session).…ellipses.SessionStoreProtocolis unchanged;SearchableSessionStoreProtocolis a separate protocol implemented by the default store.tools=["session_search"](string form for bots) andfrom praisonaiagents.tools import session_search(function form) are supported.Common patterns:
session_search(query="decision X")then scroll for context.session_search()(browse mode) at the start of a new session.store.search(...),store.window(...),store.recent(...).Best practices accordions (suggested):
window(3–10) for fast scans; widen only when you need more context.session_idprefix (the search is per-store, not per-user out of the box).Related cards:
session_searchfits in the opt-in tool list2. UPDATE —
docs/features/bot-default-tools.mdxWhy: This page currently lists
session_searchas 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):
Replacement block to apply:
Also add a brief mention of
session_searchto the "Tool Categories by Use Case" code block, e.g.:Verify the section title change ("Intentionally Excluded" → "Opt-In Tools") reads naturally with the surrounding prose; tweak transitions accordingly.
3. UPDATE —
docs.jsonRegister the new page under the Features group (never under Concepts). Expected entry:
Place it near the existing
features/bot-default-toolsentry so related tooling pages group together. Verifydocs.jsonstays valid JSON after editing.Writing Rules Recap (from
AGENTS.md)For the new page, the implementing agent must:
#8B0000,#189AB4,#10B981,#F59E0B,#6366F1, white text (#fff), stroke#7C90A0from praisonaiagents import Agent,from praisonaiagents.tools import session_search) — no deep subpaths<Steps>in Quick Start,<AccordionGroup>in Best Practices,<CardGroup>in Relateddocs/features/— neverdocs/concepts/docs.jsonunder the Features groupReferences
69bbe908e7eaa467a1672c5c3ac1dfc79d4e75fcsession_searchtool PraisonAI#2184Exact SDK source files to read (in
MervinPraison/PraisonAIat PR head)src/praisonai-agents/praisonaiagents/session/protocols.py—SearchableSessionStoreProtocol,SessionHit,SessionSummarysrc/praisonai-agents/praisonaiagents/session/store.py—DefaultSessionStore.search/.window/.recent(around the "Cross-Session Recall (Issue #2184)" comment)src/praisonai-agents/praisonaiagents/tools/session_tools.py—session_searchfunction +SessionToolsclasssrc/praisonai-agents/praisonaiagents/tools/__init__.py— exportssrc/praisonai-agents/praisonaiagents/session/__init__.py— exportsMirrored paths inside this docs repo (synced daily via
update_repos.sh)praisonaiagents/tools/session_tools.py— currently still on the old stub SHAb5188f7392ecbf3257ea0c17b503c8fc1d5e375b; will sync to the new implementation after the nextupdate_repos.shrun. 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.mdx— UPDATE as described in section 2 above.Reminder: only the default dependency-free scan exists today. A wrapper FTS5/SQLite-backed
SessionStoreis a planned follow-up — mention it as future work, do not document behaviour it doesn't have.