能力与会话命令
约 9623 字大约 32 分钟
2026-10-16
本页按 Topic、method 和方向定义完整契约。字段表与JSON中的可选扩展不等于当前全部启用,实际接入前请查支持范围;应用REST封装见应用接入。
capabilityReport · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | requestAck |
| 触发与状态变化 | 全量替换本设备当前能力;断线重连重新上报,不授予权限。 |
| 前置条件 | 设备已认证,尚不要求会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S02、S03 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| revision | uint | 必填 | 递增能力快照号 |
| purposes | string[] | 必填 | purpose 枚举 |
| transports | string[] | 必填 | none/udp/webrtc;none无实时媒体 |
| supportedInteractionModes | string[] | AI语音必填 | halfDuplex/fullDuplex |
| aecMode | string | AI语音必填 | device/none/unknown |
| cameras | Camera[] | 可选 | 缺省无摄像头 |
| inputModalities | string[] | 非实时输入必填 | text/image/audio/video/file;参考命令08 |
| outputModalities | string[] | 非实时输出必填 | text/image/audio/video/file |
| playbackOutputModalities | string[] | 文件共存设备应显式上报 | 仅audio/video,非空、无重复、必须为outputModalities子集;缺省沿用现行文件输出投影,不能用AI声音虚报文件驱动 |
| liveReceive | object | 声明liveBroadcast时必填 | 独立实时节目接收格式;至少包含audio或videoCodecs。audio固定format=opus、sampleRate=48000、channels=1、frameDuration=20,四字段齐全;videoCodecs固定非空唯一["H264"]。拒绝整体及子字段null、未知/重复字段。必须同时支持webrtc;未声明liveBroadcast不得携带,不授予麦克风、相机、节目或焦点权限 |
| frontendTools | object[] | 客户端工具必填 | name:string、interactionType:action/form、schemaRevision:uint;缺省不支持 |
| features | string[] | 必填 | audio/video/localAccept;videoReceive 为 humanCall 独立远端视频接收能力,须同时声明 humanCall、video 和本地相机,默认不支持,实际接收仍需平台明确选定第四轨 video-in;participantRoster 为显式增量成员事件接收,仅用于 humanCall/ipcTalk;participantRosterSync 为独立全量名册同步声明,当前仅接 ipcTalk 且依赖 participantRoster,两者均不授予成员轨订阅或话权。multiViewer 为扩展契约,须确认支持枚举,严格解析不接纳。纯文字及纯文件mediaPlayback固定空数组;控制扩展能力见controlCapabilities |
| controlCapabilities | object | 可选 | 当前焦点子集实现为operations:["focusControl"]、focusResources:string[](1~16个唯一资源:microphone/speaker/display/camera:ID);camera:ID须对应本快照cameras中的cameraId。可选baseline为完整资源实际空闲证明,字段见下文;严格解析、首次仓储初始化及DMS/Core接入已实现,具体运行能力按支持范围启用。其他扩展字段sourceTypes/maxVideoTracks/fullDuplexTransports仍为设计,不能提交给当前严格解析入口。省略表示不支持焦点,不影响原有能力 |
| audio | Audio | features声明audio时必填 | 编解码参数;纯视频IPC可以省略,不能虚报麦克风 |
features还可声明udpReplyStartReceipt:必须同时具有aiConversation、udp、audio及完整有效音频参数;只表示支持安装确认,不自动选定。平台须具备当前设备预检、持久安装事实和原模型安装门才可选择。实际PCM Ready与回复边界均可确认的固件才可声明;未声明设备保持原行为,None/WebRTC/Human不启用。具体回执契约见respAudioStart安装确认。
humanEndpointHandoff为独立的人际语音接续能力,不能借用aiEndpointHandoff、localAccept或同账号身份推断。必须同时具有humanCall、webrtc、audio/localAccept、Opus 48kHz/单声道/20ms及完整microphone/speaker两项控制资源和合法首次baseline。controlCapabilities.operations仍只有focusControl,不把endpointControl加入资源控制操作数组。首次baseline不是当前取得许可,接续仍须核原连接及实际整组回执。
接续目标控制恢复的增量能力为 aiEndpointControlSync,须同时声明 audio/sessionSync/localAccept/aiEndpointHandoff 和 controlCapabilities.operations 包含 focusControl、focusResources 完整 microphone/speaker 两项。它不能由历史两能力组合推断。仅实际完成完整组有限释放、新连接基线和条件重新取得的设备上报;未声明目标保持原接续行为和控制断线 failclosed。源码实施及尚未验收边界见支持范围。
该增量的完整组恢复要求已鉴权的新物理 ConnectionEpoch 严格大于原目标值。同代次只换实例明确拒绝且保持停流,设备可在首次固定十五秒窗口内以更高物理代次重试,不延长窗口、不覆盖旧焦点账本。此要求不改变原初建 ControlBinding 无完整组路径的既有规则。快照成功不自动打开采集;原完整组实际释放、第二份真实空闲基线及新焦点实际取得后仍需用户明确发起新输入。
仅该恢复组合允许同修订的两份能力:首份无伪空闲基线,原完整组实际释放并确认后,第二份增加非零真实完整 baseline;除该字段外必须与新连接第一份当前能力完全相同。Core 在持久 Rebase 前核完整结构,DMS 再按同 login/修订/结构原子补一次;私有确认位只在内部生成 RPC 中传递,不增加设备 JSON 字段。普通能力 CAS 不放宽,原 payload/token 精确重投不延长资源或恢复租期。其他基线、AEC/功能/资源变化、同代次换实例以及未声明对应能力的设备均不能走此例外。十五秒总截止贯穿快照、旧组释放、新基线和新组实际取得;耗尽按 networkTimeout 结束模型,原两秒未知动作仍保持未知而不重签。
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
实时节目接收能力已接入 Go 严格能力解析和平台邀请求交;其会话 Owner、实际媒体、MCP 和 C++ 驱动仍待接线。纯接收设备显式上报空 features,省略 AI 模式、AEC、摄像头及离散输出,不虚报采集。AI+节目一次合并上报,AI 输入 audio 和 liveReceive.audio 分别校验:AI 16kHz 不能代替节目 48kHz 接收,节目接收也不能免除 AI 全双工的设备 AEC 条件。旧能力未携带该可选字段时投影不变。带音轨视频必须完整求交,不能静默降级为无声视频;实现及验证边界见支持范围。
焦点首次空闲证明(后端首次接入已实现,持续Owner与实际驱动待完成)
controlCapabilities.baseline可省略或为null,两者都表示没有空闲证明,不能创建ready连接账本。非空对象只接受下列字段:
| 字段 | 类型 | 必填 | 含义 |
|---|---|---|---|
| state | string | 是 | 固定idle;unknown或占用状态不能通过本入口初始化 |
| revision | uint | 是 | 设备实际全局资源水位,范围0至9007199254740991;显式0有效,省略/null无效。不是能力revision,也不是数据库CAS |
| resources | string[] | 是 | 必须精确等于focusResources完整集合,顺序不敏感;不允许重复、部分空闲或额外资源 |
设备必须由共享实际驱动确认所有声明资源均空闲后才构造证明。门控请求已受理、播放器逻辑ended、静音或本地许可均不能代替实际空闲事实。后端仓储仅允许可信当前连接首次初始化;不能用重复能力上报重置ready/unknown、清除在途及旧租约或延长Owner租期。没有实际整组驱动及空闲观测的设备不得虚报baseline。既有省略字段的能力报文不变,没有新增method、Topic或版本字段。
首次建连的状态未就绪与权限拒绝分开:携带基线且接入缓存明确离线(def.False)、原绑定主人和连接代次都是安全正数时,平台返回requestAck的code=409、data.reason="capabilityNotAccepted",仍不提交Core或保存基线许可。设备消费此明确拒绝后,才可有限退避并用新token重报原完整能力;当前C++策略为500毫秒、最多两次,断开即取消,持续未就绪最终失败。无效主人/代次、未知在线值仍按原规则拒绝,403或未知结果不能走此恢复。此规则不保证上线事件漏失自愈,也不表示已取得输出资源;省略基线的原能力及旧Topic不变。
报文实例
{
"msgToken": "cap-s01",
"method": "capabilityReport",
"params": {
"revision": 1,
"purposes": [
"aiConversation"
],
"transports": [
"udp",
"webrtc"
],
"supportedInteractionModes": [
"halfDuplex",
"fullDuplex"
],
"aecMode": "device",
"audio": {
"format": "opus",
"sampleRate": 16000,
"channels": 1,
"frameDuration": 20
},
"features": [
"audio"
]
}
}对应S01-M01;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
{
"msgToken": "cap-file",
"method": "capabilityReport",
"params": {
"revision": 1,
"purposes": ["mediaPlayback"],
"transports": ["none"],
"features": [],
"outputModalities": ["audio", "video"]
}
}sessionCreate · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | sessionCreated |
| 触发与状态变化 | 设备发起会话;平台验证设备能力、业务配置、资源与授权交集,不指定供应商。 |
| 前置条件 | 能力已上报,本次资源和权限通过 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S02、S03、S09、S11 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| purpose | string | 必填 | 业务 purpose |
| targetParty | Party | humanCall设备发起必填 | 授权用户/设备/服务目标,类型见扩展命令 |
| callType | string | humanCall必填 | voice/video |
| callPolicy | object | 可选 | floor:shared/exclusive缺省shared;busy:reject/waiting缺省reject |
| mediaSource | object | mediaPlayback必填 | contentRef:string;鉴权文件源 |
| transport | string | 必填 | none/udp/webrtc;none用于无实时媒体AI或授权文件mediaPlayback,不分配UDP或Peer |
| tracks | Track[] | 必填 | 本次请求轨;none时固定空数组 |
| inputModalities | string[] | none必填 | 输入模态;声明文件输入时必填,枚举见命令08 |
| outputModalities | string[] | none必填 | 输出模态;声明非轨输出时必填,枚举见命令08 |
| supportedInteractionModes | string[] | AI语音必填 | 本次可用模式 |
| audioParams | Audio | AI语音UDP/WebRTC必填 | 本次音频请求,须与当前能力上报一致;none不协商实时音频 |
| sourceLanguage | string | 翻译必填 | BCP47语言 |
| targetLanguage | string | 翻译必填 | BCP47语言 |
| cameraId | string | 相机场景必填 | 已上报摄像头 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s01-1",
"method": "sessionCreate",
"params": {
"purpose": "aiConversation",
"transport": "webrtc",
"supportedInteractionModes": [
"halfDuplex"
],
"audioParams": {
"format": "opus",
"sampleRate": 16000,
"channels": 1,
"frameDuration": 20
},
"tracks": [
{
"trackId": "mic-1",
"kind": "audio",
"sourceId": "mic",
"direction": "sendonly",
"codec": "opus",
"state": "requested"
},
{
"trackId": "speaker-1",
"kind": "audio",
"sourceId": "speaker",
"direction": "recvonly",
"codec": "opus",
"state": "requested"
}
]
}
}对应S01-M03;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionCreated · SIG↓
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 应答 |
| 对应应答 | — |
| 触发与状态变化 | 仅代表创建并分配媒体资源成功,不代表媒体连通;成功必须带顶层 sessionId。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 不等待ACK;重复按公共规则丢弃/重放 |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S02、S03、S09、S11 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| state | string | 成功必填 | negotiating |
| callGroupId | string | humanCall成功必填 | 呼叫组ID;各端sessionId是独立会话腿 |
| selected | Selection | 成功必填 | 平台选择 |
| selected.audioParams | Audio | AI语音UDP/WebRTC成功必填 | 本次确认的音频参数;与原请求及能力交集一致,不代表媒体已连通 |
| selected.udpReplyStartReceipt | boolean | 已明确选择AI UDP安装确认时必填true,否则省略 | 不接受false、null或在非UDP中出现;声明能力不等于已选择;会话恢复与接续不得静默升级或降级 |
| tracks | Track[] | 成功必填 | 平台确认的轨 |
| media | Media | UDP必填 | 独立会话凭据 |
| playbackId | string | mediaPlayback成功必填 | 与原邀请固定同一播放器实例 |
| mediaSource | object | mediaPlayback成功必填 | contentRef:string;授权引用,不携带URL或媒体字节 |
| inputModalities | string[] | 文件mediaPlayback成功必填 | 固定空数组,不授权采集 |
| outputModalities | string[] | 文件mediaPlayback成功必填 | audio/video或二者;确认的文件输出能力 |
| endpointEpoch | uint64 | 已协商participantRosterSync的IPC成功必填 | 平台分配本接收腿的公开绑定代次;初建为1,不是内部ConnectionEpoch,设备不得自填或猜测 |
| capabilityRevision | uint64 | 与上述endpointEpoch同时必填 | 可信平台求交集时使用的实际能力版本;旧未声明端两字段均省略 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s01-1",
"method": "sessionCreated",
"sessionId": "s01-session",
"code": 200,
"data": {
"state": "negotiating",
"selected": {
"transport": "webrtc",
"interactionMode": "halfDuplex",
"audioParams": {
"format": "opus",
"sampleRate": 16000,
"channels": 1,
"frameDuration": 20
}
},
"tracks": [
{
"trackId": "mic-1",
"kind": "audio",
"sourceId": "mic",
"direction": "sendonly",
"codec": "opus",
"state": "requested"
},
{
"trackId": "speaker-1",
"kind": "audio",
"sourceId": "speaker",
"direction": "recvonly",
"codec": "opus",
"state": "requested"
}
]
}
}对应S01-M04;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionInvite · SIG↓
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 请求 |
| 对应应答 | sessionAccept 或 sessionReject |
| 触发与状态变化 | 平台邀请;humanCall 固定 accept;direct 也必须设备确认资源和隐私状态,不能跳过 sessionAccept。 |
| 前置条件 | 平台已鉴权发起者、检查业务策略 |
| 超时与重试 | 30秒或expiresAt更早值;过期结束 |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S05、S06、S07、S08 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| purpose | string | 必填 | 业务 purpose |
| admission | string | 必填 | direct/accept |
| transport | string | 必填 | webrtc/udp/none;授权文件mediaPlayback固定none |
| tracks | Track[] | 必填 | 请求轨;文件mediaPlayback固定空数组 |
| expiresAt | int64 | 必填 | Unix毫秒 |
| playbackId | string | mediaPlayback/recordPlayback必填 | 固定播放器实例,最多128字节 |
| mediaSource | object | mediaPlayback/recordPlayback必填 | 精确contentRef:string,最多512字节;不接受额外源字段 |
| inputModalities | string[] | 文件mediaPlayback必填 | 固定空数组;不借用父AI麦克风/摄像头 |
| outputModalities | string[] | 文件mediaPlayback必填 | audio/video或二者,无重复;求交实际输出驱动 |
| callGroupId | string | humanCall必填 | 同组竞态接听,独立端sessionId |
| sourceEventId | string | 事件触发呼叫必填 | 原物模型事件去重ID |
| callType | string | humanCall必填 | voice/video |
| cameraId | string | 相机场景必填 | 已上报摄像头 |
| recordingId | string | 历史播放必填 | 授权录像 |
| recordingVersion | string | recordPlayback必填 | 1~64字节固定档案版本;由可信目录固化,不接受客户端版本代替授权 |
| clip | object | recordPlayback必填 | 精确startMs/endMs安全整数;相对整份录像的半开区间,0≤startMs<endMs≤真实时长 |
| sourceLanguage | string | 翻译必填 | BCP47 |
| targetLanguage | string | 翻译必填 | BCP47 |
| endpointEpoch | uint64 | 已协商participantRosterSync的IPC邀请必填 | 平台初建分配的本腿公开绑定;不得用组ID或内部连接时间代替 |
| capabilityRevision | uint64 | 与上述endpointEpoch同时必填 | 实际求交集的能力版本;未协商同步时两字段同时省略,不降级猜值 |
人际语音接续候选邀请
仅已声明humanEndpointHandoff的humanCall/voice/accept/webrtc完整Focus候选,允许在原七字段邀请上增加可选handoff对象。其字段固定为sourceSessionId:string(原Human源腿,1~64字节)及handoffId:string(原prepare事务,1~128字节);来源不能等于本次候选sessionId。未知字段、显式null、空来源以及向未声明能力端发送该扩展均拒绝。未扩展的普通Human及无controls接续邀请保持原七字段,不要求未声明对应能力的设备更新。
该对象只提供关联,不携带资源许可或允许UI写入修订。本人接听、实际媒体连通和当前完整资源取得分别核验;候选的业务媒体门保持关闭。正式提交后,设备还须核同原邀请、同候选会话及全局事件水位的committed事实,才可在私有事务核心继承新源修订。不能从历史commit、另一候选或同账号未声明对应能力的端复制权限。expiresAt仍是原30秒事务与原通话期限中更早的值,重投/ready不得续期;设备实际完整取得的许可仍独立受原通话期限约束。
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
历史邀请为独立受限分支,设计接线待实现:正文恰为purpose、admission、transport、expiresAt、cameraId、recordingId、recordingVersion、playbackId、mediaSource、clip、tracks,固定recordPlayback/direct/webrtc。video-1为record-video/sendonly/H264;可选audio-1为record-audio/sendonly/opus,无麦克风、扬声器或实时摄像头采集轨。设备可信清单精确绑定recordingId/recordingVersion/contentRef及真实时长,平台另绑定原用户、目标、camera、clip和期限;contentRef本身不授予用户权限。首个虚拟驱动仅支持整份档案和1倍速,部分clip须明确拒绝,不假装能精确裁剪。完整场景见支持范围。
文件邀请的严格子集恰为purpose、admission、transport、tracks、expiresAt、playbackId、mediaSource、inputModalities、outputModalities九个字段。当前子集admission固定direct,但仍须sessionAccept实际资源确认;文件引用的语法通过不等于内容授权、下载或焦点许可。expiresAt为大于0且不超过9007199254740991的整数;设备需另核验时钟与期限。视频输出不等于摄像头能力,不启动采集或视觉模型取帧。Go/C++严格解析器已补,生产创建器、能力上报及桌面分派仍待接通,见支持范围。
以下为严格文件邀请示例(设计接线待完成,时间与内容引用均为占位值,不能直接播放):
{
"msgToken": "invite-file",
"method": "sessionInvite",
"sessionId": "file-child",
"eventSeq": 1,
"params": {
"purpose": "mediaPlayback",
"admission": "direct",
"transport": "none",
"tracks": [],
"expiresAt": 1800000000000,
"playbackId": "file-player",
"mediaSource": {"contentRef": "authorized-content"},
"inputModalities": [],
"outputModalities": ["audio", "video"]
}
}报文实例
{
"msgToken": "s01-7",
"method": "sessionInvite",
"sessionId": "s01-invited",
"eventSeq": 1,
"params": {
"purpose": "ipcLiveView",
"admission": "accept",
"transport": "webrtc",
"cameraId": "front",
"tracks": [
{
"trackId": "video-1",
"kind": "video",
"sourceId": "front",
"direction": "sendonly",
"codec": "H264",
"state": "requested"
}
],
"expiresAt": 1900000000000
}
}AI跨端候选邀请
purpose=aiConversation是独立邀请分支,不借用humanCall邀请。仅同用户原endpointControl.prepare关联的候选,必须admission=accept及目标明确确认;保持原供应商模型连接和业务会话,不因邀请创建第二Provider。
| 字段 | 类型 | 必填条件 | 含义 |
|---|---|---|---|
| purpose | string | 必填 | 固定aiConversation |
| admission | string | 必填 | 固定accept,不支持direct |
| expiresAt | uint | 必填 | 原接续事务绝对截止毫秒,总窗口30秒,不因ready或重投续期 |
| handoff | object | AI跨端邀请必填 | 仅sourceSessionId:string及handoffId:string,分别指原模型会话及prepare事务;不能等于候选sessionId |
| selected | object | AI跨端邀请必填 | transport:udp/webrtc、interactionMode:halfDuplex/fullDuplex、audioParams:Audio;原源已选udpReplyStartReceipt时须同形携带true,未选省略,目标必须明确声明该能力;没有pipeline字段 |
| tracks | Track[] | 必填 | 精确两条requested音频轨,mic/sendonly、speaker/recvonly,codec=opus,轨ID不得重复 |
| media | object | UDP必填,WebRTC禁止 | 仅udp对象;server:string、port:uint、key:string、nonce:string与sessionCreated同形。密钥仅候选短效,不能作为授权 |
目标必须真实支持已选格式/模式、音频和本地确认驱动,全双工还需声明设备AEC;不能因为邀请提升能力或静默降级原模式。WebRTC固定Opus 48kHz/单声道/20ms,仍通过原mediaOffer/Answer协商。UDP实际探测或WebRTC实际ICE、明确sessionAccept、当前授权及mediaState须分别核验;ready只表示held候选可用,不表示已经发布音频。提交时原授权、focus和模型scope完成CAS及确认后才切媒体,旧工具票不得升级到新端。
{
"msgToken":"ai-invite",
"method":"sessionInvite",
"sessionId":"candidate-ai-leg",
"eventSeq":1,
"params":{
"purpose":"aiConversation",
"admission":"accept",
"expiresAt":1900000000000,
"handoff":{"sourceSessionId":"original-ai-session","handoffId":"handoff-ai-1"},
"selected":{"transport":"udp","interactionMode":"fullDuplex","audioParams":{"format":"opus","sampleRate":16000,"channels":1,"frameDuration":20}},
"tracks":[
{"trackId":"mic","kind":"audio","sourceId":"mic","direction":"sendonly","codec":"opus","state":"requested"},
{"trackId":"speaker","kind":"audio","sourceId":"speaker","direction":"recvonly","codec":"opus","state":"requested"}
],
"media":{"udp":{"server":"media.example.invalid","port":32000,"key":"00112233445566778899aabbccddeeff","nonce":"01000000000000000000000000000000"}}
}
}对应S01-M15;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionAccept · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | requestAck |
| 触发与状态变化 | 沿用邀请 msgToken。邀请答复本身是需确认的请求,等待平台 ACK 后协商媒体。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S05、S06、S07、S08 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| acceptedTracks | string[] | 必填 | 邀请轨的已接受集合 |
文件mediaPlayback邀请没有实时轨,必须明确回acceptedTracks=[],不能省略/null或虚构mic/camera轨。沿用原邀请token;接受仅确认文件输出资源,不表示已下载、加载或播放。原子持久边界见支持范围,正式Runtime单次接听路由已接线,见支持范围;持续Owner、拒绝/超时和真实C++接听仍待完成。
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s01-7",
"method": "sessionAccept",
"sessionId": "s01-invited",
"params": {
"acceptedTracks": [
"video-1"
]
}
}对应S01-M16;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionReject · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | requestAck |
| 触发与状态变化 | 沿用邀请 token;不创建媒体连接,不抢占现有前台会话。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S06、S07 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| reason | string | 必填 | 原已实现用途保留userRejected/resourceBusy/privacyEnabled;历史recordPlayback另允许公共错误分类unsupportedCapability/permissionDenied,其他用途不得据此默认扩展 |
历史档案驱动不支持所邀请的整份范围或媒体格式时拒绝为unsupportedCapability;本地可信清单/版本许可拒绝为permissionDenied,不能误报隐私已开启。两者复用公共错误分类,不新增供应商或录像专用原因。历史拒绝ACK固定result.state=ended并保留原reason;该新增用途仍待实际接线验收。
文件mediaPlayback拒绝也使用原邀请token及单一reason;ACK保留实际原因,规范会话终态为userRejected,不授予新采集/播放许可、不影响父AI。正式Runtime/原子结束已接线,见支持范围;邀请超时及真实C++设备路径仍待接通。
AI接续候选的本地用户拒接沿原邀请token及候选公开sessionId发送reason=userRejected,不使用人际通话分支的declined,不向源腿发送sessionEnd或endpointControl.abort。正式Go成功ACK回显result:{state:"ended",reason:"userRejected"}。C++本地拒接入口仅产生这一原因,因而仅接受与原请求一致的该原因;resourceBusy/privacyEnabled虽属于其它明确拒接用途的既有枚举,不能代替本次用户拒接回执。旧仅result:{state:"ended"}成功ACK保留兼容;未知键、非字符串或不匹配原因不消费原请求。此兼容只作用sessionReject,sessionAccept成功ACK仍严格只有result.state=negotiating。迟到原接听ACK不能使已拒接候选建立媒体,见支持范围。
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s01-7",
"method": "sessionReject",
"sessionId": "s01-invited",
"params": {
"reason": "privacyEnabled"
}
}对应S01-M34;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionEstablished · SIG↓
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 事件 |
| 对应应答 | — |
| 触发与状态变化 | 平台确认所需参与端媒体已连通后通知;none模式按用途确认上下文或资源就绪,不协商实时媒体;文件邀请需设备确认输出资源,不等于下载、首包或扬声器起播。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 不等待ACK;重复按公共规则丢弃/重放 |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S02、S03、S05、S06、S07、S08、S09 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| state | string | 必填 | established |
| mediaRevision | uint | 必填 | 本参与端媒体代次;transport=none固定0 |
| endpointEpoch | uint | 仅明确协商aiEndpointControlSync的AI接续目标必填 | 与capabilityRevision成对,当前目标公开腿初始≥2;不是原模型创建代次,不授予采集 |
| capabilityRevision | uint | 与上述字段成对必填 | 本次正式目标能力修订;旧目标仍只收原state/mediaRevision正文 |
AI 接续目标的首 sessionEstablished 事件水位固定为 2(邀请为 1);仅新能力携带完整控制绑定,普通会话仍遵循各用途合同。目标后续 sessionSync 沿原公开腿,不发送模型锚点。控制同步不会改变原媒体代次或轨,也不会自动恢复输入。旧完整组的实际释放、承接设备全局修订号的新基线、当前完整组实际取得是独立屏障,不用网络快照或静音代替。
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s01-4",
"method": "sessionEstablished",
"sessionId": "s01-session",
"eventSeq": 1,
"data": {
"state": "established",
"mediaRevision": 1
}
}对应S01-M09;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionEnd · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | sessionEnded |
| 触发与状态变化 | 设备主动结束整个会话,立即本地停采集/播放;平台撤销轨、处理器、密钥/令牌及资源占用。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S02、S03、S05、S06、S09 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| reason | string | 必填 | userHangup/userStopped |
当前人际voice及已完成AI转人工的人工腿另限定reason=hangup,不改变其他用途的原因枚举。AI转人工挂断的应答、双腿终态及焦点释放见S13:最多10秒受原总预算和原租约更早截止裁剪;同token精确重放不续期,已完成历史重放不启动新的媒体或释放。该增量仍待完整端云验收,不能从命令已接线推断整个场景完成。
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s01-5",
"method": "sessionEnd",
"sessionId": "s01-session",
"params": {
"reason": "userHangup"
}
}对应S01-M10;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionEnded · SIG↓
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 应答或事件 |
| 对应应答 | — |
| 触发与状态变化 | 主动结束用原 token 和 code;其他结束用独立事件 token 与 eventSeq。ended 是唯一会话终态。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S01、S02、S03、S05、S06、S07、S08、S09、S11 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| state | string | 必填 | ended |
| reason | string | 必填 | userHangup/userStopped/userRejected/inviteTimeout/mediaFailed/permissionRevoked/networkTimeout |
新人际voice候选沿现有通话代码另限定:其本腿sessionEnd的确认原因为hangup;原AI作用域撤候选后,候选两腿异步结束为callerCancelled,不是原AI挂断。拒接ACK保留原sessionReject.reason,规范候选终态为userRejected。这些原因仅对已鉴权原人工候选账本及其完整两腿关联有效,其他用途不因此默认扩展;第三屏障与实际移交仍须按S13独立完成。
对已完成AI转人工的人工双腿,挂断双方原因均为hangup。请求端沿原token/code应答;另一腿沿本腿eventSeq事件,当前实现可携带同一原请求token,但不能跨会话用token关联应答。每腿结束通知先于该腿原focusControl.release可靠投递;收到结束不等于实际焦点已released,也不保证跨设备或媒体通道同序。原AI仍为ended/transferred,不因人工挂断改成新AI会话;完整流程与原关联见S13人工挂断。
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s01-5",
"method": "sessionEnded",
"sessionId": "s01-session",
"code": 200,
"data": {
"state": "ended",
"reason": "userHangup"
}
}对应S01-M11;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
sessionError · SIG↓
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 事件 |
| 对应应答 | — |
| 触发与状态变化 | 带 code 的异步错误;不可恢复时随后 sessionEnded,可恢复错误不自动结束主会话。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 不等待ACK;重复按公共规则丢弃/重放 |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S02、S03、S11 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| scope | string | 可选 | session/response/input/tool;省略session;回复错误必须显式response |
| respId | string | scope为response或tool必填 | 只影响该回复,不能关闭其他回复或整个会话 |
| inputId | string | scope为input必填 | 失败输入 |
| toolCallId | string | scope为tool必填 | 失败调用 |
| reason | string | 必填 | 错误原因 |
| retryable | boolean | 必填 | 能否在本会话恢复 |
| mediaRevision | uint | 媒体错误必填 | 失败代次 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s02-34",
"method": "sessionError",
"sessionId": "s02-session",
"code": 502,
"eventSeq": 6,
"data": {
"reason": "modelTimeout",
"retryable": true,
"scope": "response",
"respId": "reply-1"
}
}对应S02-M22;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
更新日志
2026/10/16 16:04
查看所有更新日志
fe3a7-docs(AI与音视频): 按场景整理完整接入流程与命令契约于
