@kortyx/hooks 0.8.0 → 0.9.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 +9 -0
- package/dist/index.d.ts +28 -9
- package/dist/index.js +571 -46
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.8.0...hooks-v0.9.0) (2026-04-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **hooks:** support incremental structured data streaming ([05e9678](https://github.com/kortyx-io/kortyx/commit/05e96789a9a132549c9245b1feb76d20916da42a))
|
|
9
|
+
* **hooks:** support incremental structured data streaming ([05e9678](https://github.com/kortyx-io/kortyx/commit/05e96789a9a132549c9245b1feb76d20916da42a))
|
|
10
|
+
* **hooks:** support incremental structured data streaming ([4023fda](https://github.com/kortyx-io/kortyx/commit/4023fda42bfecc81782e474e6d442b379a3fa3d4))
|
|
11
|
+
|
|
3
12
|
## [0.8.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.7.0...hooks-v0.8.0) (2026-03-11)
|
|
4
13
|
|
|
5
14
|
|
package/dist/index.d.ts
CHANGED
|
@@ -22,24 +22,43 @@ type SchemaLike<T> = {
|
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
-
type
|
|
26
|
-
type UseStructuredDataArgs<TData = unknown> = {
|
|
27
|
-
data: TData;
|
|
25
|
+
type UseStructuredDataBaseArgs = {
|
|
28
26
|
dataType?: string | undefined;
|
|
29
|
-
dataSchema?: SchemaLike<TData> | undefined;
|
|
30
|
-
mode?: StructuredDataMode | undefined;
|
|
31
27
|
schemaId?: string | undefined;
|
|
32
28
|
schemaVersion?: string | undefined;
|
|
33
29
|
id?: string | undefined;
|
|
34
|
-
|
|
30
|
+
streamId?: string | undefined;
|
|
31
|
+
};
|
|
32
|
+
type UseStructuredDataFinalArgs<TData = unknown> = UseStructuredDataBaseArgs & {
|
|
33
|
+
kind?: "final" | undefined;
|
|
34
|
+
data: TData;
|
|
35
|
+
dataSchema?: SchemaLike<TData> | undefined;
|
|
35
36
|
};
|
|
36
|
-
type
|
|
37
|
+
type UseStructuredDataSetArgs<TValue = unknown> = UseStructuredDataBaseArgs & {
|
|
38
|
+
kind: "set";
|
|
39
|
+
path: string;
|
|
40
|
+
value: TValue;
|
|
41
|
+
valueSchema?: SchemaLike<TValue> | undefined;
|
|
42
|
+
};
|
|
43
|
+
type UseStructuredDataAppendArgs<TItem = unknown> = UseStructuredDataBaseArgs & {
|
|
44
|
+
kind: "append";
|
|
45
|
+
path: string;
|
|
46
|
+
items: TItem[];
|
|
47
|
+
itemSchema?: SchemaLike<TItem> | undefined;
|
|
48
|
+
};
|
|
49
|
+
type UseStructuredDataTextDeltaArgs = UseStructuredDataBaseArgs & {
|
|
50
|
+
kind: "text-delta";
|
|
51
|
+
path: string;
|
|
52
|
+
delta: string;
|
|
53
|
+
};
|
|
54
|
+
type UseStructuredDataArgs<TData = unknown, TValue = unknown, TItem = unknown> = UseStructuredDataFinalArgs<TData> | UseStructuredDataSetArgs<TValue> | UseStructuredDataAppendArgs<TItem> | UseStructuredDataTextDeltaArgs;
|
|
37
55
|
type UseReasonStructuredConfig = {
|
|
38
|
-
stream?:
|
|
56
|
+
stream?: boolean | undefined;
|
|
39
57
|
optimistic?: boolean | undefined;
|
|
40
58
|
dataType?: string | undefined;
|
|
41
59
|
schemaId?: string | undefined;
|
|
42
60
|
schemaVersion?: string | undefined;
|
|
61
|
+
fields?: Record<string, "append" | "text-delta" | "set"> | undefined;
|
|
43
62
|
};
|
|
44
63
|
type UseReasonInterruptConfig<TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult> = {
|
|
45
64
|
requestSchema: SchemaLike<TRequest>;
|
|
@@ -82,6 +101,6 @@ declare function useStructuredData<TData = unknown>(args: UseStructuredDataArgs<
|
|
|
82
101
|
declare function useReason<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseReasonArgs<TOutput, TRequest, TResponse>): Promise<UseReasonResult<TOutput, TResponse>>;
|
|
83
102
|
declare function useInterrupt<TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
|
|
84
103
|
declare function useNodeState<T>(initialValue: T): [T, StateSetter<T>];
|
|
85
|
-
declare function useWorkflowState<T>(key: string,
|
|
104
|
+
declare function useWorkflowState<T>(key: string, ...rest: [] | [T]): [T, StateSetter<T>];
|
|
86
105
|
|
|
87
106
|
export { type HookRuntimeContext, type UseInterruptArgs, type UseReasonArgs, type UseReasonResult, type UseStructuredDataArgs, runWithHookContext, useInterrupt, useNodeState, useReason, useStructuredData, useWorkflowState };
|
package/dist/index.js
CHANGED
|
@@ -57,8 +57,9 @@ var getHookRuntimeState = (state) => {
|
|
|
57
57
|
var createInternalContext = (ctx) => {
|
|
58
58
|
const hookRuntimeState = getHookRuntimeState(ctx.state);
|
|
59
59
|
const nodeId = ctx.node.graph.node;
|
|
60
|
-
const
|
|
61
|
-
const
|
|
60
|
+
const storedNodeState = isRecord(hookRuntimeState.nodeState) ? hookRuntimeState.nodeState : void 0;
|
|
61
|
+
const storedNodeId = typeof storedNodeState?.nodeId === "string" ? String(storedNodeState.nodeId) : "";
|
|
62
|
+
const storedState = storedNodeState?.state;
|
|
62
63
|
const currentNodeState = storedNodeId && storedNodeId === nodeId ? normalizeNodeState(storedState) : { byIndex: [], byKey: {} };
|
|
63
64
|
return {
|
|
64
65
|
...ctx,
|
|
@@ -144,31 +145,73 @@ var awaitInterruptInternal = (args) => {
|
|
|
144
145
|
};
|
|
145
146
|
|
|
146
147
|
// src/structured.ts
|
|
148
|
+
var import_node_crypto = require("crypto");
|
|
149
|
+
var createStructuredStreamId = () => {
|
|
150
|
+
try {
|
|
151
|
+
return (0, import_node_crypto.randomUUID)();
|
|
152
|
+
} catch {
|
|
153
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
147
156
|
var emitStructuredData = (args) => {
|
|
148
157
|
const ctx = getHookContext();
|
|
158
|
+
const streamId = typeof args.streamId === "string" && args.streamId.length > 0 ? args.streamId : createStructuredStreamId();
|
|
159
|
+
const dataType = typeof args.dataType === "string" && args.dataType.length > 0 ? args.dataType : "generic";
|
|
160
|
+
const base = {
|
|
161
|
+
node: ctx.node.graph.node,
|
|
162
|
+
streamId,
|
|
163
|
+
dataType,
|
|
164
|
+
...typeof args.schemaId === "string" && args.schemaId.length > 0 ? { schemaId: args.schemaId } : {},
|
|
165
|
+
...typeof args.schemaVersion === "string" && args.schemaVersion.length > 0 ? { schemaVersion: args.schemaVersion } : {},
|
|
166
|
+
...typeof args.id === "string" && args.id.length > 0 ? { id: args.id } : {}
|
|
167
|
+
};
|
|
168
|
+
if (args.kind === "set") {
|
|
169
|
+
const value = parseWithSchema(
|
|
170
|
+
args.valueSchema,
|
|
171
|
+
args.value,
|
|
172
|
+
"useStructuredData value"
|
|
173
|
+
);
|
|
174
|
+
ctx.node.emit("structured_data", {
|
|
175
|
+
...base,
|
|
176
|
+
kind: "set",
|
|
177
|
+
path: args.path,
|
|
178
|
+
value
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (args.kind === "append") {
|
|
183
|
+
const items = args.items.map(
|
|
184
|
+
(item) => parseWithSchema(args.itemSchema, item, "useStructuredData append item")
|
|
185
|
+
);
|
|
186
|
+
ctx.node.emit("structured_data", {
|
|
187
|
+
...base,
|
|
188
|
+
kind: "append",
|
|
189
|
+
path: args.path,
|
|
190
|
+
items
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (args.kind === "text-delta") {
|
|
195
|
+
ctx.node.emit("structured_data", {
|
|
196
|
+
...base,
|
|
197
|
+
kind: "text-delta",
|
|
198
|
+
path: args.path,
|
|
199
|
+
delta: args.delta
|
|
200
|
+
});
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
149
203
|
const validated = parseWithSchema(
|
|
150
204
|
args.dataSchema,
|
|
151
205
|
args.data,
|
|
152
206
|
"useStructuredData data"
|
|
153
207
|
);
|
|
154
208
|
ctx.node.emit("structured_data", {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
...typeof args.mode === "string" ? { mode: args.mode } : {},
|
|
158
|
-
...typeof args.schemaId === "string" && args.schemaId.length > 0 ? { schemaId: args.schemaId } : {},
|
|
159
|
-
...typeof args.schemaVersion === "string" && args.schemaVersion.length > 0 ? { schemaVersion: args.schemaVersion } : {},
|
|
160
|
-
...typeof args.id === "string" && args.id.length > 0 ? { id: args.id } : {},
|
|
161
|
-
...typeof args.opId === "string" && args.opId.length > 0 ? { opId: args.opId } : {},
|
|
209
|
+
...base,
|
|
210
|
+
kind: "final",
|
|
162
211
|
data: validated
|
|
163
212
|
});
|
|
164
213
|
};
|
|
165
|
-
var shouldEmitStructured = (cfg) => (cfg?.stream ??
|
|
166
|
-
var resolveStructuredMode = (cfg) => {
|
|
167
|
-
const mode = cfg?.stream ?? "patch";
|
|
168
|
-
if (mode === "snapshot") return "snapshot";
|
|
169
|
-
if (mode === "patch") return "patch";
|
|
170
|
-
return "final";
|
|
171
|
-
};
|
|
214
|
+
var shouldEmitStructured = (cfg) => Boolean(cfg) && (cfg?.stream ?? true);
|
|
172
215
|
|
|
173
216
|
// src/reason/checkpoint.ts
|
|
174
217
|
var resolveReasonCheckpointKey = (args) => typeof args.id === "string" && args.id.length > 0 ? `__useReason:${args.id}` : `__useReason:auto:${args.autoIndex}`;
|
|
@@ -197,10 +240,10 @@ var resolveHookStatePatch = (args) => ({
|
|
|
197
240
|
});
|
|
198
241
|
|
|
199
242
|
// src/reason/engine.ts
|
|
200
|
-
var
|
|
243
|
+
var import_node_crypto3 = require("crypto");
|
|
201
244
|
|
|
202
245
|
// src/reason-engine.ts
|
|
203
|
-
var
|
|
246
|
+
var import_node_crypto2 = require("crypto");
|
|
204
247
|
var chunkToText = (chunk) => {
|
|
205
248
|
if (typeof chunk === "string") return chunk;
|
|
206
249
|
if (typeof chunk.text === "string") return chunk.text;
|
|
@@ -209,7 +252,7 @@ var chunkToText = (chunk) => {
|
|
|
209
252
|
};
|
|
210
253
|
var createRuntimeId = () => {
|
|
211
254
|
try {
|
|
212
|
-
return (0,
|
|
255
|
+
return (0, import_node_crypto2.randomUUID)();
|
|
213
256
|
} catch {
|
|
214
257
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
215
258
|
}
|
|
@@ -254,6 +297,7 @@ async function runReasonEngine(args) {
|
|
|
254
297
|
const text = chunkToText(chunk);
|
|
255
298
|
if (!text) continue;
|
|
256
299
|
final += text;
|
|
300
|
+
args.onTextChunk?.(text);
|
|
257
301
|
if (typeof chunk === "object" && chunk && "raw" in chunk) {
|
|
258
302
|
raw = chunk.raw;
|
|
259
303
|
}
|
|
@@ -298,7 +342,7 @@ async function runReasonEngine(args) {
|
|
|
298
342
|
// src/reason/engine.ts
|
|
299
343
|
var createRuntimeId2 = () => {
|
|
300
344
|
try {
|
|
301
|
-
return (0,
|
|
345
|
+
return (0, import_node_crypto3.randomUUID)();
|
|
302
346
|
} catch {
|
|
303
347
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
304
348
|
}
|
|
@@ -318,6 +362,7 @@ async function reasonEngine(args, meta, inputOverride) {
|
|
|
318
362
|
defaultTemperature: ctx.node.config?.model?.temperature,
|
|
319
363
|
stream: args.stream,
|
|
320
364
|
emit: args.emit,
|
|
365
|
+
onTextChunk: args.onTextChunk,
|
|
321
366
|
nodeId: ctx.node.graph.node,
|
|
322
367
|
emitEvent: ctx.node.emit,
|
|
323
368
|
id: meta.id,
|
|
@@ -494,6 +539,413 @@ var withOutputGuardrails = (input, schema) => {
|
|
|
494
539
|
].join("\n\n");
|
|
495
540
|
return withSchemaHint(base, "Expected output JSON schema", schema);
|
|
496
541
|
};
|
|
542
|
+
var withStructuredStreamHints = (input, args) => {
|
|
543
|
+
const rules = [];
|
|
544
|
+
for (const path of args.setFieldPaths ?? []) {
|
|
545
|
+
rules.push(
|
|
546
|
+
`- For the top-level field \`${path}\`, write one stable final value and do not rewrite it after it is complete.`
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
for (const path of args.appendFieldPaths ?? []) {
|
|
550
|
+
rules.push(
|
|
551
|
+
`- For the top-level array field \`${path}\`, write items in final order and finish each item before starting the next.`
|
|
552
|
+
);
|
|
553
|
+
rules.push(
|
|
554
|
+
`- Once an item in \`${path}\` is complete, do not rewrite or reorder earlier items.`
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
for (const path of args.textDeltaFieldPaths ?? []) {
|
|
558
|
+
rules.push(
|
|
559
|
+
`- For the top-level string field \`${path}\`, write the value progressively by appending text to the end.`
|
|
560
|
+
);
|
|
561
|
+
rules.push(
|
|
562
|
+
`- Do not rewrite or replace the earlier prefix of \`${path}\` once emitted.`
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
if (rules.length === 0) return input;
|
|
566
|
+
return [
|
|
567
|
+
input,
|
|
568
|
+
"Streaming rules:",
|
|
569
|
+
...rules,
|
|
570
|
+
"- Keep the overall response as valid JSON."
|
|
571
|
+
].join("\n\n");
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
// src/reason/structured-stream.ts
|
|
575
|
+
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
576
|
+
var findTopLevelArrayStart = (text, path) => {
|
|
577
|
+
const match = new RegExp(`"${escapeRegex(path)}"\\s*:\\s*\\[`).exec(text);
|
|
578
|
+
return match ? match.index + match[0].length : -1;
|
|
579
|
+
};
|
|
580
|
+
var resolveAppendFieldPaths = (cfg) => {
|
|
581
|
+
const fields = cfg?.fields;
|
|
582
|
+
if (!fields) return [];
|
|
583
|
+
const appendPaths = Object.entries(fields).filter(([, mode]) => mode === "append").map(([path]) => path);
|
|
584
|
+
for (const path of appendPaths) {
|
|
585
|
+
if (!path || path.includes(".")) {
|
|
586
|
+
throw new Error(
|
|
587
|
+
"useReason structured append streaming currently supports top-level array fields only."
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
return appendPaths;
|
|
592
|
+
};
|
|
593
|
+
var resolveSetFieldPaths = (cfg) => {
|
|
594
|
+
const fields = cfg?.fields;
|
|
595
|
+
if (!fields) return [];
|
|
596
|
+
const setPaths = Object.entries(fields).filter(([, mode]) => mode === "set").map(([path]) => path);
|
|
597
|
+
for (const path of setPaths) {
|
|
598
|
+
if (!path || path.includes(".")) {
|
|
599
|
+
throw new Error(
|
|
600
|
+
"useReason structured set streaming currently supports top-level fields only."
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return setPaths;
|
|
605
|
+
};
|
|
606
|
+
var resolveTextDeltaFieldPaths = (cfg) => {
|
|
607
|
+
const fields = cfg?.fields;
|
|
608
|
+
if (!fields) return [];
|
|
609
|
+
const textPaths = Object.entries(fields).filter(([, mode]) => mode === "text-delta").map(([path]) => path);
|
|
610
|
+
for (const path of textPaths) {
|
|
611
|
+
if (!path || path.includes(".")) {
|
|
612
|
+
throw new Error(
|
|
613
|
+
"useReason structured text-delta streaming currently supports top-level string fields only."
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return textPaths;
|
|
618
|
+
};
|
|
619
|
+
var findTopLevelFieldValueStart = (text, path) => {
|
|
620
|
+
const match = new RegExp(`"${escapeRegex(path)}"\\s*:\\s*`).exec(text);
|
|
621
|
+
return match ? match.index + match[0].length : -1;
|
|
622
|
+
};
|
|
623
|
+
var findTopLevelStringStart = (text, path) => {
|
|
624
|
+
const match = new RegExp(`"${escapeRegex(path)}"\\s*:\\s*"`).exec(text);
|
|
625
|
+
return match ? match.index + match[0].length : -1;
|
|
626
|
+
};
|
|
627
|
+
var extractCompletedStringValueAt = (args) => {
|
|
628
|
+
let value = "";
|
|
629
|
+
for (let i = args.start; i < args.text.length; i += 1) {
|
|
630
|
+
const ch = args.text[i];
|
|
631
|
+
if (ch === void 0) break;
|
|
632
|
+
if (ch === '"') {
|
|
633
|
+
return {
|
|
634
|
+
complete: true,
|
|
635
|
+
value
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
if (ch !== "\\") {
|
|
639
|
+
value += ch;
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
const next = args.text[i + 1];
|
|
643
|
+
if (!next) {
|
|
644
|
+
return {
|
|
645
|
+
complete: false
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
if (next === '"' || next === "\\" || next === "/" || next === "b" || next === "f" || next === "n" || next === "r" || next === "t") {
|
|
649
|
+
value += next === "b" ? "\b" : next === "f" ? "\f" : next === "n" ? "\n" : next === "r" ? "\r" : next === "t" ? " " : next;
|
|
650
|
+
i += 1;
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
if (next === "u") {
|
|
654
|
+
const hex = args.text.slice(i + 2, i + 6);
|
|
655
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
656
|
+
return {
|
|
657
|
+
complete: false
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
value += String.fromCharCode(Number.parseInt(hex, 16));
|
|
661
|
+
i += 5;
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
return {
|
|
665
|
+
complete: false
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
return {
|
|
669
|
+
complete: false
|
|
670
|
+
};
|
|
671
|
+
};
|
|
672
|
+
var extractCompletedNestedValueAt = (args) => {
|
|
673
|
+
let inString = false;
|
|
674
|
+
let isEscaped = false;
|
|
675
|
+
let nesting = 0;
|
|
676
|
+
for (let i = args.start; i < args.text.length; i += 1) {
|
|
677
|
+
const ch = args.text[i];
|
|
678
|
+
if (ch === void 0) break;
|
|
679
|
+
if (inString) {
|
|
680
|
+
if (isEscaped) {
|
|
681
|
+
isEscaped = false;
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
if (ch === "\\") {
|
|
685
|
+
isEscaped = true;
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
if (ch === '"') {
|
|
689
|
+
inString = false;
|
|
690
|
+
}
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
if (ch === '"') {
|
|
694
|
+
inString = true;
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
if (ch === args.opener) {
|
|
698
|
+
nesting += 1;
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
701
|
+
if (ch === args.closer) {
|
|
702
|
+
nesting -= 1;
|
|
703
|
+
if (nesting === 0) {
|
|
704
|
+
const raw = args.text.slice(args.start, i + 1);
|
|
705
|
+
try {
|
|
706
|
+
return {
|
|
707
|
+
complete: true,
|
|
708
|
+
value: JSON.parse(raw)
|
|
709
|
+
};
|
|
710
|
+
} catch {
|
|
711
|
+
return {
|
|
712
|
+
complete: false
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return {
|
|
719
|
+
complete: false
|
|
720
|
+
};
|
|
721
|
+
};
|
|
722
|
+
var extractCompletedFieldValue = (args) => {
|
|
723
|
+
const start = findTopLevelFieldValueStart(args.text, args.path);
|
|
724
|
+
if (start < 0) {
|
|
725
|
+
return {
|
|
726
|
+
found: false,
|
|
727
|
+
complete: false
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
const first = args.text[start];
|
|
731
|
+
if (!first) {
|
|
732
|
+
return {
|
|
733
|
+
found: true,
|
|
734
|
+
complete: false
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
if (first === '"') {
|
|
738
|
+
const parsed = extractCompletedStringValueAt({
|
|
739
|
+
text: args.text,
|
|
740
|
+
start: start + 1
|
|
741
|
+
});
|
|
742
|
+
return parsed.complete ? {
|
|
743
|
+
found: true,
|
|
744
|
+
complete: true,
|
|
745
|
+
value: parsed.value
|
|
746
|
+
} : {
|
|
747
|
+
found: true,
|
|
748
|
+
complete: false
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
if (first === "{") {
|
|
752
|
+
const parsed = extractCompletedNestedValueAt({
|
|
753
|
+
text: args.text,
|
|
754
|
+
start,
|
|
755
|
+
opener: "{",
|
|
756
|
+
closer: "}"
|
|
757
|
+
});
|
|
758
|
+
return parsed.complete ? {
|
|
759
|
+
found: true,
|
|
760
|
+
complete: true,
|
|
761
|
+
value: parsed.value
|
|
762
|
+
} : {
|
|
763
|
+
found: true,
|
|
764
|
+
complete: false
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
if (first === "[") {
|
|
768
|
+
const parsed = extractCompletedNestedValueAt({
|
|
769
|
+
text: args.text,
|
|
770
|
+
start,
|
|
771
|
+
opener: "[",
|
|
772
|
+
closer: "]"
|
|
773
|
+
});
|
|
774
|
+
return parsed.complete ? {
|
|
775
|
+
found: true,
|
|
776
|
+
complete: true,
|
|
777
|
+
value: parsed.value
|
|
778
|
+
} : {
|
|
779
|
+
found: true,
|
|
780
|
+
complete: false
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
for (let i = start; i < args.text.length; i += 1) {
|
|
784
|
+
const ch = args.text[i];
|
|
785
|
+
if (ch === void 0) break;
|
|
786
|
+
if (ch !== "," && ch !== "}") continue;
|
|
787
|
+
const raw = args.text.slice(start, i).trim();
|
|
788
|
+
if (!raw) {
|
|
789
|
+
return {
|
|
790
|
+
found: true,
|
|
791
|
+
complete: false
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
try {
|
|
795
|
+
return {
|
|
796
|
+
found: true,
|
|
797
|
+
complete: true,
|
|
798
|
+
value: JSON.parse(raw)
|
|
799
|
+
};
|
|
800
|
+
} catch {
|
|
801
|
+
return {
|
|
802
|
+
found: true,
|
|
803
|
+
complete: false
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return {
|
|
808
|
+
found: true,
|
|
809
|
+
complete: false
|
|
810
|
+
};
|
|
811
|
+
};
|
|
812
|
+
var extractCompletedArrayItems = (args) => {
|
|
813
|
+
const start = findTopLevelArrayStart(args.text, args.path);
|
|
814
|
+
if (start < 0) return [];
|
|
815
|
+
const items = [];
|
|
816
|
+
let inString = false;
|
|
817
|
+
let isEscaped = false;
|
|
818
|
+
let nesting = 0;
|
|
819
|
+
let itemStart = -1;
|
|
820
|
+
for (let i = start; i < args.text.length; i += 1) {
|
|
821
|
+
const ch = args.text[i];
|
|
822
|
+
if (ch === void 0) break;
|
|
823
|
+
if (inString) {
|
|
824
|
+
if (isEscaped) {
|
|
825
|
+
isEscaped = false;
|
|
826
|
+
continue;
|
|
827
|
+
}
|
|
828
|
+
if (ch === "\\") {
|
|
829
|
+
isEscaped = true;
|
|
830
|
+
continue;
|
|
831
|
+
}
|
|
832
|
+
if (ch === '"') {
|
|
833
|
+
inString = false;
|
|
834
|
+
}
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
if (ch === '"') {
|
|
838
|
+
inString = true;
|
|
839
|
+
if (itemStart < 0) itemStart = i;
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
if (itemStart < 0) {
|
|
843
|
+
if (/\s/.test(ch) || ch === ",") continue;
|
|
844
|
+
if (ch === "]") break;
|
|
845
|
+
itemStart = i;
|
|
846
|
+
if (ch === "{" || ch === "[") {
|
|
847
|
+
nesting = 1;
|
|
848
|
+
} else {
|
|
849
|
+
nesting = 0;
|
|
850
|
+
}
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
853
|
+
if (ch === "{" || ch === "[") {
|
|
854
|
+
nesting += 1;
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
if (ch === "}" || ch === "]") {
|
|
858
|
+
if (nesting > 0) {
|
|
859
|
+
nesting -= 1;
|
|
860
|
+
if (nesting > 0) continue;
|
|
861
|
+
}
|
|
862
|
+
if (ch === "]") {
|
|
863
|
+
const raw = args.text.slice(itemStart, i).trim();
|
|
864
|
+
if (raw) {
|
|
865
|
+
try {
|
|
866
|
+
items.push(JSON.parse(raw));
|
|
867
|
+
} catch {
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
break;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
if (nesting === 0 && (ch === "," || ch === "]")) {
|
|
874
|
+
const raw = args.text.slice(itemStart, i).trim();
|
|
875
|
+
if (raw) {
|
|
876
|
+
try {
|
|
877
|
+
items.push(JSON.parse(raw));
|
|
878
|
+
} catch {
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
itemStart = -1;
|
|
882
|
+
if (ch === "]") break;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return items;
|
|
886
|
+
};
|
|
887
|
+
var extractStreamingStringValue = (args) => {
|
|
888
|
+
const start = findTopLevelStringStart(args.text, args.path);
|
|
889
|
+
if (start < 0) {
|
|
890
|
+
return {
|
|
891
|
+
found: false,
|
|
892
|
+
complete: false,
|
|
893
|
+
value: ""
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
let value = "";
|
|
897
|
+
for (let i = start; i < args.text.length; i += 1) {
|
|
898
|
+
const ch = args.text[i];
|
|
899
|
+
if (ch === void 0) break;
|
|
900
|
+
if (ch === '"') {
|
|
901
|
+
return {
|
|
902
|
+
found: true,
|
|
903
|
+
complete: true,
|
|
904
|
+
value
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
if (ch !== "\\") {
|
|
908
|
+
value += ch;
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
const next = args.text[i + 1];
|
|
912
|
+
if (!next) {
|
|
913
|
+
return {
|
|
914
|
+
found: true,
|
|
915
|
+
complete: false,
|
|
916
|
+
value
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
if (next === '"' || next === "\\" || next === "/" || next === "b" || next === "f" || next === "n" || next === "r" || next === "t") {
|
|
920
|
+
value += next === "b" ? "\b" : next === "f" ? "\f" : next === "n" ? "\n" : next === "r" ? "\r" : next === "t" ? " " : next;
|
|
921
|
+
i += 1;
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
if (next === "u") {
|
|
925
|
+
const hex = args.text.slice(i + 2, i + 6);
|
|
926
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
927
|
+
return {
|
|
928
|
+
found: true,
|
|
929
|
+
complete: false,
|
|
930
|
+
value
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
value += String.fromCharCode(Number.parseInt(hex, 16));
|
|
934
|
+
i += 5;
|
|
935
|
+
continue;
|
|
936
|
+
}
|
|
937
|
+
return {
|
|
938
|
+
found: true,
|
|
939
|
+
complete: false,
|
|
940
|
+
value
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
return {
|
|
944
|
+
found: true,
|
|
945
|
+
complete: false,
|
|
946
|
+
value
|
|
947
|
+
};
|
|
948
|
+
};
|
|
497
949
|
|
|
498
950
|
// src/reason/use-reason.ts
|
|
499
951
|
var emitReasonStructuredOutput = (args) => {
|
|
@@ -501,11 +953,11 @@ var emitReasonStructuredOutput = (args) => {
|
|
|
501
953
|
emitStructuredData({
|
|
502
954
|
dataType: args.structured?.dataType ?? "reason-output",
|
|
503
955
|
data: args.output,
|
|
504
|
-
|
|
956
|
+
kind: "final",
|
|
505
957
|
...args.structured?.schemaId ? { schemaId: args.structured.schemaId } : {},
|
|
506
958
|
...args.structured?.schemaVersion ? { schemaVersion: args.structured.schemaVersion } : {},
|
|
507
959
|
...args.id ? { id: args.id } : {},
|
|
508
|
-
|
|
960
|
+
streamId: args.opId
|
|
509
961
|
});
|
|
510
962
|
};
|
|
511
963
|
async function useReason(args) {
|
|
@@ -521,6 +973,12 @@ async function useReason(args) {
|
|
|
521
973
|
);
|
|
522
974
|
const reasonMeta = typeof id === "string" ? { id, opId } : { opId };
|
|
523
975
|
const suppressTextStream = Boolean(args.outputSchema || args.interrupt);
|
|
976
|
+
const setFieldPaths = resolveSetFieldPaths(args.structured);
|
|
977
|
+
const appendFieldPaths = resolveAppendFieldPaths(args.structured);
|
|
978
|
+
const textDeltaFieldPaths = resolveTextDeltaFieldPaths(args.structured);
|
|
979
|
+
const useStructuredIncrementalStreaming = Boolean(
|
|
980
|
+
args.outputSchema && !args.interrupt && (setFieldPaths.length > 0 || appendFieldPaths.length > 0 || textDeltaFieldPaths.length > 0) && args.stream !== false && shouldEmitStructured(args.structured)
|
|
981
|
+
);
|
|
524
982
|
let firstText = "";
|
|
525
983
|
let firstRaw;
|
|
526
984
|
let firstOutput;
|
|
@@ -528,6 +986,9 @@ async function useReason(args) {
|
|
|
528
986
|
let finalText = "";
|
|
529
987
|
let finalRaw;
|
|
530
988
|
let finalOutput;
|
|
989
|
+
const emittedSetValues = /* @__PURE__ */ new Map();
|
|
990
|
+
const emittedAppendCounts = /* @__PURE__ */ new Map();
|
|
991
|
+
const emittedTextValues = /* @__PURE__ */ new Map();
|
|
531
992
|
if (existingCheckpoint) {
|
|
532
993
|
firstText = existingCheckpoint.firstText;
|
|
533
994
|
firstRaw = existingCheckpoint.firstRaw;
|
|
@@ -540,7 +1001,78 @@ async function useReason(args) {
|
|
|
540
1001
|
{
|
|
541
1002
|
...args,
|
|
542
1003
|
emit: suppressTextStream ? false : args.emit,
|
|
543
|
-
stream: suppressTextStream ? false : args.stream
|
|
1004
|
+
stream: useStructuredIncrementalStreaming ? true : suppressTextStream ? false : args.stream,
|
|
1005
|
+
...useStructuredIncrementalStreaming ? {
|
|
1006
|
+
onTextChunk: (delta) => {
|
|
1007
|
+
firstText += delta;
|
|
1008
|
+
finalText = firstText;
|
|
1009
|
+
for (const path of setFieldPaths) {
|
|
1010
|
+
const current = extractCompletedFieldValue({
|
|
1011
|
+
text: firstText,
|
|
1012
|
+
path
|
|
1013
|
+
});
|
|
1014
|
+
if (!current.found || !current.complete) continue;
|
|
1015
|
+
const nextSerialized = JSON.stringify(current.value);
|
|
1016
|
+
if (emittedSetValues.get(path) === nextSerialized) continue;
|
|
1017
|
+
emittedSetValues.set(path, nextSerialized);
|
|
1018
|
+
emitStructuredData({
|
|
1019
|
+
kind: "set",
|
|
1020
|
+
path,
|
|
1021
|
+
value: current.value,
|
|
1022
|
+
dataType: args.structured?.dataType ?? "reason-output",
|
|
1023
|
+
...args.structured?.schemaId ? { schemaId: args.structured.schemaId } : {},
|
|
1024
|
+
...args.structured?.schemaVersion ? { schemaVersion: args.structured.schemaVersion } : {},
|
|
1025
|
+
...id ? { id } : {},
|
|
1026
|
+
streamId: opId
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
for (const path of appendFieldPaths) {
|
|
1030
|
+
const items = extractCompletedArrayItems({
|
|
1031
|
+
text: firstText,
|
|
1032
|
+
path
|
|
1033
|
+
});
|
|
1034
|
+
const emittedAppendCount = emittedAppendCounts.get(path) ?? 0;
|
|
1035
|
+
if (items.length <= emittedAppendCount) continue;
|
|
1036
|
+
const nextItems = items.slice(emittedAppendCount);
|
|
1037
|
+
emittedAppendCounts.set(path, items.length);
|
|
1038
|
+
emitStructuredData({
|
|
1039
|
+
kind: "append",
|
|
1040
|
+
path,
|
|
1041
|
+
items: nextItems,
|
|
1042
|
+
dataType: args.structured?.dataType ?? "reason-output",
|
|
1043
|
+
...args.structured?.schemaId ? { schemaId: args.structured.schemaId } : {},
|
|
1044
|
+
...args.structured?.schemaVersion ? { schemaVersion: args.structured.schemaVersion } : {},
|
|
1045
|
+
...id ? { id } : {},
|
|
1046
|
+
streamId: opId
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
for (const path of textDeltaFieldPaths) {
|
|
1050
|
+
const current = extractStreamingStringValue({
|
|
1051
|
+
text: firstText,
|
|
1052
|
+
path
|
|
1053
|
+
});
|
|
1054
|
+
const emittedTextValue = emittedTextValues.get(path) ?? "";
|
|
1055
|
+
if (!current.found || current.value.length <= emittedTextValue.length || !current.value.startsWith(emittedTextValue)) {
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
const nextDelta = current.value.slice(
|
|
1059
|
+
emittedTextValue.length
|
|
1060
|
+
);
|
|
1061
|
+
emittedTextValues.set(path, current.value);
|
|
1062
|
+
if (nextDelta.length === 0) continue;
|
|
1063
|
+
emitStructuredData({
|
|
1064
|
+
kind: "text-delta",
|
|
1065
|
+
path,
|
|
1066
|
+
delta: nextDelta,
|
|
1067
|
+
dataType: args.structured?.dataType ?? "reason-output",
|
|
1068
|
+
...args.structured?.schemaId ? { schemaId: args.structured.schemaId } : {},
|
|
1069
|
+
...args.structured?.schemaVersion ? { schemaVersion: args.structured.schemaVersion } : {},
|
|
1070
|
+
...id ? { id } : {},
|
|
1071
|
+
streamId: opId
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
} : {}
|
|
544
1076
|
},
|
|
545
1077
|
reasonMeta,
|
|
546
1078
|
args.interrupt ? defaultInterruptFirstPassInput({
|
|
@@ -548,7 +1080,11 @@ async function useReason(args) {
|
|
|
548
1080
|
requestSchema: args.interrupt.requestSchema,
|
|
549
1081
|
...args.outputSchema ? { outputSchema: args.outputSchema } : {}
|
|
550
1082
|
}) : args.outputSchema ? withOutputGuardrails(
|
|
551
|
-
args.input,
|
|
1083
|
+
withStructuredStreamHints(args.input, {
|
|
1084
|
+
...setFieldPaths.length > 0 ? { setFieldPaths } : {},
|
|
1085
|
+
...appendFieldPaths.length > 0 ? { appendFieldPaths } : {},
|
|
1086
|
+
...textDeltaFieldPaths.length > 0 ? { textDeltaFieldPaths } : {}
|
|
1087
|
+
}),
|
|
552
1088
|
args.outputSchema
|
|
553
1089
|
) : void 0
|
|
554
1090
|
);
|
|
@@ -565,14 +1101,6 @@ async function useReason(args) {
|
|
|
565
1101
|
firstInterruptRequest = firstPass.request;
|
|
566
1102
|
firstOutput = firstPass.output;
|
|
567
1103
|
finalOutput = firstPass.output;
|
|
568
|
-
if (firstOutput !== void 0) {
|
|
569
|
-
emitReasonStructuredOutput({
|
|
570
|
-
...id ? { id } : {},
|
|
571
|
-
opId,
|
|
572
|
-
output: firstOutput,
|
|
573
|
-
structured: args.structured
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
1104
|
} else {
|
|
577
1105
|
firstText = first.text;
|
|
578
1106
|
finalText = first.text;
|
|
@@ -582,12 +1110,6 @@ async function useReason(args) {
|
|
|
582
1110
|
resolveOutputCandidate(first.text),
|
|
583
1111
|
"useReason output"
|
|
584
1112
|
);
|
|
585
|
-
emitReasonStructuredOutput({
|
|
586
|
-
...id ? { id } : {},
|
|
587
|
-
opId,
|
|
588
|
-
output: firstOutput,
|
|
589
|
-
structured: args.structured
|
|
590
|
-
});
|
|
591
1113
|
}
|
|
592
1114
|
finalOutput = firstOutput;
|
|
593
1115
|
}
|
|
@@ -662,14 +1184,16 @@ async function useReason(args) {
|
|
|
662
1184
|
resolveOutputCandidate(finalText),
|
|
663
1185
|
"useReason output"
|
|
664
1186
|
);
|
|
665
|
-
emitReasonStructuredOutput({
|
|
666
|
-
...id ? { id } : {},
|
|
667
|
-
opId,
|
|
668
|
-
output: finalOutput,
|
|
669
|
-
structured: args.structured
|
|
670
|
-
});
|
|
671
1187
|
}
|
|
672
1188
|
}
|
|
1189
|
+
if (finalOutput !== void 0) {
|
|
1190
|
+
emitReasonStructuredOutput({
|
|
1191
|
+
...id ? { id } : {},
|
|
1192
|
+
opId,
|
|
1193
|
+
output: finalOutput,
|
|
1194
|
+
structured: args.structured
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
673
1197
|
return {
|
|
674
1198
|
...id ? { id } : {},
|
|
675
1199
|
opId,
|
|
@@ -707,10 +1231,11 @@ function useNodeState(initialValue) {
|
|
|
707
1231
|
};
|
|
708
1232
|
return [getValue(), setValue];
|
|
709
1233
|
}
|
|
710
|
-
function useWorkflowState(key,
|
|
1234
|
+
function useWorkflowState(key, ...rest) {
|
|
711
1235
|
const ctx = getHookContext();
|
|
712
1236
|
const workflowState = ctx.workflowState;
|
|
713
|
-
const hasInitial =
|
|
1237
|
+
const hasInitial = rest.length > 0;
|
|
1238
|
+
const initialValue = rest[0];
|
|
714
1239
|
if (!Object.hasOwn(workflowState, key) && hasInitial) {
|
|
715
1240
|
workflowState[key] = initialValue;
|
|
716
1241
|
ctx.dirty = true;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/context.ts","../src/validation.ts","../src/interrupt.ts","../src/structured.ts","../src/reason/checkpoint.ts","../src/reason/engine.ts","../src/reason-engine.ts","../src/reason/parsing.ts","../src/reason/prompting.ts","../src/reason/use-reason.ts","../src/hooks.ts"],"sourcesContent":["// release-test: 2026-01-22\n/**\n * @kortyx/hooks\n *\n * Internal hook implementations resolved via async-local context.\n */\n\nexport type { HookRuntimeContext } from \"./context\";\nexport { runWithHookContext } from \"./context\";\nexport type {\n UseInterruptArgs,\n UseReasonArgs,\n UseReasonResult,\n UseStructuredDataArgs,\n} from \"./hooks\";\nexport {\n useInterrupt,\n useNodeState,\n useReason,\n useStructuredData,\n useWorkflowState,\n} from \"./hooks\";\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { GraphState, NodeContext } from \"@kortyx/core\";\nimport type { GetProviderFn } from \"@kortyx/providers\";\n\ntype NodeStateStore = {\n byIndex: unknown[];\n byKey: Record<string, unknown>;\n};\n\ntype HookRuntimeState = {\n nodeState?: Record<string, unknown>;\n workflowState?: Record<string, unknown>;\n};\n\nexport type HookRuntimeContext = {\n node: NodeContext;\n state: GraphState;\n getProvider?: GetProviderFn;\n};\n\ntype HookInternalContext = HookRuntimeContext & {\n nodeStateIndex: number;\n reasonCallIndex: number;\n currentNodeState: NodeStateStore;\n workflowState: Record<string, unknown>;\n dirty: boolean;\n};\n\nconst storage = new AsyncLocalStorage<HookInternalContext>();\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nconst normalizeNodeState = (value: unknown): NodeStateStore => {\n if (Array.isArray(value)) {\n return { byIndex: [...value], byKey: {} };\n }\n\n if (isRecord(value)) {\n const byIndex = Array.isArray(value.byIndex) ? [...value.byIndex] : [];\n const byKey = isRecord(value.byKey) ? { ...value.byKey } : {};\n return { byIndex, byKey };\n }\n\n return { byIndex: [], byKey: {} };\n};\n\nconst cloneWorkflowState = (value: unknown): Record<string, unknown> =>\n isRecord(value) ? { ...value } : {};\n\nconst getHookRuntimeState = (state: GraphState): HookRuntimeState => {\n const runtime = (state.runtime ?? {}) as Record<string, unknown>;\n const internal = isRecord(runtime.__kortyx) ? runtime.__kortyx : undefined;\n const result: HookRuntimeState = {};\n if (isRecord(internal?.nodeState)) result.nodeState = internal?.nodeState;\n if (isRecord(internal?.workflowState)) {\n result.workflowState = internal?.workflowState;\n }\n return result;\n};\n\nconst createInternalContext = (\n ctx: HookRuntimeContext,\n): HookInternalContext => {\n const hookRuntimeState = getHookRuntimeState(ctx.state);\n const nodeId = ctx.node.graph.node;\n const storedNodeId =\n typeof (hookRuntimeState.nodeState as any)?.nodeId === \"string\"\n ? String((hookRuntimeState.nodeState as any)?.nodeId)\n : \"\";\n const storedState = (hookRuntimeState.nodeState as any)?.state;\n const currentNodeState =\n storedNodeId && storedNodeId === nodeId\n ? normalizeNodeState(storedState)\n : { byIndex: [], byKey: {} };\n\n return {\n ...ctx,\n nodeStateIndex: 0,\n reasonCallIndex: 0,\n currentNodeState,\n workflowState: cloneWorkflowState(hookRuntimeState.workflowState),\n dirty: false,\n };\n};\n\nconst buildRuntimeStateUpdates = (ctx: HookInternalContext) => {\n if (!ctx.dirty) return null;\n return {\n __kortyx: {\n nodeState: {\n nodeId: ctx.node.graph.node,\n state: ctx.currentNodeState,\n },\n workflowState: ctx.workflowState,\n },\n } as Record<string, unknown>;\n};\n\nexport async function runWithHookContext<T>(\n ctx: HookRuntimeContext,\n fn: () => Promise<T>,\n): Promise<{ result: T; runtimeUpdates: Record<string, unknown> | null }> {\n const internal = createInternalContext(ctx);\n try {\n const result = await storage.run(internal, fn);\n return { result, runtimeUpdates: buildRuntimeStateUpdates(internal) };\n } catch (err) {\n const runtimeUpdates = buildRuntimeStateUpdates(internal);\n if (runtimeUpdates) {\n const currentRuntime = isRecord(internal.state.runtime)\n ? (internal.state.runtime as Record<string, unknown>)\n : {};\n internal.state.runtime = {\n ...currentRuntime,\n ...runtimeUpdates,\n } as unknown as GraphState[\"runtime\"];\n if (err && typeof err === \"object\") {\n (err as any).__kortyxHookStatePatch = runtimeUpdates;\n }\n }\n throw err;\n }\n}\n\nexport function getHookContext(): HookInternalContext {\n const ctx = storage.getStore();\n if (!ctx) {\n throw new Error(\"Hooks can only be used while a node is executing.\");\n }\n return ctx;\n}\n","import type { SchemaLike } from \"./types\";\n\nexport const parseWithSchema = <T>(\n schema: SchemaLike<T> | undefined,\n value: unknown,\n label: string,\n): T => {\n if (!schema) return value as T;\n\n const parsed = schema.safeParse(value);\n if (parsed.success) return parsed.data;\n\n const parsedError =\n \"error\" in parsed && parsed.error ? parsed.error : undefined;\n const reason =\n typeof parsedError?.message === \"string\" && parsedError.message.length > 0\n ? parsedError.message\n : \"invalid payload\";\n throw new Error(`${label} validation failed: ${reason}`);\n};\n","import type { InterruptInput, InterruptResult } from \"@kortyx/core\";\nimport { getHookContext } from \"./context\";\nimport type { UseInterruptArgs } from \"./types\";\nimport { parseWithSchema } from \"./validation\";\n\nexport const awaitInterruptInternal = <\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(\n args: UseInterruptArgs<TRequest, TResponse>,\n): Promise<TResponse> => {\n const ctx = getHookContext();\n\n const request = parseWithSchema(\n args.requestSchema,\n args.request,\n \"useInterrupt request\",\n );\n\n const enrichedRequest = {\n ...request,\n ...(typeof args.schemaId === \"string\" && args.schemaId.length > 0\n ? { schemaId: args.schemaId }\n : {}),\n ...(typeof args.schemaVersion === \"string\" && args.schemaVersion.length > 0\n ? { schemaVersion: args.schemaVersion }\n : {}),\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n ...(args.meta && typeof args.meta === \"object\" && !Array.isArray(args.meta)\n ? { meta: args.meta }\n : {}),\n } as InterruptInput;\n\n const raw = ctx.node.awaitInterrupt(enrichedRequest);\n const response = parseWithSchema(\n args.responseSchema,\n raw,\n \"useInterrupt response\",\n );\n\n return Promise.resolve(response);\n};\n","import { getHookContext } from \"./context\";\nimport type {\n StructuredDataMode,\n UseReasonStructuredConfig,\n UseStructuredDataArgs,\n} from \"./types\";\nimport { parseWithSchema } from \"./validation\";\n\nexport const emitStructuredData = <TData = unknown>(\n args: UseStructuredDataArgs<TData>,\n): void => {\n const ctx = getHookContext();\n const validated = parseWithSchema(\n args.dataSchema,\n args.data,\n \"useStructuredData data\",\n );\n\n ctx.node.emit(\"structured_data\", {\n node: ctx.node.graph.node,\n ...(typeof args.dataType === \"string\" && args.dataType.length > 0\n ? { dataType: args.dataType }\n : {}),\n ...(typeof args.mode === \"string\" ? { mode: args.mode } : {}),\n ...(typeof args.schemaId === \"string\" && args.schemaId.length > 0\n ? { schemaId: args.schemaId }\n : {}),\n ...(typeof args.schemaVersion === \"string\" && args.schemaVersion.length > 0\n ? { schemaVersion: args.schemaVersion }\n : {}),\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n ...(typeof args.opId === \"string\" && args.opId.length > 0\n ? { opId: args.opId }\n : {}),\n data: validated,\n });\n};\n\nexport const shouldEmitStructured = (\n cfg: UseReasonStructuredConfig | undefined,\n): boolean => (cfg?.stream ?? \"patch\") !== \"off\";\n\nexport const resolveStructuredMode = (\n cfg: UseReasonStructuredConfig | undefined,\n): StructuredDataMode => {\n const mode = cfg?.stream ?? \"patch\";\n if (mode === \"snapshot\") return \"snapshot\";\n if (mode === \"patch\") return \"patch\";\n return \"final\";\n};\n","import type { InterruptInput } from \"@kortyx/core\";\n\nexport type ReasonInterruptCheckpoint = {\n status: \"awaiting_interrupt\";\n request: InterruptInput;\n firstText: string;\n firstRaw?: unknown;\n firstOutput?: unknown;\n};\n\nexport const resolveReasonCheckpointKey = (args: {\n id?: string;\n autoIndex: number;\n}): string =>\n typeof args.id === \"string\" && args.id.length > 0\n ? `__useReason:${args.id}`\n : `__useReason:auto:${args.autoIndex}`;\n\nexport const readReasonCheckpoint = (\n raw: unknown,\n): ReasonInterruptCheckpoint | undefined => {\n if (!raw || typeof raw !== \"object\") return undefined;\n const value = raw as Record<string, unknown>;\n if (value.status !== \"awaiting_interrupt\") return undefined;\n if (typeof value.firstText !== \"string\") return undefined;\n if (!value.request || typeof value.request !== \"object\") return undefined;\n return {\n status: \"awaiting_interrupt\",\n request: value.request as InterruptInput,\n firstText: value.firstText,\n ...(Object.hasOwn(value, \"firstRaw\") ? { firstRaw: value.firstRaw } : {}),\n ...(Object.hasOwn(value, \"firstOutput\")\n ? { firstOutput: value.firstOutput }\n : {}),\n };\n};\n\nexport const resolveHookStatePatch = (args: {\n nodeId: string;\n currentNodeState: unknown;\n workflowState: Record<string, unknown>;\n}): Record<string, unknown> => ({\n __kortyx: {\n nodeState: {\n nodeId: args.nodeId,\n state: args.currentNodeState,\n },\n workflowState: args.workflowState,\n },\n});\n","import { randomUUID } from \"node:crypto\";\nimport type { ProviderModelRef } from \"@kortyx/providers\";\nimport { getHookContext } from \"../context\";\nimport type { RunReasonEngineResult } from \"../reason-engine\";\nimport { runReasonEngine } from \"../reason-engine\";\n\nexport type ReasonEngineInput = {\n model: ProviderModelRef;\n input: string;\n system?: string | undefined;\n temperature?: number | undefined;\n emit?: boolean | undefined;\n stream?: boolean | undefined;\n};\n\nexport const createRuntimeId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nexport async function reasonEngine(\n args: ReasonEngineInput,\n meta: { id?: string; opId: string },\n inputOverride?: string,\n): Promise<RunReasonEngineResult> {\n const ctx = getHookContext();\n const getProvider = ctx.getProvider;\n if (!getProvider) {\n throw new Error(\"useReason requires a provider factory in runtime config.\");\n }\n\n return runReasonEngine({\n getProvider,\n model: args.model,\n input: inputOverride ?? args.input,\n system: args.system,\n temperature: args.temperature,\n defaultTemperature: ctx.node.config?.model?.temperature,\n stream: args.stream,\n emit: args.emit,\n nodeId: ctx.node.graph.node,\n emitEvent: ctx.node.emit,\n id: meta.id,\n opId: meta.opId,\n });\n}\n","import { randomUUID } from \"node:crypto\";\nimport type {\n GetProviderFn,\n KortyxPromptMessage,\n KortyxStreamChunk,\n ProviderModelRef,\n} from \"@kortyx/providers\";\n\nexport interface RunReasonEngineArgs {\n getProvider: GetProviderFn;\n model: ProviderModelRef;\n input: string;\n system?: string | undefined;\n temperature?: number | undefined;\n defaultTemperature?: number | undefined;\n stream?: boolean | undefined;\n emit?: boolean | undefined;\n nodeId?: string | undefined;\n emitEvent?: ((event: string, payload: unknown) => void) | undefined;\n id?: string | undefined;\n opId?: string | undefined;\n segmentId?: string | undefined;\n}\n\nexport interface RunReasonEngineResult {\n text: string;\n raw?: unknown;\n}\n\nconst chunkToText = (chunk: KortyxStreamChunk | string): string => {\n if (typeof chunk === \"string\") return chunk;\n if (typeof chunk.text === \"string\") return chunk.text;\n if (typeof chunk.content === \"string\") return chunk.content;\n return \"\";\n};\n\nconst createRuntimeId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nconst emitNodeEvent = (\n emitEvent: RunReasonEngineArgs[\"emitEvent\"],\n nodeId: string | undefined,\n event: string,\n payload: Record<string, unknown>,\n): void => {\n if (!emitEvent) return;\n emitEvent(event, {\n ...payload,\n ...(typeof nodeId === \"string\" && nodeId.length > 0\n ? { node: nodeId }\n : {}),\n });\n};\n\nexport async function runReasonEngine(\n args: RunReasonEngineArgs,\n): Promise<RunReasonEngineResult> {\n const stream = args.stream ?? args.model.options?.streaming ?? true;\n const emit = args.emit ?? true;\n const temperature =\n args.temperature ??\n args.model.options?.temperature ??\n args.defaultTemperature;\n\n const model = args.getProvider(args.model.providerId, args.model.modelId, {\n ...(temperature !== undefined ? { temperature } : {}),\n streaming: stream,\n });\n\n const messages: KortyxPromptMessage[] = [];\n if (typeof args.system === \"string\" && args.system.length > 0) {\n messages.push({ role: \"system\", content: args.system });\n }\n messages.push({ role: \"user\", content: String(args.input ?? \"\") });\n\n const opId =\n typeof args.opId === \"string\" && args.opId.length > 0\n ? args.opId\n : createRuntimeId();\n const segmentId =\n typeof args.segmentId === \"string\" && args.segmentId.length > 0\n ? args.segmentId\n : createRuntimeId();\n\n const commonMeta: Record<string, unknown> = {\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n opId,\n segmentId,\n };\n\n if (stream) {\n let final = \"\";\n let raw: unknown;\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n }\n\n const response = await model.stream(messages);\n for await (const chunk of response) {\n const text = chunkToText(chunk);\n if (!text) continue;\n final += text;\n if (typeof chunk === \"object\" && chunk && \"raw\" in chunk) {\n raw = (chunk as KortyxStreamChunk).raw;\n }\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: text,\n });\n }\n }\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: final,\n ...(raw !== undefined ? { raw } : {}),\n };\n }\n\n const response = await model.invoke(messages);\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n if (response.content) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: response.content,\n });\n }\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: response.content,\n ...(response.raw !== undefined ? { raw: response.raw } : {}),\n };\n}\n","import type { InterruptInput } from \"@kortyx/core\";\nimport type { SchemaLike } from \"../types\";\nimport { parseWithSchema } from \"../validation\";\n\nconst tryJsonParse = (\n value: string,\n): { ok: true; value: unknown } | { ok: false } => {\n try {\n return { ok: true, value: JSON.parse(value) };\n } catch {\n return { ok: false };\n }\n};\n\nconst extractJsonCodeBlock = (value: string): string | null => {\n const match = value.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n if (!match || typeof match[1] !== \"string\") return null;\n const inner = match[1].trim();\n return inner.length > 0 ? inner : null;\n};\n\nconst tryStringify = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nexport const resolveOutputCandidate = (text: string): unknown => {\n const trimmed = text.trim();\n if (!trimmed) return text;\n\n const direct = tryJsonParse(trimmed);\n if (direct.ok) return direct.value;\n\n const block = extractJsonCodeBlock(trimmed);\n if (block) {\n const parsedBlock = tryJsonParse(block);\n if (parsedBlock.ok) return parsedBlock.value;\n }\n\n return text;\n};\n\nexport const parseInterruptFirstPassResult = <\n TRequest extends InterruptInput = InterruptInput,\n TOutput = unknown,\n>(args: {\n text: string;\n requestSchema: SchemaLike<TRequest>;\n outputSchema?: SchemaLike<TOutput>;\n}): {\n draftText: string;\n request: TRequest;\n output?: TOutput;\n} => {\n const candidate = resolveOutputCandidate(args.text);\n if (!isRecord(candidate)) {\n throw new Error(\n \"useReason first pass with interrupt must return a JSON object.\",\n );\n }\n\n const requestCandidates: unknown[] = [\n candidate.interruptRequest,\n candidate.request,\n candidate.interrupt,\n candidate,\n ];\n const requestPayload = requestCandidates.find(\n (value) => value !== null && value !== undefined,\n );\n\n const request = parseWithSchema(\n args.requestSchema,\n requestPayload,\n \"useReason interrupt.request\",\n );\n\n let output: TOutput | undefined;\n if (args.outputSchema) {\n const outputPayload = Object.hasOwn(candidate, \"output\")\n ? candidate.output\n : candidate;\n output = parseWithSchema(\n args.outputSchema,\n outputPayload,\n \"useReason output\",\n );\n }\n\n const explicitDraft =\n typeof candidate.draftText === \"string\" && candidate.draftText.length > 0\n ? candidate.draftText\n : typeof candidate.text === \"string\" && candidate.text.length > 0\n ? candidate.text\n : undefined;\n\n if (!args.outputSchema && !explicitDraft) {\n throw new Error(\n \"useReason first pass with interrupt requires `draftText` when outputSchema is not provided.\",\n );\n }\n\n const draftText =\n explicitDraft ??\n (output !== undefined ? tryStringify(output) : String(args.text ?? \"\"));\n\n return {\n draftText,\n request,\n ...(output !== undefined ? { output } : {}),\n };\n};\n","import type { InterruptInput } from \"@kortyx/core\";\nimport { toJSONSchema } from \"zod\";\nimport type { SchemaLike } from \"../types\";\n\nconst tryStringify = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n};\n\nconst tryGetSchemaHint = (schema: unknown): string | undefined => {\n try {\n const hint = toJSONSchema(schema as never);\n return JSON.stringify(hint, null, 2);\n } catch {\n return undefined;\n }\n};\n\nconst withSchemaHint = (\n input: string,\n label: string,\n schema: unknown,\n): string => {\n const hint = tryGetSchemaHint(schema);\n if (!hint) return input;\n return `${input}\\n\\n${label}:\\n${hint}`;\n};\n\nexport const defaultInterruptFirstPassInput = (args: {\n input: string;\n requestSchema: SchemaLike<unknown>;\n outputSchema?: SchemaLike<unknown>;\n}): string => {\n const base = args.outputSchema\n ? [\n args.input,\n \"Output rules:\",\n \"- Return JSON only. No markdown fences.\",\n \"- Return an object with keys: output, interruptRequest, draftText.\",\n \"- output must match the expected output JSON schema.\",\n \"- interruptRequest must match the expected interrupt request JSON schema.\",\n \"- interruptRequest must be a non-null object.\",\n \"- draftText should be a concise plain-language summary of output.\",\n \"- If uncertain, still return a valid interruptRequest with safe default options.\",\n ].join(\"\\n\\n\")\n : [\n args.input,\n \"Output rules:\",\n \"- Return JSON only. No markdown fences.\",\n \"- Return an object with keys: draftText, interruptRequest.\",\n \"- draftText should be the current draft answer text.\",\n \"- interruptRequest must match the expected interrupt request JSON schema.\",\n \"- interruptRequest must be a non-null object.\",\n \"- If uncertain, still return a valid interruptRequest with safe default options.\",\n ].join(\"\\n\\n\");\n\n const withInterruptSchema = withSchemaHint(\n base,\n \"Expected interrupt request JSON schema (for `interruptRequest`)\",\n args.requestSchema,\n );\n\n if (!args.outputSchema) return withInterruptSchema;\n const withOutputSchema = withSchemaHint(\n withInterruptSchema,\n \"Expected output JSON schema (for `output`)\",\n args.outputSchema,\n );\n return [\n withOutputSchema,\n \"JSON template:\",\n '{ \"output\": { ... }, \"interruptRequest\": { ... }, \"draftText\": \"...\" }',\n ].join(\"\\n\\n\");\n};\n\nexport const defaultContinuationInput = (args: {\n input: string;\n draftText: string;\n draftOutput?: unknown;\n request: InterruptInput;\n response: unknown;\n}): string =>\n [\n \"You are continuing a paused reasoning task after user input.\",\n \"Update the previous result using the user response and return the final answer only.\",\n \"If the previous output was JSON, return JSON in the same schema.\",\n \"\",\n `Original request:\\n${args.input}`,\n `Draft answer text:\\n${args.draftText}`,\n `Draft output object:\\n${tryStringify(args.draftOutput ?? args.draftText)}`,\n `Interrupt request shown to user:\\n${tryStringify(args.request)}`,\n `User response:\\n${tryStringify(args.response)}`,\n ].join(\"\\n\\n\");\n\nexport const withOutputGuardrails = (\n input: string,\n schema?: SchemaLike<unknown>,\n): string => {\n const base = [\n input,\n \"Output rules:\",\n \"- Return only JSON, no markdown fences.\",\n \"- Ensure the response conforms to the expected output schema.\",\n \"- Do not include explanatory text outside the JSON object.\",\n ].join(\"\\n\\n\");\n return withSchemaHint(base, \"Expected output JSON schema\", schema);\n};\n","import type { InterruptInput, InterruptResult } from \"@kortyx/core\";\nimport { getHookContext } from \"../context\";\nimport { awaitInterruptInternal } from \"../interrupt\";\nimport {\n emitStructuredData,\n resolveStructuredMode,\n shouldEmitStructured,\n} from \"../structured\";\nimport type { SchemaLike, UseReasonArgs, UseReasonResult } from \"../types\";\nimport { parseWithSchema } from \"../validation\";\nimport {\n type ReasonInterruptCheckpoint,\n readReasonCheckpoint,\n resolveHookStatePatch,\n resolveReasonCheckpointKey,\n} from \"./checkpoint\";\nimport { createRuntimeId, reasonEngine } from \"./engine\";\nimport {\n parseInterruptFirstPassResult,\n resolveOutputCandidate,\n} from \"./parsing\";\nimport {\n defaultContinuationInput,\n defaultInterruptFirstPassInput,\n withOutputGuardrails,\n} from \"./prompting\";\n\nconst emitReasonStructuredOutput = <TOutput>(args: {\n id?: string;\n opId: string;\n output: TOutput;\n structured: UseReasonArgs<TOutput>[\"structured\"];\n}): void => {\n if (!shouldEmitStructured(args.structured)) return;\n\n emitStructuredData<TOutput>({\n dataType: args.structured?.dataType ?? \"reason-output\",\n data: args.output,\n mode: resolveStructuredMode(args.structured),\n ...(args.structured?.schemaId\n ? { schemaId: args.structured.schemaId }\n : {}),\n ...(args.structured?.schemaVersion\n ? { schemaVersion: args.structured.schemaVersion }\n : {}),\n ...(args.id ? { id: args.id } : {}),\n opId: args.opId,\n });\n};\n\nexport async function useReason<\n TOutput = unknown,\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(\n args: UseReasonArgs<TOutput, TRequest, TResponse>,\n): Promise<UseReasonResult<TOutput, TResponse>> {\n const ctx = getHookContext();\n const id =\n typeof args.id === \"string\" && args.id.length > 0 ? args.id : undefined;\n const opId = createRuntimeId();\n const checkpointKey = resolveReasonCheckpointKey({\n ...(id ? { id } : {}),\n autoIndex: ctx.reasonCallIndex++,\n });\n const existingCheckpoint = readReasonCheckpoint(\n ctx.currentNodeState.byKey[checkpointKey],\n );\n\n const reasonMeta =\n typeof id === \"string\" ? ({ id, opId } as const) : ({ opId } as const);\n const suppressTextStream = Boolean(args.outputSchema || args.interrupt);\n\n let firstText = \"\";\n let firstRaw: unknown;\n let firstOutput: TOutput | undefined;\n let firstInterruptRequest: TRequest | undefined;\n\n let finalText = \"\";\n let finalRaw: unknown;\n let finalOutput: TOutput | undefined;\n\n if (existingCheckpoint) {\n firstText = existingCheckpoint.firstText;\n firstRaw = existingCheckpoint.firstRaw;\n firstOutput = existingCheckpoint.firstOutput as TOutput | undefined;\n finalText = firstText;\n finalRaw = firstRaw;\n finalOutput = firstOutput;\n } else {\n const first = await reasonEngine(\n {\n ...args,\n emit: suppressTextStream ? false : args.emit,\n stream: suppressTextStream ? false : args.stream,\n },\n reasonMeta,\n args.interrupt\n ? defaultInterruptFirstPassInput({\n input: args.input,\n requestSchema: args.interrupt.requestSchema,\n ...(args.outputSchema\n ? { outputSchema: args.outputSchema as SchemaLike<unknown> }\n : {}),\n })\n : args.outputSchema\n ? withOutputGuardrails(\n args.input,\n args.outputSchema as SchemaLike<unknown>,\n )\n : undefined,\n );\n firstRaw = first.raw;\n finalRaw = first.raw;\n\n if (args.interrupt) {\n const firstPass = parseInterruptFirstPassResult<TRequest, TOutput>({\n text: first.text,\n requestSchema: args.interrupt.requestSchema,\n ...(args.outputSchema\n ? { outputSchema: args.outputSchema as SchemaLike<TOutput> }\n : {}),\n });\n firstText = firstPass.draftText;\n finalText = firstPass.draftText;\n firstInterruptRequest = firstPass.request;\n firstOutput = firstPass.output;\n finalOutput = firstPass.output;\n\n if (firstOutput !== undefined) {\n emitReasonStructuredOutput<TOutput>({\n ...(id ? { id } : {}),\n opId,\n output: firstOutput,\n structured: args.structured,\n });\n }\n } else {\n firstText = first.text;\n finalText = first.text;\n if (args.outputSchema) {\n firstOutput = parseWithSchema(\n args.outputSchema,\n resolveOutputCandidate(first.text),\n \"useReason output\",\n );\n\n emitReasonStructuredOutput<TOutput>({\n ...(id ? { id } : {}),\n opId,\n output: firstOutput,\n structured: args.structured,\n });\n }\n finalOutput = firstOutput;\n }\n }\n\n let interruptResponse: TResponse | undefined;\n\n if (args.interrupt) {\n const requestSchema = args.interrupt.requestSchema;\n\n const interruptRequest = existingCheckpoint\n ? parseWithSchema(\n requestSchema,\n existingCheckpoint.request,\n \"useReason interrupt.request\",\n )\n : firstInterruptRequest;\n\n if (!interruptRequest) {\n throw new Error(\n \"useReason interrupt request is missing; first pass did not produce a valid interrupt payload.\",\n );\n }\n\n if (!existingCheckpoint) {\n ctx.currentNodeState.byKey[checkpointKey] = {\n status: \"awaiting_interrupt\",\n request: interruptRequest,\n firstText,\n ...(firstRaw !== undefined ? { firstRaw } : {}),\n ...(firstOutput !== undefined ? { firstOutput } : {}),\n } satisfies ReasonInterruptCheckpoint;\n ctx.dirty = true;\n }\n\n const resumeStatePatch = resolveHookStatePatch({\n nodeId: ctx.node.graph.node,\n currentNodeState: ctx.currentNodeState,\n workflowState: ctx.workflowState,\n });\n\n interruptResponse = await awaitInterruptInternal<TRequest, TResponse>({\n request: interruptRequest,\n requestSchema,\n responseSchema: args.interrupt.responseSchema,\n ...(args.interrupt.schemaId ? { schemaId: args.interrupt.schemaId } : {}),\n ...(args.interrupt.schemaVersion\n ? { schemaVersion: args.interrupt.schemaVersion }\n : {}),\n ...(id ? { id } : {}),\n meta: {\n __kortyxResumeStatePatch: resumeStatePatch,\n },\n });\n\n if (Object.hasOwn(ctx.currentNodeState.byKey, checkpointKey)) {\n delete ctx.currentNodeState.byKey[checkpointKey];\n ctx.dirty = true;\n }\n\n const continuationInput = defaultContinuationInput({\n input: args.input,\n draftText: firstText,\n ...(firstOutput !== undefined ? { draftOutput: firstOutput } : {}),\n request: interruptRequest,\n response: interruptResponse,\n });\n\n const second = await reasonEngine(\n {\n ...args,\n emit: suppressTextStream ? false : args.emit,\n stream: suppressTextStream ? false : args.stream,\n },\n reasonMeta,\n args.outputSchema\n ? withOutputGuardrails(\n continuationInput,\n args.outputSchema as SchemaLike<unknown>,\n )\n : continuationInput,\n );\n finalText = second.text;\n finalRaw = second.raw;\n\n if (args.outputSchema) {\n finalOutput = parseWithSchema(\n args.outputSchema,\n resolveOutputCandidate(finalText),\n \"useReason output\",\n );\n\n emitReasonStructuredOutput<TOutput>({\n ...(id ? { id } : {}),\n opId,\n output: finalOutput,\n structured: args.structured,\n });\n }\n }\n\n return {\n ...(id ? { id } : {}),\n opId,\n text: finalText,\n ...(finalRaw !== undefined ? { raw: finalRaw } : {}),\n ...(finalOutput !== undefined ? { output: finalOutput } : {}),\n ...(interruptResponse !== undefined ? { interruptResponse } : {}),\n };\n}\n","import type { InterruptInput, InterruptResult } from \"@kortyx/core\";\nimport { getHookContext } from \"./context\";\nimport { awaitInterruptInternal } from \"./interrupt\";\nimport { useReason as useReasonInternal } from \"./reason/use-reason\";\nimport { emitStructuredData } from \"./structured\";\nimport type {\n UseInterruptArgs,\n UseReasonArgs,\n UseReasonResult,\n UseStructuredDataArgs,\n} from \"./types\";\n\nexport type {\n SchemaLike,\n StructuredDataMode,\n UseInterruptArgs,\n UseReasonArgs,\n UseReasonInterruptConfig,\n UseReasonResult,\n UseReasonStructuredConfig,\n UseReasonStructuredStreamMode,\n UseStructuredDataArgs,\n} from \"./types\";\n\ntype StateSetter<T> = (next: T | ((prev: T) => T)) => void;\n\nexport function useStructuredData<TData = unknown>(\n args: UseStructuredDataArgs<TData>,\n): void {\n emitStructuredData(args);\n}\n\nexport function useReason<\n TOutput = unknown,\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(\n args: UseReasonArgs<TOutput, TRequest, TResponse>,\n): Promise<UseReasonResult<TOutput, TResponse>> {\n return useReasonInternal(args);\n}\n\nexport function useInterrupt<\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(args: UseInterruptArgs<TRequest, TResponse>): Promise<TResponse> {\n return awaitInterruptInternal(args);\n}\n\nexport function useNodeState<T>(initialValue: T): [T, StateSetter<T>] {\n const ctx = getHookContext();\n const nodeState = ctx.currentNodeState;\n\n const index = ctx.nodeStateIndex++;\n if (index >= nodeState.byIndex.length) {\n nodeState.byIndex[index] = initialValue as T;\n ctx.dirty = true;\n }\n\n const getValue = () => nodeState.byIndex[index] as T;\n const setValue: StateSetter<T> = (next) => {\n const prev = getValue();\n const resolved =\n typeof next === \"function\" ? (next as (p: T) => T)(prev) : next;\n nodeState.byIndex[index] = resolved;\n ctx.dirty = true;\n };\n\n return [getValue(), setValue];\n}\n\nexport function useWorkflowState<T>(\n key: string,\n initialValue?: T,\n): [T, StateSetter<T>] {\n const ctx = getHookContext();\n const workflowState = ctx.workflowState;\n const hasInitial = arguments.length > 1;\n\n if (!Object.hasOwn(workflowState, key) && hasInitial) {\n workflowState[key] = initialValue as T;\n ctx.dirty = true;\n }\n\n const getValue = () => workflowState[key] as T;\n const setValue: StateSetter<T> = (next) => {\n const prev = getValue();\n const resolved =\n typeof next === \"function\" ? (next as (p: T) => T)(prev) : next;\n workflowState[key] = resolved;\n ctx.dirty = true;\n };\n\n return [getValue(), setValue];\n}\n"],"mappings":"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","names":["useReason","import_node_crypto","response","createRuntimeId","isRecord","tryStringify","createRuntimeId","useReason"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context.ts","../src/validation.ts","../src/interrupt.ts","../src/structured.ts","../src/reason/checkpoint.ts","../src/reason/engine.ts","../src/reason-engine.ts","../src/reason/parsing.ts","../src/reason/prompting.ts","../src/reason/structured-stream.ts","../src/reason/use-reason.ts","../src/hooks.ts"],"sourcesContent":["// release-test: 2026-01-22\n/**\n * @kortyx/hooks\n *\n * Internal hook implementations resolved via async-local context.\n */\n\nexport type { HookRuntimeContext } from \"./context\";\nexport { runWithHookContext } from \"./context\";\nexport type {\n UseInterruptArgs,\n UseReasonArgs,\n UseReasonResult,\n UseStructuredDataArgs,\n} from \"./hooks\";\nexport {\n useInterrupt,\n useNodeState,\n useReason,\n useStructuredData,\n useWorkflowState,\n} from \"./hooks\";\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { GraphState, NodeContext } from \"@kortyx/core\";\nimport type { GetProviderFn } from \"@kortyx/providers\";\n\ntype NodeStateStore = {\n byIndex: unknown[];\n byKey: Record<string, unknown>;\n};\n\ntype HookRuntimeState = {\n nodeState?: Record<string, unknown>;\n workflowState?: Record<string, unknown>;\n};\n\ntype StoredNodeStateEnvelope = {\n nodeId?: unknown;\n state?: unknown;\n};\n\ntype HookStatePatchedError = {\n __kortyxHookStatePatch?: Record<string, unknown>;\n};\n\nexport type HookRuntimeContext = {\n node: NodeContext;\n state: GraphState;\n getProvider?: GetProviderFn;\n};\n\ntype HookInternalContext = HookRuntimeContext & {\n nodeStateIndex: number;\n reasonCallIndex: number;\n currentNodeState: NodeStateStore;\n workflowState: Record<string, unknown>;\n dirty: boolean;\n};\n\nconst storage = new AsyncLocalStorage<HookInternalContext>();\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nconst normalizeNodeState = (value: unknown): NodeStateStore => {\n if (Array.isArray(value)) {\n return { byIndex: [...value], byKey: {} };\n }\n\n if (isRecord(value)) {\n const byIndex = Array.isArray(value.byIndex) ? [...value.byIndex] : [];\n const byKey = isRecord(value.byKey) ? { ...value.byKey } : {};\n return { byIndex, byKey };\n }\n\n return { byIndex: [], byKey: {} };\n};\n\nconst cloneWorkflowState = (value: unknown): Record<string, unknown> =>\n isRecord(value) ? { ...value } : {};\n\nconst getHookRuntimeState = (state: GraphState): HookRuntimeState => {\n const runtime = (state.runtime ?? {}) as Record<string, unknown>;\n const internal = isRecord(runtime.__kortyx) ? runtime.__kortyx : undefined;\n const result: HookRuntimeState = {};\n if (isRecord(internal?.nodeState)) result.nodeState = internal?.nodeState;\n if (isRecord(internal?.workflowState)) {\n result.workflowState = internal?.workflowState;\n }\n return result;\n};\n\nconst createInternalContext = (\n ctx: HookRuntimeContext,\n): HookInternalContext => {\n const hookRuntimeState = getHookRuntimeState(ctx.state);\n const nodeId = ctx.node.graph.node;\n const storedNodeState = isRecord(hookRuntimeState.nodeState)\n ? (hookRuntimeState.nodeState as StoredNodeStateEnvelope)\n : undefined;\n const storedNodeId =\n typeof storedNodeState?.nodeId === \"string\"\n ? String(storedNodeState.nodeId)\n : \"\";\n const storedState = storedNodeState?.state;\n const currentNodeState =\n storedNodeId && storedNodeId === nodeId\n ? normalizeNodeState(storedState)\n : { byIndex: [], byKey: {} };\n\n return {\n ...ctx,\n nodeStateIndex: 0,\n reasonCallIndex: 0,\n currentNodeState,\n workflowState: cloneWorkflowState(hookRuntimeState.workflowState),\n dirty: false,\n };\n};\n\nconst buildRuntimeStateUpdates = (ctx: HookInternalContext) => {\n if (!ctx.dirty) return null;\n return {\n __kortyx: {\n nodeState: {\n nodeId: ctx.node.graph.node,\n state: ctx.currentNodeState,\n },\n workflowState: ctx.workflowState,\n },\n } as Record<string, unknown>;\n};\n\nexport async function runWithHookContext<T>(\n ctx: HookRuntimeContext,\n fn: () => Promise<T>,\n): Promise<{ result: T; runtimeUpdates: Record<string, unknown> | null }> {\n const internal = createInternalContext(ctx);\n try {\n const result = await storage.run(internal, fn);\n return { result, runtimeUpdates: buildRuntimeStateUpdates(internal) };\n } catch (err) {\n const runtimeUpdates = buildRuntimeStateUpdates(internal);\n if (runtimeUpdates) {\n const currentRuntime = isRecord(internal.state.runtime)\n ? (internal.state.runtime as Record<string, unknown>)\n : {};\n internal.state.runtime = {\n ...currentRuntime,\n ...runtimeUpdates,\n } as unknown as GraphState[\"runtime\"];\n if (err && typeof err === \"object\") {\n (err as HookStatePatchedError).__kortyxHookStatePatch = runtimeUpdates;\n }\n }\n throw err;\n }\n}\n\nexport function getHookContext(): HookInternalContext {\n const ctx = storage.getStore();\n if (!ctx) {\n throw new Error(\"Hooks can only be used while a node is executing.\");\n }\n return ctx;\n}\n","import type { SchemaLike } from \"./types\";\n\nexport const parseWithSchema = <T>(\n schema: SchemaLike<T> | undefined,\n value: unknown,\n label: string,\n): T => {\n if (!schema) return value as T;\n\n const parsed = schema.safeParse(value);\n if (parsed.success) return parsed.data;\n\n const parsedError =\n \"error\" in parsed && parsed.error ? parsed.error : undefined;\n const reason =\n typeof parsedError?.message === \"string\" && parsedError.message.length > 0\n ? parsedError.message\n : \"invalid payload\";\n throw new Error(`${label} validation failed: ${reason}`);\n};\n","import type { InterruptInput, InterruptResult } from \"@kortyx/core\";\nimport { getHookContext } from \"./context\";\nimport type { UseInterruptArgs } from \"./types\";\nimport { parseWithSchema } from \"./validation\";\n\nexport const awaitInterruptInternal = <\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(\n args: UseInterruptArgs<TRequest, TResponse>,\n): Promise<TResponse> => {\n const ctx = getHookContext();\n\n const request = parseWithSchema(\n args.requestSchema,\n args.request,\n \"useInterrupt request\",\n );\n\n const enrichedRequest = {\n ...request,\n ...(typeof args.schemaId === \"string\" && args.schemaId.length > 0\n ? { schemaId: args.schemaId }\n : {}),\n ...(typeof args.schemaVersion === \"string\" && args.schemaVersion.length > 0\n ? { schemaVersion: args.schemaVersion }\n : {}),\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n ...(args.meta && typeof args.meta === \"object\" && !Array.isArray(args.meta)\n ? { meta: args.meta }\n : {}),\n } as InterruptInput;\n\n const raw = ctx.node.awaitInterrupt(enrichedRequest);\n const response = parseWithSchema(\n args.responseSchema,\n raw,\n \"useInterrupt response\",\n );\n\n return Promise.resolve(response);\n};\n","import { randomUUID } from \"node:crypto\";\nimport { getHookContext } from \"./context\";\nimport type { UseReasonStructuredConfig, UseStructuredDataArgs } from \"./types\";\nimport { parseWithSchema } from \"./validation\";\n\nconst createStructuredStreamId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nexport const emitStructuredData = <TData = unknown>(\n args: UseStructuredDataArgs<TData>,\n): void => {\n const ctx = getHookContext();\n const streamId =\n typeof args.streamId === \"string\" && args.streamId.length > 0\n ? args.streamId\n : createStructuredStreamId();\n const dataType =\n typeof args.dataType === \"string\" && args.dataType.length > 0\n ? args.dataType\n : \"generic\";\n\n const base = {\n node: ctx.node.graph.node,\n streamId,\n dataType,\n ...(typeof args.schemaId === \"string\" && args.schemaId.length > 0\n ? { schemaId: args.schemaId }\n : {}),\n ...(typeof args.schemaVersion === \"string\" && args.schemaVersion.length > 0\n ? { schemaVersion: args.schemaVersion }\n : {}),\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n };\n\n if (args.kind === \"set\") {\n const value = parseWithSchema(\n args.valueSchema,\n args.value,\n \"useStructuredData value\",\n );\n ctx.node.emit(\"structured_data\", {\n ...base,\n kind: \"set\",\n path: args.path,\n value,\n });\n return;\n }\n\n if (args.kind === \"append\") {\n const items = args.items.map((item) =>\n parseWithSchema(args.itemSchema, item, \"useStructuredData append item\"),\n );\n ctx.node.emit(\"structured_data\", {\n ...base,\n kind: \"append\",\n path: args.path,\n items,\n });\n return;\n }\n\n if (args.kind === \"text-delta\") {\n ctx.node.emit(\"structured_data\", {\n ...base,\n kind: \"text-delta\",\n path: args.path,\n delta: args.delta,\n });\n return;\n }\n\n const validated = parseWithSchema(\n args.dataSchema,\n args.data,\n \"useStructuredData data\",\n );\n\n ctx.node.emit(\"structured_data\", {\n ...base,\n kind: \"final\",\n data: validated,\n });\n};\n\nexport const shouldEmitStructured = (\n cfg: UseReasonStructuredConfig | undefined,\n): boolean => Boolean(cfg) && (cfg?.stream ?? true);\n","import type { InterruptInput } from \"@kortyx/core\";\n\nexport type ReasonInterruptCheckpoint = {\n status: \"awaiting_interrupt\";\n request: InterruptInput;\n firstText: string;\n firstRaw?: unknown;\n firstOutput?: unknown;\n};\n\nexport const resolveReasonCheckpointKey = (args: {\n id?: string;\n autoIndex: number;\n}): string =>\n typeof args.id === \"string\" && args.id.length > 0\n ? `__useReason:${args.id}`\n : `__useReason:auto:${args.autoIndex}`;\n\nexport const readReasonCheckpoint = (\n raw: unknown,\n): ReasonInterruptCheckpoint | undefined => {\n if (!raw || typeof raw !== \"object\") return undefined;\n const value = raw as Record<string, unknown>;\n if (value.status !== \"awaiting_interrupt\") return undefined;\n if (typeof value.firstText !== \"string\") return undefined;\n if (!value.request || typeof value.request !== \"object\") return undefined;\n return {\n status: \"awaiting_interrupt\",\n request: value.request as InterruptInput,\n firstText: value.firstText,\n ...(Object.hasOwn(value, \"firstRaw\") ? { firstRaw: value.firstRaw } : {}),\n ...(Object.hasOwn(value, \"firstOutput\")\n ? { firstOutput: value.firstOutput }\n : {}),\n };\n};\n\nexport const resolveHookStatePatch = (args: {\n nodeId: string;\n currentNodeState: unknown;\n workflowState: Record<string, unknown>;\n}): Record<string, unknown> => ({\n __kortyx: {\n nodeState: {\n nodeId: args.nodeId,\n state: args.currentNodeState,\n },\n workflowState: args.workflowState,\n },\n});\n","import { randomUUID } from \"node:crypto\";\nimport type { ProviderModelRef } from \"@kortyx/providers\";\nimport { getHookContext } from \"../context\";\nimport type { RunReasonEngineResult } from \"../reason-engine\";\nimport { runReasonEngine } from \"../reason-engine\";\n\nexport type ReasonEngineInput = {\n model: ProviderModelRef;\n input: string;\n system?: string | undefined;\n temperature?: number | undefined;\n emit?: boolean | undefined;\n stream?: boolean | undefined;\n onTextChunk?: ((text: string) => void) | undefined;\n};\n\nexport const createRuntimeId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nexport async function reasonEngine(\n args: ReasonEngineInput,\n meta: { id?: string; opId: string },\n inputOverride?: string,\n): Promise<RunReasonEngineResult> {\n const ctx = getHookContext();\n const getProvider = ctx.getProvider;\n if (!getProvider) {\n throw new Error(\"useReason requires a provider factory in runtime config.\");\n }\n\n return runReasonEngine({\n getProvider,\n model: args.model,\n input: inputOverride ?? args.input,\n system: args.system,\n temperature: args.temperature,\n defaultTemperature: ctx.node.config?.model?.temperature,\n stream: args.stream,\n emit: args.emit,\n onTextChunk: args.onTextChunk,\n nodeId: ctx.node.graph.node,\n emitEvent: ctx.node.emit,\n id: meta.id,\n opId: meta.opId,\n });\n}\n","import { randomUUID } from \"node:crypto\";\nimport type {\n GetProviderFn,\n KortyxPromptMessage,\n KortyxStreamChunk,\n ProviderModelRef,\n} from \"@kortyx/providers\";\n\nexport interface RunReasonEngineArgs {\n getProvider: GetProviderFn;\n model: ProviderModelRef;\n input: string;\n system?: string | undefined;\n temperature?: number | undefined;\n defaultTemperature?: number | undefined;\n stream?: boolean | undefined;\n emit?: boolean | undefined;\n nodeId?: string | undefined;\n emitEvent?: ((event: string, payload: unknown) => void) | undefined;\n onTextChunk?: ((text: string) => void) | undefined;\n id?: string | undefined;\n opId?: string | undefined;\n segmentId?: string | undefined;\n}\n\nexport interface RunReasonEngineResult {\n text: string;\n raw?: unknown;\n}\n\nconst chunkToText = (chunk: KortyxStreamChunk | string): string => {\n if (typeof chunk === \"string\") return chunk;\n if (typeof chunk.text === \"string\") return chunk.text;\n if (typeof chunk.content === \"string\") return chunk.content;\n return \"\";\n};\n\nconst createRuntimeId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nconst emitNodeEvent = (\n emitEvent: RunReasonEngineArgs[\"emitEvent\"],\n nodeId: string | undefined,\n event: string,\n payload: Record<string, unknown>,\n): void => {\n if (!emitEvent) return;\n emitEvent(event, {\n ...payload,\n ...(typeof nodeId === \"string\" && nodeId.length > 0\n ? { node: nodeId }\n : {}),\n });\n};\n\nexport async function runReasonEngine(\n args: RunReasonEngineArgs,\n): Promise<RunReasonEngineResult> {\n const stream = args.stream ?? args.model.options?.streaming ?? true;\n const emit = args.emit ?? true;\n const temperature =\n args.temperature ??\n args.model.options?.temperature ??\n args.defaultTemperature;\n\n const model = args.getProvider(args.model.providerId, args.model.modelId, {\n ...(temperature !== undefined ? { temperature } : {}),\n streaming: stream,\n });\n\n const messages: KortyxPromptMessage[] = [];\n if (typeof args.system === \"string\" && args.system.length > 0) {\n messages.push({ role: \"system\", content: args.system });\n }\n messages.push({ role: \"user\", content: String(args.input ?? \"\") });\n\n const opId =\n typeof args.opId === \"string\" && args.opId.length > 0\n ? args.opId\n : createRuntimeId();\n const segmentId =\n typeof args.segmentId === \"string\" && args.segmentId.length > 0\n ? args.segmentId\n : createRuntimeId();\n\n const commonMeta: Record<string, unknown> = {\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n opId,\n segmentId,\n };\n\n if (stream) {\n let final = \"\";\n let raw: unknown;\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n }\n\n const response = await model.stream(messages);\n for await (const chunk of response) {\n const text = chunkToText(chunk);\n if (!text) continue;\n final += text;\n args.onTextChunk?.(text);\n if (typeof chunk === \"object\" && chunk && \"raw\" in chunk) {\n raw = (chunk as KortyxStreamChunk).raw;\n }\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: text,\n });\n }\n }\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: final,\n ...(raw !== undefined ? { raw } : {}),\n };\n }\n\n const response = await model.invoke(messages);\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n if (response.content) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: response.content,\n });\n }\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: response.content,\n ...(response.raw !== undefined ? { raw: response.raw } : {}),\n };\n}\n","import type { InterruptInput } from \"@kortyx/core\";\nimport type { SchemaLike } from \"../types\";\nimport { parseWithSchema } from \"../validation\";\n\nconst tryJsonParse = (\n value: string,\n): { ok: true; value: unknown } | { ok: false } => {\n try {\n return { ok: true, value: JSON.parse(value) };\n } catch {\n return { ok: false };\n }\n};\n\nconst extractJsonCodeBlock = (value: string): string | null => {\n const match = value.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n if (!match || typeof match[1] !== \"string\") return null;\n const inner = match[1].trim();\n return inner.length > 0 ? inner : null;\n};\n\nconst tryStringify = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nexport const resolveOutputCandidate = (text: string): unknown => {\n const trimmed = text.trim();\n if (!trimmed) return text;\n\n const direct = tryJsonParse(trimmed);\n if (direct.ok) return direct.value;\n\n const block = extractJsonCodeBlock(trimmed);\n if (block) {\n const parsedBlock = tryJsonParse(block);\n if (parsedBlock.ok) return parsedBlock.value;\n }\n\n return text;\n};\n\nexport const parseInterruptFirstPassResult = <\n TRequest extends InterruptInput = InterruptInput,\n TOutput = unknown,\n>(args: {\n text: string;\n requestSchema: SchemaLike<TRequest>;\n outputSchema?: SchemaLike<TOutput>;\n}): {\n draftText: string;\n request: TRequest;\n output?: TOutput;\n} => {\n const candidate = resolveOutputCandidate(args.text);\n if (!isRecord(candidate)) {\n throw new Error(\n \"useReason first pass with interrupt must return a JSON object.\",\n );\n }\n\n const requestCandidates: unknown[] = [\n candidate.interruptRequest,\n candidate.request,\n candidate.interrupt,\n candidate,\n ];\n const requestPayload = requestCandidates.find(\n (value) => value !== null && value !== undefined,\n );\n\n const request = parseWithSchema(\n args.requestSchema,\n requestPayload,\n \"useReason interrupt.request\",\n );\n\n let output: TOutput | undefined;\n if (args.outputSchema) {\n const outputPayload = Object.hasOwn(candidate, \"output\")\n ? candidate.output\n : candidate;\n output = parseWithSchema(\n args.outputSchema,\n outputPayload,\n \"useReason output\",\n );\n }\n\n const explicitDraft =\n typeof candidate.draftText === \"string\" && candidate.draftText.length > 0\n ? candidate.draftText\n : typeof candidate.text === \"string\" && candidate.text.length > 0\n ? candidate.text\n : undefined;\n\n if (!args.outputSchema && !explicitDraft) {\n throw new Error(\n \"useReason first pass with interrupt requires `draftText` when outputSchema is not provided.\",\n );\n }\n\n const draftText =\n explicitDraft ??\n (output !== undefined ? tryStringify(output) : String(args.text ?? \"\"));\n\n return {\n draftText,\n request,\n ...(output !== undefined ? { output } : {}),\n };\n};\n","import type { InterruptInput } from \"@kortyx/core\";\nimport { toJSONSchema } from \"zod\";\nimport type { SchemaLike } from \"../types\";\n\nconst tryStringify = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n};\n\nconst tryGetSchemaHint = (schema: unknown): string | undefined => {\n try {\n const hint = toJSONSchema(schema as never);\n return JSON.stringify(hint, null, 2);\n } catch {\n return undefined;\n }\n};\n\nconst withSchemaHint = (\n input: string,\n label: string,\n schema: unknown,\n): string => {\n const hint = tryGetSchemaHint(schema);\n if (!hint) return input;\n return `${input}\\n\\n${label}:\\n${hint}`;\n};\n\nexport const defaultInterruptFirstPassInput = (args: {\n input: string;\n requestSchema: SchemaLike<unknown>;\n outputSchema?: SchemaLike<unknown>;\n}): string => {\n const base = args.outputSchema\n ? [\n args.input,\n \"Output rules:\",\n \"- Return JSON only. No markdown fences.\",\n \"- Return an object with keys: output, interruptRequest, draftText.\",\n \"- output must match the expected output JSON schema.\",\n \"- interruptRequest must match the expected interrupt request JSON schema.\",\n \"- interruptRequest must be a non-null object.\",\n \"- draftText should be a concise plain-language summary of output.\",\n \"- If uncertain, still return a valid interruptRequest with safe default options.\",\n ].join(\"\\n\\n\")\n : [\n args.input,\n \"Output rules:\",\n \"- Return JSON only. No markdown fences.\",\n \"- Return an object with keys: draftText, interruptRequest.\",\n \"- draftText should be the current draft answer text.\",\n \"- interruptRequest must match the expected interrupt request JSON schema.\",\n \"- interruptRequest must be a non-null object.\",\n \"- If uncertain, still return a valid interruptRequest with safe default options.\",\n ].join(\"\\n\\n\");\n\n const withInterruptSchema = withSchemaHint(\n base,\n \"Expected interrupt request JSON schema (for `interruptRequest`)\",\n args.requestSchema,\n );\n\n if (!args.outputSchema) return withInterruptSchema;\n const withOutputSchema = withSchemaHint(\n withInterruptSchema,\n \"Expected output JSON schema (for `output`)\",\n args.outputSchema,\n );\n return [\n withOutputSchema,\n \"JSON template:\",\n '{ \"output\": { ... }, \"interruptRequest\": { ... }, \"draftText\": \"...\" }',\n ].join(\"\\n\\n\");\n};\n\nexport const defaultContinuationInput = (args: {\n input: string;\n draftText: string;\n draftOutput?: unknown;\n request: InterruptInput;\n response: unknown;\n}): string =>\n [\n \"You are continuing a paused reasoning task after user input.\",\n \"Update the previous result using the user response and return the final answer only.\",\n \"If the previous output was JSON, return JSON in the same schema.\",\n \"\",\n `Original request:\\n${args.input}`,\n `Draft answer text:\\n${args.draftText}`,\n `Draft output object:\\n${tryStringify(args.draftOutput ?? args.draftText)}`,\n `Interrupt request shown to user:\\n${tryStringify(args.request)}`,\n `User response:\\n${tryStringify(args.response)}`,\n ].join(\"\\n\\n\");\n\nexport const withOutputGuardrails = (\n input: string,\n schema?: SchemaLike<unknown>,\n): string => {\n const base = [\n input,\n \"Output rules:\",\n \"- Return only JSON, no markdown fences.\",\n \"- Ensure the response conforms to the expected output schema.\",\n \"- Do not include explanatory text outside the JSON object.\",\n ].join(\"\\n\\n\");\n return withSchemaHint(base, \"Expected output JSON schema\", schema);\n};\n\nexport const withStructuredStreamHints = (\n input: string,\n args: {\n setFieldPaths?: string[];\n appendFieldPaths?: string[];\n textDeltaFieldPaths?: string[];\n },\n): string => {\n const rules: string[] = [];\n\n for (const path of args.setFieldPaths ?? []) {\n rules.push(\n `- For the top-level field \\`${path}\\`, write one stable final value and do not rewrite it after it is complete.`,\n );\n }\n\n for (const path of args.appendFieldPaths ?? []) {\n rules.push(\n `- For the top-level array field \\`${path}\\`, write items in final order and finish each item before starting the next.`,\n );\n rules.push(\n `- Once an item in \\`${path}\\` is complete, do not rewrite or reorder earlier items.`,\n );\n }\n\n for (const path of args.textDeltaFieldPaths ?? []) {\n rules.push(\n `- For the top-level string field \\`${path}\\`, write the value progressively by appending text to the end.`,\n );\n rules.push(\n `- Do not rewrite or replace the earlier prefix of \\`${path}\\` once emitted.`,\n );\n }\n\n if (rules.length === 0) return input;\n\n return [\n input,\n \"Streaming rules:\",\n ...rules,\n \"- Keep the overall response as valid JSON.\",\n ].join(\"\\n\\n\");\n};\n","import type { UseReasonStructuredConfig } from \"../types\";\n\nconst escapeRegex = (value: string): string =>\n value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\nconst findTopLevelArrayStart = (text: string, path: string): number => {\n const match = new RegExp(`\"${escapeRegex(path)}\"\\\\s*:\\\\s*\\\\[`).exec(text);\n return match ? match.index + match[0].length : -1;\n};\n\nexport const resolveAppendFieldPaths = (\n cfg: UseReasonStructuredConfig | undefined,\n): string[] => {\n const fields = cfg?.fields;\n if (!fields) return [];\n\n const appendPaths = Object.entries(fields)\n .filter(([, mode]) => mode === \"append\")\n .map(([path]) => path);\n\n for (const path of appendPaths) {\n if (!path || path.includes(\".\")) {\n throw new Error(\n \"useReason structured append streaming currently supports top-level array fields only.\",\n );\n }\n }\n\n return appendPaths;\n};\n\nexport const resolveSetFieldPaths = (\n cfg: UseReasonStructuredConfig | undefined,\n): string[] => {\n const fields = cfg?.fields;\n if (!fields) return [];\n\n const setPaths = Object.entries(fields)\n .filter(([, mode]) => mode === \"set\")\n .map(([path]) => path);\n\n for (const path of setPaths) {\n if (!path || path.includes(\".\")) {\n throw new Error(\n \"useReason structured set streaming currently supports top-level fields only.\",\n );\n }\n }\n\n return setPaths;\n};\n\nexport const resolveTextDeltaFieldPaths = (\n cfg: UseReasonStructuredConfig | undefined,\n): string[] => {\n const fields = cfg?.fields;\n if (!fields) return [];\n\n const textPaths = Object.entries(fields)\n .filter(([, mode]) => mode === \"text-delta\")\n .map(([path]) => path);\n\n for (const path of textPaths) {\n if (!path || path.includes(\".\")) {\n throw new Error(\n \"useReason structured text-delta streaming currently supports top-level string fields only.\",\n );\n }\n }\n\n return textPaths;\n};\n\nconst findTopLevelFieldValueStart = (text: string, path: string): number => {\n const match = new RegExp(`\"${escapeRegex(path)}\"\\\\s*:\\\\s*`).exec(text);\n return match ? match.index + match[0].length : -1;\n};\n\nconst findTopLevelStringStart = (text: string, path: string): number => {\n const match = new RegExp(`\"${escapeRegex(path)}\"\\\\s*:\\\\s*\"`).exec(text);\n return match ? match.index + match[0].length : -1;\n};\n\nconst extractCompletedStringValueAt = (args: {\n text: string;\n start: number;\n}): { complete: boolean; value?: string } => {\n let value = \"\";\n\n for (let i = args.start; i < args.text.length; i += 1) {\n const ch = args.text[i];\n if (ch === undefined) break;\n\n if (ch === '\"') {\n return {\n complete: true,\n value,\n };\n }\n\n if (ch !== \"\\\\\") {\n value += ch;\n continue;\n }\n\n const next = args.text[i + 1];\n if (!next) {\n return {\n complete: false,\n };\n }\n\n if (\n next === '\"' ||\n next === \"\\\\\" ||\n next === \"/\" ||\n next === \"b\" ||\n next === \"f\" ||\n next === \"n\" ||\n next === \"r\" ||\n next === \"t\"\n ) {\n value +=\n next === \"b\"\n ? \"\\b\"\n : next === \"f\"\n ? \"\\f\"\n : next === \"n\"\n ? \"\\n\"\n : next === \"r\"\n ? \"\\r\"\n : next === \"t\"\n ? \"\\t\"\n : next;\n i += 1;\n continue;\n }\n\n if (next === \"u\") {\n const hex = args.text.slice(i + 2, i + 6);\n if (!/^[0-9a-fA-F]{4}$/.test(hex)) {\n return {\n complete: false,\n };\n }\n value += String.fromCharCode(Number.parseInt(hex, 16));\n i += 5;\n continue;\n }\n\n return {\n complete: false,\n };\n }\n\n return {\n complete: false,\n };\n};\n\nconst extractCompletedNestedValueAt = (args: {\n text: string;\n start: number;\n opener: \"{\" | \"[\";\n closer: \"}\" | \"]\";\n}): { complete: boolean; value?: unknown } => {\n let inString = false;\n let isEscaped = false;\n let nesting = 0;\n\n for (let i = args.start; i < args.text.length; i += 1) {\n const ch = args.text[i];\n if (ch === undefined) break;\n\n if (inString) {\n if (isEscaped) {\n isEscaped = false;\n continue;\n }\n if (ch === \"\\\\\") {\n isEscaped = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === args.opener) {\n nesting += 1;\n continue;\n }\n\n if (ch === args.closer) {\n nesting -= 1;\n if (nesting === 0) {\n const raw = args.text.slice(args.start, i + 1);\n try {\n return {\n complete: true,\n value: JSON.parse(raw),\n };\n } catch {\n return {\n complete: false,\n };\n }\n }\n }\n }\n\n return {\n complete: false,\n };\n};\n\nexport const extractCompletedFieldValue = (args: {\n text: string;\n path: string;\n}): { found: boolean; complete: boolean; value?: unknown } => {\n const start = findTopLevelFieldValueStart(args.text, args.path);\n if (start < 0) {\n return {\n found: false,\n complete: false,\n };\n }\n\n const first = args.text[start];\n if (!first) {\n return {\n found: true,\n complete: false,\n };\n }\n\n if (first === '\"') {\n const parsed = extractCompletedStringValueAt({\n text: args.text,\n start: start + 1,\n });\n return parsed.complete\n ? {\n found: true,\n complete: true,\n value: parsed.value,\n }\n : {\n found: true,\n complete: false,\n };\n }\n\n if (first === \"{\") {\n const parsed = extractCompletedNestedValueAt({\n text: args.text,\n start,\n opener: \"{\",\n closer: \"}\",\n });\n return parsed.complete\n ? {\n found: true,\n complete: true,\n value: parsed.value,\n }\n : {\n found: true,\n complete: false,\n };\n }\n\n if (first === \"[\") {\n const parsed = extractCompletedNestedValueAt({\n text: args.text,\n start,\n opener: \"[\",\n closer: \"]\",\n });\n return parsed.complete\n ? {\n found: true,\n complete: true,\n value: parsed.value,\n }\n : {\n found: true,\n complete: false,\n };\n }\n\n for (let i = start; i < args.text.length; i += 1) {\n const ch = args.text[i];\n if (ch === undefined) break;\n if (ch !== \",\" && ch !== \"}\") continue;\n\n const raw = args.text.slice(start, i).trim();\n if (!raw) {\n return {\n found: true,\n complete: false,\n };\n }\n\n try {\n return {\n found: true,\n complete: true,\n value: JSON.parse(raw),\n };\n } catch {\n return {\n found: true,\n complete: false,\n };\n }\n }\n\n return {\n found: true,\n complete: false,\n };\n};\n\nexport const extractCompletedArrayItems = (args: {\n text: string;\n path: string;\n}): unknown[] => {\n const start = findTopLevelArrayStart(args.text, args.path);\n if (start < 0) return [];\n\n const items: unknown[] = [];\n let inString = false;\n let isEscaped = false;\n let nesting = 0;\n let itemStart = -1;\n\n for (let i = start; i < args.text.length; i += 1) {\n const ch = args.text[i];\n if (ch === undefined) break;\n\n if (inString) {\n if (isEscaped) {\n isEscaped = false;\n continue;\n }\n if (ch === \"\\\\\") {\n isEscaped = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n if (itemStart < 0) itemStart = i;\n continue;\n }\n\n if (itemStart < 0) {\n if (/\\s/.test(ch) || ch === \",\") continue;\n if (ch === \"]\") break;\n itemStart = i;\n if (ch === \"{\" || ch === \"[\") {\n nesting = 1;\n } else {\n nesting = 0;\n }\n continue;\n }\n\n if (ch === \"{\" || ch === \"[\") {\n nesting += 1;\n continue;\n }\n\n if (ch === \"}\" || ch === \"]\") {\n if (nesting > 0) {\n nesting -= 1;\n if (nesting > 0) continue;\n }\n\n if (ch === \"]\") {\n const raw = args.text.slice(itemStart, i).trim();\n if (raw) {\n try {\n items.push(JSON.parse(raw));\n } catch {}\n }\n break;\n }\n }\n\n if (nesting === 0 && (ch === \",\" || ch === \"]\")) {\n const raw = args.text.slice(itemStart, i).trim();\n if (raw) {\n try {\n items.push(JSON.parse(raw));\n } catch {}\n }\n itemStart = -1;\n if (ch === \"]\") break;\n }\n }\n\n return items;\n};\n\nexport const extractStreamingStringValue = (args: {\n text: string;\n path: string;\n}): { found: boolean; complete: boolean; value: string } => {\n const start = findTopLevelStringStart(args.text, args.path);\n if (start < 0) {\n return {\n found: false,\n complete: false,\n value: \"\",\n };\n }\n\n let value = \"\";\n\n for (let i = start; i < args.text.length; i += 1) {\n const ch = args.text[i];\n if (ch === undefined) break;\n\n if (ch === '\"') {\n return {\n found: true,\n complete: true,\n value,\n };\n }\n\n if (ch !== \"\\\\\") {\n value += ch;\n continue;\n }\n\n const next = args.text[i + 1];\n if (!next) {\n return {\n found: true,\n complete: false,\n value,\n };\n }\n\n if (\n next === '\"' ||\n next === \"\\\\\" ||\n next === \"/\" ||\n next === \"b\" ||\n next === \"f\" ||\n next === \"n\" ||\n next === \"r\" ||\n next === \"t\"\n ) {\n value +=\n next === \"b\"\n ? \"\\b\"\n : next === \"f\"\n ? \"\\f\"\n : next === \"n\"\n ? \"\\n\"\n : next === \"r\"\n ? \"\\r\"\n : next === \"t\"\n ? \"\\t\"\n : next;\n i += 1;\n continue;\n }\n\n if (next === \"u\") {\n const hex = args.text.slice(i + 2, i + 6);\n if (!/^[0-9a-fA-F]{4}$/.test(hex)) {\n return {\n found: true,\n complete: false,\n value,\n };\n }\n value += String.fromCharCode(Number.parseInt(hex, 16));\n i += 5;\n continue;\n }\n\n return {\n found: true,\n complete: false,\n value,\n };\n }\n\n return {\n found: true,\n complete: false,\n value,\n };\n};\n","import type { InterruptInput, InterruptResult } from \"@kortyx/core\";\nimport { getHookContext } from \"../context\";\nimport { awaitInterruptInternal } from \"../interrupt\";\nimport { emitStructuredData, shouldEmitStructured } from \"../structured\";\nimport type { SchemaLike, UseReasonArgs, UseReasonResult } from \"../types\";\nimport { parseWithSchema } from \"../validation\";\nimport {\n type ReasonInterruptCheckpoint,\n readReasonCheckpoint,\n resolveHookStatePatch,\n resolveReasonCheckpointKey,\n} from \"./checkpoint\";\nimport { createRuntimeId, reasonEngine } from \"./engine\";\nimport {\n parseInterruptFirstPassResult,\n resolveOutputCandidate,\n} from \"./parsing\";\nimport {\n defaultContinuationInput,\n defaultInterruptFirstPassInput,\n withOutputGuardrails,\n withStructuredStreamHints,\n} from \"./prompting\";\nimport {\n extractCompletedArrayItems,\n extractCompletedFieldValue,\n extractStreamingStringValue,\n resolveAppendFieldPaths,\n resolveSetFieldPaths,\n resolveTextDeltaFieldPaths,\n} from \"./structured-stream\";\n\nconst emitReasonStructuredOutput = <TOutput>(args: {\n id?: string;\n opId: string;\n output: TOutput;\n structured: UseReasonArgs<TOutput>[\"structured\"];\n}): void => {\n if (!shouldEmitStructured(args.structured)) return;\n\n emitStructuredData<TOutput>({\n dataType: args.structured?.dataType ?? \"reason-output\",\n data: args.output,\n kind: \"final\",\n ...(args.structured?.schemaId\n ? { schemaId: args.structured.schemaId }\n : {}),\n ...(args.structured?.schemaVersion\n ? { schemaVersion: args.structured.schemaVersion }\n : {}),\n ...(args.id ? { id: args.id } : {}),\n streamId: args.opId,\n });\n};\n\nexport async function useReason<\n TOutput = unknown,\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(\n args: UseReasonArgs<TOutput, TRequest, TResponse>,\n): Promise<UseReasonResult<TOutput, TResponse>> {\n const ctx = getHookContext();\n const id =\n typeof args.id === \"string\" && args.id.length > 0 ? args.id : undefined;\n const opId = createRuntimeId();\n const checkpointKey = resolveReasonCheckpointKey({\n ...(id ? { id } : {}),\n autoIndex: ctx.reasonCallIndex++,\n });\n const existingCheckpoint = readReasonCheckpoint(\n ctx.currentNodeState.byKey[checkpointKey],\n );\n\n const reasonMeta =\n typeof id === \"string\" ? ({ id, opId } as const) : ({ opId } as const);\n const suppressTextStream = Boolean(args.outputSchema || args.interrupt);\n const setFieldPaths = resolveSetFieldPaths(args.structured);\n const appendFieldPaths = resolveAppendFieldPaths(args.structured);\n const textDeltaFieldPaths = resolveTextDeltaFieldPaths(args.structured);\n const useStructuredIncrementalStreaming = Boolean(\n args.outputSchema &&\n !args.interrupt &&\n (setFieldPaths.length > 0 ||\n appendFieldPaths.length > 0 ||\n textDeltaFieldPaths.length > 0) &&\n args.stream !== false &&\n shouldEmitStructured(args.structured),\n );\n\n let firstText = \"\";\n let firstRaw: unknown;\n let firstOutput: TOutput | undefined;\n let firstInterruptRequest: TRequest | undefined;\n\n let finalText = \"\";\n let finalRaw: unknown;\n let finalOutput: TOutput | undefined;\n const emittedSetValues = new Map<string, string>();\n const emittedAppendCounts = new Map<string, number>();\n const emittedTextValues = new Map<string, string>();\n\n if (existingCheckpoint) {\n firstText = existingCheckpoint.firstText;\n firstRaw = existingCheckpoint.firstRaw;\n firstOutput = existingCheckpoint.firstOutput as TOutput | undefined;\n finalText = firstText;\n finalRaw = firstRaw;\n finalOutput = firstOutput;\n } else {\n const first = await reasonEngine(\n {\n ...args,\n emit: suppressTextStream ? false : args.emit,\n stream: useStructuredIncrementalStreaming\n ? true\n : suppressTextStream\n ? false\n : args.stream,\n ...(useStructuredIncrementalStreaming\n ? {\n onTextChunk: (delta: string) => {\n firstText += delta;\n finalText = firstText;\n\n for (const path of setFieldPaths) {\n const current = extractCompletedFieldValue({\n text: firstText,\n path,\n });\n if (!current.found || !current.complete) continue;\n\n const nextSerialized = JSON.stringify(current.value);\n if (emittedSetValues.get(path) === nextSerialized) continue;\n\n emittedSetValues.set(path, nextSerialized);\n emitStructuredData({\n kind: \"set\",\n path,\n value: current.value,\n dataType: args.structured?.dataType ?? \"reason-output\",\n ...(args.structured?.schemaId\n ? { schemaId: args.structured.schemaId }\n : {}),\n ...(args.structured?.schemaVersion\n ? { schemaVersion: args.structured.schemaVersion }\n : {}),\n ...(id ? { id } : {}),\n streamId: opId,\n });\n }\n\n for (const path of appendFieldPaths) {\n const items = extractCompletedArrayItems({\n text: firstText,\n path,\n });\n const emittedAppendCount = emittedAppendCounts.get(path) ?? 0;\n if (items.length <= emittedAppendCount) continue;\n\n const nextItems = items.slice(emittedAppendCount);\n emittedAppendCounts.set(path, items.length);\n emitStructuredData({\n kind: \"append\",\n path,\n items: nextItems,\n dataType: args.structured?.dataType ?? \"reason-output\",\n ...(args.structured?.schemaId\n ? { schemaId: args.structured.schemaId }\n : {}),\n ...(args.structured?.schemaVersion\n ? { schemaVersion: args.structured.schemaVersion }\n : {}),\n ...(id ? { id } : {}),\n streamId: opId,\n });\n }\n\n for (const path of textDeltaFieldPaths) {\n const current = extractStreamingStringValue({\n text: firstText,\n path,\n });\n const emittedTextValue = emittedTextValues.get(path) ?? \"\";\n if (\n !current.found ||\n current.value.length <= emittedTextValue.length ||\n !current.value.startsWith(emittedTextValue)\n ) {\n continue;\n }\n\n const nextDelta = current.value.slice(\n emittedTextValue.length,\n );\n emittedTextValues.set(path, current.value);\n if (nextDelta.length === 0) continue;\n\n emitStructuredData({\n kind: \"text-delta\",\n path,\n delta: nextDelta,\n dataType: args.structured?.dataType ?? \"reason-output\",\n ...(args.structured?.schemaId\n ? { schemaId: args.structured.schemaId }\n : {}),\n ...(args.structured?.schemaVersion\n ? { schemaVersion: args.structured.schemaVersion }\n : {}),\n ...(id ? { id } : {}),\n streamId: opId,\n });\n }\n },\n }\n : {}),\n },\n reasonMeta,\n args.interrupt\n ? defaultInterruptFirstPassInput({\n input: args.input,\n requestSchema: args.interrupt.requestSchema,\n ...(args.outputSchema\n ? { outputSchema: args.outputSchema as SchemaLike<unknown> }\n : {}),\n })\n : args.outputSchema\n ? withOutputGuardrails(\n withStructuredStreamHints(args.input, {\n ...(setFieldPaths.length > 0 ? { setFieldPaths } : {}),\n ...(appendFieldPaths.length > 0 ? { appendFieldPaths } : {}),\n ...(textDeltaFieldPaths.length > 0\n ? { textDeltaFieldPaths }\n : {}),\n }),\n args.outputSchema as SchemaLike<unknown>,\n )\n : undefined,\n );\n firstRaw = first.raw;\n finalRaw = first.raw;\n\n if (args.interrupt) {\n const firstPass = parseInterruptFirstPassResult<TRequest, TOutput>({\n text: first.text,\n requestSchema: args.interrupt.requestSchema,\n ...(args.outputSchema\n ? { outputSchema: args.outputSchema as SchemaLike<TOutput> }\n : {}),\n });\n firstText = firstPass.draftText;\n finalText = firstPass.draftText;\n firstInterruptRequest = firstPass.request;\n firstOutput = firstPass.output;\n finalOutput = firstPass.output;\n } else {\n firstText = first.text;\n finalText = first.text;\n if (args.outputSchema) {\n firstOutput = parseWithSchema(\n args.outputSchema,\n resolveOutputCandidate(first.text),\n \"useReason output\",\n );\n }\n finalOutput = firstOutput;\n }\n }\n\n let interruptResponse: TResponse | undefined;\n\n if (args.interrupt) {\n const requestSchema = args.interrupt.requestSchema;\n\n const interruptRequest = existingCheckpoint\n ? parseWithSchema(\n requestSchema,\n existingCheckpoint.request,\n \"useReason interrupt.request\",\n )\n : firstInterruptRequest;\n\n if (!interruptRequest) {\n throw new Error(\n \"useReason interrupt request is missing; first pass did not produce a valid interrupt payload.\",\n );\n }\n\n if (!existingCheckpoint) {\n ctx.currentNodeState.byKey[checkpointKey] = {\n status: \"awaiting_interrupt\",\n request: interruptRequest,\n firstText,\n ...(firstRaw !== undefined ? { firstRaw } : {}),\n ...(firstOutput !== undefined ? { firstOutput } : {}),\n } satisfies ReasonInterruptCheckpoint;\n ctx.dirty = true;\n }\n\n const resumeStatePatch = resolveHookStatePatch({\n nodeId: ctx.node.graph.node,\n currentNodeState: ctx.currentNodeState,\n workflowState: ctx.workflowState,\n });\n\n interruptResponse = await awaitInterruptInternal<TRequest, TResponse>({\n request: interruptRequest,\n requestSchema,\n responseSchema: args.interrupt.responseSchema,\n ...(args.interrupt.schemaId ? { schemaId: args.interrupt.schemaId } : {}),\n ...(args.interrupt.schemaVersion\n ? { schemaVersion: args.interrupt.schemaVersion }\n : {}),\n ...(id ? { id } : {}),\n meta: {\n __kortyxResumeStatePatch: resumeStatePatch,\n },\n });\n\n if (Object.hasOwn(ctx.currentNodeState.byKey, checkpointKey)) {\n delete ctx.currentNodeState.byKey[checkpointKey];\n ctx.dirty = true;\n }\n\n const continuationInput = defaultContinuationInput({\n input: args.input,\n draftText: firstText,\n ...(firstOutput !== undefined ? { draftOutput: firstOutput } : {}),\n request: interruptRequest,\n response: interruptResponse,\n });\n\n const second = await reasonEngine(\n {\n ...args,\n emit: suppressTextStream ? false : args.emit,\n stream: suppressTextStream ? false : args.stream,\n },\n reasonMeta,\n args.outputSchema\n ? withOutputGuardrails(\n continuationInput,\n args.outputSchema as SchemaLike<unknown>,\n )\n : continuationInput,\n );\n finalText = second.text;\n finalRaw = second.raw;\n\n if (args.outputSchema) {\n finalOutput = parseWithSchema(\n args.outputSchema,\n resolveOutputCandidate(finalText),\n \"useReason output\",\n );\n }\n }\n\n if (finalOutput !== undefined) {\n emitReasonStructuredOutput<TOutput>({\n ...(id ? { id } : {}),\n opId,\n output: finalOutput,\n structured: args.structured,\n });\n }\n\n return {\n ...(id ? { id } : {}),\n opId,\n text: finalText,\n ...(finalRaw !== undefined ? { raw: finalRaw } : {}),\n ...(finalOutput !== undefined ? { output: finalOutput } : {}),\n ...(interruptResponse !== undefined ? { interruptResponse } : {}),\n };\n}\n","import type { InterruptInput, InterruptResult } from \"@kortyx/core\";\nimport { getHookContext } from \"./context\";\nimport { awaitInterruptInternal } from \"./interrupt\";\nimport { useReason as useReasonInternal } from \"./reason/use-reason\";\nimport { emitStructuredData } from \"./structured\";\nimport type {\n UseInterruptArgs,\n UseReasonArgs,\n UseReasonResult,\n UseStructuredDataArgs,\n} from \"./types\";\n\nexport type {\n SchemaLike,\n StructuredDataKind,\n UseInterruptArgs,\n UseReasonArgs,\n UseReasonInterruptConfig,\n UseReasonResult,\n UseReasonStructuredConfig,\n UseStructuredDataAppendArgs,\n UseStructuredDataArgs,\n UseStructuredDataFinalArgs,\n UseStructuredDataSetArgs,\n UseStructuredDataTextDeltaArgs,\n} from \"./types\";\n\ntype StateSetter<T> = (next: T | ((prev: T) => T)) => void;\n\nexport function useStructuredData<TData = unknown>(\n args: UseStructuredDataArgs<TData>,\n): void {\n emitStructuredData(args);\n}\n\nexport function useReason<\n TOutput = unknown,\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(\n args: UseReasonArgs<TOutput, TRequest, TResponse>,\n): Promise<UseReasonResult<TOutput, TResponse>> {\n return useReasonInternal(args);\n}\n\nexport function useInterrupt<\n TRequest extends InterruptInput = InterruptInput,\n TResponse = InterruptResult,\n>(args: UseInterruptArgs<TRequest, TResponse>): Promise<TResponse> {\n return awaitInterruptInternal(args);\n}\n\nexport function useNodeState<T>(initialValue: T): [T, StateSetter<T>] {\n const ctx = getHookContext();\n const nodeState = ctx.currentNodeState;\n\n const index = ctx.nodeStateIndex++;\n if (index >= nodeState.byIndex.length) {\n nodeState.byIndex[index] = initialValue as T;\n ctx.dirty = true;\n }\n\n const getValue = () => nodeState.byIndex[index] as T;\n const setValue: StateSetter<T> = (next) => {\n const prev = getValue();\n const resolved =\n typeof next === \"function\" ? (next as (p: T) => T)(prev) : next;\n nodeState.byIndex[index] = resolved;\n ctx.dirty = true;\n };\n\n return [getValue(), setValue];\n}\n\nexport function useWorkflowState<T>(\n key: string,\n ...rest: [] | [T]\n): [T, StateSetter<T>] {\n const ctx = getHookContext();\n const workflowState = ctx.workflowState;\n const hasInitial = rest.length > 0;\n const initialValue = rest[0];\n\n if (!Object.hasOwn(workflowState, key) && hasInitial) {\n workflowState[key] = initialValue as T;\n ctx.dirty = true;\n }\n\n const getValue = () => workflowState[key] as T;\n const setValue: StateSetter<T> = (next) => {\n const prev = getValue();\n const resolved =\n typeof next === \"function\" ? (next as (p: T) => T)(prev) : next;\n workflowState[key] = resolved;\n ctx.dirty = true;\n };\n\n return [getValue(), setValue];\n}\n"],"mappings":"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","names":["useReason","import_node_crypto","import_node_crypto","response","createRuntimeId","isRecord","tryStringify","createRuntimeId","useReason"]}
|
package/dist/internal.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ interface RunReasonEngineArgs {
|
|
|
11
11
|
emit?: boolean | undefined;
|
|
12
12
|
nodeId?: string | undefined;
|
|
13
13
|
emitEvent?: ((event: string, payload: unknown) => void) | undefined;
|
|
14
|
+
onTextChunk?: ((text: string) => void) | undefined;
|
|
14
15
|
id?: string | undefined;
|
|
15
16
|
opId?: string | undefined;
|
|
16
17
|
segmentId?: string | undefined;
|
package/dist/internal.js
CHANGED
package/dist/internal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal.ts","../src/reason-engine.ts"],"sourcesContent":["export type {\n RunReasonEngineArgs,\n RunReasonEngineResult,\n} from \"./reason-engine\";\nexport { runReasonEngine } from \"./reason-engine\";\n","import { randomUUID } from \"node:crypto\";\nimport type {\n GetProviderFn,\n KortyxPromptMessage,\n KortyxStreamChunk,\n ProviderModelRef,\n} from \"@kortyx/providers\";\n\nexport interface RunReasonEngineArgs {\n getProvider: GetProviderFn;\n model: ProviderModelRef;\n input: string;\n system?: string | undefined;\n temperature?: number | undefined;\n defaultTemperature?: number | undefined;\n stream?: boolean | undefined;\n emit?: boolean | undefined;\n nodeId?: string | undefined;\n emitEvent?: ((event: string, payload: unknown) => void) | undefined;\n id?: string | undefined;\n opId?: string | undefined;\n segmentId?: string | undefined;\n}\n\nexport interface RunReasonEngineResult {\n text: string;\n raw?: unknown;\n}\n\nconst chunkToText = (chunk: KortyxStreamChunk | string): string => {\n if (typeof chunk === \"string\") return chunk;\n if (typeof chunk.text === \"string\") return chunk.text;\n if (typeof chunk.content === \"string\") return chunk.content;\n return \"\";\n};\n\nconst createRuntimeId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nconst emitNodeEvent = (\n emitEvent: RunReasonEngineArgs[\"emitEvent\"],\n nodeId: string | undefined,\n event: string,\n payload: Record<string, unknown>,\n): void => {\n if (!emitEvent) return;\n emitEvent(event, {\n ...payload,\n ...(typeof nodeId === \"string\" && nodeId.length > 0\n ? { node: nodeId }\n : {}),\n });\n};\n\nexport async function runReasonEngine(\n args: RunReasonEngineArgs,\n): Promise<RunReasonEngineResult> {\n const stream = args.stream ?? args.model.options?.streaming ?? true;\n const emit = args.emit ?? true;\n const temperature =\n args.temperature ??\n args.model.options?.temperature ??\n args.defaultTemperature;\n\n const model = args.getProvider(args.model.providerId, args.model.modelId, {\n ...(temperature !== undefined ? { temperature } : {}),\n streaming: stream,\n });\n\n const messages: KortyxPromptMessage[] = [];\n if (typeof args.system === \"string\" && args.system.length > 0) {\n messages.push({ role: \"system\", content: args.system });\n }\n messages.push({ role: \"user\", content: String(args.input ?? \"\") });\n\n const opId =\n typeof args.opId === \"string\" && args.opId.length > 0\n ? args.opId\n : createRuntimeId();\n const segmentId =\n typeof args.segmentId === \"string\" && args.segmentId.length > 0\n ? args.segmentId\n : createRuntimeId();\n\n const commonMeta: Record<string, unknown> = {\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n opId,\n segmentId,\n };\n\n if (stream) {\n let final = \"\";\n let raw: unknown;\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n }\n\n const response = await model.stream(messages);\n for await (const chunk of response) {\n const text = chunkToText(chunk);\n if (!text) continue;\n final += text;\n if (typeof chunk === \"object\" && chunk && \"raw\" in chunk) {\n raw = (chunk as KortyxStreamChunk).raw;\n }\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: text,\n });\n }\n }\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: final,\n ...(raw !== undefined ? { raw } : {}),\n };\n }\n\n const response = await model.invoke(messages);\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n if (response.content) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: response.content,\n });\n }\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: response.content,\n ...(response.raw !== undefined ? { raw: response.raw } : {}),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,yBAA2B;
|
|
1
|
+
{"version":3,"sources":["../src/internal.ts","../src/reason-engine.ts"],"sourcesContent":["export type {\n RunReasonEngineArgs,\n RunReasonEngineResult,\n} from \"./reason-engine\";\nexport { runReasonEngine } from \"./reason-engine\";\n","import { randomUUID } from \"node:crypto\";\nimport type {\n GetProviderFn,\n KortyxPromptMessage,\n KortyxStreamChunk,\n ProviderModelRef,\n} from \"@kortyx/providers\";\n\nexport interface RunReasonEngineArgs {\n getProvider: GetProviderFn;\n model: ProviderModelRef;\n input: string;\n system?: string | undefined;\n temperature?: number | undefined;\n defaultTemperature?: number | undefined;\n stream?: boolean | undefined;\n emit?: boolean | undefined;\n nodeId?: string | undefined;\n emitEvent?: ((event: string, payload: unknown) => void) | undefined;\n onTextChunk?: ((text: string) => void) | undefined;\n id?: string | undefined;\n opId?: string | undefined;\n segmentId?: string | undefined;\n}\n\nexport interface RunReasonEngineResult {\n text: string;\n raw?: unknown;\n}\n\nconst chunkToText = (chunk: KortyxStreamChunk | string): string => {\n if (typeof chunk === \"string\") return chunk;\n if (typeof chunk.text === \"string\") return chunk.text;\n if (typeof chunk.content === \"string\") return chunk.content;\n return \"\";\n};\n\nconst createRuntimeId = (): string => {\n try {\n return randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n};\n\nconst emitNodeEvent = (\n emitEvent: RunReasonEngineArgs[\"emitEvent\"],\n nodeId: string | undefined,\n event: string,\n payload: Record<string, unknown>,\n): void => {\n if (!emitEvent) return;\n emitEvent(event, {\n ...payload,\n ...(typeof nodeId === \"string\" && nodeId.length > 0\n ? { node: nodeId }\n : {}),\n });\n};\n\nexport async function runReasonEngine(\n args: RunReasonEngineArgs,\n): Promise<RunReasonEngineResult> {\n const stream = args.stream ?? args.model.options?.streaming ?? true;\n const emit = args.emit ?? true;\n const temperature =\n args.temperature ??\n args.model.options?.temperature ??\n args.defaultTemperature;\n\n const model = args.getProvider(args.model.providerId, args.model.modelId, {\n ...(temperature !== undefined ? { temperature } : {}),\n streaming: stream,\n });\n\n const messages: KortyxPromptMessage[] = [];\n if (typeof args.system === \"string\" && args.system.length > 0) {\n messages.push({ role: \"system\", content: args.system });\n }\n messages.push({ role: \"user\", content: String(args.input ?? \"\") });\n\n const opId =\n typeof args.opId === \"string\" && args.opId.length > 0\n ? args.opId\n : createRuntimeId();\n const segmentId =\n typeof args.segmentId === \"string\" && args.segmentId.length > 0\n ? args.segmentId\n : createRuntimeId();\n\n const commonMeta: Record<string, unknown> = {\n ...(typeof args.id === \"string\" && args.id.length > 0\n ? { id: args.id }\n : {}),\n opId,\n segmentId,\n };\n\n if (stream) {\n let final = \"\";\n let raw: unknown;\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n }\n\n const response = await model.stream(messages);\n for await (const chunk of response) {\n const text = chunkToText(chunk);\n if (!text) continue;\n final += text;\n args.onTextChunk?.(text);\n if (typeof chunk === \"object\" && chunk && \"raw\" in chunk) {\n raw = (chunk as KortyxStreamChunk).raw;\n }\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: text,\n });\n }\n }\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: final,\n ...(raw !== undefined ? { raw } : {}),\n };\n }\n\n const response = await model.invoke(messages);\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {\n ...commonMeta,\n });\n if (response.content) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n ...commonMeta,\n delta: response.content,\n });\n }\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {\n ...commonMeta,\n });\n }\n\n return {\n text: response.content,\n ...(response.raw !== undefined ? { raw: response.raw } : {}),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,yBAA2B;AA8B3B,IAAM,cAAc,CAAC,UAA8C;AACjE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,MAAM,SAAS,SAAU,QAAO,MAAM;AACjD,MAAI,OAAO,MAAM,YAAY,SAAU,QAAO,MAAM;AACpD,SAAO;AACT;AAEA,IAAM,kBAAkB,MAAc;AACpC,MAAI;AACF,eAAO,+BAAW;AAAA,EACpB,QAAQ;AACN,WAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAAA,EAC7D;AACF;AAEA,IAAM,gBAAgB,CACpB,WACA,QACA,OACA,YACS;AACT,MAAI,CAAC,UAAW;AAChB,YAAU,OAAO;AAAA,IACf,GAAG;AAAA,IACH,GAAI,OAAO,WAAW,YAAY,OAAO,SAAS,IAC9C,EAAE,MAAM,OAAO,IACf,CAAC;AAAA,EACP,CAAC;AACH;AAEA,eAAsB,gBACpB,MACgC;AAChC,QAAM,SAAS,KAAK,UAAU,KAAK,MAAM,SAAS,aAAa;AAC/D,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,cACJ,KAAK,eACL,KAAK,MAAM,SAAS,eACpB,KAAK;AAEP,QAAM,QAAQ,KAAK,YAAY,KAAK,MAAM,YAAY,KAAK,MAAM,SAAS;AAAA,IACxE,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,IACnD,WAAW;AAAA,EACb,CAAC;AAED,QAAM,WAAkC,CAAC;AACzC,MAAI,OAAO,KAAK,WAAW,YAAY,KAAK,OAAO,SAAS,GAAG;AAC7D,aAAS,KAAK,EAAE,MAAM,UAAU,SAAS,KAAK,OAAO,CAAC;AAAA,EACxD;AACA,WAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,OAAO,KAAK,SAAS,EAAE,EAAE,CAAC;AAEjE,QAAM,OACJ,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS,IAChD,KAAK,OACL,gBAAgB;AACtB,QAAM,YACJ,OAAO,KAAK,cAAc,YAAY,KAAK,UAAU,SAAS,IAC1D,KAAK,YACL,gBAAgB;AAEtB,QAAM,aAAsC;AAAA,IAC1C,GAAI,OAAO,KAAK,OAAO,YAAY,KAAK,GAAG,SAAS,IAChD,EAAE,IAAI,KAAK,GAAG,IACd,CAAC;AAAA,IACL;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ;AACV,QAAI,QAAQ;AACZ,QAAI;AAEJ,QAAI,MAAM;AACR,oBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,QACvD,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAEA,UAAMA,YAAW,MAAM,MAAM,OAAO,QAAQ;AAC5C,qBAAiB,SAASA,WAAU;AAClC,YAAM,OAAO,YAAY,KAAK;AAC9B,UAAI,CAAC,KAAM;AACX,eAAS;AACT,WAAK,cAAc,IAAI;AACvB,UAAI,OAAO,UAAU,YAAY,SAAS,SAAS,OAAO;AACxD,cAAO,MAA4B;AAAA,MACrC;AACA,UAAI,MAAM;AACR,sBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,UACvD,GAAG;AAAA,UACH,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,MAAM;AACR,oBAAc,KAAK,WAAW,KAAK,QAAQ,YAAY;AAAA,QACrD,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,GAAI,QAAQ,SAAY,EAAE,IAAI,IAAI,CAAC;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,MAAM,OAAO,QAAQ;AAE5C,MAAI,MAAM;AACR,kBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,MACvD,GAAG;AAAA,IACL,CAAC;AACD,QAAI,SAAS,SAAS;AACpB,oBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,QACvD,GAAG;AAAA,QACH,OAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH;AACA,kBAAc,KAAK,WAAW,KAAK,QAAQ,YAAY;AAAA,MACrD,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf,GAAI,SAAS,QAAQ,SAAY,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC;AAAA,EAC5D;AACF;","names":["response"]}
|