Files
LangBot/web/src/app/infra/entities/form/dynamic.ts
T
Dongchuan Fu 0755beebcd feat: add supports for dify hitl (#2226)
* 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
2026-07-13 00:42:46 +08:00

91 lines
3.4 KiB
TypeScript

import { I18nObject } from '@/app/infra/entities/common';
/** Namespace prefix shared by ``show_if.field`` references and display-only
* form item names whose value is resolved from the caller-supplied
* ``DynamicFormComponent.systemContext``. */
export const SYSTEM_FIELD_PREFIX = '__system.';
export interface IShowIfCondition {
field: string;
operator: 'eq' | 'neq' | 'in';
value: any;
}
export interface IDynamicFormItemSchema {
id: string;
default: string | number | boolean | Array<unknown>;
label: I18nObject;
/** Form value key. Names prefixed with ``__system.`` denote display-only
* fields whose value is resolved from
* ``DynamicFormComponent.systemContext`` (e.g. ``__system.outbound_ips``
* → ``systemContext.outbound_ips``) — same namespace as ``show_if``.
* Such fields are rendered read-only with copy buttons, excluded from
* form state/validation/emission, and hidden when the value is empty. */
name: string;
required: boolean;
type: DynamicFormItemType;
description?: I18nObject;
options?: IDynamicFormItemOption[];
/** When the condition matches, the field is rendered. Same evaluator as
* ``disable_if`` — supports the ``__system.*`` namespace via
* ``DynamicFormComponent.systemContext``. */
show_if?: IShowIfCondition;
/** When the condition matches, the field is rendered as read-only/disabled
* but stays visible. Use this when the operator needs to see that the
* field exists but can't be edited under the current runtime state (e.g.
* a sandbox-bound field when Box is disabled). Pair with
* ``disabled_tooltip`` to explain why. */
disable_if?: IShowIfCondition;
/** Tooltip shown next to the field label when ``disable_if`` is active. */
disabled_tooltip?: I18nObject;
/** when type is PLUGIN_SELECTOR, the scopes is the scopes of components(plugin contains), the default is all */
scopes?: string[];
accept?: string; // For file type: accepted MIME types
login_platform?: string; // For qr-code-login type: platform identifier (e.g. 'feishu', 'weixin')
url?: string; // For download-link type: relative or absolute download URL
download_filename?: string; // Optional filename for download-link type
help_links?: Record<string, string>; // Optional docs links for display-only fields
help_label?: I18nObject; // Optional label for help_links
}
export enum DynamicFormItemType {
INT = 'integer',
FLOAT = 'float',
BOOLEAN = 'boolean',
STRING = 'string',
TEXT = 'text',
STRING_ARRAY = 'array[string]',
FILE = 'file',
FILE_ARRAY = 'array[file]',
SELECT = 'select',
LLM_MODEL_SELECTOR = 'llm-model-selector',
EMBEDDING_MODEL_SELECTOR = 'embedding-model-selector',
RERANK_MODEL_SELECTOR = 'rerank-model-selector',
MODEL_FALLBACK_SELECTOR = 'model-fallback-selector',
PROMPT_EDITOR = 'prompt-editor',
UNKNOWN = 'unknown',
KNOWLEDGE_BASE_SELECTOR = 'knowledge-base-selector',
KNOWLEDGE_BASE_MULTI_SELECTOR = 'knowledge-base-multi-selector',
PLUGIN_SELECTOR = 'plugin-selector',
BOT_SELECTOR = 'bot-selector',
TOOLS_SELECTOR = 'tools-selector',
RICH_TOOLS_SELECTOR = 'rich-tools-selector',
RESOURCES_SELECTOR = 'resources-selector',
WEBHOOK_URL = 'webhook-url',
EMBED_CODE = 'embed-code',
QR_CODE_LOGIN = 'qr-code-login',
DOWNLOAD_LINK = 'download-link',
}
export interface IFileConfig {
file_key: string;
mimetype: string;
}
export interface IDynamicFormItemOption {
name: string;
label: I18nObject;
}