diff --git a/CHANGELOG.md b/CHANGELOG.md index 840c1e1..cbe8fe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ > 所以不是每个版本号都有条目。条目格式 `## <版本> — <日期>`,新条目加在最上面。 > 工程口径的完整记录见 `PROGRESS.md` / git log。 +## 0.59.2 — 2026-07-23 + +- 手机端也能发文件了:对话输入框下新增「📎 附件」按钮,点开可拍照、从相册选照片 / 视频、或选取文件,上传后随消息一起发给助手;电脑端点击直接打开文件选择器(原有的粘贴 / 拖拽方式照旧)。 + ## 0.59.0 — 2026-07-22 - 新增「个人知识库」:左下角新入口,可以建多个库(如「行业标准」「项目资料」),把常用的 PDF / Word / PPT / Excel / 网页 / 文本资料上传进去,系统自动转成文字版、写好摘要索引;之后在对话里直接提问,我会按需查你的库作答并标注来源。扫描件 PDF 也会自动识别文字入库。库和文档可随时在面板里查看、删除。 diff --git a/PROGRESS.md b/PROGRESS.md index 4847011..49e9bd5 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -23,6 +23,7 @@ ### 2026-07 +- **07-23 / 0.59.2 / 移动端对话附件入口(📎 拍照 / 照片库 / 选文件)**:chat 输入区此前仅粘贴 / 拖拽两条附件路(移动端双双不可用,手机没有任何传文件入口)。加 📎 按钮:触屏(`pointer: coarse`)弹 showMenu 三项菜单——拍照(`capture="environment"` 直起后置相机)/ 照片库(`accept="image/*,video/*"`)/ 选取文件(无 accept);桌面端点击直开系统文件选择器(拖拽 / 粘贴照旧)。三个隐藏 input 的 change 统一走既有 `uploadAttachFiles()`(chip 托盘 / 发送注入行零改动);change 后清 value 允许连选同一文件;微信 / 企业微信只读镜像随 `applyChannelComposerLock` 禁用按钮 + 点击侧 `_composerLocked()` 双保险。纯前端(dev.html / chat.js),无后端改动。裸 file input 方案(靠 iOS 原生三选单)因 Android 行为不确定被弃,三项菜单跨平台确定。 - **07-23 / 0.59.1 / 架构审查落地:15 commit 内部重构大扫除(对外行为零变化)**:全库审查(web/核心循环/工具渲染/数据层四路并行探查)后按优先级逐项执行。①**web 拆分**——app.py 3972→197 行:73 路由迁 11 个 `web/routers/*`(register 范式同 admin.py),lifespan 后台协程按域析出(`background`/`scheduler_runner`/`wechat_runner`),schemas/model_gate/runs/userfiles/common 各归位;②**计费收口**——units JSONB 读侧唯一出口 `core/storage/usage_report.py`(web 层清零 cast),写侧拆 `telemetry.py`(四类 cost=0 留痕与真计费分家,kind 常量成 loop↔toolfail 契约单一事实源);③**loop 拆分**——传输健壮性层(畸形/吐空检测、留痕、非流式降级重试)析出 `core/llm_transport.py`(loop 1158→812),`_execute_tool_call` 148 行拆 4 个正交方法,测试打桩缝(`_collect_stream_once`/`_nonstream_once`)原样保留;④**工具注册声明式化**——`core/tool_registry.py` (组名,gate,factory) 表收敛四种 env-gate 写法(§7.5 #7 获代码强制),32 工具挂载逐名比对不变;⑤**媒体工具去重**——五工具同构(配额闸/落盘命名/记账兜底/超时重试/递归找 URL)收 `tools/media_common.py`,净减 122 行,banner/轮询等刻意差异不动;⑥**渲染统一**——块收集器(fence 闭合/表格/blockquote/段落并合)与 brief inline 切分下沉 `rendering/common`,**golden 基线**(四 profile 渲富 fixture、document.xml 逐字节对账,`tests/golden/`)零 diff 验收,分派状态机(in_refs 等)留 profile;⑦**测试 286→351**——scheduler 服务层、usage 口径、media 原语、wecom 加解密(自造密文覆盖失败路径)、路由两套(无 DB 面:11 router 鉴权门 19 端点 + kb/skills/memory/files FS;DB 面:tasks CRUD 全链 + files 顶层目录 DB-aware 四分支 + upload);测试库基建 = docker PG@5433 + `ZCBOT_TEST_DB_URL` 显式门控(RUN.md 一键命令)。**修 2 个真 bug**:restore 恢复真软删过的任务必 500(server-side onupdate 列 flush 后 expired → DetachedInstanceError,幂等路径掩盖多时,路由测试抓出);DB 测试曾沿 .env 连到生产隧道(127.0.0.1:6012)——插入的到点 job 被生产 green 调度守护真跑,门控收紧为只认 ZCBOT_TEST_DB_URL + connect_timeout=5 兜挂库,产物已全量清理。附带:scripts 50→29(已结案诊断/backfill 归档 `scripts/archive/`)、`tools/output.py`(输出处理自 base.py 析出)、export_docx 复用 rendering.common 字体助手(rendering 保持无 core 依赖的沙箱可用性,修正审查"迁 rendering"建议)。 - **07-22 / 0.59.0 / 个人知识库(纯文件 .kb/ 机制,照记忆范式)**:方案 07-22 对齐后落地(DESIGN §3.8)。**core**:`core/kb.py`(状态/视图层:库名与文件名校验、INDEX 单行格式 `- [标题](docs/x.md)|来源 sources/x.pdf|摘要:…|关键词:…` 的 parse/format、"已入库判据 = INDEX 有条目"派生 pending、删单篇连带原件与 INDEX 行、`kb_block` 注入)+ `core/kb_ingest.py`(入库管线:markitdown Python API → 扫描件 PDF 文本近零走方舟 OCR 兜底(§8.13 同通道)→ flash 单次 chat 写标题/摘要/关键词(失败降级不阻塞)→ 追加 INDEX;编排 create_task+to_thread+per-(user,库) 锁,进度内存态供轮询)。**记账**:0022 迁移放宽 `usage_events.task_id` 可 NULL(kb 入库无 task 上下文),溯源 = kind="kb_ingest"/"vision" + units `{"kb","source"}`(record_chat/vision_usage 签名同步放宽)。**API**:`/v1/kb*` 8 端点(列/建/删库、详情带入库进度、上传即入库、手动 ingest、看/删单篇),不设 HTTP 检索端点。**agent 侧零新工具**:agent_builder 在 memory_block 后注 `kb_block`(有库才注,docker/host 路径换算同 .memory);documents skill「何时不用」补自建资料路由行。**前端**:`kb.js` 两栏 modal(建/删库、上传 XHR、入库进度 3s 轮询、看/删单篇),rail 底部四按钮改图标+小字两行布局(用户 07-22 定)。冒烟:core 层 28 项全过(真实 markitdown + flash 摘要),TestClient API 15 项全过(usage 行实测 task_id=NULL + units 溯源),受影响存量测试(usage_accounting / system_prompt_paths)绿。 - **07-21 / 0.58.55 / 扫描件 PDF 直读(read_document,方舟文档理解)**:markitdown 只抽文本层,扫描件(老标准/检测报告/红头指南)转出为空=死路。探针(`scripts/probe_ark_doc.py`)验证方舟 chat file 内容块直读 PDF:格式 `{"type":"file","file":{filename,file_data}}` + `data:application/pdf;base64,` 前缀、base64 内联 17MB 可用(免 TOS)、单页栅格化 3600 万像素硬限(PIL 存 PDF 需标对 dpi)、~1300 输入 token/页(约 1 厘/页)、100 页魔术串全覆盖。落地 `tools/read_document.py`(seed_2_lite 同 variant 同 key,记账走 record_vision_usage):体积/页数双闸(30MB/100 页,pdfminer 软探页数免白付撞上下文)+ `finish_reason=length` 截断提示 + **多页 OCR `save_md` 全文落盘只返 1500 字预览**(防上下文爆);`image_ref.py` 抽 `load_pdf_as_data_url` 复用三形态路径解析与 user_root 边界。agent_builder 注册 + 系统提示 `_MEDIA_READDOC_SEG`(何时调/何时不调防重复花钱);六 skill(paper/patent/standard/proposal/rebuttal/ppt)摄取段加扫描件兜底一行。冒烟 `scripts/smoke_read_document.py` 全过(3 页 ¥0.0066,表格→md 表、公式→LaTeX)。选型对比(外部解析 API=新增第三方数据面 / 本地 OCR=过度投资)见 DESIGN §8.13。host 侧工具,**无需重建沙箱镜像**。 diff --git a/core/__init__.py b/core/__init__.py index ab696c1..02acc8b 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -1,3 +1,3 @@ # zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。 # 改版本只动这一行。 -__version__ = "0.59.1" +__version__ = "0.59.2" diff --git a/web/static/dev.html b/web/static/dev.html index c9d31db..4b0c50c 100644 --- a/web/static/dev.html +++ b/web/static/dev.html @@ -1807,11 +1807,16 @@