diff --git a/.github/workflows/providers-build.yml b/.github/workflows/providers-build.yml index 010894283..ee532a94a 100644 --- a/.github/workflows/providers-build.yml +++ b/.github/workflows/providers-build.yml @@ -81,3 +81,29 @@ jobs: run: | source test/bin/activate uv pip list + + build-single-provider: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + python-version: "3.10" + + - name: Install LlamaStack + run: | + uv venv + source .venv/bin/activate + uv pip install -e . + + - name: Build a single provider + run: | + USE_COPY_NOT_MOUNT=true LLAMA_STACK_DIR=. uv run llama stack build --image-type venv --image-name test --providers inference=remote::ollama diff --git a/llama_stack/cli/stack/_build.py b/llama_stack/cli/stack/_build.py index ac1933e0e..3251bc632 100644 --- a/llama_stack/cli/stack/_build.py +++ b/llama_stack/cli/stack/_build.py @@ -89,6 +89,43 @@ def run_stack_build_command(args: argparse.Namespace) -> None: color="red", ) sys.exit(1) + elif args.providers: + providers = dict() + for api_provider in args.providers.split(","): + if "=" not in api_provider: + cprint( + "Could not parse `--providers`. Please ensure the list is in the format api1=provider1,api2=provider2", + color="red", + ) + sys.exit(1) + api, provider = api_provider.split("=") + providers_for_api = get_provider_registry().get(Api(api), None) + if providers_for_api is None: + cprint( + f"{api} is not a valid API.", + color="red", + ) + sys.exit(1) + if provider in providers_for_api: + providers.setdefault(api, []).append(provider) + else: + cprint( + f"{provider} is not a valid provider for the {api} API.", + color="red", + ) + sys.exit(1) + distribution_spec = DistributionSpec( + providers=providers, + description=",".join(args.providers), + ) + if not args.image_type: + cprint( + f"Please specify a image-type (container | conda | venv) for {args.template}", + color="red", + ) + sys.exit(1) + + build_config = BuildConfig(image_type=args.image_type, distribution_spec=distribution_spec) elif not args.config and not args.template: name = prompt( "> Enter a name for your Llama Stack (e.g. my-local-stack): ", diff --git a/llama_stack/cli/stack/build.py b/llama_stack/cli/stack/build.py index c511a0682..93e7d9b22 100644 --- a/llama_stack/cli/stack/build.py +++ b/llama_stack/cli/stack/build.py @@ -75,6 +75,12 @@ the build. If not specified, currently active environment will be used if found. default=False, help="Run the stack after building using the same image type, name, and other applicable arguments", ) + self.parser.add_argument( + "--providers", + type=str, + default=None, + help="Build a config for a list of providers and only those providers. This list is formatted like: api1=provider1,api2=provider2. Where there can be multiple providers per API.", + ) def _run_stack_build_command(self, args: argparse.Namespace) -> None: # always keep implementation completely silo-ed away from CLI so CLI