@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,20 +0,0 @@
|
|
|
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>;
|
|
@@ -1 +0,0 @@
|
|
|
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;"}
|
|
@@ -1,10 +0,0 @@
|
|
|
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';
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { ChatMiddleware } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* A cache entry stored by the tool cache middleware.
|
|
4
|
-
*/
|
|
5
|
-
export interface ToolCacheEntry {
|
|
6
|
-
result: unknown;
|
|
7
|
-
timestamp: number;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Custom storage backend for the tool cache middleware.
|
|
11
|
-
*
|
|
12
|
-
* When provided, the middleware delegates all cache operations to this storage
|
|
13
|
-
* instead of using the built-in in-memory Map. This enables external storage
|
|
14
|
-
* backends like Redis, localStorage, databases, etc.
|
|
15
|
-
*
|
|
16
|
-
* All methods may return a Promise for async storage backends.
|
|
17
|
-
*/
|
|
18
|
-
export interface ToolCacheStorage {
|
|
19
|
-
getItem: (key: string) => ToolCacheEntry | undefined | Promise<ToolCacheEntry | undefined>;
|
|
20
|
-
setItem: (key: string, value: ToolCacheEntry) => void | Promise<void>;
|
|
21
|
-
deleteItem: (key: string) => void | Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Options for the tool cache middleware.
|
|
25
|
-
*/
|
|
26
|
-
export interface ToolCacheMiddlewareOptions {
|
|
27
|
-
/**
|
|
28
|
-
* Maximum number of entries in the cache.
|
|
29
|
-
* When exceeded, the oldest entry is evicted (LRU).
|
|
30
|
-
*
|
|
31
|
-
* Only applies to the default in-memory storage.
|
|
32
|
-
* When a custom `storage` is provided, capacity management is the storage's responsibility.
|
|
33
|
-
*
|
|
34
|
-
* @default 100
|
|
35
|
-
*/
|
|
36
|
-
maxSize?: number;
|
|
37
|
-
/**
|
|
38
|
-
* Time-to-live in milliseconds. Entries older than this are not served from cache.
|
|
39
|
-
* @default Infinity (no expiry)
|
|
40
|
-
*/
|
|
41
|
-
ttl?: number;
|
|
42
|
-
/**
|
|
43
|
-
* Tool names to cache. If not provided, all tools are cached.
|
|
44
|
-
*/
|
|
45
|
-
toolNames?: Array<string>;
|
|
46
|
-
/**
|
|
47
|
-
* Custom function to generate a cache key from tool name and args.
|
|
48
|
-
* Defaults to `JSON.stringify([toolName, args])`.
|
|
49
|
-
*/
|
|
50
|
-
keyFn?: (toolName: string, args: unknown) => string;
|
|
51
|
-
/**
|
|
52
|
-
* Custom storage backend. When provided, the middleware uses this instead of
|
|
53
|
-
* the built-in in-memory Map. The storage is responsible for its own capacity
|
|
54
|
-
* management — the `maxSize` option is ignored.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* toolCacheMiddleware({
|
|
59
|
-
* storage: {
|
|
60
|
-
* getItem: (key) => redisClient.get(key).then(v => v ? JSON.parse(v) : undefined),
|
|
61
|
-
* setItem: (key, value) => redisClient.set(key, JSON.stringify(value)),
|
|
62
|
-
* deleteItem: (key) => redisClient.del(key),
|
|
63
|
-
* },
|
|
64
|
-
* })
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
storage?: ToolCacheStorage;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Creates a middleware that caches tool call results based on tool name + arguments.
|
|
71
|
-
*
|
|
72
|
-
* When a tool is called with the same name and arguments as a previous call,
|
|
73
|
-
* the cached result is returned immediately without executing the tool.
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* ```ts
|
|
77
|
-
* import { chat, toolCacheMiddleware } from '@tanstack/ai'
|
|
78
|
-
*
|
|
79
|
-
* const stream = chat({
|
|
80
|
-
* adapter,
|
|
81
|
-
* messages,
|
|
82
|
-
* tools: [weatherTool, stockTool],
|
|
83
|
-
* middleware: [
|
|
84
|
-
* toolCacheMiddleware({ ttl: 60_000, toolNames: ['getWeather'] }),
|
|
85
|
-
* ],
|
|
86
|
-
* })
|
|
87
|
-
* ```
|
|
88
|
-
*/
|
|
89
|
-
export declare function toolCacheMiddleware(options?: ToolCacheMiddlewareOptions): ChatMiddleware;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
function defaultKeyFn(toolName, args) {
|
|
2
|
-
return JSON.stringify([toolName, args]);
|
|
3
|
-
}
|
|
4
|
-
function createDefaultStorage(maxSize) {
|
|
5
|
-
const cache = /* @__PURE__ */ new Map();
|
|
6
|
-
return {
|
|
7
|
-
getItem: (key) => {
|
|
8
|
-
const entry = cache.get(key);
|
|
9
|
-
if (entry !== void 0) {
|
|
10
|
-
cache.delete(key);
|
|
11
|
-
cache.set(key, entry);
|
|
12
|
-
}
|
|
13
|
-
return entry;
|
|
14
|
-
},
|
|
15
|
-
setItem: (key, value) => {
|
|
16
|
-
if (cache.has(key)) {
|
|
17
|
-
cache.delete(key);
|
|
18
|
-
} else if (cache.size >= maxSize) {
|
|
19
|
-
const firstKey = cache.keys().next().value;
|
|
20
|
-
if (firstKey !== void 0) {
|
|
21
|
-
cache.delete(firstKey);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
cache.set(key, value);
|
|
25
|
-
},
|
|
26
|
-
deleteItem: (key) => {
|
|
27
|
-
cache.delete(key);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function toolCacheMiddleware(options = {}) {
|
|
32
|
-
const {
|
|
33
|
-
maxSize = 100,
|
|
34
|
-
ttl = Infinity,
|
|
35
|
-
toolNames,
|
|
36
|
-
keyFn = defaultKeyFn,
|
|
37
|
-
storage = createDefaultStorage(maxSize)
|
|
38
|
-
} = options;
|
|
39
|
-
return {
|
|
40
|
-
name: "tool-cache-middleware",
|
|
41
|
-
onBeforeToolCall: async (_ctx, hookCtx) => {
|
|
42
|
-
if (toolNames && !toolNames.includes(hookCtx.toolName)) {
|
|
43
|
-
return void 0;
|
|
44
|
-
}
|
|
45
|
-
const key = keyFn(hookCtx.toolName, hookCtx.args);
|
|
46
|
-
const entry = await storage.getItem(key);
|
|
47
|
-
if (entry) {
|
|
48
|
-
const age = Date.now() - entry.timestamp;
|
|
49
|
-
if (age < ttl) {
|
|
50
|
-
return { type: "skip", result: entry.result };
|
|
51
|
-
}
|
|
52
|
-
await storage.deleteItem(key);
|
|
53
|
-
}
|
|
54
|
-
return void 0;
|
|
55
|
-
},
|
|
56
|
-
onAfterToolCall: async (_ctx, info) => {
|
|
57
|
-
if (!info.ok) return;
|
|
58
|
-
if (toolNames && !toolNames.includes(info.toolName)) return;
|
|
59
|
-
let parsedArgs;
|
|
60
|
-
try {
|
|
61
|
-
parsedArgs = JSON.parse(info.toolCall.function.arguments.trim() || "{}");
|
|
62
|
-
} catch {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const key = keyFn(info.toolName, parsedArgs);
|
|
66
|
-
await storage.setItem(key, {
|
|
67
|
-
result: info.result,
|
|
68
|
-
timestamp: Date.now()
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
export {
|
|
74
|
-
toolCacheMiddleware
|
|
75
|
-
};
|
|
76
|
-
//# sourceMappingURL=tool-cache-middleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-cache-middleware.js","sources":["../../../../../src/activities/chat/middleware/tool-cache-middleware.ts"],"sourcesContent":["import type { ChatMiddleware } from './types'\n\n/**\n * A cache entry stored by the tool cache middleware.\n */\nexport interface ToolCacheEntry {\n result: unknown\n timestamp: number\n}\n\n/**\n * Custom storage backend for the tool cache middleware.\n *\n * When provided, the middleware delegates all cache operations to this storage\n * instead of using the built-in in-memory Map. This enables external storage\n * backends like Redis, localStorage, databases, etc.\n *\n * All methods may return a Promise for async storage backends.\n */\nexport interface ToolCacheStorage {\n getItem: (\n key: string,\n ) => ToolCacheEntry | undefined | Promise<ToolCacheEntry | undefined>\n setItem: (key: string, value: ToolCacheEntry) => void | Promise<void>\n deleteItem: (key: string) => void | Promise<void>\n}\n\n/**\n * Options for the tool cache middleware.\n */\nexport interface ToolCacheMiddlewareOptions {\n /**\n * Maximum number of entries in the cache.\n * When exceeded, the oldest entry is evicted (LRU).\n *\n * Only applies to the default in-memory storage.\n * When a custom `storage` is provided, capacity management is the storage's responsibility.\n *\n * @default 100\n */\n maxSize?: number\n\n /**\n * Time-to-live in milliseconds. Entries older than this are not served from cache.\n * @default Infinity (no expiry)\n */\n ttl?: number\n\n /**\n * Tool names to cache. If not provided, all tools are cached.\n */\n toolNames?: Array<string>\n\n /**\n * Custom function to generate a cache key from tool name and args.\n * Defaults to `JSON.stringify([toolName, args])`.\n */\n keyFn?: (toolName: string, args: unknown) => string\n\n /**\n * Custom storage backend. When provided, the middleware uses this instead of\n * the built-in in-memory Map. The storage is responsible for its own capacity\n * management — the `maxSize` option is ignored.\n *\n * @example\n * ```ts\n * toolCacheMiddleware({\n * storage: {\n * getItem: (key) => redisClient.get(key).then(v => v ? JSON.parse(v) : undefined),\n * setItem: (key, value) => redisClient.set(key, JSON.stringify(value)),\n * deleteItem: (key) => redisClient.del(key),\n * },\n * })\n * ```\n */\n storage?: ToolCacheStorage\n}\n\nfunction defaultKeyFn(toolName: string, args: unknown): string {\n return JSON.stringify([toolName, args])\n}\n\nfunction createDefaultStorage(maxSize: number): ToolCacheStorage {\n const cache = new Map<string, ToolCacheEntry>()\n\n return {\n getItem: (key) => {\n const entry = cache.get(key)\n if (entry !== undefined) {\n // Refresh recency: delete and re-insert so this key becomes newest\n cache.delete(key)\n cache.set(key, entry)\n }\n return entry\n },\n setItem: (key, value) => {\n // Delete first so re-inserts also refresh recency\n if (cache.has(key)) {\n cache.delete(key)\n } else if (cache.size >= maxSize) {\n // LRU eviction: Map iteration order is insertion order — first key is least recently used\n const firstKey = cache.keys().next().value\n if (firstKey !== undefined) {\n cache.delete(firstKey)\n }\n }\n cache.set(key, value)\n },\n deleteItem: (key) => {\n cache.delete(key)\n },\n }\n}\n\n/**\n * Creates a middleware that caches tool call results based on tool name + arguments.\n *\n * When a tool is called with the same name and arguments as a previous call,\n * the cached result is returned immediately without executing the tool.\n *\n * @example\n * ```ts\n * import { chat, toolCacheMiddleware } from '@tanstack/ai'\n *\n * const stream = chat({\n * adapter,\n * messages,\n * tools: [weatherTool, stockTool],\n * middleware: [\n * toolCacheMiddleware({ ttl: 60_000, toolNames: ['getWeather'] }),\n * ],\n * })\n * ```\n */\nexport function toolCacheMiddleware(\n options: ToolCacheMiddlewareOptions = {},\n): ChatMiddleware {\n const {\n maxSize = 100,\n ttl = Infinity,\n toolNames,\n keyFn = defaultKeyFn,\n storage = createDefaultStorage(maxSize),\n } = options\n\n return {\n name: 'tool-cache-middleware',\n\n onBeforeToolCall: async (_ctx, hookCtx) => {\n if (toolNames && !toolNames.includes(hookCtx.toolName)) {\n return undefined\n }\n\n const key = keyFn(hookCtx.toolName, hookCtx.args)\n const entry = await storage.getItem(key)\n\n if (entry) {\n const age = Date.now() - entry.timestamp\n if (age < ttl) {\n return { type: 'skip', result: entry.result }\n }\n // Expired — remove\n await storage.deleteItem(key)\n }\n\n return undefined\n },\n\n onAfterToolCall: async (_ctx, info) => {\n if (!info.ok) return\n if (toolNames && !toolNames.includes(info.toolName)) return\n\n // Re-derive the key from the raw arguments to match what onBeforeToolCall produces\n let parsedArgs: unknown\n try {\n parsedArgs = JSON.parse(info.toolCall.function.arguments.trim() || '{}')\n } catch {\n return\n }\n\n const key = keyFn(info.toolName, parsedArgs)\n\n await storage.setItem(key, {\n result: info.result,\n timestamp: Date.now(),\n })\n },\n }\n}\n"],"names":[],"mappings":"AA8EA,SAAS,aAAa,UAAkB,MAAuB;AAC7D,SAAO,KAAK,UAAU,CAAC,UAAU,IAAI,CAAC;AACxC;AAEA,SAAS,qBAAqB,SAAmC;AAC/D,QAAM,4BAAY,IAAA;AAElB,SAAO;AAAA,IACL,SAAS,CAAC,QAAQ;AAChB,YAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,UAAI,UAAU,QAAW;AAEvB,cAAM,OAAO,GAAG;AAChB,cAAM,IAAI,KAAK,KAAK;AAAA,MACtB;AACA,aAAO;AAAA,IACT;AAAA,IACA,SAAS,CAAC,KAAK,UAAU;AAEvB,UAAI,MAAM,IAAI,GAAG,GAAG;AAClB,cAAM,OAAO,GAAG;AAAA,MAClB,WAAW,MAAM,QAAQ,SAAS;AAEhC,cAAM,WAAW,MAAM,KAAA,EAAO,OAAO;AACrC,YAAI,aAAa,QAAW;AAC1B,gBAAM,OAAO,QAAQ;AAAA,QACvB;AAAA,MACF;AACA,YAAM,IAAI,KAAK,KAAK;AAAA,IACtB;AAAA,IACA,YAAY,CAAC,QAAQ;AACnB,YAAM,OAAO,GAAG;AAAA,IAClB;AAAA,EAAA;AAEJ;AAsBO,SAAS,oBACd,UAAsC,IACtB;AAChB,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,MAAM;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,qBAAqB,OAAO;AAAA,EAAA,IACpC;AAEJ,SAAO;AAAA,IACL,MAAM;AAAA,IAEN,kBAAkB,OAAO,MAAM,YAAY;AACzC,UAAI,aAAa,CAAC,UAAU,SAAS,QAAQ,QAAQ,GAAG;AACtD,eAAO;AAAA,MACT;AAEA,YAAM,MAAM,MAAM,QAAQ,UAAU,QAAQ,IAAI;AAChD,YAAM,QAAQ,MAAM,QAAQ,QAAQ,GAAG;AAEvC,UAAI,OAAO;AACT,cAAM,MAAM,KAAK,IAAA,IAAQ,MAAM;AAC/B,YAAI,MAAM,KAAK;AACb,iBAAO,EAAE,MAAM,QAAQ,QAAQ,MAAM,OAAA;AAAA,QACvC;AAEA,cAAM,QAAQ,WAAW,GAAG;AAAA,MAC9B;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,iBAAiB,OAAO,MAAM,SAAS;AACrC,UAAI,CAAC,KAAK,GAAI;AACd,UAAI,aAAa,CAAC,UAAU,SAAS,KAAK,QAAQ,EAAG;AAGrD,UAAI;AACJ,UAAI;AACF,qBAAa,KAAK,MAAM,KAAK,SAAS,SAAS,UAAU,KAAA,KAAU,IAAI;AAAA,MACzE,QAAQ;AACN;AAAA,MACF;AAEA,YAAM,MAAM,MAAM,KAAK,UAAU,UAAU;AAE3C,YAAM,QAAQ,QAAQ,KAAK;AAAA,QACzB,QAAQ,KAAK;AAAA,QACb,WAAW,KAAK,IAAA;AAAA,MAAI,CACrB;AAAA,IACH;AAAA,EAAA;AAEJ;"}
|
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
import { JSONSchema, ModelMessage, StreamChunk, TokenUsage, Tool, ToolCall } from '../../../types.js';
|
|
2
|
-
import { SystemPrompt } from '../../../system-prompts.js';
|
|
3
|
-
import { Capability, CapabilityHandle, CapabilityRegistry } from './capabilities.js';
|
|
4
|
-
/**
|
|
5
|
-
* Phase of the chat middleware lifecycle.
|
|
6
|
-
* - 'init': Initial config transform before the chat engine starts
|
|
7
|
-
* - 'beforeModel': Before each adapter chatStream call (per agent iteration)
|
|
8
|
-
* - 'modelStream': During model streaming
|
|
9
|
-
* - 'beforeTools': Before tool execution phase
|
|
10
|
-
* - 'afterTools': After tool execution phase
|
|
11
|
-
* - 'structuredOutput': During the final structured-output adapter call (set
|
|
12
|
-
* for chunks from adapter.structuredOutputStream or the synthesized fallback)
|
|
13
|
-
*/
|
|
14
|
-
export type ChatMiddlewarePhase = 'init' | 'beforeModel' | 'modelStream' | 'beforeTools' | 'afterTools' | 'structuredOutput';
|
|
15
|
-
/**
|
|
16
|
-
* Stable context object passed to all middleware hooks.
|
|
17
|
-
* Created once per chat() invocation and shared across all hooks.
|
|
18
|
-
*/
|
|
19
|
-
export interface ChatMiddlewareContext<TContext = unknown> {
|
|
20
|
-
/** Unique identifier for this chat request */
|
|
21
|
-
requestId: string;
|
|
22
|
-
/** Unique identifier for this stream */
|
|
23
|
-
streamId: string;
|
|
24
|
-
/** AG-UI run identifier for correlating client and server events */
|
|
25
|
-
runId: string;
|
|
26
|
-
/**
|
|
27
|
-
* AG-UI thread identifier — a stable per-conversation ID used to
|
|
28
|
-
* correlate client and server devtools events. Resolves to the
|
|
29
|
-
* caller-provided `threadId` (or legacy `conversationId`), or an
|
|
30
|
-
* auto-generated value when neither is supplied.
|
|
31
|
-
*/
|
|
32
|
-
threadId: string;
|
|
33
|
-
/**
|
|
34
|
-
* @deprecated Use `threadId` instead. Retained as an alias of
|
|
35
|
-
* `threadId` so middleware written before the AG-UI rename keeps
|
|
36
|
-
* working unchanged. Will be removed in a future major release.
|
|
37
|
-
*/
|
|
38
|
-
conversationId?: string;
|
|
39
|
-
/** Current lifecycle phase */
|
|
40
|
-
phase: ChatMiddlewarePhase;
|
|
41
|
-
/** Current agent loop iteration (0-indexed) */
|
|
42
|
-
iteration: number;
|
|
43
|
-
/** Running count of chunks yielded so far */
|
|
44
|
-
chunkIndex: number;
|
|
45
|
-
/** Abort signal from the chat request */
|
|
46
|
-
signal?: AbortSignal;
|
|
47
|
-
/** Abort the chat run with a reason */
|
|
48
|
-
abort: (reason?: string) => void;
|
|
49
|
-
/** Runtime context provided by chat() options */
|
|
50
|
-
context: TContext;
|
|
51
|
-
/**
|
|
52
|
-
* Defer a non-blocking side-effect promise.
|
|
53
|
-
* Deferred promises do not block streaming and are awaited
|
|
54
|
-
* after the terminal hook (onFinish/onAbort/onError).
|
|
55
|
-
*/
|
|
56
|
-
defer: (promise: Promise<unknown>) => void;
|
|
57
|
-
/**
|
|
58
|
-
* Which activity this context describes — always `'chat'`. Present so the
|
|
59
|
-
* chat context structurally satisfies the base `GenerationMiddlewareContext`,
|
|
60
|
-
* letting an observe-only middleware authored against the base (e.g.
|
|
61
|
-
* `otelMiddleware`) run on both chat and media activities.
|
|
62
|
-
*/
|
|
63
|
-
activity: 'chat';
|
|
64
|
-
/** Provider name (e.g., 'openai', 'anthropic') */
|
|
65
|
-
provider: string;
|
|
66
|
-
/** Model identifier (e.g., 'gpt-4o') */
|
|
67
|
-
model: string;
|
|
68
|
-
/** Source of the chat invocation — always 'server' for server-side chat */
|
|
69
|
-
source: 'client' | 'server';
|
|
70
|
-
/** Whether the chat is streaming */
|
|
71
|
-
streaming: boolean;
|
|
72
|
-
/** System prompts configured for this chat */
|
|
73
|
-
systemPrompts: Array<SystemPrompt>;
|
|
74
|
-
/** Names of configured tools, if any */
|
|
75
|
-
toolNames?: Array<string>;
|
|
76
|
-
/** Flattened generation options (metadata) */
|
|
77
|
-
options?: Record<string, unknown> | undefined;
|
|
78
|
-
/** Provider-specific model options */
|
|
79
|
-
modelOptions?: Record<string, unknown> | undefined;
|
|
80
|
-
/** Number of messages at the start of the request */
|
|
81
|
-
messageCount: number;
|
|
82
|
-
/** Whether tools are configured */
|
|
83
|
-
hasTools: boolean;
|
|
84
|
-
/** Current assistant message ID (changes per iteration) */
|
|
85
|
-
currentMessageId: string | null;
|
|
86
|
-
/** Accumulated text content for the current iteration */
|
|
87
|
-
accumulatedContent: string;
|
|
88
|
-
/** Current messages array (read-only view) */
|
|
89
|
-
messages: ReadonlyArray<ModelMessage>;
|
|
90
|
-
/** Generate a unique ID with the given prefix */
|
|
91
|
-
createId: (prefix: string) => string;
|
|
92
|
-
/**
|
|
93
|
-
* Capability bookkeeping for this request. Populated by middleware `setup`
|
|
94
|
-
* hooks (via `provide` accessors) and read by later middleware (via `get`
|
|
95
|
-
* accessors). Prefer the accessors returned by `createCapability` over using
|
|
96
|
-
* this directly. Orthogonal to `context` (the user runtime context).
|
|
97
|
-
*/
|
|
98
|
-
capabilities: CapabilityRegistry;
|
|
99
|
-
/**
|
|
100
|
-
* Read a provided capability by its handle. Equivalent to the handle's own
|
|
101
|
-
* `get` accessor (`getX(ctx)`); throws if the capability was never provided.
|
|
102
|
-
*/
|
|
103
|
-
get: <TValue>(capability: Capability<TValue>) => TValue;
|
|
104
|
-
/**
|
|
105
|
-
* Read a capability by its handle, returning `undefined` if it was never
|
|
106
|
-
* provided (never throws).
|
|
107
|
-
*/
|
|
108
|
-
getOptional: <TValue>(capability: Capability<TValue>) => TValue | undefined;
|
|
109
|
-
/**
|
|
110
|
-
* Provide a capability value. Equivalent to the handle's own `provide`
|
|
111
|
-
* accessor (`provideX(ctx, value)`). Typically called from `setup`.
|
|
112
|
-
*/
|
|
113
|
-
provide: <TValue>(capability: Capability<TValue>, value: TValue) => void;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Chat configuration that middleware can observe or transform.
|
|
117
|
-
* This is a subset of the chat engine's effective configuration
|
|
118
|
-
* that middleware is allowed to modify.
|
|
119
|
-
*/
|
|
120
|
-
export interface ChatMiddlewareConfig {
|
|
121
|
-
messages: Array<ModelMessage>;
|
|
122
|
-
systemPrompts: Array<SystemPrompt>;
|
|
123
|
-
tools: Array<Tool>;
|
|
124
|
-
metadata?: Record<string, unknown> | undefined;
|
|
125
|
-
modelOptions?: Record<string, unknown> | undefined;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Config passed to onStructuredOutputConfig.
|
|
129
|
-
*
|
|
130
|
-
* Mirrors ChatMiddlewareConfig minus `tools` (the final structured-output call
|
|
131
|
-
* is a single typed-response request, not an agentic loop — tools cannot be
|
|
132
|
-
* forwarded to it), plus the `outputSchema` being sent to the provider.
|
|
133
|
-
* Middleware may transform the schema (e.g., inject $defs, strip
|
|
134
|
-
* vendor-incompatible keywords) by returning a partial that includes
|
|
135
|
-
* `outputSchema`.
|
|
136
|
-
*/
|
|
137
|
-
export interface StructuredOutputMiddlewareConfig extends Omit<ChatMiddlewareConfig, 'tools'> {
|
|
138
|
-
/** JSON Schema being sent to the provider for structured output. */
|
|
139
|
-
outputSchema: JSONSchema;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Context provided to tool call hooks (onBeforeToolCall / onAfterToolCall).
|
|
143
|
-
*/
|
|
144
|
-
export interface ToolCallHookContext {
|
|
145
|
-
/** The tool call being executed */
|
|
146
|
-
toolCall: ToolCall;
|
|
147
|
-
/** The resolved tool definition, if found */
|
|
148
|
-
tool: Tool | undefined;
|
|
149
|
-
/** Parsed arguments for the tool call */
|
|
150
|
-
args: unknown;
|
|
151
|
-
/** Name of the tool */
|
|
152
|
-
toolName: string;
|
|
153
|
-
/** ID of the tool call */
|
|
154
|
-
toolCallId: string;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Decision returned from onBeforeToolCall.
|
|
158
|
-
* - undefined/void: continue with normal execution
|
|
159
|
-
* - { type: 'transformArgs', args }: replace args used for execution
|
|
160
|
-
* - { type: 'skip', result }: skip execution, use provided result
|
|
161
|
-
* - { type: 'abort', reason }: abort the entire chat run
|
|
162
|
-
*/
|
|
163
|
-
export type BeforeToolCallDecision = void | undefined | null | {
|
|
164
|
-
type: 'transformArgs';
|
|
165
|
-
args: unknown;
|
|
166
|
-
} | {
|
|
167
|
-
type: 'skip';
|
|
168
|
-
result: unknown;
|
|
169
|
-
} | {
|
|
170
|
-
type: 'abort';
|
|
171
|
-
reason?: string;
|
|
172
|
-
};
|
|
173
|
-
/**
|
|
174
|
-
* Outcome information provided to onAfterToolCall.
|
|
175
|
-
*/
|
|
176
|
-
export interface AfterToolCallInfo {
|
|
177
|
-
/** The tool call that was executed */
|
|
178
|
-
toolCall: ToolCall;
|
|
179
|
-
/** The resolved tool definition */
|
|
180
|
-
tool: Tool | undefined;
|
|
181
|
-
/** Name of the tool */
|
|
182
|
-
toolName: string;
|
|
183
|
-
/** ID of the tool call */
|
|
184
|
-
toolCallId: string;
|
|
185
|
-
/** Whether the execution succeeded */
|
|
186
|
-
ok: boolean;
|
|
187
|
-
/** Duration of tool execution in milliseconds */
|
|
188
|
-
duration: number;
|
|
189
|
-
/** The result (if ok) or error (if not ok) */
|
|
190
|
-
result?: unknown;
|
|
191
|
-
error?: unknown;
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Information passed to onIteration at the start of each agent loop iteration.
|
|
195
|
-
*/
|
|
196
|
-
export interface IterationInfo {
|
|
197
|
-
/** 0-based iteration index */
|
|
198
|
-
iteration: number;
|
|
199
|
-
/** The assistant message ID created for this iteration */
|
|
200
|
-
messageId: string;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Aggregate information passed to onToolPhaseComplete after all tool calls
|
|
204
|
-
* in an iteration have been processed.
|
|
205
|
-
*/
|
|
206
|
-
export interface ToolPhaseCompleteInfo {
|
|
207
|
-
/** Tool calls that were assigned to the assistant message */
|
|
208
|
-
toolCalls: Array<ToolCall>;
|
|
209
|
-
/** Completed tool results */
|
|
210
|
-
results: Array<{
|
|
211
|
-
toolCallId: string;
|
|
212
|
-
toolName: string;
|
|
213
|
-
result: unknown;
|
|
214
|
-
duration?: number;
|
|
215
|
-
}>;
|
|
216
|
-
/** Tools that need user approval */
|
|
217
|
-
needsApproval: Array<{
|
|
218
|
-
toolCallId: string;
|
|
219
|
-
toolName: string;
|
|
220
|
-
input: unknown;
|
|
221
|
-
approvalId: string;
|
|
222
|
-
}>;
|
|
223
|
-
/** Tools that need client-side execution */
|
|
224
|
-
needsClientExecution: Array<{
|
|
225
|
-
toolCallId: string;
|
|
226
|
-
toolName: string;
|
|
227
|
-
input: unknown;
|
|
228
|
-
}>;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Token usage statistics passed to the onUsage hook.
|
|
232
|
-
* Extracted from the RUN_FINISHED chunk when usage data is present.
|
|
233
|
-
*
|
|
234
|
-
* Includes optional provider-reported `cost`/`costDetails` (see {@link TokenUsage}).
|
|
235
|
-
* Kept as an interface extending `TokenUsage` to preserve declaration merging for
|
|
236
|
-
* this publicly exported type.
|
|
237
|
-
*/
|
|
238
|
-
export interface UsageInfo extends TokenUsage {
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Information passed to onFinish.
|
|
242
|
-
*/
|
|
243
|
-
export interface FinishInfo {
|
|
244
|
-
/** The finish reason from the last model response */
|
|
245
|
-
finishReason: string | null;
|
|
246
|
-
/** Total duration of the chat run in milliseconds */
|
|
247
|
-
duration: number;
|
|
248
|
-
/** Final accumulated text content */
|
|
249
|
-
content: string;
|
|
250
|
-
/** Final usage totals, if available (optionally including provider-reported cost) */
|
|
251
|
-
usage?: TokenUsage | undefined;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Information passed to onAbort.
|
|
255
|
-
*/
|
|
256
|
-
export interface AbortInfo {
|
|
257
|
-
/** The reason for the abort, if provided */
|
|
258
|
-
reason?: string;
|
|
259
|
-
/** Duration until abort in milliseconds */
|
|
260
|
-
duration: number;
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Information passed to onError.
|
|
264
|
-
*/
|
|
265
|
-
export interface ErrorInfo {
|
|
266
|
-
/** The error that caused the failure */
|
|
267
|
-
error: unknown;
|
|
268
|
-
/** Duration until error in milliseconds */
|
|
269
|
-
duration: number;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Chat middleware interface.
|
|
273
|
-
*
|
|
274
|
-
* All hooks are optional. Middleware is composed in array order:
|
|
275
|
-
* - `onConfig`: config piped through middlewares in order (first transform influences later)
|
|
276
|
-
* - `onChunk`: each output chunk is fed into the next middleware in order
|
|
277
|
-
*
|
|
278
|
-
* @example Logging middleware
|
|
279
|
-
* ```ts
|
|
280
|
-
* const loggingMiddleware: ChatMiddleware = {
|
|
281
|
-
* name: 'logging',
|
|
282
|
-
* onStart(ctx) { console.log('Chat started', ctx.requestId) },
|
|
283
|
-
* onChunk(ctx, chunk) { console.log('Chunk:', chunk.type) },
|
|
284
|
-
* onFinish(ctx, info) { console.log('Done:', info.duration, 'ms') },
|
|
285
|
-
* }
|
|
286
|
-
* ```
|
|
287
|
-
*
|
|
288
|
-
* @example Redaction middleware
|
|
289
|
-
* ```ts
|
|
290
|
-
* const redactionMiddleware: ChatMiddleware = {
|
|
291
|
-
* name: 'redaction',
|
|
292
|
-
* onChunk(ctx, chunk) {
|
|
293
|
-
* if (chunk.type === 'TEXT_MESSAGE_CONTENT') {
|
|
294
|
-
* return { ...chunk, delta: redact(chunk.delta) }
|
|
295
|
-
* }
|
|
296
|
-
* },
|
|
297
|
-
* }
|
|
298
|
-
* ```
|
|
299
|
-
*/
|
|
300
|
-
export interface ChatMiddleware<TContext = unknown> {
|
|
301
|
-
/** Optional name for debugging and identification */
|
|
302
|
-
name?: string;
|
|
303
|
-
/**
|
|
304
|
-
* Capabilities this middleware requires. `chat()` validates that some
|
|
305
|
-
* middleware (or the adapter) provides each one; unsatisfied requirements are
|
|
306
|
-
* a compile-time error (array coverage / builder) and a runtime error before
|
|
307
|
-
* the adapter runs.
|
|
308
|
-
*/
|
|
309
|
-
requires?: ReadonlyArray<CapabilityHandle>;
|
|
310
|
-
/**
|
|
311
|
-
* Capabilities this middleware provides. Each declared capability MUST be
|
|
312
|
-
* provided (via its `provide` accessor) inside `setup`, or `chat()` throws
|
|
313
|
-
* after the setup phase.
|
|
314
|
-
*/
|
|
315
|
-
provides?: ReadonlyArray<CapabilityHandle>;
|
|
316
|
-
/**
|
|
317
|
-
* Capabilities this middleware uses if present but does not require.
|
|
318
|
-
* Non-gating: never causes a validation error. Read with
|
|
319
|
-
* `getX(ctx, { optional: true })`.
|
|
320
|
-
*/
|
|
321
|
-
optionalRequires?: ReadonlyArray<CapabilityHandle>;
|
|
322
|
-
/**
|
|
323
|
-
* Provisioning hook. Runs FIRST — before `onConfig` (init) — across all
|
|
324
|
-
* middleware in array order. Use it to call `provide` accessors so later
|
|
325
|
-
* middleware (`onConfig` onward) can consume the capabilities. Receives the
|
|
326
|
-
* stable context; does NOT receive the mutable config.
|
|
327
|
-
*/
|
|
328
|
-
setup?: (ctx: ChatMiddlewareContext<TContext>) => void | Promise<void>;
|
|
329
|
-
/**
|
|
330
|
-
* Called to observe or transform the chat configuration.
|
|
331
|
-
* Called at init and at the beginning of each agent iteration.
|
|
332
|
-
*
|
|
333
|
-
* Return a partial config to merge with the current config, or void to pass through.
|
|
334
|
-
* Only the fields you return are overwritten — everything else is preserved.
|
|
335
|
-
*/
|
|
336
|
-
onConfig?: (ctx: ChatMiddlewareContext<TContext>, config: ChatMiddlewareConfig) => void | null | Partial<ChatMiddlewareConfig> | Promise<void | null | Partial<ChatMiddlewareConfig>>;
|
|
337
|
-
/**
|
|
338
|
-
* Called at the start of the final structured-output call (when the chat
|
|
339
|
-
* was invoked with outputSchema). Pipes through middleware in order, like
|
|
340
|
-
* onConfig, but with access to the JSON Schema being sent to the provider.
|
|
341
|
-
*
|
|
342
|
-
* Return a partial to shallow-merge into the current config, or void to
|
|
343
|
-
* pass through.
|
|
344
|
-
*
|
|
345
|
-
* Fires BEFORE onConfig at the structured-output boundary. onConfig also
|
|
346
|
-
* re-fires at the same boundary with ctx.phase === 'structuredOutput',
|
|
347
|
-
* receiving the post-onStructuredOutputConfig view of the config (minus
|
|
348
|
-
* outputSchema). Use onConfig for general-purpose transforms that apply
|
|
349
|
-
* to every adapter call; use this hook when you need to transform the
|
|
350
|
-
* outputSchema or apply structured-output-specific behavior.
|
|
351
|
-
*/
|
|
352
|
-
onStructuredOutputConfig?: (ctx: ChatMiddlewareContext<TContext>, config: StructuredOutputMiddlewareConfig) => void | null | Partial<StructuredOutputMiddlewareConfig> | Promise<void | null | Partial<StructuredOutputMiddlewareConfig>>;
|
|
353
|
-
/**
|
|
354
|
-
* Called when the chat run starts (after initial onConfig).
|
|
355
|
-
*/
|
|
356
|
-
onStart?: (ctx: ChatMiddlewareContext<TContext>) => void | Promise<void>;
|
|
357
|
-
/**
|
|
358
|
-
* Called at the start of each agent loop iteration, after a new assistant message ID
|
|
359
|
-
* is created. Use this to observe iteration boundaries.
|
|
360
|
-
*/
|
|
361
|
-
onIteration?: (ctx: ChatMiddlewareContext<TContext>, info: IterationInfo) => void | Promise<void>;
|
|
362
|
-
/**
|
|
363
|
-
* Called for every chunk yielded by chat().
|
|
364
|
-
* Can observe, transform, expand, or drop chunks.
|
|
365
|
-
*
|
|
366
|
-
* @returns void (pass through), chunk (replace), chunk[] (expand), null (drop)
|
|
367
|
-
*/
|
|
368
|
-
onChunk?: (ctx: ChatMiddlewareContext<TContext>, chunk: StreamChunk) => void | StreamChunk | Array<StreamChunk> | null | Promise<void | StreamChunk | Array<StreamChunk> | null>;
|
|
369
|
-
/**
|
|
370
|
-
* Called before a tool is executed.
|
|
371
|
-
* Can observe, transform args, skip execution, or abort the run.
|
|
372
|
-
*/
|
|
373
|
-
onBeforeToolCall?: (ctx: ChatMiddlewareContext<TContext>, hookCtx: ToolCallHookContext) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>;
|
|
374
|
-
/**
|
|
375
|
-
* Called after a tool execution completes (success or failure).
|
|
376
|
-
*/
|
|
377
|
-
onAfterToolCall?: (ctx: ChatMiddlewareContext<TContext>, info: AfterToolCallInfo) => void | Promise<void>;
|
|
378
|
-
/**
|
|
379
|
-
* Called after all tool calls in an iteration have been processed.
|
|
380
|
-
* Provides aggregate data about tool execution results, approvals, and client tools.
|
|
381
|
-
*/
|
|
382
|
-
onToolPhaseComplete?: (ctx: ChatMiddlewareContext<TContext>, info: ToolPhaseCompleteInfo) => void | Promise<void>;
|
|
383
|
-
/**
|
|
384
|
-
* Called when usage data is available from a RUN_FINISHED chunk.
|
|
385
|
-
* Called once per model iteration that reports usage.
|
|
386
|
-
*/
|
|
387
|
-
onUsage?: (ctx: ChatMiddlewareContext<TContext>, usage: UsageInfo) => void | Promise<void>;
|
|
388
|
-
/**
|
|
389
|
-
* Called when the chat run completes normally.
|
|
390
|
-
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
391
|
-
*/
|
|
392
|
-
onFinish?: (ctx: ChatMiddlewareContext<TContext>, info: FinishInfo) => void | Promise<void>;
|
|
393
|
-
/**
|
|
394
|
-
* Called when the chat run is aborted.
|
|
395
|
-
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
396
|
-
*/
|
|
397
|
-
onAbort?: (ctx: ChatMiddlewareContext<TContext>, info: AbortInfo) => void | Promise<void>;
|
|
398
|
-
/**
|
|
399
|
-
* Called when the chat run encounters an unhandled error.
|
|
400
|
-
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
401
|
-
*/
|
|
402
|
-
onError?: (ctx: ChatMiddlewareContext<TContext>, info: ErrorInfo) => void | Promise<void>;
|
|
403
|
-
}
|
|
404
|
-
/** A `ChatMiddleware` with a permissive context — for use as a constraint. */
|
|
405
|
-
export type AnyChatMiddleware = ChatMiddleware<any>;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { CapabilityHandle } from './capabilities.js';
|
|
2
|
-
import { AnyChatMiddleware } from './types.js';
|
|
3
|
-
/** Minimal adapter shape needed for capability validation. */
|
|
4
|
-
interface CapabilityRequiringAdapter {
|
|
5
|
-
name: string;
|
|
6
|
-
requires?: ReadonlyArray<CapabilityHandle>;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Runtime validation: every required capability (from middleware `requires` and
|
|
10
|
-
* the adapter's `requires`) must be provided by some middleware's `provides`.
|
|
11
|
-
* `optionalRequires` is never gating. Throws a clear error otherwise.
|
|
12
|
-
*
|
|
13
|
-
* Presence only — ORDER is not validated here (a provider may appear after its
|
|
14
|
-
* consumer in the array and still pass). Use the `createChatMiddleware()`
|
|
15
|
-
* builder for compile-time order enforcement; at runtime, a consumer that reads
|
|
16
|
-
* a not-yet-provided capability during `setup` fails loud via its getter.
|
|
17
|
-
*/
|
|
18
|
-
export declare function validateCapabilities(middlewares: ReadonlyArray<AnyChatMiddleware>, adapter: CapabilityRequiringAdapter): void;
|
|
19
|
-
export {};
|