You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The header is optional. Existing clients without Idempotency-Key continue to create a fresh run per request. Durable state is stored in owner-only runs_idempotency.db; only fingerprints, opaque auth/profile scopes, run IDs, and public statuses are persisted (not payloads or credentials).
Related Relay fix
The branch is based on current main, which already contains both 9a9b670e29f592fdf50bcca1e3e777150522b6b5 and merge commit 42708f8bb39c9c2fc19146956699699bc3ea2da5; they were not duplicated.
AI code review — automated review for reference; please use your judgment.
Solid durable-idempotency design: (scope, key) reservations inserted under BEGIN IMMEDIATE make multi-worker admission actually exclusive, fingerprints compared with hmac.compare_digest, retention is enforced lazily, WAL is applied with a labeled fallback, file permissions are tightened to 0600 including -wal/-shm, and request bodies/secrets are deliberately excluded from storage. Tests cover both lifecycle branches. Two growth concerns:
gateway/platforms/api_server.py:~1551 — self._run_idempotency_ids and _run_owners grow once per keyed run and are never pruned, even though the store's 24h retention deletes rows underneath them. On a long-lived gateway this is a slow memory leak plus stale ownership claims for runs whose rows aged out (owns_run then disagrees with the set). Mirror the store's retention: prune these structures on the same cadence or derive membership from a store query.
api_server.py:_set_run_status (~6697) — every status transition (including per-tool-event updates arriving through the SSE callback) now issues an UPDATE+commit against the idempotency DB. High-frequency tool events turn this into per-event fsyncs; consider persisting only terminal/relevant transitions and keeping intermediate states in memory, since replay consumers only need the final row after completion anyway.
The :memory: fallback silently converts durable idempotency into best-effort with no operator signal — one WARNING naming the reason (unwritable path) would explain otherwise-puzzling duplicate-run reports after a restart. (nit)
Fingerprint mismatch returning "conflict" (presumably 409) rather than replaying the other body's result is exactly right. (positive)
nit: RunIdempotencyStore.close() exists but I don't see it wired into adapter shutdown — long-lived WAL connections should be closed on teardown. (nit)
No blocking issues found beyond items 1–2's long-uptime profile.
@pesho-vsn I am using this commit as a prerequisite in draft #95965 for an end-to-end RoomLink stack. Your commit and authorship are preserved unchanged; this is not intended to replace your PR. If this lands first, I will drop the patch-identical commit from the composition.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
area/sessionsSession lifecycle, resume, persistence, historycomp/gatewayGateway runner, session dispatch, deliveryneeds-decisionAwaiting maintainer decision before any implementationP3Low — cosmetic, nice to havesweeper:risk-compatibilitySweeper risk: may break existing users, config, migrations, defaults, or upgradessweeper:risk-session-stateSweeper risk: may lose/corrupt/mis-associate session or context statetype/featureNew feature or request
4 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Idempotency-Keyreservations forPOST /v1/runs409 idempotency_key_conflictTests
uv run --extra dev --extra messaging pytest -q tests/gateway/test_api_server_runs.py --disable-warnings --maxfail=1(29 passed)uv run --extra dev ruff check gateway/platforms/api_server.py tests/gateway/test_api_server_runs.pygit diff --checkCloses #88400
Compatibility
The header is optional. Existing clients without
Idempotency-Keycontinue to create a fresh run per request. Durable state is stored in owner-onlyruns_idempotency.db; only fingerprints, opaque auth/profile scopes, run IDs, and public statuses are persisted (not payloads or credentials).Related Relay fix
The branch is based on current
main, which already contains both9a9b670e29f592fdf50bcca1e3e777150522b6b5and merge commit42708f8bb39c9c2fc19146956699699bc3ea2da5; they were not duplicated.