@tanstack/ai 0.23.1 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/activities/chat/adapter.d.ts +3 -1
- package/dist/esm/activities/chat/adapter.js.map +1 -1
- package/dist/esm/activities/chat/index.d.ts +33 -9
- package/dist/esm/activities/chat/index.js +19 -9
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/messages.js +2 -1
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/middleware/compose.d.ts +14 -14
- package/dist/esm/activities/chat/middleware/compose.js.map +1 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +21 -21
- package/dist/esm/activities/chat/runtime-context-types.d.ts +43 -0
- package/dist/esm/activities/chat/stream/message-updaters.d.ts +2 -2
- package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +1 -0
- package/dist/esm/activities/chat/stream/processor.js +35 -12
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +15 -5
- package/dist/esm/activities/chat/tools/tool-calls.js +59 -19
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-definition.d.ts +12 -8
- package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
- package/dist/esm/activities/error-payload.d.ts +26 -0
- package/dist/esm/activities/error-payload.js +12 -1
- package/dist/esm/activities/error-payload.js.map +1 -1
- package/dist/esm/activities/generateAudio/index.js +9 -0
- package/dist/esm/activities/generateAudio/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/index.js +9 -0
- package/dist/esm/activities/generateSpeech/index.js.map +1 -1
- package/dist/esm/adapter-internals.d.ts +1 -1
- package/dist/esm/adapter-internals.js +3 -2
- package/dist/esm/client.d.ts +1 -1
- package/dist/esm/client.js +3 -1
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +9 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tool-registry.d.ts +7 -7
- package/dist/esm/tool-registry.js +1 -1
- package/dist/esm/tool-registry.js.map +1 -1
- package/dist/esm/types.d.ts +56 -59
- package/dist/esm/utilities/ag-ui-wire.js +1 -1
- package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
- package/dist/esm/utilities/chat-params.d.ts +8 -3
- package/dist/esm/utilities/chat-params.js +6 -2
- package/dist/esm/utilities/chat-params.js.map +1 -1
- package/dist/esm/utilities/tool-result.d.ts +21 -0
- package/dist/esm/utilities/tool-result.js +37 -0
- package/dist/esm/utilities/tool-result.js.map +1 -0
- package/dist/esm/utilities/usage.d.ts +31 -0
- package/dist/esm/utilities/usage.js +11 -0
- package/dist/esm/utilities/usage.js.map +1 -0
- package/package.json +2 -2
- package/src/activities/chat/adapter.ts +3 -0
- package/src/activities/chat/index.ts +219 -47
- package/src/activities/chat/messages.ts +2 -1
- package/src/activities/chat/middleware/compose.ts +23 -17
- package/src/activities/chat/middleware/types.ts +21 -21
- package/src/activities/chat/runtime-context-types.ts +68 -0
- package/src/activities/chat/stream/message-updaters.ts +2 -1
- package/src/activities/chat/stream/processor.ts +48 -8
- package/src/activities/chat/tools/tool-calls.ts +138 -43
- package/src/activities/chat/tools/tool-definition.ts +25 -31
- package/src/activities/error-payload.ts +44 -0
- package/src/activities/generateAudio/index.ts +10 -0
- package/src/activities/generateSpeech/index.ts +10 -0
- package/src/adapter-internals.ts +4 -1
- package/src/client.ts +5 -1
- package/src/index.ts +10 -0
- package/src/tool-registry.ts +16 -14
- package/src/types.ts +118 -79
- package/src/utilities/ag-ui-wire.ts +4 -1
- package/src/utilities/chat-params.ts +22 -7
- package/src/utilities/tool-result.ts +60 -0
- package/src/utilities/usage.ts +41 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DefaultMessageMetadataByModality, JSONSchema, Modality, StreamChunk, TextOptions } from '../../types.js';
|
|
1
|
+
import { DefaultMessageMetadataByModality, JSONSchema, Modality, StreamChunk, TextOptions, TokenUsage } from '../../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Configuration for adapter instances
|
|
4
4
|
*/
|
|
@@ -31,6 +31,8 @@ export interface StructuredOutputResult<T = unknown> {
|
|
|
31
31
|
data: T;
|
|
32
32
|
/** The raw text response from the model before parsing */
|
|
33
33
|
rawText: string;
|
|
34
|
+
/** Token usage information (if provided by the adapter) */
|
|
35
|
+
usage?: TokenUsage;
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
38
|
* Text adapter interface with pre-resolved generics.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sources":["../../../../src/activities/chat/adapter.ts"],"sourcesContent":["import type {\n DefaultMessageMetadataByModality,\n JSONSchema,\n Modality,\n StreamChunk,\n TextOptions,\n} from '../../types'\n\n/**\n * Configuration for adapter instances\n */\nexport interface TextAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Options for structured output generation.\n *\n * The internal logger is threaded through `chatOptions.logger` (inherited from\n * `TextOptions`). Adapter implementations must call `logger.request()` before\n * SDK calls, `logger.provider()` for each chunk received, and `logger.errors()`\n * in catch blocks.\n */\nexport interface StructuredOutputOptions<TProviderOptions extends object> {\n /** Text options for the request */\n chatOptions: TextOptions<TProviderOptions>\n /** JSON Schema for structured output - already converted from Zod in the ai layer */\n outputSchema: JSONSchema\n}\n\n/**\n * Result from structured output generation\n */\nexport interface StructuredOutputResult<T = unknown> {\n /** The parsed data conforming to the schema */\n data: T\n /** The raw text response from the model before parsing */\n rawText: string\n}\n\n/**\n * Text adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'gpt-4o')\n * - TProviderOptions: Provider-specific options for this model (already resolved)\n * - TInputModalities: Supported input modalities for this model (already resolved)\n * - TMessageMetadata: Metadata types for content parts (already resolved)\n * - TToolCapabilities: Tuple of tool-kind strings supported by this model, resolved from `supports.tools`\n * - TToolCallMetadata: Metadata type that round-trips with tool calls (e.g. Gemini's `thoughtSignature`)\n * - TSystemPromptMetadata: Provider-typed metadata accepted on each\n * `systemPrompts[i]` entry (e.g. Anthropic `cache_control`). Defaults to\n * `never` — adapters without per-prompt metadata reject the `metadata`\n * field at the call site.\n */\nexport interface TextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> {\n /** Discriminator for adapter kind */\n readonly kind: 'text'\n /** Provider name identifier (e.g., 'openai', 'anthropic') */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n /**\n * Stream text completions from the model\n */\n chatStream: (\n options: TextOptions<TProviderOptions>,\n ) => AsyncIterable<StreamChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * This method uses stream: false and sends the JSON schema to the provider\n * to ensure the response conforms to the expected structure.\n *\n * @param options - Structured output options containing chat options and JSON schema\n * @returns Promise with the raw data (validation is done in the chat function)\n */\n structuredOutput: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => Promise<StructuredOutputResult<unknown>>\n\n /**\n * Stream structured output using the provider's native streaming structured\n * output API (stream + response_format json_schema in a single request).\n *\n * Optional — adapters without native streaming JSON omit this method and the\n * activity layer synthesizes a stream around the non-streaming\n * `structuredOutput` call.\n *\n * Implementations must emit standard AG-UI lifecycle events (RUN_STARTED,\n * TEXT_MESSAGE_*, RUN_FINISHED) carrying raw JSON text deltas, plus a final\n * `CUSTOM` event named `structured-output.complete` whose `value` is\n * `{ object, raw, reasoning? }`.\n */\n structuredOutputStream?: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => AsyncIterable<StreamChunk>\n\n /**\n * Declares whether the adapter supports combining `tools` and a\n * schema-constrained final answer in a single streaming request.\n *\n * When `true`, the engine wires `outputSchema` into the regular\n * `chatStream()` call and skips the separate `runStructuredFinalization`\n * round-trip. The model's natural final turn carries the\n * schema-constrained JSON text and the engine harvests it from the agent\n * loop's accumulated content.\n *\n * When `false`, `undefined`, or the method is omitted, the engine runs\n * the agent loop without `outputSchema` and then issues a separate\n * `structuredOutput` / `structuredOutputStream` call against the JSON\n * schema for finalization (the legacy path).\n *\n * The method receives the per-call `modelOptions` so providers whose\n * support depends on the resolved upstream model (e.g. OpenRouter) can\n * answer per-request. Most adapters can return a constant.\n */\n supportsCombinedToolsAndSchema?: (\n modelOptions?: TProviderOptions | undefined,\n ) => boolean\n}\n\n/**\n * A TextAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyTextAdapter = TextAdapter<any, any, any, any, any, any, any>\n\n/**\n * Abstract base class for text adapters.\n * Extend this class to implement a text adapter for a specific provider.\n *\n * Generic parameters match TextAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseTextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> implements TextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n TMessageMetadataByModality,\n TToolCapabilities,\n TToolCallMetadata,\n TSystemPromptMetadata\n> {\n readonly kind = 'text' as const\n abstract readonly name: string\n readonly model: TModel\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n protected config: TextAdapterConfig\n\n constructor(config: TextAdapterConfig = {}, model: TModel) {\n this.config = config\n this.model = model\n }\n\n abstract chatStream(\n options: TextOptions<TProviderOptions>,\n ): AsyncIterable<StreamChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * Concrete implementations should override this to use provider-specific structured output.\n */\n abstract structuredOutput(\n options: StructuredOutputOptions<TProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"adapter.js","sources":["../../../../src/activities/chat/adapter.ts"],"sourcesContent":["import type {\n DefaultMessageMetadataByModality,\n JSONSchema,\n Modality,\n StreamChunk,\n TextOptions,\n TokenUsage,\n} from '../../types'\n\n/**\n * Configuration for adapter instances\n */\nexport interface TextAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Options for structured output generation.\n *\n * The internal logger is threaded through `chatOptions.logger` (inherited from\n * `TextOptions`). Adapter implementations must call `logger.request()` before\n * SDK calls, `logger.provider()` for each chunk received, and `logger.errors()`\n * in catch blocks.\n */\nexport interface StructuredOutputOptions<TProviderOptions extends object> {\n /** Text options for the request */\n chatOptions: TextOptions<TProviderOptions>\n /** JSON Schema for structured output - already converted from Zod in the ai layer */\n outputSchema: JSONSchema\n}\n\n/**\n * Result from structured output generation\n */\nexport interface StructuredOutputResult<T = unknown> {\n /** The parsed data conforming to the schema */\n data: T\n /** The raw text response from the model before parsing */\n rawText: string\n /** Token usage information (if provided by the adapter) */\n usage?: TokenUsage\n}\n\n/**\n * Text adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'gpt-4o')\n * - TProviderOptions: Provider-specific options for this model (already resolved)\n * - TInputModalities: Supported input modalities for this model (already resolved)\n * - TMessageMetadata: Metadata types for content parts (already resolved)\n * - TToolCapabilities: Tuple of tool-kind strings supported by this model, resolved from `supports.tools`\n * - TToolCallMetadata: Metadata type that round-trips with tool calls (e.g. Gemini's `thoughtSignature`)\n * - TSystemPromptMetadata: Provider-typed metadata accepted on each\n * `systemPrompts[i]` entry (e.g. Anthropic `cache_control`). Defaults to\n * `never` — adapters without per-prompt metadata reject the `metadata`\n * field at the call site.\n */\nexport interface TextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> {\n /** Discriminator for adapter kind */\n readonly kind: 'text'\n /** Provider name identifier (e.g., 'openai', 'anthropic') */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n /**\n * Stream text completions from the model\n */\n chatStream: (\n options: TextOptions<TProviderOptions>,\n ) => AsyncIterable<StreamChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * This method uses stream: false and sends the JSON schema to the provider\n * to ensure the response conforms to the expected structure.\n *\n * @param options - Structured output options containing chat options and JSON schema\n * @returns Promise with the raw data (validation is done in the chat function)\n */\n structuredOutput: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => Promise<StructuredOutputResult<unknown>>\n\n /**\n * Stream structured output using the provider's native streaming structured\n * output API (stream + response_format json_schema in a single request).\n *\n * Optional — adapters without native streaming JSON omit this method and the\n * activity layer synthesizes a stream around the non-streaming\n * `structuredOutput` call.\n *\n * Implementations must emit standard AG-UI lifecycle events (RUN_STARTED,\n * TEXT_MESSAGE_*, RUN_FINISHED) carrying raw JSON text deltas, plus a final\n * `CUSTOM` event named `structured-output.complete` whose `value` is\n * `{ object, raw, reasoning? }`.\n */\n structuredOutputStream?: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => AsyncIterable<StreamChunk>\n\n /**\n * Declares whether the adapter supports combining `tools` and a\n * schema-constrained final answer in a single streaming request.\n *\n * When `true`, the engine wires `outputSchema` into the regular\n * `chatStream()` call and skips the separate `runStructuredFinalization`\n * round-trip. The model's natural final turn carries the\n * schema-constrained JSON text and the engine harvests it from the agent\n * loop's accumulated content.\n *\n * When `false`, `undefined`, or the method is omitted, the engine runs\n * the agent loop without `outputSchema` and then issues a separate\n * `structuredOutput` / `structuredOutputStream` call against the JSON\n * schema for finalization (the legacy path).\n *\n * The method receives the per-call `modelOptions` so providers whose\n * support depends on the resolved upstream model (e.g. OpenRouter) can\n * answer per-request. Most adapters can return a constant.\n */\n supportsCombinedToolsAndSchema?: (\n modelOptions?: TProviderOptions | undefined,\n ) => boolean\n}\n\n/**\n * A TextAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyTextAdapter = TextAdapter<any, any, any, any, any, any, any>\n\n/**\n * Abstract base class for text adapters.\n * Extend this class to implement a text adapter for a specific provider.\n *\n * Generic parameters match TextAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseTextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> implements TextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n TMessageMetadataByModality,\n TToolCapabilities,\n TToolCallMetadata,\n TSystemPromptMetadata\n> {\n readonly kind = 'text' as const\n abstract readonly name: string\n readonly model: TModel\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n protected config: TextAdapterConfig\n\n constructor(config: TextAdapterConfig = {}, model: TModel) {\n this.config = config\n this.model = model\n }\n\n abstract chatStream(\n options: TextOptions<TProviderOptions>,\n ): AsyncIterable<StreamChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * Concrete implementations should override this to use provider-specific structured output.\n */\n abstract structuredOutput(\n options: StructuredOutputOptions<TProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"names":[],"mappings":"AAqKO,MAAe,gBAgBpB;AAAA,EACS,OAAO;AAAA,EAEP;AAAA,EAYC;AAAA,EAEV,YAAY,SAA4B,CAAA,GAAI,OAAe;AACzD,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AAAA,EAcU,aAAqB;AAC7B,WAAO,GAAG,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC;AAAA,EAC9E;AACF;"}
|
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
import { AnyTextAdapter } from './adapter.js';
|
|
2
|
-
import { ConstrainedModelMessage, InferSchemaType, ModelMessage, SchemaInput, StreamChunk, StructuredOutputStream, TextOptions,
|
|
2
|
+
import { AnyTool, ConstrainedModelMessage, InferSchemaType, ModelMessage, SchemaInput, StreamChunk, StructuredOutputStream, TextOptions, UIMessage } from '../../types.js';
|
|
3
3
|
import { ChatMiddleware } from './middleware/types.js';
|
|
4
4
|
import { SystemPrompt } from '../../system-prompts.js';
|
|
5
5
|
import { DebugOption } from '../../logger/types.js';
|
|
6
6
|
import { ProviderTool } from '../../tools/provider-tool.js';
|
|
7
|
+
import { ContextFromMiddleware, ContextFromTool, DefinedContext, MergeContext, UnionToIntersection } from './runtime-context-types.js';
|
|
7
8
|
/** The adapter kind this activity handles */
|
|
8
9
|
export declare const kind: "text";
|
|
10
|
+
type AnyRuntimeTool = AnyTool;
|
|
11
|
+
type ContextFromConsumer<T> = ContextFromTool<T> | ContextFromMiddleware<T>;
|
|
12
|
+
type RequiredContextFromConsumerUnion<T> = T extends unknown ? undefined extends ContextFromConsumer<T> ? never : ContextFromConsumer<T> : never;
|
|
13
|
+
type ContextFromConsumerUnion<T> = [
|
|
14
|
+
UnionToIntersection<DefinedContext<ContextFromConsumer<T>>>
|
|
15
|
+
] extends [never] ? never : [RequiredContextFromConsumerUnion<T>] extends [never] ? UnionToIntersection<DefinedContext<ContextFromConsumer<T>>> | undefined : UnionToIntersection<DefinedContext<ContextFromConsumer<T>>>;
|
|
16
|
+
type ContextFromArray<T> = T extends readonly [infer THead, ...infer TTail] ? MergeContext<ContextFromConsumer<THead>, ContextFromArray<TTail>> : T extends ReadonlyArray<infer TItem> ? ContextFromConsumerUnion<TItem> : never;
|
|
17
|
+
type ContextFromInputs<TTools, TMiddleware> = MergeContext<ContextFromArray<NonNullable<TTools>>, ContextFromArray<NonNullable<TMiddleware>>>;
|
|
18
|
+
type InferredContext<TTools, TMiddleware> = [
|
|
19
|
+
ContextFromInputs<TTools, TMiddleware>
|
|
20
|
+
] extends [never] ? unknown : ContextFromInputs<TTools, TMiddleware>;
|
|
21
|
+
type RequiredContextFromInputs<TTools, TMiddleware> = [
|
|
22
|
+
ContextFromInputs<TTools, TMiddleware>
|
|
23
|
+
] extends [never] ? {
|
|
24
|
+
context?: unknown;
|
|
25
|
+
} : undefined extends ContextFromInputs<TTools, TMiddleware> ? {
|
|
26
|
+
context?: ContextFromInputs<TTools, TMiddleware>;
|
|
27
|
+
} : {
|
|
28
|
+
context: ContextFromInputs<TTools, TMiddleware>;
|
|
29
|
+
};
|
|
30
|
+
type TextActivityOptionsWithContext<TAdapter extends AnyTextAdapter, TSchema extends SchemaInput | undefined, TStream extends boolean, TTools extends TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'], TMiddleware extends TextActivityOptions<TAdapter, TSchema, TStream, any>['middleware']> = Omit<TextActivityOptions<TAdapter, TSchema, TStream, any>, 'tools' | 'middleware' | 'context'> & {
|
|
31
|
+
tools?: TTools;
|
|
32
|
+
middleware?: TMiddleware;
|
|
33
|
+
} & RequiredContextFromInputs<TTools, TMiddleware>;
|
|
9
34
|
/**
|
|
10
35
|
* Options for the text activity.
|
|
11
36
|
* Types are extracted directly from the adapter (which has pre-resolved generics).
|
|
@@ -14,7 +39,7 @@ export declare const kind: "text";
|
|
|
14
39
|
* @template TSchema - Optional Standard Schema for structured output
|
|
15
40
|
* @template TStream - Whether to stream the output (default: true)
|
|
16
41
|
*/
|
|
17
|
-
export interface TextActivityOptions<TAdapter extends AnyTextAdapter, TSchema extends SchemaInput | undefined, TStream extends boolean> {
|
|
42
|
+
export interface TextActivityOptions<TAdapter extends AnyTextAdapter, TSchema extends SchemaInput | undefined, TStream extends boolean, TContext = unknown> {
|
|
18
43
|
/** The text adapter to use (created by a provider function like openaiText('gpt-4o')) */
|
|
19
44
|
adapter: TAdapter;
|
|
20
45
|
/**
|
|
@@ -49,7 +74,7 @@ export interface TextActivityOptions<TAdapter extends AnyTextAdapter, TSchema ex
|
|
|
49
74
|
* `supports.tools` list. Passing an unsupported tool produces a
|
|
50
75
|
* compile-time error on the array element.
|
|
51
76
|
*/
|
|
52
|
-
tools?: Array<(
|
|
77
|
+
tools?: Array<(AnyRuntimeTool & {
|
|
53
78
|
readonly '~toolKind'?: never;
|
|
54
79
|
}) | ProviderTool<string, TAdapter['~types']['toolCapabilities'][number]>> | undefined;
|
|
55
80
|
/** Controls the randomness of the output. Higher values make output more random. Range: [0.0, 2.0] */
|
|
@@ -127,12 +152,11 @@ export interface TextActivityOptions<TAdapter extends AnyTextAdapter, TSchema ex
|
|
|
127
152
|
* })
|
|
128
153
|
* ```
|
|
129
154
|
*/
|
|
130
|
-
middleware?: Array<ChatMiddleware
|
|
155
|
+
middleware?: Array<ChatMiddleware<TContext>>;
|
|
131
156
|
/**
|
|
132
|
-
*
|
|
133
|
-
* Can be used to pass request-scoped data (e.g., user ID, request context).
|
|
157
|
+
* Runtime context value passed to middleware hooks and server tools.
|
|
134
158
|
*/
|
|
135
|
-
context?:
|
|
159
|
+
context?: TContext;
|
|
136
160
|
/**
|
|
137
161
|
* Enable debug logging. Pass `true` to enable all categories with the default
|
|
138
162
|
* console logger, `false` to silence everything, or a `DebugConfig` object for
|
|
@@ -154,7 +178,7 @@ export interface TextActivityOptions<TAdapter extends AnyTextAdapter, TSchema ex
|
|
|
154
178
|
* const stream = chat({ ...chatOptions, messages })
|
|
155
179
|
* ```
|
|
156
180
|
*/
|
|
157
|
-
export declare function createChatOptions<TAdapter extends AnyTextAdapter, TSchema extends SchemaInput | undefined = undefined, TStream extends boolean = true>(options:
|
|
181
|
+
export declare function createChatOptions<TAdapter extends AnyTextAdapter, TSchema extends SchemaInput | undefined = undefined, TStream extends boolean = true, const TTools extends TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'], const TMiddleware extends TextActivityOptions<TAdapter, TSchema, TStream, any>['middleware'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['middleware']>(options: TextActivityOptionsWithContext<TAdapter, TSchema, TStream, TTools, TMiddleware>): TextActivityOptions<TAdapter, TSchema, TStream, InferredContext<TTools, TMiddleware>>;
|
|
158
182
|
/**
|
|
159
183
|
* Result type for the text activity.
|
|
160
184
|
* - If outputSchema is provided AND stream is explicitly true:
|
|
@@ -233,6 +257,6 @@ export type TextActivityResult<TSchema extends SchemaInput | undefined, TStream
|
|
|
233
257
|
* // result is { summary: string, keyPoints: string[] }
|
|
234
258
|
* ```
|
|
235
259
|
*/
|
|
236
|
-
export declare function chat<TAdapter extends AnyTextAdapter, TSchema extends SchemaInput | undefined = undefined, TStream extends boolean = boolean>(options:
|
|
260
|
+
export declare function chat<TAdapter extends AnyTextAdapter, TSchema extends SchemaInput | undefined = undefined, TStream extends boolean = boolean, const TTools extends TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'], const TMiddleware extends TextActivityOptions<TAdapter, TSchema, TStream, any>['middleware'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['middleware']>(options: TextActivityOptionsWithContext<TAdapter, TSchema, TStream, TTools, TMiddleware>): TextActivityResult<TSchema, TStream>;
|
|
237
261
|
export type { TextAdapter, TextAdapterConfig, StructuredOutputOptions, StructuredOutputResult, } from './adapter.js';
|
|
238
262
|
export { BaseTextAdapter } from './adapter.js';
|
|
@@ -2,6 +2,7 @@ import { devtoolsMiddleware } from "@tanstack/ai-event-client";
|
|
|
2
2
|
import { stripToSpecMiddleware } from "../../strip-to-spec-middleware.js";
|
|
3
3
|
import { streamToText } from "../../stream-to-response.js";
|
|
4
4
|
import { resolveDebugOption } from "../../logger/resolve.js";
|
|
5
|
+
import { normalizeToolResult } from "../../utilities/tool-result.js";
|
|
5
6
|
import { LazyToolManager } from "./tools/lazy-tool-manager.js";
|
|
6
7
|
import { ToolCallManager, MiddlewareAbortError, executeToolCalls } from "./tools/tool-calls.js";
|
|
7
8
|
import { convertSchemaToJsonSchema, isStandardSchema, parseWithStandardSchema } from "./tools/schema-converter.js";
|
|
@@ -567,7 +568,8 @@ class TextEngine {
|
|
|
567
568
|
info
|
|
568
569
|
);
|
|
569
570
|
}
|
|
570
|
-
}
|
|
571
|
+
},
|
|
572
|
+
this.middlewareCtx.context
|
|
571
573
|
);
|
|
572
574
|
const executionResult = yield* this.drainToolCallGenerator(generator);
|
|
573
575
|
if (this.isMiddlewareAborted()) {
|
|
@@ -697,7 +699,8 @@ class TextEngine {
|
|
|
697
699
|
info
|
|
698
700
|
);
|
|
699
701
|
}
|
|
700
|
-
}
|
|
702
|
+
},
|
|
703
|
+
this.middlewareCtx.context
|
|
701
704
|
);
|
|
702
705
|
const executionResult = yield* this.drainToolCallGenerator(generator);
|
|
703
706
|
this.middlewareCtx.phase = "afterTools";
|
|
@@ -798,10 +801,14 @@ class TextEngine {
|
|
|
798
801
|
for (const message of this.messages) {
|
|
799
802
|
if (message.role === "tool" && message.toolCallId) {
|
|
800
803
|
let output;
|
|
801
|
-
|
|
802
|
-
output = JSON.parse(message.content);
|
|
803
|
-
} catch {
|
|
804
|
+
if (Array.isArray(message.content)) {
|
|
804
805
|
output = message.content;
|
|
806
|
+
} else {
|
|
807
|
+
try {
|
|
808
|
+
output = JSON.parse(message.content);
|
|
809
|
+
} catch {
|
|
810
|
+
output = message.content;
|
|
811
|
+
}
|
|
805
812
|
}
|
|
806
813
|
if (output && typeof output === "object" && output.pendingExecution === true) {
|
|
807
814
|
continue;
|
|
@@ -852,7 +859,8 @@ class TextEngine {
|
|
|
852
859
|
buildToolResultChunks(results, finishEvent, argsMap) {
|
|
853
860
|
const chunks = [];
|
|
854
861
|
for (const result of results) {
|
|
855
|
-
const content =
|
|
862
|
+
const content = normalizeToolResult(result.result);
|
|
863
|
+
const wireContent = typeof content === "string" ? content : JSON.stringify(content);
|
|
856
864
|
if (argsMap) {
|
|
857
865
|
chunks.push({
|
|
858
866
|
type: "TOOL_CALL_START",
|
|
@@ -879,7 +887,8 @@ class TextEngine {
|
|
|
879
887
|
toolCallId: result.toolCallId,
|
|
880
888
|
toolCallName: result.toolName,
|
|
881
889
|
toolName: result.toolName,
|
|
882
|
-
result:
|
|
890
|
+
result: wireContent,
|
|
891
|
+
...result.state !== void 0 && { state: result.state }
|
|
883
892
|
});
|
|
884
893
|
chunks.push({
|
|
885
894
|
type: "TOOL_CALL_RESULT",
|
|
@@ -887,8 +896,9 @@ class TextEngine {
|
|
|
887
896
|
model: finishEvent.model,
|
|
888
897
|
messageId: this.createId("tool-result"),
|
|
889
898
|
toolCallId: result.toolCallId,
|
|
890
|
-
content,
|
|
891
|
-
role: "tool"
|
|
899
|
+
content: wireContent,
|
|
900
|
+
role: "tool",
|
|
901
|
+
...result.state !== void 0 && { state: result.state }
|
|
892
902
|
});
|
|
893
903
|
const placeholderIdx = this.messages.findIndex((m) => {
|
|
894
904
|
if (m.role !== "tool" || m.toolCallId !== result.toolCallId) {
|