diff --git a/desktop/src/components/ErrorNotification.tsx b/desktop/src/components/ErrorNotification.tsx new file mode 100644 index 0000000..a1c40cd --- /dev/null +++ b/desktop/src/components/ErrorNotification.tsx @@ -0,0 +1,271 @@ +/** + * ErrorNotification Component + * + * Displays error notifications as toast-style messages. + * Integrates with the centralized error handling system. + */ + +import { useState, useEffect, useCallback } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { + X, + AlertCircle, + AlertTriangle, + Info, + Bug, + WifiOff, + ShieldAlert, + Clock, + ChevronDown, + ChevronUp, +} from 'lucide-react'; +import { + getUndismissedErrors, + dismissError, + dismissAll, + type StoredError, +} from '../lib/error-handling'; +import { + ErrorCategory, + ErrorSeverity, + formatErrorForToast, +} from '../lib/error-types'; + +interface ErrorNotificationProps { + /** Maximum number of visible notifications */ + maxVisible?: number; + /** Position on screen */ + position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; + /** Auto dismiss timeout in ms (0 = no auto dismiss) */ + autoDismissMs?: number; + /** Additional CSS classes */ + className?: string; +} + +const categoryIcons: Record = { + network: WifiOff, + authentication: ShieldAlert, + authorization: ShieldAlert, + validation: AlertTriangle, + configuration: AlertTriangle, + internal: Bug, + external: AlertCircle, + timeout: Clock, + unknown: AlertCircle, +}; + +const severityColors: Record = { + critical: { + bg: 'bg-red-50 dark:bg-red-900/20', + border: 'border-red-200 dark:border-red-800', + text: 'text-red-800 dark:text-red-200', + icon: 'text-red-500', + }, + high: { + bg: 'bg-orange-50 dark:bg-orange-900/20', + border: 'border-orange-200 dark:border-orange-800', + text: 'text-orange-800 dark:text-orange-200', + icon: 'text-orange-500', + }, + medium: { + bg: 'bg-yellow-50 dark:bg-yellow-900/20', + border: 'border-yellow-200 dark:border-yellow-800', + text: 'text-yellow-800 dark:text-yellow-200', + icon: 'text-yellow-500', + }, + low: { + bg: 'bg-blue-50 dark:bg-blue-900/20', + border: 'border-blue-200 dark:border-blue-800', + text: 'text-blue-800 dark:text-blue-200', + icon: 'text-blue-500', + }, +}; + +function ErrorItem({ + error, + onDismiss, + autoDismissMs, +}: { + error: StoredError; + onDismiss: (id: string) => void; + autoDismissMs: number; +}) { + const [expanded, setExpanded] = useState(false); + const Icon = categoryIcons[error.category] || AlertCircle; + const colors = severityColors[error.severity] || severityColors.medium; + const { title, message } = formatErrorForToast(error); + + // Auto dismiss + useEffect(() => { + if (autoDismissMs > 0 && error.severity !== 'critical') { + const timer = setTimeout(() => { + onDismiss(error.id); + }, autoDismissMs); + return () => clearTimeout(timer); + } + }, [autoDismissMs, error.id, error.severity, onDismiss]); + + const hasDetails = error.stack || error.context; + + return ( + +
+ +
+
+

{title}

+ +
+

{message}

+ + {hasDetails && ( + + )} + + {expanded && hasDetails && ( + + {error.context && ( +
+ Context: + {JSON.stringify(error.context, null, 2)} +
+ )} + {error.stack && ( +
{error.stack}
+ )} +
+ )} + +
+ {error.category} + + {new Date(error.timestamp).toLocaleTimeString()} +
+
+
+
+ ); +} + +export function ErrorNotification({ + maxVisible = 3, + position = 'top-right', + autoDismissMs = 10000, + className = '', +}: ErrorNotificationProps) { + const [errors, setErrors] = useState([]); + + // Poll for new errors + useEffect(() => { + const updateErrors = () => { + setErrors(getUndismissedErrors().slice(0, maxVisible)); + }; + + updateErrors(); + const interval = setInterval(updateErrors, 1000); + return () => clearInterval(interval); + }, [maxVisible]); + + const handleDismiss = useCallback((id: string) => { + dismissError(id); + setErrors(prev => prev.filter(e => e.id !== id)); + }, []); + + const handleDismissAll = useCallback(() => { + dismissAll(); + setErrors([]); + }, []); + + const positionClasses: Record = { + 'top-right': 'top-4 right-4', + 'top-left': 'top-4 left-4', + 'bottom-right': 'bottom-4 right-4', + 'bottom-left': 'bottom-4 left-4', + }; + + if (errors.length === 0) return null; + + return ( +
+ + {errors.map(error => ( + + ))} + + + {errors.length > 1 && ( + + 清除全部 ({errors.length}) + + )} +
+ ); +} + +/** + * ErrorNotificationProvider - Include at app root + */ +export function ErrorNotificationProvider({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + {children} + + + ); +} + +export default ErrorNotification; diff --git a/docs/quick-start.md b/docs/quick-start.md new file mode 100644 index 0000000..402f3bb --- /dev/null +++ b/docs/quick-start.md @@ -0,0 +1,233 @@ +# ZCLAW 快速启动指南 + +> 5 分钟内启动 ZCLAW 开发环境 + +--- + +## 前置要求 + +| 工具 | 最低版本 | 检查命令 | +|------|----------|----------| +| Node.js | 18.x | `node -v` | +| pnpm | 8.x | `pnpm -v` | +| Rust | 1.70+ | `rustc --version` | +| OpenFang | - | `openfang --version` | + +--- + +## 快速启动 + +### Windows 用户 + +```powershell +# 在项目根目录执行 +.\scripts\quick-start-dev.ps1 +``` + +### Linux/macOS 用户 + +```bash +# 在项目根目录执行 +./scripts/quick-start.sh +``` + +--- + +## 手动启动步骤 + +### 1. 安装依赖 + +```bash +# 根目录依赖 +pnpm install + +# 桌面端依赖 +cd desktop && pnpm install && cd .. +``` + +### 2. 启动 OpenFang 后端 + +```bash +# 方法 A: 使用 CLI +openfang start + +# 方法 B: 使用 pnpm 脚本 +pnpm gateway:start +``` + +验证后端运行: +```bash +curl http://127.0.0.1:50051/api/health +# 应返回: {"status":"ok"} +``` + +### 3. 启动开发环境 + +```bash +# 方法 A: 一键启动(推荐) +pnpm start:dev + +# 方法 B: 仅启动桌面端(需要后端已运行) +pnpm desktop + +# 方法 C: 分开启动 +# 终端 1 - 启动 Gateway +pnpm dev + +# 终端 2 - 启动桌面端 +pnpm desktop +``` + +--- + +## 测试环境启动 + +### 单元测试 + +```bash +# 运行所有单元测试 +pnpm test + +# 监听模式 +pnpm test:watch + +# 桌面端测试 +cd desktop && pnpm test +``` + +### E2E 测试 + +```bash +# 运行 E2E 测试 +pnpm test:e2e + +# 带界面运行 +cd desktop && pnpm test:e2e:ui +``` + +--- + +## 开发端口说明 + +| 服务 | 端口 | 说明 | +|------|------|------| +| OpenFang 后端 | 50051 | API 和 WebSocket 服务 | +| Vite 开发服务器 | 1420 | 前端热重载 | +| Tauri 窗口 | - | 桌面应用窗口 | + +--- + +## 常见问题排查 + +### Q1: 端口被占用 + +**症状**: `Port 1420 is already in use` 或 `Port 50051 is already in use` + +**解决**: +```powershell +# Windows - 查找并终止进程 +netstat -ano | findstr "1420" +taskkill /PID /F + +# Linux/macOS +lsof -i :1420 +kill -9 +``` + +### Q2: 后端连接失败 + +**症状**: `Network Error` 或 `Connection refused` + +**排查步骤**: +```bash +# 1. 检查后端是否运行 +curl http://127.0.0.1:50051/api/health + +# 2. 检查端口监听 +netstat -ano | findstr "50051" + +# 3. 重启后端 +openfang restart +``` + +### Q3: API Key 未配置 + +**症状**: `Missing API key: No LLM provider configured` + +**解决**: +```bash +# 编辑配置文件 +# Windows: %USERPROFILE%\.openfang\.env +# Linux/macOS: ~/.openfang/.env + +# 添加 API Key +echo "ZHIPU_API_KEY=your_key" >> ~/.openfang/.env + +# 重启后端 +openfang restart +``` + +### Q4: Tauri 编译失败 + +**症状**: Rust 编译错误 + +**解决**: +```bash +# 更新 Rust +rustup update + +# 清理并重新构建 +cd desktop/src-tauri +cargo clean +cargo build +``` + +### Q5: 依赖安装失败 + +**症状**: pnpm install 报错 + +**解决**: +```bash +# 清理缓存 +pnpm store prune + +# 删除 node_modules 重新安装 +rm -rf node_modules desktop/node_modules +pnpm install +``` + +--- + +## 验证清单 + +启动成功后,验证以下功能: + +- [ ] 后端健康检查通过: `curl http://127.0.0.1:50051/api/health` +- [ ] 桌面端窗口正常显示 +- [ ] 可以发送消息并获得响应 +- [ ] 可以切换 Agent +- [ ] 可以查看设置页面 + +--- + +## 停止服务 + +```bash +# 停止所有服务 +pnpm start:stop + +# 或手动停止 +# Ctrl+C 终止运行中的进程 +``` + +--- + +## 相关文档 + +- [完整开发文档](./DEVELOPMENT.md) +- [故障排查指南](./knowledge-base/troubleshooting.md) +- [配置说明](./knowledge-base/configuration.md) + +--- + +**最后更新**: 2026-03-21 diff --git a/docs/setup/OPENFANG-SETUP.md b/docs/setup/OPENFANG-SETUP.md new file mode 100644 index 0000000..1b258d6 --- /dev/null +++ b/docs/setup/OPENFANG-SETUP.md @@ -0,0 +1,512 @@ +# OpenFang Kernel 配置指南 + +> 本文档帮助你正确配置 OpenFang Kernel,作为 ZCLAW 的后端执行引擎。 + +## 概述 + +OpenFang 是一个用 Rust 构建的生产级 Agent 操作系统(Agent Operating System)。与传统的聊天机器人框架不同,OpenFang 采用"主动执行"范式:Agent 能够按计划自主唤醒、完成任务并报告结果,而无需用户持续提示。 + +### 核心特性 + +- **高性能**:冷启动 < 200ms,空闲内存 ~40MB +- **Hands 机制**:7 个预构建的自主能力包,即插即用 +- **40+ 渠道适配器**:支持 Telegram、Discord、飞书、钉钉等 +- **27+ LLM 提供商**:包括中文模型(智谱、通义千问、Kimi、MiniMax) +- **16 层安全防护**:WASM 沙箱、Merkle 审计追踪、Ed25519 签名等 + +--- + +## 前置要求 + +### 系统要求 + +| 要求 | 最低配置 | 推荐配置 | +|------|----------|----------| +| **操作系统** | Windows 10 / macOS 10.15 / Linux | Windows 11 / macOS 13+ / Ubuntu 22.04+ | +| **CPU 架构** | x86_64 或 ARM64 | x86_64 | +| **内存** | 64MB | 256MB+ | +| **磁盘空间** | 100MB | 500MB+ | + +### 依赖项 + +OpenFang 是一个独立的单二进制文件(~32MB),无外部依赖。但以下工具可能对某些功能必要: + +- **FFmpeg**:视频处理 Hand (Clip) 需要 +- **yt-dlp**:YouTube 视频下载需要 + +--- + +## 安装步骤 + +### 方式一:官方安装脚本(推荐) + +#### Windows + +```powershell +# 使用 PowerShell +iwr -useb https://openfang.sh/install.ps1 | iex +``` + +#### macOS / Linux + +```bash +curl -fsSL https://openfang.sh/install.sh | bash +``` + +### 方式二:手动下载 + +1. 访问 [GitHub Releases](https://github.com/RightNow-AI/openfang/releases) +2. 下载对应平台的二进制文件 +3. 将文件放入 PATH 目录 + +#### Windows + +```powershell +# 下载后移动到用户目录 +move openfang.exe C:\Users\<你的用户名>\.local\bin\ +``` + +#### macOS / Linux + +```bash +chmod +x openfang +sudo mv openfang /usr/local/bin/ +``` + +### 方式三:从源码编译 + +```bash +git clone https://github.com/RightNow-AI/openfang.git +cd openfang +cargo build --release +# 编译产物位于 target/release/openfang +``` + +--- + +## 配置说明 + +### 1. 初始化配置 + +首次使用需要初始化配置文件: + +```bash +openfang init +``` + +这将在 `~/.openfang/` 目录下创建以下结构: + +``` +~/.openfang/ +├── config.toml # 主配置文件 +├── openfang.db # SQLite 数据库 +├── data/ # 数据目录 +│ ├── agents/ # Agent 配置 +│ ├── skills/ # 自定义技能 +│ └── hands/ # Hand 配置 +└── logs/ # 日志文件 +``` + +### 2. 配置文件结构 + +编辑 `~/.openfang/config.toml`: + +```toml +# OpenFang 主配置文件 + +[general] +# 默认语言 +language = "zh-CN" +# 日志级别: trace, debug, info, warn, error +log_level = "info" +# 数据目录 +data_dir = "~/.openfang/data" + +[model] +# 默认模型提供商 +provider = "zhipu" +# 默认模型 +model = "glm-4-flash" +# API Key 环境变量名(不直接写 Key) +api_key_env = "ZHIPU_API_KEY" +# 可选:自定义 API 端点 +# base_url = "https://open.bigmodel.cn/api/paas/v4" + +[api] +# API 服务端口 +port = 50051 +# 绑定地址(0.0.0.0 允许外部访问) +bind = "127.0.0.1" +# 启用 OpenAI 兼容 API +openai_compat = true + +[security] +# 启用能力门控 +capability_gates = true +# 启用审计追踪 +audit_trail = true +# 启用 WASM 沙箱 +wasm_sandbox = true + +[memory] +# 会话保留天数 +session_retention_days = 30 +# 向量嵌入模型 +embedding_model = "text-embedding-3-small" +``` + +### 3. 配置 API Key + +**重要**:永远不要在配置文件中直接写入 API Key,使用环境变量: + +#### Windows (PowerShell) + +```powershell +# 临时设置(当前会话) +$env:ZHIPU_API_KEY = "your-api-key-here" +$env:DASHSCOPE_API_KEY = "your-dashscope-key" # 通义千问 +$env:MOONSHOT_API_KEY = "your-moonshot-key" # Kimi + +# 永久设置(写入配置文件) +[Environment]::SetEnvironmentVariable("ZHIPU_API_KEY", "your-api-key", "User") +``` + +#### macOS / Linux + +```bash +# 临时设置(当前会话) +export ZHIPU_API_KEY="your-api-key-here" +export DASHSCOPE_API_KEY="your-dashscope-key" +export MOONSHOT_API_KEY="your-moonshot-key" + +# 永久设置(写入 shell 配置文件) +echo 'export ZHIPU_API_KEY="your-api-key"' >> ~/.bashrc +source ~/.bashrc +``` + +### 4. 配置中文模型 + +在 `config.toml` 中配置中文模型提供商: + +```toml +# 智谱 GLM +[model.zhipu] +provider = "zhipu" +model = "glm-4-flash" +api_key_env = "ZHIPU_API_KEY" +base_url = "https://open.bigmodel.cn/api/paas/v4" + +# 通义千问 +[model.qwen] +provider = "openai-compat" +model = "qwen-turbo" +api_key_env = "DASHSCOPE_API_KEY" +base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1" + +# Kimi (Moonshot) +[model.kimi] +provider = "openai-compat" +model = "moonshot-v1-8k" +api_key_env = "MOONSHOT_API_KEY" +base_url = "https://api.moonshot.cn/v1" + +# MiniMax +[model.minimax] +provider = "openai-compat" +model = "abab6.5-chat" +api_key_env = "MINIMAX_API_KEY" +base_url = "https://api.minimax.chat/v1" +``` + +### 5. 启动服务 + +#### 前台运行(调试用) + +```bash +openfang start +``` + +#### 后台守护进程 + +```bash +# 启动守护进程 +openfang daemon start + +# 查看状态 +openfang status + +# 停止守护进程 +openfang daemon stop +``` + +#### 检查健康状态 + +```bash +openfang doctor +``` + +--- + +## 与 ZCLAW 集成 + +### 配置 ZCLAW 连接 OpenFang + +编辑 ZCLAW 配置文件 `~/.zclaw/config.toml`: + +```toml +[gateway] +# OpenFang API 端点 +endpoint = "http://127.0.0.1:50051" +# WebSocket 端点 +ws_endpoint = "ws://127.0.0.1:50051/ws" +# 连接超时(秒) +timeout = 30 + +[model] +# 使用 OpenFang 的模型路由 +use_gateway_routing = true +``` + +### 验证连接 + +```bash +# 启动 OpenFang +openfang start + +# 在另一个终端启动 ZCLAW +cd desktop && pnpm tauri dev +``` + +--- + +## 常见问题 + +### 1. 端口被占用 + +**错误信息**:`Address already in use: 0.0.0.0:50051` + +**解决方案**: + +```bash +# 查找占用端口的进程 +# Windows +netstat -ano | findstr :50051 + +# macOS / Linux +lsof -i :50051 + +# 修改配置文件中的端口 +[api] +port = 50052 +``` + +### 2. API Key 无效 + +**错误信息**:`Authentication failed` 或 `Invalid API key` + +**排查步骤**: + +1. 确认环境变量已设置: + ```bash + # Windows + echo $env:ZHIPU_API_KEY + + # macOS / Linux + echo $ZHIPU_API_KEY + ``` + +2. 确认 API Key 格式正确(无多余空格或引号) + +3. 确认 API Key 未过期 + +### 3. 内存不足 + +**错误信息**:`Out of memory` 或系统卡顿 + +**解决方案**: + +1. 关闭不必要的服务 +2. 降低并发 Agent 数量 +3. 增加系统交换空间 + +### 4. 模型调用失败 + +**错误信息**:`Model not found` 或 `Provider error` + +**排查步骤**: + +1. 检查模型名称是否正确 +2. 确认 API 端点可访问 +3. 检查网络连接和代理设置 + +```bash +# 测试 API 连通性 +curl -I https://open.bigmodel.cn/api/paas/v4/models +``` + +### 5. 中文乱码 + +**解决方案**: + +确保系统 locale 设置正确: + +```bash +# Windows +chcp 65001 + +# macOS / Linux +export LANG=zh_CN.UTF-8 +``` + +### 6. 从 OpenClaw 迁移 + +如果你之前使用 OpenClaw,可以使用迁移工具: + +```bash +# 迁移所有内容:代理、记忆、技能、配置 +openfang migrate --from openclaw + +# 从特定路径迁移 +openfang migrate --from openclaw --path ~/.openclaw + +# 先试运行查看变更 +openfang migrate --from openclaw --dry-run +``` + +--- + +## 进阶配置 + +### 配置 Hands + +Hands 是 OpenFang 的核心创新,每个 Hand 是一个预构建的自主能力包: + +```toml +# ~/.openfang/data/hands/researcher.toml + +[hand] +name = "researcher" +description = "深度研究助手" +enabled = true + +[hand.schedule] +# 执行模式:continuous, periodic, manual +mode = "manual" +# 定时执行(cron 表达式) +# cron = "0 9 * * *" # 每天早上 9 点 + +[hand.config] +# 最大搜索深度 +max_depth = 5 +# 输出格式 +output_format = "markdown" +# 引用格式 +citation_style = "apa" +``` + +### 配置 MCP 服务器 + +```toml +# ~/.openfang/config.toml + +[[mcp_servers]] +name = "filesystem" +command = "mcp-filesystem" +args = ["--root", "/path/to/allowed/dir"] + +[[mcp_servers]] +name = "postgres" +command = "mcp-postgres" +env = { DATABASE_URL = "postgresql://localhost/mydb" } +``` + +### 配置渠道适配器 + +```toml +# ~/.openfang/config.toml + +[[channels]] +type = "feishu" +enabled = true + +[channels.config] +app_id = "cli_xxx" +app_secret_env = "FEISHU_APP_SECRET" +# 加密密钥(可选) +encrypt_key_env = "FEISHU_ENCRYPT_KEY" +``` + +--- + +## 性能调优 + +### 内存优化 + +```toml +[memory] +# 会话压缩阈值(token 数) +compaction_threshold = 80000 +# 保留最近消息数 +keep_recent = 20 +# 向量嵌入缓存大小 +embedding_cache_size = 1000 +``` + +### 并发优化 + +```toml +[runtime] +# 最大并发工具调用 +max_concurrent_tools = 10 +# 工具执行超时(秒) +tool_timeout = 60 +# Agent 循环最大迭代 +max_iterations = 50 +``` + +--- + +## 日志与监控 + +### 查看日志 + +```bash +# 实时日志 +openfang logs -f + +# 按级别过滤 +openfang logs --level error + +# 按时间范围 +openfang logs --since "2024-01-01" --until "2024-01-02" +``` + +### 监控指标 + +```bash +# 系统状态 +openfang status + +# 详细健康检查 +openfang doctor --verbose + +# 使用统计 +openfang usage --daily +``` + +--- + +## 相关链接 + +- [OpenFang 官方文档](https://openfang.sh/) +- [GitHub 仓库](https://github.com/RightNow-AI/openfang) +- [中文模型配置](./chinese-models.md) +- [ZCLAW 主文档](../../README.md) + +--- + +## 获取帮助 + +- **命令行帮助**:`openfang --help` 或 `openfang --help` +- **GitHub Issues**:https://github.com/RightNow-AI/openfang/issues +- **社区讨论**:https://deepseek.club/t/topic/996 diff --git a/docs/setup/chinese-models.md b/docs/setup/chinese-models.md new file mode 100644 index 0000000..569474c --- /dev/null +++ b/docs/setup/chinese-models.md @@ -0,0 +1,472 @@ +# 中文模型配置指南 + +> 本文档详细介绍 OpenFang Kernel 支持的中文大语言模型,以及如何获取和配置 API Key。 + +--- + +## 支持的中文模型 + +OpenFang 通过 OpenAI 兼容 API 支持所有主流中文模型提供商: + +| 提供商 | 模型系列 | 特点 | 定价 | +|--------|----------|------|------| +| **智谱 AI** | GLM-4 | 国产领先,多模态支持 | 免费 + 付费 | +| **阿里云** | 通义千问 (Qwen) | 性价比高,企业级 | 按量计费 | +| **月之暗面** | Kimi | 长上下文(200K) | 按量计费 | +| **MiniMax** | 海螺 AI | 语音能力强 | 按量计费 | +| **百度** | 文心一言 | 企业应用广泛 | 按量计费 | +| **DeepSeek** | DeepSeek | 编程能力强,低价 | 极低价格 | +| **百川智能** | Baichuan | 中文优化 | 按量计费 | +| **上海 AI Lab** | 书生浦语 | 开源模型 | 免费 | + +--- + +## 1. 智谱 GLM + +### 模型列表 + +| 模型 | 上下文 | 特点 | 适用场景 | +|------|--------|------|----------| +| `glm-4-flash` | 128K | 快速响应,免费额度 | 日常对话、快速问答 | +| `glm-4` | 128K | 旗舰模型 | 复杂任务、推理 | +| `glm-4-plus` | 128K | 增强版 | 专业应用 | +| `glm-4-air` | 128K | 轻量版 | 简单任务 | +| `glm-4v` | 8K | 多模态(图像理解) | 图像分析 | +| `glm-4-long` | 1M | 超长上下文 | 长文档处理 | + +### API Key 获取 + +1. 访问 [智谱开放平台](https://open.bigmodel.cn/) +2. 注册/登录账号 +3. 进入「API Keys」页面 +4. 点击「创建 API Key」 + +**免费额度**:新用户赠送 1000 万 tokens + +### 配置示例 + +```toml +[model.zhipu] +provider = "zhipu" +model = "glm-4-flash" +api_key_env = "ZHIPU_API_KEY" +base_url = "https://open.bigmodel.cn/api/paas/v4" +``` + +```bash +# 设置环境变量 +export ZHIPU_API_KEY="your-zhipu-api-key" +``` + +--- + +## 2. 通义千问 (Qwen) + +### 模型列表 + +| 模型 | 上下文 | 特点 | 适用场景 | +|------|--------|------|----------| +| `qwen-turbo` | 8K | 快速版 | 快速问答 | +| `qwen-plus` | 32K | 增强版 | 复杂任务 | +| `qwen-max` | 32K | 旗舰版 | 高质量输出 | +| `qwen-max-longcontext` | 200K | 长上下文 | 长文档 | +| `qwen-vl-plus` | 8K | 多模态 | 图像理解 | +| `qwen-vl-max` | 8K | 多模态增强 | 高精度图像 | + +### API Key 获取 + +1. 访问 [阿里云百炼](https://dashscope.console.aliyun.com/) +2. 登录阿里云账号 +3. 开通「灵积模型服务」 +4. 获取 API Key + +**免费额度**:部分模型有免费试用 + +### 配置示例 + +```toml +[model.qwen] +provider = "openai-compat" +model = "qwen-turbo" +api_key_env = "DASHSCOPE_API_KEY" +base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1" +``` + +```bash +# 设置环境变量 +export DASHSCOPE_API_KEY="your-dashscope-api-key" +``` + +--- + +## 3. Kimi (Moonshot) + +### 模型列表 + +| 模型 | 上下文 | 特点 | 适用场景 | +|------|--------|------|----------| +| `moonshot-v1-8k` | 8K | 基础版 | 日常对话 | +| `moonshot-v1-32k` | 32K | 长上下文 | 中等文档 | +| `moonshot-v1-128k` | 128K | 超长上下文 | 长文档分析 | + +### API Key 获取 + +1. 访问 [Moonshot AI 开放平台](https://platform.moonshot.cn/) +2. 注册/登录账号 +3. 进入「API Key 管理」 +4. 创建新的 API Key + +**免费额度**:新用户赠送 15 元体验金 + +### 配置示例 + +```toml +[model.kimi] +provider = "openai-compat" +model = "moonshot-v1-8k" +api_key_env = "MOONSHOT_API_KEY" +base_url = "https://api.moonshot.cn/v1" +``` + +```bash +# 设置环境变量 +export MOONSHOT_API_KEY="your-moonshot-api-key" +``` + +--- + +## 4. MiniMax + +### 模型列表 + +| 模型 | 上下文 | 特点 | 适用场景 | +|------|--------|------|----------| +| `abab6.5-chat` | 8K | 旗舰对话 | 通用对话 | +| `abab6.5s-chat` | 8K | 快速版 | 快速响应 | +| `abab6.5g-chat` | 8K | 通用版 | 平衡场景 | +| `abab5.5-chat` | 16K | 经典版 | 日常使用 | +| `abab5.5s-chat` | 16K | 轻量版 | 简单任务 | + +### API Key 获取 + +1. 访问 [MiniMax 开放平台](https://www.minimaxi.com/) +2. 注册/登录账号 +3. 进入「账户管理」->「API Key」 +4. 创建 API Key + +**注意**:MiniMax 需要同时配置 Group ID + +### 配置示例 + +```toml +[model.minimax] +provider = "openai-compat" +model = "abab6.5-chat" +api_key_env = "MINIMAX_API_KEY" +base_url = "https://api.minimax.chat/v1" + +[model.minimax.headers] +# MiniMax 需要 Group ID +"x-minimax-group-id" = "your-group-id" +``` + +```bash +# 设置环境变量 +export MINIMAX_API_KEY="your-minimax-api-key" +``` + +--- + +## 5. DeepSeek + +### 模型列表 + +| 模型 | 上下文 | 特点 | 适用场景 | +|------|--------|------|----------| +| `deepseek-chat` | 64K | 通用对话 | 日常使用 | +| `deepseek-coder` | 16K | 代码专精 | 编程任务 | +| `deepseek-reasoner` | 64K | 深度推理 | 复杂推理 | + +### API Key 获取 + +1. 访问 [DeepSeek 开放平台](https://platform.deepseek.com/) +2. 注册/登录账号 +3. 进入「API Keys」页面 +4. 创建 API Key + +**定价优势**:极低价格,性价比高 + +### 配置示例 + +```toml +[model.deepseek] +provider = "openai-compat" +model = "deepseek-chat" +api_key_env = "DEEPSEEK_API_KEY" +base_url = "https://api.deepseek.com" +``` + +```bash +# 设置环境变量 +export DEEPSEEK_API_KEY="your-deepseek-api-key" +``` + +--- + +## 6. 百度文心一言 + +### 模型列表 + +| 模型 | 上下文 | 特点 | 适用场景 | +|------|--------|------|----------| +| `ernie-4.0-8k` | 8K | 旗舰版 | 复杂任务 | +| `ernie-3.5-8k` | 8K | 标准版 | 日常使用 | +| `ernie-speed-8k` | 8K | 快速版 | 快速响应 | +| `ernie-lite-8k` | 8K | 轻量版 | 简单任务 | + +### API Key 获取 + +1. 访问 [百度智能云千帆平台](https://console.bce.baidu.com/qianfan/) +2. 登录百度账号 +3. 创建应用,获取 API Key 和 Secret Key + +**注意**:文心一言使用 access_token 认证,需要额外处理 + +### 配置示例 + +```toml +[model.wenxin] +provider = "openai-compat" +model = "ernie-4.0-8k" +api_key_env = "WENXIN_ACCESS_TOKEN" +base_url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions" +``` + +--- + +## 7. 百川智能 + +### 模型列表 + +| 模型 | 上下文 | 特点 | 适用场景 | +|------|--------|------|----------| +| `Baichuan4` | 128K | 旗舰版 | 复杂任务 | +| `Baichuan3-Turbo` | 32K | 快速版 | 日常使用 | +| `Baichuan3-Turbo-128k` | 128K | 长上下文 | 长文档 | + +### API Key 获取 + +1. 访问 [百川智能开放平台](https://platform.baichuan-ai.com/) +2. 注册/登录账号 +3. 获取 API Key + +### 配置示例 + +```toml +[model.baichuan] +provider = "openai-compat" +model = "Baichuan4" +api_key_env = "BAICHUAN_API_KEY" +base_url = "https://api.baichuan-ai.com/v1" +``` + +--- + +## 8. 本地模型 (Ollama) + +如果你想在本地运行开源中文模型: + +### 支持的开源模型 + +| 模型 | 参数量 | 内存需求 | 特点 | +|------|--------|----------|------| +| `qwen2:7b` | 7B | 8GB | 通用对话 | +| `qwen2:14b` | 14B | 16GB | 高质量输出 | +| `glm4:9b` | 9B | 12GB | 智谱开源版 | +| `deepseek-coder:6.7b` | 6.7B | 8GB | 代码专精 | + +### 安装 Ollama + +```bash +# macOS / Linux +curl -fsSL https://ollama.com/install.sh | sh + +# Windows +# 访问 https://ollama.com/download 下载安装包 +``` + +### 下载模型 + +```bash +# 下载通义千问 +ollama pull qwen2:7b + +# 下载 GLM4 +ollama pull glm4:9b +``` + +### 配置示例 + +```toml +[model.ollama] +provider = "openai-compat" +model = "qwen2:7b" +base_url = "http://localhost:11434/v1" +# 本地模型无需 API Key +api_key_env = "" +``` + +--- + +## 多模型配置 + +OpenFang 支持同时配置多个模型,并自动路由: + +```toml +# ~/.openfang/config.toml + +[model] +# 默认模型 +provider = "zhipu" +model = "glm-4-flash" + +# 备选模型 +[[model.alternates]] +name = "coding" +provider = "deepseek" +model = "deepseek-coder" +api_key_env = "DEEPSEEK_API_KEY" + +[[model.alternates]] +name = "long-context" +provider = "kimi" +model = "moonshot-v1-128k" +api_key_env = "MOONSHOT_API_KEY" + +[[model.alternates]] +name = "local" +provider = "openai-compat" +model = "qwen2:7b" +base_url = "http://localhost:11434/v1" + +# 模型路由规则 +[model.routing] +# 编程任务使用 DeepSeek Coder +coding = ["deepseek-coder", "glm-4"] +# 长文档使用 Kimi +long_context = ["moonshot-v1-128k", "glm-4-long"] +# 快速响应使用 Flash 或本地模型 +fast = ["glm-4-flash", "qwen2:7b"] +``` + +--- + +## 价格对比 + +| 模型 | 输入价格 (元/百万 tokens) | 输出价格 (元/百万 tokens) | +|------|---------------------------|---------------------------| +| GLM-4-Flash | 免费 | 免费 | +| GLM-4 | 100 | 100 | +| 通义千问-Turbo | 2 | 6 | +| 通义千问-Max | 40 | 120 | +| Kimi-8K | 12 | 12 | +| DeepSeek-Chat | 1 | 2 | +| DeepSeek-Coder | 1 | 2 | + +*价格仅供参考,以官方最新公告为准* + +--- + +## 最佳实践 + +### 1. 模型选择建议 + +| 场景 | 推荐模型 | 理由 | +|------|----------|------| +| 日常对话 | GLM-4-Flash | 免费且速度快 | +| 编程任务 | DeepSeek-Coder | 专业代码能力 | +| 长文档分析 | Kimi-128K | 超长上下文 | +| 复杂推理 | GLM-4 / Qwen-Max | 高质量输出 | +| 离线使用 | Ollama + Qwen2 | 本地运行 | + +### 2. API Key 安全 + +- 永远不要在代码或配置文件中硬编码 API Key +- 使用环境变量存储敏感信息 +- 定期轮换 API Key +- 为不同项目使用不同的 API Key +- 设置 API Key 使用额度限制 + +### 3. 成本控制 + +```toml +[metering] +# 每日最大花费(美元) +daily_budget = 5.0 +# 每个 Agent 每小时最大 tokens +hourly_token_limit = 100000 +# 超限行为:reject(拒绝)或 downgrade(降级) +on_limit = "downgrade" +# 降级到的模型 +fallback_model = "glm-4-flash" +``` + +--- + +## 常见问题 + +### Q: 如何测试 API Key 是否有效? + +```bash +# 使用 curl 测试智谱 API +curl -X POST https://open.bigmodel.cn/api/paas/v4/chat/completions \ + -H "Authorization: Bearer $ZHIPU_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"model": "glm-4-flash", "messages": [{"role": "user", "content": "你好"}]}' +``` + +### Q: 多个模型如何切换? + +在 Agent 配置中指定: + +```toml +[agent.my-agent] +[model] +provider = "deepseek" +model = "deepseek-coder" +``` + +### Q: 如何查看用量? + +```bash +# 查看今日用量 +openfang usage --today + +# 查看本月用量 +openfang usage --month + +# 按模型分组 +openfang usage --group-by model +``` + +### Q: API Key 泄露了怎么办? + +1. 立即在对应平台撤销泄露的 Key +2. 生成新的 API Key +3. 更新环境变量 +4. 检查账单是否有异常使用 + +--- + +## 相关链接 + +- [智谱开放平台](https://open.bigmodel.cn/) +- [阿里云百炼](https://dashscope.console.aliyun.com/) +- [Moonshot 平台](https://platform.moonshot.cn/) +- [MiniMax 开放平台](https://www.minimaxi.com/) +- [DeepSeek 平台](https://platform.deepseek.com/) +- [Ollama 官网](https://ollama.com/) + +--- + +*最后更新:2026 年 3 月* diff --git a/scripts/quick-start-dev.ps1 b/scripts/quick-start-dev.ps1 new file mode 100644 index 0000000..53eea9c --- /dev/null +++ b/scripts/quick-start-dev.ps1 @@ -0,0 +1,225 @@ +#Requires -Version 5.1 +<# +.SYNOPSIS + ZCLAW 开发环境快速启动脚本 + +.DESCRIPTION + 检查依赖、启动后端服务、启动桌面端开发环境 + +.PARAMETER SkipBackend + 跳过后端启动(假设后端已运行) + +.PARAMETER DesktopOnly + 仅启动桌面端 + +.PARAMETER Stop + 停止所有服务 + +.EXAMPLE + .\scripts\quick-start-dev.ps1 + .\scripts\quick-start-dev.ps1 -SkipBackend + .\scripts\quick-start-dev.ps1 -Stop +#> + +param( + [switch]$SkipBackend, + [switch]$DesktopOnly, + [switch]$Stop +) + +$ErrorActionPreference = "Stop" +$ProjectRoot = $PSScriptRoot | Split-Path -Parent + +# 颜色输出函数 +function Write-Step { + param([string]$Message) + Write-Host "`n[STEP] $Message" -ForegroundColor Cyan +} + +function Write-Success { + param([string]$Message) + Write-Host "[OK] $Message" -ForegroundColor Green +} + +function Write-Warning { + param([string]$Message) + Write-Host "[WARN] $Message" -ForegroundColor Yellow +} + +function Write-Error { + param([string]$Message) + Write-Host "[ERROR] $Message" -ForegroundColor Red +} + +# 停止服务 +if ($Stop) { + Write-Step "停止所有服务..." + + # 停止 OpenFang + $openfang = Get-Process -Name "openfang" -ErrorAction SilentlyContinue + if ($openfang) { + Stop-Process -Name "openfang" -Force -ErrorAction SilentlyContinue + Write-Success "OpenFang 已停止" + } + + # 停止 Vite + $vite = Get-Process -Name "node" -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowTitle -like "*vite*" -or $_.CommandLine -like "*vite*" } + if ($vite) { + $vite | Stop-Process -Force -ErrorAction SilentlyContinue + Write-Success "Vite 进程已停止" + } + + # 调用项目的停止脚本 + $stopScript = Join-Path $ProjectRoot "start-all.ps1" + if (Test-Path $stopScript) { + & $stopScript -Stop + } + + Write-Success "所有服务已停止" + exit 0 +} + +Write-Host "========================================" -ForegroundColor Cyan +Write-Host " ZCLAW Development Quick Start" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan + +# 1. 检查 Node.js +Write-Step "检查 Node.js..." +try { + $nodeVersion = node -v + if ($nodeVersion -match "v(\d+)") { + $majorVersion = [int]$Matches[1] + if ($majorVersion -lt 18) { + Write-Error "Node.js 版本过低: $nodeVersion (需要 18+)" + Write-Host "请从 https://nodejs.org 安装最新版本" + exit 1 + } + Write-Success "Node.js $nodeVersion" + } +} catch { + Write-Error "未找到 Node.js,请从 https://nodejs.org 安装" + exit 1 +} + +# 2. 检查 pnpm +Write-Step "检查 pnpm..." +try { + $pnpmVersion = pnpm -v + Write-Success "pnpm $pnpmVersion" +} catch { + Write-Warning "未找到 pnpm,正在安装..." + npm install -g pnpm + if ($LASTEXITCODE -ne 0) { + Write-Error "pnpm 安装失败" + exit 1 + } + Write-Success "pnpm 安装完成" +} + +# 3. 检查依赖安装 +Write-Step "检查依赖..." +$nodeModules = Join-Path $ProjectRoot "node_modules" +$desktopModules = Join-Path $ProjectRoot "desktop\node_modules" + +if (-not (Test-Path $nodeModules)) { + Write-Host "安装根目录依赖..." + Push-Location $ProjectRoot + pnpm install + Pop-Location +} + +if (-not (Test-Path $desktopModules)) { + Write-Host "安装桌面端依赖..." + Push-Location (Join-Path $ProjectRoot "desktop") + pnpm install + Pop-Location +} + +Write-Success "依赖已就绪" + +# 4. 检查/启动后端 +if (-not $SkipBackend -and -not $DesktopOnly) { + Write-Step "检查后端服务..." + + $backendRunning = $false + try { + $response = Invoke-WebRequest -Uri "http://127.0.0.1:50051/api/health" -TimeoutSec 2 -UseBasicParsing -ErrorAction SilentlyContinue + if ($response.StatusCode -eq 200) { + $backendRunning = $true + Write-Success "后端服务已运行" + } + } catch { + # 后端未运行 + } + + if (-not $backendRunning) { + Write-Host "启动 OpenFang 后端..." + + # 尝试多种方式启动 + $started = $false + + # 方式 1: 使用 openfang CLI + try { + $openfangCmd = Get-Command "openfang" -ErrorAction SilentlyContinue + if ($openfangCmd) { + Start-Process -FilePath "openfang" -ArgumentList "start" -NoNewWindow + $started = $true + } + } catch {} + + # 方式 2: 使用 pnpm 脚本 + if (-not $started) { + $startScript = Join-Path $ProjectRoot "start-all.ps1" + if (Test-Path $startScript) { + Start-Process -FilePath "powershell" -ArgumentList "-ExecutionPolicy", "Bypass", "-File", $startScript -NoNewWindow + $started = $true + } + } + + if (-not $started) { + Write-Error "无法启动后端服务" + Write-Host "请手动启动 OpenFang:" + Write-Host " openfang start" + Write-Host " 或运行 start-all.ps1" + exit 1 + } + + # 等待后端启动 + Write-Host "等待后端启动..." + $retries = 0 + $maxRetries = 15 + while ($retries -lt $maxRetries) { + Start-Sleep -Seconds 1 + try { + $response = Invoke-WebRequest -Uri "http://127.0.0.1:50051/api/health" -TimeoutSec 2 -UseBasicParsing -ErrorAction SilentlyContinue + if ($response.StatusCode -eq 200) { + Write-Success "后端服务启动成功" + break + } + } catch {} + $retries++ + Write-Host "." -NoNewline + } + + if ($retries -ge $maxRetries) { + Write-Error "后端启动超时" + Write-Host "请检查 OpenFang 是否正确安装" + exit 1 + } + } +} + +# 5. 启动开发环境 +Write-Step "启动开发环境..." + +Push-Location $ProjectRoot + +if ($DesktopOnly) { + Write-Host "仅启动桌面端..." + pnpm desktop +} else { + Write-Host "启动完整开发环境..." + pnpm start:dev +} + +Pop-Location diff --git a/scripts/quick-start.sh b/scripts/quick-start.sh new file mode 100644 index 0000000..61929a2 --- /dev/null +++ b/scripts/quick-start.sh @@ -0,0 +1,218 @@ +#!/bin/bash +# +# ZCLAW Development Quick Start Script +# +# Usage: +# ./scripts/quick-start.sh [options] +# +# Options: +# --skip-backend Skip backend startup (assume already running) +# --desktop-only Start desktop only +# --stop Stop all services +# --help Show this help message +# + +set -e + +PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +SKIP_BACKEND=false +DESKTOP_ONLY=false +STOP_SERVICES=false + +# Parse arguments +for arg in "$@"; do + case $arg in + --skip-backend) + SKIP_BACKEND=true + shift + ;; + --desktop-only) + DESKTOP_ONLY=true + shift + ;; + --stop) + STOP_SERVICES=true + shift + ;; + --help) + echo "ZCLAW Development Quick Start Script" + echo "" + echo "Usage: $0 [options]" + echo "" + echo "Options:" + echo " --skip-backend Skip backend startup" + echo " --desktop-only Start desktop only" + echo " --stop Stop all services" + echo " --help Show this help" + exit 0 + ;; + *) + echo "Unknown option: $arg" + exit 1 + ;; + esac +done + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +# Output functions +step() { + echo -e "\n${CYAN}[STEP]${NC} $1" +} + +success() { + echo -e "${GREEN}[OK]${NC} $1" +} + +warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Stop services +if [ "$STOP_SERVICES" = true ]; then + step "Stopping all services..." + + # Kill OpenFang processes + pkill -f "openfang" 2>/dev/null || true + + # Kill Vite processes + pkill -f "vite" 2>/dev/null || true + + # Kill Tauri processes + pkill -f "tauri" 2>/dev/null || true + + success "All services stopped" + exit 0 +fi + +echo -e "${CYAN}========================================${NC}" +echo -e "${CYAN} ZCLAW Development Quick Start${NC}" +echo -e "${CYAN}========================================${NC}" + +# 1. Check Node.js +step "Checking Node.js..." +if ! command -v node &> /dev/null; then + error "Node.js not found" + echo "Please install from https://nodejs.org" + exit 1 +fi + +NODE_VERSION=$(node -v | sed 's/v//') +MAJOR_VERSION=$(echo "$NODE_VERSION" | cut -d. -f1) + +if [ "$MAJOR_VERSION" -lt 18 ]; then + error "Node.js version too low: v$NODE_VERSION (requires 18+)" + echo "Please upgrade from https://nodejs.org" + exit 1 +fi + +success "Node.js $(node -v)" + +# 2. Check pnpm +step "Checking pnpm..." +if ! command -v pnpm &> /dev/null; then + warn "pnpm not found, installing..." + npm install -g pnpm + if [ $? -ne 0 ]; then + error "Failed to install pnpm" + exit 1 + fi +fi +success "pnpm $(pnpm -v)" + +# 3. Check and install dependencies +step "Checking dependencies..." + +if [ ! -d "$PROJECT_ROOT/node_modules" ]; then + echo "Installing root dependencies..." + cd "$PROJECT_ROOT" + pnpm install +fi + +if [ ! -d "$PROJECT_ROOT/desktop/node_modules" ]; then + echo "Installing desktop dependencies..." + cd "$PROJECT_ROOT/desktop" + pnpm install +fi + +success "Dependencies ready" + +# 4. Check/Start backend +if [ "$SKIP_BACKEND" = false ] && [ "$DESKTOP_ONLY" = false ]; then + step "Checking backend service..." + + BACKEND_RUNNING=false + + if curl -s --connect-timeout 2 "http://127.0.0.1:50051/api/health" > /dev/null 2>&1; then + BACKEND_RUNNING=true + success "Backend service already running" + fi + + if [ "$BACKEND_RUNNING" = false ]; then + echo "Starting OpenFang backend..." + + STARTED=false + + # Method 1: Use openfang CLI + if command -v openfang &> /dev/null; then + openfang start & + STARTED=true + fi + + # Method 2: Use the project's start script + if [ "$STARTED" = false ] && [ -f "$PROJECT_ROOT/start-all.sh" ]; then + "$PROJECT_ROOT/start-all.sh" & + STARTED=true + fi + + if [ "$STARTED" = false ]; then + error "Cannot start backend service" + echo "Please start OpenFang manually:" + echo " openfang start" + exit 1 + fi + + # Wait for backend + echo "Waiting for backend to start..." + RETRIES=0 + MAX_RETRIES=15 + + while [ $RETRIES -lt $MAX_RETRIES ]; do + sleep 1 + if curl -s --connect-timeout 2 "http://127.0.0.1:50051/api/health" > /dev/null 2>&1; then + success "Backend started successfully" + break + fi + RETRIES=$((RETRIES + 1)) + printf "." + done + + if [ $RETRIES -ge $MAX_RETRIES ]; then + error "Backend startup timeout" + echo "Please check if OpenFang is properly installed" + exit 1 + fi + fi +fi + +# 5. Start development environment +step "Starting development environment..." + +cd "$PROJECT_ROOT" + +if [ "$DESKTOP_ONLY" = true ]; then + echo "Starting desktop only..." + pnpm desktop +else + echo "Starting full development environment..." + pnpm start:dev +fi