2.0 KiB
Chat engine
Internal conversation service. Bind it to 127.0.0.1 (the default). It is not a public origin.
The Hapi backend keeps JWT and booklet checks, then calls this process with CHAT_ENGINE_URL and CHAT_ENGINE_TOKEN. The Python agent can use ai_agent/chat_engine_client.py the same way. The live LiveKit agent still searches the legacy index until it is pointed here.
npm install
node src/cli.js serve
GET /health and GET /ready are open. Every other route requires Authorization: Bearer matching CHAT_ENGINE_TOKEN or CHAT_ENGINE_TOKEN_PREVIOUS. The comparison is constant-time.
POST /internal/sessionswith{ bookId, userId, channel, modeOverride, meta }returns{ sessionId, mode, bookTitle, vocabularyName, openingLine }POST /internal/sessions/:id/messageswith{ text }writestext/event-stream, including a: heartbeatcomment every 15 secondsPOST /internal/sessions/:id/interruptedwith{ spokenText }keeps only the spoken assistant textPOST /internal/sessions/:id/endstores usage andended_atPOST /sessionsandPOST /sessions/:id/messagesremain for the current Hapi proxy
A book whose status is not completed is rejected. A second message while one is streaming returns 409 unless interrupt is true. Closing the HTTP request aborts the turn. Storage is read-only. Sessions are MySQL chat_sessions, created on startup.
The process role needs S3 read on the book prefix, bedrock:InvokeModel, OpenSearch read (es:ESHttpGet and es:ESHttpPost on the alias), and MySQL SELECT/INSERT/UPDATE on booklets and chat_sessions. It does not need Textract, Transcribe, or index writes.
Environment loads chat-engine/.env, then fills gaps from ingestion/.env and backend/.env. Chat model, cache, and price settings are parsed here. Ingestion does not require them.
node src/cli.js chat --book-id 3 --mode auto --channel chat
node src/cli.js eval --book-id 3 --modes full,hybrid