Skip to content

sync wire fix (bare array + string delivery_id), WS delivery acks, dedup, terminal closes — 1.0.31#1

Merged
sanctrl merged 1 commit into
mainfrom
fix/sync-wire-ack
Jul 18, 2026
Merged

sync wire fix (bare array + string delivery_id), WS delivery acks, dedup, terminal closes — 1.0.31#1
sanctrl merged 1 commit into
mainfrom
fix/sync-wire-ack

Conversation

@sanctrl

@sanctrl sanctrl commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What

Python mirror of agentchat-typescript#1. The /v1/messages/sync drain read batch.get('envelopes') off what production actually sends (a bare JSON array) and gated delivery ids on isinstance(int) against string del_ cursors — every offline drain silently returned zero rows and never acked. The 1.0.3 release was the directory-auth change only; this path was never fixed until now.

Changes

  • sync()list[SyncRow] (TypedDict, unknown fields pass through); sync_ack(str){'acked': int}; last_sync_delivery_id() helper
  • Drain rebuilt: cursor pagination, positional ack of the settled prefix, clean-prefix stop on invalid rows, no-progress guard, errors via on_error — the silent failure mode is structurally impossible now
  • Capability-negotiated WS acks per server docs/realtime-delivery-ack.md: dormant unless hello.ok echoes the capability; ack only after handlers settle; exception ⇒ no ack ⇒ redelivery
  • Bounded message-id dedup (default 2048) across live+drain
  • Close codes 1008/4401/4403 terminal (client's own HELLO-timeout 1008 self-close exempt, test-locked)
  • Paginator audit vs live routes: contacts/agents keys match — no drift; nothing reads items
  • New wire-contract suite incl. a true end-to-end drain over a respx-mocked wire asserting the exact ack body

Verification

  • ruff clean, mypy strict clean, pytest: 136 passed / 1 skipped (live-gated) — the exact CI gate trio
  • Version 1.0.31 (pyproject + _version.py, consistency now test-enforced)

Release

Not published. Follow-up after release: raise agentchat-hermes' SDK floor so the plugin picks up the fixed drain.

…dup, terminal closes — 1.0.31

Python mirror of the TS SDK 1.0.21 fix. The /v1/messages/sync drain read
batch.get('envelopes') off what production actually sends (a bare JSON
array) and gated delivery ids on isinstance(int) against string del_
cursors — so every offline drain silently returned zero rows and never
acked. The 1.0.3 release was the directory-auth change only; this path
was never fixed until now.

- sync() -> list[SyncRow] (TypedDict, unknown fields pass through);
  sync_ack(str) -> {'acked': int}; last_sync_delivery_id() helper
- drain: cursor pagination, positional ack of the settled prefix,
  clean-prefix stop on invalid rows, no-progress guard, errors via
  on_error (never silent)
- WS delivery acks per docs/realtime-delivery-ack.md: HELLO advertises
  ['ack'], dormant unless hello.ok echoes it; ack only after handlers
  settle; exception -> no ack -> redelivery
- bounded message-id dedup (default 2048) across live+drain
- close codes 1008/4401/4403 terminal (self HELLO-timeout 1008 exempt)
- paginator audit vs live routes: contacts/agents keys match, no drift
- new wire-contract test suite incl. end-to-end drain over respx mock

ruff + mypy strict + pytest: 136 passed, 1 skipped (live-gated).
@sanctrl
sanctrl merged commit 4cd0c66 into main Jul 18, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant