Per-Chat Session Scope

Share one transcript across a group with sender attribution

In group chats, share one transcript across all participants — each message prefixed with the sender’s name.

python
from praisonaiagents import Agent

agent = Agent(
    name="session-agent",
    instructions="Maintain separate context per chat session.",
)
agent.start("This is a new session — remember nothing from before.")

The user messages in a group chat; everyone shares one transcript with sender names attached.

yaml
# gateway.yaml
channels:
  telegram:
    platform: telegram
    token: "${TELEGRAM_BOT_TOKEN}"
    session:
      session_scope: per_chat

agent:
  name: assistant
  instructions: "Help the group. Refer to participants by name."
  model: gpt-4o-mini
Diagram

per_user scope (default)

👤 User A

🗂️ Session A

👤 User B

🗂️ Session B

🤖 Agent

per_chat scope

👤 Alice

🗂️ Shared Session

👤 Bob

👤 Carol

🤖 Agent

Quick Start

  1. Enable per_chat scope in your gateway config
    yaml
    # gateway.yaml
    channels:
      telegram:
        platform: telegram
        token: "${TELEGRAM_BOT_TOKEN}"
        session:
          session_scope: per_chat
    
    agent:
      name: assistant
      instructions: "Help the group. Refer to participants by name."
      model: gpt-4o-mini

    Run with:

    bash
    praisonai gateway start gateway.yaml

    In a Telegram group, the agent now sees one shared transcript:

    [Alice] when is the launch?
    [Bob] next friday
    [Alice] cool, who's demoing?
  2. Customise the attribution template
    yaml
    channels:
      telegram:
        platform: telegram
        token: "${TELEGRAM_BOT_TOKEN}"
        session:
          session_scope: per_chat
          attribution: "[{sender} at {time}] "

    The attribution template supports two placeholders:

    • {sender} — the sender’s display name
    • {time} — current time in HH:MM format

    Result: [Alice at 14:32] when is the launch?


How It Works

Diagram
BobAgentSessionAdapterAliceBobAgentSessionAdapterAliceAgent sees full history: Alice’s Q, answer, Bob’s Q“when is the launch?”lookup(platform, account, chat_id)shared session found“[Alice] when is the launch?”“Next Friday.”“Next Friday.”“who’s demoing?”lookup(platform, account, chat_id)same shared session“[Bob] who’s demoing?”“Alice is demoing.”“Alice is demoing.”

The session key in per_chat mode is:

{platform}:acct:{account}:chat:{chat_id}:{thread_id}

This keeps different group chats and threads isolated from each other, even on the same platform.


per_user vs per_chat

Diagram
graph TB
    Start[New message arrives] --> IsDM{Is it a DM?}
    IsDM -->|Yes| PerUser[per_user key\nplatform:acct:X:user:user_id]
    IsDM -->|No — group/channel| Scope{session_scope setting}
    Scope -->|per_user (default)| PerUser
    Scope -->|per_chat| PerChat[per_chat key\nplatform:acct:X:chat:chat_id:thread_id]

    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef peruser fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef perchat fill:#189AB4,stroke:#7C90A0,color:#fff

    class IsDM,Scope decision
    class PerUser peruser
    class PerChat perchat

Configuration

Set these options under session: in your channel config:

OptionTypeDefaultDescription
session_scopestr"per_user""per_user" for isolated sessions (default) or "per_chat" for shared group sessions
attributionstr"[{sender}] "Template prefixed to each turn in per_chat scope. Supports {sender} and {time}
max_historyint100Maximum number of turns to keep in session history

Valid values for session_scope: per_user, per_chat. Any other value raises a validation error.


/new in Groups

The /new command clears the shared session for the whole group — not just the sender.

All seven supported adapters (telegram, slack, discord, whatsapp, email, linear, agentmail) thread chat_id through their reset handlers. A /new from inside a DM clears only that user’s private session, not any group session.

Alice: /new
Bot: ✅ Session cleared for this group.
Bob: what were we talking about?
Bot: I don't have any previous context — what would you like help with?

per_chat + observe = shared group memory

Pair session_scope: per_chat with group_policy: observe for the classic group-assistant experience: every message lands on the shared per-chat transcript, the bot only replies when @mentioned, and the reply sees the full recent conversation with [sender] attribution.

On its own, observe records passive turns under the sender’s own per_user key — still useful for solo group DMs, but not shared across participants. Adding per_chat routes those passive turns to the shared per-chat key that a later addressed turn reads from.

yaml
# gateway.yaml
channels:
  telegram:
    platform: telegram
    token: "${TELEGRAM_BOT_TOKEN}"
    group_policy: observe        # record unmentioned messages as context
    session:
      session_scope: per_chat    # share that context across the group

Best Practices

When to enable per_chat

Use per_chat when your group needs one coherent conversation thread — for example, a team planning bot, a group Q&A assistant, or a shared research helper. Keep per_user (the default) when each user needs their own private context, like a personal productivity or support bot added to a group.

Choose an attribution template

The default "[{sender}] " is clear and compact. Add {time} when timing context helps the agent reason about sequences of events:

yaml
attribution: "[{sender} at {time}] "

Set attribution: "" to disable attribution entirely — the agent sees messages without sender prefixes.

Avoid key collisions across accounts

The key includes account to namespace different bot accounts on the same platform. If you run two gateway bots on the same Telegram group with different tokens, each bot maintains its own independent shared session. No additional config is needed — this is automatic.

Watch the history budget in busy groups

A per_chat session accumulates turns from all participants. In active groups this fills max_history faster than a one-on-one conversation. Lower max_history or enable compaction to summarise older turns:

yaml
session:
  session_scope: per_chat
  max_history: 50
  compaction:
    enabled: true
    strategy: summarize

Related