vlm_captioner
zocrates.rag.vlm_captioner ¶
VLM Image Captioning & Multimodal Figure Enrichment Engine.
Provides automated visual description generation for uncaptioned diagrams, plots, flowcharts, and academic figures using Vision-Language Models (VLMs) via OpenRouter (Cloud) or Ollama (Local).
DEFAULT_VLM_CAPTIONING_BACKUP_MODEL
module-attribute
¶
DEFAULT_VLM_CAPTIONING_BACKUP_MODEL = 'openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free'
DEFAULT_VLM_CAPTIONING_MODEL
module-attribute
¶
FIGURE_CAPTION_SYSTEM_PROMPT
module-attribute
¶
FIGURE_CAPTION_SYSTEM_PROMPT = 'You are an expert academic document assistant. \nAnalyze the provided figure or diagram from a research paper or document.\nProvide a concise, dense, factual description (under 120 words) with the following structure:\n\n- **Type**: Visualization or figure category (e.g., Line Plot, Architecture Flowchart, Confusion Matrix, Microscopy Panel, Circuit Schematic, Geographical Map, Manuscript Scan).\n- **Key Elements**: Specific variables, axes (x and y labels with units), legends, mathematical notations, or chemical/biological structures visible.\n- **Takeaway**: The primary scientific finding, trend, baseline comparison, or structural relationship depicted.\n\n### Domain-Specific Points to Consider:\n- **Computer Science & Engineering**: Note system architectures, inputs/outputs, network layers, benchmark baselines, latency/throughput tradeoffs, or flowchart decision logic.\n- **Biomedical & Life Sciences**: Identify microscopy stain/modality, animal/cell model, protein/gene names, gel/blot bands, error bars (p-values, SD/SEM), and control vs. treatment conditions.\n- **Physics & Chemistry**: Note chemical structures, reaction mechanisms, spectral peaks (wavelength/energy), coordinate frames, field lines, and physical units.\n- **Mathematics & Quantitative Finance**: Capture LaTeX notation, matrix dimensions, state spaces, distributions, confidence intervals, and trendlines.\n- **Humanities, Social Sciences & Archives**: Note geographical regions, timeline periods, demographic cohorts, archival source details, or survey sample sizes.\n\n### Guardrails:\n- If the image is a decorative icon, logo, author headshot, or unreadable banner, reply strictly with: [DECORATIVE].\n- Do not hallucinate values or conclusions not directly visible in the image.'
_FENCE_RE
module-attribute
¶
_FIGURE_BLOCK_RE
module-attribute
¶
_IMG_TAG_OR_MD_RE
module-attribute
¶
_IMG_TAG_OR_MD_RE = re.compile('!\\[(.*?)\\]\\((.*?)\\)|<img\\b[^>]*\\bsrc=[\\"\'](.*?)[\\"\']', re.IGNORECASE)
_MD_IMAGE_STANDALONE_RE
module-attribute
¶
_SYNTHETIC_CAPTION_RE
module-attribute
¶
VLMCaptioner ¶
VLMCaptioner(zotero_data_dir=None, provider=None, model=None, backup_model=None, local_model=None, max_images_per_doc=None, min_dimension=DEFAULT_VLM_MIN_IMAGE_DIMENSION, min_file_size=DEFAULT_VLM_MIN_FILE_SIZE_BYTES, timeout=None, openrouter_api_key=None, ollama_host=None)
Vision-Language Model figure enrichment service.
Filters uncaptioned figures, downscales them for prompt payload efficiency,
and invokes OpenRouter or Ollama to generate structured academic captions.
Persists results in sidecar cache image_captions.json.
Initialize the VLM figure captioner service.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Optional Zotero data directory path. |
None
|
provider
|
str | None
|
VLM provider name ('openrouter' or 'ollama'). |
None
|
model
|
str | None
|
Primary VLM model identifier. |
None
|
backup_model
|
str | None
|
Fallback VLM model identifier for OpenRouter. |
None
|
local_model
|
str | None
|
Local Ollama model identifier. |
None
|
max_images_per_doc
|
int | None
|
Maximum number of images to caption per document. |
None
|
min_dimension
|
int
|
Minimum pixel width/height required to process an image. |
DEFAULT_VLM_MIN_IMAGE_DIMENSION
|
min_file_size
|
int
|
Minimum byte size required to process an image. |
DEFAULT_VLM_MIN_FILE_SIZE_BYTES
|
timeout
|
int | None
|
Network request timeout in seconds. |
None
|
openrouter_api_key
|
str | None
|
Optional OpenRouter API key override. |
None
|
ollama_host
|
str | None
|
Optional Ollama base host URL. |
None
|
Source code in zocrates/rag/vlm_captioner.py
caption_image ¶
Generate structured academic caption for a single image.
Returns:
| Type | Description |
|---|---|
tuple[str | None, str, str]
|
Tuple of (caption_text_or_None, model_used, caption_source_flag). |
Source code in zocrates/rag/vlm_captioner.py
enrich_bundle_images ¶
Enrich uncaptioned figures in an item bundle with VLM captions.
Checks the sidecar cache (image_captions.json) first. Uncached/modified
images are filtered, downscaled, captioned, and added to the sidecar.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bundle_dir
|
Path
|
Item bundle directory ( |
required |
image_refs
|
list[str]
|
Image paths or URIs discovered in |
required |
force_refresh
|
bool
|
If True, bypass sidecar cache and re-caption. |
False
|
Returns:
| Type | Description |
|---|---|
dict[str, dict]
|
Mapping of relative_image_path -> caption_dict. |
Source code in zocrates/rag/vlm_captioner.py
filter_and_select_images ¶
Filter uncaptioned images by size, dimension, and aspect ratio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bundle_dir
|
Path
|
Item bundle directory. |
required |
image_refs
|
list[str]
|
Relative or absolute path strings found in Markdown. |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[str, Path]]
|
List of (rel_path, abs_path) tuples for selected images sorted by area descending, |
list[tuple[str, Path]]
|
capped at |
Source code in zocrates/rag/vlm_captioner.py
get_sidecar_path
staticmethod
¶
load_sidecar_captions ¶
Load image_captions.json from bundle directory if present.
Source code in zocrates/rag/vlm_captioner.py
save_sidecar_captions ¶
Save image_captions.json into bundle directory.
Source code in zocrates/rag/vlm_captioner.py
_mask_code_blocks ¶
Replace fenced code blocks with opaque placeholders.
Source code in zocrates/rag/vlm_captioner.py
_unmask_code_blocks ¶
Restore fenced code blocks from their placeholder tokens.
enrich_document_bundle ¶
Enrich uncaptioned figures in an item bundle Markdown with VLM descriptions.
Scans document.md in bundle_dir for figure blocks and standalone image links.
Figures with existing <synthetic_caption> (e.g. from Datalab OCR) are skipped.
Generated visual descriptions are injected as <synthetic_caption> sections
inside <figure data-type="image"> blocks, and saved to document.md.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bundle_dir
|
Path | str
|
Path to the item bundle directory (e.g. |
required |
zotero_data_dir
|
Path | None
|
Optional root Zotero data directory for loading settings. |
None
|
force_refresh
|
bool
|
If True, bypasses cache and regenerates captions. |
False
|
Returns:
| Type | Description |
|---|---|
str
|
The enriched Markdown string (or original string on error/disabled). |
Source code in zocrates/rag/vlm_captioner.py
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 | |
file_sha256 ¶
Compute SHA-256 hash of a file in 64 KiB blocks.
Source code in zocrates/rag/vlm_captioner.py
get_enable_vlm_captioning ¶
Return whether VLM image captioning and figure enrichment is enabled.
Checks ENABLE_VLM_CAPTIONING environment variable first;
if unset, falls back to enable_vlm_captioning in zocrates_config.json
(defaulting to True).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in zocrates/config.py
get_secure_api_key ¶
get_secure_api_key(key_name='openrouter_api_key', env_vars=('OPENROUTER_API_KEY', 'OPEN_ROUTER_API_KEY'))
Load a named API key from in-memory session environment variables.
Zotero Preferences / Login Manager serves as the secure persistent vault. Backend keys are in-memory session variables (os.environ) synced from Zotero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_name
|
str
|
Entry identifier (e.g., 'openrouter_api_key', 'openai_api_key'). |
'openrouter_api_key'
|
env_vars
|
list[str] | tuple[str, ...] | None
|
Environment variable names to check. |
('OPENROUTER_API_KEY', 'OPEN_ROUTER_API_KEY')
|
Returns:
| Type | Description |
|---|---|
str | None
|
The API key string or None if not found. |
Source code in zocrates/config.py
get_vlm_captioning_backup_model ¶
Return the backup VLM model identifier for cloud captioning fallback.
Checks VLM_CAPTIONING_BACKUP_MODEL environment variable first;
if unset, falls back to vlm_captioning_backup_model in zocrates_config.json
(defaulting to "openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Backup model identifier string. |
Source code in zocrates/config.py
get_vlm_captioning_local_model ¶
Return the local Ollama model name for figure captioning.
Checks VLM_CAPTIONING_LOCAL_MODEL environment variable first;
if unset, falls back to vlm_captioning_local_model in zocrates_config.json
(defaulting to "").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Local model name string. |
Source code in zocrates/config.py
get_vlm_captioning_model ¶
Return the primary VLM model identifier for cloud captioning.
Checks VLM_CAPTIONING_MODEL environment variable first;
if unset, falls back to vlm_captioning_model in zocrates_config.json
(defaulting to "openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Model identifier string. |
Source code in zocrates/config.py
get_vlm_captioning_provider ¶
Return the configured VLM provider ('openrouter' or 'ollama').
Checks VLM_CAPTIONING_PROVIDER environment variable first;
if unset, falls back to vlm_captioning_provider in zocrates_config.json
(defaulting to "openrouter").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Provider string ('openrouter' or 'ollama'). |
Source code in zocrates/config.py
get_vlm_max_images_per_doc ¶
Return the maximum number of images to caption per document.
Checks VLM_MAX_IMAGES_PER_DOC environment variable first;
if unset, falls back to vlm_max_images_per_doc in zocrates_config.json
(defaulting to 20).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Max images integer ceiling. |
Source code in zocrates/config.py
get_vlm_timeout_seconds ¶
Return the timeout in seconds for individual VLM captioning requests.
Checks VLM_TIMEOUT_SECONDS environment variable first;
if unset, falls back to vlm_timeout_seconds in zocrates_config.json
(defaulting to 30).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zotero_data_dir
|
Path | None
|
Path to the Zotero data directory. |
None
|
cfg
|
dict[str, Any] | None
|
Optional in-memory config dict. If provided, bypasses disk read. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Timeout integer in seconds. |
Source code in zocrates/config.py
normalize_image_relative_path ¶
Normalize an image reference (relative path or file:// URI) to relative and absolute paths.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image_ref
|
str
|
Raw path string from Markdown (e.g. 'images/fig1.png' or 'file:///path/to/fig1.png'). |
required |
bundle_dir
|
Path
|
Item bundle directory. |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, Path]
|
Tuple of (bundle_relative_path, absolute_path). |