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
TheConsoleApiClient 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
- Constructor: Accepts a
baseUrland an optionalfetchimplementation (useful for testing or custom environments) apps/web/src/consoleApi.ts#336-343. - Session Management: The client tracks the current
ConsoleSessionwhich includes thecsrf_tokenandexpires_at_unix_msapps/web/src/consoleApi.ts#329-334. - Authentication: Supports both standard login via
admin_tokenapps/web/src/consoleApi.ts#366-383 and Desktop Handoff via short-lived tokens apps/web/src/consoleApi.ts#352-364.
Data Flow: Web Console to Daemon
The following diagram illustrates the interaction between the React frontend, theConsoleApiClient, 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.
- Token Storage: The token is stored in memory within the
ConsoleApiClientinstance apps/web/src/consoleApi.ts#331. - Header Injection: Mutating requests automatically include the
x-palyra-csrf-tokenheader apps/web/src/consoleApi.ts#1330-1342. - Validation: If a mutating method is called without a session (and thus no CSRF token), the client throws an error before the request is even dispatched apps/web/src/consoleApi.test.ts#92-106.
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:
- Dispatches a
POSTrequest to/console/v1/chat/sessions/{id}/runs/streamapps/web/src/consoleApi.ts#490-500. - Obtains a
ReadableStreamfrom the response body. - Uses a
TextDecoderStreamand a custom line-buffer logic to split the stream by\napps/web/src/consoleApi.ts#1360-1380. - Parses each line as a
ChatStreamLineand yields it via anAsyncGeneratorapps/web/src/consoleApi.ts#1385-1395.
API Domain Coverage
TheConsoleApiClient organizes backend integration into functional domains, matching the palyrad service structure.
| Domain | Key Methods | Backend Route |
|---|---|---|
| Auth | getSession, login, handoff | /console/v1/auth/* |
| Chat | listChatSessions, streamChatRun | /console/v1/chat/* |
| Inventory | listInventory, getNodeStatus | /console/v1/inventory/* |
| Routines | listCronJobs, dispatchRoutine | /console/v1/routines/* |
| Approvals | listApprovals, submitDecision | /console/v1/approvals/* |
| Secrets | listSecrets, revealSecret | /console/v1/secrets/* |
| Config | inspectConfig, 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 aControlPlaneApiError 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.
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.
- Token Generation: The Desktop app generates a high-entropy
desktop_handoff_token. - URL Construction: The browser is opened to
http://localhost:7142/?desktop_handoff_token=.... - Consumption: Upon loading, the React app detects the query parameter and calls
client.consumeDesktopHandoffToken()apps/web/src/App.test.tsx#69-107. - Session Upgrade: The backend validates the token and returns a standard
ConsoleSessioncookie and CSRF token.