The beliefs SDK has four scoping controls that determine how memory is isolated and shared:
namespace— the developer-facing workspace boundarywriteScope— the authoritative layer you mutatethread— the bound thread ID for thread-scoped memoryagent— who contributed the mutation
contextLayers then controls what before() and read() merge back into the prompt context.
Namespace
Namespaces are your top-level isolation boundary. Beliefs in different namespaces never interact.
1const projectA = new Beliefs({
2 apiKey,
3 namespace: 'project-alpha',
4 writeScope: 'space',
5})
6
7const projectB = new Beliefs({
8 apiKey,
9 namespace: 'project-beta',
10 writeScope: 'space',
11})Default: 'default'
Use for: per-customer isolation, per-project separation, or per-environment separation.
Authoritative Write Scopes
thread
Per-conversation or per-task memory. This is the SDK default.
1const beliefs = new Beliefs({
2 apiKey,
3 namespace: 'support',
4 thread: 'conv-a',
5 writeScope: 'thread',
6})- Requires a bound
thread - Best for chat apps, workflow runs, and task-specific reasoning
- Default read layers:
['self', 'agent', 'space']
agent
Durable per-agent memory inside a namespace.
1const researcher = new Beliefs({
2 apiKey,
3 namespace: 'market-map',
4 agent: 'researcher',
5 writeScope: 'agent',
6})- Best for long-lived worker identity or agent-specific scratchpads
- Keeps one agent's memory separate from another's
- Default read layers:
['self', 'space']
space
One shared memory for the whole namespace.
1const beliefs = new Beliefs({
2 apiKey,
3 namespace: 'team-alpha',
4 writeScope: 'space',
5})- Best for the simplest prototype or shared-team state
- All callers in the namespace read and write the same authoritative layer
- Default read layers:
['self']
Thread Binding
If you use writeScope: 'thread', bind a thread either in the constructor or later with withThread().
Bind in the constructor
1const beliefs = new Beliefs({
2 apiKey,
3 namespace: 'support',
4 thread: conversationId,
5 writeScope: 'thread',
6})Bind later with withThread()
1const baseBeliefs = new Beliefs({
2 apiKey,
3 namespace: 'support',
4 writeScope: 'thread',
5})
6
7const beliefs = baseBeliefs.withThread(conversationId)This is useful when the framework gives you the thread or session ID at request time.
Agent Identity
agent answers "who said this?" It affects attribution and trust-weighted fusion. It does not by itself decide whether memory is shared.
1const researcher = new Beliefs({
2 apiKey,
3 namespace: 'team-alpha',
4 agent: 'researcher',
5 writeScope: 'space',
6})
7
8const reviewer = new Beliefs({
9 apiKey,
10 namespace: 'team-alpha',
11 agent: 'reviewer',
12 writeScope: 'space',
13})These two agents share the same authoritative state because they share the same namespace and writeScope: 'space'.
Context Layers
contextLayers controls what before() and read() merge together.
| Write scope | Default layers | Meaning |
|---|---|---|
thread | ['self', 'agent', 'space'] | Read the current thread plus the agent and namespace-wide projections |
agent | ['self', 'space'] | Read the agent's durable memory plus shared namespace memory |
space | ['self'] | Read only the namespace-wide shared state |
You can override the defaults when you need a narrower or wider context:
1const beliefs = new Beliefs({
2 apiKey,
3 namespace: 'support',
4 thread: conversationId,
5 writeScope: 'thread',
6 contextLayers: ['self', 'space'],
7})Design Patterns
Fastest prototype
Use one shared namespace-wide state.
1const beliefs = new Beliefs({
2 apiKey: process.env.BELIEFS_KEY,
3 namespace: 'prototype',
4 writeScope: 'space',
5})Chat application
Use per-conversation memory.
1function createBeliefs(userId: string, conversationId: string) {
2 return new Beliefs({
3 apiKey: process.env.BELIEFS_KEY,
4 namespace: userId,
5 thread: conversationId,
6 writeScope: 'thread',
7 })
8}Durable per-agent memory with shared background
1const beliefs = new Beliefs({
2 apiKey,
3 namespace: 'research-team',
4 agent: 'analyst',
5 writeScope: 'agent',
6})This keeps one agent's working memory separate while still reading shared namespace context.
Shared workspace or debate
1const optimist = new Beliefs({
2 apiKey,
3 namespace: 'market-debate',
4 agent: 'optimist',
5 writeScope: 'space',
6})
7
8const skeptic = new Beliefs({
9 apiKey,
10 namespace: 'market-debate',
11 agent: 'skeptic',
12 writeScope: 'space',
13})All participants write into the same shared state, so contradictions and supports are visible to everyone.
Environment isolation
1const ENV = process.env.NODE_ENV ?? 'development'
2
3const beliefs = new Beliefs({
4 apiKey: process.env.BELIEFS_KEY,
5 namespace: `${ENV}-${projectId}`,
6 writeScope: 'space',
7})Rules of Thumb
| Question | Recommendation |
|---|---|
| Do I want separate memory per conversation? | Use writeScope: 'thread' and bind a thread |
| Do I want one shared state for a whole project or team? | Use writeScope: 'space' |
| Do I want each agent to keep its own durable memory? | Use writeScope: 'agent' with distinct agent values |
| Do I need to scope one project away from another? | Use different namespace values |
| Do I need broader background context than the current write scope? | Override contextLayers |