the behemoth
This commit is contained in:
230
CHANGES_SUMMARY.md
Normal file
230
CHANGES_SUMMARY.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# Summary of Changes
|
||||
|
||||
## Task 1: Auto-Triggering Strategy Brainstorming
|
||||
|
||||
### Problem
|
||||
The AI Intelligence Layer required manual API calls to `/api/strategy/brainstorm` endpoint. The webhook endpoint only received enriched telemetry without race context.
|
||||
|
||||
### Solution
|
||||
Modified `/api/ingest/enriched` endpoint to:
|
||||
1. Accept both enriched telemetry AND race context
|
||||
2. Automatically trigger strategy brainstorming when buffer has ≥3 laps
|
||||
3. Return generated strategies in the webhook response
|
||||
|
||||
### Files Changed
|
||||
- `ai_intelligence_layer/models/input_models.py`: Added `EnrichedTelemetryWithContext` model
|
||||
- `ai_intelligence_layer/main.py`: Updated webhook endpoint to auto-trigger brainstorm
|
||||
|
||||
### Key Code Changes
|
||||
|
||||
**New Input Model:**
|
||||
```python
|
||||
class EnrichedTelemetryWithContext(BaseModel):
|
||||
enriched_telemetry: EnrichedTelemetryWebhook
|
||||
race_context: RaceContext
|
||||
```
|
||||
|
||||
**Updated Endpoint Logic:**
|
||||
```python
|
||||
@app.post("/api/ingest/enriched")
|
||||
async def ingest_enriched_telemetry(data: EnrichedTelemetryWithContext):
|
||||
# Store telemetry and race context
|
||||
telemetry_buffer.add(data.enriched_telemetry)
|
||||
current_race_context = data.race_context
|
||||
|
||||
# Auto-trigger brainstorm when we have enough data
|
||||
if buffer_data and len(buffer_data) >= 3:
|
||||
response = await strategy_generator.generate(
|
||||
enriched_telemetry=buffer_data,
|
||||
race_context=data.race_context
|
||||
)
|
||||
return {
|
||||
"status": "received_and_processed",
|
||||
"strategies": [s.model_dump() for s in response.strategies]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Enrichment Stage Outputs Complete Race Context
|
||||
|
||||
### Problem
|
||||
The enrichment service only output 7 enriched telemetry fields. The AI Intelligence Layer needed complete race context including race_info, driver_state, and competitors.
|
||||
|
||||
### Solution
|
||||
Extended enrichment to build and output complete race context alongside enriched telemetry metrics.
|
||||
|
||||
### Files Changed
|
||||
- `hpcsim/enrichment.py`: Added `enrich_with_context()` method and race context building
|
||||
- `hpcsim/adapter.py`: Extended normalization for race context fields
|
||||
- `hpcsim/api.py`: Updated endpoint to use new enrichment method
|
||||
- `scripts/simulate_pi_stream.py`: Added race context fields to telemetry
|
||||
- `scripts/enrich_telemetry.py`: Added `--full-context` flag
|
||||
|
||||
### Key Code Changes
|
||||
|
||||
**New Enricher Method:**
|
||||
```python
|
||||
def enrich_with_context(self, telemetry: Dict[str, Any]) -> Dict[str, Any]:
|
||||
# Compute enriched metrics (existing logic)
|
||||
enriched_telemetry = {...}
|
||||
|
||||
# Build race context
|
||||
race_context = {
|
||||
"race_info": {
|
||||
"track_name": track_name,
|
||||
"total_laps": total_laps,
|
||||
"current_lap": lap,
|
||||
"weather_condition": weather_condition,
|
||||
"track_temp_celsius": track_temp
|
||||
},
|
||||
"driver_state": {
|
||||
"driver_name": driver_name,
|
||||
"current_position": current_position,
|
||||
"current_tire_compound": normalized_tire,
|
||||
"tire_age_laps": tire_life_laps,
|
||||
"fuel_remaining_percent": fuel_level * 100.0
|
||||
},
|
||||
"competitors": self._generate_mock_competitors(...)
|
||||
}
|
||||
|
||||
return {
|
||||
"enriched_telemetry": enriched_telemetry,
|
||||
"race_context": race_context
|
||||
}
|
||||
```
|
||||
|
||||
**Updated API Endpoint:**
|
||||
```python
|
||||
@app.post("/ingest/telemetry")
|
||||
async def ingest_telemetry(payload: Dict[str, Any] = Body(...)):
|
||||
normalized = normalize_telemetry(payload)
|
||||
result = _enricher.enrich_with_context(normalized) # New method
|
||||
|
||||
# Forward to AI layer with complete context
|
||||
if _CALLBACK_URL:
|
||||
await client.post(_CALLBACK_URL, json=result)
|
||||
|
||||
return JSONResponse(result)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Additional Features
|
||||
|
||||
### Competitor Generation
|
||||
Mock competitor data is generated for testing purposes:
|
||||
- Positions around the driver (±3 positions)
|
||||
- Realistic gaps based on position delta
|
||||
- Varied tire strategies and ages
|
||||
- Driver names from F1 roster
|
||||
|
||||
### Data Normalization
|
||||
Extended adapter to handle multiple field aliases:
|
||||
- `lap_number` → `lap`
|
||||
- `track_temperature` → `track_temp`
|
||||
- `tire_life_laps` → handled correctly
|
||||
- Fuel level conversion: 0-1 range → 0-100 percentage
|
||||
|
||||
### Backward Compatibility
|
||||
- Legacy `enrich()` method still available
|
||||
- Manual `/api/strategy/brainstorm` endpoint still works
|
||||
- Scripts work with or without race context fields
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Unit Tests
|
||||
- `tests/test_enrichment.py`: Tests for new `enrich_with_context()` method
|
||||
- `tests/test_integration.py`: End-to-end integration tests
|
||||
|
||||
### Integration Test
|
||||
- `test_integration_live.py`: Live test script for running services
|
||||
|
||||
All tests pass ✅
|
||||
|
||||
---
|
||||
|
||||
## Data Flow
|
||||
|
||||
### Before:
|
||||
```
|
||||
Pi → Enrichment → AI Layer (manual brainstorm call)
|
||||
(7 metrics) (requires race_context from somewhere)
|
||||
```
|
||||
|
||||
### After:
|
||||
```
|
||||
Pi → Enrichment → AI Layer (auto-brainstorm)
|
||||
(raw + context) (enriched + context)
|
||||
↓
|
||||
Strategies
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage Example
|
||||
|
||||
**1. Start Services:**
|
||||
```bash
|
||||
# Terminal 1: Enrichment Service
|
||||
export NEXT_STAGE_CALLBACK_URL=http://localhost:9000/api/ingest/enriched
|
||||
uvicorn hpcsim.api:app --port 8000
|
||||
|
||||
# Terminal 2: AI Intelligence Layer
|
||||
cd ai_intelligence_layer
|
||||
uvicorn main:app --port 9000
|
||||
```
|
||||
|
||||
**2. Stream Telemetry:**
|
||||
```bash
|
||||
python scripts/simulate_pi_stream.py \
|
||||
--data ALONSO_2023_MONZA_RACE \
|
||||
--endpoint http://localhost:8000/ingest/telemetry \
|
||||
--speed 10.0
|
||||
```
|
||||
|
||||
**3. Observe:**
|
||||
- Enrichment service processes telemetry + builds race context
|
||||
- Webhooks sent to AI layer with complete data
|
||||
- AI layer auto-generates strategies (after lap 3)
|
||||
- Strategies returned in webhook response
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
Run the live integration test:
|
||||
```bash
|
||||
python test_integration_live.py
|
||||
```
|
||||
|
||||
This will:
|
||||
1. Check both services are running
|
||||
2. Send 5 laps of telemetry with race context
|
||||
3. Verify enrichment output structure
|
||||
4. Test manual brainstorm endpoint
|
||||
5. Display sample strategy output
|
||||
|
||||
---
|
||||
|
||||
## Benefits
|
||||
|
||||
✅ **Automatic Processing**: No manual endpoint calls needed
|
||||
✅ **Complete Context**: All required data in one webhook
|
||||
✅ **Real-time**: Strategies generated as telemetry arrives
|
||||
✅ **Stateful**: Enricher maintains race state across laps
|
||||
✅ **Type-Safe**: Pydantic models ensure data validity
|
||||
✅ **Backward Compatible**: Existing code continues to work
|
||||
✅ **Well-Tested**: Comprehensive unit and integration tests
|
||||
|
||||
---
|
||||
|
||||
## Next Steps (Optional Enhancements)
|
||||
|
||||
1. **Real Competitor Data**: Replace mock competitor generation with actual race data
|
||||
2. **Position Tracking**: Track position changes over laps
|
||||
3. **Strategy Caching**: Cache generated strategies to avoid regeneration
|
||||
4. **Webhooks Metrics**: Add monitoring for webhook delivery success
|
||||
5. **Database Storage**: Persist enriched telemetry and strategies
|
||||
Reference in New Issue
Block a user