Skip to content

Repository files navigation

chatbot-memory

Conversation-isolated memory for chatbot turns inside a single brain. Messages are text chunks tagged by conversation_id; rolling summaries and per-user preferences live as structured rows. The chatbot plugin wires these hooks automatically when this package is present as plugins/chatbot-memory.

Registry name chatbot-memory-single-brain
Install / folder id chatbot-memory
Version 1.0.0
BrainAPI >=2.13.0
Route prefix /conversations
Celery task chatbot_memory.update_conversation_after_message
Queue chatbot_memory

Product docs: Chatbot memory.

Ideal for “one brain per user or tenant, many conversation threads.” Isolation is by conversation_id (and optional user_id) within one brain_id — not a brain per chat.

Install

Clone into the directory name the chatbot plugin expects:

git clone https://github.com/Lumen-Labs/brainapi-plugin-chatbot-memory.git plugins/chatbot-memory

Registry name is the manifest name:

./bin/brainapi install chatbot-memory-single-brain
# then ensure the folder is plugins/chatbot-memory so chatbot can detect it

Restart the API and the Celery worker. The worker must consume queue chatbot_memory or meta/preferences will not update after saves.

How it works

POST /conversations/messages
  (or chatbot inference with conversation_id)
        │
        ▼
  save text chunk
  metadata: role, conversation_id, kind=chatbot_message
        │
        ▼
  Celery: update meta summary + user preferences
        │
        ▼
  GET .../context → last messages + meta + preferences
  • While the conversation summary stays under SUMMARY_CTX_MAX_LENGTH (20 000 characters), meta is an id→text map of recent turns.
  • When it overflows, an updater agent compresses the summary and can emit observations.
  • User preferences are updated asynchronously when user_id is present on the saved chunk. The HTTP POST /conversations/messages body does not include user_id; chatbot inference does, via the save_chatbot_memory_message hook.

KG enrichment from updater observations is currently disabled in code. Summaries and preferences still persist.

Chatbot auto-wiring

On register, this plugin sets:

  • context.save_chatbot_memory_message
  • context.get_chatbot_memory_conversation_context
  • context.adapters.conversation_meta
  • context.adapters.user_preferences

The chatbot plugin detects this package by directory name chatbot-memory.

API

All routes use normal BrainAPI auth and brain scoping (BrainPAT + brain id).

Save a message

POST /conversations/messages

{
  "message": "Hello",
  "role": "user",
  "conversation_id": "conv-123"
}

Response includes the saved text chunk and enqueues the async meta/preferences updater.

List conversation metadata

GET /conversations/meta?limit=100&skip=0

Returns { data: ConversationMeta[], total }.

Conversation meta CRUD

Method Path Notes
POST /conversations/{conversation_id}/meta Body { "summary": { "...": "..." } }
GET /conversations/{conversation_id}/meta 404 if missing
PUT /conversations/{conversation_id}/meta 404 if missing; same body as POST

ConversationMeta: { conversation_id: string, summary: Record<string, string> }.

List messages

GET /conversations/{conversation_id}/messages?limit=100&skip=0

Ordered turns with id, message, role, conversation_id, inserted_at.

Conversation context pack

GET /conversations/{conversation_id}/context

Returns meta, preferences (only if the controller is called with user_id — the HTTP route currently does not take user_id), and up to 10 last_messages. Chatbot inference calls the controller directly with user_id.

User preferences

GET /conversations/{user_id}/preferences

Loads the user_preferences structured row for that user in the brain (empty/null if never written).

Data model

Kind Storage Discriminator
Chat turns Text chunks metadata.kind = chatbot_message, metadata.conversation_id
Conversation summary Structured data types: [conversation_meta]
User preferences Structured data types: [user_preferences]

Use with the chatbot plugin

curl -X POST "$BRAINAPI_URL/chatbot/inference" \
  -H "Content-Type: application/json" \
  -H "BrainPAT: $BRAINPAT_TOKEN" \
  -H "X-Brain-ID: example01" \
  -d '{
    "model": "openai::gpt-4o-mini",
    "input": "What did we decide last time?",
    "conversation_id": "conv-123",
    "user_id": "user-456",
    "stream": false
  }'

With both plugins loaded, that call loads memory context, saves the user turn, generates a reply (optionally with MCP tools), and saves the agent turn.

Ops notes

  • Worker must listen on queue chatbot_memory.
  • Do not point this at LoCoMo/BEAM eval brains unless you intend to mix chat memory into those graphs.
  • Folder name must stay chatbot-memory for chatbot detection.

Layout

chatbot-memory/
  plugin.yaml
  main.py
  routes/conversations.py
  controllers/conversations.py
  adapters/conversations.py
  agents/updater.py
  prompts/updater.py
  constants/conversations.py
  workers/tasks.py
  workers/celery.py          # Queue("chatbot_memory")

Publishing

Pushes to main publish to the BrainAPI registry via GitHub Actions.

License

Apache License, Version 2.0. See LICENSE.

Related

About

BrainAPI plugin: store isolated chatbot conversations as memories in a single brain.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages