@kortyx/hooks 0.29.0 → 0.30.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,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.30.1](https://github.com/kortyx-io/kortyx/compare/hooks-v0.30.0...hooks-v0.30.1) (2026-10-03)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @kortyx/telemetry-contracts bumped to 0.13.0
11
+
12
+ ## [0.30.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.29.0...hooks-v0.30.0) (2026-09-30)
13
+
14
+
15
+ ### Features
16
+
17
+ * **hooks:** add realtime model-selected output contracts ([#249](https://github.com/kortyx-io/kortyx/issues/249)) ([ac52b47](https://github.com/kortyx-io/kortyx/commit/ac52b47151b64ce5be6ce6c7fd42d34a0fa8a76d))
18
+
19
+
20
+ ### Dependencies
21
+
22
+ * The following workspace dependencies were updated
23
+ * dependencies
24
+ * @kortyx/telemetry-contracts bumped to 0.12.0
25
+
3
26
  ## [0.29.0](https://github.com/kortyx-io/kortyx/compare/hooks-v0.28.1...hooks-v0.29.0) (2026-09-22)
4
27
 
5
28
 
package/README.md CHANGED
@@ -24,6 +24,7 @@ npm install @kortyx/hooks
24
24
  - `useReason(...)` for model calls, optional schema-constrained interrupt flow, and structured output.
25
25
  - `useInterrupt(...)` for explicit human-in-the-loop pauses.
26
26
  - `useStructuredData(...)` for UI-friendly structured stream events.
27
+ - `defineOutputContract(...)` for reusable model-selected and application-authored structured values.
27
28
  - `useRuntimeContext(...)` for request context made available to node execution.
28
29
  - `useNodeState(...)` / `useWorkflowState(...)` for stateful node logic.
29
30
 
@@ -38,6 +39,16 @@ The singular `useReason({ interrupt })` option and `result.interruptResponse`
38
39
  are deprecated and will be removed in the next major release. Migrate to
39
40
  `interrupts.contracts` and `result.interruptHistory`.
40
41
 
42
+ Pass output contracts through `useReason({ outputs: { emit, return } })` to let
43
+ the model emit values between text segments or choose a typed terminal result.
44
+ Contracts with `stream.fields` start a separate streamed JSON pass and publish
45
+ partial `set`, `append`, or `text-delta` updates before the validated `final`
46
+ value. `useStructuredData({ contract, data })` uses the same stream contract for
47
+ application-authored values. The older `outputSchema` and `structured` options
48
+ and `result.output` remain available during migration, but are deprecated and
49
+ scheduled for removal in the next major release. TypeSafe Jev's provider-native
50
+ decision schema is a temporary exception until a non-tool replacement ships.
51
+
41
52
  ## Runtime Resume Behavior
42
53
 
43
54
  On resume, the node function is replayed from the top.
package/dist/index.d.ts CHANGED
@@ -135,6 +135,28 @@ type InterruptContract<TRequest = unknown, TResponse = unknown> = {
135
135
  schemaVersion: string;
136
136
  };
137
137
  type InterruptContractMap = Record<string, InterruptContract<unknown, unknown>>;
138
+ type OutputContract<TData = unknown> = {
139
+ description: string;
140
+ schema: SchemaLike<TData>;
141
+ schemaId: string;
142
+ schemaVersion: string;
143
+ /** Paths the model may update before emitting the validated final value. */
144
+ stream?: {
145
+ fields: UseReasonStructuredFields;
146
+ } | undefined;
147
+ };
148
+ type OutputContractMap = Record<string, OutputContract<unknown>>;
149
+ type UseReasonOutputsConfig<TEmit extends OutputContractMap = OutputContractMap, TReturn extends OutputContractMap = OutputContractMap> = {
150
+ emit?: TEmit | undefined;
151
+ return?: TReturn | undefined;
152
+ maxEmissions?: number | undefined;
153
+ };
154
+ type OutputContractEntry<TContracts extends OutputContractMap> = {
155
+ [TName in Extract<keyof TContracts, string>]: TContracts[TName] extends OutputContract<infer TData> ? {
156
+ contract: TName;
157
+ data: TData;
158
+ } : never;
159
+ }[Extract<keyof TContracts, string>];
138
160
  type UseReasonInterruptsConfig<TContracts extends InterruptContractMap = InterruptContractMap> = {
139
161
  mode?: "required" | "optional" | undefined;
140
162
  /** Maximum number of model-requested human interactions for this operation. */
@@ -159,6 +181,31 @@ type UseStructuredDataBaseArgs = {
159
181
  id?: string | undefined;
160
182
  streamId?: string | undefined;
161
183
  };
184
+ type UseContractStructuredDataArgs<TData> = {
185
+ contract: OutputContract<TData>;
186
+ id?: string | undefined;
187
+ } & ({
188
+ kind?: "final" | undefined;
189
+ data: TData;
190
+ streamId?: string | undefined;
191
+ } | {
192
+ kind: "set";
193
+ path: string;
194
+ value: unknown;
195
+ valueSchema?: SchemaLike<unknown> | undefined;
196
+ streamId: string;
197
+ } | {
198
+ kind: "append";
199
+ path: string;
200
+ items: unknown[];
201
+ itemSchema?: SchemaLike<unknown> | undefined;
202
+ streamId: string;
203
+ } | {
204
+ kind: "text-delta";
205
+ path: string;
206
+ delta: string;
207
+ streamId: string;
208
+ });
162
209
  type UseStructuredDataFinalArgs<TData = unknown> = UseStructuredDataBaseArgs & {
163
210
  kind?: "final" | undefined;
164
211
  data: TData;
@@ -215,7 +262,7 @@ type UseReasonToolExecution = {
215
262
  approval?: boolean | Record<string, boolean> | undefined;
216
263
  emit?: boolean | Record<string, boolean> | undefined;
217
264
  };
218
- type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap> = {
265
+ type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap, TEmit extends OutputContractMap = OutputContractMap, TReturn extends OutputContractMap = OutputContractMap> = {
219
266
  model: ProviderModelRef;
220
267
  input: string;
221
268
  system?: string | undefined;
@@ -230,8 +277,11 @@ type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = Interrup
230
277
  stream?: boolean | undefined;
231
278
  id?: string | undefined;
232
279
  telemetry?: KortyxTraceMetadata | undefined;
280
+ /** @deprecated Removed in the next major. Use `outputs.return` with `defineOutputContract`. */
233
281
  outputSchema?: SchemaLike<TOutput> | undefined;
282
+ /** @deprecated Removed in the next major. Use output contracts for model-selected structured emissions. */
234
283
  structured?: UseReasonStructuredConfig | undefined;
284
+ outputs?: UseReasonOutputsConfig<TEmit, TReturn> | undefined;
235
285
  /** @deprecated Use `interrupts`. Removed in the next major release. */
236
286
  interrupt?: UseReasonInterruptConfig<TRequest, TResponse> | undefined;
237
287
  interrupts?: UseReasonInterruptsConfig<TContracts> | undefined;
@@ -239,6 +289,7 @@ type UseReasonArgs<TOutput = unknown, TRequest extends InterruptInput = Interrup
239
289
  toolExecution?: UseReasonToolExecution | undefined;
240
290
  };
241
291
  type UseReasonStep = {
292
+ kind?: "output" | undefined;
242
293
  toolObservations?: _kortyx_providers.ToolObservation[];
243
294
  stepIndex: number;
244
295
  text: string;
@@ -249,7 +300,7 @@ type UseReasonStep = {
249
300
  providerMetadata?: KortyxProviderMetadata | undefined;
250
301
  warnings?: KortyxWarning[] | undefined;
251
302
  };
252
- type UseReasonResult<TOutput = unknown, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap> = {
303
+ type UseReasonResult<TOutput = unknown, TResponse = InterruptResult, TContracts extends InterruptContractMap = InterruptContractMap, TEmit extends OutputContractMap = OutputContractMap, TReturn extends OutputContractMap = OutputContractMap> = {
253
304
  id?: string;
254
305
  opId: string;
255
306
  text: string;
@@ -258,7 +309,10 @@ type UseReasonResult<TOutput = unknown, TResponse = InterruptResult, TContracts
258
309
  finishReason?: KortyxFinishReason;
259
310
  providerMetadata?: KortyxProviderMetadata;
260
311
  warnings?: KortyxWarning[];
312
+ /** @deprecated Removed in the next major. Use `returned` from an output contract. */
261
313
  output?: TOutput;
314
+ emissions?: OutputContractEntry<TEmit>[];
315
+ returned?: OutputContractEntry<TReturn>;
262
316
  /** @deprecated Use `interruptHistory`. Removed in the next major release. */
263
317
  interruptResponse?: TResponse;
264
318
  interruptHistory?: InterruptHistoryEntry<TContracts>[];
@@ -284,9 +338,12 @@ type UseContractInterruptArgs<TRequest, TResponse> = {
284
338
 
285
339
  declare const defineInterruptContract: <TRequest, TResponse>(contract: InterruptContract<TRequest, TResponse>) => InterruptContract<TRequest, TResponse>;
286
340
 
341
+ declare const defineOutputContract: <TData>(contract: OutputContract<TData>) => OutputContract<TData>;
342
+
287
343
  type StateSetter<T> = (next: T | ((prev: T) => T)) => void;
344
+ declare function useStructuredData<TData>(args: UseContractStructuredDataArgs<TData>): void;
288
345
  declare function useStructuredData<TData = unknown>(args: UseStructuredDataArgs<TData>): void;
289
- 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>>;
346
+ 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>): Promise<UseReasonResult<TOutput, TResponse, TContracts, TEmit, TReturn>>;
290
347
  declare function useInterrupt<TRequest, TResponse>(args: UseContractInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
291
348
  declare function useInterrupt<TRequest extends InterruptInput = InterruptInput, TResponse = InterruptResult>(args: UseInterruptArgs<TRequest, TResponse>): Promise<TResponse>;
292
349
  /** Live execution signal for cooperative I/O. Never store it in workflow state. */
@@ -309,4 +366,4 @@ declare function useTool<T extends KortyxExecutableTool>(args: UseToolArgs<T>):
309
366
  /** Best effort lifecycle facts. Engine snapshots and interrupt tokens never leave the runtime. */
310
367
  declare function emitWorkflowCall(telemetry: KortyxTelemetryConfig | undefined, type: KortyxTelemetryEventType, payload: Record<string, unknown>): void;
311
368
 
312
- 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 };
369
+ 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 };