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 系统依赖
62 lines
2.4 KiB
Rust
62 lines
2.4 KiB
Rust
// build.rs
|
||
use std::path::Path;
|
||
use std::process::Command;
|
||
|
||
fn main() {
|
||
// 声明:只有当 dashboard/src/ 目录或 build.rs 发生改变时,才重新触发构建脚本
|
||
println!("cargo:rerun-if-changed=dashboard/src");
|
||
println!("cargo:rerun-if-changed=dashboard/package.json");
|
||
println!("cargo:rerun-if-changed=build.rs");
|
||
|
||
// Docker/CI 环境跳过前端构建 (dist 已在 Dockerfile 中预构建)
|
||
let skip_build = std::env::var("SKIP_DASHBOARD_BUILD")
|
||
.map(|v| v == "1" || v == "true")
|
||
.unwrap_or(false);
|
||
if skip_build {
|
||
println!("cargo:warning=SKIP_DASHBOARD_BUILD 已设置,跳过前端构建。");
|
||
return;
|
||
}
|
||
|
||
let dashboard_dir = Path::new("dashboard");
|
||
let node_modules_exist = dashboard_dir.join("node_modules").exists();
|
||
let dist_exists = dashboard_dir.join("dist").exists();
|
||
|
||
// 1. 如果没有 node_modules,自动运行 npm install
|
||
if !node_modules_exist {
|
||
println!("cargo:warning=未检测到 node_modules,正在自动为您安装前端依赖 (npm install)...");
|
||
let status = Command::new("npm")
|
||
.arg("install")
|
||
.current_dir(dashboard_dir)
|
||
.status();
|
||
|
||
match status {
|
||
Ok(s) if s.success() => {
|
||
println!("cargo:warning=前端依赖安装成功。");
|
||
}
|
||
_ => {
|
||
panic!("错误: 自动执行 npm install 失败,请检查是否安装了 Node.js / npm 并配置了正确的环境变量。");
|
||
}
|
||
}
|
||
}
|
||
|
||
// 2. 如果 dist 目录不存在,或者检测到前端源码变化,自动运行 npm run build
|
||
// 提示:因为上面 rerun-if-changed 绑定了 src 目录,只有 src 变动或者 dist 不存在时才会走到这步
|
||
if !dist_exists || node_modules_exist {
|
||
println!("cargo:warning=正在自动为您构建前端静态资源 (npm run build)...");
|
||
let status = Command::new("npm")
|
||
.arg("run")
|
||
.arg("build")
|
||
.current_dir(dashboard_dir)
|
||
.status();
|
||
|
||
match status {
|
||
Ok(s) if s.success() => {
|
||
println!("cargo:warning=前端资源构建打包成功。");
|
||
}
|
||
_ => {
|
||
panic!("错误: 自动构建前端静态资源失败 (npm run build),请进入 dashboard 目录手动排查编译错误。");
|
||
}
|
||
}
|
||
}
|
||
}
|