From 7f36103aa47c05318480914f91f63560136c324f Mon Sep 17 00:00:00 2001 From: fdc310 <2213070223@qq.com> Date: Thu, 18 Jun 2026 11:53:50 +0800 Subject: [PATCH] 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 --- src/langbot/pkg/platform/sources/telegram.py | 39 ++++++++++++++----- src/langbot/pkg/provider/runners/difysvapi.py | 11 ++++-- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/langbot/pkg/platform/sources/telegram.py b/src/langbot/pkg/platform/sources/telegram.py index 905f57cc..c246e52a 100644 --- a/src/langbot/pkg/platform/sources/telegram.py +++ b/src/langbot/pkg/platform/sources/telegram.py @@ -167,7 +167,7 @@ class TelegramEventConverter(abstract_platform_adapter.AbstractEventConverter): time=event.message.date.timestamp(), source_platform_object=event, ) - elif event.effective_chat.type == 'group' or 'supergroup': + elif event.effective_chat.type in ('group', 'supergroup'): return platform_events.GroupMessage( sender=platform_entities.GroupMember( id=event.effective_chat.id, @@ -234,7 +234,9 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): if data.get('form_action') or data.get('f'): import langbot_plugin.api.entities.builtin.provider.session as provider_session - workflow_run_id = data.get('workflow_run_id', '') + # workflow_run_id is not in the callback payload (too large + # for Telegram's 64-byte limit). Only w_suffix is sent; + # the runner resolves the full run id from _PENDING_FORMS. w_suffix = data.get('w', '') action_id = data.get('action_id') or data.get('a', '') session_key = data.get('session_key') or data.get('s', '') @@ -266,7 +268,8 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): break form_action_data = { - 'workflow_run_id': workflow_run_id, + # workflow_run_id is intentionally omitted; the runner + # resolves it from w_suffix via _PENDING_FORMS. 'w_suffix': w_suffix, 'action_id': action_id, 'user': f'{launcher_type.value}_{launcher_id}', @@ -541,6 +544,7 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): session_key = f'p:{message_source.sender.id}' keyboard = [] + oversized = False for action in actions: action_id = action.get('id', '') action_title = action.get('title', action_id) @@ -548,10 +552,11 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): if w_suffix: callback_payload['w'] = w_suffix callback_data = json.dumps(callback_payload, separators=(',', ':')) + if len(callback_data.encode('utf-8')) > 64: + oversized = True + break keyboard.append([InlineKeyboardButton(action_title, callback_data=callback_data)]) - reply_markup = InlineKeyboardMarkup(keyboard) - update = message_source.source_platform_object chat_id = update.effective_chat.id effective_message = update.effective_message @@ -560,11 +565,25 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): text_lines = [f'[{node_title}] Please select an action:'] if form_content: text_lines.insert(0, form_content) - args = { - 'chat_id': chat_id, - 'text': '\n\n'.join(text_lines), - 'reply_markup': reply_markup, - } + + if oversized: + # callback_data exceeds Telegram's 64-byte limit — fall back to + # a plain-text numbered list so the user can reply by number. + for idx, action in enumerate(actions, start=1): + title = action.get('title') or action.get('id') or '' + text_lines.append(f' {idx}. {title}') + args = { + 'chat_id': chat_id, + 'text': '\n\n'.join(text_lines), + } + else: + reply_markup = InlineKeyboardMarkup(keyboard) + args = { + 'chat_id': chat_id, + 'text': '\n\n'.join(text_lines), + 'reply_markup': reply_markup, + } + if message_thread_id: args['message_thread_id'] = message_thread_id diff --git a/src/langbot/pkg/provider/runners/difysvapi.py b/src/langbot/pkg/provider/runners/difysvapi.py index 9f408482..93f930d9 100644 --- a/src/langbot/pkg/provider/runners/difysvapi.py +++ b/src/langbot/pkg/provider/runners/difysvapi.py @@ -171,7 +171,7 @@ class DifyServiceAPIRunner(runner.RequestRunner): Returns: (处理后的内容, 提取的思维链内容) """ - remove_think = self.pipeline_config['output'].get('misc', '').get('remove-think') + remove_think = self.pipeline_config['output'].get('misc', {}).get('remove-think') thinking_content = '' # 从 content 中提取 标签内容 if content and '' in content and '' in content: @@ -750,7 +750,7 @@ class DifyServiceAPIRunner(runner.RequestRunner): think_end = False yielded_final = False - remove_think = self.pipeline_config['output'].get('misc', '').get('remove-think') + remove_think = self.pipeline_config['output'].get('misc', {}).get('remove-think') async for chunk in self.dify_client.chat_messages( inputs=inputs, @@ -852,7 +852,7 @@ class DifyServiceAPIRunner(runner.RequestRunner): think_start = False think_end = False - remove_think = self.pipeline_config['output'].get('misc', '').get('remove-think') + remove_think = self.pipeline_config['output'].get('misc', {}).get('remove-think') async for chunk in self.dify_client.chat_messages( inputs=inputs, @@ -997,6 +997,9 @@ class DifyServiceAPIRunner(runner.RequestRunner): raw_inputs = reason.get('inputs', {}) _set_pending_form( + # Use the same session-key format as + # _session_key_from_query (launcher_type_launcher_id). + # The 'user' field is set by adapters in this format. user, { 'workflow_run_id': new_run_id, @@ -1129,7 +1132,7 @@ class DifyServiceAPIRunner(runner.RequestRunner): pending_form_data = None display_text = '' - remove_think = self.pipeline_config['output'].get('misc', '').get('remove-think') + remove_think = self.pipeline_config['output'].get('misc', {}).get('remove-think') async for chunk in self.dify_client.workflow_run( inputs=inputs, user=f'{query.session.launcher_type.value}_{query.session.launcher_id}',