Skip to content

feat(intelligent-assistant): add optional OKP document retrieval - #310

Open
maysunfaisal wants to merge 5 commits into
redhat-developer:devfrom
maysunfaisal:okp-integration-2
Open

maysunfaisal wants to merge 5 commits into
redhat-developer:devfrom
maysunfaisal:okp-integration-2

Conversation

@maysunfaisal

@maysunfaisal maysunfaisal commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Target branch

Description

This PR integrates Offline Knowledge Portal (OKP) as an optional product-documentation source for Developer Hub Intelligent Assistant in RHDH Local.

  • Keeps Intelligent Assistant enabled by default without OKP, a Red Hat registry login, or the large OKP image download.
  • Adds an explicit Compose override for enabling OKP-backed RHDH documentation and clickable citations.
  • Updates Lightspeed Core to use the unified configuration, with separate tracked OKP and generated no-OKP variants.
  • Generates and validates the no-OKP Lightspeed configuration during configuration synchronization.
  • Adds ARM-compatible OKP startup handling.
  • Adds Docker and Podman CI coverage for LCORE readiness and the default no-OKP behavior.
  • Statically validates the OKP opt-in Compose configuration in CI without authenticating to registry.redhat.io or pulling the OKP image.
  • Documents that RHDH product-documentation assistance is disabled by default and that enabling OKP increases initial download time and resource usage.

Which issue(s) does this PR fix or relate to

https://redhat.atlassian.net/browse/RHIDP-14136

PR acceptance criteria

  • Tests updated and passing
  • Documentation updated
  • Built-in TechDocs updated if needed. Note that TechDocs changes may need to be reviewed by a Product Manager and/or Architect to ensure content accuracy, clarity, and alignment with user needs.

How to test changes / Special notes to the reviewer

Intelligent Assistant without OKP (default)

  1. Create a local provider configuration and .env file:

    cp default.env .env
    cp configs/extra-files/lightspeed-stack-no-okp.yaml \
       configs/extra-files/lightspeed-stack.local.yaml
  2. Uncomment an inference provider in configs/extra-files/lightspeed-stack.local.yaml, configure its credentials in .env, and add:

    LIGHTSPEED_STACK_CONFIG=./configs/extra-files/lightspeed-stack.local.yaml
  3. Start RHDH Local without logging in to registry.redhat.io:

    podman compose up -d
    podman compose ps
  4. Verify rhdh and lightspeed-core are running, no okp container exists, and the following commands return no output:

    podman exec lightspeed-core printenv OKP_SERVICE_URL
    podman exec lightspeed-core grep '^rag:' /app-root/lightspeed-stack.yaml
  5. Open http://localhost:7007/intelligent-assistant and verify the chatbot works without OKP-backed documentation or citations.

Intelligent Assistant with OKP (opt-in)

  1. Stop the default deployment and authenticate to the Red Hat registry:

    podman compose down
    podman login registry.redhat.io
  2. Enable OKP and create an OKP-enabled local provider configuration:

    cp compose.okp-enabled.override.example.yaml compose.override.yaml
    cp configs/extra-files/lightspeed-stack.yaml \
       configs/extra-files/lightspeed-stack-okp.local.yaml
  3. Uncomment the same inference provider in configs/extra-files/lightspeed-stack-okp.local.yaml, then add to .env:

    LIGHTSPEED_STACK_OKP_CONFIG=./configs/extra-files/lightspeed-stack-okp.local.yaml
  4. Start and verify the opt-in deployment:

    podman compose up -d
    podman compose ps
    curl -f http://localhost:8081/
  5. Verify rhdh, lightspeed-core, and okp are running, okp is healthy, and LCORE has the OKP URL:

    podman exec lightspeed-core printenv OKP_SERVICE_URL
  6. Open http://localhost:7007/intelligent-assistant, ask an RHDH documentation question, and verify the response contains clickable OKP citations.

Docker users can replace podman with docker in the commands above.

Cleanup

podman compose down --volumes
rm -f compose.override.yaml

@Jdubrick

Jdubrick commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

/fs-review

## Increasing Container Runtime Memory

If you encounter out-of-memory issues with the Lightspeed Core container, you can increase the memory available to your Podman or Docker virtual machine:
If you encounter out-of-memory issues with the Lightspeed Core or OKP container, you can increase the memory available to your Podman or Docker virtual machine:

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.

Do we have a recommended amount of resources?

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.

We don’t currently have a validated minimum. I updated the documentation to explain that OKP and LCORE increase memory usage and that 8 GiB is only an example for troubleshooting, not a requirement. The Kubernetes OKP doesnt translate to Podman requirements, so I framed it as something users can do to alleviate memory issues

# then re-uncomment provider blocks
```

Some upstream refs still ship the OKP block commented with a TODO. When syncing one of those refs, preserve or reactivate the `rag.okp` and `rag.retrieval.tool.sources: [okp]` block used by this Compose integration.

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.

Is this true? AFAIK the only 3 locations where OKP was commented out were in this repo, Operator, and Helm, but if you ran the sync script to re-fetch the LCORE config file it would wipe out that comment

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.

You’re right. lightspeed-stack.yaml should remain a verbatim copy. I replaced the confusing wording drafted by Codex..

Comment on lines +47 to +50
disable_intelligent_assistant:
description: "Disable Intelligent Assistant services when registry.redhat.io credentials are unavailable"
required: false
default: "false"

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..

@maysunfaisal
maysunfaisal requested a review from rm3l September 11, 2026 18:34
Comment thread README.md Outdated
## Quick Start

1. **Prerequisites**: [Podman](https://podman.io/docs/installation) v5.4.1+ (recommended) or [Docker](https://docs.docker.com/engine/) v28.1.0+ with Compose support
1. **Prerequisites**: [Podman](https://podman.io/docs/installation) v5.4.1+ (recommended) or [Docker](https://docs.docker.com/engine/) v28.1.0+ with Compose support, plus a [Red Hat registry login](https://access.redhat.com/RegistryAuthentication) for the bundled OKP image unless you [run Intelligent Assistant without OKP](./docs/intelligent-assistant/working-with-intelligent-assistant.md#running-without-okp)

@rm3l rm3l Sep 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So this raises the barrier to entry for users as it would now require registry.redhat.io authentication by default.
Is that okay, @benwilcock @kadel ?

So far, we have been using only public images OOTB and, when auth is required like here with PostgreSQL, it was intentionally opt-in. But I understand, as already discussed on other PRs, that OKP does not have public images at this time: https://redhat.atlassian.net/browse/RHOKP-1792

BTW, in the Helm Chart, OKP seems effectively opt-in (at least on K8s, gated on a configured ingress host): https://github.com/redhat-developer/rhdh-chart/blob/94c20cf8031f0f46b82764b6eba90de180309fa0/charts/rhdh/templates/_helpers.tpl#L321-L331
Shouldn't it be opt-in in RHDH Local as well?

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.

@rm3l Correct—this PR currently enables OKP by default and provides compose.okp-disabled.override.example.yaml as an explicit opt-out that keeps IA enabled.

I agree this introduces a registry.redhat.io authentication requirement to the default experience. We can invert this so IA without OKP is the default, while users explicitly opt in to OKP through a Compose override after authenticating.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, that sounds like a better approach IMO. Making IA-without-OKP the default keeps the clone-and-run experience intact as currently, and users who want OKP can opt in after authenticating against registry.redhat.io. We can revisit this to enable OKP by default once https://redhat.atlassian.net/browse/RHOKP-1792 is resolved.

@maysunfaisal maysunfaisal Sep 17, 2026

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.

@rm3l I have updated as per the Slack conversation, OKP is disabled by default, PTAL.

@maysunfaisal maysunfaisal changed the title feat(intelligent-assistant): replace RHDH RAG with OKP service feat(intelligent-assistant): add optional OKP document retrieval Sep 17, 2026
@rm3l

rm3l commented Sep 18, 2026

Copy link
Copy Markdown
Member

/agentic_review

@rhdh-qodo-merge

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Default document lookup endpoint fails 🐞 Bug ≡ Correctness
Description
compose.okp-enabled.override.example.yaml sets OKP_SERVICE_URL to
http://host.docker.internal:8081, while the Compose project provides neither a host-gateway alias
for supported standalone Linux Docker nor a separate browser-facing URL for this container-oriented
hostname. On runtimes without that special alias, Lightspeed Core reaches hostname resolution
failure when retrieving from OKP, and host browsers cannot follow the citation URLs generated from
the same value.
Code

compose.okp-enabled.override.example.yaml[11]

+      OKP_SERVICE_URL: ${OKP_SERVICE_URL:-http://host.docker.internal:8081}
Relevance

●● Moderate

Portability concern is plausible, but no closely matching historical acceptance or rejection
precedent was found.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The override passes the Docker Desktop-specific host.docker.internal value to Lightspeed Core, and
the active RAG configuration consumes it as the OKP endpoint for both container retrieval and
browser-facing citations. The documentation supports standalone Docker Engine and distinguishes
Docker and Podman host aliases, but the Compose service defines no extra_hosts or other
host-gateway mapping and provides no separate public citation URL, demonstrating that the configured
endpoint is not portable to both clients.

compose.okp-enabled.override.example.yaml[8-11]
configs/extra-files/lightspeed-stack.yaml[146-154]
compose.yaml[59-80]
docs/intelligent-assistant/working-with-intelligent-assistant.md[262-277]
compose.okp-enabled.override.example.yaml[4-11]
docs/rhdh-local-guide/getting-started.md[6-12]
docs/intelligent-assistant/working-with-intelligent-assistant.md[170-178]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The default OKP endpoint depends on `host.docker.internal`, which this Compose project does not configure for standalone Linux Docker and which is also unsuitable as a browser-facing hostname there. The configured URLs must allow both Lightspeed Core to reach OKP from its container and host browsers to open generated citations.

## Fix Focus Areas
- compose.okp-enabled.override.example.yaml[4-11]
- configs/extra-files/lightspeed-stack.yaml[146-154]
- docs/intelligent-assistant/working-with-intelligent-assistant.md[262-275]

## Recommended Fix
Use separate internal and public OKP endpoints: connect Lightspeed Core to the Compose service at `http://okp:8080`, and generate browser-facing citations with a public base such as `http://localhost:8081`. If separate endpoints are not supported, add the required configuration support; alternatively, use a runtime-independent address reachable from both clients or add the required host-gateway mapping while configuring citations to use `localhost:8081`. Keep the documented default aligned with actual container and browser reachability instead of defaulting both uses to a runtime-specific hostname.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Network peers reach Solr administration 🐞 Bug ⛨ Security
Description
The OKP override publishes Solr port 8983 on every host interface via 8983:8983, even though it is
documented only as a local diagnostic interface. When OKP is enabled, any network peer that can
reach the developer's machine can access Solr's HTTP administration endpoint rather than access
being limited to the local health check and operator.
Code

compose.okp-enabled.override.example.yaml[23]

+      - "8983:8983"
Relevance

●●● Strong

Restricting diagnostic ports is a concrete security hardening fix consistent with prior accepted
configuration corrections.

PR-#34

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The unqualified 8983:8983 Compose mapping publishes Solr without a host IP restriction, while the
command starts Solr and the health check accesses its administration and diagnostic endpoint. The
maintenance documentation characterizes port 8983 as local diagnostics, and existing Compose
configuration demonstrates the intended pattern by explicitly binding host-local diagnostic ports to
127.0.0.1.

compose.okp-enabled.override.example.yaml[21-35]
compose.yaml[15-18]
docs/intelligent-assistant/maintaining-intelligent-assistant.md[105-105]
compose.okp-enabled.override.example.yaml[21-23]
compose.okp-enabled.override.example.yaml[34-38]
docs/intelligent-assistant/maintaining-intelligent-assistant.md[99-105]
compose.yaml[14-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The opt-in Compose override exposes Solr's diagnostic and administration endpoint on all host interfaces even though only local access is required.

## Fix Focus Areas
- compose.okp-enabled.override.example.yaml[21-23]
- docs/intelligent-assistant/maintaining-intelligent-assistant.md[105-105]

## Recommended Fix
Change the Solr publication to a loopback-only binding such as `127.0.0.1:8983:8983`, or remove it entirely if host-side diagnostics are unnecessary. Keep the container-local health check pointed at port 8983, retain any HTTP publication only as broadly reachable as required for browser citations, and update the port documentation if its access scope changes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. ARM assistant regressions escape CI 🐞 Bug ☼ Reliability
Description
The nightly matrix explicitly excludes the new intelligent-assistant profile from ARM runners.
Because the remaining ARM profiles set disable_intelligent_assistant to true, no ARM job executes
the added Lightspeed Core readiness validation despite this change introducing ARM-specific startup
handling.
Code

.github/workflows/nightly.yaml[R93-96]

+          - os: ubuntu-24.04-arm
+            composeConfig:
+              name: "intelligent-assistant"
+              cliArgs: "-f compose.yaml"
Relevance

●●● Strong

Recent workflow precedents accept preserving matrix coverage and adding missing configuration
scenarios.

PR-#180
PR-#229

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added matrix entry appears under exclude, while disable_intelligent_assistant is false only
for the intelligent-assistant and legacy developer-lightspeed profiles. The runtime readiness step
itself runs only when the profile name is intelligent-assistant, so every surviving ARM job
bypasses it.

.github/workflows/nightly.yaml[78-104]
.github/workflows/nightly.yaml[140-143]
.github/actions/rhdh-local-compose-test/action.yaml[359-397]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The nightly matrix excludes the only ARM profile that keeps Intelligent Assistant enabled and invokes its runtime validation.

## Fix Focus Areas
- .github/workflows/nightly.yaml[93-96]
- .github/workflows/nightly.yaml[140-143]
- .github/actions/rhdh-local-compose-test/action.yaml[359-397]

## Recommended Fix
Remove the ARM `intelligent-assistant` exclusion while retaining a single representative ARM tool and user-configuration combination. Ensure that job reaches the Lightspeed Core readiness and mounted-configuration checks.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Synced configurations can diverge 🐞 Bug ☼ Reliability
Description
TARGETS lists the same mutable upstream stack file twice, and the synchronization loop downloads
it independently before producing each destination. If the selected branch advances between
requests, lightspeed-stack.yaml and its no-OKP variant are generated from different upstream
revisions and can be committed together as though synchronized.
Code

scripts/sync-lightspeed-configs.sh[R12-13]

+  "lightspeed-core-configs/lightspeed-stack.yaml|${LIGHTSPEED_DIR}/lightspeed-stack.yaml|copy_fetched_file"
+  "lightspeed-core-configs/lightspeed-stack.yaml|${LIGHTSPEED_DIR}/lightspeed-stack-no-okp.yaml|strip_okp_config"
Relevance

●● Moderate

The synchronization race is technically plausible, but no historical precedent establishes team
treatment of this edge case.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Both new target entries name lightspeed-core-configs/lightspeed-stack.yaml, but the loop invokes
fetch_file separately for every target. The workflow passes a mutable release branch to the script
and stages all generated destinations from one run, so there is no immutable revision or shared
downloaded source enforcing consistency.

scripts/sync-lightspeed-configs.sh[11-34]
scripts/sync-lightspeed-configs.sh[126-144]
.github/workflows/sync-lightspeed-configs.yaml[36-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The full and no-OKP configurations are produced from separate requests to the same mutable branch, allowing one synchronization run to mix upstream revisions.

## Fix Focus Areas
- scripts/sync-lightspeed-configs.sh[11-34]
- scripts/sync-lightspeed-configs.sh[126-144]

## Recommended Fix
Fetch every distinct `source_path` once into the temporary directory and apply all destination transforms to that cached file. Alternatively, resolve the requested ref to one immutable commit SHA before downloading any targets and use that SHA for every request.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Cross-repo context — repo relationships
  Explored: repo: redhat-developer/rhdh-plugins (sha: 8c84e6ff)
  Explored: repo: redhat-developer/rhdh (sha: 24f9e3f0)
Review mode: 🧠 Deep: This broad feature changes Compose behavior, CI workflows, shell transformation logic, service configuration, and optional container networking across many independent paths, creating a high density of subtle integration and startup defects.

Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread .github/workflows/nightly.yaml Outdated
composeConfig:
- name: "default"
cliArgs: ""
cliArgs: "-f compose.yaml"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
cliArgs: "-f compose.yaml"
cliArgs: ""

Shouldn't change anything (as long as the default compose file isn't renamed), but this was actually intentional to test the OOTB case of users simply running podman|docker compose up without any -f ...

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.

Updated, can you PTAL

@@ -0,0 +1,39 @@
# Copy this file to compose.override.yaml to enable OKP-backed product documentation.

@rm3l rm3l Sep 18, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since OKP is now opt-in, I'd recommend using the existing compose overlay pattern that we leverage (see orchestrator, postgresql, corporate proxy compose files).
If possible, it would be much simpler IMO for users to just run something like podman compose -f compose.yaml -f intelligent-assistant/compose-with-okp.yaml up -d to get OKP.
It would also make the OKP overlay easier to test in CI (instead of all the conditional steps you currently have in action.yaml), I think. And also composable with other overlays if needed, like run RHDH Local with both OKP and Orchestrator enabled.

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.

Updated, can you PTAL

ENCRYPT: "false"
ports: # dclint disable-line no-unbound-port-interfaces
- "8081:8080"
- "8983:8983"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
- "8983:8983"
- "127.0.0.1:8983:8983"

This Solr admin UI should ideally be bound to the loopback interface only. No reason to be network-exposed IMO.

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.

Updated, can you PTAL

maysunfaisal and others added 5 commits September 18, 2026 16:46
Signed-off-by: Maysun J Faisal <maysunaneek@gmail.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants