Commit Graph

3 Commits

Author SHA1 Message Date
ThearchyHelios 3dc5f5add4 助手只写了思考、一个操作都没给时自动重来一次:问数据和评测走同一个决定
真实模型验收里 deepseek 偶发只出思考、不出操作,生成过程交出 error「助手本轮未完成:模型没有给出任何修改,也没有说明
原因」,问数据这一轮照实报了,但不会自动重来——而这种偶发情况重来一次多半就好,「重来一次」的规矩本来就有
(chat/turn 的 MAX_ATTEMPTS = 2,含第一次)。

- chat/turn:error 也由 next_step 判:机读码是 EMPTY_GENERATION(copilot_empty)的判 retry,别的仍判失败(被截断的不重来:
  额度不变,重来还是截断);error_reason 取重来时交给助手的原因(error 带的 reason,没有就去掉「助手本轮未完成:」前缀);
- api/copilot.answer_ops:一个操作都没给时 CopilotIncomplete 带上这个码;error 操作多带 reason 和 next(retry | fail),和
  final 的 next 一样由服务端定;
- 问数据页(store/chat.ts)照 error.next 走:retry 就带着原因重来一次(同 retry_instruction 的从零重建措辞,次数照
  MAX_ATTEMPTS),试满了才照实报;进度写「助手上一次没有给出任何操作,正在重新生成工作流…」(lib/terms 的 CHAT_RETRY_TEXT);
  第一次建图的用量照样记进这一轮;
- 评测(eval/answer.Driver.drive)用同一个 next_step / error_reason / retry_instruction:先重来一次,还不行才记建图失败、
  助手调用失败;每次自动重来的原因照实记在 turn.retries(没过检查、复核判不可用的重来也记),评测页逐题明细写出来。

测试:test_chat_turn_policy.py 的 test_next_step_branches(error 的两支和 error_reason)、
test_the_frontend_retries_an_error_the_server_says_to_retry、test_answer_ops_says_to_retry_an_empty_generation、
test_the_eval_driver_retries_an_empty_generation_once(重来后回答 / 重来还不行,两次的用量都算);
test_copilot_answer_ops.py 的 SSE 对照多认 error 上新加的 next、reason、code。去掉修复回跑都失败。
浏览器:check-chat 新加 emptyretry 一节(重来一次后照常回答、交回去的话带原因、两次用量都记;两次都不行照实报、不试第三次),
check-chat 840 项全过。
2026-10-17 11:51:34 +08:00
ThearchyHelios ee6e07959b 问数据一轮的「决定」下沉到后端 chat/turn.py,问数据页照后端给的走(细案 01 做法 1,总方案 2.1);这一轮的花费 = 助手 + 运行 + 复核
- chat/turn.py:next_step(有 error 级问题时自查过就判失败、没自查过的老服务端才重来一次;autorun=false 只建不跑;reply、只有反问直接收尾;其余运行)、fill_input(规则同 chat.ts 的 fillInput)、retry_after_review(retry、broken、这一轮还没试满)、retry_instruction(两种措辞原样搬过来)
- answer_ops 的 final(含只问不改那条)带 next(run | ready | fail);/copilot/review 的结果带 retry_instruction(ReviewIn.attempt 按这一轮试过几次判,要重来是那句话,不重来是 null)
- 前端 store/chat.ts:final 照 next 走,复核照 retry_instruction 走(原样交回给助手),launch / watch / settle 把 attempt 带到复核;老后端没有这两个字段时退回原来的规则(常量和措辞留在 retryInstruction 里,和后端逐字对照)
- 这一轮的用量:usage 操作累加进 copilot,复核结果的 usage 累加进 review,自动重来和用户点重试换下来的运行并进 earlier,当前运行的抄进 run,一起随 meta.usage 落库;问数据页轮次头部写这一轮的花费(runCostText:估不出的写「≥」或「金额无法估算」),悬停分得清助手建图、运行、复核,文案在 lib/terms.ts 的 TURN_COST_TEXT;ReviewResult 类型补 retry_instruction、usage
- 新增 tests/test_chat_turn_policy.py(各条决定的分支;前后端对照 MAX_ATTEMPTS、认问题字段的正则、两种重来措辞——改一个字回跑会失败;复核按 attempt 给不给 retry_instruction);test_copilot_answer_ops 的基线比对改成「final 只多一个 next」
- check-chat 补一段「新服务端」:照 next=ready 不发起、照 retry_instruction 原样重来、第二次复核带 attempt=1、meta.usage 四份都记下、头部写 $0.067 且悬停分得清三部分
2026-10-16 10:59:15 +08:00
ThearchyHelios ba28dee1f0 生成过程抽成 answer_ops、复核抽成 review_of_run,助手建图和复核的用量也记下(细案 01 做法 2、3):评测和问数据页走同一条生成路径,这一轮的花费不再低报
- api/copilot.py:event_stream 原样搬成 async generator answer_ops(payload, *, catalog_view=None),交出的 op dict 不变;开流前的准备(数据源、目录检查器、助手模型、历史、查看服务)用自己的短会话,在第一条操作之前做完。SSE 路由只包一层:先取第一条,开流前的拒绝(模型没配好、限定的数据源都不在)照旧是 HTTP 错误
- catalog_view 一路传给查看服务和自查的 SQL 检查器(目录视图接缝的「生成过程从参数读」)
- providers/usage.py:Meter 是一个 LangChain 回调,和 get_usage_metadata_callback 同一个机制(登记过的上下文变量),按模型累计 tokens、次数,金额按价格目录;估不出的记 unpriced_calls。没直接用 get_usage_metadata_callback:with 块跨 yield 会把变量留在调用方上下文里,调用方随后发起的运行会继承它、被重复计一遍;metered 只在每一步 __anext__ 期间挂上,嵌套时并进外层
- 生成过程读到 done / look / ask 就关模型的流(后面的闲话不要),流末尾才报的用量拿不到:这一次照样计次数和已报的 token,记成估不出,不悄悄少算(遗留:真实接入上建图那几次多半是下限)
- providers/budget.py:BudgetFallback.astream 用 aclosing 包住里面那条流——以前调用方关流时里面那条要等垃圾回收才关,模型那次调用的收尾(用量回调)落在算完账之后;测试去掉它回跑会少计一次
- answer_ops 末尾多一条 {op: usage, by_model, input_tokens, output_tokens, calls, cost_usd, unpriced_calls};/copilot/review 拆出 review_of_run(问数据页、评测共用),结果带 usage(没调模型时全 0)和 retry_instruction(要不要带着原图重来、说什么,按 chat/turn.py 的决定算;ReviewIn 多一个 attempt)
- 新增 app/chat/turn.py(问数据一轮的决定,复核这边先用上;final.next、对照测试、前端照做在下一个提交);新增 tests/test_copilot_answer_ops.py(八种结局的 SSE 输出和抽出来之前录下的 fixtures/copilot_answer_ops_baseline.json 逐条相同,末尾多一条 usage;直接迭代和 SSE 同一串;开流前的拒绝仍是 HTTP 错误)、tests/test_usage_meter.py;读 SSE 的十一个测试文件的收流帮手跳过末尾那条 usage
2026-10-16 10:45:45 +08:00