text-to-insight 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- text_to_insight-0.1.0/LICENSE +21 -0
- text_to_insight-0.1.0/PKG-INFO +163 -0
- text_to_insight-0.1.0/README.md +107 -0
- text_to_insight-0.1.0/pyproject.toml +102 -0
- text_to_insight-0.1.0/setup.cfg +4 -0
- text_to_insight-0.1.0/tests/test_biblioteca_integracao.py +298 -0
- text_to_insight-0.1.0/tests/test_bird_eval.py +1431 -0
- text_to_insight-0.1.0/tests/test_componentes.py +662 -0
- text_to_insight-0.1.0/tests/test_data_exploration.py +627 -0
- text_to_insight-0.1.0/tests/test_data_exploration_postgres.py +399 -0
- text_to_insight-0.1.0/tests/test_exec_python.py +65 -0
- text_to_insight-0.1.0/tests/test_integracao.py +233 -0
- text_to_insight-0.1.0/tests/test_main_engine_integracao.py +182 -0
- text_to_insight-0.1.0/tests/test_model_selection.py +236 -0
- text_to_insight-0.1.0/tests/test_nodes.py +469 -0
- text_to_insight-0.1.0/tests/test_real_api_smoke.py +10 -0
- text_to_insight-0.1.0/tests/test_spider2_eval.py +1031 -0
- text_to_insight-0.1.0/tests/test_token_tracking.py +504 -0
- text_to_insight-0.1.0/text_to_insight/InsightEngine.py +226 -0
- text_to_insight-0.1.0/text_to_insight/__init__.py +7 -0
- text_to_insight-0.1.0/text_to_insight/cache.py +62 -0
- text_to_insight-0.1.0/text_to_insight/cli.py +242 -0
- text_to_insight-0.1.0/text_to_insight/execucao_python.py +83 -0
- text_to_insight-0.1.0/text_to_insight/graph.py +191 -0
- text_to_insight-0.1.0/text_to_insight/model_selection/__init__.py +19 -0
- text_to_insight-0.1.0/text_to_insight/model_selection/factory.py +25 -0
- text_to_insight-0.1.0/text_to_insight/model_selection/providers.py +24 -0
- text_to_insight-0.1.0/text_to_insight/model_selection/registry.py +145 -0
- text_to_insight-0.1.0/text_to_insight/nodes/__init__.py +42 -0
- text_to_insight-0.1.0/text_to_insight/nodes/code_agent/__init__.py +5 -0
- text_to_insight-0.1.0/text_to_insight/nodes/code_agent/code_agent.py +222 -0
- text_to_insight-0.1.0/text_to_insight/nodes/code_agent/code_sql.py +169 -0
- text_to_insight-0.1.0/text_to_insight/nodes/csv_saver.py +42 -0
- text_to_insight-0.1.0/text_to_insight/nodes/data_exploration.py +1098 -0
- text_to_insight-0.1.0/text_to_insight/nodes/enrich_schema.py +89 -0
- text_to_insight-0.1.0/text_to_insight/nodes/graph_generator.py +150 -0
- text_to_insight-0.1.0/text_to_insight/nodes/planner.py +171 -0
- text_to_insight-0.1.0/text_to_insight/nodes/response.py +150 -0
- text_to_insight-0.1.0/text_to_insight/nodes/retriever.py +76 -0
- text_to_insight-0.1.0/text_to_insight/nodes/sandbox.py +76 -0
- text_to_insight-0.1.0/text_to_insight/nodes/schema.py +264 -0
- text_to_insight-0.1.0/text_to_insight/retriever/RAG_example.py +306 -0
- text_to_insight-0.1.0/text_to_insight/retriever/__init__.py +7 -0
- text_to_insight-0.1.0/text_to_insight/retriever/engine.py +52 -0
- text_to_insight-0.1.0/text_to_insight/retriever/graph_logic.py +115 -0
- text_to_insight-0.1.0/text_to_insight/retriever/rag_logic.py +70 -0
- text_to_insight-0.1.0/text_to_insight/routers/__init__.py +17 -0
- text_to_insight-0.1.0/text_to_insight/routers/edges.py +190 -0
- text_to_insight-0.1.0/text_to_insight/runtime.py +498 -0
- text_to_insight-0.1.0/text_to_insight/state.py +96 -0
- text_to_insight-0.1.0/text_to_insight/token_tracking.py +140 -0
- text_to_insight-0.1.0/text_to_insight/utils.py +42 -0
- text_to_insight-0.1.0/text_to_insight.egg-info/PKG-INFO +163 -0
- text_to_insight-0.1.0/text_to_insight.egg-info/SOURCES.txt +56 -0
- text_to_insight-0.1.0/text_to_insight.egg-info/dependency_links.txt +1 -0
- text_to_insight-0.1.0/text_to_insight.egg-info/entry_points.txt +2 -0
- text_to_insight-0.1.0/text_to_insight.egg-info/requires.txt +35 -0
- text_to_insight-0.1.0/text_to_insight.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Caio Petroncini and TextToInsight contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: text-to-insight
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Agentes LangGraph que transformam perguntas em linguagem natural em consultas SQL seguras, executadas no seu banco, com resposta em linguagem natural
|
|
5
|
+
Author: Caio Petroncini, Julio Cesar Fuganti, Luiz Correia dos Santos, Antonio Carvalho, Bernardo Rubio, Jonas Honorato
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/gruporaia/TextToInsight
|
|
8
|
+
Project-URL: Documentation, https://github.com/gruporaia/TextToInsight#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/gruporaia/TextToInsight.git
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/gruporaia/TextToInsight/issues
|
|
11
|
+
Keywords: text-to-sql,nl2sql,llm,langgraph,rag,sql,agentes
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Database
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: langgraph>=1.1
|
|
25
|
+
Requires-Dist: langchain>=1.2
|
|
26
|
+
Requires-Dist: langchain-core>=1.2
|
|
27
|
+
Requires-Dist: langchain-google-genai>=4.2
|
|
28
|
+
Requires-Dist: langchain-openai>=1.1
|
|
29
|
+
Requires-Dist: pydantic>=2.0
|
|
30
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
31
|
+
Requires-Dist: pandas>=2.2.2
|
|
32
|
+
Requires-Dist: matplotlib>=3.9.0
|
|
33
|
+
Requires-Dist: networkx>=3.0
|
|
34
|
+
Requires-Dist: chromadb>=1.5.9
|
|
35
|
+
Requires-Dist: tabulate>=0.10.0
|
|
36
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
37
|
+
Requires-Dist: platformdirs>=3.0
|
|
38
|
+
Provides-Extra: postgres
|
|
39
|
+
Requires-Dist: psycopg2-binary>=2.9.0; extra == "postgres"
|
|
40
|
+
Provides-Extra: mysql
|
|
41
|
+
Requires-Dist: pymysql>=1.1.0; extra == "mysql"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-recording>=0.13.0; extra == "dev"
|
|
46
|
+
Requires-Dist: aiohttp<3.10.0; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest-timeout>=2.3.0; extra == "dev"
|
|
48
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
49
|
+
Requires-Dist: isort>=5.12; extra == "dev"
|
|
50
|
+
Requires-Dist: flake8>=6.0; extra == "dev"
|
|
51
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
52
|
+
Provides-Extra: docs
|
|
53
|
+
Requires-Dist: sphinx>=5.0; extra == "docs"
|
|
54
|
+
Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
|
|
55
|
+
Dynamic: license-file
|
|
56
|
+
|
|
57
|
+
# Text-to-Insight
|
|
58
|
+
|
|
59
|
+
Biblioteca Python que transforma perguntas em linguagem natural em consultas SQL seguras, executadas no seu banco, com resposta final em linguagem natural (e gráfico, quando fizer sentido).
|
|
60
|
+
|
|
61
|
+
O fluxo é um grafo de agentes em [LangGraph](https://github.com/langchain-ai/langgraph): lê o schema do banco, seleciona as tabelas relevantes (GraphRAG), calcula estatísticas das colunas, gera a SQL, executa em modo somente leitura, corrige a si mesmo em caso de erro e responde. Opcionalmente pausa para pedir esclarecimentos ao usuário (human-in-the-loop).
|
|
62
|
+
|
|
63
|
+
## Instalação
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install text-to-insight
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
SQLite funciona sem nada extra. Para PostgreSQL ou MySQL, instale o driver junto:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install "text-to-insight[postgres]" # psycopg2
|
|
73
|
+
pip install "text-to-insight[mysql]" # pymysql
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Modelos suportados: Gemini (`GOOGLE_API_KEY`) e OpenAI (`OPENAI_API_KEY`).
|
|
77
|
+
|
|
78
|
+
## Uso como biblioteca
|
|
79
|
+
|
|
80
|
+
A biblioteca **não abre conexões com o banco**. Você cria uma [Engine do SQLAlchemy](https://docs.sqlalchemy.org/en/20/core/engines.html), passa para a `InsightEngine` e continua sendo dono dela (pool, credenciais, `dispose()`). A engine nunca entra no estado do grafo, então nada sobre a conexão vai para o checkpoint do LangGraph.
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from sqlalchemy import create_engine
|
|
84
|
+
from text_to_insight import InsightEngine
|
|
85
|
+
|
|
86
|
+
# SQLite em modo somente leitura
|
|
87
|
+
db = create_engine("sqlite:///file:dados/loja.db?mode=ro&uri=true")
|
|
88
|
+
# PostgreSQL: create_engine("postgresql+psycopg2://usuario:senha@host:5432/banco")
|
|
89
|
+
|
|
90
|
+
engine = InsightEngine(
|
|
91
|
+
api_key="...",
|
|
92
|
+
model="gemini-2.5-flash", # ou "gpt-5-mini", "openai/gpt-4o", ...
|
|
93
|
+
db_engine=db,
|
|
94
|
+
hitl=True,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
resultado = engine.run(thread_id="sessao_1", query="Quantos pedidos existem no banco?")
|
|
98
|
+
|
|
99
|
+
if resultado.get("status") == "AWAITING_USER":
|
|
100
|
+
print(resultado["message"]) # pergunta do agente para o usuário
|
|
101
|
+
resultado = engine.resume(thread_id="sessao_1", user_response="Considere só pedidos entregues.")
|
|
102
|
+
|
|
103
|
+
print(resultado["sql_gerada"])
|
|
104
|
+
print(resultado["resposta_natural"])
|
|
105
|
+
|
|
106
|
+
db.dispose()
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Toda SQL gerada passa por uma validação (apenas `SELECT`/`WITH`, uma única instrução, sem comandos de escrita ou de leitura de arquivos) e roda com timeout. Mesmo assim, use um usuário de banco com permissão só de leitura.
|
|
110
|
+
|
|
111
|
+
### Opções da `InsightEngine`
|
|
112
|
+
|
|
113
|
+
| Parâmetro | Padrão | O que faz |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `db_engine` | obrigatório | Engine do SQLAlchemy do banco a consultar. |
|
|
116
|
+
| `hitl` | `False` | Permite que o agente pause e peça esclarecimentos (`AWAITING_USER`). |
|
|
117
|
+
| `use_rag` | `True` | Seleciona só as tabelas relevantes quando o schema é grande (GraphRAG). |
|
|
118
|
+
| `enrich_rag` | `False` | Gera, com o LLM, descrições curtas das colunas antes do RAG. O resultado fica em cache. |
|
|
119
|
+
| `use_data_exploration` | `True` | Inclui estatísticas das colunas no prompt (SQLite e PostgreSQL; outros bancos pulam esta etapa). |
|
|
120
|
+
| `use_exploration_selector` | `"off"` | Escolhe quais colunas explorar: `"off"`, `"llm"` ou `"rag"`. |
|
|
121
|
+
| `use_cot` | `True` | Pede raciocínio passo a passo antes da SQL. |
|
|
122
|
+
| `inferir_fks_virtuais` | `False` | Infere chaves estrangeiras por nome (`*_id`) quando o banco não as declara. |
|
|
123
|
+
| `enable_graphs` | `True` | Gera um gráfico (matplotlib) quando a visualização for útil. |
|
|
124
|
+
| `model_kwargs` | `None` | Parâmetros do LLM, ex.: `{"temperature": 0}`. |
|
|
125
|
+
| `cache_dir` | pasta de cache do usuário | Onde ficam o schema enriquecido e o índice do ChromaDB. |
|
|
126
|
+
|
|
127
|
+
Por padrão o cache fica em `~/.cache/text-to-insight` (Linux), `~/Library/Caches/text-to-insight` (macOS) ou `%LOCALAPPDATA%\text-to-insight\Cache` (Windows). O schema enriquecido é indexado pelo conteúdo do schema: se o banco mudar, ele é gerado de novo.
|
|
128
|
+
|
|
129
|
+
### Resultado
|
|
130
|
+
|
|
131
|
+
`run` e `resume` devolvem o estado final do grafo. Os campos mais úteis:
|
|
132
|
+
|
|
133
|
+
- `status`: `"aprovado"`, `"exec_erro"`, `"AWAITING_USER"` ou `"bloqueado_hitl"`;
|
|
134
|
+
- `sql_gerada`, `linhas_resultado_completo`, `total_linhas_resultado`;
|
|
135
|
+
- `resposta_natural`: resposta em linguagem natural;
|
|
136
|
+
- `caminho_csv_resultado`, `caminho_grafico`: caminhos do CSV com o resultado completo e do gráfico, quando gerado;
|
|
137
|
+
- `tokens_input`, `tokens_output`, `tokens_total`, `tokens_by_node`: uso de tokens.
|
|
138
|
+
|
|
139
|
+
API pública: `text_to_insight.InsightEngine`, `text_to_insight.Graph`, `text_to_insight.EstadoTextToInsight`.
|
|
140
|
+
|
|
141
|
+
## Uso via linha de comando
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
export GOOGLE_API_KEY=...
|
|
145
|
+
|
|
146
|
+
# arquivo SQLite (aberto somente leitura)
|
|
147
|
+
text-to-insight --db-path dados/loja.db --model gemini-2.5-flash --api-key-env GOOGLE_API_KEY \
|
|
148
|
+
"Quais categorias vendem mais?"
|
|
149
|
+
|
|
150
|
+
# qualquer banco via URL (também lida de DATABASE_URL)
|
|
151
|
+
text-to-insight --db-url postgresql://usuario:senha@host:5432/banco --hitl off \
|
|
152
|
+
"Qual o ticket médio por estado?"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`text-to-insight --help` lista as demais opções (`--hitl`, `--enrich-rag`, `--infer-fks`, `--cot`, `--data-exploration`, `--exploration-selector`, `--temperature`, `--max-tokens`).
|
|
156
|
+
|
|
157
|
+
## Desenvolvimento
|
|
158
|
+
|
|
159
|
+
- [Guia de desenvolvimento e testes](https://github.com/gruporaia/TextToInsight/blob/main/docs/DESENVOLVIMENTO.md)
|
|
160
|
+
- [Arquitetura](https://github.com/gruporaia/TextToInsight/blob/main/docs/ARQUITETURA.md)
|
|
161
|
+
- Benchmarks: [BIRD](https://github.com/gruporaia/TextToInsight/blob/main/docs/BENCHMARK_BIRD.md), [Spider 1.0 e 2.0](https://github.com/gruporaia/TextToInsight/blob/main/docs/BENCHMARK_SPIDER.md)
|
|
162
|
+
|
|
163
|
+
Desenvolvido pelo grupo RAIA (USP). Licença MIT.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Text-to-Insight
|
|
2
|
+
|
|
3
|
+
Biblioteca Python que transforma perguntas em linguagem natural em consultas SQL seguras, executadas no seu banco, com resposta final em linguagem natural (e gráfico, quando fizer sentido).
|
|
4
|
+
|
|
5
|
+
O fluxo é um grafo de agentes em [LangGraph](https://github.com/langchain-ai/langgraph): lê o schema do banco, seleciona as tabelas relevantes (GraphRAG), calcula estatísticas das colunas, gera a SQL, executa em modo somente leitura, corrige a si mesmo em caso de erro e responde. Opcionalmente pausa para pedir esclarecimentos ao usuário (human-in-the-loop).
|
|
6
|
+
|
|
7
|
+
## Instalação
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install text-to-insight
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
SQLite funciona sem nada extra. Para PostgreSQL ou MySQL, instale o driver junto:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install "text-to-insight[postgres]" # psycopg2
|
|
17
|
+
pip install "text-to-insight[mysql]" # pymysql
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Modelos suportados: Gemini (`GOOGLE_API_KEY`) e OpenAI (`OPENAI_API_KEY`).
|
|
21
|
+
|
|
22
|
+
## Uso como biblioteca
|
|
23
|
+
|
|
24
|
+
A biblioteca **não abre conexões com o banco**. Você cria uma [Engine do SQLAlchemy](https://docs.sqlalchemy.org/en/20/core/engines.html), passa para a `InsightEngine` e continua sendo dono dela (pool, credenciais, `dispose()`). A engine nunca entra no estado do grafo, então nada sobre a conexão vai para o checkpoint do LangGraph.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from sqlalchemy import create_engine
|
|
28
|
+
from text_to_insight import InsightEngine
|
|
29
|
+
|
|
30
|
+
# SQLite em modo somente leitura
|
|
31
|
+
db = create_engine("sqlite:///file:dados/loja.db?mode=ro&uri=true")
|
|
32
|
+
# PostgreSQL: create_engine("postgresql+psycopg2://usuario:senha@host:5432/banco")
|
|
33
|
+
|
|
34
|
+
engine = InsightEngine(
|
|
35
|
+
api_key="...",
|
|
36
|
+
model="gemini-2.5-flash", # ou "gpt-5-mini", "openai/gpt-4o", ...
|
|
37
|
+
db_engine=db,
|
|
38
|
+
hitl=True,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
resultado = engine.run(thread_id="sessao_1", query="Quantos pedidos existem no banco?")
|
|
42
|
+
|
|
43
|
+
if resultado.get("status") == "AWAITING_USER":
|
|
44
|
+
print(resultado["message"]) # pergunta do agente para o usuário
|
|
45
|
+
resultado = engine.resume(thread_id="sessao_1", user_response="Considere só pedidos entregues.")
|
|
46
|
+
|
|
47
|
+
print(resultado["sql_gerada"])
|
|
48
|
+
print(resultado["resposta_natural"])
|
|
49
|
+
|
|
50
|
+
db.dispose()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Toda SQL gerada passa por uma validação (apenas `SELECT`/`WITH`, uma única instrução, sem comandos de escrita ou de leitura de arquivos) e roda com timeout. Mesmo assim, use um usuário de banco com permissão só de leitura.
|
|
54
|
+
|
|
55
|
+
### Opções da `InsightEngine`
|
|
56
|
+
|
|
57
|
+
| Parâmetro | Padrão | O que faz |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `db_engine` | obrigatório | Engine do SQLAlchemy do banco a consultar. |
|
|
60
|
+
| `hitl` | `False` | Permite que o agente pause e peça esclarecimentos (`AWAITING_USER`). |
|
|
61
|
+
| `use_rag` | `True` | Seleciona só as tabelas relevantes quando o schema é grande (GraphRAG). |
|
|
62
|
+
| `enrich_rag` | `False` | Gera, com o LLM, descrições curtas das colunas antes do RAG. O resultado fica em cache. |
|
|
63
|
+
| `use_data_exploration` | `True` | Inclui estatísticas das colunas no prompt (SQLite e PostgreSQL; outros bancos pulam esta etapa). |
|
|
64
|
+
| `use_exploration_selector` | `"off"` | Escolhe quais colunas explorar: `"off"`, `"llm"` ou `"rag"`. |
|
|
65
|
+
| `use_cot` | `True` | Pede raciocínio passo a passo antes da SQL. |
|
|
66
|
+
| `inferir_fks_virtuais` | `False` | Infere chaves estrangeiras por nome (`*_id`) quando o banco não as declara. |
|
|
67
|
+
| `enable_graphs` | `True` | Gera um gráfico (matplotlib) quando a visualização for útil. |
|
|
68
|
+
| `model_kwargs` | `None` | Parâmetros do LLM, ex.: `{"temperature": 0}`. |
|
|
69
|
+
| `cache_dir` | pasta de cache do usuário | Onde ficam o schema enriquecido e o índice do ChromaDB. |
|
|
70
|
+
|
|
71
|
+
Por padrão o cache fica em `~/.cache/text-to-insight` (Linux), `~/Library/Caches/text-to-insight` (macOS) ou `%LOCALAPPDATA%\text-to-insight\Cache` (Windows). O schema enriquecido é indexado pelo conteúdo do schema: se o banco mudar, ele é gerado de novo.
|
|
72
|
+
|
|
73
|
+
### Resultado
|
|
74
|
+
|
|
75
|
+
`run` e `resume` devolvem o estado final do grafo. Os campos mais úteis:
|
|
76
|
+
|
|
77
|
+
- `status`: `"aprovado"`, `"exec_erro"`, `"AWAITING_USER"` ou `"bloqueado_hitl"`;
|
|
78
|
+
- `sql_gerada`, `linhas_resultado_completo`, `total_linhas_resultado`;
|
|
79
|
+
- `resposta_natural`: resposta em linguagem natural;
|
|
80
|
+
- `caminho_csv_resultado`, `caminho_grafico`: caminhos do CSV com o resultado completo e do gráfico, quando gerado;
|
|
81
|
+
- `tokens_input`, `tokens_output`, `tokens_total`, `tokens_by_node`: uso de tokens.
|
|
82
|
+
|
|
83
|
+
API pública: `text_to_insight.InsightEngine`, `text_to_insight.Graph`, `text_to_insight.EstadoTextToInsight`.
|
|
84
|
+
|
|
85
|
+
## Uso via linha de comando
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
export GOOGLE_API_KEY=...
|
|
89
|
+
|
|
90
|
+
# arquivo SQLite (aberto somente leitura)
|
|
91
|
+
text-to-insight --db-path dados/loja.db --model gemini-2.5-flash --api-key-env GOOGLE_API_KEY \
|
|
92
|
+
"Quais categorias vendem mais?"
|
|
93
|
+
|
|
94
|
+
# qualquer banco via URL (também lida de DATABASE_URL)
|
|
95
|
+
text-to-insight --db-url postgresql://usuario:senha@host:5432/banco --hitl off \
|
|
96
|
+
"Qual o ticket médio por estado?"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`text-to-insight --help` lista as demais opções (`--hitl`, `--enrich-rag`, `--infer-fks`, `--cot`, `--data-exploration`, `--exploration-selector`, `--temperature`, `--max-tokens`).
|
|
100
|
+
|
|
101
|
+
## Desenvolvimento
|
|
102
|
+
|
|
103
|
+
- [Guia de desenvolvimento e testes](https://github.com/gruporaia/TextToInsight/blob/main/docs/DESENVOLVIMENTO.md)
|
|
104
|
+
- [Arquitetura](https://github.com/gruporaia/TextToInsight/blob/main/docs/ARQUITETURA.md)
|
|
105
|
+
- Benchmarks: [BIRD](https://github.com/gruporaia/TextToInsight/blob/main/docs/BENCHMARK_BIRD.md), [Spider 1.0 e 2.0](https://github.com/gruporaia/TextToInsight/blob/main/docs/BENCHMARK_SPIDER.md)
|
|
106
|
+
|
|
107
|
+
Desenvolvido pelo grupo RAIA (USP). Licença MIT.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "text-to-insight"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Agentes LangGraph que transformam perguntas em linguagem natural em consultas SQL seguras, executadas no seu banco, com resposta em linguagem natural"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Caio Petroncini"},
|
|
14
|
+
{name = "Julio Cesar Fuganti"},
|
|
15
|
+
{name = "Luiz Correia dos Santos"},
|
|
16
|
+
{name = "Antonio Carvalho"},
|
|
17
|
+
{name = "Bernardo Rubio"},
|
|
18
|
+
{name = "Jonas Honorato"},
|
|
19
|
+
]
|
|
20
|
+
keywords = ["text-to-sql", "nl2sql", "llm", "langgraph", "rag", "sql", "agentes"]
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Development Status :: 3 - Alpha",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Topic :: Database",
|
|
30
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
31
|
+
]
|
|
32
|
+
requires-python = ">=3.10"
|
|
33
|
+
dependencies = [
|
|
34
|
+
"langgraph>=1.1",
|
|
35
|
+
"langchain>=1.2",
|
|
36
|
+
"langchain-core>=1.2",
|
|
37
|
+
"langchain-google-genai>=4.2",
|
|
38
|
+
"langchain-openai>=1.1",
|
|
39
|
+
"pydantic>=2.0",
|
|
40
|
+
"python-dotenv>=1.0.0",
|
|
41
|
+
"pandas>=2.2.2", # uso na geração de gráficos e análise de dados; 2.2.2 é a primeira compatível com numpy 2
|
|
42
|
+
"matplotlib>=3.9.0", # uso na geração de gráficos e visualizações; 3.9 é a primeira compatível com numpy 2
|
|
43
|
+
"networkx>=3.0",
|
|
44
|
+
"chromadb>=1.5.9",
|
|
45
|
+
"tabulate>=0.10.0",
|
|
46
|
+
"sqlalchemy>=2.0.0",
|
|
47
|
+
"platformdirs>=3.0",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.scripts]
|
|
51
|
+
text-to-insight = "text_to_insight.cli:main"
|
|
52
|
+
|
|
53
|
+
[project.optional-dependencies]
|
|
54
|
+
# Drivers de banco: a biblioteca recebe uma Engine do SQLAlchemy pronta, então
|
|
55
|
+
# só precisa do driver de quem for usar PostgreSQL/MySQL (SQLite já vem no Python).
|
|
56
|
+
postgres = ["psycopg2-binary>=2.9.0"]
|
|
57
|
+
mysql = ["pymysql>=1.1.0"]
|
|
58
|
+
dev = [
|
|
59
|
+
"pytest>=7.0",
|
|
60
|
+
"pytest-cov>=4.0",
|
|
61
|
+
"pytest-recording>=0.13.0",
|
|
62
|
+
"aiohttp<3.10.0",
|
|
63
|
+
"pytest-timeout>=2.3.0",
|
|
64
|
+
"black>=23.0",
|
|
65
|
+
"isort>=5.12",
|
|
66
|
+
"flake8>=6.0",
|
|
67
|
+
"mypy>=1.0",
|
|
68
|
+
]
|
|
69
|
+
docs = [
|
|
70
|
+
"sphinx>=5.0",
|
|
71
|
+
"sphinx-rtd-theme>=1.0",
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
[project.urls]
|
|
75
|
+
Homepage = "https://github.com/gruporaia/TextToInsight"
|
|
76
|
+
Documentation = "https://github.com/gruporaia/TextToInsight#readme"
|
|
77
|
+
Repository = "https://github.com/gruporaia/TextToInsight.git"
|
|
78
|
+
"Bug Tracker" = "https://github.com/gruporaia/TextToInsight/issues"
|
|
79
|
+
|
|
80
|
+
# Só a biblioteca vai para o PyPI; scripts/, src/ (benchmarks) e tests/ ficam fora do wheel.
|
|
81
|
+
[tool.setuptools.packages.find]
|
|
82
|
+
include = ["text_to_insight*"]
|
|
83
|
+
|
|
84
|
+
[tool.black]
|
|
85
|
+
line-length = 88
|
|
86
|
+
target-version = ['py310', 'py311', 'py312']
|
|
87
|
+
|
|
88
|
+
[tool.isort]
|
|
89
|
+
profile = "black"
|
|
90
|
+
line_length = 88
|
|
91
|
+
skip_gitignore = true
|
|
92
|
+
|
|
93
|
+
[tool.mypy]
|
|
94
|
+
python_version = "3.10"
|
|
95
|
+
warn_return_any = true
|
|
96
|
+
warn_unused_configs = true
|
|
97
|
+
disallow_untyped_defs = false
|
|
98
|
+
|
|
99
|
+
[tool.pytest.ini_options]
|
|
100
|
+
markers = [
|
|
101
|
+
"real_api: testes que executam chamadas reais ao provedor/modelo LLM",
|
|
102
|
+
]
|