首页布局优化前
This commit is contained in:
307
docs/knowledge-base/openfang-configuration.md
Normal file
307
docs/knowledge-base/openfang-configuration.md
Normal file
@@ -0,0 +1,307 @@
|
||||
# OpenFang 配置指南
|
||||
|
||||
> 记录 OpenFang 配置文件位置、格式和最佳实践。
|
||||
|
||||
---
|
||||
|
||||
## 1. 配置文件位置
|
||||
|
||||
```
|
||||
~/.openfang/
|
||||
├── config.toml # 主配置文件(启动时读取)
|
||||
├── .env # API Key 环境变量
|
||||
├── secrets.env # 敏感信息(可选)
|
||||
├── daemon.json # 守护进程状态
|
||||
└── data/
|
||||
└── openfang.db # SQLite 数据库(持久化配置)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 主配置文件 (config.toml)
|
||||
|
||||
### 智谱 (Zhipu) 配置
|
||||
|
||||
```toml
|
||||
[default_model]
|
||||
provider = "zhipu"
|
||||
model = "glm-4-flash"
|
||||
api_key_env = "ZHIPU_API_KEY"
|
||||
|
||||
[kernel]
|
||||
data_dir = "C:\\Users\\szend\\.openfang\\data"
|
||||
|
||||
[memory]
|
||||
decay_rate = 0.05
|
||||
```
|
||||
|
||||
### 百炼 (Bailian) 配置
|
||||
|
||||
```toml
|
||||
[default_model]
|
||||
provider = "bailian"
|
||||
model = "qwen3.5-plus"
|
||||
api_key_env = "BAILIAN_API_KEY"
|
||||
|
||||
[kernel]
|
||||
data_dir = "C:\\Users\\szend\\.openfang\\data"
|
||||
|
||||
[memory]
|
||||
decay_rate = 0.05
|
||||
```
|
||||
|
||||
### 配置项说明
|
||||
|
||||
| 配置项 | 说明 | 示例值 |
|
||||
|--------|------|--------|
|
||||
| `default_model.provider` | 默认 LLM 提供商 | `zhipu`, `bailian`, `gemini` |
|
||||
| `default_model.model` | 默认模型名称 | `glm-4-flash`, `qwen3.5-plus` |
|
||||
| `default_model.api_key_env` | API Key 环境变量名 | `ZHIPU_API_KEY` |
|
||||
| `kernel.data_dir` | 数据目录 | `~/.openfang/data` |
|
||||
| `memory.decay_rate` | 记忆衰减率 | `0.05` |
|
||||
|
||||
---
|
||||
|
||||
## 3. API Key 配置
|
||||
|
||||
### 方式 1: .env 文件(推荐)
|
||||
|
||||
```bash
|
||||
# ~/.openfang/.env
|
||||
ZHIPU_API_KEY=sk-sp-xxxxx
|
||||
BAILIAN_API_KEY=sk-sp-xxxxx
|
||||
GEMINI_API_KEY=your_gemini_key
|
||||
DEEPSEEK_API_KEY=your_deepseek_key
|
||||
OPENAI_API_KEY=your_openai_key
|
||||
GROQ_API_KEY=your_groq_key
|
||||
```
|
||||
|
||||
### 方式 2: secrets.env 文件
|
||||
|
||||
```bash
|
||||
# ~/.openfang/secrets.env
|
||||
ZHIPU_API_KEY=sk-sp-xxxxx
|
||||
BAILIAN_API_KEY=sk-sp-xxxxx
|
||||
```
|
||||
|
||||
### 方式 3: 通过 API 设置
|
||||
|
||||
```bash
|
||||
# 设置智谱密钥
|
||||
curl -X POST http://127.0.0.1:50051/api/providers/zhipu/key \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"key":"your-zhipu-api-key"}'
|
||||
|
||||
# 设置百炼密钥
|
||||
curl -X POST http://127.0.0.1:50051/api/providers/bailian/key \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"key":"your-bailian-api-key"}'
|
||||
```
|
||||
|
||||
### 方式 4: 启动时指定环境变量
|
||||
|
||||
```bash
|
||||
# Windows PowerShell
|
||||
$env:ZHIPU_API_KEY = "your_key"
|
||||
./openfang.exe start
|
||||
|
||||
# Linux/macOS
|
||||
ZHIPU_API_KEY=sk-sp-xxx ./openfang start
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 支持的 Provider
|
||||
|
||||
### 4.1 国内 Provider
|
||||
|
||||
| Provider | 环境变量 | Base URL | 说明 |
|
||||
|----------|----------|----------|------|
|
||||
| zhipu | `ZHIPU_API_KEY` | `https://open.bigmodel.cn/api/paas/v4` | 智谱 GLM |
|
||||
| zhipu_coding | `ZHIPU_API_KEY` | `https://open.bigmodel.cn/api/coding/paas/v4` | 智谱 CodeGeeX |
|
||||
| bailian | `BAILIAN_API_KEY` | `https://coding.dashscope.aliyuncs.com/v1` | 百炼 Coding Plan |
|
||||
| qwen | `DASHSCOPE_API_KEY` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | 通义千问 |
|
||||
| volcengine | `VOLCENGINE_API_KEY` | `https://ark.cn-beijing.volces.com/api/v3` | 火山引擎 Doubao |
|
||||
| moonshot | `MOONSHOT_API_KEY` | `https://api.moonshot.ai/v1` | Moonshot Kimi |
|
||||
| deepseek | `DEEPSEEK_API_KEY` | `https://api.deepseek.com/v1` | DeepSeek |
|
||||
|
||||
### 4.2 国际 Provider
|
||||
|
||||
| Provider | 环境变量 | Base URL | 说明 |
|
||||
|----------|----------|----------|------|
|
||||
| openai | `OPENAI_API_KEY` | `https://api.openai.com/v1` | OpenAI GPT |
|
||||
| anthropic | `ANTHROPIC_API_KEY` | `https://api.anthropic.com` | Anthropic Claude |
|
||||
| gemini | `GEMINI_API_KEY` | `https://generativelanguage.googleapis.com` | Google Gemini |
|
||||
| groq | `GROQ_API_KEY` | `https://api.groq.com/openai/v1` | Groq |
|
||||
| mistral | `MISTRAL_API_KEY` | `https://api.mistral.ai/v1` | Mistral AI |
|
||||
| xai | `XAI_API_KEY` | `https://api.x.ai/v1` | xAI Grok |
|
||||
|
||||
### 4.3 本地 Provider
|
||||
|
||||
| Provider | 环境变量 | Base URL | 说明 |
|
||||
|----------|----------|----------|------|
|
||||
| ollama | - | `http://localhost:11434/v1` | Ollama 本地 |
|
||||
| vllm | - | `http://localhost:8000/v1` | vLLM 本地 |
|
||||
| lmstudio | - | `http://localhost:1234/v1` | LM Studio 本地 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 可用模型
|
||||
|
||||
### 智谱 (Zhipu)
|
||||
|
||||
| 模型 ID | 说明 | 适用场景 |
|
||||
|---------|------|----------|
|
||||
| glm-4-flash | 快速模型 | 日常对话、快速响应 |
|
||||
| glm-4-plus | 高级模型 | 复杂推理、深度分析 |
|
||||
| glm-4 | 标准模型 | 通用场景 |
|
||||
| glm-4-air | 轻量模型 | 简单任务 |
|
||||
|
||||
### 百炼 (Bailian)
|
||||
|
||||
| 模型 ID | 说明 | 适用场景 |
|
||||
|---------|------|----------|
|
||||
| qwen3.5-plus | 通用对话 | 日常对话 |
|
||||
| qwen3-coder-next | 编码专家 | 代码生成 |
|
||||
| glm-5-bailian | GLM-5 | 通用场景 |
|
||||
| minimax-m2.5-bailian | 支持视觉 | 多模态任务 |
|
||||
| kimi-k2.5-bailian | Kimi K2.5 | 长文本处理 |
|
||||
|
||||
### 其他推荐模型
|
||||
|
||||
| Provider | 模型 ID | 适用场景 |
|
||||
|----------|---------|----------|
|
||||
| gemini | gemini-2.5-flash | 开发任务 |
|
||||
| deepseek | deepseek-chat | 快速响应 |
|
||||
| groq | llama-3.1-70b | 开源模型 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 快速切换 Provider
|
||||
|
||||
### 方法 A: 修改 config.toml
|
||||
|
||||
```toml
|
||||
# 切换到智谱
|
||||
[default_model]
|
||||
provider = "zhipu"
|
||||
model = "glm-4-flash"
|
||||
api_key_env = "ZHIPU_API_KEY"
|
||||
|
||||
# 切换到百炼
|
||||
[default_model]
|
||||
provider = "bailian"
|
||||
model = "qwen3.5-plus"
|
||||
api_key_env = "BAILIAN_API_KEY"
|
||||
```
|
||||
|
||||
**重要**: 修改后必须完全重启 OpenFang!
|
||||
|
||||
### 方法 B: 创建不同配置的 Agent
|
||||
|
||||
```bash
|
||||
# 创建使用智谱的 Agent
|
||||
curl -X POST http://127.0.0.1:50051/api/agents \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"manifest_toml": "name = \"Zhipu Agent\"\nmodel_provider = \"zhipu\"\nmodel_name = \"glm-4-flash\""}'
|
||||
|
||||
# 创建使用百炼的 Agent
|
||||
curl -X POST http://127.0.0.1:50051/api/agents \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"manifest_toml": "name = \"Bailian Agent\"\nmodel_provider = \"bailian\"\nmodel_name = \"qwen3.5-plus\""}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 配置验证
|
||||
|
||||
### 检查当前配置
|
||||
|
||||
```bash
|
||||
# 检查 API 返回的配置
|
||||
curl -s http://127.0.0.1:50051/api/config
|
||||
|
||||
# 检查状态
|
||||
curl -s http://127.0.0.1:50051/api/status | grep -E "default_provider|default_model"
|
||||
|
||||
# 检查所有 Provider 状态
|
||||
curl -s http://127.0.0.1:50051/api/providers | grep -E "id|auth_status"
|
||||
```
|
||||
|
||||
### 检查 Agent 配置
|
||||
|
||||
```bash
|
||||
# 列出所有 Agent 及其 Provider
|
||||
curl -s http://127.0.0.1:50051/api/agents | grep -E "name|model_provider|ready"
|
||||
```
|
||||
|
||||
### 测试聊天
|
||||
|
||||
```bash
|
||||
# 测试 Agent 是否能正常响应
|
||||
curl -X POST "http://127.0.0.1:50051/api/agents/{agentId}/message" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"message":"Hello"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 重要注意事项
|
||||
|
||||
### 8.1 配置热重载限制
|
||||
|
||||
**关键**: OpenFang 将配置持久化在 SQLite 数据库中,`config.toml` 只在启动时读取。
|
||||
|
||||
- `/api/config/reload` **不会**更新已持久化的默认模型配置
|
||||
- 修改 `config.toml` 后必须**完全重启 OpenFang**
|
||||
|
||||
```bash
|
||||
# 正确的重启方式
|
||||
curl -X POST http://127.0.0.1:50051/api/shutdown
|
||||
# 然后手动启动
|
||||
./openfang.exe start
|
||||
```
|
||||
|
||||
### 8.2 Agent 创建时的 Provider
|
||||
|
||||
如果创建 Agent 时没有指定 Provider,OpenFang 会使用数据库中存储的默认配置,而不是 `config.toml` 中的配置。
|
||||
|
||||
### 8.3 API Key 验证
|
||||
|
||||
确保 API Key 格式正确:
|
||||
- 智谱: `sk-sp-xxxxx` 或 `xxxxx.xxxxx.xxxxx`
|
||||
- 百炼: `sk-xxxxx`
|
||||
|
||||
---
|
||||
|
||||
## 9. 常见问题
|
||||
|
||||
### Q: 修改 config.toml 后配置没有生效?
|
||||
|
||||
**A**: 必须完全重启 OpenFang,热重载不会更新持久化配置。
|
||||
|
||||
### Q: Agent 显示 ready: false?
|
||||
|
||||
**A**: 检查 Agent 使用的 Provider 是否配置了 API Key:
|
||||
```bash
|
||||
curl -s http://127.0.0.1:50051/api/agents | grep -E "auth_status|ready"
|
||||
```
|
||||
|
||||
### Q: 如何查看所有可用的 Provider?
|
||||
|
||||
**A**:
|
||||
```bash
|
||||
curl -s http://127.0.0.1:50051/api/providers
|
||||
```
|
||||
|
||||
### Q: 如何在不重启的情况下切换 Agent?
|
||||
|
||||
**A**: 前端可以通过选择不同 Provider 的 Agent 来切换,无需重启。
|
||||
|
||||
---
|
||||
|
||||
## 更新历史
|
||||
|
||||
| 日期 | 变更 |
|
||||
|------|------|
|
||||
| 2026-03-17 | 初始版本,记录配置热重载限制 |
|
||||
@@ -97,7 +97,92 @@ echo "GEMINI_API_KEY=your_key" >> ~/.openfang/.env
|
||||
|-------|--------|------|
|
||||
| General Assistant | zhipu | 通常已配置 |
|
||||
|
||||
### 2.2 流式响应不显示
|
||||
### 2.1.1 配置热重载限制(重要)
|
||||
|
||||
**症状**: 修改 `config.toml` 后,`/api/config` 和 `/api/status` 仍然返回旧配置
|
||||
|
||||
**根本原因**: OpenFang 将配置持久化在 SQLite 数据库中,`config.toml` 只在启动时读取
|
||||
|
||||
**验证问题**:
|
||||
```bash
|
||||
# 检查 config.toml 内容
|
||||
cat ~/.openfang/config.toml
|
||||
# 输出: provider = "zhipu"
|
||||
|
||||
# 检查 API 返回的配置
|
||||
curl -s http://127.0.0.1:50051/api/config
|
||||
# 输出: {"default_model":{"provider":"bailian",...}} # 不一致!
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
1. **必须完全重启 OpenFang**(热重载 `/api/config/reload` 不会更新持久化配置)
|
||||
```bash
|
||||
# 方法 1: 通过 API 关闭(然后手动重启)
|
||||
curl -X POST http://127.0.0.1:50051/api/shutdown
|
||||
|
||||
# 方法 2: 使用 CLI
|
||||
./openfang.exe stop
|
||||
./openfang.exe start
|
||||
```
|
||||
|
||||
2. **验证配置已生效**:
|
||||
```bash
|
||||
curl -s http://127.0.0.1:50051/api/status | grep -E "default_provider|default_model"
|
||||
# 应输出: "default_provider":"zhipu"
|
||||
```
|
||||
|
||||
**配置文件位置**:
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `~/.openfang/config.toml` | 主配置(启动时读取) |
|
||||
| `~/.openfang/.env` | API Key 环境变量 |
|
||||
| `~/.openfang/secrets.env` | 敏感信息 |
|
||||
| `~/.openfang/data/openfang.db` | SQLite 数据库(持久化配置) |
|
||||
|
||||
**支持的 Provider**:
|
||||
| Provider | 环境变量 | 模型示例 |
|
||||
|----------|----------|----------|
|
||||
| zhipu | `ZHIPU_API_KEY` | glm-4-flash, GLM-4-Plus |
|
||||
| bailian | `BAILIAN_API_KEY` | qwen3.5-plus, qwen3-coder-next |
|
||||
| gemini | `GEMINI_API_KEY` | gemini-2.5-flash |
|
||||
| deepseek | `DEEPSEEK_API_KEY` | deepseek-chat |
|
||||
| openai | `OPENAI_API_KEY` | gpt-4, gpt-3.5-turbo |
|
||||
|
||||
### 2.2 Agent ID 获取失败导致无法对话
|
||||
|
||||
**症状**: Gateway 显示已连接,但发送消息无响应或报错 "No agent available"
|
||||
|
||||
**根本原因**: `fetchDefaultAgentId()` 使用错误的 API 端点
|
||||
|
||||
**错误代码**:
|
||||
```typescript
|
||||
// ❌ 错误 - /api/status 不返回 agents 字段
|
||||
const status = await this.restGet('/api/status');
|
||||
if (status?.agents && status.agents.length > 0) { ... }
|
||||
```
|
||||
|
||||
**修复代码**:
|
||||
```typescript
|
||||
// ✅ 正确 - 使用 /api/agents 端点
|
||||
const agents = await this.restGet<Array<{ id: string; name?: string; state?: string }>>('/api/agents');
|
||||
if (agents && agents.length > 0) {
|
||||
const runningAgent = agents.find(a => a.state === 'Running');
|
||||
this.defaultAgentId = (runningAgent || agents[0]).id;
|
||||
}
|
||||
```
|
||||
|
||||
**历史背景**: 这个问题与 OpenClaw 的握手认证问题类似,但根因不同:
|
||||
- OpenClaw: 需要 `cli/cli/operator` 身份 + Ed25519 配对
|
||||
- OpenFang: 不需要认证握手,但需要正确的 Agent UUID
|
||||
|
||||
**验证修复**:
|
||||
```bash
|
||||
# 确认 /api/agents 返回数据
|
||||
curl http://127.0.0.1:50051/api/agents
|
||||
# 应返回: [{ "id": "uuid", "name": "...", "state": "Running" }]
|
||||
```
|
||||
|
||||
### 2.3 流式响应不显示
|
||||
|
||||
**症状**: 消息发送后无响应或响应不完整
|
||||
|
||||
@@ -165,7 +250,94 @@ const messages = store.messages;
|
||||
|
||||
2. 检查 immer/persist 配置
|
||||
|
||||
### 3.2 流式消息累积错误
|
||||
### 3.2 切换 Agent 后对话消失
|
||||
|
||||
**症状**: 点击其他 Agent 后,之前的对话内容丢失
|
||||
|
||||
**根本原因**: `setCurrentAgent` 切换 Agent 时清空了 `messages`,但没有恢复该 Agent 之前的对话
|
||||
|
||||
**解决方案**:
|
||||
|
||||
修改 `chatStore.ts` 中的 `setCurrentAgent` 函数:
|
||||
```typescript
|
||||
setCurrentAgent: (agent) =>
|
||||
set((state) => {
|
||||
if (state.currentAgent?.id === agent.id) {
|
||||
return { currentAgent: agent };
|
||||
}
|
||||
|
||||
// Save current conversation before switching
|
||||
const conversations = upsertActiveConversation([...state.conversations], state);
|
||||
|
||||
// Try to find existing conversation for this agent
|
||||
const agentConversation = conversations.find(c => c.agentId === agent.id);
|
||||
|
||||
if (agentConversation) {
|
||||
// Restore the agent's previous conversation
|
||||
return {
|
||||
conversations,
|
||||
currentAgent: agent,
|
||||
messages: [...agentConversation.messages],
|
||||
sessionKey: agentConversation.sessionKey,
|
||||
currentConversationId: agentConversation.id,
|
||||
};
|
||||
}
|
||||
|
||||
// No existing conversation, start fresh
|
||||
return {
|
||||
conversations,
|
||||
currentAgent: agent,
|
||||
messages: [],
|
||||
sessionKey: null,
|
||||
currentConversationId: null,
|
||||
};
|
||||
}),
|
||||
```
|
||||
|
||||
修改 `partialize` 配置以保存 `currentAgentId`:
|
||||
```typescript
|
||||
partialize: (state) => ({
|
||||
conversations: state.conversations,
|
||||
currentModel: state.currentModel,
|
||||
currentAgentId: state.currentAgent?.id, // 添加此行
|
||||
currentConversationId: state.currentConversationId,
|
||||
}),
|
||||
```
|
||||
|
||||
添加 `onRehydrateStorage` 钩子恢复消息:
|
||||
```typescript
|
||||
onRehydrateStorage: () => (state) => {
|
||||
// Rehydrate Date objects from JSON strings
|
||||
if (state?.conversations) {
|
||||
for (const conv of state.conversations) {
|
||||
conv.createdAt = new Date(conv.createdAt);
|
||||
conv.updatedAt = new Date(conv.updatedAt);
|
||||
for (const msg of conv.messages) {
|
||||
msg.timestamp = new Date(msg.timestamp);
|
||||
msg.streaming = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore messages from current conversation if exists
|
||||
if (state?.currentConversationId && state.conversations) {
|
||||
const currentConv = state.conversations.find(c => c.id === state.currentConversationId);
|
||||
if (currentConv) {
|
||||
state.messages = [...currentConv.messages];
|
||||
state.sessionKey = currentConv.sessionKey;
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
**验证修复**:
|
||||
1. 与 Agent A 对话
|
||||
2. 切换到 Agent B
|
||||
3. 切换回 Agent A → 对话应恢复
|
||||
|
||||
**文件**: `desktop/src/store/chatStore.ts`
|
||||
|
||||
### 3.3 流式消息累积错误
|
||||
|
||||
**症状**: 流式内容显示不正确或重复
|
||||
|
||||
@@ -269,8 +441,125 @@ curl -s http://127.0.0.1:50051/api/hands | jq '.[] | {id, name, requirements_met
|
||||
|
||||
---
|
||||
|
||||
## 7. 新用户引导 (Onboarding)
|
||||
|
||||
### 7.1 首次使用引导流程
|
||||
|
||||
**需求**: 当用户第一次使用系统时,引导用户设置默认助手的人格信息(about me、you in my eye 等)。
|
||||
|
||||
**实现方案**:
|
||||
|
||||
1. **检测首次使用** - 使用 `useOnboarding` hook 检查 localStorage:
|
||||
```typescript
|
||||
// desktop/src/lib/use-onboarding.ts
|
||||
const ONBOARDING_COMPLETED_KEY = 'zclaw-onboarding-completed';
|
||||
const USER_PROFILE_KEY = 'zclaw-user-profile';
|
||||
|
||||
export function useOnboarding(): OnboardingState {
|
||||
// 检查 localStorage 是否有完成记录
|
||||
// 返回 { isNeeded, isLoading, markCompleted, resetOnboarding }
|
||||
}
|
||||
```
|
||||
|
||||
2. **引导向导** - 使用 `AgentOnboardingWizard` 组件:
|
||||
```typescript
|
||||
// App.tsx 中的集成
|
||||
if (showOnboarding) {
|
||||
return (
|
||||
<AgentOnboardingWizard
|
||||
isOpen={true}
|
||||
onClose={() => {
|
||||
markCompleted({ userName: 'User', userRole: 'user' });
|
||||
setShowOnboarding(false);
|
||||
}}
|
||||
onSuccess={(clone) => {
|
||||
markCompleted({
|
||||
userName: clone.userName || 'User',
|
||||
userRole: clone.userRole,
|
||||
});
|
||||
setCurrentAgent({
|
||||
id: clone.id,
|
||||
name: clone.name,
|
||||
icon: clone.emoji || '🦞',
|
||||
// ...
|
||||
});
|
||||
setShowOnboarding(false);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
3. **数据持久化** - 用户信息存储在 localStorage:
|
||||
```typescript
|
||||
interface UserProfile {
|
||||
userName: string;
|
||||
userRole?: string;
|
||||
completedAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
**文件位置**:
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `desktop/src/lib/use-onboarding.ts` | 引导状态管理 hook |
|
||||
| `desktop/src/components/AgentOnboardingWizard.tsx` | 5 步引导向导组件 |
|
||||
| `desktop/src/App.tsx` | 引导流程集成 |
|
||||
|
||||
**引导步骤**:
|
||||
1. 认识用户 - 收集用户名称和角色
|
||||
2. Agent 身份 - 设置助手名称、昵称、emoji
|
||||
3. 人格风格 - 选择沟通风格
|
||||
4. 使用场景 - 选择应用场景
|
||||
5. 工作环境 - 配置工作目录
|
||||
|
||||
### 7.2 Onboarding 创建 Agent 失败
|
||||
|
||||
**症状**: 首次使用引导完成后,点击"完成"按钮报错,Agent 创建失败
|
||||
|
||||
**根本原因**: Onboarding 应该**更新现有的默认 Agent**,而不是创建新的 Agent
|
||||
|
||||
**错误代码**:
|
||||
```typescript
|
||||
// ❌ 错误 - 总是尝试创建新 Agent
|
||||
const clone = await createClone(createOptions);
|
||||
```
|
||||
|
||||
**修复代码**:
|
||||
```typescript
|
||||
// ✅ 正确 - 如果存在现有 Agent 则更新
|
||||
let clone: Clone | undefined;
|
||||
|
||||
if (clones && clones.length > 0) {
|
||||
// 更新现有的默认 Agent
|
||||
clone = await updateClone(clones[0].id, personalityUpdates);
|
||||
} else {
|
||||
// 没有现有 Agent 才创建新的
|
||||
clone = await createClone(createOptions);
|
||||
}
|
||||
```
|
||||
|
||||
**文件**: `desktop/src/components/AgentOnboardingWizard.tsx`
|
||||
|
||||
**验证修复**:
|
||||
1. 清除 localStorage 中的 onboarding 标记
|
||||
2. 重新启动应用
|
||||
3. 完成引导流程 → 应该成功更新默认 Agent
|
||||
|
||||
---
|
||||
|
||||
## 8. 相关文档
|
||||
|
||||
- [OpenFang 配置指南](./openfang-configuration.md) - 配置文件位置、格式和最佳实践
|
||||
- [Agent 和 LLM 提供商配置](./agent-provider-config.md) - Agent 管理和 Provider 配置
|
||||
- [OpenFang WebSocket 协议](./openfang-websocket-protocol.md) - WebSocket 通信协议
|
||||
|
||||
---
|
||||
|
||||
## 更新历史
|
||||
|
||||
| 日期 | 变更 |
|
||||
|------|------|
|
||||
| 2026-03-17 | 添加首次使用引导流程 |
|
||||
| 2026-03-17 | 添加配置热重载限制问题 |
|
||||
| 2026-03-14 | 初始版本 |
|
||||
|
||||
Reference in New Issue
Block a user