CloudPlot
CloudPlot is a CopilotKit V2 and LangGraph demo for designing simulated AWS architectures through conversation. The workspace renders resource cards and VPC groupings while the chat renders backend tool activity and a human approval card.
CloudPlot is simulation-only. Its application and agent code import no AWS clients, call no AWS APIs, read no AWS credentials, and never create or change cloud resources. The demo manifests add no AWS-specific dependencies. Costs are fixed demo estimates rather than live AWS pricing.
What the demo shows
CopilotKitProvideranduseAgentconnect the V2 chat to shared LangGraph state.useRenderToolrenders add, connect, remove, and move calls without registering duplicate frontend handlers for backend tools.useHumanInTheLoopregistersapproveDeployment. Approving or rejecting returns a tool result so the model can continue the conversation; neither decision deploys anything.- Browser-local branch snapshots let users fork and revisit workspace alternatives.
- Quick-start prompts are ordinary product data shared by the rendered buttons and their behavior tests.
The main workspace is a responsive card layout, not a React Flow canvas. Connections are retained in agent state and shown in chat tool cards; the workspace itself groups resources by VPC.
Run locally
Requirements:
- Node.js 20.9 or newer
- pnpm 10
- Python 3.12 or newer
- uv
- An OpenAI API key
From the CopilotKit repository root:
pnpm install --frozen-lockfile
cd examples/showcases/cloudplot
cp .env.example .env.local
cp agent/.env.example agent/.env
# Add OPENAI_API_KEY to agent/.env.
pnpm dev
Open http://localhost:3000, then try “Build a 3-tier web application with VPC, ALB, EC2 instances, and RDS database.” The UI runs on port 3000 and the FastAPI agent runs on port 8123.
Useful commands:
pnpm dev:ui
pnpm dev:agent
pnpm lint
pnpm typecheck
pnpm test
pnpm build
cd agent
uv sync --frozen
uv run pytest
Runtime architecture
Browser
CopilotKitProvider + CopilotChat + workspace cards
|
v
Next.js /api/copilotkit
CopilotRuntime + LangGraphHttpAgent
|
v
Python FastAPI /
LangGraphAGUIAgent + CloudPlot graph
The Python service uses Uvicorn and exposes AG-UI at /. The frontend health endpoint, /api/health, probes the configured agent’s /health endpoint with a bounded timeout and returns 503 when it cannot reach the agent.
Agent checkpoints use LangGraph MemorySaver, so chat-thread state lasts only for the life of one agent process. Browser branch snapshots preserve the visible workspace locally, but an agent restart loses server-side conversation checkpoints. Durable threads require an external checkpointer, which is intentionally outside this demo’s approved scope. Setting CLOUDPLOT_REQUIRE_DURABLE_THREADS=1 makes the agent fail at startup instead of claiming unsupported durability.
Tool flow
The model can call these backend tools:
add_resourceconnect_resourcesremove_resourceupdate_resourcemove_to_vpc
The browser registers render-only cards for add, connect, remove, and move. For a requested simulated deployment, the model calls the browser-owned approveDeployment tool. The approval card resolves to approved or rejected, and CopilotKit supplies that result to the continuation run.
Backend tool results must be structured mappings or valid JSON objects. Invalid results are logged and ignored rather than being rewritten from Python-repr text.
Branches and persistence
Each branch has its own thread ID and browser-local workspace snapshot. Storage is read only after client hydration, so the SSR-safe zero UUID is never mounted into chat. Legacy branches without a thread ID are migrated on load, corrupt storage falls back to a fresh branch, and switching branches applies the saved workspace synchronously.
Project structure
agent/
main.py LangGraph state, tools, validation, and cost model
server.py FastAPI/AG-UI production entrypoint and health route
tests/ Tests of production agent and server behavior
src/
app/ Next.js page, CopilotKit route, and health route
components/ Workspace, VPC, resource, tool, and approval cards
hooks/ V2 agent, render-tool, HITL, and branch behavior
lib/quickStarts.ts Product quick-start prompt definitions
types/ Shared frontend state types
Railway deployment
Railway no longer lets new services opt into Config as Code, so configure two services explicitly in the Railway dashboard. Both services must use the same merged CopilotKit revision. See Railway's Config as Code notice and monorepo guide.
| Setting | Frontend service | Agent service |
|---|---|---|
| Root directory | / |
/examples/showcases/cloudplot/agent |
| Builder | Railpack | Dockerfile (Dockerfile) |
| Build command | pnpm nx run cloudplot:build |
Dockerfile default |
| Start command | pnpm --filter cloudplot start |
Dockerfile default |
| Health-check path | /api/health |
/health |
| Restart policy | On Failure, 5 retries | On Failure, 5 retries |
| Watch paths | /examples/showcases/cloudplot/**, /packages/**, /package.json, /pnpm-lock.yaml, /pnpm-workspace.yaml, /nx.json |
/examples/showcases/cloudplot/agent/** |
Set these service variables in Railway (the platform supplies PORT):
- Frontend:
LANGGRAPH_DEPLOYMENT_URL,CLOUDPLOT_ACCESS_CODE, and a long, randomCLOUDPLOT_SESSION_SECRET. - Agent:
OPENAI_API_KEY.
The frontend must use the repository root because its workspace:*
CopilotKit dependencies are built from the monorepo. Point
LANGGRAPH_DEPLOYMENT_URL at the agent's private Railway URL. Do not configure
AWS credentials. Do not set CLOUDPLOT_REQUIRE_DURABLE_THREADS=1 unless the
desired outcome is a fail-loud startup check. Both health checks return 503
when required configuration or dependencies are unavailable.
Manual live smoke
There is no Playwright claim for this two-service workflow. After starting or deploying both services:
- Submit a quick-start prompt and confirm resources appear in the workspace and
add_resourcecards appear in chat. - Ask to simulate deployment, approve it, and confirm the assistant continues without claiming AWS resources were created.
- Ask again, reject it, and confirm the assistant acknowledges the rejection.
- Fork a branch, change its workspace, switch branches, and reload to confirm each browser snapshot is restored.
- Stop the agent and confirm frontend
GET /api/healthreturns503; restart it and confirm the endpoint returns200.
License
MIT
Built by Mark Morgan