DEV Community

Make Long-Running Agent Events Monotonic Before Making Them Real-Time

Make Long-Running Agent Events Monotonic Before Making Them Real-Time

Real-time delivery does not guarantee a correct timeline. WebSockets reconnect. Brokers redeliver. Workers race with cancellation. A client may receive event 42, then 40, then a snapshot generated after 45. For long-running agent tasks, define convergence before optimizing animation latency.

Give each operation an ordered log type:

type OperationEvent = {
  operationId: string;
  sequence: number;
  eventId: string;
  type: "accepted" | "started" | "progress" | "needs_input" | "completed" | "failed" | "cancelled";
  occurredAt: string;
  payload: unknown;
};

The producer allocates a strictly increasing sequence per operation in the same durable transaction that appends the event. eventId deduplicates delivery; sequence detects order and gaps. Wall-clock timestamps are for display and diagnosis, not ordering.

Consumer Rules

  • sequence <= applied_sequence โ†’ ignore duplicate or stale event
  • sequence == applied_sequence + 1 โ†’ apply and advance
  • sequence > applied_sequence + 1 โ†’ buffer briefly and request replay

Terminal State Invariant

After completed, failed, or cancelled, later non-audit state transitions are rejected. Cancellation is a request until the authoritative terminal event is committed.

Reconnect with Snapshots Plus Replay

Return a snapshot containing operationId, materialized state, and throughSequence. Then replay events beginning at throughSequence + 1. The server must create the snapshot from a consistent log position; otherwise the client can miss the gap between two independent reads.

Compact old progress events only after a snapshot is durable and consumers no longer need them for audit. Retain terminal and authority-changing events according to policy.

Test Scenarios

Inject:

  • Duplicate delivery
  • Reordering
  • A missing sequence
  • Reconnect during snapshot
  • Worker death after a side effect but before event commit
  • Cancellation racing with completion
  • Two clients reconnecting at different offsets

Validation Properties

  • Every client eventually reaches the authoritative terminal state
  • Each side effect has an idempotency key independent of delivery attempts
  • No client applies the same event twice
  • Gaps become observable rather than silently skipped
  • Late progress cannot reopen a terminal task

The public MonkeyCode repository describes long-running AI tasks, managed environments, and synchronized PC/mobile workflows. Those capabilities make ordered recovery a relevant evaluation question, but this article does not claim that MonkeyCode uses this schema or report a reliability test.

Disclosure: I contribute to the MonkeyCode project. Product context is based on public documentation; the protocol is an independent reference design.

Real-time is a transport property. Correct recovery is a system property. Build the second one first.

Comments

No comments yet. Start the discussion.