O módulo config é o centro de configurações do Fluxi. Ele gerencia todas as configurações globais do sistema, incluindo chaves de API, parâmetros de LLM, configurações de agentes padrão, e preferências gerais. Funciona como um sistema de chave-valor tipado, onde cada configuração tem um tipo (string, int, float, bool, json) e uma categoria organizacional.
Centralizar e gerenciar todas as configurações do sistema de forma:
- Tipada - Cada configuração tem um tipo específico (string, int, float, bool, json)
- Categorizada - Organizadas por categoria (geral, openrouter, agente, llm, rag)
- Editável - Controle fino sobre quais configurações podem ser editadas
- Persistente - Armazenadas em banco de dados SQLite
- Acessível - API e interface web para gerenciamento
- Validada - Validação de tipos e valores
config/
├── __init__.py # Inicialização do módulo
├── config_model.py # Modelo SQLAlchemy (tabela configuracoes)
├── config_schema.py # Schemas Pydantic (validação)
├── config_service.py # Lógica de negócio e CRUD
├── config_router.py # Endpoints REST API
├── config_frontend_router.py # Rotas de interface web
├── rag_config.py # Configurações específicas de RAG
└── README.md # Esta documentação
Define a estrutura da tabela de configurações:
| Campo | Tipo | Descrição |
|---|---|---|
id |
Integer | ID único da configuração |
chave |
String(100) | Chave única (ex: "openrouter_api_key") |
valor |
Text | Valor armazenado como string |
tipo |
String(50) | Tipo do valor: string, int, float, bool, json |
descricao |
Text | Descrição da configuração |
categoria |
String(50) | Categoria: geral, openrouter, whatsapp, agente, llm, rag |
editavel |
Boolean | Se pode ser editada via interface |
criado_em |
DateTime | Data de criação |
atualizado_em |
DateTime | Data de atualização |
Validação de dados usando Pydantic:
ConfiguracaoBase: Schema base com campos comunsConfiguracaoCriar: Para criar nova configuraçãoConfiguracaoAtualizar: Para atualizar (valor e descrição)ConfiguracaoResposta: Resposta da APIModeloLLM: Schema para modelos LLM disponíveisTestarConexaoResposta: Resposta ao testar conexão com OpenRouter
Lógica de negócio completa para gerenciamento de configurações.
Leitura:
obter_por_chave(chave)- Busca configuração por chaveobter_valor(chave, padrao)- MAIS USADA: Obtém valor convertido para tipo corretolistar_por_categoria(categoria)- Lista configurações de uma categorialistar_todas()- Lista todas as configurações
Escrita:
criar(config)- Cria nova configuraçãoatualizar(chave, config)- Atualiza configuração existentedefinir_valor(chave, valor)- Define valor (cria se não existir)deletar(chave)- Remove configuração
Especializadas:
testar_conexao_openrouter(api_key)- Testa conexão e busca modelos disponíveisinicializar_configuracoes_padrao()- Cria configurações padrão na inicialização
O método obter_valor() converte automaticamente:
# int
config.tipo == "int" → int(config.valor)
# float
config.tipo == "float" → float(config.valor)
# bool
config.tipo == "bool" → valor.lower() in ("true", "1", "sim", "yes")
# json
config.tipo == "json" → json.loads(config.valor)
# string
config.tipo == "string" → config.valor (sem conversão)Endpoints REST para gerenciamento:
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/configuracoes/ |
Lista todas as configurações |
| GET | /api/configuracoes/categoria/{cat} |
Lista por categoria |
| GET | /api/configuracoes/{chave} |
Obtém configuração específica |
| POST | /api/configuracoes/ |
Cria nova configuração |
| PUT | /api/configuracoes/{chave} |
Atualiza configuração |
| DELETE | /api/configuracoes/{chave} |
Deleta configuração |
| POST | /api/configuracoes/openrouter/testar |
Testa conexão OpenRouter |
Interface web para gerenciar configurações:
| Rota | Descrição | Template |
|---|---|---|
GET /configuracoes/ |
Página de configurações | config/settings.html |
POST /configuracoes/salvar-openrouter |
Salva config OpenRouter | Redirect |
POST /configuracoes/salvar-parametros-llm |
Salva parâmetros LLM | Redirect |
POST /configuracoes/salvar-agente |
Salva config agente padrão | Redirect |
POST /configuracoes/salvar-geral |
Salva config gerais | Redirect |
POST /configuracoes/salvar-provedores-llm |
Salva provedores LLM | Redirect |
Configurações específicas para o sistema RAG (Retrieval-Augmented Generation).
- OpenAI - text-embedding-3-small, text-embedding-3-large
- Cohere - embed-english-v3.0, embed-multilingual-v3.0
- HuggingFace - sentence-transformers (vários modelos)
- Google - models/embedding-001, text-embedding-004
{
"model": "text-embedding-3-small", # Modelo de embedding
"chunk_size": 1000, # Tamanho do chunk (100-5000)
"chunk_overlap": 200, # Sobreposição (0-1000)
"top_k": 3 # Resultados retornados (1-20)
}get_config(provider)- Obtém configurações de um providerget_default_provider()- Retorna provider padrãoget_available_providers()- Lista providers disponíveisget_provider_models(provider)- Lista modelos do providervalidate_config(config)- Valida configurações
# Em main.py, evento startup
ConfiguracaoService.inicializar_configuracoes_padrao(db)Cria configurações padrão se não existirem:
- Provedores LLM (openrouter, local, fallback)
- OpenRouter (api_key, modelo, temperatura, max_tokens, top_p)
- Agente (papel, objetivo, políticas, tarefa, público, restrições)
- Sistema (diretório uploads, tamanho máx. imagem)
# Exemplo: Obter modelo LLM padrão
from config.config_service import ConfiguracaoService
modelo = ConfiguracaoService.obter_valor(
db,
"openrouter_modelo_padrao",
"google/gemini-2.0-flash-001" # Valor padrão se não encontrar
)
# Retorna: "google/gemini-2.0-flash-001" (string)
# Exemplo: Obter temperatura (float)
temperatura = ConfiguracaoService.obter_valor(
db,
"openrouter_temperatura",
0.7
)
# Retorna: 0.7 (float, já convertido)
# Exemplo: Obter max_tokens (int)
max_tokens = ConfiguracaoService.obter_valor(
db,
"openrouter_max_tokens",
2000
)
# Retorna: 2000 (int, já convertido)# Método 1: Atualizar existente
ConfiguracaoService.atualizar(
db,
"openrouter_api_key",
ConfiguracaoAtualizar(valor="sk-or-v1-abc123...")
)
# Método 2: Definir valor (cria se não existe)
ConfiguracaoService.definir_valor(
db,
"openrouter_temperatura",
0.9 # Tipo detectado automaticamente
)# Via service
resultado = await ConfiguracaoService.testar_conexao_openrouter(
db,
api_key="sk-or-v1-abc123..."
)
if resultado.sucesso:
print(f"Conectado! {len(resultado.modelos)} modelos disponíveis")
for modelo in resultado.modelos:
print(f"- {modelo.nome} (contexto: {modelo.contexto} tokens)")
else:
print(f"Erro: {resultado.mensagem}")Configurações de provedores LLM:
llm_provedor_padrao- Provedor padrão (openrouter, local, custom)llm_provedor_local_id- ID do provedor localllm_fallback_openrouter- Usar OpenRouter como fallback
Configurações do OpenRouter:
openrouter_api_key- Chave de APIopenrouter_modelo_padrao- Modelo padrão (ex: google/gemini-2.0-flash-001)openrouter_temperatura- Temperatura (0.0 a 2.0)openrouter_max_tokens- Máximo de tokens (ex: 2000)openrouter_top_p- Top P (0.0 a 1.0)
Configurações padrão para novos agentes:
agente_papel_padrao- Papel padrãoagente_objetivo_padrao- Objetivo padrãoagente_politicas_padrao- Políticas padrãoagente_tarefa_padrao- Tarefa padrãoagente_objetivo_explicito_padrao- Objetivo explícito padrãoagente_publico_padrao- Público-alvo padrãoagente_restricoes_padrao- Restrições padrão
Configurações gerais do sistema:
sistema_diretorio_uploads- Diretório de uploads (./uploads)sistema_max_tamanho_imagem_mb- Tamanho máx. de imagem em MB (10)
Configurações RAG por provider:
rag_openai_model- Modelo OpenAIrag_openai_chunk_size- Tamanho do chunkrag_openai_chunk_overlap- Sobreposiçãorag_openai_top_k- Número de resultados- (similar para cohere, huggingface, google)
database- Base do SQLAlchemy- Usado por TODOS os outros módulos para obter configurações
- SQLAlchemy - ORM para persistência
- Pydantic - Validação de schemas
- httpx - Cliente HTTP async (testar OpenRouter)
- FastAPI - Framework web
# Adicionar novas configurações programaticamente
from config.config_schema import ConfiguracaoCriar
ConfiguracaoService.criar(db, ConfiguracaoCriar(
chave="telegram_bot_token",
valor="123456:ABC-DEF...",
tipo="string",
descricao="Token do bot Telegram",
categoria="telegram",
editavel=True
))# Listar todas as configs da categoria 'agente'
configs_agente = ConfiguracaoService.listar_por_categoria(db, "agente")
for config in configs_agente:
print(f"{config.chave}: {config.valor}")from config.rag_config import RAGConfig
# Obter provider padrão
provider = RAGConfig.get_default_provider(db) # "openai"
# Obter config do provider
config = RAGConfig.get_provider_config(db, "openai")
# {
# "model": "text-embedding-3-small",
# "chunk_size": 1000,
# "chunk_overlap": 200,
# "top_k": 3
# }
# Listar modelos disponíveis
modelos = RAGConfig.get_provider_models("openai")
# ["text-embedding-3-small", "text-embedding-3-large", ...]
# Validar configuração
errors = RAGConfig.validate_config({
"chunk_size": 1000,
"chunk_overlap": 200,
"top_k": 3
})
if not errors:
print("Configuração válida!")O usuário acessa /configuracoes e vê formulários organizados por categoria:
<!-- Seção OpenRouter -->
<form action="/configuracoes/salvar-openrouter" method="post">
<input name="api_key" value="{{ config.openrouter_api_key }}">
<input name="modelo_padrao" value="{{ config.openrouter_modelo_padrao }}">
<button name="acao" value="testar">Testar Conexão</button>
<button name="acao" value="salvar">Salvar</button>
</form>Praticamente todos os módulos consultam configurações:
# agente/agente_service.py
modelo = ConfiguracaoService.obter_valor(db, "openrouter_modelo_padrao")
# llm_providers/llm_integration_service.py
provedor_padrao = ConfiguracaoService.obter_valor(db, "llm_provedor_padrao")
# rag/rag_service.py
from config.rag_config import RAGConfig
config = RAGConfig.get_provider_config(db, "openai")
# sessao/sessao_service.py
max_tamanho = ConfiguracaoService.obter_valor(db, "sistema_max_tamanho_imagem_mb")O módulo config armazena:
- Chaves de API de provedores
- Provedor padrão a ser usado
- Configuração de fallback
Testa conexão e busca modelos disponíveis:
- Valida API key
- Lista 200+ modelos LLM
- Detecta suporte a imagens e ferramentas
Configurações específicas via RAGConfig:
- Provider de embeddings (OpenAI, Cohere, HuggingFace, Google)
- Parâmetros de chunking
- Número de resultados
Diferente de um simples dicionário, cada configuração tem:
- Tipo explícito - Garante conversão correta
- Validação - Pydantic valida schemas
- Descrição - Documentação inline
- Categoria - Organização lógica
- Editabilidade - Controle de acesso
- ✅ Configurações podem ser marcadas como não editáveis
- ✅ Valores sensíveis (API keys) armazenados em banco
⚠️ Importante: Use variáveis de ambiente em produção⚠️ Importante: Não versionefluxi.dbcom API keys
- Consultas otimizadas com índice em
chave - Cache poderia ser adicionado para configurações frequentes
- Inicialização rápida (apenas cria se não existir)
Para adicionar nova categoria:
- Adicionar em
inicializar_configuracoes_padrao() - Criar formulário em
templates/config/settings.html - Adicionar rota POST em
config_frontend_router.py - (Opcional) Criar classe helper como
RAGConfig
Sempre forneça valor padrão ao usar obter_valor():
# ✅ BOM - fornece padrão
modelo = ConfiguracaoService.obter_valor(db, "modelo", "gpt-4")
# ❌ EVITE - pode retornar None
modelo = ConfiguracaoService.obter_valor(db, "modelo")Para estruturas complexas:
# Salvar JSON
ConfiguracaoService.definir_valor(
db,
"webhooks",
{
"url": "https://api.example.com/webhook",
"eventos": ["mensagem_recebida", "mensagem_enviada"]
}
)
# Recuperar JSON (já deserializado)
webhooks = ConfiguracaoService.obter_valor(db, "webhooks", {})
print(webhooks["url"]) # "https://api.example.com/webhook"Você pode criar categorias personalizadas:
ConfiguracaoService.criar(db, ConfiguracaoCriar(
chave="discord_webhook_url",
valor="https://discord.com/api/webhooks/...",
tipo="string",
categoria="discord", # Nova categoria!
descricao="Webhook para notificações Discord"
))No startup da aplicação (main.py):
@app.on_event("startup")
def startup_event():
criar_tabelas()
db = SessionLocal()
# Inicializar configurações padrão
ConfiguracaoService.inicializar_configuracoes_padrao(db)
db.close()Isso garante que todas as configurações essenciais existam.
valor = ConfiguracaoService.obter_valor(db, "chave", "padrão")ConfiguracaoService.definir_valor(db, "chave", valor)configs = ConfiguracaoService.listar_por_categoria(db, "categoria")resultado = await ConfiguracaoService.testar_conexao_openrouter(db, api_key)from config.rag_config import RAGConfig
config = RAGConfig.get_provider_config(db, "openai")Módulo criado por: Fluxi Team
Versão: 1.0.0
Última atualização: 2025