Skip to content

LCORE-2338: LS container entrypoint + deployment artifacts for unified mode - #2319

Open
max-svistunov wants to merge 2 commits into
lightspeed-core:mainfrom
max-svistunov:lcore-2338-unified-mode-deployment
Open

LCORE-2338: LS container entrypoint + deployment artifacts for unified mode#2319
max-svistunov wants to merge 2 commits into
lightspeed-core:mainfrom
max-svistunov:lcore-2338-unified-mode-deployment

Conversation

@max-svistunov

@max-svistunov max-svistunov commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Description

Implements LCORE-2338: server mode works end to end from a single unified lightspeed-stack.yaml.

The ticket assumed the Python CLI already auto-detected unified vs legacy configs — it did not: main() only performed legacy enrichment, so a container handed a unified config (no external run.yaml) could not start. This PR closes that gap and updates the deployment artifacts around it:

  • CLI auto-detection (src/llama_stack_configuration.py): main() dispatches on a new has_synthesis_input() helper mirroring the root Configuration.check_unified_vs_legacy detection (non-empty inference.providers, non-empty vector_store.providers, or a llama_stack.config block). Unified configs are synthesized via synthesize_to_file (--input ignored and need not exist; relative profile: resolves against the --config dir, R8; output keeps mode 0600, R10). Legacy configs enrich --input exactly as before, so existing layouts and the CI provider-matrix workflows are untouched.
  • Entrypoint (scripts/llama-stack-entrypoint.sh): documents the two startup modes, adopts the post-rename ogx stack run command, and fails with a clear error when generation fails and no fallback run.yaml is mounted. (Note for a follow-up: ogx stack run already emits a FutureWarning recommending ogx run — inherited from the rename, kept for consistency with the rest of main.)
  • Container image (deploy/llama-stack/test.containerfile): ships src/data/ to /opt/app-root/data so load_default_baseline() resolves next to the standalone-copied script.
  • Compose (docker-compose.yaml): one file serves both modes — mode is chosen by the content of lightspeed-stack.yaml; the run.yaml mount is documented as legacy-only and is inert in unified mode. Adds the src/data host-copy mount beside the existing script mounts.
  • Docs (deploy/llama-stack/README.md, new): image contents, the two startup modes, a minimal unified-only compose snippet (no run.yaml mount), and rebuild guidance.

.tekton/ pipelines reference no compose files and need no changes (flagging for @radofuchs as the Konflux owner per the ticket).

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement
  • Benchmarks improvement

Tools used to create PR

Identify any AI code assistants used in this PR (for transparency and review context)

  • Assisted-by: Claude Opus 4.8
  • Generated by: Claude Opus 4.8

Related Tickets & Documents

  • Related Issue # LCORE-2336, LCORE-2337
  • Closes # LCORE-2338

Checklist before requesting a review

  • I have performed a self-review of my code.
  • PR has passed all pre-merge test jobs.
  • If it is a core feature, I have added thorough tests.

Testing

  1. Run the CLI dispatch unit tests:
    uv run pytest tests/unit/test_llama_stack_synthesize.py -k "main or has_synthesis" -v
    Expected: detection matrix + both dispatch paths pass, including synthesis with a nonexistent --input and relative-profile resolution.
    Actual: 4 passed (51 passed for the whole module; full unit suite 3176 passed).
  2. Unified server mode end to end (acceptance criterion 1). Produce a unified root config by migrating CI's server-mode pair, then start the stack:
    uv run python src/llama_stack_configuration.py (via migrate_config_dumb over tests/e2e/configs/run-ci.yaml + tests/e2e/configuration/server-mode/lightspeed-stack.yaml, enrichment inputs stripped) → root lightspeed-stack.yaml; docker compose up -d llama-stack lightspeed-stack
    Expected: llama-stack log shows the synthesis path; all containers healthy; /v1/query answers through LCORE → LS.
    Actual (re-verified after rebasing onto the OGX-rename main):
    • llama-stack | Generating llama-stack config from /opt/app-root/lightspeed-stack.yaml (mode auto-detected)...
    • llama-stack | Using generated config: /tmp/generated-run.yaml
    • docker compose ps: llama-stack, lightspeed-stack, mock-mcp, mock-tls-inference all healthy
    • curl -X POST http://localhost:8080/v1/query …{"response":"unified ogx works",…}
  3. Legacy layout still works (acceptance criterion 2). Restore a legacy-shaped root lightspeed-stack.yaml (CI server-mode config, no synthesis input) with run.yaml = run-ci.yaml, recreate the two containers:
    docker compose up -d --force-recreate llama-stack lightspeed-stack
    Expected: enrichment path taken (the config has no synthesis input, so only generate_configuration over the mounted run.yaml can produce the generated config); containers healthy; /v1/query answers.
    Actual (post-rebase): all containers healthy; BYOK enrichment visible in the generated config (backend: byok_e2e-test-docs_storage); curl …{"response":"legacy ogx works",…}
  4. uv run make format / uv run make verify
    Actual: clean, except 14 pre-existing mypy errors in tests/unit/utils/test_models_dumper.py that reproduce identically on untouched upstream/main.
  5. CI on the rebased head: 24 checks pass — including the group-1 e2e jobs in BOTH server and library modes, which exercise this PR's entrypoint/compose changes end-to-end in CI. The remaining e2e failures are the groups red on main itself (CI OpenAI quota).

Summary by CodeRabbit

  • New Features

    • Added automatic support for unified and legacy configuration modes.
    • Unified configurations can now be generated from inference, vector-store, or stack settings.
    • Added support for resolving configuration profiles and bundled runtime data.
    • Added container deployment examples and guidance for both configuration modes.
  • Bug Fixes

    • Prevented startup when configuration generation fails and no fallback configuration is available.
    • Improved handling of legacy configurations with BYOK RAG settings.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 71ec458f-63a1-440a-9b83-32f3f7b97cb5

📥 Commits

Reviewing files that changed from the base of the PR and between ff24352 and e74d9b1.

📒 Files selected for processing (6)
  • deploy/llama-stack/README.md
  • deploy/llama-stack/test.containerfile
  • docker-compose.yaml
  • scripts/llama-stack-entrypoint.sh
  • src/llama_stack_configuration.py
  • tests/unit/test_llama_stack_synthesize.py

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (32)
  • GitHub Check: check
  • GitHub Check: integration_tests (3.13)
  • GitHub Check: integration_tests (3.12)
  • GitHub Check: Pylinter
  • GitHub Check: mypy
  • GitHub Check: ruff
  • GitHub Check: unit_tests (3.12)
  • GitHub Check: unit_tests (3.13)
  • GitHub Check: radon
  • GitHub Check: Pyright
  • GitHub Check: black
  • GitHub Check: build-pr
  • GitHub Check: Red Hat Konflux / rag-content-0-8-e2e-tests / lightspeed-stack-0-8
  • GitHub Check: spectral
  • GitHub Check: Red Hat Konflux / lightspeed-core-0-8-enterprise-contract / lightspeed-stack-0-8
  • GitHub Check: Red Hat Konflux / lightspeed-stack-0-8-e2e-tests / lightspeed-stack-0-8
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-0-8-on-pull-request
  • GitHub Check: E2E: library / ci / mcp
  • GitHub Check: E2E: library / ci / default
  • GitHub Check: E2E: server / ci / skills
  • GitHub Check: E2E: server / ci / tls
  • GitHub Check: E2E: server / ci / rbac
  • GitHub Check: E2E: library / ci / authorized
  • GitHub Check: E2E: library / ci / other
  • GitHub Check: E2E: library / ci / rbac
  • GitHub Check: E2E: server / ci / other
  • GitHub Check: E2E: server / ci / authorized
  • GitHub Check: E2E: server / ci / default
  • GitHub Check: E2E: library / ci / skills
  • GitHub Check: E2E: server / ci / mcp
  • GitHub Check: E2E Tests for Lightspeed Evaluation job
  • GitHub Check: check
🧰 Additional context used
📓 Path-based instructions (3)
**/*

📄 CodeRabbit inference engine (Custom checks)

**/*: Flag meaningful O(n^2)+ algorithms on non-trivial inputs, including handlers and Kubernetes list operations.
Flag N+1 patterns that list items and then query once per item, including Kubernetes API and database access.
Flag expensive work inside loops, including API calls, JSON parsing, and regex compilation.
Flag unbounded growth in caches, watchers, or buffers when eviction or limits are missing.
Flag missing pagination or limits on list operations and API endpoints.
Flag secrets or tokens logged in plaintext or hardcoded in source.
Flag API endpoints missing authentication or authorization.
Flag injection vulnerabilities, including SQL injection, command injection, and path traversal.
Flag sensitive data leaked in API responses, WebSocket messages, or logs.
Flag Kubernetes Secrets and Red Hat secrets missing OwnerReferences.

Files:

  • deploy/llama-stack/README.md
  • docker-compose.yaml
  • deploy/llama-stack/test.containerfile
  • src/llama_stack_configuration.py
  • scripts/llama-stack-entrypoint.sh
  • tests/unit/test_llama_stack_synthesize.py
src/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.py: Use absolute imports for internal modules and follow the prescribed FastAPI and Llama Stack import conventions.
All modules must begin with descriptive docstrings; use logger = get_logger(__name__) from log.py for module logging; package __init__.py files must contain brief package descriptions.
Define shared constants in the central constants.py module, add descriptive comments, and annotate constants with Final[type].
Use complete type annotations for function parameters, return types, class attributes, and type aliases; prefer specific types over Any, use modern union syntax, and use typing_extensions.Self for model validators.
All functions and classes require descriptive Google-style docstrings, including appropriate Parameters, Returns, Raises, and Attributes sections.
Use descriptive snake_case, action-oriented function names such as get_, validate_, and check_; use PascalCase class names with standard suffixes such as Configuration, Error/Exception, Resolver, and Interface.
Avoid modifying input parameters in place; return a newly constructed data structure instead.
Use async def for I/O operations and external API calls; API endpoints should raise FastAPI HTTPException with appropriate status codes and handle Llama Stack APIConnectionError.
Use from log import get_logger and standard logger levels: debug for diagnostics, info for general execution, warning for unexpected conditions or potential problems, and error for serious failures.
Configuration models must extend ConfigurationBase, set extra="forbid" to reject unknown fields, use Pydantic validators for custom validation, and use types such as Optional[FilePath], PositiveInt, and SecretStr where appropriate.
Abstract interfaces must use ABC and @abstractmethod decorators.
Never commit secrets or keys; use environment variables for sensitive data.

Files:

  • src/llama_stack_configuration.py
tests/unit/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Use pytest for unit tests, shared fixtures in conftest.py, pytest-mock for mocks, pytest.mark.asyncio for async tests, and maintain at least 60% unit-test coverage.

Files:

  • tests/unit/test_llama_stack_synthesize.py
🧠 Learnings (5)
📚 Learning: 2026-05-20T08:09:30.641Z
Learnt from: max-svistunov
Repo: lightspeed-core/lightspeed-stack PR: 1580
File: docs/design/llama-stack-config-merge/poc-results/library-mode/synthesized-run.yaml:107-110
Timestamp: 2026-05-20T08:09:30.641Z
Learning: In Llama-stack config YAMLs, when defining a Llama Guard safety shield entry, set `provider_shield_id` to the *guard model identifier* (e.g., `meta-llama/Llama-Guard-3-8B`). Do not use a chat/generative model id (e.g., `openai/gpt-4o-mini`): a chat-model id (or `native_override`) indicates only an override landed and does **not** mean the safety shield is actually gating queries. Ensure any E2E coverage for the related implementation (JIRA/E2E tests) exercises a real Llama Guard model to verify that the shield is effective.

Applied to files:

  • docker-compose.yaml
📚 Learning: 2026-06-24T13:45:37.249Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 1971
File: src/utils/markdown_repair.py:31-36
Timestamp: 2026-06-24T13:45:37.249Z
Learning: In the lightspeed-stack repository, docstrings must use the section header name "Parameters:" (not "Args:") for function arguments, even if the project references Google Python docstring conventions. Ensure docstrings follow the project’s established "Parameters:" header format for any documented function parameters.

Applied to files:

  • src/llama_stack_configuration.py
  • tests/unit/test_llama_stack_synthesize.py
📚 Learning: 2026-07-06T15:26:18.398Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 2071
File: src/models/config.py:2416-2422
Timestamp: 2026-07-06T15:26:18.398Z
Learning: In this repo’s Python code under src/**, don’t treat differences in string concatenation style as a style inconsistency when Black has effectively forced (or made clearer) use of explicit `+` string concatenation in multi-line logger/string expressions. If adjacent-literal implicit concatenation is avoided/changed specifically to accommodate Black’s formatting in these call sites, accept the `+` usage and don’t recommend converting it solely for consistency with nearby blocks that use implicit concatenation.

Applied to files:

  • src/llama_stack_configuration.py
📚 Learning: 2026-07-17T19:25:05.325Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 2166
File: src/utils/saved_prompts.py:129-157
Timestamp: 2026-07-17T19:25:05.325Z
Learning: For any endpoint that handles saved prompts and calls `src/utils/saved_prompts.py::create_saved_prompt`, treat the endpoint as the validation boundary. Before calling `create_saved_prompt`, validate the incoming saved-prompt name and content, specifically using `validate_saved_prompt_name` and then persist (store) the normalized value it returns. Do not call `create_saved_prompt` with unvalidated/raw name/content.

Applied to files:

  • src/llama_stack_configuration.py
📚 Learning: 2026-05-12T15:14:34.788Z
Learnt from: syedriko
Repo: lightspeed-core/lightspeed-stack PR: 1727
File: scripts/konflux_requirements.sh:9-15
Timestamp: 2026-05-12T15:14:34.788Z
Learning: In this repo, the `.konflux/` directory is committed/tracked and is guaranteed to exist in a fresh clone. Therefore, shell scripts that write output under `.konflux/` (e.g., create files like `.konflux/<...>`) should not waste effort by calling `mkdir -p .konflux` first. Only add directory-creation logic if the script may run in an environment/repo state where `.konflux/` might not be present.

Applied to files:

  • scripts/llama-stack-entrypoint.sh
🪛 ast-grep (0.45.1)
src/llama_stack_configuration.py

[warning] 1435-1435: File path is request-/variable-derived; validate and normalize to prevent path traversal.
Context: open(args.config, "r", encoding="utf-8")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(open-filename-from-request)

🔇 Additional comments (6)
src/llama_stack_configuration.py (1)

1375-1397: LGTM!

Also applies to: 1400-1443

tests/unit/test_llama_stack_synthesize.py (1)

11-11: LGTM!

Also applies to: 23-25, 835-946

scripts/llama-stack-entrypoint.sh (1)

3-44: LGTM!

deploy/llama-stack/test.containerfile (1)

42-50: LGTM!

docker-compose.yaml (1)

15-23: LGTM!

deploy/llama-stack/README.md (1)

1-52: LGTM!


Walkthrough

The change adds automatic unified or legacy configuration selection for Llama Stack. It updates CLI dispatch, container startup, runtime mounts, configuration assets, deployment documentation, and unit tests.

Changes

Llama Stack configuration modes

Layer / File(s) Summary
Configuration mode detection and CLI dispatch
src/llama_stack_configuration.py, tests/unit/test_llama_stack_synthesize.py
The CLI detects unified inputs and selects synthesis. Otherwise, it retains legacy enrichment. Tests cover input detection, profile resolution, unified synthesis, and BYOK RAG enrichment.
Container startup and runtime assets
scripts/llama-stack-entrypoint.sh, deploy/llama-stack/test.containerfile, docker-compose.yaml, deploy/llama-stack/README.md
The entrypoint generates /tmp/generated-run.yaml, validates fallback configuration, and launches Llama Stack only after successful configuration handling. The container and Compose setup provide the src/data assets and document both modes.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to e74d9

The change adds unified-config auto-detection while preserving legacy startup behavior and updates the related deployment artifacts; targeted tests, end-to-end checks, and CI support the current implementation, so no actionable merge-blocking risk remains beyond normal checks.

Sequence Diagram(s)

sequenceDiagram
  participant Entrypoint as llama-stack-entrypoint.sh
  participant ConfigurationCLI as src/llama_stack_configuration.py
  participant LlamaStack
  Entrypoint->>ConfigurationCLI: Detect inputs and generate configuration
  ConfigurationCLI-->>Entrypoint: Return generated-run.yaml or generation failure
  Entrypoint->>Entrypoint: Validate generated or mounted run configuration
  Entrypoint->>LlamaStack: Launch with the selected configuration
Loading

Possibly related PRs

Suggested reviewers: anik120, asimurka, radofuchs

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: container entrypoint support and deployment artifacts for unified mode.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Performance And Algorithmic Complexity ✅ Passed Changed code adds only constant-time mode checks and one config-generation call; the entrypoint has no loops, API calls, unbounded state, or pagination-sensitive list operations.
Security And Secret Handling ✅ Passed No violation found: the diff adds no API/auth or Kubernetes Secret resources, logs only paths/status, passes quoted paths to commands, and keeps synthesized config files mode 0600.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@max-svistunov max-svistunov reopened this Aug 3, 2026
@max-svistunov
max-svistunov force-pushed the lcore-2338-unified-mode-deployment branch from 69e9dff to 2f56509 Compare August 3, 2026 15:06
@max-svistunov
max-svistunov force-pushed the lcore-2338-unified-mode-deployment branch from 2f56509 to e74d9b1 Compare August 17, 2026 07:04
@max-svistunov

max-svistunov commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

@tisnik @radofuchs Could you PTAL?

The llama_stack_configuration.py CLI previously only performed legacy
enrichment: it always read the --input run.yaml and enriched it, so a
container handed a unified lightspeed-stack.yaml (with no external
run.yaml) could not start. The spec's server-mode trigger mechanism
requires the CLI to auto-detect the configuration shape.

main() now dispatches on a new has_synthesis_input() helper that mirrors
the root Configuration.check_unified_vs_legacy detection on the raw YAML
dict (non-empty inference.providers, non-empty vector_store.providers,
or a llama_stack.config block). Unified configs are synthesized via
synthesize_to_file — --input is ignored and need not exist, relative
profile: paths resolve against the --config directory (R8), and the
output keeps the 0600 secret-safety mode (R10). Legacy configs enrich
the --input run.yaml exactly as before, so existing container layouts
and CI provider-matrix runs are unaffected.

Tests cover the detection matrix (all three synthesis inputs, empty
provider lists, null sections, legacy path) and both CLI dispatch paths,
including synthesis with a nonexistent --input and relative-profile
resolution.
Make server mode work end to end from a single unified
lightspeed-stack.yaml, relying on the CLI's unified-vs-legacy
auto-detection:

- scripts/llama-stack-entrypoint.sh: document the two startup modes in
  the header (synthesis from a unified config vs legacy run.yaml
  enrichment — the Python CLI decides), rename the intermediate file to
  generated-run.yaml, and fail with a clear error when generation fails
  and no fallback run.yaml is mounted, instead of handing llama-stack a
  nonexistent path.
- deploy/llama-stack/test.containerfile: ship src/data/ to
  /opt/app-root/data so load_default_baseline() resolves next to the
  standalone-copied script (it reads ./data/default_run.yaml relative to
  its own location); chown it for the runtime user.
- docker-compose.yaml: mount the src/data host copy beside the existing
  script host-copies, and document that the run.yaml mount is only
  consumed in legacy mode — one compose file serves both modes, with the
  mode chosen by the content of lightspeed-stack.yaml, so the CI
  provider-matrix workflows that pair run-*.yaml files with this compose
  file keep working unchanged.
- deploy/llama-stack/README.md: document what the image bundles, the two
  startup modes, a minimal unified-only compose snippet (no run.yaml
  mount), and when a rebuild is needed vs covered by the host-copy
  mounts.

.tekton/ pipelines reference no compose files and need no changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant