Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 105 additions & 7 deletions .github/actions/rhdh-local-compose-test/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,19 @@ inputs:
description: Log level to use
required: false
default: "info"
disable_intelligent_assistant:
description: "Disable Intelligent Assistant services for compose profiles that do not exercise them"
required: false
default: "false"
Comment on lines +47 to +50

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder if we should just have OKP disabled always in CI, it's a pretty large image?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, the OKP image is not pulled in CI. Regular jobs disable IA and OKP, while the dedicated intelligent-assistant-without-okp job keeps LCORE enabled but profiles out OKP..


runs:
using: "composite"
steps:
- name: Configure Intelligent Assistant test profile
if: ${{ inputs.disable_intelligent_assistant == 'true' }}
shell: bash
run: echo "COMPOSE_INTELLIGENT_ASSISTANT_ARGS=-f compose.intelligent-assistant-disabled.override.example.yaml" >> "$GITHUB_ENV"

# Set RHDH_TAG and optionally RHDH_IMAGE based on the branch name for container image selection
- name: Set RHDH tag, image and catalog index
if: ${{ inputs.override_images == 'true' }}
Expand Down Expand Up @@ -185,7 +194,56 @@ runs:
env:
TOOL: ${{ inputs.container_tool }}
CLI_ARGS: ${{ inputs.compose_cli_args }}
run: $TOOL compose $CLI_ARGS config
run: $TOOL compose $CLI_ARGS $COMPOSE_INTELLIGENT_ASSISTANT_ARGS config

- name: Validate Intelligent Assistant Compose profiles
if: ${{ env.SKIP_TEST != 'true' && inputs.compose_config_name == 'default' }}
shell: bash
env:
TOOL: ${{ inputs.container_tool }}
CLI_ARGS: ${{ inputs.compose_cli_args }}
run: |
set -euo pipefail

default_config=$(mktemp)
okp_config=$(mktemp)
trap 'rm -f "$default_config" "$okp_config"' EXIT

$TOOL compose $CLI_ARGS config --format json > "$default_config"

if jq -e '.services | has("okp")' "$default_config" > /dev/null; then
echo "ERROR: OKP must not be part of the default Intelligent Assistant profile."
exit 1
fi

if jq -e '(.services["lightspeed-core"].environment // {}) | has("OKP_SERVICE_URL")' "$default_config" > /dev/null; then
echo "ERROR: OKP_SERVICE_URL must not be set by the default Intelligent Assistant profile."
exit 1
fi

jq -e '
any(
.services["lightspeed-core"].volumes[];
.target == "/app-root/lightspeed-stack.yaml"
and (.source | endswith("/configs/extra-files/lightspeed-stack-no-okp.yaml"))
)
' "$default_config" > /dev/null

# Render and validate the opt-in profile without pulling or starting OKP.
$TOOL compose \
-f compose.yaml \
-f intelligent-assistant/compose-with-okp.yaml \
config --format json > "$okp_config"

jq -e '.services | has("okp")' "$okp_config" > /dev/null
jq -e '(.services["lightspeed-core"].environment // {}) | has("OKP_SERVICE_URL")' "$okp_config" > /dev/null
jq -e '
any(
.services["lightspeed-core"].volumes[];
.target == "/app-root/lightspeed-stack.yaml"
and (.source | endswith("/configs/extra-files/lightspeed-stack.yaml"))
)
' "$okp_config" > /dev/null

- name: Add user-specific configuration
if: ${{ env.SKIP_TEST != 'true' && inputs.user_config_enabled == 'true' }}
Expand Down Expand Up @@ -264,8 +322,8 @@ runs:
TOOL: ${{ inputs.container_tool }}
CLI_ARGS: ${{ inputs.compose_cli_args }}
run: |
$TOOL compose $CLI_ARGS up --detach --quiet-pull
$TOOL compose $CLI_ARGS ps
$TOOL compose $CLI_ARGS $COMPOSE_INTELLIGENT_ASSISTANT_ARGS up --detach --quiet-pull
$TOOL compose $CLI_ARGS $COMPOSE_INTELLIGENT_ASSISTANT_ARGS ps

- name: Wait for HTTP 200 response from homepage
if: ${{ env.SKIP_TEST != 'true' }}
Expand All @@ -286,6 +344,46 @@ runs:
echo "[$(date)] RHDH is ready"
curl -i --insecure http://localhost:7007

- name: Validate Intelligent Assistant runtime
if: ${{ env.SKIP_TEST != 'true' && inputs.compose_config_name == 'default' }}
shell: bash
env:
TOOL: ${{ inputs.container_tool }}
CLI_ARGS: ${{ inputs.compose_cli_args }}
run: |
set -euo pipefail

max=30
i=0
echo "Waiting for Lightspeed Core readiness..."
until $TOOL compose $CLI_ARGS exec -T rhdh curl -fsS http://localhost:8080/readiness | jq -e '.ready == true' > /dev/null; do
i=$((i+1))
if [ "$i" -ge "$max" ]; then
echo "ERROR: Lightspeed Core did not become ready."
exit 1
fi
echo "($i/$max) Waiting for Lightspeed Core readiness..."
sleep 5
done

if $TOOL compose $CLI_ARGS ps --all --services | grep -qx okp; then
echo "ERROR: An OKP container is running in the default Intelligent Assistant profile."
exit 1
fi

if $TOOL compose $CLI_ARGS exec -T lightspeed-core env | grep -q '^OKP_SERVICE_URL='; then
echo "ERROR: OKP_SERVICE_URL is set in the default Intelligent Assistant profile."
exit 1
fi

expected_config_sha=$(sha256sum configs/extra-files/lightspeed-stack-no-okp.yaml | awk '{print $1}')
mounted_config_sha=$($TOOL compose $CLI_ARGS exec -T lightspeed-core \
sha256sum /app-root/lightspeed-stack.yaml | awk '{print $1}')
if [ "$mounted_config_sha" != "$expected_config_sha" ]; then
echo "ERROR: Lightspeed Core is not using the expected no-OKP configuration."
exit 1
fi

- name: Validate loaded plugins
if: ${{ env.SKIP_TEST != 'true' }}
shell: bash
Expand All @@ -307,9 +405,9 @@ runs:
TOOL: ${{ inputs.container_tool }}
CLI_ARGS: ${{ inputs.compose_cli_args }}
run: |
for svc in $($TOOL compose $CLI_ARGS config --services | sort); do
for svc in $($TOOL compose $CLI_ARGS $COMPOSE_INTELLIGENT_ASSISTANT_ARGS config --services | sort); do
echo "*** $svc ***"
$TOOL compose $CLI_ARGS logs --timestamps "$svc" || true
$TOOL compose $CLI_ARGS $COMPOSE_INTELLIGENT_ASSISTANT_ARGS logs --timestamps "$svc" || true
echo "************"
echo
done
Expand All @@ -321,8 +419,8 @@ runs:
TOOL: ${{ inputs.container_tool }}
CLI_ARGS: ${{ inputs.compose_cli_args }}
run: |
$TOOL compose $CLI_ARGS ps || true
$TOOL compose $CLI_ARGS down --volumes || true
$TOOL compose $CLI_ARGS $COMPOSE_INTELLIGENT_ASSISTANT_ARGS ps || true
$TOOL compose $CLI_ARGS $COMPOSE_INTELLIGENT_ASSISTANT_ARGS down --volumes || true

- name: Cleanup Podman container environment
if: ${{ always() && env.SKIP_TEST != 'true' && inputs.container_tool == 'podman' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,5 @@ jobs:
compose_cli_args: ${{ matrix.composeConfig.cliArgs }}
compose_config_name: ${{ matrix.composeConfig.name }}
user_config_enabled: ${{ matrix.userConfig }}
disable_intelligent_assistant: ${{ matrix.composeConfig.name != 'developer-lightspeed' && matrix.composeConfig.name != 'default' && 'true' || 'false' }}
override_images: ${{ startsWith(matrix.branch, 'release-') && 'true' || 'false' }}

1 change: 1 addition & 0 deletions .github/workflows/sync-lightspeed-configs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ jobs:

### Synced files
- \`configs/extra-files/lightspeed-stack.yaml\`
- \`configs/extra-files/lightspeed-stack-no-okp.yaml\`
- \`configs/extra-files/rhdh-profile.py\`

> [!CAUTION]
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ jobs:
compose_cli_args: ${{ matrix.composeConfig.cliArgs }}
compose_config_name: ${{ matrix.composeConfig.name }}
user_config_enabled: ${{ matrix.userConfig }}
disable_intelligent_assistant: ${{ matrix.composeConfig.name != 'default' && 'true' || 'false' }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ compose.override.yaml*
/configs/extra-files/*
!/configs/extra-files/github-app-credentials.example.yaml
!/configs/extra-files/lightspeed-stack.yaml
!/configs/extra-files/lightspeed-stack-no-okp.yaml
!/configs/extra-files/rhdh-profile.py
!/configs/extra-files/templates

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RHDH Local lets you quickly test software catalogs, TechDocs, plugins, templates
podman compose up -d # or: docker compose up -d
```

> **Developer Hub Intelligent Assistant** is included by default. To configure an LLM provider, see the [Developer Hub Intelligent Assistant Guide](./docs/intelligent-assistant/working-with-intelligent-assistant.md). To disable Developer Hub Intelligent Assistant, see [Disabling Intelligent Assistant](./docs/intelligent-assistant/working-with-intelligent-assistant.md#disabling-intelligent-assistant).
> **Developer Hub Intelligent Assistant** is included by default without OKP-backed product documentation. To configure an LLM provider, opt in to OKP, or disable Intelligent Assistant, see the [Developer Hub Intelligent Assistant Guide](./docs/intelligent-assistant/working-with-intelligent-assistant.md).

3. **Access**: Open [http://localhost:7007](http://localhost:7007) and log in as 'Guest'

Expand Down
4 changes: 1 addition & 3 deletions compose.intelligent-assistant-disabled.override.example.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Copy this file to compose.override.yaml to disable Developer Hub Intelligent Assistant services.
# This prevents rag-init and lightspeed-core from starting with `podman compose up -d`.
# This prevents lightspeed-core from starting with `podman compose up -d`.
# To re-enable, delete compose.override.yaml.
services:
rag-init:
profiles: [intelligent-assistant]
lightspeed-core:
profiles: [intelligent-assistant]
33 changes: 4 additions & 29 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,9 @@ services:
- dynamic-plugins-root:/opt/app-root/src/dynamic-plugins-root
- extensions-catalog:${CATALOG_ENTITIES_EXTRACT_DIR:-/extensions}

# RAG initialization service: Copies RAG embeddings and vector database to shared volumes
# This runs once at startup to prepare the RAG data for the lightspeed-core container
rag-init:
image: 'quay.io/redhat-ai-dev/rag-content:release-1.10-lls-0.5.0-8c231a3b5177f12fff9db042dfa4091d8f2f26b3'
container_name: rag-init
user: "root"
volumes:
- rag_embeddings:/data/embeddings_model
- rag_vector_db:/data/vector_db
entrypoint: [ "/bin/sh", "-c" ]
command: |
"set -e; echo 'Copying RAG data...' && \
mkdir -p /data/vector_db /data/embeddings_model && \
cp -r /rag/vector_db/* /data/vector_db/ && \
cp -r /rag/embeddings_model/* /data/embeddings_model/ && \
chown -R 1001:0 /data/vector_db /data/embeddings_model || true && \
chmod -R a+rwX /data/vector_db /data/embeddings_model && \
echo 'Copy complete.'"
restart: "no"

# Lightspeed Core Service (Library Mode)
# Runs both Lightspeed Core and Llama Stack in a single container
# Default image: quay.io/lightspeed-core/lightspeed-stack:0.5.1
# Runs Lightspeed Core with its unified embedded stack configuration
# Default image: quay.io/lightspeed-core/lightspeed-stack:dev-20260824-cbd182b
# To override: Set LIGHTSPEED_CORE_IMAGE in your .env file
lightspeed-core:
image: ${LIGHTSPEED_CORE_IMAGE:-quay.io/lightspeed-core/lightspeed-stack:dev-20260824-cbd182b} # dclint disable-line service-image-require-explicit-tag #todo: change tag to official release when available
Expand All @@ -83,17 +63,14 @@ services:
depends_on:
rhdh:
condition: service_started
rag-init:
condition: service_completed_successfully
volumes:
- ${LIGHTSPEED_STACK_CONFIG:-./configs/extra-files/lightspeed-stack.yaml}:/app-root/lightspeed-stack.yaml:Z
- ${LIGHTSPEED_STACK_CONFIG:-./configs/extra-files/lightspeed-stack-no-okp.yaml}:/app-root/lightspeed-stack.yaml:Z
- ./configs/extra-files/rhdh-profile.py:/app-root/rhdh-profile.py:Z
- rag_embeddings:/rag-content/embeddings_model
- rag_vector_db:/rag-content/vector_db
- ${VERTEX_AI_CREDENTIALS_PATH:-./configs/extra-files/templates/placeholder.json}:/app-root/credentials.json:Z
environment:
GOOGLE_APPLICATION_CREDENTIALS: /app-root/credentials.json
SERVICE_HOST: 0.0.0.0
OTEL_SDK_DISABLED: "true"
env_file:
- path: "./default.env"
required: true
Expand All @@ -109,5 +86,3 @@ services:
volumes:
dynamic-plugins-root:
extensions-catalog:
rag_embeddings:
rag_vector_db:
Loading
Loading