Context
Steps 1-5 build the core agent with persistent memory. Step 6 exposes it over the network so TUI clients, web UIs, and programmatic consumers can interact with it.
Scope
HTTP server
- Chi router setup
GET /health — {"status": "ok", "version": "..."}
GET /ready — {"ready": true, "providers": [...]}
- Graceful shutdown on SIGINT/SIGTERM
WebSocket protocol
GET /ws — WebSocket upgrade
- Client frames:
hello (auth), send (message), subscribe, cancel, session_cmd
- Server frames:
welcome, text_delta, tool_progress, turn_complete, error, session_list, session_created, session_switched
- Frame types already defined in
internal/types/channel.go
REST API
POST /api/v1/chat — non-streaming chat (returns complete response)
POST /api/v1/chat/stream — SSE streaming endpoint
GET /api/v1/sessions — list sessions
POST /api/v1/sessions — create session
GET /api/v1/sessions/:id — get session detail
Session management
- Create/resume/archive sessions
- Max concurrent sessions (
gateway.max_sessions)
- Max concurrent turns (
gateway.max_concurrent_turns)
- Idle session TTL cleanup (
session_idle_ttl_hours)
Authentication
- Simple API key auth via
gateway.api_key config
Authorization: Bearer <key> header for REST
hello frame with key for WebSocket
Turn execution bridge
- WebSocket/REST → runtime.Run() bridge
- Stream text deltas back to client in real-time
- Forward tool progress events
Files to create
internal/gateway/
├── server.go # Chi server setup, routes, middleware
├── websocket.go # WebSocket handler + frame protocol
├── rest.go # REST API handlers
├── session_mgr.go # Session lifecycle management
├── auth.go # API key middleware
└── gateway_test.go
Implements
yantra start — starts daemon with gateway
yantra serve — headless API-only mode
Dependencies
github.com/go-chi/chi/v5
nhooyr.io/websocket (or gorilla/websocket already in go.mod)
Context
Steps 1-5 build the core agent with persistent memory. Step 6 exposes it over the network so TUI clients, web UIs, and programmatic consumers can interact with it.
Scope
HTTP server
GET /health—{"status": "ok", "version": "..."}GET /ready—{"ready": true, "providers": [...]}WebSocket protocol
GET /ws— WebSocket upgradehello(auth),send(message),subscribe,cancel,session_cmdwelcome,text_delta,tool_progress,turn_complete,error,session_list,session_created,session_switchedinternal/types/channel.goREST API
POST /api/v1/chat— non-streaming chat (returns complete response)POST /api/v1/chat/stream— SSE streaming endpointGET /api/v1/sessions— list sessionsPOST /api/v1/sessions— create sessionGET /api/v1/sessions/:id— get session detailSession management
gateway.max_sessions)gateway.max_concurrent_turns)session_idle_ttl_hours)Authentication
gateway.api_keyconfigAuthorization: Bearer <key>header for RESThelloframe with key for WebSocketTurn execution bridge
Files to create
Implements
yantra start— starts daemon with gatewayyantra serve— headless API-only modeDependencies
github.com/go-chi/chi/v5nhooyr.io/websocket(orgorilla/websocketalready in go.mod)