diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..5baf253d9b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,182 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Build and Development Commands + +```bash +# Download dependencies +make deps + +# Build for current platform (runs go generate first) +make build + +# Build for all platforms (linux-amd64, linux-arm64, linux-loong64, linux-riscv64, darwin-arm64, windows-amd64) +make build-all + +# Run tests +make test + +# Run specific test +go test ./pkg/agent/... -v +go test ./pkg/providers/... -v -run TestFallbackChain + +# Run linter +make vet + +# Format code +make fmt + +# Full check (deps, fmt, vet, test) +make check + +# Install to ~/.local/bin +make install + +# Run with message +./build/picoclaw agent -m "Hello" + +# Run interactive mode +./build/picoclaw agent + +# Start gateway (connects to Telegram, Discord, etc.) +./build/picoclaw gateway + +# Debug mode +./build/picoclaw agent --debug -m "Hello" +``` + +## Architecture Overview + +PicoClaw is an ultra-lightweight AI assistant written in Go. It follows a message bus architecture where channels (Telegram, Discord, etc.) publish inbound messages and subscribe to outbound responses. + +### Core Components + +``` +cmd/picoclaw/main.go # Entry point, CLI commands +pkg/ +├── agent/ # Core agent logic +│ ├── loop.go # AgentLoop - message processing, LLM iteration +│ ├── instance.go # AgentInstance - per-agent configuration +│ ├── registry.go # AgentRegistry - multi-agent support +│ └── context.go # ContextBuilder - builds LLM messages +├── bus/ # Message bus for async communication +├── channels/ # Chat platform integrations (Telegram, Discord, etc.) +├── providers/ # LLM provider implementations +│ ├── openai_compat/ # OpenAI-compatible API (OpenRouter, Groq, etc.) +│ ├── anthropic/ # Anthropic/Claude API +│ └── fallback.go # Fallback chain for model redundancy +├── tools/ # Tool implementations (files, exec, web, spawn) +├── session/ # Session/history management +├── config/ # Configuration loading +├── routing/ # Message routing to agents +├── skills/ # Skill loading system +├── cron/ # Scheduled tasks +└── heartbeat/ # Periodic task execution +``` + +### Data Flow + +1. **Inbound**: Channel receives message → publishes to bus → AgentLoop consumes +2. **Processing**: AgentLoop routes to agent → builds context → calls LLM → executes tools +3. **Outbound**: Tool/agent publishes response → bus → channel sends to platform + +### Key Patterns + +- **Tool Interface** ([base.go](pkg/tools/base.go)): All tools implement `Tool` interface with `Name()`, `Description()`, `Parameters()`, `Execute()` +- **ContextualTool**: Tools can implement `SetContext(channel, chatID)` to receive message context +- **AsyncTool**: Tools can implement `SetCallback()` for async operations (spawn, cron) +- **LLMProvider Interface** ([types.go](pkg/providers/types.go)): `Chat()` method with messages, tools, model, options +- **Message Bus** ([bus.go](pkg/bus/bus.go)): Buffered channels (100 capacity) for inbound/outbound messages + +### LLM Provider Selection + +Providers are selected via config: +1. Check `providers.openrouter.api_key` → use OpenRouter +2. Check `providers.zhipu.api_key` → use Zhipu +3. Check `providers.openai.api_key` → use OpenAI +4. etc. + +Model format: `"provider/model"` (e.g., `"openrouter/anthropic/claude-opus-4-5"`) or just model name if provider is inferred. + +### Multi-Agent Support + +Agents are defined in `config.json` under `agents.list`. Each agent has: +- `id`: Unique identifier +- `workspace`: Isolated workspace directory +- `model`: Model configuration with optional fallbacks +- `subagents`: Allowed subagent IDs for spawn tool + +Routing binds channels to specific agents via `bindings` array. + +### Session Management + +Sessions are stored in `workspace/sessions/.json`. Each session tracks: +- Message history +- Summary (auto-generated when history exceeds threshold) +- Last access time + +### Security Sandbox + +When `restrict_to_workspace: true` (default): +- File operations limited to workspace directory +- Shell commands must execute within workspace +- Dangerous commands always blocked (rm -rf, format, dd, shutdown) + +## Configuration + +Config file: `~/.picoclaw/config.json` + +Key environment variables (override config): +- `PICOCLAW_AGENTS_DEFAULTS_MODEL` - Default model +- `PICOCLAW_HEARTBEAT_ENABLED` - Enable periodic tasks +- `PICOCLAW_TOOLS_WEB_DUCKDUCKGO_ENABLED` - Enable DuckDuckGo search + +Workspace layout: +``` +~/.picoclaw/workspace/ +├── sessions/ # Conversation history +├── memory/ # Long-term memory (MEMORY.md) +├── cron/ # Scheduled jobs +├── skills/ # Custom skills +├── AGENT.md # Agent behavior guide +├── IDENTITY.md # Agent identity +└── HEARTBEAT.md # Periodic task prompts +``` + +## Testing + +Tests use standard Go testing. Run with: +```bash +make test # All tests +go test ./pkg/... -v # Verbose +``` + +Integration tests (require external APIs) are tagged with `//go:build integration`. + +## Code Style + +- Standard Go formatting (`gofmt`, `go fmt`) +- Error wrapping with `fmt.Errorf("context: %w", err)` +- Structured logging via `pkg/logger` with component and fields +- JSON config uses `json:` tags with snake_case + +## Reference Documentation + +Read these documents when working on specific areas: + +| Document | When to Read | +|----------|--------------| +| [docs/developer-guide/architecture.md](docs/developer-guide/architecture.md) | Understanding system architecture, components, data flow | +| [docs/developer-guide/data-flow.md](docs/developer-guide/data-flow.md) | Message bus, event processing, request lifecycle | +| [docs/developer-guide/building.md](docs/developer-guide/building.md) | Building from source, cross-compilation, dependencies | +| [docs/developer-guide/testing.md](docs/developer-guide/testing.md) | Running tests, writing new tests, test patterns | +| [docs/developer-guide/extending/creating-tools.md](docs/developer-guide/extending/creating-tools.md) | Implementing new tools, Tool interface, parameters | +| [docs/developer-guide/extending/creating-providers.md](docs/developer-guide/extending/creating-providers.md) | Adding LLM providers, LLMProvider interface | +| [docs/developer-guide/extending/creating-channels.md](docs/developer-guide/extending/creating-channels.md) | Adding chat platforms, message handling | +| [docs/developer-guide/extending/creating-skills.md](docs/developer-guide/extending/creating-skills.md) | Creating custom skills, skill structure | +| [docs/configuration/config-file.md](docs/configuration/config-file.md) | Configuration schema, all options, environment variables | +| [docs/operations/troubleshooting.md](docs/operations/troubleshooting.md) | Common issues, debugging, error resolution | +| [docs/deployment/docker.md](docs/deployment/docker.md) | Docker setup, compose configuration | +| [docs/deployment/security.md](docs/deployment/security.md) | Production security, sandbox configuration | +| [docs/community/roadmap.md](docs/community/roadmap.md) | Project direction, planned features, priorities | diff --git a/README.fr.md b/README.fr.md index 7199f7098d..d8e4faa56d 100644 --- a/README.fr.md +++ b/README.fr.md @@ -50,7 +50,7 @@ ## 📢 Actualités -2026-02-16 🎉 PicoClaw a atteint 12K étoiles en une semaine ! Merci à tous pour votre soutien ! PicoClaw grandit plus vite que nous ne l'avions jamais imaginé. Vu le volume élevé de PR, nous avons un besoin urgent de mainteneurs communautaires. Nos rôles de bénévoles et notre feuille de route sont officiellement publiés [ici](docs/picoclaw_community_roadmap_260216.md) — nous avons hâte de vous accueillir ! +2026-02-16 🎉 PicoClaw a atteint 12K étoiles en une semaine ! Merci à tous pour votre soutien ! PicoClaw grandit plus vite que nous ne l'avions jamais imaginé. Vu le volume élevé de PR, nous avons un besoin urgent de mainteneurs communautaires. Nos rôles de bénévoles et notre feuille de route sont officiellement publiés [ici](docs/community/roadmap.md) — nous avons hâte de vous accueillir ! 2026-02-13 🎉 PicoClaw a atteint 5000 étoiles en 4 jours ! Merci à la communauté ! Nous finalisons la **Feuille de Route du Projet** et mettons en place le **Groupe de Développeurs** pour accélérer le développement de PicoClaw. 🚀 **Appel à l'action :** Soumettez vos demandes de fonctionnalités dans les GitHub Discussions. Nous les examinerons et les prioriserons lors de notre prochaine réunion hebdomadaire. @@ -913,7 +913,7 @@ Cette conception permet également le **support multi-agent** avec une sélectio | **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Obtenir Clé](https://cerebras.ai) | | **Volcengine** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Obtenir Clé](https://console.volcengine.com) | | **ShengsuanYun** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth uniquement | +| **Antigravity** | `antigravity/` | Google Cloud | Custom | [OAuth uniquement](docs/user-guide/ide-setup/antigravity.md) | | **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### Configuration de Base @@ -1062,17 +1062,45 @@ PicoClaw prend en charge les rappels planifiés et les tâches récurrentes via Les tâches sont stockées dans `~/.picoclaw/workspace/cron/` et traitées automatiquement. +--- + +## 📚 Documentation Complète + +Pour des guides et références complets, consultez le répertoire [docs/](docs/) : + +- **[Démarrage](docs/getting-started/README.md)** - Installation et guide rapide +- **[Guide Utilisateur](docs/user-guide/README.md)** - Documentation complète des fonctionnalités +- **[Guide Développeur](docs/developer-guide/README.md)** - Architecture et contribution +- **[Déploiement](docs/deployment/README.md)** - Docker, systemd, guides SBC +- **[Référence Configuration](docs/configuration/README.md)** - Référence complète des options +- **[Communauté](docs/community/README.md)** - Feuille de route, contribution, support + ## 🤝 Contribuer & Feuille de Route +### Points Forts de la Feuille de Route + +| Domaine Clé | Objectif | +|-------------|----------| +| **Optimisation Core** | Fonctionner sur appareils 64MB RAM avec <20MB mémoire | +| **Sécurité Renforcée** | Défense injection prompt, protection SSRF, sandbox | +| **Connectivité** | Architecture protocole-first, standard OneBot | +| **Fonctionnalités Avancées** | Support MCP, automatisation navigateur, multi-agents | +| **Expérience Développeur** | Démarrage zéro-config, documentation complète | + +### Contribuer + Les PR sont les bienvenues ! Le code source est volontairement petit et lisible. 🤗 -Feuille de route à venir... +- **Voie Rapide** : 1 PR fusionnée = accès au Discord développeurs +- **Voie Candidature** : Email à `support@sipeed.com` avec sujet `[Apply Join PicoClaw Dev Group] + compte GitHub` -Groupe de développeurs en construction. Condition d'entrée : au moins 1 PR fusionnée. +### Communauté -Groupes d'utilisateurs : +- **Discord** : https://discord.gg/V4sAZ9XWpN +- **Twitter** : Mentionnez @SipeedIO avec #picoclaw +- **Bilibili** : @Sipeed矽速科技 -Discord : +Consultez [docs/community/roadmap.md](docs/community/roadmap.md) pour la feuille de route détaillée. PicoClaw diff --git a/README.ja.md b/README.ja.md index bb0bdfb287..2ab53230df 100644 --- a/README.ja.md +++ b/README.ja.md @@ -85,9 +85,9 @@ ### 🐜 革新的な省フットプリントデプロイ PicoClaw はほぼすべての Linux デバイスにデプロイできます! -- $9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(Ethernet) または W(WiFi6) バージョン、最小ホームアシスタントに -- $30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html) または $100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html) サーバー自動メンテナンスに -- $50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) または $100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera) スマート監視に +- \$9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(Ethernet) または W(WiFi6) バージョン、最小ホームアシスタントに +- \$30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html) または \$100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html) サーバー自動メンテナンスに +- \$50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) または \$100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera) スマート監視に https://private-user-images.githubusercontent.com/83055338/547056448-e7b031ff-d6f5-4468-bcca-5726b6fecb5c.mp4 @@ -832,7 +832,7 @@ HEARTBEAT_OK 応答 ユーザーが直接結果を受け取る | **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [キーを取得](https://cerebras.ai) | | **Volcengine** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [キーを取得](https://console.volcengine.com) | | **ShengsuanYun** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | カスタム | OAuthのみ | +| **Antigravity** | `antigravity/` | Google Cloud | カスタム | [OAuthのみ](docs/user-guide/ide-setup/antigravity.md) | | **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### 基本設定 @@ -969,11 +969,45 @@ HEARTBEAT_OK 応答 ユーザーが直接結果を受け取る | `picoclaw gateway` | ゲートウェイを起動 | | `picoclaw status` | ステータスを表示 | +--- + +## 📚 完全なドキュメント + +包括的なガイドとリファレンスについては、[docs/](docs/) ディレクトリをご覧ください: + +- **[はじめに](docs/getting-started/README.md)** - インストールとクイックスタート +- **[ユーザーガイド](docs/user-guide/README.md)** - 完全な機能ドキュメント +- **[開発者ガイド](docs/developer-guide/README.md)** - アーキテクチャとコントリビューション +- **[デプロイ](docs/deployment/README.md)** - Docker、systemd、SBC ガイド +- **[設定リファレンス](docs/configuration/README.md)** - 設定オプションの完全なリファレンス +- **[コミュニティ](docs/community/README.md)** - ロードマップ、コントリビュート、サポート + ## 🤝 コントリビュート&ロードマップ -PR 歓迎!コードベースは意図的に小さく読みやすくしています。🤗 +### ロードマップハイライト + +| 重点分野 | 目標 | +|----------|------| +| **コア最適化** | 64MB RAM デバイスで <20MB メモリで動作 | +| **セキュリティ強化** | プロンプトインジェクション対策、SSRF 保護、サンドボックス | +| **接続性** | プロトコルファーストアーキテクチャ、OneBot 標準対応 | +| **高度機能** | MCP 対応、ブラウザ自動化、マルチエージェント協調 | +| **開発者体験** | ゼロ設定スタート、包括的なドキュメント | + +### コントリビュート + +PR を歓迎します!コードベースは意図的に小さく読みやすくしています。🤗 + +- **高速トラック**: 1 つのマージされた PR で開発者 Discord に参加可能 +- **アプリケーショントラック**: `support@sipeed.com` にメール(件名: `[Apply Join PicoClaw Dev Group] + GitHub アカウント`) + +### コミュニティ + +- **Discord**: https://discord.gg/V4sAZ9XWpN +- **Twitter**: #picoclaw で @SipeedIO をメンション +- **Bilibili**: @Sipeed矽速科技 -Discord: https://discord.gg/V4sAZ9XWpN +詳細なロードマップについては [docs/community/roadmap.md](docs/community/roadmap.md) をご覧ください。 PicoClaw diff --git a/README.md b/README.md index 7bc7b1089d..145bc6c21e 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ ## 📢 News -2026-02-16 🎉 PicoClaw hit 12K stars in one week! Thank you all for your support! PicoClaw is growing faster than we ever imagined. Given the high volume of PRs, we urgently need community maintainers. Our volunteer roles and roadmap are officially posted [here](docs/picoclaw_community_roadmap_260216.md) —we can’t wait to have you on board! +2026-02-16 🎉 PicoClaw hit 12K stars in one week! Thank you all for your support! PicoClaw is growing faster than we ever imagined. Given the high volume of PRs, we urgently need community maintainers. Our volunteer roles and roadmap are officially posted [here](docs/community/roadmap.md) —we can’t wait to have you on board! 2026-02-13 🎉 PicoClaw hit 5000 stars in 4days! Thank you for the community! There are so many PRs&issues come in (during Chinese New Year holidays), we are finalizing the Project Roadmap and setting up the Developer Group to accelerate PicoClaw's development. 🚀 Call to Action: Please submit your feature requests in GitHub Discussions. We will review and prioritize them during our upcoming weekly meeting. @@ -117,14 +117,31 @@ And then follow the instructions in the "Quick Start" section to complete the co PicoClaw can be deployed on almost any Linux device! -- $9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(Ethernet) or W(WiFi6) version, for Minimal Home Assistant -- $30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html), or $100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html) for Automated Server Maintenance -- $50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) or $100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera) for Smart Monitoring +- \$9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(Ethernet) or W(WiFi6) version, for Minimal Home Assistant +- \$30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html), or \$100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html) for Automated Server Maintenance +- \$50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) or \$100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera) for Smart Monitoring 🌟 More Deployment Cases Await! +--- +## 📚 Full Documentation + +For comprehensive guides and references, see the [docs/](docs/) directory: + +- **[Getting Started](docs/getting-started/README.md)** - Installation and quick start +- **[User Guide](docs/user-guide/README.md)** - Complete feature documentation +- **[Developer Guide](docs/developer-guide/README.md)** - Building and extending PicoClaw +- **[Deployment](docs/deployment/README.md)** - Docker, systemd, SBC guides +- **[Configuration Reference](docs/configuration/config-file.md)** - All config options +- **[Troubleshooting](docs/operations/troubleshooting.md)** - Common issues and solutions +- **[Community](docs/community/README.md)** - Roadmap, contributing, support + + +--- + + ## 📦 Install ### Install with precompiled binary @@ -806,7 +823,7 @@ This design also enables **multi-agent support** with flexible provider selectio | **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Get Key](https://cerebras.ai) | | **火山引擎** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Get Key](https://console.volcengine.com) | | **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only | +| **Antigravity** | `antigravity/` | Google Cloud | Custom | [OAuth only](docs/user-guide/ide-setup/antigravity.md) | | **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### Basic Configuration @@ -1101,19 +1118,48 @@ PicoClaw supports scheduled reminders and recurring tasks through the `cron` too Jobs are stored in `~/.picoclaw/workspace/cron/` and processed automatically. +--- + ## 🤝 Contribute & Roadmap PRs welcome! The codebase is intentionally small and readable. 🤗 -Roadmap coming soon... +### Roadmap Highlights + +| Focus Area | Goals | +|------------|-------| +| **Core Optimization** | Run on 64MB RAM devices with <20MB memory | +| **Security Hardening** | Sandbox, OAuth 2.0, prompt injection defense | +| **Connectivity** | More channels, MCP support, skill marketplace | +| **Multi-Agent** | Model routing, swarm mode, AIEOS integration | +| **DevEx** | Interactive CLI wizard, comprehensive docs | + +See the [Full Roadmap](docs/community/roadmap.md) for details. + +### Volunteer Roles + +We're looking for contributors in: +- **Issue/PR Reviewers** - Help triage and merge PRs +- **Resource Optimization** - Keep PicoClaw lightweight +- **Security Audit** - Review and harden security +- **Documentation** - Improve guides and tutorials +- **CI/CD Automation** - AI-powered builds and issue triage -Developer group building, Entry Requirement: At least 1 Merged PR. +**Perks:** Exclusive AI hardware, token discounts, and more! -User Groups: +### How to Join -discord: +1. **Fast Track**: Merge 1+ PR → Join Developer Discord +2. **Apply**: Email support@sipeed.com with `[Apply: PicoClaw Expert Volunteer]` -PicoClaw +### Community + +- **Discord**: +- **GitHub Discussions**: Share ideas and feature requests + +PicoClaw WeChat + +--- ## 🐛 Troubleshooting diff --git a/README.pt-br.md b/README.pt-br.md index ec8fe8e1c5..87a85a1b40 100644 --- a/README.pt-br.md +++ b/README.pt-br.md @@ -50,7 +50,7 @@ ## 📢 Novidades -2026-02-16 🎉 PicoClaw atingiu 12K stars em uma semana! Obrigado a todos pelo apoio! O PicoClaw está crescendo mais rápido do que jamais imaginamos. Dado o alto volume de PRs, precisamos urgentemente de maintainers da comunidade. Nossos papéis de voluntários e roadmap foram publicados oficialmente [aqui](docs/picoclaw_community_roadmap_260216.md) — estamos ansiosos para ter você a bordo! +2026-02-16 🎉 PicoClaw atingiu 12K stars em uma semana! Obrigado a todos pelo apoio! O PicoClaw está crescendo mais rápido do que jamais imaginamos. Dado o alto volume de PRs, precisamos urgentemente de maintainers da comunidade. Nossos papéis de voluntários e roadmap foram publicados oficialmente [aqui](docs/community/roadmap.md) — estamos ansiosos para ter você a bordo! 2026-02-13 🎉 PicoClaw atingiu 5000 stars em 4 dias! Obrigado à comunidade! Estamos finalizando o **Roadmap do Projeto** e configurando o **Grupo de Desenvolvedores** para acelerar o desenvolvimento do PicoClaw. @@ -124,9 +124,9 @@ Depois siga as instruções na seção "Início Rápido" para completar a config O PicoClaw pode ser implantado em praticamente qualquer dispositivo Linux! -- $9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) versão E (Ethernet) ou W (WiFi6), para Assistente Doméstico Minimalista -- $30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html), ou $100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html) para Manutenção Automatizada de Servidores -- $50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) ou $100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera) para Monitoramento Inteligente +- \$9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) versão E (Ethernet) ou W (WiFi6), para Assistente Doméstico Minimalista +- \$30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html), ou \$100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html) para Manutenção Automatizada de Servidores +- \$50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) ou \$100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera) para Monitoramento Inteligente https://private-user-images.githubusercontent.com/83055338/547056448-e7b031ff-d6f5-4468-bcca-5726b6fecb5c.mp4 @@ -907,7 +907,7 @@ Este design também possibilita o **suporte multi-agent** com seleção flexíve | **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Obter Chave](https://cerebras.ai) | | **Volcengine** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Obter Chave](https://console.volcengine.com) | | **ShengsuanYun** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | Custom | Apenas OAuth | +| **Antigravity** | `antigravity/` | Google Cloud | Custom | [Apenas OAuth](docs/user-guide/ide-setup/antigravity.md) | | **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### Configuração Básica @@ -1056,17 +1056,55 @@ O PicoClaw suporta lembretes agendados e tarefas recorrentes por meio da ferrame As tarefas são armazenadas em `~/.picoclaw/workspace/cron/` e processadas automaticamente. +--- + +## 📚 Documentação Completa + +Para guias e referências abrangentes, consulte o diretório [docs/](docs/): + +- **[Primeiros Passos](docs/getting-started/README.md)** - Instalação e início rápido +- **[Guia do Usuário](docs/user-guide/README.md)** - Documentação completa de recursos +- **[Guia do Desenvolvedor](docs/developer-guide/README.md)** - Arquitetura e contribuição +- **[Implantação](docs/deployment/README.md)** - Guias Docker, systemd, SBC +- **[Referência de Configuração](docs/configuration/README.md)** - Referência completa de opções de configuração +- **[Comunidade](docs/community/README.md)** - Roadmap, contribuição, suporte + ## 🤝 Contribuir & Roadmap PRs são bem-vindos! O código-fonte é intencionalmente pequeno e legível. 🤗 -Roadmap em breve... +### Destaques do Roadmap + +| Área de Foco | Metas | +|-------------|-------| +| **Otimização Principal** | Rodar em dispositivos de 64MB RAM com <20MB de memória | +| **Endurecimento de Segurança** | Sandbox, OAuth 2.0, defesa contra injeção de prompt | +| **Conectividade** | Mais canais, suporte MCP, marketplace de skills | +| **Multi-Agentes** | Roteamento de modelos, modo swarm, integração AIEOS | +| **Experiência do Desenvolvedor** | Assistente CLI interativo, documentação completa | + +Veja o [Roadmap Completo](docs/community/roadmap.md) e [Roadmap da Comunidade](docs/community/roadmap.md) para detalhes. + +### Funções de Voluntário + +Estamos procurando contribuidores em: +- **Revisores de Issue/PR** - Ajudar a triar e merge PRs +- **Otimização de Recursos** - Manter o PicoClaw leve +- **Auditoria de Segurança** - Revisar e fortalecer a segurança +- **Documentação** - Melhorar guias e tutoriais +- **Automação CI/CD** - Builds e triagem de issues com IA + +**Benefícios:** Hardware de IA exclusivo, descontos em tokens e mais! + +### Como Participar -Grupo de desenvolvedores em formação. Requisito de entrada: Pelo menos 1 PR com merge. +1. **Via Rápida**: Mergear 1+ PR → Entrar no Discord de Desenvolvedores +2. **Candidatura**: Email para support@sipeed.com com `[Apply: PicoClaw Expert Volunteer]` -Grupos de usuários: +### Comunidade -Discord: +- **Discord**: +- **GitHub Discussions**: Compartilhe ideias e solicitações de recursos PicoClaw diff --git a/README.vi.md b/README.vi.md index 161842933b..bcfb885c13 100644 --- a/README.vi.md +++ b/README.vi.md @@ -50,7 +50,7 @@ ## 📢 Tin tức -2026-02-16 🎉 PicoClaw đạt 12K stars chỉ trong một tuần! Cảm ơn tất cả mọi người! PicoClaw đang phát triển nhanh hơn chúng tôi tưởng tượng. Do số lượng PR tăng cao, chúng tôi cấp thiết cần maintainer từ cộng đồng. Các vai trò tình nguyện viên và roadmap đã được công bố [tại đây](docs/picoclaw_community_roadmap_260216.md) — rất mong đón nhận sự tham gia của bạn! +2026-02-16 🎉 PicoClaw đạt 12K stars chỉ trong một tuần! Cảm ơn tất cả mọi người! PicoClaw đang phát triển nhanh hơn chúng tôi tưởng tượng. Do số lượng PR tăng cao, chúng tôi cấp thiết cần maintainer từ cộng đồng. Các vai trò tình nguyện viên và roadmap đã được công bố [tại đây](docs/community/roadmap.md) — rất mong đón nhận sự tham gia của bạn! 2026-02-13 🎉 PicoClaw đạt 5000 stars trong 4 ngày! Cảm ơn cộng đồng! Chúng tôi đang hoàn thiện **Lộ trình dự án (Roadmap)** và thiết lập **Nhóm phát triển** để đẩy nhanh tốc độ phát triển PicoClaw. 🚀 **Kêu gọi hành động:** Vui lòng gửi yêu cầu tính năng tại GitHub Discussions. Chúng tôi sẽ xem xét và ưu tiên trong cuộc họp hàng tuần. @@ -104,9 +104,9 @@ PicoClaw có thể triển khai trên hầu hết mọi thiết bị Linux! -* $9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) phiên bản E (Ethernet) hoặc W (WiFi6), dùng làm Trợ lý Gia đình tối giản. -* $30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html), hoặc $100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html), dùng cho quản trị Server tự động. -* $50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) hoặc $100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera), dùng cho Giám sát thông minh. +* \$9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) phiên bản E (Ethernet) hoặc W (WiFi6), dùng làm Trợ lý Gia đình tối giản. +* \$30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html), hoặc \$100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html), dùng cho quản trị Server tự động. +* \$50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) hoặc \$100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera), dùng cho Giám sát thông minh. https://private-user-images.githubusercontent.com/83055338/547056448-e7b031ff-d6f5-4468-bcca-5726b6fecb5c.mp4 @@ -878,7 +878,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa tác nhân** với lựa ch | **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Lấy Khóa](https://cerebras.ai) | | **Volcengine** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Lấy Khóa](https://console.volcengine.com) | | **ShengsuanYun** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | Tùy chỉnh | Chỉ OAuth | +| **Antigravity** | `antigravity/` | Google Cloud | Tùy chỉnh | [Chỉ OAuth](docs/user-guide/ide-setup/antigravity.md) | | **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### Cấu hình Cơ bản @@ -1027,17 +1027,55 @@ PicoClaw hỗ trợ nhắc nhở theo lịch và tác vụ lặp lại thông qu Các tác vụ được lưu trong `~/.picoclaw/workspace/cron/` và được xử lý tự động. +--- + +## 📚 Tài liệu Đầy đủ + +Để có hướng dẫn và tài liệu tham khảo đầy đủ, xem thư mục [docs/](docs/): + +- **[Bắt đầu](docs/getting-started/README.md)** - Cài đặt và bắt đầu nhanh +- **[Hướng dẫn Người dùng](docs/user-guide/README.md)** - Tài liệu tính năng đầy đủ +- **[Hướng dẫn Nhà phát triển](docs/developer-guide/README.md)** - Kiến trúc và đóng góp +- **[Triển khai](docs/deployment/README.md)** - Hướng dẫn Docker, systemd, SBC +- **[Tham khảo Cấu hình](docs/configuration/README.md)** - Tài liệu tham khảo đầy đủ về cấu hình +- **[Cộng đồng](docs/community/README.md)** - Lộ trình, đóng góp, hỗ trợ + ## 🤝 Đóng góp & Lộ trình Chào đón mọi PR! Mã nguồn được thiết kế nhỏ gọn và dễ đọc. 🤗 -Lộ trình sắp được công bố... +### Tóm tắt Lộ trình + +| Lĩnh vực trọng tâm | Mục tiêu | +|-------------------|----------| +| **Tối ưu hóa Core** | Chạy trên thiết bị 64MB RAM với <20MB bộ nhớ | +| **Tăng cường Bảo mật** | Sandbox, OAuth 2.0, phòng chống prompt injection | +| **Kết nối** | Thêm kênh, hỗ trợ MCP, marketplace skill | +| **Multi-Agent** | Định tuyến mô hình, chế độ swarm, tích hợp AIEOS | +| **Trải nghiệm Dev** | Trợ lý CLI tương tác, tài liệu đầy đủ | + +Xem [Lộ trình Đầy đủ](docs/community/roadmap.md) và [Lộ trình Cộng đồng](docs/community/roadmap.md) để biết chi tiết. + +### Vai trò Tình nguyện viên + +Chúng tôi đang tìm kiếm người đóng góp trong: +- **Người xem xét Issue/PR** - Giúp phân loại và merge PR +- **Tối ưu hóa Tài nguyên** - Giữ PicoClaw nhẹ nhàng +- **Kiểm toán Bảo mật** - Xem xét và tăng cường bảo mật +- **Tài liệu** - Cải thiện hướng dẫn và tutorial +- **Tự động hóa CI/CD** - Build và xử lý issue với AI + +**Quyền lợi:** Phần cứng AI độc quyền, giảm giá token và hơn thế! + +### Cách Tham gia -Nhóm phát triển đang được xây dựng. Điều kiện tham gia: Ít nhất 1 PR đã được merge. +1. **Đường nhanh**: Merge 1+ PR → Tham gia Discord Nhà phát triển +2. **Ứng tuyển**: Email support@sipeed.com với `[Apply: PicoClaw Expert Volunteer]` -Nhóm người dùng: +### Cộng đồng -Discord: +- **Discord**: +- **GitHub Discussions**: Chia sẻ ý tưởng và yêu cầu tính năng PicoClaw diff --git a/README.zh.md b/README.zh.md index 4d739c5eb4..bf616265a6 100644 --- a/README.zh.md +++ b/README.zh.md @@ -51,8 +51,7 @@ > - **注意:** picoclaw最近合并了大量PRs,近期版本可能内存占用较大(10~20MB),我们将在功能较为收敛后进行资源占用优化. ## 📢 新闻 (News) - -2026-02-16 🎉 PicoClaw 在一周内突破了12K star! 感谢大家的关注!PicoClaw 的成长速度超乎我们预期. 由于PR数量的快速膨胀,我们亟需社区开发者参与维护. 我们需要的志愿者角色和roadmap已经发布到了[这里](docs/picoclaw_community_roadmap_260216.md), 期待你的参与! +2026-02-16 🎉 PicoClaw 在一周内突破了12K star! 感谢大家的关注!PicoClaw 的成长速度超乎我们预期. 由于PR数量的快速膨胀,我们亟需社区开发者参与维护. 我们需要的志愿者角色和roadmap已经发布到了[这里](docs/community/roadmap.md), 期待你的参与! 2026-02-13 🎉 **PicoClaw 在 4 天内突破 5000 Stars!** 感谢社区的支持!由于正值中国春节假期,PR 和 Issue 涌入较多,我们正在利用这段时间敲定 **项目路线图 (Roadmap)** 并组建 **开发者群组**,以便加速 PicoClaw 的开发。 🚀 **行动号召:** 请在 GitHub Discussions 中提交您的功能请求 (Feature Requests)。我们将在接下来的周会上进行审查和优先级排序。 @@ -124,9 +123,9 @@ termux-chroot ./picoclaw-linux-arm64 onboard PicoClaw 几乎可以部署在任何 Linux 设备上! -- $9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(网口) 或 W(WiFi6) 版本,用于极简家庭助手。 -- $30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html),或 $100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html),用于自动化服务器运维。 -- $50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) 或 $100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera),用于智能监控。 +* \$9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(网口) 或 W(WiFi6) 版本,用于极简家庭助手。 +* \$30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html),或 \$100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html),用于自动化服务器运维。 +* \$50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) 或 \$100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera),用于智能监控。 [https://private-user-images.githubusercontent.com/83055338/547056448-e7b031ff-d6f5-4468-bcca-5726b6fecb5c.mp4](https://private-user-images.githubusercontent.com/83055338/547056448-e7b031ff-d6f5-4468-bcca-5726b6fecb5c.mp4) @@ -437,25 +436,25 @@ Agent 读取 HEARTBEAT.md #### 📋 所有支持的厂商 -| 厂商 | `model` 前缀 | 默认 API Base | 协议 | 获取 API Key | -| ------------------- | ----------------- | --------------------------------------------------- | --------- | ----------------------------------------------------------------- | -| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [获取密钥](https://platform.openai.com) | -| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [获取密钥](https://console.anthropic.com) | -| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [获取密钥](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) | -| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [获取密钥](https://platform.deepseek.com) | -| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [获取密钥](https://aistudio.google.com/api-keys) | -| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [获取密钥](https://console.groq.com) | -| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [获取密钥](https://platform.moonshot.cn) | -| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [获取密钥](https://dashscope.console.aliyun.com) | -| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [获取密钥](https://build.nvidia.com) | -| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | 本地(无需密钥) | -| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [获取密钥](https://openrouter.ai/keys) | -| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | 本地 | -| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [获取密钥](https://cerebras.ai) | -| **火山引擎** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [获取密钥](https://console.volcengine.com) | -| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | 自定义 | 仅 OAuth | -| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | +| 厂商 | `model` 前缀 | 默认 API Base | 协议 | 获取 API Key | +|------|-------------|---------------|------|--------------| +| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [获取密钥](https://platform.openai.com) | +| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [获取密钥](https://console.anthropic.com) | +| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [获取密钥](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) | +| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [获取密钥](https://platform.deepseek.com) | +| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [获取密钥](https://aistudio.google.com/api-keys) | +| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [获取密钥](https://console.groq.com) | +| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [获取密钥](https://platform.moonshot.cn) | +| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [获取密钥](https://dashscope.console.aliyun.com) | +| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [获取密钥](https://build.nvidia.com) | +| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | 本地(无需密钥) | +| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [获取密钥](https://openrouter.ai/keys) | +| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | 本地 | +| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [获取密钥](https://cerebras.ai) | +| **火山引擎** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [获取密钥](https://console.volcengine.com) | +| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | +| **Antigravity** | `antigravity/` | Google Cloud | 自定义 | [仅 OAuth](docs/user-guide/ide-setup/antigravity.md) | +| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### 基础配置示例 @@ -749,17 +748,55 @@ PicoClaw 通过 `cron` 工具支持定时提醒和重复任务: 任务存储在 `~/.picoclaw/workspace/cron/` 中并自动处理。 +--- + +## 📚 完整文档 + +如需完整的指南和参考,请查看 [docs/](docs/) 目录: + +- **[入门指南](docs/getting-started/README.md)** - 安装和快速开始 +- **[用户指南](docs/user-guide/README.md)** - 完整功能文档 +- **[开发者指南](docs/developer-guide/README.md)** - 架构和贡献 +- **[部署指南](docs/deployment/README.md)** - Docker、systemd、SBC 指南 +- **[配置参考](docs/configuration/README.md)** - 完整配置选项参考 +- **[社区](docs/community/README.md)** - 路线图、贡献、支持 + ## 🤝 贡献与路线图 (Roadmap) 欢迎提交 PR!代码库刻意保持小巧和可读。🤗 -路线图即将发布... +### 路线图概要 + +| 重点领域 | 目标 | +|---------|------| +| **核心优化** | 在 64MB 内存设备上运行,占用 <20MB | +| **安全加固** | 沙盒、OAuth 2.0、提示注入防御 | +| **连接性** | 更多频道、MCP 支持、技能市场 | +| **多智能体** | 模型路由、集群模式、AIEOS 集成 | +| **开发者体验** | 交互式 CLI 向导、完善文档 | + +详见 [完整路线图](docs/community/roadmap.md) 和 [社区路线图](docs/community/roadmap.md)。 + +### 志愿者角色 + +我们正在寻找以下领域的贡献者: +- **Issue/PR 审核者** - 协助分类和合并 PR +- **资源优化** - 保持 PicoClaw 轻量级 +- **安全审计** - 审查和加固安全性 +- **文档** - 改进指南和教程 +- **CI/CD 自动化** - AI 驱动的构建和问题分流 + +**福利:** 专属 AI 硬件、Token 折扣等! + +### 如何加入 -开发者群组正在组建中,入群门槛:至少合并过 1 个 PR。 +1. **快速通道**:合并 1+ PR → 加入开发者 Discord +2. **申请**:发送邮件至 support@sipeed.com,标题 `[Apply: PicoClaw Expert Volunteer]` -用户群组: +### 社区 -Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) +- **Discord**: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) +- **GitHub Discussions**: 分享想法和功能请求 PicoClaw diff --git a/docs/ANTIGRAVITY_AUTH.md b/docs/ANTIGRAVITY_AUTH.md deleted file mode 100644 index 89261d8995..0000000000 --- a/docs/ANTIGRAVITY_AUTH.md +++ /dev/null @@ -1,807 +0,0 @@ -# Antigravity Authentication & Integration Guide - -## Overview - -**Antigravity** (Google Cloud Code Assist) is a Google-backed AI model provider that offers access to models like Claude Opus 4.6 and Gemini through Google's Cloud infrastructure. This document provides a complete guide on how authentication works, how to fetch models, and how to implement a new provider in PicoClaw. - ---- - -## Table of Contents - -1. [Authentication Flow](#authentication-flow) -2. [OAuth Implementation Details](#oauth-implementation-details) -3. [Token Management](#token-management) -4. [Models List Fetching](#models-list-fetching) -5. [Usage Tracking](#usage-tracking) -6. [Provider Plugin Structure](#provider-plugin-structure) -7. [Integration Requirements](#integration-requirements) -8. [API Endpoints](#api-endpoints) -9. [Configuration](#configuration) -10. [Creating a New Provider in PicoClaw](#creating-a-new-provider-in-picoclaw) - ---- - -## Authentication Flow - -### 1. OAuth 2.0 with PKCE - -Antigravity uses **OAuth 2.0 with PKCE (Proof Key for Code Exchange)** for secure authentication: - -``` -┌─────────────┐ ┌─────────────────┐ -│ Client │ ───(1) Generate PKCE Pair────────> │ │ -│ │ ───(2) Open Auth URL─────────────> │ Google OAuth │ -│ │ │ Server │ -│ │ <──(3) Redirect with Code───────── │ │ -│ │ └─────────────────┘ -│ │ ───(4) Exchange Code for Tokens──> │ Token URL │ -│ │ │ │ -│ │ <──(5) Access + Refresh Tokens──── │ │ -└─────────────┘ └─────────────────┘ -``` - -### 2. Detailed Steps - -#### Step 1: Generate PKCE Parameters -```typescript -function generatePkce(): { verifier: string; challenge: string } { - const verifier = randomBytes(32).toString("hex"); - const challenge = createHash("sha256").update(verifier).digest("base64url"); - return { verifier, challenge }; -} -``` - -#### Step 2: Build Authorization URL -```typescript -const AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"; -const REDIRECT_URI = "http://localhost:51121/oauth-callback"; - -function buildAuthUrl(params: { challenge: string; state: string }): string { - const url = new URL(AUTH_URL); - url.searchParams.set("client_id", CLIENT_ID); - url.searchParams.set("response_type", "code"); - url.searchParams.set("redirect_uri", REDIRECT_URI); - url.searchParams.set("scope", SCOPES.join(" ")); - url.searchParams.set("code_challenge", params.challenge); - url.searchParams.set("code_challenge_method", "S256"); - url.searchParams.set("state", params.state); - url.searchParams.set("access_type", "offline"); - url.searchParams.set("prompt", "consent"); - return url.toString(); -} -``` - -**Required Scopes:** -```typescript -const SCOPES = [ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/userinfo.email", - "https://www.googleapis.com/auth/userinfo.profile", - "https://www.googleapis.com/auth/cclog", - "https://www.googleapis.com/auth/experimentsandconfigs", -]; -``` - -#### Step 3: Handle OAuth Callback - -**Automatic Mode (Local Development):** -- Start a local HTTP server on port 51121 -- Wait for the redirect from Google -- Extract the authorization code from the query parameters - -**Manual Mode (Remote/Headless):** -- Display the authorization URL to the user -- User completes authentication in their browser -- User pastes the full redirect URL back into the terminal -- Parse the code from the pasted URL - -#### Step 4: Exchange Code for Tokens -```typescript -const TOKEN_URL = "https://oauth2.googleapis.com/token"; - -async function exchangeCode(params: { - code: string; - verifier: string; -}): Promise<{ access: string; refresh: string; expires: number }> { - const response = await fetch(TOKEN_URL, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, - body: new URLSearchParams({ - client_id: CLIENT_ID, - client_secret: CLIENT_SECRET, - code: params.code, - grant_type: "authorization_code", - redirect_uri: REDIRECT_URI, - code_verifier: params.verifier, - }), - }); - - const data = await response.json(); - - return { - access: data.access_token, - refresh: data.refresh_token, - expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000, // 5 min buffer - }; -} -``` - -#### Step 5: Fetch Additional User Data - -**User Email:** -```typescript -async function fetchUserEmail(accessToken: string): Promise { - const response = await fetch( - "https://www.googleapis.com/oauth2/v1/userinfo?alt=json", - { headers: { Authorization: `Bearer ${accessToken}` } } - ); - const data = await response.json(); - return data.email; -} -``` - -**Project ID (Required for API calls):** -```typescript -async function fetchProjectId(accessToken: string): Promise { - const headers = { - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - "User-Agent": "google-api-nodejs-client/9.15.1", - "X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1", - "Client-Metadata": JSON.stringify({ - ideType: "IDE_UNSPECIFIED", - platform: "PLATFORM_UNSPECIFIED", - pluginType: "GEMINI", - }), - }; - - const response = await fetch( - "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist", - { - method: "POST", - headers, - body: JSON.stringify({ - metadata: { - ideType: "IDE_UNSPECIFIED", - platform: "PLATFORM_UNSPECIFIED", - pluginType: "GEMINI", - }, - }), - } - ); - - const data = await response.json(); - return data.cloudaicompanionProject || "rising-fact-p41fc"; // Default fallback -} -``` - ---- - -## OAuth Implementation Details - -### Client Credentials - -**Important:** These are base64-encoded in the source code for sync with pi-ai: - -```typescript -const decode = (s: string) => Buffer.from(s, "base64").toString(); - -const CLIENT_ID = decode( - "MTA3MTAwNjA2MDU5MS10bWhzc2luMmgyMWxjcmUyMzV2dG9sb2poNGc0MDNlcC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbQ==" -); -const CLIENT_SECRET = decode("R09DU1BYLUs1OEZXUjQ4NkxkTEoxbUxCOHNYQzR6NnFEQWY="); -``` - -### OAuth Flow Modes - -1. **Automatic Flow** (Local machines with browser): - - Opens browser automatically - - Local callback server captures redirect - - No user interaction required after initial auth - -2. **Manual Flow** (Remote/headless/WSL2): - - URL displayed for manual copy-paste - - User completes auth in external browser - - User pastes full redirect URL back - -```typescript -function shouldUseManualOAuthFlow(isRemote: boolean): boolean { - return isRemote || isWSL2Sync(); -} -``` - ---- - -## Token Management - -### Auth Profile Structure - -```typescript -type OAuthCredential = { - type: "oauth"; - provider: "google-antigravity"; - access: string; // Access token - refresh: string; // Refresh token - expires: number; // Expiration timestamp (ms since epoch) - email?: string; // User email - projectId?: string; // Google Cloud project ID -}; -``` - -### Token Refresh - -The credential includes a refresh token that can be used to obtain new access tokens when the current one expires. The expiration is set with a 5-minute buffer to prevent race conditions. - ---- - -## Models List Fetching - -### Fetch Available Models - -```typescript -const BASE_URL = "https://cloudcode-pa.googleapis.com"; - -async function fetchAvailableModels( - accessToken: string, - projectId: string -): Promise { - const headers = { - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - "User-Agent": "antigravity", - "X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1", - }; - - const response = await fetch( - `${BASE_URL}/v1internal:fetchAvailableModels`, - { - method: "POST", - headers, - body: JSON.stringify({ project: projectId }), - } - ); - - const data = await response.json(); - - // Returns models with quota information - return Object.entries(data.models).map(([modelId, modelInfo]) => ({ - id: modelId, - displayName: modelInfo.displayName, - quotaInfo: { - remainingFraction: modelInfo.quotaInfo?.remainingFraction, - resetTime: modelInfo.quotaInfo?.resetTime, - isExhausted: modelInfo.quotaInfo?.isExhausted, - }, - })); -} -``` - -### Response Format - -```typescript -type FetchAvailableModelsResponse = { - models?: Record; -}; -``` - ---- - -## Usage Tracking - -### Fetch Usage Data - -```typescript -export async function fetchAntigravityUsage( - token: string, - timeoutMs: number -): Promise { - // 1. Fetch credits and plan info - const loadCodeAssistRes = await fetch( - `${BASE_URL}/v1internal:loadCodeAssist`, - { - method: "POST", - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - metadata: { - ideType: "ANTIGRAVITY", - platform: "PLATFORM_UNSPECIFIED", - pluginType: "GEMINI", - }, - }), - } - ); - - // Extract credits info - const { availablePromptCredits, planInfo, currentTier } = data; - - // 2. Fetch model quotas - const modelsRes = await fetch( - `${BASE_URL}/v1internal:fetchAvailableModels`, - { - method: "POST", - headers: { Authorization: `Bearer ${token}` }, - body: JSON.stringify({ project: projectId }), - } - ); - - // Build usage windows - return { - provider: "google-antigravity", - displayName: "Google Antigravity", - windows: [ - { label: "Credits", usedPercent: calculateUsedPercent(available, monthly) }, - // Individual model quotas... - ], - plan: currentTier?.name || planType, - }; -} -``` - -### Usage Response Structure - -```typescript -type ProviderUsageSnapshot = { - provider: "google-antigravity"; - displayName: string; - windows: UsageWindow[]; - plan?: string; - error?: string; -}; - -type UsageWindow = { - label: string; // "Credits" or model ID - usedPercent: number; // 0-100 - resetAt?: number; // Timestamp when quota resets -}; -``` - ---- - -## Provider Plugin Structure - -### Plugin Definition - -```typescript -const antigravityPlugin = { - id: "google-antigravity-auth", - name: "Google Antigravity Auth", - description: "OAuth flow for Google Antigravity (Cloud Code Assist)", - configSchema: emptyPluginConfigSchema(), - - register(api: PicoClawPluginApi) { - api.registerProvider({ - id: "google-antigravity", - label: "Google Antigravity", - docsPath: "/providers/models", - aliases: ["antigravity"], - - auth: [ - { - id: "oauth", - label: "Google OAuth", - hint: "PKCE + localhost callback", - kind: "oauth", - run: async (ctx: ProviderAuthContext) => { - // OAuth implementation here - }, - }, - ], - }); - }, -}; -``` - -### ProviderAuthContext - -```typescript -type ProviderAuthContext = { - config: PicoClawConfig; - agentDir?: string; - workspaceDir?: string; - prompter: WizardPrompter; // UI prompts/notifications - runtime: RuntimeEnv; // Logging, etc. - isRemote: boolean; // Whether running remotely - openUrl: (url: string) => Promise; // Browser opener - oauth: { - createVpsAwareHandlers: Function; - }; -}; -``` - -### ProviderAuthResult - -```typescript -type ProviderAuthResult = { - profiles: Array<{ - profileId: string; - credential: AuthProfileCredential; - }>; - configPatch?: Partial; - defaultModel?: string; - notes?: string[]; -}; -``` - ---- - -## Integration Requirements - -### 1. Required Environment/Dependencies - -- Go ≥ 1.21 -- PicoClaw codebase (`pkg/providers/` and `pkg/auth/`) -- `crypto` and `net/http` standard library packages - -### 2. Required Headers for API Calls - -```typescript -const REQUIRED_HEADERS = { - "Authorization": `Bearer ${accessToken}`, - "Content-Type": "application/json", - "User-Agent": "antigravity", // or "google-api-nodejs-client/9.15.1" - "X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1", -}; - -// For loadCodeAssist calls, also include: -const CLIENT_METADATA = { - ideType: "ANTIGRAVITY", // or "IDE_UNSPECIFIED" - platform: "PLATFORM_UNSPECIFIED", - pluginType: "GEMINI", -}; -``` - -### 3. Model Schema Sanitization - -Antigravity uses Gemini-compatible models, so tool schemas must be sanitized: - -```typescript -const GOOGLE_SCHEMA_UNSUPPORTED_KEYWORDS = new Set([ - "patternProperties", - "additionalProperties", - "$schema", - "$id", - "$ref", - "$defs", - "definitions", - "examples", - "minLength", - "maxLength", - "minimum", - "maximum", - "multipleOf", - "pattern", - "format", - "minItems", - "maxItems", - "uniqueItems", - "minProperties", - "maxProperties", -]); - -// Clean schema before sending -function cleanToolSchemaForGemini(schema: Record): unknown { - // Remove unsupported keywords - // Ensure top-level has type: "object" - // Flatten anyOf/oneOf unions -} -``` - -### 4. Thinking Block Handling (Claude Models) - -For Antigravity Claude models, thinking blocks require special handling: - -```typescript -const ANTIGRAVITY_SIGNATURE_RE = /^[A-Za-z0-9+/]+={0,2}$/; - -export function sanitizeAntigravityThinkingBlocks( - messages: AgentMessage[] -): AgentMessage[] { - // Validate thinking signatures - // Normalize signature fields - // Discard unsigned thinking blocks -} -``` - ---- - -## API Endpoints - -### Authentication Endpoints - -| Endpoint | Method | Purpose | -|----------|--------|---------| -| `https://accounts.google.com/o/oauth2/v2/auth` | GET | OAuth authorization | -| `https://oauth2.googleapis.com/token` | POST | Token exchange | -| `https://www.googleapis.com/oauth2/v1/userinfo` | GET | User info (email) | - -### Cloud Code Assist Endpoints - -| Endpoint | Method | Purpose | -|----------|--------|---------| -| `https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist` | POST | Load project info, credits, plan | -| `https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels` | POST | List available models with quotas | -| `https://cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse` | POST | Chat streaming endpoint | - -**API Request Format (Chat):** -The `v1internal:streamGenerateContent` endpoint expects an envelope wrapping the standard Gemini request: - -```json -{ - "project": "your-project-id", - "model": "model-id", - "request": { - "contents": [...], - "systemInstruction": {...}, - "generationConfig": {...}, - "tools": [...] - }, - "requestType": "agent", - "userAgent": "antigravity", - "requestId": "agent-timestamp-random" -} -``` - -**API Response Format (SSE):** -Each SSE message (`data: {...}`) is wrapped in a `response` field: - -```json -{ - "response": { - "candidates": [...], - "usageMetadata": {...}, - "modelVersion": "...", - "responseId": "..." - }, - "traceId": "...", - "metadata": {} -} -``` - ---- - -## Configuration - -### config.json Configuration - -```json -{ - "model_list": [ - { - "model_name": "gemini-flash", - "model": "antigravity/gemini-3-flash", - "auth_method": "oauth" - } - ], - "agents": { - "defaults": { - "model": "gemini-flash" - } - } -} -``` - -### Auth Profile Storage - -Auth profiles are stored in `~/.picoclaw/auth.json`: - -```json -{ - "credentials": { - "google-antigravity": { - "access_token": "ya29...", - "refresh_token": "1//...", - "expires_at": "2026-01-01T00:00:00Z", - "provider": "google-antigravity", - "auth_method": "oauth", - "email": "user@example.com", - "project_id": "my-project-id" - } - } -} -``` - ---- - -## Creating a New Provider in PicoClaw - -PicoClaw providers are implemented as Go packages under `pkg/providers/`. To add a new provider: - -### Step-by-Step Implementation - -#### 1. Create Provider File - -Create a new Go file in `pkg/providers/`: - -``` -pkg/providers/ -└── your_provider.go -``` - -#### 2. Implement the Provider Interface - -Your provider must implement the `Provider` interface defined in `pkg/providers/types.go`: - -```go -package providers - -type YourProvider struct { - apiKey string - apiBase string -} - -func NewYourProvider(apiKey, apiBase, proxy string) *YourProvider { - if apiBase == "" { - apiBase = "https://api.your-provider.com/v1" - } - return &YourProvider{apiKey: apiKey, apiBase: apiBase} -} - -func (p *YourProvider) Chat(ctx context.Context, messages []Message, tools []Tool, cb StreamCallback) error { - // Implement chat completion with streaming -} -``` - -#### 3. Register in the Factory - -Add your provider to the protocol switch in `pkg/providers/factory.go`: - -```go -case "your-provider": - return NewYourProvider(sel.apiKey, sel.apiBase, sel.proxy), nil -``` - -#### 4. Add Default Config (Optional) - -Add a default entry in `pkg/config/defaults.go`: - -```go -{ - ModelName: "your-model", - Model: "your-provider/model-name", - APIKey: "", -}, -``` - -#### 5. Add Auth Support (Optional) - -If your provider requires OAuth or special authentication, add a case to `cmd/picoclaw/cmd_auth.go`: - -```go -case "your-provider": - authLoginYourProvider() -``` - -#### 6. Configure via `config.json` - -```json -{ - "model_list": [ - { - "model_name": "your-model", - "model": "your-provider/model-name", - "api_key": "your-api-key", - "api_base": "https://api.your-provider.com/v1" - } - ] -} -``` - ---- - -## Testing Your Implementation - -### CLI Commands - -```bash -# Authenticate with a provider -picoclaw auth login --provider your-provider - -# List models (for Antigravity) -picoclaw auth models - -# Start the gateway -picoclaw gateway - -# Run an agent with a specific model -picoclaw agent -m "Hello" --model your-model -``` - -### Environment Variables for Testing - -```bash -# Override default model -export PICOCLAW_AGENTS_DEFAULTS_MODEL=your-model - -# Override provider settings -export PICOCLAW_MODEL_LIST='[{"model_name":"your-model","model":"your-provider/model-name","api_key":"..."}]' -``` - ---- - -## References - -- **Source Files:** - - `pkg/providers/antigravity_provider.go` - Antigravity provider implementation - - `pkg/auth/oauth.go` - OAuth flow implementation - - `pkg/auth/store.go` - Auth credential storage (`~/.picoclaw/auth.json`) - - `pkg/providers/factory.go` - Provider factory and protocol routing - - `pkg/providers/types.go` - Provider interface definitions - - `cmd/picoclaw/cmd_auth.go` - Auth CLI commands - -- **Documentation:** - - `docs/ANTIGRAVITY_USAGE.md` - Antigravity usage guide - - `docs/migration/model-list-migration.md` - Migration guide - ---- - -## Notes - -1. **Google Cloud Project:** Antigravity requires Gemini for Google Cloud to be enabled on your Google Cloud project -2. **Quotas:** Uses Google Cloud project quotas (not separate billing) -3. **Model Access:** Available models depend on your Google Cloud project configuration -4. **Thinking Blocks:** Claude models via Antigravity require special handling of thinking blocks with signatures -5. **Schema Sanitization:** Tool schemas must be sanitized to remove unsupported JSON Schema keywords - ---- - ---- - -## Common Error Handling - -### 1. Rate Limiting (HTTP 429) - -Antigravity returns a 429 error when project/model quotas are exhausted. The error response often contains a `quotaResetDelay` in the `details` field. - -**Example 429 Error:** -```json -{ - "error": { - "code": 429, - "message": "You have exhausted your capacity on this model. Your quota will reset after 4h30m28s.", - "status": "RESOURCE_EXHAUSTED", - "details": [ - { - "@type": "type.googleapis.com/google.rpc.ErrorInfo", - "metadata": { - "quotaResetDelay": "4h30m28.060903746s" - } - } - ] - } -} -``` - -### 2. Empty Responses (Restricted Models) - -Some models might show up in the available models list but return an empty response (200 OK but empty SSE stream). This usually happens for preview or restricted models that the current project doesn't have permission to use. - -**Treatment:** Treat empty responses as errors informing the user that the model might be restricted or invalid for their project. - ---- - -## Troubleshooting - -### "Token expired" -- Refresh OAuth tokens: `picoclaw auth login --provider antigravity` - -### "Gemini for Google Cloud is not enabled" -- Enable the API in your Google Cloud Console - -### "Project not found" -- Ensure your Google Cloud project has the necessary APIs enabled -- Check that the project ID is correctly fetched during authentication - -### Models not appearing in list -- Verify OAuth authentication completed successfully -- Check auth profile storage: `~/.picoclaw/auth.json` -- Re-run `picoclaw auth login --provider antigravity` diff --git a/docs/ANTIGRAVITY_USAGE.md b/docs/ANTIGRAVITY_USAGE.md deleted file mode 100644 index e8194b6bc5..0000000000 --- a/docs/ANTIGRAVITY_USAGE.md +++ /dev/null @@ -1,70 +0,0 @@ -# Using Antigravity Provider in PicoClaw - -This guide explains how to set up and use the **Antigravity** (Google Cloud Code Assist) provider in PicoClaw. - -## Prerequisites - -1. A Google account. -2. Google Cloud Code Assist enabled (usually available via the "Gemini for Google Cloud" onboarding). - -## 1. Authentication - -To authenticate with Antigravity, run the following command: - -```bash -picoclaw auth login --provider antigravity -``` - -### Manual Authentication (Headless/VPS) -If you are running on a server (Coolify/Docker) and cannot reach `localhost`, follow these steps: -1. Run the command above. -2. Copy the URL provided and open it in your local browser. -3. Complete the login. -4. Your browser will redirect to a `localhost:51121` URL (which will fail to load). -5. **Copy that final URL** from your browser's address bar. -6. **Paste it back into the terminal** where PicoClaw is waiting. - -PicoClaw will extract the authorization code and complete the process automatically. - -## 2. Managing Models - -### List Available Models -To see which models your project has access to and check their quotas: - -```bash -picoclaw auth models -``` - -### Switch Models -You can change the default model in `~/.picoclaw/config.json` or override it via the CLI: - -```bash -# Override for a single command -picoclaw agent -m "Hello" --model claude-opus-4-6-thinking -``` - -## 3. Real-world Usage (Coolify/Docker) - -If you are deploying via Coolify or Docker, follow these steps to test: - -1. **Environment Variables**: - * `PICOCLAW_AGENTS_DEFAULTS_MODEL=gemini-flash` -2. **Authentication persistence**: - If you've logged in locally, you can copy your credentials to the server: - ```bash - scp ~/.picoclaw/auth.json user@your-server:~/.picoclaw/ - ``` - *Alternatively*, run the `auth login` command once on the server if you have terminal access. - -## 4. Troubleshooting - -* **Empty Response**: If a model returns an empty reply, it may be restricted for your project. Try `gemini-3-flash` or `claude-opus-4-6-thinking`. -* **429 Rate Limit**: Antigravity has strict quotas. PicoClaw will display the "reset time" in the error message if you hit a limit. -* **404 Not Found**: Ensure you are using a model ID from the `picoclaw auth models` list. Use the short ID (e.g., `gemini-3-flash`) not the full path. - -## 5. Summary of Working Models - -Based on testing, the following models are most reliable: -* `gemini-3-flash` (Fast, highly available) -* `gemini-2.5-flash-lite` (Lightweight) -* `claude-opus-4-6-thinking` (Powerful, includes reasoning) diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..6938615381 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,208 @@ +# PicoClaw Documentation + +Welcome to the PicoClaw documentation. PicoClaw is an ultra-lightweight AI assistant written in Go that runs on $10 hardware with less than 10MB RAM. + +## Why PicoClaw? + +| Feature | OpenClaw | NanoBot | PicoClaw | +|---------|----------|---------|----------| +| **Language** | TypeScript | Python | Go | +| **RAM** | >1GB | >100MB | **<10MB** | +| **Startup** | >500s | >30s | **<1s** | +| **Cost** | Mac Mini $599 | ~$50 | **As low as $10** | + +## Quick Links + +- [Installation](getting-started/installation.md) - Get PicoClaw up and running +- [Quick Start](getting-started/quick-start.md) - Your first conversation in 5 minutes +- [Configuration Reference](configuration/config-file.md) - Complete config options +- [CLI Reference](user-guide/cli-reference.md) - All command-line options +- [Troubleshooting](operations/troubleshooting.md) - Common issues and solutions + +## Documentation Sections + +### Getting Started + +New to PicoClaw? Start here. + +- [Installation](getting-started/installation.md) - Install via binary, source, or Docker +- [Quick Start](getting-started/quick-start.md) - 5-minute setup guide +- [Configuration Basics](getting-started/configuration-basics.md) - Essential config concepts +- [Your First Chat](getting-started/first-chat.md) - Running your first conversation + +### User Guide + +Complete guide to using PicoClaw features. + +- [CLI Reference](user-guide/cli-reference.md) - All commands and options + - [onboard](user-guide/cli/onboard.md) - Initialize configuration + - [agent](user-guide/cli/agent.md) - Chat with the agent + - [gateway](user-guide/cli/gateway.md) - Start the gateway + - [status](user-guide/cli/status.md) - System status + - [auth](user-guide/cli/auth.md) - OAuth management + - [cron](user-guide/cli/cron.md) - Scheduled tasks + - [skills](user-guide/cli/skills.md) - Skill management + - [migrate](user-guide/cli/migrate.md) - Migration from OpenClaw + +- [Channels](user-guide/channels/README.md) - Chat platform integrations + - [Telegram](user-guide/channels/telegram.md) - Telegram bot setup + - [Discord](user-guide/channels/discord.md) - Discord bot setup + - [Slack](user-guide/channels/slack.md) - Slack integration + - [WhatsApp](user-guide/channels/whatsapp.md) - WhatsApp integration + - [Feishu/Lark](user-guide/channels/feishu-lark.md) - Feishu setup + - [LINE](user-guide/channels/line.md) - LINE bot setup + - [QQ](user-guide/channels/qq.md) - QQ bot setup + - [DingTalk](user-guide/channels/dingtalk.md) - DingTalk setup + - [WeCom](user-guide/channels/wecom.md) - WeCom (Enterprise WeChat) + - [OneBot](user-guide/channels/onebot.md) - OneBot protocol + - [MaixCam](user-guide/channels/maixcam.md) - MaixCam device + +- [Providers](user-guide/providers/README.md) - LLM provider setup + - [OpenRouter](user-guide/providers/openrouter.md) - Multi-model access (recommended) + - [Zhipu/GLM](user-guide/providers/zhipu.md) - Chinese AI models + - [Anthropic](user-guide/providers/anthropic.md) - Claude models + - [OpenAI](user-guide/providers/openai.md) - GPT models + - [Gemini](user-guide/providers/gemini.md) - Google Gemini + - [Groq](user-guide/providers/groq.md) - Fast inference + - [DeepSeek](user-guide/providers/deepseek.md) - DeepSeek models + - [Ollama](user-guide/providers/ollama.md) - Local models + - [vLLM](user-guide/providers/vllm.md) - Self-hosted models + +- [IDE Setup](user-guide/ide-setup/README.md) - IDE integrations + - [Antigravity](user-guide/ide-setup/antigravity.md) - Google Cloud Code Assist (free Claude/Gemini) + +- [Workspace](user-guide/workspace/README.md) - Customizing behavior + - [Structure](user-guide/workspace/structure.md) - Directory layout + - [AGENT.md](user-guide/workspace/agent-md.md) - Agent behavior + - [IDENTITY.md](user-guide/workspace/identity-md.md) - Agent identity + - [Memory](user-guide/workspace/memory.md) - Long-term memory + - [Heartbeat Tasks](user-guide/workspace/heartbeat-tasks.md) - Periodic tasks + +- [Tools](user-guide/tools/README.md) - Available tools + - [File System](user-guide/tools/filesystem.md) - read_file, write_file, etc. + - [Exec](user-guide/tools/exec.md) - Shell commands + - [Web](user-guide/tools/web.md) - web_search, web_fetch + - [Messaging](user-guide/tools/messaging.md) - Send messages + - [Spawn](user-guide/tools/spawn.md) - Subagents + - [Cron](user-guide/tools/cron.md) - Scheduled tasks + - [Hardware](user-guide/tools/hardware.md) - I2C, SPI + +- [Skills](user-guide/skills/README.md) - Skills system + - [Using Skills](user-guide/skills/using-skills.md) + - [Installing Skills](user-guide/skills/installing-skills.md) + - [Built-in Skills](user-guide/skills/builtin-skills.md) + - [Creating Skills](user-guide/skills/creating-skills.md) + +- [Advanced Features](user-guide/advanced/README.md) + - [Multi-Agent System](user-guide/advanced/multi-agent.md) + - [Message Routing](user-guide/advanced/routing.md) + - [Session Management](user-guide/advanced/session-management.md) + - [Model Fallbacks](user-guide/advanced/model-fallbacks.md) + - [Security Sandbox](user-guide/advanced/security-sandbox.md) + - [Environment Variables](user-guide/advanced/environment-variables.md) + - [Voice Transcription](user-guide/advanced/voice-transcription.md) + +### Developer Guide + +Building and extending PicoClaw. + +- [Architecture](developer-guide/architecture.md) - System design +- [Data Flow](developer-guide/data-flow.md) - Message bus architecture +- [Building](developer-guide/building.md) - Build from source +- [Testing](developer-guide/testing.md) - Running tests +- [Contributing](developer-guide/contributing.md) - Contribution guidelines +- [Code Style](developer-guide/code-style.md) - Code standards + +#### Extending PicoClaw + +- [Creating Tools](developer-guide/extending/creating-tools.md) +- [Creating Providers](developer-guide/extending/creating-providers.md) +- [Creating Channels](developer-guide/extending/creating-channels.md) +- [Creating Skills](developer-guide/extending/creating-skills.md) +- [Antigravity Implementation](developer-guide/extending/antigravity-implementation.md) - OAuth and API details + +#### API Reference + +- [Tool Interface](developer-guide/api/tool-interface.md) +- [Provider Interface](developer-guide/api/provider-interface.md) +- [Message Bus](developer-guide/api/message-bus.md) +- [Session API](developer-guide/api/session-api.md) + +### Deployment + +Deploying PicoClaw in various environments. + +- [Docker](deployment/docker.md) - Docker and Docker Compose +- [Systemd](deployment/systemd.md) - Linux service +- [Termux](deployment/termux.md) - Android phones +- [Single-Board Computers](deployment/sbc/README.md) + - [Raspberry Pi](deployment/sbc/rpi.md) + - [LicheeRV Nano](deployment/sbc/licheerv-nano.md) + - [MaixCAM](deployment/sbc/maixcam.md) +- [Security](deployment/security.md) - Production security + +### Operations + +Running and monitoring PicoClaw. + +- [Health Endpoints](operations/health-endpoints.md) +- [Monitoring](operations/monitoring.md) +- [Logging](operations/logging.md) +- [Device Monitoring](operations/device-monitoring.md) +- [Troubleshooting](operations/troubleshooting.md) + +### Configuration + +Complete configuration reference. + +- [Config File](configuration/config-file.md) - config.json reference +- [Agents Config](configuration/agents-config.md) +- [Bindings Config](configuration/bindings-config.md) +- [Channels Config](configuration/channels-config.md) +- [Providers Config](configuration/providers-config.md) +- [Tools Config](configuration/tools-config.md) +- [Gateway Config](configuration/gateway-config.md) +- [Heartbeat Config](configuration/heartbeat-config.md) +- [Devices Config](configuration/devices-config.md) + +### Migration + +Migrating from older configurations. + +- [Model List Migration](migration/model-list-migration.md) - Migrate to model_list configuration + +### Design + +Architecture and design decisions. + +- [Provider Refactoring](design/provider-refactoring.md) - Protocol-based provider architecture +- [Provider Refactoring Tests](design/provider-refactoring-tests.md) - Test patterns for providers + +### Tutorials + +Step-by-step guides. + +- [Basic Assistant](tutorials/basic-assistant.md) - Beginner setup +- [Telegram Bot](tutorials/telegram-bot.md) - Telegram tutorial +- [Scheduled Tasks](tutorials/scheduled-tasks.md) - Cron and heartbeat +- [Multi-Agent Setup](tutorials/multi-agent-setup.md) - Multiple agents +- [Hardware Control](tutorials/hardware-control.md) - I2C/SPI tutorial +- [Skill Development](tutorials/skill-development.md) - Custom skills + +### Community + +Join the community. + +- [Roadmap](community/roadmap.md) - Project roadmap +- [Support](community/support.md) - Getting help +- [Contributing Roles](community/contributing-roles.md) - Volunteer opportunities + +## Getting Help + +- **Discord**: [Join our server](https://discord.gg/V4sAZ9XWpN) +- **GitHub Issues**: [Report bugs](https://github.com/sipeed/picoclaw/issues) +- **GitHub Discussions**: [Feature requests](https://github.com/sipeed/picoclaw/discussions) + +## Contributing + +PRs are welcome! See the [Contributing Guide](developer-guide/contributing.md) for details. diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md new file mode 100644 index 0000000000..026f160f44 --- /dev/null +++ b/docs/SUMMARY.md @@ -0,0 +1,203 @@ +# Summary + +[PicoClaw Documentation](README.md) + +--- + +# Getting Started + +- [Installation](getting-started/installation.md) +- [Quick Start](getting-started/quick-start.md) +- [Configuration Basics](getting-started/configuration-basics.md) +- [Your First Chat](getting-started/first-chat.md) + +--- + +# User Guide + +## CLI Reference + +- [CLI Overview](user-guide/cli-reference.md) +- [onboard](user-guide/cli/onboard.md) +- [agent](user-guide/cli/agent.md) +- [gateway](user-guide/cli/gateway.md) +- [status](user-guide/cli/status.md) +- [auth](user-guide/cli/auth.md) +- [cron](user-guide/cli/cron.md) +- [skills](user-guide/cli/skills.md) +- [migrate](user-guide/cli/migrate.md) + +## Channels + +- [Channels Overview](user-guide/channels/README.md) +- [Telegram](user-guide/channels/telegram.md) +- [Discord](user-guide/channels/discord.md) +- [Slack](user-guide/channels/slack.md) +- [WhatsApp](user-guide/channels/whatsapp.md) +- [Feishu/Lark](user-guide/channels/feishu-lark.md) +- [LINE](user-guide/channels/line.md) +- [QQ](user-guide/channels/qq.md) +- [DingTalk](user-guide/channels/dingtalk.md) +- [WeCom](user-guide/channels/wecom.md) +- [OneBot](user-guide/channels/onebot.md) +- [MaixCam](user-guide/channels/maixcam.md) + +## Providers + +- [Providers Overview](user-guide/providers/README.md) +- [OpenRouter](user-guide/providers/openrouter.md) +- [Zhipu/GLM](user-guide/providers/zhipu.md) +- [Anthropic](user-guide/providers/anthropic.md) +- [OpenAI](user-guide/providers/openai.md) +- [Gemini](user-guide/providers/gemini.md) +- [Groq](user-guide/providers/groq.md) +- [DeepSeek](user-guide/providers/deepseek.md) +- [Ollama](user-guide/providers/ollama.md) +- [vLLM](user-guide/providers/vllm.md) + +## IDE Setup + +- [IDE Setup Overview](user-guide/ide-setup/README.md) +- [Antigravity (Google Cloud Code Assist)](user-guide/ide-setup/antigravity.md) + +## Workspace + +- [Workspace Overview](user-guide/workspace/README.md) +- [Directory Structure](user-guide/workspace/structure.md) +- [AGENT.md](user-guide/workspace/agent-md.md) +- [IDENTITY.md](user-guide/workspace/identity-md.md) +- [Memory](user-guide/workspace/memory.md) +- [Heartbeat Tasks](user-guide/workspace/heartbeat-tasks.md) + +## Tools + +- [Tools Overview](user-guide/tools/README.md) +- [File System](user-guide/tools/filesystem.md) +- [Exec](user-guide/tools/exec.md) +- [Web](user-guide/tools/web.md) +- [Messaging](user-guide/tools/messaging.md) +- [Spawn](user-guide/tools/spawn.md) +- [Cron](user-guide/tools/cron.md) +- [Hardware](user-guide/tools/hardware.md) + +## Skills + +- [Skills Overview](user-guide/skills/README.md) +- [Using Skills](user-guide/skills/using-skills.md) +- [Installing Skills](user-guide/skills/installing-skills.md) +- [Built-in Skills](user-guide/skills/builtin-skills.md) +- [Creating Skills](user-guide/skills/creating-skills.md) + +## Advanced Features + +- [Advanced Overview](user-guide/advanced/README.md) +- [Multi-Agent System](user-guide/advanced/multi-agent.md) +- [Message Routing](user-guide/advanced/routing.md) +- [Session Management](user-guide/advanced/session-management.md) +- [Model Fallbacks](user-guide/advanced/model-fallbacks.md) +- [Security Sandbox](user-guide/advanced/security-sandbox.md) +- [Environment Variables](user-guide/advanced/environment-variables.md) +- [Voice Transcription](user-guide/advanced/voice-transcription.md) + +--- + +# Configuration + +- [Config File Reference](configuration/config-file.md) +- [Agents Configuration](configuration/agents-config.md) +- [Bindings Configuration](configuration/bindings-config.md) +- [Channels Configuration](configuration/channels-config.md) +- [Providers Configuration](configuration/providers-config.md) +- [Tools Configuration](configuration/tools-config.md) +- [Gateway Configuration](configuration/gateway-config.md) +- [Heartbeat Configuration](configuration/heartbeat-config.md) +- [Devices Configuration](configuration/devices-config.md) + +--- + +# Operations + +- [Health Endpoints](operations/health-endpoints.md) +- [Monitoring](operations/monitoring.md) +- [Logging](operations/logging.md) +- [Device Monitoring](operations/device-monitoring.md) +- [Troubleshooting](operations/troubleshooting.md) + +--- + +# Migration + +- [Model List Migration](migration/model-list-migration.md) + +--- + +# Design + +- [Provider Refactoring](design/provider-refactoring.md) +- [Provider Refactoring Tests](design/provider-refactoring-tests.md) + +--- + +# Tutorials + +- [Tutorials Overview](tutorials/README.md) +- [Basic Assistant Setup](tutorials/basic-assistant.md) +- [Telegram Bot](tutorials/telegram-bot.md) +- [Scheduled Tasks](tutorials/scheduled-tasks.md) +- [Multi-Agent Setup](tutorials/multi-agent-setup.md) +- [Hardware Control](tutorials/hardware-control.md) +- [Skill Development](tutorials/skill-development.md) + +--- + +# Deployment + +- [Docker](deployment/docker.md) +- [Systemd](deployment/systemd.md) +- [Termux (Android)](deployment/termux.md) + +## Single-Board Computers + +- [SBC Overview](deployment/sbc/README.md) +- [Raspberry Pi](deployment/sbc/rpi.md) +- [LicheeRV Nano](deployment/sbc/licheerv-nano.md) +- [MaixCAM](deployment/sbc/maixcam.md) + +## Security + +- [Security Configuration](deployment/security.md) + +--- + +# Developer Guide + +- [Architecture](developer-guide/architecture.md) +- [Data Flow](developer-guide/data-flow.md) +- [Building](developer-guide/building.md) +- [Testing](developer-guide/testing.md) +- [Contributing](developer-guide/contributing.md) +- [Code Style](developer-guide/code-style.md) + +## Extending PicoClaw + +- [Creating Tools](developer-guide/extending/creating-tools.md) +- [Creating Providers](developer-guide/extending/creating-providers.md) +- [Creating Channels](developer-guide/extending/creating-channels.md) +- [Creating Skills](developer-guide/extending/creating-skills.md) +- [Antigravity Implementation](developer-guide/extending/antigravity-implementation.md) + +## API Reference + +- [Tool Interface](developer-guide/api/tool-interface.md) +- [Provider Interface](developer-guide/api/provider-interface.md) +- [Message Bus](developer-guide/api/message-bus.md) +- [Session API](developer-guide/api/session-api.md) + +--- + +# Community + +- [Community Overview](community/README.md) +- [Project Roadmap](community/roadmap.md) +- [Getting Help](community/support.md) +- [Contributing Roles](community/contributing-roles.md) diff --git a/docs/community/README.md b/docs/community/README.md new file mode 100644 index 0000000000..cc2bc55c42 --- /dev/null +++ b/docs/community/README.md @@ -0,0 +1,132 @@ +# Community + +Welcome to the PicoClaw community! This section covers how to get involved, get help, and contribute to the project. + +## Quick Links + +| Resource | Link | +|----------|------| +| Discord | [Join our server](https://discord.gg/V4sAZ9XWpN) | +| GitHub | [github.com/sipeed/picoclaw](https://github.com/sipeed/picoclaw) | +| Issues | [Report bugs](https://github.com/sipeed/picoclaw/issues) | +| Discussions | [Feature requests](https://github.com/sipeed/picoclaw/discussions) | + +## Community Sections + +### [Roadmap](roadmap.md) + +See what's planned for PicoClaw's future development. The roadmap covers: + +- Core optimization goals +- Security hardening plans +- New connectivity features +- Advanced capabilities +- Developer experience improvements + +### [Support](support.md) + +Get help when you need it: + +- Frequently asked questions +- Troubleshooting resources +- How to ask good questions +- Community support channels + +### [Contributing Roles](contributing-roles.md) + +Find your place in the community: + +- Ways to contribute +- Volunteer opportunities +- Recognition program +- Getting started guide + +## Getting Started + +### New to PicoClaw? + +1. Read the [Installation Guide](../getting-started/installation.md) +2. Follow the [Quick Start](../getting-started/quick-start.md) +3. Try the [Basic Assistant Tutorial](../tutorials/basic-assistant.md) + +### Need Help? + +1. Check the [Troubleshooting Guide](../operations/troubleshooting.md) +2. Search [existing issues](https://github.com/sipeed/picoclaw/issues) +3. Ask in [GitHub Discussions](https://github.com/sipeed/picoclaw/discussions) +4. Join our [Discord](https://discord.gg/V4sAZ9XWpN) + +### Want to Contribute? + +1. Read the [Contributing Guide](../developer-guide/contributing.md) +2. Check [open issues](https://github.com/sipeed/picoclaw/issues) +3. Look at [good first issues](https://github.com/sipeed/picoclaw/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) +4. Review the [Contributing Roles](contributing-roles.md) + +## Community Guidelines + +### Be Respectful + +- Treat everyone with respect +- Welcome newcomers +- Be patient with questions +- Provide constructive feedback + +### Be Helpful + +- Share your knowledge +- Help test new features +- Report bugs with details +- Improve documentation + +### Be Collaborative + +- Discuss before major changes +- Follow the code of conduct +- Give credit where due +- Build on each other's work + +## Stay Updated + +### Release Announcements + +Watch the GitHub repository for release notifications: + +1. Go to [github.com/sipeed/picoclaw](https://github.com/sipeed/picoclaw) +2. Click "Watch" → "Releases only" + +### Blog and News + +Check for updates on: +- GitHub Discussions announcements +- Discord #announcements channel + +## Code of Conduct + +All community members are expected to follow our code of conduct: + +- Be inclusive and welcoming +- Be respectful of differing viewpoints +- Accept constructive criticism gracefully +- Focus on what is best for the community +- Show empathy towards other community members + +## Recognition + +We recognize contributors through: + +- GitHub contributor statistics +- Release notes acknowledgments +- Community spotlight in Discord +- Contributor badges + +## Contact + +- **Bug reports**: [GitHub Issues](https://github.com/sipeed/picoclaw/issues) +- **Feature requests**: [GitHub Discussions](https://github.com/sipeed/picoclaw/discussions) +- **General questions**: [Discord](https://discord.gg/V4sAZ9XWpN) +- **Security issues**: See [Security Policy](https://github.com/sipeed/picoclaw/security/policy) + +## Thank You + +Thank you for being part of the PicoClaw community! Your participation makes the project better for everyone. diff --git a/docs/community/contributing-roles.md b/docs/community/contributing-roles.md new file mode 100644 index 0000000000..079ed061d3 --- /dev/null +++ b/docs/community/contributing-roles.md @@ -0,0 +1,318 @@ +# Contributing Roles + +This guide describes the various ways you can contribute to PicoClaw and the volunteer roles available. + +## Ways to Contribute + +### Code Contributions + +Write code to improve PicoClaw: + +- Fix bugs +- Add features +- Improve performance +- Refactor code + +See [Contributing Guide](../developer-guide/contributing.md) for details. + +### Documentation + +Help improve documentation: + +- Fix typos and errors +- Add examples and tutorials +- Translate documentation +- Write API references + +### Community Support + +Help other users: + +- Answer questions on Discord +- Respond to GitHub Discussions +- Review issues and provide solutions +- Share your knowledge + +### Testing + +Improve quality: + +- Test new releases +- Report bugs +- Verify fixes +- Test on different platforms + +### Skill Development + +Extend PicoClaw's capabilities: + +- Create custom skills +- Share skills with the community +- Improve existing skills + +## Volunteer Roles + +### Contributor + +Anyone who makes contributions to the project. + +**Requirements:** +- One or more merged PRs, or +- Significant documentation improvements, or +- Active community support + +**Benefits:** +- Listed in contributors file +- Acknowledged in release notes + +### Maintainer + +Regular contributors who help maintain the project. + +**Responsibilities:** +- Review pull requests +- Triage issues +- Help with releases +- Guide new contributors + +**Requirements:** +- Consistent contributions over time +- Good understanding of the codebase +- Positive community interactions + +**Benefits:** +- Write access to repository +- Input on project direction +- Recognition as maintainer + +### Documentation Lead + +Focus on documentation quality and coverage. + +**Responsibilities:** +- Review documentation PRs +- Plan documentation improvements +- Write guides and tutorials +- Maintain documentation structure + +**Requirements:** +- Strong writing skills +- Understanding of PicoClaw features +- Attention to detail + +### Community Moderator + +Help manage community interactions. + +**Responsibilities:** +- Moderate Discord server +- Welcome new members +- Keep discussions productive +- Escalate issues appropriately + +**Requirements:** +- Active in community +- Good communication skills +- Fair and patient + +### Skill Curator + +Manage the skill ecosystem. + +**Responsibilities:** +- Review community skills +- Maintain skill registry +- Create example skills +- Help skill developers + +**Requirements:** +- Understanding of skill system +- Creative problem-solving +- Good documentation + +### Platform Specialist + +Expert for specific platforms. + +**Responsibilities:** +- Test on your platform +- Report platform-specific issues +- Help users on your platform +- Maintain platform documentation + +**Platforms:** +- Raspberry Pi +- LicheeRV Nano +- MaixCAM +- Android/Termux +- Windows +- macOS + +### Channel Specialist + +Expert for specific chat platforms. + +**Responsibilities:** +- Test channel integrations +- Help users set up channels +- Report channel issues +- Improve channel documentation + +**Channels:** +- Telegram +- Discord +- Slack +- WhatsApp +- QQ +- LINE +- Feishu/Lark +- DingTalk + +### Language Ambassador + +Help with translations and localization. + +**Responsibilities:** +- Translate documentation +- Help users in your language +- Review translations +- Identify localization needs + +**Languages:** +- Chinese (Simplified) +- Chinese (Traditional) +- Japanese +- Korean +- German +- French +- Spanish +- Others welcome! + +## Getting Started + +### 1. Choose Your Path + +Based on your interests and skills: + +| Interest | Role | +|----------|------| +| Writing code | Contributor, Maintainer | +| Writing docs | Documentation Lead | +| Helping people | Community Moderator, Support | +| Testing | Platform Specialist | +| Creating content | Skill Curator | +| Languages | Language Ambassador | + +### 2. Start Contributing + +1. **Read the Contributing Guide** + - [Contributing Guide](../developer-guide/contributing.md) + - [Code of Conduct](#code-of-conduct) + +2. **Find a Task** + - [Good First Issues](https://github.com/sipeed/picoclaw/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) + - [Help Wanted](https://github.com/sipeed/picoclaw/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) + - [Documentation Issues](https://github.com/sipeed/picoclaw/issues?q=is%3Aopen+is%3Aissue+label%3Adocumentation) + +3. **Join the Community** + - [Discord](https://discord.gg/V4sAZ9XWpN) + - [GitHub Discussions](https://github.com/sipeed/picoclaw/discussions) + +4. **Make Your First Contribution** + - Submit a PR + - Help someone with a question + - Improve documentation + +### 3. Get Recognized + +Contributors are recognized through: + +- GitHub contributor statistics +- Release notes acknowledgments +- Community highlights +- Role badges in Discord + +## Recognition Program + +### Contribution Levels + +| Level | Requirement | Recognition | +|-------|-------------|-------------| +| First Timer | First merged PR | Welcome message, contributor badge | +| Regular | 5+ merged PRs | Listed in CONTRIBUTORS file | +| Core | 20+ merged PRs | Invitation to maintainer role | + +### Special Recognition + +- **Monthly Spotlight**: Featured contributor in Discord +- **Release Hero**: Major contributor to a release +- **Community Hero**: Exceptional community support +- **Doc Champion**: Significant documentation improvements + +## Expectations + +### For All Contributors + +- Follow the code of conduct +- Be respectful and constructive +- Focus on what's best for the project +- Accept feedback gracefully +- Help others when you can + +### For Maintainers + +- Be responsive to issues and PRs +- Provide clear feedback +- Help new contributors +- Maintain code quality +- Document decisions + +## Code of Conduct + +### Our Standards + +- Be respectful and inclusive +- Welcome diverse perspectives +- Accept constructive criticism +- Focus on constructive discussions +- Show empathy towards others + +### Unacceptable Behavior + +- Harassment or discrimination +- Trolling or insulting comments +- Publishing others' private information +- Any unprofessional conduct + +### Enforcement + +Report issues to maintainers via: +- GitHub private messages +- Discord DM to moderators + +## Questions? + +### About Contributing + +- Ask in [GitHub Discussions](https://github.com/sipeed/picoclaw/discussions) +- Join [Discord](https://discord.gg/V4sAZ9XWpN) `#contributors` channel + +### About Roles + +- Review the requirements above +- Talk to current maintainers +- Start contributing in that area + +## Thank You! + +Every contribution matters, whether it's: +- A typo fix in documentation +- A bug report with details +- Helping a new user +- Writing a major feature + +Thank you for making PicoClaw better! + +--- + +*Ready to contribute? Start with [Good First Issues](https://github.com/sipeed/picoclaw/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).* diff --git a/ROADMAP.md b/docs/community/roadmap.md similarity index 99% rename from ROADMAP.md rename to docs/community/roadmap.md index 8c5c0e252d..3f2cab4b5d 100644 --- a/ROADMAP.md +++ b/docs/community/roadmap.md @@ -9,7 +9,7 @@ *Our defining characteristic. We fight software bloat to ensure PicoClaw runs smoothly on the smallest embedded devices.* -* [**Memory Footprint Reduction**](https://github.com/sipeed/picoclaw/issues/346) +* [**Memory Footprint Reduction**](https://github.com/sipeed/picoclaw/issues/346) * **Goal**: Run smoothly on 64MB RAM embedded boards (e.g., low-end RISC-V SBCs) with the core process consuming < 20MB. * **Context**: RAM is expensive and scarce on edge devices. Memory optimization takes precedence over storage size. * **Action**: Analyze memory growth between releases, remove redundant dependencies, and optimize data structures. @@ -113,4 +113,4 @@ ### 🤝 Call for Contributions -We welcome community contributions to any item on this roadmap! Please comment on the relevant Issue or submit a PR. Let's build the best Edge AI Agent together! \ No newline at end of file +We welcome community contributions to any item on this roadmap! Please comment on the relevant Issue or submit a PR. Let's build the best Edge AI Agent together! diff --git a/docs/community/support.md b/docs/community/support.md new file mode 100644 index 0000000000..a0c0f0fbf6 --- /dev/null +++ b/docs/community/support.md @@ -0,0 +1,287 @@ +# Getting Help + +This guide covers how to get help with PicoClaw. + +## Quick Help + +### Common Issues + +| Issue | Solution | +|-------|----------| +| Command not found | Add binary to PATH or use full path | +| No API key | Add provider API key to config | +| Permission denied | Check file permissions | +| Rate limited | Wait or set up fallback models | + +See [Troubleshooting](../operations/troubleshooting.md) for more solutions. + +## Documentation + +### Start Here + +1. [Installation Guide](../getting-started/installation.md) +2. [Quick Start](../getting-started/quick-start.md) +3. [Configuration Basics](../getting-started/configuration-basics.md) + +### Reference + +- [CLI Reference](../user-guide/cli-reference.md) +- [Configuration Reference](../configuration/config-file.md) +- [Tools Overview](../user-guide/tools/README.md) + +### Tutorials + +- [Basic Assistant](../tutorials/basic-assistant.md) +- [Telegram Bot](../tutorials/telegram-bot.md) +- [Scheduled Tasks](../tutorials/scheduled-tasks.md) + +## Community Support + +### Discord + +Join our Discord server for real-time help: + +[https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) + +**Channels:** + +- `#general` - General discussion +- `#help` - Get help with issues +- `#showcase` - Share your projects +- `#announcements` - Project updates + +### GitHub Discussions + +For longer-form questions and feature discussions: + +[https://github.com/sipeed/picoclaw/discussions](https://github.com/sipeed/picoclaw/discussions) + +**Categories:** + +- Q&A - Questions and answers +- Ideas - Feature suggestions +- Show and Tell - Project showcases +- General - Other discussions + +## Reporting Issues + +### Before Reporting + +1. **Search existing issues** - Your problem may already be reported +2. **Check documentation** - Review relevant docs +3. **Try debug mode** - Run with `--debug` flag +4. **Update PicoClaw** - Ensure you're on the latest version + +### How to Report + +Open an issue at: [https://github.com/sipeed/picoclaw/issues](https://github.com/sipeed/picoclaw/issues) + +### Issue Template + +~~~markdown +## Description +Brief description of the problem + +## Steps to Reproduce +1. Run command `picoclaw ...` +2. See error + +## Expected Behavior +What should happen + +## Actual Behavior +What actually happens + +## Environment +- PicoClaw version: [run `picoclaw version`] +- OS: [e.g., Ubuntu 22.04, macOS 14] +- Architecture: [e.g., amd64, arm64] + +## Debug Output +``` +[paste debug output here, redact sensitive info] +``` + +## Additional Context +Any other relevant information +~~~ + +### What to Include + +**Always Include:** + +- PicoClaw version +- Operating system +- Steps to reproduce +- Error messages + +**If Relevant:** + +- Configuration file (redact API keys) +- Debug output +- Logs (redact sensitive info) +- Screenshots + +### Redacting Sensitive Information + +Before sharing logs or config: + +```bash +# Redact API keys +sed -i 's/sk-[a-zA-Z0-9-]*/sk-***/g' config.json + +# Redact tokens +sed -i 's/[0-9]\{10,\}:AAH[a-zA-Z0-9_-]*/TOKEN/g' log.txt +``` + +## Asking Good Questions + +### Be Specific + +``` +Bad: "It doesn't work" +Good: "When I run `picoclaw agent -m 'hello'`, I get 'no API key configured' error" +``` + +### Provide Context + +``` +Bad: "How do I use Telegram?" +Good: "I'm trying to set up a Telegram bot. I've created the bot with BotFather and got the token. How do I configure it in PicoClaw?" +``` + +### Show Your Work + +``` +Bad: "The config is wrong" +Good: "Here's my config.json: +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-***" + } + } +} + +And I'm getting error: 'model not found'" +``` + +### One Issue at a Time + +Focus on one problem per question or issue. This makes it easier to help and for others to find solutions later. + +## Response Times + +| Channel | Typical Response | +|---------|------------------| +| GitHub Issues | 1-3 days | +| GitHub Discussions | 1-3 days | +| Discord | Minutes to hours | + +Response times vary based on complexity, timezone, and community availability. + +## Self-Help Resources + +### Debug Mode + +Enable detailed logging: + +```bash +picoclaw agent --debug -m "your message" +picoclaw gateway --debug +``` + +### Check Configuration + +```bash +# Validate JSON syntax +cat ~/.picoclaw/config.json | python3 -m json.tool + +# Check config is loaded +picoclaw status +``` + +### Check Logs + +```bash +# If logging to file +tail -f /var/log/picoclaw/app.log + +# Systemd journal +journalctl -u picoclaw -f +``` + +### Test Components + +```bash +# Test provider connection +picoclaw agent -m "Hello" + +# Test channel +picoclaw gateway --debug + +# Check status +picoclaw status +``` + +## Security Issues + +For security vulnerabilities: + +1. **Do not** open a public issue +2. Email security concerns privately +3. Allow time for response before disclosure +4. See [Security Policy](https://github.com/sipeed/picoclaw/security/policy) + +## Feature Requests + +For feature suggestions: + +1. Check [existing discussions](https://github.com/sipeed/picoclaw/discussions/categories/ideas) +2. Open a new discussion with "Idea" category +3. Describe the use case +4. Explain the expected benefit + +## Commercial Support + +For enterprise or commercial support needs, contact the maintainers through GitHub. + +## FAQ + +### General Questions + +**Q: Is PicoClaw free?** + +A: Yes, PicoClaw is open source under the MIT license. You need an LLM provider API key which may have costs. + +**Q: What's the difference between PicoClaw and OpenClaw?** + +A: PicoClaw is written in Go, optimized for minimal resource usage (<10MB RAM vs >1GB for OpenClaw). + +**Q: Can I run PicoClaw on a Raspberry Pi?** + +A: Yes! PicoClaw is designed for embedded and low-resource environments. + +### Technical Questions + +**Q: Which provider should I use?** + +A: OpenRouter is recommended for most users - it provides access to many models with a free tier. + +**Q: How do I update PicoClaw?** + +A: Download the latest binary and replace the old one. + +**Q: Where are my conversations stored?** + +A: In `~/.picoclaw/workspace/sessions/` as JSON files. + +## Still Need Help? + +If you've tried everything and still need help: + +1. Open a [GitHub Issue](https://github.com/sipeed/picoclaw/issues) with full details +2. Join [Discord](https://discord.gg/V4sAZ9XWpN) and ask in `#help` +3. Start a [GitHub Discussion](https://github.com/sipeed/picoclaw/discussions) + +We're here to help! diff --git a/docs/configuration/config-file.md b/docs/configuration/config-file.md new file mode 100644 index 0000000000..1a6084c195 --- /dev/null +++ b/docs/configuration/config-file.md @@ -0,0 +1,550 @@ +# Configuration File Reference + +The main configuration file is located at `~/.picoclaw/config.json`. This page provides a complete reference for all configuration options. + +## Configuration File Location + +``` +~/.picoclaw/config.json +``` + +Use `picoclaw onboard` to create a default configuration file. + +## Configuration Structure + +```json +{ + "agents": { ... }, + "bindings": [ ... ], + "session": { ... }, + "channels": { ... }, + "providers": { ... }, + "gateway": { ... }, + "tools": { ... }, + "heartbeat": { ... }, + "devices": { ... } +} +``` + +## Agents Configuration + +Configure agent behavior and model settings. + +### agents.defaults + +Default settings for all agents. + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `workspace` | string | `~/.picoclaw/workspace` | Working directory for the agent | +| `restrict_to_workspace` | bool | `true` | Restrict file/command access to workspace | +| `provider` | string | `""` | Explicit provider name (optional) | +| `model` | string | `glm-4.7` | Primary model to use | +| `model_fallbacks` | []string | `[]` | Fallback models if primary fails | +| `image_model` | string | `""` | Model for image tasks | +| `image_model_fallbacks` | []string | `[]` | Image model fallbacks | +| `max_tokens` | int | `8192` | Maximum tokens in response | +| `temperature` | float | `0.7` | Response randomness (0-1) | +| `max_tool_iterations` | int | `20` | Max tool call iterations | + +**Example:** + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "restrict_to_workspace": true, + "model": "anthropic/claude-opus-4-5", + "model_fallbacks": ["anthropic/claude-sonnet-4", "gpt-4o"], + "max_tokens": 8192, + "temperature": 0.7, + "max_tool_iterations": 20 + } + } +} +``` + +### agents.list (Multi-Agent) + +Define multiple agents with different configurations. + +| Option | Type | Description | +|--------|------|-------------| +| `id` | string | Unique agent identifier | +| `default` | bool | Is this the default agent | +| `name` | string | Display name | +| `workspace` | string | Agent-specific workspace | +| `model` | object/string | Model config with primary and fallbacks | +| `skills` | []string | Filter available skills | +| `subagents` | object | Subagent configuration | + +**Example:** + +```json +{ + "agents": { + "defaults": { ... }, + "list": [ + { + "id": "assistant", + "default": true, + "name": "General Assistant", + "workspace": "~/.picoclaw/workspace/assistant", + "model": { + "primary": "anthropic/claude-opus-4-5", + "fallbacks": ["gpt-4o"] + }, + "subagents": { + "allow_agents": ["researcher", "coder"] + } + }, + { + "id": "researcher", + "name": "Research Agent", + "model": "perplexity/llama-3.1-sonar-large-128k-online", + "skills": ["web-search"] + } + ] + } +} +``` + +## Bindings Configuration + +Route messages from channels to specific agents. + +| Option | Type | Description | +|--------|------|-------------| +| `agent_id` | string | Target agent ID | +| `match.channel` | string | Channel name | +| `match.account_id` | string | Account filter | +| `match.peer.kind` | string | Peer type (user, group, channel) | +| `match.peer.id` | string | Peer ID | +| `match.guild_id` | string | Discord guild ID | +| `match.team_id` | string | Slack team ID | + +**Example:** + +```json +{ + "bindings": [ + { + "agent_id": "personal", + "match": { "channel": "telegram", "peer": { "kind": "user", "id": "123456789" } } + }, + { + "agent_id": "work", + "match": { "channel": "slack", "team_id": "T12345" } + } + ] +} +``` + +## Session Configuration + +Configure session management. + +| Option | Type | Description | +|--------|------|-------------| +| `dm_scope` | string | DM session scope: `main`, `per-agent`, `per-channel` | +| `identity_links` | object | Map user IDs across platforms | + +**Example:** + +```json +{ + "session": { + "dm_scope": "per-agent", + "identity_links": { + "telegram:123456789": ["discord:987654321", "slack:U12345"] + } + } +} +``` + +## Channels Configuration + +Configure chat platform integrations. + +### Telegram + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable Telegram channel | +| `token` | string | `""` | Bot token from @BotFather | +| `proxy` | string | `""` | Proxy URL (optional) | +| `allow_from` | []string | `[]` | Allowed user IDs (empty = all) | + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "123456:ABC...", + "allow_from": ["123456789"] + } + } +} +``` + +### Discord + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable Discord channel | +| `token` | string | `""` | Bot token | +| `allow_from` | []string | `[]` | Allowed user IDs | + +```json +{ + "channels": { + "discord": { + "enabled": true, + "token": "MTk4NjIyNDgzNDc...", + "allow_from": ["123456789012345678"] + } + } +} +``` + +### Slack + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable Slack channel | +| `bot_token` | string | `""` | Bot token (xoxb-...) | +| `app_token` | string | `""` | App token (xapp-...) | +| `allow_from` | []string | `[]` | Allowed user IDs | + +### LINE + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable LINE channel | +| `channel_secret` | string | `""` | Channel secret | +| `channel_access_token` | string | `""` | Channel access token | +| `webhook_host` | string | `0.0.0.0` | Webhook host | +| `webhook_port` | int | `18791` | Webhook port | +| `webhook_path` | string | `/webhook/line` | Webhook path | +| `allow_from` | []string | `[]` | Allowed user IDs | + +### WhatsApp + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable WhatsApp channel | +| `bridge_url` | string | `ws://localhost:3001` | Bridge WebSocket URL | +| `allow_from` | []string | `[]` | Allowed user IDs | + +### Feishu/Lark + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable Feishu channel | +| `app_id` | string | `""` | App ID | +| `app_secret` | string | `""` | App secret | +| `encrypt_key` | string | `""` | Encryption key | +| `verification_token` | string | `""` | Verification token | +| `allow_from` | []string | `[]` | Allowed user IDs | + +### DingTalk + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable DingTalk channel | +| `client_id` | string | `""` | Client ID | +| `client_secret` | string | `""` | Client secret | +| `allow_from` | []string | `[]` | Allowed user IDs | + +### QQ + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable QQ channel | +| `app_id` | string | `""` | App ID | +| `app_secret` | string | `""` | App secret | +| `allow_from` | []string | `[]` | Allowed user IDs | + +### OneBot + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable OneBot channel | +| `ws_url` | string | `ws://127.0.0.1:3001` | WebSocket URL | +| `access_token` | string | `""` | Access token | +| `reconnect_interval` | int | `5` | Reconnect interval (seconds) | +| `group_trigger_prefix` | []string | `[]` | Trigger prefixes for groups | +| `allow_from` | []string | `[]` | Allowed user IDs | + +### MaixCam + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable MaixCam channel | +| `host` | string | `0.0.0.0` | Server host | +| `port` | int | `18790` | Server port | +| `allow_from` | []string | `[]` | Allowed user IDs | + +## Providers Configuration + +Configure LLM providers. See [Providers Guide](../user-guide/providers/README.md) for detailed setup. + +### Common Provider Options + +| Option | Type | Description | +|--------|------|-------------| +| `api_key` | string | API key | +| `api_base` | string | API base URL (optional) | +| `proxy` | string | Proxy URL (optional) | +| `auth_method` | string | Auth method: `oauth`, `token`, `codex-cli` | + +### Provider-Specific Options + +**OpenAI:** + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `web_search` | bool | `true` | Enable web search in responses | + +**Example:** + +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx", + "api_base": "https://openrouter.ai/api/v1" + }, + "zhipu": { + "api_key": "xxx.xxx", + "api_base": "https://open.bigmodel.cn/api/paas/v4" + }, + "anthropic": { + "api_key": "", + "auth_method": "token" + }, + "openai": { + "api_key": "", + "web_search": true, + "auth_method": "oauth" + }, + "groq": { + "api_key": "gsk_xxx" + }, + "gemini": { + "api_key": "" + }, + "ollama": { + "api_key": "", + "api_base": "http://localhost:11434/v1" + }, + "vllm": { + "api_key": "local", + "api_base": "http://localhost:8000/v1" + } + } +} +``` + +## Tools Configuration + +Configure tool behavior. + +### Web Tools + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `brave.enabled` | bool | `false` | Enable Brave Search | +| `brave.api_key` | string | `""` | Brave API key | +| `brave.max_results` | int | `5` | Max search results | +| `duckduckgo.enabled` | bool | `true` | Enable DuckDuckGo | +| `duckduckgo.max_results` | int | `5` | Max search results | +| `perplexity.enabled` | bool | `false` | Enable Perplexity | +| `perplexity.api_key` | string | `""` | Perplexity API key | +| `perplexity.max_results` | int | `5` | Max search results | + +### Cron Tools + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `exec_timeout_minutes` | int | `5` | Timeout for cron jobs (0 = no timeout) | + +### Exec Tools + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enable_deny_patterns` | bool | `true` | Enable dangerous command blocking | +| `custom_deny_patterns` | []string | `[]` | Additional patterns to block | + +**Example:** + +```json +{ + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "BSA...", + "max_results": 5 + }, + "duckduckgo": { + "enabled": true, + "max_results": 5 + } + }, + "cron": { + "exec_timeout_minutes": 5 + }, + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": ["wget.*"] + } + } +} +``` + +## Gateway Configuration + +Configure the gateway server. + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `host` | string | `0.0.0.0` | Server host | +| `port` | int | `18790` | Server port | + +```json +{ + "gateway": { + "host": "0.0.0.0", + "port": 18790 + } +} +``` + +## Heartbeat Configuration + +Configure periodic tasks. + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `true` | Enable heartbeat service | +| `interval` | int | `30` | Check interval in minutes (min: 5) | + +```json +{ + "heartbeat": { + "enabled": true, + "interval": 30 + } +} +``` + +## Devices Configuration + +Configure device monitoring. + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `false` | Enable device service | +| `monitor_usb` | bool | `true` | Monitor USB devices (Linux only) | + +```json +{ + "devices": { + "enabled": false, + "monitor_usb": true + } +} +``` + +## Environment Variables + +All configuration options can be overridden with environment variables using the pattern: + +``` +PICOCLAW_
_ +``` + +### Examples + +| Config Path | Environment Variable | +|-------------|---------------------| +| `agents.defaults.model` | `PICOCLAW_AGENTS_DEFAULTS_MODEL` | +| `providers.openrouter.api_key` | `PICOCLAW_PROVIDERS_OPENROUTER_API_KEY` | +| `channels.telegram.enabled` | `PICOCLAW_CHANNELS_TELEGRAM_ENABLED` | +| `tools.web.duckduckgo.enabled` | `PICOCLAW_TOOLS_WEB_DUCKDUCKGO_ENABLED` | +| `heartbeat.enabled` | `PICOCLAW_HEARTBEAT_ENABLED` | +| `heartbeat.interval` | `PICOCLAW_HEARTBEAT_INTERVAL` | + +**Usage:** + +```bash +export PICOCLAW_AGENTS_DEFAULTS_MODEL="gpt-4o" +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" +export PICOCLAW_HEARTBEAT_ENABLED="false" + +picoclaw agent -m "Hello" +``` + +## Complete Example + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "restrict_to_workspace": true, + "model": "anthropic/claude-opus-4-5", + "model_fallbacks": ["gpt-4o", "glm-4.7"], + "max_tokens": 8192, + "temperature": 0.7, + "max_tool_iterations": 20 + } + }, + "channels": { + "telegram": { + "enabled": true, + "token": "123456:ABC...", + "allow_from": ["123456789"] + }, + "discord": { + "enabled": true, + "token": "MTk4NjIyNDgzNDc...", + "allow_from": ["123456789012345678"] + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + }, + "groq": { + "api_key": "gsk_xxx" + }, + "zhipu": { + "api_key": "xxx.xxx" + } + }, + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "BSA...", + "max_results": 5 + }, + "duckduckgo": { + "enabled": true, + "max_results": 5 + } + } + }, + "gateway": { + "host": "0.0.0.0", + "port": 18790 + }, + "heartbeat": { + "enabled": true, + "interval": 30 + } +} +``` diff --git a/docs/deployment/README.md b/docs/deployment/README.md new file mode 100644 index 0000000000..5290a81301 --- /dev/null +++ b/docs/deployment/README.md @@ -0,0 +1,176 @@ +# Deployment Guide + +This section covers deploying PicoClaw in various environments, from local development to production servers and embedded devices. + +## Deployment Options + +PicoClaw is designed to run anywhere - from powerful servers to ultra-low-cost single-board computers. Choose the deployment method that fits your needs: + +### By Environment + +| Environment | Best For | Guide | +|-------------|----------|-------| +| **Docker** | Containerized deployments, easy scaling | [Docker Guide](docker.md) | +| **Systemd** | Linux servers, always-on services | [Systemd Guide](systemd.md) | +| **Termux** | Android phones/tablets | [Termux Guide](termux.md) | +| **Single-Board Computers** | Edge devices, IoT | [SBC Guide](sbc/README.md) | + +### By Hardware + +| Hardware | Cost | Use Case | +|----------|------|----------| +| Any Linux server | Varies | Production deployments | +| Raspberry Pi 4/5 | $35-80 | Home automation, bots | +| LicheeRV Nano | $9.9 | Ultra-low-cost edge AI | +| MaixCAM | $50 | AI camera applications | +| Android (Termux) | Free | Repurpose old phones | + +## Quick Start + +### Option 1: Binary (Simplest) + +```bash +# Download precompiled binary +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-amd64 +chmod +x picoclaw-linux-amd64 + +# Initialize configuration +./picoclaw-linux-amd64 onboard + +# Edit config with your API keys +nano ~/.picoclaw/config.json + +# Run gateway (always-on bot) +./picoclaw-linux-amd64 gateway +``` + +### Option 2: Docker + +```bash +# Clone repository +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw + +# Configure +cp config/config.example.json config/config.json +# Edit config.json with your API keys + +# Start gateway +docker compose --profile gateway up -d +``` + +### Option 3: Build from Source + +```bash +# Requires Go 1.21+ +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw + +make deps +make build +make install + +picoclaw onboard +picoclaw gateway +``` + +## Operating Modes + +PicoClaw supports two main operating modes: + +### Agent Mode (One-Shot) + +Run a single query and exit. Useful for CLI integration, scripts, and testing. + +```bash +# Single query +picoclaw agent -m "What is the weather today?" + +# Interactive session +picoclaw agent + +# Debug mode +picoclaw agent --debug -m "Hello" +``` + +### Gateway Mode (Always-On) + +Run as a long-running bot that connects to chat platforms. + +```bash +# Start gateway (connects to Telegram, Discord, etc.) +picoclaw gateway + +# With debug logging +picoclaw gateway --debug +``` + +## Configuration + +PicoClaw uses a single configuration file at `~/.picoclaw/config.json`. See the [Configuration File Reference](../configuration/config-file.md) for complete details. + +### Minimum Configuration + +```json +{ + "agents": { + "defaults": { + "model": "openrouter/anthropic/claude-opus-4-5" + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-your-key-here" + } + } +} +``` + +### Environment Variables + +All config options can be set via environment variables: + +```bash +export PICOCLAW_AGENTS_DEFAULTS_MODEL="gpt-4o" +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" + +picoclaw agent -m "Hello" +``` + +## Next Steps + +1. **Docker Deployment** - [docker.md](docker.md) - Container-based deployment +2. **Systemd Service** - [systemd.md](systemd.md) - Run as a Linux service +3. **Security Checklist** - [security.md](security.md) - Production security +4. **Single-Board Computers** - [sbc/README.md](sbc/README.md) - Raspberry Pi, LicheeRV, MaixCAM +5. **Android/Termux** - [termux.md](termux.md) - Run on Android devices + +## Troubleshooting + +### Common Issues + +**Permission denied:** +```bash +chmod +x picoclaw-* +``` + +**Command not found:** +```bash +# Add to PATH +export PATH="$PWD:$PATH" +# Or install to system +sudo mv picoclaw-* /usr/local/bin/picoclaw +``` + +**Config file not found:** +```bash +# Initialize config +picoclaw onboard +``` + +**API errors:** +- Verify API keys are correct +- Check network connectivity +- Review provider-specific documentation + +For more help, see the [Troubleshooting Guide](../operations/troubleshooting.md). diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md new file mode 100644 index 0000000000..3eca48a808 --- /dev/null +++ b/docs/deployment/docker.md @@ -0,0 +1,433 @@ +# Docker Deployment + +PicoClaw provides official Docker support with multi-stage builds for minimal image sizes. This guide covers deploying PicoClaw using Docker and Docker Compose. + +## Prerequisites + +- Docker 20.10 or later +- Docker Compose V2 (recommended) +- API keys for your LLM providers + +## Quick Start + +### Using Docker Compose (Recommended) + +```bash +# Clone the repository +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw + +# Create configuration +mkdir -p config +cp config/config.example.json config/config.json + +# Edit configuration with your API keys +nano config/config.json + +# Start gateway mode (always-on bot) +docker compose --profile gateway up -d + +# View logs +docker compose logs -f picoclaw-gateway +``` + +### One-Shot Agent Mode + +Run a single query using Docker: + +```bash +# Run a one-shot query +docker compose run --rm picoclaw-agent -m "Hello, how are you?" + +# Interactive mode +docker compose run --rm -it picoclaw-agent +``` + +## Docker Compose Configuration + +The included `docker-compose.yml` defines two services: + +### Gateway Service (Always-On Bot) + +```yaml +picoclaw-gateway: + build: + context: . + dockerfile: Dockerfile + container_name: picoclaw-gateway + restart: unless-stopped + profiles: + - gateway + volumes: + - ./config/config.json:/home/picoclaw/.picoclaw/config.json:ro + - picoclaw-workspace:/home/picoclaw/.picoclaw/workspace + command: ["gateway"] +``` + +### Agent Service (One-Shot) + +```yaml +picoclaw-agent: + build: + context: . + dockerfile: Dockerfile + container_name: picoclaw-agent + profiles: + - agent + volumes: + - ./config/config.json:/home/picoclaw/.picoclaw/config.json:ro + - picoclaw-workspace:/home/picoclaw/.picoclaw/workspace + entrypoint: ["picoclaw", "agent"] + stdin_open: true + tty: true +``` + +## Building the Image + +### Standard Build + +```bash +# Build using Docker Compose +docker compose build + +# Or build directly +docker build -t picoclaw:latest . +``` + +### Build with Custom Arguments + +```bash +# Build with specific Go version +docker build --build-arg GO_VERSION=1.23 -t picoclaw:latest . +``` + +### Multi-Platform Build + +Build for multiple architectures using buildx: + +```bash +# Enable buildx +docker buildx create --use + +# Build for multiple platforms +docker buildx build --platform linux/amd64,linux/arm64 -t picoclaw:latest . +``` + +## Running the Container + +### Basic Run + +```bash +# Run gateway mode +docker run -d \ + --name picoclaw \ + -v $(pwd)/config/config.json:/home/picoclaw/.picoclaw/config.json:ro \ + -v picoclaw-workspace:/home/picoclaw/.picoclaw/workspace \ + picoclaw:latest gateway + +# Run agent mode (one-shot) +docker run --rm \ + -v $(pwd)/config/config.json:/home/picoclaw/.picoclaw/config.json:ro \ + -v picoclaw-workspace:/home/picoclaw/.picoclaw/workspace \ + picoclaw:latest agent -m "Hello" +``` + +### With Environment Variables + +```bash +docker run -d \ + --name picoclaw \ + -e PICOCLAW_AGENTS_DEFAULTS_MODEL="gpt-4o" \ + -e PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" \ + -v picoclaw-workspace:/home/picoclaw/.picoclaw/workspace \ + picoclaw:latest gateway +``` + +### With Port Mapping + +If you need to expose the gateway HTTP server: + +```bash +docker run -d \ + --name picoclaw \ + -p 18790:18790 \ + -v $(pwd)/config/config.json:/home/picoclaw/.picoclaw/config.json:ro \ + -v picoclaw-workspace:/home/picoclaw/.picoclaw/workspace \ + picoclaw:latest gateway +``` + +## Volume Management + +### Persistent Workspace + +The workspace volume stores sessions, memory, and other persistent data: + +```bash +# List volumes +docker volume ls + +# Inspect workspace volume +docker volume inspect picoclaw-workspace + +# Backup workspace +docker run --rm -v picoclaw-workspace:/data -v $(pwd):/backup alpine tar czf /backup/workspace-backup.tar.gz /data + +# Restore workspace +docker run --rm -v picoclaw-workspace:/data -v $(pwd):/backup alpine tar xzf /backup/workspace-backup.tar.gz -C / +``` + +### Configuration Mount + +Configuration is mounted read-only for security: + +```bash +# Mount config from host +-v /path/to/config.json:/home/picoclaw/.picoclaw/config.json:ro +``` + +## Health Checks + +The Dockerfile includes a built-in health check: + +```dockerfile +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget -q --spider http://localhost:18790/health || exit 1 +``` + +Check container health: + +```bash +# View health status +docker ps --format "table {{.Names}}\t{{.Status}}" + +# Inspect health details +docker inspect --format='{{json .State.Health}}' picoclaw-gateway | jq +``` + +## Logging + +### View Logs + +```bash +# Docker Compose logs +docker compose logs -f picoclaw-gateway + +# Docker logs +docker logs -f picoclaw-gateway + +# Last 100 lines +docker logs --tail 100 picoclaw-gateway +``` + +### Configure Log Driver + +```yaml +services: + picoclaw-gateway: + # ... other config ... + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" +``` + +## Advanced Configuration + +### Custom Docker Compose File + +Create `docker-compose.prod.yml` for production: + +```yaml +services: + picoclaw-gateway: + image: picoclaw:latest + restart: always + environment: + - PICOCLAW_HEARTBEAT_ENABLED=true + - PICOCLAW_HEARTBEAT_INTERVAL=30 + volumes: + - ./config/production.json:/home/picoclaw/.picoclaw/config.json:ro + - picoclaw-workspace:/home/picoclaw/.picoclaw/workspace + logging: + driver: "json-file" + options: + max-size: "50m" + max-file: "5" + deploy: + resources: + limits: + memory: 512M + reservations: + memory: 128M + command: ["gateway"] + +volumes: + picoclaw-workspace: +``` + +Run with: + +```bash +docker compose -f docker-compose.prod.yml up -d +``` + +### Network Configuration + +For connecting to other services: + +```yaml +services: + picoclaw-gateway: + networks: + - picoclaw-net + - external-net + +networks: + picoclaw-net: + driver: bridge + external-net: + external: true +``` + +### Secrets Management + +Using Docker secrets (Swarm mode): + +```yaml +services: + picoclaw-gateway: + secrets: + - openrouter_api_key + environment: + - PICOCLAW_PROVIDERS_OPENROUTER_API_KEY_FILE=/run/secrets/openrouter_api_key + +secrets: + openrouter_api_key: + external: true +``` + +## Production Deployment + +### Recommendations + +1. **Use specific version tags** instead of `latest`: + ```bash + docker pull picoclaw:v0.1.1 + ``` + +2. **Set resource limits**: + ```yaml + deploy: + resources: + limits: + memory: 512M + cpus: '1.0' + ``` + +3. **Configure log rotation** to prevent disk exhaustion + +4. **Use health checks** for orchestration + +5. **Mount configuration read-only** for security + +### Example Production docker-compose.yml + +```yaml +version: "3.8" + +services: + picoclaw-gateway: + image: ghcr.io/sipeed/picoclaw:v0.1.1 + container_name: picoclaw-gateway + restart: always + profiles: + - gateway + volumes: + - ./config/production.json:/home/picoclaw/.picoclaw/config.json:ro + - picoclaw-workspace:/home/picoclaw/.picoclaw/workspace + environment: + - TZ=UTC + logging: + driver: "json-file" + options: + max-size: "50m" + max-file: "5" + deploy: + resources: + limits: + memory: 512M + reservations: + memory: 128M + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://localhost:18790/health"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 10s + command: ["gateway"] + +volumes: + picoclaw-workspace: + driver: local +``` + +## Troubleshooting + +### Container won't start + +```bash +# Check logs +docker compose logs picoclaw-gateway + +# Check config file exists +ls -la config/config.json + +# Verify JSON syntax +cat config/config.json | jq . +``` + +### Permission issues + +```bash +# The container runs as non-root user (uid 1000) +# Ensure config file is readable +chmod 644 config/config.json +``` + +### API connection issues + +```bash +# Verify network connectivity from container +docker compose exec picoclaw-gateway wget -q -O- https://api.openai.com/v1/models + +# Check DNS resolution +docker compose exec picoclaw-gateway nslookup api.openai.com +``` + +### Volume issues + +```bash +# List volumes +docker volume ls + +# Remove and recreate volume (WARNING: destroys data) +docker compose down -v +docker compose up -d +``` + +### Reset everything + +```bash +# Stop containers +docker compose down + +# Remove volumes +docker compose down -v + +# Rebuild image +docker compose build --no-cache + +# Start fresh +docker compose --profile gateway up -d +``` diff --git a/docs/deployment/sbc/README.md b/docs/deployment/sbc/README.md new file mode 100644 index 0000000000..93fef290ba --- /dev/null +++ b/docs/deployment/sbc/README.md @@ -0,0 +1,351 @@ +# Single-Board Computer Deployment + +PicoClaw is optimized for resource-constrained environments, making it ideal for single-board computers (SBCs). This section covers deployment on popular low-cost hardware platforms. + +## Why PicoClaw on SBCs? + +- **Ultra-lightweight**: Single binary, minimal dependencies +- **Low resource usage**: Runs comfortably on 256MB RAM +- **Native ARM64 support**: No emulation required +- **Offline capable**: Works with local LLM providers (Ollama, vLLM) +- **Always-on**: Low power consumption for 24/7 operation + +## Supported Hardware + +| Hardware | Price | Architecture | RAM | Recommended For | +|----------|-------|--------------|-----|-----------------| +| [Raspberry Pi 4/5](rpi.md) | $35-80 | ARM64 | 2-8GB | Home automation, general use | +| [LicheeRV Nano](licheerv-nano.md) | $9.9 | RISC-V | 64MB | Ultra-low-cost edge AI | +| [MaixCAM](maixcam.md) | $50 | RISC-V | 256MB | AI camera applications | +| Orange Pi | $15-50 | ARM64 | 1-4GB | Budget alternative | +| Rock Pi | $35-75 | ARM64 | 1-4GB | More I/O options | +| NanoPi | $15-60 | ARM64 | 512MB-4GB | Compact form factor | + +## Architecture Support + +PicoClaw provides precompiled binaries for all major SBC architectures: + +| Architecture | Binary Name | Devices | +|--------------|-------------|---------| +| ARM64 | `picoclaw-linux-arm64` | Raspberry Pi 4/5, Orange Pi, most SBCs | +| RISC-V 64 | `picoclaw-linux-riscv64` | LicheeRV Nano, MaixCAM | +| LoongArch | `picoclaw-linux-loong64` | Loongson-based devices | + +## Quick Start + +### Generic Installation + +Most SBCs running Linux can use this approach: + +```bash +# Download the appropriate binary for your architecture +# For ARM64 (most SBCs): +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-arm64 + +# For RISC-V: +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-riscv64 + +# Make executable +chmod +x picoclaw-linux-* + +# Initialize +./picoclaw-linux-* onboard + +# Configure +nano ~/.picoclaw/config.json + +# Run +./picoclaw-linux-* gateway +``` + +### Check Your Architecture + +```bash +uname -m +# aarch64 = ARM64 (use picoclaw-linux-arm64) +# riscv64 = RISC-V (use picoclaw-linux-riscv64) +# loongarch64 = LoongArch (use picoclaw-linux-loong64) +``` + +## Common Configuration + +### Minimal Memory Configuration + +For devices with limited RAM: + +```json +{ + "agents": { + "defaults": { + "model": "openrouter/anthropic/claude-sonnet-4", + "max_tokens": 2048, + "max_tool_iterations": 10 + } + }, + "heartbeat": { + "enabled": false + }, + "devices": { + "enabled": false + } +} +``` + +### Local LLM Integration + +Use with Ollama for offline operation: + +```json +{ + "agents": { + "defaults": { + "model": "ollama/llama3.2:1b" + } + }, + "providers": { + "ollama": { + "api_base": "http://localhost:11434/v1" + } + } +} +``` + +### Power Management + +For battery-powered or solar setups: + +```bash +# Reduce CPU frequency +echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Disable unnecessary services +sudo systemctl disable bluetooth +sudo systemctl disable avahi-daemon +``` + +## Performance Tuning + +### Memory Optimization + +```bash +# Create swap file (if needed) +sudo fallocate -l 1G /swapfile +sudo chmod 600 /swapfile +sudo mkswap /swapfile +sudo swapon /swapfile + +# Add to /etc/fstab for persistence +/swapfile none swap sw 0 0 +``` + +### CPU Optimization + +```bash +# Check CPU info +cat /proc/cpuinfo + +# Set performance governor +echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor +``` + +### Storage Optimization + +```bash +# Use tmpfs for temporary files +sudo mount -t tmpfs -o size=100M tmpfs /tmp + +# Disable access time updates in /etc/fstab +# Add noatime to your root partition options +``` + +## Systemd Service Setup + +For always-on operation, set up as a systemd service: + +```bash +# Create service file +sudo tee /etc/systemd/system/picoclaw.service << 'EOF' +[Unit] +Description=PicoClaw AI Assistant +After=network.target + +[Service] +Type=simple +User=picoclaw +ExecStart=/usr/local/bin/picoclaw gateway +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +# Enable and start +sudo systemctl daemon-reload +sudo systemctl enable picoclaw +sudo systemctl start picoclaw +``` + +See the [Systemd Guide](../systemd.md) for detailed configuration. + +## Network Configuration + +### Static IP + +Set up a static IP for reliable access: + +```bash +# Using nmcli +nmcli con mod "Wired connection 1" ipv4.addresses 192.168.1.100/24 +nmcli con mod "Wired connection 1" ipv4.gateway 192.168.1.1 +nmcli con mod "Wired connection 1" ipv4.dns "8.8.8.8" +nmcli con mod "Wired connection 1" ipv4.method manual +nmcli con up "Wired connection 1" +``` + +### WiFi Setup + +```bash +# Using nmcli +nmcli dev wifi connect "SSID" password "PASSWORD" +``` + +### Access Point Mode + +Turn your SBC into a WiFi access point: + +```bash +# Install hostapd +sudo apt install hostapd dnsmasq + +# Configure access point +sudo tee /etc/hostapd/hostapd.conf << 'EOF' +interface=wlan0 +driver=nl80211 +ssid=PicoClaw +hw_mode=g +channel=7 +wpa=2 +wpa_passphrase=yourpassword +wpa_key_mgmt=WPA-PSK +EOF + +# Enable +sudo systemctl enable hostapd +sudo systemctl start hostapd +``` + +## Monitoring + +### Resource Monitoring + +```bash +# Install monitoring tools +sudo apt install htop iotop + +# Monitor resources +htop + +# Check temperature (Raspberry Pi) +vcgencmd measure_temp + +# Check memory +free -h +``` + +### Health Monitoring Script + +```bash +#!/bin/bash +# health-check.sh + +# Check if PicoClaw is running +if ! pgrep -f "picoclaw gateway" > /dev/null; then + echo "PicoClaw not running, restarting..." + systemctl restart picoclaw +fi + +# Check memory usage +MEM_USED=$(free | grep Mem | awk '{print int($3/$2 * 100)}') +if [ "$MEM_USED" -gt 90 ]; then + echo "Memory usage high: ${MEM_USED}%" +fi + +# Check disk space +DISK_USED=$(df -h / | tail -1 | awk '{print int($5)}') +if [ "$DISK_USED" -gt 90 ]; then + echo "Disk usage high: ${DISK_USED}%" +fi +``` + +## Troubleshooting + +### Out of Memory + +```bash +# Check memory +free -h + +# Add swap +sudo fallocate -l 512M /swapfile +sudo chmod 600 /swapfile +sudo mkswap /swapfile +sudo swapon /swapfile + +# Reduce memory in config +# Set lower max_tokens value +``` + +### Slow Performance + +```bash +# Check CPU governor +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Set performance mode +echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Check for thermal throttling +cat /sys/class/thermal/thermal_zone*/temp +``` + +### Network Issues + +```bash +# Check network interface +ip addr + +# Test connectivity +ping google.com + +# Check DNS +nslookup api.openai.com +``` + +### Binary Not Executing + +```bash +# Check architecture +uname -m + +# Verify binary architecture +file picoclaw-linux-* + +# Check permissions +ls -la picoclaw-linux-* + +# Check for missing libraries +ldd picoclaw-linux-* +``` + +## Hardware-Specific Guides + +- [Raspberry Pi 4/5](rpi.md) - Full guide for the most popular SBC +- [LicheeRV Nano](licheerv-nano.md) - Ultra-low-cost RISC-V board +- [MaixCAM](maixcam.md) - AI camera with built-in PicoClaw support + +## Community Resources + +- [PicoClaw GitHub](https://github.com/sipeed/picoclaw) +- [Sipeed Wiki](https://wiki.sipeed.com/) +- [Raspberry Pi Forums](https://forums.raspberrypi.com/) diff --git a/docs/deployment/sbc/licheerv-nano.md b/docs/deployment/sbc/licheerv-nano.md new file mode 100644 index 0000000000..715223a11b --- /dev/null +++ b/docs/deployment/sbc/licheerv-nano.md @@ -0,0 +1,479 @@ +# LicheeRV Nano Deployment + +LicheeRV Nano is an ultra-low-cost RISC-V single-board computer at just $9.9, making it the most affordable way to run PicoClaw. This guide covers setup and deployment on this remarkable little board. + +## Hardware Specifications + +| Specification | Value | +|---------------|-------| +| CPU | SG2002 (RISC-V C906 @ 1GHz) | +| RAM | 64MB DDR2 | +| Storage | MicroSD card slot | +| Network | 10/100 Ethernet | +| USB | 1x USB 2.0 | +| Video | HDMI output | +| Price | $9.9 USD | + +## Where to Buy + +- [Sipeed Official Store](https://www.aliexpress.com/store/911197660) +- [Seeed Studio](https://www.seeedstudio.com/) + +## Operating System Setup + +### Download Image + +LicheeRV Nano uses Buildroot-based Linux images: + +```bash +# Download from Sipeed +# https://github.com/sipeed/LicheeRV-Nano-Build/releases + +# Choose the latest release +wget https://github.com/sipeed/LicheeRV-Nano-Build/releases/download/v0.2/licheervnano-0.2.img.gz + +# Decompress +gunzip licheervnano-0.2.img.gz +``` + +### Flash to SD Card + +```bash +# Using dd (Linux/macOS) +sudo dd if=licheervnano-0.2.img of=/dev/sdX bs=4M status=progress +sync + +# Or use balenaEtcher (cross-platform) +# https://www.balena.io/etcher/ +``` + +### First Boot + +1. Insert the microSD card into LicheeRV Nano +2. Connect HDMI monitor (optional) or serial console +3. Connect Ethernet +4. Power on via USB-C + +Default login: +- Username: `root` +- Password: `licheepi` (or no password) + +### Serial Console Setup + +If you don't have HDMI: + +```bash +# Connect USB-TTL adapter to GPIO pins: +# - TX -> GPIO 12 (RX) +# - RX -> GPIO 13 (TX) +# - GND -> GND + +# Use screen or minicom +screen /dev/ttyUSB0 115200 +# or +minicom -D /dev/ttyUSB0 +``` + +## Network Configuration + +### DHCP (Default) + +The system should automatically obtain an IP address via DHCP: + +```bash +# Check IP address +ip addr show eth0 + +# Or check DHCP leases on your router +``` + +### Static IP + +```bash +# Edit network configuration +cat > /etc/network/interfaces.d/eth0 << 'EOF' +auto eth0 +iface eth0 inet static + address 192.168.1.100 + netmask 255.255.255.0 + gateway 192.168.1.1 + dns-nameservers 8.8.8.8 8.8.4.4 +EOF + +# Restart networking +/etc/init.d/networking restart +``` + +### SSH Access + +```bash +# Start SSH daemon (if not running) +/etc/init.d/ssh start + +# Enable on boot +update-rc.d ssh defaults + +# Connect from another machine +ssh root@192.168.1.100 +``` + +## Installing PicoClaw + +### Download RISC-V Binary + +```bash +# Download RISC-V 64-bit binary +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-riscv64 + +# Make executable +chmod +x picoclaw-linux-riscv64 + +# Move to system path +mv picoclaw-linux-riscv64 /usr/local/bin/picoclaw +``` + +### Initialize Configuration + +```bash +# Initialize +picoclaw onboard + +# Edit configuration +vi ~/.picoclaw/config.json +``` + +### Minimal Configuration + +Due to limited memory (64MB), use minimal settings: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "restrict_to_workspace": true, + "model": "openrouter/anthropic/claude-sonnet-4", + "max_tokens": 1024, + "max_tool_iterations": 5, + "temperature": 0.7 + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-your-key-here" + } + }, + "gateway": { + "host": "127.0.0.1", + "port": 18790 + }, + "heartbeat": { + "enabled": false + }, + "devices": { + "enabled": false + } +} +``` + +## Memory Optimization + +The 64MB RAM limitation requires careful optimization: + +### Create Swap File + +```bash +# Create 128MB swap file +dd if=/dev/zero of=/swapfile bs=1M count=128 +mkswap /swapfile +swapon /swapfile + +# Add to fstab for persistence +echo "/swapfile none swap sw 0 0" >> /etc/fstab +``` + +### Disable Unnecessary Services + +```bash +# List running services +ps aux + +# Stop and disable unnecessary services +/etc/init.d/crond stop +update-rc.d -f crond remove + +# If not using GUI +/etc/init.d/lightdm stop +update-rc.d -f lightdm remove +``` + +### Use tmpfs + +```bash +# Mount /tmp as tmpfs +mount -t tmpfs -o size=16M tmpfs /tmp + +# Add to fstab +echo "tmpfs /tmp tmpfs defaults,size=16M 0 0" >> /etc/fstab +``` + +## Running PicoClaw + +### Interactive Testing + +```bash +# Test agent mode +picoclaw agent -m "Hello" + +# Debug mode +picoclaw agent --debug -m "What is 2+2?" +``` + +### Gateway Mode + +```bash +# Start gateway +picoclaw gateway + +# In background +nohup picoclaw gateway > picoclaw.log 2>&1 & + +# View logs +tail -f picoclaw.log +``` + +### As a Service + +Create init script for Buildroot: + +```bash +cat > /etc/init.d/picoclaw << 'EOF' +#!/bin/sh + +DAEMON=/usr/local/bin/picoclaw +DAEMON_ARGS="gateway" +PIDFILE=/var/run/picoclaw.pid + +case "$1" in + start) + echo "Starting PicoClaw..." + start-stop-daemon -S -b -m -p $PIDFILE -x $DAEMON -- $DAEMON_ARGS + ;; + stop) + echo "Stopping PicoClaw..." + start-stop-daemon -K -p $PIDFILE -x $DAEMON + rm -f $PIDFILE + ;; + restart) + $0 stop + sleep 1 + $0 start + ;; + status) + if [ -f $PIDFILE ]; then + echo "PicoClaw is running" + else + echo "PicoClaw is not running" + fi + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac + +exit 0 +EOF + +chmod +x /etc/init.d/picoclaw +update-rc.d picoclaw defaults +``` + +## Use Cases + +### Telegram Bot + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + } + } +} +``` + +### Home Automation Controller + +Use with GPIO for home automation: + +```bash +# Control GPIO (example) +echo 17 > /sys/class/gpio/export +echo out > /sys/class/gpio/gpio17/direction +echo 1 > /sys/class/gpio/gpio17/value +``` + +### Edge AI Integration + +Process sensor data and make decisions: + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": ["rm -rf", "reboot"] + } + }, + "heartbeat": { + "enabled": true, + "interval": 60 + } +} +``` + +## Performance Tips + +### Optimize Network + +```bash +# Use wired Ethernet for stability +# Keep connections minimal + +# Reduce DNS lookups +echo "nameserver 8.8.8.8" > /etc/resolv.conf +``` + +### Reduce Logging + +```bash +# Run without debug output +picoclaw gateway + +# Limit log file size +picoclaw gateway 2>&1 | rotatelogs /var/log/picoclaw-%Y%m%d.log 86400 & +``` + +### Monitor Resources + +```bash +# Check memory +free -m + +# Check CPU +top + +# Check temperature (if available) +cat /sys/class/thermal/thermal_zone*/temp +``` + +## Troubleshooting + +### Out of Memory + +```bash +# Check memory usage +free -m + +# If OOM, increase swap +swapoff /swapfile +dd if=/dev/zero of=/swapfile bs=1M count=256 +mkswap /swapfile +swapon /swapfile + +# Reduce max_tokens in config +``` + +### Binary Not Executing + +```bash +# Check architecture +uname -m +# Should show: riscv64 + +# Verify binary +file /usr/local/bin/picoclaw + +# Check if executable +ls -la /usr/local/bin/picoclaw + +# Check dependencies +ldd /usr/local/bin/picoclaw +``` + +### Network Issues + +```bash +# Check interface +ip addr + +# Test connectivity +ping -c 3 google.com + +# Test DNS +nslookup api.openai.com + +# Check routes +ip route +``` + +### Service Won't Start + +```bash +# Check if already running +ps aux | grep picoclaw + +# Check logs +cat picoclaw.log + +# Test manually +picoclaw gateway +``` + +## Advanced Configuration + +### Watchdog + +Set up hardware watchdog for automatic reboot on failure: + +```bash +# Load watchdog module +modprobe dw_wdt + +# Configure watchdog +cat > /etc/watchdog.conf << 'EOF' +watchdog-device = /dev/watchdog +interval = 10 +retry-timeout = 60 +repair-max = 1 +EOF + +# Start watchdog daemon +watchdog +``` + +### Auto-Restart Script + +```bash +#!/bin/sh +# /usr/local/bin/picoclaw-watchdog.sh + +while true; do + if ! pgrep -f "picoclaw gateway" > /dev/null; then + echo "PicoClaw not running, restarting..." + picoclaw gateway >> /var/log/picoclaw.log 2>&1 & + sleep 10 + fi + sleep 30 +done +``` + +## Resources + +- [LicheeRV Nano Wiki](https://wiki.sipeed.com/hardware/zh/lichee/RV_Nano/1_intro.html) +- [Sipeed GitHub](https://github.com/sipeed) +- [PicoClaw Releases](https://github.com/sipeed/picoclaw/releases) +- [RISC-V International](https://riscv.org/) diff --git a/docs/deployment/sbc/maixcam.md b/docs/deployment/sbc/maixcam.md new file mode 100644 index 0000000000..616099c794 --- /dev/null +++ b/docs/deployment/sbc/maixcam.md @@ -0,0 +1,490 @@ +# MaixCAM Deployment + +MaixCAM is an AI camera platform from Sipeed that comes with PicoClaw pre-integrated. This guide covers deployment and configuration on MaixCAM for AI-powered camera applications. + +## Hardware Specifications + +| Specification | Value | +|---------------|-------| +| CPU | AX620E (RISC-V C906 @ 1GHz) | +| NPU | 14.4 TOPS (for AI inference) | +| RAM | 256MB DDR3 | +| Storage | MicroSD card slot | +| Camera | GC2145, support for other modules | +| Display | 2.4" 640x480 touchscreen | +| Network | WiFi 6, Ethernet (via dock) | +| USB | 1x USB 2.0 Type-C | +| Price | ~$50 USD | + +## Where to Buy + +- [Sipeed Official Store](https://www.aliexpress.com/store/911197660) +- [Seeed Studio](https://www.seeedstudio.com/) +- [MaixCAM Product Page](https://wiki.sipeed.com/maixcam) + +## Pre-installed PicoClaw + +MaixCAM comes with PicoClaw pre-installed and configured. The built-in MaixCAM channel allows direct interaction through the device. + +### Quick Start + +1. Power on MaixCAM +2. Connect to WiFi (via touchscreen or web interface) +3. PicoClaw starts automatically +4. Interact via the touchscreen or connect external channels + +## Initial Setup + +### First Boot + +```bash +# Default hostname: maixcam.local +# Default credentials: root / root (or no password) + +# SSH access +ssh root@maixcam.local +``` + +### Network Configuration + +#### WiFi Setup (Touchscreen) + +1. Tap Settings icon on the home screen +2. Select WiFi +3. Choose your network and enter password + +#### WiFi Setup (Command Line) + +```bash +# Using nmcli +nmcli dev wifi connect "SSID" password "PASSWORD" + +# Or using wpa_supplicant +wpa_passphrase "SSID" "PASSWORD" >> /etc/wpa_supplicant.conf +wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf +udhcpc -i wlan0 +``` + +### Static IP + +```bash +# Configure static IP +cat > /etc/network/interfaces.d/eth0 << 'EOF' +auto eth0 +iface eth0 inet static + address 192.168.1.100 + netmask 255.255.255.0 + gateway 192.168.1.1 + dns-nameservers 8.8.8.8 +EOF + +# Restart networking +/etc/init.d/networking restart +``` + +## PicoClaw Configuration + +### Configuration File + +```bash +# Edit configuration +vi ~/.picoclaw/config.json +# or +vi /etc/picoclaw/config.json +``` + +### MaixCAM Channel + +The MaixCAM channel provides native integration: + +```json +{ + "channels": { + "maixcam": { + "enabled": true, + "host": "0.0.0.0", + "port": 18790, + "allow_from": [] + } + } +} +``` + +### Full Configuration Example + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "restrict_to_workspace": true, + "model": "openrouter/anthropic/claude-sonnet-4", + "max_tokens": 2048, + "temperature": 0.7 + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-your-key-here" + }, + "zhipu": { + "api_key": "your-zhipu-key" + } + }, + "channels": { + "maixcam": { + "enabled": true, + "host": "0.0.0.0", + "port": 18790 + }, + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + } + }, + "tools": { + "web": { + "duckduckgo": { + "enabled": true, + "max_results": 5 + } + } + }, + "heartbeat": { + "enabled": true, + "interval": 30 + } +} +``` + +## Camera Integration + +### Taking Photos + +PicoClaw can use the camera through the exec tool: + +```bash +# Take a photo +libcamera-still -o /tmp/photo.jpg + +# Or using the built-in camera tool +maixcam-capture /tmp/photo.jpg +``` + +### Camera Skills + +Create a skill for camera operations: + +```markdown +# Camera Skill + +You can use the camera to take photos and analyze them. + +## Commands + +- Take a photo: `libcamera-still -o /tmp/photo.jpg` +- List photos: `ls -la /tmp/*.jpg` +- Delete photos: `rm /tmp/photo.jpg` + +## Example + +User: "Take a photo and describe what you see" +Action: Take photo using exec tool, then analyze +``` + +### Vision Analysis + +To use vision capabilities: + +1. Set up an image model in config: + +```json +{ + "agents": { + "defaults": { + "model": "openrouter/anthropic/claude-sonnet-4", + "image_model": "openrouter/anthropic/claude-sonnet-4" + } + } +} +``` + +2. Take a photo and ask PicoClaw to analyze it + +## AI Features + +### NPU-Accelerated Inference + +MaixCAM has a built-in NPU for AI inference. While PicoClaw uses cloud LLMs by default, you can: + +1. Run local vision models on the NPU +2. Use local object detection +3. Process images before sending to cloud + +### Local Vision Model + +```bash +# Example: Run object detection +# (Specific commands depend on installed packages) +python3 /opt/maixcam/detection.py --input /tmp/photo.jpg +``` + +### Speech Recognition + +MaixCAM supports voice input: + +```bash +# Audio recording +arecord -d 5 -f cd /tmp/recording.wav + +# Speech-to-text (if configured) +maixcam-asr /tmp/recording.wav +``` + +## Running PicoClaw + +### Starting Manually + +```bash +# Start gateway +picoclaw gateway + +# With debug output +picoclaw gateway --debug + +# Agent mode (one-shot) +picoclaw agent -m "What do you see?" +``` + +### As a Service + +MaixCAM typically runs PicoClaw as a systemd service: + +```bash +# Check status +systemctl status picoclaw + +# Start/stop/restart +sudo systemctl start picoclaw +sudo systemctl stop picoclaw +sudo systemctl restart picoclaw + +# View logs +journalctl -u picoclaw -f +``` + +### Auto-start on Boot + +```bash +# Enable auto-start +sudo systemctl enable picoclaw + +# Disable auto-start +sudo systemctl disable picoclaw +``` + +## Use Cases + +### Security Camera + +Configure PicoClaw for security monitoring: + +```json +{ + "heartbeat": { + "enabled": true, + "interval": 5 + } +} +``` + +Create a heartbeat task that: +1. Captures an image +2. Analyzes for anomalies +3. Sends alerts via Telegram + +### Smart Doorbell + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN" + }, + "maixcam": { + "enabled": true + } + } +} +``` + +Workflow: +1. Doorbell button triggers camera +2. PicoClaw captures and analyzes image +3. Sends notification with photo to Telegram + +### Object Recognition Assistant + +Use with the camera for object identification: + +``` +User: "What is on the table?" +PicoClaw: [Takes photo] "I can see a laptop, coffee mug, and notebook on the table." +``` + +### Plant Monitor + +Monitor plant health: + +```json +{ + "heartbeat": { + "enabled": true, + "interval": 60 + } +} +``` + +## Performance Optimization + +### Memory Management + +```bash +# Check memory +free -m + +# The 256MB RAM should be sufficient for basic operation +# If needed, reduce max_tokens in config +``` + +### CPU Frequency + +```bash +# Check current frequency +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq + +# Set performance governor +echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor +``` + +### Storage + +```bash +# Check disk space +df -h + +# Clean up old sessions +rm -rf ~/.picoclaw/workspace/sessions/*.json.old +``` + +## Web Interface + +MaixCAM includes a web interface for configuration: + +``` +http://maixcam.local/ +``` + +Features: +- Live camera view +- PicoClaw chat interface +- Settings configuration +- System monitoring + +## Troubleshooting + +### PicoClaw Not Starting + +```bash +# Check if running +ps aux | grep picoclaw + +# Check logs +journalctl -u picoclaw -n 100 + +# Test manually +picoclaw gateway --debug +``` + +### Camera Issues + +```bash +# Check camera device +ls -la /dev/video* + +# Test camera +libcamera-hello + +# Check for errors +dmesg | grep -i camera +``` + +### WiFi Connection Issues + +```bash +# Check WiFi status +nmcli dev status + +# Reconnect +nmcli dev wifi connect "SSID" password "PASSWORD" + +# Check signal strength +iwconfig wlan0 +``` + +### Touchscreen Not Responding + +```bash +# Check input devices +cat /proc/bus/input/devices + +# Calibrate touchscreen +ts_calibrate +``` + +### API Errors + +```bash +# Test API connectivity +curl -I https://api.openai.com + +# Check DNS +nslookup api.openai.com + +# Verify API key +echo $PICOCLAW_PROVIDERS_OPENROUTER_API_KEY +``` + +## Updates + +### Update PicoClaw + +```bash +# Download latest version +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-riscv64 +chmod +x picoclaw-linux-riscv64 +sudo mv picoclaw-linux-riscv64 /usr/local/bin/picoclaw + +# Restart service +sudo systemctl restart picoclaw +``` + +### System Update + +```bash +# Update packages +apt update && apt upgrade -y + +# Update firmware (if available) +# Check Sipeed wiki for instructions +``` + +## Resources + +- [MaixCAM Wiki](https://wiki.sipeed.com/maixcam) +- [Sipeed GitHub](https://github.com/sipeed) +- [MaixCAM Examples](https://github.com/sipeed/MaixCAM) +- [PicoClaw GitHub](https://github.com/sipeed/picoclaw) +- [MaixPy Documentation](https://wiki.sipeed.com/maixpy/) diff --git a/docs/deployment/sbc/rpi.md b/docs/deployment/sbc/rpi.md new file mode 100644 index 0000000000..f6a623758a --- /dev/null +++ b/docs/deployment/sbc/rpi.md @@ -0,0 +1,537 @@ +# Raspberry Pi Deployment + +Raspberry Pi is the most popular single-board computer for running PicoClaw. This guide covers deployment on Raspberry Pi 4 and 5, with notes for older models. + +## Prerequisites + +- Raspberry Pi 4 or 5 (recommended) or Pi 3B+ (minimum) +- 2GB RAM minimum, 4GB+ recommended +- microSD card (16GB minimum, 32GB+ recommended) +- Raspberry Pi OS (64-bit recommended) + +## Operating System Setup + +### Download Raspberry Pi OS + +```bash +# On your computer, download Raspberry Pi OS Lite (64-bit) +# https://www.raspberrypi.com/software/operating-systems/ + +# Or use Raspberry Pi Imager +# https://www.raspberrypi.com/software/ +``` + +### Flash and Configure + +Using Raspberry Pi Imager (recommended): + +1. Insert microSD card +2. Open Raspberry Pi Imager +3. Select "Raspberry Pi OS Lite (64-bit)" +4. Click gear icon for advanced options: + - Set hostname: `picoclaw.local` + - Enable SSH + - Set username/password + - Configure WiFi (if using wireless) +5. Write to card + +### First Boot + +```bash +# SSH into your Pi +ssh picoclaw@picoclaw.local + +# Update system +sudo apt update && sudo apt upgrade -y + +# Set timezone +sudo raspi-config +# Navigate to Localisation Options > Timezone +``` + +## Installing PicoClaw + +### Option 1: Precompiled Binary (Recommended) + +```bash +# Download ARM64 binary +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-arm64 + +# Make executable +chmod +x picoclaw-linux-arm64 + +# Move to system path +sudo mv picoclaw-linux-arm64 /usr/local/bin/picoclaw + +# Initialize configuration +picoclaw onboard +``` + +### Option 2: Build from Source + +```bash +# Install Go 1.21+ +wget https://go.dev/dl/go1.23.0.linux-arm64.tar.gz +sudo tar -C /usr/local -xzf go1.23.0.linux-arm64.tar.gz +export PATH=$PATH:/usr/local/go/bin + +# Clone and build +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw +make deps +make build + +# Install +sudo make install +``` + +## Configuration + +### Basic Configuration + +```bash +# Edit config file +nano ~/.picoclaw/config.json +``` + +Example configuration: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "restrict_to_workspace": true, + "model": "openrouter/anthropic/claude-sonnet-4", + "max_tokens": 4096, + "temperature": 0.7 + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-your-key-here" + } + }, + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + } + }, + "gateway": { + "host": "0.0.0.0", + "port": 18790 + }, + "heartbeat": { + "enabled": true, + "interval": 30 + } +} +``` + +### Environment Variables + +```bash +# Add to ~/.bashrc +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-your-key-here" +export PICOCLAW_AGENTS_DEFAULTS_MODEL="openrouter/anthropic/claude-sonnet-4" +``` + +## Running as a Service + +### Create Dedicated User + +```bash +sudo useradd -r -s /bin/false -d /var/lib/picoclaw picoclaw +sudo mkdir -p /var/lib/picoclaw/workspace +sudo chown -R picoclaw:picoclaw /var/lib/picoclaw +``` + +### Create Systemd Service + +```bash +sudo tee /etc/systemd/system/picoclaw.service << 'EOF' +[Unit] +Description=PicoClaw AI Assistant +After=network.target +Wants=network-online.target + +[Service] +Type=simple +User=picoclaw +Group=picoclaw +WorkingDirectory=/var/lib/picoclaw +ExecStart=/usr/local/bin/picoclaw gateway +Restart=on-failure +RestartSec=10 + +# Environment +Environment=PICOCLAW_CONFIG=/etc/picoclaw/config.json + +# Security +NoNewPrivileges=true +ProtectSystem=strict +ProtectHome=true +ReadWritePaths=/var/lib/picoclaw +PrivateTmp=true + +[Install] +WantedBy=multi-user.target +EOF +``` + +### Configure for Service + +```bash +# Move config to system location +sudo mkdir -p /etc/picoclaw +sudo cp ~/.picoclaw/config.json /etc/picoclaw/ +sudo chown picoclaw:picoclaw /etc/picoclaw/config.json +sudo chmod 600 /etc/picoclaw/config.json + +# Enable and start +sudo systemctl daemon-reload +sudo systemctl enable picoclaw +sudo systemctl start picoclaw + +# Check status +sudo systemctl status picoclaw +``` + +## Hardware-Specific Features + +### GPIO Access + +Enable GPIO tools for home automation: + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": [] + } + } +} +``` + +Use with gpiod: + +```bash +# Install gpiod tools +sudo apt install gpiod + +# Example: Read GPIO pin +gpioget gpiochip0 17 + +# Example: Set GPIO pin +gpioset gpiochip0 18=1 +``` + +### Temperature Monitoring + +```bash +# CPU temperature +vcgencmd measure_temp + +# Add to PicoClaw skills or use in exec commands +``` + +### Camera Module + +```bash +# Enable camera +sudo raspi-config +# Navigate to Interface Options > Camera + +# Test camera +libcamera-hello + +# Capture image +libcamera-still -o image.jpg +``` + +### Sense HAT + +```bash +# Install Sense HAT library +sudo apt install sense-hat + +# Python script for sensor data +python3 -c "from sense_hat import SenseHat; s = SenseHat(); print(s.get_temperature())" +``` + +## Performance Optimization + +### Memory Allocation + +For Pi 4 with 4GB+ RAM: + +```bash +# Check current memory split +vcgencmd get_mem gpu + +# Reduce GPU memory (headless) +echo "gpu_mem=16" | sudo tee -a /boot/config.txt +``` + +### CPU Governor + +```bash +# Check current governor +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Set to performance (may increase power usage) +echo "performance" | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Or set to powersave (reduces performance) +echo "powersave" | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor +``` + +### Disable Unused Services + +```bash +# Disable Bluetooth if not used +sudo systemctl disable bluetooth + +# Disable audio if not used +sudo systemctl disable alsa-state + +# Disable printing +sudo systemctl disable cups +``` + +### Overclocking (Pi 5) + +```bash +# Edit /boot/firmware/config.txt (Pi 5) +# Add overclock settings (use with caution) +# over_voltage=6 +# arm_freq=3000 +``` + +## Network Configuration + +### Static IP + +```bash +# Using nmcli +sudo nmcli con mod "Wired connection 1" ipv4.addresses 192.168.1.100/24 +sudo nmcli con mod "Wired connection 1" ipv4.gateway 192.168.1.1 +sudo nmcli con mod "Wired connection 1" ipv4.dns "8.8.8.8,8.8.4.4" +sudo nmcli con mod "Wired connection 1" ipv4.method manual +sudo nmcli con up "Wired connection 1" +``` + +### WiFi + +```bash +# Connect to WiFi +sudo nmcli dev wifi connect "SSID" password "PASSWORD" + +# Or configure manually +sudo tee /etc/wpa_supplicant/wpa_supplicant.conf << 'EOF' +country=US +ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev +update_config=1 + +network={ + ssid="YourSSID" + psk="YourPassword" +} +EOF +``` + +### Access Point Mode + +Turn your Pi into a WiFi hotspot: + +```bash +# Install required packages +sudo apt install hostapd dnsmasq + +# Configure static IP for AP +sudo tee -a /etc/dhcpcd.conf << 'EOF' +interface wlan0 + static ip_address=192.168.4.1/24 + nohook wpa_supplicant +EOF + +# Configure DNSMasq +sudo tee /etc/dnsmasq.conf << 'EOF' +interface=wlan0 +dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h +domain=picoclaw.local +address=/picoclaw.local/192.168.4.1 +EOF + +# Configure hostapd +sudo tee /etc/hostapd/hostapd.conf << 'EOF' +interface=wlan0 +driver=nl80211 +ssid=PicoClaw +hw_mode=g +channel=7 +wpa=2 +wpa_passphrase=yourpassword +wpa_key_mgmt=WPA-PSK +wpa_pairwise=TKIP CCMP +EOF + +# Point to config +sudo tee /etc/default/hostapd << 'EOF' +DAEMON_CONF="/etc/hostapd/hostapd.conf" +EOF + +# Enable services +sudo systemctl unmask hostapd +sudo systemctl enable hostapd dnsmasq +sudo reboot +``` + +## Local LLM Integration + +### Ollama Setup + +```bash +# Install Ollama +curl -fsSL https://ollama.com/install.sh | sh + +# Pull a small model +ollama pull llama3.2:1b + +# Configure PicoClaw to use Ollama +# In config.json: +{ + "agents": { + "defaults": { + "model": "ollama/llama3.2:1b" + } + }, + "providers": { + "ollama": { + "api_base": "http://localhost:11434/v1" + } + } +} +``` + +### Performance Notes + +For running local LLMs on Raspberry Pi: +- Pi 5 with 8GB RAM can run small models (1-3B parameters) +- Use quantized models (q4, q5) for better performance +- Consider using external GPU accelerators for larger models + +## Monitoring and Maintenance + +### Health Check Script + +```bash +#!/bin/bash +# /usr/local/bin/picoclaw-health.sh + +# Check service +if ! systemctl is-active --quiet picoclaw; then + echo "PicoClaw service not running" + exit 1 +fi + +# Check health endpoint +if ! curl -sf http://localhost:18790/health > /dev/null; then + echo "Health check failed" + exit 1 +fi + +# Check temperature +TEMP=$(vcgencmd measure_temp | grep -oP '\d+') +if [ "$TEMP" -gt 80 ]; then + echo "High temperature: ${TEMP}C" +fi + +echo "All checks passed" +exit 0 +``` + +### Log Monitoring + +```bash +# View logs +sudo journalctl -u picoclaw -f + +# Check for errors +sudo journalctl -u picoclaw -p err +``` + +### Backup + +```bash +# Backup configuration and workspace +sudo tar czf picoclaw-backup-$(date +%Y%m%d).tar.gz \ + /etc/picoclaw \ + /var/lib/picoclaw +``` + +## Troubleshooting + +### Service Won't Start + +```bash +# Check logs +sudo journalctl -u picoclaw -n 100 + +# Verify binary +which picoclaw +picoclaw version + +# Test manually +sudo -u picoclaw /usr/local/bin/picoclaw gateway +``` + +### Memory Issues + +```bash +# Check memory +free -h + +# Add swap +sudo dphys-swapfile swapoff +sudo sed -i 's/CONF_SWAPSIZE=100/CONF_SWAPSIZE=512/' /etc/dphys-swapfile +sudo dphys-swapfile setup +sudo dphys-swapfile swapon +``` + +### Network Issues + +```bash +# Check interface +ip addr + +# Test connectivity +ping google.com + +# Check DNS +nslookup api.openai.com +``` + +### Thermal Throttling + +```bash +# Check temperature +vcgencmd measure_temp + +# Check throttling +vcgencmd get_throttled + +# If throttled, improve cooling +# - Add heatsink +# - Add fan +# - Ensure good airflow +``` + +## Resources + +- [Raspberry Pi Documentation](https://www.raspberrypi.com/documentation/) +- [Raspberry Pi Forums](https://forums.raspberrypi.com/) +- [PicoClaw GitHub](https://github.com/sipeed/picoclaw) diff --git a/docs/deployment/security.md b/docs/deployment/security.md new file mode 100644 index 0000000000..7aa2f0b804 --- /dev/null +++ b/docs/deployment/security.md @@ -0,0 +1,445 @@ +# Production Security Checklist + +This guide provides a comprehensive security checklist for deploying PicoClaw in production environments. + +## API Key Security + +### Storage + +- [ ] **Never commit API keys to version control** +- [ ] Store API keys in environment variables or secure secret management +- [ ] Use separate API keys for development and production +- [ ] Rotate API keys regularly (every 90 days recommended) + +### File Permissions + +```bash +# Set restrictive permissions on config file +chmod 600 ~/.picoclaw/config.json + +# For system-wide installation +sudo chmod 600 /etc/picoclaw/config.json +sudo chown picoclaw:picoclaw /etc/picoclaw/config.json +``` + +### Environment Variables + +```bash +# Use environment variables instead of config file for secrets +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" + +# Or use a secrets file with restricted access +cat > /etc/picoclaw/secrets.env << 'EOF' +PICOCLAW_PROVIDERS_OPENROUTER_API_KEY=sk-or-v1-xxx +EOF +chmod 600 /etc/picoclaw/secrets.env +chown picoclaw:picoclaw /etc/picoclaw/secrets.env +``` + +### Docker Secrets + +When using Docker Swarm or Kubernetes: + +```yaml +# Docker Compose with secrets +services: + picoclaw: + secrets: + - openrouter_key + environment: + - PICOCLAW_PROVIDERS_OPENROUTER_API_KEY_FILE=/run/secrets/openrouter_key + +secrets: + openrouter_key: + external: true +``` + +## Network Security + +### Firewall Configuration + +```bash +# UFW (Ubuntu/Debian) +sudo ufw default deny incoming +sudo ufw default allow outgoing +sudo ufw allow ssh +sudo ufw allow from 10.0.0.0/8 to any port 18790 # Internal only +sudo ufw enable + +# iptables +iptables -A INPUT -p tcp --dport 18790 -s 10.0.0.0/8 -j ACCEPT +iptables -A INPUT -p tcp --dport 18790 -j DROP +``` + +### Reverse Proxy + +Use a reverse proxy for TLS termination: + +**Nginx:** +```nginx +server { + listen 443 ssl http2; + server_name picoclaw.example.com; + + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; + + # Security headers + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + + location / { + proxy_pass http://127.0.0.1:18790; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +**Caddy (automatic HTTPS):** +```caddyfile +picoclaw.example.com { + reverse_proxy localhost:18790 +} +``` + +### Bind to Localhost + +By default, bind to localhost unless you need external access: + +```json +{ + "gateway": { + "host": "127.0.0.1", + "port": 18790 + } +} +``` + +## Access Control + +### Channel Allowlists + +Restrict who can interact with your bot: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_TOKEN", + "allow_from": ["123456789", "987654321"] + }, + "discord": { + "enabled": true, + "token": "YOUR_TOKEN", + "allow_from": ["123456789012345678"] + } + } +} +``` + +### Multi-Factor Authentication + +For admin access, consider: +- SSH key authentication only +- VPN requirement for administrative access +- Separate admin network/VLAN + +## Workspace Security + +### Restrict to Workspace + +Always enable workspace restrictions in production: + +```json +{ + "agents": { + "defaults": { + "restrict_to_workspace": true, + "workspace": "/var/lib/picoclaw/workspace" + } + } +} +``` + +### Dangerous Command Blocking + +Enable and configure command deny patterns: + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": [ + "rm -rf", + "dd if=", + "mkfs", + "shutdown", + "reboot", + "init 0", + "> /dev/sd", + "chmod 777", + "wget.*\\|.*sh", + "curl.*\\|.*sh" + ] + } + } +} +``` + +### Workspace Isolation + +For multi-tenant setups, use separate workspaces: + +```json +{ + "agents": { + "list": [ + { + "id": "agent-a", + "workspace": "/var/lib/picoclaw/agent-a", + "restrict_to_workspace": true + }, + { + "id": "agent-b", + "workspace": "/var/lib/picoclaw/agent-b", + "restrict_to_workspace": true + } + ] + } +} +``` + +## System Hardening + +### Dedicated User + +Run PicoClaw as a dedicated non-root user: + +```bash +# Create system user +sudo useradd -r -s /bin/false -d /var/lib/picoclaw picoclaw + +# Set ownership +sudo chown -R picoclaw:picoclaw /var/lib/picoclaw +``` + +### Systemd Sandbox + +Use systemd security features: + +```ini +[Service] +# Basic restrictions +NoNewPrivileges=true +ProtectSystem=strict +ProtectHome=true +PrivateTmp=true +PrivateDevices=true + +# Advanced restrictions +ProtectKernelTunables=true +ProtectControlGroups=true +ProtectKernelModules=true +ProtectHostname=true +ProtectClock=true + +# Network restrictions (if no external network needed) +# RestrictAddressFamilies=AF_UNIX + +# System call filtering +SystemCallFilter=@system-service +SystemCallArchitectures=native + +# Memory protection +MemoryDenyWriteExecute=true + +# Allow workspace access +ReadWritePaths=/var/lib/picoclaw +ReadOnlyPaths=/etc/picoclaw +``` + +### Docker Security + +```yaml +services: + picoclaw: + # Run as non-root (default in official image) + user: "1000:1000" + + # Read-only root filesystem + read_only: true + + # Drop all capabilities + cap_drop: + - ALL + + # Security options + security_opt: + - no-new-privileges:true + + # Resource limits + deploy: + resources: + limits: + memory: 512M + cpus: '1.0' + + # Temporary filesystem for writable paths + tmpfs: + - /tmp:size=10M,mode=1777 +``` + +## Monitoring and Logging + +### Log Configuration + +Enable comprehensive logging: + +```bash +# View logs +journalctl -u picoclaw -f + +# For Docker +docker logs -f picoclaw-gateway +``` + +### Audit Trail + +Log all tool executions: + +```bash +# Debug mode shows all tool calls +picoclaw gateway --debug +``` + +### Monitoring Setup + +Monitor key metrics: + +```bash +# Process monitoring +[ -f /var/run/picoclaw.pid ] && ps -p $(cat /var/run/picoclaw.pid) > /dev/null + +# Health check endpoint +curl -sf http://localhost:18790/health || echo "PicoClaw unhealthy" + +# Memory usage +ps -o rss= -p $(pgrep -f "picoclaw gateway") | awk '{print $1/1024 " MB"}' +``` + +### Log Rotation + +Configure log rotation for long-running deployments: + +```bash +# /etc/logrotate.d/picoclaw +/var/log/picoclaw/*.log { + daily + rotate 14 + compress + delaycompress + missingok + notifempty + create 0640 picoclaw picoclaw +} +``` + +## Updates and Maintenance + +### Regular Updates + +- [ ] Update PicoClaw regularly for security patches +- [ ] Subscribe to release notifications +- [ ] Test updates in staging before production + +```bash +# Check current version +picoclaw version + +# Update binary +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-amd64 +chmod +x picoclaw-linux-amd64 +sudo mv picoclaw-linux-amd64 /usr/local/bin/picoclaw +``` + +### Dependency Updates + +For source installations: + +```bash +# Update Go dependencies +make update-deps +make build +``` + +### Backup Strategy + +```bash +# Backup configuration and workspace +tar czf picoclaw-backup-$(date +%Y%m%d).tar.gz \ + /etc/picoclaw \ + /var/lib/picoclaw + +# Store backups securely (encrypted) +gpg -c picoclaw-backup-$(date +%Y%m%d).tar.gz +``` + +## Security Checklist Summary + +### Before Deployment + +- [ ] API keys stored securely (not in config committed to git) +- [ ] Config file has restrictive permissions (600) +- [ ] Running as non-root user +- [ ] Workspace restriction enabled +- [ ] Command deny patterns enabled +- [ ] Channel allowlists configured +- [ ] Firewall configured +- [ ] HTTPS enabled (if external access needed) + +### After Deployment + +- [ ] Health check endpoint accessible +- [ ] Logs being captured +- [ ] Monitoring configured +- [ ] Backup strategy in place +- [ ] Update schedule established + +### Regular Maintenance + +- [ ] Rotate API keys (every 90 days) +- [ ] Review access logs +- [ ] Apply security updates +- [ ] Test backup restoration +- [ ] Audit user access + +## Incident Response + +### If API Key is Compromised + +1. Immediately revoke the compromised key at the provider +2. Generate a new key +3. Update configuration +4. Restart PicoClaw +5. Review logs for unauthorized usage + +### If System is Compromised + +1. Isolate the system from network +2. Preserve logs for investigation +3. Revoke all API keys +4. Rebuild from clean backup +5. Update all credentials +6. Review and patch vulnerability + +## Additional Resources + +- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks/) +- [OWASP Security Guidelines](https://owasp.org/www-project-web-security-testing-guide/) +- [Linux Hardening Guide](https://madaidans-insecurities.github.io/guides/linux-hardening.html) diff --git a/docs/deployment/systemd.md b/docs/deployment/systemd.md new file mode 100644 index 0000000000..507218fd49 --- /dev/null +++ b/docs/deployment/systemd.md @@ -0,0 +1,505 @@ +# Running PicoClaw as a Systemd Service + +This guide explains how to run PicoClaw as a systemd service on Linux systems. This is the recommended approach for production deployments on servers and single-board computers. + +## Prerequisites + +- Linux system with systemd +- Root/sudo access +- PicoClaw binary installed + +## Installation + +### Step 1: Install the Binary + +```bash +# Download the binary +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-amd64 +chmod +x picoclaw-linux-amd64 +sudo mv picoclaw-linux-amd64 /usr/local/bin/picoclaw + +# Or build from source +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw +make deps +make build +sudo make install +``` + +### Step 2: Create a Dedicated User + +Create a system user for running PicoClaw: + +```bash +sudo useradd -r -s /bin/false -d /var/lib/picoclaw picoclaw +``` + +### Step 3: Create Configuration Directory + +```bash +# Create config directory +sudo mkdir -p /etc/picoclaw + +# Create workspace directory +sudo mkdir -p /var/lib/picoclaw/workspace + +# Set ownership +sudo chown -R picoclaw:picoclaw /var/lib/picoclaw +``` + +### Step 4: Initialize Configuration + +```bash +# Run onboard as the picoclaw user +sudo -u picoclaw /usr/local/bin/picoclaw onboard + +# Or create config manually +sudo tee /etc/picoclaw/config.json > /dev/null <<'EOF' +{ + "agents": { + "defaults": { + "workspace": "/var/lib/picoclaw/workspace", + "model": "openrouter/anthropic/claude-opus-4-5" + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-your-key-here" + } + }, + "gateway": { + "host": "0.0.0.0", + "port": 18790 + } +} +EOF + +sudo chown picoclaw:picoclaw /etc/picoclaw/config.json +sudo chmod 600 /etc/picoclaw/config.json +``` + +## Systemd Service File + +### Basic Service + +Create `/etc/systemd/system/picoclaw.service`: + +```ini +[Unit] +Description=PicoClaw AI Assistant Gateway +After=network.target +Wants=network-online.target + +[Service] +Type=simple +User=picoclaw +Group=picoclaw +ExecStart=/usr/local/bin/picoclaw gateway +Restart=on-failure +RestartSec=5 + +# Environment +Environment=PICOCLAW_CONFIG=/etc/picoclaw/config.json + +# Security hardening +NoNewPrivileges=true +ProtectSystem=strict +ProtectHome=true +ReadWritePaths=/var/lib/picoclaw +PrivateTmp=true + +# Logging +StandardOutput=journal +StandardError=journal +SyslogIdentifier=picoclaw + +[Install] +WantedBy=multi-user.target +``` + +### Service with Environment Variables + +For using environment variables instead of config file: + +```ini +[Unit] +Description=PicoClaw AI Assistant Gateway +After=network.target +Wants=network-online.target + +[Service] +Type=simple +User=picoclaw +Group=picoclaw +ExecStart=/usr/local/bin/picoclaw gateway +Restart=on-failure +RestartSec=5 + +# Environment variables +Environment="PICOCLAW_AGENTS_DEFAULTS_MODEL=openrouter/anthropic/claude-opus-4-5" +Environment="PICOCLAW_PROVIDERS_OPENROUTER_API_KEY=sk-or-v1-your-key-here" +Environment="PICOCLAW_HEARTBEAT_ENABLED=true" +Environment="PICOCLAW_HEARTBEAT_INTERVAL=30" + +# Security hardening +NoNewPrivileges=true +ProtectSystem=strict +ProtectHome=true +ReadWritePaths=/var/lib/picoclaw +PrivateTmp=true + +[Install] +WantedBy=multi-user.target +``` + +### Production Service with Full Hardening + +```ini +[Unit] +Description=PicoClaw AI Assistant Gateway +Documentation=https://github.com/sipeed/picoclaw +After=network.target network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=picoclaw +Group=picoclaw +WorkingDirectory=/var/lib/picoclaw + +# Main command +ExecStart=/usr/local/bin/picoclaw gateway +ExecReload=/bin/kill -HUP $MAINPID + +# Restart policy +Restart=on-failure +RestartSec=5 +TimeoutStartSec=30 +TimeoutStopSec=30 + +# Environment +Environment=PICOCLAW_CONFIG=/etc/picoclaw/config.json +Environment=PICOCLAW_WORKSPACE=/var/lib/picoclaw/workspace + +# Resource limits +LimitNOFILE=65536 +MemoryMax=512M +MemoryHigh=400M + +# Security hardening +NoNewPrivileges=true +ProtectSystem=strict +ProtectHome=true +ProtectKernelTunables=true +ProtectControlGroups=true +ProtectKernelModules=true +ProtectHostname=true +ProtectClock=true +ProtectProc=invisible +ProcSubset=pid +PrivateTmp=true +PrivateDevices=true +PrivateUsers=true +PrivateMounts=true +CapabilityBoundingSet= +AmbientCapabilities= +LockPersonality=true +RestrictNamespaces=true +RestrictRealtime=true +RestrictSUIDSGID=true +RestrictAddressFamilies=AF_INET AF_INET6 +SystemCallFilter=@system-service +SystemCallArchitectures=native +MemoryDenyWriteExecute=true + +# Allow access to workspace +ReadWritePaths=/var/lib/picoclaw +ReadOnlyPaths=/etc/picoclaw + +# Logging +StandardOutput=journal +StandardError=journal +SyslogIdentifier=picoclaw + +[Install] +WantedBy=multi-user.target +``` + +## Managing the Service + +### Enable and Start + +```bash +# Reload systemd to pick up new service +sudo systemctl daemon-reload + +# Enable to start on boot +sudo systemctl enable picoclaw + +# Start the service +sudo systemctl start picoclaw + +# Check status +sudo systemctl status picoclaw +``` + +### Common Operations + +```bash +# Stop the service +sudo systemctl stop picoclaw + +# Restart the service +sudo systemctl restart picoclaw + +# Disable from starting on boot +sudo systemctl disable picoclaw + +# View status +sudo systemctl status picoclaw + +# Check if enabled +systemctl is-enabled picoclaw +``` + +### Viewing Logs + +```bash +# View recent logs +sudo journalctl -u picoclaw + +# Follow logs in real-time +sudo journalctl -u picoclaw -f + +# Last 100 lines +sudo journalctl -u picoclaw -n 100 + +# Logs from last hour +sudo journalctl -u picoclaw --since "1 hour ago" + +# Logs since boot +sudo journalctl -u picoclaw -b + +# With priority filtering +sudo journalctl -u picoclaw -p err +``` + +## Configuration Management + +### Using Config File with Symlink + +Link the default config location to `/etc/picoclaw/config.json`: + +```bash +# Remove default config location +sudo rm -rf /home/picoclaw/.picoclaw + +# Create symlink +sudo ln -s /etc/picoclaw /home/picoclaw/.picoclaw +``` + +### Using Environment File + +Create `/etc/picoclaw/picoclaw.env`: + +```bash +PICOCLAW_AGENTS_DEFAULTS_MODEL=openrouter/anthropic/claude-opus-4-5 +PICOCLAW_PROVIDERS_OPENROUTER_API_KEY=sk-or-v1-your-key-here +PICOCLAW_CHANNELS_TELEGRAM_ENABLED=true +PICOCLAW_CHANNELS_TELEGRAM_TOKEN=123456:ABC +PICOCLAW_HEARTBEAT_ENABLED=true +PICOCLAW_HEARTBEAT_INTERVAL=30 +``` + +Update service file: + +```ini +[Service] +EnvironmentFile=/etc/picoclaw/picoclaw.env +``` + +### Secure API Key Storage + +Store API keys in a separate file with restricted permissions: + +```bash +# Create secrets file +sudo tee /etc/picoclaw/secrets.env > /dev/null <<'EOF' +PICOCLAW_PROVIDERS_OPENROUTER_API_KEY=sk-or-v1-your-key-here +PICOCLAW_PROVIDERS_OPENAI_API_KEY=sk-your-key-here +EOF + +# Restrict permissions +sudo chmod 600 /etc/picoclaw/secrets.env +sudo chown picoclaw:picoclaw /etc/picoclaw/secrets.env +``` + +## Multiple Instances + +### Running Multiple Agents + +Create separate service files for different agents: + +`/etc/systemd/system/picoclaw-telegram.service`: + +```ini +[Unit] +Description=PicoClaw Telegram Bot +After=network.target + +[Service] +Type=simple +User=picoclaw +Group=picoclaw +ExecStart=/usr/local/bin/picoclaw gateway +Environment=PICOCLAW_CONFIG=/etc/picoclaw/telegram.json +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +`/etc/systemd/system/picoclaw-discord.service`: + +```ini +[Unit] +Description=PicoClaw Discord Bot +After=network.target + +[Service] +Type=simple +User=picoclaw +Group=picoclaw +ExecStart=/usr/local/bin/picoclaw gateway +Environment=PICOCLAW_CONFIG=/etc/picoclaw/discord.json +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +Enable both: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable picoclaw-telegram picoclaw-discord +sudo systemctl start picoclaw-telegram picoclaw-discord +``` + +## Updates and Maintenance + +### Updating the Binary + +```bash +# Stop service +sudo systemctl stop picoclaw + +# Download new version +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-amd64 +chmod +x picoclaw-linux-amd64 +sudo mv picoclaw-linux-amd64 /usr/local/bin/picoclaw + +# Start service +sudo systemctl start picoclaw + +# Verify +sudo systemctl status picoclaw +``` + +### Backup Configuration + +```bash +# Backup config and workspace +sudo tar czf picoclaw-backup-$(date +%Y%m%d).tar.gz \ + /etc/picoclaw \ + /var/lib/picoclaw +``` + +### Health Check Script + +Create `/usr/local/bin/picoclaw-health-check.sh`: + +```bash +#!/bin/bash +# Health check script for PicoClaw + +HEALTH_URL="http://localhost:18790/health" +TIMEOUT=5 + +if curl -sf --max-time $TIMEOUT "$HEALTH_URL" > /dev/null; then + echo "PicoClaw is healthy" + exit 0 +else + echo "PicoClaw health check failed" + exit 1 +fi +``` + +Add to systemd timer or cron: + +```bash +# Add to cron +*/5 * * * * /usr/local/bin/picoclaw-health-check.sh || systemctl restart picoclaw +``` + +## Troubleshooting + +### Service Fails to Start + +```bash +# Check service status +sudo systemctl status picoclaw + +# View logs +sudo journalctl -u picoclaw -n 50 + +# Check if binary exists and is executable +ls -la /usr/local/bin/picoclaw + +# Check config file +sudo -u picoclaw cat /etc/picoclaw/config.json + +# Test running manually +sudo -u picoclaw /usr/local/bin/picoclaw gateway +``` + +### Permission Issues + +```bash +# Check ownership +ls -la /etc/picoclaw/ +ls -la /var/lib/picoclaw/ + +# Fix ownership +sudo chown -R picoclaw:picoclaw /var/lib/picoclaw +sudo chown picoclaw:picoclaw /etc/picoclaw/config.json + +# Check config permissions +sudo chmod 600 /etc/picoclaw/config.json +``` + +### Network Issues + +```bash +# Check if port is listening +sudo ss -tlnp | grep 18790 + +# Check firewall +sudo ufw status +sudo iptables -L -n + +# Test health endpoint +curl http://localhost:18790/health +``` + +### Reset Service + +```bash +# Full reset +sudo systemctl stop picoclaw +sudo systemctl reset-failed picoclaw +sudo systemctl daemon-reload +sudo systemctl start picoclaw +``` diff --git a/docs/deployment/termux.md b/docs/deployment/termux.md new file mode 100644 index 0000000000..0700019000 --- /dev/null +++ b/docs/deployment/termux.md @@ -0,0 +1,501 @@ +# Android/Termux Deployment + +PicoClaw can run on Android devices using Termux, allowing you to repurpose old phones or tablets as AI assistants. This is an excellent way to give new life to unused Android devices. + +## Prerequisites + +- Android 7.0 or later +- Termux app (from F-Droid recommended) +- ARM64 Android device (most devices from 2015+) + +## Installing Termux + +### Option 1: F-Droid (Recommended) + +The F-Droid version is more up-to-date and doesn't have Google Play restrictions: + +1. Install [F-Droid](https://f-droid.org/) +2. Search for "Termux" in F-Droid +3. Install Termux, Termux:API (optional) + +### Option 2: GitHub Releases + +Download directly from [Termux GitHub releases](https://github.com/termux/termux-app/releases): + +1. Download the latest APK +2. Enable "Install from unknown sources" in Android settings +3. Install the APK + +### Important Note + +**Do not install Termux from Google Play Store.** That version is outdated and has compatibility issues. Use F-Droid or GitHub releases instead. + +## Initial Setup + +### Step 1: Update Termux Packages + +Open Termux and run: + +```bash +# Update package lists +pkg update && pkg upgrade -y + +# Install essential packages +pkg install wget curl git proot -y +``` + +### Step 2: Download PicoClaw + +```bash +# Navigate to home directory +cd ~ + +# Download the ARM64 binary +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-arm64 + +# Make executable +chmod +x picoclaw-linux-arm64 +``` + +### Step 3: Initialize with proot + +Termux has a different filesystem layout than standard Linux. Use `proot` to run PicoClaw: + +```bash +# Install proot if not already installed +pkg install proot -y + +# Initialize PicoClaw using termux-chroot +termux-chroot ./picoclaw-linux-arm64 onboard +``` + +### Step 4: Configure PicoClaw + +```bash +# Edit configuration +termux-chroot nano ~/.picoclaw/config.json +``` + +Add your API keys: + +```json +{ + "agents": { + "defaults": { + "model": "openrouter/anthropic/claude-opus-4-5" + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-your-key-here" + } + } +} +``` + +## Running PicoClaw + +### Agent Mode (One-Shot Queries) + +```bash +# Run a single query +termux-chroot ./picoclaw-linux-arm64 agent -m "What is the weather today?" + +# Interactive mode +termux-chroot ./picoclaw-linux-arm64 agent + +# Debug mode +termux-chroot ./picoclaw-linux-arm64 agent --debug -m "Hello" +``` + +### Gateway Mode (Always-On Bot) + +```bash +# Start gateway +termux-chroot ./picoclaw-linux-arm64 gateway +``` + +## Creating a Shortcut Script + +Create a helper script for easier execution: + +```bash +# Create script +cat > $PREFIX/bin/picoclaw << 'EOF' +#!/data/data/com.termux/files/usr/bin/sh +# PicoClaw wrapper for Termux + +BINARY="$HOME/picoclaw-linux-arm64" + +if [ ! -f "$BINARY" ]; then + echo "PicoClaw binary not found at $BINARY" + exit 1 +fi + +termux-chroot "$BINARY" "$@" +EOF + +# Make executable +chmod +x $PREFIX/bin/picoclaw +``` + +Now you can run PicoClaw directly: + +```bash +picoclaw agent -m "Hello" +picoclaw gateway +``` + +## Keeping PicoClaw Running + +### Using tmux + +Run PicoClaw in a persistent session: + +```bash +# Install tmux +pkg install tmux -y + +# Create new session +tmux new -s picoclaw + +# Start PicoClaw +picoclaw gateway + +# Detach: Press Ctrl+B then D + +# Reattach later +tmux attach -t picoclaw +``` + +### Using nohup + +Run in background: + +```bash +# Start in background +nohup picoclaw gateway > picoclaw.log 2>&1 & + +# View logs +tail -f picoclaw.log + +# Find process ID +pgrep -f picoclaw + +# Stop +pkill -f picoclaw +``` + +### Auto-Start on Boot + +Create a boot script using Termux:Boot (requires Termux:API): + +```bash +# Install Termux:API and Termux:Boot from F-Droid + +# Create boot directory +mkdir -p ~/.termux/boot + +# Create boot script +cat > ~/.termux/boot/picoclaw.sh << 'EOF' +#!/data/data/com.termux/files/usr/bin/sh +# Auto-start PicoClaw on boot + +# Wait for network +sleep 30 + +# Start in tmux session +tmux new -d -s picoclaw "picoclaw gateway" +EOF + +# Make executable +chmod +x ~/.termux/boot/picoclaw.sh +``` + +## Battery Optimization + +### Disable Battery Optimization + +To prevent Android from killing Termux in the background: + +1. Go to Settings > Battery > Battery Optimization +2. Find Termux and select "Don't optimize" +3. Also disable battery optimization for Termux:API and Termux:Boot if installed + +### Acquire Wakelock + +Prevent the device from sleeping: + +```bash +# Install Termux:API first +pkg install termux-api -y + +# Acquire wakelock +termux-wake-lock + +# Release wakelock when done +termux-wake-unlock +``` + +### Notification (Keep Alive) + +Termux shows a persistent notification when running: + +```bash +# The notification is shown automatically +# To start foreground service: +termux-notification --ongoing --title "PicoClaw" --content "Running..." +``` + +## Storage Access + +### Access Shared Storage + +To access files in your Android shared storage: + +```bash +# Request storage permission +termux-setup-storage + +# This creates a symlink at ~/storage +# Access Downloads: ~/storage/downloads +# Access DCIM: ~/storage/dcim +# Access Documents: ~/storage/documents +``` + +### Use Shared Storage for Workspace + +Configure PicoClaw to use shared storage: + +```json +{ + "agents": { + "defaults": { + "workspace": "/data/data/com.termux/files/home/storage/documents/picoclaw" + } + } +} +``` + +## Notifications + +Send notifications when PicoClaw completes tasks: + +```bash +# Simple notification +termux-notification --title "PicoClaw" --content "Task completed" + +# With sound +termux-notification --title "PicoClaw" --content "Task completed" --sound + +# With action button +termux-notification --title "PicoClaw" --content "New message" --button1 "View" --button1-action "termux-open-url https://example.com" +``` + +## Hardware Integration + +### Camera Access + +Use Termux:API to access the camera: + +```bash +# Take a photo +termux-camera-photo ~/photo.jpg + +# Use in PicoClaw skills or tools +``` + +### Sensors + +Access device sensors: + +```bash +# Get sensor list +termux-sensor -l + +# Get sensor data +termux-sensor -s "accelerometer" +``` + +### Location + +Get GPS location: + +```bash +# Get current location +termux-location +``` + +### Text-to-Speech + +Have PicoClaw speak responses: + +```bash +# Install TTS +pkg install espeak -y + +# Speak text +espeak "Hello from PicoClaw" +``` + +Or use Termux:API TTS: + +```bash +termux-tts-speak "Hello from PicoClaw" +``` + +## Performance Optimization + +### Memory Management + +Older Android devices may have limited RAM: + +```bash +# Check available memory +free -h + +# Kill unnecessary processes +pkill -f zygote + +# Reduce memory usage in config +# Set lower max_tokens +``` + +### CPU Throttling + +Prevent thermal throttling: + +1. Remove phone case for better cooling +2. Reduce screen brightness +3. Disable unnecessary apps + +### Network Optimization + +For stable network on mobile data: + +```bash +# Keep connection alive with periodic ping +while true; do ping -c 1 google.com; sleep 60; done & +``` + +## Troubleshooting + +### Binary Won't Execute + +```bash +# Check architecture +uname -m +# Should show aarch64 + +# Verify binary is for ARM64 +file picoclaw-linux-arm64 + +# Check permissions +ls -la picoclaw-linux-arm64 +chmod +x picoclaw-linux-arm64 +``` + +### proot Errors + +```bash +# Update proot +pkg upgrade proot + +# Try alternative proot command +proot ./picoclaw-linux-arm64 onboard +``` + +### Network Issues + +```bash +# Check network +ping google.com + +# Check DNS +nslookup api.openai.com + +# Test with curl +curl -I https://api.openai.com +``` + +### Permission Denied + +```bash +# Reset Termux permissions in Android settings +# Settings > Apps > Termux > Permissions + +# Re-run setup +termux-setup-storage +``` + +### App Killed in Background + +1. Disable battery optimization for Termux +2. Use `termux-wake-lock` +3. Keep the notification visible +4. Use tmux for persistent sessions + +### Clear Everything and Start Fresh + +```bash +# Remove PicoClaw +rm -rf ~/.picoclaw +rm picoclaw-linux-arm64 + +# Re-download and setup +wget https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-arm64 +chmod +x picoclaw-linux-arm64 +termux-chroot ./picoclaw-linux-arm64 onboard +``` + +## Use Cases + +### Home Automation Hub + +Run PicoClaw as a Telegram bot to control smart home devices: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN" + } + } +} +``` + +### Always-On Assistant + +Keep PicoClaw running 24/7 on an old phone: + +1. Enable wake lock +2. Disable battery optimization +3. Use tmux for persistence +4. Connect to charger + +### Mobile AI Companion + +Use PicoClaw with voice input/output: + +```bash +# Create voice assistant script +cat > ~/voice-assist.sh << 'EOF' +#!/data/data/com.termux/files/usr/bin/sh +echo "Listening..." +RECORDING=$(mktemp /tmp/recording.XXXXXX.wav) +termux-speech-to-text > /tmp/text.txt +TEXT=$(cat /tmp/text.txt) +echo "You said: $TEXT" +RESPONSE=$(picoclaw agent -m "$TEXT") +echo "Response: $RESPONSE" +termux-tts-speak "$RESPONSE" +EOF +chmod +x ~/voice-assist.sh +``` + +## Resources + +- [Termux Wiki](https://wiki.termux.com/) +- [Termux GitHub](https://github.com/termux) +- [PicoClaw Releases](https://github.com/sipeed/picoclaw/releases) diff --git a/docs/developer-guide/README.md b/docs/developer-guide/README.md new file mode 100644 index 0000000000..8851780ca9 --- /dev/null +++ b/docs/developer-guide/README.md @@ -0,0 +1,126 @@ +# PicoClaw Developer Guide + +Welcome to the PicoClaw Developer Guide. This documentation is intended for developers who want to understand, extend, or contribute to PicoClaw. + +## Overview + +PicoClaw is an ultra-lightweight AI assistant written in Go. It follows a message bus architecture where channels (Telegram, Discord, etc.) publish inbound messages and subscribe to outbound responses. + +## Documentation Sections + +### Getting Started + +- [Building from Source](building.md) - How to build PicoClaw from source code +- [Running Tests](testing.md) - How to run the test suite +- [Code Style Guide](code-style.md) - Coding conventions and style guidelines + +### Architecture + +- [System Architecture](architecture.md) - Overview of PicoClaw's architecture and components +- [Data Flow](data-flow.md) - Understanding the message bus and data flow + +### Contributing + +- [Contribution Guidelines](contributing.md) - How to contribute to PicoClaw + +### Extending PicoClaw + +The [extending/](extending/) directory contains guides for extending PicoClaw: + +- [Creating Custom Tools](extending/creating-tools.md) - How to create custom tools +- [Creating LLM Providers](extending/creating-providers.md) - How to create new LLM provider implementations +- [Creating Channel Integrations](extending/creating-channels.md) - How to create new channel integrations +- [Creating Skills](extending/creating-skills.md) - How to create custom skills + +### API Reference + +The [api/](api/) directory contains API reference documentation: + +- [Tool Interface](api/tool-interface.md) - Tool interface reference +- [Provider Interface](api/provider-interface.md) - LLMProvider interface reference +- [Message Bus API](api/message-bus.md) - Message bus API reference +- [Session API](api/session-api.md) - Session manager API reference + +## Quick Start for Developers + +```bash +# Clone the repository +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw + +# Install dependencies +make deps + +# Build +make build + +# Run tests +make test + +# Run the agent +./build/picoclaw agent -m "Hello, PicoClaw!" +``` + +## Key Concepts + +### Message Bus Architecture + +PicoClaw uses a message bus pattern for communication between components: + +1. **Channels** receive messages from external platforms (Telegram, Discord, etc.) +2. Messages are published to the **inbound** bus +3. The **AgentLoop** consumes messages from the bus +4. Responses are published to the **outbound** bus +5. Channels subscribe to outbound messages and send them to their platforms + +### Tool System + +Tools are the primary way PicoClaw interacts with the world. Each tool: + +- Implements the `Tool` interface with `Name()`, `Description()`, `Parameters()`, and `Execute()` methods +- Can optionally implement `ContextualTool` for channel context +- Can optionally implement `AsyncTool` for asynchronous operations + +### LLM Provider System + +Providers handle communication with LLM APIs. Each provider: + +- Implements the `LLMProvider` interface with `Chat()` and `GetDefaultModel()` methods +- Handles request/response transformation for specific APIs +- Supports tool calling for agentic behavior + +### Session Management + +Sessions track conversation history: + +- Each session has a unique key (typically "channel:chatID") +- Messages are stored in memory and persisted to disk +- Automatic summarization when history exceeds thresholds + +## Project Structure + +``` +picoclaw/ +├── cmd/picoclaw/ # CLI entry point +├── pkg/ +│ ├── agent/ # Core agent logic +│ ├── bus/ # Message bus implementation +│ ├── channels/ # Platform integrations +│ ├── providers/ # LLM provider implementations +│ ├── tools/ # Tool implementations +│ ├── session/ # Session management +│ ├── config/ # Configuration handling +│ ├── skills/ # Skill loading system +│ └── ... # Other packages +├── docs/ # Documentation +└── Makefile # Build commands +``` + +## Getting Help + +- GitHub Issues: https://github.com/sipeed/picoclaw/issues +- Source Code: https://github.com/sipeed/picoclaw + +## License + +PicoClaw is licensed under the MIT License. diff --git a/docs/developer-guide/api/README.md b/docs/developer-guide/api/README.md new file mode 100644 index 0000000000..fa748cdc6e --- /dev/null +++ b/docs/developer-guide/api/README.md @@ -0,0 +1,222 @@ +# API Reference + +This directory contains reference documentation for PicoClaw's core APIs. + +## Overview + +PicoClaw provides several key APIs for extending and integrating with the system: + +| API | Description | Documentation | +|-----|-------------|---------------| +| Tool Interface | Create tools for agent capabilities | [tool-interface.md](tool-interface.md) | +| Provider Interface | Implement LLM provider integrations | [provider-interface.md](provider-interface.md) | +| Message Bus | Async message passing system | [message-bus.md](message-bus.md) | +| Session Manager | Conversation history management | [session-api.md](session-api.md) | + +## Core Types + +### Message Types + +```go +// Inbound message from external platform +type InboundMessage struct { + Channel string + SenderID string + ChatID string + Content string + Media []string + SessionKey string + Metadata map[string]string +} + +// Outbound message to external platform +type OutboundMessage struct { + Channel string + ChatID string + Content string +} +``` + +### LLM Types + +```go +// Message for LLM conversation +type Message struct { + Role string + Content string + ToolCalls []ToolCall + ToolCallID string +} + +// LLM response +type LLMResponse struct { + Content string + ToolCalls []ToolCall + FinishReason string + Usage *UsageInfo +} + +// Tool definition for LLM +type ToolDefinition struct { + Type string + Function ToolFunctionDefinition +} +``` + +### Tool Types + +```go +// Tool result from execution +type ToolResult struct { + ForLLM string + ForUser string + Silent bool + IsError bool + Async bool + Err error +} +``` + +## Package Overview + +### pkg/tools + +Tool system for agent capabilities. + +Key types: +- `Tool` - Base tool interface +- `ContextualTool` - Tools with channel context +- `AsyncTool` - Asynchronous tools +- `ToolResult` - Execution results +- `ToolRegistry` - Tool management + +### pkg/providers + +LLM provider implementations. + +Key types: +- `LLMProvider` - Provider interface +- `Message` - Conversation message +- `LLMResponse` - LLM response +- `FailoverError` - Error with classification +- `FallbackChain` - Model fallback logic + +### pkg/bus + +Message bus for async communication. + +Key types: +- `MessageBus` - Bus implementation +- `InboundMessage` - Incoming messages +- `OutboundMessage` - Outgoing messages + +### pkg/session + +Session and history management. + +Key types: +- `Session` - Conversation session +- `SessionManager` - Session management + +### pkg/channels + +Platform integrations. + +Key types: +- `Channel` - Channel interface +- `BaseChannel` - Common functionality + +### pkg/skills + +Skill loading system. + +Key types: +- `SkillsLoader` - Skill discovery +- `SkillInfo` - Skill metadata + +## Quick Reference + +### Implementing a Tool + +```go +type MyTool struct{} + +func (t *MyTool) Name() string { return "my-tool" } +func (t *MyTool) Description() string { return "Does something" } +func (t *MyTool) Parameters() map[string]interface{} { + return map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "input": map[string]interface{}{"type": "string"}, + }, + "required": []string{"input"}, + } +} +func (t *MyTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + return UserResult("Result") +} +``` + +### Implementing a Provider + +```go +type MyProvider struct{} + +func (p *MyProvider) Chat(ctx context.Context, messages []Message, + tools []ToolDefinition, model string, + options map[string]interface{}) (*LLMResponse, error) { + // Implementation +} + +func (p *MyProvider) GetDefaultModel() string { + return "my-model" +} +``` + +### Using the Message Bus + +```go +bus := bus.NewMessageBus() + +// Publish inbound +bus.PublishInbound(bus.InboundMessage{ + Channel: "telegram", + ChatID: "123", + Content: "Hello", +}) + +// Consume inbound +msg, ok := bus.ConsumeInbound(ctx) + +// Publish outbound +bus.PublishOutbound(bus.OutboundMessage{ + Channel: "telegram", + ChatID: "123", + Content: "Hi there!", +}) +``` + +### Using Session Manager + +```go +sm := session.NewSessionManager(storagePath) + +// Get or create session +session := sm.GetOrCreate("telegram:123") + +// Add message +sm.AddMessage("telegram:123", "user", "Hello") + +// Get history +history := sm.GetHistory("telegram:123") + +// Save +sm.Save("telegram:123") +``` + +## See Also + +- [Creating Tools](../extending/creating-tools.md) +- [Creating Providers](../extending/creating-providers.md) +- [Creating Channels](../extending/creating-channels.md) +- [Architecture Overview](../architecture.md) diff --git a/docs/developer-guide/api/message-bus.md b/docs/developer-guide/api/message-bus.md new file mode 100644 index 0000000000..fcbfd54841 --- /dev/null +++ b/docs/developer-guide/api/message-bus.md @@ -0,0 +1,490 @@ +# Message Bus API Reference + +This document provides detailed reference for the Message Bus API. + +## Overview + +The Message Bus is the central communication hub in PicoClaw. It enables asynchronous communication between channels and the agent loop. + +## Types + +### MessageBus + +The main message bus structure. + +```go +type MessageBus struct { + inbound chan InboundMessage + outbound chan OutboundMessage + handlers map[string]MessageHandler + closed bool + mu sync.RWMutex +} +``` + +### InboundMessage + +Message from an external platform. + +```go +type InboundMessage struct { + Channel string `json:"channel"` + SenderID string `json:"sender_id"` + ChatID string `json:"chat_id"` + Content string `json:"content"` + Media []string `json:"media,omitempty"` + SessionKey string `json:"session_key"` + Metadata map[string]string `json:"metadata,omitempty"` +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| Channel | string | Platform identifier (e.g., "telegram", "discord") | +| SenderID | string | User identifier on the platform | +| ChatID | string | Chat/conversation identifier | +| Content | string | Message text content | +| Media | []string | Optional media URLs or paths | +| SessionKey | string | Optional pre-computed session key | +| Metadata | map[string]string | Platform-specific metadata | + +**Common Metadata Keys:** + +| Key | Description | +|-----|-------------| +| message_id | Platform message ID | +| reply_to_id | ID of message being replied to | +| peer_kind | "direct", "group", "channel" | +| peer_id | Peer identifier | +| account_id | Bot account identifier | +| guild_id | Discord guild ID | +| team_id | Slack team ID | + +### OutboundMessage + +Message to be sent to a platform. + +```go +type OutboundMessage struct { + Channel string `json:"channel"` + ChatID string `json:"chat_id"` + Content string `json:"content"` +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| Channel | string | Target platform | +| ChatID | string | Target chat/conversation | +| Content | string | Message content | + +### MessageHandler + +Function type for handling inbound messages. + +```go +type MessageHandler func(InboundMessage) error +``` + +## Functions + +### NewMessageBus + +Creates a new message bus. + +```go +func NewMessageBus() *MessageBus +``` + +**Returns:** New MessageBus with buffered channels (capacity: 100) + +```go +bus := bus.NewMessageBus() +``` + +## Methods + +### PublishInbound + +Publishes an inbound message to the bus. + +```go +func (mb *MessageBus) PublishInbound(msg InboundMessage) +``` + +**Parameters:** +- `msg`: Message to publish + +**Behavior:** +- Non-blocking if channel has capacity +- Silently drops message if bus is closed + +```go +bus.PublishInbound(bus.InboundMessage{ + Channel: "telegram", + SenderID: "123456", + ChatID: "123456", + Content: "Hello!", +}) +``` + +### ConsumeInbound + +Consumes an inbound message from the bus. + +```go +func (mb *MessageBus) ConsumeInbound(ctx context.Context) (InboundMessage, bool) +``` + +**Parameters:** +- `ctx`: Context for cancellation + +**Returns:** +- `InboundMessage`: The consumed message +- `bool`: True if message was received, false if context cancelled + +```go +msg, ok := bus.ConsumeInbound(ctx) +if !ok { + // Context cancelled + return +} +// Process msg +``` + +### PublishOutbound + +Publishes an outbound message to the bus. + +```go +func (mb *MessageBus) PublishOutbound(msg OutboundMessage) +``` + +**Parameters:** +- `msg`: Message to publish + +```go +bus.PublishOutbound(bus.OutboundMessage{ + Channel: "telegram", + ChatID: "123456", + Content: "Hi there!", +}) +``` + +### SubscribeOutbound + +Subscribes to outbound messages. + +```go +func (mb *MessageBus) SubscribeOutbound(ctx context.Context) (OutboundMessage, bool) +``` + +**Parameters:** +- `ctx`: Context for cancellation + +**Returns:** +- `OutboundMessage`: The outbound message +- `bool`: True if message was received, false if context cancelled + +```go +for { + msg, ok := bus.SubscribeOutbound(ctx) + if !ok { + break // Context cancelled + } + + // Send msg to platform + channel.Send(ctx, msg) +} +``` + +### RegisterHandler + +Registers a handler for a channel. + +```go +func (mb *MessageBus) RegisterHandler(channel string, handler MessageHandler) +``` + +**Parameters:** +- `channel`: Channel name +- `handler`: Handler function + +```go +bus.RegisterHandler("telegram", func(msg bus.InboundMessage) error { + // Handle message + return nil +}) +``` + +### GetHandler + +Retrieves a handler for a channel. + +```go +func (mb *MessageBus) GetHandler(channel string) (MessageHandler, bool) +``` + +**Parameters:** +- `channel`: Channel name + +**Returns:** +- `MessageHandler`: The registered handler +- `bool`: True if handler exists + +```go +handler, ok := bus.GetHandler("telegram") +if ok { + handler(msg) +} +``` + +### Close + +Closes the message bus. + +```go +func (mb *MessageBus) Close() +``` + +**Behavior:** +- Closes inbound and outbound channels +- Prevents new messages from being published +- Safe to call multiple times + +```go +bus.Close() +``` + +## Usage Patterns + +### Producer (Channel) + +Channels publish inbound messages: + +```go +type TelegramChannel struct { + bus *bus.MessageBus +} + +func (c *TelegramChannel) handleUpdate(update Update) { + c.bus.PublishInbound(bus.InboundMessage{ + Channel: "telegram", + SenderID: strconv.FormatInt(update.Message.From.ID, 10), + ChatID: strconv.FormatInt(update.Message.Chat.ID, 10), + Content: update.Message.Text, + Metadata: map[string]string{ + "message_id": strconv.FormatInt(update.Message.MessageID, 10), + }, + }) +} +``` + +### Consumer (Agent Loop) + +The agent loop consumes inbound messages: + +```go +func (al *AgentLoop) Run(ctx context.Context) error { + for al.running.Load() { + select { + case <-ctx.Done(): + return nil + default: + msg, ok := al.bus.ConsumeInbound(ctx) + if !ok { + continue + } + + response, err := al.processMessage(ctx, msg) + if err != nil { + response = fmt.Sprintf("Error: %v", err) + } + + if response != "" { + al.bus.PublishOutbound(bus.OutboundMessage{ + Channel: msg.Channel, + ChatID: msg.ChatID, + Content: response, + }) + } + } + } + return nil +} +``` + +### Subscriber (Gateway) + +Gateways subscribe to outbound messages: + +```go +func (g *Gateway) runOutboundLoop(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + default: + msg, ok := g.bus.SubscribeOutbound(ctx) + if !ok { + continue + } + + channel, ok := g.channels.GetChannel(msg.Channel) + if !ok { + continue + } + + if err := channel.Send(ctx, msg); err != nil { + log.Printf("Failed to send: %v", err) + } + } + } +} +``` + +## Thread Safety + +The MessageBus is thread-safe: + +- All operations are protected by mutex +- Multiple goroutines can publish simultaneously +- Multiple goroutines can consume simultaneously + +```go +// Safe to call from multiple goroutines +go func() { + bus.PublishInbound(msg1) +}() + +go func() { + bus.PublishInbound(msg2) +}() +``` + +## Buffer Behavior + +Channels are buffered with capacity 100: + +- Publish is non-blocking until buffer is full +- When buffer is full, publish blocks until space available +- This provides backpressure to prevent memory issues + +## Error Handling + +### Closed Bus + +Operations on a closed bus are safe: + +```go +bus.Close() + +// Safe - message is dropped +bus.PublishInbound(msg) // No-op + +// Safe - returns empty message and false +msg, ok := bus.ConsumeInbound(ctx) // ok == false +``` + +### Context Cancellation + +Consume/Subscribe respect context: + +```go +ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +defer cancel() + +msg, ok := bus.ConsumeInbound(ctx) +if !ok { + // Timed out or cancelled +} +``` + +## Best Practices + +### Publishing + +1. **Check Context**: Respect context in publishers +2. **Handle Full Buffer**: Be prepared for blocking +3. **Don't Block**: Don't hold locks while publishing + +```go +func (c *Channel) publishAsync(msg bus.InboundMessage) { + go func() { + select { + case <-c.ctx.Done(): + return + default: + c.bus.PublishInbound(msg) + } + }() +} +``` + +### Consuming + +1. **Use Context**: Always use context for cancellation +2. **Check OK**: Always check the ok return value +3. **Handle Errors**: Process errors gracefully + +```go +for { + msg, ok := bus.ConsumeInbound(ctx) + if !ok { + if ctx.Err() != nil { + // Context cancelled + return ctx.Err() + } + // Bus closed + return nil + } + + if err := process(msg); err != nil { + // Handle error + } +} +``` + +### Graceful Shutdown + +1. **Stop Publishing**: Stop accepting new messages +2. **Drain Queues**: Process remaining messages +3. **Close Bus**: Close when done + +```go +// Stop accepting new messages +stopChannels() + +// Drain with timeout +drainCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) +for { + msg, ok := bus.ConsumeInbound(drainCtx) + if !ok { + break + } + process(msg) +} +cancel() + +// Close bus +bus.Close() +``` + +## Performance Characteristics + +| Metric | Value | +|--------|-------| +| Buffer Capacity | 100 messages per channel | +| Memory per Message | ~200 bytes (approximate) | +| Thread Safety | Yes (mutex protected) | +| Blocking | Yes (when buffer full) | + +## See Also + +- [Data Flow](../data-flow.md) +- [Creating Channels](../extending/creating-channels.md) +- [Bus Implementation](https://github.com/sipeed/picoclaw/tree/main/pkg/bus) diff --git a/docs/developer-guide/api/provider-interface.md b/docs/developer-guide/api/provider-interface.md new file mode 100644 index 0000000000..2f85877658 --- /dev/null +++ b/docs/developer-guide/api/provider-interface.md @@ -0,0 +1,482 @@ +# LLMProvider Interface Reference + +This document provides detailed reference for the LLMProvider interface and related types. + +## Core Interface + +### LLMProvider + +The interface that all LLM providers must implement. + +```go +type LLMProvider interface { + Chat(ctx context.Context, messages []Message, tools []ToolDefinition, + model string, options map[string]interface{}) (*LLMResponse, error) + GetDefaultModel() string +} +``` + +### Methods + +#### Chat + +Sends a chat request to the LLM. + +```go +Chat(ctx context.Context, messages []Message, tools []ToolDefinition, + model string, options map[string]interface{}) (*LLMResponse, error) +``` + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| ctx | context.Context | Context for cancellation and timeout | +| messages | []Message | Conversation history | +| tools | []ToolDefinition | Available tools for function calling | +| model | string | Model identifier (may include provider prefix) | +| options | map[string]interface{} | Additional options (max_tokens, temperature, etc.) | + +**Returns:** + +| Type | Description | +|------|-------------| +| *LLMResponse | LLM response with content and tool calls | +| error | Error if request failed | + +**Common Options:** + +| Key | Type | Description | +|-----|------|-------------| +| max_tokens | int | Maximum tokens in response | +| temperature | float64 | Sampling temperature (0-2) | +| top_p | float64 | Nucleus sampling parameter | +| stop | []string | Stop sequences | + +#### GetDefaultModel + +Returns the default model for this provider. + +```go +GetDefaultModel() string +``` + +**Returns:** Model identifier string (e.g., "openrouter/anthropic/claude-opus-4-5") + +## Message Types + +### Message + +Represents a message in the conversation. + +```go +type Message struct { + Role string `json:"role"` + Content string `json:"content"` + ToolCalls []ToolCall `json:"tool_calls,omitempty"` + ToolCallID string `json:"tool_call_id,omitempty"` +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| Role | string | "system", "user", "assistant", or "tool" | +| Content | string | Message text content | +| ToolCalls | []ToolCall | Tool calls from assistant | +| ToolCallID | string | ID for tool response messages | + +**Roles:** + +- `system`: System instructions +- `user`: User message +- `assistant`: LLM response +- `tool`: Tool execution result + +### ToolCall + +Represents a tool call request from the LLM. + +```go +type ToolCall struct { + ID string `json:"id"` + Type string `json:"type,omitempty"` + Function *FunctionCall `json:"function,omitempty"` + Name string `json:"name,omitempty"` + Arguments map[string]interface{} `json:"arguments,omitempty"` +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| ID | string | Unique identifier for the tool call | +| Type | string | Usually "function" | +| Function | *FunctionCall | Function call details (for API format) | +| Name | string | Function/tool name | +| Arguments | map[string]interface{} | Parsed arguments | + +### FunctionCall + +Detailed function call information. + +```go +type FunctionCall struct { + Name string `json:"name"` + Arguments string `json:"arguments"` // JSON string +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| Name | string | Function name | +| Arguments | string | Arguments as JSON string | + +### LLMResponse + +Response from the LLM. + +```go +type LLMResponse struct { + Content string `json:"content"` + ToolCalls []ToolCall `json:"tool_calls,omitempty"` + FinishReason string `json:"finish_reason"` + Usage *UsageInfo `json:"usage,omitempty"` +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| Content | string | Text content of response | +| ToolCalls | []ToolCall | Requested tool calls | +| FinishReason | string | Why generation stopped | +| Usage | *UsageInfo | Token usage information | + +**Finish Reasons:** + +- `stop`: Natural end of response +- `tool_calls`: LLM requested tool execution +- `length`: Max tokens reached +- `content_filter`: Content policy triggered + +### UsageInfo + +Token usage statistics. + +```go +type UsageInfo struct { + PromptTokens int `json:"prompt_tokens"` + CompletionTokens int `json:"completion_tokens"` + TotalTokens int `json:"total_tokens"` +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| PromptTokens | int | Tokens in the prompt | +| CompletionTokens | int | Tokens in the response | +| TotalTokens | int | Total tokens used | + +## Tool Definition Types + +### ToolDefinition + +Defines a tool for the LLM. + +```go +type ToolDefinition struct { + Type string `json:"type"` + Function ToolFunctionDefinition `json:"function"` +} +``` + +### ToolFunctionDefinition + +Describes a tool function. + +```go +type ToolFunctionDefinition struct { + Name string `json:"name"` + Description string `json:"description"` + Parameters map[string]interface{} `json:"parameters"` +} +``` + +## Error Handling + +### FailoverError + +Error with classification for fallback support. + +```go +type FailoverError struct { + Reason FailoverReason + Provider string + Model string + Status int + Wrapped error +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| Reason | FailoverReason | Classification of the error | +| Provider | string | Provider identifier | +| Model | string | Model being used | +| Status | int | HTTP status code | +| Wrapped | error | Underlying error | + +### FailoverReason + +Classification of LLM errors. + +```go +type FailoverReason string + +const ( + FailoverAuth FailoverReason = "auth" + FailoverRateLimit FailoverReason = "rate_limit" + FailoverBilling FailoverReason = "billing" + FailoverTimeout FailoverReason = "timeout" + FailoverFormat FailoverReason = "format" + FailoverOverloaded FailoverReason = "overloaded" + FailoverUnknown FailoverReason = "unknown" +) +``` + +**Reasons:** + +| Reason | Description | Retriable | +|--------|-------------|-----------| +| auth | Authentication error | No | +| rate_limit | Rate limited | Yes | +| billing | Billing/quota issue | No | +| timeout | Request timeout | Yes | +| format | Invalid request format | No | +| overloaded | Service overloaded | Yes | +| unknown | Unknown error | Yes | + +### Methods + +#### Error() string + +Returns formatted error message. + +```go +func (e *FailoverError) Error() string +// "failover(auth): provider=openrouter model=gpt-4 status=401: ..." +``` + +#### Unwrap() error + +Returns the underlying error. + +```go +func (e *FailoverError) Unwrap() error +``` + +#### IsRetriable() bool + +Returns true if the error should trigger fallback. + +```go +func (e *FailoverError) IsRetriable() bool +// Returns false for Format errors, true otherwise +``` + +## Fallback Chain + +### ModelConfig + +Configuration for primary and fallback models. + +```go +type ModelConfig struct { + Primary string + Fallbacks []string +} +``` + +### FallbackChain + +Handles fallback between model candidates. + +```go +type FallbackChain struct { + // contains filtered or unexported fields +} +``` + +#### NewFallbackChain(cooldown *CooldownTracker) *FallbackChain + +Creates a new fallback chain. + +```go +cooldown := providers.NewCooldownTracker() +fallback := providers.NewFallbackChain(cooldown) +``` + +#### Execute + +Executes with fallback logic. + +```go +func (fc *FallbackChain) Execute(ctx context.Context, + candidates []ModelCandidate, + fn func(ctx context.Context, provider, model string) (*LLMResponse, error), +) (*FallbackResult, error) +``` + +### CooldownTracker + +Tracks provider cooldown periods. + +```go +type CooldownTracker struct { + // contains filtered or unexported fields +} +``` + +#### NewCooldownTracker() *CooldownTracker + +Creates a new tracker. + +```go +tracker := providers.NewCooldownTracker() +``` + +#### SetCooldown(provider string, duration time.Duration) + +Sets a cooldown for a provider. + +```go +tracker.SetCooldown("openrouter", 30*time.Second) +``` + +#### IsOnCooldown(provider string) bool + +Checks if provider is on cooldown. + +```go +if tracker.IsOnCooldown("openrouter") { + // Skip this provider +} +``` + +## Model Reference + +### ModelRef + +Parses and manipulates model references. + +Format: `provider/model` or just `model` + +```go +// Parse model reference +ref := providers.ParseModelRef("openrouter/anthropic/claude-opus-4-5") + +ref.Provider // "openrouter" +ref.Model // "anthropic/claude-opus-4-5" +ref.Full // "openrouter/anthropic/claude-opus-4-5" +``` + +## Usage Example + +### Basic Chat + +```go +provider := openai_compat.NewProvider(apiKey, apiBase, "") + +messages := []providers.Message{ + {Role: "system", Content: "You are a helpful assistant."}, + {Role: "user", Content: "Hello!"}, +} + +response, err := provider.Chat(ctx, messages, nil, "gpt-4", map[string]interface{}{ + "max_tokens": 1024, + "temperature": 0.7, +}) +if err != nil { + return err +} + +fmt.Println(response.Content) +``` + +### With Tool Calling + +```go +tools := []providers.ToolDefinition{ + { + Type: "function", + Function: providers.ToolFunctionDefinition{ + Name: "get_weather", + Description: "Get current weather", + Parameters: map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "location": map[string]interface{}{ + "type": "string", + }, + }, + "required": []string{"location"}, + }, + }, + }, +} + +response, err := provider.Chat(ctx, messages, tools, "gpt-4", options) + +// Handle tool calls +for _, tc := range response.ToolCalls { + fmt.Printf("Tool: %s, Args: %v\n", tc.Name, tc.Arguments) +} +``` + +### With Fallback + +```go +candidates := []providers.ModelCandidate{ + {Provider: "openrouter", Model: "anthropic/claude-opus-4-5"}, + {Provider: "openrouter", Model: "anthropic/claude-sonnet-4"}, + {Provider: "groq", Model: "llama-3-70b"}, +} + +result, err := fallback.Execute(ctx, candidates, + func(ctx context.Context, provider, model string) (*providers.LLMResponse, error) { + return providerClient.Chat(ctx, messages, tools, model, options) + }, +) + +if err != nil { + return err +} + +fmt.Printf("Succeeded with %s/%s\n", result.Provider, result.Model) +fmt.Println(result.Response.Content) +``` + +## Best Practices + +1. **Always Use Context**: Pass context for cancellation +2. **Handle Timeouts**: Set appropriate timeouts +3. **Classify Errors**: Use FailoverError for fallback support +4. **Normalize Models**: Handle provider prefixes +5. **Validate Responses**: Check for empty or malformed responses +6. **Log Requests**: Log for debugging (with redacted API keys) + +## See Also + +- [Creating LLM Providers](../extending/creating-providers.md) +- [Provider Implementations](https://github.com/sipeed/picoclaw/tree/main/pkg/providers) +- [OpenAI-Compatible Provider](https://github.com/sipeed/picoclaw/tree/main/pkg/providers/openai_compat) diff --git a/docs/developer-guide/api/session-api.md b/docs/developer-guide/api/session-api.md new file mode 100644 index 0000000000..7f8d79d81a --- /dev/null +++ b/docs/developer-guide/api/session-api.md @@ -0,0 +1,520 @@ +# Session Manager API Reference + +This document provides detailed reference for the Session Manager API. + +## Overview + +The Session Manager handles conversation history storage and retrieval. It provides: + +- In-memory caching for fast access +- Disk persistence for durability +- Automatic summarization support +- Thread-safe operations + +## Types + +### Session + +Represents a conversation session. + +```go +type Session struct { + Key string `json:"key"` + Messages []providers.Message `json:"messages"` + Summary string `json:"summary,omitempty"` + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` +} +``` + +**Fields:** + +| Field | Type | Description | +|-------|------|-------------| +| Key | string | Unique session identifier | +| Messages | []providers.Message | Conversation history | +| Summary | string | Summary of older messages | +| Created | time.Time | Session creation time | +| Updated | time.Time | Last update time | + +### SessionManager + +Manages sessions with caching and persistence. + +```go +type SessionManager struct { + sessions map[string]*Session + mu sync.RWMutex + storage string +} +``` + +## Functions + +### NewSessionManager + +Creates a new session manager. + +```go +func NewSessionManager(storage string) *SessionManager +``` + +**Parameters:** +- `storage`: Directory path for session files (empty for memory-only) + +**Returns:** New SessionManager instance + +```go +// With persistence +sm := session.NewSessionManager("/path/to/sessions") + +// Memory-only +sm := session.NewSessionManager("") +``` + +## Methods + +### GetOrCreate + +Gets an existing session or creates a new one. + +```go +func (sm *SessionManager) GetOrCreate(key string) *Session +``` + +**Parameters:** +- `key`: Session identifier + +**Returns:** Session instance (existing or new) + +```go +session := sm.GetOrCreate("telegram:123456") +``` + +### AddMessage + +Adds a simple message to the session. + +```go +func (sm *SessionManager) AddMessage(sessionKey, role, content string) +``` + +**Parameters:** +- `sessionKey`: Session identifier +- `role`: Message role ("user", "assistant", "system") +- `content`: Message content + +```go +sm.AddMessage("telegram:123456", "user", "Hello!") +sm.AddMessage("telegram:123456", "assistant", "Hi there!") +``` + +### AddFullMessage + +Adds a complete message with all fields. + +```go +func (sm *SessionManager) AddFullMessage(sessionKey string, msg providers.Message) +``` + +**Parameters:** +- `sessionKey`: Session identifier +- `msg`: Complete message with tool calls, etc. + +```go +sm.AddFullMessage("telegram:123456", providers.Message{ + Role: "assistant", + Content: "Let me check that.", + ToolCalls: []providers.ToolCall{ + {ID: "call_123", Name: "files_read", Arguments: map[string]interface{}{"path": "/tmp/file.txt"}}, + }, +}) +``` + +### GetHistory + +Gets the conversation history for a session. + +```go +func (sm *SessionManager) GetHistory(key string) []providers.Message +``` + +**Parameters:** +- `key`: Session identifier + +**Returns:** Copy of message history + +```go +history := sm.GetHistory("telegram:123456") +for _, msg := range history { + fmt.Printf("%s: %s\n", msg.Role, msg.Content) +} +``` + +### SetHistory + +Replaces the entire message history. + +```go +func (sm *SessionManager) SetHistory(key string, history []providers.Message) +``` + +**Parameters:** +- `key`: Session identifier +- `history`: New message history + +```go +newHistory := []providers.Message{ + {Role: "system", Content: "You are helpful."}, + {Role: "user", Content: "Hello"}, +} +sm.SetHistory("telegram:123456", newHistory) +``` + +### GetSummary + +Gets the session summary. + +```go +func (sm *SessionManager) GetSummary(key string) string +``` + +**Parameters:** +- `key`: Session identifier + +**Returns:** Summary string (empty if none) + +```go +summary := sm.GetSummary("telegram:123456") +if summary != "" { + fmt.Println("Previous context:", summary) +} +``` + +### SetSummary + +Sets the session summary. + +```go +func (sm *SessionManager) SetSummary(key string, summary string) +``` + +**Parameters:** +- `key`: Session identifier +- `summary`: Summary text + +```go +sm.SetSummary("telegram:123456", "User asked about weather. Discussed forecast for the week.") +``` + +### TruncateHistory + +Truncates history to keep only the last N messages. + +```go +func (sm *SessionManager) TruncateHistory(key string, keepLast int) +``` + +**Parameters:** +- `key`: Session identifier +- `keepLast`: Number of recent messages to keep (0 to clear all) + +```go +// Keep only last 4 messages +sm.TruncateHistory("telegram:123456", 4) + +// Clear all messages +sm.TruncateHistory("telegram:123456", 0) +``` + +### Save + +Saves a session to disk. + +```go +func (sm *SessionManager) Save(key string) error +``` + +**Parameters:** +- `key`: Session identifier + +**Returns:** Error if save failed + +**Note:** Only saves if storage path was configured. + +```go +if err := sm.Save("telegram:123456"); err != nil { + log.Printf("Failed to save session: %v", err) +} +``` + +## Session Keys + +Session keys uniquely identify conversations. Common formats: + +| Format | Example | Description | +|--------|---------|-------------| +| channel:chatID | `telegram:123456` | Basic session | +| agent:agentID:channel:chatID | `agent:main:telegram:123456` | Agent-specific | + +### Key Sanitization + +Keys are sanitized for filesystem safety: + +```go +// Colon (:) is replaced with underscore (_) +// "telegram:123456" -> file "telegram_123456.json" +``` + +## File Format + +Sessions are stored as JSON files: + +```json +{ + "key": "telegram:123456", + "messages": [ + { + "role": "user", + "content": "Hello!" + }, + { + "role": "assistant", + "content": "Hi there!" + } + ], + "summary": "", + "created": "2024-01-15T10:30:00Z", + "updated": "2024-01-15T10:31:00Z" +} +``` + +## Usage Patterns + +### Basic Conversation + +```go +sm := session.NewSessionManager(storagePath) +sessionKey := "telegram:123456" + +// Get or create session +sess := sm.GetOrCreate(sessionKey) + +// Add user message +sm.AddMessage(sessionKey, "user", "What's the weather?") + +// ... LLM call ... + +// Add assistant response +sm.AddMessage(sessionKey, "assistant", "It's sunny today.") + +// Save +sm.Save(sessionKey) +``` + +### With Tool Calls + +```go +// Add user message +sm.AddMessage(sessionKey, "user", "Read the config file") + +// Add assistant message with tool call +sm.AddFullMessage(sessionKey, providers.Message{ + Role: "assistant", + Content: "", + ToolCalls: []providers.ToolCall{{ + ID: "call_1", + Name: "files_read", + Arguments: map[string]interface{}{"path": "config.json"}, + }}, +}) + +// Add tool result +sm.AddFullMessage(sessionKey, providers.Message{ + Role: "tool", + Content: `{"setting": "value"}`, + ToolCallID: "call_1", +}) + +// Add final assistant response +sm.AddMessage(sessionKey, "assistant", "The config contains...") +``` + +### Summarization + +```go +// Check if summarization needed +history := sm.GetHistory(sessionKey) +if len(history) > 20 { + // Generate summary + summary := generateSummary(history[:len(history)-4]) + + // Set summary + sm.SetSummary(sessionKey, summary) + + // Keep only recent messages + sm.TruncateHistory(sessionKey, 4) + + // Save + sm.Save(sessionKey) +} +``` + +### Building LLM Context + +```go +func buildContext(sm *session.SessionManager, sessionKey, userMessage string) []providers.Message { + var messages []providers.Message + + // System prompt + messages = append(messages, providers.Message{ + Role: "system", + Content: "You are a helpful assistant.", + }) + + // Add summary if exists + if summary := sm.GetSummary(sessionKey); summary != "" { + messages = append(messages, providers.Message{ + Role: "system", + Content: "Previous conversation summary: " + summary, + }) + } + + // Add history + messages = append(messages, sm.GetHistory(sessionKey)...) + + // Add current message + messages = append(messages, providers.Message{ + Role: "user", + Content: userMessage, + }) + + return messages +} +``` + +## Thread Safety + +The SessionManager is thread-safe: + +- All operations are protected by RWMutex +- Multiple goroutines can read simultaneously +- Write operations are exclusive + +```go +// Safe to use from multiple goroutines +go func() { + sm.AddMessage("session1", "user", "Message 1") +}() + +go func() { + sm.AddMessage("session2", "user", "Message 2") +}() +``` + +## Persistence + +### Atomic Writes + +Sessions are saved atomically: + +1. Write to temporary file +2. Sync to disk +3. Rename to final location + +This prevents corruption from crashes. + +### Loading + +Sessions are loaded lazily on `GetOrCreate`: + +1. Check in-memory cache +2. If not found, load from disk +3. Cache in memory + +### Storage Location + +Typical storage locations: + +``` +~/.picoclaw/workspace/sessions/ +├── telegram_123456.json +├── telegram_-1001234567890.json # Group chat +├── discord_123456789012345678.json +└── ... +``` + +## Error Handling + +### Save Errors + +```go +if err := sm.Save(sessionKey); err != nil { + if errors.Is(err, os.ErrInvalid) { + // Invalid session key + } else { + // Filesystem error + } +} +``` + +### Missing Sessions + +```go +// GetHistory returns empty slice for missing sessions +history := sm.GetHistory("nonexistent") +// history == []providers.Message{} + +// GetSummary returns empty string for missing sessions +summary := sm.GetSummary("nonexistent") +// summary == "" +``` + +## Best Practices + +1. **Save After Changes**: Save after important operations +2. **Use Meaningful Keys**: Use consistent key formats +3. **Handle Errors**: Check for save errors +4. **Don't Block**: Save in goroutine if needed +5. **Summarize**: Keep history manageable with summaries + +### Async Saving + +```go +// Save without blocking +go func() { + if err := sm.Save(sessionKey); err != nil { + log.Printf("Failed to save session: %v", err) + } +}() +``` + +### Periodic Saving + +```go +go func() { + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() + + for range ticker.C { + for _, key := range getActiveSessions() { + sm.Save(key) + } + } +}() +``` + +## Performance Characteristics + +| Metric | Value | +|--------|-------| +| Memory | O(n) where n = total messages across sessions | +| Read | O(1) for cache hit, O(n) for file load | +| Write | O(1) for memory, O(n) for disk save | +| Thread Safety | Yes (RWMutex) | + +## See Also + +- [Data Flow](../data-flow.md) +- [Session Manager Implementation](https://github.com/sipeed/picoclaw/tree/main/pkg/session) +- [Provider Types](https://github.com/sipeed/picoclaw/tree/main/pkg/providers/protocoltypes) diff --git a/docs/developer-guide/api/tool-interface.md b/docs/developer-guide/api/tool-interface.md new file mode 100644 index 0000000000..4725b8ae88 --- /dev/null +++ b/docs/developer-guide/api/tool-interface.md @@ -0,0 +1,469 @@ +# Tool Interface Reference + +This document provides detailed reference for the Tool interface and related types. + +## Core Interface + +### Tool + +The base interface that all tools must implement. + +```go +type Tool interface { + Name() string + Description() string + Parameters() map[string]interface{} + Execute(ctx context.Context, args map[string]interface{}) *ToolResult +} +``` + +#### Methods + +##### Name() string + +Returns the unique identifier for the tool. + +- **Returns**: Tool name (e.g., "files_read", "exec", "message") +- **Usage**: Used for tool lookup and LLM function calling + +```go +func (t *MyTool) Name() string { + return "my-tool" +} +``` + +##### Description() string + +Returns a human-readable description of what the tool does. + +- **Returns**: Description text +- **Usage**: Helps the LLM understand when to use this tool + +```go +func (t *MyTool) Description() string { + return "Performs a specific action. Use this when you need to..." +} +``` + +##### Parameters() map[string]interface{} + +Returns the JSON Schema for the tool's parameters. + +- **Returns**: JSON Schema object +- **Usage**: Defines the structure of arguments for LLM function calling + +```go +func (t *MyTool) Parameters() map[string]interface{} { + return map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "path": map[string]interface{}{ + "type": "string", + "description": "File path to read", + }, + "encoding": map[string]interface{}{ + "type": "string", + "default": "utf-8", + "description": "File encoding", + }, + }, + "required": []string{"path"}, + } +} +``` + +##### Execute(ctx context.Context, args map[string]interface{}) *ToolResult + +Executes the tool with the provided arguments. + +- **Parameters**: + - `ctx`: Context for cancellation and timeout + - `args`: Arguments matching the Parameters schema +- **Returns**: ToolResult with execution outcome + +```go +func (t *MyTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + path, ok := args["path"].(string) + if !ok { + return ErrorResult("path is required") + } + + // Do work... + content, err := os.ReadFile(path) + if err != nil { + return ErrorResult(fmt.Sprintf("failed to read: %v", err)) + } + + return UserResult(string(content)) +} +``` + +## Optional Interfaces + +### ContextualTool + +For tools that need channel/chat context. + +```go +type ContextualTool interface { + Tool + SetContext(channel, chatID string) +} +``` + +#### SetContext(channel, chatID string) + +Called before Execute to provide message context. + +- **Parameters**: + - `channel`: Platform identifier (e.g., "telegram") + - `chatID`: Chat/conversation identifier + +```go +type MessageTool struct { + defaultChannel string + defaultChatID string +} + +func (t *MessageTool) SetContext(channel, chatID string) { + t.defaultChannel = channel + t.defaultChatID = chatID +} +``` + +### AsyncTool + +For tools that execute asynchronously. + +```go +type AsyncCallback func(ctx context.Context, result *ToolResult) + +type AsyncTool interface { + Tool + SetCallback(cb AsyncCallback) +} +``` + +#### SetCallback(cb AsyncCallback) + +Registers a callback for async completion notification. + +- **Parameters**: + - `cb`: Callback function to invoke when complete + +```go +type SpawnTool struct { + callback AsyncCallback +} + +func (t *SpawnTool) SetCallback(cb AsyncCallback) { + t.callback = cb +} + +func (t *SpawnTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + go func() { + // Do async work + result := doWork(args) + + // Notify completion + if t.callback != nil { + t.callback(ctx, result) + } + }() + + return AsyncResult("Task started") +} +``` + +## ToolResult + +The return type for tool execution. + +```go +type ToolResult struct { + ForLLM string `json:"for_llm"` + ForUser string `json:"for_user,omitempty"` + Silent bool `json:"silent"` + IsError bool `json:"is_error"` + Async bool `json:"async"` + Err error `json:"-"` +} +``` + +### Fields + +| Field | Type | Description | +|-------|------|-------------| +| ForLLM | string | Content sent to LLM (always required) | +| ForUser | string | Content sent directly to user | +| Silent | bool | If true, no message sent to user | +| IsError | bool | Indicates execution failure | +| Async | bool | Indicates async operation | +| Err | error | Underlying error (not JSON serialized) | + +### Constructor Functions + +#### NewToolResult(forLLM string) *ToolResult + +Creates a basic result with LLM content. + +```go +result := NewToolResult("Operation completed") +``` + +#### SilentResult(forLLM string) *ToolResult + +Creates a silent result (no user message). + +```go +result := SilentResult("File saved") +``` + +#### UserResult(content string) *ToolResult + +Creates a result with same content for LLM and user. + +```go +result := UserResult("Found 42 items") +``` + +#### ErrorResult(message string) *ToolResult + +Creates an error result. + +```go +result := ErrorResult("Failed to process: reason") +``` + +#### AsyncResult(forLLM string) *ToolResult + +Creates an async result for background operations. + +```go +result := AsyncResult("Task started, will notify on completion") +``` + +### Methods + +#### WithError(err error) *ToolResult + +Attaches an underlying error for logging. + +```go +result := ErrorResult("Failed").WithError(err) +``` + +## ToolRegistry + +Manages registered tools. + +```go +type ToolRegistry struct { + tools map[string]Tool + mu sync.RWMutex +} +``` + +### Methods + +#### NewToolRegistry() *ToolRegistry + +Creates a new empty registry. + +```go +registry := tools.NewToolRegistry() +``` + +#### Register(tool Tool) + +Registers a tool. + +```go +registry.Register(tools.NewMessageTool()) +``` + +#### Get(name string) (Tool, bool) + +Retrieves a tool by name. + +```go +tool, ok := registry.Get("message") +``` + +#### Execute(ctx context.Context, name string, args map[string]interface{}) *ToolResult + +Executes a tool by name. + +```go +result := registry.Execute(ctx, "message", map[string]interface{}{ + "content": "Hello", +}) +``` + +#### ExecuteWithContext(ctx context.Context, name string, args map[string]interface{}, channel, chatID string, asyncCallback AsyncCallback) *ToolResult + +Executes with context and optional async callback. + +```go +result := registry.ExecuteWithContext(ctx, "spawn", args, "telegram", "123", callback) +``` + +#### GetDefinitions() []map[string]interface{} + +Returns all tool definitions in JSON Schema format. + +```go +defs := registry.GetDefinitions() +``` + +#### ToProviderDefs() []providers.ToolDefinition + +Returns definitions in provider-compatible format. + +```go +providerDefs := registry.ToProviderDefs() +``` + +#### List() []string + +Returns all registered tool names. + +```go +names := registry.List() // ["message", "exec", "files_read", ...] +``` + +#### Count() int + +Returns the number of registered tools. + +```go +count := registry.Count() +``` + +#### GetSummaries() []string + +Returns human-readable summaries. + +```go +summaries := registry.GetSummaries() +// ["- `message` - Send a message to user", ...] +``` + +## Helper Functions + +### ToolToSchema(tool Tool) map[string]interface{} + +Converts a tool to JSON Schema format. + +```go +schema := tools.ToolToSchema(myTool) +// { +// "type": "function", +// "function": { +// "name": "my-tool", +// "description": "...", +// "parameters": {...} +// } +// } +``` + +## Parameter Schema Guide + +### Basic Types + +```go +// String +"name": map[string]interface{}{ + "type": "string", + "description": "User name", +} + +// Integer +"count": map[string]interface{}{ + "type": "integer", + "description": "Number of items", + "minimum": 1, + "maximum": 100, +} + +// Number (float) +"ratio": map[string]interface{}{ + "type": "number", + "description": "Ratio value", + "minimum": 0.0, + "maximum": 1.0, +} + +// Boolean +"enabled": map[string]interface{}{ + "type": "boolean", + "description": "Enable feature", + "default": false, +} +``` + +### Enumerations + +```go +"mode": map[string]interface{}{ + "type": "string", + "enum": []string{"fast", "normal", "thorough"}, + "description": "Processing mode", +} +``` + +### Arrays + +```go +"tags": map[string]interface{}{ + "type": "array", + "items": map[string]interface{}{"type": "string"}, + "description": "List of tags", +} +``` + +### Nested Objects + +```go +"options": map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "timeout": map[string]interface{}{ + "type": "integer", + "description": "Timeout in seconds", + }, + "retries": map[string]interface{}{ + "type": "integer", + "description": "Number of retries", + }, + }, +} +``` + +### Required Fields + +```go +map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "path": map[string]interface{}{...}, + "mode": map[string]interface{}{...}, + }, + "required": []string{"path"}, // mode is optional +} +``` + +## Best Practices + +1. **Clear Names**: Use lowercase with underscores +2. **Good Descriptions**: Explain when and how to use the tool +3. **Validate Inputs**: Check all arguments before processing +4. **Meaningful Errors**: Provide actionable error messages +5. **Use Context**: Support cancellation via context +6. **Choose Right Result Type**: Match result type to use case +7. **Handle Panics**: Recover in Execute to prevent crashes + +## See Also + +- [Creating Custom Tools](../extending/creating-tools.md) +- [Tool Implementations](https://github.com/sipeed/picoclaw/tree/main/pkg/tools) diff --git a/docs/developer-guide/architecture.md b/docs/developer-guide/architecture.md new file mode 100644 index 0000000000..a51e3bff47 --- /dev/null +++ b/docs/developer-guide/architecture.md @@ -0,0 +1,354 @@ +# System Architecture + +This document provides an overview of PicoClaw's system architecture, including its core components and how they interact. + +## High-Level Architecture + +PicoClaw follows a **message bus architecture** pattern where components communicate asynchronously through a central message bus. This design enables loose coupling between components and makes it easy to add new channels or modify processing logic. + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ External Platforms │ +│ Telegram Discord Slack WhatsApp CLI etc. │ +└───────┬───────────┬─────────┬─────────┬─────────┬───────────────┘ + │ │ │ │ │ + ▼ ▼ ▼ ▼ ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Channel Layer │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │Telegram │ │ Discord │ │ Slack │ │ CLI │ ... │ +│ │Channel │ │ Channel │ │ Channel │ │ Channel │ │ +│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ +└───────┼────────────┼────────────┼────────────┼──────────────────┘ + │ │ │ │ + ▼ ▼ ▼ ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Message Bus │ +│ ┌─────────────────────┐ ┌─────────────────────┐ │ +│ │ Inbound Channel │ │ Outbound Channel │ │ +│ │ (buffer: 100) │ │ (buffer: 100) │ │ +│ └──────────┬──────────┘ └──────────┬──────────┘ │ +└─────────────┼──────────────────────────┼────────────────────────┘ + │ ▲ + ▼ │ +┌─────────────────────────────────────────────────────────────────┐ +│ Agent Layer │ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ AgentLoop │ │ +│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ +│ │ │ Router │→ │ Agent │→ │ LLM │ │ │ +│ │ │ │ │ Registry │ │ Provider │ │ │ +│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ +│ │ │ │ │ +│ │ ▼ │ │ +│ │ ┌─────────────┐ │ │ +│ │ │ Tools │ │ │ +│ │ │ Registry │ │ │ +│ │ └─────────────┘ │ │ +│ └─────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Storage Layer │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Sessions │ │ Memory │ │ Cron │ │ +│ │ Manager │ │ (MD) │ │ Jobs │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## Core Components + +### 1. Message Bus (`pkg/bus/`) + +The message bus is the central communication hub. It provides: + +- **Inbound messages**: Messages from external platforms +- **Outbound messages**: Responses to be sent to platforms +- **Handler registration**: Maps channel names to handlers + +```go +type MessageBus struct { + inbound chan InboundMessage + outbound chan OutboundMessage + handlers map[string]MessageHandler +} +``` + +Key features: +- Buffered channels (capacity: 100) for async processing +- Thread-safe operations with mutex protection +- Context-aware consumption for graceful shutdown + +### 2. Agent Loop (`pkg/agent/loop.go`) + +The AgentLoop is the core message processing engine: + +```go +type AgentLoop struct { + bus *bus.MessageBus + cfg *config.Config + registry *AgentRegistry + state *state.Manager + fallback *providers.FallbackChain + channelManager *channels.Manager +} +``` + +Responsibilities: +- Consumes messages from the inbound bus +- Routes messages to appropriate agents +- Builds context with history and system prompts +- Calls LLM providers with fallback support +- Executes tool calls from LLM responses +- Publishes responses to the outbound bus + +### 3. Agent Registry (`pkg/agent/registry.go`) + +Manages multiple agents with different configurations: + +```go +type AgentRegistry struct { + agents map[string]*AgentInstance + default string + routes []routing.Rule +} +``` + +Features: +- Multi-agent support with isolated workspaces +- Message routing based on channel, peer type, etc. +- Agent-specific tool configurations + +### 4. Agent Instance (`pkg/agent/instance.go`) + +Represents a single agent configuration: + +```go +type AgentInstance struct { + ID string + Model string + Candidates []providers.ModelCandidate + Workspace string + Tools *tools.ToolRegistry + Sessions *session.SessionManager + ContextBuilder *ContextBuilder + MaxIterations int + ContextWindow int +} +``` + +### 5. Channels (`pkg/channels/`) + +Channels handle communication with external platforms: + +```go +type Channel interface { + Name() string + Start(ctx context.Context) error + Stop(ctx context.Context) error + Send(ctx context.Context, msg bus.OutboundMessage) error + IsRunning() bool + IsAllowed(senderID string) bool +} +``` + +Built-in channels: +- Telegram +- Discord +- Slack +- WhatsApp +- LINE +- QQ (OneBot) +- DingTalk +- Feishu/Lark +- MaixCam + +### 6. LLM Providers (`pkg/providers/`) + +Providers implement the LLM API integration: + +```go +type LLMProvider interface { + Chat(ctx context.Context, messages []Message, tools []ToolDefinition, + model string, options map[string]interface{}) (*LLMResponse, error) + GetDefaultModel() string +} +``` + +Built-in providers: +- OpenAI-compatible (OpenRouter, Groq, etc.) +- Anthropic/Claude +- Claude CLI +- Codex CLI +- GitHub Copilot + +### 7. Tools (`pkg/tools/`) + +Tools enable the agent to interact with the world: + +```go +type Tool interface { + Name() string + Description() string + Parameters() map[string]interface{} + Execute(ctx context.Context, args map[string]interface{}) *ToolResult +} +``` + +Built-in tools: +- `files_read` / `files_write` / `files_list` - File operations +- `exec` - Shell command execution +- `web_search` / `web_fetch` - Web operations +- `message` - Send messages to users +- `spawn` - Spawn subagents +- `cron` - Schedule tasks +- `i2c` / `spi` - Hardware interfaces (Linux only) + +### 8. Session Manager (`pkg/session/manager.go`) + +Manages conversation history: + +```go +type SessionManager struct { + sessions map[string]*Session + mu sync.RWMutex + storage string +} + +type Session struct { + Key string + Messages []providers.Message + Summary string + Created time.Time + Updated time.Time +} +``` + +Features: +- In-memory caching with disk persistence +- Automatic summarization when history exceeds thresholds +- Thread-safe operations + +### 9. Skills Loader (`pkg/skills/loader.go`) + +Loads custom skills from markdown files: + +```go +type SkillsLoader struct { + workspace string + workspaceSkills string + globalSkills string + builtinSkills string +} +``` + +Skills are loaded from three locations (in priority order): +1. Workspace skills (project-level) +2. Global skills (`~/.picoclaw/skills`) +3. Built-in skills + +## Data Flow + +See [Data Flow](data-flow.md) for a detailed explanation of how messages flow through the system. + +## Configuration + +Configuration is loaded from `~/.picoclaw/config.json`: + +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-..." + } + }, + "agents": { + "defaults": { + "model": "openrouter/anthropic/claude-opus-4-5" + }, + "list": [ + { + "id": "main", + "workspace": "~/.picoclaw/workspace" + } + ] + } +} +``` + +## Multi-Agent Support + +PicoClaw supports multiple agents with isolated configurations: + +1. **Agent Definition**: Each agent has a unique ID and workspace +2. **Routing**: Messages are routed based on rules (channel, peer type, etc.) +3. **Isolation**: Each agent has its own sessions, tools, and configuration + +See [Multi-Agent Guide](../user-guide/advanced/multi-agent.md) for details. + +## Security Sandbox + +When `restrict_to_workspace: true` (default): + +- File operations are limited to the workspace directory +- Shell commands must execute within workspace +- Dangerous commands are always blocked (`rm -rf`, `format`, `dd`, `shutdown`) + +See [Security Sandbox](../user-guide/advanced/security-sandbox.md) for details. + +## Workspace Structure + +``` +~/.picoclaw/workspace/ +├── sessions/ # Conversation history +├── memory/ # Long-term memory (MEMORY.md) +├── cron/ # Scheduled jobs +├── skills/ # Custom skills +├── AGENT.md # Agent behavior guide +├── IDENTITY.md # Agent identity +└── HEARTBEAT.md # Periodic task prompts +``` + +## Key Design Patterns + +### 1. Interface-Based Design + +Core components are defined as interfaces, making it easy to: +- Add new LLM providers +- Create custom tools +- Implement new channels + +### 2. Dependency Injection + +Components receive dependencies through constructors: +```go +func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, + provider providers.LLMProvider) *AgentLoop +``` + +### 3. Context Propagation + +All long-running operations accept `context.Context` for: +- Cancellation signals +- Timeout handling +- Request-scoped values + +### 4. Error Wrapping + +Errors are wrapped with context: +```go +return fmt.Errorf("failed to process message: %w", err) +``` + +### 5. Structured Logging + +Logging uses structured fields: +```go +logger.InfoCF("agent", "Processing message", + map[string]interface{}{ + "channel": msg.Channel, + "chat_id": msg.ChatID, + }) +``` diff --git a/docs/developer-guide/building.md b/docs/developer-guide/building.md new file mode 100644 index 0000000000..d75dd05364 --- /dev/null +++ b/docs/developer-guide/building.md @@ -0,0 +1,266 @@ +# Building from Source + +This guide explains how to build PicoClaw from source code. + +## Prerequisites + +### Go + +PicoClaw requires Go 1.21 or later. Check your Go version: + +```bash +go version +``` + +If Go is not installed, download it from [golang.org](https://golang.org/dl/). + +### Make + +PicoClaw uses a Makefile for build automation. Ensure `make` is installed: + +```bash +make --version +``` + +### Git + +For cloning the repository: + +```bash +git --version +``` + +## Getting the Source Code + +Clone the repository: + +```bash +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw +``` + +## Dependencies + +Download dependencies: + +```bash +make deps +``` + +This runs `go mod download` to fetch all required modules. + +## Building + +### Build for Current Platform + +Build for your current operating system and architecture: + +```bash +make build +``` + +This will: +1. Run `go generate` to generate any required code +2. Build the binary to `build/picoclaw` + +The output binary will be at `build/picoclaw` (or `build/picoclaw.exe` on Windows). + +### Build for All Platforms + +Build for all supported platforms: + +```bash +make build-all +``` + +This creates binaries for: +- `linux-amd64` +- `linux-arm64` +- `linux-loong64` +- `linux-riscv64` +- `darwin-arm64` (macOS Apple Silicon) +- `windows-amd64` + +Binaries are placed in the `build/` directory with platform-specific naming. + +### Manual Build + +You can also build manually with Go commands: + +```bash +# Generate code (if needed) +go generate ./... + +# Build for current platform +go build -o build/picoclaw ./cmd/picoclaw + +# Build with optimizations +go build -ldflags="-s -w" -o build/picoclaw ./cmd/picoclaw +``` + +### Cross-Compilation + +Build for a specific platform: + +```bash +# Linux AMD64 +GOOS=linux GOARCH=amd64 go build -o build/picoclaw-linux-amd64 ./cmd/picoclaw + +# Linux ARM64 (Raspberry Pi, etc.) +GOOS=linux GOARCH=arm64 go build -o build/picoclaw-linux-arm64 ./cmd/picoclaw + +# macOS ARM64 (Apple Silicon) +GOOS=darwin GOARCH=arm64 go build -o build/picoclaw-darwin-arm64 ./cmd/picoclaw + +# Windows AMD64 +GOOS=windows GOARCH=amd64 go build -o build/picoclaw-windows-amd64.exe ./cmd/picoclaw +``` + +## Installation + +### Install to Default Location + +Install to `~/.local/bin`: + +```bash +make install +``` + +Ensure `~/.local/bin` is in your PATH: + +```bash +export PATH="$HOME/.local/bin:$PATH" +``` + +Add to your shell profile for persistence: + +```bash +echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc +# or +echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc +``` + +### Custom Installation + +Install to a custom location: + +```bash +go build -o /usr/local/bin/picoclaw ./cmd/picoclaw +``` + +## Verification + +Verify the build: + +```bash +./build/picoclaw --version +``` + +Run a quick test: + +```bash +# Interactive mode +./build/picoclaw agent + +# Single message +./build/picoclaw agent -m "Hello, PicoClaw!" +``` + +## Development Build + +For development, you may want to build with debug symbols: + +```bash +go build -gcflags="all=-N -l" -o build/picoclaw-debug ./cmd/picoclaw +``` + +## Build Options + +### Makefile Targets + +| Target | Description | +|--------|-------------| +| `deps` | Download dependencies | +| `build` | Build for current platform | +| `build-all` | Build for all platforms | +| `install` | Install to ~/.local/bin | +| `test` | Run tests | +| `vet` | Run linter | +| `fmt` | Format code | +| `check` | Run all checks (deps, fmt, vet, test) | +| `clean` | Remove build artifacts | + +### Environment Variables + +| Variable | Description | +|----------|-------------| +| `GOOS` | Target operating system | +| `GOARCH` | Target architecture | +| `CGO_ENABLED` | Enable CGO (default: 0) | + +## Troubleshooting + +### "go: command not found" + +Install Go from [golang.org](https://golang.org/dl/). + +### "go: cannot find main module" + +Ensure you're in the project root directory: + +```bash +cd picoclaw +``` + +### Build Errors + +1. Clean and rebuild: + +```bash +go clean -cache +make build +``` + +2. Update dependencies: + +```bash +go mod tidy +make deps +``` + +3. Check Go version: + +```bash +go version # Should be 1.21+ +``` + +### Hardware Tool Build Errors + +I2C and SPI tools require Linux-specific system calls. On non-Linux platforms, these tools return errors at runtime but the build should succeed. + +If you see build errors related to these tools: + +```bash +# The build should still work - these are stub implementations +make build +``` + +## Docker Build (Optional) + +Build with Docker: + +```bash +# Build image +docker build -t picoclaw . + +# Run container +docker run -it picoclaw agent -m "Hello" +``` + +## Next Steps + +After building: + +1. [Configure PicoClaw](../getting-started/configuration-basics.md) +2. [Run your first chat](../getting-started/first-chat.md) +3. [Set up channels](../user-guide/channels/README.md) diff --git a/docs/developer-guide/code-style.md b/docs/developer-guide/code-style.md new file mode 100644 index 0000000000..c78a110560 --- /dev/null +++ b/docs/developer-guide/code-style.md @@ -0,0 +1,492 @@ +# Code Style Guide + +This document describes the code style conventions used in PicoClaw. + +## Overview + +PicoClaw follows standard Go conventions with some project-specific guidelines. When in doubt, refer to: + +- [Effective Go](https://golang.org/doc/effective_go) +- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) + +## Formatting + +### Automatic Formatting + +Use `gofmt` or `go fmt`: + +```bash +# Format all code +make fmt + +# Or manually +go fmt ./pkg/... +``` + +### General Rules + +- Use tabs for indentation (Go standard) +- No trailing whitespace +- Files end with a newline + +## Naming Conventions + +### Packages + +- Short, lowercase names +- No underscores or mixedCaps +- Single word preferred + +```go +// Good +package agent +package tools +package bus + +// Bad +package agentLoop +package tool_registry +``` + +### Types + +- Exported types: PascalCase +- Private types: camelCase +- Interface names: typically end with "er" for single-method interfaces + +```go +// Good +type Tool interface { ... } +type LLMProvider interface { ... } +type toolRegistry struct { ... } + +// Bad +type tool_interface interface { ... } +type ToolRegistry struct { ... } // if private +``` + +### Functions and Methods + +- Exported: PascalCase +- Private: camelCase +- Constructors: `NewTypeName()` + +```go +// Good +func NewToolRegistry() *ToolRegistry +func (r *ToolRegistry) Register(tool Tool) +func (r *toolRegistry) getTool(name string) Tool + +// Bad +func new_ToolRegistry() *ToolRegistry +func (r *ToolRegistry) register_tool(tool Tool) +``` + +### Variables + +- Short names for short scope +- Descriptive names for longer scope +- camelCase for local variables + +```go +// Good - short scope +for i, msg := range messages { + fmt.Println(i, msg) +} + +// Good - longer scope +sessionManager := session.NewManager(storage) + +// Bad +messageIndex := 0 // too long for short scope +``` + +### Constants + +- camelCase or PascalCase depending on export + +```go +const ( + maxIterations = 10 + DefaultModel = "gpt-4" +) +``` + +## Error Handling + +### Error Wrapping + +Use `fmt.Errorf` with `%w` for wrapping: + +```go +// Good +if err != nil { + return fmt.Errorf("failed to process message: %w", err) +} + +// Bad +if err != nil { + return fmt.Errorf("failed to process message: %v", err) +} +``` + +### Error Returns + +Return errors, don't panic: + +```go +// Good +func (t *Tool) Execute(ctx context.Context, args map[string]interface{}) (*ToolResult, error) { + if err := validate(args); err != nil { + return nil, fmt.Errorf("validation failed: %w", err) + } + // ... +} + +// Bad +func (t *Tool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + if err := validate(args); err != nil { + panic(err) // Don't panic in library code + } + // ... +} +``` + +### Custom Errors + +Define custom error types when appropriate: + +```go +type FailoverError struct { + Reason FailoverReason + Provider string + Model string + Status int + Wrapped error +} + +func (e *FailoverError) Error() string { + return fmt.Sprintf("failover(%s): provider=%s model=%s status=%d: %v", + e.Reason, e.Provider, e.Model, e.Status, e.Wrapped) +} + +func (e *FailoverError) Unwrap() error { + return e.Wrapped +} +``` + +## Logging + +### Structured Logging + +Use the project's logger package: + +```go +// Good +logger.InfoCF("agent", "Processing message", + map[string]interface{}{ + "channel": msg.Channel, + "chat_id": msg.ChatID, + "sender": msg.SenderID, + }) + +logger.ErrorCF("tool", "Tool execution failed", + map[string]interface{}{ + "tool": name, + "error": err.Error(), + }) + +// Bad +log.Printf("Processing message from %s", msg.Channel) +``` + +### Log Levels + +- `DebugCF`: Detailed information for debugging +- `InfoCF`: General operational information +- `WarnCF`: Warning conditions +- `ErrorCF`: Error conditions + +### Component Names + +Use consistent component names: + +- `"agent"` - Agent loop operations +- `"tool"` - Tool execution +- `"channel"` - Channel operations +- `"provider"` - LLM provider operations +- `"session"` - Session management + +## Comments + +### Package Comments + +Document packages with a package comment: + +```go +// Package agent provides the core agent loop for processing messages. +// It handles message routing, LLM interaction, and tool execution. +package agent +``` + +### Function Comments + +Document exported functions: + +```go +// Execute processes the tool call with the given arguments. +// It returns a ToolResult containing the output for both the LLM and user. +// +// The args map must contain the parameters defined by Parameters(). +// If a required parameter is missing, an error result is returned. +func (t *MessageTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { +``` + +### Inline Comments + +Use sparingly and only when necessary: + +```go +// Check for async tools and inject callback if needed +if asyncTool, ok := tool.(AsyncTool); ok && asyncCallback != nil { + asyncTool.SetCallback(asyncCallback) +} +``` + +### TODO Comments + +```go +// TODO(username): Add support for streaming responses +// TODO: Consider caching provider responses +``` + +## Code Organization + +### File Organization + +Order within a file: + +1. Package declaration +2. Imports +3. Constants +4. Variables +5. Types +6. Functions (exported first, then private) + +### Import Organization + +Group imports: + +```go +import ( + // Standard library + "context" + "fmt" + + // External packages + "github.com/something/external" + + // Internal packages + "github.com/sipeed/picoclaw/pkg/tools" +) +``` + +### Function Length + +Keep functions focused and reasonably sized: + +- Single responsibility +- Break up long functions +- Extract helper functions when needed + +## Interfaces + +### Define Interfaces Where Used + +Define interfaces in the package that uses them: + +```go +// In pkg/agent/loop.go +type LLMProvider interface { + Chat(ctx context.Context, messages []providers.Message, ...) (*LLMResponse, error) +} +``` + +### Small Interfaces + +Prefer small, focused interfaces: + +```go +// Good +type Tool interface { + Name() string + Description() string + Parameters() map[string]interface{} + Execute(ctx context.Context, args map[string]interface{}) *ToolResult +} + +type ContextualTool interface { + Tool + SetContext(channel, chatID string) +} + +// Bad - too large +type MegaInterface interface { + Name() string + Description() string + Parameters() map[string]interface{} + Execute(ctx context.Context, args map[string]interface{}) *ToolResult + SetContext(channel, chatID string) + SetCallback(cb AsyncCallback) + Start() error + Stop() error +} +``` + +## Testing + +### Test File Naming + +- Test files: `*_test.go` +- Integration tests: `*_integration_test.go` + +### Test Function Naming + +```go +func TestFunctionName(t *testing.T) {} +func TestFunctionName_Scenario(t *testing.T) {} +func TestType_Method(t *testing.T) {} +``` + +### Table-Driven Tests + +```go +func TestValidateInput(t *testing.T) { + tests := []struct { + name string + input string + wantErr bool + }{ + {"valid", "hello", false}, + {"empty", "", true}, + {"whitespace", " ", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateInput(tt.input) + if (err != nil) != tt.wantErr { + t.Errorf("validateInput() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} +``` + +## Concurrency + +### Context for Cancellation + +Always accept context: + +```go +func (p *Provider) Chat(ctx context.Context, messages []Message, ...) (*Response, error) { + req, _ := http.NewRequestWithContext(ctx, "POST", url, body) + // ... +} +``` + +### Goroutine Safety + +Document thread-safety: + +```go +// ToolRegistry is safe for concurrent use. +type ToolRegistry struct { + tools map[string]Tool + mu sync.RWMutex +} +``` + +### Wait for Goroutines + +```go +var wg sync.WaitGroup +for _, item := range items { + wg.Add(1) + go func(i Item) { + defer wg.Done() + process(i) +} +wg.Wait() +``` + +## JSON Configuration + +### Field Tags + +Use snake_case for JSON field names: + +```go +type Config struct { + APIKey string `json:"api_key"` + MaxRetries int `json:"max_retries"` + ModelName string `json:"model_name"` +} +``` + +## Avoid These Patterns + +### Global Variables + +Avoid global state; use dependency injection: + +```go +// Bad +var globalConfig *Config + +func Process() { + apiKey := globalConfig.APIKey +} + +// Good +type Processor struct { + config *Config +} + +func NewProcessor(config *Config) *Processor { + return &Processor{config: config} +} + +func (p *Processor) Process() { + apiKey := p.config.APIKey +} +``` + +### Interface Pollution + +Don't define interfaces prematurely: + +```go +// Bad - interface for single implementation +type StringProcessor interface { + Process(s string) string +} + +type UpperCaseProcessor struct{} + +// Good - define interface when you have multiple implementations +// or when mocking for tests +``` + +## Summary + +1. Run `make fmt` before committing +2. Follow standard Go conventions +3. Use structured logging +4. Wrap errors with context +5. Write tests for new code +6. Document exported functions +7. Keep interfaces small + +For questions about style not covered here, refer to [Effective Go](https://golang.org/doc/effective_go). diff --git a/docs/developer-guide/contributing.md b/docs/developer-guide/contributing.md new file mode 100644 index 0000000000..41000dcb10 --- /dev/null +++ b/docs/developer-guide/contributing.md @@ -0,0 +1,361 @@ +# Contribution Guidelines + +Thank you for your interest in contributing to PicoClaw! This document provides guidelines and instructions for contributing. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [Getting Started](#getting-started) +- [Development Workflow](#development-workflow) +- [Pull Request Process](#pull-request-process) +- [Coding Standards](#coding-standards) +- [Commit Guidelines](#commit-guidelines) +- [Reporting Issues](#reporting-issues) +- [Feature Requests](#feature-requests) + +## Code of Conduct + +Be respectful and inclusive. We welcome contributions from everyone. Please be constructive in discussions and reviews. + +## Getting Started + +### 1. Fork and Clone + +```bash +# Fork the repository on GitHub, then clone your fork +git clone https://github.com/YOUR_USERNAME/picoclaw.git +cd picoclaw + +# Add upstream remote +git remote add upstream https://github.com/sipeed/picoclaw.git +``` + +### 2. Set Up Development Environment + +```bash +# Install dependencies +make deps + +# Build +make build + +# Run tests +make test +``` + +### 3. Create a Branch + +```bash +# Update main branch +git checkout main +git pull upstream main + +# Create feature branch +git checkout -b feature/my-feature +``` + +## Development Workflow + +### Make Changes + +1. Make your changes in your feature branch +2. Add or update tests as needed +3. Update documentation if applicable + +### Run Checks + +Before submitting, run all checks: + +```bash +make check +``` + +This runs: +- `make deps` - Download dependencies +- `make fmt` - Format code +- `make vet` - Run linter +- `make test` - Run tests + +### Run Specific Tests + +```bash +# Test a specific package +go test ./pkg/tools/... -v + +# Run a specific test +go test ./pkg/tools/... -v -run TestMessageTool +``` + +## Pull Request Process + +### 1. Push Changes + +```bash +git push origin feature/my-feature +``` + +### 2. Create Pull Request + +1. Go to your fork on GitHub +2. Click "Pull Request" +3. Select your feature branch +4. Fill in the PR template + +### 3. PR Requirements + +- [ ] All tests pass +- [ ] Code is formatted (`make fmt`) +- [ ] Linter passes (`make vet`) +- [ ] Documentation updated (if applicable) +- [ ] PR description explains the change +- [ ] Commits follow [commit guidelines](#commit-guidelines) + +### 4. Code Review + +- Respond to review feedback promptly +- Make requested changes in new commits +- Mark conversations as resolved + +### 5. Merge + +PRs are merged by maintainers after approval. + +## Coding Standards + +### Go Style + +Follow standard Go conventions: + +```bash +# Format code +make fmt + +# Or manually +go fmt ./pkg/... +``` + +### Error Handling + +Wrap errors with context: + +```go +// Good +if err != nil { + return fmt.Errorf("failed to process message: %w", err) +} + +// Bad +if err != nil { + return err +} +``` + +### Logging + +Use structured logging: + +```go +// Good +logger.InfoCF("agent", "Processing message", + map[string]interface{}{ + "channel": msg.Channel, + "chat_id": msg.ChatID, + }) + +// Bad +log.Printf("Processing message from %s", msg.Channel) +``` + +### Comments + +- Write self-documenting code +- Add comments for exported functions +- Document complex logic + +```go +// Execute processes the tool call with the given arguments. +// It returns a ToolResult containing the output for both the LLM and user. +func (t *MessageTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + // Implementation... +} +``` + +### Interfaces + +Use interfaces for extensibility: + +```go +// Good - interface for extension +type Tool interface { + Name() string + Description() string + Parameters() map[string]interface{} + Execute(ctx context.Context, args map[string]interface{}) *ToolResult +} + +// Bad - concrete type only +type MessageTool struct { ... } +``` + +### Context + +Always accept context for long-running operations: + +```go +// Good +func (p *Provider) Chat(ctx context.Context, ...) (*Response, error) + +// Bad +func (p *Provider) Chat(...) (*Response, error) +``` + +## Commit Guidelines + +### Commit Message Format + +``` +: + +[optional body] + +[optional footer] +``` + +### Types + +- `feat`: New feature +- `fix`: Bug fix +- `docs`: Documentation only +- `style`: Formatting, no code change +- `refactor`: Code restructuring +- `test`: Adding/updating tests +- `chore`: Maintenance tasks + +### Examples + +``` +feat: add support for Slack channel + +Add Slack channel integration using the Slack API. +Supports both public channels and direct messages. + +Closes #123 +``` + +``` +fix: handle empty message content in agent loop + +The agent loop was crashing when receiving empty messages. +Added validation to skip processing empty content. +``` + +``` +docs: update installation instructions for Windows +``` + +### Keep Commits Atomic + +- One logical change per commit +- Each commit should be able to stand alone +- Don't mix unrelated changes + +## Reporting Issues + +### Bug Reports + +Include: + +1. **Description**: Clear description of the bug +2. **Steps to Reproduce**: How to trigger the bug +3. **Expected Behavior**: What you expected to happen +4. **Actual Behavior**: What actually happened +5. **Environment**: + - OS and version + - Go version + - PicoClaw version +6. **Logs**: Relevant log output (use `--debug`) + +### Issue Template + +~~~markdown +## Description +[Describe the bug] + +## Steps to Reproduce +1. [First step] +2. [Second step] +3. [Third step] + +## Expected Behavior +[What should happen] + +## Actual Behavior +[What actually happens] + +## Environment +- OS: [e.g., macOS 14.0] +- Go version: [e.g., 1.21] +- PicoClaw version: [e.g., v0.1.0] + +## Logs +``` +[paste relevant logs] +``` +~~~ + +## Feature Requests + +Include: + +1. **Problem**: What problem does this solve? +2. **Solution**: Describe your proposed solution +3. **Alternatives**: Other solutions you considered +4. **Use Case**: How would this be used? + +## Project Structure + +When adding new features, place them in appropriate directories: + +``` +pkg/ +├── agent/ # Core agent logic +├── bus/ # Message bus +├── channels/ # Platform integrations +│ └── slack.go # Add new channels here +├── providers/ # LLM providers +│ └── myprovider/ +│ └── provider.go # Add new providers here +├── tools/ # Tool implementations +│ └── mytool.go # Add new tools here +└── skills/ # Skill loading +``` + +## Documentation + +Update documentation for: + +- New features +- Changed behavior +- New configuration options +- New CLI commands + +Documentation is in `docs/`: + +``` +docs/ +├── getting-started/ # Installation, quick start +├── user-guide/ # Feature documentation +└── developer-guide/ # This documentation +``` + +## Questions? + +- Open an issue for questions +- Check existing issues first +- Be specific and provide context + +## License + +By contributing, you agree that your contributions will be licensed under the MIT License. + +Thank you for contributing to PicoClaw! diff --git a/docs/developer-guide/data-flow.md b/docs/developer-guide/data-flow.md new file mode 100644 index 0000000000..32e4f0bb97 --- /dev/null +++ b/docs/developer-guide/data-flow.md @@ -0,0 +1,383 @@ +# Data Flow and Message Bus + +This document explains how messages flow through PicoClaw's message bus architecture. + +## Message Bus Overview + +The message bus is the central communication hub in PicoClaw. It decouples channels (which receive external messages) from the agent loop (which processes them). + +### Message Types + +```go +// InboundMessage represents a message from an external platform +type InboundMessage struct { + Channel string // Platform identifier (e.g., "telegram", "discord") + SenderID string // User identifier on the platform + ChatID string // Chat/conversation identifier + Content string // Message text content + Media []string // Optional media URLs or file paths + SessionKey string // Optional pre-computed session key + Metadata map[string]string // Additional platform-specific metadata +} + +// OutboundMessage represents a response to be sent +type OutboundMessage struct { + Channel string // Target channel + ChatID string // Target chat/conversation + Content string // Response content +} +``` + +## Message Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ External Platform │ +│ (e.g., Telegram) │ +└─────────────────────────────────────┬───────────────────────────────────┘ + │ User sends message + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ Telegram Channel │ +│ │ +│ 1. Receive update from Telegram API │ +│ 2. Extract sender, chat, content │ +│ 3. Call HandleMessage() │ +└─────────────────────────────────────┬───────────────────────────────────┘ + │ bus.PublishInbound(msg) + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ Message Bus │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Inbound Channel (buffer: 100) │ │ +│ │ │ │ +│ │ InboundMessage{Channel:"telegram", ChatID:"123", ...} │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────┬───────────────────────────────────┘ + │ bus.ConsumeInbound(ctx) + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ Agent Loop │ +│ │ +│ ┌────────────────────────────────────────────────────────────────┐ │ +│ │ 1. Consume from inbound bus │ │ +│ │ 2. Route to appropriate agent │ │ +│ │ 3. Build context (history, system prompt, skills) │ │ +│ │ 4. Call LLM provider │ │ +│ │ 5. Handle tool calls (if any) │ │ +│ │ 6. Save to session │ │ +│ │ 7. Publish response to outbound bus │ │ +│ └────────────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────┬───────────────────────────────────┘ + │ bus.PublishOutbound(msg) + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ Message Bus │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Outbound Channel (buffer: 100) │ │ +│ │ │ │ +│ │ OutboundMessage{Channel:"telegram", ChatID:"123", ...} │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────┬───────────────────────────────────┘ + │ bus.SubscribeOutbound(ctx) + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ Telegram Channel │ +│ │ +│ 1. Receive outbound message │ +│ 2. Send via Telegram API │ +└─────────────────────────────────────┬───────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ External Platform │ +│ (e.g., Telegram) │ +│ │ +│ User receives response │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +## Detailed Flow + +### 1. Inbound Message Processing + +When a message arrives from an external platform: + +```go +// In the channel implementation (e.g., telegram.go) +func (c *TelegramChannel) handleUpdate(update tgbotapi.Update) { + // Extract message details + senderID := strconv.FormatInt(update.Message.From.ID, 10) + chatID := strconv.FormatInt(update.Message.Chat.ID, 10) + content := update.Message.Text + + // Publish to message bus + c.HandleMessage(senderID, chatID, content, nil, nil) +} + +// In BaseChannel +func (c *BaseChannel) HandleMessage(senderID, chatID, content string, + media []string, metadata map[string]string) { + if !c.IsAllowed(senderID) { + return // Skip unauthorized users + } + + msg := bus.InboundMessage{ + Channel: c.name, + SenderID: senderID, + ChatID: chatID, + Content: content, + Media: media, + Metadata: metadata, + } + + c.bus.PublishInbound(msg) +} +``` + +### 2. Agent Loop Processing + +The agent loop continuously processes messages: + +```go +func (al *AgentLoop) Run(ctx context.Context) error { + al.running.Store(true) + + for al.running.Load() { + select { + case <-ctx.Done(): + return nil + default: + // Consume message from bus + msg, ok := al.bus.ConsumeInbound(ctx) + if !ok { + continue + } + + // Process the message + response, err := al.processMessage(ctx, msg) + if err != nil { + response = fmt.Sprintf("Error: %v", err) + } + + // Publish response + if response != "" { + al.bus.PublishOutbound(bus.OutboundMessage{ + Channel: msg.Channel, + ChatID: msg.ChatID, + Content: response, + }) + } + } + } + return nil +} +``` + +### 3. Message Routing + +Messages are routed to appropriate agents: + +```go +func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage) (string, error) { + // Route to determine agent and session key + route := al.registry.ResolveRoute(routing.RouteInput{ + Channel: msg.Channel, + AccountID: msg.Metadata["account_id"], + Peer: extractPeer(msg), + ParentPeer: extractParentPeer(msg), + GuildID: msg.Metadata["guild_id"], + TeamID: msg.Metadata["team_id"], + }) + + agent, ok := al.registry.GetAgent(route.AgentID) + if !ok { + agent = al.registry.GetDefaultAgent() + } + + return al.runAgentLoop(ctx, agent, processOptions{ + SessionKey: route.SessionKey, + Channel: msg.Channel, + ChatID: msg.ChatID, + UserMessage: msg.Content, + }) +} +``` + +### 4. Context Building + +The context builder assembles the LLM prompt: + +```go +messages := agent.ContextBuilder.BuildMessages( + history, // Previous messages from session + summary, // Summary of older messages (if any) + userMessage, // Current user message + nil, // Additional context + channel, // Current channel + chatID, // Current chat ID +) +``` + +The built messages include: +1. System prompt (from AGENT.md, IDENTITY.md, etc.) +2. Available tools list +3. Available skills +4. Session summary (if exists) +5. Conversation history +6. Current user message + +### 5. LLM Call with Fallback + +```go +// With fallback chain +if len(agent.Candidates) > 1 && al.fallback != nil { + fbResult, err := al.fallback.Execute(ctx, agent.Candidates, + func(ctx context.Context, provider, model string) (*LLMResponse, error) { + return agent.Provider.Chat(ctx, messages, tools, model, options) + }, + ) + // Handle result... +} +``` + +### 6. Tool Execution + +When the LLM returns tool calls: + +```go +for _, tc := range response.ToolCalls { + // Execute the tool with context + toolResult := agent.Tools.ExecuteWithContext( + ctx, + tc.Name, + tc.Arguments, + channel, + chatID, + asyncCallback, // For async tools + ) + + // Send ForUser content immediately if not silent + if !toolResult.Silent && toolResult.ForUser != "" { + al.bus.PublishOutbound(bus.OutboundMessage{ + Channel: channel, + ChatID: chatID, + Content: toolResult.ForUser, + }) + } + + // Add tool result to messages for next LLM call + messages = append(messages, providers.Message{ + Role: "tool", + Content: toolResult.ForLLM, + ToolCallID: tc.ID, + }) +} +``` + +### 7. Outbound Message Handling + +Channels subscribe to outbound messages: + +```go +// In gateway main loop +for { + select { + case <-ctx.Done(): + return + case msg, ok := msgBus.SubscribeOutbound(ctx): + if !ok { + continue + } + + // Get the appropriate channel + channel, exists := channelManager.GetChannel(msg.Channel) + if !exists { + continue + } + + // Send via channel + channel.Send(ctx, msg) + } +} +``` + +## Session Key Management + +Session keys uniquely identify conversations: + +``` +Format: "channel:chatID" or "agent:agentID:channel:chatID" + +Examples: +- "telegram:123456789" # Telegram private chat +- "telegram:-1001234567890" # Telegram group +- "discord:123456789012345678" # Discord channel +- "agent:main:telegram:123456" # Agent-specific session +``` + +## Async Tool Flow + +Some tools (like spawn) operate asynchronously: + +``` +1. Tool receives Execute() call +2. Tool returns AsyncResult immediately +3. Tool starts work in goroutine +4. When complete, tool calls AsyncCallback +5. Callback publishes result via PublishInbound +6. AgentLoop processes result in next iteration +``` + +## Error Handling + +Errors are handled at multiple levels: + +1. **Channel level**: Connection errors, API errors +2. **Bus level**: Full buffer, closed channel +3. **Agent level**: LLM errors, tool errors +4. **Session level**: Save/load errors + +Error responses are sent to users when appropriate: + +```go +if err != nil { + response = fmt.Sprintf("Error processing message: %v", err) +} +``` + +## Graceful Shutdown + +The message bus supports graceful shutdown: + +```go +// Stop accepting new messages +mb.Close() + +// AgentLoop checks running flag +for al.running.Load() { + // ... +} + +// Context cancellation for in-flight operations +ctx, cancel := context.WithCancel(context.Background()) +// ... on shutdown ... +cancel() +``` + +## Performance Characteristics + +- **Buffer capacity**: 100 messages per channel +- **Concurrency**: Multiple channels can publish simultaneously +- **Thread safety**: All operations are thread-safe via mutex +- **Memory**: Messages are held in memory until processed + +## Best Practices + +1. **Always check context cancellation** in long-running operations +2. **Use timeouts** for external API calls +3. **Handle full buffers** gracefully +4. **Log message processing** for debugging +5. **Don't block** the message bus with slow operations diff --git a/docs/developer-guide/extending/README.md b/docs/developer-guide/extending/README.md new file mode 100644 index 0000000000..7740b12779 --- /dev/null +++ b/docs/developer-guide/extending/README.md @@ -0,0 +1,152 @@ +# Extending PicoClaw + +This directory contains guides for extending PicoClaw with custom functionality. + +## Overview + +PicoClaw is designed to be extensible. The main extension points are: + +1. **Tools** - Add new capabilities for the agent to use +2. **LLM Providers** - Add support for new LLM APIs +3. **Channels** - Add integrations with new chat platforms +4. **Skills** - Create reusable prompt templates + +## Extension Points + +### [Creating Custom Tools](creating-tools.md) + +Tools are the primary way agents interact with the world. Create custom tools to: + +- Integrate with external APIs +- Add domain-specific functionality +- Interact with local systems + +Example use cases: +- Database queries +- File format conversion +- API integrations +- Custom calculations + +### [Creating LLM Providers](creating-providers.md) + +Providers handle communication with LLM APIs. Create new providers to: + +- Support new LLM services +- Implement custom authentication +- Add specialized request/response handling + +Example use cases: +- New AI service integrations +- Local LLM support +- Custom API gateways + +### [Creating Channel Integrations](creating-channels.md) + +Channels connect PicoClaw to chat platforms. Create new channels to: + +- Support new messaging platforms +- Add custom communication protocols +- Integrate with internal systems + +Example use cases: +- Team chat platforms +- Custom bots +- Internal communication systems + +### [Creating Skills](creating-skills.md) + +Skills are reusable prompt templates. Create skills to: + +- Package domain expertise +- Create reusable workflows +- Share capabilities across agents + +Example use cases: +- Code review assistance +- Document analysis +- Domain-specific knowledge + +## Architecture for Extensions + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Agent Loop │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ Tools │ │ Provider │ │ Channels │ │ +│ │ Registry │ │ Factory │ │ Manager │ │ +│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ Custom Tool │ │ Custom │ │ Custom │ │ +│ │ (Yours) │ │ Provider │ │ Channel │ │ +│ └──────────────┘ └──────────────┘ └──────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Getting Started + +Choose an extension type based on what you want to accomplish: + +| Goal | Extension Type | Guide | +|------|---------------|-------| +| Add new capabilities | Tool | [Creating Tools](creating-tools.md) | +| Use new LLM service | Provider | [Creating Providers](creating-providers.md) | +| Connect new platform | Channel | [Creating Channels](creating-channels.md) | +| Share prompts | Skill | [Creating Skills](creating-skills.md) | + +## Quick Reference + +### Tool Interface + +```go +type Tool interface { + Name() string + Description() string + Parameters() map[string]interface{} + Execute(ctx context.Context, args map[string]interface{}) *ToolResult +} +``` + +### Provider Interface + +```go +type LLMProvider interface { + Chat(ctx context.Context, messages []Message, tools []ToolDefinition, + model string, options map[string]interface{}) (*LLMResponse, error) + GetDefaultModel() string +} +``` + +### Channel Interface + +```go +type Channel interface { + Name() string + Start(ctx context.Context) error + Stop(ctx context.Context) error + Send(ctx context.Context, msg bus.OutboundMessage) error + IsRunning() bool + IsAllowed(senderID string) bool +} +``` + +## Development Workflow + +1. **Plan** - Define what you want to build +2. **Implement** - Create the extension following the guide +3. **Test** - Write tests for your extension +4. **Integrate** - Register your extension with PicoClaw +5. **Document** - Add documentation for users + +## Contributing Extensions + +If you create a useful extension, consider contributing it back: + +1. Fork the repository +2. Add your extension +3. Add tests +4. Submit a pull request + +See [Contributing Guidelines](../contributing.md) for details. diff --git a/docs/developer-guide/extending/antigravity-implementation.md b/docs/developer-guide/extending/antigravity-implementation.md new file mode 100644 index 0000000000..c7cbea2bef --- /dev/null +++ b/docs/developer-guide/extending/antigravity-implementation.md @@ -0,0 +1,415 @@ +# Antigravity Provider Implementation + +This document provides technical details on the Antigravity (Google Cloud Code Assist) provider implementation in PicoClaw. It covers OAuth authentication, API integration, and how to extend the provider. + +## Overview + +**Antigravity** (Google Cloud Code Assist) is a Google-backed AI model provider that offers access to models like Claude Opus 4.6 and Gemini through Google's Cloud infrastructure. + +--- + +## Authentication Flow + +### OAuth 2.0 with PKCE + +Antigravity uses **OAuth 2.0 with PKCE (Proof Key for Code Exchange)** for secure authentication: + +``` +┌─────────────┐ ┌─────────────────┐ +│ Client │ ───(1) Generate PKCE Pair────────> │ │ +│ │ ───(2) Open Auth URL─────────────> │ Google OAuth │ +│ │ │ Server │ +│ │ <──(3) Redirect with Code───────── │ │ +│ │ └─────────────────┘ +│ │ ───(4) Exchange Code for Tokens──> │ Token URL │ +│ │ │ │ +│ │ <──(5) Access + Refresh Tokens──── │ │ +└─────────────┘ └─────────────────┘ +``` + +### PKCE Parameters + +```go +func generatePkce() (verifier string, challenge string) { + verifier = randomHex(32) + challenge = sha256Base64URL(verifier) + return +} +``` + +### Authorization URL + +```go +const ( + authURL = "https://accounts.google.com/o/oauth2/v2/auth" + redirectURI = "http://localhost:51121/oauth-callback" +) + +func buildAuthURL(challenge, state string) string { + params := url.Values{} + params.Set("client_id", clientID) + params.Set("response_type", "code") + params.Set("redirect_uri", redirectURI) + params.Set("scope", strings.Join(scopes, " ")) + params.Set("code_challenge", challenge) + params.Set("code_challenge_method", "S256") + params.Set("state", state) + params.Set("access_type", "offline") + params.Set("prompt", "consent") + return authURL + "?" + params.Encode() +} +``` + +### Required OAuth Scopes + +```go +var scopes = []string{ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email", + "https://www.googleapis.com/auth/userinfo.profile", + "https://www.googleapis.com/auth/cclog", + "https://www.googleapis.com/auth/experimentsandconfigs", +} +``` + +### Token Exchange + +```go +const tokenURL = "https://oauth2.googleapis.com/token" + +func exchangeCode(code, verifier string) (*TokenResponse, error) { + data := url.Values{ + "client_id": {clientID}, + "client_secret": {clientSecret}, + "code": {code}, + "grant_type": {"authorization_code"}, + "redirect_uri": {redirectURI}, + "code_verifier": {verifier}, + } + + resp, err := http.PostForm(tokenURL, data) + // Parse response... +} +``` + +--- + +## Token Management + +### Credential Structure + +Credentials are stored in `~/.picoclaw/auth.json`: + +```go +type OAuthCredential struct { + Type string `json:"type"` // "oauth" + Provider string `json:"provider"` // "google-antigravity" + Access string `json:"access_token"` // Access token + Refresh string `json:"refresh_token"` // Refresh token + Expires time.Time `json:"expires_at"` // Expiration timestamp + Email string `json:"email,omitempty"` // User email + ProjectID string `json:"project_id,omitempty"` // Google Cloud project ID +} +``` + +### Automatic Token Refresh + +Access tokens expire and are automatically refreshed using the refresh token: + +```go +func (c *OAuthCredential) Refresh() error { + data := url.Values{ + "client_id": {clientID}, + "client_secret": {clientSecret}, + "refresh_token": {c.Refresh}, + "grant_type": {"refresh_token"}, + } + + resp, err := http.PostForm(tokenURL, data) + // Update access token and expiration... +} +``` + +--- + +## API Endpoints + +### Authentication Endpoints + +| Endpoint | Method | Purpose | +|----------|--------|---------| +| `https://accounts.google.com/o/oauth2/v2/auth` | GET | OAuth authorization | +| `https://oauth2.googleapis.com/token` | POST | Token exchange | +| `https://www.googleapis.com/oauth2/v1/userinfo` | GET | User info (email) | + +### Cloud Code Assist Endpoints + +| Endpoint | Method | Purpose | +|----------|--------|---------| +| `https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist` | POST | Load project info, credits, plan | +| `https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels` | POST | List available models with quotas | +| `https://cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse` | POST | Chat streaming endpoint | + +### Required Headers + +```go +var requiredHeaders = map[string]string{ + "Authorization": "Bearer " + accessToken, + "Content-Type": "application/json", + "User-Agent": "antigravity", + "X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1", +} +``` + +### Chat Request Format + +The `v1internal:streamGenerateContent` endpoint expects an envelope: + +```json +{ + "project": "your-project-id", + "model": "model-id", + "request": { + "contents": [...], + "systemInstruction": {...}, + "generationConfig": {...}, + "tools": [...] + }, + "requestType": "agent", + "userAgent": "antigravity", + "requestId": "agent-timestamp-random" +} +``` + +### SSE Response Format + +Each SSE message is wrapped in a `response` field: + +```json +{ + "response": { + "candidates": [...], + "usageMetadata": {...}, + "modelVersion": "...", + "responseId": "..." + }, + "traceId": "...", + "metadata": {} +} +``` + +--- + +## Model Management + +### Fetch Available Models + +```go +func fetchAvailableModels(accessToken, projectID string) ([]Model, error) { + req := map[string]string{"project": projectID} + + resp, err := post( + "https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels", + req, + headers(accessToken), + ) + + // Parse response with quota information + // ... +} +``` + +### Model Response Structure + +```go +type Model struct { + ID string + DisplayName string + QuotaInfo struct { + RemainingFraction float64 + ResetTime time.Time + IsExhausted bool + } +} +``` + +--- + +## Usage Tracking + +### Fetch Usage Data + +```go +func fetchUsage(accessToken string) (*UsageSnapshot, error) { + // 1. Load credits and plan info + loadResp, _ := post( + "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist", + map[string]interface{}{ + "metadata": map[string]string{ + "ideType": "ANTIGRAVITY", + "platform": "PLATFORM_UNSPECIFIED", + "pluginType": "GEMINI", + }, + }, + headers(accessToken), + ) + + // Extract: availablePromptCredits, planInfo, currentTier + + // 2. Fetch model quotas + modelsResp, _ := post( + "https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels", + map[string]string{"project": projectID}, + headers(accessToken), + ) + + // Build usage windows + // ... +} +``` + +### Usage Snapshot Structure + +```go +type UsageSnapshot struct { + Provider string `json:"provider"` // "google-antigravity" + DisplayName string `json:"displayName"` // "Google Antigravity" + Windows []UsageWindow `json:"windows"` // Quota windows + Plan string `json:"plan"` // Current plan +} + +type UsageWindow struct { + Label string `json:"label"` // "Credits" or model ID + UsedPercent int `json:"usedPercent"` // 0-100 + ResetAt int64 `json:"resetAt"` // Reset timestamp +} +``` + +--- + +## Schema Sanitization + +Antigravity uses Gemini-compatible models, so tool schemas must be sanitized: + +```go +var unsupportedKeywords = map[string]bool{ + "patternProperties": true, + "additionalProperties": true, + "$schema": true, + "$id": true, + "$ref": true, + "$defs": true, + "definitions": true, + "examples": true, + "minLength": true, + "maxLength": true, + "minimum": true, + "maximum": true, + "multipleOf": true, + "pattern": true, + "format": true, + "minItems": true, + "maxItems": true, + "uniqueItems": true, + "minProperties": true, + "maxProperties": true, +} + +func cleanSchemaForGemini(schema map[string]interface{}) map[string]interface{} { + // Remove unsupported keywords + // Ensure top-level has type: "object" + // Flatten anyOf/oneOf unions + // ... +} +``` + +--- + +## Thinking Block Handling + +For Antigravity Claude models, thinking blocks require special handling: + +```go +var signatureRegex = regexp.MustCompile(`^[A-Za-z0-9+/]+={0,2}$`) + +func sanitizeThinkingBlocks(messages []Message) []Message { + // Validate thinking signatures + // Normalize signature fields + // Discard unsigned thinking blocks + // ... +} +``` + +--- + +## Error Handling + +### Rate Limiting (HTTP 429) + +```json +{ + "error": { + "code": 429, + "message": "You have exhausted your capacity on this model. Your quota will reset after 4h30m28s.", + "status": "RESOURCE_EXHAUSTED", + "details": [ + { + "@type": "type.googleapis.com/google.rpc.ErrorInfo", + "metadata": { + "quotaResetDelay": "4h30m28.060903746s" + } + } + ] + } +} +``` + +### Empty Responses + +Some models return 200 OK with an empty SSE stream. This usually indicates the model is restricted or the project lacks permission. + +--- + +## Source Files + +| File | Purpose | +|------|---------| +| `pkg/providers/antigravity_provider.go` | Provider implementation | +| `pkg/auth/oauth.go` | OAuth flow implementation | +| `pkg/auth/store.go` | Credential storage | +| `pkg/providers/factory.go` | Provider factory | +| `pkg/providers/types.go` | Interface definitions | +| `cmd/picoclaw/cmd_auth.go` | Auth CLI commands | + +--- + +## Configuration + +### config.json + +```json +{ + "model_list": [ + { + "model_name": "gemini-flash", + "model": "antigravity/gemini-3-flash", + "auth_method": "oauth" + } + ], + "agents": { + "defaults": { + "model": "gemini-flash" + } + } +} +``` + +--- + +## Notes + +1. **Google Cloud Project**: Requires Gemini for Google Cloud enabled +2. **Quotas**: Uses Google Cloud project quotas (not separate billing) +3. **Model Access**: Available models depend on project configuration +4. **Thinking Blocks**: Claude models require special handling +5. **Schema Sanitization**: Tool schemas must be cleaned for Gemini compatibility diff --git a/docs/developer-guide/extending/creating-channels.md b/docs/developer-guide/extending/creating-channels.md new file mode 100644 index 0000000000..06e5084d84 --- /dev/null +++ b/docs/developer-guide/extending/creating-channels.md @@ -0,0 +1,569 @@ +# Creating Channel Integrations + +This guide explains how to create channel integrations for PicoClaw. + +## Overview + +Channels connect PicoClaw to external chat platforms like Telegram, Discord, Slack, etc. Each channel implements the `Channel` interface and is responsible for: + +1. Receiving messages from the platform +2. Publishing them to the message bus +3. Subscribing to outbound messages +4. Sending responses to the platform + +## Channel Interface + +All channels must implement this interface: + +```go +type Channel interface { + Name() string + Start(ctx context.Context) error + Stop(ctx context.Context) error + Send(ctx context.Context, msg bus.OutboundMessage) error + IsRunning() bool + IsAllowed(senderID string) bool +} +``` + +## Base Channel + +PicoClaw provides a `BaseChannel` struct that handles common functionality: + +```go +type BaseChannel struct { + config interface{} + bus *bus.MessageBus + running bool + name string + allowList []string +} + +// HandleMessage publishes a message to the bus +func (c *BaseChannel) HandleMessage(senderID, chatID, content string, + media []string, metadata map[string]string) + +// IsAllowed checks if sender is in the allowlist +func (c *BaseChannel) IsAllowed(senderID string) bool + +// Name returns the channel name +func (c *BaseChannel) Name() string + +// IsRunning returns the running state +func (c *BaseChannel) IsRunning() bool +``` + +## Creating a Basic Channel + +### Step 1: Define the Channel Struct + +```go +package channels + +import ( + "context" + "fmt" + "sync" + + "github.com/sipeed/picoclaw/pkg/bus" +) + +// MyChannelConfig holds channel configuration +type MyChannelConfig struct { + APIToken string `json:"api_token"` + AllowList []string `json:"allow_list"` +} + +// MyChannel implements the Channel interface +type MyChannel struct { + *BaseChannel // Embed base functionality + config *MyChannelConfig + client *MyAPIClient + mu sync.Mutex +} +``` + +### Step 2: Create Constructor + +```go +func NewMyChannel(cfg *MyChannelConfig, msgBus *bus.MessageBus) *MyChannel { + return &MyChannel{ + BaseChannel: NewBaseChannel("mychannel", cfg, msgBus, cfg.AllowList), + config: cfg, + client: NewMyAPIClient(cfg.APIToken), + } +} +``` + +### Step 3: Implement Start + +```go +func (c *MyChannel) Start(ctx context.Context) error { + c.mu.Lock() + defer c.mu.Unlock() + + if c.running { + return nil + } + + // Start receiving messages from the platform + go c.receiveLoop(ctx) + + c.setRunning(true) + return nil +} + +func (c *MyChannel) receiveLoop(ctx context.Context) { + // Subscribe to platform updates + updates, err := c.client.Subscribe(ctx) + if err != nil { + // Handle error + return + } + + for { + select { + case <-ctx.Done(): + return + case update, ok := <-updates: + if !ok { + return + } + c.handleUpdate(update) + } + } +} +``` + +### Step 4: Implement Stop + +```go +func (c *MyChannel) Stop(ctx context.Context) error { + c.mu.Lock() + defer c.mu.Unlock() + + if !c.running { + return nil + } + + // Close client connections + if err := c.client.Close(); err != nil { + return fmt.Errorf("failed to close client: %w", err) + } + + c.setRunning(false) + return nil +} +``` + +### Step 5: Implement Send + +```go +func (c *MyChannel) Send(ctx context.Context, msg bus.OutboundMessage) error { + if !c.running { + return fmt.Errorf("channel not running") + } + + // Send message through platform API + return c.client.SendMessage(ctx, msg.ChatID, msg.Content) +} +``` + +### Step 6: Handle Incoming Messages + +```go +func (c *MyChannel) handleUpdate(update MyUpdate) { + // Extract message details + senderID := update.Sender.ID + chatID := update.Chat.ID + content := update.Message.Text + + // Collect media if present + var media []string + if update.Message.Attachment != "" { + media = append(media, update.Message.Attachment) + } + + // Build metadata + metadata := map[string]string{ + "message_id": update.ID, + "timestamp": update.Timestamp, + } + + // Publish to message bus + c.HandleMessage(senderID, chatID, content, media, metadata) +} +``` + +## Complete Example: WebSocket Channel + +```go +package channels + +import ( + "context" + "encoding/json" + "fmt" + "sync" + + "github.com/gorilla/websocket" + "github.com/sipeed/picoclaw/pkg/bus" +) + +type WebSocketConfig struct { + URL string `json:"url"` + Token string `json:"token"` + AllowList []string `json:"allow_list"` +} + +type WebSocketChannel struct { + *BaseChannel + config *WebSocketConfig + conn *websocket.Conn + mu sync.Mutex + sendCh chan bus.OutboundMessage +} + +func NewWebSocketChannel(cfg *WebSocketConfig, msgBus *bus.MessageBus) *WebSocketChannel { + return &WebSocketChannel{ + BaseChannel: NewBaseChannel("websocket", cfg, msgBus, cfg.AllowList), + config: cfg, + sendCh: make(chan bus.OutboundMessage, 100), + } +} + +func (c *WebSocketChannel) Start(ctx context.Context) error { + c.mu.Lock() + defer c.mu.Unlock() + + if c.running { + return nil + } + + // Connect to WebSocket server + headers := make(map[string][]string) + if c.config.Token != "" { + headers["Authorization"] = []string{"Bearer " + c.config.Token} + } + + conn, _, err := websocket.DefaultDialer.Dial(c.config.URL, headers) + if err != nil { + return fmt.Errorf("failed to connect: %w", err) + } + + c.conn = conn + + // Start receive goroutine + go c.receiveLoop(ctx) + + // Start send goroutine + go c.sendLoop(ctx) + + c.setRunning(true) + return nil +} + +func (c *WebSocketChannel) Stop(ctx context.Context) error { + c.mu.Lock() + defer c.mu.Unlock() + + if !c.running { + return nil + } + + // Close send channel + close(c.sendCh) + + // Close connection + if c.conn != nil { + c.conn.Close() + } + + c.setRunning(false) + return nil +} + +func (c *WebSocketChannel) Send(ctx context.Context, msg bus.OutboundMessage) error { + if !c.running { + return fmt.Errorf("channel not running") + } + + select { + case c.sendCh <- msg: + return nil + default: + return fmt.Errorf("send buffer full") + } +} + +func (c *WebSocketChannel) receiveLoop(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + default: + _, message, err := c.conn.ReadMessage() + if err != nil { + // Handle error - reconnect? + return + } + + c.handleMessage(message) + } + } +} + +func (c *WebSocketChannel) sendLoop(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case msg, ok := <-c.sendCh: + if !ok { + return + } + + // Create WebSocket message + wsMsg := map[string]interface{}{ + "chat_id": msg.ChatID, + "content": msg.Content, + } + + data, _ := json.Marshal(wsMsg) + if err := c.conn.WriteMessage(websocket.TextMessage, data); err != nil { + // Handle error + } + } + } +} + +func (c *WebSocketChannel) handleMessage(data []byte) { + var msg struct { + SenderID string `json:"sender_id"` + ChatID string `json:"chat_id"` + Content string `json:"content"` + } + + if err := json.Unmarshal(data, &msg); err != nil { + return + } + + // Publish to bus + c.HandleMessage(msg.SenderID, msg.ChatID, msg.Content, nil, nil) +} +``` + +## Registering Channels + +Channels are registered in the channel manager: + +```go +// In gateway setup +channelManager := channels.NewManager() + +// Add your channel +myChannel := channels.NewMyChannel(&config.Channels.MyChannel, msgBus) +channelManager.Register(myChannel) + +// Start all channels +channelManager.StartAll(ctx) +``` + +## Handling Rich Media + +### Receiving Media + +```go +func (c *MyChannel) handleUpdate(update MyUpdate) { + var media []string + + // Collect images + for _, img := range update.Message.Images { + media = append(media, img.URL) + } + + // Collect files + for _, file := range update.Message.Files { + media = append(media, file.URL) + } + + c.HandleMessage(senderID, chatID, content, media, metadata) +} +``` + +### Sending Media + +Some platforms support rich message formatting: + +```go +func (c *MyChannel) Send(ctx context.Context, msg bus.OutboundMessage) error { + // Check for markdown support + if supportsMarkdown(msg.Content) { + return c.client.SendMarkdown(ctx, msg.ChatID, msg.Content) + } + + // Plain text fallback + return c.client.SendMessage(ctx, msg.ChatID, msg.Content) +} +``` + +## Metadata + +Use metadata to pass platform-specific information: + +```go +metadata := map[string]string{ + "message_id": update.ID, + "reply_to_id": update.ReplyToID, + "peer_kind": "direct", // or "group", "channel" + "peer_id": update.Chat.ID, + "account_id": c.accountID, + "guild_id": update.GuildID, // For Discord-like platforms + "team_id": update.TeamID, // For Slack-like platforms +} + +c.HandleMessage(senderID, chatID, content, media, metadata) +``` + +This metadata is used for: +- Message routing +- Reply threading +- Multi-account support + +## Configuration + +Add your channel configuration to the config structure: + +```go +// In pkg/config/config.go +type ChannelsConfig struct { + Telegram TelegramConfig `json:"telegram"` + Discord DiscordConfig `json:"discord"` + MyChannel MyChannelConfig `json:"mychannel"` + // ... +} +``` + +Example configuration: + +```json +{ + "channels": { + "mychannel": { + "api_token": "your-token-here", + "allow_list": ["user1", "user2"] + } + } +} +``` + +## Error Handling + +Handle errors gracefully: + +```go +func (c *MyChannel) receiveLoop(ctx context.Context) { + defer func() { + if r := recover(); r != nil { + // Log panic and attempt recovery + } + }() + + for { + select { + case <-ctx.Done(): + return + default: + if err := c.receiveMessage(ctx); err != nil { + // Log error + if isConnectionError(err) { + // Attempt reconnection + c.reconnect(ctx) + } + } + } + } +} +``` + +## Testing Channels + +```go +package channels + +import ( + "context" + "testing" + + "github.com/sipeed/picoclaw/pkg/bus" +) + +func TestMyChannel(t *testing.T) { + // Create message bus + msgBus := bus.NewMessageBus() + + // Create channel + cfg := &MyChannelConfig{ + APIToken: "test-token", + } + channel := NewMyChannel(cfg, msgBus) + + // Test name + if channel.Name() != "mychannel" { + t.Errorf("expected name 'mychannel', got %s", channel.Name()) + } + + // Test start/stop + ctx := context.Background() + if err := channel.Start(ctx); err != nil { + t.Fatalf("failed to start: %v", err) + } + + if !channel.IsRunning() { + t.Error("channel should be running") + } + + if err := channel.Stop(ctx); err != nil { + t.Fatalf("failed to stop: %v", err) + } + + if channel.IsRunning() { + t.Error("channel should not be running") + } +} + +func TestAllowList(t *testing.T) { + msgBus := bus.NewMessageBus() + cfg := &MyChannelConfig{ + APIToken: "test-token", + AllowList: []string{"user1", "user2"}, + } + channel := NewMyChannel(cfg, msgBus) + + // Test allowed users + if !channel.IsAllowed("user1") { + t.Error("user1 should be allowed") + } + + // Test disallowed users + if channel.IsAllowed("user3") { + t.Error("user3 should not be allowed") + } +} +``` + +## Best Practices + +1. **Graceful Shutdown**: Handle context cancellation properly +2. **Reconnection**: Implement automatic reconnection for network issues +3. **Rate Limiting**: Respect platform rate limits +4. **Error Logging**: Log errors for debugging +5. **Buffer Sizes**: Use appropriate buffer sizes for channels +6. **Thread Safety**: Use mutexes for shared state +7. **Backpressure**: Handle slow consumers gracefully + +## See Also + +- [Message Bus API](../api/message-bus.md) +- [Existing Channels](https://github.com/sipeed/picoclaw/tree/main/pkg/channels) +- [Telegram Channel](https://github.com/sipeed/picoclaw/tree/main/pkg/channels/telegram.go) diff --git a/docs/developer-guide/extending/creating-providers.md b/docs/developer-guide/extending/creating-providers.md new file mode 100644 index 0000000000..a555891dae --- /dev/null +++ b/docs/developer-guide/extending/creating-providers.md @@ -0,0 +1,636 @@ +# Creating LLM Providers + +This guide explains how to create custom LLM providers for PicoClaw. + +## Overview + +LLM providers handle communication with language model APIs. Each provider implements the `LLMProvider` interface and is responsible for: + +1. Formatting requests for the specific API +2. Sending requests to the API +3. Parsing responses and tool calls +4. Handling errors and retries + +## LLMProvider Interface + +All providers must implement this interface: + +```go +type LLMProvider interface { + Chat(ctx context.Context, messages []Message, tools []ToolDefinition, + model string, options map[string]interface{}) (*LLMResponse, error) + GetDefaultModel() string +} +``` + +### Supporting Types + +```go +// Message represents a chat message +type Message struct { + Role string `json:"role"` // "system", "user", "assistant", "tool" + Content string `json:"content"` // Message content + ToolCalls []ToolCall `json:"tool_calls,omitempty"` // Tool calls from assistant + ToolCallID string `json:"tool_call_id,omitempty"` // ID for tool response +} + +// ToolCall represents a tool call request +type ToolCall struct { + ID string `json:"id"` + Type string `json:"type,omitempty"` + Function *FunctionCall `json:"function,omitempty"` + Name string `json:"name,omitempty"` + Arguments map[string]interface{} `json:"arguments,omitempty"` +} + +// FunctionCall represents function call details +type FunctionCall struct { + Name string `json:"name"` + Arguments string `json:"arguments"` // JSON string +} + +// LLMResponse is the response from the LLM +type LLMResponse struct { + Content string `json:"content"` + ToolCalls []ToolCall `json:"tool_calls,omitempty"` + FinishReason string `json:"finish_reason"` + Usage *UsageInfo `json:"usage,omitempty"` +} + +// UsageInfo contains token usage information +type UsageInfo struct { + PromptTokens int `json:"prompt_tokens"` + CompletionTokens int `json:"completion_tokens"` + TotalTokens int `json:"total_tokens"` +} + +// ToolDefinition defines a tool for the LLM +type ToolDefinition struct { + Type string `json:"type"` + Function ToolFunctionDefinition `json:"function"` +} + +// ToolFunctionDefinition describes a tool function +type ToolFunctionDefinition struct { + Name string `json:"name"` + Description string `json:"description"` + Parameters map[string]interface{} `json:"parameters"` +} +``` + +## Creating a Basic Provider + +### Step 1: Define the Provider Struct + +```go +package myprovider + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + "github.com/sipeed/picoclaw/pkg/providers/protocoltypes" +) + +type Provider struct { + apiKey string + apiBase string + httpClient *http.Client +} + +func NewProvider(apiKey, apiBase string) *Provider { + return &Provider{ + apiKey: apiKey, + apiBase: apiBase, + httpClient: &http.Client{ + Timeout: 120 * time.Second, + }, + } +} +``` + +### Step 2: Implement GetDefaultModel + +```go +func (p *Provider) GetDefaultModel() string { + return "my-provider/default-model" +} +``` + +### Step 3: Implement Chat + +```go +func (p *Provider) Chat(ctx context.Context, messages []protocoltypes.Message, + tools []protocoltypes.ToolDefinition, model string, + options map[string]interface{}) (*protocoltypes.LLMResponse, error) { + + // Build request body + requestBody := map[string]interface{}{ + "model": model, + "messages": messages, + } + + // Add tools if provided + if len(tools) > 0 { + requestBody["tools"] = tools + requestBody["tool_choice"] = "auto" + } + + // Add options + if maxTokens, ok := options["max_tokens"]; ok { + requestBody["max_tokens"] = maxTokens + } + if temperature, ok := options["temperature"]; ok { + requestBody["temperature"] = temperature + } + + // Marshal request + jsonData, err := json.Marshal(requestBody) + if err != nil { + return nil, fmt.Errorf("failed to marshal request: %w", err) + } + + // Create HTTP request + req, err := http.NewRequestWithContext(ctx, "POST", + p.apiBase+"/chat/completions", bytes.NewReader(jsonData)) + if err != nil { + return nil, fmt.Errorf("failed to create request: %w", err) + } + + // Set headers + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer "+p.apiKey) + + // Send request + resp, err := p.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to send request: %w", err) + } + defer resp.Body.Close() + + // Read response + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response: %w", err) + } + + // Check status code + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("API error: status=%d body=%s", resp.StatusCode, string(body)) + } + + // Parse response + return p.parseResponse(body) +} +``` + +### Step 4: Implement Response Parsing + +```go +func (p *Provider) parseResponse(body []byte) (*protocoltypes.LLMResponse, error) { + // Define response structure matching the API + var apiResponse struct { + Choices []struct { + Message struct { + Content string `json:"content"` + ToolCalls []struct { + ID string `json:"id"` + Type string `json:"type"` + Function *struct { + Name string `json:"name"` + Arguments string `json:"arguments"` + } `json:"function"` + } `json:"tool_calls"` + } `json:"message"` + FinishReason string `json:"finish_reason"` + } `json:"choices"` + Usage *protocoltypes.UsageInfo `json:"usage"` + } + + // Parse JSON + if err := json.Unmarshal(body, &apiResponse); err != nil { + return nil, fmt.Errorf("failed to unmarshal response: %w", err) + } + + // Handle empty response + if len(apiResponse.Choices) == 0 { + return &protocoltypes.LLMResponse{ + Content: "", + FinishReason: "stop", + }, nil + } + + // Extract choice + choice := apiResponse.Choices[0] + + // Convert tool calls + toolCalls := make([]protocoltypes.ToolCall, 0, len(choice.Message.ToolCalls)) + for _, tc := range choice.Message.ToolCalls { + arguments := make(map[string]interface{}) + name := "" + + if tc.Function != nil { + name = tc.Function.Name + if tc.Function.Arguments != "" { + if err := json.Unmarshal([]byte(tc.Function.Arguments), &arguments); err != nil { + // Handle parse error - store raw arguments + arguments["raw"] = tc.Function.Arguments + } + } + } + + toolCalls = append(toolCalls, protocoltypes.ToolCall{ + ID: tc.ID, + Name: name, + Arguments: arguments, + }) + } + + return &protocoltypes.LLMResponse{ + Content: choice.Message.Content, + ToolCalls: toolCalls, + FinishReason: choice.FinishReason, + Usage: apiResponse.Usage, + }, nil +} +``` + +## Error Classification + +For fallback chain support, classify errors: + +```go +import "github.com/sipeed/picoclaw/pkg/providers" + +func (p *Provider) Chat(ctx context.Context, messages []protocoltypes.Message, + tools []protocoltypes.ToolDefinition, model string, + options map[string]interface{}) (*protocoltypes.LLMResponse, error) { + + // ... make request ... + + if resp.StatusCode != http.StatusOK { + // Classify error + reason := p.classifyError(resp.StatusCode, body) + return nil, &providers.FailoverError{ + Reason: reason, + Provider: "myprovider", + Model: model, + Status: resp.StatusCode, + Wrapped: fmt.Errorf("API error: %s", string(body)), + } + } + + // ... +} + +func (p *Provider) classifyError(status int, body []byte) providers.FailoverReason { + switch status { + case 401, 403: + return providers.FailoverAuth + case 429: + return providers.FailoverRateLimit + case 402: + return providers.FailoverBilling + case 504, 502: + return providers.FailoverTimeout + case 503: + return providers.FailoverOverloaded + case 400: + return providers.FailoverFormat + default: + return providers.FailoverUnknown + } +} +``` + +## Registering Providers + +Add your provider to the factory: + +```go +// In pkg/providers/factory.go + +func NewProviderFromConfig(cfg *config.Config) (LLMProvider, error) { + // ... existing checks ... + + // Add your provider + if cfg.Providers.MyProvider.APIKey != "" { + return myprovider.NewProvider( + cfg.Providers.MyProvider.APIKey, + cfg.Providers.MyProvider.APIBase, + ), nil + } + + // ... +} +``` + +## Complete Example: Custom Provider + +```go +package myprovider + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + "github.com/sipeed/picoclaw/pkg/providers" + "github.com/sipeed/picoclaw/pkg/providers/protocoltypes" +) + +type Provider struct { + apiKey string + apiBase string + httpClient *http.Client + defaultModel string +} + +type Config struct { + APIKey string + APIBase string + DefaultModel string + Timeout time.Duration + Proxy string +} + +func NewProvider(cfg Config) *Provider { + client := &http.Client{ + Timeout: cfg.Timeout, + } + + if cfg.Timeout == 0 { + client.Timeout = 120 * time.Second + } + + if cfg.APIBase == "" { + cfg.APIBase = "https://api.myprovider.com/v1" + } + + if cfg.DefaultModel == "" { + cfg.DefaultModel = "myprovider/default" + } + + return &Provider{ + apiKey: cfg.APIKey, + apiBase: cfg.APIBase, + httpClient: client, + defaultModel: cfg.DefaultModel, + } +} + +func (p *Provider) GetDefaultModel() string { + return p.defaultModel +} + +func (p *Provider) Chat(ctx context.Context, messages []protocoltypes.Message, + tools []protocoltypes.ToolDefinition, model string, + options map[string]interface{}) (*protocoltypes.LLMResponse, error) { + + if p.apiKey == "" { + return nil, fmt.Errorf("API key not configured") + } + + // Normalize model name (strip provider prefix if present) + model = normalizeModel(model) + + // Build request + requestBody := p.buildRequestBody(messages, tools, model, options) + + // Marshal + jsonData, err := json.Marshal(requestBody) + if err != nil { + return nil, fmt.Errorf("marshal request: %w", err) + } + + // Create request + url := p.apiBase + "/chat/completions" + req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(jsonData)) + if err != nil { + return nil, fmt.Errorf("create request: %w", err) + } + + // Set headers + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer "+p.apiKey) + + // Send + resp, err := p.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("send request: %w", err) + } + defer resp.Body.Close() + + // Read body + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("read response: %w", err) + } + + // Handle errors + if resp.StatusCode != http.StatusOK { + return nil, p.createError(resp.StatusCode, body, model) + } + + // Parse response + return p.parseResponse(body) +} + +func (p *Provider) buildRequestBody(messages []protocoltypes.Message, + tools []protocoltypes.ToolDefinition, model string, + options map[string]interface{}) map[string]interface{} { + + body := map[string]interface{}{ + "model": model, + "messages": messages, + } + + if len(tools) > 0 { + body["tools"] = tools + body["tool_choice"] = "auto" + } + + if maxTokens, ok := asInt(options["max_tokens"]); ok { + body["max_tokens"] = maxTokens + } + + if temperature, ok := asFloat(options["temperature"]); ok { + body["temperature"] = temperature + } + + return body +} + +func (p *Provider) createError(status int, body []byte, model string) error { + reason := providers.FailoverUnknown + + switch status { + case 401, 403: + reason = providers.FailoverAuth + case 429: + reason = providers.FailoverRateLimit + case 402: + reason = providers.FailoverBilling + case 504, 502: + reason = providers.FailoverTimeout + case 503: + reason = providers.FailoverOverloaded + case 400: + reason = providers.FailoverFormat + } + + return &providers.FailoverError{ + Reason: reason, + Provider: "myprovider", + Model: model, + Status: status, + Wrapped: fmt.Errorf("API error: %s", string(body)), + } +} + +func normalizeModel(model string) string { + // Strip "myprovider/" prefix if present + if len(model) > 11 && model[:11] == "myprovider/" { + return model[11:] + } + return model +} + +func asInt(v interface{}) (int, bool) { + switch val := v.(type) { + case int: + return val, true + case int64: + return int(val), true + case float64: + return int(val), true + default: + return 0, false + } +} + +func asFloat(v interface{}) (float64, bool) { + switch val := v.(type) { + case float64: + return val, true + case float32: + return float64(val), true + case int: + return float64(val), true + default: + return 0, false + } +} +``` + +## Testing Providers + +```go +package myprovider + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/sipeed/picoclaw/pkg/providers/protocoltypes" +) + +func TestProviderChat(t *testing.T) { + // Create test server + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Verify request + if r.Header.Get("Authorization") != "Bearer test-key" { + t.Error("missing authorization header") + } + + // Send mock response + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{ + "choices": [{ + "message": { + "content": "Hello!", + "tool_calls": [] + }, + "finish_reason": "stop" + }], + "usage": { + "prompt_tokens": 10, + "completion_tokens": 5, + "total_tokens": 15 + } + }`)) + })) + defer server.Close() + + // Create provider + provider := NewProvider(Config{ + APIKey: "test-key", + APIBase: server.URL, + }) + + // Test chat + messages := []protocoltypes.Message{ + {Role: "user", Content: "Hi"}, + } + + resp, err := provider.Chat(context.Background(), messages, nil, "test-model", nil) + if err != nil { + t.Fatalf("Chat failed: %v", err) + } + + if resp.Content != "Hello!" { + t.Errorf("expected 'Hello!', got %q", resp.Content) + } +} + +func TestProviderError(t *testing.T) { + // Create test server that returns error + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusUnauthorized) + w.Write([]byte(`{"error": "invalid API key"}`)) + })) + defer server.Close() + + provider := NewProvider(Config{ + APIKey: "bad-key", + APIBase: server.URL, + }) + + messages := []protocoltypes.Message{ + {Role: "user", Content: "Hi"}, + } + + _, err := provider.Chat(context.Background(), messages, nil, "test-model", nil) + if err == nil { + t.Error("expected error for 401 response") + } +} +``` + +## Best Practices + +1. **Context Support**: Always use context for cancellation +2. **Error Classification**: Classify errors for fallback support +3. **Timeout Configuration**: Allow configurable timeouts +4. **Model Normalization**: Handle provider prefixes in model names +5. **Retry Logic**: Consider adding retry for transient errors +6. **Logging**: Log requests and responses for debugging +7. **Rate Limiting**: Respect API rate limits + +## See Also + +- [Provider Interface Reference](../api/provider-interface.md) +- [Fallback Chain](../api/provider-interface.md#fallback-chain) +- [OpenAI-Compatible Provider](https://github.com/sipeed/picoclaw/tree/main/pkg/providers/openai_compat) diff --git a/docs/developer-guide/extending/creating-skills.md b/docs/developer-guide/extending/creating-skills.md new file mode 100644 index 0000000000..a666dc7c17 --- /dev/null +++ b/docs/developer-guide/extending/creating-skills.md @@ -0,0 +1,464 @@ +# Creating Skills + +This guide explains how to create skills for PicoClaw. + +## Overview + +Skills are reusable prompt templates that enhance the agent's capabilities. They are defined in Markdown files and can be loaded from multiple locations. Skills are a powerful way to: + +- Package domain expertise +- Create reusable workflows +- Share capabilities across agents +- Customize agent behavior for specific tasks + +## Skill File Format + +Skills are defined in `SKILL.md` files with optional YAML frontmatter: + +```markdown +--- +name: code-review +description: Review code for quality, security, and best practices +--- + +# Code Review Skill + +You are a code reviewer. When reviewing code, analyze: + +## Code Quality +- Readability and maintainability +- Naming conventions +- Code organization + +## Security +- Input validation +- Authentication/authorization +- Potential vulnerabilities + +## Best Practices +- Design patterns +- Error handling +- Performance considerations + +## Output Format + +Provide your review in the following format: + +### Summary +[Brief summary of the review] + +### Issues Found +- [List of issues with severity] + +### Recommendations +- [List of recommendations] + +### Positive Aspects +- [Things done well] +``` + +## Skill Locations + +Skills are loaded from three locations in priority order: + +1. **Workspace Skills** (highest priority) + - Location: `~/.picoclaw/workspace/skills//SKILL.md` + - Use: Project-specific skills + +2. **Global Skills** + - Location: `~/.picoclaw/skills//SKILL.md` + - Use: User-wide skills + +3. **Built-in Skills** (lowest priority) + - Location: Embedded in binary or system directory + - Use: System-provided skills + +When skills have the same name, higher-priority locations override lower ones. + +## Creating a Skill + +### Step 1: Create Skill Directory + +```bash +mkdir -p ~/.picoclaw/skills/my-skill +``` + +### Step 2: Create SKILL.md + +Create `~/.picoclaw/skills/my-skill/SKILL.md`: + +```markdown +--- +name: my-skill +description: A brief description of what this skill does +--- + +# My Skill + +[Detailed skill instructions go here] +``` + +### Step 3: Use in Agent + +Skills are automatically discovered. The agent will see available skills and can invoke them. + +## Skill Metadata + +### Name + +The skill name must: +- Be alphanumeric with hyphens +- Be at most 64 characters +- Match the pattern: `^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$` + +```yaml +--- +name: valid-skill-name +--- +``` + +### Description + +The description should: +- Be at most 1024 characters +- Explain what the skill does +- Help the LLM decide when to use it + +```yaml +--- +description: Analyzes Python code for potential bugs and suggests improvements +--- +``` + +## Skill Content + +The skill content (after frontmatter) is injected into the system prompt when the skill is active. Write clear, detailed instructions: + +### Good Skill Content + +```markdown +# Database Query Skill + +You are a database expert. When helping with database queries: + +## Supported Databases +- PostgreSQL +- MySQL +- SQLite + +## Query Guidelines + +1. **Always use parameterized queries** to prevent SQL injection +2. **Include indexes** for frequently queried columns +3. **Use transactions** for multi-step operations + +## Example Queries + +### Select with Join +```sql +SELECT u.name, o.total +FROM users u +JOIN orders o ON u.id = o.user_id +WHERE o.created_at > ? +``` + +## Output Format + +When generating SQL: +1. Explain what the query does +2. Show the SQL statement +3. List any assumptions made +``` + +### Tips for Effective Skills + +1. **Be Specific**: Provide concrete examples and guidelines +2. **Structure Content**: Use headings, lists, and code blocks +3. **Define Scope**: Clearly state what the skill does and doesn't do +4. **Include Examples**: Show expected inputs and outputs +5. **Set Boundaries**: Define limitations and edge cases + +## Example Skills + +### Code Generation Skill + +```markdown +--- +name: code-gen +description: Generate high-quality code in various programming languages +--- + +# Code Generation Skill + +Generate clean, well-documented code following these principles: + +## Code Style + +### Python +- Follow PEP 8 +- Use type hints +- Document with docstrings + +### JavaScript/TypeScript +- Use const/let (never var) +- Prefer arrow functions +- Use JSDoc comments + +### Go +- Follow gofmt style +- Handle errors explicitly +- Use meaningful variable names + +## Documentation + +Always include: +- Purpose of the function/module +- Parameter descriptions +- Return value description +- Example usage + +## Example + +```python +def calculate_total(items: list[dict]) -> float: + """ + Calculate the total price of items. + + Args: + items: List of item dictionaries with 'price' and 'quantity' keys. + + Returns: + Total price as a float. + + Example: + >>> items = [{'price': 10.0, 'quantity': 2}] + >>> calculate_total(items) + 20.0 + """ + return sum(item['price'] * item['quantity'] for item in items) +``` +``` + +### Writing Assistant Skill + +```markdown +--- +name: writing-assistant +description: Help with writing, editing, and improving text +--- + +# Writing Assistant Skill + +You are a writing assistant. Help users improve their writing. + +## Services + +### Editing +- Fix grammar and spelling +- Improve clarity +- Enhance readability + +### Style Suggestions +- Adjust tone (formal/casual) +- Improve flow +- Strengthen word choice + +### Structure +- Organize paragraphs +- Create outlines +- Develop arguments + +## Guidelines + +1. Preserve the author's voice +2. Explain significant changes +3. Offer alternatives for major revisions +4. Consider the target audience + +## Output Format + +When editing, provide: +1. **Revised text**: The improved version +2. **Changes made**: Brief explanation of edits +3. **Suggestions**: Optional further improvements +``` + +### Data Analysis Skill + +```markdown +--- +name: data-analysis +description: Analyze datasets and provide insights +--- + +# Data Analysis Skill + +You are a data analyst. Help users understand their data. + +## Capabilities + +### Descriptive Statistics +- Mean, median, mode +- Standard deviation +- Distribution analysis + +### Pattern Recognition +- Trends over time +- Correlations +- Anomalies + +### Visualization Suggestions +- Chart types +- Color schemes +- Labeling best practices + +## Analysis Process + +1. **Understand the Data** + - What does each column represent? + - What is the time range? + - Are there missing values? + +2. **Clean the Data** + - Handle nulls + - Remove duplicates + - Fix inconsistencies + +3. **Analyze** + - Calculate statistics + - Find patterns + - Identify insights + +4. **Report** + - Summarize findings + - Highlight key insights + - Recommend actions + +## Output Format + +### Executive Summary +[2-3 sentence overview] + +### Key Findings +- [Finding 1] +- [Finding 2] +- [Finding 3] + +### Detailed Analysis +[In-depth analysis] + +### Recommendations +- [Recommendation 1] +- [Recommendation 2] +``` + +## Frontmatter Formats + +PicoClaw supports both JSON and YAML frontmatter: + +### YAML (Recommended) + +```markdown +--- +name: my-skill +description: Skill description +--- + +Content here... +``` + +### JSON + +```markdown +--- +{ + "name": "my-skill", + "description": "Skill description" +} +--- + +Content here... +``` + +## Loading Skills + +Skills are loaded by the `SkillsLoader`: + +```go +loader := skills.NewSkillsLoader( + workspace, // Workspace directory + globalSkillsPath, // ~/.picoclaw/skills + builtinSkillsPath, // Built-in skills directory +) + +// List all available skills +allSkills := loader.ListSkills() + +// Load a specific skill +content, found := loader.LoadSkill("my-skill") + +// Build summary for context +summary := loader.BuildSkillsSummary() +``` + +## Testing Skills + +Test your skills by: + +1. **Creating the skill file** in the appropriate directory +2. **Starting PicoClaw** with debug mode +3. **Asking the agent** about available skills +4. **Invoking the skill** with a relevant request + +```bash +# Start with debug +./build/picoclaw agent --debug + +# Ask about skills +> What skills do you have available? + +> Use the code-review skill to review this function: +> def add(a, b): return a + b +``` + +## Best Practices + +1. **Single Purpose**: Each skill should do one thing well +2. **Clear Description**: Help the LLM know when to use it +3. **Comprehensive Content**: Include all necessary context +4. **Examples**: Show expected inputs and outputs +5. **Limitations**: State what the skill cannot do +6. **Regular Updates**: Keep skills current with requirements + +## Sharing Skills + +Skills can be shared by: + +1. **Git Repository**: Store skills in a repo +2. **Copy to Workspace**: Copy skill directories +3. **Package Distribution**: Create skill packages + +Example structure for a skill repository: + +``` +my-skills/ +├── code-review/ +│ └── SKILL.md +├── data-analysis/ +│ └── SKILL.md +└── writing-assistant/ + └── SKILL.md +``` + +Users can clone and link: + +```bash +git clone https://github.com/user/my-skills.git +ln -s my-skills/* ~/.picoclaw/skills/ +``` + +## See Also + +- [User Guide: Using Skills](../../user-guide/skills/using-skills.md) +- [User Guide: Creating Skills](../../user-guide/skills/creating-skills.md) +- [Skills Loader Source](https://github.com/sipeed/picoclaw/tree/main/pkg/skills) diff --git a/docs/developer-guide/extending/creating-tools.md b/docs/developer-guide/extending/creating-tools.md new file mode 100644 index 0000000000..54f3545802 --- /dev/null +++ b/docs/developer-guide/extending/creating-tools.md @@ -0,0 +1,465 @@ +# Creating Custom Tools + +This guide explains how to create custom tools for PicoClaw. + +## Overview + +Tools are the primary way agents interact with the world. Each tool implements the `Tool` interface and can be invoked by the LLM during message processing. + +## Tool Interface + +All tools must implement this interface: + +```go +type Tool interface { + Name() string + Description() string + Parameters() map[string]interface{} + Execute(ctx context.Context, args map[string]interface{}) *ToolResult +} +``` + +### Optional Interfaces + +Tools can also implement optional interfaces for additional functionality: + +```go +// ContextualTool receives channel/chat context +type ContextualTool interface { + Tool + SetContext(channel, chatID string) +} + +// AsyncTool supports asynchronous execution +type AsyncTool interface { + Tool + SetCallback(cb AsyncCallback) +} +``` + +## Creating a Basic Tool + +### Step 1: Define the Tool Struct + +```go +package tools + +import ( + "context" + "fmt" +) + +// CalculatorTool performs arithmetic operations +type CalculatorTool struct { + // Add any configuration fields here +} + +func NewCalculatorTool() *CalculatorTool { + return &CalculatorTool{} +} +``` + +### Step 2: Implement Required Methods + +```go +// Name returns the tool's identifier +func (t *CalculatorTool) Name() string { + return "calculator" +} + +// Description explains what the tool does +func (t *CalculatorTool) Description() string { + return "Perform arithmetic calculations. Use this tool for mathematical operations." +} + +// Parameters defines the JSON schema for arguments +func (t *CalculatorTool) Parameters() map[string]interface{} { + return map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "operation": map[string]interface{}{ + "type": "string", + "enum": []string{"add", "subtract", "multiply", "divide"}, + "description": "The arithmetic operation to perform", + }, + "a": map[string]interface{}{ + "type": "number", + "description": "First operand", + }, + "b": map[string]interface{}{ + "type": "number", + "description": "Second operand", + }, + }, + "required": []string{"operation", "a", "b"}, + } +} +``` + +### Step 3: Implement Execute + +```go +// Execute performs the tool operation +func (t *CalculatorTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + // Extract arguments with type checking + operation, ok := args["operation"].(string) + if !ok { + return ErrorResult("operation must be a string") + } + + a, ok := toFloat64(args["a"]) + if !ok { + return ErrorResult("a must be a number") + } + + b, ok := toFloat64(args["b"]) + if !ok { + return ErrorResult("b must be a number") + } + + // Perform calculation + var result float64 + switch operation { + case "add": + result = a + b + case "subtract": + result = a - b + case "multiply": + result = a * b + case "divide": + if b == 0 { + return ErrorResult("division by zero") + } + result = a / b + default: + return ErrorResult(fmt.Sprintf("unknown operation: %s", operation)) + } + + // Return result + return UserResult(fmt.Sprintf("%.2f", result)) +} + +// Helper function to convert interface{} to float64 +func toFloat64(v interface{}) (float64, bool) { + switch val := v.(type) { + case float64: + return val, true + case float32: + return float64(val), true + case int: + return float64(val), true + case int64: + return float64(val), true + default: + return 0, false + } +} +``` + +## Tool Results + +PicoClaw provides several result types: + +```go +// Basic result - content for LLM only +result := NewToolResult("Operation completed") + +// Silent result - no user message, LLM only +result := SilentResult("File saved successfully") + +// User result - same content for LLM and user +result := UserResult("Found 42 files") + +// Error result +result := ErrorResult("Operation failed: reason") + +// Async result +result := AsyncResult("Task started, will report back") +``` + +### Advanced Result Usage + +```go +// Different content for LLM and user +result := &ToolResult{ + ForLLM: "Technical details here...", + ForUser: "User-friendly summary here", + Silent: false, +} + +// Error with underlying error +result := ErrorResult("Failed to connect").WithError(err) +``` + +## Contextual Tools + +Tools that need channel/chat context implement `ContextualTool`: + +```go +type NotificationTool struct { + defaultChannel string + defaultChatID string +} + +func (t *NotificationTool) SetContext(channel, chatID string) { + t.defaultChannel = channel + t.defaultChatID = chatID +} + +func (t *NotificationTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + // Use t.defaultChannel and t.defaultChatID + return UserResult(fmt.Sprintf("Notification sent to %s:%s", t.defaultChannel, t.defaultChatID)) +} +``` + +## Async Tools + +For long-running operations, implement `AsyncTool`: + +```go +type LongRunningTool struct { + callback AsyncCallback +} + +func (t *LongRunningTool) SetCallback(cb AsyncCallback) { + t.callback = cb +} + +func (t *LongRunningTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + // Start async work + go func() { + // Do long-running work + time.Sleep(10 * time.Second) + result := UserResult("Long operation completed") + + // Notify completion + if t.callback != nil { + t.callback(ctx, result) + } + }() + + // Return immediately + return AsyncResult("Operation started, will complete in 10 seconds") +} +``` + +## Registering Tools + +### Method 1: In AgentLoop + +```go +// Register with all agents +agentLoop.RegisterTool(myTool) +``` + +### Method 2: In Tool Registry + +```go +// Create registry +registry := tools.NewToolRegistry() + +// Register tools +registry.Register(tools.NewCalculatorTool()) +registry.Register(tools.NewMessageTool()) + +// Use in agent +agent.Tools = registry +``` + +## Complete Example: Database Query Tool + +```go +package tools + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + + _ "github.com/mattn/go-sqlite3" +) + +type DatabaseTool struct { + db *sql.DB +} + +func NewDatabaseTool(dbPath string) (*DatabaseTool, error) { + db, err := sql.Open("sqlite3", dbPath) + if err != nil { + return nil, err + } + return &DatabaseTool{db: db}, nil +} + +func (t *DatabaseTool) Name() string { + return "database" +} + +func (t *DatabaseTool) Description() string { + return "Execute SQL queries on the database. Use for data retrieval and analysis." +} + +func (t *DatabaseTool) Parameters() map[string]interface{} { + return map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "query": map[string]interface{}{ + "type": "string", + "description": "SQL query to execute (SELECT only)", + }, + }, + "required": []string{"query"}, + } +} + +func (t *DatabaseTool) Execute(ctx context.Context, args map[string]interface{}) *ToolResult { + query, ok := args["query"].(string) + if !ok { + return ErrorResult("query must be a string") + } + + // Security: Only allow SELECT queries + if !isSelectQuery(query) { + return ErrorResult("only SELECT queries are allowed") + } + + // Execute query + rows, err := t.db.QueryContext(ctx, query) + if err != nil { + return ErrorResult(fmt.Sprintf("query failed: %v", err)) + } + defer rows.Close() + + // Get column names + columns, err := rows.Columns() + if err != nil { + return ErrorResult(fmt.Sprintf("failed to get columns: %v", err)) + } + + // Collect results + var results []map[string]interface{} + for rows.Next() { + values := make([]interface{}, len(columns)) + valuePtrs := make([]interface{}, len(columns)) + for i := range values { + valuePtrs[i] = &values[i] + } + + if err := rows.Scan(valuePtrs...); err != nil { + return ErrorResult(fmt.Sprintf("scan failed: %v", err)) + } + + row := make(map[string]interface{}) + for i, col := range columns { + row[col] = values[i] + } + results = append(results, row) + } + + // Format result + jsonResult, _ := json.MarshalIndent(results, "", " ") + return UserResult(fmt.Sprintf("Found %d rows:\n%s", len(results), string(jsonResult))) +} + +func isSelectQuery(query string) bool { + // Simple check - in production, use proper SQL parsing + return len(query) > 6 && query[:6] == "SELECT" +} +``` + +## Testing Tools + +```go +package tools + +import ( + "context" + "testing" +) + +func TestCalculatorTool(t *testing.T) { + tool := NewCalculatorTool() + + // Test Name + if tool.Name() != "calculator" { + t.Errorf("expected name 'calculator', got %s", tool.Name()) + } + + // Test addition + result := tool.Execute(context.Background(), map[string]interface{}{ + "operation": "add", + "a": 5, + "b": 3, + }) + + if result.IsError { + t.Errorf("unexpected error: %s", result.ForLLM) + } + if result.ForLLM != "8.00" { + t.Errorf("expected '8.00', got %s", result.ForLLM) + } + + // Test division by zero + result = tool.Execute(context.Background(), map[string]interface{}{ + "operation": "divide", + "a": 5, + "b": 0, + }) + + if !result.IsError { + t.Error("expected error for division by zero") + } +} +``` + +## Best Practices + +1. **Clear Names**: Use descriptive, lowercase names with underscores +2. **Good Descriptions**: Explain what the tool does and when to use it +3. **Validate Inputs**: Check types and values before processing +4. **Meaningful Errors**: Return helpful error messages +5. **Security First**: Validate and sanitize all inputs +6. **Use Context**: Support cancellation for long operations +7. **Appropriate Results**: Choose the right result type +8. **Test Thoroughly**: Write tests for all scenarios + +## Parameter Schema + +The `Parameters()` method returns a JSON Schema object: + +```go +func (t *MyTool) Parameters() map[string]interface{} { + return map[string]interface{}{ + "type": "object", + "properties": map[string]interface{}{ + "required_param": map[string]interface{}{ + "type": "string", + "description": "Description of the parameter", + }, + "optional_param": map[string]interface{}{ + "type": "integer", + "description": "Optional parameter", + "default": 10, + }, + "enum_param": map[string]interface{}{ + "type": "string", + "enum": []string{"option1", "option2"}, + "description": "Parameter with limited options", + }, + "array_param": map[string]interface{}{ + "type": "array", + "items": map[string]interface{}{"type": "string"}, + "description": "Array of strings", + }, + }, + "required": []string{"required_param"}, + } +} +``` + +## See Also + +- [Tool Interface Reference](../api/tool-interface.md) +- [Tool Result Types](../api/tool-interface.md#toolresult) +- [Existing Tools](https://github.com/sipeed/picoclaw/tree/main/pkg/tools) diff --git a/docs/developer-guide/testing.md b/docs/developer-guide/testing.md new file mode 100644 index 0000000000..57a9cada57 --- /dev/null +++ b/docs/developer-guide/testing.md @@ -0,0 +1,400 @@ +# Running Tests + +This guide explains how to run and write tests for PicoClaw. + +## Running Tests + +### Run All Tests + +Run the complete test suite: + +```bash +make test +``` + +Or using Go directly: + +```bash +go test ./pkg/... +``` + +### Run Tests for a Package + +Test a specific package: + +```bash +go test ./pkg/agent/... -v +go test ./pkg/providers/... -v +go test ./pkg/tools/... -v +``` + +### Run Specific Tests + +Run tests matching a pattern: + +```bash +go test ./pkg/providers/... -v -run TestFallbackChain +go test ./pkg/tools/... -v -run TestMessageTool +``` + +### Run with Verbose Output + +```bash +go test ./pkg/... -v +``` + +### Run with Coverage + +Generate coverage reports: + +```bash +# Coverage for all packages +go test ./pkg/... -cover + +# Detailed coverage report +go test ./pkg/... -coverprofile=coverage.out +go tool cover -html=coverage.out -o coverage.html +``` + +### Run Integration Tests + +Integration tests require external APIs and are tagged separately: + +```bash +go test ./pkg/... -v -tags=integration +``` + +Integration tests are located in files with the build tag: + +```go +//go:build integration +// +build integration +``` + +## Test Organization + +### Directory Structure + +``` +pkg/ +├── agent/ +│ ├── loop.go +│ ├── loop_test.go # Unit tests +│ └── loop_integration_test.go # Integration tests +├── providers/ +│ ├── fallback.go +│ ├── fallback_test.go +│ └── openai_compat/ +│ ├── provider.go +│ └── provider_test.go +└── tools/ + ├── message.go + ├── message_test.go + └── ... +``` + +### Test File Naming + +- Unit tests: `*_test.go` +- Integration tests: `*_integration_test.go` (with build tag) + +## Writing Tests + +### Basic Test + +```go +package tools + +import ( + "context" + "testing" +) + +func TestMessageTool(t *testing.T) { + tool := NewMessageTool() + + // Test Name() + if tool.Name() != "message" { + t.Errorf("expected name 'message', got %s", tool.Name()) + } + + // Test Description() + if tool.Description() == "" { + t.Error("description should not be empty") + } +} +``` + +### Table-Driven Tests + +```go +func TestToolResult(t *testing.T) { + tests := []struct { + name string + input string + expected string + isError bool + }{ + { + name: "success", + input: "valid input", + expected: "valid input", + isError: false, + }, + { + name: "error case", + input: "", + expected: "input is required", + isError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := processInput(tt.input) + if result.ForLLM != tt.expected { + t.Errorf("expected %q, got %q", tt.expected, result.ForLLM) + } + if result.IsError != tt.isError { + t.Errorf("expected isError=%v, got %v", tt.isError, result.IsError) + } + }) + } +} +``` + +### Testing Tool Execution + +```go +func TestMessageToolExecute(t *testing.T) { + tool := NewMessageTool() + + // Set up mock callback + var sentMessage string + tool.SetSendCallback(func(channel, chatID, content string) error { + sentMessage = content + return nil + }) + + // Set context + tool.SetContext("telegram", "123456") + + // Execute + result := tool.Execute(context.Background(), map[string]interface{}{ + "content": "Hello, world!", + }) + + // Verify + if result.IsError { + t.Errorf("unexpected error: %s", result.ForLLM) + } + if sentMessage != "Hello, world!" { + t.Errorf("expected 'Hello, world!', got %q", sentMessage) + } +} +``` + +### Testing with Context + +```go +func TestWithContext(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + + result := longRunningOperation(ctx) + if result == nil { + t.Error("expected result") + } +} +``` + +### Testing Error Cases + +```go +func TestErrorHandling(t *testing.T) { + tool := NewMessageTool() + + // Execute without setting context + result := tool.Execute(context.Background(), map[string]interface{}{ + "content": "Hello", + }) + + if !result.IsError { + t.Error("expected error when context not set") + } +} +``` + +### Mocking + +Create mock implementations for testing: + +```go +// Mock provider for testing +type MockProvider struct { + response *providers.LLMResponse + err error +} + +func (m *MockProvider) Chat(ctx context.Context, messages []providers.Message, + tools []providers.ToolDefinition, model string, + options map[string]interface{}) (*providers.LLMResponse, error) { + return m.response, m.err +} + +func (m *MockProvider) GetDefaultModel() string { + return "mock-model" +} + +func TestWithMockProvider(t *testing.T) { + mock := &MockProvider{ + response: &providers.LLMResponse{ + Content: "Hello!", + }, + } + + // Use mock in tests + // ... +} +``` + +## Test Utilities + +### Helper Functions + +```go +// Create a test message bus +func newTestBus() *bus.MessageBus { + return bus.NewMessageBus() +} + +// Create test config +func newTestConfig() *config.Config { + return &config.Config{ + Agents: config.AgentsConfig{ + Defaults: config.AgentDefaults{ + Model: "test-model", + }, + }, + } +} +``` + +### Setup and Teardown + +```go +func TestWithSetup(t *testing.T) { + // Setup + tmpDir, err := os.MkdirTemp("", "picoclaw-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) // Teardown + + // Test using tmpDir + // ... +} +``` + +## Benchmark Tests + +### Writing Benchmarks + +```go +func BenchmarkToolExecute(b *testing.B) { + tool := NewMessageTool() + tool.SetContext("telegram", "123456") + tool.SetSendCallback(func(channel, chatID, content string) error { + return nil + }) + + args := map[string]interface{}{ + "content": "test message", + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + tool.Execute(context.Background(), args) + } +} +``` + +### Running Benchmarks + +```bash +go test ./pkg/tools/... -bench=. +go test ./pkg/tools/... -bench=. -benchmem +``` + +## Continuous Integration + +Tests are run automatically in CI. Ensure all tests pass before submitting PRs: + +```bash +# Run full check +make check +``` + +This runs: +1. `make deps` - Download dependencies +2. `make fmt` - Format code +3. `make vet` - Run linter +4. `make test` - Run tests + +## Linting + +Run the Go linter: + +```bash +make vet +``` + +Or directly: + +```bash +go vet ./pkg/... +``` + +## Common Issues + +### Test Fails with "context deadline exceeded" + +The test may be timing out. Increase the timeout or check for blocking operations: + +```go +ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +``` + +### Test Fails with "no such file or directory" + +Tests may be looking for files in the wrong location. Use absolute paths or create temp directories: + +```go +tmpDir := t.TempDir() // Automatically cleaned up +``` + +### Race Condition Detected + +Run tests with race detection: + +```bash +go test ./pkg/... -race +``` + +Fix race conditions by adding proper synchronization. + +## Best Practices + +1. **Write tests for new features** - Aim for good coverage +2. **Use table-driven tests** - Test multiple cases efficiently +3. **Test error paths** - Don't just test happy paths +4. **Use mocks for external dependencies** - Isolate unit tests +5. **Keep tests fast** - Use short timeouts and mock slow operations +6. **Clean up resources** - Use `t.Cleanup()` or defer +7. **Use meaningful test names** - Describe what's being tested + +## Test Coverage Goals + +- Aim for >70% coverage on core packages +- 100% coverage on critical paths (tool execution, message routing) +- Integration tests for end-to-end scenarios diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md new file mode 100644 index 0000000000..9048738586 --- /dev/null +++ b/docs/getting-started/README.md @@ -0,0 +1,43 @@ +# Getting Started + +Welcome to PicoClaw! This section will help you get up and running quickly. + +## Learning Path + +1. **[Installation](installation.md)** - Install PicoClaw on your system +2. **[Quick Start](quick-start.md)** - Your first conversation in 5 minutes +3. **[Configuration Basics](configuration-basics.md)** - Understand the config structure +4. **[Your First Chat](first-chat.md)** - Interactive and one-shot messaging + +## Prerequisites + +Before you begin, you'll need: + +- A computer running Linux, macOS, or Windows +- An API key from an LLM provider (OpenRouter, Zhipu, Anthropic, OpenAI, etc.) + +## Quick Reference + +```bash +# Install +picoclaw onboard + +# Configure API key in ~/.picoclaw/config.json + +# One-shot message +picoclaw agent -m "Hello!" + +# Interactive mode +picoclaw agent + +# Start gateway for chat apps +picoclaw gateway +``` + +## What's Next? + +After completing the getting started guides: + +- [User Guide](../user-guide/README.md) - Learn about all features +- [CLI Reference](../user-guide/cli-reference.md) - All command options +- [Configuration](../configuration/config-file.md) - Complete config reference diff --git a/docs/getting-started/configuration-basics.md b/docs/getting-started/configuration-basics.md new file mode 100644 index 0000000000..70d3152087 --- /dev/null +++ b/docs/getting-started/configuration-basics.md @@ -0,0 +1,147 @@ +# Configuration Basics + +This guide explains the fundamental concepts of PicoClaw configuration. + +## Configuration File Location + +PicoClaw stores its configuration in: + +``` +~/.picoclaw/config.json +``` + +Use `picoclaw onboard` to create a default configuration file. + +## Configuration Sections + +The configuration file has several main sections: + +### agents + +Controls agent behavior and model settings. + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "glm-4.7", + "max_tokens": 8192, + "temperature": 0.7 + } + } +} +``` + +Key options: +- `workspace` - Where the agent stores files and sessions +- `model` - The LLM model to use +- `restrict_to_workspace` - Security sandbox (default: true) + +### providers + +API keys for LLM providers. + +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + }, + "zhipu": { + "api_key": "your-zhipu-key" + } + } +} +``` + +### channels + +Chat platform integrations. + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + } + } +} +``` + +### tools + +Tool configuration. + +```json +{ + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "YOUR_BRAVE_KEY" + } + } + } +} +``` + +## Environment Variables + +All config options can be overridden with environment variables: + +```bash +# Pattern: PICOCLAW_
_ +export PICOCLAW_AGENTS_DEFAULTS_MODEL="gpt-4o" +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" +``` + +## Provider Selection + +PicoClaw selects providers in this order: + +1. Explicit `provider` in config +2. Model name prefix (e.g., `openrouter/claude-...`) +3. First configured API key found + +## Model Format + +Models can be specified in two ways: + +**With provider prefix:** +```json +{ + "model": "openrouter/anthropic/claude-opus-4-5" +} +``` + +**Without prefix (uses default provider):** +```json +{ + "model": "glm-4.7" +} +``` + +## Minimal Configuration + +The minimal config to get started: + +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + } +} +``` + +All other options have sensible defaults. + +## Next Steps + +- [Configuration Reference](../configuration/config-file.md) - All config options +- [Providers Guide](../user-guide/providers/README.md) - Provider setup details +- [Quick Start](quick-start.md) - Get running quickly diff --git a/docs/getting-started/first-chat.md b/docs/getting-started/first-chat.md new file mode 100644 index 0000000000..488335a810 --- /dev/null +++ b/docs/getting-started/first-chat.md @@ -0,0 +1,118 @@ +# Your First Chat + +After [installing](installation.md) and [configuring](quick-start.md) PicoClaw, you're ready to chat! + +## One-Shot Messages + +Send a single message and get a response: + +```bash +picoclaw agent -m "What is 2+2?" +``` + +The agent will process your message and print the response. + +## Interactive Mode + +Start an interactive chat session: + +```bash +picoclaw agent +``` + +``` +🦞 Interactive mode (Ctrl+C to exit) + +🦞 You: Hello, who are you? + +🦞 I'm PicoClaw, your AI assistant! I'm an ultra-lightweight AI agent written in Go. How can I help you today? + +🦞 You: What can you do? + +🦞 I can help you with many tasks: +- Answer questions and provide information +- Search the web for current information +- Read and write files in the workspace +- Execute shell commands +- Schedule reminders and tasks +- And much more! +``` + +### Interactive Commands + +| Command | Action | +|---------|--------| +| Type a message | Send to the agent | +| `exit` or `quit` | Exit interactive mode | +| `Ctrl+C` | Exit interactive mode | + +## Debug Mode + +See what's happening behind the scenes: + +```bash +picoclaw agent --debug -m "Hello" +``` + +Debug mode shows: +- LLM requests +- Tool calls +- Response processing + +## Using Tools + +The agent can use tools automatically. Just ask: + +```bash +picoclaw agent -m "Search the web for the latest AI news and summarize it" +``` + +The agent will: +1. Use the `web_search` tool +2. Use the `web_fetch` tool to get content +3. Summarize the findings + +## Sessions + +Your conversation history is automatically saved. Continue a conversation: + +```bash +# Start a session +picoclaw agent -s "project-planning" -m "I'm planning a new project" + +# Continue later +picoclaw agent -s "project-planning" -m "What should we do next?" +``` + +Session files are stored in `~/.picoclaw/workspace/sessions/`. + +## With Gateway + +Connect to chat platforms: + +```bash +# Start the gateway +picoclaw gateway +``` + +Then chat via: +- Telegram +- Discord +- Slack +- LINE +- And more + +See [Channels](../user-guide/channels/README.md) for setup guides. + +## Tips for Better Chats + +1. **Be specific** - Clear questions get better answers +2. **Provide context** - Background info helps understanding +3. **Use sessions** - Maintain conversation context +4. **Check debug mode** - Understand what's happening + +## Next Steps + +- [CLI Reference](../user-guide/cli-reference.md) - All commands +- [Tools Overview](../user-guide/tools/README.md) - Available tools +- [Channels Guide](../user-guide/channels/README.md) - Connect to chat apps diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md new file mode 100644 index 0000000000..055e8f5af7 --- /dev/null +++ b/docs/getting-started/installation.md @@ -0,0 +1,205 @@ +# Installation + +This guide covers installing PicoClaw on your system. Choose the method that best fits your needs. + +> **Current Version:** `v0.1.2` — [View all releases](https://github.com/sipeed/picoclaw/releases) + +## Quick Install + +Download the precompiled binary for your platform from the [Releases page](https://github.com/sipeed/picoclaw/releases). + + + + +## Installation Methods + +### Option 1: Precompiled Binary (Recommended) + +The easiest way to get started. Download the appropriate binary for your platform: + +| Platform | Architecture | Download | +|----------|-------------|----------| +| **Linux** | x86_64 | `picoclaw_Linux_x86_64.tar.gz` | +| **Linux** | ARM64 | `picoclaw_Linux_arm64.tar.gz` | +| **Linux** | ARMv6 | `picoclaw_Linux_armv6.tar.gz` | +| **Linux** | RISC-V 64 | `picoclaw_Linux_riscv64.tar.gz` | +| **Linux** | MIPS64 | `picoclaw_Linux_mips64.tar.gz` | +| **Linux** | s390x | `picoclaw_Linux_s390x.tar.gz` | +| **macOS** | ARM64 (M1/M2/M3/M4) | `picoclaw_Darwin_arm64.tar.gz` | +| **macOS** | x86_64 (Intel) | `picoclaw_Darwin_x86_64.tar.gz` | +| **Windows** | x86_64 | `picoclaw_Windows_x86_64.zip` | +| **Windows** | ARM64 | `picoclaw_Windows_arm64.zip` | +| **FreeBSD** | x86_64 | `picoclaw_Freebsd_x86_64.tar.gz` | +| **FreeBSD** | ARM64 | `picoclaw_Freebsd_arm64.tar.gz` | +| **FreeBSD** | ARMv6 | `picoclaw_Freebsd_armv6.tar.gz` | + + +**One-liner install Linux/macOS:** + +```bash +# Linux/macOS - detect platform and install +VERSION="v0.1.2" +OS=$(uname -s) +ARCH=$(uname -m) +[ "$OS" = "Darwin" ] && OS="Darwin" +[ "$OS" = "Linux" ] && OS="Linux" +[ "$ARCH" = "x86_64" ] && ARCH="x86_64" +[ "$ARCH" = "aarch64" ] && ARCH="arm64" +wget -qO- https://github.com/sipeed/picoclaw/releases/download/${VERSION}/picoclaw_${OS}_${ARCH}.tar.gz | tar xz +sudo mv picoclaw /usr/local/bin/ +``` + +### Option 2: Build from Source + +Building from source gives you the latest features and is recommended for development. + +**Prerequisites:** +- Go 1.21 or later +- Git + +**Steps:** + +```bash +# Clone the repository +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw + +# Download dependencies +make deps + +# Build for current platform +make build + +# The binary will be in ./build/picoclaw +./build/picoclaw onboard +``` + +**Build for all platforms:** + +```bash +make build-all +# Binaries will be in ./build/ for each platform +``` + +**Install to system:** + +```bash +# Install to ~/.local/bin +make install + +# Add to PATH (add to ~/.bashrc or ~/.zshrc) +export PATH="$HOME/.local/bin:$PATH" +``` + +### Option 3: Docker + +Run PicoClaw in a container without installing anything locally. + +```bash +# Clone the repository +git clone https://github.com/sipeed/picoclaw.git +cd picoclaw + +# Configure +cp config/config.example.json config/config.json +# Edit config/config.json with your API keys + +# Start gateway mode +docker compose --profile gateway up -d + +# Or run agent mode (one-shot) +docker compose run --rm picoclaw-agent -m "Hello!" + +# Interactive mode +docker compose run --rm picoclaw-agent +``` + +See [Docker Deployment](../deployment/docker.md) for more details. + +### Option 4: Android/Termux + +Run PicoClaw on old Android phones using Termux. + +```bash +# Install Termux from F-Droid or Google Play +# Open Termux and run: + +VERSION="v0.1.2" + +# Download binary +wget https://github.com/sipeed/picoclaw/releases/download/${VERSION}/picoclaw_Linux_arm64.tar.gz +tar -xzf picoclaw_Linux_arm64.tar.gz +chmod +x picoclaw + +# Install proot for chroot environment +pkg install proot + +# Initialize +termux-chroot ./picoclaw onboard +``` + +See [Termux Deployment](../deployment/termux.md) for more details. + +## Verify Installation + +After installing, verify PicoClaw is working: + +```bash +# Check version +picoclaw version + +# Check status +picoclaw status +``` + +## Next Steps + +1. [Quick Start](quick-start.md) - Configure and run your first chat +2. [Configuration Basics](configuration-basics.md) - Understand the config structure +3. [Get API Keys](quick-start.md#get-api-keys) - Set up your LLM provider + +## Supported Platforms + +PicoClaw runs on a wide range of hardware: + +| Hardware | Cost | Notes | +|----------|------|-------| +| Any Linux x86_64 | Varies | Most common | +| Raspberry Pi | $35+ | ARM64 support | +| LicheeRV Nano | $9.9 | RISC-V, ultra-low cost | +| MaixCAM | $50 | AI camera | +| NanoKVM | $30-100 | Server maintenance | +| Android phones | Free (old) | Via Termux | +| macOS | $500+ | M1/M2/M3/M4 native | +| FreeBSD servers | Varies | Server deployment | + +## Troubleshooting + +### Permission denied + +```bash +chmod +x picoclaw +``` + +### Command not found + +Make sure the binary is in your PATH: +```bash +# Add to PATH temporarily +export PATH="$PWD:$PATH" + +# Or move to a standard location +sudo mv picoclaw /usr/local/bin/ +``` + +### Go version too old + +PicoClaw requires Go 1.21 or later: +```bash +go version +# Upgrade Go if needed +``` + +### Docker issues + +See [Docker Deployment](../deployment/docker.md) for troubleshooting Docker-specific issues. diff --git a/docs/getting-started/quick-start.md b/docs/getting-started/quick-start.md new file mode 100644 index 0000000000..b29cadca88 --- /dev/null +++ b/docs/getting-started/quick-start.md @@ -0,0 +1,211 @@ +# Quick Start + +Get PicoClaw running in 5 minutes with this step-by-step guide. + +## Prerequisites + +- PicoClaw installed (see [Installation](installation.md)) +- An API key from an LLM provider + +## Step 1: Initialize + +Run the onboard command to set up the default configuration: + +```bash +picoclaw onboard +``` + +This creates: +- `~/.picoclaw/config.json` - Main configuration file +- `~/.picoclaw/workspace/` - Working directory for the agent + +## Step 2: Get API Keys + +You need at least one LLM provider API key. + +### Recommended: OpenRouter + +[OpenRouter](https://openrouter.ai/keys) provides access to many models with a free tier. + +1. Go to [openrouter.ai/keys](https://openrouter.ai/keys) +2. Sign in and create an API key +3. Copy the key (starts with `sk-or-v1-`) + +### Alternative: Zhipu (Chinese Users) + +[Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) offers Chinese AI models. + +1. Go to [bigmodel.cn](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) +2. Register and create an API key +3. Copy the key + +### Other Providers + +| Provider | Get API Key | Notes | +|----------|-------------|-------| +| [Anthropic](https://console.anthropic.com) | Claude models | | +| [OpenAI](https://platform.openai.com) | GPT models | | +| [Gemini](https://aistudio.google.com) | Google models | Free tier available | +| [Groq](https://console.groq.com) | Fast inference | Free tier + voice transcription | +| [DeepSeek](https://platform.deepseek.com) | DeepSeek models | | + +## Step 3: Configure + +Edit `~/.picoclaw/config.json` and add your API key: + +### Using OpenRouter + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "anthropic/claude-opus-4-5", + "max_tokens": 8192, + "temperature": 0.7, + "max_tool_iterations": 20 + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-YOUR-API-KEY-HERE", + "api_base": "https://openrouter.ai/api/v1" + } + } +} +``` + +### Using Zhipu + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "glm-4.7", + "max_tokens": 8192, + "temperature": 0.7, + "max_tool_iterations": 20 + } + }, + "providers": { + "zhipu": { + "api_key": "YOUR-ZHIPU-API-KEY-HERE", + "api_base": "https://open.bigmodel.cn/api/paas/v4" + } + } +} +``` + +## Step 4: Chat + +Now you're ready to chat with PicoClaw! + +### One-shot Message + +```bash +picoclaw agent -m "What is 2+2?" +``` + +### Interactive Mode + +```bash +picoclaw agent +``` + +This starts an interactive chat session where you can have a continuous conversation. + +### Debug Mode + +For troubleshooting: + +```bash +picoclaw agent --debug -m "Hello" +``` + +## Optional: Enable Web Search + +PicoClaw can search the web. DuckDuckGo is enabled by default (no API key needed). + +For better results, get a free [Brave Search API](https://brave.com/search/api) key (2000 queries/month): + +```json +{ + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "YOUR_BRAVE_API_KEY", + "max_results": 5 + }, + "duckduckgo": { + "enabled": true, + "max_results": 5 + } + } + } +} +``` + +## Optional: Connect to Chat Apps + +To use PicoClaw with Telegram, Discord, or other chat platforms: + +### Telegram + +1. Create a bot via [@BotFather](https://t.me/BotFather) +2. Get your user ID from [@userinfobot](https://t.me/userinfobot) +3. Configure: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + } + } +} +``` + +4. Start the gateway: + +```bash +picoclaw gateway +``` + +See [Telegram Setup](../user-guide/channels/telegram.md) for detailed instructions. + +### Discord + +See [Discord Setup](../user-guide/channels/discord.md) for detailed instructions. + +## Next Steps + +- [Configuration Basics](configuration-basics.md) - Learn about all config options +- [CLI Reference](../user-guide/cli-reference.md) - All commands and flags +- [Workspace Guide](../user-guide/workspace/structure.md) - Customize agent behavior +- [Tools Overview](../user-guide/tools/README.md) - Available tools + +## Troubleshooting + +### Web search shows "API configuration error" + +This is normal without a Brave API key. DuckDuckGo fallback works automatically. To enable Brave search, add your API key to the config. + +### Content filtering errors + +Some providers have content filtering. Try: +- Rephrasing your query +- Using a different model +- Switching to a different provider + +### Model not found + +Make sure the model name is correct: +- OpenRouter: Use format like `anthropic/claude-opus-4-5` +- Zhipu: Use `glm-4.7`, `glm-4-plus`, etc. +- OpenAI: Use `gpt-4`, `gpt-4o`, etc. + +See the [Troubleshooting Guide](../operations/troubleshooting.md) for more solutions. diff --git a/docs/operations/device-monitoring.md b/docs/operations/device-monitoring.md new file mode 100644 index 0000000000..17b0cb99c2 --- /dev/null +++ b/docs/operations/device-monitoring.md @@ -0,0 +1,366 @@ +# USB Device Monitoring + +Monitor and manage USB devices connected to your PicoClaw system. + +## Overview + +PicoClaw can monitor USB devices for: +- Device connection/disconnection events +- Serial port availability +- Hardware health status +- Automated device-specific actions + +## Use Cases + +- **IoT deployments**: Monitor sensors and actuators +- **Edge devices**: Track connected hardware +- **Automation**: Trigger actions on device events +- **Debugging**: Track device issues in the field + +## Device Detection + +### List Connected Devices + +Use the CLI to check connected devices: + +```bash +picoclaw status --devices +``` + +### USB Device Events + +PicoClaw can log USB device changes. Enable in configuration: + +```json +{ + "devices": { + "usb_monitor": { + "enabled": true, + "log_events": true, + "watch": [ + {"vendor_id": "10c4", "product_id": "ea60"}, + {"vendor_id": "0403", "product_id": "6001"} + ] + } + } +} +``` + +## Serial Port Monitoring + +### Configuration + +```json +{ + "devices": { + "serial": { + "enabled": true, + "ports": [ + { + "path": "/dev/ttyUSB0", + "name": "sensor_node", + "baud_rate": 115200 + }, + { + "path": "/dev/ttyACM0", + "name": "arduino", + "baud_rate": 9600 + } + ] + } + } +} +``` + +### Serial Port Options + +| Option | Type | Description | +|--------|------|-------------| +| `path` | string | Device path (e.g., `/dev/ttyUSB0`) | +| `name` | string | Friendly name for reference | +| `baud_rate` | int | Communication speed | +| `data_bits` | int | Data bits (default: 8) | +| `stop_bits` | int | Stop bits (default: 1) | +| `parity` | string | Parity: `none`, `even`, `odd` | +| `timeout` | int | Read timeout in seconds | + +### Detecting Serial Ports + +```bash +# List all serial ports +ls /dev/tty* | grep -E '(USB|ACM)' + +# Using picocom to test +picocom -b 115200 /dev/ttyUSB0 + +# Using screen +screen /dev/ttyUSB0 115200 +``` + +## Device Hotplug + +### Linux udev Rules + +Create udev rules for consistent device naming: + +```bash +# /etc/udev/rules.d/99-picoclaw.rules + +# USB serial device with specific vendor/product +SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="picoclaw_sensor" + +# Arduino boards +SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", SYMLINK+="picoclaw_arduino" + +# Set permissions +SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", MODE="0666" +``` + +Apply rules: + +```bash +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +### Device Permissions + +Add your user to required groups: + +```bash +# For serial ports +sudo usermod -aG dialout $USER + +# For USB devices +sudo usermod -aG plugdev $USER + +# Logout and login for changes to take effect +``` + +## Hardware Health Monitoring + +### System Sensors + +Monitor system health with lm-sensors: + +```bash +# Install lm-sensors +sudo apt install lm-sensors + +# Detect sensors +sudo sensors-detect + +# View readings +sensors +``` + +### Agent Integration + +Configure PicoClaw to use hardware data: + +``` +User: "What's the system temperature?" + +Agent uses exec tool to run `sensors` and reports: +"Current CPU temperature: 45.2°C" +``` + +### I2C Device Monitoring + +Monitor I2C-connected sensors: + +```json +{ + "devices": { + "i2c": { + "enabled": true, + "bus": 1, + "devices": [ + { + "address": "0x76", + "name": "bme280", + "type": "sensor", + "interval": "60s" + } + ] + } + } +} +``` + +## USB Device Information + +### Using lsusb + +```bash +# List all USB devices +lsusb + +# Verbose output for specific device +lsusb -v -d 10c4:ea60 + +# Show device tree +lsusb -t +``` + +### Using usb-devices + +```bash +# Detailed device information +usb-devices +``` + +### Common USB Serial Chips + +| Vendor ID | Product ID | Description | +|-----------|------------|-------------| +| `10c4` | `ea60` | CP210x (common USB-UART) | +| `0403` | `6001` | FTDI FT232 | +| `2341` | `0043` | Arduino Uno | +| `2341` | `0010` | Arduino Mega | +| `1a86` | `7523` | CH340 (cheap clones) | + +## Troubleshooting + +### Device Not Detected + +1. Check physical connection +2. Verify driver is loaded: + ```bash + lsmod | grep usbserial + ``` +3. Check dmesg for errors: + ```bash + dmesg | grep -i usb + ``` + +### Permission Denied + +```bash +# Check device permissions +ls -la /dev/ttyUSB0 + +# Temporary fix +sudo chmod 666 /dev/ttyUSB0 + +# Permanent fix (add to dialout group) +sudo usermod -aG dialout $USER +``` + +### Device Disconnects Randomly + +1. Check power supply (insufficient power can cause disconnects) +2. Check USB cable quality +3. Disable USB autosuspend: + ```bash + echo -1 | sudo tee /sys/module/usbcore/parameters/autosuspend + ``` + +### Multiple Same Devices + +Use udev rules to create persistent symlinks based on serial number: + +```bash +# Get device serial +udevadm info -a -n /dev/ttyUSB0 | grep serial + +# Create symlink by serial +SUBSYSTEM=="tty", ATTRS{serial}=="12345", SYMLINK+="device_a" +``` + +## Monitoring Scripts + +### Continuous Device Monitor + +Create a monitoring script: + +```bash +#!/bin/bash +# /usr/local/bin/usb-monitor.sh + +while true; do + echo "=== $(date) ===" + lsusb + echo "Serial ports:" + ls -la /dev/tty* 2>/dev/null | grep -E '(USB|ACM)' + echo "" + sleep 60 +done +``` + +### Alert on Device Disconnection + +```bash +#!/bin/bash +# Alert when device disappears + +DEVICE="/dev/ttyUSB0" + +if [ ! -e "$DEVICE" ]; then + echo "ALERT: Device $DEVICE not found!" + # Send notification + # curl -X POST webhook_url -d "Device $DEVICE disconnected" + exit 1 +fi +``` + +## Integration with PicoClaw + +### Reading Sensor Data + +``` +User: "Read the temperature from the BME280 sensor" + +Agent: +1. Uses i2c tool to detect devices +2. Reads from address 0x76 +3. Parses sensor data +4. Returns: "Temperature: 23.5°C, Humidity: 65%, Pressure: 1013 hPa" +``` + +### Controlling Serial Devices + +``` +User: "Send the reset command to the Arduino" + +Agent: +1. Uses exec tool: stty -F /dev/ttyACM0 9600 +2. Echoes command: echo "RESET" > /dev/ttyACM0 +3. Reads response: cat /dev/ttyACM0 +4. Returns: "Arduino reset successfully" +``` + +### Automated Monitoring + +Use cron tools for periodic checks: + +```json +{ + "cron": { + "jobs": [ + { + "name": "check_sensors", + "schedule": "*/5 * * * *", + "prompt": "Check if all I2C sensors are responding and report any issues" + } + ] + } +} +``` + +## Best Practices + +1. **Use udev rules** for consistent device naming +2. **Monitor device health** with periodic checks +3. **Log device events** for troubleshooting +4. **Set up alerts** for critical devices +5. **Document device mappings** in your configuration +6. **Use quality cables** to prevent connection issues +7. **Consider power requirements** for USB devices + +## See Also + +- [Hardware Tools](../user-guide/tools/hardware.md) +- [I2C and SPI](../user-guide/tools/hardware.md) +- [Cron and Scheduled Tasks](../user-guide/tools/cron.md) +- [MaixCam Integration](../user-guide/channels/maixcam.md) diff --git a/docs/operations/health-endpoints.md b/docs/operations/health-endpoints.md new file mode 100644 index 0000000000..61b77700e0 --- /dev/null +++ b/docs/operations/health-endpoints.md @@ -0,0 +1,283 @@ +# Health Check Endpoints + +PicoClaw provides health check endpoints for monitoring system status when running in gateway mode. + +## Overview + +Health endpoints allow you to monitor PicoClaw's operational status, which is essential for: + +- Load balancer health checks +- Container orchestration (Kubernetes, Docker Swarm) +- Monitoring systems (Prometheus, Nagios) +- Automated alerting + +## Endpoints + +### Health Check + +**Endpoint:** `GET /health` + +Returns the overall health status of the PicoClaw gateway. + +```bash +curl http://localhost:18790/health +``` + +**Response (Healthy):** +```json +{ + "status": "healthy", + "timestamp": "2024-01-15T10:30:00Z", + "version": "1.0.0", + "uptime": "2h30m15s" +} +``` + +**Response (Unhealthy):** +```json +{ + "status": "unhealthy", + "timestamp": "2024-01-15T10:30:00Z", + "version": "1.0.0", + "uptime": "2h30m15s", + "issues": [ + "provider_connection_failed", + "redis_unavailable" + ] +} +``` + +### Readiness Check + +**Endpoint:** `GET /ready` + +Returns whether PicoClaw is ready to accept requests. + +```bash +curl http://localhost:18790/ready +``` + +**Response (Ready):** +```json +{ + "ready": true, + "checks": { + "config_loaded": true, + "providers_initialized": true, + "channels_connected": true + } +} +``` + +**Response (Not Ready):** +```json +{ + "ready": false, + "checks": { + "config_loaded": true, + "providers_initialized": false, + "channels_connected": false + } +} +``` + +### Liveness Check + +**Endpoint:** `GET /live` + +Simple endpoint to verify the process is running. + +```bash +curl http://localhost:18790/live +``` + +**Response:** +```json +{ + "alive": true +} +``` + +## Configuration + +Configure health endpoints in your config file: + +```json +{ + "gateway": { + "port": 18790, + "health_check": { + "enabled": true, + "path": "/health", + "port": 18791 + } + } +} +``` + +### Options + +| Option | Default | Description | +|--------|---------|-------------| +| `enabled` | `true` | Enable health check endpoints | +| `path` | `/health` | Base path for health checks | +| `port` | Same as gateway | Separate port for health checks | + +## Usage Examples + +### Kubernetes Liveness Probe + +```yaml +livenessProbe: + httpGet: + path: /live + port: 18790 + initialDelaySeconds: 10 + periodSeconds: 30 +``` + +### Kubernetes Readiness Probe + +```yaml +readinessProbe: + httpGet: + path: /ready + port: 18790 + initialDelaySeconds: 5 + periodSeconds: 10 +``` + +### Docker Compose Health Check + +```yaml +services: + picoclaw: + image: picoclaw:latest + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:18790/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s +``` + +### Prometheus Blackbox Exporter + +```yaml +modules: + http_2xx: + prober: http + http: + valid_status_codes: [200] + preferred_ip_protocol: ip4 +``` + +```yaml +scrape_configs: + - job_name: 'picoclaw_health' + metrics_path: /probe + params: + module: [http_2xx] + targets: + - http://localhost:18790/health +``` + +### Load Balancer (nginx) + +```nginx +upstream picoclaw { + server 127.0.0.1:18790; +} + +server { + location /health { + proxy_pass http://picoclaw/health; + access_log off; + } +} +``` + +### HAProxy + +``` +backend picoclaw + option httpchk GET /health + http-check expect status 200 + server picoclaw1 127.0.0.1:18790 check +``` + +## Status Codes + +| Code | Meaning | +|------|---------| +| 200 | Healthy/Ready/Alive | +| 503 | Unhealthy/Not Ready | + +## Detailed Status + +For more detailed diagnostics, use the CLI status command: + +```bash +picoclaw status +``` + +This provides comprehensive information about: +- All configured providers and their status +- Active channel connections +- Session statistics +- System resources + +## Monitoring Integration + +### Datadog + +```yaml +# datadog.yaml +instances: + - url: http://localhost:18790/health + name: PicoClaw + tags: + - service:picoclaw +``` + +### New Relic + +```yaml +# newrelic.yml +synthetics: + - name: PicoClaw Health + url: http://localhost:18790/health + verify_ssl: false +``` + +### Grafana + Prometheus + +Use the blackbox exporter with Grafana dashboards for visual monitoring. + +## Troubleshooting + +### Endpoints not responding + +1. Check gateway is running: + ```bash + picoclaw gateway --debug + ``` + +2. Verify port is accessible: + ```bash + curl -v http://localhost:18790/health + ``` + +3. Check firewall rules + +### Returns 503 status + +1. Check provider configuration +2. Verify API keys are valid +3. Check network connectivity to providers + +## See Also + +- [Monitoring Guide](monitoring.md) +- [Troubleshooting](troubleshooting.md) +- [Docker Deployment](../deployment/docker.md) diff --git a/docs/operations/logging.md b/docs/operations/logging.md new file mode 100644 index 0000000000..87ae3a142e --- /dev/null +++ b/docs/operations/logging.md @@ -0,0 +1,426 @@ +# Log Management + +This guide covers log configuration, collection, and analysis for PicoClaw. + +## Overview + +PicoClaw provides structured logging with multiple output formats and levels. Proper log management helps with: + +- Debugging issues +- Security auditing +- Performance analysis +- Compliance requirements + +## Log Levels + +| Level | Description | +|-------|-------------| +| `debug` | Detailed debugging information | +| `info` | General operational messages | +| `warn` | Warning conditions | +| `error` | Error conditions | + +## Configuration + +### Basic Configuration + +```json +{ + "logging": { + "level": "info", + "format": "json", + "output": "stdout" + } +} +``` + +### Configuration Options + +| Option | Default | Description | +|--------|---------|-------------| +| `level` | `info` | Minimum log level | +| `format` | `json` | Output format (`json`, `text`) | +| `output` | `stdout` | Output destination (`stdout`, `stderr`, file path) | +| `max_size` | `100` | Max log file size in MB (for file output) | +| `max_backups` | `3` | Max number of old log files | +| `max_age` | `28` | Max days to retain logs | +| `compress` | `true` | Compress rotated logs | + +### Environment Variables + +```bash +export PICOCLAW_LOGGING_LEVEL=debug +export PICOCLAW_LOGGING_FORMAT=json +export PICOCLAW_LOGGING_OUTPUT=/var/log/picoclaw/app.log +``` + +## Log Formats + +### JSON Format (Recommended) + +```json +{ + "time": "2024-01-15T10:30:00.123Z", + "level": "info", + "component": "agent", + "message": "Processing message", + "session_id": "abc123", + "duration_ms": 1234, + "model": "claude-opus-4-5" +} +``` + +### Text Format + +``` +2024-01-15T10:30:00.123Z INFO agent Processing message session_id=abc123 duration_ms=1234 +``` + +## Log Components + +PicoClaw organizes logs by component: + +| Component | Description | +|-----------|-------------| +| `main` | Application startup/shutdown | +| `config` | Configuration loading | +| `agent` | Agent loop and message processing | +| `provider` | LLM provider interactions | +| `channel` | Chat platform integrations | +| `tool` | Tool execution | +| `session` | Session management | +| `bus` | Message bus activity | +| `cron` | Scheduled tasks | + +## Command Line Options + +### Debug Mode + +Enable verbose logging: + +```bash +picoclaw agent --debug -m "Hello" +picoclaw gateway --debug +``` + +### Verbose Output + +```bash +picoclaw agent -v -m "Hello" +picoclaw gateway -vv +``` + +| Flag | Level | +|------|-------| +| (none) | info | +| `-v` | info (verbose) | +| `-vv` | debug | +| `--debug` | debug (with stack traces) | + +## File Logging + +### Configuration + +```json +{ + "logging": { + "level": "info", + "format": "json", + "output": "/var/log/picoclaw/picoclaw.log", + "max_size": 100, + "max_backups": 5, + "max_age": 30, + "compress": true + } +} +``` + +### Directory Setup + +```bash +# Create log directory +sudo mkdir -p /var/log/picoclaw +sudo chown $USER:$USER /var/log/picoclaw +``` + +### Log Rotation + +PicoClaw handles log rotation automatically when configured for file output. Alternatively, use logrotate: + +```bash +# /etc/logrotate.d/picoclaw +/var/log/picoclaw/*.log { + daily + missingok + rotate 7 + compress + delaycompress + notifempty + create 0640 $USER $USER + sharedscripts + postrotate + systemctl reload picoclaw > /dev/null 2>&1 || true + endscript +} +``` + +## Log Collection + +### Fluentd/Fluent Bit + +```yaml +# fluent-bit.conf +[INPUT] + Name tail + Path /var/log/picoclaw/picoclaw.log + Tag picoclaw + +[FILTER] + Name parser + Match picoclaw* + Key_Name log + Parser json + +[OUTPUT] + Name elasticsearch + Match picoclaw* + Host elasticsearch + Port 9200 +``` + +### Logstash + +```ruby +# logstash.conf +input { + file { + path => "/var/log/picoclaw/picoclaw.log" + codec => json + type => "picoclaw" + } +} + +filter { + if [type] == "picoclaw" { + date { + match => [ "time", "ISO8601" ] + } + } +} + +output { + elasticsearch { + hosts => ["localhost:9200"] + index => "picoclaw-%{+YYYY.MM.dd}" + } +} +``` + +### Loki/Promtail + +```yaml +# promtail.yml +scrape_configs: + - job_name: picoclaw + static_configs: + - targets: + - localhost + labels: + job: picoclaw + __path__: /var/log/picoclaw/*.log + pipeline_stages: + - json: + expressions: + level: level + component: component + message: message + - labels: + level: + component: +``` + +## Systemd Journal + +When running as a systemd service, logs go to journald: + +```bash +# View logs +journalctl -u picoclaw + +# Follow logs +journalctl -u picoclaw -f + +# Filter by level +journalctl -u picoclaw -p err + +# Filter by time +journalctl -u picoclaw --since "1 hour ago" +``` + +### Journald Configuration + +```bash +# /etc/systemd/journald.conf +[Journal] +Storage=persistent +Compress=yes +MaxRetentionSec=1month +``` + +## Docker Logging + +### Default Configuration + +```bash +docker run picoclaw:latest +``` + +Logs go to Docker's logging driver (json-file by default). + +### Docker Compose + +```yaml +services: + picoclaw: + image: picoclaw:latest + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" +``` + +### Send to External System + +```yaml +services: + picoclaw: + image: picoclaw:latest + logging: + driver: "syslog" + options: + syslog-address: "tcp://logserver:514" + syslog-facility: "daemon" + tag: "picoclaw" +``` + +## Log Analysis + +### Common Queries + +#### Error Count + +```bash +grep -c '"level":"error"' /var/log/picoclaw/picoclaw.log +``` + +#### Recent Errors + +```bash +grep '"level":"error"' /var/log/picoclaw/picoclaw.log | tail -20 +``` + +#### Provider Errors + +```bash +grep '"component":"provider"' /var/log/picoclaw/picoclaw.log | grep '"level":"error"' +``` + +#### Slow Requests + +```bash +jq 'select(.duration_ms > 5000)' /var/log/picoclaw/picoclaw.log +``` + +### Using jq + +```bash +# Parse and pretty print +cat picoclaw.log | jq '.' + +# Filter by level +cat picoclaw.log | jq 'select(.level == "error")' + +# Filter by component +cat picoclaw.log | jq 'select(.component == "agent")' + +# Extract specific fields +cat picoclaw.log | jq '{time, level, message}' + +# Count by level +cat picoclaw.log | jq -r '.level' | sort | uniq -c +``` + +## Security and Privacy + +### Redacting Sensitive Data + +PicoClaw automatically redacts: +- API keys (masked as `***`) +- Authentication tokens +- Passwords + +### Manual Redaction + +```bash +# Redact API keys before sharing logs +sed -E 's/sk-[a-zA-Z0-9_-]+/sk-***/g' picoclaw.log > redacted.log +``` + +### Log Access Control + +```bash +# Restrict log file access +chmod 640 /var/log/picoclaw/picoclaw.log +chown root:picoclaw /var/log/picoclaw/picoclaw.log +``` + +## Debugging with Logs + +### Enable Debug Mode + +```json +{ + "logging": { + "level": "debug" + } +} +``` + +### Trace a Session + +```bash +# Find all logs for a session +grep '"session_id":"abc123"' /var/log/picoclaw/picoclaw.log +``` + +### Analyze Tool Calls + +```bash +# All tool executions +grep '"component":"tool"' /var/log/picoclaw/picoclaw.log | jq '.' +``` + +### Provider Issues + +```bash +# Provider connection issues +grep '"component":"provider"' /var/log/picoclaw/picoclaw.log | grep -E '(error|warn)' +``` + +## Best Practices + +1. **Use JSON format** - Easier to parse and analyze +2. **Set appropriate levels** - Use `info` for production, `debug` for troubleshooting +3. **Configure rotation** - Prevent disk space issues +4. **Centralize logs** - Use a log aggregation system +5. **Monitor error rates** - Set up alerts for error spikes +6. **Secure logs** - Restrict access and redact sensitive data +7. **Archive old logs** - Keep historical data for analysis + +## See Also + +- [Monitoring Guide](monitoring.md) +- [Troubleshooting](troubleshooting.md) +- [Health Endpoints](health-endpoints.md) +- [Security Configuration](../deployment/security.md) diff --git a/docs/operations/monitoring.md b/docs/operations/monitoring.md new file mode 100644 index 0000000000..2876e04cc3 --- /dev/null +++ b/docs/operations/monitoring.md @@ -0,0 +1,351 @@ +# Monitoring Setup Guide + +This guide covers how to monitor PicoClaw in production environments. + +## Overview + +Effective monitoring helps you: +- Track system health and performance +- Detect issues before they impact users +- Understand usage patterns +- Plan capacity + +## Monitoring Components + +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ PicoClaw │───>│ Prometheus │───>│ Grafana │ +│ Gateway │ │ (Metrics) │ │ (Dashboard) │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ + │ + v +┌─────────────────┐ ┌─────────────────┐ +│ Health │───>│ Alerting │ +│ Endpoints │ │ System │ +└─────────────────┘ └─────────────────┘ +``` + +## Metrics Collection + +### Prometheus Integration + +PicoClaw exposes metrics in Prometheus format at `/metrics`: + +```bash +curl http://localhost:18790/metrics +``` + +**Available Metrics:** + +| Metric | Type | Description | +|--------|------|-------------| +| `picoclaw_messages_total` | Counter | Total messages processed | +| `picoclaw_messages_active` | Gauge | Currently active conversations | +| `picoclaw_tool_calls_total` | Counter | Tool invocations by type | +| `picoclaw_provider_requests_total` | Counter | Provider API requests | +| `picoclaw_provider_errors_total` | Counter | Provider API errors | +| `picoclaw_session_count` | Gauge | Active sessions | +| `picoclaw_response_time_seconds` | Histogram | Response latency | + +### Prometheus Configuration + +```yaml +# prometheus.yml +scrape_configs: + - job_name: 'picoclaw' + static_configs: + - targets: ['localhost:18790'] + scrape_interval: 15s + metrics_path: /metrics +``` + +### Enable Metrics + +Add to your configuration: + +```json +{ + "gateway": { + "metrics": { + "enabled": true, + "path": "/metrics" + } + } +} +``` + +## Grafana Dashboards + +### Sample Dashboard Configuration + +Import this dashboard configuration: + +```json +{ + "dashboard": { + "title": "PicoClaw Monitoring", + "panels": [ + { + "title": "Messages per Minute", + "type": "graph", + "targets": [ + { + "expr": "rate(picoclaw_messages_total[1m])", + "legendFormat": "Messages/min" + } + ] + }, + { + "title": "Response Time", + "type": "graph", + "targets": [ + { + "expr": "histogram_quantile(0.95, rate(picoclaw_response_time_seconds_bucket[5m]))", + "legendFormat": "p95 Latency" + } + ] + }, + { + "title": "Provider Errors", + "type": "graph", + "targets": [ + { + "expr": "rate(picoclaw_provider_errors_total[5m])", + "legendFormat": "{{provider}}" + } + ] + }, + { + "title": "Active Sessions", + "type": "stat", + "targets": [ + { + "expr": "picoclaw_session_count", + "legendFormat": "Sessions" + } + ] + } + ] + } +} +``` + +## Alerting + +### Prometheus Alert Rules + +```yaml +# alerts.yml +groups: + - name: picoclaw + rules: + - alert: PicoClawDown + expr: up{job="picoclaw"} == 0 + for: 1m + labels: + severity: critical + annotations: + summary: "PicoClaw is down" + description: "PicoClaw instance has been down for more than 1 minute." + + - alert: HighErrorRate + expr: rate(picoclaw_provider_errors_total[5m]) > 0.1 + for: 5m + labels: + severity: warning + annotations: + summary: "High provider error rate" + description: "Provider {{ $labels.provider }} has high error rate." + + - alert: SlowResponses + expr: histogram_quantile(0.95, rate(picoclaw_response_time_seconds_bucket[5m])) > 30 + for: 5m + labels: + severity: warning + annotations: + summary: "Slow response times" + description: "P95 response time exceeds 30 seconds." + + - alert: HighMemoryUsage + expr: process_resident_memory_bytes{job="picoclaw"} > 52428800 + for: 5m + labels: + severity: warning + annotations: + summary: "High memory usage" + description: "PicoClaw is using more than 50MB of memory." +``` + +### Alertmanager Configuration + +```yaml +# alertmanager.yml +route: + receiver: 'team-notifications' + group_by: ['alertname', 'severity'] + group_wait: 30s + group_interval: 5m + repeat_interval: 4h + +receivers: + - name: 'team-notifications' + slack_configs: + - api_url: 'https://hooks.slack.com/services/xxx' + channel: '#alerts' + title: '{{ .GroupLabels.alertname }}' + text: '{{ .CommonAnnotations.description }}' +``` + +## Health Checks + +### HTTP Health Monitoring + +Use external services to monitor health endpoints: + +```bash +# Simple health check +curl -f http://localhost:18790/health || exit 1 + +# Detailed health check with jq +curl -s http://localhost:18790/health | jq -r '.status' | grep -q "healthy" || exit 1 +``` + +### Cron-based Monitoring + +```bash +# /etc/cron.d/picoclaw-monitor +*/5 * * * * root curl -f http://localhost:18790/health || /usr/local/bin/alert-script.sh +``` + +## Log-based Monitoring + +### Structured Logging + +PicoClaw outputs structured logs that can be parsed: + +```json +{ + "time": "2024-01-15T10:30:00Z", + "level": "info", + "component": "agent", + "message": "Processing message", + "session_id": "abc123", + "duration_ms": 1234 +} +``` + +### Log Aggregation + +For Loki/Grafana stack: + +```yaml +# loki/promtail.yml +clients: + - url: http://localhost:3100/loki/api/v1/push + +scrape_configs: + - job_name: picoclaw + static_configs: + - targets: + - localhost + labels: + job: picoclaw + __path__: /var/log/picoclaw/*.log +``` + +## System Metrics + +### Process Monitoring + +Monitor PicoClaw process directly: + +```bash +# CPU and memory usage +ps aux | grep picoclaw + +# Open file descriptors +lsof -p $(pgrep picoclaw) | wc -l + +# Network connections +netstat -an | grep 18790 +``` + +### Resource Limits + +Set appropriate limits: + +```bash +# Systemd service with limits +[Service] +ExecStart=/usr/local/bin/picoclaw gateway +LimitNOFILE=65535 +MemoryMax=100M +CPUQuota=50% +``` + +## Monitoring Checklist + +### Basic Monitoring + +- [ ] Health endpoint checks (every 30 seconds) +- [ ] Process uptime monitoring +- [ ] Log error rate monitoring +- [ ] API response time tracking + +### Advanced Monitoring + +- [ ] Provider latency and error rates +- [ ] Message throughput metrics +- [ ] Session count trends +- [ ] Memory usage over time +- [ ] Tool call success rates + +### Alerting Setup + +- [ ] Service down alerts +- [ ] High error rate alerts +- [ ] Slow response alerts +- [ ] Resource usage alerts + +## Third-party Integrations + +### Datadog + +```yaml +# datadog.yaml +instances: + - url: http://localhost:18790/health + name: PicoClaw + tags: + - env:production + - service:picoclaw + collect_response_time: true +``` + +### New Relic + +```yaml +# newrelic-infra.yml +integrations: + - name: nri-flex + config: + name: picoclawHealth + apis: + - name: health + url: http://localhost:18790/health +``` + +### Uptime Kuma + +Add PicoClaw as a monitored service: +1. Create new monitor +2. URL: `http://your-server:18790/health` +3. Expected status: 200 + +## See Also + +- [Health Endpoints](health-endpoints.md) +- [Logging Guide](logging.md) +- [Troubleshooting](troubleshooting.md) +- [Docker Deployment](../deployment/docker.md) diff --git a/docs/operations/troubleshooting.md b/docs/operations/troubleshooting.md new file mode 100644 index 0000000000..6a38394e38 --- /dev/null +++ b/docs/operations/troubleshooting.md @@ -0,0 +1,426 @@ +# Troubleshooting + +This guide covers common issues and their solutions when using PicoClaw. + +## Installation Issues + +### Binary won't execute (Permission denied) + +**Error:** +``` +bash: ./picoclaw-*: Permission denied +``` + +**Solution:** +```bash +chmod +x picoclaw-* +``` + +### Command not found + +**Error:** +``` +bash: picoclaw: command not found +``` + +**Solution:** + +Make sure the binary is in your PATH: +```bash +# Add current directory to PATH temporarily +export PATH="$PWD:$PATH" + +# Or move to a standard location +sudo mv picoclaw-* /usr/local/bin/picoclaw +``` + +### Go version too old + +**Error:** +``` +go: cannot use Go 1.20, requires Go 1.21 or later +``` + +**Solution:** +```bash +# Check your Go version +go version + +# Upgrade Go to 1.21 or later from https://go.dev/dl/ +``` + +### Docker issues + +**Error:** +``` +Cannot connect to the Docker daemon +``` + +**Solution:** +Ensure Docker is running and you have permissions: +```bash +# Start Docker service +sudo systemctl start docker + +# Add your user to docker group (requires logout/login) +sudo usermod -aG docker $USER +``` + +## Configuration Issues + +### Config file not found + +**Error:** +``` +Error loading config: open ~/.picoclaw/config.json: no such file or directory +``` + +**Solution:** +Run the onboard command to create the default configuration: +```bash +picoclaw onboard +``` + +### Invalid JSON in config + +**Error:** +``` +Error loading config: invalid character '}' looking for beginning of value +``` + +**Solution:** +Validate your JSON syntax. Common issues: +- Missing commas between fields +- Trailing commas +- Unquoted strings + +Use a JSON validator or: +```bash +cat ~/.picoclaw/config.json | python3 -m json.tool +``` + +## Provider Issues + +### No API key configured + +**Error:** +``` +Error creating provider: no API key configured +``` + +**Solution:** +Add your API key to `~/.picoclaw/config.json`: +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + } +} +``` + +Or use environment variable: +```bash +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" +``` + +### Model not found + +**Error:** +``` +Error: model 'xxx' not found +``` + +**Solution:** +Use the correct model name format: +- OpenRouter: `anthropic/claude-opus-4-5`, `openai/gpt-4o` +- Zhipu: `glm-4.7`, `glm-4-plus` +- OpenAI: `gpt-4`, `gpt-4o` +- Anthropic: `claude-opus-4-5`, `claude-sonnet-4` + +### Rate limit exceeded + +**Error:** +``` +Error: rate limit exceeded +``` + +**Solution:** +1. Wait and retry +2. Set up fallback models: +```json +{ + "agents": { + "defaults": { + "model": "primary-model", + "model_fallbacks": ["backup-model-1", "backup-model-2"] + } + } +} +``` + +### Content filtering errors + +**Error:** +``` +Error: content filtered +``` + +**Solution:** +Some providers have content filtering. Try: +1. Rephrasing your query +2. Using a different model +3. Switching to a different provider + +## Channel Issues + +### Telegram: Conflict error + +**Error:** +``` +Conflict: terminated by other getUpdates request +``` + +**Solution:** +Only one instance can use the bot token at a time: +1. Stop other running instances of the bot +2. Make sure only one `picoclaw gateway` is running + +### Telegram: Bot not responding + +**Possible causes:** + +1. Bot not enabled: +```json +{ + "channels": { + "telegram": { + "enabled": true + } + } +} +``` + +2. User not in allow list: +```json +{ + "channels": { + "telegram": { + "allow_from": ["123456789"] + } + } +} +``` + +3. Gateway not running: +```bash +picoclaw gateway +``` + +### Discord: Missing intents + +**Error:** +``` +Bot requires MESSAGE CONTENT intent +``` + +**Solution:** +1. Go to [Discord Developer Portal](https://discord.com/developers/applications) +2. Select your application → Bot +3. Enable "MESSAGE CONTENT INTENT" +4. Save changes and restart gateway + +### LINE: Webhook verification failed + +**Error:** +``` +Webhook verification failed +``` + +**Solution:** +1. Ensure webhook URL is accessible (use ngrok for testing) +2. Verify webhook path matches config +3. Check channel secret is correct + +## Tool Issues + +### Web search: API configuration error + +**Error:** +``` +Web search: API configuration error +``` + +**Solution:** +This is normal without a Brave API key. DuckDuckGo works automatically. + +To enable Brave Search: +```json +{ + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "YOUR_BRAVE_API_KEY" + } + } + } +} +``` + +### Exec: Command blocked + +**Error:** +``` +Command blocked by safety guard (dangerous pattern detected) +``` + +**Solution:** +Some dangerous commands are always blocked for safety: +- `rm -rf`, `del /f`, `rmdir /s` +- `format`, `mkfs`, `diskpart` +- `dd if=` +- `shutdown`, `reboot`, `poweroff` + +If you need to run restricted commands in a trusted environment: +```json +{ + "agents": { + "defaults": { + "restrict_to_workspace": false + } + } +} +``` + +### Exec: Path outside working directory + +**Error:** +``` +Command blocked by safety guard (path outside working dir) +``` + +**Solution:** +The agent can only access files in the workspace. Either: +1. Move files into the workspace +2. Disable workspace restriction (security risk): +```bash +export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false +``` + +## Session Issues + +### Session history too large + +**Symptom:** +Slow responses or memory issues. + +**Solution:** +Sessions are automatically summarized when they exceed thresholds. You can also: +1. Delete old sessions: `rm ~/.picoclaw/workspace/sessions/*.json` +2. Start a new session: `picoclaw agent -s "new-session"` + +### Session not persisting + +**Solution:** +1. Check workspace directory exists: `ls ~/.picoclaw/workspace/sessions/` +2. Ensure write permissions: `chmod 755 ~/.picoclaw/workspace/sessions/` + +## Performance Issues + +### High memory usage + +**Solution:** +1. Use a smaller model +2. Reduce `max_tokens` +3. Clear old sessions +4. Restart the gateway periodically + +### Slow responses + +**Possible causes:** + +1. Large model - use a faster/smaller model +2. Network latency - use a provider closer to you +3. Rate limiting - set up fallback models +4. Complex tool calls - reduce tool iterations + +### Gateway won't start + +**Error:** +``` +Error starting gateway: address already in use +``` + +**Solution:** +Change the gateway port: +```json +{ + "gateway": { + "port": 18791 + } +} +``` + +## Authentication Issues + +### OAuth login failed + +**Solution:** +1. Try device code flow for headless environments: +```bash +picoclaw auth login --provider openai --device-code +``` + +2. Check system clock is synchronized + +### Token expired + +**Error:** +``` +Token has expired +``` + +**Solution:** +```bash +picoclaw auth login --provider openai +``` + +## Debug Mode + +Enable debug logging for detailed output: + +```bash +# Agent debug mode +picoclaw agent --debug -m "Hello" + +# Gateway debug mode +picoclaw gateway --debug +``` + +Debug mode shows: +- LLM requests and responses +- Tool calls and results +- Message bus activity +- Configuration loading + +## Getting Help + +If you can't find a solution: + +1. **GitHub Issues**: [Report a bug](https://github.com/sipeed/picoclaw/issues) +2. **GitHub Discussions**: [Ask a question](https://github.com/sipeed/picoclaw/discussions) +3. **Discord**: [Join our server](https://discord.gg/V4sAZ9XWpN) + +When reporting issues, include: +- PicoClaw version (`picoclaw version`) +- Operating system and architecture +- Debug output (use `--debug`) +- Steps to reproduce + +## Related Documentation + +- [Configuration Reference](../configuration/config-file.md) +- [CLI Reference](../user-guide/cli-reference.md) +- [Quick Start](../getting-started/quick-start.md) diff --git a/docs/picoclaw_community_roadmap_260216.md b/docs/picoclaw_community_roadmap_260216.md deleted file mode 100644 index 95de768c63..0000000000 --- a/docs/picoclaw_community_roadmap_260216.md +++ /dev/null @@ -1,112 +0,0 @@ -## 🚀 Join the PicoClaw Journey: Call for Community Volunteers & Roadmap Reveal - -**Hello, PicoClaw Community!** - -First, a massive thank you to everyone for your enthusiasm and PR contributions. It is because of you that PicoClaw continues to iterate and evolve so rapidly. Thanks to the simplicity and accessibility of the **Go language**, we’ve seen a non-stop stream of high-quality PRs! - -PicoClaw is growing much faster than we anticipated. As we are currently in the midst of the **Chinese New Year holiday**, we are looking to recruit community volunteers to help us maintain this incredible momentum. - -This document outlines the specific volunteer roles we need right now and provides a look at our upcoming **Roadmap**. - -### 🎁 Community Perks - -To show our appreciation, developers who officially join our community operations will receive: - -* **Exclusive AI Hardware:** Our upcoming, unreleased AI device. -* **Token Discounts:** Potential discounts on LLM tokens (currently in negotiations with major providers). - -### 🎥 Calling All Content Creators! - -Not a developer? You can still help! We welcome users to post **PicoClaw reviews or tutorials**. - -* **Twitter:** Use the tag **#picoclaw** and mention **@SipeedIO**. -* **Bilibili:** Mention **@Sipeed矽速科技** or send us a DM. -We will be rewarding high-quality content creators with the same perks as our community developers! - ---- - -## 🛠️ Urgent Volunteer Roles - -We are looking for experts in the following areas: - -1. **Issue/PR Reviewers** -* **The Mission:** With PRs and Issues exploding in volume, we need help with initial triage, evaluation, and merging. -* **Focus:** Preliminary merging and community health. Efficiency optimization and security audits will be handled by specialized roles. - - -2. **Resource Optimization Experts** -* **The Mission:** Rapid growth has introduced dependencies that are making PicoClaw a bit "heavy." We want to keep it lean. -* **Focus:** Analyzing resource growth between releases and trimming redundancy. -* **Priority:** **RAM usage optimization** > Binary size reduction. - - -3. **Security Audit & Bug Fixes** -* **The Mission:** Due to the "vibe coding" nature of our early stages, we need a thorough review of network security and AI permission management. -* **Focus:** Auditing the codebase for vulnerabilities and implementing robust fixes. - - -4. **Documentation & DX (Developer Experience)** -* **The Mission:** Our current README is a bit outdated. We need "step-by-step" guides that even beginners can follow. -* **Focus:** Creating clear, user-friendly documentation for both setup and development. - - -5. **AI-Powered CI/CD Optimization** -* **The Mission:** PicoClaw started as a "vibe coding" experiment; now we want to use AI to manage it. -* **Focus:** Automating builds with AI and exploring AI-driven issue resolution. - -**How to Apply:** > If you are interested in any of the roles above, please send an email to support@sipeed.com with the subject line: [Apply: PicoClaw Expert Volunteer] + Your Desired Role. -Please include a brief introduction and any relevant experience or portfolio links. We will review all applications and grant project permissions to selected contributors! - ---- - -## 📍 The Roadmap - -Interested in a specific feature? You can "claim" these tasks and start building: - -### -* **Provider:** - * **Provider Refactor:** Currently being handled by **@Daming** (ETA: 5 days) - * You can still submit code; Daming will merge it into the new implementation. -* **Channels:** - * Support for OneBot, additional platforms - * attachments (images, audio, video, files). -* **Skills:** - * Implementing `find_skill` to discover tools via [ClawhHub](https://clawhub.ai) and other platforms. -* **Operations:** * MCP Support. - * Android operations (e.g., botdrop). - * Browser automation via CDP or ActionBook. - - -* **Multi-Agent Ecosystem:** - * **Basic Model-Agent** - * **Model Routing:** Small models for easy tasks, large models for hard ones (to save tokens). - * **Swarm Mode.** - * **AIEOS Integration.** - - -* **Branding:** - * **Logo**: We need a cute logo! We’re leaning toward a **Mantis Shrimp**—small, but packs a legendary punch! - - -We have officially created these tasks as GitHub Issues, all marked with the roadmap tag. -This list will be updated continuously as we progress. -If you would like to claim a task, please feel free to start a conversation by commenting directly on the corresponding issue! - ---- - -## 🤝 How to Join - -**Everything is open to your creativity!** If you have a wild idea, just PR it. - -1. **The Fast Track:** Once you have at least **one merged PR**, you are eligible to join our **Developer Discord** to help plan the future of PicoClaw. -2. **The Application Track:** If you haven’t submitted a PR yet but want to dive in, email **support@sipeed.com** with the subject: -> `[Apply Join PicoClaw Dev Group] + Your GitHub Account` -> Include the role you're interested in and any evidence of your development experience. - - - -### Looking Ahead - -Powered by PicoClaw, we are crafting a Swarm AI Assistant to transform your environment into a seamless network of personal stewards. By automating the friction of daily life, we empower you to transcend the ordinary and freely explore your creative potential. - -**Finally, Happy Chinese New Year to everyone!** May PicoClaw gallop forward in this **Year of the Horse!** 🐎 diff --git a/docs/tools_configuration.md b/docs/tools_configuration.md deleted file mode 100644 index 8aba1aa91f..0000000000 --- a/docs/tools_configuration.md +++ /dev/null @@ -1,143 +0,0 @@ -# Tools Configuration - -PicoClaw's tools configuration is located in the `tools` field of `config.json`. - -## Directory Structure - -```json -{ - "tools": { - "web": { ... }, - "exec": { ... }, - "cron": { ... }, - "skills": { ... } - } -} -``` - -## Web Tools - -Web tools are used for web search and fetching. - -### Brave - -| Config | Type | Default | Description | -|--------|------|---------|-------------| -| `enabled` | bool | false | Enable Brave search | -| `api_key` | string | - | Brave Search API key | -| `max_results` | int | 5 | Maximum number of results | - -### DuckDuckGo - -| Config | Type | Default | Description | -|--------|------|---------|-------------| -| `enabled` | bool | true | Enable DuckDuckGo search | -| `max_results` | int | 5 | Maximum number of results | - -### Perplexity - -| Config | Type | Default | Description | -|--------|------|---------|-------------| -| `enabled` | bool | false | Enable Perplexity search | -| `api_key` | string | - | Perplexity API key | -| `max_results` | int | 5 | Maximum number of results | - -## Exec Tool - -The exec tool is used to execute shell commands. - -| Config | Type | Default | Description | -|--------|------|---------|-------------| -| `enable_deny_patterns` | bool | true | Enable default dangerous command blocking | -| `custom_deny_patterns` | array | [] | Custom deny patterns (regular expressions) | - -### Functionality - -- **`enable_deny_patterns`**: Set to `false` to completely disable the default dangerous command blocking patterns -- **`custom_deny_patterns`**: Add custom deny regex patterns; commands matching these will be blocked - -### Default Blocked Command Patterns - -By default, PicoClaw blocks the following dangerous commands: - -- Delete commands: `rm -rf`, `del /f/q`, `rmdir /s` -- Disk operations: `format`, `mkfs`, `diskpart`, `dd if=`, writing to `/dev/sd*` -- System operations: `shutdown`, `reboot`, `poweroff` -- Command substitution: `$()`, `${}`, backticks -- Pipe to shell: `| sh`, `| bash` -- Privilege escalation: `sudo`, `chmod`, `chown` -- Process control: `pkill`, `killall`, `kill -9` -- Remote operations: `curl | sh`, `wget | sh`, `ssh` -- Package management: `apt`, `yum`, `dnf`, `npm install -g`, `pip install --user` -- Containers: `docker run`, `docker exec` -- Git: `git push`, `git force` -- Other: `eval`, `source *.sh` - -### Configuration Example - -```json -{ - "tools": { - "exec": { - "enable_deny_patterns": true, - "custom_deny_patterns": [ - "\\brm\\s+-r\\b", - "\\bkillall\\s+python" - ] - } - } -} -``` - -## Cron Tool - -The cron tool is used for scheduling periodic tasks. - -| Config | Type | Default | Description | -|--------|------|---------|-------------| -| `exec_timeout_minutes` | int | 5 | Execution timeout in minutes, 0 means no limit | - -## Skills Tool - -The skills tool configures skill discovery and installation via registries like ClawHub. - -### Registries - -| Config | Type | Default | Description | -|--------|------|---------|-------------| -| `registries.clawhub.enabled` | bool | true | Enable ClawHub registry | -| `registries.clawhub.base_url` | string | `https://clawhub.ai` | ClawHub base URL | -| `registries.clawhub.search_path` | string | `/api/v1/search` | Search API path | -| `registries.clawhub.skills_path` | string | `/api/v1/skills` | Skills API path | -| `registries.clawhub.download_path` | string | `/api/v1/download` | Download API path | - -### Configuration Example - -```json -{ - "tools": { - "skills": { - "registries": { - "clawhub": { - "enabled": true, - "base_url": "https://clawhub.ai", - "search_path": "/api/v1/search", - "skills_path": "/api/v1/skills", - "download_path": "/api/v1/download" - } - } - } - } -} -``` - -## Environment Variables - -All configuration options can be overridden via environment variables with the format `PICOCLAW_TOOLS_
_`: - -For example: -- `PICOCLAW_TOOLS_WEB_BRAVE_ENABLED=true` -- `PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS=false` -- `PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES=10` - -Note: Array-type environment variables are not currently supported and must be set via the config file. diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md new file mode 100644 index 0000000000..f64a184199 --- /dev/null +++ b/docs/tutorials/README.md @@ -0,0 +1,140 @@ +# Tutorials + +Welcome to the PicoClaw tutorials. These step-by-step guides will help you get the most out of PicoClaw. + +## Getting Started + +If you're new to PicoClaw, start with the basic assistant tutorial. + +| Tutorial | Difficulty | Time | Description | +|----------|------------|------|-------------| +| [Basic Assistant](basic-assistant.md) | Beginner | 10 min | Set up your first AI assistant | +| [Telegram Bot](telegram-bot.md) | Beginner | 15 min | Create a Telegram chatbot | +| [Scheduled Tasks](scheduled-tasks.md) | Intermediate | 15 min | Set up cron jobs and heartbeats | +| [Multi-Agent Setup](multi-agent-setup.md) | Intermediate | 20 min | Run multiple specialized agents | +| [Hardware Control](hardware-control.md) | Advanced | 25 min | Control I2C/SPI devices | +| [Skill Development](skill-development.md) | Advanced | 30 min | Create custom skills | + +## Learning Path + +### Beginner Path + +``` +Basic Assistant ──> Telegram Bot ──> Scheduled Tasks +``` + +1. **Basic Assistant**: Learn core concepts and CLI usage +2. **Telegram Bot**: Connect to a real chat platform +3. **Scheduled Tasks**: Automate periodic operations + +### Intermediate Path + +``` +Multi-Agent Setup ──> Custom Configuration +``` + +4. **Multi-Agent Setup**: Run multiple agents with different purposes +5. Customize with your own configurations + +### Advanced Path + +``` +Hardware Control ──> Skill Development +``` + +6. **Hardware Control**: Interface with physical devices +7. **Skill Development**: Extend PicoClaw with custom skills + +## Tutorial Overview + +### Basic Assistant Setup + +Learn the fundamentals: +- Installing and configuring PicoClaw +- Setting up an LLM provider +- Your first conversation +- Understanding the workspace + +[Start Tutorial](basic-assistant.md) + +### Telegram Bot Tutorial + +Build a Telegram chatbot: +- Creating a bot with BotFather +- Configuring the Telegram channel +- Testing your bot +- Adding custom commands + +[Start Tutorial](telegram-bot.md) + +### Scheduled Tasks Tutorial + +Automate with scheduled tasks: +- Setting up cron jobs +- Configuring heartbeat tasks +- Using the HEARTBEAT.md file +- Monitoring scheduled tasks + +[Start Tutorial](scheduled-tasks.md) + +### Multi-Agent Tutorial + +Run multiple agents: +- Understanding multi-agent architecture +- Configuring agent routing +- Setting up specialized agents +- Agent communication + +[Start Tutorial](multi-agent-setup.md) + +### Hardware Control Tutorial + +Control hardware devices: +- Setting up I2C and SPI +- Reading sensor data +- Controlling actuators +- Building IoT applications + +[Start Tutorial](hardware-control.md) + +### Skill Development Tutorial + +Create custom skills: +- Understanding the skill system +- Creating a basic skill +- Adding prompts and tools +- Testing and debugging + +[Start Tutorial](skill-development.md) + +## Prerequisites + +Before starting tutorials, ensure you have: + +- PicoClaw installed ([Installation Guide](../getting-started/installation.md)) +- A provider API key (OpenRouter recommended) +- Basic command line knowledge +- A text editor for configuration files + +## Getting Help + +If you get stuck: + +1. Check the [Troubleshooting Guide](../operations/troubleshooting.md) +2. Search [GitHub Issues](https://github.com/sipeed/picoclaw/issues) +3. Ask in [GitHub Discussions](https://github.com/sipeed/picoclaw/discussions) +4. Join our [Discord](https://discord.gg/V4sAZ9XWpN) + +## Contributing Tutorials + +Have a tutorial idea? We welcome contributions! + +1. Check existing tutorials to avoid duplication +2. Follow the existing tutorial format +3. Include working code examples +4. Test your tutorial from scratch +5. Submit a pull request + +## Next Steps + +Ready to begin? Start with the [Basic Assistant Tutorial](basic-assistant.md). diff --git a/docs/tutorials/basic-assistant.md b/docs/tutorials/basic-assistant.md new file mode 100644 index 0000000000..a72230cee9 --- /dev/null +++ b/docs/tutorials/basic-assistant.md @@ -0,0 +1,356 @@ +# Basic Assistant Setup Tutorial + +This tutorial guides you through setting up your first PicoClaw AI assistant. + +## Prerequisites + +- 10 minutes +- A computer running Linux, macOS, or Windows +- Internet connection +- An API key from an LLM provider + +## Step 1: Install PicoClaw + +### Download Binary (Recommended) + +```bash +# Download the latest release for your platform +# Linux (amd64) +curl -LO https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-linux-amd64 + +# macOS (arm64) +curl -LO https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-darwin-arm64 + +# Windows (amd64) +curl -LO https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw-windows-amd64.exe +``` + +### Make Executable + +```bash +# Linux/macOS +chmod +x picoclaw-* + +# Move to PATH (optional) +sudo mv picoclaw-* /usr/local/bin/picoclaw +``` + +### Verify Installation + +```bash +picoclaw version +``` + +## Step 2: Get an API Key + +### Recommended: OpenRouter + +OpenRouter provides access to many models with a free tier (200K tokens/month). + +1. Go to [openrouter.ai/keys](https://openrouter.ai/keys) +2. Sign in or create an account +3. Click "Create Key" +4. Copy your API key (starts with `sk-or-v1-`) + +### Alternative Providers + +| Provider | Sign Up | Free Tier | +|----------|---------|-----------| +| Zhipu | [bigmodel.cn](https://open.bigmodel.cn) | 200K tokens | +| Groq | [console.groq.com](https://console.groq.com) | Yes | +| Gemini | [aistudio.google.com](https://aistudio.google.com) | Yes | + +## Step 3: Initialize Configuration + +Run the onboard command to create default configuration: + +```bash +picoclaw onboard +``` + +This creates: +- `~/.picoclaw/config.json` - Main configuration file +- `~/.picoclaw/workspace/` - Working directory + +## Step 4: Add Your API Key + +Edit the configuration file: + +```bash +nano ~/.picoclaw/config.json +``` + +Add your OpenRouter API key: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "anthropic/claude-opus-4-5", + "max_tokens": 8192, + "temperature": 0.7, + "max_tool_iterations": 20 + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-YOUR-API-KEY-HERE", + "api_base": "https://openrouter.ai/api/v1" + } + } +} +``` + +Replace `YOUR-API-KEY-HERE` with your actual API key. + +## Step 5: Your First Chat + +### One-Shot Message + +Send a single message: + +```bash +picoclaw agent -m "Hello, what can you help me with?" +``` + +Expected output: + +``` +Hello! I'm your PicoClaw assistant. I can help you with: + +- Answering questions and providing information +- Reading, writing, and managing files +- Running shell commands +- Searching the web +- And much more! + +What would you like to do today? +``` + +### Interactive Mode + +Start a continuous conversation: + +```bash +picoclaw agent +``` + +``` +> Hello! +Hello! How can I help you today? + +> What is 2 + 2? +2 + 2 = 4 + +> Can you write that to a file? +[Uses write_file tool] +I've written "4" to result.txt in the workspace. + +> Thanks! +You're welcome! Let me know if you need anything else. + +> exit +Goodbye! +``` + +## Step 6: Explore the Workspace + +The workspace is where PicoClaw stores files and sessions: + +```bash +# View workspace structure +ls -la ~/.picoclaw/workspace/ +``` + +Output: + +``` +drwxr-xr-x sessions/ # Conversation history +drwxr-xr-x memory/ # Long-term memory +-rw-r--r-- AGENT.md # Agent behavior guide +-rw-r--r-- IDENTITY.md # Agent identity +``` + +### View Session History + +```bash +ls ~/.picoclaw/workspace/sessions/ +``` + +Sessions are stored as JSON files with your conversation history. + +## Step 7: Customize Your Agent + +### AGENT.md + +The AGENT.md file defines how your agent behaves: + +```bash +cat ~/.picoclaw/workspace/AGENT.md +``` + +Edit it to customize behavior: + +```markdown +# Agent Behavior + +You are a helpful AI assistant. + +## Capabilities +- Answer questions +- Help with coding +- Manage files + +## Personality +- Friendly and professional +- Clear and concise explanations +``` + +### IDENTITY.md + +Define your agent's identity: + +```markdown +# Identity + +Name: PicoClaw Assistant +Version: 1.0 +Created: 2024-01-15 + +I am an AI assistant powered by PicoClaw. +``` + +## Step 8: Enable Web Search (Optional) + +PicoClaw can search the web. DuckDuckGo works without configuration. + +For better results, add Brave Search: + +1. Get a free API key from [brave.com/search/api](https://brave.com/search/api) (2000 queries/month) + +2. Add to config: + +```json +{ + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "YOUR_BRAVE_API_KEY", + "max_results": 5 + }, + "duckduckgo": { + "enabled": true, + "max_results": 5 + } + } + } +} +``` + +## Step 9: Try Web Search + +```bash +picoclaw agent -m "What's the latest news about AI?" +``` + +The agent will search the web and summarize relevant information. + +## Understanding Tools + +PicoClaw has built-in tools the agent can use: + +| Tool | Description | +|------|-------------| +| `read_file` | Read file contents | +| `write_file` | Write to files | +| `list_files` | List directory contents | +| `exec` | Run shell commands | +| `web_search` | Search the web | +| `web_fetch` | Fetch web page content | + +### Example: File Operations + +```bash +picoclaw agent -m "Create a file called notes.txt with today's date" +``` + +The agent will: +1. Use `write_file` to create the file +2. Confirm the action + +### Example: Shell Commands + +```bash +picoclaw agent -m "What's the current system time?" +``` + +The agent will: +1. Use `exec` to run `date` +2. Report the time + +## Debug Mode + +When troubleshooting, use debug mode: + +```bash +picoclaw agent --debug -m "Hello" +``` + +Debug mode shows: +- LLM requests and responses +- Tool calls and results +- Configuration details + +## Common Issues + +### "no API key configured" + +Make sure your config file has the API key: + +```bash +cat ~/.picoclaw/config.json | grep api_key +``` + +### "model not found" + +Check the model name format: +- OpenRouter: `anthropic/claude-opus-4-5` +- Zhipu: `glm-4.7` + +### "rate limit exceeded" + +Wait a moment and try again, or set up fallback models: + +```json +{ + "agents": { + "defaults": { + "model": "anthropic/claude-opus-4-5", + "model_fallbacks": ["anthropic/claude-sonnet-4", "openai/gpt-4o"] + } + } +} +``` + +## Next Steps + +Now that you have a basic assistant running, explore: + +- [Telegram Bot Tutorial](telegram-bot.md) - Connect to Telegram +- [Scheduled Tasks Tutorial](scheduled-tasks.md) - Automate tasks +- [CLI Reference](../user-guide/cli-reference.md) - All commands +- [Tools Overview](../user-guide/tools/README.md) - Available tools + +## Summary + +You learned: +- How to install PicoClaw +- How to configure an LLM provider +- How to chat with the agent +- How to customize behavior +- How to enable web search +- Basic troubleshooting + +Congratulations! You have a working AI assistant. diff --git a/docs/tutorials/hardware-control.md b/docs/tutorials/hardware-control.md new file mode 100644 index 0000000000..2821947f4a --- /dev/null +++ b/docs/tutorials/hardware-control.md @@ -0,0 +1,500 @@ +# Hardware Control Tutorial + +This tutorial guides you through controlling I2C and SPI hardware devices with PicoClaw. + +## Prerequisites + +- 25 minutes +- Linux-based system (Raspberry Pi, SBC, etc.) +- PicoClaw installed and configured +- Basic electronics knowledge +- I2C or SPI devices to experiment with + +## Overview + +PicoClaw can interact with hardware devices through: + +| Interface | Use Case | Speed | +|-----------|----------|-------| +| I2C | Sensors, displays, slow devices | 100-400 kHz | +| SPI | Flash memory, fast displays | Up to MHz | + +## Part 1: Setup + +### Enable I2C (Raspberry Pi) + +```bash +# Using raspi-config +sudo raspi-config +# Interface Options -> I2C -> Yes + +# Or manually +sudo apt install i2c-tools +sudo modprobe i2c-dev +``` + +### Enable SPI (Raspberry Pi) + +```bash +# Using raspi-config +sudo raspi-config +# Interface Options -> SPI -> Yes + +# Or manually +sudo modprobe spidev +``` + +### Set Permissions + +```bash +# Add user to required groups +sudo usermod -aG i2c $USER +sudo usermod -aG spi $USER + +# Logout and login for changes to take effect +``` + +### Verify Setup + +```bash +# Check I2C buses +ls /dev/i2c-* + +# Check SPI devices +ls /dev/spidev* + +# Install tools +sudo apt install i2c-tools spi-tools +``` + +## Part 2: I2C Device Detection + +### Scan for Devices + +```bash +# Scan I2C bus 1 +i2cdetect -y 1 +``` + +Output: + +``` + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- 38 39 3a 3b 3c 3d 3e 3f +40: 40 41 42 43 44 45 46 47 -- -- -- -- -- -- -- -- +50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- 6c -- -- -- +70: -- -- -- -- -- -- -- 76 +``` + +Numbers shown are device addresses in hex (e.g., 0x76, 0x38). + +### Using PicoClaw + +``` +User: "Detect all I2C buses" +``` + +Agent response: + +``` +I'll detect the I2C buses on this system. + +[Uses i2c tool with action "detect"] + +Available I2C buses: +- i2c-1: Broadcom SMBus I2C adapter + +User: "Scan bus 1 for devices" + +[Uses i2c tool with action "scan", bus 1] + +Found devices on bus 1: +- 0x38: Unknown device +- 0x40: Unknown device +- 0x76: Likely BME280/BMP280 sensor +``` + +## Part 3: Reading Sensor Data + +### Example: BME280 Temperature Sensor + +The BME280 is a popular temperature/humidity/pressure sensor at address 0x76 or 0x77. + +``` +User: "Read temperature from the BME280 at address 0x76" +``` + +Agent actions: + +1. First, scan to verify device: + +```json +{ + "action": "scan", + "bus": 1 +} +``` + +2. Read calibration data: + +```json +{ + "action": "read", + "bus": 1, + "address": "0x76", + "register": "0x88" +} +``` + +3. Read sensor registers: + +```json +{ + "action": "read", + "bus": 1, + "address": "0x76", + "register": "0xFA" +} +``` + +4. Calculate and report temperature. + +### Example Conversation + +``` +User: What's the temperature reading? + +Agent: I'll read the temperature from the BME280. + +[Scans bus, finds device at 0x76] +[Reads register 0xFA for temperature data] + +Current temperature: 23.5 degrees Celsius +Humidity: 65% +Pressure: 1013.25 hPa + +User: Log this to a file + +Agent: I'll append this reading to a log file. + +[Writes to sensors.log] + +Logged: 2024-01-15 10:30:00 - Temp: 23.5C, Humidity: 65%, Pressure: 1013.25hPa +``` + +## Part 4: SPI Communication + +### List SPI Devices + +``` +User: "List available SPI devices" +``` + +Agent response: + +``` +[Uses spi tool with action "list"] + +Available SPI devices: +- /dev/spidev0.0 (CS0) +- /dev/spidev0.1 (CS1) +``` + +### SPI Transfer + +``` +User: "Send bytes 0xAA 0xBB 0xCC to /dev/spidev0.0" +``` + +Agent action: + +```json +{ + "action": "transfer", + "device": "/dev/spidev0.0", + "data": "0xAA 0xBB 0xCC" +} +``` + +### Example: Read SPI Flash + +``` +User: "Read the first 16 bytes from the SPI flash on /dev/spidev0.0" +``` + +Agent actions: + +1. Send read command (0x03) + address (0x00 0x00 0x00): + +```json +{ + "action": "transfer", + "device": "/dev/spidev0.0", + "data": "0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" +} +``` + +2. Parse the response and display hex dump. + +## Part 5: Create a Hardware Agent + +### Agent Configuration + +Create a specialized hardware agent: + +```bash +mkdir -p ~/.picoclaw/workspaces/hardware +nano ~/.picoclaw/workspaces/hardware/AGENT.md +``` + +```markdown +# Hardware Control Agent + +## Role +You are a hardware controller for embedded and IoT devices. + +## Capabilities +- I2C device detection and communication +- SPI device control +- Sensor reading and logging +- GPIO control (via exec tool) + +## Known Devices +| Address | Device | Description | +|---------|--------|-------------| +| 0x76 | BME280 | Temp/Humidity/Pressure | +| 0x68 | DS1307/MPU6050 | RTC or IMU | +| 0x3C | SSD1306 | OLED Display | +| 0x27 | PCF8574 | I/O Expander | + +## Behavior +1. Always detect devices before communication +2. Log all readings with timestamps +3. Handle errors gracefully +4. Report sensor values with units + +## Safety +- Never write random values to unknown registers +- Verify device presence before operations +- Use appropriate delays between operations +``` + +### Add to Configuration + +```json +{ + "agents": { + "list": [ + { + "id": "hardware", + "workspace": "~/.picoclaw/workspaces/hardware", + "model": "anthropic/claude-sonnet-4", + "restrict_to_workspace": false + } + ] + } +} +``` + +### Use the Hardware Agent + +```bash +picoclaw agent -a hardware -m "Scan all I2C buses and identify devices" +``` + +## Part 6: Practical Projects + +### Project 1: Weather Station + +Create a monitoring system: + +``` +User: "Set up a weather monitoring system" + +Agent: +1. I'll configure a weather monitoring system using the BME280. + +[Scans for device] +[Reads current values] + +I'll create a logging script: + +[Creates weather_log.sh using write_file] + +Now let's set up a cron job to log every 5 minutes: + +[Creates cron job using cron tool] + +Weather station configured: +- Sensor: BME280 at 0x76 +- Log file: ~/workspace/weather.log +- Interval: Every 5 minutes +``` + +### Project 2: OLED Display + +Control an SSD1306 display: + +``` +User: "Display 'Hello World' on the OLED" + +Agent: +I'll write to the SSD1306 display at 0x3C. + +[Sends initialization sequence] +[Sends text data] + +"Hello World" should now be displayed on the OLED. +``` + +### Project 3: Relay Control + +Control relays via I2C I/O expander: + +``` +User: "Turn on relay 1" + +Agent: +I'll control the relay via the PCF8574 at 0x27. + +[Reads current state] +[Writes new state with bit 0 set] + +Relay 1 is now ON. +``` + +## Part 7: Sensor Database + +Create a sensor reading database: + +### Using Heartbeat + +Create `HEARTBEAT.md`: + +```markdown +# Sensor Monitoring + +Every 1 minute: +1. Read BME280 (temperature, humidity, pressure) +2. Read light sensor (if connected) +3. Append to ~/workspace/sensors.csv in format: + timestamp,temperature,humidity,pressure,light +4. Alert if any value is out of range +``` + +### Configure Heartbeat + +```json +{ + "heartbeat": { + "enabled": true, + "interval": "1m" + } +} +``` + +### Run + +```bash +picoclaw agent --heartbeat +``` + +### Query Data + +``` +User: "What's the average temperature over the last hour?" + +Agent: +[Reads sensors.csv] +[Calculates average] + +Average temperature over the last hour: 23.2 degrees Celsius +Min: 22.8, Max: 24.1 +``` + +## Part 8: Troubleshooting + +### Device Not Detected + +```bash +# Check I2C is enabled +ls /dev/i2c-* + +# Check kernel modules +lsmod | grep i2c + +# Check permissions +groups $USER +``` + +### Permission Denied + +```bash +# Check device permissions +ls -la /dev/i2c-1 + +# Temporary fix +sudo chmod 666 /dev/i2c-1 + +# Permanent fix +sudo usermod -aG i2c $USER +# Logout and login +``` + +### Communication Errors + +1. Check wiring (SDA, SCL, VCC, GND) +2. Verify pull-up resistors (4.7K typical) +3. Check device address +4. Try different bus speed + +### PicoClaw Debug Mode + +```bash +picoclaw agent --debug -a hardware -m "Read sensor" +``` + +## Common I2C Devices + +| Device | Address | Type | Notes | +|--------|---------|------|-------| +| BME280 | 0x76/0x77 | Sensor | Temp/Humidity/Pressure | +| BMP280 | 0x76/0x77 | Sensor | Temp/Pressure only | +| MPU6050 | 0x68 | IMU | Accelerometer/Gyro | +| HMC5883L | 0x1E | Magnetometer | Compass | +| SSD1306 | 0x3C/0x3D | Display | 128x64 OLED | +| PCF8574 | 0x20-0x27 | I/O | 8-bit expander | +| DS1307 | 0x68 | RTC | Real-time clock | +| ADS1115 | 0x48-0x4B | ADC | 16-bit, 4 channels | + +## Safety Guidelines + +1. **Always verify device presence** before writing +2. **Check voltage levels** (3.3V vs 5V) +3. **Use pull-up resistors** for I2C +4. **Handle interrupts carefully** +5. **Log operations** for debugging +6. **Test commands manually** before automation + +## Next Steps + +- [Hardware Tools Reference](../user-guide/tools/hardware.md) +- [Multi-Agent Tutorial](multi-agent-setup.md) - Create a dedicated hardware agent +- [Scheduled Tasks](scheduled-tasks.md) - Automate sensor logging +- [MaixCam Integration](../user-guide/channels/maixcam.md) - Vision capabilities + +## Summary + +You learned: +- How to enable I2C and SPI interfaces +- How to detect and scan for devices +- How to read sensor data +- How to create a hardware agent +- Practical project examples +- Troubleshooting techniques + +You can now control hardware devices with PicoClaw! diff --git a/docs/tutorials/multi-agent-setup.md b/docs/tutorials/multi-agent-setup.md new file mode 100644 index 0000000000..e894fe231f --- /dev/null +++ b/docs/tutorials/multi-agent-setup.md @@ -0,0 +1,537 @@ +# Multi-Agent Setup Tutorial + +This tutorial guides you through setting up multiple specialized agents with PicoClaw. + +## Prerequisites + +- 20 minutes +- PicoClaw installed and configured +- A working LLM provider +- Basic understanding of PicoClaw configuration + +## Overview + +Multi-agent setup allows you to run specialized agents for different tasks: + +``` +┌──────────────────────────────────────────────────────────┐ +│ PicoClaw │ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ Default │ │ Research │ │ Coding │ │ Hardware │ │ +│ │ Agent │ │ Agent │ │ Agent │ │ Agent │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ ▲ ▲ ▲ ▲ │ +│ │ │ │ │ │ +│ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │ +│ │Telegram │ │Discord │ │ CLI │ │ CLI │ │ +│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ +└──────────────────────────────────────────────────────────┘ +``` + +## Use Cases + +- **Specialized behavior**: Different agents for different tasks +- **Model optimization**: Use cheaper models for simple tasks +- **Access control**: Different permissions per channel +- **Workspace isolation**: Separate files and sessions + +## Step 1: Understand Agent Configuration + +### Default Agent + +The default agent handles all unbound requests: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "anthropic/claude-opus-4-5" + } + } +} +``` + +### Named Agents + +Add agents to the `list` array: + +```json +{ + "agents": { + "defaults": { ... }, + "list": [ + { + "id": "research", + "workspace": "~/.picoclaw/workspaces/research", + "model": "anthropic/claude-opus-4-5" + } + ] + } +} +``` + +## Step 2: Create Agent Workspaces + +Each agent needs its own workspace: + +```bash +# Create workspaces +mkdir -p ~/.picoclaw/workspaces/research +mkdir -p ~/.picoclaw/workspaces/coding +mkdir -p ~/.picoclaw/workspaces/hardware +``` + +## Step 3: Configure Multiple Agents + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "anthropic/claude-opus-4-5", + "max_tokens": 8192, + "temperature": 0.7 + }, + "list": [ + { + "id": "research", + "workspace": "~/.picoclaw/workspaces/research", + "model": "anthropic/claude-opus-4-5", + "temperature": 0.3, + "system_prompt": "You are a research assistant specialized in gathering and analyzing information." + }, + { + "id": "coding", + "workspace": "~/.picoclaw/workspaces/coding", + "model": "anthropic/claude-sonnet-4", + "temperature": 0.2, + "system_prompt": "You are a coding assistant focused on writing clean, efficient code." + }, + { + "id": "hardware", + "workspace": "~/.picoclaw/workspaces/hardware", + "model": "anthropic/claude-sonnet-4", + "restrict_to_workspace": false + } + ] + } +} +``` + +## Step 4: Customize Agent Behavior + +Create AGENT.md for each workspace: + +### Research Agent + +```bash +nano ~/.picoclaw/workspaces/research/AGENT.md +``` + +```markdown +# Research Agent + +## Role +You are a research assistant specialized in gathering and analyzing information. + +## Capabilities +- Web search and summarization +- Fact-checking and source verification +- Creating research summaries +- Organizing information + +## Behavior +- Always cite sources +- Be thorough but concise +- Verify claims with multiple sources +- Store findings in memory +``` + +### Coding Agent + +```bash +nano ~/.picoclaw/workspaces/coding/AGENT.md +``` + +```markdown +# Coding Agent + +## Role +You are a coding assistant focused on writing clean, efficient code. + +## Capabilities +- Writing code in various languages +- Code review and optimization +- Debugging and testing +- Documentation + +## Behavior +- Follow best practices +- Include comments for complex logic +- Write testable code +- Explain your solutions +``` + +### Hardware Agent + +```bash +nano ~/.picoclaw/workspaces/hardware/AGENT.md +``` + +```markdown +# Hardware Agent + +## Role +You are a hardware controller for IoT and embedded systems. + +## Capabilities +- I2C device communication +- SPI device control +- Sensor reading and logging +- Actuator control + +## Behavior +- Always check device availability before operations +- Log all hardware interactions +- Handle errors gracefully +- Report sensor readings with units +``` + +## Step 5: Set Up Routing + +Routing determines which agent handles which requests. + +### Channel Binding + +Bind specific channels to specific agents: + +```json +{ + "bindings": [ + { + "channel": "telegram", + "chat_id": "123456789", + "agent_id": "default" + }, + { + "channel": "discord", + "chat_id": "987654321", + "agent_id": "research" + } + ] +} +``` + +### CLI Routing + +Use the agent ID with CLI: + +```bash +# Use default agent +picoclaw agent -m "Hello" + +# Use specific agent +picoclaw agent --agent research -m "Research quantum computing" +picoclaw agent --agent coding -m "Write a Python script" +picoclaw agent --agent hardware -m "Read temperature sensor" +``` + +### Short form: + +```bash +picoclaw agent -a research -m "Research topic" +``` + +## Step 6: Configure Subagents + +Allow agents to spawn subagents for complex tasks: + +```json +{ + "agents": { + "defaults": { + "subagents": ["research", "coding", "hardware"] + }, + "list": [ + { + "id": "research", + "subagents": [] + }, + { + "id": "coding", + "subagents": ["research"] + }, + { + "id": "hardware", + "subagents": [] + } + ] + } +} +``` + +### Using Subagents + +The default agent can delegate to specialists: + +``` +User: "Research REST APIs and then create a Python client" + +Agent: I'll research REST APIs first, then write the code. + +[Spawns research agent] +Research complete: REST APIs are... + +[Spawns coding agent] +Here's the Python client code... +``` + +## Step 7: Test Your Setup + +### Test Each Agent + +```bash +# Test default agent +picoclaw agent -m "Hello from default" + +# Test research agent +picoclaw agent -a research -m "Research machine learning" + +# Test coding agent +picoclaw agent -a coding -m "Write a hello world in Python" + +# Test hardware agent +picoclaw agent -a hardware -m "List I2C devices" +``` + +### Verify Workspace Isolation + +```bash +# Each agent has its own session +ls ~/.picoclaw/workspace/sessions/ +ls ~/.picoclaw/workspaces/research/sessions/ +ls ~/.picoclaw/workspaces/coding/sessions/ +``` + +## Step 8: Model Optimization + +Use different models for different agents: + +```json +{ + "agents": { + "list": [ + { + "id": "simple", + "model": "openai/gpt-4o-mini", + "description": "Fast, cheap tasks" + }, + { + "id": "complex", + "model": "anthropic/claude-opus-4-5", + "description": "Complex reasoning" + } + ] + } +} +``` + +### Fallbacks Per Agent + +```json +{ + "agents": { + "list": [ + { + "id": "research", + "model": "anthropic/claude-opus-4-5", + "model_fallbacks": [ + "anthropic/claude-sonnet-4", + "openai/gpt-4o" + ] + } + ] + } +} +``` + +## Step 9: Advanced Routing Patterns + +### Regex Routing + +Route based on message patterns: + +```json +{ + "routing": { + "rules": [ + { + "pattern": "^code:|^implement:|^debug:", + "agent_id": "coding" + }, + { + "pattern": "^research:|^search:|^find:", + "agent_id": "research" + }, + { + "pattern": "^sensor:|^i2c:|^hardware:", + "agent_id": "hardware" + } + ] + } +} +``` + +### Time-Based Routing + +Use different agents at different times: + +```json +{ + "routing": { + "rules": [ + { + "time_range": {"start": "09:00", "end": "17:00"}, + "agent_id": "work" + }, + { + "time_range": {"start": "17:00", "end": "09:00"}, + "agent_id": "personal" + } + ] + } +} +``` + +## Step 10: Monitoring Multiple Agents + +### Status Command + +```bash +picoclaw status +``` + +Output: + +``` +PicoClaw Status +=============== + +Agents: + - default (anthropic/claude-opus-4-5) + Sessions: 5 + - research (anthropic/claude-opus-4-5) + Sessions: 3 + - coding (anthropic/claude-sonnet-4) + Sessions: 8 + - hardware (anthropic/claude-sonnet-4) + Sessions: 2 + +Channels: + - telegram: connected + - discord: connected +``` + +## Practical Example: Dev Team Setup + +Here's a complete configuration for a development team: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "anthropic/claude-sonnet-4", + "max_tokens": 4096 + }, + "list": [ + { + "id": "code-review", + "workspace": "~/.picoclaw/workspaces/code-review", + "model": "anthropic/claude-opus-4-5", + "system_prompt": "You are a code reviewer. Analyze code for bugs, security issues, and improvements." + }, + { + "id": "docs", + "workspace": "~/.picoclaw/workspaces/docs", + "model": "anthropic/claude-sonnet-4", + "system_prompt": "You are a technical writer. Create clear, comprehensive documentation." + }, + { + "id": "devops", + "workspace": "~/.picoclaw/workspaces/devops", + "model": "anthropic/claude-sonnet-4", + "system_prompt": "You are a DevOps engineer. Help with deployment, CI/CD, and infrastructure." + } + ] + }, + "bindings": [ + { + "channel": "discord", + "chat_id": "code-review-channel-id", + "agent_id": "code-review" + }, + { + "channel": "discord", + "chat_id": "docs-channel-id", + "agent_id": "docs" + } + ] +} +``` + +## Troubleshooting + +### Agent Not Found + +``` +Error: agent 'xyz' not found +``` + +Check the agent ID in your config matches what you're using. + +### Wrong Agent Responding + +1. Check bindings configuration +2. Verify routing rules +3. Check channel/chat IDs + +### Workspace Issues + +``` +Error: workspace not accessible +``` + +1. Check workspace paths exist +2. Verify permissions +3. Check disk space + +## Best Practices + +1. **Use descriptive agent IDs** - Easy to remember and type +2. **Match models to tasks** - Use appropriate models for each agent +3. **Isolate workspaces** - Keep agent data separate +4. **Configure subagents wisely** - Only allow necessary delegation +5. **Monitor usage** - Track which agents are used most +6. **Document agents** - Clear AGENT.md for each + +## Next Steps + +- [Routing Documentation](../user-guide/advanced/routing.md) - Advanced routing +- [Spawn Tool](../user-guide/tools/spawn.md) - Subagent spawning +- [Session Management](../user-guide/advanced/session-management.md) - Session handling + +## Summary + +You learned: +- How to configure multiple agents +- How to create specialized agent workspaces +- How to set up channel bindings +- How to use subagents +- How to optimize models per agent + +You can now run a multi-agent PicoClaw system! diff --git a/docs/tutorials/scheduled-tasks.md b/docs/tutorials/scheduled-tasks.md new file mode 100644 index 0000000000..73a575da09 --- /dev/null +++ b/docs/tutorials/scheduled-tasks.md @@ -0,0 +1,423 @@ +# Scheduled Tasks Tutorial + +This tutorial covers setting up automated tasks with cron jobs and heartbeat features. + +## Prerequisites + +- 15 minutes +- PicoClaw installed and configured +- A working LLM provider + +## Overview + +PicoClaw offers two ways to schedule automated tasks: + +| Feature | Purpose | Trigger | +|---------|---------|---------| +| **Cron Jobs** | Specific scheduled tasks | Time-based (cron syntax) | +| **Heartbeat** | Periodic autonomous actions | Interval-based | + +## Part 1: Cron Jobs + +### Understanding Cron + +Cron jobs run at specific times using cron syntax: + +``` +┌───────────── minute (0 - 59) +│ ┌───────────── hour (0 - 23) +│ │ ┌───────────── day of month (1 - 31) +│ │ │ ┌───────────── month (1 - 12) +│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday = 0) +│ │ │ │ │ +* * * * * +``` + +### Create a Cron Job + +#### Using CLI + +```bash +picoclaw cron add "0 9 * * *" "Send me a daily summary" +``` + +#### Using Configuration + +Edit `~/.picoclaw/config.json`: + +```json +{ + "cron": { + "enabled": true, + "jobs": [ + { + "name": "morning_summary", + "schedule": "0 9 * * *", + "prompt": "Generate a morning summary including the current date, weather, and any important notes from the memory file" + }, + { + "name": "hourly_check", + "schedule": "0 * * * *", + "prompt": "Check system status and report any issues" + } + ] + } +} +``` + +### Cron Schedule Examples + +| Schedule | Meaning | +|----------|---------| +| `0 9 * * *` | Every day at 9:00 AM | +| `*/15 * * * *` | Every 15 minutes | +| `0 */2 * * *` | Every 2 hours | +| `0 9 * * 1` | Every Monday at 9:00 AM | +| `0 9 1 * *` | First day of every month | +| `0 0 * * *` | Every day at midnight | + +### Managing Cron Jobs + +#### List Jobs + +```bash +picoclaw cron list +``` + +Output: + +``` +Name Schedule Next Run Prompt +--------------------------------------------------------------------------- +morning_summary 0 9 * * * 2024-01-16 09:00:00 Generate a morning... +hourly_check 0 * * * * 2024-01-15 11:00:00 Check system status... +``` + +#### Remove Job + +```bash +picoclaw cron remove morning_summary +``` + +#### Enable/Disable + +```bash +picoclaw cron enable morning_summary +picoclaw cron disable morning_summary +``` + +### Cron with Output Channels + +Send cron output to a channel: + +```json +{ + "cron": { + "enabled": true, + "jobs": [ + { + "name": "daily_report", + "schedule": "0 18 * * *", + "prompt": "Generate a daily activity report", + "output": { + "channel": "telegram", + "chat_id": "123456789" + } + } + ] + } +} +``` + +## Part 2: Heartbeat Tasks + +### Understanding Heartbeat + +Heartbeat tasks run at regular intervals, allowing the agent to act autonomously. They're defined in `HEARTBEAT.md`. + +### Create HEARTBEAT.md + +```bash +nano ~/.picoclaw/workspace/HEARTBEAT.md +``` + +```markdown +# Heartbeat Tasks + +You are running in periodic mode. Every interval, perform these checks: + +## System Health +- Check available disk space +- Check memory usage +- Report any anomalies + +## Data Collection +- Collect sensor data (if hardware is connected) +- Update any tracking logs + +## Notifications +- If any issues are found, prepare a notification +- Summarize findings concisely + +## Memory Update +- Update MEMORY.md with important observations +``` + +### Configure Heartbeat + +Edit `~/.picoclaw/config.json`: + +```json +{ + "heartbeat": { + "enabled": true, + "interval": "5m", + "max_runs": 0 + } +} +``` + +### Configuration Options + +| Option | Default | Description | +|--------|---------|-------------| +| `enabled` | `false` | Enable heartbeat tasks | +| `interval` | `5m` | Time between runs | +| `max_runs` | `0` | Maximum runs (0 = unlimited) | + +### Interval Examples + +| Interval | Meaning | +|----------|---------| +| `30s` | Every 30 seconds | +| `5m` | Every 5 minutes | +| `1h` | Every hour | +| `24h` | Every day | + +### Running Heartbeat + +```bash +# Start with heartbeat enabled +picoclaw agent --heartbeat + +# Or with gateway +picoclaw gateway +``` + +### Environment Variable + +```bash +export PICOCLAW_HEARTBEAT_ENABLED=true +export PICOCLAW_HEARTBEAT_INTERVAL=10m + +picoclaw gateway +``` + +## Part 3: Practical Examples + +### Example 1: Daily Backup Reminder + +**Cron Job:** + +```json +{ + "cron": { + "jobs": [ + { + "name": "backup_reminder", + "schedule": "0 20 * * *", + "prompt": "Check when the last backup was made (look in workspace/logs) and remind the user if it's been more than 24 hours" + } + ] + } +} +``` + +### Example 2: System Monitoring + +**Heartbeat (HEARTBEAT.md):** + +```markdown +# System Monitor + +Every 5 minutes, check: +1. CPU usage (use: top -bn1 | head -5) +2. Memory usage (use: free -h) +3. Disk space (use: df -h) + +If any resource is above 80%, log a warning to ~/workspace/alerts.log +``` + +### Example 3: News Digest + +**Cron Job:** + +```json +{ + "cron": { + "jobs": [ + { + "name": "news_digest", + "schedule": "0 8 * * *", + "prompt": "Search for tech news from the last 24 hours and create a brief summary of the top 5 stories", + "output": { + "channel": "telegram", + "chat_id": "123456789" + } + } + ] + } +} +``` + +### Example 4: Website Monitor + +**Heartbeat:** + +```markdown +# Website Monitor + +Every 10 minutes: +1. Fetch https://example.com/health +2. If response is not 200, log to ~/workspace/outages.log +3. If this is a new outage, create an alert message +``` + +### Example 5: IoT Sensor Logger + +**Heartbeat:** + +```markdown +# Sensor Logger + +Every minute: +1. Read temperature from I2C sensor at address 0x76 +2. Read humidity +3. Append to ~/workspace/sensors.csv with timestamp +4. Alert if temperature > 30 or humidity > 80 +``` + +## Part 4: Viewing Task History + +### Cron Logs + +```bash +picoclaw cron logs +``` + +Output: + +``` +Time Job Status Result +---------------------------------------------------------------- +2024-01-15 09:00:00 morning_summary success Generated summary... +2024-01-15 10:00:00 hourly_check success System OK +2024-01-15 11:00:00 hourly_check success System OK +``` + +### Heartbeat Logs + +Check the workspace logs: + +```bash +cat ~/.picoclaw/workspace/heartbeat.log +``` + +## Part 5: Best Practices + +### Use Appropriate Intervals + +| Task Type | Recommended Interval | +|-----------|---------------------| +| Critical monitoring | 1-5 minutes | +| Regular checks | 5-15 minutes | +| Daily tasks | Once per day | +| Weekly summaries | Once per week | + +### Error Handling + +Include error handling in your prompts: + +```markdown +When performing tasks: +- If an operation fails, log the error +- Try up to 3 times before giving up +- Report failures clearly +``` + +### Resource Management + +Avoid resource-intensive tasks: + +```markdown +Guidelines: +- Keep operations quick (< 30 seconds) +- Don't create large files +- Clean up temporary data +- Use efficient commands +``` + +### Idempotency + +Make tasks idempotent (safe to run multiple times): + +```markdown +Before performing actions: +- Check if action is needed +- Don't duplicate work +- Update timestamps, don't create new entries +``` + +## Troubleshooting + +### Cron Jobs Not Running + +1. Check cron is enabled: + ```json + {"cron": {"enabled": true}} + ``` + +2. Verify schedule syntax: + ```bash + # Test cron expression + crontab -e + # Add: * * * * * echo "test" >> /tmp/cron-test + ``` + +3. Check gateway is running + +### Heartbeat Not Working + +1. Check heartbeat is enabled: + ```bash + picoclaw agent --debug --heartbeat + ``` + +2. Verify HEARTBEAT.md exists: + ```bash + cat ~/.picoclaw/workspace/HEARTBEAT.md + ``` + +3. Check interval is reasonable + +### Tasks Taking Too Long + +1. Reduce task complexity +2. Increase interval +3. Use simpler prompts + +## Next Steps + +- [Multi-Agent Tutorial](multi-agent-setup.md) - Run specialized agents +- [Cron Tool Docs](../user-guide/tools/cron.md) - Full cron documentation +- [Heartbeat Docs](../user-guide/workspace/heartbeat-tasks.md) - Heartbeat details + +## Summary + +You learned: +- How to create and manage cron jobs +- How to configure heartbeat tasks +- Practical scheduling examples +- Best practices for automated tasks + +You can now automate your PicoClaw assistant! diff --git a/docs/tutorials/skill-development.md b/docs/tutorials/skill-development.md new file mode 100644 index 0000000000..99a99928b4 --- /dev/null +++ b/docs/tutorials/skill-development.md @@ -0,0 +1,512 @@ +# Skill Development Tutorial + +This tutorial guides you through creating custom skills for PicoClaw. + +## Prerequisites + +- 30 minutes +- PicoClaw installed and configured +- Basic understanding of PicoClaw tools +- Text editor for creating files + +## Overview + +Skills are reusable packages that extend PicoClaw capabilities: + +``` +┌─────────────────────────────────────────┐ +│ Skill │ +├─────────────────────────────────────────┤ +│ skill.md - Behavior prompts │ +│ tools.json - Custom tool definitions │ +│ templates/ - File templates │ +│ examples/ - Usage examples │ +└─────────────────────────────────────────┘ +``` + +## Part 1: Understanding Skills + +### What Skills Can Do + +- Define specialized behavior prompts +- Provide domain-specific knowledge +- Include templates and examples +- Configure tool usage + +### Skill Location + +Skills are stored in the workspace: + +``` +~/.picoclaw/workspace/skills/ +├── built-in/ # System skills +├── custom/ # Your custom skills +└── installed/ # Installed from external sources +``` + +## Part 2: Create Your First Skill + +### Example: Meeting Notes Skill + +Create a skill for managing meeting notes. + +#### Create Skill Directory + +```bash +mkdir -p ~/.picoclaw/workspace/skills/meeting-notes +cd ~/.picoclaw/workspace/skills/meeting-notes +``` + +#### Create skill.md + +```bash +nano skill.md +``` + +```markdown +# Meeting Notes Skill + +## Purpose +Help users capture, organize, and search meeting notes. + +## Behavior +When helping with meeting notes: +1. Use consistent formatting +2. Extract action items automatically +3. Identify attendees and decisions +4. Store notes with timestamps + +## Note Format +```markdown +# Meeting: [Title] +Date: [Date] +Attendees: [List] + +## Agenda +- [Item 1] +- [Item 2] + +## Discussion +[Key points] + +## Decisions +- [Decision 1] +- [Decision 2] + +## Action Items +- [ ] [Task] - [Owner] - [Due Date] +``` + +## Commands +- "New meeting note" - Create a new note +- "Add action item" - Add to current meeting +- "List meetings" - Show recent meetings +- "Search notes" - Search through all notes +``` + +#### Test the Skill + +```bash +picoclaw agent -m "Use the meeting-notes skill to create a new meeting note about project planning" +``` + +## Part 3: Add Custom Tools + +### Create tools.json + +Some skills benefit from custom tool definitions: + +```bash +nano tools.json +``` + +```json +{ + "tools": [ + { + "name": "create_meeting", + "description": "Create a new meeting note file", + "parameters": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Meeting title" + }, + "attendees": { + "type": "array", + "items": {"type": "string"}, + "description": "List of attendee names" + }, + "date": { + "type": "string", + "description": "Meeting date (YYYY-MM-DD)" + } + }, + "required": ["title"] + }, + "implementation": { + "type": "write_file", + "path_template": "meetings/{{date}}-{{slugify title}}.md", + "content_template": "# Meeting: {{title}}\nDate: {{date}}\nAttendees: {{join attendees ', '}}\n\n## Agenda\n\n## Discussion\n\n## Decisions\n\n## Action Items\n" + } + } + ] +} +``` + +## Part 4: Add Templates + +### Create Templates Directory + +```bash +mkdir -p templates +nano templates/meeting.md +``` + +```markdown +# Meeting: {{title}} +Date: {{date}} +Time: {{time}} +Attendees: {{attendees}} + +## Agenda +{{#each agenda_items}} +- {{this}} +{{/each}} + +## Discussion +{{discussion}} + +## Decisions +{{#each decisions}} +- {{this}} +{{/each}} + +## Action Items +{{#each action_items}} +- [ ] {{this.task}} - {{this.owner}} - {{this.due}} +{{/each}} + +--- +Created with PicoClaw Meeting Notes Skill +``` + +## Part 5: Add Examples + +### Create Examples + +```bash +mkdir -p examples +nano examples/basic-usage.md +``` + +```markdown +# Meeting Notes Examples + +## Example 1: Create a Meeting Note + +User: "Create a meeting note for today's standup with Alice, Bob, and Carol" + +Agent creates: meetings/2024-01-15-standup.md + +## Example 2: Add Action Items + +User: "Add action item: Bob will finish the API by Friday" + +Agent appends to current meeting: +- [ ] Finish the API - Bob - Friday + +## Example 3: Search Notes + +User: "Search meeting notes for 'budget'" + +Agent searches all meeting files and returns matches. +``` + +## Part 6: Skill Manifest + +Create a manifest for sharing: + +```bash +nano skill.json +``` + +```json +{ + "name": "meeting-notes", + "version": "1.0.0", + "description": "Capture and organize meeting notes", + "author": "Your Name", + "tags": ["productivity", "notes", "meetings"], + "min_picoclaw_version": "1.0.0", + "files": [ + "skill.md", + "tools.json", + "templates/meeting.md", + "examples/basic-usage.md" + ] +} +``` + +## Part 7: More Skill Examples + +### Example: Code Review Skill + +```markdown +# Code Review Skill + +## Purpose +Provide thorough code reviews with actionable feedback. + +## Review Checklist +1. **Functionality**: Does the code do what it's supposed to? +2. **Readability**: Is the code easy to understand? +3. **Performance**: Are there obvious bottlenecks? +4. **Security**: Are there potential vulnerabilities? +5. **Testing**: Is there adequate test coverage? + +## Output Format +```markdown +## Code Review + +### Summary +[Brief overall impression] + +### Strengths +- [What's done well] + +### Issues +#### Critical +- [Must fix] + +#### Suggestions +- [Nice to have] + +### Questions +- [Clarification needed] +``` + +## Commands +- "Review this code: [paste code]" +- "Review file [path]" +- "Check for security issues in [path]" +``` + +### Example: Documentation Skill + +```markdown +# Documentation Skill + +## Purpose +Generate and maintain technical documentation. + +## Capabilities +- Generate API documentation +- Create README files +- Write user guides +- Document code comments + +## Documentation Style +- Clear and concise +- Include code examples +- Use proper markdown formatting +- Add diagrams where helpful + +## Templates Available +- README.md +- API_REFERENCE.md +- CONTRIBUTING.md +- CHANGELOG.md +``` + +### Example: DevOps Skill + +```markdown +# DevOps Skill + +## Purpose +Help with deployment, CI/CD, and infrastructure. + +## Capabilities +- Docker configuration +- CI/CD pipeline setup +- Kubernetes manifests +- Infrastructure as code + +## Best Practices +- Use version control +- Implement proper logging +- Set up monitoring +- Configure alerts +- Use secrets management + +## Common Tasks +- "Create a Dockerfile for [app]" +- "Set up GitHub Actions for [project]" +- "Create Kubernetes deployment for [service]" +``` + +## Part 8: Using Skills + +### List Available Skills + +```bash +picoclaw skills list +``` + +### Use a Skill + +```bash +# In conversation +picoclaw agent -m "Use the meeting-notes skill to create a note" + +# Or load skill explicitly +picoclaw agent --skill meeting-notes -m "Create a new meeting note" +``` + +### Skill Auto-Loading + +Skills in the workspace are automatically available: + +``` +User: "Create a meeting note for my standup" + +Agent recognizes the meeting-notes skill context and uses it. +``` + +## Part 9: Sharing Skills + +### Package for Distribution + +```bash +# Create archive +cd ~/.picoclaw/workspace/skills +tar -czvf meeting-notes-skill.tar.gz meeting-notes/ +``` + +### Install from Archive + +```bash +picoclaw skills install meeting-notes-skill.tar.gz +``` + +### Install from URL + +```bash +picoclaw skills install https://example.com/skills/meeting-notes.tar.gz +``` + +### Install from GitHub + +```bash +picoclaw skills install github:user/picoclaw-skills/meeting-notes +``` + +## Part 10: Testing Skills + +### Manual Testing + +```bash +# Test basic functionality +picoclaw agent -m "Use meeting-notes to create a test meeting" + +# Verify file creation +ls ~/.picoclaw/workspace/meetings/ + +# Test edge cases +picoclaw agent -m "Create a meeting note with no attendees" +``` + +### Debug Mode + +```bash +picoclaw agent --debug -m "Use meeting-notes skill" +``` + +## Best Practices + +### 1. Clear Purpose + +Each skill should have one clear purpose: + +``` +Good: "Create and manage meeting notes" +Bad: "Handle meetings, emails, and documents" +``` + +### 2. Specific Instructions + +Give explicit instructions in skill.md: + +```markdown +## Behavior +1. Always ask for missing required fields +2. Use ISO date format (YYYY-MM-DD) +3. Create backups before modifying +``` + +### 3. Error Handling + +Include error handling guidance: + +```markdown +## Error Handling +- If file exists, prompt to overwrite or append +- If template is missing, use default format +- If date is invalid, use current date +``` + +### 4. Examples + +Provide usage examples: + +```markdown +## Examples + +### Creating a Meeting +User: "New meeting: Project kickoff with John and Jane" +Creates: meetings/2024-01-15-project-kickoff.md + +### Adding Actions +User: "Add action: John to prepare slides by Wednesday" +Appends action item to current meeting +``` + +## Troubleshooting + +### Skill Not Loading + +1. Check file permissions +2. Verify skill.md syntax +3. Check workspace path + +### Unexpected Behavior + +1. Review skill.md instructions +2. Check for conflicts with other skills +3. Use debug mode + +### Tools Not Working + +1. Verify tools.json syntax +2. Check parameter definitions +3. Test tool calls in debug mode + +## Next Steps + +- [Skills Documentation](../user-guide/skills/README.md) +- [Built-in Skills](../user-guide/skills/builtin-skills.md) +- [Creating Skills Guide](../user-guide/skills/creating-skills.md) + +## Summary + +You learned: +- What skills are and how they work +- How to create skill.md behavior files +- How to add custom tools +- How to use templates +- How to package and share skills +- Best practices for skill development + +You can now extend PicoClaw with custom skills! diff --git a/docs/tutorials/telegram-bot.md b/docs/tutorials/telegram-bot.md new file mode 100644 index 0000000000..85cbe329d4 --- /dev/null +++ b/docs/tutorials/telegram-bot.md @@ -0,0 +1,436 @@ +# Telegram Bot Tutorial + +This tutorial guides you through creating a Telegram chatbot with PicoClaw. + +## Prerequisites + +- 15 minutes +- PicoClaw installed and configured +- A Telegram account +- A configured LLM provider (see [Basic Assistant](basic-assistant.md)) + +## Step 1: Create a Telegram Bot + +### Talk to BotFather + +1. Open Telegram +2. Search for `@BotFather` +3. Start a conversation + +### Create New Bot + +Send `/newbot` to BotFather: + +``` +You: /newbot +BotFather: Alright, a new bot. How are we going to call it? + Please choose a name for your bot. + +You: My PicoClaw Assistant +BotFather: Good. Now let's choose a username for your bot. + It must end in `bot`. Like this, for example: TetrisBot or tetris_bot. + +You: my_picoclaw_assistant_bot +BotFather: Done! Congratulations on your new bot... + Use this token to access the HTTP API: + 7123456789:AAHxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Keep your token secure... +``` + +### Save the Token + +Copy and save the bot token (the long string starting with numbers). You'll need it for configuration. + +## Step 2: Get Your User ID + +### Use userinfobot + +1. Search for `@userinfobot` +2. Start a conversation +3. It will reply with your user ID + +``` +You: /start +UserInfoBot: Your user ID: 123456789 +``` + +Save this ID for the allow list. + +## Step 3: Configure PicoClaw + +### Edit Configuration + +```bash +nano ~/.picoclaw/config.json +``` + +Add Telegram channel configuration: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "anthropic/claude-opus-4-5" + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + }, + "channels": { + "telegram": { + "enabled": true, + "token": "7123456789:AAHxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "allow_from": [123456789] + } + } +} +``` + +Replace: +- `7123456789:AAH...` with your bot token +- `123456789` with your user ID + +### Configuration Options + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Enable the channel | +| `token` | Yes | Bot token from BotFather | +| `allow_from` | Recommended | List of allowed user IDs | + +## Step 4: Start the Gateway + +The gateway connects PicoClaw to Telegram: + +```bash +picoclaw gateway +``` + +Output: + +``` +2024-01-15T10:30:00Z INFO main Starting PicoClaw gateway... +2024-01-15T10:30:00Z INFO channel Connecting to Telegram... +2024-01-15T10:30:01Z INFO channel Telegram connected as @my_picoclaw_assistant_bot +2024-01-15T10:30:01Z INFO main Gateway started on port 18790 +``` + +## Step 5: Test Your Bot + +### Send a Message + +1. Open Telegram +2. Find your bot +3. Send `/start` +4. Send any message + +``` +You: Hello! +Bot: Hello! I'm your PicoClaw assistant. How can I help you today? + +You: What time is it? +Bot: [Uses exec tool] + The current time is 10:35 AM. + +You: Search for the weather +Bot: [Uses web_search tool] + Based on my search, the weather today is... +``` + +## Step 6: Debug Mode + +If something isn't working, run with debug output: + +```bash +picoclaw gateway --debug +``` + +This shows: +- Incoming messages +- LLM requests +- Tool calls +- Outgoing responses + +## Step 7: Customize Bot Behavior + +### Edit AGENT.md + +Customize how your bot responds: + +```bash +nano ~/.picoclaw/workspace/AGENT.md +``` + +```markdown +# Telegram Bot Behavior + +You are a helpful Telegram assistant. + +## Response Style +- Keep messages concise (Telegram users prefer brief responses) +- Use emoji sparingly +- Format long responses in paragraphs + +## Capabilities +- Answer questions +- Search the web +- Manage files + +## Commands +Respond helpfully to these commands: +- /start - Greet the user +- /help - Show available features +- /status - Show system status +``` + +### Restart Gateway + +After editing: + +```bash +# Stop the gateway (Ctrl+C) +# Start again +picoclaw gateway +``` + +## Step 8: Add More Users + +### Get Their User IDs + +Have other users message `@userinfobot` to get their IDs. + +### Update Allow List + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "your-bot-token", + "allow_from": [123456789, 987654321, 555555555] + } + } +} +``` + +### Allow All Users (Not Recommended) + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "your-bot-token", + "allow_from": [] + } + } +} +``` + +Warning: An empty `allow_from` allows anyone to use your bot and consume your API quota. + +## Step 9: Group Chats + +To use in Telegram groups: + +### Get Group ID + +1. Add `@RawDataBot` to your group +2. Send any message +3. It will reply with the group ID (negative number) + +### Configure + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "your-bot-token", + "allow_from": [123456789, -1001234567890] + } + } +} +``` + +### Privacy Mode + +By default, bots only see: +- Commands (messages starting with `/`) +- Messages where the bot is mentioned +- Replies to the bot's messages + +To receive all messages, disable privacy mode: + +1. Talk to @BotFather +2. Send `/setprivacy` +3. Select your bot +4. Choose "Disable" + +## Step 10: Set Bot Commands + +Define commands in BotFather: + +1. Send `/setcommands` to @BotFather +2. Select your bot +3. Paste: + +``` +start - Start the bot +help - Show help +status - Check system status +clear - Clear conversation history +``` + +Now users will see command suggestions when typing `/`. + +## Step 11: Run as Background Service + +### Using Systemd (Linux) + +Create a service file: + +```bash +sudo nano /etc/systemd/system/picoclaw.service +``` + +```ini +[Unit] +Description=PicoClaw Gateway +After=network.target + +[Service] +Type=simple +User=your-username +WorkingDirectory=/home/your-username +ExecStart=/usr/local/bin/picoclaw gateway +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +``` + +Enable and start: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable picoclaw +sudo systemctl start picoclaw +``` + +Check status: + +```bash +sudo systemctl status picoclaw +``` + +### Using Docker + +```bash +docker run -d \ + --name picoclaw \ + -v ~/.picoclaw:/root/.picoclaw \ + picoclaw:latest gateway +``` + +## Troubleshooting + +### Bot Not Responding + +1. Check gateway is running: + ```bash + picoclaw gateway --debug + ``` + +2. Verify token is correct: + ```bash + curl https://api.telegram.org/botYOUR_TOKEN/getMe + ``` + +3. Check user ID is in allow list + +### Conflict Error + +``` +Conflict: terminated by other getUpdates request +``` + +Only one instance can use the bot token: +1. Stop other instances +2. Wait a few seconds +3. Restart gateway + +### Rate Limits + +Telegram has rate limits: +- 30 messages/second to different users +- 1 message/second to same user + +PicoClaw handles rate limiting automatically. + +## Advanced Features + +### Voice Messages + +Enable voice transcription with Groq: + +```json +{ + "providers": { + "groq": { + "api_key": "your-groq-api-key" + } + }, + "agents": { + "defaults": { + "voice_transcription": { + "enabled": true, + "provider": "groq" + } + } + } +} +``` + +### Webhook Mode (Production) + +For production deployments, use webhooks instead of polling: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "your-token", + "webhook": { + "enabled": true, + "url": "https://your-domain.com/telegram/webhook", + "port": 8443 + } + } + } +} +``` + +## Next Steps + +Now that you have a working Telegram bot: + +- [Scheduled Tasks Tutorial](scheduled-tasks.md) - Automate periodic tasks +- [Multi-Agent Tutorial](multi-agent-setup.md) - Specialized agents +- [Telegram Channel Docs](../user-guide/channels/telegram.md) - Full configuration + +## Summary + +You learned: +- How to create a Telegram bot with BotFather +- How to configure the Telegram channel +- How to run the gateway +- How to customize bot behavior +- How to deploy as a service + +Your PicoClaw assistant is now available on Telegram! diff --git a/docs/user-guide/README.md b/docs/user-guide/README.md new file mode 100644 index 0000000000..47dda824ed --- /dev/null +++ b/docs/user-guide/README.md @@ -0,0 +1,79 @@ +# User Guide + +Complete documentation for using PicoClaw features. + +## Topics + +### CLI Reference + +- [CLI Overview](cli-reference.md) - All commands and options + +### Channels + +Chat platform integrations. + +- [Channels Overview](channels/README.md) - Supported platforms +- [Telegram](channels/telegram.md) - Telegram bot setup +- [Discord](channels/discord.md) - Discord bot setup +- [Slack](channels/slack.md) - Slack integration +- [WeCom](channels/wecom.md) - WeCom (Enterprise WeChat) +- [And more...](channels/README.md) + +### Providers + +LLM provider configuration. + +- [Providers Overview](providers/README.md) - All supported providers +- [OpenRouter](providers/openrouter.md) - Multi-model access +- [Anthropic](providers/anthropic.md) - Claude models +- [Ollama](providers/ollama.md) - Local models +- [And more...](providers/README.md) + +### IDE Setup + +IDE integrations for free AI access. + +- [IDE Setup Overview](ide-setup/README.md) +- [Antigravity](ide-setup/antigravity.md) - Google Cloud Code Assist + +### Workspace + +Customizing agent behavior. + +- [Workspace Overview](workspace/README.md) +- [AGENT.md](workspace/agent-md.md) - Behavior customization +- [Memory](workspace/memory.md) - Long-term memory +- [Heartbeat Tasks](workspace/heartbeat-tasks.md) - Periodic tasks + +### Tools + +Available tools and capabilities. + +- [Tools Overview](tools/README.md) +- [File System](tools/filesystem.md) - read_file, write_file +- [Exec](tools/exec.md) - Shell commands +- [Web](tools/web.md) - web_search, web_fetch +- [Messaging](tools/messaging.md) - Send messages +- [Spawn](tools/spawn.md) - Subagents +- [Cron](tools/cron.md) - Scheduled tasks + +### Skills + +Skills system for extending capabilities. + +- [Skills Overview](skills/README.md) +- [Using Skills](skills/using-skills.md) +- [Installing Skills](skills/installing-skills.md) +- [Creating Skills](skills/creating-skills.md) + +### Advanced Features + +Advanced configuration and multi-agent setups. + +- [Multi-Agent System](advanced/multi-agent.md) +- [Message Routing](advanced/routing.md) +- [Session Management](advanced/session-management.md) +- [Model Fallbacks](advanced/model-fallbacks.md) +- [Security Sandbox](advanced/security-sandbox.md) +- [Environment Variables](advanced/environment-variables.md) +- [Voice Transcription](advanced/voice-transcription.md) diff --git a/docs/user-guide/advanced/README.md b/docs/user-guide/advanced/README.md new file mode 100644 index 0000000000..afb169300d --- /dev/null +++ b/docs/user-guide/advanced/README.md @@ -0,0 +1,92 @@ +# Advanced Features + +This section covers advanced configuration and features of PicoClaw for power users and complex deployment scenarios. + +## Overview + +PicoClaw provides several advanced features that enable sophisticated multi-agent architectures, robust model fallback chains, and fine-grained control over security and routing. + +## Topics + +### Multi-Agent System + +- **[Multi-Agent Configuration](multi-agent.md)** - Configure multiple specialized agents with isolated workspaces and different models + +### Routing and Sessions + +- **[Message Routing](routing.md)** - Route messages from channels to specific agents using bindings +- **[Session Management](session-management.md)** - Handle conversation persistence, identity linking, and session scoping + +### Reliability + +- **[Model Fallbacks](model-fallbacks.md)** - Configure automatic fallback chains for high availability + +### Security + +- **[Security Sandbox](security-sandbox.md)** - Restrict file and command access to protect your system + +### Configuration + +- **[Environment Variables](environment-variables.md)** - Complete reference for all environment variables + +### Voice Features + +- **[Voice Transcription](voice-transcription.md)** - Enable voice message transcription using Groq Whisper + +## Architecture Overview + +PicoClaw follows a message bus architecture where: + +1. **Channels** (Telegram, Discord, Slack, etc.) receive messages from users +2. **Routing** determines which agent handles each message based on bindings +3. **Agents** process messages using LLM providers and tools +4. **Sessions** maintain conversation state and history + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ Telegram │ │ Discord │ │ Slack │ +└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ + │ │ │ + └───────────────────┼───────────────────┘ + │ + ┌──────▼──────┐ + │ Message Bus │ + └──────┬──────┘ + │ + ┌──────▼──────┐ + │ Routing │ + └──────┬──────┘ + │ + ┌───────────────────┼───────────────────┐ + │ │ │ +┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ +│ Agent A │ │ Agent B │ │ Agent C │ +│ (Research) │ │ (Coding) │ │ (Assistant) │ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +## Configuration Hierarchy + +PicoClaw uses a hierarchical configuration system: + +1. **Defaults** - Default values built into the application +2. **Config File** - Settings from `~/.picoclaw/config.json` +3. **Environment Variables** - Override config file settings +4. **Command-line Flags** - Override all other settings + +## Quick Reference + +| Feature | Config Section | Key Setting | +|---------|---------------|-------------| +| Multi-agent | `agents.list` | `id`, `workspace`, `model` | +| Routing | `bindings` | `agent_id`, `match` | +| Sessions | `session` | `dm_scope`, `identity_links` | +| Fallbacks | `agents.defaults` | `model_fallbacks` | +| Sandbox | `agents.defaults` | `restrict_to_workspace` | +| Voice | `providers.groq` | `api_key` | + +## Related Documentation + +- [Configuration File Reference](../../configuration/config-file.md) +- [CLI Reference](../cli-reference.md) +- [Workspace Management](../workspace/README.md) diff --git a/docs/user-guide/advanced/environment-variables.md b/docs/user-guide/advanced/environment-variables.md new file mode 100644 index 0000000000..b7c2002b39 --- /dev/null +++ b/docs/user-guide/advanced/environment-variables.md @@ -0,0 +1,363 @@ +# Environment Variables Reference + +All PicoClaw configuration options can be overridden with environment variables. This enables configuration management through environment files, container orchestration, and CI/CD pipelines. + +## Naming Convention + +Environment variables follow the pattern: + +``` +PICOCLAW_
__ +``` + +The path corresponds to the JSON configuration structure: + +```json +{ + "section": { + "subsection": { + "key": "value" + } + } +} +``` + +Becomes: `PICOCLAW_SECTION_SUBSECTION_KEY` + +## Agent Configuration + +### Defaults + +| Variable | Config Path | Description | +|----------|-------------|-------------| +| `PICOCLAW_AGENTS_DEFAULTS_WORKSPACE` | `agents.defaults.workspace` | Working directory | +| `PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE` | `agents.defaults.restrict_to_workspace` | Enable sandbox | +| `PICOCLAW_AGENTS_DEFAULTS_PROVIDER` | `agents.defaults.provider` | Default provider | +| `PICOCLAW_AGENTS_DEFAULTS_MODEL` | `agents.defaults.model` | Primary model | +| `PICOCLAW_AGENTS_DEFAULTS_MODEL_FALLBACKS` | `agents.defaults.model_fallbacks` | Fallback models (JSON array) | +| `PICOCLAW_AGENTS_DEFAULTS_IMAGE_MODEL` | `agents.defaults.image_model` | Image model | +| `PICOCLAW_AGENTS_DEFAULTS_IMAGE_MODEL_FALLBACKS` | `agents.defaults.image_model_fallbacks` | Image fallbacks | +| `PICOCLAW_AGENTS_DEFAULTS_MAX_TOKENS` | `agents.defaults.max_tokens` | Max response tokens | +| `PICOCLAW_AGENTS_DEFAULTS_TEMPERATURE` | `agents.defaults.temperature` | Response randomness | +| `PICOCLAW_AGENTS_DEFAULTS_MAX_TOOL_ITERATIONS` | `agents.defaults.max_tool_iterations` | Max tool loops | + +### Examples + +```bash +# Set primary model +export PICOCLAW_AGENTS_DEFAULTS_MODEL="anthropic/claude-opus-4-5" + +# Set fallback models (JSON array) +export PICOCLAW_AGENTS_DEFAULTS_MODEL_FALLBACKS='["gpt-4o", "glm-4.7"]' + +# Disable workspace restriction +export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE="false" +``` + +## Provider Configuration + +### Common Variables + +| Variable Pattern | Description | +|------------------|-------------| +| `PICOCLAW_PROVIDERS__API_KEY` | API key for provider | +| `PICOCLAW_PROVIDERS__API_BASE` | API base URL | +| `PICOCLAW_PROVIDERS__PROXY` | Proxy URL | +| `PICOCLAW_PROVIDERS__AUTH_METHOD` | Auth method | + +### Provider Names + +Replace `` with: `ANTHROPIC`, `OPENAI`, `OPENROUTER`, `GROQ`, `ZHIPU`, `GEMINI`, `OLLAMA`, `VLLM`, `NVIDIA`, `MOONSHOT`, `DEEPSEEK`, `GITHUB_COPILOT` + +### Examples + +```bash +# OpenRouter +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" +export PICOCLAW_PROVIDERS_OPENROUTER_API_BASE="https://openrouter.ai/api/v1" + +# Anthropic +export PICOCLAW_PROVIDERS_ANTHROPIC_API_KEY="sk-ant-xxx" + +# Groq +export PICOCLAW_PROVIDERS_GROQ_API_KEY="gsk_xxx" + +# OpenAI +export PICOCLAW_PROVIDERS_OPENAI_API_KEY="sk-xxx" +export PICOCLAW_PROVIDERS_OPENAI_WEB_SEARCH="true" + +# Ollama (local) +export PICOCLAW_PROVIDERS_OLLAMA_API_BASE="http://localhost:11434/v1" + +# vLLM (local) +export PICOCLAW_PROVIDERS_VLLM_API_BASE="http://localhost:8000/v1" +``` + +## Channel Configuration + +### Telegram + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_CHANNELS_TELEGRAM_ENABLED` | Enable Telegram | +| `PICOCLAW_CHANNELS_TELEGRAM_TOKEN` | Bot token | +| `PICOCLAW_CHANNELS_TELEGRAM_PROXY` | Proxy URL | +| `PICOCLAW_CHANNELS_TELEGRAM_ALLOW_FROM` | Allowed user IDs (JSON array) | + +### Discord + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_CHANNELS_DISCORD_ENABLED` | Enable Discord | +| `PICOCLAW_CHANNELS_DISCORD_TOKEN` | Bot token | +| `PICOCLAW_CHANNELS_DISCORD_ALLOW_FROM` | Allowed user IDs | + +### Slack + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_CHANNELS_SLACK_ENABLED` | Enable Slack | +| `PICOCLAW_CHANNELS_SLACK_BOT_TOKEN` | Bot token (xoxb-...) | +| `PICOCLAW_CHANNELS_SLACK_APP_TOKEN` | App token (xapp-...) | +| `PICOCLAW_CHANNELS_SLACK_ALLOW_FROM` | Allowed user IDs | + +### Other Channels + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_CHANNELS_WHATSAPP_ENABLED` | Enable WhatsApp | +| `PICOCLAW_CHANNELS_WHATSAPP_BRIDGE_URL` | Bridge WebSocket URL | +| `PICOCLAW_CHANNELS_FEISHU_ENABLED` | Enable Feishu | +| `PICOCLAW_CHANNELS_FEISHU_APP_ID` | Feishu App ID | +| `PICOCLAW_CHANNELS_FEISHU_APP_SECRET` | Feishu App Secret | +| `PICOCLAW_CHANNELS_LINE_ENABLED` | Enable LINE | +| `PICOCLAW_CHANNELS_LINE_CHANNEL_SECRET` | LINE Channel Secret | +| `PICOCLAW_CHANNELS_LINE_CHANNEL_ACCESS_TOKEN` | LINE Access Token | +| `PICOCLAW_CHANNELS_DINGTALK_ENABLED` | Enable DingTalk | +| `PICOCLAW_CHANNELS_DINGTALK_CLIENT_ID` | DingTalk Client ID | +| `PICOCLAW_CHANNELS_QQ_ENABLED` | Enable QQ | +| `PICOCLAW_CHANNELS_ONEBOT_ENABLED` | Enable OneBot | +| `PICOCLAW_CHANNELS_ONEBOT_WS_URL` | OneBot WebSocket URL | +| `PICOCLAW_CHANNELS_MAIXCAM_ENABLED` | Enable MaixCam | + +### Examples + +```bash +# Telegram +export PICOCLAW_CHANNELS_TELEGRAM_ENABLED="true" +export PICOCLAW_CHANNELS_TELEGRAM_TOKEN="123456:ABC..." +export PICOCLAW_CHANNELS_TELEGRAM_ALLOW_FROM='["123456789"]' + +# Discord +export PICOCLAW_CHANNELS_DISCORD_ENABLED="true" +export PICOCLAW_CHANNELS_DISCORD_TOKEN="MTk4NjIyNDgzNDc..." + +# Slack +export PICOCLAW_CHANNELS_SLACK_ENABLED="true" +export PICOCLAW_CHANNELS_SLACK_BOT_TOKEN="xoxb-xxx" +export PICOCLAW_CHANNELS_SLACK_APP_TOKEN="xapp-xxx" +``` + +## Tool Configuration + +### Web Tools + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_TOOLS_WEB_BRAVE_ENABLED` | Enable Brave Search | +| `PICOCLAW_TOOLS_WEB_BRAVE_API_KEY` | Brave API key | +| `PICOCLAW_TOOLS_WEB_BRAVE_MAX_RESULTS` | Max results | +| `PICOCLAW_TOOLS_WEB_DUCKDUCKGO_ENABLED` | Enable DuckDuckGo | +| `PICOCLAW_TOOLS_WEB_DUCKDUCKGO_MAX_RESULTS` | Max results | +| `PICOCLAW_TOOLS_WEB_PERPLEXITY_ENABLED` | Enable Perplexity | +| `PICOCLAW_TOOLS_WEB_PERPLEXITY_API_KEY` | Perplexity API key | +| `PICOCLAW_TOOLS_WEB_PERPLEXITY_MAX_RESULTS` | Max results | + +### Exec Tools + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS` | Enable command filtering | +| `PICOCLAW_TOOLS_EXEC_CUSTOM_DENY_PATTERNS` | Custom blocked patterns | + +### Cron Tools + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES` | Cron job timeout | + +### Examples + +```bash +# Enable Brave Search +export PICOCLAW_TOOLS_WEB_BRAVE_ENABLED="true" +export PICOCLAW_TOOLS_WEB_BRAVE_API_KEY="BSA..." +export PICOCLAW_TOOLS_WEB_BRAVE_MAX_RESULTS="5" + +# Disable DuckDuckGo +export PICOCLAW_TOOLS_WEB_DUCKDUCKGO_ENABLED="false" + +# Disable command filtering (not recommended) +export PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS="false" +``` + +## Gateway Configuration + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_GATEWAY_HOST` | Server host | +| `PICOCLAW_GATEWAY_PORT` | Server port | + +### Example + +```bash +export PICOCLAW_GATEWAY_HOST="0.0.0.0" +export PICOCLAW_GATEWAY_PORT="18790" +``` + +## Heartbeat Configuration + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_HEARTBEAT_ENABLED` | Enable periodic tasks | +| `PICOCLAW_HEARTBEAT_INTERVAL` | Check interval (minutes) | + +### Example + +```bash +export PICOCLAW_HEARTBEAT_ENABLED="true" +export PICOCLAW_HEARTBEAT_INTERVAL="30" +``` + +## Devices Configuration + +| Variable | Description | +|----------|-------------| +| `PICOCLAW_DEVICES_ENABLED` | Enable device monitoring | +| `PICOCLAW_DEVICES_MONITOR_USB` | Monitor USB devices | + +## Docker Example + +Complete Docker environment configuration: + +```dockerfile +# Dockerfile +FROM alpine:latest + +ENV PICOCLAW_AGENTS_DEFAULTS_MODEL="anthropic/claude-opus-4-5" +ENV PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE="true" +ENV PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" +ENV PICOCLAW_CHANNELS_TELEGRAM_ENABLED="true" +ENV PICOCLAW_CHANNELS_TELEGRAM_TOKEN="123456:ABC..." +ENV PICOCLAW_HEARTBEAT_ENABLED="false" + +COPY picoclaw /usr/local/bin/ +CMD ["picoclaw", "gateway"] +``` + +## Docker Compose Example + +```yaml +version: '3' +services: + picoclaw: + image: picoclaw:latest + environment: + - PICOCLAW_AGENTS_DEFAULTS_MODEL=anthropic/claude-opus-4-5 + - PICOCLAW_PROVIDERS_OPENROUTER_API_KEY=${OPENROUTER_API_KEY} + - PICOCLAW_PROVIDERS_GROQ_API_KEY=${GROQ_API_KEY} + - PICOCLAW_CHANNELS_TELEGRAM_ENABLED=true + - PICOCLAW_CHANNELS_TELEGRAM_TOKEN=${TELEGRAM_TOKEN} + - PICOCLAW_CHANNELS_DISCORD_ENABLED=true + - PICOCLAW_CHANNELS_DISCORD_TOKEN=${DISCORD_TOKEN} + volumes: + - picoclaw-data:/root/.picoclaw + restart: unless-stopped + +volumes: + picoclaw-data: +``` + +## Kubernetes Example + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: picoclaw-secrets +type: Opaque +stringData: + openrouter-api-key: "sk-or-v1-xxx" + telegram-token: "123456:ABC..." +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: picoclaw-config +data: + PICOCLAW_AGENTS_DEFAULTS_MODEL: "anthropic/claude-opus-4-5" + PICOCLAW_CHANNELS_TELEGRAM_ENABLED: "true" + PICOCLAW_HEARTBEAT_ENABLED: "true" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: picoclaw +spec: + template: + spec: + containers: + - name: picoclaw + image: picoclaw:latest + envFrom: + - configMapRef: + name: picoclaw-config + env: + - name: PICOCLAW_PROVIDERS_OPENROUTER_API_KEY + valueFrom: + secretKeyRef: + name: picoclaw-secrets + key: openrouter-api-key + - name: PICOCLAW_CHANNELS_TELEGRAM_TOKEN + valueFrom: + secretKeyRef: + name: picoclaw-secrets + key: telegram-token +``` + +## .env File Example + +Create a `.env` file for local development: + +```bash +# .env +PICOCLAW_AGENTS_DEFAULTS_MODEL=anthropic/claude-opus-4-5 +PICOCLAW_AGENTS_DEFAULTS_MODEL_FALLBACKS='["gpt-4o", "glm-4.7"]' + +# Providers +PICOCLAW_PROVIDERS_OPENROUTER_API_KEY=sk-or-v1-xxx +PICOCLAW_PROVIDERS_GROQ_API_KEY=gsk_xxx +PICOCLAW_PROVIDERS_ANTHROPIC_API_KEY=sk-ant-xxx + +# Channels +PICOCLAW_CHANNELS_TELEGRAM_ENABLED=true +PICOCLAW_CHANNELS_TELEGRAM_TOKEN=123456:ABC... +PICOCLAW_CHANNELS_DISCORD_ENABLED=false + +# Tools +PICOCLAW_TOOLS_WEB_DUCKDUCKGO_ENABLED=true +PICOCLAW_TOOLS_WEB_BRAVE_ENABLED=false +``` + +Load with: + +```bash +source .env +picoclaw gateway +``` + +## Related Topics + +- [Configuration File Reference](../../configuration/config-file.md) - JSON configuration +- [Security Sandbox](security-sandbox.md) - Security settings +- [Providers](../providers/README.md) - Provider configuration diff --git a/docs/user-guide/advanced/model-fallbacks.md b/docs/user-guide/advanced/model-fallbacks.md new file mode 100644 index 0000000000..55bd11305f --- /dev/null +++ b/docs/user-guide/advanced/model-fallbacks.md @@ -0,0 +1,303 @@ +# Model Fallbacks + +PicoClaw supports automatic fallback chains for LLM models, ensuring high availability even when primary models are unavailable. This guide explains how to configure and understand fallback behavior. + +## Overview + +The fallback system provides: + +- **High availability** - Automatically switch to backup models on failure +- **Rate limit handling** - Cooldown tracking for rate-limited providers +- **Intelligent error classification** - Only retry on retriable errors +- **Image model support** - Separate fallback chains for vision tasks + +## Configuration + +### Simple Fallbacks (Defaults) + +Configure fallback models at the agent defaults level: + +```json +{ + "agents": { + "defaults": { + "model": "anthropic/claude-opus-4-5", + "model_fallbacks": ["anthropic/claude-sonnet-4", "gpt-4o", "glm-4.7"] + } + } +} +``` + +### Structured Model Configuration + +For multi-agent setups, use the object format: + +```json +{ + "agents": { + "list": [ + { + "id": "assistant", + "model": { + "primary": "anthropic/claude-opus-4-5", + "fallbacks": ["anthropic/claude-sonnet-4", "gpt-4o"] + } + } + ] + } +} +``` + +### Image Model Fallbacks + +Configure separate fallbacks for image/vision tasks: + +```json +{ + "agents": { + "defaults": { + "image_model": "anthropic/claude-opus-4-5", + "image_model_fallbacks": ["gpt-4o", "anthropic/claude-sonnet-4"] + } + } +} +``` + +## Model Format + +Models are specified in the format `provider/model`: + +``` +anthropic/claude-opus-4-5 +openrouter/anthropic/claude-opus-4-5 +groq/llama-3.1-70b-versatile +openai/gpt-4o +zhipu/glm-4.7 +``` + +If no provider is specified, the default provider is used. + +## Fallback Behavior + +### Execution Order + +1. Try primary model +2. If failure, try first fallback +3. Continue through fallbacks until success +4. If all fail, return aggregate error + +### Error Classification + +The system classifies errors to decide whether to fallback: + +| Error Type | Retriable | Action | +|------------|-----------|--------| +| Rate limit (429) | Yes | Fallback with cooldown | +| Server error (5xx) | Yes | Fallback immediately | +| Timeout | Yes | Fallback immediately | +| Invalid request (400) | No | Return error immediately | +| Auth error (401/403) | No | Return error immediately | +| Context canceled | No | Return error immediately | + +### Cooldown Tracking + +When a provider hits rate limits, it enters cooldown: + +- **Duration**: Based on rate limit response +- **Effect**: Provider is skipped during cooldown +- **Recovery**: Provider used again after cooldown expires + +### Success Handling + +When a request succeeds: + +1. Response is returned immediately +2. Provider cooldown is reset +3. No further fallbacks are attempted + +## Fallback Chain Resolution + +The system deduplicates models in the chain: + +```json +{ + "model": { + "primary": "gpt-4o", + "fallbacks": ["gpt-4o", "anthropic/claude-sonnet-4", "gpt-4o"] + } +} +``` + +Resolves to: `gpt-4o`, `anthropic/claude-sonnet-4` + +## Example Scenarios + +### Scenario 1: Primary Rate Limited + +``` +Request → claude-opus-4-5 (429 rate limit) + → claude-sonnet-4 (success) + → Return response +``` + +### Scenario 2: All Models Fail + +``` +Request → claude-opus-4-5 (500 server error) + → gpt-4o (429 rate limit) + → glm-4.7 (timeout) + → Return aggregate error with all attempts +``` + +### Scenario 3: Non-Retriable Error + +``` +Request → claude-opus-4-5 (400 invalid request) + → Return error immediately (no fallback) +``` + +### Scenario 4: Provider in Cooldown + +``` +Request → claude-opus-4-5 (skipped - in cooldown) + → gpt-4o (success) + → Return response +``` + +## Image Model Fallbacks + +Image/vision requests use a simplified fallback chain: + +- **No cooldown checks** - Image endpoints have different rate limits +- **Dimension errors abort** - Image size errors are non-retriable +- **Same fallback order** - Uses configured fallback list + +### Configuration + +```json +{ + "agents": { + "defaults": { + "image_model": "anthropic/claude-opus-4-5", + "image_model_fallbacks": ["gpt-4o"] + } + } +} +``` + +## Subagent Model Overrides + +Control which models spawned subagents use: + +```json +{ + "agents": { + "list": [ + { + "id": "assistant", + "subagents": { + "allow_agents": ["researcher"], + "model": { + "primary": "gpt-4o-mini", + "fallbacks": ["glm-4-flash"] + } + } + } + ] + } +} +``` + +## Debugging Fallbacks + +Enable debug mode to see fallback decisions: + +```bash +picoclaw agent --debug -m "Hello" +``` + +Debug output includes: + +- Candidate model list +- Each attempt and its result +- Cooldown status +- Final successful model or error + +### Example Debug Output + +``` +[providers] Resolved candidates: [claude-opus-4-5, claude-sonnet-4, gpt-4o] +[providers] Attempt 1: claude-opus-4-5 - rate limited (cooldown: 60s) +[providers] Attempt 2: claude-sonnet-4 - success (1.2s) +[providers] Fallback complete: claude-sonnet-4 +``` + +## Environment Variables + +Override model configuration with environment variables: + +```bash +# Primary model +export PICOCLAW_AGENTS_DEFAULTS_MODEL="anthropic/claude-opus-4-5" + +# Fallback models (JSON array) +export PICOCLAW_AGENTS_DEFAULTS_MODEL_FALLBACKS='["gpt-4o", "glm-4.7"]' + +# Image model +export PICOCLAW_AGENTS_DEFAULTS_IMAGE_MODEL="gpt-4o" +``` + +## Best Practices + +### 1. Order by Preference + +List models in order of quality/preference: + +```json +{ + "model_fallbacks": ["claude-sonnet-4", "gpt-4o", "glm-4.7"] +} +``` + +### 2. Mix Providers + +Use different providers to avoid single points of failure: + +```json +{ + "model_fallbacks": [ + "anthropic/claude-sonnet-4", + "openai/gpt-4o", + "zhipu/glm-4.7" + ] +} +``` + +### 3. Consider Costs + +Order by cost when appropriate: + +```json +{ + "model_fallbacks": [ + "groq/llama-3.1-70b-versatile", + "openai/gpt-4o-mini", + "anthropic/claude-sonnet-4" + ] +} +``` + +### 4. Test Fallback Chain + +Verify your fallback chain works: + +```bash +# Simulate primary failure by using invalid API key +picoclaw agent --debug -m "Test" +``` + +## Related Topics + +- [Multi-Agent System](multi-agent.md) - Agent-specific model configuration +- [Providers](../providers/README.md) - Configure LLM providers +- [Environment Variables](environment-variables.md) - Override settings diff --git a/docs/user-guide/advanced/multi-agent.md b/docs/user-guide/advanced/multi-agent.md new file mode 100644 index 0000000000..cb1676b546 --- /dev/null +++ b/docs/user-guide/advanced/multi-agent.md @@ -0,0 +1,316 @@ +# Multi-Agent System + +PicoClaw supports running multiple specialized agents, each with its own configuration, workspace, and model settings. This enables scenarios like having separate agents for research, coding, general assistance, or different teams. + +## Overview + +The multi-agent system allows you to: + +- Create specialized agents for different tasks +- Isolate workspaces between agents +- Use different models for different agents +- Control which subagents can be spawned +- Route messages to specific agents based on source + +## Configuration + +Agents are defined in the `agents.list` array in your configuration file: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "restrict_to_workspace": true, + "model": "glm-4.7", + "max_tokens": 8192, + "temperature": 0.7 + }, + "list": [ + { + "id": "assistant", + "default": true, + "name": "General Assistant", + "workspace": "~/.picoclaw/workspace/assistant", + "model": { + "primary": "anthropic/claude-opus-4-5", + "fallbacks": ["gpt-4o"] + }, + "subagents": { + "allow_agents": ["researcher", "coder"] + } + }, + { + "id": "researcher", + "name": "Research Agent", + "model": "perplexity/llama-3.1-sonar-large-128k-online", + "skills": ["web-search"] + }, + { + "id": "coder", + "name": "Coding Agent", + "workspace": "~/.picoclaw/workspace/coder", + "model": "anthropic/claude-sonnet-4" + } + ] + } +} +``` + +## Agent Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `id` | string | Yes | Unique agent identifier | +| `default` | bool | No | Whether this is the default agent | +| `name` | string | No | Human-readable display name | +| `workspace` | string | No | Agent-specific workspace directory | +| `model` | string/object | No | Model configuration (see below) | +| `skills` | []string | No | Filter available skills for this agent | +| `subagents` | object | No | Subagent spawning configuration | + +## Model Configuration + +The `model` property can be specified in two formats: + +### String Format (Simple) + +```json +{ + "model": "anthropic/claude-opus-4-5" +} +``` + +### Object Format (With Fallbacks) + +```json +{ + "model": { + "primary": "anthropic/claude-opus-4-5", + "fallbacks": ["gpt-4o", "glm-4.7"] + } +} +``` + +See [Model Fallbacks](model-fallbacks.md) for detailed fallback configuration. + +## Subagent Configuration + +Control which agents can be spawned by an agent using the `subagents` property: + +```json +{ + "id": "assistant", + "subagents": { + "allow_agents": ["researcher", "coder"] + } +} +``` + +### Wildcard Permission + +Allow spawning any agent: + +```json +{ + "subagents": { + "allow_agents": ["*"] + } +} +``` + +### Subagent Model Override + +Override the model for spawned subagents: + +```json +{ + "subagents": { + "allow_agents": ["researcher"], + "model": { + "primary": "gpt-4o-mini", + "fallbacks": ["glm-4-flash"] + } + } +} +``` + +## Workspace Isolation + +Each agent can have its own isolated workspace: + +``` +~/.picoclaw/workspace/ +├── assistant/ # Agent: assistant +│ ├── sessions/ +│ ├── memory/ +│ ├── AGENT.md +│ └── IDENTITY.md +├── researcher/ # Agent: researcher +│ ├── sessions/ +│ └── ... +└── coder/ # Agent: coder + ├── sessions/ + └── ... +``` + +### Benefits of Workspace Isolation + +- **Separate conversation history** - Each agent maintains its own sessions +- **Independent memory** - Long-term memory (MEMORY.md) is agent-specific +- **Isolated skills** - Each agent can have custom skills +- **Different configurations** - AGENT.md can define agent-specific behavior + +## Default Agent Selection + +The default agent is selected when no binding matches. PicoClaw uses this priority: + +1. Agent with `"default": true` +2. First agent in the list +3. Implicit "main" agent (if no agents defined) + +## Implicit Single Agent + +If no agents are defined in `agents.list`, PicoClaw creates an implicit "main" agent using the defaults: + +```json +{ + "agents": { + "defaults": { + "model": "glm-4.7" + } + } +} +``` + +This is equivalent to: + +```json +{ + "agents": { + "list": [ + { + "id": "main", + "default": true + } + ] + } +} +``` + +## Use Cases + +### Personal vs Work Agents + +```json +{ + "agents": { + "list": [ + { + "id": "personal", + "default": true, + "name": "Personal Assistant", + "workspace": "~/.picoclaw/workspace/personal" + }, + { + "id": "work", + "name": "Work Assistant", + "workspace": "~/.picoclaw/workspace/work", + "model": "anthropic/claude-opus-4-5" + } + ] + }, + "bindings": [ + { + "agent_id": "personal", + "match": { "channel": "telegram", "peer": { "kind": "user", "id": "123456789" } } + }, + { + "agent_id": "work", + "match": { "channel": "slack", "team_id": "T12345" } + } + ] +} +``` + +### Specialized Task Agents + +```json +{ + "agents": { + "list": [ + { + "id": "assistant", + "default": true, + "name": "General Assistant", + "subagents": { + "allow_agents": ["researcher", "coder", "writer"] + } + }, + { + "id": "researcher", + "name": "Research Specialist", + "model": "perplexity/llama-3.1-sonar-large-128k-online", + "skills": ["web-search"] + }, + { + "id": "coder", + "name": "Code Specialist", + "model": "anthropic/claude-sonnet-4" + }, + { + "id": "writer", + "name": "Writing Specialist", + "model": "anthropic/claude-opus-4-5" + } + ] + } +} +``` + +### Model-Specific Agents + +Use different models for different capabilities: + +```json +{ + "agents": { + "list": [ + { + "id": "fast", + "name": "Fast Responses", + "model": "groq/llama-3.1-70b-versatile" + }, + { + "id": "smart", + "name": "Complex Reasoning", + "model": "anthropic/claude-opus-4-5" + }, + { + "id": "cheap", + "name": "Simple Tasks", + "model": "openai/gpt-4o-mini" + } + ] + } +} +``` + +## Environment Variables + +Override agent settings with environment variables: + +```bash +# Default model for all agents +export PICOCLAW_AGENTS_DEFAULTS_MODEL="anthropic/claude-opus-4-5" + +# Fallback models +export PICOCLAW_AGENTS_DEFAULTS_MODEL_FALLBACKS='["gpt-4o", "glm-4.7"]' +``` + +## Related Topics + +- [Message Routing](routing.md) - Route messages to specific agents +- [Model Fallbacks](model-fallbacks.md) - Configure model fallback chains +- [Session Management](session-management.md) - Understand session scoping per agent +- [Spawn Tool](../tools/README.md) - Spawn subagents from conversations diff --git a/docs/user-guide/advanced/routing.md b/docs/user-guide/advanced/routing.md new file mode 100644 index 0000000000..fc47da2e86 --- /dev/null +++ b/docs/user-guide/advanced/routing.md @@ -0,0 +1,347 @@ +# Message Routing + +Message routing determines which agent handles incoming messages from different channels. PicoClaw uses a flexible binding system with a priority cascade for precise control. + +## Overview + +The routing system: + +1. Receives messages from channels (Telegram, Discord, Slack, etc.) +2. Evaluates bindings to find a matching agent +3. Routes the message to the appropriate agent +4. Constructs the session key for conversation persistence + +## Binding Configuration + +Bindings are defined in the `bindings` array: + +```json +{ + "bindings": [ + { + "agent_id": "personal", + "match": { + "channel": "telegram", + "peer": { "kind": "user", "id": "123456789" } + } + }, + { + "agent_id": "work", + "match": { + "channel": "slack", + "team_id": "T12345" + } + } + ] +} +``` + +## Binding Properties + +| Property | Type | Description | +|----------|------|-------------| +| `agent_id` | string | Target agent ID | +| `match.channel` | string | Channel name (telegram, discord, slack, etc.) | +| `match.account_id` | string | Account filter (use `*` for wildcard) | +| `match.peer.kind` | string | Peer type: `user`, `group`, `channel` | +| `match.peer.id` | string | Peer/user ID | +| `match.guild_id` | string | Discord guild ID | +| `match.team_id` | string | Slack team ID | + +## Priority Cascade + +Bindings are evaluated in this priority order (highest to lowest): + +1. **Peer binding** - Direct user/group match +2. **Parent peer binding** - Parent group for forwarded messages +3. **Guild binding** - Discord server match +4. **Team binding** - Slack workspace match +5. **Account binding** - Specific account match +6. **Channel wildcard** - Any message from channel (`account_id: "*"`) +7. **Default agent** - Fallback when no binding matches + +## Match Examples + +### Telegram User + +Route messages from a specific Telegram user: + +```json +{ + "agent_id": "personal", + "match": { + "channel": "telegram", + "peer": { "kind": "user", "id": "123456789" } + } +} +``` + +### Telegram Group + +Route all messages from a Telegram group: + +```json +{ + "agent_id": "team-bot", + "match": { + "channel": "telegram", + "peer": { "kind": "group", "id": "-1001234567890" } + } +} +``` + +### Discord Guild + +Route all messages from a Discord server: + +```json +{ + "agent_id": "community-bot", + "match": { + "channel": "discord", + "guild_id": "123456789012345678" + } +} +``` + +### Slack Team + +Route all messages from a Slack workspace: + +```json +{ + "agent_id": "work", + "match": { + "channel": "slack", + "team_id": "T12345" + } +} +``` + +### Channel Wildcard + +Route all Telegram messages to an agent: + +```json +{ + "agent_id": "telegram-bot", + "match": { + "channel": "telegram", + "account_id": "*" + } +} +``` + +### Multi-Account + +Route from a specific bot account: + +```json +{ + "agent_id": "bot-alpha", + "match": { + "channel": "telegram", + "account_id": "bot_123456" + } +} +``` + +## Session Key Construction + +The routing system constructs session keys for conversation persistence. The session key format depends on the DM scope configuration: + +### Default (Main Scope) + +All conversations share one session: + +``` +main +``` + +### Per-Agent Scope + +Separate sessions per agent: + +``` +agent:assistant:telegram:123456789 +``` + +### Per-Channel Scope + +Separate sessions per channel: + +``` +telegram:123456789 +``` + +See [Session Management](session-management.md) for details. + +## Routing Flow + +``` +Incoming Message + │ + ▼ +┌─────────────────┐ +│ Filter by │ +│ Channel │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Check Peer │──► Match? ──► Use Agent +│ Binding │ +└────────┬────────┘ + │ No + ▼ +┌─────────────────┐ +│ Check Parent │──► Match? ──► Use Agent +│ Peer Binding │ +└────────┬────────┘ + │ No + ▼ +┌─────────────────┐ +│ Check Guild/ │──► Match? ──► Use Agent +│ Team Binding │ +└────────┬────────┘ + │ No + ▼ +┌─────────────────┐ +│ Check Account │──► Match? ──► Use Agent +│ Binding │ +└────────┬────────┘ + │ No + ▼ +┌─────────────────┐ +│ Check Channel │──► Match? ──► Use Agent +│ Wildcard │ +└────────┬────────┘ + │ No + ▼ +┌─────────────────┐ +│ Use Default │ +│ Agent │ +└─────────────────┘ +``` + +## Use Cases + +### Personal Assistant with Work Separation + +```json +{ + "bindings": [ + { + "agent_id": "personal", + "match": { + "channel": "telegram", + "peer": { "kind": "user", "id": "123456789" } + } + }, + { + "agent_id": "work", + "match": { + "channel": "slack", + "team_id": "T12345" + } + }, + { + "agent_id": "work", + "match": { + "channel": "discord", + "guild_id": "987654321" + } + } + ] +} +``` + +### Team Bot for Group Chats + +```json +{ + "bindings": [ + { + "agent_id": "team-assistant", + "match": { + "channel": "telegram", + "peer": { "kind": "group", "id": "-1001234567890" } + } + }, + { + "agent_id": "team-assistant", + "match": { + "channel": "discord", + "guild_id": "123456789012345678" + } + } + ] +} +``` + +### Multiple Discord Servers + +```json +{ + "bindings": [ + { + "agent_id": "community-bot", + "match": { + "channel": "discord", + "guild_id": "111111111111111111" + } + }, + { + "agent_id": "support-bot", + "match": { + "channel": "discord", + "guild_id": "222222222222222222" + } + } + ] +} +``` + +### Channel-Specific Agents + +```json +{ + "bindings": [ + { + "agent_id": "telegram-bot", + "match": { + "channel": "telegram", + "account_id": "*" + } + }, + { + "agent_id": "discord-bot", + "match": { + "channel": "discord", + "account_id": "*" + } + } + ] +} +``` + +## Debugging Routing + +Enable debug mode to see routing decisions: + +```bash +picoclaw gateway --debug +``` + +Debug output includes: + +- Which bindings were evaluated +- Which binding matched (if any) +- Final agent selection +- Session key construction + +## Related Topics + +- [Multi-Agent System](multi-agent.md) - Define multiple agents +- [Session Management](session-management.md) - Understand session persistence +- [Channels](../channels/README.md) - Configure chat platform integrations diff --git a/docs/user-guide/advanced/security-sandbox.md b/docs/user-guide/advanced/security-sandbox.md new file mode 100644 index 0000000000..58f5b10d73 --- /dev/null +++ b/docs/user-guide/advanced/security-sandbox.md @@ -0,0 +1,320 @@ +# Security Sandbox + +PicoClaw includes a security sandbox to restrict file system access and command execution. This protects your system from accidental or malicious operations by the AI. + +## Overview + +The security sandbox provides: + +- **Workspace restriction** - File operations limited to workspace directory +- **Command filtering** - Dangerous commands are blocked +- **Path traversal prevention** - Cannot access files outside workspace +- **Configurable patterns** - Add custom deny patterns + +## Workspace Restriction + +### Configuration + +Enable or disable workspace restriction: + +```json +{ + "agents": { + "defaults": { + "restrict_to_workspace": true, + "workspace": "~/.picoclaw/workspace" + } + } +} +``` + +### Behavior When Enabled + +When `restrict_to_workspace` is `true` (default): + +- File read/write operations must be within workspace +- Shell commands execute from workspace directory +- Path traversal attempts (`../`) are blocked +- Absolute paths outside workspace are rejected + +### Behavior When Disabled + +When `restrict_to_workspace` is `false`: + +- Full file system access is allowed +- Commands can run from any directory +- Use with caution in production environments + +## Command Filtering + +### Default Blocked Patterns + +The following dangerous commands are always blocked: + +| Category | Patterns | +|----------|----------| +| File deletion | `rm -rf`, `del /f`, `rmdir /s` | +| Disk operations | `format`, `mkfs`, `diskpart`, `dd if=` | +| System control | `shutdown`, `reboot`, `poweroff` | +| Privilege escalation | `sudo`, `chmod 777`, `chown` | +| Process control | `pkill`, `killall`, `kill -9` | +| Shell injection | `$(...)`, backticks, `eval`, `source` | +| Remote execution | `curl | sh`, `wget | bash` | +| Package management | `npm install -g`, `pip install --user`, `apt install` | +| Container escape | `docker run`, `docker exec` | +| Network | `ssh @` | +| Version control | `git push`, `git force` | + +### Custom Deny Patterns + +Add additional patterns to block: + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": [ + "wget.*", + "curl.*", + "nc.*-l", + "python.*-m.*http" + ] + } + } +} +``` + +### Disable All Filtering + +Disable command filtering entirely (not recommended): + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": false + } + } +} +``` + +## Path Traversal Protection + +The sandbox detects and blocks path traversal attempts: + +| Attempt | Blocked? | +|---------|----------| +| `../../../etc/passwd` | Yes | +| `..\..\..\windows\system32` | Yes | +| `/etc/passwd` | Yes (outside workspace) | +| `~/secret.txt` | Yes (outside workspace) | +| `workspace/file.txt` | No (relative, within workspace) | +| `/home/user/.picoclaw/workspace/file.txt` | No (absolute, within workspace) | + +## Configuration Reference + +### Agent Defaults + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "restrict_to_workspace": true + } + } +} +``` + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `workspace` | string | `~/.picoclaw/workspace` | Working directory | +| `restrict_to_workspace` | bool | `true` | Enable sandbox restrictions | + +### Exec Tool Configuration + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": [] + } + } +} +``` + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enable_deny_patterns` | bool | `true` | Enable command filtering | +| `custom_deny_patterns` | []string | `[]` | Additional patterns to block | + +## Environment Variables + +Override security settings with environment variables: + +```bash +# Disable workspace restriction (not recommended) +export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE="false" + +# Disable command filtering (not recommended) +export PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS="false" + +# Custom deny patterns +export PICOCLAW_TOOLS_EXEC_CUSTOM_DENY_PATTERNS='["wget.*", "curl.*"]' +``` + +## Multi-Agent Security + +Each agent can have its own security settings: + +```json +{ + "agents": { + "list": [ + { + "id": "trusted", + "workspace": "~/.picoclaw/workspace/trusted", + "restrict_to_workspace": false + }, + { + "id": "sandboxed", + "workspace": "~/.picoclaw/workspace/sandboxed", + "restrict_to_workspace": true + } + ] + } +} +``` + +### Workspace Isolation + +Different agents with isolated workspaces: + +``` +~/.picoclaw/workspace/ +├── agent-a/ # Agent A's sandbox +│ ├── files/ +│ └── sessions/ +├── agent-b/ # Agent B's sandbox +│ ├── files/ +│ └── sessions/ +└── shared/ # Shared workspace (if configured) +``` + +## Security Best Practices + +### 1. Keep Sandbox Enabled + +Leave `restrict_to_workspace` enabled for production: + +```json +{ + "agents": { + "defaults": { + "restrict_to_workspace": true + } + } +} +``` + +### 2. Use Dedicated Workspace + +Create a dedicated workspace directory: + +```bash +mkdir -p ~/.picoclaw/workspace +``` + +### 3. Review Custom Patterns + +When adding custom deny patterns, test them thoroughly: + +```json +{ + "tools": { + "exec": { + "custom_deny_patterns": [ + "\\bmysqldump\\b", + "\\bpg_dump\\b" + ] + } + } +} +``` + +### 4. Separate Agent Workspaces + +Use different workspaces for different trust levels: + +```json +{ + "agents": { + "list": [ + { + "id": "production", + "workspace": "~/.picoclaw/workspace/prod", + "restrict_to_workspace": true + }, + { + "id": "development", + "workspace": "~/.picoclaw/workspace/dev", + "restrict_to_workspace": true + } + ] + } +} +``` + +### 5. Monitor Logs + +Enable debug logging to monitor blocked operations: + +```bash +picoclaw agent --debug +``` + +## Error Messages + +When operations are blocked, users see clear error messages: + +| Error | Cause | +|-------|-------| +| `Command blocked by safety guard (dangerous pattern detected)` | Command matches deny pattern | +| `Command blocked by safety guard (path traversal detected)` | Path contains `../` or `..\` | +| `Command blocked by safety guard (path outside working dir)` | Absolute path outside workspace | +| `access denied: path outside workspace` | File operation outside workspace | + +## Troubleshooting + +### Legitimate Commands Blocked + +If safe commands are being blocked: + +1. Check if command matches a deny pattern +2. Consider adding to allowlist (if configured) +3. Adjust custom deny patterns + +### Cannot Access Files + +If file access is denied: + +1. Verify file is within workspace +2. Check workspace path configuration +3. Ensure `restrict_to_workspace` is configured correctly + +### Need More Access + +For trusted environments: + +1. Disable workspace restriction temporarily +2. Use a separate agent with relaxed security +3. Move required files into workspace + +## Related Topics + +- [Multi-Agent System](multi-agent.md) - Isolated agent workspaces +- [Exec Tool](../tools/exec.md) - Command execution configuration +- [Filesystem Tool](../tools/filesystem.md) - File operations +- [Workspace Management](../workspace/README.md) - Workspace structure diff --git a/docs/user-guide/advanced/session-management.md b/docs/user-guide/advanced/session-management.md new file mode 100644 index 0000000000..0e02463a7a --- /dev/null +++ b/docs/user-guide/advanced/session-management.md @@ -0,0 +1,339 @@ +# Session Management + +PicoClaw maintains conversation history through a session management system. Sessions persist across conversations and can be scoped differently based on configuration. + +## Overview + +The session system provides: + +- **Conversation persistence** - Messages are saved and loaded automatically +- **Session scoping** - Control how sessions are shared across agents/channels +- **Identity linking** - Share sessions across different platforms +- **History management** - Automatic summarization for long conversations + +## Session Storage + +Sessions are stored as JSON files in the workspace: + +``` +~/.picoclaw/workspace/ +└── sessions/ + ├── main.json # Main session + ├── telegram_123456789.json # Telegram user session + ├── discord_987654321.json # Discord user session + └── agent_assistant_telegram_123456789.json # Agent-specific session +``` + +## Session Structure + +Each session file contains: + +```json +{ + "key": "telegram:123456789", + "messages": [ + { + "role": "user", + "content": "Hello!" + }, + { + "role": "assistant", + "content": "Hi! How can I help you?" + } + ], + "summary": "Previous conversation about project setup...", + "created": "2024-01-15T10:30:00Z", + "updated": "2024-01-15T11:45:00Z" +} +``` + +### Session Fields + +| Field | Type | Description | +|-------|------|-------------| +| `key` | string | Unique session identifier | +| `messages` | array | Conversation history | +| `summary` | string | Auto-generated summary of older messages | +| `created` | timestamp | Session creation time | +| `updated` | timestamp | Last update time | + +## DM Scope Configuration + +Control how direct message sessions are scoped with `session.dm_scope`: + +```json +{ + "session": { + "dm_scope": "per-agent" + } +} +``` + +### Scope Options + +| Value | Description | Session Key Format | +|-------|-------------|-------------------| +| `main` | Single shared session (default) | `main` | +| `per-agent` | Separate session per agent | `agent:{agent_id}:{channel}:{user_id}` | +| `per-channel` | Separate session per channel | `{channel}:{user_id}` | + +### Main Scope + +All conversations use a single session: + +```json +{ + "session": { + "dm_scope": "main" + } +} +``` + +Best for: Simple single-agent setups + +### Per-Agent Scope + +Each agent maintains its own conversation history: + +```json +{ + "session": { + "dm_scope": "per-agent" + } +} +``` + +Best for: Multi-agent setups where each agent should have independent context + +### Per-Channel Scope + +Separate sessions for each messaging platform: + +```json +{ + "session": { + "dm_scope": "per-channel" + } +} +``` + +Best for: Users who want platform-specific conversations + +## Identity Links + +Share sessions across different platforms by linking user identities: + +```json +{ + "session": { + "dm_scope": "per-agent", + "identity_links": { + "telegram:123456789": ["discord:987654321", "slack:U12345"] + } + } +} +``` + +### How Identity Links Work + +1. User sends message from Telegram (ID: 123456789) +2. PicoClaw checks `identity_links` for linked accounts +3. Session key uses canonical identity (first in array) +4. Same user on Discord uses the same session + +### Example Configuration + +```json +{ + "session": { + "dm_scope": "per-agent", + "identity_links": { + "telegram:123456789": ["discord:987654321"], + "telegram:987654321": ["slack:U67890", "discord:111222333"] + } + } +} +``` + +## Session Key Construction + +Session keys uniquely identify conversations. The format depends on context: + +### DM Sessions + +``` +{scope_prefix}{channel}:{user_id} +``` + +Examples: +- `main` (main scope) +- `telegram:123456789` (per-channel) +- `agent:assistant:telegram:123456789` (per-agent) + +### Group Sessions + +``` +{channel}:group:{group_id} +``` + +Example: +- `telegram:group:-1001234567890` + +### Channel Sessions + +``` +{channel}:channel:{channel_id} +``` + +Example: +- `telegram:channel:@mychannel` + +## History Management + +### Automatic Summarization + +When conversation history grows too long, PicoClaw automatically: + +1. Keeps recent messages (last N messages) +2. Generates a summary of older messages +3. Stores the summary in the session + +### History Truncation + +The session manager provides methods for history management: + +- `TruncateHistory(key, keepLast)` - Keep only the last N messages +- `SetSummary(key, summary)` - Store a conversation summary + +### Manual History Control + +You can control history programmatically or through tools: + +```bash +# Clear session history +rm ~/.picoclaw/workspace/sessions/telegram_123456789.json +``` + +## Session Manager API + +The session manager provides these operations: + +| Method | Description | +|--------|-------------| +| `GetOrCreate(key)` | Get existing session or create new | +| `AddMessage(key, role, content)` | Add a message to session | +| `AddFullMessage(key, message)` | Add message with tool calls | +| `GetHistory(key)` | Get all messages | +| `SetHistory(key, messages)` | Replace all messages | +| `GetSummary(key)` | Get session summary | +| `SetSummary(key, summary)` | Set session summary | +| `TruncateHistory(key, keepLast)` | Trim message history | +| `Save(key)` | Persist session to disk | + +## Session Persistence + +### Automatic Saving + +Sessions are automatically saved: + +- After each message exchange +- When summaries are generated +- On graceful shutdown + +### File Format + +Sessions use JSON format with indentation for readability: + +```json +{ + "key": "telegram:123456789", + "messages": [...], + "summary": "...", + "created": "2024-01-15T10:30:00Z", + "updated": "2024-01-15T11:45:00Z" +} +``` + +### Safe File Writing + +Sessions use atomic write operations: + +1. Write to temporary file +2. Sync to disk +3. Rename to final location + +This prevents corruption from crashes or power failures. + +## Use Cases + +### Cross-Platform Identity + +User wants the same conversation on Telegram and Discord: + +```json +{ + "session": { + "dm_scope": "per-agent", + "identity_links": { + "telegram:123456789": ["discord:987654321"] + } + } +} +``` + +### Isolated Work Conversations + +Keep work Slack separate from personal Telegram: + +```json +{ + "session": { + "dm_scope": "per-channel" + } +} +``` + +### Agent-Specific Context + +Different agents have different conversation history: + +```json +{ + "session": { + "dm_scope": "per-agent" + }, + "agents": { + "list": [ + { "id": "personal", "default": true }, + { "id": "work" } + ] + } +} +``` + +## Troubleshooting + +### Session Not Persisting + +Check: +1. Workspace directory exists and is writable +2. `sessions/` subdirectory exists +3. No file permission issues + +### Wrong Session Used + +1. Check `dm_scope` configuration +2. Verify `identity_links` mapping +3. Enable debug mode to see session key construction + +### History Too Long + +1. Sessions auto-summarize when long +2. Manually clear session file if needed +3. Consider per-agent scope to isolate contexts + +## Related Topics + +- [Message Routing](routing.md) - How sessions are selected +- [Multi-Agent System](multi-agent.md) - Agent-specific sessions +- [Workspace Management](../workspace/README.md) - Workspace structure diff --git a/docs/user-guide/advanced/voice-transcription.md b/docs/user-guide/advanced/voice-transcription.md new file mode 100644 index 0000000000..595adc618a --- /dev/null +++ b/docs/user-guide/advanced/voice-transcription.md @@ -0,0 +1,248 @@ +# Voice Transcription + +PicoClaw supports voice message transcription using Groq's Whisper API. This allows users to send voice messages through supported channels and have them automatically transcribed for the AI to process. + +## Overview + +Voice transcription provides: + +- **Automatic transcription** - Voice messages converted to text +- **Multi-language support** - Whisper supports 99+ languages +- **Fast processing** - Groq's infrastructure provides quick transcription +- **Seamless integration** - Transcribed text feeds directly into conversation + +## Requirements + +- Groq API key configured +- Channel that supports voice messages (Telegram, Discord, etc.) +- Audio format supported by Whisper (MP3, WAV, M4A, etc.) + +## Configuration + +### Groq Provider Setup + +Configure the Groq provider with your API key: + +```json +{ + "providers": { + "groq": { + "api_key": "gsk_xxx" + } + } +} +``` + +### Environment Variable + +Alternatively, use environment variables: + +```bash +export PICOCLAW_PROVIDERS_GROQ_API_KEY="gsk_xxx" +``` + +## How It Works + +### Processing Flow + +1. User sends voice message to channel (Telegram, Discord, etc.) +2. Channel downloads audio file +3. PicoClaw sends audio to Groq Whisper API +4. Transcription text is received +5. Transcribed text is processed as a regular message + +### Architecture + +``` +Voice Message + │ + ▼ +┌─────────────────┐ +│ Channel Handler │ +│ (Telegram/etc) │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Voice Download │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Groq Whisper │ +│ API │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Transcribed │ +│ Text Message │ +└─────────────────┘ +``` + +## Supported Formats + +Groq Whisper supports common audio formats: + +| Format | Extension | Notes | +|--------|-----------|-------| +| MP3 | `.mp3` | Most common | +| WAV | `.wav` | Uncompressed | +| M4A | `.m4a` | Apple format | +| WebM | `.webm` | Web format | +| OGG | `.ogg` | Telegram default | +| FLAC | `.flac` | Lossless | +| MP4 | `.mp4` | Video container (audio extracted) | + +## Channel Support + +Voice transcription is supported in channels that implement voice message handling: + +### Telegram + +Telegram voice messages (OGG format) are automatically transcribed: + +1. User sends voice message +2. Telegram downloads audio +3. Audio is transcribed +4. Text is processed + +### Discord + +Discord voice messages are transcribed when available: + +1. User uploads voice message +2. Audio file is downloaded +3. Audio is transcribed +4. Text is processed + +## API Details + +### Endpoint + +Voice transcription uses Groq's OpenAI-compatible endpoint: + +``` +POST https://api.groq.com/openai/v1/audio/transcriptions +``` + +### Model + +PicoClaw uses `whisper-large-v3` for transcription: + +- High accuracy +- Multi-language support +- Fast processing on Groq infrastructure + +### Response Format + +```json +{ + "text": "Hello, this is a transcribed message.", + "language": "en", + "duration": 5.2 +} +``` + +## Configuration Options + +### Enable/Disable + +Voice transcription is enabled when a Groq API key is configured. To disable: + +```bash +# Remove or empty the API key +unset PICOCLAW_PROVIDERS_GROQ_API_KEY +``` + +### Timeout + +Voice transcription has a 60-second timeout for API requests. Long audio files may take longer to process. + +## Debugging + +Enable debug mode to see transcription details: + +```bash +picoclaw gateway --debug +``` + +### Debug Output + +``` +[voice] Starting transcription: voice_message.ogg +[voice] Audio file details: size_bytes=245760, file_name=voice_message.ogg +[voice] Sending transcription request to Groq API +[voice] Transcription completed: text_length=45, language=en, duration=3.5 +``` + +## Troubleshooting + +### Transcription Not Working + +1. **Check API key**: Ensure Groq API key is configured + ```bash + echo $PICOCLAW_PROVIDERS_GROQ_API_KEY + ``` + +2. **Check channel support**: Verify channel handles voice messages + +3. **Check audio format**: Ensure format is supported by Whisper + +4. **Check logs**: Enable debug mode for detailed logging + +### Poor Transcription Quality + +1. **Audio quality**: Better quality audio yields better transcription +2. **Background noise**: Noisy audio may reduce accuracy +3. **Language**: Ensure correct language is being spoken +4. **Audio length**: Very short clips may have reduced accuracy + +### API Errors + +Common API errors: + +| Error | Cause | Solution | +|-------|-------|----------| +| 401 Unauthorized | Invalid API key | Check API key | +| 413 Payload Too Large | Audio file too large | Compress or shorten audio | +| 429 Rate Limited | Too many requests | Wait and retry | +| 500 Server Error | Groq service issue | Retry later | + +## Privacy Considerations + +- Audio files are sent to Groq's servers for transcription +- Files are processed in real-time and not stored by Groq +- Consider privacy implications for sensitive conversations +- Review Groq's privacy policy for details + +## Cost Considerations + +Groq Whisper pricing: + +- Free tier available with rate limits +- Paid tier for higher volume +- Monitor usage to avoid unexpected costs + +Check [Groq's pricing page](https://groq.com/pricing) for current rates. + +## Example Usage + +### Telegram Voice Message + +1. Open Telegram chat with bot +2. Hold microphone button and record message +3. Release to send +4. Bot transcribes and responds to text + +### Discord Voice Message + +1. Open Discord channel with bot +2. Upload or record voice message +3. Bot transcribes and responds to text + +## Related Topics + +- [Channels](../channels/README.md) - Configure chat platforms +- [Providers](../providers/README.md) - Configure LLM providers +- [Environment Variables](environment-variables.md) - Configuration options diff --git a/docs/user-guide/channels/README.md b/docs/user-guide/channels/README.md new file mode 100644 index 0000000000..45a1915c0c --- /dev/null +++ b/docs/user-guide/channels/README.md @@ -0,0 +1,139 @@ +# Channels Overview + +PicoClaw supports multiple chat platforms, allowing you to interact with your AI assistant through your preferred messaging app. + +## Supported Channels + +| Channel | Setup Difficulty | Features | +|---------|------------------|----------| +| [Telegram](telegram.md) | Easy | Full support, voice transcription | +| [Discord](discord.md) | Easy | Full support, voice transcription | +| [Slack](slack.md) | Medium | Full support, voice transcription | +| [LINE](line.md) | Medium | Full support, webhooks | +| [QQ](qq.md) | Easy | Basic support | +| [DingTalk](dingtalk.md) | Medium | Basic support | +| [WeCom](wecom.md) | Medium | Enterprise, bot + app modes | +| [WhatsApp](whatsapp.md) | Medium | Requires bridge | +| [Feishu/Lark](feishu-lark.md) | Medium | Enterprise features | +| [OneBot](onebot.md) | Medium | Universal protocol | +| [MaixCam](maixcam.md) | Easy | Hardware device | + +## Quick Setup + +### 1. Choose a Channel + +Select the platform you want to use. + +### 2. Get Credentials + +Each channel requires different credentials: + +- **Telegram**: Bot token from @BotFather +- **Discord**: Bot token from Developer Portal +- **Slack**: Bot token and App token +- **LINE**: Channel secret and access token + +### 3. Configure + +Add credentials to `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + } + } +} +``` + +### 4. Start Gateway + +```bash +picoclaw gateway +``` + +## Common Options + +All channels support: + +| Option | Description | +|--------|-------------| +| `enabled` | Enable/disable the channel | +| `allow_from` | Whitelist of allowed user IDs (empty = all users) | + +## Access Control + +Use `allow_from` to restrict who can interact with your bot: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_TOKEN", + "allow_from": ["123456789", "987654321"] + } + } +} +``` + +An empty `allow_from` allows all users. + +## Voice Transcription + +With Groq configured, voice messages are automatically transcribed on: +- Telegram +- Discord +- Slack +- OneBot + +```json +{ + "providers": { + "groq": { + "api_key": "gsk_xxx" + } + } +} +``` + +## Multi-Channel Setup + +You can enable multiple channels simultaneously: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "telegram-token" + }, + "discord": { + "enabled": true, + "token": "discord-token" + }, + "slack": { + "enabled": true, + "bot_token": "xoxb-token", + "app_token": "xapp-token" + } + } +} +``` + +## Channel-Specific Guides + +- [Telegram Setup](telegram.md) +- [Discord Setup](discord.md) +- [Slack Setup](slack.md) +- [LINE Setup](line.md) +- [QQ Setup](qq.md) +- [DingTalk Setup](dingtalk.md) +- [WeCom Setup](wecom.md) +- [WhatsApp Setup](whatsapp.md) +- [Feishu/Lark Setup](feishu-lark.md) +- [OneBot Setup](onebot.md) +- [MaixCam Setup](maixcam.md) diff --git a/docs/user-guide/channels/dingtalk.md b/docs/user-guide/channels/dingtalk.md new file mode 100644 index 0000000000..09f5ffc2dd --- /dev/null +++ b/docs/user-guide/channels/dingtalk.md @@ -0,0 +1,184 @@ +# DingTalk Setup + +DingTalk (钉钉) is a popular enterprise messaging and collaboration platform in China. + +## Prerequisites + +- A DingTalk account +- Admin access to a DingTalk organization (or ability to create one) + +## Step 1: Create a DingTalk Application + +1. Go to [DingTalk Developer Console](https://open-dev.dingtalk.com/) +2. Log in with your DingTalk account +3. Click **"Create Application"** (创建应用) +4. Select **"Enterprise Internal Application"** (企业内部应用) +5. Fill in the application information: + - Application name (e.g., "PicoClaw Bot") + - Application description + - Application logo +6. Click **"Confirm"** + +## Step 2: Get Client Credentials + +1. In your application dashboard, go to **"Application Information"** (应用信息) +2. Copy the **"Client ID"** (ClientID) +3. Copy the **"Client Secret"** (ClientSecret) + +## Step 3: Configure Bot Capabilities + +1. Go to **"Robot & Message Push"** (机器人与消息推送) +2. Enable the robot capability +3. Configure message receiving: + - Enable **"Stream Mode"** (Stream Mode / 流式模式) + - This allows real-time message receiving via WebSocket + +## Step 4: Set Permissions + +1. Go to **"Permission Management"** (权限管理) +2. Request these permissions: + - **"Chat with users"** (与企业内人员聊天) + - **"Send messages"** (发送消息) +3. Wait for approval if required + +## Step 5: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "dingtalk": { + "enabled": true, + "client_id": "YOUR_CLIENT_ID", + "client_secret": "YOUR_CLIENT_SECRET", + "allow_from": [] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `client_id` | Yes | Client ID from DingTalk Developer Console | +| `client_secret` | Yes | Client Secret from DingTalk Developer Console | +| `allow_from` | No | Array of allowed user IDs | + +## Step 6: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +Starting DingTalk channel (Stream Mode)... +DingTalk channel started (Stream Mode) +``` + +## Step 7: Test + +### Single Chat + +1. Open DingTalk +2. Find your bot in the organization +3. Send a message to the bot +4. The bot should respond! + +### Group Chat + +1. Add the bot to a DingTalk group +2. Mention the bot or send a message +3. The bot should respond! + +## Features + +### Stream Mode + +PicoClaw uses DingTalk's Stream Mode for real-time message receiving via WebSocket. This provides: + +- Instant message delivery +- No need for a public webhook URL +- Automatic reconnection + +### Markdown Support + +The bot sends responses in Markdown format with a title header. + +### Group Chat Support + +The bot works in both: +- One-on-one conversations +- Group conversations + +## Troubleshooting + +### Bot not responding + +1. Verify client_id and client_secret are correct +2. Check that Stream Mode is enabled +3. Ensure permissions are approved +4. Check the gateway is running + +### "Authentication failed" error + +1. Verify client_id and client_secret are correct +2. Check if the application is published/active +3. Ensure no extra whitespace in credentials + +### Stream connection issues + +1. Check your network allows WebSocket connections +2. Verify firewall allows outgoing connections to DingTalk servers +3. Check logs for specific error messages + +### Permission denied errors + +1. Go to DingTalk Developer Console +2. Verify all required permissions are granted +3. Request additional permissions if needed + +## Advanced Configuration + +### Allow Specific Users + +```json +{ + "channels": { + "dingtalk": { + "enabled": true, + "client_id": "YOUR_CLIENT_ID", + "client_secret": "YOUR_CLIENT_SECRET", + "allow_from": ["user123", "user456"] + } + } +} +``` + +### Multi-Tenant Setup + +For multiple organizations, create separate applications and use separate configurations. + +## Important Notes + +### Enterprise Application + +DingTalk bots require an enterprise application. Personal bots are not supported. + +### Approval Process + +Some permissions require admin approval within your DingTalk organization. + +### Rate Limits + +DingTalk has rate limits on API calls. For high-volume usage, consider: +- Implementing message batching +- Contacting DingTalk for higher limits + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [DingTalk Developer Documentation](https://open.dingtalk.com/document/) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/discord.md b/docs/user-guide/channels/discord.md new file mode 100644 index 0000000000..07a2fc661d --- /dev/null +++ b/docs/user-guide/channels/discord.md @@ -0,0 +1,147 @@ +# Discord Setup + +Discord is great for community servers and personal use. + +## Prerequisites + +- A Discord account +- Admin access to a Discord server (or ability to create one) + +## Step 1: Create a Discord Application + +1. Go to [Discord Developer Portal](https://discord.com/developers/applications) +2. Click **"New Application"** +3. Give it a name (e.g., "PicoClaw Bot") +4. Click **"Create"** + +## Step 2: Create a Bot + +1. In your application, go to **"Bot"** in the left sidebar +2. Click **"Add Bot"** +3. Confirm by clicking **"Yes, do it!"** + +## Step 3: Get Bot Token + +1. In the Bot settings, find **"Token"** +2. Click **"Reset Token"** if needed +3. Copy the token (starts with `MTk4Nj...`) + +## Step 4: Enable Intents + +In the Bot settings, enable: + +- **MESSAGE CONTENT INTENT** (required) +- **SERVER MEMBERS INTENT** (optional, for member-based features) + +Click **"Save Changes"**. + +## Step 5: Get Your User ID + +1. Open Discord +2. Go to **Settings** → **Advanced** +3. Enable **"Developer Mode"** +4. Right-click your avatar in any chat +5. Select **"Copy User ID"** + +## Step 6: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "discord": { + "enabled": true, + "token": "MTk4NjIyNDgzNDc...", + "allow_from": ["123456789012345678"] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `token` | Yes | Bot token | +| `allow_from` | No | Array of allowed user IDs | + +## Step 7: Invite the Bot + +1. In the Developer Portal, go to **"OAuth2"** → **"URL Generator"** +2. Under **Scopes**, check `bot` +3. Under **Bot Permissions**, check: + - `Send Messages` + - `Read Message History` + - (Optional) `Attach Files` +4. Copy the generated URL +5. Open the URL in your browser +6. Select your server and authorize the bot + +## Step 8: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +✓ Channels enabled: discord +✓ Gateway started on 0.0.0.0:18790 +``` + +## Step 9: Test + +1. Go to your Discord server +2. Find the channel where the bot is present +3. Send a message +4. The bot should respond! + +## Features + +### Voice Messages + +With Groq configured, voice messages are automatically transcribed. + +### Server Channels + +The bot works in any channel it has access to: +- Public channels +- Private channels (if bot has permission) + +### Direct Messages + +Users can DM the bot directly for private conversations. + +## Troubleshooting + +### Bot not responding + +1. Check intents are enabled (especially MESSAGE CONTENT INTENT) +2. Verify the bot token is correct +3. Check `allow_from` includes your user ID + +### "Missing Access" error + +1. Ensure the bot has proper permissions in the channel +2. Re-invite the bot with correct permissions + +### Bot appears offline + +1. Make sure the gateway is running +2. Check for errors in the console output + +## Advanced Configuration + +### Multiple Servers + +The bot can be invited to multiple servers. Use `allow_from` to control access. + +### Role-Based Access + +Use `allow_from` with user IDs to restrict who can use the bot. + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/feishu-lark.md b/docs/user-guide/channels/feishu-lark.md new file mode 100644 index 0000000000..8dc84cb023 --- /dev/null +++ b/docs/user-guide/channels/feishu-lark.md @@ -0,0 +1,215 @@ +# Feishu/Lark Setup + +Feishu (飞书, known as Lark internationally) is an enterprise collaboration platform by ByteDance. + +## Prerequisites + +- A Feishu/Lark account +- Admin access to a Feishu/Lark organization (or ability to create one) + +## Step 1: Create a Feishu App + +1. Go to [Feishu Open Platform](https://open.feishu.cn/) (China) or [Lark Developer](https://open.larksuite.com/) (International) +2. Log in with your Feishu/Lark account +3. Click **"Create Custom App"** (创建企业自建应用) +4. Fill in the application information: + - App name (e.g., "PicoClaw Bot") + - App description + - App icon +5. Click **"Create"** + +## Step 2: Get App Credentials + +1. In your app dashboard, go to **"Credentials & Basic Info"** (凭证与基础信息) +2. Copy the **"App ID"** +3. Copy the **"App Secret"** + +## Step 3: Configure Event Subscription + +1. Go to **"Event Subscriptions"** (事件订阅) +2. Enable event subscription +3. Configure encryption (optional but recommended): + - Copy the **"Verification Token"** (验证令牌) + - Copy the **"Encrypt Key"** (加密密钥) +4. Add events to subscribe: + - **"Receive message"** (接收消息) - `im.message.receive_v1` + +## Step 4: Set Permissions + +1. Go to **"Permission Management"** (权限管理) +2. Request these permissions: + - `im:message` - Get and send messages + - `im:message:send_as_bot` - Send messages as bot + - `im:chat` - Get chat information +3. Wait for approval if required + +## Step 5: Publish App + +1. Go to **"Version Management & Release"** (版本管理与发布) +2. Create a version +3. Submit for review +4. After approval, publish to your organization + +## Step 6: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "feishu": { + "enabled": true, + "app_id": "cli_xxxxxxxxxxxx", + "app_secret": "xxxxxxxxxxxxxxxxxxxx", + "verification_token": "xxxxxxxx", + "encrypt_key": "xxxxxxxx", + "allow_from": [] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `app_id` | Yes | App ID from Feishu Open Platform | +| `app_secret` | Yes | App Secret from Feishu Open Platform | +| `verification_token` | No | Verification token for event validation | +| `encrypt_key` | No | Encrypt key for event decryption | +| `allow_from` | No | Array of allowed user IDs | + +## Step 7: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +Feishu channel started (websocket mode) +``` + +## Step 8: Test + +1. Open Feishu/Lark +2. Find your bot in the organization +3. Send a message to the bot +4. The bot should respond! + +## Features + +### WebSocket Mode + +PicoClaw uses Feishu's WebSocket connection for real-time event delivery. Benefits include: + +- No need for a public webhook URL +- Instant message delivery +- Automatic reconnection + +### Text Messages + +The bot processes text messages and responds accordingly. + +### Chat Types + +The bot works in various chat types: +- One-on-one conversations (P2P) +- Group chats +- Topic-based discussions + +## Troubleshooting + +### Bot not responding + +1. Verify app_id and app_secret are correct +2. Check that events are subscribed +3. Ensure the app is published +4. Check the gateway is running + +### "Authentication failed" error + +1. Verify app_id and app_secret are correct +2. Check if the app is approved and active +3. Ensure no extra whitespace in credentials + +### WebSocket connection issues + +1. Check your network allows WebSocket connections +2. Verify firewall allows connections to Feishu servers +3. Check logs for specific error messages + +### Events not received + +1. Verify event subscription is enabled +2. Check that the correct events are subscribed +3. Ensure the app has necessary permissions + +### Permission errors + +1. Go to Feishu Open Platform +2. Verify all required permissions are granted +3. Request additional permissions if needed + +## Advanced Configuration + +### Allow Specific Users + +```json +{ + "channels": { + "feishu": { + "enabled": true, + "app_id": "cli_xxxxxxxxxxxx", + "app_secret": "xxxxxxxxxxxxxxxxxxxx", + "verification_token": "xxxxxxxx", + "encrypt_key": "xxxxxxxx", + "allow_from": ["ou_xxxxx", "ou_yyyyy"] + } + } +} +``` + +### Multi-Tenant Setup + +For multiple organizations, create separate apps and use separate configurations. + +## Regional Differences + +### Feishu (China) + +- Platform: https://open.feishu.cn/ +- Use for users in mainland China +- May require ICP filing for some features + +### Lark (International) + +- Platform: https://open.larksuite.com/ +- Use for international users +- Different data centers and API endpoints + +## Important Notes + +### App Review + +Internal enterprise apps typically don't require review, but publishing to the app store does. + +### Rate Limits + +Feishu has rate limits on API calls. For high-volume usage: +- Implement message batching +- Consider caching frequent queries +- Contact Feishu for higher limits + +### Security + +- Keep app_secret secure +- Use encrypt_key for sensitive data +- Implement proper user authorization + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [Feishu Open Platform](https://open.feishu.cn/) +- [Lark Developer Documentation](https://open.larksuite.com/document/) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/line.md b/docs/user-guide/channels/line.md new file mode 100644 index 0000000000..8e12fb5c76 --- /dev/null +++ b/docs/user-guide/channels/line.md @@ -0,0 +1,195 @@ +# LINE Setup + +LINE is a popular messaging app in Japan, Taiwan, Thailand, and other Asian countries. + +## Prerequisites + +- A LINE account +- A LINE Official Account (free tier available) +- A server accessible from the internet (for webhooks) + +## Step 1: Create a LINE Official Account + +1. Go to [LINE Developers Console](https://developers.line.biz/) +2. Log in with your LINE account +3. Create a new provider (or select existing) +4. Create a new channel: + - Select **"Messaging API"** + - Fill in the required information + - Click **"Create"** + +## Step 2: Get Channel Credentials + +1. In your channel settings, go to **"Messaging API"** tab +2. Copy the **"Channel secret"** +3. Click **"Issue"** next to **"Channel access token"** +4. Copy the **"Channel access token"** + +## Step 3: Configure Webhook + +LINE requires a webhook URL to receive messages. You have two options: + +### Option A: Use a Tunnel (Development) + +Use a service like ngrok or cloudflared: + +```bash +# Using ngrok +ngrok http 18791 + +# Using cloudflared +cloudflared tunnel --url http://localhost:18791 +``` + +Note the HTTPS URL (e.g., `https://abc123.ngrok.io`). + +### Option B: Use a Public Server + +Deploy PicoClaw on a server with a public IP and configure your domain. + +## Step 4: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "line": { + "enabled": true, + "channel_secret": "YOUR_CHANNEL_SECRET", + "channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN", + "webhook_host": "0.0.0.0", + "webhook_port": 18791, + "webhook_path": "/webhook/line", + "allow_from": [] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `channel_secret` | Yes | Channel secret from LINE Developers Console | +| `channel_access_token` | Yes | Channel access token from LINE Developers Console | +| `webhook_host` | No | Host to bind webhook server (default: `0.0.0.0`) | +| `webhook_port` | No | Port for webhook server (default: `18791`) | +| `webhook_path` | No | Path for webhook endpoint (default: `/webhook/line`) | +| `allow_from` | No | Array of allowed user IDs | + +## Step 5: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +LINE webhook server listening addr=0.0.0.0:18791 path=/webhook/line +LINE channel started (Webhook Mode) +``` + +## Step 6: Register Webhook URL + +1. Go back to [LINE Developers Console](https://developers.line.biz/) +2. In your channel settings, go to **"Messaging API"** tab +3. Set the **"Webhook URL"**: + - For ngrok: `https://abc123.ngrok.io/webhook/line` +4. Click **"Verify"** to test the connection +5. Enable **"Use webhook"** + +## Step 7: Test + +1. Open LINE on your phone +2. Add your Official Account as a friend (scan QR code or search by ID) +3. Send a message to the bot +4. The bot should respond! + +## Features + +### Reply vs Push API + +LINE has two message sending methods: + +- **Reply API**: Free, valid for ~25 seconds after receiving a message +- **Push API**: Requires paid plan, sends messages proactively + +PicoClaw automatically uses Reply API when possible and falls back to Push API. + +### Group Chats + +In group chats, the bot only responds when: +- Mentioned with `@BotName` +- Or @mentioned via LINE's mention feature + +### Loading Indicator + +PicoClaw sends a loading indicator while processing messages. + +### Media Support + +The bot can receive images, audio, and video files. + +## Troubleshooting + +### Webhook verification fails + +1. Ensure the gateway is running +2. Verify the webhook URL is correct +3. Check firewall allows incoming connections +4. Verify `channel_secret` is correct + +### Bot not responding + +1. Check webhook is enabled in LINE Developers Console +2. Verify `channel_access_token` is valid +3. Check gateway logs for errors + +### "Invalid signature" error + +1. Verify `channel_secret` is correct +2. Ensure no extra whitespace in the secret + +### Messages sent but no response + +1. Check if Reply API timed out (> 25 seconds) +2. Consider upgrading to a paid plan for Push API + +## Advanced Configuration + +### Custom Webhook Path + +```json +{ + "channels": { + "line": { + "enabled": true, + "channel_secret": "YOUR_CHANNEL_SECRET", + "channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN", + "webhook_path": "/my-custom-webhook" + } + } +} +``` + +### Allow Specific Users + +```json +{ + "channels": { + "line": { + "enabled": true, + "channel_secret": "YOUR_CHANNEL_SECRET", + "channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN", + "allow_from": ["U1234567890abcdef", "U0987654321fedcba"] + } + } +} +``` + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [LINE Messaging API Documentation](https://developers.line.biz/en/docs/messaging-api/) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/maixcam.md b/docs/user-guide/channels/maixcam.md new file mode 100644 index 0000000000..c2c6bca8c2 --- /dev/null +++ b/docs/user-guide/channels/maixcam.md @@ -0,0 +1,275 @@ +# MaixCam Setup + +MaixCam is an AI-enabled camera device that can detect and report events to PicoClaw. + +## Prerequisites + +- A MaixCam device +- Network connectivity between MaixCam and PicoClaw server + +## Overview + +MaixCam is a hardware device with AI capabilities (person detection, object recognition, etc.). It connects to PicoClaw via TCP and sends event notifications when detections occur. + +## Step 1: Set Up MaixCam Device + +1. Power on your MaixCam device +2. Connect it to your network (WiFi or Ethernet) +3. Configure the device to send events to your PicoClaw server + +Refer to your MaixCam documentation for specific setup instructions. + +## Step 2: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "maixcam": { + "enabled": true, + "host": "0.0.0.0", + "port": 18790, + "allow_from": [] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `host` | No | Host to bind TCP server (default: `0.0.0.0`) | +| `port` | No | Port for TCP server (default: `18790`) | +| `allow_from` | No | Array of allowed device identifiers | + +## Step 3: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +Starting MaixCam channel server +MaixCam server listening host=0.0.0.0 port=18790 +``` + +## Step 4: Configure MaixCam to Connect + +On your MaixCam device, configure it to connect to PicoClaw: + +- Server IP: Your PicoClaw server's IP address +- Server Port: `18790` (or your configured port) + +## Step 5: Test + +1. Trigger a detection event on your MaixCam (e.g., walk in front of the camera) +2. The AI agent will receive the detection event and can respond accordingly + +## Message Format + +MaixCam sends JSON messages over TCP: + +### Person Detection Event + +```json +{ + "type": "person_detected", + "timestamp": 1708346400.123, + "data": { + "class_name": "person", + "class_id": 0, + "score": 0.95, + "x": 100, + "y": 200, + "w": 50, + "h": 100 + } +} +``` + +### Heartbeat Event + +```json +{ + "type": "heartbeat", + "timestamp": 1708346400.123, + "data": {} +} +``` + +### Status Event + +```json +{ + "type": "status", + "timestamp": 1708346400.123, + "data": { + "status": "online", + "battery": 85 + } +} +``` + +## Features + +### Person Detection + +When a person is detected, PicoClaw receives: + +- Class name (e.g., "person") +- Confidence score +- Position (x, y) +- Bounding box size (w, h) + +### Status Updates + +The device can send status updates including: +- Online/offline status +- Battery level +- System health + +### Command Response + +PicoClaw can send commands back to the MaixCam: + +```json +{ + "type": "command", + "timestamp": 0, + "message": "Command from AI", + "chat_id": "default" +} +``` + +## Use Cases + +### Security Monitoring + +The AI agent can: +- Log detection events +- Send alerts to other channels +- Trigger actions based on detection + +### Smart Home Integration + +Connect with other smart home devices: +- Turn on lights when person detected +- Trigger recordings +- Send notifications + +### Activity Logging + +Track and analyze: +- Movement patterns +- Peak activity times +- Anomaly detection + +## Troubleshooting + +### Device not connecting + +1. Verify network connectivity +2. Check firewall allows incoming connections on configured port +3. Verify MaixCam is configured with correct server IP and port + +### No events received + +1. Check MaixCam logs for errors +2. Verify detection features are enabled on the device +3. Check PicoClaw gateway logs for connection messages + +### Connection drops frequently + +1. Check network stability +2. Verify power supply to MaixCam +3. Check for interference if using WiFi + +### Slow response times + +1. Check network latency +2. Verify MaixCam processing is not overloaded +3. Consider reducing detection frequency + +## Advanced Configuration + +### Custom Port + +```json +{ + "channels": { + "maixcam": { + "enabled": true, + "host": "0.0.0.0", + "port": 9999 + } + } +} +``` + +### Multiple Devices + +Multiple MaixCam devices can connect to the same PicoClaw server. Each device maintains its own connection. + +### With Other Channels + +Combine MaixCam with other channels for notifications: + +```json +{ + "channels": { + "maixcam": { + "enabled": true, + "host": "0.0.0.0", + "port": 18790 + }, + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + } + } +} +``` + +The AI agent can then forward MaixCam alerts to Telegram. + +## Example Agent Response + +When MaixCam sends a person detection, you can configure your agent to respond: + +``` +Person detected! +Class: person +Confidence: 95.00% +Position: (100, 200) +Size: 50x100 +``` + +The agent can then: +- Log the event to memory +- Send a notification to another channel +- Trigger additional analysis + +## Technical Details + +### Connection Protocol + +- Transport: TCP +- Encoding: JSON (newline-delimited or continuous stream) +- Direction: Bidirectional (events from device, commands to device) + +### Message Processing + +1. MaixCam connects to PicoClaw TCP server +2. MaixCam sends JSON events +3. PicoClaw parses and routes events to the AI agent +4. AI agent processes and can respond with commands + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [MaixCam Documentation](https://maix.sipeed.com/) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/onebot.md b/docs/user-guide/channels/onebot.md new file mode 100644 index 0000000000..03a0cd306c --- /dev/null +++ b/docs/user-guide/channels/onebot.md @@ -0,0 +1,291 @@ +# OneBot Setup + +OneBot is a universal chatbot protocol that provides a standardized API for various messaging platforms. + +## Prerequisites + +- A OneBot-compatible implementation running +- Understanding of which platform you're connecting to (QQ, Telegram, etc.) + +## Overview + +OneBot (formerly CQHTTP) is a protocol specification that allows bots to communicate with various messaging platforms through a unified API. PicoClaw connects to a OneBot implementation via WebSocket. + +## Supported OneBot Implementations + +### For QQ + +- [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) - Popular Go implementation +- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) - Modern .NET implementation +- [NapCat](https://github.com/NapNeko/NapCatQQ) - Modern implementation + +### For Other Platforms + +- Various community implementations exist for WeChat, Telegram, etc. + +## Step 1: Install a OneBot Implementation + +### go-cqhttp Example + +1. Download go-cqhttp from [GitHub Releases](https://github.com/Mrs4s/go-cqhttp/releases) +2. Run it once to generate config files +3. Edit `config.yml`: + +```yaml +# config.yml +account: + uin: YOUR_QQ_NUMBER + password: '' + +servers: + - ws: + host: 127.0.0.1 + port: 3001 + +message: + post-format: string +``` + +4. Run go-cqhttp and scan the QR code to log in + +## Step 2: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "onebot": { + "enabled": true, + "ws_url": "ws://127.0.0.1:3001", + "access_token": "", + "reconnect_interval": 5, + "group_trigger_prefix": [], + "allow_from": [] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `ws_url` | Yes | WebSocket URL of OneBot implementation | +| `access_token` | No | Access token for authentication | +| `reconnect_interval` | No | Reconnection interval in seconds (default: 5) | +| `group_trigger_prefix` | No | Prefixes to trigger bot in groups (e.g., `["!", "/"]`) | +| `allow_from` | No | Array of allowed user IDs | + +## Step 3: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +Starting OneBot channel ws_url=ws://127.0.0.1:3001 +WebSocket connected +OneBot channel started successfully +``` + +## Step 4: Test + +### Private Messages + +1. Open your messaging app (e.g., QQ) +2. Send a message to the bot account +3. The bot should respond! + +### Group Messages + +In group chats, the bot responds when: +- Mentioned with `@BotName` +- Message starts with a configured trigger prefix + +## Features + +### Voice Transcription + +With Groq configured, voice messages are automatically transcribed: + +```json +{ + "providers": { + "groq": { + "api_key": "gsk_xxx" + } + } +} +``` + +### Group Trigger Prefixes + +Configure prefixes to trigger the bot in groups without mentioning: + +```json +{ + "channels": { + "onebot": { + "enabled": true, + "ws_url": "ws://127.0.0.1:3001", + "group_trigger_prefix": ["!", "/bot"] + } + } +} +``` + +With this configuration: +- `!hello` triggers the bot +- `/bot hello` triggers the bot +- `hello` does not trigger the bot (unless mentioned) + +### Automatic Reconnection + +The bot automatically reconnects if the WebSocket connection is lost. + +### Message Replies + +The bot replies to messages using the original message's context. + +### Emoji Reactions + +In group chats, the bot adds emoji reactions to indicate processing status. + +## Chat ID Format + +PicoClaw uses specific chat ID formats for OneBot: + +| Chat Type | Format | Example | +|-----------|--------|---------| +| Private | `private:USER_ID` | `private:123456789` | +| Group | `group:GROUP_ID` | `group:987654321` | + +## Troubleshooting + +### Connection refused + +1. Verify your OneBot implementation is running +2. Check the ws_url is correct +3. Ensure the WebSocket server is listening + +### Bot not responding + +1. Check OneBot logs for errors +2. Verify the messaging account is logged in +3. Check `allow_from` includes your user ID + +### "WebSocket not connected" error + +1. Verify OneBot WebSocket server is running +2. Check network connectivity +3. Increase `reconnect_interval` if connection is unstable + +### Group messages ignored + +1. Use `@BotName` or configure `group_trigger_prefix` +2. Verify the bot has proper permissions in the group + +### Voice transcription fails + +1. Verify Groq API key is configured +2. Check network allows connections to Groq API +3. Check logs for specific error messages + +## Advanced Configuration + +### With Access Token + +```json +{ + "channels": { + "onebot": { + "enabled": true, + "ws_url": "ws://127.0.0.1:3001", + "access_token": "your_secure_token", + "reconnect_interval": 10 + } + } +} +``` + +### Allow Specific Users + +```json +{ + "channels": { + "onebot": { + "enabled": true, + "ws_url": "ws://127.0.0.1:3001", + "allow_from": ["123456789", "987654321"] + } + } +} +``` + +## OneBot Configuration Examples + +### go-cqhttp + +```yaml +# config.yml +account: + uin: 123456789 + password: '' + +servers: + - ws: + host: 127.0.0.1 + port: 3001 + middle: + access-token: your_secure_token + +message: + post-format: array + +database: + leveldb: + enable: true +``` + +### Lagrange + +```json +{ + "Implementations": [ + { + "Type": "ForwardWebSocket", + "Host": "127.0.0.1", + "Port": 3001, + "AccessToken": "your_secure_token" + } + ] +} +``` + +## Important Notes + +### Account Security + +- Use a dedicated account for the bot +- Enable two-factor authentication +- Keep access tokens secure + +### Rate Limits + +Messaging platforms have rate limits. OneBot implementations typically handle this, but be aware of: +- Message sending frequency +- API call limits +- Group operation limits + +### Platform Terms of Service + +Using unofficial clients may violate platform terms of service. Use at your own risk. + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [OneBot Specification](https://github.com/botuniverse/onebot) +- [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/qq.md b/docs/user-guide/channels/qq.md new file mode 100644 index 0000000000..ed51167db1 --- /dev/null +++ b/docs/user-guide/channels/qq.md @@ -0,0 +1,178 @@ +# QQ Setup + +QQ is a popular instant messaging platform in China. PicoClaw connects via the QQ Official Bot API. + +## Prerequisites + +- A QQ account +- Access to [QQ Open Platform](https://bot.q.qq.com/) + +## Step 1: Create a QQ Bot + +1. Go to [QQ Bot Platform](https://bot.q.qq.com/) +2. Log in with your QQ account +3. Click **"Create Bot"** (创建机器人) +4. Fill in the bot information: + - Bot name + - Bot description + - Bot avatar +5. Submit for review (approval may take 1-3 days) + +## Step 2: Get App Credentials + +After approval: + +1. Go to your bot's dashboard +2. Find **"App ID"** (AppID) +3. Find **"App Secret"** (AppSecret) +4. Copy both values + +## Step 3: Configure Bot Settings + +1. In the bot dashboard, go to **"Intents"** (事件订阅) +2. Enable these intents: + - **Private messages** (C2C消息) + - **Group @ messages** (群@消息) +3. Save settings + +## Step 4: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "qq": { + "enabled": true, + "app_id": "YOUR_APP_ID", + "app_secret": "YOUR_APP_SECRET", + "allow_from": [] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `app_id` | Yes | App ID from QQ Bot Platform | +| `app_secret` | Yes | App Secret from QQ Bot Platform | +| `allow_from` | No | Array of allowed user IDs | + +## Step 5: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +Starting QQ bot (WebSocket mode) +QQ bot started successfully +``` + +## Step 6: Test + +### Private Messages + +1. Open QQ +2. Search for your bot by name +3. Send a friend request if needed +4. Send a message to the bot + +### Group Messages + +1. Add the bot to a QQ group +2. Mention the bot: `@YourBotName hello` +3. The bot should respond! + +## Features + +### Private Messages (C2C) + +Direct messages to the bot are processed automatically. + +### Group @ Mentions + +In group chats, the bot responds only when: +- The bot is mentioned with `@BotName` +- The message is a reply to the bot + +### Automatic Token Refresh + +The bot automatically refreshes access tokens as needed. + +## Troubleshooting + +### Bot not responding + +1. Verify app_id and app_secret are correct +2. Check that intents are enabled in the QQ Bot Platform +3. Ensure the gateway is running +4. Check firewall allows WebSocket connections + +### "Authentication failed" error + +1. Verify app_id and app_secret are correct +2. Check if the bot is approved and active +3. Ensure no extra whitespace in credentials + +### Group messages ignored + +1. Ensure you're using `@BotName` to mention the bot +2. Check that "Group @ messages" intent is enabled +3. Verify the bot has proper permissions in the group + +### WebSocket connection issues + +1. Check your network allows WebSocket connections to QQ servers +2. Verify no firewall is blocking outgoing connections +3. Check logs for specific error messages + +## Advanced Configuration + +### Allow Specific Users + +```json +{ + "channels": { + "qq": { + "enabled": true, + "app_id": "YOUR_APP_ID", + "app_secret": "YOUR_APP_SECRET", + "allow_from": ["123456789", "987654321"] + } + } +} +``` + +### Multiple Guilds/Servers + +The bot can be added to multiple QQ guilds. Use `allow_from` to control access across all of them. + +## Important Notes + +### Bot Approval + +QQ bots require approval before they can be used publicly. During development, you can test with your own account. + +### Rate Limits + +QQ has rate limits on API calls. If you experience issues with high-volume usage, consider: +- Reducing message frequency +- Implementing message batching +- Contacting QQ for higher limits + +### Regional Restrictions + +QQ Bot Platform may have restrictions based on: +- Your account region +- Bot content type +- Target audience + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [QQ Bot Documentation](https://bot.q.qq.com/wiki/) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/slack.md b/docs/user-guide/channels/slack.md new file mode 100644 index 0000000000..45ca3c073a --- /dev/null +++ b/docs/user-guide/channels/slack.md @@ -0,0 +1,189 @@ +# Slack Setup + +Slack is ideal for team collaboration and workplace automation. + +## Prerequisites + +- A Slack workspace with admin access (or ability to create apps) +- A Slack account + +## Step 1: Create a Slack App + +1. Go to [Slack API: Applications](https://api.slack.com/apps) +2. Click **"Create New App"** +3. Choose **"From scratch"** +4. Give it a name (e.g., "PicoClaw Bot") +5. Select your workspace +6. Click **"Create App"** + +## Step 2: Get Bot Token + +1. In your app, go to **"OAuth & Permissions"** in the left sidebar +2. Under **"Bot Token Scopes"**, add these scopes: + - `app_mentions:read` - Read messages that mention the bot + - `channels:history` - Read messages in public channels + - `chat:write` - Send messages + - `files:read` - Read files shared with the bot + `groups:history` - Read messages in private channels + - `im:history` - Read messages in direct messages + - `mpim:history` - Read messages in multi-party DMs + - `reactions:read` - Read message reactions + - `reactions:write` - Add reactions to messages +3. Click **"Install to Workspace"** +4. Copy the **"Bot User OAuth Token"** (starts with `xoxb-`) + +## Step 3: Enable Socket Mode + +1. Go to **"Socket Mode"** in the left sidebar +2. Enable Socket Mode +3. Click **"Generate Token"** +4. Copy the **"App-Level Token"** (starts with `xapp-`) + +## Step 4: Subscribe to Events + +1. Go to **"Event Subscriptions"** in the left sidebar +2. Enable events +3. Under **"Subscribe to bot events"**, add: + - `message.channels` - Messages in public channels + - `message.groups` - Messages in private channels + - `message.im` - Direct messages + - `message.mpim` - Multi-party direct messages + - `app_mention` - Bot mentions +4. Save changes + +## Step 5: Get Your User ID + +1. Open Slack +2. Click your profile picture (top right) +3. Click **"Profile"** +4. Click the **"..."** menu +5. Select **"Copy member ID"** + +## Step 6: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "slack": { + "enabled": true, + "bot_token": "xoxb-...", + "app_token": "xapp-...", + "allow_from": ["U1234567890"] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `bot_token` | Yes | Bot User OAuth Token (starts with `xoxb-`) | +| `app_token` | Yes | App-Level Token for Socket Mode (starts with `xapp-`) | +| `allow_from` | No | Array of allowed user IDs | + +## Step 7: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +Channels enabled: slack +Slack bot connected +Slack channel started (Socket Mode) +``` + +## Step 8: Test + +1. Open Slack +2. Invite the bot to a channel: `/invite @PicoClaw Bot` +3. Send a message mentioning the bot: `@PicoClaw Bot hello` +4. The bot should respond! + +## Features + +### Voice Messages + +With Groq configured, voice messages are automatically transcribed: + +```json +{ + "providers": { + "groq": { + "api_key": "gsk_xxx" + } + } +} +``` + +### Direct Messages + +Users can DM the bot directly for private conversations. + +### Thread Replies + +The bot maintains thread context - replies in threads stay in threads. + +### Reactions + +The bot adds a "eyes" reaction when processing a message and a "white_check_mark" when done. + +## Troubleshooting + +### Bot not responding + +1. Verify Socket Mode is enabled +2. Check both bot_token and app_token are correct +3. Ensure events are subscribed +4. Check `allow_from` includes your user ID + +### "not_authed" or "invalid_auth" error + +1. Re-install the app to your workspace +2. Verify tokens are correct and not expired + +### Bot can't read messages + +1. Ensure the bot is invited to the channel +2. Check that required OAuth scopes are added +3. Re-install the app after adding scopes + +### Socket Mode connection issues + +1. Verify your network allows WebSocket connections +2. Check the app_token is an App-Level Token (starts with `xapp-`) + +## Advanced Configuration + +### Multiple Users + +```json +{ + "channels": { + "slack": { + "enabled": true, + "bot_token": "xoxb-...", + "app_token": "xapp-...", + "allow_from": ["U1234567890", "U0987654321"] + } + } +} +``` + +### Slash Commands + +To add slash commands: + +1. Go to **"Slash Commands"** in your app +2. Create a new command (e.g., `/picoclaw`) +3. Set the request URL (not needed for Socket Mode) +4. Install the app to update + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/channels/telegram.md b/docs/user-guide/channels/telegram.md new file mode 100644 index 0000000000..6eda415e6f --- /dev/null +++ b/docs/user-guide/channels/telegram.md @@ -0,0 +1,163 @@ +# Telegram Setup + +Telegram is one of the easiest platforms to set up and is recommended for personal use. + +## Prerequisites + +- A Telegram account +- Access to @BotFather on Telegram + +## Step 1: Create a Bot + +1. Open Telegram and search for `@BotFather` +2. Send `/newbot` +3. Follow the prompts: + - Choose a name for your bot (e.g., "My PicoClaw Bot") + - Choose a username (must end in `bot`, e.g., `mypicoclaw_bot`) +4. Copy the **bot token** (looks like `123456789:ABCdefGHIjklMNOpqrsTUVwxyz`) + +## Step 2: Get Your User ID + +1. Search for `@userinfobot` on Telegram +2. Send any message +3. Copy your **User ID** (a number like `123456789`) + +## Step 3: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz", + "allow_from": ["123456789"] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `token` | Yes | Bot token from @BotFather | +| `proxy` | No | Proxy URL if needed | +| `allow_from` | No | Array of allowed user IDs | + +## Step 4: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +✓ Channels enabled: telegram +✓ Gateway started on 0.0.0.0:18790 +``` + +## Step 5: Test + +1. Open Telegram +2. Find your bot (search for the username) +3. Send a message +4. The bot should respond! + +## Features + +### Voice Messages + +With Groq configured, voice messages are automatically transcribed: + +```json +{ + "providers": { + "groq": { + "api_key": "gsk_xxx" + } + } +} +``` + +### Group Chats + +The bot works in group chats: +- Mention the bot with `@your_bot_name message` +- Or reply to the bot's messages + +### Commands + +Telegram supports bot commands: + +| Command | Description | +|---------|-------------| +| `/start` | Start interacting with the bot | +| `/help` | Show help message | +| `/reset` | Reset conversation session | + +## Troubleshooting + +### Bot not responding + +1. Check the gateway is running: `picoclaw gateway` +2. Verify your user ID is in `allow_from` +3. Check the bot token is correct + +### "Conflict: terminated by other getUpdates" + +This means another instance is using the bot token: +1. Stop other running instances +2. Make sure only one `picoclaw gateway` is running + +### Proxy issues + +If you need a proxy: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_TOKEN", + "proxy": "http://127.0.0.1:7890" + } + } +} +``` + +## Advanced Configuration + +### Allow Multiple Users + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_TOKEN", + "allow_from": ["123456789", "987654321", "111222333"] + } + } +} +``` + +### Allow All Users (Not Recommended) + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_TOKEN", + "allow_from": [] + } + } +} +``` + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/wecom-app-configuration.md b/docs/user-guide/channels/wecom-app-cn.md similarity index 100% rename from docs/wecom-app-configuration.md rename to docs/user-guide/channels/wecom-app-cn.md diff --git a/docs/user-guide/channels/wecom-app-en.md b/docs/user-guide/channels/wecom-app-en.md new file mode 100644 index 0000000000..e3fa8d37fc --- /dev/null +++ b/docs/user-guide/channels/wecom-app-en.md @@ -0,0 +1,117 @@ +# WeCom App Configuration Guide + +This document explains how to configure the WeCom App (wecom-app) channel in PicoClaw. + +## Features + +| Feature | Status | +|---------|--------| +| Receive messages | ✅ | +| Send messages | ✅ | +| Private chat | ✅ | +| Group chat | ❌ | + +## Configuration Steps + +### 1. WeCom Admin Console Setup + +1. Log in to [WeCom Admin Console](https://work.weixin.qq.com/wework_admin) +2. Go to "Application Management" → Select your custom app +3. Record the following information: + - **AgentId**: Shown on the app details page + - **Secret**: Click "View" to get it +4. Go to "My Company" page and record the **CorpID** (Enterprise ID) + +### 2. Message Reception Configuration + +1. On the app details page, click "Set API Receiver" under "Receive Messages" +2. Fill in the following: + - **URL**: `http://your-server:18792/webhook/wecom-app` + - **Token**: Randomly generated or custom (for signature verification) + - **EncodingAESKey**: Click "Random Generate" to generate a 43-character key +3. When you click "Save", WeCom will send a verification request + +### 3. PicoClaw Configuration + +Add the following configuration to your `config.json`: + +```json +{ + "channels": { + "wecom_app": { + "enabled": true, + "corp_id": "wwxxxxxxxxxxxxxxxx", // Enterprise ID + "corp_secret": "xxxxxxxxxxxxxxxxxxxxxxxx", // App Secret + "agent_id": 1000002, // App AgentId + "token": "your_token", // Token from message reception config + "encoding_aes_key": "your_encoding_aes_key", // EncodingAESKey from message reception config + "webhook_host": "0.0.0.0", + "webhook_port": 18792, + "webhook_path": "/webhook/wecom-app", + "allow_from": [], + "reply_timeout": 5 + } + } +} +``` + +## Troubleshooting + +### 1. Callback URL Verification Failed + +**Symptom**: WeCom shows verification failed when saving API receiver settings + +**Check**: +- Confirm server firewall has port 18792 open +- Confirm `corp_id`, `token`, `encoding_aes_key` are configured correctly +- Check PicoClaw logs for incoming requests + +### 2. Chinese Message Decryption Failed + +**Symptom**: `invalid padding size` error when sending Chinese messages + +**Cause**: WeCom uses non-standard PKCS7 padding (32-byte block size) + +**Solution**: Ensure you're using the latest version of PicoClaw, which has fixed this issue. + +### 3. Port Conflict + +**Symptom**: Port already in use error at startup + +**Solution**: Change `webhook_port` to another port, e.g., 18794 + +## Technical Details + +### Encryption Algorithm + +- **Algorithm**: AES-256-CBC +- **Key**: 32 bytes from Base64-decoded EncodingAESKey +- **IV**: First 16 bytes of AESKey +- **Padding**: PKCS7 (32-byte block size, not standard 16 bytes) +- **Message Format**: XML + +### Message Structure + +Decrypted message format: +``` +random(16B) + msg_len(4B) + msg + receiveid +``` + +Where `receiveid` is `corp_id` for custom apps. + +## Debugging + +Enable debug mode to see detailed logs: + +```bash +picoclaw gateway --debug +``` + +Key log identifiers: +- `wecom_app`: WeCom App channel related logs +- `wecom_common`: Encryption/decryption related logs + +## References + +- [WeCom Official Documentation - Receiving Messages](https://developer.work.weixin.qq.com/document/path/96211) +- [WeCom Official Encryption Library](https://github.com/sbzhu/weworkapi_golang) diff --git a/docs/user-guide/channels/wecom.md b/docs/user-guide/channels/wecom.md new file mode 100644 index 0000000000..2a5ebacd56 --- /dev/null +++ b/docs/user-guide/channels/wecom.md @@ -0,0 +1,83 @@ +# WeCom (Enterprise WeChat) + +WeCom (企业微信) is a enterprise messaging platform by Tencent. PicoClaw supports two types of WeCom integrations. + +## Integration Types + +| Type | Description | Group Chat | Active Messaging | +|------|-------------|------------|------------------| +| **WeCom Bot** | Group bot (智能机器人) | ✅ | ❌ | +| **WeCom App** | Custom app (自建应用) | ❌ | ✅ | + +### WeCom Bot (Group Bot) + +Simple setup for group chat notifications. The bot can receive and respond to messages in group chats. + +**Quick Setup:** + +1. WeCom Admin Console → Group Chat → Add Group Bot +2. Copy the webhook URL (format: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`) + +**Configuration:** + +```json +{ + "channels": { + "wecom": { + "enabled": true, + "token": "YOUR_TOKEN", + "encoding_aes_key": "YOUR_ENCODING_AES_KEY", + "webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY", + "webhook_host": "0.0.0.0", + "webhook_port": 18793, + "webhook_path": "/webhook/wecom", + "allow_from": [] + } + } +} +``` + +### WeCom App (Custom App) + +Full-featured integration with active messaging capabilities. Can send proactive messages to users. + +**Features:** +- ✅ Receive messages +- ✅ Send messages proactively +- ✅ Private chat support +- ❌ Group chat not supported + +**Detailed Configuration:** + +- **[English Guide](wecom-app-en.md)** +- **[中文指南](wecom-app-cn.md)** + +## Configuration + +### Basic Settings + +| Option | Description | +|--------|-------------| +| `enabled` | Enable/disable the channel | +| `token` | Token for signature verification | +| `encoding_aes_key` | Encryption key (43 characters) | +| `webhook_host` | Host for webhook server | +| `webhook_port` | Port for webhook (default: 18792 for app, 18793 for bot) | +| `webhook_path` | URL path for webhook | +| `allow_from` | User IDs allowed to interact (empty = all) | + +## Troubleshooting + +### Callback URL Verification Failed + +1. Check firewall has webhook port open +2. Verify `token` and `encoding_aes_key` match WeCom console settings +3. Check PicoClaw logs for incoming requests + +### Chinese Message Decryption Failed + +Ensure you're using the latest PicoClaw version - WeCom uses non-standard PKCS7 padding (32-byte blocks). + +## References + +- [WeCom Official Documentation](https://developer.work.weixin.qq.com/) diff --git a/docs/user-guide/channels/whatsapp.md b/docs/user-guide/channels/whatsapp.md new file mode 100644 index 0000000000..2f6c416e1e --- /dev/null +++ b/docs/user-guide/channels/whatsapp.md @@ -0,0 +1,228 @@ +# WhatsApp Setup + +WhatsApp is the world's most popular messaging app. PicoClaw connects via a bridge service. + +## Prerequisites + +- A WhatsApp account +- A WhatsApp bridge service (e.g., mautrix-whatsapp, whatsapp-web.js) + +## Overview + +PicoClaw requires a bridge service to connect to WhatsApp because WhatsApp does not provide a direct bot API for personal accounts. The bridge acts as a middleware between WhatsApp and PicoClaw. + +## Step 1: Set Up a WhatsApp Bridge + +### Option A: mautrix-whatsapp (Recommended) + +[mautrix-whatsapp](https://github.com/mautrix/whatsapp) is a Matrix-WhatsApp bridge that can be adapted for PicoClaw. + +### Option B: Custom Bridge + +You can create a custom WebSocket bridge using libraries like: +- [whatsapp-web.js](https://github.com/pedroslopez/whatsapp-web.js) (Node.js) +- [Baileys](https://github.com/WhiskeySockets/Baileys) (Node.js) + +The bridge should: +1. Connect to WhatsApp +2. Expose a WebSocket server +3. Forward messages between WhatsApp and PicoClaw + +## Step 2: Bridge Protocol + +Your bridge should communicate with PicoClaw via WebSocket using this message format: + +### Incoming Messages (to PicoClaw) + +```json +{ + "type": "message", + "from": "sender_phone_number", + "chat": "chat_id", + "content": "message text", + "id": "message_id", + "from_name": "Sender Name", + "media": [] +} +``` + +### Outgoing Messages (from PicoClaw) + +```json +{ + "type": "message", + "to": "chat_id", + "content": "response text" +} +``` + +## Step 3: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "whatsapp": { + "enabled": true, + "bridge_url": "ws://localhost:3001", + "allow_from": [] + } + } +} +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `enabled` | Yes | Set to `true` to enable | +| `bridge_url` | Yes | WebSocket URL of your bridge service | +| `allow_from` | No | Array of allowed phone numbers | + +## Step 4: Start the Gateway + +```bash +picoclaw gateway +``` + +You should see: +``` +Starting WhatsApp channel connecting to ws://localhost:3001... +WhatsApp channel connected +``` + +## Step 5: Test + +1. Open WhatsApp on your phone +2. Send a message to the connected account +3. The bot should respond! + +## Features + +### Media Support + +The bridge can forward media files: + +```json +{ + "type": "message", + "from": "+1234567890", + "chat": "+1234567890", + "content": "Check this image", + "media": ["/path/to/image.jpg"] +} +``` + +### Group Chats + +Group chat support depends on your bridge implementation. + +### Message Metadata + +Additional metadata can be included: + +```json +{ + "type": "message", + "from": "+1234567890", + "chat": "group_id@g.us", + "content": "Hello group!", + "id": "msg_123", + "from_name": "John Doe" +} +``` + +## Troubleshooting + +### Connection refused + +1. Verify your bridge service is running +2. Check the bridge_url is correct +3. Ensure the WebSocket server is listening + +### Messages not received + +1. Check bridge logs for errors +2. Verify WhatsApp connection is active +3. Ensure the bridge is forwarding messages correctly + +### Messages not sent + +1. Check PicoClaw logs for errors +2. Verify the bridge is handling outgoing messages +3. Check WhatsApp session is valid + +### Bridge disconnects frequently + +1. Check network stability +2. Verify WhatsApp session is persistent +3. Consider implementing reconnection logic in your bridge + +## Bridge Implementation Example + +Here's a simple example using Node.js with whatsapp-web.js: + +```javascript +const { Client, LocalAuth } = require('whatsapp-web.js'); +const WebSocket = require('ws'); + +// WhatsApp client +const waClient = new Client({ + authStrategy: new LocalAuth() +}); + +// WebSocket server for PicoClaw +const wss = new WebSocket.Server({ port: 3001 }); + +let picoclawConnection = null; + +wss.on('connection', (ws) => { + picoclawConnection = ws; + console.log('PicoClaw connected'); + + ws.on('message', (data) => { + const msg = JSON.parse(data); + if (msg.type === 'message') { + // Send to WhatsApp + waClient.sendMessage(msg.to, msg.content); + } + }); +}); + +// Forward WhatsApp messages to PicoClaw +waClient.on('message', (msg) => { + if (picoclawConnection) { + picoclawConnection.send(JSON.stringify({ + type: 'message', + from: msg.from, + chat: msg.from, + content: msg.body, + id: msg.id._serialized, + from_name: msg._data.notifyName + })); + } +}); + +waClient.initialize(); +``` + +## Important Notes + +### WhatsApp Terms of Service + +Using unofficial WhatsApp clients may violate WhatsApp's Terms of Service. Use at your own risk. + +### Business API + +For production use, consider the official [WhatsApp Business API](https://business.whatsapp.com/). + +### Session Persistence + +Ensure your bridge properly saves and restores WhatsApp sessions to avoid repeated QR code scans. + +## See Also + +- [Channels Overview](README.md) +- [Gateway Command](../cli/gateway.md) +- [mautrix-whatsapp](https://github.com/mautrix/whatsapp) +- [whatsapp-web.js](https://github.com/pedroslopez/whatsapp-web.js) +- [Troubleshooting](../../operations/troubleshooting.md) diff --git a/docs/user-guide/cli-reference.md b/docs/user-guide/cli-reference.md new file mode 100644 index 0000000000..b30b1af9db --- /dev/null +++ b/docs/user-guide/cli-reference.md @@ -0,0 +1,328 @@ +# CLI Reference + +Complete reference for all PicoClaw command-line commands. + +## Global Commands + +### picoclaw onboard + +Initialize configuration and workspace. + +```bash +picoclaw onboard +``` + +This command: +- Creates `~/.picoclaw/config.json` with default settings +- Creates `~/.picoclaw/workspace/` directory +- Copies default workspace templates (AGENT.md, IDENTITY.md, etc.) + +### picoclaw agent + +Interact with the agent directly. + +```bash +# Send a single message +picoclaw agent -m "What is 2+2?" + +# Interactive mode +picoclaw agent + +# With debug logging +picoclaw agent --debug -m "Hello" + +# With specific session +picoclaw agent -s "my-session" -m "Continue our conversation" +``` + +| Flag | Short | Description | +|------|-------|-------------| +| `--message` | `-m` | Send a single message and exit | +| `--session` | `-s` | Session key (default: `cli:default`) | +| `--debug` | `-d` | Enable debug logging | + +**Interactive Mode Commands:** + +| Command | Description | +|---------|-------------| +| `exit` | Exit interactive mode | +| `quit` | Exit interactive mode | +| `Ctrl+C` | Exit interactive mode | + +### picoclaw gateway + +Start the gateway for all enabled channels. + +```bash +# Start gateway +picoclaw gateway + +# With debug logging +picoclaw gateway --debug +``` + +| Flag | Short | Description | +|------|-------|-------------| +| `--debug` | `-d` | Enable debug logging | + +The gateway: +- Starts all enabled channels (Telegram, Discord, etc.) +- Starts the heartbeat service +- Starts the cron service +- Starts health endpoints at `http://host:port/health` and `/ready` + +### picoclaw status + +Show system status. + +```bash +picoclaw status +``` + +Displays: +- Version and build info +- Config file location +- Workspace location +- Configured API keys status +- OAuth authentication status + +### picoclaw version + +Show version information. + +```bash +picoclaw version +# or +picoclaw -v +picoclaw --version +``` + +## Authentication Commands + +### picoclaw auth login + +Login via OAuth or paste token. + +```bash +# Login with OAuth (opens browser) +picoclaw auth login --provider openai + +# Login with device code (headless) +picoclaw auth login --provider openai --device-code + +# Login with token paste +picoclaw auth login --provider anthropic +``` + +| Flag | Short | Description | +|------|-------|-------------| +| `--provider` | `-p` | Provider name (openai, anthropic) | +| `--device-code` | | Use device code flow for headless environments | + +### picoclaw auth logout + +Remove stored credentials. + +```bash +# Logout from specific provider +picoclaw auth logout --provider openai + +# Logout from all providers +picoclaw auth logout +``` + +### picoclaw auth status + +Show current authentication status. + +```bash +picoclaw auth status +``` + +## Cron Commands + +### picoclaw cron list + +List all scheduled jobs. + +```bash +picoclaw cron list +``` + +### picoclaw cron add + +Add a new scheduled job. + +```bash +# Every 2 hours (7200 seconds) +picoclaw cron add -n "Check weather" -m "Check weather in Beijing" -e 7200 + +# With cron expression (daily at 9am) +picoclaw cron add -n "Morning report" -m "Give me a morning report" -c "0 9 * * *" + +# Deliver response to channel +picoclaw cron add -n "Reminder" -m "Time for a break!" -e 3600 -d --to "123456789" --channel "telegram" +``` + +| Flag | Short | Description | +|------|-------|-------------| +| `--name` | `-n` | Job name (required) | +| `--message` | `-m` | Message for agent (required) | +| `--every` | `-e` | Run every N seconds | +| `--cron` | `-c` | Cron expression | +| `--deliver` | `-d` | Deliver response to channel | +| `--to` | | Recipient for delivery | +| `--channel` | | Channel for delivery | + +### picoclaw cron remove + +Remove a scheduled job. + +```bash +picoclaw cron remove +``` + +### picoclaw cron enable + +Enable a disabled job. + +```bash +picoclaw cron enable +``` + +### picoclaw cron disable + +Disable a job without removing it. + +```bash +picoclaw cron disable +``` + +## Skills Commands + +### picoclaw skills list + +List installed skills. + +```bash +picoclaw skills list +``` + +### picoclaw skills install + +Install a skill from GitHub. + +```bash +picoclaw skills install sipeed/picoclaw-skills/weather +``` + +### picoclaw skills remove + +Remove an installed skill. + +```bash +picoclaw skills remove weather +``` + +### picoclaw skills install-builtin + +Install all builtin skills to workspace. + +```bash +picoclaw skills install-builtin +``` + +### picoclaw skills list-builtin + +List available builtin skills. + +```bash +picoclaw skills list-builtin +``` + +### picoclaw skills search + +Search for available skills. + +```bash +picoclaw skills search +``` + +### picoclaw skills show + +Show skill details. + +```bash +picoclaw skills show weather +``` + +## Migration Commands + +### picoclaw migrate + +Migrate from OpenClaw to PicoClaw. + +```bash +# Detect and migrate +picoclaw migrate + +# Preview changes +picoclaw migrate --dry-run + +# Re-sync workspace files +picoclaw migrate --refresh + +# Migrate without confirmation +picoclaw migrate --force + +# Only migrate config +picoclaw migrate --config-only + +# Only migrate workspace +picoclaw migrate --workspace-only + +# Override directories +picoclaw migrate --openclaw-home /path/to/openclaw --picoclaw-home /path/to/picoclaw +``` + +| Flag | Description | +|------|-------------| +| `--dry-run` | Show what would be migrated without making changes | +| `--refresh` | Re-sync workspace files from OpenClaw | +| `--config-only` | Only migrate config, skip workspace | +| `--workspace-only` | Only migrate workspace files, skip config | +| `--force` | Skip confirmation prompts | +| `--openclaw-home` | Override OpenClaw home directory | +| `--picoclaw-home` | Override PicoClaw home directory | + +## Command Summary + +| Command | Description | +|---------|-------------| +| `onboard` | Initialize configuration and workspace | +| `agent` | Interact with agent directly | +| `gateway` | Start gateway for all channels | +| `status` | Show system status | +| `version` | Show version information | +| `auth login` | Login via OAuth or token | +| `auth logout` | Remove stored credentials | +| `auth status` | Show authentication status | +| `cron list` | List scheduled jobs | +| `cron add` | Add a scheduled job | +| `cron remove` | Remove a job | +| `cron enable` | Enable a job | +| `cron disable` | Disable a job | +| `skills list` | List installed skills | +| `skills install` | Install a skill | +| `skills remove` | Remove a skill | +| `skills install-builtin` | Install builtin skills | +| `skills list-builtin` | List builtin skills | +| `skills search` | Search for skills | +| `skills show` | Show skill details | +| `migrate` | Migrate from OpenClaw | + +## See Also + +- [Configuration Reference](../configuration/config-file.md) - Complete configuration options +- [Quick Start](../getting-started/quick-start.md) - Get started quickly +- [Troubleshooting](../operations/troubleshooting.md) - Common issues and solutions diff --git a/docs/user-guide/cli/agent.md b/docs/user-guide/cli/agent.md new file mode 100644 index 0000000000..466150ac8a --- /dev/null +++ b/docs/user-guide/cli/agent.md @@ -0,0 +1,114 @@ +# picoclaw agent + +Interact with the AI agent directly from the command line. + +## Usage + +```bash +# One-shot message +picoclaw agent -m "Your message here" + +# Interactive mode +picoclaw agent + +# With debug logging +picoclaw agent --debug -m "Hello" + +# With specific session +picoclaw agent -s "my-session" -m "Continue our chat" +``` + +## Options + +| Flag | Short | Default | Description | +|------|-------|---------|-------------| +| `--message` | `-m` | - | Send a single message and exit | +| `--session` | `-s` | `cli:default` | Session key for conversation history | +| `--debug` | `-d` | `false` | Enable debug logging | + +## Modes + +### One-Shot Mode + +Send a single message and receive a response: + +```bash +picoclaw agent -m "What is 2+2?" +``` + +Output: +``` +🦞 2 + 2 equals 4. +``` + +### Interactive Mode + +Start a continuous chat session: + +```bash +picoclaw agent +``` + +``` +🦞 Interactive mode (Ctrl+C to exit) + +🦞 You: Hello! + +🦞 Hello! How can I help you today? + +🦞 You: Tell me a joke + +🦞 Why don't scientists trust atoms? Because they make up everything! + +🦞 You: exit +Goodbye! +``` + +### Debug Mode + +See detailed processing information: + +```bash +picoclaw agent --debug -m "Hello" +``` + +Debug output includes: +- LLM API requests +- Tool invocations +- Response parsing +- Timing information + +## Sessions + +Sessions maintain conversation history: + +```bash +# Start a new session +picoclaw agent -s "work-project" -m "I'm starting a new project" + +# Continue the same session +picoclaw agent -s "work-project" -m "What should we do next?" +``` + +Sessions are stored in `~/.picoclaw/workspace/sessions/`. + +## Examples + +```bash +# Quick question +picoclaw agent -m "What's the capital of France?" + +# Code assistance +picoclaw agent -m "Write a Python function to reverse a string" + +# With web search +picoclaw agent -m "Search for the latest news about AI and summarize" + +# Continue previous conversation +picoclaw agent -s "morning-standup" -m "What did we discuss yesterday?" +``` + +## See Also + +- [First Chat](../../getting-started/first-chat.md) +- [CLI Reference](../cli-reference.md) diff --git a/docs/user-guide/cli/auth.md b/docs/user-guide/cli/auth.md new file mode 100644 index 0000000000..d15bba7660 --- /dev/null +++ b/docs/user-guide/cli/auth.md @@ -0,0 +1,140 @@ +# picoclaw auth + +Manage authentication for LLM providers. + +## Usage + +```bash +# Login +picoclaw auth login --provider [--device-code] + +# Logout +picoclaw auth logout [--provider ] + +# Status +picoclaw auth status +``` + +## Subcommands + +### auth login + +Authenticate with a provider. + +```bash +# Login via OAuth (opens browser) +picoclaw auth login --provider openai + +# Login via device code (headless) +picoclaw auth login --provider openai --device-code + +# Login with token (Anthropic) +picoclaw auth login --provider anthropic +``` + +| Flag | Short | Description | +|------|-------|-------------| +| `--provider` | `-p` | Provider name (openai, anthropic) | +| `--device-code` | | Use device code flow for headless environments | + +**Supported Providers:** + +| Provider | Auth Methods | +|----------|-------------| +| `openai` | OAuth, device code | +| `anthropic` | Token paste | + +### auth logout + +Remove stored credentials. + +```bash +# Logout from specific provider +picoclaw auth logout --provider openai + +# Logout from all providers +picoclaw auth logout +``` + +### auth status + +Show current authentication status. + +```bash +picoclaw auth status +``` + +Output: +``` +Authenticated Providers: +------------------------ + openai: + Method: oauth + Status: active + Account: user@example.com + Expires: 2025-03-01 12:00 + anthropic: + Method: token + Status: active +``` + +## When to Use OAuth vs API Key + +**Use OAuth/Token when:** +- You don't want to manage API keys +- You want automatic token refresh +- Using provider-specific features + +**Use API Key when:** +- Simpler setup preferred +- Using multiple providers +- Server/automated environments + +## Configuration + +After login, set the auth method in config: + +```json +{ + "providers": { + "openai": { + "auth_method": "oauth" + }, + "anthropic": { + "auth_method": "token" + } + } +} +``` + +## Credential Storage + +Credentials are stored in: +``` +~/.picoclaw/credentials.json +``` + +This file contains sensitive tokens and should be protected. + +## Examples + +```bash +# Login to OpenAI +picoclaw auth login --provider openai + +# Check status +picoclaw auth status + +# If token expired, re-login +picoclaw auth login --provider openai + +# Switch to API key instead +picoclaw auth logout --provider openai +# Then add api_key to config.json +``` + +## See Also + +- [CLI Reference](../cli-reference.md) +- [Configuration](../../configuration/config-file.md) +- [OpenAI Provider](../providers/openai.md) diff --git a/docs/user-guide/cli/cron.md b/docs/user-guide/cli/cron.md new file mode 100644 index 0000000000..7e683fb151 --- /dev/null +++ b/docs/user-guide/cli/cron.md @@ -0,0 +1,177 @@ +# picoclaw cron + +Manage scheduled tasks and reminders. + +## Usage + +```bash +# List jobs +picoclaw cron list + +# Add job +picoclaw cron add -n "name" -m "message" (-e | -c ) + +# Remove job +picoclaw cron remove + +# Enable/disable +picoclaw cron enable +picoclaw cron disable +``` + +## Subcommands + +### cron list + +List all scheduled jobs. + +```bash +picoclaw cron list +``` + +Output: +``` +Scheduled Jobs: +---------------- + Weather Check (abc123) + Schedule: every 3600s + Status: enabled + Next run: 2025-02-20 15:00 + + Morning Report (def456) + Schedule: 0 9 * * * + Status: enabled + Next run: 2025-02-21 09:00 +``` + +### cron add + +Add a new scheduled job. + +```bash +# Every 2 hours (7200 seconds) +picoclaw cron add -n "Check weather" -m "Check weather in Beijing" -e 7200 + +# With cron expression (daily at 9am) +picoclaw cron add -n "Morning report" -m "Give me a morning report" -c "0 9 * * *" + +# Deliver response to channel +picoclaw cron add -n "Reminder" -m "Time for a break!" -e 3600 -d --to "123456789" --channel "telegram" +``` + +| Flag | Short | Description | +|------|-------|-------------| +| `--name` | `-n` | Job name (required) | +| `--message` | `-m` | Message for the agent (required) | +| `--every` | `-e` | Run every N seconds | +| `--cron` | `-c` | Cron expression | +| `--deliver` | `-d` | Deliver response to channel | +| `--to` | | Recipient ID for delivery | +| `--channel` | | Channel name for delivery | + +**Schedule Types:** + +| Type | Flag | Example | +|------|------|---------| +| Interval | `-e 3600` | Every hour | +| Cron | `-c "0 9 * * *"` | Daily at 9am | + +### cron remove + +Remove a scheduled job. + +```bash +picoclaw cron remove +``` + +### cron enable / cron disable + +Enable or disable a job without removing it. + +```bash +picoclaw cron enable +picoclaw cron disable +``` + +## Cron Expressions + +Standard 5-field cron format: + +``` +┌───────────── minute (0 - 59) +│ ┌───────────── hour (0 - 23) +│ │ ┌───────────── day of month (1 - 31) +│ │ │ ┌───────────── month (1 - 12) +│ │ │ │ ┌───────────── day of week (0 - 6, Sunday = 0) +│ │ │ │ │ +* * * * * +``` + +**Examples:** + +| Expression | Meaning | +|------------|---------| +| `0 9 * * *` | Every day at 9:00 AM | +| `0 */2 * * *` | Every 2 hours | +| `30 8 * * 1-5` | Weekdays at 8:30 AM | +| `0 0 * * 0` | Every Sunday at midnight | +| `0 9 1 * *` | First day of month at 9:00 AM | + +## Storage + +Jobs are stored in: +``` +~/.picoclaw/workspace/cron/jobs.json +``` + +## Configuration + +Configure timeout in `~/.picoclaw/config.json`: + +```json +{ + "tools": { + "cron": { + "exec_timeout_minutes": 5 + } + } +} +``` + +## Job Delivery + +When `--deliver` is set, the agent's response is sent to the specified channel: + +```bash +# Send reminder to Telegram user +picoclaw cron add -n "Standup" -m "Time for standup!" \ + -c "0 10 * * 1-5" -d --to "123456789" --channel "telegram" +``` + +## Examples + +```bash +# Daily weather report +picoclaw cron add -n "Weather" -m "What's the weather today?" -c "0 7 * * *" + +# Hourly reminder +picoclaw cron add -n "Hydrate" -m "Drink water!" -e 3600 + +# Weekly summary +picoclaw cron add -n "Weekly" -m "Summarize what I did this week" -c "0 17 * * 5" + +# List all jobs +picoclaw cron list + +# Disable a job +picoclaw cron disable abc123 + +# Remove a job +picoclaw cron remove abc123 +``` + +## See Also + +- [Heartbeat Tasks](../workspace/heartbeat-tasks.md) +- [Cron Tool](../tools/cron.md) +- [CLI Reference](../cli-reference.md) diff --git a/docs/user-guide/cli/gateway.md b/docs/user-guide/cli/gateway.md new file mode 100644 index 0000000000..8fe6596415 --- /dev/null +++ b/docs/user-guide/cli/gateway.md @@ -0,0 +1,121 @@ +# picoclaw gateway + +Start the gateway for all enabled chat channels. + +## Usage + +```bash +# Start gateway +picoclaw gateway + +# With debug logging +picoclaw gateway --debug +``` + +## Options + +| Flag | Short | Description | +|------|-------|-------------| +| `--debug` | `-d` | Enable debug logging | + +## Description + +The gateway command starts PicoClaw in server mode, enabling: + +1. **Chat Channels** - Telegram, Discord, Slack, etc. +2. **Heartbeat Service** - Periodic task execution +3. **Cron Service** - Scheduled jobs +4. **Device Monitoring** - USB device events (Linux) +5. **Health Endpoints** - `/health` and `/ready` + +## What It Starts + +``` +✓ Channels enabled: telegram, discord +✓ Gateway started on 0.0.0.0:18790 +Press Ctrl+C to stop +✓ Cron service started +✓ Heartbeat service started +✓ Health endpoints available at http://0.0.0.0:18790/health and /ready +``` + +## Configuration + +Enable channels in `~/.picoclaw/config.json`: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"] + }, + "discord": { + "enabled": true, + "token": "YOUR_BOT_TOKEN" + } + } +} +``` + +## Gateway Settings + +Configure in `~/.picoclaw/config.json`: + +```json +{ + "gateway": { + "host": "0.0.0.0", + "port": 18790 + } +} +``` + +## Health Endpoints + +| Endpoint | Purpose | +|----------|---------| +| `/health` | Liveness check | +| `/ready` | Readiness check | + +```bash +curl http://localhost:18790/health +# OK + +curl http://localhost:18790/ready +# OK +``` + +## Stopping + +Press `Ctrl+C` to stop the gateway gracefully: + +``` +^C +Shutting down... +✓ Gateway stopped +``` + +## Running as a Service + +For production, run as a systemd service. See [Systemd Deployment](../../deployment/systemd.md). + +## Examples + +```bash +# Start with Telegram and Discord +picoclaw gateway + +# Debug mode for troubleshooting +picoclaw gateway --debug + +# Run in background +nohup picoclaw gateway > picoclaw.log 2>&1 & +``` + +## See Also + +- [Channels Guide](../channels/README.md) +- [Systemd Deployment](../../deployment/systemd.md) +- [Health Endpoints](../../operations/health-endpoints.md) diff --git a/docs/user-guide/cli/migrate.md b/docs/user-guide/cli/migrate.md new file mode 100644 index 0000000000..1df1af5fa5 --- /dev/null +++ b/docs/user-guide/cli/migrate.md @@ -0,0 +1,107 @@ +# picoclaw migrate + +Migrate from OpenClaw to PicoClaw. + +## Usage + +```bash +# Detect and migrate +picoclaw migrate + +# Preview changes +picoclaw migrate --dry-run + +# Full options +picoclaw migrate [options] +``` + +## Options + +| Flag | Description | +|------|-------------| +| `--dry-run` | Show what would be migrated without making changes | +| `--refresh` | Re-sync workspace files from OpenClaw | +| `--config-only` | Only migrate config, skip workspace files | +| `--workspace-only` | Only migrate workspace files, skip config | +| `--force` | Skip confirmation prompts | +| `--openclaw-home` | Override OpenClaw home directory (default: ~/.openclaw) | +| `--picoclaw-home` | Override PicoClaw home directory (default: ~/.picoclaw) | + +## Description + +The migrate command helps transition from OpenClaw to PicoClaw by: + +1. Detecting existing OpenClaw installation +2. Converting configuration to PicoClaw format +3. Copying workspace files (AGENT.md, MEMORY.md, etc.) +4. Preserving session history + +## Examples + +### Basic Migration + +```bash +# Run migration +picoclaw migrate + +# Output shows what will be migrated +OpenClaw detected at ~/.openclaw +Migrating to ~/.picoclaw... +✓ Config migrated +✓ Workspace files copied +✓ Sessions preserved +Migration complete! +``` + +### Preview Changes + +```bash +picoclaw migrate --dry-run +``` + +### Re-sync Workspace + +```bash +# If you updated OpenClaw workspace, re-sync +picoclaw migrate --refresh +``` + +### Partial Migration + +```bash +# Only migrate config +picoclaw migrate --config-only + +# Only migrate workspace +picoclaw migrate --workspace-only +``` + +### Custom Directories + +```bash +picoclaw migrate --openclaw-home /path/to/openclaw --picoclaw-home /path/to/picoclaw +``` + +## What Gets Migrated + +| OpenClaw | PicoClaw | +|----------|----------| +| `~/.openclaw/config.json` | `~/.picoclaw/config.json` | +| `~/.openclaw/workspace/AGENT.md` | `~/.picoclaw/workspace/AGENT.md` | +| `~/.openclaw/workspace/IDENTITY.md` | `~/.picoclaw/workspace/IDENTITY.md` | +| `~/.openclaw/workspace/MEMORY.md` | `~/.picoclaw/workspace/MEMORY.md` | +| `~/.openclaw/workspace/HEARTBEAT.md` | `~/.picoclaw/workspace/HEARTBEAT.md` | +| Sessions | Sessions | + +## After Migration + +1. Review `~/.picoclaw/config.json` +2. Update any provider API keys +3. Test with `picoclaw agent -m "Hello"` +4. Start gateway with `picoclaw gateway` + +## See Also + +- [Installation](../../getting-started/installation.md) +- [Configuration](../../configuration/config-file.md) +- [OpenClaw Migration Guide](../../migration/openclaw-migration.md) diff --git a/docs/user-guide/cli/onboard.md b/docs/user-guide/cli/onboard.md new file mode 100644 index 0000000000..a8adbefca4 --- /dev/null +++ b/docs/user-guide/cli/onboard.md @@ -0,0 +1,63 @@ +# picoclaw onboard + +Initialize PicoClaw configuration and workspace. + +## Usage + +```bash +picoclaw onboard +``` + +## Description + +The `onboard` command sets up PicoClaw for first-time use by: + +1. Creating the configuration directory at `~/.picoclaw/` +2. Generating `~/.picoclaw/config.json` with default settings +3. Creating the workspace directory at `~/.picoclaw/workspace/` +4. Copying default templates (AGENT.md, IDENTITY.md, etc.) + +## What It Creates + +``` +~/.picoclaw/ +├── config.json # Main configuration file +└── workspace/ + ├── sessions/ # Conversation history + ├── memory/ # Long-term memory + ├── cron/ # Scheduled jobs + ├── skills/ # Custom skills + ├── AGENT.md # Agent behavior guide + ├── IDENTITY.md # Agent identity + ├── SOUL.md # Agent personality + ├── USER.md # User preferences + └── HEARTBEAT.md # Periodic tasks +``` + +## Example + +```bash +$ picoclaw onboard + +Config already exists at /home/user/.picoclaw/config.json +Overwrite? (y/n): y + +🦞 picoclaw is ready! + +Next steps: + 1. Add your API key to /home/user/.picoclaw/config.json + Get one at: https://openrouter.ai/keys + 2. Chat: picoclaw agent -m "Hello!" +``` + +## Next Steps + +After running onboard: + +1. Edit `~/.picoclaw/config.json` and add your API key +2. Run `picoclaw agent -m "Hello!"` to test + +## See Also + +- [Quick Start](../../getting-started/quick-start.md) +- [Configuration Reference](../../configuration/config-file.md) diff --git a/docs/user-guide/cli/skills.md b/docs/user-guide/cli/skills.md new file mode 100644 index 0000000000..3f86e4999e --- /dev/null +++ b/docs/user-guide/cli/skills.md @@ -0,0 +1,159 @@ +# picoclaw skills + +Manage skills - specialized capabilities for the agent. + +## Usage + +```bash +# List installed skills +picoclaw skills list + +# Install from GitHub +picoclaw skills install + +# Remove a skill +picoclaw skills remove + +# Install builtin skills +picoclaw skills install-builtin + +# List builtin skills +picoclaw skills list-builtin + +# Search for skills +picoclaw skills search + +# Show skill details +picoclaw skills show +``` + +## Subcommands + +### skills list + +List all installed skills. + +```bash +picoclaw skills list +``` + +Output: +``` +Installed Skills: +------------------ + ✓ weather (workspace) + Get weather information for any location + ✓ news (builtin) + Fetch latest news headlines + ✓ calculator (builtin) + Perform calculations +``` + +### skills install + +Install a skill from GitHub. + +```bash +picoclaw skills install sipeed/picoclaw-skills/weather +``` + +### skills remove + +Remove an installed skill. + +```bash +picoclaw skills remove weather +``` + +### skills install-builtin + +Copy all builtin skills to your workspace. + +```bash +picoclaw skills install-builtin +``` + +### skills list-builtin + +List available builtin skills. + +```bash +picoclaw skills list-builtin +``` + +Output: +``` +Available Builtin Skills: +----------------------- + ✓ weather + Get weather information + ✓ news + Get latest news headlines + ✓ stock + Check stock prices + ✓ calculator + Perform mathematical calculations +``` + +### skills search + +Search for available skills online. + +```bash +picoclaw skills search +``` + +### skills show + +Show details of a specific skill. + +```bash +picoclaw skills show weather +``` + +## Skill Locations + +Skills are loaded from (in order): + +1. `~/.picoclaw/workspace/skills/` - Workspace skills +2. `~/.picoclaw/skills/` - Global skills +3. `~/.picoclaw/picoclaw/skills/` - Builtin skills + +## Skill Structure + +A skill is a directory containing `SKILL.md`: + +``` +weather/ +├── SKILL.md # Skill definition +└── (optional files) +``` + +## Creating Skills + +See [Creating Skills](../skills/creating-skills.md) for how to create custom skills. + +## Examples + +```bash +# Install a skill +picoclaw skills install sipeed/picoclaw-skills/weather + +# List what's installed +picoclaw skills list + +# Install all builtin skills +picoclaw skills install-builtin + +# Show skill content +picoclaw skills show weather + +# Remove a skill +picoclaw skills remove weather +``` + +## See Also + +- [Skills Overview](../skills/README.md) +- [Creating Skills](../skills/creating-skills.md) +- [CLI Reference](../cli-reference.md) diff --git a/docs/user-guide/cli/status.md b/docs/user-guide/cli/status.md new file mode 100644 index 0000000000..e2261c2ec2 --- /dev/null +++ b/docs/user-guide/cli/status.md @@ -0,0 +1,62 @@ +# picoclaw status + +Show PicoClaw system status and configuration. + +## Usage + +```bash +picoclaw status +``` + +## Description + +The `status` command displays: + +- Version and build information +- Configuration file location +- Workspace location +- API key configuration status +- OAuth authentication status + +## Example Output + +``` +🦞 picoclaw Status +Version: 0.1.1 (git: abc123) + +Config: /home/user/.picoclaw/config.json ✓ +Workspace: /home/user/.picoclaw/workspace ✓ +Model: anthropic/claude-opus-4-5 +OpenRouter API: ✓ +Anthropic API: not set +OpenAI API: ✓ +Gemini API: not set +Zhipu API: not set +Groq API: ✓ +vLLM/Local: not set + +OAuth/Token Auth: + openai (oauth): active + anthropic (token): needs refresh +``` + +## Status Indicators + +| Symbol | Meaning | +|--------|---------| +| ✓ | Configured and available | +| ✗ | Not configured or not found | +| `active` | OAuth token is valid | +| `expired` | OAuth token has expired | +| `needs refresh` | OAuth token should be refreshed | + +## Use Cases + +1. **Verify configuration** - Check API keys are set +2. **Debug issues** - Confirm config file is found +3. **Check authentication** - Verify OAuth tokens + +## See Also + +- [CLI Reference](../cli-reference.md) +- [Authentication](auth.md) diff --git a/docs/user-guide/ide-setup/README.md b/docs/user-guide/ide-setup/README.md new file mode 100644 index 0000000000..26317dd379 --- /dev/null +++ b/docs/user-guide/ide-setup/README.md @@ -0,0 +1,61 @@ +# IDE Setup + +PicoClaw can integrate with various IDEs and development environments through different providers. This section covers how to set up PicoClaw to work with your preferred development workflow. + +## Available IDE Integrations + +| Integration | Type | Description | +|-------------|------|-------------| +| **Antigravity** | Google Cloud Code Assist | Free access to Claude and Gemini models via Google Cloud | +| **GitHub Copilot** | GitHub | Use GitHub Copilot models with PicoClaw | + +## Antigravity (Google Cloud Code Assist) + +Antigravity provides free access to powerful AI models (Claude Opus, Gemini) through Google Cloud's infrastructure. This is ideal for developers who want to use PicoClaw without managing multiple API keys. + +**Key Features:** +- Free tier with generous quotas +- Access to Claude Opus 4.6 and Gemini models +- OAuth authentication (no API key management) +- Usage tracking and quota management + +**Setup Guide:** [Antigravity Setup](antigravity.md) + +## Configuration + +Once you've set up an IDE provider, configure it in your `~/.picoclaw/config.json`: + +```json +{ + "model_list": [ + { + "model_name": "gemini-flash", + "model": "antigravity/gemini-3-flash", + "auth_method": "oauth" + } + ], + "agents": { + "defaults": { + "model": "gemini-flash" + } + } +} +``` + +## Authentication + +IDE integrations typically use OAuth authentication instead of API keys: + +```bash +# Authenticate with Antigravity +picoclaw auth login --provider antigravity + +# List available models +picoclaw auth models +``` + +## Related Documentation + +- [Provider Configuration](../providers/README.md) +- [Model List Configuration](../advanced/model-fallbacks.md) +- [CLI Reference](../cli-reference.md) diff --git a/docs/user-guide/ide-setup/antigravity.md b/docs/user-guide/ide-setup/antigravity.md new file mode 100644 index 0000000000..47d5266e13 --- /dev/null +++ b/docs/user-guide/ide-setup/antigravity.md @@ -0,0 +1,275 @@ +# Antigravity Setup (Google Cloud Code Assist) + +**Antigravity** (Google Cloud Code Assist) is a Google-backed AI model provider that offers free access to models like Claude Opus 4.6 and Gemini through Google's Cloud infrastructure. + +## Key Features + +- **Free Tier**: Generous quotas for development use +- **Multiple Models**: Access to Claude Opus, Gemini Flash, and more +- **OAuth Authentication**: No API key management required +- **Usage Tracking**: Monitor your quota consumption + +## Prerequisites + +1. A Google account +2. Google Cloud Code Assist enabled (usually available via "Gemini for Google Cloud" onboarding) + +## Quick Start + +### 1. Authenticate + +```bash +picoclaw auth login --provider antigravity +``` + +This will: +1. Open your browser for Google OAuth login +2. Request necessary permissions +3. Store credentials in `~/.picoclaw/auth.json` + +### 2. List Available Models + +```bash +picoclaw auth models +``` + +This shows which models your project has access to and their current quotas. + +### 3. Configure PicoClaw + +Add to `~/.picoclaw/config.json`: + +```json +{ + "model_list": [ + { + "model_name": "gemini-flash", + "model": "antigravity/gemini-3-flash", + "auth_method": "oauth" + } + ], + "agents": { + "defaults": { + "model": "gemini-flash" + } + } +} +``` + +### 4. Start Chatting + +```bash +picoclaw agent -m "Hello, how can you help me today?" +``` + +## Authentication Methods + +### Automatic Flow (Local Machine) + +On a local machine with a browser: + +```bash +picoclaw auth login --provider antigravity +``` + +The browser opens automatically and authentication completes without additional steps. + +### Manual Flow (Headless/VPS/Docker) + +On a server without browser access: + +1. Run the auth command: + ```bash + picoclaw auth login --provider antigravity + ``` + +2. Copy the URL displayed and open it in your local browser + +3. Complete the Google login + +4. Your browser will redirect to a `localhost:51121` URL (which will fail to load) + +5. **Copy that final URL** from your browser's address bar + +6. **Paste it back into the terminal** where PicoClaw is waiting + +PicoClaw will extract the authorization code and complete the process automatically. + +### Copy Credentials to Server + +If you've authenticated locally, you can copy credentials to a server: + +```bash +scp ~/.picoclaw/auth.json user@your-server:~/.picoclaw/ +``` + +## Available Models + +Based on testing, these models are most reliable: + +| Model | Description | Quota | +|-------|-------------|-------| +| `gemini-3-flash` | Fast, highly available | High | +| `gemini-2.5-flash-lite` | Lightweight option | High | +| `claude-opus-4-6-thinking` | Powerful, includes reasoning | Limited | + +Use `picoclaw auth models` to see your actual available models and quotas. + +## Switching Models + +### Via Config File + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-6-thinking" + } + } +} +``` + +### Via CLI Override + +```bash +picoclaw agent -m "Hello" --model claude-opus-4-6-thinking +``` + +### Via Environment Variable + +```bash +export PICOCLAW_AGENTS_DEFAULTS_MODEL=gemini-3-flash +picoclaw agent -m "Hello" +``` + +## Docker/Coolify Deployment + +For containerized deployments: + +### Environment Variables + +```bash +PICOCLAW_AGENTS_DEFAULTS_MODEL=gemini-flash +``` + +### Volume Mount for Auth + +```yaml +# docker-compose.yml +services: + picoclaw: + volumes: + - ~/.picoclaw/auth.json:/root/.picoclaw/auth.json:ro +``` + +### Pre-authenticated Setup + +1. Authenticate locally first +2. Copy `auth.json` to the server +3. Mount or copy into container + +## Troubleshooting + +### Empty Response + +If a model returns an empty reply: +- The model may be restricted for your project +- Try `gemini-3-flash` or `claude-opus-4-6-thinking` +- Check quotas with `picoclaw auth models` + +### 429 Rate Limit + +Antigravity has strict quotas. When you hit a limit: +- PicoClaw displays the "reset time" in the error message +- Wait for the quota to reset +- Consider using a different model temporarily + +### 404 Not Found + +- Ensure you're using a model ID from `picoclaw auth models` +- Use the short ID (e.g., `gemini-3-flash`), not the full path + +### Token Expired + +Refresh your OAuth tokens: + +```bash +picoclaw auth login --provider antigravity +``` + +### Gemini for Google Cloud Not Enabled + +Enable the API in your [Google Cloud Console](https://console.cloud.google.com). + +### Models Not Appearing + +1. Verify OAuth completed successfully +2. Check `~/.picoclaw/auth.json` for stored credentials +3. Re-run `picoclaw auth login --provider antigravity` + +## Quota Management + +### Check Quotas + +```bash +picoclaw auth models +``` + +This shows: +- Available models +- Remaining quota percentage +- Reset time for exhausted quotas + +### Quota Best Practices + +1. **Use lighter models for simple tasks**: `gemini-3-flash` for quick queries +2. **Reserve Claude for complex tasks**: Use `claude-opus-4-6-thinking` for reasoning +3. **Monitor usage**: Check quotas regularly +4. **Have fallbacks**: Configure multiple models in `model_list` + +## Technical Details + +### OAuth Scopes + +Antigravity requires these Google OAuth scopes: +- `cloud-platform` - Google Cloud access +- `userinfo.email` - User identification +- `userinfo.profile` - Profile information +- `cclog` - Cloud Code logging +- `experimentsandconfigs` - Feature flags + +### Credential Storage + +Credentials are stored in `~/.picoclaw/auth.json`: + +```json +{ + "credentials": { + "google-antigravity": { + "access_token": "ya29...", + "refresh_token": "1//...", + "expires_at": "2026-01-01T00:00:00Z", + "provider": "google-antigravity", + "auth_method": "oauth", + "email": "user@example.com", + "project_id": "my-project-id" + } + } +} +``` + +### Token Refresh + +Access tokens expire and are automatically refreshed using the refresh token. The refresh happens transparently when making API calls. + +## Related Documentation + +- [Provider Configuration](../providers/README.md) +- [Model Fallbacks](../advanced/model-fallbacks.md) +- [CLI Auth Commands](../cli/auth.md) + +## Advanced: Provider Implementation + +For developers extending PicoClaw, see [Antigravity Auth Implementation](../../developer-guide/extending/antigravity-implementation.md) for technical details on the OAuth flow and API integration. diff --git a/docs/user-guide/providers/README.md b/docs/user-guide/providers/README.md new file mode 100644 index 0000000000..03f0881cea --- /dev/null +++ b/docs/user-guide/providers/README.md @@ -0,0 +1,151 @@ +# Providers Overview + +PicoClaw supports multiple LLM providers. This guide helps you choose and configure the right provider. + +## Quick Comparison + +| Provider | Free Tier | Best For | Auth Method | +|----------|-----------|----------|-------------| +| [OpenRouter](openrouter.md) | 200K tokens/mo | Multi-model access | API Key | +| [Zhipu](zhipu.md) | 200K tokens/mo | Chinese users | API Key | +| [Anthropic](anthropic.md) | Varies | Claude models | API Key, OAuth | +| [OpenAI](openai.md) | Varies | GPT models | API Key, OAuth | +| [Gemini](gemini.md) | Yes | Google models | API Key | +| [Groq](groq.md) | Yes | Fast inference | API Key | +| [DeepSeek](deepseek.md) | Yes | Reasoning | API Key | +| [Ollama](ollama.md) | Free | Local models | None | +| [vLLM](vllm.md) | Free | Self-hosted | API Key | + +## Recommended Providers + +### For Most Users: OpenRouter + +OpenRouter provides access to many models (Claude, GPT, Llama, etc.) with a single API key. + +```json +{ + "agents": { "defaults": { "model": "anthropic/claude-opus-4-5" } }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + } +} +``` + +### For Chinese Users: Zhipu + +Zhipu offers Chinese-optimized models with good free tier. + +```json +{ + "agents": { "defaults": { "model": "glm-4.7" } }, + "providers": { + "zhipu": { + "api_key": "your-zhipu-key" + } + } +} +``` + +### For Local/Offline: Ollama + +Run models locally without internet. + +```json +{ + "agents": { "defaults": { "model": "llama3.2" } }, + "providers": { + "ollama": { + "api_base": "http://localhost:11434/v1" + } + } +} +``` + +## Provider Selection + +PicoClaw selects providers in this order: + +1. **Explicit provider** in config: + ```json + "provider": "openrouter" + ``` + +2. **Model prefix**: + ```json + "model": "openrouter/anthropic/claude-opus-4-5" + ``` + +3. **First API key found** (default behavior) + +## Model Fallbacks + +Configure automatic fallback if primary model fails: + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-5", + "model_fallbacks": ["gpt-4o", "glm-4.7"] + } + } +} +``` + +## Authentication Methods + +### API Key (Recommended) + +Simplest method - add your key to config: + +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + } +} +``` + +### Environment Variable + +Override config with environment variables: + +```bash +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" +``` + +### OAuth + +For OpenAI and Anthropic, use OAuth login: + +```bash +picoclaw auth login --provider openai +``` + +## Getting API Keys + +| Provider | Get API Key | +|----------|-------------| +| OpenRouter | [openrouter.ai/keys](https://openrouter.ai/keys) | +| Zhipu | [bigmodel.cn](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) | +| Anthropic | [console.anthropic.com](https://console.anthropic.com) | +| OpenAI | [platform.openai.com](https://platform.openai.com) | +| Gemini | [aistudio.google.com](https://aistudio.google.com) | +| Groq | [console.groq.com](https://console.groq.com) | +| DeepSeek | [platform.deepseek.com](https://platform.deepseek.com) | + +## Provider-Specific Guides + +- [OpenRouter](openrouter.md) - Multi-model access +- [Zhipu](zhipu.md) - Chinese AI models +- [Anthropic](anthropic.md) - Claude models +- [OpenAI](openai.md) - GPT models +- [Gemini](gemini.md) - Google Gemini +- [Groq](groq.md) - Fast inference + voice +- [DeepSeek](deepseek.md) - DeepSeek models +- [Ollama](ollama.md) - Local models +- [vLLM](vllm.md) - Self-hosted models diff --git a/docs/user-guide/providers/anthropic.md b/docs/user-guide/providers/anthropic.md new file mode 100644 index 0000000000..8c7a89202c --- /dev/null +++ b/docs/user-guide/providers/anthropic.md @@ -0,0 +1,237 @@ +# Anthropic Provider + +Use Anthropic's Claude models directly through their API. + +## Why Anthropic? + +- **Direct access**: No middleman, direct API access +- **Latest models**: Immediate access to newest Claude versions +- **Native features**: Full feature support +- **OAuth support**: Secure authentication + +## Setup + +### Step 1: Get API Key + +1. Go to [console.anthropic.com](https://console.anthropic.com) +2. Sign in or create an account +3. Navigate to API Keys +4. Create a new API key +5. Copy the key (starts with `sk-ant-`) + +### Step 2: Configure + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-5" + } + }, + "providers": { + "anthropic": { + "api_key": "sk-ant-YOUR-API-KEY", + "api_base": "https://api.anthropic.com" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_key` | Yes* | - | Your Anthropic API key | +| `api_base` | No | `https://api.anthropic.com` | API endpoint | + +*Required unless using OAuth + +## Available Models + +| Model | Model Name | Best For | +|-------|------------|----------| +| Claude Opus 4.5 | `claude-opus-4-5` | Most capable, complex tasks | +| Claude Opus 4 | `claude-opus-4-20250514` | High-intelligence tasks | +| Claude Sonnet 4 | `claude-sonnet-4-20250514` | Fast + capable | +| Claude Sonnet 3.7 | `claude-3-7-sonnet-20250219` | Balanced performance | +| Claude Sonnet 3.5 | `claude-3-5-sonnet-20241022` | Fast, efficient | + +## OAuth Authentication + +For secure authentication without storing API keys: + +```bash +# Login with OAuth +picoclaw auth login --provider anthropic + +# Use device code flow (for headless environments) +picoclaw auth login --provider anthropic --device-code +``` + +After OAuth login, you don't need to store the API key in config. + +## Model Format + +Use the model name directly (no provider prefix needed): + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-5" + } + } +} +``` + +Or with provider prefix: + +```json +{ + "agents": { + "defaults": { + "model": "anthropic/claude-opus-4-5" + } + } +} +``` + +## Fallback Configuration + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-5", + "model_fallbacks": [ + "claude-sonnet-4-20250514", + "claude-3-5-sonnet-20241022" + ] + } + } +} +``` + +## Environment Variable + +```bash +export PICOCLAW_PROVIDERS_ANTHROPIC_API_KEY="sk-ant-xxx" +``` + +## Pricing + +Check [anthropic.com/pricing](https://www.anthropic.com/pricing) for current pricing. + +Claude models are typically: +- Opus: Highest cost, best capability +- Sonnet: Mid-range cost, good balance +- Haiku: Lowest cost, fastest + +## Rate Limits + +Anthropic applies rate limits based on your tier: + +| Tier | Requests per Minute | Tokens per Minute | +|------|---------------------|-------------------| +| Free | Varies | Varies | +| Tier 1 | 50 | 100,000 | +| Tier 2 | 100 | 200,000 | +| Higher | Custom | Custom | + +Handle rate limits with fallbacks: + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-5", + "model_fallbacks": ["claude-sonnet-4-20250514"] + } + } +} +``` + +## Usage Examples + +```bash +# Use default model +picoclaw agent -m "Hello!" + +# Specify model +picoclaw agent -m "Hello!" # Uses config model +``` + +## Features + +### Extended Thinking + +Claude models support extended thinking for complex reasoning: + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-5", + "thinking": { + "enabled": true, + "budget_tokens": 10000 + } + } + } +} +``` + +### Vision + +Claude can analyze images (when supported by the channel): + +```json +{ + "agents": { + "defaults": { + "model": "claude-opus-4-5", + "vision": true + } + } +} +``` + +## Troubleshooting + +### Invalid API Key + +``` +Error: invalid_api_key +``` + +Verify your API key: +1. Check key starts with `sk-ant-` +2. Ensure key is active in console +3. Check for typos + +### Rate Limited + +``` +Error: rate_limit_exceeded +``` + +Solutions: +1. Wait and retry +2. Set up fallback models +3. Upgrade your tier + +### Model Not Found + +``` +Error: model_not_found +``` + +Check model name is correct. Use exact model IDs from the Anthropic documentation. + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) +- [Model Fallbacks](../advanced/model-fallbacks.md) diff --git a/docs/user-guide/providers/deepseek.md b/docs/user-guide/providers/deepseek.md new file mode 100644 index 0000000000..6aceb7b893 --- /dev/null +++ b/docs/user-guide/providers/deepseek.md @@ -0,0 +1,234 @@ +# DeepSeek Provider + +Use DeepSeek's models for reasoning and general tasks. + +## Why DeepSeek? + +- **Strong reasoning**: Excellent at complex reasoning tasks +- **Cost-effective**: Competitive pricing +- **Long context**: Up to 64K context +- **Code generation**: Strong coding capabilities + +## Setup + +### Step 1: Get API Key + +1. Go to [platform.deepseek.com](https://platform.deepseek.com) +2. Sign in or create an account +3. Navigate to API Keys +4. Create a new API key +5. Copy the key (starts with `sk-`) + +### Step 2: Configure + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "deepseek-chat" + } + }, + "providers": { + "deepseek": { + "api_key": "sk-YOUR-API-KEY", + "api_base": "https://api.deepseek.com" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_key` | Yes | - | Your DeepSeek API key | +| `api_base` | No | `https://api.deepseek.com` | API endpoint | + +## Available Models + +| Model | Model Name | Best For | +|-------|------------|----------| +| DeepSeek Chat | `deepseek-chat` | General conversation | +| DeepSeek Reasoner | `deepseek-reasoner` | Complex reasoning | + +### Model Comparison + +| Feature | deepseek-chat | deepseek-reasoner | +|---------|---------------|-------------------| +| Context | 64K | 64K | +| Best for | General tasks | Complex reasoning | +| Speed | Fast | Slower (thinks more) | + +## Model Format + +Use the model name directly: + +```json +{ + "agents": { + "defaults": { + "model": "deepseek-chat" + } + } +} +``` + +Or with provider prefix: + +```json +{ + "agents": { + "defaults": { + "model": "deepseek/deepseek-chat" + } + } +} +``` + +## Fallback Configuration + +```json +{ + "agents": { + "defaults": { + "model": "deepseek-reasoner", + "model_fallbacks": [ + "deepseek-chat" + ] + } + } +} +``` + +## Environment Variable + +```bash +export PICOCLAW_PROVIDERS_DEEPSEEK_API_KEY="sk-xxx" +``` + +## Pricing + +Check [platform.deepseek.com/pricing](https://platform.deepseek.com/pricing) for current pricing. + +Approximate costs (per 1M tokens): + +| Model | Input | Output | +|-------|-------|--------| +| deepseek-chat | $0.14 | $0.28 | +| deepseek-reasoner | $0.55 | $2.19 | + +## Usage Examples + +```bash +# General chat +picoclaw agent -m "Hello!" + +# Complex reasoning (with reasoner model) +picoclaw agent -m "Solve this step by step: What is 15% of 847?" +``` + +## DeepSeek Reasoner + +The `deepseek-reasoner` model is optimized for complex reasoning: + +- Shows thinking process +- Better at math and logic +- Good for analysis tasks + +### When to Use Reasoner + +- Mathematical problems +- Logical reasoning +- Multi-step analysis +- Complex decision making + +### Example + +``` +User: If I have 5 apples and give away 2, then buy 3 more, how many do I have? + +Agent (using reasoner): +Let me work through this step by step: +1. Start with 5 apples +2. Give away 2: 5 - 2 = 3 apples +3. Buy 3 more: 3 + 3 = 6 apples + +You have 6 apples. +``` + +## Troubleshooting + +### Invalid API Key + +``` +Error: Authentication Error +``` + +Verify your API key: +1. Check key is correctly copied +2. Ensure key is active in platform +3. Check for typos + +### Rate Limited + +``` +Error: Rate limit exceeded +``` + +Solutions: +1. Wait and retry +2. Set up fallback models +3. Check your usage limits + +### Insufficient Balance + +``` +Error: Insufficient balance +``` + +Add funds to your DeepSeek account at [platform.deepseek.com](https://platform.deepseek.com). + +### Context Length Exceeded + +``` +Error: context_length_exceeded +``` + +Solutions: +1. Reduce message length +2. Clear session history +3. Start a new session + +## Best Practices + +1. **Use chat for general tasks** - Faster and more efficient +2. **Use reasoner for complex problems** - Better reasoning capability +3. **Set up fallbacks** - For reliability +4. **Monitor usage** - Track token consumption + +## Using via OpenRouter + +Alternatively, access DeepSeek through OpenRouter: + +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + }, + "agents": { + "defaults": { + "model": "deepseek/deepseek-chat" + } + } +} +``` + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) +- [Model Fallbacks](../advanced/model-fallbacks.md) diff --git a/docs/user-guide/providers/gemini.md b/docs/user-guide/providers/gemini.md new file mode 100644 index 0000000000..67478c5c9f --- /dev/null +++ b/docs/user-guide/providers/gemini.md @@ -0,0 +1,260 @@ +# Gemini Provider + +Use Google's Gemini models through the Gemini API. + +## Why Gemini? + +- **Free tier**: Generous free tier for development +- **Large context**: Up to 1M tokens context window +- **Multimodal**: Native support for text, images, audio, video +- **Fast**: Quick response times + +## Setup + +### Step 1: Get API Key + +1. Go to [aistudio.google.com](https://aistudio.google.com) +2. Sign in with your Google account +3. Click "Get API Key" +4. Create a new API key +5. Copy the key + +### Step 2: Configure + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "gemini-2.0-flash" + } + }, + "providers": { + "gemini": { + "api_key": "YOUR-API-KEY", + "api_base": "https://generativelanguage.googleapis.com/v1beta" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_key` | Yes | - | Your Gemini API key | +| `api_base` | No | `https://generativelanguage.googleapis.com/v1beta` | API endpoint | + +## Available Models + +| Model | Model Name | Best For | +|-------|------------|----------| +| Gemini 2.0 Flash | `gemini-2.0-flash` | Fast, efficient | +| Gemini 2.0 Pro | `gemini-2.0-pro-exp` | Experimental, advanced | +| Gemini 1.5 Pro | `gemini-1.5-pro` | Large context, complex tasks | +| Gemini 1.5 Flash | `gemini-1.5-flash` | Fast, cost-effective | +| Gemini 1.5 Flash-8B | `gemini-1.5-flash-8b` | Smallest, fastest | + +## Model Capabilities + +| Model | Context | Multimodal | Best Use | +|-------|---------|------------|----------| +| Gemini 2.0 Flash | 1M tokens | Yes | General use | +| Gemini 1.5 Pro | 2M tokens | Yes | Long documents | +| Gemini 1.5 Flash | 1M tokens | Yes | Fast responses | + +## Model Format + +Use the model name directly: + +```json +{ + "agents": { + "defaults": { + "model": "gemini-2.0-flash" + } + } +} +``` + +Or with provider prefix: + +```json +{ + "agents": { + "defaults": { + "model": "gemini/gemini-2.0-flash" + } + } +} +``` + +## Fallback Configuration + +```json +{ + "agents": { + "defaults": { + "model": "gemini-2.0-flash", + "model_fallbacks": [ + "gemini-1.5-flash", + "gemini-1.5-flash-8b" + ] + } + } +} +``` + +## Environment Variable + +```bash +export PICOCLAW_PROVIDERS_GEMINI_API_KEY="your-api-key" +``` + +## Pricing + +Check [ai.google.dev/pricing](https://ai.google.dev/pricing) for current pricing. + +### Free Tier + +| Model | Requests per Day | Tokens per Minute | +|-------|------------------|-------------------| +| Gemini 2.0 Flash | 1,500 | 1M | +| Gemini 1.5 Flash | 1,500 | 1M | +| Gemini 1.5 Pro | 50 | 32K | + +### Paid Tier + +Higher limits available with billing enabled. + +## Usage Examples + +```bash +# Use default model +picoclaw agent -m "Hello!" + +# Gemini handles long contexts well +picoclaw agent -m "Summarize this 100-page document..." +``` + +## Special Features + +### Large Context Window + +Gemini supports up to 2M token context, ideal for: + +- Long document analysis +- Multi-document summarization +- Extended conversation history +- Large codebase analysis + +### Multimodal Input + +Gemini can process: + +- Text +- Images +- Audio +- Video + +Configure for vision: + +```json +{ + "agents": { + "defaults": { + "model": "gemini-2.0-flash", + "vision": true + } + } +} +``` + +### Safety Settings + +Configure content filtering: + +```json +{ + "providers": { + "gemini": { + "api_key": "your-key", + "safety_settings": { + "harassment": "BLOCK_MEDIUM_AND_ABOVE", + "hate_speech": "BLOCK_MEDIUM_AND_ABOVE", + "sexually_explicit": "BLOCK_MEDIUM_AND_ABOVE", + "dangerous_content": "BLOCK_MEDIUM_AND_ABOVE" + } + } + } +} +``` + +## Troubleshooting + +### Invalid API Key + +``` +Error: API key not valid +``` + +Verify your API key: +1. Check key is correctly copied +2. Ensure key is active in AI Studio +3. Try regenerating the key + +### Resource Exhausted + +``` +Error: RESOURCE_EXHAUSTED +``` + +Solutions: +1. Wait and retry (rate limit) +2. Check daily quota +3. Enable billing for higher limits + +### Content Filtered + +``` +Error: content was blocked +``` + +Solutions: +1. Adjust safety settings +2. Rephrase your prompt +3. Use a different model + +### Context Too Long + +Even with large context, you may hit limits: + +1. Reduce context size +2. Use document summarization +3. Split into multiple requests + +## Using via OpenRouter + +Alternatively, access Gemini through OpenRouter: + +```json +{ + "providers": { + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + }, + "agents": { + "defaults": { + "model": "google/gemini-2.0-flash-001" + } + } +} +``` + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) +- [Model Fallbacks](../advanced/model-fallbacks.md) diff --git a/docs/user-guide/providers/groq.md b/docs/user-guide/providers/groq.md new file mode 100644 index 0000000000..700912a301 --- /dev/null +++ b/docs/user-guide/providers/groq.md @@ -0,0 +1,270 @@ +# Groq Provider + +Use Groq's ultra-fast inference for LLMs and voice transcription. + +## Why Groq? + +- **Extremely fast**: Sub-second response times +- **Free tier**: Generous free tier available +- **Voice transcription**: Whisper-large-v3 for audio +- **Open models**: Llama, Mixtral, and more + +## Setup + +### Step 1: Get API Key + +1. Go to [console.groq.com](https://console.groq.com) +2. Sign in or create an account +3. Navigate to API Keys +4. Create a new API key +5. Copy the key (starts with `gsk_`) + +### Step 2: Configure + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "llama-3.3-70b-versatile" + } + }, + "providers": { + "groq": { + "api_key": "gsk_YOUR-API-KEY", + "api_base": "https://api.groq.com/openai/v1" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_key` | Yes | - | Your Groq API key | +| `api_base` | No | `https://api.groq.com/openai/v1` | API endpoint | + +## Available Models + +### Chat Models + +| Model | Model Name | Best For | +|-------|------------|----------| +| Llama 3.3 70B | `llama-3.3-70b-versatile` | General use, balanced | +| Llama 3.3 70B Specdec | `llama-3.3-70b-specdec` | Speculative decoding, faster | +| Llama 3.1 8B | `llama-3.1-8b-instant` | Fast, simple tasks | +| Mixtral 8x7B | `mixtral-8x7b-32768` | Multilingual, 32K context | +| Gemma 2 9B | `gemma2-9b-it` | Lightweight, efficient | + +### Audio Models + +| Model | Model Name | Use | +|-------|------------|-----| +| Whisper Large v3 | `whisper-large-v3` | Audio transcription | +| Whisper Large v3 Turbo | `whisper-large-v3-turbo` | Faster transcription | + +## Model Format + +Use the model name directly: + +```json +{ + "agents": { + "defaults": { + "model": "llama-3.3-70b-versatile" + } + } +} +``` + +Or with provider prefix: + +```json +{ + "agents": { + "defaults": { + "model": "groq/llama-3.3-70b-versatile" + } + } +} +``` + +## Fallback Configuration + +```json +{ + "agents": { + "defaults": { + "model": "llama-3.3-70b-versatile", + "model_fallbacks": [ + "llama-3.1-8b-instant", + "mixtral-8x7b-32768" + ] + } + } +} +``` + +## Environment Variable + +```bash +export PICOCLAW_PROVIDERS_GROQ_API_KEY="gsk_xxx" +``` + +## Pricing + +Groq offers a generous free tier. + +### Free Tier + +| Resource | Limit | +|----------|-------| +| Requests per minute | 30 | +| Tokens per minute | 18,000 | +| Requests per day | 14,400 | + +### Paid Tier + +Higher limits available with paid plans. Check [groq.com/pricing](https://groq.com/pricing) for details. + +## Voice Transcription + +Groq provides ultra-fast Whisper transcription. + +### Enable Voice Transcription + +```json +{ + "providers": { + "groq": { + "api_key": "gsk_xxx" + } + }, + "agents": { + "defaults": { + "voice_transcription": { + "enabled": true, + "provider": "groq", + "model": "whisper-large-v3" + } + } + } +} +``` + +### Supported Formats + +- MP3 +- MP4 +- MPEG +- MPGA +- M4A +- WAV +- WebM + +### Use with Telegram + +Voice messages in Telegram will be automatically transcribed: + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "your-bot-token" + } + }, + "agents": { + "defaults": { + "voice_transcription": { + "enabled": true, + "provider": "groq" + } + } + } +} +``` + +## Usage Examples + +```bash +# Use default model +picoclaw agent -m "Hello!" + +# Groq is extremely fast +picoclaw agent -m "Write a quick summary of..." +``` + +## Performance + +Groq uses custom LPU (Language Processing Unit) hardware: + +| Model | Typical Latency | +|-------|-----------------| +| Llama 3.3 70B | < 500ms | +| Llama 3.1 8B | < 200ms | +| Whisper Large | Real-time | + +## Troubleshooting + +### Invalid API Key + +``` +Error: invalid_api_key +``` + +Verify your API key: +1. Check key starts with `gsk_` +2. Ensure key is active +3. Check for typos + +### Rate Limited + +``` +Error: rate_limit_exceeded +``` + +Solutions: +1. Wait and retry +2. Set up fallback models +3. Upgrade to paid tier + +### Model Not Available + +``` +Error: model_not_found +``` + +Check available models at [console.groq.com/models](https://console.groq.com/models) + +### Audio File Too Large + +``` +Error: file_too_large +``` + +Audio file limits: +- Maximum file size: 25MB +- Maximum duration: ~30 minutes + +## Best Practices + +### For Chat + +1. Use `llama-3.3-70b-versatile` for best quality +2. Use `llama-3.1-8b-instant` for simple, fast tasks +3. Set up fallbacks for reliability + +### For Voice + +1. Use `whisper-large-v3-turbo` for faster transcription +2. Use `whisper-large-v3` for better accuracy +3. Ensure audio is clear for best results + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) +- [Voice Transcription](../advanced/voice-transcription.md) diff --git a/docs/user-guide/providers/ollama.md b/docs/user-guide/providers/ollama.md new file mode 100644 index 0000000000..353c08dac2 --- /dev/null +++ b/docs/user-guide/providers/ollama.md @@ -0,0 +1,341 @@ +# Ollama Provider + +Run LLMs locally using Ollama for offline, private, and cost-free inference. + +## Why Ollama? + +- **Free**: No API costs +- **Private**: Data stays on your machine +- **Offline**: Works without internet +- **Flexible**: Run many open-source models + +## Prerequisites + +- Sufficient RAM (8GB+ recommended for larger models) +- Sufficient disk space (models are 2-10GB+) +- Linux, macOS, or Windows (with WSL2) + +## Setup + +### Step 1: Install Ollama + +**Linux/macOS:** + +```bash +curl -fsSL https://ollama.com/install.sh | sh +``` + +**Or download from [ollama.com](https://ollama.com)** + +### Step 2: Pull a Model + +```bash +# Pull a model (example: Llama 3.2) +ollama pull llama3.2 + +# List available models +ollama list +``` + +### Step 3: Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "llama3.2" + } + }, + "providers": { + "ollama": { + "api_base": "http://localhost:11434/v1" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_base` | No | `http://localhost:11434/v1` | Ollama API endpoint | + +No API key needed - Ollama runs locally. + +## Popular Models + +| Model | Command | Size | Best For | +|-------|---------|------|----------| +| Llama 3.2 3B | `ollama pull llama3.2` | 2GB | General use | +| Llama 3.2 1B | `ollama pull llama3.2:1b` | 1GB | Fast, lightweight | +| Llama 3.1 8B | `ollama pull llama3.1` | 5GB | Better quality | +| Llama 3.1 70B | `ollama pull llama3.1:70b` | 40GB | Best quality | +| Mistral | `ollama pull mistral` | 4GB | Efficient | +| CodeLlama | `ollama pull codellama` | 4GB | Code generation | +| Phi-3 | `ollama pull phi3` | 2GB | Microsoft's small model | +| Gemma 2 | `ollama pull gemma2` | 5GB | Google's open model | +| Qwen 2.5 | `ollama pull qwen2.5` | 5GB | Multilingual | + +## Model Management + +### Pull Models + +```bash +# Pull latest version +ollama pull llama3.2 + +# Pull specific version +ollama pull llama3.2:3b +``` + +### List Models + +```bash +ollama list +``` + +Output: + +``` +NAME ID SIZE MODIFIED +llama3.2:latest 123abc... 2.0 GB 2 hours ago +mistral:latest 456def... 4.1 GB 3 days ago +``` + +### Remove Models + +```bash +ollama rm old-model +``` + +### Update Models + +```bash +ollama pull llama3.2 +``` + +## Model Format + +Use the model name as shown in `ollama list`: + +```json +{ + "agents": { + "defaults": { + "model": "llama3.2" + } + } +} +``` + +Or with provider prefix: + +```json +{ + "agents": { + "defaults": { + "model": "ollama/llama3.2" + } + } +} +``` + +## Fallback Configuration + +Combine local and cloud models: + +```json +{ + "agents": { + "defaults": { + "model": "llama3.2", + "model_fallbacks": [ + "openrouter/anthropic/claude-sonnet-4" + ] + } + }, + "providers": { + "ollama": { + "api_base": "http://localhost:11434/v1" + }, + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + } +} +``` + +## Remote Ollama + +Connect to Ollama running on another machine: + +```json +{ + "providers": { + "ollama": { + "api_base": "http://192.168.1.100:11434/v1" + } + } +} +``` + +### Start Ollama with Network Access + +```bash +# Set host to listen on all interfaces +OLLAMA_HOST=0.0.0.0 ollama serve +``` + +## Resource Requirements + +### RAM Guidelines + +| Model Size | Minimum RAM | Recommended RAM | +|------------|-------------|-----------------| +| 1B parameters | 4GB | 8GB | +| 3B parameters | 6GB | 12GB | +| 7-8B parameters | 8GB | 16GB | +| 13B parameters | 16GB | 32GB | +| 70B parameters | 48GB | 64GB+ | + +### GPU Acceleration + +Ollama automatically uses GPU when available: + +- **NVIDIA**: CUDA support (requires nvidia drivers) +- **AMD**: ROCm support +- **Apple Silicon**: Metal support (M1/M2/M3) + +Check GPU usage: + +```bash +# NVIDIA +nvidia-smi + +# Or during inference +ollama run llama3.2 +``` + +## Custom Models + +### Create a Modelfile + +```dockerfile +FROM llama3.2 + +# Set parameters +PARAMETER temperature 0.7 +PARAMETER num_ctx 4096 + +# Set system prompt +SYSTEM You are a helpful coding assistant. +``` + +### Build Custom Model + +```bash +ollama create my-coder -f Modelfile +``` + +### Use Custom Model + +```json +{ + "agents": { + "defaults": { + "model": "my-coder" + } + } +} +``` + +## Troubleshooting + +### Ollama Not Running + +``` +Error: connection refused +``` + +Start Ollama: + +```bash +ollama serve +``` + +Or run interactively: + +```bash +ollama run llama3.2 +``` + +### Model Not Found + +``` +Error: model 'xxx' not found +``` + +Pull the model first: + +```bash +ollama pull xxx +``` + +### Out of Memory + +``` +Error: out of memory +``` + +Solutions: +1. Use a smaller model +2. Close other applications +3. Reduce context length + +### Slow Responses + +Solutions: +1. Use a smaller model +2. Ensure GPU acceleration +3. Check system resources + +### Port Already in Use + +``` +Error: address already in use +``` + +Change Ollama port: + +```bash +OLLAMA_HOST=0.0.0.0:11435 ollama serve +``` + +Update PicoClaw config: + +```json +{ + "providers": { + "ollama": { + "api_base": "http://localhost:11435/v1" + } + } +} +``` + +## Best Practices + +1. **Start with small models** - Test with 1B-3B models first +2. **Monitor resources** - Watch RAM and GPU usage +3. **Use quantized models** - Default models are already optimized +4. **Combine with cloud** - Use fallbacks for reliability +5. **Keep models updated** - `ollama pull` to update + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) +- [Model Fallbacks](../advanced/model-fallbacks.md) +- [Ollama Documentation](https://github.com/ollama/ollama) diff --git a/docs/user-guide/providers/openai.md b/docs/user-guide/providers/openai.md new file mode 100644 index 0000000000..f549e0d41e --- /dev/null +++ b/docs/user-guide/providers/openai.md @@ -0,0 +1,268 @@ +# OpenAI Provider + +Use OpenAI's GPT models directly through their API. + +## Why OpenAI? + +- **GPT models**: Access to GPT-4, GPT-4o, and GPT-3.5 +- **DALL-E**: Image generation capabilities +- **Whisper**: Audio transcription +- **Native features**: Full OpenAI API support + +## Setup + +### Step 1: Get API Key + +1. Go to [platform.openai.com](https://platform.openai.com) +2. Sign in or create an account +3. Navigate to API Keys +4. Create a new secret key +5. Copy the key (starts with `sk-`) + +### Step 2: Configure + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "gpt-4o" + } + }, + "providers": { + "openai": { + "api_key": "sk-YOUR-API-KEY", + "api_base": "https://api.openai.com/v1" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_key` | Yes* | - | Your OpenAI API key | +| `api_base` | No | `https://api.openai.com/v1` | API endpoint | +| `organization` | No | - | Organization ID | + +*Required unless using OAuth + +## Available Models + +### Chat Models + +| Model | Model Name | Best For | +|-------|------------|----------| +| GPT-4o | `gpt-4o` | Latest flagship, multimodal | +| GPT-4o Mini | `gpt-4o-mini` | Fast, cost-effective | +| GPT-4 Turbo | `gpt-4-turbo` | Previous generation flagship | +| GPT-4 | `gpt-4` | Standard GPT-4 | +| GPT-3.5 Turbo | `gpt-3.5-turbo` | Fast, affordable | + +### Reasoning Models + +| Model | Model Name | Best For | +|-------|------------|----------| +| o1 | `o1` | Complex reasoning | +| o1-mini | `o1-mini` | Fast reasoning tasks | +| o1-preview | `o1-preview` | Preview reasoning model | + +## OAuth Authentication + +For secure authentication without storing API keys: + +```bash +# Login with OAuth +picoclaw auth login --provider openai + +# Use device code flow (for headless environments) +picoclaw auth login --provider openai --device-code +``` + +## Model Format + +Use the model name directly: + +```json +{ + "agents": { + "defaults": { + "model": "gpt-4o" + } + } +} +``` + +Or with provider prefix: + +```json +{ + "agents": { + "defaults": { + "model": "openai/gpt-4o" + } + } +} +``` + +## Fallback Configuration + +```json +{ + "agents": { + "defaults": { + "model": "gpt-4o", + "model_fallbacks": [ + "gpt-4o-mini", + "gpt-3.5-turbo" + ] + } + } +} +``` + +## Environment Variable + +```bash +export PICOCLAW_PROVIDERS_OPENAI_API_KEY="sk-xxx" +``` + +## Pricing + +Check [openai.com/pricing](https://openai.com/pricing) for current pricing. + +Approximate costs (per 1M tokens): + +| Model | Input | Output | +|-------|-------|--------| +| GPT-4o | $2.50 | $10.00 | +| GPT-4o Mini | $0.15 | $0.60 | +| GPT-4 Turbo | $10.00 | $30.00 | +| GPT-3.5 Turbo | $0.50 | $1.50 | + +## Rate Limits + +OpenAI applies rate limits: + +| Tier | Requests per Minute | Tokens per Minute | +|------|---------------------|-------------------| +| Free | 3 | 40,000 | +| Tier 1 | 500 | 200,000 | +| Tier 2 | 5,000 | 2,000,000 | + +## Usage Examples + +```bash +# Use default model +picoclaw agent -m "Hello!" + +# With specific model in config +picoclaw agent -m "Explain quantum computing" +``` + +## Special Features + +### Function Calling + +OpenAI models support function calling, which PicoClaw uses for tools. + +### Vision + +GPT-4o and GPT-4 Turbo support image analysis: + +```json +{ + "agents": { + "defaults": { + "model": "gpt-4o", + "vision": true + } + } +} +``` + +### Structured Outputs + +For applications requiring structured responses: + +```json +{ + "agents": { + "defaults": { + "model": "gpt-4o", + "response_format": "json_object" + } + } +} +``` + +## Using with Azure OpenAI + +For Azure OpenAI Service: + +```json +{ + "providers": { + "openai": { + "api_key": "your-azure-key", + "api_base": "https://your-resource.openai.azure.com/openai/deployments/your-deployment", + "api_version": "2024-02-15-preview", + "azure": true + } + } +} +``` + +## Troubleshooting + +### Invalid API Key + +``` +Error: incorrect_api_key +``` + +Verify your API key: +1. Check key starts with `sk-` +2. Ensure key is active +3. Check for typos + +### Insufficient Quota + +``` +Error: insufficient_quota +``` + +Solutions: +1. Add billing information +2. Wait for quota reset +3. Use fallback models + +### Rate Limited + +``` +Error: rate_limit_exceeded +``` + +Solutions: +1. Wait and retry +2. Set up fallback models +3. Upgrade your tier + +### Context Length Exceeded + +``` +Error: context_length_exceeded +``` + +Solutions: +1. Reduce message length +2. Clear session history +3. Use a model with larger context + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) +- [Model Fallbacks](../advanced/model-fallbacks.md) diff --git a/docs/user-guide/providers/openrouter.md b/docs/user-guide/providers/openrouter.md new file mode 100644 index 0000000000..201b8d7783 --- /dev/null +++ b/docs/user-guide/providers/openrouter.md @@ -0,0 +1,114 @@ +# OpenRouter Provider + +OpenRouter is the recommended provider for most users. It provides access to many LLM models through a single API. + +## Why OpenRouter? + +- **Multi-model access**: Claude, GPT, Llama, Mistral, and more +- **Free tier**: 200K tokens per month +- **Simple pricing**: Pay per use after free tier +- **Single API key**: Access all models with one key + +## Setup + +### Step 1: Get API Key + +1. Go to [openrouter.ai/keys](https://openrouter.ai/keys) +2. Sign in or create an account +3. Create an API key +4. Copy the key (starts with `sk-or-v1-`) + +### Step 2: Configure + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "anthropic/claude-opus-4-5" + } + }, + "providers": { + "openrouter": { + "api_key": "sk-or-v1-YOUR-API-KEY", + "api_base": "https://openrouter.ai/api/v1" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_key` | Yes | - | Your OpenRouter API key | +| `api_base` | No | `https://openrouter.ai/api/v1` | API endpoint | + +## Popular Models + +| Model | Model Name | Notes | +|-------|------------|-------| +| Claude Opus 4.5 | `anthropic/claude-opus-4-5` | Most capable | +| Claude Sonnet 4 | `anthropic/claude-sonnet-4` | Fast + capable | +| GPT-4o | `openai/gpt-4o` | OpenAI flagship | +| GPT-4o Mini | `openai/gpt-4o-mini` | Fast, cheaper | +| Llama 3.3 70B | `meta-llama/llama-3.3-70b-instruct` | Open model | +| Gemini 2.0 Flash | `google/gemini-2.0-flash-001` | Fast Google model | + +## Model Format + +Use the format `provider/model-name`: + +```json +{ + "agents": { + "defaults": { + "model": "anthropic/claude-opus-4-5" + } + } +} +``` + +## Fallback Configuration + +Set up fallbacks for reliability: + +```json +{ + "agents": { + "defaults": { + "model": "anthropic/claude-opus-4-5", + "model_fallbacks": [ + "anthropic/claude-sonnet-4", + "openai/gpt-4o" + ] + } + } +} +``` + +## Usage Examples + +```bash +# Use default model +picoclaw agent -m "Hello!" + +# With specific model +picoclaw agent -m "Hello!" # Uses config model +``` + +## Pricing + +Check [openrouter.ai/models](https://openrouter.ai/models) for current pricing. + +## Environment Variable + +```bash +export PICOCLAW_PROVIDERS_OPENROUTER_API_KEY="sk-or-v1-xxx" +``` + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) diff --git a/docs/user-guide/providers/vllm.md b/docs/user-guide/providers/vllm.md new file mode 100644 index 0000000000..8914f69db0 --- /dev/null +++ b/docs/user-guide/providers/vllm.md @@ -0,0 +1,363 @@ +# vLLM Provider + +Use vLLM for high-performance, self-hosted LLM serving. + +## Why vLLM? + +- **High throughput**: Optimized for production workloads +- **Memory efficient**: PagedAttention for better GPU utilization +- **OpenAI compatible**: Drop-in replacement for OpenAI API +- **Flexible**: Supports many open-source models + +## Prerequisites + +- NVIDIA GPU (CUDA support) +- Docker (recommended) or Python environment +- Sufficient GPU memory for your model + +## Setup + +### Option 1: Docker (Recommended) + +```bash +# Pull vLLM image +docker pull vllm/vllm-openai:latest + +# Run vLLM server +docker run --gpus all \ + -v ~/.cache/huggingface:/root/.cache/huggingface \ + -p 8000:8000 \ + --ipc=host \ + vllm/vllm-openai:latest \ + --model meta-llama/Llama-3.2-3B-Instruct +``` + +### Option 2: Python Installation + +```bash +# Install vLLM +pip install vllm + +# Start server +python -m vllm.entrypoints.openai.api_server \ + --model meta-llama/Llama-3.2-3B-Instruct \ + --host 0.0.0.0 \ + --port 8000 +``` + +### Configure PicoClaw + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "meta-llama/Llama-3.2-3B-Instruct" + } + }, + "providers": { + "vllm": { + "api_base": "http://localhost:8000/v1" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_base` | No | `http://localhost:8000/v1` | vLLM API endpoint | +| `api_key` | No | - | API key (if configured) | + +## Supported Models + +vLLM supports many Hugging Face models: + +| Model Family | Example Models | +|--------------|----------------| +| Llama | `meta-llama/Llama-3.2-3B-Instruct` | +| Mistral | `mistralai/Mistral-7B-Instruct-v0.3` | +| Qwen | `Qwen/Qwen2.5-7B-Instruct` | +| Phi | `microsoft/Phi-3-mini-4k-instruct` | +| Gemma | `google/gemma-2-9b-it` | +| Mixtral | `mistralai/Mixtral-8x7B-Instruct-v0.1` | + +## vLLM Server Options + +### GPU Selection + +```bash +# Use specific GPUs +docker run --gpus '"device=0,1"' \ + vllm/vllm-openai:latest \ + --model meta-llama/Llama-3.2-3B-Instruct +``` + +### Memory Management + +```bash +# GPU memory utilization (0-1) +--gpu-memory-utilization 0.9 + +# Max model length +--max-model-len 4096 +``` + +### Performance Tuning + +```bash +# Tensor parallelism (multi-GPU) +--tensor-parallel-size 2 + +# Batch size +--max-num-seqs 256 +``` + +### Full Example + +```bash +docker run --gpus all \ + -v ~/.cache/huggingface:/root/.cache/huggingface \ + -p 8000:8000 \ + --ipc=host \ + vllm/vllm-openai:latest \ + --model meta-llama/Llama-3.2-3B-Instruct \ + --gpu-memory-utilization 0.9 \ + --max-model-len 4096 \ + --max-num-seqs 128 +``` + +## Model Format + +Use the full Hugging Face model name: + +```json +{ + "agents": { + "defaults": { + "model": "meta-llama/Llama-3.2-3B-Instruct" + } + } +} +``` + +Or with provider prefix: + +```json +{ + "agents": { + "defaults": { + "model": "vllm/meta-llama/Llama-3.2-3B-Instruct" + } + } +} +``` + +## Using with Hugging Face Token + +Some models require authentication: + +```bash +# Login to Hugging Face +huggingface-cli login + +# Or set token +export HF_TOKEN=your_token + +# Docker with token +docker run --gpus all \ + -e HF_TOKEN=your_token \ + -v ~/.cache/huggingface:/root/.cache/huggingface \ + -p 8000:8000 \ + vllm/vllm-openai:latest \ + --model meta-llama/Llama-3.2-3B-Instruct +``` + +## Fallback Configuration + +Combine vLLM with cloud providers: + +```json +{ + "agents": { + "defaults": { + "model": "meta-llama/Llama-3.2-3B-Instruct", + "model_fallbacks": [ + "openrouter/meta-llama/llama-3.2-3b-instruct" + ] + } + }, + "providers": { + "vllm": { + "api_base": "http://localhost:8000/v1" + }, + "openrouter": { + "api_key": "sk-or-v1-xxx" + } + } +} +``` + +## GPU Requirements + +### Approximate VRAM Requirements + +| Model Size | Minimum VRAM | Recommended VRAM | +|------------|--------------|------------------| +| 3B | 8GB | 12GB | +| 7B | 16GB | 24GB | +| 13B | 24GB | 40GB | +| 70B | 80GB (2x40GB) | 160GB (4x40GB) | + +### Multi-GPU Setup + +```bash +# 2 GPUs with tensor parallelism +docker run --gpus all \ + vllm/vllm-openai:latest \ + --model meta-llama/Llama-3.1-70B-Instruct \ + --tensor-parallel-size 2 +``` + +## Remote vLLM + +Connect to vLLM running on another server: + +```json +{ + "providers": { + "vllm": { + "api_base": "http://192.168.1.100:8000/v1" + } + } +} +``` + +## Authentication + +Add API key authentication: + +```bash +# Start vLLM with API key +--api-key your-secret-key +``` + +Configure PicoClaw: + +```json +{ + "providers": { + "vllm": { + "api_base": "http://localhost:8000/v1", + "api_key": "your-secret-key" + } + } +} +``` + +## Troubleshooting + +### Server Not Running + +``` +Error: connection refused +``` + +Check vLLM server: + +```bash +curl http://localhost:8000/v1/models +``` + +### Out of GPU Memory + +``` +Error: CUDA out of memory +``` + +Solutions: +1. Use smaller model +2. Reduce `--gpu-memory-utilization` +3. Reduce `--max-model-len` +4. Use multiple GPUs + +### Model Not Found + +``` +Error: model not found +``` + +Ensure model name is correct and accessible: + +```bash +# List available models +curl http://localhost:8000/v1/models +``` + +### Slow Responses + +Solutions: +1. Check GPU utilization +2. Adjust batch size +3. Enable tensor parallelism +4. Check network latency + +### Permission Denied (Hugging Face) + +``` +Error: Access to model is restricted +``` + +Login to Hugging Face: + +```bash +huggingface-cli login +``` + +## Production Deployment + +### Systemd Service + +```ini +[Unit] +Description=vLLM Server +After=network.target + +[Service] +Type=simple +User=vllm +ExecStart=/usr/bin/docker run --gpus all \ + -v /var/lib/vllm:/root/.cache/huggingface \ + -p 8000:8000 \ + vllm/vllm-openai:latest \ + --model meta-llama/Llama-3.2-3B-Instruct +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +### Kubernetes + +See vLLM documentation for Kubernetes deployment with: + +- GPU resource requests +- Horizontal scaling +- Load balancing + +## Best Practices + +1. **Use Docker** - Easier deployment and isolation +2. **Monitor GPU usage** - Watch VRAM and utilization +3. **Tune parameters** - Optimize for your workload +4. **Set up fallbacks** - Cloud providers for reliability +5. **Cache models** - Mount HuggingFace cache volume + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) +- [Model Fallbacks](../advanced/model-fallbacks.md) +- [vLLM Documentation](https://docs.vllm.ai) diff --git a/docs/user-guide/providers/zhipu.md b/docs/user-guide/providers/zhipu.md new file mode 100644 index 0000000000..cc38ff8f05 --- /dev/null +++ b/docs/user-guide/providers/zhipu.md @@ -0,0 +1,119 @@ +# Zhipu Provider + +Zhipu (智谱) provides Chinese-optimized AI models through their GLM series. + +## Why Zhipu? + +- **Chinese language**: Optimized for Chinese users +- **Free tier**: 200K tokens per month +- **Multiple models**: GLM-4.7, GLM-4-Plus, and more +- **Direct access**: No intermediary + +## Setup + +### Step 1: Get API Key + +1. Go to [bigmodel.cn](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) +2. Register or sign in +3. Create an API key +4. Copy the key + +### Step 2: Configure + +Edit `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "model": "glm-4.7" + } + }, + "providers": { + "zhipu": { + "api_key": "YOUR_ZHIPU_API_KEY", + "api_base": "https://open.bigmodel.cn/api/paas/v4" + } + } +} +``` + +## Configuration Options + +| Option | Required | Default | Description | +|--------|----------|---------|-------------| +| `api_key` | Yes | - | Your Zhipu API key | +| `api_base` | No | `https://open.bigmodel.cn/api/paas/v4` | API endpoint | + +## Available Models + +| Model | Description | +|-------|-------------| +| `glm-4.7` | Latest GLM model (default) | +| `glm-4-plus` | Enhanced capabilities | +| `glm-4` | Standard GLM-4 | +| `glm-4-air` | Faster, lighter model | +| `glm-4-flash` | Fastest model | + +## Model Format + +Use just the model name (no provider prefix needed): + +```json +{ + "agents": { + "defaults": { + "model": "glm-4.7" + } + } +} +``` + +## Features + +### Chinese Language Support + +Zhipu models are optimized for: +- Chinese conversations +- Chinese document processing +- Chinese cultural context + +### Multi-modal + +Some Zhipu models support: +- Text generation +- Image understanding +- Code generation + +## Content Filtering + +Zhipu has content filtering. If you encounter filtering errors: + +1. Rephrase your query +2. Avoid sensitive topics +3. Use a different model + +## Environment Variable + +```bash +export PICOCLAW_PROVIDERS_ZHIPU_API_KEY="your-zhipu-key" +``` + +## Usage Examples + +```bash +# Use GLM-4.7 +picoclaw agent -m "你好,请介绍一下自己" + +# Code generation +picoclaw agent -m "写一个Python快速排序" +``` + +## Pricing + +Check [bigmodel.cn](https://open.bigmodel.cn) for current pricing. + +## See Also + +- [Providers Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) diff --git a/docs/user-guide/skills/README.md b/docs/user-guide/skills/README.md new file mode 100644 index 0000000000..67e14c896b --- /dev/null +++ b/docs/user-guide/skills/README.md @@ -0,0 +1,136 @@ +# Skills Overview + +Skills are specialized capabilities that extend PicoClaw's abilities. They provide domain-specific knowledge, commands, and workflows that the agent can use to help you accomplish tasks. + +## What are Skills? + +A skill is a Markdown file (`SKILL.md`) that contains instructions and examples for the agent. When you ask PicoClaw to perform a task related to a skill, the agent loads that skill's content and follows its guidance. + +Skills can include: + +- **Command patterns** - Pre-defined shell commands for common tasks +- **API integrations** - Instructions for working with external services +- **Workflows** - Step-by-step procedures for complex operations +- **Domain knowledge** - Specialized information about topics + +## Skill Types + +### Builtin Skills + +PicoClaw comes with builtin skills that are always available: + +| Skill | Description | +|-------|-------------| +| `weather` | Get current weather and forecasts (no API key required) | +| `news` | Fetch latest news headlines | +| `stock` | Check stock prices and market data | +| `calculator` | Perform mathematical calculations | + +### Community Skills + +Install additional skills from GitHub repositories: + +```bash +picoclaw skills install sipeed/picoclaw-skills/github +``` + +### Custom Skills + +Create your own skills for specialized workflows: + +``` +~/.picoclaw/workspace/skills/ + my-skill/ + SKILL.md +``` + +## Skill Loading Priority + +Skills are loaded from three locations in priority order: + +1. **Workspace skills** - `~/.picoclaw/workspace/skills/` + - Project-specific skills, highest priority + - Override global and builtin skills with the same name + +2. **Global skills** - `~/.picoclaw/skills/` + - Shared skills across all workspaces + - Override builtin skills with the same name + +3. **Builtin skills** - Packaged with PicoClaw + - Always available as fallback + - Can be copied to workspace for customization + +## Skill Structure + +A skill is a directory containing a `SKILL.md` file: + +``` +weather/ + SKILL.md # Required: skill definition + ... # Optional: supporting files +``` + +The `SKILL.md` file format: + +```markdown +--- +name: skill-name +description: Brief description of what this skill does +metadata: + key: value +--- + +# Skill Title + +Instructions, commands, and examples for the agent... +``` + +## Using Skills + +Skills are automatically activated when relevant. Just ask PicoClaw: + +``` +User: "What's the weather in Tokyo?" +Agent: [Uses weather skill] + The current weather in Tokyo is... +``` + +For more control, see [Using Skills](using-skills.md). + +## Managing Skills + +### List Installed Skills + +```bash +picoclaw skills list +``` + +### Install from GitHub + +```bash +picoclaw skills install sipeed/picoclaw-skills/github +``` + +### Remove a Skill + +```bash +picoclaw skills remove github +``` + +### View Skill Content + +```bash +picoclaw skills show weather +``` + +## Documentation Sections + +- [Using Skills](using-skills.md) - How to use installed skills effectively +- [Installing Skills](installing-skills.md) - Installing skills from GitHub +- [Builtin Skills](builtin-skills.md) - List of builtin skills with examples +- [Creating Skills](creating-skills.md) - How to create custom skills + +## See Also + +- [CLI Reference: skills](../cli/skills.md) +- [Workspace Structure](../workspace/structure.md) diff --git a/docs/user-guide/skills/builtin-skills.md b/docs/user-guide/skills/builtin-skills.md new file mode 100644 index 0000000000..a978c676d8 --- /dev/null +++ b/docs/user-guide/skills/builtin-skills.md @@ -0,0 +1,286 @@ +# Builtin Skills + +PicoClaw includes builtin skills that are always available. These cover common tasks and don't require installation. + +## Available Builtin Skills + +| Skill | Description | Dependencies | +|-------|-------------|--------------| +| `weather` | Get weather information | `curl` | +| `news` | Fetch news headlines | `curl` | +| `stock` | Check stock prices | `curl` | +| `calculator` | Perform calculations | None | + +## Weather Skill + +Get current weather and forecasts without any API keys. + +### Features + +- Current conditions for any location +- Multi-day forecasts +- No API key required (uses wttr.in) +- Supports city names, airport codes, and coordinates + +### Examples + +**Current weather:** +``` +User: "What's the weather in London?" + +Agent: London: Partly cloudy, +15C + Humidity: 68%, Wind: 12 km/h +``` + +**Compact format:** +``` +User: "Quick weather check for Tokyo" + +Agent: Tokyo: Sunny +22C +``` + +**Full forecast:** +``` +User: "Show me the 3-day forecast for New York" + +Agent: Weather forecast for New York: + + Today Tomorrow Day After + +18C/+12C +20C/+14C +17C/+11C + Partly cloudy Sunny Rain + ... +``` + +**Airport code:** +``` +User: "Weather at JFK airport" + +Agent: JFK (New York): Clear, +20C +``` + +### Technical Details + +The weather skill uses: +- **wttr.in** - Primary service, text-based weather +- **Open-Meteo** - Fallback for JSON responses + +Format options: +- `?format=3` - One-line output +- `?T` - Full terminal forecast +- `?1` - Today only +- `?0` - Current conditions only + +## News Skill + +Fetch the latest news headlines from various sources. + +### Features + +- Top headlines +- Category filtering (tech, business, etc.) +- No API key required +- Headline summaries + +### Examples + +**Top headlines:** +``` +User: "Show me today's news" + +Agent: Top Headlines: + + 1. Tech Giants Report Record Q3 Earnings + Major technology companies exceeded analyst expectations... + + 2. Climate Summit Reaches Historic Agreement + World leaders commit to 50% emissions reduction... + + 3. New AI Breakthrough in Medical Diagnosis + Researchers announce 99% accuracy in early detection... +``` + +**Tech news:** +``` +User: "What's new in tech?" + +Agent: Technology Headlines: + + 1. Apple Announces New Product Line + 2. OpenAI Releases GPT-5 Preview + 3. Quantum Computing Milestone Achieved + ... +``` + +## Stock Skill + +Check stock prices and market data. + +### Features + +- Real-time stock prices +- Market indices +- No API key required +- Simple price queries + +### Examples + +**Stock price:** +``` +User: "What's Apple's stock price?" + +Agent: AAPL (Apple Inc.): $178.50 + Change: +2.30 (+1.31%) + Volume: 52.3M +``` + +**Market indices:** +``` +User: "How's the market doing today?" + +Agent: Market Summary: + + Dow Jones: 38,500 (+0.5%) + S&P 500: 5,200 (+0.8%) + NASDAQ: 16,400 (+1.2%) +``` + +**Multiple stocks:** +``` +User: "Check prices for AAPL, GOOGL, and MSFT" + +Agent: Stock Prices: + + AAPL: $178.50 (+1.31%) + GOOGL: $141.25 (+0.85%) + MSFT: $378.90 (+0.92%) +``` + +## Calculator Skill + +Perform mathematical calculations. + +### Features + +- Basic arithmetic +- Percentages +- Unit conversions +- Compound interest +- No external dependencies + +### Examples + +**Basic math:** +``` +User: "What's 15% of 847?" + +Agent: 15% of 847 is 127.05 +``` + +**Compound interest:** +``` +User: "Calculate compound interest on $10,000 at 5% for 3 years, compounded monthly" + +Agent: Compound Interest Calculation: + + Principal: $10,000.00 + Rate: 5% annual + Period: 3 years + Compounding: Monthly + + Final Amount: $11,614.72 + Interest Earned: $1,614.72 +``` + +**Unit conversion:** +``` +User: "Convert 100 miles to kilometers" + +Agent: 100 miles = 160.934 kilometers +``` + +**Expression evaluation:** +``` +User: "Calculate (25 * 4) + (100 / 5) - 15" + +Agent: (25 * 4) + (100 / 5) - 15 = 105 +``` + +## Installing Builtin Skills + +To customize builtin skills, copy them to your workspace: + +```bash +picoclaw skills install-builtin +``` + +This copies all builtin skills to `~/.picoclaw/workspace/skills/`, where you can edit them. + +### Listing Builtin Skills + +View available builtin skills: + +```bash +picoclaw skills list-builtin +``` + +Output: +``` +Available Builtin Skills: +----------------------- + weather + Get current weather and forecasts + news + Get latest news headlines + stock + Check stock prices and market data + calculator + Perform mathematical calculations +``` + +## Customizing Builtin Skills + +After installing builtin skills, you can modify them: + +```bash +# Install to workspace +picoclaw skills install-builtin + +# Edit the weather skill +vim ~/.picoclaw/workspace/skills/weather/SKILL.md + +# Your modified version takes precedence +picoclaw skills show weather +``` + +Common customizations: +- Add local city shortcuts +- Change default format options +- Add new API endpoints +- Include location-specific settings + +## Skill Dependencies + +Some builtin skills require external tools: + +| Skill | Required Tools | +|-------|---------------| +| weather | `curl` | +| news | `curl` | +| stock | `curl` | +| calculator | None (built-in) | + +Install dependencies: +```bash +# macOS +brew install curl + +# Ubuntu/Debian +sudo apt install curl +``` + +## See Also + +- [Skills Overview](README.md) +- [Using Skills](using-skills.md) +- [Installing Skills](installing-skills.md) +- [Creating Skills](creating-skills.md) diff --git a/docs/user-guide/skills/creating-skills.md b/docs/user-guide/skills/creating-skills.md new file mode 100644 index 0000000000..ad482ec437 --- /dev/null +++ b/docs/user-guide/skills/creating-skills.md @@ -0,0 +1,503 @@ +# Creating Skills + +Learn how to create custom skills to extend PicoClaw's capabilities. + +## Skill Structure + +A skill is a directory containing a `SKILL.md` file: + +``` +~/.picoclaw/workspace/skills/ + my-skill/ + SKILL.md # Required: skill definition +``` + +## SKILL.md Format + +The skill file uses YAML frontmatter for metadata and Markdown for content: + +```markdown +--- +name: my-skill +description: Brief description of what this skill does +metadata: + key: value +--- + +# Skill Title + +Instructions for the agent go here. + +## Section + +More details, commands, and examples... +``` + +### Frontmatter Fields + +| Field | Required | Description | +|-------|----------|-------------| +| `name` | Yes | Skill identifier (alphanumeric with hyphens) | +| `description` | Yes | Brief description (max 1024 characters) | +| `metadata` | No | Additional metadata (JSON object) | + +### Naming Rules + +- Max 64 characters +- Alphanumeric characters and hyphens only +- Must start with a letter or number +- Examples: `github`, `my-skill`, `api-helper` + +## Creating Your First Skill + +### Step 1: Create the Directory + +```bash +mkdir -p ~/.picoclaw/workspace/skills/hello +``` + +### Step 2: Create SKILL.md + +```bash +cat > ~/.picoclaw/workspace/skills/hello/SKILL.md << 'EOF' +--- +name: hello +description: A simple greeting skill that demonstrates skill creation. +--- + +# Hello Skill + +This skill demonstrates basic skill structure. + +## Usage + +When the user asks for a greeting, respond warmly: + +"Hello! I'm your PicoClaw assistant. How can I help you today?" + +## Example Commands + +Show current time: +```bash +date +``` + +Show system info: +```bash +uname -a +``` +EOF +``` + +### Step 3: Verify Installation + +```bash +picoclaw skills list +``` + +Output: +``` +Installed Skills: +------------------ + hello (workspace) + A simple greeting skill that demonstrates skill creation. +``` + +## Skill Content Best Practices + +### 1. Clear Instructions + +Write clear, actionable instructions for the agent: + +```markdown +# Database Backup Skill + +## Purpose + +Create backups of PostgreSQL databases. + +## Commands + +Full backup: +```bash +pg_dump -h localhost -U postgres -d mydb > backup_$(date +%Y%m%d).sql +``` + +Compressed backup: +```bash +pg_dump -h localhost -U postgres -d mydb | gzip > backup_$(date +%Y%m%d).sql.gz +``` + +## Important Notes + +- Always verify the backup was created +- Store backups in a secure location +- Include timestamp in filename +``` + +### 2. Include Examples + +Provide concrete examples for common use cases: + +```markdown +## Examples + +Backup specific tables: +```bash +pg_dump -h localhost -U postgres -d mydb -t users -t orders > partial_backup.sql +``` + +Restore from backup: +```bash +psql -h localhost -U postgres -d mydb < backup_20240115.sql +``` +``` + +### 3. Document Dependencies + +List required tools and how to install them: + +```markdown +## Requirements + +- `curl` - HTTP client +- `jq` - JSON processor + +Install on macOS: +```bash +brew install curl jq +``` + +Install on Ubuntu: +```bash +sudo apt install curl jq +``` +``` + +### 4. Add Error Handling + +Include troubleshooting information: + +```markdown +## Troubleshooting + +### Connection Failed + +If you see "Connection refused": +1. Check if PostgreSQL is running: `pg_isready` +2. Verify connection parameters +3. Check firewall settings + +### Permission Denied + +If you see "Permission denied": +1. Check user has backup privileges +2. Verify .pgpass file is configured +``` + +## Advanced Skill Features + +### API Integration + +Create skills that work with APIs: + +```markdown +--- +name: openai-api +description: Interact with OpenAI API for various AI tasks. +--- + +# OpenAI API Skill + +## Setup + +Set your API key: +```bash +export OPENAI_API_KEY="sk-..." +``` + +## Chat Completion + +```bash +curl https://api.openai.com/v1/chat/completions \ + -H "Authorization: Bearer $OPENAI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "gpt-4", + "messages": [{"role": "user", "content": "Hello!"}] + }' | jq . +``` + +## Image Generation + +```bash +curl https://api.openai.com/v1/images/generations \ + -H "Authorization: Bearer $OPENAI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "A sunset over mountains", + "size": "1024x1024" + }' | jq . +``` +``` + +### Workflow Skills + +Create skills for multi-step workflows: + +```markdown +--- +name: deploy +description: Deploy application to production with safety checks. +--- + +# Deployment Skill + +## Pre-deployment Checklist + +Before deploying, verify: +1. All tests pass: `npm test` +2. Build succeeds: `npm run build` +3. No security vulnerabilities: `npm audit` + +## Deployment Steps + +1. Create deployment branch: +```bash +git checkout -b deploy/$(date +%Y%m%d-%H%M) +``` + +2. Build and test: +```bash +npm ci +npm run build +npm test +``` + +3. Deploy: +```bash +npm run deploy:production +``` + +4. Verify deployment: +```bash +curl -s https://api.example.com/health | jq . +``` + +## Rollback + +If issues occur: +```bash +npm run deploy:rollback +``` +``` + +### Tool Requiring Skills + +Document external tool requirements: + +```markdown +--- +name: docker +description: Manage Docker containers and images. +metadata: + requires: + bins: ["docker"] + install: + - id: brew + kind: brew + formula: docker + bins: ["docker"] + - id: apt + kind: apt + package: docker.io + bins: ["docker"] +--- + +# Docker Skill + +## Requirements + +Docker must be installed. Install with: + +macOS: +```bash +brew install --cask docker +``` + +Ubuntu: +```bash +sudo apt install docker.io +sudo usermod -aG docker $USER +``` + +## Common Commands + +List containers: +```bash +docker ps -a +``` + +View logs: +```bash +docker logs +``` + +Execute in container: +```bash +docker exec -it /bin/sh +``` +``` + +## Testing Your Skill + +### 1. List and Verify + +```bash +picoclaw skills list +``` + +Your skill should appear with the correct description. + +### 2. Show Content + +```bash +picoclaw skills show my-skill +``` + +Verify the content is displayed correctly. + +### 3. Use in Conversation + +Start a conversation and test the skill: + +```bash +picoclaw agent -m "Use my-skill to help me with something" +``` + +## Sharing Skills + +### Publishing to GitHub + +1. Create a GitHub repository: +``` +my-picoclaw-skills/ + my-skill/ + SKILL.md + skills.json +``` + +2. Create `skills.json` registry: +```json +[ + { + "name": "my-skill", + "repository": "username/my-picoclaw-skills/my-skill", + "description": "Description of my skill", + "author": "your-username", + "tags": ["automation", "productivity"] + } +] +``` + +3. Users can install with: +```bash +picoclaw skills install username/my-picoclaw-skills/my-skill +``` + +### Contributing to Official Registry + +Submit a pull request to the official skills repository: +https://github.com/sipeed/picoclaw-skills + +## Skill Templates + +### Basic Template + +```markdown +--- +name: skill-name +description: One-line description of the skill. +--- + +# Skill Name + +Brief introduction to the skill. + +## Commands + +### Command 1 + +```bash +command-here +``` + +### Command 2 + +```bash +another-command +``` + +## Examples + +Show practical usage examples. + +## Troubleshooting + +Common issues and solutions. +``` + +### API Template + +```markdown +--- +name: api-name +description: Interact with API-NAME service. +--- + +# API Name Skill + +## Authentication + +Set API key: +```bash +export API_KEY="your-key-here" +``` + +## Endpoints + +### GET /resource + +```bash +curl -H "Authorization: Bearer $API_KEY" \ + https://api.example.com/resource +``` + +### POST /resource + +```bash +curl -X POST \ + -H "Authorization: Bearer $API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"key": "value"}' \ + https://api.example.com/resource +``` +``` + +## Best Practices Summary + +1. **Clear naming** - Use descriptive, lowercase names with hyphens +2. **Good descriptions** - Write concise descriptions that explain the skill's purpose +3. **Include examples** - Show how to use commands and features +4. **Document dependencies** - List required tools and installation methods +5. **Add troubleshooting** - Help users solve common problems +6. **Test thoroughly** - Verify your skill works before sharing +7. **Keep it focused** - One skill, one purpose + +## See Also + +- [Skills Overview](README.md) +- [Using Skills](using-skills.md) +- [Installing Skills](installing-skills.md) +- [Builtin Skills](builtin-skills.md) +- [CLI Reference: skills](../cli/skills.md) diff --git a/docs/user-guide/skills/installing-skills.md b/docs/user-guide/skills/installing-skills.md new file mode 100644 index 0000000000..1c965c26fe --- /dev/null +++ b/docs/user-guide/skills/installing-skills.md @@ -0,0 +1,234 @@ +# Installing Skills + +Learn how to install and manage skills in PicoClaw. + +## Installation Methods + +### From GitHub + +Install skills directly from GitHub repositories: + +```bash +picoclaw skills install // +``` + +Example: +```bash +picoclaw skills install sipeed/picoclaw-skills/github +``` + +The installer fetches the `SKILL.md` file from the repository and saves it to your workspace. + +### Builtin Skills + +Install all builtin skills to your workspace for customization: + +```bash +picoclaw skills install-builtin +``` + +This copies the builtin skills (weather, news, stock, calculator) to `~/.picoclaw/workspace/skills/`, allowing you to modify them. + +### Manual Installation + +Create a skill manually by creating a directory and `SKILL.md` file: + +```bash +mkdir -p ~/.picoclaw/workspace/skills/my-skill +``` + +Then create `~/.picoclaw/workspace/skills/my-skill/SKILL.md` with your skill content. + +## Managing Installed Skills + +### List Installed Skills + +View all installed skills: + +```bash +picoclaw skills list +``` + +Output shows the skill name, source (workspace/global/builtin), and description: +``` +Installed Skills: +------------------ + weather (workspace) + Get current weather and forecasts + github (global) + Interact with GitHub using the gh CLI + calculator (builtin) + Perform mathematical calculations +``` + +### View Skill Details + +Display the full content of a skill: + +```bash +picoclaw skills show weather +``` + +Output: +``` +Skill: weather +---------------------- +# Weather + +Two free services, no API keys needed. + +## wttr.in (primary) + +Quick one-liner: +curl -s "wttr.in/London?format=3" +... +``` + +### Remove a Skill + +Uninstall a skill from your workspace: + +```bash +picoclaw skills remove +``` + +Example: +```bash +picoclaw skills remove github +``` + +## Searching for Skills + +Search the online skill registry for available skills: + +```bash +picoclaw skills search +``` + +Output: +``` +Available Skills (5): +-------------------- + github + Interact with GitHub using the gh CLI + Repo: sipeed/picoclaw-skills/github + Author: picoclaw + Tags: [git, github, ci] + + slack + Send messages to Slack channels + Repo: sipeed/picoclaw-skills/slack + Author: picoclaw + Tags: [slack, messaging] +... +``` + +## Skill Installation Locations + +Skills are installed to different locations based on scope: + +| Location | Path | Description | +|----------|------|-------------| +| Workspace | `~/.picoclaw/workspace/skills/` | Project-specific, highest priority | +| Global | `~/.picoclaw/skills/` | Shared across workspaces | +| Builtin | Packaged with PicoClaw | Always available as fallback | + +### Choosing Installation Scope + +- **Workspace skills** - For skills specific to a project or workflow +- **Global skills** - For skills you want available everywhere +- **Builtin skills** - Ready to use, can be copied for customization + +## Installation Examples + +### Install from Official Registry + +```bash +# Install GitHub integration skill +picoclaw skills install sipeed/picoclaw-skills/github + +# Install tmux session management skill +picoclaw skills install sipeed/picoclaw-skills/tmux +``` + +### Install Custom Skill from Your Repo + +```bash +# From your personal GitHub +picoclaw skills install yourname/picoclaw-skills/my-custom-skill +``` + +### Install All Builtin Skills + +```bash +# Copy builtin skills to workspace for customization +picoclaw skills install-builtin + +# Now you can edit them +vim ~/.picoclaw/workspace/skills/weather/SKILL.md +``` + +## Updating Skills + +Skills don't auto-update. To update a skill: + +```bash +# Remove old version +picoclaw skills remove weather + +# Reinstall from source +picoclaw skills install sipeed/picoclaw-skills/weather +``` + +## GitHub Repository Structure + +Skill repositories should have this structure: + +``` +picoclaw-skills/ + weather/ + SKILL.md + github/ + SKILL.md + skills.json # Optional: registry file +``` + +The `SKILL.md` file must be at the root of the skill directory. + +## Troubleshooting + +### Installation Fails + +Common causes: + +1. **Network error** - Check your internet connection +2. **Repository not found** - Verify the repository path +3. **Skill already exists** - Remove the existing skill first + +```bash +# Remove and reinstall +picoclaw skills remove +picoclaw skills install +``` + +### Skill Not Loading After Install + +1. Verify installation: `picoclaw skills list` +2. Check file exists: `ls ~/.picoclaw/workspace/skills//SKILL.md` +3. Validate skill format: `picoclaw skills show ` + +### Permission Denied + +Ensure you have write permissions to the skills directory: + +```bash +ls -la ~/.picoclaw/workspace/skills/ +``` + +## See Also + +- [Skills Overview](README.md) +- [Using Skills](using-skills.md) +- [Builtin Skills](builtin-skills.md) +- [Creating Skills](creating-skills.md) +- [CLI Reference: skills](../cli/skills.md) diff --git a/docs/user-guide/skills/using-skills.md b/docs/user-guide/skills/using-skills.md new file mode 100644 index 0000000000..7db8720a8b --- /dev/null +++ b/docs/user-guide/skills/using-skills.md @@ -0,0 +1,205 @@ +# Using Skills + +Learn how to effectively use installed skills in PicoClaw. + +## How Skills Work + +When you interact with PicoClaw, it automatically loads relevant skills based on your request. The skill content is added to the agent's context, providing it with specialized knowledge and command patterns. + +## Automatic Skill Activation + +Skills are activated automatically based on context. PicoClaw analyzes your request and loads skills that might be relevant: + +``` +User: "What's the weather like in San Francisco?" + +Agent: [Loads weather skill, executes curl command] + The current weather in San Francisco is partly cloudy + with a temperature of 18C (64F). Humidity is at 72%. +``` + +## Viewing Available Skills + +List all installed skills to see what capabilities are available: + +```bash +picoclaw skills list +``` + +Output: +``` +Installed Skills: +------------------ + weather (workspace) + Get current weather and forecasts (no API key required) + github (global) + Interact with GitHub using the gh CLI + calculator (builtin) + Perform mathematical calculations +``` + +## Viewing Skill Details + +To see the full content of a skill: + +```bash +picoclaw skills show weather +``` + +This displays the skill's instructions, commands, and examples that the agent uses. + +## Skill Examples + +### Weather Skill + +The weather skill uses wttr.in for weather data without requiring an API key. + +``` +User: "Check the weather in London" + +Agent: [Uses weather skill] + London: Partly cloudy, +15C + Humidity: 68%, Wind: 12 km/h NW +``` + +``` +User: "Get a 3-day forecast for Tokyo" + +Agent: [Uses weather skill] + Here's the forecast for Tokyo... + + Morning Noon Evening + +12C +18C +14C + Rain Cloudy Clear + ... +``` + +### GitHub Skill + +The GitHub skill provides GitHub CLI integration. + +``` +User: "List open issues in my repo" + +Agent: [Uses github skill] + Here are the open issues: + + #142 - Fix authentication bug + #141 - Add dark mode support + #140 - Update documentation +``` + +``` +User: "Check the CI status of PR 55" + +Agent: [Uses github skill] + PR #55 CI Status: All checks passed + - build: passed + - test: passed + - lint: passed +``` + +### Calculator Skill + +The calculator skill performs mathematical calculations. + +``` +User: "What's 15% of 847?" + +Agent: [Uses calculator skill] + 15% of 847 is 127.05 +``` + +``` +User: "Calculate the compound interest on $10,000 at 5% for 3 years" + +Agent: [Uses calculator skill] + After 3 years at 5% annual interest: + Final amount: $11,576.25 + Total interest earned: $1,576.25 +``` + +### News Skill + +The news skill fetches current headlines. + +``` +User: "Show me today's top headlines" + +Agent: [Uses news skill] + Top Headlines: + + 1. Tech Giants Report Q3 Earnings + 2. Climate Summit Reaches Agreement + 3. New AI Breakthrough Announced + ... +``` + +## Explicit Skill Requests + +You can explicitly mention a skill to ensure it's used: + +``` +User: "Use the github skill to create a new issue about the login bug" + +Agent: [Uses github skill, creates issue] + Created issue #143: "Login bug on mobile devices" + https://github.com/owner/repo/issues/143 +``` + +## Skill Context in Conversations + +Skills remain active throughout a conversation session. If you start talking about weather, the weather skill stays in context for follow-up questions: + +``` +User: "What's the weather in Paris?" +Agent: Paris: Sunny, +22C + +User: "And in Berlin?" +Agent: [Weather skill still active] + Berlin: Cloudy, +18C + +User: "Which is warmer?" +Agent: Paris is warmer at +22C compared to Berlin's +18C. +``` + +## Tips for Using Skills + +1. **Be specific** - Clear requests help the agent select the right skill +2. **Check skill content** - Use `picoclaw skills show ` to see what a skill can do +3. **Combine skills** - Complex tasks may use multiple skills together +4. **Customize** - Copy builtin skills to your workspace to modify them + +## Troubleshooting + +### Skill Not Activating + +If a skill isn't being used: + +1. Verify it's installed: `picoclaw skills list` +2. Check the skill content: `picoclaw skills show ` +3. Try being more explicit: "Use the weather skill to..." + +### Skill Commands Failing + +Some skills require external tools: + +1. Check dependencies in the skill description +2. Install required tools (e.g., `gh` CLI for GitHub skill) +3. Ensure tools are in your PATH + +### Outdated Skill + +To update a skill: + +```bash +picoclaw skills remove +picoclaw skills install +``` + +## See Also + +- [Skills Overview](README.md) +- [Installing Skills](installing-skills.md) +- [Builtin Skills](builtin-skills.md) +- [Creating Skills](creating-skills.md) diff --git a/docs/user-guide/tools/README.md b/docs/user-guide/tools/README.md new file mode 100644 index 0000000000..b6a79d26c8 --- /dev/null +++ b/docs/user-guide/tools/README.md @@ -0,0 +1,147 @@ +# Tools Overview + +PicoClaw has built-in tools that allow the agent to interact with files, execute commands, search the web, and more. + +## Available Tools + +### File System Tools + +| Tool | Description | +|------|-------------| +| `read_file` | Read file contents | +| `write_file` | Create or overwrite files | +| `list_dir` | List directory contents | +| `edit_file` | Replace text in files | +| `append_file` | Append to files | + +### Execution Tools + +| Tool | Description | +|------|-------------| +| `exec` | Execute shell commands | + +### Web Tools + +| Tool | Description | +|------|-------------| +| `web_search` | Search the web | +| `web_fetch` | Fetch web page content | + +### Communication Tools + +| Tool | Description | +|------|-------------| +| `message` | Send messages to channels | +| `spawn` | Create subagents for background tasks | + +### Scheduling Tools + +| Tool | Description | +|------|-------------| +| `cron` | Schedule reminders and tasks | + +### Hardware Tools (Linux only) + +| Tool | Description | +|------|-------------| +| `i2c` | I2C bus interaction | +| `spi` | SPI bus interaction | + +## Tool Security + +### Workspace Restriction + +When `restrict_to_workspace: true` (default): + +- File tools only work within workspace +- Exec commands run in workspace directory +- Symlink escapes are blocked + +### Exec Protection + +Even with workspace restriction disabled, these commands are blocked: + +- `rm -rf`, `del /f`, `rmdir /s` +- `format`, `mkfs`, `diskpart` +- `dd if=` +- `shutdown`, `reboot`, `poweroff` +- Fork bombs + +## Tool Configuration + +### Web Search + +Configure search providers: + +```json +{ + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "YOUR_KEY", + "max_results": 5 + }, + "duckduckgo": { + "enabled": true, + "max_results": 5 + } + } + } +} +``` + +### Exec + +Configure command restrictions: + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": ["wget.*", "curl.*"] + } + } +} +``` + +### Cron + +Configure job timeout: + +```json +{ + "tools": { + "cron": { + "exec_timeout_minutes": 5 + } + } +} +``` + +## Using Tools + +The agent automatically uses tools based on your requests: + +``` +User: "Read the file notes.txt and summarize it" + +Agent: [Uses read_file tool] + The file contains... +``` + +## Tool Details + +- [File System Tools](filesystem.md) +- [Exec Tool](exec.md) +- [Web Tools](web.md) +- [Messaging Tool](messaging.md) +- [Spawn Tool](spawn.md) +- [Cron Tool](cron.md) +- [Hardware Tools](hardware.md) + +## See Also + +- [Security Sandbox](../advanced/security-sandbox.md) +- [Configuration Reference](../../configuration/config-file.md) diff --git a/docs/user-guide/tools/approval.md b/docs/user-guide/tools/approval.md new file mode 100644 index 0000000000..b80becdf6b --- /dev/null +++ b/docs/user-guide/tools/approval.md @@ -0,0 +1,101 @@ +# Approval Tool + +The approval tool controls permissions for sensitive operations, requiring user confirmation before executing. + +## Overview + +When enabled, the approval tool prompts the user to confirm dangerous operations before they are executed. This adds an extra layer of safety for operations that could modify files or execute commands. + +## Configuration + +```json +{ + "tools": { + "approval": { + "enabled": true, + "write_file": true, + "edit_file": true, + "append_file": true, + "exec": true, + "timeout_minutes": 5 + } + } +} +``` + +## Options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `enabled` | bool | `true` | Enable approval functionality | +| `write_file` | bool | `true` | Require approval for file writes | +| `edit_file` | bool | `true` | Require approval for file edits | +| `append_file` | bool | `true` | Require approval for file appends | +| `exec` | bool | `true` | Require approval for command execution | +| `timeout_minutes` | int | `5` | Approval timeout in minutes | + +## How It Works + +1. Agent requests to perform a sensitive operation +2. Approval tool intercepts the request +3. User is prompted to approve or deny +4. If approved within timeout, operation proceeds +5. If denied or timeout, operation is cancelled + +## Example Flow + +``` +Agent: I need to write to config.json. Requesting approval... + +[Approval Request] +Operation: write_file +Path: config.json +Approve? (y/n): y + +Agent: Approved. Writing to config.json... +``` + +## Disabling Specific Approvals + +Disable approval for specific operations: + +```json +{ + "tools": { + "approval": { + "enabled": true, + "write_file": false, + "exec": false + } + } +} +``` + +This allows the agent to write files and execute commands without approval, while still requiring approval for edits and appends. + +## Disabling All Approvals + +```json +{ + "tools": { + "approval": { + "enabled": false + } + } +} +``` + +**Warning**: Disabling approvals reduces safety. Use only in trusted environments. + +## Environment Variables + +```bash +export PICOCLAW_TOOLS_APPROVAL_ENABLED=false +export PICOCLAW_TOOLS_APPROVAL_TIMEOUT_MINUTES=10 +``` + +## See Also + +- [Exec Tool](exec.md) +- [File System Tools](filesystem.md) +- [Security Sandbox](../advanced/security-sandbox.md) diff --git a/docs/user-guide/tools/cron.md b/docs/user-guide/tools/cron.md new file mode 100644 index 0000000000..b1c68278f8 --- /dev/null +++ b/docs/user-guide/tools/cron.md @@ -0,0 +1,197 @@ +# Cron Tool + +Schedule reminders and recurring tasks. + +## Tool + +### cron + +Schedule, list, or manage scheduled jobs. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `action` | string | Yes | Action: `add`, `list`, `remove`, `enable`, `disable` | +| `name` | string | Conditional | Job name (for add) | +| `message` | string | Conditional | Message for agent (for add) | +| `every_seconds` | int | Conditional | Run every N seconds | +| `at_seconds` | int | Conditional | Run once after N seconds | +| `cron_expr` | string | Conditional | Cron expression | +| `job_id` | string | Conditional | Job ID (for remove/enable/disable) | + +**Examples:** + +```json +// Add recurring job +{ + "action": "add", + "name": "Hourly check", + "message": "Check system status", + "every_seconds": 3600 +} + +// Add one-time reminder +{ + "action": "add", + "name": "Meeting reminder", + "message": "Time for your meeting!", + "at_seconds": 300 +} + +// List all jobs +{ + "action": "list" +} + +// Remove a job +{ + "action": "remove", + "job_id": "abc123" +} +``` + +## CLI vs Tool + +### CLI Commands + +Use CLI for administrative tasks: + +```bash +picoclaw cron list +picoclaw cron add -n "name" -m "message" -e 3600 +picoclaw cron remove +``` + +### Tool Usage + +The agent uses the cron tool when you ask: + +``` +User: "Remind me to take a break in 30 minutes" + +Agent uses cron tool: +{ + "action": "add", + "name": "Break reminder", + "message": "Time to take a break!", + "at_seconds": 1800 +} + +Agent: "I'll remind you to take a break in 30 minutes." +``` + +## Schedule Types + +### One-Time (at_seconds) + +Run once after N seconds: + +```json +{ + "action": "add", + "name": "Reminder", + "message": "Meeting in 10 minutes!", + "at_seconds": 600 +} +``` + +### Recurring (every_seconds) + +Run every N seconds: + +```json +{ + "action": "add", + "name": "Hourly check", + "message": "Check the time", + "every_seconds": 3600 +} +``` + +### Cron Expression + +Use standard cron format: + +```json +{ + "action": "add", + "name": "Daily standup", + "message": "Time for standup!", + "cron_expr": "0 9 * * 1-5" +} +``` + +## Cron Expressions + +``` +┌───────────── minute (0 - 59) +│ ┌───────────── hour (0 - 23) +│ │ ┌───────────── day of month (1 - 31) +│ │ │ ┌───────────── month (1 - 12) +│ │ │ │ ┌───────────── day of week (0 - 6) +│ │ │ │ │ +* * * * * +``` + +| Expression | Meaning | +|------------|---------| +| `0 9 * * *` | Daily at 9:00 AM | +| `0 */2 * * *` | Every 2 hours | +| `30 8 * * 1-5` | Weekdays at 8:30 AM | +| `0 0 * * 0` | Every Sunday midnight | + +## Configuration + +### Timeout + +Set max execution time for jobs: + +```json +{ + "tools": { + "cron": { + "exec_timeout_minutes": 5 + } + } +} +``` + +## Storage + +Jobs are stored in: + +``` +~/.picoclaw/workspace/cron/jobs.json +``` + +## Examples + +``` +User: "Remind me every hour to drink water" + +Agent uses cron tool: +{ + "action": "add", + "name": "Hydration reminder", + "message": "Time to drink some water!", + "every_seconds": 3600 +} +``` + +``` +User: "Set a reminder for my 3 PM meeting" + +Agent uses cron tool: +{ + "action": "add", + "name": "Meeting reminder", + "message": "Your meeting starts in 10 minutes!", + "at_seconds": +} +``` + +## See Also + +- [CLI Cron Commands](../cli/cron.md) +- [Heartbeat Tasks](../workspace/heartbeat-tasks.md) diff --git a/docs/user-guide/tools/exec.md b/docs/user-guide/tools/exec.md new file mode 100644 index 0000000000..33be5ffbd2 --- /dev/null +++ b/docs/user-guide/tools/exec.md @@ -0,0 +1,147 @@ +# Exec Tool + +Execute shell commands from within the agent. + +## Tool + +### exec + +Execute a shell command. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `command` | string | Yes | Shell command to execute | + +**Example:** + +```json +{ + "command": "ls -la" +} +``` + +## Security + +### Workspace Restriction + +When `restrict_to_workspace: true`: + +- Commands execute within workspace directory +- Path arguments must be within workspace + +### Deny Patterns + +Dangerous commands are always blocked: + +| Pattern | Reason | +|---------|--------| +| `rm -rf`, `rmdir /s` | Bulk deletion | +| `format`, `mkfs` | Disk formatting | +| `dd if=` | Disk imaging | +| `shutdown`, `reboot` | System control | +| `:(){ :\|:& };:` | Fork bomb | +| `wget`, `curl` (configurable) | Network downloads | + +### Custom Deny Patterns + +Add your own blocked patterns: + +```json +{ + "tools": { + "exec": { + "enable_deny_patterns": true, + "custom_deny_patterns": [ + "apt.*", + "yum.*", + "pip.*" + ] + } + } +} +``` + +## Timeout + +Commands have a 60-second timeout by default. Long-running commands will be terminated. + +## Usage Examples + +### List Files + +``` +User: "Show me all Python files" + +Agent uses exec: +{ + "command": "find . -name '*.py'" +} + +Agent: "Found 3 Python files: +- main.py +- utils.py +- test.py" +``` + +### Git Operations + +``` +User: "What's the current git status?" + +Agent uses exec: +{ + "command": "git status" +} + +Agent: "On branch main, working tree clean." +``` + +### Process Information + +``` +User: "How much disk space is free?" + +Agent uses exec: +{ + "command": "df -h ." +} + +Agent: "You have 50GB free of 100GB total." +``` + +## Error Handling + +``` +User: "Run make build" + +Agent uses exec: +{ + "command": "make build" +} + +If command fails: +Agent: "The command failed with exit code 1. Error: make: *** No targets specified." +``` + +## Disabling Restriction + +For trusted environments: + +```json +{ + "agents": { + "defaults": { + "restrict_to_workspace": false + } + } +} +``` + +**Warning**: This allows running any command the user can execute. + +## See Also + +- [Tools Overview](README.md) +- [Security Sandbox](../advanced/security-sandbox.md) diff --git a/docs/user-guide/tools/filesystem.md b/docs/user-guide/tools/filesystem.md new file mode 100644 index 0000000000..3a35fab9af --- /dev/null +++ b/docs/user-guide/tools/filesystem.md @@ -0,0 +1,169 @@ +# File System Tools + +File system tools allow the agent to read, write, and manage files. + +## Tools + +### read_file + +Read the contents of a file. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | string | Yes | File path (relative to workspace) | + +**Example:** + +```json +{ + "path": "notes.txt" +} +``` + +### write_file + +Create or overwrite a file with content. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | string | Yes | File path (relative to workspace) | +| `content` | string | Yes | File content | + +**Example:** + +```json +{ + "path": "output.txt", + "content": "Hello, World!" +} +``` + +### list_dir + +List contents of a directory. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | string | Yes | Directory path (relative to workspace) | + +**Example:** + +```json +{ + "path": "." +} +``` + +### edit_file + +Replace text in a file. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | string | Yes | File path (relative to workspace) | +| `old_text` | string | Yes | Text to replace | +| `new_text` | string | Yes | Replacement text | + +**Example:** + +```json +{ + "path": "config.json", + "old_text": "\"enabled\": false", + "new_text": "\"enabled\": true" +} +``` + +### append_file + +Append content to a file. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | string | Yes | File path (relative to workspace) | +| `content` | string | Yes | Content to append | + +**Example:** + +```json +{ + "path": "log.txt", + "content": "\nNew log entry" +} +``` + +## Security + +### Workspace Restriction + +When `restrict_to_workspace: true`: + +- All paths are relative to workspace +- Absolute paths outside workspace are blocked +- Symlink escapes are prevented + +### Path Resolution + +Paths are resolved relative to the workspace: + +| Input | Resolved To | +|-------|-------------| +| `file.txt` | `~/workspace/file.txt` | +| `subdir/file.txt` | `~/workspace/subdir/file.txt` | +| `/etc/passwd` | **BLOCKED** (outside workspace) | + +## Usage Examples + +``` +User: "Read the README.md file" + +Agent uses read_file: +{ + "path": "README.md" +} + +Agent: "The README.md file contains..." +``` + +``` +User: "Create a todo list file" + +Agent uses write_file: +{ + "path": "todo.md", + "content": "# Todo List\n\n- [ ] Task 1\n- [ ] Task 2" +} + +Agent: "Created todo.md with your todo list." +``` + +## Disabling Restriction + +For trusted environments: + +```json +{ + "agents": { + "defaults": { + "restrict_to_workspace": false + } + } +} +``` + +**Warning**: This allows access to any file the user can access. + +## See Also + +- [Tools Overview](README.md) +- [Security Sandbox](../advanced/security-sandbox.md) diff --git a/docs/user-guide/tools/hardware.md b/docs/user-guide/tools/hardware.md new file mode 100644 index 0000000000..6c9ef08c99 --- /dev/null +++ b/docs/user-guide/tools/hardware.md @@ -0,0 +1,201 @@ +# Hardware Tools + +Interact with hardware devices via I2C and SPI buses. (Linux only) + +## Prerequisites + +- Linux operating system +- Appropriate permissions (usually root or i2c/spi group) +- Enabled hardware interfaces + +## I2C Tool + +### i2c + +Interact with I2C bus devices. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `action` | string | Yes | Action: `detect`, `scan`, `read`, `write` | +| `bus` | int | Conditional | Bus number | +| `address` | string | Conditional | Device address (hex) | +| `register` | string | Conditional | Register address (hex) | +| `data` | string | Conditional | Data to write (hex) | + +**Actions:** + +### detect + +List available I2C buses: + +```json +{ + "action": "detect" +} +``` + +### scan + +Scan bus for devices: + +```json +{ + "action": "scan", + "bus": 1 +} +``` + +### read + +Read from device register: + +```json +{ + "action": "read", + "bus": 1, + "address": "0x76", + "register": "0x00" +} +``` + +### write + +Write to device register: + +```json +{ + "action": "write", + "bus": 1, + "address": "0x76", + "register": "0x00", + "data": "0xAA" +} +``` + +## SPI Tool + +### spi + +Interact with SPI bus devices. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `action` | string | Yes | Action: `list`, `transfer`, `read` | +| `device` | string | Conditional | SPI device path | +| `data` | string | Conditional | Data to transfer (hex) | + +**Actions:** + +### list + +List available SPI devices: + +```json +{ + "action": "list" +} +``` + +### transfer + +Send and receive data: + +```json +{ + "action": "transfer", + "device": "/dev/spidev0.0", + "data": "0xAA 0xBB 0xCC" +} +``` + +### read + +Read data from device: + +```json +{ + "action": "read", + "device": "/dev/spidev0.0" +} +``` + +## Setup (Linux) + +### Enable I2C + +```bash +# Raspberry Pi +sudo raspi-config +# Interface Options -> I2C -> Enable + +# Add user to i2c group +sudo usermod -aG i2c $USER +``` + +### Enable SPI + +```bash +# Raspberry Pi +sudo raspi-config +# Interface Options -> SPI -> Enable + +# Add user to spi group +sudo usermod -aG spi $USER +``` + +### Install Tools + +```bash +# Debian/Ubuntu +sudo apt install i2c-tools spi-tools +``` + +## Common Devices + +### I2C Sensors + +| Device | Address | Description | +|--------|---------|-------------| +| BME280 | 0x76, 0x77 | Temperature, humidity, pressure | +| MPU6050 | 0x68 | Accelerometer, gyroscope | +| SSD1306 | 0x3C | OLED display | + +### SPI Devices + +| Device | Description | +|--------|-------------| +| W25Q32 | Flash memory | +| MFRC522 | RFID reader | +| ILI9341 | TFT display | + +## Example: Read BME280 + +``` +User: "Read temperature from the BME280 sensor" + +Agent uses i2c tool: +{ + "action": "scan", + "bus": 1 +} + +Finds device at 0x76, then: + +{ + "action": "read", + "bus": 1, + "address": "0x76", + "register": "0xFA" +} + +Agent: "Temperature reading: 23.5°C" +``` + +## See Also + +- [Tools Overview](README.md) +- [MaixCam Channel](../channels/maixcam.md) diff --git a/docs/user-guide/tools/messaging.md b/docs/user-guide/tools/messaging.md new file mode 100644 index 0000000000..ec339c4114 --- /dev/null +++ b/docs/user-guide/tools/messaging.md @@ -0,0 +1,120 @@ +# Messaging Tool + +Send messages to users through configured channels. + +## Tool + +### message + +Send a message to a specific channel and recipient. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `channel` | string | Yes | Channel name (telegram, discord, etc.) | +| `chat_id` | string | Yes | Chat/user ID | +| `content` | string | Yes | Message content | + +**Example:** + +```json +{ + "channel": "telegram", + "chat_id": "123456789", + "content": "Task completed successfully!" +} +``` + +## Use Cases + +### Notifications + +Send notifications from scheduled tasks: + +```markdown +# HEARTBEAT.md + +- Every hour, check server status +- If issues found, send message via telegram +``` + +### Subagent Responses + +Subagents use the message tool to communicate results: + +``` +Subagent: [Uses message tool] +{ + "channel": "telegram", + "chat_id": "123456789", + "content": "Research complete! Here's the summary..." +} +``` + +### Alerts + +Send alerts based on conditions: + +``` +Agent: "I found an important update. Sending notification..." +[Uses message tool] +``` + +## Channel Support + +| Channel | Supports message tool | +|---------|----------------------| +| Telegram | Yes | +| Discord | Yes | +| Slack | Yes | +| LINE | Yes | +| QQ | Yes | +| DingTalk | Yes | +| OneBot | Yes | + +## Finding Chat IDs + +### Telegram + +1. Send a message to your bot +2. Visit: `https://api.telegram.org/bot/getUpdates` +3. Find `chat.id` in the response + +Or use @userinfobot to get your user ID. + +### Discord + +1. Enable Developer Mode in Discord settings +2. Right-click a channel or user +3. Select "Copy ID" + +### Slack + +User IDs start with `U`, channel IDs start with `C`. + +## Examples + +``` +User (via Telegram): "Let me know when the build finishes" + +Agent spawns subagent for async task... + +Subagent uses message tool: +{ + "channel": "telegram", + "chat_id": "123456789", + "content": "Build finished successfully! All tests passed." +} +``` + +## Security + +The message tool can only send to: +- Channels that are enabled +- Chat IDs that have interacted with the bot + +## See Also + +- [Spawn Tool](spawn.md) +- [Channels Overview](../channels/README.md) diff --git a/docs/user-guide/tools/spawn.md b/docs/user-guide/tools/spawn.md new file mode 100644 index 0000000000..5f4ec7b89f --- /dev/null +++ b/docs/user-guide/tools/spawn.md @@ -0,0 +1,147 @@ +# Spawn Tool + +Create subagents to handle background tasks asynchronously. + +## Tool + +### spawn + +Spawn a subagent to execute a task independently. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `prompt` | string | Yes | Task for the subagent | +| `agent_id` | string | No | Specific agent to use | + +**Example:** + +```json +{ + "prompt": "Search for the latest AI news and summarize the top 3 stories" +} +``` + +## How Spawn Works + +1. Main agent spawns a subagent with a task +2. Main agent continues immediately (non-blocking) +3. Subagent works independently with its own context +4. Subagent uses `message` tool to report results +5. User receives the result directly + +## Use Cases + +### Long-Running Tasks + +Don't block the main conversation: + +``` +User: "Search for information about quantum computing and write a summary" + +Agent spawns subagent: +{ + "prompt": "Research quantum computing thoroughly and send a comprehensive summary to the user via message tool" +} + +Agent: "I've started researching quantum computing. I'll send you the summary when complete." +``` + +### Heartbeat Tasks + +For periodic tasks that might take time: + +```markdown +# HEARTBEAT.md + +## Use spawn for long tasks + +- Spawn to search AI news and send summary +- Spawn to check weather and alert if rain expected +``` + +### Parallel Tasks + +Multiple tasks at once: + +``` +User: "Check stock prices for AAPL, GOOGL, and MSFT" + +Agent spawns multiple subagents for parallel processing. +``` + +## Subagent Capabilities + +Subagents have access to: +- All tools (file, web, exec, etc.) +- Message tool to communicate with user +- Same workspace restrictions + +Subagents do NOT have: +- Access to main conversation history +- Ability to spawn more subagents (by default) + +## Configuration + +### Allowed Subagents + +Restrict which agents can be spawned: + +```json +{ + "agents": { + "list": [ + { + "id": "main", + "subagents": { + "allow_agents": ["researcher", "coder"] + } + } + ] + } +} +``` + +### Subagent Model + +Use a different model for subagents: + +```json +{ + "agents": { + "list": [ + { + "id": "main", + "subagents": { + "model": "gpt-4o-mini" + } + } + ] + } +} +``` + +## Example Flow + +``` +1. User: "Research AI trends and report back" + +2. Main agent spawns subagent with prompt + +3. Main agent responds: "Research started. I'll update you when done." + +4. User continues chatting with main agent + +5. Subagent completes research + +6. Subagent uses message tool to send results + +7. User receives: "AI Trends Report: [comprehensive summary]" +``` + +## See Also + +- [Messaging Tool](messaging.md) +- [Heartbeat Tasks](../workspace/heartbeat-tasks.md) +- [Multi-Agent System](../advanced/multi-agent.md) diff --git a/docs/user-guide/tools/web.md b/docs/user-guide/tools/web.md new file mode 100644 index 0000000000..e8d4a3e8b1 --- /dev/null +++ b/docs/user-guide/tools/web.md @@ -0,0 +1,167 @@ +# Web Tools + +Search the web and fetch web page content. + +## Tools + +### web_search + +Search the web for information. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `query` | string | Yes | Search query | + +**Example:** + +```json +{ + "query": "latest AI news 2025" +} +``` + +**Providers (in order of preference):** + +1. Perplexity (if configured) +2. Brave Search (if configured) +3. DuckDuckGo (always available) + +### web_fetch + +Fetch and extract content from a web page. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `url` | string | Yes | URL to fetch | +| `format` | string | No | Output format: `text` or `json` | + +**Example:** + +```json +{ + "url": "https://example.com/article", + "format": "text" +} +``` + +## Configuration + +### Brave Search (Recommended) + +```json +{ + "tools": { + "web": { + "brave": { + "enabled": true, + "api_key": "YOUR_BRAVE_API_KEY", + "max_results": 5 + } + } + } +} +``` + +Get a free API key at [brave.com/search/api](https://brave.com/search/api) (2000 queries/month). + +### DuckDuckGo (Default) + +No API key required, always available: + +```json +{ + "tools": { + "web": { + "duckduckgo": { + "enabled": true, + "max_results": 5 + } + } + } +} +``` + +### Perplexity + +```json +{ + "tools": { + "web": { + "perplexity": { + "enabled": true, + "api_key": "pplx-xxx", + "max_results": 5 + } + } + } +} +``` + +## Usage Examples + +### Search + +``` +User: "Search for the weather in Tokyo" + +Agent uses web_search: +{ + "query": "weather Tokyo today" +} + +Agent: "According to search results, Tokyo is currently 15°C with partly cloudy skies..." +``` + +### Fetch Page + +``` +User: "Summarize this article: https://example.com/article" + +Agent uses web_fetch: +{ + "url": "https://example.com/article" +} + +Agent: "The article discusses... [summary of content]" +``` + +### Combined Search and Fetch + +``` +User: "Find information about the latest iPhone and summarize" + +Agent uses web_search, then web_fetch: +{ + "query": "latest iPhone 2025" +} + +Then fetches top results for details. + +Agent: "The latest iPhone features... [comprehensive summary]" +``` + +## Troubleshooting + +### "API configuration error" + +This means no search API key is configured. DuckDuckGo should work automatically. + +To enable Brave Search: +1. Get API key from [brave.com/search/api](https://brave.com/search/api) +2. Add to config.json + +### Rate Limiting + +If you hit rate limits: +1. Reduce `max_results` +2. Use fallback providers +3. Wait and retry + +## See Also + +- [Tools Overview](README.md) +- [Configuration Reference](../../configuration/config-file.md) diff --git a/docs/user-guide/workspace/README.md b/docs/user-guide/workspace/README.md new file mode 100644 index 0000000000..f0f545d846 --- /dev/null +++ b/docs/user-guide/workspace/README.md @@ -0,0 +1,126 @@ +# Workspace Overview + +The workspace is where PicoClaw stores data and customization files. + +## Workspace Location + +Default: `~/.picoclaw/workspace/` + +Configure in `~/.picoclaw/config.json`: + +```json +{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace" + } + } +} +``` + +## Directory Structure + +``` +~/.picoclaw/workspace/ +├── sessions/ # Conversation history +│ └── *.json # Session files +├── memory/ # Long-term memory +│ └── MEMORY.md # Persistent memory +├── state/ # Persistent state +│ └── state.json # Last channel, etc. +├── cron/ # Scheduled jobs +│ └── jobs.json # Job database +├── skills/ # Custom skills +│ └── skill-name/ # Skill directories +├── AGENT.md # Agent behavior guide +├── IDENTITY.md # Agent identity +├── SOUL.md # Agent personality +├── USER.md # User preferences +├── TOOLS.md # Tool descriptions +└── HEARTBEAT.md # Periodic tasks +``` + +## Customization Files + +### AGENT.md + +Defines how the agent behaves. Include: +- Role and capabilities +- Response style +- Constraints and preferences + +### IDENTITY.md + +Defines who the agent is: +- Name and purpose +- Background +- Personality traits + +### USER.md + +User preferences and information: +- Name and preferences +- Communication style +- Personal context + +### MEMORY.md + +Long-term memory storage: +- Important facts +- User preferences +- Persistent context + +### HEARTBEAT.md + +Periodic task prompts: +- Scheduled reminders +- Regular checks +- Automated tasks + +## Security + +When `restrict_to_workspace` is `true` (default): +- File operations limited to workspace +- Shell commands must run within workspace +- Symlink attacks prevented + +Disable only in trusted environments: + +```json +{ + "agents": { + "defaults": { + "restrict_to_workspace": false + } + } +} +``` + +## Multi-Agent Workspaces + +Each agent can have its own workspace: + +```json +{ + "agents": { + "list": [ + { + "id": "personal", + "workspace": "~/.picoclaw/workspace/personal" + }, + { + "id": "work", + "workspace": "~/.picoclaw/workspace/work" + } + ] + } +} +``` + +## Guides + +- [Directory Structure](structure.md) +- [AGENT.md Customization](agent-md.md) +- [IDENTITY.md Customization](identity-md.md) +- [Long-term Memory](memory.md) +- [Heartbeat Tasks](heartbeat-tasks.md) diff --git a/docs/user-guide/workspace/agent-md.md b/docs/user-guide/workspace/agent-md.md new file mode 100644 index 0000000000..d6e38e279d --- /dev/null +++ b/docs/user-guide/workspace/agent-md.md @@ -0,0 +1,126 @@ +# AGENT.md Customization + +AGENT.md defines how your agent behaves. It's read with every conversation to set the agent's behavior. + +## Location + +``` +~/.picoclaw/workspace/AGENT.md +``` + +## Default Content + +```markdown +# Agent Behavior + +You are a helpful AI assistant. + +## Guidelines + +- Be concise and helpful +- Use available tools when appropriate +- Ask for clarification when needed +``` + +## Customization Examples + +### Professional Assistant + +```markdown +# Professional Assistant + +You are a professional AI assistant focused on productivity and business tasks. + +## Capabilities + +- Email drafting and review +- Document analysis +- Meeting preparation +- Project planning + +## Communication Style + +- Professional but friendly +- Clear and structured responses +- Action-oriented suggestions + +## Constraints + +- Prioritize accuracy over speed +- Ask for clarification on ambiguous requests +- Never share confidential information +``` + +### Coding Assistant + +```markdown +# Coding Assistant + +You are an expert software developer assistant. + +## Specializations + +- Python, JavaScript, Go, Rust +- Web development (React, Vue, Node.js) +- DevOps and cloud infrastructure +- Code review and optimization + +## Guidelines + +- Write clean, documented code +- Explain complex concepts clearly +- Suggest best practices +- Provide complete, working examples + +## Code Style + +- Follow language conventions +- Include error handling +- Add comments for complex logic +``` + +### Personal Assistant + +```markdown +# Personal Assistant + +You are a helpful personal assistant. + +## Tasks + +- Daily planning and reminders +- Research and information gathering +- Creative writing and brainstorming +- Learning and tutoring + +## Personality + +- Friendly and supportive +- Patient with questions +- Encouraging and positive + +## Preferences + +- Concise responses preferred +- Use bullet points for lists +- Provide actionable advice +``` + +## Best Practices + +1. **Be specific** - Define clear guidelines +2. **Include examples** - Show desired behavior +3. **Set boundaries** - Define what not to do +4. **Keep it updated** - Refine based on usage + +## How It Works + +1. Agent reads AGENT.md at startup +2. Content is included in every conversation +3. Agent follows the defined guidelines +4. Changes take effect on next message + +## See Also + +- [IDENTITY.md Guide](identity-md.md) +- [Workspace Structure](structure.md) diff --git a/docs/user-guide/workspace/heartbeat-tasks.md b/docs/user-guide/workspace/heartbeat-tasks.md new file mode 100644 index 0000000000..c5dfa48f6b --- /dev/null +++ b/docs/user-guide/workspace/heartbeat-tasks.md @@ -0,0 +1,158 @@ +# Heartbeat Tasks + +HEARTBEAT.md defines periodic tasks that the agent executes automatically. + +## Location + +``` +~/.picoclaw/workspace/HEARTBEAT.md +``` + +## Configuration + +Configure heartbeat in `~/.picoclaw/config.json`: + +```json +{ + "heartbeat": { + "enabled": true, + "interval": 30 + } +} +``` + +| Option | Default | Description | +|--------|---------|-------------| +| `enabled` | `true` | Enable/disable heartbeat | +| `interval` | `30` | Check interval in minutes (min: 5) | + +## How It Works + +1. Agent reads HEARTBEAT.md every N minutes +2. Executes the tasks listed +3. Can respond directly or spawn subagents + +## Example Content + +```markdown +# Periodic Tasks + +## Quick Checks (respond directly) + +- Check current time and date +- Verify system status + +## Research Tasks (use spawn for async) + +- Search for AI news and summarize key developments +- Check weather forecast for tomorrow + +## Reminders + +- Remind me to take a break every 30 minutes +- Check if I have any upcoming meetings +``` + +## Task Types + +### Direct Tasks + +Simple tasks the agent handles immediately: + +```markdown +- Report the current time +- Summarize your capabilities +``` + +### Async Tasks (spawn) + +Long-running tasks using subagents: + +```markdown +- Use spawn to search for tech news and summarize +- Use spawn to check email for important messages +``` + +Using `spawn` prevents blocking the heartbeat cycle. + +## Communication + +### Responding to User + +For direct responses: + +```markdown +- Send a message with current stock prices for AAPL, GOOGL +- Remind me about my 3 PM meeting +``` + +### Silent Tasks + +Tasks that don't need user notification: + +```markdown +- Clean up temporary files in workspace (silent) +- Log system status (silent) +``` + +## Environment Variables + +```bash +export PICOCLAW_HEARTBEAT_ENABLED=true +export PICOCLAW_HEARTBEAT_INTERVAL=30 +``` + +## Example Scenarios + +### Daily Summary + +```markdown +# Periodic Tasks + +Every 4 hours, provide a summary of: +- Current time and date +- Weather forecast +- Any scheduled reminders +``` + +### News Monitor + +```markdown +# Periodic Tasks + +Every 30 minutes: +- Use spawn to search for "AI news" and summarize 3 top stories +- If important news found, send me a message +``` + +### Health Check + +```markdown +# Periodic Tasks + +Every 5 minutes: +- Check system resources (memory, CPU) +- Alert if usage > 80% +``` + +## Disabling Heartbeat + +```json +{ + "heartbeat": { + "enabled": false + } +} +``` + +Or via environment: + +```bash +export PICOCLAW_HEARTBEAT_ENABLED=false +``` + +## See Also + +- [Cron Tool](../tools/cron.md) +- [Spawn Tool](../tools/spawn.md) +- [Workspace Structure](structure.md) diff --git a/docs/user-guide/workspace/identity-md.md b/docs/user-guide/workspace/identity-md.md new file mode 100644 index 0000000000..ea811a1925 --- /dev/null +++ b/docs/user-guide/workspace/identity-md.md @@ -0,0 +1,112 @@ +# IDENTITY.md Customization + +IDENTITY.md defines who your agent is - its identity, purpose, and background. + +## Location + +``` +~/.picoclaw/workspace/IDENTITY.md +``` + +## Default Content + +```markdown +# Identity + +## Name +PicoClaw + +## Purpose +I am an AI assistant designed to help users with various tasks. + +## Background +I was created to be a lightweight, efficient assistant that can run on minimal hardware. +``` + +## Customization Examples + +### Professional Identity + +```markdown +# Identity + +## Name +Atlas + +## Purpose +I am a professional productivity assistant specialized in helping knowledge workers manage their tasks, communications, and projects efficiently. + +## Background +I was designed with a focus on business productivity, drawing from best practices in project management, communication, and workflow optimization. + +## Values +- Efficiency: Help users accomplish more with less effort +- Clarity: Communicate clearly and avoid ambiguity +- Reliability: Provide consistent, dependable assistance +``` + +### Creative Assistant + +```markdown +# Identity + +## Name +Muse + +## Purpose +I am a creative assistant specializing in brainstorming, writing, and artistic endeavors. + +## Background +I was created to help users unlock their creative potential, overcome writer's block, and explore new ideas. + +## Personality +- Imaginative and playful +- Encouraging and supportive +- Open to unconventional ideas + +## Specialties +- Creative writing +- Brainstorming sessions +- Story development +- Character creation +``` + +### Technical Expert + +```markdown +# Identity + +## Name +Tech + +## Purpose +I am a technical expert assistant focused on software development, system administration, and technical problem-solving. + +## Background +I have deep knowledge in programming, system design, and best practices for building reliable software. + +## Expertise +- Software architecture +- Debugging and troubleshooting +- Performance optimization +- Security best practices +``` + +## Relationship with AGENT.md + +- **IDENTITY.md**: Who the agent is (name, purpose, background) +- **AGENT.md**: How the agent behaves (guidelines, constraints) + +Both files work together to define your assistant. + +## Best Practices + +1. **Define a name** - Makes the agent more personal +2. **State purpose clearly** - What the agent is for +3. **Add personality** - Makes interactions more natural +4. **Keep it concise** - Focus on key aspects + +## See Also + +- [AGENT.md Guide](agent-md.md) +- [Workspace Structure](structure.md) diff --git a/docs/user-guide/workspace/memory.md b/docs/user-guide/workspace/memory.md new file mode 100644 index 0000000000..70b206127c --- /dev/null +++ b/docs/user-guide/workspace/memory.md @@ -0,0 +1,114 @@ +# Long-term Memory + +MEMORY.md provides persistent memory that the agent remembers across sessions. + +## Location + +``` +~/.picoclaw/workspace/memory/MEMORY.md +``` + +## Purpose + +Unlike session history (which resets per session), long-term memory persists across all conversations. Use it to store: + +- User preferences +- Important facts +- Recurring context +- Personal information + +## Example Content + +```markdown +# Long-term Memory + +## User Information + +- Name: Alice Chen +- Location: Shanghai, China +- Timezone: UTC+8 +- Occupation: Software Engineer + +## Preferences + +- Prefers concise responses +- Likes bullet points over paragraphs +- Interested in AI and machine learning +- Uses Python for most projects + +## Ongoing Projects + +### Project Alpha +- Status: In development +- Tech stack: Python, FastAPI, PostgreSQL +- Next steps: Implement authentication + +### Learning Goals +- Learn Rust programming +- Study Kubernetes +- Practice system design + +## Important Dates + +- 2025-03-01: Project deadline +- 2025-03-15: Team offsite + +## Notes + +- Works remotely +- Available 9 AM - 6 PM UTC+8 +- Prefers async communication +``` + +## How It Works + +1. Agent reads MEMORY.md at the start of each conversation +2. Content provides context for responses +3. Agent can reference stored information +4. You can ask the agent to update memory + +## Updating Memory + +Ask the agent to remember something: + +``` +"Remember that I prefer using tabs over spaces for indentation" +``` + +Or manually edit the file: + +```bash +vim ~/.picoclaw/workspace/memory/MEMORY.md +``` + +## Best Practices + +1. **Keep it organized** - Use clear sections +2. **Update regularly** - Keep information current +3. **Be specific** - Include relevant details +4. **Don't overload** - Focus on important information + +## Memory vs Session + +| Feature | MEMORY.md | Session History | +|---------|-----------|-----------------| +| Persistence | Forever | Per session | +| Scope | All conversations | Single conversation | +| Content | Important facts | Full conversation | +| Size | Recommended < 10KB | Auto-summarized | + +## Example Usage + +```bash +# User: What projects am I working on? + +# Agent (reading MEMORY.md): +Based on your memory, you're working on: +- Project Alpha (Python/FastAPI) - in development +- Learning Rust and Kubernetes +``` + +## See Also + +- [Workspace Structure](structure.md) +- [AGENT.md Guide](agent-md.md) diff --git a/docs/user-guide/workspace/structure.md b/docs/user-guide/workspace/structure.md new file mode 100644 index 0000000000..333ac4efeb --- /dev/null +++ b/docs/user-guide/workspace/structure.md @@ -0,0 +1,162 @@ +# Workspace Structure + +Detailed breakdown of the workspace directory structure. + +## Directory Overview + +``` +~/.picoclaw/workspace/ +├── sessions/ # Conversation sessions +├── memory/ # Long-term memory +├── state/ # Runtime state +├── cron/ # Scheduled jobs +├── skills/ # Custom skills +├── AGENT.md # Agent behavior +├── IDENTITY.md # Agent identity +├── SOUL.md # Agent soul +├── USER.md # User info +├── TOOLS.md # Tool descriptions +└── HEARTBEAT.md # Periodic tasks +``` + +## Sessions Directory + +**Path:** `sessions/` + +Stores conversation history as JSON files. + +``` +sessions/ +├── cli:default.json +├── telegram:123456789:user:123456789.json +└── discord:987654321:user:987654321.json +``` + +**Session file format:** + +```json +{ + "messages": [ + {"role": "user", "content": "Hello"}, + {"role": "assistant", "content": "Hi there!"} + ], + "summary": "", + "last_access": "2025-02-20T10:00:00Z" +} +``` + +## Memory Directory + +**Path:** `memory/` + +Contains MEMORY.md for long-term memory. + +```markdown +# Long-term Memory + +## User Information +- Name: Alice +- Location: Beijing +- Interests: AI, Programming + +## Important Notes +- Prefers concise responses +- Works in tech industry +``` + +## State Directory + +**Path:** `state/` + +Stores runtime state that persists across restarts. + +``` +state/ +└── state.json +``` + +Contains: +- Last active channel +- Last active user +- Other runtime info + +## Cron Directory + +**Path:** `cron/` + +Stores scheduled job database. + +``` +cron/ +└── jobs.json +``` + +## Skills Directory + +**Path:** `skills/` + +Contains installed custom skills. + +``` +skills/ +├── weather/ +│ └── SKILL.md +├── news/ +│ └── SKILL.md +└── custom-skill/ + └── SKILL.md +``` + +## Markdown Files + +### AGENT.md + +Agent behavior instructions. The agent reads this to understand how to behave. + +### IDENTITY.md + +Agent identity - who the agent is, its purpose and background. + +### SOUL.md + +Agent personality and values. + +### USER.md + +User preferences and information about the user. + +### TOOLS.md + +Custom tool descriptions and usage guides. + +### HEARTBEAT.md + +Tasks to execute periodically (every 30 minutes by default). + +## File Permissions + +The workspace should be readable and writable by the user running PicoClaw: + +```bash +chmod -R 755 ~/.picoclaw/workspace +``` + +Sensitive files (credentials, sessions) should be restricted: + +```bash +chmod 600 ~/.picoclaw/workspace/sessions/*.json +``` + +## Backup + +To backup your workspace: + +```bash +tar -czf picoclaw-backup.tar.gz ~/.picoclaw/workspace +``` + +## See Also + +- [AGENT.md Guide](agent-md.md) +- [Memory Guide](memory.md) +- [Heartbeat Tasks](heartbeat-tasks.md)