Skip to content

fix(dingtalk): support dingtalk-stream >= 0.20 async API and fix timeout#10153

Closed
gundamff wants to merge 1 commit into
NousResearch:mainfrom
gundamff:fix/dingtalk-async-timeout
Closed

fix(dingtalk): support dingtalk-stream >= 0.20 async API and fix timeout#10153
gundamff wants to merge 1 commit into
NousResearch:mainfrom
gundamff:fix/dingtalk-async-timeout

Conversation

@gundamff

Copy link
Copy Markdown

Summary

This PR fixes DingTalk adapter compatibility with dingtalk-stream SDK >= 0.20 and resolves timeout issues.

Changes

  • SDK Version Detection: Automatically detect SDK version using inspect.iscoroutinefunction()
  • Webhook URL Fix: Support both api.dingtalk.com and oapi.dingtalk.com in regex
  • Message Parsing: Parse CallbackMessage.data dict for SDK >= 0.20
  • Async Processing: Handle messages in background thread to avoid blocking dingtalk-stream
  • Timeout Fix: Increase timeout from 60s to 300s for AI response

Testing

Tested with:

  • DingTalk SDK 0.24.3
  • Python 3.11
  • Multi-turn conversations working correctly with fast response

Related Issues

Fixes slow response and timeout errors in DingTalk bot.

- Add SDK version detection for async/sync method compatibility using inspect.iscoroutinefunction()
- Fix webhook URL regex to support both api.dingtalk.com and oapi.dingtalk.com
- Parse CallbackMessage.data dict for SDK >= 0.20 compatibility
- Process messages in background thread to avoid blocking dingtalk-stream
- Increase timeout from 60s to 300s for AI response handling

Fixes timeout errors and improves response speed for DingTalk bot with SDK >= 0.20.
@mxnstrexgl

Copy link
Copy Markdown

REVIEW SUMMARY

APPROVE with minor suggestions.

CHANGES VERIFIED

  1. SDK VERSION DETECTION: inspect.iscoroutinefunction() runtime detection is clean
  2. WEBHOOK URL: Regex expansion to support oapi.dingtalk.com is backward compatible
  3. MESSAGE PARSING: _MsgWrapper correctly bridges CallbackMessage.data to ChatbotMessage interface
  4. ASYNC PROCESSING: Background thread prevents blocking dingtalk-stream
  5. TIMEOUT: 60s → 300s accommodates slower AI responses

SECURITY CHECKLIST

  • NO hardcoded credentials
  • Webhook URL validation preserved (_DINGTALK_WEBHOOK_RE)
  • Env var loading unchanged
  • SSRF protection on session_webhook

QUALITY OBSERVATIONS

GOOD:

  • Runtime SDK detection avoids hard version checks
  • Method binding at module load is clean pattern
  • daemon=True threads prevent zombie processes
  • Exception handling in _dispatch_message catches errors gracefully

SUGGESTIONS:

  1. THREAD POOLING: Creating thread-per-message under high load could be expensive. Consider concurrent.futures.ThreadPoolExecutor:
# In __init__
self._thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10)

# In _dispatch_message
def handle_message(): ...
self._thread_pool.submit(handle_message)
  1. RACE CONDITION: _session_webhooks eviction logic is not atomic. Multiple threads could race on pop():
# Consider threading.Lock for eviction or use dict pop with sentinel
with self._webhook_lock:
    if len(self._session_webhooks) >= _SESSION_WEBHOOKS_MAX:
        self._session_webhooks.pop(next(iter(self._session_webhooks)))
  1. JSON PARSING: _parse_callback_data uses json.loads() on string data without size limit. Consider adding a max size check to prevent memory issues from malicious payloads.

NITPICKS

  • Line 334: json import inside method - move to top-level since already imported
  • types.SimpleNamespace could replace _MsgWrapper class for cleaner code

TESTING

Existing tests pass. Recommend adding test for _parse_callback_data with SDK >= 0.20 mock data.

Overall solid fix for dingtalk-stream compatibility issues.

@teknium1

Copy link
Copy Markdown
Contributor

Closing as superseded by #11471 (#11471) which salvaged @kevinskysunny's minimal fix (#11257) and added a follow-up for the broken _extract_text() path found during E2E testing.

Thanks for the fix — a lot of contributors hit this SDK break at the same time. Your investigation helped confirm the root cause.

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.

3 participants