feat: Enhance select input handling and validation in Dify API runner and Telegram adapter

This commit is contained in:
fdc310
2026-07-12 00:31:12 +08:00
parent 4b6931d294
commit 354aadfce0
4 changed files with 204 additions and 27 deletions
@@ -36,7 +36,7 @@ def test_telegram_select_field_options_are_extracted():
def test_telegram_select_callback_becomes_input_progress():
assert _telegram_form_action_from_callback({'f': 1, 'x': 1}) == {
'action_id': '',
'inputs': {'select': '1'},
'inputs': {'select': {'index': 1}},
'_input_progress': True,
}
@@ -602,6 +602,42 @@ class TestDifyHumanInputForms:
assert action['inputs'] == {'us_input': 'hello', 'xiala': '2'}
assert action['_form_data']['_action_select_only'] is True
@pytest.mark.asyncio
async def test_invalid_select_reply_keeps_the_current_form_field(self):
from langbot.pkg.provider.runners import difysvapi
runner = self._create_runner()
session_key = 'person_user-1'
difysvapi._PENDING_FORMS.clear()
difysvapi._set_pending_form(
session_key,
{
'form_token': 'token-1',
'workflow_run_id': 'run-1',
'actions': [{'id': 'yes', 'title': 'Yes'}],
'input_defs': [
{
'output_variable_name': 'choice',
'type': 'select',
'option_source': {'type': 'constant', 'value': ['A', 'B']},
}
],
'inputs': {},
'current_input_field': 'choice',
'user': session_key,
},
)
query = MagicMock()
query.message_chain = platform_message.MessageChain([platform_message.Plain(text='')])
action = await runner._match_pending_form_action(query, session_key, 'C')
assert action['_partial'] is True
assert action['inputs'] == {}
assert action['_form_data']['_current_input_field'] == 'choice'
assert 'choice: 1. A, 2. B' in action['notice']
assert difysvapi._get_latest_pending_form(session_key)['inputs'] == {}
@pytest.mark.asyncio
async def test_workflow_pause_without_text_yields_form_chunk(self):
from langbot.pkg.provider.runners import difysvapi
@@ -809,6 +845,60 @@ class TestDifyHumanInputForms:
assert second['inputs'] == {'comment': 'looks good', 'choice': 'B'}
assert second['_form_data']['_action_select_only'] is True
def test_card_select_preserves_numeric_option_values(self):
from langbot.pkg.provider.runners import difysvapi
runner = self._create_runner()
session_key = 'person_user-1'
difysvapi._PENDING_FORMS.clear()
difysvapi._set_pending_form(
session_key,
{
'form_token': 'token-1',
'workflow_run_id': 'run-1',
'actions': [{'id': 'yes', 'title': 'Yes'}],
'input_defs': [
{
'output_variable_name': 'choice',
'type': 'select',
'option_source': {'type': 'constant', 'value': ['1', '2']},
}
],
'inputs': {},
'current_input_field': 'choice',
'user': session_key,
},
)
action = runner._merge_pending_form_action(
session_key,
{
'form_token': 'token-1',
'workflow_run_id': 'run-1',
'inputs': {'select': '1'},
'_current_input_field': 'choice',
'_input_progress': True,
},
)
assert action['_partial'] is True
assert action['inputs'] == {'choice': '1'}
def test_invalid_card_select_value_is_not_saved(self):
from langbot.pkg.provider.runners import difysvapi
form = {
'input_defs': [
{
'output_variable_name': 'choice',
'type': 'select',
'option_source': {'type': 'constant', 'value': ['A', 'B']},
}
]
}
assert difysvapi._normalize_form_action_inputs(form, {'choice': 'C'}) == {}
@pytest.mark.asyncio
async def test_blocking_resume_uses_chatflow_answer_node_output(self):
runner = self._create_runner()