@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,121 +0,0 @@
|
|
|
1
|
-
import { toRunErrorPayload } from "./activities/error-payload.js";
|
|
2
|
-
async function streamToText(stream) {
|
|
3
|
-
let accumulatedContent = "";
|
|
4
|
-
for await (const chunk of stream) {
|
|
5
|
-
if (chunk.type === "TEXT_MESSAGE_CONTENT" && chunk.delta) {
|
|
6
|
-
accumulatedContent += chunk.delta;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
return accumulatedContent;
|
|
10
|
-
}
|
|
11
|
-
function toServerSentEventsStream(stream, abortController) {
|
|
12
|
-
const encoder = new TextEncoder();
|
|
13
|
-
return new ReadableStream({
|
|
14
|
-
async start(controller) {
|
|
15
|
-
try {
|
|
16
|
-
for await (const chunk of stream) {
|
|
17
|
-
if (abortController?.signal.aborted) {
|
|
18
|
-
break;
|
|
19
|
-
}
|
|
20
|
-
controller.enqueue(
|
|
21
|
-
encoder.encode(`data: ${JSON.stringify(chunk)}
|
|
22
|
-
|
|
23
|
-
`)
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
controller.close();
|
|
27
|
-
} catch (error) {
|
|
28
|
-
if (abortController?.signal.aborted) {
|
|
29
|
-
controller.close();
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
controller.enqueue(
|
|
33
|
-
encoder.encode(
|
|
34
|
-
`data: ${JSON.stringify({
|
|
35
|
-
type: "RUN_ERROR",
|
|
36
|
-
timestamp: Date.now(),
|
|
37
|
-
error: toRunErrorPayload(error)
|
|
38
|
-
})}
|
|
39
|
-
|
|
40
|
-
`
|
|
41
|
-
)
|
|
42
|
-
);
|
|
43
|
-
controller.close();
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
cancel() {
|
|
47
|
-
if (abortController) {
|
|
48
|
-
abortController.abort();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
function toServerSentEventsResponse(stream, init) {
|
|
54
|
-
const { headers, abortController, ...responseInit } = init ?? {};
|
|
55
|
-
const mergedHeaders = new Headers({
|
|
56
|
-
"Content-Type": "text/event-stream",
|
|
57
|
-
"Cache-Control": "no-cache",
|
|
58
|
-
Connection: "keep-alive"
|
|
59
|
-
});
|
|
60
|
-
if (headers) {
|
|
61
|
-
const userHeaders = new Headers(headers);
|
|
62
|
-
userHeaders.forEach((value, key) => {
|
|
63
|
-
mergedHeaders.set(key, value);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return new Response(toServerSentEventsStream(stream, abortController), {
|
|
67
|
-
...responseInit,
|
|
68
|
-
headers: mergedHeaders
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
function toHttpStream(stream, abortController) {
|
|
72
|
-
const encoder = new TextEncoder();
|
|
73
|
-
return new ReadableStream({
|
|
74
|
-
async start(controller) {
|
|
75
|
-
try {
|
|
76
|
-
for await (const chunk of stream) {
|
|
77
|
-
if (abortController?.signal.aborted) {
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
controller.enqueue(encoder.encode(`${JSON.stringify(chunk)}
|
|
81
|
-
`));
|
|
82
|
-
}
|
|
83
|
-
controller.close();
|
|
84
|
-
} catch (error) {
|
|
85
|
-
if (abortController?.signal.aborted) {
|
|
86
|
-
controller.close();
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
controller.enqueue(
|
|
90
|
-
encoder.encode(
|
|
91
|
-
`${JSON.stringify({
|
|
92
|
-
type: "RUN_ERROR",
|
|
93
|
-
timestamp: Date.now(),
|
|
94
|
-
error: toRunErrorPayload(error)
|
|
95
|
-
})}
|
|
96
|
-
`
|
|
97
|
-
)
|
|
98
|
-
);
|
|
99
|
-
controller.close();
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
cancel() {
|
|
103
|
-
if (abortController) {
|
|
104
|
-
abortController.abort();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
function toHttpResponse(stream, init) {
|
|
110
|
-
return new Response(toHttpStream(stream, init?.abortController), {
|
|
111
|
-
...init
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
export {
|
|
115
|
-
streamToText,
|
|
116
|
-
toHttpResponse,
|
|
117
|
-
toHttpStream,
|
|
118
|
-
toServerSentEventsResponse,
|
|
119
|
-
toServerSentEventsStream
|
|
120
|
-
};
|
|
121
|
-
//# sourceMappingURL=stream-to-response.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-to-response.js","sources":["../../src/stream-to-response.ts"],"sourcesContent":["import { toRunErrorPayload } from './activities/error-payload'\nimport type { StreamChunk } from './types'\n\n/**\n * Collect all text content from a StreamChunk async iterable and return as a string.\n *\n * This function consumes the entire stream, accumulating content from TEXT_MESSAGE_CONTENT events,\n * and returns the final concatenated text.\n *\n * @param stream - AsyncIterable of StreamChunks from chat()\n * @returns Promise<string> - The accumulated text content\n *\n * @example\n * ```typescript\n * const stream = chat({\n * adapter: openaiText(),\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * const text = await streamToText(stream);\n * console.log(text); // \"Hello! How can I help you today?\"\n * ```\n */\nexport async function streamToText(\n stream: AsyncIterable<StreamChunk>,\n): Promise<string> {\n let accumulatedContent = ''\n\n for await (const chunk of stream) {\n if (chunk.type === 'TEXT_MESSAGE_CONTENT' && chunk.delta) {\n accumulatedContent += chunk.delta\n }\n }\n\n return accumulatedContent\n}\n\n/**\n * Convert a StreamChunk async iterable to a ReadableStream in Server-Sent Events format\n *\n * This creates a ReadableStream that emits chunks in SSE format:\n * - Each chunk is prefixed with \"data: \"\n * - Each chunk is followed by \"\\n\\n\"\n * - Stream ends when the underlying iterable is exhausted (RUN_FINISHED is the terminal event)\n *\n * @param stream - AsyncIterable of StreamChunks from chat()\n * @param abortController - Optional AbortController to abort when stream is cancelled\n * @returns ReadableStream in Server-Sent Events format\n */\nexport function toServerSentEventsStream(\n stream: AsyncIterable<StreamChunk>,\n abortController?: AbortController,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder()\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const chunk of stream) {\n // Check if stream was cancelled/aborted\n if (abortController?.signal.aborted) {\n break\n }\n\n // Send each chunk as Server-Sent Events format\n controller.enqueue(\n encoder.encode(`data: ${JSON.stringify(chunk)}\\n\\n`),\n )\n }\n\n controller.close()\n } catch (error: unknown) {\n // Don't send error if aborted\n if (abortController?.signal.aborted) {\n controller.close()\n return\n }\n\n // Send error event (AG-UI RUN_ERROR)\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: 'RUN_ERROR',\n timestamp: Date.now(),\n error: toRunErrorPayload(error),\n })}\\n\\n`,\n ),\n )\n controller.close()\n }\n },\n cancel() {\n // When the ReadableStream is cancelled (e.g., client disconnects),\n // abort the underlying stream\n if (abortController) {\n abortController.abort()\n }\n },\n })\n}\n\n/**\n * Convert a StreamChunk async iterable to a Response in Server-Sent Events format\n *\n * This creates a Response that emits chunks in SSE format:\n * - Each chunk is prefixed with \"data: \"\n * - Each chunk is followed by \"\\n\\n\"\n * - Stream ends when the underlying iterable is exhausted (RUN_FINISHED is the terminal event)\n *\n * @param stream - AsyncIterable of StreamChunks from chat()\n * @param init - Optional Response initialization options (including `abortController`)\n * @returns Response in Server-Sent Events format\n *\n * @example\n * ```typescript\n * const stream = chat({ adapter: openaiText(), model: \"gpt-4o\", messages: [...] });\n * return toServerSentEventsResponse(stream, { abortController });\n * ```\n */\nexport function toServerSentEventsResponse(\n stream: AsyncIterable<StreamChunk>,\n init?: ResponseInit & { abortController?: AbortController },\n): Response {\n const { headers, abortController, ...responseInit } = init ?? {}\n\n // Start with default SSE headers\n const mergedHeaders = new Headers({\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n })\n\n // Override with user headers if provided, handling all HeadersInit forms:\n // Headers instance, string[][], or plain object\n if (headers) {\n const userHeaders = new Headers(headers)\n userHeaders.forEach((value, key) => {\n mergedHeaders.set(key, value)\n })\n }\n\n return new Response(toServerSentEventsStream(stream, abortController), {\n ...responseInit,\n headers: mergedHeaders,\n })\n}\n\n/**\n * Convert a StreamChunk async iterable to a ReadableStream in HTTP stream format (newline-delimited JSON)\n *\n * This creates a ReadableStream that emits chunks as newline-delimited JSON:\n * - Each chunk is JSON.stringify'd and followed by \"\\n\"\n * - No SSE formatting (no \"data: \" prefix)\n *\n * This format is compatible with `fetchHttpStream` connection adapter.\n *\n * @param stream - AsyncIterable of StreamChunks from chat()\n * @param abortController - Optional AbortController to abort when stream is cancelled\n * @returns ReadableStream in HTTP stream format (newline-delimited JSON)\n *\n * @example\n * ```typescript\n * const stream = chat({ adapter: openaiText(), model: \"gpt-4o\", messages: [...] });\n * const readableStream = toHttpStream(stream);\n * // Use with Response for HTTP streaming (not SSE)\n * return new Response(readableStream, {\n * headers: { 'Content-Type': 'application/x-ndjson' }\n * });\n * ```\n */\nexport function toHttpStream(\n stream: AsyncIterable<StreamChunk>,\n abortController?: AbortController,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder()\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const chunk of stream) {\n // Check if stream was cancelled/aborted\n if (abortController?.signal.aborted) {\n break\n }\n\n // Send each chunk as newline-delimited JSON\n controller.enqueue(encoder.encode(`${JSON.stringify(chunk)}\\n`))\n }\n\n controller.close()\n } catch (error: unknown) {\n // Don't send error if aborted\n if (abortController?.signal.aborted) {\n controller.close()\n return\n }\n\n // Send error event (AG-UI RUN_ERROR)\n controller.enqueue(\n encoder.encode(\n `${JSON.stringify({\n type: 'RUN_ERROR',\n timestamp: Date.now(),\n error: toRunErrorPayload(error),\n })}\\n`,\n ),\n )\n controller.close()\n }\n },\n cancel() {\n // When the ReadableStream is cancelled (e.g., client disconnects),\n // abort the underlying stream\n if (abortController) {\n abortController.abort()\n }\n },\n })\n}\n\n/**\n * Convert a StreamChunk async iterable to a Response in HTTP stream format (newline-delimited JSON)\n *\n * This creates a Response that emits chunks in HTTP stream format:\n * - Each chunk is JSON.stringify'd and followed by \"\\n\"\n * - No SSE formatting (no \"data: \" prefix)\n *\n * This format is compatible with `fetchHttpStream` connection adapter.\n *\n * @param stream - AsyncIterable of StreamChunks from chat()\n * @param init - Optional Response initialization options (including `abortController`)\n * @returns Response in HTTP stream format (newline-delimited JSON)\n *\n * @example\n * ```typescript\n * const stream = chat({ adapter: openaiText(), model: \"gpt-4o\", messages: [...] });\n * return toHttpResponse(stream, { abortController });\n * ```\n */\nexport function toHttpResponse(\n stream: AsyncIterable<StreamChunk>,\n init?: ResponseInit & { abortController?: AbortController },\n): Response {\n return new Response(toHttpStream(stream, init?.abortController), {\n ...init,\n })\n}\n"],"names":[],"mappings":";AAuBA,eAAsB,aACpB,QACiB;AACjB,MAAI,qBAAqB;AAEzB,mBAAiB,SAAS,QAAQ;AAChC,QAAI,MAAM,SAAS,0BAA0B,MAAM,OAAO;AACxD,4BAAsB,MAAM;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;AAcO,SAAS,yBACd,QACA,iBAC4B;AAC5B,QAAM,UAAU,IAAI,YAAA;AAEpB,SAAO,IAAI,eAAe;AAAA,IACxB,MAAM,MAAM,YAAY;AACtB,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAEhC,cAAI,iBAAiB,OAAO,SAAS;AACnC;AAAA,UACF;AAGA,qBAAW;AAAA,YACT,QAAQ,OAAO,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA,CAAM;AAAA,UAAA;AAAA,QAEvD;AAEA,mBAAW,MAAA;AAAA,MACb,SAAS,OAAgB;AAEvB,YAAI,iBAAiB,OAAO,SAAS;AACnC,qBAAW,MAAA;AACX;AAAA,QACF;AAGA,mBAAW;AAAA,UACT,QAAQ;AAAA,YACN,SAAS,KAAK,UAAU;AAAA,cACtB,MAAM;AAAA,cACN,WAAW,KAAK,IAAA;AAAA,cAChB,OAAO,kBAAkB,KAAK;AAAA,YAAA,CAC/B,CAAC;AAAA;AAAA;AAAA,UAAA;AAAA,QACJ;AAEF,mBAAW,MAAA;AAAA,MACb;AAAA,IACF;AAAA,IACA,SAAS;AAGP,UAAI,iBAAiB;AACnB,wBAAgB,MAAA;AAAA,MAClB;AAAA,IACF;AAAA,EAAA,CACD;AACH;AAoBO,SAAS,2BACd,QACA,MACU;AACV,QAAM,EAAE,SAAS,iBAAiB,GAAG,aAAA,IAAiB,QAAQ,CAAA;AAG9D,QAAM,gBAAgB,IAAI,QAAQ;AAAA,IAChC,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,YAAY;AAAA,EAAA,CACb;AAID,MAAI,SAAS;AACX,UAAM,cAAc,IAAI,QAAQ,OAAO;AACvC,gBAAY,QAAQ,CAAC,OAAO,QAAQ;AAClC,oBAAc,IAAI,KAAK,KAAK;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,SAAS,yBAAyB,QAAQ,eAAe,GAAG;AAAA,IACrE,GAAG;AAAA,IACH,SAAS;AAAA,EAAA,CACV;AACH;AAyBO,SAAS,aACd,QACA,iBAC4B;AAC5B,QAAM,UAAU,IAAI,YAAA;AAEpB,SAAO,IAAI,eAAe;AAAA,IACxB,MAAM,MAAM,YAAY;AACtB,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAEhC,cAAI,iBAAiB,OAAO,SAAS;AACnC;AAAA,UACF;AAGA,qBAAW,QAAQ,QAAQ,OAAO,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA,CAAI,CAAC;AAAA,QACjE;AAEA,mBAAW,MAAA;AAAA,MACb,SAAS,OAAgB;AAEvB,YAAI,iBAAiB,OAAO,SAAS;AACnC,qBAAW,MAAA;AACX;AAAA,QACF;AAGA,mBAAW;AAAA,UACT,QAAQ;AAAA,YACN,GAAG,KAAK,UAAU;AAAA,cAChB,MAAM;AAAA,cACN,WAAW,KAAK,IAAA;AAAA,cAChB,OAAO,kBAAkB,KAAK;AAAA,YAAA,CAC/B,CAAC;AAAA;AAAA,UAAA;AAAA,QACJ;AAEF,mBAAW,MAAA;AAAA,MACb;AAAA,IACF;AAAA,IACA,SAAS;AAGP,UAAI,iBAAiB;AACnB,wBAAgB,MAAA;AAAA,MAClB;AAAA,IACF;AAAA,EAAA,CACD;AACH;AAqBO,SAAS,eACd,QACA,MACU;AACV,SAAO,IAAI,SAAS,aAAa,QAAQ,MAAM,eAAe,GAAG;AAAA,IAC/D,GAAG;AAAA,EAAA,CACJ;AACH;"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { ChatMiddleware } from './activities/chat/middleware/types.js';
|
|
2
|
-
import { StreamChunk } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Strip only the deprecated nested `error` object from RUN_ERROR events.
|
|
5
|
-
* The flat `message`/`code` fields are the spec-compliant form.
|
|
6
|
-
*
|
|
7
|
-
* All other fields pass through unchanged. @ag-ui/core's BaseEventSchema
|
|
8
|
-
* uses `.passthrough()`, so extra fields (model, content, usage,
|
|
9
|
-
* finishReason, toolName, stepId, etc.) are allowed and won't break
|
|
10
|
-
* spec validation or verifyEvents.
|
|
11
|
-
*/
|
|
12
|
-
export declare function stripToSpec(chunk: StreamChunk): StreamChunk;
|
|
13
|
-
/**
|
|
14
|
-
* Middleware that ensures events are AG-UI spec compliant.
|
|
15
|
-
* Currently only strips the deprecated nested `error` object from RUN_ERROR.
|
|
16
|
-
* All other fields pass through unchanged (passthrough allowed by spec).
|
|
17
|
-
*/
|
|
18
|
-
export declare function stripToSpecMiddleware(): ChatMiddleware;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
function stripToSpec(chunk) {
|
|
2
|
-
if (chunk.type === "RUN_ERROR" && "error" in chunk) {
|
|
3
|
-
const { error: _deprecated, ...rest } = chunk;
|
|
4
|
-
return rest;
|
|
5
|
-
}
|
|
6
|
-
return chunk;
|
|
7
|
-
}
|
|
8
|
-
function stripToSpecMiddleware() {
|
|
9
|
-
return {
|
|
10
|
-
name: "strip-to-spec",
|
|
11
|
-
onChunk(_ctx, chunk) {
|
|
12
|
-
return stripToSpec(chunk);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
export {
|
|
17
|
-
stripToSpec,
|
|
18
|
-
stripToSpecMiddleware
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=strip-to-spec-middleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"strip-to-spec-middleware.js","sources":["../../src/strip-to-spec-middleware.ts"],"sourcesContent":["import type { ChatMiddleware } from './activities/chat/middleware/types'\nimport type { StreamChunk } from './types'\n\n/**\n * Strip only the deprecated nested `error` object from RUN_ERROR events.\n * The flat `message`/`code` fields are the spec-compliant form.\n *\n * All other fields pass through unchanged. @ag-ui/core's BaseEventSchema\n * uses `.passthrough()`, so extra fields (model, content, usage,\n * finishReason, toolName, stepId, etc.) are allowed and won't break\n * spec validation or verifyEvents.\n */\nexport function stripToSpec(chunk: StreamChunk): StreamChunk {\n // Only strip the deprecated nested error object from RUN_ERROR\n if (chunk.type === 'RUN_ERROR' && 'error' in chunk) {\n const { error: _deprecated, ...rest } = chunk as Record<string, unknown>\n return rest as StreamChunk\n }\n return chunk\n}\n\n/**\n * Middleware that ensures events are AG-UI spec compliant.\n * Currently only strips the deprecated nested `error` object from RUN_ERROR.\n * All other fields pass through unchanged (passthrough allowed by spec).\n */\nexport function stripToSpecMiddleware(): ChatMiddleware {\n return {\n name: 'strip-to-spec',\n onChunk(_ctx, chunk) {\n return stripToSpec(chunk)\n },\n }\n}\n"],"names":[],"mappings":"AAYO,SAAS,YAAY,OAAiC;AAE3D,MAAI,MAAM,SAAS,eAAe,WAAW,OAAO;AAClD,UAAM,EAAE,OAAO,aAAa,GAAG,SAAS;AACxC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOO,SAAS,wBAAwC;AACtD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MAAM,OAAO;AACnB,aAAO,YAAY,KAAK;AAAA,IAC1B;AAAA,EAAA;AAEJ;"}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A single entry in `chat({ systemPrompts: [...] })`.
|
|
3
|
-
*
|
|
4
|
-
* Accepts a plain string (the common case) or a structured object that lets
|
|
5
|
-
* providers attach typed metadata to the prompt — e.g. Anthropic
|
|
6
|
-
* `cache_control` for prompt caching, future per-prompt safety overrides for
|
|
7
|
-
* Gemini, etc.
|
|
8
|
-
*
|
|
9
|
-
* At the chat call site, `metadata` is narrowed by the adapter via
|
|
10
|
-
* `~types['systemPromptMetadata']`. Providers that don't declare one inherit
|
|
11
|
-
* the default `never`, which makes the field carry no meaningful value: TS
|
|
12
|
-
* only accepts `undefined` there, and provider-foreign metadata that reaches
|
|
13
|
-
* an adapter via JS / `as any` is silently dropped, never written to the
|
|
14
|
-
* wire. For type-safe per-provider metadata, refer to the provider's
|
|
15
|
-
* `<Provider>SystemPromptMetadata` interface (e.g. `AnthropicSystemPromptMetadata`).
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* // The 90% case — plain strings work everywhere.
|
|
19
|
-
* systemPrompts: ['Be concise.', 'Cite sources.']
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* // Provider-specific metadata via the object form. No `satisfies` cast
|
|
23
|
-
* // is needed — the adapter narrows the `metadata` field's type at the
|
|
24
|
-
* // call site so users get autocomplete and structural checking
|
|
25
|
-
* // automatically.
|
|
26
|
-
* import { anthropicText } from '@tanstack/ai-anthropic'
|
|
27
|
-
*
|
|
28
|
-
* chat({
|
|
29
|
-
* adapter: anthropicText(),
|
|
30
|
-
* systemPrompts: [
|
|
31
|
-
* {
|
|
32
|
-
* content: 'Stable instructions — cache me.',
|
|
33
|
-
* metadata: { cache_control: { type: 'ephemeral' } },
|
|
34
|
-
* },
|
|
35
|
-
* 'Volatile per-request instruction.',
|
|
36
|
-
* ],
|
|
37
|
-
* })
|
|
38
|
-
*/
|
|
39
|
-
export type SystemPrompt<TMetadata = unknown> = string | {
|
|
40
|
-
content: string;
|
|
41
|
-
metadata?: TMetadata;
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* Normalised shape adapters see after the chat layer turns string entries
|
|
45
|
-
* into `{ content }` objects. Adapters call `normalizeSystemPrompts` once at
|
|
46
|
-
* the top of their option-mapping pipeline so the rest of the code only has
|
|
47
|
-
* to handle one shape.
|
|
48
|
-
*/
|
|
49
|
-
export interface NormalizedSystemPrompt<TMetadata = unknown> {
|
|
50
|
-
content: string;
|
|
51
|
-
metadata?: TMetadata;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Normalise the public `systemPrompts` shape (`Array<string | { content, metadata? }>`)
|
|
55
|
-
* to a homogenous `Array<{ content, metadata? }>`. Adapters use this so they
|
|
56
|
-
* don't have to type-narrow string vs object inline.
|
|
57
|
-
*
|
|
58
|
-
* Returns an empty array (never `undefined`) so callers can chain `.map` /
|
|
59
|
-
* `.join` without an extra null check.
|
|
60
|
-
*
|
|
61
|
-
* Throws a `TypeError` (naming the offending index) if an object-form entry's
|
|
62
|
-
* `content` isn't a string. Public API boundary — callers reaching this
|
|
63
|
-
* function through `as any` / external JS would otherwise stream a literal
|
|
64
|
-
* `"undefined"` into the model's system prompt with no signal.
|
|
65
|
-
*/
|
|
66
|
-
export declare function normalizeSystemPrompts<TMetadata = unknown>(prompts: ReadonlyArray<SystemPrompt> | undefined): Array<NormalizedSystemPrompt<TMetadata>>;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
function normalizeSystemPrompts(prompts) {
|
|
2
|
-
if (!prompts || prompts.length === 0) return [];
|
|
3
|
-
return prompts.map((p, i) => {
|
|
4
|
-
if (typeof p === "string") return { content: p };
|
|
5
|
-
const candidate = p;
|
|
6
|
-
if (candidate === null || typeof candidate !== "object") {
|
|
7
|
-
throw new TypeError(
|
|
8
|
-
`systemPrompts[${i}]: expected a string or { content, metadata? }, got ${candidate === null ? "null" : typeof candidate}`
|
|
9
|
-
);
|
|
10
|
-
}
|
|
11
|
-
const { content } = candidate;
|
|
12
|
-
if (typeof content !== "string") {
|
|
13
|
-
throw new TypeError(
|
|
14
|
-
`systemPrompts[${i}]: content must be a string, got ${typeof content}`
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
return p;
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
export {
|
|
21
|
-
normalizeSystemPrompts
|
|
22
|
-
};
|
|
23
|
-
//# sourceMappingURL=system-prompts.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompts.js","sources":["../../src/system-prompts.ts"],"sourcesContent":["/**\n * A single entry in `chat({ systemPrompts: [...] })`.\n *\n * Accepts a plain string (the common case) or a structured object that lets\n * providers attach typed metadata to the prompt — e.g. Anthropic\n * `cache_control` for prompt caching, future per-prompt safety overrides for\n * Gemini, etc.\n *\n * At the chat call site, `metadata` is narrowed by the adapter via\n * `~types['systemPromptMetadata']`. Providers that don't declare one inherit\n * the default `never`, which makes the field carry no meaningful value: TS\n * only accepts `undefined` there, and provider-foreign metadata that reaches\n * an adapter via JS / `as any` is silently dropped, never written to the\n * wire. For type-safe per-provider metadata, refer to the provider's\n * `<Provider>SystemPromptMetadata` interface (e.g. `AnthropicSystemPromptMetadata`).\n *\n * @example\n * // The 90% case — plain strings work everywhere.\n * systemPrompts: ['Be concise.', 'Cite sources.']\n *\n * @example\n * // Provider-specific metadata via the object form. No `satisfies` cast\n * // is needed — the adapter narrows the `metadata` field's type at the\n * // call site so users get autocomplete and structural checking\n * // automatically.\n * import { anthropicText } from '@tanstack/ai-anthropic'\n *\n * chat({\n * adapter: anthropicText(),\n * systemPrompts: [\n * {\n * content: 'Stable instructions — cache me.',\n * metadata: { cache_control: { type: 'ephemeral' } },\n * },\n * 'Volatile per-request instruction.',\n * ],\n * })\n */\nexport type SystemPrompt<TMetadata = unknown> =\n | string\n | {\n content: string\n metadata?: TMetadata\n }\n\n/**\n * Normalised shape adapters see after the chat layer turns string entries\n * into `{ content }` objects. Adapters call `normalizeSystemPrompts` once at\n * the top of their option-mapping pipeline so the rest of the code only has\n * to handle one shape.\n */\nexport interface NormalizedSystemPrompt<TMetadata = unknown> {\n content: string\n metadata?: TMetadata\n}\n\n/**\n * Normalise the public `systemPrompts` shape (`Array<string | { content, metadata? }>`)\n * to a homogenous `Array<{ content, metadata? }>`. Adapters use this so they\n * don't have to type-narrow string vs object inline.\n *\n * Returns an empty array (never `undefined`) so callers can chain `.map` /\n * `.join` without an extra null check.\n *\n * Throws a `TypeError` (naming the offending index) if an object-form entry's\n * `content` isn't a string. Public API boundary — callers reaching this\n * function through `as any` / external JS would otherwise stream a literal\n * `\"undefined\"` into the model's system prompt with no signal.\n */\nexport function normalizeSystemPrompts<TMetadata = unknown>(\n // Accept the wide public shape (`SystemPrompt<unknown>`) regardless of the\n // caller's `TMetadata`. Adapters know their own metadata shape; the\n // generic narrows the *output* so adapter code can read `p.metadata.X`\n // without an additional cast.\n prompts: ReadonlyArray<SystemPrompt> | undefined,\n): Array<NormalizedSystemPrompt<TMetadata>> {\n if (!prompts || prompts.length === 0) return []\n return prompts.map((p, i) => {\n if (typeof p === 'string') return { content: p }\n // Defence in depth: TypeScript narrows `p` to the object arm here, but\n // this function is a public API boundary that callers can reach via\n // plain JS or `as any`. Re-validate at runtime so we never stream a\n // literal `\"undefined\"` into the model.\n const candidate = p as unknown\n if (candidate === null || typeof candidate !== 'object') {\n throw new TypeError(\n `systemPrompts[${i}]: expected a string or { content, metadata? }, got ${candidate === null ? 'null' : typeof candidate}`,\n )\n }\n const { content } = candidate as { content?: unknown }\n if (typeof content !== 'string') {\n throw new TypeError(\n `systemPrompts[${i}]: content must be a string, got ${typeof content}`,\n )\n }\n return p as NormalizedSystemPrompt<TMetadata>\n })\n}\n"],"names":[],"mappings":"AAqEO,SAAS,uBAKd,SAC0C;AAC1C,MAAI,CAAC,WAAW,QAAQ,WAAW,UAAU,CAAA;AAC7C,SAAO,QAAQ,IAAI,CAAC,GAAG,MAAM;AAC3B,QAAI,OAAO,MAAM,SAAU,QAAO,EAAE,SAAS,EAAA;AAK7C,UAAM,YAAY;AAClB,QAAI,cAAc,QAAQ,OAAO,cAAc,UAAU;AACvD,YAAM,IAAI;AAAA,QACR,iBAAiB,CAAC,uDAAuD,cAAc,OAAO,SAAS,OAAO,SAAS;AAAA,MAAA;AAAA,IAE3H;AACA,UAAM,EAAE,YAAY;AACpB,QAAI,OAAO,YAAY,UAAU;AAC/B,YAAM,IAAI;AAAA,QACR,iBAAiB,CAAC,oCAAoC,OAAO,OAAO;AAAA,MAAA;AAAA,IAExE;AACA,WAAO;AAAA,EACT,CAAC;AACH;"}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { AnyTool } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* A registry that holds tools and allows dynamic tool management.
|
|
4
|
-
*
|
|
5
|
-
* The registry can be either mutable (allowing additions/removals during execution)
|
|
6
|
-
* or frozen (static tool list, for backward compatibility with tools arrays).
|
|
7
|
-
*/
|
|
8
|
-
export interface ToolRegistry<TTool extends AnyTool = AnyTool> {
|
|
9
|
-
/**
|
|
10
|
-
* Get all current tools in the registry.
|
|
11
|
-
* Called each agent loop iteration to get the latest tool list.
|
|
12
|
-
*/
|
|
13
|
-
getTools: () => Array<TTool>;
|
|
14
|
-
/**
|
|
15
|
-
* Add a tool to the registry dynamically.
|
|
16
|
-
* For frozen registries, this is a no-op.
|
|
17
|
-
*
|
|
18
|
-
* @param tool - The tool to add
|
|
19
|
-
*/
|
|
20
|
-
add: (tool: TTool) => void;
|
|
21
|
-
/**
|
|
22
|
-
* Remove a tool from the registry by name.
|
|
23
|
-
* For frozen registries, this always returns false.
|
|
24
|
-
*
|
|
25
|
-
* @param name - The name of the tool to remove
|
|
26
|
-
* @returns true if the tool was removed, false if not found or frozen
|
|
27
|
-
*/
|
|
28
|
-
remove: (name: string) => boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Check if a tool exists in the registry.
|
|
31
|
-
*
|
|
32
|
-
* @param name - The name of the tool to check
|
|
33
|
-
*/
|
|
34
|
-
has: (name: string) => boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Get a tool by name.
|
|
37
|
-
*
|
|
38
|
-
* @param name - The name of the tool to get
|
|
39
|
-
* @returns The tool if found, undefined otherwise
|
|
40
|
-
*/
|
|
41
|
-
get: (name: string) => TTool | undefined;
|
|
42
|
-
/**
|
|
43
|
-
* Whether this registry is frozen (immutable).
|
|
44
|
-
* Frozen registries don't allow add/remove operations.
|
|
45
|
-
*/
|
|
46
|
-
readonly isFrozen: boolean;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Create a mutable tool registry for dynamic tool scenarios.
|
|
50
|
-
*
|
|
51
|
-
* Tools can be added and removed during chat execution, and the
|
|
52
|
-
* changes will be reflected in subsequent agent loop iterations.
|
|
53
|
-
*
|
|
54
|
-
* @param initialTools - Optional initial set of tools
|
|
55
|
-
* @returns A mutable ToolRegistry
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```typescript
|
|
59
|
-
* const registry = createToolRegistry([toolA, toolB])
|
|
60
|
-
*
|
|
61
|
-
* const stream = chat({
|
|
62
|
-
* adapter,
|
|
63
|
-
* messages,
|
|
64
|
-
* toolRegistry: registry,
|
|
65
|
-
* })
|
|
66
|
-
*
|
|
67
|
-
* // Later, during tool execution:
|
|
68
|
-
* registry.add(newTool) // Immediately available to LLM
|
|
69
|
-
* ```
|
|
70
|
-
*/
|
|
71
|
-
export declare function createToolRegistry<TTool extends AnyTool = AnyTool>(initialTools?: Array<TTool>): ToolRegistry<TTool>;
|
|
72
|
-
/**
|
|
73
|
-
* Create a frozen (immutable) tool registry from a tools array.
|
|
74
|
-
*
|
|
75
|
-
* This is used internally to wrap static `tools` arrays for backward compatibility.
|
|
76
|
-
* Add and remove operations are no-ops on frozen registries.
|
|
77
|
-
*
|
|
78
|
-
* @param tools - The static array of tools
|
|
79
|
-
* @returns A frozen ToolRegistry
|
|
80
|
-
*/
|
|
81
|
-
export declare function createFrozenRegistry<TTool extends AnyTool = AnyTool>(tools?: Array<TTool>): ToolRegistry<TTool>;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
function createToolRegistry(initialTools = []) {
|
|
2
|
-
const tools = /* @__PURE__ */ new Map();
|
|
3
|
-
for (const tool of initialTools) {
|
|
4
|
-
tools.set(tool.name, tool);
|
|
5
|
-
}
|
|
6
|
-
return {
|
|
7
|
-
getTools: () => Array.from(tools.values()),
|
|
8
|
-
add: (tool) => {
|
|
9
|
-
tools.set(tool.name, tool);
|
|
10
|
-
},
|
|
11
|
-
remove: (name) => {
|
|
12
|
-
return tools.delete(name);
|
|
13
|
-
},
|
|
14
|
-
has: (name) => {
|
|
15
|
-
return tools.has(name);
|
|
16
|
-
},
|
|
17
|
-
get: (name) => {
|
|
18
|
-
return tools.get(name);
|
|
19
|
-
},
|
|
20
|
-
isFrozen: false
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function createFrozenRegistry(tools = []) {
|
|
24
|
-
const toolMap = /* @__PURE__ */ new Map();
|
|
25
|
-
for (const tool of tools) {
|
|
26
|
-
toolMap.set(tool.name, tool);
|
|
27
|
-
}
|
|
28
|
-
const frozenTools = Object.freeze([...tools]);
|
|
29
|
-
return {
|
|
30
|
-
getTools: () => [...frozenTools],
|
|
31
|
-
add: (_tool) => {
|
|
32
|
-
},
|
|
33
|
-
remove: (_name) => {
|
|
34
|
-
return false;
|
|
35
|
-
},
|
|
36
|
-
has: (name) => {
|
|
37
|
-
return toolMap.has(name);
|
|
38
|
-
},
|
|
39
|
-
get: (name) => {
|
|
40
|
-
return toolMap.get(name);
|
|
41
|
-
},
|
|
42
|
-
isFrozen: true
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
export {
|
|
46
|
-
createFrozenRegistry,
|
|
47
|
-
createToolRegistry
|
|
48
|
-
};
|
|
49
|
-
//# sourceMappingURL=tool-registry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-registry.js","sources":["../../src/tool-registry.ts"],"sourcesContent":["import type { AnyTool } from './types'\n\n/**\n * A registry that holds tools and allows dynamic tool management.\n *\n * The registry can be either mutable (allowing additions/removals during execution)\n * or frozen (static tool list, for backward compatibility with tools arrays).\n */\nexport interface ToolRegistry<TTool extends AnyTool = AnyTool> {\n /**\n * Get all current tools in the registry.\n * Called each agent loop iteration to get the latest tool list.\n */\n getTools: () => Array<TTool>\n\n /**\n * Add a tool to the registry dynamically.\n * For frozen registries, this is a no-op.\n *\n * @param tool - The tool to add\n */\n add: (tool: TTool) => void\n\n /**\n * Remove a tool from the registry by name.\n * For frozen registries, this always returns false.\n *\n * @param name - The name of the tool to remove\n * @returns true if the tool was removed, false if not found or frozen\n */\n remove: (name: string) => boolean\n\n /**\n * Check if a tool exists in the registry.\n *\n * @param name - The name of the tool to check\n */\n has: (name: string) => boolean\n\n /**\n * Get a tool by name.\n *\n * @param name - The name of the tool to get\n * @returns The tool if found, undefined otherwise\n */\n get: (name: string) => TTool | undefined\n\n /**\n * Whether this registry is frozen (immutable).\n * Frozen registries don't allow add/remove operations.\n */\n readonly isFrozen: boolean\n}\n\n/**\n * Create a mutable tool registry for dynamic tool scenarios.\n *\n * Tools can be added and removed during chat execution, and the\n * changes will be reflected in subsequent agent loop iterations.\n *\n * @param initialTools - Optional initial set of tools\n * @returns A mutable ToolRegistry\n *\n * @example\n * ```typescript\n * const registry = createToolRegistry([toolA, toolB])\n *\n * const stream = chat({\n * adapter,\n * messages,\n * toolRegistry: registry,\n * })\n *\n * // Later, during tool execution:\n * registry.add(newTool) // Immediately available to LLM\n * ```\n */\nexport function createToolRegistry<TTool extends AnyTool = AnyTool>(\n initialTools: Array<TTool> = [],\n): ToolRegistry<TTool> {\n const tools = new Map<string, TTool>()\n\n for (const tool of initialTools) {\n tools.set(tool.name, tool)\n }\n\n return {\n getTools: () => Array.from(tools.values()),\n\n add: (tool: TTool) => {\n tools.set(tool.name, tool)\n },\n\n remove: (name: string) => {\n return tools.delete(name)\n },\n\n has: (name: string) => {\n return tools.has(name)\n },\n\n get: (name: string) => {\n return tools.get(name)\n },\n\n isFrozen: false,\n }\n}\n\n/**\n * Create a frozen (immutable) tool registry from a tools array.\n *\n * This is used internally to wrap static `tools` arrays for backward compatibility.\n * Add and remove operations are no-ops on frozen registries.\n *\n * @param tools - The static array of tools\n * @returns A frozen ToolRegistry\n */\nexport function createFrozenRegistry<TTool extends AnyTool = AnyTool>(\n tools: Array<TTool> = [],\n): ToolRegistry<TTool> {\n const toolMap = new Map<string, TTool>()\n\n for (const tool of tools) {\n toolMap.set(tool.name, tool)\n }\n\n const frozenTools = Object.freeze([...tools])\n\n return {\n getTools: () => [...frozenTools],\n\n add: (_tool: TTool) => {\n // No-op for frozen registry\n },\n\n remove: (_name: string) => {\n // No-op for frozen registry\n return false\n },\n\n has: (name: string) => {\n return toolMap.has(name)\n },\n\n get: (name: string) => {\n return toolMap.get(name)\n },\n\n isFrozen: true,\n }\n}\n"],"names":[],"mappings":"AA6EO,SAAS,mBACd,eAA6B,IACR;AACrB,QAAM,4BAAY,IAAA;AAElB,aAAW,QAAQ,cAAc;AAC/B,UAAM,IAAI,KAAK,MAAM,IAAI;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL,UAAU,MAAM,MAAM,KAAK,MAAM,QAAQ;AAAA,IAEzC,KAAK,CAAC,SAAgB;AACpB,YAAM,IAAI,KAAK,MAAM,IAAI;AAAA,IAC3B;AAAA,IAEA,QAAQ,CAAC,SAAiB;AACxB,aAAO,MAAM,OAAO,IAAI;AAAA,IAC1B;AAAA,IAEA,KAAK,CAAC,SAAiB;AACrB,aAAO,MAAM,IAAI,IAAI;AAAA,IACvB;AAAA,IAEA,KAAK,CAAC,SAAiB;AACrB,aAAO,MAAM,IAAI,IAAI;AAAA,IACvB;AAAA,IAEA,UAAU;AAAA,EAAA;AAEd;AAWO,SAAS,qBACd,QAAsB,IACD;AACrB,QAAM,8BAAc,IAAA;AAEpB,aAAW,QAAQ,OAAO;AACxB,YAAQ,IAAI,KAAK,MAAM,IAAI;AAAA,EAC7B;AAEA,QAAM,cAAc,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC;AAE5C,SAAO;AAAA,IACL,UAAU,MAAM,CAAC,GAAG,WAAW;AAAA,IAE/B,KAAK,CAAC,UAAiB;AAAA,IAEvB;AAAA,IAEA,QAAQ,CAAC,UAAkB;AAEzB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,CAAC,SAAiB;AACrB,aAAO,QAAQ,IAAI,IAAI;AAAA,IACzB;AAAA,IAEA,KAAK,CAAC,SAAiB;AACrB,aAAO,QAAQ,IAAI,IAAI;AAAA,IACzB;AAAA,IAEA,UAAU;AAAA,EAAA;AAEd;"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { Tool } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* A provider-specific tool produced by an adapter-package factory
|
|
4
|
-
* (e.g. `webSearchTool` from `@tanstack/ai-anthropic/tools`).
|
|
5
|
-
*
|
|
6
|
-
* The two `~`-prefixed fields are type-only phantom brands — they are never
|
|
7
|
-
* assigned at runtime. They allow the core type system to match a factory's
|
|
8
|
-
* output against the selected model's `supports.tools` list and surface a
|
|
9
|
-
* compile-time error when the combination is unsupported.
|
|
10
|
-
*
|
|
11
|
-
* User-defined tools (via `toolDefinition()`) remain plain `Tool` and stay
|
|
12
|
-
* assignable to any model.
|
|
13
|
-
*
|
|
14
|
-
* @template TProvider - Provider identifier (e.g. `'anthropic'`, `'openai'`).
|
|
15
|
-
* @template TKind - Canonical tool-kind string matching the provider's
|
|
16
|
-
* `supports.tools` entries (e.g. `'web_search'`, `'code_execution'`).
|
|
17
|
-
*/
|
|
18
|
-
export interface ProviderTool<TProvider extends string, TKind extends string> extends Tool {
|
|
19
|
-
readonly '~provider': TProvider;
|
|
20
|
-
readonly '~toolKind': TKind;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Attach the `ProviderTool` phantom brand to a plain `Tool`-shaped object.
|
|
24
|
-
*
|
|
25
|
-
* The brand fields (`'~provider'`, `'~toolKind'`) exist only in the type
|
|
26
|
-
* system and are never assigned at runtime, so this is a single audited
|
|
27
|
-
* type-only assertion. Use it inside adapter `xxxTool()` factories instead
|
|
28
|
-
* of `as unknown as` — the cast collapses to one named site.
|
|
29
|
-
*/
|
|
30
|
-
export declare function brandProviderTool<T extends ProviderTool<string, string>>(tool: Omit<T, '~provider' | '~toolKind'>): T;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider-tool.js","sources":["../../../src/tools/provider-tool.ts"],"sourcesContent":["import type { Tool } from '../types'\n\n/**\n * A provider-specific tool produced by an adapter-package factory\n * (e.g. `webSearchTool` from `@tanstack/ai-anthropic/tools`).\n *\n * The two `~`-prefixed fields are type-only phantom brands — they are never\n * assigned at runtime. They allow the core type system to match a factory's\n * output against the selected model's `supports.tools` list and surface a\n * compile-time error when the combination is unsupported.\n *\n * User-defined tools (via `toolDefinition()`) remain plain `Tool` and stay\n * assignable to any model.\n *\n * @template TProvider - Provider identifier (e.g. `'anthropic'`, `'openai'`).\n * @template TKind - Canonical tool-kind string matching the provider's\n * `supports.tools` entries (e.g. `'web_search'`, `'code_execution'`).\n */\nexport interface ProviderTool<\n TProvider extends string,\n TKind extends string,\n> extends Tool {\n readonly '~provider': TProvider\n readonly '~toolKind': TKind\n}\n\n/**\n * Attach the `ProviderTool` phantom brand to a plain `Tool`-shaped object.\n *\n * The brand fields (`'~provider'`, `'~toolKind'`) exist only in the type\n * system and are never assigned at runtime, so this is a single audited\n * type-only assertion. Use it inside adapter `xxxTool()` factories instead\n * of `as unknown as` — the cast collapses to one named site.\n */\nexport function brandProviderTool<T extends ProviderTool<string, string>>(\n tool: Omit<T, '~provider' | '~toolKind'>,\n): T {\n return tool as T\n}\n"],"names":[],"mappings":"AAkCO,SAAS,kBACd,MACG;AACH,SAAO;AACT;"}
|