Edges, ingress, and clients
Your agent should meet people where they already are — chat, email, the web, even another agent — without a bespoke integration for each. Every surface is an edge: a thin adapter over one documented API, so adding one never touches the orchestration core.
An edge is any surface a conversation arrives through: chat, web, email, a cron trigger, or another agent. Polychrome invests in interaction patterns and one contract, not in vendor products — each vendor is a thin adapter that slots into one pattern row below. See the design doc and issue #31.
The public API
Every edge calls the same surface: a streaming Connect RPC, plus a chat-completions-compatible POST /v1/chat/completions route. Existing tooling can reach a turn by changing only its base URL. The route is a thin byte-level shim in front of the same handler — not a second orchestration path.
- Namespaced conversation ids. The caller supplies the id as
{namespace}:{native-id}. The id partitions the event log, and the shared format keeps every edge deriving ids the same way. - Streaming, approvals, and handoffs are documented extensions over the base chat schema. They map onto event kinds the log already persists, so a paused approval or a handoff to another agent shows up on the wire instead of going silent.
| Edge | Example conversation id |
|---|---|
| Slack | slack:T…:C… |
| MCP | mcp:caller |
| Web | web:uuid |
The adapter contract
A small Rust EdgeAdapter trait names the decisions that change from edge to edge, so surfaces stay interchangeable. Two concerns are pure mappings and become the trait's methods. The other three come from the shared edge SDK and work identically on every edge.
| Concern | How the contract carries it |
|---|---|
| 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 dialer |
| Auth and trust boundary | edge-native: authenticate the caller at the edge transport |
The reference edge is the worked example, and the operator CLI uses the same SDK. Any adapter that satisfies the contract works, regardless of the protocol it wraps.
Edges by interaction pattern
The patterns below classify edges by how a conversation behaves: how messages arrive, how replies flow back, and what durability the exchange needs. That behavior is what shapes an adapter.
| Pattern | What it is | Why it matters |
|---|---|---|
| Chat | Thread-based, human-in-the-loop request/response | Table-stakes distribution; one shape covers many platforms |
| Embedded | The chat-completions HTTP route with a UI on top | Commercially expected; a renderer over the public API |
| Threads | Long-lived, reply-driven (email and open standards) | Multi-day threads → durable log; approval-by-reply → HITL pause |
| Events | Triggered by issues, change-requests, and mentions | Provenance made concrete: a signed, replayable record of what changed and why |
| Multiplayer | Expose a Polychrome conversation as an MCP server | Be the durable, isolated, audited execution layer inside other agents |
| Triggers | cron, queues, webhooks, filesystem events | Per-conversation isolation + replay matter most for unattended runs |