@kortyx/hooks 0.26.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.28.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.27.0...hooks-v0.28.0) (2026-09-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * **hooks:** add model-driven interrupt contracts to useReason ([#224](https://github.com/kortyx-io/kortyx/issues/224)) ([e0147d5](https://github.com/kortyx-io/kortyx/commit/e0147d5234ca38d450d452af924b242f8cbdeb16))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @kortyx/core bumped to 0.10.0
16
+ * @kortyx/providers bumped to 0.8.1
17
+ * @kortyx/telemetry-contracts bumped to 0.11.0
18
+
19
+ ## [0.27.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.26.0...hooks-v0.27.0) (2026-09-21)
20
+
21
+
22
+ ### Features
23
+
24
+ * **observability:** report handled workflow errors ([#222](https://github.com/kortyx-io/kortyx/issues/222)) ([68a3b0e](https://github.com/kortyx-io/kortyx/commit/68a3b0eea5d93cb89bdcef63c4767f3b0d59e60d))
25
+
26
+
27
+ ### Dependencies
28
+
29
+ * The following workspace dependencies were updated
30
+ * dependencies
31
+ * @kortyx/telemetry-contracts bumped to 0.10.0
32
+
3
33
  ## [0.26.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.25.3...hooks-v0.26.0) (2026-09-18)
4
34
 
5
35
 
package/README.md CHANGED
@@ -27,9 +27,16 @@ npm install @kortyx/hooks
27
27
  - `useRuntimeContext(...)` for request context made available to node execution.
28
28
  - `useNodeState(...)` / `useWorkflowState(...)` for stateful node logic.
29
29
 
30
- `useReason({ interrupt })` defaults to required interrupt behavior. Use
31
- `interrupt.mode: "optional"` when the model should decide whether to continue
32
- with a single model call or pause for user input.
30
+ Define reusable model-driven human-input contracts with
31
+ `defineInterruptContract(...)`, then pass one or more through
32
+ `useReason({ interrupts: { contracts } })`. Contract calls share the ordinary
33
+ tool loop, so tools can run before and after a pause. Use `mode: "optional"`
34
+ when the model may finish without asking, and `maxRequests` to bound sequential
35
+ human turns.
36
+
37
+ The singular `useReason({ interrupt })` option and `result.interruptResponse`
38
+ are deprecated and will be removed in the next major release. Migrate to
39
+ `interrupts.contracts` and `result.interruptHistory`.
33
40
 
34
41
  ## Runtime Resume Behavior
35
42
 
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _kortyx_core from '@kortyx/core';
2
- import { WorkflowDefinition, TokenUsage, InterruptInput, GraphState, NodeConfig, InterruptResult } from '@kortyx/core';
3
- import { K as KortyxTelemetryConfig, R as ReasonTraceAdapter, a as KortyxTraceMetadata, b as KortyxTelemetryEventType } from './tracing-BUpf8RrV.js';
4
- export { E as EnsureWorkflowTopologyRequest, c as EnsureWorkflowTopologyResponse, d as KortyxErrorDetails, e as KortyxTelemetryContentCapture, f as KortyxTelemetryCorrelation, g as KortyxTelemetryEvent, h as KortyxTelemetryPrompt, i as KortyxTelemetryReporter, j as KortyxTelemetryService, k as KortyxTraceAdapter, l as KortyxTraceErrorProjection, m as ReasonTraceAttributes, n as ReasonTraceSpan, o as ReasonTraceSpanEndArgs, p as ReasonTraceSpanStartArgs } from './tracing-BUpf8RrV.js';
2
+ import { WorkflowDefinition, TokenUsage, InterruptInput, GraphState, NodeConfig, InterruptResumeValue, InterruptResult } from '@kortyx/core';
3
+ import { K as KortyxTelemetryConfig, R as ReasonTraceAdapter, a as KortyxTraceMetadata, b as ReportErrorOptions, c as KortyxTelemetryEventType } from './tracing-BsxYlgEw.js';
4
+ 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-BsxYlgEw.js';
5
5
  import { FailureDescriptor, KortyxError } from '@kortyx/core/errors';
6
6
  import * as _kortyx_providers from '@kortyx/providers';
7
7
  import { ToolObservation, ProviderModelRef, KortyxReasoningOptions, KortyxResponseFormat, KortyxExecutableTool, KortyxUsage, KortyxFinishReason, KortyxProviderMetadata, KortyxWarning, KortyxToolCall, KortyxToolResult } from '@kortyx/providers';
@@ -95,7 +95,7 @@ type HookNodeRuntimeContext = {
95
95
  };
96
96
  config: NodeConfig;
97
97
  emit: (event: string, payload: unknown) => void;
98
- awaitInterrupt: (args: InterruptInput) => InterruptResult;
98
+ awaitInterrupt: (args: InterruptInput) => InterruptResumeValue;
99
99
  callWorkflow?: WorkflowCallService;
100
100
  workflowCallTelemetry?: KortyxTelemetryConfig | undefined;
101
101
  };
@@ -120,6 +120,30 @@ type SchemaLike<T> = {
120
120
  };
121
121
  };
122
122
  };
123
+ type InterruptContract<TRequest = unknown, TResponse = unknown> = {
124
+ /** Human-readable guidance included in the model-visible control tool. */
125
+ description: string;
126
+ requestSchema: SchemaLike<TRequest>;
127
+ responseSchema: SchemaLike<TResponse>;
128
+ /** Stable UI contract identifier. */
129
+ schemaId: string;
130
+ /** Version of the UI contract payload. */
131
+ schemaVersion: string;
132
+ };
133
+ type InterruptContractMap = Record<string, InterruptContract<unknown, unknown>>;
134
+ type UseReasonInterruptsConfig<TContracts extends InterruptContractMap = InterruptContractMap> = {
135
+ mode?: "required" | "optional" | undefined;
136
+ /** Maximum number of model-requested human interactions for this operation. */
137
+ maxRequests?: number | undefined;
138
+ contracts: TContracts;
139
+ };
140
+ type InterruptHistoryEntry<TContracts extends InterruptContractMap = InterruptContractMap> = {
141
+ [TName in Extract<keyof TContracts, string>]: TContracts[TName] extends InterruptContract<infer TRequest, infer TResponse> ? {
142
+ contract: TName;
143
+ request: TRequest;
144
+ response: TResponse;
145
+ } : never;
146
+ }[Extract<keyof TContracts, string>];
123
147
  type StructuredPath = string;
124
148
  type UseReasonStructuredFieldMode = "append" | "text-delta" | "set";
125
149
  type UseReasonStructuredFieldKey = string;
@@ -171,6 +195,10 @@ type UseReasonStructuredConfig = {
171
195
  */
172
196
  fields?: UseReasonStructuredFields | undefined;
173
197
  };
198
+ /**
199
+ * @deprecated Use `UseReasonInterruptsConfig` and `defineInterruptContract`.
200
+ * Removed in the next major release.
201
+ */
174
202
  type UseReasonInterruptConfig<TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult> = {
175
203
  mode?: "required" | "optional" | undefined;
176
204
  requestSchema: SchemaLike<TRequest>;
@@ -183,7 +211,7 @@ type UseReasonToolExecution = {
183
211
  approval?: boolean | Record<string, boolean> | undefined;
184
212
  emit?: boolean | Record<string, boolean> | undefined;
185
213
  };
186
- type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult> = {
214
+ type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap> = {
187
215
  model: ProviderModelRef;
188
216
  input: string;
189
217
  system?: string | undefined;
@@ -200,7 +228,9 @@ type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = Interrup
200
228
  telemetry?: KortyxTraceMetadata | undefined;
201
229
  outputSchema?: SchemaLike<TOutput> | undefined;
202
230
  structured?: UseReasonStructuredConfig | undefined;
231
+ /** @deprecated Use `interrupts`. Removed in the next major release. */
203
232
  interrupt?: UseReasonInterruptConfig<TRequest, TResponse> | undefined;
233
+ interrupts?: UseReasonInterruptsConfig<TContracts> | undefined;
204
234
  tools?: KortyxExecutableTool[] | undefined;
205
235
  toolExecution?: UseReasonToolExecution | undefined;
206
236
  };
@@ -215,7 +245,7 @@ type UseReasonStep = {
215
245
  providerMetadata?: KortyxProviderMetadata | undefined;
216
246
  warnings?: KortyxWarning[] | undefined;
217
247
  };
218
- type UseReasonResult<TOutput = unknown, TResponse = InterruptResult> = {
248
+ type UseReasonResult<TOutput = unknown, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap> = {
219
249
  id?: string;
220
250
  opId: string;
221
251
  text: string;
@@ -225,7 +255,9 @@ type UseReasonResult<TOutput = unknown, TResponse = InterruptResult> = {
225
255
  providerMetadata?: KortyxProviderMetadata;
226
256
  warnings?: KortyxWarning[];
227
257
  output?: TOutput;
258
+ /** @deprecated Use `interruptHistory`. Removed in the next major release. */
228
259
  interruptResponse?: TResponse;
260
+ interruptHistory?: InterruptHistoryEntry<TContracts>[];
229
261
  toolCalls?: KortyxToolCall[];
230
262
  toolResults?: KortyxToolResult[];
231
263
  steps?: UseReasonStep[];
@@ -239,10 +271,19 @@ type UseInterruptArgs<TRequest extends InterruptInput = InterruptInput, TRespons
239
271
  id?: string | undefined;
240
272
  meta?: Record<string, unknown> | undefined;
241
273
  };
274
+ type UseContractInterruptArgs<TRequest, TResponse> = {
275
+ contract: InterruptContract<TRequest, TResponse>;
276
+ request: TRequest;
277
+ id?: string | undefined;
278
+ meta?: Record<string, unknown> | undefined;
279
+ };
280
+
281
+ declare const defineInterruptContract: <TRequest, TResponse>(contract: InterruptContract<TRequest, TResponse>) => InterruptContract<TRequest, TResponse>;
242
282
 
243
283
  type StateSetter<T> = (next: T | ((prev: T) => T)) => void;
244
284
  declare function useStructuredData<TData = unknown>(args: UseStructuredDataArgs<TData>): void;
245
- declare function useReason<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseReasonArgs<TOutput, TRequest, TResponse>): Promise<UseReasonResult<TOutput, TResponse>>;
285
+ declare function useReason<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap>(args: UseReasonArgs<TOutput, TRequest, TResponse, TContracts>): Promise<UseReasonResult<TOutput, TResponse, TContracts>>;
286
+ declare function useInterrupt<TRequest, TResponse>(args: UseContractInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
246
287
  declare function useInterrupt<TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
247
288
  /** Live execution signal for cooperative I/O. Never store it in workflow state. */
248
289
  declare function useAbortSignal(): AbortSignal | undefined;
@@ -250,6 +291,9 @@ declare function useRuntimeContext<TContext extends Record<string, unknown> = Re
250
291
  declare function useNodeState<T>(initialValue: T): [T, StateSetter<T>];
251
292
  declare function useWorkflowState<T>(key: string, ...rest: [] | [T]): [T, StateSetter<T>];
252
293
 
294
+ /** Reports a handled error to the configured observer without stopping execution. */
295
+ declare function reportError(error: unknown, options?: ReportErrorOptions): void;
296
+
253
297
  type UseToolArgs<T extends KortyxExecutableTool> = {
254
298
  tool: T;
255
299
  input: Parameters<T["execute"]> extends [] ? unknown : Parameters<T["execute"]>[0];
@@ -261,4 +305,4 @@ declare function useTool<T extends KortyxExecutableTool>(args: UseToolArgs<T>):
261
305
  /** Best effort lifecycle facts. Engine snapshots and interrupt tokens never leave the runtime. */
262
306
  declare function emitWorkflowCall(telemetry: KortyxTelemetryConfig | undefined, type: KortyxTelemetryEventType, payload: Record<string, unknown>): void;
263
307
 
264
- export { type CompleteResponseOptions, type HookRuntimeContext, KortyxTelemetryConfig, KortyxTelemetryEventType, KortyxTraceMetadata, ParallelError, ReasonTraceAdapter, type UseInterruptArgs, type UseReasonArgs, type UseReasonResult, type UseReasonStep, type UseReasonToolExecution, type UseStructuredDataArgs, type UseToolArgs, WorkflowCallError, type WorkflowCallOutcome, type WorkflowCallService, completeResponse, createWorkflowHooks, emitWorkflowCall, parallel, runWithHookContext, useAbortSignal, useInterrupt, useNodeState, useReason, useRuntimeContext, useStructuredData, useTool, useWorkflow, useWorkflowState, workflowCallFingerprint };
308
+ export { type CompleteResponseOptions, type HookRuntimeContext, type InterruptContract, type InterruptContractMap, type InterruptHistoryEntry, KortyxTelemetryConfig, KortyxTelemetryEventType, KortyxTraceMetadata, ParallelError, ReasonTraceAdapter, ReportErrorOptions, type UseContractInterruptArgs, type UseInterruptArgs, type UseReasonArgs, type UseReasonInterruptConfig, type UseReasonInterruptsConfig, type UseReasonResult, type UseReasonStep, type UseReasonToolExecution, type UseStructuredDataArgs, type UseToolArgs, WorkflowCallError, type WorkflowCallOutcome, type WorkflowCallService, completeResponse, createWorkflowHooks, defineInterruptContract, emitWorkflowCall, parallel, reportError, runWithHookContext, useAbortSignal, useInterrupt, useNodeState, useReason, useRuntimeContext, useStructuredData, useTool, useWorkflow, useWorkflowState, workflowCallFingerprint };