createConversationContext
Creates a context manager for storing conversation state, metadata, and metrics.
Overview​
createConversationContext
is an atomic primitive that manages contextual information and metadata for conversations. It provides state management with nested key support, automatic metric tracking, and event handlers for persistence.
Independence: This primitive stands alone - use it without any other Grid components for state management, user preferences, session tracking, or analytics. No conversation history or manager required.
Import​
import { createConversationContext } from "@mrck-labs/grid-core";
Function Signature​
function createConversationContext(
options?: ConversationContextOptions
): ConversationContext
Parameters​
options (optional)​
- Type:
ConversationContextOptions
- Properties:
handlers
(optional)- Type:
ConversationContextHandlers
- Properties:
onStateChanged
:(key: string, value: any) => Promise<void>
- Called when state is updated
onMetadataChanged
:(key: string, value: any) => Promise<void>
- Called when metadata is updated
- Type:
Return Type: ConversationContext​
Methods​
updateState​
updateState(key: string, value: any): Promise<void>
Update a single state value. Supports nested keys using dot notation.
Parameters:
key
: State key (supports dot notation for nesting)value
: Value to set
Example:
await context.updateState("user.name", "Alice");
await context.updateState("user.preferences.theme", "dark");
updateStates​
updateStates(updates: Record<string, any>): Promise<void>
Update multiple state values at once.
Parameters:
updates
: Object with key-value pairs to update
Example:
await context.updateStates({
"user.name": "Alice",
"user.preferences.language": "en",
"session.startTime": Date.now()
});
getState​
getState(): Record<string, any>
Get a copy of the entire state object.
Returns: Deep copy of the current state
getStateValue​
getStateValue(key: string): any
Get a specific state value by key. Supports nested keys.
Parameters:
key
: State key (supports dot notation)
Returns: The value at the specified key, or undefined
Example:
const userName = context.getStateValue("user.name");
const theme = context.getStateValue("user.preferences.theme");
updateMetadata​
updateMetadata(key: string, value: any): Promise<void>
Update metadata about the conversation.
Parameters:
key
: Metadata keyvalue
: Value to set
Example:
await context.updateMetadata("topic", "weather");
await context.updateMetadata("priority", "high");
getMetadata​
getMetadata(key?: string): any
Get metadata value(s).
Parameters:
key
(optional): Specific metadata key
Returns:
- If key provided: The value for that key
- If no key: The entire metadata object
incrementMessageCount​
incrementMessageCount(): void
Increment the internal message counter.
incrementToolCallCount​
incrementToolCallCount(count: number = 1): void
Increment the tool call counter.
Parameters:
count
: Number to increment by (default: 1)
getMetrics​
getMetrics(): ConversationMetrics
Get conversation metrics.
Returns: Object containing:
messageCount
: Total messages processedtoolCallCount
: Total tool calls madestartTime
: Conversation start timestampduration
: Time since conversation started (ms)
getSessionId​
getSessionId(): string
Get the auto-generated session ID.
Returns: Unique session identifier
getUserId​
getUserId(): string | undefined
Get the user ID if set in state.
Returns: User ID from state["user.id"] or undefined
resetState​
resetState(): Promise<void>
Clear all state while preserving metadata and metrics.
getSnapshot​
getSnapshot(): ConversationSnapshot
Get a complete snapshot of context for persistence.
Returns: Object containing:
state
: Current state objectmetadata
: Current metadata objectmetrics
: Current metricssessionId
: Session identifier
Examples​
Basic State Management​
const context = createConversationContext();
// Set user information
await context.updateState("user.name", "Alice");
await context.updateState("user.id", "user_123");
// Set preferences
await context.updateStates({
"user.preferences.language": "en",
"user.preferences.timezone": "America/New_York",
"user.preferences.notifications": true
});
// Get values
const userName = context.getStateValue("user.name"); // "Alice"
const language = context.getStateValue("user.preferences.language"); // "en"
const allState = context.getState(); // Returns full state object
With Event Handlers​
const context = createConversationContext({
handlers: {
onStateChanged: async (key, value) => {
console.log(`State updated: ${key} = ${value}`);
await database.state.upsert({
where: { key },
update: { value, updatedAt: new Date() },
create: { key, value, sessionId: context.getSessionId() }
});
},
onMetadataChanged: async (key, value) => {
console.log(`Metadata updated: ${key} = ${value}`);
await database.metadata.upsert({
where: { key },
update: { value },
create: { key, value }
});
}
}
});
Metadata and Metrics​
const context = createConversationContext();
// Set conversation metadata
await context.updateMetadata("topic", "technical-support");
await context.updateMetadata("priority", "high");
await context.updateMetadata("tags", ["billing", "subscription"]);
// Track activity
context.incrementMessageCount(); // User message
context.incrementMessageCount(); // Assistant response
context.incrementToolCallCount(2); // Two tools used
// Get metrics
const metrics = context.getMetrics();
console.log(metrics);
// {
// messageCount: 2,
// toolCallCount: 2,
// startTime: 1234567890,
// duration: 5000
// }
// Get specific metadata
const topic = context.getMetadata("topic"); // "technical-support"
const allMetadata = context.getMetadata(); // All metadata
Persistence and Restoration​
// Save context
const snapshot = context.getSnapshot();
await database.sessions.create({
data: {
sessionId: snapshot.sessionId,
snapshot: JSON.stringify(snapshot),
savedAt: new Date()
}
});
// Later: Restore context
const saved = await database.sessions.findUnique({
where: { sessionId }
});
const savedSnapshot = JSON.parse(saved.snapshot);
// Create new context and restore state
const newContext = createConversationContext();
Object.entries(savedSnapshot.state).forEach(([key, value]) => {
newContext.updateState(key, value);
});
Object.entries(savedSnapshot.metadata).forEach(([key, value]) => {
newContext.updateMetadata(key, value);
});
Complex State Management​
const context = createConversationContext();
// Build complex user profile
await context.updateStates({
"user.id": "user_123",
"user.name": "Alice Johnson",
"user.email": "alice@example.com",
"user.subscription.plan": "premium",
"user.subscription.expiresAt": "2024-12-31",
"user.settings.theme": "dark",
"user.settings.language": "en",
"user.settings.notifications.email": true,
"user.settings.notifications.push": false
});
// Track conversation flow
await context.updateStates({
"conversation.intent": "support",
"conversation.subIntent": "billing",
"conversation.sentiment": "frustrated",
"conversation.resolution": "pending"
});
// Get nested values
const plan = context.getStateValue("user.subscription.plan"); // "premium"
const emailNotifs = context.getStateValue("user.settings.notifications.email"); // true
Best Practices​
- Use dot notation for organization - Structure state hierarchically (e.g., "user.preferences.theme")
- Leverage event handlers - Implement persistence through the handler callbacks
- Track metrics consistently - Call increment methods when processing messages/tools
- Separate state from metadata - Use state for conversation data, metadata for categorization
- Take snapshots regularly - Use getSnapshot() for checkpointing long conversations
TypeScript Types​
interface ConversationMetrics {
messageCount: number;
toolCallCount: number;
startTime: number;
duration: number;
}
interface ConversationSnapshot {
state: Record<string, any>;
metadata: Record<string, any>;
metrics: ConversationMetrics;
sessionId: string;
}
Related APIs​
createConversationHistory
- For managing message historycreateConversationManager
- Combines history and contextcreateConversationLoop
- Full conversation orchestration