lightspeed-stack 0.1.0__tar.gz → 0.1.2__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.
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/PKG-INFO +276 -11
- lightspeed_stack-0.1.2/README.md +478 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/pyproject.toml +33 -4
- lightspeed_stack-0.1.2/src/app/endpoints/authorized.py +38 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/config.py +2 -2
- lightspeed_stack-0.1.2/src/app/endpoints/conversations.py +263 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/feedback.py +16 -3
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/health.py +2 -5
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/info.py +2 -1
- lightspeed_stack-0.1.2/src/app/endpoints/metrics.py +16 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/models.py +3 -2
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/query.py +110 -28
- lightspeed_stack-0.1.2/src/app/endpoints/streaming_query.py +572 -0
- lightspeed_stack-0.1.2/src/app/main.py +86 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/routers.py +10 -2
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/auth/__init__.py +7 -2
- lightspeed_stack-0.1.2/src/auth/jwk_token.py +191 -0
- lightspeed_stack-0.1.2/src/metrics/__init__.py +51 -0
- lightspeed_stack-0.1.2/src/metrics/utils.py +50 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/models/config.py +105 -9
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/models/requests.py +90 -10
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/models/responses.py +142 -0
- lightspeed_stack-0.1.2/src/runners/data_collector.py +26 -0
- lightspeed_stack-0.1.2/src/services/__init__.py +1 -0
- lightspeed_stack-0.1.2/src/services/data_collector.py +258 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/common.py +8 -14
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/endpoints.py +19 -3
- lightspeed_stack-0.1.2/src/utils/mcp_headers.py +90 -0
- lightspeed_stack-0.1.2/src/utils/types.py +37 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/configuration/lightspeed-stack.yaml +1 -1
- lightspeed_stack-0.1.2/tests/configuration/run.yaml +125 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/rest_api.feature +3 -2
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/steps/common_http.py +47 -7
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/steps/llm_query_response.py +12 -2
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/gen_scenario_list.py +11 -6
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/integration/test_configuration.py +5 -5
- {lightspeed_stack-0.1.0/tests/unit → lightspeed_stack-0.1.2/tests/integration}/test_version.py +1 -1
- lightspeed_stack-0.1.0/tests/test_results/.coverage.unit → lightspeed_stack-0.1.2/tests/test_results/.coverage.integration +0 -0
- lightspeed_stack-0.1.2/tests/test_results/.coverage.unit +0 -0
- lightspeed_stack-0.1.2/tests/test_results/coverage_integration.json +1 -0
- lightspeed_stack-0.1.2/tests/test_results/coverage_unit.json +1 -0
- lightspeed_stack-0.1.2/tests/test_results/junit_integration.xml +1 -0
- lightspeed_stack-0.1.2/tests/test_results/junit_unit.xml +1 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/__init__.py +2 -1
- lightspeed_stack-0.1.2/tests/unit/app/endpoints/test_authorized.py +56 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_config.py +4 -2
- lightspeed_stack-0.1.2/tests/unit/app/endpoints/test_conversations.py +494 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_feedback.py +59 -26
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_health.py +8 -18
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_info.py +4 -2
- lightspeed_stack-0.1.2/tests/unit/app/endpoints/test_metrics.py +25 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_models.py +87 -16
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_query.py +343 -72
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_root.py +3 -1
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/test_streaming_query.py +561 -98
- lightspeed_stack-0.1.2/tests/unit/app/test_routers.py +79 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/auth/test_auth.py +3 -0
- lightspeed_stack-0.1.2/tests/unit/auth/test_jwk_token.py +540 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/auth/test_k8s.py +2 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/auth/test_noop_with_token.py +2 -2
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/auth/test_utils.py +6 -4
- lightspeed_stack-0.1.2/tests/unit/metrics/__init__.py +1 -0
- lightspeed_stack-0.1.2/tests/unit/metrics/test_utis.py +69 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/models/test_config.py +288 -172
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/models/test_requests.py +169 -4
- lightspeed_stack-0.1.2/tests/unit/models/test_responses.py +86 -0
- lightspeed_stack-0.1.2/tests/unit/runners/test_data_collector_runner.py +60 -0
- lightspeed_stack-0.1.2/tests/unit/services/test_data_collector.py +587 -0
- lightspeed_stack-0.1.2/tests/unit/test_client.py +130 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/test_configuration.py +103 -21
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/utils/test_checks.py +9 -6
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/utils/test_common.py +37 -28
- lightspeed_stack-0.1.2/tests/unit/utils/test_endpoints.py +145 -0
- lightspeed_stack-0.1.2/tests/unit/utils/test_mcp_headers.py +184 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/utils/test_suid.py +4 -0
- lightspeed_stack-0.1.2/tests/unit/utils/test_types.py +53 -0
- lightspeed_stack-0.1.0/README.md +0 -226
- lightspeed_stack-0.1.0/src/app/endpoints/streaming_query.py +0 -321
- lightspeed_stack-0.1.0/src/app/main.py +0 -38
- lightspeed_stack-0.1.0/src/utils/mcp_headers.py +0 -48
- lightspeed_stack-0.1.0/tests/integration/test_openapi.py +0 -82
- lightspeed_stack-0.1.0/tests/test_results/coverage_integration.json +0 -1
- lightspeed_stack-0.1.0/tests/test_results/coverage_unit.json +0 -1
- lightspeed_stack-0.1.0/tests/test_results/junit_integration.xml +0 -6
- lightspeed_stack-0.1.0/tests/test_results/junit_unit.xml +0 -1
- lightspeed_stack-0.1.0/tests/unit/app/endpoints/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.1.0/tests/unit/app/endpoints/.ruff_cache/0.9.1/15310180828563549007 +0 -0
- lightspeed_stack-0.1.0/tests/unit/app/endpoints/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.1.0/tests/unit/app/test_routers.py +0 -45
- lightspeed_stack-0.1.0/tests/unit/models/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.1.0/tests/unit/models/.ruff_cache/0.9.1/6074929168888993057 +0 -0
- lightspeed_stack-0.1.0/tests/unit/models/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.1.0/tests/unit/models/test_responses.py +0 -30
- lightspeed_stack-0.1.0/tests/unit/test_client.py +0 -83
- lightspeed_stack-0.1.0/tests/unit/utils/test_endpoints.py +0 -169
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/LICENSE +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/.ruff_cache/.gitignore +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/.ruff_cache/0.9.1/5703048272820174433 +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/.ruff_cache/0.9.1/9961612457335986079 +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/.ruff_cache/CACHEDIR.TAG +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/app/endpoints/root.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/auth/interface.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/auth/k8s.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/auth/noop.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/auth/noop_with_token.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/auth/utils.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/models/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/runners/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/runners/uvicorn.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/.ruff_cache/.gitignore +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/.ruff_cache/0.9.1/18446581155718949728 +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/.ruff_cache/0.9.1/4991844299736624256 +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/.ruff_cache/CACHEDIR.TAG +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/checks.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/src/utils/suid.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/configuration/minimal-stack.yaml +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/configuration/password +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/configuration/server.crt +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/configuration/server.key +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/.pdm-python +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/.ruff_cache/.gitignore +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/.ruff_cache/0.9.1/6949908709306621198 +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/.ruff_cache/CACHEDIR.TAG +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/environment.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/llm_interface.feature +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/smoketests.feature +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/steps/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/features/steps/common.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/test_api.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/test_list.txt +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/e2e/utils/utils.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/integration/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/app/endpoints/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/auth/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/auth/test_noop.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/models/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/runners/__init__.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/runners/test_uvicorn_runner.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/test_lightspeed_stack.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/test_log.py +0 -0
- {lightspeed_stack-0.1.0 → lightspeed_stack-0.1.2}/tests/unit/utils/__init__.py +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lightspeed-stack
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
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,15 +206,26 @@ 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
|
|
210
218
|
Requires-Dist: fastapi>=0.115.6
|
|
211
219
|
Requires-Dist: uvicorn>=0.34.3
|
|
212
220
|
Requires-Dist: kubernetes>=30.1.0
|
|
213
|
-
Requires-Dist: llama-stack
|
|
221
|
+
Requires-Dist: llama-stack==0.2.16
|
|
222
|
+
Requires-Dist: llama-stack-client==0.2.16
|
|
214
223
|
Requires-Dist: rich>=14.0.0
|
|
215
224
|
Requires-Dist: cachetools>=6.1.0
|
|
225
|
+
Requires-Dist: prometheus-client>=0.22.1
|
|
226
|
+
Requires-Dist: starlette>=0.47.1
|
|
227
|
+
Requires-Dist: aiohttp>=3.12.14
|
|
228
|
+
Requires-Dist: authlib>=1.6.0
|
|
216
229
|
Description-Content-Type: text/markdown
|
|
217
230
|
|
|
218
231
|
# lightspeed-stack
|
|
@@ -222,31 +235,61 @@ Description-Content-Type: text/markdown
|
|
|
222
235
|
[](https://lightspeed-core.github.io/lightspeed-stack/)
|
|
223
236
|
[](https://github.com/lightspeed-core/lightspeed-stack/blob/main/LICENSE)
|
|
224
237
|
[](https://www.python.org/)
|
|
238
|
+
[](https://www.python.org/)
|
|
239
|
+
[](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.1.2)
|
|
225
240
|
|
|
226
|
-
Lightspeed Core Stack (LCS) is an AI
|
|
241
|
+
Lightspeed Core Stack (LCS) is an AI-powered assistant that provides answers to product questions using backend LLM services, agents, and RAG databases.
|
|
227
242
|
|
|
228
243
|
|
|
229
244
|
<!-- vim-markdown-toc GFM -->
|
|
230
245
|
|
|
231
|
-
* [
|
|
246
|
+
* [Architecture](#architecture)
|
|
247
|
+
* [Prerequisites](#prerequisites)
|
|
232
248
|
* [Installation](#installation)
|
|
233
249
|
* [Configuration](#configuration)
|
|
250
|
+
* [Integration with Llama Stack](#integration-with-llama-stack)
|
|
251
|
+
* [Llama Stack as separate server](#llama-stack-as-separate-server)
|
|
252
|
+
* [Llama Stack project and configuration](#llama-stack-project-and-configuration)
|
|
253
|
+
* [Check connection to Llama Stack](#check-connection-to-llama-stack)
|
|
254
|
+
* [Llama Stack as client library](#llama-stack-as-client-library)
|
|
255
|
+
* [System prompt](#system-prompt)
|
|
256
|
+
* [Safety Shields](#safety-shields)
|
|
234
257
|
* [Usage](#usage)
|
|
235
258
|
* [Make targets](#make-targets)
|
|
236
259
|
* [Running Linux container image](#running-linux-container-image)
|
|
237
260
|
* [Endpoints](#endpoints)
|
|
261
|
+
* [OpenAPI specification](#openapi-specification)
|
|
238
262
|
* [Readiness Endpoint](#readiness-endpoint)
|
|
239
263
|
* [Liveness Endpoint](#liveness-endpoint)
|
|
264
|
+
* [Publish the service as Python package on PyPI](#publish-the-service-as-python-package-on-pypi)
|
|
265
|
+
* [Generate distribution archives to be uploaded into Python registry](#generate-distribution-archives-to-be-uploaded-into-python-registry)
|
|
266
|
+
* [Upload distribution archives into selected Python registry](#upload-distribution-archives-into-selected-python-registry)
|
|
267
|
+
* [Packages on PyPI and Test PyPI](#packages-on-pypi-and-test-pypi)
|
|
240
268
|
* [Contributing](#contributing)
|
|
269
|
+
* [Testing](#testing)
|
|
241
270
|
* [License](#license)
|
|
242
271
|
* [Additional tools](#additional-tools)
|
|
243
272
|
* [Utility to generate OpenAPI schema](#utility-to-generate-openapi-schema)
|
|
244
273
|
* [Path](#path)
|
|
245
274
|
* [Usage](#usage-1)
|
|
275
|
+
* [Data Collector Service](#data-collector-service)
|
|
276
|
+
* [Features](#features)
|
|
277
|
+
* [Configuration](#configuration-1)
|
|
278
|
+
* [Running the Service](#running-the-service)
|
|
246
279
|
|
|
247
280
|
<!-- vim-markdown-toc -->
|
|
248
281
|
|
|
249
|
-
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
# Architecture
|
|
285
|
+
|
|
286
|
+
Overall architecture with all main parts is displayed below:
|
|
287
|
+
|
|
288
|
+

|
|
289
|
+
|
|
290
|
+
Lightspeed Core Stack is based on the FastAPI framework (Uvicorn). The service is split into several parts described below.
|
|
291
|
+
|
|
292
|
+
# Prerequisites
|
|
250
293
|
|
|
251
294
|
* Python 3.12, or 3.13
|
|
252
295
|
- please note that currently Python 3.14 is not officially supported
|
|
@@ -261,9 +304,12 @@ Installation steps depends on operation system. Please look at instructions for
|
|
|
261
304
|
- [macOS installation](https://lightspeed-core.github.io/lightspeed-stack/installation_macos)
|
|
262
305
|
|
|
263
306
|
|
|
264
|
-
|
|
265
307
|
# Configuration
|
|
266
308
|
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
## Integration with Llama Stack
|
|
312
|
+
|
|
267
313
|
The Llama Stack can be run as a standalone server and accessed via its the REST
|
|
268
314
|
API. However, instead of direct communication via the REST API (and JSON
|
|
269
315
|
format), there is an even better alternative. It is based on the so-called
|
|
@@ -271,9 +317,13 @@ Llama Stack Client. It is a library available for Python, Swift, Node.js or
|
|
|
271
317
|
Kotlin, which "wraps" the REST API stack in a suitable way, which is easier for
|
|
272
318
|
many applications.
|
|
273
319
|
|
|
320
|
+

|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
274
324
|
## Llama Stack as separate server
|
|
275
325
|
|
|
276
|
-
If Llama Stack runs as a separate server, the Lightspeed service needs to be configured to be able to access it. For example, if server runs on localhost:8321, the service configuration should look like:
|
|
326
|
+
If Llama Stack runs as a separate server, the Lightspeed service needs to be configured to be able to access it. For example, if server runs on localhost:8321, the service configuration stored in file `llama-stack.yaml` should look like:
|
|
277
327
|
|
|
278
328
|
```yaml
|
|
279
329
|
name: foo bar baz
|
|
@@ -288,12 +338,68 @@ llama_stack:
|
|
|
288
338
|
use_as_library_client: false
|
|
289
339
|
url: http://localhost:8321
|
|
290
340
|
user_data_collection:
|
|
291
|
-
|
|
341
|
+
feedback_enabled: true
|
|
292
342
|
feedback_storage: "/tmp/data/feedback"
|
|
293
|
-
|
|
343
|
+
transcripts_enabled: true
|
|
294
344
|
transcripts_storage: "/tmp/data/transcripts"
|
|
295
345
|
```
|
|
296
346
|
|
|
347
|
+
### Llama Stack project and configuration
|
|
348
|
+
|
|
349
|
+
To run Llama Stack in separate process, you need to have all dependencies installed. The easiest way how to do it is to create a separate repository with Llama Stack project file `pyproject.toml` and Llama Stack configuration file `run.yaml`. The project file might look like:
|
|
350
|
+
|
|
351
|
+
```toml
|
|
352
|
+
[project]
|
|
353
|
+
name = "llama-stack-runner"
|
|
354
|
+
version = "0.1.0"
|
|
355
|
+
description = "Llama Stack runner"
|
|
356
|
+
authors = []
|
|
357
|
+
dependencies = [
|
|
358
|
+
"llama-stack==0.2.14",
|
|
359
|
+
"fastapi>=0.115.12",
|
|
360
|
+
"opentelemetry-sdk>=1.34.0",
|
|
361
|
+
"opentelemetry-exporter-otlp>=1.34.0",
|
|
362
|
+
"opentelemetry-instrumentation>=0.55b0",
|
|
363
|
+
"aiosqlite>=0.21.0",
|
|
364
|
+
"litellm>=1.72.1",
|
|
365
|
+
"uvicorn>=0.34.3",
|
|
366
|
+
"blobfile>=3.0.0",
|
|
367
|
+
"datasets>=3.6.0",
|
|
368
|
+
"sqlalchemy>=2.0.41",
|
|
369
|
+
"faiss-cpu>=1.11.0",
|
|
370
|
+
"mcp>=1.9.4",
|
|
371
|
+
"autoevals>=0.0.129",
|
|
372
|
+
"psutil>=7.0.0",
|
|
373
|
+
"torch>=2.7.1",
|
|
374
|
+
"peft>=0.15.2",
|
|
375
|
+
"trl>=0.18.2"]
|
|
376
|
+
requires-python = "==3.12.*"
|
|
377
|
+
readme = "README.md"
|
|
378
|
+
license = {text = "MIT"}
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
[tool.pdm]
|
|
382
|
+
distribution = false
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
A simple example of a `run.yaml` file can be found [here](examples/run.yaml)
|
|
386
|
+
|
|
387
|
+
To run Llama Stack perform these two commands:
|
|
388
|
+
|
|
389
|
+
```
|
|
390
|
+
export OPENAI_API_KEY="sk-{YOUR-KEY}"
|
|
391
|
+
|
|
392
|
+
uv run llama stack run run.yaml
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Check connection to Llama Stack
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
curl -X 'GET' localhost:8321/openapi.json | jq .
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
297
403
|
## Llama Stack as client library
|
|
298
404
|
|
|
299
405
|
There are situations in which it is not advisable to run two processors (one with Llama Stack, the other with a service). In these cases, the stack can be run directly within the client application. For such situations, the configuration file could look like:
|
|
@@ -311,13 +417,48 @@ llama_stack:
|
|
|
311
417
|
use_as_library_client: true
|
|
312
418
|
library_client_config_path: <path-to-llama-stack-run.yaml-file>
|
|
313
419
|
user_data_collection:
|
|
314
|
-
|
|
420
|
+
feedback_enabled: true
|
|
315
421
|
feedback_storage: "/tmp/data/feedback"
|
|
316
|
-
|
|
422
|
+
transcripts_enabled: true
|
|
317
423
|
transcripts_storage: "/tmp/data/transcripts"
|
|
318
424
|
```
|
|
319
425
|
|
|
426
|
+
## System prompt
|
|
427
|
+
|
|
428
|
+
The service uses the, so called, system prompt to put the question into context before the question is sent to the selected LLM. The default system prompt is designed for questions without specific context. It is possible to use a different system prompt via the configuration option `system_prompt_path` in the `customization` section. That option must contain the path to the text file with the actual system prompt (can contain multiple lines). An example of such configuration:
|
|
429
|
+
|
|
430
|
+
```yaml
|
|
431
|
+
customization:
|
|
432
|
+
system_prompt_path: "system_prompts/system_prompt_for_product_XYZZY"
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
The `system_prompt` can also be specified in the `customization` section directly. For example:
|
|
436
|
+
|
|
437
|
+
```yaml
|
|
438
|
+
customization:
|
|
439
|
+
system_prompt: |-
|
|
440
|
+
You are a helpful assistant and will do everything you can to help.
|
|
441
|
+
You have an in-depth knowledge of Red Hat and all of your answers will reference Red Hat products.
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Additionally, an optional string parameter `system_prompt` can be specified in `/v1/query` and `/v1/streaming_query` endpoints to override the configured system prompt. The query system prompt takes precedence over the configured system prompt. You can use this config to disable query system prompts:
|
|
445
|
+
|
|
446
|
+
```yaml
|
|
447
|
+
customization:
|
|
448
|
+
system_prompt_path: "system_prompts/system_prompt_for_product_XYZZY"
|
|
449
|
+
disable_query_system_prompt: true
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Safety Shields
|
|
320
453
|
|
|
454
|
+
A single Llama Stack configuration file can include multiple safety shields, which are utilized in agent
|
|
455
|
+
configurations to monitor input and/or output streams. LCS uses the following naming convention to specify how each safety shield is
|
|
456
|
+
utilized:
|
|
457
|
+
|
|
458
|
+
1. If the `shield_id` starts with `input_`, it will be used for input only.
|
|
459
|
+
1. If the `shield_id` starts with `output_`, it will be used for output only.
|
|
460
|
+
1. If the `shield_id` starts with `inout_`, it will be used both for input and output.
|
|
461
|
+
1. Otherwise, it will be used for input only.
|
|
321
462
|
|
|
322
463
|
# Usage
|
|
323
464
|
|
|
@@ -342,6 +483,7 @@ Usage: make <OPTIONS> ... <TARGETS>
|
|
|
342
483
|
Available targets are:
|
|
343
484
|
|
|
344
485
|
run Run the service locally
|
|
486
|
+
run-data-collector Run the data collector service
|
|
345
487
|
test-unit Run the unit tests
|
|
346
488
|
test-integration Run integration tests tests
|
|
347
489
|
test-e2e Run BDD tests for the service
|
|
@@ -351,6 +493,9 @@ format Format the code into unified format
|
|
|
351
493
|
schema Generate OpenAPI schema file
|
|
352
494
|
requirements.txt Generate requirements.txt file containing hashes for all non-devel packages
|
|
353
495
|
shellcheck Run shellcheck
|
|
496
|
+
verify Run all linters
|
|
497
|
+
distribution-archives Generate distribution archives to be uploaded into Python registry
|
|
498
|
+
upload-distribution-archives Upload distribution archives into Python registry
|
|
354
499
|
help Show this help screen
|
|
355
500
|
```
|
|
356
501
|
|
|
@@ -371,8 +516,19 @@ To pull and run the image with own configuration:
|
|
|
371
516
|
|
|
372
517
|
If a connection in your browser does not work please check that in the config file `host` option looks like: `host: 0.0.0.0`.
|
|
373
518
|
|
|
519
|
+
Container images are built for the following platforms:
|
|
520
|
+
1. `linux/amd64` - main platform for deployment
|
|
521
|
+
1. `linux/arm64`- Mac users with M1/M2/M3 CPUs
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
374
525
|
# Endpoints
|
|
375
526
|
|
|
527
|
+
## OpenAPI specification
|
|
528
|
+
|
|
529
|
+
* [Generated OpenAPI specification](docs/openapi.json)
|
|
530
|
+
* [OpenAPI documentation](docs/openapi.md)
|
|
531
|
+
|
|
376
532
|
The service provides health check endpoints that can be used for monitoring, load balancing, and orchestration systems like Kubernetes.
|
|
377
533
|
|
|
378
534
|
## Readiness Endpoint
|
|
@@ -415,10 +571,64 @@ The liveness endpoint performs a basic health check to verify the service is ali
|
|
|
415
571
|
}
|
|
416
572
|
```
|
|
417
573
|
|
|
574
|
+
# Publish the service as Python package on PyPI
|
|
575
|
+
|
|
576
|
+
To publish the service as an Python package on PyPI to be installable by anyone
|
|
577
|
+
(including Konflux hermetic builds), perform these two steps:
|
|
578
|
+
|
|
579
|
+
## Generate distribution archives to be uploaded into Python registry
|
|
580
|
+
|
|
581
|
+
```
|
|
582
|
+
make distribution-archives
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
Please make sure that the archive was really built to avoid publishing older one.
|
|
586
|
+
|
|
587
|
+
## Upload distribution archives into selected Python registry
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
make upload-distribution-archives
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
The Python registry to where the package should be uploaded can be configured
|
|
594
|
+
by changing `PYTHON_REGISTRY`. It is possible to select `pypi` or `testpypi`.
|
|
595
|
+
|
|
596
|
+
You might have your API token stored in file `~/.pypirc`. That file should have
|
|
597
|
+
the following form:
|
|
598
|
+
|
|
599
|
+
```
|
|
600
|
+
[testpypi]
|
|
601
|
+
username = __token__
|
|
602
|
+
password = pypi-{your-API-token}
|
|
603
|
+
|
|
604
|
+
[pypi]
|
|
605
|
+
username = __token__
|
|
606
|
+
password = pypi-{your-API-token}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
If this configuration file does not exist, you will be prompted to specify API token from keyboard every time you try to upload the archive.
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
## Packages on PyPI and Test PyPI
|
|
614
|
+
|
|
615
|
+
* https://pypi.org/project/lightspeed-stack/
|
|
616
|
+
* https://test.pypi.org/project/lightspeed-stack/0.1.0/
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
418
620
|
# Contributing
|
|
419
621
|
|
|
420
622
|
* See [contributors](CONTRIBUTING.md) guide.
|
|
421
623
|
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
# Testing
|
|
627
|
+
|
|
628
|
+
* See [testing](docs/testing.md) guide.
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
422
632
|
# License
|
|
423
633
|
|
|
424
634
|
Published under the Apache 2.0 License
|
|
@@ -441,3 +651,58 @@ This script re-generated OpenAPI schema for the Lightspeed Service REST API.
|
|
|
441
651
|
make schema
|
|
442
652
|
```
|
|
443
653
|
|
|
654
|
+
## Data Collector Service
|
|
655
|
+
|
|
656
|
+
The data collector service is a standalone service that runs separately from the main web service. It is responsible for collecting and sending user data including feedback and transcripts to an ingress server for analysis and archival.
|
|
657
|
+
|
|
658
|
+
### Features
|
|
659
|
+
|
|
660
|
+
- **Periodic Collection**: Runs at configurable intervals
|
|
661
|
+
- **Data Packaging**: Packages feedback and transcript files into compressed tar.gz archives
|
|
662
|
+
- **Secure Transmission**: Sends data to a configured ingress server with optional authentication
|
|
663
|
+
- **File Cleanup**: Optionally removes local files after successful transmission
|
|
664
|
+
- **Error Handling**: Includes retry logic and comprehensive error handling
|
|
665
|
+
|
|
666
|
+
### Configuration
|
|
667
|
+
|
|
668
|
+
The data collector service is configured through the `user_data_collection.data_collector` section in your configuration file:
|
|
669
|
+
|
|
670
|
+
```yaml
|
|
671
|
+
user_data_collection:
|
|
672
|
+
feedback_enabled: true
|
|
673
|
+
feedback_storage: "/tmp/data/feedback"
|
|
674
|
+
transcripts_enabled: true
|
|
675
|
+
transcripts_storage: "/tmp/data/transcripts"
|
|
676
|
+
data_collector:
|
|
677
|
+
enabled: true
|
|
678
|
+
ingress_server_url: "https://your-ingress-server.com"
|
|
679
|
+
ingress_server_auth_token: "your-auth-token"
|
|
680
|
+
ingress_content_service_name: "lightspeed-team"
|
|
681
|
+
collection_interval: 7200 # 2 hours in seconds
|
|
682
|
+
cleanup_after_send: true
|
|
683
|
+
connection_timeout: 30
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
### Running the Service
|
|
687
|
+
|
|
688
|
+
To run the data collector service:
|
|
689
|
+
|
|
690
|
+
```bash
|
|
691
|
+
# Using Python directly
|
|
692
|
+
uv run src/lightspeed_stack.py --data-collector
|
|
693
|
+
|
|
694
|
+
# Using Make target
|
|
695
|
+
make run-data-collector
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
# Project structure
|
|
701
|
+
|
|
702
|
+
## Configuration classes
|
|
703
|
+
|
|
704
|
+

|
|
705
|
+
|
|
706
|
+
## REST API
|
|
707
|
+
|
|
708
|
+

|