Navexa
Tree-first PDF indexing and reasoning RAG for structured, semi-structured, unstructured, and transcript documents.
Documentation · GitHub Repository · Contributing · Release Notes · Issues · Installation · Quick Start
Navexa is a Python library for turning PDFs into a hierarchical tree and running reasoning-based retrieval (vectorless RAG) on top of that tree.
Core capabilities:
- PDF indexing into
tree_navexa.json - Structured, semi-structured, unstructured, and transcript indexing flows
- Optional LLM-assisted TOC/outline/summaries
- Reasoning-based node retrieval and grounded answering
- Built-in usage and estimated cost tracking for LLM calls
What's New in 0.1.6
- Preferred grouped runtime config:
model_config={...}for provider/model credentials and routingparser_config={...}for parser name, output format, and Docling options
- CLI now matches the Python API:
--model-config--parser-config
semi_structuredsupports bothllmandno-llmtranscriptremains the only indexing flow that is strictly LLM-required- Recoverable Docling issues are surfaced as:
- one-line Navexa warnings at runtime
- structured entries in
tree_navexa.pipeline.warnings
- External reasoning integrations use
BaseExternalLLM
For the full version history, see RELEASE.md.
Installation
Option 1: Use the current local source (editable)
cd navexa
python3 -m pip install -e .
Option 2: From source (regular)
cd navexa
python3 -m pip install .
Option 3: From PyPI (recommended for users)
python3 -m pip install navexa
Update Navexa
Upgrade to latest:
python3 -m pip install --upgrade navexa
Install a specific version:
python3 -m pip install navexa==0.1.6
For Jupyter Notebook/Lab, install the notebook extra to avoid the common tqdm warning
(TqdmWarning: IProgress not found):
python3 -m pip install "navexa[notebook]"
Check the installed version
import navexa
print(navexa.__version__)
Option 4: From GitHub source
python3 -m pip install git+https://github.com/debugger404/navexa.git
Use the local source in notebooks
If you want a notebook to use the current local copy of Navexa:
cd navexa
python3 -m pip install -e .
If a notebook shows ModuleNotFoundError: navexa, check which Python
environment the notebook kernel is using:
import navexa, sys
print(navexa.__file__)
print(sys.executable)
Environment and LLM Setup
You do not need a .env file for parser/indexing behavior.
Use parser_config={...} in API calls when you want per-run parser behavior.
Use environment variables only when needed for:
- LLM credentials/provider routing, or
- global defaults you want shared across runs.
Navexa reads environment from OS variables and .env files.
Env loading order:
NAVEXA_ENV_FILE(explicit file path).envin current working directory (or parent)- repo-local
.env(backward compatibility)
Minimal setup for OpenAI:
export NAVEXA_LLM_PROVIDER="openai"
export OPENAI_API_KEY="..."
export OPENAI_MODEL_NAME="gpt-4.1-mini"
Minimal setup for Azure OpenAI:
export NAVEXA_LLM_PROVIDER="azure"
export AZURE_OPENAI_API_KEY="..."
export AZURE_OPENAI_BASE_URL="https://<resource>.openai.azure.com"
export AZURE_DEPLOYMENT_NAME="<deployment-name>"
export AZURE_DEPLOYMENT_RAW_NAME="gpt-4.1-mini"
If AZURE_OPENAI_BASE_URL is set to just the resource URL, Navexa appends
/openai/v1 automatically.
Use custom .env path (optional):
export NAVEXA_ENV_FILE="./.env"
You can also copy and fill (optional):
.env.example
Direct model_config in Code
If you do not want to rely on .env loading, you can pass provider/model
settings directly in API calls with model_config={...}.
Recommended shape:
model_config = {
"provider": "openai", # openai | azure
"model": "gpt-4.1-mini", # Azure: deployment name
"api_key": "...",
"base_url": None, # required for azure
"pricing_model": None, # optional; useful for Azure custom deployment names
}
Azure example:
model_config = {
"provider": "azure",
"model": "my-gpt41mini-deployment",
"api_key": "...",
"base_url": "https://<resource>.openai.azure.com",
"pricing_model": "gpt-4.1-mini",
}
Azure aliases also work:
deployment_nameinstead ofmodeldeployment_raw_nameinstead ofpricing_model
For Azure, model_config takes the same core values as the env setup:
provider="azure"api_key-> same value asAZURE_OPENAI_API_KEYbase_url-> same value asAZURE_OPENAI_BASE_URLmodelordeployment_name-> same value asAZURE_DEPLOYMENT_NAMEpricing_modelordeployment_raw_name-> same value asAZURE_DEPLOYMENT_RAW_NAME
Use it in API code:
from navexa import index_structured_document_tree
result = index_structured_document_tree(
pdf_path="/path/to/file.pdf",
mode="llm",
model_config={
"provider": "azure",
"deployment_name": "my-gpt41mini-deployment",
"deployment_raw_name": "gpt-4.1-mini",
"api_key": "...",
"base_url": "https://<resource>.openai.azure.com",
},
)
Support:
- Python API supports
model_config={...} - CLI supports
--model-config - legacy
model=/--modelstill work for compatibility but are deprecated
Model/credential precedence:
Preferred usage:
- env defaults, or
model_config={...}in code
Deprecated compatibility path:
3. explicit model=...
Actual resolution order today:
- explicit
model=...(deprecated but still supported) model_config["model"]- env default model (
OPENAI_MODEL_NAMEorAZURE_DEPLOYMENT_NAME) - if still missing: configuration error
Credential/base URL precedence:
model_config.env/ OS environment
Output safety:
- Navexa stores a redacted summary of resolved model settings in
tree_navexa.pipeline.model_config - API keys are never written to output JSON
Recommended Parser Setup
Use this rule:
- Put long-lived defaults in
.env - Pass
parser_config={...}in the function when you want per-run overrides - Avoid mixing
parser_configwith old parser fields
Recommended parser shape:
parser_config = {
"name": "docling",
"output_format": "markdown",
"options": {
"profile": "balanced",
"do_ocr": True,
"force_full_page_ocr": True,
"do_table_structure": True,
"do_picture_description": False,
"enable_remote_services": False,
"backend": "torch",
"image_mode": "placeholder",
"quiet": True,
},
}
Precedence order:
- built-in defaults
.envdefaults- explicit
parser_config
For Docling parser options specifically, the merge order is:
- selected profile defaults
- matching
.envvalues - explicit
parser_config["options"]
Example:
- profile:
fast_textsetsdo_ocr=False .env:NAVEXA_DOCLING_OCR=1- code:
parser_config["options"]={"do_ocr": False}
Final value:
do_ocr=False
Why:
- profile is the starting point
.envoverrides the profile- explicit function config overrides both
Deprecated Python API parser inputs:
parser_modeloutput_formatdocling_options
These legacy Python API fields still work for compatibility, but they are deprecated.
If parser_config is provided, it takes precedence and the legacy parser fields are ignored.
Supported Environment Variables
These env values are defaults. If you pass model_config={...} or
parser_config={...} in code, the explicit code values win.
LLM credentials and routing
| Variable | Purpose | Example |
|---|---|---|
NAVEXA_LLM_PROVIDER |
LLM provider switch | openai or azure |
OPENAI_API_KEY |
OpenAI API key (openai provider) | sk-... |
OPENAI_MODEL_NAME |
OpenAI model name (openai provider) | gpt-4.1-mini |
AZURE_OPENAI_API_KEY |
Azure API key (azure provider) | ... |
AZURE_OPENAI_BASE_URL |
Azure base URL (azure provider) | https://<resource>.openai.azure.com |
AZURE_DEPLOYMENT_NAME |
Azure deployment name (azure provider) | my-deployment |
AZURE_DEPLOYMENT_RAW_NAME |
Raw model name for pricing map/metadata | gpt-4.1-mini |
Model resolution order
Navexa resolves model from:
- explicit
model=parameter (deprecated but still supported) model_config["model"]- if provider is
openai:OPENAI_MODEL_NAME - if provider is
azure:AZURE_DEPLOYMENT_NAME - if still missing: raise configuration error (no fallback)
Provider resolution order:
model_config["provider"]NAVEXA_LLM_PROVIDER- default:
openai
Pipeline defaults
| Variable | Purpose | Default |
|---|---|---|
NAVEXA_MODE |
Runtime mode (llm or no-llm) |
no-llm |
NAVEXA_DOCUMENT_TYPE |
Default doc type | structured |
NAVEXA_VERBOSE |
Verbosity (low,medium,high or 1,2,3) |
medium |
NAVEXA_IF_ADD_NODE_SUMMARY |
Include summaries (yes/no) |
yes |
NAVEXA_MAX_TOKEN_NUM_EACH_NODE |
Max tokens per node | 12000 |
NAVEXA_MAX_PAGE_NUM_EACH_NODE |
Max pages per node | 8 |
NAVEXA_DISABLE_SUMMARY |
Force-disable summaries | 0 |
Parser Environment Defaults
| Variable | Purpose | Default |
|---|---|---|
NAVEXA_DOCLING_PROFILE |
Docling profile preset (balanced, image_manual, fast_text) |
balanced |
NAVEXA_PARSER_MODEL |
Parser backend | docling |
NAVEXA_DOCLING_OUTPUT_FORMAT |
markdown or text |
markdown |
NAVEXA_DOCLING_OCR |
Enable OCR (0/1) |
1 |
NAVEXA_RAPIDOCR_BACKEND |
OCR backend | torch |
NAVEXA_DOCLING_FORCE_FULL_PAGE_OCR |
Force OCR on full page | 1 |
NAVEXA_DOCLING_TABLE_STRUCTURE |
Enable table structure extraction (0/1) |
1 |
NAVEXA_DOCLING_PICTURE_DESCRIPTION |
Picture descriptions | 0 |
NAVEXA_DOCLING_REMOTE_SERVICES |
Enable remote services | 0 |
NAVEXA_DOCLING_IMAGE_MODE |
placeholder, embedded, referenced, none |
placeholder |
NAVEXA_DOCLING_QUIET |
Reduce Docling/RapidOCR logs | 1 |
These env values act as defaults for parser_config when the matching field is not passed explicitly in code.
Quick Start
from navexa import index_structured_document_tree, save_document_tree
result = index_structured_document_tree(
pdf_path="/path/to/file.pdf",
mode="llm",
model_config={
"provider": "openai",
"model": "gpt-4.1-mini",
"api_key": "...",
},
verbosity="medium",
parser_config={
"name": "docling",
"output_format": "markdown",
"options": {
"profile": "balanced", # balanced | image_manual | fast_text
"do_ocr": True, # optional override
"force_full_page_ocr": True, # optional override
"do_table_structure": True, # optional override
"do_picture_description": False, # optional override
"backend": "torch", # torch | onnxruntime
"image_mode": "placeholder", # placeholder | embedded | referenced | none
"quiet": True,
},
},
max_token_num_each_node=12000,
max_page_num_each_node=8,
if_add_node_summary="yes",
)
save = save_document_tree(
index_result=result,
out_dir=None, # defaults to <pdf_dir>/<pdf_stem>_navexa_out
write_tree=True,
write_validation=True,
write_compat=False,
)
print(save.out_dir)
print(save.paths)
print(result.tree_navexa["cost"])
Public APIs
Top-level imports (from navexa):
index_structured_document_treeindex_semi_structured_document_treeindex_unstructured_document_treeindex_transcript_document_treesave_document_treeindex_and_save_document_treefetch_document_treefetch_validation_reportfetch_compat_treebuild_search_tree_viewbuild_node_indexreason_over_treeprint_reasoning_traceextract_selected_contextanswer_from_contextrun_reasoning_ragload_navexa_env
Indexing Functions
1) index_structured_document_tree(...)
LLM requirement: optional
Best for: documents with clear headings/TOC
2) index_semi_structured_document_tree(...)
LLM requirement: optional
Best for: inconsistent headings/order where deterministic parsing works, but LLM can improve weak heading normalization
Behavior:
- without LLM, Navexa still builds headings deterministically from the markdown tree and base outline pipeline
- if that outline is weak, it falls back to heuristic heading generation from page text
- with LLM enabled, Navexa uses the same deterministic base and then improves weak headings via heading normalization
Runtime signal:
- logs include
heading_source=existing|heuristic|llmfor semi-structured flow - output JSON includes
pipeline.semi_structured_source
3) index_unstructured_document_tree(...)
LLM requirement: optional
Best for: weak heading structure; builds chunk-based synthetic sections
4) index_transcript_document_tree(...)
LLM requirement: required
Best for: meeting/interview transcript documents
Note: transcript indexing does not use parser/Docling configuration, so this API does not expose
parser_config, parser_model, output_format, or docling_options.
TOC/Section Strategy by Document Type
| Document Type | Uses TOC Detection Pipeline | Uses LLM for TOC/Heading | Deterministic Fallback |
|---|---|---|---|
structured |
yes | optional | yes |
semi_structured |
yes | optional (heading normalization enhancer) | yes |
unstructured |
no (chunk-first synthetic sections) | optional (title generation only) | yes |
transcript |
n/a (topic grouping flow) | required | no (requires LLM) |
Parser Config Summary
New grouped parameter: parser_config
Available in:
index_structured_document_tree(...)index_semi_structured_document_tree(...)index_unstructured_document_tree(...)- compatibility wrappers (
index_document_tree(...),index_and_save_document_tree(...))
Recommended usage:
parser_config={
"name": "docling",
"output_format": "markdown",
"options": {"profile": "balanced"},
}
Effective parser config is:
- logged at runtime, and
- stored in output JSON at
tree_navexa.pipeline.parser_config - recoverable Docling extraction warnings are stored at
tree_navexa.pipeline.warnings
Recoverable warning behavior:
- Navexa suppresses raw Docling tracebacks when usable content was still recovered
- Navexa logs a one-line warning instead
- the warning is preserved in output JSON for later inspection
Precedence reminder:
- parser profile defaults are applied first
- matching
.envvalues override the profile defaults - explicit
parser_config["options"]overrides both - if legacy Python API fields are also passed,
parser_configwins
Inside parser_config:
nameoutput_formatoptions
Current default behavior:
profile="balanced"do_ocr=Trueforce_full_page_ocr=Truedo_table_structure=Truedo_picture_description=Falseenable_remote_services=Falsebackend="torch"image_mode="placeholder"quiet=True
Deprecated Python API parser fields:
parser_modeloutput_formatdocling_options
These remain accepted in the Python API for compatibility but are deprecated. Prefer parser_config.
Shared Indexing Parameters and Values
| Parameter | Type | Allowed Values | Default |
|---|---|---|---|
pdf_path |
str |
valid PDF path | required |
model |
Optional[str] |
provider model/deployment name | deprecated |
model_config |
Optional[dict] |
see model section above | None |
mode |
Optional[str] |
llm, use-llm, with-llm, no-llm |
None |
verbosity |
Optional[str] |
low, medium, high, 1, 2, 3, debug, detailed |
None |
parser_config |
Optional[dict] |
see parser section below | None |
parser_model |
Optional[str] |
currently docling only |
deprecated |
output_format |
Optional[str] |
markdown, text |
deprecated |
docling_options |
Optional[dict] |
legacy Docling options | deprecated |
max_token_num_each_node |
int |
>=1 |
12000 |
max_page_num_each_node |
int |
>=1 |
8 |
if_add_node_summary |
str |
yes, no |
yes |
The parser-related parameters above apply to:
index_structured_document_tree(...)index_semi_structured_document_tree(...)index_unstructured_document_tree(...)
Model-related note:
- prefer
model_configfor in-code configuration modelstill works for compatibility, but it is deprecated- all indexing APIs accept
model - all indexing APIs accept
model_config - if both are passed,
modelwins overmodel_config["model"]
Transcript-specific note:
index_transcript_document_tree(...)does not exposemode,parser_config,parser_model,output_format, ordocling_options
Structured/semi-structured note:
- if you set
parser_config["output_format"]="text"or legacyoutput_format="text"forstructuredorsemi_structured, Navexa will force it tomarkdown - reason: heading/tree extraction for these flows depends on markdown heading structure
- Navexa logs a warning when this coercion happens
Function-specific extra parameters:
semi_heading_prompt_templateinindex_semi_structured_document_treetranscript_topic_prompt_templateinindex_transcript_document_tree
Backward compatibility:
index_document_tree(...)still exists and routes to structured flow.
parser_config Dictionary Reference
Use parser_config when you want parser behavior controlled directly in code.
Step by step:
- set parser name in
parser_config["name"] - set parser output in
parser_config["output_format"] - put parser-specific options in
parser_config["options"] - pass only the fields you want to override
Example:
parser_config = {
"name": "docling",
"output_format": "markdown",
"options": {
"profile": "image_manual",
"backend": "torch",
"do_picture_description": True,
},
}
Current parser names:
docling
Current output formats:
markdowntext
Important behavior:
structuredandsemi_structureddo not truly run intextparser mode- if
output_format="text"is requested for those flows, Navexa coerces it tomarkdown unstructuredcan still use eithermarkdownortext
parser_config["options"] for name="docling":
| Key | Type | Allowed Values | Default | Scenario |
|---|---|---|---|---|
profile |
str |
balanced, image_manual, fast_text |
balanced |
Start-point preset |
do_ocr |
bool |
True, False |
True |
Turn OCR on/off |
force_full_page_ocr |
bool |
True, False |
True |
Scanned/image PDFs |
do_table_structure |
bool |
True, False |
True |
Table-heavy docs |
do_picture_description |
bool |
True, False |
False |
Image/manual docs |
enable_remote_services |
bool |
True, False |
False |
Remote enrichment |
backend |
str |
torch, onnxruntime |
torch |
OCR runtime choice |
image_mode |
str |
placeholder, embedded, referenced, none |
placeholder |
Markdown image policy |
quiet |
bool |
True, False |
True |
Reduce parser logs |
Profile behavior:
| Profile | OCR | Full-page OCR | Table Structure | Picture Description | Best For |
|---|---|---|---|---|---|
balanced |
on | on | on | off | Most documents |
image_manual |
on | on | on | on | Image-heavy manuals/decks |
fast_text |
off | off | on | off | Native digital text PDFs |
Backend note:
backend="torch": default, generally most stable.backend="onnxruntime": often lighter/faster on CPU-only environments.onnxruntimeis included in Navexa install dependencies.
Quiet note:
quiet=Truereduces normal Docling/RapidOCR log noise- major failures still raise clear Navexa errors
- recoverable parser issues are still reported through
pipeline.warnings
Legacy compatibility note:
parser_model,output_format, anddocling_optionsstill work- they are deprecated in the Python API
- if
parser_configis also passed,parser_configwins
Save and Fetch APIs
Save
save_document_tree(index_result, out_dir=None, save_mode="explicit", write_tree=True, write_validation=False, write_compat=False)
Notes:
- At least one of
write_tree/write_validation/write_compatmust beTrue - If
out_dir=None, default is<pdf_dir>/<pdf_stem>_navexa_out
Fetch
fetch_document_tree(source, file_name="tree_navexa.json")fetch_validation_report(source)fetch_compat_tree(source)
source can be:
- in-memory dict
- JSON file path
- output directory path
IndexResultobject
Reasoning and RAG APIs
Tree preparation
build_search_tree_view(tree, strip_fields=("exclusive_text", "full_text"))
build_node_index(tree, include_page_ranges=True, exclude_fields=None)
Tree reasoning
reason_over_tree(query, tree, model=None, model_config=None, prompt_template=None, llm_callable=None, return_prompt=False, verbosity=None, strip_fields=("exclusive_text","full_text"), prompt_extra=None)
Return object fields:
thinkingnode_listraw_responseused_prompt(if requested)parsed_json
Trace print
print_reasoning_trace(reasoning_result, node_index)
Context extraction
extract_selected_context(tree, node_list, text_mode="inclusive", dedupe_ancestor=True)
text_mode values:
inclusive-> usesfull_textexclusive-> usesexclusive_text
dedupe_ancestor behavior:
True: if parent and child are both selected, child is droppedFalse: keeps all selected nodes
Answer generation
answer_from_context(query, context_text, model=None, model_config=None, prompt_template=None, llm_callable=None, return_prompt=False, verbosity=None, prompt_extra=None)
End-to-end
run_reasoning_rag(query, tree_or_source, model=None, model_config=None, tree_prompt_template=None, answer_prompt_template=None, llm_callable=None, return_prompt=False, verbosity=None, strip_fields=("exclusive_text","full_text"), text_mode="inclusive", dedupe_ancestor=True, tree_prompt_extra=None, answer_prompt_extra=None)
Returns:
tree,tree_view,node_indexreasoning,context,answercost_before,cost_after,cost_delta
Prompt Template + prompt_extra Examples
Important:
prompt_extra(andtree_prompt_extra/answer_prompt_extra) is passed as JSON payload.- If your template includes
{extra_json}, Navexa replaces it with payload JSON. - If your template does not include
{extra_json}and payload is provided, Navexa appends anAdditional ... (JSON)section automatically. - If payload is empty, nothing is appended.
Example: reason_over_tree(...) with custom prompt template and prompt_extra
from navexa import reason_over_tree
custom_tree_prompt = """
You are a strict node selector.
Question: {query}
Tree:
{tree_json}
Constraints:
{extra_json}
Return JSON:
{"thinking":"...", "node_list":["0001"]}
"""
reasoning = reason_over_tree(
query="What are key warnings?",
tree=tree,
model_config={"provider": "openai", "model": "gpt-4.1-mini", "api_key": "..."},
prompt_template=custom_tree_prompt,
prompt_extra={"must_include_terms": ["warning", "precaution"], "max_nodes": 2},
return_prompt=True,
)
print(reasoning.node_list)
print(reasoning.used_prompt)
Example: answer_from_context(...) with prompt_extra
from navexa import answer_from_context
answer_template = """
Answer only from context.
Question: {query}
Context: {context}
Policy: {extra_json}
"""
answer = answer_from_context(
query="What are key warnings?",
context_text="Warnings: liver toxicity; monitor ALT/AST.",
model_config={"provider": "openai", "model": "gpt-4.1-mini", "api_key": "..."},
prompt_template=answer_template,
prompt_extra={"style": "bullet", "max_points": 3},
return_prompt=True,
)
print(answer.answer)
print(answer.used_prompt)
Example: run_reasoning_rag(...) with separate extras
from navexa import run_reasoning_rag
rag = run_reasoning_rag(
query="What are key warnings?",
tree_or_source=tree,
model_config={"provider": "openai", "model": "gpt-4.1-mini", "api_key": "..."},
tree_prompt_template=custom_tree_prompt,
answer_prompt_template=answer_template,
tree_prompt_extra={"max_nodes": 2},
answer_prompt_extra={"style": "short"},
return_prompt=True,
)
print(rag.reasoning.used_prompt)
print(rag.answer.used_prompt)
End-to-End Example (Index + RAG)
from navexa import (
index_structured_document_tree,
save_document_tree,
fetch_document_tree,
run_reasoning_rag,
print_reasoning_trace,
)
pdf_path = "/path/to/file.pdf"
query = "What are the key warnings?"
index_result = index_structured_document_tree(
pdf_path=pdf_path,
mode="llm",
model_config={
"provider": "openai",
"model": "gpt-4.1-mini",
"api_key": "...",
},
verbosity="high",
)
save_result = save_document_tree(
index_result=index_result,
out_dir="/path/to/output",
write_tree=True,
write_validation=True,
write_compat=False,
)
tree = fetch_document_tree(save_result.out_dir)
rag = run_reasoning_rag(
query=query,
tree_or_source=tree,
model_config={
"provider": "openai",
"model": "gpt-4.1-mini",
"api_key": "...",
},
return_prompt=True,
verbosity="high",
)
print_reasoning_trace(rag.reasoning, rag.node_index)
print("\nAnswer:\n", rag.answer.answer)
print("\nCost delta:\n", rag.cost_delta)
CLI Usage
After install, CLI entry point:
navexa-index --pdf /path/file.pdf --out-dir /path/out
If navexa-index is "command not found":
- If you installed into a virtualenv, activate it first:
source <venv>/bin/activate - If you installed with
pip install --user, the script is usually at~/.local/bin/navexa-index. Add it to PATH once:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
All CLI flags:
| Flag | Allowed Values | Default |
|---|---|---|
--pdf |
PDF path | required |
--out-dir |
output dir | required |
--model-config |
JSON object or JSON file path | None |
--model |
model/deployment string | deprecated |
--mode |
llm, no-llm |
NAVEXA_MODE or no-llm |
--document-type |
structured, semi_structured, unstructured, transcript |
structured |
--parser-config |
JSON object or JSON file path | None |
--parser-model |
docling |
docling |
--output-format |
markdown, text |
markdown |
--docling-profile |
balanced, image_manual, fast_text |
balanced |
--docling-ocr |
0, 1 |
profile/env resolved |
--docling-force-full-page-ocr |
0, 1 |
profile/env resolved |
--docling-table-structure |
0, 1 |
profile/env resolved |
--docling-picture-description |
0, 1 |
profile/env resolved |
--docling-backend |
string (e.g. torch, onnxruntime) |
profile/env resolved |
--docling-image-mode |
placeholder, embedded, referenced, none |
profile/env resolved |
--docling-remote-services |
0, 1 |
profile/env resolved |
--docling-quiet |
0, 1 |
profile/env resolved |
--verbose |
1,2,3,low,medium,high |
medium |
--max-token-num-each-node |
int | 12000 |
--max-page-num-each-node |
int | 8 |
--if-add-node-summary |
yes, no |
yes |
--with-validation |
switch | off |
--with-compat |
switch | off |
Preferred CLI parser setup:
- use
--model-configfor grouped provider/model credentials and routing - use legacy
--modelonly as a compatibility override - if both
--model-configand--modelare passed, legacy--modelwins for compatibility - use
--parser-configfor the grouped parser model - use the old flat parser flags only as compatibility shorthands
- if
--parser-configis passed together with old parser flags,--parser-configwins and the old parser flags are ignored - if
--document-type transcriptis used, parser configuration is ignored
Example with grouped model + parser config:
navexa-index \
--pdf /path/file.pdf \
--out-dir /path/out \
--mode llm \
--document-type structured \
--model-config '{"provider":"azure","deployment_name":"my-deploy","deployment_raw_name":"gpt-4.1-mini","api_key":"...","base_url":"https://<resource>.openai.azure.com"}' \
--parser-config '{"name":"docling","output_format":"markdown","options":{"profile":"balanced","backend":"torch","quiet":true}}' \
--verbose high \
--if-add-node-summary yes \
--with-validation
Example with grouped parser config:
navexa-index \
--pdf /path/file.pdf \
--out-dir /path/out \
--mode llm \
--document-type structured \
--parser-config '{"name":"docling","output_format":"markdown","options":{"profile":"balanced","backend":"torch","quiet":true}}' \
--verbose high \
--if-add-node-summary yes \
--with-validation
Equivalent legacy shorthand example:
navexa-index \
--pdf /path/file.pdf \
--out-dir /path/out \
--mode llm \
--document-type structured \
--output-format markdown \
--verbose high \
--if-add-node-summary yes \
--with-validation
Output Files
Generated files:
tree_navexa.json(canonical)validation_report.json(optional)tree_legacy_compat.json(optional)
tree_navexa.json top-level keys include:
doc_id,doc_name,pages,pipeline_versionsource(path/hash/page count)cost(calls/tokens/estimated cost)pipeline(mode, document type, parser settings, node limits, steps)structure(hierarchical nodes withchildren)transcript(present for transcript flow)
Useful pipeline fields:
model_config: resolved safe model/provider metadataparser_config: resolved parser configurationwarnings: recoverable parser/runtime warnings
Logging and Cost
Verbosity:
low: compact result logsmedium: stage-by-stage logshigh: debug-level details and usage deltas
Cost fields are available in:
tree_navexa["cost"]IndexResult.meta["cost"]RAGResult.cost_deltafor reasoning runs
Prompt Overrides and Custom LLM
Detailed docs:
docs/README.mddocs/custom_llm_integration.mddocs/prompt_templates.md
You can override prompts:
semi_heading_prompt_templatetranscript_topic_prompt_templatetree_prompt_templateanswer_prompt_template
Use a provider-backed BaseExternalLLM adapter with llm_callable=....
Behavior:
- if
llm_callableis provided, Navexa uses your externalBaseExternalLLMadapter - if
llm_callableis not provided, Navexa uses internal provider/env client
Failure Behavior and Troubleshooting
Common cases:
- Missing API key in LLM-required flows (
transcript) -> raisesRuntimeError mode="llm"with missing credentials (any document type) -> raisesRuntimeError- Missing API key in optional LLM flow with
modeunset (structured/semi_structured/unstructured) -> runs in effectiveno-llm - Invalid
parser_config["name"]or legacyparser_model->ValueError(currently onlydocling) - Invalid
parser_config["output_format"]or legacyoutput_format->ValueError(markdownortext) - Empty/invalid tree input to reasoning APIs ->
ValueError - Recoverable Docling OCR/parser issues -> Navexa logs a one-line warning and stores it in
tree_navexa.pipeline.warnings - Major Docling failure with no usable extracted content -> Navexa raises
RuntimeErrorwith retry guidance instead of showing raw third-party traceback
Notebook note:
asyncio.run()loop conflicts are handled in reasoning functions with thread fallback.- If you still run into notebook event-loop issues, restart kernel and re-run imports.
Acknowledgment
Navexa is an independent implementation. Some architecture patterns and selected adapted code paths were informed by PageIndex.
Attribution files:
THIRD_PARTY_NOTICES.mdLICENSE
License
This project is licensed under MIT.
Practical compliance checklist:
- Keep this repository
LICENSE. - Keep third-party attribution notices.
- Preserve upstream MIT notice for copied/substantially adapted portions.
This documentation is technical guidance, not legal advice.
Metadata
Release files for navexa 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| navexa-0.1.6.tar.gz | 87.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| navexa-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 168.0 kB