@tanstack/ai 0.16.0 → 0.18.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.
Files changed (63) hide show
  1. package/dist/esm/activities/chat/adapter.d.ts +14 -0
  2. package/dist/esm/activities/chat/adapter.js.map +1 -1
  3. package/dist/esm/activities/chat/index.d.ts +27 -8
  4. package/dist/esm/activities/chat/index.js +245 -14
  5. package/dist/esm/activities/chat/index.js.map +1 -1
  6. package/dist/esm/activities/chat/messages.js +26 -2
  7. package/dist/esm/activities/chat/messages.js.map +1 -1
  8. package/dist/esm/activities/chat/middleware/compose.js +1 -1
  9. package/dist/esm/activities/chat/middleware/compose.js.map +1 -1
  10. package/dist/esm/activities/chat/middleware/types.d.ts +12 -1
  11. package/dist/esm/activities/chat/tools/schema-converter.js +5 -0
  12. package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -1
  13. package/dist/esm/activities/error-payload.d.ts +0 -8
  14. package/dist/esm/activities/error-payload.js +20 -2
  15. package/dist/esm/activities/error-payload.js.map +1 -1
  16. package/dist/esm/activities/generateImage/adapter.d.ts +2 -2
  17. package/dist/esm/activities/generateImage/adapter.js.map +1 -1
  18. package/dist/esm/activities/generateVideo/adapter.d.ts +2 -2
  19. package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
  20. package/dist/esm/activities/index.d.ts +1 -0
  21. package/dist/esm/activities/index.js +2 -0
  22. package/dist/esm/activities/index.js.map +1 -1
  23. package/dist/esm/activities/stream-generation-result.js +0 -2
  24. package/dist/esm/activities/stream-generation-result.js.map +1 -1
  25. package/dist/esm/activities/summarize/adapter.d.ts +4 -4
  26. package/dist/esm/activities/summarize/adapter.js.map +1 -1
  27. package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +45 -0
  28. package/dist/esm/activities/summarize/chat-stream-summarize.js +148 -0
  29. package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -0
  30. package/dist/esm/activities/summarize/index.d.ts +1 -0
  31. package/dist/esm/activities/summarize/index.js +4 -2
  32. package/dist/esm/activities/summarize/index.js.map +1 -1
  33. package/dist/esm/index.d.ts +3 -0
  34. package/dist/esm/index.js +6 -0
  35. package/dist/esm/index.js.map +1 -1
  36. package/dist/esm/types.d.ts +123 -11
  37. package/dist/esm/utilities/ag-ui-wire.d.ts +44 -0
  38. package/dist/esm/utilities/ag-ui-wire.js +96 -0
  39. package/dist/esm/utilities/ag-ui-wire.js.map +1 -0
  40. package/dist/esm/utilities/chat-params.d.ts +80 -0
  41. package/dist/esm/utilities/chat-params.js +96 -0
  42. package/dist/esm/utilities/chat-params.js.map +1 -0
  43. package/package.json +3 -3
  44. package/skills/ai-core/ag-ui-protocol/SKILL.md +46 -3
  45. package/skills/ai-core/structured-outputs/SKILL.md +92 -1
  46. package/src/activities/chat/adapter.ts +17 -0
  47. package/src/activities/chat/index.ts +401 -35
  48. package/src/activities/chat/messages.ts +44 -4
  49. package/src/activities/chat/middleware/compose.ts +1 -1
  50. package/src/activities/chat/middleware/types.ts +12 -1
  51. package/src/activities/chat/tools/schema-converter.ts +14 -0
  52. package/src/activities/error-payload.ts +31 -2
  53. package/src/activities/generateImage/adapter.ts +8 -2
  54. package/src/activities/generateVideo/adapter.ts +8 -2
  55. package/src/activities/index.ts +5 -0
  56. package/src/activities/stream-generation-result.ts +4 -6
  57. package/src/activities/summarize/adapter.ts +8 -4
  58. package/src/activities/summarize/chat-stream-summarize.ts +238 -0
  59. package/src/activities/summarize/index.ts +12 -9
  60. package/src/index.ts +11 -0
  61. package/src/types.ts +146 -11
  62. package/src/utilities/ag-ui-wire.ts +182 -0
  63. package/src/utilities/chat-params.ts +199 -0
@@ -0,0 +1,148 @@
1
+ import { EventType } from "@ag-ui/core";
2
+ import { toRunErrorPayload } from "../error-payload.js";
3
+ import { BaseSummarizeAdapter } from "./adapter.js";
4
+ class ChatStreamSummarizeAdapter extends BaseSummarizeAdapter {
5
+ constructor(textAdapter, model, name = "chat-stream-summarize") {
6
+ super({}, model);
7
+ this.name = name;
8
+ this.textAdapter = textAdapter;
9
+ }
10
+ async summarize(options) {
11
+ const systemPrompt = this.buildSummarizationPrompt(options);
12
+ let summary = "";
13
+ const id = this.generateId();
14
+ let model = options.model;
15
+ let usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
16
+ options.logger.request(
17
+ `activity=summarize provider=${this.name} model=${options.model} text-length=${options.text.length} maxLength=${options.maxLength ?? "unset"}`,
18
+ { provider: this.name, model: options.model }
19
+ );
20
+ try {
21
+ for await (const chunk of this.textAdapter.chatStream(
22
+ this.buildTextOptions(options, systemPrompt)
23
+ )) {
24
+ if (chunk.type === "TEXT_MESSAGE_CONTENT") {
25
+ if (chunk.content) {
26
+ summary = chunk.content;
27
+ } else if (chunk.delta) {
28
+ summary += chunk.delta;
29
+ }
30
+ model = chunk.model || model;
31
+ }
32
+ if (chunk.type === "RUN_FINISHED") {
33
+ if (chunk.usage) {
34
+ usage = chunk.usage;
35
+ }
36
+ }
37
+ if (chunk.type === "RUN_ERROR") {
38
+ const message = (chunk.error && typeof chunk.error.message === "string" ? chunk.error.message : null) ?? "Summarization failed";
39
+ const code = chunk.error && typeof chunk.error.code === "string" ? chunk.error.code : void 0;
40
+ const err = new Error(message);
41
+ if (code) {
42
+ ;
43
+ err.code = code;
44
+ }
45
+ throw err;
46
+ }
47
+ }
48
+ } catch (error) {
49
+ options.logger.errors(`${this.name}.summarize fatal`, {
50
+ error: toRunErrorPayload(error, `${this.name}.summarize failed`),
51
+ source: `${this.name}.summarize`
52
+ });
53
+ throw error;
54
+ }
55
+ return { id, model, summary, usage };
56
+ }
57
+ async *summarizeStream(options) {
58
+ const systemPrompt = this.buildSummarizationPrompt(options);
59
+ options.logger.request(
60
+ `activity=summarizeStream provider=${this.name} model=${options.model} text-length=${options.text.length} maxLength=${options.maxLength ?? "unset"}`,
61
+ { provider: this.name, model: options.model }
62
+ );
63
+ const id = this.generateId();
64
+ let summary = "";
65
+ let model = options.model;
66
+ let usage = {
67
+ promptTokens: 0,
68
+ completionTokens: 0,
69
+ totalTokens: 0
70
+ };
71
+ try {
72
+ for await (const chunk of this.textAdapter.chatStream(
73
+ this.buildTextOptions(options, systemPrompt)
74
+ )) {
75
+ if (chunk.type === "TEXT_MESSAGE_CONTENT") {
76
+ if (chunk.content) {
77
+ summary = chunk.content;
78
+ } else if (chunk.delta) {
79
+ summary += chunk.delta;
80
+ }
81
+ if (chunk.model) model = chunk.model;
82
+ }
83
+ if (chunk.type === "RUN_FINISHED") {
84
+ if (chunk.usage) usage = chunk.usage;
85
+ if (chunk.model) model = chunk.model;
86
+ yield {
87
+ type: EventType.CUSTOM,
88
+ name: "generation:result",
89
+ value: { id, model, summary, usage },
90
+ model,
91
+ timestamp: Date.now()
92
+ };
93
+ }
94
+ yield chunk;
95
+ }
96
+ } catch (error) {
97
+ options.logger.errors(`${this.name}.summarizeStream fatal`, {
98
+ error: toRunErrorPayload(error, `${this.name}.summarizeStream failed`),
99
+ source: `${this.name}.summarizeStream`
100
+ });
101
+ throw error;
102
+ }
103
+ }
104
+ /**
105
+ * Build the TextOptions passed to the underlying chatStream. Provider
106
+ * `modelOptions` from the summarize call are forwarded as-is so knobs like
107
+ * Anthropic cache headers, Gemini safety settings, or Ollama tuning params
108
+ * still reach the wire layer.
109
+ */
110
+ buildTextOptions(options, systemPrompt) {
111
+ return {
112
+ model: options.model,
113
+ messages: [{ role: "user", content: options.text }],
114
+ systemPrompts: [systemPrompt],
115
+ maxTokens: options.maxLength,
116
+ temperature: 0.3,
117
+ modelOptions: options.modelOptions,
118
+ logger: options.logger
119
+ };
120
+ }
121
+ buildSummarizationPrompt(options) {
122
+ let prompt = "You are a professional summarizer. ";
123
+ switch (options.style) {
124
+ case "bullet-points":
125
+ prompt += "Provide a summary in bullet point format. ";
126
+ break;
127
+ case "paragraph":
128
+ prompt += "Provide a summary in paragraph format. ";
129
+ break;
130
+ case "concise":
131
+ prompt += "Provide a very concise summary in 1-2 sentences. ";
132
+ break;
133
+ default:
134
+ prompt += "Provide a clear and concise summary. ";
135
+ }
136
+ if (options.focus && options.focus.length > 0) {
137
+ prompt += `Focus on the following aspects: ${options.focus.join(", ")}. `;
138
+ }
139
+ if (options.maxLength) {
140
+ prompt += `Keep the summary under ${options.maxLength} tokens. `;
141
+ }
142
+ return prompt;
143
+ }
144
+ }
145
+ export {
146
+ ChatStreamSummarizeAdapter
147
+ };
148
+ //# sourceMappingURL=chat-stream-summarize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-stream-summarize.js","sources":["../../../../src/activities/summarize/chat-stream-summarize.ts"],"sourcesContent":["import { EventType } from '@ag-ui/core'\nimport { toRunErrorPayload } from '../error-payload'\nimport { BaseSummarizeAdapter } from './adapter'\nimport type {\n StreamChunk,\n SummarizationOptions,\n SummarizationResult,\n TextOptions,\n} from '../../types'\n\n/**\n * Minimal contract for a text adapter that supports `chatStream`. Lets\n * `ChatStreamSummarizeAdapter` work with any text adapter without coupling\n * to a specific implementation.\n *\n * The provider-options shape is intentionally `any` here — the wrapper only\n * forwards `modelOptions` straight through, so a text adapter with a richer\n * per-model options type (e.g. `ResolveProviderOptions<TModel>`) is still\n * acceptable. Summarize-level type safety is enforced via\n * `SummarizationOptions<TProviderOptions>` on the wrapper itself.\n */\nexport interface ChatStreamCapable {\n chatStream: (options: TextOptions<any>) => AsyncIterable<StreamChunk>\n}\n\n/**\n * Extract the per-model `modelOptions` type a text adapter accepts. Used by\n * provider summarize factories so their `modelOptions` IntelliSense matches\n * what the underlying text adapter actually understands.\n */\nexport type InferTextProviderOptions<TAdapter> = TAdapter extends {\n '~types': { providerOptions: infer P }\n}\n ? P extends object\n ? P\n : object\n : object\n\n/**\n * Summarize adapter that wraps any `ChatStreamCapable` text adapter and\n * prompts it for summarization. Not tied to any wire format.\n */\nexport class ChatStreamSummarizeAdapter<\n TModel extends string,\n TProviderOptions extends object = Record<string, unknown>,\n> extends BaseSummarizeAdapter<TModel, TProviderOptions> {\n readonly name: string\n\n private textAdapter: ChatStreamCapable\n\n constructor(\n textAdapter: ChatStreamCapable,\n model: TModel,\n name: string = 'chat-stream-summarize',\n ) {\n super({}, model)\n this.name = name\n this.textAdapter = textAdapter\n }\n\n async summarize(\n options: SummarizationOptions<TProviderOptions>,\n ): Promise<SummarizationResult> {\n const systemPrompt = this.buildSummarizationPrompt(options)\n\n let summary = ''\n const id = this.generateId()\n let model = options.model\n let usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 }\n\n options.logger.request(\n `activity=summarize provider=${this.name} model=${options.model} text-length=${options.text.length} maxLength=${options.maxLength ?? 'unset'}`,\n { provider: this.name, model: options.model },\n )\n\n try {\n for await (const chunk of this.textAdapter.chatStream(\n this.buildTextOptions(options, systemPrompt),\n )) {\n if (chunk.type === 'TEXT_MESSAGE_CONTENT') {\n if (chunk.content) {\n summary = chunk.content\n } else if (chunk.delta) {\n // Append delta only when present — a content-less chunk with no\n // delta would otherwise concat literal `'undefined'`.\n summary += chunk.delta\n }\n model = chunk.model || model\n }\n if (chunk.type === 'RUN_FINISHED') {\n if (chunk.usage) {\n usage = chunk.usage\n }\n }\n // Surface failures: the underlying chatStream emits RUN_ERROR instead\n // of throwing, so without this branch summarize() would return an\n // empty summary and pretend a failed run succeeded.\n if (chunk.type === 'RUN_ERROR') {\n const message =\n (chunk.error && typeof chunk.error.message === 'string'\n ? chunk.error.message\n : null) ?? 'Summarization failed'\n const code =\n chunk.error && typeof chunk.error.code === 'string'\n ? chunk.error.code\n : undefined\n const err = new Error(message)\n if (code) {\n ;(err as Error & { code?: string }).code = code\n }\n throw err\n }\n }\n } catch (error: unknown) {\n // Narrow before logging: raw SDK errors can carry request metadata\n // (including auth headers) which we must never surface to user loggers.\n options.logger.errors(`${this.name}.summarize fatal`, {\n error: toRunErrorPayload(error, `${this.name}.summarize failed`),\n source: `${this.name}.summarize`,\n })\n throw error\n }\n\n return { id, model, summary, usage }\n }\n\n async *summarizeStream(\n options: SummarizationOptions<TProviderOptions>,\n ): AsyncIterable<StreamChunk> {\n const systemPrompt = this.buildSummarizationPrompt(options)\n\n options.logger.request(\n `activity=summarizeStream provider=${this.name} model=${options.model} text-length=${options.text.length} maxLength=${options.maxLength ?? 'unset'}`,\n { provider: this.name, model: options.model },\n )\n\n const id = this.generateId()\n let summary = ''\n let model = options.model\n let usage: SummarizationResult['usage'] = {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n }\n\n try {\n for await (const chunk of this.textAdapter.chatStream(\n this.buildTextOptions(options, systemPrompt),\n )) {\n // Accumulate the same way `summarize()` does so consumers see deltas\n // AND the terminal `generation:result` event below carries the same\n // final summary that non-streaming returns.\n if (chunk.type === 'TEXT_MESSAGE_CONTENT') {\n if (chunk.content) {\n summary = chunk.content\n } else if (chunk.delta) {\n summary += chunk.delta\n }\n if (chunk.model) model = chunk.model\n }\n\n // Emit the GenerationClient-shaped result event just before the\n // terminal RUN_FINISHED so subscribers (useSummarize) populate\n // `result` before flipping `status` to success.\n if (chunk.type === 'RUN_FINISHED') {\n if (chunk.usage) usage = chunk.usage\n if (chunk.model) model = chunk.model\n yield {\n type: EventType.CUSTOM,\n name: 'generation:result',\n value: { id, model, summary, usage } satisfies SummarizationResult,\n model,\n timestamp: Date.now(),\n }\n }\n\n yield chunk\n }\n } catch (error: unknown) {\n options.logger.errors(`${this.name}.summarizeStream fatal`, {\n error: toRunErrorPayload(error, `${this.name}.summarizeStream failed`),\n source: `${this.name}.summarizeStream`,\n })\n throw error\n }\n }\n\n /**\n * Build the TextOptions passed to the underlying chatStream. Provider\n * `modelOptions` from the summarize call are forwarded as-is so knobs like\n * Anthropic cache headers, Gemini safety settings, or Ollama tuning params\n * still reach the wire layer.\n */\n protected buildTextOptions(\n options: SummarizationOptions<TProviderOptions>,\n systemPrompt: string,\n ): TextOptions<TProviderOptions> {\n return {\n model: options.model,\n messages: [{ role: 'user', content: options.text }],\n systemPrompts: [systemPrompt],\n maxTokens: options.maxLength,\n temperature: 0.3,\n modelOptions: options.modelOptions,\n logger: options.logger,\n }\n }\n\n protected buildSummarizationPrompt(\n options: SummarizationOptions<TProviderOptions>,\n ): string {\n let prompt = 'You are a professional summarizer. '\n\n switch (options.style) {\n case 'bullet-points':\n prompt += 'Provide a summary in bullet point format. '\n break\n case 'paragraph':\n prompt += 'Provide a summary in paragraph format. '\n break\n case 'concise':\n prompt += 'Provide a very concise summary in 1-2 sentences. '\n break\n default:\n prompt += 'Provide a clear and concise summary. '\n }\n\n if (options.focus && options.focus.length > 0) {\n prompt += `Focus on the following aspects: ${options.focus.join(', ')}. `\n }\n\n if (options.maxLength) {\n prompt += `Keep the summary under ${options.maxLength} tokens. `\n }\n\n return prompt\n }\n}\n"],"names":[],"mappings":"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"}
@@ -105,3 +105,4 @@ export declare function summarize<TAdapter extends SummarizeAdapter<string, obje
105
105
  export declare function createSummarizeOptions<TAdapter extends SummarizeAdapter<string, object>, TStream extends boolean = false>(options: SummarizeActivityOptions<TAdapter, TStream>): SummarizeActivityOptions<TAdapter, TStream>;
106
106
  export type { SummarizeAdapter, SummarizeAdapterConfig, AnySummarizeAdapter, } from './adapter.js';
107
107
  export { BaseSummarizeAdapter } from './adapter.js';
108
+ export { ChatStreamSummarizeAdapter, type ChatStreamCapable, type InferTextProviderOptions, } from './chat-stream-summarize.js';
@@ -17,7 +17,7 @@ function summarize(options) {
17
17
  );
18
18
  }
19
19
  async function runSummarize(options) {
20
- const { adapter, text, maxLength, style, focus } = options;
20
+ const { adapter, text, maxLength, style, focus, modelOptions } = options;
21
21
  const model = adapter.model;
22
22
  const requestId = createId("summarize");
23
23
  const inputLength = text.length;
@@ -41,6 +41,7 @@ async function runSummarize(options) {
41
41
  maxLength,
42
42
  style,
43
43
  focus,
44
+ modelOptions,
44
45
  logger
45
46
  };
46
47
  try {
@@ -70,7 +71,7 @@ async function runSummarize(options) {
70
71
  }
71
72
  }
72
73
  async function* runStreamingSummarize(options) {
73
- const { adapter, text, maxLength, style, focus } = options;
74
+ const { adapter, text, maxLength, style, focus, modelOptions } = options;
74
75
  const model = adapter.model;
75
76
  const logger = resolveDebugOption(options.debug);
76
77
  logger.request(`activity=summarize provider=${adapter.name}`, {
@@ -84,6 +85,7 @@ async function* runStreamingSummarize(options) {
84
85
  maxLength,
85
86
  style,
86
87
  focus,
88
+ modelOptions,
87
89
  logger
88
90
  };
89
91
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/activities/summarize/index.ts"],"sourcesContent":["/**\n * Summarize Activity\n *\n * Generates summaries from text input.\n * This is a self-contained module with implementation, types, and JSDoc.\n */\n\nimport { aiEventClient } from '@tanstack/ai-event-client'\nimport { streamGenerationResult } from '../stream-generation-result.js'\nimport { resolveDebugOption } from '../../logger/resolve'\nimport type { InternalLogger } from '../../logger/internal-logger'\nimport type { DebugOption } from '../../logger/types'\nimport type { SummarizeAdapter } from './adapter'\nimport type {\n StreamChunk,\n SummarizationOptions,\n SummarizationResult,\n} from '../../types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'summarize' as const\n\n// ===========================\n// Type Extraction Helpers\n// ===========================\n\n/** Extract provider options from a SummarizeAdapter via ~types */\nexport type SummarizeProviderOptions<TAdapter> =\n TAdapter extends SummarizeAdapter<any, any>\n ? TAdapter['~types']['providerOptions']\n : object\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the summarize activity.\n * The model is extracted from the adapter's model property.\n *\n * @template TAdapter - The summarize adapter type\n * @template TStream - Whether to stream the output\n */\nexport interface SummarizeActivityOptions<\n TAdapter extends SummarizeAdapter<string, object>,\n TStream extends boolean = false,\n> {\n /** The summarize adapter to use (must be created with a model) */\n adapter: TAdapter & { kind: typeof kind }\n /** The text to summarize */\n text: string\n /** Maximum length of the summary (in words or characters, provider-dependent) */\n maxLength?: number\n /** Style of summary to generate */\n style?: 'bullet-points' | 'paragraph' | 'concise'\n /** Topics or aspects to focus on in the summary */\n focus?: Array<string>\n /** Provider-specific options */\n modelOptions?: SummarizeProviderOptions<TAdapter>\n /**\n * Whether to stream the summarization result.\n * When true, returns an AsyncIterable<StreamChunk> for streaming output.\n * When false or not provided, returns a Promise<SummarizationResult>.\n *\n * @default false\n */\n stream?: TStream\n /**\n * Enable debug logging. Pass `true` to enable all categories, `false` to\n * silence everything including errors, or a `DebugConfig` object for granular\n * control and/or a custom `Logger`.\n */\n debug?: DebugOption\n}\n\n// ===========================\n// Activity Result Type\n// ===========================\n\n/**\n * Result type for the summarize activity.\n * - If stream is true: AsyncIterable<StreamChunk>\n * - Otherwise: Promise<SummarizationResult>\n */\nexport type SummarizeActivityResult<TStream extends boolean> =\n TStream extends true\n ? AsyncIterable<StreamChunk>\n : Promise<SummarizationResult>\n\n// ===========================\n// Helper Functions\n// ===========================\n\nfunction createId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n// ===========================\n// Activity Implementation\n// ===========================\n\n/**\n * Summarize activity - generates summaries from text.\n *\n * Supports both streaming and non-streaming modes.\n *\n * @example Basic summarization\n * ```ts\n * import { summarize } from '@tanstack/ai'\n * import { openaiSummarize } from '@tanstack/ai-openai'\n *\n * const result = await summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long article text here...'\n * })\n *\n * console.log(result.summary)\n * ```\n *\n * @example Summarization with style\n * ```ts\n * const result = await summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long article text here...',\n * style: 'bullet-points',\n * maxLength: 100\n * })\n * ```\n *\n * @example Focused summarization\n * ```ts\n * const result = await summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long technical document...',\n * focus: ['key findings', 'methodology']\n * })\n * ```\n *\n * @example Streaming summarization\n * ```ts\n * for await (const chunk of summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long article text here...',\n * stream: true\n * })) {\n * if (chunk.type === 'content') {\n * process.stdout.write(chunk.delta)\n * }\n * }\n * ```\n */\nexport function summarize<\n TAdapter extends SummarizeAdapter<string, object>,\n TStream extends boolean = false,\n>(\n options: SummarizeActivityOptions<TAdapter, TStream>,\n): SummarizeActivityResult<TStream> {\n const { stream } = options\n\n if (stream) {\n return runStreamingSummarize(\n options as unknown as SummarizeActivityOptions<\n SummarizeAdapter<string, object>,\n true\n >,\n ) as SummarizeActivityResult<TStream>\n }\n\n return runSummarize(\n options as unknown as SummarizeActivityOptions<\n SummarizeAdapter<string, object>,\n false\n >,\n ) as SummarizeActivityResult<TStream>\n}\n\n/**\n * Run non-streaming summarization\n */\nasync function runSummarize(\n options: SummarizeActivityOptions<SummarizeAdapter<string, object>, false>,\n): Promise<SummarizationResult> {\n const { adapter, text, maxLength, style, focus } = options\n const model = adapter.model\n const requestId = createId('summarize')\n const inputLength = text.length\n const startTime = Date.now()\n const logger: InternalLogger = resolveDebugOption(options.debug)\n\n aiEventClient.emit('summarize:request:started', {\n requestId,\n provider: adapter.name,\n model,\n inputLength,\n timestamp: startTime,\n })\n\n logger.request(`activity=summarize provider=${adapter.name}`, {\n provider: adapter.name,\n model,\n inputLength,\n })\n\n const summarizeOptions: SummarizationOptions = {\n model,\n text,\n maxLength,\n style,\n focus,\n logger,\n }\n\n try {\n const result = await adapter.summarize(summarizeOptions)\n\n const duration = Date.now() - startTime\n const outputLength = result.summary.length\n\n aiEventClient.emit('summarize:request:completed', {\n requestId,\n provider: adapter.name,\n model,\n inputLength,\n outputLength,\n duration,\n timestamp: Date.now(),\n })\n\n logger.output(`activity=summarize length=${outputLength}`, {\n hasSummary: !!result.summary,\n outputLength,\n })\n\n return result\n } catch (error) {\n logger.errors('summarize activity failed', {\n error,\n source: 'summarize',\n })\n throw error\n }\n}\n\n/**\n * Run streaming summarization\n * Uses the adapter's native streaming if available, otherwise falls back\n * to non-streaming and yields the result as a single chunk.\n */\nasync function* runStreamingSummarize(\n options: SummarizeActivityOptions<SummarizeAdapter<string, object>, true>,\n): AsyncIterable<StreamChunk> {\n const { adapter, text, maxLength, style, focus } = options\n const model = adapter.model\n const logger: InternalLogger = resolveDebugOption(options.debug)\n\n logger.request(`activity=summarize provider=${adapter.name}`, {\n provider: adapter.name,\n model,\n stream: true,\n })\n\n const summarizeOptions: SummarizationOptions = {\n model,\n text,\n maxLength,\n style,\n focus,\n logger,\n }\n\n try {\n // Use real streaming if the adapter supports it\n if (adapter.summarizeStream) {\n yield* adapter.summarizeStream(summarizeOptions)\n return\n }\n\n // Fall back to non-streaming — wrap result with streamGenerationResult\n yield* streamGenerationResult(() => adapter.summarize(summarizeOptions))\n } catch (error) {\n logger.errors('summarize activity failed', {\n error,\n source: 'summarize',\n })\n throw error\n }\n}\n\n// ===========================\n// Options Factory\n// ===========================\n\n/**\n * Create typed options for the summarize() function without executing.\n */\nexport function createSummarizeOptions<\n TAdapter extends SummarizeAdapter<string, object>,\n TStream extends boolean = false,\n>(\n options: SummarizeActivityOptions<TAdapter, TStream>,\n): SummarizeActivityOptions<TAdapter, TStream> {\n return options\n}\n\n// Re-export adapter types\nexport type {\n SummarizeAdapter,\n SummarizeAdapterConfig,\n AnySummarizeAdapter,\n} from './adapter'\nexport { BaseSummarizeAdapter } from './adapter'\n"],"names":[],"mappings":";;;AAwBO,MAAM,OAAO;AAyEpB,SAAS,SAAS,QAAwB;AACxC,SAAO,GAAG,MAAM,IAAI,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC1E;AAwDO,SAAS,UAId,SACkC;AAClC,QAAM,EAAE,WAAW;AAEnB,MAAI,QAAQ;AACV,WAAO;AAAA,MACL;AAAA,IAAA;AAAA,EAKJ;AAEA,SAAO;AAAA,IACL;AAAA,EAAA;AAKJ;AAKA,eAAe,aACb,SAC8B;AAC9B,QAAM,EAAE,SAAS,MAAM,WAAW,OAAO,UAAU;AACnD,QAAM,QAAQ,QAAQ;AACtB,QAAM,YAAY,SAAS,WAAW;AACtC,QAAM,cAAc,KAAK;AACzB,QAAM,YAAY,KAAK,IAAA;AACvB,QAAM,SAAyB,mBAAmB,QAAQ,KAAK;AAE/D,gBAAc,KAAK,6BAA6B;AAAA,IAC9C;AAAA,IACA,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EAAA,CACZ;AAED,SAAO,QAAQ,+BAA+B,QAAQ,IAAI,IAAI;AAAA,IAC5D,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA;AAAA,EAAA,CACD;AAED,QAAM,mBAAyC;AAAA,IAC7C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,UAAU,gBAAgB;AAEvD,UAAM,WAAW,KAAK,IAAA,IAAQ;AAC9B,UAAM,eAAe,OAAO,QAAQ;AAEpC,kBAAc,KAAK,+BAA+B;AAAA,MAChD;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAA;AAAA,IAAI,CACrB;AAED,WAAO,OAAO,6BAA6B,YAAY,IAAI;AAAA,MACzD,YAAY,CAAC,CAAC,OAAO;AAAA,MACrB;AAAA,IAAA,CACD;AAED,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,OAAO,6BAA6B;AAAA,MACzC;AAAA,MACA,QAAQ;AAAA,IAAA,CACT;AACD,UAAM;AAAA,EACR;AACF;AAOA,gBAAgB,sBACd,SAC4B;AAC5B,QAAM,EAAE,SAAS,MAAM,WAAW,OAAO,UAAU;AACnD,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAyB,mBAAmB,QAAQ,KAAK;AAE/D,SAAO,QAAQ,+BAA+B,QAAQ,IAAI,IAAI;AAAA,IAC5D,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,QAAQ;AAAA,EAAA,CACT;AAED,QAAM,mBAAyC;AAAA,IAC7C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,MAAI;AAEF,QAAI,QAAQ,iBAAiB;AAC3B,aAAO,QAAQ,gBAAgB,gBAAgB;AAC/C;AAAA,IACF;AAGA,WAAO,uBAAuB,MAAM,QAAQ,UAAU,gBAAgB,CAAC;AAAA,EACzE,SAAS,OAAO;AACd,WAAO,OAAO,6BAA6B;AAAA,MACzC;AAAA,MACA,QAAQ;AAAA,IAAA,CACT;AACD,UAAM;AAAA,EACR;AACF;AASO,SAAS,uBAId,SAC6C;AAC7C,SAAO;AACT;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/activities/summarize/index.ts"],"sourcesContent":["/**\n * Summarize Activity\n *\n * Generates summaries from text input.\n * This is a self-contained module with implementation, types, and JSDoc.\n */\n\nimport { aiEventClient } from '@tanstack/ai-event-client'\nimport { streamGenerationResult } from '../stream-generation-result.js'\nimport { resolveDebugOption } from '../../logger/resolve'\nimport type { InternalLogger } from '../../logger/internal-logger'\nimport type { DebugOption } from '../../logger/types'\nimport type { SummarizeAdapter } from './adapter'\nimport type { StreamChunk, SummarizationResult } from '../../types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'summarize' as const\n\n// ===========================\n// Type Extraction Helpers\n// ===========================\n\n/** Extract provider options from a SummarizeAdapter via ~types */\nexport type SummarizeProviderOptions<TAdapter> =\n TAdapter extends SummarizeAdapter<any, any>\n ? TAdapter['~types']['providerOptions']\n : object\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the summarize activity.\n * The model is extracted from the adapter's model property.\n *\n * @template TAdapter - The summarize adapter type\n * @template TStream - Whether to stream the output\n */\nexport interface SummarizeActivityOptions<\n TAdapter extends SummarizeAdapter<string, object>,\n TStream extends boolean = false,\n> {\n /** The summarize adapter to use (must be created with a model) */\n adapter: TAdapter & { kind: typeof kind }\n /** The text to summarize */\n text: string\n /** Maximum length of the summary (in words or characters, provider-dependent) */\n maxLength?: number\n /** Style of summary to generate */\n style?: 'bullet-points' | 'paragraph' | 'concise'\n /** Topics or aspects to focus on in the summary */\n focus?: Array<string>\n /** Provider-specific options */\n modelOptions?: SummarizeProviderOptions<TAdapter>\n /**\n * Whether to stream the summarization result.\n * When true, returns an AsyncIterable<StreamChunk> for streaming output.\n * When false or not provided, returns a Promise<SummarizationResult>.\n *\n * @default false\n */\n stream?: TStream\n /**\n * Enable debug logging. Pass `true` to enable all categories, `false` to\n * silence everything including errors, or a `DebugConfig` object for granular\n * control and/or a custom `Logger`.\n */\n debug?: DebugOption\n}\n\n// ===========================\n// Activity Result Type\n// ===========================\n\n/**\n * Result type for the summarize activity.\n * - If stream is true: AsyncIterable<StreamChunk>\n * - Otherwise: Promise<SummarizationResult>\n */\nexport type SummarizeActivityResult<TStream extends boolean> =\n TStream extends true\n ? AsyncIterable<StreamChunk>\n : Promise<SummarizationResult>\n\n// ===========================\n// Helper Functions\n// ===========================\n\nfunction createId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n// ===========================\n// Activity Implementation\n// ===========================\n\n/**\n * Summarize activity - generates summaries from text.\n *\n * Supports both streaming and non-streaming modes.\n *\n * @example Basic summarization\n * ```ts\n * import { summarize } from '@tanstack/ai'\n * import { openaiSummarize } from '@tanstack/ai-openai'\n *\n * const result = await summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long article text here...'\n * })\n *\n * console.log(result.summary)\n * ```\n *\n * @example Summarization with style\n * ```ts\n * const result = await summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long article text here...',\n * style: 'bullet-points',\n * maxLength: 100\n * })\n * ```\n *\n * @example Focused summarization\n * ```ts\n * const result = await summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long technical document...',\n * focus: ['key findings', 'methodology']\n * })\n * ```\n *\n * @example Streaming summarization\n * ```ts\n * for await (const chunk of summarize({\n * adapter: openaiSummarize('gpt-4o-mini'),\n * text: 'Long article text here...',\n * stream: true\n * })) {\n * if (chunk.type === 'content') {\n * process.stdout.write(chunk.delta)\n * }\n * }\n * ```\n */\nexport function summarize<\n TAdapter extends SummarizeAdapter<string, object>,\n TStream extends boolean = false,\n>(\n options: SummarizeActivityOptions<TAdapter, TStream>,\n): SummarizeActivityResult<TStream> {\n const { stream } = options\n\n if (stream) {\n return runStreamingSummarize(\n options as unknown as SummarizeActivityOptions<\n SummarizeAdapter<string, object>,\n true\n >,\n ) as SummarizeActivityResult<TStream>\n }\n\n return runSummarize(\n options as unknown as SummarizeActivityOptions<\n SummarizeAdapter<string, object>,\n false\n >,\n ) as SummarizeActivityResult<TStream>\n}\n\n/**\n * Run non-streaming summarization\n */\nasync function runSummarize(\n options: SummarizeActivityOptions<SummarizeAdapter<string, object>, false>,\n): Promise<SummarizationResult> {\n const { adapter, text, maxLength, style, focus, modelOptions } = options\n const model = adapter.model\n const requestId = createId('summarize')\n const inputLength = text.length\n const startTime = Date.now()\n const logger: InternalLogger = resolveDebugOption(options.debug)\n\n aiEventClient.emit('summarize:request:started', {\n requestId,\n provider: adapter.name,\n model,\n inputLength,\n timestamp: startTime,\n })\n\n logger.request(`activity=summarize provider=${adapter.name}`, {\n provider: adapter.name,\n model,\n inputLength,\n })\n\n const summarizeOptions = {\n model,\n text,\n maxLength,\n style,\n focus,\n modelOptions,\n logger,\n }\n\n try {\n const result = await adapter.summarize(summarizeOptions)\n\n const duration = Date.now() - startTime\n const outputLength = result.summary.length\n\n aiEventClient.emit('summarize:request:completed', {\n requestId,\n provider: adapter.name,\n model,\n inputLength,\n outputLength,\n duration,\n timestamp: Date.now(),\n })\n\n logger.output(`activity=summarize length=${outputLength}`, {\n hasSummary: !!result.summary,\n outputLength,\n })\n\n return result\n } catch (error) {\n logger.errors('summarize activity failed', {\n error,\n source: 'summarize',\n })\n throw error\n }\n}\n\n/**\n * Run streaming summarization\n * Uses the adapter's native streaming if available, otherwise falls back\n * to non-streaming and yields the result as a single chunk.\n */\nasync function* runStreamingSummarize(\n options: SummarizeActivityOptions<SummarizeAdapter<string, object>, true>,\n): AsyncIterable<StreamChunk> {\n const { adapter, text, maxLength, style, focus, modelOptions } = options\n const model = adapter.model\n const logger: InternalLogger = resolveDebugOption(options.debug)\n\n logger.request(`activity=summarize provider=${adapter.name}`, {\n provider: adapter.name,\n model,\n stream: true,\n })\n\n const summarizeOptions = {\n model,\n text,\n maxLength,\n style,\n focus,\n modelOptions,\n logger,\n }\n\n try {\n // Use real streaming if the adapter supports it\n if (adapter.summarizeStream) {\n yield* adapter.summarizeStream(summarizeOptions)\n return\n }\n\n // Fall back to non-streaming — wrap result with streamGenerationResult\n yield* streamGenerationResult(() => adapter.summarize(summarizeOptions))\n } catch (error) {\n logger.errors('summarize activity failed', {\n error,\n source: 'summarize',\n })\n throw error\n }\n}\n\n// ===========================\n// Options Factory\n// ===========================\n\n/**\n * Create typed options for the summarize() function without executing.\n */\nexport function createSummarizeOptions<\n TAdapter extends SummarizeAdapter<string, object>,\n TStream extends boolean = false,\n>(\n options: SummarizeActivityOptions<TAdapter, TStream>,\n): SummarizeActivityOptions<TAdapter, TStream> {\n return options\n}\n\n// Re-export adapter types\nexport type {\n SummarizeAdapter,\n SummarizeAdapterConfig,\n AnySummarizeAdapter,\n} from './adapter'\nexport { BaseSummarizeAdapter } from './adapter'\nexport {\n ChatStreamSummarizeAdapter,\n type ChatStreamCapable,\n type InferTextProviderOptions,\n} from './chat-stream-summarize'\n"],"names":[],"mappings":";;;AAoBO,MAAM,OAAO;AAyEpB,SAAS,SAAS,QAAwB;AACxC,SAAO,GAAG,MAAM,IAAI,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC1E;AAwDO,SAAS,UAId,SACkC;AAClC,QAAM,EAAE,WAAW;AAEnB,MAAI,QAAQ;AACV,WAAO;AAAA,MACL;AAAA,IAAA;AAAA,EAKJ;AAEA,SAAO;AAAA,IACL;AAAA,EAAA;AAKJ;AAKA,eAAe,aACb,SAC8B;AAC9B,QAAM,EAAE,SAAS,MAAM,WAAW,OAAO,OAAO,iBAAiB;AACjE,QAAM,QAAQ,QAAQ;AACtB,QAAM,YAAY,SAAS,WAAW;AACtC,QAAM,cAAc,KAAK;AACzB,QAAM,YAAY,KAAK,IAAA;AACvB,QAAM,SAAyB,mBAAmB,QAAQ,KAAK;AAE/D,gBAAc,KAAK,6BAA6B;AAAA,IAC9C;AAAA,IACA,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EAAA,CACZ;AAED,SAAO,QAAQ,+BAA+B,QAAQ,IAAI,IAAI;AAAA,IAC5D,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA;AAAA,EAAA,CACD;AAED,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,UAAU,gBAAgB;AAEvD,UAAM,WAAW,KAAK,IAAA,IAAQ;AAC9B,UAAM,eAAe,OAAO,QAAQ;AAEpC,kBAAc,KAAK,+BAA+B;AAAA,MAChD;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAA;AAAA,IAAI,CACrB;AAED,WAAO,OAAO,6BAA6B,YAAY,IAAI;AAAA,MACzD,YAAY,CAAC,CAAC,OAAO;AAAA,MACrB;AAAA,IAAA,CACD;AAED,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,OAAO,6BAA6B;AAAA,MACzC;AAAA,MACA,QAAQ;AAAA,IAAA,CACT;AACD,UAAM;AAAA,EACR;AACF;AAOA,gBAAgB,sBACd,SAC4B;AAC5B,QAAM,EAAE,SAAS,MAAM,WAAW,OAAO,OAAO,iBAAiB;AACjE,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAyB,mBAAmB,QAAQ,KAAK;AAE/D,SAAO,QAAQ,+BAA+B,QAAQ,IAAI,IAAI;AAAA,IAC5D,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,QAAQ;AAAA,EAAA,CACT;AAED,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,MAAI;AAEF,QAAI,QAAQ,iBAAiB;AAC3B,aAAO,QAAQ,gBAAgB,gBAAgB;AAC/C;AAAA,IACF;AAGA,WAAO,uBAAuB,MAAM,QAAQ,UAAU,gBAAgB,CAAC;AAAA,EACzE,SAAS,OAAO;AACd,WAAO,OAAO,6BAA6B;AAAA,MACzC;AAAA,MACA,QAAQ;AAAA,IAAA,CACT;AACD,UAAM;AAAA,EACR;AACF;AASO,SAAS,uBAId,SAC6C;AAC7C,SAAO;AACT;"}
@@ -22,6 +22,9 @@ export type { RealtimeToken, RealtimeTokenAdapter, RealtimeTokenOptions, Realtim
22
22
  export { convertMessagesToModelMessages, generateMessageId, uiMessageToModelMessages, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeToUIMessage, } from './activities/chat/messages.js';
23
23
  export { StreamProcessor, createReplayStream, ImmediateStrategy, PunctuationStrategy, BatchStrategy, WordBoundaryStrategy, CompositeStrategy, PartialJSONParser, defaultJSONParser, parsePartialJSON, } from './activities/chat/stream/index.js';
24
24
  export type { ChunkStrategy, ChunkRecording, InternalToolCallState, ProcessorResult, ProcessorState, StreamProcessorEvents, StreamProcessorOptions, ToolCallState, ToolResultState, JSONParser, } from './activities/chat/stream/index.js';
25
+ export { chatParamsFromRequest, chatParamsFromRequestBody, mergeAgentTools, } from './utilities/chat-params.js';
26
+ export { uiMessagesToWire } from './utilities/ag-ui-wire.js';
27
+ export type { WireMessage } from './utilities/ag-ui-wire.js';
25
28
  export { createModel, extendAdapter } from './extend-adapter.js';
26
29
  export type { ExtendedModelDef } from './extend-adapter.js';
27
30
  export type { Logger, DebugCategories, DebugConfig, DebugOption, } from './logger/types.js';
package/dist/esm/index.js CHANGED
@@ -14,6 +14,8 @@ import { createFrozenRegistry, createToolRegistry } from "./tool-registry.js";
14
14
  import { detectImageMimeType } from "./utils.js";
15
15
  import { realtimeToken } from "./realtime/index.js";
16
16
  import { convertMessagesToModelMessages, generateMessageId, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeToUIMessage, uiMessageToModelMessages } from "./activities/chat/messages.js";
17
+ import { chatParamsFromRequest, chatParamsFromRequestBody, mergeAgentTools } from "./utilities/chat-params.js";
18
+ import { uiMessagesToWire } from "./utilities/ag-ui-wire.js";
17
19
  import { createModel, extendAdapter } from "./extend-adapter.js";
18
20
  import { ConsoleLogger } from "./logger/console-logger.js";
19
21
  import { StreamProcessor, createReplayStream } from "./activities/chat/stream/processor.js";
@@ -32,6 +34,8 @@ export {
32
34
  ToolCallManager,
33
35
  WordBoundaryStrategy,
34
36
  chat,
37
+ chatParamsFromRequest,
38
+ chatParamsFromRequestBody,
35
39
  combineStrategies,
36
40
  convertMessagesToModelMessages,
37
41
  convertSchemaToJsonSchema,
@@ -57,6 +61,7 @@ export {
57
61
  generateVideo,
58
62
  getVideoJobStatus,
59
63
  maxIterations,
64
+ mergeAgentTools,
60
65
  modelMessageToUIMessage,
61
66
  modelMessagesToUIMessages,
62
67
  normalizeToUIMessage,
@@ -70,6 +75,7 @@ export {
70
75
  toServerSentEventsStream,
71
76
  toolDefinition,
72
77
  uiMessageToModelMessages,
78
+ uiMessagesToWire,
73
79
  untilFinishReason
74
80
  };
75
81
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { StandardJSONSchemaV1 } from '@standard-schema/spec';
1
+ import { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import { InternalLogger } from './logger/internal-logger.js';
3
3
  import { BaseEvent as AGUIBaseEvent, CustomEvent as AGUICustomEvent, MessagesSnapshotEvent as AGUIMessagesSnapshotEvent, ReasoningEncryptedValueEvent as AGUIReasoningEncryptedValueEvent, ReasoningEndEvent as AGUIReasoningEndEvent, ReasoningMessageContentEvent as AGUIReasoningMessageContentEvent, ReasoningMessageEndEvent as AGUIReasoningMessageEndEvent, ReasoningMessageStartEvent as AGUIReasoningMessageStartEvent, ReasoningStartEvent as AGUIReasoningStartEvent, RunErrorEvent as AGUIRunErrorEvent, RunFinishedEvent as AGUIRunFinishedEvent, RunStartedEvent as AGUIRunStartedEvent, StateDeltaEvent as AGUIStateDeltaEvent, StateSnapshotEvent as AGUIStateSnapshotEvent, StepFinishedEvent as AGUIStepFinishedEvent, StepStartedEvent as AGUIStepStartedEvent, TextMessageContentEvent as AGUITextMessageContentEvent, TextMessageEndEvent as AGUITextMessageEndEvent, TextMessageStartEvent as AGUITextMessageStartEvent, ToolCallArgsEvent as AGUIToolCallArgsEvent, ToolCallEndEvent as AGUIToolCallEndEvent, ToolCallResultEvent as AGUIToolCallResultEvent, ToolCallStartEvent as AGUIToolCallStartEvent, EventType } from '@ag-ui/core';
4
4
  /**
@@ -54,22 +54,32 @@ export interface JSONSchema {
54
54
  [key: string]: any;
55
55
  }
56
56
  /**
57
- * Union type for schema input - can be any Standard JSON Schema compliant schema or a plain JSONSchema object.
57
+ * Union type for schema input - can be any Standard Schema compliant validator,
58
+ * any Standard JSON Schema compliant schema, or a plain JSONSchema object.
58
59
  *
59
- * Standard JSON Schema compliant libraries include:
60
+ * Standard JSON Schema compliant libraries (carry the JSON-schema converter):
60
61
  * - Zod v4.2+ (natively supports StandardJSONSchemaV1)
61
62
  * - ArkType v2.1.28+ (natively supports StandardJSONSchemaV1)
62
63
  * - Valibot v1.2+ (via `toStandardJsonSchema()` from `@valibot/to-json-schema`)
63
64
  *
65
+ * StandardSchemaV1 covers libraries whose published types only expose the
66
+ * validator surface — Zod's core `$ZodType['~standard']` is currently typed
67
+ * as `StandardSchemaV1.Props` even though the runtime attaches the
68
+ * `jsonSchema` converter, so this branch is what makes `InferSchemaType`
69
+ * recover the inferred type for callers using `z.ZodType<T>`.
70
+ *
64
71
  * @see https://standardschema.dev/json-schema
65
72
  */
66
- export type SchemaInput = StandardJSONSchemaV1<any, any> | JSONSchema;
73
+ export type SchemaInput = StandardJSONSchemaV1<any, any> | StandardSchemaV1<any, any> | JSONSchema;
67
74
  /**
68
75
  * Infer the TypeScript type from a schema.
69
76
  * For Standard JSON Schema compliant schemas, extracts the input type.
70
- * For plain JSONSchema, returns `any` since we can't infer types from JSON Schema at compile time.
77
+ * For Standard Schema validators (e.g. Zod's `~standard` surface), extracts
78
+ * the input type from the `StandardSchemaV1` shape.
79
+ * For plain JSONSchema, returns `unknown` since we can't infer types from
80
+ * JSON Schema at compile time.
71
81
  */
72
- export type InferSchemaType<T> = T extends StandardJSONSchemaV1<infer TInput, unknown> ? TInput : unknown;
82
+ export type InferSchemaType<T> = T extends StandardJSONSchemaV1<infer TInput, unknown> ? TInput : T extends StandardSchemaV1<infer TInput, unknown> ? TInput : unknown;
73
83
  export interface ToolCall<TMetadata = unknown> {
74
84
  id: string;
75
85
  type: 'function';
@@ -598,8 +608,14 @@ export interface TextOptions<TProviderOptionsSuperset extends Record<string, any
598
608
  */
599
609
  outputSchema?: SchemaInput;
600
610
  /**
601
- * Conversation ID for correlating client and server-side devtools events.
602
- * When provided, server-side events will be linked to the client conversation in devtools.
611
+ * @deprecated Use `threadId` instead. `conversationId` is the legacy
612
+ * pre-AG-UI name for the same concept (a stable per-conversation
613
+ * identifier used to correlate client/server devtools events). When
614
+ * `conversationId` is omitted, the runtime falls back to `threadId`
615
+ * automatically, so most callers can simply pass `threadId` (or rely
616
+ * on `chatParamsFromRequest`, which surfaces it on `params`).
617
+ *
618
+ * Will be removed in a future major release.
603
619
  */
604
620
  conversationId?: string;
605
621
  /**
@@ -633,6 +649,11 @@ export interface TextOptions<TProviderOptionsSuperset extends Record<string, any
633
649
  * If not provided, a unique ID will be generated.
634
650
  */
635
651
  runId?: string;
652
+ /**
653
+ * Parent run ID for AG-UI protocol nested run correlation.
654
+ * Surfaced for observability/middleware; not consumed by the LLM call.
655
+ */
656
+ parentRunId?: string;
636
657
  }
637
658
  /**
638
659
  * Re-export EventType enum from @ag-ui/core for use in event creation.
@@ -895,6 +916,95 @@ export interface CustomEvent extends AGUICustomEvent {
895
916
  /** Model identifier for multi-model support */
896
917
  model?: string;
897
918
  }
919
+ /**
920
+ * Final event of a streaming structured-output run. Carries the validated
921
+ * `object` (typed as `T` after the orchestrator runs Standard Schema parsing),
922
+ * the `raw` JSON text that produced it, and — for thinking/reasoning models —
923
+ * the accumulated reasoning text. Adapters emit this with `T = unknown`; the
924
+ * chat orchestrator narrows to the schema's inferred type after validation.
925
+ *
926
+ * `reasoning` is `undefined` when the model produced none (most non-thinking
927
+ * models) and when the underlying adapter doesn't expose reasoning streams.
928
+ *
929
+ * `name` is a string literal so consumers can narrow directly:
930
+ *
931
+ * ```ts
932
+ * if (chunk.type === 'CUSTOM' && chunk.name === 'structured-output.complete') {
933
+ * chunk.value.object // typed as T
934
+ * }
935
+ * ```
936
+ */
937
+ export interface StructuredOutputCompleteEvent<T = unknown> extends Omit<CustomEvent, 'name' | 'value'> {
938
+ name: 'structured-output.complete';
939
+ value: {
940
+ object: T;
941
+ raw: string;
942
+ reasoning?: string;
943
+ };
944
+ }
945
+ /**
946
+ * Emitted when a server tool requires approval before execution. The agent
947
+ * loop yields this and pauses — `structured-output.complete` will not fire
948
+ * for that run. The shape is fixed by the orchestrator's tool-approval flow
949
+ * (see `buildApprovalChunks` in `activities/chat/index.ts`).
950
+ */
951
+ export interface ApprovalRequestedEvent extends Omit<CustomEvent, 'name' | 'value'> {
952
+ name: 'approval-requested';
953
+ value: {
954
+ toolCallId: string;
955
+ toolName: string;
956
+ input: unknown;
957
+ approval: {
958
+ id: string;
959
+ needsApproval: true;
960
+ };
961
+ };
962
+ }
963
+ /**
964
+ * Emitted when a client tool is invoked. The agent loop yields this and
965
+ * pauses to let the caller run the tool client-side — `structured-output.complete`
966
+ * will not fire for that run. Shape fixed by `buildClientToolChunks` in
967
+ * `activities/chat/index.ts`.
968
+ */
969
+ export interface ToolInputAvailableEvent extends Omit<CustomEvent, 'name' | 'value'> {
970
+ name: 'tool-input-available';
971
+ value: {
972
+ toolCallId: string;
973
+ toolName: string;
974
+ input: unknown;
975
+ };
976
+ }
977
+ /**
978
+ * Public type for streams returned by `chat({ outputSchema, stream: true })`.
979
+ *
980
+ * Yields all standard `StreamChunk` lifecycle events plus the three tagged
981
+ * `CUSTOM` events the orchestrator can emit through this path:
982
+ * - `structured-output.complete` — terminal event with typed `value.object: T`
983
+ * - `approval-requested` — server tool needs approval (pauses the run)
984
+ * - `tool-input-available` — client tool invocation (pauses the run)
985
+ *
986
+ * Each variant has a literal `name`, so a single discriminated narrow gives
987
+ * you a typed `value` with no helper or cast:
988
+ *
989
+ * ```ts
990
+ * for await (const chunk of stream) {
991
+ * if (chunk.type === 'CUSTOM' && chunk.name === 'structured-output.complete') {
992
+ * chunk.value.object // typed as T
993
+ * } else if (chunk.type === 'CUSTOM' && chunk.name === 'approval-requested') {
994
+ * chunk.value.toolCallId // typed as string
995
+ * }
996
+ * }
997
+ * ```
998
+ *
999
+ * Caveat: tools can emit arbitrary user-defined custom events via the
1000
+ * `emitCustomEvent(name, value)` context API. Those flow through this stream
1001
+ * at runtime but are intentionally absent from this type — including a bare
1002
+ * `CustomEvent` (whose `value: any` would poison the union) would collapse
1003
+ * `chunk.value` back to `any` after the narrow. If you rely on
1004
+ * `emitCustomEvent` plus `outputSchema + stream: true`, branch on `CUSTOM`
1005
+ * outside the literal-`name` narrows or cast explicitly.
1006
+ */
1007
+ export type StructuredOutputStream<T = unknown> = AsyncIterable<Exclude<StreamChunk, CustomEvent> | StructuredOutputCompleteEvent<T> | ApprovalRequestedEvent | ToolInputAvailableEvent>;
898
1008
  /**
899
1009
  * Emitted when reasoning starts for a message.
900
1010
  *
@@ -976,12 +1086,14 @@ export interface TextCompletionChunk {
976
1086
  totalTokens: number;
977
1087
  };
978
1088
  }
979
- export interface SummarizationOptions {
1089
+ export interface SummarizationOptions<TProviderOptions extends object = Record<string, unknown>> {
980
1090
  model: string;
981
1091
  text: string;
982
1092
  maxLength?: number;
983
1093
  style?: 'bullet-points' | 'paragraph' | 'concise';
984
1094
  focus?: Array<string>;
1095
+ /** Provider-specific options forwarded by the summarize() activity. */
1096
+ modelOptions?: TProviderOptions;
985
1097
  /**
986
1098
  * Internal logger threaded from the summarize() entry point. Adapters must
987
1099
  * call logger.request() before the SDK call and logger.errors() in catch blocks.
@@ -1002,7 +1114,7 @@ export interface SummarizationResult {
1002
1114
  * Options for image generation.
1003
1115
  * These are the common options supported across providers.
1004
1116
  */
1005
- export interface ImageGenerationOptions<TProviderOptions extends object = object, TSize extends string = string> {
1117
+ export interface ImageGenerationOptions<TProviderOptions extends object = object, TSize extends string | undefined = string> {
1006
1118
  /** The model to use for image generation */
1007
1119
  model: string;
1008
1120
  /** Text description of the desired image(s) */
@@ -1110,7 +1222,7 @@ export interface AudioGenerationResult {
1110
1222
  *
1111
1223
  * @experimental Video generation is an experimental feature and may change.
1112
1224
  */
1113
- export interface VideoGenerationOptions<TProviderOptions extends object = object, TSize extends string = string> {
1225
+ export interface VideoGenerationOptions<TProviderOptions extends object = object, TSize extends string | undefined = string> {
1114
1226
  /** The model to use for video generation */
1115
1227
  model: string;
1116
1228
  /** Text description of the desired video */
@@ -0,0 +1,44 @@
1
+ import { ContentPart, UIMessage } from '../types.js';
2
+ type AGUITextInputContent = {
3
+ type: 'text';
4
+ text: string;
5
+ };
6
+ type AGUIInputContent = AGUITextInputContent | (ContentPart & {
7
+ type: 'image' | 'audio' | 'video' | 'document';
8
+ });
9
+ type AGUIToolCallMirror = {
10
+ id: string;
11
+ type: 'function';
12
+ function: {
13
+ name: string;
14
+ arguments: string;
15
+ };
16
+ };
17
+ type AGUIToolMessage = {
18
+ role: 'tool';
19
+ id: string;
20
+ toolCallId: string;
21
+ content: string;
22
+ error?: string;
23
+ };
24
+ type AGUIReasoningMessage = {
25
+ role: 'reasoning';
26
+ id: string;
27
+ content: string;
28
+ };
29
+ type WireAnchorMessage = UIMessage & {
30
+ content?: string | Array<AGUIInputContent>;
31
+ toolCalls?: Array<AGUIToolCallMirror>;
32
+ };
33
+ export type WireMessage = WireAnchorMessage | AGUIToolMessage | AGUIReasoningMessage;
34
+ /**
35
+ * Serialize TanStack `UIMessage`s into the AG-UI `RunAgentInput.messages`
36
+ * wire shape. Each anchor (system/user/assistant) carries the canonical
37
+ * `parts` array verbatim plus AG-UI mirror fields (`content`, `toolCalls`)
38
+ * so AG-UI Zod parsing succeeds. Tool results and thinking parts on
39
+ * assistant messages are additionally emitted as fan-out
40
+ * `{role:'tool',...}` and `{role:'reasoning',...}` entries for strict
41
+ * AG-UI server consumers.
42
+ */
43
+ export declare function uiMessagesToWire(messages: Array<UIMessage>): Array<WireMessage>;
44
+ export {};