Files
go-sip/docs/通信与事件数据交互_v0.1.md
T

43 KiB
Raw Blame History

Dispatcher / Agent 通信与事件数据交互 v0.1

1. 范围、权威与状态

本文件保留现有外部命令/事件与内部职责目录,并明确本轮适用范围:P1为1 Agent/1 Asterisk/单 Cell、至少3家SIP trunk 的契约与协议 fixture、单租户、静态配置、ASR-only与完整AI双模式;真实 SaaS/MQ 联调、双节点、第二 Cell、第二租户和生产切换延期第二阶段。 全量目录不等于本轮全部实现;当前只交付设计,运行通过记录另见验收证据。

  • 外部业务字段以《SaaS交互_OpenAPI与MQ契约规划_v0.1.md》正文v1.0为权威;现有OpenAPI用于接口/字段核对。原文件名不代表正文版本。
  • OpenAPI与MQ字段索引 是5份OpenAPI、42个HTTP操作、115个命名组件及2份JSON Schema的只读机器提取快照,记录源哈希,不是第二套手写Schema。
  • 下文 “现有契约” 不允许自行改字段/语义;“内部草案” 是待批准的gRPC方法/数据模型,不冒充已有OpenAPI;“缺口” 明确阻塞相应实现/验收。
  • 用户已确认保留Unary RPC、Dispatcher维护Agent Endpoint列表、Agent共用一套mTLS证书。OSS配置源于SaaSDispatcher统一承接,Agent直传OSS。文本继续实时MQ回传,OSS只作归档。
  • 准确的文字事件名是 transcript.updatedcall.transcript 是之前讨论中的泛称,不是合法event_type,不新增该别名。
  • 首发AI范围已确认:百炼/火山ASR、OpenAI兼容LLM、火山TTS。业务控制参数由Dispatcher按任务版本向SaaS获取,Agent按执行快照使用;不得从源码常量、本地业务配置或SDK默认值形成第二配置源。具体模型/协议/额度仍须批准和PoC。

1.1 已对齐部分与仍待补齐的约束

逐字段及SHA-256复核确认,当前MQ信封已与正文对齐;本轮讨论中曾判断存在旧信封漂移,该判断已撤回,不是当前源文件缺陷。

当前正文/Schema一致内容 仍须验证
命令类别/ID command_type / command_id 拒绝旧type/message_id作为替代,保护作用域幂等
事件类别 event_type,枚举覆盖8种事件 不接受call.transcript等不存在的别名
聚合版本 aggregate_type / aggregate_id / aggregate_version 按实体域合并,不能降为全局event_version
时间 issued_at / not_after、occurred_at 区分授权、发生和接收时间,验证截止
命令payload required已含task_revision等正文12字段 类型、长度、白名单及跨字段业务规则
事件payload 目前仍主要是通用object 8种专属payload、条件必填/状态/失败分支需在上游唯一源补齐

GAP-01只指事件专属payload和未机读化业务约束的覆盖不足,不指信封字段漂移。 P0补齐并跑正反例。本轮不覆盖父项目已有文件;不能把仅通过通用object校验当完整事件验收。

1.2 分期不改变外部契约

  • P1保留call.execute、既有7条SaaS交互路径和8种事件;整体补传是现有交付可靠性能力,不是待建设的通用回放平台。
  • 42操作/115组件仅为上游目录;不把管理平台30操作移入Dispatcher。按实际入口及引用闭包生成校验,来源包/只读索引仍完整留存,不通过删Schema缩小范围。
  • 单租户仅指启用策略:保留tenant_key精确路由、租户独立队列/复合幂等键、有界窗口和单 Cell 全局配额;双租户公平、第二 Cell 汇总和多Dispatcher协调另立第二阶段。
  • P1不新增MQ模式字段、事件或临时接口。ASR-only的Schema表达须先补GAP-08R04/R06在线改配延后,但最后许可、控制、静态维护屏障和持久恢复不能延后。

2. 角色、传输和可靠性边界

通道 发送方 → 接收方 内容 接受/交付的含义
RabbitMQ命令 SaaS → Dispatcher call.execute Dispatcher事务持久受理/拒绝和outbox后才ACK
HTTP现有7路径 SaaS ↔ Dispatcher5)及Dispatcher → SaaS2 控制/查询/整体补传;录音上传申请/complete 控制202只代表acceptedcomplete为对象验证,不是业务结果回调
既有AI配置读取 Dispatcher → SaaS受控配置服务 任务引用的不可变AI版本及获授权供应商配置引用 复用§6.1的已有GET,不新增HTTP拨号或任务业务回调;Agent不直连SaaS
内部Unary gRPC Dispatcher ↔ Agent 执行授权、控制、配置、状态、最终文字、上传元信息 每个RPC有独立deadline、权限、请求关联及幂等;不是一条双向数据流
ARI/RTP Agent ↔ 本Cell Asterisk 通道/桥/媒体/录音 实际拨号副作用不与任何数据库事务原子提交
OSS数据面 Agent → OSS P1已封口录音;文本OSS归档后续 PUT成功不等于SaaS verifiedETag不等于SHA-256
RabbitMQ结果 Dispatcher → SaaS 本文8类event_type publisher confirm只表示broker收妥;SaaS用inbox+业务同事务应用,无额外应用收讫协议
SIP配置管理 管理平台 → 批准静态制品/受控部署 → Agent;D核验准入 版本/哈希/目标及实际加载事实,P1维护窗口生效 管理平台唯一编辑面;静态交接见GAP-03;在线D推送暂缓

Agent不持MQ/SaaS管理凭据、不直接消费SaaS队列,不新增公开HTTP拨号/结果回调。普通Unary同样复用HTTP/2连接,不能按每通电话新建连接。

3. 标识和版本不可混用

标识/版本 范围与用途
tenant_id / tenant_key 前者可信归属,后者原值一对一队列绑定;不清洗/编码/截断,224 UTF-8字节预算不满足时保留原任务并停发
command_id 租户作用域业务命令幂等键;HTTP Idempotency-Key及正文关联按原契约
execution_id 租户作用域授权执行,换command_id不得重复拨号
task_id / task_item_id / task_revision 任务、成员和控制版本;与软件/配置版本无关
call_id / attempt_id 一次逻辑通话与具体拨号尝试;只有持久化意图后才产生call。P1不启用自动FALLBACK;未来启用仍属原执行并计CPS
event_id / aggregate_* SaaS MQ inbox和对应实体/状态域版本;由Dispatcher持久事务分配/递增
turn_id / segment_id / revision 文字片段与最终稿替换语义,不以消息到达时间判断新旧
recording_id / upload_id / oss_id 既有录音授权、会话和验证后资产引用;不能用路径或ETag伪造oss_id
agent_id / cell_id(内部草案) Dispatcher预配置的执行端身份与Cell绑定,不能由Agent自报覆盖;共享证书不等于单节点身份
boot_id / session_epoch(内部草案) 一次进程启动及Dispatcher绑定代次;旧回报不能覆盖新会话,旧执行事实仍需对账,不直接丢弃
agent_version / protocol_version 二进制发布版本、gRPC协议版本;不是AI的agent_version_id
desired/applied revision、config_sha256 发布意图与实际加载事实;相同版本异哈希冲突,不能以文件已写代替applied

内部关联字段最终名称/格式在Proto冻结时确定。现有外部信封/配置优先以原版本JSON字节+schema引用/摘要嵌入内部消息并按源Schema校验,避免在Proto再手写一份业务Schema;不得经Struct/float转换破坏大整数、空值或哈希语义。

4. 现有call.execute完整业务入口

Routing keyagent-call.tenant.{tenant_key}.call.executedirect exchange;资源命名空间仍为agent-call。

外壳字段 语义
schema_version 已支持契约版本;不支持明确拒绝
command_type 固定call.execute
command_id、tenant_id、tenant_key、trace_id 幂等、归属、路由和追踪
issued_at、not_after 签发和每次新发起截止;不能以重投延期
payload 下表;不接受任意SIP/AI URL、凭据或主叫注入
payload字段 约束
execution_id、task_id、task_item_id 原业务归属及执行身份
task_revision 必须等于当前已生效、允许运行的控制版本
callee 原始号码,不提前拼线路前缀;服务端白名单另验
route_policy_id、caller_profile_id 服务端已配置并授权的策略/主叫引用
agent_version_id 当前租户可信、不可变AI快照
variables 白名单、类型、长度约束;非代码或任意URL
ring_timeout_ms、max_call_duration_ms 不超过服务端/供应商上限

Dispatcher先验身份/Schema/关联,再识别历史幂等事实;新执行才检查当前时效/控制/配置/资源。固定admission_deadline,准入失败有界终结,不依赖资源释放才扫描。实际发起前再次检查所有租约/控制/截止;意图已落地但是否发出未知时reconciling,不回退成无call_id的拒绝,也不重拨。

P1从管理批准的静态route_policy/caller_profile选择供应商trunk与获授权Cell,不在通话过程中改绑或自动跨供应商重拨。每家使用原始callee应用自身规则。AI模式从该租户不可变agent_version_id读取:ASR-only只占ASR资源且不调用LLM/TTS;完整模式同时校验三类AI额度,不能静默降级。当前Schema缺少明确模式表达,批准GAP-08前不伪造空LLM/TTS配置。

5. 8种SaaS业务事件全集

5.1 通用外壳

每种事件必有:schema_versionevent_idevent_typetenant_idtenant_keytrace_idoccurred_ataggregate_typeaggregate_idaggregate_versionpayload

Routing key为agent-call.{event_type}。SaaS按(tenant_id,event_id)去重,inbox与业务更新同事务,成功后ACK。Dispatcher保存版本化快照及outbox,重发保留event_id/内容,不因RPC重报创建第二个业务事件。本文不会把示例里的可选字段擅自升级成机器required;尚缺的payload Schema见GAP-01。

event_type 事实来源 / 发布者 必需或条件业务字段 时点与合并
command.result Dispatcher自身受理/控制/执行汇总 → Dispatcher command_id、command_type、status、reason_code;适用的task/execution/call关联;execute含等待/准入字段;control含requested/applied_task_revision command聚合;accepted/waiting不代表已拨;202不代表applied;重试不重复递增revision
call.status Agent经ARI观测+Dispatcher授权账本 → Dispatcher call_id、execution_id、任务关联、call_state、call_version、attempt_id、attempt状态、实际线路/Cell/出口、时间/原因;尚未定名的键在GAP-01冻结 同call/attempt域更新;只有实际证据才dialing/ringing/answered,迟到状态不回退
transcript.updated Agent的ASR/对话/播放证据 → Dispatcher call_id、turn_id、segment_id、role、revision、text、is_final、start_ms、end_ms、playback_state transcript_segment域;同段高revision替换,final不被中间稿覆盖;不等整通话OSS上传
call.finished Agent终态事实+Dispatcher对账/汇总 → Dispatcher call_id、execution_id、任务关联、call_version、outcome、起止/时长/原因、attempt汇总、资产处理快照 固定通话终态,后处理可pending,不覆盖独立资产的新状态
recording.ready SaaS complete/独立对象校验成功 → Dispatcher call_id、recording_id、oss_id、format、channels、sample_rate_hz、duration_ms、size_bytes、checksum_sha256 recording域;只报告verified资产,不携带上传凭据/公开URL
recording.failed Agent本地/上传失败、Dispatcher授权/校验失败 → Dispatcher call_id、recording_id、stage、reason_code、retryable、next_retry_at(若有) 标记资产失败,不改变通话终态;合法ready可完成恢复
transcript.failed Agent/Dispatcher发现文字缺段或不可恢复错误 → Dispatcher call_id、原因、retryable、受影响segment(适用时) 明确不完整,不能把现有部分文件包装成完整最终稿
contact.opt_out 获批业务判定 → Agent及时报告 → Dispatcher call_id、task_id、task_item_id、请求时间、关联turn/segment(若有) SaaS及时持久禁发并处理关联任务屏障,不等挂断;不自造关键词判定

中文描述但尚无精确JSON键/类型的字段(例如部分终止原因、attempt汇总、失败细分)必须在GAP-01中按上游定义补全后生成;不得由Go实现自行发明。表中源于既有样例的具体键须通过正文/机读联合验收。

5.2 文字与资产语义

  • role建议customer/agent/systemplayback_state为not_applicable/generated/sent/playback_confirmed/cancelled/unknown,具体冻结按主契约。生成/发送不等于已听见。
  • 当前同段final同内容幂等、异内容冲突;未来允许修订须改契约。超长turn拆稳定segment,不截断文本。
  • call_state允许queued→dialing→ringing→answered→ended,省略未发生阶段;waiting是命令状态。reconciling不是虚构终态。
  • recording的pending/uploading/verifying/ready、transcript的pending/streaming/finalized/failed、delivery的pending/broker_confirmed/failed分别维护。
  • call.finished先到、较低版本的独立recording.ready后到仍应合并;不能用全局最大版本滤掉资产/片段。
  • 文本OSS归档不是第9种既有事件,也不能冒充recording.ready;查看实时文字继续用transcript.updated。归档授权/引用扩展见GAP-02,P1不启用且不阻塞实时文字。
  • ASR-only仍上报真实customer文字及获批opt-out事实,不伪造agent回答/播放或接通证据。两模式下角色/播放状态/失败分支的合法组合须在GAP-01/GAP-08补齐;不能为省事关闭实时文字或opt-out。

6. 现有HTTP接口归属与字段查阅

全部参数、请求/响应、错误和Schema见 字段索引。保留的7个SaaS业务交互路径为:

方法/路径 新实现归属 注意
POST /internal/v1/outbound/tasks/{task_id}/controls Dispatcher提供 expected_task_revision CASpause/resume/stopstop显式drain/hangup及权限;202≠applied
GET /internal/v1/outbound/commands/{command_id} Dispatcher提供 command聚合快照和等待/准入字段
GET /internal/v1/outbound/calls/{call_id} Dispatcher提供 通话/attempt与独立资产状态快照
POST /internal/v1/outbound/calls/{call_id}/replays Dispatcher提供 固定截止点整体补传,不支持局部事件/turn筛选
POST /internal/v1/outbound/commands/{source_command_id}/replays Dispatcher提供 command尚无call也可补传;保持原ID,不递归自身结果
POST /internal/v1/outbound/recording-uploads SaaS提供,Dispatcher调用 租户/幂等/录音元信息校验;Agent不直接感知SaaS认证域
POST /internal/v1/outbound/recording-uploads/{upload_id}/complete SaaS提供,Dispatcher调用 对象独立验证;verified之前不得发布recording.ready

若源OpenAPI的实际路径/参数变化,先同步源指纹和索引,不按本表猜测实现。HTTP作用域、Idempotency-Key、tenant/target绑定、404/409/410等保持原语义。AI配置作为实际需要的外部配置源消费,不重建其管理面;管理平台30操作不移入Dispatcher。Cell的3个mTLS操作保留参考,P1可经批准静态制品交接而不暴露旧在线apply面;不能同时让管理平台、部署脚本和Dispatcher各自写同一配置。

6.1 SaaS任务配置 → Dispatcher → AgentP1必需)

“任务配置”沿用MQ任务的 agent_version_id 及获批 variables 引用:Dispatcher调用已有 GET /internal/v1/ai/agent-versions/{agent_version_id} 获取SaaS维护的不可变配置,不新增猜测的task-config路径。AI配置发布接口仍由上游拥有,D/Agent不另建编辑面;该GET由哪个SaaS部署入口承载、鉴权/租户绑定及provider_ref的受控解析合同在GAP-09冻结。其不改变前述7个业务交互路径的定义。

  1. D先验MQ可信租户/版本/幂等;历史执行走原事实恢复,不因调参重新执行。新执行在发起前取得对应租户版本,不把模型/音色/timeout等直接加入call.execute。
  2. D验证源Schema、不可变内容摘要、租户授权、两种模式和SDK能力,解析该版本批准的provider_ref/credential_ref。SaaS返回的受控供应商配置提供API种类/协议版本、端点、region/资源标识等;缺合同标blocked,不在源码中按供应商名称拼端点或填示例resource_id。
  3. 缓存键至少绑定租户和agent_version_id;同版本异内容拒绝并告警。按批准的撤销/新鲜度策略使用已验证缓存;SaaS不可达且无仍有效的已授权快照则暂停/拒绝新准入,遵守原admission_deadline,不用默认模型、其它租户缓存或无限期旧配置顶替。HTTP读取可有界重试,不持SQLite事务等待网络。
  4. D将该执行最终有效配置、源版本/摘要及SDK能力匹配绑定到原execution。沿获批R07传送原Schema JSON/摘要或已确认缓存引用;引用缺失可经R03受控获取,不依赖延后的R04热更新。A二次校验并报告实际使用版本/摘要,错版本不进入最后许可。
  5. Agent从会话局部只读快照生成SDK请求和本地控制器参数;可复用连接/Transport,不修改所有通话共用的model/voice/temperature等全局对象。首发有明确的百炼/火山ASR薄适配,选择一次固定到执行,不建插件、自动AI fallback或同通话动态换供应商。
  6. 在已支持并获授权的模型/参数范围内,调参在SaaS发布新AI版本,由新任务显式引用后生效,无需改Go代码、重建镜像或重启D/A。排队旧任务/在途通话固定原版本,不能读取“latest”热改;授权撤销/stop仍按控制协议收敛,不以快照固定为由忽略撤销。

静态发布仅指SIP/节点部署配置,不意味着AI业务参数写死。 配置读取不是业务结果HTTP回调;实际音频仍A↔供应商,SaaS/D不代理音频流。

6.2 参数覆盖与缺口(需求索引,不是新Schema)

现有严格对象 additionalProperties: false 必须保留。下表“已有”是当前源字段;“待补”是P0向上游提交的语义需求,不是可直接发送的JSON键/已获批枚举。每个启用参数须在批准的SDK/模型能力矩阵中有单位、范围、缺省、对应请求字段或本地控制点及测试证据。

控制范围 当前源契约已有 首发需补齐/确认的可调能力
通用供应商/模式 各AI的provider_ref、credential_ref、modelagent_version_id GAP-08两模式;GAP-09受控端点/API版本、模型能力、火山app/resource/cluster及认证类型引用的来源/授权,不把密钥作为普通配置值
ASR输入与结果 asr.language/interim/timeout_ms/inputencoding/sample_rate_hz/channels/sample_width_bytes 模型必填或明确缺省、实时中间稿/最终稿行为、发送帧时长/块大小及结束规则;不能沿用示例16kHz覆盖源配置
ASR识别调试 当前未定义这些专属字段 所选协议支持的热词/词表引用、标点、ITN/文本规范化、语气词/顺滑控制、语种提示、VAD/端点检测/尾部静音阈值;百炼与火山分别映射,不假设同名同义
LLM模型/采样 llm.model/temperature/max_tokens/timeout_ms top_p、stop序列、上下文轮数/Token预算;供应商确有需求和支持时补penalty/seed/推理控制,不能把任意extra JSON透传。max_tokens与实际API输出/推理Token语义须匹配
提示词与变量 prompt.text/allowed_variables/max_bytesMQ variables 渲染失败/缺变量/超限明确拒绝,不执行模板代码;上下文截取策略可审计,不把正文或变量值写入普通日志
TTS声音与音频 tts.model/voice/speed/timeout_ms/formatencoding/sample_rate_hz/channels 所选火山协议支持的音量/增益、音调,以及确有需求的情感/风格;语速/音量单位和范围显式映射,不靠示例speaker/resource_id默认值
对话/打断 conversation.opening/allow_interrupt/silence_timeout_ms/max_duration_ms/max_turns 本地与服务端VAD职责、触发打断的最短语音/防抖等适用阈值;只由可信配置控制,关闭打断也必须保留stop/hangup权限
分句/缓存/时序 conversation.sentence_max_chars/max_pending_audio_chunks;各AI.timeout_ms 分句等待、音频缓存按时长/字节的上限、连接/首结果或Token/首音频/流空闲/总时限的作用域;SDK超时与本地看门狗不能互相覆盖

首发必须把已有字段和实际选定模型支持、商务调试需要的上述扩展接通;不为不存在的模型能力造兼容层。未支持参数要在发布/准入时报明确错误,不能“接受但忽略”;必要参数缺SDK支持则对应能力blocked(见组件清单§4.3)。

6.3 默认值、适配与安全边界

  • SaaS发布不可变版本时按获批Schema/供应商能力物化默认值并留来源;JSON Schema的default只是注解,不能假设校验器会自动填。过渡中缺必需有效值则拒绝,不从Go常量、env、SDK默认或示例请求补业务值。协议固定常量及部署安全上限不属于可任意调参范围。
  • 区分未提供、null、显式0/false/空列表;例如temperature=0、interim=false、allow_interrupt=false不能被Go零值/omitempty或SDK设置器吞掉。条件必填与缺省由上游定义,不能因ASR-only跳过整个配置校验。
  • SDK请求字段/单位按批准映射转换,保留requested/effective的脱敏差异;越界、冲突、不支持报可定位字段原因,不静默截断/钳制。总通话时限不得超过MQ命令、授权及平台上限,组合规则G0冻结;任务不能通过调大timeout突破stop/许可/资源硬屏障。
  • provider端点只能来自可信SaaS配置并命中受控host/协议/端口及出口策略,禁任意重定向/内网探测;localhost或IP直连例外须显式管理批准。credential_ref按租户/供应商/执行授权解析,由受控Secret/短期授权交付;Agent不持SaaS管理凭据,不把密钥、prompt、完整请求/对话记入日志。
  • 供应商差异只通过上游批准的有类型、有限范围配置扩展表达;不得借metadata、variables、自由headers或raw_request字典绕过严格Schema。部署只提供身份/网络/硬限额/Secret,不覆写业务模型/音色/语速等值。
  • 默认禁用可能重复计费/播放的AI SDK自动重试(OpenAI显式WithMaxRetries(0));未来开启须有批准的副作用/幂等语义,不因SaaS配置了retry就无限重发。已出流/已取消/结果未知不可重放旧生成。
  • 调试证据仅含获授权的租户/执行关联、配置版本/摘要、SDK及协议版本、参数名/脱敏有效值和拒绝原因;不新增公共调参API。普通日志不打印prompt/变量/密钥,敏感缓存按独立持久化权限和保留策略管理。

7. 内部gRPC公共规则(草案)

以下方法名/字段组用于P0审议,尚无.proto或代码生成物,不作为新增SaaS接口。

  • 采用官方grpc-go与protobuf,全部Unary;两个角色都可作为受控gRPC客户端/服务端,共用HTTP/2连接池。
  • 方向认证:Agent只接受受信Dispatcher角色的管理调用;Dispatcher只接受Agent群组证书和有效节点会话。共享证书只证明群组,不证明agent_id。
  • 元数据至少表达协议版本、request/trace关联、已绑定Agent/Cell/boot/会话代次、操作幂等标识、截止时间;具体字段冻结,不把敏感token放业务payload或日志。
  • 外部租户身份从Dispatcher已受理执行绑定,Agent报告不能切换tenant/call/asset归属。动态地址只能从预配置Endpoint列表获得,不执行Agent自报URL,防SSRF/错误绑定。
  • 请求幂等键必须包含操作和目标;同键同内容返回原结果,同键异内容冲突。RPC超时只表示结果未知,不能自动重拨;查询/恢复保持原标识。
  • Execute/Control/Apply返回accepted只表本地接收/持久文件记录;真正applied/终态通过回报或查询确认。业务“不能执行”与gRPC传输错误分开。
  • 重要执行/资产事实先写Agent文件,Dispatcher将事实去重、业务更新与MQ outbox同事务持久后才返回成功。回包丢失重报原fact,不新增MQ事件;该内部确认不是SaaS应用收讫。
  • 状态采样可以覆盖旧快照,最终文字、opt-out、终态、资产事件不可静默丢弃。有界重试/背压,接近文件容量阈值停新准入而非丢事实。
  • 事实的source_sequence/boot用于关联和诊断,不能用Agent全局最大序列丢掉其它通话或迟到资产。认证的当前会话与事实发生时的boot分开;合法历史文件经当前会话上报仍需按原执行对账,不能仅因旧boot丢弃。
  • Proto留存已发布字段号,不复用删除字段;兼容范围、未知枚举/能力降级和gRPC最大消息/超时/并发在G0 profile冻结,不以4MiB库默认值代替契约。

7.1 错误分类与重试(内部草案)

gRPC状态/业务情况 调用方动作
UNAUTHENTICATED / PERMISSION_DENIED 不重试成其它身份,更新批准凭据/会话或隔离并告警;不能据此释放未知通话
INVALID_ARGUMENT 拒绝坏字段/Schema/尺寸,不自动改写为另一任务
FAILED_PRECONDITION 未引导、版本/配置/资产契约未就绪等先修条件;文本归档缺接口不能fallback录音
ABORTED / ALREADY_EXISTS CAS/归属冲突或同幂等键异内容,查询原决定,不换ID绕过
RESOURCE_EXHAUSTED 按受控退避/原截止反压;先确认是否已accepted,不重复占额度
UNAVAILABLE / DEADLINE_EXCEEDED 结果可能已发生;查询/对账,仅对获批幂等操作重试
CANCELLED 取消本次RPC等待不等于停止已获授权的通话;业务停止走明确控制命令
NOT_FOUND 查询目标未找到,不足以证明从未拨过/未上传;结合中央事实和持久文件判断

传输错误码不直接映射SaaS业务reason_code,后者仍由正文契约及事实决定;已接受长任务通过后续报告完成,不持有一个长时间阻塞RPC。

8. Unary职责目录与首发子集(内部草案)

字段组均为数据需求,不是已批准的字段编号。对已有HTTP/MQ结构用源契约引用,不重写第二套结构。

P1保留R01R03、R05、R07R13的实际职责;R04/R06在线改配延后。 方法数不作为交付指标,G0可批准合并简单职责,但不能省略许可/控制/查询/事实持久确认/录音交接,也不先生成未用服务空壳。R03用于初次绑定后的策略/版本引用;静态制品由受控部署入口提供,不依赖R04/R06才能启动。

ID / 方法职责 方向 请求数据 响应与副作用
R01 GetAgentStatus D→A 已配置Endpoint目标、请求关联;激活前只允许Dispatcher身份做受限探测 返回boot/版本/能力/采样/加载快照;不会发起电话、不回凭据
R02 ActivateAgent D→A D确定的agent/cell绑定、boot、会话代次、受限会话凭据/期限、协议选择 A校验目标/本地既有归属,保存会话;D持久绑定后才可取敏感配置;冲突或旧boot隔离
R03 GetBootstrap A→D 群组mTLS+激活后节点会话、已知运行配置版本 未激活只返回pending/非敏感兼容信息;已激活返回本Agent运行策略、SIP/AI期望版本索引、OSS策略引用,不返回全局凭据库
R04 ApplyRuntimeConfig(后续) D→A 不可变运行配置版本/摘要/前置版本、适用Agent/boot/会话;受限凭据引用或密封交付 校验、原子应用、报告结果;配置不合法/依赖不可用则not-ready,不覆盖最后已确认可用版本
R05 SetAdmissionState D→A 受影响trunk/资源范围、发布/维护屏障标识、关闭/开放条件、目标代次 关闭新准入并报告许可/预留/拨号/振铃/已接通/未知占用;开放需D确认,不是SaaS任务控制事件
R06 ApplyTrunkConfig(后续) D→A Publication原结构:mode/cell_id/trunk_id/revision/expected_local_revision/config/config_sha256,加已冻结内部屏障关联 SDK/生成器校验和实际加载;沿用Acknowledgement/State语义,未知不假applied;缺屏障拒绝破坏性reload
R07 Execute D→A 正文call.execute原版本JSON、已持久call/attempt/通道关联、唯一归属/资源许可、路由及配置版本引用 接受/拒绝;不等待整通话;同execution不重拨,ARI响应丢失转对账
R08 GetExecutionPermit A→D 原执行/attempt、配置/控制/会话版本及许可关联 D核验控制/时效/完整配额后给有界最后许可或拒绝;所有发出许可纳入pause/发布屏障,不能重复退款/发额度
R09 ApplyTaskControl D→A 原ControlRequest语义、task/租户目标、requested revision、持久控制命令及授权策略 accepted/applying;真正屏障/挂断确认后回报applied;pause/drain保留已拨出/振铃及已接通的原生命周期,stop hangup另验权限
R10 QueryExecution D→A 原执行/通道关联或受限分页对账请求 返回Asterisk观测、执行文件/未交付资产状态及证据时间;通道不在当前列表不证明从未拨过
R11 ReportExecutionEvent A→D 稳定fact标识/内容摘要、执行/通道归属、观测时间、来源序列、事实类别及源业务数据 D事务去重并生成/关联权威MQ事件,成功回持久接收结果;调用方不指定aggregate_version跳过D裁决
R12 RequestUpload A→D 绑定执行的资产类别/稳定ID、size/checksum及源录音元信息;同一资产的显式重试申请(新15分钟 token) recording调用SaaS upload-request;返回受限目标/headers/期限/会话。text_archive分支在GAP-02冻结前拒绝,不伪装录音
R13 CompleteUpload A→D 原绑定资产/会话、实际文件元信息与完成事实 D幂等调用SaaS complete、验证后提交资产状态/outboxtext_archive同样受GAP-02门禁,不以PUT回报直接生成ready

P1的R05/R09及静态维护必须校验目标/版本并收敛R08许可,不长期锁SQLite等网络。未来R06同样纳入屏障;“全部Unary”或“静态配置”都不等于无需业务屏障。

8.1 内部事实与外部事件映射(草案)

下表列全R11/R13需要承载的事实种类;名称只是草案标签,不新增RabbitMQ event_type。Agent报告事实,Dispatcher裁决全局状态/版本。

类别 来源/入口 必须关联的数据 Dispatcher输出
执行接收/拒绝 R07结果及R11 原命令/执行/意图/Agent/boot、是否已持久接收、拒绝原因 更新内部投递状态;按命令状态机发command.result,意图已建立的失败不伪造无call拒绝
通话阶段观测 ARI→R11 call/attempt/通道、线路/Cell/出口快照、观测阶段/时间及证据 call.status;不能仅凭本地计时报告dialing/answered
通话终态 ARI/执行器→R11 原执行/通话/attempt、终止来源/原因/时长、未决资产 对账后call.finished及对应command.result,后处理不阻塞终态
最终/中间文字与播放 ASR/AI→R11 turn/segment/revision/text/final/播放证据及时间范围 transcript.updated;不把生成当已播放
文字失败 R11 通话、受影响段/原因/可恢复性 transcript.failed
拒绝再联系 获批判定→R11 通话/任务/成员、请求时间/段关联 contact.opt_out,及时驱动SaaS禁发/任务屏障
控制屏障/挂断进度 R09/R11/查询 command/task/revision、目标范围、旧许可与各阶段占用、挂断事实 D汇合所有必要目标后才command.result applied
配置加载/失败/恢复 P1静态部署后R01/R11;后续R04/R06 静态制品/目标关联、Agent/boot、desired/applied/revision/hash、实际加载证据 P1留存加载证据/AgentStatus;在线管理发布回执后续,不新增SaaS业务事件
资产上传/交接/失败 R12/R13及失败R11 绑定资产/会话、文件封口/size/checksum、SaaS verified结果或错误 recording.ready/failed;成功以SaaS校验为准,文本归档扩展受GAP-02限制

健康采样走R01,不把每次心跳作为持久业务MQ事件。节点移除要先保留受控只收尾状态直到原执行/资产对账完成;强制移除需显式人工恢复路径,不能一删Endpoint就丢弃待交付事实。

9. Agent状态数据字典(内部草案)

通过R01周期查询;样本时刻、接收时刻、采样窗口及缺失原因都记录。指标缺失是unknown,不填0。gRPC health SERVING只表示服务能响应,不能替代可拨号判断。下表为能力目录:P1只冻结身份/boot、协议、准入所需CPU/内存/FD/媒体/spool资源、静态applied版本、线路与本模式AI健康;完整IO/负载历史、staged发布态及大清单分页按需后续建设,不能让非准入遥测缺失阻塞整个首发。

数据组 字段需求/语义 调度用途
身份与会话 预配置agent_id/cell_id、boot_id、会话代次、启动时间、最后采样序列 拒绝错节点/旧boot/乱序覆盖;发现重复实例时隔离新准入
软件 二进制版本/构建提交、gRPC协议/功能能力、配置Schema/生成器版本、Asterisk版本及镜像标识(可核验时) 不兼容禁止调度;同项目更新不要求两角色同时瞬间升级
整机 OS/架构、CPU核数/使用率、load1/5/15、内存可用/进程RSS、FD使用/上限、磁盘与spool容量/IO 拒绝过载而非越配;区分宿主机、容器/cgroup和进程口径
媒体资源 媒体端口总量/已分配/可用、已知通话阶段数、RTP丢包/抖动/包率、ARI连接与事件滞后 资源不足/证据过期则跳过,不能把CPU空闲当可无限拨号
配置 每provider/trunk的desired、staged、applied版本/摘要、加载确认时间、状态/错误/发布屏障 匹配本次路由的精确已加载版本;pending/failed/漂移不接新任务
SIP线路 受配的provider_id/trunk_id、transport/codec能力、注册是否适用及状态、受控健康观测、出口/白名单核验状态 “支持协议”与“已配置且获授权供应商”分开;不把不需注册线路当注册失败
凭据 仅引用/版本/可用性/到期信息,不返回密钥正文 过期/不可解析阻止新准入并告警
AI与资产 可信agent_version缓存可用性、ASR/LLM/TTS依赖健康;待上传条数/字节/最老年龄、最近失败/重试 按模式必需资源与spool门禁;未启用能力明确标注,不把Mock变real
就绪 registering/bootstrapping/ready/draining/degraded/offline/quarantined等内部状态及原因 最终是否调度由D以权威配额、最后许可及新鲜状态综合决定

使用gopsutil/标准库/ARI SDK,不自写/proc解析器;不读取不必要的用户环境、设备序列号或完整配置秘密。P1仅回传有界静态供应商清单/必要状态,不先建分页服务。新鲜度使用D接收时间,Agent壁钟仅作观测,偏差按既有profile保护;ASR-only不会因未用的LLM/TTS离线变not-ready,完整模式不可缺任何必要依赖。

10. 文件、事件和OSS交付

10.1 Agent文件最小集合

每个执行/资产有受控目录与元信息文件、文字追加文件、音频临时/封口文件、待回报事实及上传进度。字段记录原tenant/execution/call/attempt关联、内容摘要、是否封口/验证/已被D持久接收、下一步恢复动作;目录名不得直接拼任意tenant_key/外部路径。

关键元信息先同步到盘后原子替换,文件单写者、追加记录尾部可识别,不把Flush当Sync;不创建Agent SQLite、通用数据库或自造消息中间件。重启扫描只恢复对账/上传/上报,不重跑originate。录音用现成Asterisk/音频能力,不手写WAV头。

10.2 录音时序

  1. 接通开始流式记录实际双向音频;实时文字同时走R11,不等资产封口。
  2. 完成/取消时正确封口;故障时保留完整段并明确不完整状态。
  3. A调用R12,D复用原录音身份向SaaS申请授权;CALL_NOT_REGISTERED保留原文件稍后恢复。
  4. A按指定HTTPS目标/headers直传OSS,不持长期AK;签名失效续原会话,对象ID/内容绑定不变。
  5. A调用R13D完成SaaS独立对象校验,verified后事务落资产状态和recording.ready outbox。
  6. D可靠发布MQ;A只有取得“D持久接收”还不够立即删文件,仍须满足既有verified、ready交接、无未决恢复、至少24h测试保留条件。

10.3 文本归档

P1保留本地文字恢复文件和实时transcript.updated;文本OSS归档延后,是额外资产,不替代实时文字和opt-out。

需要SaaS另定义文本归档授权/complete/引用:资产类型、ID、JSONL或其它格式、编码、内容清单/哈希、segment版本、完整性/失败、保留和查询权限。现有recording接口没有这些定义,不能用wav/recording_id伪装。 未冻结前明确“文本OSS归档未启用”,不影响已批准的文字MQ链路;也不宣称该需求已实现。

11. 断连、重复与乱序处理

故障 必须执行 禁止行为
Execute超时/响应丢失 原ID查D事实及Asterisk/文件,必要时reconciling;SDK不能无条件重试副作用 换execution/attempt/Cell重新拨号
ReportEvent回包丢失 A重报同factD关联原event_id及版本 新建一个语义重复MQ事件
D不可达 A停新执行,已有获授权通话按原策略继续、文本/录音/结果落盘;恢复补报 因断RPC就伪造call.finished或直接释放未知占用
A新boot/失联 D保留未知占用,重新绑定前对账、核验配置/许可;不自动迁移活动通话 看到新boot的0通话就清旧配额
配置部分成功 阻塞受影响资源、保留真实installed快照、对账/回滚也要确认 只改desired/active指针就重新ready
OSS成功但complete/回报丢失 原资产/会话幂等恢复;防旧签名覆盖verified对象 新建另一份资产或重拨
D恢复较旧SQLite备份 停新准入、恢复唯一所有权、比对A/MQ/资产事实再开放 恢复过期许可/遗漏幂等水位后直接运行
永久丢盘 报明确资产/文字失败与告警,仍对账SIP副作用 假称文件可恢复或用合成内容替代

12. P1静态发布与后续在线发布

P1数据流:管理平台审批不可变制品 → 核验来源/版本/哈希及单 Cell 授权 fixture → D/R05关闭受影响资源新准入、收敛许可/占用 → 维护窗口由受控部署入口原子交付/加载或重启 → R01/R10及Asterisk实际加载证据核验 → D恢复满足条件的资源准入。初装也先核验再ready;有未知占用不得跳过屏障,失败/人工恢复均重新核验,不靠旧active指针自动开放。

PublicationAcknowledgement/State见字段索引。GAP-03只先批准P1静态制品/加载事实所需适配:精确cell/trunk、revision、config_sha256、来源和唯一写入路径;不私改现有Schema、不假称在线API已支持。凭据仍用credential_ref受控解析,不能塞入MQ。

未来在线发布才增加D持久发布编排、R04/R06推送、全目标回执/动态新增移除/自动回滚。P1静态节点清单的人工变更和凭据轮换仍须维护/排空/重激活;稳定SIP配置不逐呼改写。配置变更不自动授权真实测试呼叫或额外注册探测,管理平台30个业务API不搬入Dispatcher。

13. 缺口与冻结责任

G0开发准备与契约冻结方案 D01–D10方向及模式/许可/恢复机制已获用户确认;下表仍跟踪尚未交付的源字段/合同和验证,不再表示已确认方向待用户审批。该文档不是第二套Schema,权威源发布并验证后才关闭相应GAP。

D07已确认:Agent通过R12从Dispatcher获取受限OSS配置,随后Agent→OSS直接上传文件内容R13只向Dispatcher提交原资产/会话及上传元信息。Dispatcher不代理/转发录音文件,仍负责SaaS会话申请/completeverified后经MQ回传OSS ID;每次下发token有效15分钟,过期后仅接受显式重新申请,不自动续期;Agent不直连SaaS不等于不能直连OSS。

ID 缺口 文档处理/退出条件
GAP-01 信封已对齐,但8种事件payload专属Schema及部分条件规则未完整机读化 在上游唯一生成源补齐并验正反例;未覆盖部分阻塞冻结/业务上线,不能以object校验冒充完整验收
GAP-02 SaaS录音配置来源/作用域、文本归档授权/complete/引用缺口 P1确认录音配置由SaaS提供并沿用2接口取得受限上传信息,不增加第二配置源;文本归档合同延后,不阻塞录音/实时文字
GAP-03 静态制品交接与后续在线管理发布适配 P1先批准静态版本/哈希/目标/来源/加载事实及唯一写入合同,旧直写停用;完整在线发布/回滚和R04/R06延后
GAP-04 首发Unary及身份/许可/状态结构尚无批准Proto P1冻结R01R03/R05/R07R13实际职责、字段/错误/幂等/大小/超时;可获批合并,R04/R06不先造空框架
GAP-05 共用证书的单节点授权与全组泄露风险 保留用户共用证书决定,但必须有受控Endpoint、独立D身份、自动节点会话、重放隔离及全组轮换/撤销演练;不能宣称节点级证书隔离
GAP-06 首发资源保护、模式能力、单 Cell 授权/限额与维护窗口 P1登记受限profile及基础恢复条件;缺必需能力拒绝,低负载不越额;SIP 外呼增加 Asia/Shanghai 09:0020:00 时间门禁。复杂评分/滚动升级后续
GAP-07 单活D故障/人工恢复目标与永久资产损失 P1核验唯一所有权、SQLite备份/恢复/对账、文件损失和RPO/RTO;跨机自动HA后续,不新增PG/NFS共享
GAP-08 当前AI Schema强制llm/prompt/tts/asr/conversation且无明确ASR-only表达 P0由上游批准两模式选择/缺省、条件必填、资源/超时及文字播放/失败语义并生成校验;不增临时MQ字段、不伪造LLM/TTS配置,两种真实模式都通过才可P1签收
GAP-09 SaaS任务AI配置的读取归属/授权、provider_ref解析、调试参数和有效快照尚未完全机读化 确认已有AI版本GET由SaaS承载及租户/版本绑定;在唯一源补§6.2实际参数、单位/默认/范围/能力、缓存撤销及摘要/Unary交接规则;锁定百炼/火山ASR、OpenAI兼容LLM、火山TTS参数映射PoC。不加临时路径或任意透传,SDK缺字段先补库/替代

具体验收见 验证与切换验收 §1.1–§1.2。GAP-01/05/07/08/09及GAP-02/03/04/06的P1部分均为首发门禁;延后部分只在相应功能启用前冻结,不能记为通过。“文档齐全”不等于契约已获批。