Terminal User Interface (TUI)
The Palyra TUI is aratatui-based interface providing a rich, interactive environment for managing agent sessions. It handles real-time event streaming, tool approval workflows, and multi-agent switching.
Implementation and State Management
The TUI is centered around theApp struct crates/palyra-cli/src/tui/mod.rs#107-130, which maintains the UI state, including the OperatorRuntime, current session metadata, and a transcript of interaction entries.
The application operates in several modes crates/palyra-cli/src/tui/mod.rs#45-52:
Chat: The primary interaction surface.Picker: For selecting agents, sessions, or models.Approval: A blocking state for manual tool execution authorization.Settings: Toggling UI features like “Show Thinking” or “Local Shell”.
Event Loop and Rendering
The TUI uses a standard event loop powered bycrossterm crates/palyra-cli/src/tui/mod.rs#148-164. It polls for terminal events every 50ms and drains asynchronous events from the ManagedRunStream crates/palyra-cli/src/tui/mod.rs#150.
| Component | Role | Source |
|---|---|---|
setup_terminal | Enables raw mode and alternate screen | crates/palyra-cli/src/tui/mod.rs#166-171 |
drain_stream_events | Processes incoming NDJSON events from the daemon | crates/palyra-cli/src/tui/mod.rs#150 |
render | Draws the UI frames using ratatui widgets | crates/palyra-cli/src/tui/mod.rs#151 |
ACP Bridge (Agent Control Protocol)
The ACP Bridge allows Palyra to act as a backend for IDEs and external tools (like VS Code or JetBrains) by shimming the standard input/output into Palyra’s gRPC protocol.Shim Architecture
The bridge implements thePalyraAcpAgent crates/palyra-cli/src/acp_bridge.rs#81-98, which translates ACP JSON-RPC requests into Palyra GatewayRuntimeClient calls.
Natural Language to Code Entity Space: ACP Flow
Sources: crates/palyra-cli/src/acp_bridge.rs#31-63, crates/palyra-cli/src/acp_bridge.rs#81-98
Session and Permission Mapping
- Session Persistence: The bridge maintains a
BridgeStatecrates/palyra-cli/src/acp_bridge.rs#39-42 to map ACPSessionIdstrings to Palyra’s ULID-based session keys. - Permissions: ACP permission requests are bridged via
request_permissioncrates/palyra-cli/src/acp_bridge.rs#118-131, supporting decision scopes likeallow-onceandallow-alwayscrates/palyra-cli/src/acp_bridge.rs#25-28.
Agent Interaction and Run Orchestration
The CLI interacts with the daemon via theOperatorRuntime crates/palyra-cli/src/client/operator.rs#15-17, which abstracts gRPC connection management and stream handling.
Managed Run Streams
A “Run” is orchestrated through aManagedRunStream crates/palyra-cli/src/client/operator.rs#31-35. This handles the bidirectional nature of the open_run_stream gRPC call:
- Downstream: Receives
RunStreamEvent(text chunks, tool calls, status updates) crates/palyra-cli/src/client/operator.rs#42-48. - Upstream: Sends
ToolApprovalResponseback to the daemon when a tool requires operator consent crates/palyra-cli/src/client/operator.rs#50-68.
Run Execution Logic
Theexecute_agent_stream function (called by run_agent) crates/palyra-cli/src/commands/agent.rs#73 handles the lifecycle of a single prompt:
- Prompt Resolution: Resolves input from CLI arguments or
stdincrates/palyra-cli/src/commands/agent.rs#48. - Connection Overrides: Applies principal, device ID, and token overrides crates/palyra-cli/src/commands/agent.rs#49-59.
- NDJSON Streaming: If enabled, outputs raw protocol events as line-delimited JSON for machine consumption crates/palyra-cli/src/commands/agent.rs#73.
Session Management
The CLI provides comprehensive session control through thesessions command group crates/palyra-cli/src/commands/sessions.rs#47-94.
Key Operations
- Listing: Supports pagination (
after), archiving filters, and NDJSON output crates/palyra-cli/src/commands/sessions.rs#48-50. - History: Uses the
ControlPlaneClientto search session catalogs crates/palyra-cli/src/commands/sessions.rs#104-122. - Compaction: Commands like
CompactPreviewandCompactApplyallow for manual session context management crates/palyra-cli/src/commands/sessions.rs#31-32.
Session Resolution
Before a run begins, the CLI often callsresolve_session crates/palyra-cli/src/client/operator.rs#112-118. This ensures the session_key and session_label provided by the operator are mapped to a valid CanonicalId (ULID) in the daemon’s JournalStore.
Sources: crates/palyra-cli/src/commands/sessions.rs#1-154, crates/palyra-cli/src/client/operator.rs#101-118
Operator Client Transport
The transport layer relies onGatewayRuntimeClient crates/palyra-cli/src/client/runtime.rs, which wraps the Tonic-generated gRPC stubs.
Connection Security
Connections are established usingAgentConnection metadata, which includes:
- mTLS / Token Auth: Authenticating via
PALYRA_ADMIN_TOKENcrates/palyra-daemon/tests/health_endpoint.rs#67. - Principal Binding: Associating the CLI session with a specific operator identity (e.g.,
user:ops) crates/palyra-cli/tests/daemon_status.rs#52. - Device Identity: Identifying the specific terminal or host via a
device_idcrates/palyra-cli/tests/daemon_status.rs#53.
Diagnostics
Thedaemon status and admin-status commands verify transport health by checking the /healthz endpoint crates/palyra-daemon/tests/health_endpoint.rs#27 and gRPC service availability crates/palyra-cli/tests/cli_v1_acp_shim.rs#23-57.
Sources: crates/palyra-cli/tests/daemon_status.rs#18-132, crates/palyra-daemon/tests/health_endpoint.rs#1-158