@kortyx/hooks 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.1](https://github.com/kortyx-io/kortyx/compare/hooks-v0.4.0...hooks-v0.4.1) (2026-02-17)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **build:** align package tsconfig with shared lib baseline ([48d2b57](https://github.com/kortyx-io/kortyx/commit/48d2b5765fefbb5fcbbe548e749e7b5f51b450b9))
9
+ * **build:** wire tsup for publishable packages ([e7b1b5c](https://github.com/kortyx-io/kortyx/commit/e7b1b5c28af55becffc137233dd92d8953d7cb8e))
10
+ * **dev:** restore tsc watch flow for local workspace ([4305823](https://github.com/kortyx-io/kortyx/commit/430582372cad466bf28af554042aa11bdb8bf027))
11
+
12
+ ## [0.4.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.3.0...hooks-v0.4.0) (2026-02-17)
13
+
14
+
15
+ ### Features
16
+
17
+ * **agent:** strict createAgent and unify useReason streaming ([6725f97](https://github.com/kortyx-io/kortyx/commit/6725f976fc32083fb7d2590f1353d16a99afb46f))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **hooks:** move reason engine to internal subpath export ([b82f2f2](https://github.com/kortyx-io/kortyx/commit/b82f2f2a93067f91dd010334486eb0f3a3a547b8))
23
+
3
24
  ## [0.3.0](https://github.com/kortyx-io/Kortyx/compare/hooks-v0.2.3...hooks-v0.3.0) (2026-02-07)
4
25
 
5
26
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,41 @@
1
- export type { HookRuntimeContext } from "./context";
2
- export { runWithHookContext } from "./context";
3
- export { useAiInterrupt, useAiMemory, useAiProvider, useEmit, useNodeState, useStructuredData, useWorkflowState, } from "./hooks";
4
- //# sourceMappingURL=index.d.ts.map
1
+ import { NodeContext, GraphState, InterruptInput, InterruptResult } from '@kortyx/core';
2
+ import { MemoryAdapter } from '@kortyx/memory';
3
+ import { GetProviderFn, ProviderModelRef } from '@kortyx/providers';
4
+
5
+ type HookRuntimeContext = {
6
+ node: NodeContext;
7
+ state: GraphState;
8
+ getProvider?: GetProviderFn;
9
+ memoryAdapter?: MemoryAdapter;
10
+ };
11
+ declare function runWithHookContext<T>(ctx: HookRuntimeContext, fn: () => Promise<T>): Promise<{
12
+ result: T;
13
+ memoryUpdates: Record<string, unknown> | null;
14
+ }>;
15
+
16
+ type StateSetter<T> = (next: T | ((prev: T) => T)) => void;
17
+ type UseReasonArgs = {
18
+ model: ProviderModelRef;
19
+ input: string;
20
+ system?: string | undefined;
21
+ temperature?: number | undefined;
22
+ emit?: boolean | undefined;
23
+ stream?: boolean | undefined;
24
+ };
25
+ type UseReasonResult = {
26
+ text: string;
27
+ raw?: unknown;
28
+ };
29
+ declare function useEmit(): NodeContext["emit"];
30
+ declare function useStructuredData(args: {
31
+ data: unknown;
32
+ dataType?: string | undefined;
33
+ }): void;
34
+ declare function useReason(args: UseReasonArgs): Promise<UseReasonResult>;
35
+ declare function useAiMemory(): MemoryAdapter;
36
+ declare function useAiInterrupt(input: InterruptInput): Promise<InterruptResult>;
37
+ declare function useNodeState<T>(initialValue: T): [T, StateSetter<T>];
38
+ declare function useNodeState<T>(key: string, initialValue?: T): [T, StateSetter<T>];
39
+ declare function useWorkflowState<T>(key: string, initialValue?: T): [T, StateSetter<T>];
40
+
41
+ export { type HookRuntimeContext, type UseReasonArgs, type UseReasonResult, runWithHookContext, useAiInterrupt, useAiMemory, useEmit, useNodeState, useReason, useStructuredData, useWorkflowState };
package/dist/index.js CHANGED
@@ -1,13 +1,284 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useWorkflowState = exports.useStructuredData = exports.useNodeState = exports.useEmit = exports.useAiProvider = exports.useAiMemory = exports.useAiInterrupt = exports.runWithHookContext = void 0;
4
- var context_1 = require("./context");
5
- Object.defineProperty(exports, "runWithHookContext", { enumerable: true, get: function () { return context_1.runWithHookContext; } });
6
- var hooks_1 = require("./hooks");
7
- Object.defineProperty(exports, "useAiInterrupt", { enumerable: true, get: function () { return hooks_1.useAiInterrupt; } });
8
- Object.defineProperty(exports, "useAiMemory", { enumerable: true, get: function () { return hooks_1.useAiMemory; } });
9
- Object.defineProperty(exports, "useAiProvider", { enumerable: true, get: function () { return hooks_1.useAiProvider; } });
10
- Object.defineProperty(exports, "useEmit", { enumerable: true, get: function () { return hooks_1.useEmit; } });
11
- Object.defineProperty(exports, "useNodeState", { enumerable: true, get: function () { return hooks_1.useNodeState; } });
12
- Object.defineProperty(exports, "useStructuredData", { enumerable: true, get: function () { return hooks_1.useStructuredData; } });
13
- Object.defineProperty(exports, "useWorkflowState", { enumerable: true, get: function () { return hooks_1.useWorkflowState; } });
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ runWithHookContext: () => runWithHookContext,
23
+ useAiInterrupt: () => useAiInterrupt,
24
+ useAiMemory: () => useAiMemory,
25
+ useEmit: () => useEmit,
26
+ useNodeState: () => useNodeState,
27
+ useReason: () => useReason,
28
+ useStructuredData: () => useStructuredData,
29
+ useWorkflowState: () => useWorkflowState
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/context.ts
34
+ var import_node_async_hooks = require("async_hooks");
35
+ var storage = new import_node_async_hooks.AsyncLocalStorage();
36
+ var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
37
+ var normalizeNodeState = (value) => {
38
+ if (Array.isArray(value)) {
39
+ return { byIndex: [...value], byKey: {} };
40
+ }
41
+ if (isRecord(value)) {
42
+ const byIndex = Array.isArray(value.byIndex) ? [...value.byIndex] : [];
43
+ const byKey = isRecord(value.byKey) ? { ...value.byKey } : {};
44
+ return { byIndex, byKey };
45
+ }
46
+ return { byIndex: [], byKey: {} };
47
+ };
48
+ var cloneWorkflowState = (value) => isRecord(value) ? { ...value } : {};
49
+ var getHookMemory = (state) => {
50
+ const memory = state.memory ?? {};
51
+ const internal = isRecord(memory.__kortyx) ? memory.__kortyx : void 0;
52
+ const result = {};
53
+ if (isRecord(internal?.nodeState)) result.nodeState = internal?.nodeState;
54
+ if (isRecord(internal?.workflowState)) {
55
+ result.workflowState = internal?.workflowState;
56
+ }
57
+ return result;
58
+ };
59
+ var createInternalContext = (ctx) => {
60
+ const hookMemory = getHookMemory(ctx.state);
61
+ const nodeId = ctx.node.graph.node;
62
+ const storedNodeId = typeof hookMemory.nodeState?.nodeId === "string" ? String(hookMemory.nodeState?.nodeId) : "";
63
+ const storedState = hookMemory.nodeState?.state;
64
+ const currentNodeState = storedNodeId && storedNodeId === nodeId ? normalizeNodeState(storedState) : { byIndex: [], byKey: {} };
65
+ return {
66
+ ...ctx,
67
+ nodeStateIndex: 0,
68
+ currentNodeState,
69
+ workflowState: cloneWorkflowState(hookMemory.workflowState),
70
+ dirty: false
71
+ };
72
+ };
73
+ var buildMemoryUpdates = (ctx) => {
74
+ if (!ctx.dirty) return null;
75
+ return {
76
+ __kortyx: {
77
+ nodeState: {
78
+ nodeId: ctx.node.graph.node,
79
+ state: ctx.currentNodeState
80
+ },
81
+ workflowState: ctx.workflowState
82
+ }
83
+ };
84
+ };
85
+ async function runWithHookContext(ctx, fn) {
86
+ const internal = createInternalContext(ctx);
87
+ try {
88
+ const result = await storage.run(internal, fn);
89
+ return { result, memoryUpdates: buildMemoryUpdates(internal) };
90
+ } catch (err) {
91
+ const memoryUpdates = buildMemoryUpdates(internal);
92
+ if (memoryUpdates && err && typeof err === "object") {
93
+ err.__kortyxMemoryUpdates = memoryUpdates;
94
+ }
95
+ throw err;
96
+ }
97
+ }
98
+ function getHookContext() {
99
+ const ctx = storage.getStore();
100
+ if (!ctx) {
101
+ throw new Error("Hooks can only be used while a node is executing.");
102
+ }
103
+ return ctx;
104
+ }
105
+
106
+ // src/reason-engine.ts
107
+ var chunkToText = (chunk) => {
108
+ if (typeof chunk === "string") return chunk;
109
+ if (typeof chunk.text === "string") return chunk.text;
110
+ if (typeof chunk.content === "string") return chunk.content;
111
+ return "";
112
+ };
113
+ var emitNodeEvent = (emitEvent, nodeId, event, payload) => {
114
+ if (!emitEvent) return;
115
+ emitEvent(event, {
116
+ ...payload,
117
+ ...typeof nodeId === "string" && nodeId.length > 0 ? { node: nodeId } : {}
118
+ });
119
+ };
120
+ async function runReasonEngine(args) {
121
+ const stream = args.stream ?? args.model.options?.streaming ?? true;
122
+ const emit = args.emit ?? true;
123
+ const temperature = args.temperature ?? args.model.options?.temperature ?? args.defaultTemperature;
124
+ const model = args.getProvider(args.model.providerId, args.model.modelId, {
125
+ ...temperature !== void 0 ? { temperature } : {},
126
+ streaming: stream
127
+ });
128
+ const messages = [];
129
+ if (typeof args.system === "string" && args.system.length > 0) {
130
+ messages.push({ role: "system", content: args.system });
131
+ }
132
+ messages.push({ role: "user", content: String(args.input ?? "") });
133
+ if (stream) {
134
+ let final = "";
135
+ let raw;
136
+ if (emit) {
137
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-start", {});
138
+ }
139
+ const response2 = await model.stream(messages);
140
+ for await (const chunk of response2) {
141
+ const text = chunkToText(chunk);
142
+ if (!text) continue;
143
+ final += text;
144
+ if (typeof chunk === "object" && chunk && "raw" in chunk) {
145
+ raw = chunk.raw;
146
+ }
147
+ if (emit) {
148
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-delta", {
149
+ delta: text
150
+ });
151
+ }
152
+ }
153
+ if (emit) {
154
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {});
155
+ }
156
+ return {
157
+ text: final,
158
+ ...raw !== void 0 ? { raw } : {}
159
+ };
160
+ }
161
+ const response = await model.invoke(messages);
162
+ if (emit) {
163
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-start", {});
164
+ if (response.content) {
165
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-delta", {
166
+ delta: response.content
167
+ });
168
+ }
169
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {});
170
+ }
171
+ return {
172
+ text: response.content,
173
+ ...response.raw !== void 0 ? { raw: response.raw } : {}
174
+ };
175
+ }
176
+
177
+ // src/hooks.ts
178
+ function useEmit() {
179
+ const ctx = getHookContext();
180
+ return ctx.node.emit;
181
+ }
182
+ function useStructuredData(args) {
183
+ const ctx = getHookContext();
184
+ ctx.node.emit("structured_data", {
185
+ node: ctx.node.graph.node,
186
+ ...typeof args.dataType === "string" && args.dataType.length > 0 ? { dataType: args.dataType } : {},
187
+ data: args.data
188
+ });
189
+ }
190
+ async function reasonEngine(args) {
191
+ const ctx = getHookContext();
192
+ const getProvider = ctx.getProvider;
193
+ if (!getProvider) {
194
+ throw new Error("useReason requires a provider factory in runtime config.");
195
+ }
196
+ return runReasonEngine({
197
+ getProvider,
198
+ model: args.model,
199
+ input: args.input,
200
+ system: args.system,
201
+ temperature: args.temperature,
202
+ defaultTemperature: ctx.node.config?.model?.temperature,
203
+ stream: args.stream,
204
+ emit: args.emit,
205
+ nodeId: ctx.node.graph.node,
206
+ emitEvent: ctx.node.emit
207
+ });
208
+ }
209
+ function useReason(args) {
210
+ return reasonEngine(args);
211
+ }
212
+ function useAiMemory() {
213
+ const ctx = getHookContext();
214
+ if (!ctx.memoryAdapter) {
215
+ throw new Error("useAiMemory requires a memory adapter in runtime config.");
216
+ }
217
+ return ctx.memoryAdapter;
218
+ }
219
+ function useAiInterrupt(input) {
220
+ const ctx = getHookContext();
221
+ return Promise.resolve(ctx.node.awaitInterrupt(input));
222
+ }
223
+ function useNodeState(keyOrInitial, initialValue) {
224
+ const ctx = getHookContext();
225
+ const nodeState = ctx.currentNodeState;
226
+ if (typeof keyOrInitial === "string") {
227
+ const key = keyOrInitial;
228
+ const hasInitial = arguments.length > 1;
229
+ if (!Object.hasOwn(nodeState.byKey, key) && hasInitial) {
230
+ nodeState.byKey[key] = initialValue;
231
+ ctx.dirty = true;
232
+ }
233
+ const getValue2 = () => nodeState.byKey[key];
234
+ const setValue2 = (next) => {
235
+ const prev = getValue2();
236
+ const resolved = typeof next === "function" ? next(prev) : next;
237
+ nodeState.byKey[key] = resolved;
238
+ ctx.dirty = true;
239
+ };
240
+ return [getValue2(), setValue2];
241
+ }
242
+ const index = ctx.nodeStateIndex++;
243
+ if (index >= nodeState.byIndex.length) {
244
+ nodeState.byIndex[index] = keyOrInitial;
245
+ ctx.dirty = true;
246
+ }
247
+ const getValue = () => nodeState.byIndex[index];
248
+ const setValue = (next) => {
249
+ const prev = getValue();
250
+ const resolved = typeof next === "function" ? next(prev) : next;
251
+ nodeState.byIndex[index] = resolved;
252
+ ctx.dirty = true;
253
+ };
254
+ return [getValue(), setValue];
255
+ }
256
+ function useWorkflowState(key, initialValue) {
257
+ const ctx = getHookContext();
258
+ const workflowState = ctx.workflowState;
259
+ const hasInitial = arguments.length > 1;
260
+ if (!Object.hasOwn(workflowState, key) && hasInitial) {
261
+ workflowState[key] = initialValue;
262
+ ctx.dirty = true;
263
+ }
264
+ const getValue = () => workflowState[key];
265
+ const setValue = (next) => {
266
+ const prev = getValue();
267
+ const resolved = typeof next === "function" ? next(prev) : next;
268
+ workflowState[key] = resolved;
269
+ ctx.dirty = true;
270
+ };
271
+ return [getValue(), setValue];
272
+ }
273
+ // Annotate the CommonJS export names for ESM import in node:
274
+ 0 && (module.exports = {
275
+ runWithHookContext,
276
+ useAiInterrupt,
277
+ useAiMemory,
278
+ useEmit,
279
+ useNodeState,
280
+ useReason,
281
+ useStructuredData,
282
+ useWorkflowState
283
+ });
284
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/reason-engine.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 { UseReasonArgs, UseReasonResult } from \"./hooks\";\nexport {\n useAiInterrupt,\n useAiMemory,\n useEmit,\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 { MemoryAdapter } from \"@kortyx/memory\";\nimport type { GetProviderFn } from \"@kortyx/providers\";\n\ntype NodeStateStore = {\n byIndex: unknown[];\n byKey: Record<string, unknown>;\n};\n\ntype HookMemory = {\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 memoryAdapter?: MemoryAdapter;\n};\n\ntype HookInternalContext = HookRuntimeContext & {\n nodeStateIndex: 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 getHookMemory = (state: GraphState): HookMemory => {\n const memory = (state.memory ?? {}) as Record<string, unknown>;\n const internal = isRecord(memory.__kortyx) ? memory.__kortyx : undefined;\n const result: HookMemory = {};\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 hookMemory = getHookMemory(ctx.state);\n const nodeId = ctx.node.graph.node;\n const storedNodeId =\n typeof (hookMemory.nodeState as any)?.nodeId === \"string\"\n ? String((hookMemory.nodeState as any)?.nodeId)\n : \"\";\n const storedState = (hookMemory.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 currentNodeState,\n workflowState: cloneWorkflowState(hookMemory.workflowState),\n dirty: false,\n };\n};\n\nconst buildMemoryUpdates = (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; memoryUpdates: Record<string, unknown> | null }> {\n const internal = createInternalContext(ctx);\n try {\n const result = await storage.run(internal, fn);\n return { result, memoryUpdates: buildMemoryUpdates(internal) };\n } catch (err) {\n const memoryUpdates = buildMemoryUpdates(internal);\n if (memoryUpdates && err && typeof err === \"object\") {\n (err as any).__kortyxMemoryUpdates = memoryUpdates;\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 {\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}\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 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 if (stream) {\n let final = \"\";\n let raw: unknown;\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {});\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 delta: text,\n });\n }\n }\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {});\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 if (response.content) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n delta: response.content,\n });\n }\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {});\n }\n\n return {\n text: response.content,\n ...(response.raw !== undefined ? { raw: response.raw } : {}),\n };\n}\n","import type {\n InterruptInput,\n InterruptResult,\n NodeContext,\n} from \"@kortyx/core\";\nimport type { MemoryAdapter } from \"@kortyx/memory\";\nimport type { ProviderModelRef } from \"@kortyx/providers\";\nimport { getHookContext } from \"./context\";\nimport type { RunReasonEngineResult } from \"./reason-engine\";\nimport { runReasonEngine } from \"./reason-engine\";\n\ntype StateSetter<T> = (next: T | ((prev: T) => T)) => void;\n\nexport type UseReasonArgs = {\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 type UseReasonResult = {\n text: string;\n raw?: unknown;\n};\n\nexport function useEmit(): NodeContext[\"emit\"] {\n const ctx = getHookContext();\n return ctx.node.emit;\n}\n\nexport function useStructuredData(args: {\n data: unknown;\n dataType?: string | undefined;\n}): void {\n const ctx = getHookContext();\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 data: args.data,\n });\n}\n\nasync function reasonEngine(\n args: UseReasonArgs,\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: 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 });\n}\n\nexport function useReason(args: UseReasonArgs): Promise<UseReasonResult> {\n return reasonEngine(args);\n}\n\nexport function useAiMemory(): MemoryAdapter {\n const ctx = getHookContext();\n if (!ctx.memoryAdapter) {\n throw new Error(\"useAiMemory requires a memory adapter in runtime config.\");\n }\n return ctx.memoryAdapter;\n}\n\nexport function useAiInterrupt(\n input: InterruptInput,\n): Promise<InterruptResult> {\n const ctx = getHookContext();\n return Promise.resolve(ctx.node.awaitInterrupt(input));\n}\n\nexport function useNodeState<T>(initialValue: T): [T, StateSetter<T>];\nexport function useNodeState<T>(\n key: string,\n initialValue?: T,\n): [T, StateSetter<T>];\nexport function useNodeState<T>(\n keyOrInitial: string | T,\n initialValue?: T,\n): [T, StateSetter<T>] {\n const ctx = getHookContext();\n const nodeState = ctx.currentNodeState;\n\n if (typeof keyOrInitial === \"string\") {\n const key = keyOrInitial;\n const hasInitial = arguments.length > 1;\n\n if (!Object.hasOwn(nodeState.byKey, key) && hasInitial) {\n nodeState.byKey[key] = initialValue as T;\n ctx.dirty = true;\n }\n\n const getValue = () => nodeState.byKey[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 nodeState.byKey[key] = resolved;\n ctx.dirty = true;\n };\n\n return [getValue(), setValue];\n }\n\n const index = ctx.nodeStateIndex++;\n if (index >= nodeState.byIndex.length) {\n nodeState.byIndex[index] = keyOrInitial 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":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,8BAAkC;AA6BlC,IAAM,UAAU,IAAI,0CAAuC;AAE3D,IAAM,WAAW,CAAC,UAChB,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,qBAAqB,CAAC,UAAmC;AAC7D,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,EAAE,SAAS,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC,EAAE;AAAA,EAC1C;AAEA,MAAI,SAAS,KAAK,GAAG;AACnB,UAAM,UAAU,MAAM,QAAQ,MAAM,OAAO,IAAI,CAAC,GAAG,MAAM,OAAO,IAAI,CAAC;AACrE,UAAM,QAAQ,SAAS,MAAM,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,IAAI,CAAC;AAC5D,WAAO,EAAE,SAAS,MAAM;AAAA,EAC1B;AAEA,SAAO,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,EAAE;AAClC;AAEA,IAAM,qBAAqB,CAAC,UAC1B,SAAS,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC;AAEpC,IAAM,gBAAgB,CAAC,UAAkC;AACvD,QAAM,SAAU,MAAM,UAAU,CAAC;AACjC,QAAM,WAAW,SAAS,OAAO,QAAQ,IAAI,OAAO,WAAW;AAC/D,QAAM,SAAqB,CAAC;AAC5B,MAAI,SAAS,UAAU,SAAS,EAAG,QAAO,YAAY,UAAU;AAChE,MAAI,SAAS,UAAU,aAAa,GAAG;AACrC,WAAO,gBAAgB,UAAU;AAAA,EACnC;AACA,SAAO;AACT;AAEA,IAAM,wBAAwB,CAC5B,QACwB;AACxB,QAAM,aAAa,cAAc,IAAI,KAAK;AAC1C,QAAM,SAAS,IAAI,KAAK,MAAM;AAC9B,QAAM,eACJ,OAAQ,WAAW,WAAmB,WAAW,WAC7C,OAAQ,WAAW,WAAmB,MAAM,IAC5C;AACN,QAAM,cAAe,WAAW,WAAmB;AACnD,QAAM,mBACJ,gBAAgB,iBAAiB,SAC7B,mBAAmB,WAAW,IAC9B,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,EAAE;AAE/B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,gBAAgB;AAAA,IAChB;AAAA,IACA,eAAe,mBAAmB,WAAW,aAAa;AAAA,IAC1D,OAAO;AAAA,EACT;AACF;AAEA,IAAM,qBAAqB,CAAC,QAA6B;AACvD,MAAI,CAAC,IAAI,MAAO,QAAO;AACvB,SAAO;AAAA,IACL,UAAU;AAAA,MACR,WAAW;AAAA,QACT,QAAQ,IAAI,KAAK,MAAM;AAAA,QACvB,OAAO,IAAI;AAAA,MACb;AAAA,MACA,eAAe,IAAI;AAAA,IACrB;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,KACA,IACuE;AACvE,QAAM,WAAW,sBAAsB,GAAG;AAC1C,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,IAAI,UAAU,EAAE;AAC7C,WAAO,EAAE,QAAQ,eAAe,mBAAmB,QAAQ,EAAE;AAAA,EAC/D,SAAS,KAAK;AACZ,UAAM,gBAAgB,mBAAmB,QAAQ;AACjD,QAAI,iBAAiB,OAAO,OAAO,QAAQ,UAAU;AACnD,MAAC,IAAY,wBAAwB;AAAA,IACvC;AACA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,iBAAsC;AACpD,QAAM,MAAM,QAAQ,SAAS;AAC7B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AACA,SAAO;AACT;;;ACjGA,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,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,MAAI,QAAQ;AACV,QAAI,QAAQ;AACZ,QAAI;AAEJ,QAAI,MAAM;AACR,oBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc,CAAC,CAAC;AAAA,IAC7D;AAEA,UAAMA,YAAW,MAAM,MAAM,OAAO,QAAQ;AAC5C,qBAAiB,SAASA,WAAU;AAClC,YAAM,OAAO,YAAY,KAAK;AAC9B,UAAI,CAAC,KAAM;AACX,eAAS;AACT,UAAI,OAAO,UAAU,YAAY,SAAS,SAAS,OAAO;AACxD,cAAO,MAA4B;AAAA,MACrC;AACA,UAAI,MAAM;AACR,sBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,UACvD,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,MAAM;AACR,oBAAc,KAAK,WAAW,KAAK,QAAQ,YAAY,CAAC,CAAC;AAAA,IAC3D;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,CAAC,CAAC;AAC3D,QAAI,SAAS,SAAS;AACpB,oBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,QACvD,OAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH;AACA,kBAAc,KAAK,WAAW,KAAK,QAAQ,YAAY,CAAC,CAAC;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf,GAAI,SAAS,QAAQ,SAAY,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC;AAAA,EAC5D;AACF;;;AC1FO,SAAS,UAA+B;AAC7C,QAAM,MAAM,eAAe;AAC3B,SAAO,IAAI,KAAK;AAClB;AAEO,SAAS,kBAAkB,MAGzB;AACP,QAAM,MAAM,eAAe;AAC3B,MAAI,KAAK,KAAK,mBAAmB;AAAA,IAC/B,MAAM,IAAI,KAAK,MAAM;AAAA,IACrB,GAAI,OAAO,KAAK,aAAa,YAAY,KAAK,SAAS,SAAS,IAC5D,EAAE,UAAU,KAAK,SAAS,IAC1B,CAAC;AAAA,IACL,MAAM,KAAK;AAAA,EACb,CAAC;AACH;AAEA,eAAe,aACb,MACgC;AAChC,QAAM,MAAM,eAAe;AAC3B,QAAM,cAAc,IAAI;AACxB,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAEA,SAAO,gBAAgB;AAAA,IACrB;AAAA,IACA,OAAO,KAAK;AAAA,IACZ,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb,aAAa,KAAK;AAAA,IAClB,oBAAoB,IAAI,KAAK,QAAQ,OAAO;AAAA,IAC5C,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,IACX,QAAQ,IAAI,KAAK,MAAM;AAAA,IACvB,WAAW,IAAI,KAAK;AAAA,EACtB,CAAC;AACH;AAEO,SAAS,UAAU,MAA+C;AACvE,SAAO,aAAa,IAAI;AAC1B;AAEO,SAAS,cAA6B;AAC3C,QAAM,MAAM,eAAe;AAC3B,MAAI,CAAC,IAAI,eAAe;AACtB,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO,IAAI;AACb;AAEO,SAAS,eACd,OAC0B;AAC1B,QAAM,MAAM,eAAe;AAC3B,SAAO,QAAQ,QAAQ,IAAI,KAAK,eAAe,KAAK,CAAC;AACvD;AAOO,SAAS,aACd,cACA,cACqB;AACrB,QAAM,MAAM,eAAe;AAC3B,QAAM,YAAY,IAAI;AAEtB,MAAI,OAAO,iBAAiB,UAAU;AACpC,UAAM,MAAM;AACZ,UAAM,aAAa,UAAU,SAAS;AAEtC,QAAI,CAAC,OAAO,OAAO,UAAU,OAAO,GAAG,KAAK,YAAY;AACtD,gBAAU,MAAM,GAAG,IAAI;AACvB,UAAI,QAAQ;AAAA,IACd;AAEA,UAAMC,YAAW,MAAM,UAAU,MAAM,GAAG;AAC1C,UAAMC,YAA2B,CAAC,SAAS;AACzC,YAAM,OAAOD,UAAS;AACtB,YAAM,WACJ,OAAO,SAAS,aAAc,KAAqB,IAAI,IAAI;AAC7D,gBAAU,MAAM,GAAG,IAAI;AACvB,UAAI,QAAQ;AAAA,IACd;AAEA,WAAO,CAACA,UAAS,GAAGC,SAAQ;AAAA,EAC9B;AAEA,QAAM,QAAQ,IAAI;AAClB,MAAI,SAAS,UAAU,QAAQ,QAAQ;AACrC,cAAU,QAAQ,KAAK,IAAI;AAC3B,QAAI,QAAQ;AAAA,EACd;AAEA,QAAM,WAAW,MAAM,UAAU,QAAQ,KAAK;AAC9C,QAAM,WAA2B,CAAC,SAAS;AACzC,UAAM,OAAO,SAAS;AACtB,UAAM,WACJ,OAAO,SAAS,aAAc,KAAqB,IAAI,IAAI;AAC7D,cAAU,QAAQ,KAAK,IAAI;AAC3B,QAAI,QAAQ;AAAA,EACd;AAEA,SAAO,CAAC,SAAS,GAAG,QAAQ;AAC9B;AAEO,SAAS,iBACd,KACA,cACqB;AACrB,QAAM,MAAM,eAAe;AAC3B,QAAM,gBAAgB,IAAI;AAC1B,QAAM,aAAa,UAAU,SAAS;AAEtC,MAAI,CAAC,OAAO,OAAO,eAAe,GAAG,KAAK,YAAY;AACpD,kBAAc,GAAG,IAAI;AACrB,QAAI,QAAQ;AAAA,EACd;AAEA,QAAM,WAAW,MAAM,cAAc,GAAG;AACxC,QAAM,WAA2B,CAAC,SAAS;AACzC,UAAM,OAAO,SAAS;AACtB,UAAM,WACJ,OAAO,SAAS,aAAc,KAAqB,IAAI,IAAI;AAC7D,kBAAc,GAAG,IAAI;AACrB,QAAI,QAAQ;AAAA,EACd;AAEA,SAAO,CAAC,SAAS,GAAG,QAAQ;AAC9B;","names":["response","getValue","setValue"]}
@@ -0,0 +1,21 @@
1
+ import { GetProviderFn, ProviderModelRef } from '@kortyx/providers';
2
+
3
+ interface RunReasonEngineArgs {
4
+ getProvider: GetProviderFn;
5
+ model: ProviderModelRef;
6
+ input: string;
7
+ system?: string | undefined;
8
+ temperature?: number | undefined;
9
+ defaultTemperature?: number | undefined;
10
+ stream?: boolean | undefined;
11
+ emit?: boolean | undefined;
12
+ nodeId?: string | undefined;
13
+ emitEvent?: ((event: string, payload: unknown) => void) | undefined;
14
+ }
15
+ interface RunReasonEngineResult {
16
+ text: string;
17
+ raw?: unknown;
18
+ }
19
+ declare function runReasonEngine(args: RunReasonEngineArgs): Promise<RunReasonEngineResult>;
20
+
21
+ export { type RunReasonEngineArgs, type RunReasonEngineResult, runReasonEngine };
@@ -0,0 +1,100 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/internal.ts
20
+ var internal_exports = {};
21
+ __export(internal_exports, {
22
+ runReasonEngine: () => runReasonEngine
23
+ });
24
+ module.exports = __toCommonJS(internal_exports);
25
+
26
+ // src/reason-engine.ts
27
+ var chunkToText = (chunk) => {
28
+ if (typeof chunk === "string") return chunk;
29
+ if (typeof chunk.text === "string") return chunk.text;
30
+ if (typeof chunk.content === "string") return chunk.content;
31
+ return "";
32
+ };
33
+ var emitNodeEvent = (emitEvent, nodeId, event, payload) => {
34
+ if (!emitEvent) return;
35
+ emitEvent(event, {
36
+ ...payload,
37
+ ...typeof nodeId === "string" && nodeId.length > 0 ? { node: nodeId } : {}
38
+ });
39
+ };
40
+ async function runReasonEngine(args) {
41
+ const stream = args.stream ?? args.model.options?.streaming ?? true;
42
+ const emit = args.emit ?? true;
43
+ const temperature = args.temperature ?? args.model.options?.temperature ?? args.defaultTemperature;
44
+ const model = args.getProvider(args.model.providerId, args.model.modelId, {
45
+ ...temperature !== void 0 ? { temperature } : {},
46
+ streaming: stream
47
+ });
48
+ const messages = [];
49
+ if (typeof args.system === "string" && args.system.length > 0) {
50
+ messages.push({ role: "system", content: args.system });
51
+ }
52
+ messages.push({ role: "user", content: String(args.input ?? "") });
53
+ if (stream) {
54
+ let final = "";
55
+ let raw;
56
+ if (emit) {
57
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-start", {});
58
+ }
59
+ const response2 = await model.stream(messages);
60
+ for await (const chunk of response2) {
61
+ const text = chunkToText(chunk);
62
+ if (!text) continue;
63
+ final += text;
64
+ if (typeof chunk === "object" && chunk && "raw" in chunk) {
65
+ raw = chunk.raw;
66
+ }
67
+ if (emit) {
68
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-delta", {
69
+ delta: text
70
+ });
71
+ }
72
+ }
73
+ if (emit) {
74
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {});
75
+ }
76
+ return {
77
+ text: final,
78
+ ...raw !== void 0 ? { raw } : {}
79
+ };
80
+ }
81
+ const response = await model.invoke(messages);
82
+ if (emit) {
83
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-start", {});
84
+ if (response.content) {
85
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-delta", {
86
+ delta: response.content
87
+ });
88
+ }
89
+ emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {});
90
+ }
91
+ return {
92
+ text: response.content,
93
+ ...response.raw !== void 0 ? { raw: response.raw } : {}
94
+ };
95
+ }
96
+ // Annotate the CommonJS export names for ESM import in node:
97
+ 0 && (module.exports = {
98
+ runReasonEngine
99
+ });
100
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +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 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}\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 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 if (stream) {\n let final = \"\";\n let raw: unknown;\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-start\", {});\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 delta: text,\n });\n }\n }\n\n if (emit) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {});\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 if (response.content) {\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-delta\", {\n delta: response.content,\n });\n }\n emitNodeEvent(args.emitEvent, args.nodeId, \"text-end\", {});\n }\n\n return {\n text: response.content,\n ...(response.raw !== undefined ? { raw: response.raw } : {}),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACyBA,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,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,MAAI,QAAQ;AACV,QAAI,QAAQ;AACZ,QAAI;AAEJ,QAAI,MAAM;AACR,oBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc,CAAC,CAAC;AAAA,IAC7D;AAEA,UAAMA,YAAW,MAAM,MAAM,OAAO,QAAQ;AAC5C,qBAAiB,SAASA,WAAU;AAClC,YAAM,OAAO,YAAY,KAAK;AAC9B,UAAI,CAAC,KAAM;AACX,eAAS;AACT,UAAI,OAAO,UAAU,YAAY,SAAS,SAAS,OAAO;AACxD,cAAO,MAA4B;AAAA,MACrC;AACA,UAAI,MAAM;AACR,sBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,UACvD,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,MAAM;AACR,oBAAc,KAAK,WAAW,KAAK,QAAQ,YAAY,CAAC,CAAC;AAAA,IAC3D;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,CAAC,CAAC;AAC3D,QAAI,SAAS,SAAS;AACpB,oBAAc,KAAK,WAAW,KAAK,QAAQ,cAAc;AAAA,QACvD,OAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH;AACA,kBAAc,KAAK,WAAW,KAAK,QAAQ,YAAY,CAAC,CAAC;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf,GAAI,SAAS,QAAQ,SAAY,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC;AAAA,EAC5D;AACF;","names":["response"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kortyx/hooks",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "private": false,
5
5
  "description": "Lifecycle hooks and extension points for Kortyx.",
6
6
  "keywords": [
@@ -13,7 +13,7 @@
13
13
  "kortyx"
14
14
  ],
15
15
  "license": "Apache-2.0",
16
- "homepage": "https://github.com/kortyx-io/kortyx/tree/main/packages/hooks#readme",
16
+ "homepage": "https://kortyx.io/",
17
17
  "bugs": {
18
18
  "url": "https://github.com/kortyx-io/kortyx/issues"
19
19
  },
@@ -24,6 +24,10 @@
24
24
  ".": {
25
25
  "types": "./dist/index.d.ts",
26
26
  "default": "./dist/index.js"
27
+ },
28
+ "./internal": {
29
+ "types": "./dist/internal.d.ts",
30
+ "default": "./dist/internal.js"
27
31
  }
28
32
  },
29
33
  "files": [
@@ -32,7 +36,7 @@
32
36
  "CHANGELOG.md"
33
37
  ],
34
38
  "scripts": {
35
- "build": "tsc -p tsconfig.build.json",
39
+ "build": "tsup",
36
40
  "predev": "tsc -p tsconfig.build.json",
37
41
  "dev": "tsc --watch",
38
42
  "lint": "biome check src",
@@ -46,12 +50,13 @@
46
50
  },
47
51
  "devDependencies": {
48
52
  "turbo": "^2.5.4",
49
- "typescript": "5.7.2"
53
+ "typescript": "5.7.2",
54
+ "tsup": "^8.5.1"
50
55
  },
51
56
  "sideEffects": false,
52
57
  "repository": {
53
58
  "type": "git",
54
- "url": "https://github.com/kortyx-io/kortyx",
59
+ "url": "https://github.com/kortyx-io/kortyx.git",
55
60
  "directory": "packages/hooks"
56
61
  }
57
62
  }
package/dist/context.d.ts DELETED
@@ -1,26 +0,0 @@
1
- import type { GraphState, NodeContext } from "@kortyx/core";
2
- import type { MemoryAdapter } from "@kortyx/memory";
3
- import type { GetProviderFn } from "@kortyx/providers";
4
- type NodeStateStore = {
5
- byIndex: unknown[];
6
- byKey: Record<string, unknown>;
7
- };
8
- export type HookRuntimeContext = {
9
- node: NodeContext;
10
- state: GraphState;
11
- getProvider?: GetProviderFn;
12
- memoryAdapter?: MemoryAdapter;
13
- };
14
- type HookInternalContext = HookRuntimeContext & {
15
- nodeStateIndex: number;
16
- currentNodeState: NodeStateStore;
17
- workflowState: Record<string, unknown>;
18
- dirty: boolean;
19
- };
20
- export declare function runWithHookContext<T>(ctx: HookRuntimeContext, fn: () => Promise<T>): Promise<{
21
- result: T;
22
- memoryUpdates: Record<string, unknown> | null;
23
- }>;
24
- export declare function getHookContext(): HookInternalContext;
25
- export {};
26
- //# sourceMappingURL=context.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAOF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF,KAAK,mBAAmB,GAAG,kBAAkB,GAAG;IAC9C,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,cAAc,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAwEF,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,GAAG,EAAE,kBAAkB,EACvB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAC,CAYvE;AAED,wBAAgB,cAAc,IAAI,mBAAmB,CAMpD"}
package/dist/context.js DELETED
@@ -1,82 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runWithHookContext = runWithHookContext;
4
- exports.getHookContext = getHookContext;
5
- const node_async_hooks_1 = require("node:async_hooks");
6
- const storage = new node_async_hooks_1.AsyncLocalStorage();
7
- const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
8
- const normalizeNodeState = (value) => {
9
- if (Array.isArray(value)) {
10
- return { byIndex: [...value], byKey: {} };
11
- }
12
- if (isRecord(value)) {
13
- const byIndex = Array.isArray(value.byIndex) ? [...value.byIndex] : [];
14
- const byKey = isRecord(value.byKey) ? { ...value.byKey } : {};
15
- return { byIndex, byKey };
16
- }
17
- return { byIndex: [], byKey: {} };
18
- };
19
- const cloneWorkflowState = (value) => isRecord(value) ? { ...value } : {};
20
- const getHookMemory = (state) => {
21
- const memory = (state.memory ?? {});
22
- const internal = isRecord(memory.__kortyx) ? memory.__kortyx : undefined;
23
- const result = {};
24
- if (isRecord(internal?.nodeState))
25
- result.nodeState = internal?.nodeState;
26
- if (isRecord(internal?.workflowState)) {
27
- result.workflowState = internal?.workflowState;
28
- }
29
- return result;
30
- };
31
- const createInternalContext = (ctx) => {
32
- const hookMemory = getHookMemory(ctx.state);
33
- const nodeId = ctx.node.graph.node;
34
- const storedNodeId = typeof hookMemory.nodeState?.nodeId === "string"
35
- ? String(hookMemory.nodeState?.nodeId)
36
- : "";
37
- const storedState = hookMemory.nodeState?.state;
38
- const currentNodeState = storedNodeId && storedNodeId === nodeId
39
- ? normalizeNodeState(storedState)
40
- : { byIndex: [], byKey: {} };
41
- return {
42
- ...ctx,
43
- nodeStateIndex: 0,
44
- currentNodeState,
45
- workflowState: cloneWorkflowState(hookMemory.workflowState),
46
- dirty: false,
47
- };
48
- };
49
- const buildMemoryUpdates = (ctx) => {
50
- if (!ctx.dirty)
51
- return null;
52
- return {
53
- __kortyx: {
54
- nodeState: {
55
- nodeId: ctx.node.graph.node,
56
- state: ctx.currentNodeState,
57
- },
58
- workflowState: ctx.workflowState,
59
- },
60
- };
61
- };
62
- async function runWithHookContext(ctx, fn) {
63
- const internal = createInternalContext(ctx);
64
- try {
65
- const result = await storage.run(internal, fn);
66
- return { result, memoryUpdates: buildMemoryUpdates(internal) };
67
- }
68
- catch (err) {
69
- const memoryUpdates = buildMemoryUpdates(internal);
70
- if (memoryUpdates && err && typeof err === "object") {
71
- err.__kortyxMemoryUpdates = memoryUpdates;
72
- }
73
- throw err;
74
- }
75
- }
76
- function getHookContext() {
77
- const ctx = storage.getStore();
78
- if (!ctx) {
79
- throw new Error("Hooks can only be used while a node is executing.");
80
- }
81
- return ctx;
82
- }
package/dist/hooks.d.ts DELETED
@@ -1,29 +0,0 @@
1
- import type { InterruptInput, InterruptResult, NodeContext } from "@kortyx/core";
2
- import type { MemoryAdapter } from "@kortyx/memory";
3
- type StateSetter<T> = (next: T | ((prev: T) => T)) => void;
4
- export type AiCallArgs = {
5
- prompt: string;
6
- system?: string | undefined;
7
- temperature?: number | undefined;
8
- emit?: boolean | undefined;
9
- stream?: boolean | undefined;
10
- };
11
- export type AiCallResult = {
12
- text: string;
13
- };
14
- export type AiModel = {
15
- call: (args: AiCallArgs) => Promise<AiCallResult>;
16
- };
17
- export declare function useEmit(): NodeContext["emit"];
18
- export declare function useStructuredData(args: {
19
- data: unknown;
20
- dataType?: string | undefined;
21
- }): void;
22
- export declare function useAiProvider(modelId?: string): AiModel;
23
- export declare function useAiMemory(): MemoryAdapter;
24
- export declare function useAiInterrupt(input: InterruptInput): Promise<InterruptResult>;
25
- export declare function useNodeState<T>(initialValue: T): [T, StateSetter<T>];
26
- export declare function useNodeState<T>(key: string, initialValue?: T): [T, StateSetter<T>];
27
- export declare function useWorkflowState<T>(key: string, initialValue?: T): [T, StateSetter<T>];
28
- export {};
29
- //# sourceMappingURL=hooks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,WAAW,EACZ,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;AA6C3D,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CACnD,CAAC;AAEF,wBAAgB,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAG7C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B,GAAG,IAAI,CASP;AAED,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAoCvD;AAED,wBAAgB,WAAW,IAAI,aAAa,CAM3C;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,wBAAgB,YAAY,CAAC,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,CAAC,GACf,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AA+CvB,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,CAAC,GACf,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAoBrB"}
package/dist/hooks.js DELETED
@@ -1,143 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useEmit = useEmit;
4
- exports.useStructuredData = useStructuredData;
5
- exports.useAiProvider = useAiProvider;
6
- exports.useAiMemory = useAiMemory;
7
- exports.useAiInterrupt = useAiInterrupt;
8
- exports.useNodeState = useNodeState;
9
- exports.useWorkflowState = useWorkflowState;
10
- const context_1 = require("./context");
11
- const DEFAULT_PROVIDER = "google";
12
- const DEFAULT_MODEL = "gemini-2.5-flash";
13
- const resolveModel = (modelId, config) => {
14
- const defaultProvider = config?.provider ?? DEFAULT_PROVIDER;
15
- const defaultModel = config?.name ?? DEFAULT_MODEL;
16
- if (!modelId) {
17
- return {
18
- provider: defaultProvider,
19
- name: defaultModel,
20
- temperature: config?.temperature,
21
- };
22
- }
23
- const separatorIndex = modelId.indexOf(":");
24
- if (separatorIndex === -1) {
25
- return {
26
- provider: defaultProvider,
27
- name: modelId,
28
- temperature: config?.temperature,
29
- };
30
- }
31
- const provider = modelId.slice(0, separatorIndex) || defaultProvider;
32
- const name = modelId.slice(separatorIndex + 1) || defaultModel;
33
- return {
34
- provider,
35
- name,
36
- temperature: config?.temperature,
37
- };
38
- };
39
- function useEmit() {
40
- const ctx = (0, context_1.getHookContext)();
41
- return ctx.node.emit;
42
- }
43
- function useStructuredData(args) {
44
- const ctx = (0, context_1.getHookContext)();
45
- ctx.node.emit("structured_data", {
46
- node: ctx.node.graph.node,
47
- ...(typeof args.dataType === "string" && args.dataType.length > 0
48
- ? { dataType: args.dataType }
49
- : {}),
50
- data: args.data,
51
- });
52
- }
53
- function useAiProvider(modelId) {
54
- const ctx = (0, context_1.getHookContext)();
55
- const getProvider = ctx.getProvider;
56
- if (!getProvider) {
57
- throw new Error("useAiProvider requires a provider factory in runtime config.");
58
- }
59
- const { provider, name, temperature } = resolveModel(modelId, ctx.node.config?.model);
60
- return {
61
- call: async ({ prompt, system, temperature: overrideTemperature }) => {
62
- if (!ctx.node.speak) {
63
- throw new Error("useAiProvider requires ctx.speak in NodeContext.");
64
- }
65
- const text = await ctx.node.speak({
66
- ...(typeof system === "string" && system.length > 0 ? { system } : {}),
67
- user: prompt,
68
- model: {
69
- provider,
70
- name,
71
- ...(overrideTemperature !== undefined
72
- ? { temperature: overrideTemperature }
73
- : temperature !== undefined
74
- ? { temperature }
75
- : {}),
76
- },
77
- stream: { minChars: 12, flushMs: 50, segmentChars: 48 },
78
- });
79
- return { text };
80
- },
81
- };
82
- }
83
- function useAiMemory() {
84
- const ctx = (0, context_1.getHookContext)();
85
- if (!ctx.memoryAdapter) {
86
- throw new Error("useAiMemory requires a memory adapter in runtime config.");
87
- }
88
- return ctx.memoryAdapter;
89
- }
90
- function useAiInterrupt(input) {
91
- const ctx = (0, context_1.getHookContext)();
92
- return Promise.resolve(ctx.node.awaitInterrupt(input));
93
- }
94
- function useNodeState(keyOrInitial, initialValue) {
95
- const ctx = (0, context_1.getHookContext)();
96
- const nodeState = ctx.currentNodeState;
97
- if (typeof keyOrInitial === "string") {
98
- const key = keyOrInitial;
99
- const hasInitial = arguments.length > 1;
100
- if (!Object.hasOwn(nodeState.byKey, key) && hasInitial) {
101
- nodeState.byKey[key] = initialValue;
102
- ctx.dirty = true;
103
- }
104
- const getValue = () => nodeState.byKey[key];
105
- const setValue = (next) => {
106
- const prev = getValue();
107
- const resolved = typeof next === "function" ? next(prev) : next;
108
- nodeState.byKey[key] = resolved;
109
- ctx.dirty = true;
110
- };
111
- return [getValue(), setValue];
112
- }
113
- const index = ctx.nodeStateIndex++;
114
- if (index >= nodeState.byIndex.length) {
115
- nodeState.byIndex[index] = keyOrInitial;
116
- ctx.dirty = true;
117
- }
118
- const getValue = () => nodeState.byIndex[index];
119
- const setValue = (next) => {
120
- const prev = getValue();
121
- const resolved = typeof next === "function" ? next(prev) : next;
122
- nodeState.byIndex[index] = resolved;
123
- ctx.dirty = true;
124
- };
125
- return [getValue(), setValue];
126
- }
127
- function useWorkflowState(key, initialValue) {
128
- const ctx = (0, context_1.getHookContext)();
129
- const workflowState = ctx.workflowState;
130
- const hasInitial = arguments.length > 1;
131
- if (!Object.hasOwn(workflowState, key) && hasInitial) {
132
- workflowState[key] = initialValue;
133
- ctx.dirty = true;
134
- }
135
- const getValue = () => workflowState[key];
136
- const setValue = (next) => {
137
- const prev = getValue();
138
- const resolved = typeof next === "function" ? next(prev) : next;
139
- workflowState[key] = resolved;
140
- ctx.dirty = true;
141
- };
142
- return [getValue(), setValue];
143
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EACL,cAAc,EACd,WAAW,EACX,aAAa,EACb,OAAO,EACP,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,SAAS,CAAC"}