Skip to content

Instantly share code, notes, and snippets.

@Southclaws
Created January 11, 2026 21:09
Show Gist options
  • Select an option

  • Save Southclaws/e402d3914dfe534949f2f40c6ee259c8 to your computer and use it in GitHub Desktop.

Select an option

Save Southclaws/e402d3914dfe534949f2f40c6ee259c8 to your computer and use it in GitHub Desktop.
Vercel AI SDK UIMessage in OpenAPI/JSONSchema Format
components:
schemas:
# -
# Vercel AI SDK UIMessage format
# These schemas match the structure from @ai-sdk/react for compatibility
#
# Generate types from these using Orval or json-schema-to-typescript so
# you can validate them. This allows you to generate code for backends in
# any language allowing you to build Vercel AI SDK backends in non-TS.
# -
UIMessage:
type: object
required: [id, role, parts]
description: |
A message in the Vercel AI SDK format. This is compatible with the
UIMessage interface from @ai-sdk/react and can be used directly with
the useChat hook.
properties:
id:
type: string
description: Unique message identifier
role:
type: string
enum: [system, user, assistant]
description: The role of the message sender
parts:
type: array
items: { $ref: "#/components/schemas/UIMessagePart" }
description: The parts that make up the message content
metadata:
type: object
additionalProperties: true
description: Optional metadata associated with the message
UIMessagePart:
oneOf:
- $ref: "#/components/schemas/TextUIPart"
- $ref: "#/components/schemas/ReasoningUIPart"
- $ref: "#/components/schemas/ToolUIPart"
- $ref: "#/components/schemas/FileUIPart"
discriminator:
propertyName: type
mapping:
text: "#/components/schemas/TextUIPart"
reasoning: "#/components/schemas/ReasoningUIPart"
dynamic: "#/components/schemas/ToolUIPart"
file: "#/components/schemas/FileUIPart"
description: |
A part of a UIMessage. Can be text, reasoning, tool invocation, or file.
required: [type]
properties:
type:
type: string
description: The type of the message part
enum: [text, reasoning, dynamic-tool, file]
TextUIPart:
type: object
required: [type, text]
description: A text part of a message
properties:
type:
type: string
enum: [text]
text:
type: string
description: The text content
state:
type: string
enum: [streaming, done]
description: The state of the text part
ReasoningUIPart:
type: object
required: [type, text]
description: A reasoning part of a message (extended thinking/reasoning)
properties:
type:
type: string
enum: [reasoning]
text:
type: string
description: The reasoning text
state:
type: string
enum: [streaming, done]
description: The state of the reasoning part
ToolUIPart:
oneOf:
- $ref: "#/components/schemas/ToolUIPartInputStreaming"
- $ref: "#/components/schemas/ToolUIPartInputAvailable"
- $ref: "#/components/schemas/ToolUIPartOutputAvailable"
- $ref: "#/components/schemas/ToolUIPartOutputError"
discriminator:
propertyName: state
mapping:
input-streaming: "#/components/schemas/ToolUIPartInputStreaming"
input-available: "#/components/schemas/ToolUIPartInputAvailable"
output-available: "#/components/schemas/ToolUIPartOutputAvailable"
output-error: "#/components/schemas/ToolUIPartOutputError"
description: A tool invocation part (dynamic-tool format matching Vercel AI SDK)
ToolUIPartBase:
type: object
required: [type, toolCallId, toolName]
properties:
type:
type: string
enum: [dynamic-tool]
description: Type identifier for dynamic tool calls
toolCallId:
type: string
description: Unique ID for this tool call
toolName:
type: string
description: Name of the tool being called
title:
type: string
description: Optional title for the tool call
providerExecuted:
type: boolean
description: Whether the tool was executed by the provider
ToolUIPartInputStreaming:
allOf:
- $ref: "#/components/schemas/ToolUIPartBase"
- type: object
required: [state, input]
properties:
state:
type: string
enum: [input-streaming]
input:
type: object
additionalProperties: true
description: Partial input (streaming)
ToolUIPartInputAvailable:
allOf:
- $ref: "#/components/schemas/ToolUIPartBase"
- type: object
required: [state, input]
properties:
state:
type: string
enum: [input-available]
input:
type: object
additionalProperties: true
description: Complete input arguments
ToolUIPartOutputAvailable:
allOf:
- $ref: "#/components/schemas/ToolUIPartBase"
- type: object
required: [state, input, output]
properties:
state:
type: string
enum: [output-available]
input:
type: object
additionalProperties: true
description: Input arguments used
output:
type: object
additionalProperties: true
description: Output result from the tool
preliminary:
type: boolean
description: Whether this is a preliminary result
ToolUIPartOutputError:
allOf:
- $ref: "#/components/schemas/ToolUIPartBase"
- type: object
required: [state, input, errorText]
properties:
state:
type: string
enum: [output-error]
input:
type: object
additionalProperties: true
description: Input that caused the error
errorText:
type: string
description: Error message
FileUIPart:
type: object
required: [type, mediaType, url]
description: A file part of a message
properties:
type:
type: string
enum: [file]
mediaType:
type: string
description: IANA media type of the file
filename:
type: string
description: Optional filename
url:
type: string
description: URL to the file (can be a data URL or hosted URL)
# -
# Robot session messages - extends UIMessage with our metadata
# -
RobotSessionMessage:
allOf:
- $ref: "#/components/schemas/UIMessage"
- type: object
required: [created_at]
properties:
created_at:
type: string
format: date-time
description: When the message was sent
robot:
$ref: "#/components/schemas/Robot"
description: Robot that generated this message
author:
$ref: "#/components/schemas/ProfileReference"
description: Human author of the message
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment