{"_id":"@astralibx/chat-engine","_rev":"6-8fdac4c6ea6ac0a6b23549365533fc21","name":"@astralibx/chat-engine","dist-tags":{"latest":"0.4.1"},"versions":{"0.1.1":{"name":"@astralibx/chat-engine","version":"0.1.1","keywords":["chat","socket.io","real-time","session","messaging","agent","redis","faq","widget"],"license":"MIT","_id":"@astralibx/chat-engine@0.1.1","maintainers":[{"name":"astralib","email":"1997hariprakash@gmail.com"}],"homepage":"https://github.com/Hariprakash1997/astralib#readme","bugs":{"url":"https://github.com/Hariprakash1997/astralib/issues"},"dist":{"shasum":"34ccc6bcd608f9c9d23b6fabee160ab4e30427a7","tarball":"https://registry.npmjs.org/@astralibx/chat-engine/-/chat-engine-0.1.1.tgz","fileCount":8,"integrity":"sha512-JFwViF3lqiQrRek+OcEw7L7PFXVufpzxMLzvn3NlDGgaVoYGix2skxXLRg61MoAazJWNTv5MNiiII61OSNK8cg==","signatures":[{"sig":"MEQCIFZfKVWV07bn59xLuxSw43O//nVG8qcZPMxjc/IGEsSoAiBHBL+rr7cLc4lri9lLtXtg7ugPClSqAbFBlNXVwS3pyw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":805663},"main":"dist/index.cjs","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"df956e4b9f30b71fc0ee0eba6b811eee2092bf52","scripts":{"dev":"tsup --watch","lint":"eslint src/","test":"vitest run","build":"tsup","clean":"rm -rf dist","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"astralib","email":"1997hariprakash@gmail.com"},"repository":{"url":"git+https://github.com/Hariprakash1997/astralib.git","type":"git","directory":"packages/chat/chat-engine"},"_npmVersion":"10.9.4","description":"Real-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, and FAQ/guided questions management","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^3.23.0","@astralibx/core":"^1.2.0","@astralibx/chat-types":"^0.1.1"},"_hasShrinkwrap":false,"devDependencies":{"express":"^5.0.0","ioredis":"^5.4.2","mongoose":"^8.12.1","socket.io":"^4.8.0","typescript":"^5.8.2","@types/node":"^22.0.0","@types/express":"^5.0.0","@vitest/coverage-v8":"^3.0.0"},"peerDependencies":{"express":"^4.18.0 || ^5.0.0","ioredis":"^5.0.0","mongoose":"^7.0.0 || ^8.0.0","socket.io":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/chat-engine_0.1.1_1773730923445_0.5992856313877912","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@astralibx/chat-engine","version":"0.1.2","keywords":["chat","socket.io","real-time","session","messaging","agent","redis","faq","widget"],"license":"MIT","_id":"@astralibx/chat-engine@0.1.2","maintainers":[{"name":"astralib","email":"1997hariprakash@gmail.com"}],"homepage":"https://github.com/Hariprakash1997/astralib#readme","bugs":{"url":"https://github.com/Hariprakash1997/astralib/issues"},"dist":{"shasum":"6c2bdaad476539f89f54a3bf0f12300d7ef707cf","tarball":"https://registry.npmjs.org/@astralibx/chat-engine/-/chat-engine-0.1.2.tgz","fileCount":8,"integrity":"sha512-+5wtvYYhtzwM8o0cRMXLVZF5XPXAM8WDl90sB+lqPWI6/Lj5IaI3qxuNnZEENx90LgiHqwppWl+Kwoq2xLljmQ==","signatures":[{"sig":"MEQCIEkMYzbsrCGVWitcALCyWd1cnsJDBKwxBgQdal74MHsUAiBVCbeTJP4j6HwaujJWCpC02ufgx4wQZuImwxbiYjSuoA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":805235},"main":"dist/index.cjs","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"fd42f0db8c9fd08982aee61f94304819cd425d54","scripts":{"dev":"tsup --watch","lint":"eslint src/","test":"vitest run","build":"tsup","clean":"rm -rf dist","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"astralib","email":"1997hariprakash@gmail.com"},"repository":{"url":"git+https://github.com/Hariprakash1997/astralib.git","type":"git","directory":"packages/chat/chat-engine"},"_npmVersion":"10.9.4","description":"Real-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, and FAQ/guided questions management","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^3.23.0","@astralibx/core":"^1.2.1","@astralibx/chat-types":"^0.1.2"},"_hasShrinkwrap":false,"devDependencies":{"express":"^5.0.0","ioredis":"^5.4.2","mongoose":"^8.12.1","socket.io":"^4.8.0","typescript":"^5.8.2","@types/node":"^22.0.0","@types/express":"^5.0.0","@vitest/coverage-v8":"^3.0.0"},"peerDependencies":{"express":"^4.18.0 || ^5.0.0","ioredis":"^5.0.0","mongoose":"^7.0.0 || ^8.0.0","socket.io":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/chat-engine_0.1.2_1773733706925_0.4229855430033249","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@astralibx/chat-engine","version":"0.2.0","keywords":["chat","socket.io","real-time","session","messaging","agent","redis","faq","widget"],"license":"MIT","_id":"@astralibx/chat-engine@0.2.0","maintainers":[{"name":"astralib","email":"1997hariprakash@gmail.com"}],"homepage":"https://github.com/Hariprakash1997/astralib#readme","bugs":{"url":"https://github.com/Hariprakash1997/astralib/issues"},"dist":{"shasum":"b4caceebde5b9965741956bac8471fd651839390","tarball":"https://registry.npmjs.org/@astralibx/chat-engine/-/chat-engine-0.2.0.tgz","fileCount":8,"integrity":"sha512-7i2ekblEzUWk6ea17R2diBhrMG4/O85KRiE/UOI9rypHPMM6DE9Rt5VK0kNHZu+qRS2FrNMCBCRySy9ejHMTwg==","signatures":[{"sig":"MEUCIDMY1HoJ02kliP3FRKe8r+mmQePfIAxIPomPlBBt7sbLAiEAhkLqI/4MzUYUsNj+l/XT8qxKB0JsxCfEJMEZIVdItjk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1010441},"main":"dist/index.cjs","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"b96fb6e63feccf19591d627ddda0c3d04f165ad2","scripts":{"dev":"tsup --watch","lint":"eslint src/","test":"vitest run","build":"tsup","clean":"rm -rf dist","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"astralib","email":"1997hariprakash@gmail.com"},"repository":{"url":"git+https://github.com/Hariprakash1997/astralib.git","type":"git","directory":"packages/chat/chat-engine"},"_npmVersion":"10.9.4","description":"Real-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, and FAQ/guided questions management","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^3.23.0","@astralibx/core":"^1.2.1","@astralibx/chat-types":"^0.2.0"},"_hasShrinkwrap":false,"devDependencies":{"express":"^5.0.0","ioredis":"^5.4.2","mongoose":"^8.12.1","socket.io":"^4.8.0","typescript":"^5.8.2","@types/node":"^22.0.0","@types/express":"^5.0.0","@vitest/coverage-v8":"^3.0.0"},"peerDependencies":{"express":"^4.18.0 || ^5.0.0","ioredis":"^5.0.0","mongoose":"^7.0.0 || ^8.0.0","socket.io":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/chat-engine_0.2.0_1773814059827_0.01397490993730055","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@astralibx/chat-engine","version":"0.3.0","keywords":["chat","socket.io","real-time","session","messaging","agent","redis","faq","widget"],"license":"MIT","_id":"@astralibx/chat-engine@0.3.0","maintainers":[{"name":"astralib","email":"1997hariprakash@gmail.com"}],"homepage":"https://github.com/Hariprakash1997/astralib#readme","bugs":{"url":"https://github.com/Hariprakash1997/astralib/issues"},"dist":{"shasum":"4fc5b7d4dfb1ffc3930415b7e16aa527aba2e34b","tarball":"https://registry.npmjs.org/@astralibx/chat-engine/-/chat-engine-0.3.0.tgz","fileCount":8,"integrity":"sha512-QV+ZlSafvl1tFshFJgAeKfVA4D0y5uN5hPG8Nqz+vJxgB/CkEZzPz+ZSvV9g6bo/lmzARpxj9yhx7wwlTnrFOA==","signatures":[{"sig":"MEQCIEAeHKfdu9uvMuic5KITFbji1Ca6vgvqJZasz4q5ysYJAiBWatafTNFVWo15KXS/RvBkCw6P/tOghbs1D3gwCEkOXw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1736460},"main":"dist/index.cjs","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"ae1365ff1004be6b7ef07ac5ca5a5d6d8d9a6fa6","scripts":{"dev":"tsup --watch","lint":"eslint src/","test":"vitest run","build":"tsup","clean":"rm -rf dist","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"astralib","email":"1997hariprakash@gmail.com"},"repository":{"url":"git+https://github.com/Hariprakash1997/astralib.git","type":"git","directory":"packages/chat/chat-engine"},"_npmVersion":"10.9.4","description":"Real-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, and FAQ/guided questions management","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^3.23.0","@astralibx/core":"^1.2.1","@astralibx/chat-types":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"express":"^5.0.0","ioredis":"^5.4.2","mongoose":"^8.12.1","socket.io":"^4.8.0","typescript":"^5.8.2","@types/node":"^22.0.0","@types/express":"^5.0.0","@vitest/coverage-v8":"^3.0.0"},"peerDependencies":{"express":"^4.18.0 || ^5.0.0","ioredis":"^5.0.0","mongoose":"^7.0.0 || ^8.0.0","socket.io":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/chat-engine_0.3.0_1773917001742_0.9509214534694832","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@astralibx/chat-engine","version":"0.4.0","keywords":["chat","socket.io","real-time","session","messaging","agent","redis","faq","widget"],"license":"MIT","_id":"@astralibx/chat-engine@0.4.0","maintainers":[{"name":"astralib","email":"1997hariprakash@gmail.com"}],"homepage":"https://github.com/Hariprakash1997/astralib#readme","bugs":{"url":"https://github.com/Hariprakash1997/astralib/issues"},"dist":{"shasum":"4db01317bda144793486450da13da05af00fcbab","tarball":"https://registry.npmjs.org/@astralibx/chat-engine/-/chat-engine-0.4.0.tgz","fileCount":8,"integrity":"sha512-tUIs3fjeTS9yG0pYb6NyOQiwdeg3BcJ9FSb10HNmmFhPdIxlccO6P/Wt35h4+gVyMH/i83cO1DW+wOZRpTjPcA==","signatures":[{"sig":"MEUCIQCfYRii3DcDGSAk9P3ZZJB0043KgZOXD8FEvux9rkCRfAIgN1nbgOimX02rMd5w7oacLAOjUD7Uv+QiZGo4MoT5C88=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1788330},"main":"dist/index.cjs","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"4d2a55b3968e55f083d4a957eb2319acb1fa5ba3","scripts":{"dev":"tsup --watch","lint":"eslint src/","test":"vitest run","build":"tsup","clean":"rm -rf dist","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"astralib","email":"1997hariprakash@gmail.com"},"repository":{"url":"git+https://github.com/Hariprakash1997/astralib.git","type":"git","directory":"packages/chat/chat-engine"},"_npmVersion":"10.9.4","description":"Real-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, and FAQ/guided questions management","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^3.23.0","@astralibx/core":"^1.2.1","@astralibx/chat-types":"^0.4.0"},"_hasShrinkwrap":false,"devDependencies":{"express":"^5.0.0","ioredis":"^5.4.2","mongoose":"^8.12.1","socket.io":"^4.8.0","typescript":"^5.8.2","@types/node":"^22.0.0","@types/express":"^5.0.0","@vitest/coverage-v8":"^3.0.0"},"peerDependencies":{"express":"^4.18.0 || ^5.0.0","ioredis":"^5.0.0","mongoose":"^7.0.0 || ^8.0.0","socket.io":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/chat-engine_0.4.0_1773998151171_0.09278767330724724","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@astralibx/chat-engine","version":"0.4.1","description":"Real-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, and FAQ/guided questions management","repository":{"type":"git","url":"git+https://github.com/Hariprakash1997/astralib.git","directory":"packages/chat/chat-engine"},"main":"dist/index.cjs","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.ts","default":"./dist/index.cjs"}}},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","lint":"eslint src/","clean":"rm -rf dist"},"keywords":["chat","socket.io","real-time","session","messaging","agent","redis","faq","widget"],"license":"MIT","dependencies":{"@astralibx/chat-types":"^0.4.0","@astralibx/core":"^1.2.1","zod":"^3.23.0"},"peerDependencies":{"express":"^4.18.0 || ^5.0.0","mongoose":"^7.0.0 || ^8.0.0","socket.io":"^4.0.0","ioredis":"^5.0.0"},"devDependencies":{"@types/express":"^5.0.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^3.0.0","express":"^5.0.0","ioredis":"^5.4.2","mongoose":"^8.12.1","socket.io":"^4.8.0","typescript":"^5.8.2"},"_id":"@astralibx/chat-engine@0.4.1","gitHead":"0488f44a86c3dd1c854677012a7978c30f317df3","bugs":{"url":"https://github.com/Hariprakash1997/astralib/issues"},"homepage":"https://github.com/Hariprakash1997/astralib#readme","_nodeVersion":"22.22.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-RsRIoEme7E919aYASwPyyKlLZ0t6kI064BxP7YxEsmwP94Dtfit0NVzAHgCNT66DbTxLDX5F+e5Jckbp3HjgQw==","shasum":"641fb60010345bf379fd632958237a0285cc817d","tarball":"https://registry.npmjs.org/@astralibx/chat-engine/-/chat-engine-0.4.1.tgz","fileCount":8,"unpackedSize":1795621,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIH65CEap+kzPT3xu1r3ltoWCE77qisuz/KL6FNktusLnAiEAzV2iEywxY7dfXdbFmG18TmaEtSXHYRTiMULvwkTjeIM="}]},"_npmUser":{"name":"astralib","email":"1997hariprakash@gmail.com"},"directories":{},"maintainers":[{"name":"astralib","email":"1997hariprakash@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/chat-engine_0.4.1_1774230935893_0.8506024620269865"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-17T07:02:03.340Z","modified":"2026-03-23T01:55:36.509Z","0.1.1":"2026-03-17T07:02:03.598Z","0.1.2":"2026-03-17T07:48:27.088Z","0.2.0":"2026-03-18T06:07:40.019Z","0.3.0":"2026-03-19T10:43:21.906Z","0.4.0":"2026-03-20T09:15:51.348Z","0.4.1":"2026-03-23T01:55:36.059Z"},"bugs":{"url":"https://github.com/Hariprakash1997/astralib/issues"},"license":"MIT","homepage":"https://github.com/Hariprakash1997/astralib#readme","keywords":["chat","socket.io","real-time","session","messaging","agent","redis","faq","widget"],"repository":{"type":"git","url":"git+https://github.com/Hariprakash1997/astralib.git","directory":"packages/chat/chat-engine"},"description":"Real-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, and FAQ/guided questions management","maintainers":[{"name":"astralib","email":"1997hariprakash@gmail.com"}],"readme":"# @astralibx/chat-engine\n\n[![npm version](https://img.shields.io/npm/v/@astralibx/chat-engine.svg)](https://www.npmjs.com/package/@astralibx/chat-engine)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nReal-time chat engine with Socket.IO gateway, session lifecycle, message routing, agent management, Redis caching, rate limiting, FAQ/guided questions management, and REST admin API.\n\n## Install\n\n```bash\nnpm install @astralibx/chat-engine\n```\n\n### Peer Dependencies\n\n| Package | Required |\n|---------|----------|\n| `express` | Yes |\n| `mongoose` | Yes |\n| `socket.io` | Yes |\n| `ioredis` | Yes |\n\n```bash\nnpm install express mongoose socket.io ioredis\n```\n\n## Requirements\n\nRedis is **mandatory** for chat-engine. It handles:\n- Visitor/agent connection tracking\n- Rate limiting\n- Session activity tracking\n- AI response locking\n- Pending message storage\n- Typing indicator debounce\n\nThere is no in-memory fallback. Provide a Redis connection via `redis.connection`.\n\n## Quick Start\n\n```ts\nimport { createChatEngine } from '@astralibx/chat-engine';\nimport mongoose from 'mongoose';\nimport Redis from 'ioredis';\nimport express from 'express';\nimport { createServer } from 'http';\n\nconst app = express();\napp.use(express.json());\n\nconst connection = mongoose.createConnection('mongodb://localhost:27017/chat');\nconst redis = new Redis();\n\nconst engine = createChatEngine({\n  db: { connection, collectionPrefix: '' },\n  redis: { connection: redis, keyPrefix: 'chat:' },\n  socket: {\n    cors: { origin: ['https://example.com'], credentials: true },\n    namespaces: { visitor: '/chat', agent: '/agent' },\n  },\n  adapters: {\n    assignAgent: async (context) => {\n      // Return an available agent or null for queue\n      return null;\n    },\n  },\n});\n\n// Mount REST routes\napp.use('/api/chat', engine.routes);\n\n// Attach Socket.IO gateway\nconst httpServer = createServer(app);\nengine.attach(httpServer);\nhttpServer.listen(3000);\n```\n\n## Full Setup with AI\n\n```ts\nconst engine = createChatEngine({\n  db: { connection },\n  redis: { connection: redis, keyPrefix: 'myapp:chat:' },\n  socket: {\n    cors: { origin: ['https://myapp.com'], credentials: true },\n  },\n  adapters: {\n    assignAgent: async (context) => {\n      // Find least busy online agent\n      const agent = await engine.agents.findLeastBusy();\n      return agent ? engine.agents.toAgentInfo(agent) : null;\n    },\n    generateAiResponse: ai.generateResponse,  // from @astralibx/chat-ai\n    authenticateAgent: async (token) => {\n      const user = await verifyJWT(token);\n      return user ? { adminUserId: user.id, displayName: user.name } : null;\n    },\n  },\n  hooks: {\n    onSessionCreated: (session) => console.log('New chat:', session.sessionId),\n    onEscalation: (sessionId) => notifySlack(`Chat ${sessionId} needs human agent`),\n    onMetric: (metric) => prometheus.observe(metric.name, metric.value, metric.labels),\n  },\n});\n```\n\n## Features\n\n### Messaging & Real-time\n\n- **Real-time messaging** -- Socket.IO gateway with visitor and agent namespaces, typing indicators, read receipts, and pending message delivery for offline visitors. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/socket-events.md)\n- **Typing throttle** -- Visitor typing events are automatically throttled server-side (max 1 per 2s) with 30-second auto-timeout to prevent flooding.\n- **Pending message queue** -- Messages sent while a visitor is disconnected are stored in Redis and delivered automatically on reconnect.\n- **Rate limiting** -- Per-session message rate limiting via Redis (default: 30/min). Rejects excess messages with `RATE_LIMIT_EXCEEDED` error code. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/configuration.md)\n- **File sharing validation** -- Per-message file type and size validation against configurable allowed MIME types and max file size before upload. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/file-uploads.md)\n\n### Sessions\n\n- **Session lifecycle** -- Create, resume, resolve, abandon sessions with idle timeout, reconnect window, and feedback collection. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Session resumption window** -- Abandoned sessions can be resumed within a configurable time window (`sessionResumptionMs`, default 24h). Resolved/closed sessions never resume.\n- **Single session per visitor** -- When enabled (default), reuses the most recent active session for the same visitor across tabs/devices instead of creating duplicates.\n- **Session visibility window** -- Sessions auto-extend their `visibleUntil` timestamp on every visitor message. Expired sessions are hidden from the dashboard. Configurable via `sessionVisibilityMs`.\n- **Session tags** -- Add/remove tags on sessions from a configurable pool (`availableTags`). Available via REST API and socket events.\n- **Session notes** -- Agents can write and delete notes on any session. Notes persist across agent transfers.\n- **Session context export** -- Programmatic `getSessionContext(sessionId)` returns full snapshot: session summary, all messages, preferences, conversation summary, feedback, and metadata. Useful for AI input and handoff.\n\n### AI Engine\n\n- **Two-layer AI mode** -- Global AI mode (`manual`, `ai`, `agent-wise`) with per-agent overrides. Resolution: agent-level `modeOverride`/`aiEnabled` takes precedence over global mode when `allowPerAgentMode` is enabled. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/adapters.md)\n\n> **`generateAiResponse` return type** -- The adapter must return `AiResponseOutput` from `@astralibx/chat-types`:\n>\n> ```ts\n> import type { AiResponseOutput } from '@astralibx/chat-types';\n>\n> // AiResponseOutput shape:\n> {\n>   messages: string[];              // array for multi-bubble, single item for one message\n>   conversationSummary?: string;    // stored on session, passed to next AI call\n>   shouldEscalate?: boolean;        // true = auto-escalate to human agent\n>   escalationReason?: string;       // reason shown in system message\n>   extracted?: Record<string, unknown>;  // extracted contact data\n>   memoryHints?: MemoryHint[];      // memory management hints\n>   metadata?: Record<string, unknown>;\n> }\n> ```\n- **AI message debouncing** -- When a visitor sends rapid messages, the engine accumulates them and sends a single AI response after a configurable delay (`aiDebounceMs`, default 15s). Prevents AI flooding.\n- **Multi-bubble AI responses** -- AI adapter can return an array of messages. Engine delivers them sequentially with configurable inter-bubble delays, typing indicators, and realistic timing simulation.\n- **Realistic typing simulation** -- Full delivery lifecycle: delivery delay (300-1000ms) → read delay (scales with message length) → pre-typing pause (500-1500ms) → typing indicator (based on message length) → message sent. All delays configurable via `aiSimulation` config.\n- **AI character profiles** -- Configure AI personality per-agent or globally: name, tone, personality (required), plus optional responseStyle, rules, formality, emojiUsage, expertise, bio. Agent-level character overrides global. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/configuration.md)\n- **Conversation summarization** -- AI adapter can return a `conversationSummary` string alongside messages. Engine stores it on the session and passes it to subsequent AI calls for long-term context.\n- **AI auto-escalation** -- AI adapter can return `shouldEscalate: true` with an optional `escalationReason`. Engine automatically escalates to human agent, creates a system message, notifies all agents, and fires the `onEscalation` hook.\n- **Agent-initiated AI messages** -- Agents can trigger AI responses on-demand via the `SendAiMessage` socket event. Engine resolves the AI character, generates the response, delivers multi-bubble messages, and broadcasts to all connected agents.\n- **AI request lifecycle** -- `onAiRequest` hook fires at `received`, `completed`, and `failed` stages with `durationMs` tracking. 30-second timeout on AI generation. AI lock prevents concurrent responses per session.\n- **Training quality labels** -- Agents can label individual messages and sessions as `good`, `bad`, or `needs_review` for ML training data. Gated by `labelingEnabled` config (default: off). [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/socket-events.md)\n\n### Agents & Teams\n\n- **Agent management** -- CRUD agents, online/offline tracking, concurrent chat limits, chat transfer between agents. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Team hierarchy & escalation** -- Multi-level agent hierarchy with teams, direct reports, and tree views for structured escalation paths. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Escalation** -- Visitor-initiated escalation from AI to human agent with auto-assignment and queue management. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/socket-events.md)\n- **Agent activity tracking** -- Per-agent activity timestamps stored in Redis on every significant action (connect, accept, send, resolve, transfer). Used for \"last seen\" tracking.\n- **Agent multi-tab support** -- Per-agent connection count tracking in Redis. Agents can open the dashboard in multiple tabs; each connection is tracked separately.\n- **Manager chat watching** -- Managers (agents with `isManager` flag) can subscribe to any active session via `WatchChat` event. Read-only observation with real-time message sync. Managers see all active sessions on connect.\n- **Support person discovery** -- Visitors can fetch a list of available public agents (`FetchSupportPersons`) and select a preferred agent (`SetPreferredAgent`). Gated by `visitorAgentSelection` setting. In fixed chat mode, agent switching is only allowed if the current agent is offline.\n\n### Visitor Identity\n\n- **User identity resolution** -- `resolveUserIdentity` adapter called on visitor connect. Can return `userId` or `{ userId, userCategory }` for priority routing. If resolved userId differs from current visitorId, all anonymous sessions are automatically merged to the authenticated identity.\n- **User conversation history** -- `getUserHistory(visitorId)` returns up to N past sessions (configurable via `userHistoryLimit`, default 5). Gated by `userHistoryEnabled` setting.\n- **User info storage** -- Store visitor name, email, mobile on sessions via `updateUserInfo()`. Populated via identify event, REST API, or data extraction adapters.\n\n### Queue & Assignment\n\n- **Queue position tracking** -- Dynamic queue position recalculation when agents accept or resolve chats. Wait time estimation based on last 50 resolved sessions' average duration, number of online agents, and queue position.\n\n### Analytics & Monitoring\n\n- **Dashboard real-time stats** -- `getDashboardStats()` returns active sessions, waiting sessions, resolved today, total agents, active agents. Automatically broadcast to all connected agents via `agent:stats_update` after every significant event (connect, accept, resolve, status change). Also available via `GET /stats` REST endpoint. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Analytics & reports** -- Agent performance reports, overall chat reports, session export (JSON/CSV), and visitor analytics collection with per-field privacy controls (`collectIp`, `collectBrowser`, `collectLocation`, etc.). [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Webhooks** -- 8 event types with HMAC signature verification, retry logic, and REST management API. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/webhooks.md)\n- **Lifecycle hooks** -- 20+ hooks for session events, messages, escalation, AI lifecycle, memory, metrics, and errors. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/hooks.md)\n\n### Configuration & Admin\n\n- **Multi-tenant** -- Shared database with automatic tenant scoping on all queries and creates. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/multi-tenant.md)\n- **File uploads** -- Pluggable file storage adapter (S3, GCS, local disk) with admin controls for size/type restrictions and MIME validation. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/file-uploads.md)\n- **Rating & feedback** -- Configurable rating types (thumbs/stars/emoji) with two-step follow-up flow. Supports both new (typed rating + follow-up) and legacy (1-5 numeric) submission paths. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/rating-feedback.md)\n- **Business hours** -- Per-day schedule with timezone support, holiday dates, and configurable outside-hours behavior. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/configuration.md)\n- **FAQ and guided questions** -- CRUD, reorder, import, category filtering. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Canned responses** -- Pre-built agent replies with category and search support. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Widget config** -- Public endpoint for client widget configuration. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md)\n- **Pluggable adapters** -- Authentication, agent assignment, AI generation, visitor identification, file storage, event tracking. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/adapters.md)\n- **Error classes** -- Typed errors with codes for every failure scenario. [Details](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/error-handling.md)\n\n## Architecture\n\nThe library exposes an Express router and a Socket.IO gateway from a single factory call:\n\n| Export | Purpose | Access |\n|--------|---------|--------|\n| `engine.routes` | REST admin API -- sessions, agents, FAQ, settings, stats | Protected (add your auth middleware) |\n| `engine.attach(httpServer)` | Socket.IO gateway -- visitor and agent namespaces | WebSocket (adapter-authenticated) |\n\nAll services are also available programmatically via the returned `engine` object.\n\n## Getting Started Guide\n\n1. [Configuration](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/configuration.md) -- Set up database, Redis, socket, and options\n2. [Adapters](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/adapters.md) -- Implement agent assignment, AI, authentication, and file storage\n3. [Hooks](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/hooks.md) -- Wire up analytics, logging, and monitoring\n\nGuides: [Webhooks](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/webhooks.md) | [Multi-Tenant](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/multi-tenant.md) | [File Uploads](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/file-uploads.md) | [Rating & Feedback](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/rating-feedback.md)\n\nReference: [API Routes](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/api-routes.md) | [Socket Events](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/socket-events.md) | [Error Handling](https://github.com/Hariprakash1997/astralib/blob/main/packages/chat/chat-engine/docs/error-handling.md)\n\n### Redis Key Prefix (Required for Multi-Project Deployments)\n\n> **WARNING:** If multiple projects share the same Redis server, you MUST set a unique `keyPrefix` per project. Without this, sessions and connection state will collide across projects.\n\n```ts\nconst engine = createChatEngine({\n  redis: {\n    connection: redis,\n    keyPrefix: 'myproject-chat:', // REQUIRED if sharing Redis\n  },\n  // ...\n});\n```\n\n## Links\n\n- [GitHub](https://github.com/Hariprakash1997/astralib/tree/main/packages/chat/chat-engine)\n- [chat-types](https://github.com/Hariprakash1997/astralib/tree/main/packages/chat/chat-types)\n\n## License\n\nMIT\n","readmeFilename":"README.md"}