Backend-only service for emotion-driven product recommendation via Apache Kafka.
This repository is no longer a frontend dashboard or multi-app monorepo. It now acts as a core recommendation service that other projects can consume.
The service implements MDCRS:
- L1: Dynamic Knowledge Graph with half-life decay
- L2: LLM Inner Monologue for cognitive-state inference (with deterministic fallback)
- L3: Curiosity-Driven RL scoring
- Input topic:
behavior.events.v1 - Intermediate topic:
emotion.inferred.v1 - Output topic:
recommendation.generated.v1 - Feedback topic:
recommendation.feedback.v1 - DLQ topic:
mdcrs.dlq.v1
Service responsibilities:
- Consume behavior events
- Build/update graph memory
- Infer cognitive state
- Score recommendations
- Publish inferred emotion and recommendations
- Update policy via feedback events
apps/ai-service/fastapi-service/main.py: API entrypoint (/health,/ready,/admin/worker-status)apps/ai-service/fastapi-service/kafka_worker.py: Kafka consumer/producer loopsapps/ai-service/fastapi-service/kafka_contracts.py: Event contracts (Pydantic)apps/ai-service/fastapi-service/mdcrs_engine.py: MDCRS algorithm coredatabase_schema.sql: PostgreSQL schema for graph/state/reward persistence
- Start stack:
./integrated-startup.sh start- Verify service:
curl http://localhost:8000/health
curl http://localhost:8000/ready- See logs:
./integrated-startup.sh logs- Stop stack:
./integrated-startup.sh stopExample behavior.events.v1 message:
{
"meta": {
"event_id": "evt-001",
"correlation_id": "corr-001",
"user_id": "user-123",
"session_id": "sess-1",
"event_time": "2026-04-09T12:00:00Z",
"source": "catalog-service",
"schema_version": "v1"
},
"user_profile": {"age": 30, "gender": "female"},
"context": {"weather": "cold"},
"signals": [
{"type": "scroll", "category": "fashion", "dwell_ms": 200},
{"type": "hover", "category": "home", "dwell_ms": 1800},
{"type": "click", "category": "home", "item_id": "p-22", "dwell_ms": 2600}
]
}- LLM inference is enabled when
OPENAI_API_KEYis set. - If LLM is unavailable, engine falls back to deterministic rules.
- Worker has idempotent event handling and DLQ publishing on parse/process failures.