本页还没有译文
本页 33 段还没译成日本語,下面显示的是英文原文。UIMessage
还没翻译译自英文(ai-sdk.dev)本页 33 段都还没译
UIMessage serves as the source of truth for your application's state, representing the complete message history including metadata, data parts, and all contextual information. In contrast to ModelMessage, which represents the state or context passed to the model, UIMessage contains the full application state needed for UI rendering and client-side functionality.
Type Safety
UIMessage is designed to be type-safe and accepts three generic parameters to ensure proper typing throughout your application:
METADATA- Custom metadata type for additional message informationDATA_PARTS- Custom data part types for structured data componentsTOOLS- Tool definitions for type-safe tool interactions
Creating Your Own UIMessage Type
Here's an example of how to create a custom typed UIMessage for your application:
import { InferUITools, ToolSet, UIMessage, tool } from 'ai';
import z from 'zod';
const metadataSchema = z.object({
someMetadata: z.string().datetime(),
});
type MyMetadata = z.infer<typeof metadataSchema>;
const dataPartSchema = z.object({
someDataPart: z.object({}),
anotherDataPart: z.object({}),
});
type MyDataPart = z.infer<typeof dataPartSchema>;
const tools = {
someTool: tool({}),
} satisfies ToolSet;
type MyTools = InferUITools<typeof tools>;
export type MyUIMessage = UIMessage<MyMetadata, MyDataPart, MyTools>;UIMessage Interface
interface UIMessage<
METADATA = unknown,
DATA_PARTS extends UIDataTypes = UIDataTypes,
TOOLS extends UITools = UITools,
> {
/**
* A unique identifier for the message.
*/
id: string;
/**
* The role of the message.
*/
role: 'system' | 'user' | 'assistant';
/**
* The metadata of the message.
*/
metadata?: METADATA;
/**
* The parts of the message. Use this for rendering the message in the UI.
*/
parts: Array<UIMessagePart<DATA_PARTS, TOOLS>>;
}UIMessagePart Types
TextUIPart
A text part of a message.
type TextUIPart = {
type: 'text';
/**
* The text content.
*/
text: string;
/**
* The state of the text part.
*/
state?: 'streaming' | 'done';
};ReasoningUIPart
A reasoning part of a message.
type ReasoningUIPart = {
type: 'reasoning';
/**
* The reasoning part ID.
*/
id?: string;
/**
* The reasoning text.
*/
text: string;
/**
* The state of the reasoning part.
*/
state?: 'streaming' | 'done';
/**
* The provider metadata.
*/
providerMetadata?: Record<string, any>;
};ToolUIPart
A tool part of a message that represents tool invocations and their results.
Note
The type is based on the name of the tool (e.g., tool-someTool for a tool
named someTool).
type ToolUIPart<TOOLS extends UITools = UITools> = ValueOf<{
[NAME in keyof TOOLS & string]: {
type: `tool-${NAME}`;
toolCallId: string;
} & (
| {
state: 'input-streaming';
input: DeepPartial<TOOLS[NAME]['input']> | undefined;
providerExecuted?: boolean;
output?: never;
errorText?: never;
}
| {
state: 'input-available';
input: TOOLS[NAME]['input'];
providerExecuted?: boolean;
output?: never;
errorText?: never;
}
| {
state: 'approval-requested';
input: TOOLS[NAME]['input'];
output?: never;
errorText?: never;
approval: {
id: string;
approved?: never;
descriptor?: unknown;
requestReason?: string;
reason?: never;
isAutomatic?: boolean;
signature?: string;
};
}
| {
state: 'approval-responded';
input: TOOLS[NAME]['input'];
output?: never;
errorText?: never;
approval: {
id: string;
approved: boolean;
descriptor?: unknown;
requestReason?: string;
reason?: string;
isAutomatic?: boolean;
signature?: string;
};
}
| {
state: 'output-available';
input: TOOLS[NAME]['input'];
output: TOOLS[NAME]['output'];
errorText?: never;
providerExecuted?: boolean;
}
| {
state: 'output-error';
input: TOOLS[NAME]['input'];
output?: never;
errorText: string;
providerExecuted?: boolean;
}
);
}>;approval.descriptor contains optional opaque metadata supplied as
approvalDescriptor on the approval request stream chunk. It is preserved when
the tool part transitions from approval-requested to approval-responded and
in later approval-bearing output states.
ToolOutputErrorUIPart
A static or dynamic tool part whose execution failed. Use the
isToolOutputErrorUIPart type guard when rendering messages so your code does
not need to check the tool state discriminator directly.
import { isToolOutputErrorUIPart, type UIMessage } from 'ai';
function ToolError({ part }: { part: UIMessage['parts'][number] }) {
if (!isToolOutputErrorUIPart(part)) {
return null;
}
return <div role="alert">{part.errorText}</div>;
}The generic ToolOutputErrorUIPart<TOOLS> type preserves the input types of
static tools and also includes dynamic tool errors:
type ToolOutputErrorUIPart<TOOLS extends UITools = UITools> = Extract<
ToolUIPart<TOOLS> | DynamicToolUIPart,
{ state: 'output-error' }
>;CustomContentUIPart
A provider-specific custom content part of a message.
type CustomContentUIPart = {
type: 'custom';
/**
* The kind of custom content, in the format `{provider}.{provider-type}`.
*/
kind: `${string}.${string}`;
/**
* The provider metadata.
*/
providerMetadata?: Record<string, any>;
};SourceUrlUIPart
A source URL part of a message.
type SourceUrlUIPart = {
type: 'source-url';
sourceId: string;
url: string;
title?: string;
providerMetadata?: Record<string, any>;
};SourceDocumentUIPart
A document source part of a message.
type SourceDocumentUIPart = {
type: 'source-document';
sourceId: string;
mediaType: string;
title: string;
filename?: string;
providerMetadata?: Record<string, any>;
};FileUIPart
A file part of a message.
type FileUIPart = {
type: 'file';
/**
* IANA media type of the file.
*/
mediaType: string;
/**
* Optional filename of the file.
*/
filename?: string;
/**
* The URL of the file.
* It can either be a URL to a hosted file or a Data URL.
*/
url: string;
};DataUIPart
A data part of a message for custom data types.
Note
The type is based on the name of the data part (e.g., data-someDataPart for
a data part named someDataPart).
type DataUIPart<DATA_TYPES extends UIDataTypes> = ValueOf<{
[NAME in keyof DATA_TYPES & string]: {
type: `data-${NAME}`;
id?: string;
data: DATA_TYPES[NAME];
};
}>;StepStartUIPart
A step boundary part of a message.
type StepStartUIPart = {
type: 'step-start';
};