caoqianming
|
25616d12cc
|
refactor(software): introduce capability contracts
|
2026-08-14 12:55:46 +08:00 |
caoqianming
|
b929cee832
|
fix(windows-node): 收敛结果上传状态并补充诊断日志
|
2026-08-14 11:15:54 +08:00 |
caoqianming
|
13ba6b1a61
|
feat(software): add local monitoring and multi-artifact jobs
|
2026-08-14 10:41:49 +08:00 |
caoqianming
|
51a213e3a7
|
fix(software): normalize job output artifacts
|
2026-08-14 08:57:36 +08:00 |
caoqianming
|
40f8899cc1
|
feat(software): require artifact inputs for Origin jobs
|
2026-08-13 17:25:21 +08:00 |
caoqianming
|
e6128c7e5b
|
build(windows-node): add batch deployment workflow
|
2026-08-13 17:00:40 +08:00 |
caoqianming
|
8aafe3272f
|
feat(software): add professional software job center
|
2026-08-13 15:59:31 +08:00 |
caoqianming
|
ded8cba54c
|
refactor(software): rename Windows execution domain
|
2026-08-13 15:28:04 +08:00 |
caoqianming
|
3e0a719f80
|
feat(compute): complete Origin job execution pipeline
|
2026-08-13 14:39:36 +08:00 |
caoqianming
|
faa2279f00
|
docs(release): separate development pushes from releases
|
2026-08-13 13:55:47 +08:00 |
caoqianming
|
054aaf8e8c
|
feat(chat): 结构化用户附件并支持图片预览
|
2026-08-13 10:32:08 +08:00 |
caoqianming
|
b555059bc4
|
feat(admin): manage Windows compute nodes
|
2026-08-12 17:17:02 +08:00 |
caoqianming
|
fac4e5fa0a
|
feat(compute): add Windows Node desktop client
|
2026-08-12 16:57:06 +08:00 |
caoqianming
|
109d395356
|
feat(compute): 实现 Windows Node 注册与心跳
|
2026-08-12 15:56:28 +08:00 |
caoqianming
|
1ac9aa1ba0
|
fix(files): prevent silent upload overwrites
|
2026-08-12 14:13:42 +08:00 |
caoqianming
|
6b37ce141f
|
perf(storage): optimize database hot paths
|
2026-08-12 13:54:40 +08:00 |
caoqianming
|
4932f00e90
|
feat(artifacts): add lifecycle tracking and trash
|
2026-08-12 12:44:28 +08:00 |
caoqianming
|
2b4316ed25
|
refactor(external-systems)!: 统一为通用 API provider
移除 factory_mes preset 和兼容包装,新增存量 definition 一次性迁移脚本,并让 OpenAPI 参数直接遵循规格约束。
BREAKING CHANGE: 管理 API 不再接受 factory_mes provider,部署新版前必须先执行 definition 迁移脚本。
|
2026-08-10 17:26:39 +08:00 |
caoqianming
|
44b7df6f20
|
feat(external-systems): add generic MCP connector
|
2026-08-10 16:04:51 +08:00 |
caoqianming
|
8d741e4141
|
fix(preview): support document previews in app webviews
|
2026-08-10 08:55:44 +08:00 |
caoqianming
|
9032c5b517
|
fix(external-systems): preserve credentials on definition updates
|
2026-08-07 11:25:29 +08:00 |
caoqianming
|
0e4bd0456a
|
feat(external-systems): 重构连接治理与运行态缓存
|
2026-08-07 10:12:37 +08:00 |
caoqianming
|
02e7d2cb14
|
feat(files): create folders from file panel
|
2026-08-06 15:04:15 +08:00 |
caoqianming
|
7e544827c0
|
feat(files): toggle task hidden directories
|
2026-08-06 12:05:36 +08:00 |
caoqianming
|
80fbc7ab4a
|
feat(external-systems): support generic OpenAPI integrations
|
2026-08-05 17:18:29 +08:00 |
caoqianming
|
af0ad934bb
|
feat(external-systems): guide MES aggregate queries
|
2026-08-05 15:01:43 +08:00 |
caoqianming
|
cb9a39f33d
|
feat(external-systems): add managed MES connections
|
2026-08-04 16:53:58 +08:00 |
caoqianming
|
cee4eb4c14
|
feat(eval): add reproducible technical benchmark
|
2026-08-03 16:10:38 +08:00 |
caoqianming
|
57655984dd
|
feat(web): add task-scoped artifact references
|
2026-08-03 13:49:20 +08:00 |
caoqianming
|
8999fb1b77
|
fix(rendering): detect LibreOffice components
|
2026-08-03 09:27:30 +08:00 |
caoqianming
|
13e3e50371
|
fix(web): sort tasks by recent activity
|
2026-07-31 15:02:13 +08:00 |
caoqianming
|
afdcf46577
|
feat(tasks): streamline task creation and embedded entry
|
2026-07-31 14:31:50 +08:00 |
caoqianming
|
cfc1d17af7
|
优化工具失败观测与重复保护
|
2026-07-29 09:29:44 +08:00 |
caoqianming
|
98713bb7fa
|
feat(seedance): support image-to-video references
|
2026-07-27 10:50:13 +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
|
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
|
f7e5a80ed9
|
feat(auth): JWT 滑动续签——活跃用户临期无感换 token,不再因 7d TTL 掉线(bump 0.58.39)
原状:无状态 HS256 JWT(默 7d TTL)无任何续签路径,过期即 401——platform 靠
PLATFORM_KEY 自行重换,SPA 用户只能重输密码。判断:平台层握长期 PLATFORM_KEY、
login 本就幂等换发,缺的不是 refresh token 而是"无感重换"这层;放鉴权中间件一次
改动同时惠及 platform 层与 SPA,且纯加法契约。
- web/auth.py:AuthConfig 加 refresh_threshold_seconds(env
ZCBOT_JWT_REFRESH_THRESHOLD_SECONDS,默 TTL 的 1/4,设 0 关闭);verify_token
拆出 decode_token+_uid_from_payload;require_user/admin 共用 _authenticate,
注入 Response,临期就地 mint 新 token 放响应头 X-Refreshed-Token /
X-Token-Expires-At(仅续未过期的,已过期先抛 401)
- web/app.py:CORS 加 expose_headers 放行两头,否则浏览器 fetch 读不到
- web/static/js/api.js:中央 api() 封装 absorbRefreshedToken——任一响应带新
token 就无感换 state.token+localStorage
- 验证:4 case 全绿(fresh 不续/临期续且 exp 正确延长/已过期仍 401/阈值 0 关闭)
顺带:EMBED.md 收敛为纯 platform iframe 对接文档——删企业微信免登 §9(实质併入
RUN.md 企微段「应用主页免登」的内部链路)、校准 §3 换 token 返回体过期字段、补
滑动续签说明;新 env 进 RUN.md、用户可感知条目进 CHANGELOG。
additive,不改字段语义/URL/DB schema;WS ASR 路径 verify_token 签名不变。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-18 10:21:35 +08:00 |
caoqianming
|
859c02cf65
|
feat(ops+web): run 级错误持久提示+失败聚集+provider 致命错误即时告警(bump 0.58.21)
反 2a1bc25d 教训(Zai 余额不足连挂 3 次续跑,前端零提示、admin 零感知):
- chat.js: renderPersistedRunError 挂 renderMessages 末尾——run_status=error
且无 live run 时消息流末尾补「上次运行出错」持久卡(live 错误卡被收尾
loadMessages 整屏重建冲掉是"发了继续啥也没发生"的根因);下次 run 起跑
后端清 run_error 自然消失
- usage.py: record_run_error(kind=run_error, cost 0)——tasks.run_error 只留
最后一次,此行才是聚合的完整数据源;app.py _run_agent_bg except 落库
- toolfail.py: 第三段扫描聚成 kind=run / tool=(run),admin 面板+巡检邮件
零改动带上;alert_provider_critical 余额/配额/认证关键词命中即时邮件
ZCBOT_DEVELOPER_EMAIL(同签名 6h 进程内冷却,全路径静默失败)
- tests/test_toolfail_malformed.py +3 用例;PROGRESS/CHANGELOG/RUN 同步
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-13 14:06:29 +08:00 |
caoqianming
|
da289b2ce2
|
feat(ops): 畸形 tool_call 进工具失败聚集 + 巡检邮件只发活跃聚集(bump 0.58.19)
畸形轮整轮丢弃、messages 无痕,admin「工具失败聚集」原本看不见这类失败
(toolfail 只扫 role=tool 报错);且巡检邮件去重集是内存态,每次部署清零,
高频部署期每次重启都把 7 天窗口内早已安静的存量聚集重发一遍。
- 新增 record_malformed_tool_call:丢弃畸形轮时写 usage_events 一行
kind=tool_malformed(units={tool,len,err,head,tail,tokens_in/out}),
cost_cny 恒 0 —— cost 全 kind 合计且随任务展示,provider 抖动不算用户
花销;真实 token 快照进 units 供反推浪费。DB 写失败静默不阻塞重试
- core/toolfail.py 加第二段扫描(usage_events kind=tool_malformed),聚成
kind=malformed 同构 cluster,admin 面板/巡检邮件零改动自动带上;聚合
逻辑抽 _add 闭包双数据源复用
- 巡检邮件发信前加 count_24h>0 过滤:已安静的聚集重启后不再重发,还在
烧的重启后再提醒一次(刻意保留)
- 新增 tests/test_toolfail_malformed.py 4 用例(mock session_scope);
RUN.md env 巡检段 + 故障兜底同步;PROGRESS 更新
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-13 12:04:22 +08:00 |
caoqianming
|
3c714b34c4
|
fix(loop): 畸形 tool_call 首败即降级非流式 + 损坏原文留痕(bump 0.58.18)
task 716ed3be 实测:deepseek-v4-pro 大参数中文 write(3~4k 字符)流式重 roll
同轮连挂 3 次全畸形,失败强相关而非独立随机,每章拖 3 分钟+,最后总靠非流式
兜底救场,3 次流式重试纯烧 token。
- _MAX_MALFORMED_RETRIES=3(3 流式+1 非流式)→ _MAX_MALFORMED_ATTEMPTS=3
(1 流式+2 非流式),首败即降级;修掉旧 warn 计数可显示 "4/3" 的 off-by-one
- 新增 _log_malformed_args:丢弃前把损坏 arguments 首尾各 300 字符(ascii()
转义)+ JSON 报错位置打 stdout [malformed] 标签 —— 畸形轮不入库,这是唯一
留痕,供定性 provider delta 错位 vs 本地拼接 bug 及报 case 取证
- 新增 tests/test_loop_malformed_retry.py 4 用例;RUN.md 故障兜底同步
(v4-pro 也中招 + [malformed] 取证口径);CHANGELOG/PROGRESS 更新
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-13 11:02:27 +08:00 |
caoqianming
|
62bfb07312
|
feat(ops): 工具失败聚集巡检,同签名报错自动冒头(bump 0.58.11)
反 9dcae061 结构性缺口(mmdc 挂 90 天 0 成功无人知,靠人工扫 DB 才发现):
- core/toolfail.py:扫近 7 天 role=tool 错误([Error/timeout/exit!=0]),
按 工具名+归一化签名(路径/数字/uuid 抹平) 聚合,>=5 次且跨 >=2 task 判聚集
- web/app.py _toolfail_scanner:每天跑(仿 _disk_scanner),聚集发
ZCBOT_DEVELOPER_EMAIL(复用 SMTP_*,未配则日志);签名进程内去重
- GET /v1/admin/tool-failures + admin 页"工具失败"表(低阈值看全量)
生产 DB 冒烟:一次扫出 8 类真聚集(沙箱缺 file 命令 x13 跨 13 task、
web_fetch 断网 x7、mmdc 超时批次 x6 等)。无新表无 migration。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-13 08:36:31 +08:00 |
caoqianming
|
73d07c9560
|
fix(sandbox): init.sh 放行容器自身 loopback,mermaid 渲染真·终案(bump 0.58.10)
90 天 67 次 timeout 真凶:127.0.0.0/8 DROP 掐死 puppeteer 连 chromium 的
127.0.0.1 DevTools WebSocket(SYN DROP -> TCP 重试 ~127s,恒定 2m15s 超时
+ [object Object] + 零 CPU)。容器 127.0.0.1 是自己 netns 的 lo、到不了宿主,
DROP 无安全收益纯误伤。apply_blocklist 首条 -o lo ACCEPT(v6 同款),
127.0.0.11:53 豁免收编,127/8 与 ::1 DROP 降为 belt-and-suspenders。
服务器全款复刻容器实测:放行前小图也挂 2m14s;放行后小图 3.9s、
真实大图 -w 2800 -s 2 仅 5.2s(1 vCPU 渲大图慢亦为误判)。
之前 probe 全因 --entrypoint bash 绕过 init.sh 无 iptables 而全绿误判。
生效:镜像重建(init.sh COPY 层秒过)+ 回收存量容器。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-12 10:40:48 +08:00 |
caoqianming
|
d7add3926c
|
fix(sandbox): mermaid 渲染必崩定案:chromium 坏点版本;refresh 旋钮 + build canary 根治(bump 0.58.8)
9dcae061 三轮排查收官。真凶 = 7-08 镜像重建时 apt 烤进的 chromium 点版本
150.0.7871.46 自带启动即崩 bug(int3 自杀、零日志、strace 无失败 syscall;
上游 .100 已修,容器内 --only-upgrade chromium 实测复活出图)。被洗清的:
hardening 六件套 / seccomp / AppArmor / overcommit / ulimit / max_map_count /
QEMU EPYC vCPU / 镜像环境(纯净 trixie 对照 rc=0 反转定位)。
修复:
- Dockerfile ARG CHROMIUM_REFRESH cache-bust 旋钮:chromium 出问题改日期
重建,只刷 chromium 层,pip 大层不动
- Dockerfile build 末尾渲染 canary:真渲一张中文最小图,chromium/字体链坏
则 build 当场失败(有它 7-08 就不会把坏版本带上线)
- RUN.md 故障兜底条目改写最终版(两根因 + 判别特征);CHANGELOG 面向用户记
部署:服务器重建镜像(新 ARG 自然打穿 chromium 层 cache)+ 回收存量容器。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-11 12:19:31 +08:00 |
caoqianming
|
6c3122eb4b
|
feat(sandbox): chromium 秒崩第二根因 bisect 探针(bump 0.58.4)
pids-limit 1024 部署后复测(task 9dcae061,green 实例全新容器):mmdc 仍
首调秒崩 "Failed to launch the browser process: Code: null" —— 排除 pids
打满,第二根因在 hardening flag × chromium 150(trixie)交互。
新 deploy/sandbox/probe_chromium_bisect.sh:线上 docker run 全款 hardening
逐 flag 开关(no-new-privileges / read-only / cap-drop / mem·cpu /
seccomp=unconfined),每 case 跑 mmdc + 裸 chromium 两条,--user zcbot +
HOME=/tmp 忠实复现 exec 路径,尾部带判读表。RUN.md 故障兜底条目同步。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-11 09:35:10 +08:00 |
caoqianming
|
38f6157b3a
|
fix(sandbox): pids-limit 256→1024 修容器内 mermaid 渲染必崩(bump 0.58.2)
task 9dcae061 排查:近 90 天 mmdc 渲图 0 成功(26 launch fail + 67 timeout)。
根因:--pids-limit 线程也计数,chromium headless 一次 ~150-200 线程,叠加
shell 超时残留的 mmdc+chromium 树(超时只杀 host 侧 docker CLI),256 打满
→ pthread_create EAGAIN(06-23 c4f03d56 实锤)→ chromium SIGTRAP。
dbus 报错是干扰项(成功时也打)。
- agent.yaml sandbox.pids_limit + pool.py DEFAULT_PIDS_LIMIT 两处 256→1024
- RUN.md 故障兜底补条目;PROGRESS 记录
- 附诊断脚本 scripts/diag_task_9dcae061.py / diag_mmdc_history2.py / diag_mmdc_ok_case.py
- 待服务器验证:重启 web + 容器回收后跑 probe_mermaid.sh;若 chromium 150
仍秒崩另查宿主 docker/seccomp;彻底修法是 Step 3b PGID kill 协议(未动)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-11 09:02:45 +08:00 |
caoqianming
|
86f50ff133
|
feat(models): unifyllm 再加 gpt-5.5 / gpt-5.4-mini 进 pro 档(bump 0.58.1)
- config/models/unifyllm.yaml 新增 gpt55 / gpt54_mini variant(照 gpt56_sol
模板,temp 硬约束 1.0;mini 档 quality 记 good、max_iterations 100)
- agent.yaml model_tiers.pro 加 2 条
- diag_unifyllm.py 默认冒烟清单 5→7 个模型(RUN.md 同步),两模型
tool-calling 实测均过
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-10 21:06:37 +08:00 |
caoqianming
|
5a8f5bd930
|
feat(media): 第二图像后端 gpt_image(unifyllm 网关,pro 档)(bump 0.58.0)
- config/media/unifyllm.yaml + tools/gpt_image.py:仅 prompt 参数(网关忽略
size/quality,尺寸上游自动定,不支持 i2i),b64 直落 figures/,banner 协议
同 seedream,价目未知期 cost 记 0、usage tokens 进 units 留对账
- 媒体装配泛化:ArkConfig 通用键名(api_key_env/base_url,ark_* 兜底);
_choose_image_variant 跨 provider 选 image variant(默认仍 seedream_5,
本 run 只挂一个图像工具);_MEDIA_TOOLS_BLOCK 拆分段按实挂工具拼装
- web:_list_media_variants 扫 config/media/*.yaml(image/video 清单 +
admin 门控 catalog);media.js 三处白名单加 gpt_image;prompt 润色 hint
无 default_size 不再谎报 2048
- gpt_image 进 pro 档,与 seedream 共享 images_per_day 配额
- 手工验证 scripts/test_gpt_image_manual.py 全过(含真调网关落图),
unittest 201 过
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-10 20:47:06 +08:00 |
caoqianming
|
ba2afa9e98
|
feat(models): unifyllm 网关接入,5 个国际旗舰模型进 pro 档(bump 0.57.0)
- config/models/unifyllm.yaml:Claude Fable 5 / Opus 4.8 / Sonnet 4.6 /
GPT-5.6 Sol / Gemini 3.1 Pro,litellm openai/ 前缀 + api_base 覆盖,零代码
- 实测:gpt-5.x litellm 硬拦 temp!=1、gemini-3.1-pro temp=0.3 返回空,
两者 optimal_temperature=1.0;流式+tool calling+parallel 5 模型全通
- scripts/diag_unifyllm.py 冒烟脚本(--stream/--temp)
- 服务器需代理出口(直连 unifyllm.ai TLS 失败),RUN.md env 段已注明
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-10 17:16:46 +08:00 |
caoqianming
|
daf0db854a
|
feat(procs): 后台进程 bg proc + 对话锁/完成通知 + seedance 续查(bump 0.56.0)
- shell/run_python 加 background=true(模型判断,>~1min 走后台):进程 detach 独立运行,
不受工具超时/服务重启/蓝绿切换影响;新 check_process 工具查状态/日志尾部/终止
- 状态协议纯文件(<user_root>/.zcbot_procs/<task>/<proc>/,exit_code 出现即终态,
无 DB 无队列组件):host=stdlib wrapper detach(限时+杀树+日志截尾 10MB);
docker=专用容器 zcbot-proc-*(同款硬化+iptables,product=proc 与 sandbox
reaper/shutdown_all 生命周期解耦);web lifespan 每小时 sweep(7d TTL+孤儿容器)
- web:GET /v1/procs(用户级)+ POST /v1/tasks/{id}/procs/{pid}/kill;前端
[Background] 工具卡活化(spinner/跳秒/停止,历史重渲恢复)+ 完成 toast(跨 task
可跳转)+ 对话锁(bgproc 运行期 composer 发送→停止/Enter 拦截,先锁后放消
刷新时序窗口;润色/语音与 streaming 期一致可用)
- seedance:resume_task_id 续查(轮询超时/中断后取回结果,跳过提交不重复计费),
fast/pro poll_timeout 统一 1200s;取消/超时文案引导续查
- core/llm.py:litellm timeout 显式化(默认 600s 不变,ZCBOT_LLM_TIMEOUT_S 可调)
- DESIGN 新增 §8.12(含边界:不做 job 链/自动续跑/不引 Celery);RUN/PROGRESS/
CHANGELOG 同步;scripts/test_bgproc_manual.py 手工验证;unittest 全量 201 过
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-10 16:47:11 +08:00 |
caoqianming
|
9e59cf9e44
|
chore(quota): per-user 磁盘配额 5GB -> 20GB(bump 0.55.1)
应用层软配额上调(agent.yaml quotas.disk_bytes_per_user,重启 web 生效);
RUN 故障兜底行 + CHANGELOG 用户条目同步。OS 层 prjquota 仍留待外部开放前。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-10 08:35:52 +08:00 |