Skip to content

Latest commit

 

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Benney Prism

An AI concierge that lives in your hotel room 24/7. No cameras, no microphones — only ambient signals (door open/close, booking metadata, flight

  • traffic lookups) and the guest's persona keywords. Two agents shipping today, a third pluggable.
  1. Trip planner — a custom-trained personality-aligned neural network compresses the guest's 15-keyword profile into a 384-D vector, KNN's them against 61,824 synthetic families, and aggregates which activity each similar family chose at this slot. Probabilistic itinerary planner with per-slot bands ("45% of similar families chose Stanford"), bootstrap CIs, and Claude Haiku 4.5-narrated reasoning per pick. Jet-lag aware via the Forger–Jewett–Kronauer 1999 circadian limit-cycle oscillator — the model down-weights high-energy activities at slots that fall on the guest's body-clock night.
  2. Staff assistant — ambient room-event ingester. Door open/close + itinerary + AviationStack flight data + Google Maps traffic → Haiku-narrated action cards for housekeeping, room service, and arrival prep. "Quick turn now, 24 min before return", "Start sous-vide 12:51 to hit door hot at 1:22", "Welcome ready 2:20 PM, UA742 delayed 35 min."

Both share a single 15-keyword family encoder + a sentence-transformers activity bank, so a third agent (restaurant picker, concierge chat) plugs in by swapping the bank.

Voice agent

Benney also has a voice. The mic button on the prism wires browser STT → /voice endpoint → Claude Haiku 4.5 (with Rosewood Sand Hill property context + the guest's persona + current itinerary state) → ElevenLabs TTS. The cat rig has 35+ animation states; emotion tags returned by Claude (<emotion>excited</emotion>) drive the visual reaction live as Benney speaks. Without API keys the endpoint falls back to a silent stub so the demo still works.

Voice flow:

mic press → SpeechRecognition (browser, free) → POST /voice
  → Claude reply with <emotion>tag</emotion>
  → ElevenLabs TTS (base64 mp3)
  → cat shifts to listening/thinking/speaking/happy as states unfold

Why a population-of-personas model (not a chatbot)

Recommendations come from the behaviour of similar guests, not from an LLM guessing what's nice. Each synthetic family in the cohort has its own 30-slot itinerary, generated by a scheduler that respects open hours, slot-of-day, geographic continuity, and a graduated repetition penalty. When a new guest queries /next-slot, the aggregator finds their nearest 1,000 synthetic neighbours, filters those down by Jaccard trajectory match to their picks so far, and tallies what that subpopulation chose. The recommendation is a probability distribution with confidence intervals, not a single answer.

In production we'd swap the synthetic cohort for real prior-guest data and the recommendations become continuously more accurate.

Benney the cat's name + design come from Rosewood Amsterdam, where the real Benney is the property's mascot.

Layout

hotel_agents/
├── shared/             — Family schema, FamilyEncoder, embedding cache
├── trip_planner/       — FitScorer, scheduler, PopulationAggregator, /next-slot
├── staff_assistant/    — state machine, predictors, AviationStack + Google Maps, /staff-feed
├── scripts/            — augment_cohort.py, merge_*.py, train_fit_scorer.py
├── checkpoints/        — family_encoder.pt, fit_scorer.pt, activity_bank.pt
└── data/               — activities_bay.json (190), families.jsonl (384 cleaned)

frontend/               — drop-in React components for the prism UI
├── TripPlannerLive.tsx + .css     (?trip=1)
└── StaffBoardLive.tsx + .css      (?staff=1)

Quick start

# 1. Python env
pip install -r hotel_agents/requirements.txt

# 2. Build the activity bank (sentence-transformers embeddings → checkpoints/activity_bank.pt)
python -m hotel_agents.scripts.build_activity_bank

# 3. Generate the cohort (61k families × 30 slots, ~30 min CPU / ~10 min on a Blackwell)
python -m hotel_agents.scripts.augment_cohort --keep-seeds

# 4. Run the servers
uvicorn hotel_agents.trip_planner.server:app  --port 7878   # trip planner
uvicorn hotel_agents.staff_assistant.server:app --port 7879  # staff assistant

# 5. Seed the staff demo
python -m hotel_agents.staff_assistant.seed_demo

Drop frontend/*.tsx + .css into a Vite/React app's src/sides/. Route ?trip=1TripPlannerLive, ?staff=1StaffBoardLive. Both poll the servers above; configure VITE_BENNEY_API and VITE_STAFF_API if not on localhost.

Architecture

Guest 15-kw profile  ─┐
                      ├─▶  FamilyEncoder ─▶ family_vec (384-D)
                      │
Activity description ─┘─▶  Sentence-Transformers ─▶ activity_vec (384-D)

family_vec + activity_vec + slot_idx + history_vec
        │
        ▼
   FitScorer (ResNet MLP, 91% val accuracy on Sonnet-cleaned data)
        │
        ▼
  Schedule(family) ─────────────► 30-slot itinerary  ─┐
                                                       │
  Augment(seed × 160) × Schedule ─► 61k cohort npz ◄───┘
                                                       │
                                                       ▼
                                               PopulationAggregator
                                                       │
                                                       ▼
                                          GET /next-slot ─► probabilities
                                          POST /reasoning ─► Haiku narration

For the staff assistant:

door_open / door_close / food_order / flight_update
        │
        ▼
    RoomState (in_room, slot_idx, pending_order, arrival_flight)
        │
        ▼
   Predictor (heuristic, no ML) ─► Prediction
                                    (return_time, cleaning_window,
                                     food_cook_start, arrival_setup)
        │
        ▼
    Narrator (Haiku 4.5, cached) ─► ActionCard

Why this design

  • Closed-vocabulary 15-kw family profile so the encoder learns clean decision boundaries — no free-text drift.
  • KNN + Jaccard trajectory filter so the per-slot probabilities reflect families whose first N slots match the current guest's, not the whole cohort.
  • Bootstrap CIs + vs-baseline annotation so the UI can render "popular / standard / niche / buried" bands and stop pretending every recommendation is equally confident.
  • Hard slot-open mask + tag boost + distance penalty + graduated repetition penalty at schedule time, so the model doesn't put museums at breakfast or send the guest from SF to Napa for lunch then back to SF for dinner.

License

MIT.

About

Benney Prism — projection-mapped hotel-room AI: trip planner (KNN over 50k synthetic families) + staff assistant (ambient signals, room service timing, arrival prep)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages