Skip to content

trading_agent.terminal.screens.settings_screen

The Settings page: the standing "always allow" permissions, with revoke, and the configuration file with secrets masked.

It copies the web page's SettingsPage.tsx. The configuration is read-only here, as on the web page.

Typical usage example:

app.push_screen(SettingsScreen('general'))

SettingsScreen

SettingsScreen(desk_name)

Bases: PageScreen

The Settings page.

Source code in src/trading_agent/terminal/screens/page_screen.py
def __init__(self, desk_name: str):
    """Creates the page.

    Args:
        desk_name (str): The desk the chat shows, which a desk's page starts on.
    """
    super().__init__(classes='page')
    self.desk_name = desk_name

compose_page

compose_page()

Builds the permissions table and the configuration.

Yields:

Type Description
Widget

The sections, in a scroll area.

Source code in src/trading_agent/terminal/screens/settings_screen.py
def compose_page(self):
    """Builds the permissions table and the configuration.

    Yields:
        Widget: The sections, in a scroll area.
    """
    with containers.VerticalScroll(classes='page-body'):
        yield widgets.Static(
            '[b]Standing permissions[/b] [dim]tools a desk may call without asking · delete revokes[/dim]',
            classes='page-heading',
        )
        yield widgets.DataTable(id='settings-grants', cursor_type='row')
        yield widgets.Static(
            '[b]Configuration[/b] [dim]trading_agent.toml, secrets masked, read-only[/dim]',
            classes='page-heading',
        )
        yield widgets.Static('', id='settings-configuration')

on_mount

on_mount()

Sets up the table, then reads the settings.

Source code in src/trading_agent/terminal/screens/settings_screen.py
def on_mount(self) -> None:
    """Sets up the table, then reads the settings."""
    self.table('settings-grants').add_columns(
        'Desk', 'Tool', 'Allowed since'
    )
    super().on_mount()

refresh_page async

refresh_page()

Reads the permissions and the configuration.

Source code in src/trading_agent/terminal/screens/settings_screen.py
@work(exclusive=True, group='page')
async def refresh_page(self) -> None:
    """Reads the permissions and the configuration."""
    gateway = self.app.gateway
    try:
        grants = await gateway.permission_grants()
        configuration = await gateway.configuration()
    except gateway_client.GatewayError as error:
        self.problem(error.message)
        return
    clock = formatter.Formatter()
    table = self.table('settings-grants')
    table.clear()
    for grant in grants:
        table.add_row(
            str(grant.get('desk', '')),
            str(grant.get('tool_name', '')),
            clock.day_time(str(grant.get('granted_at', ''))),
            key=f'{grant.get("desk")}|{grant.get("tool_name")}',
        )
    if not grants:
        table.add_row('—', 'none: every tool in [approvals] asks first', '')
    sections = []
    for name, value in configuration.items():
        sections.append(
            Content.from_markup('[b $accent]$name[/]', name=name)
        )
        sections.append(
            Content(json.dumps(value, indent=2, ensure_ascii=False))
        )
    self.query_one('#settings-configuration', widgets.Static).update(
        Content('\n').join(sections)
    )

action_revoke

action_revoke()

Revokes the highlighted standing permission.

Source code in src/trading_agent/terminal/screens/settings_screen.py
def action_revoke(self) -> None:
    """Revokes the highlighted standing permission."""
    key = self.selected_key('settings-grants')
    if key is None or '|' not in key:
        return
    desk, tool_name = key.split('|', 1)
    self._revoke(desk, tool_name)