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

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

|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
274
316
|
## Llama Stack as separate server
|
|
275
317
|
|
|
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:
|
|
318
|
+
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
319
|
|
|
278
320
|
```yaml
|
|
279
321
|
name: foo bar baz
|
|
@@ -288,12 +330,68 @@ llama_stack:
|
|
|
288
330
|
use_as_library_client: false
|
|
289
331
|
url: http://localhost:8321
|
|
290
332
|
user_data_collection:
|
|
291
|
-
|
|
333
|
+
feedback_enabled: true
|
|
292
334
|
feedback_storage: "/tmp/data/feedback"
|
|
293
|
-
|
|
335
|
+
transcripts_enabled: true
|
|
294
336
|
transcripts_storage: "/tmp/data/transcripts"
|
|
295
337
|
```
|
|
296
338
|
|
|
339
|
+
### Llama Stack project and configuration
|
|
340
|
+
|
|
341
|
+
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:
|
|
342
|
+
|
|
343
|
+
```toml
|
|
344
|
+
[project]
|
|
345
|
+
name = "llama-stack-runner"
|
|
346
|
+
version = "0.1.0"
|
|
347
|
+
description = "Llama Stack runner"
|
|
348
|
+
authors = []
|
|
349
|
+
dependencies = [
|
|
350
|
+
"llama-stack==0.2.14",
|
|
351
|
+
"fastapi>=0.115.12",
|
|
352
|
+
"opentelemetry-sdk>=1.34.0",
|
|
353
|
+
"opentelemetry-exporter-otlp>=1.34.0",
|
|
354
|
+
"opentelemetry-instrumentation>=0.55b0",
|
|
355
|
+
"aiosqlite>=0.21.0",
|
|
356
|
+
"litellm>=1.72.1",
|
|
357
|
+
"uvicorn>=0.34.3",
|
|
358
|
+
"blobfile>=3.0.0",
|
|
359
|
+
"datasets>=3.6.0",
|
|
360
|
+
"sqlalchemy>=2.0.41",
|
|
361
|
+
"faiss-cpu>=1.11.0",
|
|
362
|
+
"mcp>=1.9.4",
|
|
363
|
+
"autoevals>=0.0.129",
|
|
364
|
+
"psutil>=7.0.0",
|
|
365
|
+
"torch>=2.7.1",
|
|
366
|
+
"peft>=0.15.2",
|
|
367
|
+
"trl>=0.18.2"]
|
|
368
|
+
requires-python = "==3.12.*"
|
|
369
|
+
readme = "README.md"
|
|
370
|
+
license = {text = "MIT"}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
[tool.pdm]
|
|
374
|
+
distribution = false
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
A simple example of a `run.yaml` file can be found [here](examples/run.yaml)
|
|
378
|
+
|
|
379
|
+
To run Llama Stack perform these two commands:
|
|
380
|
+
|
|
381
|
+
```
|
|
382
|
+
export OPENAI_API_KEY="sk-{YOUR-KEY}"
|
|
383
|
+
|
|
384
|
+
uv run llama stack run run.yaml
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Check connection to Llama Stack
|
|
388
|
+
|
|
389
|
+
```
|
|
390
|
+
curl -X 'GET' localhost:8321/openapi.json | jq .
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
297
395
|
## Llama Stack as client library
|
|
298
396
|
|
|
299
397
|
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 +409,48 @@ llama_stack:
|
|
|
311
409
|
use_as_library_client: true
|
|
312
410
|
library_client_config_path: <path-to-llama-stack-run.yaml-file>
|
|
313
411
|
user_data_collection:
|
|
314
|
-
|
|
412
|
+
feedback_enabled: true
|
|
315
413
|
feedback_storage: "/tmp/data/feedback"
|
|
316
|
-
|
|
414
|
+
transcripts_enabled: true
|
|
317
415
|
transcripts_storage: "/tmp/data/transcripts"
|
|
318
416
|
```
|
|
319
417
|
|
|
418
|
+
## System prompt
|
|
419
|
+
|
|
420
|
+
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:
|
|
421
|
+
|
|
422
|
+
```yaml
|
|
423
|
+
customization:
|
|
424
|
+
system_prompt_path: "system_prompts/system_prompt_for_product_XYZZY"
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
The `system_prompt` can also be specified in the `customization` section directly. For example:
|
|
428
|
+
|
|
429
|
+
```yaml
|
|
430
|
+
customization:
|
|
431
|
+
system_prompt: |-
|
|
432
|
+
You are a helpful assistant and will do everything you can to help.
|
|
433
|
+
You have an in-depth knowledge of Red Hat and all of your answers will reference Red Hat products.
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
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:
|
|
437
|
+
|
|
438
|
+
```yaml
|
|
439
|
+
customization:
|
|
440
|
+
system_prompt_path: "system_prompts/system_prompt_for_product_XYZZY"
|
|
441
|
+
disable_query_system_prompt: true
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## Safety Shields
|
|
320
445
|
|
|
446
|
+
A single Llama Stack configuration file can include multiple safety shields, which are utilized in agent
|
|
447
|
+
configurations to monitor input and/or output streams. LCS uses the following naming convention to specify how each safety shield is
|
|
448
|
+
utilized:
|
|
449
|
+
|
|
450
|
+
1. If the `shield_id` starts with `input_`, it will be used for input only.
|
|
451
|
+
1. If the `shield_id` starts with `output_`, it will be used for output only.
|
|
452
|
+
1. If the `shield_id` starts with `inout_`, it will be used both for input and output.
|
|
453
|
+
1. Otherwise, it will be used for input only.
|
|
321
454
|
|
|
322
455
|
# Usage
|
|
323
456
|
|
|
@@ -342,6 +475,7 @@ Usage: make <OPTIONS> ... <TARGETS>
|
|
|
342
475
|
Available targets are:
|
|
343
476
|
|
|
344
477
|
run Run the service locally
|
|
478
|
+
run-data-collector Run the data collector service
|
|
345
479
|
test-unit Run the unit tests
|
|
346
480
|
test-integration Run integration tests tests
|
|
347
481
|
test-e2e Run BDD tests for the service
|
|
@@ -351,6 +485,9 @@ format Format the code into unified format
|
|
|
351
485
|
schema Generate OpenAPI schema file
|
|
352
486
|
requirements.txt Generate requirements.txt file containing hashes for all non-devel packages
|
|
353
487
|
shellcheck Run shellcheck
|
|
488
|
+
verify Run all linters
|
|
489
|
+
distribution-archives Generate distribution archives to be uploaded into Python registry
|
|
490
|
+
upload-distribution-archives Upload distribution archives into Python registry
|
|
354
491
|
help Show this help screen
|
|
355
492
|
```
|
|
356
493
|
|
|
@@ -371,8 +508,19 @@ To pull and run the image with own configuration:
|
|
|
371
508
|
|
|
372
509
|
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
510
|
|
|
511
|
+
Container images are built for the following platforms:
|
|
512
|
+
1. `linux/amd64` - main platform for deployment
|
|
513
|
+
1. `linux/arm64`- Mac users with M1/M2/M3 CPUs
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
374
517
|
# Endpoints
|
|
375
518
|
|
|
519
|
+
## OpenAPI specification
|
|
520
|
+
|
|
521
|
+
* [Generated OpenAPI specification](docs/openapi.json)
|
|
522
|
+
* [OpenAPI documentation](docs/openapi.md)
|
|
523
|
+
|
|
376
524
|
The service provides health check endpoints that can be used for monitoring, load balancing, and orchestration systems like Kubernetes.
|
|
377
525
|
|
|
378
526
|
## Readiness Endpoint
|
|
@@ -415,10 +563,64 @@ The liveness endpoint performs a basic health check to verify the service is ali
|
|
|
415
563
|
}
|
|
416
564
|
```
|
|
417
565
|
|
|
566
|
+
# Publish the service as Python package on PyPI
|
|
567
|
+
|
|
568
|
+
To publish the service as an Python package on PyPI to be installable by anyone
|
|
569
|
+
(including Konflux hermetic builds), perform these two steps:
|
|
570
|
+
|
|
571
|
+
## Generate distribution archives to be uploaded into Python registry
|
|
572
|
+
|
|
573
|
+
```
|
|
574
|
+
make distribution-archives
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Please make sure that the archive was really built to avoid publishing older one.
|
|
578
|
+
|
|
579
|
+
## Upload distribution archives into selected Python registry
|
|
580
|
+
|
|
581
|
+
```
|
|
582
|
+
make upload-distribution-archives
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
The Python registry to where the package should be uploaded can be configured
|
|
586
|
+
by changing `PYTHON_REGISTRY`. It is possible to select `pypi` or `testpypi`.
|
|
587
|
+
|
|
588
|
+
You might have your API token stored in file `~/.pypirc`. That file should have
|
|
589
|
+
the following form:
|
|
590
|
+
|
|
591
|
+
```
|
|
592
|
+
[testpypi]
|
|
593
|
+
username = __token__
|
|
594
|
+
password = pypi-{your-API-token}
|
|
595
|
+
|
|
596
|
+
[pypi]
|
|
597
|
+
username = __token__
|
|
598
|
+
password = pypi-{your-API-token}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
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.
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
## Packages on PyPI and Test PyPI
|
|
606
|
+
|
|
607
|
+
* https://pypi.org/project/lightspeed-stack/
|
|
608
|
+
* https://test.pypi.org/project/lightspeed-stack/0.1.0/
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
|
|
418
612
|
# Contributing
|
|
419
613
|
|
|
420
614
|
* See [contributors](CONTRIBUTING.md) guide.
|
|
421
615
|
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
# Testing
|
|
619
|
+
|
|
620
|
+
* See [testing](docs/testing.md) guide.
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
422
624
|
# License
|
|
423
625
|
|
|
424
626
|
Published under the Apache 2.0 License
|
|
@@ -441,3 +643,58 @@ This script re-generated OpenAPI schema for the Lightspeed Service REST API.
|
|
|
441
643
|
make schema
|
|
442
644
|
```
|
|
443
645
|
|
|
646
|
+
## Data Collector Service
|
|
647
|
+
|
|
648
|
+
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.
|
|
649
|
+
|
|
650
|
+
### Features
|
|
651
|
+
|
|
652
|
+
- **Periodic Collection**: Runs at configurable intervals
|
|
653
|
+
- **Data Packaging**: Packages feedback and transcript files into compressed tar.gz archives
|
|
654
|
+
- **Secure Transmission**: Sends data to a configured ingress server with optional authentication
|
|
655
|
+
- **File Cleanup**: Optionally removes local files after successful transmission
|
|
656
|
+
- **Error Handling**: Includes retry logic and comprehensive error handling
|
|
657
|
+
|
|
658
|
+
### Configuration
|
|
659
|
+
|
|
660
|
+
The data collector service is configured through the `user_data_collection.data_collector` section in your configuration file:
|
|
661
|
+
|
|
662
|
+
```yaml
|
|
663
|
+
user_data_collection:
|
|
664
|
+
feedback_enabled: true
|
|
665
|
+
feedback_storage: "/tmp/data/feedback"
|
|
666
|
+
transcripts_enabled: true
|
|
667
|
+
transcripts_storage: "/tmp/data/transcripts"
|
|
668
|
+
data_collector:
|
|
669
|
+
enabled: true
|
|
670
|
+
ingress_server_url: "https://your-ingress-server.com"
|
|
671
|
+
ingress_server_auth_token: "your-auth-token"
|
|
672
|
+
ingress_content_service_name: "lightspeed-team"
|
|
673
|
+
collection_interval: 7200 # 2 hours in seconds
|
|
674
|
+
cleanup_after_send: true
|
|
675
|
+
connection_timeout: 30
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### Running the Service
|
|
679
|
+
|
|
680
|
+
To run the data collector service:
|
|
681
|
+
|
|
682
|
+
```bash
|
|
683
|
+
# Using Python directly
|
|
684
|
+
uv run src/lightspeed_stack.py --data-collector
|
|
685
|
+
|
|
686
|
+
# Using Make target
|
|
687
|
+
make run-data-collector
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
# Project structure
|
|
693
|
+
|
|
694
|
+
## Configuration classes
|
|
695
|
+
|
|
696
|
+

|
|
697
|
+
|
|
698
|
+
## REST API
|
|
699
|
+
|
|
700
|
+

|