lightspeed-stack 0.2.0__tar.gz → 0.4.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.
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/PKG-INFO +612 -153
- lightspeed_stack-0.4.0/README.md +1214 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/pyproject.toml +45 -16
- lightspeed_stack-0.4.0/src/a2a_storage/README.md +20 -0
- lightspeed_stack-0.4.0/src/a2a_storage/__init__.py +23 -0
- lightspeed_stack-0.4.0/src/a2a_storage/context_store.py +58 -0
- lightspeed_stack-0.4.0/src/a2a_storage/in_memory_context_store.py +93 -0
- lightspeed_stack-0.4.0/src/a2a_storage/postgres_context_store.py +143 -0
- lightspeed_stack-0.4.0/src/a2a_storage/sqlite_context_store.py +144 -0
- lightspeed_stack-0.4.0/src/a2a_storage/storage_factory.py +185 -0
- lightspeed_stack-0.4.0/src/app/README.md +14 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/database.py +21 -10
- lightspeed_stack-0.4.0/src/app/endpoints/README.md +68 -0
- lightspeed_stack-0.4.0/src/app/endpoints/a2a.py +882 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/endpoints/authorized.py +14 -20
- lightspeed_stack-0.4.0/src/app/endpoints/config.py +59 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/endpoints/conversations.py +165 -181
- lightspeed_stack-0.4.0/src/app/endpoints/conversations_v2.py +258 -0
- lightspeed_stack-0.4.0/src/app/endpoints/conversations_v3.py +633 -0
- lightspeed_stack-0.4.0/src/app/endpoints/feedback.py +233 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/endpoints/health.py +50 -32
- lightspeed_stack-0.4.0/src/app/endpoints/info.py +76 -0
- lightspeed_stack-0.4.0/src/app/endpoints/metrics.py +64 -0
- lightspeed_stack-0.4.0/src/app/endpoints/models.py +82 -0
- lightspeed_stack-0.4.0/src/app/endpoints/providers.py +160 -0
- lightspeed_stack-0.4.0/src/app/endpoints/query.py +912 -0
- lightspeed_stack-0.4.0/src/app/endpoints/query_v2.py +895 -0
- lightspeed_stack-0.4.0/src/app/endpoints/rags.py +154 -0
- lightspeed_stack-0.4.0/src/app/endpoints/rlsapi_v1.py +224 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/endpoints/root.py +36 -5
- lightspeed_stack-0.4.0/src/app/endpoints/shields.py +82 -0
- lightspeed_stack-0.4.0/src/app/endpoints/streaming_query.py +1155 -0
- lightspeed_stack-0.4.0/src/app/endpoints/streaming_query_v2.py +478 -0
- lightspeed_stack-0.4.0/src/app/endpoints/tools.py +145 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/main.py +74 -17
- lightspeed_stack-0.4.0/src/app/routers.py +65 -0
- lightspeed_stack-0.4.0/src/authentication/README.md +29 -0
- lightspeed_stack-0.4.0/src/authentication/__init__.py +84 -0
- lightspeed_stack-0.4.0/src/authentication/api_key_token.py +74 -0
- lightspeed_stack-0.4.0/src/authentication/interface.py +48 -0
- lightspeed_stack-0.4.0/src/authentication/jwk_token.py +249 -0
- {lightspeed_stack-0.2.0/src/auth → lightspeed_stack-0.4.0/src/authentication}/k8s.py +136 -55
- {lightspeed_stack-0.2.0/src/auth → lightspeed_stack-0.4.0/src/authentication}/noop.py +23 -11
- lightspeed_stack-0.4.0/src/authentication/noop_with_token.py +67 -0
- lightspeed_stack-0.4.0/src/authentication/rh_identity.py +250 -0
- lightspeed_stack-0.4.0/src/authentication/utils.py +31 -0
- lightspeed_stack-0.4.0/src/authorization/README.md +11 -0
- lightspeed_stack-0.4.0/src/authorization/__init__.py +1 -0
- lightspeed_stack-0.4.0/src/authorization/azure_token_manager.py +102 -0
- lightspeed_stack-0.4.0/src/authorization/middleware.py +191 -0
- lightspeed_stack-0.4.0/src/authorization/resolvers.py +357 -0
- lightspeed_stack-0.4.0/src/cache/README.md +26 -0
- lightspeed_stack-0.4.0/src/cache/__init__.py +1 -0
- lightspeed_stack-0.4.0/src/cache/cache.py +165 -0
- lightspeed_stack-0.4.0/src/cache/cache_error.py +5 -0
- lightspeed_stack-0.4.0/src/cache/cache_factory.py +54 -0
- lightspeed_stack-0.4.0/src/cache/in_memory_cache.py +163 -0
- lightspeed_stack-0.4.0/src/cache/noop_cache.py +143 -0
- lightspeed_stack-0.4.0/src/cache/postgres_cache.py +547 -0
- lightspeed_stack-0.4.0/src/cache/sqlite_cache.py +523 -0
- lightspeed_stack-0.4.0/src/metrics/README.md +8 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/metrics/__init__.py +1 -1
- lightspeed_stack-0.4.0/src/metrics/utils.py +100 -0
- lightspeed_stack-0.4.0/src/models/README.md +20 -0
- lightspeed_stack-0.4.0/src/models/cache_entry.py +30 -0
- lightspeed_stack-0.4.0/src/models/config.py +1713 -0
- lightspeed_stack-0.4.0/src/models/context.py +48 -0
- lightspeed_stack-0.4.0/src/models/database/README.md +11 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/models/database/conversations.py +2 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/models/requests.py +185 -27
- lightspeed_stack-0.4.0/src/models/responses.py +2082 -0
- lightspeed_stack-0.4.0/src/models/rlsapi/README.md +11 -0
- lightspeed_stack-0.4.0/src/models/rlsapi/__init__.py +1 -0
- lightspeed_stack-0.4.0/src/models/rlsapi/requests.py +200 -0
- lightspeed_stack-0.4.0/src/models/rlsapi/responses.py +54 -0
- lightspeed_stack-0.4.0/src/quota/README.md +35 -0
- lightspeed_stack-0.4.0/src/quota/__init__.py +18 -0
- lightspeed_stack-0.4.0/src/quota/cluster_quota_limiter.py +47 -0
- lightspeed_stack-0.4.0/src/quota/connect_pg.py +49 -0
- lightspeed_stack-0.4.0/src/quota/connect_sqlite.py +37 -0
- lightspeed_stack-0.4.0/src/quota/quota_exceed_error.py +53 -0
- lightspeed_stack-0.4.0/src/quota/quota_limiter.py +186 -0
- lightspeed_stack-0.4.0/src/quota/quota_limiter_factory.py +89 -0
- lightspeed_stack-0.4.0/src/quota/revokable_quota_limiter.py +360 -0
- lightspeed_stack-0.4.0/src/quota/sql.py +147 -0
- lightspeed_stack-0.4.0/src/quota/token_usage_history.py +201 -0
- lightspeed_stack-0.4.0/src/quota/user_quota_limiter.py +49 -0
- lightspeed_stack-0.4.0/src/runners/README.md +11 -0
- lightspeed_stack-0.4.0/src/runners/quota_scheduler.py +384 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/runners/uvicorn.py +11 -3
- lightspeed_stack-0.4.0/src/utils/README.md +47 -0
- lightspeed_stack-0.4.0/src/utils/__init__.py +1 -0
- lightspeed_stack-0.4.0/src/utils/checks.py +146 -0
- lightspeed_stack-0.4.0/src/utils/common.py +139 -0
- lightspeed_stack-0.4.0/src/utils/connection_decorator.py +48 -0
- lightspeed_stack-0.4.0/src/utils/endpoints.py +828 -0
- lightspeed_stack-0.4.0/src/utils/llama_stack_version.py +100 -0
- lightspeed_stack-0.4.0/src/utils/mcp_auth_headers.py +87 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/utils/mcp_headers.py +5 -3
- lightspeed_stack-0.4.0/src/utils/query.py +122 -0
- lightspeed_stack-0.4.0/src/utils/quota.py +108 -0
- lightspeed_stack-0.4.0/src/utils/responses.py +56 -0
- lightspeed_stack-0.4.0/src/utils/shields.py +157 -0
- lightspeed_stack-0.4.0/src/utils/suid.py +101 -0
- lightspeed_stack-0.4.0/src/utils/token_counter.py +136 -0
- lightspeed_stack-0.4.0/src/utils/tool_formatter.py +133 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/utils/transcripts.py +45 -9
- lightspeed_stack-0.4.0/src/utils/types.py +263 -0
- lightspeed_stack-0.4.0/tests/configuration/lightspeed-stack-proper-name.yaml +44 -0
- lightspeed_stack-0.4.0/tests/configuration/minimal-stack.yaml +30 -0
- lightspeed_stack-0.4.0/tests/configuration/multiline_system_prompt.txt +14 -0
- lightspeed_stack-0.4.0/tests/configuration/rag.txt +0 -0
- lightspeed_stack-0.4.0/tests/configuration/rh-identity-config.yaml +17 -0
- lightspeed_stack-0.4.0/tests/configuration/system_prompt.txt +1 -0
- lightspeed_stack-0.4.0/tests/e2e/README.md +11 -0
- lightspeed_stack-0.4.0/tests/e2e/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/e2e/configs/README.md +2 -0
- lightspeed_stack-0.4.0/tests/e2e/configs/run-azure.yaml +161 -0
- lightspeed_stack-0.4.0/tests/e2e/configs/run-ci.yaml +169 -0
- lightspeed_stack-0.4.0/tests/e2e/configs/run-rhaiis.yaml +162 -0
- lightspeed_stack-0.4.0/tests/e2e/configs/run-rhelai.yaml +162 -0
- lightspeed_stack-0.4.0/tests/e2e/configs/run-vertexai.yaml +157 -0
- lightspeed_stack-0.4.0/tests/e2e/configs/run-watsonx.yaml +168 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/README.md +2 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/library-mode/README.md +2 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/library-mode/lightspeed-stack-auth-noop-token.yaml +25 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/library-mode/lightspeed-stack-invalid-feedback-storage.yaml +19 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/library-mode/lightspeed-stack-no-cache.yaml +21 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/library-mode/lightspeed-stack.yaml +19 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/server-mode/README.md +2 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/server-mode/lightspeed-stack-auth-noop-token.yaml +31 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/server-mode/lightspeed-stack-invalid-feedback-storage.yaml +25 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/server-mode/lightspeed-stack-no-cache.yaml +27 -0
- lightspeed_stack-0.4.0/tests/e2e/configuration/server-mode/lightspeed-stack.yaml +20 -0
- lightspeed_stack-0.4.0/tests/e2e/features/README.md +5 -0
- lightspeed_stack-0.4.0/tests/e2e/features/authorized_noop.feature +56 -0
- lightspeed_stack-0.4.0/tests/e2e/features/authorized_noop_token.feature +82 -0
- lightspeed_stack-0.4.0/tests/e2e/features/conversation_cache_v2.feature +401 -0
- lightspeed_stack-0.4.0/tests/e2e/features/conversations.feature +197 -0
- lightspeed_stack-0.4.0/tests/e2e/features/environment.py +267 -0
- lightspeed_stack-0.4.0/tests/e2e/features/faiss.feature +55 -0
- lightspeed_stack-0.4.0/tests/e2e/features/feedback.feature +359 -0
- lightspeed_stack-0.4.0/tests/e2e/features/health.feature +64 -0
- lightspeed_stack-0.4.0/tests/e2e/features/info.feature +129 -0
- lightspeed_stack-0.4.0/tests/e2e/features/query.feature +175 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/e2e/features/rest_api.feature +0 -2
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/e2e/features/smoketests.feature +0 -2
- lightspeed_stack-0.4.0/tests/e2e/features/steps/README.md +29 -0
- lightspeed_stack-0.4.0/tests/e2e/features/steps/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/e2e/features/steps/auth.py +75 -0
- lightspeed_stack-0.4.0/tests/e2e/features/steps/common.py +38 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/e2e/features/steps/common_http.py +94 -10
- lightspeed_stack-0.4.0/tests/e2e/features/steps/conversation.py +355 -0
- lightspeed_stack-0.4.0/tests/e2e/features/steps/feedback.py +147 -0
- lightspeed_stack-0.4.0/tests/e2e/features/steps/health.py +65 -0
- lightspeed_stack-0.4.0/tests/e2e/features/steps/info.py +180 -0
- lightspeed_stack-0.4.0/tests/e2e/features/steps/llm_query_response.py +199 -0
- lightspeed_stack-0.4.0/tests/e2e/features/streaming_query.feature +147 -0
- lightspeed_stack-0.4.0/tests/e2e/rag/kv_store.db +0 -0
- lightspeed_stack-0.4.0/tests/e2e/test_api.py +1 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/e2e/test_list.txt +4 -1
- lightspeed_stack-0.4.0/tests/e2e/utils/README.md +5 -0
- lightspeed_stack-0.4.0/tests/e2e/utils/utils.py +257 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/configs/lightspeed-stack.yaml +25 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/configs/run.yaml +162 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/gpu/cluster-policy.yaml +31 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/gpu/create-nfd.yaml +8 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/lightspeed/lightspeed-stack.yaml +25 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/lightspeed/llama-stack.yaml +36 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/namespaces/nfd.yaml +5 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/namespaces/nvidia-operator.yaml +5 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/operators/ds-cluster.yaml +17 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/operators/operatorgroup.yaml +26 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/operators/operators.yaml +60 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/test-pod/spin-up.yaml +30 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/vllm/vllm-inference-service-cpu.yaml +13 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/vllm/vllm-inference-service-gpu.yaml +25 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/vllm/vllm-runtime-cpu.yaml +65 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/manifests/vllm/vllm-runtime-gpu.yaml +82 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/pipeline-services.sh +25 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/pipeline-test-pod.sh +5 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/pipeline-vllm.sh +11 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/pipeline.sh +270 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/run-tests.sh +17 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/scripts/bootstrap.sh +96 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/scripts/deploy-vllm.sh +78 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/scripts/fetch-vllm-image.sh +36 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/scripts/get-vllm-pod-info.sh +133 -0
- lightspeed_stack-0.4.0/tests/e2e-prow/rhoai/scripts/gpu-setup.sh +208 -0
- lightspeed_stack-0.4.0/tests/integration/README.md +23 -0
- lightspeed_stack-0.4.0/tests/integration/conftest.py +159 -0
- lightspeed_stack-0.4.0/tests/integration/endpoints/README.md +20 -0
- lightspeed_stack-0.4.0/tests/integration/endpoints/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/integration/endpoints/test_config_integration.py +86 -0
- lightspeed_stack-0.4.0/tests/integration/endpoints/test_health_integration.py +182 -0
- lightspeed_stack-0.4.0/tests/integration/endpoints/test_info_integration.py +151 -0
- lightspeed_stack-0.4.0/tests/integration/endpoints/test_query_v2_integration.py +1396 -0
- lightspeed_stack-0.4.0/tests/integration/endpoints/test_rlsapi_v1_integration.py +328 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/integration/test_configuration.py +15 -2
- lightspeed_stack-0.4.0/tests/integration/test_middleware_integration.py +34 -0
- lightspeed_stack-0.4.0/tests/integration/test_openapi_json.py +361 -0
- lightspeed_stack-0.4.0/tests/integration/test_rh_identity_integration.py +140 -0
- lightspeed_stack-0.4.0/tests/integration/test_version.py +46 -0
- lightspeed_stack-0.4.0/tests/profiles/test/profile.py +60 -0
- lightspeed_stack-0.4.0/tests/profiles/test_three/profile.py +49 -0
- lightspeed_stack-0.4.0/tests/profiles/test_two/test.txt +1 -0
- lightspeed_stack-0.4.0/tests/unit/README.md +26 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/__init__.py +2 -1
- lightspeed_stack-0.4.0/tests/unit/a2a_storage/README.md +14 -0
- lightspeed_stack-0.4.0/tests/unit/a2a_storage/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/a2a_storage/test_in_memory_context_store.py +95 -0
- lightspeed_stack-0.4.0/tests/unit/a2a_storage/test_sqlite_context_store.py +147 -0
- lightspeed_stack-0.4.0/tests/unit/a2a_storage/test_storage_factory.py +172 -0
- lightspeed_stack-0.4.0/tests/unit/app/README.md +14 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/README.md +65 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_a2a.py +887 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_authorized.py +86 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_config.py +72 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_conversations.py +1548 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_conversations_v2.py +875 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_feedback.py +417 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/app/endpoints/test_health.py +62 -22
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_info.py +147 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/app/endpoints/test_metrics.py +16 -4
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/app/endpoints/test_models.py +81 -70
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_providers.py +202 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_query.py +2557 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_query_v2.py +1005 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_rags.py +246 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_rlsapi_v1.py +329 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_root.py +24 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_shields.py +383 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_streaming_query.py +2468 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_streaming_query_v2.py +627 -0
- lightspeed_stack-0.4.0/tests/unit/app/endpoints/test_tools.py +630 -0
- lightspeed_stack-0.4.0/tests/unit/app/test_database.py +402 -0
- lightspeed_stack-0.4.0/tests/unit/app/test_main_middleware.py +74 -0
- lightspeed_stack-0.4.0/tests/unit/app/test_routers.py +166 -0
- lightspeed_stack-0.4.0/tests/unit/authentication/README.md +29 -0
- lightspeed_stack-0.4.0/tests/unit/authentication/test_api_key_token.py +133 -0
- {lightspeed_stack-0.2.0/tests/unit/auth → lightspeed_stack-0.4.0/tests/unit/authentication}/test_auth.py +6 -6
- lightspeed_stack-0.4.0/tests/unit/authentication/test_jwk_token.py +862 -0
- lightspeed_stack-0.4.0/tests/unit/authentication/test_k8s.py +583 -0
- {lightspeed_stack-0.2.0/tests/unit/auth → lightspeed_stack-0.4.0/tests/unit/authentication}/test_noop.py +8 -6
- {lightspeed_stack-0.2.0/tests/unit/auth → lightspeed_stack-0.4.0/tests/unit/authentication}/test_noop_with_token.py +30 -15
- lightspeed_stack-0.4.0/tests/unit/authentication/test_rh_identity.py +403 -0
- lightspeed_stack-0.4.0/tests/unit/authentication/test_utils.py +42 -0
- lightspeed_stack-0.4.0/tests/unit/authorization/README.md +11 -0
- lightspeed_stack-0.4.0/tests/unit/authorization/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/authorization/test_azure_token_manager.py +155 -0
- lightspeed_stack-0.4.0/tests/unit/authorization/test_middleware.py +369 -0
- lightspeed_stack-0.4.0/tests/unit/authorization/test_resolvers.py +438 -0
- lightspeed_stack-0.4.0/tests/unit/cache/README.md +17 -0
- lightspeed_stack-0.4.0/tests/unit/cache/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/cache/test_cache_factory.py +242 -0
- lightspeed_stack-0.4.0/tests/unit/cache/test_noop_cache.py +232 -0
- lightspeed_stack-0.4.0/tests/unit/cache/test_postgres_cache.py +838 -0
- lightspeed_stack-0.4.0/tests/unit/cache/test_sqlite_cache.py +573 -0
- lightspeed_stack-0.4.0/tests/unit/conftest.py +74 -0
- lightspeed_stack-0.4.0/tests/unit/metrics/README.md +8 -0
- lightspeed_stack-0.4.0/tests/unit/metrics/test_utis.py +134 -0
- lightspeed_stack-0.4.0/tests/unit/models/README.md +5 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/README.md +62 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_a2a_state_configuration.py +103 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_authentication_configuration.py +464 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_byok_rag.py +144 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_conversation_history.py +259 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_cors.py +104 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_customization.py +82 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_database_configuration.py +85 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_dump_configuration.py +1127 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_inference_configuration.py +52 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_jwt_role_rule.py +151 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_llama_stack_configuration.py +78 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_model_context_protocol_server.py +305 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_postgresql_database_configuration.py +113 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_quota_handlers_config.py +20 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_quota_limiter_config.py +79 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_quota_scheduler_config.py +72 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_service_configuration.py +39 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_tls_configuration.py +104 -0
- lightspeed_stack-0.4.0/tests/unit/models/config/test_user_data_collection.py +75 -0
- lightspeed_stack-0.4.0/tests/unit/models/requests/README.md +17 -0
- lightspeed_stack-0.4.0/tests/unit/models/requests/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/models/requests/test_attachment.py +30 -0
- lightspeed_stack-0.2.0/tests/unit/models/test_requests.py → lightspeed_stack-0.4.0/tests/unit/models/requests/test_feedback_request.py +16 -175
- lightspeed_stack-0.4.0/tests/unit/models/requests/test_feedback_status_update_request.py +23 -0
- lightspeed_stack-0.4.0/tests/unit/models/requests/test_query_request.py +184 -0
- lightspeed_stack-0.4.0/tests/unit/models/responses/README.md +20 -0
- lightspeed_stack-0.4.0/tests/unit/models/responses/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/models/responses/test_authorized_response.py +46 -0
- lightspeed_stack-0.4.0/tests/unit/models/responses/test_error_responses.py +760 -0
- lightspeed_stack-0.4.0/tests/unit/models/responses/test_query_response.py +86 -0
- lightspeed_stack-0.4.0/tests/unit/models/responses/test_rag_chunk.py +112 -0
- lightspeed_stack-0.4.0/tests/unit/models/responses/test_successful_responses.py +1022 -0
- lightspeed_stack-0.4.0/tests/unit/models/rlsapi/README.md +11 -0
- lightspeed_stack-0.4.0/tests/unit/models/rlsapi/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/models/rlsapi/test_requests.py +464 -0
- lightspeed_stack-0.4.0/tests/unit/models/rlsapi/test_responses.py +158 -0
- lightspeed_stack-0.4.0/tests/unit/quota/README.md +23 -0
- lightspeed_stack-0.4.0/tests/unit/quota/__init__.py +1 -0
- lightspeed_stack-0.4.0/tests/unit/quota/test_cluster_quota_limiter.py +173 -0
- lightspeed_stack-0.4.0/tests/unit/quota/test_connect_pg.py +45 -0
- lightspeed_stack-0.4.0/tests/unit/quota/test_connect_sqlite.py +26 -0
- lightspeed_stack-0.4.0/tests/unit/quota/test_quota_exceed_error.py +32 -0
- lightspeed_stack-0.4.0/tests/unit/quota/test_quota_limiter_factory.py +226 -0
- lightspeed_stack-0.4.0/tests/unit/quota/test_user_quota_limiter.py +171 -0
- lightspeed_stack-0.4.0/tests/unit/runners/README.md +8 -0
- lightspeed_stack-0.4.0/tests/unit/runners/test_uvicorn_runner.py +102 -0
- lightspeed_stack-0.4.0/tests/unit/test_client.py +152 -0
- lightspeed_stack-0.4.0/tests/unit/test_configuration.py +853 -0
- lightspeed_stack-0.4.0/tests/unit/test_configuration_unknown_fields.py +12 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/test_lightspeed_stack.py +1 -1
- lightspeed_stack-0.4.0/tests/unit/test_llama_stack_configuration.py +182 -0
- lightspeed_stack-0.4.0/tests/unit/utils/README.md +41 -0
- lightspeed_stack-0.4.0/tests/unit/utils/auth_helpers.py +26 -0
- lightspeed_stack-0.4.0/tests/unit/utils/test_checks.py +173 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/utils/test_common.py +35 -27
- lightspeed_stack-0.4.0/tests/unit/utils/test_connection_decorator.py +58 -0
- lightspeed_stack-0.4.0/tests/unit/utils/test_endpoints.py +1143 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/utils/test_llama_stack_version.py +28 -5
- lightspeed_stack-0.4.0/tests/unit/utils/test_mcp_auth_headers.py +116 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/utils/test_mcp_headers.py +37 -29
- lightspeed_stack-0.4.0/tests/unit/utils/test_responses.py +260 -0
- lightspeed_stack-0.4.0/tests/unit/utils/test_shields.py +344 -0
- lightspeed_stack-0.4.0/tests/unit/utils/test_suid.py +77 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/utils/test_transcripts.py +40 -13
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/utils/test_types.py +14 -10
- lightspeed_stack-0.2.0/README.md +0 -766
- lightspeed_stack-0.2.0/src/app/endpoints/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.2.0/src/app/endpoints/.ruff_cache/0.9.1/9961612457335986079 +0 -0
- lightspeed_stack-0.2.0/src/app/endpoints/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.2.0/src/app/endpoints/config.py +0 -72
- lightspeed_stack-0.2.0/src/app/endpoints/feedback.py +0 -173
- lightspeed_stack-0.2.0/src/app/endpoints/info.py +0 -35
- lightspeed_stack-0.2.0/src/app/endpoints/metrics.py +0 -30
- lightspeed_stack-0.2.0/src/app/endpoints/models.py +0 -92
- lightspeed_stack-0.2.0/src/app/endpoints/query.py +0 -581
- lightspeed_stack-0.2.0/src/app/endpoints/streaming_query.py +0 -773
- lightspeed_stack-0.2.0/src/app/routers.py +0 -38
- lightspeed_stack-0.2.0/src/auth/__init__.py +0 -43
- lightspeed_stack-0.2.0/src/auth/interface.py +0 -19
- lightspeed_stack-0.2.0/src/auth/jwk_token.py +0 -191
- lightspeed_stack-0.2.0/src/auth/noop_with_token.py +0 -46
- lightspeed_stack-0.2.0/src/auth/utils.py +0 -26
- lightspeed_stack-0.2.0/src/metrics/utils.py +0 -50
- lightspeed_stack-0.2.0/src/models/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.2.0/src/models/.ruff_cache/0.9.1/2435063725374233068 +0 -0
- lightspeed_stack-0.2.0/src/models/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.2.0/src/models/config.py +0 -319
- lightspeed_stack-0.2.0/src/models/responses.py +0 -566
- lightspeed_stack-0.2.0/src/services/__init__.py +0 -1
- lightspeed_stack-0.2.0/src/utils/__init__.py +0 -1
- lightspeed_stack-0.2.0/src/utils/checks.py +0 -27
- lightspeed_stack-0.2.0/src/utils/common.py +0 -77
- lightspeed_stack-0.2.0/src/utils/endpoints.py +0 -127
- lightspeed_stack-0.2.0/src/utils/llama_stack_version.py +0 -51
- lightspeed_stack-0.2.0/src/utils/suid.py +0 -28
- lightspeed_stack-0.2.0/src/utils/types.py +0 -78
- lightspeed_stack-0.2.0/tests/configuration/minimal-stack.yaml +0 -6
- lightspeed_stack-0.2.0/tests/e2e/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.2.0/tests/e2e/.ruff_cache/0.9.1/6949908709306621198 +0 -0
- lightspeed_stack-0.2.0/tests/e2e/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.2.0/tests/e2e/__init__.py +0 -1
- lightspeed_stack-0.2.0/tests/e2e/features/authorized.feature +0 -34
- lightspeed_stack-0.2.0/tests/e2e/features/conversations.feature +0 -54
- lightspeed_stack-0.2.0/tests/e2e/features/environment.py +0 -38
- lightspeed_stack-0.2.0/tests/e2e/features/feedback.feature +0 -90
- lightspeed_stack-0.2.0/tests/e2e/features/health.feature +0 -53
- lightspeed_stack-0.2.0/tests/e2e/features/info.feature +0 -46
- lightspeed_stack-0.2.0/tests/e2e/features/query.feature +0 -60
- lightspeed_stack-0.2.0/tests/e2e/features/steps/__init__.py +0 -1
- lightspeed_stack-0.2.0/tests/e2e/features/steps/auth.py +0 -25
- lightspeed_stack-0.2.0/tests/e2e/features/steps/common.py +0 -16
- lightspeed_stack-0.2.0/tests/e2e/features/steps/conversation.py +0 -18
- lightspeed_stack-0.2.0/tests/e2e/features/steps/feedback.py +0 -38
- lightspeed_stack-0.2.0/tests/e2e/features/steps/health.py +0 -18
- lightspeed_stack-0.2.0/tests/e2e/features/steps/info.py +0 -22
- lightspeed_stack-0.2.0/tests/e2e/features/steps/llm_query_response.py +0 -80
- lightspeed_stack-0.2.0/tests/e2e/features/streaming_query.feature +0 -39
- lightspeed_stack-0.2.0/tests/e2e/test_api.py +0 -1
- lightspeed_stack-0.2.0/tests/e2e/utils/utils.py +0 -28
- lightspeed_stack-0.2.0/tests/integration/test_version.py +0 -27
- lightspeed_stack-0.2.0/tests/test_results/.coverage.integration +0 -0
- lightspeed_stack-0.2.0/tests/test_results/.coverage.unit +0 -0
- lightspeed_stack-0.2.0/tests/test_results/coverage_integration.json +0 -1
- lightspeed_stack-0.2.0/tests/test_results/coverage_unit.json +0 -1
- lightspeed_stack-0.2.0/tests/test_results/junit_integration.xml +0 -1
- lightspeed_stack-0.2.0/tests/test_results/junit_unit.xml +0 -1
- lightspeed_stack-0.2.0/tests/unit/app/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.2.0/tests/unit/app/.ruff_cache/0.9.1/10631576872848856737 +0 -0
- lightspeed_stack-0.2.0/tests/unit/app/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/.ruff_cache/0.9.1/15310180828563549007 +0 -0
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_authorized.py +0 -61
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_config.py +0 -63
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_conversations.py +0 -599
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_feedback.py +0 -198
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_info.py +0 -41
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_query.py +0 -1473
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_root.py +0 -16
- lightspeed_stack-0.2.0/tests/unit/app/endpoints/test_streaming_query.py +0 -1517
- lightspeed_stack-0.2.0/tests/unit/app/test_routers.py +0 -94
- lightspeed_stack-0.2.0/tests/unit/auth/test_jwk_token.py +0 -540
- lightspeed_stack-0.2.0/tests/unit/auth/test_k8s.py +0 -246
- lightspeed_stack-0.2.0/tests/unit/auth/test_utils.py +0 -33
- lightspeed_stack-0.2.0/tests/unit/conftest.py +0 -28
- lightspeed_stack-0.2.0/tests/unit/metrics/test_utis.py +0 -76
- lightspeed_stack-0.2.0/tests/unit/models/test_config.py +0 -932
- lightspeed_stack-0.2.0/tests/unit/models/test_responses.py +0 -86
- lightspeed_stack-0.2.0/tests/unit/runners/test_uvicorn_runner.py +0 -102
- lightspeed_stack-0.2.0/tests/unit/test_client.py +0 -73
- lightspeed_stack-0.2.0/tests/unit/test_configuration.py +0 -437
- lightspeed_stack-0.2.0/tests/unit/utils/.ruff_cache/.gitignore +0 -2
- lightspeed_stack-0.2.0/tests/unit/utils/.ruff_cache/0.9.1/8897072278360683352 +0 -0
- lightspeed_stack-0.2.0/tests/unit/utils/.ruff_cache/CACHEDIR.TAG +0 -1
- lightspeed_stack-0.2.0/tests/unit/utils/test_checks.py +0 -80
- lightspeed_stack-0.2.0/tests/unit/utils/test_endpoints.py +0 -593
- lightspeed_stack-0.2.0/tests/unit/utils/test_suid.py +0 -27
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/LICENSE +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/app/endpoints/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/models/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/models/database/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/models/database/base.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/src/runners/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/configuration/lightspeed-stack.yaml +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/configuration/password +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/configuration/run.yaml +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/configuration/server.crt +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/configuration/server.key +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/e2e/.pdm-python +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/e2e/gen_scenario_list.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/integration/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/app/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/app/endpoints/__init__.py +0 -0
- {lightspeed_stack-0.2.0/tests/unit/auth → lightspeed_stack-0.4.0/tests/unit/authentication}/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/metrics/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/models/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/runners/__init__.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/tests/unit/test_log.py +0 -0
- {lightspeed_stack-0.2.0 → lightspeed_stack-0.4.0}/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.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: LLM tooling stack
|
|
5
5
|
Keywords: LLM,RAG
|
|
6
6
|
Maintainer-Email: =?utf-8?b?UGF2ZWwgVGnFoW5vdnNrw70=?= <tisnik@centrum.cz>
|
|
@@ -218,18 +218,29 @@ Requires-Python: <3.14,>=3.12
|
|
|
218
218
|
Requires-Dist: fastapi>=0.115.12
|
|
219
219
|
Requires-Dist: uvicorn>=0.34.3
|
|
220
220
|
Requires-Dist: kubernetes>=30.1.0
|
|
221
|
-
Requires-Dist: llama-stack==0.
|
|
222
|
-
Requires-Dist: llama-stack-client==0.
|
|
221
|
+
Requires-Dist: llama-stack==0.3.5
|
|
222
|
+
Requires-Dist: llama-stack-client==0.3.5
|
|
223
223
|
Requires-Dist: rich>=14.0.0
|
|
224
224
|
Requires-Dist: cachetools>=6.1.0
|
|
225
225
|
Requires-Dist: prometheus-client>=0.22.1
|
|
226
226
|
Requires-Dist: starlette>=0.47.1
|
|
227
227
|
Requires-Dist: aiohttp>=3.12.14
|
|
228
228
|
Requires-Dist: authlib>=1.6.0
|
|
229
|
+
Requires-Dist: a2a-sdk<0.4.0,>=0.3.4
|
|
229
230
|
Requires-Dist: email-validator>=2.2.0
|
|
230
|
-
Requires-Dist: openai
|
|
231
|
-
Requires-Dist: sqlalchemy>=2.0.42
|
|
231
|
+
Requires-Dist: openai>=1.99.9
|
|
232
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.42
|
|
233
|
+
Requires-Dist: aiosqlite>=0.21.0
|
|
234
|
+
Requires-Dist: asyncpg>=0.31.0
|
|
232
235
|
Requires-Dist: semver<4.0.0
|
|
236
|
+
Requires-Dist: jsonpath-ng>=1.6.1
|
|
237
|
+
Requires-Dist: psycopg2-binary>=2.9.10
|
|
238
|
+
Requires-Dist: litellm>=1.75.5.post1
|
|
239
|
+
Requires-Dist: urllib3==2.6.3
|
|
240
|
+
Requires-Dist: PyYAML>=6.0.0
|
|
241
|
+
Requires-Dist: einops>=0.8.1
|
|
242
|
+
Requires-Dist: azure-core>=1.38.0
|
|
243
|
+
Requires-Dist: azure-identity
|
|
233
244
|
Description-Content-Type: text/markdown
|
|
234
245
|
|
|
235
246
|
# lightspeed-stack
|
|
@@ -240,60 +251,103 @@ Description-Content-Type: text/markdown
|
|
|
240
251
|
[](https://github.com/lightspeed-core/lightspeed-stack/blob/main/LICENSE)
|
|
241
252
|
[](https://www.python.org/)
|
|
242
253
|
[](https://www.python.org/)
|
|
243
|
-
[](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.
|
|
254
|
+
[](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.4.0)
|
|
244
255
|
|
|
245
256
|
Lightspeed Core Stack (LCS) is an AI-powered assistant that provides answers to product questions using backend LLM services, agents, and RAG databases.
|
|
246
|
-
|
|
257
|
+
|
|
247
258
|
The service includes comprehensive user data collection capabilities for various types of user interaction data, which can be exported to Red Hat's Dataverse for analysis using the companion [lightspeed-to-dataverse-exporter](https://github.com/lightspeed-core/lightspeed-to-dataverse-exporter) service.
|
|
248
259
|
|
|
249
260
|
|
|
250
261
|
<!-- vim-markdown-toc GFM -->
|
|
251
262
|
|
|
263
|
+
* [lightspeed-stack](#lightspeed-stack)
|
|
264
|
+
* [About The Project](#about-the-project)
|
|
252
265
|
* [Architecture](#architecture)
|
|
253
266
|
* [Prerequisites](#prerequisites)
|
|
254
267
|
* [Installation](#installation)
|
|
268
|
+
* [Run LCS locally](#run-lcs-locally)
|
|
255
269
|
* [Configuration](#configuration)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
* [
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
* [
|
|
270
|
-
* [
|
|
271
|
-
* [
|
|
270
|
+
* [LLM Compatibility](#llm-compatibility)
|
|
271
|
+
* [Set LLM provider and model](#set-llm-provider-and-model)
|
|
272
|
+
* [Selecting provider and model](#selecting-provider-and-model)
|
|
273
|
+
* [Provider and model selection in REST API request](#provider-and-model-selection-in-rest-api-request)
|
|
274
|
+
* [Default provider and model](#default-provider-and-model)
|
|
275
|
+
* [Supported providers](#supported-providers)
|
|
276
|
+
* [Integration with Llama Stack](#integration-with-llama-stack)
|
|
277
|
+
* [Llama Stack as separate server](#llama-stack-as-separate-server)
|
|
278
|
+
* [MCP Server and Tool Configuration](#mcp-server-and-tool-configuration)
|
|
279
|
+
* [Configuring MCP Servers](#configuring-mcp-servers)
|
|
280
|
+
* [Configuring MCP Server Authentication](#configuring-mcp-server-authentication)
|
|
281
|
+
* [1. Static Tokens from Files (Recommended for Service Credentials)](#1-static-tokens-from-files-recommended-for-service-credentials)
|
|
282
|
+
* [2. Kubernetes Service Account Tokens (For K8s Deployments)](#2-kubernetes-service-account-tokens-for-k8s-deployments)
|
|
283
|
+
* [3. Client-Provided Tokens (For Per-User Authentication)](#3-client-provided-tokens-for-per-user-authentication)
|
|
284
|
+
* [Combining Authentication Methods](#combining-authentication-methods)
|
|
285
|
+
* [Authentication Method Comparison](#authentication-method-comparison)
|
|
286
|
+
* [Important: Automatic Server Skipping](#important-automatic-server-skipping)
|
|
287
|
+
* [Llama Stack project and configuration](#llama-stack-project-and-configuration)
|
|
288
|
+
* [Check connection to Llama Stack](#check-connection-to-llama-stack)
|
|
289
|
+
* [Llama Stack as client library](#llama-stack-as-client-library)
|
|
290
|
+
* [Llama Stack version check](#llama-stack-version-check)
|
|
291
|
+
* [User data collection](#user-data-collection)
|
|
292
|
+
* [System prompt](#system-prompt)
|
|
293
|
+
* [System Prompt Path](#system-prompt-path)
|
|
294
|
+
* [System Prompt Literal](#system-prompt-literal)
|
|
295
|
+
* [Custom Profile](#custom-profile)
|
|
296
|
+
* [Control model/provider overrides via authorization](#control-modelprovider-overrides-via-authorization)
|
|
297
|
+
* [Safety Shields](#safety-shields)
|
|
298
|
+
* [Authentication](#authentication)
|
|
299
|
+
* [CORS](#cors)
|
|
300
|
+
* [Default values](#default-values)
|
|
301
|
+
* [Allow credentials](#allow-credentials)
|
|
272
302
|
* [RAG Configuration](#rag-configuration)
|
|
303
|
+
* [Example configurations for inference](#example-configurations-for-inference)
|
|
273
304
|
* [Usage](#usage)
|
|
274
|
-
|
|
275
|
-
|
|
305
|
+
* [Make targets](#make-targets)
|
|
306
|
+
* [Running Linux container image](#running-linux-container-image)
|
|
307
|
+
* [Building Container Images](#building-container-images)
|
|
308
|
+
* [Llama-Stack as Separate Service (Server Mode)](#llama-stack-as-separate-service-server-mode)
|
|
309
|
+
* [macOS (arm64)](#macos-arm64)
|
|
310
|
+
* [Llama-Stack as Library (Library Mode)](#llama-stack-as-library-library-mode)
|
|
311
|
+
* [macOS](#macos)
|
|
312
|
+
* [Verify it's running properly](#verify-its-running-properly)
|
|
313
|
+
* [Custom Container Image](#custom-container-image)
|
|
276
314
|
* [Endpoints](#endpoints)
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
315
|
+
* [OpenAPI specification](#openapi-specification)
|
|
316
|
+
* [Readiness Endpoint](#readiness-endpoint)
|
|
317
|
+
* [Liveness Endpoint](#liveness-endpoint)
|
|
318
|
+
* [Database structure](#database-structure)
|
|
280
319
|
* [Publish the service as Python package on PyPI](#publish-the-service-as-python-package-on-pypi)
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
320
|
+
* [Generate distribution archives to be uploaded into Python registry](#generate-distribution-archives-to-be-uploaded-into-python-registry)
|
|
321
|
+
* [Upload distribution archives into selected Python registry](#upload-distribution-archives-into-selected-python-registry)
|
|
322
|
+
* [Packages on PyPI and Test PyPI](#packages-on-pypi-and-test-pypi)
|
|
284
323
|
* [Contributing](#contributing)
|
|
285
324
|
* [Testing](#testing)
|
|
286
325
|
* [License](#license)
|
|
287
326
|
* [Additional tools](#additional-tools)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
327
|
+
* [Utility to generate OpenAPI schema](#utility-to-generate-openapi-schema)
|
|
328
|
+
* [Path](#path)
|
|
329
|
+
* [Usage](#usage-1)
|
|
330
|
+
* [Makefile target to generate OpenAPI specification](#makefile-target-to-generate-openapi-specification)
|
|
331
|
+
* [Utility to generate documentation from source code](#utility-to-generate-documentation-from-source-code)
|
|
332
|
+
* [Path](#path-1)
|
|
333
|
+
* [Usage](#usage-2)
|
|
291
334
|
* [Data Export Integration](#data-export-integration)
|
|
292
|
-
|
|
293
|
-
|
|
335
|
+
* [Quick Integration](#quick-integration)
|
|
336
|
+
* [Documentation](#documentation)
|
|
294
337
|
* [Project structure](#project-structure)
|
|
295
|
-
|
|
296
|
-
|
|
338
|
+
* [Configuration classes](#configuration-classes)
|
|
339
|
+
* [REST API](#rest-api)
|
|
340
|
+
* [Sequence diagrams](#sequence-diagrams)
|
|
341
|
+
* [Query endpoint REST API handler](#query-endpoint-rest-api-handler)
|
|
342
|
+
* [Streaming query endpoint REST API handler](#streaming-query-endpoint-rest-api-handler)
|
|
343
|
+
* [Versioning](#versioning)
|
|
344
|
+
* [Development Tools](#development-tools)
|
|
345
|
+
* [MCP Mock Server](#mcp-mock-server)
|
|
346
|
+
* [Konflux](#konflux)
|
|
347
|
+
* [Updating Dependencies for Hermetic Builds](#updating-dependencies-for-hermetic-builds)
|
|
348
|
+
* [When to Update Dependency Files](#when-to-update-dependency-files)
|
|
349
|
+
* [Updating Python Dependencies](#updating-python-dependencies)
|
|
350
|
+
* [Updating RPM Dependencies](#updating-rpm-dependencies)
|
|
297
351
|
|
|
298
352
|
<!-- vim-markdown-toc -->
|
|
299
353
|
|
|
@@ -313,6 +367,33 @@ Lightspeed Core Stack is based on the FastAPI framework (Uvicorn). The service i
|
|
|
313
367
|
- please note that currently Python 3.14 is not officially supported
|
|
314
368
|
- all sources are made (backward) compatible with Python 3.12; it is checked on CI
|
|
315
369
|
|
|
370
|
+
* OpenAI API Key (Recommended for Getting Started)
|
|
371
|
+
|
|
372
|
+
Lightspeed Stack supports multiple LLM providers.
|
|
373
|
+
|
|
374
|
+
| Provider | Setup Documentation |
|
|
375
|
+
|----------------|-----------------------------------------------------------------------|
|
|
376
|
+
| OpenAI | https://platform.openai.com |
|
|
377
|
+
| Azure OpenAI | https://azure.microsoft.com/en-us/products/ai-services/openai-service |
|
|
378
|
+
| Google VertexAI| https://cloud.google.com/vertex-ai |
|
|
379
|
+
| IBM WatsonX | https://www.ibm.com/products/watsonx |
|
|
380
|
+
| RHOAI (vLLM) | See tests/e2e-prow/rhoai/configs/run.yaml |
|
|
381
|
+
| RHEL AI (vLLM) | See tests/e2e/configs/run-rhelai.yaml |
|
|
382
|
+
|
|
383
|
+
See `docs/providers.md` for configuration details.
|
|
384
|
+
|
|
385
|
+
You will need an API key from one of these providers to run LightSpeed Stack.
|
|
386
|
+
|
|
387
|
+
For example, if you choose to use OpenAI:
|
|
388
|
+
|
|
389
|
+
1. **Create an account** at [platform.openai.com](https://platform.openai.com)
|
|
390
|
+
2. **Add payment information** (new accounts receive free trial credits)
|
|
391
|
+
3. **Generate an API key** from your dashboard at [API Keys](https://platform.openai.com/api-keys)
|
|
392
|
+
4. **Export the key** in your environment:
|
|
393
|
+
```bash
|
|
394
|
+
export OPENAI_API_KEY="sk-your-api-key-here"
|
|
395
|
+
```
|
|
396
|
+
|
|
316
397
|
# Installation
|
|
317
398
|
|
|
318
399
|
Installation steps depends on operation system. Please look at instructions for your system:
|
|
@@ -321,11 +402,132 @@ Installation steps depends on operation system. Please look at instructions for
|
|
|
321
402
|
- [Linux installation](https://lightspeed-core.github.io/lightspeed-stack/installation_linux)
|
|
322
403
|
- [macOS installation](https://lightspeed-core.github.io/lightspeed-stack/installation_macos)
|
|
323
404
|
|
|
405
|
+
# Run LCS locally
|
|
406
|
+
|
|
407
|
+
To quickly get hands on LCS, we can run it using the default configurations provided in this repository:
|
|
408
|
+
|
|
409
|
+
0. install dependencies using [uv](https://docs.astral.sh/uv/getting-started/installation/)
|
|
410
|
+
```bash
|
|
411
|
+
uv sync --group dev --group llslibdev
|
|
412
|
+
```
|
|
413
|
+
1. create llama stack `run.yaml`. you can do this by running the local run generation script
|
|
414
|
+
```bash
|
|
415
|
+
./scripts/generate_local_run.sh
|
|
416
|
+
```
|
|
417
|
+
2. export the LLM token environment variable that Llama stack requires. for OpenAI, we set the env var by
|
|
418
|
+
```bash
|
|
419
|
+
export OPENAI_API_KEY=sk-xxxxx
|
|
420
|
+
```
|
|
421
|
+
3. start Llama stack server
|
|
422
|
+
```bash
|
|
423
|
+
uv run llama stack run local-run.yaml
|
|
424
|
+
```
|
|
425
|
+
4. [Optional] If you're new to Llama stack, run through a quick tutorial to learn the basics of what the server is used for, by running the interactive tutorial script
|
|
426
|
+
```bash
|
|
427
|
+
./scripts/llama_stack_tutorial.sh
|
|
428
|
+
```
|
|
429
|
+
5. check the LCS settings in [lightspeed-stack.yaml](lightspeed-stack.yaml). `llama_stack.url` should be `url: http://localhost:8321`
|
|
430
|
+
6. start LCS server
|
|
431
|
+
```
|
|
432
|
+
make run
|
|
433
|
+
```
|
|
434
|
+
7. access LCS web UI at [http://localhost:8080/](http://localhost:8080/)
|
|
435
|
+
|
|
324
436
|
|
|
325
437
|
# Configuration
|
|
326
438
|
|
|
439
|
+
## LLM Compatibility
|
|
440
|
+
|
|
441
|
+
Lightspeed Core Stack (LCS) provides support for Large Language Model providers. The models listed in the table below represent specific examples that have been tested within LCS.
|
|
442
|
+
__Note__: Support for individual models is dependent on the specific inference provider's implementation within the currently supported version of Llama Stack.
|
|
443
|
+
|
|
444
|
+
| Provider | Model | Tool Calling | provider_type | Example |
|
|
445
|
+
| -------- | ---------------------------------------------- | ------------ | -------------- | -------------------------------------------------------------------------- |
|
|
446
|
+
| OpenAI | gpt-5, gpt-4o, gpt4-turbo, gpt-4.1, o1, o3, o4 | Yes | remote::openai | [1](examples/openai-faiss-run.yaml) [2](examples/openai-pgvector-run.yaml) |
|
|
447
|
+
| OpenAI | gpt-3.5-turbo, gpt-4 | No | remote::openai | |
|
|
448
|
+
| RHOAI (vLLM)| meta-llama/Llama-3.2-1B-Instruct | Yes | remote::vllm | [1](tests/e2e-prow/rhoai/configs/run.yaml) |
|
|
449
|
+
| RHAIIS (vLLM)| meta-llama/Llama-3.1-8B-Instruct | Yes | remote::vllm | [1](tests/e2e/configs/run-rhaiis.yaml) |
|
|
450
|
+
| RHEL AI (vLLM)| meta-llama/Llama-3.1-8B-Instruct | Yes | remote::vllm | [1](tests/e2e/configs/run-rhelai.yaml) |
|
|
451
|
+
| Azure | gpt-5, gpt-5-mini, gpt-5-nano, gpt-4o-mini, o3-mini, o4-mini, o1| Yes | remote::azure | [1](examples/azure-run.yaml) |
|
|
452
|
+
| Azure | gpt-5-chat, gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, o1-mini | No or limited | remote::azure | |
|
|
453
|
+
| VertexAI | google/gemini-2.0-flash, google/gemini-2.5-flash, google/gemini-2.5-pro [^1] | Yes | remote::vertexai | [1](examples/vertexai-run.yaml) |
|
|
454
|
+
| WatsonX | meta-llama/llama-3-3-70b-instruct | Yes | remote::watsonx | [1](examples/watsonx-run.yaml) |
|
|
455
|
+
|
|
456
|
+
[^1]: List of models is limited by design in llama-stack, future versions will probably allow to use more models (see [here](https://github.com/llamastack/llama-stack/blob/release-0.3.x/llama_stack/providers/remote/inference/vertexai/vertexai.py#L54))
|
|
457
|
+
|
|
458
|
+
The "provider_type" is used in the llama stack configuration file when refering to the provider.
|
|
459
|
+
|
|
460
|
+
For details of OpenAI model capabilities, please refer to https://platform.openai.com/docs/models/compare
|
|
327
461
|
|
|
328
462
|
|
|
463
|
+
## Set LLM provider and model
|
|
464
|
+
|
|
465
|
+
The LLM provider and model are set in the configuration file for Llama Stack. This repository has a Llama stack configuration file [run.yaml](examples/run.yaml) that can serve as a good example.
|
|
466
|
+
|
|
467
|
+
The LLM providers are set in the section `providers.inference`. This example adds a inference provider "openai" to the llama stack. To use environment variables as configuration values, we can use the syntax `${env.ENV_VAR_NAME}`.
|
|
468
|
+
|
|
469
|
+
For more details, please refer to [llama stack documentation](https://llama-stack.readthedocs.io/en/latest/distributions/configuration.html#providers). Here is a list of llamastack supported providers and their configuration details: [llama stack providers](https://llama-stack.readthedocs.io/en/latest/providers/inference/index.html#providers)
|
|
470
|
+
|
|
471
|
+
```yaml
|
|
472
|
+
inference:
|
|
473
|
+
- provider_id: openai
|
|
474
|
+
provider_type: remote::openai
|
|
475
|
+
config:
|
|
476
|
+
api_key: ${env.OPENAI_API_KEY}
|
|
477
|
+
url: ${env.SERVICE_URL}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
The section `models` is a list of models offered by the inference provider. Attention that the field `model_id` is a user chosen name for referring to the model locally, the field `provider_model_id` refers to the model name on the provider side. The field `provider_id` must refer to one of the inference providers we defined in the provider list above.
|
|
481
|
+
|
|
482
|
+
```yaml
|
|
483
|
+
models:
|
|
484
|
+
- model_id: gpt-4-turbo
|
|
485
|
+
provider_id: openai
|
|
486
|
+
model_type: llm
|
|
487
|
+
provider_model_id: gpt-4-turbo
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## Selecting provider and model
|
|
491
|
+
|
|
492
|
+
It is possible to configure multiple LLM providers and models are configured. In this case it is needed to:
|
|
493
|
+
|
|
494
|
+
- select the provider + model in query request
|
|
495
|
+
- specify default model and provider in Lightspeed Core Stack configuration file
|
|
496
|
+
|
|
497
|
+
### Provider and model selection in REST API request
|
|
498
|
+
|
|
499
|
+
Provider and model can be specified in `/v1/query` and `/v1/streaming-query` REST API requests:
|
|
500
|
+
|
|
501
|
+
```json
|
|
502
|
+
{
|
|
503
|
+
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
|
|
504
|
+
"generate_topic_summary": true,
|
|
505
|
+
"provider": "openai",
|
|
506
|
+
"model": "gpt-5",
|
|
507
|
+
"no_tools": false,
|
|
508
|
+
"query": "write a deployment yaml for the mongodb image",
|
|
509
|
+
"system_prompt": "You are a helpful assistant"
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Default provider and model
|
|
514
|
+
|
|
515
|
+
It is possible to configure default provider and model in Lightspeed Core Stack configuration file, under the `inference` node:
|
|
516
|
+
|
|
517
|
+
```yaml
|
|
518
|
+
inference:
|
|
519
|
+
- default_provider: SELECTED PROVIDER
|
|
520
|
+
default_model: SELECTED MODEL
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
These settings will be used when no provider or model are specified in REST API request.
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
## Supported providers
|
|
528
|
+
|
|
529
|
+
For a comprehensive list of supported providers, take a look [here](docs/providers.md).
|
|
530
|
+
|
|
329
531
|
## Integration with Llama Stack
|
|
330
532
|
|
|
331
533
|
The Llama Stack can be run as a standalone server and accessed via its the REST
|
|
@@ -367,36 +569,145 @@ user_data_collection:
|
|
|
367
569
|
|
|
368
570
|
**Note**: The `run.yaml` configuration is currently an implementation detail. In the future, all configuration will be available directly from the lightspeed-core config.
|
|
369
571
|
|
|
572
|
+
**Important**: Only MCP servers defined in the `lightspeed-stack.yaml` configuration are available to the agents. Tools configured in the llama-stack `run.yaml` are not accessible to lightspeed-core agents.
|
|
573
|
+
|
|
370
574
|
#### Configuring MCP Servers
|
|
371
575
|
|
|
372
|
-
MCP (Model Context Protocol) servers provide tools and capabilities to the AI agents. These are configured in the `mcp_servers` section of your `lightspeed-stack.yaml
|
|
576
|
+
MCP (Model Context Protocol) servers provide tools and capabilities to the AI agents. These are configured in the `mcp_servers` section of your `lightspeed-stack.yaml`.
|
|
577
|
+
|
|
578
|
+
**Basic Configuration Structure:**
|
|
579
|
+
|
|
580
|
+
Each MCP server requires two fields:
|
|
581
|
+
- `name`: Unique identifier for the MCP server
|
|
582
|
+
- `url`: The endpoint where the MCP server is running
|
|
583
|
+
|
|
584
|
+
And one optional field:
|
|
585
|
+
- `provider_id`: MCP provider identification (defaults to `"model-context-protocol"`)
|
|
586
|
+
|
|
587
|
+
**Minimal Example:**
|
|
373
588
|
|
|
374
589
|
```yaml
|
|
375
590
|
mcp_servers:
|
|
376
591
|
- name: "filesystem-tools"
|
|
377
|
-
|
|
378
|
-
url: "http://localhost:3000"
|
|
592
|
+
url: "http://localhost:9000"
|
|
379
593
|
- name: "git-tools"
|
|
380
|
-
|
|
381
|
-
url: "http://localhost:3001"
|
|
382
|
-
- name: "database-tools"
|
|
383
|
-
provider_id: "model-context-protocol"
|
|
384
|
-
url: "http://localhost:3002"
|
|
594
|
+
url: "http://localhost:9001"
|
|
385
595
|
```
|
|
386
596
|
|
|
387
|
-
|
|
597
|
+
In addition to the basic configuration above, you can configure authentication headers for your MCP servers to securely communicate with services that require credentials.
|
|
598
|
+
|
|
599
|
+
#### Configuring MCP Server Authentication
|
|
600
|
+
|
|
601
|
+
Lightspeed Core Stack supports three methods for authenticating with MCP servers, each suited for different use cases:
|
|
602
|
+
|
|
603
|
+
##### 1. Static Tokens from Files (Recommended for Service Credentials)
|
|
604
|
+
|
|
605
|
+
Store authentication tokens in secret files and reference them in your configuration. This is ideal for API keys, service tokens, or any credentials that don't change per-user:
|
|
606
|
+
|
|
607
|
+
```yaml
|
|
608
|
+
mcp_servers:
|
|
609
|
+
- name: "api-service"
|
|
610
|
+
url: "http://api-service:8080"
|
|
611
|
+
authorization_headers:
|
|
612
|
+
Authorization: "/var/secrets/api-token" # Path to file containing token
|
|
613
|
+
X-API-Key: "/var/secrets/api-key" # Multiple headers supported
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
The secret files should contain only the header value (tokens are automatically stripped of whitespace):
|
|
617
|
+
|
|
618
|
+
```bash
|
|
619
|
+
# /var/secrets/api-token
|
|
620
|
+
Bearer sk-abc123def456...
|
|
621
|
+
|
|
622
|
+
# /var/secrets/api-key
|
|
623
|
+
my-api-key-value
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
##### 2. Kubernetes Service Account Tokens (For K8s Deployments)
|
|
627
|
+
|
|
628
|
+
Use the special `"kubernetes"` keyword to automatically use the authenticated user's Kubernetes token. This is perfect for MCP servers running in the same Kubernetes cluster:
|
|
629
|
+
|
|
630
|
+
```yaml
|
|
631
|
+
mcp_servers:
|
|
632
|
+
- name: "k8s-internal-service"
|
|
633
|
+
url: "http://internal-mcp.default.svc.cluster.local:8080"
|
|
634
|
+
authorization_headers:
|
|
635
|
+
Authorization: "kubernetes" # Uses user's k8s token from request auth
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
The user's Kubernetes token is extracted from the incoming request's `Authorization` header and forwarded to the MCP server.
|
|
388
639
|
|
|
389
|
-
|
|
640
|
+
##### 3. Client-Provided Tokens (For Per-User Authentication)
|
|
390
641
|
|
|
391
|
-
|
|
642
|
+
Use the special `"client"` keyword to allow clients to provide custom tokens per-request. This enables user-specific authentication:
|
|
643
|
+
|
|
644
|
+
```yaml
|
|
645
|
+
mcp_servers:
|
|
646
|
+
- name: "user-specific-service"
|
|
647
|
+
url: "http://user-service:8080"
|
|
648
|
+
authorization_headers:
|
|
649
|
+
Authorization: "client" # Token provided via MCP-HEADERS
|
|
650
|
+
X-User-Token: "client" # Multiple client headers supported
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
Clients then provide tokens via the `MCP-HEADERS` HTTP header:
|
|
392
654
|
|
|
393
655
|
```bash
|
|
394
656
|
curl -X POST "http://localhost:8080/v1/query" \
|
|
395
657
|
-H "Content-Type: application/json" \
|
|
396
|
-
-H "MCP-HEADERS: {\"
|
|
397
|
-
-d '{"query": "
|
|
658
|
+
-H "MCP-HEADERS: {\"user-specific-service\": {\"Authorization\": \"Bearer user-token-123\", \"X-User-Token\": \"custom-value\"}}" \
|
|
659
|
+
-d '{"query": "Get my data"}'
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
**Note**: `MCP-HEADERS` is an **HTTP request header** containing a JSON-encoded dictionary. The dictionary is keyed by **server name** (not URL), matching the `name` field in your MCP server configuration. Each server name maps to another dictionary containing the HTTP headers to forward to that specific MCP server.
|
|
663
|
+
|
|
664
|
+
**Structure**: `MCP-HEADERS: {"<server-name>": {"<header-name>": "<header-value>", ...}, ...}`
|
|
665
|
+
|
|
666
|
+
##### Combining Authentication Methods
|
|
667
|
+
|
|
668
|
+
You can mix and match authentication methods across different MCP servers, and even combine multiple methods for a single server:
|
|
669
|
+
|
|
670
|
+
```yaml
|
|
671
|
+
mcp_servers:
|
|
672
|
+
# Static credentials for public API
|
|
673
|
+
- name: "weather-api"
|
|
674
|
+
url: "http://weather-api:8080"
|
|
675
|
+
authorization_headers:
|
|
676
|
+
X-API-Key: "/var/secrets/weather-api-key"
|
|
677
|
+
|
|
678
|
+
# Kubernetes auth for internal services
|
|
679
|
+
- name: "internal-db"
|
|
680
|
+
url: "http://db-mcp.cluster.local:8080"
|
|
681
|
+
authorization_headers:
|
|
682
|
+
Authorization: "kubernetes"
|
|
683
|
+
|
|
684
|
+
# Mixed: static API key + per-user token
|
|
685
|
+
- name: "multi-tenant-service"
|
|
686
|
+
url: "http://multi-tenant:8080"
|
|
687
|
+
authorization_headers:
|
|
688
|
+
X-Service-Key: "/var/secrets/service-key" # Static service credential
|
|
689
|
+
Authorization: "client" # User-specific token
|
|
398
690
|
```
|
|
399
691
|
|
|
692
|
+
##### Authentication Method Comparison
|
|
693
|
+
|
|
694
|
+
| Method | Use Case | Configuration | Token Scope | Example |
|
|
695
|
+
|--------|----------|---------------|-------------|---------|
|
|
696
|
+
| **Static File** | Service tokens, API keys | File path in config | Global (all users) | `"/var/secrets/token"` |
|
|
697
|
+
| **Kubernetes** | K8s service accounts | `"kubernetes"` keyword | Per-user (from auth) | `"kubernetes"` |
|
|
698
|
+
| **Client** | User-specific tokens | `"client"` keyword + HTTP header | Per-request | `"client"` |
|
|
699
|
+
|
|
700
|
+
##### Important: Automatic Server Skipping
|
|
701
|
+
|
|
702
|
+
**If an MCP server has `authorization_headers` configured but the required tokens cannot be resolved at runtime, the server will be automatically skipped for that request.** This prevents failed authentication attempts to MCP servers.
|
|
703
|
+
|
|
704
|
+
**Examples:**
|
|
705
|
+
- A server with `Authorization: "kubernetes"` will be skipped if the user's request doesn't include a Kubernetes token
|
|
706
|
+
- A server with `Authorization: "client"` will be skipped if no `MCP-HEADERS` are provided in the request
|
|
707
|
+
- A server with multiple headers will be skipped if **any** required header cannot be resolved
|
|
708
|
+
|
|
709
|
+
Skipped servers are logged as warnings. Check Lightspeed Core logs to see which servers were skipped and why.
|
|
710
|
+
|
|
400
711
|
|
|
401
712
|
### Llama Stack project and configuration
|
|
402
713
|
|
|
@@ -411,7 +722,7 @@ version = "0.1.0"
|
|
|
411
722
|
description = "Llama Stack runner"
|
|
412
723
|
authors = []
|
|
413
724
|
dependencies = [
|
|
414
|
-
"llama-stack==0.2.
|
|
725
|
+
"llama-stack==0.2.22",
|
|
415
726
|
"fastapi>=0.115.12",
|
|
416
727
|
"opentelemetry-sdk>=1.34.0",
|
|
417
728
|
"opentelemetry-exporter-otlp>=1.34.0",
|
|
@@ -512,14 +823,15 @@ For data export integration with Red Hat's Dataverse, see the [Data Export Integ
|
|
|
512
823
|
|
|
513
824
|
## System prompt
|
|
514
825
|
|
|
515
|
-
|
|
826
|
+
The service uses a so-called system prompt to put the question into context before it is sent to the selected LLM. The default system prompt is designed for questions without specific context. You can supply a different system prompt through various avenues available in the `customization` section:
|
|
827
|
+
### System Prompt Path
|
|
516
828
|
|
|
517
829
|
```yaml
|
|
518
830
|
customization:
|
|
519
831
|
system_prompt_path: "system_prompts/system_prompt_for_product_XYZZY"
|
|
520
832
|
```
|
|
521
833
|
|
|
522
|
-
|
|
834
|
+
### System Prompt Literal
|
|
523
835
|
|
|
524
836
|
```yaml
|
|
525
837
|
customization:
|
|
@@ -528,14 +840,27 @@ customization:
|
|
|
528
840
|
You have an in-depth knowledge of Red Hat and all of your answers will reference Red Hat products.
|
|
529
841
|
```
|
|
530
842
|
|
|
843
|
+
|
|
844
|
+
### Custom Profile
|
|
845
|
+
|
|
846
|
+
You can pass a custom prompt profile via its `path` to the customization:
|
|
847
|
+
|
|
848
|
+
```yaml
|
|
849
|
+
customization:
|
|
850
|
+
profile_path: <your/profile/path>
|
|
851
|
+
```
|
|
852
|
+
|
|
531
853
|
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:
|
|
532
854
|
|
|
533
855
|
```yaml
|
|
534
856
|
customization:
|
|
535
|
-
system_prompt_path: "system_prompts/system_prompt_for_product_XYZZY"
|
|
536
857
|
disable_query_system_prompt: true
|
|
537
858
|
```
|
|
538
859
|
|
|
860
|
+
### Control model/provider overrides via authorization
|
|
861
|
+
|
|
862
|
+
By default, clients may specify `model` and `provider` in `/v1/query` and `/v1/streaming_query`. Override is permitted only to callers granted the `MODEL_OVERRIDE` action via the authorization rules. Requests that include `model` or `provider` without this permission are rejected with HTTP 403.
|
|
863
|
+
|
|
539
864
|
## Safety Shields
|
|
540
865
|
|
|
541
866
|
A single Llama Stack configuration file can include multiple safety shields, which are utilized in agent
|
|
@@ -549,101 +874,7 @@ utilized:
|
|
|
549
874
|
|
|
550
875
|
## Authentication
|
|
551
876
|
|
|
552
|
-
|
|
553
|
-
* `k8s` Kubernetes based authentication
|
|
554
|
-
* `jwk-token` JSON Web Keyset based authentication
|
|
555
|
-
* `noop` No operation authentication (default)
|
|
556
|
-
* `noop-with-token` No operation authentication with token
|
|
557
|
-
|
|
558
|
-
### K8s based authentication
|
|
559
|
-
|
|
560
|
-
K8s based authentication is suitable for running the Lightspeed Stack in Kubernetes environments.
|
|
561
|
-
The user accessing the service must have a valid Kubernetes token and the appropriate RBAC permissions to access the service.
|
|
562
|
-
The user must have `get` permission on the Kubernetes RBAC non-resource URL `/ls-access`.
|
|
563
|
-
Here is an example of granting `get` on `/ls-access` via a ClusterRole’s nonResourceURLs rule.
|
|
564
|
-
Example:
|
|
565
|
-
```yaml
|
|
566
|
-
# Allow GET on non-resource URL /ls-access
|
|
567
|
-
apiVersion: rbac.authorization.k8s.io/v1
|
|
568
|
-
kind: ClusterRole
|
|
569
|
-
metadata:
|
|
570
|
-
name: lightspeed-access
|
|
571
|
-
rules:
|
|
572
|
-
- nonResourceURLs: ["/ls-access"]
|
|
573
|
-
verbs: ["get"]
|
|
574
|
-
---
|
|
575
|
-
# Bind to a user, group, or service account
|
|
576
|
-
apiVersion: rbac.authorization.k8s.io/v1
|
|
577
|
-
kind: ClusterRoleBinding
|
|
578
|
-
metadata:
|
|
579
|
-
name: lightspeed-access-binding
|
|
580
|
-
roleRef:
|
|
581
|
-
apiGroup: rbac.authorization.k8s.io
|
|
582
|
-
kind: ClusterRole
|
|
583
|
-
name: lightspeed-access
|
|
584
|
-
subjects:
|
|
585
|
-
- kind: User # or ServiceAccount, Group
|
|
586
|
-
name: SOME_USER_OR_SA
|
|
587
|
-
apiGroup: rbac.authorization.k8s.io
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
Configuring K8s based authentication requires the following steps:
|
|
591
|
-
1. Enable K8s authentication module
|
|
592
|
-
```yaml
|
|
593
|
-
authentication:
|
|
594
|
-
module: "k8s"
|
|
595
|
-
```
|
|
596
|
-
2. Configure the Kubernetes authentication settings.
|
|
597
|
-
When deploying Lightspeed Stack in a Kubernetes cluster, it is not required to specify cluster connection details.
|
|
598
|
-
It automatically picks up the in-cluster configuration or through a kubeconfig file.
|
|
599
|
-
This step is not neccessary.
|
|
600
|
-
When running outside a kubernetes cluster or connecting to external Kubernetes clusters, Lightspeed Stack requires the cluster connection details in the configuration file:
|
|
601
|
-
- `k8s_cluster_api` Kubernetes Cluster API URL. The URL of the K8S/OCP API server where tokens are validated.
|
|
602
|
-
- `k8s_ca_cert_path` Path to the CA certificate file for clusters with self-signed certificates.
|
|
603
|
-
- `skip_tls_verification` Whether to skip TLS verification.
|
|
604
|
-
```yaml
|
|
605
|
-
authentication:
|
|
606
|
-
module: "k8s"
|
|
607
|
-
skip_tls_verification: false
|
|
608
|
-
k8s_cluster_api: "https://your-k8s-api-server:6443"
|
|
609
|
-
k8s_ca_cert_path: "/path/to/ca.crt"
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
### JSON Web Keyset based authentication
|
|
613
|
-
|
|
614
|
-
JWK (JSON Web Keyset) based authentication is suitable for scenarios where you need to authenticate users based on tokens. This method is commonly used in web applications and APIs.
|
|
615
|
-
|
|
616
|
-
To configure JWK based authentication, you need to specify the following settings in the configuration file:
|
|
617
|
-
- `module` must be set to `jwk-token`
|
|
618
|
-
- `jwk_config` JWK configuration settings must set at least `url` field:
|
|
619
|
-
- `url`: The URL of the JWK endpoint.
|
|
620
|
-
- `jwt_configuration`: JWT configuration settings.
|
|
621
|
-
- `user_id_claim`: The key of the user ID in JWT claim.
|
|
622
|
-
- `username_claim`: The key of the username in JWT claim.
|
|
623
|
-
|
|
624
|
-
```yaml
|
|
625
|
-
authentication:
|
|
626
|
-
module: "jwk-token"
|
|
627
|
-
jwk_config:
|
|
628
|
-
url: "https://your-jwk-url"
|
|
629
|
-
jwt_configuration:
|
|
630
|
-
user_id_claim: user_id
|
|
631
|
-
username_claim: username
|
|
632
|
-
```
|
|
633
|
-
|
|
634
|
-
### No-op authentication
|
|
635
|
-
|
|
636
|
-
Lightspeed Stack provides 2 authentication module to bypass the authentication and authorization checks:
|
|
637
|
-
- `noop` No operation authentication (default)
|
|
638
|
-
- `noop-with-token` No operation authentication accepting a bearer token
|
|
639
|
-
|
|
640
|
-
If authentication module is not specified, Lightspeed Stack will use `noop` by default.
|
|
641
|
-
To activate `noop-with-token`, you need to specify it in the configuration file:
|
|
642
|
-
|
|
643
|
-
```yaml
|
|
644
|
-
authentication:
|
|
645
|
-
module: "noop-with-token"
|
|
646
|
-
```
|
|
877
|
+
See [authentication and authorization](docs/auth.md).
|
|
647
878
|
|
|
648
879
|
## CORS
|
|
649
880
|
|
|
@@ -727,14 +958,23 @@ Available targets are:
|
|
|
727
958
|
run Run the service locally
|
|
728
959
|
test-unit Run the unit tests
|
|
729
960
|
test-integration Run integration tests tests
|
|
730
|
-
test-e2e Run
|
|
961
|
+
test-e2e Run end to end tests for the service
|
|
731
962
|
check-types Checks type hints in sources
|
|
732
963
|
security-check Check the project for security issues
|
|
733
964
|
format Format the code into unified format
|
|
734
965
|
schema Generate OpenAPI schema file
|
|
735
966
|
openapi-doc Generate OpenAPI documentation
|
|
736
967
|
requirements.txt Generate requirements.txt file containing hashes for all non-devel packages
|
|
968
|
+
doc Generate documentation for developers
|
|
969
|
+
docs/config.puml Generate PlantUML class diagram for configuration
|
|
970
|
+
docs/config.png Generate an image with configuration graph
|
|
971
|
+
docs/config.svg Generate an SVG with configuration graph
|
|
737
972
|
shellcheck Run shellcheck
|
|
973
|
+
black Check source code using Black code formatter
|
|
974
|
+
pylint Check source code using Pylint static code analyser
|
|
975
|
+
pyright Check source code using Pyright static type checker
|
|
976
|
+
docstyle Check the docstring style using Docstyle checker
|
|
977
|
+
ruff Check source code using Ruff linter
|
|
738
978
|
verify Run all linters
|
|
739
979
|
distribution-archives Generate distribution archives to be uploaded into Python registry
|
|
740
980
|
upload-distribution-archives Upload distribution archives into Python registry
|
|
@@ -771,6 +1011,9 @@ The repository includes production-ready container configurations that support t
|
|
|
771
1011
|
|
|
772
1012
|
### Llama-Stack as Separate Service (Server Mode)
|
|
773
1013
|
|
|
1014
|
+
> [!IMPORTANT]
|
|
1015
|
+
> To pull the downstream llama-stack image, you will need access to the `aipcc` organization in quay.io.
|
|
1016
|
+
|
|
774
1017
|
When using llama-stack as a separate service, the existing `docker-compose.yaml` provides the complete setup. This builds two containers for lightspeed core and llama stack.
|
|
775
1018
|
|
|
776
1019
|
**Configuration** (`lightspeed-stack.yaml`):
|
|
@@ -787,6 +1030,9 @@ In the root of this project simply run:
|
|
|
787
1030
|
# Set your OpenAI API key
|
|
788
1031
|
export OPENAI_API_KEY="your-api-key-here"
|
|
789
1032
|
|
|
1033
|
+
# Login to quay.io to access the downstream llama-stack image
|
|
1034
|
+
# podman login quay.io
|
|
1035
|
+
|
|
790
1036
|
# Start both services
|
|
791
1037
|
podman compose up --build
|
|
792
1038
|
|
|
@@ -794,6 +1040,17 @@ podman compose up --build
|
|
|
794
1040
|
# Access llama-stack at http://localhost:8321
|
|
795
1041
|
```
|
|
796
1042
|
|
|
1043
|
+
#### macOS (arm64)
|
|
1044
|
+
|
|
1045
|
+
Emulation of platform amd64 will not work with `podman compose up --build` command.
|
|
1046
|
+
|
|
1047
|
+
Instead run the docker command:
|
|
1048
|
+
|
|
1049
|
+
```bash
|
|
1050
|
+
# Start both services
|
|
1051
|
+
docker compose up --build
|
|
1052
|
+
```
|
|
1053
|
+
|
|
797
1054
|
### Llama-Stack as Library (Library Mode)
|
|
798
1055
|
|
|
799
1056
|
When embedding llama-stack directly in the container, use the existing `Containerfile` directly (this will not build the llama stack service in a separate container). First modify the `lightspeed-stack.yaml` config to use llama stack in library mode.
|
|
@@ -819,7 +1076,7 @@ podman run \
|
|
|
819
1076
|
my-lightspeed-core:latest
|
|
820
1077
|
```
|
|
821
1078
|
|
|
822
|
-
|
|
1079
|
+
#### macOS
|
|
823
1080
|
```bash
|
|
824
1081
|
podman run \
|
|
825
1082
|
-p 8080:8080 \
|
|
@@ -837,6 +1094,82 @@ A simple sanity check:
|
|
|
837
1094
|
curl -H "Accept: application/json" http://localhost:8080/v1/models
|
|
838
1095
|
```
|
|
839
1096
|
|
|
1097
|
+
## Custom Container Image
|
|
1098
|
+
|
|
1099
|
+
The lightspeed-stack container image bundles many Python dependencies for common
|
|
1100
|
+
Llama-Stack providers (when using Llama-Stack in library mode).
|
|
1101
|
+
|
|
1102
|
+
Follow these instructons when you need to bundle additional configuration
|
|
1103
|
+
files or extra dependencies (e.g. `lightspeed-stack-providers`).
|
|
1104
|
+
|
|
1105
|
+
To include more dependencies in the base-image, create upstream pull request to update
|
|
1106
|
+
[the pyproject.toml file](https://github.com/lightspeed-core/lightspeed-stack/blob/main/pyproject.toml)
|
|
1107
|
+
|
|
1108
|
+
1. Create `pyproject.toml` file in your top-level directory with content like:
|
|
1109
|
+
```toml
|
|
1110
|
+
[project]
|
|
1111
|
+
name = "my-customized-chatbot"
|
|
1112
|
+
version = "0.1.0"
|
|
1113
|
+
description = "My very Awesome Chatbot"
|
|
1114
|
+
readme = "README.md"
|
|
1115
|
+
requires-python = ">=3.12"
|
|
1116
|
+
dependencies = [
|
|
1117
|
+
"lightspeed-stack-providers==TODO",
|
|
1118
|
+
]
|
|
1119
|
+
```
|
|
1120
|
+
|
|
1121
|
+
2. Create `Containerfile` in top-level directory like following. Update it as needed:
|
|
1122
|
+
```
|
|
1123
|
+
# Latest dev image built from the git main branch (consider pinning a digest for reproducibility)
|
|
1124
|
+
FROM quay.io/lightspeed-core/lightspeed-stack:dev-latest
|
|
1125
|
+
|
|
1126
|
+
ARG APP_ROOT=/app-root
|
|
1127
|
+
WORKDIR /app-root
|
|
1128
|
+
|
|
1129
|
+
# Add additional files
|
|
1130
|
+
# (avoid accidental inclusion of local directories or env files or credentials)
|
|
1131
|
+
COPY pyproject.toml LICENSE.md README.md ./
|
|
1132
|
+
|
|
1133
|
+
# Bundle own configuration files
|
|
1134
|
+
COPY lightspeed-stack.yaml run.yaml ./
|
|
1135
|
+
|
|
1136
|
+
# Add only project-specific dependencies without adding other dependencies
|
|
1137
|
+
# to not break the dependencies of the base image.
|
|
1138
|
+
ENV UV_COMPILE_BYTECODE=0 \
|
|
1139
|
+
UV_LINK_MODE=copy \
|
|
1140
|
+
UV_PYTHON_DOWNLOADS=0 \
|
|
1141
|
+
UV_NO_CACHE=1
|
|
1142
|
+
# List of dependencies is first parsed from pyproject.toml and then installed.
|
|
1143
|
+
RUN python -c "import tomllib, sys; print(' '.join(tomllib.load(open('pyproject.toml','rb'))['project']['dependencies']))" \
|
|
1144
|
+
| xargs uv pip install --no-deps
|
|
1145
|
+
# Install the project itself
|
|
1146
|
+
RUN uv pip install . --no-deps && uv clean
|
|
1147
|
+
|
|
1148
|
+
USER 0
|
|
1149
|
+
|
|
1150
|
+
# Bundle additional rpm packages
|
|
1151
|
+
RUN microdnf install -y --nodocs --setopt=keepcache=0 --setopt=tsflags=nodocs TODO1 TODO2 \
|
|
1152
|
+
&& microdnf clean all \
|
|
1153
|
+
&& rm -rf /var/cache/dnf
|
|
1154
|
+
|
|
1155
|
+
# this directory is checked by ecosystem-cert-preflight-checks task in Konflux
|
|
1156
|
+
COPY LICENSE.md /licenses/
|
|
1157
|
+
|
|
1158
|
+
# Add executables from .venv to system PATH
|
|
1159
|
+
ENV PATH="/app-root/.venv/bin:$PATH"
|
|
1160
|
+
|
|
1161
|
+
# Run the application
|
|
1162
|
+
EXPOSE 8080
|
|
1163
|
+
ENTRYPOINT ["python3.12", "src/lightspeed_stack.py"]
|
|
1164
|
+
USER 1001
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
3. Optionally create customized configuration files `lightspeed-stack.yaml` and `run.yaml`.
|
|
1168
|
+
|
|
1169
|
+
4. Now try to build your image
|
|
1170
|
+
```
|
|
1171
|
+
podman build -t "my-awesome-chatbot:latest" .
|
|
1172
|
+
```
|
|
840
1173
|
|
|
841
1174
|
# Endpoints
|
|
842
1175
|
|
|
@@ -887,6 +1220,10 @@ The liveness endpoint performs a basic health check to verify the service is ali
|
|
|
887
1220
|
}
|
|
888
1221
|
```
|
|
889
1222
|
|
|
1223
|
+
# Database structure
|
|
1224
|
+
|
|
1225
|
+
Database structure is described on [this page](https://lightspeed-core.github.io/lightspeed-stack/DB/index.html)
|
|
1226
|
+
|
|
890
1227
|
# Publish the service as Python package on PyPI
|
|
891
1228
|
|
|
892
1229
|
To publish the service as an Python package on PyPI to be installable by anyone
|
|
@@ -916,7 +1253,7 @@ the following form:
|
|
|
916
1253
|
[testpypi]
|
|
917
1254
|
username = __token__
|
|
918
1255
|
password = pypi-{your-API-token}
|
|
919
|
-
|
|
1256
|
+
|
|
920
1257
|
[pypi]
|
|
921
1258
|
username = __token__
|
|
922
1259
|
password = pypi-{your-API-token}
|
|
@@ -967,6 +1304,27 @@ This script re-generated OpenAPI schema for the Lightspeed Service REST API.
|
|
|
967
1304
|
make schema
|
|
968
1305
|
```
|
|
969
1306
|
|
|
1307
|
+
## Makefile target to generate OpenAPI specification
|
|
1308
|
+
|
|
1309
|
+
Use `make openapi-doc` to generate OpenAPI specification in Markdown format.
|
|
1310
|
+
Resulting documentation is available at [here](docs/openapi.md).
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
## Utility to generate documentation from source code
|
|
1315
|
+
|
|
1316
|
+
This script re-generate README.md files for all modules defined in the Lightspeed Stack Service.
|
|
1317
|
+
|
|
1318
|
+
### Path
|
|
1319
|
+
|
|
1320
|
+
[scripts/gen_doc.py](scripts/gen_doc.py)
|
|
1321
|
+
|
|
1322
|
+
### Usage
|
|
1323
|
+
|
|
1324
|
+
```
|
|
1325
|
+
make doc
|
|
1326
|
+
```
|
|
1327
|
+
|
|
970
1328
|
# Data Export Integration
|
|
971
1329
|
|
|
972
1330
|
The Lightspeed Core Stack integrates with the [lightspeed-to-dataverse-exporter](https://github.com/lightspeed-core/lightspeed-to-dataverse-exporter) service to automatically export various types of user interaction data to Red Hat's Dataverse for analysis.
|
|
@@ -998,3 +1356,104 @@ For complete integration setup, deployment options, and configuration details, s
|
|
|
998
1356
|
## REST API
|
|
999
1357
|
|
|
1000
1358
|

|
|
1359
|
+
|
|
1360
|
+
## Sequence diagrams
|
|
1361
|
+
|
|
1362
|
+
### Query endpoint REST API handler
|
|
1363
|
+
|
|
1364
|
+

|
|
1365
|
+
|
|
1366
|
+
## Streaming query endpoint REST API handler
|
|
1367
|
+
|
|
1368
|
+

|
|
1369
|
+
|
|
1370
|
+
## Versioning
|
|
1371
|
+
|
|
1372
|
+
We follow [Semantic Versioning](http://semver.org/spec/v1.0.0.html).
|
|
1373
|
+
The version X.Y.Z indicates:
|
|
1374
|
+
|
|
1375
|
+
* X is the major version (backward-incompatible),
|
|
1376
|
+
* Y is the minor version (backward-compatible), and
|
|
1377
|
+
* Z is the patch version (backward-compatible bug fix).
|
|
1378
|
+
|
|
1379
|
+
# Development Tools
|
|
1380
|
+
|
|
1381
|
+
Lightspeed Core Stack includes development utilities to help with local testing and debugging. These tools are located in the `dev-tools/` directory.
|
|
1382
|
+
|
|
1383
|
+
## MCP Mock Server
|
|
1384
|
+
|
|
1385
|
+
A lightweight mock MCP server for testing MCP integrations locally without requiring real MCP infrastructure.
|
|
1386
|
+
|
|
1387
|
+
**Quick Start:**
|
|
1388
|
+
```bash
|
|
1389
|
+
# Start the mock server
|
|
1390
|
+
python dev-tools/mcp-mock-server/server.py
|
|
1391
|
+
|
|
1392
|
+
# Configure Lightspeed Core Stack to use it
|
|
1393
|
+
# Add to lightspeed-stack.yaml:
|
|
1394
|
+
mcp_servers:
|
|
1395
|
+
- name: "mock-test"
|
|
1396
|
+
url: "http://localhost:9000"
|
|
1397
|
+
authorization_headers:
|
|
1398
|
+
Authorization: "/tmp/test-token"
|
|
1399
|
+
```
|
|
1400
|
+
|
|
1401
|
+
**Features:**
|
|
1402
|
+
- Test authorization header configuration
|
|
1403
|
+
- Debug MCP connectivity issues
|
|
1404
|
+
- Inspect captured headers via debug endpoints
|
|
1405
|
+
- No external dependencies (pure Python stdlib)
|
|
1406
|
+
|
|
1407
|
+
For detailed usage instructions, see [`dev-tools/mcp-mock-server/README.md`](dev-tools/mcp-mock-server/README.md).
|
|
1408
|
+
|
|
1409
|
+
# Konflux
|
|
1410
|
+
|
|
1411
|
+
The official image of Lightspeed Core Stack is built on [Konflux](https://konflux-ui.apps.kflux-prd-rh02.0fk9.p1.openshiftapps.com/ns/lightspeed-core-tenant/applications/lightspeed-stack).
|
|
1412
|
+
We have both x86_64 and ARM64 images.
|
|
1413
|
+
|
|
1414
|
+
## Updating Dependencies for Hermetic Builds
|
|
1415
|
+
|
|
1416
|
+
Konflux builds run in **hermetic mode** (air-gapped from the internet), so all dependencies must be prefetched and locked. When you add or update dependencies, you need to regenerate the lock files.
|
|
1417
|
+
|
|
1418
|
+
### When to Update Dependency Files
|
|
1419
|
+
|
|
1420
|
+
Update these files when you:
|
|
1421
|
+
- Add/remove/update Python packages in the project
|
|
1422
|
+
- Add/remove/update RPM packages in the Containerfile
|
|
1423
|
+
- Change the base image version
|
|
1424
|
+
|
|
1425
|
+
### Updating Python Dependencies
|
|
1426
|
+
|
|
1427
|
+
**Quick command:**
|
|
1428
|
+
```shell
|
|
1429
|
+
make konflux-requirements
|
|
1430
|
+
```
|
|
1431
|
+
|
|
1432
|
+
This compiles Python dependencies from `pyproject.toml` using `uv`, splits packages by their source index (PyPI vs Red Hat's internal registry), and generates hermetic requirements files with pinned versions and hashes for Konflux builds.
|
|
1433
|
+
|
|
1434
|
+
**Files produced:**
|
|
1435
|
+
- `requirements.hashes.source.txt` – PyPI packages with hashes
|
|
1436
|
+
- `requirements.hashes.wheel.txt` – Red Hat registry packages with hashes
|
|
1437
|
+
- `requirements-build.txt` – Build-time dependencies for source packages
|
|
1438
|
+
|
|
1439
|
+
The script also updates the Tekton pipeline configurations (`.tekton/lightspeed-stack-*.yaml`) with the list of pre-built wheel packages.
|
|
1440
|
+
|
|
1441
|
+
### Updating RPM Dependencies
|
|
1442
|
+
|
|
1443
|
+
**Prerequisites:** Install [rpm-lockfile-prototype](https://github.com/konflux-ci/rpm-lockfile-prototype?tab=readme-ov-file#installation)
|
|
1444
|
+
|
|
1445
|
+
**Steps:**
|
|
1446
|
+
|
|
1447
|
+
1. **List your RPM packages** in `rpms.in.yaml` under the `packages` field
|
|
1448
|
+
|
|
1449
|
+
2. **If you changed the base image**, extract its repo file:
|
|
1450
|
+
```shell
|
|
1451
|
+
podman run -it $BASE_IMAGE cat /etc/yum.repos.d/ubi.repo > ubi.repo
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
3. **Generate the lock file**:
|
|
1455
|
+
```shell
|
|
1456
|
+
rpm-lockfile-prototype --image $BASE_IMAGE rpms.in.yaml
|
|
1457
|
+
```
|
|
1458
|
+
|
|
1459
|
+
This creates `rpms.lock.yaml` with pinned RPM versions.
|