@mastra/dynamodb 1.0.2 → 1.0.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @mastra/dynamodb
2
2
 
3
+ ## 1.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - dependencies updates: ([#14061](https://github.com/mastra-ai/mastra/pull/14061))
8
+ - Updated dependency [`@aws-sdk/client-dynamodb@^3.1004.0` ↗︎](https://www.npmjs.com/package/@aws-sdk/client-dynamodb/v/3.1004.0) (from `^3.902.0`, in `dependencies`)
9
+ - Updated dependency [`@aws-sdk/lib-dynamodb@^3.1004.0` ↗︎](https://www.npmjs.com/package/@aws-sdk/lib-dynamodb/v/3.1004.0) (from `^3.902.0`, in `dependencies`)
10
+
11
+ - Fixed slow semantic recall on large threads in the MongoDB and DynamoDB memory stores. Included message lookups now avoid unnecessary work when semantic recall only needs specific messages and nearby context. (Fixes #11702) ([#14022](https://github.com/mastra-ai/mastra/pull/14022))
12
+
13
+ - Updated dependencies [[`4f71b43`](https://github.com/mastra-ai/mastra/commit/4f71b436a4a6b8839842d8da47b57b84509af56c), [`a070277`](https://github.com/mastra-ai/mastra/commit/a07027766ce195ba74d0783116d894cbab25d44c), [`b628b91`](https://github.com/mastra-ai/mastra/commit/b628b9128b372c0f54214d902b07279f03443900), [`332c014`](https://github.com/mastra-ai/mastra/commit/332c014e076b81edf7fe45b58205882726415e90), [`6b63153`](https://github.com/mastra-ai/mastra/commit/6b63153878ea841c0f4ce632ba66bb33e57e9c1b), [`4246e34`](https://github.com/mastra-ai/mastra/commit/4246e34cec9c26636d0965942268e6d07c346671), [`b8837ee`](https://github.com/mastra-ai/mastra/commit/b8837ee77e2e84197609762bfabd8b3da326d30c), [`866cc2c`](https://github.com/mastra-ai/mastra/commit/866cc2cb1f0e3b314afab5194f69477fada745d1), [`5d950f7`](https://github.com/mastra-ai/mastra/commit/5d950f7bf426a215a1808f0abef7de5c8336ba1c), [`28c85b1`](https://github.com/mastra-ai/mastra/commit/28c85b184fc32b40f7f160483c982da6d388ecbd), [`e9a08fb`](https://github.com/mastra-ai/mastra/commit/e9a08fbef1ada7e50e961e2f54f55e8c10b4a45c), [`1d0a8a8`](https://github.com/mastra-ai/mastra/commit/1d0a8a8acf33203d5744fc429b090ad8598aa8ed), [`631ffd8`](https://github.com/mastra-ai/mastra/commit/631ffd82fed108648b448b28e6a90e38c5f53bf5), [`6bcbf8a`](https://github.com/mastra-ai/mastra/commit/6bcbf8a6774d5a53b21d61db8a45ce2593ca1616), [`aae2295`](https://github.com/mastra-ai/mastra/commit/aae2295838a2d329ad6640829e87934790ffe5b8), [`aa61f29`](https://github.com/mastra-ai/mastra/commit/aa61f29ff8095ce46a4ae16e46c4d8c79b2b685b), [`7ff3714`](https://github.com/mastra-ai/mastra/commit/7ff37148515439bb3be009a60e02c3e363299760), [`18c3a90`](https://github.com/mastra-ai/mastra/commit/18c3a90c9e48cf69500e308affeb8eba5860b2af), [`41d79a1`](https://github.com/mastra-ai/mastra/commit/41d79a14bd8cb6de1e2565fd0a04786bae2f211b), [`f35487b`](https://github.com/mastra-ai/mastra/commit/f35487bb2d46c636e22aa71d90025613ae38235a), [`6dc2192`](https://github.com/mastra-ai/mastra/commit/6dc21921aef0f0efab15cd0805fa3d18f277a76f), [`eeb3a3f`](https://github.com/mastra-ai/mastra/commit/eeb3a3f43aca10cf49479eed2a84b7d9ecea02ba), [`e673376`](https://github.com/mastra-ai/mastra/commit/e6733763ad1321aa7e5ae15096b9c2104f93b1f3), [`05f8d90`](https://github.com/mastra-ai/mastra/commit/05f8d9009290ce6aa03428b3add635268615db85), [`b2204c9`](https://github.com/mastra-ai/mastra/commit/b2204c98a42848bbfb6f0440f005dc2b6354f1cd), [`a1bf1e3`](https://github.com/mastra-ai/mastra/commit/a1bf1e385ed4c0ef6f11b56c5887442970d127f2), [`b6f647a`](https://github.com/mastra-ai/mastra/commit/b6f647ae2388e091f366581595feb957e37d5b40), [`0c57b8b`](https://github.com/mastra-ai/mastra/commit/0c57b8b0a69a97b5a4ae3f79be6c610f29f3cf7b), [`b081f27`](https://github.com/mastra-ai/mastra/commit/b081f272cf411716e1d6bd72ceac4bcee2657b19), [`4b8da97`](https://github.com/mastra-ai/mastra/commit/4b8da97a5ce306e97869df6c39535d9069e563db), [`0c09eac`](https://github.com/mastra-ai/mastra/commit/0c09eacb1926f64cfdc9ae5c6d63385cf8c9f72c), [`6b9b93d`](https://github.com/mastra-ai/mastra/commit/6b9b93d6f459d1ba6e36f163abf62a085ddb3d64), [`31b6067`](https://github.com/mastra-ai/mastra/commit/31b6067d0cc3ab10e1b29c36147f3b5266bc714a), [`797ac42`](https://github.com/mastra-ai/mastra/commit/797ac4276de231ad2d694d9aeca75980f6cd0419), [`0bc289e`](https://github.com/mastra-ai/mastra/commit/0bc289e2d476bf46c5b91c21969e8d0c6864691c), [`9b75a06`](https://github.com/mastra-ai/mastra/commit/9b75a06e53ebb0b950ba7c1e83a0142047185f46), [`4c3a1b1`](https://github.com/mastra-ai/mastra/commit/4c3a1b122ea083e003d71092f30f3b31680b01c0), [`256df35`](https://github.com/mastra-ai/mastra/commit/256df3571d62beb3ad4971faa432927cc140e603), [`85cc3b3`](https://github.com/mastra-ai/mastra/commit/85cc3b3b6f32ae4b083c26498f50d5b250ba944b), [`97ea28c`](https://github.com/mastra-ai/mastra/commit/97ea28c746e9e4147d56047bbb1c4a92417a3fec), [`d567299`](https://github.com/mastra-ai/mastra/commit/d567299cf81e02bd9d5221d4bc05967d6c224161), [`716ffe6`](https://github.com/mastra-ai/mastra/commit/716ffe68bed81f7c2690bc8581b9e140f7bf1c3d), [`8296332`](https://github.com/mastra-ai/mastra/commit/8296332de21c16e3dfc3d0b2d615720a6dc88f2f), [`4df2116`](https://github.com/mastra-ai/mastra/commit/4df211619dd922c047d396ca41cd7027c8c4c8e7), [`2219c1a`](https://github.com/mastra-ai/mastra/commit/2219c1acbd21da116da877f0036ffb985a9dd5a3), [`17c4145`](https://github.com/mastra-ai/mastra/commit/17c4145166099354545582335b5252bdfdfd908b)]:
14
+ - @mastra/core@1.11.0
15
+
16
+ ## 1.0.3-alpha.0
17
+
18
+ ### Patch Changes
19
+
20
+ - dependencies updates: ([#14061](https://github.com/mastra-ai/mastra/pull/14061))
21
+ - Updated dependency [`@aws-sdk/client-dynamodb@^3.1004.0` ↗︎](https://www.npmjs.com/package/@aws-sdk/client-dynamodb/v/3.1004.0) (from `^3.902.0`, in `dependencies`)
22
+ - Updated dependency [`@aws-sdk/lib-dynamodb@^3.1004.0` ↗︎](https://www.npmjs.com/package/@aws-sdk/lib-dynamodb/v/3.1004.0) (from `^3.902.0`, in `dependencies`)
23
+
24
+ - Fixed slow semantic recall on large threads in the MongoDB and DynamoDB memory stores. Included message lookups now avoid unnecessary work when semantic recall only needs specific messages and nearby context. (Fixes #11702) ([#14022](https://github.com/mastra-ai/mastra/pull/14022))
25
+
26
+ - Updated dependencies [[`4f71b43`](https://github.com/mastra-ai/mastra/commit/4f71b436a4a6b8839842d8da47b57b84509af56c), [`a070277`](https://github.com/mastra-ai/mastra/commit/a07027766ce195ba74d0783116d894cbab25d44c), [`b628b91`](https://github.com/mastra-ai/mastra/commit/b628b9128b372c0f54214d902b07279f03443900), [`332c014`](https://github.com/mastra-ai/mastra/commit/332c014e076b81edf7fe45b58205882726415e90), [`6b63153`](https://github.com/mastra-ai/mastra/commit/6b63153878ea841c0f4ce632ba66bb33e57e9c1b), [`4246e34`](https://github.com/mastra-ai/mastra/commit/4246e34cec9c26636d0965942268e6d07c346671), [`b8837ee`](https://github.com/mastra-ai/mastra/commit/b8837ee77e2e84197609762bfabd8b3da326d30c), [`5d950f7`](https://github.com/mastra-ai/mastra/commit/5d950f7bf426a215a1808f0abef7de5c8336ba1c), [`28c85b1`](https://github.com/mastra-ai/mastra/commit/28c85b184fc32b40f7f160483c982da6d388ecbd), [`e9a08fb`](https://github.com/mastra-ai/mastra/commit/e9a08fbef1ada7e50e961e2f54f55e8c10b4a45c), [`631ffd8`](https://github.com/mastra-ai/mastra/commit/631ffd82fed108648b448b28e6a90e38c5f53bf5), [`aae2295`](https://github.com/mastra-ai/mastra/commit/aae2295838a2d329ad6640829e87934790ffe5b8), [`aa61f29`](https://github.com/mastra-ai/mastra/commit/aa61f29ff8095ce46a4ae16e46c4d8c79b2b685b), [`7ff3714`](https://github.com/mastra-ai/mastra/commit/7ff37148515439bb3be009a60e02c3e363299760), [`41d79a1`](https://github.com/mastra-ai/mastra/commit/41d79a14bd8cb6de1e2565fd0a04786bae2f211b), [`e673376`](https://github.com/mastra-ai/mastra/commit/e6733763ad1321aa7e5ae15096b9c2104f93b1f3), [`b2204c9`](https://github.com/mastra-ai/mastra/commit/b2204c98a42848bbfb6f0440f005dc2b6354f1cd), [`a1bf1e3`](https://github.com/mastra-ai/mastra/commit/a1bf1e385ed4c0ef6f11b56c5887442970d127f2), [`b6f647a`](https://github.com/mastra-ai/mastra/commit/b6f647ae2388e091f366581595feb957e37d5b40), [`0c57b8b`](https://github.com/mastra-ai/mastra/commit/0c57b8b0a69a97b5a4ae3f79be6c610f29f3cf7b), [`b081f27`](https://github.com/mastra-ai/mastra/commit/b081f272cf411716e1d6bd72ceac4bcee2657b19), [`0c09eac`](https://github.com/mastra-ai/mastra/commit/0c09eacb1926f64cfdc9ae5c6d63385cf8c9f72c), [`6b9b93d`](https://github.com/mastra-ai/mastra/commit/6b9b93d6f459d1ba6e36f163abf62a085ddb3d64), [`31b6067`](https://github.com/mastra-ai/mastra/commit/31b6067d0cc3ab10e1b29c36147f3b5266bc714a), [`797ac42`](https://github.com/mastra-ai/mastra/commit/797ac4276de231ad2d694d9aeca75980f6cd0419), [`0bc289e`](https://github.com/mastra-ai/mastra/commit/0bc289e2d476bf46c5b91c21969e8d0c6864691c), [`9b75a06`](https://github.com/mastra-ai/mastra/commit/9b75a06e53ebb0b950ba7c1e83a0142047185f46), [`4c3a1b1`](https://github.com/mastra-ai/mastra/commit/4c3a1b122ea083e003d71092f30f3b31680b01c0), [`85cc3b3`](https://github.com/mastra-ai/mastra/commit/85cc3b3b6f32ae4b083c26498f50d5b250ba944b), [`97ea28c`](https://github.com/mastra-ai/mastra/commit/97ea28c746e9e4147d56047bbb1c4a92417a3fec), [`d567299`](https://github.com/mastra-ai/mastra/commit/d567299cf81e02bd9d5221d4bc05967d6c224161), [`716ffe6`](https://github.com/mastra-ai/mastra/commit/716ffe68bed81f7c2690bc8581b9e140f7bf1c3d), [`8296332`](https://github.com/mastra-ai/mastra/commit/8296332de21c16e3dfc3d0b2d615720a6dc88f2f), [`4df2116`](https://github.com/mastra-ai/mastra/commit/4df211619dd922c047d396ca41cd7027c8c4c8e7), [`2219c1a`](https://github.com/mastra-ai/mastra/commit/2219c1acbd21da116da877f0036ffb985a9dd5a3), [`17c4145`](https://github.com/mastra-ai/mastra/commit/17c4145166099354545582335b5252bdfdfd908b)]:
27
+ - @mastra/core@1.11.0-alpha.0
28
+
3
29
  ## 1.0.2
4
30
 
5
31
  ### Patch Changes
@@ -3,7 +3,7 @@ name: mastra-dynamodb
3
3
  description: Documentation for @mastra/dynamodb. Use when working with @mastra/dynamodb APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/dynamodb"
6
- version: "1.0.2"
6
+ version: "1.0.3"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -16,7 +16,7 @@ Read the individual reference documents for detailed explanations and code examp
16
16
 
17
17
  ### Reference
18
18
 
19
- - [Reference: DynamoDB Storage](references/reference-storage-dynamodb.md) - Documentation for the DynamoDB storage implementation in Mastra, using a single-table design with ElectroDB.
19
+ - [Reference: DynamoDB storage](references/reference-storage-dynamodb.md) - Documentation for the DynamoDB storage implementation in Mastra, using a single-table design with ElectroDB.
20
20
 
21
21
 
22
22
  Read [assets/SOURCE_MAP.json](assets/SOURCE_MAP.json) for source code references.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.2",
2
+ "version": "1.0.3",
3
3
  "package": "@mastra/dynamodb",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -1,8 +1,8 @@
1
- # DynamoDB Storage
1
+ # DynamoDB storage
2
2
 
3
3
  The DynamoDB storage implementation provides a scalable and performant NoSQL database solution for Mastra, leveraging a single-table design pattern with [ElectroDB](https://electrodb.dev/).
4
4
 
5
- > **Observability Not Supported:** DynamoDB storage **does not support the observability domain**. Traces from the `DefaultExporter` cannot be persisted to DynamoDB, and Mastra Studio's observability features won't work with DynamoDB as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse or PostgreSQL.
5
+ > **Observability Not Supported:** DynamoDB storage **doesn't support the observability domain**. Traces from the `DefaultExporter` can't be persisted to DynamoDB, and Mastra Studio's observability features won't work with DynamoDB as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse or PostgreSQL.
6
6
 
7
7
  > **Item Size Limit:** DynamoDB enforces a **400 KB maximum item size**. This limit can be exceeded when storing messages with base64-encoded attachments such as images. See [Handling large attachments](https://mastra.ai/docs/memory/storage) for workarounds including uploading attachments to external storage.
8
8
 
@@ -108,19 +108,19 @@ For local development, you can use [DynamoDB Local](https://docs.aws.amazon.com/
108
108
 
109
109
  ## Parameters
110
110
 
111
- **id:** (`string`): Unique identifier for this storage instance.
111
+ **id** (`string`): Unique identifier for this storage instance.
112
112
 
113
- **config.tableName:** (`string`): The name of your DynamoDB table.
113
+ **config.tableName** (`string`): The name of your DynamoDB table.
114
114
 
115
- **config.region?:** (`string`): AWS region. Defaults to 'us-east-1'. For local development, can be set to 'localhost' or similar.
115
+ **config.region** (`string`): AWS region. Defaults to 'us-east-1'. For local development, can be set to 'localhost' or similar.
116
116
 
117
- **config.endpoint?:** (`string`): Custom endpoint for DynamoDB (e.g., 'http\://localhost:8000' for local development).
117
+ **config.endpoint** (`string`): Custom endpoint for DynamoDB (e.g., 'http\://localhost:8000' for local development).
118
118
 
119
- **config.credentials?:** (`object`): AWS credentials object with \`accessKeyId\` and \`secretAccessKey\`. If not provided, the AWS SDK will attempt to source credentials from environment variables, IAM roles (e.g., for EC2/Lambda), or the shared AWS credentials file.
119
+ **config.credentials** (`object`): AWS credentials object with \`accessKeyId\` and \`secretAccessKey\`. If not provided, the AWS SDK will attempt to source credentials from environment variables, IAM roles (e.g., for EC2/Lambda), or the shared AWS credentials file.
120
120
 
121
- **config.ttl?:** (`object`): TTL (Time To Live) configuration for automatic data expiration. Configure per entity type: thread, message, trace, eval, workflow\_snapshot, resource, score. Each entity config includes: enabled (boolean), attributeName (string, default: 'ttl'), defaultTtlSeconds (number).
121
+ **config.ttl** (`object`): TTL (Time To Live) configuration for automatic data expiration. Configure per entity type: thread, message, trace, eval, workflow\_snapshot, resource, score. Each entity config includes: enabled (boolean), attributeName (string, default: 'ttl'), defaultTtlSeconds (number).
122
122
 
123
- ## TTL (Time To Live) Configuration
123
+ ## TTL (time to live) configuration
124
124
 
125
125
  DynamoDB TTL allows you to automatically delete items after a specified time period. This is useful for:
126
126
 
@@ -188,11 +188,11 @@ TTL can be configured for these entity types:
188
188
 
189
189
  Each entity type accepts the following configuration:
190
190
 
191
- **enabled:** (`boolean`): Whether TTL is enabled for this entity type.
191
+ **enabled** (`boolean`): Whether TTL is enabled for this entity type.
192
192
 
193
- **attributeName?:** (`string`): The DynamoDB attribute name to use for TTL. Must match the TTL attribute configured on your DynamoDB table. Defaults to 'ttl'.
193
+ **attributeName** (`string`): The DynamoDB attribute name to use for TTL. Must match the TTL attribute configured on your DynamoDB table. Defaults to 'ttl'.
194
194
 
195
- **defaultTtlSeconds?:** (`number`): Default TTL in seconds from item creation time. Items will be automatically deleted by DynamoDB after this duration.
195
+ **defaultTtlSeconds** (`number`): Default TTL in seconds from item creation time. Items will be automatically deleted by DynamoDB after this duration.
196
196
 
197
197
  ### Enabling TTL on Your DynamoDB Table
198
198
 
@@ -211,12 +211,12 @@ aws dynamodb update-time-to-live \
211
211
  1. Go to the DynamoDB console
212
212
  2. Select your table
213
213
  3. Go to "Additional settings" tab
214
- 4. Under "Time to Live (TTL)", click "Manage TTL"
214
+ 4. Under "Time to Live (TTL)", select "Manage TTL"
215
215
  5. Enable TTL and specify the attribute name (default: `ttl`)
216
216
 
217
217
  > **Note:** DynamoDB deletes expired items within 48 hours after expiration. Items remain queryable until actually deleted.
218
218
 
219
- ## AWS IAM Permissions
219
+ ## AWS IAM permissions
220
220
 
221
221
  The IAM role or user executing the code needs appropriate permissions to interact with the specified DynamoDB table and its indexes. Below is a sample policy. Replace `${YOUR_TABLE_NAME}` with your actual table name and `${YOUR_AWS_REGION}` and `${YOUR_AWS_ACCOUNT_ID}` with appropriate values.
222
222
 
@@ -246,7 +246,7 @@ The IAM role or user executing the code needs appropriate permissions to interac
246
246
  }
247
247
  ```
248
248
 
249
- ## Key Considerations
249
+ ## Key considerations
250
250
 
251
251
  Before diving into the architectural details, keep these key points in mind when working with the DynamoDB storage adapter:
252
252
 
@@ -255,7 +255,7 @@ Before diving into the architectural details, keep these key points in mind when
255
255
  - **Understanding GSIs:** Familiarity with how the GSIs are structured (as per `TABLE_SETUP.md`) is important for understanding data retrieval and potential query patterns.
256
256
  - **ElectroDB:** The adapter uses ElectroDB to manage interactions with DynamoDB, providing a layer of abstraction and type safety over raw DynamoDB operations.
257
257
 
258
- ## Architectural Approach
258
+ ## Architectural approach
259
259
 
260
260
  This storage adapter utilizes a **single-table design pattern** leveraging [ElectroDB](https://electrodb.dev/), a common and recommended approach for DynamoDB. This differs architecturally from relational database adapters (like `@mastra/pg` or `@mastra/libsql`) that typically use multiple tables, each dedicated to a specific entity (threads, messages, etc.).
261
261
 
package/dist/index.cjs CHANGED
@@ -1347,6 +1347,20 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1347
1347
  field,
1348
1348
  direction
1349
1349
  });
1350
+ if (perPage === 0 && (!include || include.length === 0)) {
1351
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
1352
+ }
1353
+ if (perPage === 0 && include && include.length > 0) {
1354
+ const includeMessages2 = await this._getIncludedMessages({ include });
1355
+ const list2 = new agent.MessageList().add(includeMessages2, "memory");
1356
+ return {
1357
+ messages: this._sortMessages(list2.get.all.db(), field, direction),
1358
+ total: 0,
1359
+ page,
1360
+ perPage: perPageForResponse,
1361
+ hasMore: false
1362
+ };
1363
+ }
1350
1364
  const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1351
1365
  const results = await query.go();
1352
1366
  let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg && typeof msg.content === "object");
@@ -1381,8 +1395,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1381
1395
  const messageIds = new Set(paginatedMessages.map((m) => m.id));
1382
1396
  let includeMessages = [];
1383
1397
  if (include && include.length > 0) {
1384
- const selectBy = { include };
1385
- includeMessages = await this._getIncludedMessages(selectBy);
1398
+ includeMessages = await this._getIncludedMessages({ include });
1386
1399
  for (const includeMsg of includeMessages) {
1387
1400
  if (!messageIds.has(includeMsg.id)) {
1388
1401
  paginatedMessages.push(includeMsg);
@@ -1392,14 +1405,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1392
1405
  }
1393
1406
  const list = new agent.MessageList().add(paginatedMessages, "memory");
1394
1407
  let finalMessages = list.get.all.db();
1395
- finalMessages = finalMessages.sort((a, b) => {
1396
- const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1397
- const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1398
- if (aValue === bValue) {
1399
- return a.id.localeCompare(b.id);
1400
- }
1401
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
1402
- });
1408
+ finalMessages = this._sortMessages(finalMessages, field, direction);
1403
1409
  const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
1404
1410
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1405
1411
  let hasMore = false;
@@ -1586,68 +1592,74 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1586
1592
  }
1587
1593
  }
1588
1594
  // Helper method to get included messages with context
1589
- async _getIncludedMessages(selectBy) {
1590
- if (!selectBy?.include?.length) {
1595
+ _sortMessages(messages, field, direction) {
1596
+ return messages.sort((a, b) => {
1597
+ const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1598
+ const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1599
+ if (aValue === bValue) {
1600
+ return a.id.localeCompare(b.id);
1601
+ }
1602
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
1603
+ });
1604
+ }
1605
+ async _getIncludedMessages({
1606
+ include
1607
+ }) {
1608
+ if (!include?.length) {
1591
1609
  return [];
1592
1610
  }
1593
- const includeMessages = [];
1594
- for (const includeItem of selectBy.include) {
1595
- try {
1596
- const { id, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
1597
- const targetResult = await this.service.entities.message.get({ entity: "message", id }).go();
1598
- if (!targetResult.data) {
1599
- this.logger.warn("Target message not found", { id });
1600
- continue;
1601
- }
1602
- const targetMessageData = targetResult.data;
1603
- const searchThreadId = targetMessageData.threadId;
1604
- this.logger.debug("Getting included messages for", {
1605
- id,
1606
- searchThreadId,
1607
- withPreviousMessages,
1608
- withNextMessages
1609
- });
1610
- const query = this.service.entities.message.query.byThread({ entity: "message", threadId: searchThreadId });
1611
- const results = await query.go();
1612
- const allMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg && typeof msg.content === "object");
1613
- this.logger.debug("Found messages in thread", {
1614
- threadId: searchThreadId,
1615
- messageCount: allMessages.length,
1616
- messageIds: allMessages.map((m) => m.id)
1617
- });
1618
- allMessages.sort((a, b) => {
1619
- const timeA = a.createdAt.getTime();
1620
- const timeB = b.createdAt.getTime();
1621
- if (timeA === timeB) {
1622
- return a.id.localeCompare(b.id);
1623
- }
1624
- return timeA - timeB;
1625
- });
1626
- const targetIndex = allMessages.findIndex((msg) => msg.id === id);
1627
- if (targetIndex === -1) {
1628
- this.logger.warn("Target message not found in thread", { id, threadId: searchThreadId });
1629
- continue;
1630
- }
1631
- this.logger.debug("Found target message at index", { id, targetIndex, totalMessages: allMessages.length });
1632
- const startIndex = Math.max(0, targetIndex - withPreviousMessages);
1633
- const endIndex = Math.min(allMessages.length, targetIndex + withNextMessages + 1);
1634
- const contextMessages = allMessages.slice(startIndex, endIndex);
1635
- this.logger.debug("Context messages", {
1636
- startIndex,
1637
- endIndex,
1638
- contextCount: contextMessages.length,
1639
- contextIds: contextMessages.map((m) => m.id)
1640
- });
1641
- includeMessages.push(...contextMessages);
1642
- } catch (error) {
1643
- this.logger.warn("Failed to get included message", { messageId: includeItem.id, error });
1611
+ const targetResults = await Promise.all(
1612
+ include.map(
1613
+ (inc) => this.service.entities.message.get({ entity: "message", id: inc.id }).go().then((r) => ({ id: inc.id, data: r.data })).catch(() => ({ id: inc.id, data: null }))
1614
+ )
1615
+ );
1616
+ const targetMap = /* @__PURE__ */ new Map();
1617
+ for (const { id, data } of targetResults) {
1618
+ if (data) {
1619
+ targetMap.set(id, { threadId: data.threadId });
1644
1620
  }
1645
1621
  }
1646
- this.logger.debug("Total included messages", {
1647
- count: includeMessages.length,
1648
- ids: includeMessages.map((m) => m.id)
1622
+ if (targetMap.size === 0) return [];
1623
+ const threadCache = /* @__PURE__ */ new Map();
1624
+ const uniqueThreadIds = [...new Set([...targetMap.values()].map((t) => t.threadId))];
1625
+ await Promise.all(
1626
+ uniqueThreadIds.map(async (threadId) => {
1627
+ try {
1628
+ const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1629
+ const results = await query.go();
1630
+ const messages = results.data.map((data) => this.parseMessageData(data)).filter(
1631
+ (msg) => "content" in msg && typeof msg.content === "object"
1632
+ );
1633
+ messages.sort((a, b) => {
1634
+ const timeA = a.createdAt.getTime();
1635
+ const timeB = b.createdAt.getTime();
1636
+ if (timeA === timeB) return a.id.localeCompare(b.id);
1637
+ return timeA - timeB;
1638
+ });
1639
+ threadCache.set(threadId, messages);
1640
+ } catch {
1641
+ }
1642
+ })
1643
+ );
1644
+ const includeMessages = [];
1645
+ for (const includeItem of include) {
1646
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
1647
+ const target = targetMap.get(id);
1648
+ if (!target) continue;
1649
+ const allMessages = threadCache.get(target.threadId);
1650
+ if (!allMessages) continue;
1651
+ const targetIndex = allMessages.findIndex((msg) => msg.id === id);
1652
+ if (targetIndex === -1) continue;
1653
+ const startIndex = Math.max(0, targetIndex - withPreviousMessages);
1654
+ const endIndex = Math.min(allMessages.length, targetIndex + withNextMessages + 1);
1655
+ includeMessages.push(...allMessages.slice(startIndex, endIndex));
1656
+ }
1657
+ const seen = /* @__PURE__ */ new Set();
1658
+ return includeMessages.filter((msg) => {
1659
+ if (seen.has(msg.id)) return false;
1660
+ seen.add(msg.id);
1661
+ return true;
1649
1662
  });
1650
- return includeMessages;
1651
1663
  }
1652
1664
  async updateMessages(args) {
1653
1665
  const { messages } = args;