diff --git a/.changeset/fluffy-snails-hide.md b/.changeset/fluffy-snails-hide.md new file mode 100644 index 000000000000..2b320af424a1 --- /dev/null +++ b/.changeset/fluffy-snails-hide.md @@ -0,0 +1,7 @@ +--- +'@ai-sdk/provider-utils': patch +'@ai-sdk/ui-utils': patch +'ai': patch +--- + +chore (core): rename CoreTool to Tool diff --git a/content/docs/03-ai-sdk-core/05-generating-text.mdx b/content/docs/03-ai-sdk-core/05-generating-text.mdx index e83fe4dc86ff..faf95289fae4 100644 --- a/content/docs/03-ai-sdk-core/05-generating-text.mdx +++ b/content/docs/03-ai-sdk-core/05-generating-text.mdx @@ -241,7 +241,7 @@ all text to uppercase: ```ts const upperCaseTransform = - >() => + () => (options: { tools: TOOLS; stopStream: () => void }) => new TransformStream, TextStreamPart>({ transform(chunk, controller) { @@ -263,7 +263,7 @@ and all callbacks are invoked. ```ts const stopWordTransform = - >() => + () => ({ stopStream }: { stopStream: () => void }) => new TransformStream, TextStreamPart>({ // note: this is a simplified transformation for testing; diff --git a/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx b/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx index ced60731a3d9..033d21605e19 100644 --- a/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +++ b/content/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx @@ -304,18 +304,18 @@ To enable this, the AI SDK provides several helper types for tools, tool calls, You can use them to strongly type your variables, function parameters, and return types in parts of the code that are not directly related to `streamText` or `generateText`. -Each tool call is typed with `CoreToolCall`, depending +Each tool call is typed with `ToolCall`, depending on the tool that has been invoked. -Similarly, the tool results are typed with `CoreToolResult`. +Similarly, the tool results are typed with `ToolResult`. -The tools in `streamText` and `generateText` are defined as a `Record`. -The type inference helpers `CoreToolCallUnion>` -and `CoreToolResultUnion>` can be used to +The tools in `streamText` and `generateText` are defined as a `ToolSet`. +The type inference helpers `ToolCallUnion` +and `ToolResultUnion` can be used to extract the tool call and tool result types from the tools. ```ts highlight="18-19,23-24" import { openai } from '@ai-sdk/openai'; -import { CoreToolCallUnion, CoreToolResultUnion, generateText, tool } from 'ai'; +import { ToolCallUnion, ToolResultUnion, generateText, tool } from 'ai'; import { z } from 'zod'; const myToolSet = { @@ -331,8 +331,8 @@ const myToolSet = { }), }; -type MyToolCall = CoreToolCallUnion; -type MyToolResult = CoreToolResultUnion; +type MyToolCall = ToolCallUnion; +type MyToolResult = ToolResultUnion; async function generateSomething(prompt: string): Promise<{ text: string; diff --git a/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx b/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx index 56841edf8e14..8effa770782f 100644 --- a/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx @@ -260,12 +260,12 @@ To see `generateText` in action, check out [these examples](#examples). }, { name: 'tools', - type: 'Record', + type: 'ToolSet', description: 'Tools that are accessible to and can be called by the model. The model needs to support calling tools.', properties: [ { - type: 'CoreTool', + type: 'Tool', parameters: [ { name: 'description', diff --git a/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx b/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx index 737feaa9f744..7fab559aed3a 100644 --- a/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx @@ -262,12 +262,12 @@ To see `streamText` in action, check out [these examples](#examples). }, { name: 'tools', - type: 'Record', + type: 'ToolSet', description: 'Tools that are accessible to and can be called by the model. The model needs to support calling tools.', properties: [ { - type: 'CoreTool', + type: 'Tool', parameters: [ { name: 'description', diff --git a/content/docs/07-reference/01-ai-sdk-core/20-tool.mdx b/content/docs/07-reference/01-ai-sdk-core/20-tool.mdx index 5cfda1bfe3ee..6cad42435bb5 100644 --- a/content/docs/07-reference/01-ai-sdk-core/20-tool.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/20-tool.mdx @@ -41,11 +41,11 @@ export const weatherTool = tool({ content={[ { name: 'tool', - type: 'CoreTool', + type: 'Tool', description: 'The tool definition.', properties: [ { - type: 'CoreTool', + type: 'Tool', parameters: [ { name: 'description', diff --git a/content/docs/07-reference/02-ai-sdk-ui/31-convert-to-core-messages.mdx b/content/docs/07-reference/02-ai-sdk-ui/31-convert-to-core-messages.mdx index 32d348115de8..b381e43e7b67 100644 --- a/content/docs/07-reference/02-ai-sdk-ui/31-convert-to-core-messages.mdx +++ b/content/docs/07-reference/02-ai-sdk-ui/31-convert-to-core-messages.mdx @@ -46,7 +46,7 @@ export async function POST(req: Request) { }, { name: 'options', - type: '{ tools?: Record }', + type: '{ tools?: ToolSet }', description: 'Optional configuration object. Provide tools to enable multi-modal tool responses.', }, diff --git a/content/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx b/content/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx index c1d7ee80995d..eda703ccb6f6 100644 --- a/content/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +++ b/content/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx @@ -332,7 +332,7 @@ To see `streamUI` in action, check out [these examples](#examples). }, { name: 'tools', - type: 'Record', + type: 'ToolSet', description: 'Tools that are accessible to and can be called by the model.', properties: [ diff --git a/content/docs/07-reference/03-ai-sdk-rsc/20-render.mdx b/content/docs/07-reference/03-ai-sdk-rsc/20-render.mdx index ad5c20024db1..305fbeaec055 100644 --- a/content/docs/07-reference/03-ai-sdk-rsc/20-render.mdx +++ b/content/docs/07-reference/03-ai-sdk-rsc/20-render.mdx @@ -162,7 +162,7 @@ A helper function to create a streamable UI from LLM providers. This function is }, { name: 'functions', - type: 'Record', + type: 'ToolSet', isOptional: true, description: 'Tools that are accessible to and can be called by the model.', @@ -196,7 +196,7 @@ A helper function to create a streamable UI from LLM providers. This function is }, { name: 'tools', - type: 'Record', + type: 'ToolSet', isOptional: true, description: 'Tools that are accessible to and can be called by the model.', diff --git a/examples/ai-core/src/types/tool-set.ts b/examples/ai-core/src/types/tool-set.ts index c3814d3b908d..ee00f1e0f43e 100644 --- a/examples/ai-core/src/types/tool-set.ts +++ b/examples/ai-core/src/types/tool-set.ts @@ -1,5 +1,5 @@ import { openai } from '@ai-sdk/openai'; -import { CoreToolCallUnion, CoreToolResultUnion, generateText, tool } from 'ai'; +import { ToolCallUnion, ToolResultUnion, generateText, tool } from 'ai'; import { z } from 'zod'; const myToolSet = { @@ -15,8 +15,8 @@ const myToolSet = { }), }; -type MyToolCall = CoreToolCallUnion; -type MyToolResult = CoreToolResultUnion; +type MyToolCall = ToolCallUnion; +type MyToolResult = ToolResultUnion; async function generateSomething(prompt: string): Promise<{ text: string; diff --git a/packages/ai/core/generate-text/generate-text-result.ts b/packages/ai/core/generate-text/generate-text-result.ts index 583cefb7856a..4423a72aabcb 100644 --- a/packages/ai/core/generate-text/generate-text-result.ts +++ b/packages/ai/core/generate-text/generate-text-result.ts @@ -1,5 +1,4 @@ import { CoreAssistantMessage, CoreToolMessage } from '../prompt'; -import { CoreTool } from '../tool/tool'; import { CallWarning, FinishReason, @@ -12,15 +11,13 @@ import { LanguageModelUsage } from '../types/usage'; import { StepResult } from './step-result'; import { ToolCallArray } from './tool-call'; import { ToolResultArray } from './tool-result'; +import { ToolSet } from './tool-set'; /** The result of a `generateText` call. It contains the generated text, the tool calls that were made during the generation, and the results of the tool calls. */ -export interface GenerateTextResult< - TOOLS extends Record, - OUTPUT, -> { +export interface GenerateTextResult { /** The generated text. */ diff --git a/packages/ai/core/generate-text/generate-text.ts b/packages/ai/core/generate-text/generate-text.ts index 9089038878c5..6696f2621bcd 100644 --- a/packages/ai/core/generate-text/generate-text.ts +++ b/packages/ai/core/generate-text/generate-text.ts @@ -17,8 +17,7 @@ import { getTracer } from '../telemetry/get-tracer'; import { recordSpan } from '../telemetry/record-span'; import { selectTelemetryAttributes } from '../telemetry/select-telemetry-attributes'; import { TelemetrySettings } from '../telemetry/telemetry-settings'; -import { CoreTool } from '../tool/tool'; -import { CoreToolChoice, LanguageModel, ProviderMetadata } from '../types'; +import { LanguageModel, ProviderMetadata, ToolChoice } from '../types'; import { addLanguageModelUsage, calculateLanguageModelUsage, @@ -33,6 +32,7 @@ import { toResponseMessages } from './to-response-messages'; import { ToolCallArray } from './tool-call'; import { ToolCallRepairFunction } from './tool-call-repair'; import { ToolResultArray } from './tool-result'; +import { ToolSet } from './tool-set'; const originalGenerateId = createIdGenerator({ prefix: 'aitxt', @@ -92,7 +92,7 @@ If set and supported by the model, calls will generate deterministic results. A result object that contains the generated text, the results of the tool calls, and additional information. */ export async function generateText< - TOOLS extends Record, + TOOLS extends ToolSet, OUTPUT = never, OUTPUT_PARTIAL = never, >({ @@ -134,7 +134,7 @@ The tools that the model can call. The model needs to support calling tools. /** The tool choice strategy. Default: 'auto'. */ - toolChoice?: CoreToolChoice; + toolChoice?: ToolChoice; /** Maximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1. @@ -560,7 +560,7 @@ A function that attempts to repair a tool call that failed to parse. }); } -async function executeTools>({ +async function executeTools({ toolCalls, tools, tracer, @@ -653,7 +653,7 @@ async function executeTools>({ ); } -class DefaultGenerateTextResult, OUTPUT> +class DefaultGenerateTextResult implements GenerateTextResult { readonly text: GenerateTextResult['text']; diff --git a/packages/ai/core/generate-text/index.ts b/packages/ai/core/generate-text/index.ts index 4e63307f0cf0..ec6096808bb5 100644 --- a/packages/ai/core/generate-text/index.ts +++ b/packages/ai/core/generate-text/index.ts @@ -8,12 +8,16 @@ export type { StreamTextTransform } from './stream-text'; export type { StreamTextResult, TextStreamPart } from './stream-text-result'; export type { ToolCallRepairFunction } from './tool-call-repair'; -// TODO 4.1: rename to ToolCall and ToolResult, deprecate old names export type { - ToolCall as CoreToolCall, - ToolCallUnion as CoreToolCallUnion, + CoreToolCall, + CoreToolCallUnion, + ToolCall, + ToolCallUnion, } from './tool-call'; export type { - ToolResult as CoreToolResult, - ToolResultUnion as CoreToolResultUnion, + CoreToolResult, + CoreToolResultUnion, + ToolResult, + ToolResultUnion, } from './tool-result'; +export type { ToolSet } from './tool-set'; diff --git a/packages/ai/core/generate-text/parse-tool-call.ts b/packages/ai/core/generate-text/parse-tool-call.ts index 6b81f3f83f2b..51228ebf8779 100644 --- a/packages/ai/core/generate-text/parse-tool-call.ts +++ b/packages/ai/core/generate-text/parse-tool-call.ts @@ -3,14 +3,14 @@ import { safeParseJSON, safeValidateTypes } from '@ai-sdk/provider-utils'; import { Schema, asSchema } from '@ai-sdk/ui-utils'; import { InvalidToolArgumentsError } from '../../errors/invalid-tool-arguments-error'; import { NoSuchToolError } from '../../errors/no-such-tool-error'; +import { ToolCallRepairError } from '../../errors/tool-call-repair-error'; import { CoreMessage } from '../prompt'; -import { CoreTool } from '../tool'; import { inferParameters } from '../tool/tool'; import { ToolCallUnion } from './tool-call'; import { ToolCallRepairFunction } from './tool-call-repair'; -import { ToolCallRepairError } from '../../errors/tool-call-repair-error'; +import { ToolSet } from './tool-set'; -export async function parseToolCall>({ +export async function parseToolCall({ toolCall, tools, repairToolCall, @@ -68,7 +68,7 @@ export async function parseToolCall>({ } } -async function doParseToolCall>({ +async function doParseToolCall({ toolCall, tools, }: { diff --git a/packages/ai/core/generate-text/run-tools-transformation.ts b/packages/ai/core/generate-text/run-tools-transformation.ts index 7ff171ed95a6..550104a376ff 100644 --- a/packages/ai/core/generate-text/run-tools-transformation.ts +++ b/packages/ai/core/generate-text/run-tools-transformation.ts @@ -7,7 +7,6 @@ import { assembleOperationName } from '../telemetry/assemble-operation-name'; import { recordSpan } from '../telemetry/record-span'; import { selectTelemetryAttributes } from '../telemetry/select-telemetry-attributes'; import { TelemetrySettings } from '../telemetry/telemetry-settings'; -import { CoreTool } from '../tool'; import { FinishReason, LanguageModelUsage, @@ -19,10 +18,9 @@ import { parseToolCall } from './parse-tool-call'; import { ToolCallUnion } from './tool-call'; import { ToolCallRepairFunction } from './tool-call-repair'; import { ToolResultUnion } from './tool-result'; +import { ToolSet } from './tool-set'; -export type SingleRequestTextStreamPart< - TOOLS extends Record, -> = +export type SingleRequestTextStreamPart = | { type: 'text-delta'; textDelta: string; @@ -66,7 +64,7 @@ export type SingleRequestTextStreamPart< error: unknown; }; -export function runToolsTransformation>({ +export function runToolsTransformation({ tools, generatorStream, toolCallStreaming, diff --git a/packages/ai/core/generate-text/smooth-stream.ts b/packages/ai/core/generate-text/smooth-stream.ts index c328376d9fa5..2f0ef085aee4 100644 --- a/packages/ai/core/generate-text/smooth-stream.ts +++ b/packages/ai/core/generate-text/smooth-stream.ts @@ -1,7 +1,7 @@ import { InvalidArgumentError } from '@ai-sdk/provider'; import { delay as originalDelay } from '@ai-sdk/provider-utils'; -import { CoreTool } from '../tool/tool'; import { TextStreamPart } from './stream-text-result'; +import { ToolSet } from './tool-set'; const CHUNKING_REGEXPS = { word: /\s*\S+\s+/m, @@ -16,7 +16,7 @@ const CHUNKING_REGEXPS = { * * @returns A transform stream that smooths text streaming output. */ -export function smoothStream>({ +export function smoothStream({ delayInMs = 10, chunking = 'word', _internal: { delay = originalDelay } = {}, diff --git a/packages/ai/core/generate-text/step-result.ts b/packages/ai/core/generate-text/step-result.ts index 7c9c9e2e0de6..64f668fdb657 100644 --- a/packages/ai/core/generate-text/step-result.ts +++ b/packages/ai/core/generate-text/step-result.ts @@ -1,5 +1,4 @@ import { CoreAssistantMessage, CoreToolMessage } from '../prompt/message'; -import { CoreTool } from '../tool'; import { CallWarning, FinishReason, @@ -11,6 +10,7 @@ import { import { LanguageModelUsage } from '../types/usage'; import { ToolCallArray } from './tool-call'; import { ToolResultArray } from './tool-result'; +import { ToolSet } from './tool-set'; /** A message that was generated during the generation process. @@ -27,7 +27,7 @@ Message ID generated by the AI SDK. /** * The result of a single step in the generation process. */ -export type StepResult> = { +export type StepResult = { /** The generated text. */ diff --git a/packages/ai/core/generate-text/stream-text-result.ts b/packages/ai/core/generate-text/stream-text-result.ts index af875f4ab367..635f60745fb8 100644 --- a/packages/ai/core/generate-text/stream-text-result.ts +++ b/packages/ai/core/generate-text/stream-text-result.ts @@ -2,7 +2,6 @@ import { ServerResponse } from 'node:http'; import { StreamData } from '../../streams/stream-data'; import { DataStreamWriter } from '../data-stream/data-stream-writer'; import { CoreAssistantMessage, CoreToolMessage } from '../prompt/message'; -import { CoreTool } from '../tool'; import { CallWarning, FinishReason, @@ -16,14 +15,12 @@ import { AsyncIterableStream } from '../util/async-iterable-stream'; import { StepResult } from './step-result'; import { ToolCallUnion } from './tool-call'; import { ToolResultUnion } from './tool-result'; +import { ToolSet } from './tool-set'; /** A result object for accessing different stream types and additional information. */ -export interface StreamTextResult< - TOOLS extends Record, - PARTIAL_OUTPUT, -> { +export interface StreamTextResult { /** Warnings from the model provider (e.g. unsupported settings) for the first step. */ @@ -224,7 +221,7 @@ A stream of partial outputs. It uses the `experimental_output` specification. toTextStreamResponse(init?: ResponseInit): Response; } -export type TextStreamPart> = +export type TextStreamPart = | { type: 'text-delta'; textDelta: string; diff --git a/packages/ai/core/generate-text/stream-text.test.ts b/packages/ai/core/generate-text/stream-text.test.ts index 4dffcd65fe05..0a8dcc8f0d4b 100644 --- a/packages/ai/core/generate-text/stream-text.test.ts +++ b/packages/ai/core/generate-text/stream-text.test.ts @@ -22,11 +22,12 @@ import { MockLanguageModelV1 } from '../test/mock-language-model-v1'; import { createMockServerResponse } from '../test/mock-server-response'; import { MockTracer } from '../test/mock-tracer'; import { mockValues } from '../test/mock-values'; -import { CoreTool, tool } from '../tool/tool'; +import { tool } from '../tool/tool'; import { object, text } from './output'; import { StepResult } from './step-result'; import { streamText } from './stream-text'; import { StreamTextResult, TextStreamPart } from './stream-text-result'; +import { ToolSet } from './tool-set'; function createTestModel({ stream = convertArrayToReadableStream([ @@ -3122,7 +3123,7 @@ describe('streamText', () => { describe('options.transform', () => { describe('with base transformation', () => { const upperCaseTransform = - >() => + () => (options: { tools: TOOLS }) => new TransformStream, TextStreamPart>({ transform(chunk, controller) { @@ -3861,7 +3862,7 @@ describe('streamText', () => { describe('with multiple transformations', () => { const toUppercaseAndAddCommaTransform = - >() => + () => (options: { tools: TOOLS }) => new TransformStream, TextStreamPart>({ transform(chunk, controller) { @@ -3878,7 +3879,7 @@ describe('streamText', () => { }); const omitCommaTransform = - >() => + () => (options: { tools: TOOLS }) => new TransformStream, TextStreamPart>({ transform(chunk, controller) { @@ -3912,7 +3913,7 @@ describe('streamText', () => { describe('with transformation that aborts stream', () => { const stopWordTransform = - >() => + () => ({ stopStream }: { stopStream: () => void }) => new TransformStream, TextStreamPart>({ // note: this is a simplified transformation for testing; diff --git a/packages/ai/core/generate-text/stream-text.ts b/packages/ai/core/generate-text/stream-text.ts index ef46ba8f2d8b..ab17f5922dd7 100644 --- a/packages/ai/core/generate-text/stream-text.ts +++ b/packages/ai/core/generate-text/stream-text.ts @@ -22,12 +22,11 @@ import { getTracer } from '../telemetry/get-tracer'; import { recordSpan } from '../telemetry/record-span'; import { selectTelemetryAttributes } from '../telemetry/select-telemetry-attributes'; import { TelemetrySettings } from '../telemetry/telemetry-settings'; -import { CoreTool } from '../tool'; import { - CoreToolChoice, FinishReason, LanguageModel, LogProbs, + ToolChoice, } from '../types/language-model'; import { LanguageModelResponseMetadata } from '../types/language-model-response-metadata'; import { ProviderMetadata } from '../types/provider-metadata'; @@ -54,6 +53,7 @@ import { toResponseMessages } from './to-response-messages'; import { ToolCallUnion } from './tool-call'; import { ToolCallRepairFunction } from './tool-call-repair'; import { ToolResultUnion } from './tool-result'; +import { ToolSet } from './tool-set'; const originalGenerateId = createIdGenerator({ prefix: 'aitxt', @@ -71,11 +71,10 @@ A transformation that is applied to the stream. @param stopStream - A function that stops the source stream. @param tools - The tools that are accessible to and can be called by the model. The model needs to support calling tools. */ -export type StreamTextTransform> = - (options: { - tools: TOOLS; // for type inference - stopStream: () => void; - }) => TransformStream, TextStreamPart>; +export type StreamTextTransform = (options: { + tools: TOOLS; // for type inference + stopStream: () => void; +}) => TransformStream, TextStreamPart>; /** Generate a text and call tools for a given prompt using a language model. @@ -126,7 +125,7 @@ If set and supported by the model, calls will generate deterministic results. A result object for accessing different stream types and additional information. */ export function streamText< - TOOLS extends Record, + TOOLS extends ToolSet, OUTPUT = never, PARTIAL_OUTPUT = never, >({ @@ -174,7 +173,7 @@ The tools that the model can call. The model needs to support calling tools. /** The tool choice strategy. Default: 'auto'. */ - toolChoice?: CoreToolChoice; + toolChoice?: ToolChoice; /** Maximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1. @@ -321,16 +320,13 @@ Internal. For test use only. May change without notice. }); } -type EnrichedStreamPart< - TOOLS extends Record, - PARTIAL_OUTPUT, -> = { +type EnrichedStreamPart = { part: TextStreamPart; partialOutput: PARTIAL_OUTPUT | undefined; }; function createOutputTransformStream< - TOOLS extends Record, + TOOLS extends ToolSet, OUTPUT, PARTIAL_OUTPUT, >( @@ -406,11 +402,8 @@ function createOutputTransformStream< }); } -class DefaultStreamTextResult< - TOOLS extends Record, - OUTPUT, - PARTIAL_OUTPUT, -> implements StreamTextResult +class DefaultStreamTextResult + implements StreamTextResult { private readonly warningsPromise = new DelayedPromise< Awaited['warnings']> @@ -496,7 +489,7 @@ class DefaultStreamTextResult< prompt: Prompt['prompt']; messages: Prompt['messages']; tools: TOOLS | undefined; - toolChoice: CoreToolChoice | undefined; + toolChoice: ToolChoice | undefined; toolCallStreaming: boolean; transforms: Array>; activeTools: Array | undefined; diff --git a/packages/ai/core/generate-text/to-response-messages.ts b/packages/ai/core/generate-text/to-response-messages.ts index 4eaa4200551c..92d60a583b76 100644 --- a/packages/ai/core/generate-text/to-response-messages.ts +++ b/packages/ai/core/generate-text/to-response-messages.ts @@ -1,13 +1,13 @@ import { ToolResultPart } from '../prompt'; -import { CoreTool } from '../tool/tool'; import { ResponseMessage } from './step-result'; import { ToolCallArray } from './tool-call'; import { ToolResultArray } from './tool-result'; +import { ToolSet } from './tool-set'; /** Converts the result of a `generateText` call to a list of response messages. */ -export function toResponseMessages>({ +export function toResponseMessages({ text = '', tools, toolCalls, diff --git a/packages/ai/core/generate-text/tool-call-repair.ts b/packages/ai/core/generate-text/tool-call-repair.ts index c8cfdffb8f0a..2396584d61f0 100644 --- a/packages/ai/core/generate-text/tool-call-repair.ts +++ b/packages/ai/core/generate-text/tool-call-repair.ts @@ -2,7 +2,7 @@ import { JSONSchema7, LanguageModelV1FunctionToolCall } from '@ai-sdk/provider'; import { InvalidToolArgumentsError } from '../../errors/invalid-tool-arguments-error'; import { NoSuchToolError } from '../../errors/no-such-tool-error'; import { CoreMessage } from '../prompt'; -import { CoreTool } from '../tool'; +import { ToolSet } from './tool-set'; /** * A function that attempts to repair a tool call that failed to parse. @@ -17,12 +17,11 @@ import { CoreTool } from '../tool'; * @param options.parameterSchema - A function that returns the JSON Schema for a tool. * @param options.error - The error that occurred while parsing the tool call. */ -export type ToolCallRepairFunction> = - (options: { - system: string | undefined; - messages: CoreMessage[]; - toolCall: LanguageModelV1FunctionToolCall; - tools: TOOLS; - parameterSchema: (options: { toolName: string }) => JSONSchema7; - error: NoSuchToolError | InvalidToolArgumentsError; - }) => Promise; +export type ToolCallRepairFunction = (options: { + system: string | undefined; + messages: CoreMessage[]; + toolCall: LanguageModelV1FunctionToolCall; + tools: TOOLS; + parameterSchema: (options: { toolName: string }) => JSONSchema7; + error: NoSuchToolError | InvalidToolArgumentsError; +}) => Promise; diff --git a/packages/ai/core/generate-text/tool-call.ts b/packages/ai/core/generate-text/tool-call.ts index 1f01ed2f003a..c6bd3a7d4ae5 100644 --- a/packages/ai/core/generate-text/tool-call.ts +++ b/packages/ai/core/generate-text/tool-call.ts @@ -1,11 +1,11 @@ -import { CoreTool } from '../tool'; import { inferParameters } from '../tool/tool'; import { ValueOf } from '../util/value-of'; +import { ToolSet } from './tool-set'; -export type { ToolCall } from '@ai-sdk/provider-utils'; +export type { CoreToolCall, ToolCall } from '@ai-sdk/provider-utils'; // transforms the tools into a tool call union -export type ToolCallUnion> = ValueOf<{ +export type ToolCallUnion = ValueOf<{ [NAME in keyof TOOLS]: { type: 'tool-call'; toolCallId: string; @@ -14,6 +14,10 @@ export type ToolCallUnion> = ValueOf<{ }; }>; -export type ToolCallArray> = Array< - ToolCallUnion ->; +/** + * @deprecated Use `ToolCallUnion` instead. + */ +// TODO remove in v5 +export type CoreToolCallUnion = ToolCallUnion; + +export type ToolCallArray = Array>; diff --git a/packages/ai/core/generate-text/tool-result.ts b/packages/ai/core/generate-text/tool-result.ts index 9748016c5721..7b13249588bd 100644 --- a/packages/ai/core/generate-text/tool-result.ts +++ b/packages/ai/core/generate-text/tool-result.ts @@ -1,23 +1,23 @@ -import { CoreTool } from '../tool'; import { inferParameters } from '../tool/tool'; import { ValueOf } from '../util/value-of'; +import { ToolSet } from './tool-set'; -export type { ToolResult } from '@ai-sdk/provider-utils'; +export type { CoreToolResult, ToolResult } from '@ai-sdk/provider-utils'; // limits the tools to those with an execute value -type ToToolsWithExecute> = { +type ToToolsWithExecute = { [K in keyof TOOLS as TOOLS[K] extends { execute: any } ? K : never]: TOOLS[K]; }; // limits the tools to those that have execute !== undefined -type ToToolsWithDefinedExecute> = { +type ToToolsWithDefinedExecute = { [K in keyof TOOLS as TOOLS[K]['execute'] extends undefined ? never : K]: TOOLS[K]; }; // transforms the tools into a tool result union -type ToToolResultObject> = ValueOf<{ +type ToToolResultObject = ValueOf<{ [NAME in keyof TOOLS]: { type: 'tool-result'; toolCallId: string; @@ -27,9 +27,16 @@ type ToToolResultObject> = ValueOf<{ }; }>; -export type ToolResultUnion> = - ToToolResultObject>>; +export type ToolResultUnion = ToToolResultObject< + ToToolsWithDefinedExecute> +>; + +/** + * @deprecated Use `ToolResultUnion` instead. + */ +// TODO remove in v5 +export type CoreToolResultUnion = ToolResultUnion; -export type ToolResultArray> = Array< +export type ToolResultArray = Array< ToolResultUnion >; diff --git a/packages/ai/core/generate-text/tool-set.ts b/packages/ai/core/generate-text/tool-set.ts new file mode 100644 index 000000000000..af3c01d1ba8e --- /dev/null +++ b/packages/ai/core/generate-text/tool-set.ts @@ -0,0 +1,3 @@ +import { Tool } from '../tool'; + +export type ToolSet = Record; diff --git a/packages/ai/core/prompt/convert-to-core-messages.ts b/packages/ai/core/prompt/convert-to-core-messages.ts index a172355962a5..b571ceaacca0 100644 --- a/packages/ai/core/prompt/convert-to-core-messages.ts +++ b/packages/ai/core/prompt/convert-to-core-messages.ts @@ -1,5 +1,5 @@ +import { ToolSet } from '../generate-text/tool-set'; import { CoreMessage, ToolCallPart, ToolResultPart } from '../prompt'; -import { CoreTool } from '../tool/tool'; import { attachmentsToParts } from './attachments-to-parts'; import { MessageConversionError } from './message-conversion-error'; import { UIMessage } from './ui-message'; @@ -8,9 +8,10 @@ import { UIMessage } from './ui-message'; Converts an array of messages from useChat into an array of CoreMessages that can be used with the AI core functions (e.g. `streamText`). */ -export function convertToCoreMessages< - TOOLS extends Record = never, ->(messages: Array, options?: { tools?: TOOLS }) { +export function convertToCoreMessages( + messages: Array, + options?: { tools?: TOOLS }, +) { const tools = options?.tools ?? ({} as TOOLS); const coreMessages: CoreMessage[] = []; diff --git a/packages/ai/core/prompt/prepare-tools-and-tool-choice.test.ts b/packages/ai/core/prompt/prepare-tools-and-tool-choice.test.ts index eaf3aa0b9ec9..917f666b4acd 100644 --- a/packages/ai/core/prompt/prepare-tools-and-tool-choice.test.ts +++ b/packages/ai/core/prompt/prepare-tools-and-tool-choice.test.ts @@ -1,8 +1,9 @@ import { z } from 'zod'; -import { CoreTool, tool } from '../tool/tool'; +import { ToolSet } from '../generate-text/tool-set'; +import { Tool, tool } from '../tool/tool'; import { prepareToolsAndToolChoice } from './prepare-tools-and-tool-choice'; -const mockTools: Record = { +const mockTools: ToolSet = { tool1: tool({ description: 'Tool 1 description', parameters: z.object({}), @@ -13,14 +14,14 @@ const mockTools: Record = { }), }; -const mockProviderDefinedTool: CoreTool = { +const mockProviderDefinedTool: Tool = { type: 'provider-defined', id: 'provider.tool-id', args: { key: 'value' }, parameters: z.object({}), }; -const mockToolsWithProviderDefined: Record = { +const mockToolsWithProviderDefined: ToolSet = { ...mockTools, providerTool: mockProviderDefinedTool, }; diff --git a/packages/ai/core/prompt/prepare-tools-and-tool-choice.ts b/packages/ai/core/prompt/prepare-tools-and-tool-choice.ts index 4cf62a241d53..11c05a7c7b29 100644 --- a/packages/ai/core/prompt/prepare-tools-and-tool-choice.ts +++ b/packages/ai/core/prompt/prepare-tools-and-tool-choice.ts @@ -4,19 +4,17 @@ import { LanguageModelV1ToolChoice, } from '@ai-sdk/provider'; import { asSchema } from '@ai-sdk/ui-utils'; -import { CoreTool } from '../tool/tool'; -import { CoreToolChoice } from '../types/language-model'; +import { ToolSet } from '../generate-text'; +import { ToolChoice } from '../types/language-model'; import { isNonEmptyObject } from '../util/is-non-empty-object'; -export function prepareToolsAndToolChoice< - TOOLS extends Record, ->({ +export function prepareToolsAndToolChoice({ tools, toolChoice, activeTools, }: { tools: TOOLS | undefined; - toolChoice: CoreToolChoice | undefined; + toolChoice: ToolChoice | undefined; activeTools: Array | undefined; }): { tools: diff --git a/packages/ai/core/prompt/standardize-prompt.ts b/packages/ai/core/prompt/standardize-prompt.ts index 53d9f674e7a2..1110b0180b4e 100644 --- a/packages/ai/core/prompt/standardize-prompt.ts +++ b/packages/ai/core/prompt/standardize-prompt.ts @@ -1,12 +1,12 @@ import { InvalidPromptError } from '@ai-sdk/provider'; import { safeValidateTypes } from '@ai-sdk/provider-utils'; import { z } from 'zod'; +import { ToolSet } from '../generate-text/tool-set'; +import { convertToCoreMessages } from './convert-to-core-messages'; +import { detectPromptType } from './detect-prompt-type'; import { CoreMessage, coreMessageSchema } from './message'; import { Prompt } from './prompt'; -import { detectPromptType } from './detect-prompt-type'; -import { convertToCoreMessages } from './convert-to-core-messages'; import { UIMessage } from './ui-message'; -import { CoreTool } from '../tool/tool'; export type StandardizedPrompt = { /** @@ -26,7 +26,7 @@ export type StandardizedPrompt = { messages: CoreMessage[]; }; -export function standardizePrompt>({ +export function standardizePrompt({ prompt, tools, }: { diff --git a/packages/ai/core/tool/index.ts b/packages/ai/core/tool/index.ts index 6b043273ebfa..ba0fbb738e40 100644 --- a/packages/ai/core/tool/index.ts +++ b/packages/ai/core/tool/index.ts @@ -1,2 +1,2 @@ export { tool } from './tool'; -export type { CoreTool, ToolExecutionOptions } from './tool'; +export type { CoreTool, Tool, ToolExecutionOptions } from './tool'; diff --git a/packages/ai/core/tool/tool.ts b/packages/ai/core/tool/tool.ts index b03e93a00ddf..d14e492e820d 100644 --- a/packages/ai/core/tool/tool.ts +++ b/packages/ai/core/tool/tool.ts @@ -36,7 +36,7 @@ This enables the language model to generate the input. The tool can also contain an optional execute function for the actual execution function of the tool. */ -export type CoreTool = { +export type Tool = { /** The schema of the input that the tool expects. The language model will use this to generate the input. It is also used to validate the output of the language model. @@ -90,32 +90,41 @@ The arguments for configuring the tool. Must match the expected arguments define } ); +/** + * @deprecated Use `Tool` instead. + */ +// TODO remove in v5 +export type CoreTool = Tool< + PARAMETERS, + RESULT +>; + /** Helper function for inferring the execute args of a tool. */ // Note: special type inference is needed for the execute function args to make sure they are inferred correctly. export function tool( - tool: CoreTool & { + tool: Tool & { execute: ( args: inferParameters, options: ToolExecutionOptions, ) => PromiseLike; }, -): CoreTool & { +): Tool & { execute: ( args: inferParameters, options: ToolExecutionOptions, ) => PromiseLike; }; export function tool( - tool: CoreTool & { + tool: Tool & { execute?: undefined; }, -): CoreTool & { +): Tool & { execute: undefined; }; export function tool( - tool: CoreTool, -): CoreTool { + tool: Tool, +): Tool { return tool; } diff --git a/packages/ai/core/types/index.ts b/packages/ai/core/types/index.ts index 1d3deedd46cb..0aea0780458a 100644 --- a/packages/ai/core/types/index.ts +++ b/packages/ai/core/types/index.ts @@ -14,6 +14,7 @@ export type { LanguageModelV1Prompt, LanguageModelV1StreamPart, LogProbs, + ToolChoice, } from './language-model'; export type { LanguageModelRequestMetadata } from './language-model-request-metadata'; export type { LanguageModelResponseMetadata } from './language-model-response-metadata'; diff --git a/packages/ai/core/types/language-model.ts b/packages/ai/core/types/language-model.ts index e7ce24a52c55..2abfd8f5d87f 100644 --- a/packages/ai/core/types/language-model.ts +++ b/packages/ai/core/types/language-model.ts @@ -65,9 +65,15 @@ Tool choice for the generation. It supports the following settings: - `none`: the model must not call tools - `{ type: 'tool', toolName: string (typed) }`: the model must call the specified tool */ -// TODO 4.1 rename to ToolChoice -export type CoreToolChoice> = +export type ToolChoice> = | 'auto' | 'none' | 'required' | { type: 'tool'; toolName: keyof TOOLS }; + +/** + * @deprecated Use `ToolChoice` instead. + */ +// TODO remove in v5 +export type CoreToolChoice> = + ToolChoice; diff --git a/packages/ai/rsc/stream-ui/stream-ui.tsx b/packages/ai/rsc/stream-ui/stream-ui.tsx index 7bfe7a135aba..b5c58c5c56ed 100644 --- a/packages/ai/rsc/stream-ui/stream-ui.tsx +++ b/packages/ai/rsc/stream-ui/stream-ui.tsx @@ -11,7 +11,7 @@ import { Prompt } from '../../core/prompt/prompt'; import { standardizePrompt } from '../../core/prompt/standardize-prompt'; import { CallWarning, - CoreToolChoice, + ToolChoice, FinishReason, ProviderMetadata, } from '../../core/types'; @@ -115,7 +115,7 @@ export async function streamUI< /** * The tool choice strategy. Default: 'auto'. */ - toolChoice?: CoreToolChoice; + toolChoice?: ToolChoice; text?: RenderText; initial?: ReactNode; diff --git a/packages/provider-utils/src/index.ts b/packages/provider-utils/src/index.ts index e2b51f9925f2..249d5bf244e4 100644 --- a/packages/provider-utils/src/index.ts +++ b/packages/provider-utils/src/index.ts @@ -20,5 +20,5 @@ export * from './validator'; export * from './without-trailing-slash'; export type { IDGenerator } from './generate-id'; -export type { ToolCall } from './types/tool-call'; -export type { ToolResult } from './types/tool-result'; +export type { CoreToolCall, ToolCall } from './types/tool-call'; +export type { CoreToolResult, ToolResult } from './types/tool-result'; diff --git a/packages/provider-utils/src/types/tool-call.ts b/packages/provider-utils/src/types/tool-call.ts index cd3575586519..47ab21427113 100644 --- a/packages/provider-utils/src/types/tool-call.ts +++ b/packages/provider-utils/src/types/tool-call.ts @@ -18,3 +18,9 @@ Arguments of the tool call. This is a JSON-serializable object that matches the */ args: ARGS; } + +/** + * @deprecated Use `ToolCall` instead. + */ +// TODO remove in v5 +export type CoreToolCall = ToolCall; diff --git a/packages/provider-utils/src/types/tool-result.ts b/packages/provider-utils/src/types/tool-result.ts index 999a4b4cb056..4399e46f4cd9 100644 --- a/packages/provider-utils/src/types/tool-result.ts +++ b/packages/provider-utils/src/types/tool-result.ts @@ -23,3 +23,13 @@ Result of the tool call. This is the result of the tool's execution. */ result: RESULT; } + +/** + * @deprecated Use `ToolResult` instead. + */ +// TODO remove in v5 +export type CoreToolResult = ToolResult< + NAME, + ARGS, + RESULT +>; diff --git a/packages/swarm/src/agent.ts b/packages/swarm/src/agent.ts index 36bb07ac7362..fe4ad503a3da 100644 --- a/packages/swarm/src/agent.ts +++ b/packages/swarm/src/agent.ts @@ -1,4 +1,4 @@ -import { CoreToolChoice, LanguageModel, Schema } from 'ai'; +import { ToolChoice, LanguageModel, Schema } from 'ai'; import { z } from 'zod'; type Parameters = z.ZodTypeAny | Schema; @@ -79,14 +79,14 @@ export class Agent { readonly model: LanguageModel | undefined; readonly system: ((context: CONTEXT) => string) | string | undefined; readonly tools: Record> | undefined; - readonly toolChoice: CoreToolChoice | undefined; + readonly toolChoice: ToolChoice | undefined; constructor(options: { name: string; system?: ((context: CONTEXT) => string) | string | undefined; model?: LanguageModel; tools?: Record; - toolChoice?: CoreToolChoice; + toolChoice?: ToolChoice; }) { this.name = options.name; this.model = options.model; diff --git a/packages/swarm/src/run-swarm.ts b/packages/swarm/src/run-swarm.ts index a87b06d2a627..69710ef2893b 100644 --- a/packages/swarm/src/run-swarm.ts +++ b/packages/swarm/src/run-swarm.ts @@ -1,8 +1,8 @@ import { CoreAssistantMessage, CoreMessage, - CoreTool, - CoreToolChoice, + Tool, + ToolChoice, CoreToolMessage, FinishReason, generateText, @@ -30,7 +30,7 @@ export async function runSwarm({ context?: CONTEXT; model: LanguageModel; maxSteps?: number; - toolChoice?: CoreToolChoice; + toolChoice?: ToolChoice; debug?: boolean; onStepFinish?: (event: StepResult) => Promise | void; }): Promise<{ @@ -56,7 +56,7 @@ export async function runSwarm({ : activeAgent.system, tools: Object.fromEntries( Object.entries(activeAgent.tools ?? {}).map( - ([name, tool]): [string, CoreTool] => [ + ([name, tool]): [string, Tool] => [ name, tool.type === 'handover' ? { diff --git a/packages/ui-utils/src/data-stream-parts.test.ts b/packages/ui-utils/src/data-stream-parts.test.ts index 83053c149523..3c45c6c0605a 100644 --- a/packages/ui-utils/src/data-stream-parts.test.ts +++ b/packages/ui-utils/src/data-stream-parts.test.ts @@ -1,6 +1,6 @@ import { - ToolCall as CoreToolCall, - ToolResult as CoreToolResult, + ToolCall as ToolCall, + ToolResult as ToolResult, } from '@ai-sdk/provider-utils'; import { formatDataStreamPart, parseDataStreamPart } from './data-stream-parts'; @@ -63,7 +63,7 @@ describe('data-stream-parts', () => { describe('tool_call stream part', () => { it('should format a tool_call stream part', () => { - const toolCall: CoreToolCall = { + const toolCall: ToolCall = { toolCallId: 'tc_0', toolName: 'example_tool', args: { test: 'value' }, @@ -75,7 +75,7 @@ describe('tool_call stream part', () => { }); it('should parse a tool_call stream part', () => { - const toolCall: CoreToolCall = { + const toolCall: ToolCall = { toolCallId: 'tc_0', toolName: 'example_tool', args: { test: 'value' }, @@ -93,7 +93,7 @@ describe('tool_call stream part', () => { describe('tool_result stream part', () => { it('should format a tool_result stream part', () => { const toolResult: Omit< - CoreToolResult, + ToolResult, 'args' | 'toolName' > = { toolCallId: 'tc_0', diff --git a/packages/ui-utils/src/data-stream-parts.ts b/packages/ui-utils/src/data-stream-parts.ts index 1b387ec01df3..407fde862081 100644 --- a/packages/ui-utils/src/data-stream-parts.ts +++ b/packages/ui-utils/src/data-stream-parts.ts @@ -1,7 +1,7 @@ import { LanguageModelV1FinishReason } from '@ai-sdk/provider'; import { - ToolCall as CoreToolCall, - ToolResult as CoreToolResult, + ToolCall as ToolCall, + ToolResult as ToolResult, } from '@ai-sdk/provider-utils'; import { JSONValue } from './types'; @@ -71,7 +71,7 @@ const messageAnnotationsStreamPart: DataStreamPart< const toolCallStreamPart: DataStreamPart< '9', 'tool_call', - CoreToolCall + ToolCall > = { code: '9', name: 'tool_call', @@ -93,7 +93,7 @@ const toolCallStreamPart: DataStreamPart< return { type: 'tool_call', - value: value as unknown as CoreToolCall, + value: value as unknown as ToolCall, }; }, }; @@ -101,7 +101,7 @@ const toolCallStreamPart: DataStreamPart< const toolResultStreamPart: DataStreamPart< 'a', 'tool_result', - Omit, 'args' | 'toolName'> + Omit, 'args' | 'toolName'> > = { code: 'a', name: 'tool_result', @@ -121,7 +121,7 @@ const toolResultStreamPart: DataStreamPart< return { type: 'tool_result', value: value as unknown as Omit< - CoreToolResult, + ToolResult, 'args' | 'toolName' >, }; diff --git a/packages/ui-utils/src/types.ts b/packages/ui-utils/src/types.ts index 4ac0c90d8e2b..3ab561caa842 100644 --- a/packages/ui-utils/src/types.ts +++ b/packages/ui-utils/src/types.ts @@ -1,9 +1,5 @@ import { LanguageModelV1FinishReason } from '@ai-sdk/provider'; -import { - ToolCall as CoreToolCall, - ToolResult as CoreToolResult, - FetchFunction, -} from '@ai-sdk/provider-utils'; +import { ToolCall, ToolResult, FetchFunction } from '@ai-sdk/provider-utils'; import { LanguageModelUsage } from './duplicated/usage'; export * from './use-assistant-types'; @@ -16,9 +12,9 @@ there is one tool invocation. While the call is in progress, the invocation is a Once the call is complete, the invocation is a tool result. */ export type ToolInvocation = - | ({ state: 'partial-call' } & CoreToolCall) - | ({ state: 'call' } & CoreToolCall) - | ({ state: 'result' } & CoreToolResult); + | ({ state: 'partial-call' } & ToolCall) + | ({ state: 'call' } & ToolCall) + | ({ state: 'result' } & ToolResult); /** * An attachment that can be sent along with a message. @@ -193,7 +189,7 @@ either synchronously or asynchronously. onToolCall?: ({ toolCall, }: { - toolCall: CoreToolCall; + toolCall: ToolCall; }) => void | Promise | unknown; /**