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
9 changes: 9 additions & 0 deletions docs/_static/install-builder.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export function buildCommand(state) {
}
for (const name of ['ui', 'execution', 'observability', ...Object.keys(modules).filter(name => !observabilityServices.includes(name))]) set(`modules.${name}.enabled`, ['ui', 'execution'].includes(name) || enabled.has(name));
set('modules.bcm.redfish.enabled', enabled.has('bcm') && !!state.redfish);
set('llm.requestCompatibility.researchToolCalls.enabled', enabled.has('research') && !!state.researchToolCalls);
if (enabled.has('research') && state.researchToolCalls) set('llm.requestCompatibility.enabled', true);
for (const service of ['prometheus', 'alertmanager']) {
set(`observability.${service}Url`, enabled.has(service) ? value(`${service}Url`) : '', true);
}
Expand Down Expand Up @@ -115,12 +117,17 @@ if (root) {
const redfishOptions = document.createElement('div'); redfishOptions.className = 'builder-suboptions';
const redfishLabel = document.createElement('label'); const redfishInput = document.createElement('input'); redfishInput.type = 'checkbox'; redfishInput.name = 'redfish';
redfishInput.addEventListener('change', () => {state.redfish = redfishInput.checked; update(false);}); redfishLabel.append(redfishInput, document.createTextNode('Read-only Redfish')); redfishOptions.append(redfishLabel);
const researchOptions = document.createElement('div'); researchOptions.className = 'builder-suboptions';
const researchLabel = document.createElement('label'); const researchInput = document.createElement('input'); researchInput.type = 'checkbox'; researchInput.name = 'researchToolCalls';
researchInput.addEventListener('change', () => {state.researchToolCalls = researchInput.checked; update(false);}); researchLabel.append(researchInput, document.createTextNode('Search tool compatibility workaround')); researchOptions.append(researchLabel);
for (const [name, label] of Object.entries(modules)) {
const wrapper = document.createElement('label'); const input = document.createElement('input'); input.type = 'checkbox'; input.name = name;
input.addEventListener('change', () => {const requested = new Set(state.modules); input.checked ? requested.add(name) : requested.delete(name); state.modules = [...requested]; update(true);});
wrapper.append(input, document.createTextNode(label)); inputs.set(name, input);
if (name === 'bcm') {
const block = document.createElement('div'); block.className = 'builder-module'; block.append(wrapper, redfishOptions); buttons.append(block);
} else if (name === 'research') {
const block = document.createElement('div'); block.className = 'builder-module'; block.append(wrapper, researchOptions); buttons.append(block);
} else buttons.append(wrapper);
}
moduleGroup.append(buttons); form.append(moduleGroup);
Expand All @@ -142,6 +149,7 @@ if (root) {
function update(renderSettings) {
const enabled = enabledModules(state);
redfishOptions.hidden = !enabled.has('bcm'); redfishInput.checked = !!state.redfish;
researchOptions.hidden = !enabled.has('research'); researchInput.checked = !!state.researchToolCalls;
for (const [name, input] of inputs) {input.checked = enabled.has(name); input.disabled = enabled.has(name) && !state.modules.includes(name);}
if (renderSettings) {
settingsBody.replaceChildren();
Expand Down Expand Up @@ -177,6 +185,7 @@ if (root) {
if (enabled.has('bcm')) notes.push(`Create ${state.bcmSecret || fields.bcmSecret[1]} with key id_ecdsa; its SSH identity must bootstrap the read-only CMSH user.`);
if (enabled.has('bcm') && state.redfish) notes.push('Redfish reads node BMCs through the BCM head using credentials stored in BCM. Resets and configuration changes are unavailable. BMC TLS certificate verification is off by default; see the Redfish installation guide to configure it.');
if (enabled.has('research')) notes.push('Create iraop-secrets with NVIDIA_API_KEY, NVIDIA_CHAT_API_KEY and IRAOP_API_KEY; prepare the corpus directory.');
if (enabled.has('research') && state.researchToolCalls) notes.push('The search workaround is for inference backends returning named search arguments as ordinary text. Verify the affected protocol first; it does not establish answer or citation quality. Full request tracing stays disabled by default.');
if (enabled.has('webSearch')) notes.push('Web search uses DuckDuckGo without an API key; the OpenClaw pod needs HTTPS egress to duckduckgo.com. Clear it for air-gapped installations.');
if (state.inference !== 'external') notes.push('Verify GPU, memory and model cache requirements in the on-prem inference section.');
prerequisites.textContent = notes.join(' '); code.textContent = buildCommand(state); status.textContent = '';
Expand Down
55 changes: 55 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,61 @@ helm upgrade mosaic "$MOSAIC_CHART" \
unset NVIDIA_API_KEY IRAOP_API_KEY
```

`iraop_query` requires a nonempty answer and at least one document reference with
a filename and positive page number. A response without that evidence returns
`status: "incomplete"` and an error event in the Research panel. Its unverified
answer is withheld from model-visible content; the full original MCP response
remains in the tool result's `details` in the OpenClaw session transcript. The
chat history API may omit `details`. OpenClaw assigns its transport-level
`isError` flag independently, so `isError: false` does not mean research passed.

Missing sources can reflect an agent or model/tool execution problem even when
the PDF is indexed and direct search works. Check collection metadata, the
original PDF, actual search execution and citations separately. A source
reference alone does not establish that every claim or inline citation is
correct, or that a proposed cause matches the current cluster.

#### Optional research tool compatibility

Some inference configurations return a named search tool's JSON arguments as
ordinary text, without an OpenAI `tool_calls` envelope. The research agent then
never executes the search. An opt-in workaround is available in the existing
LLM compatibility proxy:

```bash
helm upgrade mosaic "$MOSAIC_CHART" \
--devel -n mosaic --reuse-values \
--set modules.research.enabled=true \
--set llm.requestCompatibility.enabled=true \
--set llm.requestCompatibility.researchToolCalls.enabled=true \
--wait --timeout 12m
```

This setting is disabled by default. For an initial research request exposing
`task` and the supported query-only `opensearch_search` schema, it explicitly
selects that read-only search and disables thinking for this first generation.
It wraps only a complete, validated JSON argument object into the named tool
envelope; the original research agent must execute the actual search. Proper
upstream tool calls pass through. Explicit selection of another tool, synthesis
after a tool result, and unrelated OpenClaw requests retain their existing
behavior. Malformed or unfinished arguments return an error, never a fabricated
search result. Collection scope remains enforced by the research service.

Use this workaround only after reproducing the protocol problem. For example,
the installed vLLM `Qwen3CoderToolParser` may declare named/required tool calls
unsupported; the checkpoint's documented parser configuration should also be
checked. This proxy setting does not change or restart the model server, and
does not certify document relevance, citation accuracy or general answer quality.

For a controlled validation, additionally set
`llm.requestCompatibility.researchToolCalls.auditEnabled=true`. Full research
request bodies, raw upstream response bytes and returned response bytes are
saved as Base64 in `/audit/records` inside the proxy Pod. Authentication/cookie
headers are excluded. These traces can contain private prompts and documents;
export them to the authorized evidence location before replacing the Pod.
The volume is temporary and limited to 128 MiB; audit write failures fail the
request. Disable this tracing setting after the required evidence is exported.

### Hardware Agent

The Hardware Agent reuses the Base Command Manager head address and `bcm-host-ssh-key` configured above. The chart exposes the required Base Command Manager lookup inside the cluster and generates its internal credentials. It uses NVDebug evidence and generic analysis.
Expand Down
2 changes: 2 additions & 0 deletions docs/installation_builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ CPU, RAM, GPUs and disk update automatically with your selections. Values come f

Select Base Command Manager to expose the optional **Read-only Redfish** checkbox inside its module block. See the [Redfish installation guide](installation.md#read-only-redfish) for BMC credential resolution and TLS verification settings.

Select Research to expose the optional **Search tool compatibility workaround** checkbox. Leave it off unless the inference backend returns named search arguments as ordinary text and the agent fails to execute the search. See [research evidence validation](installation.md#research) and [the compatibility guide](installation.md#optional-research-tool-compatibility) for the supported schema and verification steps. The builder does not enable full request-body tracing; temporary tracing requires separate controlled configuration and export.

```{raw} html
<div id="install-command-builder"><noscript>Enable JavaScript to use the builder, or follow the <a href="installation.html">installation guide</a>.</noscript></div>
```
Binary file modified helm/mosaic-stack/files/agent-documentation.tar.gz
Binary file not shown.
Loading
Loading