TeleonTeleon AITeleon AI

Cortex Memory

Patterns for multi-tenant memory, layers, auto-context, and storage backends

Cortex is Teleon’s memory system for AI agents. It provides persistent, searchable memory for your agent runs.

For the full method-level API (all parameters, return types, and examples), see Cortex API in API Reference.

Cortex API
Memory & learning

What this guide covers

  • How to enable Cortex on an agent
  • How scope enforcement provides multi-tenant isolation
  • How to use layers for hierarchical memory (company/team/personal)
  • How auto-context injection works via cortex.context
  • How to configure storage backends for persistence

Enable Cortex

from teleon import TeleonClient
 
client = TeleonClient(api_key="tlk_live_xxx")
 
@client.agent(name="support", cortex=True)
async def support_agent(query: str, customer_id: str, cortex):
    await cortex.store(content=f"Customer asked: {query}", customer_id=customer_id, type="query")
    results = await cortex.search(query="previous issues", filter={"customer_id": customer_id})
    history = await cortex.get(filter={"customer_id": customer_id}, limit=10)
    return "ok"

Scope enforcement (multi-tenancy)

Scope ensures data isolation between tenants. When you define scope fields, they are automatically enforced on all operations.

@client.agent(
    name="support",
    cortex={
        "scope": ["customer_id"],
    },
)
async def support_agent(query: str, customer_id: str, cortex):
    await cortex.store(content="Note", type="note")
    results = await cortex.search(query="issues")
    return "ok"

How scope works

When scope fields are configured:

  • Scope values are extracted from function arguments
  • Every store() automatically includes the scope fields
  • Every search(), get(), update(), delete(), and count() is automatically filtered by scope
  • Users cannot override scope values

Memory layers

Layers provide hierarchical memory organization. Each layer has its own scope.

@client.agent(
    name="support",
    cortex={
        "scope": ["team_id", "user_id"],
        "layers": {
            "company": {"scope": []},
            "team": {"scope": ["team_id"]},
            "personal": {"scope": ["user_id"]},
        },
    },
)
async def support_agent(query: str, team_id: str, user_id: str, cortex):
    await cortex.company.store(content="Company policy update")
    await cortex.team.store(content="Team standup notes")
    await cortex.personal.store(content="My personal reminder")
    return "ok"

Auto-context injection

Cortex can automatically retrieve relevant context before agent execution and make it available via cortex.context.

@client.agent(
    name="support",
    cortex={
        "auto_context": {
            "enabled": True,
            "history_limit": 10,
            "relevant_limit": 5,
            "max_tokens": 2000,
            "filter": {"type": "important"},
        }
    },
)
async def support_agent(query: str, cortex):
    if cortex.context:
        context_text = cortex.context.text
    return "ok"

Context properties

cortex.context.entries
cortex.context.text
len(cortex.context)
bool(cortex.context)

Storage backends

By default, Cortex uses in-memory storage for development/testing. For persistence, configure a backend.

PostgreSQL with pgvector

from teleon.cortex import set_storage_backend, PostgresBackend
 
backend = PostgresBackend(
    host="localhost",
    port=5432,
    database="teleon",
    user="postgres",
    password="secret",
)
set_storage_backend(backend)
 
@client.agent(name="agent", cortex=True)
async def agent(query: str, cortex):
    return "ok"

Redis with RediSearch

from teleon.cortex import set_storage_backend, RedisBackend
 
backend = RedisBackend(
    host="localhost",
    port=6379,
    password="secret",
)
set_storage_backend(backend)

Best practices

  1. Use scope for multi-tenancy.
  2. Keep content concise.
  3. Use meaningful fields (type, topic, status) for filtering.
  4. Set TTL for temporary data.
  5. Use layers for hierarchy.
  6. Enable auto-context when appropriate.

Troubleshooting

Memory not persisting

By default, Cortex uses in-memory storage. For persistence, configure PostgreSQL or Redis backend.

Scope field not found

Ensure scope fields are in function arguments:

@client.agent(cortex={"scope": ["customer_id"]})
async def agent(query: str, customer_id: str, cortex):
    return "ok"

Empty search results

  • Check scope values match stored data
  • Verify filter fields exist in stored entries
  • Try a broader query or remove filters