Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.praison.ai/llms.txt

Use this file to discover all available pages before exploring further.

Cross-platform sessions let one user keep a single conversation across every messaging platform.
from praisonai.bots import BotOS
from praisonaiagents import Agent
from praisonaiagents.session import FileIdentityResolver

agent = Agent(name="assistant", instructions="Be helpful.")

resolver = FileIdentityResolver()                        # ~/.praisonai/identity.json
resolver.link("telegram", "12345",       "alice")
resolver.link("discord",  "snowflake-1", "alice")

BotOS(
    agent=agent,
    platforms=["telegram", "discord"],
    identity_resolver=resolver,
).run()

How It Works

Quick Start

1

One platform, one user

from praisonai.bots import Bot
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="Be helpful.")
bot = Bot("telegram", agent=agent)
await bot.start()
2

Two platforms, one user

from praisonai.bots import BotOS
from praisonaiagents import Agent
from praisonaiagents.session import FileIdentityResolver

agent = Agent(name="assistant", instructions="Be helpful.")

resolver = FileIdentityResolver()
resolver.link("telegram", "12345", "alice")
resolver.link("discord", "snowflake-1", "alice")

botos = BotOS(
    agent=agent,
    platforms=["telegram", "discord"],
    identity_resolver=resolver,
)
await botos.start()
3

In-process testing / ephemeral

from praisonai.bots import BotOS
from praisonaiagents import Agent
from praisonaiagents.session import InMemoryIdentityResolver

agent = Agent(name="assistant", instructions="Be helpful.")

resolver = InMemoryIdentityResolver()  # Ephemeral for tests
resolver.link("telegram", "12345", "alice")
resolver.link("discord", "snowflake-1", "alice")

botos = BotOS(
    agent=agent,
    platforms=["telegram", "discord"],
    identity_resolver=resolver,
)

Choosing Your Resolver

SessionContext for Tools

Any tool the agent calls can read who is messaging:
from praisonaiagents import Agent
from praisonaiagents.session import get_session_context

def whoami() -> str:
    ctx = get_session_context()
    return f"You are {ctx.user_name or ctx.user_id} on {ctx.platform}"

agent = Agent(name="assistant", instructions="Use whoami when asked.", tools=[whoami])

SessionContext Fields

FieldTypeDescription
platformstr"telegram", "discord", "slack", …
chat_idstrPlatform chat / channel id
chat_namestrHuman-readable channel name
thread_idstrThread / topic id (Slack threads, Telegram topics)
user_idstrRaw platform user id
user_namestrDisplay name
unified_user_idstrResult of IdentityResolver.resolve()
Use set_session_context / clear_session_context for advanced custom adapters. Returns a token; reset in a finally block.

Mirror for Outbound Deliveries

Cron jobs, scheduled deliveries, and cross-platform replies need to mirror the assistant’s outbound message into the user’s history:
from praisonai.bots import mirror_to_session

# After sending a notification programmatically
mirror_to_session(
    session_mgr=bot._session,
    user_id="alice",
    message_text="Reminder: your standup is in 5 minutes.",
    source_label="cron",
)

Parameters

ParameterTypeDescription
session_mgrBotSessionManagerSession manager instance
user_idstrUnified user ID
message_textstrMessage content to mirror
source_labelstrSource identifier ("cron", "web", "cross_platform")
metadatadictOptional extra metadata
lockthreading.RLockOptional lock for synchronization
Errors are swallowed and logged — a mirror failure must never break the outbound delivery itself.

Storage & Privacy

FileIdentityResolver defaults to ~/.praisonai/identity.json (override via PRAISONAI_IDENTITY_PATH env var or constructor path=). File is written atomically and chmod 0o600.
Identity links are explicit and opt-in. No automatic linking — wire the resolver only after a verified DM-pairing flow confirms the same human controls both accounts.
Without a resolver, the legacy bot_{platform}_{user_id} storage key is preserved bit-for-bit — fully backward compatible.

Best Practices

For production single-host bots, FileIdentityResolver provides persistent storage with atomic writes and proper file permissions.
from praisonaiagents.session import FileIdentityResolver

resolver = FileIdentityResolver()  # ~/.praisonai/identity.json
For multi-process/multi-host deployments, back it with SQLite, Redis, or a database:
from praisonaiagents.session import IdentityResolverProtocol

class DatabaseIdentityResolver:
    def resolve(self, platform: str, platform_user_id: str) -> str:
        # Query your database
        pass
    
    def link(self, platform: str, platform_user_id: str, unified_user_id: str) -> None:
        # Store in your database
        pass
Never auto-link based on display name. Always require a DM-verified pairing flow:
# After DM verification succeeds
resolver.link("telegram", telegram_user_id, verified_unified_id)
resolver.link("discord", discord_user_id, verified_unified_id)
Instead of os.environ, read SessionContext — concurrent message handlers won’t trample each other:
def get_user_platform() -> str:
    ctx = get_session_context()
    return ctx.platform  # Thread-safe, context-aware

BotOS

Multi-platform bot orchestrator

Messaging Bots

Platform-specific bot guides