@agentick/kernel 0.0.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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +401 -0
  3. package/dist/.tsbuildinfo.build +1 -0
  4. package/dist/channel-helpers.d.ts +32 -0
  5. package/dist/channel-helpers.d.ts.map +1 -0
  6. package/dist/channel-helpers.js +62 -0
  7. package/dist/channel-helpers.js.map +1 -0
  8. package/dist/channel.d.ts +164 -0
  9. package/dist/channel.d.ts.map +1 -0
  10. package/dist/channel.js +199 -0
  11. package/dist/channel.js.map +1 -0
  12. package/dist/context.d.ts +412 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +289 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/event-buffer.d.ts +208 -0
  17. package/dist/event-buffer.d.ts.map +1 -0
  18. package/dist/event-buffer.js +335 -0
  19. package/dist/event-buffer.js.map +1 -0
  20. package/dist/execution-helpers.d.ts +179 -0
  21. package/dist/execution-helpers.d.ts.map +1 -0
  22. package/dist/execution-helpers.js +212 -0
  23. package/dist/execution-helpers.js.map +1 -0
  24. package/dist/execution-tracker.d.ts +61 -0
  25. package/dist/execution-tracker.d.ts.map +1 -0
  26. package/dist/execution-tracker.js +319 -0
  27. package/dist/execution-tracker.js.map +1 -0
  28. package/dist/guard.d.ts +65 -0
  29. package/dist/guard.d.ts.map +1 -0
  30. package/dist/guard.js +15 -0
  31. package/dist/guard.js.map +1 -0
  32. package/dist/index.d.ts +61 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +62 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/logger.d.ts +341 -0
  37. package/dist/logger.d.ts.map +1 -0
  38. package/dist/logger.js +346 -0
  39. package/dist/logger.js.map +1 -0
  40. package/dist/metrics-helpers.d.ts +40 -0
  41. package/dist/metrics-helpers.d.ts.map +1 -0
  42. package/dist/metrics-helpers.js +72 -0
  43. package/dist/metrics-helpers.js.map +1 -0
  44. package/dist/otel-provider.d.ts +54 -0
  45. package/dist/otel-provider.d.ts.map +1 -0
  46. package/dist/otel-provider.js +107 -0
  47. package/dist/otel-provider.js.map +1 -0
  48. package/dist/procedure-graph.d.ts +136 -0
  49. package/dist/procedure-graph.d.ts.map +1 -0
  50. package/dist/procedure-graph.js +272 -0
  51. package/dist/procedure-graph.js.map +1 -0
  52. package/dist/procedure.d.ts +757 -0
  53. package/dist/procedure.d.ts.map +1 -0
  54. package/dist/procedure.js +895 -0
  55. package/dist/procedure.js.map +1 -0
  56. package/dist/schema.d.ts +153 -0
  57. package/dist/schema.d.ts.map +1 -0
  58. package/dist/schema.js +385 -0
  59. package/dist/schema.js.map +1 -0
  60. package/dist/stream.d.ts +106 -0
  61. package/dist/stream.d.ts.map +1 -0
  62. package/dist/stream.js +186 -0
  63. package/dist/stream.js.map +1 -0
  64. package/dist/telemetry.d.ts +182 -0
  65. package/dist/telemetry.d.ts.map +1 -0
  66. package/dist/telemetry.js +124 -0
  67. package/dist/telemetry.js.map +1 -0
  68. package/dist/testing.d.ts +55 -0
  69. package/dist/testing.d.ts.map +1 -0
  70. package/dist/testing.js +96 -0
  71. package/dist/testing.js.map +1 -0
  72. package/package.json +48 -0
@@ -0,0 +1,757 @@
1
+ /**
2
+ * New Procedure Implementation - Variable Arity, Decorators, Pipelines
3
+ *
4
+ * Design Principles:
5
+ * - Everything is a Procedure
6
+ * - Variable arity support (0, 1, N args)
7
+ * - Decorator = Function (same type)
8
+ * - Hooks are Procedures (@hook decorator)
9
+ * - Pipelines for middleware bundles
10
+ * - Direct calls (no registration)
11
+ * - Automatic tracking (execution graph, telemetry)
12
+ */
13
+ import { type KernelContext } from "./context";
14
+ import { ExecutionHandleBrand, type ExecutionBoundaryConfig } from "./execution-tracker";
15
+ import { EventBuffer, type TypedEvent } from "./event-buffer";
16
+ /**
17
+ * Extract the result type from a handle-like object.
18
+ * If T has a `result` property that is a Promise, extract its resolved type.
19
+ */
20
+ export type ResultOf<T> = T extends {
21
+ result: Promise<infer R>;
22
+ } ? R : T;
23
+ /**
24
+ * Enhanced Promise returned by all procedures.
25
+ *
26
+ * ProcedurePromise extends Promise<T> with a `.result` property that chains
27
+ * through to the inner result. This allows ergonomic access to final values
28
+ * without losing access to the handle.
29
+ *
30
+ * @typeParam T - The type the promise resolves to (usually a handle or value)
31
+ *
32
+ * @example Get the handle
33
+ * ```typescript
34
+ * const handle = await run(<Agent />, opts);
35
+ * handle.status; // 'running'
36
+ * for await (const event of handle) { }
37
+ * ```
38
+ *
39
+ * @example Get the result directly
40
+ * ```typescript
41
+ * const result = await run(<Agent />, opts).result;
42
+ * // Equivalent to: (await run(<Agent />, opts)).result
43
+ * ```
44
+ *
45
+ * @example Both work
46
+ * ```typescript
47
+ * const promise = run(<Agent />, opts);
48
+ * const handle = await promise; // Get handle
49
+ * const result = await promise.result; // Get final result
50
+ * ```
51
+ */
52
+ export interface ProcedurePromise<T> extends Promise<T> {
53
+ /**
54
+ * Promise that resolves to the final result.
55
+ * Chains through to T.result if T has a result property.
56
+ */
57
+ readonly result: Promise<ResultOf<T>>;
58
+ }
59
+ /**
60
+ * Create a ProcedurePromise from a regular Promise.
61
+ *
62
+ * Adds a `.result` property that chains through to the inner handle's result.
63
+ * If the resolved value has a `.result` property, `.result` resolves to that.
64
+ * Otherwise, `.result` resolves to the value itself.
65
+ *
66
+ * @param promise - The base promise to enhance
67
+ * @returns Enhanced ProcedurePromise with .result chaining
68
+ */
69
+ export declare function createProcedurePromise<T>(promise: Promise<T>): ProcedurePromise<T>;
70
+ /**
71
+ * Symbol used to brand Procedure objects for deterministic type checking.
72
+ * Using Symbol.for() ensures the same symbol across module instances.
73
+ */
74
+ export declare const PROCEDURE_SYMBOL: unique symbol;
75
+ /**
76
+ * Check if a value is a Procedure using Symbol branding.
77
+ *
78
+ * This is more reliable than duck typing because it uses a unique Symbol
79
+ * that can only be present on objects created by the procedure system.
80
+ *
81
+ * @param value - The value to check
82
+ * @returns True if the value is a branded Procedure
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const proc = createProcedure(async (x: number) => x * 2);
87
+ * isProcedure(proc); // true
88
+ * isProcedure(() => {}); // false
89
+ * isProcedure({ use: () => {} }); // false (duck typing would say true)
90
+ * ```
91
+ */
92
+ export declare function isProcedure(value: any): value is Procedure<any>;
93
+ /**
94
+ * Middleware function that can intercept and transform procedure execution.
95
+ *
96
+ * Middleware can:
97
+ * - Transform input arguments before passing to the next middleware/handler
98
+ * - Modify the result after `next()` returns
99
+ * - Short-circuit execution by not calling `next()`
100
+ * - Handle or transform errors
101
+ *
102
+ * @typeParam TArgs - The argument types of the procedure
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const loggingMiddleware: Middleware<[string]> = async (args, envelope, next) => {
107
+ * console.log(`${envelope.operationName} called with:`, args);
108
+ * const start = Date.now();
109
+ * try {
110
+ * const result = await next();
111
+ * console.log(`Completed in ${Date.now() - start}ms`);
112
+ * return result;
113
+ * } catch (error) {
114
+ * console.error(`Failed:`, error);
115
+ * throw error;
116
+ * }
117
+ * };
118
+ * ```
119
+ *
120
+ * @example Transform arguments
121
+ * ```typescript
122
+ * const upperMiddleware: Middleware<[string]> = async (args, envelope, next) => {
123
+ * return next([args[0].toUpperCase()]);
124
+ * };
125
+ * ```
126
+ *
127
+ * @see {@link ProcedureEnvelope} - The envelope containing execution metadata
128
+ * @see {@link createPipeline} - Bundle multiple middleware for reuse
129
+ */
130
+ export type Middleware<TArgs extends any[] = any[]> = (args: TArgs, envelope: ProcedureEnvelope<TArgs>, next: (transformedArgs?: TArgs) => Promise<any>) => Promise<any>;
131
+ /**
132
+ * Metadata envelope passed to middleware containing execution context.
133
+ *
134
+ * @typeParam TArgs - The argument types of the procedure
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const middleware: Middleware<[string]> = async (args, envelope, next) => {
139
+ * if (envelope.sourceType === 'hook') {
140
+ * console.log(`Hook ${envelope.operationName} from ${envelope.sourceId}`);
141
+ * }
142
+ * return next();
143
+ * };
144
+ * ```
145
+ */
146
+ export interface ProcedureEnvelope<TArgs extends any[]> {
147
+ /** Whether this is a regular procedure or a hook */
148
+ sourceType: "procedure" | "hook";
149
+ /** Identifier of the source (e.g., class name for decorated methods) */
150
+ sourceId?: string;
151
+ /** Name of the operation being executed */
152
+ operationName: string;
153
+ /** The arguments passed to the procedure */
154
+ args: TArgs;
155
+ /** The current kernel context */
156
+ context: KernelContext;
157
+ /** Procedure metadata (tool names, model IDs, etc.) */
158
+ metadata?: Record<string, unknown>;
159
+ }
160
+ /**
161
+ * Handle for monitoring and controlling a running procedure execution.
162
+ *
163
+ * ExecutionHandle is AsyncIterable for streaming events.
164
+ * Use `.result` to get the final value as a Promise.
165
+ *
166
+ * NOTE: ExecutionHandle is NOT PromiseLike. This is intentional - it allows
167
+ * procedures to return ProcedurePromise<ExecutionHandle> where `await proc()`
168
+ * gives you the handle (not the result). Use `await handle.result` for the
169
+ * final value, or `await proc().result` for a one-liner.
170
+ *
171
+ * @typeParam TResult - The return type of the procedure
172
+ * @typeParam TEvent - The event type for streaming (defaults to any)
173
+ *
174
+ * @example Get handle, then result
175
+ * ```typescript
176
+ * const handle = await myProc('input');
177
+ * handle.status; // 'running'
178
+ * const result = await handle.result;
179
+ * ```
180
+ *
181
+ * @example Get result directly
182
+ * ```typescript
183
+ * const result = await myProc('input').result;
184
+ * ```
185
+ *
186
+ * @example Stream events
187
+ * ```typescript
188
+ * const handle = await myProc('input');
189
+ * for await (const event of handle) {
190
+ * console.log('Event:', event);
191
+ * }
192
+ * ```
193
+ *
194
+ * @example Access status and control
195
+ * ```typescript
196
+ * const handle = await myProc('input');
197
+ * console.log('Status:', handle.status); // 'running'
198
+ * handle.abort('user cancelled');
199
+ * console.log('Status:', handle.status); // 'aborted'
200
+ * ```
201
+ *
202
+ * @see {@link ExecutionHandleImpl} - Default implementation
203
+ * @see {@link HandleFactory} - Custom handle factory function type
204
+ */
205
+ export interface ExecutionHandle<TResult, TEvent extends TypedEvent = any> extends AsyncIterable<TEvent> {
206
+ /** Brand identifying this as an ExecutionHandle (not a plain AsyncIterable) */
207
+ readonly [ExecutionHandleBrand]: true;
208
+ /** Current execution status */
209
+ readonly status: "running" | "completed" | "error" | "aborted" | "cancelled" | "pending" | "failed";
210
+ /** Trace ID for distributed tracing correlation */
211
+ readonly traceId: string;
212
+ /**
213
+ * Event buffer for streaming execution events.
214
+ * Supports dual consumption - multiple iterators can independently consume all events.
215
+ * Late subscribers receive replayed events from the start.
216
+ *
217
+ * API is compatible with EventEmitter: on, once, off, emit, addListener, removeListener.
218
+ * Use `on('eventType', handler)` to subscribe to specific event types.
219
+ * Use `on(handler)` or `on('*', handler)` for wildcard subscription.
220
+ */
221
+ readonly events: EventBuffer<TEvent>;
222
+ /** Abort the execution */
223
+ abort(reason?: string): void;
224
+ /**
225
+ * Promise that resolves with the final result.
226
+ * Use `await handle.result` to get the value.
227
+ */
228
+ readonly result: Promise<TResult>;
229
+ [Symbol.asyncIterator](): AsyncIterator<TEvent>;
230
+ }
231
+ /**
232
+ * Default implementation of ExecutionHandle.
233
+ *
234
+ * Creates a handle that wraps a result promise and event stream.
235
+ * Uses EventBuffer for dual consumption - multiple iterators can independently
236
+ * consume all events, and late subscribers receive replayed events.
237
+ *
238
+ * @typeParam TResult - The return type of the procedure
239
+ * @typeParam TEvent - The event type for streaming
240
+ */
241
+ export declare class ExecutionHandleImpl<TResult, TEvent extends TypedEvent = any> implements ExecutionHandle<TResult, TEvent> {
242
+ readonly result: Promise<TResult>;
243
+ readonly traceId: string;
244
+ readonly [ExecutionHandleBrand]: true;
245
+ private _status;
246
+ private _abortController;
247
+ readonly events: EventBuffer<TEvent>;
248
+ constructor(result: Promise<TResult>, events: EventBuffer<TEvent>, traceId: string, abortController?: AbortController);
249
+ get status(): "running" | "completed" | "error" | "aborted";
250
+ abort(reason?: string): void;
251
+ /**
252
+ * Push an event to the buffer.
253
+ * This is the primary way to emit events from procedure handlers.
254
+ */
255
+ pushEvent(event: TEvent): void;
256
+ [Symbol.asyncIterator](): AsyncIterator<TEvent>;
257
+ }
258
+ /**
259
+ * Factory function for creating custom execution handles.
260
+ *
261
+ * Use this to provide custom handle implementations with additional
262
+ * functionality like cancellation, status tracking, or specialized events.
263
+ *
264
+ * @typeParam THandle - The custom handle type (must extend ExecutionHandle)
265
+ * @typeParam TContext - The context type (must extend KernelContext)
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * const customHandleFactory: HandleFactory = (events, traceId, result, context, abortController) => {
270
+ * const handle = new ExecutionHandleImpl(result, events, traceId, abortController);
271
+ * // Add custom properties/methods
272
+ * return Object.assign(handle, {
273
+ * customMethod() { ... }
274
+ * });
275
+ * };
276
+ *
277
+ * const proc = createProcedure(
278
+ * { handleFactory: customHandleFactory },
279
+ * async (input) => input
280
+ * );
281
+ * ```
282
+ *
283
+ * @see {@link ExecutionHandle} - The base handle interface
284
+ * @see {@link ExecutionHandleImpl} - Default implementation
285
+ */
286
+ export type HandleFactory<THandle extends ExecutionHandle<any, any> = ExecutionHandle<any, any>, TContext extends KernelContext = KernelContext> = (events: EventBuffer<any>, traceId: string, result: Promise<any>, context: TContext, abortController?: AbortController) => THandle;
287
+ /**
288
+ * Configuration options for creating a procedure.
289
+ *
290
+ * @example
291
+ * ```typescript
292
+ * const proc = createProcedure({
293
+ * name: 'myProcedure',
294
+ * schema: z.object({ input: z.string() }),
295
+ * middleware: [loggingMiddleware],
296
+ * timeout: 5000,
297
+ * }, async ({ input }) => input.toUpperCase());
298
+ * ```
299
+ *
300
+ * @see {@link createProcedure} - Create a procedure with these options
301
+ */
302
+ export interface ProcedureOptions {
303
+ /** Name of the procedure (used in telemetry and logging) */
304
+ name?: string;
305
+ /** Middleware pipeline to apply to this procedure */
306
+ middleware?: (Middleware<any[]> | MiddlewarePipeline)[];
307
+ /**
308
+ * Factory for creating execution handles.
309
+ *
310
+ * - `undefined` (default): Creates ExecutionHandleImpl, returns ExecutionHandle
311
+ * - `HandleFactory`: Creates custom handle, returns that handle type
312
+ * - `false`: Pass-through mode - no handle created, returns handler result directly
313
+ *
314
+ * Use `false` for procedures that delegate to other procedures returning handles,
315
+ * avoiding double-wrapping.
316
+ *
317
+ * @example Pass-through procedure
318
+ * ```typescript
319
+ * const run = createProcedure(
320
+ * { name: 'agentick:run', handleFactory: false },
321
+ * (element, input) => app.run(input) // Returns SessionExecutionHandle directly
322
+ * );
323
+ * ```
324
+ */
325
+ handleFactory?: HandleFactory | true | false;
326
+ /**
327
+ * Schema for input validation.
328
+ * Supports Zod 3, Zod 4, Standard Schema, or any schema with parse/validate method.
329
+ */
330
+ schema?: unknown;
331
+ /** Parent procedure name (for hooks) */
332
+ parentProcedure?: string;
333
+ /** @internal Whether this is a procedure or hook */
334
+ sourceType?: "procedure" | "hook";
335
+ /** @internal Source identifier (e.g., class name) */
336
+ sourceId?: string;
337
+ /** Metadata for telemetry span attributes (e.g., { type: 'tool', id: 'myTool' }) */
338
+ metadata?: Record<string, any>;
339
+ /** Timeout in milliseconds. If exceeded, throws AbortError.timeout() */
340
+ timeout?: number;
341
+ /**
342
+ * Skip ExecutionTracker procedure tracking for this procedure.
343
+ * Used for transparent wrappers like withContext() that delegate to another procedure.
344
+ * @internal
345
+ */
346
+ skipTracking?: boolean;
347
+ /**
348
+ * Declarative execution boundary configuration.
349
+ *
350
+ * - `'always'`: Always create a new root execution (engine:execute, engine:stream)
351
+ * - `'child'`: Always create a new child execution (component_tool, fork, spawn)
352
+ * - `'auto'`: Create only if not already in an execution (model:generate, model:stream)
353
+ * - `false`: Never create an execution boundary (compile:tick, internal procedures)
354
+ *
355
+ * @default 'auto'
356
+ */
357
+ executionBoundary?: ExecutionBoundaryConfig;
358
+ /**
359
+ * Explicit execution type (e.g., 'engine', 'model', 'component_tool', 'fork', 'spawn').
360
+ * If not provided, derived from procedure name.
361
+ * Only used when this procedure becomes an execution boundary.
362
+ */
363
+ executionType?: string;
364
+ }
365
+ /**
366
+ * A callable function wrapper with middleware, validation, and execution control.
367
+ *
368
+ * Procedures are the core execution primitive in Agentick. They wrap any async function
369
+ * and provide:
370
+ * - **Middleware pipeline** - Transform args, intercept results, handle errors
371
+ * - **Schema validation** - Zod-based input validation
372
+ * - **Execution handles** - Every call returns ExecutionHandle for control
373
+ * - **Automatic tracking** - Every call is tracked in the procedure graph
374
+ * - **Composition** - Chain procedures with `.pipe()`
375
+ *
376
+ * Procedures return ProcedurePromise wrapping ExecutionHandle (AsyncIterable):
377
+ * - `await proc(args)` → ExecutionHandle (status, abort, streaming)
378
+ * - `await proc(args).result` → the final value
379
+ * - `for await (const event of await proc(args))` → streams events
380
+ *
381
+ * @typeParam THandler - The function type being wrapped
382
+ *
383
+ * @example Get handle, then result
384
+ * ```typescript
385
+ * const greet = createProcedure(async (name: string) => `Hello, ${name}!`);
386
+ * const handle = await greet('World');
387
+ * const result = await handle.result; // 'Hello, World!'
388
+ * ```
389
+ *
390
+ * @example Stream events
391
+ * ```typescript
392
+ * const handle = await proc(input);
393
+ * for await (const event of handle) {
394
+ * console.log('Event:', event);
395
+ * }
396
+ * ```
397
+ *
398
+ * @example Access handle status
399
+ * ```typescript
400
+ * const handle = proc(input);
401
+ * console.log('Status:', handle.status); // 'running'
402
+ * handle.abort('cancelled');
403
+ * ```
404
+ *
405
+ * @example With middleware
406
+ * ```typescript
407
+ * const proc = createProcedure(async (x: number) => x * 2)
408
+ * .use(loggingMiddleware)
409
+ * .use(timingMiddleware);
410
+ * ```
411
+ *
412
+ * @see {@link createProcedure} - Create a new procedure
413
+ * @see {@link Middleware} - Middleware function type
414
+ * @see {@link ExecutionHandle} - Handle for execution control
415
+ */
416
+ export interface Procedure<THandler extends (...args: any[]) => any, TPassThrough extends boolean = false> {
417
+ /**
418
+ * Call the procedure directly.
419
+ * Returns ProcedurePromise — supports `.result` chaining in all modes.
420
+ *
421
+ * Usage:
422
+ * - `await proc()` → ExecutionHandle (or T in passthrough mode)
423
+ * - `await proc().result` → T (the final value)
424
+ */
425
+ (...args: ExtractArgs<THandler>): TPassThrough extends true ? ProcedurePromise<ExtractReturn<THandler>> : ProcedurePromise<ExecutionHandle<ExtractReturn<THandler>>>;
426
+ /**
427
+ * Execute the procedure with explicit arguments.
428
+ * Equivalent to direct call.
429
+ */
430
+ exec(...args: ExtractArgs<THandler>): TPassThrough extends true ? ProcedurePromise<ExtractReturn<THandler>> : ProcedurePromise<ExecutionHandle<ExtractReturn<THandler>>>;
431
+ /**
432
+ * Add middleware to the procedure. Returns a new Procedure (immutable).
433
+ * Typed overload preserves IntelliSense for inline middleware.
434
+ * Generic overload accepts pre-built middleware (guards, logging, etc.).
435
+ */
436
+ use(...middleware: (Middleware<ExtractArgs<THandler>> | MiddlewarePipeline)[]): Procedure<THandler, TPassThrough>;
437
+ use(...middleware: (Middleware | MiddlewarePipeline)[]): Procedure<THandler, TPassThrough>;
438
+ /**
439
+ * Create a procedure variant with merged context. Returns a new Procedure.
440
+ * @param ctx - Partial context to merge with the current context
441
+ */
442
+ withContext(ctx: Partial<KernelContext>): Procedure<THandler, TPassThrough>;
443
+ /**
444
+ * Add a single middleware. Returns a new Procedure.
445
+ * Convenience method equivalent to `.use(mw)`.
446
+ */
447
+ withMiddleware(mw: Middleware<ExtractArgs<THandler>> | Middleware | MiddlewarePipeline): Procedure<THandler, TPassThrough>;
448
+ /**
449
+ * Create a procedure variant with a timeout. Returns a new Procedure.
450
+ * Throws `AbortError.timeout()` if the timeout is exceeded.
451
+ * @param ms - Timeout in milliseconds
452
+ */
453
+ withTimeout(ms: number): Procedure<THandler, TPassThrough>;
454
+ /**
455
+ * Create a procedure variant with merged metadata. Returns a new Procedure.
456
+ * Metadata is passed to ExecutionTracker and included in procedure events.
457
+ * Useful for passing model IDs, tool names, or other execution-specific info.
458
+ *
459
+ * @param metadata - Metadata to merge with existing procedure metadata
460
+ *
461
+ * @example
462
+ * ```typescript
463
+ * // Model adapter passes model info
464
+ * const result = await model.generate
465
+ * .withMetadata({ modelId: 'gpt-4o', provider: 'openai' })
466
+ * .exec(messages);
467
+ *
468
+ * // Tool passes tool info
469
+ * const result = await tool.execute
470
+ * .withMetadata({ toolName: 'search', toolId: 'search-v2' })
471
+ * .exec(input);
472
+ * ```
473
+ */
474
+ withMetadata(metadata: Record<string, unknown>): Procedure<THandler, TPassThrough>;
475
+ /**
476
+ * Pipe the output of this procedure to another procedure.
477
+ * Creates a new procedure that runs this procedure, then passes its result to the next.
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * const parse = createProcedure(async (input: string) => JSON.parse(input));
482
+ * const validate = createProcedure(async (data: object) => schema.parse(data));
483
+ * const transform = createProcedure(async (valid: Valid) => transform(valid));
484
+ *
485
+ * const pipeline = parse.pipe(validate).pipe(transform);
486
+ * const result = await pipeline('{"name": "test"}');
487
+ * ```
488
+ */
489
+ pipe<TNext extends (arg: ExtractReturn<THandler>) => any>(next: Procedure<TNext>): Procedure<(...args: ExtractArgs<THandler>) => Promise<ExtractReturn<TNext>>, TPassThrough>;
490
+ }
491
+ /**
492
+ * Helper type to extract argument types from a function signature.
493
+ * Handles functions with `this` parameters and generator functions.
494
+ *
495
+ * @example
496
+ * ```typescript
497
+ * type Args1 = ExtractArgs<(input: string) => void>; // [string]
498
+ * type Args2 = ExtractArgs<(this: Test, input: string) => void>; // [string]
499
+ * type Args3 = ExtractArgs<() => Generator<string>>; // []
500
+ * ```
501
+ */
502
+ export type ExtractArgs<T> = T extends {
503
+ (this: infer _This, ...args: infer Args): any;
504
+ } ? Args : T extends {
505
+ (...args: infer Args): any;
506
+ } ? Args : T extends {
507
+ (this: infer _This, ...args: infer Args): Generator<infer _Y, infer _R, infer _N>;
508
+ } ? Args : T extends {
509
+ (...args: infer Args): Generator<infer _Y, infer _R, infer _N>;
510
+ } ? Args : T extends {
511
+ (this: infer _This, ...args: infer Args): AsyncGenerator<infer _Y, infer _R, infer _N>;
512
+ } ? Args : T extends {
513
+ (...args: infer Args): AsyncGenerator<infer _Y, infer _R, infer _N>;
514
+ } ? Args : never;
515
+ /**
516
+ * Helper type to extract return type from a function signature.
517
+ * Handles both Promise and direct returns, and unwraps Promise.
518
+ * Preserves AsyncIterable as-is.
519
+ */
520
+ export type ExtractReturn<T> = T extends (...args: any[]) => infer Return ? Return extends Promise<infer U> ? U : Return extends AsyncIterable<any> ? Return : Return : never;
521
+ /**
522
+ * Helper type to transform a method signature to Procedure type.
523
+ * Extracts args and return type, then creates Procedure<TArgs, TOutput>.
524
+ *
525
+ * Use this type to get proper IntelliSense for decorated methods:
526
+ *
527
+ * @example
528
+ * ```typescript
529
+ * class Model {
530
+ * @procedure()
531
+ * async execute(input: string): Promise<string> { ... }
532
+ * }
533
+ *
534
+ * // For IntelliSense, you can use:
535
+ * type ModelWithProcedures = {
536
+ * execute: AsProcedure<Model['execute']>;
537
+ * };
538
+ *
539
+ * // Or cast at usage:
540
+ * const model = new Model();
541
+ * const execute = model.execute as AsProcedure<typeof model.execute>;
542
+ * ```
543
+ */
544
+ export type AsProcedure<T extends (...args: any[]) => any> = Procedure<T>;
545
+ /**
546
+ * Helper type to transform all methods in a class to Procedures.
547
+ *
548
+ * **Primary Use Case**: Use with decorators when you need IntelliSense.
549
+ *
550
+ * ```typescript
551
+ * class Model {
552
+ * @procedure()
553
+ * async execute(input: string): Promise<string> { ... }
554
+ * }
555
+ *
556
+ * // Most of the time - runtime works perfectly, no types needed
557
+ * const model = new Model();
558
+ * await model.execute('test'); // ✅ Works
559
+ *
560
+ * // When you need IntelliSense - cast once
561
+ * const typedModel = model as WithProcedures<Model>;
562
+ * typedModel.execute.use(...); // ✅ Full IntelliSense
563
+ * typedModel.execute.withHandle(); // ✅ Full IntelliSense
564
+ * ```
565
+ *
566
+ * **Alternative**: Use property initializers for full types everywhere:
567
+ * ```typescript
568
+ * class Model {
569
+ * execute = createProcedure(async (input: string) => input);
570
+ * // ✅ Full types always, but more verbose
571
+ * }
572
+ * ```
573
+ */
574
+ export type WithProcedures<T> = {
575
+ [K in keyof T]: T[K] extends (...args: any[]) => any ? AsProcedure<T[K]> : T[K];
576
+ };
577
+ /**
578
+ * A reusable bundle of middleware that can be applied to procedures.
579
+ *
580
+ * Pipelines allow you to define common middleware combinations once
581
+ * and reuse them across multiple procedures.
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * const commonPipeline = createPipeline()
586
+ * .use(loggingMiddleware)
587
+ * .use(timingMiddleware)
588
+ * .use(errorHandlingMiddleware);
589
+ *
590
+ * const proc1 = createProcedure(handler1).use(commonPipeline);
591
+ * const proc2 = createProcedure(handler2).use(commonPipeline);
592
+ * ```
593
+ *
594
+ * @see {@link createPipeline} - Create a new middleware pipeline
595
+ * @see {@link Middleware} - Individual middleware function type
596
+ */
597
+ export interface MiddlewarePipeline {
598
+ /** Add middleware to this pipeline. Returns the pipeline for chaining. */
599
+ use(...middleware: Middleware<any[]>[]): MiddlewarePipeline;
600
+ /** Get all middleware in this pipeline. */
601
+ getMiddleware(): Middleware<any[]>[];
602
+ }
603
+ /**
604
+ * Create a reusable middleware pipeline.
605
+ *
606
+ * Pipelines bundle multiple middleware together for reuse across procedures.
607
+ * They can be passed to `procedure.use()` just like individual middleware.
608
+ *
609
+ * @param middleware - Initial middleware to include in the pipeline
610
+ * @returns A new MiddlewarePipeline
611
+ *
612
+ * @example
613
+ * ```typescript
614
+ * // Create a pipeline with initial middleware
615
+ * const authPipeline = createPipeline([authMiddleware, rateLimitMiddleware]);
616
+ *
617
+ * // Or build it up with .use()
618
+ * const logPipeline = createPipeline()
619
+ * .use(requestLogging)
620
+ * .use(responseLogging);
621
+ *
622
+ * // Apply to procedures
623
+ * const proc = createProcedure(handler)
624
+ * .use(authPipeline)
625
+ * .use(logPipeline);
626
+ * ```
627
+ *
628
+ * @see {@link MiddlewarePipeline} - The pipeline interface
629
+ */
630
+ export declare function createPipeline(middleware?: Middleware<any[]>[]): MiddlewarePipeline;
631
+ export declare function isAsyncIterable(obj: any): obj is AsyncIterable<any>;
632
+ /**
633
+ * Helper to create a generator procedure that captures 'this' context.
634
+ */
635
+ type Handler<TArgs extends any[]> = ((...args: TArgs) => any) | ((this: any, ...args: TArgs) => any);
636
+ export declare function generatorProcedure<TThis, TArgs extends any[], THandler extends Handler<TArgs>>(optionsOrFn?: ProcedureOptions | THandler, fn?: THandler): Procedure<THandler>;
637
+ /**
638
+ * Create a Procedure from a function.
639
+ *
640
+ * By default, calling the procedure returns an ExecutionHandle.
641
+ * Use `handleFactory: false` for pass-through mode where the handler's
642
+ * return value is returned directly (useful for delegating to other procedures).
643
+ *
644
+ * @example Standard procedure (returns ExecutionHandle)
645
+ * ```typescript
646
+ * const greet = createProcedure(async (name: string) => `Hello, ${name}!`);
647
+ * const handle = greet('World'); // ExecutionHandle
648
+ * const result = await handle; // "Hello, World!"
649
+ * ```
650
+ *
651
+ * @example Pass-through procedure (returns handler result directly)
652
+ * ```typescript
653
+ * const run = createProcedure(
654
+ * { name: 'agentick:run', handleFactory: false },
655
+ * (element, input) => app.run(input) // Returns SessionExecutionHandle
656
+ * );
657
+ * const handle = run(<jsx />, opts); // SessionExecutionHandle directly
658
+ * ```
659
+ */
660
+ export declare function createProcedure<THandler extends (...args: any[]) => any>(handler: THandler): Procedure<THandler>;
661
+ export declare function createProcedure<THandler extends (...args: any[]) => any>(options: ProcedureOptions & {
662
+ handleFactory: false;
663
+ }, handler: THandler): Procedure<THandler, true>;
664
+ export declare function createProcedure<THandler extends (...args: any[]) => any>(options: ProcedureOptions, handler: THandler): Procedure<THandler>;
665
+ /**
666
+ * Pipe multiple procedures together, passing the output of each to the next.
667
+ *
668
+ * @example
669
+ * ```typescript
670
+ * const parse = createProcedure(async (json: string) => JSON.parse(json));
671
+ * const validate = createProcedure(async (data: unknown) => schema.parse(data));
672
+ * const transform = createProcedure(async (valid: Valid) => transform(valid));
673
+ *
674
+ * // Create a pipeline that parses, validates, then transforms
675
+ * const pipeline = pipe(parse, validate, transform);
676
+ * const result = await pipeline('{"name": "test"}');
677
+ * ```
678
+ */
679
+ export declare function pipe<T1 extends (...args: any[]) => any>(p1: Procedure<T1>): Procedure<T1>;
680
+ export declare function pipe<T1 extends (...args: any[]) => any, T2 extends (arg: ExtractReturn<T1>) => any>(p1: Procedure<T1>, p2: Procedure<T2>): Procedure<(...args: ExtractArgs<T1>) => Promise<ExtractReturn<T2>>>;
681
+ export declare function pipe<T1 extends (...args: any[]) => any, T2 extends (arg: ExtractReturn<T1>) => any, T3 extends (arg: ExtractReturn<T2>) => any>(p1: Procedure<T1>, p2: Procedure<T2>, p3: Procedure<T3>): Procedure<(...args: ExtractArgs<T1>) => Promise<ExtractReturn<T3>>>;
682
+ export declare function pipe<T1 extends (...args: any[]) => any, T2 extends (arg: ExtractReturn<T1>) => any, T3 extends (arg: ExtractReturn<T2>) => any, T4 extends (arg: ExtractReturn<T3>) => any>(p1: Procedure<T1>, p2: Procedure<T2>, p3: Procedure<T3>, p4: Procedure<T4>): Procedure<(...args: ExtractArgs<T1>) => Promise<ExtractReturn<T4>>>;
683
+ export declare function pipe<T1 extends (...args: any[]) => any, T2 extends (arg: ExtractReturn<T1>) => any, T3 extends (arg: ExtractReturn<T2>) => any, T4 extends (arg: ExtractReturn<T3>) => any, T5 extends (arg: ExtractReturn<T4>) => any>(p1: Procedure<T1>, p2: Procedure<T2>, p3: Procedure<T3>, p4: Procedure<T4>, p5: Procedure<T5>): Procedure<(...args: ExtractArgs<T1>) => Promise<ExtractReturn<T5>>>;
684
+ /**
685
+ * Compose multiple procedures into a single procedure (right-to-left execution).
686
+ * This is the functional programming convention: compose(a, b, c)(x) = a(b(c(x)))
687
+ *
688
+ * For left-to-right execution, use `pipe()` instead.
689
+ *
690
+ * @example
691
+ * ```typescript
692
+ * const format = createProcedure((s: string) => s.toUpperCase());
693
+ * const validate = createProcedure((s: string) => s.trim());
694
+ * const parse = createProcedure((input: string) => input);
695
+ *
696
+ * // compose executes right-to-left: parse -> validate -> format
697
+ * const pipeline = compose(format, validate, parse);
698
+ * const result = await pipeline(' hello '); // "HELLO"
699
+ * ```
700
+ */
701
+ export declare function compose<T1 extends (...args: any[]) => any>(p1: Procedure<T1>): Procedure<T1>;
702
+ export declare function compose<T1 extends (arg: ExtractReturn<T2>) => any, T2 extends (...args: any[]) => any>(p1: Procedure<T1>, p2: Procedure<T2>): Procedure<(...args: ExtractArgs<T2>) => Promise<ExtractReturn<T1>>>;
703
+ export declare function compose<T1 extends (arg: ExtractReturn<T2>) => any, T2 extends (arg: ExtractReturn<T3>) => any, T3 extends (...args: any[]) => any>(p1: Procedure<T1>, p2: Procedure<T2>, p3: Procedure<T3>): Procedure<(...args: ExtractArgs<T3>) => Promise<ExtractReturn<T1>>>;
704
+ export declare function compose<T1 extends (arg: ExtractReturn<T2>) => any, T2 extends (arg: ExtractReturn<T3>) => any, T3 extends (arg: ExtractReturn<T4>) => any, T4 extends (...args: any[]) => any>(p1: Procedure<T1>, p2: Procedure<T2>, p3: Procedure<T3>, p4: Procedure<T4>): Procedure<(...args: ExtractArgs<T4>) => Promise<ExtractReturn<T1>>>;
705
+ export declare function compose<T1 extends (arg: ExtractReturn<T2>) => any, T2 extends (arg: ExtractReturn<T3>) => any, T3 extends (arg: ExtractReturn<T4>) => any, T4 extends (arg: ExtractReturn<T5>) => any, T5 extends (...args: any[]) => any>(p1: Procedure<T1>, p2: Procedure<T2>, p3: Procedure<T3>, p4: Procedure<T4>, p5: Procedure<T5>): Procedure<(...args: ExtractArgs<T5>) => Promise<ExtractReturn<T1>>>;
706
+ /**
707
+ * Create a Hook Procedure from a function.
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * const processChunk = createHook(async (chunk: string) => chunk.toUpperCase());
712
+ * // Type inferred: Procedure<[string], string>
713
+ * ```
714
+ */
715
+ export declare function createHook<THandler extends (...args: any[]) => any>(handler: THandler): Procedure<THandler>;
716
+ export declare function createHook<THandler extends (...args: any[]) => any>(options: ProcedureOptions, handler: THandler): Procedure<THandler>;
717
+ /**
718
+ * Type-safe helper to apply middleware to a Procedure while preserving types.
719
+ *
720
+ * This helper ensures that middleware types are correctly matched to the Procedure's
721
+ * argument types, avoiding the need for type assertions.
722
+ *
723
+ * @example
724
+ * ```typescript
725
+ * const proc = createProcedure({ name: 'test' }, async (input: string) => input);
726
+ * const middleware: Middleware<[string]>[] = [...];
727
+ * const procWithMw = applyMiddleware(proc, middleware);
728
+ * // procWithMw is still Procedure<[string], string> - types preserved!
729
+ * ```
730
+ */
731
+ export declare function applyMiddleware<TArgs extends any[], TOutput>(procedure: Procedure<(...args: TArgs) => TOutput>, ...middleware: (Middleware<TArgs> | MiddlewarePipeline)[]): Procedure<(...args: TArgs) => TOutput>;
732
+ /**
733
+ * Type-safe helper to apply middleware from a registry/hook system.
734
+ *
735
+ * This is useful when middleware comes from hook registries where types might
736
+ * be unions or `Middleware<any[]>`. The helper ensures type safety by requiring
737
+ * the middleware to match the Procedure's argument types.
738
+ *
739
+ * @example
740
+ * ```typescript
741
+ * const proc = createProcedure({ name: 'test' }, async (input: string) => input);
742
+ * const registryMiddleware = registry.getMiddleware('test'); // Middleware<any[]>[]
743
+ * const procWithMw = applyRegistryMiddleware(proc, registryMiddleware);
744
+ * // Types are preserved and validated
745
+ * ```
746
+ */
747
+ export declare function applyRegistryMiddleware<THandler extends (...args: any[]) => any>(procedure: Procedure<THandler>, ...middleware: (Middleware<any[]> | MiddlewarePipeline)[]): Procedure<THandler>;
748
+ export declare function wrapProcedure(middleware: Middleware<any[]>[]): {
749
+ <THandler extends (...args: any[]) => any>(handler: THandler): Procedure<THandler>;
750
+ <THandler extends (...args: any[]) => any>(config: ProcedureOptions, handler: THandler): Procedure<THandler>;
751
+ };
752
+ export declare function wrapHook(middleware: Middleware<any[]>[]): {
753
+ <THandler extends (...args: any[]) => any>(handler: THandler): Procedure<THandler>;
754
+ <THandler extends (...args: any[]) => any>(config: ProcedureOptions, handler: THandler): Procedure<THandler>;
755
+ };
756
+ export {};
757
+ //# sourceMappingURL=procedure.d.ts.map