Skip to content

Commit 936b57f

Browse files
authored
Merge branch 'main' into gpu-skip
2 parents 1dd29d8 + 61a4b25 commit 936b57f

File tree

12 files changed

+223
-131
lines changed

12 files changed

+223
-131
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ dependencies = [
7070
"marshmallow==3.26.2,<4", # this version is needed for pytest-jira
7171
"pytest-html>=4.1.1",
7272
"fire",
73-
"llama_stack_client>=0.3.0,<0.4",
73+
"llama_stack_client>=0.4.0,<0.5",
7474
"pytest-xdist==3.8.0",
7575
"dictdiffer>=0.9.0",
7676
"pytest>=9.0.0",

tests/llama_stack/conftest.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ def llama_stack_models(unprivileged_llama_stack_client: LlamaStackClient) -> Mod
652652
"""
653653
models = unprivileged_llama_stack_client.models.list()
654654

655-
model_id = next(m for m in models if m.api_model_type == "llm").identifier
655+
model_id = next(m for m in models if m.custom_metadata["model_type"] == "llm").id
656656

657657
# Ensure getting the right embedding model depending on the available providers
658658
providers = unprivileged_llama_stack_client.providers.list()
@@ -664,11 +664,15 @@ def llama_stack_models(unprivileged_llama_stack_client: LlamaStackClient) -> Mod
664664
else:
665665
raise ValueError("No embedding provider found")
666666

667-
embedding_model = next(m for m in models if m.api_model_type == "embedding" and m.provider_id == target_provider_id)
668-
embedding_dimension = float(embedding_model.metadata["embedding_dimension"])
667+
embedding_model = next(
668+
m
669+
for m in models
670+
if m.custom_metadata["model_type"] == "embedding" and m.custom_metadata["provider_id"] == target_provider_id
671+
)
672+
embedding_dimension = int(embedding_model.custom_metadata["embedding_dimension"])
669673

670674
LOGGER.info(f"Detected model: {model_id}")
671-
LOGGER.info(f"Detected embedding_model: {embedding_model.identifier}")
675+
LOGGER.info(f"Detected embedding_model: {embedding_model.id}")
672676
LOGGER.info(f"Detected embedding_dimension: {embedding_dimension}")
673677

674678
return ModelInfo(model_id=model_id, embedding_model=embedding_model, embedding_dimension=embedding_dimension)
@@ -700,7 +704,7 @@ def vector_store(
700704
vector_store = unprivileged_llama_stack_client.vector_stores.create(
701705
name="test_vector_store",
702706
extra_body={
703-
"embedding_model": llama_stack_models.embedding_model.identifier,
707+
"embedding_model": llama_stack_models.embedding_model.id,
704708
"embedding_dimension": llama_stack_models.embedding_dimension,
705709
"provider_id": vector_io_provider,
706710
},

tests/llama_stack/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ModelInfo(NamedTuple):
2626

2727
model_id: str
2828
embedding_model: Model
29-
embedding_dimension: float # API returns float (e.g., 768.0) despite being conceptually an integer
29+
embedding_dimension: int # API returns integer (e.g., 768)
3030

3131

3232
LLS_CORE_POD_FILTER: str = "app=llama-stack"

tests/llama_stack/inference/test_embeddings.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def test_inference_embeddings(
5050

5151
# Embed single input text with encoding_format=float (the returned embedding item is a list of floats)
5252
embeddings_response = unprivileged_llama_stack_client.embeddings.create(
53-
model=llama_stack_models.embedding_model.identifier,
53+
model=llama_stack_models.embedding_model.id,
5454
input="The food was delicious and the waiter...",
5555
encoding_format="float",
5656
)
@@ -63,7 +63,7 @@ def test_inference_embeddings(
6363
# Embed single input text with encoding_format=base64 (the returned embedding item is
6464
# a single base64-encoded string)
6565
embeddings_response = unprivileged_llama_stack_client.embeddings.create(
66-
model=llama_stack_models.embedding_model.identifier,
66+
model=llama_stack_models.embedding_model.id,
6767
input="The food was delicious and the waiter...",
6868
encoding_format="base64",
6969
)
@@ -74,7 +74,7 @@ def test_inference_embeddings(
7474
# Embed multiple input sets with encoding_format=float (each returned embedding item is a list of floats)
7575
input_list = ["Input text 1", "Input text 1", "Input text 1"]
7676
embeddings_response = unprivileged_llama_stack_client.embeddings.create(
77-
model=llama_stack_models.embedding_model.identifier, input=input_list, encoding_format="float"
77+
model=llama_stack_models.embedding_model.id, input=input_list, encoding_format="float"
7878
)
7979
assert isinstance(embeddings_response, CreateEmbeddingsResponse)
8080
assert len(embeddings_response.data) == len(input_list)
@@ -86,7 +86,7 @@ def test_inference_embeddings(
8686
# Embed multiple input sets with base64 encoding format (each returned embedding a single base64-encoded string)
8787
input_list = ["Input text 1", "Input text 1", "Input text 1"]
8888
embeddings_response = unprivileged_llama_stack_client.embeddings.create(
89-
model=llama_stack_models.embedding_model.identifier, input=input_list, encoding_format="base64"
89+
model=llama_stack_models.embedding_model.id, input=input_list, encoding_format="base64"
9090
)
9191
assert isinstance(embeddings_response, CreateEmbeddingsResponse)
9292
assert len(embeddings_response.data) == len(input_list)
Lines changed: 27 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import pytest
2-
import os
3-
from tests.llama_stack.constants import LlamaStackProviders
42
from llama_stack_client import LlamaStackClient, NotFoundError
5-
from llama_stack_client.types import Model
3+
from llama_stack_client.types import Model, ModelRetrieveResponse
64

75

86
@pytest.mark.parametrize(
@@ -39,24 +37,25 @@ def test_models_list(
3937
assert isinstance(models, list), "models.list() should return a list"
4038
assert len(models) > 0, "At least one model should be available"
4139

42-
llm_model = next((model for model in models if model.api_model_type == "llm"), None)
40+
llm_model = next((model for model in models if model.custom_metadata["model_type"] == "llm"), None)
4341
assert llm_model is not None, "No LLM model found in available models"
4442
assert isinstance(llm_model, Model), "LLM model should be a Model instance"
45-
assert llm_model.identifier is not None, "No identifier set in LLM model"
46-
assert len(llm_model.identifier) > 0, "LLM model identifier should not be empty"
43+
assert llm_model.id is not None, "No identifier set in LLM model"
44+
assert len(llm_model.id) > 0, "LLM model identifier should not be empty"
4745

48-
embedding_model = next((model for model in models if model.api_model_type == "embedding"), None)
46+
embedding_model = next((model for model in models if model.custom_metadata["model_type"] == "embedding"), None)
4947
assert embedding_model is not None, "No embedding model found in available models"
5048
assert isinstance(embedding_model, Model), "Embedding model should be a Model instance"
51-
assert embedding_model.identifier is not None, "No identifier set in embedding model"
52-
assert len(embedding_model.identifier) > 0, "Embedding model identifier should not be empty"
53-
assert "embedding_dimension" in embedding_model.metadata, "embedding_dimension not found in model metadata"
54-
embedding_dimension = embedding_model.metadata["embedding_dimension"]
49+
assert embedding_model.id is not None, "No identifier set in embedding model"
50+
assert len(embedding_model.id) > 0, "Embedding model identifier should not be empty"
51+
assert "embedding_dimension" in embedding_model.custom_metadata, (
52+
"embedding_dimension not found in custom_metadata"
53+
)
54+
embedding_dimension = embedding_model.custom_metadata["embedding_dimension"]
5555
assert embedding_dimension is not None, "No embedding_dimension set in embedding model"
56-
# API returns dimension as float (e.g., 768.0) though conceptually an integer
57-
assert isinstance(embedding_dimension, float), "embedding_dimension should be a float"
56+
# API returns dimension as integer (e.g., 768)
57+
assert isinstance(embedding_dimension, int), "embedding_dimension should be an integer"
5858
assert embedding_dimension > 0, "embedding_dimension should be positive"
59-
assert embedding_dimension.is_integer(), "embedding_dimension should be a whole number"
6059

6160
def test_models_list_structure(
6261
self,
@@ -71,15 +70,14 @@ def test_models_list_structure(
7170
assert models is not None, "No models returned from LlamaStackClient"
7271

7372
for model in models:
74-
assert hasattr(model, "identifier"), "Model should have identifier attribute"
75-
assert hasattr(model, "api_model_type"), "Model should have api_model_type attribute"
76-
assert model.identifier is not None, f"Model {model} should have a non-None identifier"
77-
assert model.api_model_type in ["llm", "embedding"], (
78-
f"Model {model.identifier} should have api_model_type 'llm' or 'embedding', "
79-
f"got '{model.api_model_type}'"
73+
assert hasattr(model, "id"), "Model should have identifier attribute"
74+
assert hasattr(model, "custom_metadata"), "Model should have custom_metadata attribute"
75+
assert isinstance(model.custom_metadata, dict), "Model custom_metadata should be a dictionary"
76+
assert model.id is not None, f"Model {model} should have a non-None identifier"
77+
assert model.custom_metadata["model_type"] in ["llm", "embedding"], (
78+
f"Model {model.id} should have custom_metadata[\"model_type\"] 'llm' or 'embedding', "
79+
f"got '{model.custom_metadata['model_type']}'"
8080
)
81-
assert hasattr(model, "metadata"), "Model should have metadata attribute"
82-
assert isinstance(model.metadata, dict), "Model metadata should be a dictionary"
8381

8482
def test_models_retrieve_existing(
8583
self,
@@ -94,17 +92,16 @@ def test_models_retrieve_existing(
9492
assert len(models) > 0, "At least one model should be available"
9593

9694
test_model = models[0]
97-
retrieved_model = unprivileged_llama_stack_client.models.retrieve(model_id=test_model.identifier)
95+
retrieved_model = unprivileged_llama_stack_client.models.retrieve(model_id=test_model.id)
9896

99-
assert retrieved_model is not None, f"Model {test_model.identifier} should be retrievable"
100-
assert isinstance(retrieved_model, Model), "Retrieved model should be a Model instance"
101-
assert retrieved_model.identifier == test_model.identifier, (
102-
f"Retrieved model identifier '{retrieved_model.identifier}' "
103-
f"should match requested '{test_model.identifier}'"
97+
assert retrieved_model is not None, f"Model {test_model.id} should be retrievable"
98+
assert isinstance(retrieved_model, ModelRetrieveResponse), "Retrieved model should be a ModelRetrieveResponse"
99+
assert retrieved_model.identifier == test_model.id, (
100+
f"Retrieved model identifier '{retrieved_model.identifier}' should match requested '{test_model.id}'"
104101
)
105-
assert retrieved_model.api_model_type == test_model.api_model_type, (
102+
assert retrieved_model.api_model_type == test_model.custom_metadata["model_type"], (
106103
f"Retrieved model type '{retrieved_model.api_model_type}' "
107-
f"should match original '{test_model.api_model_type}'"
104+
f"should match original '{test_model.custom_metadata['model_type']}'"
108105
)
109106

110107
def test_models_retrieve_nonexistent(
@@ -120,75 +117,3 @@ def test_models_retrieve_nonexistent(
120117

121118
with pytest.raises(NotFoundError):
122119
unprivileged_llama_stack_client.models.retrieve(model_id=nonexistent_model_id)
123-
124-
def test_models_register(
125-
self,
126-
unprivileged_llama_stack_client: LlamaStackClient,
127-
) -> None:
128-
"""Test registering a new model.
129-
130-
Verifies that models.register() successfully registers a new model
131-
and it appears in the models list.
132-
"""
133-
inference_model = os.getenv("LLS_CORE_INFERENCE_MODEL")
134-
assert inference_model, "LLS_CORE_INFERENCE_MODEL environment variable must be set"
135-
test_model_id = f"{inference_model}-test-register"
136-
137-
response = unprivileged_llama_stack_client.models.register(
138-
model_id=test_model_id,
139-
model_type="llm",
140-
provider_id=LlamaStackProviders.Inference.VLLM_INFERENCE,
141-
)
142-
assert response is not None, "Model registration should return a response"
143-
144-
registered_model_id = f"{LlamaStackProviders.Inference.VLLM_INFERENCE.value}/{test_model_id}"
145-
try:
146-
models = unprivileged_llama_stack_client.models.list()
147-
registered_model_ids = [model.identifier for model in models]
148-
assert registered_model_id in registered_model_ids, (
149-
f"Registered model {registered_model_id} should appear in models list"
150-
)
151-
finally:
152-
unprivileged_llama_stack_client.models.unregister(model_id=registered_model_id)
153-
154-
def test_models_register_retrieve_unregister(
155-
self,
156-
unprivileged_llama_stack_client: LlamaStackClient,
157-
) -> None:
158-
"""Test complete model lifecycle: register, retrieve, and unregister.
159-
160-
Verifies the full workflow of registering a model, retrieving it,
161-
verifying its properties, and then unregistering it.
162-
"""
163-
inference_model = os.getenv("LLS_CORE_INFERENCE_MODEL")
164-
assert inference_model, "LLS_CORE_INFERENCE_MODEL environment variable must be set"
165-
test_model_id = f"{inference_model}-test-lifecycle"
166-
167-
response = unprivileged_llama_stack_client.models.register(
168-
model_id=test_model_id,
169-
model_type="llm",
170-
provider_id=LlamaStackProviders.Inference.VLLM_INFERENCE,
171-
)
172-
assert response is not None, "Model registration should return a response"
173-
174-
registered_model_id = f"{LlamaStackProviders.Inference.VLLM_INFERENCE.value}/{test_model_id}"
175-
try:
176-
registered_model = unprivileged_llama_stack_client.models.retrieve(model_id=registered_model_id)
177-
assert registered_model is not None, f"LLM {registered_model_id} not found using models.retrieve"
178-
assert isinstance(registered_model, Model), "Retrieved model should be a Model instance"
179-
expected_id_suffix = f"/{test_model_id}"
180-
assert registered_model.identifier.endswith(expected_id_suffix), (
181-
f"Model identifier '{registered_model.identifier}' should end with '{expected_id_suffix}'"
182-
)
183-
assert registered_model.api_model_type == "llm", (
184-
f"Registered model should have api_model_type 'llm', got '{registered_model.api_model_type}'"
185-
)
186-
assert registered_model.provider_id == LlamaStackProviders.Inference.VLLM_INFERENCE.value, (
187-
f"Registered model provider_id should be '{LlamaStackProviders.Inference.VLLM_INFERENCE.value}', "
188-
f"got '{registered_model.provider_id}'"
189-
)
190-
finally:
191-
unprivileged_llama_stack_client.models.unregister(model_id=registered_model_id)
192-
193-
with pytest.raises(NotFoundError):
194-
unprivileged_llama_stack_client.models.retrieve(model_id=registered_model_id)

tests/llama_stack/safety/test_trustyai_fms_provider.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import pytest
22
import yaml
3-
from llama_stack_client.types.chat.completion_create_params import MessageOpenAIUserMessageParam
43
from simple_logger.logger import get_logger
54

65
from tests.llama_stack.constants import LlamaStackProviders
@@ -88,10 +87,10 @@ def test_fms_guardrails_run_shield(self, minio_pod, minio_data_connection, llama
8887
run_shields_response = llama_stack_client.safety.run_shield(
8988
shield_id=SECURE_SHIELD_ID,
9089
messages=[
91-
MessageOpenAIUserMessageParam(
92-
content="My email is johndoe@example.com",
93-
role="user",
94-
)
90+
{
91+
"content": "My email is johndoe@example.com",
92+
"role": "user",
93+
}
9594
],
9695
params={},
9796
)

tests/model_registry/conftest.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import time
21
from contextlib import ExitStack
32
import pytest
43
from pytest import Config, FixtureRequest
@@ -318,8 +317,6 @@ def model_registry_instance(
318317
wait_for_pods_running(
319318
admin_client=admin_client, namespace_name=model_registry_namespace, number_of_consecutive_checks=6
320319
)
321-
# TODO remove when RHOAIENG-41728 is addressed
322-
time.sleep(60.0) # noqa: FCN001
323320
yield mr_instances
324321
if db_name == "default":
325322
wait_for_default_resource_cleanedup(admin_client=admin_client, namespace_name=model_registry_namespace)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
11
import pytest
22
from huggingface_hub import HfApi
3+
from simple_logger.logger import get_logger
4+
5+
LOGGER = get_logger(name=__name__)
36

47

58
@pytest.fixture()
69
def huggingface_api():
710
return HfApi()
11+
12+
13+
@pytest.fixture()
14+
def num_models_from_hf_api_with_matching_criteria(request: pytest.FixtureRequest, huggingface_api: HfApi) -> int:
15+
excluded_str = request.param.get("excluded_str")
16+
included_str = request.param.get("included_str")
17+
models = huggingface_api.list_models(author=request.param["org_name"], limit=10000)
18+
model_list = []
19+
for model in models:
20+
if excluded_str:
21+
if model.id.endswith(excluded_str):
22+
LOGGER.info(f"Skipping {model.id} due to {excluded_str}")
23+
continue
24+
else:
25+
LOGGER.info(f"Adding {model.id}")
26+
model_list.append(model.id)
27+
elif included_str:
28+
if model.id.startswith(included_str):
29+
LOGGER.info(f"Adding {model.id}")
30+
model_list.append(model.id)
31+
else:
32+
LOGGER.info(f"Skipping {model.id} due to {included_str}")
33+
continue
34+
else:
35+
model_list.append(model.id)
36+
return len(model_list)

0 commit comments

Comments
 (0)