Skip to content

Commit db35516

Browse files
committed
fix: handling settings extension in the CLI properly
Signed-off-by: Tomas Weiss <[email protected]>
1 parent 5017241 commit db35516

File tree

1 file changed

+70
-0
lines changed
  • apps/agentstack-cli/src/agentstack_cli/commands

1 file changed

+70
-0
lines changed

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

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@
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+
)
6478
from agentstack_sdk.platform import BuildState, ModelProvider, Provider, UserFeedback
6579
from agentstack_sdk.platform.context import Context, ContextPermissions, ContextToken, Permissions
6680
from 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+
434478
async 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

Comments
 (0)