Skip to main content
The ConsoleApiClient is the primary TypeScript interface used by the Palyra Web Console to communicate with the palyrad daemon’s Admin/Console API. It encapsulates authentication lifecycle, CSRF protection, and complex data streaming patterns required for real-time agent interactions.

Class Architecture and Lifecycle

The ConsoleApiClient is defined in apps/web/src/consoleApi.ts. It acts as a stateful client that manages session tokens and provides typed methods for every administrative and operational domain in the system.

Core Implementation

Data Flow: Web Console to Daemon

The following diagram illustrates the interaction between the React frontend, the ConsoleApiClient, and the backend Axum handlers. Figure 1: Console-to-Daemon Request Pipeline Sources: apps/web/src/consoleApi.ts#336-400, apps/web/src/consoleApi.test.ts#44-90.

CSRF Protection and Security

The client implements a “fail-closed” CSRF protection mechanism. Any request using a mutating HTTP method (POST, PUT, PATCH, DELETE) requires a valid CSRF token retrieved during the session bootstrap or login phase. Sources: apps/web/src/consoleApi.ts#1330-1350, apps/web/src/consoleApi.test.ts#44-90.

NDJSON Streaming Implementation

For chat interactions and log tails, Palyra uses Newline Delimited JSON (NDJSON) streaming. This allows the UI to render partial LLM responses and real-time events without waiting for the entire payload.

streamChatRun Logic

The streamChatRun method implements the following flow:
  1. Dispatches a POST request to /console/v1/chat/sessions/{id}/runs/stream apps/web/src/consoleApi.ts#490-500.
  2. Obtains a ReadableStream from the response body.
  3. Uses a TextDecoderStream and a custom line-buffer logic to split the stream by \n apps/web/src/consoleApi.ts#1360-1380.
  4. Parses each line as a ChatStreamLine and yields it via an AsyncGenerator apps/web/src/consoleApi.ts#1385-1395.
Figure 2: Streaming Data Flow Sources: apps/web/src/consoleApi.ts#484-510, apps/web/src/consoleApi.ts#1352-1400.

API Domain Coverage

The ConsoleApiClient organizes backend integration into functional domains, matching the palyrad service structure.
DomainKey MethodsBackend Route
AuthgetSession, login, handoff/console/v1/auth/*
ChatlistChatSessions, streamChatRun/console/v1/chat/*
InventorylistInventory, getNodeStatus/console/v1/inventory/*
RoutineslistCronJobs, dispatchRoutine/console/v1/routines/*
ApprovalslistApprovals, submitDecision/console/v1/approvals/*
SecretslistSecrets, revealSecret/console/v1/secrets/*
ConfiginspectConfig, mutateConfig/console/v1/config/*

Error Envelopes and Retry Logic

The client expects responses in a standard envelope format. If the backend returns a non-2xx status code, the client parses the body into a ControlPlaneApiError apps/web/src/consoleApi.ts#318-327.
  • Retry Strategy: The UI bootstrap process (in App.test.tsx) demonstrates that the console retries session fetches (e.g., on 429 Rate Limit) before falling back to the login screen apps/web/src/App.test.tsx#38-67.
Sources: apps/web/src/consoleApi.ts#345-1320, apps/web/src/App.test.tsx#38-67.

Desktop Handoff Integration

A critical feature for the Desktop Application (apps/desktop) is the ability to launch the system default browser and automatically authenticate the user.
  1. Token Generation: The Desktop app generates a high-entropy desktop_handoff_token.
  2. URL Construction: The browser is opened to http://localhost:7142/?desktop_handoff_token=....
  3. Consumption: Upon loading, the React app detects the query parameter and calls client.consumeDesktopHandoffToken() apps/web/src/App.test.tsx#69-107.
  4. Session Upgrade: The backend validates the token and returns a standard ConsoleSession cookie and CSRF token.
Sources: apps/web/src/App.test.tsx#69-107, apps/web/src/consoleApi.ts#352-364.