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 SingleSelectField as SettingsSingleSelectField
76+ from agentstack_sdk .a2a .extensions .ui .settings import (
77+ SingleSelectFieldValue as SettingsSingleSelectFieldValue ,
78+ )
6479from agentstack_sdk .platform import BuildState , File , ModelProvider , Provider , UserFeedback
6580from agentstack_sdk .platform .context import Context , ContextPermissions , ContextToken , Permissions
6681from agentstack_sdk .platform .model_provider import ModelCapability
@@ -446,11 +461,43 @@ async def _ask_form_questions(form_render: FormRender) -> FormResponse:
446461 return FormResponse (values = form_values )
447462
448463
464+ async def _ask_settings_questions (settings_render : SettingsRender ) -> AgentRunSettings :
465+ """Ask user to configure settings using inquirer."""
466+ settings_values : dict [str , SettingsFieldValue ] = {}
467+
468+ console .print ("[bold]Agent Settings[/bold]\n " )
469+
470+ for field in settings_render .fields :
471+ if isinstance (field , CheckboxGroupField ):
472+ checkbox_values : dict [str , SettingsCheckboxFieldValue ] = {}
473+ for checkbox in field .fields :
474+ answer = await inquirer .confirm ( # pyright: ignore[reportPrivateImportUsage]
475+ message = checkbox .label + ":" ,
476+ default = checkbox .default_value ,
477+ ).execute_async ()
478+ checkbox_values [checkbox .id ] = SettingsCheckboxFieldValue (value = answer )
479+ settings_values [field .id ] = CheckboxGroupFieldValue (values = checkbox_values )
480+ elif isinstance (field , SettingsSingleSelectField ):
481+ choices = [Choice (value = opt .value , name = opt .label ) for opt in field .options ]
482+ answer = await inquirer .fuzzy ( # pyright: ignore[reportPrivateImportUsage]
483+ message = field .label + ":" ,
484+ choices = choices ,
485+ default = field .default_value ,
486+ ).execute_async ()
487+ settings_values [field .id ] = SettingsSingleSelectFieldValue (value = answer )
488+ else :
489+ raise ValueError (f"Unsupported settings field type: { type (field ).__name__ } " )
490+
491+ console .print ()
492+ return AgentRunSettings (values = settings_values )
493+
494+
449495async def _run_agent (
450496 client : Client ,
451497 input : str | DataPart | FormResponse ,
452498 agent_card : AgentCard ,
453499 context_token : ContextToken ,
500+ settings : AgentRunSettings | None = None ,
454501 dump_files_path : Path | None = None ,
455502 handle_input : Callable [[], str ] | None = None ,
456503 task_id : str | None = None ,
@@ -523,6 +570,7 @@ async def _run_agent(
523570 if platform_extension_spec
524571 else {}
525572 )
573+ | ({SettingsExtensionSpec .URI : settings .model_dump (mode = "json" )} if settings else {})
526574 )
527575
528576 msg = Message (
@@ -939,6 +987,15 @@ async def run_agent(
939987 splash_screen = Group (Markdown (f"# { agent .name } \n { agent .description } " ), NewLine ())
940988 handle_input = _create_input_handler ([], splash_screen = splash_screen )
941989
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+
942999 if not input :
9431000 if interaction_mode not in {InteractionMode .MULTI_TURN , InteractionMode .SINGLE_TURN }:
9441001 err_console .error (
@@ -959,6 +1016,7 @@ async def run_agent(
9591016
9601017 if interaction_mode == InteractionMode .MULTI_TURN :
9611018 console .print (f"{ user_greeting } \n " )
1019+ settings_input = await _ask_settings_questions (settings_render ) if settings_render else None
9621020 turn_input = await _ask_form_questions (initial_form_render ) if initial_form_render else handle_input ()
9631021 async with a2a_client (provider .agent_card , context_token = context_token ) as client :
9641022 while True :
@@ -968,6 +1026,7 @@ async def run_agent(
9681026 input = turn_input ,
9691027 agent_card = agent ,
9701028 context_token = context_token ,
1029+ settings = settings_input ,
9711030 dump_files_path = dump_files ,
9721031 handle_input = handle_input ,
9731032 )
@@ -976,24 +1035,29 @@ async def run_agent(
9761035 elif interaction_mode == InteractionMode .SINGLE_TURN :
9771036 user_greeting = ui_annotations .get ("user_greeting" , None ) or "Enter your instructions."
9781037 console .print (f"{ user_greeting } \n " )
1038+ settings_input = await _ask_settings_questions (settings_render ) if settings_render else None
9791039 console .print ()
9801040 async with a2a_client (provider .agent_card , context_token = context_token ) as client :
9811041 await _run_agent (
9821042 client ,
9831043 input = await _ask_form_questions (initial_form_render ) if initial_form_render else handle_input (),
9841044 agent_card = agent ,
9851045 context_token = context_token ,
1046+ settings = settings_input ,
9861047 dump_files_path = dump_files ,
9871048 handle_input = handle_input ,
9881049 )
9891050
9901051 else :
1052+ settings_input = await _ask_settings_questions (settings_render ) if settings_render else None
1053+
9911054 async with a2a_client (provider .agent_card , context_token = context_token ) as client :
9921055 await _run_agent (
9931056 client ,
9941057 input ,
9951058 agent_card = agent ,
9961059 context_token = context_token ,
1060+ settings = settings_input ,
9971061 dump_files_path = dump_files ,
9981062 handle_input = handle_input ,
9991063 )
0 commit comments