Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Ask about the property, policies and amenities, or check live room availability, in one conversation.
LifestyleTypeScript · CSSGitHub @yogi-68OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
The Banyan Grove — AI Guest Assistant
A full-stack guest assistant for a hotel website. Guests ask about the property, policies and
amenities in plain language, and check live room availability — in one conversation, without
leaving the page.
The Banyan Grove is a fictional 48-room boutique hotel in Bengaluru, invented for this
project. All rooms, rates and policies are sample data.
Every factual answer carries the fact that justifies it. Tap to read it.
Engine-computed prices, rooms that were ruled out with reasons, and an honest refusal.Read the full README ↗A full-stack guest assistant for a hotel website. Guests ask about the property, policies and amenities in plain language, and check live room availability — in one conversation, without leaving the page.
The Banyan Grove is a fictional 48-room boutique hotel in Bengaluru, invented for this project. All rooms, rates and policies are sample data.
| Document | What it covers |
|---|---|
| README.md (this file) | Setup, how to run, project layout, scripts |
| ARCHITECTURE.md | Components, request lifecycle, data flow, trade-offs |
| PRODUCT_NOTES.md | Product, UX, AI and engineering decisions — the written answers |
| EVALUATION.md | 16 evaluation scenarios and observed results |
| docs/api-examples.md | curl for every endpoint, including failures |
| AI_TOOLS.md | AI tools used while building this |
Requires Node 20.11+ (developed on Node 22/25) and npm 10+.
git clone <your-repo-url> hotel-guest-assistant
cd hotel-guest-assistant
npm install
npm run dev
Open http://localhost:3000. The API runs on http://localhost:4000.
That is the whole setup. No API key, no database, no Docker.
The app defaults to a deterministic offline provider. To use OpenAI:
cd apps/server
cp .env.example .env # if you have not already
# then add your key to apps/server/.env:
# AI_PROVIDER=openai
# OPENAI_API_KEY=sk-...
Restart with npm run dev. .env is gitignored; the key stays in the server process and is never
sent to the browser.
AI_PROVIDER=failing npm run dev
Every answer now comes from the degraded knowledge-base path, with a banner in the UI. The API
still returns 200, never a 500.
.
├── apps/
│ ├── server/ Express + TypeScript API (port 4000)
│ │ ├── src/
│ │ │ ├── ai/ Provider interface, OpenAI, offline mock, resilience, prompt
│ │ │ ├── domain/
│ │ │ │ ├── knowledge/ hotel-kb.json, BM25 retriever, tokenizer
│ │ │ │ ├── availability/ inventory.json, pricing, checkAvailability engine
│ │ │ │ └── conversation/ Session store, slot filling
│ │ │ ├── orchestrator/ The turn pipeline + citation validation
│ │ │ ├── routes/ chat, availability, hotel, health
│ │ │ └── middleware/ requestId, validation, rate limit, error handler
│ │ └── tests/ unit · integration · e2e · eval scenarios
│ └── web/ Next.js 15 + React 19 + Tailwind 4 (port 3000)
│ └── src/
│ ├── components/ ChatShell, MessageBubble, AvailabilityCard, BookingForm…
│ ├── hooks/ useChat state machine, useStickToBottom
│ └── lib/ Typed API client with its own error taxonomy
└── packages/
└── contracts/ Zod schemas + types shared by both sides
Run from the repository root.
| Command | What it does |
|---|---|
npm run dev | Both apps, with hot reload |
npm run build | Production build of both |
npm test | Full suite — 169 tests, offline, no key needed |
npm run test:e2e | 7 end-to-end tests against a real HTTP server |
npm run eval | The 16 evaluation scenarios, with a pass/fail table |
npm run eval -- --live | The same scenarios against the real model |
npm run eval -- --mode=full | Scored with the whole knowledge base in context (A/B baseline) |
npm run typecheck | TypeScript across the workspace |
apps/server/.env — see apps/server/.env.example.
| Variable | Default | Notes |
|---|---|---|
AI_PROVIDER | mock | mock (offline) · openai · failing (fault injection) |
OPENAI_API_KEY | — | Required only when AI_PROVIDER=openai. Validated at boot. |
OPENAI_MODEL | gpt-4o-mini | Any chat-completions model with tool calling |
RETRIEVAL_MODE | lexical | lexical (top-K) or full (entire KB) |
PORT | 4000 | |
WEB_ORIGIN | http://localhost:3000,http://127.0.0.1:3000 | Comma-separated CORS allowlist |
AI_TIMEOUT_MS | 15000 | Per model attempt |
AI_MAX_RETRIES | 2 | Transient failures only |
RATE_LIMIT_MAX | 30 | Requests per minute per IP, on /api/chat only |
apps/web/.env.local — NEXT_PUBLIC_API_BASE_URL (default http://localhost:4000). This is
the only backend configuration the browser sees.
Full request and response examples, including every error case, are in docs/api-examples.md.
| Method | Path | Purpose |
|---|---|---|
POST | /api/chat | Ask a question. Accepts conversation + structured stay context. |
POST | /api/availability | Check rooms deterministically — no model involved. |
GET | /api/hotel | Bootstrap data for the UI (name, rooms, suggested questions). |
GET | /api/health · /api/health/ready | Liveness and readiness. |
curl -s -X POST http://localhost:4000/api/chat \
-H 'Content-Type: application/json' \
-d '{"message":"What time is check-in?"}'
{
"ok": true,
"requestId": "…",
"sessionId": "…",
"reply": { "text": "Check-in starts at 2:00 PM.", "type": "answer", "confidence": 0.91 },
"sources": [{ "id": "F26", "label": "Policies / Check-in time", "text": "Check-in starts at 2:00 PM." }],
"availability": null,
"slots": { "checkIn": null, "checkOut": null, "adults": null, "children": null },
"needs": [],
"suggestions": ["Is breakfast included?"],
"meta": { "provider": "mock", "latencyMs": 3, "toolCalls": [], "grounded": true, "degraded": false }
}
npm test # 169 tests: 138 server, 31 web
npm run test:e2e # 7 real-HTTP end-to-end tests
npm run eval # 16 evaluation scenarios (offline)
Verified against the real model too: npm run eval -- --live scores 16/16 on gpt-4o-mini.
That run is worth reading about in EVALUATION.md — it initially scored 12/16 and
exposed two genuine product bugs that the offline suite could not have found.
Everything runs offline against the deterministic provider, so results are reproducible and CI never calls a paid API. Coverage includes the retriever and its no-context gate, pricing and date maths, citation validation, retry and circuit-breaker behaviour, the conversation state machine, and each failure mode end to end. See EVALUATION.md for scenario-level results.
Port already in use — the API is on 4000 and the web app on 3000. Change with PORT in
apps/server/.env and NEXT_PUBLIC_API_BASE_URL in apps/web/.env.local.
"Invalid server configuration: OPENAI_API_KEY is required" — AI_PROVIDER=openai with no key.
Add the key, or set AI_PROVIDER=mock.
The UI says it cannot reach the hotel — the API is not running, or WEB_ORIGIN does not
include the address you are loading the page from. Check curl http://localhost:4000/api/health.
Answers feel robotic — you are on the offline provider. That is the default. Set
AI_PROVIDER=openai with a key for real language.