> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deyta.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Examples

> Runnable, end-to-end demos of the first-party adapters (LangGraph, OpenAI Agents SDK, and CrewAI) that the reference pages describe.

The [`examples/20_integrations/`](https://github.com/DeytaHQ/khora/tree/main/examples/20_integrations)
tier shows the adapters from this section wired into real agent frameworks. Where
the per-adapter reference pages document the *contract*, these scripts show the
*shape*: a working graph, session, or crew you can copy and run. They complement
the broader [example tiers](/khora/examples/basics) (basics → core APIs →
workloads).

<Note>
  Each demo runs on the zero-infra embedded backend (`pip install
      "khora[sqlite-lance]"` + `OPENAI_API_KEY`) and accepts `--config
      examples/khora.standard.yaml` to switch to PostgreSQL + Neo4j. You'll also need
  the framework itself installed (`langgraph`, `openai-agents`, or `crewai`).
</Note>

<Warning>
  The LangGraph and CrewAI adapters require a **stable `user_id` of 8+ characters**
  and reject empty, short, or `"default"` ids, a guardrail against silent
  cross-user reads. Derive it from your auth subject, not a placeholder.
</Warning>

## LangGraph · `KhoraStore`

A two-node `StateGraph` (`recall → respond`) backed by `KhoraStore`. Before each
reply the agent semantically searches prior turns; after it, it persists the new
turn. The point: **memory belongs to the store, not the graph**. Drop the graph,
rebuild it with the same store, and the history is still there.

```python theme={null}
from khora.integrations.langgraph import KhoraStore

store = KhoraStore(kb, user_id="alice-acme-prod")   # 8+ chars, never "default"
graph = build_graph(store)                           # builder.compile(store=store)

# inside a node — semantic search over previously stored items:
hits = await store.asearch(MEMORY_NS, query=user_msg, limit=3)

# persist the turn so future recalls can find it:
await store.aput(MEMORY_NS, turn_id, {"text": user_msg, "role": "user"})
```

**Takeaway:** `KhoraStore` implements LangGraph's `BaseStore` (`asearch` / `aput`)
over a khora namespace scoped to `user_id`, with VectorCypher handling entity and
recency-aware recall. See the
[LangGraph reference](/khora/integrations/langgraph) for the full contract.

## OpenAI Agents SDK · `KhoraSession`

The defining memory-library demo: a user walks away and comes back tomorrow, and the
agent still knows what they discussed. Two `KhoraSession` instances share one
namespace under different `session_id` values ("Monday" and "Tuesday"). Memory
written in one session is recallable from the other, because the **namespace is the
isolation boundary, the session is not**.

```python theme={null}
from khora.integrations.openai_agents import KhoraSession
from khora.integrations.openai_agents.session import session_uuid

monday = KhoraSession(kb=kb, namespace=ns_id, session_id="conv-2026-05-19")
await monday.add_items([{"role": "user", "content": "I'm allergic to peanuts."}])

# A different session_id, the SAME namespace — yesterday's facts are reachable:
recall = await kb.recall("What food restrictions does the user have?", namespace=ns_id)

# GDPR-friendly cleanup — cascade-delete one session's documents + chunks:
await kb.forget_session(ns_id, session_uuid("conv-2026-05-19"))
```

**Takeaway:** the SDK's `session_id` (any string) is mapped onto khora's via UUID5,
so ids round-trip cleanly. Use the namespace as the per-user boundary and
`forget_session` to scope retention when a conversation ends. See the
[OpenAI Agents reference](/khora/integrations/openai-agents) for `khora_recall_tool`
and `KhoraMemoryHooks`.

## CrewAI · `KhoraMemory`

Two agents (researcher, writer) over three namespaces: one **shared** pool both read
and write, plus a **private** notebook each. The shape agentic teams actually need
(collaboration where it matters, isolation where it doesn't) falls out of handing
each agent a different `KhoraMemory` instance.

```python theme={null}
from khora.integrations.crewai import KhoraMemory

researcher_shared = KhoraMemory(kb=kb, namespace=shared_ns, user_id="agent-researcher-001", scope_root="/team")
writer_shared     = KhoraMemory(kb=kb, namespace=shared_ns, user_id="agent-writer-001",     scope_root="/team")
writer_private    = KhoraMemory(kb=kb, namespace=writer_ns, user_id="agent-writer-001",     scope_root="/scratch")

researcher_shared.remember("Customer interviews show 80% want self-hosted Postgres.",
                           scope="/team/findings", importance=0.9)

hits = writer_shared.recall("what do customers want?", limit=5)   # hit.score, hit.record.content
# writer_private.recall(...) sees none of the researcher's notes — the isolation guarantee.
```

**Takeaway:** `KhoraMemory` binds `(kb, namespace, user_id)` and plugs into CrewAI's
unified `Memory`. Same namespace + different `user_id` → shared storage,
writes distinguished by user. Different namespaces → full isolation. See the
[CrewAI reference](/khora/integrations/crewai).

## Other adapters

[Google ADK](/khora/integrations/google-adk) (`KhoraMemoryService`) and
[LlamaIndex](/khora/integrations/llamaindex) ship adapters with their own reference
pages but don't have a tier-20 walkthrough yet. Every adapter also has a per-framework
smoke test under
[`examples/integrations/<framework>/`](https://github.com/DeytaHQ/khora/tree/main/examples/integrations)
that exercises the contract against a deterministic mock LLM.
