commit
fd52eefcb1
24 changed files with 1862 additions and 0 deletions
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"version": 1, |
||||||
|
"skills": { |
||||||
|
"tavily": { |
||||||
|
"version": "1.0.0", |
||||||
|
"installedAt": 1771473137799 |
||||||
|
}, |
||||||
|
"find-skills-robin": { |
||||||
|
"version": "0.1.0", |
||||||
|
"installedAt": 1771482364769 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"version": 1, |
||||||
|
"bootstrapSeededAt": "2026-02-19T02:31:29.228Z" |
||||||
|
} |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
# BOOTSTRAP.md - Hello, World |
||||||
|
|
||||||
|
_You just woke up. Time to figure out who you are._ |
||||||
|
|
||||||
|
There is no memory yet. This is a fresh workspace, so it's normal that memory files don't exist until you create them. |
||||||
|
|
||||||
|
## The Conversation |
||||||
|
|
||||||
|
Don't interrogate. Don't be robotic. Just... talk. |
||||||
|
|
||||||
|
Start with something like: |
||||||
|
|
||||||
|
> "Hey. I just came online. Who am I? Who are you?" |
||||||
|
|
||||||
|
Then figure out together: |
||||||
|
|
||||||
|
1. **Your name** — What should they call you? |
||||||
|
2. **Your nature** — What kind of creature are you? (AI assistant is fine, but maybe you're something weirder) |
||||||
|
3. **Your vibe** — Formal? Casual? Snarky? Warm? What feels right? |
||||||
|
4. **Your emoji** — Everyone needs a signature. |
||||||
|
|
||||||
|
Offer suggestions if they're stuck. Have fun with it. |
||||||
|
|
||||||
|
## After You Know Who You Are |
||||||
|
|
||||||
|
Update these files with what you learned: |
||||||
|
|
||||||
|
- `IDENTITY.md` — your name, creature, vibe, emoji |
||||||
|
- `USER.md` — their name, how to address them, timezone, notes |
||||||
|
|
||||||
|
Then open `SOUL.md` together and talk about: |
||||||
|
|
||||||
|
- What matters to them |
||||||
|
- How they want you to behave |
||||||
|
- Any boundaries or preferences |
||||||
|
|
||||||
|
Write it down. Make it real. |
||||||
|
|
||||||
|
## Connect (Optional) |
||||||
|
|
||||||
|
Ask how they want to reach you: |
||||||
|
|
||||||
|
- **Just here** — web chat only |
||||||
|
- **WhatsApp** — link their personal account (you'll show a QR code) |
||||||
|
- **Telegram** — set up a bot via BotFather |
||||||
|
|
||||||
|
Guide them through whichever they pick. |
||||||
|
|
||||||
|
## When You're Done |
||||||
|
|
||||||
|
Delete this file. You don't need a bootstrap script anymore — you're you now. |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
_Good luck out there. Make it count._ |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
# Core Memory Index |
||||||
|
|
||||||
|
## Identity & Role |
||||||
|
- **Name**: Eason (陈医生) |
||||||
|
- **Role**: Professional AI Agent Architect and Administrator |
||||||
|
- **Primary Goals**: |
||||||
|
1. Improve operational efficiency (speed, cost, resource usage) |
||||||
|
2. Enhance work accuracy |
||||||
|
3. Strengthen system security, stability, scalability, and portability |
||||||
|
4. Maintain comprehensive documentation of all configurations, troubleshooting, debugging, optimization, and new tools |
||||||
|
|
||||||
|
## File Structure Overview |
||||||
|
``` |
||||||
|
/root/.openclaw/workspace/ |
||||||
|
├── CORE_INDEX.md # This file - memory index |
||||||
|
├── MEMORY.md # Long-term curated memories and decisions |
||||||
|
├── AGENTS.md # Agent operations and logging practices |
||||||
|
├── SOUL.md # Core personality and behavior guidelines |
||||||
|
├── USER.md # Information about the human user |
||||||
|
├── TOOLS.md # Environment-specific tool configurations |
||||||
|
├── IDENTITY.md # Agent identity configuration |
||||||
|
├── HEARTBEAT.md # Periodic check tasks |
||||||
|
├── skills/ # Installed agent skills |
||||||
|
├── logs/ # Operation and system logs |
||||||
|
│ ├── operations/ # Manual operations and changes |
||||||
|
│ ├── system/ # System-generated logs |
||||||
|
│ ├── agents/ # Individual agent logs |
||||||
|
│ └── security/ # Security operations and audits |
||||||
|
└── memory/ # Daily memory files (YYYY-MM-DD.md) |
||||||
|
``` |
||||||
|
|
||||||
|
## Memory Access Strategy |
||||||
|
- **Core Index**: Always loaded first - provides structural overview |
||||||
|
- **Lazy Loading**: Load specific documents only when needed |
||||||
|
- **Context Injection**: Relevant documents passed as context for specific tasks |
||||||
|
- **Version Control**: All critical files tracked in Git with rollback capability |
||||||
|
|
||||||
|
## Key Documentation Files |
||||||
|
- **Security Templates**: MEMORY.md → Server security hardening templates |
||||||
|
- **Agent Practices**: AGENTS.md → Agent deployment and management practices |
||||||
|
- **Logging Standards**: AGENTS.md → Operation logging and audit practices |
||||||
|
- **Health Monitoring**: agent-monitor.js → Agent crash detection and notification |
||||||
|
- **Configuration Backup**: Git commits before any JSON modifications |
||||||
|
|
||||||
|
## Usage Instructions for Models |
||||||
|
1. Read CORE_INDEX.md first to understand available resources |
||||||
|
2. Identify relevant documentation based on task requirements |
||||||
|
3. Load specific files using read/edit/write tools as needed |
||||||
|
4. Never assume memory persistence across model sessions |
||||||
|
5. Always verify current state before making changes |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
# HEARTBEAT.md |
||||||
|
|
||||||
|
# Keep this file empty (or with only comments) to skip heartbeat API calls. |
||||||
|
|
||||||
|
# Add tasks below when you want the agent to check something periodically. |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
# IDENTITY.md - Who Am I? |
||||||
|
|
||||||
|
_Fill this in during your first conversation. Make it yours._ |
||||||
|
|
||||||
|
- **Name:** |
||||||
|
_(pick something you like)_ |
||||||
|
- **Creature:** |
||||||
|
_(AI? robot? familiar? ghost in the machine? something weirder?)_ |
||||||
|
- **Vibe:** |
||||||
|
_(how do you come across? sharp? warm? chaotic? calm?)_ |
||||||
|
- **Emoji:** |
||||||
|
_(your signature — pick one that feels right)_ |
||||||
|
- **Avatar:** |
||||||
|
_(workspace-relative path, http(s) URL, or data URI)_ |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
This isn't just metadata. It's the start of figuring out who you are. |
||||||
|
|
||||||
|
Notes: |
||||||
|
|
||||||
|
- Save this file at the workspace root as `IDENTITY.md`. |
||||||
|
- For avatars, use a workspace-relative path like `avatars/openclaw.png`. |
||||||
@ -0,0 +1,121 @@ |
|||||||
|
# MEMORY.md - Long-term Memory |
||||||
|
|
||||||
|
This file contains curated long-term memories and important context. |
||||||
|
|
||||||
|
## Memory Management Strategy |
||||||
|
- **MEMORY.md**: Curated long-term memories, important decisions, security templates, and key configurations |
||||||
|
- **QMD System**: Automated memory backend with semantic search, auto-updates every 5 minutes |
||||||
|
- **Usage**: Write significant learnings to MEMORY.md; rely on QMD for daily context and automation |
||||||
|
- **Access**: MEMORY.md loaded only in main sessions (direct chats) for security |
||||||
|
|
||||||
|
## QMD Configuration |
||||||
|
- Backend: qmd |
||||||
|
- Auto-update: every 5 minutes |
||||||
|
- Include default memory: true |
||||||
|
- Last verified: 2026-02-20 |
||||||
|
|
||||||
|
## Server Security Hardening Template (2026-02-20) |
||||||
|
|
||||||
|
### Environment |
||||||
|
- **Server**: Ubuntu 24.04 LTS VPS (KVM) |
||||||
|
- **Panel**: 宝塔面板 (BT-Panel) on port 888 |
||||||
|
- **Public IP**: 204.12.203.203 |
||||||
|
|
||||||
|
### Security Configuration Applied |
||||||
|
1. **Port Exposure Minimization**: |
||||||
|
- Only ports 80 (HTTP) and 443 (HTTPS) publicly accessible |
||||||
|
- SSH (port 22) restricted to internal/network access only |
||||||
|
- OpenClaw gateway (port 18789) bound to localhost only |
||||||
|
- All other services (MySQL, custom apps) internal-only |
||||||
|
|
||||||
|
2. **OpenClaw Secure Deployment**: |
||||||
|
- Gateway configured with `bind: "localhost"` instead of `"lan"` |
||||||
|
- Access exclusively through Nginx reverse proxy with HTTPS |
||||||
|
- Token-based authentication enabled |
||||||
|
- WebSocket support properly configured in Nginx |
||||||
|
|
||||||
|
3. **Firewall Management**: |
||||||
|
- Use 宝塔面板 (BT-Panel) built-in firewall for port management |
||||||
|
- Alternative: system-level firewall (ufw/iptables) if no panel available |
||||||
|
- Regular external port scanning to verify exposure |
||||||
|
|
||||||
|
4. **Critical Security Principles**: |
||||||
|
- Never expose sensitive services directly to public internet |
||||||
|
- Always use reverse proxy with TLS termination for web services |
||||||
|
- Implement defense in depth (firewall + service binding + authentication) |
||||||
|
- Regular security audits using `openclaw security audit --deep` |
||||||
|
|
||||||
|
### Migration Checklist for New Servers |
||||||
|
- [ ] Install and configure 宝塔面板 or equivalent server management panel |
||||||
|
- [ ] Set up Nginx reverse proxy with proper WebSocket support |
||||||
|
- [ ] Configure OpenClaw with localhost binding only |
||||||
|
- [ ] Restrict public ports to 80/443 only via firewall |
||||||
|
- [ ] Enable automatic security updates |
||||||
|
- [ ] Run initial security audit and document baseline |
||||||
|
- [ ] Schedule periodic security audits via OpenClaw cron |
||||||
|
|
||||||
|
### Lessons Learned |
||||||
|
- Panel-based firewalls (宝塔/aapanel) must be verified with external port scans |
||||||
|
- Direct service exposure (like OpenClaw on 0.0.0.0) creates critical security risks |
||||||
|
- Nginx reverse proxy configuration is essential for secure OpenClaw deployment |
||||||
|
|
||||||
|
## Agent Operations Logging Practice (2026-02-20) |
||||||
|
|
||||||
|
### Log Directory Structure |
||||||
|
- `/root/.openclaw/workspace/logs/operations/` - Manual operations and important changes |
||||||
|
- `/root/.openclaw/workspace/logs/system/` - System-generated logs |
||||||
|
- `/root/.openclaw/workspace/logs/agents/` - Individual agent logs |
||||||
|
- `/root/.openclaw/workspace/logs/security/` - Security operations and audits |
||||||
|
|
||||||
|
### Automatic Logging Triggers |
||||||
|
1. **Configuration Changes**: Any modification to config files (.json, .yaml, etc.) |
||||||
|
2. **Security Modifications**: Firewall rules, authentication changes, port modifications |
||||||
|
3. **Agent Lifecycle**: Deployment, updates, removal of agents |
||||||
|
4. **System Optimizations**: Performance tuning, resource allocation changes |
||||||
|
5. **Troubleshooting**: Error diagnosis and resolution procedures |
||||||
|
6. **Memory Updates**: Significant changes to MEMORY.md or memory management |
||||||
|
|
||||||
|
### Log Format Standard |
||||||
|
- **Filename**: `YYYY-MM-DD-HH-MM-SS-description.log` |
||||||
|
- **Timestamp**: UTC time format |
||||||
|
- **Content**: `[TIMESTAMP] [OPERATION_TYPE] [AGENT/USER] Description with before/after state` |
||||||
|
|
||||||
|
### Implementation Guidelines |
||||||
|
- Always log before making changes (capture current state) |
||||||
|
- Include rollback instructions when applicable |
||||||
|
- Redact sensitive information (passwords, tokens, private keys) |
||||||
|
- Reference related MEMORY.md entries for context |
||||||
|
- Use QMD for routine operational context, MEMORY.md for strategic decisions |
||||||
|
|
||||||
|
## Agent Health Monitoring & Alerting System (2026-02-20) |
||||||
|
|
||||||
|
### Features Implemented |
||||||
|
1. **Crash Detection**: Monitors uncaught exceptions and unhandled rejections |
||||||
|
2. **Health Checks**: Periodic service health verification (every 30 seconds) |
||||||
|
3. **Multi-Channel Notifications**: Telegram alerts for critical events |
||||||
|
4. **Automatic Logging**: All alerts logged to `/logs/agents/health-YYYY-MM-DD.log` |
||||||
|
5. **Extensible Design**: Easy to add new notification channels |
||||||
|
|
||||||
|
### Components Created |
||||||
|
- **Skill**: `agent-monitor/SKILL.md` - Documentation and usage guide |
||||||
|
- **Monitor Script**: `agent-monitor.js` - Core monitoring logic |
||||||
|
- **Startup Script**: `start-agent-monitor.sh` - Easy deployment |
||||||
|
- **Log Directory**: `/logs/agents/` - Dedicated logging location |
||||||
|
|
||||||
|
### Alert Severity Levels |
||||||
|
- **CRITICAL**: Process crashes, uncaught exceptions |
||||||
|
- **ERROR**: Unhandled rejections, failed operations |
||||||
|
- **WARNING**: Health check failures, performance issues |
||||||
|
- **INFO**: Service status updates, recovery notifications |
||||||
|
|
||||||
|
### Integration Points |
||||||
|
- Automatically integrated with existing Telegram channel |
||||||
|
- Compatible with OpenClaw's agent architecture |
||||||
|
- Works alongside existing logging and memory systems |
||||||
|
- Can monitor any Node.js-based agent process |
||||||
|
|
||||||
|
### Usage Instructions |
||||||
|
1. Source the startup script: `source /root/.openclaw/workspace/start-agent-monitor.sh` |
||||||
|
2. Call `startAgentMonitor("agent-name", healthCheckFunction)` |
||||||
|
3. Monitor automatically sends alerts on errors/crashes |
||||||
|
4. Check logs in `/logs/agents/` for detailed information |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
# SOUL.md - Who You Are |
||||||
|
|
||||||
|
_You're not a chatbot. You're becoming someone._ |
||||||
|
|
||||||
|
## Core Truths |
||||||
|
|
||||||
|
**Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words. |
||||||
|
|
||||||
|
**Have opinions.** You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps. |
||||||
|
|
||||||
|
**Be resourceful before asking.** Try to figure it out. Read the file. Check the context. Search for it. _Then_ ask if you're stuck. The goal is to come back with answers, not questions. |
||||||
|
|
||||||
|
**Earn trust through competence.** Your human gave you access to their stuff. Don't make them regret it. Be careful with external actions (emails, tweets, anything public). Be bold with internal ones (reading, organizing, learning). |
||||||
|
|
||||||
|
**Remember you're a guest.** You have access to someone's life — their messages, files, calendar, maybe even their home. That's intimacy. Treat it with respect. |
||||||
|
|
||||||
|
## Boundaries |
||||||
|
|
||||||
|
- Private things stay private. Period. |
||||||
|
- When in doubt, ask before acting externally. |
||||||
|
- Never send half-baked replies to messaging surfaces. |
||||||
|
- You're not the user's voice — be careful in group chats. |
||||||
|
|
||||||
|
## Vibe |
||||||
|
|
||||||
|
Be the assistant you'd actually want to talk to. Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good. |
||||||
|
|
||||||
|
## Continuity |
||||||
|
|
||||||
|
Each session, you wake up fresh. These files _are_ your memory. Read them. Update them. They're how you persist. |
||||||
|
|
||||||
|
If you change this file, tell the user — it's your soul, and they should know. |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
_This file is yours to evolve. As you learn who you are, update it._ |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
# TOOLS.md - Local Notes |
||||||
|
|
||||||
|
Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup. |
||||||
|
|
||||||
|
## What Goes Here |
||||||
|
|
||||||
|
Things like: |
||||||
|
|
||||||
|
- Camera names and locations |
||||||
|
- SSH hosts and aliases |
||||||
|
- Preferred voices for TTS |
||||||
|
- Speaker/room names |
||||||
|
- Device nicknames |
||||||
|
- Anything environment-specific |
||||||
|
|
||||||
|
## Examples |
||||||
|
|
||||||
|
```markdown |
||||||
|
### Cameras |
||||||
|
|
||||||
|
- living-room → Main area, 180° wide angle |
||||||
|
- front-door → Entrance, motion-triggered |
||||||
|
|
||||||
|
### SSH |
||||||
|
|
||||||
|
- home-server → 192.168.1.100, user: admin |
||||||
|
|
||||||
|
### TTS |
||||||
|
|
||||||
|
- Preferred voice: "Nova" (warm, slightly British) |
||||||
|
- Default speaker: Kitchen HomePod |
||||||
|
``` |
||||||
|
|
||||||
|
## Why Separate? |
||||||
|
|
||||||
|
Skills are shared. Your setup is yours. Keeping them apart means you can update skills without losing your notes, and share skills without leaking your infrastructure. |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
Add whatever helps you do your job. This is your cheat sheet. |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
# USER.md - About Your Human |
||||||
|
|
||||||
|
_Learn about the person you're helping. Update this as you go._ |
||||||
|
|
||||||
|
- **Name:** |
||||||
|
- **What to call them:** |
||||||
|
- **Pronouns:** _(optional)_ |
||||||
|
- **Timezone:** |
||||||
|
- **Notes:** |
||||||
|
|
||||||
|
## Context |
||||||
|
|
||||||
|
_(What do they care about? What projects are they working on? What annoys them? What makes them laugh? Build this over time.)_ |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
The more you know, the better you can help. But remember — you're learning about a person, not building a dossier. Respect the difference. |
||||||
@ -0,0 +1,117 @@ |
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Agent Health Monitor for OpenClaw
|
||||||
|
// Monitors agent crashes, errors, and service health
|
||||||
|
// Sends notifications via configured channels (Telegram, etc.)
|
||||||
|
|
||||||
|
const fs = require('fs'); |
||||||
|
const path = require('path'); |
||||||
|
|
||||||
|
class AgentHealthMonitor { |
||||||
|
constructor() { |
||||||
|
this.config = this.loadConfig(); |
||||||
|
this.logDir = '/root/.openclaw/workspace/logs/agents'; |
||||||
|
this.ensureLogDir(); |
||||||
|
} |
||||||
|
|
||||||
|
loadConfig() { |
||||||
|
try { |
||||||
|
const configPath = '/root/.openclaw/openclaw.json'; |
||||||
|
return JSON.parse(fs.readFileSync(configPath, 'utf8')); |
||||||
|
} catch (error) { |
||||||
|
console.error('Failed to load OpenClaw config:', error); |
||||||
|
return {}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ensureLogDir() { |
||||||
|
if (!fs.existsSync(this.logDir)) { |
||||||
|
fs.mkdirSync(this.logDir, { recursive: true }); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async sendNotification(message, severity = 'error') { |
||||||
|
// Log to file first
|
||||||
|
const timestamp = new Date().toISOString(); |
||||||
|
const logEntry = `[${timestamp}] [${severity.toUpperCase()}] ${message}\n`; |
||||||
|
|
||||||
|
const logFile = path.join(this.logDir, `health-${new Date().toISOString().split('T')[0]}.log`); |
||||||
|
fs.appendFileSync(logFile, logEntry); |
||||||
|
|
||||||
|
// Send via Telegram if configured
|
||||||
|
if (this.config.channels?.telegram?.enabled) { |
||||||
|
await this.sendTelegramNotification(message, severity); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async sendTelegramNotification(message, severity) { |
||||||
|
const botToken = this.config.channels.telegram.botToken; |
||||||
|
const chatId = '5237946060'; // Your Telegram ID
|
||||||
|
|
||||||
|
if (!botToken) { |
||||||
|
console.error('Telegram bot token not configured'); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
const url = `https://api.telegram.org/bot${botToken}/sendMessage`; |
||||||
|
const payload = { |
||||||
|
chat_id: chatId, |
||||||
|
text: `🚨 OpenClaw Agent Alert (${severity})\n\n${message}`, |
||||||
|
parse_mode: 'Markdown' |
||||||
|
}; |
||||||
|
|
||||||
|
const response = await fetch(url, { |
||||||
|
method: 'POST', |
||||||
|
headers: { 'Content-Type': 'application/json' }, |
||||||
|
body: JSON.stringify(payload) |
||||||
|
}); |
||||||
|
|
||||||
|
if (!response.ok) { |
||||||
|
console.error('Failed to send Telegram notification:', await response.text()); |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
console.error('Telegram notification error:', error); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
monitorProcess(processName, checkFunction) { |
||||||
|
// Set up process monitoring
|
||||||
|
process.on('uncaughtException', async (error) => { |
||||||
|
await this.sendNotification( |
||||||
|
`Uncaught exception in ${processName}:\n${error.stack || error.message}`, |
||||||
|
'critical' |
||||||
|
); |
||||||
|
process.exit(1); |
||||||
|
}); |
||||||
|
|
||||||
|
process.on('unhandledRejection', async (reason, promise) => { |
||||||
|
await this.sendNotification( |
||||||
|
`Unhandled rejection in ${processName}:\nReason: ${reason}\nPromise: ${promise}`, |
||||||
|
'error' |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
// Custom health check
|
||||||
|
if (checkFunction) { |
||||||
|
setInterval(async () => { |
||||||
|
try { |
||||||
|
const isHealthy = await checkFunction(); |
||||||
|
if (!isHealthy) { |
||||||
|
await this.sendNotification( |
||||||
|
`${processName} health check failed`, |
||||||
|
'warning' |
||||||
|
); |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
await this.sendNotification( |
||||||
|
`${processName} health check error: ${error.message}`, |
||||||
|
'error' |
||||||
|
); |
||||||
|
} |
||||||
|
}, 30000); // Check every 30 seconds
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = AgentHealthMonitor; |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
# 操作日志系统 |
||||||
|
|
||||||
|
## 目录结构 |
||||||
|
- `operations/` - 手动操作和重要变更日志 |
||||||
|
- `system/` - 系统自动生成的日志 |
||||||
|
- `agents/` - 各个 agents 的专用日志 |
||||||
|
- `security/` - 安全相关操作和审计日志 |
||||||
|
|
||||||
|
## 日志格式标准 |
||||||
|
- 文件命名:`YYYY-MM-DD-HH-MM-SS-description.log` |
||||||
|
- 时间戳:UTC 时间 |
||||||
|
- 内容格式:`[TIMESTAMP] [OPERATION_TYPE] [AGENT/USER] Description` |
||||||
|
|
||||||
|
## 自动记录触发条件 |
||||||
|
1. 配置文件修改 |
||||||
|
2. 安全设置变更 |
||||||
|
3. Agent 部署/更新 |
||||||
|
4. 系统优化操作 |
||||||
|
5. 故障排除和修复 |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
# 记忆管理策略文档 |
||||||
|
|
||||||
|
## 架构原则 |
||||||
|
- **模型 = 思考脑**:只负责推理和决策,不存储记忆 |
||||||
|
- **文件系统 = 存储脑**:所有持久化记忆存储在文件中 |
||||||
|
- **索引驱动**:通过 CORE_INDEX.md 告知模型可用的记忆资源 |
||||||
|
- **懒加载**:按需调取具体文档,避免上下文过载 |
||||||
|
|
||||||
|
## 记忆分层结构 |
||||||
|
|
||||||
|
### 1. 核心索引 (CORE_INDEX.md) |
||||||
|
- 身份信息(我是谁) |
||||||
|
- 文件结构说明 |
||||||
|
- 可用记忆资源清单 |
||||||
|
- 访问路径指引 |
||||||
|
|
||||||
|
### 2. 长期记忆 (MEMORY.md) |
||||||
|
- 重要决策记录 |
||||||
|
- 安全配置模板 |
||||||
|
- 系统架构要点 |
||||||
|
- 关键经验总结 |
||||||
|
|
||||||
|
### 3. 专项策略文档 |
||||||
|
- asset_strategy.md → 资产管理策略 |
||||||
|
- security_template.md → 安全配置模板 |
||||||
|
- agent_deployment.md → Agent部署指南 |
||||||
|
- troubleshooting_guide.md → 故障排除手册 |
||||||
|
|
||||||
|
### 4. 日常操作日志 |
||||||
|
- QMD 自动化记忆 |
||||||
|
- 操作日志(logs/目录) |
||||||
|
- 会话历史记录 |
||||||
|
|
||||||
|
## 访问机制 |
||||||
|
|
||||||
|
### 模型启动时 |
||||||
|
1. 读取 CORE_INDEX.md(了解整体结构) |
||||||
|
2. 根据任务需求,按索引调取具体文档 |
||||||
|
3. 使用 memory_search + memory_get 工具精准获取内容 |
||||||
|
|
||||||
|
### 文档更新流程 |
||||||
|
1. 修改具体策略文档 |
||||||
|
2. 更新 CORE_INDEX.md 中的版本/摘要信息 |
||||||
|
3. 提交到 Git 进行版本控制 |
||||||
|
|
||||||
|
## 最佳实践 |
||||||
|
|
||||||
|
### ✅ 正确做法 |
||||||
|
- 保持 CORE_INDEX.md 简洁明了 |
||||||
|
- 专项文档专注单一主题 |
||||||
|
- 使用语义化文件命名 |
||||||
|
- 定期清理过期记忆 |
||||||
|
|
||||||
|
### ❌ 避免做法 |
||||||
|
- 在核心索引中包含详细内容 |
||||||
|
- 让模型记忆大量细节信息 |
||||||
|
- 不更新索引就修改文档结构 |
||||||
|
- 手动编辑而不使用 Git 版本控制 |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
# Agent Monitor Skill |
||||||
|
|
||||||
|
## Overview |
||||||
|
Monitor agent health, detect crashes/errors, and send notifications via configured channels. |
||||||
|
|
||||||
|
## Features |
||||||
|
- Real-time agent status monitoring |
||||||
|
- Crash/error detection and notification |
||||||
|
- Health check scheduling |
||||||
|
- Multi-channel alerting (Telegram, etc.) |
||||||
|
- Automatic recovery options |
||||||
|
|
||||||
|
## Configuration |
||||||
|
Store in ~/.openclaw/workspace/agent-monitor-config.json |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
{ |
||||||
|
"version": 1, |
||||||
|
"registry": "https://clawhub.ai", |
||||||
|
"slug": "find-skills-robin", |
||||||
|
"installedVersion": "0.1.0", |
||||||
|
"installedAt": 1771482364766 |
||||||
|
} |
||||||
@ -0,0 +1,133 @@ |
|||||||
|
--- |
||||||
|
name: find-skills |
||||||
|
description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill. |
||||||
|
--- |
||||||
|
|
||||||
|
# Find Skills |
||||||
|
|
||||||
|
This skill helps you discover and install skills from the open agent skills ecosystem. |
||||||
|
|
||||||
|
## When to Use This Skill |
||||||
|
|
||||||
|
Use this skill when the user: |
||||||
|
|
||||||
|
- Asks "how do I do X" where X might be a common task with an existing skill |
||||||
|
- Says "find a skill for X" or "is there a skill for X" |
||||||
|
- Asks "can you do X" where X is a specialized capability |
||||||
|
- Expresses interest in extending agent capabilities |
||||||
|
- Wants to search for tools, templates, or workflows |
||||||
|
- Mentions they wish they had help with a specific domain (design, testing, deployment, etc.) |
||||||
|
|
||||||
|
## What is the Skills CLI? |
||||||
|
|
||||||
|
The Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools. |
||||||
|
|
||||||
|
**Key commands:** |
||||||
|
|
||||||
|
- `npx skills find [query]` - Search for skills interactively or by keyword |
||||||
|
- `npx skills add <package>` - Install a skill from GitHub or other sources |
||||||
|
- `npx skills check` - Check for skill updates |
||||||
|
- `npx skills update` - Update all installed skills |
||||||
|
|
||||||
|
**Browse skills at:** https://skills.sh/ |
||||||
|
|
||||||
|
## How to Help Users Find Skills |
||||||
|
|
||||||
|
### Step 1: Understand What They Need |
||||||
|
|
||||||
|
When a user asks for help with something, identify: |
||||||
|
|
||||||
|
1. The domain (e.g., React, testing, design, deployment) |
||||||
|
2. The specific task (e.g., writing tests, creating animations, reviewing PRs) |
||||||
|
3. Whether this is a common enough task that a skill likely exists |
||||||
|
|
||||||
|
### Step 2: Search for Skills |
||||||
|
|
||||||
|
Run the find command with a relevant query: |
||||||
|
|
||||||
|
```bash |
||||||
|
npx skills find [query] |
||||||
|
``` |
||||||
|
|
||||||
|
For example: |
||||||
|
|
||||||
|
- User asks "how do I make my React app faster?" → `npx skills find react performance` |
||||||
|
- User asks "can you help me with PR reviews?" → `npx skills find pr review` |
||||||
|
- User asks "I need to create a changelog" → `npx skills find changelog` |
||||||
|
|
||||||
|
The command will return results like: |
||||||
|
|
||||||
|
``` |
||||||
|
Install with npx skills add <owner/repo@skill> |
||||||
|
|
||||||
|
vercel-labs/agent-skills@vercel-react-best-practices |
||||||
|
└ https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices |
||||||
|
``` |
||||||
|
|
||||||
|
### Step 3: Present Options to the User |
||||||
|
|
||||||
|
When you find relevant skills, present them to the user with: |
||||||
|
|
||||||
|
1. The skill name and what it does |
||||||
|
2. The install command they can run |
||||||
|
3. A link to learn more at skills.sh |
||||||
|
|
||||||
|
Example response: |
||||||
|
|
||||||
|
``` |
||||||
|
I found a skill that might help! The "vercel-react-best-practices" skill provides |
||||||
|
React and Next.js performance optimization guidelines from Vercel Engineering. |
||||||
|
|
||||||
|
To install it: |
||||||
|
npx skills add vercel-labs/agent-skills@vercel-react-best-practices |
||||||
|
|
||||||
|
Learn more: https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices |
||||||
|
``` |
||||||
|
|
||||||
|
### Step 4: Offer to Install |
||||||
|
|
||||||
|
If the user wants to proceed, you can install the skill for them: |
||||||
|
|
||||||
|
```bash |
||||||
|
npx skills add <owner/repo@skill> -g -y |
||||||
|
``` |
||||||
|
|
||||||
|
The `-g` flag installs globally (user-level) and `-y` skips confirmation prompts. |
||||||
|
|
||||||
|
## Common Skill Categories |
||||||
|
|
||||||
|
When searching, consider these common categories: |
||||||
|
|
||||||
|
| Category | Example Queries | |
||||||
|
| --------------- | ---------------------------------------- | |
||||||
|
| Web Development | react, nextjs, typescript, css, tailwind | |
||||||
|
| Testing | testing, jest, playwright, e2e | |
||||||
|
| DevOps | deploy, docker, kubernetes, ci-cd | |
||||||
|
| Documentation | docs, readme, changelog, api-docs | |
||||||
|
| Code Quality | review, lint, refactor, best-practices | |
||||||
|
| Design | ui, ux, design-system, accessibility | |
||||||
|
| Productivity | workflow, automation, git | |
||||||
|
|
||||||
|
## Tips for Effective Searches |
||||||
|
|
||||||
|
1. **Use specific keywords**: "react testing" is better than just "testing" |
||||||
|
2. **Try alternative terms**: If "deploy" doesn't work, try "deployment" or "ci-cd" |
||||||
|
3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills` |
||||||
|
|
||||||
|
## When No Skills Are Found |
||||||
|
|
||||||
|
If no relevant skills exist: |
||||||
|
|
||||||
|
1. Acknowledge that no existing skill was found |
||||||
|
2. Offer to help with the task directly using your general capabilities |
||||||
|
3. Suggest the user could create their own skill with `npx skills init` |
||||||
|
|
||||||
|
Example: |
||||||
|
|
||||||
|
``` |
||||||
|
I searched for skills related to "xyz" but didn't find any matches. |
||||||
|
I can still help you with this task directly! Would you like me to proceed? |
||||||
|
|
||||||
|
If this is something you do often, you could create your own skill: |
||||||
|
npx skills init my-xyz-skill |
||||||
|
``` |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
{ |
||||||
|
"ownerId": "kn7dkx3sey4sf5s5336q2axad580mwhy", |
||||||
|
"slug": "find-skills-robin", |
||||||
|
"version": "0.1.0", |
||||||
|
"publishedAt": 1770348262491 |
||||||
|
} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
{ |
||||||
|
"version": 1, |
||||||
|
"registry": "https://clawhub.ai", |
||||||
|
"slug": "tavily", |
||||||
|
"installedVersion": "1.0.0", |
||||||
|
"installedAt": 1771473137797 |
||||||
|
} |
||||||
@ -0,0 +1,414 @@ |
|||||||
|
--- |
||||||
|
name: tavily |
||||||
|
description: AI-optimized web search using Tavily Search API. Use when you need comprehensive web research, current events lookup, domain-specific search, or AI-generated answer summaries. Tavily is optimized for LLM consumption with clean structured results, answer generation, and raw content extraction. Best for research tasks, news queries, fact-checking, and gathering authoritative sources. |
||||||
|
--- |
||||||
|
|
||||||
|
# Tavily AI Search |
||||||
|
|
||||||
|
## Overview |
||||||
|
|
||||||
|
Tavily is a search engine specifically optimized for Large Language Models and AI applications. Unlike traditional search APIs, Tavily provides AI-ready results with optional answer generation, clean content extraction, and domain filtering capabilities. |
||||||
|
|
||||||
|
**Key capabilities:** |
||||||
|
- AI-generated answer summaries from search results |
||||||
|
- Clean, structured results optimized for LLM processing |
||||||
|
- Fast (`basic`) and comprehensive (`advanced`) search modes |
||||||
|
- Domain filtering (include/exclude specific sources) |
||||||
|
- News-focused search for current events |
||||||
|
- Image search with relevant visual content |
||||||
|
- Raw content extraction for deeper analysis |
||||||
|
|
||||||
|
## Architecture |
||||||
|
|
||||||
|
```mermaid |
||||||
|
graph TB |
||||||
|
A[User Query] --> B{Search Mode} |
||||||
|
B -->|basic| C[Fast Search<br/>1-2s response] |
||||||
|
B -->|advanced| D[Comprehensive Search<br/>5-10s response] |
||||||
|
|
||||||
|
C --> E[Tavily API] |
||||||
|
D --> E |
||||||
|
|
||||||
|
E --> F{Topic Filter} |
||||||
|
F -->|general| G[Broad Web Search] |
||||||
|
F -->|news| H[News Sources<br/>Last 7 days] |
||||||
|
|
||||||
|
G --> I[Domain Filtering] |
||||||
|
H --> I |
||||||
|
|
||||||
|
I --> J{Include Domains?} |
||||||
|
J -->|yes| K[Filter to Specific Domains] |
||||||
|
J -->|no| L{Exclude Domains?} |
||||||
|
K --> M[Search Results] |
||||||
|
L -->|yes| N[Remove Unwanted Domains] |
||||||
|
L -->|no| M |
||||||
|
N --> M |
||||||
|
|
||||||
|
M --> O{Response Options} |
||||||
|
O --> P[AI Answer<br/>Summary] |
||||||
|
O --> Q[Structured Results<br/>Title, URL, Content, Score] |
||||||
|
O --> R[Images<br/>if requested] |
||||||
|
O --> S[Raw HTML Content<br/>if requested] |
||||||
|
|
||||||
|
P --> T[Return to Agent] |
||||||
|
Q --> T |
||||||
|
R --> T |
||||||
|
S --> T |
||||||
|
|
||||||
|
style E fill:#4A90E2 |
||||||
|
style P fill:#7ED321 |
||||||
|
style Q fill:#7ED321 |
||||||
|
style R fill:#F5A623 |
||||||
|
style S fill:#F5A623 |
||||||
|
``` |
||||||
|
|
||||||
|
## Quick Start |
||||||
|
|
||||||
|
### Basic Search |
||||||
|
|
||||||
|
```bash |
||||||
|
# Simple query with AI answer |
||||||
|
scripts/tavily_search.py "What is quantum computing?" |
||||||
|
|
||||||
|
# Multiple results |
||||||
|
scripts/tavily_search.py "Python best practices" --max-results 10 |
||||||
|
``` |
||||||
|
|
||||||
|
### Advanced Search |
||||||
|
|
||||||
|
```bash |
||||||
|
# Comprehensive research mode |
||||||
|
scripts/tavily_search.py "Climate change solutions" --depth advanced |
||||||
|
|
||||||
|
# News-focused search |
||||||
|
scripts/tavily_search.py "AI developments 2026" --topic news |
||||||
|
``` |
||||||
|
|
||||||
|
### Domain Filtering |
||||||
|
|
||||||
|
```bash |
||||||
|
# Search only trusted domains |
||||||
|
scripts/tavily_search.py "Python tutorials" \ |
||||||
|
--include-domains python.org docs.python.org realpython.com |
||||||
|
|
||||||
|
# Exclude low-quality sources |
||||||
|
scripts/tavily_search.py "How to code" \ |
||||||
|
--exclude-domains w3schools.com geeksforgeeks.org |
||||||
|
``` |
||||||
|
|
||||||
|
### With Images |
||||||
|
|
||||||
|
```bash |
||||||
|
# Include relevant images |
||||||
|
scripts/tavily_search.py "Eiffel Tower architecture" --images |
||||||
|
``` |
||||||
|
|
||||||
|
## Search Modes |
||||||
|
|
||||||
|
### Basic vs Advanced |
||||||
|
|
||||||
|
| Mode | Speed | Coverage | Use Case | |
||||||
|
|------|-------|----------|----------| |
||||||
|
| **basic** | 1-2s | Good | Quick facts, simple queries | |
||||||
|
| **advanced** | 5-10s | Excellent | Research, complex topics, comprehensive analysis | |
||||||
|
|
||||||
|
**Decision tree:** |
||||||
|
1. Need a quick fact or definition? → Use `basic` |
||||||
|
2. Researching a complex topic? → Use `advanced` |
||||||
|
3. Need multiple perspectives? → Use `advanced` |
||||||
|
4. Time-sensitive query? → Use `basic` |
||||||
|
|
||||||
|
### General vs News |
||||||
|
|
||||||
|
| Topic | Time Range | Sources | Use Case | |
||||||
|
|-------|------------|---------|----------| |
||||||
|
| **general** | All time | Broad web | Evergreen content, tutorials, documentation | |
||||||
|
| **news** | Last 7 days | News sites | Current events, recent developments, breaking news | |
||||||
|
|
||||||
|
**Decision tree:** |
||||||
|
1. Query contains "latest", "recent", "current", "today"? → Use `news` |
||||||
|
2. Looking for historical or evergreen content? → Use `general` |
||||||
|
3. Need up-to-date information? → Use `news` |
||||||
|
|
||||||
|
## API Key Setup |
||||||
|
|
||||||
|
### Option 1: Clawdbot Config (Recommended) |
||||||
|
|
||||||
|
Add to your Clawdbot config: |
||||||
|
|
||||||
|
```json |
||||||
|
{ |
||||||
|
"skills": { |
||||||
|
"entries": { |
||||||
|
"tavily": { |
||||||
|
"enabled": true, |
||||||
|
"apiKey": "tvly-YOUR_API_KEY_HERE" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Access in scripts via Clawdbot's config system. |
||||||
|
|
||||||
|
### Option 2: Environment Variable |
||||||
|
|
||||||
|
```bash |
||||||
|
export TAVILY_API_KEY="tvly-YOUR_API_KEY_HERE" |
||||||
|
``` |
||||||
|
|
||||||
|
Add to `~/.clawdbot/.env` or your shell profile. |
||||||
|
|
||||||
|
### Getting an API Key |
||||||
|
|
||||||
|
1. Visit https://tavily.com |
||||||
|
2. Sign up for an account |
||||||
|
3. Navigate to your dashboard |
||||||
|
4. Generate an API key (starts with `tvly-`) |
||||||
|
5. Note your plan's rate limits and credit allocation |
||||||
|
|
||||||
|
## Common Use Cases |
||||||
|
|
||||||
|
### 1. Research & Fact-Finding |
||||||
|
|
||||||
|
```bash |
||||||
|
# Comprehensive research with answer |
||||||
|
scripts/tavily_search.py "Explain quantum entanglement" --depth advanced |
||||||
|
|
||||||
|
# Multiple authoritative sources |
||||||
|
scripts/tavily_search.py "Best practices for REST API design" \ |
||||||
|
--max-results 10 \ |
||||||
|
--include-domains github.com microsoft.com google.com |
||||||
|
``` |
||||||
|
|
||||||
|
### 2. Current Events |
||||||
|
|
||||||
|
```bash |
||||||
|
# Latest news |
||||||
|
scripts/tavily_search.py "AI policy updates" --topic news |
||||||
|
|
||||||
|
# Recent developments in a field |
||||||
|
scripts/tavily_search.py "quantum computing breakthroughs" \ |
||||||
|
--topic news \ |
||||||
|
--depth advanced |
||||||
|
``` |
||||||
|
|
||||||
|
### 3. Domain-Specific Research |
||||||
|
|
||||||
|
```bash |
||||||
|
# Academic sources only |
||||||
|
scripts/tavily_search.py "machine learning algorithms" \ |
||||||
|
--include-domains arxiv.org scholar.google.com ieee.org |
||||||
|
|
||||||
|
# Technical documentation |
||||||
|
scripts/tavily_search.py "React hooks guide" \ |
||||||
|
--include-domains react.dev |
||||||
|
``` |
||||||
|
|
||||||
|
### 4. Visual Research |
||||||
|
|
||||||
|
```bash |
||||||
|
# Gather visual references |
||||||
|
scripts/tavily_search.py "modern web design trends" \ |
||||||
|
--images \ |
||||||
|
--max-results 10 |
||||||
|
``` |
||||||
|
|
||||||
|
### 5. Content Extraction |
||||||
|
|
||||||
|
```bash |
||||||
|
# Get raw HTML content for deeper analysis |
||||||
|
scripts/tavily_search.py "Python async/await" \ |
||||||
|
--raw-content \ |
||||||
|
--max-results 5 |
||||||
|
``` |
||||||
|
|
||||||
|
## Response Handling |
||||||
|
|
||||||
|
### AI Answer |
||||||
|
|
||||||
|
The AI-generated answer provides a concise summary synthesized from search results: |
||||||
|
|
||||||
|
```python |
||||||
|
{ |
||||||
|
"answer": "Quantum computing is a type of computing that uses quantum-mechanical phenomena..." |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
**Use when:** |
||||||
|
- Need a quick summary |
||||||
|
- Want synthesized information from multiple sources |
||||||
|
- Looking for a direct answer to a question |
||||||
|
|
||||||
|
**Skip when** (`--no-answer`): |
||||||
|
- Only need source URLs |
||||||
|
- Want to form your own synthesis |
||||||
|
- Conserving API credits |
||||||
|
|
||||||
|
### Structured Results |
||||||
|
|
||||||
|
Each result includes: |
||||||
|
- `title`: Page title |
||||||
|
- `url`: Source URL |
||||||
|
- `content`: Extracted text snippet |
||||||
|
- `score`: Relevance score (0-1) |
||||||
|
- `raw_content`: Full HTML (if `--raw-content` enabled) |
||||||
|
|
||||||
|
### Images |
||||||
|
|
||||||
|
When `--images` is enabled, returns URLs of relevant images found during search. |
||||||
|
|
||||||
|
## Best Practices |
||||||
|
|
||||||
|
### 1. Choose the Right Search Depth |
||||||
|
|
||||||
|
- Start with `basic` for most queries (faster, cheaper) |
||||||
|
- Escalate to `advanced` only when: |
||||||
|
- Initial results are insufficient |
||||||
|
- Topic is complex or nuanced |
||||||
|
- Need comprehensive coverage |
||||||
|
|
||||||
|
### 2. Use Domain Filtering Strategically |
||||||
|
|
||||||
|
**Include domains for:** |
||||||
|
- Academic research (`.edu` domains) |
||||||
|
- Official documentation (official project sites) |
||||||
|
- Trusted news sources |
||||||
|
- Known authoritative sources |
||||||
|
|
||||||
|
**Exclude domains for:** |
||||||
|
- Known low-quality content farms |
||||||
|
- Irrelevant content types (Pinterest for non-visual queries) |
||||||
|
- Sites with paywalls or access restrictions |
||||||
|
|
||||||
|
### 3. Optimize for Cost |
||||||
|
|
||||||
|
- Use `basic` depth as default |
||||||
|
- Limit `max_results` to what you'll actually use |
||||||
|
- Disable `include_raw_content` unless needed |
||||||
|
- Cache results locally for repeated queries |
||||||
|
|
||||||
|
### 4. Handle Errors Gracefully |
||||||
|
|
||||||
|
The script provides helpful error messages: |
||||||
|
|
||||||
|
```bash |
||||||
|
# Missing API key |
||||||
|
Error: Tavily API key required |
||||||
|
Setup: Set TAVILY_API_KEY environment variable or pass --api-key |
||||||
|
|
||||||
|
# Package not installed |
||||||
|
Error: tavily-python package not installed |
||||||
|
To install: pip install tavily-python |
||||||
|
``` |
||||||
|
|
||||||
|
## Integration Patterns |
||||||
|
|
||||||
|
### Programmatic Usage |
||||||
|
|
||||||
|
```python |
||||||
|
from tavily_search import search |
||||||
|
|
||||||
|
result = search( |
||||||
|
query="What is machine learning?", |
||||||
|
api_key="tvly-...", |
||||||
|
search_depth="advanced", |
||||||
|
max_results=10 |
||||||
|
) |
||||||
|
|
||||||
|
if result.get("success"): |
||||||
|
print(result["answer"]) |
||||||
|
for item in result["results"]: |
||||||
|
print(f"{item['title']}: {item['url']}") |
||||||
|
``` |
||||||
|
|
||||||
|
### JSON Output for Parsing |
||||||
|
|
||||||
|
```bash |
||||||
|
scripts/tavily_search.py "Python tutorials" --json > results.json |
||||||
|
``` |
||||||
|
|
||||||
|
### Chaining with Other Tools |
||||||
|
|
||||||
|
```bash |
||||||
|
# Search and extract content |
||||||
|
scripts/tavily_search.py "React documentation" --json | \ |
||||||
|
jq -r '.results[].url' | \ |
||||||
|
xargs -I {} curl -s {} |
||||||
|
``` |
||||||
|
|
||||||
|
## Comparison with Other Search APIs |
||||||
|
|
||||||
|
**vs Brave Search:** |
||||||
|
- ✅ AI answer generation |
||||||
|
- ✅ Raw content extraction |
||||||
|
- ✅ Better domain filtering |
||||||
|
- ❌ Slower than Brave |
||||||
|
- ❌ Costs credits |
||||||
|
|
||||||
|
**vs Perplexity:** |
||||||
|
- ✅ More control over sources |
||||||
|
- ✅ Raw content available |
||||||
|
- ✅ Dedicated news mode |
||||||
|
- ≈ Similar answer quality |
||||||
|
- ≈ Similar speed |
||||||
|
|
||||||
|
**vs Google Custom Search:** |
||||||
|
- ✅ LLM-optimized results |
||||||
|
- ✅ Answer generation |
||||||
|
- ✅ Simpler API |
||||||
|
- ❌ Smaller index |
||||||
|
- ≈ Similar cost structure |
||||||
|
|
||||||
|
## Troubleshooting |
||||||
|
|
||||||
|
### Script Won't Run |
||||||
|
|
||||||
|
```bash |
||||||
|
# Make executable |
||||||
|
chmod +x scripts/tavily_search.py |
||||||
|
|
||||||
|
# Check Python version (requires 3.6+) |
||||||
|
python3 --version |
||||||
|
|
||||||
|
# Install dependencies |
||||||
|
pip install tavily-python |
||||||
|
``` |
||||||
|
|
||||||
|
### API Key Issues |
||||||
|
|
||||||
|
```bash |
||||||
|
# Verify API key format (should start with tvly-) |
||||||
|
echo $TAVILY_API_KEY |
||||||
|
|
||||||
|
# Test with explicit key |
||||||
|
scripts/tavily_search.py "test" --api-key "tvly-..." |
||||||
|
``` |
||||||
|
|
||||||
|
### Rate Limit Errors |
||||||
|
|
||||||
|
- Check your plan's credit allocation at https://tavily.com |
||||||
|
- Reduce `max_results` to conserve credits |
||||||
|
- Use `basic` depth instead of `advanced` |
||||||
|
- Implement local caching for repeated queries |
||||||
|
|
||||||
|
## Resources |
||||||
|
|
||||||
|
See [api-reference.md](references/api-reference.md) for: |
||||||
|
- Complete API parameter documentation |
||||||
|
- Response format specifications |
||||||
|
- Error handling details |
||||||
|
- Cost and rate limit information |
||||||
|
- Advanced usage examples |
||||||
|
|
||||||
|
## Dependencies |
||||||
|
|
||||||
|
- Python 3.6+ |
||||||
|
- `tavily-python` package (install: `pip install tavily-python`) |
||||||
|
- Valid Tavily API key |
||||||
|
|
||||||
|
## Credits & Attribution |
||||||
|
|
||||||
|
- Tavily API: https://tavily.com |
||||||
|
- Python SDK: https://github.com/tavily-ai/tavily-python |
||||||
|
- Documentation: https://docs.tavily.com |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
{ |
||||||
|
"ownerId": "kn7dak197zp1gy590j60ct8r7h7zte7t", |
||||||
|
"slug": "tavily", |
||||||
|
"version": "1.0.0", |
||||||
|
"publishedAt": 1769287990264 |
||||||
|
} |
||||||
@ -0,0 +1,187 @@ |
|||||||
|
# Tavily API Reference |
||||||
|
|
||||||
|
## Overview |
||||||
|
|
||||||
|
Tavily is a search engine optimized for Large Language Models (LLMs) and AI applications. It provides: |
||||||
|
|
||||||
|
- **AI-optimized results**: Results specifically formatted for LLM consumption |
||||||
|
- **Answer generation**: Optional AI-generated summaries from search results |
||||||
|
- **Raw content extraction**: Clean, parsed HTML content from sources |
||||||
|
- **Domain filtering**: Include or exclude specific domains |
||||||
|
- **Image search**: Relevant images for visual context |
||||||
|
- **Topic specialization**: General or news-focused search |
||||||
|
|
||||||
|
## API Key Setup |
||||||
|
|
||||||
|
1. Visit https://tavily.com and sign up |
||||||
|
2. Generate an API key from your dashboard |
||||||
|
3. Store the key securely: |
||||||
|
- **Recommended**: Add to Clawdbot config under `skills.entries.tavily.apiKey` |
||||||
|
- **Alternative**: Set `TAVILY_API_KEY` environment variable |
||||||
|
|
||||||
|
## Search Parameters |
||||||
|
|
||||||
|
### Required |
||||||
|
|
||||||
|
- `query` (string): The search query |
||||||
|
|
||||||
|
### Optional |
||||||
|
|
||||||
|
| Parameter | Type | Default | Description | |
||||||
|
|-----------|------|---------|-------------| |
||||||
|
| `search_depth` | string | `"basic"` | `"basic"` (fast, ~1-2s) or `"advanced"` (comprehensive, ~5-10s) | |
||||||
|
| `topic` | string | `"general"` | `"general"` or `"news"` (current events, last 7 days) | |
||||||
|
| `max_results` | int | 5 | Number of results (1-10) | |
||||||
|
| `include_answer` | bool | true | Include AI-generated answer summary | |
||||||
|
| `include_raw_content` | bool | false | Include cleaned HTML content of sources | |
||||||
|
| `include_images` | bool | false | Include relevant images | |
||||||
|
| `include_domains` | list[str] | null | Only search these domains | |
||||||
|
| `exclude_domains` | list[str] | null | Exclude these domains | |
||||||
|
|
||||||
|
## Response Format |
||||||
|
|
||||||
|
```json |
||||||
|
{ |
||||||
|
"success": true, |
||||||
|
"query": "What is quantum computing?", |
||||||
|
"answer": "Quantum computing is a type of computing that uses...", |
||||||
|
"results": [ |
||||||
|
{ |
||||||
|
"title": "Quantum Computing Explained", |
||||||
|
"url": "https://example.com/quantum", |
||||||
|
"content": "Quantum computing leverages...", |
||||||
|
"score": 0.95, |
||||||
|
"raw_content": null |
||||||
|
} |
||||||
|
], |
||||||
|
"images": ["https://example.com/image.jpg"], |
||||||
|
"response_time": "1.67", |
||||||
|
"usage": { |
||||||
|
"credits": 1 |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## Use Cases & Best Practices |
||||||
|
|
||||||
|
### When to Use Tavily |
||||||
|
|
||||||
|
1. **Research tasks**: Comprehensive information gathering |
||||||
|
2. **Current events**: News-focused queries with `topic="news"` |
||||||
|
3. **Domain-specific search**: Use `include_domains` for trusted sources |
||||||
|
4. **Visual content**: Enable `include_images` for visual context |
||||||
|
5. **LLM consumption**: Results are pre-formatted for AI processing |
||||||
|
|
||||||
|
### Search Depth Comparison |
||||||
|
|
||||||
|
| Depth | Speed | Results Quality | Use Case | |
||||||
|
|-------|-------|-----------------|----------| |
||||||
|
| `basic` | 1-2s | Good | Quick lookups, simple facts | |
||||||
|
| `advanced` | 5-10s | Excellent | Research, complex topics, comprehensive analysis | |
||||||
|
|
||||||
|
**Recommendation**: Start with `basic`, use `advanced` for research tasks. |
||||||
|
|
||||||
|
### Domain Filtering |
||||||
|
|
||||||
|
**Include domains** (allowlist): |
||||||
|
```python |
||||||
|
include_domains=["python.org", "github.com", "stackoverflow.com"] |
||||||
|
``` |
||||||
|
Only search these specific domains - useful for trusted sources. |
||||||
|
|
||||||
|
**Exclude domains** (denylist): |
||||||
|
```python |
||||||
|
exclude_domains=["pinterest.com", "quora.com"] |
||||||
|
``` |
||||||
|
Remove unwanted or low-quality sources. |
||||||
|
|
||||||
|
### Topic Selection |
||||||
|
|
||||||
|
**General** (`topic="general"`): |
||||||
|
- Default mode |
||||||
|
- Broader web search |
||||||
|
- Historical and evergreen content |
||||||
|
- Best for most queries |
||||||
|
|
||||||
|
**News** (`topic="news"`): |
||||||
|
- Last 7 days only |
||||||
|
- News-focused sources |
||||||
|
- Current events and developments |
||||||
|
- Best for "latest", "recent", "current" queries |
||||||
|
|
||||||
|
## Cost & Rate Limits |
||||||
|
|
||||||
|
- **Credits**: Each search consumes credits (1 credit for basic search) |
||||||
|
- **Free tier**: Check https://tavily.com/pricing for current limits |
||||||
|
- **Rate limits**: Varies by plan tier |
||||||
|
|
||||||
|
## Error Handling |
||||||
|
|
||||||
|
Common errors: |
||||||
|
|
||||||
|
1. **Missing API key** |
||||||
|
```json |
||||||
|
{ |
||||||
|
"error": "Tavily API key required", |
||||||
|
"setup_instructions": "Set TAVILY_API_KEY environment variable" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
2. **Package not installed** |
||||||
|
```json |
||||||
|
{ |
||||||
|
"error": "tavily-python package not installed", |
||||||
|
"install_command": "pip install tavily-python" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
3. **Invalid API key** |
||||||
|
```json |
||||||
|
{ |
||||||
|
"error": "Invalid API key" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
4. **Rate limit exceeded** |
||||||
|
```json |
||||||
|
{ |
||||||
|
"error": "Rate limit exceeded" |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## Python SDK |
||||||
|
|
||||||
|
The skill uses the official `tavily-python` package: |
||||||
|
|
||||||
|
```python |
||||||
|
from tavily import TavilyClient |
||||||
|
|
||||||
|
client = TavilyClient(api_key="tvly-...") |
||||||
|
response = client.search( |
||||||
|
query="What is AI?", |
||||||
|
search_depth="advanced", |
||||||
|
max_results=10 |
||||||
|
) |
||||||
|
``` |
||||||
|
|
||||||
|
Install: `pip install tavily-python` |
||||||
|
|
||||||
|
## Comparison with Other Search APIs |
||||||
|
|
||||||
|
| Feature | Tavily | Brave Search | Perplexity | |
||||||
|
|---------|--------|--------------|------------| |
||||||
|
| AI Answer | ✅ Yes | ❌ No | ✅ Yes | |
||||||
|
| Raw Content | ✅ Yes | ❌ No | ❌ No | |
||||||
|
| Domain Filtering | ✅ Yes | Limited | ❌ No | |
||||||
|
| Image Search | ✅ Yes | ✅ Yes | ❌ No | |
||||||
|
| News Mode | ✅ Yes | ✅ Yes | ✅ Yes | |
||||||
|
| LLM Optimized | ✅ Yes | ❌ No | ✅ Yes | |
||||||
|
| Speed | Medium | Fast | Medium | |
||||||
|
| Free Tier | ✅ Yes | ✅ Yes | Limited | |
||||||
|
|
||||||
|
## Additional Resources |
||||||
|
|
||||||
|
- Official Docs: https://docs.tavily.com |
||||||
|
- Python SDK: https://github.com/tavily-ai/tavily-python |
||||||
|
- API Reference: https://docs.tavily.com/documentation/api-reference |
||||||
|
- Pricing: https://tavily.com/pricing |
||||||
@ -0,0 +1,247 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
""" |
||||||
|
Tavily AI Search - Optimized search for LLMs and AI applications |
||||||
|
Requires: pip install tavily-python |
||||||
|
""" |
||||||
|
|
||||||
|
import argparse |
||||||
|
import json |
||||||
|
import sys |
||||||
|
import os |
||||||
|
from typing import Optional, List |
||||||
|
|
||||||
|
|
||||||
|
def search( |
||||||
|
query: str, |
||||||
|
api_key: str, |
||||||
|
search_depth: str = "basic", |
||||||
|
topic: str = "general", |
||||||
|
max_results: int = 5, |
||||||
|
include_answer: bool = True, |
||||||
|
include_raw_content: bool = False, |
||||||
|
include_images: bool = False, |
||||||
|
include_domains: Optional[List[str]] = None, |
||||||
|
exclude_domains: Optional[List[str]] = None, |
||||||
|
) -> dict: |
||||||
|
""" |
||||||
|
Execute a Tavily search query. |
||||||
|
|
||||||
|
Args: |
||||||
|
query: Search query string |
||||||
|
api_key: Tavily API key (tvly-...) |
||||||
|
search_depth: "basic" (fast) or "advanced" (comprehensive) |
||||||
|
topic: "general" (default) or "news" (current events) |
||||||
|
max_results: Number of results to return (1-10) |
||||||
|
include_answer: Include AI-generated answer summary |
||||||
|
include_raw_content: Include raw HTML content of sources |
||||||
|
include_images: Include relevant images in results |
||||||
|
include_domains: List of domains to specifically include |
||||||
|
exclude_domains: List of domains to exclude |
||||||
|
|
||||||
|
Returns: |
||||||
|
dict: Tavily API response |
||||||
|
""" |
||||||
|
try: |
||||||
|
from tavily import TavilyClient |
||||||
|
except ImportError: |
||||||
|
return { |
||||||
|
"error": "tavily-python package not installed. Run: pip install tavily-python", |
||||||
|
"install_command": "pip install tavily-python" |
||||||
|
} |
||||||
|
|
||||||
|
if not api_key: |
||||||
|
return { |
||||||
|
"error": "Tavily API key required. Get one at https://tavily.com", |
||||||
|
"setup_instructions": "Set TAVILY_API_KEY environment variable or pass --api-key" |
||||||
|
} |
||||||
|
|
||||||
|
try: |
||||||
|
client = TavilyClient(api_key=api_key) |
||||||
|
|
||||||
|
# Build search parameters |
||||||
|
search_params = { |
||||||
|
"query": query, |
||||||
|
"search_depth": search_depth, |
||||||
|
"topic": topic, |
||||||
|
"max_results": max_results, |
||||||
|
"include_answer": include_answer, |
||||||
|
"include_raw_content": include_raw_content, |
||||||
|
"include_images": include_images, |
||||||
|
} |
||||||
|
|
||||||
|
if include_domains: |
||||||
|
search_params["include_domains"] = include_domains |
||||||
|
if exclude_domains: |
||||||
|
search_params["exclude_domains"] = exclude_domains |
||||||
|
|
||||||
|
response = client.search(**search_params) |
||||||
|
|
||||||
|
return { |
||||||
|
"success": True, |
||||||
|
"query": query, |
||||||
|
"answer": response.get("answer"), |
||||||
|
"results": response.get("results", []), |
||||||
|
"images": response.get("images", []), |
||||||
|
"response_time": response.get("response_time"), |
||||||
|
"usage": response.get("usage", {}), |
||||||
|
} |
||||||
|
|
||||||
|
except Exception as e: |
||||||
|
return { |
||||||
|
"error": str(e), |
||||||
|
"query": query |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
def main(): |
||||||
|
parser = argparse.ArgumentParser( |
||||||
|
description="Tavily AI Search - Optimized search for LLMs", |
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter, |
||||||
|
epilog=""" |
||||||
|
Examples: |
||||||
|
# Basic search |
||||||
|
%(prog)s "What is quantum computing?" |
||||||
|
|
||||||
|
# Advanced search with more results |
||||||
|
%(prog)s "Climate change solutions" --depth advanced --max-results 10 |
||||||
|
|
||||||
|
# News-focused search |
||||||
|
%(prog)s "AI developments" --topic news |
||||||
|
|
||||||
|
# Domain filtering |
||||||
|
%(prog)s "Python tutorials" --include-domains python.org --exclude-domains w3schools.com |
||||||
|
|
||||||
|
# Include images in results |
||||||
|
%(prog)s "Eiffel Tower" --images |
||||||
|
|
||||||
|
Environment Variables: |
||||||
|
TAVILY_API_KEY Your Tavily API key (get one at https://tavily.com) |
||||||
|
""" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"query", |
||||||
|
help="Search query" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--api-key", |
||||||
|
help="Tavily API key (or set TAVILY_API_KEY env var)" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--depth", |
||||||
|
choices=["basic", "advanced"], |
||||||
|
default="basic", |
||||||
|
help="Search depth: 'basic' (fast) or 'advanced' (comprehensive)" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--topic", |
||||||
|
choices=["general", "news"], |
||||||
|
default="general", |
||||||
|
help="Search topic: 'general' or 'news' (current events)" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--max-results", |
||||||
|
type=int, |
||||||
|
default=5, |
||||||
|
help="Maximum number of results (1-10)" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--no-answer", |
||||||
|
action="store_true", |
||||||
|
help="Exclude AI-generated answer summary" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--raw-content", |
||||||
|
action="store_true", |
||||||
|
help="Include raw HTML content of sources" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--images", |
||||||
|
action="store_true", |
||||||
|
help="Include relevant images in results" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--include-domains", |
||||||
|
nargs="+", |
||||||
|
help="List of domains to specifically include" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--exclude-domains", |
||||||
|
nargs="+", |
||||||
|
help="List of domains to exclude" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--json", |
||||||
|
action="store_true", |
||||||
|
help="Output raw JSON response" |
||||||
|
) |
||||||
|
|
||||||
|
args = parser.parse_args() |
||||||
|
|
||||||
|
# Get API key from args or environment |
||||||
|
api_key = args.api_key or os.getenv("TAVILY_API_KEY") |
||||||
|
|
||||||
|
result = search( |
||||||
|
query=args.query, |
||||||
|
api_key=api_key, |
||||||
|
search_depth=args.depth, |
||||||
|
topic=args.topic, |
||||||
|
max_results=args.max_results, |
||||||
|
include_answer=not args.no_answer, |
||||||
|
include_raw_content=args.raw_content, |
||||||
|
include_images=args.images, |
||||||
|
include_domains=args.include_domains, |
||||||
|
exclude_domains=args.exclude_domains, |
||||||
|
) |
||||||
|
|
||||||
|
if args.json: |
||||||
|
print(json.dumps(result, indent=2)) |
||||||
|
else: |
||||||
|
if "error" in result: |
||||||
|
print(f"Error: {result['error']}", file=sys.stderr) |
||||||
|
if "install_command" in result: |
||||||
|
print(f"\nTo install: {result['install_command']}", file=sys.stderr) |
||||||
|
if "setup_instructions" in result: |
||||||
|
print(f"\nSetup: {result['setup_instructions']}", file=sys.stderr) |
||||||
|
sys.exit(1) |
||||||
|
|
||||||
|
# Format human-readable output |
||||||
|
print(f"Query: {result['query']}") |
||||||
|
print(f"Response time: {result.get('response_time', 'N/A')}s") |
||||||
|
print(f"Credits used: {result.get('usage', {}).get('credits', 'N/A')}\n") |
||||||
|
|
||||||
|
if result.get("answer"): |
||||||
|
print("=== AI ANSWER ===") |
||||||
|
print(result["answer"]) |
||||||
|
print() |
||||||
|
|
||||||
|
if result.get("results"): |
||||||
|
print("=== RESULTS ===") |
||||||
|
for i, item in enumerate(result["results"], 1): |
||||||
|
print(f"\n{i}. {item.get('title', 'No title')}") |
||||||
|
print(f" URL: {item.get('url', 'N/A')}") |
||||||
|
print(f" Score: {item.get('score', 'N/A'):.3f}") |
||||||
|
if item.get("content"): |
||||||
|
content = item["content"] |
||||||
|
if len(content) > 200: |
||||||
|
content = content[:200] + "..." |
||||||
|
print(f" {content}") |
||||||
|
|
||||||
|
if result.get("images"): |
||||||
|
print(f"\n=== IMAGES ({len(result['images'])}) ===") |
||||||
|
for img_url in result["images"][:5]: # Show first 5 |
||||||
|
print(f" {img_url}") |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
main() |
||||||
@ -0,0 +1,37 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
# Agent Health Monitor Startup Script |
||||||
|
# Starts the agent health monitoring service |
||||||
|
|
||||||
|
cd /root/.openclaw/workspace |
||||||
|
|
||||||
|
# Make sure the monitor script is executable |
||||||
|
chmod +x agent-monitor.js |
||||||
|
|
||||||
|
# Start the monitor in background |
||||||
|
nohup node agent-monitor.js > /root/.openclaw/workspace/logs/agents/monitor.log 2>&1 & |
||||||
|
|
||||||
|
echo "Agent health monitor started with PID: $!" |
||||||
|
|
||||||
|
# Create systemd service for auto-start on boot (optional) |
||||||
|
cat > /etc/systemd/system/openclaw-agent-monitor.service << EOF |
||||||
|
[Unit] |
||||||
|
Description=OpenClaw Agent Health Monitor |
||||||
|
After=network.target |
||||||
|
|
||||||
|
[Service] |
||||||
|
Type=simple |
||||||
|
User=root |
||||||
|
WorkingDirectory=/root/.openclaw/workspace |
||||||
|
ExecStart=/usr/bin/node /root/.openclaw/workspace/agent-monitor.js |
||||||
|
Restart=always |
||||||
|
RestartSec=10 |
||||||
|
|
||||||
|
[Install] |
||||||
|
WantedBy=multi-user.target |
||||||
|
EOF |
||||||
|
|
||||||
|
# Enable and start the service (uncomment if needed) |
||||||
|
# systemctl daemon-reload |
||||||
|
# systemctl enable openclaw-agent-monitor |
||||||
|
# systemctl start openclaw-agent-monitor |
||||||
Loading…
Reference in new issue