@tanstack/ai 0.35.0 → 0.36.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/package.json +2 -2
- package/skills/ai-core/tool-calling/SKILL.md +26 -1
- package/src/activities/chat/index.ts +8 -0
- package/src/activities/chat/tools/lazy-tool-manager.ts +12 -4
- package/src/activities/chat/tools/lazy-tools.ts +33 -0
- package/src/index.ts +5 -0
- package/src/types.ts +23 -1
- package/dist/esm/activities/chat/adapter.d.ts +0 -163
- package/dist/esm/activities/chat/adapter.js +0 -17
- package/dist/esm/activities/chat/adapter.js.map +0 -1
- package/dist/esm/activities/chat/agent-loop-strategies.d.ts +0 -59
- package/dist/esm/activities/chat/agent-loop-strategies.js +0 -23
- package/dist/esm/activities/chat/agent-loop-strategies.js.map +0 -1
- package/dist/esm/activities/chat/index.d.ts +0 -264
- package/dist/esm/activities/chat/index.js +0 -1723
- package/dist/esm/activities/chat/index.js.map +0 -1
- package/dist/esm/activities/chat/mcp/manager.d.ts +0 -25
- package/dist/esm/activities/chat/mcp/manager.js +0 -71
- package/dist/esm/activities/chat/mcp/manager.js.map +0 -1
- package/dist/esm/activities/chat/mcp/types.d.ts +0 -56
- package/dist/esm/activities/chat/messages.d.ts +0 -78
- package/dist/esm/activities/chat/messages.js +0 -374
- package/dist/esm/activities/chat/messages.js.map +0 -1
- package/dist/esm/activities/chat/middleware/builder.d.ts +0 -46
- package/dist/esm/activities/chat/middleware/builder.js +0 -17
- package/dist/esm/activities/chat/middleware/builder.js.map +0 -1
- package/dist/esm/activities/chat/middleware/capabilities.d.ts +0 -93
- package/dist/esm/activities/chat/middleware/capabilities.js +0 -45
- package/dist/esm/activities/chat/middleware/capabilities.js.map +0 -1
- package/dist/esm/activities/chat/middleware/compose.d.ts +0 -87
- package/dist/esm/activities/chat/middleware/compose.js +0 -510
- package/dist/esm/activities/chat/middleware/compose.js.map +0 -1
- package/dist/esm/activities/chat/middleware/define.d.ts +0 -20
- package/dist/esm/activities/chat/middleware/define.js +0 -7
- package/dist/esm/activities/chat/middleware/define.js.map +0 -1
- package/dist/esm/activities/chat/middleware/index.d.ts +0 -10
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.d.ts +0 -89
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +0 -76
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +0 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +0 -405
- package/dist/esm/activities/chat/middleware/validate.d.ts +0 -19
- package/dist/esm/activities/chat/middleware/validate.js +0 -30
- package/dist/esm/activities/chat/middleware/validate.js.map +0 -1
- package/dist/esm/activities/chat/runtime-context-types.d.ts +0 -43
- package/dist/esm/activities/chat/stream/index.d.ts +0 -11
- package/dist/esm/activities/chat/stream/json-parser.d.ts +0 -38
- package/dist/esm/activities/chat/stream/json-parser.js +0 -28
- package/dist/esm/activities/chat/stream/json-parser.js.map +0 -1
- package/dist/esm/activities/chat/stream/message-updaters.d.ts +0 -81
- package/dist/esm/activities/chat/stream/message-updaters.js +0 -253
- package/dist/esm/activities/chat/stream/message-updaters.js.map +0 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +0 -439
- package/dist/esm/activities/chat/stream/processor.js +0 -1426
- package/dist/esm/activities/chat/stream/processor.js.map +0 -1
- package/dist/esm/activities/chat/stream/strategies.d.ts +0 -43
- package/dist/esm/activities/chat/stream/strategies.js +0 -54
- package/dist/esm/activities/chat/stream/strategies.js.map +0 -1
- package/dist/esm/activities/chat/stream/types.d.ts +0 -90
- package/dist/esm/activities/chat/tools/lazy-tool-manager.d.ts +0 -81
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js +0 -188
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +0 -1
- package/dist/esm/activities/chat/tools/schema-converter.d.ts +0 -140
- package/dist/esm/activities/chat/tools/schema-converter.js +0 -167
- package/dist/esm/activities/chat/tools/schema-converter.js.map +0 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +0 -140
- package/dist/esm/activities/chat/tools/tool-calls.js +0 -512
- package/dist/esm/activities/chat/tools/tool-calls.js.map +0 -1
- package/dist/esm/activities/chat/tools/tool-definition.d.ts +0 -135
- package/dist/esm/activities/chat/tools/tool-definition.js +0 -25
- package/dist/esm/activities/chat/tools/tool-definition.js.map +0 -1
- package/dist/esm/activities/error-payload.d.ts +0 -30
- package/dist/esm/activities/error-payload.js +0 -54
- package/dist/esm/activities/error-payload.js.map +0 -1
- package/dist/esm/activities/generateAudio/adapter.d.ts +0 -62
- package/dist/esm/activities/generateAudio/adapter.js +0 -16
- package/dist/esm/activities/generateAudio/adapter.js.map +0 -1
- package/dist/esm/activities/generateAudio/index.d.ts +0 -85
- package/dist/esm/activities/generateAudio/index.js +0 -114
- package/dist/esm/activities/generateAudio/index.js.map +0 -1
- package/dist/esm/activities/generateImage/adapter.d.ts +0 -78
- package/dist/esm/activities/generateImage/adapter.js +0 -16
- package/dist/esm/activities/generateImage/adapter.js.map +0 -1
- package/dist/esm/activities/generateImage/index.d.ts +0 -134
- package/dist/esm/activities/generateImage/index.js +0 -121
- package/dist/esm/activities/generateImage/index.js.map +0 -1
- package/dist/esm/activities/generateSpeech/adapter.d.ts +0 -62
- package/dist/esm/activities/generateSpeech/adapter.js +0 -16
- package/dist/esm/activities/generateSpeech/adapter.js.map +0 -1
- package/dist/esm/activities/generateSpeech/index.d.ts +0 -96
- package/dist/esm/activities/generateSpeech/index.js +0 -119
- package/dist/esm/activities/generateSpeech/index.js.map +0 -1
- package/dist/esm/activities/generateTranscription/adapter.d.ts +0 -62
- package/dist/esm/activities/generateTranscription/adapter.js +0 -16
- package/dist/esm/activities/generateTranscription/adapter.js.map +0 -1
- package/dist/esm/activities/generateTranscription/index.d.ts +0 -109
- package/dist/esm/activities/generateTranscription/index.js +0 -109
- package/dist/esm/activities/generateTranscription/index.js.map +0 -1
- package/dist/esm/activities/generateVideo/adapter.d.ts +0 -145
- package/dist/esm/activities/generateVideo/adapter.js +0 -30
- package/dist/esm/activities/generateVideo/adapter.js.map +0 -1
- package/dist/esm/activities/generateVideo/index.d.ts +0 -223
- package/dist/esm/activities/generateVideo/index.js +0 -295
- package/dist/esm/activities/generateVideo/index.js.map +0 -1
- package/dist/esm/activities/generateVideo/snap.d.ts +0 -14
- package/dist/esm/activities/generateVideo/snap.js +0 -54
- package/dist/esm/activities/generateVideo/snap.js.map +0 -1
- package/dist/esm/activities/index.d.ts +0 -27
- package/dist/esm/activities/index.js +0 -43
- package/dist/esm/activities/index.js.map +0 -1
- package/dist/esm/activities/middleware/index.d.ts +0 -2
- package/dist/esm/activities/middleware/run.d.ts +0 -20
- package/dist/esm/activities/middleware/run.js +0 -42
- package/dist/esm/activities/middleware/run.js.map +0 -1
- package/dist/esm/activities/middleware/types.d.ts +0 -118
- package/dist/esm/activities/stream-generation-result.d.ts +0 -15
- package/dist/esm/activities/stream-generation-result.js +0 -49
- package/dist/esm/activities/stream-generation-result.js.map +0 -1
- package/dist/esm/activities/summarize/adapter.d.ts +0 -74
- package/dist/esm/activities/summarize/adapter.js +0 -16
- package/dist/esm/activities/summarize/adapter.js.map +0 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +0 -45
- package/dist/esm/activities/summarize/chat-stream-summarize.js +0 -212
- package/dist/esm/activities/summarize/chat-stream-summarize.js.map +0 -1
- package/dist/esm/activities/summarize/index.d.ts +0 -108
- package/dist/esm/activities/summarize/index.js +0 -113
- package/dist/esm/activities/summarize/index.js.map +0 -1
- package/dist/esm/adapter-internals.d.ts +0 -5
- package/dist/esm/adapter-internals.js +0 -10
- package/dist/esm/adapter-internals.js.map +0 -1
- package/dist/esm/client.d.ts +0 -44
- package/dist/esm/client.js +0 -67
- package/dist/esm/client.js.map +0 -1
- package/dist/esm/extend-adapter.d.ts +0 -152
- package/dist/esm/extend-adapter.js +0 -21
- package/dist/esm/extend-adapter.js.map +0 -1
- package/dist/esm/index.d.ts +0 -44
- package/dist/esm/index.js +0 -106
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/logger/console-logger.d.ts +0 -29
- package/dist/esm/logger/console-logger.js +0 -83
- package/dist/esm/logger/console-logger.js.map +0 -1
- package/dist/esm/logger/internal-logger.d.ts +0 -41
- package/dist/esm/logger/internal-logger.js +0 -86
- package/dist/esm/logger/internal-logger.js.map +0 -1
- package/dist/esm/logger/resolve.d.ts +0 -14
- package/dist/esm/logger/resolve.js +0 -54
- package/dist/esm/logger/resolve.js.map +0 -1
- package/dist/esm/logger/types.d.ts +0 -75
- package/dist/esm/middlewares/content-guard.d.ts +0 -77
- package/dist/esm/middlewares/content-guard.js +0 -156
- package/dist/esm/middlewares/content-guard.js.map +0 -1
- package/dist/esm/middlewares/index.d.ts +0 -2
- package/dist/esm/middlewares/index.js +0 -7
- package/dist/esm/middlewares/index.js.map +0 -1
- package/dist/esm/middlewares/otel.d.ts +0 -81
- package/dist/esm/middlewares/otel.js +0 -745
- package/dist/esm/middlewares/otel.js.map +0 -1
- package/dist/esm/middlewares/tool-cache.d.ts +0 -1
- package/dist/esm/middlewares/usage-attributes.d.ts +0 -24
- package/dist/esm/middlewares/usage-attributes.js +0 -43
- package/dist/esm/middlewares/usage-attributes.js.map +0 -1
- package/dist/esm/realtime/index.d.ts +0 -28
- package/dist/esm/realtime/index.js +0 -8
- package/dist/esm/realtime/index.js.map +0 -1
- package/dist/esm/realtime/types.d.ts +0 -282
- package/dist/esm/stream-to-response.d.ts +0 -102
- package/dist/esm/stream-to-response.js +0 -121
- package/dist/esm/stream-to-response.js.map +0 -1
- package/dist/esm/strip-to-spec-middleware.d.ts +0 -18
- package/dist/esm/strip-to-spec-middleware.js +0 -20
- package/dist/esm/strip-to-spec-middleware.js.map +0 -1
- package/dist/esm/system-prompts.d.ts +0 -66
- package/dist/esm/system-prompts.js +0 -23
- package/dist/esm/system-prompts.js.map +0 -1
- package/dist/esm/tool-registry.d.ts +0 -81
- package/dist/esm/tool-registry.js +0 -49
- package/dist/esm/tool-registry.js.map +0 -1
- package/dist/esm/tools/provider-tool.d.ts +0 -30
- package/dist/esm/tools/provider-tool.js +0 -7
- package/dist/esm/tools/provider-tool.js.map +0 -1
- package/dist/esm/types.d.ts +0 -1573
- package/dist/esm/utilities/ag-ui-wire.d.ts +0 -44
- package/dist/esm/utilities/ag-ui-wire.js +0 -107
- package/dist/esm/utilities/ag-ui-wire.js.map +0 -1
- package/dist/esm/utilities/chat-params.d.ts +0 -85
- package/dist/esm/utilities/chat-params.js +0 -100
- package/dist/esm/utilities/chat-params.js.map +0 -1
- package/dist/esm/utilities/errors.d.ts +0 -13
- package/dist/esm/utilities/errors.js +0 -22
- package/dist/esm/utilities/errors.js.map +0 -1
- package/dist/esm/utilities/media-prompt.d.ts +0 -35
- package/dist/esm/utilities/media-prompt.js +0 -43
- package/dist/esm/utilities/media-prompt.js.map +0 -1
- package/dist/esm/utilities/numbers.d.ts +0 -8
- package/dist/esm/utilities/numbers.js +0 -12
- package/dist/esm/utilities/numbers.js.map +0 -1
- package/dist/esm/utilities/sampling-keys.d.ts +0 -20
- package/dist/esm/utilities/sampling-keys.js +0 -20
- package/dist/esm/utilities/sampling-keys.js.map +0 -1
- package/dist/esm/utilities/tool-result.d.ts +0 -21
- package/dist/esm/utilities/tool-result.js +0 -37
- package/dist/esm/utilities/tool-result.js.map +0 -1
- package/dist/esm/utilities/usage.d.ts +0 -31
- package/dist/esm/utilities/usage.js +0 -11
- package/dist/esm/utilities/usage.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -17
- package/dist/esm/utils.js +0 -20
- package/dist/esm/utils.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.js","sources":["../../../../../src/activities/chat/middleware/capabilities.ts"],"sourcesContent":["/** Options accepted by a capability getter. */\nexport interface CapabilityGetOptions {\n /** When true, return undefined instead of throwing if the capability is absent. */\n optional?: boolean\n}\n\n/**\n * The minimal context shape a capability accessor needs. The full\n * `ChatMiddlewareContext` satisfies this (it has `capabilities`), so accessors\n * accept any middleware context without referencing `any`.\n */\nexport interface CapabilityContext {\n capabilities: CapabilityRegistry\n}\n\n/** Reads a capability value off a context. Overloaded so the flag narrows the return. */\nexport interface CapabilityGetter<TValue> {\n (ctx: CapabilityContext): TValue\n (ctx: CapabilityContext, opts: { optional: true }): TValue | undefined\n}\n\n/** Writes a capability value onto a context. */\nexport type CapabilityProvider<TValue> = (\n ctx: CapabilityContext,\n value: TValue,\n) => void\n\n/**\n * A capability handle. It is BOTH a `[get, provide]` tuple (array-destructurable)\n * AND the identity used in middleware `requires`/`provides` declarations.\n *\n * Runtime identity is this object's reference. The `capabilityName` literal is\n * used for diagnostics and COMPILE-TIME tracking only — capability names MUST be\n * unique across an app or the type-level coverage check conflates them.\n */\nexport type Capability<\n TValue = unknown,\n TName extends string = string,\n> = readonly [\n get: CapabilityGetter<TValue>,\n provide: CapabilityProvider<TValue>,\n] & {\n readonly capabilityName: TName\n /** @internal Presence check for the post-setup assertion. */\n has: (ctx: CapabilityContext) => boolean\n}\n\n/**\n * A capability handle with permissive value/name — for use as a constraint in\n * `requires`/`provides` arrays. Concentrates `any` in one named alias (same\n * convention as `AnyTextAdapter`/`AnyTool`); needed so `Capability<SpecificT>`\n * is assignable to the handle-array element type.\n */\nexport type CapabilityHandle = Capability<any, string>\n\n/**\n * Per-request bookkeeping: which capabilities were provided, plus the\n * duplicate-provide notification. Capability VALUES live in per-capability\n * WeakMaps (see `createCapability`), not here — this only tracks presence.\n */\nexport class CapabilityRegistry {\n private readonly provided = new Set<CapabilityHandle>()\n private onDuplicate?: (name: string) => void\n\n /** Register a callback fired when a handle is provided more than once. */\n setOnDuplicate(cb: (name: string) => void): void {\n this.onDuplicate = cb\n }\n\n /** Record that `handle` was provided; fire the duplicate callback on repeats. */\n markProvided(handle: CapabilityHandle): void {\n if (this.provided.has(handle)) this.onDuplicate?.(handle.capabilityName)\n this.provided.add(handle)\n }\n\n has(handle: CapabilityHandle): boolean {\n return this.provided.has(handle)\n }\n}\n\n/**\n * Create a capability. Returns a hybrid handle that destructures to\n * `[get, provide]` and is itself the identity for `requires`/`provides`.\n *\n * Curried so the value type is supplied explicitly while the name literal is\n * INFERRED from the argument: `createCapability<T>()('name')`. (A single call\n * `createCapability<T>('name')` cannot work — supplying `T` explicitly stops\n * TypeScript inferring the name, collapsing it to `string` and defeating the\n * compile-time coverage check that keys on the literal name.)\n *\n * @example Provider + consumer middleware\n * ```ts\n * const counterCapability = createCapability<{ value: number }>()('counter')\n * const [getCounter, provideCounter] = counterCapability\n *\n * const withCounter = defineChatMiddleware({\n * name: 'counter',\n * provides: [counterCapability],\n * setup(ctx) { provideCounter(ctx, { value: 0 }) },\n * })\n *\n * const readsCounter = defineChatMiddleware({\n * name: 'reads-counter',\n * requires: [counterCapability],\n * onChunk(ctx) { getCounter(ctx).value++ },\n * })\n *\n * chat({ adapter, messages, middleware: [withCounter, readsCounter] })\n * ```\n *\n * @remarks Capability `name`s must be unique across your app: compile-time\n * coverage tracking keys on the name literal (runtime keys on reference).\n */\nexport function createCapability<TValue = unknown>(): <\n const TName extends string,\n>(\n name: TName,\n) => Capability<TValue, TName> {\n return <const TName extends string>(\n name: TName,\n ): Capability<TValue, TName> => {\n // Each capability owns a typed WeakMap keyed by the context object. Because\n // the value type is TValue, reads are typed with no assertion.\n const values = new WeakMap<CapabilityContext, TValue>()\n\n function get(ctx: CapabilityContext): TValue\n function get(\n ctx: CapabilityContext,\n opts: { optional: true },\n ): TValue | undefined\n function get(\n ctx: CapabilityContext,\n opts?: CapabilityGetOptions,\n ): TValue | undefined {\n if (!values.has(ctx)) {\n if (opts?.optional) return undefined\n throw new Error(\n `Capability \"${name}\" was requested but never provided. Ensure a ` +\n `middleware provides it in setup(), ordered before this consumer.`,\n )\n }\n return values.get(ctx)\n }\n\n const provide: CapabilityProvider<TValue> = (ctx, value) => {\n values.set(ctx, value)\n ctx.capabilities.markProvided(handle)\n }\n\n const pair: readonly [\n CapabilityGetter<TValue>,\n CapabilityProvider<TValue>,\n ] = [get, provide]\n // Object.assign's return type is the intersection of the tuple and the\n // props, which IS Capability<TValue, TName> — no cast needed.\n const handle = Object.assign(pair, {\n capabilityName: name,\n has: (ctx: CapabilityContext) => values.has(ctx),\n })\n return handle\n }\n}\n"],"names":[],"mappings":"AA4DO,MAAM,mBAAmB;AAAA,EACb,+BAAe,IAAA;AAAA,EACxB;AAAA;AAAA,EAGR,eAAe,IAAkC;AAC/C,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,aAAa,QAAgC;AAC3C,QAAI,KAAK,SAAS,IAAI,MAAM,EAAG,MAAK,cAAc,OAAO,cAAc;AACvE,SAAK,SAAS,IAAI,MAAM;AAAA,EAC1B;AAAA,EAEA,IAAI,QAAmC;AACrC,WAAO,KAAK,SAAS,IAAI,MAAM;AAAA,EACjC;AACF;AAmCO,SAAS,mBAIe;AAC7B,SAAO,CACL,SAC8B;AAG9B,UAAM,6BAAa,QAAA;AAOnB,aAAS,IACP,KACA,MACoB;AACpB,UAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AACpB,YAAI,MAAM,SAAU,QAAO;AAC3B,cAAM,IAAI;AAAA,UACR,eAAe,IAAI;AAAA,QAAA;AAAA,MAGvB;AACA,aAAO,OAAO,IAAI,GAAG;AAAA,IACvB;AAEA,UAAM,UAAsC,CAAC,KAAK,UAAU;AAC1D,aAAO,IAAI,KAAK,KAAK;AACrB,UAAI,aAAa,aAAa,MAAM;AAAA,IACtC;AAEA,UAAM,OAGF,CAAC,KAAK,OAAO;AAGjB,UAAM,SAAS,OAAO,OAAO,MAAM;AAAA,MACjC,gBAAgB;AAAA,MAChB,KAAK,CAAC,QAA2B,OAAO,IAAI,GAAG;AAAA,IAAA,CAChD;AACD,WAAO;AAAA,EACT;AACF;"}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { StreamChunk } from '../../../types.js';
|
|
2
|
-
import { InternalLogger } from '../../../logger/internal-logger.js';
|
|
3
|
-
import { AbortInfo, AfterToolCallInfo, BeforeToolCallDecision, ChatMiddleware, ChatMiddlewareConfig, ChatMiddlewareContext, ErrorInfo, FinishInfo, IterationInfo, StructuredOutputMiddlewareConfig, ToolCallHookContext, ToolPhaseCompleteInfo, UsageInfo } from './types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Internal middleware runner that manages composed execution of middleware hooks.
|
|
6
|
-
* Created once per chat() invocation.
|
|
7
|
-
*/
|
|
8
|
-
export declare class MiddlewareRunner<TContext = unknown> {
|
|
9
|
-
private readonly middlewares;
|
|
10
|
-
private readonly logger;
|
|
11
|
-
constructor(middlewares: ReadonlyArray<ChatMiddleware<TContext>>, logger: InternalLogger);
|
|
12
|
-
get hasMiddleware(): boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Pipe config through all middleware onConfig hooks in order.
|
|
15
|
-
* Each middleware receives the merged config from previous middleware.
|
|
16
|
-
* Partial returns are shallow-merged with the current config.
|
|
17
|
-
*/
|
|
18
|
-
runOnConfig(ctx: ChatMiddlewareContext<TContext>, config: ChatMiddlewareConfig): Promise<ChatMiddlewareConfig>;
|
|
19
|
-
/**
|
|
20
|
-
* Pipe config through all middleware onStructuredOutputConfig hooks in order.
|
|
21
|
-
* Each middleware receives the merged config from previous middleware.
|
|
22
|
-
* Partial returns are shallow-merged with the current config.
|
|
23
|
-
*
|
|
24
|
-
* Called once at the structured-output boundary, before runOnConfig at the
|
|
25
|
-
* same boundary (which receives a ChatMiddlewareConfig view, no outputSchema).
|
|
26
|
-
*/
|
|
27
|
-
runOnStructuredOutputConfig(ctx: ChatMiddlewareContext<TContext>, config: StructuredOutputMiddlewareConfig): Promise<StructuredOutputMiddlewareConfig>;
|
|
28
|
-
/**
|
|
29
|
-
* Run all `setup` hooks in array order, then assert every declared `provides`
|
|
30
|
-
* capability was actually provided. Wires the last-wins duplicate-provide
|
|
31
|
-
* warning into the registry. Runs before init `onConfig`.
|
|
32
|
-
*
|
|
33
|
-
* Takes the full `ChatMiddlewareContext` — the same stable context the engine
|
|
34
|
-
* threads through every other hook — because it both forwards `ctx` to each
|
|
35
|
-
* `setup` hook and emits instrumentation events from it.
|
|
36
|
-
*/
|
|
37
|
-
runSetup(ctx: ChatMiddlewareContext<TContext>): Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* Call onStart on all middleware in order.
|
|
40
|
-
*/
|
|
41
|
-
runOnStart(ctx: ChatMiddlewareContext<TContext>): Promise<void>;
|
|
42
|
-
/**
|
|
43
|
-
* Pipe a single chunk through all middleware onChunk hooks in order.
|
|
44
|
-
* Returns the resulting chunks (0..N) to yield to the consumer.
|
|
45
|
-
*
|
|
46
|
-
* - void: pass through unchanged
|
|
47
|
-
* - chunk: replace with this chunk
|
|
48
|
-
* - chunk[]: expand to multiple chunks
|
|
49
|
-
* - null: drop the chunk entirely
|
|
50
|
-
*/
|
|
51
|
-
runOnChunk(ctx: ChatMiddlewareContext<TContext>, chunk: StreamChunk): Promise<Array<StreamChunk>>;
|
|
52
|
-
/**
|
|
53
|
-
* Run onBeforeToolCall through middleware in order.
|
|
54
|
-
* Returns the first non-void decision, or undefined to continue normally.
|
|
55
|
-
*/
|
|
56
|
-
runOnBeforeToolCall(ctx: ChatMiddlewareContext<TContext>, hookCtx: ToolCallHookContext): Promise<BeforeToolCallDecision>;
|
|
57
|
-
/**
|
|
58
|
-
* Run onAfterToolCall on all middleware in order.
|
|
59
|
-
*/
|
|
60
|
-
runOnAfterToolCall(ctx: ChatMiddlewareContext<TContext>, info: AfterToolCallInfo): Promise<void>;
|
|
61
|
-
/**
|
|
62
|
-
* Run onUsage on all middleware in order.
|
|
63
|
-
*/
|
|
64
|
-
runOnUsage(ctx: ChatMiddlewareContext<TContext>, usage: UsageInfo): Promise<void>;
|
|
65
|
-
/**
|
|
66
|
-
* Run onFinish on all middleware in order.
|
|
67
|
-
*/
|
|
68
|
-
runOnFinish(ctx: ChatMiddlewareContext<TContext>, info: FinishInfo): Promise<void>;
|
|
69
|
-
/**
|
|
70
|
-
* Run onAbort on all middleware in order.
|
|
71
|
-
*/
|
|
72
|
-
runOnAbort(ctx: ChatMiddlewareContext<TContext>, info: AbortInfo): Promise<void>;
|
|
73
|
-
/**
|
|
74
|
-
* Run onError on all middleware in order.
|
|
75
|
-
*/
|
|
76
|
-
runOnError(ctx: ChatMiddlewareContext<TContext>, info: ErrorInfo): Promise<void>;
|
|
77
|
-
/**
|
|
78
|
-
* Run onIteration on all middleware in order.
|
|
79
|
-
* Called at the start of each agent loop iteration.
|
|
80
|
-
*/
|
|
81
|
-
runOnIteration(ctx: ChatMiddlewareContext<TContext>, info: IterationInfo): Promise<void>;
|
|
82
|
-
/**
|
|
83
|
-
* Run onToolPhaseComplete on all middleware in order.
|
|
84
|
-
* Called after all tool calls in an iteration have been processed.
|
|
85
|
-
*/
|
|
86
|
-
runOnToolPhaseComplete(ctx: ChatMiddlewareContext<TContext>, info: ToolPhaseCompleteInfo): Promise<void>;
|
|
87
|
-
}
|
|
@@ -1,510 +0,0 @@
|
|
|
1
|
-
import { aiEventClient } from "@tanstack/ai-event-client";
|
|
2
|
-
function shouldSkipInstrumentation(mw) {
|
|
3
|
-
return mw.name === "devtools" || mw.name === "strip-to-spec";
|
|
4
|
-
}
|
|
5
|
-
function instrumentCtx(ctx) {
|
|
6
|
-
return {
|
|
7
|
-
requestId: ctx.requestId,
|
|
8
|
-
streamId: ctx.streamId,
|
|
9
|
-
clientId: ctx.threadId,
|
|
10
|
-
timestamp: Date.now()
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
class MiddlewareRunner {
|
|
14
|
-
middlewares;
|
|
15
|
-
logger;
|
|
16
|
-
constructor(middlewares, logger) {
|
|
17
|
-
this.middlewares = middlewares;
|
|
18
|
-
this.logger = logger;
|
|
19
|
-
}
|
|
20
|
-
get hasMiddleware() {
|
|
21
|
-
return this.middlewares.length > 0;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Pipe config through all middleware onConfig hooks in order.
|
|
25
|
-
* Each middleware receives the merged config from previous middleware.
|
|
26
|
-
* Partial returns are shallow-merged with the current config.
|
|
27
|
-
*/
|
|
28
|
-
async runOnConfig(ctx, config) {
|
|
29
|
-
let current = config;
|
|
30
|
-
for (const mw of this.middlewares) {
|
|
31
|
-
if (mw.onConfig) {
|
|
32
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
33
|
-
const start = Date.now();
|
|
34
|
-
const result = await mw.onConfig(ctx, current);
|
|
35
|
-
const hasTransform = result !== void 0 && result !== null;
|
|
36
|
-
if (hasTransform) {
|
|
37
|
-
current = { ...current, ...result };
|
|
38
|
-
if (!skip) {
|
|
39
|
-
this.logger.config(
|
|
40
|
-
`middleware=${mw.name ?? "unnamed"} keys=${Object.keys(result).join(",")}`,
|
|
41
|
-
{
|
|
42
|
-
middleware: mw.name ?? "unnamed",
|
|
43
|
-
changes: result
|
|
44
|
-
}
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (!skip) {
|
|
49
|
-
const base = instrumentCtx(ctx);
|
|
50
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
51
|
-
...base,
|
|
52
|
-
middlewareName: mw.name || "unnamed",
|
|
53
|
-
hookName: "onConfig",
|
|
54
|
-
iteration: ctx.iteration,
|
|
55
|
-
duration: Date.now() - start,
|
|
56
|
-
hasTransform
|
|
57
|
-
});
|
|
58
|
-
if (hasTransform) {
|
|
59
|
-
aiEventClient.emit("middleware:config:transformed", {
|
|
60
|
-
...base,
|
|
61
|
-
middlewareName: mw.name || "unnamed",
|
|
62
|
-
iteration: ctx.iteration,
|
|
63
|
-
changes: result
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return current;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Pipe config through all middleware onStructuredOutputConfig hooks in order.
|
|
73
|
-
* Each middleware receives the merged config from previous middleware.
|
|
74
|
-
* Partial returns are shallow-merged with the current config.
|
|
75
|
-
*
|
|
76
|
-
* Called once at the structured-output boundary, before runOnConfig at the
|
|
77
|
-
* same boundary (which receives a ChatMiddlewareConfig view, no outputSchema).
|
|
78
|
-
*/
|
|
79
|
-
async runOnStructuredOutputConfig(ctx, config) {
|
|
80
|
-
let current = config;
|
|
81
|
-
for (const mw of this.middlewares) {
|
|
82
|
-
if (mw.onStructuredOutputConfig) {
|
|
83
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
84
|
-
const start = Date.now();
|
|
85
|
-
const result = await mw.onStructuredOutputConfig(ctx, current);
|
|
86
|
-
const hasTransform = result !== void 0 && result !== null;
|
|
87
|
-
if (hasTransform) {
|
|
88
|
-
current = { ...current, ...result };
|
|
89
|
-
if (!skip) {
|
|
90
|
-
this.logger.config(
|
|
91
|
-
`middleware=${mw.name ?? "unnamed"} keys=${Object.keys(result).join(",")}`,
|
|
92
|
-
{
|
|
93
|
-
middleware: mw.name ?? "unnamed",
|
|
94
|
-
changes: result
|
|
95
|
-
}
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (!skip) {
|
|
100
|
-
const base = instrumentCtx(ctx);
|
|
101
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
102
|
-
...base,
|
|
103
|
-
middlewareName: mw.name || "unnamed",
|
|
104
|
-
hookName: "onStructuredOutputConfig",
|
|
105
|
-
iteration: ctx.iteration,
|
|
106
|
-
duration: Date.now() - start,
|
|
107
|
-
hasTransform
|
|
108
|
-
});
|
|
109
|
-
if (hasTransform) {
|
|
110
|
-
aiEventClient.emit("middleware:config:transformed", {
|
|
111
|
-
...base,
|
|
112
|
-
middlewareName: mw.name || "unnamed",
|
|
113
|
-
iteration: ctx.iteration,
|
|
114
|
-
// `result` is `Partial<StructuredOutputMiddlewareConfig>` —
|
|
115
|
-
// Object.fromEntries(Object.entries(result)) yields the
|
|
116
|
-
// structural `Record<string, unknown>` the event emitter wants
|
|
117
|
-
// without an `as` cast.
|
|
118
|
-
changes: Object.fromEntries(Object.entries(result))
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return current;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Run all `setup` hooks in array order, then assert every declared `provides`
|
|
128
|
-
* capability was actually provided. Wires the last-wins duplicate-provide
|
|
129
|
-
* warning into the registry. Runs before init `onConfig`.
|
|
130
|
-
*
|
|
131
|
-
* Takes the full `ChatMiddlewareContext` — the same stable context the engine
|
|
132
|
-
* threads through every other hook — because it both forwards `ctx` to each
|
|
133
|
-
* `setup` hook and emits instrumentation events from it.
|
|
134
|
-
*/
|
|
135
|
-
async runSetup(ctx) {
|
|
136
|
-
ctx.capabilities.setOnDuplicate((name) => {
|
|
137
|
-
this.logger.warn(
|
|
138
|
-
`capability "${name}" was provided more than once; last provider wins`,
|
|
139
|
-
{ capability: name }
|
|
140
|
-
);
|
|
141
|
-
});
|
|
142
|
-
for (const mw of this.middlewares) {
|
|
143
|
-
if (mw.setup) {
|
|
144
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
145
|
-
const start = Date.now();
|
|
146
|
-
await mw.setup(ctx);
|
|
147
|
-
if (!skip) {
|
|
148
|
-
this.logger.middleware(
|
|
149
|
-
`hook=setup middleware=${mw.name ?? "unnamed"}`,
|
|
150
|
-
{ middleware: mw.name ?? "unnamed", hook: "setup" }
|
|
151
|
-
);
|
|
152
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
153
|
-
...instrumentCtx(ctx),
|
|
154
|
-
middlewareName: mw.name || "unnamed",
|
|
155
|
-
hookName: "setup",
|
|
156
|
-
iteration: ctx.iteration,
|
|
157
|
-
duration: Date.now() - start,
|
|
158
|
-
hasTransform: false
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
for (const mw of this.middlewares) {
|
|
164
|
-
for (const handle of mw.provides ?? []) {
|
|
165
|
-
if (!ctx.capabilities.has(handle)) {
|
|
166
|
-
throw new Error(
|
|
167
|
-
`Middleware "${mw.name ?? "unnamed"}" declares it provides "${handle.capabilityName}" but never called provide() in setup().`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Call onStart on all middleware in order.
|
|
175
|
-
*/
|
|
176
|
-
async runOnStart(ctx) {
|
|
177
|
-
for (const mw of this.middlewares) {
|
|
178
|
-
if (mw.onStart) {
|
|
179
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
180
|
-
const start = Date.now();
|
|
181
|
-
await mw.onStart(ctx);
|
|
182
|
-
if (!skip) {
|
|
183
|
-
this.logger.middleware(
|
|
184
|
-
`hook=onStart middleware=${mw.name ?? "unnamed"}`,
|
|
185
|
-
{ middleware: mw.name ?? "unnamed", hook: "onStart" }
|
|
186
|
-
);
|
|
187
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
188
|
-
...instrumentCtx(ctx),
|
|
189
|
-
middlewareName: mw.name || "unnamed",
|
|
190
|
-
hookName: "onStart",
|
|
191
|
-
iteration: ctx.iteration,
|
|
192
|
-
duration: Date.now() - start,
|
|
193
|
-
hasTransform: false
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Pipe a single chunk through all middleware onChunk hooks in order.
|
|
201
|
-
* Returns the resulting chunks (0..N) to yield to the consumer.
|
|
202
|
-
*
|
|
203
|
-
* - void: pass through unchanged
|
|
204
|
-
* - chunk: replace with this chunk
|
|
205
|
-
* - chunk[]: expand to multiple chunks
|
|
206
|
-
* - null: drop the chunk entirely
|
|
207
|
-
*/
|
|
208
|
-
async runOnChunk(ctx, chunk) {
|
|
209
|
-
let chunks = [chunk];
|
|
210
|
-
for (const mw of this.middlewares) {
|
|
211
|
-
if (!mw.onChunk) continue;
|
|
212
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
213
|
-
const nextChunks = [];
|
|
214
|
-
for (const c of chunks) {
|
|
215
|
-
const chunkType = c.type;
|
|
216
|
-
if (!skip) {
|
|
217
|
-
this.logger.middleware(
|
|
218
|
-
`hook=onChunk middleware=${mw.name ?? "unnamed"} in=${chunkType}`,
|
|
219
|
-
{ middleware: mw.name ?? "unnamed", hook: "onChunk", in: c }
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
const result = await mw.onChunk(ctx, c);
|
|
223
|
-
if (result === null) {
|
|
224
|
-
if (!skip) {
|
|
225
|
-
this.logger.middleware(
|
|
226
|
-
`hook=onChunk middleware=${mw.name ?? "unnamed"} in=${chunkType} out=<dropped>`,
|
|
227
|
-
{
|
|
228
|
-
middleware: mw.name ?? "unnamed",
|
|
229
|
-
hook: "onChunk",
|
|
230
|
-
dropped: true
|
|
231
|
-
}
|
|
232
|
-
);
|
|
233
|
-
aiEventClient.emit("middleware:chunk:transformed", {
|
|
234
|
-
...instrumentCtx(ctx),
|
|
235
|
-
middlewareName: mw.name || "unnamed",
|
|
236
|
-
originalChunkType: chunkType,
|
|
237
|
-
resultCount: 0,
|
|
238
|
-
wasDropped: true
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
continue;
|
|
242
|
-
} else if (result === void 0) {
|
|
243
|
-
nextChunks.push(c);
|
|
244
|
-
} else if (Array.isArray(result)) {
|
|
245
|
-
nextChunks.push(...result);
|
|
246
|
-
if (!skip) {
|
|
247
|
-
this.logger.middleware(
|
|
248
|
-
`hook=onChunk middleware=${mw.name ?? "unnamed"} in=${chunkType} out=[${result.map((r) => r.type).join(",")}]`,
|
|
249
|
-
{
|
|
250
|
-
middleware: mw.name ?? "unnamed",
|
|
251
|
-
hook: "onChunk",
|
|
252
|
-
in: c,
|
|
253
|
-
out: result
|
|
254
|
-
}
|
|
255
|
-
);
|
|
256
|
-
aiEventClient.emit("middleware:chunk:transformed", {
|
|
257
|
-
...instrumentCtx(ctx),
|
|
258
|
-
middlewareName: mw.name || "unnamed",
|
|
259
|
-
originalChunkType: chunkType,
|
|
260
|
-
resultCount: result.length,
|
|
261
|
-
wasDropped: false
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
} else {
|
|
265
|
-
nextChunks.push(result);
|
|
266
|
-
if (!skip) {
|
|
267
|
-
this.logger.middleware(
|
|
268
|
-
`hook=onChunk middleware=${mw.name ?? "unnamed"} in=${chunkType} out=${result.type}`,
|
|
269
|
-
{
|
|
270
|
-
middleware: mw.name ?? "unnamed",
|
|
271
|
-
hook: "onChunk",
|
|
272
|
-
in: c,
|
|
273
|
-
out: result
|
|
274
|
-
}
|
|
275
|
-
);
|
|
276
|
-
aiEventClient.emit("middleware:chunk:transformed", {
|
|
277
|
-
...instrumentCtx(ctx),
|
|
278
|
-
middlewareName: mw.name || "unnamed",
|
|
279
|
-
originalChunkType: chunkType,
|
|
280
|
-
resultCount: 1,
|
|
281
|
-
wasDropped: false
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
chunks = nextChunks;
|
|
287
|
-
}
|
|
288
|
-
return chunks;
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Run onBeforeToolCall through middleware in order.
|
|
292
|
-
* Returns the first non-void decision, or undefined to continue normally.
|
|
293
|
-
*/
|
|
294
|
-
async runOnBeforeToolCall(ctx, hookCtx) {
|
|
295
|
-
for (const mw of this.middlewares) {
|
|
296
|
-
if (mw.onBeforeToolCall) {
|
|
297
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
298
|
-
const start = Date.now();
|
|
299
|
-
const decision = await mw.onBeforeToolCall(ctx, hookCtx);
|
|
300
|
-
const hasTransform = decision !== void 0 && decision !== null;
|
|
301
|
-
if (!skip) {
|
|
302
|
-
this.logger.middleware(
|
|
303
|
-
`hook=onBeforeToolCall middleware=${mw.name ?? "unnamed"}`,
|
|
304
|
-
{ middleware: mw.name ?? "unnamed", hook: "onBeforeToolCall" }
|
|
305
|
-
);
|
|
306
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
307
|
-
...instrumentCtx(ctx),
|
|
308
|
-
middlewareName: mw.name || "unnamed",
|
|
309
|
-
hookName: "onBeforeToolCall",
|
|
310
|
-
iteration: ctx.iteration,
|
|
311
|
-
duration: Date.now() - start,
|
|
312
|
-
hasTransform
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
if (hasTransform) {
|
|
316
|
-
return decision;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
return void 0;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Run onAfterToolCall on all middleware in order.
|
|
324
|
-
*/
|
|
325
|
-
async runOnAfterToolCall(ctx, info) {
|
|
326
|
-
for (const mw of this.middlewares) {
|
|
327
|
-
if (mw.onAfterToolCall) {
|
|
328
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
329
|
-
const start = Date.now();
|
|
330
|
-
await mw.onAfterToolCall(ctx, info);
|
|
331
|
-
if (!skip) {
|
|
332
|
-
this.logger.middleware(
|
|
333
|
-
`hook=onAfterToolCall middleware=${mw.name ?? "unnamed"}`,
|
|
334
|
-
{ middleware: mw.name ?? "unnamed", hook: "onAfterToolCall" }
|
|
335
|
-
);
|
|
336
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
337
|
-
...instrumentCtx(ctx),
|
|
338
|
-
middlewareName: mw.name || "unnamed",
|
|
339
|
-
hookName: "onAfterToolCall",
|
|
340
|
-
iteration: ctx.iteration,
|
|
341
|
-
duration: Date.now() - start,
|
|
342
|
-
hasTransform: false
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Run onUsage on all middleware in order.
|
|
350
|
-
*/
|
|
351
|
-
async runOnUsage(ctx, usage) {
|
|
352
|
-
for (const mw of this.middlewares) {
|
|
353
|
-
if (mw.onUsage) {
|
|
354
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
355
|
-
const start = Date.now();
|
|
356
|
-
await mw.onUsage(ctx, usage);
|
|
357
|
-
if (!skip) {
|
|
358
|
-
this.logger.middleware(
|
|
359
|
-
`hook=onUsage middleware=${mw.name ?? "unnamed"}`,
|
|
360
|
-
{ middleware: mw.name ?? "unnamed", hook: "onUsage" }
|
|
361
|
-
);
|
|
362
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
363
|
-
...instrumentCtx(ctx),
|
|
364
|
-
middlewareName: mw.name || "unnamed",
|
|
365
|
-
hookName: "onUsage",
|
|
366
|
-
iteration: ctx.iteration,
|
|
367
|
-
duration: Date.now() - start,
|
|
368
|
-
hasTransform: false
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Run onFinish on all middleware in order.
|
|
376
|
-
*/
|
|
377
|
-
async runOnFinish(ctx, info) {
|
|
378
|
-
for (const mw of this.middlewares) {
|
|
379
|
-
if (mw.onFinish) {
|
|
380
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
381
|
-
const start = Date.now();
|
|
382
|
-
await mw.onFinish(ctx, info);
|
|
383
|
-
if (!skip) {
|
|
384
|
-
this.logger.middleware(
|
|
385
|
-
`hook=onFinish middleware=${mw.name ?? "unnamed"}`,
|
|
386
|
-
{ middleware: mw.name ?? "unnamed", hook: "onFinish" }
|
|
387
|
-
);
|
|
388
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
389
|
-
...instrumentCtx(ctx),
|
|
390
|
-
middlewareName: mw.name || "unnamed",
|
|
391
|
-
hookName: "onFinish",
|
|
392
|
-
iteration: ctx.iteration,
|
|
393
|
-
duration: Date.now() - start,
|
|
394
|
-
hasTransform: false
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Run onAbort on all middleware in order.
|
|
402
|
-
*/
|
|
403
|
-
async runOnAbort(ctx, info) {
|
|
404
|
-
for (const mw of this.middlewares) {
|
|
405
|
-
if (mw.onAbort) {
|
|
406
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
407
|
-
const start = Date.now();
|
|
408
|
-
await mw.onAbort(ctx, info);
|
|
409
|
-
if (!skip) {
|
|
410
|
-
this.logger.middleware(
|
|
411
|
-
`hook=onAbort middleware=${mw.name ?? "unnamed"}`,
|
|
412
|
-
{ middleware: mw.name ?? "unnamed", hook: "onAbort" }
|
|
413
|
-
);
|
|
414
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
415
|
-
...instrumentCtx(ctx),
|
|
416
|
-
middlewareName: mw.name || "unnamed",
|
|
417
|
-
hookName: "onAbort",
|
|
418
|
-
iteration: ctx.iteration,
|
|
419
|
-
duration: Date.now() - start,
|
|
420
|
-
hasTransform: false
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Run onError on all middleware in order.
|
|
428
|
-
*/
|
|
429
|
-
async runOnError(ctx, info) {
|
|
430
|
-
for (const mw of this.middlewares) {
|
|
431
|
-
if (mw.onError) {
|
|
432
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
433
|
-
const start = Date.now();
|
|
434
|
-
await mw.onError(ctx, info);
|
|
435
|
-
if (!skip) {
|
|
436
|
-
this.logger.middleware(
|
|
437
|
-
`hook=onError middleware=${mw.name ?? "unnamed"}`,
|
|
438
|
-
{ middleware: mw.name ?? "unnamed", hook: "onError" }
|
|
439
|
-
);
|
|
440
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
441
|
-
...instrumentCtx(ctx),
|
|
442
|
-
middlewareName: mw.name || "unnamed",
|
|
443
|
-
hookName: "onError",
|
|
444
|
-
iteration: ctx.iteration,
|
|
445
|
-
duration: Date.now() - start,
|
|
446
|
-
hasTransform: false
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Run onIteration on all middleware in order.
|
|
454
|
-
* Called at the start of each agent loop iteration.
|
|
455
|
-
*/
|
|
456
|
-
async runOnIteration(ctx, info) {
|
|
457
|
-
for (const mw of this.middlewares) {
|
|
458
|
-
if (mw.onIteration) {
|
|
459
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
460
|
-
const start = Date.now();
|
|
461
|
-
await mw.onIteration(ctx, info);
|
|
462
|
-
if (!skip) {
|
|
463
|
-
this.logger.middleware(
|
|
464
|
-
`hook=onIteration middleware=${mw.name ?? "unnamed"}`,
|
|
465
|
-
{ middleware: mw.name ?? "unnamed", hook: "onIteration" }
|
|
466
|
-
);
|
|
467
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
468
|
-
...instrumentCtx(ctx),
|
|
469
|
-
middlewareName: mw.name || "unnamed",
|
|
470
|
-
hookName: "onIteration",
|
|
471
|
-
iteration: ctx.iteration,
|
|
472
|
-
duration: Date.now() - start,
|
|
473
|
-
hasTransform: false
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Run onToolPhaseComplete on all middleware in order.
|
|
481
|
-
* Called after all tool calls in an iteration have been processed.
|
|
482
|
-
*/
|
|
483
|
-
async runOnToolPhaseComplete(ctx, info) {
|
|
484
|
-
for (const mw of this.middlewares) {
|
|
485
|
-
if (mw.onToolPhaseComplete) {
|
|
486
|
-
const skip = shouldSkipInstrumentation(mw);
|
|
487
|
-
const start = Date.now();
|
|
488
|
-
await mw.onToolPhaseComplete(ctx, info);
|
|
489
|
-
if (!skip) {
|
|
490
|
-
this.logger.middleware(
|
|
491
|
-
`hook=onToolPhaseComplete middleware=${mw.name ?? "unnamed"}`,
|
|
492
|
-
{ middleware: mw.name ?? "unnamed", hook: "onToolPhaseComplete" }
|
|
493
|
-
);
|
|
494
|
-
aiEventClient.emit("middleware:hook:executed", {
|
|
495
|
-
...instrumentCtx(ctx),
|
|
496
|
-
middlewareName: mw.name || "unnamed",
|
|
497
|
-
hookName: "onToolPhaseComplete",
|
|
498
|
-
iteration: ctx.iteration,
|
|
499
|
-
duration: Date.now() - start,
|
|
500
|
-
hasTransform: false
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
export {
|
|
508
|
-
MiddlewareRunner
|
|
509
|
-
};
|
|
510
|
-
//# sourceMappingURL=compose.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compose.js","sources":["../../../../../src/activities/chat/middleware/compose.ts"],"sourcesContent":["import { aiEventClient } from '@tanstack/ai-event-client'\nimport type { StreamChunk } from '../../../types'\nimport type { InternalLogger } from '../../../logger/internal-logger'\nimport type {\n AbortInfo,\n AfterToolCallInfo,\n BeforeToolCallDecision,\n ChatMiddleware,\n ChatMiddlewareConfig,\n ChatMiddlewareContext,\n ErrorInfo,\n FinishInfo,\n IterationInfo,\n StructuredOutputMiddlewareConfig,\n ToolCallHookContext,\n ToolPhaseCompleteInfo,\n UsageInfo,\n} from './types'\n\n/** Check if a middleware should be skipped for instrumentation events. */\nfunction shouldSkipInstrumentation(mw: ChatMiddleware<any>): boolean {\n return mw.name === 'devtools' || mw.name === 'strip-to-spec'\n}\n\n/** Build the base context for middleware instrumentation events. */\nfunction instrumentCtx(ctx: ChatMiddlewareContext<any>) {\n return {\n requestId: ctx.requestId,\n streamId: ctx.streamId,\n clientId: ctx.threadId,\n timestamp: Date.now(),\n }\n}\n\n/**\n * Internal middleware runner that manages composed execution of middleware hooks.\n * Created once per chat() invocation.\n */\nexport class MiddlewareRunner<TContext = unknown> {\n private readonly middlewares: ReadonlyArray<ChatMiddleware<TContext>>\n private readonly logger: InternalLogger\n\n constructor(\n middlewares: ReadonlyArray<ChatMiddleware<TContext>>,\n logger: InternalLogger,\n ) {\n this.middlewares = middlewares\n this.logger = logger\n }\n\n get hasMiddleware(): boolean {\n return this.middlewares.length > 0\n }\n\n /**\n * Pipe config through all middleware onConfig hooks in order.\n * Each middleware receives the merged config from previous middleware.\n * Partial returns are shallow-merged with the current config.\n */\n async runOnConfig(\n ctx: ChatMiddlewareContext<TContext>,\n config: ChatMiddlewareConfig,\n ): Promise<ChatMiddlewareConfig> {\n let current = config\n for (const mw of this.middlewares) {\n if (mw.onConfig) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n const result = await mw.onConfig(ctx, current)\n const hasTransform = result !== undefined && result !== null\n if (hasTransform) {\n current = { ...current, ...result }\n if (!skip) {\n this.logger.config(\n `middleware=${mw.name ?? 'unnamed'} keys=${Object.keys(result).join(',')}`,\n {\n middleware: mw.name ?? 'unnamed',\n changes: result,\n },\n )\n }\n }\n if (!skip) {\n const base = instrumentCtx(ctx)\n aiEventClient.emit('middleware:hook:executed', {\n ...base,\n middlewareName: mw.name || 'unnamed',\n hookName: 'onConfig',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform,\n })\n if (hasTransform) {\n aiEventClient.emit('middleware:config:transformed', {\n ...base,\n middlewareName: mw.name || 'unnamed',\n iteration: ctx.iteration,\n changes: result,\n })\n }\n }\n }\n }\n return current\n }\n\n /**\n * Pipe config through all middleware onStructuredOutputConfig hooks in order.\n * Each middleware receives the merged config from previous middleware.\n * Partial returns are shallow-merged with the current config.\n *\n * Called once at the structured-output boundary, before runOnConfig at the\n * same boundary (which receives a ChatMiddlewareConfig view, no outputSchema).\n */\n async runOnStructuredOutputConfig(\n ctx: ChatMiddlewareContext<TContext>,\n config: StructuredOutputMiddlewareConfig,\n ): Promise<StructuredOutputMiddlewareConfig> {\n let current = config\n for (const mw of this.middlewares) {\n if (mw.onStructuredOutputConfig) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n const result = await mw.onStructuredOutputConfig(ctx, current)\n const hasTransform = result !== undefined && result !== null\n if (hasTransform) {\n current = { ...current, ...result }\n if (!skip) {\n this.logger.config(\n `middleware=${mw.name ?? 'unnamed'} keys=${Object.keys(result).join(',')}`,\n {\n middleware: mw.name ?? 'unnamed',\n changes: result,\n },\n )\n }\n }\n if (!skip) {\n const base = instrumentCtx(ctx)\n aiEventClient.emit('middleware:hook:executed', {\n ...base,\n middlewareName: mw.name || 'unnamed',\n hookName: 'onStructuredOutputConfig',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform,\n })\n if (hasTransform) {\n aiEventClient.emit('middleware:config:transformed', {\n ...base,\n middlewareName: mw.name || 'unnamed',\n iteration: ctx.iteration,\n // `result` is `Partial<StructuredOutputMiddlewareConfig>` —\n // Object.fromEntries(Object.entries(result)) yields the\n // structural `Record<string, unknown>` the event emitter wants\n // without an `as` cast.\n changes: Object.fromEntries(Object.entries(result)),\n })\n }\n }\n }\n }\n return current\n }\n\n /**\n * Run all `setup` hooks in array order, then assert every declared `provides`\n * capability was actually provided. Wires the last-wins duplicate-provide\n * warning into the registry. Runs before init `onConfig`.\n *\n * Takes the full `ChatMiddlewareContext` — the same stable context the engine\n * threads through every other hook — because it both forwards `ctx` to each\n * `setup` hook and emits instrumentation events from it.\n */\n async runSetup(ctx: ChatMiddlewareContext<TContext>): Promise<void> {\n ctx.capabilities.setOnDuplicate((name) => {\n this.logger.warn(\n `capability \"${name}\" was provided more than once; last provider wins`,\n { capability: name },\n )\n })\n\n for (const mw of this.middlewares) {\n if (mw.setup) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.setup(ctx)\n if (!skip) {\n this.logger.middleware(\n `hook=setup middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'setup' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'setup',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n\n for (const mw of this.middlewares) {\n for (const handle of mw.provides ?? []) {\n if (!ctx.capabilities.has(handle)) {\n throw new Error(\n `Middleware \"${mw.name ?? 'unnamed'}\" declares it provides ` +\n `\"${handle.capabilityName}\" but never called provide() in setup().`,\n )\n }\n }\n }\n }\n\n /**\n * Call onStart on all middleware in order.\n */\n async runOnStart(ctx: ChatMiddlewareContext<TContext>): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onStart) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onStart(ctx)\n if (!skip) {\n this.logger.middleware(\n `hook=onStart middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onStart' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onStart',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n\n /**\n * Pipe a single chunk through all middleware onChunk hooks in order.\n * Returns the resulting chunks (0..N) to yield to the consumer.\n *\n * - void: pass through unchanged\n * - chunk: replace with this chunk\n * - chunk[]: expand to multiple chunks\n * - null: drop the chunk entirely\n */\n async runOnChunk(\n ctx: ChatMiddlewareContext<TContext>,\n chunk: StreamChunk,\n ): Promise<Array<StreamChunk>> {\n let chunks: Array<StreamChunk> = [chunk]\n\n for (const mw of this.middlewares) {\n if (!mw.onChunk) continue\n const skip = shouldSkipInstrumentation(mw)\n\n const nextChunks: Array<StreamChunk> = []\n for (const c of chunks) {\n // Cast: @ag-ui/core Zod passthrough types prevent direct `.type` access\n const chunkType = c.type\n if (!skip) {\n this.logger.middleware(\n `hook=onChunk middleware=${mw.name ?? 'unnamed'} in=${chunkType}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onChunk', in: c },\n )\n }\n const result = await mw.onChunk(ctx, c)\n if (result === null) {\n // Drop this chunk\n if (!skip) {\n this.logger.middleware(\n `hook=onChunk middleware=${mw.name ?? 'unnamed'} in=${chunkType} out=<dropped>`,\n {\n middleware: mw.name ?? 'unnamed',\n hook: 'onChunk',\n dropped: true,\n },\n )\n aiEventClient.emit('middleware:chunk:transformed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n originalChunkType: chunkType,\n resultCount: 0,\n wasDropped: true,\n })\n }\n continue\n } else if (result === undefined) {\n // Pass through — no instrumentation for pass-throughs\n nextChunks.push(c)\n } else if (Array.isArray(result)) {\n // Expand\n nextChunks.push(...result)\n if (!skip) {\n this.logger.middleware(\n `hook=onChunk middleware=${mw.name ?? 'unnamed'} in=${chunkType} out=[${result.map((r: StreamChunk) => r.type).join(',')}]`,\n {\n middleware: mw.name ?? 'unnamed',\n hook: 'onChunk',\n in: c,\n out: result,\n },\n )\n aiEventClient.emit('middleware:chunk:transformed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n originalChunkType: chunkType,\n resultCount: result.length,\n wasDropped: false,\n })\n }\n } else {\n // Replace\n nextChunks.push(result)\n if (!skip) {\n this.logger.middleware(\n `hook=onChunk middleware=${mw.name ?? 'unnamed'} in=${chunkType} out=${result.type}`,\n {\n middleware: mw.name ?? 'unnamed',\n hook: 'onChunk',\n in: c,\n out: result,\n },\n )\n aiEventClient.emit('middleware:chunk:transformed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n originalChunkType: chunkType,\n resultCount: 1,\n wasDropped: false,\n })\n }\n }\n }\n chunks = nextChunks\n }\n\n return chunks\n }\n\n /**\n * Run onBeforeToolCall through middleware in order.\n * Returns the first non-void decision, or undefined to continue normally.\n */\n async runOnBeforeToolCall(\n ctx: ChatMiddlewareContext<TContext>,\n hookCtx: ToolCallHookContext,\n ): Promise<BeforeToolCallDecision> {\n for (const mw of this.middlewares) {\n if (mw.onBeforeToolCall) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n const decision = await mw.onBeforeToolCall(ctx, hookCtx)\n const hasTransform = decision !== undefined && decision !== null\n if (!skip) {\n this.logger.middleware(\n `hook=onBeforeToolCall middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onBeforeToolCall' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onBeforeToolCall',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform,\n })\n }\n if (hasTransform) {\n return decision\n }\n }\n }\n return undefined\n }\n\n /**\n * Run onAfterToolCall on all middleware in order.\n */\n async runOnAfterToolCall(\n ctx: ChatMiddlewareContext<TContext>,\n info: AfterToolCallInfo,\n ): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onAfterToolCall) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onAfterToolCall(ctx, info)\n if (!skip) {\n this.logger.middleware(\n `hook=onAfterToolCall middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onAfterToolCall' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onAfterToolCall',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n\n /**\n * Run onUsage on all middleware in order.\n */\n async runOnUsage(\n ctx: ChatMiddlewareContext<TContext>,\n usage: UsageInfo,\n ): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onUsage) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onUsage(ctx, usage)\n if (!skip) {\n this.logger.middleware(\n `hook=onUsage middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onUsage' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onUsage',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n\n /**\n * Run onFinish on all middleware in order.\n */\n async runOnFinish(\n ctx: ChatMiddlewareContext<TContext>,\n info: FinishInfo,\n ): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onFinish) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onFinish(ctx, info)\n if (!skip) {\n this.logger.middleware(\n `hook=onFinish middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onFinish' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onFinish',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n\n /**\n * Run onAbort on all middleware in order.\n */\n async runOnAbort(\n ctx: ChatMiddlewareContext<TContext>,\n info: AbortInfo,\n ): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onAbort) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onAbort(ctx, info)\n if (!skip) {\n this.logger.middleware(\n `hook=onAbort middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onAbort' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onAbort',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n\n /**\n * Run onError on all middleware in order.\n */\n async runOnError(\n ctx: ChatMiddlewareContext<TContext>,\n info: ErrorInfo,\n ): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onError) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onError(ctx, info)\n if (!skip) {\n this.logger.middleware(\n `hook=onError middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onError' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onError',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n\n /**\n * Run onIteration on all middleware in order.\n * Called at the start of each agent loop iteration.\n */\n async runOnIteration(\n ctx: ChatMiddlewareContext<TContext>,\n info: IterationInfo,\n ): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onIteration) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onIteration(ctx, info)\n if (!skip) {\n this.logger.middleware(\n `hook=onIteration middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onIteration' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onIteration',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n\n /**\n * Run onToolPhaseComplete on all middleware in order.\n * Called after all tool calls in an iteration have been processed.\n */\n async runOnToolPhaseComplete(\n ctx: ChatMiddlewareContext<TContext>,\n info: ToolPhaseCompleteInfo,\n ): Promise<void> {\n for (const mw of this.middlewares) {\n if (mw.onToolPhaseComplete) {\n const skip = shouldSkipInstrumentation(mw)\n const start = Date.now()\n await mw.onToolPhaseComplete(ctx, info)\n if (!skip) {\n this.logger.middleware(\n `hook=onToolPhaseComplete middleware=${mw.name ?? 'unnamed'}`,\n { middleware: mw.name ?? 'unnamed', hook: 'onToolPhaseComplete' },\n )\n aiEventClient.emit('middleware:hook:executed', {\n ...instrumentCtx(ctx),\n middlewareName: mw.name || 'unnamed',\n hookName: 'onToolPhaseComplete',\n iteration: ctx.iteration,\n duration: Date.now() - start,\n hasTransform: false,\n })\n }\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|