Files
go-sip/README.md
T

93 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# go-sip
Go SIP 调度与执行项目:同一 module/二进制通过 Cobra 提供 `dispatcher`、`agent` 两个业务子命令,分阶段替换 Python。现行**外部** SaaS↔Dispatcher 合同仍为 MQ-only;本轮**项目内本地 Mock** 目标为四条只读 HTTP GET、v3 MQ 及单份最终结果,其中只有任务发现改按 [`docs/thirds/v0.2.md`](docs/thirds/v0.2.md) §2.5,其他本地 SaaS 协议仍按 v0.1。项目内提案和 Mock 不代表 SaaS/management 已签收或上线。
> **当前状态:F00–F04、F08、F09 与项目内 Mock C 已完成本地适用验证;F06 的本地制品/拒绝门禁通过,真实部署和切换未执行。** P1 业务模块覆盖率均 ≥65%(MQ 须带 RabbitMQ 集成测试);CLI 和历史包未达线单独列为技术债,不宣称全仓达标。默认 Mock 不生成真实录音,上传成功/失败分支由隔离测试注入合成事实。真实 SaaS/MQ、供应商/ECS、Asterisk 媒体、生产切换及第二 Cell/第二租户仍属未验证或后续阶段;缺少 Asterisk/tcpdump 时部署 preflight 按要求 fail-closed,未冒充 mixed/real 通过。
> 本项目已独立拆仓运营;源码、配置、依赖、迁移、测试、部署和文档均在此目录内维护。远程仓库为 `git.ipao.vip/rogee/go-sip`,本地 Git 默认分支为 `main`;真实外呼仍受逐次授权、capture-first、白名单和时间门禁约束。
## 已确认的范围
- 使用 **Go 1.27.1**、Cobra单项目双命令和同一发布制品;角色分进程、权限/目录分离。
- 不接PG:Dispatcher独立SQLite统一任务/配额/outbox;Agent无业务数据库,文本/录音/必要恢复信息落文件。
- 内部 **Unary gRPC**;Dispatcher配置Agent Endpoint列表,Agent业务启动只需Dispatcher Endpoint,证书/监听/本地资源通过部署提供。
- 所有Agent共用mTLS证书、Dispatcher身份独立;需Endpoint主动激活/受限节点会话,不能把群组证书当单节点身份。
- 本次以稳定、快速单节点上线为目标:**1 个 Agent、1 套 Asterisk、1 个单活 Dispatcher、单 Cell、至少 3 家独立 SIP trunk 的契约/协议 fixture、1 个内测商务租户**;双节点、第二 Cell、双租户延期第二阶段。
- SIP 使用管理平台批准的不可变静态快照;维护窗口发布、排空和实际加载确认保留,在线动态发布/回滚编排暂缓。**现行真实路径**仍受 Asia/Shanghai 每日 `09:00`(含)至 `20:00`(不含)及白名单门禁约束;任务×线路时段与任务排除日期仅在本地 Mock V3 验证,不放开真实试拨。
- 有适用开源库/官方 SDK 时强制复用,不从零手写 SIP/ARI、RTP、MQ、数据库、OSS 或 AI 协议客户端;选库失败先报告阻塞,不静默转自研。
- 重写完整 Agent:调度控制面、Cell 外呼执行、ARI/RTP/录音、AI 流式适配、Cell 配置接收。
- 分阶段迁移,最终构建、测试和运行不依赖 Python、父仓库目录或其它业务项目内部代码。
- Asterisk 继续负责 SIP;独立 SIP 管理平台继续拥有配置管理权,均不纳入重写。
- **外部运行基线与本地目标分开**:当前真实 SaaS↔Dispatcher 仍按已发布 MQ-only 合同工作。P1 本地目标按项目内契约采用四条只读 HTTP GET(SIP 全量、单任务含智能体、归属任务清单、按 `tenant_id` 取额度)和 v3 MQ 命令/控制/回执/唯一最终 `call.result`,移除对外 query/replay 及拆分通话事件。F01/F07 Schema、正反例、来源/hash 与 Mock C 已通过,F02–F04/F08/F09 本地验证见下文;外部兼容仍未验证,不扩为多 D 协调/HA。
- **OSS配置存于Dispatcher配置文件,Agent向Dispatcher领取临时上传TOKEN后直传OSS,不保存长期凭据。** SaaS不下发OSS配置/TOKEN;D保留SDK签发能力,不转发文件。上传不申请SaaS会话、不等待verified/OSS ID或业务处理回复;D仅在原上传事实可靠进入指定持久MQ队列后记录交付完成。实时文字仍为 `transcript.updated`,归档不能替代实时事件。
- 本次必须支持 **ASR-only** 与 **ASR + LLM + TTS** 两种模式;本阶段已完成本地/协议隔离双模式验收。百炼/火山ASR、OpenAI兼容LLM、火山TTS的真实供应商能力和生产参数联调仍标第二阶段/未启用,不能将 Mock 写成真实供应商通过;禁止复用旧LLM/TTS。
- **现行 AI 配置**按任务 agent_version_id 经 MQ 向 SaaS 取得并持久绑定;过去独立的 AI GET 已废弃。**新目标**将获授权的智能体配置放入任务只读 HTTP 响应,不复活旧 GET 或保留 MQ 配置回退。 模型、提示词、音色/语速、识别、超时/打断等参数不写死;新版本用于新任务,无需重启,在途通话固定快照。静态SIP发布不代表AI配置静态硬编码。
- 本轮验收范围收敛为单节点、单 Agent、单 Cell、单租户;保留 tenant_key 原值、独立队列、复合幂等和有界窗口。双节点、第二 Cell、双租户公平/背压/恢复不在本轮开发或验收范围,作为后续阶段。
- 当前外部上传合同仍是 R12 临时授权、Agent 直传、R13 报告及 `recording.uploaded` 可靠入队。P1 本地目标改为每通话一份最终 `call.result`(含 `uploaded/unavailable/not_created`),不再发送拆分录音/实时文字/拒联事件;15 分钟收口、8 MiB 消息体上限及超限 outbox 阻塞已通过本地 Mock 验证,但未完成真实媒体、OSS 或 SaaS 应用签收。
## 当前本地实现
旧 MQ-only 基线的身份隔离、配置、回执、控制、AI授权及上传通知有 loopback RabbitMQ 本地证据,见 `docs/evidence/20260922-mq-only-local-final.md`;该证据不代签新目标。本轮项目内结果分别见 [F03 v0.3/F09](docs/evidence/f09-local-acceptance-v0.3.md)、[F04](docs/evidence/f04-local-dial-policy-v0.1.md)、[F08](docs/evidence/f08-local-final-result-v0.1.md) 和 [F06 本地发布阻断](docs/evidence/f06-local-release-gates-v0.3.md);[F03 v0.2](docs/evidence/f03-local-task-discovery-v0.2.md) 只留作历史。部署 preflight 在缺失 Asterisk/tcpdump 时明确失败并保留日志;本地测试不等同真实 SaaS、供应商或生产验收。
- `contracts/upstream/` 嵌入项目内自包含 W01 基线,记录父源 commit、dirty 继承和 SHA-256;运行时代码读取该包,不读取父目录。
- `internal/store/` 提供 SQLite inbox、任务、租户/跨 Cell 配额、控制 CAS、replay 和 outbox 事务。
- `internal/agent/` 只使用文件保存执行状态、transcript、录音/资产和崩溃恢复信息;boot 不释放未知占用;录音通过 Dispatcher 授权的短期 Alibaba OSS presigned PUT 直传,上传尝试和通知恢复分别持久记录,失败/过期保留源文件,不自动续期或重新PUT。
- `internal/ai/` 对固定 AI Schema 做不可变快照校验,支持项目内显式 `full_ai`/`asr_only` 分支;`mock_pipeline` 只用于隔离协议/取消/参数测试,不宣称真实供应商已启用。
- 旧 `internal/control/` HTTP业务实现、启动入口、CLI参数及环境配置已删除,不保留兼容通道。
- `internal/rpc/` 提供 `agent.v1` Unary handlers、mTLS TLS1.3 配置、会话世代/fencing、CAS、permit/fact/upload metadata 边界;Agent CLI 可选启动受证书保护的 gRPC listener,并校验静态 Cell 制品与 AI 授权边界。`internal/calllog/` 提供按手机号 HMAC 关联、掩码和 allow-list JSONL 外呼业务日志,不写原始号码、凭据、音频、转写或 prompt。
- `internal/health/` 使用 gopsutil 采样主机/进程资源;媒体端口和 AI 配额未接入时明确报告 unknown。`internal/mq/` 默认 bounded prefetch=1、per-tenant DLQ 和 publisher confirm;`make mq-integration-local` 只启动 disposable RabbitMQ。
- `make acceptance-local` 校验当前项目内合同、格式、race/vet/build 和受限 RabbitMQ 本地矩阵;不访问真实服务。`make release-check-local` 构建并校验一次性本地制品与归档包、v0.1 业务/v0.3 发现/v3 队列草案和 Proto 的版本/hash,验证已有制品、打包目录、归档及校验文件均不会被覆盖,且 CLI 旧开关不存在、mixed/real 制品在打开资源前拒绝。`make release` 仅允许在 `dist/` 下指定**尚不存在**的目标目录,记录 dirty-source 与版本/hash,始终标记 `production_approval=false`;两者均不部署或拨号。真实 OSS 授权测试仍须另用受控环境显式开启,不能从 Mock 或上述制品检查推定通过。
- 直接依赖版本/本地许可证清单见 [`docs/evidence/20260918-dependencies.md`](docs/evidence/20260918-dependencies.md);门禁结论见 [`docs/evidence/20260918-acceptance-matrix.md`](docs/evidence/20260918-acceptance-matrix.md);SIP 注册/认证/From/PAI/前缀/选路对比见 [`docs/evidence/20260919-sip-routing-implementation-comparison.md`](docs/evidence/20260919-sip-routing-implementation-comparison.md),手机号业务日志边界见 [`docs/evidence/20260919-phone-call-business-log.md`](docs/evidence/20260919-phone-call-business-log.md)。
以上 20260918–20260922 的历史证据只覆盖旧基线;本轮新合同、Mock C 和 F03–F09/F06 的本地证据单独列在前文。两组证据都不等于真实供应商、生产 SaaS/MQ receipt、实际切换或第二阶段拓扑通过。范围和延期项见 [`docs/evidence/20260920-scope-amendment.md`](docs/evidence/20260920-scope-amendment.md)。
## 显式重新申请上传授权
仅对已有失败或结果未知的上传使用:
```sh
sip-go-agent agent upload-retry --spool /path/to/agent-spool \
--upload-id '<原上传ID>' --request-id '<新的小写UUID v4>' \
--file '/path/to/retained-recording.wav'
```
该命令使用既有Dispatcher端点/mTLS部署配置,不发起呼叫。请求ID必须由调用方显式提供;每个ID最多一次PUT,已成功上传的文件只恢复通知,不能再次PUT。重复旧请求不会获得续期TOKEN。`completed` 只表示指定持久MQ队列已接收原通知,不表示SaaS已处理。使用前仍需满足对应环境的统一部署与诊断要求。
## 文档
文档目录总览见 [`docs/README.md`](docs/README.md)。后续 Agent 先读[本轮配置读取与有界外呼计划](docs/plan-config-read-v0.1.md),按 F 工作包确认 C/L/M 和 I/M/G 前置及权威合同;原 [plan-0918](docs/archive/plan-0918.md) 恢复原文归档,仅供追溯。并行开发按新计划§9登记单写范围、隔离工作区/测试资源和合并回归,由集成负责人统一维护§8总台账;开发子Agent固定使用 **gpt-5.6-luna+max+fast**,不可用时报告阻塞,不静默降级。本轮未启动开发子Agent。
| 文档 | 内容 |
| --- | --- |
| [本轮配置读取与有界外呼计划](docs/plan-config-read-v0.1.md) | 首读入口:F00–F09、C/L/M 与 I/M/G 门禁、单写/验证状态;四条只读 GET 的外部合同仍待签收 |
| [任务发现事件游标计划](docs/plan-0926.md) | v0.3 项目内合同、运行与本地 Mock 范围;外部顺序、墓碑容量和切换另行签收 |
| [旧 plan-0918 归档原文](docs/archive/plan-0918.md) | W00–W16 历史状态及旧 MQ-only 阶段证据;非本轮执行入口 |
| [Go重写方案 v0.3](docs/architecture/Go重写方案_v0.3.md) | 本次单节点/单 Cell/单租户目标、至少3 SIP fixture、双AI模式、P0/P1/第二阶段分期 |
| [通信与事件数据交互 v0.1](docs/contracts/通信与事件数据交互_v0.1.md) | 首发Unary、静态SIP与双模式、§6.1–6.3 SaaS配置来源/参数矩阵/安全边界 |
| [SaaS↔Dispatcher 第三方对接顺序](docs/thirds/第三方对接事件与请求消费顺序_v0.1.md)、[任务发现 v0.3](docs/thirds/v0.3.md) | 仅任务发现按 v0.3 项目内修订;[v0.2](docs/thirds/v0.2.md) 是历史,其余项目内 SaaS 协议仍用 v0.1;外部合同/取消查询补传仍待签收 |
| [现行 MQ 机器契约](contracts/upstream/v1/mq.schema.json)、[Agent Proto](proto/agent/v1/agent.proto) | 现行消息和Unary字段权威;HTTP配置仅有项目提案 |
| [OpenAPI与MQ字段索引 v0.1](docs/references/OpenAPI与MQ字段索引_v0.1.md) | 旧源只读提取42个HTTP操作/115个组件及哈希;不代表新MQ-only入口,不手改生成物 |
| [deploys:物理机 systemd 发布包](deploys/README.md) | 锁定 Debian 13/Go 1.27.1/发布版本,构建并上传不依赖 Docker 的 Agent/Dispatcher 安装包 |
| [验证与切换验收 v0.3](docs/acceptance/验证与切换验收_v0.3.md) | 10个首发汇总门禁、88项基线按阶段适用、P2公平性及独立容量验收 |
| [开源组件选型与复用清单 v0.2](docs/dependencies/开源组件选型与复用清单_v0.2.md) | §1.3首发基础库/AI SDK选择,§4.3参数能力及锁版/许可/PoC门禁 |
| [G0开发准备与契约冻结方案 v0.1](docs/architecture/G0开发准备与契约冻结提案_v0.1.md) | 原D01–D10方向已确认;MQ-only新增GAP-10及受影响G0须重新验证,真实外部发布/生产联调另行安排 |
| [AGENTS.md](AGENTS.md) | 本独立子项目的开发与安全约束 |
## 独立项目原则
- 当前设计文档以本目录 `docs/` 为唯一维护位置,不再向父项目另存一份。
- 对接协议的现有权威来源仍属于上游;后续在本项目导入带来源、版本和 SHA-256 的不可变契约发布包,不能另写一套同名 Schema。
- 后续发行包、CI、数据库和运行配置独立。不能靠 `../agent_call`、`../management`、`../sip_mock_server` 或父项目环境文件运行。
- 业务代码范围仅包括 SIP Agent/Dispatcher 与 Asterisk;RabbitMQ、OSS、AI 供应商及 SaaS API 是 SaaS 提供的基础设施,不在本项目生产包中部署。独立集成测试使用自有隔离数据库、RabbitMQ 和契约 fixture;OSS数据面复用官方SDK/标准HTTP,D按自身配置文件提供临时TOKEN,A直传且不持有长期AK/SK;不申请SaaS上传会话,不等待SaaS校验或业务处理;外部 SIP Mock 只能以固定镜像及版本化协议接入,不导入其源码。
- 真实外呼、云创建、供应商调用和消费授权均是独立门禁,不能由测试成功或本文档自动授权。
## 旧阶段基线与本轮入口
以下为旧阶段的原有分期记录;四条只读 HTTP GET(配置、任务发现、租户额度)、有界消费和时段改造的新依赖、状态与门禁以[本轮计划](docs/plan-config-read-v0.1.md)为准。
1. **P0:先完成MQ-only新合同(GAP-10)。** 冻结D唯一ID/生命周期、独立Topic/队列/绑定、全部请求响应/关联/错误/期限及Unary异步衔接;旧包原样保留。其余已有基线按受影响范围重新验证,包括8种事件payload、双AI模式(GAP-08)、SaaS任务AI配置读取/调参(GAP-09)、首发Unary职责、单 Cell 静态快照来源/加载回执、D配置文件/临时上传TOKEN及上传通知可靠入队和至少3家SIP trunk的配置/协议 fixture。只核验实际采用的SDK;火山TTS参数覆盖、精确版本/许可证未核验前不宣布锁库,不等待未来动态发布/文本OSS归档合同。
2. **P1:本次单节点内测上线。** 完成单 Cell、单租户、双模式、幂等/控制/配额/恢复/录音安全的本地/隔离闭环;真实 ECS、真实外呼、生产 SaaS/MQ 联调不作为本阶段前置。
3. **第二阶段:** 真实 SaaS/MQ 对接、RabbitMQ ACL/TLS及适用的业务回执、真实供应商/ECS 联调,以及双节点、第二 Cell、第二租户公平调度。
4. **后续另立项:** 在线动态发布、自动跨供应商FALLBACK、多Dispatcher HA/分布式配额、权重借用、文本OSS归档、1000路完整AI/N+1。既有call/command整体补传不是通用回放平台,当前单节点首发仍保留。
阶段目标详见主方案§1/§10,首发验收见验收方案§1.1–§1.2;文件名保持不变。旧 MQ-only 本地门禁见[归档计划 §8.2](docs/archive/plan-0918.md)和`docs/evidence/20260922-mq-only-local-final.md`;本轮新目标仅按[新计划 §8](docs/plan-config-read-v0.1.md)记状态;真实依赖、供应商、云/拨号、生产receipt、容量和切换仍属第二阶段,归档旧证据见 `docs/archive/evidence/20260920-local-p1-acceptance.md`。