* feat: Implement workflow form handling for paused workflows
- Added module-level storage for pending forms to manage state across sessions.
- Introduced functions to set, get, and clear pending forms with expiration handling.
- Enhanced DifyServiceAPIRunner to support resuming paused workflows via form actions.
- Implemented logic to yield human input requests and display appropriate messages.
- Updated workflow submission methods to handle paused states and resume actions.
- Ensured proper merging of pending form actions with user inputs for seamless interaction.
* feat: Add '_routed_by_rule' variable to form action in Lark and Telegram adapters
* feat: Enhance Lark and Telegram adapters with new form handling for paused workflows
* feat: Enhance TelegramAdapter to handle form action buttons and message threading
* feat: Improve TelegramAdapter message handling with enhanced error management and draft message support
* feat: Add the function for formatting human input text to support adapters without rich UI.
* feat(dingtalk): implement human input card support and card action handling
- Add a new module `card_callback.py` to handle card action button clicks from DingTalk.
- Introduce `DingTalkCardActionHandler` to process card action callbacks and extract parameters.
- Update `DingTalkAdapter` to manage card state and handle form input through a single card template.
- Add configuration for `human_input_card_template_id` in `dingtalk.yaml` to specify the template for human input.
- Create a new card template `dingtalk_human_input_card.json` for rendering human input prompts and buttons.
* feat(dingtalk): enhance human input card functionality with streaming support and active turn management
- Updated the DingTalk card template to enable streaming mode and multi-update configuration.
- Removed the obsolete delete_card method from DingTalkClient to streamline card management.
- Enhanced DingTalkAdapter to manage active turn cards and accumulated streaming text, ensuring a seamless user experience during human input prompts.
- Modified the create_message_card method to utilize existing active cards for resumed workflows, preventing duplication.
- Improved the _paint_form_on_card method to update existing cards with human input prompts and buttons dynamically.
- Updated the dingtalk_human_input_card.json template to reflect the new streaming capabilities and configuration options.
* feat(wecom): implement Dify human input pause handling with button interaction support
* feat(qqofficial): implement Dify human input button interaction handling and markdown keyboard support
* feat(qqofficial): implement one-click QR binding and enhance localization support
* feat(discord): implement Discord form view with button interactions for Dify actions
* fix(telegram): correct group chat type check and handle oversized callback data for Telegram actions
fix(difysvapi): ensure safe access to remove-think configuration in pipeline settings
* feat(dify): add support for chatflow app type and enhance human input handling
* feat(telegram): add action title feedback for user selections in Telegram messages
* feat(lark): enhance LarkAdapter to store form content for resume notices
* feat(dingtalk): update display formatting for card content with HTML line breaks
* feat(dingtalk): add feedback functionality to cards with 👍/👎 buttons
- Implemented feedback state management for cards, allowing users to provide feedback via thumbs up/down buttons.
- Enhanced card rendering to include feedback buttons when appropriate.
- Registered feedback listeners to handle feedback events and update card states accordingly.
- Updated the card template to support dynamic button rendering for feedback actions.
- Improved error handling and logging for feedback actions and card updates.
* fix: add Avatar component to dingtalk_human_input_card.json for enhanced user interaction
* feat(wecom): add optional source block to interactive template cards for enhanced branding
* feat(wecom): add functions for template card action extraction and update, enhance button interaction handling
* feat(qqofficial): synchronize passive-reply counter with inbound message sequence
* feat(qqofficial): add method to identify invisible form placeholder chunks in messages
* feat(dingtalk): add download link for human input card template and enhance dynamic form configuration
* feat(telegram): enhance message handling with group stream deletion and form placeholder detection
* Add unit tests for DingTalk, Lark, WeComBot, and Dify service API runners
- Implement tests for DingTalk adapter helper functions including form content cleaning, input extraction, and completed input lines.
- Create unit tests for Lark adapter helper functions focusing on input extraction and completed input lines.
- Add tests for WeComBot template card functionalities, including event extraction and payload building for human input.
- Enhance Dify service API runner tests to cover human input forms, including input collection, action handling, and form snapshot extraction.
* feat: Enhance Telegram and QQ Official adapters with select field handling and form action processing
- Added support for select fields in Telegram adapter, including option extraction and callback handling.
- Implemented form action processing for Telegram callbacks, improving user interaction feedback.
- Introduced new helper functions for building keyboards and resolving select button actions in QQ Official adapter.
- Enhanced DifyServiceAPIRunner to handle cumulative streaming responses and improve error handling during workflow resumes.
- Added unit tests for new functionalities in Telegram and QQ Official adapters, ensuring robust behavior for select fields and form actions.
* feat(lark): add functions for current input definitions and visible form content handling
feat(qqofficial): update fallback text handling for non-streaming scenarios
feat(difysvapi): enhance form content processing for interactive fields and actions
test: add unit tests for Lark and QQ Official adapter functionalities
* Add tests for DingTalk adapter content processing and markdown formatting
- Updated the assertion in `test_dingtalk_completed_input_lines_include_text_and_select_values` to remove unnecessary markdown formatting.
- Added new tests to verify that `_dingtalk_clean_form_content` maintains the order of prompts and completed values in various scenarios.
- Introduced `test_dingtalk_card_markdown_preserves_internal_line_breaks` to ensure internal line breaks are correctly converted to HTML line breaks.
* feat: Refactor input handling and feedback messages across multiple adapters
* feat: Update the human-computer interaction template cards, and optimize the prompt information and content display.
* feat: Refactor pending form handling to isolate by bot and pipeline
* feat: Enhance error handling and caching for Dify and WeCom interactions
* feat: Enhance select input handling and validation in Dify API runner and Telegram adapter
* feat: Add missing completed input lines handling in DingTalk adapter
* feat: Add pipeline_uuid handling across multiple adapters and update related tests
* feat(box): bidirectional attachment transfer for sandbox
Materialize inbound attachments into the sandbox workspace so agents can
process user-sent files, and collect agent-produced files from the outbox
to attach them back to the reply.
- box(service): add materialize_inbound_attachments / collect_outbound
attachments. Prefer direct host-filesystem read/write on the bind-mounted
workspace (no size limit), falling back to chunked exec only for
non-shared backends (e2b/remote). Clear per-query inbox/outbox dirs at
turn start to avoid query_id-reuse collisions.
- provider(localagent): inject inbound attachment descriptors into the
sandbox and append a system note telling the agent the inbox/outbox paths.
- pipeline(wrapper): collect outbox files on the final stream chunk and
append them as attachment components to the response chain.
- web(debug-dialog): render File components with a download link when
base64/url is present; add base64/path fields to the File entity.
- tests: cover inbound/outbound, large-file transfer without truncation,
and stale-dir clearing (86 passing).
* feat(box): support voice/file attachment round-trip end-to-end
Extends the bidirectional attachment transfer to audio and arbitrary files
through the real webchat UI, and fixes the model-payload errors that
non-image attachments triggered.
- platform(websocket_adapter): resolve Voice/File component storage keys to
base64 (previously only Image), so audio/documents reach the sandbox inbox.
- web(debug-dialog): accept audio/* and any file in the uploader (was
image-only), classify by mimetype, upload Voice/File via the documents
endpoint, and render non-image staged attachments as a chip.
- provider(litellmchat): drop non-image file parts (file_base64 / file_url)
when building the OpenAI/LiteLLM payload. These come from Voice/File
attachments — including ones replayed from conversation history — and the
agent reads their bytes from the sandbox, not the model. Without this the
provider rejects the request: 'invalid content type=file_base64'.
- provider(localagent): also strip those parts from the current user message
alongside the sandbox-path note (model-facing clarity; the requester is the
real safety net for history).
- tests: cover the requester strip/keep behavior (file dropped, image kept and
reshaped to image_url, mixed history, plain-string content).
* test(box): cover inbound/outbound attachment helpers; fix ruff format
- ruff format localagent.py (CI ruff format --check was failing)
- add unit tests for ResponseWrapper outbound-attachment helpers (wrapper.py 78%->98%)
- add unit tests for LocalAgentRunner._inject_inbound_attachments
- add unit tests for WebSocketAdapter._process_image_components (0%->covered)
Lifts PR patch coverage from 68.97% to ~88% (>75% target).
* refactor: pipeline routing rules - add routed_by_rule bypass and diagnostic logging
- Add routing rules editor (RoutingRulesEditor component)
- Add routed_by_rule bypass logic in response rules
- Add diagnostic logging for pipeline routing
- Database migration for bot pipeline routing rules
- Extract RoutingRulesEditor component from BotForm
- Revert log levels to debug
* feat: add message_has_element routing rule type
Support routing by message element type (Image, Voice, File, Forward,
Face, At, AtAll, Quote) with eq/neq operators.
* test: add unit tests for pipeline routing rules
20 tests covering _match_operator (eq/neq/contains/not_contains/
starts_with/regex/invalid) and resolve_pipeline_uuid (launcher_type/
launcher_id/message_content/message_has_element/first-match-wins/
skip-invalid/default-operator).
* fix(web): add missing 'message_has_element' to routing rule type validation
The Zod schema and TypeScript type for PipelineRoutingRule.type were
missing the 'message_has_element' variant, causing silent form validation
failure when saving routing rules with this type.
* feat: add pipeline discard functionality and localization support
* feat(web): improve drag-and-drop with DragOverlay, add discard monitoring and pipeline icons
- Add DragOverlay for smooth cursor-following drag in routing rules editor
- Remove transition to eliminate redundant swap animation on drop
- Record discarded messages in monitoring system via _record_discarded_message
- Display pipeline name (Workflow icon) and runner name (Play icon) on session monitor messages
- Show discard badge on discarded messages in session monitor
- Add i18n translations for discarded/userMessage/botMessage
* fix: ensure discarded messages appear in session monitor and improve icons
- Create/update monitoring session for discarded messages so they show in
the bot session monitor (was only inserting message rows, not sessions)
- Use human-readable 'Discarded' as pipeline_name instead of '__discard__'
- Change runner icon from Play to Bot for better AI Agent semantics
* fix: merge discarded messages into same session and remove session-level pipeline name
- Use LauncherTypes enum for session_id in discarded messages to match
the format used by monitoring_helper (fixes duplicate sessions)
- Don't overwrite session pipeline info on discard — a session can have
messages from multiple pipelines
- Remove pipeline_name from session list and chat header since it's
now shown per-message and a session is no longer single-pipeline
* fix(web): only show save button on config tab in bot detail page
* fix(web): scroll to bottom after messages render in session monitor
---------
Co-authored-by: RockChinQ <rockchinq@gmail.com>