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 <cdoern@redhat.com>
This commit is contained in:
Charlie Doern 2025-11-18 15:32:44 -05:00
parent 91f1b352b4
commit 6ffaae62f8
6 changed files with 34 additions and 40 deletions

View file

@ -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

View file

@ -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'

View file

@ -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:
image_name: ramalama
apis:
- inference
providers:
inference:
- provider_type: remote::ramalama
- provider_id: ramalama
provider_type: remote::ramalama
module: ramalama_stack==0.3.0a0
image_type: venv
image_name: null
additional_pip_packages:
- aiosqlite
- sqlalchemy[asyncio]
config: {}
server:
port: 8321
```
No other steps are required beyond installing dependencies with `llama stack list-deps <distro> | 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.

View file

@ -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)

View file

@ -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 = []

View file

@ -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.",