多模态输入、回复终态与客户端工具
约 3164 字大约 11 分钟
2026-10-16
本页按 Topic、method 和方向定义完整契约。字段表与JSON中的可选扩展不等于当前全部启用,实际接入前请查支持范围;应用REST封装见应用接入。
内容、授权与生命周期
ContentPart为对象:type:string必填,text/image/audio/video/file;text类型必填text:string(非空);其他类型必填contentRef:string、mimeType:string,禁止内嵌Base64及任意外网URL。每次最多16项,信封上限64KiB;超限413。素材须通过已鉴权文件上传服务取得引用,提交前平台再次验证会话所属用户、用途、有效期及文件类型;上传成功不授予AI读取权限。文件接口沿用平台文件服务,非新MQTT method。
inputModalities/outputModalities是text/image/audio/video/file枚举数组。端能力、业务模型和用户授权三者取交集;省略数组仅沿用既有已协商轨模态,不推断支持文件。文本/文件会话transport=none、tracks=[],不启动麦克风、媒体节点或音频计费;升级为实时媒体须另建媒体会话,不以空SDP伪造连通。
inputSend的requestAck(code=200)之后按result.inputId关联respCreated。文本、媒体共用contentIndex,respTextDone只封闭一个文本段;respMedia封闭一个媒体段,表情不占段。回复最后发respDone;contentCount是段总数,不能把respTextDone、respAudioDone或toolCallResult单独当回复终态。跨Topic时respDone可能先于音频控制到达,接收端以respId终态阻止新内容,不据此伪报硬件已停止。
输入失败不产生respCreated;受理后失败发respDone(failed)。默认一会话一次生成,已有生成或持续音频输入返回409 inputBusy;需先定向取消并等respDone,或先audioStop确认输入暂停。连续实时音频分段不通过inputSend,仍走S03/S20。
工具只执行注册白名单内的客户端工具;工具名、参数和formSchema都不能成为任意脚本执行入口。executionToken绑定登录端/设备、sessionId、respId、toolCallId及expiresAt;从toolCallExecute发出起最多60秒,以更早expiresAt为准。成功/失败/未知结果均仅回注一次。重复同结果返回原回执;不同结果409 tokenConflict;取消、过期或端归属变化返回409 toolCallExpired/403 permissionDenied。会话结束立刻撤销未用令牌并清理等待者,设备写操作可能已生效,不能宣称取消等于回滚。
应用通过interaction.control(command=inputSend/toolCallSubmit)提交,对应interaction.result.data.result映射原应答正文;data.operation始终是interaction.control。应用内容使用interaction.message,不把工具执行塞进状态通知。能力上报注册frontendTools(name、interactionType、schemaRevision),未声明禁止下发toolCallExecute;后端MCP设备动作仍用S04。
inputSend · MSG↑
提交一轮文字或已上传媒体;不用于连续PCM/Opus。仅AI会话允许,持续采集时先audioStop,否则409 inputBusy。
- 发送→接收:设备→平台;Topic/接口:
$thing/up/message/{productID}/{deviceName}。 - 应答:requestAck;请求10秒、同token最多重试2次;事件不等待ACK。执行工具结果另有60秒期限。
- 前置:已建立且授权的AI会话,能力及模型模态有交集。错误应答只需code和data.reason。
- 重复/迟到:同token同内容重放原结果,冲突409;终态不复活。输入按inputId、工具按toolCallId另作业务去重;换token不允许重复执行。
- 状态与失败:成功受理不等于模型完成或设备播放;失败只结束对应输入/调用。 缺字段400、无权403、不存在404、状态冲突409、不支持422,超时504;不得静默换模型或扩大授权。
- 适用场景:S21;适用能力见支持范围。
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| inputId | string | 必填 | 端分配、会话内唯一;重试不改变 |
| contents | ContentPart[] | 必填 | 至少一项;类型见本页 |
| outputModalities | string[] | 必填 | text/audio/image/video/file;必须在协商交集内 |
报文实例
{
"msgToken": "s21-6",
"method": "inputSend",
"sessionId": "s21-session",
"params": {
"inputId": "input-1",
"contents": [
{
"type": "text",
"text": "描述这张图片"
},
{
"type": "image",
"contentRef": "<authorized-image-ref>",
"mimeType": "image/jpeg"
}
],
"outputModalities": [
"text"
]
}
}对应S21-M06。
respMedia · MSG↓
模型输出的媒体引用,不经MQTT传文件;按respId+contentIndex去重。
- 发送→接收:平台→设备;Topic/接口:
$thing/down/message/{productID}/{deviceName}。 - 应答:—;请求10秒、同token最多重试2次;事件不等待ACK。执行工具结果另有60秒期限。
- 前置:已建立且授权的AI会话,能力及模型模态有交集。错误应答只需code和data.reason。
- 重复/迟到:同token同内容重放原结果,冲突409;终态不复活。输入按inputId、工具按toolCallId另作业务去重;换token不允许重复执行。
- 状态与失败:成功受理不等于模型完成或设备播放;失败只结束对应输入/调用。 缺字段400、无权403、不存在404、状态冲突409、不支持422,超时504;不得静默换模型或扩大授权。
- 适用场景:S21;适用能力见支持范围。
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 回复ID |
| contentIndex | uint | 必填 | 本回复从0编号 |
| mediaType | string | 必填 | image/video/audio/file |
| contentRef | string | 必填 | 鉴权文件引用,不能当公开URL |
| mimeType | string | 必填 | 实际媒体类型 |
| description | string | 可选 | 展示说明 |
报文实例
{
"msgToken": "s21-10",
"method": "respMedia",
"sessionId": "s21-session",
"messageSeq": 3,
"data": {
"respId": "reply-1",
"contentIndex": 1,
"mediaType": "image",
"contentRef": "<authorized-result-ref>",
"mimeType": "image/png"
}
}对应S21-M10。
respEmotion · MSG↓
UI表情提示,不开启执行器,不当作硬件动作。缺省不发送;取消后丢弃。
Unicode显示白名单:😶 🙂 😊 😆 😂 😔 😠 😭 😍 😳 😲 😱 🤔 😉 😎 😌 🤤 😘 😏 😴 😜 🙄。设备收到白名单外值不执行任何动作。
- 发送→接收:平台→设备;Topic/接口:
$thing/down/message/{productID}/{deviceName}。 - 应答:—;请求10秒、同token最多重试2次;事件不等待ACK。执行工具结果另有60秒期限。
- 前置:已建立且授权的AI会话,能力及模型模态有交集。错误应答只需code和data.reason。
- 重复/迟到:同token同内容重放原结果,冲突409;终态不复活。输入按inputId、工具按toolCallId另作业务去重;换token不允许重复执行。
- 状态与失败:成功受理不等于模型完成或设备播放;失败只结束对应输入/调用。 缺字段400、无权403、不存在404、状态冲突409、不支持422,超时504;不得静默换模型或扩大授权。
- 适用场景:S21;适用能力见支持范围。
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 回复ID |
| emoji | string | 必填 | 允许列表中的Unicode表情 |
| emotion | string | 必填 | neutral/happy/sad/angry/surprised;未识别按neutral |
报文实例
{
"msgToken": "s21-11",
"method": "respEmotion",
"sessionId": "s21-session",
"messageSeq": 4,
"data": {
"respId": "reply-1",
"emoji": "😊",
"emotion": "happy"
}
}对应S21-M11。
respDone · MSG↓
回复聚合终态;文本、媒体与工具均已终结或取消,平台不再产生该回复的新内容;不是设备播放完成。
内容终态不可改写,但仍可收到定向播放中断清理同回复的残留播放。completed与随后停止设备缓冲并不矛盾;不能因已有respDone就过滤播放中断,也不能为表示停声再次发送respDone(cancelled)。
- 发送→接收:平台→设备;Topic/接口:
$thing/down/message/{productID}/{deviceName}。 - 应答:—;请求10秒、同token最多重试2次;事件不等待ACK。执行工具结果另有60秒期限。
- 前置:已建立且授权的AI会话,能力及模型模态有交集。错误应答只需code和data.reason。
- 重复/迟到:同token同内容重放原结果,冲突409;终态不复活。输入按inputId、工具按toolCallId另作业务去重;换token不允许重复执行。
- 状态与失败:聚合终态只生成一次,后续内容丢弃。 缺字段400、无权403、不存在404、状态冲突409、不支持422,超时504;不得静默换模型或扩大授权。
- 适用场景:S21;适用能力见支持范围。
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 回复ID |
| inputId | string | 来源组合与respCreated一致 | 已确定关联的输入,不猜测当前采集段 |
| utteranceId | string | 来源组合与respCreated一致 | 平台识别条目;与inputId至少一个,见输入来源定义 |
| status | string | 必填 | completed/cancelled/failed |
| reason | string | 非completed必填 | 稳定原因 |
| contentCount | uint | 必填 | 最终内容段数,包含文本及媒体 |
| audioState | string | 必填 | none/sent/cancelled/failed;描述发送端,不是播放端 |
报文实例
{
"msgToken": "s21-12",
"method": "respDone",
"sessionId": "s21-session",
"messageSeq": 5,
"data": {
"respId": "reply-1",
"inputId": "input-1",
"status": "completed",
"contentCount": 2,
"audioState": "none"
}
}对应S21-M12。
toolCallSubmit · MSG↑
定向客户端工具执行结果回传;仅原会话原端可提交,工具名不授予执行权限。
- 发送→接收:设备→平台;Topic/接口:
$thing/up/message/{productID}/{deviceName}。 - 应答:requestAck;请求10秒、同token最多重试2次;事件不等待ACK。执行工具结果另有60秒期限。
- 前置:已建立且授权的AI会话,能力及模型模态有交集。错误应答只需code和data.reason。
- 重复/迟到:同token同内容重放原结果,冲突409;终态不复活。输入按inputId、工具按toolCallId另作业务去重;换token不允许重复执行。
- 状态与失败:成功受理不等于模型完成或设备播放;失败只结束对应输入/调用。 缺字段400、无权403、不存在404、状态冲突409、不支持422,超时504;不得静默换模型或扩大授权。
- 适用场景:S22;适用能力见支持范围。
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 回复ID |
| toolCallId | string | 必填 | 调用ID |
| executionToken | string | 必填 | 一次调用的定向授权令牌 |
| status | string | 必填 | succeeded/failed/unknown;超时且副作用不确定用unknown |
| result | object | 必填 | 经过工具schema校验的结果或脱敏错误 |
报文实例
{
"msgToken": "s22-2",
"method": "toolCallSubmit",
"sessionId": "s22-session",
"params": {
"respId": "reply-1",
"toolCallId": "tool-1",
"executionToken": "<scoped-single-call-token>",
"status": "succeeded",
"result": {
"theme": "dark"
}
}
}对应S22-M02。
interaction.message · APP↓
应用内容事件包装;登录端鉴权,data.command只允许本手册MSG下行事件,禁止嵌套包装。沿用独立messageSeq,不用eventSeq。
- 发送→接收:平台→应用;Topic/接口:WS interaction.event。
- 应答:—;请求10秒、同token最多重试2次;事件不等待ACK。执行工具结果另有60秒期限。
- 前置:已建立且授权的AI会话,能力及模型模态有交集。错误应答只需code和data.reason。
- 重复/迟到:同token同内容重放原结果,冲突409;终态不复活。输入按inputId、工具按toolCallId另作业务去重;换token不允许重复执行。
- 状态与失败:成功受理不等于模型完成或设备播放;失败只结束对应输入/调用。 缺字段400、无权403、不存在404、状态冲突409、不支持422,超时504;不得静默换模型或扩大授权。
- 适用场景:S22;适用能力见支持范围。
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| command | string | 必填 | resp*/toolCall*/translationResult等MSG下行事件,不含应答及异步投递 |
| result | object | 必填 | 与对应事件data同构;令牌只投递给指定执行端 |
报文实例
{
"msgToken": "s22-11",
"method": "interaction.message",
"sessionId": "s22-session",
"messageSeq": 6,
"data": {
"command": "toolCallExecute",
"result": {
"respId": "app-reply",
"toolCallId": "app-tool",
"name": "set_local_display_theme",
"arguments": {
"theme": "dark"
},
"isFrontend": true,
"interactionType": "action",
"executionToken": "<app-endpoint-token>",
"expiresAt": 1900000000000
}
}
}对应S22-M11。
更新日志
2026/10/16 16:04
查看所有更新日志
fe3a7-docs(AI与音视频): 按场景整理完整接入流程与命令契约于
