visual-rag-toolkit 0.1.3__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/PKG-INFO +5 -2
  2. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/README.md +4 -1
  3. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/__init__.py +1 -1
  4. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/ui/sidebar.py +22 -0
  5. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/ui/upload.py +1 -1
  6. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/pyproject.toml +25 -1
  7. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/__init__.py +25 -10
  8. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/demo_runner.py +3 -5
  9. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/indexing/qdrant_indexer.py +4 -2
  10. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/retrieval/multi_vector.py +6 -7
  11. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/retrieval/two_stage.py +0 -1
  12. visual_rag_toolkit-0.1.3/demo/example_metadata_mapping_sigir.json +0 -37
  13. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/.github/workflows/ci.yaml +0 -0
  14. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/.github/workflows/publish_pypi.yaml +0 -0
  15. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/.gitignore +0 -0
  16. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/LICENSE +0 -0
  17. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/README.md +0 -0
  18. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/__init__.py +0 -0
  19. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/analyze_results.py +0 -0
  20. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/benchmark_datasets.txt +0 -0
  21. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/prepare_submission.py +0 -0
  22. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/quick_test.py +0 -0
  23. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/run_vidore.py +0 -0
  24. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/vidore_beir_qdrant/run_qdrant_beir.py +0 -0
  25. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/vidore_tatdqa_test/__init__.py +0 -0
  26. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/vidore_tatdqa_test/dataset_loader.py +0 -0
  27. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/vidore_tatdqa_test/metrics.py +0 -0
  28. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/vidore_tatdqa_test/run_qdrant.py +0 -0
  29. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/benchmarks/vidore_tatdqa_test/sweep_eval.py +0 -0
  30. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/app.py +0 -0
  31. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/commands.py +0 -0
  32. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/config.py +0 -0
  33. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/download_models.py +0 -0
  34. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/evaluation.py +0 -0
  35. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/indexing.py +0 -0
  36. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/qdrant_utils.py +0 -0
  37. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/results.py +0 -0
  38. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/test_qdrant_connection.py +0 -0
  39. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/ui/__init__.py +0 -0
  40. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/ui/benchmark.py +0 -0
  41. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/ui/header.py +0 -0
  42. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/demo/ui/playground.py +0 -0
  43. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/examples/COMMANDS.md +0 -0
  44. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/examples/config.yaml +0 -0
  45. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/examples/process_pdfs.py +0 -0
  46. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/examples/search_demo.py +0 -0
  47. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/requirements.txt +0 -0
  48. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/tests/__init__.py +0 -0
  49. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/tests/test_config.py +0 -0
  50. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/tests/test_pdf_processor.py +0 -0
  51. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/tests/test_pooling.py +0 -0
  52. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/tests/test_strategies.py +0 -0
  53. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/cli/__init__.py +0 -0
  54. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/cli/main.py +0 -0
  55. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/config.py +0 -0
  56. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/embedding/__init__.py +0 -0
  57. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/embedding/pooling.py +0 -0
  58. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/embedding/visual_embedder.py +0 -0
  59. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/indexing/__init__.py +0 -0
  60. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/indexing/cloudinary_uploader.py +0 -0
  61. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/indexing/pdf_processor.py +0 -0
  62. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/indexing/pipeline.py +0 -0
  63. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/preprocessing/__init__.py +0 -0
  64. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/preprocessing/crop_empty.py +0 -0
  65. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/qdrant_admin.py +0 -0
  66. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/retrieval/__init__.py +0 -0
  67. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/retrieval/single_stage.py +0 -0
  68. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/retrieval/three_stage.py +0 -0
  69. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/visualization/__init__.py +0 -0
  70. {visual_rag_toolkit-0.1.3 → visual_rag_toolkit-0.1.4}/visual_rag/visualization/saliency.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: visual-rag-toolkit
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: End-to-end visual document retrieval with ColPali, featuring two-stage pooling for scalable search
5
5
  Project-URL: Homepage, https://github.com/Ara-Yeroyan/visual-rag-toolkit
6
6
  Project-URL: Documentation, https://github.com/Ara-Yeroyan/visual-rag-toolkit#readme
@@ -88,9 +88,12 @@ Description-Content-Type: text/markdown
88
88
  [![PyPI](https://img.shields.io/pypi/v/visual-rag-toolkit)](https://pypi.org/project/visual-rag-toolkit/)
89
89
  [![Python](https://img.shields.io/pypi/pyversions/visual-rag-toolkit)](https://pypi.org/project/visual-rag-toolkit/)
90
90
  [![License](https://img.shields.io/pypi/l/visual-rag-toolkit)](LICENSE)
91
+ [![Demo](https://img.shields.io/badge/Demo-Hugging%20Face-yellow)](https://huggingface.co/spaces/Yeroyan/visual-rag-toolkit)
91
92
 
92
93
  End-to-end visual document retrieval toolkit featuring **fast multi-stage retrieval** (prefetch with pooled vectors + exact MaxSim reranking).
93
94
 
95
+ **[Try the Live Demo](https://huggingface.co/spaces/Yeroyan/visual-rag-toolkit)** - Upload PDFs, index to Qdrant, and query with visual retrieval.
96
+
94
97
  This repo contains:
95
98
  - a **Python package** (`visual_rag`)
96
99
  - a **Streamlit demo app** (`demo/`)
@@ -368,7 +371,7 @@ If you use this toolkit in your research, please cite:
368
371
 
369
372
  ```bibtex
370
373
  @software{visual_rag_toolkit,
371
- title = {Visual RAG Toolkit: Scalable Visual Document Retrieval with Two-Stage Pooling},
374
+ title = {Visual RAG Toolkit: Scalable Visual Document Retrieval with 1D Convolutional Pooling},
372
375
  author = {Ara Yeroyan},
373
376
  year = {2026},
374
377
  url = {https://github.com/Ara-Yeroyan/visual-rag-toolkit}
@@ -3,9 +3,12 @@
3
3
  [![PyPI](https://img.shields.io/pypi/v/visual-rag-toolkit)](https://pypi.org/project/visual-rag-toolkit/)
4
4
  [![Python](https://img.shields.io/pypi/pyversions/visual-rag-toolkit)](https://pypi.org/project/visual-rag-toolkit/)
5
5
  [![License](https://img.shields.io/pypi/l/visual-rag-toolkit)](LICENSE)
6
+ [![Demo](https://img.shields.io/badge/Demo-Hugging%20Face-yellow)](https://huggingface.co/spaces/Yeroyan/visual-rag-toolkit)
6
7
 
7
8
  End-to-end visual document retrieval toolkit featuring **fast multi-stage retrieval** (prefetch with pooled vectors + exact MaxSim reranking).
8
9
 
10
+ **[Try the Live Demo](https://huggingface.co/spaces/Yeroyan/visual-rag-toolkit)** - Upload PDFs, index to Qdrant, and query with visual retrieval.
11
+
9
12
  This repo contains:
10
13
  - a **Python package** (`visual_rag`)
11
14
  - a **Streamlit demo app** (`demo/`)
@@ -283,7 +286,7 @@ If you use this toolkit in your research, please cite:
283
286
 
284
287
  ```bibtex
285
288
  @software{visual_rag_toolkit,
286
- title = {Visual RAG Toolkit: Scalable Visual Document Retrieval with Two-Stage Pooling},
289
+ title = {Visual RAG Toolkit: Scalable Visual Document Retrieval with 1D Convolutional Pooling},
287
290
  author = {Ara Yeroyan},
288
291
  year = {2026},
289
292
  url = {https://github.com/Ara-Yeroyan/visual-rag-toolkit}
@@ -7,4 +7,4 @@ A Streamlit-based UI for:
7
7
  - Interactive playground for visual search
8
8
  """
9
9
 
10
- __version__ = "0.1.0"
10
+ __version__ = "0.1.4"
@@ -16,6 +16,28 @@ from demo.qdrant_utils import (
16
16
 
17
17
 
18
18
  def render_sidebar():
19
+ # CSS to make sidebar metrics smaller
20
+ st.markdown("""
21
+ <style>
22
+ /* Smaller metrics in sidebar */
23
+ [data-testid="stSidebar"] [data-testid="stMetricValue"] {
24
+ font-size: 1.2rem !important;
25
+ }
26
+ [data-testid="stSidebar"] [data-testid="stMetricLabel"] {
27
+ font-size: 0.75rem !important;
28
+ }
29
+ /* Smaller expander headers in sidebar */
30
+ [data-testid="stSidebar"] [data-testid="stExpander"] summary {
31
+ font-size: 0.9rem !important;
32
+ }
33
+ /* Compact subheaders */
34
+ [data-testid="stSidebar"] h3 {
35
+ font-size: 1rem !important;
36
+ margin-bottom: 0.5rem !important;
37
+ }
38
+ </style>
39
+ """, unsafe_allow_html=True)
40
+
19
41
  with st.sidebar:
20
42
  st.subheader("🔑 Qdrant Credentials")
21
43
 
@@ -449,7 +449,7 @@ def process_pdfs(uploaded_files, config):
449
449
 
450
450
  if total_uploaded > 0:
451
451
  st.session_state["upload_success"] = f"Uploaded {total_uploaded} pages to {collection_name}"
452
- st.balloons()
452
+ st.rerun() # Immediately refresh to show success toast + balloons
453
453
 
454
454
  except Exception as e:
455
455
  st.error(f"❌ Processing error: {e}")
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "visual-rag-toolkit"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "End-to-end visual document retrieval with ColPali, featuring two-stage pooling for scalable search"
9
9
  readme = "README.md"
10
10
  license = {file = "LICENSE"}
@@ -151,3 +151,27 @@ python_version = "3.9"
151
151
  warn_return_any = true
152
152
  warn_unused_configs = true
153
153
  ignore_missing_imports = true
154
+
155
+ [tool.bumpversion]
156
+ current_version = "0.1.4"
157
+ parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
158
+ serialize = ["{major}.{minor}.{patch}"]
159
+ commit = true
160
+ tag = true
161
+ tag_name = "v{new_version}"
162
+ message = "Bump version: {current_version} → {new_version}"
163
+
164
+ [[tool.bumpversion.files]]
165
+ filename = "pyproject.toml"
166
+ search = 'version = "{current_version}"'
167
+ replace = 'version = "{new_version}"'
168
+
169
+ [[tool.bumpversion.files]]
170
+ filename = "visual_rag/__init__.py"
171
+ search = '__version__ = "{current_version}"'
172
+ replace = '__version__ = "{new_version}"'
173
+
174
+ [[tool.bumpversion.files]]
175
+ filename = "demo/__init__.py"
176
+ search = '__version__ = "{current_version}"'
177
+ replace = '__version__ = "{new_version}"'
@@ -33,17 +33,17 @@ Each component works independently - use only what you need.
33
33
 
34
34
  import logging
35
35
 
36
- __version__ = "0.1.3"
36
+ __version__ = "0.1.4"
37
37
 
38
38
 
39
39
  def setup_logging(level: str = "INFO", format: str = None) -> None:
40
40
  """
41
41
  Configure logging for visual_rag package.
42
-
42
+
43
43
  Args:
44
44
  level: Log level ("DEBUG", "INFO", "WARNING", "ERROR")
45
45
  format: Custom format string. Default shows time, level, and message.
46
-
46
+
47
47
  Example:
48
48
  >>> import visual_rag
49
49
  >>> visual_rag.setup_logging("INFO")
@@ -51,13 +51,13 @@ def setup_logging(level: str = "INFO", format: str = None) -> None:
51
51
  """
52
52
  if format is None:
53
53
  format = "[%(asctime)s] %(levelname)s - %(message)s"
54
-
54
+
55
55
  logging.basicConfig(
56
56
  level=getattr(logging, level.upper(), logging.INFO),
57
57
  format=format,
58
58
  datefmt="%H:%M:%S",
59
59
  )
60
-
60
+
61
61
  # Also set the visual_rag logger specifically
62
62
  logger = logging.getLogger("visual_rag")
63
63
  logger.setLevel(getattr(logging, level.upper(), logging.INFO))
@@ -111,13 +111,16 @@ try:
111
111
  except ImportError:
112
112
  QdrantAdmin = None
113
113
 
114
- try:
115
- from visual_rag.demo_runner import demo
116
- except ImportError:
117
- demo = None
114
+ # demo is lazily imported to avoid RuntimeWarning when running as __main__
115
+ # Access via visual_rag.demo() which triggers __getattr__
118
116
 
119
117
  # Config utilities (always available)
120
- from visual_rag.config import get, get_section, load_config
118
+ try:
119
+ from visual_rag.config import get, get_section, load_config
120
+ except ImportError:
121
+ get = None
122
+ get_section = None
123
+ load_config = None
121
124
 
122
125
  __all__ = [
123
126
  # Version
@@ -138,3 +141,15 @@ __all__ = [
138
141
  # Logging
139
142
  "setup_logging",
140
143
  ]
144
+
145
+
146
+ def __getattr__(name: str):
147
+ """Lazy import for demo to avoid RuntimeWarning when running as __main__."""
148
+ if name == "demo":
149
+ try:
150
+ from visual_rag.demo_runner import demo
151
+
152
+ return demo
153
+ except ImportError:
154
+ return None
155
+ raise AttributeError(f"module 'visual_rag' has no attribute {name!r}")
@@ -52,13 +52,11 @@ def demo(
52
52
  cmd = [sys.executable, "-m", "streamlit", "run", str(app_path)]
53
53
  cmd += ["--server.address", str(host)]
54
54
  cmd += ["--server.port", str(int(port))]
55
- cmd += ["--server.headless", "true" if headless else "false"]
55
+ # headless=true prevents browser from auto-opening; open_browser overrides
56
+ should_be_headless = headless and not open_browser
57
+ cmd += ["--server.headless", "true" if should_be_headless else "false"]
56
58
  cmd += ["--browser.gatherUsageStats", "false"]
57
59
  cmd += ["--server.runOnSave", "false"]
58
- cmd += ["--browser.serverAddress", str(host)]
59
- if not open_browser:
60
- cmd += ["--browser.serverPort", str(int(port))]
61
- cmd += ["--browser.open", "false"]
62
60
 
63
61
  if extra_args:
64
62
  cmd += list(extra_args)
@@ -335,7 +335,9 @@ class QdrantIndexer:
335
335
  return val.tolist()
336
336
  return val
337
337
 
338
- def _build_qdrant_points(batch_points: List[Dict[str, Any]]) -> List[qdrant_models.PointStruct]:
338
+ def _build_qdrant_points(
339
+ batch_points: List[Dict[str, Any]],
340
+ ) -> List[qdrant_models.PointStruct]:
339
341
  qdrant_points: List[qdrant_models.PointStruct] = []
340
342
  for p in batch_points:
341
343
  global_pooled = p.get("global_pooled_embedding")
@@ -382,7 +384,7 @@ class QdrantIndexer:
382
384
  )
383
385
 
384
386
  logger.info(f" ✅ Uploaded {len(points)} points to Qdrant")
385
-
387
+
386
388
  if delay_between_batches > 0:
387
389
  if _is_cancelled():
388
390
  return 0
@@ -56,14 +56,10 @@ class MultiVectorRetriever:
56
56
  )
57
57
 
58
58
  qdrant_url = (
59
- qdrant_url
60
- or os.getenv("QDRANT_URL")
61
- or os.getenv("SIGIR_QDRANT_URL") # legacy
59
+ qdrant_url or os.getenv("QDRANT_URL") or os.getenv("SIGIR_QDRANT_URL") # legacy
62
60
  )
63
61
  if not qdrant_url:
64
- raise ValueError(
65
- "QDRANT_URL is required (pass qdrant_url or set env var)."
66
- )
62
+ raise ValueError("QDRANT_URL is required (pass qdrant_url or set env var).")
67
63
 
68
64
  qdrant_api_key = (
69
65
  qdrant_api_key
@@ -97,7 +93,10 @@ class MultiVectorRetriever:
97
93
  _ = client.get_collections()
98
94
  except Exception as e:
99
95
  msg = str(e)
100
- if "StatusCode.PERMISSION_DENIED" in msg or "http2 header with status: 403" in msg:
96
+ if (
97
+ "StatusCode.PERMISSION_DENIED" in msg
98
+ or "http2 header with status: 403" in msg
99
+ ):
101
100
  client = _make_client(False)
102
101
  else:
103
102
  raise
@@ -22,7 +22,6 @@ from typing import Any, Dict, List, Optional, Union
22
22
 
23
23
  import numpy as np
24
24
  import torch
25
-
26
25
  from qdrant_client.http import models as qdrant_models
27
26
  from qdrant_client.models import FieldCondition, Filter, MatchAny, MatchValue
28
27
 
@@ -1,37 +0,0 @@
1
- {
2
- "filenames": {
3
- "sigir2025-llms": {
4
- "year": 2025,
5
- "source": "Conference Paper",
6
- "district": null,
7
- "doc_type": "paper",
8
- "project": "sigir-demo",
9
- "tags": ["llms", "retrieval"]
10
- },
11
- "sigir2025-ginger": {
12
- "year": 2025,
13
- "source": "Conference Paper",
14
- "district": null,
15
- "doc_type": "paper",
16
- "project": "sigir-demo",
17
- "tags": ["ginger", "case-study"]
18
- },
19
- "2505.15859v1": {
20
- "year": 2025,
21
- "source": "arXiv",
22
- "district": null,
23
- "doc_type": "preprint",
24
- "project": "sigir-demo",
25
- "tags": ["arxiv", "ranking"]
26
- },
27
- "2507.04942v2": {
28
- "year": 2025,
29
- "source": "arXiv",
30
- "district": null,
31
- "doc_type": "preprint",
32
- "project": "sigir-demo",
33
- "tags": ["arxiv", "rag"]
34
- }
35
- }
36
- }
37
-