openrag 0.4.1.dev22__tar.gz → 0.5.0__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.
- {openrag-0.4.1.dev22/src/openrag.egg-info → openrag-0.5.0}/PKG-INFO +12 -5
- {openrag-0.4.1.dev22 → openrag-0.5.0}/pyproject.toml +14 -6
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/agent.py +29 -43
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/auth.py +69 -9
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/chat.py +9 -3
- openrag-0.5.0/src/api/connectors.py +1611 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/documents.py +82 -20
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/keys.py +1 -1
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/knowledge_filter.py +2 -5
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/langflow_files.py +23 -20
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/provider_validation.py +3 -3
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/search.py +0 -1
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/settings.py +260 -74
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/upload.py +16 -2
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/v1/chat.py +6 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/v1/settings.py +3 -2
- openrag-0.5.0/src/auth/ibm_auth.py +90 -0
- openrag-0.5.0/src/bootstrap.py +23 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/config/config_manager.py +50 -14
- openrag-0.5.0/src/config/paths.py +93 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/config/settings.py +73 -30
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/connection_manager.py +87 -2
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/google_drive/connector.py +190 -194
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/google_drive/oauth.py +90 -41
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/ibm_cos/connector.py +0 -5
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/onedrive/connector.py +241 -160
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/onedrive/oauth.py +139 -103
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/service.py +189 -85
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/sharepoint/connector.py +333 -242
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/sharepoint/oauth.py +61 -68
- openrag-0.5.0/src/dependencies.py +427 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/main.py +524 -213
- openrag-0.5.0/src/mcp_http/server.py +229 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/models/processors.py +418 -267
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/models/tasks.py +10 -1
- {openrag-0.4.1.dev22 → openrag-0.5.0/src/openrag.egg-info}/PKG-INFO +12 -5
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/openrag.egg-info/SOURCES.txt +9 -3
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/openrag.egg-info/requires.txt +11 -4
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/openrag.egg-info/top_level.txt +3 -0
- openrag-0.5.0/src/services/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/api_key_service.py +16 -15
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/auth_service.py +117 -87
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/chat_service.py +42 -13
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/conversation_persistence_service.py +3 -2
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/flows_service.py +252 -187
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/langflow_file_service.py +69 -52
- openrag-0.5.0/src/services/langflow_mcp_service.py +281 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/models_service.py +54 -11
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/search_service.py +117 -69
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/session_ownership_service.py +2 -1
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/task_service.py +17 -7
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/session_manager.py +24 -10
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/docker-compose.yml +13 -6
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/ingestion_flow.json +2141 -1742
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/openrag_agent.json +1193 -998
- openrag-0.5.0/src/tui/_assets/flows/openrag_nudges.json +4674 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/openrag_url_mcp.json +3588 -2753
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/config_fields.py +21 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/main.py +81 -1
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/managers/docling_manager.py +81 -105
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/managers/env_manager.py +32 -11
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/screens/config.py +11 -2
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/screens/monitor.py +85 -93
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/utils/startup_checks.py +19 -86
- openrag-0.5.0/src/utils/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/acl_utils.py +5 -2
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/document_processing.py +39 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/embedding_fields.py +39 -12
- openrag-0.5.0/src/utils/encryption.py +209 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/file_utils.py +20 -1
- openrag-0.5.0/src/utils/langflow_headers.py +76 -0
- openrag-0.5.0/src/utils/logging_config.py +321 -0
- openrag-0.5.0/src/utils/opensearch_delete.py +105 -0
- openrag-0.5.0/src/utils/opensearch_utils.py +402 -0
- openrag-0.5.0/src/utils/run_mode_utils.py +36 -0
- openrag-0.4.1.dev22/src/api/connector_router.py +0 -71
- openrag-0.4.1.dev22/src/api/connectors.py +0 -917
- openrag-0.4.1.dev22/src/connectors/langflow_connector_service.py +0 -400
- openrag-0.4.1.dev22/src/dependencies.py +0 -222
- openrag-0.4.1.dev22/src/services/langflow_mcp_service.py +0 -275
- openrag-0.4.1.dev22/src/tui/_assets/flows/openrag_nudges.json +0 -4851
- openrag-0.4.1.dev22/src/tui/_assets/openrag-documents/openrag-documentation.pdf +0 -0
- openrag-0.4.1.dev22/src/utils/langflow_headers.py +0 -79
- openrag-0.4.1.dev22/src/utils/logging_config.py +0 -151
- openrag-0.4.1.dev22/src/utils/opensearch_utils.py +0 -160
- {openrag-0.4.1.dev22 → openrag-0.5.0}/LICENSE +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/MANIFEST.in +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/README.md +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/setup.cfg +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/docling.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/flows.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/models.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/nudges.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/oidc.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/provider_health.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/router.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/tasks.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/v1/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/v1/documents.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/v1/knowledge_filters.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/v1/models.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/api/v1/search.py +0 -0
- {openrag-0.4.1.dev22/src/config → openrag-0.5.0/src/auth}/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/auth_context.py +0 -0
- {openrag-0.4.1.dev22/src/models → openrag-0.5.0/src/config}/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/config/embedding_constants.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/config/model_constants.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/aws_s3/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/aws_s3/api.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/aws_s3/auth.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/aws_s3/connector.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/aws_s3/models.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/aws_s3/support.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/base.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/google_drive/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/ibm_cos/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/ibm_cos/api.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/ibm_cos/auth.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/ibm_cos/models.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/ibm_cos/support.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/onedrive/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/sharepoint/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/connectors/sharepoint/utils.py +0 -0
- {openrag-0.4.1.dev22/src/services → openrag-0.5.0/src/mcp_http}/__init__.py +0 -0
- {openrag-0.4.1.dev22/src/utils → openrag-0.5.0/src/models}/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/models/url.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/openrag.egg-info/dependency_links.txt +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/openrag.egg-info/entry_points.txt +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/document_service.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/knowledge_filter_service.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/langflow_history_service.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/services/monitor_service.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/docker-compose.gpu.yml +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/components/ollama_embedding.json +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/components/ollama_llm.json +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/components/ollama_llm_text.json +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/components/watsonx_embedding.json +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/components/watsonx_llm.json +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/flows/components/watsonx_llm_text.json +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/openrag-documents/docling.pdf +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/openrag-documents/ibm_anthropic.pdf +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/_assets/openrag-documents/warmup_ocr.pdf +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/cli.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/managers/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/managers/container_manager.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/screens/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/screens/diagnostics.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/screens/logs.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/screens/welcome.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/utils/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/utils/clipboard.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/utils/platform.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/utils/validation.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/utils/version_check.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/command_modal.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/diagnostics_notification.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/error_notification.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/factory_reset_warning_modal.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/flow_backup_warning_modal.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/prune_options_modal.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/upgrade_instructions_modal.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/version_mismatch_warning_modal.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/tui/widgets/waves.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/container_utils.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/docling_client.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/embeddings.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/env_utils.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/gpu_detection.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/hash_utils.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/langflow_utils.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/opensearch_queries.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/paths.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/telemetry/__init__.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/telemetry/category.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/telemetry/client.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/telemetry/message_id.py +0 -0
- {openrag-0.4.1.dev22 → openrag-0.5.0}/src/utils/version_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrag
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
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:
|
|
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.
|
|
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,16 @@ 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
|
|
40
|
-
Requires-Dist:
|
|
41
|
+
Requires-Dist: prometheus-fastapi-instrumentator>=7.1.0
|
|
42
|
+
Requires-Dist: litellm==1.83.14
|
|
41
43
|
Requires-Dist: pyyaml>=6.0
|
|
42
44
|
Requires-Dist: tiktoken>=0.7.0
|
|
43
|
-
Requires-Dist:
|
|
45
|
+
Requires-Dist: fastmcp>=3.2.3
|
|
46
|
+
Requires-Dist: openai==2.24.0
|
|
47
|
+
Requires-Dist: tenacity>=9.1.4
|
|
48
|
+
Requires-Dist: pygments>=2.20.0
|
|
49
|
+
Requires-Dist: pyasn1>=0.6.3
|
|
50
|
+
Requires-Dist: requests>=2.33.0
|
|
44
51
|
Dynamic: license-file
|
|
45
52
|
|
|
46
53
|
<div align="center">
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openrag"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.5.0"
|
|
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
|
-
"
|
|
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.
|
|
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,26 @@ dependencies = [
|
|
|
43
44
|
"textual-fspicker>=0.6.0",
|
|
44
45
|
"structlog>=25.4.0",
|
|
45
46
|
"zxcvbn>=4.5.0",
|
|
46
|
-
"
|
|
47
|
+
"prometheus-fastapi-instrumentator>=7.1.0",
|
|
48
|
+
"litellm==1.83.14",
|
|
47
49
|
"pyyaml>=6.0",
|
|
48
50
|
"tiktoken>=0.7.0",
|
|
49
|
-
"
|
|
51
|
+
"fastmcp>=3.2.3",
|
|
52
|
+
"openai==2.24.0",
|
|
53
|
+
"tenacity>=9.1.4",
|
|
54
|
+
"pygments>=2.20.0",
|
|
55
|
+
"pyasn1>=0.6.3",
|
|
56
|
+
"requests>=2.33.0",
|
|
50
57
|
]
|
|
51
58
|
|
|
52
59
|
[dependency-groups]
|
|
53
|
-
dev = ["pytest>=
|
|
60
|
+
dev = ["pytest>=9.0.3", "pytest-asyncio>=0.21.0", "pytest-mock>=3.12.0", "pytest-cov>=4.0.0"]
|
|
54
61
|
|
|
55
62
|
[project.scripts]
|
|
56
63
|
openrag = "tui.main:run_tui"
|
|
57
64
|
|
|
58
65
|
[tool.uv]
|
|
59
66
|
package = true
|
|
67
|
+
override-dependencies = ["python-dotenv>=1.1.0"]
|
|
60
68
|
|
|
61
69
|
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
391
|
-
import traceback
|
|
392
|
-
|
|
393
|
-
traceback.print_exc()
|
|
381
|
+
logger.exception("[AGENT] Langflow stream failed")
|
|
394
382
|
raise
|
|
395
383
|
|
|
396
384
|
|
|
@@ -527,25 +515,24 @@ async def async_chat_stream(
|
|
|
527
515
|
yield chunk
|
|
528
516
|
|
|
529
517
|
# Add the complete assistant response to message history with response_id and timestamp
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
conversation_state["messages"].append(assistant_message)
|
|
518
|
+
assistant_message = {
|
|
519
|
+
"role": "assistant",
|
|
520
|
+
"content": full_response,
|
|
521
|
+
"response_id": response_id,
|
|
522
|
+
"timestamp": datetime.now(),
|
|
523
|
+
}
|
|
524
|
+
# Store usage data if available (from response.completed event)
|
|
525
|
+
if usage_data:
|
|
526
|
+
assistant_message["response_data"] = {"usage": usage_data}
|
|
527
|
+
conversation_state["messages"].append(assistant_message)
|
|
541
528
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
529
|
+
# Store the conversation thread with its response_id
|
|
530
|
+
if response_id:
|
|
531
|
+
conversation_state["last_activity"] = datetime.now()
|
|
532
|
+
await store_conversation_thread(user_id, response_id, conversation_state)
|
|
533
|
+
logger.debug(
|
|
534
|
+
f"Stored conversation thread for user {user_id} with response_id: {response_id}"
|
|
535
|
+
)
|
|
549
536
|
|
|
550
537
|
|
|
551
538
|
# Async langflow function with conversation storage (non-streaming)
|
|
@@ -801,16 +788,15 @@ async def async_langflow_chat_stream(
|
|
|
801
788
|
yield chunk
|
|
802
789
|
|
|
803
790
|
# Add the complete assistant response to message history with response_id, timestamp, and function call data
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
# Store usage data if available (from response.completed event)
|
|
791
|
+
assistant_message = {
|
|
792
|
+
"role": "assistant",
|
|
793
|
+
"content": full_response,
|
|
794
|
+
"response_id": response_id,
|
|
795
|
+
"timestamp": datetime.now(),
|
|
796
|
+
"chunks": collected_chunks, # Store complete chunk data for function calls
|
|
797
|
+
"error": error_occurred, # Mark if this was an error response
|
|
798
|
+
}
|
|
799
|
+
# Store usage data if available (from response.completed event)
|
|
814
800
|
if usage_data:
|
|
815
801
|
assistant_message["response_data"] = {"usage": usage_data}
|
|
816
802
|
conversation_state["messages"].append(assistant_message)
|
|
@@ -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
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
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
|
)
|