@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 +44 -0
- package/dist/index.d.ts +17 -2
- package/dist/index.js +110 -7
- package/dist/index.js.map +1 -1
- package/dist/internal.js +8 -2
- package/dist/internal.js.map +1 -1
- package/package.json +3 -3
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
|
|
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
|
-
|
|
603
|
-
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
...
|
|
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,
|