@kortyx/hooks 0.32.0 → 0.34.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 +48 -0
- package/dist/index.d.ts +23 -3
- package/dist/index.js +267 -38
- package/dist/index.js.map +1 -1
- package/dist/internal.js +104 -5
- package/dist/internal.js.map +1 -1
- package/package.json +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.34.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.33.0...hooks-v0.34.0) (2026-10-11)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add shared SDK and Studio usage telemetry ([#313](https://github.com/kortyx-io/kortyx/issues/313)) ([7d5f0c0](https://github.com/kortyx-io/kortyx/commit/7d5f0c005bd7721dc6a529554e75c14573d76a0f))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **website:** reconcile credibility branch with current main ([60199f9](https://github.com/kortyx-io/kortyx/commit/60199f992242eb7c409a95bc7a6898d31bac601d))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Dependencies
|
|
17
|
+
|
|
18
|
+
* The following workspace dependencies were updated
|
|
19
|
+
* dependencies
|
|
20
|
+
* @kortyx/core bumped to 0.13.1
|
|
21
|
+
* @kortyx/providers bumped to 0.9.2
|
|
22
|
+
* @kortyx/telemetry-contracts bumped to 0.17.0
|
|
23
|
+
* @kortyx/prompts bumped to 0.2.0
|
|
24
|
+
* @kortyx/usage-telemetry bumped to 0.2.0
|
|
25
|
+
|
|
26
|
+
## [0.33.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.32.1...hooks-v0.33.0) (2026-10-10)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
* version, evaluate, serve and migrate Studio prompts ([#288](https://github.com/kortyx-io/kortyx/issues/288)) ([0802f8b](https://github.com/kortyx-io/kortyx/commit/0802f8b91c4a541d176dd8a75c659063e2c28c8c))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Dependencies
|
|
35
|
+
|
|
36
|
+
* The following workspace dependencies were updated
|
|
37
|
+
* dependencies
|
|
38
|
+
* @kortyx/telemetry-contracts bumped to 0.16.0
|
|
39
|
+
* @kortyx/prompts bumped to 0.1.0
|
|
40
|
+
|
|
41
|
+
## [0.32.1](https://github.com/kortyx-io/kortyx/compare/hooks-v0.32.0...hooks-v0.32.1) (2026-10-09)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### Dependencies
|
|
45
|
+
|
|
46
|
+
* The following workspace dependencies were updated
|
|
47
|
+
* dependencies
|
|
48
|
+
* @kortyx/core bumped to 0.13.0
|
|
49
|
+
* @kortyx/providers bumped to 0.9.1
|
|
50
|
+
|
|
3
51
|
## [0.32.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.31.0...hooks-v0.32.0) (2026-10-08)
|
|
4
52
|
|
|
5
53
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as _kortyx_core from '@kortyx/core';
|
|
2
2
|
import { WorkflowDefinition, TokenUsage, InterruptInput, GraphState, NodeConfig, InterruptResumeValue, InterruptResult } from '@kortyx/core';
|
|
3
|
+
import * as _kortyx_prompts from '@kortyx/prompts';
|
|
4
|
+
import { CompiledPrompt, PromptRef } from '@kortyx/prompts';
|
|
3
5
|
import { K as KortyxTelemetryConfig, R as ReasonTraceAdapter, a as KortyxTraceMetadata, b as ReportErrorOptions, c as KortyxTelemetryEventType } from './tracing-mXE0Euvx.js';
|
|
4
6
|
export { E as EnsureWorkflowTopologyRequest, d as EnsureWorkflowTopologyResponse, e as KortyxErrorDetails, f as KortyxTelemetryContentCapture, g as KortyxTelemetryCorrelation, h as KortyxTelemetryEvent, i as KortyxTelemetryPrompt, j as KortyxTelemetryReporter, k as KortyxTelemetryService, l as KortyxTraceAdapter, m as KortyxTraceErrorProjection, n as ReasonTraceAttributes, o as ReasonTraceSpan, p as ReasonTraceSpanEndArgs, q as ReasonTraceSpanStartArgs } from './tracing-mXE0Euvx.js';
|
|
5
7
|
import { FailureDescriptor, KortyxError } from '@kortyx/core/errors';
|
|
@@ -12,7 +14,6 @@ type CompleteResponseOptions = {
|
|
|
12
14
|
message?: string | undefined;
|
|
13
15
|
data?: unknown;
|
|
14
16
|
};
|
|
15
|
-
/** Finish client delivery, leaving the node and workflow execution running. */
|
|
16
17
|
declare function completeResponse(options?: CompleteResponseOptions): Promise<void>;
|
|
17
18
|
|
|
18
19
|
/** All siblings have settled; results retain the order passed to parallel(). */
|
|
@@ -85,6 +86,7 @@ declare function useWorkflow(args: {
|
|
|
85
86
|
}>;
|
|
86
87
|
|
|
87
88
|
type HookNodeRuntimeContext = {
|
|
89
|
+
prompts?: _kortyx_prompts.PromptExecution | undefined;
|
|
88
90
|
completeResponse?: ((options: CompleteResponseOptions, state: GraphState) => Promise<void>) | undefined;
|
|
89
91
|
/** Transient execution control; never part of checkpointed state. */
|
|
90
92
|
abortSignal?: AbortSignal | undefined;
|
|
@@ -267,6 +269,7 @@ type UseReasonToolExecution = {
|
|
|
267
269
|
};
|
|
268
270
|
type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap, TEmit extends OutputContractMap = OutputContractMap, TReturn extends OutputContractMap = OutputContractMap> = {
|
|
269
271
|
model: ProviderModelRef;
|
|
272
|
+
messages?: _kortyx_providers.KortyxPromptMessage[] | undefined;
|
|
270
273
|
input: string;
|
|
271
274
|
system?: string | undefined;
|
|
272
275
|
temperature?: number | undefined;
|
|
@@ -346,7 +349,12 @@ declare const defineOutputContract: <TData>(contract: OutputContract<TData>) =>
|
|
|
346
349
|
type StateSetter<T> = (next: T | ((prev: T) => T)) => void;
|
|
347
350
|
declare function useStructuredData<TData>(args: UseContractStructuredDataArgs<TData>): void;
|
|
348
351
|
declare function useStructuredData<TData = unknown>(args: UseStructuredDataArgs<TData>): void;
|
|
349
|
-
declare function useReason<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap, TEmit extends OutputContractMap = OutputContractMap, TReturn extends OutputContractMap = OutputContractMap>(args: UseReasonArgs<TOutput, TRequest, TResponse, TContracts, TEmit, TReturn>
|
|
352
|
+
declare function useReason<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap, TEmit extends OutputContractMap = OutputContractMap, TReturn extends OutputContractMap = OutputContractMap>(args: UseReasonArgs<TOutput, TRequest, TResponse, TContracts, TEmit, TReturn> | (Omit<UseReasonArgs<TOutput, TRequest, TResponse, TContracts, TEmit, TReturn>, "input" | "system" | "messages"> & {
|
|
353
|
+
prompt: CompiledPrompt;
|
|
354
|
+
input?: never;
|
|
355
|
+
system?: never;
|
|
356
|
+
messages?: never;
|
|
357
|
+
})): Promise<UseReasonResult<TOutput, TResponse, TContracts, TEmit, TReturn>>;
|
|
350
358
|
declare function useInterrupt<TRequest, TResponse>(args: UseContractInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
|
|
351
359
|
declare function useInterrupt<TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
|
|
352
360
|
/** Live execution signal for cooperative I/O. Never store it in workflow state. */
|
|
@@ -355,6 +363,12 @@ declare function useRuntimeContext<TContext extends Record<string, unknown> = Re
|
|
|
355
363
|
declare function useNodeState<T>(initialValue: T): [T, StateSetter<T>];
|
|
356
364
|
declare function useWorkflowState<T>(key: string, ...rest: [] | [T]): [T, StateSetter<T>];
|
|
357
365
|
|
|
366
|
+
type UseReasonPromptArgs = Omit<UseReasonArgs, "input" | "system" | "messages"> & {
|
|
367
|
+
prompt: CompiledPrompt;
|
|
368
|
+
input?: never;
|
|
369
|
+
system?: never;
|
|
370
|
+
};
|
|
371
|
+
|
|
358
372
|
/** Reports a handled error to the configured observer without stopping execution. */
|
|
359
373
|
declare function reportError(error: unknown, options?: ReportErrorOptions): void;
|
|
360
374
|
|
|
@@ -366,7 +380,13 @@ type UseToolArgs<T extends KortyxExecutableTool> = {
|
|
|
366
380
|
};
|
|
367
381
|
declare function useTool<T extends KortyxExecutableTool>(args: UseToolArgs<T>): Promise<Awaited<ReturnType<T["execute"]>>>;
|
|
368
382
|
|
|
383
|
+
/** Resolve both roles from one immutable version in the current execution. */
|
|
384
|
+
declare function usePrompt<Inputs, Config>(reference: PromptRef<Inputs, Config>, options: {
|
|
385
|
+
variables: Inputs;
|
|
386
|
+
version?: number;
|
|
387
|
+
}): Promise<CompiledPrompt<Config>>;
|
|
388
|
+
|
|
369
389
|
/** Best effort lifecycle facts. Engine snapshots and interrupt tokens never leave the runtime. */
|
|
370
390
|
declare function emitWorkflowCall(telemetry: KortyxTelemetryConfig | undefined, type: KortyxTelemetryEventType, payload: Record<string, unknown>): void;
|
|
371
391
|
|
|
372
|
-
export { type CompleteResponseOptions, type HookRuntimeContext, type InterruptContract, type InterruptContractMap, type InterruptHistoryEntry, KortyxTelemetryConfig, KortyxTelemetryEventType, KortyxTraceMetadata, type OutputContract, type OutputContractEntry, type OutputContractMap, ParallelError, ReasonTraceAdapter, ReportErrorOptions, type UseContractInterruptArgs, type UseContractStructuredDataArgs, type UseInterruptArgs, type UseReasonArgs, type UseReasonInterruptConfig, type UseReasonInterruptsConfig, type UseReasonOutputsConfig, type UseReasonResult, type UseReasonStep, type UseReasonToolExecution, type UseStructuredDataArgs, type UseToolArgs, WorkflowCallError, type WorkflowCallOutcome, type WorkflowCallService, completeResponse, createWorkflowHooks, defineInterruptContract, defineOutputContract, emitWorkflowCall, parallel, reportError, runWithHookContext, useAbortSignal, useInterrupt, useNodeState, useReason, useRuntimeContext, useStructuredData, useTool, useWorkflow, useWorkflowState, workflowCallFingerprint };
|
|
392
|
+
export { type CompleteResponseOptions, type HookRuntimeContext, type InterruptContract, type InterruptContractMap, type InterruptHistoryEntry, KortyxTelemetryConfig, KortyxTelemetryEventType, KortyxTraceMetadata, type OutputContract, type OutputContractEntry, type OutputContractMap, ParallelError, ReasonTraceAdapter, ReportErrorOptions, type UseContractInterruptArgs, type UseContractStructuredDataArgs, type UseInterruptArgs, type UseReasonArgs, type UseReasonInterruptConfig, type UseReasonInterruptsConfig, type UseReasonOutputsConfig, type UseReasonPromptArgs, type UseReasonResult, type UseReasonStep, type UseReasonToolExecution, type UseStructuredDataArgs, type UseToolArgs, WorkflowCallError, type WorkflowCallOutcome, type WorkflowCallService, completeResponse, createWorkflowHooks, defineInterruptContract, defineOutputContract, emitWorkflowCall, parallel, reportError, runWithHookContext, useAbortSignal, useInterrupt, useNodeState, usePrompt, useReason, useRuntimeContext, useStructuredData, useTool, useWorkflow, useWorkflowState, workflowCallFingerprint };
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
useAbortSignal: () => useAbortSignal,
|
|
33
33
|
useInterrupt: () => useInterrupt,
|
|
34
34
|
useNodeState: () => useNodeState,
|
|
35
|
+
usePrompt: () => usePrompt,
|
|
35
36
|
useReason: () => useReason2,
|
|
36
37
|
useRuntimeContext: () => useRuntimeContext,
|
|
37
38
|
useStructuredData: () => useStructuredData,
|
|
@@ -137,11 +138,11 @@ var cleanupCompletedReasonCheckpoints = (ctx) => {
|
|
|
137
138
|
}
|
|
138
139
|
if (changed) ctx.stateDirty = true;
|
|
139
140
|
};
|
|
140
|
-
var toTokenUsageDelta = (
|
|
141
|
-
if (!
|
|
142
|
-
const input =
|
|
143
|
-
const output =
|
|
144
|
-
const total =
|
|
141
|
+
var toTokenUsageDelta = (usage2) => {
|
|
142
|
+
if (!usage2) return void 0;
|
|
143
|
+
const input = usage2.input ?? 0;
|
|
144
|
+
const output = usage2.output ?? 0;
|
|
145
|
+
const total = usage2.total ?? input + output + (usage2.outputIncludesReasoning ? 0 : usage2.reasoning ?? 0);
|
|
145
146
|
if (input === 0 && output === 0 && total === 0) {
|
|
146
147
|
return void 0;
|
|
147
148
|
}
|
|
@@ -151,8 +152,8 @@ var toTokenUsageDelta = (usage) => {
|
|
|
151
152
|
total
|
|
152
153
|
};
|
|
153
154
|
};
|
|
154
|
-
function accumulateTokenUsage(
|
|
155
|
-
const delta = toTokenUsageDelta(
|
|
155
|
+
function accumulateTokenUsage(usage2) {
|
|
156
|
+
const delta = toTokenUsageDelta(usage2);
|
|
156
157
|
if (!delta) return;
|
|
157
158
|
const ctx = getHookContext();
|
|
158
159
|
const current = ctx.tokenUsage ?? {
|
|
@@ -238,12 +239,98 @@ function snapshotHookState() {
|
|
|
238
239
|
};
|
|
239
240
|
}
|
|
240
241
|
|
|
242
|
+
// src/usage.ts
|
|
243
|
+
var import_node = require("@kortyx/usage-telemetry/node");
|
|
244
|
+
|
|
245
|
+
// package.json
|
|
246
|
+
var package_default = {
|
|
247
|
+
name: "@kortyx/hooks",
|
|
248
|
+
version: "0.34.0",
|
|
249
|
+
private: false,
|
|
250
|
+
description: "Lifecycle hooks and extension points for Kortyx.",
|
|
251
|
+
keywords: [
|
|
252
|
+
"ai",
|
|
253
|
+
"agent",
|
|
254
|
+
"agents",
|
|
255
|
+
"orchestration",
|
|
256
|
+
"framework",
|
|
257
|
+
"hooks",
|
|
258
|
+
"kortyx"
|
|
259
|
+
],
|
|
260
|
+
license: "Apache-2.0",
|
|
261
|
+
homepage: "https://kortyx.io/",
|
|
262
|
+
bugs: {
|
|
263
|
+
url: "https://github.com/kortyx-io/kortyx/issues"
|
|
264
|
+
},
|
|
265
|
+
author: "Kortyx (https://github.com/kortyx-io)",
|
|
266
|
+
main: "./dist/index.js",
|
|
267
|
+
types: "./dist/index.d.ts",
|
|
268
|
+
exports: {
|
|
269
|
+
".": {
|
|
270
|
+
types: "./dist/index.d.ts",
|
|
271
|
+
default: "./dist/index.js"
|
|
272
|
+
},
|
|
273
|
+
"./internal": {
|
|
274
|
+
types: "./dist/internal.d.ts",
|
|
275
|
+
default: "./dist/internal.js"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
files: [
|
|
279
|
+
"dist/**",
|
|
280
|
+
"README.md",
|
|
281
|
+
"CHANGELOG.md"
|
|
282
|
+
],
|
|
283
|
+
scripts: {
|
|
284
|
+
build: "tsup",
|
|
285
|
+
predev: "tsc -p tsconfig.build.json",
|
|
286
|
+
dev: "tsc --watch",
|
|
287
|
+
lint: "biome check src",
|
|
288
|
+
test: "vitest run && pnpm -s type-check",
|
|
289
|
+
coverage: "vitest run --coverage && pnpm -s type-check",
|
|
290
|
+
"test:watch": "vitest",
|
|
291
|
+
"type-check": "tsc --noEmit -p tsconfig.test.json"
|
|
292
|
+
},
|
|
293
|
+
dependencies: {
|
|
294
|
+
"@kortyx/core": "workspace:*",
|
|
295
|
+
"@kortyx/providers": "workspace:*",
|
|
296
|
+
"@kortyx/telemetry-contracts": "workspace:*",
|
|
297
|
+
zod: "catalog:",
|
|
298
|
+
"@kortyx/prompts": "workspace:*",
|
|
299
|
+
"@kortyx/usage-telemetry": "workspace:*"
|
|
300
|
+
},
|
|
301
|
+
devDependencies: {
|
|
302
|
+
turbo: "catalog:",
|
|
303
|
+
typescript: "catalog:",
|
|
304
|
+
tsup: "catalog:",
|
|
305
|
+
vitest: "catalog:",
|
|
306
|
+
"@vitest/coverage-v8": "catalog:"
|
|
307
|
+
},
|
|
308
|
+
sideEffects: false,
|
|
309
|
+
repository: {
|
|
310
|
+
type: "git",
|
|
311
|
+
url: "https://github.com/kortyx-io/kortyx.git",
|
|
312
|
+
directory: "packages/hooks"
|
|
313
|
+
},
|
|
314
|
+
publishConfig: {
|
|
315
|
+
access: "public"
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// src/usage.ts
|
|
320
|
+
var client = () => (0, import_node.getUsageTelemetry)("hooks", package_default.version);
|
|
321
|
+
var usage = {
|
|
322
|
+
start: (...args) => client().start(...args),
|
|
323
|
+
feature: (...args) => client().feature(...args),
|
|
324
|
+
measure: (...args) => client().measure(...args),
|
|
325
|
+
flush: () => client().flush()
|
|
326
|
+
};
|
|
327
|
+
|
|
241
328
|
// src/complete-response.ts
|
|
242
329
|
var optionsSchema = import_zod.z.object({
|
|
243
330
|
message: import_zod.z.string().optional(),
|
|
244
331
|
data: import_zod.z.json().optional()
|
|
245
332
|
}).strict();
|
|
246
|
-
async function
|
|
333
|
+
async function completeResponseInternal(options = {}) {
|
|
247
334
|
const ctx = getHookContext();
|
|
248
335
|
const parsed = optionsSchema.parse(options);
|
|
249
336
|
if (!ctx.node.completeResponse) {
|
|
@@ -253,6 +340,12 @@ async function completeResponse(options = {}) {
|
|
|
253
340
|
}
|
|
254
341
|
await ctx.node.completeResponse(parsed, snapshotHookState());
|
|
255
342
|
}
|
|
343
|
+
function completeResponse(options = {}) {
|
|
344
|
+
return usage.measure(
|
|
345
|
+
"sdk.complete_response",
|
|
346
|
+
() => completeResponseInternal(options)
|
|
347
|
+
);
|
|
348
|
+
}
|
|
256
349
|
|
|
257
350
|
// src/interrupt.ts
|
|
258
351
|
var import_core = require("@kortyx/core");
|
|
@@ -651,7 +744,7 @@ var createStructuredStreamId = () => {
|
|
|
651
744
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
652
745
|
}
|
|
653
746
|
};
|
|
654
|
-
var
|
|
747
|
+
var emitStructuredDataInternal = (args) => {
|
|
655
748
|
const ctx = getHookContext();
|
|
656
749
|
const streamId = typeof args.streamId === "string" && args.streamId.length > 0 ? args.streamId : createStructuredStreamId();
|
|
657
750
|
const dataType = typeof args.dataType === "string" && args.dataType.length > 0 ? args.dataType : "generic";
|
|
@@ -714,6 +807,16 @@ var emitStructuredData = (args) => {
|
|
|
714
807
|
};
|
|
715
808
|
var shouldEmitStructured = (cfg) => Boolean(cfg);
|
|
716
809
|
var shouldStreamStructured = (cfg) => Boolean(cfg) && (cfg?.stream ?? true);
|
|
810
|
+
var emitStructuredData = (args) => {
|
|
811
|
+
const scope = usage.start("sdk.structured", { format: args.kind });
|
|
812
|
+
try {
|
|
813
|
+
emitStructuredDataInternal(args);
|
|
814
|
+
scope.end();
|
|
815
|
+
} catch (error) {
|
|
816
|
+
scope.fail(error);
|
|
817
|
+
throw error;
|
|
818
|
+
}
|
|
819
|
+
};
|
|
717
820
|
|
|
718
821
|
// src/tool.ts
|
|
719
822
|
var import_node_async_hooks2 = require("async_hooks");
|
|
@@ -1191,6 +1294,11 @@ async function executeObservedTool(args) {
|
|
|
1191
1294
|
}
|
|
1192
1295
|
ctx.node.consumeExecution?.("maxToolCalls");
|
|
1193
1296
|
observation.executed = true;
|
|
1297
|
+
const operationUsage = usage.start("sdk.tool", {
|
|
1298
|
+
calling_mode: args.callingMode,
|
|
1299
|
+
source: args.tool.source === "mcp" ? "mcp" : "native",
|
|
1300
|
+
executed: true
|
|
1301
|
+
});
|
|
1194
1302
|
const started = performance.now();
|
|
1195
1303
|
return withSafeTraceSpan(
|
|
1196
1304
|
toolTrace(observation),
|
|
@@ -1240,9 +1348,13 @@ async function executeObservedTool(args) {
|
|
|
1240
1348
|
scope.telemetry ?? args.tool.telemetry
|
|
1241
1349
|
);
|
|
1242
1350
|
}
|
|
1351
|
+
if (observation.outcome === "fault") operationUsage.fail(error);
|
|
1243
1352
|
throw error;
|
|
1244
1353
|
} finally {
|
|
1245
1354
|
observation.durationMs = Math.max(0, performance.now() - started);
|
|
1355
|
+
operationUsage.end(
|
|
1356
|
+
observation.outcome === "fault" ? "failed" : observation.outcome ?? "suspended"
|
|
1357
|
+
);
|
|
1246
1358
|
span.end?.({
|
|
1247
1359
|
attributes: {
|
|
1248
1360
|
...observation,
|
|
@@ -1354,6 +1466,7 @@ var ownershipFrom = (observation) => ({
|
|
|
1354
1466
|
// src/reason/engine.ts
|
|
1355
1467
|
var import_node_crypto5 = require("crypto");
|
|
1356
1468
|
var import_core4 = require("@kortyx/core");
|
|
1469
|
+
var import_prompts = require("@kortyx/prompts");
|
|
1357
1470
|
|
|
1358
1471
|
// src/reason-engine.ts
|
|
1359
1472
|
var import_node_crypto4 = require("crypto");
|
|
@@ -1398,7 +1511,7 @@ var resolveProviderOptions = (defaults, overrides) => {
|
|
|
1398
1511
|
}
|
|
1399
1512
|
return providerOptions;
|
|
1400
1513
|
};
|
|
1401
|
-
async function
|
|
1514
|
+
async function runReasonEngineInternal(args) {
|
|
1402
1515
|
let stream = args.stream ?? args.model.options?.streaming ?? true;
|
|
1403
1516
|
const emit = args.emit ?? true;
|
|
1404
1517
|
const temperature = args.temperature ?? args.model.options?.temperature ?? args.defaultTemperature;
|
|
@@ -1425,6 +1538,11 @@ async function runReasonEngine(args) {
|
|
|
1425
1538
|
...providerOptions !== void 0 ? { providerOptions } : {}
|
|
1426
1539
|
});
|
|
1427
1540
|
if (tools2?.length && !model.supportsToolStreaming) stream = false;
|
|
1541
|
+
usage.feature("sdk.model", {
|
|
1542
|
+
streaming: stream,
|
|
1543
|
+
tools: Boolean(tools2?.length),
|
|
1544
|
+
provider: args.model.provider.id
|
|
1545
|
+
});
|
|
1428
1546
|
const messages = args.messages !== void 0 ? args.messages : [
|
|
1429
1547
|
...typeof args.system === "string" && args.system.length > 0 ? [{ role: "system", content: args.system }] : [],
|
|
1430
1548
|
{ role: "user", content: String(args.input ?? "") }
|
|
@@ -1504,7 +1622,7 @@ async function runReasonEngine(args) {
|
|
|
1504
1622
|
let continuation;
|
|
1505
1623
|
let final = "";
|
|
1506
1624
|
let raw;
|
|
1507
|
-
let
|
|
1625
|
+
let usage2;
|
|
1508
1626
|
let finishReason;
|
|
1509
1627
|
let toolCalls;
|
|
1510
1628
|
let providerMetadata;
|
|
@@ -1545,7 +1663,7 @@ async function runReasonEngine(args) {
|
|
|
1545
1663
|
raw = chunk.raw;
|
|
1546
1664
|
}
|
|
1547
1665
|
if (chunk.usage !== void 0) {
|
|
1548
|
-
|
|
1666
|
+
usage2 = chunk.usage;
|
|
1549
1667
|
}
|
|
1550
1668
|
if (chunk.finishReason !== void 0) {
|
|
1551
1669
|
finishReason = chunk.finishReason;
|
|
@@ -1583,7 +1701,7 @@ async function runReasonEngine(args) {
|
|
|
1583
1701
|
}
|
|
1584
1702
|
}
|
|
1585
1703
|
(0, import_core3.throwIfExecutionAborted)(abortSignal);
|
|
1586
|
-
assertModelFinish({ finishReason, usage });
|
|
1704
|
+
assertModelFinish({ finishReason, usage: usage2 });
|
|
1587
1705
|
if (emit) {
|
|
1588
1706
|
emitNodeEvent(args.emitEvent, args.nodeId, "text-end", {
|
|
1589
1707
|
...commonMeta
|
|
@@ -1593,7 +1711,7 @@ async function runReasonEngine(args) {
|
|
|
1593
1711
|
text: final,
|
|
1594
1712
|
...continuation ? { continuation } : {},
|
|
1595
1713
|
...raw !== void 0 ? { raw } : {},
|
|
1596
|
-
...
|
|
1714
|
+
...usage2 !== void 0 ? { usage: usage2 } : {},
|
|
1597
1715
|
...finishReason !== void 0 ? { finishReason } : {},
|
|
1598
1716
|
...toolCalls !== void 0 ? { toolCalls } : {},
|
|
1599
1717
|
...providerMetadata !== void 0 ? { providerMetadata } : {},
|
|
@@ -1639,6 +1757,14 @@ async function runReasonEngine(args) {
|
|
|
1639
1757
|
throw failure;
|
|
1640
1758
|
}
|
|
1641
1759
|
}
|
|
1760
|
+
function runReasonEngine(args) {
|
|
1761
|
+
return usage.measure("sdk.model", () => runReasonEngineInternal(args), {
|
|
1762
|
+
provider: args.model.provider.id,
|
|
1763
|
+
requested_streaming: args.stream ?? args.model.options?.streaming ?? true,
|
|
1764
|
+
tools: Boolean((args.tools ?? args.model.options?.tools)?.length),
|
|
1765
|
+
format: args.responseFormat?.type ?? args.model.options?.responseFormat?.type ?? "text"
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1642
1768
|
|
|
1643
1769
|
// src/reason/engine.ts
|
|
1644
1770
|
var createRuntimeId2 = () => {
|
|
@@ -1657,6 +1783,19 @@ async function reasonEngine(args, meta, inputOverride) {
|
|
|
1657
1783
|
);
|
|
1658
1784
|
(0, import_core4.throwIfExecutionAborted)(abortSignal);
|
|
1659
1785
|
ctx.node.consumeExecution?.("maxModelPasses");
|
|
1786
|
+
const prompt = args.telemetry?.prompt;
|
|
1787
|
+
const identity = prompt?.metadata;
|
|
1788
|
+
if ((0, import_prompts.isPromptUsageMetadata)(identity)) {
|
|
1789
|
+
const { dependencies, ...parent } = identity;
|
|
1790
|
+
ctx.node.prompts?.recordUsage({ ...parent, model: args.model.modelId });
|
|
1791
|
+
for (const dependency of dependencies ?? [])
|
|
1792
|
+
ctx.node.prompts?.recordUsage({
|
|
1793
|
+
...dependency,
|
|
1794
|
+
environment: identity.environment,
|
|
1795
|
+
snapshotRevision: identity.snapshotRevision,
|
|
1796
|
+
model: args.model.modelId
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1660
1799
|
try {
|
|
1661
1800
|
return await runReasonEngine({
|
|
1662
1801
|
model: args.model,
|
|
@@ -1670,7 +1809,12 @@ async function reasonEngine(args, meta, inputOverride) {
|
|
|
1670
1809
|
responseFormat: args.responseFormat,
|
|
1671
1810
|
providerOptions: args.providerOptions,
|
|
1672
1811
|
tools: args.tools,
|
|
1673
|
-
messages: args.messages
|
|
1812
|
+
messages: args.messages && inputOverride !== void 0 ? args.messages.map(
|
|
1813
|
+
(message, index) => index === args.messages.reduce(
|
|
1814
|
+
(last, item, position) => item.role === "user" ? position : last,
|
|
1815
|
+
-1
|
|
1816
|
+
) ? { ...message, content: inputOverride } : message
|
|
1817
|
+
) : args.messages,
|
|
1674
1818
|
defaultTemperature: ctx.node.config?.model?.temperature,
|
|
1675
1819
|
stream: args.stream,
|
|
1676
1820
|
emit: args.emit,
|
|
@@ -1683,8 +1827,8 @@ async function reasonEngine(args, meta, inputOverride) {
|
|
|
1683
1827
|
opId: meta.opId
|
|
1684
1828
|
});
|
|
1685
1829
|
} catch (error) {
|
|
1686
|
-
const
|
|
1687
|
-
if (
|
|
1830
|
+
const usage2 = error?.usage;
|
|
1831
|
+
if (usage2) accumulateTokenUsage(usage2);
|
|
1688
1832
|
throw error;
|
|
1689
1833
|
}
|
|
1690
1834
|
}
|
|
@@ -2574,6 +2718,38 @@ var parseInterruptFirstPassResult = (args) => {
|
|
|
2574
2718
|
}
|
|
2575
2719
|
};
|
|
2576
2720
|
|
|
2721
|
+
// src/reason/prompt.ts
|
|
2722
|
+
var import_prompts2 = require("@kortyx/prompts");
|
|
2723
|
+
function normalizePromptReasonArgs(args) {
|
|
2724
|
+
if (!("prompt" in args)) return args;
|
|
2725
|
+
if (args.input !== void 0 || args.system !== void 0 || "messages" in args)
|
|
2726
|
+
throw new import_prompts2.PromptError(
|
|
2727
|
+
"PROMPT_REASON_CONFLICT",
|
|
2728
|
+
"Use either prompt or input/system/messages in useReason."
|
|
2729
|
+
);
|
|
2730
|
+
const { prompt, ...rest } = args;
|
|
2731
|
+
if (!(0, import_prompts2.isCompiledPrompt)(prompt))
|
|
2732
|
+
throw new import_prompts2.PromptError(
|
|
2733
|
+
"PROMPT_REASON_INVALID",
|
|
2734
|
+
"useReason requires a compiled prompt returned by usePrompt."
|
|
2735
|
+
);
|
|
2736
|
+
return {
|
|
2737
|
+
...rest,
|
|
2738
|
+
input: prompt.format === "system-user" ? prompt.user ?? "" : prompt.messages.filter((message) => message.role === "user").at(-1)?.content ?? "",
|
|
2739
|
+
...prompt.format === "system-user" ? { system: prompt.system } : { messages: structuredClone(prompt.messages) },
|
|
2740
|
+
telemetry: {
|
|
2741
|
+
...args.telemetry,
|
|
2742
|
+
prompt: {
|
|
2743
|
+
name: prompt.ref.id,
|
|
2744
|
+
version: prompt.ref.version,
|
|
2745
|
+
type: prompt.format === "chat" ? "chat" : "text",
|
|
2746
|
+
source: prompt.ref.source,
|
|
2747
|
+
metadata: (0, import_prompts2.promptUsageMetadata)(prompt)
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
};
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2577
2753
|
// src/reason/prompting.ts
|
|
2578
2754
|
var import_zod4 = require("zod");
|
|
2579
2755
|
var tryStringify2 = (value) => {
|
|
@@ -2823,19 +2999,34 @@ var normalizeToolResult = (toolCall, value) => {
|
|
|
2823
2999
|
...value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value) ? { structuredContent: value } : {}
|
|
2824
3000
|
};
|
|
2825
3001
|
};
|
|
2826
|
-
var createInitialMessages = (args) =>
|
|
2827
|
-
|
|
2828
|
-
{
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
]
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
3002
|
+
var createInitialMessages = (args) => {
|
|
3003
|
+
if (args.messages) {
|
|
3004
|
+
const ordered = args.messages.map((message) => ({ ...message }));
|
|
3005
|
+
const lastUser = ordered.reduce(
|
|
3006
|
+
(last, message, position) => message.role === "user" ? position : last,
|
|
3007
|
+
-1
|
|
3008
|
+
);
|
|
3009
|
+
if (args.inputOverride && lastUser >= 0)
|
|
3010
|
+
ordered[lastUser] = { ...ordered[lastUser], content: args.input };
|
|
3011
|
+
const instructions = [args.interruptInstructions, args.outputInstructions].filter(Boolean).join("\n\n");
|
|
3012
|
+
if (instructions)
|
|
3013
|
+
ordered.unshift({ role: "system", content: instructions });
|
|
3014
|
+
return ordered;
|
|
3015
|
+
}
|
|
3016
|
+
return [
|
|
3017
|
+
...typeof args.system === "string" || args.interruptInstructions || args.outputInstructions ? [
|
|
3018
|
+
{
|
|
3019
|
+
role: "system",
|
|
3020
|
+
content: [
|
|
3021
|
+
args.system,
|
|
3022
|
+
args.interruptInstructions,
|
|
3023
|
+
args.outputInstructions
|
|
3024
|
+
].filter((value) => Boolean(value)).join("\n\n")
|
|
3025
|
+
}
|
|
3026
|
+
] : [],
|
|
3027
|
+
{ role: "user", content: String(args.input ?? "") }
|
|
3028
|
+
];
|
|
3029
|
+
};
|
|
2839
3030
|
var runReasonToolLoop = async (args) => {
|
|
2840
3031
|
const { useReasonArgs, id, traceSpan, checkpointKey } = args;
|
|
2841
3032
|
const ctx = getHookContext();
|
|
@@ -2977,6 +3168,8 @@ var runReasonToolLoop = async (args) => {
|
|
|
2977
3168
|
let completed = false;
|
|
2978
3169
|
const maxSteps = Math.max(1, useReasonArgs.toolExecution?.maxSteps ?? 3);
|
|
2979
3170
|
const messages = checkpoint?.messages ?? createInitialMessages({
|
|
3171
|
+
messages: useReasonArgs.messages,
|
|
3172
|
+
inputOverride: Boolean(useReasonArgs.outputSchema),
|
|
2980
3173
|
system: useReasonArgs.system,
|
|
2981
3174
|
input: useReasonArgs.outputSchema ? withOutputGuardrails(useReasonArgs.input, useReasonArgs.outputSchema) : useReasonArgs.input,
|
|
2982
3175
|
...interruptConfig ? {
|
|
@@ -3011,7 +3204,7 @@ var runReasonToolLoop = async (args) => {
|
|
|
3011
3204
|
let finalRaw;
|
|
3012
3205
|
let finalOutput;
|
|
3013
3206
|
let aggregatedUsage = steps.reduce(
|
|
3014
|
-
(
|
|
3207
|
+
(usage2, step) => mergeUsage(usage2, step.usage),
|
|
3015
3208
|
void 0
|
|
3016
3209
|
);
|
|
3017
3210
|
let finalFinishReason;
|
|
@@ -4114,7 +4307,10 @@ async function runReason(args) {
|
|
|
4114
4307
|
}
|
|
4115
4308
|
);
|
|
4116
4309
|
}
|
|
4117
|
-
async function useReason(
|
|
4310
|
+
async function useReason(request) {
|
|
4311
|
+
const args = normalizePromptReasonArgs(
|
|
4312
|
+
request
|
|
4313
|
+
);
|
|
4118
4314
|
try {
|
|
4119
4315
|
return await runReason(args);
|
|
4120
4316
|
} finally {
|
|
@@ -4419,6 +4615,38 @@ function reportError(error, options = {}) {
|
|
|
4419
4615
|
}
|
|
4420
4616
|
}
|
|
4421
4617
|
|
|
4618
|
+
// src/use-prompt.ts
|
|
4619
|
+
var import_prompts3 = require("@kortyx/prompts");
|
|
4620
|
+
async function usePrompt(reference, options) {
|
|
4621
|
+
const ctx = getHookContext();
|
|
4622
|
+
if (!ctx.node.prompts)
|
|
4623
|
+
throw new import_prompts3.PromptError(
|
|
4624
|
+
"PROMPT_SOURCE_NOT_CONFIGURED",
|
|
4625
|
+
"Configure createAgent({ prompts: createPrompts(...) }) before calling usePrompt."
|
|
4626
|
+
);
|
|
4627
|
+
const stored = ctx.workflowState.__promptSnapshot;
|
|
4628
|
+
const snapshot = await ctx.node.prompts.snapshot(stored);
|
|
4629
|
+
if (!stored) {
|
|
4630
|
+
ctx.workflowState.__promptSnapshot = snapshot;
|
|
4631
|
+
ctx.stateDirty = true;
|
|
4632
|
+
}
|
|
4633
|
+
const key = `__promptPin:${reference.id}:${options.version ?? "assignment"}`;
|
|
4634
|
+
const pin = options.version !== void 0 ? await ctx.node.prompts.pin(
|
|
4635
|
+
reference.id,
|
|
4636
|
+
options.version,
|
|
4637
|
+
ctx.workflowState[key]
|
|
4638
|
+
) : void 0;
|
|
4639
|
+
if (pin && !ctx.workflowState[key]) {
|
|
4640
|
+
ctx.workflowState[key] = pin;
|
|
4641
|
+
ctx.stateDirty = true;
|
|
4642
|
+
}
|
|
4643
|
+
return ctx.node.prompts.resolve(reference, {
|
|
4644
|
+
...options,
|
|
4645
|
+
stored: snapshot,
|
|
4646
|
+
...pin ? { pin } : {}
|
|
4647
|
+
});
|
|
4648
|
+
}
|
|
4649
|
+
|
|
4422
4650
|
// src/workflow.ts
|
|
4423
4651
|
var import_node_crypto6 = require("crypto");
|
|
4424
4652
|
var import_core8 = require("@kortyx/core");
|
|
@@ -4574,14 +4802,14 @@ async function runWorkflowCall(args, task) {
|
|
|
4574
4802
|
...content
|
|
4575
4803
|
});
|
|
4576
4804
|
};
|
|
4577
|
-
const recordUsage = (
|
|
4578
|
-
if (!
|
|
4805
|
+
const recordUsage = (usage2) => {
|
|
4806
|
+
if (!usage2) return;
|
|
4579
4807
|
accumulateTokenUsage({
|
|
4580
|
-
input:
|
|
4581
|
-
output:
|
|
4582
|
-
total:
|
|
4808
|
+
input: usage2.input - (record.usage?.input ?? 0),
|
|
4809
|
+
output: usage2.output - (record.usage?.output ?? 0),
|
|
4810
|
+
total: usage2.total - (record.usage?.total ?? 0)
|
|
4583
4811
|
});
|
|
4584
|
-
record.usage =
|
|
4812
|
+
record.usage = usage2;
|
|
4585
4813
|
};
|
|
4586
4814
|
const cached = record.status === "completed";
|
|
4587
4815
|
try {
|
|
@@ -4702,6 +4930,7 @@ async function runWorkflowCall(args, task) {
|
|
|
4702
4930
|
useAbortSignal,
|
|
4703
4931
|
useInterrupt,
|
|
4704
4932
|
useNodeState,
|
|
4933
|
+
usePrompt,
|
|
4705
4934
|
useReason,
|
|
4706
4935
|
useRuntimeContext,
|
|
4707
4936
|
useStructuredData,
|