caoqianming
|
c489210b2a
|
fix(external-systems): 修复 MES 接口路径前缀
|
2026-08-04 17:28:13 +08:00 |
caoqianming
|
cb9a39f33d
|
feat(external-systems): add managed MES connections
|
2026-08-04 16:53:58 +08:00 |
caoqianming
|
20c5bffa7b
|
feat(ppt): prioritize zongyuan red template routing
|
2026-08-04 12:09:02 +08:00 |
caoqianming
|
eedaf2c1fe
|
feat(web): add compact message actions
|
2026-08-04 11:33:27 +08:00 |
caoqianming
|
8cf08c0f23
|
feat(web): widen artifact previews and refine file chips
|
2026-08-04 09:11:32 +08:00 |
caoqianming
|
0bc8c28a02
|
fix(eval): 修复依赖审计网络与缓存配置
|
2026-08-04 08:39:53 +08:00 |
caoqianming
|
137d27acdd
|
fix(security): 强化工程类型检查与依赖审计
|
2026-08-03 16:59:32 +08:00 |
caoqianming
|
cee4eb4c14
|
feat(eval): add reproducible technical benchmark
|
2026-08-03 16:10:38 +08:00 |
caoqianming
|
bc45753f77
|
feat(models): unify thinking controls
|
2026-08-03 14:36:50 +08:00 |
caoqianming
|
dfda6fd772
|
feat(image): support GPT image editing
|
2026-08-03 14:31:38 +08:00 |
caoqianming
|
57655984dd
|
feat(web): add task-scoped artifact references
|
2026-08-03 13:49:20 +08:00 |
caoqianming
|
4ec2638d38
|
feat(web): embed interactive HTML artifacts
|
2026-08-03 11:34:35 +08:00 |
caoqianming
|
328607671a
|
feat(web): preview HTML and source files
|
2026-08-03 11:16:40 +08:00 |
caoqianming
|
f217672365
|
feat(web): render Mermaid diagrams in chat
|
2026-08-03 10:26:39 +08:00 |
caoqianming
|
a00ebfe50e
|
fix(markdown): repair nested code fences
|
2026-08-03 10:11:25 +08:00 |
caoqianming
|
a8b84b1d6f
|
feat(web): allow attachments to start conversations
|
2026-08-03 09:57:21 +08:00 |
caoqianming
|
b0e0182b73
|
fix(agent): route PDF ingestion through markitdown
|
2026-08-03 09:43:57 +08:00 |
caoqianming
|
8999fb1b77
|
fix(rendering): detect LibreOffice components
|
2026-08-03 09:27:30 +08:00 |
caoqianming
|
21a90cf201
|
fix(rendering): route PDF conversion through platform tools
|
2026-08-03 08:55:54 +08:00 |
caoqianming
|
75bb482015
|
feat(media): support GPT image output controls
|
2026-07-31 17:32:15 +08:00 |
caoqianming
|
13e3e50371
|
fix(web): sort tasks by recent activity
|
2026-07-31 15:02:13 +08:00 |
caoqianming
|
cd6a76cba9
|
fix(storage): 兼容消息中的 NUL 字符
|
2026-07-31 14:43:10 +08:00 |
caoqianming
|
afdcf46577
|
feat(tasks): streamline task creation and embedded entry
|
2026-07-31 14:31:50 +08:00 |
caoqianming
|
da265b88d5
|
fix(web): open embedded task working directory
|
2026-07-31 13:54:22 +08:00 |
caoqianming
|
3c022494f5
|
fix(web): retitle cleared conversations
|
2026-07-31 13:00:34 +08:00 |
caoqianming
|
bcdbdd4738
|
Streamline conversation activity UI
|
2026-07-29 15:59:00 +08:00 |
caoqianming
|
02b278b175
|
Refine mobile conversation layout
|
2026-07-29 15:13:51 +08:00 |
caoqianming
|
369c74483c
|
Refine workspace reading and mobile layout
|
2026-07-29 14:59:10 +08:00 |
caoqianming
|
07eba5c402
|
Polish web workspace visual foundation
|
2026-07-29 14:34:46 +08:00 |
caoqianming
|
cfc1d17af7
|
优化工具失败观测与重复保护
|
2026-07-29 09:29:44 +08:00 |
caoqianming
|
6f2840a5d0
|
统一运行生命周期入口
|
2026-07-28 15:34:42 +08:00 |
caoqianming
|
7cfeebfa89
|
增强消息运行可靠性
|
2026-07-27 17:50:31 +08:00 |
caoqianming
|
70683b7d09
|
增强知识库文件写入一致性
|
2026-07-27 16:37:56 +08:00 |
caoqianming
|
ade3a847f6
|
Fix web search date handling
|
2026-07-27 12:50:07 +08:00 |
caoqianming
|
c3a6f7deee
|
Add workspace-first new conversation flow
|
2026-07-27 12:28:56 +08:00 |
caoqianming
|
85c918dc2f
|
Add safe conversational workspace rename
|
2026-07-27 11:23:20 +08:00 |
caoqianming
|
98713bb7fa
|
feat(seedance): support image-to-video references
|
2026-07-27 10:50:13 +08:00 |
caoqianming
|
e0aa8130af
|
fix(kb): 零库时注入冷启动契约,修「放进知识库」被误写进记忆
根因:kb_block 零库返回空串,agent 不知道 KB 机制存在,用户点名"知识库"
被就近理解成记忆写进 .memory/(真实用户事故)。与 memory 空契约常驻同一课。
- core/kb.py: 新增 _KB_COLD_START(建库步骤 + INDEX 行格式 + KB/记忆分工,
~百 token);kb_block 零库分支改注该契约,有库分支不变
- tests/test_kb_block.py: 锁两分支(冷启动文案/路径展示/全量 INDEX/空库)
- DESIGN.md §3.8: "有库才注入"取舍更新为冷启动注入 + 事故记录
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-24 15:31:50 +08:00 |
caoqianming
|
bcd2b90942
|
refactor(storage): 失败埋点拆出 telemetry.py + kind 契约常量化;补 wecom 加解密测试
收官三小项(架构审查残余):
- core/storage/telemetry.py:四个留痕函数(malformed/salvaged/empty/run_error,
cost 恒 0)从 usage.py 迁出——「usage=计费」心智不再被埋点污染(数据层 Top4);
kind 字符串升为常量,loop/llm_transport(写)与 toolfail(读 SQL)两侧共用
同一事实源,此前靠字面量约定、改名会静默漏读。core.storage.__init__ 转发
出口不变,调用面仅 web/runs.py 一处改 import
- tests/test_wecom_crypto.py:7 用例,企微回调加解密(WXBizMsgCrypt 等价实现)
测试侧按同方案自造密文,覆盖验签/receiveid/padding 各失败路径——wechat 子系统
(审查 Top3 零测试)中唯一可纯测的一块补上
- DB 测试探针补 connect_timeout=5:测试库挂掉时快速降级 skip,不再把整个
discovery 挂死在 TCP 建连上(Docker engine 打嗝时实测挂死过)
带测试库 351 全过 / 无测试库 341 过(DB 组干净 skip)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 14:21:45 +08:00 |
caoqianming
|
fd79edb344
|
test(web): DB 面路由测试(tasks CRUD/files DB-aware/upload)+ 修 restore 500
测试库基建落地(docker postgres:16-alpine @5433 + migration 0001-0022,
RUN.md 补一键命令),tests/test_web_routes_db.py 10 用例补齐 nodb 套件留待面:
- tasks CRUD 全链:建(默认模型/working_dir)/列(分页壳)/详(上下文压力
字段)/PATCH 校验/软删→列表消失→恢复/同 wd 共享 + folders 计数
- files 顶层目录 DB-aware(§7.4):rename 级联改 tasks.working_dir(tasks_
updated=1 且 DB 生效)、running→409、move 被引用→409、递归删被引用→409、
软删 task 后放行
- upload 配额 gate 路径 + 根目录列表(system_wd_names)+ 非法文件名 400
- clear/cancel 状态闸、models 档位列表、schedules 404 路径
修 bug(本套件抓出的存量缺陷,重构前即有):POST /v1/tasks/{id}/restore
用 ORM 脏标记恢复,updated_at 是 server-side onupdate,flush 后列被标记
expired,session 关闭后序列化读它抛 DetachedInstanceError——真软删过的
任务恢复必 500(幂等路径无脏标记故此前未暴露)。修法:flush+refresh 后
在 session 内完成 task_dict 序列化。
带测试库全量 344 全过;未设 ZCBOT_TEST_DB_URL 时干净 skip;测试库零残留。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 13:50:57 +08:00 |
caoqianming
|
0d34141527
|
test(web): 路由级测试首批(无 DB 面)——鉴权门全覆盖 + kb/skills/memory/files FS 路径
拆分 router 后的接线回归(审查 Top1 风险面此前零路由测试):
- 公开端点:/healthz、/v1/changelog(limit clamp)、/ 302
- 鉴权门:11 个 router 的 19 个代表端点无 token 一律 401(哪个模块漏挂
Depends(require_user) 当场红);坏 token 401、坏 platform_key 403、
user_id 非法 400(落库之前拦下)
- FS 类业务:kb 建/详/删/非法名、skills 列/详/内置不可删、memory 只读+穿越
404、files 子目录列/下载/越界 400/非顶层改名/拷贝 409 预检/删文件/非空目录 400
- 隔离:JWT 与 app 同源 env 直签(不假设 key 值,兼容 litellm dotenv 抢先加载);
随机 user_id 子树 teardown 整树删;TestClient 不进 with(不跑 lifespan 不碰 DB)
- 顶层目录 DB-aware 分支与 upload 配额留给 ZCBOT_TEST_DB_URL 套件
334 测试全过。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 13:34:07 +08:00 |
caoqianming
|
035aec44ac
|
test(rendering): golden 基线——四 profile 渲染富 fixture,docx XML 逐字节对账
给 md 解析路径的后续重构上硬闸(§8.6 当年"前后字节一致"验收的固化):
- fixture 覆盖信息带/TL;DR 卡/判断 callout/blockquote/表格/代码块(含 mermaid
回退)/缺图占位/四类列表/参考文献 DOI·URL 条目/相邻引文上标/化学式/软换行
并合/refs 段外 [n] 行等全部分支
- 对账面 word/document.xml + footer*.xml(无时间戳,确定性已验证:连续两次
渲染逐字节一致);core.xml 元数据刻意不比
- 5 份 golden(brief 彩/黑白、paper zh、proposal、report+toc);有意变更走
ZCBOT_REGEN_GOLDENS=1 重生成并在 commit 里说明,重构类改动必须零 diff
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 13:24:26 +08:00 |
caoqianming
|
5a5ebfbe24
|
refactor(tools): 输出处理原语移出 base.py——base 只留 Tool 基类与路径边界
compact_tool_output / format_timeout_result 是「工具输出处理」关注点,与
Tool ABC / FileOutOfBounds 路径安全混装在 base.py(审查小项)。析出
tools/output.py,8 处引用(5 工具 + executor_docker + 2 测试)同步改。
318 测试全过。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 13:15:04 +08:00 |
caoqianming
|
8038fb7491
|
refactor(tools): 媒体工具同构析出 tools/media_common.py + 17 个单测
审查 P1#6:seedance/seedream/gpt_image/look_at_image/read_document 五处
同构(逐字或参数化后逐字)收敛为共享原语:
- quota_gate(每日配额闸,文案逐字保持)/ stamped_path(<ts>-<rand6> 落盘
命名+建目录)/ write_meta(.meta.json)/ record_usage_safe(记账失败不
阻塞)/ ark_chat_with_retry(超时透明重试,业务错误不重试)/
extract_chat_answer(chat 文本+截断标志)/ find_first_url(递归找 URL,
accept 谓词覆盖 seedance 的 video_url 优先语义)
- 五工具各自的 banner 格式 / body 组装 / seedance 轮询刻意保持不动
- tests/test_media_common.py:17 个纯函数/打桩单测(配额文案、重试次序、
业务错误不重试、视频 URL 谓词等)
318 测试全过;真实配置冒烟 32 工具挂载不变、schema 完整。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 13:10:32 +08:00 |
caoqianming
|
7568ceeb48
|
test(scheduler): 补 core/scheduler 服务层测试(审查 Top3 缺口)+ DB 测试门控收紧
- tests/test_scheduler.py:纯逻辑(cron 校验/next_run 墙钟时区折算/run message
包装)+ DB 级(create 校验、claim 推进 next_run 不重复认领、disabled/软删/
过期不认领、连续失败自动停用、skipped 不动计数)。认领类用例统一用 2000 年
纪元时间,claim_due_jobs(now=纪元) 只可能命中测试 job,永不触碰真实 job
- **DB 测试门控收紧(test_scheduler + test_usage_report)**:只认显式
ZCBOT_TEST_DB_URL,绝不回退 .env 的 ZCBOT_DB_URL —— 实锤教训:.env 的 URL
经隧道指向生产库,测试插入的到点 job 被生产 green 实例调度守护认领并真跑了
agent(4 次一句话迷你调用,费用几厘,产物已按测试专属 user 全量清理,零残留)
- RUN.md:环境段补 ZCBOT_TEST_DB_URL 说明,故障兜底表加一行
301 测试全过(未设测试库时 DB 组自动 skip)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 13:00:13 +08:00 |
caoqianming
|
cac0bfcfe4
|
refactor(core): loop.py 传输健壮性层析出 llm_transport.py + _execute_tool_call 拆分
架构审查 P1#4:loop.py 把「provider wire 层瞬态故障自愈」与「agent 控制流」
塞在同一文件;_execute_tool_call 一个函数线性堆 10 个关注点(148 行)。
- 新增 core/llm_transport.py(438 行):畸形/必填 key 被吞/空响应检测、三类
故障留痕、usage/delta 提取、robust_stream 重试策略(首败降级非流式 +
salvage 可救当轮续)。取流两路径与 salvage 以 callable 注入——不 import
loop,单测在 AgentLoop 实例上打桩 _collect_stream_once/_nonstream_once
的现有缝隙原样保留
- loop.py 1158→812 行,回归 ReAct 主干:_stream_llm 只留上下文压缩准备
(context 关注点),wire 健壮性委托 robust_stream;_collect_stream_once/
_nonstream_once/_try_salvage_response 留在 loop(持 llm/emit 态 + 测试缝)
- _execute_tool_call 148 行拆为编排 + 4 个正交方法:_check_repeat_block
(两道拦截)/_maybe_skill_model_switch(热切)/_repeat_feedback(登记+
软提示)/_maybe_pptx_guard(产物机检)
- 4 个测试文件 import 指向同步更新(is_empty_response 等改公有名)
292 测试全过(loop 重试/空响应/repeat-guard/salvage 套件覆盖改动路径)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 12:44:22 +08:00 |
caoqianming
|
7354578aaa
|
refactor(storage): 计费读侧收口 core/storage/usage_report.py + 首批 DB 级测试
风险点(架构审查 P0#2):UsageEvent.units JSONB 的 key 由 usage.py 写入,
读侧 cast(units[...].astext) 却散在 web/admin.py 与 web 各处硬编码——写读
跨文件隐式耦合且零测试,改 key 会静默算错计费统计。
- 新增 core/storage/usage_report.py:units 读侧唯一出口(列表达式单一事实
源),含 task_usage_aggregates(逐 task 批量)/ usage_overview(全局+7d
趋势)/ models_usage(按模型)/ user_usage_page(按用户分页)
- web/admin.py 三个内联聚合函数删除,改调 usage_report;web 层不再出现
任何 JSONB cast(grep 已核)
- web/common.usage_aggregates 移除,tasks/schedules 路由改引 core 版
- tests/test_usage_report.py:6 个 DB 级测试锁口径(cost 全 kind 合计、
token/cache_hit 仅 chat、task_id 可空的 kb_ingest 不进 task 聚合、cutoff
过滤、用户分页含档案字段)。无 PG 自动 skip;只插/删测试专属 user 的行。
发现并记录:ZCBOT_DB_URL 平时靠 import litellm 的隐式 dotenv 进 env,
测试显式从 .env 抠 key 不背 8s 重依赖。
292 测试全过,测试数据零残留。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 10:33:13 +08:00 |
caoqianming
|
25d8a6572f
|
refactor(web): app.py 拆分——73 路由迁 11 个 router 模块,3972 行减至 732
照 admin.py 的 register_*_routes 注册范式把 create_app 巨型闭包拆开,
依赖(require_user/auth_cfg)显式传参,对外 /v1 契约零变化:
- web/routers/:misc/models/authroutes/wechat(含企微)/kb/schedules/
skills_memory/files/asr/tasks/messages 共 11 个模块
- web/common.py:跨 router 常量与 helper(task_dict/usage_aggregates/
sse_event/assert_owns_task 等)
- web/schemas.py:13 个 Pydantic 请求模型独立成文件
- web/model_gate.py:模型档位门控 + image/video variant 解析
- web/runs.py:run_agent_bg + run_channel_conversation(BG worker 与
渠道入站对话核心,从 app.py 模块级函数析出)
- web/userfiles.py:路径安全原语(safe_join 越界校验/transfer 预检)收口
- app.py 只剩 App 工厂 + lifespan 后台协程群
验证:286 测试全过;路由面 81 条逐条一致;TestClient 冒烟
(healthz 200/坏 platform_key 403/未鉴权 401/lifespan 正常启动)。
test_changelog/test_pptx_render 的 import 指向同步更新。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-23 10:18:57 +08:00 |
caoqianming
|
fb214de960
|
fix(context): 窗口体量估算实测校准——50%压缩/85%折叠/占用环换 token 实测口径(bump 0.58.52)
diag 实测(scripts/diag_context_pressure.py 留仓):折叠机制有效、零撞硬上限,
但静态 CHARS_PER_TOKEN=2.5 对中文密集窗口低估近一倍——名义 85% 折叠线实际
~155% reliable 才触发(task 9a863424 冲到 40.7 万 tokens);代码密集反向虚高
(fe2d8b73 估 1.2M 实际 616k)。
修法是信号校准、不加新机制:
- context.py: estimate_window_tokens(provider 实报 usage 覆盖窗口主体,仅实测
点后尾巴按 2.5 估)+ calibrated_chars_per_token(比值夹 [1.0,4.0] 带宽)
- session.py: last_measured_usage() 取窗口内最后一条实报 usage 的 assistant 行
(best-effort 绝不抛;idx→内存 pos 映射校验 role)
- context_fold.py: maybe_fold 触发判定换 token 实测口径
- loop.py: 压缩门槛与 context_limit_chars(前端环)用校准比值,逐轮以
sent_chars/prompt_tokens 刷新;校准态挪类属性兜默认,任何异常回退 2.5
已知残余:折叠后 run 在首次 chat 完成前崩掉会多折一次(摘要偏保守,原文全在
DB),不为此加持久化状态。run 中途折叠/超限自愈按 §5 无信号不实施继续搁置。
真实生产 task 只读验证映射与校准(drift 0.95x/0.51x/0.86x),286 测试全绿。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-21 12:49:02 +08:00 |
caoqianming
|
f535dbaa9a
|
fix(llm,loop): glm.pro52 空响应治本——禁 thinking 免推理烧穿输出上限 + loop 区分截断(bump 0.58.49)
失败面板 empty_response 簇 2026-07 主角 glm.pro52。探针 + DB + 代码三重定层根因链:
1. caps.max_output 是全仓死字段(只在 capabilities.py 定义,_build_kwargs 从不作为
max_tokens 发出)→ 网关放任 glm-5.2 跑到自带 65536 输出硬上限;
2. glm-5.2 thinking 网关侧默认开(线上探针实测 reasoning_content=766>0,尽管 config
thinking_mode:false —— 那开关是 glm.yaml 未做的 TODO,根本没透传);
3. 重任务(100k 上下文)上思考膨胀烧满 65536 被截断(finish_reason=length)、content 空
→ loop 判空响应整轮丢弃 + 同上下文无效重试(task 35744bea:5 次 empty 全
tokens_out=65536,事件4=attempt2)。单任务烧 ~327k 输出 token。
与 opus48/deepseek 的网关 wire bug 不同根 —— 这是我方 max_output 死 + 未约束推理模型。
修(禁 thinking + loop 健壮化):
- core/llm.py _build_kwargs 加 family=="glm" 分支,据 thinking_mode 透传
extra_body={"thinking":{"type":"enabled|disabled"}}(GLM body 级协议,与 OpenAI 的
reasoning_effort 不同族;litellm zai provider 转发 extra_body)。当前 glm 档均 false=disabled。
线上探针 A/B 实测:disabled 后 reasoning_content 766->0、正文/工具照常。
- core/loop.py 加 _finish_reason,空响应路径区分 length(截断,我方预算烧穿,重试无效)与
wire 吐空,warn 措辞据实;record_empty_response units 记 finish_reason(JSON 免 migration)。
- 修既坏的 test_loop_empty_response(mock 缺 executor)+ 补截断措辞用例,61 测试全绿。
- 探针 diag_glm_empty_probe.py 加 monkeypatch 绕沙箱池 + PROBE_THINKING_OFF A/B 开关。
行为变化(知情):glm.pro52 用户现在拿禁思考的 glm-5.2(config 本就 thinking_mode:false)——
不再卡壳/空转,代价是硬任务少了推理链。遗留:max_output 对所有模型仍未生效(本次没盲发
max_tokens,怕截断大 write 的 args),需逐档评估安全值后另做。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-21 08:16:54 +08:00 |