nexus-ai-pro 2.0.0 → 2.2.0

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 (282) hide show
  1. package/API_STABILITY.md +65 -0
  2. package/CHANGELOG.md +267 -1
  3. package/MIGRATING.md +1 -1
  4. package/README.md +17 -8
  5. package/dist/agent/create-agent.d.ts +9 -1
  6. package/dist/agent/create-agent.js +40 -1
  7. package/dist/cache/memory-cache.d.ts +8 -0
  8. package/dist/cache/memory-cache.js +9 -0
  9. package/dist/cache/semantic-cache.d.ts +6 -3
  10. package/dist/cache/semantic-cache.js +5 -2
  11. package/dist/cli/args.js +3 -0
  12. package/dist/cli/db.d.ts +16 -4
  13. package/dist/cli/db.js +169 -22
  14. package/dist/cli/doctor.d.ts +17 -0
  15. package/dist/cli/doctor.js +53 -0
  16. package/dist/cli/graph.d.ts +9 -0
  17. package/dist/cli/graph.js +47 -0
  18. package/dist/cli.js +21 -2
  19. package/dist/core/lifecycle.js +11 -6
  20. package/dist/core/nexus.d.ts +12 -2
  21. package/dist/core/nexus.js +106 -23
  22. package/dist/doctor/index.d.ts +90 -0
  23. package/dist/doctor/index.js +237 -0
  24. package/dist/evals/judge.d.ts +11 -0
  25. package/dist/evals/judge.js +33 -0
  26. package/dist/evaluate/index.d.ts +1 -0
  27. package/dist/evaluate/index.js +1 -0
  28. package/dist/evaluate/provenance.d.ts +22 -0
  29. package/dist/evaluate/provenance.js +10 -0
  30. package/dist/evaluate/run.js +20 -4
  31. package/dist/graph/durability.d.ts +27 -0
  32. package/dist/graph/durability.js +66 -0
  33. package/dist/graph/errors.d.ts +30 -4
  34. package/dist/graph/errors.js +18 -2
  35. package/dist/graph/event-stream.d.ts +75 -0
  36. package/dist/graph/event-stream.js +289 -0
  37. package/dist/graph/functional.d.ts +80 -7
  38. package/dist/graph/functional.js +138 -35
  39. package/dist/graph/graph.d.ts +56 -8
  40. package/dist/graph/graph.js +331 -49
  41. package/dist/graph/index.d.ts +4 -2
  42. package/dist/graph/index.js +3 -1
  43. package/dist/graph/lint.d.ts +57 -0
  44. package/dist/graph/lint.js +141 -0
  45. package/dist/graph/run-control.d.ts +28 -0
  46. package/dist/graph/run-control.js +26 -0
  47. package/dist/images/evals.js +4 -2
  48. package/dist/operations/adapters.d.ts +52 -4
  49. package/dist/operations/adapters.js +194 -7
  50. package/dist/operations/runner.js +14 -15
  51. package/dist/operations/stats.js +8 -1
  52. package/dist/operations/store.d.ts +5 -1
  53. package/dist/operations/store.js +7 -0
  54. package/dist/ops/circuit-breaker.d.ts +52 -0
  55. package/dist/ops/circuit-breaker.js +4 -0
  56. package/dist/ops/circuit-store.d.ts +13 -2
  57. package/dist/ops/circuit-store.js +68 -0
  58. package/dist/ops/circuit-sync.d.ts +17 -0
  59. package/dist/ops/circuit-sync.js +86 -0
  60. package/dist/ops/health.d.ts +24 -0
  61. package/dist/ops/health.js +38 -10
  62. package/dist/ops/index.d.ts +1 -1
  63. package/dist/ops/index.js +1 -1
  64. package/dist/ops/rate-limit-adapters.d.ts +23 -0
  65. package/dist/ops/rate-limit-adapters.js +34 -0
  66. package/dist/ops/rate-limiter.d.ts +14 -2
  67. package/dist/ops/rate-limiter.js +31 -0
  68. package/dist/postgres/circuits.d.ts +21 -4
  69. package/dist/postgres/circuits.js +65 -4
  70. package/dist/postgres/client.d.ts +0 -2
  71. package/dist/postgres/client.js +0 -4
  72. package/dist/postgres/evaluate.d.ts +16 -4
  73. package/dist/postgres/evaluate.js +17 -5
  74. package/dist/postgres/index.d.ts +32 -11
  75. package/dist/postgres/index.js +65 -31
  76. package/dist/postgres/migrations.d.ts +60 -0
  77. package/dist/postgres/migrations.js +121 -0
  78. package/dist/postgres/operations.d.ts +14 -3
  79. package/dist/postgres/operations.js +45 -15
  80. package/dist/postgres/prompts.d.ts +11 -2
  81. package/dist/postgres/prompts.js +14 -3
  82. package/dist/postgres/rollups.d.ts +35 -0
  83. package/dist/postgres/rollups.js +129 -0
  84. package/dist/postgres/store.d.ts +11 -2
  85. package/dist/postgres/store.js +14 -3
  86. package/dist/postgres/traces.d.ts +13 -3
  87. package/dist/postgres/traces.js +25 -3
  88. package/dist/postgres/vectors.d.ts +11 -2
  89. package/dist/postgres/vectors.js +14 -3
  90. package/dist/router/auto-router.d.ts +34 -7
  91. package/dist/router/auto-router.js +201 -68
  92. package/dist/server/assistant.d.ts +44 -0
  93. package/dist/server/assistant.js +39 -0
  94. package/dist/server/errors.d.ts +12 -0
  95. package/dist/server/errors.js +7 -0
  96. package/dist/server/index.d.ts +1 -1
  97. package/dist/server/index.js +1 -1
  98. package/dist/server/runs.d.ts +28 -1
  99. package/dist/server/runs.js +110 -14
  100. package/dist/sqlite/index.d.ts +16 -3
  101. package/dist/sqlite/index.js +16 -3
  102. package/dist/sqlite/migrations.d.ts +26 -0
  103. package/dist/sqlite/migrations.js +63 -0
  104. package/dist/sqlite/operations.d.ts +14 -3
  105. package/dist/sqlite/operations.js +42 -15
  106. package/dist/sqlite/store.d.ts +9 -2
  107. package/dist/sqlite/store.js +13 -3
  108. package/dist/sqlite/vectors.d.ts +11 -2
  109. package/dist/sqlite/vectors.js +13 -2
  110. package/dist/store/tenant.d.ts +12 -0
  111. package/dist/store/tenant.js +29 -0
  112. package/dist/tenancy/index.d.ts +113 -0
  113. package/dist/tenancy/index.js +233 -0
  114. package/dist/testing/record.d.ts +42 -0
  115. package/dist/testing/record.js +57 -5
  116. package/dist/tracing/index.d.ts +3 -3
  117. package/dist/tracing/index.js +2 -2
  118. package/dist/tracing/instrument.js +30 -0
  119. package/dist/tracing/otlp.d.ts +91 -0
  120. package/dist/tracing/otlp.js +124 -0
  121. package/dist/tracing/rollups.d.ts +100 -0
  122. package/dist/tracing/rollups.js +139 -0
  123. package/dist/tracing/stores.d.ts +17 -0
  124. package/dist/tracing/stores.js +23 -0
  125. package/dist/tracing/tracer.d.ts +50 -4
  126. package/dist/tracing/tracer.js +85 -6
  127. package/dist/types/config.d.ts +33 -2
  128. package/dist/types/evaluate.d.ts +37 -0
  129. package/dist/types/graph.d.ts +354 -9
  130. package/dist/types/graph.js +3 -1
  131. package/dist/types/messages.d.ts +5 -0
  132. package/dist/types/operations.d.ts +22 -2
  133. package/dist/types/response.d.ts +20 -0
  134. package/dist/types/server.d.ts +18 -0
  135. package/dist/types/tracing.d.ts +11 -0
  136. package/dist/utils/schema-migrations.d.ts +97 -0
  137. package/dist/utils/schema-migrations.js +91 -0
  138. package/dist/utils/signals.d.ts +17 -0
  139. package/dist/utils/signals.js +26 -0
  140. package/dist/utils/tenant.d.ts +14 -0
  141. package/dist/utils/tenant.js +16 -0
  142. package/dist/version.d.ts +5 -0
  143. package/dist/version.js +1 -0
  144. package/dist-cjs/agent/create-agent.d.ts +9 -1
  145. package/dist-cjs/agent/create-agent.js +40 -1
  146. package/dist-cjs/cache/memory-cache.d.ts +8 -0
  147. package/dist-cjs/cache/memory-cache.js +9 -0
  148. package/dist-cjs/cache/semantic-cache.d.ts +6 -3
  149. package/dist-cjs/cache/semantic-cache.js +5 -2
  150. package/dist-cjs/cli/args.js +3 -0
  151. package/dist-cjs/cli/db.d.ts +16 -4
  152. package/dist-cjs/cli/db.js +200 -20
  153. package/dist-cjs/cli/doctor.d.ts +17 -0
  154. package/dist-cjs/cli/doctor.js +56 -0
  155. package/dist-cjs/cli/graph.d.ts +9 -0
  156. package/dist-cjs/cli/graph.js +50 -0
  157. package/dist-cjs/core/lifecycle.js +11 -6
  158. package/dist-cjs/core/nexus.d.ts +12 -2
  159. package/dist-cjs/core/nexus.js +106 -23
  160. package/dist-cjs/doctor/index.d.ts +90 -0
  161. package/dist-cjs/doctor/index.js +276 -0
  162. package/dist-cjs/evals/judge.d.ts +11 -0
  163. package/dist-cjs/evals/judge.js +33 -0
  164. package/dist-cjs/evaluate/index.d.ts +1 -0
  165. package/dist-cjs/evaluate/index.js +3 -1
  166. package/dist-cjs/evaluate/provenance.d.ts +22 -0
  167. package/dist-cjs/evaluate/provenance.js +14 -0
  168. package/dist-cjs/evaluate/run.js +20 -4
  169. package/dist-cjs/graph/durability.d.ts +27 -0
  170. package/dist-cjs/graph/durability.js +70 -0
  171. package/dist-cjs/graph/errors.d.ts +30 -4
  172. package/dist-cjs/graph/errors.js +20 -3
  173. package/dist-cjs/graph/event-stream.d.ts +75 -0
  174. package/dist-cjs/graph/event-stream.js +295 -0
  175. package/dist-cjs/graph/functional.d.ts +80 -7
  176. package/dist-cjs/graph/functional.js +137 -34
  177. package/dist-cjs/graph/graph.d.ts +56 -8
  178. package/dist-cjs/graph/graph.js +330 -48
  179. package/dist-cjs/graph/index.d.ts +4 -2
  180. package/dist-cjs/graph/index.js +7 -1
  181. package/dist-cjs/graph/lint.d.ts +57 -0
  182. package/dist-cjs/graph/lint.js +144 -0
  183. package/dist-cjs/graph/run-control.d.ts +28 -0
  184. package/dist-cjs/graph/run-control.js +30 -0
  185. package/dist-cjs/images/evals.js +4 -2
  186. package/dist-cjs/operations/adapters.d.ts +52 -4
  187. package/dist-cjs/operations/adapters.js +193 -6
  188. package/dist-cjs/operations/runner.js +14 -15
  189. package/dist-cjs/operations/stats.js +8 -1
  190. package/dist-cjs/operations/store.d.ts +5 -1
  191. package/dist-cjs/operations/store.js +7 -0
  192. package/dist-cjs/ops/circuit-breaker.d.ts +52 -0
  193. package/dist-cjs/ops/circuit-breaker.js +4 -0
  194. package/dist-cjs/ops/circuit-store.d.ts +13 -2
  195. package/dist-cjs/ops/circuit-store.js +68 -0
  196. package/dist-cjs/ops/circuit-sync.d.ts +17 -0
  197. package/dist-cjs/ops/circuit-sync.js +87 -0
  198. package/dist-cjs/ops/health.d.ts +24 -0
  199. package/dist-cjs/ops/health.js +38 -10
  200. package/dist-cjs/ops/index.d.ts +1 -1
  201. package/dist-cjs/ops/rate-limit-adapters.d.ts +23 -0
  202. package/dist-cjs/ops/rate-limit-adapters.js +35 -1
  203. package/dist-cjs/ops/rate-limiter.d.ts +14 -2
  204. package/dist-cjs/ops/rate-limiter.js +32 -0
  205. package/dist-cjs/postgres/circuits.d.ts +21 -4
  206. package/dist-cjs/postgres/circuits.js +98 -3
  207. package/dist-cjs/postgres/client.d.ts +0 -2
  208. package/dist-cjs/postgres/client.js +0 -5
  209. package/dist-cjs/postgres/evaluate.d.ts +16 -4
  210. package/dist-cjs/postgres/evaluate.js +50 -4
  211. package/dist-cjs/postgres/index.d.ts +32 -11
  212. package/dist-cjs/postgres/index.js +69 -20
  213. package/dist-cjs/postgres/migrations.d.ts +60 -0
  214. package/dist-cjs/postgres/migrations.js +129 -0
  215. package/dist-cjs/postgres/operations.d.ts +14 -3
  216. package/dist-cjs/postgres/operations.js +78 -14
  217. package/dist-cjs/postgres/prompts.d.ts +11 -2
  218. package/dist-cjs/postgres/prompts.js +47 -2
  219. package/dist-cjs/postgres/rollups.d.ts +35 -0
  220. package/dist-cjs/postgres/rollups.js +168 -0
  221. package/dist-cjs/postgres/store.d.ts +11 -2
  222. package/dist-cjs/postgres/store.js +47 -2
  223. package/dist-cjs/postgres/traces.d.ts +13 -3
  224. package/dist-cjs/postgres/traces.js +58 -2
  225. package/dist-cjs/postgres/vectors.d.ts +11 -2
  226. package/dist-cjs/postgres/vectors.js +47 -2
  227. package/dist-cjs/router/auto-router.d.ts +34 -7
  228. package/dist-cjs/router/auto-router.js +201 -68
  229. package/dist-cjs/server/assistant.d.ts +44 -0
  230. package/dist-cjs/server/assistant.js +39 -0
  231. package/dist-cjs/server/errors.d.ts +12 -0
  232. package/dist-cjs/server/errors.js +9 -1
  233. package/dist-cjs/server/index.d.ts +1 -1
  234. package/dist-cjs/server/index.js +2 -1
  235. package/dist-cjs/server/runs.d.ts +28 -1
  236. package/dist-cjs/server/runs.js +109 -13
  237. package/dist-cjs/sqlite/index.d.ts +16 -3
  238. package/dist-cjs/sqlite/index.js +31 -10
  239. package/dist-cjs/sqlite/migrations.d.ts +26 -0
  240. package/dist-cjs/sqlite/migrations.js +71 -0
  241. package/dist-cjs/sqlite/operations.d.ts +14 -3
  242. package/dist-cjs/sqlite/operations.js +76 -15
  243. package/dist-cjs/sqlite/store.d.ts +9 -2
  244. package/dist-cjs/sqlite/store.js +47 -3
  245. package/dist-cjs/sqlite/vectors.d.ts +11 -2
  246. package/dist-cjs/sqlite/vectors.js +47 -2
  247. package/dist-cjs/store/tenant.d.ts +12 -0
  248. package/dist-cjs/store/tenant.js +33 -0
  249. package/dist-cjs/tenancy/index.d.ts +113 -0
  250. package/dist-cjs/tenancy/index.js +250 -0
  251. package/dist-cjs/testing/record.d.ts +42 -0
  252. package/dist-cjs/testing/record.js +57 -5
  253. package/dist-cjs/tracing/index.d.ts +3 -3
  254. package/dist-cjs/tracing/index.js +4 -1
  255. package/dist-cjs/tracing/instrument.js +30 -0
  256. package/dist-cjs/tracing/otlp.d.ts +91 -0
  257. package/dist-cjs/tracing/otlp.js +129 -0
  258. package/dist-cjs/tracing/rollups.d.ts +100 -0
  259. package/dist-cjs/tracing/rollups.js +147 -0
  260. package/dist-cjs/tracing/stores.d.ts +17 -0
  261. package/dist-cjs/tracing/stores.js +24 -0
  262. package/dist-cjs/tracing/tracer.d.ts +50 -4
  263. package/dist-cjs/tracing/tracer.js +87 -6
  264. package/dist-cjs/types/config.d.ts +33 -2
  265. package/dist-cjs/types/evaluate.d.ts +37 -0
  266. package/dist-cjs/types/graph.d.ts +354 -9
  267. package/dist-cjs/types/graph.js +3 -1
  268. package/dist-cjs/types/messages.d.ts +5 -0
  269. package/dist-cjs/types/operations.d.ts +22 -2
  270. package/dist-cjs/types/response.d.ts +20 -0
  271. package/dist-cjs/types/server.d.ts +18 -0
  272. package/dist-cjs/types/tracing.d.ts +11 -0
  273. package/dist-cjs/utils/schema-migrations.d.ts +97 -0
  274. package/dist-cjs/utils/schema-migrations.js +102 -0
  275. package/dist-cjs/utils/signals.d.ts +17 -0
  276. package/dist-cjs/utils/signals.js +29 -0
  277. package/dist-cjs/utils/tenant.d.ts +14 -0
  278. package/dist-cjs/utils/tenant.js +22 -0
  279. package/dist-cjs/version.d.ts +5 -0
  280. package/dist-cjs/version.js +4 -0
  281. package/llms.txt +4 -3
  282. package/package.json +110 -2
@@ -37,8 +37,12 @@ exports.CompiledGraph = exports.StateGraph = void 0;
37
37
  exports.createGraph = createGraph;
38
38
  const node_crypto_1 = require("node:crypto");
39
39
  const graph_js_1 = require("../types/graph.js");
40
+ const tenant_js_1 = require("../store/tenant.js");
41
+ const signals_js_1 = require("../utils/signals.js");
40
42
  const checkpointer_js_1 = require("./checkpointer.js");
41
43
  const checkpoint_migration_js_1 = require("./checkpoint-migration.js");
44
+ const durability_js_1 = require("./durability.js");
45
+ const event_stream_js_1 = require("./event-stream.js");
42
46
  const errors_js_1 = require("./errors.js");
43
47
  const DEFAULT_MAX_STEPS = 25;
44
48
  const DEFAULT_MAX_CONCURRENCY = 16;
@@ -50,6 +54,7 @@ const DEFAULT_RETRY = {
50
54
  jitter: true,
51
55
  };
52
56
  const SUBGRAPH = Symbol('nexus.graph.subgraph');
57
+ const FORWARD_EVENT = Symbol('nexus.graph.forwardEvent');
53
58
  const FOLLOWING_UPDATES = Symbol('nexus.graph.followingUpdates');
54
59
  class StateGraph {
55
60
  channels;
@@ -161,6 +166,7 @@ class CompiledGraph {
161
166
  now;
162
167
  store;
163
168
  nodeCache;
169
+ writers = new Set();
164
170
  constructor(channels, nodes, edges, options, scope = {}) {
165
171
  this.channels = channels;
166
172
  this.nodes = nodes;
@@ -170,6 +176,9 @@ class CompiledGraph {
170
176
  this.now = options.now ?? (() => new Date());
171
177
  this.store = options.checkpointer === false ? undefined : (options.checkpointer ?? new checkpointer_js_1.MemoryGraphCheckpointer());
172
178
  }
179
+ async flush() {
180
+ await Promise.all([...this.writers].map((writer) => writer.flush()));
181
+ }
173
182
  async invoke(input = {}, runOptions = {}) {
174
183
  const threadId = resolveThreadId(runOptions.threadId);
175
184
  let last;
@@ -181,11 +190,42 @@ class CompiledGraph {
181
190
  const threadId = resolveThreadId(runOptions.threadId);
182
191
  return this.run(threadId, runOptions, async () => {
183
192
  this.assertInput(input);
193
+ if (runOptions.tenantId !== undefined) {
194
+ const existing = await this.checkpointer()?.get(threadId);
195
+ if (existing && !ownedBy(existing, runOptions.tenantId)) {
196
+ throw new errors_js_1.GraphValidationError(`Thread "${threadId}" cannot be used by this tenant; choose another id`);
197
+ }
198
+ }
184
199
  const state = this.seedState(input);
185
200
  const next = this.entryNodes();
186
201
  return { threadId, step: 0, state, next, status: 'running', createdAt: this.now().toISOString() };
187
202
  });
188
203
  }
204
+ events(input = {}, options = {}) {
205
+ const threadId = resolveThreadId(options.threadId);
206
+ return this.eventStream(threadId, options, (runOptions) => this.stream(input, runOptions));
207
+ }
208
+ resumeEvents(threadId, value, options = {}) {
209
+ return this.eventStream(threadId, options, (runOptions) => this.resume(threadId, value, runOptions));
210
+ }
211
+ continueEvents(threadId, options = {}) {
212
+ return this.eventStream(threadId, options, (runOptions) => this.continue(threadId, runOptions));
213
+ }
214
+ eventStream(threadId, options, run) {
215
+ return new event_stream_js_1.GraphEventStream((onEvent, signal) => {
216
+ const linked = (0, signals_js_1.linkSignals)([options.signal, signal]);
217
+ return releasing(run({
218
+ ...options,
219
+ threadId,
220
+ signal: linked.signal,
221
+ ...(options.subgraphs ? { subgraphEvents: true } : {}),
222
+ onEvent: (event) => {
223
+ options.onEvent?.(event);
224
+ onEvent(event);
225
+ },
226
+ }), linked.dispose);
227
+ }, (last) => this.toResult(threadId, last), (0, event_stream_js_1.streamSettings)(options));
228
+ }
189
229
  resume(threadId, value, runOptions = {}) {
190
230
  return this.run(threadId, runOptions, async () => {
191
231
  const checkpoint = await this.requireCheckpoint(threadId);
@@ -235,7 +275,7 @@ class CompiledGraph {
235
275
  continue(threadId, runOptions = {}) {
236
276
  return this.run(threadId, runOptions, async () => {
237
277
  const checkpoint = await this.requireCheckpoint(threadId);
238
- return { ...checkpoint, status: 'running', error: undefined };
278
+ return { ...checkpoint, status: 'running', error: undefined, drained: undefined };
239
279
  });
240
280
  }
241
281
  resumeFrom(threadId, step, runOptions = {}) {
@@ -246,19 +286,25 @@ class CompiledGraph {
246
286
  return { ...(0, checkpoint_migration_js_1.migrateCheckpoint)(stored), status: 'running' };
247
287
  });
248
288
  }
249
- async state(threadId, step) {
289
+ async state(threadId, step, options = {}) {
250
290
  const stored = await this.checkpointer()?.get(threadId, step);
251
- return stored ? (0, checkpoint_migration_js_1.migrateCheckpoint)(stored) : undefined;
291
+ if (!stored || !ownedBy(stored, options.tenantId))
292
+ return undefined;
293
+ return (0, checkpoint_migration_js_1.migrateCheckpoint)(stored);
252
294
  }
253
- async history(threadId, limit) {
295
+ async history(threadId, limit, options = {}) {
254
296
  const stored = (await this.checkpointer()?.history(threadId, limit)) ?? [];
297
+ if (stored[0] && !ownedBy(stored[0], options.tenantId))
298
+ return [];
255
299
  return stored.map((item) => (0, checkpoint_migration_js_1.migrateCheckpoint)(item));
256
300
  }
257
301
  asNode() {
258
302
  const node = async (context) => {
303
+ const forward = context[FORWARD_EVENT];
259
304
  const runOptions = {
260
305
  threadId: `${context.threadId}:${context.taskId}`,
261
306
  signal: context.signal,
307
+ ...(forward ? { onEvent: forward, subgraphEvents: true } : {}),
262
308
  };
263
309
  const paused = await this.state(runOptions.threadId);
264
310
  let result;
@@ -301,13 +347,18 @@ class CompiledGraph {
301
347
  describe() {
302
348
  const nodes = [...this.nodes.entries()].map(([id, definition]) => {
303
349
  const subgraph = definition.fn[SUBGRAPH];
304
- const { ends, defer, retry, timeoutMs, cache } = definition.options;
350
+ const { ends, defer, timeoutMs, cache, idempotent } = definition.options;
351
+ const maxAttempts = this.retryPolicy(definition).maxAttempts;
352
+ const timeout = this.timeoutOf(definition);
305
353
  return {
306
354
  id,
307
355
  ...(ends?.length ? { ends: [...ends] } : {}),
308
356
  ...(defer ? { defer } : {}),
309
- ...((retry?.maxAttempts ?? this.options.retry?.maxAttempts ?? 1) > 1 ? { retry: true } : {}),
357
+ ...(maxAttempts > 1 ? { retry: true, maxAttempts } : {}),
310
358
  ...(timeoutMs !== undefined ? { timeoutMs } : {}),
359
+ ...(timeout.runMs !== undefined || timeout.idleMs !== undefined ? { timeout } : {}),
360
+ ...(this.errorHandler(definition) ? { onError: true } : {}),
361
+ ...(idempotent ? { idempotent: true } : {}),
311
362
  ...(cache ? { cache: true } : {}),
312
363
  ...(subgraph ? { subgraph: subgraph.describe() } : {}),
313
364
  };
@@ -342,10 +393,13 @@ class CompiledGraph {
342
393
  dynamic: [...dynamic],
343
394
  ...(this.scope.input ? { input: [...this.scope.input] } : {}),
344
395
  ...(this.scope.output ? { output: [...this.scope.output] } : {}),
396
+ durability: this.options.durability ?? 'sync',
397
+ checkpointer: this.options.checkpointer === false ? 'none' : this.options.checkpointer === undefined ? 'memory' : 'custom',
398
+ maxConcurrency: this.options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY,
345
399
  };
346
400
  }
347
401
  async updateState(threadId, update, options = {}) {
348
- const checkpoint = await this.requireCheckpoint(threadId);
402
+ const checkpoint = await this.requireCheckpoint(threadId, options.tenantId);
349
403
  const state = this.reduce(checkpoint.state, [update]);
350
404
  const createdAt = this.now().toISOString();
351
405
  if (!options.asNode) {
@@ -380,8 +434,9 @@ class CompiledGraph {
380
434
  if (!store)
381
435
  throw new errors_js_1.GraphValidationError('fork() needs a checkpointer to copy history from');
382
436
  const history = (await store.history(threadId, Number.MAX_SAFE_INTEGER)).map((item) => (0, checkpoint_migration_js_1.migrateCheckpoint)(item));
383
- if (history.length === 0)
437
+ if (history.length === 0 || !ownedBy(history[0], options.tenantId)) {
384
438
  throw new errors_js_1.GraphThreadNotFoundError(threadId);
439
+ }
385
440
  const cutoff = options.step ?? history[0].step;
386
441
  const lineage = history.filter((item) => item.step <= cutoff).reverse();
387
442
  if (lineage.at(-1)?.step !== cutoff) {
@@ -432,22 +487,69 @@ class CompiledGraph {
432
487
  }
433
488
  }
434
489
  async *runSteps(threadId, runOptions, seed) {
490
+ const mode = runOptions.durability ?? this.options.durability ?? 'sync';
491
+ const writer = new durability_js_1.CheckpointWriter(async (written) => {
492
+ await this.save(written);
493
+ notify(runOptions, { type: 'checkpoint', step: written.step, status: written.status, next: written.next });
494
+ }, mode, this.options.maxPendingWrites);
495
+ this.writers.add(writer);
496
+ let failed = false;
497
+ try {
498
+ yield* this.steps(threadId, runOptions, seed, (written, durable) => writer.persist(written, durable));
499
+ }
500
+ catch (error) {
501
+ failed = true;
502
+ throw error;
503
+ }
504
+ finally {
505
+ this.writers.delete(writer);
506
+ if (failed)
507
+ await writer.flush().catch(() => undefined);
508
+ else
509
+ await writer.flush();
510
+ }
511
+ }
512
+ async *steps(threadId, runOptions, seed, persist) {
435
513
  const maxSteps = runOptions.maxSteps ?? this.options.maxSteps ?? DEFAULT_MAX_STEPS;
436
514
  const stopBefore = runOptions.interruptBefore ?? this.options.interruptBefore ?? [];
437
515
  const stopAfter = runOptions.interruptAfter ?? this.options.interruptAfter ?? [];
438
- const persist = async (written) => {
439
- await this.save(written);
440
- notify(runOptions, { type: 'checkpoint', step: written.step, status: written.status, next: written.next });
441
- };
442
516
  let checkpoint = await seed();
517
+ const owner = tenantOf(checkpoint);
518
+ if (runOptions.tenantId !== undefined && owner !== undefined && owner !== runOptions.tenantId) {
519
+ throw new errors_js_1.GraphThreadNotFoundError(threadId);
520
+ }
521
+ const tenantId = runOptions.tenantId ?? owner;
522
+ if (tenantId !== undefined) {
523
+ runOptions = { ...runOptions, tenantId, metadata: { ...runOptions.metadata, tenantId } };
524
+ if (owner === undefined)
525
+ checkpoint = { ...checkpoint, metadata: { ...checkpoint.metadata, tenantId } };
526
+ }
443
527
  let passBreakpoint = checkpoint.breakpoint?.when === 'before';
444
528
  if (checkpoint.breakpoint)
445
529
  checkpoint = { ...checkpoint, breakpoint: undefined };
530
+ if (checkpoint.next.length === 0) {
531
+ if (checkpoint.status === 'running')
532
+ checkpoint = { ...checkpoint, status: 'completed' };
533
+ await persist(checkpoint, true);
534
+ yield this.toEvent(checkpoint, []);
535
+ return;
536
+ }
446
537
  await persist(checkpoint);
447
538
  while (checkpoint.next.length > 0) {
539
+ if (runOptions.control?.draining) {
540
+ const at = this.now().toISOString();
541
+ checkpoint = {
542
+ ...checkpoint,
543
+ status: 'interrupted',
544
+ drained: { ...(runOptions.control.reason ? { reason: runOptions.control.reason } : {}), at },
545
+ createdAt: at,
546
+ };
547
+ await persist(checkpoint, true);
548
+ throw new errors_js_1.GraphDrainedError(threadId, checkpoint.step, runOptions.control.reason);
549
+ }
448
550
  if (runOptions.signal?.aborted) {
449
551
  checkpoint = { ...checkpoint, status: 'interrupted', createdAt: this.now().toISOString() };
450
- await persist(checkpoint);
552
+ await persist(checkpoint, true);
451
553
  yield this.toEvent(checkpoint, []);
452
554
  return;
453
555
  }
@@ -472,7 +574,7 @@ class CompiledGraph {
472
574
  breakpoint: { when: 'before', nodes: breakBefore },
473
575
  createdAt: this.now().toISOString(),
474
576
  };
475
- await persist(checkpoint);
577
+ await persist(checkpoint, true);
476
578
  yield this.toEvent(checkpoint, []);
477
579
  return;
478
580
  }
@@ -492,6 +594,7 @@ class CompiledGraph {
492
594
  const gotos = { ...(checkpoint.gotos ?? {}) };
493
595
  let parentCommand;
494
596
  let failure;
597
+ const recovered = [];
495
598
  for (const [index, task] of pendingTasks.entries()) {
496
599
  const outcome = outcomes[index];
497
600
  if (!outcome)
@@ -503,6 +606,8 @@ class CompiledGraph {
503
606
  if (outcome.goto?.length)
504
607
  gotos[task.id] = outcome.goto;
505
608
  parentCommand ??= outcome.parent;
609
+ if (outcome.recovered)
610
+ recovered.push(outcome.recovered);
506
611
  finished.push(task.id);
507
612
  }
508
613
  else if (outcome.kind === 'interrupt') {
@@ -518,6 +623,7 @@ class CompiledGraph {
518
623
  const ranNodes = distinctNodes(allTasks.filter((task) => completed.includes(task.id)));
519
624
  const ranTasks = pendingTasks;
520
625
  const routeFields = Object.keys(gotos).length > 0 ? { gotos } : {};
626
+ const recoveryFields = recovered.length > 0 ? { recovered } : {};
521
627
  if (failure) {
522
628
  const failed = {
523
629
  ...checkpoint,
@@ -525,6 +631,7 @@ class CompiledGraph {
525
631
  ...pausedFields(allTasks, unfinished),
526
632
  completed,
527
633
  ...routeFields,
634
+ ...recoveryFields,
528
635
  status: 'failed',
529
636
  error: {
530
637
  name: failure.error instanceof Error ? failure.error.name : 'Error',
@@ -532,7 +639,7 @@ class CompiledGraph {
532
639
  },
533
640
  createdAt: this.now().toISOString(),
534
641
  };
535
- await persist(failed);
642
+ await persist(failed, true);
536
643
  throw failure.error instanceof errors_js_1.GraphNodeError
537
644
  ? failure.error
538
645
  : new errors_js_1.GraphNodeError(failure.task.node, step, failure.error);
@@ -545,11 +652,12 @@ class CompiledGraph {
545
652
  ...pausedFields(allTasks, unfinished),
546
653
  completed,
547
654
  ...routeFields,
655
+ ...recoveryFields,
548
656
  status: asking ? 'awaiting_input' : 'interrupted',
549
657
  interrupts,
550
658
  createdAt: this.now().toISOString(),
551
659
  };
552
- await persist(checkpoint);
660
+ await persist(checkpoint, true);
553
661
  yield this.toEvent(checkpoint, ranNodes, ranTasks, attempts);
554
662
  return;
555
663
  }
@@ -561,10 +669,11 @@ class CompiledGraph {
561
669
  next: [],
562
670
  status: 'completed',
563
671
  resolved: checkpoint.resolved,
672
+ ...recoveryFields,
564
673
  createdAt: this.now().toISOString(),
565
674
  ...(runOptions.metadata ? { metadata: runOptions.metadata } : {}),
566
675
  };
567
- await persist(checkpoint);
676
+ await persist(checkpoint, true);
568
677
  yield { ...this.toEvent(checkpoint, ranNodes, ranTasks, attempts), parentCommand };
569
678
  return;
570
679
  }
@@ -583,10 +692,11 @@ class CompiledGraph {
583
692
  status: breakAfter.length > 0 ? 'interrupted' : next.length > 0 ? 'running' : 'completed',
584
693
  ...(breakAfter.length > 0 ? { breakpoint: { when: 'after', nodes: breakAfter } } : {}),
585
694
  resolved: checkpoint.resolved,
695
+ ...recoveryFields,
586
696
  createdAt: this.now().toISOString(),
587
697
  ...(runOptions.metadata ? { metadata: runOptions.metadata } : {}),
588
698
  };
589
- await persist(checkpoint);
699
+ await persist(checkpoint, recovered.length > 0 || next.length === 0 || breakAfter.length > 0);
590
700
  yield this.toEvent(checkpoint, ranNodes, ranTasks, attempts);
591
701
  if (breakAfter.length > 0)
592
702
  return;
@@ -596,8 +706,8 @@ class CompiledGraph {
596
706
  const definition = this.nodes.get(task.node);
597
707
  if (!definition)
598
708
  throw new errors_js_1.GraphValidationError(`Node "${task.node}" disappeared before it could run`);
599
- const policy = { ...DEFAULT_RETRY, ...this.options.retry, ...definition.options.retry };
600
- const timeoutMs = definition.options.timeoutMs;
709
+ const policy = this.retryPolicy(definition);
710
+ const limits = { ...this.timeoutOf(definition), ...task.timeout };
601
711
  const cachePolicy = definition.options.cache;
602
712
  const cache = cachePolicy ? await this.loadNodeCache() : undefined;
603
713
  const cacheKey = cachePolicy && cache ? cache.key(cachePolicy, task.node, checkpoint.state, task.input) : undefined;
@@ -619,22 +729,18 @@ class CompiledGraph {
619
729
  }
620
730
  }
621
731
  let attempts = 0;
732
+ const firstAttemptAt = this.now().toISOString();
622
733
  while (true) {
623
734
  attempts += 1;
624
735
  notify(runOptions, { type: 'task_start', step, taskId: task.id, node: task.node, attempt: attempts });
625
- const timeout = timeoutMs === undefined ? undefined : AbortSignal.timeout(timeoutMs);
626
- const sources = [stepSignal, ...(runOptions.signal ? [runOptions.signal] : []), ...(timeout ? [timeout] : [])];
627
- const signal = sources.length === 1 ? sources[0] : AbortSignal.any(sources);
736
+ const timer = attemptTimer(task.node, limits);
737
+ const linked = (0, signals_js_1.linkSignals)([stepSignal, runOptions.signal, timer?.signal]);
738
+ const signal = linked.signal;
628
739
  try {
629
- const running = this.runNode(definition.fn, task, step, threadId, checkpoint, runOptions, signal, attempts);
630
- if (timeout)
740
+ const running = this.runNode(definition.fn, task, step, threadId, checkpoint, runOptions, signal, attempts, timer?.touch);
741
+ if (timer)
631
742
  running.catch(() => undefined);
632
- const output = timeout
633
- ? await Promise.race([
634
- running,
635
- rejectWhenAborted(timeout, () => new errors_js_1.GraphNodeTimeoutError(task.node, timeoutMs)),
636
- ])
637
- : await running;
743
+ const output = timer ? await Promise.race([running, timer.expired]) : await running;
638
744
  const parent = output.command?.graph === graph_js_1.Command.PARENT ? output.command : undefined;
639
745
  const goto = parent ? undefined : toRouteRecords(output.command?.goto);
640
746
  const updates = parent ? [] : output.updates;
@@ -652,6 +758,7 @@ class CompiledGraph {
652
758
  return { kind: 'ok', updates, goto, parent, attempts };
653
759
  }
654
760
  catch (error) {
761
+ timer?.stop();
655
762
  if (error instanceof errors_js_1.GraphInterrupt) {
656
763
  return {
657
764
  kind: 'interrupt',
@@ -669,10 +776,24 @@ class CompiledGraph {
669
776
  }
670
777
  if (runOptions.signal?.aborted || stepSignal.aborted)
671
778
  return { kind: 'aborted', attempts };
672
- const failure = timeout?.aborted ? new errors_js_1.GraphNodeTimeoutError(task.node, timeoutMs) : error;
779
+ const failure = timer?.error() ?? error;
673
780
  const retryable = policy.retryOn ? policy.retryOn(failure, attempts) : isRetryable(failure);
674
781
  if (attempts >= Math.max(1, policy.maxAttempts) || !retryable) {
675
- return { kind: 'failed', error: failure, attempts };
782
+ return this.recover(definition, task, step, checkpoint, runOptions, {
783
+ node: task.node,
784
+ taskId: task.id,
785
+ step,
786
+ attempts,
787
+ firstAttemptAt,
788
+ failedAt: this.now().toISOString(),
789
+ error: failure,
790
+ retryExhausted: retryable,
791
+ ...(failure instanceof errors_js_1.GraphNodeTimeoutError
792
+ ? { timeout: { type: failure.kind, limitMs: failure.timeoutMs } }
793
+ : {}),
794
+ ...(task.input === undefined ? {} : { input: task.input }),
795
+ threadId,
796
+ });
676
797
  }
677
798
  notify(runOptions, {
678
799
  type: 'task_retry',
@@ -684,9 +805,81 @@ class CompiledGraph {
684
805
  });
685
806
  await delay(backoffDelay(policy, attempts), runOptions.signal);
686
807
  }
808
+ finally {
809
+ timer?.stop();
810
+ linked.dispose();
811
+ }
687
812
  }
688
813
  }
689
- async runNode(fn, task, step, threadId, checkpoint, runOptions, signal, attempt) {
814
+ async recover(definition, task, step, checkpoint, runOptions, failure) {
815
+ const handler = this.errorHandler(definition);
816
+ const event = {
817
+ type: 'task_failed',
818
+ step,
819
+ taskId: task.id,
820
+ node: task.node,
821
+ attempts: failure.attempts,
822
+ error: describe(failure.error),
823
+ };
824
+ if (!handler || failure.error instanceof errors_js_1.GraphValidationError) {
825
+ notify(runOptions, { ...event, recovered: false });
826
+ return { kind: 'failed', error: failure.error, attempts: failure.attempts };
827
+ }
828
+ let decided;
829
+ try {
830
+ decided = await handler(failure, { state: Object.freeze({ ...checkpoint.state }) });
831
+ }
832
+ catch (error) {
833
+ notify(runOptions, { ...event, recovered: false });
834
+ return { kind: 'failed', error, attempts: failure.attempts };
835
+ }
836
+ const command = decided instanceof graph_js_1.Command ? decided : undefined;
837
+ const parent = command?.graph === graph_js_1.Command.PARENT ? command : undefined;
838
+ const goto = parent ? undefined : toRouteRecords(command?.goto);
839
+ const own = command ? command.update : decided;
840
+ const updates = parent || !own ? [] : [own];
841
+ notify(runOptions, { ...event, recovered: true });
842
+ return {
843
+ kind: 'ok',
844
+ updates,
845
+ goto,
846
+ parent,
847
+ attempts: failure.attempts,
848
+ recovered: {
849
+ node: failure.node,
850
+ taskId: failure.taskId,
851
+ step,
852
+ attempts: failure.attempts,
853
+ error: {
854
+ name: failure.error instanceof Error ? failure.error.name : 'Error',
855
+ message: describe(failure.error),
856
+ },
857
+ failedAt: failure.failedAt,
858
+ retryExhausted: failure.retryExhausted,
859
+ ...(failure.timeout ? { timeout: failure.timeout } : {}),
860
+ ...(goto?.length ? { goto: goto.map(routeName) } : {}),
861
+ },
862
+ };
863
+ }
864
+ retryPolicy(definition) {
865
+ return {
866
+ ...DEFAULT_RETRY,
867
+ ...this.options.retry,
868
+ ...this.options.nodeDefaults?.retry,
869
+ ...definition.options.retry,
870
+ };
871
+ }
872
+ timeoutOf(definition) {
873
+ const defaults = this.options.nodeDefaults?.timeout;
874
+ const own = definition.options;
875
+ const runMs = own.timeout?.runMs ?? own.timeoutMs ?? defaults?.runMs;
876
+ const idleMs = own.timeout?.idleMs ?? defaults?.idleMs;
877
+ return { ...(runMs === undefined ? {} : { runMs }), ...(idleMs === undefined ? {} : { idleMs }) };
878
+ }
879
+ errorHandler(definition) {
880
+ return definition.options.onError ?? this.options.nodeDefaults?.onError;
881
+ }
882
+ async runNode(fn, task, step, threadId, checkpoint, runOptions, signal, attempt, touch = noop) {
690
883
  const node = task.node;
691
884
  let interruptIndex = 0;
692
885
  const context = {
@@ -694,11 +887,18 @@ class CompiledGraph {
694
887
  node,
695
888
  step,
696
889
  threadId,
890
+ ...(runOptions.tenantId !== undefined ? { tenantId: runOptions.tenantId } : {}),
697
891
  taskId: task.id,
698
892
  input: task.input,
699
893
  attempt,
700
894
  signal,
701
- ...(this.options.store ? { store: this.options.store } : {}),
895
+ ...(this.options.store
896
+ ? {
897
+ store: runOptions.tenantId !== undefined
898
+ ? (0, tenant_js_1.tenantStore)(this.options.store, runOptions.tenantId)
899
+ : this.options.store,
900
+ }
901
+ : {}),
702
902
  interrupt: (request) => {
703
903
  const index = interruptIndex++;
704
904
  const key = (0, errors_js_1.interruptKey)({ node, taskId: task.id, step, index });
@@ -710,8 +910,21 @@ class CompiledGraph {
710
910
  }
711
911
  throw new errors_js_1.GraphInterrupt(request, node, step, index, task.id);
712
912
  },
713
- emit: (data) => notify(runOptions, { type: 'custom', step, taskId: task.id, node, data }),
913
+ emit: (data) => {
914
+ touch();
915
+ notify(runOptions, { type: 'custom', step, taskId: task.id, node, data });
916
+ },
917
+ heartbeat: touch,
918
+ message: (chunk) => {
919
+ touch();
920
+ notify(runOptions, { type: 'message', step, taskId: task.id, node, chunk });
921
+ },
922
+ tool: (event) => {
923
+ touch();
924
+ notify(runOptions, { type: 'tool', step, taskId: task.id, node, tool: event });
925
+ },
714
926
  report: (progress) => {
927
+ touch();
715
928
  if (!runOptions.onProgress)
716
929
  return;
717
930
  try {
@@ -721,6 +934,11 @@ class CompiledGraph {
721
934
  }
722
935
  },
723
936
  };
937
+ if (runOptions.subgraphEvents) {
938
+ Object.defineProperty(context, FORWARD_EVENT, {
939
+ value: (event) => notify(runOptions, { ...event, namespace: [node, ...(event.namespace ?? [])] }),
940
+ });
941
+ }
724
942
  const result = await fn(context);
725
943
  const interrupted = interruptIndex > 0;
726
944
  if (result instanceof graph_js_1.Command) {
@@ -780,7 +998,12 @@ class CompiledGraph {
780
998
  if (!this.nodes.has(target.node)) {
781
999
  throw new errors_js_1.GraphValidationError(`Send from "${from}" targets unknown node "${target.node}"`);
782
1000
  }
783
- tasks.push({ id: `${target.node}#${step + 1}.${sends++}`, node: target.node, input: target.input });
1001
+ tasks.push({
1002
+ id: `${target.node}#${step + 1}.${sends++}`,
1003
+ node: target.node,
1004
+ input: target.input,
1005
+ ...(target.options?.timeout ? { timeout: target.options.timeout } : {}),
1006
+ });
784
1007
  return;
785
1008
  }
786
1009
  if (target === graph_js_1.END)
@@ -807,7 +1030,9 @@ class CompiledGraph {
807
1030
  }
808
1031
  }
809
1032
  for (const { from, target } of routes) {
810
- add(typeof target === 'string' ? target : new graph_js_1.Send(target.node, target.input), from);
1033
+ add(typeof target === 'string'
1034
+ ? target
1035
+ : new graph_js_1.Send(target.node, target.input, target.timeout ? { timeout: target.timeout } : undefined), from);
811
1036
  }
812
1037
  return tasks;
813
1038
  }
@@ -823,9 +1048,9 @@ class CompiledGraph {
823
1048
  }
824
1049
  return this.reduce(state, [input]);
825
1050
  }
826
- async requireCheckpoint(threadId) {
1051
+ async requireCheckpoint(threadId, tenantId) {
827
1052
  const checkpoint = await this.checkpointer()?.get(threadId);
828
- if (!checkpoint)
1053
+ if (!checkpoint || !ownedBy(checkpoint, tenantId))
829
1054
  throw new errors_js_1.GraphThreadNotFoundError(threadId);
830
1055
  return (0, checkpoint_migration_js_1.migrateCheckpoint)(checkpoint);
831
1056
  }
@@ -875,6 +1100,7 @@ class CompiledGraph {
875
1100
  ? { interrupt: checkpoint.interrupts[0], interrupts: checkpoint.interrupts }
876
1101
  : {}),
877
1102
  ...(checkpoint.breakpoint ? { breakpoint: checkpoint.breakpoint } : {}),
1103
+ ...(checkpoint.recovered?.length ? { recovered: checkpoint.recovered } : {}),
878
1104
  };
879
1105
  }
880
1106
  toResult(threadId, last) {
@@ -971,21 +1197,77 @@ function toRouteRecords(goto) {
971
1197
  if (goto === undefined)
972
1198
  return undefined;
973
1199
  return (Array.isArray(goto) ? goto : [goto]).map((target) => target instanceof graph_js_1.Send
974
- ? { node: target.node, ...(target.input === undefined ? {} : { input: target.input }) }
1200
+ ? {
1201
+ node: target.node,
1202
+ ...(target.input === undefined ? {} : { input: target.input }),
1203
+ ...(target.options?.timeout ? { timeout: target.options.timeout } : {}),
1204
+ }
975
1205
  : target);
976
1206
  }
977
1207
  function routeName(route) {
978
1208
  return typeof route === 'string' ? route : route.node;
979
1209
  }
980
- function rejectWhenAborted(signal, error) {
981
- return new Promise((_, reject) => {
982
- if (signal.aborted) {
983
- reject(error());
984
- return;
985
- }
986
- signal.addEventListener('abort', () => reject(error()), { once: true });
1210
+ function noop() { }
1211
+ function attemptTimer(node, limits) {
1212
+ const { runMs, idleMs } = limits;
1213
+ if (runMs === undefined && idleMs === undefined)
1214
+ return undefined;
1215
+ const controller = new AbortController();
1216
+ let reached;
1217
+ let reject = noop;
1218
+ const expired = new Promise((_, fail) => {
1219
+ reject = fail;
987
1220
  });
1221
+ expired.catch(noop);
1222
+ const fire = (error) => {
1223
+ if (reached)
1224
+ return;
1225
+ reached = error;
1226
+ controller.abort(error);
1227
+ reject(error);
1228
+ };
1229
+ const runTimer = runMs === undefined ? undefined : setTimeout(() => fire(new errors_js_1.GraphNodeTimeoutError(node, runMs)), runMs);
1230
+ let idleTimer;
1231
+ const armIdle = () => {
1232
+ if (idleMs === undefined || reached)
1233
+ return;
1234
+ if (idleTimer)
1235
+ clearTimeout(idleTimer);
1236
+ idleTimer = setTimeout(() => fire(new errors_js_1.GraphNodeTimeoutError(node, idleMs, 'idle')), idleMs);
1237
+ };
1238
+ armIdle();
1239
+ return {
1240
+ signal: controller.signal,
1241
+ expired,
1242
+ touch: armIdle,
1243
+ error: () => reached,
1244
+ stop: () => {
1245
+ if (runTimer)
1246
+ clearTimeout(runTimer);
1247
+ if (idleTimer)
1248
+ clearTimeout(idleTimer);
1249
+ idleTimer = undefined;
1250
+ },
1251
+ };
988
1252
  }
989
1253
  function isRetryable(error) {
990
1254
  return !(error instanceof errors_js_1.GraphValidationError);
991
1255
  }
1256
+ function tenantOf(checkpoint) {
1257
+ const tenantId = checkpoint.metadata?.tenantId;
1258
+ return typeof tenantId === 'string' ? tenantId : undefined;
1259
+ }
1260
+ function ownedBy(checkpoint, tenantId) {
1261
+ if (tenantId === undefined)
1262
+ return true;
1263
+ const owner = tenantOf(checkpoint);
1264
+ return owner === undefined || owner === tenantId;
1265
+ }
1266
+ async function* releasing(source, release) {
1267
+ try {
1268
+ yield* source;
1269
+ }
1270
+ finally {
1271
+ release();
1272
+ }
1273
+ }
@@ -2,6 +2,8 @@ export { CompiledGraph, StateGraph, createGraph } from './graph.js';
2
2
  export { type CheckpointDraft, type GraphCheckpointV2, migrateCheckpoint, toCheckpoint, } from './checkpoint-migration.js';
3
3
  export { appendList, appendSet, counter, lastValue, mergeObject, reducerChannel, } from './channels.js';
4
4
  export { MemoryGraphCheckpointer, OperationStoreCheckpointer, type MemoryGraphCheckpointerOptions, type OperationStoreCheckpointerOptions, } from './checkpointer.js';
5
- export { GraphError, GraphInterrupt, GraphNodeError, GraphNodeTimeoutError, GraphNotInterruptedError, GraphStepLimitError, GraphThreadNotFoundError, GraphValidationError, interruptKey, } from './errors.js';
5
+ export { GraphDrainedError, GraphError, GraphInterrupt, GraphNodeError, GraphNodeTimeoutError, GraphNotInterruptedError, GraphStepLimitError, GraphThreadNotFoundError, GraphValidationError, interruptKey, } from './errors.js';
6
+ export { RunControl } from './run-control.js';
7
+ export { GraphEventStream, GraphStreamOverflowError } from './event-stream.js';
6
8
  export { Command, END, Send, START } from '../types/graph.js';
7
- export type { Channel, ChannelSchema, CommandTarget, CompileOptions, EdgeRouter, GraphBreakpoint, GraphCheckpoint, GraphCheckpointV1, GraphCheckpointer, GraphDescription, GraphEvent, GraphInput, GraphProgress, GraphResult, GraphRunOptions, GraphRouteTarget, GraphStatus, GraphStepEvent, GraphTask, InterruptRequest, NodeCacheEntry, NodeCachePolicy, NodeContext, NodeFn, NodeOptions, NodeResult, PendingInterrupt, RetryPolicy, StateOf, StateUpdate, StoredGraphCheckpoint, } from '../types/graph.js';
9
+ export type { Channel, ChannelSchema, CommandTarget, CompileOptions, DurabilityMode, EdgeRouter, GraphBreakpoint, GraphCheckpoint, GraphCheckpointV1, GraphCheckpointer, GraphDescription, GraphEvent, GraphEventsOptions, GraphInput, GraphProgress, GraphResult, GraphRunOptions, GraphRouteTarget, GraphStatus, GraphStepEvent, GraphMessageChunk, GraphStreamEvent, GraphStreamOverflow, GraphStreamProjection, GraphStreamStats, GraphToolEvent, GraphTask, InterruptRequest, NodeCacheEntry, NodeCachePolicy, NodeContext, NodeErrorHandler, NodeFailure, NodeFn, NodeOptions, NodeResult, NodeTimeout, PendingInterrupt, RecoveredFailure, RetryPolicy, RunControlLike, SendOptions, StateOf, StateUpdate, StoredGraphCheckpoint, } from '../types/graph.js';