AgentDesk Development Project by Asad Jehan ZebAgentDesk Development Project by Asad Jehan Zeb

AgentDesk Development Project

Asad Jehan Zeb

Asad Jehan Zeb

AgentDesk

AgentDesk is a control room for AI agents — configure them, run them, and inspect exactly what happened. It's built to be remixed: fork it, swap the demo data for your own domain, and point the runtime at a real model provider when you're ready.
It works two ways out of the box:
Demo mode — deterministic, local, zero API keys. Every screen (agents, runs, tasks, knowledge, integrations, analytics) is fully interactive from the first load.
Provider mode — set an API key on the server and pick a provider in Settings to execute agents for real. Three providers ship today: OpenAI, Anthropic, and OpenRouter.
Both modes go through the same AgentRuntime interface in the UI, so nothing in the application code branches on "am I really calling a model." It just asks the runtime to run, and the runtime decides how.

Quickstart

Requires Node.js 24 and pnpm.

Open the printed frontend URL. Demo mode works immediately with no setup. To try real execution, stop the API server, set a provider's key, and start it again:

Then in the app, go to Settings → Runtime, switch to Provider runtime, and pick the provider you configured. Settings and Integrations both show whether each provider is actually configured on the server — not just whether you toggled a switch.

Environment variables

Variable Required? Used by Purpose PORT Yes, for the frontend artifacts/agentdesk Vite dev/build server port BASE_PATH Yes, for the frontend artifacts/agentdesk Base path the frontend is served from (e.g. /) OPENAI_API_KEY Optional artifacts/api-server Enables real agent execution via OpenAI ANTHROPIC_API_KEY Optional artifacts/api-server Enables real agent execution via Anthropic (Claude) OPENROUTER_API_KEY Optional artifacts/api-server Enables real agent execution via OpenRouter (routes to many model vendors through one key) API_PROXY_TARGET Optional artifacts/agentdesk (dev only) Where the frontend dev server proxies /api requests. Defaults to http://localhost:5000. DATABASE_URL Not currently needed @workspace/db Scaffolded for future use; the API server doesn't import @workspace/db yet, so you can ignore this until you wire up persistence.
Every provider key above is read server-side only. None of them are ever sent to the client, stored in localStorage, or logged — even on failure.

Architecture: AgentRuntime and ProviderAdapter

There are two small, deliberately generic abstractions — one on the client, one on the server. OpenAI, Anthropic, and OpenRouter are three concrete implementations of each; none of them are special-cased anywhere outside their own adapter file.
Client — artifacts/agentdesk/src/lib/runtime.ts

getRuntime() reads the mode and active provider persisted from the Settings page and returns DemoRuntime or the selected provider runtime. Every page that runs an agent (RunModal) calls runtime.run(...) and doesn't otherwise care which one it got. Demo runs return a simulated multi-step trace and placeholder output. Provider runs make one real round trip and return the model's actual output — no fabricated tool calls, no hidden reasoning — with a clean "Failed" result (not a crash) if the provider errors or isn't configured.
Server — artifacts/api-server/src/providers/

providers/registry.ts holds the list every provider is registered in. routes/runtime.ts is entirely generic over that list — it never mentions any provider by name. It exposes:
GET /api/runtime/status — which providers exist and whether each has usable credentials. Never returns the credential itself.
POST /api/runtime/run{ provider, agentName, model?, instructions?, task }{ provider, model, output, tokens?, durationMs }, or a structured { error, message } with 400/503/502 depending on what went wrong.
Adding a fourth provider means:
Write providers/<name>.ts implementing ProviderAdapter.
Add it to the array in providers/registry.ts.
Add createProviderRuntime('<name>', '<Label>') on the client (runtime.ts), and register it in the small PROVIDER_RUNTIMES lookup next to it.
No changes to the route, the OpenAPI contract, or the Integrations/Settings UI are required — those already render whatever GET /api/runtime/status reports, and the Settings provider picker already lists whatever's in that array.

Where things live


To regenerate the API client after changing lib/api-spec/openapi.yaml:

Scripts

pnpm run typecheck — typecheck every package
pnpm run build — typecheck + build every package
pnpm --filter @workspace/agentdesk run dev — frontend dev server
pnpm --filter @workspace/api-server run dev — API server (build + start)

What's demo vs. real, at a glance

Area Demo mode Provider mode Agent execution Simulated 6-step trace, canned output One real request to whichever provider is selected, actual model output Integrations page Local, reversible "connections," clearly labeled Demo Server-verified Connected / Not configured for each provider, driven by GET /api/runtime/status Settings Toggle only changes local state Lets you pick which configured provider is active, and shows whether its key is actually set on the server Credentials None Read from server environment variables only — never touch the browser

License

This project started as a Replit Buildathon submission and is intended as a starting point to fork and adapt.
Like this project

Posted Aug 10, 2026

Developed AgentDesk, a control room for AI agent configuration and execution.