fix(dingtalk): add AI Card QPS token-bucket throttle#17365
Conversation
DingTalk's interactive-card PUT API enforces ~20 QPS per tenant; exceeding it returns 403 and drops the card update. - Add _CardTokenBucket — async token-bucket rate limiter (20 QPS) with automatic 2s exponential backoff on 403 responses - Add per-card 800ms minimum interval between non-finalize edits (matches openclaw-connector reply-dispatcher.ts:103) - Per-chat error-send cooldown (60s) to avoid spamming users - Finalize edits are NEVER throttled — dropping them would leave the card stuck in streaming state - Global bucket shared across all adapters in the process to #
|
Hi @alt-glitch, thanks for the review and labels! 🙏 You're right — this PR extracts the card QPS throttle component from #14333. To clarify: @PeterGuy326 and @spike2204 are from the same team — the DingTalk (钉钉) Open Platform team at Alibaba. We're the team that builds and maintains the DingTalk stream SDK, AI Card APIs, and Robot OpenAPI that this adapter integrates with. The original #14333 bundled three independent fixes (websockets proxy + card QPS + inbound queue) into a single stacked PR. We've re-submitted them as 3 separate, self-contained PRs (#17364, #17365, #17366) against About this specific fix: The 50 QPS limit on AI Card streaming APIs is an actual platform-enforced rate limit. We've observed HTTP 429 storms in production when 10+ concurrent conversations update cards simultaneously. The token-bucket approach here mirrors what we recommend in our own DingTalk AI Card best practices documentation. Happy to address any feedback — the original #14333 can be closed once these granular PRs are reviewed. 🚀 |
|
The Only at umbrella https://github.com/NousResearch/hermes-agent/pull/12769/changes#diff-5dca76751f29bee741c70b70ed7d84c9040b69771464c4f093596d88af680e35R159 or stacked PR https://github.com/NousResearch/hermes-agent/pull/14333/changes#diff-5dca76751f29bee741c70b70ed7d84c9040b69771464c4f093596d88af680e35R158 |
|
And |
Summary
DingTalk's AI Card streaming API enforces a 50 QPS limit per robot. Without client-side throttling, bursts of concurrent conversations trigger HTTP 429 errors that abort card updates mid-stream.
Changes
_CardTokenBucketclass — async token-bucket rate limiter with configurable QPS, burst capacity, and max wait timeout_CARD_BUCKETshared across all adapter instances_card_create,_card_update,_card_closecall withawait _CARD_BUCKET.acquire()Related
Part of the DingTalk adapter enhancement series — see #12769 for the umbrella PR.