AI Agent Desktop application for StateSet - manage autonomous customer service agents with real-time streaming UI.
- Autonomous AI Agents: Run AI agents in continuous loops that autonomously handle customer service tasks
- Real-time Streaming: SSE-based live updates showing agent thinking, tool calls, and responses
- Platform Integrations: OAuth connections for Shopify, Gorgias, Zendesk, and more
- Multi-brand Support: Manage multiple brands with separate configurations
- Loop Control: Pause, resume, and stop agents at any time
- Metrics Dashboard: Track token usage, tool calls, and agent performance
┌─────────────────────────────────────────┐
│ Electron Desktop App │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Login │ │Dashboard│ │ Console │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │
│ SSE Stream │
└────────────────────┼────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ StateSet Engine API (engine.stateset.cloud.stateset.app) │
│ │
│ Agent Sessions → Sandbox Execution │
│ OAuth → Platform APIs │
└─────────────────────────────────────────┘
The app runs as three connected layers:
- Electron main process (
electron/main.ts) Creates the desktop window and tray behavior, enforces navigation/security policy, handles secure key storage, and exposes IPC handlers for auth/store/oauth/notifications/updates. - Preload bridge (
electron/preload.ts) Exposes a minimalwindow.electronAPIsurface so the renderer can call approved capabilities without direct Node.js access. - React renderer (
src/main.tsx+src/App.tsx) Boots UI, initializes auth/preferences, and renders protected routes (Dashboard,Agent Console,Connections,Settings, etc.) once authenticated.
At runtime:
- Auth state is restored from secure storage and validated with
GET /api/v1/auth/me. - API requests flow through
src/lib/api.ts(retry, timeout, circuit breaker, validation, request dedupe). - React Query stores server state; Zustand stores app/session UI state.
- Agent console uses SSE (
src/hooks/useAgentStream.ts) for live event streaming. - Offline cache (
src/lib/cache.ts, IndexedDB) provides fallback reads for key lists.
For full details, see docs/ARCHITECTURE.md. For desktop-engine contract details, see docs/ENGINE_API_ALIGNMENT.md.
Example: clicking Start for a stopped agent on Dashboard.
- User clicks start in
Dashboard(src/pages/Dashboard.tsx). useOptimisticSessionMutationmarks session state asstartingimmediately for responsive UI.- Mutation calls
agentApi.startSession(tenantId, brandId, sessionId)insrc/lib/api.ts. agentApisendsPOST /api/v1/tenants/:tenantId/brands/:brandId/agents/:sessionId/start.apiRequest()handles retry/timeout/circuit-breaker concerns and records metrics.- On success, React Query invalidates session queries and refetches canonical state.
- UI re-renders with updated status (
running/paused) from API. - In
Agent Console(src/pages/AgentConsole.tsx),useAgentStream()connects to SSE endpoint. - SSE events (
thinking,message,tool_call,metrics,status_changed) stream in and update the live timeline + metrics panel. - Background sync updates tray status and optionally shows desktop notifications (
src/hooks/useBackgroundAgents.ts).
- Node.js 22.12+ (see
.nvmrc) - npm or yarn
- Clone the repository:
git clone https://github.com/stateset/stateset-desktop.git
cd stateset-desktop- Install dependencies:
npm install- Create environment file:
cp .env.example .env- Configure your API URL in
.env:
VITE_API_URL=https://engine.stateset.cloud.stateset.app
npm startYou can also run the app with a direct command:
./startFor a globally available command, install the tiny CLI helper:
./scripts/install-cli.shThen run from anywhere:
stateset-desktopThis will:
- Start Vite dev server on port 5173
- Launch Electron pointing to the dev server
- Enable hot module replacement
npm run buildThis creates distributable packages in the release/ directory.
stateset-desktop/
├── electron/ # Electron main process
│ ├── main.ts # Main entry point
│ ├── preload.ts # IPC bridge
│ └── oauth/ # OAuth handlers
├── src/ # React renderer
│ ├── components/ # UI components
│ ├── pages/ # Page components
│ ├── hooks/ # React hooks
│ ├── lib/ # API client
│ ├── stores/ # Zustand stores
│ └── types/ # TypeScript types
├── public/ # Static assets
└── assets/ # App icons
The app communicates with the StateSet API for:
- Authentication: API key validation
- Agent Sessions: CRUD operations, start/stop/pause
- SSE Streaming: Real-time event stream
- Secrets: Platform credential storage
See CONTRIBUTING.md for development setup and guidelines.
To report a vulnerability, see SECURITY.md.
MIT License - see LICENSE for details.