Skip to content

feat: support DingTalk streaming AI cards#8890

Open
Accenemy wants to merge 1 commit into
AstrBotDevs:masterfrom
Accenemy:fix/dingtalk-stream-card
Open

feat: support DingTalk streaming AI cards#8890
Accenemy wants to merge 1 commit into
AstrBotDevs:masterfrom
Accenemy:fix/dingtalk-stream-card

Conversation

@Accenemy

@Accenemy Accenemy commented Jun 19, 2026

Copy link
Copy Markdown

中文说明

这个 PR 为 AstrBot 内置钉钉平台适配器增加原生“互动 AI 卡片流式回复”支持。

目前 WebUI 里的钉钉设置已经有 card_template_id 配置项,并提示“启用后将使用互动卡片进行流式回复”,但实际 DingtalkMessageEvent.send_streaming() 仍然会把模型输出缓冲到结束后再作为普通消息发送。用户在钉钉里提问后需要等待完整生成结束才看到回复,体验上不是流式输出。

本 PR 基于已经在外部插件中验证通过的适配逻辑迁移到官方钉钉 adapter:填写钉钉互动卡片模板 ID 后,流式回复会创建钉钉 AI 卡片,并把模型生成的文本持续更新到卡片内容变量中;未配置模板或创建卡片失败时,会自动回退到原来的普通消息发送方式。

改动内容

  • 使用现有 card_template_id 作为钉钉流式卡片开关。
  • 通过 dingtalk_stream.AICardReplier 创建并投递钉钉互动 AI 卡片。
  • 将流式生成的纯文本内容按间隔更新到卡片中。
  • 新增可选配置 card_content_key,用于指定卡片模板中的内容变量名,默认 content
  • 新增可选配置 card_update_interval,用于控制卡片更新最小间隔,默认 0.35 秒。
  • 未配置模板、缺少原始钉钉消息或卡片创建失败时,自动回退到原来的缓冲普通消息。
  • 对非纯文本消息段保留原有普通消息发送路径。
  • 在流式生成异常或取消时,也会尝试发送最终卡片状态并清理卡片会话,避免会话残留。

验证情况

  • 已执行 git diff --check
  • 已基于同一套 adapter 逻辑,通过外部插件在 Docker Compose 部署的 AstrBot v4.25.5 中完成实际验证:钉钉平台填写 card_template_id,卡片内容变量为 content,开启流式输出后可以正常以互动 AI 卡片形式流式更新。

本地环境的 python3 是 3.9.6,而当前项目要求 Python >=3.12,因此没有在本地运行 Python 语法检查或完整测试。

English Summary

This PR adds native DingTalk interactive AI card streaming support to the built-in DingTalk platform adapter. When card_template_id is configured, streaming text chunks are delivered through a DingTalk AI card via dingtalk_stream.AICardReplier; otherwise the adapter falls back to the existing buffered normal-message behavior.

Summary by Sourcery

Add native streaming reply support for DingTalk using interactive AI cards, with configurable card content field and update interval, while preserving fallback to buffered plain messages.

New Features:

  • Stream model responses to DingTalk as interactive AI cards when a card template ID is configured.
  • Allow configuring the content variable key used in the DingTalk card template for streaming text.
  • Allow configuring the minimum interval between DingTalk AI card content updates.

Enhancements:

  • Introduce a safe float parsing helper for DingTalk platform configuration values.
  • Ensure non-text segments in streaming responses continue to be sent via the existing plain message path.
  • Clean up DingTalk AI card sessions on completion or failure to avoid stale state.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for DingTalk streaming interactive cards by adding configuration options, implementing card creation and update methods in the DingTalk adapter, and updating the event handler to stream message updates. The review feedback highlights a potential memory leak if the streaming generator raises an exception, which can be resolved by wrapping the loop in a try...finally block, and a bug where a configured update interval of 0.0 is overridden due to a falsy check.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread astrbot/core/platform/sources/dingtalk/dingtalk_event.py
@Accenemy Accenemy force-pushed the fix/dingtalk-stream-card branch from 11b0ca7 to 9b36e52 Compare June 19, 2026 05:16
@Accenemy Accenemy marked this pull request as ready for review June 19, 2026 05:21
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. labels Jun 19, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In DingtalkMessageEvent._send_streaming_as_plain_text, the previous call to super().send_streaming(...) has been removed and the use_fallback parameter is now ignored; if you intended to preserve the base-class streaming/fallback behavior, consider still delegating to super() after buffering or dropping the unused parameter.
  • The card streaming path repeatedly sends the full accumulated full_content on each update; if payload size or rate limits become a concern, consider tracking and sending only the newly appended text (e.g., via a diff or slice) instead of the entire history each time.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `DingtalkMessageEvent._send_streaming_as_plain_text`, the previous call to `super().send_streaming(...)` has been removed and the `use_fallback` parameter is now ignored; if you intended to preserve the base-class streaming/fallback behavior, consider still delegating to `super()` after buffering or dropping the unused parameter.
- The card streaming path repeatedly sends the full accumulated `full_content` on each update; if payload size or rate limits become a concern, consider tracking and sending only the newly appended text (e.g., via a diff or slice) instead of the entire history each time.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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

Labels

area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant