# Flexible GraphRAG Configuration

# =============================================================================
# Document Parser Configuration (Docling / LlamaParse)
# =============================================================================

# Document Parser Configuration
# DOCUMENT_PARSER can be "docling" (default, open-source) or "llamaparse" (cloud-based, requires API key)
# Docling: Free, open-source, runs locally, good for most document types
# LlamaParse: Cloud-based parsing service from LlamaIndex, advanced multimodal parsing, requires API key
DOCUMENT_PARSER=docling
#DOCUMENT_PARSER=llamaparse

# Save parsing results to files for inspection (works for both Docling and LlamaParse)
# When enabled, saves parsing outputs to ./parsing_output/
# - Docling: Saves both markdown (.md) and plaintext (.txt) outputs + metadata JSON
# - LlamaParse: Saves both markdown (.md) and plaintext (.txt) outputs + metadata JSON
# Useful for debugging and understanding how parsers interpret documents
#SAVE_PARSING_OUTPUT=false
#SAVE_PARSING_OUTPUT=true

# Format to use for knowledge graph extraction (what gets sent to LLM for entity/relation extraction)
# Applies to both Docling and LlamaParse
# Options:
#   "auto" (default) - Use markdown if tables detected, otherwise use plaintext
#   "markdown" - Always use markdown format (better for documents with tables/structure)
#   "plaintext" - Always use plaintext format (better for text-heavy documents)
# Note: Both formats are always saved to disk when SAVE_PARSING_OUTPUT=true
#PARSER_FORMAT_FOR_EXTRACTION=auto
#PARSER_FORMAT_FOR_EXTRACTION=markdown
#PARSER_FORMAT_FOR_EXTRACTION=plaintext

# =============================================================================
# Docling Config

# Docling Device Configuration (only used if DOCUMENT_PARSER=docling)
# Options:
#   "auto" (default) - Automatically uses GPU if available, falls back to CPU
#   "cpu" - Force CPU-only processing
#   "cuda" - Force CUDA/GPU processing (requires CUDA-capable GPU and PyTorch with CUDA)
#   "mps" - Force Apple Metal Performance Shaders (Mac with Apple Silicon)
# Note: GPU processing significantly speeds up PDF/document conversion with tables
#DOCLING_DEVICE=auto
#DOCLING_DEVICE=cpu
#DOCLING_DEVICE=cuda

# =============================================================================
# LlamaParse Config

# LlamaParse API Key (only needed if DOCUMENT_PARSER=llamaparse)
# Get your API key from https://cloud.llamaindex.ai/  bottom left "API Keys", then "Generate New Key"
# LlamaParse offers high-quality document parsing of complex documents
#LLAMAPARSE_API_KEY=llx-your-api-key-here

# LlamaParse Mode Configuration (only used if DOCUMENT_PARSER=llamaparse)
# Options:
#   "parse_page_without_llm" - 1 credit/page (cheapest, simple, text-only output, no markdown)
#   "parse_page_with_llm" - 3 credits/page (good balance, uses LLM, markdown output) - DEFAULT
#   "parse_page_with_agent" - 10-90 credits/page (best quality, markdown output, requires LLAMAPARSE_AGENT_MODEL)
#LLAMAPARSE_MODE=parse_page_with_llm

# LlamaParse Agent Model (only used if LLAMAPARSE_MODE=parse_page_with_agent)
# Available models from LlamaCloud (costs vary by model):
#   "openai-gpt-4-1-mini" - 10 credits/page (recommended balance)
#   Other models available - check LlamaCloud for full list / credit cost
#LLAMAPARSE_AGENT_MODEL=openai-gpt-4-1-mini


# =============================================================================
# Data Source Configuration
# =============================================================================

# Example configurations for different data sources:
# WEB_CONFIG={"url": "https://example.com/page"}
# WIKIPEDIA_CONFIG={"query": "artificial intelligence", "language": "en", "max_docs": 1}
# YOUTUBE_CONFIG={"url": "https://www.youtube.com/watch?v=VIDEO_ID", "chunk_size_seconds": 60}

# Amazon S3 Configuration
# S3_CONFIG={"bucket_name": "my-bucket", "access_key": "AKIAIOSFODNN7EXAMPLE", "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "region_name": "us-east-1", "prefix": "documents/"}
# Alternative format using "bucket" (S3Reader compatible):
# S3_CONFIG={"bucket": "my-bucket", "access_key": "AKIAIOSFODNN7EXAMPLE", "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "region_name": "us-east-1", "prefix": "documents/"}
# Required: bucket_name (or bucket), access_key, secret_key
# Optional: region_name (if not specified, falls back to S3_REGION_NAME env var or default "us-east-1"), prefix (folder path within bucket)
# Note: S3_CONFIG takes precedence over individual S3_* environment variables (see section 5 below)

# Google Cloud Storage Configuration
# GCS_CONFIG={"bucket_name": "my-bucket", "project_id": "my-project-123", "credentials": "{\"type\":\"service_account\",\"project_id\":\"my-project\",...}", "prefix": "documents/"}
# Required: bucket_name, project_id, credentials (service account JSON as string)
# Optional: prefix (folder path), folder_name, service_account_key_path (alternative to credentials string)
# Note: credentials should be JSON service account key from GCP Console as a string

# Google Drive Configuration
# GOOGLE_DRIVE_CONFIG={"credentials": "{\"type\":\"service_account\",\"project_id\":\"my-project\",...}", "folder_id": "1A2B3C4D5E6F7G8H9I0J", "file_ids": ["file1-id", "file2-id"], "query": "name contains 'report'"}
# Required: Either credentials (service account JSON string) OR credentials_path OR token_path
# Optional: folder_id, file_ids (specific files), query (search query), credentials_path, token_path
# Note: credentials should be service account JSON key or OAuth credentials file path

# Azure Blob Storage Configuration
# AZURE_BLOB_CONFIG={"container_name": "documents", "account_url": "https://myaccount.blob.core.windows.net", "account_name": "myaccount", "account_key": "base64key==", "prefix": "folder/"}
# Required: container_name, account_url, account_name, account_key
# Optional: blob (specific blob name), prefix (folder path), connection_string (alternative to account_key)

# Microsoft OneDrive Configuration
# ONEDRIVE_CONFIG={"user_principal_name": "admin@tenant.onmicrosoft.com", "client_id": "12345678-1234-1234-1234-123456789abc", "client_secret": "XFA8Q~abc123...", "tenant_id": "87654321-4321-4321-4321-cba987654321", "folder_path": "/Documents"}
# Required: user_principal_name (M365 email), client_id, client_secret, tenant_id
# Optional: folder_path (default: / for root), folder_id, file_ids
# Setup instructions: docs/DATA-SOURCE-CONFIGURATION.md

# Microsoft SharePoint Configuration
# SHAREPOINT_CONFIG={"client_id": "12345678-1234-1234-1234-123456789abc", "client_secret": "XFA8Q~abc123...", "tenant_id": "87654321-4321-4321-4321-cba987654321", "site_name": "MySite", "folder_path": "/Shared Documents"}
# Required: client_id, client_secret, tenant_id, site_name (SharePoint site name, not full URL)
# Optional: site_id, folder_path (default: /), folder_id, file_ids
# Setup instructions: docs/DATA-SOURCE-CONFIGURATION.md

# Box Configuration
# Developer Token (simplest, expires in 60 minutes):
# BOX_CONFIG={"folder_id": "0", "developer_token": "your_developer_token"}
# Client Credentials Grant (production, long-lived):
# BOX_CONFIG={"folder_id": "0", "client_id": "abc123", "client_secret": "xyz789", "user_id": "12345678"}
# For detailed setup instructions, see docs/DATA-SOURCE-CONFIGURATION.md

# Sample Text for Testing (optional - overrides default Dune text)
# SAMPLE_TEXT="Luke Skywalker is a Jedi Knight from Tatooine. His father is Darth Vader, formerly known as Anakin Skywalker."

# ====================================================================
# 1. GRAPH DATABASE CONFIGURATION
# ====================================================================

GRAPH_DB=neo4j
#GRAPH_DB=kuzu
#GRAPH_DB=falkordb
#GRAPH_DB=arcadedb
#GRAPH_DB=memgraph
#GRAPH_DB=nebula
#GRAPH_DB=neptune
#GRAPH_DB=neptune_analytics
#GRAPH_DB=none

# Enable knowledge graph extraction 
#ENABLE_KNOWLEDGE_GRAPH=false
ENABLE_KNOWLEDGE_GRAPH=true

# Knowledge graph extractor type: "simple", "schema", or "dynamic"
# simple: Basic extraction without schema constraints (uses SimpleLLMPathExtractor) 
# schema: Uses provided or buitlin schema for structured extraction (uses SchemaLLMPathExtractor) - default
# Use SchemaLLMPathExtractor with strict=True when you have a well-defined domain and want to ensure consistency
# Use SchemaLLMPathExtractor with strict=False when you want some flexibility while still being guided by a schema
# (for bedrock, fireworks, groq DynamicLLMPathExtractor is used instead of SchemaLLMPathExtractor to avoid a LlamaIndex issue)
# dynamic: More flexible extraction that can expand more beyond initial schema or no provided schema (uses DynamicLLMPathExtractor)
KG_EXTRACTOR_TYPE=schema
#KG_EXTRACTOR_TYPE=dynamic
#KG_EXTRACTOR_TYPE=simple

# Graph Database Connection Configurations:

# Neo4j
GRAPH_DB_CONFIG={"url": "bolt://localhost:7687", "username": "neo4j", "password": "password"}

# Kuzu (database file will be created as ./kuzu_db/database.kz)
# use_structured_schema: false (default) - enables initial entity types and schema (not generic entity type schema)
# use_vector_index: false (default) - enables Kuzu's built-in vector capabilities use internally
#GRAPH_DB_CONFIG={"db_path": "./kuzu_db/database.kz", "use_structured_schema": false, "use_vector_index": false}

# FalkorDB
#GRAPH_DB_CONFIG={"url": "falkor://localhost:6379"}
#GRAPH_DB_CONFIG={"url": "falkor://localhost:6379", "database": "falkor"}

# ArcadeDB (multi-model database with graph capabilities)
# include_basic_schema: True (default) - initial types: PERSON, ORGANIZATION, LOCATION, PLACE + Entity, TextChunk, MENTIONS
#                       False - initial types: Entity, TextChunk, MENTIONS only
#                       For both settings: LlamaIndex PathExtractors/KG_EXTRACTOR_TYPE control additional types
# Remote mode (default) — requires a running ArcadeDB server
#GRAPH_DB_CONFIG={"host": "localhost", "port": 2480, "username": "root", "password": "playwithdata", "database": "flexible_graphrag", "include_basic_schema": true}
#GRAPH_DB_CONFIG={"host": "localhost", "port": 2480, "username": "root", "password": "playwithdata", "database": "flexible_graphrag", "include_basic_schema": false}
# Embedded mode — no separate server required; install arcadedb-embedded>=26.2.1 first
# embedded_server: false (default) - pure in-process, no HTTP endpoint exposed
# embedded_server: true - also starts an HTTP server on embedded_server_port (default 2482)
#GRAPH_DB_CONFIG={"mode": "embedded", "db_path": "./arcadedb_data", "database": "flexible_graphrag", "include_basic_schema": true}
#GRAPH_DB_CONFIG={"mode": "embedded", "db_path": "./arcadedb_data", "database": "flexible_graphrag", "embedded_server": true, "embedded_server_port": 2482, "embedded_server_password": "playwithdata", "include_basic_schema": true}

# MemGraph (real-time graph database)
# Basic configuration:
#GRAPH_DB_CONFIG={"url": "bolt://localhost:7688", "username": "", "password": ""}
# Full configuration with database parameter:
#GRAPH_DB_CONFIG={"url": "bolt://localhost:7688", "username": "", "password": "", "database": "memgraph"}

# NebulaGraph (distributed graph database)
# Basic configuration (uses defaults for connection):
#GRAPH_DB_CONFIG={"space": "flexible_graphrag", "overwrite": true}
# Full configuration with connection parameters (address/port format):
#GRAPH_DB_CONFIG={"space": "flexible_graphrag", "overwrite": true, "address": "localhost", "port": 9669, "username": "root", "password": "nebula"}
# Full configuration with URL format:
#GRAPH_DB_CONFIG={"space": "flexible_graphrag", "overwrite": true, "url": "nebula://localhost:9669", "username": "root", "password": "nebula"}
# Alternative format (space_name also supported for backward compatibility):
#GRAPH_DB_CONFIG={"space_name": "flexible_graphrag", "address": "localhost", "port": 9669, "username": "root", "password": "nebula"}

# Amazon Neptune (managed graph database service)
# With explicit AWS credentials:
#GRAPH_DB_CONFIG={"host": "your-neptune-cluster.cluster-xyz.us-east-1.neptune.amazonaws.com", "port": 8182, "region": "us-east-1", "access_key": "your_access_key", "secret_key": "your_secret_key"}
# With AWS credentials profile (alternative approach):
#GRAPH_DB_CONFIG={"host": "your-neptune-cluster.cluster-xyz.us-east-1.neptune.amazonaws.com", "port": 8182, "region": "us-east-1", "credentials_profile_name": "my-aws-profile"}

# Amazon Neptune Analytics (serverless graph analytics engine)
# NOTE: Neptune Analytics has non-atomic vector index limitations
# The system automatically sets embed_kg_nodes=False for Neptune Analytics to avoid vector conflicts
# Use a separate VECTOR_DB for embeddings when using Neptune Analytics
# With explicit AWS credentials:
#GRAPH_DB_CONFIG={"graph_identifier": "g-1234567890", "region": "us-east-1", "access_key": "your_access_key", "secret_key": "your_secret_key"}
# With AWS credentials profile (alternative approach):
#GRAPH_DB_CONFIG={"graph_identifier": "g-1234567890", "region": "us-east-1", "credentials_profile_name": "my-aws-profile"}
# Using default AWS credentials (from environment variables, IAM role, etc.):
#GRAPH_DB_CONFIG={"graph_identifier": "g-1234567890", "region": "us-east-1"}
# Note: Neptune Analytics requires a region to be specified
# Recommended: Use Neptune Analytics for graph + separate VECTOR_DB for embeddings


# ====================================================================
# SCHEMA CONFIGURATION - Controls entity and relationship extraction
# ====================================================================

# default uses schema builtin into LlamaIndex (no schema passed to SchemaLLMPathExtractor or DynamicLLMPathExtractor)
SCHEMA_NAME=default

# Schema set to sample uses SAMPLE_SCHEMA in config.py
# "entities": ["PERSON", "ORGANIZATION", "LOCATION", "PLACE", "TECHNOLOGY", "PROJECT"],
# "relations": ["WORKS_FOR", "LOCATED_IN", "USES", "COLLABORATES_WITH", "DEVELOPS", "HAS", "PART_OF", "WORKED_ON", "WORKED_WITH", "WORKED_AT"],
# "validation_schema": [ bunch of type relation-type type triplets ]
#SCHEMA_NAME=sample

# Custom schema example for SchemaLLMPathExtractor (and DynamicLLMPathExtractor)
#SCHEMA_NAME=cmis_press
#SCHEMAS=[{"name": "cmis_press", "schema": {"entities": ["PERSON", "ORGANIZATION", "TECHNOLOGY", "SPECIFICATION", "CONCEPT"], "relations": ["WORKS_FOR", "DEVELOPS", "SUPPORTS", "IMPLEMENTS", "COLLABORATES_WITH", "ANNOUNCES"], "validation_schema": [["PERSON", "WORKS_FOR", "ORGANIZATION"], ["PERSON", "DEVELOPS", "TECHNOLOGY"], ["ORGANIZATION", "SUPPORTS", "SPECIFICATION"], ["ORGANIZATION", "IMPLEMENTS", "TECHNOLOGY"], ["ORGANIZATION", "COLLABORATES_WITH", "ORGANIZATION"], ["ORGANIZATION", "ANNOUNCES", "SPECIFICATION"]], "strict": false}}]

STRICT_SCHEMA_VALIDATION=false  # true = only extract types in schema; false = schema guides but LLM can go beyond it (default)

# Disable entity and relation property extraction
# Default: false - properties enabled for all providers (OpenAI uses function calling to avoid the
# "additionalProperties: false" structured output constraint)
# Set to true only if a specific LLM provider or model produces errors during property extraction
#DISABLE_PROPERTIES=false


# ====================================================================
# 2. VECTOR DATABASE CONFIGURATION  
# ====================================================================

#VECTOR_DB=neo4j
VECTOR_DB=qdrant
#VECTOR_DB=elasticsearch
#VECTOR_DB=opensearch
#VECTOR_DB=chroma
#VECTOR_DB=milvus
#VECTOR_DB=weaviate
#VECTOR_DB=pinecone
#VECTOR_DB=postgres
#VECTOR_DB=lancedb
#VECTOR_DB=none

# Vector Database Connection Configurations:

# Qdrant
VECTOR_DB_CONFIG={"host": "localhost", "port": 6333, "collection_name": "hybrid_search_vector", "https": false}

# Elasticsearch
#VECTOR_DB_CONFIG={"url": "http://localhost:9200", "index_name": "hybrid_search_vector"}

# OpenSearch Configuration (Vector Store) - Dense vector search
#VECTOR_DB_CONFIG={"url": "http://localhost:9201", "index_name": "hybrid_search_vector"}

# Neo4j VECTOR database configuration (separate from graph)
#VECTOR_DB_CONFIG={"url": "bolt://localhost:7687", "username": "neo4j", "password": "password", "index_name": "hybrid_search_vector", "database": "neo4j"}

# Chroma (local vector database with persistence)
# Local mode (file-based storage):
#VECTOR_DB_CONFIG={"persist_directory": "./chroma_db", "collection_name": "hybrid_search"}
# HTTP mode (connect to remote ChromaDB server):
#VECTOR_DB_CONFIG={"host": "localhost", "port": 8001, "collection_name": "hybrid_search"}

# Milvus (scalable vector database)
#VECTOR_DB_CONFIG={"host": "localhost", "port": 19530, "collection_name": "hybrid_search", "username": "root", "password": "milvus"}

# Weaviate (vector search engine with semantic capabilities)
# For local Docker instance (no authentication):
#VECTOR_DB_CONFIG={"url": "http://localhost:8081", "index_name": "HybridSearch"}
# For authenticated instance (with API key):
#VECTOR_DB_CONFIG={"url": "http://localhost:8081", "index_name": "HybridSearch", "api_key": "your_weaviate_api_key"}

# Pinecone (managed serverless vector database service)
# Sign up at https://app.pinecone.io (free starter plan available)
# Note: dimension is auto-detected from your embedding model, don't include it in config
#VECTOR_DB_CONFIG={"api_key": "your_pinecone_api_key", "region": "us-east-1", "cloud": "aws", "index_name": "hybrid-search", "metric": "cosine"}

# PostgreSQL with pgvector extension
#VECTOR_DB_CONFIG={"host": "localhost", "port": 5433, "database": "postgres", "username": "postgres", "password": "password", "table_name": "hybrid_search_vectors"}

# LanceDB (modern embedded vector database)
#VECTOR_DB_CONFIG={"uri": "./lancedb", "table_name": "hybrid_search", "vector_column_name": "vector", "text_column_name": "text"}


# ====================================================================
# 3. SEARCH DATABASE CONFIGURATION
# ====================================================================

#SEARCH_DB=bm25
SEARCH_DB=elasticsearch
#SEARCH_DB=opensearch
#SEARCH_DB=none

# Search Database Connection Configurations:
# Elasticsearch
SEARCH_DB_CONFIG={"url": "http://localhost:9200", "index_name": "hybrid_search_fulltext"}

# OpenSearch Configuration (Search Store) - BM25 fulltext search
#SEARCH_DB_CONFIG={"url": "http://localhost:9201", "index_name": "hybrid_search_fulltext"}

# ====================================================================
# 4. LLM CONFIGURATION
# ====================================================================
# For detailed configuration examples and all options, see: docs/LLM-EMBEDDING-CONFIG.md

# LLM Provider Selection
LLM_PROVIDER=openai
#LLM_PROVIDER=ollama
#LLM_PROVIDER=azure_openai
#LLM_PROVIDER=gemini
#LLM_PROVIDER=anthropic
#LLM_PROVIDER=vertex_ai
#LLM_PROVIDER=bedrock
#LLM_PROVIDER=groq
#LLM_PROVIDER=fireworks
#LLM_PROVIDER=openai_like    # Any OpenAI-compatible API (also used to use vLLM docker)
#LLM_PROVIDER=vllm           # vLLM Python package (Linux/macOS only — see vLLM section below)
#LLM_PROVIDER=litellm        # LiteLLM proxy (100+ providers)
#LLM_PROVIDER=openrouter     # OpenRouter (200+ models via unified API)

# OpenAI Configuration (if using OpenAI)
OPENAI_API_KEY=your-openai-api-key-here
OPENAI_MODEL=gpt-4.1-mini
#OPENAI_MODEL=gpt-5-mini        #  LlamaIndex classifies gpt-5 family as reasoning (O1) models
                                 #   → temperature is forced to 1.0 regardless of OPENAI_TEMPERATURE
                                 #   → non-deterministic extraction, use gpt-4.1-mini instead
#OPENAI_MODEL=gpt-4o
#OPENAI_MODEL=gpt-4o-mini
# gpt-4.1-mini:  $0.40/$1.60 per 1M tokens, 1M ctx   — best value; respects temperature=0.0
# gpt-5-mini:    $0.25/$2.00 per 1M tokens, 400K ctx  — reasoning model; temp forced to 1.0 by LlamaIndex
# gpt-4o:        $2.50/$10.00 per 1M tokens, 128K ctx — high quality, more expensive
# gpt-4o-mini:   $0.15/$0.60 per 1M tokens, 128K ctx  — fastest/cheapest, lower extraction quality
OPENAI_TEMPERATURE=0.0  # 0.0 = deterministic extraction (recommended)
# OPENAI_TIMEOUT=120.0  # LLM request timeout in seconds (default: 2 minutes)

# Ollama Configuration (if using Ollama - local LLM)
# See docs/OLLAMA-CONFIGURATION.md for detailed setup and optimization
# See docs/LLM/LLM-TESTING-RESULTS.md for full Ollama benchmark results
#OLLAMA_MODEL=gpt-oss:20b             # 20B params - RECOMMENDED for graph extraction
#OLLAMA_MODEL=llama3.1:8b             # 8B params  - NOT RECOMMENDED: very slow, hangs on 2nd doc
#OLLAMA_MODEL=llama3.2:3b             # 3B params  - NOT RECOMMENDED: stalls at 8192 context, low entity count
#OLLAMA_BASE_URL=http://localhost:11434
#OLLAMA_TIMEOUT=900.0  # 15 minutes timeout for graph extraction (default: 900.0)

# Azure OpenAI Configuration (if using Azure OpenAI)
# See docs/LLM-EMBEDDING-CONFIG.md for detailed examples
# AZURE_OPENAI_API_KEY=your-azure-openai-key
# AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
# AZURE_OPENAI_ENGINE=gpt-4o-mini  # Your deployment name
# AZURE_OPENAI_MODEL=gpt-4o-mini
# AZURE_OPENAI_API_VERSION=2024-12-01-preview

# Google Gemini Configuration (if using Gemini)
# See docs/LLM-EMBEDDING-CONFIG.md for detailed examples
# GOOGLE_API_KEY=your-google-api-key
# GEMINI_MODEL=gemini-3-flash-preview    # fast model - recommended default
# GEMINI_MODEL=gemini-3.1-pro-preview    # pro quality - use instead of deprecated gemini-3-pro-preview
# GEMINI_MODEL=gemini-2.5-flash          # alternative
# Note: text-embedding-004 was deprecated 2026-01-14 — use gemini-embedding-2-preview (768 dims)

# Anthropic Claude Configuration (if using Claude)
# See docs/LLM-EMBEDDING-CONFIG.md for detailed examples
# ANTHROPIC_API_KEY=your-anthropic-api-key
# ANTHROPIC_MODEL=claude-sonnet-4-5-20250929
# Note: Claude only creates chunk nodes during graph building (no entity/relationship extraction)

# Google Vertex AI Configuration (if using Vertex AI)
# See docs/LLM-EMBEDDING-CONFIG.md for detailed examples and package options
# VERTEX_AI_PROJECT=your-gcp-project-id  # Required
# VERTEX_AI_LOCATION=us-central1
# VERTEX_AI_MODEL=gemini-2.5-flash        # recommended — gemini-3-flash-preview not available on Vertex AI
# VERTEX_AI_MODEL=gemini-3.1-pro-preview  # pro quality option
# VERTEX_AI_CREDENTIALS_PATH=/path/to/service-account-key.json  # Optional
# See: https://developers.llamaindex.ai/python/examples/llm/google_genai/#vertex-ai-support

# Amazon Bedrock Configuration (if using Bedrock)
# See docs/LLM-EMBEDDING-CONFIG.md for detailed examples and available models
# BEDROCK_MODEL=anthropic.claude-3-5-sonnet-20241022-v2:0
# BEDROCK_REGION=us-east-1
# BEDROCK_ACCESS_KEY=your-aws-access-key  # Optional: uses default AWS credentials if not provided
# BEDROCK_SECRET_KEY=your-aws-secret-key

# Groq Configuration (if using Groq - ultra-fast inference)
# See docs/LLM-EMBEDDING-CONFIG.md for detailed examples and available models
# See pricing: https://groq.com/pricing
# All Groq models have 131,072 context window; LlamaIndex doesn't know Groq-specific models
# and defaults to 3900 tokens — flexible-graphrag overrides this automatically.
# GROQ_API_KEY=your-groq-api-key  # Get from https://console.groq.com
# GROQ_MODEL=openai/gpt-oss-20b      # 131072 ctx, 65536 max completion, 1000 t/s — recommended
# GROQ_MODEL=openai/gpt-oss-120b     # 131072 ctx, 65536 max completion, 500 t/s
# GROQ_MODEL=llama-3.3-70b-versatile # 131072 ctx, 32768 max completion, 280 t/s
# GROQ_MODEL=llama-3.1-8b-instant    # 131072 ctx, 131072 max completion, 560 t/s (smaller model)
# Note: Groq doesn't provide embeddings - defaults to local Ollama embeddings

# Fireworks AI Configuration (if using Fireworks - fast compound AI)
# Filter to: Serverless deployment + Function calling support
# All models below confirmed serverless + function calling.
# Uses DynamicLLMPathExtractor (SchemaLLMPathExtractor throws exceptions).
# flexible-graphrag uses streaming mode (_FireworksStreaming subclass) to bypass the
#   non-streaming 4096 max_tokens cap. Default max_tokens=16384.
# FIREWORKS_API_KEY=your-fireworks-api-key  # Get from https://fireworks.ai
# FIREWORKS_MODEL=accounts/fireworks/models/gpt-oss-120b
#FIREWORKS_MODEL=accounts/fireworks/models/deepseek-v3p2
#FIREWORKS_MODEL=accounts/fireworks/models/minimax-m2p5
#FIREWORKS_MODEL=accounts/fireworks/models/kimi-k2p5
#FIREWORKS_MODEL=accounts/fireworks/models/qwen3-vl-30b-a3b-thinking

# OpenAI-Like Configuration (any OpenAI-compatible API — including vLLM Docker)
# Use for: Ollama /v1 endpoint, vLLM Docker container, or any other OpenAI-compatible server.
# See docs/LLM/LLM-EMBEDDING-CONFIG.md section 17 for examples (Ollama quick-test, vLLM Docker).
# LLM_PROVIDER=openai_like
# OPENAI_LIKE_MODEL=local-model               # Model name as reported by your server
# OPENAI_LIKE_API_BASE=http://localhost:PORT/v1
# OPENAI_LIKE_API_KEY=local                   # Any string if not required
# OPENAI_LIKE_CONTEXT_WINDOW=4096
# OPENAI_LIKE_FUNCTION_CALLING=true           # Set false if model doesn't support tool calling
# OPENAI_LIKE_TIMEOUT=120.0

# vLLM — Two Options (see docs/LLM/LLM-EMBEDDING-CONFIG.md section 18 for full setup guide)
#
# OPTION 1: vLLM via Docker (all platforms — Windows, macOS, Linux)
# Start: uncomment includes/vllm.yaml in docker/docker-compose.yaml, then set below:
# LLM_PROVIDER=openai_like
# OPENAI_LIKE_MODEL=Qwen/Qwen2.5-7B-Instruct
# OPENAI_LIKE_API_BASE=http://localhost:8002/v1
# OPENAI_LIKE_API_KEY=fake
# OPENAI_LIKE_CONTEXT_WINDOW=8192
# OPENAI_LIKE_FUNCTION_CALLING=false
# OPENAI_LIKE_TIMEOUT=120.0
# Docker Compose substitutes VLLM_* vars into the container's startup command (override defaults here):
# VLLM_MODEL=Qwen/Qwen2.5-7B-Instruct   # HuggingFace model ID (default: Qwen2.5-7B-Instruct)
# VLLM_MAX_MODEL_LEN=8192               # max context length in tokens (default: 8192)
# VLLM_GPU_UTIL=0.90                    # fraction of GPU VRAM to use, 0.0-1.0 (default: 0.90)
# VLLM_DTYPE=auto                       # weight dtype: auto, float16, bfloat16 (default: auto)
# VLLM_MAX_NUM_SEQS=16                  # max concurrent sequences (default: 16)
# HF_TOKEN=                             # HuggingFace token — only needed for gated models
#
# OPTION 2: vLLM Python package — LLM_PROVIDER=vllm (Linux / macOS — UNTESTED)
# Not available on Windows. Requires: uv pip install vllm
# LLM_PROVIDER=vllm
# VLLM_MODEL=Qwen/Qwen2.5-7B-Instruct
# VLLM_MAX_MODEL_LEN=8192
# VLLM_GPU_UTIL=0.90
# VLLM_DTYPE=auto
# VLLM_MAX_NUM_SEQS=16
# HF_TOKEN=

# LiteLLM Configuration (proxy for 100+ providers)
# Requires proxy extra: pip install "litellm[proxy]"  (cmd: pip install litellm[proxy])
# Run: litellm --model ollama/gpt-oss:20b --port 4000
# Docs: https://docs.litellm.ai/docs/proxy/quick_start
# LLM_PROVIDER=litellm
# LITELLM_MODEL=gpt-4o-mini                   # Model name as configured in LiteLLM
# LITELLM_API_BASE=http://localhost:4000/v1    # LiteLLM proxy endpoint
# LITELLM_API_KEY=local                       # LiteLLM master key (or "local" if none)
# LITELLM_FUNCTION_CALLING=true

# OpenRouter Configuration (unified API for 200+ models)
# Get API key from https://openrouter.ai/keys (free tier available)
# LLM_PROVIDER=openrouter
# OPENROUTER_API_KEY=sk-or-your-key-here
# OPENROUTER_MODEL=openai/gpt-4o-mini         # or anthropic/claude-3-5-sonnet, meta-llama/llama-3.3-70b-instruct, etc.


# LLM Extraction Mode
# Controls how LlamaIndex calls the LLM for structured KG extraction (entity/relation extraction).
#   function   (default) — tool/function calling mode; most reliable for property extraction.
#              Avoids the OpenAI "additionalProperties: false" structured output bug.
#   json_schema           — structured output / JSON schema mode (PydanticProgramMode.DEFAULT)
#   auto                  — let LlamaIndex decide per provider (also maps to DEFAULT internally)
# Only change this if a specific model/server behaves poorly with function calling.
# Per-provider overrides: OPENAI_LIKE_FUNCTION_CALLING, LITELLM_FUNCTION_CALLING
#LLM_EXTRACTION_MODE=function


# ====================================================================
# EMBEDDING CONFIGURATION (Independent of LLM Provider)
# ====================================================================
# Embeddings are configured independently of your LLM provider.
# You can mix any LLM provider with any embedding provider.
# For detailed configuration examples, see: docs/LLM/LLM-EMBEDDING-CONFIG.md
#
# EMBEDDING_KIND: openai, ollama, google, vertex, azure, bedrock, fireworks, openai_like, litellm
# EMBEDDING_MODEL: Specific model name
# EMBEDDING_DIMENSION: Optional explicit dimension override (auto-detected for known models)

# Quick Examples (see docs for full details):
# - Local Ollama embeddings: EMBEDDING_KIND=ollama, EMBEDDING_MODEL=nomic-embed-text (768 dims)
# - OpenAI embeddings: EMBEDDING_KIND=openai, EMBEDDING_MODEL=text-embedding-3-small (1536 dims)
# - Vertex AI embeddings: EMBEDDING_KIND=vertex, EMBEDDING_MODEL=text-embedding-005 (768 dims)  # or gemini-embedding-2-preview / gemini-embedding-001
# - Google Gemini embeddings: EMBEDDING_KIND=google, EMBEDDING_MODEL=gemini-embedding-2-preview (768 dims)  # or gemini-embedding-001
# - Bedrock embeddings: EMBEDDING_KIND=bedrock, EMBEDDING_MODEL=amazon.titan-embed-text-v2:0 (1024 dims)
# - Fireworks embeddings: EMBEDDING_KIND=fireworks, EMBEDDING_MODEL=nomic-ai/nomic-embed-text-v1.5 (768 dims)

# OpenAI Embeddings (default)
EMBEDDING_KIND=openai
EMBEDDING_MODEL=text-embedding-3-small

# Ollama Embeddings (if using Ollama embeddings)
# See docs/LLM-EMBEDDING-CONFIG.md for detailed model options
# WARNING: all-minilm (384 dims, 512 context) is NOT recommended - its 512-token limit causes errors
# when embedding graph nodes (combined entity + relationship text). Use nomic-embed-text instead.
# EMBEDDING_KIND=ollama
#EMBEDDING_MODEL=nomic-embed-text       # 768 dims, 8192 context - recommended default
#EMBEDDING_MODEL=mxbai-embed-large      # 1024 dims, 512 context - higher quality but limited context
#EMBEDDING_MODEL=all-minilm             # 384 dims, 512 context - NOT RECOMMENDED (context too small)

# Google Gemini Embeddings (if using Gemini LLM or standalone)
# EMBEDDING_KIND=google
# EMBEDDING_MODEL=gemini-embedding-2-preview  # 768 dims - recommended (text-embedding-004 deprecated 2026-01-14)
# EMBEDDING_MODEL=gemini-embedding-001        # 768 dims - stable GA alternative

# Google Vertex AI Embeddings (if using Vertex AI LLM or standalone)
# EMBEDDING_KIND=vertex
# EMBEDDING_MODEL=gemini-embedding-2-preview  # 768 dims - recommended
# EMBEDDING_MODEL=gemini-embedding-001        # 768 dims - stable GA alternative
# EMBEDDING_MODEL=text-embedding-005          # 768 dims - text-only option (text-embedding-004 deprecated 2026-01-14)

# OpenAI-Like Embeddings (uses OpenAILikeEmbedding class)
# Any server with a /v1/embeddings endpoint: LM Studio, LocalAI, vLLM, Llamafile, etc.
# Can be used with ANY LLM provider - e.g. OpenAI LLM + local embeddings for privacy/cost savings
# Confirmed working: nomic-embed-text via Ollama (localhost:11434/v1) with OpenAI gpt-4.1-mini (2026-03-20)
# See docs/LLM/LLM-EMBEDDING-CONFIG.md for full details and examples
# EMBEDDING_KIND=openai_like
# EMBEDDING_MODEL=nomic-embed-text                         # Model name served by your local server
# OPENAI_LIKE_EMBEDDING_API_BASE=http://localhost:11434/v1      # Ollama default — or your server's /v1 URL
# OPENAI_LIKE_API_KEY=local                                # Any string if auth not required
# EMBEDDING_DIMENSION=768                                       # Required for nomic-embed-text

# LiteLLM Embeddings (uses LiteLLMEmbedding class)
# Route embeddings through a LiteLLM proxy to any backend (OpenAI, Ollama, Bedrock, etc.)
# Can be used with ANY LLM provider - e.g. Groq LLM + LiteLLM embeddings
# Confirmed working: text-embedding-3-small via LiteLLM proxy (2026-03-19)
# See docs/LLM/LLM-EMBEDDING-CONFIG.md for full details and examples
# EMBEDDING_KIND=litellm
# EMBEDDING_MODEL=text-embedding-3-small                   # Model as configured in your LiteLLM proxy
# LITELLM_EMBEDDING_API_BASE=http://localhost:4000/v1           # Must include /v1 suffix
# LITELLM_API_KEY=local                                    # LiteLLM master key

# ====================================================================
# 5. CONTENT SOURCES CONFIGURATION
# ====================================================================

# Data Source Type (mainly for REST API and MCP server usage)
# Options: filesystem, cmis, alfresco, upload, web, wikipedia, youtube, s3, gcs, azure_blob, onedrive, sharepoint, box, google_drive
# Note: UI clients typically override this setting with their own data source selection
DATA_SOURCE=filesystem

# Source Paths (for filesystem data source - REST API and MCP server)
# Note: UI clients use file upload dialogs instead of this configuration
# For path format examples, see docs/DATA-SOURCE-CONFIGURATION.md
SOURCE_PATHS=["./sample-docs/cmispress.txt"]

# CMIS Configuration (if using CMIS)
CMIS_URL=http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
CMIS_USERNAME=admin
CMIS_PASSWORD=admin

# Alfresco Configuration (if using Alfresco)
# Note: Requires python-alfresco-api >= 1.1.5 for optimal performance
# Paths: Use short format like "/Shared/GraphRAG" (recommended - matches Alfresco Share UI)
#        Full format like "/Company Home/Shared/GraphRAG" also works (prefix is auto-stripped)
#        Both formats supported - system handles /Company Home prefix automatically
ALFRESCO_URL=http://localhost:8080
ALFRESCO_USERNAME=admin
ALFRESCO_PASSWORD=admin
# ALFRESCO_STOMP_PORT: ActiveMQ STOMP port for real-time events (default: 61613)
# Note: If you've changed the ActiveMQ STOMP port in docker-compose (e.g., to 8613), set it here
#ALFRESCO_STOMP_PORT=8613

# Amazon S3 Configuration (if using S3)
# Note: These values serve as defaults/fallbacks when S3_CONFIG is not provided or incomplete
# S3_CONFIG (in section above) takes precedence, these are used as fallbacks
# S3_REGION_NAME=us-east-1           # AWS region for S3 bucket (default: us-east-1 if not in S3_CONFIG)
# S3_BUCKET_NAME=my-bucket           # Default bucket name (used if not specified in S3_CONFIG)
# S3_PREFIX=documents/               # Default prefix/path within bucket
# S3_PREFIX=""                       # Or leave empty for whole bucket (top level)
# S3_ACCESS_KEY=myaccesskeyid        # AWS access key ID (used if not specified in S3_CONFIG)
# S3_SECRET_KEY=mysecretaccesskey    # AWS secret access key (used if not specified in S3_CONFIG)

# ====================================================================
# DATABASE CONNECTION DETAILS (Individual Configs)
# ====================================================================

# Neo4j Configuration (for both vector and graph storage)
# Browser URL: http://localhost:7474/browser (for database management and queries)
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
# NEO4J_DATABASE=neo4j  # Optional: specify database name (default: neo4j)

# Neo4j AuraDB (cloud) example:
# NEO4J_URI=neo4j+s://<dbid>.databases.neo4j.io
# NEO4J_USER=neo4j
# NEO4J_PASSWORD=<aura-generated-password>
# Console URL: https://console.neo4j.io

# Elasticsearch Configuration
ELASTICSEARCH_URL=http://localhost:9200
ELASTICSEARCH_USERNAME=
ELASTICSEARCH_PASSWORD=

# Qdrant Configuration
QDRANT_HOST=localhost
QDRANT_PORT=6333
QDRANT_API_KEY=
# QDRANT_COLLECTION=hybrid_search  # Optional: collection name
# QDRANT_HTTPS=false  # Use HTTPS for remote Qdrant instances

# Weaviate Configuration
WEAVIATE_URL=http://localhost:8081
WEAVIATE_INDEX_NAME=HybridSearch
# WEAVIATE_API_KEY=your_weaviate_api_key  # Optional: for authenticated instances
# WEAVIATE_TEXT_KEY=content  # Optional: field name for text content

# OpenSearch Configuration
OPENSEARCH_URL=http://localhost:9201
OPENSEARCH_USERNAME=
OPENSEARCH_PASSWORD=

# Processing Configuration
CHUNK_SIZE=1024
CHUNK_OVERLAP=128

#CHUNK_SIZE=512
#CHUNK_OVERLAP=64

# Knowledge Graph Extraction Limits (configurable for different content densities)
# MAX_TRIPLETS_PER_CHUNK: Used by DynamicLLMPathExtractor and SchemaLLMPathExtractor - controls how many entity-relationship triplets can be extracted per text chunk
# MAX_PATHS_PER_CHUNK: Used by SimpleLLMPathExtractor - controls how many relationship paths can be extracted per text chunk
# Higher values allow more comprehensive extraction from dense content but may increase processing time
# Lower values are faster but may miss entities/relationships in complex documents
# These values are higher than the usual 20-25 seen in examples, are more to rule out
# that this is what is limiting extraction.
#MAX_TRIPLETS_PER_CHUNK=100
#MAX_PATHS_PER_CHUNK=100

MAX_TRIPLETS_PER_CHUNK=20
MAX_PATHS_PER_CHUNK=20

# Timeout configurations moved to docs/TIMEOUT-CONFIGURATIONS.md
# Uncomment and adjust these if you need custom timeout values:
# 
# DOCLING_TIMEOUT=600  # Docling conversion timeout per document (seconds, default: 10 minutes)
# DOCLING_CANCEL_CHECK_INTERVAL=0.5  # How often to check for cancellation (seconds)
#   - We wrap Docling in background executor with periodic polling for cancellation
#   - Lower = more responsive, higher = less CPU overhead
# 
# KG_EXTRACTION_TIMEOUT=3600  # Knowledge graph extraction timeout per document
# KG_CANCEL_CHECK_INTERVAL=2.0  # How often to check for cancellation during KG extraction
# 
# OPENAI_TIMEOUT=120.0  # For OpenAI LLM requests
# OLLAMA_TIMEOUT=300.0  # For Ollama LLM requests

# ====================================================================
# 6. INCREMENTAL UPDATES CONFIGURATION (Optional - for auto-sync monitoring)
# ====================================================================

# Enable incremental updates system (automatic monitoring and sync)
# Set to "true" to enable auto-sync capabilities
# Requires PostgreSQL for state management
# Default: false (incremental updates disabled)
ENABLE_INCREMENTAL_UPDATES=false

# PostgreSQL connection for state management (required if ENABLE_INCREMENTAL_UPDATES=true)
# Recommended: Reuse existing postgres-pgvector service on port 5433
# Create database: flexible_graphrag_incremental (separate from pgvector database)
# Setup: See flexible-graphrag/incremental_updates/schema.sql
# POSTGRES_INCREMENTAL_URL=postgresql://postgres:password@localhost:5433/flexible_graphrag_incremental

# Optional: Periodic refresh interval (seconds) - how often to scan datasources
# Default: 3600 (1 hour) - datasources refresh automatically every hour
# Individual datasources can override this via API
# INCREMENTAL_REFRESH_INTERVAL=3600

# Optional: Watchdog filesystem delay (seconds) - debounce for file changes
# Default: 60 (1 minute) - filesystem changes are processed after 1 minute of inactivity
# Individual datasources can override this via API
# INCREMENTAL_WATCHDOG_DELAY=60

# Note: Individual datasources created via UI "Enable Sync" checkbox can override
# these defaults with custom refresh intervals and watchdog delays per datasource

# Setup Instructions: See flexible-graphrag/incremental_updates/SETUP-GUIDE.md
# - PostgreSQL schema setup
# - Database creation steps
# - Configuration details
# - Troubleshooting guide

# =============================================================================
# 7. OBSERVABILITY CONFIGURATION (OpenTelemetry Traces and Metrics)
# =============================================================================
# Enable observability with OpenTelemetry, Prometheus, Grafana, Jaeger
# Set to "true" to enable automatic instrumentation of LlamaIndex operations
ENABLE_OBSERVABILITY=false

# Observability Backend Mode (choose your telemetry producer)
# Options:
#   "openinference" - Default, trace-focused, requires spanmetrics connector for token metrics
#   "openlit" - Alternative with built-in token metrics (gen_ai_usage_*_tokens_total)
#   "both" - DUAL MODE (recommended!) - Best of both worlds!
#     - OpenInference: Detailed traces with full LlamaIndex operation visibility
#     - OpenLIT: Token metrics, cost tracking, VectorDB metrics out-of-the-box
#     - Custom metrics: Graph extraction, retrieval, document processing
# Recommendation: Use "both" for complete observability with all metrics
OBSERVABILITY_BACKEND=both

# OTLP (OpenTelemetry Protocol) exporter endpoint
# Default: http://localhost:4318 (OTLP HTTP receiver)
# For gRPC: use http://localhost:4317
# For cloud services (SigNoz, Langfuse, etc.), use their endpoint
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

# Service metadata for traces
OTEL_SERVICE_NAME=flexible-graphrag
OTEL_SERVICE_VERSION=1.0.0
OTEL_SERVICE_NAMESPACE=llm-apps

# Enable automatic LlamaIndex instrumentation (captures all LlamaIndex operations)
# Set to "false" if you only want manual tracing with custom decorators
ENABLE_LLAMA_INDEX_INSTRUMENTATION=true

# ====================================================================
# RDF / TRIPLE STORE CONFIGURATION
# ====================================================================
# Flexible GraphRAG supports storing extracted knowledge graphs in RDF
# triple stores (Fuseki, GraphDB, Oxigraph) in addition to or instead
# of the configured property graph (Neo4j, etc.).
#
# INGESTION_STORAGE_MODE controls where extracted KG data is written:
#   property_graph (default) - property graph only (Neo4j, etc.)
#   rdf_only                 - RDF stores only (skips PropertyGraphIndex)
#   both                     - property graph AND RDF stores simultaneously
#INGESTION_STORAGE_MODE=property_graph
#INGESTION_STORAGE_MODE=rdf_only
#INGESTION_STORAGE_MODE=both

# RDF_ANNOTATION_SYNTAX: how relation properties are encoded in RDF output
#   rdf_1.2      (default) - RDF 1.2 inline {| |} annotation syntax
#                          Turtle 1.2 standard; cleaner and preferred for new data.
#                          Example: <s> <p> <o> {| <prop> "value" |} .
#                          Requires: Fuseki 5 (Jena 5), GraphDB 10+, Oxigraph 0.4+
#   rdf_star             - Legacy << >> assertion-annotation lines
#                          Example: << <s> <p> <o> >>  <prop>  "value" .
#                          Same store support as rdf_1.2, older syntax.
#   flat                 - Plain compound-predicate triples, no annotation semantics
#                          Example: <s>  onto:rel__prop  "value" .
#                          Works with any SPARQL 1.1 triple store.
RDF_ANNOTATION_SYNTAX=rdf_1.2

# Base namespace for entity instance URIs in RDF output.
# "Alice Johnson" -> <https://integratedsemantics.org/flexible-graphrag/kg/alice_johnson>
RDF_BASE_NAMESPACE=https://integratedsemantics.org/flexible-graphrag/kg/

# Relation properties are stored as RDF-star annotations (RDF 1.2):
#   <<:alice onto:WORKS_FOR :techcorp>> onto:since "2020"^^xsd:integer .
# All three stores support RDF-star natively: Fuseki (Jena 4+), GraphDB, Oxigraph

# -------------------------------------------------------------------
# RDF Store Connections (METHOD 1 - Standalone vars, recommended)
# -------------------------------------------------------------------

# Apache Fuseki
#FUSEKI_ENABLED=false
#FUSEKI_ENABLED=true
#FUSEKI_BASE_URL=http://localhost:3030
#FUSEKI_DATASET=flexible-graphrag
#FUSEKI_USERNAME=admin
#FUSEKI_PASSWORD=admin

# Ontotext GraphDB
#GRAPHDB_ENABLED=false
#GRAPHDB_ENABLED=true
#GRAPHDB_BASE_URL=http://localhost:7200
#GRAPHDB_REPOSITORY=flexible-graphrag
#GRAPHDB_USERNAME=admin
#GRAPHDB_PASSWORD=admin

# Oxigraph (embedded with file path or HTTP mode with docker container)
#OXIGRAPH_ENABLED=false
#OXIGRAPH_ENABLED=true
# HTTP mode (preferred — uses Docker container at port 7878, no file locking):
#OXIGRAPH_URL=http://localhost:7878
# Embedded mode (single-process only, not recommended when API server is running):
#OXIGRAPH_STORE_PATH=./data/oxigraph_store

# -------------------------------------------------------------------
# RDF Store Connections (METHOD 2 - JSON array, advanced/dynamic)
# -------------------------------------------------------------------
# Only used when no standalone vars above are enabled.
# Comma-separated list of store names to activate:
#RDF_ENABLED_STORES=fuseki,graphdb
#
# Full store definitions as a JSON array:
#RDF_STORES=[{"name":"fuseki","type":"fuseki","config":{"base_url":"http://localhost:3030","dataset":"flexible-graphrag"}},{"name":"graphdb","type":"graphdb","config":{"base_url":"http://localhost:7200","repository":"flexible-graphrag","username":"admin","password":"admin"}}]

# ===========================
# Query Routing Defaults
# ===========================
# QUERY_ROUTING_DEFAULT: Where to route graph queries
#  - property_graph: Query configured property graph (Neo4j, etc.) only (Cypher)
#  - sparql: Query RDF stores only (Fuseki/GraphDB/Oxigraph)
#  - hybrid: Query both property graph AND RDF stores, merge results
#  - auto: Automatically choose based on query structure
# Note: This is different from "hybrid search" (vector+fulltext+graph)
QUERY_ROUTING_DEFAULT=property_graph

# DEFAULT_RDF_BACKEND: reserved for future query routing — not currently used by the code.
#DEFAULT_RDF_BACKEND=fuseki

# Enable/disable query language support
SUPPORT_SPARQL=true
SUPPORT_CYPHER=true

# -------------------------------------------------------------------
# RDF Export
# -------------------------------------------------------------------
# Expose /export/rdf API endpoint to dump property graph as RDF
ENABLE_RDF_EXPORT=false
# Serialization format: turtle | ntriples | rdfxml | nquads
RDF_EXPORT_FORMAT=turtle

# ===========================
# RDF Retrieval Configuration (LangChain Integration)
# ===========================
# Enable LangChain-based RDF graph retrieval in hybrid search
# When enabled, adds natural language to SPARQL query capability
# Required packages (install manually based on your provider):
#   uv pip install langchain langchain-community langchain-openai SPARQLWrapper   # GraphDB/Fuseki/Oxigraph + OpenAI
#   uv pip install langchain-google-genai                 # Gemini
#   uv pip install langchain-google-vertexai              # Vertex AI
#   uv pip install langchain-anthropic                    # Anthropic / Claude
#   uv pip install langchain-aws                          # Bedrock or Neptune RDF
#   uv pip install langchain-ollama                       # Ollama
#   uv pip install langchain-groq                         # Groq
#   uv pip install langchain-fireworks                    # Fireworks AI
USE_LANGCHAIN_RDF=false

# RDF store type for retrieval: graphdb | fuseki | oxigraph | neptune_rdf
# Must match one of the enabled RDF stores (GRAPHDB_ENABLED, FUSEKI_ENABLED, OXIGRAPH_ENABLED)
# graphdb    - Ontotext GraphDB via LangChain OntotextGraphDBGraph + GraphSparqlQAChain
# fuseki     - Apache Fuseki (Jena) via LangChain RdfGraph + GraphSparqlQAChain
# oxigraph   - Oxigraph HTTP server via LangChain RdfGraph + GraphSparqlQAChain
# neptune_rdf - Amazon Neptune RDF via LangChain NeptuneRdfGraph + create_neptune_sparql_qa_chain
RDF_STORE_TYPE=graphdb

# Weight for RDF retrieval results in fusion (0.0-1.0)
# Higher = more emphasis on graph-based context
RDF_RETRIEVAL_WEIGHT=0.3

# Number of results to return from RDF retriever
RDF_RETRIEVAL_TOP_K=5

# ===========================
# LangChain Property Graph Store (fusion retriever)
# ===========================
# When USE_LANGCHAIN_PG=true, a LangChain property graph QA chain is used for
# the graph retriever slot in the hybrid fusion pipeline instead of the
# LlamaIndex graph_index (PropertyGraphIndex).  Only one is active at a time.
#
# IMPORTANT: ingestion and retrieval must target the same store.
# GRAPH_DB=none with USE_LANGCHAIN_PG=true results in an empty graph — the
# LangChain chain has nothing to query.  Always set GRAPH_DB= to the same
# store type as LANGCHAIN_PG_STORE_TYPE when ingesting via this pipeline.
#
# Supported LANGCHAIN_PG_STORE_TYPE values:
#   neo4j            - Neo4j (bolt) via langchain_neo4j > langchain_community
#   memgraph         - Memgraph (bolt) via langchain_memgraph > langchain_community
#   kuzu             - Kùzu embedded via langchain_kuzu > langchain_community  (needs KUZU_DB_PATH)
#   falkordb         - FalkorDB via langchain_community
#   hugegraph        - Apache HugeGraph via langchain_community
#   nebula           - NebulaGraph via langchain_community
#   tigergraph       - TigerGraph via langchain_community
#   arcadedb         - ArcadeDB via langchain_arcadedb  (uv pip install langchain-arcadedb)
#   arangodb         - ArangoDB via langchain_community chains
#   neptune          - Neptune Database OpenCypher via langchain_aws
#   neptune_analytics- Neptune Analytics via langchain_aws
#   apache_age       - Apache AGE (PostgreSQL Cypher) via langchain_community
#   cosmos_gremlin   - Azure Cosmos DB Gremlin via langchain_community
#   spanner          - Google Spanner Graph via langchain_google_spanner
#
# Connection details are read from the same GRAPH_DB connection fields
# (e.g. for neo4j: graph_config url/username/password, for arangodb:
# ARANGODB_URL / ARANGODB_USERNAME / ARANGODB_PASSWORD, etc.)
USE_LANGCHAIN_PG=false
#LANGCHAIN_PG_STORE_TYPE=neo4j

# LangChain PG vector search — embedding similarity search against graph entity nodes.
# Works independently of USE_LANGCHAIN_PG and GRAPH_DB — only requires that
# GRAPH_DB=neo4j ingestion has run (which creates the __Entity__[embedding] index).
# Can run alongside the LlamaIndex graph_retriever; fusion deduplicates overlapping hits.
#LANGCHAIN_PG_VECTOR_SEARCH=false
# Index / label / property names (defaults match LlamaIndex ingestion schema):
#LANGCHAIN_PG_VECTOR_INDEX=entity
#LANGCHAIN_PG_VECTOR_NODE_LABEL=__Entity__
#LANGCHAIN_PG_VECTOR_EMBEDDING_PROPERTY=embedding
#LANGCHAIN_PG_VECTOR_TEXT_PROPERTY=name

# LangChain PG neighborhood retriever — k-hop graph expansion from vector seeds.
# Mirrors LlamaIndex VectorContextRetriever for stores that only have LangChain support.
# Skipped automatically when the LlamaIndex graph_retriever is active.
#USE_PG_NEIGHBORHOOD=false
#PG_NEIGHBORHOOD_HOPS=2             # max relationship hops (default 2)
#PG_NEIGHBORHOOD_TOP_K_SEEDS=10     # vector hits used as expansion seeds

# Synonym exploder — LLM-based query rewriter applied before selected retrievers.
# Generates synonyms/related keywords (^ separated, same convention as LLMSynonymRetriever)
# to improve lexical + embedding recall.
#
# SYNONYM_EXPLODER_SCOPE accepts a comma-separated list of retriever tags, or:
#   all   — wrap the entire fusion retriever (one LLM call covers everything)
#   none  — disable
# Per-retriever tags (combine freely):
#   llamaindex_vector           — LlamaIndex VectorStoreIndex retriever
#   llamaindex_search           — LlamaIndex BM25 / Elasticsearch / OpenSearch
#   llamaindex_pg_graph         — LlamaIndex PropertyGraph graph_retriever
#   langchain_pg_vector         — LangChain PG vector retriever
#   langchain_rdf_graph         — LangChain RDF/SPARQL retriever
#   langchain_pg_graph          — LangChain property-graph Cypher QA retriever
#   langchain_pg_neighborhood   — PG neighborhood k-hop retriever
#USE_SYNONYM_EXPLODER=false
#SYNONYM_EXPLODER_MAX_KEYWORDS=8
#SYNONYM_EXPLODER_SCOPE=langchain_pg_graph,langchain_pg_vector

# ===========================
# Ontology Configuration
# ===========================
# Enable ontology-based knowledge graph extraction
# When enabled, uses RDF/RDFS/OWL ontology schemas for entity/relation extraction (OWL is optional)
USE_ONTOLOGY=false
#USE_ONTOLOGY=true

# --- Single ontology file (simplest) ---
# All classes, object properties, and datatype properties in one file.
#ONTOLOGY_PATH=./rdf/schemas/company_ontology.ttl

# --- Comma-separated list of specific files (second precedence) ---
# Split ontologies are a common pattern: one file for classes/relations,
# another for datatype properties, plus optional third-party ontologies
# (FOAF, Dublin Core, schema.org) or a generic common_ontology.ttl.
ONTOLOGY_PATHS=./rdf/schemas/company_classes.ttl,./rdf/schemas/company_properties.ttl,./rdf/schemas/common_ontology.ttl

# --- Directory of ontology files (highest precedence) ---
# All .ttl / .rdf / .owl / .n3 / .nt files in the directory are loaded and merged.
# Useful when maintaining many domain ontologies or mixing published ontologies.
#ONTOLOGY_DIR=./rdf/schemas/

# Serialization format for ONTOLOGY_PATH and ONTOLOGY_PATHS.
# Directory loading (ONTOLOGY_DIR) auto-detects format from file extension.
ONTOLOGY_FORMAT=turtle          # turtle | rdfxml | ntriples | nquads
