mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-12-17 22:39:47 +00:00
feat: group deps by provider
dependencies are currently installed and listed in an unassociated way with the provider they come from. From a user POV, associating deps with the specific provider introducing them is crucial in order to eliminate unwanted dependences if using a larger distro like starter. For example, If I am using starter on a daily basis but then go `llama stack build --distro starter...` and get 15 NEW dependencies, there is currently NO way for me to tell which provider introduced them. This work fixes the output of the build process and `--print-deps-only` Signed-off-by: Charlie Doern <cdoern@redhat.com>
This commit is contained in:
parent
e195ee3091
commit
268766c72e
4 changed files with 214 additions and 82 deletions
|
|
@ -230,12 +230,31 @@ def run_stack_build_command(args: argparse.Namespace) -> None:
|
||||||
if args.print_deps_only:
|
if args.print_deps_only:
|
||||||
print(f"# Dependencies for {distro_name or args.config or image_name}")
|
print(f"# Dependencies for {distro_name or args.config or image_name}")
|
||||||
normal_deps, special_deps, external_provider_dependencies = get_provider_dependencies(build_config)
|
normal_deps, special_deps, external_provider_dependencies = get_provider_dependencies(build_config)
|
||||||
normal_deps += SERVER_DEPENDENCIES
|
normal_deps["default"] += SERVER_DEPENDENCIES
|
||||||
print(f"uv pip install {' '.join(normal_deps)}")
|
cprint(
|
||||||
for special_dep in special_deps:
|
"Please install needed dependencies using the following commands:",
|
||||||
print(f"uv pip install {special_dep}")
|
color="yellow",
|
||||||
for external_dep in external_provider_dependencies:
|
file=sys.stderr,
|
||||||
print(f"uv pip install {external_dep}")
|
)
|
||||||
|
|
||||||
|
for prov, deps in normal_deps.items():
|
||||||
|
if len(deps) == 0:
|
||||||
|
continue
|
||||||
|
cprint(f"# Normal Dependencies for {prov}", color="yellow")
|
||||||
|
cprint(f"uv pip install {' '.join(deps)}", file=sys.stderr)
|
||||||
|
|
||||||
|
for prov, deps in special_deps.items():
|
||||||
|
if len(deps) == 0:
|
||||||
|
continue
|
||||||
|
cprint(f"# Special Dependencies for {prov}", color="yellow")
|
||||||
|
cprint(f"uv pip install {' '.join(deps)}", file=sys.stderr)
|
||||||
|
|
||||||
|
for prov, deps in external_provider_dependencies.items():
|
||||||
|
if len(deps) == 0:
|
||||||
|
continue
|
||||||
|
cprint(f"# External Provider Dependencies for {prov}", color="yellow")
|
||||||
|
cprint(f"uv pip install {' '.join(deps)}", file=sys.stderr)
|
||||||
|
print()
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
import importlib.resources
|
import importlib.resources
|
||||||
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
@ -41,7 +42,7 @@ class ApiInput(BaseModel):
|
||||||
|
|
||||||
def get_provider_dependencies(
|
def get_provider_dependencies(
|
||||||
config: BuildConfig | DistributionTemplate,
|
config: BuildConfig | DistributionTemplate,
|
||||||
) -> tuple[list[str], list[str], list[str]]:
|
) -> tuple[dict[str, list[str]], dict[str, list[str]], dict[str, list[str]]]:
|
||||||
"""Get normal and special dependencies from provider configuration."""
|
"""Get normal and special dependencies from provider configuration."""
|
||||||
if isinstance(config, DistributionTemplate):
|
if isinstance(config, DistributionTemplate):
|
||||||
config = config.build_config()
|
config = config.build_config()
|
||||||
|
|
@ -49,8 +50,8 @@ def get_provider_dependencies(
|
||||||
providers = config.distribution_spec.providers
|
providers = config.distribution_spec.providers
|
||||||
additional_pip_packages = config.additional_pip_packages
|
additional_pip_packages = config.additional_pip_packages
|
||||||
|
|
||||||
deps = []
|
deps = {}
|
||||||
external_provider_deps = []
|
external_provider_deps = {}
|
||||||
registry = get_provider_registry(config)
|
registry = get_provider_registry(config)
|
||||||
for api_str, provider_or_providers in providers.items():
|
for api_str, provider_or_providers in providers.items():
|
||||||
providers_for_api = registry[Api(api_str)]
|
providers_for_api = registry[Api(api_str)]
|
||||||
|
|
@ -69,37 +70,86 @@ def get_provider_dependencies(
|
||||||
# this ensures we install the top level module for our external providers
|
# this ensures we install the top level module for our external providers
|
||||||
if provider_spec.module:
|
if provider_spec.module:
|
||||||
if isinstance(provider_spec.module, str):
|
if isinstance(provider_spec.module, str):
|
||||||
external_provider_deps.append(provider_spec.module)
|
external_provider_deps.setdefault(provider_spec.provider_type, []).append(provider_spec.module)
|
||||||
else:
|
else:
|
||||||
external_provider_deps.extend(provider_spec.module)
|
external_provider_deps.setdefault(provider_spec.provider_type, []).extend(provider_spec.module)
|
||||||
if hasattr(provider_spec, "pip_packages"):
|
if hasattr(provider_spec, "pip_packages"):
|
||||||
deps.extend(provider_spec.pip_packages)
|
deps.setdefault(provider_spec.provider_type, []).extend(provider_spec.pip_packages)
|
||||||
if hasattr(provider_spec, "container_image") and provider_spec.container_image:
|
if hasattr(provider_spec, "container_image") and provider_spec.container_image:
|
||||||
raise ValueError("A stack's dependencies cannot have a container image")
|
raise ValueError("A stack's dependencies cannot have a container image")
|
||||||
|
|
||||||
normal_deps = []
|
normal_deps = {}
|
||||||
special_deps = []
|
special_deps = {}
|
||||||
for package in deps:
|
for provider, package in deps.items():
|
||||||
if "--no-deps" in package or "--index-url" in package:
|
if any("--no-deps" in s for s in package) or any("--index-url" in s for s in package):
|
||||||
special_deps.append(package)
|
special_deps.setdefault(provider, []).append(package)
|
||||||
else:
|
else:
|
||||||
normal_deps.append(package)
|
normal_deps.setdefault(provider, []).append(package)
|
||||||
|
|
||||||
normal_deps.extend(additional_pip_packages or [])
|
normal_deps["default"] = additional_pip_packages or []
|
||||||
|
|
||||||
return list(set(normal_deps)), list(set(special_deps)), list(set(external_provider_deps))
|
# Helper function to flatten and deduplicate dependencies
|
||||||
|
def flatten_and_dedup(deps_list):
|
||||||
|
flattened = []
|
||||||
|
for item in deps_list:
|
||||||
|
if isinstance(item, list):
|
||||||
|
flattened.extend(item)
|
||||||
|
else:
|
||||||
|
flattened.append(item)
|
||||||
|
return list(set(flattened))
|
||||||
|
|
||||||
|
for key in normal_deps.keys():
|
||||||
|
normal_deps[key] = flatten_and_dedup(normal_deps[key])
|
||||||
|
for key in special_deps.keys():
|
||||||
|
special_deps[key] = flatten_and_dedup(special_deps[key])
|
||||||
|
for key in external_provider_deps.keys():
|
||||||
|
external_provider_deps[key] = flatten_and_dedup(external_provider_deps[key])
|
||||||
|
|
||||||
|
return normal_deps, special_deps, external_provider_deps
|
||||||
|
|
||||||
|
|
||||||
def print_pip_install_help(config: BuildConfig):
|
def print_pip_install_help(config: BuildConfig):
|
||||||
normal_deps, special_deps, _ = get_provider_dependencies(config)
|
normal_deps, special_deps, external_provider_dependencies = get_provider_dependencies(config)
|
||||||
|
normal_deps["default"] += SERVER_DEPENDENCIES
|
||||||
cprint(
|
cprint(
|
||||||
f"Please install needed dependencies using the following commands:\n\nuv pip install {' '.join(normal_deps)}",
|
"Please install needed dependencies using the following commands:",
|
||||||
color="yellow",
|
color="yellow",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
for special_dep in special_deps:
|
|
||||||
cprint(f"uv pip install {special_dep}", color="yellow", file=sys.stderr)
|
for provider, deps in normal_deps.items():
|
||||||
|
if len(deps) == 0:
|
||||||
|
continue
|
||||||
|
cprint(f"# Normal Dependencies for {provider}", color="yellow")
|
||||||
|
cprint(f"uv pip install {' '.join(deps)}", file=sys.stderr)
|
||||||
|
|
||||||
|
for provider, deps in special_deps.items():
|
||||||
|
if len(deps) == 0:
|
||||||
|
continue
|
||||||
|
cprint(f"# Special Dependencies for {provider}", color="yellow")
|
||||||
|
cprint(f"uv pip install {' '.join(deps)}", file=sys.stderr)
|
||||||
|
|
||||||
|
for provider, deps in external_provider_dependencies.items():
|
||||||
|
if len(deps) == 0:
|
||||||
|
continue
|
||||||
|
cprint(f"# External Provider Dependencies for {provider}", color="yellow")
|
||||||
|
cprint(f"uv pip install {' '.join(deps)}", file=sys.stderr)
|
||||||
|
print()
|
||||||
|
return
|
||||||
|
|
||||||
|
cprint(
|
||||||
|
"Please install needed dependencies using the following commands:",
|
||||||
|
color="yellow",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
|
||||||
|
for provider, deps in normal_deps.items():
|
||||||
|
cprint(f"# Normal Dependencies for {provider}")
|
||||||
|
cprint(f"uv pip install {deps}", color="yellow", file=sys.stderr)
|
||||||
|
|
||||||
|
for provider, deps in special_deps.items():
|
||||||
|
cprint(f"# Special Dependencies for {provider}")
|
||||||
|
cprint(f"uv pip install {deps}", color="yellow", file=sys.stderr)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -112,12 +162,12 @@ def build_image(
|
||||||
container_base = build_config.distribution_spec.container_image or "python:3.12-slim"
|
container_base = build_config.distribution_spec.container_image or "python:3.12-slim"
|
||||||
|
|
||||||
normal_deps, special_deps, external_provider_deps = get_provider_dependencies(build_config)
|
normal_deps, special_deps, external_provider_deps = get_provider_dependencies(build_config)
|
||||||
normal_deps += SERVER_DEPENDENCIES
|
normal_deps["default"] += SERVER_DEPENDENCIES
|
||||||
if build_config.external_apis_dir:
|
if build_config.external_apis_dir:
|
||||||
external_apis = load_external_apis(build_config)
|
external_apis = load_external_apis(build_config)
|
||||||
if external_apis:
|
if external_apis:
|
||||||
for _, api_spec in external_apis.items():
|
for _, api_spec in external_apis.items():
|
||||||
normal_deps.extend(api_spec.pip_packages)
|
normal_deps["default"].extend(api_spec.pip_packages)
|
||||||
|
|
||||||
if build_config.image_type == LlamaStackImageType.CONTAINER.value:
|
if build_config.image_type == LlamaStackImageType.CONTAINER.value:
|
||||||
script = str(importlib.resources.files("llama_stack") / "core/build_container.sh")
|
script = str(importlib.resources.files("llama_stack") / "core/build_container.sh")
|
||||||
|
|
@ -130,7 +180,7 @@ def build_image(
|
||||||
"--container-base",
|
"--container-base",
|
||||||
container_base,
|
container_base,
|
||||||
"--normal-deps",
|
"--normal-deps",
|
||||||
" ".join(normal_deps),
|
json.dumps(normal_deps),
|
||||||
]
|
]
|
||||||
# When building from a config file (not a template), include the run config path in the
|
# When building from a config file (not a template), include the run config path in the
|
||||||
# build arguments
|
# build arguments
|
||||||
|
|
@ -143,15 +193,15 @@ def build_image(
|
||||||
"--env-name",
|
"--env-name",
|
||||||
str(image_name),
|
str(image_name),
|
||||||
"--normal-deps",
|
"--normal-deps",
|
||||||
" ".join(normal_deps),
|
json.dumps(normal_deps),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Always pass both arguments, even if empty, to maintain consistent positional arguments
|
# Always pass both arguments, even if empty, to maintain consistent positional arguments
|
||||||
if special_deps:
|
if special_deps:
|
||||||
args.extend(["--optional-deps", "#".join(special_deps)])
|
args.extend(["--optional-deps", json.dumps(special_deps)])
|
||||||
if external_provider_deps:
|
if external_provider_deps:
|
||||||
args.extend(
|
args.extend(
|
||||||
["--external-provider-deps", "#".join(external_provider_deps)]
|
["--external-provider-deps", json.dumps(external_provider_deps)]
|
||||||
) # the script will install external provider module, get its deps, and install those too.
|
) # the script will install external provider module, get its deps, and install those too.
|
||||||
|
|
||||||
return_code = run_command(args)
|
return_code = run_command(args)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ NC='\033[0m' # No Color
|
||||||
# Usage function
|
# Usage function
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 --image-name <image_name> --container-base <container_base> --normal-deps <pip_dependencies> [--run-config <run_config>] [--external-provider-deps <external_provider_deps>] [--optional-deps <special_pip_deps>]"
|
echo "Usage: $0 --image-name <image_name> --container-base <container_base> --normal-deps <pip_dependencies> [--run-config <run_config>] [--external-provider-deps <external_provider_deps>] [--optional-deps <special_pip_deps>]"
|
||||||
echo "Example: $0 --image-name llama-stack-img --container-base python:3.12-slim --normal-deps 'numpy pandas' --run-config ./run.yaml --external-provider-deps 'foo' --optional-deps 'bar'"
|
echo "Example: $0 --image-name llama-stack-img --container-base python:3.12-slim --normal-deps '{\"default\": [\"numpy\", \"pandas\"]}' --run-config ./run.yaml --external-provider-deps '{\"vector_db\": [\"chromadb\"]}' --optional-deps '{\"special\": [\"bar\"]}'"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +74,7 @@ while [[ $# -gt 0 ]]; do
|
||||||
;;
|
;;
|
||||||
--external-provider-deps)
|
--external-provider-deps)
|
||||||
if [[ -z "$2" || "$2" == --* ]]; then
|
if [[ -z "$2" || "$2" == --* ]]; then
|
||||||
echo "Error: --external-provider-deps requires a string value" >&2
|
echo "Error: --external-provider-deps requires a JSON object" >&2
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
external_provider_deps="$2"
|
external_provider_deps="$2"
|
||||||
|
|
@ -175,33 +175,30 @@ fi
|
||||||
# Add pip dependencies first since llama-stack is what will change most often
|
# Add pip dependencies first since llama-stack is what will change most often
|
||||||
# so we can reuse layers.
|
# so we can reuse layers.
|
||||||
if [ -n "$normal_deps" ]; then
|
if [ -n "$normal_deps" ]; then
|
||||||
read -ra pip_args <<< "$normal_deps"
|
# Parse JSON and install dependencies for each provider
|
||||||
quoted_deps=$(printf " %q" "${pip_args[@]}")
|
echo "$normal_deps" | jq -r 'to_entries[] | "\(.key)\t\(.value | join(" "))"' | while IFS=$'\t' read -r provider deps; do
|
||||||
add_to_container << EOF
|
if [ -n "$deps" ]; then
|
||||||
RUN uv pip install --no-cache $quoted_deps
|
echo "Installing normal dependencies for provider '$provider'"
|
||||||
EOF
|
read -ra pip_args <<< "$deps"
|
||||||
fi
|
quoted_deps=$(printf " %q" "${pip_args[@]}")
|
||||||
|
add_to_container <<EOF
|
||||||
if [ -n "$optional_deps" ]; then
|
|
||||||
IFS='#' read -ra parts <<<"$optional_deps"
|
|
||||||
for part in "${parts[@]}"; do
|
|
||||||
read -ra pip_args <<< "$part"
|
|
||||||
quoted_deps=$(printf " %q" "${pip_args[@]}")
|
|
||||||
add_to_container <<EOF
|
|
||||||
RUN uv pip install --no-cache $quoted_deps
|
RUN uv pip install --no-cache $quoted_deps
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$external_provider_deps" ]; then
|
if [ -n "$external_provider_deps" ]; then
|
||||||
IFS='#' read -ra parts <<<"$external_provider_deps"
|
echo "Installing external provider dependencies from JSON: $external_provider_deps"
|
||||||
for part in "${parts[@]}"; do
|
# Parse JSON and iterate packages only (no flags or URLs assumed)
|
||||||
read -ra pip_args <<< "$part"
|
echo "$external_provider_deps" | jq -r 'to_entries[] | .value[]' | while read -r part; do
|
||||||
quoted_deps=$(printf " %q" "${pip_args[@]}")
|
if [ -n "$part" ]; then
|
||||||
add_to_container <<EOF
|
echo "Installing external provider module: $part"
|
||||||
RUN uv pip install --no-cache $quoted_deps
|
add_to_container <<EOF
|
||||||
|
RUN uv pip install --no-cache $part
|
||||||
EOF
|
EOF
|
||||||
add_to_container <<EOF
|
echo "Getting provider spec for module: $part"
|
||||||
|
add_to_container <<EOF
|
||||||
RUN python3 - <<PYTHON | uv pip install --no-cache -r -
|
RUN python3 - <<PYTHON | uv pip install --no-cache -r -
|
||||||
import importlib
|
import importlib
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -217,6 +214,28 @@ except Exception as e:
|
||||||
print(f'Error getting provider spec for {package_name}: {e}', file=sys.stderr)
|
print(f'Error getting provider spec for {package_name}: {e}', file=sys.stderr)
|
||||||
PYTHON
|
PYTHON
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$optional_deps" ]; then
|
||||||
|
echo "Installing optional dependencies from JSON: $optional_deps"
|
||||||
|
# For optional deps, process each spec separately to preserve flags like --no-deps
|
||||||
|
last_provider=""
|
||||||
|
echo "$optional_deps" | jq -r 'to_entries[] | .key as $k | .value[] | "\($k)\t\(.)"' | while IFS=$'\t' read -r provider spec; do
|
||||||
|
if [ -n "$spec" ]; then
|
||||||
|
if [ "$provider" != "$last_provider" ]; then
|
||||||
|
echo "Installing optional dependencies for provider '$provider'"
|
||||||
|
last_provider="$provider"
|
||||||
|
fi
|
||||||
|
echo "Installing dependency: $spec"
|
||||||
|
# Split spec into args and install
|
||||||
|
read -r -a pip_args <<< "$spec"
|
||||||
|
quoted_deps=$(printf " %q" "${pip_args[@]}")
|
||||||
|
add_to_container <<EOF
|
||||||
|
RUN uv pip install --no-cache $quoted_deps
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ source "$SCRIPT_DIR/common.sh"
|
||||||
# Usage function
|
# Usage function
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 --env-name <env_name> --normal-deps <pip_dependencies> [--external-provider-deps <external_provider_deps>] [--optional-deps <special_pip_deps>]"
|
echo "Usage: $0 --env-name <env_name> --normal-deps <pip_dependencies> [--external-provider-deps <external_provider_deps>] [--optional-deps <special_pip_deps>]"
|
||||||
echo "Example: $0 --env-name mybuild --normal-deps 'numpy pandas scipy' --external-provider-deps 'foo' --optional-deps 'bar'"
|
echo "Example: $0 --env-name mybuild --normal-deps '{\"default\": [\"numpy\", \"pandas\"]}' --external-provider-deps '{\"vector_db\": [\"chromadb\"]}' --optional-deps '{\"special\": [\"bar\"]}'"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ while [[ $# -gt 0 ]]; do
|
||||||
;;
|
;;
|
||||||
--normal-deps)
|
--normal-deps)
|
||||||
if [[ -z "$2" || "$2" == --* ]]; then
|
if [[ -z "$2" || "$2" == --* ]]; then
|
||||||
echo "Error: --normal-deps requires a string value" >&2
|
echo "Error: --normal-deps requires a JSON object" >&2
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
normal_deps="$2"
|
normal_deps="$2"
|
||||||
|
|
@ -58,7 +58,7 @@ while [[ $# -gt 0 ]]; do
|
||||||
;;
|
;;
|
||||||
--external-provider-deps)
|
--external-provider-deps)
|
||||||
if [[ -z "$2" || "$2" == --* ]]; then
|
if [[ -z "$2" || "$2" == --* ]]; then
|
||||||
echo "Error: --external-provider-deps requires a string value" >&2
|
echo "Error: --external-provider-deps requires a JSON object" >&2
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
external_provider_deps="$2"
|
external_provider_deps="$2"
|
||||||
|
|
@ -66,7 +66,7 @@ while [[ $# -gt 0 ]]; do
|
||||||
;;
|
;;
|
||||||
--optional-deps)
|
--optional-deps)
|
||||||
if [[ -z "$2" || "$2" == --* ]]; then
|
if [[ -z "$2" || "$2" == --* ]]; then
|
||||||
echo "Error: --optional-deps requires a string value" >&2
|
echo "Error: --optional-deps requires a JSON object" >&2
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
optional_deps="$2"
|
optional_deps="$2"
|
||||||
|
|
@ -116,6 +116,36 @@ pre_run_checks() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Function to install dependencies from JSON object
|
||||||
|
install_deps_from_json() {
|
||||||
|
local json_deps="$1"
|
||||||
|
local dep_type="$2"
|
||||||
|
|
||||||
|
if [ -n "$json_deps" ]; then
|
||||||
|
if [ "$dep_type" = "optional" ]; then
|
||||||
|
# For optional deps, process each spec separately to preserve flags like --no-deps
|
||||||
|
local last_provider=""
|
||||||
|
echo "$json_deps" | jq -r 'to_entries[] | .key as $k | .value[] | "\($k)\t\(.)"' | while IFS=$'\t' read -r provider spec; do
|
||||||
|
if [ -n "$spec" ]; then
|
||||||
|
if [ "$provider" != "$last_provider" ]; then
|
||||||
|
echo "Installing $dep_type dependencies for provider '$provider'"
|
||||||
|
last_provider="$provider"
|
||||||
|
fi
|
||||||
|
uv pip install $spec
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# For normal deps, install all at once (no special flags)
|
||||||
|
echo "$json_deps" | jq -r 'to_entries[] | "\(.key)\t\(.value | join(" "))"' | while IFS=$'\t' read -r provider deps; do
|
||||||
|
if [ -n "$deps" ]; then
|
||||||
|
echo "Installing $dep_type dependencies for provider '$provider'"
|
||||||
|
uv pip install $deps
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
# Use only global variables set by flag parser
|
# Use only global variables set by flag parser
|
||||||
if [ -n "$UV_SYSTEM_PYTHON" ] || [ "$env_name" == "__system__" ]; then
|
if [ -n "$UV_SYSTEM_PYTHON" ] || [ "$env_name" == "__system__" ]; then
|
||||||
|
|
@ -136,17 +166,29 @@ run() {
|
||||||
llama-stack=="$TEST_PYPI_VERSION" \
|
llama-stack=="$TEST_PYPI_VERSION" \
|
||||||
$normal_deps
|
$normal_deps
|
||||||
if [ -n "$optional_deps" ]; then
|
if [ -n "$optional_deps" ]; then
|
||||||
IFS='#' read -ra parts <<<"$optional_deps"
|
install_deps_from_json "$optional_deps" "optional"
|
||||||
for part in "${parts[@]}"; do
|
|
||||||
echo "$part"
|
|
||||||
uv pip install $part
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
if [ -n "$external_provider_deps" ]; then
|
if [ -n "$external_provider_deps" ]; then
|
||||||
IFS='#' read -ra parts <<<"$external_provider_deps"
|
# Install external provider modules (no special flags supported)
|
||||||
for part in "${parts[@]}"; do
|
echo "Installing external provider modules"
|
||||||
echo "$part"
|
echo "$external_provider_deps" | jq -r 'to_entries[] | .value[]' | while read -r part; do
|
||||||
uv pip install "$part"
|
if [ -n "$part" ]; then
|
||||||
|
echo "Installing external provider module: $part"
|
||||||
|
uv pip install "$part"
|
||||||
|
echo "Getting provider spec for module: $part and installing dependencies"
|
||||||
|
package_name=$(echo "$part" | sed 's/[<>=!].*//')
|
||||||
|
python3 -c "
|
||||||
|
import importlib
|
||||||
|
import sys
|
||||||
|
try:
|
||||||
|
module = importlib.import_module(f'$package_name.provider')
|
||||||
|
spec = module.get_provider_spec()
|
||||||
|
if hasattr(spec, 'pip_packages') and spec.pip_packages:
|
||||||
|
print('\\n'.join(spec.pip_packages))
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error getting provider spec for $package_name: {e}', file=sys.stderr)
|
||||||
|
" | uv pip install -r -
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
|
@ -163,9 +205,9 @@ run() {
|
||||||
else
|
else
|
||||||
EDITABLE=""
|
EDITABLE=""
|
||||||
fi
|
fi
|
||||||
uv pip install --no-cache-dir $EDITABLE "$LLAMA_STACK_DIR"
|
uv pip install --no-cache-dir --quiet $EDITABLE "$LLAMA_STACK_DIR"
|
||||||
else
|
else
|
||||||
uv pip install --no-cache-dir llama-stack
|
uv pip install --no-cache-dir --quiet llama-stack
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then
|
if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then
|
||||||
|
|
@ -181,26 +223,26 @@ run() {
|
||||||
else
|
else
|
||||||
EDITABLE=""
|
EDITABLE=""
|
||||||
fi
|
fi
|
||||||
uv pip install --no-cache-dir $EDITABLE "$LLAMA_STACK_CLIENT_DIR"
|
uv pip install --no-cache-dir --quiet $EDITABLE "$LLAMA_STACK_CLIENT_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "Installing pip dependencies\n"
|
printf "Installing pip dependencies\n"
|
||||||
uv pip install $normal_deps
|
install_deps_from_json "$normal_deps" "normal"
|
||||||
if [ -n "$optional_deps" ]; then
|
if [ -n "$optional_deps" ]; then
|
||||||
IFS='#' read -ra parts <<<"$optional_deps"
|
install_deps_from_json "$optional_deps" "optional"
|
||||||
for part in "${parts[@]}"; do
|
|
||||||
echo "Installing special provider module: $part"
|
|
||||||
uv pip install $part
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
if [ -n "$external_provider_deps" ]; then
|
if [ -n "$external_provider_deps" ]; then
|
||||||
IFS='#' read -ra parts <<<"$external_provider_deps"
|
install_deps_from_json "$external_provider_deps" "external provider"
|
||||||
for part in "${parts[@]}"; do
|
|
||||||
echo "Installing external provider module: $part"
|
# For external provider deps, also get and install their dependencies
|
||||||
uv pip install "$part"
|
echo "Getting provider specs and installing dependencies for external providers"
|
||||||
echo "Getting provider spec for module: $part and installing dependencies"
|
echo "$external_provider_deps" | jq -r 'to_entries[] | "\(.key) \(.value | join(" "))"' | while read -r provider deps; do
|
||||||
package_name=$(echo "$part" | sed 's/[<>=!].*//')
|
if [ -n "$deps" ]; then
|
||||||
python3 -c "
|
echo "Getting provider specs for provider '$provider' dependencies: $deps"
|
||||||
|
for dep in $deps; do
|
||||||
|
package_name=$(echo "$dep" | sed 's/[<>=!].*//')
|
||||||
|
echo "Getting provider spec for module: $package_name"
|
||||||
|
python3 -c "
|
||||||
import importlib
|
import importlib
|
||||||
import sys
|
import sys
|
||||||
try:
|
try:
|
||||||
|
|
@ -211,6 +253,8 @@ try:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'Error getting provider spec for $package_name: {e}', file=sys.stderr)
|
print(f'Error getting provider spec for $package_name: {e}', file=sys.stderr)
|
||||||
" | uv pip install -r -
|
" | uv pip install -r -
|
||||||
|
done
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue