Skip to content

payallenka/AgentHub

Repository files navigation

AgentHub: Offline-First Collaborative AI Dashboard

AgentHub is a collaborative AI dashboard that combines real-time CRDT-based state synchronization, offline-first persistence, and secure backend proxying for AI model calls. It is designed for robust local development and seamless production deployment, supporting multi-user collaboration and local data durability.


Features

  • Offline-first: All state is persisted locally using IndexedDB, ensuring the app works even without a network connection.
  • Real-time collaboration: Uses Yjs CRDTs and y-websocket for conflict-free, multi-user state sync.
  • Single-domain deployment: The Node.js backend serves the React app, API, and WebSocket endpoint from one server for maximum compatibility.
  • Secure AI proxy: All Groq API calls are proxied through the backend, keeping API keys safe and off the client.
  • Sync status indicators: The UI displays network and sync status for transparency and debugging.

Tech Stack

  • Frontend: React 18, Tailwind CSS, lucide-react
  • Sync: Yjs, y-websocket, y-indexeddb
  • Backend: Node.js, Express, ws (WebSocket), node-fetch, dotenv
  • Dev Tools: concurrently, react-scripts
  • Deployment: Railway, Vercel, Fly.io, or any Node-compatible host

Project Structure

  • src/ – React UI and sync logic
    • App.js – Main dashboard UI and sync status overlay
    • agent/useAgentStore.js – App state, hydration, sync wiring, CRDT merge
    • agent/yjsAgent.js – Yjs doc and WebSocket provider bootstrap
    • agent/groq.js – Groq API client (uses backend proxy)
  • server.js – Express API, WebSocket upgrade handler, static build hosting
  • public/ – Static assets and HTML template
  • build/ – Production build output (created by npm run build)

Environment Variables

Copy .env.example to .env and fill in the required values:

cp .env.example .env

Core variables:

  • PORT – Backend server port (default: 5000)
  • GROQ_API_KEY – Groq API key (server-side only)
  • GROQ_MODEL – Groq model ID (e.g., llama-3.1-8b-instant)
  • YJS_WS_PATH – WebSocket path (default: /yjs)
  • REACT_APP_YJS_WS_URL – (optional) Explicit WebSocket URL for the client (e.g., wss://your-domain/yjs)
  • REACT_APP_GROQ_PROXY_URL – (optional) Explicit Groq proxy URL for the client (e.g., https://your-domain/groq)

Installation

Install all dependencies:

npm install

Local Development

Recommended: UI + API/WS together

This will start both the React development server and the Node backend:

npm run all

What this does:

Individual scripts

  • npm run dev – React dev server only
  • npm run proxy – Node backend only
  • npm run sync – Standalone y-websocket server on port 1234 (optional/legacy)

Production Build & Run

Build the frontend:

npm run build

Run the backend server (serves the built frontend, API, and WebSocket):

npm run proxy

Endpoints in production:

  • Static React build from /build
  • API endpoint: POST /groq
  • Health endpoint: GET /sync-health
  • Yjs WebSocket endpoint: wss://<your-domain>/yjs/<room>

Deployment

For best reliability, deploy as a single service (same domain for UI, API, and WebSocket):

  1. Build the frontend: npm run build
  2. Deploy the Node server (server.js) with the build/ directory included
  3. Use wss://<your-domain>/yjs as the sync endpoint in production

Supported platforms: Railway, Vercel (with Node backend), Fly.io, Render, or any Node-compatible host that supports WebSocket upgrades.


How Sync Works

  1. App initializes a local Yjs document
  2. IndexedDB restores prior local state immediately
  3. WebSocket provider joins the room agent-crdt-state-v1
  4. CRDT updates merge conflict-free across all connected clients
  5. UI reflects network and sync state (connected, syncing, disconnected)

Troubleshooting

Sync stuck / WebSocket not connecting

  • Check that the browser is connecting to wss://<your-domain>/yjs/agent-crdt-state-v1
  • Ensure the backend receives upgrade requests on /yjs/*
  • Confirm the production build is up-to-date (clear cache/hard refresh)
  • Make sure your hosting platform supports WebSocket upgrades end-to-end

"window is not defined" errors

  • Use browser guards (typeof window !== 'undefined') in any client modules that may be imported during SSR or Node execution

License

This project is licensed under the MIT License. See the LICENSE file for details.

This starts:

  • React app at http://localhost:3000
  • Node server at http://localhost:5000
  • WebSocket upgrade endpoint at ws://localhost:5000/yjs

Individual scripts

  • npm run dev – React dev server only
  • npm run proxy – Node server only
  • npm run sync – standalone y-websocket server on 1234 (optional/legacy)

Production Build & Run

Build the frontend:

npm run build

Run the backend server:

npm run proxy

In production, server.js serves:

  • Static React build from build/
  • API endpoint: POST /groq
  • Health endpoint: GET /sync-health
  • Yjs WS endpoint: wss://<domain>/yjs/<room>

Deployment Notes

For best reliability, deploy as a single service (same domain for UI + API + WebSocket).

Recommended flow:

  1. Build frontend (npm run build)
  2. Deploy Node server (server.js) with build/ included
  3. Use wss://<your-domain>/yjs as sync endpoint

How Sync Works

  1. App initializes local Yjs doc
  2. IndexedDB restores prior local state immediately
  3. WebSocket provider joins room agent-crdt-state-v1
  4. CRDT updates merge conflict-free across clients
  5. UI reflects network + sync state (connected, syncing, disconnected)

Troubleshooting

Sync stuck / WebSocket down

  • Verify browser WS URL is wss://<domain>/yjs/agent-crdt-state-v1
  • Ensure backend receives upgrade requests on /yjs/*
  • Confirm production build is fresh (clear cache/hard refresh)
  • Ensure platform supports WebSocket upgrades end-to-end

window is not defined

  • Use browser guards (typeof window !== 'undefined') in client modules used during build/runtime boundaries.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors