# Wire All 4 Microservice Agents Into Chat
Wires all 4 microservice-backed agents into the chat so the LLM can call real services and return session URLs.
---
## Changes
### New
* `src/routes/chat.ts`
* Added a direct HTTP chat endpoint.
* When the LLM calls:
* `start_interview_session`
* `analyze_resume`
* `start_roleplay_session`
* `compute_qscore`
* The route executes real service probes and returns live session URLs.
---
### Fixed
* `src/index.ts`
* Rivet proxy now forwards requests to the engine at `localhost:6420`
instead of using `registry.handler()`.
* Prevents the:
```txt
Runtime already started as runner
```
conflict.
* `src/actors/user-actor.ts`
* `receiveMessage()` now returns:
```ts
{
reply,
sessions: []
}
```
* Includes per-module session URLs in responses.
* `docker-compose.yml`
* Fixed:
* Gitea health check port
* Port mapping
* `A2A_ALLOWED_KEY` default value
* `src/config.ts`
* Added:
```ts
resumeServiceUrl
```
* Configured to use port `8002`.
---
### Rewritten
* `prompts/system.txt`
* Reworked into a conversational step-by-step flow.
* Added explicit rule:
> CALL THE TOOL IMMEDIATELY
---
### Updated
* `agents/*.md` (6 files)
* Updated:
* Domain descriptions
* Trigger phrases
* Agent boundaries
---
## Verified
| Agent | Service | Result |
| ------------- | ------------------------ | --------------------------- |
| Resume (Mira) | `resume-builder:8002` | Real analysis |
| Sara | `interview-service:8007` | Real Gemini session + URL |
| Emily | `roleplay-service:8008` | Real roleplay session + URL |
| Quinn | `qscore-service:8000` | Real Q-Score (~84) |
---
## Outcome
The chat system can now:
* Trigger real backend agent services directly from LLM tool calls
* Return live session URLs
* Maintain structured multi-agent responses
* Avoid Rivet runtime conflicts
* Support end-to-end conversational workflows across all 4 agents
Reviewed-on: puter/growqr-backend#3
Co-authored-by: NinjasPyajamas <divyansh242805@gmail.com>
Co-committed-by: NinjasPyajamas <divyansh242805@gmail.com>
117 lines
4.5 KiB
Markdown
117 lines
4.5 KiB
Markdown
# GrowQR — backend + frontend
|
||
|
||
A multi-agent platform where every user gets a private Grow Agent (Rivet Kit actor) that orchestrates sub-agents and owns a per-user OpenCode + Gitea Docker stack. See `docs/PRD.md` for the product spec.
|
||
|
||
## What's wired up
|
||
|
||
- **Auth**: Clerk (frontend + backend JWT verification).
|
||
- **DB**: Postgres + Drizzle (users, actor registry, container mappings, repos, OpenCode sessions, events).
|
||
- **Actors**: Rivet Kit — `growAgent` per user (master) and `subAgent` (worker), with a real OpenCode Zen / OpenAI-compatible tool-use loop.
|
||
- **Per-user containers**: Gitea (memory repo) + OpenCode (workflow execution), spawned via `dockerode`, with admin user + access token bootstrap, ports allocated from a managed pool, lifecycle reconciled on backend boot.
|
||
- **Frontend**: Next.js 16 with `@clerk/nextjs` for auth and `rivetkit/client` for direct actor connections + event streaming.
|
||
- **Tool surface available to the Grow Agent**: `spawn_sub_agent`, `commit_memory`, `read_memory`, `list_memory`.
|
||
|
||
## One-time setup
|
||
|
||
You need three external accounts before running:
|
||
|
||
1. **Clerk** — create an app at https://dashboard.clerk.com → copy the publishable + secret keys.
|
||
2. **OpenCode Zen** — create an API key at https://opencode.ai/auth.
|
||
3. **Docker** — Docker Desktop (or any daemon `dockerode` can reach via `/var/run/docker.sock`).
|
||
|
||
Then:
|
||
|
||
```bash
|
||
# Backend env
|
||
cp .env.example .env
|
||
# fill in CLERK_SECRET_KEY, CLERK_PUBLISHABLE_KEY, OPENCODE_API_KEY
|
||
|
||
# Frontend env
|
||
cd growqr-frontend
|
||
cp .env.example .env.local
|
||
# fill in NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY
|
||
cd ..
|
||
```
|
||
|
||
## Running
|
||
|
||
```bash
|
||
# 1. Start Postgres + Rivet engine (per-user OpenCode/Gitea containers are
|
||
# spawned dynamically by the backend when a user signs in).
|
||
docker compose up -d postgres rivet-engine
|
||
|
||
# 2. Install + migrate
|
||
npm install
|
||
npm run db:migrate
|
||
|
||
# 3. Backend
|
||
npm run dev # http://localhost:4000
|
||
|
||
# 4. Frontend (separate terminal)
|
||
cd growqr-frontend
|
||
npm install
|
||
npm run dev # http://localhost:3000
|
||
```
|
||
|
||
Open http://localhost:3000, sign up, verify your email, and the home page will:
|
||
|
||
1. Mirror your Clerk user into Postgres.
|
||
2. Spawn your dedicated Gitea + OpenCode containers (first run pulls images — ~20–40s).
|
||
3. Connect the Grow Agent chat to your dedicated Rivet actor.
|
||
4. Stream agent + sub-agent events back to the UI.
|
||
|
||
## Architecture
|
||
|
||
```
|
||
Browser
|
||
│ Clerk JWT
|
||
▼
|
||
Next.js (3000) ──fetch──▶ /users/bootstrap, /users/me (Hono on 4000)
|
||
│
|
||
└─Rivet client──▶ /api/rivet/* (Hono → registry.handler)
|
||
│
|
||
▼
|
||
Grow Agent actor (one per user)
|
||
│
|
||
├─ OpenCode Zen (Kimi K2.6 + tool use)
|
||
├─ commit_memory ────▶ Gitea container (per user)
|
||
└─ spawn_sub_agent ────▶ OpenCode container (per user)
|
||
(multiplexed sessions)
|
||
```
|
||
|
||
## Useful commands
|
||
|
||
```bash
|
||
npm run typecheck # backend
|
||
npm run db:generate # diff schema → new migration
|
||
npm run db:studio # browse Postgres via Drizzle Studio
|
||
|
||
cd growqr-frontend
|
||
npx tsc --noEmit # frontend types
|
||
npm run lint
|
||
```
|
||
|
||
## Troubleshooting
|
||
|
||
- **"missing bearer token"** from `/users/bootstrap` — Clerk session not attached. Sign out and back in.
|
||
- **`Gitea did not become ready`** during provisioning — Gitea takes 10–20s on first pull. Wait, then `POST /actors/provision` (the frontend retries via polling).
|
||
- **OpenCode container exits immediately** — check `OPENCODE_IMAGE`. The compose env passes `Cmd: ["serve", ...]`; if you swap to a different image, ensure it exposes the `opencode serve` HTTP surface on `:4096`.
|
||
- **`No free ports in USER_PORT_RANGE`** — bump `USER_PORT_RANGE_END` in `.env` or stop unused user stacks via `POST /actors/stop`.
|
||
|
||
## PRD status
|
||
|
||
All MVP items in `docs/PRD.md` §9 are implemented:
|
||
|
||
- [x] User auth (Clerk)
|
||
- [x] Actor registry (Postgres + Rivet)
|
||
- [x] One Grow Agent Rivet Kit actor per user
|
||
- [x] Sub-agent registration under the Grow Agent
|
||
- [x] Per-user Gitea Docker + memory repo
|
||
- [x] Memory commits into the user's Gitea
|
||
- [x] Per-user OpenCode Docker + session API
|
||
- [x] Message endpoint from frontend to Grow Agent (via Rivet)
|
||
- [x] Event stream from agent to frontend (via Rivet broadcast)
|
||
- [x] Frontend: login, master chat, sub-agent progress, channel-style logs
|
||
|
||
Payments and the full quest/pathway runner are deferred to v2 (PRD §10).
|