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