@mastra/memory 1.0.0-beta.10 → 1.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { embedMany } from './_types/@internal_ai-sdk-v4/dist/index.js';
2
2
  import type { MastraDBMessage } from '@mastra/core/agent';
3
3
  import type { MemoryConfig, SharedMemoryConfig, StorageThreadType, WorkingMemoryTemplate, MessageDeleteInput } from '@mastra/core/memory';
4
4
  import { MastraMemory } from '@mastra/core/memory';
5
- import type { StorageListThreadsByResourceIdOutput, StorageListThreadsByResourceIdInput, StorageListMessagesInput, MemoryStorage } from '@mastra/core/storage';
5
+ import type { StorageListThreadsByResourceIdOutput, StorageListThreadsByResourceIdInput, StorageListMessagesInput, MemoryStorage, StorageCloneThreadInput, StorageCloneThreadOutput, ThreadCloneMetadata } from '@mastra/core/storage';
6
6
  import type { ToolAction } from '@mastra/core/tools';
7
7
  import { deepMergeWorkingMemory } from './tools/working-memory.js';
8
8
  export { deepMergeWorkingMemory };
@@ -127,6 +127,139 @@ export declare class Memory extends MastraMemory {
127
127
  * @returns Promise that resolves when all messages are deleted
128
128
  */
129
129
  deleteMessages(input: MessageDeleteInput): Promise<void>;
130
+ /**
131
+ * Clone a thread and its messages to create a new independent thread.
132
+ * The cloned thread will have metadata tracking its source.
133
+ *
134
+ * If semantic recall is enabled, the cloned messages will also be embedded
135
+ * and added to the vector store for semantic search.
136
+ *
137
+ * @param args - Clone configuration options
138
+ * @param args.sourceThreadId - ID of the thread to clone
139
+ * @param args.newThreadId - ID for the new cloned thread (if not provided, a random UUID will be generated)
140
+ * @param args.resourceId - Resource ID for the new thread (defaults to source thread's resourceId)
141
+ * @param args.title - Title for the new cloned thread
142
+ * @param args.metadata - Additional metadata to merge with clone metadata
143
+ * @param args.options - Options for filtering which messages to include
144
+ * @param args.options.messageLimit - Maximum number of messages to copy (from most recent)
145
+ * @param args.options.messageFilter - Filter messages by date range or specific IDs
146
+ * @param memoryConfig - Optional memory configuration override
147
+ * @returns The newly created thread and the cloned messages
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * // Clone entire thread
152
+ * const { thread, clonedMessages } = await memory.cloneThread({
153
+ * sourceThreadId: 'thread-123',
154
+ * });
155
+ *
156
+ * // Clone with custom ID
157
+ * const { thread, clonedMessages } = await memory.cloneThread({
158
+ * sourceThreadId: 'thread-123',
159
+ * newThreadId: 'my-custom-thread-id',
160
+ * });
161
+ *
162
+ * // Clone with message limit
163
+ * const { thread, clonedMessages } = await memory.cloneThread({
164
+ * sourceThreadId: 'thread-123',
165
+ * title: 'My cloned conversation',
166
+ * options: {
167
+ * messageLimit: 10, // Only clone last 10 messages
168
+ * },
169
+ * });
170
+ *
171
+ * // Clone with date filter
172
+ * const { thread, clonedMessages } = await memory.cloneThread({
173
+ * sourceThreadId: 'thread-123',
174
+ * options: {
175
+ * messageFilter: {
176
+ * startDate: new Date('2024-01-01'),
177
+ * endDate: new Date('2024-06-01'),
178
+ * },
179
+ * },
180
+ * });
181
+ * ```
182
+ */
183
+ cloneThread(args: StorageCloneThreadInput, memoryConfig?: MemoryConfig): Promise<StorageCloneThreadOutput>;
184
+ /**
185
+ * Embed cloned messages for semantic recall.
186
+ * This is similar to the embedding logic in saveMessages but operates on already-saved messages.
187
+ */
188
+ private embedClonedMessages;
189
+ /**
190
+ * Get the clone metadata from a thread if it was cloned from another thread.
191
+ *
192
+ * @param thread - The thread to check
193
+ * @returns The clone metadata if the thread is a clone, null otherwise
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * const thread = await memory.getThreadById({ threadId: 'thread-123' });
198
+ * const cloneInfo = memory.getCloneMetadata(thread);
199
+ * if (cloneInfo) {
200
+ * console.log(`This thread was cloned from ${cloneInfo.sourceThreadId}`);
201
+ * }
202
+ * ```
203
+ */
204
+ getCloneMetadata(thread: StorageThreadType | null): ThreadCloneMetadata | null;
205
+ /**
206
+ * Check if a thread is a clone of another thread.
207
+ *
208
+ * @param thread - The thread to check
209
+ * @returns True if the thread is a clone, false otherwise
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * const thread = await memory.getThreadById({ threadId: 'thread-123' });
214
+ * if (memory.isClone(thread)) {
215
+ * console.log('This is a cloned thread');
216
+ * }
217
+ * ```
218
+ */
219
+ isClone(thread: StorageThreadType | null): boolean;
220
+ /**
221
+ * Get the source thread that a cloned thread was created from.
222
+ *
223
+ * @param threadId - ID of the cloned thread
224
+ * @returns The source thread if found, null if the thread is not a clone or source doesn't exist
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * const sourceThread = await memory.getSourceThread('cloned-thread-123');
229
+ * if (sourceThread) {
230
+ * console.log(`Original thread: ${sourceThread.title}`);
231
+ * }
232
+ * ```
233
+ */
234
+ getSourceThread(threadId: string): Promise<StorageThreadType | null>;
235
+ /**
236
+ * List all threads that were cloned from a specific source thread.
237
+ *
238
+ * @param sourceThreadId - ID of the source thread
239
+ * @param resourceId - Optional resource ID to filter by
240
+ * @returns Array of threads that are clones of the source thread
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * const clones = await memory.listClones('original-thread-123', 'user-456');
245
+ * console.log(`Found ${clones.length} clones of this thread`);
246
+ * ```
247
+ */
248
+ listClones(sourceThreadId: string, resourceId?: string): Promise<StorageThreadType[]>;
249
+ /**
250
+ * Get the clone history chain for a thread (all ancestors back to the original).
251
+ *
252
+ * @param threadId - ID of the thread to get history for
253
+ * @returns Array of threads from oldest ancestor to the given thread (inclusive)
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * const history = await memory.getCloneHistory('deeply-cloned-thread');
258
+ * // Returns: [originalThread, firstClone, secondClone, deeplyClonedThread]
259
+ * ```
260
+ */
261
+ getCloneHistory(threadId: string): Promise<StorageThreadType[]>;
130
262
  }
131
263
  export { SemanticRecall, WorkingMemory, MessageHistory } from '@mastra/core/processors';
264
+ export type { StorageCloneThreadInput, StorageCloneThreadOutput, ThreadCloneMetadata } from '@mastra/core/storage';
132
265
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import { createTool } from '@mastra/core/tools';
15
15
  import { convertSchemaToZod } from '@mastra/schema-compat';
16
16
  export { MessageHistory, SemanticRecall, WorkingMemory } from '@mastra/core/processors';
17
17
 
18
- // ../_vendored/ai_v4/dist/chunk-IHGBB4AL.js
18
+ // ../_vendored/ai_v4/dist/chunk-OPIPXJLE.js
19
19
  var __create = Object.create;
20
20
  var __defProp = Object.defineProperty;
21
21
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -377,7 +377,7 @@ function getErrorMessage2(error) {
377
377
  function isAbortError(error) {
378
378
  return error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError");
379
379
  }
380
- var validatorSymbol = Symbol.for("vercel.ai.validator");
380
+ var validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
381
381
  function validator(validate) {
382
382
  return { [validatorSymbol]: true, validate };
383
383
  }
@@ -435,7 +435,7 @@ function safeParseJSON({
435
435
  };
436
436
  }
437
437
  }
438
- var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");
438
+ var ignoreOverride = /* @__PURE__ */ Symbol("Let zodToJsonSchema decide on which parser to use");
439
439
  var defaultOptions = {
440
440
  name: void 0,
441
441
  $refStrategy: "root",
@@ -2243,7 +2243,7 @@ function zodSchema(zodSchema22, options) {
2243
2243
  }
2244
2244
  );
2245
2245
  }
2246
- var schemaSymbol = Symbol.for("vercel.ai.schema");
2246
+ var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
2247
2247
  function jsonSchema(jsonSchema22, {
2248
2248
  validate
2249
2249
  } = {}) {
@@ -2330,7 +2330,7 @@ function _makeCompatibilityCheck(ownVersion) {
2330
2330
  }
2331
2331
  var isCompatible = _makeCompatibilityCheck(VERSION);
2332
2332
  var major = VERSION.split(".")[0];
2333
- var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for("opentelemetry.js.api." + major);
2333
+ var GLOBAL_OPENTELEMETRY_API_KEY = /* @__PURE__ */ Symbol.for("opentelemetry.js.api." + major);
2334
2334
  var _global = _globalThis;
2335
2335
  function registerGlobal(type, instance, diag, allowOverride) {
2336
2336
  var _a172;
@@ -4693,7 +4693,7 @@ function secureJsonParse(text4) {
4693
4693
  Error.stackTraceLimit = stackTraceLimit;
4694
4694
  }
4695
4695
  }
4696
- var validatorSymbol2 = Symbol.for("vercel.ai.validator");
4696
+ var validatorSymbol2 = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
4697
4697
  function validator2(validate) {
4698
4698
  return { [validatorSymbol2]: true, validate };
4699
4699
  }
@@ -5007,7 +5007,7 @@ var getRelativePath2 = (pathA, pathB) => {
5007
5007
  }
5008
5008
  return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/");
5009
5009
  };
5010
- var ignoreOverride2 = Symbol(
5010
+ var ignoreOverride2 = /* @__PURE__ */ Symbol(
5011
5011
  "Let zodToJsonSchema decide on which parser to use"
5012
5012
  );
5013
5013
  var defaultOptions2 = {
@@ -6127,7 +6127,7 @@ function zodSchema2(zodSchema22, options) {
6127
6127
  return zod3Schema(zodSchema22);
6128
6128
  }
6129
6129
  }
6130
- var schemaSymbol2 = Symbol.for("vercel.ai.schema");
6130
+ var schemaSymbol2 = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
6131
6131
  function jsonSchema2(jsonSchema22, {
6132
6132
  validate
6133
6133
  } = {}) {
@@ -6182,7 +6182,7 @@ var require_get_context = __commonJS({
6182
6182
  getContext: () => getContext3
6183
6183
  });
6184
6184
  module.exports = __toCommonJS(get_context_exports);
6185
- var SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context");
6185
+ var SYMBOL_FOR_REQ_CONTEXT = /* @__PURE__ */ Symbol.for("@vercel/request-context");
6186
6186
  function getContext3() {
6187
6187
  const fromSymbol = globalThis;
6188
6188
  return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {};
@@ -7211,7 +7211,7 @@ function _makeCompatibilityCheck2(ownVersion) {
7211
7211
  }
7212
7212
  var isCompatible2 = _makeCompatibilityCheck2(VERSION22);
7213
7213
  var major2 = VERSION22.split(".")[0];
7214
- var GLOBAL_OPENTELEMETRY_API_KEY2 = Symbol.for("opentelemetry.js.api." + major2);
7214
+ var GLOBAL_OPENTELEMETRY_API_KEY2 = /* @__PURE__ */ Symbol.for("opentelemetry.js.api." + major2);
7215
7215
  var _global2 = _globalThis2;
7216
7216
  function registerGlobal2(type, instance, diag, allowOverride) {
7217
7217
  var _a162;
@@ -9657,7 +9657,7 @@ function addAdditionalPropertiesToJsonSchema(jsonSchema22) {
9657
9657
  }
9658
9658
  return jsonSchema22;
9659
9659
  }
9660
- var ignoreOverride3 = Symbol(
9660
+ var ignoreOverride3 = /* @__PURE__ */ Symbol(
9661
9661
  "Let zodToJsonSchema decide on which parser to use"
9662
9662
  );
9663
9663
  var defaultOptions3 = {
@@ -10739,7 +10739,7 @@ var zod3ToJsonSchema = (schema, options) => {
10739
10739
  combined.$schema = "http://json-schema.org/draft-07/schema#";
10740
10740
  return combined;
10741
10741
  };
10742
- var schemaSymbol3 = Symbol.for("vercel.ai.schema");
10742
+ var schemaSymbol3 = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
10743
10743
  function lazySchema(createSchema) {
10744
10744
  let schema;
10745
10745
  return () => {
@@ -11140,7 +11140,7 @@ var require_get_context2 = __commonJS$1({
11140
11140
  getContext: () => getContext3
11141
11141
  });
11142
11142
  module.exports = __toCommonJS(get_context_exports);
11143
- var SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context");
11143
+ var SYMBOL_FOR_REQ_CONTEXT = /* @__PURE__ */ Symbol.for("@vercel/request-context");
11144
11144
  function getContext3() {
11145
11145
  const fromSymbol = globalThis;
11146
11146
  return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {};
@@ -12173,7 +12173,7 @@ function _makeCompatibilityCheck3(ownVersion) {
12173
12173
  }
12174
12174
  var isCompatible3 = _makeCompatibilityCheck3(VERSION23);
12175
12175
  var major3 = VERSION23.split(".")[0];
12176
- var GLOBAL_OPENTELEMETRY_API_KEY3 = Symbol.for("opentelemetry.js.api." + major3);
12176
+ var GLOBAL_OPENTELEMETRY_API_KEY3 = /* @__PURE__ */ Symbol.for("opentelemetry.js.api." + major3);
12177
12177
  var _global3 = _globalThis3;
12178
12178
  function registerGlobal3(type, instance, diag, allowOverride) {
12179
12179
  var _a146;
@@ -14408,6 +14408,9 @@ var DefaultEmbedManyResult3 = class {
14408
14408
  createIdGenerator3({ prefix: "aiobj", size: 24 });
14409
14409
  createIdGenerator3({ prefix: "aiobj", size: 24 });
14410
14410
  function deepMergeWorkingMemory(existing, update) {
14411
+ if (!update || typeof update !== "object" || Object.keys(update).length === 0) {
14412
+ return existing && typeof existing === "object" ? { ...existing } : {};
14413
+ }
14411
14414
  if (!existing || typeof existing !== "object") {
14412
14415
  return update;
14413
14416
  }
@@ -14481,6 +14484,9 @@ var updateWorkingMemoryTool = (memoryConfig) => {
14481
14484
  existingData = null;
14482
14485
  }
14483
14486
  }
14487
+ if (inputData.memory === void 0 || inputData.memory === null) {
14488
+ return { success: true, message: "No memory data provided, existing memory unchanged." };
14489
+ }
14484
14490
  let newData;
14485
14491
  if (typeof inputData.memory === "string") {
14486
14492
  try {
@@ -15265,6 +15271,233 @@ ${template.content !== this.defaultWorkingMemoryTemplate ? `- Only store informa
15265
15271
  const memoryStore = await this.getMemoryStore();
15266
15272
  await memoryStore.deleteMessages(messageIds);
15267
15273
  }
15274
+ /**
15275
+ * Clone a thread and its messages to create a new independent thread.
15276
+ * The cloned thread will have metadata tracking its source.
15277
+ *
15278
+ * If semantic recall is enabled, the cloned messages will also be embedded
15279
+ * and added to the vector store for semantic search.
15280
+ *
15281
+ * @param args - Clone configuration options
15282
+ * @param args.sourceThreadId - ID of the thread to clone
15283
+ * @param args.newThreadId - ID for the new cloned thread (if not provided, a random UUID will be generated)
15284
+ * @param args.resourceId - Resource ID for the new thread (defaults to source thread's resourceId)
15285
+ * @param args.title - Title for the new cloned thread
15286
+ * @param args.metadata - Additional metadata to merge with clone metadata
15287
+ * @param args.options - Options for filtering which messages to include
15288
+ * @param args.options.messageLimit - Maximum number of messages to copy (from most recent)
15289
+ * @param args.options.messageFilter - Filter messages by date range or specific IDs
15290
+ * @param memoryConfig - Optional memory configuration override
15291
+ * @returns The newly created thread and the cloned messages
15292
+ *
15293
+ * @example
15294
+ * ```typescript
15295
+ * // Clone entire thread
15296
+ * const { thread, clonedMessages } = await memory.cloneThread({
15297
+ * sourceThreadId: 'thread-123',
15298
+ * });
15299
+ *
15300
+ * // Clone with custom ID
15301
+ * const { thread, clonedMessages } = await memory.cloneThread({
15302
+ * sourceThreadId: 'thread-123',
15303
+ * newThreadId: 'my-custom-thread-id',
15304
+ * });
15305
+ *
15306
+ * // Clone with message limit
15307
+ * const { thread, clonedMessages } = await memory.cloneThread({
15308
+ * sourceThreadId: 'thread-123',
15309
+ * title: 'My cloned conversation',
15310
+ * options: {
15311
+ * messageLimit: 10, // Only clone last 10 messages
15312
+ * },
15313
+ * });
15314
+ *
15315
+ * // Clone with date filter
15316
+ * const { thread, clonedMessages } = await memory.cloneThread({
15317
+ * sourceThreadId: 'thread-123',
15318
+ * options: {
15319
+ * messageFilter: {
15320
+ * startDate: new Date('2024-01-01'),
15321
+ * endDate: new Date('2024-06-01'),
15322
+ * },
15323
+ * },
15324
+ * });
15325
+ * ```
15326
+ */
15327
+ async cloneThread(args, memoryConfig) {
15328
+ const memoryStore = await this.getMemoryStore();
15329
+ const result = await memoryStore.cloneThread(args);
15330
+ const config = this.getMergedThreadConfig(memoryConfig);
15331
+ if (this.vector && config.semanticRecall && result.clonedMessages.length > 0) {
15332
+ await this.embedClonedMessages(result.clonedMessages, config);
15333
+ }
15334
+ return result;
15335
+ }
15336
+ /**
15337
+ * Embed cloned messages for semantic recall.
15338
+ * This is similar to the embedding logic in saveMessages but operates on already-saved messages.
15339
+ */
15340
+ async embedClonedMessages(messages, config) {
15341
+ if (!this.vector || !this.embedder) {
15342
+ return;
15343
+ }
15344
+ const embeddingData = [];
15345
+ let dimension;
15346
+ await Promise.all(
15347
+ messages.map(async (message) => {
15348
+ let textForEmbedding = null;
15349
+ if (message.content?.content && typeof message.content.content === "string" && message.content.content.trim() !== "") {
15350
+ textForEmbedding = message.content.content;
15351
+ } else if (message.content?.parts && message.content.parts.length > 0) {
15352
+ const joined = message.content.parts.filter((part) => part.type === "text").map((part) => part.text).join(" ").trim();
15353
+ if (joined) textForEmbedding = joined;
15354
+ }
15355
+ if (!textForEmbedding) return;
15356
+ const result = await this.embedMessageContent(textForEmbedding);
15357
+ dimension = result.dimension;
15358
+ embeddingData.push({
15359
+ embeddings: result.embeddings,
15360
+ metadata: result.chunks.map(() => ({
15361
+ message_id: message.id,
15362
+ thread_id: message.threadId,
15363
+ resource_id: message.resourceId
15364
+ }))
15365
+ });
15366
+ })
15367
+ );
15368
+ if (embeddingData.length > 0 && dimension !== void 0) {
15369
+ const { indexName } = await this.createEmbeddingIndex(dimension, config);
15370
+ const allVectors = [];
15371
+ const allMetadata = [];
15372
+ for (const data of embeddingData) {
15373
+ allVectors.push(...data.embeddings);
15374
+ allMetadata.push(...data.metadata);
15375
+ }
15376
+ await this.vector.upsert({
15377
+ indexName,
15378
+ vectors: allVectors,
15379
+ metadata: allMetadata
15380
+ });
15381
+ }
15382
+ }
15383
+ /**
15384
+ * Get the clone metadata from a thread if it was cloned from another thread.
15385
+ *
15386
+ * @param thread - The thread to check
15387
+ * @returns The clone metadata if the thread is a clone, null otherwise
15388
+ *
15389
+ * @example
15390
+ * ```typescript
15391
+ * const thread = await memory.getThreadById({ threadId: 'thread-123' });
15392
+ * const cloneInfo = memory.getCloneMetadata(thread);
15393
+ * if (cloneInfo) {
15394
+ * console.log(`This thread was cloned from ${cloneInfo.sourceThreadId}`);
15395
+ * }
15396
+ * ```
15397
+ */
15398
+ getCloneMetadata(thread) {
15399
+ if (!thread?.metadata?.clone) {
15400
+ return null;
15401
+ }
15402
+ return thread.metadata.clone;
15403
+ }
15404
+ /**
15405
+ * Check if a thread is a clone of another thread.
15406
+ *
15407
+ * @param thread - The thread to check
15408
+ * @returns True if the thread is a clone, false otherwise
15409
+ *
15410
+ * @example
15411
+ * ```typescript
15412
+ * const thread = await memory.getThreadById({ threadId: 'thread-123' });
15413
+ * if (memory.isClone(thread)) {
15414
+ * console.log('This is a cloned thread');
15415
+ * }
15416
+ * ```
15417
+ */
15418
+ isClone(thread) {
15419
+ return this.getCloneMetadata(thread) !== null;
15420
+ }
15421
+ /**
15422
+ * Get the source thread that a cloned thread was created from.
15423
+ *
15424
+ * @param threadId - ID of the cloned thread
15425
+ * @returns The source thread if found, null if the thread is not a clone or source doesn't exist
15426
+ *
15427
+ * @example
15428
+ * ```typescript
15429
+ * const sourceThread = await memory.getSourceThread('cloned-thread-123');
15430
+ * if (sourceThread) {
15431
+ * console.log(`Original thread: ${sourceThread.title}`);
15432
+ * }
15433
+ * ```
15434
+ */
15435
+ async getSourceThread(threadId) {
15436
+ const thread = await this.getThreadById({ threadId });
15437
+ const cloneMetadata = this.getCloneMetadata(thread);
15438
+ if (!cloneMetadata) {
15439
+ return null;
15440
+ }
15441
+ return this.getThreadById({ threadId: cloneMetadata.sourceThreadId });
15442
+ }
15443
+ /**
15444
+ * List all threads that were cloned from a specific source thread.
15445
+ *
15446
+ * @param sourceThreadId - ID of the source thread
15447
+ * @param resourceId - Optional resource ID to filter by
15448
+ * @returns Array of threads that are clones of the source thread
15449
+ *
15450
+ * @example
15451
+ * ```typescript
15452
+ * const clones = await memory.listClones('original-thread-123', 'user-456');
15453
+ * console.log(`Found ${clones.length} clones of this thread`);
15454
+ * ```
15455
+ */
15456
+ async listClones(sourceThreadId, resourceId) {
15457
+ let targetResourceId = resourceId;
15458
+ if (!targetResourceId) {
15459
+ const sourceThread = await this.getThreadById({ threadId: sourceThreadId });
15460
+ if (!sourceThread) {
15461
+ return [];
15462
+ }
15463
+ targetResourceId = sourceThread.resourceId;
15464
+ }
15465
+ const { threads } = await this.listThreadsByResourceId({
15466
+ resourceId: targetResourceId,
15467
+ perPage: false
15468
+ // Get all threads
15469
+ });
15470
+ return threads.filter((thread) => {
15471
+ const cloneMetadata = this.getCloneMetadata(thread);
15472
+ return cloneMetadata?.sourceThreadId === sourceThreadId;
15473
+ });
15474
+ }
15475
+ /**
15476
+ * Get the clone history chain for a thread (all ancestors back to the original).
15477
+ *
15478
+ * @param threadId - ID of the thread to get history for
15479
+ * @returns Array of threads from oldest ancestor to the given thread (inclusive)
15480
+ *
15481
+ * @example
15482
+ * ```typescript
15483
+ * const history = await memory.getCloneHistory('deeply-cloned-thread');
15484
+ * // Returns: [originalThread, firstClone, secondClone, deeplyClonedThread]
15485
+ * ```
15486
+ */
15487
+ async getCloneHistory(threadId) {
15488
+ const history = [];
15489
+ let currentThreadId = threadId;
15490
+ while (currentThreadId) {
15491
+ const thread = await this.getThreadById({ threadId: currentThreadId });
15492
+ if (!thread) {
15493
+ break;
15494
+ }
15495
+ history.unshift(thread);
15496
+ const cloneMetadata = this.getCloneMetadata(thread);
15497
+ currentThreadId = cloneMetadata?.sourceThreadId ?? null;
15498
+ }
15499
+ return history;
15500
+ }
15268
15501
  };
15269
15502
 
15270
15503
  export { Memory, deepMergeWorkingMemory };