openrag 0.4.1.dev21__tar.gz → 0.5.0.dev1__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 (179) hide show
  1. {openrag-0.4.1.dev21/src/openrag.egg-info → openrag-0.5.0.dev1}/PKG-INFO +11 -3
  2. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/pyproject.toml +13 -4
  3. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/agent.py +3 -15
  4. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/auth.py +69 -9
  5. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/chat.py +9 -3
  6. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/connector_router.py +13 -2
  7. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/connectors.py +9 -10
  8. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/documents.py +9 -3
  9. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/keys.py +1 -1
  10. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/knowledge_filter.py +2 -5
  11. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/provider_validation.py +3 -3
  12. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/search.py +0 -1
  13. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/settings.py +256 -74
  14. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/upload.py +16 -2
  15. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/v1/chat.py +6 -0
  16. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/v1/settings.py +3 -2
  17. openrag-0.5.0.dev1/src/auth/ibm_auth.py +90 -0
  18. openrag-0.5.0.dev1/src/bootstrap.py +23 -0
  19. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/config/config_manager.py +50 -14
  20. openrag-0.5.0.dev1/src/config/paths.py +93 -0
  21. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/config/settings.py +72 -30
  22. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/connection_manager.py +87 -2
  23. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/google_drive/connector.py +58 -53
  24. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/google_drive/oauth.py +90 -41
  25. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/ibm_cos/connector.py +0 -5
  26. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/langflow_connector_service.py +18 -2
  27. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/onedrive/connector.py +8 -11
  28. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/onedrive/oauth.py +60 -65
  29. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/service.py +6 -2
  30. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/sharepoint/connector.py +8 -11
  31. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/sharepoint/oauth.py +61 -68
  32. openrag-0.5.0.dev1/src/dependencies.py +419 -0
  33. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/main.py +513 -199
  34. openrag-0.5.0.dev1/src/mcp_http/server.py +229 -0
  35. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/models/processors.py +52 -2
  36. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1/src/openrag.egg-info}/PKG-INFO +11 -3
  37. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/openrag.egg-info/SOURCES.txt +8 -1
  38. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/openrag.egg-info/requires.txt +10 -2
  39. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/openrag.egg-info/top_level.txt +3 -0
  40. openrag-0.5.0.dev1/src/services/__init__.py +0 -0
  41. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/api_key_service.py +16 -15
  42. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/auth_service.py +116 -84
  43. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/chat_service.py +42 -13
  44. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/conversation_persistence_service.py +3 -2
  45. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/flows_service.py +252 -187
  46. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/langflow_file_service.py +52 -43
  47. openrag-0.5.0.dev1/src/services/langflow_mcp_service.py +281 -0
  48. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/models_service.py +54 -11
  49. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/search_service.py +117 -69
  50. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/session_ownership_service.py +2 -1
  51. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/session_manager.py +24 -10
  52. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/docker-compose.yml +13 -6
  53. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/ingestion_flow.json +2136 -1737
  54. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/openrag_agent.json +1193 -998
  55. openrag-0.5.0.dev1/src/tui/_assets/flows/openrag_nudges.json +4674 -0
  56. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/openrag_url_mcp.json +3588 -2753
  57. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/config_fields.py +21 -0
  58. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/main.py +81 -1
  59. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/managers/docling_manager.py +42 -63
  60. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/managers/env_manager.py +32 -11
  61. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/screens/config.py +11 -2
  62. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/utils/startup_checks.py +19 -86
  63. openrag-0.5.0.dev1/src/utils/__init__.py +0 -0
  64. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/acl_utils.py +5 -2
  65. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/document_processing.py +39 -0
  66. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/embedding_fields.py +39 -12
  67. openrag-0.5.0.dev1/src/utils/encryption.py +209 -0
  68. openrag-0.5.0.dev1/src/utils/langflow_headers.py +76 -0
  69. openrag-0.5.0.dev1/src/utils/logging_config.py +321 -0
  70. openrag-0.5.0.dev1/src/utils/opensearch_utils.py +387 -0
  71. openrag-0.5.0.dev1/src/utils/run_mode_utils.py +36 -0
  72. openrag-0.4.1.dev21/src/dependencies.py +0 -222
  73. openrag-0.4.1.dev21/src/services/langflow_mcp_service.py +0 -275
  74. openrag-0.4.1.dev21/src/tui/_assets/flows/openrag_nudges.json +0 -4851
  75. openrag-0.4.1.dev21/src/tui/_assets/openrag-documents/openrag-documentation.pdf +0 -0
  76. openrag-0.4.1.dev21/src/utils/langflow_headers.py +0 -79
  77. openrag-0.4.1.dev21/src/utils/logging_config.py +0 -151
  78. openrag-0.4.1.dev21/src/utils/opensearch_utils.py +0 -160
  79. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/LICENSE +0 -0
  80. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/MANIFEST.in +0 -0
  81. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/README.md +0 -0
  82. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/setup.cfg +0 -0
  83. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/__init__.py +0 -0
  84. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/docling.py +0 -0
  85. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/flows.py +0 -0
  86. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/langflow_files.py +0 -0
  87. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/models.py +0 -0
  88. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/nudges.py +0 -0
  89. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/oidc.py +0 -0
  90. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/provider_health.py +0 -0
  91. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/router.py +0 -0
  92. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/tasks.py +0 -0
  93. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/v1/__init__.py +0 -0
  94. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/v1/documents.py +0 -0
  95. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/v1/knowledge_filters.py +0 -0
  96. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/v1/models.py +0 -0
  97. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/api/v1/search.py +0 -0
  98. {openrag-0.4.1.dev21/src/config → openrag-0.5.0.dev1/src/auth}/__init__.py +0 -0
  99. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/auth_context.py +0 -0
  100. {openrag-0.4.1.dev21/src/models → openrag-0.5.0.dev1/src/config}/__init__.py +0 -0
  101. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/config/embedding_constants.py +0 -0
  102. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/config/model_constants.py +0 -0
  103. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/__init__.py +0 -0
  104. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/aws_s3/__init__.py +0 -0
  105. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/aws_s3/api.py +0 -0
  106. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/aws_s3/auth.py +0 -0
  107. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/aws_s3/connector.py +0 -0
  108. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/aws_s3/models.py +0 -0
  109. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/aws_s3/support.py +0 -0
  110. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/base.py +0 -0
  111. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/google_drive/__init__.py +0 -0
  112. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/ibm_cos/__init__.py +0 -0
  113. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/ibm_cos/api.py +0 -0
  114. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/ibm_cos/auth.py +0 -0
  115. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/ibm_cos/models.py +0 -0
  116. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/ibm_cos/support.py +0 -0
  117. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/onedrive/__init__.py +0 -0
  118. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/sharepoint/__init__.py +0 -0
  119. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/connectors/sharepoint/utils.py +0 -0
  120. {openrag-0.4.1.dev21/src/services → openrag-0.5.0.dev1/src/mcp_http}/__init__.py +0 -0
  121. {openrag-0.4.1.dev21/src/utils → openrag-0.5.0.dev1/src/models}/__init__.py +0 -0
  122. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/models/tasks.py +0 -0
  123. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/models/url.py +0 -0
  124. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/openrag.egg-info/dependency_links.txt +0 -0
  125. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/openrag.egg-info/entry_points.txt +0 -0
  126. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/document_service.py +0 -0
  127. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/knowledge_filter_service.py +0 -0
  128. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/langflow_history_service.py +0 -0
  129. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/monitor_service.py +0 -0
  130. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/services/task_service.py +0 -0
  131. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/__init__.py +0 -0
  132. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/docker-compose.gpu.yml +0 -0
  133. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/components/ollama_embedding.json +0 -0
  134. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/components/ollama_llm.json +0 -0
  135. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/components/ollama_llm_text.json +0 -0
  136. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/components/watsonx_embedding.json +0 -0
  137. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/components/watsonx_llm.json +0 -0
  138. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/flows/components/watsonx_llm_text.json +0 -0
  139. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/openrag-documents/docling.pdf +0 -0
  140. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/openrag-documents/ibm_anthropic.pdf +0 -0
  141. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/_assets/openrag-documents/warmup_ocr.pdf +0 -0
  142. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/cli.py +0 -0
  143. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/managers/__init__.py +0 -0
  144. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/managers/container_manager.py +0 -0
  145. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/screens/__init__.py +0 -0
  146. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/screens/diagnostics.py +0 -0
  147. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/screens/logs.py +0 -0
  148. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/screens/monitor.py +0 -0
  149. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/screens/welcome.py +0 -0
  150. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/utils/__init__.py +0 -0
  151. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/utils/clipboard.py +0 -0
  152. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/utils/platform.py +0 -0
  153. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/utils/validation.py +0 -0
  154. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/utils/version_check.py +0 -0
  155. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/__init__.py +0 -0
  156. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/command_modal.py +0 -0
  157. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/diagnostics_notification.py +0 -0
  158. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/error_notification.py +0 -0
  159. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/factory_reset_warning_modal.py +0 -0
  160. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/flow_backup_warning_modal.py +0 -0
  161. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/prune_options_modal.py +0 -0
  162. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/upgrade_instructions_modal.py +0 -0
  163. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/version_mismatch_warning_modal.py +0 -0
  164. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/tui/widgets/waves.py +0 -0
  165. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/container_utils.py +0 -0
  166. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/docling_client.py +0 -0
  167. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/embeddings.py +0 -0
  168. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/env_utils.py +0 -0
  169. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/file_utils.py +0 -0
  170. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/gpu_detection.py +0 -0
  171. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/hash_utils.py +0 -0
  172. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/langflow_utils.py +0 -0
  173. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/opensearch_queries.py +0 -0
  174. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/paths.py +0 -0
  175. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/telemetry/__init__.py +0 -0
  176. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/telemetry/category.py +0 -0
  177. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/telemetry/client.py +0 -0
  178. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/telemetry/message_id.py +0 -0
  179. {openrag-0.4.1.dev21 → openrag-0.5.0.dev1}/src/utils/version_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openrag
3
- Version: 0.4.1.dev21
3
+ Version: 0.5.0.dev1
4
4
  Summary: OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations.
5
5
  Classifier: Development Status :: 4 - Beta
6
6
  Classifier: Environment :: Console
@@ -17,14 +17,15 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: agentd>=0.8.1
19
19
  Requires-Dist: aiofiles>=24.1.0
20
- Requires-Dist: cryptography>=45.0.6
20
+ Requires-Dist: aiohttp>=3.13.4
21
+ Requires-Dist: cryptography>=46.0.6
21
22
  Requires-Dist: google-api-python-client>=2.143.0
22
23
  Requires-Dist: google-auth-httplib2>=0.2.0
23
24
  Requires-Dist: google-auth-oauthlib>=1.2.0
24
25
  Requires-Dist: msal>=1.29.0
25
26
  Requires-Dist: httpx>=0.27.0
26
27
  Requires-Dist: opensearch-py[async]>=3.0.0
27
- Requires-Dist: pyjwt>=2.8.0
28
+ Requires-Dist: pyjwt>=2.12.0
28
29
  Requires-Dist: python-multipart>=0.0.20
29
30
  Requires-Dist: fastapi>=0.115.0
30
31
  Requires-Dist: uvicorn>=0.35.0
@@ -37,10 +38,17 @@ Requires-Dist: python-dotenv>=1.0.0
37
38
  Requires-Dist: textual-fspicker>=0.6.0
38
39
  Requires-Dist: structlog>=25.4.0
39
40
  Requires-Dist: zxcvbn>=4.5.0
41
+ Requires-Dist: prometheus-fastapi-instrumentator>=7.1.0
40
42
  Requires-Dist: litellm==1.83.3
41
43
  Requires-Dist: pyyaml>=6.0
42
44
  Requires-Dist: tiktoken>=0.7.0
45
+ Requires-Dist: prometheus-fastapi-instrumentator>=7.1.0
46
+ Requires-Dist: fastmcp>=3.2.3
43
47
  Requires-Dist: openai>=2.30.0
48
+ Requires-Dist: tenacity>=9.1.4
49
+ Requires-Dist: pygments>=2.20.0
50
+ Requires-Dist: pyasn1>=0.6.3
51
+ Requires-Dist: requests>=2.33.0
44
52
  Dynamic: license-file
45
53
 
46
54
  <div align="center">
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "openrag"
7
- version = "0.4.1.dev21"
7
+ version = "0.5.0.dev1"
8
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"
@@ -23,14 +23,15 @@ classifiers = [
23
23
  dependencies = [
24
24
  "agentd>=0.8.1",
25
25
  "aiofiles>=24.1.0",
26
- "cryptography>=45.0.6",
26
+ "aiohttp>=3.13.4",
27
+ "cryptography>=46.0.6",
27
28
  "google-api-python-client>=2.143.0",
28
29
  "google-auth-httplib2>=0.2.0",
29
30
  "google-auth-oauthlib>=1.2.0",
30
31
  "msal>=1.29.0",
31
32
  "httpx>=0.27.0",
32
33
  "opensearch-py[async]>=3.0.0",
33
- "pyjwt>=2.8.0",
34
+ "pyjwt>=2.12.0",
34
35
  "python-multipart>=0.0.20",
35
36
  "fastapi>=0.115.0",
36
37
  "uvicorn>=0.35.0",
@@ -43,19 +44,27 @@ dependencies = [
43
44
  "textual-fspicker>=0.6.0",
44
45
  "structlog>=25.4.0",
45
46
  "zxcvbn>=4.5.0",
47
+ "prometheus-fastapi-instrumentator>=7.1.0",
46
48
  "litellm==1.83.3",
47
49
  "pyyaml>=6.0",
48
50
  "tiktoken>=0.7.0",
51
+ "prometheus-fastapi-instrumentator>=7.1.0",
52
+ "fastmcp>=3.2.3",
49
53
  "openai>=2.30.0",
54
+ "tenacity>=9.1.4",
55
+ "pygments>=2.20.0",
56
+ "pyasn1>=0.6.3",
57
+ "requests>=2.33.0",
50
58
  ]
51
59
 
52
60
  [dependency-groups]
53
- dev = ["pytest>=8", "pytest-asyncio>=0.21.0", "pytest-mock>=3.12.0", "pytest-cov>=4.0.0"]
61
+ dev = ["pytest>=9.0.3", "pytest-asyncio>=0.21.0", "pytest-mock>=3.12.0", "pytest-cov>=4.0.0"]
54
62
 
55
63
  [project.scripts]
56
64
  openrag = "tui.main:run_tui"
57
65
 
58
66
  [tool.uv]
59
67
  package = true
68
+ override-dependencies = ["python-dotenv>=1.1.0"]
60
69
 
61
70
 
@@ -138,9 +138,6 @@ async def async_response_stream(
138
138
  detected_tool_call = False
139
139
  async for chunk in response:
140
140
  chunk_count += 1
141
- logger.debug(
142
- "Stream chunk received", chunk_count=chunk_count, chunk=str(chunk)
143
- )
144
141
 
145
142
  import json
146
143
 
@@ -258,10 +255,7 @@ async def async_response_stream(
258
255
  logger.info("Response generated", log_prefix=log_prefix, response=full_response)
259
256
 
260
257
  except Exception as e:
261
- logger.error("Exception in streaming", error=str(e))
262
- import traceback
263
-
264
- traceback.print_exc()
258
+ logger.exception("[AGENT] Streaming failed")
265
259
  raise
266
260
 
267
261
 
@@ -316,10 +310,7 @@ async def async_response(
316
310
  msg = error_msg
317
311
  raise ValueError(msg)
318
312
  except Exception as e:
319
- logger.error("Exception in non-streaming response", error=str(e))
320
- import traceback
321
-
322
- traceback.print_exc()
313
+ logger.exception("[AGENT] Non-streaming response failed")
323
314
  raise
324
315
 
325
316
 
@@ -387,10 +378,7 @@ async def async_langflow_stream(
387
378
  yield chunk
388
379
  logger.debug("Langflow stream completed")
389
380
  except Exception as e:
390
- logger.error("Exception in langflow stream", error=str(e))
391
- import traceback
392
-
393
- traceback.print_exc()
381
+ logger.exception("[AGENT] Langflow stream failed")
394
382
  raise
395
383
 
396
384
 
@@ -1,8 +1,12 @@
1
1
  from typing import Optional
2
2
 
3
- from fastapi import Depends, Request
3
+ from fastapi import Depends, HTTPException, Request
4
4
  from fastapi.responses import JSONResponse
5
5
  from utils.telemetry import TelemetryClient, Category, MessageId
6
+ from utils.version_utils import OPENRAG_VERSION
7
+ from utils.logging_config import get_logger
8
+
9
+ logger = get_logger(__name__)
6
10
 
7
11
  from dependencies import (
8
12
  get_auth_service,
@@ -20,6 +24,8 @@ class AuthInitBody(BaseModel):
20
24
  redirect_uri: Optional[str] = None
21
25
 
22
26
 
27
+
28
+
23
29
  class AuthCallbackBody(BaseModel):
24
30
  connection_id: str
25
31
  authorization_code: str
@@ -47,9 +53,7 @@ async def auth_init(
47
53
  return JSONResponse(result)
48
54
 
49
55
  except Exception as e:
50
- import traceback
51
-
52
- traceback.print_exc()
56
+ logger.exception("[AUTH] OAuth init failed")
53
57
  return JSONResponse(
54
58
  {"error": f"Failed to initialize OAuth: {str(e)}"}, status_code=500
55
59
  )
@@ -74,9 +78,14 @@ async def auth_callback(
74
78
  response = JSONResponse(
75
79
  {k: v for k, v in result.items() if k != "jwt_token"}
76
80
  )
81
+ # Store only the raw JWT (without "Bearer " prefix) in the cookie.
82
+ # The prefix is added by the OpenSearch client when building the Authorization header.
83
+ jwt_value = result["jwt_token"]
84
+ if jwt_value.startswith("Bearer "):
85
+ jwt_value = jwt_value[len("Bearer "):]
77
86
  response.set_cookie(
78
87
  key="auth_token",
79
- value=result["jwt_token"],
88
+ value=jwt_value,
80
89
  httponly=True,
81
90
  secure=False,
82
91
  samesite="lax",
@@ -87,9 +96,7 @@ async def auth_callback(
87
96
  return JSONResponse(result)
88
97
 
89
98
  except Exception as e:
90
- import traceback
91
-
92
- traceback.print_exc()
99
+ logger.exception("[AUTH] OAuth callback failed")
93
100
  await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_OAUTH_FAILED)
94
101
  return JSONResponse({"error": f"Callback failed: {str(e)}"}, status_code=500)
95
102
 
@@ -101,6 +108,7 @@ async def auth_me(
101
108
  ):
102
109
  """Get current user information"""
103
110
  result = await auth_service.get_user_info(request)
111
+ result["version"] = OPENRAG_VERSION
104
112
  return JSONResponse(result)
105
113
 
106
114
 
@@ -108,8 +116,28 @@ async def auth_logout(
108
116
  auth_service=Depends(get_auth_service),
109
117
  user: User = Depends(get_current_user),
110
118
  ):
111
- """Logout user by clearing auth cookie"""
119
+ """Logout user by clearing auth cookie(s)"""
120
+ from config.settings import IBM_AUTH_ENABLED, IBM_SESSION_COOKIE_NAME
121
+
112
122
  await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_LOGOUT)
123
+
124
+ if IBM_AUTH_ENABLED:
125
+ # Best-effort: clear cookies from the browser, but warn that the
126
+ # server-side AMS session is NOT terminated. The IBM session cookie
127
+ # is owned by Traefik/AMS — it may be re-injected on the next
128
+ # proxied request if AMS still considers the session active.
129
+ response = JSONResponse(
130
+ {
131
+ "status": "partial_logout",
132
+ "message": "Browser cookies cleared, but the IBM session is "
133
+ "managed by the identity provider and may still be active. "
134
+ "Please log out through IBM Watsonx Data for full session termination.",
135
+ }
136
+ )
137
+ response.delete_cookie(key=IBM_SESSION_COOKIE_NAME, httponly=True, samesite="lax")
138
+ response.delete_cookie(key="ibm-auth-basic", httponly=True, samesite="lax")
139
+ return response
140
+
113
141
  response = JSONResponse(
114
142
  {"status": "logged_out", "message": "Successfully logged out"}
115
143
  )
@@ -120,3 +148,35 @@ async def auth_logout(
120
148
  )
121
149
 
122
150
  return response
151
+
152
+
153
+ async def ibm_login(request: Request):
154
+ """IBM login endpoint.
155
+
156
+ Production: Traefik intercepts the request, validates Basic credentials
157
+ with AMS, and sets the ibm-openrag-session cookie before forwarding here.
158
+ This handler just returns 200 — no cookie work needed.
159
+
160
+ Local dev (no Traefik): stores the Basic Auth header in ibm-auth-basic
161
+ cookie so subsequent requests can be authenticated by _get_ibm_user.
162
+ """
163
+ from config.settings import IBM_AUTH_ENABLED, IBM_SESSION_COOKIE_NAME
164
+
165
+ if not IBM_AUTH_ENABLED:
166
+ raise HTTPException(status_code=404, detail="IBM auth is not enabled")
167
+
168
+ response = JSONResponse({"status": "ok"})
169
+
170
+ # Local dev fallback only — in production Traefik sets the session cookie.
171
+ if not request.cookies.get(IBM_SESSION_COOKIE_NAME):
172
+ auth_header = request.headers.get("Authorization", "")
173
+ if auth_header.startswith("Basic "):
174
+ # secure =True not needed for local development
175
+ response.set_cookie(
176
+ "ibm-auth-basic",
177
+ auth_header,
178
+ httponly=True,
179
+ samesite="lax",
180
+ )
181
+
182
+ return response
@@ -101,6 +101,9 @@ async def langflow_endpoint(
101
101
  previous_response_id=body.previous_response_id,
102
102
  stream=True,
103
103
  filter_id=body.filter_id,
104
+ owner=user.user_id,
105
+ owner_name=user.name,
106
+ owner_email=user.email,
104
107
  ),
105
108
  media_type="text/event-stream",
106
109
  headers={
@@ -118,13 +121,14 @@ async def langflow_endpoint(
118
121
  previous_response_id=body.previous_response_id,
119
122
  stream=False,
120
123
  filter_id=body.filter_id,
124
+ owner=user.user_id,
125
+ owner_name=user.name,
126
+ owner_email=user.email,
121
127
  )
122
128
  return JSONResponse(result)
123
129
 
124
130
  except Exception as e:
125
- import traceback
126
- traceback.print_exc()
127
- logger.error("Langflow request failed", error=str(e))
131
+ logger.exception("[CHAT] Langflow request failed")
128
132
  return JSONResponse(
129
133
  {"error": f"Langflow request failed: {str(e)}"}, status_code=500
130
134
  )
@@ -139,6 +143,7 @@ async def chat_history_endpoint(
139
143
  history = await chat_service.get_chat_history(user.user_id)
140
144
  return JSONResponse(history)
141
145
  except Exception as e:
146
+ logger.exception("[CHAT] Failed to get chat history")
142
147
  return JSONResponse(
143
148
  {"error": f"Failed to get chat history: {str(e)}"}, status_code=500
144
149
  )
@@ -153,6 +158,7 @@ async def langflow_history_endpoint(
153
158
  history = await chat_service.get_langflow_history(user.user_id)
154
159
  return JSONResponse(history)
155
160
  except Exception as e:
161
+ logger.exception("[CHAT] Failed to get langflow history")
156
162
  return JSONResponse(
157
163
  {"error": f"Failed to get langflow history: {str(e)}"}, status_code=500
158
164
  )
@@ -50,11 +50,22 @@ class ConnectorRouter:
50
50
  return await self.get_active_service().get_connector(connection_id)
51
51
 
52
52
  async def sync_specific_files(
53
- self, connection_id: str, user_id: str, file_list: list, jwt_token: str = None, file_infos: list = None
53
+ self,
54
+ connection_id: str,
55
+ user_id: str,
56
+ file_list: list,
57
+ jwt_token: str = None,
58
+ file_infos: list = None,
59
+ ingest_settings: dict = None,
54
60
  ):
55
61
  """Sync specific files using the active service."""
56
62
  return await self.get_active_service().sync_specific_files(
57
- connection_id, user_id, file_list, jwt_token, file_infos=file_infos
63
+ connection_id,
64
+ user_id,
65
+ file_list,
66
+ jwt_token,
67
+ file_infos=file_infos,
68
+ ingest_settings=ingest_settings,
58
69
  )
59
70
 
60
71
  def __getattr__(self, name):
@@ -1,4 +1,4 @@
1
- from typing import Any, List, Optional
1
+ from typing import Any, Dict, List, Optional
2
2
 
3
3
  from fastapi import Depends, Request
4
4
  from pydantic import BaseModel
@@ -93,6 +93,8 @@ class ConnectorSyncBody(BaseModel):
93
93
  sync_all: bool = False
94
94
  # When set, only ingest files from these buckets (IBM COS specific).
95
95
  bucket_filter: Optional[List[str]] = None
96
+ # Per-request ingest options from the connector upload UI (overrides saved Knowledge for this sync).
97
+ settings: Optional[Dict[str, Any]] = None
96
98
 
97
99
 
98
100
  async def list_connectors(
@@ -106,7 +108,7 @@ async def list_connectors(
106
108
  )
107
109
  return JSONResponse({"connectors": connector_types})
108
110
  except Exception as e:
109
- logger.info("Error listing connectors", error=str(e))
111
+ logger.error("[CONNECTOR] Error listing connectors", error=str(e))
110
112
  return JSONResponse({"connectors": []})
111
113
 
112
114
 
@@ -197,13 +199,14 @@ async def connector_sync(
197
199
  if selected_files:
198
200
  # Explicit files selected (e.g., from file picker) - sync those specific files
199
201
  from .documents import _ensure_index_exists
200
- await _ensure_index_exists()
202
+ await _ensure_index_exists(jwt_token)
201
203
  task_id = await connector_service.sync_specific_files(
202
204
  working_connection.connection_id,
203
205
  user.user_id,
204
206
  selected_files,
205
207
  jwt_token=jwt_token,
206
208
  file_infos=file_infos,
209
+ ingest_settings=body.settings,
207
210
  )
208
211
  elif body.sync_all or body.bucket_filter:
209
212
  # Full ingest: discover and ingest all files (or files from specific buckets).
@@ -241,6 +244,7 @@ async def connector_sync(
241
244
  user.user_id,
242
245
  all_file_ids,
243
246
  jwt_token=jwt_token,
247
+ ingest_settings=body.settings,
244
248
  )
245
249
  else:
246
250
  # sync_all: ingest everything the connector can see
@@ -549,15 +553,10 @@ async def connector_webhook(
549
553
  )
550
554
 
551
555
  except Exception as e:
552
- logger.error(
553
- "Failed to process webhook for connection",
556
+ logger.exception(
557
+ "[CONNECTOR] Failed to process webhook",
554
558
  connection_id=connection.connection_id,
555
- error=str(e),
556
559
  )
557
- import traceback
558
-
559
- traceback.print_exc()
560
-
561
560
  return JSONResponse(
562
561
  {
563
562
  "status": "error",
@@ -99,10 +99,16 @@ async def delete_documents_by_filename_core(
99
99
  )
100
100
 
101
101
 
102
- async def _ensure_index_exists():
102
+ async def _ensure_index_exists(jwt_token: str = None):
103
103
  """Create the OpenSearch index if it doesn't exist yet."""
104
104
  from main import init_index
105
- await init_index()
105
+ from config.settings import IBM_AUTH_ENABLED, clients as app_clients
106
+
107
+ opensearch_client = None
108
+ if IBM_AUTH_ENABLED and jwt_token:
109
+ opensearch_client = app_clients.create_user_opensearch_client(jwt_token)
110
+
111
+ await init_index(opensearch_client)
106
112
 
107
113
 
108
114
  async def check_filename_exists(
@@ -144,7 +150,7 @@ async def check_filename_exists(
144
150
  except Exception as search_err:
145
151
  if "index_not_found_exception" in str(search_err):
146
152
  logger.info("Index does not exist, creating it now before upload")
147
- await _ensure_index_exists()
153
+ await _ensure_index_exists(jwt_token)
148
154
  return JSONResponse({"exists": False, "filename": filename}, status_code=200)
149
155
  raise
150
156
 
@@ -28,7 +28,7 @@ async def list_keys_endpoint(
28
28
 
29
29
  GET /keys
30
30
  """
31
- result = await api_key_service.list_keys(user.user_id, None)
31
+ result = await api_key_service.list_keys(user.user_id, user.jwt_token)
32
32
  return JSONResponse(result)
33
33
 
34
34
 
@@ -418,12 +418,9 @@ async def knowledge_filter_webhook(
418
418
  )
419
419
 
420
420
  except Exception as e:
421
- logger.error(
422
- "Failed to process knowledge filter webhook",
421
+ logger.exception(
422
+ "[API] Knowledge filter webhook failed",
423
423
  filter_id=filter_id,
424
424
  subscription_id=subscription_id,
425
- error=str(e),
426
425
  )
427
- import traceback
428
- traceback.print_exc()
429
426
  return JSONResponse({"error": f"Webhook processing failed: {str(e)}"}, status_code=500)
@@ -316,7 +316,7 @@ async def _test_openai_completion_with_tools(api_key: str, llm_model: str) -> No
316
316
 
317
317
  # If max_tokens doesn't work, try with max_completion_tokens
318
318
  if response.status_code != 200:
319
- logger.info("max_tokens parameter failed, trying max_completion_tokens instead")
319
+ logger.warning("[API] max_tokens parameter failed, trying max_completion_tokens instead")
320
320
  payload = {**base_payload, "max_completion_tokens": 50}
321
321
  response = await client.post(
322
322
  "https://api.openai.com/v1/chat/completions",
@@ -454,7 +454,7 @@ async def _test_watsonx_completion_with_tools(
454
454
 
455
455
  # Test completion with tools
456
456
  url = f"{endpoint}/ml/v1/text/chat"
457
- params = {"version": "2024-09-16"}
457
+ params = {"version": "2026-04-15"}
458
458
  payload = {
459
459
  "model_id": llm_model,
460
460
  "project_id": project_id,
@@ -549,7 +549,7 @@ async def _test_watsonx_embedding(
549
549
 
550
550
  # Test embedding
551
551
  url = f"{endpoint}/ml/v1/text/embeddings"
552
- params = {"version": "2024-09-16"}
552
+ params = {"version": "2026-04-15"}
553
553
  payload = {
554
554
  "model_id": embedding_model,
555
555
  "project_id": project_id,
@@ -33,7 +33,6 @@ async def search(
33
33
 
34
34
  logger.debug(
35
35
  "Search API request",
36
- user=str(user),
37
36
  user_id=user.user_id,
38
37
  has_jwt_token=jwt_token is not None,
39
38
  query=body.query,