@mongodb-js/agent-engine-sdk-langgraph 0.11.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.
Files changed (128) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/LICENSE.md +201 -0
  3. package/README.md +149 -0
  4. package/dist/agent.d.ts +53 -0
  5. package/dist/agent.d.ts.map +1 -0
  6. package/dist/agent.js +508 -0
  7. package/dist/agent.js.map +1 -0
  8. package/dist/backends/tool_sandbox.d.ts +15 -0
  9. package/dist/backends/tool_sandbox.d.ts.map +1 -0
  10. package/dist/backends/tool_sandbox.js +15 -0
  11. package/dist/backends/tool_sandbox.js.map +1 -0
  12. package/dist/backends/toolpod.d.ts +68 -0
  13. package/dist/backends/toolpod.d.ts.map +1 -0
  14. package/dist/backends/toolpod.js +451 -0
  15. package/dist/backends/toolpod.js.map +1 -0
  16. package/dist/call_interrupt.d.ts +20 -0
  17. package/dist/call_interrupt.d.ts.map +1 -0
  18. package/dist/call_interrupt.js +23 -0
  19. package/dist/call_interrupt.js.map +1 -0
  20. package/dist/checkpoint_branch.d.ts +58 -0
  21. package/dist/checkpoint_branch.d.ts.map +1 -0
  22. package/dist/checkpoint_branch.js +239 -0
  23. package/dist/checkpoint_branch.js.map +1 -0
  24. package/dist/checkpointer.d.ts +21 -0
  25. package/dist/checkpointer.d.ts.map +1 -0
  26. package/dist/checkpointer.js +31 -0
  27. package/dist/checkpointer.js.map +1 -0
  28. package/dist/deep_agent.d.ts +49 -0
  29. package/dist/deep_agent.d.ts.map +1 -0
  30. package/dist/deep_agent.js +110 -0
  31. package/dist/deep_agent.js.map +1 -0
  32. package/dist/deep_agent_checkpointer.d.ts +11 -0
  33. package/dist/deep_agent_checkpointer.d.ts.map +1 -0
  34. package/dist/deep_agent_checkpointer.js +19 -0
  35. package/dist/deep_agent_checkpointer.js.map +1 -0
  36. package/dist/deep_agent_task.d.ts +26 -0
  37. package/dist/deep_agent_task.d.ts.map +1 -0
  38. package/dist/deep_agent_task.js +49 -0
  39. package/dist/deep_agent_task.js.map +1 -0
  40. package/dist/durable_deep_agent.d.ts +23 -0
  41. package/dist/durable_deep_agent.d.ts.map +1 -0
  42. package/dist/durable_deep_agent.js +176 -0
  43. package/dist/durable_deep_agent.js.map +1 -0
  44. package/dist/durable_message_identity.d.ts +5 -0
  45. package/dist/durable_message_identity.d.ts.map +1 -0
  46. package/dist/durable_message_identity.js +106 -0
  47. package/dist/durable_message_identity.js.map +1 -0
  48. package/dist/durable_session.d.ts +30 -0
  49. package/dist/durable_session.d.ts.map +1 -0
  50. package/dist/durable_session.js +400 -0
  51. package/dist/durable_session.js.map +1 -0
  52. package/dist/durable_subgraphs.d.ts +13 -0
  53. package/dist/durable_subgraphs.d.ts.map +1 -0
  54. package/dist/durable_subgraphs.js +82 -0
  55. package/dist/durable_subgraphs.js.map +1 -0
  56. package/dist/durable_tools.d.ts +12 -0
  57. package/dist/durable_tools.d.ts.map +1 -0
  58. package/dist/durable_tools.js +41 -0
  59. package/dist/durable_tools.js.map +1 -0
  60. package/dist/execution_session.d.ts +63 -0
  61. package/dist/execution_session.d.ts.map +1 -0
  62. package/dist/execution_session.js +300 -0
  63. package/dist/execution_session.js.map +1 -0
  64. package/dist/index.d.ts +19 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +17 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/llm_adapter.d.ts +41 -0
  69. package/dist/llm_adapter.d.ts.map +1 -0
  70. package/dist/llm_adapter.js +177 -0
  71. package/dist/llm_adapter.js.map +1 -0
  72. package/dist/messages.d.ts +56 -0
  73. package/dist/messages.d.ts.map +1 -0
  74. package/dist/messages.js +592 -0
  75. package/dist/messages.js.map +1 -0
  76. package/dist/node_logger_adapter.d.ts +51 -0
  77. package/dist/node_logger_adapter.d.ts.map +1 -0
  78. package/dist/node_logger_adapter.js +163 -0
  79. package/dist/node_logger_adapter.js.map +1 -0
  80. package/dist/platform_checkpointer.d.ts +70 -0
  81. package/dist/platform_checkpointer.d.ts.map +1 -0
  82. package/dist/platform_checkpointer.js +252 -0
  83. package/dist/platform_checkpointer.js.map +1 -0
  84. package/dist/query.d.ts +103 -0
  85. package/dist/query.d.ts.map +1 -0
  86. package/dist/query.js +623 -0
  87. package/dist/query.js.map +1 -0
  88. package/dist/runtime.d.ts +336 -0
  89. package/dist/runtime.d.ts.map +1 -0
  90. package/dist/runtime.js +881 -0
  91. package/dist/runtime.js.map +1 -0
  92. package/dist/secure_llm.d.ts +93 -0
  93. package/dist/secure_llm.d.ts.map +1 -0
  94. package/dist/secure_llm.js +423 -0
  95. package/dist/secure_llm.js.map +1 -0
  96. package/dist/session_factory.d.ts +6 -0
  97. package/dist/session_factory.d.ts.map +1 -0
  98. package/dist/session_factory.js +29 -0
  99. package/dist/session_factory.js.map +1 -0
  100. package/dist/session_fork.d.ts +76 -0
  101. package/dist/session_fork.d.ts.map +1 -0
  102. package/dist/session_fork.js +428 -0
  103. package/dist/session_fork.js.map +1 -0
  104. package/dist/subagents.d.ts +37 -0
  105. package/dist/subagents.d.ts.map +1 -0
  106. package/dist/subagents.js +67 -0
  107. package/dist/subagents.js.map +1 -0
  108. package/dist/suspend.d.ts +27 -0
  109. package/dist/suspend.d.ts.map +1 -0
  110. package/dist/suspend.js +87 -0
  111. package/dist/suspend.js.map +1 -0
  112. package/dist/thread_id.d.ts +30 -0
  113. package/dist/thread_id.d.ts.map +1 -0
  114. package/dist/thread_id.js +69 -0
  115. package/dist/thread_id.js.map +1 -0
  116. package/dist/workflow_json.d.ts +11 -0
  117. package/dist/workflow_json.d.ts.map +1 -0
  118. package/dist/workflow_json.js +49 -0
  119. package/dist/workflow_json.js.map +1 -0
  120. package/dist/workflow_message.d.ts +11 -0
  121. package/dist/workflow_message.d.ts.map +1 -0
  122. package/dist/workflow_message.js +179 -0
  123. package/dist/workflow_message.js.map +1 -0
  124. package/dist/workflow_state.d.ts +7 -0
  125. package/dist/workflow_state.d.ts.map +1 -0
  126. package/dist/workflow_state.js +62 -0
  127. package/dist/workflow_state.js.map +1 -0
  128. package/package.json +66 -0
package/dist/query.js ADDED
@@ -0,0 +1,623 @@
1
+ /**
2
+ * LangGraph-backed implementation of runner-shared's `AERQueryPlugin`.
3
+ *
4
+ * Reads from the same MongoDB collections that LangGraph's `MongoDBSaver`
5
+ * writes to (`checkpoints`, `checkpoint_writes`). Deserialization is
6
+ * delegated to the saver's `serde` so this code does not need to know how
7
+ * LangGraph encodes state on disk.
8
+ *
9
+ * Port of Python's `agent_engine_sdk_langgraph/query.py`. One structural
10
+ * difference: the JS `MongoDBSaver` keeps its `Db` handle protected, so the
11
+ * plugin is constructed with the `MongoClient` + database name instead.
12
+ *
13
+ * Checkpoints are keyed by a workspace-scoped `thread_id` — see
14
+ * `thread_id.ts`. The plugin composes that scope onto the plain `session_id`
15
+ * it receives before querying, and strips it back off before returning.
16
+ * Reads never query the bare unscoped key when a workspace scope is known:
17
+ * bare keys are shared across every workspace on the store.
18
+ * An empty scope is legitimate only on explicitly unscoped runtimes (local
19
+ * dev / tests, no `APP_ID`), whose writes are bare-keyed to match. Managed
20
+ * runtimes carry `REQUIRE_PROJECT_SCOPED_DB` and reject a missing `APP_ID`.
21
+ */
22
+ import { LLMToolCall, } from "@mongodb-js/agent-engine-sdk";
23
+ import { getLogger } from "@mongodb-js/agent-engine-runner-shared";
24
+ import { sessionIdFromThreadId, threadIdsForQuery, threadIdsForSessionsQuery, } from "./thread_id.js";
25
+ const logger = getLogger("agent_engine_sdk_langgraph.query");
26
+ const PREVIEW_MAX_CHARS = 80;
27
+ const PREVIEW_WRITES_PER_SESSION = 5;
28
+ // Cap on the bytes logged from a deserialization exception. langgraph's
29
+ // serde errors can carry chunks of the raw on-disk payload (and therefore
30
+ // user content) — truncate so a Splunk-visible warning never doubles as a
31
+ // data-leak vector.
32
+ const DESERIALIZATION_ERROR_MAX_CHARS = 200;
33
+ // Cap the per-session checkpoint scan in `getMessagesForSession`. LangGraph
34
+ // writes one checkpoint per graph step, so an unbounded scan is O(turns) in
35
+ // both DB I/O and deserialization cost. Sessions with more than this many
36
+ // checkpoints return the messages present in the most recent
37
+ // `MAX_CHECKPOINTS_PER_SESSION` checkpoints; older turns are not surfaced.
38
+ // Raise this if real sessions routinely exceed it.
39
+ const MAX_CHECKPOINTS_PER_SESSION = 500;
40
+ // Time budgets on the read paths so a slow / hung MongoDB fails the request
41
+ // fast instead of pinning it.
42
+ const AGGREGATION_TIMEOUT_MS = 15_000;
43
+ const MESSAGE_READ_TIMEOUT_MS = 20_000;
44
+ // Cap on how many per-session checkpoint scans the summaries path runs at
45
+ // once. A sessions-list request can name hundreds of sessions; without a bound
46
+ // each one would open its own checkpoint cursor simultaneously, so a single
47
+ // request could hold hundreds of concurrent Mongo cursors and deserialize
48
+ // hundreds of checkpoint windows in parallel.
49
+ const MESSAGE_COUNT_CONCURRENCY = 10;
50
+ // LangChain message type → platform Message role used on the wire.
51
+ // Matches the live invoke/stream vocabulary in sdk-core (`Role`: user, assistant,
52
+ // tool, system). "function" is an older LangChain message type collapsed onto
53
+ // "tool" so callers do not need to distinguish.
54
+ const ROLE_MAP = {
55
+ human: "user",
56
+ ai: "assistant",
57
+ system: "system",
58
+ tool: "tool",
59
+ function: "tool",
60
+ };
61
+ /** AERQueryPlugin backed by LangGraph's MongoDBSaver. */
62
+ export class LangGraphQueryPlugin {
63
+ saver;
64
+ checkpointsCollection;
65
+ writesCollection;
66
+ workspaceId;
67
+ workspaceIdResolver;
68
+ constructor(params) {
69
+ this.saver = params.saver;
70
+ const db = params.client.db(params.dbName);
71
+ this.checkpointsCollection = db.collection(params.saver.checkpointCollectionName);
72
+ this.writesCollection = db.collection(params.saver.checkpointWritesCollectionName);
73
+ this.workspaceId = params.workspaceId ?? "";
74
+ this.workspaceIdResolver = params.workspaceIdResolver;
75
+ }
76
+ /**
77
+ * Resolve the workspace scope for a read. "" is a legitimate scope — an
78
+ * explicitly unscoped runtime (local dev / tests, no APP_ID) whose
79
+ * checkpoints are bare-keyed by construction, matching the write path. The
80
+ * runner rejects this state when managed-runtime scoping is required. A
81
+ * resolver returning null/undefined signals a genuinely unresolvable scope
82
+ * (a custom resolver that cannot make that call) and fails closed rather
83
+ * than silently reading the shared store.
84
+ */
85
+ effectiveWorkspaceId() {
86
+ if (this.workspaceIdResolver !== undefined) {
87
+ const resolved = this.workspaceIdResolver();
88
+ if (resolved === null || resolved === undefined) {
89
+ throw new Error("checkpoint workspace scope unavailable; refusing to serve " +
90
+ "session queries without a workspace");
91
+ }
92
+ return resolved;
93
+ }
94
+ return this.workspaceId;
95
+ }
96
+ async getSummariesForSessions(sessionIds) {
97
+ if (sessionIds.length === 0) {
98
+ return { sessions: [] };
99
+ }
100
+ return {
101
+ sessions: await this.aggregateSessionSummaries([...sessionIds]),
102
+ };
103
+ }
104
+ async getMessagesForSession(sessionId) {
105
+ const authoritative = await this.loadAuthoritativeMessages(sessionId);
106
+ if (authoritative === null) {
107
+ return { messages: [] };
108
+ }
109
+ const { messages, firstAppearanceByIndex } = authoritative;
110
+ return {
111
+ messages: messages.map((message, messageIndex) => toSessionMessage({
112
+ message,
113
+ sessionId,
114
+ messageIndex,
115
+ timestamp: firstAppearanceByIndex.get(messageIndex) ?? "",
116
+ })),
117
+ };
118
+ }
119
+ /**
120
+ * Resolve a session's authoritative message list: the `messages` channel of
121
+ * the most recent checkpoint that carries a usable one, plus each message
122
+ * index's first-appearance timestamp. Returns null when no checkpoint has a
123
+ * usable `messages` channel.
124
+ *
125
+ * Both the messages endpoint and the sessions-list `message_count` derive
126
+ * from this so the two always agree — `message_count` reports the
127
+ * number of messages, not the number of checkpoints.
128
+ */
129
+ async loadAuthoritativeMessages(sessionId) {
130
+ // A corrupt checkpoint here propagates to the caller rather than being
131
+ // silently skipped: that's the right call for state-store corruption. On
132
+ // the messages endpoint it surfaces as a 500; `collectMessageCounts`
133
+ // downgrades it per session so one bad session can't fail a whole list.
134
+ const threadIds = threadIdsForQuery(sessionId, this.effectiveWorkspaceId());
135
+ const checkpointsNewestFirst = await this.collectCheckpointsForThreadIds(threadIds);
136
+ // The most recent checkpoint with a usable `messages` list is the
137
+ // authoritative message list.
138
+ const checkpointsWithMessagesNewestFirst = [];
139
+ for (const checkpointTuple of checkpointsNewestFirst) {
140
+ const messages = extractMessages(checkpointTuple);
141
+ if (messages !== null) {
142
+ checkpointsWithMessagesNewestFirst.push([checkpointTuple, messages]);
143
+ }
144
+ }
145
+ const newestEntry = checkpointsWithMessagesNewestFirst[0];
146
+ if (newestEntry === undefined) {
147
+ return null;
148
+ }
149
+ return {
150
+ messages: newestEntry[1],
151
+ firstAppearanceByIndex: attributeFirstAppearanceTimestamps(checkpointsWithMessagesNewestFirst),
152
+ };
153
+ }
154
+ /**
155
+ * Materialize a bounded checkpoint window across one or more thread keys.
156
+ *
157
+ * The scan is wrapped in a wall-clock deadline rather than checked between
158
+ * yields: the driver's `MongoClient` is constructed without socket/read
159
+ * timeouts, so a stalled cursor can leave the `for await` parked forever and
160
+ * an in-loop clock check would never run.
161
+ */
162
+ async collectCheckpointsForThreadIds(threadIds) {
163
+ return withDeadline(this.streamCheckpointsForThreadIds(threadIds), MESSAGE_READ_TIMEOUT_MS, `session message read timed out after ${MESSAGE_READ_TIMEOUT_MS}ms`);
164
+ }
165
+ async streamCheckpointsForThreadIds(threadIds) {
166
+ const checkpoints = [];
167
+ for (const threadId of threadIds) {
168
+ for await (const checkpointTuple of this.saver.list({ configurable: { thread_id: threadId } }, { limit: MAX_CHECKPOINTS_PER_SESSION })) {
169
+ checkpoints.push(checkpointTuple);
170
+ }
171
+ }
172
+ checkpoints.sort((left, right) => checkpointTimestamp(right).localeCompare(checkpointTimestamp(left)));
173
+ return checkpoints.slice(0, MAX_CHECKPOINTS_PER_SESSION);
174
+ }
175
+ // ------------------------------------------------------------------
176
+ // Session summaries
177
+ // ------------------------------------------------------------------
178
+ async aggregateSessionSummaries(sessionIds) {
179
+ const workspaceId = this.effectiveWorkspaceId();
180
+ const threadIds = threadIdsForSessionsQuery(sessionIds, workspaceId);
181
+ const aggregateDocs = await this.checkpointsCollection
182
+ .aggregate(sessionSummariesPipeline(threadIds), {
183
+ maxTimeMS: AGGREGATION_TIMEOUT_MS,
184
+ })
185
+ .toArray();
186
+ const aggregateDocBySessionId = new Map();
187
+ for (const aggregateDoc of aggregateDocs) {
188
+ const sessionId = sessionIdFromThreadId(String(aggregateDoc["_id"] ?? ""), workspaceId);
189
+ if (sessionId === "")
190
+ continue;
191
+ const existing = aggregateDocBySessionId.get(sessionId);
192
+ aggregateDocBySessionId.set(sessionId, mergeSessionSummaryAggregate(existing, aggregateDoc));
193
+ }
194
+ const summarySessionIds = [...aggregateDocBySessionId.keys()];
195
+ const [previewBySessionId, messageCountBySessionId] = await Promise.all([
196
+ this.collectPreviews(summarySessionIds),
197
+ this.collectMessageCounts(summarySessionIds),
198
+ ]);
199
+ return [...aggregateDocBySessionId.entries()].map(([sessionId, aggregateDoc]) => ({
200
+ session_id: sessionId,
201
+ last_activity: isoOrEmpty(aggregateDoc["latest_ts"]),
202
+ created_at: isoOrEmpty(aggregateDoc["first_ts"]),
203
+ message_count: messageCountBySessionId.get(sessionId) ?? 0,
204
+ first_message_preview: previewBySessionId.get(sessionId) ?? "",
205
+ }));
206
+ }
207
+ /**
208
+ * Count messages per session from the same authoritative list the messages
209
+ * endpoint returns, so a summary's `message_count` matches that endpoint
210
+ * exactly. Sessions with no usable checkpoint count as 0.
211
+ *
212
+ * Unlike the single-session messages endpoint — where a corrupt checkpoint
213
+ * rightly surfaces as a 500 — a failed read here degrades that one session's
214
+ * count to 0 and leaves the rest of the list intact. One unreadable session
215
+ * must not take down a summaries request naming hundreds of others.
216
+ */
217
+ async collectMessageCounts(sessionIds) {
218
+ const counts = new Map();
219
+ for (let offset = 0; offset < sessionIds.length; offset += MESSAGE_COUNT_CONCURRENCY) {
220
+ const chunk = sessionIds.slice(offset, offset + MESSAGE_COUNT_CONCURRENCY);
221
+ await Promise.all(chunk.map(async (sessionId) => {
222
+ try {
223
+ const authoritative = await this.loadAuthoritativeMessages(sessionId);
224
+ counts.set(sessionId, authoritative?.messages.length ?? 0);
225
+ }
226
+ catch (exc) {
227
+ logger.warn({ sessionId, error: String(exc) }, "message count unavailable for session; reporting 0");
228
+ counts.set(sessionId, 0);
229
+ }
230
+ }));
231
+ }
232
+ return counts;
233
+ }
234
+ async collectPreviews(sessionIds) {
235
+ const previews = new Map();
236
+ if (sessionIds.length === 0)
237
+ return previews;
238
+ const workspaceId = this.effectiveWorkspaceId();
239
+ const threadIds = threadIdsForSessionsQuery(sessionIds, workspaceId);
240
+ const aggregateDocs = await this.writesCollection
241
+ .aggregate(messagePreviewsPipeline(threadIds), {
242
+ maxTimeMS: AGGREGATION_TIMEOUT_MS,
243
+ })
244
+ .toArray();
245
+ const writesBySessionId = new Map();
246
+ for (const aggregateDoc of aggregateDocs) {
247
+ const sessionId = sessionIdFromThreadId(String(aggregateDoc["_id"] ?? ""), workspaceId);
248
+ if (sessionId === "")
249
+ continue;
250
+ const candidateWrites = Array.isArray(aggregateDoc["writes"])
251
+ ? aggregateDoc["writes"]
252
+ : [];
253
+ const existing = writesBySessionId.get(sessionId) ?? [];
254
+ writesBySessionId.set(sessionId, [...existing, ...candidateWrites]);
255
+ }
256
+ for (const [sessionId, candidateWrites] of writesBySessionId.entries()) {
257
+ const preview = await this.firstNonEmptyHumanPreview(candidateWrites, sessionId);
258
+ if (preview !== "")
259
+ previews.set(sessionId, preview);
260
+ }
261
+ return previews;
262
+ }
263
+ /**
264
+ * Return the first non-empty human-message preview across `writes`.
265
+ *
266
+ * `writes` is the per-session accumulation from the preview pipeline,
267
+ * ordered oldest-first. Returns `""` if no write decodes to a human
268
+ * message with text content.
269
+ */
270
+ async firstNonEmptyHumanPreview(candidateWrites, sessionId) {
271
+ for (const writeRecord of candidateWrites) {
272
+ const preview = await this.decodeHumanPreview(writeRecord, sessionId);
273
+ if (preview !== "")
274
+ return preview;
275
+ }
276
+ return "";
277
+ }
278
+ /**
279
+ * Decode a single `checkpoint_writes` document and return the first
280
+ * human-authored text content it contains, truncated.
281
+ *
282
+ * Returns `""` for non-human writes, malformed writes, and any
283
+ * deserialization failures (logged at WARNING for observability).
284
+ */
285
+ async decodeHumanPreview(writeRecord, sessionId) {
286
+ const serdeTypeTag = writeRecord["type"];
287
+ const serdeData = toSerdeData(writeRecord["value"]);
288
+ if (typeof serdeTypeTag !== "string" || serdeTypeTag === "")
289
+ return "";
290
+ if (serdeData === null)
291
+ return "";
292
+ let deserialized;
293
+ try {
294
+ deserialized = await this.saver.serde.loadsTyped(serdeTypeTag, serdeData);
295
+ }
296
+ catch (exc) {
297
+ // Warn (not debug) so schema drift / data corruption is visible in
298
+ // Splunk instead of silently serving empty previews.
299
+ const excName = exc instanceof Error ? exc.name : typeof exc;
300
+ const excMessage = exc instanceof Error ? exc.message : String(exc);
301
+ logger.warn(`preview deserialization failed for session ${sessionId}: ` +
302
+ `${excName}: ${excMessage.slice(0, DESERIALIZATION_ERROR_MAX_CHARS)}`);
303
+ return "";
304
+ }
305
+ const decodedMessages = Array.isArray(deserialized)
306
+ ? deserialized
307
+ : [deserialized];
308
+ for (const decodedMessage of decodedMessages) {
309
+ const content = humanContent(decodedMessage);
310
+ if (content !== "")
311
+ return content.slice(0, PREVIEW_MAX_CHARS);
312
+ }
313
+ return "";
314
+ }
315
+ }
316
+ // ----------------------------------------------------------------------
317
+ // Module-level helpers — kept stateless and pure so they're easy to read
318
+ // and easy to test in isolation.
319
+ // ----------------------------------------------------------------------
320
+ /**
321
+ * Reject with `message` if `work` has not settled within `timeoutMs`.
322
+ *
323
+ * The abandoned work keeps running until its own I/O settles — there is no
324
+ * cancellation token to hand the saver's async generator — but the caller is
325
+ * released on time instead of waiting on a cursor that may never yield.
326
+ */
327
+ async function withDeadline(work, timeoutMs, message) {
328
+ let timer;
329
+ const deadline = new Promise((_resolve, reject) => {
330
+ timer = setTimeout(() => reject(new Error(message)), timeoutMs);
331
+ });
332
+ try {
333
+ return await Promise.race([work, deadline]);
334
+ }
335
+ finally {
336
+ if (timer !== undefined)
337
+ clearTimeout(timer);
338
+ }
339
+ }
340
+ function mergeSessionSummaryAggregate(existing, newDoc) {
341
+ if (existing === undefined)
342
+ return { ...newDoc };
343
+ const latestTs = maxTimestamp(existing["latest_ts"], newDoc["latest_ts"]);
344
+ const firstTs = minTimestamp(existing["first_ts"], newDoc["first_ts"]);
345
+ return {
346
+ _id: existing["_id"] ?? newDoc["_id"],
347
+ latest_ts: latestTs,
348
+ first_ts: firstTs,
349
+ };
350
+ }
351
+ function maxTimestamp(left, right) {
352
+ if (left instanceof Date && right instanceof Date) {
353
+ return left > right ? left : right;
354
+ }
355
+ return left ?? right;
356
+ }
357
+ function minTimestamp(left, right) {
358
+ if (left instanceof Date && right instanceof Date) {
359
+ return left < right ? left : right;
360
+ }
361
+ return left ?? right;
362
+ }
363
+ /**
364
+ * Aggregation pipeline that reduces per-session checkpoint rows to one
365
+ * summary row per `thread_id` (first/last activity). The message count is
366
+ * derived separately from the authoritative message list (see
367
+ * `collectMessageCounts`) so it matches the messages endpoint.
368
+ */
369
+ function sessionSummariesPipeline(threadIds) {
370
+ return [
371
+ { $match: { thread_id: { $in: threadIds } } },
372
+ { $addFields: { _ts: { $toDate: "$_id" } } },
373
+ {
374
+ $group: {
375
+ _id: "$thread_id",
376
+ latest_ts: { $max: "$_ts" },
377
+ first_ts: { $min: "$_ts" },
378
+ },
379
+ },
380
+ { $sort: { latest_ts: -1 } },
381
+ ];
382
+ }
383
+ /**
384
+ * Aggregation pipeline that pulls the oldest few `messages`-channel writes
385
+ * per session so we can extract a human-message preview.
386
+ *
387
+ * `$firstN` caps the per-session write count at the accumulator — the full
388
+ * sorted stream is never materialized in memory. The preceding
389
+ * `$sort: {_id: 1}` makes "first N" mean "oldest N".
390
+ */
391
+ function messagePreviewsPipeline(threadIds) {
392
+ return [
393
+ {
394
+ $match: {
395
+ thread_id: { $in: threadIds },
396
+ channel: "messages",
397
+ },
398
+ },
399
+ { $sort: { _id: 1 } },
400
+ {
401
+ $group: {
402
+ _id: "$thread_id",
403
+ writes: {
404
+ $firstN: {
405
+ input: { type: "$type", value: "$value" },
406
+ n: PREVIEW_WRITES_PER_SESSION,
407
+ },
408
+ },
409
+ },
410
+ },
411
+ ];
412
+ }
413
+ /**
414
+ * Normalize a `checkpoint_writes.value` field to what `serde.loadsTyped`
415
+ * accepts. The driver surfaces it as a BSON `Binary`; mirror the saver's own
416
+ * read path (`doc.value.value("utf8")`). Returns null for unusable values.
417
+ */
418
+ function toSerdeData(value) {
419
+ if (typeof value === "string" || value instanceof Uint8Array)
420
+ return value;
421
+ if (value !== null &&
422
+ typeof value === "object" &&
423
+ typeof value.value === "function") {
424
+ return value.value("utf8");
425
+ }
426
+ return null;
427
+ }
428
+ /**
429
+ * Return the `messages` channel from a CheckpointTuple if it's a list,
430
+ * otherwise null.
431
+ *
432
+ * A null return signals "skip this checkpoint" — the channel is either
433
+ * absent, malformed, or the checkpoint itself isn't an object.
434
+ */
435
+ function extractMessages(checkpointTuple) {
436
+ const checkpoint = checkpointTuple.checkpoint;
437
+ if (checkpoint === null || typeof checkpoint !== "object")
438
+ return null;
439
+ const channelValues = checkpoint["channel_values"];
440
+ if (channelValues === null || typeof channelValues !== "object")
441
+ return null;
442
+ const messages = channelValues["messages"];
443
+ return Array.isArray(messages) ? messages : null;
444
+ }
445
+ /**
446
+ * Read `checkpoint.ts` — LangGraph's own ISO-8601 timestamp field —
447
+ * falling back to the empty string if it's missing.
448
+ */
449
+ function checkpointTimestamp(checkpointTuple) {
450
+ const checkpoint = checkpointTuple.checkpoint;
451
+ if (checkpoint === null || typeof checkpoint !== "object")
452
+ return "";
453
+ const ts = checkpoint["ts"];
454
+ return ts === null || ts === undefined || ts === "" ? "" : String(ts);
455
+ }
456
+ /**
457
+ * For each message index in the conversation history, return the timestamp
458
+ * of the *earliest* checkpoint where that index existed.
459
+ *
460
+ * The caller passes pairs in newest-first order (the natural `list()`
461
+ * direction); this function walks them oldest-first so each index records
462
+ * its first appearance.
463
+ */
464
+ function attributeFirstAppearanceTimestamps(checkpointsWithMessagesNewestFirst) {
465
+ const firstAppearanceByIndex = new Map();
466
+ for (const [checkpointTuple, messagesAtThisStep] of [
467
+ ...checkpointsWithMessagesNewestFirst,
468
+ ].reverse()) {
469
+ const timestamp = checkpointTimestamp(checkpointTuple);
470
+ for (let messageIndex = 0; messageIndex < messagesAtThisStep.length; messageIndex++) {
471
+ if (!firstAppearanceByIndex.has(messageIndex)) {
472
+ firstAppearanceByIndex.set(messageIndex, timestamp);
473
+ }
474
+ }
475
+ }
476
+ return firstAppearanceByIndex;
477
+ }
478
+ /**
479
+ * Return a LangChain message's type tag ("human", "ai", "tool", ...).
480
+ * Prefers `getType()` (the modern accessor on revived BaseMessage
481
+ * instances); falls back to the `type` property for stand-ins that don't
482
+ * implement the message protocol.
483
+ */
484
+ function messageType(message) {
485
+ if (message === null || typeof message !== "object")
486
+ return "";
487
+ const candidate = message;
488
+ if (typeof candidate.getType === "function") {
489
+ try {
490
+ return String(candidate.getType() ?? "");
491
+ }
492
+ catch {
493
+ return "";
494
+ }
495
+ }
496
+ return candidate.type === null || candidate.type === undefined
497
+ ? ""
498
+ : String(candidate.type);
499
+ }
500
+ /**
501
+ * Return a flat-string view of a LangChain message's content.
502
+ *
503
+ * Uses `BaseMessage.text` when available — it collapses string/list content
504
+ * to a string and extracts only `type: "text"` blocks. Falls back to
505
+ * `String(content)` for stand-ins that don't implement the LangChain
506
+ * message protocol (e.g. test doubles).
507
+ */
508
+ function messageText(message) {
509
+ if (message === null || typeof message !== "object")
510
+ return "";
511
+ const candidate = message;
512
+ if (typeof candidate.text === "string")
513
+ return candidate.text;
514
+ const content = candidate.content;
515
+ if (content === null || content === undefined || content === "")
516
+ return "";
517
+ return typeof content === "string" ? content : String(content);
518
+ }
519
+ function humanContent(decodedMessage) {
520
+ if (messageType(decodedMessage) !== "human")
521
+ return "";
522
+ return messageText(decodedMessage);
523
+ }
524
+ function toSessionMessage(args) {
525
+ const candidate = args.message !== null && typeof args.message === "object"
526
+ ? args.message
527
+ : {};
528
+ const rawMessageType = messageType(args.message);
529
+ const role = ROLE_MAP[rawMessageType] ?? rawMessageType;
530
+ const name = typeof candidate.name === "string" ? candidate.name : "";
531
+ const messageId = typeof candidate.id === "string" && candidate.id !== ""
532
+ ? candidate.id
533
+ : `msg-${args.sessionId}-${args.messageIndex}`;
534
+ return {
535
+ id: messageId,
536
+ role,
537
+ content: messageText(args.message),
538
+ timestamp: args.timestamp,
539
+ session_id: args.sessionId,
540
+ name,
541
+ tool_calls: toolCalls(args.message),
542
+ tool_call_id: toolCallId(args.message),
543
+ additional_kwargs: jsonSafeMetadata(candidate.additional_kwargs),
544
+ };
545
+ }
546
+ function toolCalls(message) {
547
+ if (message === null || typeof message !== "object")
548
+ return null;
549
+ const rawToolCalls = message.tool_calls;
550
+ if (!Array.isArray(rawToolCalls))
551
+ return null;
552
+ const calls = rawToolCalls
553
+ .filter((toolCall) => {
554
+ return toolCall !== null && typeof toolCall === "object";
555
+ })
556
+ .map((toolCall) => {
557
+ const data = {};
558
+ if (typeof toolCall["id"] === "string")
559
+ data.id = toolCall["id"];
560
+ if (typeof toolCall["name"] === "string")
561
+ data.name = toolCall["name"];
562
+ const args = toolCall["args"] ?? toolCall["arguments"];
563
+ const safeArgs = jsonSafeValue(args);
564
+ if (safeArgs !== undefined)
565
+ data.args = safeArgs;
566
+ if (typeof toolCall["type"] === "string")
567
+ data.type = toolCall["type"];
568
+ if (typeof toolCall["index"] === "number")
569
+ data.index = toolCall["index"];
570
+ return new LLMToolCall(data);
571
+ });
572
+ return calls.length > 0 ? calls : null;
573
+ }
574
+ function toolCallId(message) {
575
+ if (message === null || typeof message !== "object")
576
+ return null;
577
+ const value = message.tool_call_id;
578
+ return typeof value === "string" && value !== "" ? value : null;
579
+ }
580
+ function jsonSafeValue(value) {
581
+ if (value === undefined)
582
+ return undefined;
583
+ try {
584
+ const encoded = JSON.stringify(value);
585
+ if (encoded === undefined)
586
+ return undefined;
587
+ return JSON.parse(encoded);
588
+ }
589
+ catch {
590
+ return undefined;
591
+ }
592
+ }
593
+ /**
594
+ * Keep only JSON-serializable metadata fields, mirroring Python's
595
+ * per-field JsonValue validation: a single non-JSON field is dropped (with
596
+ * a warning) without discarding the rest of the metadata.
597
+ */
598
+ function jsonSafeMetadata(value) {
599
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
600
+ return null;
601
+ }
602
+ const metadata = {};
603
+ for (const [key, rawField] of Object.entries(value)) {
604
+ try {
605
+ const encoded = JSON.stringify(rawField);
606
+ if (encoded === undefined) {
607
+ logger.warn(`Skipping non-JSON message metadata field: ${key}`);
608
+ continue;
609
+ }
610
+ metadata[key] = JSON.parse(encoded);
611
+ }
612
+ catch {
613
+ logger.warn(`Skipping non-JSON message metadata field: ${key}`);
614
+ }
615
+ }
616
+ return Object.keys(metadata).length > 0 ? metadata : null;
617
+ }
618
+ function isoOrEmpty(value) {
619
+ if (value instanceof Date)
620
+ return value.toISOString();
621
+ return "";
622
+ }
623
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}