Add send-file directive and Discord/CLI file support (#319)

Co-authored-by: Jason Carreira <jason@visotrust.com>
Co-authored-by: Cameron <cameron@pfiffer.org>
Co-authored-by: Charles Packer <packercharles@gmail.com>
Co-authored-by: Sarah Wooders <sarahwooders@gmail.com>
Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jason Carreira
2026-02-23 18:44:34 -05:00
committed by GitHub
parent ad4c22ba54
commit 1fbd6d5a2e
14 changed files with 364 additions and 22 deletions

View File

@@ -41,6 +41,28 @@ Adds an emoji reaction to a message.
- Unicode emoji: direct characters like `👍`
- `message` (optional) -- Target message ID. Defaults to the message that triggered the response.
### `<send-file>`
Sends a file or image to the same channel/chat as the triggering message.
```xml
<send-file path="/tmp/report.pdf" caption="Report attached" />
<send-file path="/tmp/photo.png" kind="image" caption="Look!" />
<send-file path="/tmp/temp-export.csv" cleanup="true" />
```
**Attributes:**
- `path` / `file` (required) -- Local file path on the LettaBot server
- `caption` / `text` (optional) -- Caption text for the file
- `kind` (optional) -- `image` or `file` (defaults to auto-detect based on extension)
- `cleanup` (optional) -- `true` to delete the file after sending (default: false)
**Security:**
- File paths are restricted to the configured `sendFileDir` directory (defaults to `data/outbound/` under the agent's working directory). Paths outside this directory are blocked and logged.
- Symlinks that resolve outside the allowed directory are also blocked.
- File size is limited to `sendFileMaxSize` (default: 50MB).
- The `cleanup` attribute only works when `sendFileCleanup: true` is set in the agent's features config (disabled by default).
### `<no-reply/>`
Suppresses response delivery entirely. The agent's text is discarded.
@@ -66,13 +88,13 @@ Backslash-escaped quotes (common when LLMs generate XML inside a JSON context) a
## Channel Support
| Channel | `addReaction` | Notes |
|-----------|:---:|-------|
| Telegram | Yes | Limited to Telegram's [allowed reaction set](https://core.telegram.org/bots/api#reactiontype) (~75 emoji) |
| Slack | Yes | Uses Slack emoji names (`:thumbsup:` style). Custom workspace emoji supported. |
| Discord | Yes | Unicode emoji and common aliases. Custom server emoji not yet supported. |
| WhatsApp | No | Directive is skipped with a warning |
| Signal | No | Directive is skipped with a warning |
| Channel | `addReaction` | `send-file` | Notes |
|-----------|:---:|:---:|-------|
| Telegram | Yes | Yes | Reactions limited to Telegram's [allowed reaction set](https://core.telegram.org/bots/api#reactiontype). |
| Slack | Yes | Yes | Reactions use Slack emoji names (`:thumbsup:` style). |
| Discord | Yes | Yes | Custom server emoji not yet supported. |
| WhatsApp | No | Yes | Reactions skipped with a warning. |
| Signal | No | No | Directive skipped with a warning. |
When a channel doesn't implement `addReaction`, the directive is silently skipped and a warning is logged. This never blocks message delivery.
@@ -112,7 +134,7 @@ The parser (`src/core/directives.ts`) is designed to be extensible. Adding a new
3. Add a parsing case in `parseChildDirectives()`
4. Add an execution case in `executeDirectives()` in `bot.ts`
See issue [#240](https://github.com/letta-ai/lettabot/issues/240) for planned directives like `<send-file>`.
See issue [#240](https://github.com/letta-ai/lettabot/issues/240) for planned directives.
## Source