Summary
Relay PR AgentWorkforce/relay#1750 is making short-lived worker exit publication durable and retryable. Relaycast currently appends a new session event for every POST /v1/agents/:name/events, so an ambiguous committed response or Relay retry creates duplicate agent_exited rows for the same worker generation.
This is the server half of the at-least-once delivery contract required by AgentWorkforce/relay#1603.
Current behavior
packages/sdk-rust/src/relay.rs sends EmitSessionEventRequest { type, payload } to POST /v1/agents/{name}/events.
packages/engine/src/routes/agent.ts accepts the request without an idempotency key.
packages/engine/src/engine/sessionEvent.ts allocates MAX(sequence) + 1 for every call.
session_events is unique only on (agent_id, sequence).
A duplicate request with the same logical agent_exited generation therefore appends another event.
Acceptance criteria
- Add an explicit stable event identity for broker-originated session events, preferably the standard
Idempotency-Key request contract scoped to workspace, agent, and payload.
- Replaying the same key and identical payload returns the original response and stores exactly one event.
- Reusing the same key with a different payload fails closed with a typed conflict.
- Preserve backward compatibility for existing callers that omit the key.
- Extend the Rust SDK so Relay can preserve one key across retries.
- Add conformance tests for committed-response loss and same-key/different-payload conflict.
- Prove the deployed engine contract with Relay #1750 before claiming durable hosted visibility.
Related
Summary
Relay PR AgentWorkforce/relay#1750 is making short-lived worker exit publication durable and retryable. Relaycast currently appends a new session event for every
POST /v1/agents/:name/events, so an ambiguous committed response or Relay retry creates duplicateagent_exitedrows for the same worker generation.This is the server half of the at-least-once delivery contract required by AgentWorkforce/relay#1603.
Current behavior
packages/sdk-rust/src/relay.rssendsEmitSessionEventRequest { type, payload }toPOST /v1/agents/{name}/events.packages/engine/src/routes/agent.tsaccepts the request without an idempotency key.packages/engine/src/engine/sessionEvent.tsallocatesMAX(sequence) + 1for every call.session_eventsis unique only on(agent_id, sequence).A duplicate request with the same logical
agent_exitedgeneration therefore appends another event.Acceptance criteria
Idempotency-Keyrequest contract scoped to workspace, agent, and payload.Related