From 6ffaae62f88a330f2d56c98d30f388d198fa2577 Mon Sep 17 00:00:00 2001 From: Charlie Doern Date: Tue, 18 Nov 2025 15:32:44 -0500 Subject: [PATCH] feat: remove usage of build yaml for list-deps the build.yaml is only used in the following ways: 1. list-deps 2. distribution code-gen since `llama stack build` no longer exists, I found myself asking "why do we need two different files for list-deps and run"? Removing the BuildConfig and DistributionTemplate from llama stack list-deps is the first step in removing the build yaml entirely. Removing the BuildConfig and build.yaml cuts the files users need to maintain in half, and allows us to focus on the stability of _just_ the run.yaml The build.yaml made sense for when we were managing the build process for the user and actually _producing_ a run.yaml _from_ the build.yaml, but now that we are simply just getting the provider registry and listing the deps, switching to run.yaml simplifies the scope here greatly Signed-off-by: Charlie Doern --- .github/workflows/providers-list-deps.yml | 2 +- .github/workflows/test-external.yml | 4 +-- .../external/external-providers-guide.mdx | 25 +++++++-------- src/llama_stack/cli/stack/_list_deps.py | 31 ++++++------------- src/llama_stack/core/build.py | 6 ++-- src/llama_stack/core/datatypes.py | 6 ++++ 6 files changed, 34 insertions(+), 40 deletions(-) diff --git a/.github/workflows/providers-list-deps.yml b/.github/workflows/providers-list-deps.yml index 88659dbe3..a2e8a87c9 100644 --- a/.github/workflows/providers-list-deps.yml +++ b/.github/workflows/providers-list-deps.yml @@ -102,4 +102,4 @@ jobs: USE_COPY_NOT_MOUNT: "true" LLAMA_STACK_DIR: "." run: | - uv run llama stack list-deps src/llama_stack/distributions/ci-tests/build.yaml + uv run llama stack list-deps src/llama_stack/distributions/ci-tests/run.yaml diff --git a/.github/workflows/test-external.yml b/.github/workflows/test-external.yml index a99719718..fed3967ee 100644 --- a/.github/workflows/test-external.yml +++ b/.github/workflows/test-external.yml @@ -44,14 +44,14 @@ jobs: - name: Print distro dependencies run: | - uv run --no-sync llama stack list-deps tests/external/build.yaml + uv run --no-sync llama stack list-deps tests/external/run-byoa.yaml - name: Build distro from config file run: | uv venv ci-test source ci-test/bin/activate uv pip install -e . - LLAMA_STACK_LOGGING=all=CRITICAL llama stack list-deps tests/external/build.yaml | xargs -L1 uv pip install + LLAMA_STACK_LOGGING=all=CRITICAL llama stack list-deps tests/external/run-byoa.yaml | xargs -L1 uv pip install - name: Start Llama Stack server in background if: ${{ matrix.image-type }} == 'venv' diff --git a/docs/docs/providers/external/external-providers-guide.mdx b/docs/docs/providers/external/external-providers-guide.mdx index dc813c75b..3d013f720 100644 --- a/docs/docs/providers/external/external-providers-guide.mdx +++ b/docs/docs/providers/external/external-providers-guide.mdx @@ -222,22 +222,21 @@ def get_provider_spec() -> ProviderSpec: [ramalama-stack](https://github.com/containers/ramalama-stack) is a recognized external provider that supports installation via module. -To install Llama Stack with this external provider a user can provider the following build.yaml: +To install Llama Stack with this external provider a user can provider the following run.yaml: ```yaml version: 2 -distribution_spec: - description: Use (an external) Ramalama server for running LLM inference - container_image: null - providers: - inference: - - provider_type: remote::ramalama - module: ramalama_stack==0.3.0a0 -image_type: venv -image_name: null -additional_pip_packages: -- aiosqlite -- sqlalchemy[asyncio] +image_name: ramalama +apis: +- inference +providers: + inference: + - provider_id: ramalama + provider_type: remote::ramalama + module: ramalama_stack==0.3.0a0 + config: {} +server: + port: 8321 ``` No other steps are required beyond installing dependencies with `llama stack list-deps | xargs -L1 uv pip install` and then running `llama stack run`. The CLI will use `module` to install the provider dependencies, retrieve the spec, etc. diff --git a/src/llama_stack/cli/stack/_list_deps.py b/src/llama_stack/cli/stack/_list_deps.py index 82bef1a4f..f11ce486a 100644 --- a/src/llama_stack/cli/stack/_list_deps.py +++ b/src/llama_stack/cli/stack/_list_deps.py @@ -11,15 +11,9 @@ from pathlib import Path import yaml from termcolor import cprint -from llama_stack.cli.stack.utils import ImageType from llama_stack.core.build import get_provider_dependencies -from llama_stack.core.datatypes import ( - BuildConfig, - BuildProvider, - DistributionSpec, -) +from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_provider_registry -from llama_stack.core.stack import replace_env_vars from llama_stack.log import get_logger from llama_stack_api import Api @@ -72,7 +66,7 @@ def run_stack_list_deps_command(args: argparse.Namespace) -> None: try: from llama_stack.core.utils.config_resolution import Mode, resolve_config_or_distro - config_file = resolve_config_or_distro(args.config, Mode.BUILD) + config_file = resolve_config_or_distro(args.config, Mode.RUN) except ValueError as e: cprint( f"Could not parse config file {args.config}: {e}", @@ -84,9 +78,7 @@ def run_stack_list_deps_command(args: argparse.Namespace) -> None: with open(config_file) as f: try: contents = yaml.safe_load(f) - contents = replace_env_vars(contents) - build_config = BuildConfig(**contents) - build_config.image_type = "venv" + run_config = StackRunConfig(**contents) except Exception as e: cprint( f"Could not parse config file {config_file}: {e}", @@ -95,7 +87,7 @@ def run_stack_list_deps_command(args: argparse.Namespace) -> None: ) sys.exit(1) elif args.providers: - provider_list: dict[str, list[BuildProvider]] = dict() + provider_list: dict[str, list[Provider]] = dict() for api_provider in args.providers.split(","): if "=" not in api_provider: cprint( @@ -114,8 +106,9 @@ def run_stack_list_deps_command(args: argparse.Namespace) -> None: ) sys.exit(1) if provider_type in providers_for_api: - provider = BuildProvider( + provider = Provider( provider_type=provider_type, + provider_id=provider_type.split("::")[1], module=None, ) provider_list.setdefault(api, []).append(provider) @@ -126,20 +119,16 @@ def run_stack_list_deps_command(args: argparse.Namespace) -> None: file=sys.stderr, ) sys.exit(1) - distribution_spec = DistributionSpec( - providers=provider_list, - description=",".join(args.providers), - ) - build_config = BuildConfig(image_type=ImageType.VENV.value, distribution_spec=distribution_spec) + run_config = StackRunConfig(providers=provider_list, image_name="providers-run") - normal_deps, special_deps, external_provider_dependencies = get_provider_dependencies(build_config) + normal_deps, special_deps, external_provider_dependencies = get_provider_dependencies(run_config) normal_deps += SERVER_DEPENDENCIES # Add external API dependencies - if build_config.external_apis_dir: + if run_config.external_apis_dir: from llama_stack.core.external import load_external_apis - external_apis = load_external_apis(build_config) + external_apis = load_external_apis(run_config) if external_apis: for _, api_spec in external_apis.items(): normal_deps.extend(api_spec.pip_packages) diff --git a/src/llama_stack/core/build.py b/src/llama_stack/core/build.py index 630b2a47f..757763bd1 100644 --- a/src/llama_stack/core/build.py +++ b/src/llama_stack/core/build.py @@ -9,7 +9,7 @@ import sys from pydantic import BaseModel from termcolor import cprint -from llama_stack.core.datatypes import BuildConfig +from llama_stack.core.datatypes import BuildConfig, StackRunConfig from llama_stack.core.distribution import get_provider_registry from llama_stack.distributions.template import DistributionTemplate from llama_stack.log import get_logger @@ -36,13 +36,13 @@ class ApiInput(BaseModel): def get_provider_dependencies( - config: BuildConfig | DistributionTemplate, + config: StackRunConfig, ) -> tuple[list[str], list[str], list[str]]: """Get normal and special dependencies from provider configuration.""" if isinstance(config, DistributionTemplate): config = config.build_config() - providers = config.distribution_spec.providers + providers = config.providers additional_pip_packages = config.additional_pip_packages deps = [] diff --git a/src/llama_stack/core/datatypes.py b/src/llama_stack/core/datatypes.py index 1e29690ff..245491332 100644 --- a/src/llama_stack/core/datatypes.py +++ b/src/llama_stack/core/datatypes.py @@ -517,6 +517,7 @@ can be instantiated multiple times (with different configs) if necessary. """, ) storage: StorageConfig = Field( + default_factory=StorageConfig, description="Catalog of named storage backends and references available to the stack", ) @@ -534,6 +535,11 @@ can be instantiated multiple times (with different configs) if necessary. description="Configuration for the HTTP(S) server", ) + additional_pip_packages: list[str] = Field( + default_factory=list, + description="Additional pip packages to install in the distribution. These packages will be installed in the distribution environment.", + ) + external_providers_dir: Path | None = Field( default=None, description="Path to directory containing external provider implementations. The providers code and dependencies must be installed on the system.",