feat: add POST /api/v1/chat endpoint for agent messaging (#242)

* feat: add POST /api/v1/chat endpoint for sending messages to agents

Adds an HTTP endpoint that accepts a JSON message, sends it to the
lettabot agent via sendToAgent(), and returns the agent's response.
This enables external systems (e.g. server-side tools in other agents)
to communicate with lettabot programmatically.

- Add ChatRequest/ChatResponse types
- Add AgentRouter interface extending MessageDeliverer with sendToAgent()
- Implement AgentRouter on LettaGateway with agent-name routing
- Add POST /api/v1/chat route with auth, validation, and JSON body parsing

Written by Cameron ◯ Letta Code

"The most profound technologies are those that disappear." -- Mark Weiser

* feat: add SSE streaming support to /api/v1/chat endpoint

When the client sends Accept: text/event-stream, the chat endpoint
streams SDK messages as SSE events instead of waiting for the full
response. Each event is a JSON StreamMsg (assistant, tool_call,
tool_result, reasoning, result). The result event signals end-of-stream.

- Export StreamMsg type from bot.ts
- Add streamToAgent() to AgentSession interface and LettaBot
- Wire streamToAgent() through LettaGateway with agent-name routing
- Add SSE path in chat route (Accept header content negotiation)
- Handle client disconnect mid-stream gracefully

Written by Cameron ◯ Letta Code

"Any sufficiently advanced technology is indistinguishable from magic." -- Arthur C. Clarke

* test+docs: add chat endpoint tests and API documentation

- 10 tests for POST /api/v1/chat: auth, validation, sync response,
  agent routing, SSE streaming, stream error handling
- 6 tests for gateway sendToAgent/streamToAgent routing
- Fix timingSafeEqual crash on mismatched key lengths (return 401, not 500)
- Document chat endpoint in configuration.md with sync and SSE examples
- Add Chat API link to docs/README.md index

Written by Cameron ◯ Letta Code

"First, solve the problem. Then, write the code." -- John Johnson
This commit is contained in:
Cameron
2026-02-09 16:53:31 -08:00
committed by GitHub
parent 6f5a322840
commit deb1c4532a
11 changed files with 545 additions and 11 deletions

View File

@@ -444,7 +444,7 @@ Attachments are stored in `/tmp/lettabot/attachments/`.
## API Server Configuration
The built-in API server provides health checks and CLI messaging endpoints.
The built-in API server provides health checks, CLI messaging, and a chat endpoint for programmatic agent access.
```yaml
api:
@@ -459,6 +459,74 @@ api:
| `api.host` | string | `127.0.0.1` | Bind address. Use `0.0.0.0` for Docker/Railway |
| `api.corsOrigin` | string | _(none)_ | CORS origin header for cross-origin access |
### Chat Endpoint
Send messages to a lettabot agent and get responses via HTTP. Useful for integrating
with other services, server-side tools, webhooks, or custom frontends.
**Synchronous** (default):
```bash
curl -X POST http://localhost:8080/api/v1/chat \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"message": "What is on my todo list?"}'
```
Response:
```json
{
"success": true,
"response": "Here are your current tasks...",
"agentName": "LettaBot"
}
```
**Streaming** (SSE):
```bash
curl -N -X POST http://localhost:8080/api/v1/chat \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{"message": "What is on my todo list?"}'
```
Each SSE event is a JSON object with a `type` field:
| Event type | Description |
|------------|-------------|
| `reasoning` | Model thinking/reasoning tokens |
| `assistant` | Response text (may arrive in multiple chunks) |
| `tool_call` | Agent is calling a tool (`toolName`, `toolCallId`) |
| `tool_result` | Tool execution result (`content`, `isError`) |
| `result` | End of stream (`success`, optional `error`) |
Example stream:
```
data: {"type":"reasoning","content":"Let me check..."}
data: {"type":"assistant","content":"Here are your "}
data: {"type":"assistant","content":"current tasks."}
data: {"type":"result","success":true}
```
**Request fields:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `message` | string | Yes | The message to send to the agent |
| `agent` | string | No | Agent name (defaults to first configured agent) |
**Authentication:** All requests require the `X-Api-Key` header. The API key is auto-generated on first run and saved to `lettabot-api.json`, or set via `LETTABOT_API_KEY` env var.
**Multi-agent:** In multi-agent configs, use the `agent` field to target a specific agent by name. Omit it to use the first agent. A 404 is returned if the agent name doesn't match any configured agent.
## Environment Variables
Environment variables override config file values: