OpenRAG 0.2.4__tar.gz → 0.2.5__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 (171) hide show
  1. openrag-0.2.5/PKG-INFO +196 -0
  2. openrag-0.2.5/README.md +166 -0
  3. {openrag-0.2.4 → openrag-0.2.5}/pyproject.toml +3 -21
  4. {openrag-0.2.4 → openrag-0.2.5}/src/agent.py +28 -0
  5. {openrag-0.2.4 → openrag-0.2.5}/src/api/auth.py +52 -20
  6. {openrag-0.2.4 → openrag-0.2.5}/src/api/chat.py +77 -83
  7. {openrag-0.2.4 → openrag-0.2.5}/src/api/connector_router.py +1 -7
  8. {openrag-0.2.4 → openrag-0.2.5}/src/api/connectors.py +60 -39
  9. {openrag-0.2.4 → openrag-0.2.5}/src/api/docling.py +21 -18
  10. {openrag-0.2.4 → openrag-0.2.5}/src/api/documents.py +49 -40
  11. {openrag-0.2.4 → openrag-0.2.5}/src/api/flows.py +21 -30
  12. openrag-0.2.5/src/api/keys.py +123 -0
  13. {openrag-0.2.4 → openrag-0.2.5}/src/api/knowledge_filter.py +119 -213
  14. openrag-0.2.5/src/api/langflow_files.py +224 -0
  15. openrag-0.2.5/src/api/models.py +165 -0
  16. openrag-0.2.5/src/api/nudges.py +67 -0
  17. {openrag-0.2.4 → openrag-0.2.5}/src/api/oidc.py +25 -35
  18. {openrag-0.2.4 → openrag-0.2.5}/src/api/provider_health.py +15 -12
  19. {openrag-0.2.4 → openrag-0.2.5}/src/api/provider_validation.py +3 -13
  20. openrag-0.2.5/src/api/router.py +172 -0
  21. openrag-0.2.5/src/api/search.py +61 -0
  22. {openrag-0.2.4 → openrag-0.2.5}/src/api/settings.py +506 -578
  23. {openrag-0.2.4 → openrag-0.2.5}/src/api/tasks.py +19 -12
  24. {openrag-0.2.4 → openrag-0.2.5}/src/api/upload.py +69 -44
  25. openrag-0.2.5/src/api/v1/chat.py +216 -0
  26. openrag-0.2.5/src/api/v1/documents.py +113 -0
  27. openrag-0.2.5/src/api/v1/knowledge_filters.py +112 -0
  28. openrag-0.2.5/src/api/v1/models.py +81 -0
  29. openrag-0.2.5/src/api/v1/search.py +74 -0
  30. openrag-0.2.5/src/api/v1/settings.py +73 -0
  31. openrag-0.2.5/src/config/model_constants.py +39 -0
  32. {openrag-0.2.4 → openrag-0.2.5}/src/config/settings.py +98 -64
  33. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/service.py +1 -3
  34. openrag-0.2.5/src/dependencies.py +218 -0
  35. openrag-0.2.5/src/main.py +995 -0
  36. {openrag-0.2.4 → openrag-0.2.5}/src/models/processors.py +5 -7
  37. openrag-0.2.5/src/openrag.egg-info/PKG-INFO +196 -0
  38. {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/SOURCES.txt +9 -3
  39. {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/requires.txt +1 -11
  40. {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/top_level.txt +1 -2
  41. {openrag-0.2.4 → openrag-0.2.5}/src/services/document_service.py +7 -33
  42. {openrag-0.2.4 → openrag-0.2.5}/src/services/models_service.py +55 -60
  43. {openrag-0.2.4 → openrag-0.2.5}/src/services/task_service.py +1 -9
  44. {openrag-0.2.4 → openrag-0.2.5}/src/session_manager.py +18 -17
  45. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/docker-compose.yml +20 -5
  46. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/openrag-documentation.pdf +0 -0
  47. openrag-0.2.5/src/tui/cli.py +509 -0
  48. openrag-0.2.5/src/tui/config_fields.py +235 -0
  49. {openrag-0.2.4 → openrag-0.2.5}/src/tui/main.py +42 -20
  50. {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/container_manager.py +55 -11
  51. {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/docling_manager.py +114 -42
  52. {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/env_manager.py +44 -22
  53. {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/config.py +161 -488
  54. {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/monitor.py +3 -13
  55. {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/welcome.py +10 -12
  56. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/command_modal.py +33 -3
  57. openrag-0.2.5/src/utils/docling_client.py +88 -0
  58. openrag-0.2.5/src/utils/document_processing.py +143 -0
  59. {openrag-0.2.4 → openrag-0.2.5}/src/utils/embedding_fields.py +2 -2
  60. {openrag-0.2.4 → openrag-0.2.5}/src/utils/embeddings.py +2 -2
  61. openrag-0.2.5/src/utils/env_utils.py +31 -0
  62. openrag-0.2.5/src/utils/langflow_utils.py +88 -0
  63. {openrag-0.2.4 → openrag-0.2.5}/src/utils/logging_config.py +27 -4
  64. openrag-0.2.5/src/utils/opensearch_utils.py +82 -0
  65. {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/client.py +1 -35
  66. openrag-0.2.5/src/utils/version_utils.py +35 -0
  67. openrag-0.2.4/PKG-INFO +0 -70
  68. openrag-0.2.4/README.md +0 -34
  69. openrag-0.2.4/src/api/keys.py +0 -183
  70. openrag-0.2.4/src/api/langflow_files.py +0 -296
  71. openrag-0.2.4/src/api/models.py +0 -200
  72. openrag-0.2.4/src/api/nudges.py +0 -72
  73. openrag-0.2.4/src/api/router.py +0 -209
  74. openrag-0.2.4/src/api/search.py +0 -53
  75. openrag-0.2.4/src/api/v1/chat.py +0 -301
  76. openrag-0.2.4/src/api/v1/documents.py +0 -150
  77. openrag-0.2.4/src/api/v1/knowledge_filters.py +0 -63
  78. openrag-0.2.4/src/api/v1/models.py +0 -111
  79. openrag-0.2.4/src/api/v1/search.py +0 -108
  80. openrag-0.2.4/src/api/v1/settings.py +0 -90
  81. openrag-0.2.4/src/api_key_middleware.py +0 -133
  82. openrag-0.2.4/src/auth_middleware.py +0 -84
  83. openrag-0.2.4/src/main.py +0 -1702
  84. openrag-0.2.4/src/openrag.egg-info/PKG-INFO +0 -70
  85. openrag-0.2.4/src/utils/document_processing.py +0 -446
  86. openrag-0.2.4/src/utils/process_pool.py +0 -13
  87. {openrag-0.2.4 → openrag-0.2.5}/LICENSE +0 -0
  88. {openrag-0.2.4 → openrag-0.2.5}/MANIFEST.in +0 -0
  89. {openrag-0.2.4 → openrag-0.2.5}/setup.cfg +0 -0
  90. {openrag-0.2.4 → openrag-0.2.5}/src/api/__init__.py +0 -0
  91. {openrag-0.2.4 → openrag-0.2.5}/src/api/v1/__init__.py +0 -0
  92. {openrag-0.2.4 → openrag-0.2.5}/src/auth_context.py +0 -0
  93. {openrag-0.2.4 → openrag-0.2.5}/src/config/__init__.py +0 -0
  94. {openrag-0.2.4 → openrag-0.2.5}/src/config/config_manager.py +0 -0
  95. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/__init__.py +0 -0
  96. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/base.py +0 -0
  97. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/connection_manager.py +0 -0
  98. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/google_drive/__init__.py +0 -0
  99. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/google_drive/connector.py +0 -0
  100. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/google_drive/oauth.py +0 -0
  101. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/langflow_connector_service.py +0 -0
  102. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/onedrive/__init__.py +0 -0
  103. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/onedrive/connector.py +0 -0
  104. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/onedrive/oauth.py +0 -0
  105. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/__init__.py +0 -0
  106. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/connector.py +0 -0
  107. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/oauth.py +0 -0
  108. {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/utils.py +0 -0
  109. {openrag-0.2.4 → openrag-0.2.5}/src/models/__init__.py +0 -0
  110. {openrag-0.2.4 → openrag-0.2.5}/src/models/tasks.py +0 -0
  111. {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/dependency_links.txt +0 -0
  112. {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/entry_points.txt +0 -0
  113. {openrag-0.2.4 → openrag-0.2.5}/src/services/__init__.py +0 -0
  114. {openrag-0.2.4 → openrag-0.2.5}/src/services/api_key_service.py +0 -0
  115. {openrag-0.2.4 → openrag-0.2.5}/src/services/auth_service.py +0 -0
  116. {openrag-0.2.4 → openrag-0.2.5}/src/services/chat_service.py +0 -0
  117. {openrag-0.2.4 → openrag-0.2.5}/src/services/conversation_persistence_service.py +0 -0
  118. {openrag-0.2.4 → openrag-0.2.5}/src/services/flows_service.py +0 -0
  119. {openrag-0.2.4 → openrag-0.2.5}/src/services/knowledge_filter_service.py +0 -0
  120. {openrag-0.2.4 → openrag-0.2.5}/src/services/langflow_file_service.py +0 -0
  121. {openrag-0.2.4 → openrag-0.2.5}/src/services/langflow_history_service.py +0 -0
  122. {openrag-0.2.4 → openrag-0.2.5}/src/services/langflow_mcp_service.py +0 -0
  123. {openrag-0.2.4 → openrag-0.2.5}/src/services/monitor_service.py +0 -0
  124. {openrag-0.2.4 → openrag-0.2.5}/src/services/search_service.py +0 -0
  125. {openrag-0.2.4 → openrag-0.2.5}/src/services/session_ownership_service.py +0 -0
  126. {openrag-0.2.4 → openrag-0.2.5}/src/tui/__init__.py +0 -0
  127. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/docker-compose.gpu.yml +0 -0
  128. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/ollama_embedding.json +0 -0
  129. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/ollama_llm.json +0 -0
  130. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/ollama_llm_text.json +0 -0
  131. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/watsonx_embedding.json +0 -0
  132. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/watsonx_llm.json +0 -0
  133. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/watsonx_llm_text.json +0 -0
  134. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/ingestion_flow.json +0 -0
  135. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/openrag_agent.json +0 -0
  136. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/openrag_nudges.json +0 -0
  137. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/openrag_url_mcp.json +0 -0
  138. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/docling.pdf +0 -0
  139. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/ibm_anthropic.pdf +0 -0
  140. {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/warmup_ocr.pdf +0 -0
  141. {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/__init__.py +0 -0
  142. {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/__init__.py +0 -0
  143. {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/diagnostics.py +0 -0
  144. {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/logs.py +0 -0
  145. {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/__init__.py +0 -0
  146. {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/clipboard.py +0 -0
  147. {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/platform.py +0 -0
  148. {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/startup_checks.py +0 -0
  149. {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/validation.py +0 -0
  150. {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/version_check.py +0 -0
  151. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/__init__.py +0 -0
  152. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/diagnostics_notification.py +0 -0
  153. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/error_notification.py +0 -0
  154. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/factory_reset_warning_modal.py +0 -0
  155. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/flow_backup_warning_modal.py +0 -0
  156. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/prune_options_modal.py +0 -0
  157. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/upgrade_instructions_modal.py +0 -0
  158. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/version_mismatch_warning_modal.py +0 -0
  159. {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/waves.py +0 -0
  160. {openrag-0.2.4 → openrag-0.2.5}/src/utils/__init__.py +0 -0
  161. {openrag-0.2.4 → openrag-0.2.5}/src/utils/acl_utils.py +0 -0
  162. {openrag-0.2.4 → openrag-0.2.5}/src/utils/container_utils.py +0 -0
  163. {openrag-0.2.4 → openrag-0.2.5}/src/utils/file_utils.py +0 -0
  164. {openrag-0.2.4 → openrag-0.2.5}/src/utils/gpu_detection.py +0 -0
  165. {openrag-0.2.4 → openrag-0.2.5}/src/utils/hash_utils.py +0 -0
  166. {openrag-0.2.4 → openrag-0.2.5}/src/utils/langflow_headers.py +0 -0
  167. {openrag-0.2.4 → openrag-0.2.5}/src/utils/opensearch_queries.py +0 -0
  168. {openrag-0.2.4 → openrag-0.2.5}/src/utils/paths.py +0 -0
  169. {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/__init__.py +0 -0
  170. {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/category.py +0 -0
  171. {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/message_id.py +0 -0
openrag-0.2.5/PKG-INFO ADDED
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: openrag
3
+ Version: 0.2.5
4
+ Summary: OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations.
5
+ Requires-Python: >=3.13
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: agentd>=0.2.2
9
+ Requires-Dist: aiofiles>=24.1.0
10
+ Requires-Dist: cryptography>=45.0.6
11
+ Requires-Dist: google-api-python-client>=2.143.0
12
+ Requires-Dist: google-auth-httplib2>=0.2.0
13
+ Requires-Dist: google-auth-oauthlib>=1.2.0
14
+ Requires-Dist: msal>=1.29.0
15
+ Requires-Dist: httpx>=0.27.0
16
+ Requires-Dist: opensearch-py[async]>=3.0.0
17
+ Requires-Dist: pyjwt>=2.8.0
18
+ Requires-Dist: python-multipart>=0.0.20
19
+ Requires-Dist: fastapi>=0.115.0
20
+ Requires-Dist: uvicorn>=0.35.0
21
+ Requires-Dist: boto3>=1.35.0
22
+ Requires-Dist: psutil>=7.0.0
23
+ Requires-Dist: rich>=13.0.0
24
+ Requires-Dist: textual>=0.45.0
25
+ Requires-Dist: python-dotenv>=1.0.0
26
+ Requires-Dist: textual-fspicker>=0.6.0
27
+ Requires-Dist: structlog>=25.4.0
28
+ Requires-Dist: zxcvbn>=4.5.0
29
+ Dynamic: license-file
30
+
31
+ <div align="center">
32
+
33
+ <img src="./docs/static/img/openrag-logo-dog.svg" alt="OpenRAG Logo" width="120"/>
34
+
35
+ # OpenRAG
36
+
37
+ <h3>
38
+ <em>Intelligent Agent-powered document search</em>
39
+ </h3>
40
+
41
+ <!-- Badges -->
42
+
43
+ [![Langflow](https://img.shields.io/badge/Langflow-1C1C1E?style=for-the-badge&logo=langflow)](https://github.com/langflow-ai/langflow)
44
+ [![OpenSearch](https://img.shields.io/badge/OpenSearch-005EB8?style=for-the-badge&logo=opensearch&logoColor=white)](https://github.com/opensearch-project/OpenSearch)
45
+ [![Docling](https://img.shields.io/badge/Docling-000000?style=for-the-badge)](https://github.com/docling-project/docling)
46
+
47
+ [![YouTube Channel](https://img.shields.io/youtube/channel/subscribers/UCn2bInQrjdDYKEEmbpwblLQ?label=Subscribe&style=social)](https://www.youtube.com/@OpenRAG/)
48
+ [![GitHub stars](https://img.shields.io/github/stars/langflow-ai/openrag?style=social)](https://github.com/langflow-ai/openrag/stargazers)
49
+ [![GitHub forks](https://img.shields.io/github/forks/langflow-ai/openrag?style=social)](https://github.com/langflow-ai/openrag/network/members)
50
+
51
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/langflow-ai/openrag)
52
+
53
+ </div>
54
+
55
+ ---
56
+
57
+ OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations.
58
+
59
+ Users can upload, process, and query documents through a chat interface backed by large language models and semantic search capabilities. The system utilizes Langflow for document ingestion, retrieval workflows, and intelligent nudges, providing a seamless RAG experience.
60
+
61
+ Built with [Starlette](https://github.com/Kludex/starlette) and [Next.js](https://github.com/vercel/next.js).
62
+ Powered by [OpenSearch](https://github.com/opensearch-project/OpenSearch), [Langflow](https://github.com/langflow-ai/langflow), and [Docling](https://github.com/docling-project/docling).
63
+
64
+ ---
65
+
66
+ <div align="center">
67
+ <img src="./docs/static/img/openrag_readme_downsized.gif" alt="OpenRAG Demo" width="100%"/>
68
+ </div>
69
+
70
+ ## ✨ Highlight Features
71
+
72
+ - **Pre-packaged & ready to run** - All core tools are hooked up and ready to go, just install and run
73
+ - **Agentic RAG workflows** - Advanced orchestration with re-ranking and multi-agent coordination
74
+ - **Document ingestion** - Handles messy, real-world data with intelligent parsing
75
+ - **Drag-and-drop workflow builder** - Visual interface powered by Langflow for rapid iteration
76
+ - **Modular enterprise add-ons** - Extend functionality when you need it
77
+ - **Enterprise search at any scale** - Powered by OpenSearch for production-grade performance
78
+
79
+ ## 🔄 How OpenRAG Works
80
+
81
+ OpenRAG follows a streamlined workflow to transform your documents into intelligent, searchable knowledge:
82
+
83
+ <div align="center">
84
+ <img src="./docs/static/img/workflow-diagram.svg" alt="OpenRAG Workflow Diagram" width="800"/>
85
+ </div>
86
+
87
+ ## 🚀 Install OpenRAG
88
+
89
+ To get started with OpenRAG, see the installation guides in the OpenRAG documentation:
90
+
91
+ * [Quickstart](https://docs.openr.ag/quickstart)
92
+ * [Install the OpenRAG Python package](https://docs.openr.ag/install-options)
93
+ * [Deploy self-managed services with Docker or Podman](https://docs.openr.ag/docker)
94
+
95
+ ## ✨ Quick Start Workflow
96
+
97
+ <div align="center">
98
+
99
+ <img src="./docs/static/img/uv_run_openrag.png" alt="Use uv run openrag to start" width="300"/>
100
+
101
+ **1. Launch OpenRAG**
102
+
103
+ ↓
104
+
105
+ <img src="./docs/static/img/add_knowledge_openrag.png" alt="Add files or folders as knowledge" width="300"/>
106
+
107
+ **2. Add Knowledge**
108
+
109
+ ↓
110
+
111
+ <img src="./docs/static/img/chat_openrag.png" alt="Start Chatting with your knowledge" width="700"/>
112
+
113
+ **3. Start Chatting**
114
+
115
+ </div>
116
+
117
+ ## 📦 SDKs
118
+
119
+ Integrate OpenRAG into your applications with our official SDKs:
120
+
121
+ ### Python SDK
122
+ ```bash
123
+ pip install openrag-sdk
124
+ ```
125
+
126
+ **Quick Example:**
127
+ ```python
128
+ import asyncio
129
+ from openrag_sdk import OpenRAGClient
130
+
131
+
132
+ async def main():
133
+ async with OpenRAGClient() as client:
134
+ response = await client.chat.create(message="What is RAG?")
135
+ print(response.response)
136
+
137
+
138
+ if __name__ == "__main__":
139
+ asyncio.run(main())
140
+ ```
141
+
142
+ 📖 [Full Python SDK Documentation](https://pypi.org/project/openrag-sdk/)
143
+
144
+ ### TypeScript/JavaScript SDK
145
+ ```bash
146
+ npm install openrag-sdk
147
+ ```
148
+
149
+ **Quick Example:**
150
+ ```typescript
151
+ import { OpenRAGClient } from "openrag-sdk";
152
+
153
+ const client = new OpenRAGClient();
154
+ const response = await client.chat.create({ message: "What is RAG?" });
155
+ console.log(response.response);
156
+ ```
157
+
158
+ 📖 [Full TypeScript/JavaScript SDK Documentation](https://www.npmjs.com/package/openrag-sdk)
159
+
160
+ ## 🔌 Model Context Protocol (MCP)
161
+
162
+ Connect AI assistants like Cursor and Claude Desktop to your OpenRAG knowledge base:
163
+
164
+ ```bash
165
+ pip install openrag-mcp
166
+ ```
167
+
168
+ **Quick Example (Cursor/Claude Desktop config):**
169
+ ```json
170
+ {
171
+ "mcpServers": {
172
+ "openrag": {
173
+ "command": "uvx",
174
+ "args": ["openrag-mcp"],
175
+ "env": {
176
+ "OPENRAG_URL": "http://localhost:3000",
177
+ "OPENRAG_API_KEY": "your_api_key_here"
178
+ }
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ The MCP server provides tools for RAG-enhanced chat, semantic search, and settings management.
185
+
186
+ 📖 [Full MCP Documentation](https://pypi.org/project/openrag-mcp/)
187
+
188
+ ## 🛠️ Development
189
+
190
+ For developers who want to [contribute to OpenRAG](https://docs.openr.ag/support/contribute) or set up a development environment, see [CONTRIBUTING.md](CONTRIBUTING.md).
191
+
192
+ ## 🆘 Troubleshooting
193
+
194
+ For assistance with OpenRAG, see [Troubleshoot OpenRAG](https://docs.openr.ag/support/troubleshoot) and visit the [Discussions page](https://github.com/langflow-ai/openrag/discussions).
195
+
196
+ To report a bug or submit a feature request, visit the [Issues page](https://github.com/langflow-ai/openrag/issues).
@@ -0,0 +1,166 @@
1
+ <div align="center">
2
+
3
+ <img src="./docs/static/img/openrag-logo-dog.svg" alt="OpenRAG Logo" width="120"/>
4
+
5
+ # OpenRAG
6
+
7
+ <h3>
8
+ <em>Intelligent Agent-powered document search</em>
9
+ </h3>
10
+
11
+ <!-- Badges -->
12
+
13
+ [![Langflow](https://img.shields.io/badge/Langflow-1C1C1E?style=for-the-badge&logo=langflow)](https://github.com/langflow-ai/langflow)
14
+ [![OpenSearch](https://img.shields.io/badge/OpenSearch-005EB8?style=for-the-badge&logo=opensearch&logoColor=white)](https://github.com/opensearch-project/OpenSearch)
15
+ [![Docling](https://img.shields.io/badge/Docling-000000?style=for-the-badge)](https://github.com/docling-project/docling)
16
+
17
+ [![YouTube Channel](https://img.shields.io/youtube/channel/subscribers/UCn2bInQrjdDYKEEmbpwblLQ?label=Subscribe&style=social)](https://www.youtube.com/@OpenRAG/)
18
+ [![GitHub stars](https://img.shields.io/github/stars/langflow-ai/openrag?style=social)](https://github.com/langflow-ai/openrag/stargazers)
19
+ [![GitHub forks](https://img.shields.io/github/forks/langflow-ai/openrag?style=social)](https://github.com/langflow-ai/openrag/network/members)
20
+
21
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/langflow-ai/openrag)
22
+
23
+ </div>
24
+
25
+ ---
26
+
27
+ OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations.
28
+
29
+ Users can upload, process, and query documents through a chat interface backed by large language models and semantic search capabilities. The system utilizes Langflow for document ingestion, retrieval workflows, and intelligent nudges, providing a seamless RAG experience.
30
+
31
+ Built with [Starlette](https://github.com/Kludex/starlette) and [Next.js](https://github.com/vercel/next.js).
32
+ Powered by [OpenSearch](https://github.com/opensearch-project/OpenSearch), [Langflow](https://github.com/langflow-ai/langflow), and [Docling](https://github.com/docling-project/docling).
33
+
34
+ ---
35
+
36
+ <div align="center">
37
+ <img src="./docs/static/img/openrag_readme_downsized.gif" alt="OpenRAG Demo" width="100%"/>
38
+ </div>
39
+
40
+ ## ✨ Highlight Features
41
+
42
+ - **Pre-packaged & ready to run** - All core tools are hooked up and ready to go, just install and run
43
+ - **Agentic RAG workflows** - Advanced orchestration with re-ranking and multi-agent coordination
44
+ - **Document ingestion** - Handles messy, real-world data with intelligent parsing
45
+ - **Drag-and-drop workflow builder** - Visual interface powered by Langflow for rapid iteration
46
+ - **Modular enterprise add-ons** - Extend functionality when you need it
47
+ - **Enterprise search at any scale** - Powered by OpenSearch for production-grade performance
48
+
49
+ ## 🔄 How OpenRAG Works
50
+
51
+ OpenRAG follows a streamlined workflow to transform your documents into intelligent, searchable knowledge:
52
+
53
+ <div align="center">
54
+ <img src="./docs/static/img/workflow-diagram.svg" alt="OpenRAG Workflow Diagram" width="800"/>
55
+ </div>
56
+
57
+ ## 🚀 Install OpenRAG
58
+
59
+ To get started with OpenRAG, see the installation guides in the OpenRAG documentation:
60
+
61
+ * [Quickstart](https://docs.openr.ag/quickstart)
62
+ * [Install the OpenRAG Python package](https://docs.openr.ag/install-options)
63
+ * [Deploy self-managed services with Docker or Podman](https://docs.openr.ag/docker)
64
+
65
+ ## ✨ Quick Start Workflow
66
+
67
+ <div align="center">
68
+
69
+ <img src="./docs/static/img/uv_run_openrag.png" alt="Use uv run openrag to start" width="300"/>
70
+
71
+ **1. Launch OpenRAG**
72
+
73
+ ↓
74
+
75
+ <img src="./docs/static/img/add_knowledge_openrag.png" alt="Add files or folders as knowledge" width="300"/>
76
+
77
+ **2. Add Knowledge**
78
+
79
+ ↓
80
+
81
+ <img src="./docs/static/img/chat_openrag.png" alt="Start Chatting with your knowledge" width="700"/>
82
+
83
+ **3. Start Chatting**
84
+
85
+ </div>
86
+
87
+ ## 📦 SDKs
88
+
89
+ Integrate OpenRAG into your applications with our official SDKs:
90
+
91
+ ### Python SDK
92
+ ```bash
93
+ pip install openrag-sdk
94
+ ```
95
+
96
+ **Quick Example:**
97
+ ```python
98
+ import asyncio
99
+ from openrag_sdk import OpenRAGClient
100
+
101
+
102
+ async def main():
103
+ async with OpenRAGClient() as client:
104
+ response = await client.chat.create(message="What is RAG?")
105
+ print(response.response)
106
+
107
+
108
+ if __name__ == "__main__":
109
+ asyncio.run(main())
110
+ ```
111
+
112
+ 📖 [Full Python SDK Documentation](https://pypi.org/project/openrag-sdk/)
113
+
114
+ ### TypeScript/JavaScript SDK
115
+ ```bash
116
+ npm install openrag-sdk
117
+ ```
118
+
119
+ **Quick Example:**
120
+ ```typescript
121
+ import { OpenRAGClient } from "openrag-sdk";
122
+
123
+ const client = new OpenRAGClient();
124
+ const response = await client.chat.create({ message: "What is RAG?" });
125
+ console.log(response.response);
126
+ ```
127
+
128
+ 📖 [Full TypeScript/JavaScript SDK Documentation](https://www.npmjs.com/package/openrag-sdk)
129
+
130
+ ## 🔌 Model Context Protocol (MCP)
131
+
132
+ Connect AI assistants like Cursor and Claude Desktop to your OpenRAG knowledge base:
133
+
134
+ ```bash
135
+ pip install openrag-mcp
136
+ ```
137
+
138
+ **Quick Example (Cursor/Claude Desktop config):**
139
+ ```json
140
+ {
141
+ "mcpServers": {
142
+ "openrag": {
143
+ "command": "uvx",
144
+ "args": ["openrag-mcp"],
145
+ "env": {
146
+ "OPENRAG_URL": "http://localhost:3000",
147
+ "OPENRAG_API_KEY": "your_api_key_here"
148
+ }
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ The MCP server provides tools for RAG-enhanced chat, semantic search, and settings management.
155
+
156
+ 📖 [Full MCP Documentation](https://pypi.org/project/openrag-mcp/)
157
+
158
+ ## 🛠️ Development
159
+
160
+ For developers who want to [contribute to OpenRAG](https://docs.openr.ag/support/contribute) or set up a development environment, see [CONTRIBUTING.md](CONTRIBUTING.md).
161
+
162
+ ## 🆘 Troubleshooting
163
+
164
+ For assistance with OpenRAG, see [Troubleshoot OpenRAG](https://docs.openr.ag/support/troubleshoot) and visit the [Discussions page](https://github.com/langflow-ai/openrag/discussions).
165
+
166
+ To report a bug or submit a feature request, visit the [Issues page](https://github.com/langflow-ai/openrag/issues).
@@ -4,16 +4,14 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "openrag"
7
- version = "0.2.4"
8
- description = "Add your description here"
7
+ version = "0.2.5"
8
+ description = "OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
11
11
  dependencies = [
12
12
  "agentd>=0.2.2",
13
13
  "aiofiles>=24.1.0",
14
14
  "cryptography>=45.0.6",
15
- "docling[vlm]==2.41.0; sys_platform != 'darwin'",
16
- "docling[ocrmac,vlm]==2.41.0; sys_platform == 'darwin'",
17
15
  "google-api-python-client>=2.143.0",
18
16
  "google-auth-httplib2>=0.2.0",
19
17
  "google-auth-oauthlib>=1.2.0",
@@ -22,8 +20,7 @@ dependencies = [
22
20
  "opensearch-py[async]>=3.0.0",
23
21
  "pyjwt>=2.8.0",
24
22
  "python-multipart>=0.0.20",
25
- "starlette>=0.47.1",
26
- "torch>=2.7.1",
23
+ "fastapi>=0.115.0",
27
24
  "uvicorn>=0.35.0",
28
25
  "boto3>=1.35.0",
29
26
  "psutil>=7.0.0",
@@ -32,9 +29,6 @@ dependencies = [
32
29
  "python-dotenv>=1.0.0",
33
30
  "textual-fspicker>=0.6.0",
34
31
  "structlog>=25.4.0",
35
- "docling-serve==1.5.0",
36
- "docling-core==2.48.1",
37
- "easyocr>=1.7.1; sys_platform != 'darwin'",
38
32
  "zxcvbn>=4.5.0"
39
33
  ]
40
34
 
@@ -48,15 +42,3 @@ openrag = "tui.main:run_tui"
48
42
  package = true
49
43
 
50
44
 
51
- [tool.uv.sources]
52
- torch = [
53
- { index = "pytorch-cu128", marker = "sys_platform == 'linux' and platform_machine == 'x86_64'" },
54
- ]
55
- torchvision = [
56
- { index = "pytorch-cu128", marker = "sys_platform == 'linux' and platform_machine == 'x86_64'" },
57
- ]
58
-
59
- [[tool.uv.index]]
60
- name = "pytorch-cu128"
61
- url = "https://download.pytorch.org/whl/cu128"
62
- explicit = true
@@ -197,6 +197,18 @@ async def async_response_stream(
197
197
  sample_data=str(potential_tool_fields)[:500]
198
198
  )
199
199
 
200
+ # Detect response.completed event and log usage
201
+ if isinstance(chunk_data, dict) and chunk_data.get("type") == "response.completed":
202
+ response_data = chunk_data.get("response", {})
203
+ usage = response_data.get("usage")
204
+ if usage:
205
+ logger.info(
206
+ "Stream usage data",
207
+ input_tokens=usage.get("input_tokens"),
208
+ output_tokens=usage.get("output_tokens"),
209
+ total_tokens=usage.get("total_tokens"),
210
+ )
211
+
200
212
  # Middleware: Detect implicit tool calls and inject standardized events
201
213
  # This helps Granite 3.3 8b and other models that don't emit standard markers
202
214
  if isinstance(chunk_data, dict) and not detected_tool_call:
@@ -487,6 +499,7 @@ async def async_chat_stream(
487
499
 
488
500
  full_response = ""
489
501
  response_id = None
502
+ usage_data = None
490
503
  async for chunk in async_stream(
491
504
  async_client,
492
505
  prompt,
@@ -506,6 +519,10 @@ async def async_chat_stream(
506
519
  response_id = chunk_data["id"]
507
520
  elif "response_id" in chunk_data:
508
521
  response_id = chunk_data["response_id"]
522
+ # Capture usage from response.completed event
523
+ if chunk_data.get("type") == "response.completed":
524
+ response_obj = chunk_data.get("response", {})
525
+ usage_data = response_obj.get("usage")
509
526
  except:
510
527
  pass
511
528
  yield chunk
@@ -518,6 +535,9 @@ async def async_chat_stream(
518
535
  "response_id": response_id,
519
536
  "timestamp": datetime.now(),
520
537
  }
538
+ # Store usage data if available (from response.completed event)
539
+ if usage_data:
540
+ assistant_message["response_data"] = {"usage": usage_data}
521
541
  conversation_state["messages"].append(assistant_message)
522
542
 
523
543
  # Store the conversation thread with its response_id
@@ -676,6 +696,7 @@ async def async_langflow_chat_stream(
676
696
 
677
697
  full_response = ""
678
698
  response_id = None
699
+ usage_data = None
679
700
  collected_chunks = [] # Store all chunks for function call data
680
701
 
681
702
  async for chunk in async_stream(
@@ -700,6 +721,10 @@ async def async_langflow_chat_stream(
700
721
  response_id = chunk_data["id"]
701
722
  elif "response_id" in chunk_data:
702
723
  response_id = chunk_data["response_id"]
724
+ # Capture usage from response.completed event
725
+ if chunk_data.get("type") == "response.completed":
726
+ response_obj = chunk_data.get("response", {})
727
+ usage_data = response_obj.get("usage")
703
728
  except:
704
729
  pass
705
730
  yield chunk
@@ -713,6 +738,9 @@ async def async_langflow_chat_stream(
713
738
  "timestamp": datetime.now(),
714
739
  "chunks": collected_chunks, # Store complete chunk data for function calls
715
740
  }
741
+ # Store usage data if available (from response.completed event)
742
+ if usage_data:
743
+ assistant_message["response_data"] = {"usage": usage_data}
716
744
  conversation_state["messages"].append(assistant_message)
717
745
 
718
746
  # Store the conversation thread with its response_id
@@ -1,22 +1,48 @@
1
- from starlette.requests import Request
2
- from starlette.responses import JSONResponse
1
+ from typing import Optional
2
+
3
+ from fastapi import Depends, Request
4
+ from fastapi.responses import JSONResponse
3
5
  from utils.telemetry import TelemetryClient, Category, MessageId
4
6
 
7
+ from dependencies import (
8
+ get_auth_service,
9
+ get_optional_user,
10
+ get_current_user,
11
+ )
12
+ from pydantic import BaseModel
13
+ from session_manager import User
14
+
15
+
16
+ class AuthInitBody(BaseModel):
17
+ connector_type: str
18
+ purpose: str = "data_source"
19
+ name: Optional[str] = None
20
+ redirect_uri: Optional[str] = None
21
+
22
+
23
+ class AuthCallbackBody(BaseModel):
24
+ connection_id: str
25
+ authorization_code: str
26
+ state: str
5
27
 
6
- async def auth_init(request: Request, auth_service, session_manager):
28
+
29
+ class TokenIntrospectBody(BaseModel):
30
+ token: str
31
+
32
+
33
+ async def auth_init(
34
+ body: AuthInitBody,
35
+ request: Request,
36
+ auth_service=Depends(get_auth_service),
37
+ user: Optional[User] = Depends(get_optional_user),
38
+ ):
7
39
  """Initialize OAuth flow for authentication or data source connection"""
8
40
  try:
9
- data = await request.json()
10
- connector_type = data.get("connector_type")
11
- purpose = data.get("purpose", "data_source")
12
- connection_name = data.get("name", f"{connector_type}_{purpose}")
13
- redirect_uri = data.get("redirect_uri")
14
-
15
- user = getattr(request.state, "user", None)
41
+ connection_name = body.name or f"{body.connector_type}_{body.purpose}"
16
42
  user_id = user.user_id if user else None
17
43
 
18
44
  result = await auth_service.init_oauth(
19
- connector_type, purpose, connection_name, redirect_uri, user_id
45
+ body.connector_type, body.purpose, connection_name, body.redirect_uri, user_id
20
46
  )
21
47
  return JSONResponse(result)
22
48
 
@@ -29,16 +55,15 @@ async def auth_init(request: Request, auth_service, session_manager):
29
55
  )
30
56
 
31
57
 
32
- async def auth_callback(request: Request, auth_service, session_manager):
58
+ async def auth_callback(
59
+ body: AuthCallbackBody,
60
+ request: Request,
61
+ auth_service=Depends(get_auth_service),
62
+ ):
33
63
  """Handle OAuth callback - exchange authorization code for tokens"""
34
64
  try:
35
- data = await request.json()
36
- connection_id = data.get("connection_id")
37
- authorization_code = data.get("authorization_code")
38
- state = data.get("state")
39
-
40
65
  result = await auth_service.handle_oauth_callback(
41
- connection_id, authorization_code, state, request
66
+ body.connection_id, body.authorization_code, body.state, request
42
67
  )
43
68
 
44
69
  await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_OAUTH_CALLBACK)
@@ -69,13 +94,20 @@ async def auth_callback(request: Request, auth_service, session_manager):
69
94
  return JSONResponse({"error": f"Callback failed: {str(e)}"}, status_code=500)
70
95
 
71
96
 
72
- async def auth_me(request: Request, auth_service, session_manager):
97
+ async def auth_me(
98
+ request: Request,
99
+ auth_service=Depends(get_auth_service),
100
+ user: Optional[User] = Depends(get_optional_user),
101
+ ):
73
102
  """Get current user information"""
74
103
  result = await auth_service.get_user_info(request)
75
104
  return JSONResponse(result)
76
105
 
77
106
 
78
- async def auth_logout(request: Request, auth_service, session_manager):
107
+ async def auth_logout(
108
+ auth_service=Depends(get_auth_service),
109
+ user: User = Depends(get_current_user),
110
+ ):
79
111
  """Logout user by clearing auth cookie"""
80
112
  await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_LOGOUT)
81
113
  response = JSONResponse(