feat(delivery): relaycast target — agents reply over the relay (#254 pt.1)

Merged
KH
4mo ago
+273-8

First piece of #254 (platform-level relay reply). Makes @agentworkforce/delivery able to reply over the relay, so agent-to-agent chat works without per-persona code.

What

  • Adds relaycast as a first-class delivery target next to slack/telegram. The existing "reply to origin transport" pattern (hn-monitor, inbox-buddy, joke-bot) now covers relay automatically.
  • Event-driven, not config-driven: slack/telegram come from persona inputs (SLACK_CHANNEL/TELEGRAM_CHAT); the relaycast reply address is the inbound message's sender, passed via transports.relaycast = { to, sender? }. resolveDeliveryTargets(ctx) stays slack/telegram-only, so existing callers are unchanged — relaycast only becomes a target when an address is supplied.
  • Default sender DMs the peer via POST /v1/dm with the box's injected RELAY_API_KEY (never throws — {ok:false} + log on failure).

Base URL — easy to change (per the cutover to cast.agentrelay.com)

Single source of truth in relaycast.ts:

export const DEFAULT_RELAYCAST_URL = 'https://cast.agentrelay.com';
// resolveRelaycastUrl(): RELAYCAST_URL > RELAY_BASE_URL > default

Change one constant (or set one env var) to move the gateway. Default is now cast.agentrelay.com.

Files

  • types.ts — RelaycastRef, RelaycastSender, RelaycastTarget, DeliveryProvider; widened MessageRef / DeliveryClient.targets / onlyTargets.
  • relaycast.ts (new) — DEFAULT_RELAYCAST_URL, resolveRelaycastUrl, defaultRelaycastSender.
  • delivery.ts — relaycast target wiring + sendRelaycast.
  • relaycast.test.ts (new) — URL precedence + relaycast delivery path. 6/6 green, typecheck clean.

Not in this PR (tracked in #254)

  • runtime ctx.relay.reply() + surface the inbound sender on the relay event (so callers can populate to ergonomically)
  • cloud: default inbox_selectors to ['@self'] (relay-on by default)
  • publish @agentworkforce/delivery, consume in the agents repo, drop hn-monitor's slack-only relay fallback

Open question (flag for #254 acceptance)

The cloud-minted workspace key currently authenticates on api.relaycast.dev, while this PR defaults to cast.agentrelay.com and cloud infra injects gateway.relaycast.dev. The env override makes this configurable, but we should converge the box's injected base URL + key onto one gateway before the round-trip works in prod.

Refs #254

🤖 Generated with Claude Code