Appearance
Dialogue Reference
This page covers the two main classes for working with dialogues: DialogueDB (the entry point) and Dialogue (a conversation instance).
DialogueDB Class
The top-level class for interacting with DialogueDB. Create one instance and use it throughout your application.
typescript
import { DialogueDB } from 'dialogue-db';
const db = new DialogueDB({ apiKey: process.env.DIALOGUE_DB_API_KEY });createDialogue
Create a new dialogue, optionally with initial messages, state, and metadata.
typescript
const dialogue = await db.createDialogue({
namespace: 'user_123', // optional grouping
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Hello!' }
],
state: { topic: 'onboarding' }, // optional initial state
metadata: { channel: 'web' }, // optional, can't be changed after creation
tags: ['support'] // optional
});Parameters: CreateDialogueInput (all fields optional)
| Field | Type | Description |
|---|---|---|
namespace | string | Namespace for multi-tenancy isolation |
threadOf | string | Parent dialogue ID to create as a thread |
label | string | Human-readable label |
messages | CreateMessageInput[] | Initial messages (max 25) |
state | Record<string, any> | Initial state data |
metadata | Record<string, string | number | boolean> | Immutable metadata |
tags | string[] | Categorization tags |
Returns: Promise<Dialogue>
getDialogue
Retrieve a dialogue by ID. Returns null if not found.
typescript
const dialogue = await db.getDialogue('dialogue-id');
const dialogue = await db.getDialogue('dialogue-id', 'user_123'); // with namespaceParameters: id: string, namespace?: string
Returns: Promise<Dialogue | null>
getOrCreateDialogue
Get an existing dialogue or create a new one. Useful for session-based patterns where you want to resume or start fresh.
typescript
const dialogue = await db.getOrCreateDialogue({
id: 'session-abc',
namespace: 'user_123'
});Parameters: { id?: string, namespace?: string, threadOf?: string }
Returns: Promise<Dialogue>
listDialogues
List dialogues with pagination and filtering.
typescript
const { items, next } = await db.listDialogues({
limit: 20,
order: 'desc',
namespace: 'user_123'
});
// Next page
if (next) {
const page2 = await db.listDialogues({ limit: 20, next });
}Parameters: ListDialogueFilters (all fields optional)
| Field | Type | Description |
|---|---|---|
limit | number | Max items per page |
order | 'asc' | 'desc' | Sort order by creation date |
next | string | Pagination cursor from previous response |
namespace | string | Filter by namespace |
threadOf | string | Filter to threads of a parent dialogue |
created | string | Filter by creation date prefix (e.g., "2025-01") |
startDate | string | Dialogues created on or after (ISO 8601) |
endDate | string | Dialogues created before or on (ISO 8601) |
Returns: Promise<ListResponse<Dialogue>> — { items: Dialogue[], next?: string }
deleteDialogue
Permanently delete a dialogue. Messages within the dialogue remain accessible.
typescript
await db.deleteDialogue('dialogue-id');
await db.deleteDialogue('dialogue-id', 'user_123'); // with namespaceParameters: id: string, namespace?: string
Returns: Promise<void>
searchDialogues
Semantic search across dialogues. See Memory & Search for details.
typescript
const dialogues = await db.searchDialogues('billing questions', {
limit: 10,
filter: { tags: ['support'] }
});searchMessages
Semantic search across messages. See Memory & Search for details.
typescript
const messages = await db.searchMessages('password reset instructions', {
limit: 20
});searchMemories
Semantic search across memories. See Memory & Search for details.
typescript
const memories = await db.searchMemories('user preferences');createMemory / getMemory / listMemories / deleteMemory
See Memory & Search Reference.
Dialogue Class
A Dialogue instance represents a single conversation. You get one from db.createDialogue(), db.getDialogue(), or db.getOrCreateDialogue().
Properties
| Property | Type | Mutable | Description |
|---|---|---|---|
id | string | No | Unique identifier |
projectId | string | No | Project this dialogue belongs to |
requestId | string | No | Request tracking ID |
status | "active" | "ended" | "archived" | No | Dialogue lifecycle status |
namespace | string? | No | Multi-tenancy namespace |
threadOf | string? | No | Parent dialogue ID (if this is a thread) |
totalMessages | number? | No | Total message count |
threadCount | number? | No | Number of child threads |
lastMessageCreated | string? | No | Timestamp of most recent message |
metadata | Record<string, any> | No | Immutable metadata set at creation |
created | string | No | Creation timestamp (ISO 8601) |
modified | string | No | Last modification timestamp |
archivedAt | string? | No | Archive timestamp |
endedAt | string? | No | End timestamp |
messages | readonly Message[] | No | Loaded messages |
isDirty | boolean | No | true if state or tags have unsaved changes |
hasMoreMessages | boolean | No | true if more messages available to load |
label | string? | Yes | Human-readable label |
state | Record<string, any> | Yes | Conversation state (batched until save()) |
tags | string[] | Yes | Tags (batched until save()) |
setState
Shallow-merge values into the dialogue state. Chainable. Changes are batched until save().
typescript
dialogue.setState({ step: 2 }).setState({ topic: 'billing' });
await dialogue.save();Parameters: value: Record<string, any>
Returns: this
saveState
Merge state and persist immediately (single API call).
typescript
await dialogue.saveState({ step: 2, topic: 'billing' });Parameters: state: Record<string, any>
Returns: Promise<Dialogue>
saveTags
Set tags and persist immediately.
typescript
await dialogue.saveTags(['vip', 'priority']);Parameters: tags: string[]
Returns: Promise<Dialogue>
saveMessage
Create a single message and persist immediately.
typescript
const message = await dialogue.saveMessage({
role: 'assistant',
content: 'How can I help?',
metadata: { model: 'gpt-4' },
tags: ['generated']
});Parameters: CreateMessageInput (without dialogueId)
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Yes | "user", "assistant", or "system" |
content | string | object | object[] | Yes | Message content |
id | string | No | Custom message ID |
tags | string[] | No | Message tags |
metadata | Record<string, string | number | boolean> | No | Message metadata (can't be changed later) |
Returns: Promise<Message>
saveMessages
Create multiple messages and persist immediately.
typescript
const messages = await dialogue.saveMessages([
{ role: 'user', content: 'Question 1' },
{ role: 'assistant', content: 'Answer 1' }
]);Parameters: Array<CreateMessageInput> (without dialogueId)
Returns: Promise<Message[]>
loadMessages
Load messages from the API. Supports pagination via the next option.
typescript
// Initial load
const messages = await dialogue.loadMessages({ limit: 50 });
// Load next page
if (dialogue.hasMoreMessages) {
const more = await dialogue.loadMessages({ limit: 50, next: true });
}Parameters: { limit?: number, next?: boolean }
Returns: Promise<Message[]>
deleteMessage
Delete a specific message by ID.
typescript
await dialogue.deleteMessage('message-id');Parameters: messageId: string
Returns: Promise<void>
createThread
Create a child thread linked to this dialogue. Threads are independent dialogues organized under a parent.
typescript
const thread = await dialogue.createThread({
metadata: { purpose: 'reasoning' },
tags: ['internal']
});
// Add messages to the thread
await thread.saveMessage({
role: 'system',
content: 'Analyzing user request...'
});Parameters: { metadata?: Record<string, any>, tags?: string[] } (all optional)
Returns: Promise<Dialogue>
WARNING
createThread() does not accept a messages parameter. Add messages after creation using saveMessage() or saveMessages().
getThreads
Get all child threads of this dialogue.
typescript
const threads = await dialogue.getThreads();
threads.forEach(t => console.log(t.id, t.totalMessages));Returns: Promise<Dialogue[]>
end
Mark the dialogue as ended. After ending, no new messages can be added.
typescript
await dialogue.end();
console.log(dialogue.status); // "ended"Returns: Promise<void>
compact
Not Yet Implemented
compact() exists on the Dialogue class but currently throws a DialogueDBError with code NOT_IMPLEMENTED. Use the REST API for compact operations.
save
Persist all batched changes (state, tags, label) in a single API call. Also saves any dirty messages.
typescript
dialogue.state = { step: 1 };
dialogue.tags = ['important'];
dialogue.label = 'Support Ticket #42';
await dialogue.save(); // single API callReturns: Promise<Dialogue>
Save Behavior
Understanding when changes hit the API:
| Operation | When Saved | Method |
|---|---|---|
saveMessage() / saveMessages() | Immediately | POST to API |
saveState() | Immediately | PUT to API |
saveTags() | Immediately | PUT to API |
dialogue.state = ... | On save() | Batched locally |
dialogue.tags = ... | On save() | Batched locally |
dialogue.label = ... | On save() | Batched locally |
Check dialogue.isDirty to see if there are unsaved changes.
Pagination
The Dialogue class tracks pagination state for messages:
typescript
const dialogue = await db.getDialogue('id');
// dialogue.messages contains the initial batch (up to 10)
console.log(dialogue.messages.length);
// Load more if available
while (dialogue.hasMoreMessages) {
await dialogue.loadMessages({ limit: 50, next: true });
}
// All messages now in dialogue.messages
console.log(dialogue.messages.length);TypeScript Types
typescript
import type {
IDialogue,
CreateDialogueInput,
UpdateDialogueInput,
ListDialogueFilters,
ListResponse
} from 'dialogue-db';IDialogue
typescript
interface IDialogue {
id: string;
projectId: string;
requestId: string;
status: 'active' | 'ended' | 'archived';
created: string;
modified: string;
tags: string[];
namespace?: string;
threadOf?: string;
label?: string;
state?: Record<string, any>;
messages?: IMessage[];
metadata?: Record<string, string | number | boolean>;
totalMessages?: number;
threadCount?: number;
}CreateDialogueInput
typescript
type CreateDialogueInput = {
namespace?: string;
threadOf?: string;
label?: string;
messages?: CreateMessageInput[];
state?: Record<string, any>;
metadata?: Record<string, string | number | boolean>;
tags?: string[];
};ListDialogueFilters
typescript
type ListDialogueFilters = {
limit?: number;
order?: 'asc' | 'desc';
next?: string;
namespace?: string;
threadOf?: string;
created?: string;
startDate?: string;
endDate?: string;
};
