Memory.cloneThread()
The .cloneThread() method creates a copy of an existing conversation thread, including all its messages. This enables creating divergent conversation paths from a specific point in a conversation. When semantic recall is enabled, the method also creates vector embeddings for the cloned messages.
Usage ExampleDirect link to Usage Example
const { thread, clonedMessages } = await memory.cloneThread({
sourceThreadId: "original-thread-123",
});
ParametersDirect link to Parameters
sourceThreadId:
string
The ID of the thread to clone
newThreadId?:
string
Optional custom ID for the cloned thread. If not provided, one will be generated.
resourceId?:
string
Optional resource ID for the cloned thread. Defaults to the source thread's resourceId.
title?:
string
Optional title for the cloned thread. Defaults to '[source title] (Copy)'.
metadata?:
Record<string, unknown>
Optional metadata to merge with the source thread's metadata. Clone metadata is automatically added.
options?:
CloneOptions
Optional filtering options for the clone operation.
Options ParametersDirect link to Options Parameters
messageLimit?:
number
Maximum number of messages to clone. When set, clones the most recent N messages.
messageFilter?:
MessageFilter
Filter criteria for selecting which messages to clone.
MessageFilter ParametersDirect link to MessageFilter Parameters
startDate?:
Date
Only clone messages created on or after this date.
endDate?:
Date
Only clone messages created on or before this date.
messageIds?:
string[]
Only clone messages with these specific IDs.
ReturnsDirect link to Returns
thread:
StorageThreadType
The newly created cloned thread with clone metadata.
clonedMessages:
MastraDBMessage[]
Array of the cloned messages with new IDs assigned to the new thread.
Clone MetadataDirect link to Clone Metadata
The cloned thread's metadata includes a clone property with:
sourceThreadId:
string
The ID of the original thread that was cloned.
clonedAt:
Date
Timestamp when the clone was created.
lastMessageId?:
string
The ID of the last message in the source thread at the time of cloning.
Extended Usage ExampleDirect link to Extended Usage Example
src/test-clone.ts
import { mastra } from "./mastra";
const agent = mastra.getAgent("agent");
const memory = await agent.getMemory();
// Clone a thread with all messages
const { thread: fullClone } = await memory.cloneThread({
sourceThreadId: "original-thread-123",
title: "Alternative Conversation Path",
});
// Clone with a custom ID
const { thread: customIdClone } = await memory.cloneThread({
sourceThreadId: "original-thread-123",
newThreadId: "my-custom-clone-id",
});
// Clone only the last 5 messages
const { thread: partialClone, clonedMessages } = await memory.cloneThread({
sourceThreadId: "original-thread-123",
options: {
messageLimit: 5,
},
});
// Clone messages from a specific date range
const { thread: dateFilteredClone } = await memory.cloneThread({
sourceThreadId: "original-thread-123",
options: {
messageFilter: {
startDate: new Date("2024-01-01"),
endDate: new Date("2024-01-31"),
},
},
});
// Continue conversation on the cloned thread
const response = await agent.generate("Let's try a different approach", {
threadId: fullClone.id,
resourceId: fullClone.resourceId,
});
Vector EmbeddingsDirect link to Vector Embeddings
When the Memory instance has semantic recall enabled (with a vector store and embedder configured), cloneThread() automatically creates vector embeddings for all cloned messages. This ensures that semantic search works correctly on the cloned thread.
import { Memory } from "@mastra/memory";
import { LibSQLStore, LibSQLVector } from "@mastra/libsql";
const memory = new Memory({
storage: new LibSQLStore({ url: "file:./memory.db" }),
vector: new LibSQLVector({ connectionUrl: "file:./vector.db" }),
embedder: embeddingModel,
options: {
semanticRecall: true,
},
});
// Clone will also create embeddings for cloned messages
const { thread } = await memory.cloneThread({
sourceThreadId: "original-thread",
});
// Semantic search works on the cloned thread
const results = await memory.recall({
threadId: thread.id,
vectorSearchString: "search query",
});