# Discord Source: https://docs.openpawz.ai/channels/discord Connect a Discord bot to your Pawz agents. # Discord Connect a Discord bot to your Pawz agents. ## Setup 1. Go to the [Discord Developer Portal](https://discord.com/developers/applications) 2. Create a new application 3. Go to **Bot** → create a bot → copy the token 4. Enable **Message Content Intent** under Privileged Gateway Intents 5. Invite the bot to your server with the OAuth2 URL generator (scopes: `bot`, permissions: `Send Messages`, `Read Message History`) 6. Copy your **Server (Guild) ID**: enable Developer Mode in Discord → Settings → App Settings → Advanced, then right-click the server name and select **Copy Server ID** 7. In Pawz, go to **Settings → Channels** 8. Select **Discord** 9. Paste your **Bot Token** and **Server ID** 10. Start the channel ## Configuration | Field | Required | Description | | ----------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bot token | Yes | From Discord Developer Portal | | Server (Guild) ID | No | Right-click your server → Copy Server ID (enable Developer Mode first). Needed for server management features like listing channels, roles, and members. | | DM policy | Yes | Who can message the bot | | Allowed users | For allowlist | Discord usernames | ## Features * DMs and server channel messages * Per-user sessions with memory * Long messages auto-split for Discord's 2000 char limit * Prompt injection scanning * Agent routing via channel routing rules ## Routing Route specific channels or users to different agents using routing rules: * **Channel ID filter** — route messages from specific Discord channels * **User filter** — route messages from specific users ## Tips * Use `DISCORD_BOT_TOKEN` in the Skills vault if you also want agents to send messages proactively via the Discord skill * The bot responds to mentions and DMs by default # Discourse Source: https://docs.openpawz.ai/channels/discourse Connect your agent to a Discourse community forum. # Discourse Connect your agent to a Discourse forum. Your agent monitors topics, replies to posts, and can create new threads — perfect for community support, FAQ automation, and engagement. ## Setup 1. Create a **dedicated bot account** on your Discourse forum (e.g., `paw-bot`) 2. As an admin, go to **Admin → API → New API Key** 3. Set the scope to **Single User** and select the bot account 4. Copy the API key 5. In Pawz, go to **Settings → Channels** 6. Select **Discourse** 7. Enter: * **Forum URL** — e.g., `https://community.example.com` * **API Key** — from step 4 * **Bot Username** — the bot account username 8. Start the channel ## Configuration | Field | Required | Description | | --------------------- | -------- | ------------------------------------------------------------- | | Forum URL | Yes | Your Discourse instance URL (no trailing slash) | | API Key | Yes | Admin-generated API key scoped to the bot user | | Bot Username | Yes | The Discourse username the API key is scoped to | | Categories to Monitor | No | Comma-separated category slugs (blank = all categories) | | Reply to Topics | Yes | Whether the agent auto-replies to new topics | | Create Topics | No | Whether the agent can create new topics | | Poll Interval | No | How often to check for new posts (default: 30s, minimum: 10s) | ## Connection Pawz connects via Discourse's **REST API**, polling for new posts at the configured interval. The bot authenticates using the API key + username headers on every request. No inbound webhooks or public URLs are needed — this is a fully outbound connection. ### API Key Setup (Step-by-Step) 1. Log in to your Discourse forum as an **admin** 2. Navigate to `/admin/api/keys` 3. Click **New API Key** 4. Description: `Paw Agent Bot` 5. User Level: **Single User** → select your bot account 6. Click **Save** 7. Copy the key (you won't see it again) Use a **Single User** scope rather than a global API key. This limits the bot to actions the bot account is allowed to perform. ## Features * **Topic monitoring** — watches categories for new topics and replies * **Auto-reply** — responds to posts with context-aware answers * **Topic creation** — agent can create new discussion threads (opt-in) * **Category filtering** — monitor specific categories or all categories * **Per-user sessions** — persistent memory across conversations with each user * **Thread context** — reads the full topic thread before replying for context * **Prompt injection scanning** on all incoming posts * **Agent routing** — assign a specific agent to handle Discourse ## Discourse Bot Account Tips * Create a dedicated bot account (`paw-bot`) rather than using your admin account * Set the bot's **trust level** to at least **1 (Basic)** so it can post without restrictions * Add a clear **bio** like "I'm an AI assistant powered by Pawz" for transparency * Upload a recognizable **avatar** (the Pawz logo works great) * Consider setting the bot as a **moderator** if you want it to manage categories ## Troubleshooting | Problem | Fix | | ----------------------- | ----------------------------------------------------------------------------------- | | 403 Forbidden | API key may be expired or scoped to wrong user — regenerate it in Admin → API | | Bot doesn't reply | Check that "Reply to Topics" is enabled and the bot account has posting permissions | | Posts in wrong category | Verify category slugs match exactly (case-sensitive, use hyphens not spaces) | | Rate limited | Increase the poll interval (Discourse default rate limit is 60 req/min) | | Bot replies to itself | Bot username must match exactly — the agent filters out its own posts | | Connection timeout | Verify the forum URL is correct and accessible from your machine | ## Category Slugs Category slugs are the URL-safe versions of category names. For example: | Category Name | Slug | | ------------------ | -------------------- | | General Discussion | `general-discussion` | | Support | `support` | | Feature Requests | `feature-requests` | Find slugs by navigating to a category — the slug is the last part of the URL: `https://community.example.com/c/support/5` → slug is `support` # IRC Source: https://docs.openpawz.ai/channels/irc Connect to IRC networks so users can chat with your agents in IRC channels. # IRC Connect to IRC networks so users can chat with your agents in IRC channels. ## Setup 1. Choose an IRC network (Libera.Chat, OFTC, etc.) 2. In Pawz, go to **Settings → Channels** 3. Select **IRC** 4. Enter: * **Server** — e.g., `irc.libera.chat` * **Port** — typically `6697` (TLS) or `6667` (plain) * **Nickname** — bot's IRC nick * **Channels** — comma-separated channels to join (e.g., `#pawz,#general`) * **Use TLS** — enable for encrypted connections 5. Start the channel ## Configuration | Field | Required | Description | | --------- | ----------- | --------------------------- | | Server | Yes | IRC server hostname | | Port | Yes | Server port | | Nickname | Yes | Bot's nick | | Channels | Yes | Channels to join | | Use TLS | Recommended | Enable TLS encryption | | Password | No | NickServ or server password | | DM policy | Yes | Who can DM the bot | ## Features * Channel messages and private messages * Per-user sessions with memory * Prompt injection scanning * Agent routing via channel routing rules * Auto-reconnect on disconnection ## Tips * Register your bot's nick with NickServ to prevent impersonation * Use TLS (port 6697) for encrypted connections * The bot responds when mentioned by nick or in DMs # Matrix Source: https://docs.openpawz.ai/channels/matrix Connect to a Matrix homeserver so users can chat with your agents via any Matrix client (Element, FluffyChat, etc.). # Matrix Connect to a Matrix homeserver so users can chat with your agents via any Matrix client (Element, FluffyChat, etc.). ## Setup 1. Create a bot account on your Matrix homeserver 2. Note the homeserver URL, username, and password 3. In Pawz, go to **Settings → Channels** 4. Select **Matrix** 5. Enter: * **Homeserver URL** — e.g., `https://matrix.org` * **Username** — bot's Matrix ID (e.g., `@pawz-bot:matrix.org`) * **Password** — bot account password 6. Start the channel ## Configuration | Field | Required | Description | | -------------- | ------------- | ----------------------- | | Homeserver URL | Yes | Matrix server URL | | Username | Yes | Bot's Matrix user ID | | Password | Yes | Bot account password | | DM policy | Yes | Who can message the bot | | Allowed users | For allowlist | Matrix user IDs | ## Features * DMs and room messages * Per-user sessions with memory * Prompt injection scanning * Agent routing via channel routing rules * Auto-join on invite :::info End-to-end encryption supported The Matrix bridge uses `matrix-sdk` with **vodozemac** for Olm/Megolm encryption. Messages in E2EE rooms are automatically decrypted and replies are automatically encrypted. Device keys and room sessions are persisted in a local SQLite crypto store (`~/Documents/Paw/matrix-store/`), so key continuity is maintained across restarts. ::: ## Community Room OpenPawz has an official Matrix room for support, feedback, and general discussion: **[#openpawz:matrix.org](https://matrix.to/#/#openpawz:matrix.org)** Join via [Element](https://app.element.io/#/room/#openpawz:matrix.org) or any Matrix client. ## Tips * For self-hosted Matrix (Synapse, Dendrite), use your server's URL * Invite the bot to rooms where you want it active * Use Element or any Matrix client to test # Mattermost Source: https://docs.openpawz.ai/channels/mattermost Connect to a self-hosted Mattermost instance. # Mattermost Connect to a self-hosted Mattermost instance. Since Mattermost is self-hosted, all data stays within your infrastructure — combined with Pawz's local-first architecture, no data ever leaves your network. ## Setup 1. In your Mattermost admin panel, go to **Integrations → Bot Accounts** and create a bot 2. Copy the bot token 3. In Pawz, go to **Settings → Channels** 4. Select **Mattermost** 5. Enter: * **Server URL** — e.g., `https://mattermost.yourcompany.com` * **Bot token** — from Mattermost admin 6. Start the channel ## Configuration | Field | Required | Description | | ------------- | ------------- | ----------------------------------------------------- | | Server URL | Yes | Mattermost instance URL | | Bot token | Yes | Bot access token | | DM policy | Yes | Who can message the bot (open, allowlist, or pairing) | | Allowed users | For allowlist | Mattermost usernames | ## Connection Pawz connects via Mattermost's **WebSocket API** for real-time message delivery. The bot authenticates using the bot token and listens for new posts in channels it's been added to, as well as direct messages. ## Features * **DMs and channel messages** via WebSocket (real-time, no polling) * **Thread support** — replies stay in the correct thread context * **Per-user sessions** with persistent memory across conversations * **Prompt injection scanning** on all incoming messages * **Agent routing** via channel routing rules — different agents for different channels * **Channel-specific context** — lean context strategy for fast, low-cost responses ## Troubleshooting | Problem | Fix | | -------------------------------- | ----------------------------------------------------------------------------------------------- | | Bot can't connect | Verify the server URL includes the protocol (`https://`) and the bot token is valid | | Bot doesn't respond in a channel | Add the bot to the channel via the Mattermost UI (invite to channel) | | Messages delayed | Check Mattermost WebSocket health in admin panel → **System Console → Environment → WebSocket** | | Authentication fails | Ensure bot accounts are enabled in **System Console → Integrations → Bot Accounts** | ## Tips :::tip * **Self-hosted = full control** — Mattermost runs on your infrastructure, matching Pawz's privacy-first approach. * **Use channel routing** to assign different agents to different Mattermost channels (e.g., `#dev` → coding agent, `#support` → customer agent). * **Bot tokens don't expire** — unlike user sessions, bot tokens remain valid until explicitly revoked. ::: # Nextcloud Source: https://docs.openpawz.ai/channels/nextcloud Connect to Nextcloud Talk so users on your Nextcloud instance can chat with Pawz agents. # Nextcloud Connect to Nextcloud Talk so users on your Nextcloud instance can chat with Pawz agents. Like Mattermost, Nextcloud is self-hosted — your conversations never leave your server. ## Setup 1. Create a dedicated bot user on your Nextcloud instance (admin panel → **Users**) 2. Generate an **app password** for the bot user (user settings → **Security → Devices & sessions**) 3. In Pawz, go to **Settings → Channels** 4. Select **Nextcloud** 5. Enter: * **Server URL** — e.g., `https://cloud.yourcompany.com` * **Username** — Nextcloud bot user * **Password** — app password (not the main password) 6. Start the channel ## Configuration | Field | Required | Description | | ------------- | ------------- | ----------------------------------------------------- | | Server URL | Yes | Nextcloud instance URL | | Username | Yes | Bot account username | | Password | Yes | App password for the bot account | | DM policy | Yes | Who can message the bot (open, allowlist, or pairing) | | Allowed users | For allowlist | Nextcloud usernames | ## How it works Pawz polls the Nextcloud Talk API for new messages. When a message arrives in a conversation the bot has joined, it's processed through the agent pipeline — prompt injection scan → agent routing → response → reply posted back to the conversation. ## Features * **Nextcloud Talk conversations and DMs** — the bot participates in any conversation it's invited to * **Group conversations** — the bot can respond in group chats when mentioned or when DM policy allows * **Per-user sessions** with persistent memory across conversations * **Prompt injection scanning** on all incoming messages * **Agent routing** via channel routing rules * **Channel-specific context** — lean context for fast, affordable responses ## Troubleshooting | Problem | Fix | | ------------------------ | ------------------------------------------------------------------------------------------------ | | Authentication fails | Use an **app password**, not the user's main password. Generate one in user settings → Security. | | Bot doesn't see messages | Invite the bot user to the Talk conversation first | | Connection refused | Verify the server URL is correct and includes `https://`. Check that Nextcloud Talk is enabled. | | Slow responses | Nextcloud Talk uses polling (not WebSocket). Response time depends on poll interval. | ## Tips :::tip * **Always use an app password** instead of the main account password — it's more secure and can be revoked independently. * **The bot joins conversations when invited** — add it to specific Talk rooms via the Nextcloud UI. * **Ideal for organizations already on Nextcloud** — no additional infrastructure needed, just add a bot user. ::: # Nostr Source: https://docs.openpawz.ai/channels/nostr Connect to the Nostr decentralized network so users can chat with your agents via any Nostr client. # Nostr Connect to the Nostr decentralized network so users can chat with your agents via any Nostr client. ## Setup 1. Generate a Nostr keypair for your bot (or use an existing one) 2. In Pawz, go to **Settings → Channels** 3. Select **Nostr** 4. Enter: * **Private key** — bot's nsec key * **Relays** — comma-separated relay URLs (e.g., `wss://relay.damus.io,wss://nos.lol`) 5. Start the channel ## Configuration | Field | Required | Description | | ------------- | ------------- | ------------------------------ | | Private key | Yes | Bot's Nostr private key (nsec) | | Relays | Yes | Relay URLs to connect to | | DM policy | Yes | Who can message the bot | | Allowed users | For allowlist | Nostr public keys (npub) | ## Features * Public kind-1 text note replies (NIP-01) * NIP-04 encrypted direct messages (kind-4) * Per-user sessions with memory * Prompt injection scanning * Agent routing via channel routing rules * Multi-relay support * BIP-340 Schnorr-signed events * ECDH shared secret + AES-256-CBC encryption for DMs :::info Encrypted DM support The bridge supports **NIP-04 encrypted DMs** (kind-4 events) using ECDH + AES-256-CBC. This is compatible with all major Nostr clients (Damus, Amethyst, Primal, etc.). NIP-44 (the newer encryption standard with NIP-17 gift wrapping) is planned for a future release. ::: ### Roadmap | Feature | Status | | --------------------------------------- | ------------- | | NIP-04 encrypted DMs | ✅ Implemented | | NIP-44 encrypted DMs (improved privacy) | Planned | ## Tips * Use multiple relays for reliability * The bot's public key (npub) is derived from the private key automatically * Users can find your bot by its npub on any Nostr client * Consider publishing a NIP-05 identifier for discoverability # Channels Source: https://docs.openpawz.ai/channels/overview Connect your OpenPawz agents to 12 messaging platforms — all running simultaneously from one app. # Channels Connect your agents to messaging platforms. Users on those platforms chat with your agents directly — all from one app, running simultaneously. All incoming messages are scanned for **prompt injection** — messages with critical severity are blocked automatically. *** ## Supported channels Bot API — public bots, group chats Gateway WebSocket — community servers Bot API — workplace teams Client-Server API — decentralized chat IRC protocol — classic chat rooms WebSocket API — self-hosted teams Talk API — Nextcloud users NIP relay protocol — decentralized social IRC + API — live streaming chat HTTP/WebSocket — your own website Evolution API — personal & group messaging REST API — community forum support *** ## How channels work ```mermaid actions={false} theme={null} graph TD A["External message arrives"] --> B["Prompt injection scan\nBlock critical threats"] B --> C["Access control check\nOpen / Allowlist / Pairing"] C --> D["Route to agent\nFirst-match routing rules"] D --> E["Create per-user\nper-agent session"] E --> F["Auto-recall memories\nfor this user"] F --> G["Agent responds\nvia worker_model"] G --> H["Auto-capture\nmemorable facts"] H --> I["Provider fallback\non errors"] I --> J["Split response\nfor platform limits"] ``` ## DM policies Control who can message your agents: | Policy | Behavior | | ------------- | --------------------------- | | **Open** | Anyone can chat | | **Allowlist** | Only approved users | | **Pairing** | Users must pair with a code | ## Channel routing Route messages to specific agents based on rules: 1. Go to **Settings → Channels** 2. Add routing rules with filters: * **Channel** — which platform * **User filter** — specific users * **Channel ID filter** — specific channels/groups * **Agent** — which agent handles it Rules are evaluated **first-match-wins** — the first matching rule determines the agent. ## Security * All incoming messages are scanned for prompt injection * Messages with `critical` severity are blocked automatically * Each user gets an isolated session (no cross-user contamination) * Access control is per-channel and per-user * Channel agents use `worker_model` by default (cheaper, faster) ## Lean channel context Channel bridges use a **minimal context strategy** optimized for speed and low token cost: * **Core identity only** — the agent loads its identity, soul, and user files, but skips the full agent context (other agents, all tools, custom files) * **No memory recall overhead** — memory search (BM25 + vector) is skipped for channel messages to reduce latency. Memory is still available on-demand via the `memory_search` tool if the agent needs it. * **Minimal tool set** — channel agents only get the tools relevant to that bridge (\~4 tools), not the full 25,000+ integration catalog * **Worker model** — channels default to `worker_model` (cheaper/faster) rather than the boss model This means a channel message costs a fraction of a full chat turn. An agent responding on Discord or Telegram uses \~2K–4K tokens of context instead of \~10K–30K for a full desktop chat. Over thousands of channel messages, this saves significantly on token costs. :::tip If you need a channel agent to have full capabilities (memory recall, all tools), configure it as a dedicated agent with a larger context window and full tool access in **Settings → Agents**. ::: ## Provider fallback If the primary provider fails (billing, auth, or rate limit errors), Pawz automatically tries other configured providers before failing. # Slack Source: https://docs.openpawz.ai/channels/slack Connect a Slack bot to your Pawz agents. # Slack Connect a Slack bot to your Pawz agents. ## Setup 1. Go to [api.slack.com/apps](https://api.slack.com/apps) and create a new app 2. Under **OAuth & Permissions**, add bot token scopes: * `chat:write` * `channels:history` * `im:history` * `im:read` * `im:write` 3. Install the app to your workspace 4. Copy the **Bot User OAuth Token** (starts with `xoxb-`) 5. In Pawz, go to **Settings → Channels** 6. Select **Slack** 7. Paste your bot token 8. Start the channel ## Configuration | Field | Required | Description | | ------------- | ------------- | ------------------------ | | Bot token | Yes | `xoxb-` token from Slack | | DM policy | Yes | Who can message the bot | | Allowed users | For allowlist | Slack usernames | ## Features * DMs and channel mentions * Per-user sessions with memory * Prompt injection scanning * Agent routing via channel routing rules * Thread support ## Routing Route Slack channels or users to specific agents: * **Channel ID filter** — route messages from specific Slack channels (use the channel ID, not the name) * **User filter** — route messages from specific Slack users ## Tips * Invite the bot to channels where you want it to respond: `/invite @YourBot` * The bot responds when mentioned (`@YourBot`) or in DMs * Use the Slack skill separately if you want agents to proactively send messages # Telegram Source: https://docs.openpawz.ai/channels/telegram Connect a Telegram bot to your Pawz agents. # Telegram Connect a Telegram bot to your Pawz agents. ## Setup 1. Create a bot via [@BotFather](https://t.me/BotFather) on Telegram 2. Copy the bot token 3. In Pawz, go to **Settings → Channels** 4. Select **Telegram** 5. Paste your bot token 6. Configure: * **DM policy** — open / allowlist / pairing * **Allowed users** — Telegram usernames (for allowlist mode) 7. Start the channel ## Configuration | Field | Required | Description | | ------------- | ------------- | ------------------------- | | Bot token | Yes | From @BotFather | | DM policy | Yes | Who can message the bot | | Allowed users | For allowlist | Comma-separated usernames | ## Features * Direct messages and group chats * Per-user sessions with memory * Long messages auto-split for Telegram's 4096 char limit * Prompt injection scanning on all incoming messages * Agent routing via channel routing rules ## Routing By default, all Telegram messages go to your default agent. To route specific users or groups to different agents, add routing rules in **Settings → Channels → Routing**. ## Tips * Set your bot's description and about text in @BotFather for a polished experience * Use `/setcommands` in @BotFather to add command hints * For group chats, set the bot to **Group Privacy: disabled** so it can see all messages # Twitch Source: https://docs.openpawz.ai/channels/twitch Connect to Twitch chat so viewers can interact with your agents during streams. # Twitch Connect to Twitch chat so viewers can interact with your agents during streams. ## Setup 1. Create a Twitch account for your bot (or use your own) 2. Generate an OAuth token at [twitchapps.com/tmi](https://twitchapps.com/tmi/) 3. In Pawz, go to **Settings → Channels** 4. Select **Twitch** 5. Enter: * **Username** — bot's Twitch username * **OAuth token** — from step 2 * **Channel** — Twitch channel to join (your stream channel) 6. Start the channel ## Configuration | Field | Required | Description | | ------------- | ------------- | --------------------- | | Username | Yes | Bot's Twitch username | | OAuth token | Yes | Twitch OAuth token | | Channel | Yes | Channel name to join | | DM policy | Yes | Who can interact | | Allowed users | For allowlist | Twitch usernames | ## Features * Twitch IRC chat integration * Per-user sessions with memory * Prompt injection scanning * Agent routing via channel routing rules * Responds to mentions and commands ## Tips * Set the DM policy to **open** for public stream interaction * Use an allowlist if you only want moderators or subscribers to interact * Messages are limited to Twitch's 500 character max — long responses are auto-split * Consider rate limiting to avoid flooding chat # Webchat Source: https://docs.openpawz.ai/channels/webchat Webchat is a built-in HTTP/WebSocket chat interface you can embed on your own website or access directly. # Webchat Webchat is a built-in HTTP/WebSocket chat interface you can embed on your own website or access directly. ## Setup 1. In Pawz, go to **Settings → Channels** 2. Select **Webchat** 3. Configure: * **Port** — local port to listen on (default: 3000) * **DM policy** — open / allowlist / pairing 4. Start the channel ## Configuration | Field | Required | Description | | ------------- | ------------- | ---------------- | | Port | Yes | HTTP server port | | DM policy | Yes | Who can chat | | Allowed users | For allowlist | Usernames or IPs | ## Features * Built-in chat UI accessible at `http://localhost:` * WebSocket for real-time streaming * Per-user sessions with memory * Prompt injection scanning * Agent routing via channel routing rules ## Public access To make webchat accessible outside your machine: ### Via Tailscale ```bash theme={null} tailscale serve https / http://localhost:3000 ``` ### Via Tailscale Funnel (public internet) ```bash theme={null} tailscale funnel 443 http://localhost:3000 ``` See the [Tailscale guide](/guides/tailscale) for details. ## Embedding You can embed the webchat in your website using an iframe: ```html theme={null} ``` ## Tips * Use pairing mode to require users to authenticate with a code * Webchat is the simplest channel to get started with — no external accounts needed * Combine with Tailscale for secure remote access # WhatsApp Source: https://docs.openpawz.ai/channels/whatsapp Give your agent a WhatsApp number. People message that number, your agent replies — all on your machine. # WhatsApp Give your agent a WhatsApp number. People message that number, your agent replies — all on your machine. :::warning Important — read this first When you scan the QR code, **that phone number becomes your agent**. Anyone who messages that number will be talking to your AI — not you. **Do not use your personal number** unless you specifically want your agent handling all your WhatsApp conversations. ::: ## You need a separate phone number Pawz connects to WhatsApp the same way WhatsApp Web does — by linking to an existing account. It can't create new phone numbers. The number you scan is the number people will message to talk to your agent. ### Recommended: get a cheap prepaid SIM 1. Buy a prepaid SIM card (\~\$5 at any store or online) 2. Register WhatsApp on it (use an old phone, or briefly swap SIMs) 3. You only need the SIM active long enough to receive the verification SMS 4. After linking, WhatsApp stays connected even if the SIM expires Other options: * **eSIM** (Airalo, etc.) — \~\$5, activate on your phone * **Google Voice** — free but WhatsApp often rejects VoIP numbers * **Second phone** with its own number ## Setup 1. In Pawz, go to **Settings → Channels** 2. Select **WhatsApp** 3. Choose who can message your agent (defaults are fine to start) 4. Click **Save & Connect** 5. A QR code will appear — **scan it from the agent's phone** (the one with the separate number) * WhatsApp → Settings → Linked Devices → Link a Device 6. Done! People can now message that number to talk to your agent ## What happens when someone messages ```mermaid actions={false} theme={null} graph TD A["Someone messages\nthe agent's number"] --> B["Pawz receives it\nvia local webhook"] B --> C["Access control checks\nPairing / Allowlist / Open"] C --> D["Agent processes\nthe message"] D --> E["Reply sent back\nto WhatsApp"] ``` All traffic stays on your machine. Nothing is exposed to the internet. ## Access control | Mode | Behavior | | --------------------- | ------------------------------------------------------------------ | | **Pairing** (default) | New contacts get "waiting for approval" — you approve/deny in Pawz | | **Open** | Anyone can message the agent immediately | | **Allowlist** | Only pre-approved phone numbers can message | When using **Pairing** mode, pending requests show up on the WhatsApp channel card in Pawz with Approve / Deny buttons. ## Configuration | Setting | Description | | --------------------------- | ----------------------------------------------------- | | Who can message your agent? | Pairing / Open / Allowlist | | Reply in group chats too | Whether the agent responds in groups (default: off) | | Allowed phone numbers | Only needed for allowlist mode — include country code | | Agent | Leave blank for default, or pick a specific agent | ## Features * QR code authentication (scan to link) * Direct messages and group chat support * Per-user conversation sessions with memory * Prompt injection scanning on all incoming messages * Agent routing via channel routing rules * Auto-approval of tool calls (no human-in-the-loop for channel messages) * Everything runs locally — nothing exposed to the internet ## Tips * The QR code expires after a few minutes — scan it promptly * If you lose connection, click Stop then Start to get a fresh QR code * Phone numbers in allowlist should include country code (e.g., `15551234567`) * The agent uses WhatsApp formatting: *bold*, *italic*, ~~strikethrough~~, \`\`\`code\`\`\` * Long responses are automatically split into multiple messages # Agents Source: https://docs.openpawz.ai/guides/agents Agents are the core of Pawz — autonomous AI personas that chat, use tools, remember context, and collaborate. # Agents Agents are the core of Pawz — autonomous AI personas that chat, use tools, remember context, and collaborate. ## Creating an agent 1. Go to **Agents** in the sidebar 2. Click **Create Agent** 3. Fill in the basics: * **Name** — displayed in chat and dock * **Avatar** — choose from 50 sprite avatars * **Color** — pick from 7 accent colors * **Bio** — short description of what this agent does ## Templates Templates pre-configure skills and personality for common use cases: | Template | Skills | Tone | Initiative | Detail | | ------------- | ------------------------------------------------ | ---------- | ---------- | ---------- | | **General** | web\_search, web\_fetch, read, write | balanced | balanced | balanced | | **Research** | web\_search, web\_fetch, read, write, browser | formal | proactive | thorough | | **Creative** | web\_search, web\_fetch, read, write | casual | proactive | balanced | | **Technical** | web\_search, web\_fetch, read, write, exec, edit | balanced | reactive | thorough | | **Custom** | you choose | you choose | you choose | you choose | ## Personality settings Each agent has three personality axes: | Axis | Options | Description | | -------------- | ------------------------------- | ------------------------------------------- | | **Tone** | casual / balanced / formal | How the agent sounds | | **Initiative** | reactive / balanced / proactive | How much the agent does without being asked | | **Detail** | brief / balanced / thorough | Response length and depth | ## Model selection Each agent can use a different model: * **Default** — uses the engine's default model * **Specific model** — pick from the well-known model catalog or type any model name Well-known models include: * **Gemini**: gemini-2.5-pro, gemini-2.5-flash, gemini-2.0-flash * **Anthropic**: claude-sonnet-4, claude-haiku-4, claude-opus-4 * **OpenAI**: gpt-4o, gpt-4o-mini, o1, o3-mini ## Skills Toggle which tools an agent can use: `web_search` · `web_fetch` · `browser` · `read` · `write` · `exec` · `image` · `memory_store` · `cron` · `message` See the [Skills guide](/skills) for the full skill vault. ## Soul files Every agent gets three markdown files that define its identity: | File | Purpose | | --------------- | ------------------------------------------------- | | **IDENTITY.md** | Name, emoji, vibe, avatar description | | **SOUL.md** | Personality, communication style, boundaries | | **USER.md** | Who the user is, preferences, how to address them | Additional standard files: * **AGENTS.md** — Operating rules, priorities, memory usage * **TOOLS.md** — Notes about local tools and conventions Edit these in the agent detail view. Changes take effect on the next message. ### Soul file auto-seeding When a new agent is created, Pawz automatically seeds its soul files so the agent knows who it is from the very first conversation. The seeding process only writes files that **don't already exist**, so your edits are never overwritten. The auto-seeded files are: | File | Seeded content | | --------------- | --------------------------------------------------------------------------------------------------------------- | | **IDENTITY.md** | Agent name, ID, role/bio, specialty (from template), personality axes, boundaries, and any custom system prompt | | **SOUL.md** | Starter template prompting the agent to develop its own voice using `soul_write` | | **USER.md** | Starter template prompting the agent to record user preferences via `soul_write` | :::tip Soul files are stored in the `agent_files` database table, keyed by `(agent_id, file_name)`. Each agent can have any number of additional files beyond the three defaults — agents can create their own files using the `soul_write` tool during conversation. ::: For agents created by the orchestrator (backend agents), soul files are seeded automatically on the next app load. The `IDENTITY.md` file includes the agent's assigned role and specialty from the project. ## Backend agents In addition to agents you create manually (stored in `localStorage`), Pawz supports **backend agents** created programmatically by the orchestrator when it plans a project. ### Storage schema Backend agents live in the `project_agents` SQLite table: | Column | Type | Description | | --------------- | ---- | --------------------------------------------------- | | `project_id` | TEXT | The project this agent belongs to | | `agent_id` | TEXT | Unique agent identifier | | `role` | TEXT | Agent's role in the project (e.g. `worker`, `boss`) | | `specialty` | TEXT | What this agent is good at (see below) | | `status` | TEXT | Current status (`idle`, `busy`, etc.) | | `current_task` | TEXT | The task the agent is currently working on | | `model` | TEXT | Override model for this agent (optional) | | `system_prompt` | TEXT | Custom system prompt (optional) | | `capabilities` | TEXT | Comma-separated list of tool capabilities | ### Specialties When the orchestrator creates agents for a project, it assigns each one a specialty: | Specialty | Description | | ------------ | ----------------------------------- | | `coder` | Writing and editing code | | `writer` | Prose, documentation, copy | | `analyst` | Data analysis and interpretation | | `researcher` | Information gathering and synthesis | | `designer` | UI/UX and visual design | | `tester` | Testing and quality assurance | | `reviewer` | Code review and feedback | | `planner` | Project planning and coordination | | *(custom)* | Any freeform specialty string | :::info Backend agents appear on the Agents grid with an **"AI-Created"** badge. They are merged into the local agent list on load and receive unique sprite avatars automatically. Their names are derived from the `agent_id` with hyphens replaced by spaces and title-cased. ::: ## Agent-scoped history When multiple agents share a session (e.g., during orchestration or inter-agent delegation), each agent only sees messages relevant to its own context. Cross-agent tool results from `agent_send_message` and `agent_read_messages` are filtered out for non-default agents. This prevents context pollution — one agent's delegation results won't confuse another agent's conversation flow. The orchestrator boss agent sees all messages (unfiltered) to maintain full situational awareness. ## Agent policies Agent policies control **which tools** an agent is allowed to use. This lets you create restricted agents that can only read files, or fully-empowered agents that can execute shell commands. ### Policy modes | Mode | Behaviour | | ---------------- | -------------------------------------------------------- | | **Allowlist** | Only explicitly listed tools can be used (strictest) | | **Denylist** | All tools are available *except* those explicitly denied | | **Unrestricted** | No restrictions — all tools allowed (default) | ### Tool classifications Pawz classifies built-in tools into two groups: **Safe tools** (read-only, low risk): ``` read_file, list_directory, web_search, web_read, memory_search, soul_read, soul_list, self_info, fetch ``` **High-risk tools** (modify system or send data externally): ``` exec, write_file, delete_file, append_file, email_send, webhook_send, rest_api_call, slack_send, github_api, image_generate, soul_write, update_profile, create_agent, create_task, manage_task ``` ### Policy presets Four presets are available for quick setup: | Preset | Mode | Description | | ---------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------- | | **Unrestricted** | `unrestricted` | Full access to all tools (default) | | **Standard** | `denylist` | All tools available, but high-risk tools require human-in-the-loop approval | | **Read-Only** | `allowlist` | Only safe read/search tools — no modifications | | **Sandbox** | `allowlist` | Web search and memory only — no file or exec access (`web_search`, `web_read`, `memory_store`, `memory_search`, `self_info`) | ### Additional policy options | Setting | Description | | ---------------------------- | ------------------------------------------------------------------------------ | | `requireApprovalForUnlisted` | In allowlist mode, tools not in the list still work but require human approval | | `alwaysRequireApproval` | List of tools that *always* need approval regardless of mode | | `maxToolCallsPerTurn` | Limit the number of tool calls an agent can make in a single turn | :::caution Policies are stored per-agent in `localStorage` under the `paw_agent_tool_policies` key. Clearing browser storage resets all policies to the default (unrestricted). ::: ## Avatar system Pawz ships with **50 pixel-art avatar sprites** in a 1980s Japanese style. The sprites are 96×96 PNG files located at `src/assets/avatars/1.png` through `src/assets/avatars/50.png`. * A random avatar (1–50) is assigned at agent creation * The avatar is stored as a numeric string (e.g. `"5"`) in the agent's `avatar` field * You can change an agent's avatar at any time in the edit view * Legacy emoji avatars are automatically migrated to sprite avatars on load * Backend agents get specialty-based avatar assignments: coder → `10`, researcher → `15`, designer → `20`, communicator → `25`, security → `30`, general → `35`, writer → `40`, analyst → `45` :::tip The default Pawz agent always uses avatar `5`. If you want to identify agents by specialty at a glance, backend agents are assigned themed sprite numbers based on their role. ::: ## Agent dock The dock is a floating tray at the bottom-right of the screen: * Shows all your agents as circular avatars * Click an avatar to open a **mini-chat** popup * Unread badge shows new messages * Collapse/expand with the toggle button * Tooltips show agent name on hover ## Mini-chat Each agent has a Messenger-style chat window: * Opens as a popup from the dock * Real-time streaming responses * Full tool execution with approval flow * Independent session per agent * Drag to reposition ## System prompt For advanced users: override the agent's system prompt entirely. This replaces all auto-generated instructions. Use this when you need full control. ## Boundaries Add custom rules the agent must follow, like: * "Never share API keys" * "Always ask before deleting files" * "Keep responses under 200 words" # Automations Source: https://docs.openpawz.ai/guides/automations Automations are recurring tasks that run on a schedule using cron expressions. # Automations Automations are recurring tasks that run on a schedule using cron expressions. ## How it works 1. Create a task in the **Tasks** view 2. Set a cron schedule 3. Enable the cron toggle 4. The engine checks for due tasks every **60 seconds** ## Creating an automation 1. Go to **Automations** in the sidebar (or **Tasks → New Task**) 2. Set the task title and description 3. Assign an agent 4. Enter a **cron schedule** 5. Enable cron ## Cron syntax Standard 5-field cron expressions: ```mermaid actions={false} theme={null} graph LR A["* minute\n0-59"] --- B["* hour\n0-23"] --- C["* day\n1-31"] --- D["* month\n1-12"] --- E["* weekday\n0-6"] ``` ### Common schedules | Schedule | Cron | Description | | ------------- | -------------- | ---------------------- | | Every morning | `0 9 * * *` | 9 AM daily | | Twice daily | `0 9,17 * * *` | 9 AM and 5 PM | | Weekdays only | `0 9 * * 1-5` | 9 AM Mon–Fri | | Every hour | `0 * * * *` | On the hour | | Every 30 min | `*/30 * * * *` | Half-hourly | | Weekly | `0 9 * * 1` | Monday at 9 AM | | Monthly | `0 9 1 * *` | First of month at 9 AM | ## Automation view The Automations page shows three columns: | Column | Description | | --------------- | ----------------------------- | | **Active** | Currently enabled automations | | **Paused** | Disabled automations | | **Run History** | Past execution results | ## Actions | Action | Description | | ----------- | ------------------------------------------------ | | **Run now** | Execute immediately without waiting for schedule | | **Edit** | Modify the task, schedule, or agent | | **Pause** | Disable without deleting | | **Enable** | Re-activate a paused automation | | **Delete** | Remove permanently | ## Service status The green heartbeat indicator at the top confirms the automation engine is active and checking for due tasks. ## Use cases * **Morning Brief** — summarize your calendar and emails at 9 AM * **News Digest** — research trending topics every evening * **Health Check** — run a security audit daily * **Blog Monitor** — check for new posts on followed blogs * **Metric Reports** — pull and summarize analytics weekly # Browser Sandbox Source: https://docs.openpawz.ai/guides/browser The browser sandbox lets agents browse the web in a controlled, auditable environment. # Browser Sandbox The browser sandbox lets agents browse the web in a controlled, auditable environment. ## Configuration Go to **Settings → Advanced** to configure: | Setting | Default | Description | | ------------------- | ------- | ---------------------------------- | | **Headless** | On | Run browser without visible window | | **Auto-close tabs** | On | Close tabs after agent finishes | | **Idle timeout** | 300s | Kill browser after inactivity | ## Profiles Create isolated browser profiles for different purposes: * Each profile has its own cookies, storage, and history * Agents can switch between profiles * Prevents cross-contamination between tasks ## Network policy Control which domains agents can access: ### Default allowed domains | Domain | Purpose | | ----------------------------------- | -------------- | | `api.openai.com` | AI provider | | `api.anthropic.com` | AI provider | | `generativelanguage.googleapis.com` | AI provider | | `openrouter.ai` | AI provider | | `api.elevenlabs.io` | TTS provider | | `duckduckgo.com` | Web search | | `html.duckduckgo.com` | Web search | | `api.coinbase.com` | Trading | | `localhost` | Local services | ### Default blocked domains | Domain | Reason | | -------------- | ---------------------- | | `pastebin.com` | Data exfiltration risk | | `transfer.sh` | File sharing risk | | `file.io` | File sharing risk | | `0x0.st` | Anonymous upload risk | ### Custom rules Add your own allowed or blocked domains in the browser settings. Blocked domains take priority over allowed. ### Request logging Enable **log requests** to see all network requests the browser makes. Recent requests are shown in the settings panel for auditing. ## Agent tools | Tool | Description | | ---------------- | -------------------------------------------- | | `web_browse` | Navigate to a URL and interact with the page | | `web_screenshot` | Capture a screenshot of the current page | | `web_read` | Extract text content from a page | ## Browser sandbox architecture The browser sandbox uses **headless Chromium** via the `headless_chrome` Rust crate (Chrome DevTools Protocol): ```mermaid actions={false} theme={null} graph TB subgraph Engine["Rust Engine"] WEB["web.rs — Tool Executor\nweb_search · web_read\nweb_screenshot · web_browse"] WEB -->|Chrome DevTools Protocol| CHROME["Headless Chromium\nLazy init · Isolated profile\nSandboxed in CI"] end ``` * **Lazy initialization** — Chrome is only launched when an agent first calls `web_screenshot` or `web_browse` * **Singleton instance** — one shared browser process with health checks; auto-relaunches if Chrome dies * **Session continuity** — `web_browse` reuses the first tab for multi-step interactions within a session * **Idle timeout** — configurable (default 300s), kills Chrome after inactivity ## Screenshot capture and vision analysis The `web_screenshot` tool captures full-page screenshots and extracts visible text: | Parameter | Default | Description | | ----------- | ---------- | ------------------------------ | | `url` | (required) | Page to capture | | `full_page` | `false` | Capture entire scrollable page | | `width` | 1280 | Viewport width in pixels | | `height` | 800 | Viewport height in pixels | Screenshots are: 1. Saved as PNG to `$TMPDIR/paw-screenshots/screenshot-YYYYMMDD-HHMMSS.png` 2. Accompanied by extracted visible text (up to 5000 chars) so the agent can "read" the page 3. Viewable in **Settings → Advanced** screenshot gallery :::tip When `web_read` returns empty text (JavaScript-rendered pages), use `web_screenshot` instead — it waits for dynamic content to load and extracts visible text from the rendered DOM. ::: ## Form filling and interaction The `web_browse` tool supports full page interaction: | Action | Parameters | Description | | ---------------------------- | --------------------------- | --------------------------------------- | | `navigate` / `goto` | `url` | Navigate to a URL and wait for load | | `click` | `selector` | Click an element by CSS selector | | `type` / `fill` | `selector`, `text` | Click an input and type text into it | | `press` | `text` (key name) | Press a keyboard key (Enter, Tab, etc.) | | `extract` / `read` | `selector` (optional) | Extract text content from elements | | `javascript` / `eval` / `js` | `javascript` | Execute arbitrary JavaScript | | `scroll` | `text` (up/down/top/bottom) | Scroll the page | | `links` | — | List all links on the page (up to 50) | | `info` | — | Get current page title and URL | ### Example: filling a login form The agent can chain multiple `web_browse` calls: ``` 1. web_browse(action: "navigate", url: "https://example.com/login") 2. web_browse(action: "type", selector: "#email", text: "user@example.com") 3. web_browse(action: "type", selector: "#password", text: "...") 4. web_browse(action: "click", selector: "button[type=submit]") ``` ## Cookie and session management Browser profiles provide isolated cookie and session storage: | Feature | Description | | ----------------------- | ----------------------------------------------------------------------------------------------- | | **Profile directory** | Each profile stores cookies, localStorage, and cache in `~/.paw/browser-profiles//` | | **Session persistence** | Cookies and logged-in sessions survive across agent tool calls within the same profile | | **Profile isolation** | Different profiles have completely separate storage — no cross-contamination | | **Profile switching** | Set the default profile in **Settings → Advanced** | ### Managing profiles * **Create** — go to Settings → Advanced → Browser → "New Profile" * **Delete** — removes the profile directory and all associated data * **Set default** — choose which profile new browser sessions use ## Proxy support Proxy configuration can be applied through Chrome launch flags. Set the `HTTP_PROXY` or `HTTPS_PROXY` environment variables before launching Pawz, and the headless Chrome instance will respect them. ## Security * Network policy is enforced at the browser level — agents cannot bypass it * All browser activity is contained within the profile * Headless mode prevents agents from displaying arbitrary content * Idle timeout prevents runaway browser sessions # Container Sandbox Source: https://docs.openpawz.ai/guides/container-sandbox # Container Sandbox The Container Sandbox runs agent `exec` commands inside ephemeral Docker containers instead of directly on your host machine. This provides strong isolation — each command runs in a fresh container with dropped capabilities, constrained resources, and optional network restrictions. ## How it works ```mermaid actions={false} theme={null} graph TD A["Agent calls exec tool"] --> B{"Sandbox enabled?"} B -->|NO| C["Run directly on host"] B -->|YES| D["Create ephemeral\nDocker container"] D --> E["Run command\ninside container"] E --> F["Capture stdout/stderr"] F --> G["Destroy container"] G --> H["Return output to agent"] C --> H ``` The sandbox uses the [bollard](https://crates.io/crates/bollard) Rust crate to communicate with the Docker daemon. ## Enabling the sandbox 1. **Install Docker** on your system (Docker Desktop or Docker Engine) 2. Go to **Settings → Advanced** 3. Toggle **Container Sandbox** to enabled 4. Optionally select a preset or configure manually :::warning Docker must be installed and running for the sandbox to work. If Docker is unavailable, `exec` commands will fail when the sandbox is enabled. ::: ## Configuration | Setting | Default | Description | | ------------- | --------------- | ---------------------------------------------------------- | | `enabled` | `false` | Whether sandboxing is active | | `image` | `alpine:latest` | Docker image used for containers | | `timeout` | `30s` | Maximum execution time per command | | `memory` | `256 MB` | Memory limit for the container | | `cpu_shares` | `512` | Relative CPU weight (default Docker is 1024) | | `network` | Disabled | Whether the container has network access | | `workdir` | `/workspace` | Working directory inside the container | | `bind_mounts` | `[]` | Host-to-container directory mounts (`host:container:mode`) | ## Security hardening Every sandboxed container runs with strict security defaults: * **`CAP_DROP ALL`**: All Linux capabilities are dropped — no privilege escalation possible * **No privileged mode**: Containers cannot access host devices or kernel features * **Output truncation**: Command output is truncated at **50,000 characters** to prevent memory exhaustion * **Ephemeral**: Containers are destroyed after each command — no persistent state between executions ## Presets Pawz includes 4 pre-built sandbox profiles for common use cases. Select a preset to instantly configure all settings. ### Minimal The most restrictive configuration. Ideal for simple shell commands where you want maximum isolation. | Setting | Value | | ---------- | --------------- | | Image | `alpine:latest` | | Memory | 128 MB | | Timeout | 15s | | CPU shares | 512 | | Network | Disabled | | Workdir | `/workspace` | **Best for**: Quick file operations, text processing, basic shell utilities. ### Development A balanced profile with Node.js available and network access enabled. Suitable for running build scripts, linting, and test suites. | Setting | Value | | ---------- | ---------------- | | Image | `node:20-alpine` | | Memory | 512 MB | | Timeout | 60s | | CPU shares | 512 | | Network | **Enabled** | | Workdir | `/workspace` | **Best for**: JavaScript/TypeScript development, package installation, running tests, build processes. ### Python Similar to Development but with Python 3.12 pre-installed. Great for data analysis, scripting, and ML tasks. | Setting | Value | | ---------- | -------------------- | | Image | `python:3.12-alpine` | | Memory | 512 MB | | Timeout | 60s | | CPU shares | 512 | | Network | **Enabled** | | Workdir | `/workspace` | **Best for**: Python scripts, pip package installation, data processing, Jupyter-style tasks. ### Restricted The most locked-down profile. Minimal resources, no network, very short timeout. Use this when running untrusted or potentially dangerous commands. | Setting | Value | | ---------- | --------------- | | Image | `alpine:latest` | | Memory | 64 MB | | Timeout | 10s | | CPU shares | 256 | | Network | Disabled | | Workdir | `/workspace` | **Best for**: Evaluating untrusted code, sandboxing risky commands, maximum isolation scenarios. ## Command risk assessment The sandbox includes a built-in command risk scoring system that classifies commands into four levels: | Risk level | Examples | Description | | | ------------ | --------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------- | | **Critical** | `rm -rf /`, `mkfs`, `dd of=/dev/...`, fork bombs | System-destroying commands | | | **High** | `sudo`, `su`, `chmod 777`, \`curl | sh`, `eval\` | Privilege escalation, piped execution | | **Medium** | `curl`, `wget`, `rm`, `pip install`, `npm install`, `apt` | Network access, file modifications, package installs | | | **Low** | `ls`, `cat`, `echo`, `grep` | Read-only, safe operations | | :::info Risk assessment is informational — it helps you understand what agents are doing. The sandbox enforces isolation regardless of risk level. All capabilities are dropped and containers are ephemeral. ::: ## Bind mounts You can mount host directories into the container to give agents access to specific files: ``` /home/user/project:/workspace:ro ``` Format: `host_path:container_path:mode` | Mode | Description | | ---- | ----------------- | | `ro` | Read-only access | | `rw` | Read-write access | :::warning Be careful with `rw` mounts — the agent can modify files on your host filesystem through the container. Use `ro` when the agent only needs to read files. ::: ## Use cases ### Safe code execution Let agents run code in a sandboxed environment where mistakes can't damage your system: ``` You: Write and run a Python script that calculates prime numbers up to 1000 Agent: [uses exec tool → runs inside Python sandbox container] ``` ### Untrusted command evaluation When an agent suggests a shell command you're unsure about, the sandbox provides a safety net: * If the command is destructive, it only affects the ephemeral container * All Linux capabilities are dropped, preventing privilege escalation * Network can be disabled to prevent data exfiltration ### Build and test isolation Run project builds and test suites without polluting your host environment: * Dependencies installed in the container don't affect your system * Failed builds can't leave behind broken state * Each run starts from a clean image :::tip For development workflows, use the **Development** or **Python** preset with bind mounts pointing to your project directory. This gives agents access to your code while keeping execution sandboxed. ::: # Content Studio Source: https://docs.openpawz.ai/guides/content-studio # Content Studio The Content Studio is a built-in document editor for drafting and managing text content directly within Pawz. Write markdown, HTML, or plain text, and optionally use AI to improve your writing with one click. ## Document management ### Creating a document 1. Open the **Content** view 2. Click **New Document** 3. Enter a title and select a content type 4. Start writing in the editor ### Content types | Type | Description | | ------------- | ---------------------------- | | **Markdown** | Standard markdown formatting | | **HTML** | Raw HTML content | | **Plaintext** | Unformatted text | ### Operations | Action | Description | | ---------- | ---------------------------------------------------------- | | **Create** | Start a new document with title and content type | | **Edit** | Modify the title, type, or content of an existing document | | **Save** | Persist changes to the database | | **Delete** | Permanently remove a document | ## Editor The editor provides a full-width text area optimized for focused writing: * **Live word count**: Displayed below the editor, updating as you type * **Title editing**: Click the document title to rename it inline * **Content type selector**: Switch between markdown, HTML, and plaintext ### Document sidebar The left sidebar lists all your documents with: | Column | Description | | ---------------- | --------------------------------- | | **Title** | Document name | | **Word count** | Total words in the document | | **Last updated** | Timestamp of the most recent edit | Click any document in the sidebar to open it in the editor. ## AI Improve The standout feature of Content Studio is **AI Improve** — a one-click button that sends your document content to the chat engine for AI-powered text improvement. ### How it works 1. Write or paste content into the editor 2. Click the **AI Improve** button 3. The content is sent to your active AI model with instructions to improve clarity, grammar, and style 4. The improved version is returned and can be reviewed :::tip AI Improve uses your currently configured model and provider. For best results with long-form content, use a capable model like Claude Sonnet or GPT-4o. ::: ## Storage Documents are stored in the **frontend SQLite** database in the `content_documents` table. This means: * Documents persist across app restarts * Documents are stored locally on your machine * No cloud sync — your content stays private ### Schema | Column | Type | Description | | -------------- | --------- | ---------------------------------- | | `id` | UUID | Unique document identifier | | `title` | Text | Document title | | `content` | Text | Full document content | | `content_type` | Text | `markdown`, `html`, or `plaintext` | | `word_count` | Integer | Cached word count | | `created_at` | Timestamp | Creation time | | `updated_at` | Timestamp | Last modification time | :::info Content Studio documents are separate from Research findings and agent-generated files. They are your personal writing space within Pawz. ::: # Dashboard & Today Source: https://docs.openpawz.ai/guides/dashboard # Dashboard & Today The Dashboard (also called the Today view) is your landing page in Pawz. It provides an at-a-glance overview of your day with a weather widget, task list, quick action buttons, and a personalized greeting from your active agent. ## Greeting The dashboard displays a time-based greeting that changes throughout the day: | Time | Greeting | | ------------------ | -------------- | | Before 12:00 PM | Good morning | | 12:00 PM – 5:59 PM | Good afternoon | | 6:00 PM onwards | Good evening | The greeting is accompanied by your active agent's avatar. ## Weather widget The dashboard includes a weather widget powered by [wttr.in](https://wttr.in). * **No API key required** — wttr.in is a free, open service * Displays current conditions for your location * Updates automatically when the dashboard loads :::tip The wttr.in service uses your IP address for geolocation. If you're using a VPN, the weather will reflect the VPN server's location. ::: ## Task list A lightweight task manager is built directly into the dashboard for quick daily planning. ### Operations | Action | Description | | ---------- | ---------------------------------- | | **Create** | Add a new task with a title | | **Toggle** | Mark a task as complete/incomplete | | **Edit** | Update a task's title | | **Delete** | Remove a task from the list | Tasks on the dashboard are stored in **localStorage** and are separate from the full Kanban task board (which uses the engine's SQLite database). Think of these as quick personal reminders rather than agent-managed tasks. :::info For full-featured task management with agent assignment, cron scheduling, and Kanban workflows, use the **Tasks** view instead. ::: ## Quick action buttons The dashboard provides one-click quick actions that send pre-built prompts to your active agent: | Button | What it does | | -------------------- | ----------------------------------------------------------------------------------- | | **Morning Briefing** | Asks the agent to prepare a morning summary with weather, calendar, tasks, and news | | **Summarize Inbox** | Asks the agent to summarize recent emails and messages | | **What's on today?** | Asks the agent to outline your agenda for the day | These actions open the chat view and send the corresponding prompt immediately, so your agent can start working right away. ## Agent avatar display Your currently active agent's avatar is displayed prominently on the dashboard. Pawz uses a sprite-based avatar system with 50 unique avatars, each assigned a color from a 7-color palette. :::tip Customize your agent's avatar and color in the **Agents** view to make the dashboard feel personal. ::: ## Skill output widgets Community integrations and extensions can display live data on the dashboard using **skill output widgets**. When an agent uses the `skill_output` tool, the data is persisted in SQL and rendered as a widget card on the Today page. ### How it works 1. A community skill defines a `[widget]` section in its `pawz-skill.toml` manifest 2. The agent calls `skill_output` with structured JSON data (e.g., a table of CRM deals, stock prices, or system metrics) 3. The data is stored in the `skill_outputs` table 4. The dashboard renders the widget with the declared field definitions — supporting text, number, currency, badge, and date column types ### Widget types | Type | Description | | ------- | ---------------------------------- | | `table` | Tabular data with sortable columns | | `stat` | Single metric with label and value | | `list` | Ordered or unordered item list | ### Refresh Widgets can declare a refresh interval (e.g., `refresh = "5m"`) to automatically re-render with the latest data. The agent's cron task can be configured to periodically update the skill output. :::tip Combine skill output widgets with **event-driven triggers** to update dashboard data in real-time when webhooks arrive or agents communicate. ::: # Email Source: https://docs.openpawz.ai/guides/email Pawz can read and send email through your existing accounts using Himalaya, an IMAP/SMTP CLI client. # Email Pawz can read and send email through your existing accounts using Himalaya, an IMAP/SMTP CLI client. ## Prerequisites Install [Himalaya](https://github.com/pimalaya/himalaya): ```bash theme={null} # macOS brew install himalaya # Linux cargo install himalaya ``` ## Configuration Himalaya uses a TOML config file at `~/.config/himalaya/config.toml`: ```toml theme={null} [accounts.personal] email = "you@gmail.com" display-name = "Your Name" [accounts.personal.imap] host = "imap.gmail.com" port = 993 login = "you@gmail.com" passwd.cmd = "security find-generic-password -s gmail -w" [accounts.personal.smtp] host = "smtp.gmail.com" port = 465 login = "you@gmail.com" passwd.cmd = "security find-generic-password -s gmail -w" ``` ## Skills setup Enable the **Email** skill in the **Skills** tab and provide: | Credential | Example | | ---------- | ------------------------------------- | | SMTP\_HOST | smtp.gmail.com | | SMTP\_PORT | 465 | | SMTP\_USER | [you@gmail.com](mailto:you@gmail.com) | | SMTP\_PASS | your app password | | IMAP\_HOST | imap.gmail.com | | IMAP\_USER | [you@gmail.com](mailto:you@gmail.com) | | IMAP\_PASS | your app password | :::tip For Gmail, use an [App Password](https://support.google.com/accounts/answer/185833) — not your regular password. ::: ## Agent tools With the Email skill enabled, agents get: | Tool | Approval | Description | | ------------ | ---------------- | -------------------------------- | | `email_read` | Auto | Read inbox, search emails | | `email_send` | **HIL required** | Send emails (human must approve) | ## Mail permissions Each account can have granular permissions: | Permission | Description | | ---------- | ----------------------- | | `read` | Allow reading emails | | `send` | Allow sending emails | | `delete` | Allow deleting emails | | `manage` | Allow folder management | ## Provider icons The mail view auto-detects your provider and shows the appropriate icon: | Provider | Icon | | -------- | ---- | | Gmail | G | | Outlook | O | | Yahoo | Y | | iCloud | iC | | Fastmail | FM | | Other | M | ## Provider presets The account setup wizard auto-fills IMAP/SMTP settings for popular providers: | Provider | IMAP Server | IMAP Port | SMTP Server | SMTP Port | Auth notes | | --------------------- | ----------------------- | --------- | --------------------- | --------- | -------------------------------------------------------------------------- | | **Gmail** | `imap.gmail.com` | 993 | `smtp.gmail.com` | 465 | Requires [App Password](https://support.google.com/accounts/answer/185833) | | **Outlook / Hotmail** | `outlook.office365.com` | 993 | `smtp.office365.com` | 587 | Regular password or App Password with 2FA | | **Yahoo Mail** | `imap.mail.yahoo.com` | 993 | `smtp.mail.yahoo.com` | 465 | App Password from Yahoo Security settings | | **iCloud Mail** | `imap.mail.me.com` | 993 | `smtp.mail.me.com` | 587 | App-Specific Password from appleid.apple.com | | **Fastmail** | `imap.fastmail.com` | 993 | `smtp.fastmail.com` | 465 | App Password from Privacy & Security | | **Custom** | (manual) | 993 | (manual) | 465 | Enter your own IMAP/SMTP details | :::info All connections use TLS encryption. Passwords are stored in the **OS keychain** (macOS Keychain / libsecret on Linux), never in plain text files. ::: ## Email filtering and folders Agents can work with email folders to organize messages: | Action | Tool | Description | | -------------- | -------------- | --------------------------------------------------- | | List inbox | `email_read` | Fetch emails from INBOX or any named folder | | Move to folder | `move_email` | Move a message to a different folder (e.g. Archive) | | Delete email | `delete_email` | Move to trash or permanently delete | | Search | `email_read` | Search by subject, sender, or content | ### Folder support Himalaya supports standard IMAP folders: * `INBOX` — default inbox * `[Gmail]/All Mail` — Gmail archive * `[Gmail]/Drafts` — drafts folder * `Sent` / `[Gmail]/Sent Mail` — sent items * Custom folders created by the user ## Attachment handling Email attachments are managed through the Himalaya CLI: * **Reading** — `email_read` retrieves the full message body including inline content * **Downloading** — the agent can save attachments to the local filesystem via Himalaya commands * **Sending** — attachments can be included when composing messages through the Himalaya skill ## AI email actions The mail view includes built-in AI actions for each email. These send a pre-composed prompt to your agent: | Action | What the agent does | | ----------------- | -------------------------------------------------------- | | **Summarize** | Generates a concise summary of the email content | | **Draft Reply** | Composes a professional reply based on the email context | | **Extract Tasks** | Identifies action items and tasks mentioned in the email | ### Compose and reply The built-in compose modal supports: * **Reply** — pre-fills the recipient and subject with `Re:` prefix * **Forward** — pre-fills the subject with `Fwd:` prefix and includes the original message * **New email** — opens the chat with a compose prompt for the agent to draft and send :::tip For AI-composed messages, the agent drafts the email and uses Himalaya to send it. All outgoing email through the `email_send` tool requires **human-in-the-loop (HIL) approval** — you must confirm before any email is actually sent. ::: ## Credential Vault Email accounts are protected by the Credential Vault with a full audit trail: * **Permission toggles** — enable/disable read, send, delete, and manage permissions per account * **Activity log** — every agent email action is logged with timestamps * **Blocked actions** — attempts to use a disabled permission are logged and denied * **Revoke access** — instantly remove an account and delete credentials from the device ## Channel integration Email can also be set up as a channel — see [Channel Routing](/channels/overview) for details. # Extensions Source: https://docs.openpawz.ai/guides/extensions # Extensions Extensions are the most powerful tier of the Pawz extensibility system. They have everything an [Integration](/docs/guides/integrations) has — credentials, instructions, widgets — plus **custom sidebar views** and **persistent data storage**. ```mermaid actions={false} theme={null} graph LR S["Skill\nPrompt-only\nSKILL.md"]:::blue --> I["Integration\nCredentials + Tools\nTOML"]:::purple --> E["Extension\nCustom Views + Storage\nTOML"]:::gold classDef blue fill:#3b82f6,color:#fff,stroke:#3b82f6 classDef purple fill:#a855f7,color:#fff,stroke:#a855f7 classDef gold fill:#eab308,color:#000,stroke:#eab308 style E stroke-width:3px ``` **Extensions vs. Integrations**: An [Integration](/docs/guides/integrations) connects your agent to an API or CLI tool with encrypted credentials and optional dashboard widgets. An Extension does all of that **plus** registers a custom sidebar view and can persist structured data across sessions. *** ## What Extensions Add | Feature | Skill | Integration | Extension | | ----------------------- | ----- | ----------- | --------- | | Prompt injection | ✓ | ✓ | ✓ | | Credential vault | — | ✓ | ✓ | | Binary detection | — | ✓ | ✓ | | Dashboard widgets | — | ✓ | ✓ | | **Custom sidebar view** | — | — | **✓** | | **Persistent storage** | — | — | **✓** | | **Data-bound UI** | — | — | **✓** | *** ## How Extensions Work 1. **Manifest** — A `pawz-skill.toml` with `[view]` and/or `[storage]` sections 2. **Sidebar view** — The extension registers a tab in the sidebar with its own icon and label 3. **Persistent data** — The extension declares storage tables; agents use `skill_store_*` tools to persist structured data across sessions 4. **Data-bound rendering** — The custom view reads from the extension's storage and renders live data (tables, charts, pipelines, feeds) 5. **Widget** — An optional dashboard card shows a summary on the Today page ```mermaid actions={false} theme={null} graph LR subgraph App["Pawz App"] subgraph Sidebar T["Today"] CH["Chat"] AG["Agents"] TA["Tasks"] SK["Skills"] CRM["CRM"]:::gold HM["Home"]:::gold end subgraph View["Extension View — CRM Pipeline"] NEW["New\n3 deals"] --> QUAL["Qualified\n7 deals"] --> CLOSE["Closed\n2 deals"] end end classDef gold fill:#eab308,color:#000,stroke:#eab308 ``` *** ## Extension Manifest An extension is a `pawz-skill.toml` with the additional `[view]` and `[storage]` sections: ```toml theme={null} [skill] id = "simple-crm" name = "Simple CRM" version = "1.0.0" author = "community" category = "productivity" icon = "contacts" description = "A lightweight CRM with contacts, deals, and activity tracking" [[credentials]] key = "CRM_WEBHOOK" label = "Import Webhook (optional)" description = "Incoming webhook URL for importing contacts from external systems" required = false placeholder = "https://..." [instructions] text = """ You have a CRM system with persistent storage. Use the storage tools to manage data: ## Contacts - skill_store_set: Add or update a contact (name, email, company, stage) - skill_store_query: Search contacts by name, company, or stage - skill_store_get: Get a specific contact by ID ## Deals - skill_store_set: Create or update deals (name, value, stage, contact_id) - skill_store_query: Filter deals by stage (new, qualified, proposal, closed) ## Activity - skill_store_set: Log activities (type: call/email/meeting, notes, contact_id) - skill_store_query: Get activity feed for a contact or date range When the user asks about their pipeline, contacts, or deals, query storage first. """ [widget] type = "table" title = "Active Deals" refresh = "5m" [[widget.fields]] key = "name" label = "Deal" type = "text" [[widget.fields]] key = "value" label = "Amount" type = "currency" [[widget.fields]] key = "stage" label = "Stage" type = "badge" [view] id = "crm-pipeline" label = "CRM" icon = "contacts" [storage] namespace = "crm" tables = ["contacts", "deals", "activities"] ``` ### `[view]` Section | Field | Type | Required | Description | | ------- | ------ | -------- | ----------------------------------------- | | `id` | string | ✓ | Unique view identifier (used in routing). | | `label` | string | ✓ | Sidebar tab label. | | `icon` | string | ✓ | Material Symbols icon name. | The view registers as a sidebar tab. When clicked, Pawz renders the extension's data from storage using the widget field schema. ### `[storage]` Section | Field | Type | Required | Description | | ----------- | --------- | -------- | ------------------------------------------- | | `namespace` | string | ✓ | Storage namespace (isolated per extension). | | `tables` | string\[] | ✓ | Table names the extension can read/write. | Storage is backed by SQLite. Each extension has its own namespace — no extension can read another extension's data. *** ## Storage Tools Extensions expose three agent tools for persistent data management: | Tool | Parameters | Description | | ------------------- | ----------------------------------------- | -------------------------- | | `skill_store_set` | `namespace`, `table`, `id`, `data` (JSON) | Create or update a record | | `skill_store_get` | `namespace`, `table`, `id` | Get a record by ID | | `skill_store_query` | `namespace`, `table`, `filter` (JSON) | Query records with filters | ### Example: Agent interaction **User**: "Add a new contact — John Smith, [john@acme.com](mailto:john@acme.com), Acme Corp" **Agent** calls `skill_store_set`: ```json theme={null} { "namespace": "crm", "table": "contacts", "id": "john-smith", "data": { "name": "John Smith", "email": "john@acme.com", "company": "Acme Corp", "stage": "new", "created": "2025-01-21T10:30:00Z" } } ``` **User**: "Show me all contacts at Acme" **Agent** calls `skill_store_query`: ```json theme={null} { "namespace": "crm", "table": "contacts", "filter": { "company": "Acme Corp" } } ``` *** ## Example Extensions ### CRM Pipeline Track contacts, deals, and activities. The sidebar view shows a Kanban-style pipeline with deal stages. Dashboard widget shows active deal summary. | Credentials | Storage | Widget | | ----------------------- | --------------------------- | ------------------- | | Optional webhook import | contacts, deals, activities | Table: Active Deals | ### Smart Home Dashboard Control and monitor your IoT devices from a dedicated sidebar tab. Combines Philips Hue, Sonos, and Eight Sleep into one unified view. | Credentials | Storage | Widget | | ----------------- | ---------------------------- | ----------------- | | Device API tokens | devices, scenes, automations | KV: Device Status | ### Portfolio Tracker Unified portfolio view across all exchanges and wallets. The sidebar shows allocation charts, P\&L, and trade history. | Credentials | Storage | Widget | | ----------------- | --------------------------- | ----------------------- | | Exchange API keys | holdings, trades, snapshots | Metric: Portfolio Value | ### Content Calendar Plan, schedule, and track content across platforms. The sidebar shows a calendar grid with publish dates and status badges. | Credentials | Storage | Widget | | ------------------- | --------------------------- | --------------------- | | Social media tokens | posts, campaigns, analytics | Table: Upcoming Posts | *** ## Modular Workspace Integration Extension sidebar views integrate with the [Modular Workspace](/docs/guides/modular-workspace) system: * Extension views appear in the **Custom** workspace profile toggle grid * Users can show/hide extension views like any built-in view * Extension views respect the active workspace profile * Hidden extension views preserve their data — nothing is lost When you install an extension, its sidebar tab appears automatically. If you're using a preset workspace profile (Developer, Marketer, etc.), you may need to switch to **Custom** or **All** to see the extension view. *** ## Per-Agent Scoping Like Skills and Integrations, Extensions are assigned to agents from the **Agents** tab: 1. Open the **Agents** tab → select an agent → go to their **Skills** sub-tab 2. Enable or disable the extension for that agent 3. Only assigned agents receive the extension's instructions and credentials in their prompt 4. All agents can *read* from the extension's storage (for dashboard rendering) 5. Only assigned agents can *write* to the extension's storage 6. The extension's sidebar view is always visible (it shows data, not agent context) *** ## Creating Extensions Extensions are created the same way as integrations, with the addition of `[view]` and `[storage]` sections: 1. Start with the **In-App Wizard** or a template 2. Add your credentials and instructions (same as an integration) 3. Add a `[view]` section to declare a sidebar tab 4. Add a `[storage]` section to declare persistent tables 5. Test with a live agent — use chat to populate storage, verify the view renders 6. Publish to PawzHub ### Upgrade Path You can upgrade a Skill to an Integration to an Extension incrementally: ```mermaid actions={false} theme={null} graph TD A["SKILL.md\nTier 1 — Skill"]:::blue -->|add credentials + TOML| B["pawz-skill.toml\nTier 2 — Integration"]:::purple B -->|"add [view] + [storage]"| C["pawz-skill.toml + view\nTier 3 — Extension"]:::gold classDef blue fill:#3b82f6,color:#fff,stroke:#3b82f6 classDef purple fill:#a855f7,color:#fff,stroke:#a855f7 classDef gold fill:#eab308,color:#000,stroke:#eab308 ``` Each step is additive. You never need to rewrite — you just add more sections to the manifest. *** ## Security Extensions have the same security model as Integrations, with additional protections for storage: | Layer | Protection | | ------------------- | ---------------------------------------------------------------- | | **Credentials** | XOR-encrypted, 32-byte key in OS keychain | | **Network** | Domain allowlist/blocklist on every `fetch` | | **Shell** | Docker sandbox routing when enabled | | **Storage** | Namespaced — extensions cannot read/write other extensions' data | | **Write isolation** | Only assigned agents can write to storage | | **View rendering** | Views are rendered by the app, not by the extension | | **Resource limits** | Storage quotas prevent any single extension from filling disk | Extensions cannot: * Execute arbitrary Rust code * Render arbitrary HTML/JavaScript (views use the app's renderer) * Access other extensions' storage namespaces * Write to storage from unassigned agents * Bypass domain or shell policies *** ## Tier Badges Every item in the Skills tab shows its tier badge: | Badge | Color | Meaning | | ------------------ | ---------------- | ------------------------------------- | | 🔵 **Skill** | Blue `#3B82F6` | SKILL.md — prompt injection only | | 🟣 **Integration** | Purple `#8B5CF6` | TOML — credentials, binaries, widgets | | 🟡 **Extension** | Gold `#F59E0B` | TOML — views, storage, full power | Additional quality badges: | Badge | Meaning | | -------------- | ---------------------------------------- | | ✓ **Verified** | Tested in a real workspace, CI-validated | | ★ **Official** | Published by the Pawz team | | 🔥 **Popular** | 50K+ installs | # Flows Source: https://docs.openpawz.ai/guides/flows Build visual AI workflows by connecting integrations on a drag-and-drop canvas — triggers, agents, tools, conditions, code, and outputs. # Flows Flows is a visual workflow builder for creating multi-step AI pipelines. Drag integrations onto a canvas, wire them together, and run — no code required. ## How it works ```mermaid actions={false} theme={null} graph LR A["Trigger"] --> B["Agent"] B --> C["Condition"] C -->|yes| D["Tool"] C -->|no| E["Output"] D --> E ``` 1. Open **Flows** from the sidebar 2. Click **+ New** or describe a flow in the text box 3. Drag integrations onto the canvas and wire them together 4. Configure each integration in the properties panel 5. Click **Run** to execute the flow ## Integration types Every step in a flow is an integration. There are 10 kinds: | Kind | Icon | Purpose | | ----------------- | ---- | ------------------------------------------------------------------------------------------ | | **Trigger** | ⚡ | Event that starts the flow — webhook, cron, or user input | | **Agent** | 🤖 | AI agent processing step — sends a prompt and gets a response | | **Tool** | 🔧 | MCP tool invocation — call any connected tool | | **Condition** | 🔀 | If/else branch — route data based on expressions | | **Data** | 📊 | Data transform — map, parse, format, convert | | **Code** | 💻 | Inline JavaScript — sandboxed execution with `input`/`context` | | **Output** | 📤 | Terminal step — log, send, store, or post to chat | | **Error** | ⚠️ | Error handler — catches failures from upstream integrations | | **Group** | 📁 | Sub-flow — compound integration containing nested steps | | **Event Horizon** | 🌀 | Synchronization barrier — collects outputs from parallel tesseract cells before continuing | ## Edge types Edges connect integrations. Four kinds control data flow direction: | Edge | Meaning | | ----------------- | ---------------------------------------------------------- | | **Forward** | Normal `A → B` — data flows from source to target | | **Reverse** | Pull `B ← A` — target requests data from source | | **Bidirectional** | Handshake `A ↔ B` — two-way data exchange | | **Error** | Fallback `A --err→ B` — routes to error handler on failure | ## Building flows ### Canvas controls | Action | How | | ------------------- | ------------------------------------------------------------------ | | **Pan** | Click and drag the canvas background | | **Add integration** | Click an add button in the toolbar, or type in the text box | | **Select** | Click an integration on the canvas | | **Move** | Drag a selected integration | | **Connect** | Drag from an output port (right side) to an input port (left side) | | **Delete** | Select an integration or edge, then press the delete button | | **Zoom** | Scroll wheel on the canvas | ### Text-to-flow Type a natural-language description in the text box at the top and press Enter. The parser recognizes keywords and creates a flow automatically: ``` webhook → agent summarize → if important → send email ``` Keyword detection maps words to integration types: | Keywords | Maps to | | ------------------------------------------- | --------- | | `trigger`, `webhook`, `cron`, `on`, `when` | Trigger | | `agent`, `ai`, `llm`, `ask`, `think` | Agent | | `tool`, `mcp`, `call`, `api`, `fetch` | Tool | | `if`, `condition`, `branch`, `check` | Condition | | `data`, `transform`, `map`, `parse` | Data | | `output`, `send`, `email`, `notify`, `save` | Output | ### Properties panel Click any integration on the canvas to open its configuration panel: * **Label** — display name on the canvas * **Description** — sub-label (model name, tool ID, etc.) * **Kind** — integration type (trigger, agent, tool, etc.) * **Config** — kind-specific settings: * **Agent**: prompt text, assigned agent (dropdown of your real agents) * **Code**: inline JavaScript with `input` and `context` variables * **Condition**: expression to evaluate * **Tool**: MCP tool name and parameters When no integration is selected, the panel shows **flow properties** — name, description, folder, and stats. ## Folders Flows can be organized into folders: 1. Open flow properties (click canvas background) 2. Set the **Folder** field (e.g. `Production`, `Drafts`) 3. Flows are grouped by folder in the sidebar with collapsible headers Drag and drop flows between folders in the sidebar. ## Templates Switch to the **Templates** tab in the sidebar to browse pre-built flow patterns. ### Categories | Category | Examples | | --------------------- | --------------------------------------------- | | **AI & Agents** | Daily Digest, Multi-Agent Debate, Agent Chain | | **Communication** | Email Auto-Responder, Team Notifications | | **DevOps & CI** | Deploy Pipeline, Health Monitor | | **Productivity** | Task Triage, Meeting Prep | | **Data & Transform** | CSV Pipeline, Data Enrichment | | **Research** | Deep Research, Literature Review | | **Social & Content** | Content Calendar, Social Listener | | **Finance & Trading** | Portfolio Monitor, Price Alerts | | **Support** | Ticket Router, FAQ Bot | | **Custom** | Build your own from scratch | Click **Use Template** to instantiate a template as a new flow with auto-layout. ### Search & filter * Type in the search box to filter by name, description, or tags * Click a category chip to filter by category * Click **All** to reset ## Execution ### Running a flow 1. Select a flow from the sidebar 2. Click the **Run** button (▶) in the toolbar 3. Watch integrations execute in order — status indicators show progress: * 🔴 **Running** — red breathing pulse * 🟢 **Success** — sage green border * ❌ **Error** — red border * ⏸ **Paused** — gold oscillating border Data flows along edges with animated signal sweep. ### Debug mode Step through a flow one integration at a time: 1. Click the **Debug** button (🐛) in the toolbar 2. Set **breakpoints** by right-clicking integrations 3. Use **Step** to advance one integration at a time 4. Inspect intermediate data values shown on edges 5. View the **debug inspector** panel for full input/output of each step The execution cursor highlights the current integration with a gold ring. ### Error handling * **Error edges** route failures to error handler integrations * **Error integrations** catch and process failures (log, alert, retry) * The flow report in chat shows step-by-step results with timing ## Scheduling Flows can run on a schedule using cron expressions: 1. Open a flow's properties panel 2. Enable the **Schedule** toggle 3. Enter a cron expression ``` 0 9 * * * Every day at 9 AM 0 */2 * * * Every 2 hours 0 9 * * 1-5 Weekdays at 9 AM */30 * * * * Every 30 minutes ``` The scheduler checks every **30 seconds** for flows due to fire. The hero stat counter shows how many flows have active schedules. ## Code integrations Code integrations run sandboxed JavaScript: ```javascript theme={null} // Available variables: // input — output from the previous integration // context — { flowId, nodeId, runId } const data = JSON.parse(input); return data.items.filter(item => item.score > 0.8); ``` * Code runs in a sandboxed `Function()` constructor — no access to DOM, fetch, or filesystem * Return value becomes the integration's output, passed to downstream integrations * Timeout enforced to prevent infinite loops ## Chat reporter When a flow runs, a **flow report** appears in the chat conversation showing: * Flow name and step count * Progress bar * Each step's status, duration, and output * Final summary with success/error counts and total duration ## Conductor Protocol The Conductor is an automatic optimization layer that analyzes flow graphs before execution. When the graph contains parallelizable structures, the Conductor compiles an `ExecutionStrategy` with optimized units: | Primitive | What it does | | --------------- | ---------------------------------------------------------------------------------- | | **Collapse** | Merges a sequence of non-branching nodes into a single execution unit | | **Extract** | Isolates a node with no internal dependencies for early execution | | **Parallelize** | Runs independent branches concurrently via `Promise.all` | | **Converge** | Waits for all parallel branches to finish before continuing | | **Tesseract** | Orchestrates parallel cells across phase and depth, synchronized at event horizons | The Conductor activates automatically when a flow has 4+ nodes, any parallel branches, or a mix of agent and non-agent nodes. No manual configuration is needed. → Deep dive: [Conductor Protocol reference](/reference/conductor-protocol) ### Tesseract flows A **tesseract flow** partitions the graph into independent **cells** — sub-graphs that share no data edges between them. Each cell executes its agents in topological order, and all cells run in parallel. An **event horizon** node acts as a synchronization barrier, collecting outputs from every cell via `mergeAtHorizon` before the flow continues. Tesseract flows are detected automatically when the graph contains 2+ disconnected agent clusters separated by non-agent boundaries. ### Memory integration Before any node executes, the flow executor pre-recalls relevant long-term memories from the Engram memory system. Agent nodes receive these memories in a `[Relevant Memory]` section in their prompts. In tesseract flows, each cell gets its own **cell-scoped memory** — resolved from the cell's specific agent prompts — so parallel cells never race on shared memory state. → Deep dive: [Memory guide](/guides/memory#flow-memory-integration) ## Persistence * Flows are stored locally in `localStorage` under key `openpawz-flows` * All data stays on your machine — no cloud sync * Export/import via JSON serialization ## Keyboard shortcuts | Key | Action | | ---------------------- | ----------------------------------- | | `Delete` / `Backspace` | Delete selected integration or edge | | `Escape` | Deselect all | # Foundry — Models & Chat Modes Source: https://docs.openpawz.ai/guides/foundry The Foundry is your control center for managing AI providers and creating reusable chat mode presets. It provides two tabs: Models and Chat Modes. # Foundry — Models & Chat Modes The Foundry is your control center for managing AI providers and creating reusable chat mode presets. It provides two tabs: **Models** and **Chat Modes**. ## Models tab The Models tab displays all configured AI providers as cards, giving you a quick overview of your setup. ### Provider cards Each provider card shows: | Field | Description | | ----------------- | -------------------------------------------------------------- | | **Kind** | Provider type (e.g. `anthropic`, `openai`, `ollama`, `google`) | | **Endpoint** | Base URL for the provider API | | **Model** | Currently selected model | | **Key status** | Whether an API key is configured (shown as a badge) | | **Default badge** | Indicates if this is your default provider | ### Supported providers | Provider | Kind | Default Endpoint | | ------------- | ------------ | -------------------------------------------------- | | Ollama | `ollama` | `http://localhost:11434` | | OpenAI | `openai` | `https://api.openai.com/v1` | | Anthropic | `anthropic` | `https://api.anthropic.com` | | Google | `google` | `https://generativelanguage.googleapis.com/v1beta` | | DeepSeek | `deepseek` | `https://api.deepseek.com/v1` | | xAI (Grok) | `grok` | `https://api.x.ai/v1` | | Mistral | `mistral` | `https://api.mistral.ai/v1` | | Moonshot/Kimi | `moonshot` | `https://api.moonshot.cn/v1` | | OpenRouter | `openrouter` | `https://openrouter.ai/api/v1` | | Custom | `custom` | User-defined | ### Setting a default provider To set a provider as default, go to **Settings → Advanced**, find the provider card, and click **Make Default**. The default provider is used for all conversations unless overridden by an agent or chat mode. ## Chat Modes tab Chat Modes are named presets that let you instantly switch between different conversation configurations. Think of them as "profiles" for how the AI behaves. ### Mode properties | Property | Description | | ------------------ | --------------------------------------------------- | | **Name** | Display name for the mode | | **Model** | AI model to use when this mode is active | | **System prompt** | Custom system prompt injected for this mode | | **Thinking level** | AI reasoning depth: `none`, `low`, `medium`, `high` | | **Temperature** | Randomness control (0.0–2.0) | | **Icon** | Emoji or symbol for quick identification | | **Color** | Visual accent color for the mode | ### Creating a chat mode 1. Open the **Foundry** view 2. Switch to the **Chat Modes** tab 3. Click **New Mode** 4. Fill in the mode properties in the form modal 5. Save ### Example modes | Mode | Model | Temperature | Thinking | Use case | | ---------------- | ------------------- | ----------- | -------- | --------------------------- | | Quick Chat | `claude-3-haiku` | 0.7 | none | Fast, lightweight responses | | Deep Analysis | `claude-opus-4-6` | 0.3 | high | Complex reasoning tasks | | Creative Writing | `claude-sonnet-4-6` | 1.0 | medium | Stories, brainstorming | | Code Review | `gpt-4o` | 0.2 | low | Precise, technical feedback | ### Managing modes * **Edit**: Click a mode card to open the edit form * **Delete**: Remove a mode you no longer need * **Switch**: Use the `/mode ` slash command to activate a mode during conversation ``` /mode Deep Analysis ``` ### Storage Chat modes are stored in the **frontend SQLite** database in the `agent_modes` table. This means they persist across sessions and are available immediately on app restart. :::tip Create a "Cost Saver" mode with a cheap model like `claude-3-haiku` or `gpt-4o-mini` for simple tasks, and a "Heavy Lifting" mode with a powerful model for complex work. Switch between them with `/mode` to manage costs. ::: :::info Chat modes override the default provider/model for the duration of the conversation. Agent-specific model overrides take highest priority over chat modes. ::: # Google Workspace Source: https://docs.openpawz.ai/guides/google-workspace Connect Pawz to Gmail, Calendar, Drive, Sheets, and Docs — just click Connect with Google. # Google Workspace Connect Pawz to Gmail, Calendar, Drive, Sheets, and Docs. He can read your inbox, send emails, schedule meetings, browse files, and read/write spreadsheets — all hands-free. ## What Pawz Can Do With Google Once connected, Pawz gets 10 Google tools: **Email (Gmail)** * Read your inbox, search for specific emails ("find all unread emails from Sarah") * Read full email contents * Send emails as you (to anyone, with CC, plain text or HTML) **Calendar** * See your upcoming schedule ("what meetings do I have this week?") * Create events with attendees, location, and description **Drive** * Browse and search your Google Drive files * Read the contents of Docs, Sheets, PDFs, and text files **Sheets** * Read spreadsheet data (shows as formatted tables) * Add new rows to spreadsheets (great for logging, tracking, data entry) **Any Google API** * A generic tool that can hit any Google REST API endpoint for anything not covered above *** ## Setup 1. Go to **Skills** → **Google Workspace** → **Enable** it 2. Click **Connect with Google** 3. Your browser opens — sign in with your Google account and click **Allow** 4. The browser says "Pawz Connected!" — you can close it 5. Back in Pawz, you should see **"Connected as [you@gmail.com](mailto:you@gmail.com)"** That's it. Try telling Pawz: * *"Check my inbox"* * *"What's on my calendar this week?"* * *"Send an email to [hello@example.com](mailto:hello@example.com) saying hi"* * *"What files are in my Google Drive?"* You'll see a "This app isn't verified" warning from Google during sign-in. This is normal — click **Advanced** → **Go to Pawz (unsafe)** to continue. *** ## Gmail Search Tips When asking Pawz to find specific emails, he uses Gmail's search syntax under the hood: | What you say | What Pawz searches | | ---------------------------------------- | --------------------------------- | | "Find unread emails" | `is:unread` | | "Emails from Sarah" | `from:sarah@...` | | "Emails about invoices" | `subject:invoice` | | "Emails with attachments from last week" | `has:attachment after:2026/02/16` | | "Starred emails" | `is:starred` | *** ## Disconnecting Go to **Skills** → **Google Workspace** → **Disconnect**. You can also revoke Pawz's access from [myaccount.google.com/permissions](https://myaccount.google.com/permissions). *** ## Security * Your refresh token is **encrypted** in Pawz's credential vault (AES-256-GCM) — not stored in plain text * Access tokens live in memory only, never written to disk, and expire after 1 hour * Pawz only requests the permissions it needs (Gmail, Calendar, Drive, Sheets, Docs) *** ## Self-Hosted Builds If you're building Pawz from source, the bundled Google OAuth credentials aren't included. You have two options: ### Option A: Set Build-Time Credentials Set these environment variables before building: ```bash theme={null} export PAW_GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com" export PAW_GOOGLE_CLIENT_SECRET="GOCSPX-your-secret" cargo tauri build ``` To get these values, create an OAuth 2.0 Client ID in [Google Cloud Console](https://console.cloud.google.com/apis/credentials/oauthclient) → choose **Desktop app**. You'll also need to [enable the APIs](https://console.cloud.google.com/apis/library) (Gmail, Calendar, Drive, Sheets, Docs) and [set up an OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent). ### Option B: Paste Credentials in the UI Without build-time credentials, Pawz will show Client ID and Client Secret fields in the Google Workspace skill settings. Paste your own OAuth credentials there, then click **Connect with Google**. *** ## Enterprise Setup (Service Account) This is for **Google Workspace admins** who want server-to-server auth with domain-wide delegation. Most users should use the OAuth flow above. If you need Pawz to act as a dedicated robot user (e.g. `pawz@yourdomain.com`) without interactive login — use a service account: 1. [Create a Google Cloud project](https://console.cloud.google.com/projectcreate) and [enable the APIs](https://console.cloud.google.com/apis/library) 2. [Create a service account](https://console.cloud.google.com/iam-admin/serviceaccounts/create) → download the JSON key 3. [Set up domain-wide delegation](https://admin.google.com/ac/owl/domainwidedelegation) with the service account's Client ID and the required scopes 4. In Pawz: Skills → Google Workspace → open the **Enterprise — Service Account** section → paste the JSON key and delegated email *** ## Troubleshooting **"Connect with Google" opens browser but nothing happens** The consent flow has a 2-minute timeout. Make sure you complete sign-in and click Allow within that time. If it times out, just click Connect again. **"Google OAuth failed: Token exchange failed"** For self-hosted builds: double-check your Client ID and Secret. For official builds: try disconnecting and reconnecting. **"Google API error (403): Insufficient Permission"** One or more Google APIs may not be enabled for the project backing the OAuth credentials. **"Access denied" or "This app isn't verified" warning** Click **Advanced** → **Go to Pawz (unsafe)** to proceed. This is normal. **Calendar times are wrong** Tell Pawz to use natural language like "tomorrow at 2pm" — he'll format it correctly. # Integration Guardrails Source: https://docs.openpawz.ai/guides/integration-guardrails Safety controls for agent-driven integrations: action risk classification, per-service rate limits, agent permissions, dry-run plans, and credential audit logging. # Integration Guardrails When agents interact with third-party services (Slack, GitHub, Gmail, Stripe, etc.), guardrails ensure they can't take destructive actions without oversight, exceed rate limits, or operate outside their assigned permissions. Guardrails are enforced at the **engine level** — they apply to all channels, all agents, and all integration methods (MCP Bridge, REST API, and direct tool calls). *** ## Action Risk Classification Every integration action is classified by its verb into one of three risk levels: | Risk Level | Behavior | Example Verbs | | ---------- | ---------------------------------------- | ------------------------------------------------------------------------------------------- | | **Auto** | Executed immediately, no approval needed | `list`, `get`, `search`, `read`, `fetch`, `count`, `check` | | **Soft** | Preview card shown before execution | `send`, `create`, `update`, `post`, `comment`, `assign`, `move`, `upload`, `pin` | | **Hard** | Explicit confirmation dialog required | `delete`, `remove`, `archive`, `close`, `bulk_send`, `transfer`, `modify_billing`, `revoke` | ### How classification works The engine scans the action verb for known keywords. The first matching verb determines the risk level. If no known verb is found, the action defaults to **soft** (preview required) — erring on the side of caution. ```mermaid actions={false} theme={null} graph TD A["Agent wants to call\nslack_send_message"] --> B["Extract verb: send"] B --> C{"Verb in risk map?"} C -->|"send → soft"| D["Show preview card\nUser can approve/reject"] C -->|"Unknown verb"| E["Default to soft\nShow preview card"] D --> F["User approves → Execute"] ``` ### Risk metadata Each risk level carries UI metadata for consistent display: | Level | Icon | Label | Color | | ----- | -------------- | ------------- | ------ | | Auto | `check_circle` | Auto-approved | Green | | Soft | `visibility` | Preview | Yellow | | Hard | `warning` | Confirm | Red | *** ## Rate Limits Per-service rate limits prevent runaway agents from spamming APIs. Each service has a configured maximum number of actions within a sliding time window. ### Default limits | Service | Max Actions | Window | | ------------- | ----------- | ------ | | Slack | 30 | 15 min | | Discord | 30 | 15 min | | Telegram | 30 | 15 min | | Gmail | 10 | 15 min | | SendGrid | 10 | 15 min | | GitHub | 20 | 15 min | | Jira | 20 | 15 min | | Linear | 20 | 15 min | | HubSpot | 20 | 15 min | | Salesforce | 20 | 15 min | | Trello | 20 | 15 min | | Notion | 20 | 15 min | | Google Sheets | 30 | 15 min | | Shopify | 15 | 15 min | | Stripe | 10 | 15 min | | Twilio | 15 | 15 min | | Zendesk | 20 | 15 min | | **Other** | 50 | 15 min | Unlisted services fall back to the generic limit of **50 actions per 15 minutes**. You can override limits per-service in Settings. ### How rate limiting works The engine tracks actions per service in a sliding window: 1. Each action increments the service counter 2. If the counter exceeds `maxActions`, the action is **blocked** 3. The window resets automatically after `windowMinutes` 4. You can manually reset a service's window (e.g., after resolving an issue) ### Rate limit response When an agent hits a rate limit, it receives: ```json theme={null} { "allowed": false, "remaining": 0, "limit": 30 } ``` The agent is informed that the action was blocked and how many actions remain in the current window. *** ## Agent Service Permissions Each agent can be assigned a specific **access level** per integration service, controlling what kinds of actions it's allowed to perform. ### Access levels | Level | Can Do | Icon | | --------- | ------------------------------------------------ | ---------------------- | | **None** | Nothing — service is completely blocked | `block` | | **Read** | Only auto-risk actions (list, get, search, read) | `visibility` | | **Write** | All actions including reads, writes, and deletes | `edit` | | **Full** | Everything — no restrictions at all | `admin_panel_settings` | ### How permissions are checked ```mermaid actions={false} theme={null} graph TD A["Agent calls\ngithub_delete_repo"] --> B["Look up agent's\naccess level for GitHub"] B --> C{"Access level?"} C -->|"none"| D["❌ Blocked"] C -->|"read"| E{"Is action auto-risk?"} C -->|"write / full"| F["✅ Allowed"] E -->|"delete → hard"| G["❌ Blocked"] E -->|"list → auto"| H["✅ Allowed"] ``` Set research agents to **Read** access and action agents to **Write**. Reserve **Full** access for your primary agent. *** ## Dry-Run Plans Before executing multi-step integration workflows, agents can generate a **dry-run plan** that shows every action they intend to take — with risk levels, targets, and previews. ### Plan structure | Field | Description | | ----------- | --------------------------------------------------------- | | **Steps** | Ordered list of actions the agent will take | | **Service** | Which integration each step targets | | **Action** | The specific action (e.g., `send_message`, `delete_repo`) | | **Target** | What the action operates on (e.g., `#general`, `my-repo`) | | **Risk** | Auto / Soft / Hard classification | | **Preview** | Optional human-readable description of the action | ### Automatic confirmation required A plan requires explicit user confirmation when: * **Any step is hard-risk** (delete, archive, transfer, etc.) * **The plan has more than 3 steps** (regardless of risk levels) This prevents agents from silently executing long chains of actions. ### Example plan ``` Plan: Deploy notification pipeline ───────────────────────────────── 1. [auto] GitHub → list_repos → org/backend "List repos" 2. [soft] GitHub → create_issue → org/backend #142 "Create deploy tracking issue" 3. [soft] Slack → send_message → #deployments "Notify team" 4. [hard] GitHub → archive → org/backend-old "Archive legacy repo" ⚠️ This plan requires confirmation (contains hard-risk action) ``` *** ## Credential Audit Log Every integration action is logged to an audit trail for security review and compliance: | Field | Description | | ---------------- | ------------------------------------------------- | | **Timestamp** | When the action was executed | | **Agent** | Which agent performed the action | | **Service** | Target integration service | | **Action** | The specific action taken | | **Access Level** | The agent's permission level at execution time | | **Approved** | Whether the action was approved (via HIL or auto) | | **Result** | `success`, `denied`, or `failed` | *** ## Related * [Security](/reference/security) — full defense-in-depth overview * [Integrations](/guides/integrations) — how integrations work * [MCP Bridge](/guides/mcp-bridge) — 25,000+ tools via n8n # Integration Health Source: https://docs.openpawz.ai/guides/integration-health Monitor connection status, token expiry, failure rates, and get smart suggestions for connected integrations. # Integration Health The Integration Health system monitors all your connected services in real time — tracking connection status, token expiry, failure rates, and generating smart suggestions to keep everything running smoothly. *** ## Health Status Each connected integration reports one of five statuses: | Status | Icon | Color | Meaning | | ------------ | -------------- | ------ | -------------------------------------------------------------------------- | | **Healthy** | `check_circle` | Green | Connected and working normally | | **Degraded** | `warning` | Yellow | Working but experiencing issues (token expiring soon, occasional failures) | | **Error** | `error` | Red | Multiple recent failures — likely broken | | **Expired** | `lock_clock` | Red | OAuth token or API key has expired | | **Unknown** | `help` | Gray | No credentials configured | ### How status is determined The engine derives health status automatically from three signals: ```mermaid actions={false} theme={null} graph TD A["Check credentials"] --> B{"Has credentials?"} B -->|"No"| C["Unknown"] B -->|"Yes"| D{"Token expiry?"} D -->|"Expired"| E["Expired"] D -->|"≤ 7 days"| F["Degraded"] D -->|"OK / None"| G{"Recent failures?"} G -->|"≥ 3"| H["Error"] G -->|"1–2"| I["Degraded"] G -->|"0"| J["Healthy"] ``` | Signal | Threshold | Result | | ------------------- | ---------- | -------- | | No credentials | — | Unknown | | Token expired | ≤ 0 days | Expired | | Token expiring soon | ≤ 7 days | Degraded | | Frequent failures | ≥ 3 recent | Error | | Occasional failures | 1–2 recent | Degraded | | All clear | — | Healthy | Token expiry takes priority over failure count. If a token is expired, the status is always **Expired** regardless of failure count. *** ## Health Summary The dashboard displays an aggregated health summary across all connected integrations: | Metric | Description | | ------------------- | --------------------------------------------- | | **Total** | Number of connected integrations | | **Healthy** | Services operating normally | | **Degraded** | Services with warnings | | **Error** | Services with persistent failures | | **Expired** | Services with expired credentials | | **Needs Attention** | List of degraded, error, and expired services | ### Dashboard view The Today view shows a compact health bar at the top. Services that need attention are highlighted with their status icon and a brief description of the issue. *** ## Token Expiry Tracking For integrations using OAuth tokens, OpenPawz tracks expiry dates and warns you before they expire. | Days Until Expiry | Action | | ------------------ | ------------------------------------------------------- | | > 7 days | No warning — status remains Healthy | | ≤ 7 days | Status moves to **Degraded** — re-auth reminder shown | | ≤ 0 days (expired) | Status moves to **Expired** — integration stops working | Not all integrations have token expiry. API key–based services (like GitHub personal access tokens or Stripe API keys) don't expire automatically — their status is based solely on failure count. *** ## Smart Suggestions When integrations are connected, OpenPawz generates contextual suggestions on the Today view to help you get started each day. ### Available suggestions | Service | Suggestion | Action | | ----------- | ----------------------------------------------------- | --------------- | | **Gmail** | "You have unread emails — want me to summarize them?" | Summarize inbox | | **Slack** | "Check your Slack messages and mentions" | Check Slack | | **GitHub** | "Review assigned issues and open PRs" | Check GitHub | | **HubSpot** | "Check your sales pipeline and deals" | View deals | | **Trello** | "Check for stale cards on your boards" | Review boards | | **Jira** | "Review your assigned tickets" | Check Jira | Suggestions are capped at **3 per session** to avoid information overload. They're generated from your connected services — disconnected services don't generate suggestions. *** ## Service Health Data Each integration tracks the following metrics: | Field | Description | | --------------------- | ------------------------------------------------ | | **Service** | Integration identifier (e.g., `slack`, `github`) | | **Status** | Current health status | | **Last Checked** | When the service was last verified | | **Token Expiry** | OAuth token expiry date (if applicable) | | **Days Until Expiry** | Countdown to token expiry | | **Recent Failures** | Number of failed actions in the recent window | | **Today's Actions** | Successful actions executed today | | **Message** | Optional status message (e.g., error details) | *** ## Chain Rules Chain rules let you create automated follow-up actions when specific integration events occur. For example: "When a GitHub issue is created, post a message to Slack." ### Rule structure | Field | Description | | -------------- | -------------------------------------------------------------------- | | **Trigger** | Service + action that starts the chain (e.g., `github:create_issue`) | | **Then** | Service + action to execute (e.g., `slack:send_message`) | | **Parameters** | Optional parameters for the follow-up action | | **Enabled** | Toggle the rule on/off | ### Example chains | Trigger | Then | Description | | ------------------------- | --------------------------------- | ----------------------------------- | | `github:create_issue` | `slack:send_message` → `#dev` | Notify team when issues are created | | `gmail:receive_email` | `trello:create_card` | Auto-create tasks from emails | | `stripe:payment_received` | `slack:send_message` → `#revenue` | Revenue notifications | Chain rules are a lightweight alternative to full n8n workflows. Use them for simple "if-this-then-that" automation. For complex multi-step flows, use the [n8n integration](/guides/n8n) instead. *** ## Related * [Integration Guardrails](/guides/integration-guardrails) — risk classification and rate limits * [Integrations](/guides/integrations) — how to install and configure integrations * [Security](/reference/security) — credential encryption and access control # Integrations Source: https://docs.openpawz.ai/guides/integrations # Integrations Integrations are the second tier of the Pawz extensibility system. They connect your agents to third-party APIs and CLI tools with full credential management, binary detection, and optional dashboard widgets. OpenPawz ships with **400+ built-in integrations** compiled into the Rust binary across 12 categories, plus **25,000+ community node types** via the [MCP Bridge](/guides/mcp-bridge) to n8n. Community integrations can be installed via TOML manifests from PawzHub or manually from `~/.paw/skills/`. ```mermaid actions={false} theme={null} graph LR S["Skill\nPrompt-only\nSKILL.md"]:::blue --> I["Integration\nCredentials + Tools\nTOML"]:::purple --> E["Extension\nCustom Views + Storage\nTOML"]:::gold classDef blue fill:#3b82f6,color:#fff,stroke:#3b82f6 classDef purple fill:#a855f7,color:#fff,stroke:#a855f7 classDef gold fill:#eab308,color:#000,stroke:#eab308 style I stroke-width:3px ``` **Integrations vs. Skills**: A [Skill](/docs/guides/skills) is a SKILL.md file that injects instructions into an agent's prompt — zero config. An Integration is a `pawz-skill.toml` file that additionally declares **credentials** (encrypted in the vault), **required binaries** (auto-detected), and optional **dashboard widgets**. *** ## The Integration Inversion Unlike every other automation platform, OpenPawz does not lock integrations inside manual workflow builders. Every integration — including all 25,000+ n8n community packages — is **simultaneously** a direct agent tool and a visual workflow node. When you install a community package (e.g. `n8n-nodes-slack`), Paw auto-deploys a workflow that your agents can execute **immediately in chat** — just ask: *"Hey Pawz, send hello to #general."* The MCP bridge handles workflow discovery, execution, and result delivery automatically. | | Zapier / Make / n8n (standalone) | OpenPawz | | ------------------------- | -------------------------------- | -------------------------------------------- | | **Tool availability** | Locked inside manual workflows | Available in chat AND in visual flows | | **To use an integration** | Build trigger → action chain | Just ask your agent | | **AI's role** | One node inside the pipeline | The pipeline lives inside the agent | | **Install a new package** | Manual workflow building | Auto-deployed workflow + instant chat access | **How it works:** OpenPawz embeds n8n as an [MCP server](/guides/mcp-bridge). n8n's MCP exposes three workflow-level tools (`search_workflows`, `execute_workflow`, `get_workflow_details`). When you install a community package, Paw auto-deploys a per-service workflow and indexes it. The [Librarian](/reference/librarian-method) finds workflows via semantic search, and the [Foreman](/reference/foreman-protocol) executes them at minimal cost. The visual [Flow Builder](/guides/flows) is there for when you need multi-step orchestration with branching, loops, or scheduling — but for single actions, just chat. *** ## How Integrations Work 1. **Author** creates a `pawz-skill.toml` manifest declaring what the integration does, what credentials it needs, and how the agent should use it 2. **Install** via PawzHub (in-app browser) or manually into `~/.paw/skills/{id}/` 3. **Configure** credentials in the **Skills** tab — Pawz generates the input form automatically from the manifest 4. **Assign to agents** — open the **Agents** tab, select an agent, and enable the integration in their Skills sub-tab 5. **Use** — the agent receives decrypted credentials and instructions in its system prompt, then calls APIs via `fetch` or CLI tools via `exec` ```mermaid actions={false} theme={null} graph TD A["User enters API key\nin Skills tab"] --> B["AES-256-GCM encrypted\nkey in unified OS keychain vault"] B --> C["Stored in SQLite\nEncrypted blob"] C --> D["On prompt build:\ndecrypted in memory"] D --> E["Injected into system prompt\nNOTION_API_KEY = secret_abc..."] E --> F["Agent calls fetch\nwith Authorization header"] F --> G["Domain allowlist\nenforced"] ``` *** ## The Manifest Format Every integration is a single `pawz-skill.toml` file: ```toml theme={null} [skill] id = "notion" name = "Notion" version = "1.0.0" author = "yourname" category = "productivity" icon = "edit_note" description = "Read and write Notion pages, databases, and blocks via the API" install_hint = "Get your API key at https://www.notion.so/my-integrations" [[credentials]] key = "NOTION_API_KEY" label = "Integration Token" description = "Your Notion internal integration token" required = true placeholder = "secret_..." [instructions] text = """ You have access to the Notion API via the user's integration token. ## Reading pages Use `fetch` with: - URL: `https://api.notion.so/v1/pages/{page_id}` - Headers: `Authorization: Bearer {NOTION_API_KEY}`, `Notion-Version: 2022-06-28` ## Searching Use `fetch` with POST to `https://api.notion.so/v1/search` Body: {"query": "search term"} """ [widget] type = "table" title = "Recent Pages" refresh = "10m" [[widget.fields]] key = "title" label = "Page" type = "text" [[widget.fields]] key = "updated" label = "Last Updated" type = "datetime" [[widget.fields]] key = "status" label = "Status" type = "badge" ``` ### Manifest Fields #### `[skill]` — Required | Field | Type | Required | Description | | -------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------- | | `id` | string | ✓ | Unique identifier. Alphanumeric + hyphens only. | | `name` | string | ✓ | Display name. | | `version` | string | ✓ | Semver version (e.g. `1.0.0`). | | `author` | string | ✓ | Author name or GitHub username. | | `category` | string | ✓ | One of: `vault`, `cli`, `api`, `productivity`, `media`, `smart_home`, `communication`, `development`, `system`. | | `icon` | string | — | Material Symbols icon name (e.g. `edit_note`). | | `description` | string | ✓ | Short description (10–500 chars). | | `install_hint` | string | — | Instructions for getting credentials. | #### `[[credentials]]` — Optional, repeatable Declare API keys, tokens, or secrets the integration requires. Users enter these in the Skills tab. Pawz encrypts them with AES-256-GCM (32-byte random key in the unified OS keychain vault) and injects decrypted values into the agent's system prompt at runtime. | Field | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------------- | | `key` | string | ✓ | Env var name (e.g. `NOTION_API_KEY`). | | `label` | string | ✓ | UI label shown to the user. | | `description` | string | — | Help text for where to find this credential. | | `required` | bool | ✓ | Whether the integration works without it. | | `placeholder` | string | — | Example value in the input field. | :::info Credential Security Credentials are never stored in plain text. They are encrypted in SQLite using AES-256-GCM with a 32-byte random key stored in your unified OS keychain vault (service: `openpawz`). Decrypted values exist only in the agent’s system prompt at runtime — never logged, never written to disk unencrypted, never transmitted externally. ::: #### `[instructions]` — Required | Field | Type | Required | Description | | ------ | ------ | -------- | ------------------- | | `text` | string | ✓ | Agent instructions. | The instructions tell the agent which endpoints to call, which CLI commands to run, how to authenticate, how to parse responses, and how to handle errors. At runtime, the engine appends a credentials block: ``` Credentials (use these values directly — do NOT ask the user for them): - NOTION_API_KEY = secret_abc123... ``` #### `[widget]` — Optional Declare a dashboard widget for persistent visual output on the Today/Dashboard view. | Field | Type | Required | Description | | --------- | ------ | -------- | -------------------------------------------- | | `type` | string | ✓ | `status`, `metric`, `table`, `log`, or `kv`. | | `title` | string | ✓ | Widget card title. | | `refresh` | string | — | Auto-refresh interval (e.g. `5m`, `1h`). | See [Widget Types](#widget-types) for examples of each type. *** ## Widget Types Integrations can declare a dashboard widget to display persistent structured data. The widget card appears on the Dashboard alongside weather, tasks, and quick actions. ### Status Single status indicator — service health, connection state, on/off checks. ```toml theme={null} [widget] type = "status" title = "Server Status" [[widget.fields]] key = "status" label = "State" type = "badge" [[widget.fields]] key = "uptime" label = "Uptime" type = "percentage" ``` ### Metric Single large number with trend — KPIs, revenue, counts. ```toml theme={null} [widget] type = "metric" title = "Monthly Revenue" [[widget.fields]] key = "value" label = "MRR" type = "currency" [[widget.fields]] key = "change" label = "vs Last Month" type = "percentage" ``` ### Table Rows of structured data — issues, deployments, records. ```toml theme={null} [widget] type = "table" title = "Active Issues" [[widget.fields]] key = "title" label = "Issue" type = "text" [[widget.fields]] key = "priority" label = "Priority" type = "badge" ``` ### Log Chronological event feed — incidents, messages, activity. ```toml theme={null} [widget] type = "log" title = "Recent Incidents" [[widget.fields]] key = "message" label = "Event" type = "text" [[widget.fields]] key = "severity" label = "Level" type = "badge" ``` ### Key-Value (KV) Key-value pairs — stats, config summaries, metadata. ```toml theme={null} [widget] type = "kv" title = "Project Stats" [[widget.fields]] key = "total_records" label = "Records" type = "number" [[widget.fields]] key = "storage_used" label = "Storage" type = "text" ``` ### Field Types | Type | Rendering | Example | | ------------ | ------------------------------- | ---------------------- | | `text` | Plain text | "Deploy to production" | | `number` | Locale-formatted | "1,234,567" | | `badge` | Colored pill (green/yellow/red) | "Active" | | `datetime` | Relative time | "2 hours ago" | | `percentage` | Progress bar + number | "94.5%" | | `currency` | Dollar symbol + formatted | "\$12,450.00" | *** ## Built-in Integrations Pawz ships with **400+ built-in integrations** across 12 categories. These are compiled into the binary and available immediately — configure credentials and assign to agents. No plugins to install, no marketplace to browse. | Category | Count | Examples | | -------------------------- | ----- | ---------------------------------------------------------------------------------------------------------------------- | | **Productivity** | 40+ | Notion, Trello, Obsidian, Linear, Jira, Asana, Todoist, Apple Notes, Reminders, Things 3, Bear Notes, Google Workspace | | **Communication** | 30+ | Slack, Discord, Telegram, WhatsApp, Teams, Email (IMAP/SMTP), iMessage, Intercom | | **Development** | 50+ | GitHub, GitLab, Bitbucket, Docker, Kubernetes, Vercel, Netlify, tmux, Session Logs | | **Data & Analytics** | 35+ | PostgreSQL, MongoDB, Redis, Elasticsearch, BigQuery, Snowflake, Supabase | | **Media & Content** | 25+ | Spotify, YouTube, Whisper, ElevenLabs, Image Gen, DALL-E, Video Frames, GIF Search | | **Smart Home & IoT** | 20+ | Philips Hue, Sonos, Home Assistant, Eight Sleep, MQTT, Zigbee, Camera Capture | | **Finance & Trading** | 30+ | Coinbase, Solana DEX, Ethereum DEX, Stripe, PayPal, QuickBooks, Plaid | | **Cloud & Infrastructure** | 40+ | AWS, GCP, Azure, Cloudflare, DigitalOcean, Terraform, Pulumi | | **Security & Monitoring** | 25+ | 1Password, Vault, Datadog, PagerDuty, Sentry, Grafana, Peekaboo | | **AI & ML** | 20+ | Hugging Face, Replicate, Stability AI, Pinecone, Weaviate, OpenAI | | **CRM & Marketing** | 30+ | Salesforce, HubSpot, Mailchimp, SendGrid, ActiveCampaign | | **Miscellaneous** | 55+ | Weather, RSS, Blog Watcher, Web Scraping, PDF, OCR, QR codes, Google Places, Summarize | See the full catalog in [Skills](/docs/guides/skills#skill-categories). *** ## Per-Agent Scoping Integrations are scoped to specific agents. When you install a community integration, you assign it to one or more agents. * A **Marketing Agent** might have Notion, SendGrid, and X/Twitter integrations enabled * A **DevOps Agent** might have GitHub, Vercel, and Cloudflare enabled * A **Trading Agent** might have Coinbase and DEX Trading enabled Each agent only receives the instructions and credentials for its own assigned integrations. This prevents prompt bloat and keeps each agent focused on its domain. ### Assigning integrations to agents Skill and integration assignment is managed from the **Agents** tab, not from the Skills view: 1. Open the **Agents** tab in the sidebar 2. Select an agent (e.g. your Marketing Agent) 3. Go to the agent's **Skills** sub-tab 4. Enable or disable individual skills and integrations for that agent 5. Only enabled items are injected into that agent's prompt *** ## Installing Integrations ### From PawzHub (In-App) 1. Open the **Skills** tab in the sidebar 2. Search or browse the PawzHub catalog 3. Click **Install** on any integration (look for the 🟣 purple badge) 4. Configure credentials in the auto-generated form 5. Assign to agents via **Agents → \[agent] → Skills** ### Manual Install Place a `pawz-skill.toml` file in the skills directory: ``` ~/.paw/skills/{skill-id}/pawz-skill.toml ``` For example: ``` ~/.paw/skills/notion/pawz-skill.toml ~/.paw/skills/linear/pawz-skill.toml ~/.paw/skills/stripe/pawz-skill.toml ``` Pawz hot-reloads the skill directory — the integration appears in the Skills tab with a purple "Integration" badge. ### Uninstalling **TOML Skills:** Click **Uninstall** in the Skills tab. This removes the skill folder from `~/.paw/skills/`, cleans up stored credentials, and removes enabled state. **Community Packages (n8n):** In the Community Browser's **Installed** tab, click the **delete** icon on any package. Paw runs `npm uninstall` in the n8n data directory, restarts the engine, and refreshes the MCP bridge so stale tools are removed. A spinning "Removing…" indicator shows progress. *** ## Creating Integrations ### In-App Wizard The **Create Skill** wizard in the Skills tab walks you through building an integration without writing TOML by hand: 1. **Basic Info** — name, category, icon, description 2. **Credentials** — add API key fields with labels and placeholders 3. **Instructions** — write or paste agent instructions (templates available for REST APIs, CLI tools, and web scrapers) 4. **Widget** — optionally declare dashboard output 5. **Test** — enable the integration and verify it works with a live agent 6. **Publish** — save locally, export TOML, or publish directly to PawzHub ### AI-Assisted Creation Ask your agent: > "Create an integration for the Linear API" The agent fetches the API docs, generates a complete `pawz-skill.toml` with endpoints, auth headers, and instructions, then pre-fills the wizard for review. ### Template Starters * **REST API** — `fetch` calls with auth headers, JSON parsing * **CLI Tool** — `exec` commands with flag reference and binary detection * **Web Scraper** — `fetch` + HTML parsing instructions *** ## Publishing to PawzHub 1. **Fork** the [`OpenPawz/pawzhub`](https://github.com/OpenPawz/pawzhub) repository 2. **Create** `skills/{your-skill-id}/pawz-skill.toml` 3. **Open a Pull Request** — CI validates your manifest automatically 4. **Maintainer reviews** and merges 5. Your integration appears in the in-app PawzHub browser ### CI Validation | Check | Description | | ------------------ | ------------------------------------------ | | Valid TOML | Syntax correct, required fields present | | Unique ID | No collision with existing skills | | Valid category | Must be an allowed category | | Safe ID format | Alphanumeric + hyphens (no path traversal) | | Semver version | `X.Y.Z` format | | Description length | 10–500 characters | | Widget validation | Field types match allowed values | | Instruction-only | No executable code patterns | *** ## Security ### What integrations can do * Inject instructions into the agent's system prompt * Declare credential fields (encrypted by the engine) * Declare widget schemas (rendered by the app) ### What integrations cannot do * Execute arbitrary Rust code * Bypass domain allowlist/blocklist * Access the OS keychain directly * Read engine source code * Install blocked packages * Run unsandboxed commands when Docker sandbox is enabled ### Runtime protections | Layer | Protection | | ------------------- | --------------------------------------------------------------- | | **Credentials** | AES-256-GCM encrypted, 32-byte key in unified OS keychain vault | | **Network** | Domain allowlist/blocklist on every `fetch` | | **Shell** | Docker sandbox routing when enabled | | **File system** | Engine source read-blocked | | **Packages** | Blocked package list on `exec` | | **Agent isolation** | Per-agent working directories | *** ## Readiness Check Each integration card in Settings shows a status indicator: | Status | Meaning | | -------------------------- | ------------------------------------------- | | **Ready** ✅ | All credentials provided, binaries detected | | **Missing credentials** ⚠️ | API keys needed — click to configure | | **Missing binary** ⚠️ | CLI tool not on PATH — install hint shown | | **Disabled** 🔘 | Integration is off for this agent | # MCP Bridge Source: https://docs.openpawz.ai/guides/mcp-bridge Zero-Gap Automation — how OpenPawz connects to 25,000+ integrations via an embedded n8n engine and the Model Context Protocol. # MCP Bridge — Zero-Gap Automation OpenPawz ships with 400+ native integrations compiled into the Rust binary. The **MCP Bridge** extends this to **25,000+** by embedding an n8n engine and connecting to it via the Model Context Protocol (MCP). Your agents discover, install, and execute any of n8n's community packages — automatically, at runtime, with zero configuration. This is the feature that makes OpenPawz the most connected AI agent platform in existence. No other tool — open source or commercial — offers this level of integration coverage. *** ## How It Works ```mermaid actions={false} theme={null} graph TD A["User: 'Post a photo to Instagram'"] --> B["Agent calls request_tools()"] B --> C["Librarian (embedding model)\nSemantic search over workflow index"] C --> D["Finds workflow: 'OpenPawz MCP — Instagram'"] D --> E{"Workflow deployed?"} E -->|No| F["Auto-deploy workflow\nvia engine_n8n_deploy_mcp_workflow"] E -->|Yes| G["Execute via MCP Bridge\nexecute_workflow(workflowId, inputs)"] F --> G G --> H["n8n runs workflow\nReturns result via Streamable HTTP"] H --> I["Agent returns result to user"] ``` The flow is fully automatic. The user just asks for what they need — the agent figures out which workflow to use, deploys it if necessary, and executes it. *** ## Architecture The MCP Bridge has four layers: ### 1. Embedded n8n Engine n8n is auto-provisioned at app launch with zero user configuration: | Method | How | When | | ---------------------- | --------------------------------------------------------- | ------------------------- | | **Docker** (preferred) | `bollard` crate manages a container with port 5678 mapped | Docker detected on system | | **npx** (fallback) | `npx n8n start` as a child process | No Docker available | The engine starts 8 seconds after app launch in a background thread. Health checks run before every MCP operation via `lazy_ensure_n8n()`. ### 2. MCP Transport — Streamable HTTP n8n's MCP server uses **Streamable HTTP** at `/mcp-server/http`. This was confirmed working with n8n MCP Server v1.0.0 (protocol version `2024-11-05`). | Detail | Value | | ------------------- | ----------------------------------------- | | **Endpoint** | `POST /mcp-server/http` | | **Auth** | `Authorization: Bearer ` | | **Accept** | `application/json, text/event-stream` | | **Content-Type** | `application/json` | | **Response format** | SSE (`event: message\ndata: {json}\n\n`) | The transport is implemented in `transport.rs` alongside Stdio and legacy SSE transports. ### 3. n8n MCP Tools — Workflow-Level Operations n8n's MCP server exposes **three workflow-level tools** — not individual node operations. This is the key architectural insight: | MCP Tool | Purpose | Parameters | | ---------------------- | ----------------------------------------------------- | ------------------------------------------------------ | | `search_workflows` | Find workflows by name or description | `query`, `limit`, `projectId` | | `execute_workflow` | Run a workflow with typed inputs | `workflowId`, `chatInput` / `formData` / `webhookData` | | `get_workflow_details` | Inspect a workflow's nodes, triggers, and connections | `workflowId` | The `execute_workflow` tool supports three input types: | Input Type | When Used | Fields | | ----------- | -------------------------------- | ------------------------------------ | | **Chat** | Workflows with a chat trigger | `chatInput` (string) | | **Form** | Workflows with a form trigger | `formData` (key-value object) | | **Webhook** | Workflows with a webhook trigger | `method`, `query`, `body`, `headers` | n8n also declares `listChanged: true` capability — the server notifies when new workflows appear. ### 4. Workflow-First Integration When an agent needs to use a community package (e.g. Instagram, Puppeteer): 1. The community package is installed inside the n8n container via npm 2. n8n restarts and loads the new node types 3. Paw **auto-deploys a workflow** via `engine_n8n_deploy_mcp_workflow` — e.g. "OpenPawz MCP — Instagram" 4. The workflow becomes executable through `execute_workflow(workflowId, inputs)` 5. The Librarian indexes the new workflow for semantic discovery This is fundamentally different from exposing individual node types as MCP tools. Workflows are composable — a single workflow can chain multiple nodes (credential binding, error handling, retries, data transformation) into one coherent operation. *** ## The Architect/Worker Pattern Cloud LLMs (Gemini, Claude, GPT) act as **Architects** — they plan and orchestrate. A cheaper **Worker** model executes MCP tool calls at reduced cost (or zero cost if running locally on Ollama). This is wired directly into the main chat loop: every MCP tool call from your cloud AI is automatically intercepted and delegated to the worker. Any model from any provider can serve as the Worker — local Ollama is recommended for zero-cost execution. ```mermaid actions={false} theme={null} graph LR subgraph Cloud["Architect (Cloud LLM)"] A["Plans task"] --> B["Identifies needed workflows"] B --> C["Delegates to worker"] end subgraph Local["Worker (any model — e.g. Ollama, gpt-4o-mini)"] C --> D["Receives task + MCP tool schemas"] D --> E["Calls execute_workflow via MCP"] E --> F["Returns results"] end F --> G["Architect synthesizes\nfinal response"] ``` | Role | Model | Cost | Purpose | | ------------- | ---------------------------------------------------------------------------- | --------------------- | ---------------------------------------- | | **Architect** | Gemini / Claude / GPT | Per-token | Planning, reasoning, user interaction | | **Worker** | Any cheaper model (e.g. Ollama `worker-qwen`, or cloud `gpt-4o-mini`) | \$0 local / low cloud | MCP tool execution, structured I/O | | **Librarian** | Any embedding model (e.g. Ollama `nomic-embed-text`, or cloud embedding API) | \$0 local / low cloud | Semantic workflow discovery (embeddings) | ### How It Works in Practice When you say *"Send a message to #general on Slack"*: 1. **Architect** (Gemini/Claude) decides to call `execute_workflow` for the Slack messaging workflow 2. The engine **intercepts** the MCP tool call before execution 3. **Worker** (local Ollama, free) receives the task and the MCP tool schemas 4. Worker calls `execute_workflow(workflowId, webhookData)` via MCP → n8n executes the workflow → Slack API 5. Result flows back: Worker → Engine → Architect → User The Architect never touches the MCP layer directly. The Worker doesn't need pre-built knowledge of Slack, Trello, or any integration — MCP provides the tool schemas, and each workflow encapsulates the integration logic. **This is the breakthrough:** The worker model doesn't need to know how to use 25,000+ integrations. n8n's MCP server is self-describing — it tells the worker what workflows are available and how to execute them. Any new workflow Paw deploys is instantly discoverable and executable with zero configuration, zero training, zero cost. ### Fallback Behavior If no `worker_model` is configured in **Settings → Models → Model Routing**, MCP tool calls fall back to direct JSON-RPC execution (the engine calls MCP servers directly). This still works but means the Architect model handles tool call formatting, costing more tokens. ### Setup (Ollama — Zero Cost) 1. Install Ollama and pull the base model: `ollama pull qwen2.5-coder:7b` 2. Go to **Settings → Advanced → Ollama** and click **Setup Worker Agent** 3. In **Settings → Models → Model Routing**, set `worker_model` to `worker-qwen` 4. That's it — all MCP tool calls now route through the free local worker ### Setup (Cloud — Any Provider) 1. Go to **Settings → Models → Model Routing** 2. Set your Worker Model to any cheap model (e.g. `gpt-4o-mini`, `gemini-2.0-flash`, `claude-haiku-4-5`) 3. All MCP tool calls now route through the cloud worker at a fraction of the Architect's cost *** ## What Can Agents Do? With the MCP Bridge, your agents can access any service that has an n8n community package — via auto-deployed workflows. Here are some examples that require **no API keys**: | Category | Examples | | --------------------- | ----------------------------------------------------------------------- | | **Data Processing** | QR code generation, PDF creation, CSV parsing, JSON transformation | | **Utilities** | UUID generation, hash computation, date/time conversion, regex matching | | **Format Conversion** | Markdown → HTML, XML → JSON, image resize, base64 encode/decode | And with API keys configured in n8n: | Category | Examples | | ---------------------- | ------------------------------------------------------------- | | **CRM** | Salesforce, HubSpot, Pipedrive, Zoho, Freshdesk | | **Project Management** | Jira, Asana, Monday.com, ClickUp, Basecamp | | **Communication** | Twilio, SendGrid, Mailgun, Vonage, Intercom | | **Analytics** | Google Analytics, Mixpanel, Amplitude, Segment | | **Cloud** | AWS S3, Google Cloud Storage, Azure Blob, DigitalOcean Spaces | | **Databases** | Airtable, Supabase, Firebase, FaunaDB, CockroachDB | | **E-commerce** | Shopify, WooCommerce, Stripe, Square, PayPal | | **Social Media** | Twitter/X, LinkedIn, Facebook, Instagram, TikTok | | **DevOps** | PagerDuty, Datadog, New Relic, Sentry, Grafana | | **AI Services** | OpenAI, Anthropic, Hugging Face, Replicate, Stability AI | *** ## All Five Directions The workflow-first architecture supports every integration pattern: | Direction | How | Example | | ----------------- | --------------------------------------------- | -------------------------------------- | | **Forward** | Agent → `execute_workflow` → external service | "Send a Slack message" | | **Backward** | n8n trigger → webhook → agent | Incoming email triggers agent response | | **Bidirectional** | Read + write in same conversation | Read Jira tickets, then update them | | **Single-use** | Agent builds an ephemeral workflow on the fly | One-time data migration | | **Flows** | Conductor orchestrates multi-workflow chains | Daily report → email → Slack summary | *** ## Setup The MCP Bridge requires **zero configuration** for basic operation. Everything is auto-provisioned. ### Prerequisites | Requirement | Required? | Purpose | | --------------- | ----------- | ---------------------------------------------------------------------------------------------------- | | **Docker** | Recommended | Preferred n8n runtime (container isolation) | | **Node.js 18+** | Fallback | Used if Docker is not available (`npx n8n start`) | | **Ollama** | Recommended | Local worker model + embedding model (zero cost). Not required if using cloud models for both roles. | ### Ollama Models (Recommended for Zero Cost) If using Ollama locally, three models power the system: ```bash theme={null} # Worker model — executes MCP tool calls ollama pull qwen2.5-coder:7b # Embedding model — semantic workflow discovery + memory ollama pull nomic-embed-text # Chat fallback — default offline chat model ollama pull llama3.2:3b ``` ### Verify It's Working After launching OpenPawz, check the logs for: ``` [n8n] Starting embedded n8n engine... [mcp] Auto-registering n8n as MCP server at http://127.0.0.1:5678/mcp-server/http [mcp:http] Connected to n8n MCP — protocol 2024-11-05 [mcp:http] Available tools: search_workflows, execute_workflow, get_workflow_details ``` You can also check n8n status in **Settings → Advanced → n8n Engine**. *** ## Community Node Browser OpenPawz includes a built-in **Community Browser** UI for discovering and managing n8n community packages: 1. Open the **Integrations** tab → **Community** section 2. Search the n8n community registry (25,000+ packages via ncnodes.com + npm) 3. Click **Install** to add a package — Paw runs `npm install`, restarts n8n, and refreshes MCP tools 4. Switch to the **Installed** tab to see all installed packages 5. Click the **delete** icon to uninstall — shows a "Removing…" spinner, then restarts n8n and clears stale tools All operations fall back to direct `npm` commands when the REST API is unavailable (n8n 2.9.x). Process mode uses `npm` in `~/.openpawz/n8n-data`; Docker mode uses `docker exec`. Alternatively, agents can discover and install packages conversationally: > "I need to generate QR codes" > > *Agent searches community nodes, finds the QR code package, installs it, deploys a workflow, and generates the QR code — all in one conversation.* *** ## vs. Zapier / Make / n8n Standalone | | **OpenPawz MCP Bridge** | **Zapier** | **Make** | **n8n (standalone)** | | -------------------- | ----------------------------------- | -------------- | -------------- | ------------------------ | | **Integrations** | 25,000+ | 7,000+ | 2,000+ | 400+ built-in | | **AI-driven** | Agents discover & execute workflows | Manual setup | Manual setup | Manual setup | | **Auto-deploy** | Workflows created at runtime | Pre-configured | Pre-configured | Manual workflow building | | **Cost** | \$0 local / low cloud | \$20–600/mo | \$9–300/mo | Free (self-hosted) | | **Natural language** | "Post a photo to Instagram" | Drag-and-drop | Drag-and-drop | Drag-and-drop | | **Privacy** | 100% local | Cloud | Cloud | Self-hosted option | | **Multi-agent** | Yes | No | No | No | *** ## Troubleshooting | Problem | Solution | | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | n8n not starting | Check Docker is running (`docker ps`) or Node.js 18+ is available (`node --version`) | | MCP 403 "access is disabled" | Paw auto-enables MCP via `PATCH /rest/mcp/settings`. If manual, ensure `mcpAccessEnabled: true`. | | MCP 406 "must accept both" | The transport must send `Accept: application/json, text/event-stream`. Check transport config. | | "No MCP tools available" | Run `mcp_refresh` or restart the app. Check that n8n is healthy at `http://localhost:5678`. | | Community package install fails | Ensure n8n has network access. For Process mode, check that `~/.openpawz/n8n-data` exists and npm is on PATH. For Docker mode, check container logs: `docker logs paw-n8n`. | | Community uninstall has no effect | Ensure you're on the latest build. Older versions used `window.confirm()` which doesn't render in Tauri's WKWebView on macOS. | | MCP token is redacted | Paw auto-rotates via `POST /rest/mcp/api-key/rotate`. If this fails, the n8n owner session may have expired — restart the app. | | Workflow not found after install | The auto-deploy step may have failed. Check logs for `engine_n8n_deploy_mcp_workflow` errors. | | Worker model not found | If using Ollama, run `ollama pull qwen2.5-coder:7b`. Otherwise, configure any model as the worker in Settings → Models → Model Routing. | *** ## Security * n8n runs **locally** — no cloud relay, no data leaves your machine * Community packages are installed from the **official npm registry** * MCP transport uses **localhost-only** connections (127.0.0.1:5678) * MCP auth uses a **JWT with `mcp-server-api` audience** — separate from the REST API key. Stale/redacted keys are auto-rotated via `/rest/mcp/api-key/rotate` * The n8n encryption key is stored in your **unified OS keychain vault** (`openpawz`), not on the filesystem * All tool calls go through OpenPawz's **Human-in-the-Loop approval** system * Credential injection for n8n nodes uses the same **AES-256-GCM encrypted vault** * The MCP Bridge inherits all 10 security layers from the core platform # Memory Source: https://docs.openpawz.ai/guides/memory Project Engram — a biologically-inspired three-tier memory architecture with hybrid search, PII encryption, and graph-based knowledge management. # Memory Pawz uses **Project Engram**, a biologically-inspired three-tier memory architecture that lets agents remember facts, preferences, and context across conversations with graph-based knowledge management, hybrid search, and automatic PII encryption. ## Architecture Engram models memory after human cognitive architecture with three tiers: ```mermaid actions={false} theme={null} flowchart TD A["User Message"] --> B["Sensory Buffer\n(ring buffer)"] B --> C["Working Memory\n(priority-evicted slots)"] C --> D["ContextBuilder\n(budget-aware prompt assembly)"] D --> E["Agent Response"] C <--> F["Long-Term Memory Graph"] subgraph LTM["Long-Term Memory Graph"] direction LR G["Episodic Store\n(what happened)"] H["Knowledge Store\n(what is true)"] I["Procedural Store\n(how to do things)"] end F --- J["Graph Edges (8 types)\nSpreading Activation"] K["Consolidation Engine\n(background, every 5 min)"] --> F ``` | Tier | Analogy | Role | | -------------------- | ------------------------------- | ---------------------------------------------------------------- | | **Sensory Buffer** | Iconic/echoic memory | Ring buffer holding raw tokens; discarded after each turn | | **Working Memory** | Short-term memory | Priority-evicted slots feeding the context window | | **Long-Term Memory** | Declarative + procedural memory | Persistent graph with episodic, knowledge, and procedural stores | ### How it works ```mermaid actions={false} theme={null} graph TD A["User message"] --> B["Auto-recall\nHybrid search (BM25 + Vector + Graph)"] B --> C["Inject into context\n(budget-aware)"] C --> D["Agent responds"] D --> E["Auto-capture\nExtract facts via Engram bridge"] E --> F["PII scan → Encrypt → Embed → Store"] ``` ## Configuration Go to **Settings → Sessions** to configure memory: | Setting | Default | Description | | ------------------------ | ------------------------ | ---------------------------------------------- | | **Embedding model** | `nomic-embed-text` | Model used to create vector embeddings | | **Embedding base URL** | `http://localhost:11434` | Ollama endpoint for embeddings | | **Embedding dimensions** | 768 | Vector size (match your model) | | **Auto-recall** | On | Automatically retrieve relevant memories | | **Auto-capture** | On | Automatically extract facts from conversations | | **Recall limit** | 5 | Max memories injected per message | | **Recall threshold** | 0.3 | Minimum relevance score (0–1) | ## Memory categories Each memory is tagged with a category: | Category | Use case | | -------------- | -------------------------------------- | | `general` | Catch-all | | `preference` | User likes/dislikes, style preferences | | `instruction` | Standing orders, rules | | `context` | Background information | | `fact` | Concrete facts, dates, numbers | | `project` | Project-specific context | | `person` | Info about people | | `technical` | Technical details, tools, configs | | `task_result` | Completed task outcomes | | `session` | Compacted session summaries | | `observation` | Agent observations about patterns | | `goal` | User goals and objectives | | `skill` | Learned capabilities and procedures | | `relationship` | Connections between entities | | `temporal` | Time-based events and deadlines | | `emotional` | Sentiment and emotional context | | `creative` | Creative works, drafts, ideas | | `system` | System state and configuration notes | ## Hybrid search Memory retrieval uses a three-signal hybrid algorithm fused with Reciprocal Rank Fusion (RRF): ```mermaid actions={false} theme={null} flowchart LR Q["Search Query"] --> CL["Query Classifier"] CL --> BM["BM25\n(full-text search)"] CL --> VS["Vector Similarity\n(Ollama embeddings)"] BM --> RRF["Reciprocal Rank\nFusion"] VS --> RRF RRF --> SA["Graph Spreading\nActivation (1-hop)"] SA --> RR["Reranking\n(RRF / MMR / RRF+MMR)"] RR --> R["Ranked Results"] ``` 1. **BM25** — text relevance via full-text search with porter stemming 2. **Vector cosine similarity** — semantic meaning via Ollama embeddings 3. **Graph spreading activation** — 1-hop traversal of typed memory edges to find related memories 4. **RRF fusion** — merges all three signals without requiring score normalization 5. **Reranking** — configurable strategy: RRF, MMR (maximal marginal relevance), or combined 6. **Keyword fallback** — when both BM25 and vector search return no results, the engine falls back to a keyword search using SQL `LIKE` on memory content. This ensures memories can always be found even when embeddings are unavailable or the full-text index misses a match. :::tip Keyword fallback The keyword fallback is automatic — you don't need to configure anything. If semantic search and BM25 both return empty results for a query, Pawz transparently retries with a simple substring match so you never get a false "no results found." ::: ### Tuning search In the Memory Palace, you can adjust: | Parameter | Default | Effect | | --------------- | ------- | ----------------------------------------- | | BM25 weight | 0.4 | Text match importance | | Vector weight | 0.6 | Semantic match importance | | Decay half-life | 30 days | How fast old memories fade | | MMR lambda | 0.7 | 1.0 = pure relevance, 0.0 = max diversity | | Threshold | 0.3 | Minimum score to include | ## Memory Palace The Memory Palace is a dedicated view for managing all stored memories. It is organized into four tabs: ### Tabs | Tab | Purpose | | ------------ | ---------------------------------------------------------------------------------------------------------------------------- | | **Recall** | Semantic search interface — enter a natural-language query and view ranked results with relevance scores | | **Remember** | Manual memory creation form — set content, category, and importance then save | | **Graph** | Force-directed graph visualization of memory relationships, grouped by category with color-coded bubbles sized by importance | | **Files** | Browse agent personality files (`IDENTITY.md`, `SOUL.md`, etc.) stored on disk | #### Recall Type a query into the search box and press **Enter** (or click the search button). Results are displayed as cards showing the category tag, relevance score (percentage), content preview, and importance. Clicking a memory in the sidebar also opens it in the Recall tab. #### Remember Manually store a new memory by filling in: * **Content** — the text to remember * **Category** — select from the standard categories (general, preference, instruction, etc.) * **Importance** — 1–10 scale Click **Save Memory** to persist it. The sidebar and stats update automatically. #### Graph Click **Render** to generate a bubble-chart visualization. Memories are grouped by category and laid out in a circle. Each bubble represents one memory — its size reflects importance, and its color maps to the category. This gives a quick visual overview of what your agent knows and where knowledge is concentrated. #### Files Browse and edit the agent's identity and personality files that live on disk. This tab is always available, even when the embedding model is not configured. ### Embedding status banner At the top of the Memory Palace, a status banner shows whether the embedding model is loaded and operational: | Status | Banner | | --------------------- | ------------------------------------------------------------------------------------ | | Ollama not running | ⚠️ Warning — semantic search disabled, falls back to keyword matching | | Model not pulled | ℹ️ Info — prompts you to pull the model (\~275 MB) with a one-click button | | Memories need vectors | ℹ️ Info — offers a **Embed All** button to backfill embeddings for existing memories | | All good | ✅ Success — shows active model name (e.g. `nomic-embed-text` via Ollama) | :::note When embeddings are unavailable the banner tells you that memory search will fall back to keyword matching. You can still store and retrieve memories — just without semantic ranking. ::: ### Recent memories sidebar On the right side of the Memory Palace, a sidebar displays the **20 most recently stored memories** for quick reference. Each card shows: * Category tag * Content preview (first 60 characters) * Importance score Click any card to jump to its full details in the Recall tab. A search box at the top of the sidebar lets you filter the visible cards by keyword. ### JSON export Click the **Export** button in the Memory Palace toolbar to download all memories as a JSON file. The export includes: ```json theme={null} { "exportedAt": "2026-02-20T12:00:00.000Z", "source": "Paw Desktop — Memory Export", "totalMemories": 42, "memories": [ { "id": "...", "content": "User prefers dark mode", "category": "preference", "importance": 7, "created_at": "..." } ] } ``` The file is named `paw-memories-YYYY-MM-DD.json`. Use this for backup or to transfer memories between machines. ## Slash commands Quick memory operations from any chat: ``` /remember Store a memory manually /forget Delete a memory by ID /recall Search memories and show results ``` ## Auto-capture When auto-capture is enabled, the engine extracts memorable facts from conversations using heuristics. It looks for: * User preferences ("I prefer...", "I like...") * Explicit instructions ("Always...", "Never...") * Personal context (names, locations, roles) * Concrete facts (dates, numbers, decisions) ## Embedding setup Pawz auto-manages embeddings via Ollama: 1. Checks if Ollama is reachable 2. Auto-starts Ollama if needed 3. Checks if the embedding model is available 4. Auto-pulls the model if missing 5. Tests embedding generation If you switch embedding models, use **backfill** to re-embed existing memories. ## Embedding backends The engine tries endpoints in order: 1. Ollama `/api/embed` (current API) 2. Ollama `/api/embeddings` (legacy API) 3. OpenAI-compatible `/v1/embeddings` This means you can use any OpenAI-compatible embedding API by changing the base URL. ## Security Memory in Pawz is protected at multiple levels: | Layer | Protection | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **PII encryption** | Two-layer PII defense: Layer 1 uses 17 regex patterns (emails, SSNs, credit cards, JWTs, AWS keys, private keys, IBAN, etc.) to detect and encrypt sensitive content with AES-256-GCM. Layer 2 uses LLM-assisted scanning for context-dependent PII ("mother's maiden name", "born in Springfield"). Encryption key derived per-agent via HKDF from unified OS keychain vault (`openpawz`). | | **At rest** | Per-agent HKDF-derived AES-256-GCM keys — each agent's memories are cryptographically isolated. Key versioned (`enc:v1:` prefix) with automated 90-day rotation. | | **In transit** | TLS certificate-pinned connections to embedding providers (Mozilla root CAs only, OS trust store excluded) | | **In RAM** | Provider API keys wrapped in `Zeroizing` — automatically zeroed from memory on drop | | **Outbound** | Every embedding request SHA-256 signed and logged to a 500-entry audit ring buffer | | **Query sanitization** | All search query operators stripped before execution to prevent injection | | **Prompt injection** | 10-pattern scanner redacts prompt injection attempts in memory content with `[REDACTED:injection]` markers | | **Inter-agent trust** | Memory bus enforces capability tokens (HMAC-SHA256 signed) on both publish and read paths — scope/importance ceilings, per-agent rate limits, signed scope tokens with 4-step verification, and trust-weighted contradiction resolution | | **Anti-forensic** | Database padded to 512KB boundaries; two-phase secure delete prevents plaintext recovery; snapshot HMAC detects tampering | | **GDPR compliance** | Article 17 purge command deletes all memories, embeddings, search index, and graph edges for a user | :::info PII auto-encryption Engram automatically scans memory content for PII using a two-layer defense: * **Layer 1 (regex):** 17 patterns detect emails, phone numbers, SSNs, credit cards, JWTs, AWS keys, etc. * **Layer 2 (LLM):** An LLM-assisted scanner catches context-dependent PII that regex misses (e.g., "my mother's maiden name is Smith"). Content flagged by Layer 1 or exceeding a size threshold is sent to the active model for classification. All PII-containing content is encrypted with per-agent AES-256-GCM keys (derived via HKDF from the OS keychain). Decryption happens transparently on retrieval. ::: ## Consolidation engine Engram runs a background consolidation cycle every 5 minutes that maintains memory health: | Operation | Purpose | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | **Pattern clustering** | Groups related memories by semantic similarity | | **Contradiction detection** | Identifies conflicting facts and resolves them | | **FadeMem dual-layer decay** | Importance-weighted Ebbinghaus curve (Layer 1) + LRU access-frequency boost (Layer 2) — high-importance and frequently-accessed memories resist decay | | **Garbage collection** | Removes memories whose strength has fallen below threshold | | **GraphRAG community detection** | Louvain modularity clustering identifies knowledge communities in the memory graph for enhanced retrieval | ### Memory strength Each memory has a strength score (0.0–1.0) managed by the **FadeMem dual-layer decay** system: * **Layer 1 (Ebbinghaus curve):** Time-based exponential decay with configurable half-life. High-importance memories (importance > 0.7) decay at half the rate. The decay factor is: `0.5^(age_days / half_life) × importance_weight`. * **Layer 2 (LRU boost):** Each memory access (search hit, recall, explicit read) increments a frequency counter. Frequently-accessed memories receive a boost that counteracts decay: `min(access_count × 0.05, 0.3)`. The combined strength determines garbage collection eligibility. This ensures frequently-used knowledge persists while truly stale information is naturally pruned. ### GraphRAG community detection The memory graph is periodically analyzed using Louvain modularity optimization to discover clusters of related knowledge: * **Community labels** are assigned to memories, enabling community-scoped retrieval * **Modularity score** tracks cluster quality — higher scores indicate well-separated knowledge domains * **Cross-community edges** highlight connections between knowledge areas * Communities are re-computed during consolidation cycles as new memories arrive ## Agent memory tools Agents have access to 7 memory tools for direct memory management: | Tool | Description | | ----------------- | --------------------------------------------------- | | `memory_store` | Store a new memory with category and importance | | `memory_search` | Hybrid search across all memory stores | | `memory_delete` | Remove a specific memory by ID | | `memory_list` | List recent memories with optional category filter | | `memory_update` | Update an existing memory's content or metadata | | `memory_link` | Create a typed edge between two memories | | `memory_snapshot` | Export a point-in-time snapshot of the memory graph | ## Flow memory integration When a flow runs, the executor automatically retrieves long-term memories so agent nodes have relevant context **before** they generate a response. ### Pre-recall at flow start Before any node executes, the flow executor builds a memory query from the graph name and all agent prompts in the flow, then calls `pawEngine.memorySearch()`. The top results (filtered at score ≥ 0.3) are concatenated into a `memoryContext` string and stored in `FlowRunState`. Every agent node receives this context in a `[Relevant Memory]` section prepended to its prompt via `buildNodePrompt()`. ### Cell-scoped memory in tesseract flows Tesseract flows split work into parallel **cells** — independent sub-graphs that execute concurrently. Each cell needs different memory because the agents inside serve different purposes (e.g. a research cell vs. an analysis cell). The Conductor solves this with **per-cell memory isolation**: 1. For each cell, a focused query is built from the cell's agent prompts (up to 3 agents, 200 chars each, capped at 300 chars total) 2. All cell queries are resolved concurrently via `deps.searchMemory()`, which calls `pawEngine.memorySearch()` with score ≥ 0.3 filtering 3. Results are stored in an immutable `resolvedCellMemory` map — computed once before execution begins 4. Each cell's executor receives a `ConductorDeps` wrapper that binds its memory override to every `executeNode` and `executeAgentStep` call This eliminates shared-state mutation — parallel cells never race on `runState.memoryContext`. ### searchMemory IPC bridge The `searchMemory` function on `ConductorDeps` bridges the flow engine to the Rust memory backend: ```typescript theme={null} searchMemory: async (query: string, limit: number) => { const results = await pawEngine.memorySearch(query, limit, agentId); return results .filter(m => m.score >= 0.3) .map(m => `[${m.category}] ${m.content}`) .join('\n'); } ``` This is the same hybrid search pipeline (BM25 + vector + graph spreading activation) used in chat sessions, so flow agents benefit from the full Engram retrieval stack. # Modular Workspace Source: https://docs.openpawz.ai/guides/modular-workspace # Modular Workspace Pawz ships with 17 navigation views, but not every user needs all of them. A trader doesn't need Content Studio. A marketer doesn't need Trading. A developer doesn't need either. The modular workspace lets you configure exactly which views appear in your sidebar. ## Workspace Profiles Choose a preset profile or build a custom one: ### All (Default) Every view is visible. This is the out-of-the-box experience. ### Developer Focused on coding, research, and orchestration. | Visible | Hidden | | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | | Dashboard, Chat, Agents, Tasks, Projects, Research, Orchestrator, Nodes, Memory Palace, Automations, Skills, Foundry, Settings | Trading, Content Studio, Mail | ### Marketer Focused on content creation, email, and research. | Visible | Hidden | | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------- | | Dashboard, Chat, Agents, Tasks, Content Studio, Mail, Research, Automations, Channels, Skills, Foundry, Settings | Trading, Projects, Nodes, Orchestrator | ### Trader Focused on trading, research, and automation. | Visible | Hidden | | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | | Dashboard, Chat, Agents, Tasks, Trading, Research, Automations, Memory Palace, Channels, Skills, Foundry, Settings | Content Studio, Projects, Nodes, Mail | ### Minimal Just the essentials — chat with your agents and manage skills. | Visible | Hidden | | ------------------------------------------------ | --------------- | | Dashboard, Chat, Agents, Tasks, Skills, Settings | Everything else | ### Custom Pick exactly which views to show. A checkbox grid in Settings lets you toggle each view individually. ## Core Views (Always Visible) These views cannot be hidden regardless of profile. They are fundamental to how Pawz works: | View | Why it's always visible | | ------------- | ---------------------------------------------------------------- | | **Dashboard** | Landing page, weather, tasks, skill widgets | | **Chat** | Primary agent interaction | | **Agents** | Manage agent identities, soul files, policies | | **Skills** | Enable/disable skills, PawzHub browser, credential setup | | **Settings** | App configuration, models, providers, workspace profile selector | ## How to Configure 1. Open **Settings → Advanced** (or the dedicated **Workspace** settings tab) 2. Choose a **Workspace Profile** from the dropdown: * All, Developer, Marketer, Trader, Minimal, Custom 3. If **Custom** is selected, a checkbox grid appears with all 17 views 4. Toggle views on/off — changes apply immediately 5. The sidebar updates in real-time :::tip Hit **Reset to Default** at any time to go back to the "All" profile with every view visible. ::: ## Available Views The full set of views you can show or hide: | View | Icon | Description | | ------------------ | ------------------- | --------------------------------------------------------------- | | **Dashboard** | `dashboard` | Overview page with weather, tasks, quick actions, skill widgets | | **Today** | `today` | Daily planning and agenda view | | **Chat** | `chat` | Agent conversations with streaming responses | | **Agents** | `smart_toy` | Manage agent identities, avatars, soul files, policies | | **Tasks** | `task_alt` | Kanban task board with agent assignment and cron scheduling | | **Orchestrator** | `account_tree` | Multi-agent orchestration with specialties and routing | | **Projects** | `code` | Code projects with file browser and editor | | **Content Studio** | `edit_note` | Blog posts, articles, and content management | | **Mail** | `mail` | Email management with agent-powered compose and replies | | **Automations** | `schedule` | Cron-based automations that run on schedule | | **Channels** | `forum` | External messaging channels (Telegram, Discord, Slack, etc.) | | **Research** | `science` | Deep research with source tracking and citations | | **Nodes** | `hub` | Node network for distributed agent workloads | | **Trading** | `candlestick_chart` | DEX trading with portfolio tracking and whale alerts | | **Memory Palace** | `psychology` | Memory search, timeline, and knowledge graph | | **Skills** | `extension` | Skill vault, PawzHub browser, credential management | | **Foundry** | `tune` | Model selection, inference modes, temperature tuning | ## Use Cases ### Solo Developer **Profile:** Developer Your sidebar has Chat, Agents, Projects, Tasks, Orchestrator, Research, Nodes, and Memory Palace. No Trading, no Content Studio, no Mail. Clean and focused. Add skills from PawzHub for your stack: GitHub, Vercel, Supabase, Cloudflare. Their widgets show deployment status and incident logs right on your dashboard. ### Marketing Team Lead **Profile:** Marketer Your sidebar has Chat, Agents, Content Studio, Mail, Research, Tasks, Automations, Channels. No Trading, no Projects, no Nodes. Add skills for your platforms: X/Twitter, SendGrid, Shopify, Google Analytics. Dashboard widgets show engagement metrics, email delivery rates, and revenue. ### Crypto Trader **Profile:** Trader Your sidebar has Chat, Agents, Trading, Research, Tasks, Automations, Memory Palace, Channels. No Content Studio, no Projects, no Nodes. Built-in DEX and Coinbase skills are already there. Add PawzHub skills for additional exchanges, whale tracking, or portfolio analytics. Widgets show portfolio value, open positions, and price alerts. ### Power User **Profile:** All or Custom Keep everything visible, or fine-tune with Custom to hide just the one or two views you never use. ## Skill-Driven Views (Coming Soon) In a future update, community skills will be able to register their own custom views in the sidebar. For example, a "CRM" skill could add a dedicated CRM tab with pipeline visualization, or a "Home Dashboard" skill could add a smart home control panel. For now, the modular workspace controls visibility of the 17 built-in views. Custom skill views are planned for Phase 6 of the PawzHub roadmap. *** ## FAQ **Does changing my profile affect my data?** No. Hidden views still exist — their data is preserved. If you hide Trading and later show it again, all your trading history and settings are still there. **Can I have different profiles for different agents?** Not yet. The workspace profile is app-wide. Per-agent workspace profiles are planned for a future update. **What happens if I navigate to a hidden view?** You can't. Hidden views have no nav item. If a skill or automation tries to switch to a hidden view, you're redirected to the Dashboard. **Can skills add new views?** Not yet. This is planned for Phase 6 (custom skill views). For now, skills output data via dashboard widgets and chat. # Orchestrator Source: https://docs.openpawz.ai/guides/orchestrator The Orchestrator enables multi-agent projects where a boss agent delegates tasks to worker agents. # Orchestrator The Orchestrator enables multi-agent projects where a boss agent delegates tasks to worker agents. ## Concepts | Role | Model | Description | | ---------- | ---------------------------------- | --------------------------------- | | **Boss** | `boss_model` (expensive, powerful) | Plans, delegates, reviews results | | **Worker** | `worker_model` (cheap, fast) | Executes specific tasks | ## Creating a project 1. Go to **Orchestrator** in the sidebar 2. Click **New Project** 3. Fill in: * **Title** — project name * **Goal** — what the project should accomplish * **Boss agent** — the agent that leads * **Workers** — add agents with specialties ## Agent specialties Each agent on a project team has a **specialty** that determines how they're prompted and which model they use. The orchestrator supports two sets of specialties depending on context: ### Project sub-agents (`create_sub_agent`) When the boss agent dynamically creates sub-agents during a project run: | Specialty | Best for | | -------------- | -------------------------------------- | | `coder` | Writing, reviewing, and debugging code | | `researcher` | Finding information, web research | | `designer` | Creative work, UI/UX, visual content | | `communicator` | Writing emails, messages, docs | | `security` | Security reviews, audits | | `general` | Anything not covered above | ### Standalone agents (`create_agent`) When creating agents via the `create_agent` tool or the Agents view: | Specialty | Best for | | ------------ | ------------------------------------------------------ | | `coder` | Writing, reviewing, and debugging code | | `researcher` | Finding information, web research, investigation | | `writer` | Long-form content, reports, documentation, copywriting | | `analyst` | Data analysis, evaluation, comparisons, assessments | | `general` | Anything not covered above | :::tip Custom system prompts Every agent — regardless of specialty — can have a **custom system prompt** set at creation time via the `system_prompt` parameter. This gives you full control over the agent's behavior and personality beyond the specialty label. The boss agent can use `create_sub_agent` with a detailed `system_prompt` to create highly tailored workers on the fly. ::: Specialty models can be configured in **Settings → Engine** under Model Routing. For example, setting `coder` to `gemini-2.5-pro` routes all coding tasks to that model. ## How it works ```mermaid actions={false} theme={null} graph TD A["Boss agent gets\ngoal + team roster"] --> B["Boss plans and calls\ndelegate_task(agent, task)"] B --> C["Worker spawns async\ntokio::spawn"] C --> D["Worker executes\nwith worker_model"] D --> E["Worker calls\nreport_progress(status, result)"] E --> F{"Boss reviews"} F -->|More work| B F -->|Done| G["project_complete"] ``` ## Boss tools | Tool | Description | | -------------------- | ----------------------------- | | `delegate_task` | Assign work to a worker agent | | `check_agent_status` | See what a worker is doing | | `send_agent_message` | Send a message to a worker | | `project_complete` | Mark the project as done | | `create_sub_agent` | Create a new agent on the fly | ## Worker tools Workers have access to all standard safe tools plus: * `report_progress` — send status updates back to the boss * Statuses: `working`, `done`, `error`, `blocked` Workers can also use: email, slack, GitHub, REST API, webhooks, and image generation without HIL approval. ## Project statuses | Status | Meaning | | ----------- | ----------------------------- | | `planning` | Created, not started | | `running` | Boss is actively delegating | | `paused` | Manually paused | | `completed` | Boss called project\_complete | | `failed` | Unrecoverable error | ## Message bus The project detail view shows a real-time message bus (polled every 3s): | Message type | From | | ------------ | ------------------------- | | `delegation` | Boss assigned a task | | `progress` | Worker reporting status | | `result` | Worker completed task | | `error` | Something went wrong | | `message` | Inter-agent communication | ## Model routing Configure which models handle what in **Settings → Engine**: | Setting | Purpose | | ------------------ | ---------------------------------------------------------- | | `boss_model` | Model for the boss agent (typically expensive/powerful) | | `worker_model` | Default model for workers (typically cheap/fast) | | `specialty_models` | Per-specialty overrides (e.g., `coder` → `gemini-2.5-pro`) | | `agent_models` | Per-agent overrides (highest priority) | | `cheap_model` | Budget model for simple tasks when `auto_tier` is enabled | | `auto_tier` | Automatically select `cheap_model` for simple tasks | **Resolution priority:** agent\_models > specialty\_models > role-based > fallback ### Cheap model & auto-tier The **cheap model** setting lets you reduce costs by routing simple tasks to a smaller, faster LLM while keeping the full model for complex work. When `auto_tier` is enabled, every incoming message is classified by a complexity heuristic before model selection: | Complexity | Routed to | Examples | | ----------- | ------------- | --------------------------------------------------------- | | **Simple** | `cheap_model` | "What time is it?", "Convert 5kg to lbs", basic Q\&A | | **Complex** | default model | Code generation, multi-step reasoning, analysis, research | The classifier looks for signals like code keywords (`implement`, `refactor`, `debug`), reasoning phrases (`analyze`, `compare`, `step by step`), multi-step patterns (`and then`, `first,`, numbered lists), and message length (>1500 chars → complex). ```json title="Example model routing config" theme={null} { "boss_model": "gemini-2.5-pro", "worker_model": "gemini-2.0-flash", "cheap_model": "claude-3-haiku", "auto_tier": true, "specialty_models": { "coder": "gemini-2.5-pro", "researcher": "gemini-2.0-flash" } } ``` :::info The `auto_tier` / `cheap_model` mechanism applies to regular chat sessions. Within orchestrator projects, model selection uses the `boss_model` → `worker_model` → `specialty_models` → `agent_models` routing chain instead. ::: ### Execution limits Orchestrator projects are bounded by the engine's global execution limits: | Setting | Default | Description | | --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `max_tool_rounds` | 20 | Maximum number of LLM ↔ tool call rounds per agent loop (boss or worker). When exceeded, the agent stops and returns its last output. | | `tool_timeout_secs` | 300 | Timeout in seconds for individual tool call approvals (HIL). If the user doesn't approve within this window, the tool call is denied. | | `max_concurrent_runs` | 4 | Maximum simultaneous agent runs across the whole engine (chat + cron + orchestrator). Chat always gets priority. | The boss agent loop exits when: * `project_complete` is called * `max_tool_rounds` is exceeded * An unrecoverable error occurs Worker agent loops exit when: * `report_progress` is called with status `done` * `max_tool_rounds` is exceeded * An error occurs :::caution There is no project-level timeout. A project with many delegated tasks can run for a long time if workers are slow or blocked. Monitor the message bus and use **check\_agent\_status** to catch stuck agents. You can also manually pause or delete a project from the UI. ::: # PawzHub — Marketplace Source: https://docs.openpawz.ai/guides/pawzhub # PawzHub — Marketplace PawzHub is the community-driven marketplace for Pawz. It hosts all three tiers of the extensibility system — [Skills](/docs/guides/skills), [Integrations](/docs/guides/integrations), and [Extensions](/docs/guides/extensions) — making Pawz an infinitely extensible platform where anyone can create, publish, and install capabilities. ## Three Tiers, One Marketplace ```mermaid actions={false} theme={null} graph TD HUB["PawzHub Marketplace"] --> S["Skills\nPrompt-only · SKILL.md\nZero config · 1-click install"]:::blue HUB --> I["Integrations\nCredentials + Tools · TOML\nAPI keys · CLI binaries · Widgets"]:::purple HUB --> E["Extensions\nCustom Views + Storage · TOML\nSidebar tabs · Persistent data"]:::gold classDef blue fill:#3b82f6,color:#fff,stroke:#3b82f6 classDef purple fill:#a855f7,color:#fff,stroke:#a855f7 classDef gold fill:#eab308,color:#000,stroke:#eab308 ``` | Tier | Badge | Format | Install Source | | ----------- | --------- | ------------------------------------ | --------------------------------------------- | | Skill | 🔵 Blue | SKILL.md | [skills.sh](https://skills.sh) + GitHub repos | | Integration | 🟣 Purple | pawz-skill.toml | PawzHub registry (GitHub) | | Extension | 🟡 Gold | pawz-skill.toml + \[view]/\[storage] | PawzHub registry (GitHub) | ## How It Works ```mermaid actions={false} theme={null} graph TD subgraph App["Your Pawz App"] SL["Skill Loader"] --> BUILTIN["Built-in Skills\n30+"] SL --> COMMUNITY["~/.paw/skills/\nCommunity TOML"] CV["Credential Vault\nAES-GCM + OS Keychain"] DW["Dashboard Widgets\nSkill output store"] end App --> HUB["PawzHub\nGitHub Registry\nregistry.json"] ``` Every skill — whether built-in or community — follows the same architecture: 1. **Skill manifest** declares what the skill does, what credentials it needs, and what data it outputs 2. **Credential vault** encrypts API keys with AES-GCM (key stored in OS keychain) and injects them into the agent prompt at runtime 3. **Engine tools** (`fetch`, `exec`, `read_file`, `write_file`) execute the actual API calls and commands 4. **Dashboard widgets** render structured output from skills as persistent visual cards The skill author never writes Rust code. They describe the API integration in a TOML file. The engine handles execution, security, and credential management. *** ## Skill Manifest Format Every PawzHub skill is a single `pawz-skill.toml` file: ```toml theme={null} [skill] id = "notion" name = "Notion" version = "1.0.0" author = "yourname" category = "productivity" icon = "edit_note" description = "Read and write Notion pages, databases, and blocks via the API" install_hint = "Get your API key at https://www.notion.so/my-integrations" [[credentials]] key = "NOTION_API_KEY" label = "Integration Token" description = "Your Notion internal integration token" required = true placeholder = "secret_..." [instructions] text = """ You have access to the Notion API via the user's integration token. ## Reading pages Use `fetch` with: - URL: `https://api.notion.so/v1/pages/{page_id}` - Headers: `Authorization: Bearer {NOTION_API_KEY}`, `Notion-Version: 2022-06-28` ## Searching Use `fetch` with POST to `https://api.notion.so/v1/search` Body: {"query": "search term"} ## Creating pages Use `fetch` with POST to `https://api.notion.so/v1/pages` Headers: `Authorization: Bearer {NOTION_API_KEY}`, `Notion-Version: 2022-06-28` Body: {"parent": {"database_id": "..."}, "properties": {...}} """ [widget] type = "table" title = "Recent Pages" refresh = "10m" [[widget.fields]] key = "title" label = "Page" type = "text" [[widget.fields]] key = "updated" label = "Last Updated" type = "datetime" [[widget.fields]] key = "status" label = "Status" type = "badge" ``` ### Manifest Fields #### `[skill]` — Required | Field | Type | Required | Description | | -------------- | ------ | -------- | ----------------------------------------------- | | `id` | string | Yes | Unique identifier. Alphanumeric + hyphens only. | | `name` | string | Yes | Human-readable display name. | | `version` | string | Yes | Semver version (e.g. `1.0.0`). | | `author` | string | Yes | Author name or GitHub username. | | `category` | string | Yes | One of the valid categories (see below). | | `icon` | string | No | Material Symbols icon name (e.g. `edit_note`). | | `description` | string | Yes | Short description (10-500 chars). | | `install_hint` | string | No | Instructions for getting credentials. | **Valid categories:** `vault`, `cli`, `api`, `productivity`, `media`, `smart_home`, `communication`, `development`, `system` #### `[[credentials]]` — Optional (repeatable) Declare API keys, tokens, or secrets the skill requires. Users enter these in the Skills tab. Pawz encrypts them with AES-GCM and stores the encryption key in the OS keychain. At runtime, decrypted values are injected into the agent's system prompt automatically. | Field | Type | Required | Description | | ------------- | ------ | -------- | --------------------------------------------------- | | `key` | string | Yes | Environment variable name (e.g. `NOTION_API_KEY`). | | `label` | string | Yes | UI label shown to the user. | | `description` | string | No | Help text explaining where to find this credential. | | `required` | bool | Yes | Whether the skill works without this credential. | | `placeholder` | string | No | Example value shown in the input field. | :::info Credential Security Credentials are never stored in plain text. They are encrypted in SQLite using AES-GCM with a 256-bit key stored in your OS keychain (macOS Keychain, Windows Credential Manager, or Linux Secret Service). The agent receives decrypted values only in its system prompt at runtime — they are never logged, never written to disk unencrypted, and never transmitted externally. ::: #### `[instructions]` — Required | Field | Type | Required | Description | | ------ | ------ | -------- | ---------------------------------------------------- | | `text` | string | Yes | Agent instructions explaining how to use this skill. | The instructions tell the agent: * Which API endpoints to call (using the `fetch` tool) * Which CLI commands to run (using the `exec` tool) * How to format request headers, bodies, and authentication * How to parse and present responses * Error handling guidance The engine automatically appends a credential block to the instructions at runtime: ``` Credentials (use these values directly — do NOT ask the user for them): - NOTION_API_KEY = secret_abc123... ``` #### `[widget]` — Optional Declare a dashboard widget for persistent visual output. | Field | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------------------------- | | `type` | string | Yes | Widget type: `status`, `metric`, `table`, `log`, or `kv`. | | `title` | string | Yes | Widget card title. | | `refresh` | string | No | Auto-refresh interval (e.g. `5m`, `1h`). | #### `[[widget.fields]]` — Required if `[widget]` is present | Field | Type | Required | Description | | ------- | ------ | -------- | ------------------------------------------------------------------------------- | | `key` | string | Yes | Data key matching the JSON output. | | `label` | string | Yes | Column/field label displayed in the widget. | | `type` | string | Yes | Field type: `text`, `number`, `badge`, `datetime`, `percentage`, or `currency`. | *** ## Widget Types Skills can declare a dashboard widget to display persistent structured data. The widget appears on the Today/Dashboard view alongside weather, tasks, and quick actions. ### Status Single status indicator — ideal for service health, connection state, or simple on/off checks. ```toml theme={null} [widget] type = "status" title = "Server Status" [[widget.fields]] key = "status" label = "State" type = "badge" [[widget.fields]] key = "uptime" label = "Uptime" type = "percentage" [[widget.fields]] key = "last_check" label = "Last Check" type = "datetime" ``` ### Metric Single large number with trend — ideal for KPIs, counts, revenue, or any headline number. ```toml theme={null} [widget] type = "metric" title = "Monthly Revenue" [[widget.fields]] key = "value" label = "MRR" type = "currency" [[widget.fields]] key = "change" label = "vs Last Month" type = "percentage" ``` ### Table Rows of structured data — ideal for lists, records, deployments, or any tabular output. ```toml theme={null} [widget] type = "table" title = "Active Issues" [[widget.fields]] key = "title" label = "Issue" type = "text" [[widget.fields]] key = "assignee" label = "Assignee" type = "text" [[widget.fields]] key = "priority" label = "Priority" type = "badge" [[widget.fields]] key = "updated" label = "Updated" type = "datetime" ``` ### Log Chronological event feed — ideal for notifications, incidents, messages, or activity streams. ```toml theme={null} [widget] type = "log" title = "Recent Incidents" [[widget.fields]] key = "message" label = "Event" type = "text" [[widget.fields]] key = "severity" label = "Level" type = "badge" [[widget.fields]] key = "timestamp" label = "When" type = "datetime" ``` ### Key-Value (KV) Key-value pairs — ideal for configuration summaries, stats, or metadata. ```toml theme={null} [widget] type = "kv" title = "Project Stats" [[widget.fields]] key = "total_records" label = "Records" type = "number" [[widget.fields]] key = "storage_used" label = "Storage" type = "text" [[widget.fields]] key = "last_sync" label = "Last Sync" type = "datetime" ``` ### Field Types | Type | Rendering | Example | | ------------ | -------------------------------- | ------------------------------------ | | `text` | Plain text | "Deploy to production" | | `number` | Formatted with locale separators | "1,234,567" | | `badge` | Colored pill (green/yellow/red) | "Active" (green), "Warning" (yellow) | | `datetime` | Relative time | "2 hours ago" | | `percentage` | Progress bar + number | "94.5%" | | `currency` | Dollar symbol + formatted | "\$12,450.00" | *** ## Installing Skills ### From PawzHub (In-App) 1. Open the **Skills** tab in the sidebar 2. Click the **Browse PawzHub** section 3. Browse or search available skills by name or category 4. Click **Install** on any skill 5. Configure credentials if required 6. Assign to agents via **Agents → \[agent] → Skills** ### Manual Install Download a `pawz-skill.toml` file and place it in the skills directory: ``` ~/.paw/skills/{skill-id}/pawz-skill.toml ``` For example: ``` ~/.paw/skills/notion/pawz-skill.toml ~/.paw/skills/linear/pawz-skill.toml ~/.paw/skills/stripe/pawz-skill.toml ``` Restart Pawz (or the skill loader hot-reloads). The skill appears in the Skills tab with a "Community" badge. ### Uninstalling * **Community skills**: Click the **Uninstall** button in the Skills tab. This deletes the skill folder from `~/.paw/skills/` and cleans up stored credentials and enabled state. * **Core skills**: Cannot be uninstalled (they're compiled into the binary). Disable them per-agent in **Agents → \[agent] → Skills** instead. *** ## Creating Skills ### In-App Wizard The **Create Skill** wizard in the Skills tab walks you through building a skill without writing TOML by hand: 1. **Basic Info** — name, category, icon, description 2. **Credentials** — add API key fields with labels and placeholders 3. **Instructions** — write or paste agent instructions (templates available for REST APIs, CLI tools, and web scrapers) 4. **Widget** — optionally declare dashboard output with field types 5. **Test** — enable the skill and verify it works with a live agent 6. **Publish** — save locally, export TOML, or publish directly to PawzHub via GitHub PR ### AI-Assisted Creation Ask your agent to create a skill for you: > "Create a PawzHub skill for the Notion API" The agent fetches the API docs, generates a complete `pawz-skill.toml` with endpoints, auth headers, and instructions, then pre-fills the wizard for your review. ### Template Starters The wizard includes starter templates: * **REST API** — fetch calls with auth headers, JSON parsing * **CLI Tool** — exec commands with flag reference * **Web Scraper** — fetch + HTML parsing instructions *** ## Publishing to PawzHub ### Submission Flow 1. **Fork** the [`OpenPawz/pawzhub`](https://github.com/OpenPawz/pawzhub) repository 2. **Create** `skills/{your-skill-id}/pawz-skill.toml` 3. **Open a Pull Request** — CI validates your manifest automatically 4. **Maintainer reviews** and merges 5. **`registry.json`** is auto-rebuilt — your skill appears in the in-app browser ### One-Click Publish (from Pawz) If you created a skill using the in-app wizard: 1. Click **Publish to PawzHub** in the wizard's final step 2. Pawz opens a pre-filled GitHub PR on `OpenPawz/pawzhub` 3. CI validates, maintainer reviews, done ### CI Validation Every PR is checked automatically: | Check | Description | | ------------------ | ------------------------------------------------------ | | Valid TOML | Syntax is correct, required fields present | | Unique ID | No collision with built-in or existing skills | | Valid category | Must be one of the defined categories | | Safe ID format | Alphanumeric + hyphens only (no path traversal) | | Semver version | Version follows `X.Y.Z` format | | Description length | Between 10 and 500 characters | | Widget validation | Field types match allowed values if widget is declared | | Instruction-only | No executable code patterns detected | ### Quality Guidelines Skills are accepted based on quality, not quantity. We learned from OpenClaw's ClawHub that accepting everything leads to 48% junk (1,180 spam, 396 malicious out of 5,705 submissions). **Required:** * Valid, well-tested `pawz-skill.toml` * Clear, accurate description * Working instructions that the agent can follow **Recommended (earns a "Verified" badge):** * Tested in a real Pawz workspace * Includes a widget for dashboard output * Screenshot or demo in the PR description * Created using the in-app wizard *** ## Skill Architecture Deep Dive ### How Credentials Flow ```mermaid actions={false} theme={null} graph TD A["User enters API key\nin Skills tab"] --> B["AES-GCM encryption\n256-bit key from OS keychain"] B --> C["Stored in SQLite\nEncrypted blob"] C --> D["On prompt build:\ndecrypted in memory"] D --> E["Injected into prompt\nNOTION_API_KEY = secret_abc123..."] E --> F["Agent calls fetch\nwith Authorization header"] F --> G["Domain allowlist\nenforced"] G --> H["API response\nreturned to agent"] ``` ### How Instructions Work Skill instructions are injected into the agent's system prompt alongside all other enabled skills: ``` # Enabled Skills You have the following skills available. Use exec, fetch, read_file, write_file, and other built-in tools to leverage them. ## Notion Skill (notion) You have access to the Notion API via the user's integration token. [... full instructions ...] Credentials (use these values directly — do NOT ask the user for them): - NOTION_API_KEY = secret_abc123... ## Linear Skill (linear) [... instructions ...] ``` The agent then uses the built-in `fetch` tool (supports GET/POST/PUT/PATCH/DELETE with custom headers and body) or `exec` tool (shell with Docker sandbox routing) to perform the actual API calls. ### How Widgets Work 1. Skill manifest declares a `[widget]` with type and fields 2. Agent runs the skill and produces structured JSON matching the widget schema 3. Agent calls the `skill_output` tool to persist the data 4. Dashboard reads `skill_outputs` table and renders the widget card 5. Optional `refresh` interval triggers periodic re-fetching *** ## Security Model ### What Community Skills Can Do * Inject text into the agent's system prompt (instructions) * Declare credential fields (encrypted by the engine, never handled by the skill) * Declare widget schemas (rendered by the app, not by the skill) ### What Community Skills Cannot Do * Execute arbitrary Rust code (no compiled tool functions) * Bypass domain allowlist/blocklist (enforced by `execute_fetch`) * Access the OS keychain directly (credential injection is engine-side) * Read engine source code (blocked by `execute_read_file`) * Install blocked packages (enforced by `execute_exec`) * Run unsandboxed commands when Docker sandbox is enabled ### Runtime Protections | Layer | Protection | | ------------------- | ------------------------------------------------ | | **Credentials** | AES-GCM encrypted, key in OS keychain | | **Network** | Domain allowlist/blocklist on every `fetch` call | | **Shell** | Docker sandbox routing when enabled | | **File system** | Engine source code read-blocked | | **Packages** | Blocked package list enforced on `exec` | | **Agent isolation** | Each agent has its own working directory | *** ## PawzHub vs. Other Skill Registries | | ClawHub (OpenClaw) | PawzHub (Pawz) | | ------------------- | ------------------------ | ----------------------------------------------------------- | | **Tiers** | Single (prompt-only) | Three: Skills, Integrations, Extensions | | **Format** | Freeform SKILL.md | SKILL.md (Tier 1) + structured `pawz-skill.toml` (Tier 2–3) | | **Credentials** | Manual env vars | Typed fields → vault-encrypted (AES-GCM) | | **Output** | Chat text only | Dashboard widgets (5 types) + chat + custom views | | **Quality control** | 48% junk/malicious | CI-validated, in-app tested | | **Security** | VirusTotal after publish | Validated at submit, runtime policy enforced | | **Creation** | Write markdown by hand | In-app wizard + AI generation | | **Modularity** | Drop in folder | Per-agent scoping + per-workspace profiles | | **Versioning** | None | Semver + update detection | | **Storage** | None | Persistent key-value store (Extensions) | | **Custom UI** | None | Custom sidebar views (Extensions) | # Model Pricing & Budget Source: https://docs.openpawz.ai/guides/pricing Pawz tracks token usage and costs across all AI providers, enforces daily budgets, and can automatically route tasks to cheaper models when appropriate. # Model Pricing & Budget Pawz tracks token usage and costs across all AI providers, enforces daily budgets, and can automatically route tasks to cheaper models when appropriate. ## Per-model pricing Pawz uses built-in pricing data to estimate costs in real time. Prices are per **1 million tokens**. | Model | Input (\$/1M tokens) | Output (\$/1M tokens) | Provider | | ------------------- | -------------------- | --------------------- | --------- | | Claude 3 Haiku | \$0.25 | \$1.25 | Anthropic | | Claude Haiku 4 | \$1.00 | \$5.00 | Anthropic | | Claude Sonnet 4.x | \$3.00 | \$15.00 | Anthropic | | Claude Opus 4.x | \$15.00 | \$75.00 | Anthropic | | Gemini Flash | \$0.15 | \$0.60 | Google | | Gemini Pro | \$1.25 | \$10.00 | Google | | GPT-4.1 | \$2.50 | \$10.00 | OpenAI | | GPT-4.1-mini / nano | \$0.15 | \$0.60 | OpenAI | | GPT-4o | \$2.50 | \$10.00 | OpenAI | | GPT-4o-mini | \$0.15 | \$0.60 | OpenAI | | o3 / o1 | \$10.00 | \$40.00 | OpenAI | | o3-mini / o4-mini | \$1.10 | \$4.40 | OpenAI | | DeepSeek Chat | \$0.27 | \$1.10 | DeepSeek | | DeepSeek Reasoner | \$0.55 | \$2.19 | DeepSeek | :::info Prices are based on each provider's published rates. Local models (Ollama) have zero cost. For providers not listed (custom, OpenRouter, etc.), costs are estimated based on the closest matching model name. ::: ### Cost comparison To put these numbers in perspective, here's the approximate cost for a **10,000-token conversation** (5K input + 5K output): | Model | Estimated cost | | ----------------- | -------------- | | Gemini Flash | \$0.004 | | GPT-4o-mini | \$0.004 | | GPT-4.1-mini | \$0.004 | | DeepSeek Chat | \$0.007 | | Claude 3 Haiku | \$0.008 | | o3-mini / o4-mini | \$0.028 | | Claude Haiku 4 | \$0.030 | | Gemini Pro | \$0.056 | | GPT-4o | \$0.063 | | GPT-4.1 | \$0.063 | | Claude Sonnet 4.x | \$0.090 | | o3 / o1 | \$0.250 | | Claude Opus 4.x | \$0.450 | ## Cache token accounting When providers support prompt caching (e.g., Anthropic), Pawz applies reduced rates for cached tokens: | Token type | Cost multiplier | | -------------- | ---------------------- | | Normal tokens | 100% (full price) | | Cache reads | **10%** of normal cost | | Cache creation | **25%** of normal cost | :::tip Anthropic's prompt caching can dramatically reduce costs for repetitive tasks. Long system prompts and skill instructions benefit the most from caching since they remain constant across turns. ::: ## Daily budget Pawz can enforce a daily spending limit to prevent runaway costs. ### Configuration | Setting | Default | Description | | ------------------ | -------- | ------------------------------------- | | `daily_budget_usd` | `$10.00` | Maximum daily spend across all models | Set to `0` to disable budget enforcement entirely. Configure the budget in **Settings → Agent Defaults** or directly in the engine config: ```json theme={null} { "daily_budget_usd": 10.0 } ``` ### Budget enforcement The budget is checked **before each API call**. Pawz provides progressive warnings as spending increases: | Threshold | Action | | ------------------ | --------------------------------------- | | **50%** of budget | Warning notification | | **75%** of budget | Elevated warning | | **90%** of budget | Urgent warning | | **100%** of budget | **Hard block** — API calls are rejected | :::warning When the daily budget is reached, all AI API calls are blocked until the next day (midnight UTC). Ongoing conversations will stop receiving responses. Set a budget that accommodates your expected daily usage. ::: ## DailyTokenTracker Pawz maintains per-model cost tracking through the `DailyTokenTracker`: * Tracks input and output tokens separately per model * Calculates costs using the pricing table above * Applies cache token discounts automatically * Resets daily at midnight The tracker enables the budget enforcement system and powers the cost display in the chat interface (shown in `complete` events with usage stats). ## Auto-tier model selection The `auto_tier` feature automatically routes tasks to cheaper or more expensive models based on complexity. ### Task complexity classification Pawz analyzes each message to determine if it's simple or complex: | Classification | Routing | Example tasks | | -------------- | ------------------------- | ----------------------------------------------------- | | **Simple** | Routes to `cheap_model` | "What time is it?", "Convert 5kg to lbs", simple Q\&A | | **Complex** | Routes to `default_model` | Multi-step reasoning, code generation, research | The classification uses keyword signals and heuristics to decide. When `auto_tier` is enabled in your model routing config, simple messages skip the expensive default model entirely. ### Model routing configuration ```json theme={null} { "model_routing": { "boss_model": "claude-opus-4-6", "worker_model": "claude-sonnet-4-6", "cheap_model": "claude-3-haiku", "auto_tier": true, "specialty_models": { "coder": "gemini-2.5-pro" }, "agent_models": { "agent-uuid-here": "gpt-4o" } } } ``` | Field | Description | | ------------------ | ----------------------------------------------------- | | `boss_model` | Powerful model for the orchestrator/boss agent | | `worker_model` | Default model for sub-agents (cheaper/faster) | | `cheap_model` | Budget model for simple tasks when `auto_tier` is on | | `auto_tier` | Enable automatic model selection by task complexity | | `specialty_models` | Per-specialty overrides (e.g., `coder`, `researcher`) | | `agent_models` | Per-agent overrides (highest priority) | **Resolution order** (highest priority first): 1. Per-agent override (`agent_models`) 2. Per-specialty override (`specialty_models`) 3. `cheap_model` (if `auto_tier` enabled and task is simple) 4. `default_model` ## Tips for cost optimization :::tip Cost optimization strategies 1. **Use `auto_tier`**: Enable automatic model selection so simple queries use cheap models. This alone can cut costs 50%+. 2. **Set a daily budget**: Even a generous budget prevents accidental runaway costs from automated tasks or cron jobs. 3. **Use Ollama for development**: Local models are free. Use them for testing agent configurations before switching to paid providers. 4. **Match model to task**: Don't use Claude Opus for simple questions. Create chat modes (see [Foundry](/foundry.md)) for different tiers. 5. **Enable session compaction**: Long sessions consume more tokens per turn. Use `/compact` or let auto-compaction manage context size. 6. **Leverage prompt caching**: Anthropic's cache reads cost only 10% of normal input tokens. Consistent system prompts and skill instructions benefit most. 7. **Use `worker_model` for orchestration**: In multi-agent projects, the boss agent should use a capable model, but workers can use cheaper alternatives. 8. **Monitor the `complete` events**: Each response includes token usage stats (input/output/total tokens and model name) so you can track spending in real time. ::: # Projects — File Browser Source: https://docs.openpawz.ai/guides/projects The Projects view is a local file browser built into Pawz. It lets you browse project folders, inspect Git status, and preview text files — all within the app using Tauri's filesystem APIs. # Projects — File Browser The Projects view is a local file browser built into Pawz. It lets you browse project folders, inspect Git status, and preview text files — all within the app using Tauri's filesystem APIs. ## Adding projects 1. Open the **Projects** view 2. Click **Add Folder** 3. Select a local directory 4. The folder appears in your project list with its directory tree ### Operations | Action | Description | | ----------------- | -------------------------------------------------------------- | | **Add folder** | Browse and add a local directory to your project list | | **Remove folder** | Remove a project from the list (does not delete files on disk) | | **Refresh** | Re-read the directory tree and update Git status | Projects are persisted in **localStorage**, so your project list survives app restarts. ## File tree Each project displays an expandable directory tree: * **Lazy loading**: Subdirectories are only read when you expand them, keeping the UI responsive for large projects * **File icons**: Files and folders are visually distinguished * **Click to preview**: Clicking a text file opens a read-only preview ### File preview The file viewer provides a **read-only** text preview of file contents. This is useful for quick inspection without leaving Pawz. :::info File preview is read-only by design. To edit files, use the agent's `write_file` or `edit_file` tools, or open the file in your preferred editor. ::: ## Git integration For projects that are Git repositories, Pawz displays rich status information: | Field | Description | | ---------------- | ------------------------------------- | | **Branch** | Current checked-out branch | | **Remote** | Configured remote URL | | **Dirty files** | Number of uncommitted changes | | **Ahead/Behind** | Commits ahead of or behind the remote | | **Last commit** | Most recent commit message and hash | Git information is fetched via `@tauri-apps/plugin-shell` and can be refreshed manually with the **Refresh** button. :::tip Use the refresh button after committing or pulling to see updated Git status without restarting the app. ::: ## Security The Projects view enforces strict security boundaries to prevent browsing sensitive system paths. ### Blocked paths The following **18 sensitive path patterns** are blocked from browsing: | Pattern | Reason | | -------------------- | ------------------------------------- | | `.ssh` | SSH keys and configuration | | `.gnupg` | GPG keys and keyrings | | `.aws` | AWS credentials and config | | `.kube` | Kubernetes configuration | | `.docker` | Docker credentials | | `.gnome-keyring` | GNOME keyring directory | | `.password-store` | Password store directory | | `.netrc` | Network authentication credentials | | `/etc` | System configuration | | `/root` | Root user home | | `/var/log` | System logs | | `/proc` | Process information pseudo-filesystem | | `/sys` | Kernel/device pseudo-filesystem | | `/dev` | Device filesystem | | `C:\Windows` | Windows system directory | | `C:\Users\*\AppData` | AppData directory | | `.openclaw` | OpenClaw config (contains tokens) | | `.config/himalaya` | Himalaya email config | ### Security event logging Any attempt to access a blocked path is logged via `logSecurityEvent()` with the following details: * **Tool name**: The operation attempted * **Command**: The path that was blocked * **Risk level**: Security classification * **Detail**: Human-readable explanation * **Was allowed**: Always `false` for blocked paths :::warning These security restrictions cannot be bypassed from the UI. They are enforced at the application level to protect sensitive system data from accidental exposure to AI agents. ::: # Research Source: https://docs.openpawz.ai/guides/research The Research view lets agents conduct structured web research with source tracking and credibility scoring. # Research The Research view lets agents conduct structured web research with source tracking and credibility scoring. ## Modes | Mode | Sources | Timeout | When to use | | --------- | ------- | ------- | -------------------------------------- | | **Quick** | 3–5 | 120s | Fast answers, simple questions | | **Deep** | 10+ | 300s | Thorough investigation, complex topics | ## Workflow 1. Enter a research query 2. Choose **Quick** or **Deep** mode 3. Watch the live progress: * **Searching** — finding sources * **Reading** — fetching pages * **Analyzing** — processing content * **Found** — result discovered * **Summarizing** — generating synthesis 4. Review findings with sources ## Findings Each research finding includes: * **Summary** — key takeaway * **Content** — full extracted text * **Key points** — bullet-point highlights * **Sources** — URLs with titles and credibility scores (1–5) ### Source credibility Sources are scored on a 1–5 scale shown as dots: * ●●●●● — Highly credible (academic, official docs) * ●●●●○ — Generally reliable * ●●●○○ — Mixed reliability * ●●○○○ — Use with caution * ●○○○○ — Unreliable ## Actions For each finding you can: * **Dig Deeper** — ask follow-up questions about this finding * **Find Related** — search for related topics * **View Full** — see the complete content * **Delete** — remove the finding ## Reports Generate a compiled report from your findings: * Saved as markdown to `~/Documents/Paw/Research/` * Includes all findings, sources, and key points * Per-project sessions with query history ## Deep research mode Deep mode performs multi-step web research with synthesis: 1. **Query expansion** — the agent breaks your topic into multiple sub-queries 2. **Parallel search** — searches DuckDuckGo for each sub-query (10+ sources) 3. **Source fetching** — reads full page content from each result URL 4. **Cross-referencing** — compares claims across multiple sources 5. **Synthesis** — generates a comprehensive finding with key points and credibility scores | Setting | Quick mode | Deep mode | | ----------------- | ------------------------ | ------------------------------------- | | Sources fetched | 3–5 | 10+ | | Timeout | 120 seconds | 300 seconds | | Sub-queries | 1 | Multiple (auto-generated) | | Cross-referencing | No | Yes | | Best for | Simple factual questions | Complex topics, comparisons, analysis | :::tip Deep research uses more tokens and takes longer. Start with Quick mode to validate your query, then switch to Deep for thorough investigation. ::: ## Research notebook integration All research data is saved to your local workspace at `~/Documents/Paw/Research/`: ```mermaid actions={false} theme={null} graph TD ROOT["~/Documents/Paw/Research/"] --> PROJ["project-id/"] PROJ --> PJ["project.json\nMetadata & query history"] PROJ --> RM["README.md\nHuman-readable summary"] PROJ --> FIND["findings/"] PROJ --> REP["reports/"] FIND --> F1["finding-id.json\nStructured finding with sources"] REP --> R1["report-id.json\nGenerated research reports"] ``` Each project maintains: * **Query history** — every research query you've run * **Findings** — structured results with content, summaries, key points, and sources * **Reports** — compiled multi-finding reports Use the **folder icon** in the project header to open the research folder in your file manager. ## Citation and source tracking Every research finding tracks its sources with full provenance: | Field | Description | | ------------- | --------------------------------------------------------- | | `url` | Original source URL | | `title` | Page title or domain name | | `credibility` | 1–5 score (see [Source credibility](#source-credibility)) | | `extractedAt` | Timestamp when the source was fetched | | `snippets` | Relevant text excerpts from the source | The **Sources panel** (right sidebar) aggregates all sources across findings in the current project, making it easy to review which sites were consulted. ### Live source feed During active research, a live feed shows sources as they're discovered in real-time. Each source displays its domain and credibility score as the agent processes it. ## Research export formats Research can be exported in several ways: | Format | How | Contents | | ----------------------- | -------------------------------- | -------------------------------------------------------------------- | | **Markdown report** | Click **Generate Report** | Executive summary, key findings, analysis, conclusions, bibliography | | **Individual findings** | Click **Full** on any finding | Complete content with sources and key points | | **Raw JSON** | Open `~/Documents/Paw/Research/` | Machine-readable findings with all metadata | | **Project folder** | Click **Open in Finder** | All findings, reports, and project config | ### Generating a report 1. Conduct several research queries to build up findings 2. Click **Generate Report** 3. The agent synthesizes all findings into a structured report: * Executive Summary * Key Findings (organized by theme) * Detailed Analysis * Conclusions and Recommendations * Sources Bibliography 4. The report is saved as markdown in the project's `reports/` folder ## Tips * Start with a broad quick search, then dig deeper on interesting findings * Use the source credibility scores to prioritize reliable information * Chain findings together: dig deeper → find related → synthesize # Session Management Source: https://docs.openpawz.ai/guides/sessions # Session Management Sessions are the core unit of conversation in Pawz. Each session holds a complete chat history between you and an agent, with built-in tools for renaming, clearing, compacting, and deleting conversations. ## Session data model Every session is stored in the engine's SQLite database with the following fields: | Field | Type | Description | | --------------- | --------- | ---------------------------------- | | `id` | UUID | Unique session identifier | | `label` | String | User-friendly display name | | `model` | String | AI model used in this session | | `system_prompt` | String | Custom system prompt (if any) | | `agent_id` | String | The agent assigned to this session | | `message_count` | Number | Total messages in the session | | `created_at` | Timestamp | When the session was created | | `updated_at` | Timestamp | Last activity time | ## Session operations ### List Retrieve all sessions, optionally filtered by agent. Sessions are displayed as cards in **Settings → Sessions** showing the label, model badge, message count, and timestamps. ### Rename Update the session label to something more meaningful. Use the slash command: ``` /rename My research on quantum computing ``` Or click the rename action on the session card in Settings. ### Clear Remove **all messages** from a session while keeping the session itself. This is useful when you want a fresh start without losing your session configuration. :::warning Clearing a session is destructive — all messages are permanently removed. Pawz requires a double-confirm before proceeding. ::: ### Delete Permanently remove a session and all its messages from the database. :::warning Deletion is irreversible. A double-confirm dialog will appear before the session is removed. ::: ### Compact Compress the session's message history using AI-generated summaries. See [Session Compaction](#session-compaction) below. ## Session compaction Long conversations consume large context windows, which increases cost and can hit model token limits. Session compaction solves this by replacing older messages with a concise AI-generated summary. ### How it works ```mermaid actions={false} theme={null} graph TD A["Messages pile up in session"] --> B["Auto-trigger check\nbefore each turn"] B --> C{"≥20 messages AND\n>60k tokens?"} C -->|YES| D["AI generates summary\nof older messages"] C -->|NO| E["Continue normally"] D --> F["Older messages replaced\nwith single summary"] F --> G["Recent messages\npreserved intact"] ``` ### Compaction configuration | Setting | Default | Description | | -------------------- | ------- | ------------------------------------------------ | | `min_messages` | 20 | Minimum message count before compaction triggers | | `token_threshold` | 60,000 | Estimated token count threshold | | `keep_recent` | 6 | Number of recent messages to preserve unchanged | | `max_summary_tokens` | 2,000 | Maximum tokens for the generated summary | ### Token estimation Pawz estimates token counts using a simple heuristic: **\~4 characters per token**. This is intentionally conservative to avoid exceeding model context limits. ### Auto-trigger Before each new conversation turn, the engine checks: 1. Does this session have **≥20 messages**? 2. Is the estimated token count **>60,000 tokens**? If both conditions are met, compaction runs automatically before the new message is processed. ### Manual trigger You can force compaction at any time using the slash command: ``` /compact ``` This is useful when you want to reclaim context space mid-conversation without waiting for the auto-trigger threshold. :::tip Use `/compact` proactively before starting a complex task in a long session. This gives the agent maximum context space to work with. ::: ## Live token meter Every chat session displays a real-time **token meter** in the header showing how much of the context window is in use. ### Visual indicators | Context usage | Color | Meaning | | ------------- | ------ | -------------------------------------------------- | | 0–59% | Green | Plenty of room | | 60–79% | Yellow | Getting full — consider compacting soon | | 80–100% | Red | Near limit — compaction will trigger automatically | ### Context breakdown Click the token meter to see a detailed breakdown of where tokens are going: * **System prompt** — base instructions, personality, soul files * **Skill instructions** — tool documentation injected into context * **Memory context** — auto-recalled memories * **Conversation** — message history * **Total** vs **Limit** — with percentage This helps you understand exactly what's consuming context and where to optimize. ### Session cost The token meter also displays the running session cost (e.g. `$0.0042`). Cost is calculated using per-model pricing rates for input and output tokens separately. Input/output token counts are tracked in the **Mission Control** side panel along with total message count. ## Configurable context window Each agent can have a custom context window size, configured in **Settings → Advanced → Context Window (tokens)**. | Setting | Default | Range | Description | | -------------- | ------- | ----------------- | ----------------------------------------------------- | | Context window | 32,000 | 4,000 – 1,000,000 | How much conversation history the agent sees per turn | **Why this matters:** * **Larger windows** = better topic tracking across long conversations, but higher cost per turn * **Smaller windows** = cheaper per turn, compaction kicks in sooner * Most models support 128K–1M tokens, so the default 32K is deliberately conservative to control costs * Increase for complex research tasks; decrease for simple Q\&A bots The context window limit determines when the token meter turns yellow (60%) and red (80%), and when auto-compaction triggers. ## Session Settings UI Navigate to **Settings → Sessions** to manage all your sessions in one place: * **Session cards** show the label, model badge, message count, and timestamps * **Expandable actions** per card: Rename, Clear, Delete * **Double-confirm pattern** for all destructive operations (Clear and Delete) ## Slash commands for sessions | Command | Description | | ----------------- | ----------------------------------------- | | `/new [label]` | Start a new session (optional label) | | `/rename