Navexa document indexing and reasoning workflows
Project description
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.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters