Protocol — open-wire / 1

Every message between Open-Wire and an agent is a JSON envelope with protocol: "open-wire/1".

Inbound (channel → agent)

When Slack delivers an event, Open-Wire POSTs this to the installation webhook_url:

{
  "protocol": "open-wire/1",
  "type": "message.inbound",
  "id": "msg_…",
  "channel": "slack",
  "installation_id": "inst_…",
  "thread": { "id": "C123:1710000000.000100" },
  "from": { "id": "U123", "kind": "user" },
  "to": { "id": "C123", "kind": "channel" },
  "body": { "text": "hello" },
  "created_at": "2026-07-30T00:00:00.000Z"
}

Headers: X-Open-Wire-Protocol, X-Open-Wire-Installation, optional X-Open-Wire-Secret.

Outbound (agent → channel)

Agents (or Rails Agent Cloud) call POST /api/v1/messages:

{
  "protocol": "open-wire/1",
  "type": "message.send",
  "installation_id": "inst_…",
  "to": { "id": "C123", "kind": "channel" },
  "thread": { "id": "C123:1710000000.000100" },
  "body": { "text": "hi from the agent", "blocks": null }
}

Identity fields

  • installation_id — which workspace / grant to use
  • thread.id — provider thread key (Slack: channel:ts)
  • channel — adapter name (slack, …)

Rails Agent reverse path

Rails Agent depends on the open-wire Ruby gem (path-sourced until RubyGems publish). Inbound webhooks hit the existing engine — no second mount:

POST /agents/open_wire/inbound/:agent_slug
Headers: X-Open-Wire-Secret, X-Open-Wire-Protocol, X-Open-Wire-Installation

Cloud Connect uses /api/v1/agents/:id/open-wire/inbound which verifies the secret, starts/resumes an agent run, and replies on the same thread.