架构说明
本文档介绍 JAcoworks 的技术架构,适合开发者和技术管理者阅读。
整体架构
┌─────────────────────────────────────────────────────────────┐
│ JAcoworks 桌面端 │
│ (Tauri v2 + React 18) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ 登录/认证 │ │ 本地对话 │ │ OpenClaw 对话 │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
│ │ │ │ │
└─────────┼─────────────────┼────────────────────┼────────────┘
│ │ │
│ ┌──────┴───────┐ │
│ │ vm-agent │ │
│ │ (Pi SDK │ │
│ │ sidecar) │ │
│ └──────┬───────┘ │
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ Go 网关 (:8090) │
│ (frpc 穿透 → 67.230.171.248:8090) │
│ │
│ ┌────────┐ ┌──────────┐ ┌─────────┐ ┌──────────────────┐ │
│ │ 认证 │ │ 会话CRUD │ │ WS代理 │ │ LLM配置下发 │ │
│ └────────┘ └──────────┘ └────┬────┘ └──────────────────┘ │
└───────────────────────────────┼──────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ PostgreSQL │ │ LXD 容器 │ │ LLM 中转站 │
│ (Railway) │ │ (OpenClaw) │ │ (67.230.171.248 │
│ │ │ │ │ :8317) │
└──────────────┘ └──────────────────┘ └─────────────────┘
桌面端 (Tauri v2 + React 18)
桌面端是用户直接交互的界面层,基于 Tauri v2 构建。
技术选型
- Tauri v2: Rust 驱动的桌面应用框架,原生性能、极小体积
- React 18: 前端 UI 框架
- 纯 CSS 变量: 基于 Design Token 的样式系统,无 CSS-in-JS 框架依赖
核心模块
| 模块 | 职责 |
|---|---|
sidecar.rs | Agent sidecar 进程生命周期管理、RPC 通信、记忆管理 |
stream.rs | HTTP 请求封装(网关 API 调用) |
App.tsx | 应用入口,登录状态判断,模式切换 |
components/ | UI 组件(ChatView、Composer、Sidebar 等) |
hooks/ | React Hooks(Agent 引导、流式对话、响应式布局等) |
lib/ | 业务逻辑(认证、会话管理、配置、传输层等) |
openclaw/ | OpenClaw 模式完全独立的前端模块 |
双模式前端架构
- 本地模式:
react/目录下的组件,通过 Tauri sidecar RPC 与 Agent 通信 - OpenClaw 模式:
react/openclaw/独立模块,通过 WebSocket 与云端容器通信 - 两种模式不复用对话组件,仅共享认证、配置和传输层
本地 Agent (Pi SDK Sidecar)
本地 Agent 是运行在用户电脑上的 Node.js 进程,通过 stdin/stdout 与桌面端进行 RPC 通信。
技术栈
- Pi SDK: Agent 核心框架,管理 Session、Provider、Extension
- TypeScript: 严格模式,ES2022 目标
核心架构
桌面端 (Tauri)
│
│ stdin/stdout JSON Lines RPC
▼
┌───────────────────────────────────┐
│ vm-agent │
│ │
│ ┌─────────┐ ┌───────────────┐ │
│ │ RPC │ │ Agent.ts │ │
│ │ 主循环 │──│ Session 池 │ │
│ │ │ │ 4 Provider │ │
│ └─────────┘ └───────┬───────┘ │
│ │ │
│ ┌─────────────┐ ┌───┴────┐ │
│ │ Memory Ext. │ │ Tools │ │
│ │ 记忆扩展 │ │ 工具 │ │
│ └─────────────┘ └────────┘ │
└───────────────────────────────────┘
│
│ HTTPS
▼
LLM 中转站
RPC 协议
- 输入 (stdin): JSON 命令 ——
prompt、abort、destroy_session、generate_title、health等 - 输出 (stdout): JSON 事件 ——
response、session_event、error、done、ready - 启动时发送
ready事件,包含可用技能列表
Provider 注册
Agent 注册 4 个 LLM Provider,每个对应一个模型家族:
| Provider ID | 协议 | 模型前缀 |
|---|---|---|
proxy-claude | Anthropic Messages API | claude-* |
proxy-gpt | OpenAI Chat Completions | gpt-* |
proxy-gemini | OpenAI Chat Completions | gemini-* |
proxy-grok | OpenAI Chat Completions | grok-* |
Session 隔离
- 每个
session_id+user_id组合对应独立的 Pi SDK Session - 记忆目录按
user_id隔离 - Session 池支持复用和销毁
Go 网关
Go 网关是系统的管控层,处理认证、会话持久化、LLM 配置下发和 WebSocket 代理。
职责边界
网关只负责管控面,不参与对话逻辑:
| 职责 | 说明 |
|---|---|
| 认证 | 飞书 SSO (Goth Provider) + 邮箱密码 (bcrypt) + 激活码注册 |
| 会话 CRUD | chat_sessions 表的增删改查 |
| LLM 配置下发 | GET /api/agent/config 返回中转站地址和密钥 |
| WS 代理 | WebSocket 代理到 OpenClaw 容器 |
| LXD 管理 | 容器创建、启停、冻结 |
| 审计日志 | 记录关键操作 |
部署架构
网关运行在宿主机 (192.168.31.162) 上,通过 frpc 反向代理暴露到公网:
客户端 → 67.230.171.248:8090 → frpc → 宿主机:8090 (Go 网关)
LLM 中转站
LLM 中转站统一接入多家模型提供商的 API,对外提供标准化接口。
- 地址:
http://67.230.171.248:8317 - 支持协议: Anthropic Messages API + OpenAI Chat Completions API
- 统一认证: 单一 API Key 访问所有模型
- 流式支持: SSE (Server-Sent Events) 流式响应
请求路由
vm-agent → 中转站 → Anthropic API (Claude)
→ OpenAI API (GPT)
→ Google API (Gemini)
→ xAI API (Grok)
数据库
PostgreSQL (Railway 托管)
- 连接地址:
trolley.proxy.rlwy.net:28177 - 托管平台: Railway
核心数据表
| 表 | 说明 |
|---|---|
users | 用户信息(邮箱、密码哈希、角色、飞书 OpenID) |
auth_sessions | 登录会话(Token + 过期时间) |
chat_sessions | 对话会话(标题、消息 JSONB、模型、工作空间路径) |
containers | OpenClaw 容器分配(每用户唯一) |
invite_codes | 激活码(最大使用次数、已用次数) |
audit_logs | 审计日志 |
releases | 版本发布信息 |
release_assets | 平台安装包 |
feedback | 用户反馈 |
双模式架构总结
本地模式: 桌面端 → sidecar RPC → vm-agent → LLM 中转站
↕
本地文件系统 + 记忆
OpenClaw: 桌面端 → WebSocket → 网关 WS 代理 → LXD 容器 Agent
↕
容器文件系统
两种模式共享同一套认证体系和会话存储,用户可以无缝切换。