Skip to main content

LlamaIndex integration for MemoryLayer.ai - persistent memory for LlamaIndex applications

Project description

MemoryLayer.ai LlamaIndex Integration

LlamaIndex integration for MemoryLayer.ai - Persistent memory for LlamaIndex applications.

Installation

pip install memorylayer-llamaindex

Quick Start

from llama_index.core.llms import ChatMessage, MessageRole
from llama_index.core.memory import ChatMemoryBuffer
from memorylayer_llamaindex import MemoryLayerChatStore

# Create the chat store connected to MemoryLayer
chat_store = MemoryLayerChatStore(
    base_url="http://localhost:61001",
    api_key="your-api-key",
    workspace_id="ws_123"
)

# Create ChatMemoryBuffer with persistent storage
memory = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store,
    chat_store_key="user_alice",
    token_limit=3000
)

# Store messages - they persist across application restarts!
memory.put(ChatMessage(role=MessageRole.USER, content="Hello! I'm learning Python."))
memory.put(ChatMessage(
    role=MessageRole.ASSISTANT,
    content="Great! Python is a wonderful language. What would you like to learn about?"
))

# Retrieve conversation history
history = memory.get()
for msg in history:
    print(f"[{msg.role.value}]: {msg.content}")

Features

  • LlamaIndex Native - Implements BaseChatStore interface for seamless integration
  • Persistent Memory - Chat history survives application restarts
  • Multi-Session Support - Isolated conversations per user/session via chat keys
  • Async Support - Full async/await API for high-performance applications
  • Agent Compatible - Works with LlamaIndex agents and chat engines
  • Type-safe - Full type hints with Pydantic models

Core Integration

ChatMemoryBuffer

The primary integration point is MemoryLayerChatStore with LlamaIndex's ChatMemoryBuffer:

from llama_index.core.memory import ChatMemoryBuffer
from memorylayer_llamaindex import MemoryLayerChatStore

chat_store = MemoryLayerChatStore(
    base_url="http://localhost:61001",
    api_key="your-api-key",
    workspace_id="ws_demo"
)

# Each user/session gets isolated memory via chat_store_key
memory = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store,
    chat_store_key="user_session_123",
    token_limit=4000
)

# Messages are automatically persisted
memory.put(ChatMessage(role=MessageRole.USER, content="Remember this fact"))
memory.put(ChatMessage(role=MessageRole.ASSISTANT, content="I'll remember that!"))

# Later, even after restart, retrieve full history
history = memory.get()

SimpleChatEngine

from llama_index.core.chat_engine import SimpleChatEngine
from llama_index.llms.openai import OpenAI

chat_store = MemoryLayerChatStore(
    base_url="http://localhost:61001",
    api_key="your-api-key",
    workspace_id="ws_demo"
)

memory = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store,
    chat_store_key="chat_session_1",
    token_limit=4000
)

llm = OpenAI(model="gpt-4o-mini")
chat_engine = SimpleChatEngine.from_defaults(
    memory=memory,
    llm=llm,
    system_prompt="You are a helpful assistant with persistent memory."
)

# Chat with persistent memory
response = chat_engine.chat("Hello! I'm Sarah, a data scientist.")
print(response)

# Later sessions will remember the conversation

FunctionAgent

from llama_index.core.agent.workflow import FunctionAgent
from llama_index.core.tools import FunctionTool
from llama_index.core.workflow import Context
from llama_index.llms.openai import OpenAI

chat_store = MemoryLayerChatStore(
    base_url="http://localhost:61001",
    api_key="your-api-key",
    workspace_id="ws_agents"
)

memory = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store,
    chat_store_key="agent_session_1",
    token_limit=8000
)

# Define tools
def get_time() -> str:
    """Get current time."""
    from datetime import datetime
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

tools = [FunctionTool.from_defaults(fn=get_time)]

# Create agent with persistent memory
llm = OpenAI(model="gpt-4o-mini")
agent = FunctionAgent(tools=tools, llm=llm)
ctx = Context(agent)

# Run agent - memory persists across interactions
response = await agent.run("What time is it?", ctx=ctx, memory=memory)

Direct ChatStore Operations

For fine-grained control, use MemoryLayerChatStore directly:

Set Messages

# Replace all messages for a key
chat_store.set_messages("user_123", [
    ChatMessage(role=MessageRole.SYSTEM, content="You are a helpful assistant."),
    ChatMessage(role=MessageRole.USER, content="Hello!"),
    ChatMessage(role=MessageRole.ASSISTANT, content="Hi there!")
])

Get Messages

# Retrieve all messages for a key
messages = chat_store.get_messages("user_123")
for msg in messages:
    print(f"[{msg.role.value}]: {msg.content}")

Add Message

# Add a single message
chat_store.add_message(
    "user_123",
    ChatMessage(role=MessageRole.USER, content="New message")
)

Delete Messages

# Delete all messages for a key
deleted = chat_store.delete_messages("user_123")

# Delete a specific message by index
deleted_msg = chat_store.delete_message("user_123", idx=2)

# Delete the last message
last_msg = chat_store.delete_last_message("user_123")

Get Keys

# List all chat keys in the store
keys = chat_store.get_keys()
print(f"Active conversations: {keys}")

Async Operations

All operations have async equivalents for high-performance applications:

import asyncio

async def async_example():
    chat_store = MemoryLayerChatStore(
        base_url="http://localhost:61001",
        api_key="your-api-key",
        workspace_id="ws_demo"
    )

    # Async set messages
    await chat_store.aset_messages("async_user", [
        ChatMessage(role=MessageRole.USER, content="Async hello!"),
        ChatMessage(role=MessageRole.ASSISTANT, content="Async hi!")
    ])

    # Async add message
    await chat_store.async_add_message(
        "async_user",
        ChatMessage(role=MessageRole.USER, content="Follow-up")
    )

    # Async get messages
    messages = await chat_store.aget_messages("async_user")

    # Async delete
    await chat_store.adelete_messages("async_user")

    # Async get keys
    keys = await chat_store.aget_keys()

asyncio.run(async_example())

Multi-Session Conversations

Each chat_store_key maintains isolated conversation history:

chat_store = MemoryLayerChatStore(
    base_url="http://localhost:61001",
    api_key="your-api-key",
    workspace_id="ws_demo"
)

# Separate memories for different users
alice_memory = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store,
    chat_store_key="user_alice"
)

bob_memory = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store,
    chat_store_key="user_bob"
)

# Alice's conversation
alice_memory.put(ChatMessage(role=MessageRole.USER, content="What's the weather?"))

# Bob's conversation (completely separate)
bob_memory.put(ChatMessage(role=MessageRole.USER, content="Help with Python code"))

# Each retrieves only their own history
alice_history = alice_memory.get()  # Only Alice's messages
bob_history = bob_memory.get()      # Only Bob's messages

Persistence Across Restarts

Messages stored via MemoryLayerChatStore persist in MemoryLayer's database:

# Session 1: Store messages
chat_store = MemoryLayerChatStore(
    base_url="http://localhost:61001",
    api_key="your-api-key",
    workspace_id="ws_demo"
)

memory = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store,
    chat_store_key="persistent_session"
)

memory.put(ChatMessage(role=MessageRole.USER, content="My favorite color is blue."))
memory.put(ChatMessage(role=MessageRole.ASSISTANT, content="Got it! I'll remember that."))

# === Application Restart ===

# Session 2: Messages are still there!
chat_store2 = MemoryLayerChatStore(
    base_url="http://localhost:61001",
    api_key="your-api-key",
    workspace_id="ws_demo"
)

memory2 = ChatMemoryBuffer.from_defaults(
    chat_store=chat_store2,
    chat_store_key="persistent_session"
)

history = memory2.get()
print(f"Retrieved {len(history)} messages from previous session")

Utility Functions

The package exports utility functions for custom integrations:

Message Conversion

from memorylayer_llamaindex import (
    chat_message_to_memory_payload,
    memory_to_chat_message,
    message_role_to_string,
    string_to_message_role
)

# Convert ChatMessage to MemoryLayer payload
msg = ChatMessage.from_str("Hello!", role=MessageRole.USER)
payload = chat_message_to_memory_payload(msg, key="user_123", index=0)
# payload = {"content": "Hello!", "type": "episodic", "tags": [...], ...}

# Convert MemoryLayer memory back to ChatMessage
memory = {"content": "Hello!", "metadata": {"role": "user", "message_index": 0}}
chat_msg = memory_to_chat_message(memory)

# Role conversions
role_str = message_role_to_string(MessageRole.ASSISTANT)  # "assistant"
role = string_to_message_role("user")  # MessageRole.USER

Helper Functions

from memorylayer_llamaindex import get_message_index, get_chat_key, CHAT_KEY_TAG_PREFIX

# Extract metadata from memories
memory = {"metadata": {"message_index": 5, "chat_key": "user_123"}}
index = get_message_index(memory)  # 5
key = get_chat_key(memory)         # "user_123"

# Tag prefix constant
print(CHAT_KEY_TAG_PREFIX)  # "llamaindex_chat_key:"

API Reference

MemoryLayerChatStore

Parameter Type Default Description
base_url str "http://localhost:61001" MemoryLayer API base URL
api_key str | None None API key for authentication
workspace_id str | None None Workspace ID for operations
timeout float 30.0 Request timeout in seconds

Sync Methods

Method Description
set_messages(key, messages) Replace all messages for a key
get_messages(key) Get all messages for a key
add_message(key, message) Add a single message
delete_messages(key) Delete all messages for a key
delete_message(key, idx) Delete message at index
delete_last_message(key) Delete the last message
get_keys() Get all chat keys

Async Methods

Method Description
aset_messages(key, messages) Async set messages
aget_messages(key) Async get messages
async_add_message(key, message) Async add message
adelete_messages(key) Async delete all messages
adelete_message(key, idx) Async delete at index
adelete_last_message(key) Async delete last message
aget_keys() Async get all keys

Examples

See the examples directory for complete working examples:

  • basic_chat_memory.py - Basic ChatMemoryBuffer usage, multi-session support, persistence, direct store operations
  • agent_with_memory.py - Agent integration, multi-turn conversations, async patterns, context retrieval

Development

Install Development Dependencies

cd oss/memorylayer-sdk-llamaindex-python
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"

Run Tests

pytest

Type Checking

mypy src/memorylayer_llamaindex

Linting

ruff check src/memorylayer_llamaindex
ruff format src/memorylayer_llamaindex

Requirements

  • Python 3.12+
  • memorylayer-client - MemoryLayer Python SDK
  • llama-index-core>=0.10.0 - LlamaIndex core library

License

Apache 2.0 License - see LICENSE file for details.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memorylayer_llamaindex-0.0.3.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memorylayer_llamaindex-0.0.3-py3-none-any.whl (5.5 kB view details)

Uploaded Python 3

File details

Details for the file memorylayer_llamaindex-0.0.3.tar.gz.

File metadata

  • Download URL: memorylayer_llamaindex-0.0.3.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for memorylayer_llamaindex-0.0.3.tar.gz
Algorithm Hash digest
SHA256 a7d5e6419382bdb35f291f5654012ddae5196cd19a6e141281a4d7c8f2d8bc0a
MD5 41168655706625ba055df19b48bdc06b
BLAKE2b-256 1d5681adce585bdb42e6c244a47bdc3eeb90229e09b8ebab825bb1a3393ba58e

See more details on using hashes here.

Provenance

The following attestation bundles were made for memorylayer_llamaindex-0.0.3.tar.gz:

Publisher: release.yml on scitrera/memorylayer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file memorylayer_llamaindex-0.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for memorylayer_llamaindex-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0c8a1751416ca8407ff02f95a29c928f9c644c27130af9509ad61e357a4c725e
MD5 14c0f319a93f107c1f9aeb6686d52b03
BLAKE2b-256 ae0d55385700e267a20b3600db4edeee0527de5ba23521487003e69a7cbe65d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for memorylayer_llamaindex-0.0.3-py3-none-any.whl:

Publisher: release.yml on scitrera/memorylayer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page