Skip to content

Brains

Updated View as Markdown

A brain is a named collection of knowledge packs. Instead of listing pack IDs on every chat request, you group the packs once under a brain and attach the whole set with a single brain_id. A user might have one brain for their company handbook, another for a product catalog — each a stable bundle they can point a conversation at.

A brain owns nothing on its own. It is just a name plus a list of which packs are in it. Packs go in and out, and the brain uses whatever packs are in it at the moment of the request. The documents, their ingestion, and their access rules all still live on the packs themselves (see Knowledge Packs).

Think of it like a playlist. The songs (packs) exist independently; a playlist (brain) just references them in one place. Deleting a playlist never deletes the songs, and the same song can sit on many playlists.

Where that metaphor breaks down: a brain only points at its packs — it never copies them. If a pack is deleted after you add it, the brain simply stops returning it, and there is nothing left behind to clean up.

flowchart LR
    subgraph Build["Assemble once"]
        direction TB
        B["Create a brain<br/>name · description"] --> M["Add knowledge packs<br/>POST /brains/{id}/knowledge-packs"]
    end
    subgraph Use["Every chat request"]
        direction TB
        R["POST /v1/chat/completions<br/>brain_id"] --> D["Resolve brain → its pack IDs"]
        D --> C["Hybrid search + inject as<br/>Relevant Document Context"]
    end
    M -.->|"brain now holds N packs"| R

    style B fill:#f0f9ff,stroke:#3b82f6,color:#181818
    style M fill:#ecfdf5,stroke:#10b981,color:#181818
    style R fill:#f0f9ff,stroke:#3b82f6,color:#181818
    style D fill:#e6f4ff,stroke:#0a99ff,color:#181818
    style C fill:#ecfdf5,stroke:#10b981,color:#181818

All brain endpoints require authentication. User-scoped endpoints (/brains) accept either a user Bearer token from Truememory Auth, or the calling app’s service token plus X-On-Behalf-Of: <user_id> when your backend proxies for a user. Admin endpoints (/admin/brains/*) require the service token or an admin user token — see Admin endpoints.

Using a brain in a chat request

This is the whole point of a brain. On a /v1/chat/completions request, pass brain_id (or brain_ids for several at once):

POST https://your-tie-host/v1/chat/completions
Authorization: Bearer $TOKEN
Content-Type: application/json

{
  "model": "anthropic/claude-sonnet-4-5",
  "messages": [
    { "role": "user", "content": "What's our refund window for annual plans?" }
  ],
  "brain_id": "b1a2c3..."
}

Truememory resolves the brain to the pack IDs it currently holds, then runs the same retrieval as knowledge_pack_ids — hybrid search over the packs, top chunks injected under Relevant Document Context. Everything from Knowledge Packs → Retrieval applies: only ready packs are searched, and pack visibility is enforced first.

Grounding a request in several brains

Pass brain_ids to attach more than one brain to the same request — the handbook plus the product catalog, say:

{
  "model": "anthropic/claude-sonnet-4-5",
  "messages": [{ "role": "user", "content": "Does the Pro plan follow the standard refund window?" }],
  "brain_ids": ["b1a2c3...", "d4e5f6..."]
}

Every named brain resolves in one lookup, and the packs are merged into a single deduplicated set before retrieval — a pack that sits in two of the brains is searched once. brain_id is the singular alias for the same field: send both and Truememory resolves their union.

A few behaviors worth knowing:

  • knowledge_pack_ids wins. If a request sends a non-empty knowledge_pack_ids, the brains are ignored and the explicit IDs are used.
  • An empty brain injects nothing. If the brains hold no packs (or their packs were deleted), no document context is added — the request proceeds normally.
  • Only memory-enabled agents resolve them. Brains are read on the same path as memory context. Agents that do not use memory, or requests with memory reads disabled, skip resolution.
  • An unreachable brain is a 404. Resolution is scoped to what the caller can read — brains they own, hold an entitlement for, or that are public. An ID that fails that check returns BRAIN_NOT_FOUND with the offending ID in details, rather than answering with less grounding than you asked for. In a multi-brain request, one bad ID fails the whole request.

Creating and managing a brain

# Create
POST https://your-tie-host/brains
Authorization: Bearer $TOKEN
Content-Type: application/json

{ "name": "Company Handbook", "description": "HR policies and SOPs", "app_id": "vibrantly" }

name is required; description and app_id are optional. The response returns the brain with its id, user_id, app_id, and timestamps.

Endpoint Behavior
POST /brains Create a brain owned by the caller
GET /brains List the caller’s brains. Filters: app_id; paginate with limit (default 50, max 200) and offset
GET /brains/{id} Fetch one brain
PATCH /brains/{id} Update name and/or description. name cannot be set to null
DELETE /brains/{id} Delete the brain. Its packs are untouched — only the collection is removed

Adding and removing packs

Add and remove packs through these endpoints. Adding a pack that is already in the brain is safe — it is not added twice.

# Add a pack to a brain
POST https://your-tie-host/brains/{brain_id}/knowledge-packs
Authorization: Bearer $TOKEN
Content-Type: application/json

{ "pack_id": "7f3c..." }
Endpoint Behavior
POST /brains/{id}/knowledge-packs Add a pack (body { "pack_id": "..." }). The pack must be one the caller owns or a public pack
GET /brains/{id}/knowledge-packs List the packs currently in the brain
DELETE /brains/{id}/knowledge-packs/{pack_id} Remove a pack from the brain (the pack itself is not deleted)

A brain points at its packs rather than holding copies of them. So a pack that is deleted after you add it simply disappears from the brain’s list and from retrieval — no leftover entry to remove, and no error.

Admin endpoints

The /admin/brains/* block manages brains across all users without the per-user ownership check. It is gated by the Truememory service token (AUTH_SECRET) or an admin user token; end-user tokens cannot reach it.

The admin surface mirrors the user one — create, list, fetch, update, delete, and add or remove packs — with two differences:

  • Ownerless (app-owned or global) brains. POST /admin/brains accepts an optional user_id. Set it to assign the brain to a user; leave it null to create a brain with no owner — an app-scoped brain (with app_id) or a fully global one (both null).
  • No ownership filter. GET /admin/brains lists across everyone, with optional user_id and app_id filters plus limit/offset. Admin pack-add does not require the pack to be owned by any particular user.
# Create a global brain (no owner) scoped to one app
POST https://your-tie-host/admin/brains
Authorization: Bearer $AUTH_SECRET
Content-Type: application/json

{ "name": "Shared Playbook", "app_id": "vibrantly", "user_id": null }

Common pitfalls

  • Expecting a brain to add itself. Like packs, brains are opt-in per request. A brain injects context only when a request passes its brain_id (or lists it in brain_ids).
  • Sending brain_id and knowledge_pack_ids together. The explicit knowledge_pack_ids wins and the brain is ignored — not merged. Pass one or the other. (brain_id and brain_ids, by contrast, are merged.)
  • Resolving a brain you cannot read. Resolution is scoped to the caller. A brain you neither own, hold an entitlement for, nor can see as public returns 404 BRAIN_NOT_FOUND — including when it is one ID among several.
  • Deleting a brain to remove documents. Deleting a brain removes only the collection. The packs — and their entitlements and skill tags — remain. Delete the packs themselves if that is the intent.
  • Adding a pack you cannot see. A user add requires a pack you own or a public pack; anything else is rejected.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close