Edges, ingress, and clients
Connect an agent to chat, the web, other agents, or scheduled triggers. Each edge adapts its client protocol to the public API.
An edge is an adapter that connects a client to the public API. It translates messages, authenticates callers, and renders replies for that client.
The public API
Every edge calls the same surface: a streaming Connect RPC, plus a chat-completions-compatible POST /v1/chat/completions route. Compatible clients can use the HTTP route with the required authentication and conversation settings. Both protocols call the same turn handler.
- Stable conversation ids. Each edge derives an id from its native conversation coordinates. Chat edges hash those coordinates into a UUIDv5, so identifiers such as phone numbers do not appear in the conversation id. Other callers can use a namespaced id through the shared SDK.
- Streaming, approvals, and handoffs are documented extensions over the base chat schema. They map onto event kinds the log already persists, so clients receive pending approvals and agent handoffs in the response.
| Edge | Example conversation id |
|---|---|
| UUIDv5 of the business phone number id and sender WhatsApp id | |
| MCP | mcp:caller |
| Web | web:uuid |
The adapter contract
The Rust EdgeAdapter trait defines identity and input conversion methods. The shared SDK provides response handling and approval support. Each edge authenticates callers using its transport's authentication mechanism.
| Concern | Implementation |
|---|---|
| Identity and namespacing | trait method conversation_id / namespace |
| Ingress | trait method to_turn_input (native event → turn messages) |
| Egress / streaming | SDK-composed: render the turn-event stream |
| Approval and handoff | SDK-composed: react to approval / handoff events; answer via the approval client |
| Auth and trust boundary | edge-native: authenticate the caller at the edge transport |
Use the reference chat edge as an implementation example. The CLI uses the same SDK.
Edges by interaction pattern
An edge's interaction pattern determines how it receives messages, returns replies, and preserves conversation history.
| Pattern | What it is | Supported interaction |
|---|---|---|
| Chat | Direct or thread-based conversations with human approval | Receive messages and return replies on chat platforms |
| Embedded | The chat-completions HTTP route with a UI on top | Render public API responses in an application |
| Threads | Long-lived, reply-driven (email and open standards) | Preserve multi-day threads and accept approval replies |
| Events | Triggered by issues, change-requests, and mentions | Record incoming events and resulting turns in a signed, replayable log |
| Agent-to-agent | Expose Polychrome conversations through the A2A JSON-RPC API | Let another agent invoke an isolated conversation and inspect its recorded results |
| Triggers | cron, queues, webhooks, filesystem events | Isolate unattended runs and record their results for replay |
What each edge can do today
Edges implement different parts of the contract. The table lists available capabilities and remaining limitations.
| Edge | Turns | Approvals | Deployable | Attribution | Streaming |
|---|---|---|---|---|---|
| Chat (Slack) | Available | Available | Available | Available | Available |
| Chat (Telegram) | Available | Available | Available | Available | Available |
| Chat (WhatsApp) | Available | Available | Available | Available | Not available |
| Trigger | Available | Not available | Available | Partial | Not available |
| Agent-to-agent | Available | Available | Partial | Partial | Available |
- Chat (Slack)
- The reference implementation.
- Chat (WhatsApp)
- One-to-one business chat. Aggregated replies; Approve, Deny, and Deny & stop buttons. No remembered approval or in-chat question answers.
- Trigger
- Queue, webhook, and filesystem sources.
- Agent-to-agent
- Peers use distinct bearer credentials; turns do not assert a human caller.
The polyc-whatsapp crate builds polychrome-whatsapp, a WhatsApp Business Cloud API edge. It accepts one-to-one text messages, attributes the sender, and sends the completed reply back to the chat. It consumes the control plane's event stream but does not stream partial text to WhatsApp. Group chats, threads, and media input are not supported by this receiver.
Configure Meta's callback URL to reach /whatsapp/webhook. The GET subscription handshake checks the configured verify token. POST deliveries must carry a valid X-Hub-Signature-256 HMAC over the raw body, using the Meta app secret. The edge separately authenticates to the control plane with its edge bearer credential and signed attribution envelope.
Conversation ids are UUIDv5 hashes of (phone_number_id, wa_id). Each person has one conversation per business number. Caller identity uses provider whatsapp, business phone number id as scope, and the sender's WhatsApp id as the external identifier. The conversation is marked direct. Account linking accepts a six-digit code or a deep-link token issued on another surface before the message reaches the model.
Pending tool approvals use three reply buttons: Approve, Deny, and Deny & stop. This edge does not offer “approve and remember,” admin-invite acceptance, or answers to ask_question prompts. Question prompts direct the reader to another surface.
The receiver enforces a 24-hour window after the user's last inbound message for free-form sends. Outside that window it sends a configured approved template; without a template, it refuses the send and records the failure. Template body variables come from configuration, not from the paused turn. This also matters for delayed approvals and notifications: an active agent does not guarantee a message can be delivered to WhatsApp. See configuration and deployment.