# pedropompeu/franq architecture

> Architecture diagram of the GitHub repository pedropompeu/franq, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/pedropompeu/franq
- Repository: https://github.com/pedropompeu/franq

## Overview

Indaga is a Portuguese-language natural-language-to-SQL assistant over a read-only SQLite database. Users ask through the Streamlit interface, API, or CLI; the agent gathers schema and business context, asks an LLM to plan and review a query, executes it with read-only safeguards, and returns a response with data and presentation guidance. The product also provides conversation memory, privacy masking, warnings, visualizations, evaluation, and optional tracing. Edges reflect README statements and SOURCE INDEX references; unsampled implementation details are not inferred.

Main entry points: [`src/agent/graph.py`](https://github.com/pedropompeu/franq/blob/main/src/agent/graph.py) (Agent graph), [`app.py`](https://github.com/pedropompeu/franq/blob/main/app.py) (Streamlit app), [`src/api.py`](https://github.com/pedropompeu/franq/blob/main/src/api.py) (HTTP API), [`src/cli.py`](https://github.com/pedropompeu/franq/blob/main/src/cli.py) (Command line)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["User entry"]
  node_streamlit["Streamlit app<br/>[app.py]"]
  node_http_api["HTTP API<br/>[api.py]"]
  node_cli["Command line<br/>[cli.py]"]
end

subgraph group_agent["Query agent"]
  node_assistant["Agent graph<br/>[graph.py]"]
  node_contracts["Decision contracts<br/>[models.py]"]
  node_prompts["Agent prompts<br/>[prompts.py]"]
  node_memory[("Conversation memory<br/>[memory.py]")]
  node_privacy["PII pseudonymization<br/>[privacy.py]"]
  node_notices["Result warnings<br/>[notices.py]"]
  node_llm["LLM provider<br/>[llm.py]"]
end

subgraph group_data["Data access"]
  node_semantic["Business dictionary<br/>[dictionary.py]"]
  node_sql["SQL tools<br/>[tools.py]"]
  node_sqlite[("SQLite database<br/>[anexo_desafio_1.db]")]
end

subgraph group_presentation["Results and UI"]
  node_ui_view["Result presentation<br/>[view.py]"]
  node_query_graph["Query visualization<br/>[query_graph.py]"]
  node_data_graph["Data visualization<br/>[data_graph.py]"]
end

subgraph group_operations["Evaluation and tracing"]
  node_evaluation["Evaluation runner<br/>[evaluation.py]"]
  node_tracing[("Local tracing<br/>[observability.py]")]
  node_langfuse["LangFuse bridge<br/>[langfuse_bridge.py]"]
end

node_user(("User"))
node_gemini{{"Google Gemini"}}

node_user -->|"asks via"| node_streamlit
node_user -->|"asks via"| node_http_api
node_user -->|"asks via"| node_cli
node_streamlit -->|"invokes"| node_assistant
node_http_api -->|"invokes"| node_assistant
node_cli -->|"invokes"| node_assistant
node_assistant -->|"uses decisions"| node_contracts
node_assistant -->|"uses prompts"| node_prompts
node_assistant -->|"reads and stores turns"| node_memory
node_assistant -->|"masks model data"| node_privacy
node_assistant -->|"loads context"| node_semantic
node_assistant -->|"executes queries"| node_sql
node_assistant -->|"requests decisions"| node_llm
node_sql -->|"reads"| node_sqlite
node_llm -->|"calls provider"| node_gemini
node_assistant -->|"computes warnings"| node_notices
node_streamlit -->|"renders results"| node_ui_view
node_streamlit -->|"shows query graph"| node_query_graph
node_streamlit -->|"shows data graph"| node_data_graph
node_evaluation -->|"evaluates answers"| node_assistant
node_assistant -->|"writes traces"| node_tracing
node_assistant -.->|"sends traces"| node_langfuse

click node_streamlit "https://github.com/pedropompeu/franq/blob/main/app.py"
click node_http_api "https://github.com/pedropompeu/franq/blob/main/src/api.py"
click node_cli "https://github.com/pedropompeu/franq/blob/main/src/cli.py"
click node_assistant "https://github.com/pedropompeu/franq/blob/main/src/agent/graph.py"
click node_contracts "https://github.com/pedropompeu/franq/blob/main/src/agent/models.py"
click node_prompts "https://github.com/pedropompeu/franq/blob/main/src/agent/prompts.py"
click node_memory "https://github.com/pedropompeu/franq/blob/main/src/agent/memory.py"
click node_privacy "https://github.com/pedropompeu/franq/blob/main/src/privacy.py"
click node_notices "https://github.com/pedropompeu/franq/blob/main/src/agent/notices.py"
click node_semantic "https://github.com/pedropompeu/franq/blob/main/src/semantic/dictionary.py"
click node_sql "https://github.com/pedropompeu/franq/blob/main/src/db/tools.py"
click node_sqlite "https://github.com/pedropompeu/franq/blob/main/data/anexo_desafio_1.db"
click node_llm "https://github.com/pedropompeu/franq/blob/main/src/llm.py"
click node_ui_view "https://github.com/pedropompeu/franq/blob/main/src/ui/view.py"
click node_query_graph "https://github.com/pedropompeu/franq/blob/main/src/ui/query_graph.py"
click node_data_graph "https://github.com/pedropompeu/franq/blob/main/src/ui/data_graph.py"
click node_evaluation "https://github.com/pedropompeu/franq/blob/main/src/evaluation.py"
click node_tracing "https://github.com/pedropompeu/franq/blob/main/src/observability.py"
click node_langfuse "https://github.com/pedropompeu/franq/blob/main/src/langfuse_bridge.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_streamlit,node_http_api,node_cli,node_user toneBlue
class node_assistant,node_contracts,node_prompts,node_memory,node_privacy,node_notices,node_llm toneAmber
class node_semantic,node_sql,node_sqlite toneMint
class node_ui_view,node_query_graph,node_data_graph toneRose
class node_evaluation,node_tracing,node_langfuse,node_gemini toneIndigo
```

## Components

### User entry

- [Streamlit app](https://github.com/pedropompeu/franq/blob/main/app.py): `app.py`
- [HTTP API](https://github.com/pedropompeu/franq/blob/main/src/api.py): `src/api.py`
- [Command line](https://github.com/pedropompeu/franq/blob/main/src/cli.py): `src/cli.py`

### Query agent

- [Agent graph](https://github.com/pedropompeu/franq/blob/main/src/agent/graph.py): `src/agent/graph.py`
- [Decision contracts](https://github.com/pedropompeu/franq/blob/main/src/agent/models.py): `src/agent/models.py`
- [Agent prompts](https://github.com/pedropompeu/franq/blob/main/src/agent/prompts.py): `src/agent/prompts.py`
- [Conversation memory](https://github.com/pedropompeu/franq/blob/main/src/agent/memory.py): `src/agent/memory.py`
- [PII pseudonymization](https://github.com/pedropompeu/franq/blob/main/src/privacy.py): `src/privacy.py`
- [Result warnings](https://github.com/pedropompeu/franq/blob/main/src/agent/notices.py): `src/agent/notices.py`
- [LLM provider](https://github.com/pedropompeu/franq/blob/main/src/llm.py): `src/llm.py`

### Data access

- [Business dictionary](https://github.com/pedropompeu/franq/blob/main/src/semantic/dictionary.py): `src/semantic/dictionary.py`
- [SQL tools](https://github.com/pedropompeu/franq/blob/main/src/db/tools.py): `src/db/tools.py`
- [SQLite database](https://github.com/pedropompeu/franq/blob/main/data/anexo_desafio_1.db): `data/anexo_desafio_1.db`

### Results and UI

- [Result presentation](https://github.com/pedropompeu/franq/blob/main/src/ui/view.py): `src/ui/view.py`
- [Query visualization](https://github.com/pedropompeu/franq/blob/main/src/ui/query_graph.py): `src/ui/query_graph.py`
- [Data visualization](https://github.com/pedropompeu/franq/blob/main/src/ui/data_graph.py): `src/ui/data_graph.py`

### Evaluation and tracing

- [Evaluation runner](https://github.com/pedropompeu/franq/blob/main/src/evaluation.py): `src/evaluation.py`
- [Local tracing](https://github.com/pedropompeu/franq/blob/main/src/observability.py): `src/observability.py`
- [LangFuse bridge](https://github.com/pedropompeu/franq/blob/main/src/langfuse_bridge.py): `src/langfuse_bridge.py`

### Other components

- **User**
- **Google Gemini**

## Connections

- User → Streamlit app: asks via (evidence: `README.md`)
- User → HTTP API: asks via (evidence: `README.md`)
- User → Command line: asks via (evidence: `README.md`)
- Streamlit app → Agent graph: invokes (evidence: `app.py`)
- HTTP API → Agent graph: invokes (evidence: `src/api.py`)
- Command line → Agent graph: invokes (evidence: `src/cli.py`)
- Agent graph → Decision contracts: uses decisions (evidence: `src/agent/graph.py`)
- Agent graph → Agent prompts: uses prompts (evidence: `src/agent/graph.py`)
- Agent graph → Conversation memory: reads and stores turns (evidence: `src/agent/graph.py`)
- Agent graph → PII pseudonymization: masks model data (evidence: `src/agent/graph.py`)
- Agent graph → Business dictionary: loads context (evidence: `src/agent/graph.py`)
- Agent graph → SQL tools: executes queries (evidence: `src/agent/graph.py`)
- Agent graph → LLM provider: requests decisions (evidence: `src/agent/graph.py`)
- SQL tools → SQLite database: reads (evidence: `src/db/tools.py`)
- LLM provider → Google Gemini: calls provider (evidence: `src/llm.py`)
- Agent graph → Result warnings: computes warnings (evidence: `src/agent/graph.py`)
- Streamlit app → Result presentation: renders results (evidence: `app.py`)
- Streamlit app → Query visualization: shows query graph (evidence: `app.py`)
- Streamlit app → Data visualization: shows data graph (evidence: `app.py`)
- Evaluation runner → Agent graph: evaluates answers (evidence: `src/evaluation.py`)
- Agent graph → Local tracing: writes traces (evidence: `src/agent/graph.py`)
- Agent graph → LangFuse bridge: sends traces
