How to Use IsolationOverrides and withIsolation() for Scoping Clients Across Sessions in TencentDB Agent Memory
Use IsolationOverrides and withIsolation() to create scoped clones of memory clients that override isolation context fields without mutating the original instance, enabling flexible session scoping and cross-session data aggregation.
TencentDB Agent Memory organizes data through a hierarchical isolation system defined by team, agent, user, and session identifiers. The TypeScript SDK (located at @tencentdb/memory-core) provides the withIsolation() method to dynamically adjust these scopes. This guide explains the internal mechanics of IsolationOverrides, the withIsolation() pattern, and practical techniques for scoping clients across sessions based on the source implementation.
Understanding the Isolation Context Hierarchy
TencentDB Agent Memory enforces data isolation through five identifier fields defined in V3IsolationContext (sdk/memory-core/typescript/src/v3/types.ts, lines 45-53):
| Field | Scope Level | Purpose |
|---|---|---|
teamId |
Service | Organizational boundary for memory instances |
agentId |
Agent | Specific AI agent within the team |
userId |
User | End-user who generated the data |
sessionId |
Session | Individual conversation context |
taskId (optional) |
Task | Finer-grained sub-session identifier |
These fields form a mandatory inclusion hierarchy—each level implicitly includes all levels above it. The IsolationContext class (client.ts, lines 54-99) stores these values as an immutable base context and provides the with(overrides) method to compute derived contexts.
How V3IsolationOverrides Enables Partial Context Updates
V3IsolationOverrides (types.ts, lines 53-61) is a **Partial` type that allows any subset of isolation fields to be modified:
// From sdk/memory-core/typescript/src/v3/types.ts
export type V3IsolationOverrides = Partial<V3IsolationContext> & {
// Allows setting specific fields to null for aggregation
sessionId?: string | null;
taskId?: string | null;
};
The key distinction: overrides accept null values to explicitly remove scope constraints. This enables cross-session aggregation patterns that would otherwise require constructing entirely new clients.
The withIsolation() Method: Creating Scoped Client Clones
MemoryClient.withIsolation() (client.ts, lines 152-180) implements an immutable client scoping pattern:
// From sdk/memory-core/typescript/src/v3/client.ts
withIsolation(overrides: V3IsolationOverrides): MemoryClient {
const newIsolation = this.isolation.with(overrides);
return new MemoryClient({
...this.config,
isolation: newIsolation,
});
}
Critical behavior: The method returns a new MemoryClient instance rather than mutating the receiver. The internal IsolationContext.with() method performs a shallow merge:
- Copies base context fields
- Applies override values (including
null) - Returns new
IsolationContextinstance
This immutability guarantees that concurrent or sequential operations on different scoped clients never interfere.
Scoping Clients Across Sessions: Three Common Patterns
Pattern 1: Session-Switching for Multi-Turn Conversations
Create isolated clients for distinct conversation threads while preserving team/agent/user context:
import { MemoryClient } from '@tencentdb/memory-core';
const baseClient = new MemoryClient({
transport: httpTransport,
teamId: 'team-prod',
agentId: 'support-agent',
userId: 'user-789',
sessionId: 'session-alpha',
});
// Spawn client for different conversation
const betaClient = baseClient.withIsolation({ sessionId: 'session-beta' });
// Operations on each client remain strictly isolated
await baseClient.addMessage({ role: 'user', content: 'Alpha question' });
await betaClient.addMessage({ role: 'user', content: 'Beta question' });
Relevant source: src/v3/client.ts – MemoryClient constructor isolation handling and withIsolation implementation.
Pattern 2: Cross-Session Aggregation with Null Overrides
Override sessionId to null to query data across all sessions for the same user/agent/team tuple:
// Aggregate L0/L1 memory across all user sessions
const aggClient = baseClient.withIsolation({ sessionId: null });
const allConversations = await aggClient.queryConversation({
limit: 50,
includeArchived: true,
});
// L1 summaries spanning sessions
const longTermMemories = await aggClient.querySummary({
memoryLevel: 1,
timeRange: '30d',
});
This pattern is essential for implementing persistent user memory that transcends individual conversation boundaries.
Pattern 3: Multi-Tenant Analytics with Team/Agent Overrides
// Cross-team analytics with full aggregation scope
const analyticsClient = baseClient.withIsolation({
teamId: 'analytics-tenant',
agentId: 'cross-team-reviewer',
sessionId: null,
taskId: null,
});
// Query runs in analytics tenant context, ignoring original client's scope
const auditTrail = await analyticsClient.queryConversation({ limit: 1000 });
Relevant source: src/v3/types.ts – V3IsolationOverrides definition supporting arbitrary field combinations.
Python SDK Equivalence
The Python SDK implements identical semantics through with_isolation() (sdk/memory-core/python/tencentdb_agent_memory/v3/client.py):
from tencentdb_agent_memory.v3.client import MemoryClient
client = MemoryClient(
transport=http_transport,
team_id="team-prod",
agent_id="support-agent",
user_id="user-789",
session_id="session-alpha",
)
# Session switch
client_beta = client.with_isolation(session_id="session-beta")
# Cross-session aggregation
client_all = client.with_isolation(session_id=None)
conversations = client_all.query_conversation(limit=50)
The _IsolationCtx class provides the same immutable with() merging logic as its TypeScript counterpart.
Server-Side Resolution and Override Propagation
Client-side overrides propagate through the request lifecycle via server-side resolution. The resolveIsolation function (MemoryCore/src/gateway/v2-schemas.ts, lines 355-389) handles merging:
- Explicit request body payload (highest priority)
x-tdai-*HTTP headers (fallback)- Default bucket values (e.g.,
"anonymous"for missing session)
// Simplified from v2-schemas.ts
const resolveIsolation = (payload, headers) => ({
teamId: payload.teamId ?? headers['x-tdai-team'] ?? 'default-team',
sessionId: payload.sessionId ?? headers['x-tdai-session'] ?? 'anonymous',
// ... additional fields
});
When withIsolation({ sessionId: null }) is used, the client explicitly omits the session identifier from the request payload, triggering the server's default assignment unless headers provide an alternative.
Performance and Threading Considerations
| Aspect | Behavior |
|---|---|
| Client instantiation | O(1) shallow copy; no I/O performed |
| Context merging | Shallow object spread; minimal overhead |
| Thread safety | Immutable instances permit concurrent use across threads |
| Memory overhead | Each scoped client holds reference to shared transport/config |
The cloning pattern intentionally avoids deep copying—transport layers and configuration objects are shared across scoped clients.
Summary
- Isolation context in TencentDB Agent Memory comprises
teamId,agentId,userId,sessionId, and optionaltaskIdidentifiers defined inV3IsolationContext V3IsolationOverridesenables partial, immutable modifications to isolation scope, includingnullvalues to remove constraintswithIsolation()returns a newMemoryClientwith merged context, preserving the original instance's scope for concurrent operations- Cross-session aggregation is achieved by overriding
sessionIdtonull, causing queries to span all sessions for the same user/agent/team - Server-side resolution in
v2-schemas.tsmerges client overrides with headers and defaults, ensuring consistent enforcement across the request pipeline
Frequently Asked Questions
What happens if I override a field to undefined versus null in TypeScript?
undefined values in V3IsolationOverrides are ignored during the merge, preserving the base context's value. null values explicitly clear the field, enabling broader aggregation scopes. The IsolationContext.with() method distinguishes these cases using hasOwnProperty checks (client.ts, lines 70-85).
Can I use withIsolation() to restrict scope to a narrower session, then revert to the original?
Yes—immutability makes this pattern safe. Store the original client reference and create derived scopes as needed. Each withIsolation() call produces an independent instance; discarding a scoped client automatically reverts to the parent's context:
const original = /* ... */;
const narrow = original.withIsolation({ sessionId: 'specific-session' });
// Use narrow for scoped operations
// original remains unchanged for subsequent use
How does multi-tenant isolation prevent cross-team data leakage?
The server-side resolveIsolation function enforces that request payloads cannot escalate privileges—team and agent overrides in withIsolation() only function if the transport's authentication credentials grant access to the target tenant. Unauthorized scope changes result in permission errors at the gateway layer, not silent data exposure.
Is taskId commonly used in practice, or is it reserved for future extension?
Current implementations primarily leverage the four required identifiers. taskId appears in V3IsolationOverrides for experimental sub-session granularity (e.g., multi-step workflows within a single conversation). The field is optional in all SDKs and safely omitted for standard session-scoped operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →