# 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 行以上。