Fixes the debouncer race where a fast comment message flushes on its
own before slow audio transcription completes, splitting a single
user turn into two.
Telegram sends "forward with a comment" as two separate messages. Buffer
inputs for ~600ms after each arrival and flush a single merged AgentInput;
label forwarded content with its origin so the merged text is intelligible.
The Dockerfile installs Chromium via `playwright install chromium`, but
Playwright MCP defaults to Chrome (the branded Google build) when no
browser is specified. On a fresh container the launch fails and the
agent falls back to installing Chrome at runtime. Baking the env var
into the image keeps installed browser and default in sync.
Adds a `send` custom tool so the agent can push files and images from the
workspace to the owner as Telegram attachments, closing the gap where the
bot could receive files but only ever reply with text.
Two review followups:
- Consume the piped stderr from @playwright/mcp so browser-launch
failures surface in our own logs (was set to "pipe" but never read).
- Drop the wrong ["mcp-server-playwright"] lookup; the actual bin key
is "playwright-mcp". Falling through Object.values worked but was
dead code.
Bridge @playwright/mcp as a stdio subprocess and re-export its tools
as Pi custom tools, gated on PLAYWRIGHT_ENABLED. Uses Type.Unsafe to
pass MCP inputSchema through to the model without hand-mapping.
Extends the calendar tool to create, modify, and delete recurring events
via raw RFC 5545 recurrence lines, with instance vs. series scope on
update/delete and a list_instances action to fetch a series' occurrences.
Telegram delivers voice messages with a .oga extension (audio-only OGG),
which OpenAI's transcription API rejects even though the container bytes
are identical to .ogg.