The Hayley Chat Adapter Microservice is an orchestration layer that processes conversational AI queries for property management platforms. It acts as the central hub between the Hayley AI Engine (ML/NLP) and all downstream services.
Core responsibilities:
node,Β rag,Β fixed,Β adapter,Β spf)Client
βββΊ FastAPI Server (Port 6000)
βββΊ Hayley Chat Adapter
βββΊ Hayley Engine (ML/NLP)
βββΊ Translate to Human (Spanish)
βββΊ Agent Handoff Service
βββΊ GraphQL API (Message Persistence)
| Layer | Technology | Version |
|---|---|---|
| Web Framework | FastAPI | β₯ 0.111.0 |
| ASGI Server | Uvicorn | 0.30.1 |
| Validation | Pydantic | latest |
| HTTP Client | requests, aiohttp | latest |
| NLP | spaCy + en_core_web_md | β₯ 3.7.0 |
| Phone Parsing | phonenumbers | β₯ 8.13.0 |
| Caching | fastapi-cache2 (InMemory) | latest |
| Token Counting | tiktoken (cl100k_base) | latest |
| Logging | loguru | latest |
| LLM Observability | Langfuse | β₯ 3.11.2 |
| Distributed Tracing | OpenTelemetry | β₯ 1.28.0 |
| Config | PyYAML | latest |
hayley-chat-adapter-microservice/
βββ app.py β FastAPI entrypoint, endpoints, Langfuse init
βββ config.yaml β Environment-specific service URLs
βββ requirements.txt β Python dependencies
βββ Dockerfile β Docker build (exposes port 6000)
βββ .env β Secrets and environment variables
β
βββ bean/
β βββ chat_adapter_response.py β Pydantic response model
β
βββ utils/
β βββ chat_adapter.py β Core orchestration logic
β βββ utils.py β GraphQL, caching, contact extraction
β βββ arguments.py β Constants and defaults
β βββ constants.py β System-wide constants
β
βββ deployments/
βββ qa/Jenkinsfile
βββ stg/Jenkinsfile
βββ prod/Jenkinsfile
1. POST /chat_adapter received
2. Pydantic validates request β 400 on failure
3. Trim history to last 4 messages
4. Call Hayley Engine
5. Format response by retrieval_type:
"node" + "neighborhood_summary" β verbose response
"node" β format_node_response_to_markdown()
"rag|fixed|adapter|spf" β concise response
6. Extract contact info (if sub_intent matches)
7. createHayleyMessage [question] via GraphQL
8. Fire async agent handoff (non-blocking)
9. createHayleyMessage [answer] via GraphQL
10. Return assembled response with trace_id
Health check β no request body required.
Response
{
"success": 200
}
Request
{
"propertyId": "1234567890123456789",
"message": "Show me available 2-bedroom apartments",
"orgId": "9876543210987654321",
"session_id": "aaaabbbbccccddddeeeeffffgggghhhh",
"conversation_id": "1111111111111111111",
"graphql_api_key": "Rjp3U6OfhyuxMVSYHCJErDlFeZamWs5QwIX4dKik",
"tourScheduleEnabled": true,
"history": [
{ "role": "user", "content": "Hello" },
{ "role": "assistant", "content": "Hi! How can I help?" }
],
"entry_id": "optional-entry-id",
"booking_id": "optional-booking-id",
"reschedule_information": {},
"schedule_information": {},
"spanish_support_enabled": false,
"spanish_toggle": false,
"is_first_entry": false
}
Field Validation Rules
| Field | Format | Required |
|---|---|---|
| propertyId | 19-digit string or Base64 | Yes |
| orgId | 19-digit string or Base64 | Yes |
| session_id | MD5 hash, UUID v4, orΒ fake_hyly_session_id | Yes |
| conversation_id | 19-digit string or Base64 | Yes |
| graphql_api_key | Base64URLΒ ^[A-Za-z0-9_-]+$ | Yes |
| tourScheduleEnabled | boolean | Yes |
| history | array ofΒ { role, content } | Yes |
| entry_id | string | No |
| booking_id | string | No |
| reschedule_information | object | No |
| schedule_information | object | No |
| spanish_support_enabled | boolean (default: false) | No |
| spanish_toggle | boolean (default: false) | No |
| is_first_entry | boolean (default: false) | No |
Response
{
"response": "Here are available 2-bedroom units at...",
"intent": "property_search",
"sub_intent": "unit_availability",
"message_id": "1709542253522009420",
"retrieval_type": "node",
"orchestrator_level1_details": {},
"orchestrator_level2_details": {},
"keyword_cache": { "bedrooms": 2 },
"not_available": [],
"context": null,
"follow_up": "Would you like to schedule a tour?",
"latency": {
"hayley_engine_latency": 1234,
"chat_adapter_latency": 2456,
"extract_and_update_contact_latency": 45,
"create_message_latency": 312
},
"language": "en",
"agent_handoff": null,
"memory": null,
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
Error Responses
// 400 β Validation error
{ "detail": { "message": "Invalid propertyId format", "trace_id": "4bf92f35..." } }
// 500 β Internal error
{ "detail": { "message": "Unexpected error", "trace_id": "4bf92f35..." } }
// 503 β Downstream unavailable
{ "detail": "Service temporarily unavailable" }
| Environment | Base URL | Health Check |
|---|---|---|
| QA | http://0.0.0.0:6000 | http://0.0.0.0:6000/heartbeat |
| STG | https://stg2-ml.hyly.us | https://stg2-ml.hyly.us/.../heartbeat |
| Prod | https://ml2.hy.ly | https://ml2.hy.ly/.../heartbeat |
Downstream Services by Environment
| Service | QA | STG | Prod |
|---|---|---|---|
| Hayley Engine | http://0.0.0.0:2600/hayley_engine | https://stg2-ml.hyly.us/hayley_engine_microservice/hayley_engine | https://ml2.hy.ly/hayley_engine_microservice/hayley_engine |
| Translate to Human | http://0.0.0.0:7500/tth | https://stg2-ml.hyly.us/hayley_translate_to_human_microservice/tth | https://ml2.hy.ly/hayley_translate_to_human_microservice/tth |
| Agent Handoff | https://qa.hyly.us/leads_api/v1/hayley/agent_handoff | https://my.hyly.us/leads_api/v1/hayley/agent_handoff | https://my.hy.ly/leads_api/v1/hayley/agent_handoff |
| GraphQL API | https://qa.hyly.us/graphql | https://my.hyly.us/graphql | https://my.hy.ly/graphql |
| Service | Purpose |
|---|---|
| Hayley Engine | ML/NLP β intent classification and response generation |
| Translate to Human | Spanish translation whenΒ spanish_toggle=true |
| Agent Handoff | Human escalation β async fire-and-forget viaΒ hyly_agent_handoffΒ package |
| GraphQL API | Message persistence βΒ createHayleyMessage,Β updateHayleyConversation |
| Endpoint | Purpose |
|---|---|
/api/v1/units | Retrieve property unit data |
/api/v1/floor_plans/ | Fetch floor plan information |
/api/v1/apartments/all_type_available_time_slots | Get available tour time slots |
/api/v1/hayley/google_query | Extract neighborhood keywords |
/api/v1/properties/api_token | Fetch GraphQL API token |
| Package | Version | Purpose |
|---|---|---|
| fastapi | β₯ 0.111.0 | Web framework |
| uvicorn | 0.30.1 | ASGI server |
| spacy + en_core_web_md | β₯ 3.7.0 | Named entity recognition |
| phonenumbers | β₯ 8.13.0 | Phone number parsing |
| langfuse | β₯ 3.11.2 | LLM observability |
| opentelemetry-api/sdk | β₯ 1.28.0 | Distributed tracing |
| fastapi-cache2 | latest | In-memory caching |
| tiktoken | latest | Token counting |
| loguru | latest | Structured logging |
| hyly_agent_handoff | git (main) | Agent handoff client |
# Deployment target
ENVIRONMENT="qa|staging|prod"
# Langfuse β LLM Observability
LANGFUSE_PUBLIC_KEY="pk-lf-..."
LANGFUSE_SECRET_KEY="sk-lf-..."
LANGFUSE_BASE_URL="https://langfuse.hyly.us"
LANGFUSE_DEBUG="false"
# GraphQL API Keys (per environment)
graphql_api_key="..." # QA
graphql_api_key_stg="..." # Staging
graphql_api_key_prod="..." # Prod
# GraphQL Endpoint URLs
GRAPHQL_QA_URL="https://qa.hyly.us/graphql"
GRAPHQL_STG_URL="https://my.hyly.us/graphql"
GRAPHQL_PROD_URL="https://my.hy.ly/graphql"
# GraphQL Authorization Headers
GRAPHQL_KEY_QA="userid___1709542253522009420"
GRAPHQL_KEY_STAGING="userid___1777464981952577365"
GRAPHQL_KEY_PROD="myhyly-hyblast-sync"
# Tracing
DISABLE_TRACING="false"
| Constant | Value | Description |
|---|---|---|
CACHE_TIMEOUT | 7200 | Session cache TTL in seconds (2 hours) |
cache_retrieve_threshold | 0.98 | Cache similarity threshold |
| Max history (cache) | 8 | Max messages kept per session |
| Max history (engine call) | 4 | Messages forwarded to Hayley Engine |
| Contact extraction triggers | customer_info,Β contact,Β complaint_filing,Β agent_hand_off,Β emergency_maintenance | Sub-intents that trigger NER extraction |
pip install -r requirements.txt
export ENVIRONMENT=qa
uvicorn app:app --reload --host 0.0.0.0 --port 6000
docker build -t hayley-chat-adapter .
docker run -p 6000:6000 --env-file .env hayley-chat-adapter
| Commit | Description |
|---|---|
540102d | Merge PR #159 from munishgandhi/DEV |
04ed59c | Merge PR #158 β observability v3 |
a32ec34 | File set for chat adapter |
c2ec4f8 | Observability clean of traces |
2d8fd23 | Add logger for create message API latency |