@kortyx/hooks 0.19.0 → 0.22.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.22.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.21.0...hooks-v0.22.0) (2026-09-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * complete client responses while workflows continue in background ([#165](https://github.com/kortyx-io/kortyx/issues/165)) ([a8a08cd](https://github.com/kortyx-io/kortyx/commit/a8a08cd1e9533e4b44efa4af54a2d2cec54431ae))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @kortyx/telemetry-contracts bumped to 0.5.0
16
+
17
+ ## [0.21.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.20.0...hooks-v0.21.0) (2026-09-10)
18
+
19
+
20
+ ### Features
21
+
22
+ * **runtime:** add shared execution limits and checkpoint continuation ([#163](https://github.com/kortyx-io/kortyx/issues/163)) ([e22232c](https://github.com/kortyx-io/kortyx/commit/e22232c059fae4f7df1bd36423902bd365887942))
23
+
24
+
25
+ ### Dependencies
26
+
27
+ * The following workspace dependencies were updated
28
+ * dependencies
29
+ * @kortyx/core bumped to 0.8.0
30
+ * @kortyx/telemetry-contracts bumped to 0.4.0
31
+
32
+ ## [0.20.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.19.0...hooks-v0.20.0) (2026-09-10)
33
+
34
+
35
+ ### Features
36
+
37
+ * cancel workflow trees and reflect cancellation in Studio ([#161](https://github.com/kortyx-io/kortyx/issues/161)) ([699ad18](https://github.com/kortyx-io/kortyx/commit/699ad18905955c6340c3d85b9fae7f0bffd00a0d))
38
+ * execute and resume workflows without chat transport ([#159](https://github.com/kortyx-io/kortyx/issues/159)) ([6decb17](https://github.com/kortyx-io/kortyx/commit/6decb1714fedc021ac9e125b6ed9f75475ed928a))
39
+
40
+
41
+ ### Dependencies
42
+
43
+ * The following workspace dependencies were updated
44
+ * dependencies
45
+ * @kortyx/core bumped to 0.7.0
46
+
3
47
  ## [0.19.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.18.0...hooks-v0.19.0) (2026-09-09)
4
48
 
5
49
 
package/dist/index.d.ts CHANGED
@@ -1,10 +1,18 @@
1
- import { WorkflowDefinition, TokenUsage, InterruptInput, NodeConfig, InterruptResult, GraphState } from '@kortyx/core';
1
+ import * as _kortyx_core from '@kortyx/core';
2
+ import { WorkflowDefinition, TokenUsage, InterruptInput, GraphState, NodeConfig, InterruptResult } from '@kortyx/core';
2
3
  import { K as KortyxTelemetryConfig, R as ReasonTraceAdapter, a as KortyxTraceMetadata, b as KortyxTelemetryEventType } from './tracing-BI6YKHSf.js';
3
4
  export { E as EnsureWorkflowTopologyRequest, c as EnsureWorkflowTopologyResponse, d as KortyxTelemetryContentCapture, e as KortyxTelemetryCorrelation, f as KortyxTelemetryEvent, g as KortyxTelemetryPrompt, h as KortyxTelemetryReporter, i as KortyxTelemetryService, j as KortyxTraceAdapter, k as ReasonTraceAttributes, l as ReasonTraceSpan, m as ReasonTraceSpanEndArgs, n as ReasonTraceSpanStartArgs } from './tracing-BI6YKHSf.js';
4
5
  import { z } from 'zod';
5
6
  import { ProviderModelRef, KortyxReasoningOptions, KortyxResponseFormat, KortyxExecutableTool, KortyxUsage, KortyxFinishReason, KortyxProviderMetadata, KortyxWarning, KortyxToolCall, KortyxToolResult } from '@kortyx/providers';
6
7
  import '@kortyx/telemetry-contracts';
7
8
 
9
+ type CompleteResponseOptions = {
10
+ message?: string | undefined;
11
+ data?: unknown;
12
+ };
13
+ /** Finish client delivery, leaving the node and workflow execution running. */
14
+ declare function completeResponse(options?: CompleteResponseOptions): Promise<void>;
15
+
8
16
  type WorkflowCallOutcome = {
9
17
  status: "completed";
10
18
  data: Record<string, unknown>;
@@ -13,6 +21,7 @@ type WorkflowCallOutcome = {
13
21
  status: "interrupted";
14
22
  request: InterruptInput;
15
23
  snapshot: unknown;
24
+ usage?: TokenUsage | undefined;
16
25
  };
17
26
  type WorkflowCallService = (args: {
18
27
  id: string;
@@ -60,6 +69,10 @@ declare function useWorkflow(args: {
60
69
  }>;
61
70
 
62
71
  type HookNodeRuntimeContext = {
72
+ completeResponse?: ((options: CompleteResponseOptions, state: GraphState) => Promise<void>) | undefined;
73
+ /** Transient execution control; never part of checkpointed state. */
74
+ abortSignal?: AbortSignal | undefined;
75
+ consumeExecution?: ((limit: _kortyx_core.ExecutionLimit) => void) | undefined;
63
76
  graph: {
64
77
  name: string;
65
78
  node: string;
@@ -214,6 +227,8 @@ type StateSetter<T> = (next: T | ((prev: T) => T)) => void;
214
227
  declare function useStructuredData<TData = unknown>(args: UseStructuredDataArgs<TData>): void;
215
228
  declare function useReason<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseReasonArgs<TOutput, TRequest, TResponse>): Promise<UseReasonResult<TOutput, TResponse>>;
216
229
  declare function useInterrupt<TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
230
+ /** Live execution signal for cooperative I/O. Never store it in workflow state. */
231
+ declare function useAbortSignal(): AbortSignal | undefined;
217
232
  declare function useRuntimeContext<TContext extends Record<string, unknown> = Record<string, unknown>>(): TContext;
218
233
  declare function useNodeState<T>(initialValue: T): [T, StateSetter<T>];
219
234
  declare function useWorkflowState<T>(key: string, ...rest: [] | [T]): [T, StateSetter<T>];
@@ -221,4 +236,4 @@ declare function useWorkflowState<T>(key: string, ...rest: [] | [T]): [T, StateS
221
236
  /** Best effort lifecycle facts. Engine snapshots and interrupt tokens never leave the runtime. */
222
237
  declare function emitWorkflowCall(telemetry: KortyxTelemetryConfig | undefined, type: KortyxTelemetryEventType, payload: Record<string, unknown>): void;
223
238
 
224
- export { type HookRuntimeContext, KortyxTelemetryConfig, KortyxTelemetryEventType, KortyxTraceMetadata, ReasonTraceAdapter, type UseInterruptArgs, type UseReasonArgs, type UseReasonResult, type UseReasonStep, type UseReasonToolExecution, type UseStructuredDataArgs, WorkflowCallError, type WorkflowCallOutcome, type WorkflowCallService, createWorkflowHooks, emitWorkflowCall, runWithHookContext, useInterrupt, useNodeState, useReason, useRuntimeContext, useStructuredData, useWorkflow, useWorkflowState, workflowCallFingerprint };
239
+ export { type CompleteResponseOptions, type HookRuntimeContext, KortyxTelemetryConfig, KortyxTelemetryEventType, KortyxTraceMetadata, ReasonTraceAdapter, type UseInterruptArgs, type UseReasonArgs, type UseReasonResult, type UseReasonStep, type UseReasonToolExecution, type UseStructuredDataArgs, WorkflowCallError, type WorkflowCallOutcome, type WorkflowCallService, completeResponse, createWorkflowHooks, emitWorkflowCall, runWithHookContext, useAbortSignal, useInterrupt, useNodeState, useReason, useRuntimeContext, useStructuredData, useWorkflow, useWorkflowState, workflowCallFingerprint };
package/dist/index.js CHANGED
@@ -20,9 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  var index_exports = {};
21
21
  __export(index_exports, {
22
22
  WorkflowCallError: () => WorkflowCallError,
23
+ completeResponse: () => completeResponse,
23
24
  createWorkflowHooks: () => createWorkflowHooks,
24
25
  emitWorkflowCall: () => emitWorkflowCall,
25
26
  runWithHookContext: () => runWithHookContext,
27
+ useAbortSignal: () => useAbortSignal,
26
28
  useInterrupt: () => useInterrupt,
27
29
  useNodeState: () => useNodeState,
28
30
  useReason: () => useReason2,
@@ -34,6 +36,9 @@ __export(index_exports, {
34
36
  });
35
37
  module.exports = __toCommonJS(index_exports);
36
38
 
39
+ // src/complete-response.ts
40
+ var import_zod = require("zod");
41
+
37
42
  // src/context.ts
38
43
  var import_node_async_hooks = require("async_hooks");
39
44
  var storage = new import_node_async_hooks.AsyncLocalStorage();
@@ -187,6 +192,33 @@ function getHookContext() {
187
192
  }
188
193
  return ctx;
189
194
  }
195
+ function snapshotHookState() {
196
+ const ctx = getHookContext();
197
+ return {
198
+ ...ctx.state,
199
+ lastNode: ctx.node.graph.node,
200
+ runtime: { ...ctx.state.runtime, ...buildRuntimeStateUpdates(ctx) }
201
+ };
202
+ }
203
+
204
+ // src/complete-response.ts
205
+ var optionsSchema = import_zod.z.object({
206
+ message: import_zod.z.string().optional(),
207
+ data: import_zod.z.json().optional()
208
+ }).strict();
209
+ async function completeResponse(options = {}) {
210
+ const ctx = getHookContext();
211
+ const parsed = optionsSchema.parse(options);
212
+ if (!ctx.node.completeResponse) {
213
+ throw new Error(
214
+ "completeResponse requires an agent-managed root workflow."
215
+ );
216
+ }
217
+ await ctx.node.completeResponse(parsed, snapshotHookState());
218
+ }
219
+
220
+ // src/interrupt.ts
221
+ var import_core = require("@kortyx/core");
190
222
 
191
223
  // src/reason/checkpoint.ts
192
224
  var resolveReasonCheckpointKey = (args) => typeof args.id === "string" && args.id.length > 0 ? `__useReason:${args.id}` : `__useReason:auto:${args.autoIndex}`;
@@ -243,6 +275,7 @@ var parseWithSchema = (schema, value, label) => {
243
275
  // src/interrupt.ts
244
276
  var awaitInterruptInternal = (args) => {
245
277
  const ctx = getHookContext();
278
+ (0, import_core.throwIfExecutionAborted)(ctx.node.abortSignal);
246
279
  const request = parseWithSchema(
247
280
  args.requestSchema,
248
281
  args.request,
@@ -276,6 +309,9 @@ var awaitInterruptInternal = (args) => {
276
309
  return Promise.resolve(response);
277
310
  };
278
311
 
312
+ // src/reason/use-reason.ts
313
+ var import_core5 = require("@kortyx/core");
314
+
279
315
  // src/structured.ts
280
316
  var import_node_crypto = require("crypto");
281
317
 
@@ -370,9 +406,11 @@ var shouldStreamStructured = (cfg) => Boolean(cfg) && (cfg?.stream ?? true);
370
406
 
371
407
  // src/reason/engine.ts
372
408
  var import_node_crypto3 = require("crypto");
409
+ var import_core3 = require("@kortyx/core");
373
410
 
374
411
  // src/reason-engine.ts
375
412
  var import_node_crypto2 = require("crypto");
413
+ var import_core2 = require("@kortyx/core");
376
414
  var toError = (value) => value instanceof Error ? value : new Error(String(value));
377
415
  var createRuntimeId = () => {
378
416
  try {
@@ -399,6 +437,7 @@ async function runReasonEngine(args) {
399
437
  const responseFormat = args.responseFormat ?? args.model.options?.responseFormat;
400
438
  const providerOptions = args.providerOptions ?? args.model.options?.providerOptions;
401
439
  const tools = args.tools ?? args.model.options?.tools;
440
+ (0, import_core2.throwIfExecutionAborted)(abortSignal);
402
441
  const model = args.model.provider.getModel(args.model.modelId, {
403
442
  ...temperature !== void 0 ? { temperature } : {},
404
443
  streaming: stream,
@@ -491,6 +530,7 @@ async function runReasonEngine(args) {
491
530
  }
492
531
  const response2 = await model.stream(messages);
493
532
  for await (const chunk of response2) {
533
+ (0, import_core2.throwIfExecutionAborted)(abortSignal);
494
534
  switch (chunk.type) {
495
535
  case "text-delta": {
496
536
  if (chunk.delta.length === 0) break;
@@ -569,10 +609,12 @@ async function runReasonEngine(args) {
569
609
  ...providerMetadata !== void 0 ? { providerMetadata } : {},
570
610
  ...warnings !== void 0 ? { warnings } : {}
571
611
  };
612
+ (0, import_core2.throwIfExecutionAborted)(abortSignal);
572
613
  endTrace(traceSpan, result2);
573
614
  return result2;
574
615
  }
575
616
  const response = await model.invoke(messages);
617
+ (0, import_core2.throwIfExecutionAborted)(abortSignal);
576
618
  if (emit) {
577
619
  emitNodeEvent(args.emitEvent, args.nodeId, "text-start", {
578
620
  ...commonMeta
@@ -599,8 +641,9 @@ async function runReasonEngine(args) {
599
641
  endTrace(traceSpan, result);
600
642
  return result;
601
643
  } catch (error) {
602
- failTrace(traceSpan, error);
603
- throw error;
644
+ const failure = abortSignal?.aborted ? (0, import_core2.createExecutionCancelledError)() : error;
645
+ failTrace(traceSpan, failure);
646
+ throw failure;
604
647
  }
605
648
  }
606
649
 
@@ -614,6 +657,13 @@ var createRuntimeId2 = () => {
614
657
  };
615
658
  async function reasonEngine(args, meta, inputOverride) {
616
659
  const ctx = getHookContext();
660
+ const abortSignal = (0, import_core3.combineAbortSignals)(
661
+ ctx.node.abortSignal,
662
+ args.abortSignal,
663
+ args.model.options?.abortSignal
664
+ );
665
+ (0, import_core3.throwIfExecutionAborted)(abortSignal);
666
+ ctx.node.consumeExecution?.("maxModelPasses");
617
667
  return runReasonEngine({
618
668
  model: args.model,
619
669
  input: inputOverride ?? args.input,
@@ -621,7 +671,7 @@ async function reasonEngine(args, meta, inputOverride) {
621
671
  temperature: args.temperature,
622
672
  maxOutputTokens: args.maxOutputTokens,
623
673
  stopSequences: args.stopSequences,
624
- abortSignal: args.abortSignal,
674
+ abortSignal,
625
675
  reasoning: args.reasoning,
626
676
  responseFormat: args.responseFormat,
627
677
  providerOptions: args.providerOptions,
@@ -807,7 +857,7 @@ var parseInterruptFirstPassResult = (args) => {
807
857
  };
808
858
 
809
859
  // src/reason/prompting.ts
810
- var import_zod = require("zod");
860
+ var import_zod2 = require("zod");
811
861
  var tryStringify2 = (value) => {
812
862
  if (typeof value === "string") return value;
813
863
  try {
@@ -818,7 +868,7 @@ var tryStringify2 = (value) => {
818
868
  };
819
869
  var tryGetSchemaHint = (schema) => {
820
870
  try {
821
- const hint = (0, import_zod.toJSONSchema)(schema);
871
+ const hint = (0, import_zod2.toJSONSchema)(schema);
822
872
  return JSON.stringify(hint, null, 2);
823
873
  } catch {
824
874
  return void 0;
@@ -1572,6 +1622,7 @@ var extractStreamingStringValues = (args) => {
1572
1622
  };
1573
1623
 
1574
1624
  // src/reason/tools.ts
1625
+ var import_core4 = require("@kortyx/core");
1575
1626
  var toErrorMessage = (error) => error instanceof Error ? error.message : String(error);
1576
1627
  var toToolDefinitions = (tools) => tools.map((tool) => ({
1577
1628
  name: tool.name,
@@ -1625,6 +1676,11 @@ var createInitialMessages = (args) => [
1625
1676
  var runReasonToolLoop = async (args) => {
1626
1677
  const { useReasonArgs, id, opId, traceSpan } = args;
1627
1678
  const ctx = getHookContext();
1679
+ const abortSignal = (0, import_core4.combineAbortSignals)(
1680
+ ctx.node.abortSignal,
1681
+ useReasonArgs.abortSignal,
1682
+ useReasonArgs.model.options?.abortSignal
1683
+ );
1628
1684
  const tools = useReasonArgs.tools ?? [];
1629
1685
  const toolByName = /* @__PURE__ */ new Map();
1630
1686
  let validationCompleted = false;
@@ -1674,6 +1730,7 @@ var runReasonToolLoop = async (args) => {
1674
1730
  };
1675
1731
  try {
1676
1732
  for (let stepIndex = 0; stepIndex < maxSteps; stepIndex += 1) {
1733
+ (0, import_core4.throwIfExecutionAborted)(abortSignal);
1677
1734
  traceSpan?.addEvent?.("useReason.tool-step.start", {
1678
1735
  stepIndex,
1679
1736
  toolCount: toolDefinitions.length
@@ -1691,6 +1748,7 @@ var runReasonToolLoop = async (args) => {
1691
1748
  finalText = step.text;
1692
1749
  finalRaw = step.raw;
1693
1750
  aggregatedUsage = mergeUsage(aggregatedUsage, step.usage);
1751
+ accumulateTokenUsage(step.usage);
1694
1752
  finalFinishReason = step.finishReason;
1695
1753
  aggregatedProviderMetadata = mergeProviderMetadata(
1696
1754
  aggregatedProviderMetadata,
@@ -1724,6 +1782,7 @@ var runReasonToolLoop = async (args) => {
1724
1782
  toolCalls
1725
1783
  });
1726
1784
  for (const toolCall of toolCalls) {
1785
+ (0, import_core4.throwIfExecutionAborted)(abortSignal);
1727
1786
  const tool = toolByName.get(toolCall.name);
1728
1787
  if (!tool) {
1729
1788
  throw new Error(
@@ -1791,10 +1850,13 @@ var runReasonToolLoop = async (args) => {
1791
1850
  }
1792
1851
  }
1793
1852
  try {
1853
+ (0, import_core4.throwIfExecutionAborted)(abortSignal);
1854
+ ctx.node.consumeExecution?.("maxToolCalls");
1794
1855
  const rawResult = await tool.execute(toolCall.input, {
1795
1856
  toolCallId: toolCall.id,
1796
- ...useReasonArgs.abortSignal ? { abortSignal: useReasonArgs.abortSignal } : {}
1857
+ ...abortSignal ? { abortSignal } : {}
1797
1858
  });
1859
+ (0, import_core4.throwIfExecutionAborted)(abortSignal);
1798
1860
  const result2 = normalizeToolResult(toolCall, rawResult);
1799
1861
  toolResults.push(result2);
1800
1862
  allToolResults.push(result2);
@@ -1814,6 +1876,9 @@ var runReasonToolLoop = async (args) => {
1814
1876
  isError: Boolean(result2.isError)
1815
1877
  });
1816
1878
  } catch (error) {
1879
+ (0, import_core4.throwIfExecutionAborted)(abortSignal);
1880
+ if ((0, import_core4.isExecutionLimitReached)(error) || (0, import_core4.isExecutionCancelled)(error))
1881
+ throw error;
1817
1882
  const result2 = {
1818
1883
  toolCallId: toolCall.id,
1819
1884
  name: tool.name,
@@ -1937,6 +2002,13 @@ var assertReasoningThoughtsCompatibility = (args) => {
1937
2002
  async function useReason(args) {
1938
2003
  assertReasoningThoughtsCompatibility(args);
1939
2004
  const ctx = getHookContext();
2005
+ const abortSignal = (0, import_core5.combineAbortSignals)(
2006
+ ctx.node.abortSignal,
2007
+ args.abortSignal,
2008
+ args.model.options?.abortSignal
2009
+ );
2010
+ (0, import_core5.throwIfExecutionAborted)(abortSignal);
2011
+ args = { ...args, abortSignal };
1940
2012
  const id = typeof args.id === "string" && args.id.length > 0 ? args.id : void 0;
1941
2013
  const opId = createRuntimeId2();
1942
2014
  const checkpointKey = resolveReasonCheckpointKey({
@@ -2306,6 +2378,9 @@ function useReason2(args) {
2306
2378
  function useInterrupt(args) {
2307
2379
  return awaitInterruptInternal(args);
2308
2380
  }
2381
+ function useAbortSignal() {
2382
+ return getHookContext().node.abortSignal;
2383
+ }
2309
2384
  function useRuntimeContext() {
2310
2385
  const ctx = getHookContext();
2311
2386
  const config = ctx.state.config;
@@ -2350,6 +2425,7 @@ function useWorkflowState(key, ...rest) {
2350
2425
 
2351
2426
  // src/workflow.ts
2352
2427
  var import_node_crypto5 = require("crypto");
2428
+ var import_core6 = require("@kortyx/core");
2353
2429
 
2354
2430
  // src/workflow-telemetry.ts
2355
2431
  var import_node_crypto4 = require("crypto");
@@ -2436,6 +2512,7 @@ function createWorkflowHooks(workflows) {
2436
2512
  }
2437
2513
  async function useWorkflow(args) {
2438
2514
  const ctx = getHookContext();
2515
+ (0, import_core6.throwIfExecutionAborted)(ctx.node.abortSignal);
2439
2516
  const service = ctx.node.callWorkflow;
2440
2517
  if (!service)
2441
2518
  throw new Error("useWorkflow requires an agent workflow registry.");
@@ -2469,6 +2546,7 @@ async function useWorkflow(args) {
2469
2546
  workflow,
2470
2547
  "call input or target changed during replay"
2471
2548
  );
2549
+ if (!record) ctx.node.consumeExecution?.("maxChildInvocations");
2472
2550
  record ??= {
2473
2551
  fingerprint,
2474
2552
  invocationId: (0, import_node_crypto5.randomUUID)(),
@@ -2502,6 +2580,15 @@ async function useWorkflow(args) {
2502
2580
  ...content
2503
2581
  });
2504
2582
  };
2583
+ const recordUsage = (usage) => {
2584
+ if (!usage) return;
2585
+ accumulateTokenUsage({
2586
+ input: usage.input - (record.usage?.input ?? 0),
2587
+ output: usage.output - (record.usage?.output ?? 0),
2588
+ total: usage.total - (record.usage?.total ?? 0)
2589
+ });
2590
+ record.usage = usage;
2591
+ };
2505
2592
  const cached = record.status === "completed";
2506
2593
  try {
2507
2594
  for (const interruption of record.interrupts) {
@@ -2530,14 +2617,28 @@ async function useWorkflow(args) {
2530
2617
  ...record.interrupts.length ? { response: record.interrupts.at(-1)?.response } : {}
2531
2618
  });
2532
2619
  } catch (error) {
2620
+ (0, import_core6.throwIfExecutionAborted)(ctx.node.abortSignal);
2621
+ if ((0, import_core6.isExecutionCancelled)(error)) throw error;
2622
+ if ((0, import_core6.isExecutionLimitReached)(error)) {
2623
+ const child = error;
2624
+ if (child.__kortyxChildSnapshot)
2625
+ record.snapshot = child.__kortyxChildSnapshot;
2626
+ recordUsage(child.__kortyxChildUsage);
2627
+ report("suspended", {
2628
+ reason: "limit_reached",
2629
+ limit: error.limitReached
2630
+ });
2631
+ throw error;
2632
+ }
2533
2633
  record.status = "failed";
2534
2634
  record.error = error instanceof Error ? error.message : String(error);
2535
2635
  report("failed", { error: "Child workflow failed" });
2536
2636
  throw new WorkflowCallError(workflow, record.error);
2537
2637
  }
2638
+ (0, import_core6.throwIfExecutionAborted)(ctx.node.abortSignal);
2639
+ recordUsage(outcome.usage);
2538
2640
  if (outcome.status === "completed") {
2539
2641
  record.data = outcome.data;
2540
- accumulateTokenUsage(outcome.usage);
2541
2642
  workflowCallFingerprint(record.data);
2542
2643
  record.status = "completed";
2543
2644
  delete record.snapshot;
@@ -2574,9 +2675,11 @@ async function useWorkflow(args) {
2574
2675
  // Annotate the CommonJS export names for ESM import in node:
2575
2676
  0 && (module.exports = {
2576
2677
  WorkflowCallError,
2678
+ completeResponse,
2577
2679
  createWorkflowHooks,
2578
2680
  emitWorkflowCall,
2579
2681
  runWithHookContext,
2682
+ useAbortSignal,
2580
2683
  useInterrupt,
2581
2684
  useNodeState,
2582
2685
  useReason,