Skip to main content
This page documents the architecture of the Palyra Web Dashboard (apps/web) data layer, focusing on the ConsoleApiClient for server communication and the useConsoleAppState hook for centralized state management, session lifecycle, and auto-refresh logic.

Console API Client

The ConsoleApiClient is the primary interface for the React SPA to communicate with the palyrad daemon via the /console/v1 and /admin/v1 HTTP endpoints. It handles CSRF protection, error normalization, and provides specialized support for NDJSON streaming.

CSRF and Session Management

The client maintains an internal ConsoleSession state. For any mutating request (POST, PUT, DELETE), it automatically injects the x-palyra-csrf-token header derived from the active session apps/web/src/consoleApi.ts#1-10. If a CSRF token is required but missing, the client fails closed to prevent unauthorized mutations apps/web/src/consoleApi.test.ts#92-106.

Error Normalization

All API responses are parsed through a normalization layer. If a response is not successful, it is converted into a ControlPlaneApiError, which captures the HTTP status code and the structured error message from the daemon apps/web/src/consoleApi.ts#13-16.

NDJSON Streaming

For real-time updates (e.g., chat runs, log tailing), the client supports Newline Delimited JSON (NDJSON) streaming. It utilizes the ReadableStream API to yield objects to the UI as they arrive from the daemon apps/web/src/consoleApi.ts#6-8. Console API Client Interaction Flow Sources: apps/web/src/consoleApi.ts#1-100, apps/web/src/consoleApi.test.ts#44-90

State Management and useConsoleAppState

The useConsoleAppState hook serves as the “brain” of the dashboard. It orchestrates domain-specific hooks (Auth, Browser, Config, Support) and manages the global UI state (theme, active section, notifications).

Key Responsibilities

  1. Bootstrapping: Manages the initial loading sequence, including session recovery and desktop handoff apps/web/src/useConsoleAppState.tsx#168-170.
  2. Section Routing: Maps the current URL hash to a Section identifier, which determines which component is rendered in the ConsoleSectionContent apps/web/src/console/ConsoleSectionContent.tsx#26-98.
  3. Domain Integration: Aggregates state from specialized hooks like useAuthDomain, useBrowserDomain, and useSupportDomain apps/web/src/useConsoleAppState.tsx#21-25.

Auto-Refresh TTL Engine

To keep the dashboard data fresh without constant manual intervention, the app implements a TTL (Time-To-Live) based auto-refresh engine. Each section has a defined refresh interval apps/web/src/useConsoleAppState.tsx#42-54.
SectionTTL (ms)
overview, auth, browser, memory, operations10,000
channels8,000
config, secrets15,000
The shouldAutoRefreshSection function compares the current timestamp against the lastRefreshedAt ref to determine if a background fetch is necessary apps/web/src/useConsoleAppState.tsx#62-72. Sources: apps/web/src/console/useConsoleAppState.tsx#1-170, apps/web/src/console/navigation.ts#54-74

Authentication and Handoff Lifecycle

The dashboard supports three primary entry paths: standard session cookies, explicit login via token, and “Desktop Handoff.”

Desktop Handoff

When the dashboard is launched from the Palyra Desktop app, it includes a desktop_handoff_token in the query string. The loadDesktopHandoffSession function attempts to exchange this token for a full session before falling back to standard bootstrap apps/web/src/useConsoleAppState.tsx#109-123.

Sign-In/Sign-Out Flow

  1. SignIn: The signIn function submits the LoginForm to api.login(). On success, the returned session is stored, and the booting state is set to false apps/web/src/App.tsx#20-30.
  2. SignOut: Clears local session state and redirects to the auth screen.
Authentication State Machine Sources: apps/web/src/App.test.tsx#69-107, apps/web/src/console/useConsoleAppState.tsx#88-123, apps/web/src/App.tsx#11-33

Section Routing and Navigation

Navigation is handled via a hash-based router (HashRouter) in production to ensure compatibility with local file serving and desktop environments apps/web/src/App.tsx#45-47. Sections are organized into logical groups defined in CONSOLE_NAV_GROUPS apps/web/src/console/navigation.ts#26-52:
  • Chat: The primary agent interaction surface.
  • Observability: Overview, Sessions, Usage, Logs, Inventory, Support.
  • Control: Approvals, Routines (Cron), Channels, Browser.
  • Agent: Agents, Skills, Memory.
  • Settings: Auth Profiles, Access, Config, Secrets, Diagnostics.

Component Mapping

The ConsoleSectionContent component acts as a switch-case dispatcher that receives the global app state and renders the corresponding domain component apps/web/src/console/ConsoleSectionContent.tsx#26-98. Sources: apps/web/src/console/navigation.ts#1-130, apps/web/src/console/ConsoleSectionContent.tsx#1-98