Skip to content

feat(agui): introduce typed MessageContent and InputContent model for multimodal AG-UI messages (issue#551) - #2518

Open
xzxiaoshan wants to merge 2 commits into
agentscope-ai:mainfrom
xzxiaoshan:feat/agui-typed-message-content
Open

feat(agui): introduce typed MessageContent and InputContent model for multimodal AG-UI messages (issue#551)#2518
xzxiaoshan wants to merge 2 commits into
agentscope-ai:mainfrom
xzxiaoshan:feat/agui-typed-message-content

Conversation

@xzxiaoshan

@xzxiaoshan xzxiaoshan commented Aug 1, 2026

Copy link
Copy Markdown

完成 issue #551

Summary

将 AG-UI 协议的 AguiMessage.contentString 升级为类型安全的 sealed 联合类型 MessageContent,支持纯文本和多模态内容块(text/image/audio/video/document),对齐 AG-UI 协议规范。

Background

此前 AguiMessage.content 仅支持 String,无法承载多模态输入。本 PR 按照类型安全的设计原则,引入 AG-UI 协议层的类型化模型,替代 Object / List<Map<String, Object>> 等弱类型方案。

架构总览

    AG-UI 协议层                        转换层                    AgentScope 模型层
 ┌─────────────────────┐          ┌──────────────┐          ┌──────────────────────┐
 │  AguiMessage        │          │              │          │  Msg                 │
 │  content:           │          │  InputContent│          │  content:            │
 │    MessageContent   │────────▶ │      ↕       │ ───────▶ │    List<ContentBlock>│
 │                     │          │  ContentBlock│          │                      │
 │  MessageContent     │          │              │          │  ContentBlock        │
 │  ┌─Text──────────┐  │          │  text    →   │          │  ├─TextBlock         │
 │  │(String value) │  │          │   TextBlock  │          │  ├─ImageBlock        │
 │  └───────────────┘  │          │              │          │  ├─AudioBlock        │
 │  ┌─Blocks────────┐  │          │  image   →   │          │  ├─VideoBlock        │
 │  │ List<Input    │  │          │   ImageBlock │          │  ├─ThinkingBlock     │
 │  │  Content>     │  │          │              │          │  ├─ToolUseBlock      │
 │  └───────────────┘  │          │  document→   │          │  └─ToolResultBlock   │
 │                     │          │   TextBlock  │          │                      │
 │  InputContent       │          │              │          │                      │
 │  (sealed interface) │          │ (pattern     │          │  (sealed interface)  │
 │  ├─TextContent──── │          │   matching,  │          │                      │
 │  ├─ImageContent─── │          │   编译期穷尽) │          │                      │
 │  ├─AudioContent─── │          │              │          │                      │
 │  ├─VideoContent─── │          │              │          │                      │
 │  └─DocumentContent─ │          │              │          │                      │
 └─────────────────────┘          └──────────────┘          └──────────────────────┘
     协议术语,不叫                                         内部模型术语,不叫
     "多模态"                                               "多模态"

注意:架构图右侧 AgentScope 模型层(ContentBlock 及其子类型)已存在,是 agentscope-java 既有的标准定义,无需重新设计。本架构建议中新增的仅是左侧 AG-UI 协议层的类型化模型(MessageContent / InputContent),以及中间 Converter 的改进——对接到既有 ContentBlock 体系。

设计要点

1. AguiMessage.content —— 类型安全的联合

MessageContent (sealed interface)
├── Text(String value)              → JSON: "你好"
└── Blocks(List<InputContent> parts) → JSON: [{"type":"text",...},{"type":"image",...}]
  • 用 sealed interface 表达 string | InputContent[] 联合类型
  • 命名用 Text / Blocks(或 hasBlocks()),不引入"多模态"
  • 自定义 JSON 编解码器:反序列化按 JSON token(标量/数组)分派,序列化按 instanceof 透明输出

2. InputContent —— 类型化的协议模型

InputContent (sealed interface)
├── TextInputContent
├── ImageInputContent
├── AudioInputContent
├── VideoInputContent
└── DocumentInputContent
  • 对应 AG-UI 协议的 InputContent 联合类型
  • 取代 Map<String, Object>,提供编译期类型安全
  • JSON 多态通过 type 字段分派(标准 @JSONType(seeAlso=...)

3. Converter —— 编译期穷尽的类型映射

InputContent → ContentBlock(pattern matching switch)

TextInputContent     → TextBlock
ImageInputContent    → ImageBlock
AudioInputContent    → AudioBlock
VideoInputContent    → VideoBlock
DocumentInputContent → TextBlock(降级)

// sealed switch 编译期穷尽,新增类型时编译器报错提醒

引用的 AG-UI 格式定义

https://docs.ag-ui.com/concepts/messages

interface UserMessage {
  id: string
  role: "user"
  content: string | InputContent[] // Text or multimodal input from the user
  name?: string // Optional user identifier
}

type InputContent =
  | TextInputContent
  | ImageInputContent
  | AudioInputContent
  | VideoInputContent
  | DocumentInputContent

interface InputContentDataSource {
  type: "data"
  value: string
  mimeType: string
}

interface InputContentUrlSource {
  type: "url"
  value: string
  mimeType?: string
}

type InputContentSource = InputContentDataSource | InputContentUrlSource

interface TextInputContent {
  type: "text"
  text: string
}

interface ImageInputContent {
  type: "image"
  source: InputContentSource
  metadata?: Record<string, unknown>
}

interface AudioInputContent {
  type: "audio"
  source: InputContentSource
  metadata?: Record<string, unknown>
}

interface VideoInputContent {
  type: "video"
  source: InputContentSource
  metadata?: Record<string, unknown>
}

interface DocumentInputContent {
  type: "document"
  source: InputContentSource
  metadata?: Record<string, unknown>
}

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant