Skip to content

API Reference

This section contains the API reference for all modules in the OpenSymbolicAI CLI.

Modules

  • App - Main application and entry point
  • Models - Data models and schemas
  • Scanner - Agent discovery and scanning
  • Model Cache - AI model configuration caching
  • Screens - TUI screens and components

Top-level API

OpenSymbolicAI CLI - Agent Runner TUI.

AgentRunnerApp

Bases: App[None]

A TUI for discovering and running agents.

Source code in src/opensymbolicai_cli/app.py
class AgentRunnerApp(App[None]):
    """A TUI for discovering and running agents."""

    TITLE = "OpenSymbolicAI Agent Runner"
    CSS = """
    Screen {
        layout: grid;
        grid-size: 2;
        grid-columns: 1fr 3fr;
    }

    Sidebar {
        width: 100%;
        height: 100%;
        border: solid $primary;
        padding: 1;
    }

    .sidebar-title {
        text-style: bold;
        color: $accent;
        margin-bottom: 1;
    }

    #agent-list {
        height: 1fr;
    }

    .agent-name {
        padding: 0 1;
    }

    MainContent {
        width: 100%;
        height: 100%;
        border: solid $secondary;
        padding: 1;
    }

    .content-title {
        text-style: bold;
        color: $accent;
        margin-bottom: 1;
    }

    #agent-details {
        height: 1fr;
    }

    .detail-title {
        text-style: bold;
        color: $accent;
        margin-bottom: 1;
    }

    .detail-section {
        color: $accent;
        margin-top: 1;
    }

    .detail-text {
        color: $text-muted;
    }

    .placeholder {
        color: $text-muted;
        text-style: italic;
    }
    """

    BINDINGS = [
        Binding("q", "quit", "Quit"),
        Binding("d", "details", "Details"),
        Binding("s", "settings", "Settings"),
        Binding("r", "refresh", "Refresh"),
        Binding("?", "help", "Help"),
    ]

    def __init__(self) -> None:
        super().__init__()
        self.settings = Settings.load()
        self.agents: list[DiscoveredAgent] = []
        self.selected_agent: DiscoveredAgent | None = None

    def compose(self) -> ComposeResult:
        yield Header()
        yield Sidebar()
        yield MainContent()
        yield Footer()

    def on_mount(self) -> None:
        """Called when the app is mounted."""
        self._scan_agents()

    def _scan_agents(self) -> None:
        """Scan for agents in the configured folder."""
        agent_list = self.query_one("#agent-list", ListView)
        details = self.query_one("#agent-details", AgentDetails)
        agent_list.clear()

        if not self.settings.agents_folder:
            details.show_placeholder()
            self.notify("No agents folder configured. Press 's' to set one.")
            return

        if not self.settings.agents_folder.exists():
            details.show_placeholder()
            self.notify(f"Agents folder not found: {self.settings.agents_folder}")
            return

        self.agents = scan_directory_for_agents(self.settings.agents_folder)

        if not self.agents:
            details.show_placeholder()
            self.notify("No agents found in the configured folder.")
            return

        for agent in self.agents:
            agent_list.append(AgentListItem(agent))

        # Auto-select the first agent
        agent_list.index = 0
        self.selected_agent = self.agents[0]
        details.show_agent(self.agents[0])

        self.notify(f"Found {len(self.agents)} agent(s)")

    def on_list_view_highlighted(self, event: ListView.Highlighted) -> None:
        """Handle cursor movement in the agent list."""
        if isinstance(event.item, AgentListItem):
            self.selected_agent = event.item.agent
            details = self.query_one("#agent-details", AgentDetails)
            details.show_agent(event.item.agent)

    def on_list_view_selected(self, event: ListView.Selected) -> None:
        """Handle agent selection from the list - opens execution screen."""
        if isinstance(event.item, AgentListItem):
            self.selected_agent = event.item.agent
            # Open execution screen when Enter is pressed
            self.push_screen(AgentExecutionScreen(event.item.agent, self.settings))

    def action_settings(self) -> None:
        """Open the settings screen."""
        self.push_screen(SettingsScreen(self.settings), self._on_settings_closed)

    def _on_settings_closed(self, settings: Settings | None) -> None:
        """Handle settings screen closing."""
        if settings is not None:
            self.settings = settings
            settings.save()
            self.notify(f"Settings saved: {settings.default_provider}/{settings.default_model}")
            # Rescan agents with new folder
            self._scan_agents()

    def action_refresh(self) -> None:
        """Refresh the agent list."""
        self._scan_agents()

    def action_help(self) -> None:
        """Show help."""
        self.notify("Help: q=quit, d=details, s=settings, r=refresh, ?=help")

    def action_details(self) -> None:
        """Open the agent details screen."""
        if self.selected_agent is None:
            self.notify("No agent selected")
            return
        if not self.selected_agent.methods:
            self.notify("No methods found for this agent")
            return
        self.push_screen(AgentDetailsScreen(self.selected_agent))

action_details()

Open the agent details screen.

Source code in src/opensymbolicai_cli/app.py
def action_details(self) -> None:
    """Open the agent details screen."""
    if self.selected_agent is None:
        self.notify("No agent selected")
        return
    if not self.selected_agent.methods:
        self.notify("No methods found for this agent")
        return
    self.push_screen(AgentDetailsScreen(self.selected_agent))

action_help()

Show help.

Source code in src/opensymbolicai_cli/app.py
def action_help(self) -> None:
    """Show help."""
    self.notify("Help: q=quit, d=details, s=settings, r=refresh, ?=help")

action_refresh()

Refresh the agent list.

Source code in src/opensymbolicai_cli/app.py
def action_refresh(self) -> None:
    """Refresh the agent list."""
    self._scan_agents()

action_settings()

Open the settings screen.

Source code in src/opensymbolicai_cli/app.py
def action_settings(self) -> None:
    """Open the settings screen."""
    self.push_screen(SettingsScreen(self.settings), self._on_settings_closed)

on_list_view_highlighted(event)

Handle cursor movement in the agent list.

Source code in src/opensymbolicai_cli/app.py
def on_list_view_highlighted(self, event: ListView.Highlighted) -> None:
    """Handle cursor movement in the agent list."""
    if isinstance(event.item, AgentListItem):
        self.selected_agent = event.item.agent
        details = self.query_one("#agent-details", AgentDetails)
        details.show_agent(event.item.agent)

on_list_view_selected(event)

Handle agent selection from the list - opens execution screen.

Source code in src/opensymbolicai_cli/app.py
def on_list_view_selected(self, event: ListView.Selected) -> None:
    """Handle agent selection from the list - opens execution screen."""
    if isinstance(event.item, AgentListItem):
        self.selected_agent = event.item.agent
        # Open execution screen when Enter is pressed
        self.push_screen(AgentExecutionScreen(event.item.agent, self.settings))

on_mount()

Called when the app is mounted.

Source code in src/opensymbolicai_cli/app.py
def on_mount(self) -> None:
    """Called when the app is mounted."""
    self._scan_agents()

main()

Entry point for the CLI.

Source code in src/opensymbolicai_cli/__init__.py
def main() -> None:
    """Entry point for the CLI."""
    app = AgentRunnerApp()
    app.run()