ThearchyHelios
|
4e3623885b
|
合入 W2-a 的复核修复(nr8/a:导入的 NOT NULL 补值与孤儿行、收尾 dispose、sslmode 换算、PostgreSQL 写入去 NUL、不分大小写搜索 contains_ci、json_eq 两库同语义、JSON 守卫、用户可见列表补决胜键、bubblewrap --clearenv、部署脚本与原子写的几处、README 连接数预算)
# Conflicts:
# backend/app/api/schedules.py
# backend/app/main.py
|
2026-10-19 12:21:38 +08:00 |
|
ThearchyHelios
|
0d9f1d9339
|
用户看得到的列表补决胜键(复核 R-a9):按名称、时间等可能并列的排序后面补上同一个模型的 id,并列时两种库排出来一样
- 实测 /api/evals/calibers、/api/schedules/trigger-options 按 Workflow.name 排序遇同名并列时 SQLite、PostgreSQL 顺序不同。用 AST 逐个过了一遍 order_by:最后一个排序键是 created_at / updated_at / last_active_at / at / name / 各种 *_at 之类、不唯一的列,又不带 DISTINCT、GROUP BY 的,补「, 模型.id」(降序补 id.desc()),共 104 处,分布在 api、apps、auth、blueprints、chat、data、engine、eval、ledger、look、memory、process、providers、scheduler(runs.py 里的三处在上一个提交里)
- 按唯一列(seq、version、唯一的 name)排的不动;按聚合、coalesce 之类表达式排的说明见 db/postgres
|
2026-10-19 12:07:06 +08:00 |
|
ThearchyHelios
|
ae254b052e
|
合入遗留收口分支 nr8/l 的复核修复(变化记录先占住那一行再读改写、召回里行序不定的指标、事件触发列表按任务各取上限、选对象按名字查用 ilike、子工作流写入认旧键、几处测试的竞态)
# Conflicts:
# backend/app/ledger/recall.py
|
2026-10-19 12:05:19 +08:00 |
|
ThearchyHelios
|
20f8eb37e0
|
选对象按名字查改用 ilike(复核 L3):PostgreSQL 上 LIKE 分 ASCII 大小写、SQLite 不分,两种库说法不一;% 和 _ 照 runs._like 转义、按字面匹配。补测试
|
2026-10-19 11:44:49 +08:00 |
|
ThearchyHelios
|
87f0d62f9b
|
多进程协调(W2-b)第一步:新增 app/cluster——工作进程在库里登记、心跳续租约(属主随进程,进程没了它认领的行一起到期),调度当班的租约,发给属主进程的停止 / 记事件请求,PostgreSQL 的 LISTEN/NOTIFY 叫醒,跨进程的互斥锁(咨询锁),SQLite 单进程守卫(第二个进程拒绝启动);运行、问数据一轮、起草 / 剖析 / 探查 / 评测 / 影子起草、文档、发布单记 owner,启动整理改成只接手属主不在了的行,当班进程隔一会儿再接手一次;运行的并发名额改成库里按交互 / 应用 / 定时 / 系统四类发(各有全站上限和优先级,设置里可调),替掉进程内的信号量;同源队记在库里;运行停止、记事件跨进程交给属主;运行事件、问数据事件跨进程转发(库里按 seq 追,不落库的流式增量和保活心跳只转给在看的进程);每日花费账先占住那一行再读写;访问密钥限流、登录失败计数在 PostgreSQL 时记在库里;登录设置、对外地址、向量模型、能力快照、数据源连接池、应用页面缓存跨进程失效;上传版本库、记录表、按需探查、出具、召回、补算、按需视图、个人刷新、定时发起的锁换成跨进程的锁
|
2026-10-19 11:40:33 +08:00 |
|
ThearchyHelios
|
358206312e
|
事件触发的规模:定时任务列表里每个事件触发任务「有几条在等」一次查齐(outbox.pending_for_many:待派发数一条 SQL 按任务分组算,窗口要看的事件一次读出),不再每行查一次;每一拍派发只读触发条件的事件种类、对象对得上的任务(SQLAlchemy 的通用 JSON 访问),保存时查环一层查一次、只顺着「上游工作流运行成功结束」的边找;选对象(trigger-options)按事件、关键字查、一页最多 100 个、more 说还有没有,当前选中的总在里面,编辑页一页没列完时多一个按名称查找。顺带修:等着的时候任务改了条件、最早那条不再合条件时,「什么时候合成触发」按剩下的最早一条算(列表上的时刻和真发起的一致);一个窗口的结束时刻和这个任务已有的另一次触发撞在同一刻(别的期次早一拍发了)时往后挪,那几条事件照常发起,不再被记到已有的触发上
|
2026-10-19 09:46:47 +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
|
3f1eeff841
|
数据事件触发(界面):定时页新建时选「定时 / 事件触发」、事件那一节、列表与详情的等待状态、触发历史和运行详情的「由事件触发」
做了什么:
- 新建定时任务(目标是工作流时)先选怎么触发:定时 / 事件触发(TriggerEditor 的 TriggerModePicker);修改时只读地写出触发方式、
说明建好之后不能改。选了事件触发,频率那一节换成事件(EventSection):三种事件、对象下拉(能选哪些、不能选的原因由新接口
GET /api/schedules/trigger-options 给,界面照着画、选不了的置灰并写原因)、上传表格的期次(只认新增的一期)、上游工作流的
只认应用 / 只认来源和触发链上限的说明、去抖、时区;换事件种类时对象和过滤清掉。
- 预览按一次事件渲染输入(对象最近一次的事件,没有时照实说是示例值),不列触发时间;变量按事件种类取(api.schedules.eventVariables),
插得进 {{ event.* }};请求体带 trigger_kind、trigger,cron 交空串;修改时只交改了的触发条件。model.ts 加 TriggerForm 与
triggerBody / switchEvent,表单问题里事件触发不查频率、要求选对象;服务端 422 指 trigger 时落到事件那一节。
- 列表、详情:「事件触发」标签,频率处写触发说明;下次运行写在等什么(去抖中收到几次、何时合成一次触发;有事件等待派发;调度
没开时照实说不会派发)。触发历史:类型「事件」,写「由事件触发:…」、合并了几次、第几层;立即运行按最近一次事件发起的写
「按事件:…」并标示例值。运行详情页头写「由事件触发:…(定时任务「X」)」(RunDetailView 只多传一个 trigger 属性),立即运行
按事件发起的写「立即运行定时任务「X」,按事件:…」,不说成由事件触发;应用页印章同样不算。
- 文案进 lib/termsTrigger.ts;SCHEDULE_TEXT 只补触发类型「事件」和「还需处理」里的「触发事件」。立即运行按示例事件的说法
不再在服务端加「(示例值)」后缀,是不是示例值看 real。
为什么:总方案 §4 要求定时页能建事件触发的任务、列表 / 详情 / 触发历史 / 记录页照实显示;能不能选、为什么由服务端判,界面不放逻辑。
验证:tsc、check-copy;check-schedules 加纯函数一段(表单 ⇄ 请求体)和三段页面(新建的请求体、列表 / 详情 / 触发历史、运行详情
页头,含 390px 浅色),假接口加了触发选项、事件预览、事件变量、事件触发任务的夹具,写请求断言请求体;原有各段照过;check-runs 照过。
|
2026-10-18 16:11:55 +08:00 |
|
ThearchyHelios
|
a1ab3247f9
|
数据事件触发(后端):待派发事件表、调度循环派发与去抖、防环、{{ event.* }} 模板变量、接口收 trigger_kind / trigger
做了什么:
- 新表 trigger_events(待派发事件)、trigger_deliveries(一个事件派给一个定时任务、等去抖),放在 db/models_triggers.py,
models.py 末尾整模块导入。事件在发生处、和那件事同一个事务里写一行:上传表格按期累积的新一期启用(table_versions 的
publish_build / publish_snapshot 切指针那一下,移除、作废、回滚不算)、正式运行成功收尾(runner._finalize 写终态的事务里
加两行调用 outbox.stage_run_finished)、探查 / 剖析新记了要处理的变化(source_changes.notify_after_job,一个任务一条)。
发生处不发起运行:事务边界、重复与重启都在派发这边说清,也为第 2 波多进程做准备(认领靠条件 UPDATE)。
- scheduler/outbox.py:调度循环每一拍(fire_due 之后)派发:pending 事件条件 UPDATE 认领成 routed,同一事务里给合条件、启用着的
事件触发任务写 delivery;窗口从最早一条的发生时刻起算 debounce_s(缺省 60 秒),过了就合成一次触发,内容取最新的那条,
fire_at 取窗口结束的时刻(同一窗口永远同一个时刻,触发记录唯一约束兜住重复派发);照 fire_once 发起正式运行,ScheduleFire
kind=event、inputs 写 {event: 事件说明, inputs: 渲染出的输入};上一次没结束记 skipped_overlap;派发太晚(超出补发宽限)
记 skipped_misfire;任务停用、改了触发条件时等着的标 dropped。AGENTLAB_SCHEDULER 关着时没有这一拍,事件留着,接口照实说。
- scheduler/triggers.py:三种事件的触发条件(table.version 可选只认新增的一期;workflow.finished 可选只认某个应用 / 某种来源;
source.changed)、核对对象(表格是按期累积的上传表格、上游工作流已发布、应用在)、说法、{{ event.* }} 变量(table、version、
period、activated_at;workflow_id、run_id、outputs.<字段>;source、counts)、示例事件(预览、立即运行用对象最近一次真实的事件)、
防环:保存时查 workflow.finished 串成的环(停用的也算,A→B→A、自己触发自己都拒,422 写出经过的工作流),运行时按 origin 里的
触发深度兜底(超过 5 层记未能发起)。
- service:fire_once / _fire_workflow 接事件(模板按事件种类校验、渲染 {{ event.* }},运行来源 origin.trigger 带种类、对象、
事件 id、深度、经过的运行和一句说法);check_template / render_inputs / variables 加可选的 event 参数,cron 任务一字不变。
- api/schedules.py:收 trigger_kind(cron 缺省)/ trigger,event 时目标只能是工作流、cron 存空串、下一次触发为空;返回带
trigger_kind、trigger、trigger_text(也是 description_text)、trigger_state(几条事件在等、去抖到何时、调度开没开);触发
历史带 event;预览按示例事件渲染;变量清单按事件种类给;新增 GET /api/schedules/trigger-options(各事件能选的对象及不能选的
原因、来源、应用,界面不自己判);立即运行按示例事件发起;触发方式建好之后不能改。Webhook 照旧可配,通知写「事件触发」那一行。
- 应用页印章的来源(apps/resolve._from_text)照实写「由事件触发:…」。
为什么:总方案 §4 已拍板接这三种事件、不接口径发布,一套定时机制(X4);派发放在调度循环里而不是发生处,事务和重复都说得清。
测试:test_schedule_events.py(三种事件各触发一次、去抖合并与窗口外另起、重叠跳过、停用 / 改条件丢弃、调度关着时事件留着、
超出宽限、触发链深度与上限、模板校验与渲染、期次写法、通知、印章)、test_schedule_events_api.py(建、核对、防环、改、预览、
变量、立即运行、触发状态、可选对象);test_schedules_api.py 的约定键集合补上新加的几项。
|
2026-10-18 15:53:08 +08:00 |
|
ThearchyHelios
|
7f5578c094
|
定时任务页认得数据源维护:触发历史列出建了的探查、剖析任务和没执行的步骤;「去数据源页设置」改链 #source-<id>(复核 W4R-05、W4R-04)
W4R-05 为什么:数据源维护的一次触发建的是探查、剖析任务,没有运行;api/schedules._fire_outs 不交触发记录的 inputs,
FireRow 只认 run_id 和 eval_run_id,于是每一次建了任务的维护都写成「已发起 · 未发起运行」,和数据源页「定时维护」的
「最近一次」对不上;「立即运行」一次维护还弹「未能发起运行」。
- 后端 api/schedules._fire_outs:目标是数据源维护的触发另带 inputs({steps, jobs, skipped},app/data/source_maintenance
记在触发上的那一份,和数据源页「定时维护」读的同一个形状);别的目标给 null(工作流触发的 inputs 是按模板渲染的工作流
输入,触发历史不列)。触发历史、页头「上次触发」、列表、立即运行的答复都走它。test_schedules_api 的 FIRE_KEYS 加 inputs。
- 前端 FireHistory:维护的那一行逐个列建了的任务(步骤、任务种类、编号、表数),探查链到数据源页那张卡片、剖析链到数据
目录里那个任务的进度(?pjob=,同「最近一次」);没执行的步骤逐条写原因,服务端连成一句的原因不再重复;没建任务写
「没有建任务」(刚触发、任务还在建写「正在建维护任务」),不写「未发起运行」。
- 立即运行(parts.runNow):维护开始了说「已开始维护」、详情逐行写建了什么;跳过照实说上一次维护还没做完;没开始说
「没有开始维护」和原因。状态小标签的悬停同理。
- types.ts 加 ScheduleMaintenanceStep、ScheduleMaintenanceInputs(和 W4-d 的 MaintenanceFireInputs 结构一致,合并后
交叉类型照样过 tsc);叫法进 SCHEDULE_TEXT(步骤叫法同服务端 STEP_LABEL,测试逐个对上)。
W4R-04 为什么:维护定时详情里「去数据源页设置」链到 /data/databases?source=<id>,数据源页(W4-d)只认 #source-<id>
(目录页后台任务条「查看」的约定),点过去落在列表顶上。统一成 #source-<id>:链接都经 model.sourceCardPath 出,
探查任务的链接同用它。
检查:check-schedules 新增「纯函数:数据源维护链到哪里、建了什么怎么写」「数据源维护的触发历史」两段(假接口:四种
维护触发、立即运行开始与跳过),改「链到数据源页」的断言;394 项全过。去掉 FireRow 的维护分支、链接改回 ?source= 回跑:
4 项失败。后端新文件 tests/test_maintenance_fire_history.py(立即运行一次维护后触发历史、页头、列表都带 inputs;工作流
触发不列渲染的输入;步骤和叫法前后端对上)。
|
2026-10-16 22:02:09 +08:00 |
|
ThearchyHelios
|
9e33c0f801
|
评测的两个通知事件照实叫「定时评测有退步」「定时评测没有评完」(复核 L3)
eval.regressed、eval.failed 只在定时发起的评测收尾时推(runner._conclude 只认 trigger == "schedule"),手动发起的那次人自己
在看、不推,这和细案 01 做法 15 把这两个事件放在定时一节里一致。可订阅时的叫法却是「评测有退步」「评测失败」,没写「定时」:
有人给全局渠道勾上「评测失败」、再手动发起一次评测并止损停下,渠道里收不到任何消息,界面上也没处说为什么。
- notify/service.EVENTS 和前端 NOTIFY_TEXT.eventLabel 同一句改成「定时评测有退步」「定时评测没有评完」(test_notify_events
逐字对照两边)。eval.failed 不只是失败:到了上限、止损停下(partial)同样推,所以叫「没有评完」,和消息标题本来的说法一致。
- notify_eval 的消息标题也带上「定时」:定时评测「题集名」有退步 / 没有评完。
- 新测试:两个事件的叫法带「定时」;手动发起的评测止损停下,订阅了这两个事件的全局渠道收不到任何消息(去掉 trigger 的判断
这一条就失败)。
- 模块说明、接口说明里引用旧叫法的几处一并改。
|
2026-10-16 18:23:03 +08:00 |
|
ThearchyHelios
|
e29adf80d0
|
评测执行的测试:执行、评分、统计与对比、清理、定时与通知
为什么:照细案 01 的测试清单把这一波的行为钉住,顺带修了跑测试时撞出来的两处。
- test_eval_runner:后台排队、并发不超过 max_parallel 也不超过全局并发的四分之一、同一题集同时只能一次、停止后只重做
没做完的(评完的不动)、重启标中断不续跑、单次金额上限触顶不再开新题、评测每日账单独记(不占裁判、核查的额度)、
连续 3 题助手调用失败止损、每题超时取消正在跑的运行、停在审批上的作答取消掉(评测不代批)、接口的估算与进度、设置里
eval 一组和 /settings/eval/spend
- test_eval_score:五种结论、写出精度和百分数、维度配对与弱匹配、多行 / 名单 / 没有数据 / 反问、路径和期望先于数字、
dual 两版、允许的相对误差和双盲复算是同一个函数;读封存的答案、逐题 E1 用账本的比对函数;重评只读封存、不调模型
- test_eval_stats:Wilson、精确 McNemar、P50/P90 和手算对照;总表的各项;转移与四种归因;指纹差异;配对表;选基准
- test_eval_cleanup:保留规则;forget 只删一条引用都不剩的文件;清理后总表还在、结果和底下的运行删掉、共用的工件留着
- test_eval_schedule:定时接口收题集(拒工作流、输入模板、Webhook)、到点建一次评测并写 eval_run_id、重叠跳过、错过的按
宽限补;有退步推「评测有退步」、没评完推「评测失败」,消息里没有期望值和答案里的数
- test_eval_e2e 补:开评拍目录快照、记表结构前后;打开裁判时结论裁判走按需裁判那条路、花费记在评测账上,文字要点单列
- 修:期望反问的题在建图、运行失败(含超时)时把原因写全;改非工作流目标的定时任务时提交后不再读过期对象
|
2026-10-16 16:49:47 +08:00 |
|
ThearchyHelios
|
2371e75f17
|
评测执行的主干:后台评测、无头作答、评分、统计、对比与 A/B、清理(下一轮第 3 波 W3-c 第一段)
为什么:第 2 波只有题集和期望答案的来源,评测本身跑不起来。这一段把细案 01 做法 9–12、16、17 的后端接上,
量的是用户在问数据页拿到的同一轮,而不是另抄一份编排。
- eval/answer.py:无头作答,串起 answer_ops → chat/turn 的决定 → launch_run(origin=eval,带目录视图、只读、遮罩)
→ 等终态(停在审批的取消、记「评测不代批」;驳回记路径「被驳回」)→ review_of_run → 按同一规则重来一次;
工作流题按钉住版本的图跑探索运行(不发正式运行,免得被 pick_base 和应用视图取到)。用量按角色记
- eval/runner.py:用 core/job_runtime,一次评测一个任务,题 × 重复 × 臂一项;A/B 几臂共用期望、同一题同时开跑;
开评拍目录快照、记上传表格版本和表结构哈希的前后;并发不超过 max_parallel 和全局并发的四分之一;每题时限;
评测单独一本账(开跑前估算、每题预留后找补、触顶不再开新题);止损;能停、只重试没做完的、重启标中断不续跑
- eval/score.py:六种期望、五种结论(量纲不同单列)、维度配对与弱匹配、路径不对直接不通过、口径 dual 两版都报;
逐题 E1 用口径账本的 compare_queries(总方案 X2,不另写 signals);SCORER_VERSION 可重评(eval/rescore.py,只读封存)
- eval/judging.py:结论裁判走按需裁判同一条路(evidence._judge_now),文字要点由裁判判、单列不计准确率;花费经
judge.charged_to 记在评测那本账上(engine/judge.py 只加了一个上下文变量和取账本的一处)
- eval/stats.py、eval/compare.py:准确率与可追溯准确率 + Wilson 区间、各项分布、P50/P90、按角色成本、引用率、逐题 E1;
选基准、逐题转移与归因、指纹差异、A/B 配对表与精确 McNemar;「目录贡献」预设对照(当前 vs 关,可加只用已核实)
- eval/cleanup.py + core/artifact_store.forget:保留最近 N 次 + 钉住的基线 + A/B 另几臂,删结果、明细工件、底下的运行和
引用行,工件文件一条引用都不剩才删;总表永久保留
- engine/tolerance.py:双盲复算的 _agree / _delta_pct 原样搬来共用(dual_check 改 import,行为不变)
- 设置加 eval 一组(builder 读、admin 写)和 GET /api/settings/eval/spend;题集预算在全站缺省上覆盖,每日上限只能往下收
- api/evals.py:发起(单臂 / A/B / 目录贡献预设)、估算、进度、逐题、停止、重试、重评、钉基线、和上一次比、配对表、清理
- main.py 的 lifespan:影子起草和评测的启动整理、关停(评测先于运行停,停时取消自己发起的运行)
- 测试:test_eval_e2e(dual_check_shop + 剧本模型:按支付日 330 通过且 SQL 等价,按下单日 310 不通过、差在 time;
目录对照 1:0;和上一次比找到退步、归因做法变);通知事件、定时接口形状的老测试按新事件和新字段更新
|
2026-10-16 16:38:09 +08:00 |
|
ThearchyHelios
|
e3d0fe618c
|
定时目标的底座(总方案 X4,细案 01 做法 15):定时只有一套,目标种类在 scheduler/service 里一处封装
- service.target_of / target_columns:读写目标只经这里。workflow 目标 target_id 同 workflow_id;非工作流目标 workflow_id 存空串(老表的非空约束,只加不改的迁移放宽不了),这条规矩不散到别处
- fire_once 按目标种类分派:工作流那段原样搬进 _fire_workflow(重叠跳过、渲染输入、记触发、发起一字不变);这一波别的种类照实记「未能发起」并写明是哪类目标,不发起运行、不把空串当工作流去跑
- 建任务、PATCH 改工作流经 target_columns 一起写两列;存量任务(target_id 为空)照旧按 workflow_id 发起
- 接口和界面这一波不暴露新种类(第 3 波开放),返回的形状不变
- 新增 tests/test_schedule_target.py
|
2026-10-16 10:07:15 +08:00 |
|
ThearchyHelios
|
277982ead3
|
普通用户建应用(后端):
- 蓝图:bp_* 操作和逐卡白名单、蓝图检查、留痕、按蓝图判权限;五个场景模板加自由形(骨架、关节、应用骨架、定时任务),实例化与骨架比对;BlueprintApplier / TemplateApplier(只收模板声明过的关节)与自查;look 新类别口径卡;蓝图对话和填关节两个流式接口,不同组的关节并行填、出错的组串行重试;模板列表
- 试运行与发布单:四种起点(对话、模板、问数据的一轮、已发布版本);试运行是探索运行,草稿应用按这次运行解析、印章写试运行,流程类派给自己、不触发升级;发布单九步、预检只读、每步留痕、停下后接着做、核对卡片指纹和应用管理权、启动时整理中断的单;白话层覆盖全部问题编号
- 记录表与文件:平台托管只追加的记录表、按高水位固定数据、连接上的临时视图做行级可见、写入走动作(records_append)、表版本在发布时切换、草稿不影响线上、记录列表遮敏感列;文件按哈希存、两步上传、提交时绑定运行、下载按读权限、清理、file_text、按配方导入一期(table_import_period)
- 个人应用:存成个人应用(问数据的约束)、刷新(遮罩、只读、每日上限)、只有拥有者看得见、提交审核与共享副本、开关下发到认人接口;页面编辑的候选;隐藏组件不下发;三条新检查
|
2026-10-15 12:09:29 +08:00 |
|
ThearchyHelios
|
941723b17c
|
端到端验收修复与指标出具:
- 身份与工具:登录页建第一个管理员(认人接口的 401 说明能不能建);搭建者有只读的人和组名录,选人给候选并核对名字;授权三行带标题;端点请求头名校验(空名、非法名存不进、发不出时说清原因);写入能力在工具页试运行一律演练、不发送,HTTP 状态照实说成败;写记忆不算只读、查询能力只能选同一端点上的只读能力;审批与遮罩的说法和实际规则一致;开登录时不要署名、导入和发布记登录的人;使用者不显示推演等只给搭建者的操作,403 按是否开登录说话;登录页只认一次人
- 流程与实例:图里用到的岗位(派给谁、超时升级给谁、发送确认派给谁)全部派生、没绑人的发布时报错;写外部系统的参数按能力声明的类型收拢后再算哈希和发送,收不成就不发;发起人的实例页只看这一步的状态,处理人才给待办卡;会签进度带登录核实和时间,升级后照实写规则;实例状态写流程的结论(已退回、未确认、等待核实写入结果),核实生效后不再挂失败原因;流程应用首页不派生最近封存运行的结果块,看板没数据时是安静的空态;样例⑩的金额带类型和下限、待办标题带金额,表单上下限前后端一起生效
- 看板与证据:定时任务模板加 ISO 周、上一 ISO 周、本月、上月;出处链穿过原样解析查询结果的整形节点,追不到原始数据的照实说停在哪里,样例⑨改用 cell();应用首页和版本历史都能做成应用;指标块单位不重复;版本列表带退役说明;定时任务页头跟着刷新;删视图要确认、新视图能起名;编辑器属性用中文名、术语带解释
- 指标出具(用户 2026-10-15 拍板):契约只写「指标来自」、上游没有报告撰写节点、成果里没有模型写的话时按指标出具——必需指标齐、指标输入追到原始数据、成果字段里的数回指得上才完整出具;受管级要求每个指标静态地追到原始数据(governed.metric_untraced);出具横幅和应用印章写明按指标
- 受管工作流降为已发布只给管理员(Q8 顺延,服务端同样拦);工作流接口带当前发布版的级别,画布上改过之后也认得出受管工作流
|
2026-10-15 07:15:37 +08:00 |
|
ThearchyHelios
|
df6b0dd3ae
|
M4:触发历史的翻页游标写成 Z 结尾,照原样拼进查询串也能翻页
next_before 原来是「2026-10-06T14:37:03.376320+00:00」,照接口说明「原样传回」拼进地址时「+」被查询串解成空格,
回 422「翻页位置需要是接口返回的 next_before」。界面用 URLSearchParams 编码不受影响,照说明写脚本、做集成的会撞上。
现在游标是 UTC 的 Z 结尾、精确到微秒(和运行列表的游标一个写法,放进地址不用编码);解析时 Z、+00:00、被解成空格
的「 00:00」(老的游标照原样拼进地址时就是这样)都认,不是时间的照旧回 422。check-schedules 的假接口照服务端用记录
时间作游标,另加一节:老服务端给 +00:00 的游标时,页面编码成 %2B 传回、第二页接得上、不重复。
|
2026-10-07 00:02:15 +08:00 |
|
ThearchyHelios
|
1bee9b5100
|
触发历史不再给基准已过时的自动对比;对比页找不到默认基准时标题不再和「可在上方选择」打架,换基准的下拉和基准卡写明失败、取消的运行
- 中间失败的那次事后被接着运行成功之后,第 3 周存着的那份对比(比的是第 1 周,previous 为假)和运行详情「与上一次
对比」的默认基准(现在是第 2 周)又对不上,两处却都写「上一次成功的运行」。auto_compare.outdated 对基准当时就不是
紧挨着的上一次的那几份按 pick_base 现挑一遍,基准变了的算过时;api/schedules._fire_outs 对过时的给 null(不给链接、
不给旧计数),两个同名入口比的始终是同一对运行。基准没变的照旧给:中间那次还没结束、后来失败、被删掉都一样。紧挨着
的上一次不会过时(两次之间插不进新的运行),不核
- test_base_follows_launch_order_not_finish_time 补上:接着运行完之后第 3 周的触发记录不再带对比、任务列表的 last_fire
同样不带、运行详情的默认基准是第 2 周;另加一条基准仍是挑出来的那一次时照旧给出
- 对比页找不到默认基准:标题由「未找到可作为基准的运行」改为「没有默认基准」——失败、取消但封存了的运行不当默认基准,
却照样能在上方手动选;服务端的原因改成「没有找到上一次成功的运行:需要同一工作流、同一运行类别里比这次先发起、成功
结束并已封存的运行」,运行详情弹出的提示单独读也说得清
- 换基准的下拉给失败、已取消的运行写上状态,基准卡也标出来;下拉说明补一句默认基准只取成功结束的运行
- 运行详情「更多」的菜单项点之前不知道基准是哪一次,基准不是紧挨着的上一次时仍叫「与上一次对比」,和触发历史的叫法
不同:注释照实写明,留作后续
|
2026-10-06 13:33:40 +08:00 |
|
ThearchyHelios
|
45fe01effe
|
定时任务自动对比复核整改(后端):只比成功的运行、按发起先后挑上一次成功的基准、和两边的封存绑定,对比挪到认领之前在锁外做并限时限并发;失败通知的处理行不再重复原因
- 只比成功结束的运行,基准也只取成功的:失败、取消的运行指标不全,和上一次比只会得出「移除 N 个」,拿失败的那次当
基准每个指标都成了「新增」。基准改成自己查同一定时任务、同一工作流、比这次先发起的运行里成功并封存的最近一次,
不再用对比接口的 default_base(按结束时间挑:老的失败运行事后被接着跑完,会拿后一次触发当它的「上一次」)。
中间隔着失败、取消的运行时,通知写「与上一次成功的运行(#短编号,日期)相比」,Fire.compare 多一个 previous
- 和封存绑定:运行的封存要盖住最后一条结束事件才算封存完(sealed_now)。runner 先写终态、再另起会话封存,失败后
接着跑完的运行在两步之间还带着失败时的清单哈希,以前这一拍会直接认领、按旧封存比、通知里写旧的清单哈希;现在
等新的封存,等不来就照常推送但不比、不写哈希。停在审批上的通知也不再写失败时留下的哈希。对比工件连同两边的清单
哈希一起存,触发历史发现任何一边不在终态或清单哈希变了就给 null;对比途中封存变了不记(条件写)
- 时机和时限:锁里只挑出状态有变化的触发,认领挪到对比之后、锁外按条件 UPDATE 做。对比最多等 20 秒(含排队),
同一时刻最多 2 个;超时只记警告,通知不带对比照常推送。停机时扫描在对比途中被取消,这次触发还没认领,下次照常
比、照常推(以前先认领、后比,这条通知会永远丢掉)。同一份封存已经比过的直接用记下的结果
- 失败通知:从没开始执行的,原因刚写过,处理行不再让人「查看原因」,任务在排期上写「下一次触发会照常发起」,停用
的写怎么重新发起;开始执行过的改成「请在 AgentLab 的「记录」中查看失败原因」,和挂起那句指向同一个导航入口
- 新增 test_scheduler_compare_guards.py(封存绑定、时限、取消、并发、复用),test_scheduler_compare.py 补真实缺
指标的失败运行、上一次失败、补跑老运行几种用例;去掉实现逐项验证过会变红
|
2026-10-06 08:48:56 +08:00 |
|
ThearchyHelios
|
f8ac8dc1d6
|
定时任务自动对比收尾:基准那一次不在终态或被删时不给对比、对比工件读不出来时触发历史照常打开;检查脚本按实际底色量对比度
- 触发历史的 compare:以前只看这一次的运行在不在终态。基准那一次被强制删除、失败后被继续执行时,对比页比不了,
「对比上一次」链过去只会报错——基准一侧同样要在终态,否则给 null
- 对比工件读不出来(权限、磁盘出错)时记一条警告、给 null:以前 OSError 直接抛出,整页触发历史回 500。被改过
(内容与哈希不符)的以前就给 null,这次补上用例
- check-schedules:页头的定时任务链接、触发历史的「对比上一次」改成量 WCAG 对比度(≥ 4.5),底色顺着祖先叠到
不透明为止。以前比的是「字色不等于页头的底色」,页头本身透明,那样比永远成立;深色也补上同样的检查。另加一项
署名的立即运行配长名字:署名照写、链接截断、页头不横向溢出
|
2026-10-06 07:43:01 +08:00 |
|
ThearchyHelios
|
f0f1b99ead
|
定时运行结束后自动和同一定时任务的上一次对比:结果存成工件记在触发记录上,触发历史和通知只给计数摘要与对比页链接
- 新增 app/scheduler/auto_compare.py:通知扫描认领到运行进入终态(结束、失败、取消)的那一次之后、推送之前,
调运行对比接口的现成函数(default_base、compare_runs,不改它们)比一次。基准只取 default_base 的「同一定时
任务」那一档,退回「同一工作流」的不比——那不是这个任务的上一次。没封存的不比;比不了(基准封存核对不一致等)
记警告、意外异常记堆栈,都不影响通知。整份结果存成 run_compare 工件,不挂在运行名下(不进运行的工件列表),
工件 id 写进 ScheduleFire.compare_artifact;再次进入终态(失败后继续执行)时按新的封存重新比、覆盖旧结果
- 接口:Fire 多一个 compare: {base_run_id, summary}(summary 同对比接口的计数)或 null。运行现在不在终态
(被继续执行)、工件读不出来时为 null;工件摘要按 id 缓存(内容寻址,不会过期),读盘在线程里
- 通知:结束、失败的通知多一行「与上一次相比:只数据变 3 个、口径与数据都变 1 个、SQL 结构变 0 个」(三类总写,
其余各类有才写,两边都没有指标时不写一串 0 个),配了对外访问地址时附对比页链接(/runs/compare?target=…&base=…),
四种格式都带;通用格式多一个 compare 字段。只给个数,不放任何具体数字
- 没配 Webhook 的任务也比:触发历史里要用
|
2026-10-05 18:45:59 +08:00 |
|
ThearchyHelios
|
a9d7cba884
|
定时任务复核修正(第 1 轮):重启挂起的运行不再让任务静默停摆,格式选错、地址发不出去时照实报,整份回写不再丢掉到点的触发
- 挂起:上一次运行在服务重启时被挂起(interrupted、没有待审批)不会自己接着执行,之后每次触发都按重叠跳过,原因写
「还没有结束」,一条通知也不推,任务就此静默停摆。interrupted 照规格仍算没结束,但跳过原因按挡路的运行分三种写
(仍在进行中、正在等待审批、已挂起并请在「记录」中继续运行或放弃),运行编号写成界面上的 #前 6 位,去掉「按设置」;
挂起的那次按 failed 事件推一次,写明原因和处理办法,不是每次触发都推。停在审批时每停一个审批点推一次(已处理状态
带上第几段执行,以前第二个审批点不再推);审批刚批完、还没接着执行(answered)不当挂起
- 没有结束时间的失败运行(服务重启时还在排队、被改成 failed)永远不会封存:等封存改按最后更新时间算,以前按「现在」
等,每一拍都等、永远不推
- 平台错误码按地址的主机认,不看所选格式:格式和地址对不上时,测试显示「已送达」、正式推送记成功,群里却收不到;
现在记失败并带上平台的错误码。群机器人的地址(飞书、企业微信、钉钉)保存时要配它平台的格式,否则 422;格式省略时
按地址认。只在地址或格式真改了时查,库里已有的旧设置不挡停用、改名
- 地址校验:端口不是 1 到 65535 的数字、夹着空格或不可见字符(零宽空格、控制字符)、httpx 建不了请求的(主机名不合
IDNA 规则)保存时就回 422 和中文说明;推送时另兜住 InvalidURL 和其他异常,测试接口不再回 500 或英文报错;端口写错
的地址也照样取出主机名
- PATCH 看值变没变,不看键在不在:整份表单回写不再重新校验没改的工作流(工作流删了也能停用),cron、时区、启用状态
真改了才重算下一次触发。启用着改 cron、时区时,从原来那个到点的时刻接着算,新表达式也覆盖那一刻就还发起这一次。
补两人同时保存的测试,证明条件 UPDATE 守住了乐观锁
- 发起中的占位:接口读到正在发起的触发按「已发起」给(run_id 为空),不再闪一次「未能发起:服务在发起运行前停止」;
库里仍先写占位,进程被强杀时照实说没有发起
- stop:先置停止标志再取任务,这一拍收尾不再新起通知扫描(以前会落下一个不在等待名单里的通知任务);循环和通知两件
事并行等,宽限缩到 3 秒和 1.5 秒,给关停时的 run_manager.shutdown 留出 docker stop 的大半时间
- 通知正文:立即运行写「手动触发」,补发标明「错过后补发」;失败不再写「原因:运行失败,详情请查看运行记录」,改写
失败节点的名字和处理办法;状态叫法和界面一致(等待审批,已挂起,可继续运行);「封存哈希」改叫「清单哈希」,运行
编号写 #前 6 位;测试消息只说收到它证明得了的事(企业微信、没配密钥时不提签名)。测试接口的 message 改成 ok、
http_status 之外的补充说明(送达时提醒去接收端确认,失败时是原因),前端接在「测试消息已送达(HTTP 200)」后面不再重复
- 422 文案:不回显 Python 的值(None 写「未填写」,列表不原样回显、点出不认识的那一项),格式、事件写中文名;
copy-allow.json 为平台名「钉钉」加一条(和前端包为 terms.ts 加的那条并存,试合并不冲突)
- test_loop_ticks_until_stopped:下一次放在整分上、只认发起的那一条,去掉约 1/60 的偶发失败
- 逐个做过变异,改回后对应测试都变红:挂起不推、跳过原因退回旧写法、没结束时间按现在等、错误码只看格式、去掉版本
条件、到点保留和值比较一起去掉、不屏蔽发起中的触发、stop 既不查停止标志也不兜底、answered 当挂起、审批状态不带段号、
不建请求校验地址、保存时不查格式
|
2026-10-05 10:00:25 +08:00 |
|
ThearchyHelios
|
b66eb955b5
|
定时任务小修:数字按 isdecimal 认,输入生成失败的原因不再说成模板写错
- 「²」这类字符 isdigit 为真、int() 却认不得:写进 cron 或每页条数时会冒出英文的 ValueError(被全局处理器
回成 400)。改按 isdecimal 认,照常回中文的 422
- 库里的 cron 或时区后来坏了时,立即运行记下的原因以前写「输入模板无法渲染」,其实模板没错:改成照实说
「无法生成这次运行的输入」,后面跟是哪一项
|
2026-10-05 08:50:57 +08:00 |
|
ThearchyHelios
|
6d11145a39
|
定时任务接口:增删改查、预览、变量清单、立即运行、触发历史和测试 Webhook
- 按前后端约定的 Schedule / Fire 形状返回;Webhook 地址和签名密钥加密存放,接口只给主机和末 4 位、有没有密钥
- 创建、修改时校验名称、cron、时区、工作流存在、正式运行要有发布版本(没有就说明原因、建议改探索运行)、输入
模板和入口字段;不对回 422 {detail(中文), field},请求体自己解析,连 JSON 写坏了也回中文
- PATCH 带 version,条件 UPDATE 做乐观锁,对不上回 409;webhook.url 省略表示不改、空串或 null 表示删除,secret
省略不改、空串去掉;只停用、改名不重新校验工作流——工作流撤了发布也要能先把任务停下来
- 预览给下几次触发(UTC)和按下一次触发渲染的输入,带工作流时只查字段名、不查缺的必填项(用户还在填)
- 立即运行和到点触发同一套规则(重叠跳过、正式运行只从当前发布版本发起),运行记在点按钮的人名下;触发时间
取到秒,同一秒连点交回同一条,不会发起两次
- 触发历史按创建时间倒序翻页,Fire 带运行现在的状态和推送记录;删除任务连同触发历史和推送记录,发起过的运行留着
|
2026-10-05 08:43:44 +08:00 |
|
ThearchyHelios
|
a3058e7df8
|
复核套件骨架(后端):先把后续几个工作包要用的位置占好,各包只改自己的文件。节点类型加双盲复算 dual_check、反方审稿 challenge,执行器是占位(记一条 info 日志后跳过,产出 skipped 和原因),校验按普通节点走,叫法进 labels,暂不写进助手的节点说明。出具契约留一个通用口子:成果节点上游任何节点产出里的 issuance_gaps(字符串列表)收进缺口,前面加上「节点类型「节点名」:」,出具随之降档、不会升档;只认这个成果的上游,写坏的条目跳过。路由先登记 schedules、compare、bundle、inquiry、whatif 五个空前缀,挂在 /api/runs 下的四个排在 runs.router 之前,以后加固定路径不会被 /{run_id} 吃掉。定时任务的调度先放空的 start / stop,AGENTLAB_SCHEDULER 默认开、0 / false / off 关,写进设置;启动时开着才 start,测试环境默认关
|
2026-10-04 23:40:20 +08:00 |
|