Skip to main content
Register custom storage backends for conversations, knowledge, and state through a central registry.
from praisonaiagents import Agent, db

agent = Agent(
    name="Assistant",
    instructions="Persist conversations to MySQL",
    db=db(database_url="mysql://user:pass@localhost:3306/praisonai"),
    session_id="session-1",
)
agent.start("Hello — save this conversation")
The user chats with the agent; registered plugins persist conversations, knowledge, and state.

Quick Start

1

Simple Usage

Use a built-in backend via the registry:
from praisonai.persistence import create_conversation_store

store = create_conversation_store(
    "mysql",
    url="mysql://user:pass@localhost:3306/praisonai",
)
2

With Configuration

Register a custom backend at runtime:
from praisonai.persistence import get_default_registry

def my_store_factory(url=None, **kwargs):
    from my_pkg import MyConversationStore
    return MyConversationStore(url=url, **kwargs)

registry = get_default_registry("conversation")
registry.register("mybackend", my_store_factory, aliases=("mb",))
store = registry.create("mb", url="proto://host")
CONVERSATION_STORES, KNOWLEDGE_STORES, and STATE_STORES are still importable from praisonai.persistence.registry for backward compatibility — they are now lazy attributes that build on first access via __getattr__. New code should prefer get_default_registry(kind) for clarity.
Package it as an entry point in pyproject.toml:
[project.entry-points."praisonai.conversation_stores"]
mybackend = "my_pkg.factory:create_store"

How It Works

No import-time cost. Importing praisonai.persistence.registry no longer walks Python entry points or registers the ~40 built-in loaders as a side effect — each kind’s registry is built lazily the first time you call get_default_registry(kind) (or reference the legacy *_STORES names). import praisonai is now safe to run in tests, notebooks, and multi-tenant runtimes without side effects.
Three global registries cover each storage kind:
RegistryEntry-point groupPurpose
CONVERSATION_STORESpraisonai.conversation_storesChat history and sessions
KNOWLEDGE_STORESpraisonai.knowledge_storesVector databases and RAG
STATE_STORESpraisonai.state_storesApplication state and cache

Multi-tenant isolation

All three factory functions accept an injected registry= — pass your own StoreRegistry to keep tenant registrations from leaking into the process-default registry.
from praisonai.persistence import StoreRegistry, create_conversation_store

def tenant_a_factory(url=None, **kwargs):
    from my_pkg import MyConversationStore
    return MyConversationStore(url=url, **kwargs)

tenant_a = StoreRegistry("conversation", "praisonai.conversation_stores")
tenant_a.register("mystore", tenant_a_factory)

store = create_conversation_store(
    "mystore",
    url="proto://host",
    registry=tenant_a,   # scoped — does not touch the process default
)
Same shape for create_knowledge_store(..., registry=) and create_state_store(..., registry=). See Registry Dependency Injection for the wider pattern.

Configuration Options

StoreRegistry API

Third-party backend authors register plugins via the same three entry-point groups (praisonai.conversation_stores / praisonai.knowledge_stores / praisonai.state_stores). Lazy loading means the entry-point scan runs on first use of that kind only, not on every import praisonai.
MethodSignatureDescription
registerregister(name, factory, *, aliases=())Register a backend factory with optional aliases
createcreate(name, **kwargs)Create a store instance by name or alias
list_registered() -> list[str]All registered backend names
list_aliases() -> dict[str, str]Alias → canonical name mappings
get_default_registryget_default_registry(kind: str) -> StoreRegistryReturn the process-default registry for "conversation" / "knowledge" / "state", building it lazily on first call. Prefer DI (registry=) in library code.

Built-in conversation backends

postgres, async_postgres, mysql, async_mysql, sqlite, sync_sqlite, async_sqlite, json, singlestore, supabase, surrealdb, turso Common aliases: neon, cockroachdb, crdbpostgres; aiomysqlasync_mysql; libsqlturso.

Built-in knowledge backends

chroma, qdrant, pinecone, weaviate, lancedb, milvus, pgvector, redis, cassandra, clickhouse, and others.

Built-in state backends

redis, dynamodb, firestore, mongodb, async_mongodb, upstash, memory, gcs

Best Practices

Follow built-in backends — import heavy dependencies inside the factory function, not at module level.
Register short aliases (mb, pg) alongside canonical names for easier CLI and config usage.
Factory functions should raise clear errors with connection hints — the registry lists available backends on ValueError.
Registries use threading.Lock — factory functions should also be safe for concurrent creation.

Database Persistence

Overview of all persistence backends

Framework Adapter Plugins

Plugin system for multi-agent frameworks