diff --git a/.env.alfred b/.env.alfred new file mode 100644 index 0000000..c82f6d9 --- /dev/null +++ b/.env.alfred @@ -0,0 +1,93 @@ +MAX_HISTORY_MESSAGES=10 +MAX_TOOL_ITERATIONS=10 +REQUEST_TIMEOUT=30 + +# LLM Settings +LLM_TEMPERATURE=0.2 + +# Persistence +DATA_STORAGE_DIR=data + +# Network configuration +HOST=0.0.0.0 +PORT=3080 + +# Build informations (Synced with pyproject.toml via bootstrap) +ALFRED_VERSION= +IMAGE_NAME= +LIBRECHAT_VERSION= +PYTHON_VERSION= +PYTHON_VERSION_SHORT= +RAG_VERSION= +RUNNER= +SERVICE_NAME= + +# --- SECURITY KEYS (CRITICAL) --- +# These are used for session tokens and encrypting sensitive data in MongoDB. +# If you lose these, you lose access to encrypted stored credentials. +JWT_SECRET= +JWT_REFRESH_SECRET= +CREDS_KEY= +CREDS_IV= + +# --- DATABASES (AUTO-SECURED) --- +# Alfred uses MongoDB for application state and PostgreSQL for Vector RAG. +# Passwords will be generated as 24-character secure tokens if left blank. + +# MongoDB (Application Data) +MONGO_URI= +MONGO_HOST=mongodb +MONGO_PORT=27017 +MONGO_USER=alfred +MONGO_PASSWORD= +MONGO_DB_NAME=LibreChat + +# PostgreSQL (Vector Database / RAG) +POSTGRES_URI= +POSTGRES_HOST=vectordb +POSTGRES_PORT=5432 +POSTGRES_USER=alfred +POSTGRES_PASSWORD= +POSTGRES_DB_NAME=alfred + +# --- EXTERNAL SERVICES --- +# Media Metadata (Required) +# Get your key at https://www.themoviedb.org/ +TMDB_API_KEY= +TMDB_BASE_URL=https://api.themoviedb.org/3 + +# qBittorrent integration +QBITTORRENT_URL=http://qbittorrent:16140 +QBITTORRENT_USERNAME=admin +QBITTORRENT_PASSWORD= +QBITTORRENT_PORT=16140 + +# Meilisearch +MEILI_ENABLED=FALSE +MEILI_NO_ANALYTICS=TRUE +MEILI_HOST=http://meilisearch:7700 +MEILI_MASTER_KEY= + +# --- LLM CONFIGURATION --- +# Providers: 'local', 'openai', 'anthropic', 'deepseek', 'google', 'kimi' +DEFAULT_LLM_PROVIDER=local + +# Local LLM (Ollama) +OLLAMA_BASE_URL=http://ollama:11434 +OLLAMA_MODEL=llama3.3:latest + +# --- API KEYS (OPTIONAL) --- +# Fill only the ones you intend to use. +ANTHROPIC_API_KEY= +DEEPSEEK_API_KEY= +GOOGLE_API_KEY= +KIMI_API_KEY= +OPENAI_API_KEY= + +# --- RAG ENGINE --- +# Enable/Disable the Retrieval Augmented Generation system +RAG_ENABLED=TRUE +RAG_API_URL=http://rag_api:8000 +RAG_API_PORT=8000 +EMBEDDINGS_PROVIDER=ollama +EMBEDDINGS_MODEL=nomic-embed-text diff --git a/.env.librechat b/.env.librechat new file mode 100644 index 0000000..db09bb4 --- /dev/null +++ b/.env.librechat @@ -0,0 +1,878 @@ +#=====================================================================# +# LibreChat Configuration # +#=====================================================================# +# Please refer to the reference documentation for assistance # +# with configuring your LibreChat environment. # +# # +# https://www.librechat.ai/docs/configuration/dotenv # +#=====================================================================# + +#==================================================# +# Server Configuration # +#==================================================# + +HOST=localhost +PORT=3080 + +MONGO_URI=mongodb://127.0.0.1:27017/LibreChat +#The maximum number of connections in the connection pool. */ +MONGO_MAX_POOL_SIZE= +#The minimum number of connections in the connection pool. */ +MONGO_MIN_POOL_SIZE= +#The maximum number of connections that may be in the process of being established concurrently by the connection pool. */ +MONGO_MAX_CONNECTING= +#The maximum number of milliseconds that a connection can remain idle in the pool before being removed and closed. */ +MONGO_MAX_IDLE_TIME_MS= +#The maximum time in milliseconds that a thread can wait for a connection to become available. */ +MONGO_WAIT_QUEUE_TIMEOUT_MS= +# Set to false to disable automatic index creation for all models associated with this connection. */ +MONGO_AUTO_INDEX= +# Set to `false` to disable Mongoose automatically calling `createCollection()` on every model created on this connection. */ +MONGO_AUTO_CREATE= + +DOMAIN_CLIENT=http://localhost:3080 +DOMAIN_SERVER=http://localhost:3080 + +NO_INDEX=true +# Use the address that is at most n number of hops away from the Express application. +# req.socket.remoteAddress is the first hop, and the rest are looked for in the X-Forwarded-For header from right to left. +# A value of 0 means that the first untrusted address would be req.socket.remoteAddress, i.e. there is no reverse proxy. +# Defaulted to 1. +TRUST_PROXY=1 + +# Minimum password length for user authentication +# Default: 8 +# Note: When using LDAP authentication, you may want to set this to 1 +# to bypass local password validation, as LDAP servers handle their own +# password policies. +# MIN_PASSWORD_LENGTH=8 + +# When enabled, the app will continue running after encountering uncaught exceptions +# instead of exiting the process. Not recommended for production unless necessary. +# CONTINUE_ON_UNCAUGHT_EXCEPTION=false + +#===============# +# JSON Logging # +#===============# + +# Use when process console logs in cloud deployment like GCP/AWS +CONSOLE_JSON=false + +#===============# +# Debug Logging # +#===============# + +DEBUG_LOGGING=true +DEBUG_CONSOLE=false +# Set to true to enable agent debug logging +AGENT_DEBUG_LOGGING=false + +# Enable memory diagnostics (logs heap/RSS snapshots every 60s, auto-enabled with --inspect) +# MEM_DIAG=true + +#=============# +# Permissions # +#=============# + +# UID=1000 +# GID=1000 + +#==============# +# Node Options # +#==============# + +# NOTE: NODE_MAX_OLD_SPACE_SIZE is NOT recognized by Node.js directly. +# This variable is used as a build argument for Docker or CI/CD workflows, +# and is NOT used by Node.js to set the heap size at runtime. +# To configure Node.js memory, use NODE_OPTIONS, e.g.: +# NODE_OPTIONS="--max-old-space-size=6144" +# See: https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib +NODE_MAX_OLD_SPACE_SIZE=6144 + +#===============# +# Configuration # +#===============# +# Use an absolute path, a relative path, or a URL + +# CONFIG_PATH="/alternative/path/to/librechat.yaml" + +#==================# +# Langfuse Tracing # +#==================# + +# Get Langfuse API keys for your project from the project settings page: https://cloud.langfuse.com + +# LANGFUSE_PUBLIC_KEY= +# LANGFUSE_SECRET_KEY= +# LANGFUSE_BASE_URL= + +#===================================================# +# Endpoints # +#===================================================# + +# ENDPOINTS=openAI,assistants,azureOpenAI,google,anthropic + +PROXY= + +#===================================# +# Known Endpoints - librechat.yaml # +#===================================# +# https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints + +# ANYSCALE_API_KEY= +# APIPIE_API_KEY= +# COHERE_API_KEY= +# DEEPSEEK_API_KEY= +# DATABRICKS_API_KEY= +# FIREWORKS_API_KEY= +# GROQ_API_KEY= +# HUGGINGFACE_TOKEN= +# MISTRAL_API_KEY= +# OPENROUTER_KEY= +# PERPLEXITY_API_KEY= +# SHUTTLEAI_API_KEY= +# TOGETHERAI_API_KEY= +# UNIFY_API_KEY= +# XAI_API_KEY= + +#============# +# Anthropic # +#============# + +ANTHROPIC_API_KEY=user_provided +# ANTHROPIC_MODELS=claude-sonnet-4-6,claude-opus-4-6,claude-opus-4-20250514,claude-sonnet-4-20250514,claude-3-7-sonnet-20250219,claude-3-5-sonnet-20241022,claude-3-5-haiku-20241022,claude-3-opus-20240229,claude-3-sonnet-20240229,claude-3-haiku-20240307 +# ANTHROPIC_REVERSE_PROXY= + +# Set to true to use Anthropic models through Google Vertex AI instead of direct API +# ANTHROPIC_USE_VERTEX= +# ANTHROPIC_VERTEX_REGION=us-east5 + +#============# +# Azure # +#============# + +# Note: these variables are DEPRECATED +# Use the `librechat.yaml` configuration for `azureOpenAI` instead +# You may also continue to use them if you opt out of using the `librechat.yaml` configuration + +# AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated +# AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated +# AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated +# AZURE_API_KEY= # Deprecated +# AZURE_OPENAI_API_INSTANCE_NAME= # Deprecated +# AZURE_OPENAI_API_DEPLOYMENT_NAME= # Deprecated +# AZURE_OPENAI_API_VERSION= # Deprecated +# AZURE_OPENAI_API_COMPLETIONS_DEPLOYMENT_NAME= # Deprecated +# AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME= # Deprecated + +#=================# +# AWS Bedrock # +#=================# + +# BEDROCK_AWS_DEFAULT_REGION=us-east-1 # A default region must be provided +# BEDROCK_AWS_ACCESS_KEY_ID=someAccessKey +# BEDROCK_AWS_SECRET_ACCESS_KEY=someSecretAccessKey +# BEDROCK_AWS_SESSION_TOKEN=someSessionToken + +# Note: This example list is not meant to be exhaustive. If omitted, all known, supported model IDs will be included for you. +# BEDROCK_AWS_MODELS=anthropic.claude-sonnet-4-6,anthropic.claude-opus-4-6-v1,anthropic.claude-3-5-sonnet-20240620-v1:0,meta.llama3-1-8b-instruct-v1:0 +# Cross-region inference model IDs: us.anthropic.claude-sonnet-4-6,us.anthropic.claude-opus-4-6-v1,global.anthropic.claude-opus-4-6-v1 + +# See all Bedrock model IDs here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html#model-ids-arns + +# Notes on specific models: +# The following models are not support due to not supporting streaming: +# ai21.j2-mid-v1 + +# The following models are not support due to not supporting conversation history: +# ai21.j2-ultra-v1, cohere.command-text-v14, cohere.command-light-text-v14 + +#============# +# Google # +#============# + +GOOGLE_KEY=user_provided + +# GOOGLE_REVERSE_PROXY= +# Some reverse proxies do not support the X-goog-api-key header, uncomment to pass the API key in Authorization header instead. +# GOOGLE_AUTH_HEADER=true + +# Gemini API (AI Studio) +# GOOGLE_MODELS=gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash,gemini-2.0-flash-lite + +# Vertex AI +# GOOGLE_MODELS=gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash-001,gemini-2.0-flash-lite-001 + +# GOOGLE_TITLE_MODEL=gemini-2.0-flash-lite-001 + +# Google Cloud region for Vertex AI (used by both chat and image generation) +# GOOGLE_LOC=us-central1 + +# Alternative region env var for Gemini Image Generation +# GOOGLE_CLOUD_LOCATION=global + +# Vertex AI Service Account Configuration +# Path to your Google Cloud service account JSON file +# GOOGLE_SERVICE_KEY_FILE=/path/to/service-account.json + +# Google Safety Settings +# NOTE: These settings apply to both Vertex AI and Gemini API (AI Studio) +# +# For Vertex AI: +# To use the BLOCK_NONE setting, you need either: +# (a) Access through an allowlist via your Google account team, or +# (b) Switch to monthly invoiced billing: https://cloud.google.com/billing/docs/how-to/invoiced-billing +# +# For Gemini API (AI Studio): +# BLOCK_NONE is available by default, no special account requirements. +# +# Available options: BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, BLOCK_LOW_AND_ABOVE +# +# GOOGLE_SAFETY_SEXUALLY_EXPLICIT=BLOCK_ONLY_HIGH +# GOOGLE_SAFETY_HATE_SPEECH=BLOCK_ONLY_HIGH +# GOOGLE_SAFETY_HARASSMENT=BLOCK_ONLY_HIGH +# GOOGLE_SAFETY_DANGEROUS_CONTENT=BLOCK_ONLY_HIGH +# GOOGLE_SAFETY_CIVIC_INTEGRITY=BLOCK_ONLY_HIGH + +#========================# +# Gemini Image Generation # +#========================# + +# Gemini Image Generation Tool (for Agents) +# Supports multiple authentication methods in priority order: +# 1. User-provided API key (via GUI) +# 2. GEMINI_API_KEY env var (admin-configured) +# 3. GOOGLE_KEY env var (shared with Google chat endpoint) +# 4. Vertex AI service account (via GOOGLE_SERVICE_KEY_FILE) + +# Option A: Use dedicated Gemini API key for image generation +# GEMINI_API_KEY=your-gemini-api-key + +# Vertex AI model for image generation (defaults to gemini-2.5-flash-image) +# GEMINI_IMAGE_MODEL=gemini-2.5-flash-image + +#============# +# OpenAI # +#============# + +OPENAI_API_KEY=user_provided +# OPENAI_MODELS=gpt-5,gpt-5-codex,gpt-5-mini,gpt-5-nano,o3-pro,o3,o4-mini,gpt-4.1,gpt-4.1-mini,gpt-4.1-nano,o3-mini,o1-pro,o1,gpt-4o,gpt-4o-mini + +DEBUG_OPENAI=false + +# TITLE_CONVO=false +# OPENAI_TITLE_MODEL=gpt-4o-mini + +# OPENAI_SUMMARIZE=true +# OPENAI_SUMMARY_MODEL=gpt-4o-mini + +# OPENAI_FORCE_PROMPT=true + +# OPENAI_REVERSE_PROXY= + +# OPENAI_ORGANIZATION= + +#====================# +# Assistants API # +#====================# + +ASSISTANTS_API_KEY=user_provided +# ASSISTANTS_BASE_URL= +# ASSISTANTS_MODELS=gpt-4o,gpt-4o-mini,gpt-3.5-turbo-0125,gpt-3.5-turbo-16k-0613,gpt-3.5-turbo-16k,gpt-3.5-turbo,gpt-4,gpt-4-0314,gpt-4-32k-0314,gpt-4-0613,gpt-3.5-turbo-0613,gpt-3.5-turbo-1106,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview + +#==========================# +# Azure Assistants API # +#==========================# + +# Note: You should map your credentials with custom variables according to your Azure OpenAI Configuration +# The models for Azure Assistants are also determined by your Azure OpenAI configuration. + +# More info, including how to enable use of Assistants with Azure here: +# https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints/azure#using-assistants-with-azure + +CREDS_KEY=f34be427ebb29de8d88c107a71546019685ed8b241d8f2ed00c3df97ad2566f0 +CREDS_IV=e2341419ec3dd3d19b13a1a87fafcbfb + +# Azure AI Search +#----------------- +AZURE_AI_SEARCH_SERVICE_ENDPOINT= +AZURE_AI_SEARCH_INDEX_NAME= +AZURE_AI_SEARCH_API_KEY= + +AZURE_AI_SEARCH_API_VERSION= +AZURE_AI_SEARCH_SEARCH_OPTION_QUERY_TYPE= +AZURE_AI_SEARCH_SEARCH_OPTION_TOP= +AZURE_AI_SEARCH_SEARCH_OPTION_SELECT= + +# OpenAI Image Tools Customization +#---------------- +# IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool +# IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool +# IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments +# IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5) +# IMAGE_GEN_OAI_DESCRIPTION= +# IMAGE_GEN_OAI_DESCRIPTION_WITH_FILES=Custom description for image generation tool when files are present +# IMAGE_GEN_OAI_DESCRIPTION_NO_FILES=Custom description for image generation tool when no files are present +# IMAGE_EDIT_OAI_DESCRIPTION=Custom description for image editing tool +# IMAGE_GEN_OAI_PROMPT_DESCRIPTION=Custom prompt description for image generation tool +# IMAGE_EDIT_OAI_PROMPT_DESCRIPTION=Custom prompt description for image editing tool + +# DALL·E +#---------------- +# DALLE_API_KEY= +# DALLE3_API_KEY= +# DALLE2_API_KEY= +# DALLE3_SYSTEM_PROMPT= +# DALLE2_SYSTEM_PROMPT= +# DALLE_REVERSE_PROXY= +# DALLE3_BASEURL= +# DALLE2_BASEURL= + +# DALL·E (via Azure OpenAI) +# Note: requires some of the variables above to be set +#---------------- +# DALLE3_AZURE_API_VERSION= +# DALLE2_AZURE_API_VERSION= + +# Flux +#----------------- +FLUX_API_BASE_URL=https://api.us1.bfl.ai +# FLUX_API_BASE_URL = 'https://api.bfl.ml'; + +# Get your API key at https://api.us1.bfl.ai/auth/profile +# FLUX_API_KEY= + +# Google +#----------------- +GOOGLE_SEARCH_API_KEY= +GOOGLE_CSE_ID= + +# Stable Diffusion +#----------------- +SD_WEBUI_URL=http://host.docker.internal:7860 + +# Tavily +#----------------- +TAVILY_API_KEY= + +# Traversaal +#----------------- +TRAVERSAAL_API_KEY= + +# WolframAlpha +#----------------- +WOLFRAM_APP_ID= + +# Zapier +#----------------- +ZAPIER_NLA_API_KEY= + +#==================================================# +# Search # +#==================================================# + +SEARCH=true +MEILI_NO_ANALYTICS=true +MEILI_HOST=http://0.0.0.0:7700 +MEILI_MASTER_KEY=DrhYf7zENyR6AlUCKmnz0eYASOQdl6zxH7s7MKFSfFCt + +# Optional: Disable indexing, useful in a multi-node setup +# where only one instance should perform an index sync. +# MEILI_NO_SYNC=true + +#==================================================# +# Speech to Text & Text to Speech # +#==================================================# + +STT_API_KEY= +TTS_API_KEY= + +#==================================================# +# RAG # +#==================================================# +# More info: https://www.librechat.ai/docs/configuration/rag_api + +# RAG_OPENAI_BASEURL= +# RAG_OPENAI_API_KEY= +# RAG_USE_FULL_CONTEXT= +# EMBEDDINGS_PROVIDER=openai +# EMBEDDINGS_MODEL=text-embedding-3-small + +#===================================================# +# User System # +#===================================================# + +#========================# +# Moderation # +#========================# + +OPENAI_MODERATION=false +OPENAI_MODERATION_API_KEY= +# OPENAI_MODERATION_REVERSE_PROXY= + +BAN_VIOLATIONS=true +BAN_DURATION=1000 * 60 * 60 * 2 +BAN_INTERVAL=20 + +LOGIN_VIOLATION_SCORE=1 +REGISTRATION_VIOLATION_SCORE=1 +CONCURRENT_VIOLATION_SCORE=1 +MESSAGE_VIOLATION_SCORE=1 +NON_BROWSER_VIOLATION_SCORE=20 +TTS_VIOLATION_SCORE=0 +STT_VIOLATION_SCORE=0 +FORK_VIOLATION_SCORE=0 +IMPORT_VIOLATION_SCORE=0 +FILE_UPLOAD_VIOLATION_SCORE=0 + +LOGIN_MAX=7 +LOGIN_WINDOW=5 +REGISTER_MAX=5 +REGISTER_WINDOW=60 + +LIMIT_CONCURRENT_MESSAGES=true +CONCURRENT_MESSAGE_MAX=2 + +LIMIT_MESSAGE_IP=true +MESSAGE_IP_MAX=40 +MESSAGE_IP_WINDOW=1 + +LIMIT_MESSAGE_USER=false +MESSAGE_USER_MAX=40 +MESSAGE_USER_WINDOW=1 + +ILLEGAL_MODEL_REQ_SCORE=5 + +#========================# +# Balance # +#========================# + +# CHECK_BALANCE=false +# START_BALANCE=20000 # note: the number of tokens that will be credited after registration. + +#========================# +# Registration and Login # +#========================# + +ALLOW_EMAIL_LOGIN=true +ALLOW_REGISTRATION=true +ALLOW_SOCIAL_LOGIN=false +ALLOW_SOCIAL_REGISTRATION=false +ALLOW_PASSWORD_RESET=false +# ALLOW_ACCOUNT_DELETION=true # note: enabled by default if omitted/commented out +ALLOW_UNVERIFIED_EMAIL_LOGIN=true + +SESSION_EXPIRY=1000 * 60 * 15 +REFRESH_TOKEN_EXPIRY=(1000 * 60 * 60 * 24) * 7 + +JWT_SECRET=16f8c0ef4a5d391b26034086c628469d3f9f497f08163ab9b40137092f2909ef +JWT_REFRESH_SECRET=eaa5191f2914e30b9387fd84e254e4ba6fc51b4654968a9b0803b456a54b8418 + +# Discord +DISCORD_CLIENT_ID= +DISCORD_CLIENT_SECRET= +DISCORD_CALLBACK_URL=/oauth/discord/callback + +# Facebook +FACEBOOK_CLIENT_ID= +FACEBOOK_CLIENT_SECRET= +FACEBOOK_CALLBACK_URL=/oauth/facebook/callback + +# GitHub +GITHUB_CLIENT_ID= +GITHUB_CLIENT_SECRET= +GITHUB_CALLBACK_URL=/oauth/github/callback +# GitHub Enterprise +# GITHUB_ENTERPRISE_BASE_URL= +# GITHUB_ENTERPRISE_USER_AGENT= + +# Google +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +GOOGLE_CALLBACK_URL=/oauth/google/callback + +# Apple +APPLE_CLIENT_ID= +APPLE_TEAM_ID= +APPLE_KEY_ID= +APPLE_PRIVATE_KEY_PATH= +APPLE_CALLBACK_URL=/oauth/apple/callback + +# OpenID +OPENID_CLIENT_ID= +OPENID_CLIENT_SECRET= +OPENID_ISSUER= +OPENID_SESSION_SECRET= +OPENID_SCOPE="openid profile email" +OPENID_CALLBACK_URL=/oauth/openid/callback +OPENID_REQUIRED_ROLE= +OPENID_REQUIRED_ROLE_TOKEN_KIND= +OPENID_REQUIRED_ROLE_PARAMETER_PATH= +OPENID_ADMIN_ROLE= +OPENID_ADMIN_ROLE_PARAMETER_PATH= +OPENID_ADMIN_ROLE_TOKEN_KIND= +# Set to determine which user info property returned from OpenID Provider to store as the User's username +OPENID_USERNAME_CLAIM= +# Set to determine which user info property returned from OpenID Provider to store as the User's name +OPENID_NAME_CLAIM= +# Set to determine which user info claim to use as the email/identifier for user matching (e.g., "upn" for Entra ID) +# When not set, defaults to: email -> preferred_username -> upn +OPENID_EMAIL_CLAIM= +# Optional audience parameter for OpenID authorization requests +OPENID_AUDIENCE= + +OPENID_BUTTON_LABEL= +OPENID_IMAGE_URL= +# Set to true to automatically redirect to the OpenID provider when a user visits the login page +# This will bypass the login form completely for users, only use this if OpenID is your only authentication method +OPENID_AUTO_REDIRECT=false +# Set to true to use PKCE (Proof Key for Code Exchange) for OpenID authentication +OPENID_USE_PKCE=false +#Set to true to reuse openid tokens for authentication management instead of using the mongodb session and the custom refresh token. +OPENID_REUSE_TOKENS= +#By default, signing key verification results are cached in order to prevent excessive HTTP requests to the JWKS endpoint. +#If a signing key matching the kid is found, this will be cached and the next time this kid is requested the signing key will be served from the cache. +#Default is true. +OPENID_JWKS_URL_CACHE_ENABLED= +OPENID_JWKS_URL_CACHE_TIME= # 600000 ms eq to 10 minutes leave empty to disable caching +#Set to true to trigger token exchange flow to acquire access token for the userinfo endpoint. +OPENID_ON_BEHALF_FLOW_FOR_USERINFO_REQUIRED= +OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE="user.read" # example for Scope Needed for Microsoft Graph API +# Set to true to use the OpenID Connect end session endpoint for logout +OPENID_USE_END_SESSION_ENDPOINT= +# URL to redirect to after OpenID logout (defaults to ${DOMAIN_CLIENT}/login) +OPENID_POST_LOGOUT_REDIRECT_URI= +# Maximum logout URL length before using logout_hint instead of id_token_hint (default: 2000) +OPENID_MAX_LOGOUT_URL_LENGTH= + +#========================# +# SharePoint Integration # +#========================# +# Requires Entra ID (OpenID) authentication to be configured + +# Enable SharePoint file picker in chat and agent panels +# ENABLE_SHAREPOINT_FILEPICKER=true + +# SharePoint tenant base URL (e.g., https://yourtenant.sharepoint.com) +# SHAREPOINT_BASE_URL=https://yourtenant.sharepoint.com + +# Microsoft Graph API And SharePoint scopes for file picker +# SHAREPOINT_PICKER_SHAREPOINT_SCOPE==https://yourtenant.sharepoint.com/AllSites.Read +# SHAREPOINT_PICKER_GRAPH_SCOPE=Files.Read.All +#========================# + +# SAML +# Note: If OpenID is enabled, SAML authentication will be automatically disabled. +SAML_ENTRY_POINT= +SAML_ISSUER= +SAML_CERT= +SAML_CALLBACK_URL=/oauth/saml/callback +SAML_SESSION_SECRET= + +# Attribute mappings (optional) +SAML_EMAIL_CLAIM= +SAML_USERNAME_CLAIM= +SAML_GIVEN_NAME_CLAIM= +SAML_FAMILY_NAME_CLAIM= +SAML_PICTURE_CLAIM= +SAML_NAME_CLAIM= + +# Logint buttion settings (optional) +SAML_BUTTON_LABEL= +SAML_IMAGE_URL= + +# Whether the SAML Response should be signed. +# - If "true", the entire `SAML Response` will be signed. +# - If "false" or unset, only the `SAML Assertion` will be signed (default behavior). +# SAML_USE_AUTHN_RESPONSE_SIGNED= + + +#===============================================# +# Microsoft Graph API / Entra ID Integration # +#===============================================# + +# Enable Entra ID people search integration in permissions/sharing system +# When enabled, the people picker will search both local database and Entra ID +USE_ENTRA_ID_FOR_PEOPLE_SEARCH=false + +# When enabled, entra id groups owners will be considered as members of the group +ENTRA_ID_INCLUDE_OWNERS_AS_MEMBERS=false + +# Microsoft Graph API scopes needed for people/group search +# Default scopes provide access to user profiles and group memberships +OPENID_GRAPH_SCOPES=User.Read,People.Read,GroupMember.Read.All + +# LDAP +LDAP_URL= +LDAP_BIND_DN= +LDAP_BIND_CREDENTIALS= +LDAP_USER_SEARCH_BASE= +#LDAP_SEARCH_FILTER="mail=" +LDAP_CA_CERT_PATH= +# LDAP_TLS_REJECT_UNAUTHORIZED= +# LDAP_STARTTLS= +# LDAP_LOGIN_USES_USERNAME=true +# LDAP_ID= +# LDAP_USERNAME= +# LDAP_EMAIL= +# LDAP_FULL_NAME= + +#========================# +# Email Password Reset # +#========================# + +EMAIL_SERVICE= +EMAIL_HOST= +EMAIL_PORT=25 +EMAIL_ENCRYPTION= +EMAIL_ENCRYPTION_HOSTNAME= +EMAIL_ALLOW_SELFSIGNED= +# Leave both empty for SMTP servers that do not require authentication +EMAIL_USERNAME= +EMAIL_PASSWORD= +EMAIL_FROM_NAME= +EMAIL_FROM=noreply@librechat.ai + +#========================# +# Mailgun API # +#========================# + +# MAILGUN_API_KEY=your-mailgun-api-key +# MAILGUN_DOMAIN=mg.yourdomain.com +# EMAIL_FROM=noreply@yourdomain.com +# EMAIL_FROM_NAME="LibreChat" + +# # Optional: For EU region +# MAILGUN_HOST=https://api.eu.mailgun.net + +#========================# +# Firebase CDN # +#========================# + +FIREBASE_API_KEY= +FIREBASE_AUTH_DOMAIN= +FIREBASE_PROJECT_ID= +FIREBASE_STORAGE_BUCKET= +FIREBASE_MESSAGING_SENDER_ID= +FIREBASE_APP_ID= + +#========================# +# S3 AWS Bucket # +#========================# + +AWS_ENDPOINT_URL= +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_REGION= +AWS_BUCKET_NAME= +# Required for path-style S3-compatible providers (MinIO, Hetzner, Backblaze B2, etc.) +# that don't support virtual-hosted-style URLs (bucket.endpoint). Not needed for AWS S3. +# AWS_FORCE_PATH_STYLE=false + +#========================# +# Azure Blob Storage # +#========================# + +AZURE_STORAGE_CONNECTION_STRING= +AZURE_STORAGE_PUBLIC_ACCESS=false +AZURE_CONTAINER_NAME=files + +#========================# +# Shared Links # +#========================# + +ALLOW_SHARED_LINKS=true +# Allows unauthenticated access to shared links. Defaults to false (auth required) if not set. +ALLOW_SHARED_LINKS_PUBLIC=false + +#==============================# +# Static File Cache Control # +#==============================# + +# Leave commented out to use defaults: 1 day (86400 seconds) for s-maxage and 2 days (172800 seconds) for max-age +# NODE_ENV must be set to production for these to take effect +# STATIC_CACHE_MAX_AGE=172800 +# STATIC_CACHE_S_MAX_AGE=86400 + +# If you have another service in front of your LibreChat doing compression, disable express based compression here +# DISABLE_COMPRESSION=true + +# If you have gzipped version of uploaded image images in the same folder, this will enable gzip scan and serving of these images +# Note: The images folder will be scanned on startup and a ma kept in memory. Be careful for large number of images. +# ENABLE_IMAGE_OUTPUT_GZIP_SCAN=true + +#===================================================# +# UI # +#===================================================# + +APP_TITLE=LibreChat +# CUSTOM_FOOTER="My custom footer" +HELP_AND_FAQ_URL=https://librechat.ai + +# SHOW_BIRTHDAY_ICON=true + +# Google tag manager id +#ANALYTICS_GTM_ID=user provided google tag manager id + +# limit conversation file imports to a certain number of bytes in size to avoid the container +# maxing out memory limitations by unremarking this line and supplying a file size in bytes +# such as the below example of 250 mib +# CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES=262144000 + + +#===============# +# REDIS Options # +#===============# + +# Enable Redis for caching and session storage +# USE_REDIS=true +# Enable Redis for resumable LLM streams (defaults to USE_REDIS value if not set) +# Set to false to use in-memory storage for streams while keeping Redis for other caches +# USE_REDIS_STREAMS=true + +# Single Redis instance +# REDIS_URI=redis://127.0.0.1:6379 + +# Redis cluster (multiple nodes) +# REDIS_URI=redis://127.0.0.1:7001,redis://127.0.0.1:7002,redis://127.0.0.1:7003 + +# Redis with TLS/SSL encryption and CA certificate +# REDIS_URI=rediss://127.0.0.1:6380 +# REDIS_CA=/path/to/ca-cert.pem + +# Elasticache may need to use an alternate dnsLookup for TLS connections. see "Special Note: Aws Elasticache Clusters with TLS" on this webpage: https://www.npmjs.com/package/ioredis +# Enable alternative dnsLookup for redis +# REDIS_USE_ALTERNATIVE_DNS_LOOKUP=true + +# Redis authentication (if required) +# REDIS_USERNAME=your_redis_username +# REDIS_PASSWORD=your_redis_password + +# Redis key prefix configuration +# Use environment variable name for dynamic prefix (recommended for cloud deployments) +# REDIS_KEY_PREFIX_VAR=K_REVISION +# Or use static prefix directly +# REDIS_KEY_PREFIX=librechat + +# Redis connection limits +# REDIS_MAX_LISTENERS=40 + +# Redis ping interval in seconds (0 = disabled, >0 = enabled) +# When set to a positive integer, Redis clients will ping the server at this interval to keep connections alive +# When unset or 0, no pinging is performed (recommended for most use cases) +# REDIS_PING_INTERVAL=300 + +# Force specific cache namespaces to use in-memory storage even when Redis is enabled +# Comma-separated list of CacheKeys +# Defaults to CONFIG_STORE,APP_CONFIG so YAML-derived config stays per-container (safe for blue/green deployments) +# Set to empty string to force all namespaces through Redis: FORCED_IN_MEMORY_CACHE_NAMESPACES= +# FORCED_IN_MEMORY_CACHE_NAMESPACES=CONFIG_STORE,APP_CONFIG + +# Leader Election Configuration (for multi-instance deployments with Redis) +# Duration in seconds that the leader lease is valid before it expires (default: 25) +# LEADER_LEASE_DURATION=25 +# Interval in seconds at which the leader renews its lease (default: 10) +# LEADER_RENEW_INTERVAL=10 +# Maximum number of retry attempts when renewing the lease fails (default: 3) +# LEADER_RENEW_ATTEMPTS=3 +# Delay in seconds between retry attempts when renewing the lease (default: 0.5) +# LEADER_RENEW_RETRY_DELAY=0.5 + +#==================================================# +# Others # +#==================================================# +# You should leave the following commented out # + +# NODE_ENV= + +# E2E_USER_EMAIL= +# E2E_USER_PASSWORD= + +#=====================================================# +# Cache Headers # +#=====================================================# +# Headers that control caching of the index.html # +# Default configuration prevents caching to ensure # +# users always get the latest version. Customize # +# only if you understand caching implications. # + +# INDEX_CACHE_CONTROL=no-cache, no-store, must-revalidate +# INDEX_PRAGMA=no-cache +# INDEX_EXPIRES=0 + +# no-cache: Forces validation with server before using cached version +# no-store: Prevents storing the response entirely +# must-revalidate: Prevents using stale content when offline + +#=====================================================# +# OpenWeather # +#=====================================================# +OPENWEATHER_API_KEY= + +#====================================# +# LibreChat Code Interpreter API # +#====================================# + +# https://code.librechat.ai +# LIBRECHAT_CODE_API_KEY=your-key + +#======================# +# Web Search # +#======================# + +# Note: All of the following variable names can be customized. +# Omit values to allow user to provide them. + +# For more information on configuration values, see: +# https://librechat.ai/docs/features/web_search + +# Search Provider (Required) +# SERPER_API_KEY=your_serper_api_key + +# Scraper (Required) +# FIRECRAWL_API_KEY=your_firecrawl_api_key +# Optional: Custom Firecrawl API URL +# FIRECRAWL_API_URL=your_firecrawl_api_url + +# Reranker (Required) +# JINA_API_KEY=your_jina_api_key +# or +# COHERE_API_KEY=your_cohere_api_key + +#======================# +# MCP Configuration # +#======================# + +# Treat 401/403 responses as OAuth requirement when no oauth metadata found +# MCP_OAUTH_ON_AUTH_ERROR=true + +# Timeout for OAuth detection requests in milliseconds +# MCP_OAUTH_DETECTION_TIMEOUT=5000 + +# Cache connection status checks for this many milliseconds to avoid expensive verification +# MCP_CONNECTION_CHECK_TTL=60000 + +# Skip code challenge method validation (e.g., for AWS Cognito that supports S256 but doesn't advertise it) +# When set to true, forces S256 code challenge even if not advertised in .well-known/openid-configuration +# MCP_SKIP_CODE_CHALLENGE_CHECK=false + +# Circuit breaker: max connect/disconnect cycles before tripping (per server) +# MCP_CB_MAX_CYCLES=7 + +# Circuit breaker: sliding window (ms) for counting cycles +# MCP_CB_CYCLE_WINDOW_MS=45000 + +# Circuit breaker: cooldown (ms) after the cycle breaker trips +# MCP_CB_CYCLE_COOLDOWN_MS=15000 + +# Circuit breaker: max consecutive failed connection rounds before backoff +# MCP_CB_MAX_FAILED_ROUNDS=3 + +# Circuit breaker: sliding window (ms) for counting failed rounds +# MCP_CB_FAILED_WINDOW_MS=120000 + +# Circuit breaker: base backoff (ms) after failed round threshold is reached +# MCP_CB_BASE_BACKOFF_MS=30000 + +# Circuit breaker: max backoff cap (ms) for exponential backoff +# MCP_CB_MAX_BACKOFF_MS=300000 diff --git a/.env.make b/.env.make new file mode 100644 index 0000000..373d53a --- /dev/null +++ b/.env.make @@ -0,0 +1,9 @@ +# Auto-generated from pyproject.toml — do not edit manually +export ALFRED_VERSION=0.1.7 +export PYTHON_VERSION=3.14.3 +export PYTHON_VERSION_SHORT=3.14 +export IMAGE_NAME=alfred_media_organizer +export SERVICE_NAME=alfred +export LIBRECHAT_VERSION=v0.8.4 +export RAG_VERSION=v0.7.3 +export UV_VERSION=0.11.6 diff --git a/Dockerfile b/Dockerfile index 27ae013..aace701 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,14 +3,15 @@ ARG PYTHON_VERSION ARG PYTHON_VERSION_SHORT -ARG RUNNER +ARG UV_VERSION + # =========================================== # Stage 1: Builder # =========================================== FROM python:${PYTHON_VERSION}-slim-bookworm AS builder # Re-declare ARGs after FROM to make them available in this stage -ARG RUNNER +ARG UV_VERSION # STFU - No need - Write logs asap ENV DEBIAN_FRONTEND=noninteractive \ @@ -18,30 +19,21 @@ ENV DEBIAN_FRONTEND=noninteractive \ PYTHONUNBUFFERED=1 # Install build dependencies (needs root) -RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential \ +RUN apt-get update \ + && apt-get install -y --no-install-recommends build-essential \ && rm -rf /var/lib/apt/lists/* -# Install runner globally (needs root) - Save cache for future -RUN --mount=type=cache,target=/root/.cache/pip \ - pip install $RUNNER +# Install uv globally (needs root) - Save cache for future +COPY --from=ghcr.io/astral-sh/uv:${UV_VERSION} /uv /usr/local/bin/uv # Set working directory for dependency installation WORKDIR /tmp # Copy dependency files -COPY pyproject.toml poetry.lock* uv.lock* Makefile ./ +COPY pyproject.toml uv.lock Makefile ./ # Install dependencies as root (to avoid permission issues with system packages) -RUN --mount=type=cache,target=/root/.cache/pip \ - --mount=type=cache,target=/root/.cache/pypoetry \ - --mount=type=cache,target=/root/.cache/uv \ - if [ "$RUNNER" = "poetry" ]; then \ - poetry config virtualenvs.create false && \ - poetry install --only main --no-root; \ - elif [ "$RUNNER" = "uv" ]; then \ - uv pip install --system -r pyproject.toml; \ - fi +RUN --mount=type=cache,target=/root/.cache/uv uv sync --system COPY scripts/ ./scripts/ COPY .env.example ./ @@ -51,16 +43,7 @@ COPY .env.example ./ # =========================================== FROM builder AS test -ARG RUNNER - -RUN --mount=type=cache,target=/root/.cache/pip \ - --mount=type=cache,target=/root/.cache/pypoetry \ - --mount=type=cache,target=/root/.cache/uv \ - if [ "$RUNNER" = "poetry" ]; then \ - poetry install --no-root; \ - elif [ "$RUNNER" = "uv" ]; then \ - uv pip install --system -e .[dev]; \ - fi +RUN --mount=type=cache,target=/root/.cache/uv uv sync --system -e .[dev] COPY alfred/ ./alfred COPY scripts ./scripts diff --git a/Makefile b/Makefile index d28a8a2..27e7df4 100644 --- a/Makefile +++ b/Makefile @@ -13,23 +13,23 @@ DOCKER_COMPOSE := docker compose DOCKER_BUILD := docker build --no-cache \ --build-arg PYTHON_VERSION=$(PYTHON_VERSION) \ --build-arg PYTHON_VERSION_SHORT=$(PYTHON_VERSION_SHORT) \ - --build-arg RUNNER=$(RUNNER) + --build-arg UV_VERSION=$(UV_VERSION) # --- Phony --- -.PHONY: .env bootstrap up down restart logs ps shell build build-test install \ +.PHONY: bootstrap up down restart logs ps shell build build-test install \ update install-hooks test coverage lint format clean major minor patch help # --- Setup --- -.env .env.make: +.env.alfred .env.librechat .env.secrets .env.make: @echo "Initializing environment..." - @python scripts/bootstrap.py \ + @uv run python scripts/bootstrap.py \ && echo "✓ Environment ready" \ || (echo "✗ Environment setup failed" && exit 1) -bootstrap: .env .env.make +bootstrap: .env.alfred .env.librechat .env.secrets .env.make # --- Docker --- -up: .env +up: .env.alfred .env.secrets @echo "Starting containers with profiles: [full]..." @$(PROFILES_PARAM) $(DOCKER_COMPOSE) up -d --remove-orphans \ && echo "✓ Containers started" \ @@ -75,44 +75,44 @@ build-test: .env.make # --- Dependencies --- install: @echo "Installing dependencies with $(RUNNER)..." - @$(RUNNER) install \ + @uv install \ && echo "✓ Dependencies installed" \ || (echo "✗ Installation failed" && exit 1) install-hooks: @echo "Installing pre-commit hooks..." - @$(RUNNER) run pre-commit install \ + @uv run pre-commit install \ && echo "✓ Hooks installed" \ || (echo "✗ Hook installation failed" && exit 1) update: @echo "Updating dependencies with $(RUNNER)..." - @$(RUNNER) update \ + @uv update \ && echo "✓ Dependencies updated" \ || (echo "✗ Update failed" && exit 1) # --- Quality --- test: @echo "Running tests..." - @$(RUNNER) run pytest \ + @uv run pytest \ && echo "✓ Tests passed" \ || (echo "✗ Tests failed" && exit 1) coverage: @echo "Running tests with coverage..." - @$(RUNNER) run pytest --cov=. --cov-report=html --cov-report=term \ + @uv run pytest --cov=. --cov-report=html --cov-report=term \ && echo "✓ Coverage report generated" \ || (echo "✗ Coverage failed" && exit 1) lint: @echo "Linting code..." - @$(RUNNER) run ruff check --fix . \ + @uv run ruff check --fix . \ && echo "✓ Linting complete" \ || (echo "✗ Linting failed" && exit 1) format: @echo "Formatting code..." - @$(RUNNER) run ruff format . && $(RUNNER) run ruff check --fix . \ + @uv run ruff format . && $(RUNNER) run ruff check --fix . \ && echo "✓ Code formatted" \ || (echo "✗ Formatting failed" && exit 1) @@ -125,7 +125,7 @@ clean: # --- Versioning --- major minor patch: _check-main @echo "Bumping $@ version..." - @$(RUNNER) run bump-my-version bump $@ \ + @uv run bump-my-version bump $@ \ && echo "✓ Version bumped" \ || (echo "✗ Version bump failed" && exit 1) @@ -161,6 +161,9 @@ help: @echo "" @echo "Usage: make [target] [p=profile1,profile2]" @echo "" + @echo "Setup:" + @echo " bootstrap Generate .env.alfred, .env.librechat, .env.secrets and .env.make" + @echo "" @echo "Docker:" @echo " up Start containers (default profile: core)" @echo " Example: make up p=rag,meili" diff --git a/alfred/settings.py b/alfred/settings.py index 50ef520..da4b2b3 100644 --- a/alfred/settings.py +++ b/alfred/settings.py @@ -1,112 +1,46 @@ -import secrets -from pathlib import Path -from typing import NamedTuple +""" +Application settings — Alfred only. + +Loaded from .env.alfred and .env.secrets (via docker-compose env_file). +At runtime, all variables are already in the environment — pydantic-settings +picks them up automatically. +""" + +from pathlib import Path -import tomllib from pydantic import Field, computed_field, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict BASE_DIR = Path(__file__).resolve().parent.parent -ENV_FILE_PATH = BASE_DIR / ".env" -toml_path = BASE_DIR / "pyproject.toml" class ConfigurationError(Exception): """Raised when configuration is invalid.""" - pass - - -class ProjectVersions(NamedTuple): - """ - Immutable structure for project versions. - Forces explicit naming and prevents accidental swaps. - """ - - librechat: str - rag: str - alfred: str - - -def get_versions_from_toml() -> ProjectVersions: - """ - Reads versioning information from pyproject.toml. - Returns the default value if the file or key is missing. - """ - - if not toml_path.exists(): - raise FileNotFoundError(f"pyproject.toml not found: {toml_path}") - - with open(toml_path, "rb") as f: - data = tomllib.load(f) - try: - return ProjectVersions( - librechat=data["tool"]["alfred"]["settings"]["librechat_version"], - rag=data["tool"]["alfred"]["settings"]["rag_version"], - alfred=data["tool"]["poetry"]["version"], - ) - except KeyError as e: - raise KeyError(f"Error: Missing key {e} in pyproject.toml") from e - - -# Load versions once -VERSIONS: ProjectVersions = get_versions_from_toml() - class Settings(BaseSettings): model_config = SettingsConfigDict( - env_file=ENV_FILE_PATH, + env_file=[BASE_DIR / ".env.alfred", BASE_DIR / ".env.secrets"], env_file_encoding="utf-8", extra="ignore", case_sensitive=False, ) - # --- GENERAL SETTINGS --- + + # --- APP --- host: str = "0.0.0.0" port: int = 3080 - debug_logging: bool = False - debug_console: bool = False - data_storage: str = "data" - librechat_version: str = Field(VERSIONS.librechat, description="Librechat version") - rag_version: str = Field(VERSIONS.rag, description="RAG engine version") - alfred_version: str = Field(VERSIONS.alfred, description="Alfred version") - - # --- CONTEXT SETTINGS --- max_history_messages: int = 10 max_tool_iterations: int = 10 request_timeout: int = 30 + llm_temperature: float = 0.2 + data_storage_dir: str = "data" - # TODO: Finish - deepseek_base_url: str = "https://api.deepseek.com" - deepseek_model: str = "deepseek-chat" - - # --- API KEYS --- - anthropic_api_key: str | None = Field(None, description="Claude API key") - deepseek_api_key: str | None = Field(None, description="Deepseek API key") - google_api_key: str | None = Field(None, description="Gemini API key") - kimi_api_key: str | None = Field(None, description="Kimi API key") - openai_api_key: str | None = Field(None, description="ChatGPT API key") - - # --- SECURITY KEYS --- - # Generated automatically if not in .env to ensure "Secure by Default" - jwt_secret: str = Field(default_factory=lambda: secrets.token_urlsafe(32)) - jwt_refresh_secret: str = Field(default_factory=lambda: secrets.token_urlsafe(32)) - - # We keep these for encryption of keys in MongoDB (AES-256 Hex format) - creds_key: str = Field(default_factory=lambda: secrets.token_hex(32)) - creds_iv: str = Field(default_factory=lambda: secrets.token_hex(16)) - - # --- SERVICES --- - qbittorrent_url: str = "http://qbittorrent:16140" - qbittorrent_username: str = "admin" - qbittorrent_password: str = Field(default_factory=lambda: secrets.token_urlsafe(16)) - + # --- DATABASE --- mongo_host: str = "mongodb" - mongo_user: str = "alfred" - mongo_password: str = Field( - default_factory=lambda: secrets.token_urlsafe(24), repr=False, exclude=True - ) mongo_port: int = 27017 - mongo_db_name: str = "alfred" + mongo_user: str = "alfred" + mongo_password: str = Field(repr=False) + mongo_db_name: str = "LibreChat" @computed_field(repr=False) @property @@ -118,11 +52,9 @@ class Settings(BaseSettings): ) postgres_host: str = "vectordb" - postgres_user: str = "alfred" - postgres_password: str = Field( - default_factory=lambda: secrets.token_urlsafe(24), repr=False, exclude=True - ) postgres_port: int = 5432 + postgres_user: str = "alfred" + postgres_password: str = Field(repr=False) postgres_db_name: str = "alfred" @computed_field(repr=False) @@ -133,77 +65,69 @@ class Settings(BaseSettings): f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db_name}" ) - tmdb_api_key: str | None = Field(None, description="The Movie Database API key") - tmdb_base_url: str = "https://api.themoviedb.org/3" - - # --- LLM PICKER & CONFIG --- - # Providers: 'local', 'deepseek', ... + # --- LLM --- default_llm_provider: str = "local" ollama_base_url: str = "http://ollama:11434" # Models: ... ollama_model: str = "llama3.3:latest" - llm_temperature: float = 0.2 + deepseek_base_url: str = "https://api.deepseek.com" + deepseek_model: str = "deepseek-chat" - # --- RAG ENGINE --- - rag_enabled: bool = True # TODO: Handle False + # --- API KEYS --- + tmdb_api_key: str | None = None + deepseek_api_key: str | None = None + openai_api_key: str | None = None + anthropic_api_key: str | None = None + google_api_key: str | None = None + kimi_api_key: str | None = None + + # --- EXTERNAL SERVICES --- + tmdb_base_url: str = "https://api.themoviedb.org/3" + qbittorrent_url: str = "http://qbittorrent:16140" + qbittorrent_username: str = "admin" + qbittorrent_password: str = Field(repr=False) + + # --- RAG --- + rag_enabled: bool = True rag_api_url: str = "http://rag_api:8000" embeddings_provider: str = "ollama" # Models: ... embeddings_model: str = "nomic-embed-text" # --- MEILISEARCH --- - meili_enabled: bool = Field(True, description="Enable meili") + meili_enabled: bool = False meili_no_analytics: bool = True meili_host: str = "http://meilisearch:7700" - meili_master_key: str = Field( - default_factory=lambda: secrets.token_urlsafe(32), - description="Master key for Meilisearch", - repr=False, - ) + meili_master_key: str = Field(repr=False) # --- VALIDATORS --- @field_validator("llm_temperature") @classmethod def validate_temperature(cls, v: float) -> float: if not 0.0 <= v <= 2.0: - raise ConfigurationError( - f"Temperature must be between 0.0 and 2.0, got {v}" - ) + raise ConfigurationError(f"Temperature must be between 0.0 and 2.0, got {v}") return v @field_validator("max_tool_iterations") @classmethod def validate_max_iterations(cls, v: int) -> int: if not 1 <= v <= 20: - raise ConfigurationError( - f"max_tool_iterations must be between 1 and 50, got {v}" - ) + raise ConfigurationError(f"max_tool_iterations must be between 1 and 20, got {v}") return v @field_validator("request_timeout") @classmethod def validate_timeout(cls, v: int) -> int: if not 1 <= v <= 300: - raise ConfigurationError( - f"request_timeout must be between 1 and 300 seconds, got {v}" - ) + raise ConfigurationError(f"request_timeout must be between 1 and 300 seconds, got {v}") return v - @field_validator("deepseek_base_url", "tmdb_base_url") - @classmethod - def validate_url(cls, v: str, info) -> str: - if not v.startswith(("http://", "https://")): - raise ConfigurationError(f"Invalid {info.field_name}") - return v - - def is_tmdb_configured(self): + # --- HELPERS --- + def is_tmdb_configured(self) -> bool: return bool(self.tmdb_api_key) - def is_deepseek_configured(self): + def is_deepseek_configured(self) -> bool: return bool(self.deepseek_api_key) - def dump_safe(self): - return self.model_dump(exclude_none=False) - settings = Settings() diff --git a/docker-compose.yaml b/docker-compose.yaml index 656be7b..5612d9a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -9,7 +9,7 @@ services: args: PYTHON_VERSION: ${PYTHON_VERSION} PYTHON_VERSION_SHORT: ${PYTHON_VERSION_SHORT} - RUNNER: ${RUNNER} + UV_VERSION: ${UV_VERSION} command: python scripts/bootstrap.py networks: - alfred-net @@ -23,13 +23,15 @@ services: args: PYTHON_VERSION: ${PYTHON_VERSION} PYTHON_VERSION_SHORT: ${PYTHON_VERSION_SHORT} - RUNNER: ${RUNNER} + UV_VERSION: ${UV_VERSION} depends_on: alfred-init: condition: service_completed_successfully restart: unless-stopped env_file: - - path: .env + - path: .env.alfred + required: true + - path: .env.secrets required: true volumes: - ./data:/data @@ -52,7 +54,11 @@ services: condition: service_healthy restart: unless-stopped env_file: - - path: .env + - path: .env.librechat + required: true + - path: .env.alfred + required: true + - path: .env.secrets required: true environment: # Remap value name @@ -78,7 +84,9 @@ services: alfred-init: condition: service_completed_successfully env_file: - - path: .env + - path: .env.alfred + required: true + - path: .env.secrets required: true environment: # Remap value name @@ -107,7 +115,9 @@ services: condition: service_completed_successfully restart: unless-stopped env_file: - - path: .env + - path: .env.alfred + required: true + - path: .env.secrets required: true volumes: - ./data/ollama:/root/.ollama @@ -124,7 +134,9 @@ services: condition: service_completed_successfully restart: unless-stopped env_file: - - path: .env + - path: .env.alfred + required: true + - path: .env.secrets required: true volumes: - ./data/meilisearch:/meili_data @@ -143,7 +155,9 @@ services: condition: service_healthy restart: unless-stopped env_file: - - path: .env + - path: .env.alfred + required: true + - path: .env.secrets required: true ports: - "${RAG_API_PORT}:${RAG_API_PORT}" @@ -162,7 +176,9 @@ services: condition: service_completed_successfully restart: unless-stopped env_file: - - path: .env + - path: .env.alfred + required: true + - path: .env.secrets required: true ports: - "${POSTGRES_PORT}:${POSTGRES_PORT}" @@ -170,7 +186,7 @@ services: - ./data/vectordb:/var/lib/postgresql/data profiles: ["rag", "full"] healthcheck: - test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB_NAME}" ] + test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER:-alfred} -d $${POSTGRES_DB_NAME:-alfred}" ] interval: 5s timeout: 5s retries: 5 @@ -188,7 +204,9 @@ services: condition: service_completed_successfully restart: unless-stopped env_file: - - path: .env + - path: .env.alfred + required: true + - path: .env.secrets required: true environment: - PUID=1000 diff --git a/mongod.conf b/mongod.conf index bb6ac98..2e1278b 100644 --- a/mongod.conf +++ b/mongod.conf @@ -9,10 +9,6 @@ net: storage: dbPath: /data/db -# Security settings -security: - authorization: enabled - # System log settings systemLog: destination: file diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index efb0a52..0000000 --- a/poetry.lock +++ /dev/null @@ -1,1221 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "annotated-doc" -version = "0.0.4" -description = "Document parameters, class attributes, return types, and variables inline, with Annotated." -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320"}, - {file = "annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4"}, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, -] - -[[package]] -name = "anyio" -version = "4.12.0" -description = "High-level concurrency and networking framework on top of asyncio or Trio" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb"}, - {file = "anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0"}, -] - -[package.dependencies] -idna = ">=2.8" - -[package.extras] -trio = ["trio (>=0.31.0)", "trio (>=0.32.0)"] - -[[package]] -name = "bracex" -version = "2.6" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.9" -files = [ - {file = "bracex-2.6-py3-none-any.whl", hash = "sha256:0b0049264e7340b3ec782b5cb99beb325f36c3782a32e36e876452fd49a09952"}, - {file = "bracex-2.6.tar.gz", hash = "sha256:98f1347cd77e22ee8d967a30ad4e310b233f7754dbf31ff3fceb76145ba47dc7"}, -] - -[[package]] -name = "bump-my-version" -version = "1.2.6" -description = "Version bump your Python project" -optional = false -python-versions = ">=3.8" -files = [ - {file = "bump_my_version-1.2.6-py3-none-any.whl", hash = "sha256:a2f567c10574a374b81a9bd6d2bd3cb2ca74befe5c24c3021123773635431659"}, - {file = "bump_my_version-1.2.6.tar.gz", hash = "sha256:1f2f0daa5d699904e9739be8efb51c4c945461bad83cd4da4c89d324d9a18343"}, -] - -[package.dependencies] -click = "<8.4" -httpx = ">=0.28.1" -pydantic = ">=2.0.0" -pydantic-settings = "*" -questionary = "*" -rich = "*" -rich-click = "*" -tomlkit = "*" -wcmatch = ">=8.5.1" - -[[package]] -name = "certifi" -version = "2026.1.4" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.7" -files = [ - {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, - {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, -] - -[[package]] -name = "cfgv" -version = "3.5.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.10" -files = [ - {file = "cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0"}, - {file = "cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.4" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7" -files = [ - {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, - {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, - {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, -] - -[[package]] -name = "click" -version = "8.3.1" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.10" -files = [ - {file = "click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"}, - {file = "click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.13.1" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.10" -files = [ - {file = "coverage-7.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1fa280b3ad78eea5be86f94f461c04943d942697e0dac889fa18fff8f5f9147"}, - {file = "coverage-7.13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c3d8c679607220979434f494b139dfb00131ebf70bb406553d69c1ff01a5c33d"}, - {file = "coverage-7.13.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:339dc63b3eba969067b00f41f15ad161bf2946613156fb131266d8debc8e44d0"}, - {file = "coverage-7.13.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:db622b999ffe49cb891f2fff3b340cdc2f9797d01a0a202a0973ba2562501d90"}, - {file = "coverage-7.13.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1443ba9acbb593fa7c1c29e011d7c9761545fe35e7652e85ce7f51a16f7e08d"}, - {file = "coverage-7.13.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c832ec92c4499ac463186af72f9ed4d8daec15499b16f0a879b0d1c8e5cf4a3b"}, - {file = "coverage-7.13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:562ec27dfa3f311e0db1ba243ec6e5f6ab96b1edfcfc6cf86f28038bc4961ce6"}, - {file = "coverage-7.13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4de84e71173d4dada2897e5a0e1b7877e5eefbfe0d6a44edee6ce31d9b8ec09e"}, - {file = "coverage-7.13.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a5a68357f686f8c4d527a2dc04f52e669c2fc1cbde38f6f7eb6a0e58cbd17cae"}, - {file = "coverage-7.13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:77cc258aeb29a3417062758975521eae60af6f79e930d6993555eeac6a8eac29"}, - {file = "coverage-7.13.1-cp310-cp310-win32.whl", hash = "sha256:bb4f8c3c9a9f34423dba193f241f617b08ffc63e27f67159f60ae6baf2dcfe0f"}, - {file = "coverage-7.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:c8e2706ceb622bc63bac98ebb10ef5da80ed70fbd8a7999a5076de3afaef0fb1"}, - {file = "coverage-7.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a55d509a1dc5a5b708b5dad3b5334e07a16ad4c2185e27b40e4dba796ab7f88"}, - {file = "coverage-7.13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d010d080c4888371033baab27e47c9df7d6fb28d0b7b7adf85a4a49be9298b3"}, - {file = "coverage-7.13.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d938b4a840fb1523b9dfbbb454f652967f18e197569c32266d4d13f37244c3d9"}, - {file = "coverage-7.13.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bf100a3288f9bb7f919b87eb84f87101e197535b9bd0e2c2b5b3179633324fee"}, - {file = "coverage-7.13.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef6688db9bf91ba111ae734ba6ef1a063304a881749726e0d3575f5c10a9facf"}, - {file = "coverage-7.13.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0b609fc9cdbd1f02e51f67f51e5aee60a841ef58a68d00d5ee2c0faf357481a3"}, - {file = "coverage-7.13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c43257717611ff5e9a1d79dce8e47566235ebda63328718d9b65dd640bc832ef"}, - {file = "coverage-7.13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e09fbecc007f7b6afdfb3b07ce5bd9f8494b6856dd4f577d26c66c391b829851"}, - {file = "coverage-7.13.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a03a4f3a19a189919c7055098790285cc5c5b0b3976f8d227aea39dbf9f8bfdb"}, - {file = "coverage-7.13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3820778ea1387c2b6a818caec01c63adc5b3750211af6447e8dcfb9b6f08dbba"}, - {file = "coverage-7.13.1-cp311-cp311-win32.whl", hash = "sha256:ff10896fa55167371960c5908150b434b71c876dfab97b69478f22c8b445ea19"}, - {file = "coverage-7.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:a998cc0aeeea4c6d5622a3754da5a493055d2d95186bad877b0a34ea6e6dbe0a"}, - {file = "coverage-7.13.1-cp311-cp311-win_arm64.whl", hash = "sha256:fea07c1a39a22614acb762e3fbbb4011f65eedafcb2948feeef641ac78b4ee5c"}, - {file = "coverage-7.13.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3"}, - {file = "coverage-7.13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e"}, - {file = "coverage-7.13.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c"}, - {file = "coverage-7.13.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62"}, - {file = "coverage-7.13.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968"}, - {file = "coverage-7.13.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e"}, - {file = "coverage-7.13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f"}, - {file = "coverage-7.13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee"}, - {file = "coverage-7.13.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf"}, - {file = "coverage-7.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c"}, - {file = "coverage-7.13.1-cp312-cp312-win32.whl", hash = "sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7"}, - {file = "coverage-7.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6"}, - {file = "coverage-7.13.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c"}, - {file = "coverage-7.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78"}, - {file = "coverage-7.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b"}, - {file = "coverage-7.13.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd"}, - {file = "coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992"}, - {file = "coverage-7.13.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4"}, - {file = "coverage-7.13.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a"}, - {file = "coverage-7.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766"}, - {file = "coverage-7.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4"}, - {file = "coverage-7.13.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398"}, - {file = "coverage-7.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784"}, - {file = "coverage-7.13.1-cp313-cp313-win32.whl", hash = "sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461"}, - {file = "coverage-7.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500"}, - {file = "coverage-7.13.1-cp313-cp313-win_arm64.whl", hash = "sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9"}, - {file = "coverage-7.13.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc"}, - {file = "coverage-7.13.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a"}, - {file = "coverage-7.13.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4"}, - {file = "coverage-7.13.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6"}, - {file = "coverage-7.13.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1"}, - {file = "coverage-7.13.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd"}, - {file = "coverage-7.13.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c"}, - {file = "coverage-7.13.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0"}, - {file = "coverage-7.13.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e"}, - {file = "coverage-7.13.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53"}, - {file = "coverage-7.13.1-cp313-cp313t-win32.whl", hash = "sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842"}, - {file = "coverage-7.13.1-cp313-cp313t-win_amd64.whl", hash = "sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2"}, - {file = "coverage-7.13.1-cp313-cp313t-win_arm64.whl", hash = "sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09"}, - {file = "coverage-7.13.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894"}, - {file = "coverage-7.13.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a"}, - {file = "coverage-7.13.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f"}, - {file = "coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909"}, - {file = "coverage-7.13.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4"}, - {file = "coverage-7.13.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75"}, - {file = "coverage-7.13.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9"}, - {file = "coverage-7.13.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465"}, - {file = "coverage-7.13.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864"}, - {file = "coverage-7.13.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9"}, - {file = "coverage-7.13.1-cp314-cp314-win32.whl", hash = "sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5"}, - {file = "coverage-7.13.1-cp314-cp314-win_amd64.whl", hash = "sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a"}, - {file = "coverage-7.13.1-cp314-cp314-win_arm64.whl", hash = "sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0"}, - {file = "coverage-7.13.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a"}, - {file = "coverage-7.13.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6"}, - {file = "coverage-7.13.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673"}, - {file = "coverage-7.13.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5"}, - {file = "coverage-7.13.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d"}, - {file = "coverage-7.13.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8"}, - {file = "coverage-7.13.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486"}, - {file = "coverage-7.13.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564"}, - {file = "coverage-7.13.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7"}, - {file = "coverage-7.13.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416"}, - {file = "coverage-7.13.1-cp314-cp314t-win32.whl", hash = "sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f"}, - {file = "coverage-7.13.1-cp314-cp314t-win_amd64.whl", hash = "sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79"}, - {file = "coverage-7.13.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4"}, - {file = "coverage-7.13.1-py3-none-any.whl", hash = "sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573"}, - {file = "coverage-7.13.1.tar.gz", hash = "sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd"}, -] - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "distlib" -version = "0.4.0" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, - {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, -] - -[[package]] -name = "execnet" -version = "2.1.2" -description = "execnet: rapid multi-Python deployment" -optional = false -python-versions = ">=3.8" -files = [ - {file = "execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec"}, - {file = "execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd"}, -] - -[package.extras] -testing = ["hatch", "pre-commit", "pytest", "tox"] - -[[package]] -name = "fastapi" -version = "0.127.1" -description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -optional = false -python-versions = ">=3.9" -files = [ - {file = "fastapi-0.127.1-py3-none-any.whl", hash = "sha256:31d670a4f9373cc6d7994420f98e4dc46ea693145207abc39696746c83a44430"}, - {file = "fastapi-0.127.1.tar.gz", hash = "sha256:946a87ee5d931883b562b6bada787d6c8178becee2683cb3f9b980d593206359"}, -] - -[package.dependencies] -annotated-doc = ">=0.0.2" -pydantic = ">=2.7.0" -starlette = ">=0.40.0,<0.51.0" -typing-extensions = ">=4.8.0" - -[package.extras] -all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "jinja2 (>=3.1.5)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] -standard-no-fastapi-cloud-cli = ["email-validator (>=2.0.0)", "fastapi-cli[standard-no-fastapi-cloud-cli] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "jinja2 (>=3.1.5)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] - -[[package]] -name = "filelock" -version = "3.20.2" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.10" -files = [ - {file = "filelock-3.20.2-py3-none-any.whl", hash = "sha256:fbba7237d6ea277175a32c54bb71ef814a8546d8601269e1bfc388de333974e8"}, - {file = "filelock-3.20.2.tar.gz", hash = "sha256:a2241ff4ddde2a7cebddf78e39832509cb045d18ec1a09d7248d6bfc6bfbbe64"}, -] - -[[package]] -name = "h11" -version = "0.16.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.8" -files = [ - {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, - {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, - {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.16" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.28.1" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, - {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "identify" -version = "2.6.15" -description = "File identification library for Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757"}, - {file = "identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "idna" -version = "3.11" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, - {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.3.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.10" -files = [ - {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, - {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, -] - -[[package]] -name = "markdown-it-py" -version = "4.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.10" -files = [ - {file = "markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147"}, - {file = "markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "markdown-it-pyrs", "mistletoe (>=1.0,<2.0)", "mistune (>=3.0,<4.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins (>=0.5.0)"] -profiling = ["gprof2dot"] -rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "requests"] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "nodeenv" -version = "1.10.0" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827"}, - {file = "nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb"}, -] - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "platformdirs" -version = "4.5.1" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.10" -files = [ - {file = "platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31"}, - {file = "platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda"}, -] - -[package.extras] -docs = ["furo (>=2025.9.25)", "proselint (>=0.14)", "sphinx (>=8.2.3)", "sphinx-autodoc-typehints (>=3.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.4.2)", "pytest-cov (>=7)", "pytest-mock (>=3.15.1)"] -type = ["mypy (>=1.18.2)"] - -[[package]] -name = "pluggy" -version = "1.6.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, - {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["coverage", "pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "4.5.1" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.10" -files = [ - {file = "pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77"}, - {file = "pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "prompt-toolkit" -version = "3.0.52" -description = "Library for building powerful interactive command lines in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"}, - {file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "pydantic" -version = "2.12.5" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d"}, - {file = "pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49"}, -] - -[package.dependencies] -annotated-types = ">=0.6.0" -pydantic-core = "2.41.5" -typing-extensions = ">=4.14.1" -typing-inspection = ">=0.4.2" - -[package.extras] -email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146"}, - {file = "pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2"}, - {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97"}, - {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9"}, - {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52"}, - {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941"}, - {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a"}, - {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c"}, - {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2"}, - {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556"}, - {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49"}, - {file = "pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba"}, - {file = "pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9"}, - {file = "pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6"}, - {file = "pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b"}, - {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a"}, - {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8"}, - {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e"}, - {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1"}, - {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b"}, - {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b"}, - {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284"}, - {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594"}, - {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e"}, - {file = "pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b"}, - {file = "pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe"}, - {file = "pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f"}, - {file = "pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7"}, - {file = "pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0"}, - {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69"}, - {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75"}, - {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05"}, - {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc"}, - {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c"}, - {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5"}, - {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c"}, - {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294"}, - {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1"}, - {file = "pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d"}, - {file = "pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815"}, - {file = "pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3"}, - {file = "pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9"}, - {file = "pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34"}, - {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0"}, - {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33"}, - {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e"}, - {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2"}, - {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586"}, - {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d"}, - {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740"}, - {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e"}, - {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858"}, - {file = "pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36"}, - {file = "pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11"}, - {file = "pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd"}, - {file = "pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a"}, - {file = "pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14"}, - {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1"}, - {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66"}, - {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869"}, - {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2"}, - {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375"}, - {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553"}, - {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90"}, - {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07"}, - {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb"}, - {file = "pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23"}, - {file = "pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf"}, - {file = "pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c"}, - {file = "pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008"}, - {file = "pydantic_core-2.41.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf"}, - {file = "pydantic_core-2.41.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5"}, - {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d"}, - {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60"}, - {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82"}, - {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5"}, - {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3"}, - {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425"}, - {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504"}, - {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5"}, - {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3"}, - {file = "pydantic_core-2.41.5-cp39-cp39-win32.whl", hash = "sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460"}, - {file = "pydantic_core-2.41.5-cp39-cp39-win_amd64.whl", hash = "sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b"}, - {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034"}, - {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c"}, - {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2"}, - {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad"}, - {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd"}, - {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc"}, - {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56"}, - {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963"}, - {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f"}, - {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51"}, - {file = "pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e"}, -] - -[package.dependencies] -typing-extensions = ">=4.14.1" - -[[package]] -name = "pydantic-settings" -version = "2.12.0" -description = "Settings management using Pydantic" -optional = false -python-versions = ">=3.10" -files = [ - {file = "pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809"}, - {file = "pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0"}, -] - -[package.dependencies] -pydantic = ">=2.7.0" -python-dotenv = ">=0.21.0" -typing-inspection = ">=0.4.0" - -[package.extras] -aws-secrets-manager = ["boto3 (>=1.35.0)", "boto3-stubs[secretsmanager]"] -azure-key-vault = ["azure-identity (>=1.16.0)", "azure-keyvault-secrets (>=4.8.0)"] -gcp-secret-manager = ["google-cloud-secret-manager (>=2.23.1)"] -toml = ["tomli (>=2.0.1)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "pygments" -version = "2.19.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, - {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pytest" -version = "8.4.2" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}, - {file = "pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}, -] - -[package.dependencies] -colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} -iniconfig = ">=1" -packaging = ">=20" -pluggy = ">=1.5,<2" -pygments = ">=2.7.2" - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.23.8" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, - {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, -] - -[package.dependencies] -pytest = ">=7.0.0,<9" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] - -[[package]] -name = "pytest-cov" -version = "4.1.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - -[[package]] -name = "pytest-xdist" -version = "3.8.0" -description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"}, - {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"}, -] - -[package.dependencies] -execnet = ">=2.1" -pytest = ">=7.0.0" - -[package.extras] -psutil = ["psutil (>=3.0)"] -setproctitle = ["setproctitle"] -testing = ["filelock"] - -[[package]] -name = "python-dotenv" -version = "1.2.1" -description = "Read key-value pairs from a .env file and set them as environment variables" -optional = false -python-versions = ">=3.9" -files = [ - {file = "python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61"}, - {file = "python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6"}, -] - -[package.extras] -cli = ["click (>=5.0)"] - -[[package]] -name = "pyyaml" -version = "6.0.3" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"}, - {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"}, - {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"}, - {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"}, - {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"}, - {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"}, - {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"}, - {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"}, - {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"}, - {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"}, - {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}, - {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}, - {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}, - {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}, - {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}, - {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}, - {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, - {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}, - {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}, - {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}, - {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, - {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, - {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, - {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, - {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, - {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, - {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, - {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, - {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, - {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, - {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}, - {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}, - {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}, - {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}, - {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}, - {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}, - {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}, - {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}, - {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}, - {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}, - {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}, - {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}, - {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"}, - {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"}, - {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"}, - {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"}, - {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"}, - {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"}, - {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, -] - -[[package]] -name = "questionary" -version = "2.1.1" -description = "Python library to build pretty command line user prompts ⭐️" -optional = false -python-versions = ">=3.9" -files = [ - {file = "questionary-2.1.1-py3-none-any.whl", hash = "sha256:a51af13f345f1cdea62347589fbb6df3b290306ab8930713bfae4d475a7d4a59"}, - {file = "questionary-2.1.1.tar.gz", hash = "sha256:3d7e980292bb0107abaa79c68dd3eee3c561b83a0f89ae482860b181c8bd412d"}, -] - -[package.dependencies] -prompt_toolkit = ">=2.0,<4.0" - -[[package]] -name = "requests" -version = "2.32.5" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.9" -files = [ - {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, - {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset_normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "rich" -version = "14.2.0" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd"}, - {file = "rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4"}, -] - -[package.dependencies] -markdown-it-py = ">=2.2.0" -pygments = ">=2.13.0,<3.0.0" - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] - -[[package]] -name = "rich-click" -version = "1.9.5" -description = "Format click help output nicely with rich" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rich_click-1.9.5-py3-none-any.whl", hash = "sha256:9b195721a773b1acf0e16ff9ec68cef1e7d237e53471e6e3f7ade462f86c403a"}, - {file = "rich_click-1.9.5.tar.gz", hash = "sha256:48120531493f1533828da80e13e839d471979ec8d7d0ca7b35f86a1379cc74b6"}, -] - -[package.dependencies] -click = ">=8" -colorama = {version = "*", markers = "platform_system == \"Windows\""} -rich = ">=12" - -[package.extras] -dev = ["inline-snapshot (>=0.24)", "jsonschema (>=4)", "mypy (>=1.14.1)", "nodeenv (>=1.9.1)", "packaging (>=25)", "pre-commit (>=3.5)", "pytest (>=8.3.5)", "pytest-cov (>=5)", "rich-codex (>=1.2.11)", "ruff (>=0.12.4)", "typer (>=0.15)", "types-setuptools (>=75.8.0.20250110)"] -docs = ["markdown-include (>=0.8.1)", "mike (>=2.1.3)", "mkdocs-github-admonitions-plugin (>=0.1.1)", "mkdocs-glightbox (>=0.4)", "mkdocs-include-markdown-plugin (>=7.1.7)", "mkdocs-material-extensions (>=1.3.1)", "mkdocs-material[imaging] (>=9.5.18,<9.6.0)", "mkdocs-redirects (>=1.2.2)", "mkdocs-rss-plugin (>=1.15)", "mkdocs[docs] (>=1.6.1)", "mkdocstrings[python] (>=0.26.1)", "rich-codex (>=1.2.11)", "typer (>=0.15)"] - -[[package]] -name = "ruff" -version = "0.14.10" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49"}, - {file = "ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f"}, - {file = "ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f"}, - {file = "ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f"}, - {file = "ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d"}, - {file = "ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405"}, - {file = "ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60"}, - {file = "ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830"}, - {file = "ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6"}, - {file = "ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154"}, - {file = "ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6"}, - {file = "ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4"}, -] - -[[package]] -name = "starlette" -version = "0.50.0" -description = "The little ASGI library that shines." -optional = false -python-versions = ">=3.10" -files = [ - {file = "starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca"}, - {file = "starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca"}, -] - -[package.dependencies] -anyio = ">=3.6.2,<5" - -[package.extras] -full = ["httpx (>=0.27.0,<0.29.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"] - -[[package]] -name = "tomlkit" -version = "0.13.3" -description = "Style preserving TOML library" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, - {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -files = [ - {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, - {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -description = "Runtime typing introspection tools" -optional = false -python-versions = ">=3.9" -files = [ - {file = "typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"}, - {file = "typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464"}, -] - -[package.dependencies] -typing-extensions = ">=4.12.0" - -[[package]] -name = "urllib3" -version = "2.6.2" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.9" -files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, -] - -[package.extras] -brotli = ["brotli (>=1.2.0)", "brotlicffi (>=1.2.0.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["backports-zstd (>=1.0.0)"] - -[[package]] -name = "uvicorn" -version = "0.40.0" -description = "The lightning-fast ASGI server." -optional = false -python-versions = ">=3.10" -files = [ - {file = "uvicorn-0.40.0-py3-none-any.whl", hash = "sha256:c6c8f55bc8bf13eb6fa9ff87ad62308bbbc33d0b67f84293151efe87e0d5f2ee"}, - {file = "uvicorn-0.40.0.tar.gz", hash = "sha256:839676675e87e73694518b5574fd0f24c9d97b46bea16df7b8c05ea1a51071ea"}, -] - -[package.dependencies] -click = ">=7.0" -h11 = ">=0.8" - -[package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - -[[package]] -name = "virtualenv" -version = "20.35.4" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.8" -files = [ - {file = "virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b"}, - {file = "virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<5" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] - -[[package]] -name = "wcmatch" -version = "10.1" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.9" -files = [ - {file = "wcmatch-10.1-py3-none-any.whl", hash = "sha256:5848ace7dbb0476e5e55ab63c6bbd529745089343427caa5537f230cc01beb8a"}, - {file = "wcmatch-10.1.tar.gz", hash = "sha256:f11f94208c8c8484a16f4f48638a85d771d9513f4ab3f37595978801cb9465af"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wcwidth" -version = "0.2.14" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = ">=3.6" -files = [ - {file = "wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1"}, - {file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "==3.14.2" -content-hash = "ec920fd78ea55c063bf2e4696c328056b50d8d1694f057c2d455ca2619938aac" diff --git a/pyproject.toml b/pyproject.toml index ae376e8..b1c200e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,50 +1,67 @@ -[tool.poetry] +[project] name = "alfred" version = "0.1.7" description = "AI agent for managing a local media library" authors = ["Francwa "] readme = "README.md" -package-mode = false +requires-python = "==3.14.3" +dependencies = [ + "python-dotenv~=1.0.0", + "requests~=2.32.5", + "fastapi~=0.127.1", + "pydantic~=2.12.4", + "uvicorn~=0.40.0", + "httpx~=0.28.1", + "pydantic-settings~=2.12.0", + "click~=8.1", +] -[tool.alfred.settings] +[tool.alfred] image_name = "alfred_media_organizer" -librechat_version = "v0.8.1" -rag_version = "v0.7.0" -runner = "poetry" +librechat_version = "v0.8.4" +rag_version = "v0.7.3" service_name = "alfred" +uv_version = "0.11.6" -[tool.alfred.security] -jwt_secret = "32:b64" -jwt_refresh_secret = "32:b64" -creds_key = "32:b64" -creds_iv = "16:b64" -meili_master_key = "32:b64" -mongo_password = "16:hex" -postgres_password = "16:hex" -qbittorrent_password = "16:hex" +[tool.alfred.secrets] +JWT_SECRET = "32:hex" +JWT_REFRESH_SECRET = "32:hex" +CREDS_KEY = "32:hex" +CREDS_IV = "16:hex" +MEILI_MASTER_KEY = "32:b64" +MONGO_PASSWORD = "16:hex" +POSTGRES_PASSWORD = "16:hex" +QBITTORRENT_PASSWORD = "16:hex" -[tool.poetry.dependencies] -python = "==3.14.2" -python-dotenv = "^1.0.0" -requests = "^2.32.5" -fastapi = "^0.127.1" -pydantic = "^2.12.4" -uvicorn = "^0.40.0" -pytest-xdist = "^3.8.0" -httpx = "^0.28.1" -pydantic-settings = "^2.12.0" +[tool.alfred.config.pattern] +type = "multi" +patterns = [ + "^#[=\\-*#]{3,}#?\\s*$", + "^#\\s+(.+?)\\s+#\\s*$", + "^#[=\\-*#]{3,}#?\\s*$", +] + +[tool.alfred.config] +extra_fields = [] + +[tool.uv] +package = false + +[dependency-groups] +dev = [ + "pytest~=8.0.0", + "pytest-cov~=4.1.0", + "pytest-asyncio~=0.23.0", + "pytest-xdist~=3.8.0", + "ruff~=0.14.7", + "pre-commit~=4.5.1", + "bump-my-version~=1.2.5", +] -[tool.poetry.group.dev.dependencies] -pytest = "^8.0.0" -pytest-cov = "^4.1.0" -pytest-asyncio = "^0.23.0" -ruff = "^0.14.7" -pre-commit = "^4.5.1" -bump-my-version = "^1.2.5" [build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" [tool.pytest.ini_options] # Chemins où pytest cherche les tests diff --git a/scan.json b/scan.json new file mode 100644 index 0000000..19af0ab --- /dev/null +++ b/scan.json @@ -0,0 +1,4693 @@ +{ + "meta": { + "upstream": "LibreChat", + "version": "v0.8.4", + "env_example_url": "https://raw.githubusercontent.com/danny-avila/LibreChat/v0.8.4/.env.example", + "file_hash": "sha256:1282b2e760c5b74c6c58067fbc6de13b25bab3e3f73724bb396e729eb249e3aa", + "analyzed_at": "2026-04-23T14:07:45.746637+00:00", + "total_keys": 344, + "active_keys": 177, + "commented_keys": 167, + "total_categories": 40, + "deprecated_keys": 0, + "hardcoded_keys": 5, + "unknown_keys": 344, + "removed_keys": 0 + }, + "categories": { + "Server Configuration": { + "description": null, + "key_count": 16, + "selected": true + }, + "JSON Logging": { + "description": null, + "key_count": 1, + "selected": true + }, + "Debug Logging": { + "description": null, + "key_count": 3, + "selected": true + }, + "Permissions": { + "description": null, + "key_count": 2, + "selected": true + }, + "Node Options": { + "description": null, + "key_count": 2, + "selected": true + }, + "Configuration": { + "description": null, + "key_count": 1, + "selected": true + }, + "Langfuse Tracing": { + "description": null, + "key_count": 3, + "selected": true + }, + "Endpoints": { + "description": null, + "key_count": 2, + "selected": true + }, + "Known Endpoints - librechat.yaml": { + "description": null, + "key_count": 14, + "selected": true + }, + "Web Search": { + "description": null, + "key_count": 5, + "selected": true + }, + "Anthropic": { + "description": null, + "key_count": 5, + "selected": true + }, + "Azure": { + "description": null, + "key_count": 9, + "selected": true + }, + "AWS Bedrock": { + "description": null, + "key_count": 5, + "selected": true + }, + "Google": { + "description": null, + "key_count": 13, + "selected": true + }, + "Gemini Image Generation": { + "description": null, + "key_count": 2, + "selected": true + }, + "OpenAI": { + "description": null, + "key_count": 10, + "selected": true + }, + "Assistants API": { + "description": null, + "key_count": 3, + "selected": true + }, + "Azure Assistants API": { + "description": null, + "key_count": 38, + "selected": true + }, + "Search": { + "description": null, + "key_count": 5, + "selected": true + }, + "Speech to Text & Text to Speech": { + "description": null, + "key_count": 2, + "selected": true + }, + "RAG": { + "description": null, + "key_count": 5, + "selected": true + }, + "Moderation": { + "description": null, + "key_count": 29, + "selected": true + }, + "Balance": { + "description": null, + "key_count": 2, + "selected": true + }, + "Registration and Login": { + "description": null, + "key_count": 58, + "selected": true + }, + "SharePoint Integration": { + "description": null, + "key_count": 18, + "selected": true + }, + "Microsoft Graph API / Entra ID Integration": { + "description": null, + "key_count": 16, + "selected": true + }, + "Email Password Reset": { + "description": null, + "key_count": 8, + "selected": true + }, + "Mailgun API": { + "description": null, + "key_count": 5, + "selected": true + }, + "Firebase CDN": { + "description": null, + "key_count": 6, + "selected": true + }, + "S3 AWS Bucket": { + "description": null, + "key_count": 6, + "selected": true + }, + "Azure Blob Storage": { + "description": null, + "key_count": 3, + "selected": true + }, + "Shared Links": { + "description": null, + "key_count": 2, + "selected": true + }, + "Static File Cache Control": { + "description": null, + "key_count": 4, + "selected": true + }, + "UI": { + "description": null, + "key_count": 6, + "selected": true + }, + "REDIS Options": { + "description": null, + "key_count": 16, + "selected": true + }, + "Others": { + "description": null, + "key_count": 3, + "selected": true + }, + "Cache Headers": { + "description": null, + "key_count": 3, + "selected": true + }, + "OpenWeather": { + "description": null, + "key_count": 1, + "selected": true + }, + "LibreChat Code Interpreter API": { + "description": null, + "key_count": 1, + "selected": true + }, + "MCP Configuration": { + "description": null, + "key_count": 11, + "selected": true + } + }, + "keys": { + "HOST": { + "category": "Server Configuration", + "status": "active", + "default_upstream": "localhost", + "description": "Specifies the host address for the server", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "PORT": { + "category": "Server Configuration", + "status": "active", + "default_upstream": "3080", + "description": "Specifies the port where the server listens (default: 3080)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_URI": { + "category": "Server Configuration", + "status": "active", + "default_upstream": "mongodb://127.0.0.1:27017/LibreChat", + "description": "MongoDB connection URI", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_MAX_POOL_SIZE": { + "category": "Server Configuration", + "status": "active", + "default_upstream": null, + "description": "Maximum connections in MongoDB connection pool", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_MIN_POOL_SIZE": { + "category": "Server Configuration", + "status": "active", + "default_upstream": null, + "description": "Minimum connections in MongoDB connection pool", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_MAX_CONNECTING": { + "category": "Server Configuration", + "status": "active", + "default_upstream": null, + "description": "Max concurrent connections being established", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_MAX_IDLE_TIME_MS": { + "category": "Server Configuration", + "status": "active", + "default_upstream": null, + "description": "Max milliseconds a connection can remain idle", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_WAIT_QUEUE_TIMEOUT_MS": { + "category": "Server Configuration", + "status": "active", + "default_upstream": null, + "description": "Max time a thread waits for connection availability", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_AUTO_INDEX": { + "category": "Server Configuration", + "status": "active", + "default_upstream": null, + "description": "Disable automatic index creation for models", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MONGO_AUTO_CREATE": { + "category": "Server Configuration", + "status": "active", + "default_upstream": null, + "description": "Disable Mongoose auto createCollection() calls", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DOMAIN_CLIENT": { + "category": "Server Configuration", + "status": "active", + "default_upstream": "http://localhost:3080", + "description": "Client-side domain URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DOMAIN_SERVER": { + "category": "Server Configuration", + "status": "active", + "default_upstream": "http://localhost:3080", + "description": "Server-side domain URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "NO_INDEX": { + "category": "Server Configuration", + "status": "active", + "default_upstream": "true", + "description": "Prevents search engines from indexing website", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "TRUST_PROXY": { + "category": "Server Configuration", + "status": "active", + "default_upstream": "1", + "description": "Number of hops away from Express app (default: 1)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MIN_PASSWORD_LENGTH": { + "category": "Server Configuration", + "status": "commented", + "default_upstream": "8", + "description": "Minimum password length requirement", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CONTINUE_ON_UNCAUGHT_EXCEPTION": { + "category": "Server Configuration", + "status": "commented", + "default_upstream": "false", + "description": "Continue app after uncaught exceptions", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CONSOLE_JSON": { + "category": "JSON Logging", + "status": "active", + "default_upstream": "false", + "description": "Enable JSON console logs for cloud deployments", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DEBUG_LOGGING": { + "category": "Debug Logging", + "status": "active", + "default_upstream": "true", + "description": "Keep debug logs active (default: true)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DEBUG_CONSOLE": { + "category": "Debug Logging", + "status": "active", + "default_upstream": "false", + "description": "Enable verbose console/stdout logs", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MEM_DIAG": { + "category": "Debug Logging", + "status": "commented", + "default_upstream": "true", + "description": "Enable memory diagnostics logging", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "UID": { + "category": "Permissions", + "status": "commented", + "default_upstream": "1000", + "description": "User ID for Docker container permissions", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GID": { + "category": "Permissions", + "status": "commented", + "default_upstream": "1000", + "description": "Group ID for Docker container permissions", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "NODE_OPTIONS": { + "category": "Node Options", + "status": "commented", + "default_upstream": "\"--max-old-space-size=6144\"", + "description": "NOTE: NODE_MAX_OLD_SPACE_SIZE is NOT recognized by Node.js directly. This variable is used as a build argument for Docker or CI/CD workflows, and is NOT used by Node.js to set the heap size at runtime. To configure Node.js memory, use NODE_OPTIONS, e.g.:", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "NODE_MAX_OLD_SPACE_SIZE": { + "category": "Node Options", + "status": "active", + "default_upstream": "6144", + "description": "NOTE: NODE_MAX_OLD_SPACE_SIZE is NOT recognized by Node.js directly. This variable is used as a build argument for Docker or CI/CD workflows, and is NOT used by Node.js to set the heap size at runtime. To configure Node.js memory, use NODE_OPTIONS, e.g.: NODE_OPTIONS=\"--max-old-space-size=6144\" See: https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CONFIG_PATH": { + "category": "Configuration", + "status": "commented", + "default_upstream": "\"/alternative/path/to/librechat.yaml\"", + "description": "Alternative location for librechat.yaml configuration file", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LANGFUSE_PUBLIC_KEY": { + "category": "Langfuse Tracing", + "status": "commented", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LANGFUSE_SECRET_KEY": { + "category": "Langfuse Tracing", + "status": "commented", + "default_upstream": null, + "description": "LANGFUSE_PUBLIC_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LANGFUSE_BASE_URL": { + "category": "Langfuse Tracing", + "status": "commented", + "default_upstream": null, + "description": "LANGFUSE_PUBLIC_KEY= LANGFUSE_SECRET_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ENDPOINTS": { + "category": "Endpoints", + "status": "commented", + "default_upstream": "openAI,assistants,azureOpenAI,google,anthropic", + "description": "Comma-separated list of available endpoints", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "PROXY": { + "category": "Endpoints", + "status": "active", + "default_upstream": null, + "description": "Proxy setting for all endpoints", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ANYSCALE_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for Anyscale", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "APIPIE_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for Apipie", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "COHERE_API_KEY": { + "category": "Web Search", + "status": "commented", + "default_upstream": "your_cohere_api_key", + "description": "API key for Cohere", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DEEPSEEK_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for Deepseek", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DATABRICKS_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "ANYSCALE_API_KEY= APIPIE_API_KEY= COHERE_API_KEY= DEEPSEEK_API_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIREWORKS_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for Fireworks", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GROQ_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for Groq", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "HUGGINGFACE_TOKEN": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "ANYSCALE_API_KEY= APIPIE_API_KEY= COHERE_API_KEY= DEEPSEEK_API_KEY= DATABRICKS_API_KEY= FIREWORKS_API_KEY= GROQ_API_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MISTRAL_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for Mistral", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENROUTER_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for OpenRouter", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "PERPLEXITY_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for Perplexity", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SHUTTLEAI_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for ShuttleAI", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "TOGETHERAI_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "API key for TogetherAI", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "UNIFY_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "ANYSCALE_API_KEY= APIPIE_API_KEY= COHERE_API_KEY= DEEPSEEK_API_KEY= DATABRICKS_API_KEY= FIREWORKS_API_KEY= GROQ_API_KEY= HUGGINGFACE_TOKEN= MISTRAL_API_KEY= OPENROUTER_KEY= PERPLEXITY_API_KEY= SHUTTLEAI_API_KEY= TOGETHERAI_API_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "XAI_API_KEY": { + "category": "Known Endpoints - librechat.yaml", + "status": "commented", + "default_upstream": null, + "description": "ANYSCALE_API_KEY= APIPIE_API_KEY= COHERE_API_KEY= DEEPSEEK_API_KEY= DATABRICKS_API_KEY= FIREWORKS_API_KEY= GROQ_API_KEY= HUGGINGFACE_TOKEN= MISTRAL_API_KEY= OPENROUTER_KEY= PERPLEXITY_API_KEY= SHUTTLEAI_API_KEY= TOGETHERAI_API_KEY= UNIFY_API_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ANTHROPIC_API_KEY": { + "category": "Anthropic", + "status": "active", + "default_upstream": "user_provided", + "description": "Anthropic API key or 'user_provided'", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ANTHROPIC_MODELS": { + "category": "Anthropic", + "status": "commented", + "default_upstream": "claude-sonnet-4-6,claude-opus-4-6,claude-opus-4-20250514,claude-sonnet-4-20250514,claude-3-7-sonnet-20250219,claude-3-5-sonnet-20241022,claude-3-5-haiku-20241022,claude-3-opus-20240229,claude-3-sonnet-20240229,claude-3-haiku-20240307", + "description": "Comma-separated list of Anthropic models", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ANTHROPIC_REVERSE_PROXY": { + "category": "Anthropic", + "status": "commented", + "default_upstream": null, + "description": "Reverse proxy for Anthropic endpoint", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ANTHROPIC_USE_VERTEX": { + "category": "Anthropic", + "status": "commented", + "default_upstream": null, + "description": "Use Anthropic models through Google Vertex AI", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ANTHROPIC_VERTEX_REGION": { + "category": "Anthropic", + "status": "commented", + "default_upstream": "us-east5", + "description": "Google Cloud region for Vertex AI", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_OPENAI_DEFAULT_MODEL": { + "category": "Azure", + "status": "commented", + "default_upstream": "gpt-3.5-turbo # Deprecated", + "description": "Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_OPENAI_MODELS": { + "category": "Azure", + "status": "commented", + "default_upstream": "gpt-3.5-turbo,gpt-4 # Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_USE_MODEL_AS_DEPLOYMENT_NAME": { + "category": "Azure", + "status": "commented", + "default_upstream": "TRUE # Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_API_KEY": { + "category": "Azure", + "status": "commented", + "default_upstream": "# Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_OPENAI_API_INSTANCE_NAME": { + "category": "Azure", + "status": "commented", + "default_upstream": "# Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated AZURE_API_KEY= # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_OPENAI_API_DEPLOYMENT_NAME": { + "category": "Azure", + "status": "commented", + "default_upstream": "# Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated AZURE_API_KEY= # Deprecated AZURE_OPENAI_API_INSTANCE_NAME= # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_OPENAI_API_VERSION": { + "category": "Azure", + "status": "commented", + "default_upstream": "# Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated AZURE_API_KEY= # Deprecated AZURE_OPENAI_API_INSTANCE_NAME= # Deprecated AZURE_OPENAI_API_DEPLOYMENT_NAME= # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_OPENAI_API_COMPLETIONS_DEPLOYMENT_NAME": { + "category": "Azure", + "status": "commented", + "default_upstream": "# Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated AZURE_API_KEY= # Deprecated AZURE_OPENAI_API_INSTANCE_NAME= # Deprecated AZURE_OPENAI_API_DEPLOYMENT_NAME= # Deprecated AZURE_OPENAI_API_VERSION= # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME": { + "category": "Azure", + "status": "commented", + "default_upstream": "# Deprecated", + "description": "AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated AZURE_API_KEY= # Deprecated AZURE_OPENAI_API_INSTANCE_NAME= # Deprecated AZURE_OPENAI_API_DEPLOYMENT_NAME= # Deprecated AZURE_OPENAI_API_VERSION= # Deprecated AZURE_OPENAI_API_COMPLETIONS_DEPLOYMENT_NAME= # Deprecated", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BEDROCK_AWS_DEFAULT_REGION": { + "category": "AWS Bedrock", + "status": "commented", + "default_upstream": "us-east-1 # A default region must be provided", + "description": "A default region must be provided", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BEDROCK_AWS_ACCESS_KEY_ID": { + "category": "AWS Bedrock", + "status": "commented", + "default_upstream": "someAccessKey", + "description": "AWS access key ID for Bedrock", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BEDROCK_AWS_SECRET_ACCESS_KEY": { + "category": "AWS Bedrock", + "status": "commented", + "default_upstream": "someSecretAccessKey", + "description": "AWS secret access key for Bedrock", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BEDROCK_AWS_SESSION_TOKEN": { + "category": "AWS Bedrock", + "status": "commented", + "default_upstream": "someSessionToken", + "description": "AWS session token for Bedrock", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BEDROCK_AWS_MODELS": { + "category": "AWS Bedrock", + "status": "commented", + "default_upstream": "anthropic.claude-sonnet-4-6,anthropic.claude-opus-4-6-v1,anthropic.claude-3-5-sonnet-20240620-v1:0,meta.llama3-1-8b-instruct-v1:0", + "description": "Comma-separated list of Bedrock model IDs", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_KEY": { + "category": "Google", + "status": "active", + "default_upstream": "user_provided", + "description": "Google API key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_REVERSE_PROXY": { + "category": "Google", + "status": "commented", + "default_upstream": null, + "description": "Google reverse proxy URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_AUTH_HEADER": { + "category": "Google", + "status": "commented", + "default_upstream": "true", + "description": "Use Authorization header instead of X-goog-api-key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_MODELS": { + "category": "Google", + "status": "commented", + "default_upstream": "gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash-001,gemini-2.0-flash-lite-001", + "description": "Available Gemini/Vertex AI models", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_TITLE_MODEL": { + "category": "Google", + "status": "commented", + "default_upstream": "gemini-2.0-flash-lite-001", + "description": "DEPRECATED: Model for Google titling", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_LOC": { + "category": "Google", + "status": "commented", + "default_upstream": "us-central1", + "description": "Google Cloud location for processing API requests", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_CLOUD_LOCATION": { + "category": "Google", + "status": "commented", + "default_upstream": "global", + "description": "Alternative region for Gemini image generation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_SERVICE_KEY_FILE": { + "category": "Google", + "status": "commented", + "default_upstream": "/path/to/service-account.json", + "description": "Path to Google service account JSON key file", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_SAFETY_SEXUALLY_EXPLICIT": { + "category": "Google", + "status": "commented", + "default_upstream": "BLOCK_ONLY_HIGH", + "description": "Safety setting for sexually explicit content", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_SAFETY_HATE_SPEECH": { + "category": "Google", + "status": "commented", + "default_upstream": "BLOCK_ONLY_HIGH", + "description": "Safety setting for hate speech content", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_SAFETY_HARASSMENT": { + "category": "Google", + "status": "commented", + "default_upstream": "BLOCK_ONLY_HIGH", + "description": "Safety setting for harassment content", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_SAFETY_DANGEROUS_CONTENT": { + "category": "Google", + "status": "commented", + "default_upstream": "BLOCK_ONLY_HIGH", + "description": "Safety setting for dangerous content", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_SAFETY_CIVIC_INTEGRITY": { + "category": "Google", + "status": "commented", + "default_upstream": "BLOCK_ONLY_HIGH", + "description": "Safety setting for civic integrity content", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GEMINI_API_KEY": { + "category": "Gemini Image Generation", + "status": "commented", + "default_upstream": "your-gemini-api-key", + "description": "Dedicated Gemini API key for image generation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GEMINI_IMAGE_MODEL": { + "category": "Gemini Image Generation", + "status": "commented", + "default_upstream": "gemini-2.5-flash-image", + "description": "Gemini model for image generation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_API_KEY": { + "category": "OpenAI", + "status": "active", + "default_upstream": "user_provided", + "description": "OpenAI API key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_MODELS": { + "category": "OpenAI", + "status": "commented", + "default_upstream": "gpt-5,gpt-5-codex,gpt-5-mini,gpt-5-nano,o3-pro,o3,o4-mini,gpt-4.1,gpt-4.1-mini,gpt-4.1-nano,o3-mini,o1-pro,o1,gpt-4o,gpt-4o-mini", + "description": "Customize available OpenAI models", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DEBUG_OPENAI": { + "category": "OpenAI", + "status": "active", + "default_upstream": "false", + "description": "Enable debug mode for OpenAI endpoint", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "TITLE_CONVO": { + "category": "OpenAI", + "status": "commented", + "default_upstream": "false", + "description": "Enable titling for all endpoints", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_TITLE_MODEL": { + "category": "OpenAI", + "status": "commented", + "default_upstream": "gpt-4o-mini", + "description": "DEPRECATED: Model for OpenAI titling", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_SUMMARIZE": { + "category": "OpenAI", + "status": "commented", + "default_upstream": "true", + "description": "Enable message summarization", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_SUMMARY_MODEL": { + "category": "OpenAI", + "status": "commented", + "default_upstream": "gpt-4o-mini", + "description": "Model used for OpenAI summarization", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_FORCE_PROMPT": { + "category": "OpenAI", + "status": "commented", + "default_upstream": "true", + "description": "Force prompt payload instead of messages", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_REVERSE_PROXY": { + "category": "OpenAI", + "status": "commented", + "default_upstream": null, + "description": "DEPRECATED: OpenAI reverse proxy", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_ORGANIZATION": { + "category": "OpenAI", + "status": "commented", + "default_upstream": null, + "description": "OpenAI organization for API requests", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ASSISTANTS_API_KEY": { + "category": "Assistants API", + "status": "active", + "default_upstream": "user_provided", + "description": "OpenAI API key for Assistants API", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ASSISTANTS_BASE_URL": { + "category": "Assistants API", + "status": "commented", + "default_upstream": null, + "description": "Alternate base URL for Assistants API", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ASSISTANTS_MODELS": { + "category": "Assistants API", + "status": "commented", + "default_upstream": "gpt-4o,gpt-4o-mini,gpt-3.5-turbo-0125,gpt-3.5-turbo-16k-0613,gpt-3.5-turbo-16k,gpt-3.5-turbo,gpt-4,gpt-4-0314,gpt-4-32k-0314,gpt-4-0613,gpt-3.5-turbo-0613,gpt-3.5-turbo-1106,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview", + "description": "Available models for Assistants", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CREDS_KEY": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": "f34be427ebb29de8d88c107a71546019685ed8b241d8f2ed00c3df97ad2566f0", + "description": "32-byte hex key for securely storing credentials (required)", + "deprecated": false, + "hardcoded": true, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CREDS_IV": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": "e2341419ec3dd3d19b13a1a87fafcbfb", + "description": "16-byte hex IV for securely storing credentials (required)", + "deprecated": false, + "hardcoded": true, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_AI_SEARCH_SERVICE_ENDPOINT": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_AI_SEARCH_INDEX_NAME": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_AI_SEARCH_API_KEY": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_AI_SEARCH_API_VERSION": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_AI_SEARCH_SEARCH_OPTION_QUERY_TYPE": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_AI_SEARCH_SEARCH_OPTION_TOP": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_AI_SEARCH_SEARCH_OPTION_SELECT": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_API_KEY": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "# Create or reuse OpenAI API key for image generation tool", + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_BASEURL": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "# Custom OpenAI base URL for image generation tool", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_AZURE_API_VERSION": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "# Custom Azure OpenAI deployments", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_MODEL": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5)", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_DESCRIPTION": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_DESCRIPTION_WITH_FILES": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "Custom description for image generation tool when files are present", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5) IMAGE_GEN_OAI_DESCRIPTION=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_DESCRIPTION_NO_FILES": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "Custom description for image generation tool when no files are present", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5) IMAGE_GEN_OAI_DESCRIPTION= IMAGE_GEN_OAI_DESCRIPTION_WITH_FILES=Custom description for image generation tool when files are present", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_EDIT_OAI_DESCRIPTION": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "Custom description for image editing tool", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5) IMAGE_GEN_OAI_DESCRIPTION= IMAGE_GEN_OAI_DESCRIPTION_WITH_FILES=Custom description for image generation tool when files are present IMAGE_GEN_OAI_DESCRIPTION_NO_FILES=Custom description for image generation tool when no files are present", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_GEN_OAI_PROMPT_DESCRIPTION": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "Custom prompt description for image generation tool", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5) IMAGE_GEN_OAI_DESCRIPTION= IMAGE_GEN_OAI_DESCRIPTION_WITH_FILES=Custom description for image generation tool when files are present IMAGE_GEN_OAI_DESCRIPTION_NO_FILES=Custom description for image generation tool when no files are present IMAGE_EDIT_OAI_DESCRIPTION=Custom description for image editing tool", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMAGE_EDIT_OAI_PROMPT_DESCRIPTION": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "Custom prompt description for image editing tool", + "description": "IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5) IMAGE_GEN_OAI_DESCRIPTION= IMAGE_GEN_OAI_DESCRIPTION_WITH_FILES=Custom description for image generation tool when files are present IMAGE_GEN_OAI_DESCRIPTION_NO_FILES=Custom description for image generation tool when no files are present IMAGE_EDIT_OAI_DESCRIPTION=Custom description for image editing tool IMAGE_GEN_OAI_PROMPT_DESCRIPTION=Custom prompt description for image generation tool", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE_API_KEY": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE3_API_KEY": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE_API_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE2_API_KEY": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE_API_KEY= DALLE3_API_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE3_SYSTEM_PROMPT": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE_API_KEY= DALLE3_API_KEY= DALLE2_API_KEY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE2_SYSTEM_PROMPT": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE_API_KEY= DALLE3_API_KEY= DALLE2_API_KEY= DALLE3_SYSTEM_PROMPT=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE_REVERSE_PROXY": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE_API_KEY= DALLE3_API_KEY= DALLE2_API_KEY= DALLE3_SYSTEM_PROMPT= DALLE2_SYSTEM_PROMPT=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE3_BASEURL": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE_API_KEY= DALLE3_API_KEY= DALLE2_API_KEY= DALLE3_SYSTEM_PROMPT= DALLE2_SYSTEM_PROMPT= DALLE_REVERSE_PROXY=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE2_BASEURL": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE_API_KEY= DALLE3_API_KEY= DALLE2_API_KEY= DALLE3_SYSTEM_PROMPT= DALLE2_SYSTEM_PROMPT= DALLE_REVERSE_PROXY= DALLE3_BASEURL=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE3_AZURE_API_VERSION": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DALLE2_AZURE_API_VERSION": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "DALLE3_AZURE_API_VERSION=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FLUX_API_BASE_URL": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": "'https://api.bfl.ml';", + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FLUX_API_KEY": { + "category": "Azure Assistants API", + "status": "commented", + "default_upstream": null, + "description": "Get your API key at https://api.us1.bfl.ai/auth/profile", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_SEARCH_API_KEY": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_CSE_ID": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SD_WEBUI_URL": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": "http://host.docker.internal:7860", + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "TAVILY_API_KEY": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": "Tavily API key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "TRAVERSAAL_API_KEY": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": "Traversaal API key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "WOLFRAM_APP_ID": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": "Wolfram Alpha App ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ZAPIER_NLA_API_KEY": { + "category": "Azure Assistants API", + "status": "active", + "default_upstream": null, + "description": "Zapier NLA API key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SEARCH": { + "category": "Search", + "status": "active", + "default_upstream": "true", + "description": "Enable search in messages and conversations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MEILI_NO_ANALYTICS": { + "category": "Search", + "status": "active", + "default_upstream": "true", + "description": "Disable anonymized telemetry for MeiliSearch", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MEILI_HOST": { + "category": "Search", + "status": "active", + "default_upstream": "http://0.0.0.0:7700", + "description": "MeiliSearch API host URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MEILI_MASTER_KEY": { + "category": "Search", + "status": "active", + "default_upstream": "DrhYf7zENyR6AlUCKmnz0eYASOQdl6zxH7s7MKFSfFCt", + "description": "Master key for MeiliSearch (must be replaced)", + "deprecated": false, + "hardcoded": true, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MEILI_NO_SYNC": { + "category": "Search", + "status": "commented", + "default_upstream": "true", + "description": "Disable Meilisearch index sync", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "STT_API_KEY": { + "category": "Speech to Text & Text to Speech", + "status": "active", + "default_upstream": null, + "description": "API key for Speech-to-Text service", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "TTS_API_KEY": { + "category": "Speech to Text & Text to Speech", + "status": "active", + "default_upstream": null, + "description": "API key for Text-to-Speech service", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "RAG_OPENAI_BASEURL": { + "category": "RAG", + "status": "commented", + "default_upstream": null, + "description": "Custom OpenAI base URL for RAG", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "RAG_OPENAI_API_KEY": { + "category": "RAG", + "status": "commented", + "default_upstream": null, + "description": "OpenAI API key for RAG embeddings", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "RAG_USE_FULL_CONTEXT": { + "category": "RAG", + "status": "commented", + "default_upstream": null, + "description": "Fetch entire file context instead of top results", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMBEDDINGS_PROVIDER": { + "category": "RAG", + "status": "commented", + "default_upstream": "openai", + "description": "Embeddings provider (default: openai)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMBEDDINGS_MODEL": { + "category": "RAG", + "status": "commented", + "default_upstream": "text-embedding-3-small", + "description": "Embeddings model to use", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_MODERATION": { + "category": "Moderation", + "status": "active", + "default_upstream": "false", + "description": "Enable OpenAI moderation on endpoints", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_MODERATION_API_KEY": { + "category": "Moderation", + "status": "active", + "default_upstream": null, + "description": "OpenAI API key for moderation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENAI_MODERATION_REVERSE_PROXY": { + "category": "Moderation", + "status": "commented", + "default_upstream": null, + "description": "Reverse proxy for OpenAI moderation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BAN_VIOLATIONS": { + "category": "Moderation", + "status": "active", + "default_upstream": "true", + "description": "Enable banning users for violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BAN_DURATION": { + "category": "Moderation", + "status": "active", + "default_upstream": "1000 * 60 * 60 * 2", + "description": "Duration of ban in milliseconds (JS expression)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "BAN_INTERVAL": { + "category": "Moderation", + "status": "active", + "default_upstream": "20", + "description": "Ban interval threshold for violation scores", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LOGIN_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "1", + "description": "Score for login violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REGISTRATION_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "1", + "description": "Score for registration violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CONCURRENT_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "1", + "description": "Score for concurrent violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MESSAGE_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "1", + "description": "Score for message violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "NON_BROWSER_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "20", + "description": "Score for non-browser violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "TTS_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "0", + "description": "Score for TTS violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "STT_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "0", + "description": "Score for STT violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FORK_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "0", + "description": "Score for fork violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "IMPORT_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "0", + "description": "Score for import violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FILE_UPLOAD_VIOLATION_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "0", + "description": "Score for file upload violations", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LOGIN_MAX": { + "category": "Moderation", + "status": "active", + "default_upstream": "7", + "description": "Max logins allowed per IP per window", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LOGIN_WINDOW": { + "category": "Moderation", + "status": "active", + "default_upstream": "5", + "description": "Login window time in minutes", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REGISTER_MAX": { + "category": "Moderation", + "status": "active", + "default_upstream": "5", + "description": "Max registrations per IP per window", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REGISTER_WINDOW": { + "category": "Moderation", + "status": "active", + "default_upstream": "60", + "description": "Registration window time in minutes", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LIMIT_CONCURRENT_MESSAGES": { + "category": "Moderation", + "status": "active", + "default_upstream": "true", + "description": "Limit concurrent messages per request", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CONCURRENT_MESSAGE_MAX": { + "category": "Moderation", + "status": "active", + "default_upstream": "2", + "description": "Max messages per request", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LIMIT_MESSAGE_IP": { + "category": "Moderation", + "status": "active", + "default_upstream": "true", + "description": "Limit messages per IP", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MESSAGE_IP_MAX": { + "category": "Moderation", + "status": "active", + "default_upstream": "40", + "description": "Max messages per IP per window", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MESSAGE_IP_WINDOW": { + "category": "Moderation", + "status": "active", + "default_upstream": "1", + "description": "Message IP rate limit window in minutes", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LIMIT_MESSAGE_USER": { + "category": "Moderation", + "status": "active", + "default_upstream": "false", + "description": "Limit messages per user", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MESSAGE_USER_MAX": { + "category": "Moderation", + "status": "active", + "default_upstream": "40", + "description": "Max messages per user per window", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MESSAGE_USER_WINDOW": { + "category": "Moderation", + "status": "active", + "default_upstream": "1", + "description": "Message user rate limit window in minutes", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ILLEGAL_MODEL_REQ_SCORE": { + "category": "Moderation", + "status": "active", + "default_upstream": "5", + "description": "Score for illegal model requests", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CHECK_BALANCE": { + "category": "Balance", + "status": "commented", + "default_upstream": "false", + "description": "Enable token credit balances", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "START_BALANCE": { + "category": "Balance", + "status": "commented", + "default_upstream": "20000 # note: the number of tokens that will be credited after registration.", + "description": "CHECK_BALANCE=false", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_EMAIL_LOGIN": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "true", + "description": "Enable email login", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_REGISTRATION": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "true", + "description": "Enable email registration", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_SOCIAL_LOGIN": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "false", + "description": "Allow social network login", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_SOCIAL_REGISTRATION": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "false", + "description": "Allow social network registration", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_PASSWORD_RESET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "false", + "description": "Enable password reset functionality", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_ACCOUNT_DELETION": { + "category": "Registration and Login", + "status": "commented", + "default_upstream": "true # note: enabled by default if omitted/commented out", + "description": "note: enabled by default if omitted/commented out", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_UNVERIFIED_EMAIL_LOGIN": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "true", + "description": "Allow login without email verification", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SESSION_EXPIRY": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "1000 * 60 * 15", + "description": "Session expiry time in milliseconds (JS expression)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REFRESH_TOKEN_EXPIRY": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "(1000 * 60 * 60 * 24) * 7", + "description": "Refresh token expiry time in milliseconds (JS expression)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "JWT_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "16f8c0ef4a5d391b26034086c628469d3f9f497f08163ab9b40137092f2909ef", + "description": "JWT signing secret — 64-char hex, must be replaced", + "deprecated": false, + "hardcoded": true, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "JWT_REFRESH_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "eaa5191f2914e30b9387fd84e254e4ba6fc51b4654968a9b0803b456a54b8418", + "description": "JWT refresh signing secret — 64-char hex, must be replaced", + "deprecated": false, + "hardcoded": true, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DISCORD_CLIENT_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Discord client ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DISCORD_CLIENT_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Discord client secret", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DISCORD_CALLBACK_URL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "/oauth/discord/callback", + "description": "Discord authentication callback URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FACEBOOK_CLIENT_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Facebook client ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FACEBOOK_CLIENT_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Facebook client secret", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FACEBOOK_CALLBACK_URL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "/oauth/facebook/callback", + "description": "Facebook authentication callback URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GITHUB_CLIENT_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "GitHub client ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GITHUB_CLIENT_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "GitHub client secret", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GITHUB_CALLBACK_URL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "/oauth/github/callback", + "description": "GitHub authentication callback URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GITHUB_ENTERPRISE_BASE_URL": { + "category": "Registration and Login", + "status": "commented", + "default_upstream": null, + "description": "GitHub Enterprise instance base URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GITHUB_ENTERPRISE_USER_AGENT": { + "category": "Registration and Login", + "status": "commented", + "default_upstream": null, + "description": "GitHub Enterprise user agent", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_CLIENT_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Google OAuth client ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_CLIENT_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Google OAuth client secret", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "GOOGLE_CALLBACK_URL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "/oauth/google/callback", + "description": "Google authentication callback URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "APPLE_CLIENT_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Apple Services ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "APPLE_TEAM_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Apple Developer Team ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "APPLE_KEY_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Apple Key ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "APPLE_PRIVATE_KEY_PATH": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Path to Apple .p8 key file", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "APPLE_CALLBACK_URL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "/oauth/apple/callback", + "description": "Apple authentication callback URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_CLIENT_ID": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "OpenID client ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_CLIENT_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "OpenID client secret", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_ISSUER": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "OpenID issuer URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_SESSION_SECRET": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "OpenID session storage secret", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_SCOPE": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "\"openid profile email\"", + "description": "OpenID scope", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_CALLBACK_URL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "/oauth/openid/callback", + "description": "OpenID authentication callback URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_REQUIRED_ROLE": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Required role(s) for user validation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_REQUIRED_ROLE_TOKEN_KIND": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Token kind for role validation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_REQUIRED_ROLE_PARAMETER_PATH": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Parameter path for role validation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_ADMIN_ROLE": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Role for LibreChat admin", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_ADMIN_ROLE_PARAMETER_PATH": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Parameter path for admin role", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_ADMIN_ROLE_TOKEN_KIND": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Token source for admin role", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_USERNAME_CLAIM": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "User info property for username", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_NAME_CLAIM": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "User info property for display name", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_EMAIL_CLAIM": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "User info claim for email/identifier", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_AUDIENCE": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "OpenID audience parameter", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_BUTTON_LABEL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "OpenID login button label", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_IMAGE_URL": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "OpenID login button image URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_AUTO_REDIRECT": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "false", + "description": "Auto-redirect to OpenID provider", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_USE_PKCE": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "false", + "description": "Use PKCE for OpenID authentication", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_REUSE_TOKENS": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Enable reuse of OpenID provider tokens", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_JWKS_URL_CACHE_ENABLED": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Enable caching of JWKS signing keys", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_JWKS_URL_CACHE_TIME": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "# 600000 ms eq to 10 minutes leave empty to disable caching", + "description": "JWKS cache duration in milliseconds", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_ON_BEHALF_FLOW_FOR_USERINFO_REQUIRED": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Enable on-behalf-of flow for userinfo", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE": { + "category": "Registration and Login", + "status": "active", + "default_upstream": "\"user.read\" # example for Scope Needed for Microsoft Graph API", + "description": "example for Scope Needed for Microsoft Graph API", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_USE_END_SESSION_ENDPOINT": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Use issuer end session endpoint", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_POST_LOGOUT_REDIRECT_URI": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Redirect URI after logout", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_MAX_LOGOUT_URL_LENGTH": { + "category": "Registration and Login", + "status": "active", + "default_upstream": null, + "description": "Maximum logout URL length before using logout_hint instead of id_token_hint (default: 2000)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ENABLE_SHAREPOINT_FILEPICKER": { + "category": "SharePoint Integration", + "status": "commented", + "default_upstream": "true", + "description": "Enable SharePoint file picker", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SHAREPOINT_BASE_URL": { + "category": "SharePoint Integration", + "status": "commented", + "default_upstream": "https://yourtenant.sharepoint.com", + "description": "SharePoint tenant base URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SHAREPOINT_PICKER_SHAREPOINT_SCOPE": { + "category": "SharePoint Integration", + "status": "commented", + "default_upstream": "=https://yourtenant.sharepoint.com/AllSites.Read", + "description": "SharePoint OAuth scope", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SHAREPOINT_PICKER_GRAPH_SCOPE": { + "category": "SharePoint Integration", + "status": "commented", + "default_upstream": "Files.Read.All", + "description": "Microsoft Graph scope for file downloads", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_ENTRY_POINT": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML identity provider entry point URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_ISSUER": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML service provider entity ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_CERT": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML signing certificate", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_CALLBACK_URL": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": "/oauth/saml/callback", + "description": "SAML authentication callback URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_SESSION_SECRET": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML session storage secret", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_EMAIL_CLAIM": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML assertion email attribute", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_USERNAME_CLAIM": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML assertion username attribute", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_GIVEN_NAME_CLAIM": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML assertion given name attribute", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_FAMILY_NAME_CLAIM": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML assertion family name attribute", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_PICTURE_CLAIM": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML assertion profile picture attribute", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_NAME_CLAIM": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML assertion full name attribute", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_BUTTON_LABEL": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML login button label", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_IMAGE_URL": { + "category": "SharePoint Integration", + "status": "active", + "default_upstream": null, + "description": "SAML login button image URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SAML_USE_AUTHN_RESPONSE_SIGNED": { + "category": "SharePoint Integration", + "status": "commented", + "default_upstream": null, + "description": "Sign entire SAML Response", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "USE_ENTRA_ID_FOR_PEOPLE_SEARCH": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": "false", + "description": "Enable Entra ID people search", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ENTRA_ID_INCLUDE_OWNERS_AS_MEMBERS": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": "false", + "description": "Include group owners as members", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENID_GRAPH_SCOPES": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": "User.Read,People.Read,GroupMember.Read.All", + "description": "Microsoft Graph API scopes", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_URL": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": null, + "description": "LDAP server URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_BIND_DN": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": null, + "description": "LDAP bind DN", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_BIND_CREDENTIALS": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": null, + "description": "LDAP bind password", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_USER_SEARCH_BASE": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": null, + "description": "LDAP user search base", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_SEARCH_FILTER": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": "\"mail=\"", + "description": "LDAP search filter", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_CA_CERT_PATH": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "active", + "default_upstream": null, + "description": "LDAP CA certificate path", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_TLS_REJECT_UNAUTHORIZED": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": null, + "description": "LDAP TLS certificate verification", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_STARTTLS": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": null, + "description": "Enable LDAP StartTLS", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_LOGIN_USES_USERNAME": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": "true", + "description": "Use username instead of email for LDAP login", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_ID": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": null, + "description": "LDAP attribute for unique user ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_USERNAME": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": null, + "description": "LDAP attribute for username", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_EMAIL": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": null, + "description": "LDAP attribute for email", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LDAP_FULL_NAME": { + "category": "Microsoft Graph API / Entra ID Integration", + "status": "commented", + "default_upstream": null, + "description": "LDAP attribute(s) for full name", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_SERVICE": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": null, + "description": "Email service provider (e.g. gmail, sendgrid)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_HOST": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": null, + "description": "SMTP mail server host", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_PORT": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": "25", + "description": "SMTP mail server port", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_ENCRYPTION": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": null, + "description": "Email encryption method (starttls, tls, none)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_ENCRYPTION_HOSTNAME": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": null, + "description": "Hostname for email encryption verification", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_ALLOW_SELFSIGNED": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": null, + "description": "Allow self-signed TLS certificates", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_USERNAME": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": null, + "description": "SMTP authentication username", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_PASSWORD": { + "category": "Email Password Reset", + "status": "active", + "default_upstream": null, + "description": "SMTP authentication password", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_FROM_NAME": { + "category": "Mailgun API", + "status": "commented", + "default_upstream": "\"LibreChat\"", + "description": "From display name for outgoing mail", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "EMAIL_FROM": { + "category": "Mailgun API", + "status": "commented", + "default_upstream": "noreply@yourdomain.com", + "description": "From email address for outgoing mail", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MAILGUN_API_KEY": { + "category": "Mailgun API", + "status": "commented", + "default_upstream": "your-mailgun-api-key", + "description": "Mailgun API key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MAILGUN_DOMAIN": { + "category": "Mailgun API", + "status": "commented", + "default_upstream": "mg.yourdomain.com", + "description": "Mailgun domain", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MAILGUN_HOST": { + "category": "Mailgun API", + "status": "commented", + "default_upstream": "https://api.eu.mailgun.net", + "description": "Custom Mailgun API host (EU region)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIREBASE_API_KEY": { + "category": "Firebase CDN", + "status": "active", + "default_upstream": null, + "description": "Firebase API key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIREBASE_AUTH_DOMAIN": { + "category": "Firebase CDN", + "status": "active", + "default_upstream": null, + "description": "Firebase Auth domain", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIREBASE_PROJECT_ID": { + "category": "Firebase CDN", + "status": "active", + "default_upstream": null, + "description": "Firebase project ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIREBASE_STORAGE_BUCKET": { + "category": "Firebase CDN", + "status": "active", + "default_upstream": null, + "description": "Firebase storage bucket", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIREBASE_MESSAGING_SENDER_ID": { + "category": "Firebase CDN", + "status": "active", + "default_upstream": null, + "description": "Firebase Cloud Messaging sender ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIREBASE_APP_ID": { + "category": "Firebase CDN", + "status": "active", + "default_upstream": null, + "description": "Firebase App ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AWS_ENDPOINT_URL": { + "category": "S3 AWS Bucket", + "status": "active", + "default_upstream": null, + "description": "Custom endpoint URL for S3-compatible services", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AWS_ACCESS_KEY_ID": { + "category": "S3 AWS Bucket", + "status": "active", + "default_upstream": null, + "description": "AWS IAM user access key ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AWS_SECRET_ACCESS_KEY": { + "category": "S3 AWS Bucket", + "status": "active", + "default_upstream": null, + "description": "AWS IAM user secret access key", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AWS_REGION": { + "category": "S3 AWS Bucket", + "status": "active", + "default_upstream": null, + "description": "AWS region for S3 bucket", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AWS_BUCKET_NAME": { + "category": "S3 AWS Bucket", + "status": "active", + "default_upstream": null, + "description": "S3 bucket name", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AWS_FORCE_PATH_STYLE": { + "category": "S3 AWS Bucket", + "status": "commented", + "default_upstream": "false", + "description": "Force path-style URLs for S3-compatible services", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_STORAGE_CONNECTION_STRING": { + "category": "Azure Blob Storage", + "status": "active", + "default_upstream": null, + "description": "Azure Blob Storage connection string", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_STORAGE_PUBLIC_ACCESS": { + "category": "Azure Blob Storage", + "status": "active", + "default_upstream": "false", + "description": "Enable public access for Azure blobs", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "AZURE_CONTAINER_NAME": { + "category": "Azure Blob Storage", + "status": "active", + "default_upstream": "files", + "description": "Azure Blob container name", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_SHARED_LINKS": { + "category": "Shared Links", + "status": "active", + "default_upstream": "true", + "description": "Enable shared conversation links", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ALLOW_SHARED_LINKS_PUBLIC": { + "category": "Shared Links", + "status": "active", + "default_upstream": "false", + "description": "Allow public access to shared links", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "STATIC_CACHE_MAX_AGE": { + "category": "Static File Cache Control", + "status": "commented", + "default_upstream": "172800", + "description": "Cache-Control max-age in seconds for static files", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "STATIC_CACHE_S_MAX_AGE": { + "category": "Static File Cache Control", + "status": "commented", + "default_upstream": "86400", + "description": "Cache-Control s-maxage in seconds for shared caches", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "DISABLE_COMPRESSION": { + "category": "Static File Cache Control", + "status": "commented", + "default_upstream": "true", + "description": "Disables compression for static files", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ENABLE_IMAGE_OUTPUT_GZIP_SCAN": { + "category": "Static File Cache Control", + "status": "commented", + "default_upstream": "true", + "description": "Enables serving gzipped versions of uploaded images", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "APP_TITLE": { + "category": "UI", + "status": "active", + "default_upstream": "LibreChat", + "description": "Application title shown in UI", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CUSTOM_FOOTER": { + "category": "UI", + "status": "commented", + "default_upstream": "\"My custom footer\"", + "description": "Custom footer text", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "HELP_AND_FAQ_URL": { + "category": "UI", + "status": "active", + "default_upstream": "https://librechat.ai", + "description": "URL for the Help and FAQ button", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SHOW_BIRTHDAY_ICON": { + "category": "UI", + "status": "commented", + "default_upstream": "true", + "description": "Show birthday hat icon on special dates", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "ANALYTICS_GTM_ID": { + "category": "UI", + "status": "commented", + "default_upstream": "user provided google tag manager id", + "description": "Google Tag Manager ID", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES": { + "category": "UI", + "status": "commented", + "default_upstream": "262144000", + "description": "Max file size in bytes for conversation imports", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "USE_REDIS": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "true", + "description": "Enable Redis for caching", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "USE_REDIS_STREAMS": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "true", + "description": "Enable Redis for resumable streams", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_URI": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "rediss://127.0.0.1:6380", + "description": "Redis connection URI", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_CA": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "/path/to/ca-cert.pem", + "description": "Path to CA certificate for Redis TLS", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_USE_ALTERNATIVE_DNS_LOOKUP": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "true", + "description": "Enable alternate DNS lookup for Redis TLS", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_USERNAME": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "your_redis_username", + "description": "Redis username for authentication", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_PASSWORD": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "your_redis_password", + "description": "Redis password for authentication", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_KEY_PREFIX_VAR": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "K_REVISION", + "description": "Environment variable for dynamic Redis key prefix", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_KEY_PREFIX": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "librechat", + "description": "Static prefix for Redis keys", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_MAX_LISTENERS": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "40", + "description": "Maximum event listeners per Redis client", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "REDIS_PING_INTERVAL": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "300", + "description": "Redis ping interval in seconds", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FORCED_IN_MEMORY_CACHE_NAMESPACES": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "CONFIG_STORE,APP_CONFIG", + "description": "Cache namespaces to force in-memory storage", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LEADER_LEASE_DURATION": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "25", + "description": "Leader lease validity duration in seconds", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LEADER_RENEW_INTERVAL": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "10", + "description": "Leader lease renewal interval in seconds", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LEADER_RENEW_ATTEMPTS": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "3", + "description": "Max lease renewal retry attempts", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LEADER_RENEW_RETRY_DELAY": { + "category": "REDIS Options", + "status": "commented", + "default_upstream": "0.5", + "description": "Delay between renewal retries in seconds", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "NODE_ENV": { + "category": "Others", + "status": "commented", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "E2E_USER_EMAIL": { + "category": "Others", + "status": "commented", + "default_upstream": null, + "description": null, + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "E2E_USER_PASSWORD": { + "category": "Others", + "status": "commented", + "default_upstream": null, + "description": "E2E_USER_EMAIL=", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "INDEX_CACHE_CONTROL": { + "category": "Cache Headers", + "status": "commented", + "default_upstream": "no-cache, no-store, must-revalidate", + "description": "Cache-Control header for index.html", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "INDEX_PRAGMA": { + "category": "Cache Headers", + "status": "commented", + "default_upstream": "no-cache", + "description": "Pragma header for index.html", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "INDEX_EXPIRES": { + "category": "Cache Headers", + "status": "commented", + "default_upstream": "0", + "description": "Expires header for index.html", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "OPENWEATHER_API_KEY": { + "category": "OpenWeather", + "status": "active", + "default_upstream": null, + "description": "OpenWeather API key for One Call API 3.0", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "LIBRECHAT_CODE_API_KEY": { + "category": "LibreChat Code Interpreter API", + "status": "commented", + "default_upstream": "your-key", + "description": "API key for Code Interpreter service", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "SERPER_API_KEY": { + "category": "Web Search", + "status": "commented", + "default_upstream": "your_serper_api_key", + "description": "API key for Serper search provider", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIRECRAWL_API_KEY": { + "category": "Web Search", + "status": "commented", + "default_upstream": "your_firecrawl_api_key", + "description": "API key for Firecrawl scraper service", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "FIRECRAWL_API_URL": { + "category": "Web Search", + "status": "commented", + "default_upstream": "your_firecrawl_api_url", + "description": "Custom Firecrawl API URL", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "JINA_API_KEY": { + "category": "Web Search", + "status": "commented", + "default_upstream": "your_jina_api_key", + "description": "API key for Jina reranker service", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_OAUTH_ON_AUTH_ERROR": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "true", + "description": "Treat 401/403 responses as OAuth requirement", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_OAUTH_DETECTION_TIMEOUT": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "5000", + "description": "OAuth detection timeout in milliseconds", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CONNECTION_CHECK_TTL": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "60000", + "description": "Cache TTL for MCP connection checks", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_SKIP_CODE_CHALLENGE_CHECK": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "false", + "description": "Skip OAuth code challenge validation", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CB_MAX_CYCLES": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "7", + "description": "Circuit breaker: max connect/disconnect cycles before tripping (per server)", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CB_CYCLE_WINDOW_MS": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "45000", + "description": "Circuit breaker: sliding window (ms) for counting cycles", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CB_CYCLE_COOLDOWN_MS": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "15000", + "description": "Circuit breaker: cooldown (ms) after the cycle breaker trips", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CB_MAX_FAILED_ROUNDS": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "3", + "description": "Circuit breaker: max consecutive failed connection rounds before backoff", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CB_FAILED_WINDOW_MS": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "120000", + "description": "Circuit breaker: sliding window (ms) for counting failed rounds", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CB_BASE_BACKOFF_MS": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "30000", + "description": "Circuit breaker: base backoff (ms) after failed round threshold is reached", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + }, + "MCP_CB_MAX_BACKOFF_MS": { + "category": "MCP Configuration", + "status": "commented", + "default_upstream": "300000", + "description": "Circuit breaker: max backoff cap (ms) for exponential backoff", + "deprecated": false, + "hardcoded": false, + "selection": "unknown", + "file_target": null, + "custom_value": null, + "mandatory": false, + "depends_on": [] + } + } +} diff --git a/scripts/bootstrap.py b/scripts/bootstrap.py index 5b54fe8..613903e 100644 --- a/scripts/bootstrap.py +++ b/scripts/bootstrap.py @@ -1,239 +1,149 @@ +#!/usr/bin/env python3 +"""Bootstrap script - generates .env.alfred, .env.librechat, .env.secrets and .env.make.""" + +import re import secrets +import sys from pathlib import Path import tomllib -from config_loader import load_build_config, write_env_make + +BASE_DIR = Path(__file__).resolve().parent.parent + +def load_secrets_spec(toml_data: dict) -> dict[str, tuple[int, str]]: + """Load secrets spec from pyproject.toml [tool.alfred.secrets].""" + raw = toml_data.get("tool", {}).get("alfred", {}).get("secrets", {}) + result = {} + for key, rule in raw.items(): + size_str, fmt = rule.split(":") + result[key] = (int(size_str), fmt) + return result -def generate_secret(rule: str) -> str: - """ - Generates a cryptographically secure secret based on a spec string. - Example specs: '32:b64', '16:hex'. - """ - chunks: list[str] = rule.split(":") - size: int = int(chunks[0]) - tech: str = chunks[1] +def generate_secret(size: int, fmt: str) -> str: + match fmt: + case "hex": + return secrets.token_hex(size) + case "b64": + return secrets.token_urlsafe(size) + case _: + raise ValueError(f"Unknown format: {fmt}") - if tech == "b64": - return secrets.token_urlsafe(size) - elif tech == "hex": - return secrets.token_hex(size) + +def load_env_file(path: Path) -> dict[str, str]: + """Load key=value pairs from an env file, ignoring comments and blanks.""" + result = {} + if not path.exists(): + return result + for line in path.read_text().splitlines(): + stripped = line.strip() + if stripped and not stripped.startswith("#") and "=" in stripped: + key, _, value = stripped.partition("=") + result[key.strip()] = value.strip() + return result + + +def copy_example_if_missing(src: Path, dst: Path, label: str) -> None: + """Copy src to dst only if dst doesn't exist yet.""" + if dst.exists(): + print(f" ↻ {dst.name} already exists, skipping") + return + if not src.exists(): + print(f" ⚠ {label} example not found at {src} — skipping (add it manually)") + return + dst.write_text(src.read_text()) + print(f" + {dst.name} created from {src.name}") + + +def generate_secrets_file(path: Path, secrets_spec: dict[str, tuple[int, str]]) -> None: + """Generate .env.secrets with missing secrets, never overwrite existing ones.""" + existing = load_env_file(path) + lines = list(path.read_text().splitlines()) if path.exists() else [ + "# Auto-generated secrets — DO NOT COMMIT", + "# Run 'make bootstrap' to generate missing secrets", + "", + ] + + added = [] + for key, (size, fmt) in secrets_spec.items(): + if key not in existing: + value = generate_secret(size, fmt) + lines.append(f"{key}={value}") + added.append(key) + + path.write_text("\n".join(lines) + "\n") + + if added: + print(f" + Generated: {', '.join(added)}") else: - raise ValueError(f"Invalid security format: {tech}") + print(" ↻ All secrets already exist, nothing generated") def extract_python_version(version_string: str) -> tuple[str, str]: - """ - Extract Python version from poetry dependency string. - Examples: - "==3.14.2" -> ("3.14.2", "3.14") - "^3.14.2" -> ("3.14.2", "3.14") - "~3.14.2" -> ("3.14.2", "3.14") - "3.14.2" -> ("3.14.2", "3.14") - """ - import re # noqa: PLC0415 - - # Remove poetry version operators (==, ^, ~, >=, etc.) - clean_version = re.sub(r"^[=^~><]+", "", version_string.strip()) - - # Extract version parts - parts = clean_version.split(".") - + clean = re.sub(r"^[=^~><]+", "", version_string.strip()) + parts = clean.split(".") if len(parts) >= 2: - full_version = clean_version - short_version = f"{parts[0]}.{parts[1]}" - return full_version, short_version - else: - raise ValueError(f"Invalid Python version format: {version_string}") + return clean, f"{parts[0]}.{parts[1]}" + raise ValueError(f"Invalid Python version: {version_string}") -# TODO: Refactor -def bootstrap(): # noqa: PLR0912, PLR0915 - """ - Initializes the .env file by merging .env.example with generated secrets - and build variables from pyproject.toml. - Also generates .env.make for Makefile. +def write_env_make(toml_data: dict) -> None: + """Write .env.make from pyproject.toml.""" + project = toml_data["project"] + alfred = toml_data["tool"]["alfred"] - ALWAYS preserves existing secrets! - """ - base_dir = Path(__file__).resolve().parent.parent - env_path = base_dir / ".env" + python_full, python_short = extract_python_version(project["requires-python"]) - example_path = base_dir / ".env.example" - if not example_path.exists(): - print(f"❌ {example_path.name} not found.") - return + lines = [ + "# Auto-generated from pyproject.toml — do not edit manually", + f"export ALFRED_VERSION={project['version']}", + f"export PYTHON_VERSION={python_full}", + f"export PYTHON_VERSION_SHORT={python_short}", + f"export IMAGE_NAME={alfred['image_name']}", + f"export SERVICE_NAME={alfred['service_name']}", + f"export LIBRECHAT_VERSION={alfred['librechat_version']}", + f"export RAG_VERSION={alfred['rag_version']}", + f"export UV_VERSION={alfred['uv_version']}", + ] - toml_path = base_dir / "pyproject.toml" + env_make_path = BASE_DIR / ".env.make" + env_make_path.write_text("\n".join(lines) + "\n") + print(f" + {env_make_path.name} written") + + +def main() -> int: + print("🚀 Starting bootstrap...") + + toml_path = BASE_DIR / "pyproject.toml" if not toml_path.exists(): - print(f"❌ {toml_path.name} not found.") - return + print(f"❌ pyproject.toml not found: {toml_path}") + return 1 - # ALWAYS load existing .env if it exists - existing_env = {} - if env_path.exists(): - print("🔄 Reading existing .env...") - with open(env_path) as f: - for line in f: - if "=" in line and not line.strip().startswith("#"): - key, value = line.split("=", 1) - existing_env[key.strip()] = value.strip() - print(f" Found {len(existing_env)} existing keys") - print("🔧 Updating .env file (keeping secrets)...") - else: - print("🔧 Initializing: Creating secure .env file...") - - # Load data from pyproject.toml with open(toml_path, "rb") as f: - data = tomllib.load(f) - security_keys = data["tool"]["alfred"]["security"] - settings_keys = data["tool"]["alfred"]["settings"] - dependencies = data["tool"]["poetry"]["dependencies"] - alfred_version = data["tool"]["poetry"]["version"] + toml_data = tomllib.load(f) - # Normalize TOML keys to UPPER_CASE for .env format (done once) - security_keys_upper = {k.upper(): v for k, v in security_keys.items()} - settings_keys_upper = {k.upper(): v for k, v in settings_keys.items()} - - # Extract Python version - python_version_full, python_version_short = extract_python_version( - dependencies["python"] + print("\n📄 Env files:") + copy_example_if_missing( + src=BASE_DIR / ".env.example", + dst=BASE_DIR / ".env.alfred", + label="Alfred", + ) + copy_example_if_missing( + src=BASE_DIR / "librechat" / ".env.example", + dst=BASE_DIR / ".env.librechat", + label="LibreChat", ) - # Read .env.example - with open(example_path) as f: - example_lines = f.readlines() + secrets_spec = load_secrets_spec(toml_data) + print("\n🔐 Secrets:") + generate_secrets_file(BASE_DIR / ".env.secrets", secrets_spec) - new_lines = [] - # Process each line from .env.example - for raw_line in example_lines: - line = raw_line.strip() + print("\n🔧 Build config:") + write_env_make(toml_data) - if line and not line.startswith("#") and "=" in line: - key, value = line.split("=", 1) - key = key.strip() - - # Check if key exists in current .env (update mode) - if key in existing_env: - # Keep existing value for secrets - if key in security_keys_upper: - new_lines.append(f"{key}={existing_env[key]}\n") - print(f" ↻ Kept existing {key}") - # Update build vars from pyproject.toml - elif key in settings_keys_upper: - new_value = settings_keys_upper[key] - if existing_env[key] != new_value: - new_lines.append(f"{key}={new_value}\n") - print(f" ↻ Updated {key}: {existing_env[key]} → {new_value}") - else: - new_lines.append(f"{key}={existing_env[key]}\n") - print(f" ↻ Kept {key}={existing_env[key]}") - # Update Python versions - elif key == "PYTHON_VERSION": - if existing_env[key] != python_version_full: - new_lines.append(f"{key}={python_version_full}\n") - print( - f" ↻ Updated Python: {existing_env[key]} → {python_version_full}" - ) - else: - new_lines.append(f"{key}={existing_env[key]}\n") - print(f" ↻ Kept Python: {existing_env[key]}") - elif key == "PYTHON_VERSION_SHORT": - if existing_env[key] != python_version_short: - new_lines.append(f"{key}={python_version_short}\n") - print( - f" ↻ Updated Python (short): {existing_env[key]} → {python_version_short}" - ) - else: - new_lines.append(f"{key}={existing_env[key]}\n") - print(f" ↻ Kept Python (short): {existing_env[key]}") - elif key == "ALFRED_VERSION": - if existing_env.get(key) != alfred_version: - new_lines.append(f"{key}={alfred_version}\n") - print( - f" ↻ Updated Alfred version: {existing_env.get(key, 'N/A')} → {alfred_version}" - ) - else: - new_lines.append(f"{key}={alfred_version}\n") - print(f" ↻ Kept Alfred version: {alfred_version}") - # Keep other existing values - else: - new_lines.append(f"{key}={existing_env[key]}\n") - # Key doesn't exist, generate/add it - elif key in security_keys_upper: - rule = security_keys_upper[key] - secret = generate_secret(rule) - new_lines.append(f"{key}={secret}\n") - print(f" + Secret generated for {key} ({rule})") - elif key in settings_keys_upper: - value = settings_keys_upper[key] - new_lines.append(f"{key}={value}\n") - print(f" + Setting added: {key}={value}") - elif key == "PYTHON_VERSION": - new_lines.append(f"{key}={python_version_full}\n") - print(f" + Python version: {python_version_full}") - elif key == "PYTHON_VERSION_SHORT": - new_lines.append(f"{key}={python_version_short}\n") - print(f" + Python version (short): {python_version_short}") - elif key == "ALFRED_VERSION": - new_lines.append(f"{key}={alfred_version}\n") - print(f" + Alfred version: {alfred_version}") - else: - new_lines.append(raw_line) - else: - # Keep comments and empty lines - new_lines.append(raw_line) - - # Compute database URIs from the generated values - final_env = {} - for line in new_lines: - if "=" in line and not line.strip().startswith("#"): - key, value = line.split("=", 1) - final_env[key.strip()] = value.strip() - - # Compute MONGO_URI - if "MONGO_USER" in final_env and "MONGO_PASSWORD" in final_env: - mongo_uri = ( - f"mongodb://{final_env.get('MONGO_USER', 'alfred')}:" - f"{final_env.get('MONGO_PASSWORD', '')}@" - f"{final_env.get('MONGO_HOST', 'mongodb')}:" - f"{final_env.get('MONGO_PORT', '27017')}/" - f"{final_env.get('MONGO_DB_NAME', 'alfred')}?authSource=admin" - ) - # Update MONGO_URI in new_lines - for i, line in enumerate(new_lines): - if line.startswith("MONGO_URI="): - new_lines[i] = f"MONGO_URI={mongo_uri}\n" - print(" ✓ Computed MONGO_URI") - break - - # Compute POSTGRES_URI - if "POSTGRES_USER" in final_env and "POSTGRES_PASSWORD" in final_env: - postgres_uri = ( - f"postgresql://{final_env.get('POSTGRES_USER', 'alfred')}:" - f"{final_env.get('POSTGRES_PASSWORD', '')}@" - f"{final_env.get('POSTGRES_HOST', 'vectordb')}:" - f"{final_env.get('POSTGRES_PORT', '5432')}/" - f"{final_env.get('POSTGRES_DB_NAME', 'alfred')}" - ) - # Update POSTGRES_URI in new_lines - for i, line in enumerate(new_lines): - if line.startswith("POSTGRES_URI="): - new_lines[i] = f"POSTGRES_URI={postgres_uri}\n" - print(" ✓ Computed POSTGRES_URI") - break - - # Write .env file - with open(env_path, "w", encoding="utf-8") as f: - f.writelines(new_lines) - print(f"\n✅ {env_path.name} generated successfully.") - - # Generate .env.make for Makefile using shared config loader - config = load_build_config(base_dir) - write_env_make(config, base_dir) - print("✅ .env.make generated for Makefile.") - print("\n⚠️ Reminder: Please manually add your API keys to the .env file.") + print("\n✅ Bootstrap complete!") + return 0 if __name__ == "__main__": - bootstrap() + sys.exit(main()) diff --git a/scripts/config_loader.py b/scripts/config_loader.py index e558e14..dabc210 100644 --- a/scripts/config_loader.py +++ b/scripts/config_loader.py @@ -1,4 +1,4 @@ -"""Shared configuration loader for bootstrap and CI.""" +"""Shared configuration loader — reads build config from pyproject.toml.""" import re from pathlib import Path @@ -13,31 +13,25 @@ class BuildConfig(NamedTuple): alfred_version: str python_version: str python_version_short: str - runner: str image_name: str service_name: str librechat_version: str rag_version: str + uv_version: str def extract_python_version(version_string: str) -> tuple[str, str]: """ - Extract Python version from poetry dependency string. + Extract Python version from uv dependency string. Examples: "==3.14.2" -> ("3.14.2", "3.14") - "^3.14.2" -> ("3.14.2", "3.14") - "~3.14.2" -> ("3.14.2", "3.14") - "3.14.2" -> ("3.14.2", "3.14") + "^3.14.2" -> ("3.14.2", "3.14") """ - clean_version = re.sub(r"^[=^~><]+", "", version_string.strip()) - parts = clean_version.split(".") - + clean = re.sub(r"^[=^~><]+", "", version_string.strip()) + parts = clean.split(".") if len(parts) >= 2: - full_version = clean_version - short_version = f"{parts[0]}.{parts[1]}" - return full_version, short_version - else: - raise ValueError(f"Invalid Python version format: {version_string}") + return clean, f"{parts[0]}.{parts[1]}" + raise ValueError(f"Invalid Python version format: {version_string}") def load_build_config(base_dir: Path | None = None) -> BuildConfig: @@ -51,23 +45,21 @@ def load_build_config(base_dir: Path | None = None) -> BuildConfig: with open(toml_path, "rb") as f: data = tomllib.load(f) - settings_keys = data["tool"]["alfred"]["settings"] - dependencies = data["tool"]["poetry"]["dependencies"] - alfred_version = data["tool"]["poetry"]["version"] - python_version_full, python_version_short = extract_python_version( - dependencies["python"] - ) + project = data["project"] + alfred = data["tool"]["alfred"] + + python_full, python_short = extract_python_version(project["requires-python"]) return BuildConfig( - alfred_version=alfred_version, - python_version=python_version_full, - python_version_short=python_version_short, - runner=settings_keys["runner"], - image_name=settings_keys["image_name"], - service_name=settings_keys["service_name"], - librechat_version=settings_keys["librechat_version"], - rag_version=settings_keys["rag_version"], + alfred_version=project["version"], + python_version=python_full, + python_version_short=python_short, + image_name=alfred["image_name"], + service_name=alfred["service_name"], + librechat_version=alfred["librechat_version"], + rag_version=alfred["rag_version"], + uv_version=alfred["uv_version"], ) @@ -76,14 +68,17 @@ def write_env_make(config: BuildConfig, base_dir: Path | None = None) -> None: if base_dir is None: base_dir = Path(__file__).resolve().parent.parent + lines = [ + "# Auto-generated from pyproject.toml — do not edit manually", + f"export ALFRED_VERSION={config.alfred_version}", + f"export PYTHON_VERSION={config.python_version}", + f"export PYTHON_VERSION_SHORT={config.python_version_short}", + f"export IMAGE_NAME={config.image_name}", + f"export SERVICE_NAME={config.service_name}", + f"export LIBRECHAT_VERSION={config.librechat_version}", + f"export RAG_VERSION={config.rag_version}", + f"export UV_VERSION={config.uv_version}", + ] + env_make_path = base_dir / ".env.make" - with open(env_make_path, "w", encoding="utf-8") as f: - f.write("# Auto-generated from pyproject.toml\n") - f.write(f"export ALFRED_VERSION={config.alfred_version}\n") - f.write(f"export PYTHON_VERSION={config.python_version}\n") - f.write(f"export PYTHON_VERSION_SHORT={config.python_version_short}\n") - f.write(f"export RUNNER={config.runner}\n") - f.write(f"export IMAGE_NAME={config.image_name}\n") - f.write(f"export SERVICE_NAME={config.service_name}\n") - f.write(f"export LIBRECHAT_VERSION={config.librechat_version}\n") - f.write(f"export RAG_VERSION={config.rag_version}\n") + env_make_path.write_text("\n".join(lines) + "\n") diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..e56dc0b --- /dev/null +++ b/uv.lock @@ -0,0 +1,779 @@ +version = 1 +revision = 3 +requires-python = "==3.14.3" + +[[package]] +name = "alfred" +version = "0.1.7" +source = { virtual = "." } +dependencies = [ + { name = "click" }, + { name = "fastapi" }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "python-dotenv" }, + { name = "requests" }, + { name = "uvicorn" }, +] + +[package.dev-dependencies] +dev = [ + { name = "bump-my-version" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-xdist" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "click", specifier = "~=8.1" }, + { name = "fastapi", specifier = "~=0.127.1" }, + { name = "httpx", specifier = "~=0.28.1" }, + { name = "pydantic", specifier = "~=2.12.4" }, + { name = "pydantic-settings", specifier = "~=2.12.0" }, + { name = "python-dotenv", specifier = "~=1.0.0" }, + { name = "requests", specifier = "~=2.32.5" }, + { name = "uvicorn", specifier = "~=0.40.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "bump-my-version", specifier = "~=1.2.5" }, + { name = "pre-commit", specifier = "~=4.5.1" }, + { name = "pytest", specifier = "~=8.0.0" }, + { name = "pytest-asyncio", specifier = "~=0.23.0" }, + { name = "pytest-cov", specifier = "~=4.1.0" }, + { name = "pytest-xdist", specifier = "~=3.8.0" }, + { name = "ruff", specifier = "~=0.14.7" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, +] + +[[package]] +name = "bracex" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/9a/fec38644694abfaaeca2798b58e276a8e61de49e2e37494ace423395febc/bracex-2.6.tar.gz", hash = "sha256:98f1347cd77e22ee8d967a30ad4e310b233f7754dbf31ff3fceb76145ba47dc7", size = 26642, upload-time = "2025-06-22T19:12:31.254Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/2a/9186535ce58db529927f6cf5990a849aa9e052eea3e2cfefe20b9e1802da/bracex-2.6-py3-none-any.whl", hash = "sha256:0b0049264e7340b3ec782b5cb99beb325f36c3782a32e36e876452fd49a09952", size = 11508, upload-time = "2025-06-22T19:12:29.781Z" }, +] + +[[package]] +name = "bump-my-version" +version = "1.2.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "questionary" }, + { name = "rich" }, + { name = "rich-click" }, + { name = "tomlkit" }, + { name = "wcmatch" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/45/11/0f73c652396f86197ea6d509c78e8c44c3483d9a86437ca53ce55edca8e8/bump_my_version-1.2.7.tar.gz", hash = "sha256:d915a10b41e0c9db5a2fa39bde9f45f92e1e4194242d819c9ceb9eca8831cd21", size = 1198071, upload-time = "2026-02-14T13:44:59.923Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/ed/ad1755f82cd5a0baafe342e7154696a93e57f04f86515402f14e5beceb36/bump_my_version-1.2.7-py3-none-any.whl", hash = "sha256:16f89360f979c0a8eb3249ebe3e13ae4f0cb5481d7bb58e12a9f66996922acfd", size = 60013, upload-time = "2026-02-14T13:44:58.318Z" }, +] + +[[package]] +name = "certifi" +version = "2026.4.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, + { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, + { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, + { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, + { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, + { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, + { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, + { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, + { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, + { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, + { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, + { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, + { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, + { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, + { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, + { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, + { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, + { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, + { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, + { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, + { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, + { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, +] + +[[package]] +name = "click" +version = "8.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coverage" +version = "7.13.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hash = "sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179", size = 915967, upload-time = "2026-03-17T10:33:18.341Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f", size = 219621, upload-time = "2026-03-17T10:32:08.589Z" }, + { url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e", size = 219953, upload-time = "2026-03-17T10:32:10.507Z" }, + { url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a", size = 250992, upload-time = "2026-03-17T10:32:12.41Z" }, + { url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510", size = 253503, upload-time = "2026-03-17T10:32:14.449Z" }, + { url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247", size = 254852, upload-time = "2026-03-17T10:32:16.56Z" }, + { url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6", size = 257161, upload-time = "2026-03-17T10:32:19.004Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0", size = 251021, upload-time = "2026-03-17T10:32:21.344Z" }, + { url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882", size = 252858, upload-time = "2026-03-17T10:32:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740", size = 250823, upload-time = "2026-03-17T10:32:25.516Z" }, + { url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16", size = 255099, upload-time = "2026-03-17T10:32:27.944Z" }, + { url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0", size = 250638, upload-time = "2026-03-17T10:32:29.914Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0", size = 252295, upload-time = "2026-03-17T10:32:31.981Z" }, + { url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl", hash = "sha256:35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc", size = 222360, upload-time = "2026-03-17T10:32:34.233Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633", size = 223174, upload-time = "2026-03-17T10:32:36.369Z" }, + { url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl", hash = "sha256:1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8", size = 221739, upload-time = "2026-03-17T10:32:38.736Z" }, + { url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b", size = 220351, upload-time = "2026-03-17T10:32:41.196Z" }, + { url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c", size = 220612, upload-time = "2026-03-17T10:32:43.204Z" }, + { url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9", size = 261985, upload-time = "2026-03-17T10:32:45.514Z" }, + { url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29", size = 264107, upload-time = "2026-03-17T10:32:47.971Z" }, + { url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607", size = 266513, upload-time = "2026-03-17T10:32:50.1Z" }, + { url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90", size = 267650, upload-time = "2026-03-17T10:32:52.391Z" }, + { url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3", size = 261089, upload-time = "2026-03-17T10:32:54.544Z" }, + { url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab", size = 263982, upload-time = "2026-03-17T10:32:56.803Z" }, + { url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562", size = 261579, upload-time = "2026-03-17T10:32:59.466Z" }, + { url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2", size = 265316, upload-time = "2026-03-17T10:33:01.847Z" }, + { url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea", size = 260427, upload-time = "2026-03-17T10:33:03.945Z" }, + { url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a", size = 262745, upload-time = "2026-03-17T10:33:06.285Z" }, + { url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl", hash = "sha256:0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215", size = 223146, upload-time = "2026-03-17T10:33:08.756Z" }, + { url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43", size = 224254, upload-time = "2026-03-17T10:33:11.174Z" }, + { url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl", hash = "sha256:9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45", size = 222276, upload-time = "2026-03-17T10:33:13.466Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346, upload-time = "2026-03-17T10:33:15.691Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "execnet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, +] + +[[package]] +name = "fastapi" +version = "0.127.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/8a/6b9ba6eb8ff3817caae83120495965d9e70afb4d6348cb120e464ee199f4/fastapi-0.127.1.tar.gz", hash = "sha256:946a87ee5d931883b562b6bada787d6c8178becee2683cb3f9b980d593206359", size = 391876, upload-time = "2025-12-26T13:04:47.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/f3/a6858d147ed2645c095d11dc2440f94a5f1cd8f4df888e3377e6b5281a0f/fastapi-0.127.1-py3-none-any.whl", hash = "sha256:31d670a4f9373cc6d7994420f98e4dc46ea693145207abc39696746c83a44430", size = 112332, upload-time = "2025-12-26T13:04:45.329Z" }, +] + +[[package]] +name = "filelock" +version = "3.29.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/fe/997687a931ab51049acce6fa1f23e8f01216374ea81374ddee763c493db5/filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90", size = 57571, upload-time = "2026-04-19T15:39:10.068Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258", size = 39812, upload-time = "2026-04-19T15:39:08.752Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "identify" +version = "2.6.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567, upload-time = "2026-04-17T18:39:50.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" }, +] + +[[package]] +name = "idna" +version = "3.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "packaging" +version = "26.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/de/0d2b39fb4af88a0258f3bac87dfcbb48e73fbdea4a2ed0e2213f9a4c2f9a/packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de", size = 215519, upload-time = "2026-04-14T21:12:49.362Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232, upload-time = "2025-12-16T21:14:33.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437, upload-time = "2025-12-16T21:14:32.409Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "8.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3f/c0/238f25cb27495fdbaa5c48cef9886162e9df1f3d0e957fc8326d9c24fa2f/pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd", size = 1396924, upload-time = "2024-02-24T22:21:30.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/ea/d0ab9595a0d4b2320483e634123171deaf50885e29d442180efcbf2ed0b2/pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096", size = 333984, upload-time = "2024-02-24T22:21:27.561Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "0.23.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/b4/0b378b7bf26a8ae161c3890c0b48a91a04106c5713ce81b4b080ea2f4f18/pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3", size = 46920, upload-time = "2024-07-17T17:39:34.617Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2", size = 17663, upload-time = "2024-07-17T17:39:32.478Z" }, +] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/15/da3df99fd551507694a9b01f512a2f6cf1254f33601605843c3775f39460/pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", size = 63245, upload-time = "2023-05-24T18:44:56.845Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/4b/8b78d126e275efa2379b1c2e09dc52cf70df16fc3b90613ef82531499d73/pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a", size = 21949, upload-time = "2023-05-24T18:44:54.079Z" }, +] + +[[package]] +name = "pytest-xdist" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, +] + +[[package]] +name = "python-discovery" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/ef/3bae0e537cfe91e8431efcba4434463d2c5a65f5a89edd47c6cf2f03c55f/python_discovery-1.2.2.tar.gz", hash = "sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb", size = 58872, upload-time = "2026-04-07T17:28:49.249Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl", hash = "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size = 31894, upload-time = "2026-04-07T17:28:48.09Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115, upload-time = "2024-01-23T06:33:00.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863, upload-time = "2024-01-23T06:32:58.246Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "questionary" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "prompt-toolkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/45/eafb0bba0f9988f6a2520f9ca2df2c82ddfa8d67c95d6625452e97b204a5/questionary-2.1.1.tar.gz", hash = "sha256:3d7e980292bb0107abaa79c68dd3eee3c561b83a0f89ae482860b181c8bd412d", size = 25845, upload-time = "2025-08-28T19:00:20.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl", hash = "sha256:a51af13f345f1cdea62347589fbb6df3b290306ab8930713bfae4d475a7d4a59", size = 36753, upload-time = "2025-08-28T19:00:19.56Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "rich-click" +version = "1.9.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/27/091e140ea834272188e63f8dd6faac1f5c687582b687197b3e0ec3c78ebf/rich_click-1.9.7.tar.gz", hash = "sha256:022997c1e30731995bdbc8ec2f82819340d42543237f033a003c7b1f843fc5dc", size = 74838, upload-time = "2026-01-31T04:29:27.707Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/e5/d708d262b600a352abe01c2ae360d8ff75b0af819b78e9af293191d928e6/rich_click-1.9.7-py3-none-any.whl", hash = "sha256:2f99120fca78f536e07b114d3b60333bc4bb2a0969053b1250869bcdc1b5351b", size = 71491, upload-time = "2026-01-31T04:29:26.777Z" }, +] + +[[package]] +name = "ruff" +version = "0.14.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/06/f71e3a86b2df0dfa2d2f72195941cd09b44f87711cb7fa5193732cb9a5fc/ruff-0.14.14.tar.gz", hash = "sha256:2d0f819c9a90205f3a867dbbd0be083bee9912e170fd7d9704cc8ae45824896b", size = 4515732, upload-time = "2026-01-22T22:30:17.527Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/89/20a12e97bc6b9f9f68343952da08a8099c57237aef953a56b82711d55edd/ruff-0.14.14-py3-none-linux_armv6l.whl", hash = "sha256:7cfe36b56e8489dee8fbc777c61959f60ec0f1f11817e8f2415f429552846aed", size = 10467650, upload-time = "2026-01-22T22:30:08.578Z" }, + { url = "https://files.pythonhosted.org/packages/a3/b1/c5de3fd2d5a831fcae21beda5e3589c0ba67eec8202e992388e4b17a6040/ruff-0.14.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6006a0082336e7920b9573ef8a7f52eec837add1265cc74e04ea8a4368cd704c", size = 10883245, upload-time = "2026-01-22T22:30:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7c/3c1db59a10e7490f8f6f8559d1db8636cbb13dccebf18686f4e3c9d7c772/ruff-0.14.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:026c1d25996818f0bf498636686199d9bd0d9d6341c9c2c3b62e2a0198b758de", size = 10231273, upload-time = "2026-01-22T22:30:34.642Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6e/5e0e0d9674be0f8581d1f5e0f0a04761203affce3232c1a1189d0e3b4dad/ruff-0.14.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f666445819d31210b71e0a6d1c01e24447a20b85458eea25a25fe8142210ae0e", size = 10585753, upload-time = "2026-01-22T22:30:31.781Z" }, + { url = "https://files.pythonhosted.org/packages/23/09/754ab09f46ff1884d422dc26d59ba18b4e5d355be147721bb2518aa2a014/ruff-0.14.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c0f18b922c6d2ff9a5e6c3ee16259adc513ca775bcf82c67ebab7cbd9da5bc8", size = 10286052, upload-time = "2026-01-22T22:30:24.827Z" }, + { url = "https://files.pythonhosted.org/packages/c8/cc/e71f88dd2a12afb5f50733851729d6b571a7c3a35bfdb16c3035132675a0/ruff-0.14.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1629e67489c2dea43e8658c3dba659edbfd87361624b4040d1df04c9740ae906", size = 11043637, upload-time = "2026-01-22T22:30:13.239Z" }, + { url = "https://files.pythonhosted.org/packages/67/b2/397245026352494497dac935d7f00f1468c03a23a0c5db6ad8fc49ca3fb2/ruff-0.14.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:27493a2131ea0f899057d49d303e4292b2cae2bb57253c1ed1f256fbcd1da480", size = 12194761, upload-time = "2026-01-22T22:30:22.542Z" }, + { url = "https://files.pythonhosted.org/packages/5b/06/06ef271459f778323112c51b7587ce85230785cd64e91772034ddb88f200/ruff-0.14.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01ff589aab3f5b539e35db38425da31a57521efd1e4ad1ae08fc34dbe30bd7df", size = 12005701, upload-time = "2026-01-22T22:30:20.499Z" }, + { url = "https://files.pythonhosted.org/packages/41/d6/99364514541cf811ccc5ac44362f88df66373e9fec1b9d1c4cc830593fe7/ruff-0.14.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc12d74eef0f29f51775f5b755913eb523546b88e2d733e1d701fe65144e89b", size = 11282455, upload-time = "2026-01-22T22:29:59.679Z" }, + { url = "https://files.pythonhosted.org/packages/ca/71/37daa46f89475f8582b7762ecd2722492df26421714a33e72ccc9a84d7a5/ruff-0.14.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb8481604b7a9e75eff53772496201690ce2687067e038b3cc31aaf16aa0b974", size = 11215882, upload-time = "2026-01-22T22:29:57.032Z" }, + { url = "https://files.pythonhosted.org/packages/2c/10/a31f86169ec91c0705e618443ee74ede0bdd94da0a57b28e72db68b2dbac/ruff-0.14.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:14649acb1cf7b5d2d283ebd2f58d56b75836ed8c6f329664fa91cdea19e76e66", size = 11180549, upload-time = "2026-01-22T22:30:27.175Z" }, + { url = "https://files.pythonhosted.org/packages/fd/1e/c723f20536b5163adf79bdd10c5f093414293cdf567eed9bdb7b83940f3f/ruff-0.14.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e8058d2145566510790eab4e2fad186002e288dec5e0d343a92fe7b0bc1b3e13", size = 10543416, upload-time = "2026-01-22T22:30:01.964Z" }, + { url = "https://files.pythonhosted.org/packages/3e/34/8a84cea7e42c2d94ba5bde1d7a4fae164d6318f13f933d92da6d7c2041ff/ruff-0.14.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e651e977a79e4c758eb807f0481d673a67ffe53cfa92209781dfa3a996cf8412", size = 10285491, upload-time = "2026-01-22T22:30:29.51Z" }, + { url = "https://files.pythonhosted.org/packages/55/ef/b7c5ea0be82518906c978e365e56a77f8de7678c8bb6651ccfbdc178c29f/ruff-0.14.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cc8b22da8d9d6fdd844a68ae937e2a0adf9b16514e9a97cc60355e2d4b219fc3", size = 10733525, upload-time = "2026-01-22T22:30:06.499Z" }, + { url = "https://files.pythonhosted.org/packages/6a/5b/aaf1dfbcc53a2811f6cc0a1759de24e4b03e02ba8762daabd9b6bd8c59e3/ruff-0.14.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:16bc890fb4cc9781bb05beb5ab4cd51be9e7cb376bf1dd3580512b24eb3fda2b", size = 11315626, upload-time = "2026-01-22T22:30:36.848Z" }, + { url = "https://files.pythonhosted.org/packages/2c/aa/9f89c719c467dfaf8ad799b9bae0df494513fb21d31a6059cb5870e57e74/ruff-0.14.14-py3-none-win32.whl", hash = "sha256:b530c191970b143375b6a68e6f743800b2b786bbcf03a7965b06c4bf04568167", size = 10502442, upload-time = "2026-01-22T22:30:38.93Z" }, + { url = "https://files.pythonhosted.org/packages/87/44/90fa543014c45560cae1fffc63ea059fb3575ee6e1cb654562197e5d16fb/ruff-0.14.14-py3-none-win_amd64.whl", hash = "sha256:3dde1435e6b6fe5b66506c1dff67a421d0b7f6488d466f651c07f4cab3bf20fd", size = 11630486, upload-time = "2026-01-22T22:30:10.852Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6a/40fee331a52339926a92e17ae748827270b288a35ef4a15c9c8f2ec54715/ruff-0.14.14-py3-none-win_arm64.whl", hash = "sha256:56e6981a98b13a32236a72a8da421d7839221fa308b223b9283312312e5ac76c", size = 10920448, upload-time = "2026-01-22T22:30:15.417Z" }, +] + +[[package]] +name = "starlette" +version = "0.50.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, +] + +[[package]] +name = "tomlkit" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/af/14b24e41977adb296d6bd1fb59402cf7d60ce364f90c890bd2ec65c43b5a/tomlkit-0.14.0.tar.gz", hash = "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064", size = 187167, upload-time = "2026-01-13T01:14:53.304Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl", hash = "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680", size = 39310, upload-time = "2026-01-13T01:14:51.965Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/d1/8f3c683c9561a4e6689dd3b1d345c815f10f86acd044ee1fb9a4dcd0b8c5/uvicorn-0.40.0.tar.gz", hash = "sha256:839676675e87e73694518b5574fd0f24c9d97b46bea16df7b8c05ea1a51071ea", size = 81761, upload-time = "2025-12-21T14:16:22.45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/d8/2083a1daa7439a66f3a48589a57d576aa117726762618f6bb09fe3798796/uvicorn-0.40.0-py3-none-any.whl", hash = "sha256:c6c8f55bc8bf13eb6fa9ff87ad62308bbbc33d0b67f84293151efe87e0d5f2ee", size = 68502, upload-time = "2025-12-21T14:16:21.041Z" }, +] + +[[package]] +name = "virtualenv" +version = "21.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "python-discovery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/98/3a7e644e19cb26133488caff231be390579860bbbb3da35913c49a1d0a46/virtualenv-21.2.4.tar.gz", hash = "sha256:b294ef68192638004d72524ce7ef303e9d0cf5a44c95ce2e54a7500a6381cada", size = 5850742, upload-time = "2026-04-14T22:15:31.438Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/8d/edd0bd910ff803c308ee9a6b7778621af0d10252219ad9f19ef4d4982a61/virtualenv-21.2.4-py3-none-any.whl", hash = "sha256:29d21e941795206138d0f22f4e45ff7050e5da6c6472299fb7103318763861ac", size = 5831232, upload-time = "2026-04-14T22:15:29.342Z" }, +] + +[[package]] +name = "wcmatch" +version = "10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bracex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/3e/c0bdc27cf06f4e47680bd5803a07cb3dfd17de84cde92dd217dcb9e05253/wcmatch-10.1.tar.gz", hash = "sha256:f11f94208c8c8484a16f4f48638a85d771d9513f4ab3f37595978801cb9465af", size = 117421, upload-time = "2025-06-22T19:14:02.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/d8/0d1d2e9d3fabcf5d6840362adcf05f8cf3cd06a73358140c3a97189238ae/wcmatch-10.1-py3-none-any.whl", hash = "sha256:5848ace7dbb0476e5e55ab63c6bbd529745089343427caa5537f230cc01beb8a", size = 39854, upload-time = "2025-06-22T19:14:00.978Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, +]