231 lines
6.6 KiB
Markdown
231 lines
6.6 KiB
Markdown
# 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
|