@tanstack/ai 0.36.0 → 0.38.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/dist/esm/activities/chat/adapter.d.ts +163 -0
- package/dist/esm/activities/chat/adapter.js +17 -0
- package/dist/esm/activities/chat/adapter.js.map +1 -0
- package/dist/esm/activities/chat/agent-loop-strategies.d.ts +59 -0
- package/dist/esm/activities/chat/agent-loop-strategies.js +23 -0
- package/dist/esm/activities/chat/agent-loop-strategies.js.map +1 -0
- package/dist/esm/activities/chat/index.d.ts +270 -0
- package/dist/esm/activities/chat/index.js +1724 -0
- package/dist/esm/activities/chat/index.js.map +1 -0
- package/dist/esm/activities/chat/mcp/manager.d.ts +25 -0
- package/dist/esm/activities/chat/mcp/manager.js +80 -0
- package/dist/esm/activities/chat/mcp/manager.js.map +1 -0
- package/dist/esm/activities/chat/mcp/types.d.ts +78 -0
- package/dist/esm/activities/chat/messages.d.ts +78 -0
- package/dist/esm/activities/chat/messages.js +374 -0
- package/dist/esm/activities/chat/messages.js.map +1 -0
- package/dist/esm/activities/chat/middleware/builder.d.ts +46 -0
- package/dist/esm/activities/chat/middleware/builder.js +17 -0
- package/dist/esm/activities/chat/middleware/builder.js.map +1 -0
- package/dist/esm/activities/chat/middleware/capabilities.d.ts +93 -0
- package/dist/esm/activities/chat/middleware/capabilities.js +45 -0
- package/dist/esm/activities/chat/middleware/capabilities.js.map +1 -0
- package/dist/esm/activities/chat/middleware/compose.d.ts +87 -0
- package/dist/esm/activities/chat/middleware/compose.js +510 -0
- package/dist/esm/activities/chat/middleware/compose.js.map +1 -0
- package/dist/esm/activities/chat/middleware/define.d.ts +20 -0
- package/dist/esm/activities/chat/middleware/define.js +7 -0
- package/dist/esm/activities/chat/middleware/define.js.map +1 -0
- package/dist/esm/activities/chat/middleware/index.d.ts +10 -0
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.d.ts +89 -0
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +76 -0
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +1 -0
- package/dist/esm/activities/chat/middleware/types.d.ts +405 -0
- package/dist/esm/activities/chat/middleware/validate.d.ts +19 -0
- package/dist/esm/activities/chat/middleware/validate.js +30 -0
- package/dist/esm/activities/chat/middleware/validate.js.map +1 -0
- package/dist/esm/activities/chat/runtime-context-types.d.ts +43 -0
- package/dist/esm/activities/chat/stream/index.d.ts +11 -0
- package/dist/esm/activities/chat/stream/json-parser.d.ts +38 -0
- package/dist/esm/activities/chat/stream/json-parser.js +28 -0
- package/dist/esm/activities/chat/stream/json-parser.js.map +1 -0
- package/dist/esm/activities/chat/stream/message-updaters.d.ts +81 -0
- package/dist/esm/activities/chat/stream/message-updaters.js +253 -0
- package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -0
- package/dist/esm/activities/chat/stream/processor.d.ts +439 -0
- package/dist/esm/activities/chat/stream/processor.js +1449 -0
- package/dist/esm/activities/chat/stream/processor.js.map +1 -0
- package/dist/esm/activities/chat/stream/strategies.d.ts +43 -0
- package/dist/esm/activities/chat/stream/strategies.js +54 -0
- package/dist/esm/activities/chat/stream/strategies.js.map +1 -0
- package/dist/esm/activities/chat/stream/types.d.ts +90 -0
- package/dist/esm/activities/chat/tools/lazy-tool-manager.d.ts +82 -0
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js +194 -0
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +1 -0
- package/dist/esm/activities/chat/tools/lazy-tools.d.ts +15 -0
- package/dist/esm/activities/chat/tools/lazy-tools.js +16 -0
- package/dist/esm/activities/chat/tools/lazy-tools.js.map +1 -0
- package/dist/esm/activities/chat/tools/schema-converter.d.ts +140 -0
- package/dist/esm/activities/chat/tools/schema-converter.js +167 -0
- package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -0
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +145 -0
- package/dist/esm/activities/chat/tools/tool-calls.js +548 -0
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -0
- package/dist/esm/activities/chat/tools/tool-definition.d.ts +135 -0
- package/dist/esm/activities/chat/tools/tool-definition.js +25 -0
- package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -0
- package/dist/esm/activities/error-payload.d.ts +30 -0
- package/dist/esm/activities/error-payload.js +54 -0
- package/dist/esm/activities/error-payload.js.map +1 -0
- package/dist/esm/activities/generateAudio/adapter.d.ts +62 -0
- package/dist/esm/activities/generateAudio/adapter.js +16 -0
- package/dist/esm/activities/generateAudio/adapter.js.map +1 -0
- package/dist/esm/activities/generateAudio/index.d.ts +85 -0
- package/dist/esm/activities/generateAudio/index.js +114 -0
- package/dist/esm/activities/generateAudio/index.js.map +1 -0
- package/dist/esm/activities/generateImage/adapter.d.ts +78 -0
- package/dist/esm/activities/generateImage/adapter.js +16 -0
- package/dist/esm/activities/generateImage/adapter.js.map +1 -0
- package/dist/esm/activities/generateImage/index.d.ts +134 -0
- package/dist/esm/activities/generateImage/index.js +121 -0
- package/dist/esm/activities/generateImage/index.js.map +1 -0
- package/dist/esm/activities/generateSpeech/adapter.d.ts +62 -0
- package/dist/esm/activities/generateSpeech/adapter.js +16 -0
- package/dist/esm/activities/generateSpeech/adapter.js.map +1 -0
- package/dist/esm/activities/generateSpeech/index.d.ts +96 -0
- package/dist/esm/activities/generateSpeech/index.js +119 -0
- package/dist/esm/activities/generateSpeech/index.js.map +1 -0
- package/dist/esm/activities/generateTranscription/adapter.d.ts +62 -0
- package/dist/esm/activities/generateTranscription/adapter.js +16 -0
- package/dist/esm/activities/generateTranscription/adapter.js.map +1 -0
- package/dist/esm/activities/generateTranscription/index.d.ts +109 -0
- package/dist/esm/activities/generateTranscription/index.js +109 -0
- package/dist/esm/activities/generateTranscription/index.js.map +1 -0
- package/dist/esm/activities/generateVideo/adapter.d.ts +145 -0
- package/dist/esm/activities/generateVideo/adapter.js +30 -0
- package/dist/esm/activities/generateVideo/adapter.js.map +1 -0
- package/dist/esm/activities/generateVideo/index.d.ts +223 -0
- package/dist/esm/activities/generateVideo/index.js +295 -0
- package/dist/esm/activities/generateVideo/index.js.map +1 -0
- package/dist/esm/activities/generateVideo/snap.d.ts +14 -0
- package/dist/esm/activities/generateVideo/snap.js +54 -0
- package/dist/esm/activities/generateVideo/snap.js.map +1 -0
- package/dist/esm/activities/index.d.ts +27 -0
- package/dist/esm/activities/index.js +43 -0
- package/dist/esm/activities/index.js.map +1 -0
- package/dist/esm/activities/middleware/index.d.ts +2 -0
- package/dist/esm/activities/middleware/run.d.ts +20 -0
- package/dist/esm/activities/middleware/run.js +42 -0
- package/dist/esm/activities/middleware/run.js.map +1 -0
- package/dist/esm/activities/middleware/types.d.ts +118 -0
- package/dist/esm/activities/stream-generation-result.d.ts +15 -0
- package/dist/esm/activities/stream-generation-result.js +49 -0
- package/dist/esm/activities/stream-generation-result.js.map +1 -0
- package/dist/esm/activities/summarize/adapter.d.ts +74 -0
- package/dist/esm/activities/summarize/adapter.js +16 -0
- package/dist/esm/activities/summarize/adapter.js.map +1 -0
- package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +45 -0
- package/dist/esm/activities/summarize/chat-stream-summarize.js +212 -0
- package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -0
- package/dist/esm/activities/summarize/index.d.ts +108 -0
- package/dist/esm/activities/summarize/index.js +113 -0
- package/dist/esm/activities/summarize/index.js.map +1 -0
- package/dist/esm/adapter-internals.d.ts +5 -0
- package/dist/esm/adapter-internals.js +10 -0
- package/dist/esm/adapter-internals.js.map +1 -0
- package/dist/esm/client.d.ts +44 -0
- package/dist/esm/client.js +67 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/extend-adapter.d.ts +152 -0
- package/dist/esm/extend-adapter.js +21 -0
- package/dist/esm/extend-adapter.js.map +1 -0
- package/dist/esm/index.d.ts +45 -0
- package/dist/esm/index.js +109 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/logger/console-logger.d.ts +29 -0
- package/dist/esm/logger/console-logger.js +83 -0
- package/dist/esm/logger/console-logger.js.map +1 -0
- package/dist/esm/logger/internal-logger.d.ts +41 -0
- package/dist/esm/logger/internal-logger.js +86 -0
- package/dist/esm/logger/internal-logger.js.map +1 -0
- package/dist/esm/logger/resolve.d.ts +14 -0
- package/dist/esm/logger/resolve.js +54 -0
- package/dist/esm/logger/resolve.js.map +1 -0
- package/dist/esm/logger/types.d.ts +75 -0
- package/dist/esm/middlewares/content-guard.d.ts +77 -0
- package/dist/esm/middlewares/content-guard.js +156 -0
- package/dist/esm/middlewares/content-guard.js.map +1 -0
- package/dist/esm/middlewares/index.d.ts +2 -0
- package/dist/esm/middlewares/index.js +7 -0
- package/dist/esm/middlewares/index.js.map +1 -0
- package/dist/esm/middlewares/otel.d.ts +81 -0
- package/dist/esm/middlewares/otel.js +745 -0
- package/dist/esm/middlewares/otel.js.map +1 -0
- package/dist/esm/middlewares/tool-cache.d.ts +1 -0
- package/dist/esm/middlewares/usage-attributes.d.ts +24 -0
- package/dist/esm/middlewares/usage-attributes.js +43 -0
- package/dist/esm/middlewares/usage-attributes.js.map +1 -0
- package/dist/esm/realtime/index.d.ts +28 -0
- package/dist/esm/realtime/index.js +8 -0
- package/dist/esm/realtime/index.js.map +1 -0
- package/dist/esm/realtime/types.d.ts +282 -0
- package/dist/esm/stream-to-response.d.ts +102 -0
- package/dist/esm/stream-to-response.js +121 -0
- package/dist/esm/stream-to-response.js.map +1 -0
- package/dist/esm/strip-to-spec-middleware.d.ts +18 -0
- package/dist/esm/strip-to-spec-middleware.js +20 -0
- package/dist/esm/strip-to-spec-middleware.js.map +1 -0
- package/dist/esm/system-prompts.d.ts +66 -0
- package/dist/esm/system-prompts.js +23 -0
- package/dist/esm/system-prompts.js.map +1 -0
- package/dist/esm/tool-registry.d.ts +81 -0
- package/dist/esm/tool-registry.js +49 -0
- package/dist/esm/tool-registry.js.map +1 -0
- package/dist/esm/tools/provider-tool.d.ts +30 -0
- package/dist/esm/tools/provider-tool.js +7 -0
- package/dist/esm/tools/provider-tool.js.map +1 -0
- package/dist/esm/types.d.ts +1627 -0
- package/dist/esm/utilities/ag-ui-wire.d.ts +44 -0
- package/dist/esm/utilities/ag-ui-wire.js +107 -0
- package/dist/esm/utilities/ag-ui-wire.js.map +1 -0
- package/dist/esm/utilities/chat-params.d.ts +85 -0
- package/dist/esm/utilities/chat-params.js +100 -0
- package/dist/esm/utilities/chat-params.js.map +1 -0
- package/dist/esm/utilities/errors.d.ts +13 -0
- package/dist/esm/utilities/errors.js +22 -0
- package/dist/esm/utilities/errors.js.map +1 -0
- package/dist/esm/utilities/media-prompt.d.ts +35 -0
- package/dist/esm/utilities/media-prompt.js +43 -0
- package/dist/esm/utilities/media-prompt.js.map +1 -0
- package/dist/esm/utilities/numbers.d.ts +8 -0
- package/dist/esm/utilities/numbers.js +12 -0
- package/dist/esm/utilities/numbers.js.map +1 -0
- package/dist/esm/utilities/sampling-keys.d.ts +20 -0
- package/dist/esm/utilities/sampling-keys.js +20 -0
- package/dist/esm/utilities/sampling-keys.js.map +1 -0
- package/dist/esm/utilities/tool-result.d.ts +21 -0
- package/dist/esm/utilities/tool-result.js +37 -0
- package/dist/esm/utilities/tool-result.js.map +1 -0
- package/dist/esm/utilities/usage.d.ts +31 -0
- package/dist/esm/utilities/usage.js +11 -0
- package/dist/esm/utilities/usage.js.map +1 -0
- package/dist/esm/utils.d.ts +17 -0
- package/dist/esm/utils.js +20 -0
- package/dist/esm/utils.js.map +1 -0
- package/package.json +3 -3
- package/skills/ai-core/chat-experience/SKILL.md +30 -2
- package/skills/ai-core/media-generation/SKILL.md +13 -0
- package/skills/ai-core/tool-calling/SKILL.md +10 -3
- package/src/activities/chat/mcp/manager.ts +31 -1
- package/src/activities/chat/mcp/types.ts +23 -0
- package/src/activities/chat/messages.ts +5 -0
- package/src/activities/chat/stream/processor.ts +42 -0
- package/src/activities/chat/tools/tool-calls.ts +96 -2
- package/src/client.ts +1 -0
- package/src/types.ts +31 -0
|
@@ -0,0 +1,510 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CapabilityHandle } from './capabilities.js';
|
|
2
|
+
import { ChatMiddleware } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A middleware whose `requires`/`provides` tuple types are captured precisely
|
|
5
|
+
* (via `const` inference) for the array coverage check and the builder.
|
|
6
|
+
*/
|
|
7
|
+
export interface DefinedChatMiddleware<TContext, TRequires extends ReadonlyArray<CapabilityHandle>, TProvides extends ReadonlyArray<CapabilityHandle>> extends ChatMiddleware<TContext> {
|
|
8
|
+
requires?: TRequires;
|
|
9
|
+
provides?: TProvides;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Identity helper for authoring middleware with precise capability inference.
|
|
13
|
+
* Returns the middleware unchanged at runtime; only sharpens its type so the
|
|
14
|
+
* `chat()` array coverage check and `createChatMiddleware` builder can read the
|
|
15
|
+
* exact `requires`/`provides`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function defineChatMiddleware<TContext = unknown, const TRequires extends ReadonlyArray<CapabilityHandle> = readonly [], const TProvides extends ReadonlyArray<CapabilityHandle> = readonly []>(middleware: ChatMiddleware<TContext> & {
|
|
18
|
+
requires?: TRequires;
|
|
19
|
+
provides?: TProvides;
|
|
20
|
+
}): DefinedChatMiddleware<TContext, TRequires, TProvides>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.js","sources":["../../../../../src/activities/chat/middleware/define.ts"],"sourcesContent":["import type { CapabilityHandle } from './capabilities'\nimport type { ChatMiddleware } from './types'\n\n/**\n * A middleware whose `requires`/`provides` tuple types are captured precisely\n * (via `const` inference) for the array coverage check and the builder.\n */\nexport interface DefinedChatMiddleware<\n TContext,\n TRequires extends ReadonlyArray<CapabilityHandle>,\n TProvides extends ReadonlyArray<CapabilityHandle>,\n> extends ChatMiddleware<TContext> {\n requires?: TRequires\n provides?: TProvides\n}\n\n/**\n * Identity helper for authoring middleware with precise capability inference.\n * Returns the middleware unchanged at runtime; only sharpens its type so the\n * `chat()` array coverage check and `createChatMiddleware` builder can read the\n * exact `requires`/`provides`.\n */\nexport function defineChatMiddleware<\n TContext = unknown,\n const TRequires extends ReadonlyArray<CapabilityHandle> = readonly [],\n const TProvides extends ReadonlyArray<CapabilityHandle> = readonly [],\n>(\n middleware: ChatMiddleware<TContext> & {\n requires?: TRequires\n provides?: TProvides\n },\n): DefinedChatMiddleware<TContext, TRequires, TProvides> {\n return middleware\n}\n"],"names":[],"mappings":"AAsBO,SAAS,qBAKd,YAIuD;AACvD,SAAO;AACT;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { ChatMiddleware, ChatMiddlewareContext, ChatMiddlewarePhase, ChatMiddlewareConfig, StructuredOutputMiddlewareConfig, ToolCallHookContext, BeforeToolCallDecision, AfterToolCallInfo, IterationInfo, ToolPhaseCompleteInfo, UsageInfo, FinishInfo, AbortInfo, ErrorInfo, } from './types.js';
|
|
2
|
+
export { MiddlewareRunner } from './compose.js';
|
|
3
|
+
export { createCapability, CapabilityRegistry } from './capabilities.js';
|
|
4
|
+
export type { Capability, CapabilityHandle, CapabilityContext, CapabilityGetter, CapabilityProvider, CapabilityGetOptions, } from './capabilities.js';
|
|
5
|
+
export { defineChatMiddleware } from './define.js';
|
|
6
|
+
export type { DefinedChatMiddleware } from './define.js';
|
|
7
|
+
export { createChatMiddleware } from './builder.js';
|
|
8
|
+
export type { ChatMiddlewareBuilder, MissingCapabilities, NamesOf, } from './builder.js';
|
|
9
|
+
export { validateCapabilities } from './validate.js';
|
|
10
|
+
export type { AnyChatMiddleware } from './types.js';
|