diff --git a/apps/jingrow/ai-docs/README.md b/apps/jingrow/ai-docs/README.md new file mode 100644 index 0000000..a9c642c --- /dev/null +++ b/apps/jingrow/ai-docs/README.md @@ -0,0 +1,143 @@ +# Jlocal AI开发文档 + +## 项目概述 + +Jlocal是Jingrow的本地版,与SaaS版Jingrow共享数据库,通过API保持通信。核心目标是实现本地运行智能体、触发钩子、定时任务等功能。 + +**与SaaS版Jingrow的关系**: +- 共享数据库:数据层完全共享 +- API通信:通过HTTP API与SaaS版后端交互 +- 前端兼容:前端代码与SaaS版保持一致,无需修改 + +**技术栈**: +- 后端: Python 3.10+ / FastAPI / MariaDB / Redis / Dramatiq +- 前端: Vue 3 / Naive UI / Pinia / Vue Router / Vite / TypeScript (与SaaS版相同) + +## 架构概览 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 前端 (Vue 3) │ +│ 与SaaS版前端代码完全一致 │ +└─────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ Jlocal 本地后端 (FastAPI) │ +│ ┌───────────────────────────────────────────────────────────────────┐ │ +│ │ 路由分发层 │ │ +│ │ ┌─────────────────────┐ ┌─────────────────────────────────┐ │ │ +│ │ │ 本地路由 │ │ 代理路由 (转发到JINGROW) │ │ │ +│ │ │ /jingrow/* │ │ /api/action/* (白名单外) │ │ │ +│ │ │ /api/action/login │ │ /api/data/* │ │ │ +│ │ │ /api/action/logout │ │ /api/v2/* │ │ │ +│ │ │ 白名单内方法 │ └─────────────────────────────────┘ │ │ +│ │ └─────────────────────┘ │ │ │ +│ │ │ ▼ │ │ +│ │ ▼ ┌─────────────────────────────┐ │ │ +│ │ ┌─────────────────────┐ │ ApiAdapter │ │ │ +│ │ │ 本地执行逻辑 │ │ (HTTP请求转发) │ │ │ +│ │ │ - 智能体执行引擎 │ └─────────────────────────────┘ │ │ +│ │ │ - 定时任务调度 │ │ │ │ +│ │ │ - 本地任务队列 │ │ │ │ +│ │ │ - 环境配置管理 │ ▼ │ │ +│ │ └─────────────────────┘ ┌─────────────────────────────┐ │ │ +│ └──────────────────────────────│ JINGROW_SERVER_URL │────┘ │ +│ │ (SaaS版Jingrow后端) │ │ +│ └─────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ 共享数据库 (MariaDB) │ +│ - 所有数据表共享,包括:Local Ai Agent、Scheduled Job Type等 │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +## 目录结构 + +``` +jlocal/apps/jingrow/ +├── jingrow/ # 后端核心 +│ ├── __init__.py # 框架入口,白名单装饰器 +│ ├── main.py # FastAPI应用入口 +│ ├── config.py # 配置管理 +│ ├── dramatiq.py # 任务队列入口 +│ ├── app.py # 应用启动 +│ ├── hooks.py # 钩子配置 +│ ├── model/ # 数据模型层 +│ │ └── page.py # Page基类 +│ ├── core/ # 核心模块 +│ │ ├── adapters/ # API适配器 +│ │ │ └── api_adapter.py # JINGROW API转发 +│ │ └── hooks/ # 钩子系统 +│ ├── services/ # 服务层 +│ │ ├── whitelist.py # 白名单路由服务 +│ │ └── scheduler.py # 定时任务服务 +│ ├── api/ # API路由 +│ │ ├── auth_api.py # 认证API +│ │ ├── agents.py # 智能体API +│ │ ├── system.py # 系统配置API +│ │ └── ... # 其他API +│ ├── ai/ # AI模块 +│ │ └── pagetype/ # AI Agent相关 +│ ├── utils/ # 工具函数 +│ │ ├── auth.py # 认证工具 +│ │ ├── jingrow_api.py # JINGROW API调用 +│ │ └── ... # 其他工具 +│ └── tools/ # AI工具 +├── frontend/ # 新版前端 (与SaaS版相同) +├── frontend_old/ # 旧版前端 (已废弃) +├── ai-docs/ # 本文档 +└── pyproject.toml # 项目配置 +``` + +## 核心概念 + +### 路由分流策略 + +**本地处理的路由**: +- `/jingrow/*` - 本地专用API (环境配置、本地任务等) +- `/api/action/login` - 登录 (需要设置本地cookie) +- `/api/action/logout` - 登出 (需要清除本地cookie) +- 白名单内的RPC方法 - 本地执行的函数 + +**转发到JINGROW的路由**: +- `/api/data/*` - CRUD操作 +- `/api/v2/*` - RESTful API +- `/api/action/*` - 白名单外的RPC方法 + +### 白名单机制 + +使用 `@jingrow.whitelist()` 装饰器暴露API: +```python +@jingrow.whitelist() +def my_local_method(arg1, arg2): + return {"result": "data"} + +# 允许访客访问 +@jingrow.whitelist(allow_guest=True) +def public_method(): + pass +``` + +### 配置管理 + +环境变量配置 (`.env`): +``` +JINGROW_SERVER_URL=https://admin.jingrow.com +JINGROW_API_KEY=xxx +JINGROW_API_SECRET=xxx +BACKEND_HOST=0.0.0.0 +BACKEND_PORT=9001 +``` + +## 文档索引 + +| 文档 | 说明 | +|------|------| +| [架构设计](guides/architecture.md) | 系统架构/路由分流/数据流 | +| [路由分流策略](guides/routing.md) | 本地路由与转发路由详解 | +| [后端API](backend/api.md) | 本地API/白名单机制 | +| [前端API](frontend/api.md) | API封装/状态管理 | +| [开发规范](guides/best-practices.md) | 代码规范/最佳实践 | diff --git a/apps/jingrow/ai-docs/guides/architecture.md b/apps/jingrow/ai-docs/guides/architecture.md new file mode 100644 index 0000000..0792e35 --- /dev/null +++ b/apps/jingrow/ai-docs/guides/architecture.md @@ -0,0 +1,193 @@ +# 系统架构 + +## Jlocal与Jingrow的关系 + +### 设计理念 + +Jlocal作为Jingrow的本地版,核心设计理念是: + +1. **前端完全兼容**:前端代码与SaaS版完全一致,无需任何修改 +2. **数据层共享**:与SaaS版共享同一数据库 +3. **本地执行优先**:智能体执行、定时任务等需要本地资源的操作在本地完成 +4. **API透明转发**:其他API请求透明转发到SaaS版后端 + +### 架构图 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ 用户浏览器 │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────────┐ +│ 前端 (Vue 3 + Naive UI) │ +│ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ shared/api/ │ │shared/stores│ │ views/ │ │ core/ │ │ +│ │ API封装 │ │ 状态管理 │ │ 页面组件 │ │ 核心组件 │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ │ +│ API调用格式: /api/action/{module.path.method} │ +│ /api/data/{pagetype} │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Jlocal 本地后端 (FastAPI) │ +│ │ +│ ┌───────────────────────────────────────────────────────────────────────┐ │ +│ │ 路由分发层 │ │ +│ │ │ │ +│ │ 请求进入 → 路由匹配 → 本地处理 or 转发JINGROW │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌───────────────────────┼───────────────────────┐ │ +│ ▼ ▼ ▼ │ +│ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │ +│ │ 本地路由 │ │ 白名单路由 │ │ 代理路由 │ │ +│ │ /jingrow/* │ │ /api/action/* │ │ /api/data/* │ │ +│ │ │ │ (白名单内) │ │ /api/v2/* │ │ +│ │ - login │ │ │ │ /api/action/* │ │ +│ │ - logout │ │ 本地执行函数 │ │ (白名单外) │ │ +│ │ - system │ │ │ │ │ │ +│ │ - agents │ └───────────────────┘ └───────────────────┘ │ +│ │ - scheduler │ │ │ +│ │ - local_jobs │ │ │ +│ └───────────────────┘ ▼ │ +│ ┌───────────────────┐ │ +│ │ ApiAdapter │ │ +│ │ │ │ +│ │ HTTP请求转发到 │ │ +│ │ JINGROW_SERVER │ │ +│ └───────────────────┘ │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ + ┌───────────────────────┼───────────────────────┐ + ▼ ▼ ▼ +┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ +│ 本地执行引擎 │ │ 共享数据库 │ │ JINGROW_SERVER │ +│ │ │ (MariaDB) │ │ (SaaS版后端) │ +│ - 智能体执行 │ │ │ │ │ +│ - 定时任务调度 │ │ 所有数据表共享 │ │ - 完整业务逻辑 │ +│ - 钩子触发 │ │ │ │ - 权限验证 │ +│ - 本地任务队列 │ │ │ │ - 数据操作 │ +│ - Dramatiq Worker│ │ │ │ │ +└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ +``` + +## 路由分流详解 + +### 分流规则 + +| 路由模式 | 处理位置 | 说明 | +|----------|----------|------| +| `/jingrow/login` | 本地 | 登录,设置本地cookie | +| `/jingrow/logout` | 本地 | 登出,清除本地cookie | +| `/jingrow/system/*` | 本地 | 环境配置管理 | +| `/jingrow/agents/*` | 本地 | 智能体执行 | +| `/jingrow/scheduler/*` | 本地 | 调度器管理 | +| `/jingrow/local_jobs/*` | 本地 | 本地任务管理 | +| `/api/action/login` | 本地 | 兼容SaaS版前端登录 | +| `/api/action/logout` | 本地 | 兼容SaaS版前端登出 | +| `/api/action/{method}` | 白名单判断 | 白名单内→本地,白名单外→转发 | +| `/api/data/*` | 转发JINGROW | CRUD操作 | +| `/api/v2/*` | 转发JINGROW | RESTful API | + +### 白名单机制 + +白名单用于标记哪些RPC方法需要在本地执行: + +```python +# 注册白名单函数 +@jingrow.whitelist() +def local_method(arg1, arg2): + """这个方法会在本地执行""" + return {"result": "data"} + +# 允许访客访问 +@jingrow.whitelist(allow_guest=True) +def public_method(): + pass + +# 限制HTTP方法 +@jingrow.whitelist(methods=["POST"]) +def post_only_method(): + pass +``` + +**路由处理流程**: + +``` +请求: /api/action/jingrow.realtime.get_user_info + ↓ + 路由分发层 + ↓ + 检查是否在白名单中? + ↙ ↘ + 是 否 + ↓ ↓ + 本地执行 转发JINGROW +``` + +## 数据流 + +### 登录流程 + +``` +1. 前端 → POST /api/action/login {usr, pwd} +2. Jlocal → JINGROW: POST /api/action/login +3. JINGROW → 返回 session_cookie +4. Jlocal → 设置本地cookie (sid) +5. Jlocal → 返回 {message: "Logged In"} +``` + +### 智能体执行流程 + +``` +1. 前端 → POST /jingrow/agents/execute {agent_id} +2. Jlocal → 创建 Local Job 记录 +3. Jlocal → Dramatiq 队列入队 +4. Worker → 执行智能体流程 +5. Worker → 更新 Local Job 状态 +6. Worker → 同步状态到 JINGROW (可选) +``` + +### 定时任务流程 + +``` +1. APScheduler → 触发定时任务 +2. Jlocal → 检查 Local Ai Agent 配置 +3. Jlocal → 执行智能体 +4. Jlocal → 记录执行结果 +``` + +## 模块职责 + +### 后端模块 + +| 模块 | 职责 | +|------|------| +| `main.py` | FastAPI应用入口,路由注册 | +| `services/whitelist.py` | 白名单路由服务,RPC方法分发 | +| `services/scheduler.py` | APScheduler定时任务管理 | +| `core/adapters/api_adapter.py` | JINGROW API转发适配器 | +| `api/auth_api.py` | 认证相关API | +| `api/agents.py` | 智能体执行API | +| `api/system.py` | 系统配置API | +| `utils/auth.py` | 认证工具函数 | +| `utils/jingrow_api.py` | JINGROW API调用封装 | + +### 前端模块 + +前端模块与SaaS版完全相同,详见 [frontend/api.md](../frontend/api.md) + +## 与SaaS版差异 + +| 功能 | SaaS版 | Jlocal | +|------|--------|--------| +| 后端框架 | Werkzeug + jingrow ORM | FastAPI | +| 任务队列 | Celery + Redis | Dramatiq + Redis | +| 定时任务 | jingrow scheduler | APScheduler | +| 智能体执行 | 后端执行 | 本地执行 | +| 数据库 | 独立 | 共享 | +| 前端 | Vue 3 | 相同代码 | diff --git a/apps/jingrow/ai-docs/guides/routing.md b/apps/jingrow/ai-docs/guides/routing.md new file mode 100644 index 0000000..854d274 --- /dev/null +++ b/apps/jingrow/ai-docs/guides/routing.md @@ -0,0 +1,191 @@ +# Jlocal 路由机制 + +## 概述 + +Jlocal 基于 FastAPI 实现路由系统,采用**静态路由 + 动态路由**双层架构: + +``` +请求 → FastAPI + ↓ + ┌────┴────┐ + ↓ ↓ +静态路由 动态路由 +(api/*) (whitelist) + ↓ ↓ +本地处理 白名单判断 +``` + +## 路由注册顺序 + +```python +# main.py + +def create_app(): + # 1. 自动注册 api 目录下的静态路由 + include_routers_from_package(app, "jingrow.api") + + # 2. 手动注册动态路由(最后注册,避免冲突) + app.include_router(router) # whitelist.py 的 router +``` + +**重要**:注册顺序决定路由匹配优先级,静态路由优先于动态路由。 + +## 一、静态路由(api 目录) + +### 自动注册机制 + +`jingrow/api/` 目录下的模块会被自动扫描注册: + +```python +# utils/router_auto_register.py + +def include_routers_from_package(app: FastAPI, package: str): + pkg = importlib.import_module(package) + modules = list(pkgutil.iter_modules(pkg.__path__, package + ".")) + + for module_info in modules: + mod = importlib.import_module(module_info.name) + router = getattr(mod, "router", None) + if router is not None: + app.include_router(router) +``` + +### 模块规范 + +每个路由模块必须: + +1. 定义 `router = APIRouter()` 变量 +2. 使用明确的路由路径(避免通配符冲突) + +```python +# api/auth_api.py 示例 + +router = APIRouter() + +@router.post("/api/action/login") +async def login_route(login_data: LoginRequest): + # 本地处理登录逻辑 + result = login(login_data.username, login_data.password) + return create_response_with_cookie(result, result.get("session_cookie")) +``` + +## 二、动态路由(whitelist) + +### 路由定义 + +```python +# services/whitelist.py + +router = APIRouter() # 无前缀 + +@router.api_route("/{module_path:path}", methods=["GET", "POST", "PUT", "DELETE"]) +async def handle_request(request: Request, module_path: str): + # 验证格式:必须包含点(如 jingrow.sessions.get_boot_info) + if '.' not in module_path: + raise HTTPException(status_code=404, detail="Not Found") + + return await _process_whitelist_call(request, module_path) +``` + +### 处理流程 + +``` +请求: /jingrow.sessions.get_boot_info + ↓ + 动态导入模块 + ↓ + 检查白名单装饰器 + ↙ ↘ + 有 无 + ↓ ↓ + 本地执行 返回 404 +``` + +### 白名单装饰器 + +```python +# 在任意模块中使用 + +import jingrow + +@jingrow.whitelist() +def local_method(arg1, arg2): + """需要登录才能调用""" + return {"result": "data"} + +@jingrow.whitelist(allow_guest=True) +def public_method(): + """允许访客调用""" + return {"result": "public"} + +@jingrow.whitelist(methods=["POST"]) +def post_only_method(): + """只允许 POST 请求""" + return {"result": "created"} +``` + +## 四、开发指南 + +### 添加白名单函数 + +1. 在任意模块中定义函数 +2. 添加 `@jingrow.whitelist()` 装饰器 +3. 确保模块被导入(在 main.py 或其他入口导入) + +```python +# services/my_service.py + +import jingrow + +@jingrow.whitelist() +def my_rpc_method(param1: str): + return {"result": param1} +``` + +### 路由冲突处理 + +1. 静态路由优先于动态路由 +2. 精确匹配优先于通配符 +3. 后注册的路由不会覆盖先注册的 + +## 五、注意事项 + +1. **不要在 whitelist.py 中添加业务逻辑**,它只负责路由分发 +2. **本地特有功能使用 api 目录**,自动注册 +3. **需要动态 RPC 调用使用白名单装饰器** +4. **路由路径要明确**,避免通配符冲突 + +## 六、SaaS 端转发 + +对于 SaaS 端已有的 API,需要在本地添加代理路由: + +### 方式一:在 api 目录添加代理路由 + +```python +# api/data.py - 代理 /api/data/* 到 SaaS 端 + +from fastapi import APIRouter, Request +from fastapi.responses import JSONResponse +import requests +from jingrow.config import Config + +router = APIRouter(prefix="/api/data") + +@router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"]) +async def proxy_data(request: Request, path: str): + url = f"{Config.jingrow_server_url}/api/data/{path}" + # 转发请求到 SaaS 端 + resp = requests.get(url, headers={...}, timeout=30) + return JSONResponse(content=resp.json(), status_code=resp.status_code) +``` + + + +### 常见需要转发的路由 + +| 路由 | 说明 | +|------|------| +| `/api/data/*` | CRUD 数据操作 | +| `/api/action/jingrow.sessions.*` | 会话相关 | +| `/api/action/jingrow.client.*` | 客户端数据获取 | +| `/api/action/jingrow.realtime.*` | 实时通信 | \ No newline at end of file