feat: Docker 容器化、Cookie 鉴权、Coordinator 编排、FTS5 搜索与 P1-P3 全面收尾

Docker 容器化部署
  - 提供 Mode A (Alpine musl, ~23MB) 和 Mode B (Distroless glibc, ~87MB)
    两种镜像,Docker Compose 一键启动
  - build.rs 支持 SKIP_DASHBOARD_BUILD 跳过前端构建
  - 国内镜像加速 (npm/apt/apk) 通过 USE_MIRRORS build-arg 控制

  安全:Cookie-Based 鉴权系统
  - HttpOnly/SameSite=Strict Cookie 会话管理(24h 过期自动清理)
  - 登录/登出/验证接口 + 中间件注入
  - 前端登录页面 + 退出按钮
  - 三层 CORS:localhost 鉴权 / 全放通 bookmarklet / 受保护路由
  - 书签脚本 fetch 添加 credentials:'include'

  Coordinator 模式 (P2)
  - 4 个 meta-tool (delegate_task/check_task/task_stop/synthesize)
  - WorkerPool + Semaphore 并发控制 + 超时保护
  - 前端协调者模式开关

  Hook 系统:UserPromptSubmit 事件 (P2)
  - 第 13 个生命周期事件,fire-and-forget 审计

  FTS5 全文搜索 (P3)
  - agent_sessions_fts + agent_messages_fts 虚拟表
  - search_history Agent 工具 + /api/search/history HTTP 接口
  - 前端防抖搜索框 + 仅当前会话筛选

  工具加载优化 (P3)
  - defer_loading 延迟加载 (7 个重型工具)
  - is_readonly 只读标记 (9 个查询工具)
  - classifier_summary 工具目录供 LLM 按需判断

  模型回退策略 (P3)
  - LLM_FALLBACK_MODEL 优先回退 + LLM_FALLBACK_CHAIN 链式轮换
  - LlmClient model 改为 Arc<RwLock> 支持运行时切换
  - 连续 3 次过载后自动切换

  压缩记忆桥接 (P3)
  - 压缩丢弃消息 → 子代理提取持久记忆 (extract_memories_from_compaction)

  git2 依赖修复
  - 切换到 vendored-libgit2,消除 OpenSSL 系统依赖
This commit is contained in:
fmq
2026-06-23 20:22:06 +08:00
parent 698d007f39
commit cec4b8cf7b
58 changed files with 3366 additions and 345 deletions
+57 -3
View File
@@ -44,6 +44,9 @@ classDiagram
+check_permissions(args) PermissionRule[]
+causes_sibling_abort() bool
+execute_with_progress(args, ctx, tx) ToolOutput
+classifier_summary() String
+is_readonly() bool
+defer_loading() bool
}
class InterruptBehavior {
@@ -106,10 +109,13 @@ classDiagram
| `check_permissions()` | `Vec<PermissionRule>` | `[]` | 工具自定义权限规则:`Deny{tool, reason}` / `Allow{tool}` / `Ask{tool, message}`。与 `PermissionChecker` 管道协同工作 |
| `causes_sibling_abort()` | `bool` | `false` | 该工具错误时是否中止兄弟并行执行。用于 `download_paper``parse_paper` 等关键工具 |
| `execute_with_progress(args, ctx, tx)` | `ToolOutput` | 委托 `execute()` | 长时间操作可覆写,通过 `progress_tx` 发送进度更新到前端 |
| `classifier_summary()` | `String` | 取 `description` 第一句,截断到 100 字符 | 工具简要分类描述(~15 词),供 LLM 判断是否需要加载延迟工具 |
| `is_readonly()` | `bool` | `false`(保守) | 是否只读(无副作用)。9 个只读工具覆写为 `true` |
| `defer_loading()` | `bool` | `false`(常驻) | 是否延迟加载(不在初始 prompt 中)。7 个重型/小众工具覆写为 `true` |
---
## 工具清单(23 个)
## 工具清单(24 个)
### 文件系统工具(6 个)— `filesystem/`
@@ -140,7 +146,7 @@ classDiagram
| `query_target` | ✅ | CDS Sesame 天体目标查询(IAU 名称解析 + 坐标/类型) |
| `save_note` | ❌ | 高亮批注持久化到数据库 |
### Agent 自管理工具(5 个)
### Agent 自管理工具(6 个)
| 工具 | 并发安全 | 中断行为 | 功能 |
|:---|:---|:---|:---|
@@ -149,6 +155,7 @@ classDiagram
| `load_skill` | ✅ | Cancel | 按需加载 SKILL.md 技能文件。支持 **inline** 模式(直接返回内容)和 **fork** 模式(启动子代理按技能指引执行任务) |
| `save_memory` | ❌ | Block | 跨会话记忆持久化。写入时门控:质量检查(过短/模糊/瞬时/代码模式)+ Jaccard 70% 去重 |
| `ask_user` | N/A | Block | 暂停 ReAct 循环向用户提问。oneshot 通道机制:创建问题 → SSE 推送前端 → 阻塞等待 → 5 分钟超时。子代理中不可用(silent 模式) |
| `search_history` | ✅ | Cancel | FTS5 跨会话历史搜索。支持会话标题/摘要和消息内容全文检索,避免重复研究已完成的工作 |
### 高级编排工具(4 个)
@@ -270,7 +277,7 @@ sequenceDiagram
RT->>TR: new_with_queue(queue, skill_registry)
TR->>TR: add_base_tools()
Note over TR: 注册 19 个基础工具
Note over TR: 注册 19 个基础工具(不含 search_history,该工具在 Runtime 中按需注入)
TR->>Tools: read_file, grep_files, glob_files, run_bash
TR->>Tools: file_write, file_edit
TR->>Tools: search_papers, get_paper_metadata
@@ -294,6 +301,15 @@ sequenceDiagram
TR->>TR: definitions()
Note over TR: HashMap 值收集 → 按 name 字母序排序
Note over TR: 排序保证跨调用稳定性 → 提升 prompt cache 命中率
RT->>TR: resident_definitions()
Note over TR: 返回常驻工具(defer_loading=false)→ 注入初始 prompt
RT->>TR: deferred_definitions()
Note over TR: 返回延迟工具(defer_loading=true)→ 供 LLM 按需加载
RT->>TR: tool_catalog()
Note over TR: 所有工具的 name + classifier_summary → 供 LLM 判断延迟工具需求
```
### 注册表工厂方法
@@ -406,6 +422,43 @@ execute() → ToolOutput { content }
---
## 工具加载分类(P3 特性)
`classifier_summary``is_readonly``defer_loading` 三个 trait 方法共同支持两维度工具分类:
### 只读 vs 写入分类 (`is_readonly`)
只读工具无副作用(不修改文件系统、不触发下载、不写入数据库),可在 Auto 模式下跳过权限确认直接执行。
| 分类 | `is_readonly` | 工具 |
|:---|:---|:---|
| 只读 (9) | `true` | `read_file``grep_files``glob_files``search_papers``get_paper_metadata``get_paper_content``rag_search``query_target``check_team_inbox` |
| 写入/副作用 | `false`(默认) | 其余所有工具(包括 `run_bash``file_write``download_paper``save_note` 等) |
### 常驻 vs 延迟加载 (`defer_loading`)
常驻工具定义注入初始系统 prompt,延迟工具仅在 LLM 需要时通过 `load_tool` 动态加载,减少 prompt 体积。
| 分类 | `defer_loading` | 工具 |
|:---|:---|:---|
| 常驻 (18) | `false`(默认) | 核心文件 I/O、论文搜索/检索、用户交互等高频工具 |
| 延迟 (7) | `true` | `parse_paper``download_paper``bg_task_run``bg_task_check``spawn_teammate``send_teammate_message``team_broadcast``search_history` |
### 工作流
```
初始化:
resident_definitions() → 注入 system prompt(常驻工具 JSON Schema
tool_catalog() → name + classifier_summary 清单 → 供 LLM 决策
LLM 运行时:
分析 task → 查看 catalog → 判断是否需要延迟工具
→ 调用 defer_load_specific(name) → 注入单工具 definition
→ 正常执行工具调用
```
---
## 目录结构
```
@@ -435,5 +488,6 @@ src/agent/tools/
├── background.rs # bg_task_run + bg_task_check — 后台异步任务
├── team.rs # spawn/send/broadcast/check_inbox — 多 Agent 协作
├── memory.rs # save_memory — 带质量门控的跨会话记忆
├── search_history.rs # search_history — FTS5 跨会话历史搜索(延迟加载)
└── persist.rs # maybe_persist_tool_result — 大输出磁盘持久化
```