17 Commits

Author SHA1 Message Date
Rohit Kushwaha
d724cdc08c fix(discord): bake identity files and soul yaml into Docker image
Coolify can't volume-mount local files, so COPY them into the image
at build time. Identity files go to ~/.pocketpaw/identity/ and
paw.yaml goes to ~/paw.yaml for easy import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 20:40:05 +05:30
Rohit Kushwaha
d5c4d11776 feat(discord): rewrite identity prompts and add soul config for Discord deployment
- Rewrite IDENTITY.md and INSTRUCTIONS.md to be concise, human, no em dashes
- Rewrite discord.md behavior layer with message awareness and context rules
- Add paw.yaml soul-protocol config for persistent AI personality
- Enable soul by default in .env.example with import instructions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 20:40:05 +05:30
Rohit Kushwaha
c95d250843 refactor(docs): streamline identity and instructions for Discord behavior 2026-03-21 01:47:43 +05:30
Rohit Kushwaha
e6d9121879 chore(discord): refine bot identity and conversation behavior guidelines
Rewrite IDENTITY.md and INSTRUCTIONS.md to emphasize selective,
low-noise behavior. The bot should default to silence, prefer
reactions over replies, and only participate when it genuinely
improves the conversation. Adds a clear decision order (do nothing,
react, reply, thread) and concrete good/bad examples.
2026-03-21 00:56:07 +05:30
Rohit Kushwaha
5515eb7460 feat(discord): add Claude Code OAuth token support for Docker/Coolify
- Add POCKETPAW_CLAUDE_CODE_OAUTH_TOKEN config and pass it through to
  the Claude CLI subprocess as CLAUDE_CODE_OAUTH_TOKEN
- Create ~/.claude.json marker file in Dockerfile (fixes "login to
  start" prompt even when credentials exist)
- Pre-create ~/.claude dir with correct ownership and set HOME env var
- Document Option E (setup-token) and Option F (interactive login)
  in .env.example
2026-03-20 21:42:09 +05:30
Rohit Kushwaha
1896fc85c3 feat(discord): add Claude Code CLI auth option for Docker
Mount ~/.claude credentials into the container so the Discord bot can
reuse the host's Claude Code login without needing an API key.
2026-03-19 21:05:52 +05:30
Rohit Kushwaha
9399cdade6 perf(discord): remove Playwright and Chromium from Discord Dockerfile
Removes ~500MB+ from the image and significantly reduces memory usage.
Browser automation isn't needed for the Discord bot.
2026-03-19 16:43:23 +05:30
Rohit Kushwaha
7a1568490e feat: add soul config to .env.example files and upgrade Discord compose
Add soul-protocol settings to both .env.example files. Add workspace
volume and resource limits (8GB/4CPU) to Discord docker-compose.
2026-03-19 16:33:48 +05:30
Rohit Kushwaha
66fb8210ac docs: add new Discord conversation settings to .env.example files 2026-03-19 15:12:43 +05:30
Rohit Kushwaha
c2c78bab44 feat(discord): add server-wide conversation mode and upgrade Docker setup
Add discord_conversation_all_channels config to enable auto-conversation
in all server channels without needing /converse per channel. Scoped to
allowed_guild_ids so unauthorized servers can't abuse it.

Pin Node.js to 22.14.0 in both Dockerfiles. Upgrade Discord Dockerfile
to full-featured with all extras, Playwright, Codex, and OCR support.
2026-03-19 14:57:55 +05:30
Rohit Kushwaha
620f4cacab feat(discord): replace discord.py with discli adapter (#604)
* feat(discord): replace discord.py with discli subprocess adapter

Replace the direct discord.py library dependency with discord-cli-agent (discli),
a subprocess-based adapter that communicates via JSONL over stdin/stdout. This
gives the agent full Discord superpowers: reactions, threads, message search,
DMs, and channel management via the new DiscordCLITool.

- Rewrite DiscordAdapter as DiscliAdapter (subprocess bridge to discli serve)
- Add DiscordCLITool wrapping discli CLI for agent-initiated Discord actions
- Replace discord.py with discord-cli-agent in all pyproject.toml extras
- Update dependency checks in headless.py and dashboard_state.py
- Register discord_cli tool in builtin tools and tool policy
- Rewrite test suite for new adapter API (46 tests passing)
- Update deploy identity/instructions with new capabilities (reactions, threads, search)

* fix(tests): update extras install test for discord-cli-agent

Update test_check_installed_dep assertion from discord.py to
discord-cli-agent to match the dependency change.

* fix(tests): update extras install test for discli module name

* fix(tests): update media attachment tests for DiscliAdapter

* fix(discord): drain stderr and clean up process on startup failure

Two fixes for the dashboard showing stuck "starting" status:

1. Add _drain_stderr() task to continuously read discli's stderr pipe.
   Without this, if discord.py logs warnings to stderr the pipe buffer
   fills up and the process blocks, preventing the ready event from
   being emitted on stdout.

2. Call _on_stop() before raising on startup timeout so the subprocess
   and background tasks are properly cleaned up instead of leaking.

* feat(discord): add thread/poll to system prompt and tool description

- Add Discord section to default instructions with thread/poll examples
- Update DiscordCLITool description with thread create and poll create
- Mark /resume target param as optional

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(discord): inject discord.md instructions when on Discord channel

- Create bootstrap/discord.md with full Discord capability docs
  (messages, DMs, threads, polls, channels, roles, members, server)
- Context builder loads channel-specific instruction files and injects
  them into the system prompt only when on that channel
- Inject discord_username and discord_guild_id from message metadata
  so the LLM knows who it's talking to and can DM them
- Pass metadata through from agent loop to context builder
- Remove Discord section from default_provider.py (now in discord.md)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: bump discord-cli-agent dependency to >=0.6.0

Requires v0.6.0 for the complete serve action registry
(threads, polls, DMs, channels, roles, members, server).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(discord): propagate bot token to parent env for CLI tool

DiscordCLITool spawns separate discli processes that need
DISCORD_BOT_TOKEN, but the token was only set in the serve
subprocess env. Now also sets it in os.environ so all child
processes (including discord_cli tool calls) inherit it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: register DiscordCLITool in tools CLI dispatcher

discord_cli was missing from the CLI registry, so all agent calls
via `python -m pocketpaw.tools.cli discord_cli '...'` failed with
"Unknown tool". This is why the bot couldn't DM, create threads,
or do any Discord operations through the Claude SDK backend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: background channel startup, CLI auth bypass, converse tests

- Dashboard: start slow adapters (Discord) in background so HTTP
  response returns fast; frontend polls until running
- Claude SDK: skip API key check when claude CLI is available
  (handles OAuth auth internally)
- Tests: add converse slash command enable/disable tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(discord): add slash commands, user mentions, and admin-gate converse

Add rename/backend/model/tools/delete/backends slash commands to the
Discord adapter, include sender_id in context, document user mention
syntax (<@ID>), restrict /converse to admins, and update /help output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(security): patch command injection, temp leak, and deprecated API

- DiscordCLITool: replace create_subprocess_shell with
  create_subprocess_exec + shlex.split to prevent shell injection
- Clean up slash config temp file on adapter stop
- Use asyncio.get_running_loop() instead of deprecated get_event_loop()
- Convert conversation_channel_ids from list to set
- Scope Claude CLI auth bypass to claude_code provider only
- Add is_admin to converse test events

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(discord): MCP server, permission fix, and system prompt overhaul

- Add pocketpaw-discord MCP server that wraps discli, exposing Discord
  operations (send messages, polls, threads, reactions, roles, etc.)
  as native MCP tools for all backends (codex_cli, google_adk, etc.)
- Auto-register the MCP server when the Discord adapter starts
- Fix /converse permission check: accept Manage Server in addition to
  Administrator, use interaction.permissions (Discord payload) instead
  of guild_permissions (member cache) via discli 0.6.4
- Rewrite discord.md system prompt: hide internal tool names from users,
  add context-based reaction guidance, keep responses conversational
- Fix [NO_RESPONSE] marker leaking through streaming responses
- Handle rate_limit_event from Anthropic API in stateless query path
- Update docs and CLAUDE.md for discli adapter and MCP integration
- Remove stale /allowchannel /allowuser references from dashboard UI

* fix(dependencies): update discord-cli-agent to version 0.6.4

* style: format discord_server and discord_adapter

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 17:54:13 +05:30
Rohit Kushwaha
f7b55d9fac fix: Discord adapter reply, typing, /kill, and edge cases (#602)
* fix: Discord adapter reply, typing indicator, /kill, and edge cases

- Reply to user messages using message.reply() instead of channel.send()
- Add typing indicator that shows while agent is processing (8s refresh)
- Add /kill slash command to cancel in-flight requests
- Handle stale interaction tokens (15min expiry) with channel.send fallback
- Handle deleted source messages with graceful fallback
- Track buffer overflow to prevent duplicate overflow sends during edits
- Clean up typing/source state on [NO_RESPONSE] discard and stream end
- 10 new tests covering reply, typing, stale interaction, and overflow

* fix: tighten conversation mode and update Discord bot identity

- Update IDENTITY.md with proper PocketPaw project context and role
- Update INSTRUCTIONS.md with explicit [NO_RESPONSE] rules and examples
- Make engaged mode [NO_RESPONSE] prompt much more explicit for weaker models
- Remove overly aggressive "bot in last 3 messages" response trigger
- Bot now only engages when: directly addressed, immediately previous speaker,
  or a question is asked with bot active in last 4 messages

* fix: add project links to Discord bot identity

Website, docs, GitHub, issues, Discord invite, and Twitter links
added to both IDENTITY.md and INSTRUCTIONS.md so the bot can
point users to the right resources.

* feat(discord): native Discord UX improvements

- Add thinking reaction (brain emoji) on user message, removed when
  response starts streaming
- Slash command autocomplete for /resume (session names), /backend
  (registered backends), and /tools (tool profiles)
- Dynamic presence: shows "Helping N users" when actively processing
- Extract large code blocks (>800 chars) as file attachments instead
  of pasting inline
- Pass user display name and Discord roles in inbound metadata
- 3 new tests for reactions and code block extraction

* fix(discord): remove hardcoded thinking reaction

Reactions should be contextual/intelligent, not a fixed brain emoji
on every message. Removed all reaction add/remove logic and tests.

* feat(discord): add heuristic emoji reactions in conversation channels

When the bot skips a message (decides not to respond), it now reacts
with contextual emoji based on simple pattern matching:

- Thumbs up for "thanks/ty" (only if bot was the previous speaker)
- Wave for greetings (hi, hey, gm)
- Laugh for lol/lmao/haha
- Party for celebrations (lfg, pog, yay)
- Pensive for sadness (rip, oof, bruh)
- Mind blown for wow/insane/wild

Skips questions to avoid implying the bot will respond. One reaction
max per message. Zero LLM cost, just regex matching.

* revert: remove heuristic reactions, will add agent-driven react tool later
2026-03-14 05:02:00 +05:30
Rohit Kushwaha
6adb3b01bc fix: bundle Claude Code CLI in Discord Docker image 2026-03-14 04:07:28 +05:30
Rohit Kushwaha
b5c337b060 fix: handle permission errors in identity file creation for Docker 2026-03-14 04:03:31 +05:30
Rohit Kushwaha
9ee0ddc21c fix: remove :ro from identity volume mount to allow default file creation 2026-03-14 03:58:16 +05:30
Rohit Kushwaha
2c62c336e0 fix: rename docker-compose.yml to .yaml for Coolify compatibility 2026-03-14 03:53:16 +05:30
Rohit Kushwaha
824f6195f5 feat: add Discord deployment config under deploy/discord (#597)
Organized deployment files per-channel under deploy/:
- deploy/discord/Dockerfile - multi-stage Python 3.12 build
- deploy/discord/docker-compose.yml - service with identity mount
- deploy/discord/.env.example - 4 provider options documented
- deploy/discord/identity/ - customizable bot personality

Build context points to repo root so pyproject.toml and src/ are
accessible. Users run: cd deploy/discord && cp .env.example .env &&
docker compose up -d
2026-03-14 03:47:37 +05:30