This is an automated email from the ASF dual-hosted git repository.

ArafatKhan2198 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone-site.git


The following commit(s) were added to refs/heads/master by this push:
     new 557a0a393b HDDS-15915. Document Recon chatbot gateway provider and 
update JCEKS setup in admin guide. (#496).
557a0a393b is described below

commit 557a0a393b4754a87c287252f70532f7b9912a1e
Author: Arafat2198 <[email protected]>
AuthorDate: Mon Jul 20 13:49:00 2026 +0530

    HDDS-15915. Document Recon chatbot gateway provider and update JCEKS setup 
in admin guide. (#496).
---
 .../02-recon/03-recon-ai-assistant.mdx             | 107 +++++++++++++++++++--
 1 file changed, 97 insertions(+), 10 deletions(-)

diff --git 
a/docs/05-administrator-guide/03-operations/09-observability/02-recon/03-recon-ai-assistant.mdx
 
b/docs/05-administrator-guide/03-operations/09-observability/02-recon/03-recon-ai-assistant.mdx
index b77cb7df44..301d08cfa7 100644
--- 
a/docs/05-administrator-guide/03-operations/09-observability/02-recon/03-recon-ai-assistant.mdx
+++ 
b/docs/05-administrator-guide/03-operations/09-observability/02-recon/03-recon-ai-assistant.mdx
@@ -69,14 +69,16 @@ one interface (see [Supported providers & 
models](#supported-providers)).
 
 ## 3. Supported providers & models {#supported-providers}
 
-The assistant supports **three** `LLM` providers. You configure one (or more) 
by supplying an API key;
-a provider with no key is simply unavailable.
+The assistant supports **three direct** `LLM` providers plus a **`gateway`** 
provider for
+OpenAI-compatible gateways. You configure one (or more) by supplying an API 
key; a provider with no
+key is simply unavailable.
 
 | Provider | Reached via | Notes |
 |---|---|---|
 | **OpenAI** | Native OpenAI API (`https://api.openai.com`) | Standard 
chat-completions API. |
 | **Google Gemini** | Google's **OpenAI-compatible** endpoint 
(`https://generativelanguage.googleapis.com/v1beta/openai/`) | Used instead of 
the native Gemini client for reliable timeout handling. |
 | **Anthropic (Claude)** | Native Anthropic API | Sends a beta header for the 
1M-token context window (`anthropic.beta.header`). |
+| **Gateway** | Your **OpenAI-compatible** gateway (for example LiteLLM), set 
via `gateway.base.url` | One endpoint for many models (OpenAI, Claude, Gemini). 
See [Using an OpenAI-compatible gateway](#gateway-provider). |
 
 **Default model lists** (configurable without a code change; surfaced by `GET 
/chatbot/models`):
 
@@ -85,6 +87,7 @@ a provider with no key is simply unavailable.
 | OpenAI | `ozone.recon.chatbot.openai.models` | `gpt-4.1, gpt-4.1-mini, 
gpt-4.1-nano` |
 | Gemini | `ozone.recon.chatbot.gemini.models` | `gemini-2.5-pro, 
gemini-2.5-flash, gemini-3-flash-preview, gemini-3.1-pro-preview` |
 | Anthropic | `ozone.recon.chatbot.anthropic.models` | `claude-opus-4-6, 
claude-sonnet-4-6` |
+| Gateway | `ozone.recon.chatbot.gateway.models` | _(none - you must list the 
aliases your gateway exposes)_ |
 
 The **default selection** is provider `gemini`, model `gemini-2.5-flash`.
 
@@ -104,6 +107,56 @@ actually configured. This explains why an answer can come 
from a different model
   **default model** is used.
 - If the resolved model is not valid for the resolved provider, **both reset 
to the defaults**.
 
+### Using an OpenAI-compatible gateway {#gateway-provider}
+
+If you route all `LLM` traffic through a single **OpenAI-compatible gateway** 
(for example LiteLLM),
+use the dedicated `gateway` provider instead of the direct 
`openai`/`gemini`/`anthropic` providers.
+This is the cleanest option when OpenAI, Claude, and Gemini models are all 
served behind one endpoint
+and one API key.
+
+| Key | Required | Description |
+|---|---|---|
+| `ozone.recon.chatbot.provider` | yes | Set to `gateway`. |
+| `ozone.recon.chatbot.gateway.base.url` | yes | Your gateway's 
OpenAI-compatible base URL (no default). |
+| `ozone.recon.chatbot.gateway.api.key` | yes | Gateway API key (prefer 
`JCEKS` - see [Managing API keys](#managing-api-keys)). |
+| `ozone.recon.chatbot.gateway.models` | yes | Comma-separated model aliases 
your gateway exposes. |
+| `ozone.recon.chatbot.default.model` | no | Default model (should be one of 
the aliases above). |
+
+Example (`ozone-site.xml`):
+
+```xml
+<property>
+  <name>ozone.recon.chatbot.enabled</name>
+  <value>true</value>
+</property>
+<property>
+  <name>ozone.recon.chatbot.provider</name>
+  <value>gateway</value>
+</property>
+<property>
+  <name>ozone.recon.chatbot.gateway.base.url</name>
+  <value>https://your-gateway/v1</value>
+</property>
+<property>
+  <name>ozone.recon.chatbot.gateway.models</name>
+  <value>gpt-4o,claude-sonnet,gemini-2.5-pro</value>
+</property>
+<property>
+  <name>ozone.recon.chatbot.default.model</name>
+  <value>claude-sonnet</value>
+</property>
+```
+
+Key points:
+
+- **Model aliases must match exactly** what your gateway exposes. There is no 
auto-discovery; you
+  maintain the list in `gateway.models`.
+- The UI groups models by name prefix (`gpt*` → OpenAI, `claude*` → Anthropic, 
`gemini*` → Gemini)
+  for display, but every request is routed through the single `gateway` 
provider.
+- There is **no** `anthropic.base.url` override. To reach Claude models 
through an OpenAI-compatible
+  endpoint, use the `gateway` provider.
+- Recon fails fast if `gateway.base.url` is missing while the gateway provider 
is in use.
+
 ## 4. Prerequisites & network egress
 
 Before enabling the assistant:
@@ -191,8 +244,9 @@ The credential **alias must equal the config key name** 
(for example
      -provider localjceks://file/etc/security/recon-keys.jceks
    ```
 
-   Repeat for `ozone.recon.chatbot.openai.api.key` and
-   `ozone.recon.chatbot.anthropic.api.key` as needed. The command prompts for 
the secret value.
+   Repeat for the aliases you use - for example 
`ozone.recon.chatbot.openai.api.key`,
+   `ozone.recon.chatbot.anthropic.api.key`, or 
`ozone.recon.chatbot.gateway.api.key` (when using the
+   [gateway provider](#gateway-provider)). The command prompts for the secret 
value.
 
 2. Point Recon at the keystore in `ozone-site.xml`:
 
@@ -204,14 +258,42 @@ The credential **alias must equal the config key name** 
(for example
    ```
 
 3. Protect the keystore. Restrict file permissions (for example `chmod 600`, 
owned by the Recon
-   service user) and supply the keystore password out-of-band - for example via
-   `HADOOP_CREDSTORE_PASSWORD` or a password file - rather than relying on the 
default.
+   service user) and supply the keystore password out-of-band, rather than 
relying on the default.
+   There are two ways to provide the keystore password:
+
+   - **Environment variable** - set `HADOOP_CREDSTORE_PASSWORD` in the Recon 
process environment.
+   - **Password file** - set 
`hadoop.security.credstore.java-keystore-provider.password-file` in
+     `ozone-site.xml`. Its value is a **filename** (resolved on the 
classpath/config dir), not the
+     password itself; store the password in that file and restrict its 
permissions.
 
 4. Restart Recon and verify with `GET /api/v1/chatbot/health` 
(`llmClientAvailable` should be `true`).
 
+> **Important - remove plaintext keys when using `JCEKS`.** Recon resolves 
secrets `JCEKS`-first and
+> **falls back to plaintext** in `ozone-site.xml`. If a plaintext key is left 
in place, Recon may
+> silently use it even when you believe the keystore is in effect. For a true 
secure setup, delete
+> the plaintext `*.api.key` entries so the keystore is the only source.
+
+**Verify the key really comes from `JCEKS`:**
+
+- `GET /api/v1/chatbot/health` returns `llmClientAvailable: true`.
+- `ozone getconf -confKey ozone.recon.chatbot.gateway.api.key` (or the 
relevant provider key) returns
+  **empty** - confirming there is no plaintext key and the value is sourced 
from the keystore.
+
+**Failure behavior to expect:**
+
+- **Wrong or missing keystore password** - every alias in that keystore 
becomes unreadable, so all
+  `JCEKS`-sourced providers go unavailable at once (`llmClientAvailable: 
false`).
+- **Missing / unreadable key** - `health` reports `llmClientAvailable: false`. 
If the chatbot is still
+  `enabled` and the affected provider is the only one configured (common with 
`gateway`), a `/chat`
+  request fails at query time with **HTTP 500** (not 503). Use `health` as the 
reliable indicator.
+
 **Rotation / removal:** update or delete the alias with `hadoop credential 
create` / `hadoop
-credential delete`, then restart Recon. If a key is missing, that provider is 
simply unavailable; the
-feature still works through any other configured provider.
+credential delete`, then **restart Recon** (new alias values take effect only 
after a restart). If a
+key is missing, that provider is simply unavailable; the feature still works 
through any other
+configured provider.
+
+> **Note:** `JCEKS` does **not** require a secure/Kerberized cluster - it 
works on unsecure clusters
+> too.
 
 | Environment | Recommended storage |
 |---|---|
@@ -252,7 +334,7 @@ All keys are under the prefix `ozone.recon.chatbot.`.
 
 | Key | Default | Description |
 |---|---|---|
-| `provider` | `gemini` | Default provider: `openai`, `gemini`, or 
`anthropic`. |
+| `provider` | `gemini` | Default provider: `openai`, `gemini`, `anthropic`, 
or `gateway`. |
 | `default.model` | `gemini-2.5-flash` | Default model when none is requested 
or the requested one is unavailable. |
 
 ### API keys (see Section 6)
@@ -262,6 +344,7 @@ All keys are under the prefix `ozone.recon.chatbot.`.
 | `openai.api.key` | _(none)_ | OpenAI API key. Prefer `JCEKS` storage. |
 | `gemini.api.key` | _(none)_ | Gemini API key. Prefer `JCEKS` storage. |
 | `anthropic.api.key` | _(none)_ | Anthropic API key. Prefer `JCEKS` storage. |
+| `gateway.api.key` | _(none)_ | Gateway API key (used when 
`provider=gateway`). Prefer `JCEKS` storage. |
 
 ### Base URL overrides
 
@@ -269,6 +352,7 @@ All keys are under the prefix `ozone.recon.chatbot.`.
 |---|---|---|
 | `openai.base.url` | `https://api.openai.com` | Override to target an 
OpenAI-compatible gateway. |
 | `gemini.base.url` | 
`https://generativelanguage.googleapis.com/v1beta/openai/` | Gemini's 
OpenAI-compatible endpoint. |
+| `gateway.base.url` | _(none)_ | Required when `provider=gateway`. Your 
OpenAI-compatible gateway URL. Recon fails fast if unset while the gateway 
provider is in use. |
 
 ### Execution policy
 
@@ -293,6 +377,7 @@ All keys are under the prefix `ozone.recon.chatbot.`.
 | `openai.models` | `gpt-4.1, gpt-4.1-mini, gpt-4.1-nano` |
 | `gemini.models` | `gemini-2.5-pro, gemini-2.5-flash, gemini-3-flash-preview, 
gemini-3.1-pro-preview` |
 | `anthropic.models` | `claude-opus-4-6, claude-sonnet-4-6` |
+| `gateway.models` | _(none - list the aliases your gateway exposes, e.g. 
`gpt-4o, claude-sonnet, gemini-2.5-pro`)_ |
 
 ### Anthropic header
 
@@ -456,7 +541,7 @@ should offer. The list is empty when no provider is 
configured:
 | 400 | Empty/blank query. |
 | 503 | Feature disabled, or the request queue is full (overloaded). |
 | 504 | Request exceeded `request.timeout.ms`. |
-| 500 | Internal error (details are logged, not returned). |
+| 500 | Internal error (details are logged, not returned). Also returned when 
the resolved provider has no usable key at query time - for example a `JCEKS` 
key that cannot be read - and no other provider is configured. Check `GET 
/api/v1/chatbot/health`. |
 
 The `userId` is masked in logs so identities are not leaked.
 
@@ -516,6 +601,8 @@ The shipped versions are tuned for Recon - change them 
deliberately.
 | Empty answer from a reasoning model (e.g. `gemini-2.5-pro`) | The model 
spent its token budget "thinking". Prefer a fast model (flash), or raise token 
limits. |
 | Answered by an unexpected model/provider | Routing fallback - the requested 
provider/model was not configured. See 
[routing](#provider--model-routing-fallback-behavior). |
 | "No API key configured" | Check the provider, the key, and 
`hadoop.security.credential.provider.path`. |
+| `llmClientAvailable: false` after enabling `JCEKS` | Wrong/missing keystore 
password (`HADOOP_CREDSTORE_PASSWORD` or the password file), or the alias name 
does not match the config key. A bad password makes **all** aliases in that 
keystore unreadable. |
+| Chat works but you expected `JCEKS` to be in use | A plaintext `*.api.key` 
is still present and is used as fallback. Remove it; confirm `ozone getconf` 
returns empty for the key. |
 | HTTP 504 (timeout) / HTTP 503 (overloaded) | Tune `thread.pool.size`, 
`max.queue.size`, `request.timeout.ms`. |
 | Stale answers | Recon sync lag - answers reflect the last sync. Check 
`api_v1_task_status`. |
 | Egress / connection failures | Firewall, proxy, or `*.base.url`. See 
[Prerequisites & egress](#4-prerequisites--network-egress). |


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to