Navegador

navegador / docs / guide / intelligence.md
1
# Intelligence Layer
2
3
The intelligence layer adds capabilities that go beyond structural graph queries: semantic similarity search, community detection, natural language queries, and documentation generation. These features require an LLM provider or embedding model.
4
5
---
6
7
## Setup
8
9
Install the intelligence extras:
10
11
```bash
12
pip install "navegador[intelligence]"
13
```
14
15
Configure your LLM provider:
16
17
=== "OpenAI"
18
19
```bash
20
export NAVEGADOR_LLM_PROVIDER=openai
21
export OPENAI_API_KEY=sk-...
22
```
23
24
=== "Anthropic"
25
26
```bash
27
export NAVEGADOR_LLM_PROVIDER=anthropic
28
export ANTHROPIC_API_KEY=sk-ant-...
29
```
30
31
=== "Local (Ollama)"
32
33
```bash
34
export NAVEGADOR_LLM_PROVIDER=ollama
35
export NAVEGADOR_LLM_MODEL=llama3.2
36
# no API key required; Ollama must be running on localhost:11434
37
```
38
39
Or set via `navegador.toml`:
40
41
```toml
42
[intelligence]
43
provider = "openai"
44
model = "text-embedding-3-small" # embedding model
45
llm_model = "gpt-4o-mini" # generation model
46
```
47
48
---
49
50
## Semantic search
51
52
Standard `navegador search` matches on names and text. Semantic search matches on **meaning**: a query for "billing" finds code about "invoices", "subscriptions", and "charges" even when those words don't appear in the query.
53
54
```bash
55
navegador search "handle payment failure" --semantic
56
navegador search "retry with backoff" --semantic --limit 10
57
navegador search "authentication middleware" --semantic --all
58
```
59
60
!!! note
61
First run after ingestion builds the embedding index. This may take a minute on large codebases. The index is cached in the database and updated incrementally on re-ingest.
62
63
### Combining semantic and text search
64
65
```bash
66
# semantic search scoped to a domain
67
navegador search "billing failure" --semantic --domain Payments
68
69
# hybrid: semantic ranking with text pre-filter
70
navegador search "rate limit" --semantic --all
71
```
72
73
### Python API
74
75
```python
76
from navegador.graph import GraphStore
77
from navegador.intelligence import SemanticSearch
78
79
store = GraphStore.sqlite(".navegador/navegador.db")
80
search = SemanticSearch(store)
81
82
results = search.query("handle payment failure", limit=10)
83
for node in results:
84
print(f"[{node.label}] {node.name} score={node.score:.3f}")
85
```
86
87
---
88
89
## Community detection
90
91
Community detection groups nodes in the graph into clusters based on structural connectivity. Clusters typically correspond to logical modules or subsystems, even when the code doesn't explicitly organize itself that way.
92
93
```bash
94
navegador intelligence communities
95
navegador intelligence communities --algorithm louvain
96
navegador intelligence communities --format json
97
```
98
99
### Algorithms
100
101
| Algorithm | Best for |
102
|---|---|
103
| `louvain` (default) | Large codebases; fast and produces stable clusters |
104
| `leiden` | Higher modularity; slower |
105
| `label-propagation` | Very large graphs |
106
107
### Output
108
109
```
110
Detected 6 communities:
111
112
Community 1 (47 nodes) — suggested name: Auth
113
Core: AuthService, validate_token, JWTManager
114
Files: src/auth/ (12 files)
115
116
Community 2 (38 nodes) — suggested name: Payments
117
Core: PaymentProcessor, charge_card, StripeClient
118
Files: src/payments/ (9 files)
119
120
Community 3 (22 nodes) — suggested name: Orders
121
Core: OrderService, create_order, OrderRepository
122
Files: src/orders/ (6 files)
123
...
124
```
125
126
Suggested names are generated by the LLM by inspecting the core nodes of each cluster.
127
128
### Persisting communities
129
130
```bash
131
navegador intelligence communities --save
132
```
133
134
This writes `Community` nodes and `MEMBER_OF` edges into the graph, making communities queryable:
135
136
```bash
137
navegador query "MATCH (f:Function)-[:MEMBER_OF]->(c:Community) WHERE c.name = 'Payments' RETURN f.name, f.file"
138
```
139
140
---
141
142
## Natural language queries
143
144
`navegador ask` lets you query the graph in plain English. The LLM translates your question into Cypher, executes it, and returns a natural language answer with citations.
145
146
```bash
147
navegador ask "Which functions call process_payment?"
148
navegador ask "What rules govern the Payments domain?"
149
navegador ask "Show me all classes that inherit from BaseProcessor"
150
navegador ask "What decisions have been made about the database?"
151
```
152
153
### How it works
154
155
1. Your question is embedded and matched against graph schema context
156
2. The LLM generates a Cypher query based on the question and schema
157
3. Navegador executes the query against the graph
158
4. The LLM formats the results as a natural language answer with source references
159
160
### Safety
161
162
Generated queries are run in read-only mode. Write operations (`CREATE`, `MERGE`, `DELETE`, `SET`) in generated queries are blocked.
163
164
```bash
165
# show the generated Cypher without executing
166
navegador ask "Which functions have no tests?" --show-query
167
168
# execute and show both Cypher and answer
169
navegador ask "Which functions have no tests?" --verbose
170
```
171
172
---
173
174
## Documentation generation
175
176
`navegador docgen` generates or improves docstrings for undocumented functions and classes, using graph context to produce accurate, context-aware descriptions.
177
178
```bash
179
# generate docs for all undocumented functions in a file
180
navegador docgen src/payments/processor.py
181
182
# generate docs for a specific function
183
navegador docgen --target process_payment
184
185
# dry run: show what would be generated without writing
186
navegador docgen src/payments/processor.py --dry-run
187
188
# write directly to source files
189
navegador docgen src/payments/processor.py --write
190
```
191
192
### What it includes
193
194
The generated docstring draws on:
195
196
- The function's call graph (what it calls and what calls it)
197
- Related concepts and rules from the knowledge layer
198
- The class or module context
199
- Existing docstrings in the same file as style examples
200
201
### Output
202
203
```python
204
def process_payment(order_id: str, amount: Decimal, idempotency_key: str) -> PaymentResult:
205
"""Process a payment for an order.
206
207
Charges the card on file for the given order using the Stripe payment
208
processor. Requires an idempotency key to prevent double-charging on
209
client retries (see: RequireIdempotencyKey rule, UseStripeForPayments
210
decision).
211
212
Args:
213
order_id: The unique identifier of the order to charge.
214
amount: The amount to charge in the order's currency.
215
idempotency_key: Client-supplied key for idempotent retries.
216
217
Returns:
218
PaymentResult with charge_id and status.
219
220
Raises:
221
PaymentError: If the charge fails or the card is declined.
222
DuplicatePaymentError: If a payment with this idempotency_key
223
already exists with a different amount.
224
"""
225
```
226
227
### Batch generation
228
229
```bash
230
# generate docs for all undocumented functions in the repo
231
navegador docgen ./src --write --format google
232
233
# formats: google (default), numpy, sphinx
234
```
235
236
!!! warning
237
`--write` modifies source files in place. Review changes with `--dry-run` first and commit before running with `--write` so you can diff and revert.
238
239
---
240
241
## Python API
242
243
```python
244
from navegador.graph import GraphStore
245
from navegador.intelligence import SemanticSearch, CommunityDetector, NaturalLanguageQuery, DocGenerator
246
247
store = GraphStore.sqlite(".navegador/navegador.db")
248
249
# semantic search
250
search = SemanticSearch(store)
251
results = search.query("retry logic", limit=5)
252
253
# community detection
254
detector = CommunityDetector(store)
255
communities = detector.detect(algorithm="louvain", save=True)
256
257
# natural language query
258
nlq = NaturalLanguageQuery(store)
259
answer = nlq.ask("What functions call process_payment?")
260
print(answer.text)
261
print(answer.cypher) # generated Cypher
262
263
# doc generation
264
docgen = DocGenerator(store)
265
draft = docgen.generate_for_function("process_payment")
266
print(draft.docstring)
267
```
268

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button