Skip to content

Commit f00bcd9

Browse files
authored
feat: allow for multiple external provider specs (#3341)
# What does this PR do? when using the providers.d method of installation users could hand craft their AdapterSpec's to use overlapping code meaning one repo could contain an inline and remote impl. Currently installing a provider via module does not allow for that as each repo is only allowed to have one `get_provider_spec` method with one Spec returned add an optional way for `get_provider_spec` to return a list of `ProviderSpec` where each can be either an inline or remote impl. Note: the `adapter_type` in `get_provider_spec` MUST match the `provider_type` in the build/run yaml for this to work. resolves #3226 ## Test Plan once this merges we need to re-enable the external provider test and account for this functionality. Work needs to be done in the external provider repos to support this functionality. Signed-off-by: Charlie Doern <[email protected]>
1 parent 426cac0 commit f00bcd9

File tree

2 files changed

+479
-3
lines changed

2 files changed

+479
-3
lines changed

llama_stack/core/distribution.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ def get_external_providers_from_module(
243243
spec = module.get_provider_spec()
244244
else:
245245
# pass in a partially filled out provider spec to satisfy the registry -- knowing we will be overwriting it later upon build and run
246+
# in the case we are building we CANNOT import this module of course because it has not been installed.
246247
spec = ProviderSpec(
247248
api=Api(provider_api),
248249
provider_type=provider.provider_type,
@@ -251,9 +252,20 @@ def get_external_providers_from_module(
251252
config_class="",
252253
)
253254
provider_type = provider.provider_type
254-
# in the case we are building we CANNOT import this module of course because it has not been installed.
255-
# return a partially filled out spec that the build script will populate.
256-
registry[Api(provider_api)][provider_type] = spec
255+
if isinstance(spec, list):
256+
# optionally allow people to pass inline and remote provider specs as a returned list.
257+
# with the old method, users could pass in directories of specs using overlapping code
258+
# we want to ensure we preserve that flexibility in this method.
259+
logger.info(
260+
f"Detected a list of external provider specs from {provider.module} adding all to the registry"
261+
)
262+
for provider_spec in spec:
263+
if provider_spec.provider_type != provider.provider_type:
264+
continue
265+
logger.info(f"Adding {provider.provider_type} to registry")
266+
registry[Api(provider_api)][provider.provider_type] = provider_spec
267+
else:
268+
registry[Api(provider_api)][provider_type] = spec
257269
except ModuleNotFoundError as exc:
258270
raise ValueError(
259271
"get_provider_spec not found. If specifying an external provider via `module` in the Provider spec, the Provider must have the `provider.get_provider_spec` module available"

0 commit comments

Comments
 (0)