把普通对话的预留、取消、追加、寒暄结算和用量计算收进结算工厂。
Independent Staging Quality Gate / validate (push) Successful in 13m51s
Independent Staging Quality Gate / publish (push) Successful in 4m6s

完成回答、直达校正、输出审核和开流前加载仍留在路由里,使 diff 停在 1500 行以内。

Co-Authored-By: Grok (agent loop)
This commit is contained in:
jesse-ux
2026-10-15 19:12:44 +08:00
co-authored by Grok (agent loop)
parent 32b238cf86
commit cd7e0a3493
18 changed files with 1139 additions and 245 deletions
@@ -0,0 +1,63 @@
# PROGRESS · 普通对话接口拆分第一步
issue #66。分支 `codex/consult-route-split-20261013`,从 `origin/staging` `32b238cf` 新建。按任务书 §7 先让出完成回答、直达校正、输出审核和上下文摘要,再让出开流前整段(T1)。T4、T5 保留。
## 做了什么
搬进 `frontend/src/lib/consult/settlement.ts` 的工厂 `createConsultSettlement`:
| 原位置 | 新位置 |
| --- | --- |
| 预留回调体 | `reserveCredit` |
| `cancel` 函数体 | `cancel`(route 留一行转调用) |
| 追加问题与写满 409 | `appendQuestion` |
| 寒暄 `complete_consultation_free` | `completeSmalltalk` |
| `usagePayload` 函数体 | `usagePayload`(route 留一行转调用) |
| 三个 schema、`first`、`retryDetachedSettlement`、`mergeUsage`、`Usage` | 同文件导出;完成回答仍从 route 引用 |
仍留在 `route.ts`:`completeResponse`、`completeDirectRectificationTurn`、`moderateAnswer`、`completeModeratedResponse`、`checkpointConsultationContext`,以及开流前的旧入口、限额、提示词提取、历史窗口、输入审核。
`route.ts` 行数 1943 → 1780,净减 163。`accounting.rpc(` 仍有 3 处(完成回答、审核后完成、直达校正)。目标净减 450 与 rpc 为 0 留给第二阶段。
## 偏离
- §7:完成回答、直达校正、输出审核、上下文摘要、T1 本轮不做。
- `usageStartedAt` 用读取函数,在计算 `durationMs` 时才取,因为工厂早于该赋值创建。`selectedModel` 仍是后面的常量,工厂经 `modelSlot` 读取。
- `cancel` 与 `usagePayload` 在 route 留转调用,完成回答的调用点不用改写。
- 行为测试覆盖预留、写满 409、取消把 `request_completed` 当成功、寒暄免费结算、重试 3 次且退避 150/300 毫秒、用量字段。完成回答、直达校正、`settleResult` 只执行一次留在 route,不在本轮行为测试里。
- T4 比较前把 `durationMs` 置 0。这是唯一的归一化。
## 三栏
| 文件 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| request-rate-limit | 限额早于 `reserve_consultation_usage` | 限额早于 `reserveCredit`;RPC 在 settlement | 预留体搬走,顺序仍在 route |
| content-moderation | 审核早于该 RPC | 审核早于 `reserveCredit`;RPC 在 settlement | 同上 |
| consult-prep-gate | 追加 RPC 早于读标题 | `appendQuestion()` 早于读标题;RPC 在 settlement | 追加搬走 |
| consult-first-frame | 流内两处 RPC 与 `session_full`;寒暄分支含免费 RPC | 流内是两次工厂调用;正文与寒暄 RPC 在 settlement | 预留、追加、寒暄结算搬走 |
| consultation-smalltalk | 寒暄分支含免费 RPC | 分支调用 `completeSmalltalk`;RPC 在 settlement | 寒暄结算搬走 |
| session-title | 切片从追加失败分支起 | 切片从 `appendQuestion()` 起到 `usagePayload` | 失败分支搬走,标题仍在其后 |
| consult-reports-billing | route 同时引入错误类与定价函数 | route 只引入错误类;定价函数在 settlement | 定价随预留搬走 |
| chat-session-authority | route 含追加 RPC 与写满文案 | 文案在 settlement;`reserveCredit` 早于 `appendQuestion` | 追加在预留成功之后 |
| consultation-session-capacity | route 含两处 `session_full` | 两处在 settlement;route 原样返回 | 写满 409 随追加搬走 |
| consult-latency | route 含 `consultationUsageMetadata` | 该调用在 settlement 的用量函数 | 用量载荷搬走 |
| application-billing | route 的用量函数含模型字段、合并与 `eventKey` | 这些在 settlement;route 转调用并写入 `p_actual_usage` | 用量载荷搬走 |
| consultation-stream-recovery | route 含预留 RPC、取消函数体、重试上限 | 这些在 settlement;完成回答的重试仍在 route | 预留、取消、重试助手搬走 |
## 检查
| 检查 | 命令 | 结果数字 |
| --- | --- | --- |
| 类型 | `tsc --noEmit -p .` | 退出码 0 |
| 规范 | `npm run lint` | 退出码 0;0 错误,123 条既有警告 |
| 定向测试 | `tsx --test` 结算、开流前与读 route 的 24 个文件 | 203 通过,0 失败,0 取消 |
| 差分 | `consult-route-split-diff.mts` | 16 个场景全部一致;基线 `32b238cf` |
| 行数差 | `git diff --numstat origin/staging` 加新文件行数 | 见下 |
T4 一致的场景:401、冻结 423、请求体 400、会话不存在 404、校正会话 409、模型变更 409、模型不可用 503、提示词提取 400、输入审核拦截、点数不足 402、session_full 409、寒暄、普通咨询完成、输出审核命中、生成中失败(取消)、直达校正。
对照 `origin/staging` 的增删合计(含本文件):1384。
## 第二阶段
把完成回答、直达校正、输出审核和上下文摘要搬进同一工厂,再做 T1。之后去掉 route 上的两处转调用,让 `accounting.rpc(` 为 0,并把 `route.ts` 净减做到 450 行以上。