Skip to content

fix(dingtalk): add AI Card QPS token-bucket throttle#17365

Open
spike2204 wants to merge 1 commit into
NousResearch:mainfrom
spike2204:fix/dingtalk-card-qps-throttle
Open

fix(dingtalk): add AI Card QPS token-bucket throttle#17365
spike2204 wants to merge 1 commit into
NousResearch:mainfrom
spike2204:fix/dingtalk-card-qps-throttle

Conversation

@spike2204

Copy link
Copy Markdown

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

  • Add _CardTokenBucket class — async token-bucket rate limiter with configurable QPS, burst capacity, and max wait timeout
  • Instantiate process-wide _CARD_BUCKET shared across all adapter instances
  • Guard every _card_create, _card_update, _card_close call with await _CARD_BUCKET.acquire()

Related

Part of the DingTalk adapter enhancement series — see #12769 for the umbrella PR.

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 #
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/dingtalk DingTalk adapter labels Apr 29, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Overlaps with the card QPS throttle component of #14333. Part of umbrella #12769.

@spike2204

Copy link
Copy Markdown
Author

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 main so each can be reviewed and merged independently.

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. 🚀

@Librazy

Librazy commented May 11, 2026

Copy link
Copy Markdown

@Librazy

Librazy commented May 11, 2026

Copy link
Copy Markdown

And _CARD_BUCKET and all throttle related codes are missing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/dingtalk DingTalk adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants