# 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

```typescript
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. 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.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<string, string>`): 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'),
    },
  },
})

// Continue conversation on the cloned thread
const response = await agent.generate("Let's try a different approach", {
  threadId: fullClone.id,
  resourceId: fullClone.resourceId,
})
```

## 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.

```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',
})
```

## 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.