Skip to content

Commit db483a2

Browse files
authored
fix: handling settings extension in the CLI properly (#1746)
* fix: handling settings extension in the CLI properly Signed-off-by: Tomas Weiss <tomas.weiss2@gmail.com> * fix: code review comments Signed-off-by: Tomas Weiss <tomas.weiss2@gmail.com> --------- Signed-off-by: Tomas Weiss <tomas.weiss2@gmail.com>
1 parent 70e32f4 commit db483a2

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

  • apps/agentstack-cli/src/agentstack_cli/commands

apps/agentstack-cli/src/agentstack_cli/commands/agent.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,21 @@
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+
)
6479
from agentstack_sdk.platform import BuildState, File, ModelProvider, Provider, UserFeedback
6580
from agentstack_sdk.platform.context import Context, ContextPermissions, ContextToken, Permissions
6681
from 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+
449495
async 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

Comments
 (0)