name: glpi-neuroforge-master services: searxng: image: ${SEARXNG_IMAGE:-docker.io/searxng/searxng:latest} profiles: - research restart: unless-stopped environment: SEARXNG_SECRET: ${SEARXNG_SECRET} SEARXNG_BASE_URL: http://searxng:8080/ FORCE_OWNERSHIP: 'false' volumes: - ./deploy/searxng/settings.yml:/etc/searxng/settings.yml:ro - searxng-cache:/var/cache/searxng ports: - 127.0.0.1:${SEARXNG_HOST_PORT:-8888}:8080 read_only: true tmpfs: - /tmp:size=64m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL neuroforge: image: git.send.nrw/sendnrw/glpi-neuroforge-mega-neuroforge:${IMAGE_TAG:?Set IMAGE_TAG to an immutable release tag, for example 1.6.2} command: - -data - /app/data - -listen - :8080 restart: unless-stopped environment: NEUROFORGE_ADMIN_TOKEN: ${NEUROFORGE_ADMIN_TOKEN:?Set a unique NeuroForge admin token} NEUROFORGE_APP_API_KEY: ${NEUROFORGE_APP_API_KEY:?Set a unique NeuroForge app API key} NEUROFORGE_INTEGRATION_TOKEN: ${NEUROFORGE_INTEGRATION_TOKEN:?Set a unique NeuroForge integration token} NEUROFORGE_CONTROL_READ_TOKEN: ${NEUROFORGE_CONTROL_READ_TOKEN:?Set a unique NeuroForge control read token} NEUROFORGE_WORKER_TOKEN: ${NEUROFORGE_WORKER_TOKEN:?Set a unique NeuroForge worker token} NEUROFORGE_METRICS_TOKEN: ${NEUROFORGE_METRICS_TOKEN:?Set a unique NeuroForge metrics token} NEUROFORGE_CLUSTER_TOKEN: ${NEUROFORGE_CLUSTER_TOKEN:-} OPENAI_API_KEY: ${OPENAI_API_KEY:-} NEUROFORGE_OLLAMA_URL: ${OLLAMA_BASE_URL:?Set Ollama URL reachable from master, normally GPU subagent host} NEUROFORGE_OLLAMA_CHAT_MODEL: ${OLLAMA_MODEL:-gemma3} NEUROFORGE_OLLAMA_EMBEDDING_MODEL: ${OLLAMA_EMBEDDING_MODEL:-embeddinggemma} NEUROFORGE_OLLAMA_NUM_CTX: ${NEUROFORGE_OLLAMA_NUM_CTX:-8192} NEUROFORGE_OLLAMA_NUM_PREDICT: ${NEUROFORGE_OLLAMA_NUM_PREDICT:-0} NEUROFORGE_WORKER_LEASE_SECONDS: ${NEUROFORGE_WORKER_LEASE_SECONDS:-120} NEUROFORGE_WORKER_HEARTBEAT_SECONDS: ${NEUROFORGE_WORKER_HEARTBEAT_SECONDS:-15} NEUROFORGE_WORKER_STALE_AFTER_SECONDS: ${NEUROFORGE_WORKER_STALE_AFTER_SECONDS:-60} NEUROFORGE_WORKER_DEFAULT_MAX_ATTEMPTS: ${NEUROFORGE_WORKER_DEFAULT_MAX_ATTEMPTS:-3} NEUROFORGE_WORKER_RETRY_BACKOFF_SECONDS: ${NEUROFORGE_WORKER_RETRY_BACKOFF_SECONDS:-15} NEUROFORGE_WORKER_MAX_QUEUED_JOBS: ${NEUROFORGE_WORKER_MAX_QUEUED_JOBS:-5000} NEUROFORGE_WORKER_MAX_QUEUED_PAYLOAD_MB: ${NEUROFORGE_WORKER_MAX_QUEUED_PAYLOAD_MB:-128} NEUROFORGE_WORKER_MASTER_APPLY_MAX_ATTEMPTS: ${NEUROFORGE_WORKER_MASTER_APPLY_MAX_ATTEMPTS:-5} NEUROFORGE_WORKER_MASTER_APPLY_BACKOFF_SECONDS: ${NEUROFORGE_WORKER_MASTER_APPLY_BACKOFF_SECONDS:-5} NEUROFORGE_WORKER_JOB_RETENTION_HOURS: ${NEUROFORGE_WORKER_JOB_RETENTION_HOURS:-24} NEUROFORGE_WORKER_MAX_TERMINAL_JOBS: ${NEUROFORGE_WORKER_MAX_TERMINAL_JOBS:-2000} NEUROFORGE_GRAPH_BACKFILL_ENABLED: ${NEUROFORGE_GRAPH_BACKFILL_ENABLED:-true} NEUROFORGE_GRAPH_BACKFILL_INTERVAL_SECONDS: ${NEUROFORGE_GRAPH_BACKFILL_INTERVAL_SECONDS:-10} NEUROFORGE_GRAPH_BACKFILL_BATCH_SIZE: ${NEUROFORGE_GRAPH_BACKFILL_BATCH_SIZE:-16} NEUROFORGE_GRAPH_BACKFILL_MAX_QUEUED: ${NEUROFORGE_GRAPH_BACKFILL_MAX_QUEUED:-64} NEUROFORGE_GRAPH_BACKFILL_MIN_DEGREE: ${NEUROFORGE_GRAPH_BACKFILL_MIN_DEGREE:-3} NEUROFORGE_GRAPH_CANDIDATE_MULTIPLIER: ${NEUROFORGE_GRAPH_CANDIDATE_MULTIPLIER:-6} NEUROFORGE_GRAPH_RETRY_AFTER_MINUTES: ${NEUROFORGE_GRAPH_RETRY_AFTER_MINUTES:-360} NEUROFORGE_GRAPH_REQUIRE_WORKER: ${NEUROFORGE_GRAPH_REQUIRE_WORKER:-true} NEUROFORGE_GRAPH_MAX_HOPS: ${NEUROFORGE_GRAPH_MAX_HOPS:-3} NEUROFORGE_GRAPH_HOP_DECAY: ${NEUROFORGE_GRAPH_HOP_DECAY:-0.60} NEUROFORGE_GRAPH_MAX_EXPANSION: ${NEUROFORGE_GRAPH_MAX_EXPANSION:-64} NEUROFORGE_GRAPH_MIN_EDGE_WEIGHT: ${NEUROFORGE_GRAPH_MIN_EDGE_WEIGHT:-0.05} NEUROFORGE_OFFLOAD_CHAT: ${NEUROFORGE_OFFLOAD_CHAT:-true} NEUROFORGE_OFFLOAD_EMBEDDINGS: ${NEUROFORGE_OFFLOAD_EMBEDDINGS:-true} NEUROFORGE_DISTRIBUTED_INFERENCE_WAIT_SECONDS: ${NEUROFORGE_DISTRIBUTED_INFERENCE_WAIT_SECONDS:-180} NEUROFORGE_READINESS_OLLAMA_LIVE: ${NEUROFORGE_READINESS_OLLAMA_LIVE:-true} NEUROFORGE_CONTROLLED_LEARNING: ${NEUROFORGE_CONTROLLED_LEARNING:-true} NEUROFORGE_GOAL_LEARNING_ENABLED: ${NEUROFORGE_GOAL_LEARNING_ENABLED:-false} NEUROFORGE_RESEARCH_ENABLED: ${NEUROFORGE_RESEARCH_ENABLED:-false} NEUROFORGE_SEARXNG_ENABLED: ${NEUROFORGE_SEARXNG_ENABLED:-false} NEUROFORGE_SEARXNG_URL: ${NEUROFORGE_SEARXNG_URL:-http://searxng:8080} NEUROFORGE_RESEARCH_GOAL_ENABLED: ${NEUROFORGE_RESEARCH_GOAL_ENABLED:-true} NEUROFORGE_AUTONOMY_ENABLED: ${NEUROFORGE_AUTONOMY_ENABLED:-false} NEUROFORGE_AUTONOMY_INTERVAL_MINUTES: ${NEUROFORGE_AUTONOMY_INTERVAL_MINUTES:-30} NEUROFORGE_RESEARCH_MAX_QUERIES: ${NEUROFORGE_RESEARCH_MAX_QUERIES:-2} NEUROFORGE_RESEARCH_MAX_PAGES: ${NEUROFORGE_RESEARCH_MAX_PAGES:-4} NEUROFORGE_KB_STAGING_ENABLED: ${NEUROFORGE_KB_STAGING_ENABLED:-true} NEUROFORGE_KB_STAGING_URL: http://knowledge:8080/api/integrations/staging NEUROFORGE_KB_STAGING_TOKEN: ${KB_INTEGRATION_TOKEN:?Set the Knowledge integration token} NEUROFORGE_KB_STAGING_MIN_EVIDENCE: ${NEUROFORGE_KB_STAGING_MIN_EVIDENCE:-4} NEUROFORGE_KB_STAGING_MIN_SOURCES: ${NEUROFORGE_KB_STAGING_MIN_SOURCES:-2} NEUROFORGE_KB_STAGING_MIN_CORROBORATIONS: ${NEUROFORGE_KB_STAGING_MIN_CORROBORATIONS:-0} NEUROFORGE_KB_STAGING_MAX_EVIDENCE: ${NEUROFORGE_KB_STAGING_MAX_EVIDENCE:-12} NEUROFORGE_KB_STAGING_SYNTHESIS_MODE: ${NEUROFORGE_KB_STAGING_SYNTHESIS_MODE:-llm} NEUROFORGE_KB_STAGING_REQUIRE_AUTHORITATIVE_SOURCE: ${NEUROFORGE_KB_STAGING_REQUIRE_AUTHORITATIVE_SOURCE:-true} NEUROFORGE_KB_STAGING_MIN_AUTHORITATIVE_SOURCES: ${NEUROFORGE_KB_STAGING_MIN_AUTHORITATIVE_SOURCES:-1} NEUROFORGE_KB_STAGING_AUTHORITATIVE_DOMAINS: ${NEUROFORGE_KB_STAGING_AUTHORITATIVE_DOMAINS:-} NEUROFORGE_KB_STAGING_VERIFY_CLAIMS: ${NEUROFORGE_KB_STAGING_VERIFY_CLAIMS:-true} NEUROFORGE_KB_STAGING_MIN_CLAIM_COVERAGE: ${NEUROFORGE_KB_STAGING_MIN_CLAIM_COVERAGE:-1.0} NEUROFORGE_KB_STAGING_REQUIRE_AUTHORITATIVE_ACTIONS: ${NEUROFORGE_KB_STAGING_REQUIRE_AUTHORITATIVE_ACTIONS:-true} NEUROFORGE_KB_STAGING_MAX_VERIFICATION_STATEMENTS: ${NEUROFORGE_KB_STAGING_MAX_VERIFICATION_STATEMENTS:-32} NEUROFORGE_KB_STAGING_VERIFICATION_REPAIR: ${NEUROFORGE_KB_STAGING_VERIFICATION_REPAIR:-true} NEUROFORGE_KB_STAGING_SYNTHESIS_MAX_TOKENS: ${NEUROFORGE_KB_STAGING_SYNTHESIS_MAX_TOKENS:-2600} NEUROFORGE_KB_STAGING_EVIDENCE_PROMPT_MAX_CHARS: ${NEUROFORGE_KB_STAGING_EVIDENCE_PROMPT_MAX_CHARS:-14000} NEUROFORGE_KB_STAGING_MIN_ARTICLE_CHARS: ${NEUROFORGE_KB_STAGING_MIN_ARTICLE_CHARS:-3500} NEUROFORGE_KB_STAGING_TARGET_ARTICLE_CHARS: ${NEUROFORGE_KB_STAGING_TARGET_ARTICLE_CHARS:-6500} NEUROFORGE_KB_STAGING_MAX_ARTICLE_CHARS: ${NEUROFORGE_KB_STAGING_MAX_ARTICLE_CHARS:-10000} NEUROFORGE_KB_STAGING_MIN_ANSWER_CHARS: ${NEUROFORGE_KB_STAGING_MIN_ANSWER_CHARS:-160} NEUROFORGE_KB_STAGING_MAX_ANSWER_CHARS: ${NEUROFORGE_KB_STAGING_MAX_ANSWER_CHARS:-1200} ports: - ${NEUROFORGE_BIND_ADDRESS:-0.0.0.0}:${NEUROFORGE_HOST_PORT:-8090}:8080 volumes: - neuroforge-data:/app/data read_only: true tmpfs: - /tmp:size=64m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL healthcheck: test: - CMD - wget - -q - -O - '-' - http://127.0.0.1:8080/readyz interval: 15s timeout: 3s retries: 8 start_period: 15s stop_grace_period: 35s agent-data-init: image: git.send.nrw/sendnrw/glpi-neuroforge-mega-agent-data-init:${IMAGE_TAG:?Set IMAGE_TAG to an immutable release tag, for example 1.6.2} restart: 'no' user: 0:0 volumes: - agent-data:/app/data security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - FOWNER agent: image: git.send.nrw/sendnrw/glpi-neuroforge-mega-agent:${IMAGE_TAG:?Set IMAGE_TAG to an immutable release tag, for example 1.6.2} restart: unless-stopped environment: AI_CONTENT_LABEL_ENABLED: ${AI_CONTENT_LABEL_ENABLED:-} AUTO_CATEGORY: ${AUTO_CATEGORY:-} AUTO_ESCALATION: ${AUTO_ESCALATION:-} AUTO_PRIORITY: ${AUTO_PRIORITY:-} AUTO_REPLY: ${AUTO_REPLY:-} BRAIN_ACTIVITY_API_KEY: ${NEUROFORGE_INTEGRATION_TOKEN:?Set the NeuroForge integration token} BRAIN_ACTIVITY_URL: http://neuroforge:8080/api/v1/integrations/events CATEGORY_CONFIDENCE: ${CATEGORY_CONFIDENCE:-} CATEGORY_PROMPT_LIMIT: ${CATEGORY_PROMPT_LIMIT:-} CHANGE_CALENDAR_ENABLED: ${CHANGE_CALENDAR_ENABLED:-} CHANGE_LOOKAHEAD: ${CHANGE_LOOKAHEAD:-} CHANGE_LOOKBACK: ${CHANGE_LOOKBACK:-} COMMUNICATION_CLOSING: ${COMMUNICATION_CLOSING:-} COMMUNICATION_LANGUAGE: ${COMMUNICATION_LANGUAGE:-} COMMUNICATION_SALUTATION: ${COMMUNICATION_SALUTATION:-} COMMUNICATION_SIGNATURE: ${COMMUNICATION_SIGNATURE:-} COMMUNICATION_STYLE: ${COMMUNICATION_STYLE:-} CONTEXT_BLOCK_AUTO_REPLY_ON_ERRORS: ${CONTEXT_BLOCK_AUTO_REPLY_ON_ERRORS:-} CONTEXT_BLOCK_AUTO_REPLY_ON_INCIDENT: ${CONTEXT_BLOCK_AUTO_REPLY_ON_INCIDENT:-} CONTEXT_ENABLED: ${CONTEXT_ENABLED:-} CONTEXT_INCIDENT_REPLY_TEXT: ${CONTEXT_INCIDENT_REPLY_TEXT:-} CONTEXT_MAINTENANCE_REPLY_TEXT: ${CONTEXT_MAINTENANCE_REPLY_TEXT:-} CONTEXT_RELEVANCE_MIN_SCORE: ${CONTEXT_RELEVANCE_MIN_SCORE:-} CONTEXT_STATUS_REPLY_ENABLED: ${CONTEXT_STATUS_REPLY_ENABLED:-} CONTEXT_STATUS_REPLY_MIN_AI_CONFIDENCE: ${CONTEXT_STATUS_REPLY_MIN_AI_CONFIDENCE:-} CONTEXT_STATUS_REPLY_MIN_FINAL_SCORE: ${CONTEXT_STATUS_REPLY_MIN_FINAL_SCORE:-} CONTEXT_STATUS_REPLY_MIN_RELEVANCE: ${CONTEXT_STATUS_REPLY_MIN_RELEVANCE:-} CONTEXT_TIMEOUT: ${CONTEXT_TIMEOUT:-} CONTROL_READ_TOKEN: ${CONTROL_READ_TOKEN:?Set the Agent control read token} DATA_DIR: /app/data DRY_RUN: ${DRY_RUN:-} ESCALATION_ADD_PRIVATE_FOLLOWUP: ${ESCALATION_ADD_PRIVATE_FOLLOWUP:-} ESCALATION_ALLOWED_ACTIONS: ${ESCALATION_ALLOWED_ACTIONS:-} ESCALATION_ALLOWED_REASON_CODES: ${ESCALATION_ALLOWED_REASON_CODES:-} ESCALATION_ANALYSIS_TIMEOUT: ${ESCALATION_ANALYSIS_TIMEOUT:-} ESCALATION_CONFIDENCE: ${ESCALATION_CONFIDENCE:-} ESCALATION_ENABLED: ${ESCALATION_ENABLED:-} ESCALATION_MAJOR_INCIDENT_MIN_RELEVANCE: ${ESCALATION_MAJOR_INCIDENT_MIN_RELEVANCE:-} ESCALATION_MAJOR_INCIDENT_NOTE: ${ESCALATION_MAJOR_INCIDENT_NOTE:-} ESCALATION_MANAGER_REVIEW_GROUP_ID: ${ESCALATION_MANAGER_REVIEW_GROUP_ID:-} ESCALATION_MANAGER_REVIEW_MIN_LEVEL: ${ESCALATION_MANAGER_REVIEW_MIN_LEVEL:-} ESCALATION_MANAGER_REVIEW_NOTE: ${ESCALATION_MANAGER_REVIEW_NOTE:-} ESCALATION_MANAGER_REVIEW_USER_ID: ${ESCALATION_MANAGER_REVIEW_USER_ID:-} ESCALATION_MAX_LEVEL: ${ESCALATION_MAX_LEVEL:-} ESCALATION_MIN_AGE: ${ESCALATION_MIN_AGE:-} ESCALATION_MIN_INACTIVITY: ${ESCALATION_MIN_INACTIVITY:-} ESCALATION_SCAN_INTERVAL: ${ESCALATION_SCAN_INTERVAL:-} ESCALATION_SECOND_LEVEL_GROUP_ID: ${ESCALATION_SECOND_LEVEL_GROUP_ID:-} ESCALATION_SECOND_LEVEL_NOTE: ${ESCALATION_SECOND_LEVEL_NOTE:-} ESCALATION_SECURITY_GROUP_ID: ${ESCALATION_SECURITY_GROUP_ID:-} ESCALATION_SECURITY_NOTE: ${ESCALATION_SECURITY_NOTE:-} ESCALATION_SERVICE_OWNER_GROUP_ID: ${ESCALATION_SERVICE_OWNER_GROUP_ID:-} ESCALATION_SERVICE_OWNER_MIN_LEVEL: ${ESCALATION_SERVICE_OWNER_MIN_LEVEL:-} ESCALATION_SERVICE_OWNER_NOTE: ${ESCALATION_SERVICE_OWNER_NOTE:-} ESCALATION_SERVICE_OWNER_USER_ID: ${ESCALATION_SERVICE_OWNER_USER_ID:-} ESCALATION_SLA_RISK_WINDOW: ${ESCALATION_SLA_RISK_WINDOW:-} ESCALATION_WEBHOOK_ALLOW_INSECURE_HTTP: ${ESCALATION_WEBHOOK_ALLOW_INSECURE_HTTP:-} ESCALATION_WEBHOOK_BEARER_TOKEN: ${ESCALATION_WEBHOOK_BEARER_TOKEN:-} ESCALATION_WEBHOOK_TIMEOUT: ${ESCALATION_WEBHOOK_TIMEOUT:-} ESCALATION_WEBHOOK_URL: ${ESCALATION_WEBHOOK_URL:-} GLPI_AGENT_USER_ID: ${GLPI_AGENT_USER_ID:-} GLPI_ALLOWED_STATUS_IDS: ${GLPI_ALLOWED_STATUS_IDS:-} GLPI_ALLOW_INSECURE_HTTP: ${GLPI_ALLOW_INSECURE_HTTP:-} GLPI_API_VERSION: ${GLPI_API_VERSION:-} GLPI_CHANGE_FILTER: ${GLPI_CHANGE_FILTER:-} GLPI_CHANGE_LIMIT: ${GLPI_CHANGE_LIMIT:-} GLPI_CHANGE_PATH: ${GLPI_CHANGE_PATH:-} GLPI_CLIENT_ID: ${GLPI_CLIENT_ID:?Set GLPI_CLIENT_ID} GLPI_CLIENT_SECRET: ${GLPI_CLIENT_SECRET:?Set GLPI_CLIENT_SECRET} GLPI_ESCALATION_FILTER: ${GLPI_ESCALATION_FILTER:-} GLPI_ESCALATION_GROUP_PATCH_FIELD: ${GLPI_ESCALATION_GROUP_PATCH_FIELD:-} GLPI_ESCALATION_ITIL_LINK_BODY: ${GLPI_ESCALATION_ITIL_LINK_BODY:-} GLPI_ESCALATION_ITIL_LINK_PATH: ${GLPI_ESCALATION_ITIL_LINK_PATH:-} GLPI_ESCALATION_LIMIT: ${GLPI_ESCALATION_LIMIT:-} GLPI_ESCALATION_USER_PATCH_FIELD: ${GLPI_ESCALATION_USER_PATCH_FIELD:-} GLPI_KB_AUTO_REPLY: ${GLPI_KB_AUTO_REPLY:-} GLPI_KB_AUTO_REPLY_ALLOW_UNCATEGORIZED: ${GLPI_KB_AUTO_REPLY_ALLOW_UNCATEGORIZED:-} GLPI_KB_AUTO_REPLY_CATEGORY_IDS: ${GLPI_KB_AUTO_REPLY_CATEGORY_IDS:-} GLPI_KB_AUTO_REPLY_ITIL_CATEGORY_IDS: ${GLPI_KB_AUTO_REPLY_ITIL_CATEGORY_IDS:-} GLPI_KB_AUTO_REPLY_UNCATEGORIZED_ARTICLE_IDS: ${GLPI_KB_AUTO_REPLY_UNCATEGORIZED_ARTICLE_IDS:-} GLPI_KB_ENABLED: ${GLPI_KB_ENABLED:-} GLPI_KB_FILTER: ${GLPI_KB_FILTER:-} GLPI_KB_LIMIT: ${GLPI_KB_LIMIT:-} GLPI_KB_PATH: ${GLPI_KB_PATH:-} GLPI_KB_SOURCE: ${GLPI_KB_SOURCE:-} GLPI_KB_SYNC_INTERVAL: ${GLPI_KB_SYNC_INTERVAL:-} GLPI_MAJOR_INCIDENT_FILTER: ${GLPI_MAJOR_INCIDENT_FILTER:-} GLPI_MAJOR_INCIDENT_LIMIT: ${GLPI_MAJOR_INCIDENT_LIMIT:-} GLPI_PASSWORD: ${GLPI_PASSWORD:?Set GLPI_PASSWORD} GLPI_POLL_INTERVAL: ${GLPI_POLL_INTERVAL:-} GLPI_POLL_LIMIT: ${GLPI_POLL_LIMIT:-} GLPI_TICKET_FILTER: ${GLPI_TICKET_FILTER:-} GLPI_TIMEOUT: ${GLPI_TIMEOUT:-} GLPI_URL: ${GLPI_URL:?Set GLPI_URL} GLPI_USERNAME: ${GLPI_USERNAME:?Set GLPI_USERNAME} GLPI_USER_DEVICE_FILTER_TEMPLATE: ${GLPI_USER_DEVICE_FILTER_TEMPLATE:-} GLPI_USER_DEVICE_LIMIT: ${GLPI_USER_DEVICE_LIMIT:-} GLPI_USER_DEVICE_PATHS: ${GLPI_USER_DEVICE_PATHS:-} HTTP_ADDR: :8080 KNOWLEDGE_ALLOWED_SOURCES: ${KNOWLEDGE_ALLOWED_SOURCES:-} KNOWLEDGE_AUDIT_TOP_K: ${KNOWLEDGE_AUDIT_TOP_K:-} KNOWLEDGE_AUTO_REPLY_SOURCES: ${KNOWLEDGE_AUTO_REPLY_SOURCES:-} KNOWLEDGE_CANDIDATE_MAX_GAP: ${KNOWLEDGE_CANDIDATE_MAX_GAP:-} KNOWLEDGE_CATEGORY_MAP_FILE: ${KNOWLEDGE_CATEGORY_MAP_FILE:-} KNOWLEDGE_CATEGORY_MODE: ${KNOWLEDGE_CATEGORY_MODE:-} KNOWLEDGE_CATEGORY_SOURCES: ${KNOWLEDGE_CATEGORY_SOURCES:-} KNOWLEDGE_CHUNK_OVERLAP_WORDS: ${KNOWLEDGE_CHUNK_OVERLAP_WORDS:-} KNOWLEDGE_CHUNK_WORDS: ${KNOWLEDGE_CHUNK_WORDS:-} KNOWLEDGE_DIR: /app/knowledge KNOWLEDGE_EMBEDDING_PROFILE: ${KNOWLEDGE_EMBEDDING_PROFILE:-} KNOWLEDGE_EMBED_BATCH_SIZE: ${KNOWLEDGE_EMBED_BATCH_SIZE:-} KNOWLEDGE_EVIDENCE_WEIGHT_AI: ${KNOWLEDGE_EVIDENCE_WEIGHT_AI:-} KNOWLEDGE_EVIDENCE_WEIGHT_CATEGORY: ${KNOWLEDGE_EVIDENCE_WEIGHT_CATEGORY:-} KNOWLEDGE_EVIDENCE_WEIGHT_RETRIEVAL: ${KNOWLEDGE_EVIDENCE_WEIGHT_RETRIEVAL:-} KNOWLEDGE_IGNORE_GLOBS: ${KNOWLEDGE_IGNORE_GLOBS:-} KNOWLEDGE_INDEX_MODE: ${KNOWLEDGE_INDEX_MODE:-} KNOWLEDGE_INDEX_SCAN_INTERVAL: ${KNOWLEDGE_INDEX_SCAN_INTERVAL:-} KNOWLEDGE_MAX_CHUNKS_PER_DOC: ${KNOWLEDGE_MAX_CHUNKS_PER_DOC:-} KNOWLEDGE_MAX_QUERY_CHUNKS: ${KNOWLEDGE_MAX_QUERY_CHUNKS:-} KNOWLEDGE_MIN_SCORE: ${KNOWLEDGE_MIN_SCORE:-} KNOWLEDGE_RETRIEVAL_FLOOR: ${KNOWLEDGE_RETRIEVAL_FLOOR:-} KNOWLEDGE_TOP_K: ${KNOWLEDGE_TOP_K:-} KNOWLEDGE_VECTOR_BACKEND: ${KNOWLEDGE_VECTOR_BACKEND:-dual} KNOWLEDGE_WEB_EDIT_ENABLED: ${AGENT_LEGACY_KNOWLEDGE_EDITOR_ENABLED:-false} KNOWLEDGE_WEIGHT_CATEGORY: ${KNOWLEDGE_WEIGHT_CATEGORY:-} KNOWLEDGE_WEIGHT_KEYWORDS: ${KNOWLEDGE_WEIGHT_KEYWORDS:-} KNOWLEDGE_WEIGHT_LEXICAL: ${KNOWLEDGE_WEIGHT_LEXICAL:-} KNOWLEDGE_WEIGHT_SEMANTIC: ${KNOWLEDGE_WEIGHT_SEMANTIC:-} KNOWLEDGE_WEIGHT_TITLE: ${KNOWLEDGE_WEIGHT_TITLE:-} LEARNING_ENABLED: ${LEARNING_ENABLED:-} LEARNING_EXAMPLES_PER_CATEGORY: ${LEARNING_EXAMPLES_PER_CATEGORY:-} LEARNING_MAX_EXAMPLES: ${LEARNING_MAX_EXAMPLES:-} LOG_LEVEL: ${LOG_LEVEL:-} MAJOR_INCIDENTS_ENABLED: ${MAJOR_INCIDENTS_ENABLED:-} NEUROFORGE_API_KEY: ${NEUROFORGE_INTEGRATION_TOKEN:?Set the NeuroForge integration token} NEUROFORGE_FAIL_OPEN: ${NEUROFORGE_FAIL_OPEN:-true} NEUROFORGE_NAMESPACE: ${NEUROFORGE_NAMESPACE:-glpi-agent} NEUROFORGE_SEARCH_K: ${NEUROFORGE_SEARCH_K:-128} NEUROFORGE_TIMEOUT: ${NEUROFORGE_TIMEOUT:-} NEUROFORGE_URL: http://neuroforge:8080 OLLAMA_EMBEDDING_MODEL: ${OLLAMA_EMBEDDING_MODEL:-} OLLAMA_FAILOVER_ATTEMPTS: ${OLLAMA_FAILOVER_ATTEMPTS:-} OLLAMA_FAILOVER_ENABLED: ${OLLAMA_FAILOVER_ENABLED:-} OLLAMA_JSON_RETRIES: ${OLLAMA_JSON_RETRIES:-} OLLAMA_KEEP_ALIVE: ${OLLAMA_KEEP_ALIVE:-} OLLAMA_MAX_CONCURRENT: ${OLLAMA_MAX_CONCURRENT:-} OLLAMA_MODEL: ${OLLAMA_MODEL:-} OLLAMA_NODE_FAILURE_COOLDOWN: ${OLLAMA_NODE_FAILURE_COOLDOWN:-} OLLAMA_NODE_HEALTH_INTERVAL: ${OLLAMA_NODE_HEALTH_INTERVAL:-} OLLAMA_NODE_MAX_INFLIGHT: ${OLLAMA_NODE_MAX_INFLIGHT:-} OLLAMA_NODE_NAMES: ${OLLAMA_NODE_NAMES:-} OLLAMA_NODE_REQUEST_TIMEOUT: ${OLLAMA_NODE_REQUEST_TIMEOUT:-} OLLAMA_NODE_WEIGHTS: ${OLLAMA_NODE_WEIGHTS:-} OLLAMA_NUM_PREDICT: ${OLLAMA_NUM_PREDICT:-} OLLAMA_REQUIRE_EMBEDDING_MODEL: ${OLLAMA_REQUIRE_EMBEDDING_MODEL:-} OLLAMA_REQUIRE_SAME_MODEL_DIGEST: ${OLLAMA_REQUIRE_SAME_MODEL_DIGEST:-} OLLAMA_ROUTING_MODE: ${OLLAMA_ROUTING_MODE:-} OLLAMA_THINK: ${OLLAMA_THINK:-} OLLAMA_TIMEOUT: ${OLLAMA_TIMEOUT:-} OLLAMA_URL: ${OLLAMA_BASE_URL:?Set Ollama URL reachable from master} OLLAMA_URLS: ${OLLAMA_URLS:?Set one or more Ollama URLs reachable from master} OUTCOME_LEARNING_ENABLED: ${OUTCOME_LEARNING_ENABLED:-true} OUTCOME_LEARNING_FAIL_OPEN: ${OUTCOME_LEARNING_FAIL_OPEN:-false} OUTCOME_LEARNING_MAX_OUTCOMES: ${OUTCOME_LEARNING_MAX_OUTCOMES:-2000} OUTCOME_RETRIEVAL_ENABLED: ${OUTCOME_RETRIEVAL_ENABLED:-true} OUTCOME_RETRIEVAL_FAIL_OPEN: ${OUTCOME_RETRIEVAL_FAIL_OPEN:-true} OUTCOME_RETRIEVAL_MIN_SIMILARITY: ${OUTCOME_RETRIEVAL_MIN_SIMILARITY:-0.58} OUTCOME_RETRIEVAL_SEARCH_K: ${OUTCOME_RETRIEVAL_SEARCH_K:-6} PRIORITY_ALLOWED_REASON_CODES: ${PRIORITY_ALLOWED_REASON_CODES:-} PRIORITY_ANALYSIS_TIMEOUT: ${PRIORITY_ANALYSIS_TIMEOUT:-} PRIORITY_CONFIDENCE: ${PRIORITY_CONFIDENCE:-} PRIORITY_ENABLED: ${PRIORITY_ENABLED:-} PRIORITY_MAX_INCREASE: ${PRIORITY_MAX_INCREASE:-} QUEUE_SIZE: ${QUEUE_SIZE:-} RAG_ENABLED: ${RAG_ENABLED:-} REPLY_CONFIDENCE: ${REPLY_CONFIDENCE:-} UPTIME_KUMA_API_KEY: ${UPTIME_KUMA_API_KEY:-} UPTIME_KUMA_ENABLED: ${UPTIME_KUMA_ENABLED:-} UPTIME_KUMA_INCLUDE_MAINTENANCE: ${UPTIME_KUMA_INCLUDE_MAINTENANCE:-} UPTIME_KUMA_MAX_ISSUES: ${UPTIME_KUMA_MAX_ISSUES:-} UPTIME_KUMA_MODE: ${UPTIME_KUMA_MODE:-} UPTIME_KUMA_STATUS_PAGES: ${UPTIME_KUMA_STATUS_PAGES:-} UPTIME_KUMA_TIMEOUT: ${UPTIME_KUMA_TIMEOUT:-} UPTIME_KUMA_URL: ${UPTIME_KUMA_URL:-} USER_DEVICE_CONTEXT_ENABLED: ${USER_DEVICE_CONTEXT_ENABLED:-} WEBHOOK_SECRET: ${WEBHOOK_SECRET:-} WEB_ALLOW_ANONYMOUS: ${WEB_ALLOW_ANONYMOUS:-} WEB_PASSWORD: ${WEB_PASSWORD:-} WEB_USERNAME: ${WEB_USERNAME:-} WORKERS: ${WORKERS:-} ports: - 127.0.0.1:${AGENT_HOST_PORT:-8080}:8080 volumes: - agent-data:/app/data - ${KB_DATA_PATH:-./knowledge}:/app/knowledge:ro depends_on: agent-data-init: condition: service_completed_successfully read_only: true tmpfs: - /tmp:size=64m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL healthcheck: test: - CMD - /app/glpi-ai-agent - healthcheck interval: 15s timeout: 3s retries: 8 start_period: 10s stop_grace_period: 20s knowledge: image: git.send.nrw/sendnrw/glpi-neuroforge-mega-knowledge:${IMAGE_TAG:?Set IMAGE_TAG to an immutable release tag, for example 1.6.2} restart: unless-stopped environment: APP_MODE: ${KB_APP_MODE:-editor} DATA_DIR: /data/knowledge BACKUP_DIR: /data/backups STAGING_DIR: /data/staging LISTEN_ADDR: :8080 APP_TITLE: ${APP_TITLE:-} APP_SUBTITLE: ${APP_SUBTITLE:-} AUTO_RELOAD_INTERVAL: ${AUTO_RELOAD_INTERVAL:-} BASIC_AUTH_USER: ${BASIC_AUTH_USER:?Set the Knowledge web user} BASIC_AUTH_PASSWORD: ${BASIC_AUTH_PASSWORD:?Set the Knowledge web password} AI_FALLBACK_ENABLED: ${AI_FALLBACK_ENABLED:-false} OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:?Set Ollama URL reachable from master} OLLAMA_MODEL: ${OLLAMA_MODEL:-gemma3} OLLAMA_TIMEOUT: ${OLLAMA_TIMEOUT:-10m} OLLAMA_MAX_CONCURRENT: ${OLLAMA_MAX_CONCURRENT:-2} OLLAMA_STAGING_AUTO_REPLY: ${OLLAMA_STAGING_AUTO_REPLY:-false} OLLAMA_STAGING_MIN_SCORE: ${OLLAMA_STAGING_MIN_SCORE:-0.72} BRAIN_ACTIVITY_URL: http://neuroforge:8080/api/v1/integrations/events BRAIN_ACTIVITY_API_KEY: ${NEUROFORGE_INTEGRATION_TOKEN:?Set the NeuroForge integration token} KB_INTEGRATION_TOKEN: ${KB_INTEGRATION_TOKEN:?Set the Knowledge integration token} ports: - 127.0.0.1:${KNOWLEDGE_HOST_PORT:-8081}:8080 volumes: - ${KB_DATA_PATH:-./knowledge}:/data/knowledge:${KB_DATA_MOUNT_MODE:-rw} - ${KB_STAGING_PATH:-./staging}:/data/staging:rw - ${KB_BACKUP_PATH:-./backups}:/data/backups:rw read_only: true tmpfs: - /tmp:size=32m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL stop_grace_period: 35s control: image: git.send.nrw/sendnrw/glpi-neuroforge-mega-control:${IMAGE_TAG:?Set IMAGE_TAG to an immutable release tag, for example 1.6.2} restart: unless-stopped environment: CONTROL_ADDR: :8070 CONTROL_BASIC_AUTH_USER: ${CONTROL_BASIC_AUTH_USER:?Set the Control Center user} CONTROL_BASIC_AUTH_PASSWORD: ${CONTROL_BASIC_AUTH_PASSWORD:?Set the Control Center password} AGENT_URL: http://agent:8080 KNOWLEDGE_URL: http://knowledge:8080 NEUROFORGE_URL: http://neuroforge:8080 NEUROFORGE_API_KEY: ${NEUROFORGE_CONTROL_READ_TOKEN:?Set the NeuroForge control read token} CONTROL_READ_TOKEN: ${CONTROL_READ_TOKEN:?Set the Agent control read token} CODEBASE_MEMORY_URL: ${CODEBASE_MEMORY_URL:-} PUBLIC_CODEBASE_MEMORY_URL: ${PUBLIC_CODEBASE_MEMORY_URL:-} KNOWLEDGE_VECTOR_BACKEND: ${KNOWLEDGE_VECTOR_BACKEND:-dual} NEUROFORGE_SEARCH_K: ${NEUROFORGE_SEARCH_K:-128} NEUROFORGE_FAIL_OPEN: ${NEUROFORGE_FAIL_OPEN:-true} NEUROFORGE_CONTROLLED_LEARNING: ${NEUROFORGE_CONTROLLED_LEARNING:-true} NEUROFORGE_GOAL_LEARNING_ENABLED: ${NEUROFORGE_GOAL_LEARNING_ENABLED:-false} OUTCOME_LEARNING_ENABLED: ${OUTCOME_LEARNING_ENABLED:-true} OUTCOME_RETRIEVAL_ENABLED: ${OUTCOME_RETRIEVAL_ENABLED:-true} OUTCOME_RETRIEVAL_SEARCH_K: ${OUTCOME_RETRIEVAL_SEARCH_K:-6} OUTCOME_RETRIEVAL_MIN_SIMILARITY: ${OUTCOME_RETRIEVAL_MIN_SIMILARITY:-0.58} OUTCOME_RETRIEVAL_FAIL_OPEN: ${OUTCOME_RETRIEVAL_FAIL_OPEN:-true} NEUROFORGE_RESEARCH_ENABLED: ${NEUROFORGE_RESEARCH_ENABLED:-false} NEUROFORGE_SEARXNG_ENABLED: ${NEUROFORGE_SEARXNG_ENABLED:-false} NEUROFORGE_KB_STAGING_ENABLED: ${NEUROFORGE_KB_STAGING_ENABLED:-true} NEUROFORGE_AUTONOMY_ENABLED: ${NEUROFORGE_AUTONOMY_ENABLED:-false} PUBLIC_AGENT_URL: http://localhost:${AGENT_HOST_PORT:-8080} PUBLIC_KNOWLEDGE_URL: http://localhost:${KNOWLEDGE_HOST_PORT:-8081} PUBLIC_NEUROFORGE_URL: http://localhost:${NEUROFORGE_HOST_PORT:-8090}/admin ports: - 127.0.0.1:${CONTROL_HOST_PORT:-8070}:8070 read_only: true tmpfs: - /tmp:size=16m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL extra_hosts: - host.docker.internal:host-gateway stop_grace_period: 25s prometheus-secrets-init: profiles: - monitoring image: alpine:3.22.1 restart: 'no' environment: NEUROFORGE_METRICS_TOKEN: ${NEUROFORGE_METRICS_TOKEN:?Set NeuroForge metrics token} command: - /bin/sh - -ec - printf "%s" "$${NEUROFORGE_METRICS_TOKEN}" > /secrets/neuroforge_metrics.token; chown 65534:65534 /secrets/neuroforge_metrics.token; chmod 0400 /secrets/neuroforge_metrics.token volumes: - prometheus-secrets:/secrets read_only: true tmpfs: - /tmp:size=8m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL prometheus-config-init: profiles: - monitoring image: alpine:3.22.1 restart: 'no' environment: CPU_TARGET: ${CPU_SUBAGENT_NODE_EXPORTER_TARGET:-cpu-subagent.example.invalid:9100} GPU_TARGET: ${GPU_SUBAGENT_NODE_EXPORTER_TARGET:-gpu-subagent.example.invalid:9100} GPU_DCGM_TARGET: ${GPU_SUBAGENT_DCGM_EXPORTER_TARGET:-gpu-subagent.example.invalid:9400} command: - /bin/sh - -ec - sed -e "s|__CPU_TARGET__|$${CPU_TARGET}|g" -e "s|__GPU_TARGET__|$${GPU_TARGET}|g" -e "s|__GPU_DCGM_TARGET__|$${GPU_DCGM_TARGET}|g" /template/prometheus.yml.template > /rendered/prometheus.yml volumes: - ./monitoring/prometheus:/template:ro - prometheus-config:/rendered read_only: true tmpfs: - /tmp:size=8m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL node-exporter: profiles: - monitoring image: ${NODE_EXPORTER_IMAGE:-prom/node-exporter:v1.12.1} restart: unless-stopped command: - --path.procfs=/host/proc - --path.sysfs=/host/sys - --path.rootfs=/rootfs - --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/) volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro - /:/rootfs:ro,rslave read_only: true security_opt: - no-new-privileges:true cap_drop: - ALL prometheus: profiles: - monitoring image: ${PROMETHEUS_IMAGE:-prom/prometheus:v3.14.0} restart: unless-stopped command: - --config.file=/etc/prometheus/prometheus.yml - --storage.tsdb.path=/prometheus - --storage.tsdb.retention.time=${PROMETHEUS_RETENTION:-30d} - --web.enable-lifecycle ports: - 127.0.0.1:${PROMETHEUS_HOST_PORT:-9090}:9090 volumes: - prometheus-config:/etc/prometheus:ro - ./monitoring/prometheus/alerts.yml:/etc/prometheus-alerts/alerts.yml:ro - prometheus-data:/prometheus - prometheus-secrets:/etc/prometheus-secrets:ro depends_on: neuroforge: condition: service_started prometheus-secrets-init: condition: service_completed_successfully prometheus-config-init: condition: service_completed_successfully read_only: true tmpfs: - /tmp:size=32m,mode=1777 security_opt: - no-new-privileges:true cap_drop: - ALL grafana: profiles: - monitoring image: ${GRAFANA_IMAGE:-grafana/grafana:13.2.0} restart: unless-stopped environment: GF_SECURITY_ADMIN_USER: ${GRAFANA_ADMIN_USER:-admin} GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:?Set Grafana admin password} GF_USERS_ALLOW_SIGN_UP: 'false' GF_AUTH_ANONYMOUS_ENABLED: 'false' GF_SERVER_ROOT_URL: ${GRAFANA_ROOT_URL:-http://localhost:3000} ports: - 127.0.0.1:${GRAFANA_HOST_PORT:-3000}:3000 volumes: - grafana-data:/var/lib/grafana - ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro - ./monitoring/grafana/dashboards:/var/lib/grafana/dashboards:ro depends_on: prometheus: condition: service_started security_opt: - no-new-privileges:true cap_drop: - ALL volumes: neuroforge-data: null agent-data: null searxng-cache: null prometheus-data: null prometheus-secrets: null prometheus-config: null grafana-data: null