ConversationStore Interface
ConversationStore is the abstract interface for persisting multi-turn chat history. It is a runtime store (read on every agent turn) that is distinct from the TraceStore (fire-and-forget observability writes).
Import
import {
ConversationStore,
ConversationFilter,
MessageQueryOptions,
Conversation,
ConversationMessage,
ConversationRole,
} from "@modernpath/agent-framework";
ConversationStore Methods
Write Path
| Method | Signature | Description |
createConversation | createConversation(conv: Omit<Conversation, "messageCount">): Promise<void> | Creates a new conversation. The messageCount is initialized to 0 internally. |
addMessage | addMessage(conversationId: string, msg: ConversationMessage): Promise<void> | Appends a message to an existing conversation. Updates conversation.updatedAt and increments messageCount. Throws if the conversation does not exist. |
updateConversation | updateConversation(conversationId: string, updates: Partial<Pick<Conversation, "title" \| "metadata">>): Promise<void> | Updates conversation metadata such as title or the metadata bag. |
Read Path
| Method | Signature | Description |
getConversation | getConversation(conversationId: string): Promise<Conversation \| null> | Retrieves a conversation by ID (without messages). Returns null if not found. |
getMessages | getMessages(conversationId: string, opts?: MessageQueryOptions): Promise<ConversationMessage[]> | Gets messages for a conversation, ordered by timestamp ascending. Supports limit (returns most recent N) and before (pagination). |
listConversations | listConversations(filter: ConversationFilter): Promise<Conversation[]> | Lists conversations matching the filter, ordered by updatedAt descending. |
Lifecycle
| Method | Signature | Description |
deleteConversation | deleteConversation(conversationId: string): Promise<void> | Deletes a conversation and all its messages. |
Types
Conversation
interface Conversation {
schemaVersion: 1;
conversationId: string;
userId: number;
auditingId: number;
agentName: string;
title?: string;
createdAt: Date;
updatedAt: Date;
messageCount: number;
metadata?: Record<string, any>;
}
| Field | Type | Description |
conversationId | string | Primary key. When a TraceStore is also used, this equals Trace.sessionId. |
userId | number | User who owns this conversation. |
auditingId | number | Auditing context identifier. |
agentName | string | Which agent handles this conversation. |
title | string | Auto-generated or user-set conversation title. |
messageCount | number | Denormalized count for listing UIs. |
metadata | object | Arbitrary metadata (e.g. default store, default parameters). |
ConversationMessage
interface ConversationMessage {
schemaVersion: 1;
messageId: string;
conversationId: string;
role: ConversationRole;
content: string;
timestamp: Date;
traceId?: string;
sources?: Array<{
documentId?: string;
documentName?: string;
chunk?: string;
score?: number;
}>;
metadata?: Record<string, any>;
}
| Field | Type | Description |
messageId | string | Primary key (ULID recommended for natural sort order). |
role | ConversationRole | "user", "assistant", or "system". |
content | string | Message text content. |
timestamp | Date | When the message was created. |
traceId | string | Back-link to the trace that produced this assistant message. |
sources | array | RAG sources returned with this assistant message. |
ConversationRole
type ConversationRole = "user" | "assistant" | "system";
ConversationFilter
interface ConversationFilter {
userId?: number;
agentName?: string;
limit?: number; // Default: 50
offset?: number;
}
MessageQueryOptions
interface MessageQueryOptions {
limit?: number;
before?: Date;
}
| Option | Type | Description |
limit | number | Maximum number of messages to return. Returns the most recent N messages (in ascending order). |
before | Date | Return messages before this timestamp. Useful for pagination or context-window trimming. |
Code Example
import type { ConversationStore } from "@modernpath/agent-framework";
async function sendMessage(
store: ConversationStore,
conversationId: string,
userMessage: string,
agent: BaseAgent,
) {
// Load conversation history for agent context
const messages = await store.getMessages(conversationId, { limit: 50 });
const history = messages.map((m) => ({
role: m.role,
content: m.content,
timestamp: m.timestamp,
}));
// Execute agent with history
const result = await agent.execute({
userId: 1,
auditingId: 100,
prompt: userMessage,
parameters: {},
history,
});
// Save user message
await store.addMessage(conversationId, {
schemaVersion: 1,
messageId: crypto.randomUUID(),
conversationId,
role: "user",
content: userMessage,
timestamp: new Date(),
});
// Save assistant message
await store.addMessage(conversationId, {
schemaVersion: 1,
messageId: crypto.randomUUID(),
conversationId,
role: "assistant",
content: result.data?.answer ?? "",
timestamp: new Date(),
traceId: result.metadata?.traceId,
sources: result.data?.sources,
});
return result;
}
Related Pages