Jodinho commited on
Commit
e1b5d1b
Β·
1 Parent(s): 39249f4

docs: complete enterprise technical README rewrite for joule-dynamics-server

Browse files
Files changed (1) hide show
  1. README.md +261 -100
README.md CHANGED
@@ -1,100 +1,261 @@
1
- # Joule Dynamics Real Estate Intelligence Server (Pulse AI)
2
-
3
- High-throughput, token-optimized agentic AI backend powering the **Joule Dynamics Real Estate Rate Monitor & Market Intelligence Layer**. Built with **FastAPI**, **Groq LPU Inference**, **Supabase (pgvector & RPCs)**, and **Appwrite Storage**.
4
-
5
- ---
6
-
7
- ## πŸ›οΈ System Architecture
8
-
9
- ```
10
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
11
- β”‚ User Query (via SSE) β”‚
12
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
13
- β”‚
14
- β–Ό
15
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
16
- β”‚ 1. ROUTER & CATEGORY GATING (Tier 1) β”‚
17
- β”‚ Model: openai/gpt-oss-20b (~150ms) β”‚
18
- β”‚ β€’ Classifies Route (PATH_A/B/BOTH/etc)β”‚
19
- β”‚ β€’ Extracts Categories [MARKET, GEO...]β”‚
20
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
21
- β”‚
22
- β–Ό
23
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
24
- β”‚ 2. DYNAMIC TOOL DISCOVERY (Semantic) β”‚
25
- β”‚ Model: all-MiniLM-L6-v2 (~20ms local) β”‚
26
- β”‚ β€’ Gated candidate filtering β”‚
27
- β”‚ β€’ Top-3 tool vector similarity rankingβ”‚
28
- β”‚ β€’ Attaches Universal Action Tools β”‚
29
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
30
- β”‚
31
- β–Ό
32
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
33
- β”‚ 3. BRAIN & AGENTIC SYNTHESIS (Tier 2) β”‚
34
- β”‚ Model: openai/gpt-oss-120b β”‚
35
- β”‚ β€’ Executes Supabase RPCs / Vector RAG β”‚
36
- β”‚ β€’ Multi-step tool loop (max 4 rounds) β”‚
37
- β”‚ β€’ Streams Markdown tokens via SSE β”‚
38
- β”‚ β€’ Emits interactive suggested actions β”‚
39
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
40
- ```
41
-
42
- ---
43
-
44
- ## ⚑ Core Architectural Features
45
-
46
- ### 1. Two-Tier Model Routing Hierarchy
47
- - **Tier 1 β€” Classification Router (`openai/gpt-oss-20b` | Fallback: `groq/compound-mini`):** Evaluates user intent within ~190 reasoning tokens and tags tool categories (`MARKET`, `ANOMALY`, `PROPERTY`, `GEO`).
48
- - **Tier 2 β€” Agentic Brain & Synthesis (`openai/gpt-oss-120b` | Fallback: `qwen/qwen3.6-27b`):** 120B parameter model orchestrating database tool calls, anomaly analysis, and streaming responses.
49
-
50
- ### 2. Hierarchical Dynamic Tool Discovery & Schema Gating
51
- Instead of sending all 18 tool schemas on every request (consuming >2,000 prompt tokens), a 2-stage discovery engine filters tools:
52
- 1. **Category Gating:** Gated by Router-selected domain buckets.
53
- 2. **Semantic Similarity:** Cosine similarity via local `all-MiniLM-L6-v2` embeddings ranks Top-3 tools + Universal Tools (`suggest_actions`, `generate_data_export`).
54
- 3. **Efficiency:** Reduces tool prompt overhead by **75%** while keeping schema precision high.
55
-
56
- ### 3. Context-Aware Query Enrichment
57
- Short/single-word follow-ups (e.g. selecting `"Miami"` or `"Yesterday"`) are dynamically enriched with prior turn context before computing embeddings, ensuring accurate tool retrieval.
58
-
59
- ### 4. Supabase PostgREST RPC Layer
60
- 15 read-only SQL functions with strict parameter clamping and normalization (KPIs, market snapshots, 25%+ price surge alerts, dynamic rate revisions, and geocoded radius queries).
61
-
62
- ### 5. Conversational Tool Carryover & Action Chips
63
- - Emits native `suggest_actions` tool payloads delivered in the SSE `event: done` stream.
64
- - Multi-step tasks exceeding loop caps provide continuation action chips (`["Yes, generate download report", "No, keep overview"]`) to seamlessly carry workflows across turns.
65
-
66
- ---
67
-
68
- ## πŸ“‘ API Endpoints & Communication Protocol
69
-
70
- ### Real-Time Chat Stream (Server-Sent Events)
71
- - **Route:** `POST /api/v1/real-estate/chat/stream`
72
- - **Headers:** `Content-Type: application/json`, `Accept: text/event-stream`
73
- - **Payload:**
74
- ```json
75
- {
76
- "message": "What is the average nightly rate in Miami?",
77
- "session_id": "session-xyz",
78
- "context": {
79
- "market": "Miami"
80
- }
81
- }
82
- ```
83
-
84
- ### Event Stream Lifecycle:
85
- 1. `event: status` βž” Route classification (`{ "classification": "PATH_A" }`)
86
- 2. `event: tool_call` βž” Real-time tool badge (`{ "tool": "get_market_snapshot", "args": {...} }`)
87
- 3. `event: token` βž” Incremental markdown tokens (`{ "text": "..." }`)
88
- 4. `event: done` βž” Final payload with interactive action chips (`{ "reply": "...", "suggested_actions": ["Miami", "NYC/NJ Metro"] }`)
89
- 5. `event: error` βž” Structured error details with automatic fallback handling
90
-
91
- ---
92
-
93
- ## πŸ› οΈ Tech Stack & Dependencies
94
-
95
- - **Framework:** FastAPI / Uvicorn (Dockerized)
96
- - **Inference Engine:** Groq API SDK (High-Speed LPU Inference)
97
- - **Database & Vectors:** Supabase (PostgreSQL, pgvector, PostgREST RPCs)
98
- - **Local Embeddings:** Sentence-Transformers (`all-MiniLM-L6-v2`)
99
- - **Storage:** Appwrite Storage (Markdown Report Exports)
100
- - **Observability:** Langfuse Tracing & OpenTelemetry
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Joule Dynamics Real Estate Intelligence Server (Pulse AI)
2
+
3
+ [![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=for-the-badge&logo=fastapi)](https://fastapi.tiangolo.com)
4
+ [![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org)
5
+ [![Groq LPU](https://img.shields.io/badge/Groq-LPU_Inference-F05A28?style=for-the-badge)](https://groq.com)
6
+ [![Supabase](https://img.shields.io/badge/Supabase-PostgreSQL_%26_pgvector-3ECF8E?style=for-the-badge&logo=supabase&logoColor=white)](https://supabase.com)
7
+ [![Langfuse](https://img.shields.io/badge/Langfuse-Observability-000000?style=for-the-badge&logo=langfuse&logoColor=white)](https://langfuse.com)
8
+ [![Hugging Face Spaces](https://img.shields.io/badge/Hugging_Face-Spaces_Docker-FFD21E?style=for-the-badge&logo=huggingface&logoColor=black)](https://huggingface.co/spaces)
9
+
10
+ ---
11
+
12
+ ## 1. Executive Summary
13
+
14
+ **Joule Dynamics Server** is a high-throughput, agentic inference backend engineered specifically to power the **Real Estate Telemetry & Rate Intelligence Dashboard**.
15
+
16
+ Operating far beyond standard CRUD paradigms, this server functions as an autonomous reasoning engine that compiles unstructured, natural-language investor queries into deterministic, parameterized **PostgreSQL PL/pgSQL stored procedures**, **window function aggregations**, and **pgvector semantic scans**. By combining ultra-low-latency LPU inference (Groq) with hierarchical schema gating and Server-Sent Events (SSE), the engine delivers real-time market snapshots, anomaly alerts (25%+ rate deviations), and geographic proximity analytics with sub-second time-to-first-token.
17
+
18
+ ---
19
+
20
+ ## 2. System Architecture (The AI Pipeline)
21
+
22
+ The telemetry backend utilizes an asynchronous, non-blocking pipeline spanning intent classification, localized dynamic tool retrieval, database execution, and streaming synthesis.
23
+
24
+ ```
25
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
26
+ β”‚ Client Query via SSE Protocol β”‚
27
+ β”‚ POST /api/v1/real-estate/chat/stream β”‚
28
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
29
+ β”‚
30
+ β–Ό
31
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
32
+ β”‚ 1. INTENT ROUTING & CATEGORY GATING β”‚
33
+ β”‚ Model: openai/gpt-oss-20b (~150ms) β”‚
34
+ β”‚ β€’ Classifies: PATH_A | PATH_B | BOTH | etc. β”‚
35
+ β”‚ β€’ Tags Domain: ["MARKET", "ANOMALY", "GEO"...] β”‚
36
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
37
+ β”‚
38
+ β–Ό
39
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
40
+ β”‚ 2. DYNAMIC TOOL DISCOVERY (Embedding Engine) β”‚
41
+ β”‚ Model: all-MiniLM-L6-v2 (Local, ~20ms latency) β”‚
42
+ β”‚ β€’ Filters registry by domain categories β”‚
43
+ β”‚ β€’ Cosine similarity ranking on tool descriptions β”‚
44
+ β”‚ β€’ Injects Top-3 Tools + Universal Action Tools β”‚
45
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
46
+ β”‚
47
+ β–Ό
48
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
49
+ β”‚ 3. BRAIN & AGENTIC SYNTHESIS LOOP β”‚
50
+ β”‚ Model: openai/gpt-oss-120b β”‚
51
+ β”‚ β€’ Multi-step tool orchestration (max 4 rounds) β”‚
52
+ β”‚ β€’ Parameter clamping & alias normalization β”‚
53
+ β”‚ β€’ Execution via PostgREST RPC & pgvector RAG β”‚
54
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
55
+ β”‚
56
+ β–Ό
57
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
58
+ β”‚ 4. SERVER-SENT EVENTS (SSE) STREAMING β”‚
59
+ β”‚ β€’ event: status (Routing state) β”‚
60
+ β”‚ β€’ event: tool_call (Active DB RPC payload) β”‚
61
+ β”‚ β€’ event: token (Live Markdown tokens) β”‚
62
+ β”‚ β€’ event: done (Final + Action Chips) β”‚
63
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
64
+ ```
65
+
66
+ ### Pipeline Lifecycle:
67
+ 1. **Routing & Intent Disambiguation:** Fast-path classifier (`openai/gpt-oss-20b`) categorizes the query into one of 6 pathways (`PATH_A` Live Data, `PATH_B` Methodology/RAG, `BOTH` Hybrid, `GREETING`, `COMMERCIAL_HANDOFF`, `OUT_OF_SCOPE`) and tags domain categories.
68
+ 2. **Context-Aware Dynamic Schema Gating:** To prevent token bloat (saving >75% of prompt tokens), a local sentence-transformer (`all-MiniLM-L6-v2`) ranks tool schemas against the user prompt (enriched with conversational history) and exposes strictly the Top-3 relevant tools + universal tools.
69
+ 3. **Autonomous Execution Loop:** The synthesis engine (`openai/gpt-oss-120b`) generates JSON function call payloads, dispatches them against Supabase PostgREST RPC endpoints, and streams real-time execution badges to the client.
70
+ 4. **Resilient Loop Carryover:** If a complex, multi-intent prompt hits the 4-round loop ceiling before completing all operations (e.g. data fetch + export generation), the engine synthesizes findings and automatically emits interactive action chips (`suggest_actions`) to carry over work into subsequent turns.
71
+
72
+ ---
73
+
74
+ ## 3. The 18-Tool Agentic Framework
75
+
76
+ The agent has direct access to 18 specialized tools mapping to PostgreSQL PL/pgSQL stored procedures, geospatial calculations, and export workers:
77
+
78
+ | Category | Tool Name | Database / RPC Target | Technical Function & Capabilities |
79
+ |---|---|---|---|
80
+ | **Market & KPIs** | `get_dashboard_kpis` | `public.get_dashboard_kpis` | Aggregates portfolio KPIs (active properties, 7d delta, 25%+ price surge count, scrape health). |
81
+ | **Market & KPIs** | `get_market_averages` | `public.get_market_averages` | Calculates nightly rates and 7-day trailing baseline averages using SQL window functions. |
82
+ | **Market & KPIs** | `get_market_snapshot` | `public.get_market_snapshot` | Single-day comprehensive summary: active inventory, min/max rates, and occupancy rate %. |
83
+ | **Market & KPIs** | `get_market_trend` | `public.get_market_trend` | Multi-day historical rate trajectory (up to 90 days) across Miami and NYC/NJ Metro. |
84
+ | **Market & KPIs** | `get_tracked_markets` | `public.get_tracked_markets` | Returns platform coverage, listing volumes, and operational regions in the database. |
85
+ | **Market & KPIs** | `get_recently_changed_tracking` | `public.get_recently_changed_tracking` | Audit log of listings newly activated or paused in the scraping registry. |
86
+ | **Anomalies** | `get_spike_alerts` | `public.get_spike_alerts` | Scans for sudden rate spikes exceeding configurable threshold (default 25% over 7d baseline). |
87
+ | **Anomalies** | `get_rate_anomaly_report` | `public.get_rate_anomaly_report` | Deep pricing anomaly investigation: lists previous rates, baseline delta, and deviation %. |
88
+ | **Anomalies** | `get_most_volatile_properties` | `public.get_most_volatile_properties` | Ranks properties with the highest dynamic pricing frequency and variance over lookback window. |
89
+ | **Listings & Rates** | `get_property_snapshot` | `public.get_property_snapshot` | Single-listing telemetry: bedrooms, coordinates, current rate, 7d baseline, and availability. |
90
+ | **Listings & Rates** | `get_property_rate_changes` | `public.get_property_rate_changes` | Chronological price revision log tracking exact host rate adjustments over time. |
91
+ | **Listings & Rates** | `compare_properties` | `public.compare_properties` | Multi-property side-by-side comparison across pricing, occupancy, and bedroom configurations. |
92
+ | **Listings & Rates** | `search_properties` | `public.search_properties` | Multi-parameter search filtered by market, bedroom count, platform, availability, and search terms. |
93
+ | **Listings & Rates** | `get_availability_rate` | `public.get_availability_rate` | Computes calendar booking ratios, vacancy percentage, and active inventory metrics. |
94
+ | **Geospatial** | `geocode_address` | *Python Geocoding Worker* | Translates natural language addresses/landmarks into decimal latitude/longitude coordinates. |
95
+ | **Geospatial** | `get_nearby_properties` | `public.get_nearby_properties` | Executes Haversine radius queries on geographic coordinates to find nearest listings. |
96
+ | **Geospatial** | `get_distance_km` | `public.get_distance_km` | PostGIS / mathematical straight-line distance computation between two property UUIDs. |
97
+ | **Universal Actions** | `generate_data_export` | *Appwrite Storage Worker* | Compiles structured real estate analysis into downloadable Markdown (`.md`) reports. |
98
+ | **Universal Actions** | `suggest_actions` | *SSE UI Protocol* | Dispatches native interactive action chips/buttons to guide user follow-ups and next steps. |
99
+
100
+ ---
101
+
102
+ ## 4. Observability & Telemetry
103
+
104
+ Every request passing through `joule-dynamics-server` is deeply instrumented with **Langfuse** and **OpenTelemetry** for end-to-end tracing:
105
+
106
+ ```
107
+ [Trace: chat-session-001]
108
+ β”œβ”€β”€ [Span: router-classification] Model: openai/gpt-oss-20b Tokens: 210 Latency: 148ms
109
+ β”œβ”€β”€ [Span: dynamic-tool-discovery] Model: all-MiniLM-L6-v2 Ranked: 18 Latency: 22ms
110
+ β”œβ”€β”€ [Generation: agent-round-1] Model: openai/gpt-oss-120b Tokens: 480 Latency: 610ms
111
+ β”‚ └── [Tool: get_market_snapshot] Status: success Rows: 1 Latency: 45ms
112
+ └── [Generation: agent-synthesis] Model: openai/gpt-oss-120b Tokens: 320 Latency: 410ms
113
+ ```
114
+
115
+ - **Step-by-Step Trajectory Tracking:** Captures multi-round LLM tool calls, arguments, database query responses, and final streaming text.
116
+ - **Latency & Error Profiling:** Automatically detects and isolates PostgREST `PGRST202` schema errors, Groq rate-limiting retries, and tool execution bottlenecks.
117
+ - **Token & Cost Attribution:** Live calculation of input, completion, and reasoning tokens across both routing and synthesis model tiers.
118
+
119
+ ---
120
+
121
+ ## 5. API Contracts & Streaming Protocol
122
+
123
+ ### Endpoint: `POST /api/v1/real-estate/chat/stream`
124
+ - **Request Headers:** `Content-Type: application/json`, `Accept: text/event-stream`
125
+ - **Request Body:**
126
+ ```json
127
+ {
128
+ "message": "What is the average nightly rate in Miami for 2-bedroom listings?",
129
+ "session_id": "usr_session_8f92a",
130
+ "context": {
131
+ "market": "Miami"
132
+ }
133
+ }
134
+ ```
135
+
136
+ ### Event Stream Chunks:
137
+
138
+ #### 1. Route Classification
139
+ ```http
140
+ event: status
141
+ data: {"classification": "PATH_A"}
142
+ ```
143
+
144
+ #### 2. Live Tool Execution Badge
145
+ ```http
146
+ event: tool_call
147
+ data: {"tool": "search_properties", "args": {"p_market": "Miami", "p_bedrooms": 2}}
148
+ ```
149
+
150
+ #### 3. Token Stream (Live Markdown)
151
+ ```http
152
+ event: token
153
+ data: {"text": "In "}
154
+
155
+ event: token
156
+ data: {"text": "Miami, "}
157
+
158
+ event: token
159
+ data: {"text": "the average rate for 2-bedroom properties is **$285/night**."}
160
+ ```
161
+
162
+ #### 4. Final Payload & Action Chips
163
+ ```http
164
+ event: done
165
+ data: {
166
+ "reply": "In Miami, the average rate for 2-bedroom properties is **$285/night**...",
167
+ "suggested_actions": ["Compare with NYC", "Generate Download Report", "View Price Volatility"],
168
+ "tools_called": [{"tool": "search_properties", "args": {"p_market": "Miami", "p_bedrooms": 2}}]
169
+ }
170
+ ```
171
+
172
+ ---
173
+
174
+ ## 6. Local Development & Environment Setup
175
+
176
+ ### 1. Prerequisites
177
+ - Python 3.10+
178
+ - Git & Virtualenv
179
+
180
+ ### 2. Installation
181
+ ```bash
182
+ # Clone repository
183
+ git clone https://github.com/JohnJodinho/joule-dynamics-server.git
184
+ cd joule-dynamics-server
185
+
186
+ # Create and activate virtual environment
187
+ python -m venv venv
188
+ # On Linux/macOS:
189
+ source venv/bin/activate
190
+ # On Windows:
191
+ . env\Scriptsctivate
192
+
193
+ # Install dependencies
194
+ pip install -r requirements.txt
195
+ ```
196
+
197
+ ### 3. Environment Configuration (`.env`)
198
+ Create a `.env` file in the project root with the following parameters:
199
+
200
+ ```env
201
+ # ── Core Server Configuration ──
202
+ PORT=7860
203
+ HOST=0.0.0.0
204
+ ALLOWED_ORIGINS=*
205
+
206
+ # ── Groq LPU Inference ──
207
+ GROQ_API_KEY=gsk_your_groq_api_key_here
208
+ GROQ_ROUTE_MODEL=openai/gpt-oss-20b
209
+ GROQ_FALLBACK_ROUTE_MODEL=groq/compound-mini
210
+ GROQ_SYNTHESIS_MODEL=openai/gpt-oss-120b
211
+ GROQ_FALLBACK_SYNTHESIS_MODEL=qwen/qwen3.6-27b
212
+
213
+ # ── Supabase Database & Vectors ──
214
+ SUPABASE_URL=https://your-project.supabase.co
215
+ SUPABASE_KEY=your_supabase_service_role_or_anon_key
216
+
217
+ # ── Langfuse Observability ──
218
+ LANGFUSE_PUBLIC_KEY=pk-lf-your_public_key
219
+ LANGFUSE_SECRET_KEY=sk-lf-your_secret_key
220
+ LANGFUSE_HOST=https://cloud.langfuse.com
221
+
222
+ # ── Appwrite Storage (Report Exports) ──
223
+ APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
224
+ APPWRITE_PROJECT_ID=your_project_id
225
+ APPWRITE_API_KEY=your_appwrite_api_key
226
+ APPWRITE_BUCKET_ID=your_bucket_id
227
+ ```
228
+
229
+ ### 4. Run Development Server
230
+ ```bash
231
+ uvicorn app:app --host 0.0.0.0 --port 7860 --reload
232
+ ```
233
+
234
+ Server will be active at `http://localhost:7860`. Interactive Swagger OpenAPI docs available at `http://localhost:7860/docs`.
235
+
236
+ ---
237
+
238
+ ## 7. Production Deployment (Hugging Face Spaces)
239
+
240
+ This server is packaged as a Docker container designed for seamless deployment on **Hugging Face Spaces**.
241
+
242
+ ### Deployment Steps:
243
+ 1. Create a new Space on [Hugging Face](https://huggingface.co/new-space) and select **Docker** as the SDK.
244
+ 2. In your Space's root `README.md`, ensure the standard YAML metadata block is present at the very top:
245
+ ```yaml
246
+ ---
247
+ title: Joule Dynamics Server
248
+ emoji: πŸ“Š
249
+ colorFrom: blue
250
+ colorTo: indigo
251
+ sdk: docker
252
+ app_port: 7860
253
+ pinned: false
254
+ ---
255
+ ```
256
+ 3. In your Space **Settings** $
257
+ 4. Push code to the Space repository:
258
+ ```bash
259
+ git push hf main
260
+ ```
261
+ The Docker container will automatically build, install requirements, pre-load the local embedding model cache, and expose the FastAPI SSE server on port `7860`.