diff --git a/PROGRESS.md b/PROGRESS.md index 081dd65..0e0f3bc 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -23,6 +23,7 @@ ### 2026-07 +- **07-07 / 0.45.0**:移动端显示修复 + 对外品牌名 env——① 浮层菜单(⋯ 任务菜单 `dom.js`、⚙ 媒体模型弹层 `chat.js`)原只做右对齐,手机上触发钮靠左时菜单冲出屏幕左缘盖住正文,改成"右对齐放不下→左对齐 + 双向钳视口";手机断点补:菜单项加大触控目标、模型下拉限宽 48vw、「管理」入口统一挪到 任务/对话/文件 tabs 行右侧小按钮(embed 与普通模式同款,靠 CSS order 实现不动 DOM)、header 品牌名单行省略。② 新 env `ZCBOT_BRAND_NAME`(默认「总院科研辅助助手」,zcbot 只是内部代号):`/healthz` 返 brand 字段,前端 boot 拉取覆盖页面标题/顶栏/登录卡(静态页默认值也已改为默认品牌);微信/企微测试推送、OAuth 提示页、绑定页等用户可见文案全部改用品牌名或中性"助手",不再露 zcbot。RUN.md env 段同步。 - **07-07 / 0.44.0**:企业微信应用主页免登——企微后台「应用主页」填 `/v1/wecom/entry`,成员点开应用即静默授权(snsapi_base)登进 embed 控制台。后端两端点(entry 302 授权、callback code→userid→反查绑定→签 JWT→fragment 带 token 302 进 `dev.html?embed=1&wecom=1`),UA 分支让外部浏览器退 wwlogin 扫码;前端 wecom 变体(fragment 吃 token 即清 hash,401 回 entry 静默重签,不需要 parent_origin);未绑定成员提示先在控制台绑定(不自动建号,避免重复账号)。EMBED.md §9 + RUN.md 企微段同步。 - **07-07 / 0.43.1**:跳秒指示补两处空窗——① 刷新/重连接管后 phaseSince 随页面内存丢失,退回静态"思考中"不跳秒(恰是用户因疑似卡死而刷新的场景),重建直播卡时立即按"思考中"起跳,下一个阶段事件校正;② 发消息 POST 返回即起跳,覆盖 build_agent + 首轮 TTFT(原先要等 llm_start 才开始计时)。重连后秒数从重连时刻起算(非真实累计),可接受。 - **07-07 / 0.43.0**:run 长耗时可视化——修"前端一直静止显示思考中被当成卡死":① 新增 SSE `reasoning{delta}` 事件(loop 提取 `delta.reasoning_content`,thinking 模型分钟级推理原先整段丢弃、前端零反馈),前端渲染灰色折叠"思考过程"卡,历史消息里持久化的 reasoning_content 同款渲染;② 前端活跃状态指示:TTFT/推理期占位段每秒跳"思考中/深度思考中 · Ns"(CSS attr(data-status)),工具卡运行中加 spinner + 跳秒、结果到达定格为执行耗时;每轮 llm_start 重建占位段,工具轮之后不再空窗。 diff --git a/RUN.md b/RUN.md index f70ccaf..9e744c6 100644 --- a/RUN.md +++ b/RUN.md @@ -85,6 +85,9 @@ # 用户即可在企业微信里直接和 zcbot 对话(回调 URL = <公网 base>/v1/wecom/callback)。 # WECOM_CALLBACK_TOKEN=... # 接收消息 Token(企微后台生成) # WECOM_CALLBACK_AESKEY=... # EncodingAESKey(43 字符,企微后台生成) + # 对外品牌名:zcbot 是内部代号,所有用户可见文案(页面标题/顶栏/登录卡/微信·企微推送与 + # 提示页)统一用品牌名。/healthz 返回 brand 字段,前端 boot 拉取覆盖静态页默认值。 + # ZCBOT_BRAND_NAME=总院科研辅助助手 # 可选,默认即此值 ``` > litellm 在 import 时副作用加载 .env;入口走 `main.py`,`.env` 自动生效。直跑 `python -c "from core.storage import ..."` 不经 litellm 链路时记得自己 `import litellm` 触发,或手动 `export ZCBOT_DB_URL=...`。 - **依赖**:`pip install -r requirements.txt`(已在 `.venv` 里;含 `bcrypt`、`segno`、`cryptography`)。 diff --git a/core/__init__.py b/core/__init__.py index c4a1822..40a3f79 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -1,3 +1,3 @@ # zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。 # 改版本只动这一行。 -__version__ = "0.44.0" +__version__ = "0.45.0" diff --git a/web/app.py b/web/app.py index 1f450b2..82631f9 100644 --- a/web/app.py +++ b/web/app.py @@ -69,6 +69,10 @@ from .static_files import NoCacheStaticFiles # 读法)③ /healthz 返回,蓝绿切换时验证 nginx 已指到新实例。 INSTANCE = os.getenv("ZCBOT_INSTANCE", "").strip() +# 对外品牌名:zcbot 只是内部项目代号,所有用户可见文案(页面标题 / 推送消息 / OAuth +# 提示页)统一用这个。/healthz 也返回,前端 boot 时拉取覆盖静态页里的默认值。 +BRAND = os.getenv("ZCBOT_BRAND_NAME", "").strip() or "总院科研辅助助手" + STATUS_FILTERS = ("active", "completed", "abandoned") STATUS_WRITABLE = ("completed", "abandoned") # web 不让从 web 端切回 active(走 CLI) # 渠道镜像 task 的 channel 取值(每用户每渠道一条常驻只读对话):从普通任务列表排除, @@ -1300,7 +1304,9 @@ def create_app() -> FastAPI: @app.get("/healthz", tags=["misc"]) def healthz(): # instance:蓝绿部署时验证打到的是哪个实例(blue/green);单实例为 null - return {"status": "ok", "version": __version__, "instance": INSTANCE or None} + # brand:对外品牌名(ZCBOT_BRAND_NAME),前端 boot 拉取覆盖页面标题 / 顶栏 / 登录卡 + return {"status": "ok", "version": __version__, "instance": INSTANCE or None, + "brand": BRAND} @app.get("/WW_verify_{token}.txt", include_in_schema=False) def wecom_domain_verify(token: str): @@ -1391,7 +1397,7 @@ def create_app() -> FastAPI: """自检:给已绑用户推一条测试消息(需用户近 24h 在微信开口过)。""" from core.wechat import service as _wx res = await asyncio.to_thread( - _wx.push_clawbot, user_id, "zcbot 测试消息:绑定成功,这条来自你的 zcbot。" + _wx.push_clawbot, user_id, f"{BRAND} 测试消息:微信绑定成功,推送通道正常。" ) return {"ok": res.ok, "reason": res.reason} @@ -1404,7 +1410,7 @@ def create_app() -> FastAPI: return HTMLResponse( f"" f"