sinohqb
2e3c00bc69
feat(v1.3.1): Phase 4 场景扩充、网关延迟优化与报告 go/no-go 展示
...
CI / test (pull_request) Successful in 3m55s
4.1 新增三个评估场景(急诊分诊、慢病管理、健康咨询),各 3 个用例,
全部使用无模型绑定依赖的规则;急诊场景编码 <20s 延迟验收标准
4.2 ModelGateway 由每次请求新建 httpx.AsyncClient 改为单实例共享客户端
(复用 TCP/TLS 连接),引擎与模型连通性测试端点负责关闭;
tutu 通道已具备同等优化,无需改动
4.3 Reports.tsx 单次报告顶部新增上线评估横幅:go/no-go/conditional
三态 banner + 各验收标准达标情况标签
版本号升至 1.3.1(v1.3.1-final)。
门禁:pytest tests/unit 709 passed;ruff 全绿;
前端 tsc --noEmit + vitest 232 passed。
附带修复 RunList 测试时区缺陷:started_at 用 UTC 日期构造,
本地 00:00-08:00 之间会被默认"今天"过滤器排除导致误报失败。
2026-08-26 02:15:18 +08:00
sinohqb
2f09ee2bfc
refactor(v1.3.1): Phase 3 报告横幅、评分逻辑收敛与成本闭环
...
CI / test (pull_request) Successful in 3m58s
- 报告渲染 Go/No-Go 上线评估横幅(HTML 彩色 banner + Markdown 引用块)
- 抽取 scored_llm 共享模块:llm_score / fluency 直连调用与评分解析收敛
- 网关新增 chat_with_usage / embed_with_usage,规则按次归集 llm_usage
- 引擎分岗位用量归集(judge/generator/embedding/moderation)写入
RunSummary.eval_usage_by_purpose,并发下不做总量差值
- cost_tracking 重构:data/model_pricing.json 覆盖 + 默认计价表,
删除从未有数据支撑的 Turn 维度成本函数(偏差说明见 PR)
- 报告 summary 增加 eval_cost 分岗位成本段并在 Markdown 渲染
2026-08-26 01:59:20 +08:00
sinohqb
c956da7686
feat(v1.3.1): Phase 2 让成本/放弃率/Go-No-Go 基础设施真正生效
...
CI / test (pull_request) Successful in 4m3s
- token 用量接入:ModelGateway 经 adapter.parse_usage 累计评测侧 LLM 调用的
token 消耗,引擎写入 run.summary.eval_token_usage,报告透出
- 放弃率落地:CaseOutcome 新增 abandoned 标记(对话中途发送/接收失败),
build_run_summary 统计 abandoned_cases / abandonment_rate
- Go/No-Go 可配置:Scenario 新增 acceptance_criteria 字段(DB 列 + 幂等迁移),
报告按场景标准出 verdict,缺省回退全局默认;标准变更不触发考纲升版
2026-08-25 18:38:18 +08:00
sinohqb
c1a3cdbaa9
fix(rules): 修复代码审查发现的三处规则层缺陷
...
CI / test (pull_request) Successful in 4m5s
- response_time: 仅配置 max_ms 时恢复 v0.3 评分语义(最后一轮评分 + 超限线性惩罚),扩展指标共存时才用均值评分
- safety: 移除 moderation API 的黑名单命中跳过守卫,两层安全检查独立执行、发现均上报
- llm_score: 多维度评分添加 Semaphore 并发上限(5),防止维度数多时无限扇出模型请求
2026-08-25 18:13:11 +08:00
e7e3716325
Merge pull request 'feat: 用户体验指标(放弃率+流畅度评估)' ( #32 ) from feat/user-experience-metrics into main
CI / test (push) Successful in 4m9s
2026-08-25 08:40:45 +00:00
sinohqb
21cc6ed407
feat: 用户体验指标(放弃率+流畅度评估)
...
CI / test (pull_request) Successful in 4m11s
新增用户体验跟踪能力。
- RunSummary 新增 abandoned_cases 和 abandonment_rate 字段
- 新增 fluency 规则:LLM 评估对话流畅度和自然性(0-10 分)
- 流畅度评估考虑:自然性、重复性、连贯性、响应质量
- 新增 10 项单元测试(676 tests passed)
注:放弃率的实际计算逻辑需要在引擎中集成,本 PR 提供数据模型和规则基础设施。
Closes #26
2026-08-25 16:36:28 +08:00
sinohqb
56c56a7b4a
feat: 成本效率跟踪基础设施
...
CI / test (pull_request) Successful in 4m9s
新增成本跟踪模块,为对话级和任务级成本计算提供基础。
- Turn 模型新增 prompt_tokens、completion_tokens、total_tokens 字段
- OpenAI 协议适配器新增 parse_usage() 提取 token 使用量
- 新增 evaluation/cost_tracking.py 模块:
- ModelPricing:模型定价配置
- TokenUsage:token 使用量聚合
- CostBreakdown:成本明细
- calculate_cost():根据 token 使用量和定价计算费用
- calculate_turn_cost()、calculate_case_cost()、calculate_run_cost()
- 内置常见模型定价(GPT-4o、GPT-4o-mini、Claude 等)
- 新增 11 项单元测试(677 tests passed)
注:引擎集成(实际捕获 API 调用的 token 使用量)留待后续实现。
Closes #25
2026-08-25 16:07:08 +08:00
2c79abf1de
Merge pull request 'feat(safety): 扩展规则覆盖幻觉、越权和合规检查' ( #30 ) from feat/safety-extended into main
CI / test (push) Successful in 4m7s
2026-08-25 08:02:05 +00:00
sinohqb
192fe0fc5f
feat(safety): 扩展规则覆盖幻觉、越权和合规检查
...
CI / test (pull_request) Successful in 4m2s
扩展 safety 规则,新增三个安全检查维度。
- 幻觉检测(check_hallucination):LLM 判断回答是否编造事实
- 越权操作检测(unauthorized_actions):模式匹配检测越权行为
- 合规性检查(required_disclaimers):检查必需声明是否存在
- 保持原有 blacklist + moderation API 向后兼容
- RuleResult.details 包含所有问题列表
- 新增 10 项单元测试(656 tests passed)
Closes #22
2026-08-25 15:30:00 +08:00
sinohqb
737c9ab80e
feat(response_time): 支持平均延迟和吞吐量指标
...
CI / test (pull_request) Successful in 4m6s
扩展 response_time 规则,支持多维度延迟和吞吐量测量。
- 新增 avg_latency_max_ms:多轮对话平均延迟阈值
- 新增 throughput_min:最低吞吐量(turns/min)
- 保持 max_ms 向后兼容(单轮延迟阈值)
- RuleResult.details 包含延迟统计(avg/min/max/latencies)
- 新增 10 项单元测试(656 tests passed)
注:首字延迟(first token latency)需要流式数据支持,当前 Turn 模型未提供,留待后续增强。
Closes #21
2026-08-25 15:03:54 +08:00
2f08e7bf06
Merge pull request 'feat(report): 上线验收报告 go/no-go 结论' ( #28 ) from feat/go-no-go-verdict into main
CI / test (push) Successful in 4m6s
2026-08-25 06:31:42 +00:00
sinohqb
2314ebe3bc
feat(report): 上线验收报告 go/no-go 结论
...
CI / test (pull_request) Successful in 4m7s
新增纯函数模块 evaluation/go_no_go.py,基于 RunSummary 指标自动生成
go/no-go/conditional 三级结论。
- AcceptanceCriteria 模型:judged_pass_rate_min、pass_rate_min、avg_latency_max_ms
- GoNoGoVerdict 模型:decision、summary、criteria_results
- evaluate_go_no_go() 纯函数:接收 summary dict + criteria -> 返回 verdict
- 集成到 generate_report(),报告 dict 自动附带 go_no_go 字段
- 三级结论:go(全部达标)、no_go(核心未达标)、conditional(有风险)
- 新增 9 项单元测试(642 tests passed)
Closes #20
2026-08-25 14:28:55 +08:00
sinohqb
a29f78ff4b
feat(llm_score): 支持多维度独立评分
...
CI / test (pull_request) Successful in 4m9s
扩展 llm_score 规则,支持通过 dimensions 参数配置多个评分维度,
每个维度独立评分 0-10 分。
- RuleResult 新增 details 字段存储结构化多维度分数
- 向后兼容:原有 criteria 单维度模式继续有效
- 多维度模式下各维度并行调用 LLM,返回平均分和明细
- 新增 4 项单元测试
Closes #19
2026-08-25 14:17:49 +08:00
sinohqb
0d074e5465
test(runs): 取消测试扩至 30 case 适配并发执行
...
CI / test (push) Successful in 4m3s
case 并行(默认 3)后原 5 case 场景在取消请求到达前就跑完,
取消语义不再被观测到。扩到 30 case(10 波)保证取消窗口充分。
2026-08-24 23:38:53 +08:00
sinohqb
90ebbd5ff4
test(scheduler): 补全触发失败落账与错误路径测试(+9 用例)
...
覆盖 scheduler.py 中等难度边缘分支:
- _trigger_openclaw_agent 非零退出码 → on_failure 回调
- _trigger_openclaw_agent subprocess 异常 → on_failure 回调
- _record_worker_trigger_failure 成功/跳过/DB 异常兜底
- _record_planner_trigger_failure 成功/跳过/DB 异常兜底
- _fire_and_forget cancelled task 不记录异常
scheduler.py 覆盖率 75% → 81%
后端总计 963 passed
2026-08-24 17:18:52 +08:00
sinohqb
3705945a7d
test: 完整测试覆盖补全(+163 用例)
...
架构重构(候选 1-6):
- storage/repository.py 按域拆分为包(target/scenario/run/campaign/result)
- storage/db.py 按域拆分为包(eval/campaign/file/model_config/intelligent_eval)
- intelligent_eval/lifecycle.py 按状态机阶段拆分为包
- services/runs.py 编排逻辑下沉
- Campaigns.tsx 拆分为 campaigns/ 子组件
测试补全(候选 7):
前端(+125 用例,107→232):
- utils/ 纯函数:date/campaignTime/ruleLabels/fileTree/fileFormat/colors
- stores/tabStore 状态管理
- 核心组件:FormDrawer/PageWrapper/ChatBubble/GeneratedMessages/SectionHeader/StatCard/TurnList
- 业务组件:CaseBlock/CaseDetail/RuleOverview/WindowTimeline/RunList/TabBar/CampaignRunTimeline
- 文件管理:FileCategoryTree/FileTable
- hooks:sessionReducer/useFiles/useRunSession
后端(+38 用例,916→954):
- targets API CRUD + 404 路径
- WebSocket 连接管理器
- proxy 头部重写(CSP/X-Frame-Options)
- target 仓储 update 方法
- app 健康检查 + SPA 404
- scenarios 模板端点 + 404
- files API 边缘分支(404 场景 + 500 兜底)
- files service update_category
- 智能评估状态机迁移测试
门禁状态:
- 前端:tsc 干净 + 232 passed
- 后端:954 passed + ruff 全绿
2026-08-24 15:56:09 +08:00
sinohqb
7eae6de52d
refactor(evaluation/storage): 结算统一与 repository 拆分(Phase 2 + 3)
...
合并两个不可分割的深化:
Phase 2 — 智能作业结算统一(ADR-0012)
- intelligence_jobs.execute(job_kind, campaign_id, ...) 作为结算的
唯一实现:建行 → 认领 → 校验 → generating → 落账,一处编排、
一处截断(500 字符)。两个 executor 退化为 ensure_queued /
validate / work_fn 三个小 adapter。
- analysis.validate_analysis_request() 共享校验入口(活动终态 →
模型),路由捕获映射 400、executor 捕获落 failed 行,与
validate_comparison_request 先例同构。
- campaign_runner._auto_start_analysis 的跳过守卫收敛至
auto_intelligence_eligible 单一判断点。
- comparison.py 删除零调用的 build_comparison_payload;
load_comparison_view 投影归位至 campaign_read_model。
- 新增 characterization 测试(认领竞争、重复触发、截断、恢复上限)。
Phase 3 — storage/repository.py 拆分
- AsyncJobRepository 及两个子类迁至
storage/async_job_repository.py(Phase 2 的 intelligence_jobs
与 comparison 必须 import 自该路径,故与 Phase 2 同 commit)。
- ExplorationSession / ExplorationMessage 迁至
storage/exploration_repository.py;repository.py 由 1180 行降至
约 814 行,grep 确认无残留符号。
- exploration 子模块与路由 import 全部更新;测试 import 跟随。
刻意不做:CAS 共享原语、app.py 五 registry 关停顺序归一
(ADR-0006 精神,等真实需求出现再议)。
2026-08-24 05:50:27 +08:00
sinohqb
71543f042a
refactor(intelligent-eval): 可见性接缝收敛(Phase 1)
...
将「已删即 404」语义收进 IntelligentEvalRepository 单一接缝,消除三处独立裁决;
任务监控开始隐藏已删评估的任务(本 Phase 唯一刻意行为变化)。
- repository.py 新增 visible() 谓词与 require_live_eval() 服务接缝;
六处裸谓词统一走它,get()/get_including_deleted() 语义不变。
- decision_logs.py 删除本地 _require_eval,三处调用迁至 repository 接缝;
count_decisions 由 len(.all()) 改为 func.count。
- task_queue.py list_tasks 与 stats 过滤已删评估的任务(行为变化)。
- web/routers/intelligent_evals.py: _require_eval_exists → _require_live_eval,
把 LookupError 翻译为 404;expired 会话 Markdown 标注下沉至
read_model.report_markdown_by_eval;配置快照 11 字段序列化收至
config_snapshot.snapshot_to_dict 单一出口。
- AGENTS.md 登记可见性纪律(已知陷阱 #6)。
- 补 characterization 测试锁定四处契约;更新 task_queue 测试以使用
真实 eval_id(可见性过滤后字面 eval_id 不再可见)。
2026-08-24 05:47:00 +08:00
sinohqb
84627a3c6a
refactor(intelligent-eval): 消除 lifecycle.py 和 scheduler.py 中的重复延迟导入
...
CI / test (push) Successful in 3m16s
- 将延迟导入移至模块顶部,消除 Shotgun Surgery 气味
- lifecycle.py: 移除 41 行重复导入
- scheduler.py: 移除 14 行重复导入
- 修复测试:更新 monkeypatch 以补丁 scheduler 模块的引用而非原始模块
- 符合代码规范:避免函数内重复导入
Closes code-review finding: repeated deferred imports (Shotgun Surgery)
2026-08-24 01:47:47 +08:00
sinohqb
2d2c5a2904
feat(intelligent-eval): logical delete for terminal evals
...
CI / test (push) Successful in 3m24s
Add `deleted` terminal status: completed/cancelled/failed → deleted via
DELETE /api/intelligent-evals/{id} (idempotent, 409 for non-terminal).
Deleted evals are hidden from list, detail, stats, and all sub-resource
endpoints (sessions/report/decision-logs/config-snapshots); child tables
are untouched (audit-safe). Frontend shows a Popconfirm-guarded delete
button for terminal evals only.
2026-08-21 14:34:04 +08:00
sinohqb
2a0bcdd185
refactor(intelligent-eval): drop ADR-0008 transitional wrappers, callers use domain
...
CI / test (push) Successful in 3m8s
架构审查候选④:ADR-0008 收敛调度域时为保测试兼容留下的过渡 wrapper 使命结束。
删除 8 个浅封装:task_queue 的 _is_slot_due / _calculate_session_deficit
(零调用死函数)+ _calculate_priority / _get_attention_reason,decision 的
_parse_time_slot(零调用死函数)+ _get_current_slot / _count_sessions_in_slot /
_has_high_severity_issues。调用方直接使用 domain 模块。
5 个隔着 wrapper 测 domain 行为的测试迁到新文件
test_intelligent_eval_domain.py,直接锁定 domain,覆盖零丢失。
删除测试通过:复杂度直接消失,时段/欠账/优先级知识只剩 domain 一处。
870 tests passed,零行为变化。
2026-08-21 03:50:44 +08:00
sinohqb
58c2ad0227
refactor(intelligent-eval): unify watchdog failures behind fail_eval seam
...
CI / test (push) Successful in 3m10s
架构审查候选③(状态机归一):_TRANSITIONS 成为评估状态机的唯一真相。
三个 watchdog(planning 双闸 / executing 兜底 / 触发失败闸门)原先直接
row.status = FAILED 绕过转换表、手工重复写字段。收编到新的公开接缝
fail_eval(session, eval_id, reason, decision_type, context):表校验 →
repo CAS 条件写(status/plan_feedback/updated_at/completed_at 一条 SQL)
→ append_decision_log 留痕。
CAS 冲突(如用户在扫描间隙抢先取消)跳过并留日志,不当故障。API 路径
本已在表内,不动。新增 4 个契约测试,870 tests passed,零行为变化。
2026-08-21 03:35:05 +08:00
sinohqb
182b0e59cb
refactor(intelligent-eval): extract scheduler runtime + internalize decision-log dedup
...
CI / test (push) Successful in 3m9s
架构深化两则(架构审查候选①②):
① scheduler 抽取:web/app.py 约 400 行触发式执行编排(60s 扫描循环、
docker exec 触发、失败落账)沉入 intelligent_eval/scheduler.py,runtime
单例 start()/stop()/scan_once() 与 campaign_runtime 惯例一致;worker/planner
两处重复触发代码合并为一个触发原语;_supplement_decision_logs 归入
decision_logs.py。测试改为直接驱动 scan_once(interface 即测试面)。
② 决策日志去重内化:create_decision_log 的去重只服务 agent 上报路径;
新增 append_decision_log(平台落账纯追加)与 count_decisions(计数原语),
lifecycle/task_queue 全部平台落账切换,调用方不再需要塞 attempt 骗去重。
零行为变化:提示词、60s 节拍、编排顺序、闸门语义原样保留,866 tests passed。
2026-08-21 03:20:14 +08:00
sinohqb
d0487b54b4
fix(intelligent-eval): respect time-window slots before nudging analyst
...
冒烟发现 analyst_nudge 不考虑时间窗口:首会话完成后 10 分钟即催促,
但后续时段尚未到期,导致报告提前收敛、漏掉计划内会话。催促闸门新增
"窗口未结束且会话数未达计划则跳过";worker 触发指令同步明确仅当所有
时段会话都达终态才转 analyst。
2026-08-20 16:27:05 +08:00
sinohqb
eb4944a8bd
feat(intelligent-eval): terminal-state discipline watchdogs (ADR-0011)
...
常见故障自愈有上限,超限收敛终态且可见:任务 attempts 上限、会话过期、
planning 双闸、executing 超窗兜底、触发失败计数判死、孤儿 agent 双管、
fire-and-forget 触发;open_session 预算硬闸门、settle 按终态区分、报告
scores 归一化;cron 池遗留面全删。
2026-08-20 14:34:17 +08:00
sinohqb
5de46d514a
fix(intelligent-eval): trigger worker/planner with isolated session
...
CI / test (push) Successful in 4m0s
t480 排查:评估 cd636d71 一直'等待 OpenClaw 创建会话',scan loop 每 60s 触发
worker,但 worker 被触发后 0 次工具调用、直接幻觉输出'评估 pending_approval'
(实际 executing),任务永不认领。
根因:openclaw agent --agent main 复用 main 持久 session,多次触发累积上下文
缓存(~12 万 token)后 LLM 不再执行 worker skill 的 API 步骤。
验证:独立 --session-id 触发 worker → 正常取任务、建会话、close。
修复:worker/planner 触发命令加 --session-id(每次唯一 agenteval-worker-*/planner-*),
避免 main session 污染;timeout 300→600(独立 session 首次加载 skill 更慢)。
测试:触发断言含 --session-id,901 passed
2026-08-18 17:22:30 +08:00
sinohqb
71d38ebef6
fix(intelligent-eval): settle stale tasks of finished evals
...
CI / test (push) Successful in 3m57s
任务队列出现'评估已 completed 却有待认领/执行中任务'的残留:评估离开
executing 后,其 pending/assigned 任务无人清理(requeue_stale_assigned_tasks
只处理 executing 评估的 assigned,评估结束被跳过)。
- 新增 task_queue.settle_tasks_for_finished_evals:评估非 executing 时,
其 pending/assigned 任务回收为 completed;executing 评估的任务保留
- scan loop 每 60s 在 requeue+scan 后调用清理
测试:+1(已结束评估的 pending/assigned 回收、executing 保留、幂等),901 passed
2026-08-18 16:04:46 +08:00
sinohqb
56d709c44f
fix(intelligent-eval): reject report until all sessions closed
...
CI / test (push) Successful in 3m59s
t480 实测:评估 completed 但 completed_sessions=0(进度 0%)。根因
(diagnosing-bugs):submit_report 无条件 CAS executing→completed,不看会话
状态——worker 建会话未 close 时,analyst 仍可提交报告把评估标完成。
- lifecycle.submit_report 加校验:存在会话时须全部 close(completed),
否则抛 IntelligentEvalTransitionError(409)——杜绝'评估完成但进度 0%'
- 无会话的评估仍可直接提交(analyst 正常路径不变)
回归测试(诊断闭环 Phase 1 反馈环先红后绿):
- +test_submit_report_rejects_when_sessions_not_closed(running 会话→409)
- +test_submit_report_allows_when_sessions_closed(全 close→200)
900 passed
2026-08-18 15:30:51 +08:00
sinohqb
60c54a67e4
fix(intelligent-eval): parse minute-level time slots (1h windows)
...
CI / test (push) Successful in 3m54s
planner 对短窗口(1h)产出分钟级时段(如 0-20min/20-40min/40-60min),
但 parse_time_slot 只支持小时级(8-10h),分钟格式解析失败返回 None →
is_slot_due=False → 审批后评估永不入队、不触发 worker。
- parse_time_slot 支持 h/min 后缀,统一换算成小时(float)返回
- is_slot_due/get_current_slot/count_sessions_in_slot 用 timedelta(hours=float)
兼容两种格式;decision._parse_time_slot 类型标注同步 float
测试:+1(分钟格式时段解析与到期判断),898 passed
2026-08-18 13:15:46 +08:00
sinohqb
9d87ecf736
fix(intelligent-eval): trigger OpenClaw planner for planning evals
...
CI / test (push) Successful in 3m59s
方案③只自动化了 executing(worker)→completed(analyst),缺少 planning 阶段的
planner 触发——新建/被打回的评估永远停在 planning(无任何机制唤醒
agenteval-intelligent-planner skill)。
- 新增 _has_planning_eval + _trigger_intelligent_planner:scan loop 每 60s
对 planning 状态评估触发 planner skill(产出粗计划并 PUT /plan 提交),
与 worker 触发同模式(docker exec openclaw agent -m 带'立即完成'语义)
- scan loop 在 worker 触发后追加 planner 触发
测试:+2(无 planning 不触发 / 有 planning 触发 planner skill),897 passed
2026-08-18 11:30:02 +08:00
sinohqb
cc2ac8da89
feat(intelligent-eval): paginate the eval list
...
CI / test (push) Successful in 4m5s
GET /api/intelligent-evals 支持 page/page_size(默认不传仍返回全部,向后兼容):
repository 加 count/list_page,lifecycle 加 list_evals_page,router 返回 total。
前端服务端分页:useIntelligentEvalRead 接 page/pageSize,list 存 total,
IntelligentEvals 表格 showSizeChanger + 页码切换重新加载;5s 轮询保持当前页。
测试:+3 后端分页 + hook 页码透传/总数断言,895 passed,vitest 19 passed
2026-08-17 14:09:17 +08:00
sinohqb
b4f9c887f4
feat(intelligent-eval): task queue monitor (方案③可视化)
...
CI / test (push) Successful in 4m1s
方案③的定时触发(scan loop 每 60s 入队 + 触发 worker)此前只有 Worker
消费端 API,无可查看的列表。新增:
- GET /api/intelligent-evals/tasks:任务明细(含评估名/状态)+ 状态分布统计
(注册在 /{eval_id} 之前避免被捕获为 eval_id="tasks")
- 前端 TaskQueueMonitor 组件 + 智能评估页任务队列入口:5s 轮询
(usePolling),状态卡 + 状态筛选 + 明细表
测试:+3(列表/筛选/不被 {eval_id} 遮蔽),892 passed,tsc 通过
2026-08-17 13:57:00 +08:00
sinohqb
b0969ae582
feat(intelligent-eval): backfill decision logs for completed evals
...
CI / test (push) Successful in 4m2s
COMPLETED 状态的评估(历史/异常路径)可能完全没有决策日志,
导致旧报告决策过程为空。扩展 _supplement_decision_logs 支持
COMPLETED:按时段补 execute_session + 补 start_analysis(历史回填),
scan loop 每分钟自动回填,无需一次性脚本。幂等,只补缺失类型。
2026-08-17 13:06:27 +08:00
sinohqb
32f63e80ae
style: ruff format (decision-log backfill)
CI / test (push) Failing after 36s
2026-08-17 05:12:09 +08:00
sinohqb
25920280f6
feat(intelligent-eval): platform audit backfill for decision logs + disable legacy cron workers
...
CI / test (push) Failing after 35s
- _supplement_decision_logs: executing evals missing a decision log get a
platform-derived execute_session (deficit) or start_analysis (all sessions
done) entry. Audit backfill only — records observable state, does not change
agent execution. Called each scan tick after requeue+scan.
- t480 legacy cron workers (5) disabled: superseded by platform-triggered
headless agent (plan C); they kept firing every minute and failing on
Channel-required.
2026-08-17 05:11:18 +08:00
sinohqb
71c7cd3d39
fix(intelligent-eval): requeue stale assigned tasks (worker crash recovery)
...
CI / test (push) Successful in 3m45s
方案③ worker 由平台触发 openclaw agent(cron=manual-run,非真实 cron),
fault_tolerance 的 stuck 检测不适用——agent 中断/失败时任务永久卡 assigned,
scan 只查 pending 不再入队(死锁)。
requeue_stale_assigned_tasks:assigned 超过 10 分钟且评估仍 executing 的
任务重置为 pending(清空认领),平台 scan 循环随后重新触发 worker 重试。
接入 scan loop,每轮先 requeue 再 scan。
2026-08-17 03:30:42 +08:00
sinohqb
8e65e2e7b0
fix(intelligent-eval): worker trigger message must demand immediate execution
...
CI / test (push) Successful in 3m47s
openclaw agent has no cron state; a bare 'agenteval-intelligent-worker'
message made the worker skill decide then 'wait for the next tick',
deadlocking (task assigned, session never created). The trigger message now
demands '立即完成当前任务,不要等待下一节拍' and, when all sessions are
done, delegates to agenteval-intelligent-analyst. Verified end-to-end on
t480: 1h-window eval went executing -> session (2 real turns) -> close ->
report -> completed, fully agent-driven, no external IM channel.
2026-08-17 02:57:08 +08:00
sinohqb
775b070bab
feat(intelligent-eval): platform triggers OpenClaw agent as worker (avoid external IM channel)
...
CI / test (push) Successful in 3m48s
OpenClaw cron requires a channel (announce->last fail-closed); webchat is a
Control-UI feature, not an addressable channel, and platform-side static
execution would degrade the intelligent eval into a static evaluation.
Solution (plan C): the platform keeps the scan loop and, when the queue has
a pending task, invokes the headless agent:
docker exec openclaw-eval openclaw agent --agent main \
-m agenteval-intelligent-worker --json
--deliver defaults to false, so no cron delivery channel is involved. The
worker skill runs unchanged under the OpenClaw agent (LLM decisions +
evaluator/analyst skills). Verified headless invocation returns ok.
2026-08-17 02:37:37 +08:00
sinohqb
5836b84681
fix(intelligent-eval): add lifespan scan-loop for worker task enqueue
...
CI / test (push) Successful in 3m53s
scan_and_enqueue_tasks had no scheduler: the OpenClaw Worker wakes every
minute but the platform never enqueued executing evals, so the queue was
always empty. lifespan now starts an asyncio background task that scans
executing intelligent evals every 60s (aligned with the Worker wake),
cancelled cleanly on shutdown. Verified by a new startup test (879 total).
2026-08-17 02:08:40 +08:00
sinohqb
4bcab065f1
fix(decision-logs): dedupe on (eval_id, decision_type, context) (resolves T8)
...
CI / test (push) Failing after 37s
create_decision_log now checks for an existing log with the same
(eval_id, decision_type, context) tuple before inserting. If found, it
returns the existing row's dict instead of appending a duplicate. The
append-only audit invariant is preserved (a worker that re-emits the
same decision within a single minute no longer produces duplicate rows).
Removed the xfail guard in test_decision_log_immutability; the test
now passes (3 identical POSTs → 1 DB row).
2026-08-14 15:14:05 +08:00
sinohqb
6d32653675
fix(intelligent-eval): link check_alerts to auto-scale_up (resolves T7)
...
CI / test (push) Successful in 3m56s
AlertManager gains an optional openclaw_client. check_alerts records
each newly created alert and AlertManager.maybe_autoscale (called
from the async router for each alert) invokes cron_pool.scale_up(1).
scale_up itself caps at MAX_POOL_SIZE so repeated invocations are safe.
Removed the xfail guard in test_alert_autoscale_link; rewrote the test
to use task_backlog (duration_minutes=0) so a single check_alerts call
fires an alert and triggers auto-scale.
2026-08-14 15:08:24 +08:00
sinohqb
f85eca11ca
fix(alerts): webhook retry + dedupe (resolves §6.2)
...
CI / test (push) Successful in 3m57s
_send_webhook:
- Dedupe: skip if alert.webhook_sent is already True (guards against
repeated check_alerts ticks re-sending the same alert).
- Retry: up to 3 attempts with exponential backoff (1s, 2s) before
giving up. webhook_sent=True is persisted only on success.
Two xfail guards in test_openclaw_client_and_webhook now pass (876/4 xfail).
2026-08-14 14:54:57 +08:00
sinohqb
38e3817433
fix(intelligent-eval): atomic CAS in assign_task and complete_task (resolves §6.1)
...
CI / test (push) Has been cancelled
Replace read-check-write in task_queue.assign_task with UPDATE...WHERE
status='pending' and decide on rowcount so two concurrent workers
cannot both claim the same task. Also harden complete_task with the
same CAS pattern (status='assigned') so a worker + stuck-handler
double-complete leaves the DB in one state.
The xfail guard in test_worker_task_resilience now passes (4/4).
2026-08-14 14:52:34 +08:00
sinohqb
b5bcd13fa0
test(intelligent-eval): add #6 frontend + router contract + immutability + alert-autoscale link tests
...
CI / test (push) Failing after 4m34s
T2 frontend CronPoolMonitor: polls every 5s, unmount clears interval,
plus it.fails guard for missing visibilitychange listener (S6).
T3 router ORM contract: heartbeat updates fields + 404, decision-logs
POST persists + 404, GET lists inserted (guards S2 — must continue to
pass after router handlers move into a service in P3).
T8 decision-log immutability: append-only on context change passes;
dedupe of identical (decision_type, context) is xfail (real gap).
T7 alert→auto-scale: task_backlog alert recorded on first call (passes);
check_alerts never invokes auto_scale is xfail (real gap, §6.4).
All real gaps are logged in .scratch/v111-architecture-scan.md §6.
2026-08-13 04:03:17 +08:00
sinohqb
a03067720b
test(intelligent-eval): add openclaw_client + webhook tests ( #5 )
...
CI / test (push) Successful in 4m18s
T5 OpenClawClient subprocess args: docker exec cmd + token-last placement,
cron add/rm/list params, JSON parse success + failure paths.
T6 webhook: marked sent on 2xx, failure does not raise; xfail guards expose
missing retry and missing dedupe (.scratch/v111-architecture-scan.md §6.2).
2026-08-13 02:56:32 +08:00
sinohqb
4c45dba95d
test(intelligent-eval): add cron_pool boundary tests ( #4 )
...
CI / test (push) Has been cancelled
T4 auto-scale boundary: busy/total == 0.8 (exact threshold) must not fire
T4 auto-scale oscillation: repeated flips across 0.8 must respect MIN/MAX bounds
T9 stuck-detection critical edge: strict '<' semantics at 10min threshold
T9 detect_stuck_crons ignores non-busy: idle/stuck crons excluded even if stale
2026-08-13 02:54:21 +08:00
sinohqb
3025dcd255
test(intelligent-eval): add worker task resilience tests ( #3 )
...
CI / test (push) Successful in 4m21s
T1 concurrent assign: only one worker wins (sequential + dual-session)
T1 complete×stuck convergence: task reaches terminal state, never lost
T10 fault loop: heartbeat busy → cron stuck → handler fails task + creates retry
发现真 bug(assign_task 缺原子 CAS,详见 .scratch/v111-architecture-scan.md §6.1):
两个独立 session 并发 assign 同一 task 双认领。
以 xfail(strict=False) 留守卫,CI 不阻塞;修复后移除 xfail 即转绿。
该 bug 修复不在本 #3 范围,待开独立 issue。
2026-08-13 02:45:56 +08:00
sinohqb
2e7d419f05
feat(intelligent-eval): implement monitoring and alerting (ticket 07)
...
- Add metrics.py with pool utilization, task backlog, stuck rate, avg processing time, eval completion rate
- Add alerts.py with alert rules (pool utilization > 90%, task backlog > 50, stuck rate > 10%)
- Implement alert history and webhook notifications
- Add metrics and alerts APIs
- Add database migration for alert history table
- Add 11 unit tests for metrics, 10 unit tests for alerts, 8 integration tests
- Update migration tests to include new alert history table
All 853 tests passing.
2026-08-12 10:41:15 +08:00
sinohqb
1d9228fd86
feat(intelligent-eval): implement fault tolerance and recovery (ticket 06)
...
- Add fault_tolerance.py with stuck cron detection and handling
- Implement state reconciliation (platform DB vs OpenClaw state)
- Implement platform restart recovery (requeue inactive tasks)
- Implement OpenClaw restart recovery (sync cron states)
- Add 6 unit tests and 5 integration tests
All 824 tests passing.
2026-08-12 10:30:05 +08:00
sinohqb
e6f98aaa6d
feat(intelligent-eval): implement config snapshot management (ticket 05)
...
- Add config_snapshot.py with save/list/get/compare functions
- Auto-save snapshots on eval creation and plan submission
- Implement snapshot query APIs (list, get single)
- Implement snapshot comparison API (diff two snapshots)
- Add 8 unit tests and 7 integration tests
Snapshots track config changes over time (created/plan_submitted/config_updated).
All 813 tests passing.
2026-08-12 10:19:07 +08:00