Commit Graph

386 Commits

Author SHA1 Message Date
ThearchyHelios 9461c03a63 分析结论的「在验证什么」照实说谁写的:分析卡上那一条是模板作者写的,标「分析卡上写的『在验证什么』」;Agent 现场做的照旧「Agent 写的假设」(台账条目带 item 的是分析卡、带 call_id 的是 Agent)。服务端按 origin 给 hypothesis_label、hypothesis_note 两句,证据面板、导出页、可验证报告都照原样显示,不自己拼。测试:证据接口两种都测,分析卡的链、导出页、核对页各加一条断言 2026-10-21 15:52:19 +00:00
ThearchyHelios 3d730480b9 check-all 的 ESTIMATE 按分析能力一轮第 2 波之后的实测改三项(只决定排队顺序):check-evidence 91 → 157 秒、check-compare 45 → 100 秒、check-bundle 16 → 36 秒(2026-10-21 两套服务、八道并行);证据面板、运行对比、可验证报告各加了分析结论的几段,变长了 2026-10-21 20:04:13 +08:00
ThearchyHelios 03cedbaf1d 合入 W2-c 前端:分析卡节点与分析项编辑器、报告节点两个新字段、设置「分析」一节、问数据时间线的分析步骤与出具横幅三项、运行对比的分析卡一区、证据面板与正文接上分析结论(六步出处链、闭合核对、两期可比性、说法违规标注、分析范围)、可验证报告核对页与分析样本页、口径账本摘要防 NaN;服务端补分析工具事件里的判定与分析结论的单独出处接口
# Conflicts:
#	backend/tests/test_eval_schedule.py
2026-10-21 19:34:24 +08:00
ThearchyHelios bf89269c11 评测前端:变体里能选「分析工具」开 / 关,发起评测多一种「分析工具贡献对照」。typesEval 加 EvalAnalysisTools、EvalPreset,EvalVariant 多 analysis;termsEval 加分析工具的叫法、提示和这种对照的说明,对比「都没变」那句带上分析工具。StartDialog:ArmFields 多一格分析工具(题集的默认变体同一张表单),预设对照里由预设定的那一项不摆(目录贡献不摆目录、分析工具贡献不摆分析工具);分析工具贡献对照交 {preset: analysis_tools, variant},变体里不带分析工具和名字,缺省每题 3 次。结果页、对比页、A/B 照服务端的变体那一句和指纹差异显示。check-evals:发起时评一次选「关」、两种预设的请求体和估算的两臂,对比写「分析工具:开 → 关」,分析工具贡献对照的两臂和详情页头;test_frontend_eval_unions 对上分析工具的取值、叫法和预设对照 2026-10-21 19:32:38 +08:00
ThearchyHelios 954946d4e3 check-all 不往子进程传的段过滤补全:check-stream 新加的 STREAM_ONLY,连同早就有、一直没列进来的 COMPARE_ONLY、INQUIRY_ONLY、SHARE_ONLY、ACCESS_KEYS_ONLY、APP_EDITOR_ONLY、CAPABILITIES_ONLY。壳里留着其中一个时,整套检查会悄悄只跑那几项的一小截、照样报全部通过 2026-10-21 19:11:24 +08:00
ThearchyHelios 017cbee5aa 可验证报告样本页加异动周报(analysis,分析能力一轮):Agent 在虚构零售库 shop 上查两周的总数和按地区两周的销售额,做按地区的变化拆解(带总数核对)、波动基线(两周历史不够,算不了)、两期可比性检查,结论按快照真算(app.analysis.run,目录事实按虚构的数据目录给),Agent 节点的 tool.end 照分析工具真实的写法带结论工件和判定那一段;报告引用拆解的判定语、具名的数、结果表的格和整张结果表,正文后面是 engine/analysis_scope 按虚构的数据目录算出的分析范围(没拆的是渠道)。check-bundle:样本页 19 份;异动周报原样导出全部通过——③ 三份结论和两份输入快照随文件附带,④ 输入快照按「已核对的分析结论的输入」认,⑤ 分开数判定语,点开判定语看得到判定标准、方法与版本、附带说明、Agent 写的假设、输入和导出时的复算,具名的数、结果表的格写对出处,分析范围的编号点得开(正文没引用的 A2 也随文件附带)、范围里的编号不核正文显示,390 宽不溢出;只改判定语、具名的数的显示并重算全部哈希各自变红并点名。另:「查询快照以外的工件标成遮罩」的原因照第 1 波改过的说法(只有查询快照、口径卡、分析结论和报告文档……),原来的断言没跟着改。test_bundle_build 的样本页清单加上它、核对它的形状 2026-10-21 19:09:21 +08:00
ThearchyHelios 29874166df 证据面板与报告正文接上分析结论(分析能力一轮)。点判定语、具名的数、结果表的格:出处链照服务端的分析几步(判定 → 方法 → 计算 → 输入 → 复算 → 封存)——判定写编号和方法的叫法(method_label)、判定语照原样、判定标准、点名的段、方向、谁做的(Agent 现场 / 分析卡 / 口径卡执行时的可比性检查)、附带说明、Agent 写的假设(另说它不是结论);方法写版本、实际用的阈值(契约的叫法)、规范化后的参数;计算写代入式、具名的数、结果表(被引用的数描出来、那一格高亮);输入每份一节,总数和各段之和的闭合核对照服务端算好的数,输入快照的查询步骤接在后面、点 Q 跳过去;复算一致与否、封存范围内台账记没记过、算不了的写原因;分析结论的数不走口径账本。口径卡指标上多一行「两期可比性」(判定、判定语,展开看那份可比性结论的整条链,随卡封存)。说法违规(判断词未挂分析结论、判断与分析结论不符、因果说法没有依据,按 unit / segment / span)标在正文上:只在判断词下面画提醒色波浪线,那段文字是一个可点的片段,句末挂「说法待核」,n / N 跳得到;点开写种类的叫法(同审计)、服务端的原话、所挂的结论(点一下落到它的判定语)。正文后面是系统写的「分析范围」(现象、拆过、排除、算不了、没拆的候选维度、做过几次差异检验),编号点得开——正文没引用的取新接口 …/evidence/analyses/{alias} 的出处链,关掉焦点回到那个编号。整句面板挂的依据是分析结论时写「派生自 Q1、Q2」(证据图的 derived_from 边,按这份报告认)。记录页:审计表的说法违规行写种类的叫法、点得开;工件页签认得分析结论(哪一种分析,算不了的写没有做成)。夹具 evidence-analysis.json 是真运行组装的(后端测试库里的虚构零售库 shop,模型换成脚本)。check-evidence 加三节(分析结论的出处链、说法违规与分析范围、指标上的两期可比性),check-runs 加一节(审计行、工件页签) 2026-10-21 18:57:22 +08:00
ThearchyHelios 887d086261 合入 W2-a 想 + 文档:问题意图词表、分析方法定稿(analysis.method@2)、助手建图认分析卡与分析工具(分析类问题的形状、自查只挡一轮、关分析工具的开关)、复核信号并成一条只写说明、内置模板 ⑪「异动分析(可追溯)」、中英文档(新增 analysis 一篇、七对文档与升级说明、README) 2026-10-21 18:54:50 +08:00
ThearchyHelios 468f670f89 运行对比页加「分析卡」一区(服务端 compare 的 analyses):两次运行的分析卡按节点和分析项对齐,一项一行——分析卡的名字和项的标识、算子的叫法(契约)、两次的判定语照原样(没有的一边写「—」,算不了的照判定语写原因)、变了没有(判定一致 / 判定变了 / 判定一致而判定语里的数变了 / 这次新增 / 这次没有,按服务端比出来的代码挑说法和颜色);只列判定,不拆变化来源;两次都没有分析卡(老服务端没有这一项)时不画。check-compare 加一节:先后照服务端、几种变化、新增与没有、老服务端不画、窄屏不溢出;夹具的形状照服务端真算的(compare.compare 跑虚构周报加分析卡) 2026-10-21 18:38:48 +08:00
ThearchyHelios ee923ef6f8 问数据时间线的分析步骤与出具横幅的三项(分析能力一轮)。时间线(run/decode):新步骤种类 analysis——Agent 的五个分析工具一次调用一行,标题写算子的叫法(契约的叫法,不写 analysis_decompose),做成后照 tool.end 的 analysis 接上本节点的编号(A1,和交回模型的「【分析 A1】」同一个)、副标题是服务端渲染的判定语,结论工件可下钻,参数(没填的不列)进展开区、Agent 写的假设另列;算不了的是一条结论(提醒色,判定语就是「…没有做成:原因」,下一步说照实写原因、不能据此下判断),紧跟着的 analysis_refused 提醒折进那一行;写错的调用(tool.error 带 call_error)副标题写没有记成结论、下一步写 Agent 会照着改、原话在展开区;老服务端没有 analysis 那一段时只照参数写叫法,不从 preview(结论 JSON 的前一截)里拼。分析卡每项一行(analysis.end,不再落成「未识别的事件」):叫法和这一项的标识、判定语、结论工件。报告的分析说法重写后仍有(report_analysis_claims)、口径卡的可比性没做成(metric_comparability_skipped)说成人话。回答流:分析的图标、展开看判定语和假设,长列表折起来时分析那几行照样露出来(不算出了问题);运行中的状态字写「正在执行分析:变化拆解(可加)…」。出具横幅(IssuanceBanner)照出具声明列三项:分析说法核对(strict 记缺口、check 只标注,几处、原话、种类的叫法同审计)、指标的两期可比性(判定语和原因)、报告引用的指标没追到原始数据(追到哪为止、记没记缺口)。夹具:fixtures.json 加两次真跑的运行(后端测试库里的虚构零售库 shop、模型换成脚本:Agent 查库、写错一次拆解、拆解、波动基线算不了、可比性检查,报告 3 处说法标注;分析卡两项),synthetic 加协作成员调分析工具,dev/fixtures/analysis.tsx 三个预览用例。check-decode、check-stream 各加分析的几节(check-stream 加 STREAM_ONLY 只跑几段) 2026-10-21 18:35:22 +08:00
ThearchyHelios ce5ef5e5f0 口径账本的轮次摘要只数四种标签(来自口径、相关口径、这次的推理、没比对):认不出种类的标签(不是对象、没有种类、不是这四种)不计、也不算进总数,摘要那一句说得平、不出 NaN。分析结论的数不和口径比对,服务端不给它们标签(00-总方案 D11),这里是防着以后多出别的种类。check-ledger 的使用者一节混进两个认不出种类的标签 2026-10-21 18:24:18 +08:00
ThearchyHelios 9358d9ec48 评测前端认两种分析期望:题目编辑器在预览之后选贡献或判定(分析方法、模式、按哪几列、期次、点名前几段),试算写出服务端算的判定和判定语;结果页逐题写期望和答案的判定,点开写判定语、引用了哪一份结论或正文那一句;总览按期望的种类分开写结论
- typesEval.ts:期望种类加 contribution、verdict,期望带 op、mode、params;EvalAnalysisOp、EvalAnalysisMode、EvalJudgement(同服务端契约和 judgements.JUDGEMENTS);期望值、评分带判定类、点名的段、方向、判定语;总表加 outcomes_by_kind
- termsEval.ts:贡献、判定的叫法;分析方法、模式的叫法和契约的 OP_LABELS、MODE_LABELS 一字不差(test_frontend_eval_unions 逐个对照,连同判定类);判定类、方向、参数的叫法;指纹差异一句补上分析设置
- parts.tsx:期望写成「变化拆解(可加) · 按地区 · 销售额」;判定写成「主要来源:华东(下降)」「超出常规波动(上升)」「差异站得住(西南高于华东)」,算不了的照实写原因;判定类、段、方向都是服务端给的,界面只套叫法
- CaseEditor.tsx:分析期望的表单按分析方法列参数(参数名同分析工具,列从预览结果里选),换方法、模式只留新方法还认的参数;编辑配了几个期望的题时另外的期望列出来、保存时照旧带上(以前只留第一个,第二个期望会丢)
- EvaluationPage.tsx:逐题表、展开的明细、总览按种类
- scripts/check-evals.mjs:夹具补分析期望(加题选算子、试算、保存的请求体不带来源方向判定,编辑保留另外的期望;结果页四种结论、点开的明细、总览按种类),共 130 项
2026-10-21 18:23:57 +08:00
ThearchyHelios 84e6c2e13f 设置「偏好设置」加「分析」一节(服务端 analysis 一组):判定用的阈值、Agent 每次执行最多分析几次、最多下钻几层、列出前几段,分成变化拆解、波动基线与趋势判断、差异检验、次数与层数四组。照口径账本一节的写法:草稿由偏好页持有、和其余设置共用一条保存条,存的时候整组写 analysis(没改的照原值带上,不被冲回缺省);叫法、范围照契约 LABELS / RANGES(每项下面写范围,类型、范围当场按契约的说法说,保存键不能点),两两之间的大小交给服务端核、422 的原话写在保存条上;服务端把 2 存成 2.0、写「2.0」不算改;老服务端没有这一组时不显示。check-manage 加一节:十七项的叫法都是契约的、显示生效的值、超范围和整数项、保存条的叫法、整组写、服务端拒收、改回原值、老服务端 2026-10-21 18:20:10 +08:00
ThearchyHelios 78800511e0 前端:分析卡节点(分析能力一轮)。节点库「把关」一类加「分析卡」(类型色 --nt-analysis,亮暗两套),卡片摘要写做哪几种分析(「波动基线、变化拆解(可加)」,叫法照契约);检查器的分析项编辑器:每项标识、分析方法(五个算子)、模式(有模式的才给)、输入只列上游的查询节点(调用数据库查询工具的「调用工具」节点、合并查询,删掉或挪到下游的照实列出),按方法摆参数格(analysisItems.paramSpecs:维度列、期次、基期、本期、度量列或分子分母、乘积和因子、比较方式、粒度、对照组、几对……,期次可以写 {{ }}),可加、比率的变化拆解另有总数核对两格和下钻(上一层只列排在前面的变化拆解),变化拆解、可比性检查可以写成基期、本期两份查询,换方法、模式时只留新方法用得到的参数;在验证什么一句话;阈值覆盖只列写了的几项、从没写的里选,范围当场按契约说(两两之间的大小交给服务端),全删掉不留空对象。服务端按 items[i].<键> 报的问题落在那一格下面,定位退不到的子键(params.parent.key)逐段往上退;查询节点连到分析卡时还没选输入的第一项选上它(同合并查询,和连线同一步撤销)。报告节点加「分析说法核对」(缺省重写一次后标出)、「分析范围」(高级,缺省有分析结论时附上),选项以 engine/labels.py 的短说法开头。叫法、范围只照契约一份(lib/termsAnalysis:OP_LABELS / MODE_LABELS / LABELS / RANGES,check-studio 读后端源码逐项比对)。check-studio 加两节:叫法与契约一致、分析卡的画布编辑与校验定位 2026-10-21 18:17:56 +08:00
ThearchyHelios 690e855ea5 内置模板 ⑪「异动分析(可追溯)」:两个调用工具节点取数(整体按周 26 周、按地区两周,期次在 SQL 里按每周第一天的日期算出来、整体按周倒序排),分析卡固定做两项(本周的变化放回历史看的波动基线、按地区的可加变化拆解,总数取整体按周的第 0、1 行核对闭合;阈值不写死、取设置),报告撰写节点按受管级别写明最严的几项(含分析说法核对严格),出口按报告来自 + 单元格引用的契约出具。拿来就能按受管级别发布。界面文案白名单加一条:模板 SQL 里中文列别名按 SQLite 加的双引号是 SQL 语法。测试:画布校验、受管发布检查没有错误(模板 ⑨ 一并核)、接一份虚构的四地区 26 周零售库从头运行,两项都做成(明显超出常规波动、主要来自华东)、完整出具 2026-10-21 18:08:59 +08:00
ThearchyHelios 2714890d0d 文档重新梳理:README 精简成介绍和索引,细节按主题拆进 docs/zh-CN 与 docs/en(17 篇一一对应),英文文档不含中文
README.zh-CN.md / README.md 只留:这是什么、为什么用它、主要功能(按领域一行一条,链到文档)、快速开始、部署、文档索引、
开发与测试、许可(原文不动)。原来的每一节按读者和任务分到 17 篇主题文档:ask-data、workflows、evidence、
data-sources(新增:接入数据库、只读保证、上传表格、跨库合并、遮罩列)、data-catalog、tools(新增:工具、审批档位、
能力登记、端点、网络规则——它们管所有工作流,不只应用)、apps、evaluation-and-ledger、schedules(含通知)、deployment、
configuration、postgresql-and-scaling、identity-and-security、architecture、development、upgrade-notes(按时间倒序,
每波先写要做的事)、faq。删掉的只有模块名(api/copilot_gen.py、chat/drive.py、data/schema_view.py)、重复的话和
「以前…现在…」的叙述;操作步骤、命令、配置名、限制、权限边界都有归宿。中文是原文,英文按新的中文写;英文里界面文字
只写英文名,开头注明界面目前只有简体中文,中文占位符换成英文占位符,中文数字的例子改成不依赖中文的说法。
数据剖析可以同时剖析 2–3 张表(baf23998)收进 data-catalog。
新增 scripts/check-docs.py:英文文档(README.md、docs/en/**)不许有中日韩字符和全角符号(代码块也算),
README、docs/**、deploy/README.md 的相对链接和锚点都要通,docs/zh-CN 与 docs/en 文件一一对应、标题层级相同。
中文提示里指向 README 章节的地方改指新文档:cluster/guard.py、cluster/version.py、db/base.py 两处报错,
data/schema_view.py 文档串,.env.example 三处,scripts/prod.sh、scripts/test-postgres.sh,terms.ts 两处、
DataSourcesTab.tsx、check-manage.mjs 注释,deploy/README.md 三处链接。deploy/agentlab.env 未动。
验收:check-docs 0 问题(英文文档 18 个 0 处中文,相对链接 369 条 0 断链,18 对标题层级一致);相关后端测试
117 通过、7 跳过;tsc -b、check-copy 通过。
2026-10-21 10:23:26 +08:00
ThearchyHelios f774e42463 数据剖析可以同时剖析几张表:剖析设置加「同时剖析的表数」(table_concurrency,1–3,缺省 1,即以前的一张做完再做下一张;上限 3 是给这个源上的分析留出连接池的临时连接),每张表的查询仍一条一条发,所以同一时刻对业务库最多这么多条查询。剖析任务的执行改成按设置开几个执行者,按任务里的顺序一张结束就开始下一张;进度、发过的查询各落在自己那张表上(不再记「正在做的那一张」)。每张表开始前照旧重读数据源:停用、关掉剖析或止损后不再开始新的表,正在做的几张照常做完(止损时剩下的项记止损的原因),都结束后再把没开始的记停下;止损的连续失败、超时比例按几张表的查询合起来算。停止、关停时正在做的几张各自收尾,做完的项照常写进目录,都收完才往上交(等的时候又被停止也等完);一张表让任务整体出错(快照被改动、数据源没了、记结果写库出错)时,另几张按停止收尾、原因写这一句,本进程续不上租约的不写。同时要估同一张表的行数时只估一次(按表加锁,先来的没估成后来的自己估)。同源已有剖析时的 409 说法从「第 x / y 张表」改成「已完成 x / y 张表」。界面:设置表单多一格(单位「张」,提示写明业务库同时要应付几条查询、和分析共用连接),风险说明、卡片悬停、开始前的醒目一句在大于 1 时写明「同时剖析 N 张表、每张表的查询一条一条地发」,预算多一行,这次最多用时按几轮算。测试:同一时刻在途查询不超过设置、每张表仍一条一条发(1/2/3 三种)、几张一起显示进行中并按顺序开始、同时停止各自写进目录、止损后不再开始新表、停用时正在做的做完、一张出错另几张按停止收尾、共享行数只估一次;check-catalog-profile 加一节(预算、估算、说法、两行进行中、表清单)。验收:后端全量 14979 通过;止损那条并发测试单独跑 30 遍、整个剖析任务测试文件并行跑 15 遍都没有偶发;tsc;check-catalog-profile 217 项、check-copy 28 项全过 2026-10-21 09:08:10 +08:00
ThearchyHelios aadc8d0115 中文 README 移到 README.zh-CN.md(内容不改,顶上加语言切换),中文提示里指向 README 章节的地方改指中文版
git mv 保留历史;顶上一行「[English](README.md) | 简体中文」,英文版随后单独提交。
改指 README.zh-CN.md 的:报错文字(cluster/guard.py、cluster/version.py、db/base.py 两处)、.env.example 三处注释、
scripts/prod.sh 用法说明、scripts/test-postgres.sh 注释、「口径同 README「哪些角色看得到原值」」的四处代码注释
(terms.ts 两处、DataSourcesTab.tsx、check-manage.mjs),deploy/README.md 里三处「仓库 README」写成指向
../README.zh-CN.md 对应章节的链接。
没改的:deploy/deploy.sh 四处「README 的常见问题」「README「用 PostgreSQL」」和 deploy/agentlab.env 117 行——离线包里和
deploy.sh 放在一起的 README.md 就是 deploy/README.md,那几句指的正是它的常见问题、用 PostgreSQL 两节;
deploy/README.md 第 16 行文件清单说的是它自己;version.py、runner.py 文档串里「以前 README 写…」是旧事的叙述。
验收:相关后端测试 117 通过、7 跳过;tsc -b、check-copy 通过。
2026-10-21 08:13:58 +08:00
ThearchyHelios 9e1ff11278 交叉表支持按文字导入的指标(如「高峰时段」一行写着「18-19」),堵上占位符陷阱:配方的 measures 分段加 text_measures(标签 → text / hour_range),落成文字列(时段存规范写法),空格、公式、占位符照块的取值规则,数字、日期、解析不了的时段报 value_not_text / value_not_hour_range;规则起草遇到无标题指标块里整行是文字的行(标签不带词表单位)按文字指标起草,并出卡片和问题要人确认(「不是」就去掉,回到按数字导入、试运行拒收),确认清单加 text_measure 项,前后对照报类型和存法变化;数值区不合格的格一行合成一条起草失败(不再一行 30 条)。陷阱:以前照「请添加占位符」把「18-19」加成占位符,整格静默存成空值、干跑照样通过——静态校验拒收含数字的占位符(placeholder_digits,重放和沿用现行配方的放行),value_not_number 的下一步按格子情况写:整行文字的提示改「指标类型」并给修复按钮 declare_text_measure,含数字的不再提示加占位符;标签带单位的拒按文字导入(text_measure_unit),文字列不能写单位(unit_on_text)。配方面板每个指标多一个「指标类型」下拉(数字 / 时段 / 文字)。默认值不进规范形式,已存配方的哈希不变。测试 tests/test_recipe_text_measures.py(合成夹具,假名);check-manage 加指标类型三项 2026-10-20 11:41:28 +08:00
ThearchyHelios 680ea4ecf8 覆盖检查:现查没成功(大表全表 MIN / MAX 超时、库一时连不上)也记 LIVE_TTL_S,期间同一张表直接退回剖析、取值观察,不再每次白等 PROBE_TIMEOUT_S 秒(测试 test_a_failed_probe_is_not_retried_for_a_while);方言容器集成测试(scripts/dialect_it.py)加一段覆盖检查:只存当天的滚动表(DATE 列,MySQL / MariaDB 另有按文字 'YYYYMMDD' 存的),按运行当天现算的上周区间判成没有数据、区间包含当天只是别的条件筛空的不报,查询后和助手自查两个入口都核——PostgreSQL 16、MySQL 8.4、MariaDB 11、Oracle Free 23 全过 2026-10-20 10:58:20 +08:00
ThearchyHelios e9bb0afd4c 报告里标识列的数不分千位(产线编码 1203 不再写成「1,203」):新增 engine/cell_format.plain_columns,按序看查询当时冻结的数据目录给源列标的度量类型(identifier / status / attribute 不分,flow / stock / ratio 分)、源列名像编码编号(CODE、ID、NO 整词或结尾、驼峰的 Id/No/Code、编码、编号、代码)、是分组键(列、别名、序号都认)而不是聚合;SUM、COUNT、AVG 这类聚合是量,MIN、MAX 按那一列判;判断不了的照旧分千位。只看查询快照和它指向的表结构快照(内容寻址),组装、流式渲染、写作目录、出口复核一致。单元格显示规则 3 版:真有格子因此改了写法的文档记 cell_display: 3、引用上记 plain;离线核对页认 3 版、照 plain 渲染(解析不了 SQL),老文档按记下的版本复核照旧分千位。样本里订单号(order_no)随之不分组,check-bundle 跟着改 2026-10-19 17:55:02 +08:00
ThearchyHelios 49118eeef2 复核 R-d5(dev.sh 读 .env 不全):认 KEY = value(等号两边有空格,和后端的 dotenv 一致);放开发库密码的数据目录也照「环境变量 > backend/.env > .env」读 AGENTLAB_DATA_DIR,相对路径按后端的工作目录 backend/ 算,.postgres-dev 落在后端实际用的数据目录下。单测:等号带空格、export、行尾注释、backend/.env 优先、相对的数据目录 2026-10-19 16:13:35 +08:00
ThearchyHelios d117237bbc 配置模板补上 PostgreSQL 和多进程的几项:.env.example 的应用库一节分成应用库、连接池、PgBouncer、多进程、开发用 PostgreSQL 五组,补上 AGENTLAB_DATABASE_DIRECT_URL、AGENTLAB_DB_PGBOUNCER、AGENTLAB_DB_POOL_TIMEOUT、AGENTLAB_DB_POOL_RECYCLE、AGENTLAB_DB_STARTUP_TIMEOUT、AGENTLAB_WORKERS、AGENTLAB_WORKER_LEASE_S、AGENTLAB_WORKER_HEARTBEAT_S、AGENTLAB_SCHEDULER、AGENTLAB_SCHEDULER_TICK_S、AGENTLAB_BUILD 和 dev.sh --postgres 的 AGENTLAB_DEV_PG_*(都注释着,名字、缺省值照 core/config.py 和脚本);dev.sh 的 AGENTLAB_DEV_PG_* 也认 .env / backend/.env(环境变量优先,和后端的配置同一个规矩,不 source)。deploy/agentlab.env 末尾再追加「外接 PostgreSQL 与多进程(可选)」一段(地址写宿主机网桥 172.17.0.1、放行容器网段,和内置库二选一;断点库、PgBouncer、直连地址、工作进程、租约、连接池、启动时等库),已有的行一行没动。deploy.sh:AGENTLAB_DATABASE_DIRECT_URL 也算外接的库(和内置互斥),只设直连地址不设 AGENTLAB_DATABASE_URL、内置库开 AGENTLAB_DB_PGBOUNCER、SQLite 时 AGENTLAB_WORKERS 大于 1 都在起容器之前照实拦下(migrate-to-postgres 在停服务之前查)。单测:这些 AGENTLAB_* 经 --env-file 进容器、几条拦截、模板两段的项和缺省值、dev.sh 从 .env 读设置,以及守卫——config.py 里应用库、连接池、多进程、调度几类配置每一项都要在 .env.example 里有 2026-10-19 15:41:37 +08:00
ThearchyHelios 5318c33f57 合入 nr8/b 的 ac8b194c(复核 R-b1–R-b6、交互留底的运行名额、先占额度再出具、直连地址 AGENTLAB_DATABASE_DIRECT_URL 和 AGENTLAB_DB_PGBOUNCER、不许新旧版本混跑、prod.sh 和 Docker 入口问 python -m app.cluster workers、镜像带构建号);没有冲突,README、config.py、db/base.py 自动合并 2026-10-19 14:01:07 +08:00
ThearchyHelios 320fd69af2 镜像大小照实写:内置 PostgreSQL 的镜像导出约 160 MB、导入后约 0.7 GB(postgres:16.15,arm64 上量的) 2026-10-19 13:47:38 +08:00
ThearchyHelios 9e6a6db406 deploy.sh 带内置 PostgreSQL:install --postgres 在旁边再起一个 PostgreSQL 容器(镜像小版本固定 postgres:16.15、可用 POSTGRES_IMAGE 改;同一个 docker 网络、端口不对外;数据在 docker 数据卷;密码第一次自动生成在数据目录的 .postgres/、0600,按 POSTGRES_PASSWORD_FILE 和 PGPASSFILE 传,不进镜像、日志和 docker inspect;agentlab.env 什么都不用填)。用过一次的数据目录记在 .postgres/state,之后 install / upgrade / start 不用再加。start、restart 先起库等 pg_isready 再起服务,stop 先停服务再停库,status 显示两个容器,logs --postgres 看库的,uninstall 连库的容器和网络一起删、数据卷和数据目录留着。和外接 PostgreSQL(agentlab.env 里的 AGENTLAB_DATABASE_URL)互斥,照实报错;已有 SQLite 库的数据目录不许 install --postgres(指向 migrate-to-postgres),别的数据目录留下的数据卷不拿来用。upgrade 先停旧服务、自动备份(SQLite 用备份接口拷到 backups/sqlite/,内置库 pg_dump 到 backups/postgres/,各留最近 BACKUP_KEEP 份),备份没做成就把旧服务起回来不升级;POSTGRES_IMAGE 换了时库的容器按新镜像重建、起不来就换回原来的。新增 migrate-to-postgres:停服务 → 备份 → 起库 → copy-to-postgres 先 --dry-run 再正式导入、核对 → 记下已切换 → 按内置库起服务;记下之前哪一步出错都退回 SQLite(服务原样恢复、库的容器停掉、状态记成 migrating),重跑先清空上次导了一半的再导,已切过的什么都不做,不是这个数据目录留下的数据卷不清空。容器、网络、数据卷、端口等可用 DEPLOY_<名字> 环境变量盖过(测试、并排部署)。package-docker.sh 把同一个标签的 PostgreSQL 镜像导出成 postgres-image.tar 一起打包(--no-postgres 不带),标签只在 deploy.sh 里定一处。单测用假的 docker(tests/fake_docker.py)核对先后顺序、生成的参数、互斥和各条回退 2026-10-19 13:43:52 +08:00
ThearchyHelios bf74423651 dev.sh 加 --postgres:起(已经有就复用、停着就起)一个本地开发用的 PostgreSQL 容器,端口只开在 127.0.0.1(缺省 55432),数据在 docker 数据卷,密码第一次自动生成在数据目录的 .postgres-dev/ 里,后端按 PGPASSFILE 读、照它设 AGENTLAB_DATABASE_URL;容器名、端口、数据卷、镜像可用 AGENTLAB_DEV_PG_* 改,同名容器不是这个脚本起的、端口和已有容器的不一致都照实报错。不加就和原来一样:SQLite,不用 docker 2026-10-19 13:43:33 +08:00
ThearchyHelios 451c05aacb 文案检查:应用库、断点库地址写错时报错里给的地址示例(postgresql+asyncpg://用户:密码@主机:5432/库名 等)登记进 copy-allow.json——://、:、@ 是地址语法,用户照着改环境变量,不能换成全角
(cherry picked from commit 3403a0b2cc)
2026-10-19 13:40:54 +08:00
ThearchyHelios 5578cf137d 复核 R-b4(prod.sh、Docker 入口读不到 .env 里的配置):新增 python -m app.cluster workers——照后端自己的配置(环境变量和 .env 一起读)说起几个工作进程,SQLite 而大于 1 时照实报错、退出码 2;prod.sh 只在命令行给了 --workers 时写进环境变量,进程数一律问后端,Docker 的入口同样问它。补测试:SQLite 而大于 1 拒绝、PostgreSQL 照给的数 2026-10-19 13:23:02 +08:00
ThearchyHelios 2935ac5d67 合入 nr8/a 的 3403a0b2(文案检查:地址示例的半角标点登记进 copy-allow.json) 2026-10-19 12:48:13 +08:00
ThearchyHelios 3403a0b2cc 文案检查:应用库、断点库地址写错时报错里给的地址示例(postgresql+asyncpg://用户:密码@主机:5432/库名 等)登记进 copy-allow.json——://、:、@ 是地址语法,用户照着改环境变量,不能换成全角 2026-10-19 12:35:04 +08:00
ThearchyHelios e6a3ee8f95 转发运行事件时跳过不认识的事件种类(回放照样读得到);test-multiprocess.sh 不带参数时 macOS 的 bash 3.2 报 args 未定义,参数直接原样交给 pytest 2026-10-19 12:30:30 +08:00
ThearchyHelios 4a80936c38 多进程的跑法和说法:prod.sh 加 --workers(AGENTLAB_WORKERS,SQLite 时大于 1 先拦下),Docker 入口按 AGENTLAB_WORKERS 起 uvicorn --workers,dev.sh 写明开发时单进程;README 把各处「单进程前提」改成实话——SQLite 单进程(第二个进程拒绝启动),PostgreSQL 可多进程,新增「多进程」一节:怎么起、配置项、认领和租约与各类接手规矩、跨进程停止、运行并发的四类与缺省、调度当班、实时流、进程里的账和缓存(哪些进了库、哪些留在进程里及其影响)、多台机器的条件(共享存储同一路径、对时、NFS 上 SQLite 文件的实话)、升级要停掉全部进程、多进程端到端测试;deploy/README 补多进程。按需视图的锁改成按应用取(每日上限几个键之间也数得准),出具的锁改成全站一把(每日上限是全站的) 2026-10-19 12:08:17 +08:00
ThearchyHelios 1acf960312 多进程端到端验收:scripts/test-multiprocess.sh 用本机 postgres:16 起临时库,tests/test_multiprocess_e2e.py(缺省跳过,AGENTLAB_MULTIPROCESS_E2E=1)在上面起两个 uvicorn 工作进程,用演示模型跑七个场景——两个进程都登记、一个当班;运行由接到请求的进程认领,另一个进程上的流收得到实时事件和流式增量,同一个审批决定同时发给两边只执行一次,两边事件流不重不漏、封存核对得上;跨进程停止;定时只触发一次;全站一个名额时评测的作答运行排着队,后来的问数据运行先拿到名额;两个进程同时记同一本每日账不越过上限;强杀一个进程后在跑的运行被照实标中断、停在审批上的照常在另一个进程上批完、当班交接。顺带修:等名额时被停止也照实收成已取消(以前停在排队中);当班的本地余量不超过租约的四分之一(租约调短时一直不当班);启动清理上传半成品时没有别的活着的进程就全清;文件锁守卫的几项测试只在 SQLite 跑;问数据事件日志清理那一拍不带时刻时按现在算 2026-10-19 12:03:35 +08:00
ThearchyHelios 9a0d87aa6e 合入遗留收口分支 nr8/l(问数据心跳不落库与事件日志清理、续跑重新核对身份、事件触发批量查询与去抖边界、子图编号与驳回出口等),W2-b 在此之上做多进程协调 2026-10-19 10:46:34 +08:00
ThearchyHelios 76290baaf1 问数据的心跳只落换了阶段的那一拍:浏览器检查发现刷新后过程里「规划」那一行没了——页面按心跳的阶段画那一行,全都不落库就回放不出来。现在换了阶段的那一拍(规划 → 查看 → 搭建……)照落,同一阶段接着的保活心跳才只在流上发、不落库;页面接着的心跳顶替上一拍、不叠成好几条。检查脚本的伪服务端照同一个规矩,「一条只收一份」比心跳之外的操作 2026-10-19 10:41:06 +08:00
ThearchyHelios 5e6ba12678 断点库模块去掉没用上的 kind();test-postgres.sh 的注释照现在的连接池写法改 2026-10-19 10:27:17 +08:00
ThearchyHelios 2d108d116f 表结构变了之后口径凑不齐参数时照实记下:以前不试算、也不记日志,一声不响地跳过。现在记一条日志写缺哪几个参数(必填、没给值也没有缺省值的入口字段)和参数本来从哪来,同时写进变化记录的 affects.probes(同一版只记一条),变化页的「影响」一块写「「x」v3:缺少参数 start、end,没有试算」;同一条变化再被探查到时这份记录不丢。变化接口给的 affects 缺的几项补上空的 2026-10-19 10:10:38 +08:00
ThearchyHelios 71d535c4ce 对账要人选对照时按逐格比对的结论预选:这一列单独比和口径取数的某一列等价(ledger/match._cells 证明了),口径卡上只读那一格的指标就是它最可能的对照,409 的 options 里给 suggested;对账框照它预选、标「预选」,人可以改。只是「相关」的那一格不预选(比到的是第一个试的列,不是最像的),一个口径列对上几个指标的也不预选 2026-10-19 10:05:04 +08:00
ThearchyHelios 2e7d6103ea 应用库可移植到 PostgreSQL:AGENTLAB_DATABASE_URL 设成 postgresql+asyncpg://… 时整个应用库用 PostgreSQL,断点用官方的 langgraph-checkpoint-postgres(同一个库,AGENTLAB_CHECKPOINT_URL 可另给);不设时照旧是数据目录里的 SQLite,行为不变
- 配置:database_url、checkpoint_url(启动时校验写法,只认 PostgreSQL)、连接池四项;启动日志写用的是哪种库(主机、库名、用户,不写密码)
- 引擎(db/base.make_engine):SQLite 照旧 WAL、外键、忙等;PostgreSQL 用连接池、探活、会话时区 UTC,装上方言调整(db/postgres.py):建表时 String(n) 是不限长的 VARCHAR(SQLite 从不查长度,导过来的存量也可能超长)、ORDER BY 里可空列的 NULL 位置照 SQLite 补写(升序在前、降序在后,窗口函数里同样);Integer 列在 PostgreSQL 上是 BIGINT(列挂到表上时换成 with_variant,绑定参数跟着列按 BIGINT 转换);JSON 列两边都存原文(PostgreSQL 的 json,不用 JSONB:JSONB 重排对象里的键,快照的列序、表的先后读回来就变了);JSON 里的 NaN 写成 null、NUL 去掉(PostgreSQL 不收)
- 迁移按方言:已有的列和索引用 inspector 认;PostgreSQL 上补列的类型取模型里这一列的、缺省值取迁移表里的(布尔 0/1 换成 false/true),ADD COLUMN IF NOT EXISTS;去重语句里的布尔按方言写;部分唯一索引补 postgresql_where;init_db 在 PostgreSQL 上拿咨询锁(几个进程同时启动不撞)
- 应用库上的 SQLite 专用写法改成按方言编译的表达式(db/portable.py):json_extract 的十几处(口径召回、出具、对账、个人应用、幂等键、访问控制、数据源变化通知、剖析任务、待办超时)换成 json_eq / json_flag / json_text,json_type 换成 json_is_string(两种库同一套带类型的比较);能力登记的 sqlite insert 换成按会话方言的 insert_ignore;能力使用次数的 json_each 按方言分支;附件「没绑记录」的条件不靠 json 的等号;按报错文字认唯一约束的地方换成 unique_violation(按表和列认,两种库的报错都认得)
- 断点(engine/checkpoints.py):PostgreSQL 时开 psycopg 连接池、在咨询锁里 setup;runner 只认 BaseCheckpointSaver,读断点仍只走 saver 的公开接口
- 依赖:新 extra postgres(asyncpg、psycopg[binary] 3、psycopg-pool、langgraph-checkpoint-postgres 3.1.2);langgraph-checkpoint 卡在 <4.3(断点格式就在这个包里,postgres 包新版要 4.3,不动已装的 4.2.0);锁文件补上新包
- 运行收尾:记 action.unknown、安排核实做完才把运行摘掉(以前先摘掉,等「不在跑了」再读事件的一方在库慢时读不到这一条)
- 测试:AGENTLAB_TEST_DATABASE_URL 时跑在 PostgreSQL 上(每个 xdist 进程建自己的库、按事件循环分的连接池 tests/pgpool.py),不设时盖掉环境里的数据库地址照旧用 SQLite;scripts/test-postgres.sh 起临时的 postgres:16 容器跑全量;sqlite_only 标记;另开连接改库的几个竞态测试、触发器测试改成两种库都能跑(tests/appdb.py);新增 test_db_portable 守着方言调整、JSON 键序、超长字符串、大整数、NULL 排序、时区、PostgreSQL 老库迁移
2026-10-19 09:52:09 +08:00
ThearchyHelios 358206312e 事件触发的规模:定时任务列表里每个事件触发任务「有几条在等」一次查齐(outbox.pending_for_many:待派发数一条 SQL 按任务分组算,窗口要看的事件一次读出),不再每行查一次;每一拍派发只读触发条件的事件种类、对象对得上的任务(SQLAlchemy 的通用 JSON 访问),保存时查环一层查一次、只顺着「上游工作流运行成功结束」的边找;选对象(trigger-options)按事件、关键字查、一页最多 100 个、more 说还有没有,当前选中的总在里面,编辑页一页没列完时多一个按名称查找。顺带修:等着的时候任务改了条件、最早那条不再合条件时,「什么时候合成触发」按剩下的最早一条算(列表上的时刻和真发起的一致);一个窗口的结束时刻和这个任务已有的另一次触发撞在同一刻(别的期次早一拍发了)时往后挪,那几条事件照常发起,不再被记到已有的触发上 2026-10-19 09:46:47 +08:00
ThearchyHelios edde451d19 问数据事件日志:助手的心跳不落库、已结束的轮次按期清理。心跳(模型几秒没出声时的 heartbeat 操作)是纯保活,以前每 3 秒落一条库;现在只在本进程里记最近的一拍(chat/log.beat),流上发一条不带 seq 的,重连时流先补最近的那一拍,之后落了任何事件就作废;页面照收不带 seq 的心跳、不动收到的最后一个 seq。其余事件照落(第 2 波跨进程从库里按 seq 追)。已结束(成功、失败、取消、中断)超过 14 天的轮次整轮删事件日志(chat/log.purge,挂在调度循环的那一拍里,一小时最多一次):重开已结束的一轮读的是 conversation_turns 那一行,不读事件日志;任务行留着,seq 接着发号。README 数据位置写明 2026-10-19 09:34:14 +08:00
ThearchyHelios 17e99cd76c 驳回出口之后,待办、通知、Webhook 照实说转到哪:中断内容带上驳回之后去哪(engine/replay.reject_route:接了驳回出口写转到哪几步,没接的写运行就此结束,审批没接、没设驳回即终止的写这一路到此为止),待办卡的提示、驳回按钮、驳回后的提示、处理过的「结果」照它说,不再一律写「转入驳回分支」「本次运行终止」;超时驳回不再露出英文结论码;双盲裁决、动作确认被驳回的提示同样照它说。子工作流里的关卡走驳回出口时,名字记成「子工作流 › x」(RunContext.global_label),走过的那几步交回父图的 trail,父运行的终态事件照实带上途经驳回,实例页、通知写「「子工作流 › 把关」被驳回,转到「子工作流 › 退回」」,不写内部 id、不写成已完成。定时任务的 Webhook:照驳回那条路成功结束的,标题、状态写途经驳回,另起一行写谁被驳回、转到哪一步 2026-10-19 08:59:15 +08:00
ThearchyHelios c0739dfd5d 合入 W1-c 数据事件触发:定时任务加「事件触发」(上传表格出新一期、上游工作流正式运行成功结束、数据源有要处理的变化),事件在发生处写进待派发事件、调度循环去抖派发;保存时与运行时防环;{{ event.* }} 模板变量;途经驳回、应用补算的缺省不认(可勾选);积压一拍处理完、过期的合成一条跳过;按期次分窗口;定时页可选「定时 / 事件触发」 2026-10-18 18:23:33 +08:00
ThearchyHelios 3d5fb19fbd 合入 W1-b 子工作流证据交回父图 + 驳回出口:子图每一步进同一个运行的事件流;子图出口字段带出处,父图口径卡、报告跨子图追到原始数据(运行时、证据面板、静态检查同一套,最多 3 层);报告目录收进子图里的查询和口径卡;审批、动作确认、代码和工具审批、双盲裁决可接「驳回」出口,驳回后沿出口往下走(不接时行为不变),动作确认走出口不发送;发布检查拦下走不到结束的驳回路径;实例页、通知写「被驳回,转到 X」;子图里的报告按全局 id 记、父图只认自己的报告 2026-10-18 18:23:15 +08:00
ThearchyHelios 3e6032bdca 复核修正(前端):节点计数、并行数、「当前在跑」不把子工作流里的步骤另算;子图那一步写「子工作流 › 那一步」
- B5 run/trace:子工作流里的步骤(isSubStep:节点 id「子工作流节点 id/…」)算在子工作流那一步里——完成数不另算(以前运行详情
  会写「7/3」),没有 run.started 时的分母也不算它们;Telemetry 的「当前「X」等 N 个」同一个规矩,子工作流和它里面那一步不算成
  两个同时在跑
- B6 run/trace.stepLabel:图上没有的子图步骤接上子工作流的名字(「取数子流程 › 查订单」,和服务端终态事件的 label 同一个拼法,
  名字取 node.started 记的);运行胶囊(RunHud)、泳道(RunTimeline)的失败、阻断说法和泳道名、记录页的失败横幅与航迹
  (RunDetailView.labelOf)都用它,不再写「失败于「sub/x」」

检查脚本:check-decode 加两段(子工作流步骤的完成数、并行数、当前在跑;出错在子图里那一步时的名字)
2026-10-18 18:18:53 +08:00
ThearchyHelios 656a550408 数据事件触发按复核意见修正:途经驳回、去抖积压、source.changed 补写、按期次分窗口、补算缺省不认、示例出口字段同一套过滤
M1 途经驳回(编排者已定):outbox.stage_run_finished 收可选的 rejected_via(缺省 None 即没途经驳回),事件内容带 rejected 和
rejected_via,说法接「(途经驳回)」,模板有 {{ event.rejected }}(true / false)。触发条件缺省只认没途经驳回的,trigger 加
include_rejected(界面「也认途经驳回的」勾选,说明照实写)。runner._finalize 把 _rejected_via(state) 传进来那一下留给编排者
在合并时接(runner 的 _rejected_via 在 W1-b 的分支上);测试直接调 stage_run_finished 传参覆盖。

C1 去抖积压:以前一拍只走一个窗口,积压时后面的越等越久、全过了宽限,而且每个窗口各记一条跳过,原因还说调度没在跑。
现在 _drain 按发生时刻把等着的事件切成窗口,一拍里把到点的处理完(最多 100 个窗口、5000 条);排在前面已过补发宽限的合成
一条 skipped_misfire(合并了几次事件、几个窗口、时间跨度,上传表格另写合掉的期次),派给任务时已经晚于宽限才说「调度未运行」,
否则照实说积压;宽限内的照常发起(照重叠规则跳过的照实记)。

C3 source.changed:这一处确实没法和变化记录同一个事务(一次探查、剖析的变化分好几批落库,一批只触发一次要等任务结束才知道),
改成说实话:models_triggers 的说明写清哪两种同事务、哪一种不是。trigger_events 加 dedupe_key(source.changed:<任务号>,唯一),
emit_source_changed 按它去重;调度的一拍(刚起的服务第一拍就补,之后每 10 分钟)由 backfill_source_changes 按任务号补写:2 天内
测到、还开着的要处理级变化,任务已结束却没有事件的补一条。分组在 Python 里做,不用各库写法不同的 JSON 取值。

C4 按期次分窗口:triggers.window_key 让上传表格按期次各自成窗口,9 月、10 月连着启用各有各的触发;同一期的重传照旧合并。
两个窗口结束在同一刻时后一个挪 1 微秒,fire_at 不撞唯一约束。

C5 应用补算:workflow.finished 缺省不认 app_backfill 发起的(升版补算连发好几条、各是某一期的历史输入),trigger 加
include_backfill(界面「也认应用补算的」),选了「只认应用补算」时本来就认;说法写「途经驳回、应用补算的不算」。

C6 示例出口字段:triggers.outputs_of 一处过滤「_」开头的键,真派发、预览、立即运行共用;示例事件也按 matches 跳过缺省不认的
途经驳回、应用补算,取合条件的最近一次。

测试:新加 test_schedule_events_review.py(11 项,先写、先看着失败;去掉 matches 的驳回判断、把每拍窗口数改回 1 回跑,对应用例
各自失败),test_schedule_events_api.py 加一项「也认」两项经接口存取和说法;check-schedules 加「上游工作流的请求体」一段、纯函数
几条、触发历史里合并跳过那一行的夹具。
验证:后端全量 14479 通过;tsc、check-copy;check-schedules 447 项、check-runs 327 项通过(拿锁、--stacks 1)。
2026-10-18 18:09:20 +08:00
ThearchyHelios d6318b639d 问数据页的复核修正(前端):使用者不给「继续运行」,两个标签页同时打开停在半路的一轮时后到的那个接着看
- 使用者(user 角色)续不了运行(服务端照 POST /api/runs/{id}/continue 的老规矩回 403):补救区不摆「继续运行」,服务重启打断的
  那一轮说明里也不叫它去点,改说「如需整轮重来,请点击「重新运行本轮」」(lib/terms 的 CHAT_TURN_TEXT);重试本轮、重新运行本轮照常。
  以前这个按钮对使用者也摆着,点了只弹一句 403。
- 两个标签页同时打开停在半路的一轮:都会请服务端接着收尾,服务端现在只起得来一次,后到的那个收到 409 chat_turn_busy 时不再说
  「无法确认本轮的当前状态」,改成问一下这一轮现在怎样——在跑就从这一次尝试的第一条接着播,收了尾就照那一行摆。
- scripts/check-chat.mjs 新加两段:「使用者(user 角色)」(伪造 /api/auth/me 认出使用者:中断的、跑挂的都不给继续运行,一次续跑都
  不发)、「两个标签页同时打开」(服务端只接着收尾一次,两边都收尾、答案一样、都不写库)。去掉修复回跑,这两段都会失败。
2026-10-18 18:07:03 +08:00
ThearchyHelios fa9725adf2 问数据一轮的收尾补漏:接着收尾不算占着对话,实时流没等到结局不再转圈,刷新后接着播的过程照实时的样子摆
- 一段对话里停在半路的几轮(老轮次、服务重启后停着的)要一起交给服务端收尾:resume 不建图、不发起运行,不再按「这段对话正忙」
  拒掉第二轮(以前打开这样的对话,只有第一轮收得了尾)。测试先写、去掉修复回跑会失败。
- 实时流结束了却没见到这一轮的 end(服务端那一轮出了岔子、这一轮被删了或没权限了):回服务端问一次那一行,照它摆;问不到就
  照实说「无法确认本轮的当前状态」,给「重新核对」。重新核对一轮还没有运行的:问服务端它在不在跑,在跑接着播。
- 刷新、关掉再打开后接着播的那一轮就是正在跑的一轮:建图的过程照实时的样子一直摆着,不当成要点开才取的历史轮次
  (check-chat「刷新后接着看」一段多守这一条,去掉修复回跑会失败)。
2026-10-18 16:55:30 +08:00
ThearchyHelios 5ff3e1136d 问数据整轮放到服务端跑(前端):store/chat.ts 改成「发起 + 播放」,断线按 seq 重连补齐,刷新、关掉再打开接着看
为什么:一轮问数据搬到服务端之后(上一个提交),页面不该再推这一轮:建图那条流、发起运行、复核、按复核重来、落库都和页面
绑在一起,页面一断这一轮就停。现在页面只发起、只看,要不要运行、要不要重来、什么时候交付都照服务端说的。

做了什么:
- 新的 api/chatTurns.ts:发起、查询、停止(挂在 api.chatTurns),streamChatTurn 订阅这一轮的事件日志——先回放、再接实时;
  断了按收到的最后一个 seq 自动重连(收到东西马上接着连,连不上按退避),45 秒什么都没收到(服务端 15 秒一拍心跳)当连接死了。
- store/chat.ts:plan / launch / settle / retry 换成发起(launchTurn)+ 播放(play)。收到的操作照原来的渲染逻辑画(画布边收
  边长、过程步骤、思考、查看、用量);收到 run 就接上运行自己的实时流画过程(watch 只画过程,不再判结局);stage 说到了
  哪一步(停在审批上立刻去拿待审批);turn.retry 照原来自动重来那样重置;end 照服务端落库的那一行摆结局(和刷新之后从库里
  恢复的是同一份 restoreTurn)。「重试本轮」「重新运行本轮」「放宽步数」「跑一下」「继续运行」「停止」都走新接口。
- 页面不再写这一轮的结局(不再 PATCH 轮次、不再调 /copilot/review、不再发 POST /api/runs);失败的说法照服务端记的原因
  (meta.cause)按 lib/explain 讲,老轮次记的 failure 照旧认。
- 刷新、关掉再打开:服务端还在跑的一轮(ConversationTurn.job)从这一次尝试的第一条事件接着播;库里停在半路、服务端又没在跑
  的(老轮次、服务重启后停着的)请服务端接着收尾(mode=resume),不在页面上自己收尾。问数据页的显示不变。
- 页面上那份退路(MAX_ATTEMPTS、fillInput、retryInstruction、等复核的计时)去掉:决定只在服务端一处。后端对照测试改成守
  「页面上不再有这几样」。
- scripts/check-chat.mjs:伪造的服务端照 backend/app/chat/job.py 的做法用原来那几份剧本把一轮跑完(生成、发起运行、等运行的剧本
  放完、复核、拼那一行),原有各段照过;守落库的几处改成守「页面不 PATCH 这一轮」和照服务端那一行摆;新加「断线重连补齐」
  「刷新、关掉再打开接着看」「停止(建图中也停得下)」几段,并核对发起、重试、放宽步数、继续运行、停止的请求体。
- 服务端顺带:turn.attempt 带上到目前为止的用量、从什么时候算起(补交付的到运行结束为止),turn.retry 带上换下来的那次运行
  并进之后的用量(页面上的运行壳子里没有用量);接着收尾(resume)不要求运行还在,运行记录删了的照实收成「运行记录不见了」。
2026-10-18 16:49:26 +08:00