> Discover all available pages from the documentation index: https://mastra.ai/llms.txt # 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 example The following example creates a `Memory` instance and clones an existing thread. ```typescript import { Memory } from '@mastra/memory' import { LibSQLStore } from '@mastra/libsql' const memory = new Memory({ storage: new LibSQLStore({ id: 'memory-store', url: 'file:./memory.db' }), }) const { thread, clonedMessages } = await memory.cloneThread({ sourceThreadId: 'original-thread-123', }) ``` ## 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. If omitted, the clone uses Clone of ${sourceThread.title} when the source thread has a title. Otherwise, the title is empty. **metadata** (`Record`): 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.messageLimit** (`number`): Maximum number of messages to clone. When set, clones the most recent N messages. **options.messageFilter** (`MessageFilter`): Filter criteria for selecting which messages to clone. **options.messageFilter.startDate** (`Date`): Only clone messages created on or after this date. **options.messageFilter.endDate** (`Date`): Only clone messages created on or before this date. **options.messageFilter.messageIds** (`string[]`): Only clone messages with these specific IDs. ## 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. **messageIdMap** (`Record`): A mapping from source message IDs to their corresponding cloned message IDs. ### 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 example ```typescript 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'), }, }, }) // Clone specific messages const { thread: selectedMessagesClone } = await memory.cloneThread({ sourceThreadId: 'original-thread-123', options: { messageFilter: { messageIds: ['message-1', 'message-2'], }, }, }) // Continue conversation on the cloned thread const response = await agent.generate('Try a different approach', { memory: { thread: fullClone.id, resource: fullClone.resourceId, }, }) ``` Pass the cloned `thread.id` and `thread.resourceId` to `agent.generate()` to continue the conversation from the cloned thread. ## 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. In this example, `embeddingModel` is the embedding model configured for the project. ```typescript import { Memory } from '@mastra/memory' import { LibSQLStore, LibSQLVector } from '@mastra/libsql' const memory = new Memory({ storage: new LibSQLStore({ id: 'memory-store', url: 'file:./memory.db' }), vector: new LibSQLVector({ id: 'vector-store', url: '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', }) ``` ## Working memory When working memory is enabled, `cloneThread()` copies or shares working memory based on the working-memory scope and the clone's `resourceId`: - **Thread-scoped working memory**: The working memory is copied to the cloned thread. - **Resource-scoped working memory with the same `resourceId`**: The working memory is shared because the source and cloned threads belong to the same resource. - **Resource-scoped working memory with a different `resourceId`**: The working memory is copied to the cloned thread's resource. ## Observational Memory When [Observational Memory](https://mastra.ai/docs/memory/observational-memory) is enabled, `cloneThread()` automatically clones the OM records associated with the source thread. The behavior depends on the OM scope: - **Thread-scoped OM**: The OM record is cloned to the new thread. All internal message ID references are remapped to point to the cloned messages. - **Resource-scoped OM (same `resourceId`)**: The OM record is shared between the source and cloned threads since they belong to the same resource. No duplication occurs. - **Resource-scoped OM (different `resourceId`)**: The OM record is cloned to the new resource. Message IDs are remapped and any thread-identifying tags within observations are updated to reference the cloned thread. Only the current (most recent) OM generation is cloned — older history generations aren't copied. Transient processing state (observation/reflection in-progress flags) is reset on the cloned record.