Skip to main content

openclaw-bot-review-dashboard

A lightweight web dashboard for monitoring OpenClaw agents, models, sessions, and health status in real-time without a database

Ir para a instalação

Informações da origem

Repositório
reason-machines/hermes-skills
Última atividade na origem
17 de maio de 2026 às 16:21
Idioma detectado do SKILL.md
inglês
Estrelas
5
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
openclaw-bot-review-dashboard
description
A lightweight web dashboard for monitoring OpenClaw agents, models, sessions, and health status in real-time without a database
triggers
["how do I monitor my OpenClaw bots","set up OpenClaw dashboard","view OpenClaw agent status","monitor OpenClaw model usage and tokens","check OpenClaw session health","deploy OpenClaw monitoring dashboard","configure OpenClaw bot review interface","track OpenClaw agent performance"]
# OpenClaw Bot Review Dashboard > Skill by [ara.so](https://ara.so) — Hermes Skills collection. ## What It Does OpenClaw Bot Review Dashboard is a Next.js-based web interface that provides real-time monitoring for OpenClaw agents across multiple platforms (Feishu, Discord, etc.). It reads directly from `~/.openclaw/openclaw.json` and local session files to display: - Bot/agent status with model bindings and platform health - Model configurations with context windows and capabilities - Session management with token usage tracking - Statistics and trends (token consumption, response times) - Skill inventory (built-in, extension, custom) - Alert rules with notification support - Gateway health monitoring with auto-polling - Pixel-art office visualization of agents No database required — all data is derived from OpenClaw's local configuration. ## Installation ### Standard Setup ```bash # Clone the repository git clone https://github.com/xmanrui/OpenClaw-bot-review.git cd OpenClaw-bot-review # Install dependencies npm install # Start development server npm run start ``` The dashboard will be available at `http://localhost:3000`. ### Production Build ```bash # Build for production npm run build # Start production server npm run start ``` ### Docker Deployment ```bash # Build Docker image docker build -t openclaw-dashboard . # Run container with default OpenClaw path (~/.openclaw) docker run -d --name openclaw-dashboard \ -p 3000:3000 \ -v $HOME/.openclaw:/root/.openclaw:ro \ openclaw-dashboard # Run with custom OpenClaw config path docker run -d --name openclaw-dashboard \ -p 3000:3000 \ -e OPENCLAW_HOME=/opt/openclaw \ -v /path/to/openclaw:/opt/openclaw:ro \ openclaw-dashboard ``` ## Requirements - **Node.js**: 18+ required - **OpenClaw**: Must be installed with config at `~/.openclaw/openclaw.json` - **Platforms**: Works with Feishu, Discord, and other OpenClaw-supported platforms ## Configuration ### Environment Variables ```bash # Custom OpenClaw config path export OPENCLAW_HOME=/opt/openclaw # Port configuration (default: 3000) export PORT=3000 # Start with custom config OPENCLAW_HOME=/opt/openclaw npm run start ``` ### Directory Structure The dashboard expects the following OpenClaw directory structure: ``` ~/.openclaw/ ├── openclaw.json # Main configuration file ├── sessions/ # Session data per agent │ ├── agent1/ │ │ ├── session1.json │ │ └── session2.json │ └── agent2/ └── skills/ # Installed skills ``` ### OpenClaw Configuration The dashboard reads from `openclaw.json`: ```json { "agents": [ { "name": "my-agent", "emoji": "🤖", "model": "gpt-4", "platforms": { "feishu": { "app_id": "${FEISHU_APP_ID}", "app_secret": "${FEISHU_APP_SECRET}" } } } ], "models": { "gpt-4": { "provider": "openai", "api_key": "${OPENAI_API_KEY}", "context_window": 8192, "max_output": 4096 } }, "gateway": { "enabled": true, "port": 8080 } } ``` ## Key Features and Usage ### Bot Dashboard View all agents at a glance: ```typescript // The dashboard automatically reads from ~/.openclaw/openclaw.json // Each bot card shows: // - Name and emoji // - Bound model // - Platform status (Feishu, Discord, etc.) // - Session count // - Gateway health indicator ``` ### Model Management Monitor all configured models: ```typescript // Models page displays: // - Provider (OpenAI, Anthropic, etc.) // - Model name and version // - Context window size // - Max output tokens // - Reasoning support // - Per-model connectivity test ``` ### Session Monitoring Track active sessions per agent: ```typescript // Sessions are automatically detected from: // ~/.openclaw/sessions/{agent-name}/*.json // Each session shows: // - Type (DM, group, cron) // - Platform // - Token usage // - Last activity // - Connectivity test button ``` ### Auto-Refresh Configuration ```typescript // Available refresh intervals: // - Manual (no auto-refresh) // - 10 seconds // - 30 seconds // - 1 minute // - 5 minutes // - 10 minutes // Select from dropdown in top-right corner ``` ### Theme and Language ```typescript // Theme toggle: Light / Dark mode // Available in sidebar // Language toggle: English / 中文 // Available in top navigation ``` ## API Routes The dashboard includes Next.js API routes for reading OpenClaw data: ### Get All Bots ```typescript // pages/api/bots.ts import type { NextApiRequest, NextApiResponse } from 'next'; import { readOpenClawConfig } from '@/lib/openclaw'; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } try { const config = await readOpenClawConfig(); const bots = config.agents.map(agent => ({ name: agent.name, emoji: agent.emoji, model: agent.model, platforms: Object.keys(agent.platforms || {}), sessionCount: getSessionCount(agent.name), })); res.status(200).json({ bots }); } catch (error) { res.status(500).json({ error: 'Failed to read config' }); } } ``` ### Get Models ```typescript // pages/api/models.ts export default async function handler( req: NextApiRequest, res: NextApiResponse ) { const config = await readOpenClawConfig(); const models = Object.entries(config.models).map(([name, model]) => ({ name, provider: model.provider, contextWindow: model.context_window, maxOutput: model.max_output, reasoning: model.reasoning_support || false, })); res.status(200).json({ models }); } ``` ### Test Platform Connection ```typescript // pages/api/test/platform.ts export default async function handler( req: NextApiRequest, res: NextApiResponse ) { const { platform, agentName } = req.query; try { const result = await testPlatformConnection( platform as string, agentName as string ); res.status(200).json({ success: result.success, message: result.message }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } } ``` ### Gateway Health Check ```typescript // pages/api/gateway/health.ts export default async function handler( req: NextApiRequest, res: NextApiResponse ) { const config = await readOpenClawConfig(); if (!config.gateway?.enabled) { return res.status(200).json({ healthy: false, reason: 'disabled' }); } try { const port = config.gateway.port || 8080; const response = await fetch(`http://localhost:${port}/health`); const healthy = response.ok; res.status(200).json({ healthy, port }); } catch (error) { res.status(200).json({ healthy: false, reason: 'unreachable' }); } } ``` ## Common Patterns ### Reading OpenClaw Config ```typescript // lib/openclaw.ts import fs from 'fs/promises'; import path from 'path'; import os from 'os'; export interface OpenClawConfig { agents: Agent[]; models: Record<string, Model>; gateway?: Gateway; } export async function readOpenClawConfig(): Promise<OpenClawConfig> { const openclawHome = process.env.OPENCLAW_HOME || path.join(os.homedir(), '.openclaw'); const configPath = path.join(openclawHome, 'openclaw.json'); try { const content = await fs.readFile(configPath, 'utf-8'); return JSON.parse(content); } catch (error) { throw new Error(`Failed to read OpenClaw config: ${error.message}`); } } ``` ### Reading Session Data ```typescript // lib/sessions.ts export async function getAgentSessions(agentName: string) { const openclawHome = process.env.OPENCLAW_HOME || path.join(os.homedir(), '.openclaw'); const sessionsDir = path.join(openclawHome, 'sessions', agentName); try { const files = await fs.readdir(sessionsDir); const sessions = await Promise.all( files .filter(f => f.endsWith('.json')) .map(async file => { const content = await fs.readFile( path.join(sessionsDir, file), 'utf-8' ); return JSON.parse(content); }) ); return sessions; } catch (error) { return []; } } ``` ### Testing Platform Connection ```typescript // lib/test.ts export async function testPlatformConnection( platform: string, agentName: string ): Promise<{ success: boolean; message: string }> { const config = await readOpenClawConfig(); const agent = config.agents.find(a => a.name === agentName); if (!agent) { return { success: false, message: 'Agent not found' }; } const platformConfig = agent.platforms?.[platform]; if (!platformConfig) { return { success: false, message: `${platform} not configured` }; } if (platform === 'feishu') { // Test Feishu API try { const response = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ app_id: process.env[platformConfig.app_id] || platformConfig.app_id, app_secret: process.env[platformConfig.app_secret] || platformConfig.app_secret, }), }); const data = await response.json(); return { success: data.code === 0, message: data.code === 0 ? 'Connected' : data.msg, }; } catch (error) { return { success: false, message: error.message }; } } return { success: false, message: 'Platform test not implemented' }; } ``` ### Component Example: Bot Card ```typescript // components/BotCard.tsx import { useState } from 'react'; interface BotCardProps { bot: { name: string; emoji: string; model: string; platforms: string[]; sessionCount: number; }; } export default function BotCard({ bot }: BotCardProps) { const [isTestingPlatform, setIsTestingPlatform] = useState(false); const testPlatform = async (platform: string) => { setIsTestingPlatform(true); try { const res = await fetch( `/api/test/platform?platform=${platform}&agentName=${bot.name}` ); const data = await res.json(); alert(data.message); } finally { setIsTestingPlatform(false); } }; return ( <div className="border rounded-lg p-4 shadow-sm hover:shadow-md transition"> <div className="flex items-center gap-2 mb-2"> <span className="text-3xl">{bot.emoji}</span> <h3 className="text-lg font-semibold">{bot.name}</h3> </div> <div className="text-sm text-gray-600 dark:text-gray-400"> <p>Model: {bot.model}</p> <p>Sessions: {bot.sessionCount}</p> </div> <div className="mt-3 flex gap-2"> {bot.platforms.map(platform => ( <button key={platform} onClick={() => testPlatform(platform)} disabled={isTestingPlatform}
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub