{"repo": "bensalemboualem/rag-dz", "files": {"infrastructure/docker/docker-compose.yml": {"7d6e298b582d583185cd24b914c17d9daeaa9491": {"t": 1785745256.4343567, "n": 14597, "h": "cbb03ef4ecd9d483", "c": "# ==============================================\n# IA FACTORY ALGÉRIE (RAG-DZ) - Docker Compose\n# ==============================================\n# Instance Souveraine - Région: DZ (Algérie)\n# Ports: 8180-8191 (plage réservée IAF-DZ)\n# ==============================================\n\nservices:\n # ==============================================\n # DATABASES & CACHE\n # ==============================================\n\n # PostgreSQL avec PGVector (Recherche Vectorielle)\n iafactory-postgres:\n image: pgvector/pgvector:pg16\n container_name: iaf-dz-postgres\n environment:\n POSTGRES_USER: ${POSTGRES_USER:?POSTGRES_USER requis dans .env}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD requis dans .env}\n POSTGRES_DB: ${POSTGRES_DB:-archon}\n TZ: Africa/Algiers\n volumes:\n - postgres_data:/var/lib/postgresql/data\n - ./infrastructure/sql/init.sql:/docker-entrypoint-initdb.d/01-init.sql\n - ./infrastructure/sql/pgvector_migration.sql:/docker-entrypoint-initdb.d/02-pgvector.sql\n ports:\n - \"127.0.0.1:6330:5432\"\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n networks:\n - iafactory-net\n command: postgres -c shared_preload_libraries=vector\n restart: unless-stopped\n\n # Redis Cache\n iafactory-redis:\n image: redis:7-alpine\n container_name: iaf-dz-redis\n command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru\n volumes:\n - redis_data:/data\n ports:\n - \"6331:6379\"\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 10s\n timeout: 3s\n retries: 5\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # Qdrant Vector Database\n iafactory-qdrant:\n image: qdrant/qdrant:latest\n container_name: iaf-dz-qdrant\n volumes:\n - qdrant_data:/qdrant/storage\n ports:\n - \"6332:6333\"\n environment:\n QDRANT_LOG_LEVEL: ${LOG_LEVEL:-INFO}\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # ==============================================\n # BACKEND API (RAG Souverain)\n # ==============================================\n\n iafactory-backend:\n build:\n context: ./backend/rag-compat\n dockerfile: Dockerfile\n container_name: iaf-dz-backend\n env_file:\n - .env.local\n depends_on:\n iafactory-postgres:\n condition: service_healthy\n iafactory-redis:\n condition: service_healthy\n iafactory-qdrant:\n condition: service_started\n environment:\n # Région Souveraine\n SOVEREIGNTY_REGION: DZ\n SOVEREIGNTY_LABEL: \"Algérie\"\n TZ: Africa/Algiers\n\n # Database - uses env vars for password\n POSTGRES_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@iafactory-postgres:5432/${POSTGRES_DB:-archon}\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@iafactory-postgres:5432/${POSTGRES_DB:-archon}\n\n # Redis\n REDIS_URL: redis://iafactory-redis:6379/0\n REDIS_PASSWORD: ${REDIS_PASSWORD:-}\n\n # Qdrant\n QDRANT_HOST: iafactory-qdrant\n QDRANT_PORT: 6333\n\n # LLM Provider (Groq = gratuit et rapide)\n ENABLE_LLM: \"true\"\n LLM_PROVIDER: ${LLM_PROVIDER:-groq}\n LLM_MODEL: ${LLM_MODEL:-llama-3.3-70b-versatile}\n GROQ_API_KEY: ${GROQ_API_KEY:-}\n OPENAI_API_KEY: ${OPENAI_API_KEY:-}\n ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n GOOGLE_GENERATIVE_AI_API_KEY: ${GOOGLE_GENERATIVE_AI_API_KEY:-}\n\n # TTS Voice (ElevenLabs pour arabe haute qualité)\n ELEVENLABS_API_KEY: ${ELEVENLABS_API_KEY:-}\n\n # Security - REQUIRED: set in .env file\n API_SECRET_KEY: ${API_SECRET_KEY:?API_SECRET_KEY requis dans .env}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY:?JWT_SECRET_KEY requis dans .env}\n ALLOWED_ORIGINS: http://localhost:8180,http://localhost:8181,http://localhost:8182,http://localhost:8183,http://localhost:8184,http://localhost:8185\n\n # Rate Limiting\n RATE_LIMIT_PER_MINUTE: ${RATE_LIMIT_PER_MINUTE:-60}\n RATE_LIMIT_PER_HOUR: ${RATE_LIMIT_PER_HOUR:-1000}\n ENABLE_RATE_LIMITING: ${ENABLE_RATE_LIMITING:-true}\n\n # Embeddings (Multilingue FR/AR/EN)\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-sentence-transformers/paraphrase-multilingual-mpnet-base-v2}\n EMBEDDING_DEVICE: ${EMBEDDING_DEVICE:-cpu}\n EMBEDDING_BATCH_SIZE: ${EMBEDDING_BATCH_SIZE:-32}\n\n # Reranking\n USE_RERANKING: ${USE_RERANKING:-true}\n RERANKING_MODEL: ${RERANKING_MODEL:-cross-encoder/ms-marco-MiniLM-L-6-v2}\n RERANKING_TOP_K: ${RERANKING_TOP_K:-10}\n\n # PGVector\n USE_PGVECTOR: ${USE_PGVECTOR:-true}\n\n # Service Info\n SERVICE_NAME: iafactory-dz-api\n SERVICE_VERSION: 1.0.0\n LOG_LEVEL: ${LOG_LEVEL:-INFO}\n ENVIRONMENT: ${ENVIRONMENT:-development}\n\n # Features\n ENABLE_CORS: ${ENABLE_CORS:-true}\n ENABLE_METRICS: ${ENABLE_METRICS:-true}\n ENABLE_API_KEY_AUTH: ${ENABLE_API_KEY_AUTH:-false}\n\n # BMAD Configuration\n BMAD_DEFAULT_PROVIDER: ${BMAD_DEFAULT_PROVIDER:-groq}\n\n # Twilio SMS & WhatsApp (DZ)\n TWILIO_ACCOUNT_SID: ${TWILIO_ACCOUNT_SID:-}\n TWILIO_AUTH_TOKEN: ${TWILIO_AUTH_TOKEN:-}\n TWILIO_PHONE_NUMBER: ${TWILIO_PHONE_NUMBER:-}\n TWILIO_WHATSAPP_NUMBER: ${TWILIO_WHATSAPP_NUMBER:-}\n\n ports:\n - \"8180:8180\"\n volumes:\n - ./backend/rag-compat:/app\n - ./bmad:/bmad:ro\n - backend_cache:/root/.cache\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8180/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # ==============================================\n # FRONTEND APPLICATIONS\n # ==============================================\n\n # IAFactory Hub (Dashboard Principal)\n iafactory-hub:\n build:\n context: ./frontend/archon-ui\n dockerfile: Dockerfile\n args:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_API_SECRET_KEY: ${API_SECRET_KEY}\n container_name: iaf-dz-hub\n depends_on:\n - iafactory-backend\n environment:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_WS_URL: ${VITE_WS_URL:-ws://localhost:8180/ws}\n VITE_SHOW_DEVTOOLS: ${VITE_SHOW_DEVTOOLS:-true}\n VITE_API_SECRET_KEY: ${API_SECRET_KEY}\n VITE_API_KEY: ${API_SECRET_KEY}\n VITE_SOVEREIGNTY_REGION: DZ\n ports:\n - \"8182:3737\"\n volumes:\n - ./frontend/archon-ui/src:/app/src\n - ./frontend/archon-ui/public:/app/public\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # IAFactory Docs (Gestion Documentaire)\n iafactory-docs:\n build:\n context: ./frontend/rag-ui\n dockerfile: Dockerfile\n args:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n container_name: iaf-dz-docs\n depends_on:\n - iafactory-backend\n environment:\n REACT_APP_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_SOVEREIGNTY_REGION: DZ\n ports:\n - \"8183:5173\"\n volumes:\n - ./frontend/rag-ui/src:/app/src\n - ./frontend/rag-ui/public:/app/public\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # IAFactory Studio (Bolt.DIY - AI Code Editor)\n iafactory-studio:\n build:\n context: ./bolt-diy\n dockerfile: Dockerfile\n container_name: iaf-dz-studio\n depends_on:\n - iafactory-backend\n environment:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_ARCHON_API_URL: http://localhost:8180\n OPENAI_API_KEY: ${OPENAI_API_KEY:-}\n ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}\n GROQ_API_KEY: ${GROQ_API_KEY:-}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n GOOGLE_GENERATIVE_AI_API_KEY: ${GOOGLE_GENERATIVE_AI_API_KEY:-}\n OLLAMA_API_BASE_URL: http://iafactory-ollama:11434\n VITE_SOVEREIGNTY_REGION: DZ\n volumes:\n - ./bolt-diy/app:/app/app:ro\n - ./bolt-diy/public:/app/public\n ports:\n - \"8184:5173\"\n networks:\n - iafactory-net\n restart: unless-stopped\n profiles:\n - studio\n\n # ==============================================\n # SEO & LANDING PAGES\n # ==============================================\n\n # SEO-DZ-Boost - Landing Pages SEO pour Google Algérie\n iafactory-seo-dz:\n build:\n context: ./apps/seo-dz-boost\n dockerfile: Dockerfile\n container_name: iaf-dz-seo\n environment:\n ANALYTICS_PROVIDER: ${ANALYTICS_PROVIDER:-plausible}\n ANALYTICS_ID: ${ANALYTICS_ID:-}\n GA4_MEASUREMENT_ID: ${GA4_MEASUREMENT_ID:-}\n PLAUSIBLE_DOMAIN: ${PLAUSIBLE_DOMAIN:-www.iafactoryalgeria.com}\n MATOMO_URL: ${MATOMO_URL:-}\n MATOMO_SITE_ID: ${MATOMO_SITE_ID:-}\n ports:\n - \"8218:80\"\n networks:\n - iafactory-net\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:80/\"]\n interval: 30s\n timeout: 10s\n retries: 3\n labels:\n - \"traefik.enable=true\"\n - \"traefik.http.routers.seo-dz.rule=Host(`www.iafactoryalgeria.com`)\"\n - \"traefik.http.services.seo-dz.loadbalancer.server.port=80\"\n\n # ==============================================\n # DEVELOPER PORTAL (Module 16)\n # ==============================================\n\n # API Portal - Dashboard développeur façon OpenAI/Stripe\n iafactory-api-portal:\n build:\n context: ./apps/api-portal/frontend\n dockerfile: Dockerfile\n container_name: iaf-dz-api-portal\n depends_on:\n - iafactory-backend\n environment:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_SOVEREIGNTY_REGION: DZ\n ports:\n - \"8219:3000\"\n networks:\n - iafactory-net\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3000/\"]\n interval: 30s\n timeout: 10s\n retries: 3\n labels:\n - \"traefik.enable=true\"\n - \"traefik.http.routers.api-portal.rule=Host(`dev.iafactoryalgeria.com`)\"\n - \"traefik.http.services.api-portal.loadbalancer.server.port=3000\"\n\n # ==============================================\n # WORKFLOW & AUTOMATION\n # ==============================================\n\n # n8n Workflow Automation\n iafactory-n8n:\n image: docker.n8n.io/n8nio/n8n:latest\n container_name: iaf-dz-n8n\n depends_on:\n iafactory-postgres:\n condition: service_healthy\n environment:\n # Database\n DB_TYPE: postgresdb\n DB_POSTGRESDB_HOST: iafactory-postgres\n DB_POSTGRESDB_PORT: 5432\n DB_POSTGRESDB_DATABASE: ${POSTGRES_DB:-archon}\n DB_POSTGRESDB_USER: ${POSTGRES_USER:-postgres}\n DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}\n DB_POSTGRESDB_SCHEMA: n8n\n\n # Auth\n N8N_BASIC_AUTH_ACTIVE: ${N8N_BASIC_AUTH_ACTIVE:-true}\n N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER:-admin}\n N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD:-admin}\n\n # Webhook\n WEBHOOK_URL: ${N8N_WEBHOOK_URL:-http://localhost:8185}\n N8N_HOST: ${N8N_HOST:-localhost}\n N8N_PORT: 5678\n N8N_PROTOCOL: http\n\n # Timezone Algérie\n GENERIC_TIMEZONE: Africa/Algiers\n TZ: Africa/Algiers\n\n # Execution\n EXECUTIONS_DATA_PRUNE: \"true\"\n EXECUTIONS_DATA_MAX_AGE: 168\n\n # API\n N8N_API_ENABLED: \"true\"\n N8N_DIAGNOSTICS_ENABLED: \"false\"\n N8N_PERSONALIZATION_ENABLED: \"false\"\n volumes:\n - n8n_data:/home/node/.n8n\n - ./infrastructure/n8n/workflows:/home/node/workflows:ro\n ports:\n - \"8185:5678\"\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # ==============================================\n # AI MODELS (Optionnel)\n # ==============================================\n\n # Ollama - Modèles IA Locaux (pour LLM Council)\n iafactory-ollama:\n image: ollama/ollama:latest\n container_name: iaf-dz-ollama\n volumes:\n - ollama_data:/root/.ollama\n ports:\n - \"127.0.0.1:11434:11434\"\n networks:\n - iafactory-net\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:11434/api/tags\"]\n interval: 30s\n timeout: 10s\n retries: 3\n # Pour GPU support (optionnel):\n # deploy:\n # resources:\n # reservations:\n # devices:\n # - driver: nvidia\n # count: 1\n # capabilities: [gpu]\n\n # ==============================================\n # MONITORING (Optionnel)\n # ==============================================\n\n # Prometheus\n iafactory-prometheus:\n image: prom/prometheus:latest\n container_name: iaf-dz-prometheus\n volumes:\n - ./infrastructure/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml\n - ./infrastructure/monitoring/alerts.yml:/etc/prometheus/alerts.yml\n - prometheus_data:/prometheus\n command:\n - '--config.file=/etc/prometheus/prometheus.yml'\n - '--storage.tsdb.path=/prometheus'\n - '--storage.tsdb.retention.time=30d'\n ports:\n - \"8187:9090\"\n networks:\n - iafactory-net\n restart: unless-stopped\n profiles:\n - monitoring\n\n # Grafana\n iafactory-grafana:\n image: grafana/grafana:latest\n container_name: iaf-dz-grafana\n depends_on:\n - iafactory-prometheus\n environment:\n GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}\n GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin}\n GF_USERS_ALLOW_SIGN_UP: \"false\"\n GF_SERVER_ROOT_URL: http://localhost:8188\n GF_INSTALL_PLUGINS: redis-datasource\n volumes:\n - ./infrastructure/monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards\n - ./infrastructure/monitoring/grafana/datasources:/etc/grafana/provisioning/datasources\n - grafana_data:/var/lib/grafana\n ports:\n - \"8188:3000\"\n networks:\n - iafactory-net\n restart: unless-stopped\n profiles:\n - monitoring\n\n# ==============================================\n# NETWORKS\n# ==============================================\nnetworks:\n iafactory-net:\n driver: bridge\n name: iafactory-net\n\n# ==============================================\n# VOLUMES\n# ==============================================\nvolumes:\n postgres_data:\n name: iaf-dz-postgres-data\n redis_data:\n name: iaf-dz-redis-data\n qdrant_data:\n name: iaf-dz-qdrant-data\n ollama_data:\n name: iaf-dz-ollama-data\n backend_cache:\n name: iaf-dz-backend-cache\n prometheus_data:\n name: iaf-dz-prometheus-data\n grafana_data:\n name: iaf-dz-grafana-data\n n8n_data:\n name: iaf-dz-n8n-data\n"}, "cec8535cc766b8b211c8bee394ecca3c44b713a7": {"t": 1785749289.4335523, "n": 14597, "h": "cbb03ef4ecd9d483", "c": "# ==============================================\n# IA FACTORY ALGÉRIE (RAG-DZ) - Docker Compose\n# ==============================================\n# Instance Souveraine - Région: DZ (Algérie)\n# Ports: 8180-8191 (plage réservée IAF-DZ)\n# ==============================================\n\nservices:\n # ==============================================\n # DATABASES & CACHE\n # ==============================================\n\n # PostgreSQL avec PGVector (Recherche Vectorielle)\n iafactory-postgres:\n image: pgvector/pgvector:pg16\n container_name: iaf-dz-postgres\n environment:\n POSTGRES_USER: ${POSTGRES_USER:?POSTGRES_USER requis dans .env}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD requis dans .env}\n POSTGRES_DB: ${POSTGRES_DB:-archon}\n TZ: Africa/Algiers\n volumes:\n - postgres_data:/var/lib/postgresql/data\n - ./infrastructure/sql/init.sql:/docker-entrypoint-initdb.d/01-init.sql\n - ./infrastructure/sql/pgvector_migration.sql:/docker-entrypoint-initdb.d/02-pgvector.sql\n ports:\n - \"127.0.0.1:6330:5432\"\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n networks:\n - iafactory-net\n command: postgres -c shared_preload_libraries=vector\n restart: unless-stopped\n\n # Redis Cache\n iafactory-redis:\n image: redis:7-alpine\n container_name: iaf-dz-redis\n command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru\n volumes:\n - redis_data:/data\n ports:\n - \"6331:6379\"\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 10s\n timeout: 3s\n retries: 5\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # Qdrant Vector Database\n iafactory-qdrant:\n image: qdrant/qdrant:latest\n container_name: iaf-dz-qdrant\n volumes:\n - qdrant_data:/qdrant/storage\n ports:\n - \"6332:6333\"\n environment:\n QDRANT_LOG_LEVEL: ${LOG_LEVEL:-INFO}\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # ==============================================\n # BACKEND API (RAG Souverain)\n # ==============================================\n\n iafactory-backend:\n build:\n context: ./backend/rag-compat\n dockerfile: Dockerfile\n container_name: iaf-dz-backend\n env_file:\n - .env.local\n depends_on:\n iafactory-postgres:\n condition: service_healthy\n iafactory-redis:\n condition: service_healthy\n iafactory-qdrant:\n condition: service_started\n environment:\n # Région Souveraine\n SOVEREIGNTY_REGION: DZ\n SOVEREIGNTY_LABEL: \"Algérie\"\n TZ: Africa/Algiers\n\n # Database - uses env vars for password\n POSTGRES_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@iafactory-postgres:5432/${POSTGRES_DB:-archon}\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@iafactory-postgres:5432/${POSTGRES_DB:-archon}\n\n # Redis\n REDIS_URL: redis://iafactory-redis:6379/0\n REDIS_PASSWORD: ${REDIS_PASSWORD:-}\n\n # Qdrant\n QDRANT_HOST: iafactory-qdrant\n QDRANT_PORT: 6333\n\n # LLM Provider (Groq = gratuit et rapide)\n ENABLE_LLM: \"true\"\n LLM_PROVIDER: ${LLM_PROVIDER:-groq}\n LLM_MODEL: ${LLM_MODEL:-llama-3.3-70b-versatile}\n GROQ_API_KEY: ${GROQ_API_KEY:-}\n OPENAI_API_KEY: ${OPENAI_API_KEY:-}\n ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n GOOGLE_GENERATIVE_AI_API_KEY: ${GOOGLE_GENERATIVE_AI_API_KEY:-}\n\n # TTS Voice (ElevenLabs pour arabe haute qualité)\n ELEVENLABS_API_KEY: ${ELEVENLABS_API_KEY:-}\n\n # Security - REQUIRED: set in .env file\n API_SECRET_KEY: ${API_SECRET_KEY:?API_SECRET_KEY requis dans .env}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY:?JWT_SECRET_KEY requis dans .env}\n ALLOWED_ORIGINS: http://localhost:8180,http://localhost:8181,http://localhost:8182,http://localhost:8183,http://localhost:8184,http://localhost:8185\n\n # Rate Limiting\n RATE_LIMIT_PER_MINUTE: ${RATE_LIMIT_PER_MINUTE:-60}\n RATE_LIMIT_PER_HOUR: ${RATE_LIMIT_PER_HOUR:-1000}\n ENABLE_RATE_LIMITING: ${ENABLE_RATE_LIMITING:-true}\n\n # Embeddings (Multilingue FR/AR/EN)\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-sentence-transformers/paraphrase-multilingual-mpnet-base-v2}\n EMBEDDING_DEVICE: ${EMBEDDING_DEVICE:-cpu}\n EMBEDDING_BATCH_SIZE: ${EMBEDDING_BATCH_SIZE:-32}\n\n # Reranking\n USE_RERANKING: ${USE_RERANKING:-true}\n RERANKING_MODEL: ${RERANKING_MODEL:-cross-encoder/ms-marco-MiniLM-L-6-v2}\n RERANKING_TOP_K: ${RERANKING_TOP_K:-10}\n\n # PGVector\n USE_PGVECTOR: ${USE_PGVECTOR:-true}\n\n # Service Info\n SERVICE_NAME: iafactory-dz-api\n SERVICE_VERSION: 1.0.0\n LOG_LEVEL: ${LOG_LEVEL:-INFO}\n ENVIRONMENT: ${ENVIRONMENT:-development}\n\n # Features\n ENABLE_CORS: ${ENABLE_CORS:-true}\n ENABLE_METRICS: ${ENABLE_METRICS:-true}\n ENABLE_API_KEY_AUTH: ${ENABLE_API_KEY_AUTH:-false}\n\n # BMAD Configuration\n BMAD_DEFAULT_PROVIDER: ${BMAD_DEFAULT_PROVIDER:-groq}\n\n # Twilio SMS & WhatsApp (DZ)\n TWILIO_ACCOUNT_SID: ${TWILIO_ACCOUNT_SID:-}\n TWILIO_AUTH_TOKEN: ${TWILIO_AUTH_TOKEN:-}\n TWILIO_PHONE_NUMBER: ${TWILIO_PHONE_NUMBER:-}\n TWILIO_WHATSAPP_NUMBER: ${TWILIO_WHATSAPP_NUMBER:-}\n\n ports:\n - \"8180:8180\"\n volumes:\n - ./backend/rag-compat:/app\n - ./bmad:/bmad:ro\n - backend_cache:/root/.cache\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8180/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # ==============================================\n # FRONTEND APPLICATIONS\n # ==============================================\n\n # IAFactory Hub (Dashboard Principal)\n iafactory-hub:\n build:\n context: ./frontend/archon-ui\n dockerfile: Dockerfile\n args:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_API_SECRET_KEY: ${API_SECRET_KEY}\n container_name: iaf-dz-hub\n depends_on:\n - iafactory-backend\n environment:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_WS_URL: ${VITE_WS_URL:-ws://localhost:8180/ws}\n VITE_SHOW_DEVTOOLS: ${VITE_SHOW_DEVTOOLS:-true}\n VITE_API_SECRET_KEY: ${API_SECRET_KEY}\n VITE_API_KEY: ${API_SECRET_KEY}\n VITE_SOVEREIGNTY_REGION: DZ\n ports:\n - \"8182:3737\"\n volumes:\n - ./frontend/archon-ui/src:/app/src\n - ./frontend/archon-ui/public:/app/public\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # IAFactory Docs (Gestion Documentaire)\n iafactory-docs:\n build:\n context: ./frontend/rag-ui\n dockerfile: Dockerfile\n args:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n container_name: iaf-dz-docs\n depends_on:\n - iafactory-backend\n environment:\n REACT_APP_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_SOVEREIGNTY_REGION: DZ\n ports:\n - \"8183:5173\"\n volumes:\n - ./frontend/rag-ui/src:/app/src\n - ./frontend/rag-ui/public:/app/public\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # IAFactory Studio (Bolt.DIY - AI Code Editor)\n iafactory-studio:\n build:\n context: ./bolt-diy\n dockerfile: Dockerfile\n container_name: iaf-dz-studio\n depends_on:\n - iafactory-backend\n environment:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_ARCHON_API_URL: http://localhost:8180\n OPENAI_API_KEY: ${OPENAI_API_KEY:-}\n ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}\n GROQ_API_KEY: ${GROQ_API_KEY:-}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n GOOGLE_GENERATIVE_AI_API_KEY: ${GOOGLE_GENERATIVE_AI_API_KEY:-}\n OLLAMA_API_BASE_URL: http://iafactory-ollama:11434\n VITE_SOVEREIGNTY_REGION: DZ\n volumes:\n - ./bolt-diy/app:/app/app:ro\n - ./bolt-diy/public:/app/public\n ports:\n - \"8184:5173\"\n networks:\n - iafactory-net\n restart: unless-stopped\n profiles:\n - studio\n\n # ==============================================\n # SEO & LANDING PAGES\n # ==============================================\n\n # SEO-DZ-Boost - Landing Pages SEO pour Google Algérie\n iafactory-seo-dz:\n build:\n context: ./apps/seo-dz-boost\n dockerfile: Dockerfile\n container_name: iaf-dz-seo\n environment:\n ANALYTICS_PROVIDER: ${ANALYTICS_PROVIDER:-plausible}\n ANALYTICS_ID: ${ANALYTICS_ID:-}\n GA4_MEASUREMENT_ID: ${GA4_MEASUREMENT_ID:-}\n PLAUSIBLE_DOMAIN: ${PLAUSIBLE_DOMAIN:-www.iafactoryalgeria.com}\n MATOMO_URL: ${MATOMO_URL:-}\n MATOMO_SITE_ID: ${MATOMO_SITE_ID:-}\n ports:\n - \"8218:80\"\n networks:\n - iafactory-net\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:80/\"]\n interval: 30s\n timeout: 10s\n retries: 3\n labels:\n - \"traefik.enable=true\"\n - \"traefik.http.routers.seo-dz.rule=Host(`www.iafactoryalgeria.com`)\"\n - \"traefik.http.services.seo-dz.loadbalancer.server.port=80\"\n\n # ==============================================\n # DEVELOPER PORTAL (Module 16)\n # ==============================================\n\n # API Portal - Dashboard développeur façon OpenAI/Stripe\n iafactory-api-portal:\n build:\n context: ./apps/api-portal/frontend\n dockerfile: Dockerfile\n container_name: iaf-dz-api-portal\n depends_on:\n - iafactory-backend\n environment:\n VITE_API_URL: ${VITE_API_URL:-http://localhost:8180}\n VITE_SOVEREIGNTY_REGION: DZ\n ports:\n - \"8219:3000\"\n networks:\n - iafactory-net\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3000/\"]\n interval: 30s\n timeout: 10s\n retries: 3\n labels:\n - \"traefik.enable=true\"\n - \"traefik.http.routers.api-portal.rule=Host(`dev.iafactoryalgeria.com`)\"\n - \"traefik.http.services.api-portal.loadbalancer.server.port=3000\"\n\n # ==============================================\n # WORKFLOW & AUTOMATION\n # ==============================================\n\n # n8n Workflow Automation\n iafactory-n8n:\n image: docker.n8n.io/n8nio/n8n:latest\n container_name: iaf-dz-n8n\n depends_on:\n iafactory-postgres:\n condition: service_healthy\n environment:\n # Database\n DB_TYPE: postgresdb\n DB_POSTGRESDB_HOST: iafactory-postgres\n DB_POSTGRESDB_PORT: 5432\n DB_POSTGRESDB_DATABASE: ${POSTGRES_DB:-archon}\n DB_POSTGRESDB_USER: ${POSTGRES_USER:-postgres}\n DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}\n DB_POSTGRESDB_SCHEMA: n8n\n\n # Auth\n N8N_BASIC_AUTH_ACTIVE: ${N8N_BASIC_AUTH_ACTIVE:-true}\n N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER:-admin}\n N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD:-admin}\n\n # Webhook\n WEBHOOK_URL: ${N8N_WEBHOOK_URL:-http://localhost:8185}\n N8N_HOST: ${N8N_HOST:-localhost}\n N8N_PORT: 5678\n N8N_PROTOCOL: http\n\n # Timezone Algérie\n GENERIC_TIMEZONE: Africa/Algiers\n TZ: Africa/Algiers\n\n # Execution\n EXECUTIONS_DATA_PRUNE: \"true\"\n EXECUTIONS_DATA_MAX_AGE: 168\n\n # API\n N8N_API_ENABLED: \"true\"\n N8N_DIAGNOSTICS_ENABLED: \"false\"\n N8N_PERSONALIZATION_ENABLED: \"false\"\n volumes:\n - n8n_data:/home/node/.n8n\n - ./infrastructure/n8n/workflows:/home/node/workflows:ro\n ports:\n - \"8185:5678\"\n networks:\n - iafactory-net\n restart: unless-stopped\n\n # ==============================================\n # AI MODELS (Optionnel)\n # ==============================================\n\n # Ollama - Modèles IA Locaux (pour LLM Council)\n iafactory-ollama:\n image: ollama/ollama:latest\n container_name: iaf-dz-ollama\n volumes:\n - ollama_data:/root/.ollama\n ports:\n - \"127.0.0.1:11434:11434\"\n networks:\n - iafactory-net\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:11434/api/tags\"]\n interval: 30s\n timeout: 10s\n retries: 3\n # Pour GPU support (optionnel):\n # deploy:\n # resources:\n # reservations:\n # devices:\n # - driver: nvidia\n # count: 1\n # capabilities: [gpu]\n\n # ==============================================\n # MONITORING (Optionnel)\n # ==============================================\n\n # Prometheus\n iafactory-prometheus:\n image: prom/prometheus:latest\n container_name: iaf-dz-prometheus\n volumes:\n - ./infrastructure/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml\n - ./infrastructure/monitoring/alerts.yml:/etc/prometheus/alerts.yml\n - prometheus_data:/prometheus\n command:\n - '--config.file=/etc/prometheus/prometheus.yml'\n - '--storage.tsdb.path=/prometheus'\n - '--storage.tsdb.retention.time=30d'\n ports:\n - \"8187:9090\"\n networks:\n - iafactory-net\n restart: unless-stopped\n profiles:\n - monitoring\n\n # Grafana\n iafactory-grafana:\n image: grafana/grafana:latest\n container_name: iaf-dz-grafana\n depends_on:\n - iafactory-prometheus\n environment:\n GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}\n GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin}\n GF_USERS_ALLOW_SIGN_UP: \"false\"\n GF_SERVER_ROOT_URL: http://localhost:8188\n GF_INSTALL_PLUGINS: redis-datasource\n volumes:\n - ./infrastructure/monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards\n - ./infrastructure/monitoring/grafana/datasources:/etc/grafana/provisioning/datasources\n - grafana_data:/var/lib/grafana\n ports:\n - \"8188:3000\"\n networks:\n - iafactory-net\n restart: unless-stopped\n profiles:\n - monitoring\n\n# ==============================================\n# NETWORKS\n# ==============================================\nnetworks:\n iafactory-net:\n driver: bridge\n name: iafactory-net\n\n# ==============================================\n# VOLUMES\n# ==============================================\nvolumes:\n postgres_data:\n name: iaf-dz-postgres-data\n redis_data:\n name: iaf-dz-redis-data\n qdrant_data:\n name: iaf-dz-qdrant-data\n ollama_data:\n name: iaf-dz-ollama-data\n backend_cache:\n name: iaf-dz-backend-cache\n prometheus_data:\n name: iaf-dz-prometheus-data\n grafana_data:\n name: iaf-dz-grafana-data\n n8n_data:\n name: iaf-dz-n8n-data\n"}}, "agents/core/base_agent.py": {"7d6e298b582d583185cd24b914c17d9daeaa9491": {"t": 1785745450.5017703, "n": 3356, "h": "08ef0525238a404f", "c": "\"\"\"\nBase Agent Class for IA Factory\n\"\"\"\nfrom typing import List, Dict, Any, Optional, Callable\nfrom pydantic import BaseModel, Field\nfrom abc import ABC, abstractmethod\nfrom openai import AsyncOpenAI\nfrom anthropic import AsyncAnthropic\nimport logging\nfrom datetime import datetime\nimport os\n\nlogger = logging.getLogger(__name__)\n\nclass AgentConfig(BaseModel):\n name: str\n model: str = \"deepseek-chat\"\n temperature: float = 0.7\n max_tokens: int = 2000\n tools: List[str] = Field(default_factory=list)\n memory_enabled: bool = True\n language: str = \"fr\"\n system_prompt: Optional[str] = None\n\nclass AgentMessage(BaseModel):\n role: str\n content: str\n timestamp: datetime = Field(default_factory=datetime.now)\n metadata: Dict[str, Any] = Field(default_factory=dict)\n\nclass AgentResponse(BaseModel):\n content: str\n tools_used: List[str] = Field(default_factory=list)\n metadata: Dict[str, Any] = Field(default_factory=dict)\n tokens_used: Optional[int] = None\n duration_ms: Optional[float] = None\n\nclass BaseAgent(ABC):\n def __init__(self, config: AgentConfig):\n self.config = config\n self.memory: List[AgentMessage] = [] if config.memory_enabled else None\n self.tools_registry: Dict[str, Callable] = {}\n self.client = self._init_llm_client()\n logger.info(f\"Initialized {config.name} with model {config.model}\")\n \n def _init_llm_client(self):\n model = self.config.model.lower()\n if \"deepseek\" in model:\n return AsyncOpenAI(\n api_key=os.getenv(\"DEEPSEEK_API_KEY\"),\n base_url=\"https://api.deepseek.com\"\n )\n elif model.startswith(\"gpt\"):\n return AsyncOpenAI(api_key=os.getenv(\"OPENAI_API_KEY\"))\n elif model.startswith(\"claude\"):\n return AsyncAnthropic(api_key=os.getenv(\"ANTHROPIC_API_KEY\"))\n return AsyncOpenAI(api_key=os.getenv(\"DEEPSEEK_API_KEY\"), base_url=\"https://api.deepseek.com\")\n \n @abstractmethod\n async def execute(self, input_data: Dict[str, Any]) -> AgentResponse:\n pass\n \n def add_memory(self, message: AgentMessage):\n if self.memory is not None:\n self.memory.append(message)\n if len(self.memory) > 50:\n self.memory = self.memory[-50:]\n \n async def _call_llm(self, messages: List[Dict[str, str]]) -> Dict[str, Any]:\n try:\n completion = await self.client.chat.completions.create(\n model=self.config.model,\n messages=messages,\n temperature=self.config.temperature,\n max_tokens=self.config.max_tokens\n )\n return {\"content\": completion.choices[0].message.content, \"tokens\": completion.usage.total_tokens}\n except Exception as e:\n logger.error(f\"LLM call failed: {e}\")\n return {\"content\": f\"Erreur: {str(e)}\", \"tokens\": 0}\n\nclass MultiAgentTeam:\n def __init__(self, agents: List[BaseAgent], orchestrator: str = \"sequential\"):\n self.agents = agents\n self.orchestrator = orchestrator\n \n async def execute_all(self, input_data: Dict[str, Any]) -> List[AgentResponse]:\n results = []\n for agent in self.agents:\n result = await agent.execute(input_data)\n results.append(result)\n return results\n"}, "cec8535cc766b8b211c8bee394ecca3c44b713a7": {"t": 1785749288.735945, "n": 3356, "h": "08ef0525238a404f", "c": "\"\"\"\nBase Agent Class for IA Factory\n\"\"\"\nfrom typing import List, Dict, Any, Optional, Callable\nfrom pydantic import BaseModel, Field\nfrom abc import ABC, abstractmethod\nfrom openai import AsyncOpenAI\nfrom anthropic import AsyncAnthropic\nimport logging\nfrom datetime import datetime\nimport os\n\nlogger = logging.getLogger(__name__)\n\nclass AgentConfig(BaseModel):\n name: str\n model: str = \"deepseek-chat\"\n temperature: float = 0.7\n max_tokens: int = 2000\n tools: List[str] = Field(default_factory=list)\n memory_enabled: bool = True\n language: str = \"fr\"\n system_prompt: Optional[str] = None\n\nclass AgentMessage(BaseModel):\n role: str\n content: str\n timestamp: datetime = Field(default_factory=datetime.now)\n metadata: Dict[str, Any] = Field(default_factory=dict)\n\nclass AgentResponse(BaseModel):\n content: str\n tools_used: List[str] = Field(default_factory=list)\n metadata: Dict[str, Any] = Field(default_factory=dict)\n tokens_used: Optional[int] = None\n duration_ms: Optional[float] = None\n\nclass BaseAgent(ABC):\n def __init__(self, config: AgentConfig):\n self.config = config\n self.memory: List[AgentMessage] = [] if config.memory_enabled else None\n self.tools_registry: Dict[str, Callable] = {}\n self.client = self._init_llm_client()\n logger.info(f\"Initialized {config.name} with model {config.model}\")\n \n def _init_llm_client(self):\n model = self.config.model.lower()\n if \"deepseek\" in model:\n return AsyncOpenAI(\n api_key=os.getenv(\"DEEPSEEK_API_KEY\"),\n base_url=\"https://api.deepseek.com\"\n )\n elif model.startswith(\"gpt\"):\n return AsyncOpenAI(api_key=os.getenv(\"OPENAI_API_KEY\"))\n elif model.startswith(\"claude\"):\n return AsyncAnthropic(api_key=os.getenv(\"ANTHROPIC_API_KEY\"))\n return AsyncOpenAI(api_key=os.getenv(\"DEEPSEEK_API_KEY\"), base_url=\"https://api.deepseek.com\")\n \n @abstractmethod\n async def execute(self, input_data: Dict[str, Any]) -> AgentResponse:\n pass\n \n def add_memory(self, message: AgentMessage):\n if self.memory is not None:\n self.memory.append(message)\n if len(self.memory) > 50:\n self.memory = self.memory[-50:]\n \n async def _call_llm(self, messages: List[Dict[str, str]]) -> Dict[str, Any]:\n try:\n completion = await self.client.chat.completions.create(\n model=self.config.model,\n messages=messages,\n temperature=self.config.temperature,\n max_tokens=self.config.max_tokens\n )\n return {\"content\": completion.choices[0].message.content, \"tokens\": completion.usage.total_tokens}\n except Exception as e:\n logger.error(f\"LLM call failed: {e}\")\n return {\"content\": f\"Erreur: {str(e)}\", \"tokens\": 0}\n\nclass MultiAgentTeam:\n def __init__(self, agents: List[BaseAgent], orchestrator: str = \"sequential\"):\n self.agents = agents\n self.orchestrator = orchestrator\n \n async def execute_all(self, input_data: Dict[str, Any]) -> List[AgentResponse]:\n results = []\n for agent in self.agents:\n result = await agent.execute(input_data)\n results.append(result)\n return results\n"}}, "services/api/app/llm_router/providers/deepseek_provider.py": {"7d6e298b582d583185cd24b914c17d9daeaa9491": {"t": 1785746391.4112089, "n": 2401, "h": "7c15bf020742b2f2", "c": "import requests\nimport time\nfrom typing import List\nfrom .base import BaseProvider, Message, LLMResponse\n\nclass DeepSeekProvider(BaseProvider):\n \"\"\"Provider for DeepSeek models (excellent for code)\"\"\"\n\n # Pricing per 1M tokens\n PRICING = {\n \"deepseek-chat\": 0.14,\n \"deepseek-coder\": 0.14\n }\n\n def __init__(self, api_key: str, model_name: str):\n super().__init__(api_key, model_name)\n self.api_url = \"https://api.deepseek.com/v1/chat/completions\"\n self.headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"Content-Type\": \"application/json\"\n }\n\n def generate( # FIXED: removed async, using requests HTTP\n self,\n messages: List[Message],\n temperature: float = 0.7,\n max_tokens: int = 2000,\n **kwargs\n ) -> LLMResponse:\n \"\"\"Generate completion using DeepSeek\"\"\"\n start_time = time.time()\n\n # Format messages for DeepSeek API\n formatted_messages = self.format_messages(messages)\n\n # Prepare request payload\n payload = {\n \"model\": self.model_name,\n \"messages\": formatted_messages,\n \"temperature\": temperature,\n \"max_tokens\": max_tokens\n }\n\n # Call DeepSeek API via HTTP (avoids OpenAI SDK 'proxies' issue)\n response = requests.post(\n self.api_url,\n headers=self.headers,\n json=payload,\n timeout=30\n )\n\n latency_ms = int((time.time() - start_time) * 1000)\n\n # Check response\n if response.status_code != 200:\n raise Exception(f\"DeepSeek API error {response.status_code}: {response.text}\")\n\n data = response.json()\n\n # Extract response\n content = data[\"choices\"][0][\"message\"][\"content\"]\n tokens_used = data[\"usage\"][\"total_tokens\"]\n\n # Calculate cost\n cost = self.calculate_cost(tokens_used)\n\n return LLMResponse(\n content=content,\n model=self.model_name,\n provider=\"deepseek\",\n tokens_used=tokens_used,\n cost=cost,\n latency_ms=latency_ms\n )\n\n def calculate_cost(self, tokens_used: int) -> float:\n \"\"\"Calculate cost for DeepSeek based on pricing\"\"\"\n cost_per_1m = self.PRICING.get(self.model_name, 0.14)\n return (tokens_used / 1_000_000) * cost_per_1m\n"}, "cec8535cc766b8b211c8bee394ecca3c44b713a7": {"t": 1785749292.620687, "n": 2401, "h": "7c15bf020742b2f2", "c": "import requests\nimport time\nfrom typing import List\nfrom .base import BaseProvider, Message, LLMResponse\n\nclass DeepSeekProvider(BaseProvider):\n \"\"\"Provider for DeepSeek models (excellent for code)\"\"\"\n\n # Pricing per 1M tokens\n PRICING = {\n \"deepseek-chat\": 0.14,\n \"deepseek-coder\": 0.14\n }\n\n def __init__(self, api_key: str, model_name: str):\n super().__init__(api_key, model_name)\n self.api_url = \"https://api.deepseek.com/v1/chat/completions\"\n self.headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"Content-Type\": \"application/json\"\n }\n\n def generate( # FIXED: removed async, using requests HTTP\n self,\n messages: List[Message],\n temperature: float = 0.7,\n max_tokens: int = 2000,\n **kwargs\n ) -> LLMResponse:\n \"\"\"Generate completion using DeepSeek\"\"\"\n start_time = time.time()\n\n # Format messages for DeepSeek API\n formatted_messages = self.format_messages(messages)\n\n # Prepare request payload\n payload = {\n \"model\": self.model_name,\n \"messages\": formatted_messages,\n \"temperature\": temperature,\n \"max_tokens\": max_tokens\n }\n\n # Call DeepSeek API via HTTP (avoids OpenAI SDK 'proxies' issue)\n response = requests.post(\n self.api_url,\n headers=self.headers,\n json=payload,\n timeout=30\n )\n\n latency_ms = int((time.time() - start_time) * 1000)\n\n # Check response\n if response.status_code != 200:\n raise Exception(f\"DeepSeek API error {response.status_code}: {response.text}\")\n\n data = response.json()\n\n # Extract response\n content = data[\"choices\"][0][\"message\"][\"content\"]\n tokens_used = data[\"usage\"][\"total_tokens\"]\n\n # Calculate cost\n cost = self.calculate_cost(tokens_used)\n\n return LLMResponse(\n content=content,\n model=self.model_name,\n provider=\"deepseek\",\n tokens_used=tokens_used,\n cost=cost,\n latency_ms=latency_ms\n )\n\n def calculate_cost(self, tokens_used: int) -> float:\n \"\"\"Calculate cost for DeepSeek based on pricing\"\"\"\n cost_per_1m = self.PRICING.get(self.model_name, 0.14)\n return (tokens_used / 1_000_000) * cost_per_1m\n"}}, "apps/_archived/council/index_server.html": {"7d6e298b582d583185cd24b914c17d9daeaa9491": {"t": 1785746405.0088425, "n": 58274, "h": "f1d4d1fa1eed03d7", "c": "\n\n
\n \n \nComposez votre équipe d'experts IA sur mesure avec une infinité de combinaisons
\nComposez votre équipe d'experts IA sur mesure avec une infinité de combinaisons
\nComposez votre équipe d'experts IA sur mesure avec une infinité de combinaisons
\nComposez votre équipe d'experts IA sur mesure avec une infinité de combinaisons
\n