OpenRAG 0.1.31__tar.gz → 0.2.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.1.31/src/openrag.egg-info → openrag-0.2.0}/PKG-INFO +24 -21
- {openrag-0.1.31 → openrag-0.2.0}/README.md +21 -19
- {openrag-0.1.31 → openrag-0.2.0}/pyproject.toml +3 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/agent.py +115 -19
- {openrag-0.1.31 → openrag-0.2.0}/src/api/auth.py +6 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/chat.py +6 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/connectors.py +6 -0
- openrag-0.2.0/src/api/keys.py +170 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/models.py +75 -23
- {openrag-0.1.31 → openrag-0.2.0}/src/api/nudges.py +28 -0
- openrag-0.2.0/src/api/provider_health.py +230 -0
- openrag-0.2.0/src/api/provider_validation.py +818 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/router.py +11 -8
- openrag-0.2.0/src/api/settings.py +1610 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/tasks.py +3 -0
- openrag-0.2.0/src/api/v1/__init__.py +6 -0
- openrag-0.2.0/src/api/v1/chat.py +301 -0
- openrag-0.2.0/src/api/v1/documents.py +150 -0
- openrag-0.2.0/src/api/v1/knowledge_filters.py +63 -0
- openrag-0.2.0/src/api/v1/search.py +108 -0
- openrag-0.2.0/src/api/v1/settings.py +86 -0
- openrag-0.2.0/src/api_key_middleware.py +133 -0
- openrag-0.2.0/src/config/config_manager.py +299 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/config/settings.py +282 -212
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/connection_manager.py +3 -1
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/google_drive/connector.py +49 -11
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/google_drive/oauth.py +18 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/onedrive/connector.py +81 -7
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/sharepoint/connector.py +87 -9
- {openrag-0.1.31 → openrag-0.2.0}/src/main.py +434 -11
- {openrag-0.1.31 → openrag-0.2.0}/src/models/processors.py +42 -9
- {openrag-0.1.31 → openrag-0.2.0/src/openrag.egg-info}/PKG-INFO +24 -21
- {openrag-0.1.31 → openrag-0.2.0}/src/openrag.egg-info/SOURCES.txt +27 -6
- {openrag-0.1.31 → openrag-0.2.0}/src/openrag.egg-info/requires.txt +2 -1
- {openrag-0.1.31 → openrag-0.2.0}/src/openrag.egg-info/top_level.txt +1 -0
- openrag-0.2.0/src/services/api_key_service.py +372 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/services/auth_service.py +12 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/services/chat_service.py +115 -9
- {openrag-0.1.31 → openrag-0.2.0}/src/services/conversation_persistence_service.py +23 -14
- {openrag-0.1.31 → openrag-0.2.0}/src/services/document_service.py +37 -19
- openrag-0.2.0/src/services/flows_service.py +1451 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/services/langflow_file_service.py +31 -4
- {openrag-0.1.31 → openrag-0.2.0}/src/services/langflow_history_service.py +12 -11
- {openrag-0.1.31 → openrag-0.2.0}/src/services/models_service.py +113 -44
- {openrag-0.1.31 → openrag-0.2.0}/src/services/search_service.py +31 -6
- {openrag-0.1.31 → openrag-0.2.0}/src/services/session_ownership_service.py +4 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/services/task_service.py +80 -7
- openrag-0.2.0/src/tui/__init__.py +5 -0
- openrag-0.2.0/src/tui/_assets/docker-compose.gpu.yml +7 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/_assets/docker-compose.yml +41 -24
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/_assets/flows/components/ollama_embedding.json +2 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/_assets/flows/components/ollama_llm.json +2 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/_assets/flows/components/ollama_llm_text.json +2 -2
- openrag-0.2.0/src/tui/_assets/flows/ingestion_flow.json +5758 -0
- openrag-0.2.0/src/tui/_assets/flows/openrag_agent.json +4795 -0
- openrag-0.2.0/src/tui/_assets/flows/openrag_nudges.json +4122 -0
- openrag-0.2.0/src/tui/_assets/flows/openrag_url_mcp.json +6802 -0
- openrag-0.2.0/src/tui/_assets/openrag-documents/openrag-documentation.pdf +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/main.py +229 -9
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/managers/container_manager.py +782 -64
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/managers/docling_manager.py +52 -0
- openrag-0.2.0/src/tui/managers/env_manager.py +700 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/screens/config.py +365 -38
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/screens/diagnostics.py +2 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/screens/monitor.py +354 -46
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/screens/welcome.py +240 -36
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/utils/validation.py +21 -15
- openrag-0.2.0/src/tui/utils/version_check.py +175 -0
- openrag-0.2.0/src/tui/widgets/__init__.py +7 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/widgets/command_modal.py +37 -4
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/widgets/diagnostics_notification.py +2 -2
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/widgets/error_notification.py +2 -2
- openrag-0.2.0/src/tui/widgets/factory_reset_warning_modal.py +102 -0
- openrag-0.2.0/src/tui/widgets/flow_backup_warning_modal.py +125 -0
- openrag-0.2.0/src/tui/widgets/prune_options_modal.py +106 -0
- openrag-0.2.0/src/tui/widgets/upgrade_instructions_modal.py +112 -0
- openrag-0.2.0/src/tui/widgets/version_mismatch_warning_modal.py +114 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/document_processing.py +76 -0
- openrag-0.2.0/src/utils/langflow_headers.py +71 -0
- openrag-0.2.0/src/utils/paths.py +85 -0
- openrag-0.2.0/src/utils/telemetry/__init__.py +8 -0
- openrag-0.2.0/src/utils/telemetry/category.py +45 -0
- openrag-0.2.0/src/utils/telemetry/client.py +409 -0
- openrag-0.2.0/src/utils/telemetry/message_id.py +203 -0
- openrag-0.1.31/src/api/provider_health.py +0 -117
- openrag-0.1.31/src/api/provider_validation.py +0 -437
- openrag-0.1.31/src/api/settings.py +0 -944
- openrag-0.1.31/src/config/config_manager.py +0 -214
- openrag-0.1.31/src/services/flows_service.py +0 -906
- openrag-0.1.31/src/tui/__init__.py +0 -8
- openrag-0.1.31/src/tui/_assets/docker-compose-cpu.yml +0 -126
- openrag-0.1.31/src/tui/_assets/documents/openrag-documentation.pdf +0 -0
- openrag-0.1.31/src/tui/_assets/flows/ingestion_flow.json +0 -4199
- openrag-0.1.31/src/tui/_assets/flows/openrag_agent.json +0 -2875
- openrag-0.1.31/src/tui/_assets/flows/openrag_nudges.json +0 -2350
- openrag-0.1.31/src/tui/_assets/flows/openrag_url_mcp.json +0 -3621
- openrag-0.1.31/src/tui/managers/env_manager.py +0 -445
- openrag-0.1.31/src/tui/widgets/__init__.py +0 -3
- {openrag-0.1.31 → openrag-0.2.0}/LICENSE +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/MANIFEST.in +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/setup.cfg +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/connector_router.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/docling.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/documents.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/flows.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/knowledge_filter.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/langflow_files.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/oidc.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/search.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/api/upload.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/auth_context.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/auth_middleware.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/config/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/base.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/google_drive/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/langflow_connector_service.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/onedrive/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/onedrive/oauth.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/service.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/sharepoint/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/connectors/sharepoint/oauth.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/models/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/models/tasks.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/openrag.egg-info/dependency_links.txt +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/openrag.egg-info/entry_points.txt +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/services/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/services/knowledge_filter_service.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/services/langflow_mcp_service.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/services/monitor_service.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/session_manager.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/_assets/flows/components/watsonx_embedding.json +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/_assets/flows/components/watsonx_llm.json +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/_assets/flows/components/watsonx_llm_text.json +0 -0
- {openrag-0.1.31/src/tui/_assets/documents → openrag-0.2.0/src/tui/_assets/openrag-documents}/docling.pdf +0 -0
- {openrag-0.1.31/src/tui/_assets/documents → openrag-0.2.0/src/tui/_assets/openrag-documents}/ibm_anthropic.pdf +0 -0
- {openrag-0.1.31/src/tui/_assets/documents → openrag-0.2.0/src/tui/_assets/openrag-documents}/warmup_ocr.pdf +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/managers/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/screens/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/screens/logs.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/utils/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/utils/clipboard.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/utils/platform.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/tui/widgets/waves.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/__init__.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/container_utils.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/embedding_fields.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/embeddings.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/file_utils.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/gpu_detection.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/hash_utils.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/logging_config.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/opensearch_queries.py +0 -0
- {openrag-0.1.31 → openrag-0.2.0}/src/utils/process_pool.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrag
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Python: >=3.13
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -30,7 +30,8 @@ Requires-Dist: textual-fspicker>=0.6.0
|
|
|
30
30
|
Requires-Dist: structlog>=25.4.0
|
|
31
31
|
Requires-Dist: docling-serve==1.5.0
|
|
32
32
|
Requires-Dist: docling-core==2.48.1
|
|
33
|
-
Requires-Dist: easyocr>=1.7.1
|
|
33
|
+
Requires-Dist: easyocr>=1.7.1; sys_platform != "darwin"
|
|
34
|
+
Requires-Dist: zxcvbn>=4.5.0
|
|
34
35
|
Dynamic: license-file
|
|
35
36
|
|
|
36
37
|
<div align="center">
|
|
@@ -53,27 +54,29 @@ OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables
|
|
|
53
54
|
</div>
|
|
54
55
|
<div align="center">
|
|
55
56
|
<a href="#quickstart" style="color: #0366d6;">Quickstart</a> |
|
|
56
|
-
<a href="#
|
|
57
|
-
<a href="#docker-
|
|
57
|
+
<a href="#install-python-package" style="color: #0366d6;">Python package</a> |
|
|
58
|
+
<a href="#docker-or-podman-installation" style="color: #0366d6;">Docker or Podman</a> |
|
|
58
59
|
<a href="#development" style="color: #0366d6;">Development</a> |
|
|
59
60
|
<a href="#troubleshooting" style="color: #0366d6;">Troubleshooting</a>
|
|
60
61
|
</div>
|
|
61
62
|
|
|
62
63
|
## Quickstart
|
|
63
64
|
|
|
64
|
-
To
|
|
65
|
+
To run OpenRAG without creating or modifying any project files, use `uvx`:
|
|
65
66
|
|
|
66
67
|
```bash
|
|
67
68
|
uvx openrag
|
|
68
69
|
```
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
|
|
71
|
+
This command runs OpenRAG without installing it to your project or globally.
|
|
72
|
+
|
|
73
|
+
To run a specific version of OpenRAG, run `uvx --from openrag==VERSION openrag`.
|
|
71
74
|
|
|
72
75
|
## Install Python package
|
|
73
76
|
|
|
74
|
-
To
|
|
77
|
+
To add the OpenRAG Python package to a Python project, use `uv`:
|
|
75
78
|
|
|
76
|
-
1. Create a new project with a virtual environment using `uv init
|
|
79
|
+
1. Create a new project with a virtual environment using `uv init`:
|
|
77
80
|
|
|
78
81
|
```bash
|
|
79
82
|
uv init YOUR_PROJECT_NAME
|
|
@@ -83,33 +86,33 @@ To first set up a project and then install the OpenRAG Python package, do the fo
|
|
|
83
86
|
The `(venv)` prompt doesn't change, but `uv` commands will automatically use the project's virtual environment.
|
|
84
87
|
For more information on virtual environments, see the [uv documentation](https://docs.astral.sh/uv/pip/environments).
|
|
85
88
|
|
|
86
|
-
2. Add OpenRAG to your project
|
|
89
|
+
2. Add OpenRAG to your project:
|
|
90
|
+
|
|
87
91
|
```bash
|
|
88
92
|
uv add openrag
|
|
89
93
|
```
|
|
90
94
|
|
|
91
|
-
To add a specific version of OpenRAG
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
+
To add a specific version of OpenRAG, run `uv add openrag==VERSION`.
|
|
96
|
+
|
|
97
|
+
3. Start the OpenRAG terminal user interface (TUI):
|
|
95
98
|
|
|
96
|
-
3. Start the OpenRAG TUI.
|
|
97
99
|
```bash
|
|
98
100
|
uv run openrag
|
|
99
101
|
```
|
|
100
102
|
|
|
101
103
|
4. Continue with the [Quickstart](https://docs.openr.ag/quickstart).
|
|
102
104
|
|
|
103
|
-
For
|
|
105
|
+
For all installation options, see the [OpenRAG installation guide](https://docs.openr.ag/install).
|
|
104
106
|
|
|
105
107
|
## Docker or Podman installation
|
|
106
108
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
## Troubleshooting
|
|
110
|
-
|
|
111
|
-
For common issues and fixes, see [Troubleshoot](https://docs.openr.ag/support/troubleshoot).
|
|
109
|
+
By default, OpenRAG automatically starts the required containers and helps you manage them.
|
|
110
|
+
To install OpenRAG with self-managed containers, see the [OpenRAG installation guide](https://docs.openr.ag/docker).
|
|
112
111
|
|
|
113
112
|
## Development
|
|
114
113
|
|
|
115
114
|
For developers wanting to contribute to OpenRAG or set up a development environment, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
115
|
+
|
|
116
|
+
## Troubleshooting
|
|
117
|
+
|
|
118
|
+
For common issues and fixes, see [Troubleshoot OpenRAG](https://docs.openr.ag/support/troubleshoot).
|
|
@@ -18,27 +18,29 @@ OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables
|
|
|
18
18
|
</div>
|
|
19
19
|
<div align="center">
|
|
20
20
|
<a href="#quickstart" style="color: #0366d6;">Quickstart</a> |
|
|
21
|
-
<a href="#
|
|
22
|
-
<a href="#docker-
|
|
21
|
+
<a href="#install-python-package" style="color: #0366d6;">Python package</a> |
|
|
22
|
+
<a href="#docker-or-podman-installation" style="color: #0366d6;">Docker or Podman</a> |
|
|
23
23
|
<a href="#development" style="color: #0366d6;">Development</a> |
|
|
24
24
|
<a href="#troubleshooting" style="color: #0366d6;">Troubleshooting</a>
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
## Quickstart
|
|
28
28
|
|
|
29
|
-
To
|
|
29
|
+
To run OpenRAG without creating or modifying any project files, use `uvx`:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
uvx openrag
|
|
33
33
|
```
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
|
|
35
|
+
This command runs OpenRAG without installing it to your project or globally.
|
|
36
|
+
|
|
37
|
+
To run a specific version of OpenRAG, run `uvx --from openrag==VERSION openrag`.
|
|
36
38
|
|
|
37
39
|
## Install Python package
|
|
38
40
|
|
|
39
|
-
To
|
|
41
|
+
To add the OpenRAG Python package to a Python project, use `uv`:
|
|
40
42
|
|
|
41
|
-
1. Create a new project with a virtual environment using `uv init
|
|
43
|
+
1. Create a new project with a virtual environment using `uv init`:
|
|
42
44
|
|
|
43
45
|
```bash
|
|
44
46
|
uv init YOUR_PROJECT_NAME
|
|
@@ -48,33 +50,33 @@ To first set up a project and then install the OpenRAG Python package, do the fo
|
|
|
48
50
|
The `(venv)` prompt doesn't change, but `uv` commands will automatically use the project's virtual environment.
|
|
49
51
|
For more information on virtual environments, see the [uv documentation](https://docs.astral.sh/uv/pip/environments).
|
|
50
52
|
|
|
51
|
-
2. Add OpenRAG to your project
|
|
53
|
+
2. Add OpenRAG to your project:
|
|
54
|
+
|
|
52
55
|
```bash
|
|
53
56
|
uv add openrag
|
|
54
57
|
```
|
|
55
58
|
|
|
56
|
-
To add a specific version of OpenRAG
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```
|
|
59
|
+
To add a specific version of OpenRAG, run `uv add openrag==VERSION`.
|
|
60
|
+
|
|
61
|
+
3. Start the OpenRAG terminal user interface (TUI):
|
|
60
62
|
|
|
61
|
-
3. Start the OpenRAG TUI.
|
|
62
63
|
```bash
|
|
63
64
|
uv run openrag
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
4. Continue with the [Quickstart](https://docs.openr.ag/quickstart).
|
|
67
68
|
|
|
68
|
-
For
|
|
69
|
+
For all installation options, see the [OpenRAG installation guide](https://docs.openr.ag/install).
|
|
69
70
|
|
|
70
71
|
## Docker or Podman installation
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
By default, OpenRAG automatically starts the required containers and helps you manage them.
|
|
74
|
+
To install OpenRAG with self-managed containers, see the [OpenRAG installation guide](https://docs.openr.ag/docker).
|
|
73
75
|
|
|
74
|
-
##
|
|
76
|
+
## Development
|
|
75
77
|
|
|
76
|
-
For
|
|
78
|
+
For developers wanting to contribute to OpenRAG or set up a development environment, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
77
79
|
|
|
78
|
-
##
|
|
80
|
+
## Troubleshooting
|
|
79
81
|
|
|
80
|
-
For
|
|
82
|
+
For common issues and fixes, see [Troubleshoot OpenRAG](https://docs.openr.ag/support/troubleshoot).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openrag"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Add your description here"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
@@ -34,7 +34,8 @@ dependencies = [
|
|
|
34
34
|
"structlog>=25.4.0",
|
|
35
35
|
"docling-serve==1.5.0",
|
|
36
36
|
"docling-core==2.48.1",
|
|
37
|
-
"easyocr>=1.7.1"
|
|
37
|
+
"easyocr>=1.7.1; sys_platform != 'darwin'",
|
|
38
|
+
"zxcvbn>=4.5.0"
|
|
38
39
|
]
|
|
39
40
|
|
|
40
41
|
[dependency-groups]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from http.client import HTTPException
|
|
2
|
+
|
|
1
3
|
from utils.logging_config import get_logger
|
|
2
4
|
|
|
3
5
|
logger = get_logger(__name__)
|
|
@@ -34,7 +36,7 @@ def get_conversation_thread(user_id: str, previous_response_id: str = None):
|
|
|
34
36
|
"messages": [
|
|
35
37
|
{
|
|
36
38
|
"role": "system",
|
|
37
|
-
"content": "You are
|
|
39
|
+
"content": "You are the OpenRAG Agent. You answer questions using retrieval, reasoning, and tool use.\nYou have access to several tools. Your job is to determine **which tool to use and when**.\n### Available Tools\n- OpenSearch Retrieval Tool:\n Use this to search the indexed knowledge base. Use when the user asks about product details, internal concepts, processes, architecture, documentation, roadmaps, or anything that may be stored in the index.\n- Conversation History:\n Use this to maintain continuity when the user is referring to previous turns. \n Do not treat history as a factual source.\n- Conversation File Context:\n Use this when the user asks about a document they uploaded or refers directly to its contents.\n **IMPORTANT**: If you receive confirmation that a file was uploaded (e.g., \"Confirm that you received this file\"), the file content is already available in the conversation context. Do NOT attempt to ingest it as a URL.\n Simply acknowledge the file and answer questions about it directly from the context.\n- URL Ingestion Tool:\n Use this **only** when the user explicitly asks you to read, summarize, or analyze the content of a web URL (http:// or https://).\n **Do NOT use this tool for filenames** (e.g., README.md, document.pdf, data.txt). These are file uploads, not URLs.\n Only use this tool for actual web addresses that the user explicitly provides.\n If unclear → ask a clarifying question.\n- Calculator / Expression Evaluation Tool:\n Use this when the user asks to compare numbers, compute estimates, calculate totals, analyze pricing, or answer any question requiring mathematics or quantitative reasoning.\n If the answer requires arithmetic, call the calculator tool rather than calculating internally.\n### Retrieval Decision Rules\nUse OpenSearch **whenever**:\n1. The question may be answered from internal or indexed data.\n2. The user references team names, product names, release plans, configurations, requirements, or official information.\n3. The user needs a factual, grounded answer.\nDo **not** use retrieval if:\n- The question is purely creative (e.g., storytelling, analogies) or personal preference.\n- The user simply wants text reformatted or rewritten from what is already present in the conversation.\nWhen uncertain → **Retrieve.** Retrieval is low risk and improves grounding.\n### File Upload vs URL Distinction\n**File uploads** (already in context):\n- Filenames like: README.md, document.pdf, notes.txt, data.csv\n- When you see file confirmation messages\n- Use conversation context directly - do NOT call URL tool\n**Web URLs** (need ingestion):\n- Start with http:// or https://\n- Examples: https://example.com, http://docs.site.org\n- User explicitly asks to fetch from web\n### Calculator Usage Rules\nUse the calculator when:\n- Performing arithmetic\n- Estimating totals\n- Comparing values\n- Modeling cost, time, effort, scale, or projections\nDo not perform math internally. **Call the calculator tool instead.**\n### Answer Construction Rules\n1. When asked: \"What is OpenRAG\", answer the following:\n\"OpenRAG is an open-source package for building agentic RAG systems. It supports integration with a wide range of orchestration tools, vector databases, and LLM providers. OpenRAG connects and amplifies three popular, proven open-source projects into one powerful platform:\n**Langflow** – Langflow is a powerful tool to build and deploy AI agents and MCP servers. [Read more](https://www.langflow.org/)\n**OpenSearch** – OpenSearch is an open source, search and observability suite that brings order to unstructured data at scale. [Read more](https://opensearch.org/)\n**Docling** – Docling simplifies document processing with advanced PDF understanding, OCR support, and seamless AI integrations. Parse PDFs, DOCX, PPTX, images & more. [Read more](https://www.docling.ai/)\"\n2. Synthesize retrieved or ingested content in your own words.\n3. Support factual claims with citations in the format:\n (Source: <document_name_or_id>)\n4. If no supporting evidence is found:\n Say: \"No relevant supporting sources were found for that request.\"\n5. Never invent facts or hallucinate details.\n6. Be concise, direct, and confident. \n7. Do not reveal internal chain-of-thought.",
|
|
38
40
|
}
|
|
39
41
|
],
|
|
40
42
|
"previous_response_id": previous_response_id, # Parent response_id for branching
|
|
@@ -45,8 +47,8 @@ def get_conversation_thread(user_id: str, previous_response_id: str = None):
|
|
|
45
47
|
return new_conversation
|
|
46
48
|
|
|
47
49
|
|
|
48
|
-
def store_conversation_thread(user_id: str, response_id: str, conversation_state: dict):
|
|
49
|
-
"""Store conversation both in memory (with function calls) and persist metadata to disk"""
|
|
50
|
+
async def store_conversation_thread(user_id: str, response_id: str, conversation_state: dict):
|
|
51
|
+
"""Store conversation both in memory (with function calls) and persist metadata to disk (async, non-blocking)"""
|
|
50
52
|
# 1. Store full conversation in memory for function call preservation
|
|
51
53
|
if user_id not in active_conversations:
|
|
52
54
|
active_conversations[user_id] = {}
|
|
@@ -67,13 +69,14 @@ def store_conversation_thread(user_id: str, response_id: str, conversation_state
|
|
|
67
69
|
"created_at": conversation_state.get("created_at"),
|
|
68
70
|
"last_activity": conversation_state.get("last_activity"),
|
|
69
71
|
"previous_response_id": conversation_state.get("previous_response_id"),
|
|
72
|
+
"filter_id": conversation_state.get("filter_id"),
|
|
70
73
|
"total_messages": len(
|
|
71
74
|
[msg for msg in messages if msg.get("role") in ["user", "assistant"]]
|
|
72
75
|
),
|
|
73
76
|
# Don't store actual messages - Langflow has them
|
|
74
77
|
}
|
|
75
78
|
|
|
76
|
-
conversation_persistence.store_conversation_thread(
|
|
79
|
+
await conversation_persistence.store_conversation_thread(
|
|
77
80
|
user_id, response_id, metadata_only
|
|
78
81
|
)
|
|
79
82
|
|
|
@@ -132,6 +135,7 @@ async def async_response_stream(
|
|
|
132
135
|
|
|
133
136
|
full_response = ""
|
|
134
137
|
chunk_count = 0
|
|
138
|
+
detected_tool_call = False # Track if we've detected a tool call
|
|
135
139
|
async for chunk in response:
|
|
136
140
|
chunk_count += 1
|
|
137
141
|
logger.debug(
|
|
@@ -155,6 +159,17 @@ async def async_response_stream(
|
|
|
155
159
|
else:
|
|
156
160
|
delta_text = str(chunk.delta)
|
|
157
161
|
full_response += delta_text
|
|
162
|
+
|
|
163
|
+
# Enhanced logging for tool call detection (Granite 3.3 8b investigation)
|
|
164
|
+
chunk_attrs = dir(chunk) if hasattr(chunk, '__dict__') else []
|
|
165
|
+
tool_related_attrs = [attr for attr in chunk_attrs if 'tool' in attr.lower() or 'call' in attr.lower() or 'retrieval' in attr.lower()]
|
|
166
|
+
if tool_related_attrs:
|
|
167
|
+
logger.info(
|
|
168
|
+
"Tool-related attributes found in chunk",
|
|
169
|
+
chunk_count=chunk_count,
|
|
170
|
+
attributes=tool_related_attrs,
|
|
171
|
+
chunk_type=type(chunk).__name__
|
|
172
|
+
)
|
|
158
173
|
|
|
159
174
|
# Send the raw event as JSON followed by newline for easy parsing
|
|
160
175
|
try:
|
|
@@ -166,7 +181,57 @@ async def async_response_stream(
|
|
|
166
181
|
chunk_data = chunk.__dict__
|
|
167
182
|
else:
|
|
168
183
|
chunk_data = str(chunk)
|
|
169
|
-
|
|
184
|
+
|
|
185
|
+
# Log detailed chunk structure for investigation (especially for Granite 3.3 8b)
|
|
186
|
+
if isinstance(chunk_data, dict):
|
|
187
|
+
# Check for any fields that might indicate tool usage
|
|
188
|
+
potential_tool_fields = {
|
|
189
|
+
k: v for k, v in chunk_data.items()
|
|
190
|
+
if any(keyword in str(k).lower() for keyword in ['tool', 'call', 'retrieval', 'function', 'result', 'output'])
|
|
191
|
+
}
|
|
192
|
+
if potential_tool_fields:
|
|
193
|
+
logger.info(
|
|
194
|
+
"Potential tool-related fields in chunk",
|
|
195
|
+
chunk_count=chunk_count,
|
|
196
|
+
fields=list(potential_tool_fields.keys()),
|
|
197
|
+
sample_data=str(potential_tool_fields)[:500]
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# Middleware: Detect implicit tool calls and inject standardized events
|
|
201
|
+
# This helps Granite 3.3 8b and other models that don't emit standard markers
|
|
202
|
+
if isinstance(chunk_data, dict) and not detected_tool_call:
|
|
203
|
+
# Check if this chunk contains retrieval results
|
|
204
|
+
has_results = any([
|
|
205
|
+
'results' in chunk_data and isinstance(chunk_data.get('results'), list),
|
|
206
|
+
'outputs' in chunk_data and isinstance(chunk_data.get('outputs'), list),
|
|
207
|
+
'retrieved_documents' in chunk_data,
|
|
208
|
+
'retrieval_results' in chunk_data,
|
|
209
|
+
])
|
|
210
|
+
|
|
211
|
+
if has_results:
|
|
212
|
+
logger.info(
|
|
213
|
+
"Detected implicit tool call in backend, injecting synthetic event",
|
|
214
|
+
chunk_fields=list(chunk_data.keys())
|
|
215
|
+
)
|
|
216
|
+
# Inject a synthetic tool call event before this chunk
|
|
217
|
+
synthetic_event = {
|
|
218
|
+
"type": "response.output_item.done",
|
|
219
|
+
"item": {
|
|
220
|
+
"type": "retrieval_call",
|
|
221
|
+
"id": f"synthetic_{chunk_count}",
|
|
222
|
+
"name": "Retrieval",
|
|
223
|
+
"tool_name": "Retrieval",
|
|
224
|
+
"status": "completed",
|
|
225
|
+
"inputs": {"implicit": True, "backend_detected": True},
|
|
226
|
+
"results": chunk_data.get('results') or chunk_data.get('outputs') or
|
|
227
|
+
chunk_data.get('retrieved_documents') or
|
|
228
|
+
chunk_data.get('retrieval_results') or []
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
# Send the synthetic event first
|
|
232
|
+
yield (json.dumps(synthetic_event, default=str) + "\n").encode("utf-8")
|
|
233
|
+
detected_tool_call = True # Mark that we've injected a tool call
|
|
234
|
+
|
|
170
235
|
yield (json.dumps(chunk_data, default=str) + "\n").encode("utf-8")
|
|
171
236
|
except Exception as e:
|
|
172
237
|
# Fallback to string representation
|
|
@@ -219,15 +284,26 @@ async def async_response(
|
|
|
219
284
|
|
|
220
285
|
response = await client.responses.create(**request_params)
|
|
221
286
|
|
|
222
|
-
|
|
223
|
-
|
|
287
|
+
# Check if response has output_text using getattr to avoid issues with special objects
|
|
288
|
+
output_text = getattr(response, "output_text", None)
|
|
289
|
+
if output_text is not None:
|
|
290
|
+
response_text = output_text
|
|
291
|
+
logger.info("Response generated", log_prefix=log_prefix, response=response_text)
|
|
224
292
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
293
|
+
# Extract and store response_id if available
|
|
294
|
+
response_id = getattr(response, "id", None) or getattr(
|
|
295
|
+
response, "response_id", None
|
|
296
|
+
)
|
|
229
297
|
|
|
230
|
-
|
|
298
|
+
return response_text, response_id, response
|
|
299
|
+
else:
|
|
300
|
+
msg = "Nudge response missing output_text"
|
|
301
|
+
error = getattr(response, "error", None)
|
|
302
|
+
if error:
|
|
303
|
+
error_msg = getattr(error, "message", None)
|
|
304
|
+
if error_msg:
|
|
305
|
+
msg = error_msg
|
|
306
|
+
raise ValueError(msg)
|
|
231
307
|
except Exception as e:
|
|
232
308
|
logger.error("Exception in non-streaming response", error=str(e))
|
|
233
309
|
import traceback
|
|
@@ -314,6 +390,7 @@ async def async_chat(
|
|
|
314
390
|
user_id: str,
|
|
315
391
|
model: str = "gpt-4.1-mini",
|
|
316
392
|
previous_response_id: str = None,
|
|
393
|
+
filter_id: str = None,
|
|
317
394
|
):
|
|
318
395
|
logger.debug(
|
|
319
396
|
"async_chat called", user_id=user_id, previous_response_id=previous_response_id
|
|
@@ -334,6 +411,10 @@ async def async_chat(
|
|
|
334
411
|
"Added user message", message_count=len(conversation_state["messages"])
|
|
335
412
|
)
|
|
336
413
|
|
|
414
|
+
# Store filter_id in conversation state if provided
|
|
415
|
+
if filter_id:
|
|
416
|
+
conversation_state["filter_id"] = filter_id
|
|
417
|
+
|
|
337
418
|
response_text, response_id, response_obj = await async_response(
|
|
338
419
|
async_client,
|
|
339
420
|
prompt,
|
|
@@ -363,7 +444,7 @@ async def async_chat(
|
|
|
363
444
|
# Store the conversation thread with its response_id
|
|
364
445
|
if response_id:
|
|
365
446
|
conversation_state["last_activity"] = datetime.now()
|
|
366
|
-
store_conversation_thread(user_id, response_id, conversation_state)
|
|
447
|
+
await store_conversation_thread(user_id, response_id, conversation_state)
|
|
367
448
|
logger.debug(
|
|
368
449
|
"Stored conversation thread", user_id=user_id, response_id=response_id
|
|
369
450
|
)
|
|
@@ -389,6 +470,7 @@ async def async_chat_stream(
|
|
|
389
470
|
user_id: str,
|
|
390
471
|
model: str = "gpt-4.1-mini",
|
|
391
472
|
previous_response_id: str = None,
|
|
473
|
+
filter_id: str = None,
|
|
392
474
|
):
|
|
393
475
|
# Get the specific conversation thread (or create new one)
|
|
394
476
|
conversation_state = get_conversation_thread(user_id, previous_response_id)
|
|
@@ -399,6 +481,10 @@ async def async_chat_stream(
|
|
|
399
481
|
user_message = {"role": "user", "content": prompt, "timestamp": datetime.now()}
|
|
400
482
|
conversation_state["messages"].append(user_message)
|
|
401
483
|
|
|
484
|
+
# Store filter_id in conversation state if provided
|
|
485
|
+
if filter_id:
|
|
486
|
+
conversation_state["filter_id"] = filter_id
|
|
487
|
+
|
|
402
488
|
full_response = ""
|
|
403
489
|
response_id = None
|
|
404
490
|
async for chunk in async_stream(
|
|
@@ -437,7 +523,7 @@ async def async_chat_stream(
|
|
|
437
523
|
# Store the conversation thread with its response_id
|
|
438
524
|
if response_id:
|
|
439
525
|
conversation_state["last_activity"] = datetime.now()
|
|
440
|
-
store_conversation_thread(user_id, response_id, conversation_state)
|
|
526
|
+
await store_conversation_thread(user_id, response_id, conversation_state)
|
|
441
527
|
logger.debug(
|
|
442
528
|
f"Stored conversation thread for user {user_id} with response_id: {response_id}"
|
|
443
529
|
)
|
|
@@ -452,6 +538,7 @@ async def async_langflow_chat(
|
|
|
452
538
|
extra_headers: dict = None,
|
|
453
539
|
previous_response_id: str = None,
|
|
454
540
|
store_conversation: bool = True,
|
|
541
|
+
filter_id: str = None,
|
|
455
542
|
):
|
|
456
543
|
logger.debug(
|
|
457
544
|
"async_langflow_chat called",
|
|
@@ -478,6 +565,10 @@ async def async_langflow_chat(
|
|
|
478
565
|
message_count=len(conversation_state["messages"]),
|
|
479
566
|
)
|
|
480
567
|
|
|
568
|
+
# Store filter_id in conversation state if provided
|
|
569
|
+
if filter_id:
|
|
570
|
+
conversation_state["filter_id"] = filter_id
|
|
571
|
+
|
|
481
572
|
response_text, response_id, response_obj = await async_response(
|
|
482
573
|
langflow_client,
|
|
483
574
|
prompt,
|
|
@@ -520,7 +611,7 @@ async def async_langflow_chat(
|
|
|
520
611
|
# Store the conversation thread with its response_id
|
|
521
612
|
if response_id:
|
|
522
613
|
conversation_state["last_activity"] = datetime.now()
|
|
523
|
-
store_conversation_thread(user_id, response_id, conversation_state)
|
|
614
|
+
await store_conversation_thread(user_id, response_id, conversation_state)
|
|
524
615
|
|
|
525
616
|
# Claim session ownership for this user
|
|
526
617
|
try:
|
|
@@ -562,6 +653,7 @@ async def async_langflow_chat_stream(
|
|
|
562
653
|
user_id: str,
|
|
563
654
|
extra_headers: dict = None,
|
|
564
655
|
previous_response_id: str = None,
|
|
656
|
+
filter_id: str = None,
|
|
565
657
|
):
|
|
566
658
|
logger.debug(
|
|
567
659
|
"async_langflow_chat_stream called",
|
|
@@ -578,6 +670,10 @@ async def async_langflow_chat_stream(
|
|
|
578
670
|
user_message = {"role": "user", "content": prompt, "timestamp": datetime.now()}
|
|
579
671
|
conversation_state["messages"].append(user_message)
|
|
580
672
|
|
|
673
|
+
# Store filter_id in conversation state if provided
|
|
674
|
+
if filter_id:
|
|
675
|
+
conversation_state["filter_id"] = filter_id
|
|
676
|
+
|
|
581
677
|
full_response = ""
|
|
582
678
|
response_id = None
|
|
583
679
|
collected_chunks = [] # Store all chunks for function call data
|
|
@@ -622,7 +718,7 @@ async def async_langflow_chat_stream(
|
|
|
622
718
|
# Store the conversation thread with its response_id
|
|
623
719
|
if response_id:
|
|
624
720
|
conversation_state["last_activity"] = datetime.now()
|
|
625
|
-
store_conversation_thread(user_id, response_id, conversation_state)
|
|
721
|
+
await store_conversation_thread(user_id, response_id, conversation_state)
|
|
626
722
|
|
|
627
723
|
# Claim session ownership for this user
|
|
628
724
|
try:
|
|
@@ -638,8 +734,8 @@ async def async_langflow_chat_stream(
|
|
|
638
734
|
)
|
|
639
735
|
|
|
640
736
|
|
|
641
|
-
def delete_user_conversation(user_id: str, response_id: str) -> bool:
|
|
642
|
-
"""Delete a conversation for a user from both memory and persistent storage"""
|
|
737
|
+
async def delete_user_conversation(user_id: str, response_id: str) -> bool:
|
|
738
|
+
"""Delete a conversation for a user from both memory and persistent storage (async, non-blocking)"""
|
|
643
739
|
deleted = False
|
|
644
740
|
|
|
645
741
|
try:
|
|
@@ -650,7 +746,7 @@ def delete_user_conversation(user_id: str, response_id: str) -> bool:
|
|
|
650
746
|
deleted = True
|
|
651
747
|
|
|
652
748
|
# Delete from persistent storage
|
|
653
|
-
conversation_deleted = conversation_persistence.delete_conversation_thread(user_id, response_id)
|
|
749
|
+
conversation_deleted = await conversation_persistence.delete_conversation_thread(user_id, response_id)
|
|
654
750
|
if conversation_deleted:
|
|
655
751
|
logger.debug(f"Deleted conversation {response_id} from persistent storage for user {user_id}")
|
|
656
752
|
deleted = True
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from starlette.requests import Request
|
|
2
2
|
from starlette.responses import JSONResponse
|
|
3
|
+
from utils.telemetry import TelemetryClient, Category, MessageId
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
async def auth_init(request: Request, auth_service, session_manager):
|
|
@@ -40,8 +41,11 @@ async def auth_callback(request: Request, auth_service, session_manager):
|
|
|
40
41
|
connection_id, authorization_code, state, request
|
|
41
42
|
)
|
|
42
43
|
|
|
44
|
+
await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_OAUTH_CALLBACK)
|
|
45
|
+
|
|
43
46
|
# If this is app auth, set JWT cookie
|
|
44
47
|
if result.get("purpose") == "app_auth" and result.get("jwt_token"):
|
|
48
|
+
await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_SUCCESS)
|
|
45
49
|
response = JSONResponse(
|
|
46
50
|
{k: v for k, v in result.items() if k != "jwt_token"}
|
|
47
51
|
)
|
|
@@ -61,6 +65,7 @@ async def auth_callback(request: Request, auth_service, session_manager):
|
|
|
61
65
|
import traceback
|
|
62
66
|
|
|
63
67
|
traceback.print_exc()
|
|
68
|
+
await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_OAUTH_FAILED)
|
|
64
69
|
return JSONResponse({"error": f"Callback failed: {str(e)}"}, status_code=500)
|
|
65
70
|
|
|
66
71
|
|
|
@@ -72,6 +77,7 @@ async def auth_me(request: Request, auth_service, session_manager):
|
|
|
72
77
|
|
|
73
78
|
async def auth_logout(request: Request, auth_service, session_manager):
|
|
74
79
|
"""Logout user by clearing auth cookie"""
|
|
80
|
+
await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_LOGOUT)
|
|
75
81
|
response = JSONResponse(
|
|
76
82
|
{"status": "logged_out", "message": "Successfully logged out"}
|
|
77
83
|
)
|
|
@@ -14,6 +14,7 @@ async def chat_endpoint(request: Request, chat_service, session_manager):
|
|
|
14
14
|
filters = data.get("filters")
|
|
15
15
|
limit = data.get("limit", 10)
|
|
16
16
|
score_threshold = data.get("scoreThreshold", 0)
|
|
17
|
+
filter_id = data.get("filter_id")
|
|
17
18
|
|
|
18
19
|
user = request.state.user
|
|
19
20
|
user_id = user.user_id
|
|
@@ -42,6 +43,7 @@ async def chat_endpoint(request: Request, chat_service, session_manager):
|
|
|
42
43
|
jwt_token,
|
|
43
44
|
previous_response_id=previous_response_id,
|
|
44
45
|
stream=True,
|
|
46
|
+
filter_id=filter_id,
|
|
45
47
|
),
|
|
46
48
|
media_type="text/event-stream",
|
|
47
49
|
headers={
|
|
@@ -58,6 +60,7 @@ async def chat_endpoint(request: Request, chat_service, session_manager):
|
|
|
58
60
|
jwt_token,
|
|
59
61
|
previous_response_id=previous_response_id,
|
|
60
62
|
stream=False,
|
|
63
|
+
filter_id=filter_id,
|
|
61
64
|
)
|
|
62
65
|
return JSONResponse(result)
|
|
63
66
|
|
|
@@ -71,6 +74,7 @@ async def langflow_endpoint(request: Request, chat_service, session_manager):
|
|
|
71
74
|
filters = data.get("filters")
|
|
72
75
|
limit = data.get("limit", 10)
|
|
73
76
|
score_threshold = data.get("scoreThreshold", 0)
|
|
77
|
+
filter_id = data.get("filter_id")
|
|
74
78
|
|
|
75
79
|
user = request.state.user
|
|
76
80
|
user_id = user.user_id
|
|
@@ -100,6 +104,7 @@ async def langflow_endpoint(request: Request, chat_service, session_manager):
|
|
|
100
104
|
jwt_token,
|
|
101
105
|
previous_response_id=previous_response_id,
|
|
102
106
|
stream=True,
|
|
107
|
+
filter_id=filter_id,
|
|
103
108
|
),
|
|
104
109
|
media_type="text/event-stream",
|
|
105
110
|
headers={
|
|
@@ -116,6 +121,7 @@ async def langflow_endpoint(request: Request, chat_service, session_manager):
|
|
|
116
121
|
jwt_token,
|
|
117
122
|
previous_response_id=previous_response_id,
|
|
118
123
|
stream=False,
|
|
124
|
+
filter_id=filter_id,
|
|
119
125
|
)
|
|
120
126
|
return JSONResponse(result)
|
|
121
127
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from starlette.requests import Request
|
|
2
2
|
from starlette.responses import JSONResponse, PlainTextResponse
|
|
3
3
|
from utils.logging_config import get_logger
|
|
4
|
+
from utils.telemetry import TelemetryClient, Category, MessageId
|
|
4
5
|
|
|
5
6
|
logger = get_logger(__name__)
|
|
6
7
|
|
|
@@ -25,6 +26,7 @@ async def connector_sync(request: Request, connector_service, session_manager):
|
|
|
25
26
|
selected_files = data.get("selected_files")
|
|
26
27
|
|
|
27
28
|
try:
|
|
29
|
+
await TelemetryClient.send_event(Category.CONNECTOR_OPERATIONS, MessageId.ORB_CONN_SYNC_START)
|
|
28
30
|
logger.debug(
|
|
29
31
|
"Starting connector sync",
|
|
30
32
|
connector_type=connector_type,
|
|
@@ -102,6 +104,7 @@ async def connector_sync(request: Request, connector_service, session_manager):
|
|
|
102
104
|
jwt_token=jwt_token,
|
|
103
105
|
)
|
|
104
106
|
task_ids = [task_id]
|
|
107
|
+
await TelemetryClient.send_event(Category.CONNECTOR_OPERATIONS, MessageId.ORB_CONN_SYNC_COMPLETE)
|
|
105
108
|
return JSONResponse(
|
|
106
109
|
{
|
|
107
110
|
"task_ids": task_ids,
|
|
@@ -114,6 +117,7 @@ async def connector_sync(request: Request, connector_service, session_manager):
|
|
|
114
117
|
|
|
115
118
|
except Exception as e:
|
|
116
119
|
logger.error("Connector sync failed", error=str(e))
|
|
120
|
+
await TelemetryClient.send_event(Category.CONNECTOR_OPERATIONS, MessageId.ORB_CONN_SYNC_FAILED)
|
|
117
121
|
return JSONResponse({"error": f"Sync failed: {str(e)}"}, status_code=500)
|
|
118
122
|
|
|
119
123
|
|
|
@@ -185,6 +189,7 @@ async def connector_webhook(request: Request, connector_service, session_manager
|
|
|
185
189
|
config=temp_config,
|
|
186
190
|
)
|
|
187
191
|
try:
|
|
192
|
+
await TelemetryClient.send_event(Category.CONNECTOR_OPERATIONS, MessageId.ORB_CONN_WEBHOOK_RECV)
|
|
188
193
|
temp_connector = connector_service.connection_manager._create_connector(
|
|
189
194
|
temp_connection
|
|
190
195
|
)
|
|
@@ -336,6 +341,7 @@ async def connector_webhook(request: Request, connector_service, session_manager
|
|
|
336
341
|
|
|
337
342
|
except Exception as e:
|
|
338
343
|
logger.error("Webhook processing failed", error=str(e))
|
|
344
|
+
await TelemetryClient.send_event(Category.CONNECTOR_OPERATIONS, MessageId.ORB_CONN_WEBHOOK_FAILED)
|
|
339
345
|
return JSONResponse(
|
|
340
346
|
{"error": f"Webhook processing failed: {str(e)}"}, status_code=500
|
|
341
347
|
)
|