Sometimes you need to give users control over how your agent behaves—like toggling “Thinking Mode,” choosing a response style, or selecting specific data sources.
The Settings Extension allows you to define these options in your code; the platform then automatically renders a native UI for the user and passes their choices back to your agent.
Settings extensions are a type of Service Extension that allows you to easily “inject dependencies” into your agent. This follows the inversion of control principle where your agent defines what it needs, and the platform provides those dependencies.
Basic Implementation
Follow these steps to add a simple user defined settings to your agent:
import os
from collections.abc import AsyncGenerator
from typing import Annotated
from a2a.types import Message
from agentstack_sdk.a2a.extensions.ui.settings import (
CheckboxField,
CheckboxGroupField,
CheckboxGroupFieldValue,
SettingsExtensionServer,
SettingsExtensionSpec,
SettingsRender,
)
from agentstack_sdk.a2a.types import RunYield
from agentstack_sdk.server import Server
from agentstack_sdk.server.context import RunContext
server = Server()
@server.agent()
async def settings_agent(
message: Message,
context: RunContext,
settings: Annotated[
SettingsExtensionServer,
SettingsExtensionSpec(
params=SettingsRender(
fields=[
CheckboxGroupField(
id="thinking_group",
fields=[
CheckboxField(
id="thinking",
label="Enable Thinking Mode",
default_value=True,
)
],
)
],
),
),
],
) -> AsyncGenerator[RunYield, Message]:
"""Agent that demonstrates settings configuration"""
if not settings:
yield "Settings extension hasn't been activated, no settings are available"
return
parsed_settings = settings.parse_settings_response()
thinking_group = parsed_settings.values["thinking_group"]
if isinstance(thinking_group, CheckboxGroupFieldValue):
if thinking_group.values["thinking"].value:
yield "Thinking mode is enabled - I'll show my reasoning process.\n"
else:
yield "Thinking mode is disabled - I'll provide direct responses.\n"
def run():
server.run(host=os.getenv("HOST", "127.0.0.1"), port=int(os.getenv("PORT", 8000)))
if __name__ == "__main__":
run()
Import the Settings extension
Import SettingsExtensionServer, SettingsExtensionSpec, SettingsRender, and field types from agentstack_sdk.a2a.extensions.ui.settings.
Inject the extension
Add a settings parameter to your agent function using the Annotated type hint with SettingsExtensionServer and SettingsExtensionSpec.
Define your settings structure
Create a SettingsRender object with the fields you want users to configure.
Process settings data
Use parse_settings_response() to access the user’s configuration choices. Use parsed_settings.values['field_id'] to access the submitted values from your settings fields.
Check if the extension exists: Always verify that the settings extension is provided before using it, as service extensions are optional.
Settings Field Types
Agent Stack supports various field types for collecting different kinds of configuration data:
CheckboxField
Single checkbox fields for boolean configuration options:
from agentstack_sdk.a2a.extensions.ui.settings import CheckboxField
CheckboxField(
id="debug_mode",
label="Enable Debug Mode",
default_value=False,
)
CheckboxGroupField
Groups multiple checkboxes together for related boolean options:
from agentstack_sdk.a2a.extensions.ui.settings import CheckboxField, CheckboxGroupField
CheckboxGroupField(
id="features",
fields=[
CheckboxField(
id="thinking",
label="Show Thinking Process",
default_value=True,
),
CheckboxField(
id="citations",
label="Include Citations",
default_value=False,
),
],
)
SingleSelectField
Dropdown fields for choosing an option from a list:
from agentstack_sdk.a2a.extensions.ui.settings import OptionItem, SingleSelectField
SingleSelectField(
id="response_style",
label="Response Style",
options=[
OptionItem(value="formal", label="Formal"),
OptionItem(value="casual", label="Casual"),
OptionItem(value="technical", label="Technical"),
],
default_value="casual",
)