openrag 0.4.1.dev7__tar.gz → 0.4.1.dev9__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.dev7/src/openrag.egg-info → openrag-0.4.1.dev9}/PKG-INFO +1 -1
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/pyproject.toml +1 -1
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/agent.py +69 -21
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/settings.py +1 -3
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/main.py +42 -2
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9/src/openrag.egg-info}/PKG-INFO +1 -1
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/task_service.py +10 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/docker-compose.yml +13 -16
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/embeddings.py +1 -1
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/opensearch_utils.py +37 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/LICENSE +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/MANIFEST.in +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/README.md +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/setup.cfg +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/auth.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/chat.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/connector_router.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/connectors.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/docling.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/documents.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/flows.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/keys.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/knowledge_filter.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/langflow_files.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/models.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/nudges.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/oidc.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/provider_health.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/provider_validation.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/router.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/search.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/tasks.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/upload.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/v1/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/v1/chat.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/v1/documents.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/v1/knowledge_filters.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/v1/models.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/v1/search.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/api/v1/settings.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/auth_context.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/config/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/config/config_manager.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/config/model_constants.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/config/settings.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/aws_s3/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/aws_s3/api.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/aws_s3/auth.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/aws_s3/connector.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/aws_s3/models.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/aws_s3/support.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/base.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/connection_manager.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/google_drive/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/google_drive/connector.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/google_drive/oauth.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/ibm_cos/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/ibm_cos/api.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/ibm_cos/auth.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/ibm_cos/connector.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/ibm_cos/models.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/ibm_cos/support.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/langflow_connector_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/onedrive/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/onedrive/connector.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/onedrive/oauth.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/sharepoint/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/sharepoint/connector.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/sharepoint/oauth.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/connectors/sharepoint/utils.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/dependencies.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/models/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/models/processors.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/models/tasks.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/models/url.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/openrag.egg-info/SOURCES.txt +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/openrag.egg-info/dependency_links.txt +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/openrag.egg-info/entry_points.txt +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/openrag.egg-info/requires.txt +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/openrag.egg-info/top_level.txt +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/api_key_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/auth_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/chat_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/conversation_persistence_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/document_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/flows_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/knowledge_filter_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/langflow_file_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/langflow_history_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/langflow_mcp_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/models_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/monitor_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/search_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/services/session_ownership_service.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/session_manager.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/docker-compose.gpu.yml +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/ollama_embedding.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/ollama_llm.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/ollama_llm_text.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/watsonx_embedding.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/watsonx_llm.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/watsonx_llm_text.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/ingestion_flow.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/openrag_agent.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/openrag_nudges.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/openrag_url_mcp.json +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/openrag-documents/docling.pdf +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/openrag-documents/ibm_anthropic.pdf +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/openrag-documents/openrag-documentation.pdf +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/openrag-documents/warmup_ocr.pdf +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/cli.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/config_fields.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/main.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/managers/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/managers/container_manager.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/managers/docling_manager.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/managers/env_manager.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/screens/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/screens/config.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/screens/diagnostics.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/screens/logs.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/screens/monitor.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/screens/welcome.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/utils/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/utils/clipboard.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/utils/platform.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/utils/startup_checks.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/utils/validation.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/utils/version_check.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/command_modal.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/diagnostics_notification.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/error_notification.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/factory_reset_warning_modal.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/flow_backup_warning_modal.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/prune_options_modal.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/upgrade_instructions_modal.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/version_mismatch_warning_modal.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/widgets/waves.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/acl_utils.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/container_utils.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/docling_client.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/document_processing.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/embedding_fields.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/env_utils.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/file_utils.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/gpu_detection.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/hash_utils.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/langflow_headers.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/langflow_utils.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/logging_config.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/opensearch_queries.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/paths.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/telemetry/__init__.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/telemetry/category.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/telemetry/client.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/utils/telemetry/message_id.py +0 -0
- {openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/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.
|
|
3
|
+
Version: 0.4.1.dev9
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openrag"
|
|
7
|
-
version = "0.4.1.
|
|
7
|
+
version = "0.4.1.dev9"
|
|
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"
|
|
@@ -158,7 +158,7 @@ async def async_response_stream(
|
|
|
158
158
|
else:
|
|
159
159
|
delta_text = str(chunk.delta)
|
|
160
160
|
full_response += delta_text
|
|
161
|
-
|
|
161
|
+
|
|
162
162
|
# Enhanced logging for tool call detection (Granite 3.3 8b investigation)
|
|
163
163
|
chunk_attrs = dir(chunk) if hasattr(chunk, '__dict__') else []
|
|
164
164
|
tool_related_attrs = [attr for attr in chunk_attrs if 'tool' in attr.lower() or 'call' in attr.lower() or 'retrieval' in attr.lower()]
|
|
@@ -180,7 +180,7 @@ async def async_response_stream(
|
|
|
180
180
|
chunk_data = chunk.__dict__
|
|
181
181
|
else:
|
|
182
182
|
chunk_data = str(chunk)
|
|
183
|
-
|
|
183
|
+
|
|
184
184
|
# Log detailed chunk structure for investigation (especially for Granite 3.3 8b)
|
|
185
185
|
if isinstance(chunk_data, dict):
|
|
186
186
|
# Check for any fields that might indicate tool usage
|
|
@@ -218,7 +218,7 @@ async def async_response_stream(
|
|
|
218
218
|
'retrieved_documents' in chunk_data,
|
|
219
219
|
'retrieval_results' in chunk_data,
|
|
220
220
|
])
|
|
221
|
-
|
|
221
|
+
|
|
222
222
|
if has_results:
|
|
223
223
|
logger.info(
|
|
224
224
|
"Detected implicit tool call in backend, injecting synthetic event",
|
|
@@ -242,7 +242,7 @@ async def async_response_stream(
|
|
|
242
242
|
# Send the synthetic event first
|
|
243
243
|
yield (json.dumps(synthetic_event, default=str) + "\n").encode("utf-8")
|
|
244
244
|
detected_tool_call = True # Mark that we've injected a tool call
|
|
245
|
-
|
|
245
|
+
|
|
246
246
|
yield (json.dumps(chunk_data, default=str) + "\n").encode("utf-8")
|
|
247
247
|
except Exception as e:
|
|
248
248
|
# Fallback to string representation
|
|
@@ -626,20 +626,68 @@ async def async_langflow_chat(
|
|
|
626
626
|
|
|
627
627
|
# Extract sources from retrieval tool calls in the response
|
|
628
628
|
sources = []
|
|
629
|
+
|
|
630
|
+
# Layer 1: Structured output items (OpenAI Responses API format).
|
|
631
|
+
# Relaxed: check for any output item with a non-empty `results` field,
|
|
632
|
+
# regardless of `type` string (Langflow may use different type names).
|
|
629
633
|
if hasattr(response_obj, "output") and response_obj.output:
|
|
630
634
|
for output_item in response_obj.output:
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
if
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
635
|
+
for result in getattr(output_item, "results", None) or []:
|
|
636
|
+
rd = (
|
|
637
|
+
result.model_dump()
|
|
638
|
+
if hasattr(result, "model_dump")
|
|
639
|
+
else (result if isinstance(result, dict) else {})
|
|
640
|
+
)
|
|
641
|
+
if "text" in rd:
|
|
642
|
+
sources.append({
|
|
643
|
+
"filename": rd.get("filename", ""),
|
|
644
|
+
"text": rd.get("text", ""),
|
|
645
|
+
"score": rd.get("score", 0),
|
|
646
|
+
"page": rd.get("page"),
|
|
647
|
+
"mimetype": rd.get("mimetype"),
|
|
648
|
+
})
|
|
649
|
+
|
|
650
|
+
# Layer 2: Top-level dict inspection (mirrors streaming middleware in async_response_stream).
|
|
651
|
+
# Langflow may embed retrieval results directly in the response dict rather than
|
|
652
|
+
# inside typed output items.
|
|
653
|
+
if not sources:
|
|
654
|
+
resp_dict = (
|
|
655
|
+
response_obj.model_dump()
|
|
656
|
+
if hasattr(response_obj, "model_dump")
|
|
657
|
+
else getattr(response_obj, "__dict__", {})
|
|
658
|
+
)
|
|
659
|
+
implicit_results = (
|
|
660
|
+
resp_dict.get("results")
|
|
661
|
+
or resp_dict.get("outputs")
|
|
662
|
+
or resp_dict.get("retrieved_documents")
|
|
663
|
+
or resp_dict.get("retrieval_results")
|
|
664
|
+
or []
|
|
665
|
+
)
|
|
666
|
+
if isinstance(implicit_results, list):
|
|
667
|
+
for result in implicit_results:
|
|
668
|
+
if isinstance(result, dict) and "text" in result:
|
|
669
|
+
sources.append({
|
|
670
|
+
"filename": result.get("filename", ""),
|
|
671
|
+
"text": result.get("text", ""),
|
|
672
|
+
"score": result.get("score", 0),
|
|
673
|
+
"page": result.get("page"),
|
|
674
|
+
"mimetype": result.get("mimetype"),
|
|
675
|
+
})
|
|
676
|
+
|
|
677
|
+
# Layer 3: Citation-text fallback.
|
|
678
|
+
# Parse "(Source: filename)" patterns emitted by the LLM when it cites documents.
|
|
679
|
+
# This is the last-resort fallback when Langflow's response object carries no
|
|
680
|
+
# structured retrieval data.
|
|
681
|
+
if not sources:
|
|
682
|
+
import re
|
|
683
|
+
for match in re.finditer(r"\(Source:\s*([^\)]+)\)", response_text):
|
|
684
|
+
sources.append({
|
|
685
|
+
"filename": match.group(1).strip(),
|
|
686
|
+
"text": "",
|
|
687
|
+
"score": 0,
|
|
688
|
+
"page": None,
|
|
689
|
+
"mimetype": None,
|
|
690
|
+
})
|
|
643
691
|
|
|
644
692
|
if not store_conversation:
|
|
645
693
|
return response_text, response_id, sources
|
|
@@ -739,7 +787,7 @@ async def async_langflow_chat_stream(
|
|
|
739
787
|
response_id = chunk_data["id"]
|
|
740
788
|
elif "response_id" in chunk_data:
|
|
741
789
|
response_id = chunk_data["response_id"]
|
|
742
|
-
|
|
790
|
+
|
|
743
791
|
# Check for error status
|
|
744
792
|
if chunk_data.get("finish_reason") == "error" or chunk_data.get("status") == "failed":
|
|
745
793
|
error_occurred = True
|
|
@@ -788,7 +836,7 @@ async def async_langflow_chat_stream(
|
|
|
788
836
|
# Log the error
|
|
789
837
|
logger.error(f"Error in langflow chat stream: {e}", exc_info=True)
|
|
790
838
|
error_occurred = True
|
|
791
|
-
|
|
839
|
+
|
|
792
840
|
# Store error message in conversation history so it persists
|
|
793
841
|
error_message = {
|
|
794
842
|
"role": "assistant",
|
|
@@ -797,19 +845,19 @@ async def async_langflow_chat_stream(
|
|
|
797
845
|
"error": True,
|
|
798
846
|
}
|
|
799
847
|
conversation_state["messages"].append(error_message)
|
|
800
|
-
|
|
848
|
+
|
|
801
849
|
# Try to store the conversation with error message
|
|
802
850
|
# Use a temporary response_id if we don't have one
|
|
803
851
|
if not response_id:
|
|
804
852
|
response_id = f"error_{user_id}_{int(datetime.now().timestamp())}"
|
|
805
|
-
|
|
853
|
+
|
|
806
854
|
try:
|
|
807
855
|
conversation_state["last_activity"] = datetime.now()
|
|
808
856
|
await store_conversation_thread(user_id, response_id, conversation_state)
|
|
809
857
|
logger.debug(f"Stored conversation with error for user {user_id}")
|
|
810
858
|
except Exception as store_error:
|
|
811
859
|
logger.error(f"Failed to store error conversation: {store_error}")
|
|
812
|
-
|
|
860
|
+
|
|
813
861
|
# Re-raise the exception so it propagates to the API layer
|
|
814
862
|
raise
|
|
815
863
|
|
|
@@ -1664,8 +1664,6 @@ async def rollback_onboarding(
|
|
|
1664
1664
|
{"error": "No onboarding configuration to rollback"}, status_code=400
|
|
1665
1665
|
)
|
|
1666
1666
|
|
|
1667
|
-
jwt_token = user.jwt_token
|
|
1668
|
-
|
|
1669
1667
|
logger.info("Rolling back onboarding configuration due to file failures")
|
|
1670
1668
|
|
|
1671
1669
|
# Get all tasks for the user
|
|
@@ -1728,7 +1726,7 @@ async def rollback_onboarding(
|
|
|
1728
1726
|
if filename:
|
|
1729
1727
|
try:
|
|
1730
1728
|
opensearch_client = session_manager.get_user_opensearch_client(
|
|
1731
|
-
user.user_id, jwt_token
|
|
1729
|
+
user.user_id, user.jwt_token
|
|
1732
1730
|
)
|
|
1733
1731
|
from utils.opensearch_queries import build_filename_delete_body
|
|
1734
1732
|
from config.settings import get_index_name
|
|
@@ -248,10 +248,23 @@ async def init_index():
|
|
|
248
248
|
)
|
|
249
249
|
else:
|
|
250
250
|
logger.info(
|
|
251
|
-
"Index already exists, skipping creation",
|
|
251
|
+
"Index already exists, skipping creation and changing number of replicas",
|
|
252
252
|
index_name=index_name,
|
|
253
253
|
embedding_model=embedding_model,
|
|
254
254
|
)
|
|
255
|
+
# Set number of replicas to 0 to not create unused nodes in OpenSearch, in case it was created with more replicas
|
|
256
|
+
current = await clients.opensearch.indices.get_settings(index=index_name)
|
|
257
|
+
current_replicas = int(
|
|
258
|
+
current[index_name]["settings"]["index"].get("number_of_replicas", 1)
|
|
259
|
+
)
|
|
260
|
+
if current_replicas != 0:
|
|
261
|
+
await clients.opensearch.indices.put_settings(
|
|
262
|
+
index=index_name,
|
|
263
|
+
body={"index": {"number_of_replicas": 0}},
|
|
264
|
+
)
|
|
265
|
+
logger.info(
|
|
266
|
+
"Updated documents index settings",
|
|
267
|
+
)
|
|
255
268
|
await TelemetryClient.send_event(
|
|
256
269
|
Category.OPENSEARCH_INDEX, MessageId.ORB_OS_INDEX_EXISTS
|
|
257
270
|
)
|
|
@@ -259,6 +272,9 @@ async def init_index():
|
|
|
259
272
|
# Create knowledge filters index
|
|
260
273
|
knowledge_filter_index_name = "knowledge_filters"
|
|
261
274
|
knowledge_filter_index_body = {
|
|
275
|
+
"settings": {
|
|
276
|
+
"index": {"number_of_replicas": 0, "number_of_shards": 1},
|
|
277
|
+
},
|
|
262
278
|
"mappings": {
|
|
263
279
|
"properties": {
|
|
264
280
|
"id": {"type": "keyword"},
|
|
@@ -272,7 +288,7 @@ async def init_index():
|
|
|
272
288
|
"created_at": {"type": "date"},
|
|
273
289
|
"updated_at": {"type": "date"},
|
|
274
290
|
}
|
|
275
|
-
}
|
|
291
|
+
},
|
|
276
292
|
}
|
|
277
293
|
|
|
278
294
|
if not await clients.opensearch.indices.exists(
|
|
@@ -294,6 +310,19 @@ async def init_index():
|
|
|
294
310
|
index_name=knowledge_filter_index_name,
|
|
295
311
|
)
|
|
296
312
|
|
|
313
|
+
current = await clients.opensearch.indices.get_settings(index=knowledge_filter_index_name)
|
|
314
|
+
current_replicas = int(
|
|
315
|
+
current[knowledge_filter_index_name]["settings"]["index"].get("number_of_replicas", 1)
|
|
316
|
+
)
|
|
317
|
+
if current_replicas != 0:
|
|
318
|
+
await clients.opensearch.indices.put_settings(
|
|
319
|
+
index=knowledge_filter_index_name,
|
|
320
|
+
body={"index": {"number_of_replicas": 0}},
|
|
321
|
+
)
|
|
322
|
+
logger.info(
|
|
323
|
+
"Updated knowledge filters index settings",
|
|
324
|
+
)
|
|
325
|
+
|
|
297
326
|
# Create API keys index for public API authentication
|
|
298
327
|
if not await clients.opensearch.indices.exists(index=API_KEYS_INDEX_NAME):
|
|
299
328
|
await clients.opensearch.indices.create(
|
|
@@ -1861,6 +1890,16 @@ async def create_app():
|
|
|
1861
1890
|
await TelemetryClient.send_event(
|
|
1862
1891
|
Category.APPLICATION_SHUTDOWN, MessageId.ORB_APP_SHUTDOWN
|
|
1863
1892
|
)
|
|
1893
|
+
logger.info("Application shutdown initiated")
|
|
1894
|
+
|
|
1895
|
+
# Gracefully shutdown OpenSearch connection first
|
|
1896
|
+
try:
|
|
1897
|
+
from utils.opensearch_utils import graceful_opensearch_shutdown
|
|
1898
|
+
await graceful_opensearch_shutdown(clients.opensearch)
|
|
1899
|
+
clients.opensearch = None # prevent double-close in clients.cleanup()
|
|
1900
|
+
except Exception as e:
|
|
1901
|
+
logger.error("Error during graceful OpenSearch shutdown", error=str(e))
|
|
1902
|
+
|
|
1864
1903
|
await cleanup_subscriptions_proper(services)
|
|
1865
1904
|
# Cleanup task service (cancels background tasks and process pool)
|
|
1866
1905
|
await services["task_service"].shutdown()
|
|
@@ -1870,6 +1909,7 @@ async def create_app():
|
|
|
1870
1909
|
from utils.telemetry.client import cleanup_telemetry_client
|
|
1871
1910
|
|
|
1872
1911
|
await cleanup_telemetry_client()
|
|
1912
|
+
logger.info("Application shutdown completed")
|
|
1873
1913
|
|
|
1874
1914
|
return app
|
|
1875
1915
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrag
|
|
3
|
-
Version: 0.4.1.
|
|
3
|
+
Version: 0.4.1.dev9
|
|
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
|
|
@@ -411,6 +411,16 @@ class TaskService:
|
|
|
411
411
|
|
|
412
412
|
# Mark task as completed if all files (including appended ones) are done
|
|
413
413
|
if upload_task.processed_files >= upload_task.total_files:
|
|
414
|
+
# Force an index refresh BEFORE marking the task COMPLETED so that
|
|
415
|
+
# callers polling for COMPLETED status can immediately query or delete
|
|
416
|
+
# the newly indexed chunks without hitting the near-real-time refresh window.
|
|
417
|
+
if upload_task.successful_files > 0:
|
|
418
|
+
try:
|
|
419
|
+
from config.settings import clients, get_index_name
|
|
420
|
+
await clients.opensearch.indices.refresh(index=get_index_name())
|
|
421
|
+
except Exception as e:
|
|
422
|
+
logger.debug("Index refresh after ingest failed (non-fatal)", error=str(e))
|
|
423
|
+
|
|
414
424
|
upload_task.status = TaskStatus.COMPLETED
|
|
415
425
|
upload_task.updated_at = time.time()
|
|
416
426
|
|
|
@@ -10,26 +10,20 @@ services:
|
|
|
10
10
|
environment:
|
|
11
11
|
- discovery.type=single-node
|
|
12
12
|
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_PASSWORD}
|
|
13
|
-
|
|
14
|
-
command: >
|
|
15
|
-
bash -c "
|
|
16
|
-
# Ensure data directory has correct permissions
|
|
17
|
-
sudo chown -R opensearch:opensearch /usr/share/opensearch/data || true
|
|
18
|
-
|
|
19
|
-
# Start OpenSearch in background
|
|
20
|
-
/usr/share/opensearch/opensearch-docker-entrypoint.sh opensearch &
|
|
21
|
-
|
|
22
|
-
# Wait a bit for OpenSearch to start, then apply security config
|
|
23
|
-
sleep 10 && /usr/share/opensearch/setup-security.sh &
|
|
24
|
-
|
|
25
|
-
# Wait for background processes
|
|
26
|
-
wait
|
|
27
|
-
"
|
|
13
|
+
- OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
|
|
28
14
|
ports:
|
|
29
15
|
- "9200:9200"
|
|
30
16
|
- "9600:9600"
|
|
31
17
|
volumes:
|
|
32
|
-
-
|
|
18
|
+
- opensearch-data:/usr/share/opensearch/data
|
|
19
|
+
stop_grace_period: 2m
|
|
20
|
+
healthcheck:
|
|
21
|
+
test: ["CMD-SHELL", "curl -ku admin:$$OPENSEARCH_PASSWORD 'https://localhost:9200/_cluster/health' -s | grep -qE '\"status\":\"(green|yellow)\"'"]
|
|
22
|
+
interval: 15s
|
|
23
|
+
timeout: 10s
|
|
24
|
+
retries: 20
|
|
25
|
+
start_period: 60s
|
|
26
|
+
restart: unless-stopped
|
|
33
27
|
|
|
34
28
|
dashboards:
|
|
35
29
|
image: opensearchproject/opensearch-dashboards:3.0.0
|
|
@@ -186,3 +180,6 @@ services:
|
|
|
186
180
|
- LANGFLOW_ENABLE_SUPERUSER_CLI=${LANGFLOW_ENABLE_SUPERUSER_CLI}
|
|
187
181
|
# - DEFAULT_FOLDER_NAME=OpenRAG
|
|
188
182
|
- HIDE_GETTING_STARTED_PROGRESS=true
|
|
183
|
+
|
|
184
|
+
volumes:
|
|
185
|
+
opensearch-data:
|
|
@@ -121,3 +121,40 @@ async def wait_for_opensearch(
|
|
|
121
121
|
message: str = "Failed to verify whether OpenSearch is ready."
|
|
122
122
|
logger.error(message)
|
|
123
123
|
raise OpenSearchNotReadyError(message)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
async def graceful_opensearch_shutdown(opensearch_client: AsyncOpenSearch) -> None:
|
|
127
|
+
"""Gracefully shutdown OpenSearch client connection.
|
|
128
|
+
|
|
129
|
+
This ensures that all pending operations are completed and connections
|
|
130
|
+
are properly closed before the application exits.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
opensearch_client: The OpenSearch client to shutdown.
|
|
134
|
+
"""
|
|
135
|
+
if opensearch_client is None:
|
|
136
|
+
logger.debug("OpenSearch client is None, skipping graceful shutdown")
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
logger.info("Initiating graceful OpenSearch shutdown...")
|
|
141
|
+
|
|
142
|
+
# Flush any pending write operations before closing
|
|
143
|
+
try:
|
|
144
|
+
await asyncio.wait_for(
|
|
145
|
+
opensearch_client.indices.flush(index="_all", wait_if_ongoing=True),
|
|
146
|
+
timeout=10.0
|
|
147
|
+
)
|
|
148
|
+
logger.debug("Index flush completed")
|
|
149
|
+
except asyncio.TimeoutError:
|
|
150
|
+
logger.warning("Timeout during index flush")
|
|
151
|
+
except Exception as e:
|
|
152
|
+
logger.warning("Error during index flush", error=str(e))
|
|
153
|
+
|
|
154
|
+
# Close the client connection
|
|
155
|
+
await opensearch_client.close()
|
|
156
|
+
logger.info("OpenSearch client connection closed gracefully")
|
|
157
|
+
|
|
158
|
+
except Exception as e:
|
|
159
|
+
logger.error("Error during graceful OpenSearch shutdown", error=str(e))
|
|
160
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/ollama_embedding.json
RENAMED
|
File without changes
|
|
File without changes
|
{openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/ollama_llm_text.json
RENAMED
|
File without changes
|
{openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/watsonx_embedding.json
RENAMED
|
File without changes
|
|
File without changes
|
{openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/flows/components/watsonx_llm_text.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openrag-0.4.1.dev7 → openrag-0.4.1.dev9}/src/tui/_assets/openrag-documents/ibm_anthropic.pdf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|