diff --git a/docs/getting_started.md b/docs/getting_started.md index cf761cce0..0ab3461dd 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -8,43 +8,61 @@ This guides allows you to quickly get started with building and running a Llama - Quick 3 line command to build and start a LlamaStack server using our Meta Reference implementation for all API endpoints with `conda` as build type. **`llama stack build`** +- You'll be prompted to enter build information interactively. ``` -llama stack build ./llama_stack/distribution/example_configs/conda/local-conda-example-build.yaml --name my-local-llama-stack -... -... -Build spec configuration saved at ~/.llama/distributions/conda/my-local-llama-stack-build.yaml +llama stack build + +> Enter an unique name for identifying your Llama Stack build distribution (e.g. my-local-stack): my-local-llama-stack +> Enter the image type you want your distribution to be built with (docker or conda): conda + + Llama Stack is composed of several APIs working together. Let's configure the providers (implementations) you want to use for these APIs. +> Enter the API provider for the inference API: (default=meta-reference): meta-reference +> Enter the API provider for the safety API: (default=meta-reference): meta-reference +> Enter the API provider for the agents API: (default=meta-reference): meta-reference +> Enter the API provider for the memory API: (default=meta-reference): meta-reference +> Enter the API provider for the telemetry API: (default=meta-reference): meta-reference + + > (Optional) Enter a short description for your Llama Stack distribution: + +Build spec configuration saved at ~/.conda/envs/llamastack-my-local-llama-stack/my-local-llama-stack-build.yaml ``` **`llama stack configure`** ``` -llama stack configure ~/.llama/distributions/conda/my-local-llama-stack-build.yaml +llama stack configure my-local-llama-stack -Configuring API: inference (meta-reference) +Configuring APIs to serve... +Enter comma-separated list of APIs to serve: + +Configuring API `inference`... + +Configuring provider `meta-reference`... Enter value for model (default: Meta-Llama3.1-8B-Instruct) (required): -Enter value for quantization (optional): +Do you want to configure quantization? (y/n): n Enter value for torch_seed (optional): Enter value for max_seq_len (required): 4096 Enter value for max_batch_size (default: 1) (required): +Configuring API `safety`... -Configuring API: memory (meta-reference-faiss) - -Configuring API: safety (meta-reference) +Configuring provider `meta-reference`... Do you want to configure llama_guard_shield? (y/n): n Do you want to configure prompt_guard_shield? (y/n): n +Configuring API `agents`... -Configuring API: agentic_system (meta-reference) -Enter value for brave_search_api_key (optional): -Enter value for bing_search_api_key (optional): -Enter value for wolfram_api_key (optional): +Configuring provider `meta-reference`... +Configuring API `memory`... -Configuring API: telemetry (console) +Configuring provider `meta-reference`... +Configuring API `telemetry`... -YAML configuration has been written to ~/.llama/builds/conda/my-local-llama-stack-run.yaml +Configuring provider `meta-reference`... +> YAML configuration has been written to /home/xiyan/.llama/builds/conda/my-local-llama-stack-run.yaml. +You can now run `llama stack run my-local-llama-stack --port PORT` or `llama stack run /home/xiyan/.llama/builds/conda/my-local-llama-stack-run.yaml --port PORT ``` **`llama stack run`** ``` -llama stack run ~/.llama/builds/conda/my-local-llama-stack-run.yaml +llama stack run my-local-llama-stack ... > initializing model parallel with size 1 diff --git a/llama_stack/cli/stack/build.py b/llama_stack/cli/stack/build.py index f6f79b621..e49da58f0 100644 --- a/llama_stack/cli/stack/build.py +++ b/llama_stack/cli/stack/build.py @@ -29,7 +29,9 @@ class StackBuild(Subcommand): self.parser.add_argument( "config", type=str, - help="Path to a config file to use for the build. You may find example configs in llama_stack/distribution/example_configs", + default=None, + nargs="*", + help="Path to a config file to use for the build. You can find example configs in llama_stack/distribution/example_configs. If this argument is not provided, you will be prompted to enter information interactively", ) self.parser.add_argument( @@ -44,9 +46,10 @@ class StackBuild(Subcommand): import json import os + from llama_stack.distribution.build import ApiInput, build_image, ImageType + from llama_stack.distribution.utils.config_dirs import DISTRIBS_BASE_DIR from llama_stack.distribution.utils.serialize import EnumEncoder - from llama_stack.distribution.build import ApiInput, build_image, ImageType from termcolor import cprint # save build.yaml spec for building same distribution again @@ -57,7 +60,10 @@ class StackBuild(Subcommand): llama_stack_path / "configs/distributions" / build_config.image_type ) else: - build_dir = DISTRIBS_BASE_DIR / build_config.image_type + build_dir = ( + Path(os.getenv("CONDA_PREFIX")).parent + / f"llamastack-{build_config.name}" + ) os.makedirs(build_dir, exist_ok=True) build_file_path = build_dir / f"{build_config.name}-build.yaml" @@ -70,17 +76,76 @@ class StackBuild(Subcommand): cprint( f"Build spec configuration saved at {str(build_file_path)}", + color="blue", + ) + cprint( + f"You may now run `llama stack configure {build_config.name}` or `llama stack configure {str(build_file_path)}`", color="green", ) def _run_stack_build_command(self, args: argparse.Namespace) -> None: - from llama_stack.distribution.utils.prompt_for_config import prompt_for_config + from llama_stack.distribution.distribution import Api, api_providers from llama_stack.distribution.utils.dynamic import instantiate_class_type + from prompt_toolkit import prompt + from prompt_toolkit.validation import Validator + from termcolor import cprint if not args.config: - self.parser.error( - "No config file specified. Please use `llama stack build /path/to/*-build.yaml`. Example config files can be found in llama_stack/distribution/example_configs" + name = prompt( + "> Enter a unique name for identifying your Llama Stack build (e.g. my-local-stack): " ) + image_type = prompt( + "> Enter the image type you want your Llama Stack to be built as (docker or conda): ", + validator=Validator.from_callable( + lambda x: x in ["docker", "conda"], + error_message="Invalid image type, please enter conda or docker", + ), + default="conda", + ) + + cprint( + f"\n Llama Stack is composed of several APIs working together. Let's configure the providers (implementations) you want to use for these APIs.", + color="green", + ) + + providers = dict() + for api in Api: + all_providers = api_providers() + providers_for_api = all_providers[api] + + api_provider = prompt( + "> Enter the API provider for the {} API: (default=meta-reference): ".format( + api.value + ), + validator=Validator.from_callable( + lambda x: x in providers_for_api, + error_message="Invalid provider, please enter one of the following: {}".format( + providers_for_api.keys() + ), + ), + default=( + "meta-reference" + if "meta-reference" in providers_for_api + else list(providers_for_api.keys())[0] + ), + ) + + providers[api.value] = api_provider + + description = prompt( + "\n > (Optional) Enter a short description for your Llama Stack: ", + default="", + ) + + distribution_spec = DistributionSpec( + providers=providers, + description=description, + ) + + build_config = BuildConfig( + name=name, image_type=image_type, distribution_spec=distribution_spec + ) + self._run_stack_build_command_from_build_config(build_config) return with open(args.config, "r") as f: diff --git a/llama_stack/cli/stack/configure.py b/llama_stack/cli/stack/configure.py index c184a1db5..6b3b53f3e 100644 --- a/llama_stack/cli/stack/configure.py +++ b/llama_stack/cli/stack/configure.py @@ -9,7 +9,6 @@ import json from pathlib import Path import yaml -from termcolor import cprint from llama_stack.cli.subcommand import Subcommand from llama_stack.distribution.utils.config_dirs import BUILDS_BASE_DIR @@ -50,9 +49,12 @@ class StackConfigure(Subcommand): import pkg_resources from llama_stack.distribution.build import ImageType + from termcolor import cprint docker_image = None - build_config_file = Path(args.config) + conda_dir = Path(os.getenv("CONDA_PREFIX")).parent / f"llamastack-{args.config}" + build_config_file = Path(conda_dir) / f"{args.config}-build.yaml" + if not build_config_file.exists(): cprint( f"Could not find {build_config_file}. Trying docker image name instead...", @@ -79,8 +81,9 @@ class StackConfigure(Subcommand): ) build_name = docker_image.removeprefix("llamastack-") + saved_file = str(builds_dir / f"{build_name}-run.yaml") cprint( - f"YAML configuration has been written to {builds_dir / f'{build_name}-run.yaml'}", + f"YAML configuration has been written to {saved_file}. You can now run `llama stack run {saved_file}`", color="green", ) return @@ -97,6 +100,7 @@ class StackConfigure(Subcommand): ): from llama_stack.distribution.configure import configure_api_providers from llama_stack.distribution.utils.serialize import EnumEncoder + from termcolor import cprint builds_dir = BUILDS_BASE_DIR / build_config.image_type if output_dir: @@ -132,6 +136,11 @@ class StackConfigure(Subcommand): f.write(yaml.dump(to_write, sort_keys=False)) cprint( - f"> YAML configuration has been written to {run_config_file}", + f"> YAML configuration has been written to {run_config_file}.", color="blue", ) + + cprint( + f"You can now run `llama stack run {image_name} --port PORT` or `llama stack run {run_config_file} --port PORT`", + color="green", + ) diff --git a/llama_stack/cli/stack/run.py b/llama_stack/cli/stack/run.py index 29fec608e..95d91aa05 100644 --- a/llama_stack/cli/stack/run.py +++ b/llama_stack/cli/stack/run.py @@ -47,6 +47,8 @@ class StackRun(Subcommand): def _run_stack_run_cmd(self, args: argparse.Namespace) -> None: import pkg_resources + from llama_stack.distribution.build import ImageType + from llama_stack.distribution.utils.config_dirs import BUILDS_BASE_DIR from llama_stack.distribution.utils.exec import run_with_pty @@ -54,12 +56,22 @@ class StackRun(Subcommand): self.parser.error("Must specify a config file to run") return - path = args.config - config_file = Path(path) + config_file = Path(args.config) + if not config_file.exists() and not args.config.endswith(".yaml"): + # check if it's a build config saved to conda dir + config_file = Path( + BUILDS_BASE_DIR / ImageType.conda.value / f"{args.config}-run.yaml" + ) + + if not config_file.exists() and not args.config.endswith(".yaml"): + # check if it's a build config saved to docker dir + config_file = Path( + BUILDS_BASE_DIR / ImageType.docker.value / f"{args.config}-run.yaml" + ) if not config_file.exists(): self.parser.error( - f"File {str(config_file)} does not exist. Did you run `llama stack build`?" + f"File {str(config_file)} does not exist. Please run `llama stack build` and `llama stack configure ` to generate a run.yaml file" ) return