6161 TextField ,
6262 TextFieldValue ,
6363)
64+ from agentstack_sdk .a2a .extensions .ui .settings import (
65+ AgentRunSettings ,
66+ CheckboxGroupField ,
67+ CheckboxGroupFieldValue ,
68+ SettingsExtensionSpec ,
69+ SettingsFieldValue ,
70+ SettingsRender ,
71+ )
72+ from agentstack_sdk .a2a .extensions .ui .settings import (
73+ CheckboxFieldValue as SettingsCheckboxFieldValue ,
74+ )
75+ from agentstack_sdk .a2a .extensions .ui .settings import (
76+ SingleSelectFieldValue as SettingsSingleSelectFieldValue ,
77+ )
6478from agentstack_sdk .platform import BuildState , ModelProvider , Provider , UserFeedback
6579from agentstack_sdk .platform .context import Context , ContextPermissions , ContextToken , Permissions
6680from agentstack_sdk .platform .model_provider import ModelCapability
@@ -431,11 +445,42 @@ async def _ask_form_questions(form_render: FormRender) -> FormResponse:
431445 return FormResponse (values = form_values )
432446
433447
448+ async def _ask_settings_questions (settings_render : SettingsRender ) -> AgentRunSettings :
449+ """Ask user to configure settings using inquirer."""
450+ settings_values : dict [str , SettingsFieldValue ] = {}
451+
452+ console .print ("[bold]Agent Settings[/bold]\n " )
453+
454+ for field in settings_render .fields :
455+ if isinstance (field , CheckboxGroupField ):
456+ checkbox_values : dict [str , SettingsCheckboxFieldValue ] = {}
457+ for checkbox in field .fields :
458+ answer = await inquirer .confirm ( # pyright: ignore[reportPrivateImportUsage]
459+ message = checkbox .label + ":" ,
460+ default = checkbox .default_value ,
461+ ).execute_async ()
462+ checkbox_values [checkbox .id ] = SettingsCheckboxFieldValue (value = answer )
463+ settings_values [field .id ] = CheckboxGroupFieldValue (values = checkbox_values )
464+
465+ else :
466+ choices = [Choice (value = opt .value , name = opt .label ) for opt in field .options ]
467+ answer = await inquirer .fuzzy ( # pyright: ignore[reportPrivateImportUsage]
468+ message = field .label + ":" ,
469+ choices = choices ,
470+ default = field .default_value ,
471+ ).execute_async ()
472+ settings_values [field .id ] = SettingsSingleSelectFieldValue (value = answer )
473+
474+ console .print ()
475+ return AgentRunSettings (values = settings_values )
476+
477+
434478async def _run_agent (
435479 client : Client ,
436480 input : str | DataPart | FormResponse ,
437481 agent_card : AgentCard ,
438482 context_token : ContextToken ,
483+ settings : AgentRunSettings | None = None ,
439484 dump_files_path : Path | None = None ,
440485 handle_input : Callable [[], str ] | None = None ,
441486 task_id : str | None = None ,
@@ -508,6 +553,7 @@ async def _run_agent(
508553 if platform_extension_spec
509554 else {}
510555 )
556+ | ({SettingsExtensionSpec .URI : settings .model_dump (mode = "json" )} if settings else {})
511557 )
512558
513559 msg = Message (
@@ -941,8 +987,18 @@ async def run_agent(
941987 None ,
942988 )
943989
990+ settings_render = next (
991+ (
992+ SettingsRender .model_validate (ext .params )
993+ for ext in agent .capabilities .extensions or ()
994+ if ext .uri == SettingsExtensionSpec .URI and ext .params
995+ ),
996+ None ,
997+ )
998+
944999 if interaction_mode == InteractionMode .MULTI_TURN :
9451000 console .print (f"{ user_greeting } \n " )
1001+ settings_input = await _ask_settings_questions (settings_render ) if settings_render else None
9461002 turn_input = await _ask_form_questions (initial_form_render ) if initial_form_render else handle_input ()
9471003 async with a2a_client (provider .agent_card ) as client :
9481004 while True :
@@ -952,6 +1008,7 @@ async def run_agent(
9521008 input = turn_input ,
9531009 agent_card = agent ,
9541010 context_token = context_token ,
1011+ settings = settings_input ,
9551012 dump_files_path = dump_files ,
9561013 handle_input = handle_input ,
9571014 )
@@ -960,24 +1017,37 @@ async def run_agent(
9601017 elif interaction_mode == InteractionMode .SINGLE_TURN :
9611018 user_greeting = ui_annotations .get ("user_greeting" , None ) or "Enter your instructions."
9621019 console .print (f"{ user_greeting } \n " )
1020+ settings_input = await _ask_settings_questions (settings_render ) if settings_render else None
9631021 console .print ()
9641022 async with a2a_client (provider .agent_card ) as client :
9651023 await _run_agent (
9661024 client ,
9671025 input = await _ask_form_questions (initial_form_render ) if initial_form_render else handle_input (),
9681026 agent_card = agent ,
9691027 context_token = context_token ,
1028+ settings = settings_input ,
9701029 dump_files_path = dump_files ,
9711030 handle_input = handle_input ,
9721031 )
9731032
9741033 else :
1034+ settings_render = next (
1035+ (
1036+ SettingsRender .model_validate (ext .params )
1037+ for ext in agent .capabilities .extensions or ()
1038+ if ext .uri == SettingsExtensionSpec .URI and ext .params
1039+ ),
1040+ None ,
1041+ )
1042+ settings_input = await _ask_settings_questions (settings_render ) if settings_render else None
1043+
9751044 async with a2a_client (provider .agent_card ) as client :
9761045 await _run_agent (
9771046 client ,
9781047 input ,
9791048 agent_card = agent ,
9801049 context_token = context_token ,
1050+ settings = settings_input ,
9811051 dump_files_path = dump_files ,
9821052 handle_input = handle_input ,
9831053 )
0 commit comments