Skip to content

Commit cd3291c

Browse files
authored
Merge pull request #714 from are-ces/rhelai-support
LCORE-333: Lightspeed core needs to fully support RHEL AI LLM provider
2 parents 5d280c9 + 37142bd commit cd3291c

File tree

6 files changed

+327
-1
lines changed

6 files changed

+327
-1
lines changed

.github/workflows/e2e_tests_rhaiis.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ jobs:
120120
121121
- name: Test RHAIIS connectivity
122122
run: |
123-
curl ${RHAIIS_URL}:8000/v1/models -H "Authorization: Bearer ${RHAIIS_API_KEY}"
123+
curl -f ${RHAIIS_URL}:8000/v1/models -H "Authorization: Bearer ${RHAIIS_API_KEY}"
124124
125125
- name: Run service manually
126126
run: |
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# .github/workflows/e2e_tests_rhelai.yaml
2+
name: RHEL AI E2E Tests
3+
4+
on:
5+
schedule:
6+
- cron: "0 0 * * *" # Runs once a day at midnight UTC
7+
workflow_dispatch:
8+
9+
jobs:
10+
e2e_tests:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
environment: [ "rhelai" ]
15+
env:
16+
RHEL_AI_URL: ${{ secrets.RHEL_AI_URL }}
17+
RHEL_AI_PORT: ${{ secrets.RHEL_AI_PORT }}
18+
RHEL_AI_API_KEY: ${{ secrets.RHEL_AI_API_KEY }}
19+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
20+
RHEL_AI_MODEL: ${{ vars.RHEL_AI_MODEL }}
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
# On PR_TARGET → the fork (or same repo) that opened the PR.
26+
# On push → falls back to the current repository.
27+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
28+
29+
# On PR_TARGET → the PR head *commit* (reproducible).
30+
# On push → the pushed commit that triggered the workflow.
31+
ref: ${{ github.event.pull_request.head.ref || github.sha }}
32+
33+
# Don’t keep credentials when running untrusted PR code under PR_TARGET.
34+
persist-credentials: ${{ github.event_name != 'pull_request_target' }}
35+
36+
- name: Verify actual git checkout result
37+
run: |
38+
echo "=== Git Status After Checkout ==="
39+
echo "Remote URLs:"
40+
git remote -v
41+
echo ""
42+
echo "Current branch: $(git branch --show-current 2>/dev/null || echo 'detached HEAD')"
43+
echo "Current commit: $(git rev-parse HEAD)"
44+
echo "Current commit message: $(git log -1 --oneline)"
45+
echo ""
46+
echo "=== Recent commits (should show setup-metrics commits) ==="
47+
git log --oneline -5
48+
49+
- uses: 1arp/[email protected]
50+
with:
51+
path: '.'
52+
isAbsolutePath: false
53+
file: 'lightspeed-stack.yaml'
54+
content: |
55+
name: Lightspeed Core Service (LCS)
56+
service:
57+
host: 0.0.0.0
58+
port: 8080
59+
auth_enabled: false
60+
workers: 1
61+
color_log: true
62+
access_log: true
63+
llama_stack:
64+
# Uses a remote llama-stack service
65+
# The instance would have already been started with a llama-stack-run.yaml file
66+
use_as_library_client: false
67+
# Alternative for "as library use"
68+
# use_as_library_client: true
69+
# library_client_config_path: <path-to-llama-stack-run.yaml-file>
70+
url: http://llama-stack:8321
71+
api_key: xyzzy
72+
user_data_collection:
73+
feedback_enabled: true
74+
feedback_storage: "/tmp/data/feedback"
75+
transcripts_enabled: true
76+
transcripts_storage: "/tmp/data/transcripts"
77+
78+
authentication:
79+
module: "noop"
80+
81+
- name: Select and configure run.yaml
82+
env:
83+
CONFIG_ENVIRONMENT: ${{ matrix.environment || 'rhelai' }}
84+
run: |
85+
CONFIGS_DIR="tests/e2e/configs"
86+
ENVIRONMENT="$CONFIG_ENVIRONMENT"
87+
88+
echo "Looking for configurations in $CONFIGS_DIR/"
89+
90+
# List available configurations
91+
if [ -d "$CONFIGS_DIR" ]; then
92+
echo "Available configurations:"
93+
ls -la "$CONFIGS_DIR"/*.yaml 2>/dev/null || echo "No YAML files found in $CONFIGS_DIR/"
94+
else
95+
echo "Configs directory '$CONFIGS_DIR' not found!"
96+
exit 1
97+
fi
98+
99+
# Determine which config file to use
100+
CONFIG_FILE="$CONFIGS_DIR/run-$ENVIRONMENT.yaml"
101+
102+
echo "Looking for: $CONFIG_FILE"
103+
104+
if [ -f "$CONFIG_FILE" ]; then
105+
echo "Found config for environment: $ENVIRONMENT"
106+
cp "$CONFIG_FILE" run.yaml
107+
else
108+
echo "Configuration file not found: $CONFIG_FILE"
109+
echo "Available files in $CONFIGS_DIR:"
110+
ls -la "$CONFIGS_DIR/"
111+
exit 1
112+
fi
113+
114+
# Update paths for container environment (relative -> absolute)
115+
sed -i 's|db_path: \.llama/distributions|db_path: /app-root/.llama/distributions|g' run.yaml
116+
sed -i 's|db_path: tmp/|db_path: /app-root/.llama/distributions/|g' run.yaml
117+
118+
echo "Successfully configured for environment: $ENVIRONMENT"
119+
echo "Using configuration: $(basename "$CONFIG_FILE")"
120+
121+
- name: Test RHEL_AI connectivity
122+
run: |
123+
echo $RHEL_AI_MODEL
124+
curl -f ${RHEL_AI_URL}:${RHEL_AI_PORT}/v1/models -H "Authorization: Bearer ${RHEL_AI_API_KEY}"
125+
126+
- name: Run service manually
127+
run: |
128+
docker compose version
129+
docker compose up -d
130+
131+
# Check for errors and show logs if any services failed
132+
if docker compose ps | grep -E 'Exit|exited|stopped'; then
133+
echo "Some services failed to start - showing logs:"
134+
docker compose logs
135+
exit 1
136+
else
137+
echo "All services started successfully"
138+
fi
139+
140+
- name: Wait for services
141+
run: |
142+
echo "Waiting for services to be healthy..."
143+
sleep 20 # adjust depending on boot time
144+
145+
- name: Quick connectivity test
146+
run: |
147+
echo "Testing basic connectivity before full test suite..."
148+
curl -f http://localhost:8080/v1/models || {
149+
echo "❌ Basic connectivity failed - showing logs before running full tests"
150+
docker compose logs --tail=30
151+
exit 1
152+
}
153+
154+
- name: Run e2e tests
155+
run: |
156+
echo "Installing test dependencies..."
157+
pip install uv
158+
uv sync
159+
160+
echo "Running comprehensive e2e test suite..."
161+
make test-e2e
162+
163+
- name: Show logs on failure
164+
if: failure()
165+
run: |
166+
echo "=== Test failure logs ==="
167+
echo "=== llama-stack logs ==="
168+
docker compose logs llama-stack
169+
170+
echo ""
171+
echo "=== lightspeed-stack logs ==="
172+
docker compose logs lightspeed-stack

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ Lightspeed Core Stack (LCS) supports the large language models from the provider
125125
| OpenAI | gpt-5, gpt-4o, gpt4-turbo, gpt-4.1, o1, o3, o4 | Yes | remote::openai | [1](examples/openai-faiss-run.yaml) [2](examples/openai-pgvector-run.yaml) |
126126
| OpenAI | gpt-3.5-turbo, gpt-4 | No | remote::openai | |
127127
| RHAIIS (vLLM)| meta-llama/Llama-3.1-8B-Instruct | Yes | remote::vllm | [1](tests/e2e/configs/run-rhaiis.yaml) |
128+
| RHEL AI (vLLM)| meta-llama/Llama-3.1-8B-Instruct | Yes | remote::vllm | [1](tests/e2e/configs/run-rhelai.yaml) |
128129
| Azure | gpt-5, gpt-5-mini, gpt-5-nano, gpt-5-chat, gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, o3-mini, o4-mini | Yes | remote::azure | [1](examples/azure-run.yaml) |
129130
| Azure | o1, o1-mini | No | remote::azure | |
130131

docker-compose.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ services:
1818
- RHAIIS_URL=${RHAIIS_URL}
1919
- RHAIIS_API_KEY=${RHAIIS_API_KEY}
2020
- RHAIIS_MODEL=${RHAIIS_MODEL}
21+
- RHEL_AI_URL=${RHEL_AI_URL}
22+
- RHEL_AI_PORT=${RHEL_AI_PORT}
23+
- RHEL_AI_API_KEY=${RHEL_AI_API_KEY}
24+
- RHEL_AI_MODEL=${RHEL_AI_MODEL}
2125
- LLAMA_STACK_LOGGING=all=debug # enable llama-stack debug log
2226
networks:
2327
- lightspeednet

docs/providers.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Red Hat providers:
6262
| Name | Version Tested | Type | Pip Dependencies | Supported in LCS |
6363
|---|---|---|---|:---:|
6464
| RHAIIS (vllm) | 3.2.3 (on RHEL 9.20250429.0.4) | remote | `openai` ||
65+
| RHEL AI (vllm) | 1.5.2 | remote | `openai` ||
6566

6667

6768
---

tests/e2e/configs/run-rhelai.yaml

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
version: '2'
2+
image_name: rhelai-configuration
3+
4+
apis:
5+
- agents
6+
- datasetio
7+
- eval
8+
- files
9+
- inference
10+
- post_training
11+
- safety
12+
- scoring
13+
- telemetry
14+
- tool_runtime
15+
- vector_io
16+
benchmarks: []
17+
container_image: null
18+
datasets: []
19+
external_providers_dir: null
20+
inference_store:
21+
db_path: .llama/distributions/ollama/inference_store.db
22+
type: sqlite
23+
logging: null
24+
metadata_store:
25+
db_path: .llama/distributions/ollama/registry.db
26+
namespace: null
27+
type: sqlite
28+
providers:
29+
files:
30+
- config:
31+
storage_dir: /tmp/llama-stack-files
32+
metadata_store:
33+
type: sqlite
34+
db_path: .llama/distributions/ollama/files_metadata.db
35+
provider_id: localfs
36+
provider_type: inline::localfs
37+
agents:
38+
- config:
39+
persistence_store:
40+
db_path: .llama/distributions/ollama/agents_store.db
41+
namespace: null
42+
type: sqlite
43+
responses_store:
44+
db_path: .llama/distributions/ollama/responses_store.db
45+
type: sqlite
46+
provider_id: meta-reference
47+
provider_type: inline::meta-reference
48+
datasetio:
49+
- config:
50+
kvstore:
51+
db_path: .llama/distributions/ollama/huggingface_datasetio.db
52+
namespace: null
53+
type: sqlite
54+
provider_id: huggingface
55+
provider_type: remote::huggingface
56+
- config:
57+
kvstore:
58+
db_path: .llama/distributions/ollama/localfs_datasetio.db
59+
namespace: null
60+
type: sqlite
61+
provider_id: localfs
62+
provider_type: inline::localfs
63+
eval:
64+
- config:
65+
kvstore:
66+
db_path: .llama/distributions/ollama/meta_reference_eval.db
67+
namespace: null
68+
type: sqlite
69+
provider_id: meta-reference
70+
provider_type: inline::meta-reference
71+
inference:
72+
- provider_id: sentence-transformers # Can be any embedding provider
73+
provider_type: inline::sentence-transformers
74+
config: {}
75+
- provider_id: vllm
76+
provider_type: remote::vllm
77+
config:
78+
url: http://${env.RHEL_AI_URL}:${env.RHEL_AI_PORT}/v1/
79+
api_token: ${env.RHEL_AI_API_KEY}
80+
tls_verify: false
81+
max_tokens: 2048
82+
- provider_id: openai
83+
provider_type: remote::openai
84+
config:
85+
api_key: ${env.OPENAI_API_KEY}
86+
post_training:
87+
- config:
88+
checkpoint_format: huggingface
89+
device: cpu
90+
distributed_backend: null
91+
dpo_output_dir: "."
92+
provider_id: huggingface
93+
provider_type: inline::huggingface-gpu
94+
safety:
95+
- config:
96+
excluded_categories: []
97+
provider_id: llama-guard
98+
provider_type: inline::llama-guard
99+
scoring:
100+
- config: {}
101+
provider_id: basic
102+
provider_type: inline::basic
103+
- config: {}
104+
provider_id: llm-as-judge
105+
provider_type: inline::llm-as-judge
106+
- config:
107+
openai_api_key: '********'
108+
provider_id: braintrust
109+
provider_type: inline::braintrust
110+
telemetry:
111+
- config:
112+
service_name: 'lightspeed-stack-telemetry'
113+
sinks: sqlite
114+
sqlite_db_path: .llama/distributions/ollama/trace_store.db
115+
provider_id: meta-reference
116+
provider_type: inline::meta-reference
117+
tool_runtime:
118+
- provider_id: model-context-protocol
119+
provider_type: remote::model-context-protocol
120+
config: {}
121+
scoring_fns: []
122+
server:
123+
auth: null
124+
host: null
125+
port: 8321
126+
quota: null
127+
tls_cafile: null
128+
tls_certfile: null
129+
tls_keyfile: null
130+
shields:
131+
- shield_id: llama-guard-shield
132+
provider_id: llama-guard
133+
provider_shield_id: "gpt-4-turbo"
134+
models:
135+
- metadata:
136+
embedding_dimension: 768 # Depends on chosen model
137+
model_id: sentence-transformers/all-mpnet-base-v2 # Example embedding model
138+
provider_id: sentence-transformers
139+
provider_model_id: sentence-transformers/all-mpnet-base-v2 # Location of embedding model
140+
model_type: embedding
141+
- model_id: ${env.RHEL_AI_MODEL}
142+
provider_id: vllm
143+
model_type: llm
144+
provider_model_id: ${env.RHEL_AI_MODEL}
145+
- model_id: gpt-4-turbo
146+
provider_id: openai
147+
model_type: llm
148+
provider_model_id: gpt-4-turbo

0 commit comments

Comments
 (0)