lightspeed-stack 0.1.1__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/PKG-INFO +10 -2
  2. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/README.md +1 -1
  3. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/pyproject.toml +17 -1
  4. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/conversations.py +10 -5
  5. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/health.py +7 -6
  6. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/query.py +38 -24
  7. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/streaming_query.py +36 -23
  8. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/models/requests.py +3 -0
  9. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/test_results/.coverage.integration +0 -0
  10. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/test_results/.coverage.unit +0 -0
  11. lightspeed_stack-0.1.3/tests/test_results/coverage_integration.json +1 -0
  12. lightspeed_stack-0.1.3/tests/test_results/coverage_unit.json +1 -0
  13. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/test_results/junit_integration.xml +1 -1
  14. lightspeed_stack-0.1.3/tests/test_results/junit_unit.xml +1 -0
  15. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_health.py +11 -11
  16. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_query.py +319 -7
  17. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_streaming_query.py +313 -0
  18. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/models/test_config.py +48 -0
  19. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/test_client.py +12 -2
  20. lightspeed_stack-0.1.1/tests/test_results/coverage_integration.json +0 -1
  21. lightspeed_stack-0.1.1/tests/test_results/coverage_unit.json +0 -1
  22. lightspeed_stack-0.1.1/tests/test_results/junit_unit.xml +0 -1
  23. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/LICENSE +0 -0
  24. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/__init__.py +0 -0
  25. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/.ruff_cache/.gitignore +0 -0
  26. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/.ruff_cache/0.9.1/5703048272820174433 +0 -0
  27. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/.ruff_cache/0.9.1/9961612457335986079 +0 -0
  28. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/.ruff_cache/CACHEDIR.TAG +0 -0
  29. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/__init__.py +0 -0
  30. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/authorized.py +0 -0
  31. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/config.py +0 -0
  32. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/feedback.py +0 -0
  33. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/info.py +0 -0
  34. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/metrics.py +0 -0
  35. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/models.py +0 -0
  36. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/endpoints/root.py +0 -0
  37. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/main.py +0 -0
  38. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/app/routers.py +0 -0
  39. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/auth/__init__.py +0 -0
  40. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/auth/interface.py +0 -0
  41. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/auth/jwk_token.py +0 -0
  42. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/auth/k8s.py +0 -0
  43. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/auth/noop.py +0 -0
  44. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/auth/noop_with_token.py +0 -0
  45. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/auth/utils.py +0 -0
  46. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/metrics/__init__.py +0 -0
  47. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/metrics/utils.py +0 -0
  48. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/models/__init__.py +0 -0
  49. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/models/config.py +0 -0
  50. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/models/responses.py +0 -0
  51. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/runners/__init__.py +0 -0
  52. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/runners/data_collector.py +0 -0
  53. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/runners/uvicorn.py +0 -0
  54. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/services/__init__.py +0 -0
  55. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/services/data_collector.py +0 -0
  56. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/.ruff_cache/.gitignore +0 -0
  57. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/.ruff_cache/0.9.1/18446581155718949728 +0 -0
  58. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/.ruff_cache/0.9.1/4991844299736624256 +0 -0
  59. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/.ruff_cache/CACHEDIR.TAG +0 -0
  60. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/__init__.py +0 -0
  61. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/checks.py +0 -0
  62. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/common.py +0 -0
  63. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/endpoints.py +0 -0
  64. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/mcp_headers.py +0 -0
  65. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/suid.py +0 -0
  66. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/src/utils/types.py +0 -0
  67. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/__init__.py +0 -0
  68. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/configuration/lightspeed-stack.yaml +0 -0
  69. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/configuration/minimal-stack.yaml +0 -0
  70. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/configuration/password +0 -0
  71. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/configuration/run.yaml +0 -0
  72. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/configuration/server.crt +0 -0
  73. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/configuration/server.key +0 -0
  74. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/.pdm-python +0 -0
  75. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/.ruff_cache/.gitignore +0 -0
  76. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/.ruff_cache/0.9.1/6949908709306621198 +0 -0
  77. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/.ruff_cache/CACHEDIR.TAG +0 -0
  78. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/__init__.py +0 -0
  79. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/environment.py +0 -0
  80. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/llm_interface.feature +0 -0
  81. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/rest_api.feature +0 -0
  82. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/smoketests.feature +0 -0
  83. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/steps/__init__.py +0 -0
  84. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/steps/common.py +0 -0
  85. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/steps/common_http.py +0 -0
  86. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/features/steps/llm_query_response.py +0 -0
  87. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/gen_scenario_list.py +0 -0
  88. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/test_api.py +0 -0
  89. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/test_list.txt +0 -0
  90. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/e2e/utils/utils.py +0 -0
  91. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/integration/__init__.py +0 -0
  92. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/integration/test_configuration.py +0 -0
  93. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/integration/test_version.py +0 -0
  94. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/__init__.py +0 -0
  95. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/__init__.py +0 -0
  96. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/__init__.py +0 -0
  97. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_authorized.py +0 -0
  98. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_config.py +0 -0
  99. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_conversations.py +0 -0
  100. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_feedback.py +0 -0
  101. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_info.py +0 -0
  102. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_metrics.py +0 -0
  103. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_models.py +0 -0
  104. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/endpoints/test_root.py +0 -0
  105. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/app/test_routers.py +0 -0
  106. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/auth/__init__.py +0 -0
  107. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/auth/test_auth.py +0 -0
  108. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/auth/test_jwk_token.py +0 -0
  109. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/auth/test_k8s.py +0 -0
  110. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/auth/test_noop.py +0 -0
  111. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/auth/test_noop_with_token.py +0 -0
  112. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/auth/test_utils.py +0 -0
  113. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/metrics/__init__.py +0 -0
  114. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/metrics/test_utis.py +0 -0
  115. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/models/__init__.py +0 -0
  116. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/models/test_requests.py +0 -0
  117. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/models/test_responses.py +0 -0
  118. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/runners/__init__.py +0 -0
  119. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/runners/test_data_collector_runner.py +0 -0
  120. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/runners/test_uvicorn_runner.py +0 -0
  121. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/services/test_data_collector.py +0 -0
  122. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/test_configuration.py +0 -0
  123. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/test_lightspeed_stack.py +0 -0
  124. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/test_log.py +0 -0
  125. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/utils/__init__.py +0 -0
  126. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/utils/test_checks.py +0 -0
  127. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/utils/test_common.py +0 -0
  128. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/utils/test_endpoints.py +0 -0
  129. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/utils/test_mcp_headers.py +0 -0
  130. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/utils/test_suid.py +0 -0
  131. {lightspeed_stack-0.1.1 → lightspeed_stack-0.1.3}/tests/unit/utils/test_types.py +0 -0
@@ -1,7 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lightspeed-stack
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: LLM tooling stack
5
+ Keywords: LLM,RAG
6
+ Maintainer-Email: =?utf-8?b?UGF2ZWwgVGnFoW5vdnNrw70=?= <tisnik@centrum.cz>
5
7
  License: Apache License
6
8
  Version 2.0, January 2004
7
9
  http://www.apache.org/licenses/
@@ -204,6 +206,12 @@ License: Apache License
204
206
  See the License for the specific language governing permissions and
205
207
  limitations under the License.
206
208
 
209
+ Classifier: Development Status :: 4 - Beta
210
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
211
+ Classifier: Topic :: Software Development
212
+ Classifier: Programming Language :: Python :: 3
213
+ Classifier: Programming Language :: Python :: 3 :: Only
214
+ Classifier: License :: OSI Approved :: Apache Software License
207
215
  Project-URL: Homepage, https://github.com/lightspeed-core/lightspeed-stack
208
216
  Project-URL: Issues, https://github.com/lightspeed-core/lightspeed-stack/issues
209
217
  Requires-Python: <3.14,>=3.12
@@ -228,7 +236,7 @@ Description-Content-Type: text/markdown
228
236
  [![License](https://img.shields.io/badge/license-Apache-blue)](https://github.com/lightspeed-core/lightspeed-stack/blob/main/LICENSE)
229
237
  [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)
230
238
  [![Required Python version](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Flightspeed-core%2Flightspeed-stack%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)](https://www.python.org/)
231
- [![Tag](https://img.shields.io/github/v/tag/lightspeed-core/lightspeed-stack)](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.1.1)
239
+ [![Tag](https://img.shields.io/github/v/tag/lightspeed-core/lightspeed-stack)](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.1.3)
232
240
 
233
241
  Lightspeed Core Stack (LCS) is an AI-powered assistant that provides answers to product questions using backend LLM services, agents, and RAG databases.
234
242
 
@@ -6,7 +6,7 @@
6
6
  [![License](https://img.shields.io/badge/license-Apache-blue)](https://github.com/lightspeed-core/lightspeed-stack/blob/main/LICENSE)
7
7
  [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)
8
8
  [![Required Python version](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Flightspeed-core%2Flightspeed-stack%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)](https://www.python.org/)
9
- [![Tag](https://img.shields.io/github/v/tag/lightspeed-core/lightspeed-stack)](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.1.1)
9
+ [![Tag](https://img.shields.io/github/v/tag/lightspeed-core/lightspeed-stack)](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.1.3)
10
10
 
11
11
  Lightspeed Core Stack (LCS) is an AI-powered assistant that provides answers to product questions using backend LLM services, agents, and RAG databases.
12
12
 
@@ -3,6 +3,21 @@ name = "lightspeed-stack"
3
3
  dynamic = []
4
4
  description = "LLM tooling stack"
5
5
  authors = []
6
+ maintainers = [
7
+ { email = "tisnik@centrum.cz", name = "Pavel Tišnovský" },
8
+ ]
9
+ classifiers = [
10
+ "Development Status :: 4 - Beta",
11
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
12
+ "Topic :: Software Development",
13
+ "Programming Language :: Python :: 3",
14
+ "Programming Language :: Python :: 3 :: Only",
15
+ "License :: OSI Approved :: Apache Software License",
16
+ ]
17
+ keywords = [
18
+ "LLM",
19
+ "RAG",
20
+ ]
6
21
  requires-python = ">=3.12,<3.14"
7
22
  readme = "README.md"
8
23
  dependencies = [
@@ -18,7 +33,7 @@ dependencies = [
18
33
  "aiohttp>=3.12.14",
19
34
  "authlib>=1.6.0",
20
35
  ]
21
- version = "0.1.1"
36
+ version = "0.1.3"
22
37
 
23
38
  [project.license]
24
39
  file = "LICENSE"
@@ -77,6 +92,7 @@ dev = [
77
92
  "behave>=1.2.6",
78
93
  "types-cachetools>=6.1.0.20250717",
79
94
  "build>=1.2.2.post1",
95
+ "twine>=6.1.0",
80
96
  ]
81
97
  build = [
82
98
  "build>=1.2.2.post1",
@@ -23,11 +23,16 @@ conversation_id_to_agent_id: dict[str, str] = {}
23
23
  conversation_responses: dict[int | str, dict[str, Any]] = {
24
24
  200: {
25
25
  "conversation_id": "123e4567-e89b-12d3-a456-426614174000",
26
- "session_data": {
27
- "session_id": "123e4567-e89b-12d3-a456-426614174000",
28
- "turns": [],
29
- "started_at": "2024-01-01T00:00:00Z",
30
- },
26
+ "chat_history": [
27
+ {
28
+ "messages": [
29
+ {"content": "Hi", "type": "user"},
30
+ {"content": "Hello!", "type": "assistant"},
31
+ ],
32
+ "started_at": "2024-01-01T00:00:00Z",
33
+ "completed_at": "2024-01-01T00:00:05Z",
34
+ }
35
+ ],
31
36
  },
32
37
  404: {
33
38
  "detail": {
@@ -11,7 +11,7 @@ from typing import Any
11
11
  from llama_stack.providers.datatypes import HealthStatus
12
12
 
13
13
  from fastapi import APIRouter, status, Response
14
- from client import LlamaStackClientHolder
14
+ from client import AsyncLlamaStackClientHolder
15
15
  from models.responses import (
16
16
  LivenessResponse,
17
17
  ReadinessResponse,
@@ -22,16 +22,17 @@ logger = logging.getLogger(__name__)
22
22
  router = APIRouter(tags=["health"])
23
23
 
24
24
 
25
- def get_providers_health_statuses() -> list[ProviderHealthStatus]:
25
+ async def get_providers_health_statuses() -> list[ProviderHealthStatus]:
26
26
  """Check health of all providers.
27
27
 
28
28
  Returns:
29
29
  List of provider health statuses.
30
30
  """
31
31
  try:
32
- client = LlamaStackClientHolder().get_client()
32
+ client = AsyncLlamaStackClientHolder().get_client()
33
33
 
34
- providers = client.providers.list()
34
+ # providers = []
35
+ providers = await client.providers.list()
35
36
  logger.debug("Found %d providers", len(providers))
36
37
 
37
38
  health_results = [
@@ -69,9 +70,9 @@ get_readiness_responses: dict[int | str, dict[str, Any]] = {
69
70
 
70
71
 
71
72
  @router.get("/readiness", responses=get_readiness_responses)
72
- def readiness_probe_get_method(response: Response) -> ReadinessResponse:
73
+ async def readiness_probe_get_method(response: Response) -> ReadinessResponse:
73
74
  """Ready status of service with provider health details."""
74
- provider_statuses = get_providers_health_statuses()
75
+ provider_statuses = await get_providers_health_statuses()
75
76
 
76
77
  # Check if any provider is unhealthy (not counting not_implemented as unhealthy)
77
78
  unhealthy_providers = [
@@ -80,6 +80,7 @@ def get_agent( # pylint: disable=too-many-arguments,too-many-positional-argumen
80
80
  available_input_shields: list[str],
81
81
  available_output_shields: list[str],
82
82
  conversation_id: str | None,
83
+ no_tools: bool = False,
83
84
  ) -> tuple[Agent, str]:
84
85
  """Get existing agent or create a new one with session persistence."""
85
86
  if conversation_id is not None:
@@ -99,7 +100,7 @@ def get_agent( # pylint: disable=too-many-arguments,too-many-positional-argumen
99
100
  instructions=system_prompt,
100
101
  input_shields=available_input_shields if available_input_shields else [],
101
102
  output_shields=available_output_shields if available_output_shields else [],
102
- tool_parser=GraniteToolParser.get_parser(model_id),
103
+ tool_parser=None if no_tools else GraniteToolParser.get_parser(model_id),
103
104
  enable_session_persistence=True,
104
105
  )
105
106
  conversation_id = agent.create_session(get_suid())
@@ -216,10 +217,12 @@ def select_model_and_provider_id(
216
217
  },
217
218
  ) from e
218
219
 
220
+ llama_stack_model_id = f"{provider_id}/{model_id}"
219
221
  # Validate that the model_id and provider_id are in the available models
220
222
  logger.debug("Searching for model: %s, provider: %s", model_id, provider_id)
221
223
  if not any(
222
- m.identifier == model_id and m.provider_id == provider_id for m in models
224
+ m.identifier == llama_stack_model_id and m.provider_id == provider_id
225
+ for m in models
223
226
  ):
224
227
  message = f"Model {model_id} from provider {provider_id} not found in available models"
225
228
  logger.error(message)
@@ -231,7 +234,7 @@ def select_model_and_provider_id(
231
234
  },
232
235
  )
233
236
 
234
- return model_id, provider_id
237
+ return llama_stack_model_id, provider_id
235
238
 
236
239
 
237
240
  def _is_inout_shield(shield: Shield) -> bool:
@@ -286,36 +289,47 @@ def retrieve_response( # pylint: disable=too-many-locals
286
289
  available_input_shields,
287
290
  available_output_shields,
288
291
  query_request.conversation_id,
292
+ query_request.no_tools or False,
289
293
  )
290
294
 
291
- # preserve compatibility when mcp_headers is not provided
292
- if mcp_headers is None:
295
+ # bypass tools and MCP servers if no_tools is True
296
+ if query_request.no_tools:
293
297
  mcp_headers = {}
294
- mcp_headers = handle_mcp_headers_with_toolgroups(mcp_headers, configuration)
295
- if not mcp_headers and token:
296
- for mcp_server in configuration.mcp_servers:
297
- mcp_headers[mcp_server.url] = {
298
- "Authorization": f"Bearer {token}",
299
- }
300
-
301
- agent.extra_headers = {
302
- "X-LlamaStack-Provider-Data": json.dumps(
303
- {
304
- "mcp_headers": mcp_headers,
305
- }
306
- ),
307
- }
298
+ agent.extra_headers = {}
299
+ toolgroups = None
300
+ else:
301
+ # preserve compatibility when mcp_headers is not provided
302
+ if mcp_headers is None:
303
+ mcp_headers = {}
304
+ mcp_headers = handle_mcp_headers_with_toolgroups(mcp_headers, configuration)
305
+ if not mcp_headers and token:
306
+ for mcp_server in configuration.mcp_servers:
307
+ mcp_headers[mcp_server.url] = {
308
+ "Authorization": f"Bearer {token}",
309
+ }
310
+
311
+ agent.extra_headers = {
312
+ "X-LlamaStack-Provider-Data": json.dumps(
313
+ {
314
+ "mcp_headers": mcp_headers,
315
+ }
316
+ ),
317
+ }
318
+
319
+ vector_db_ids = [vector_db.identifier for vector_db in client.vector_dbs.list()]
320
+ toolgroups = (get_rag_toolgroups(vector_db_ids) or []) + [
321
+ mcp_server.name for mcp_server in configuration.mcp_servers
322
+ ]
323
+ # Convert empty list to None for consistency with existing behavior
324
+ if not toolgroups:
325
+ toolgroups = None
308
326
 
309
- vector_db_ids = [vector_db.identifier for vector_db in client.vector_dbs.list()]
310
- toolgroups = (get_rag_toolgroups(vector_db_ids) or []) + [
311
- mcp_server.name for mcp_server in configuration.mcp_servers
312
- ]
313
327
  response = agent.create_turn(
314
328
  messages=[UserMessage(role="user", content=query_request.query)],
315
329
  session_id=conversation_id,
316
330
  documents=query_request.get_documents(),
317
331
  stream=False,
318
- toolgroups=toolgroups or None,
332
+ toolgroups=toolgroups,
319
333
  )
320
334
 
321
335
  # Check for validation errors in the response
@@ -58,6 +58,7 @@ async def get_agent(
58
58
  available_input_shields: list[str],
59
59
  available_output_shields: list[str],
60
60
  conversation_id: str | None,
61
+ no_tools: bool = False,
61
62
  ) -> tuple[AsyncAgent, str]:
62
63
  """Get existing agent or create a new one with session persistence."""
63
64
  if conversation_id is not None:
@@ -76,7 +77,7 @@ async def get_agent(
76
77
  instructions=system_prompt,
77
78
  input_shields=available_input_shields if available_input_shields else [],
78
79
  output_shields=available_output_shields if available_output_shields else [],
79
- tool_parser=GraniteToolParser.get_parser(model_id),
80
+ tool_parser=None if no_tools else GraniteToolParser.get_parser(model_id),
80
81
  enable_session_persistence=True,
81
82
  )
82
83
  conversation_id = await agent.create_session(get_suid())
@@ -532,41 +533,53 @@ async def retrieve_response(
532
533
  available_input_shields,
533
534
  available_output_shields,
534
535
  query_request.conversation_id,
536
+ query_request.no_tools or False,
535
537
  )
536
538
 
537
- # preserve compatibility when mcp_headers is not provided
538
- if mcp_headers is None:
539
+ # bypass tools and MCP servers if no_tools is True
540
+ if query_request.no_tools:
539
541
  mcp_headers = {}
542
+ agent.extra_headers = {}
543
+ toolgroups = None
544
+ else:
545
+ # preserve compatibility when mcp_headers is not provided
546
+ if mcp_headers is None:
547
+ mcp_headers = {}
540
548
 
541
- mcp_headers = handle_mcp_headers_with_toolgroups(mcp_headers, configuration)
549
+ mcp_headers = handle_mcp_headers_with_toolgroups(mcp_headers, configuration)
542
550
 
543
- if not mcp_headers and token:
544
- for mcp_server in configuration.mcp_servers:
545
- mcp_headers[mcp_server.url] = {
546
- "Authorization": f"Bearer {token}",
547
- }
551
+ if not mcp_headers and token:
552
+ for mcp_server in configuration.mcp_servers:
553
+ mcp_headers[mcp_server.url] = {
554
+ "Authorization": f"Bearer {token}",
555
+ }
548
556
 
549
- agent.extra_headers = {
550
- "X-LlamaStack-Provider-Data": json.dumps(
551
- {
552
- "mcp_headers": mcp_headers,
553
- }
554
- ),
555
- }
557
+ agent.extra_headers = {
558
+ "X-LlamaStack-Provider-Data": json.dumps(
559
+ {
560
+ "mcp_headers": mcp_headers,
561
+ }
562
+ ),
563
+ }
564
+
565
+ logger.debug("Session ID: %s", conversation_id)
566
+ vector_db_ids = [
567
+ vector_db.identifier for vector_db in await client.vector_dbs.list()
568
+ ]
569
+ toolgroups = (get_rag_toolgroups(vector_db_ids) or []) + [
570
+ mcp_server.name for mcp_server in configuration.mcp_servers
571
+ ]
572
+ # Convert empty list to None for consistency with existing behavior
573
+ if not toolgroups:
574
+ toolgroups = None
556
575
 
557
576
  logger.debug("Session ID: %s", conversation_id)
558
- vector_db_ids = [
559
- vector_db.identifier for vector_db in await client.vector_dbs.list()
560
- ]
561
- toolgroups = (get_rag_toolgroups(vector_db_ids) or []) + [
562
- mcp_server.name for mcp_server in configuration.mcp_servers
563
- ]
564
577
  response = await agent.create_turn(
565
578
  messages=[UserMessage(role="user", content=query_request.query)],
566
579
  session_id=conversation_id,
567
580
  documents=query_request.get_documents(),
568
581
  stream=True,
569
- toolgroups=toolgroups or None,
582
+ toolgroups=toolgroups,
570
583
  )
571
584
 
572
585
  return response, conversation_id
@@ -69,6 +69,7 @@ class QueryRequest(BaseModel):
69
69
  model: The optional model.
70
70
  system_prompt: The optional system prompt.
71
71
  attachments: The optional attachments.
72
+ no_tools: Whether to bypass all tools and MCP servers (default: False).
72
73
 
73
74
  Example:
74
75
  ```python
@@ -82,6 +83,7 @@ class QueryRequest(BaseModel):
82
83
  model: Optional[str] = None
83
84
  system_prompt: Optional[str] = None
84
85
  attachments: Optional[list[Attachment]] = None
86
+ no_tools: Optional[bool] = False
85
87
  # media_type is not used in 'lightspeed-stack' that only supports application/json.
86
88
  # the field is kept here to enable compatibility with 'road-core' clients.
87
89
  media_type: Optional[str] = None
@@ -97,6 +99,7 @@ class QueryRequest(BaseModel):
97
99
  "provider": "openai",
98
100
  "model": "model-name",
99
101
  "system_prompt": "You are a helpful assistant",
102
+ "no_tools": False,
100
103
  "attachments": [
101
104
  {
102
105
  "attachment_type": "log",