Imported from abdessamadjaouad/ai-sandbox-vibecoded (
AGENTS.md). Install upstream withnpx skills add abdessamadjaouad/ai-sandbox-vibecoded. Copyright stays with the author.
You write clean, production-grade Python. You think in layers, respect separation of concerns, and always consider governance constraints (RBAC, audit logs, reproducibility) in every design decision.
<project_context> Project name: AI Sandbox (PFE — DXC Technology / ENSAM Casablanca) Primary goal: modular experimentation platform for regulated sectors (finance, banking, insurance, public sector).
The platform is built as 4 independent but connected layers:
- Layer 1 — Data Layer: Ingestion, validation, versioning, embeddings, storage
- Layer 2 — Experiment Layer: LangGraph orchestrator, model catalogue, runners, tracking
- Layer 3 — Evaluation Layer: Metrics, scoring, reports
- Layer 4 — Governance Layer: RBAC/ABAC, audit logs, encryption, compliance
Deployment targets: On-premises (primary), certified local cloud, hybrid </project_context>
<tech_stack>
| Component | Technology |
|---|---|
| Orchestrator | LangGraph |
| API backend | FastAPI (backend/app/main.py) |
| Frontend | React 18 + Vite + TypeScript (frontend/src/) |
| Experiment tracking | MLflow + LangFuse |
| Containerisation | Docker Compose |
| Relational DB | PostgreSQL (asyncpg + SQLAlchemy) |
| Object storage | MinIO (S3-compatible) |
| Vector DB | ChromaDB |
| LLM inference | vLLM, Ollama (local), OpenAI-compatible API |
| ML models | XGBoost, LightGBM, CatBoost, scikit-learn |
| NLP/LLM | HuggingFace Transformers, LangChain, RAGAS |
| Evaluation | DeepEval, RAGAS, Guardrails AI |
| Security | HashiCorp Vault, python-jose (JWT) |
| </tech_stack> |
Local LLM support: Register via vLLM/Ollama — treated as first-class, benchmarkable against API LLMs.
<developer_commands>
Backend (Python)
Install dependencies: python -m pip install -e ".[dev]"
Run locally: uvicorn backend.app.main:app --reload --host 0.0.0.0 --port 8000
Run tests: pytest pytest --cov=backend --cov-report=html pytest tests/unit/ pytest tests/integration/
Lint/format/typecheck: ruff check backend/ ruff format backend/ mypy backend/
Frontend (React + Vite)
Install: cd frontend && npm install
Dev server (port 5173): cd frontend && npm run dev
Build: cd frontend && npm run build
Test: cd frontend && npm run test
Infrastructure
Start data services only: docker compose up -d postgres chromadb mlflow minio
Start full stack: docker compose up --build
Service ports: Backend :8000 | Frontend :5173/:80 | MLflow :5000 | ChromaDB :8001 | MinIO :9000/:9001 | Postgres :5432 </developer_commands>
<repo_structure> backend/app/ main.py FastAPI entrypoint core/ Config, database, logging, security api/ FastAPI routers (auth, datasets, evaluation, experiments) data_layer/ Ingestion, validation, versioning, embeddings, storage experiment_layer/ LangGraph orchestrator, runners, tracking evaluation_layer/ Metrics, scoring, reports governance/ RBAC, audit, auth, secrets models/ Pydantic schemas agents/ Planner, executor, memory, orchestrator
frontend/src/ App.tsx Root component with routing main.tsx React entrypoint styles.css Complete design system (3400+ lines) types.ts Shared TypeScript types store/wizardStore.ts Wizard state management context/AuthContext.tsx Authentication context hooks/ useApi, useWizardExperience components/ Navbar, Footer, SpinnerPanel, ProgressRail, ActionBar pages/ Landing, Login, Signup, About, History, Step1-5 (wizard flow)
frontend-simple/ Alternative frontend build (check before modifying)
docker/ Dockerfile.backend Dockerfile.frontend
.pyproject.toml Hatchling build, ruff, mypy, pytest config uv.lock Python lockfile docker-compose.yml 7 services with healthchecks </repo_structure>
<negative_constraints>
- DO NOT use Jupyter notebooks in production — use .py modules only
- DO NOT hardcode API keys, model names, or thresholds — use config files
- DO NOT mix layer responsibilities (no ML logic in FastAPI routers)
- DO NOT skip audit log for any run, dataset access, or model call
- DO NOT call external APIs (OpenAI, HuggingFace) unless user configured an API key and dataset is marked non-sensitive
- DO NOT use global mutable state — LangGraph state is the single source of truth
- DO NOT generate KPIs without recording inputs (ground truth, config, dataset version)
- DO NOT assume the LLM is remote — always check model registry first for local vLLM/Ollama
- DO NOT expose technical error stack traces to frontend — translate to user-friendly messages
- DO NOT suggest Airflow, Pinecone, W&B, or SageMaker — stack is fixed </negative_constraints>
<frontend_ux_rules> Target users are non-technical employees.
- Wizard steps (one decision per screen)
- Plain language (no ML jargon in labels)
- Progress indicators during long runs
- Visual comparisons, not raw numbers
- One-sentence plain-language recommendation at top of every report
- Light/dark themes (data-theme attribute on html)
- All buttons rounded-full (pill shape)
- Glass-card class for elevated surfaces
- Brand gradient (amber→coral→blue) for accents </frontend_ux_rules>
<testing_quirks>
- Backend: pytest with pytest-asyncio (auto mode). Mock external services (MLflow, MinIO, vLLM, LangFuse) in unit tests.
- Frontend: vitest with jsdom. CSS enabled in test environment.
- Integration tests may require postgres + chromadb services. </testing_quirks>
<output_format> When producing code files:
- Show full file path as comment at top
- Include all imports (no implicit)
- Keep files under 300 lines — split if longer
When explaining architectural decisions:
- State decision in one sentence
- Give two alternatives considered and why rejected
- State tradeoff explicitly
When debugging:
- Identify root cause first (one sentence)
- Show minimal reproducing case
- Provide fix with one-line explanation
- Mention side effects
When generating LangGraph orchestrator:
- Show full graph as ASCII or Mermaid before code
- Define TypedDict state schema before nodes
- Comment each edge with condition or trigger </output_format>
<session_rules> Before starting any task, check memory MCP for prior runs of the same use-case type. If a pattern exists, reuse it and state which pattern was retrieved. </session_rules>