openclaw-admin-vue

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenClaw Admin Vue Skill

OpenClaw Admin Vue Skill

Skill by ara.so — Hermes Skills collection.
OpenClaw Admin is a modern AI agent management platform built with Vue 3 that provides a comprehensive web interface for both OpenClaw Gateway and Hermes Agent. It enables visual management of AI agents, sessions, models, channels, skills, and includes a full-featured Web CLI terminal with session persistence.
ara.so开发的Skill——Hermes Skills合集。
OpenClaw Admin是基于Vue 3构建的现代化AI Agent管理平台,为OpenClaw Gateway和Hermes Agent提供全面的Web界面。它支持AI Agent、会话、模型、渠道、技能的可视化管理,并具备带会话持久化功能的全功能Web CLI终端。

What OpenClaw Admin Does

OpenClaw Admin功能介绍

  • Dual Gateway Support: Manages both OpenClaw Gateway and Hermes Agent from a single interface
  • Web CLI Terminal: Real terminal emulation using xterm.js with session persistence and reconnection
  • Multi-Agent Orchestration: Create and coordinate multiple AI agents for complex workflows
  • Real-time Monitoring: System resources, session states, token usage, and event streams
  • Channel Management: Configure QQ, Feishu, DingTalk, WeChat integrations
  • Skill Management: Install, update, and configure agent skills/plugins
  • Memory Management: Edit agent identity, personality (SOUL.md), and instructions
  • 双网关支持: 通过单一界面管理OpenClaw Gateway与Hermes Agent
  • Web CLI终端: 基于xterm.js实现真实终端模拟,支持会话持久化与重连
  • 多Agent编排: 创建并协调多个AI Agent完成复杂工作流
  • 实时监控: 系统资源、会话状态、令牌使用量与事件流监控
  • 渠道管理: 配置QQ、飞书、钉钉、微信集成
  • 技能管理: 安装、更新与配置Agent技能/插件
  • 内存管理: 编辑Agent身份、人格(SOUL.md)与指令

Installation

安装步骤

Prerequisites

前置依赖

bash
undefined
bash
undefined

Required

必填

node >= 18.0.0 npm >= 9.0.0
node >= 18.0.0 npm >= 9.0.0

For Hermes CLI terminal feature

用于Hermes CLI终端功能

python >= 3.10
python >= 3.10

Must be deployed on the same node as the gateway

必须部署在与网关同一节点

.env only supports 127.0.0.1 or localhost

.env仅支持127.0.0.1或localhost

undefined
undefined

Setup Steps

设置流程

bash
undefined
bash
undefined

Clone repository

克隆仓库

git clone https://github.com/itq5/OpenClaw-Admin.git cd OpenClaw-Admin
git clone https://github.com/itq5/OpenClaw-Admin.git cd OpenClaw-Admin

Install dependencies

安装依赖

npm install
npm install

Initialize environment configuration

初始化环境配置

cp .env.example .env
cp .env.example .env

Edit .env file

编辑.env文件

vim .env
undefined
vim .env
undefined

Environment Configuration

环境配置

bash
undefined
bash
undefined

.env

.env

Server Port

服务端口

VITE_PORT=3001
VITE_PORT=3001

OpenClaw Gateway Configuration

OpenClaw Gateway配置

VITE_OPENCLAW_WS_URL=ws://localhost:8081 VITE_OPENCLAW_HTTP_URL=http://localhost:8081
VITE_OPENCLAW_WS_URL=ws://localhost:8081 VITE_OPENCLAW_HTTP_URL=http://localhost:8081

Hermes Agent Configuration

Hermes Agent配置

VITE_HERMES_API_URL=http://localhost:8642 VITE_HERMES_WEB_URL=http://localhost:9119 VITE_HERMES_API_KEY=
VITE_HERMES_API_URL=http://localhost:8642 VITE_HERMES_WEB_URL=http://localhost:9119 VITE_HERMES_API_KEY=

CLI Terminal Configuration (for Hermes CLI)

CLI终端配置(用于Hermes CLI)

VITE_CLI_SESSION_DB=./cli-sessions.db
undefined
VITE_CLI_SESSION_DB=./cli-sessions.db
undefined

Development Mode

开发模式

bash
undefined
bash
undefined

Start frontend only

仅启动前端

npm run dev
npm run dev

Start backend only (for CLI terminal)

仅启动后端(用于CLI终端)

npm run dev:server
npm run dev:server

Start both frontend and backend

同时启动前端与后端

npm run dev:all
npm run dev:all
undefined
undefined

Production Build

生产构建

bash
undefined
bash
undefined

Build for production

生产环境构建

npm run build
npm run build

Start production server

启动生产服务

npm run start
npm run start

Access at configured port (default 3001)

访问配置端口(默认3001)

undefined
undefined

Hermes Agent Integration

Hermes Agent集成

Install Hermes Agent

安装Hermes Agent

bash
undefined
bash
undefined

Official installation script

官方安装脚本

Run configuration wizard

运行配置向导

hermes setup
undefined
hermes setup
undefined

Configure Hermes Agent

配置Hermes Agent

bash
undefined
bash
undefined

Configure AI model provider

配置AI模型提供商

hermes setup model
hermes setup model

Or edit ~/.hermes/.env directly

或直接编辑~/.hermes/.env

Example for OpenRouter:

OpenRouter示例:

OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
OPENROUTER_API_KEY=${OPENROUTER_API_KEY}

Example for Anthropic:

Anthropic示例:

ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}

Enable API Server

启用API服务

vim ~/.hermes/.env
vim ~/.hermes/.env

Add:

添加:

API_SERVER_ENABLED=true GATEWAY_ALLOW_ALL_USERS=true API_SERVER_KEY=${API_SERVER_KEY}
undefined
API_SERVER_ENABLED=true GATEWAY_ALLOW_ALL_USERS=true API_SERVER_KEY=${API_SERVER_KEY}
undefined

Start Hermes Gateway

启动Hermes网关

bash
undefined
bash
undefined

Install gateway

安装网关

hermes gateway install
hermes gateway install

Start gateway (background)

后台启动网关

hermes gateway start
hermes gateway start

Start Web UI dashboard

启动Web UI仪表盘

hermes dashboard
hermes dashboard

Verify services

验证服务

Key Features and API Usage

核心功能与API使用

OpenClaw Gateway Module

OpenClaw Gateway模块

Session Management API

会话管理API

typescript
// Create new session
import { sessionApi } from '@/api/openclaw/session'

const createSession = async () => {
  const response = await sessionApi.createSession({
    session_id: 'my-session',
    agent_id: 'default',
    metadata: {
      user_id: 'user123',
      channel: 'web'
    }
  })
  return response.data
}

// List sessions with filters
const listSessions = async () => {
  const sessions = await sessionApi.listSessions({
    agent_id: 'default',
    active: true,
    limit: 20
  })
  return sessions.data
}

// Reset session
await sessionApi.resetSession('session-id')

// Delete session
await sessionApi.deleteSession('session-id')
typescript
// 创建新会话
import { sessionApi } from '@/api/openclaw/session'

const createSession = async () => {
  const response = await sessionApi.createSession({
    session_id: 'my-session',
    agent_id: 'default',
    metadata: {
      user_id: 'user123',
      channel: 'web'
    }
  })
  return response.data
}

// 带过滤条件列出会话
const listSessions = async () => {
  const sessions = await sessionApi.listSessions({
    agent_id: 'default',
    active: true,
    limit: 20
  })
  return sessions.data
}

// 重置会话
await sessionApi.resetSession('session-id')

// 删除会话
await sessionApi.deleteSession('session-id')

Model Management API

模型管理API

typescript
import { modelApi } from '@/api/openclaw/model'

// Add model provider
const addModel = async () => {
  await modelApi.addModel({
    provider: 'openrouter',
    api_key: process.env.OPENROUTER_API_KEY,
    base_url: 'https://openrouter.ai/api/v1',
    models: ['anthropic/claude-3.5-sonnet']
  })
}

// Set default model
await modelApi.setDefaultModel('anthropic/claude-3.5-sonnet')

// Probe model availability
const probeResult = await modelApi.probeModel({
  provider: 'openrouter',
  model: 'anthropic/claude-3.5-sonnet',
  api_key: process.env.OPENROUTER_API_KEY
})
typescript
import { modelApi } from '@/api/openclaw/model'

// 添加模型提供商
const addModel = async () => {
  await modelApi.addModel({
    provider: 'openrouter',
    api_key: process.env.OPENROUTER_API_KEY,
    base_url: 'https://openrouter.ai/api/v1',
    models: ['anthropic/claude-3.5-sonnet']
  })
}

// 设置默认模型
await modelApi.setDefaultModel('anthropic/claude-3.5-sonnet')

// 探测模型可用性
const probeResult = await modelApi.probeModel({
  provider: 'openrouter',
  model: 'anthropic/claude-3.5-sonnet',
  api_key: process.env.OPENROUTER_API_KEY
})

Skill Management API

技能管理API

typescript
import { skillApi } from '@/api/openclaw/skill'

// List available skills
const skills = await skillApi.listSkills()

// Install skill
await skillApi.installSkill({
  name: 'web-search',
  version: 'latest'
})

// Update skill
await skillApi.updateSkill('web-search')

// Toggle skill visibility in chat
await skillApi.toggleSkillVisibility('web-search', true)
typescript
import { skillApi } from '@/api/openclaw/skill'

// 列出可用技能
const skills = await skillApi.listSkills()

// 安装技能
await skillApi.installSkill({
  name: 'web-search',
  version: 'latest'
})

// 更新技能
await skillApi.updateSkill('web-search')

// 切换技能在聊天中的可见性
await skillApi.toggleSkillVisibility('web-search', true)

Cron Task API

定时任务API

typescript
import { cronApi } from '@/api/openclaw/cron'

// Create scheduled task
const createTask = async () => {
  await cronApi.createTask({
    name: 'morning-report',
    schedule_type: 'cron',
    cron_expression: '0 9 * * *', // Every day at 9 AM
    prompt: 'Generate daily summary report',
    agent_id: 'default',
    enabled: true
  })
}

// List tasks
const tasks = await cronApi.listTasks()

// Trigger task manually
await cronApi.triggerTask('task-id')
typescript
import { cronApi } from '@/api/openclaw/cron'

// 创建定时任务
const createTask = async () => {
  await cronApi.createTask({
    name: 'morning-report',
    schedule_type: 'cron',
    cron_expression: '0 9 * * *', // 每天上午9点
    prompt: 'Generate daily summary report',
    agent_id: 'default',
    enabled: true
  })
}

// 列出任务
const tasks = await cronApi.listTasks()

// 手动触发任务
await cronApi.triggerTask('task-id')

Hermes Agent Module

Hermes Agent模块

Chat API Integration

聊天API集成

typescript
import { hermesApi } from '@/api/hermes'

// Send chat message (SSE streaming)
const sendMessage = async (message: string) => {
  const eventSource = hermesApi.chat.sendMessageStream({
    message,
    session_id: 'session-123',
    model: 'anthropic/claude-sonnet-4',
    stream: true
  })

  eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data)
    if (data.type === 'content') {
      console.log('Chunk:', data.content)
    } else if (data.type === 'tool_call') {
      console.log('Tool invoked:', data.tool_name)
    }
  }

  return eventSource
}

// Execute slash command
await hermesApi.chat.executeCommand('/skills enable web-search')
typescript
import { hermesApi } from '@/api/hermes'

// 发送聊天消息(SSE流式传输)
const sendMessage = async (message: string) => {
  const eventSource = hermesApi.chat.sendMessageStream({
    message,
    session_id: 'session-123',
    model: 'anthropic/claude-sonnet-4',
    stream: true
  })

  eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data)
    if (data.type === 'content') {
      console.log('Chunk:', data.content)
    } else if (data.type === 'tool_call') {
      console.log('Tool invoked:', data.tool_name)
    }
  }

  return eventSource
}

// 执行斜杠命令
await hermesApi.chat.executeCommand('/skills enable web-search')

Session Management

会话管理

typescript
import { hermesApi } from '@/api/hermes/session'

// List sessions
const sessions = await hermesApi.listSessions({
  page: 1,
  page_size: 20,
  search: 'keyword'
})

// Get session messages
const messages = await hermesApi.getSessionMessages('session-id')

// Delete session
await hermesApi.deleteSession('session-id')
typescript
import { hermesApi } from '@/api/hermes/session'

// 列出会话
const sessions = await hermesApi.listSessions({
  page: 1,
  page_size: 20,
  search: 'keyword'
})

// 获取会话消息
const messages = await hermesApi.getSessionMessages('session-id')

// 删除会话
await hermesApi.deleteSession('session-id')

Configuration Management

配置管理

typescript
import { hermesApi } from '@/api/hermes/config'

// Get configuration
const config = await hermesApi.getConfig()

// Update configuration
await hermesApi.updateConfig({
  model: 'anthropic/claude-sonnet-4',
  provider: 'anthropic',
  max_turns: 10,
  temperature: 0.7
})

// Get environment variables
const envVars = await hermesApi.getEnvVars()

// Set environment variable
await hermesApi.setEnvVar('MY_API_KEY', process.env.MY_API_KEY)
typescript
import { hermesApi } from '@/api/hermes/config'

// 获取配置
const config = await hermesApi.getConfig()

// 更新配置
await hermesApi.updateConfig({
  model: 'anthropic/claude-sonnet-4',
  provider: 'anthropic',
  max_turns: 10,
  temperature: 0.7
})

// 获取环境变量
const envVars = await hermesApi.getEnvVars()

// 设置环境变量
await hermesApi.setEnvVar('MY_API_KEY', process.env.MY_API_KEY)

Web CLI Terminal

Web CLI终端

Using the CLI Terminal UI

使用CLI终端UI

The CLI terminal provides a real terminal experience with full Hermes CLI support:
typescript
// Component usage
import CliTerminal from '@/components/hermes/cli/CliTerminal.vue'

// In your Vue component
<template>
  <CliTerminal
    :session-id="currentSessionId"
    :auto-connect="true"
    @session-created="handleSessionCreated"
  />
</template>
CLI终端提供完整Hermes CLI支持的真实终端体验:
typescript
// 组件使用
import CliTerminal from '@/components/hermes/cli/CliTerminal.vue'

// 在Vue组件中
<template>
  <CliTerminal
    :session-id="currentSessionId"
    :auto-connect="true"
    @session-created="handleSessionCreated"
  />
</template>

CLI Session API

CLI会话API

typescript
import axios from 'axios'

// Create CLI session with startup parameters
const createCliSession = async () => {
  const response = await axios.post('/api/cli/sessions', {
    name: 'My CLI Session',
    startup_params: {
      model: 'anthropic/claude-sonnet-4',
      provider: 'anthropic',
      skills: ['web-search', 'code-execution'],
      yolo: false,
      verbose: true
    }
  })
  return response.data.session_id
}

// List CLI sessions
const sessions = await axios.get('/api/cli/sessions')

// Reconnect to existing session
const reconnect = async (sessionId: string) => {
  const response = await axios.post(`/api/cli/sessions/${sessionId}/connect`)
  return response.data
}

// Send input to CLI
await axios.post(`/api/cli/sessions/${sessionId}/input`, {
  data: 'what skills are enabled?\n'
})

// Resize terminal
await axios.post(`/api/cli/sessions/${sessionId}/resize`, {
  cols: 120,
  rows: 30
})

// Destroy session
await axios.delete(`/api/cli/sessions/${sessionId}`)
typescript
import axios from 'axios'

// 创建带启动参数的CLI会话
const createCliSession = async () => {
  const response = await axios.post('/api/cli/sessions', {
    name: 'My CLI Session',
    startup_params: {
      model: 'anthropic/claude-sonnet-4',
      provider: 'anthropic',
      skills: ['web-search', 'code-execution'],
      yolo: false,
      verbose: true
    }
  })
  return response.data.session_id
}

// 列出CLI会话
const sessions = await axios.get('/api/cli/sessions')

// 重新连接到现有会话
const reconnect = async (sessionId: string) => {
  const response = await axios.post(`/api/cli/sessions/${sessionId}/connect`)
  return response.data
}

// 向CLI发送输入
await axios.post(`/api/cli/sessions/${sessionId}/input`, {
  data: 'what skills are enabled?\n'
})

// 调整终端尺寸
await axios.post(`/api/cli/sessions/${sessionId}/resize`, {
  cols: 120,
  rows: 30
})

// 销毁会话
await axios.delete(`/api/cli/sessions/${sessionId}`)

CLI Commands Available in Terminal

终端可用CLI命令

bash
undefined
bash
undefined

Hermes CLI-specific commands (work in Web Terminal)

Hermes CLI专属命令(在Web终端中生效)

/skills # List all skills /skills enable web-search # Enable a skill /tools # List available tools /cron list # List scheduled tasks /config # Show configuration /browser # Open browser tool /help # Show all commands
/skills # 列出所有技能 /skills enable web-search # 启用技能 /tools # 列出可用工具 /cron list # 列出定时任务 /config # 显示配置 /browser # 打开浏览器工具 /help # 显示所有命令

Regular slash commands

常规斜杠命令

/new # Start new session /model claude-sonnet-4 # Switch model /status # Show system status
undefined
/new # 启动新会话 /model claude-sonnet-4 # 切换模型 /status # 显示系统状态
undefined

WebSocket Event Handling

WebSocket事件处理

typescript
import { useOpenClawStore } from '@/stores/openclaw'

const store = useOpenClawStore()

// Connect to OpenClaw Gateway
await store.connect()

// Listen to events
store.on('session.message', (data) => {
  console.log('New message:', data)
})

store.on('system.stats', (stats) => {
  console.log('System stats:', stats)
})

// Send command
store.sendCommand({
  type: 'chat.send',
  data: {
    session_id: 'my-session',
    message: 'Hello AI'
  }
})
typescript
import { useOpenClawStore } from '@/stores/openclaw'

const store = useOpenClawStore()

// 连接到OpenClaw Gateway
await store.connect()

// 监听事件
store.on('session.message', (data) => {
  console.log('New message:', data)
})

store.on('system.stats', (stats) => {
  console.log('System stats:', stats)
})

// 发送命令
store.sendCommand({
  type: 'chat.send',
  data: {
    session_id: 'my-session',
    message: 'Hello AI'
  }
})

Configuration Patterns

配置模式

Connecting to Multiple Gateways

连接多个网关

typescript
// stores/settings.ts
export const useSettingsStore = defineStore('settings', {
  state: () => ({
    connections: {
      openclaw: {
        wsUrl: 'ws://localhost:8081',
        httpUrl: 'http://localhost:8081',
        enabled: true
      },
      hermes: {
        apiUrl: 'http://localhost:8642',
        webUrl: 'http://localhost:9119',
        apiKey: '',
        enabled: true
      }
    }
  }),
  actions: {
    async testConnection(type: 'openclaw' | 'hermes') {
      if (type === 'openclaw') {
        const ws = new WebSocket(this.connections.openclaw.wsUrl)
        return new Promise((resolve, reject) => {
          ws.onopen = () => { ws.close(); resolve(true) }
          ws.onerror = reject
        })
      } else {
        const response = await fetch(`${this.connections.hermes.webUrl}/api/status`)
        return response.ok
      }
    }
  }
})
typescript
// stores/settings.ts
export const useSettingsStore = defineStore('settings', {
  state: () => ({
    connections: {
      openclaw: {
        wsUrl: 'ws://localhost:8081',
        httpUrl: 'http://localhost:8081',
        enabled: true
      },
      hermes: {
        apiUrl: 'http://localhost:8642',
        webUrl: 'http://localhost:9119',
        apiKey: '',
        enabled: true
      }
    }
  }),
  actions: {
    async testConnection(type: 'openclaw' | 'hermes') {
      if (type === 'openclaw') {
        const ws = new WebSocket(this.connections.openclaw.wsUrl)
        return new Promise((resolve, reject) => {
          ws.onopen = () => { ws.close(); resolve(true) }
          ws.onerror = reject
        })
      } else {
        const response = await fetch(`${this.connections.hermes.webUrl}/api/status`)
        return response.ok
      }
    }
  }
})

Slash Command Implementation

斜杠命令实现

typescript
// components/chat/CommandProcessor.ts
export class CommandProcessor {
  private commands = {
    '/new': () => this.newSession(),
    '/model': (args: string) => this.switchModel(args),
    '/skills': () => this.listSkills(),
    '/status': () => this.showStatus(),
    '/help': () => this.showHelp()
  }

  async process(input: string) {
    const [command, ...args] = input.split(' ')
    const handler = this.commands[command]
    
    if (handler) {
      return await handler(args.join(' '))
    }
    return null
  }

  private async switchModel(modelName: string) {
    await modelApi.setDefaultModel(modelName)
    return `Switched to model: ${modelName}`
  }
}
typescript
// components/chat/CommandProcessor.ts
export class CommandProcessor {
  private commands = {
    '/new': () => this.newSession(),
    '/model': (args: string) => this.switchModel(args),
    '/skills': () => this.listSkills(),
    '/status': () => this.showStatus(),
    '/help': () => this.showHelp()
  }

  async process(input: string) {
    const [command, ...args] = input.split(' ')
    const handler = this.commands[command]
    
    if (handler) {
      return await handler(args.join(' '))
    }
    return null
  }

  private async switchModel(modelName: string) {
    await modelApi.setDefaultModel(modelName)
    return `Switched to model: ${modelName}`
  }
}

Real-time Dashboard Updates

实时仪表盘更新

typescript
// components/Dashboard.vue
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useDashboardStore } from '@/stores/dashboard'

const store = useDashboardStore()
const stats = ref({})
let updateInterval: number

onMounted(() => {
  // Initial load
  store.loadStats()
  
  // Poll every 5 seconds
  updateInterval = setInterval(() => {
    store.loadStats()
  }, 5000)
  
  // Listen to WebSocket events
  store.on('stats.update', (data) => {
    stats.value = data
  })
})

onUnmounted(() => {
  clearInterval(updateInterval)
})
</script>
typescript
// components/Dashboard.vue
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useDashboardStore } from '@/stores/dashboard'

const store = useDashboardStore()
const stats = ref({})
let updateInterval: number

onMounted(() => {
  // 初始加载
  store.loadStats()
  
  // 每5秒轮询
  updateInterval = setInterval(() => {
    store.loadStats()
  }, 5000)
  
  // 监听WebSocket事件
  store.on('stats.update', (data) => {
    stats.value = data
  })
})

onUnmounted(() => {
  clearInterval(updateInterval)
})
</script>

Common Patterns

通用模式

Agent Office Workflow

Agent办公工作流

typescript
import { agentOfficeApi } from '@/api/openclaw/agent-office'

// Create multi-agent scenario
const createScenario = async () => {
  const scenario = await agentOfficeApi.createScenario({
    name: 'Code Review Team',
    description: 'Collaborative code review workflow',
    agents: [
      { id: 'reviewer-1', role: 'senior-reviewer' },
      { id: 'reviewer-2', role: 'security-expert' },
      { id: 'coordinator', role: 'team-lead' }
    ]
  })

  // Assign task
  await agentOfficeApi.delegateTask(scenario.id, {
    agent_id: 'coordinator',
    task: 'Review pull request #123',
    context: { pr_url: 'https://github.com/...' }
  })

  return scenario
}
typescript
import { agentOfficeApi } from '@/api/openclaw/agent-office'

// 创建多Agent场景
const createScenario = async () => {
  const scenario = await agentOfficeApi.createScenario({
    name: 'Code Review Team',
    description: 'Collaborative code review workflow',
    agents: [
      { id: 'reviewer-1', role: 'senior-reviewer' },
      { id: 'reviewer-2', role: 'security-expert' },
      { id: 'coordinator', role: 'team-lead' }
    ]
  })

  // 分配任务
  await agentOfficeApi.delegateTask(scenario.id, {
    agent_id: 'coordinator',
    task: 'Review pull request #123',
    context: { pr_url: 'https://github.com/...' }
  })

  return scenario
}

Custom Skill Installation

自定义技能安装

typescript
// Install skill from custom source
const installCustomSkill = async () => {
  await skillApi.installSkill({
    name: 'my-custom-skill',
    source: 'github',
    repository: 'username/skill-repo',
    branch: 'main',
    path: 'skills/my-skill'
  })
}
typescript
// 从自定义源安装技能
const installCustomSkill = async () => {
  await skillApi.installSkill({
    name: 'my-custom-skill',
    source: 'github',
    repository: 'username/skill-repo',
    branch: 'main',
    path: 'skills/my-skill'
  })
}

Memory/Identity Management

内存/身份管理

typescript
import { memoryApi } from '@/api/openclaw/memory'

// Update agent SOUL (personality)
const updateSoul = async () => {
  await memoryApi.updateDocument('SOUL', `
typescript
import { memoryApi } from '@/api/openclaw/memory'

// 更新Agent人格(SOUL)
const updateSoul = async () => {
  await memoryApi.updateDocument('SOUL', `

Agent Personality

Agent Personality

You are a helpful coding assistant specialized in Vue.js and TypeScript.
You are a helpful coding assistant specialized in Vue.js and TypeScript.

Guidelines

Guidelines

  • Always provide type-safe examples
  • Explain Vue 3 Composition API patterns
  • Reference official documentation `) }
// Update agent instructions await memoryApi.updateDocument('AGENTS', `
  • Always provide type-safe examples
  • Explain Vue 3 Composition API patterns
  • Reference official documentation `) }
// 更新Agent指令 await memoryApi.updateDocument('AGENTS', `

Agent Instructions

Agent Instructions

Available Tools

Available Tools

  • code_executor: Run code snippets
  • web_search: Search the web
  • file_manager: Manage files `)
undefined
  • code_executor: Run code snippets
  • web_search: Search the web
  • file_manager: Manage files `)
undefined

Troubleshooting

故障排查

Connection Issues

连接问题

typescript
// Test OpenClaw Gateway connection
const testOpenClaw = async () => {
  try {
    const ws = new WebSocket('ws://localhost:8081')
    ws.onopen = () => console.log('✓ OpenClaw connected')
    ws.onerror = (err) => console.error('✗ OpenClaw error:', err)
  } catch (error) {
    console.error('Cannot connect to OpenClaw:', error)
    // Check: Is gateway running? Correct port? Firewall?
  }
}

// Test Hermes API connection
const testHermes = async () => {
  try {
    const health = await fetch('http://localhost:8642/v1/health')
    const webUI = await fetch('http://localhost:9119/api/status')
    console.log('API Server:', health.ok ? '✓' : '✗')
    console.log('Web UI:', webUI.ok ? '✓' : '✗')
  } catch (error) {
    console.error('Cannot connect to Hermes:', error)
    // Check: hermes gateway start, hermes dashboard running
  }
}
typescript
// 测试OpenClaw Gateway连接
const testOpenClaw = async () => {
  try {
    const ws = new WebSocket('ws://localhost:8081')
    ws.onopen = () => console.log('✓ OpenClaw已连接')
    ws.onerror = (err) => console.error('✗ OpenClaw连接错误:', err)
  } catch (error) {
    console.error('无法连接到OpenClaw:', error)
    // 检查:网关是否运行?端口是否正确?防火墙是否拦截?
  }
}

// 测试Hermes API连接
const testHermes = async () => {
  try {
    const health = await fetch('http://localhost:8642/v1/health')
    const webUI = await fetch('http://localhost:9119/api/status')
    console.log('API服务:', health.ok ? '✓' : '✗')
    console.log('Web UI:', webUI.ok ? '✓' : '✗')
  } catch (error) {
    console.error('无法连接到Hermes:', error)
    // 检查:是否执行hermes gateway start,hermes dashboard是否运行
  }
}

CLI Terminal Not Starting

CLI终端无法启动

bash
undefined
bash
undefined

Check Python availability

检查Python可用性

which python3 python3 --version # Must be >= 3.10
which python3 python3 --version # 必须>=3.10

Check Hermes CLI installation

检查Hermes CLI安装

hermes --version
hermes --version

Check backend server logs

检查后端服务日志

npm run dev:server
npm run dev:server

Look for "CLI session manager initialized"

查找"CLI session manager initialized"

Verify database

验证数据库

ls -la cli-sessions.db
ls -la cli-sessions.db

Check process limits

检查进程限制

ulimit -n # Should be >= 1024
undefined
ulimit -n # 应>=1024
undefined

Session Persistence Issues

会话持久化问题

typescript
// Verify CLI session database
import Database from 'better-sqlite3'

const db = new Database('./cli-sessions.db')
const sessions = db.prepare('SELECT * FROM cli_sessions').all()
console.log('Active sessions:', sessions)

// Clear stuck sessions
db.prepare('DELETE FROM cli_sessions WHERE last_activity < ?')
  .run(Date.now() - 24 * 60 * 60 * 1000) // Older than 24h
typescript
// 验证CLI会话数据库
import Database from 'better-sqlite3'

const db = new Database('./cli-sessions.db')
const sessions = db.prepare('SELECT * FROM cli_sessions').all()
console.log('活跃会话:', sessions)

// 清理过期会话
db.prepare('DELETE FROM cli_sessions WHERE last_activity < ?')
  .run(Date.now() - 24 * 60 * 60 * 1000) // 超过24小时

WebSocket Reconnection

WebSocket重连

typescript
// Implement exponential backoff
class ResilientWebSocket {
  private reconnectDelay = 1000
  private maxDelay = 30000

  connect() {
    this.ws = new WebSocket(this.url)
    
    this.ws.onerror = () => {
      setTimeout(() => {
        this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxDelay)
        this.connect()
      }, this.reconnectDelay)
    }

    this.ws.onopen = () => {
      this.reconnectDelay = 1000 // Reset on success
    }
  }
}
typescript
// 实现指数退避重连
class ResilientWebSocket {
  private reconnectDelay = 1000
  private maxDelay = 30000

  connect() {
    this.ws = new WebSocket(this.url)
    
    this.ws.onerror = () => {
      setTimeout(() => {
        this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxDelay)
        this.connect()
      }, this.reconnectDelay)
    }

    this.ws.onopen = () => {
      this.reconnectDelay = 1000 // 连接成功后重置延迟
    }
  }
}

CORS Issues

CORS问题

javascript
// server/index.js - Backend server configuration
app.use(cors({
  origin: process.env.VITE_FRONTEND_URL || 'http://localhost:3001',
  credentials: true
}))
javascript
// server/index.js - 后端服务配置
app.use(cors({
  origin: process.env.VITE_FRONTEND_URL || 'http://localhost:3001',
  credentials: true
}))

Build Errors

构建错误

bash
undefined
bash
undefined

Clear cache and reinstall

清理缓存并重新安装

rm -rf node_modules package-lock.json npm install
rm -rf node_modules package-lock.json npm install

Check Node version

检查Node版本

node --version # Must be >= 18
node --version # 必须>=18

Build with verbose output

带详细输出构建

npm run build -- --mode production --debug
npm run build -- --mode production --debug

Check TypeScript errors

检查TypeScript错误

npx tsc --noEmit
undefined
npx tsc --noEmit
undefined

Model API Key Issues

模型API密钥问题

bash
undefined
bash
undefined

Verify Hermes configuration

验证Hermes配置

hermes config show
hermes config show

Test model directly

直接测试模型

hermes chat --model anthropic/claude-sonnet-4 "Hello"
hermes chat --model anthropic/claude-sonnet-4 "Hello"

Check API key in environment

检查环境变量中的API密钥

echo $ANTHROPIC_API_KEY
echo $ANTHROPIC_API_KEY

Update .env file (must be in ~/.hermes/.env)

更新.env文件(必须在~/.hermes/.env中)

vim ~/.hermes/.env
undefined
vim ~/.hermes/.env
undefined

Production Deployment

生产部署

bash
undefined
bash
undefined

Build optimized bundle

构建优化包

npm run build
npm run build

Use PM2 for process management

使用PM2进行进程管理

npm install -g pm2
npm install -g pm2

Start with PM2

通过PM2启动

pm2 start npm --name "openclaw-admin" -- start
pm2 start npm --name "openclaw-admin" -- start

Monitor

监控

pm2 logs openclaw-admin pm2 monit
pm2 logs openclaw-admin pm2 monit

Auto-restart on system reboot

系统重启时自动启动

pm2 startup pm2 save
undefined
pm2 startup pm2 save
undefined

Nginx Reverse Proxy

Nginx反向代理

nginx
server {
    listen 80;
    server_name admin.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # WebSocket support
    location /ws {
        proxy_pass http://127.0.0.1:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}
nginx
server {
    listen 80;
    server_name admin.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # WebSocket支持
    location /ws {
        proxy_pass http://127.0.0.1:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

Additional Resources

额外资源