Skip to content

fix: configurable model name + debug logging (#21)#22

Open
freema wants to merge 1 commit intomainfrom
fix/21-hardcoded-model-debug-logging
Open

fix: configurable model name + debug logging (#21)#22
freema wants to merge 1 commit intomainfrom
fix/21-hardcoded-model-debug-logging

Conversation

@freema
Copy link
Copy Markdown
Owner

@freema freema commented Mar 28, 2026

Summary

  • Fix hardcoded model: 'claude-opus-4-5' → default 'openclaw' (configurable via OPENCLAW_MODEL env var / --model CLI flag)
  • Implement DEBUG=true logging that was documented but never wired up — now logs request/response bodies for troubleshooting (credentials redacted, headers never logged, bodies truncated to 4096 chars)
  • Add bridge/gateway compatibility table to docs

Closes #21

Changes

  • src/openclaw/client.ts — configurable model param, debug logging in request() method
  • src/utils/logger.tssetDebugEnabled() + logDebug() functions
  • src/cli.ts--model / -m and --debug CLI options (respects DEBUG=true and NODE_ENV=development)
  • src/openclaw/registry.ts — passes model to all client instances
  • src/index.ts — wires debug + model through registry
  • Config.env.example, docker-compose.yml updated
  • Docs — configuration.md, logging.md, installation.md, deployment.md, README.md
  • Tests — new tests for custom model, logDebug, setDebugEnabled

Test plan

  • npm run typecheck — 0 errors
  • npm run test:run — 136/136 passed
  • npm run lint — clean
  • npm run build — success
  • End-to-end test against live gateway (waiting for reporter confirmation)

Change hardcoded model 'claude-opus-4-5' to configurable OPENCLAW_MODEL
(default: 'openclaw') matching gateway API contract since 2026.3.24.
Implement DEBUG=true logging that was documented but never wired up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
freema added a commit to freema/openclaw-a2a that referenced this pull request Mar 28, 2026
Model was hardcoded to 'openclaw' which works for current gateways,
but should be configurable for custom agent routing setups.
Mirrors freema/openclaw-mcp#22.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@freema freema requested a review from Copilot March 29, 2026 20:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses gateway compatibility issues by making the chat completion model configurable and by wiring up the previously documented debug logging so request/response payloads can be inspected during troubleshooting.

Changes:

  • Replace hardcoded chat model with a default openclaw, configurable via OPENCLAW_MODEL and --model/-m.
  • Add debug logging support (DEBUG=true / --debug) and emit request/response diagnostics (with redaction + truncation).
  • Update docs and example configs to reflect the new model/debug options and compatibility guidance.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/utils/logger.ts Adds debug enablement and logDebug() support with sanitization.
src/openclaw/client.ts Uses configurable model; adds debug logging inside request() and logs gateway error bodies.
src/openclaw/registry.ts Passes the configured model through to all OpenClawClient instances.
src/index.ts Wires CLI debug/model into logger + registry and logs selected startup settings.
src/config/constants.ts Introduces DEFAULT_MODEL constant.
src/cli.ts Adds --model/-m and --debug CLI flags, plus env var defaults.
src/tests/utils/logger.test.ts Adds coverage for debug toggling and sanitization in debug logs.
src/tests/openclaw/client.test.ts Updates expected default model and tests custom model usage.
docs/logging.md Documents debug behavior and what is/isn’t logged at different levels.
docs/installation.md Updates CLI help snippet to include --model and --debug.
docs/deployment.md Adds compatibility table and troubleshooting guidance for 400s/model selection.
docs/configuration.md Documents OPENCLAW_MODEL env var.
docker-compose.yml Adds OPENCLAW_MODEL and DEBUG to environment section.
README.md Adds OPENCLAW_MODEL to example configurations.
.env.example Documents OPENCLAW_MODEL and clarifies debug behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


### `400 Bad Request` from gateway on `openclaw_chat`

Gateway versions 2026.3.24+ require `model: "openclaw"` (or `"openclaw/<agentId>"`). The MCP bridge defaults to `"openclaw"` since v1.3.1. If you're using an older bridge version, upgrade or set `OPENCLAW_MODEL=openclaw`. If you need custom model routing, set `OPENCLAW_MODEL` to the value your gateway expects.
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

Docs inconsistency: this section says the bridge defaults to model: "openclaw" since v1.3.1, but the compatibility table above states the fix is present in ≥ 1.3.0, and package.json currently reports version 1.3.0. Please align the stated version(s) so users know which release contains the change.

Suggested change
Gateway versions 2026.3.24+ require `model: "openclaw"` (or `"openclaw/<agentId>"`). The MCP bridge defaults to `"openclaw"` since v1.3.1. If you're using an older bridge version, upgrade or set `OPENCLAW_MODEL=openclaw`. If you need custom model routing, set `OPENCLAW_MODEL` to the value your gateway expects.
Gateway versions 2026.3.24+ require `model: "openclaw"` (or `"openclaw/<agentId>"`). The MCP bridge defaults to `"openclaw"` since v1.3.0. If you're using an older bridge version, upgrade or set `OPENCLAW_MODEL=openclaw`. If you need custom model routing, set `OPENCLAW_MODEL` to the value your gateway expects.

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +52
logDebug(`Request: ${options.method ?? 'GET'} ${url}`);
if (options.body) {
logDebug(`Request body: ${this.truncateForLog(options.body as string)}`);
}
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

In request(), the debug message string is always constructed (including truncateForLog(...)) before calling logDebug, even when debug is disabled. This defeats the purpose of a cheap debug path and can become noticeable for large bodies. Consider adding an isDebugEnabled() (or a lazy logDebug(() => string) API) and guarding the body truncation/formatting behind it.

Copilot uses AI. Check for mistakes.
Comment on lines 67 to 73
if (!response.ok) {
const errorBody = await response.text();
logDebug(`Response error (${response.status}): ${this.truncateForLog(errorBody)}`);
throw new OpenClawApiError(
`API request failed: ${response.status} ${response.statusText}`,
response.status
);
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

request() always reads the full error response body (await response.text()) even when debug logging is disabled, and it does so without applying the existing 10MB size guard (Content-Length/body length) used for successful responses. This can add unnecessary latency/memory use on errors and allows very large error bodies to bypass the limit. Consider only reading/logging the body when debug is enabled, and applying the same MAX_RESPONSE_SIZE_BYTES checks before consuming it.

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +34
export function logDebug(message: string): void {
if (debugEnabled) {
console.error(`[openclaw-mcp] DEBUG: ${sanitizeLogMessage(message)}`);
}
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

logDebug() currently can't be used in a way that avoids eager computation of log messages at call sites (template interpolation runs before the function sees debugEnabled). To keep debug logging truly low-overhead, consider exposing an isDebugEnabled() getter or changing logDebug to accept a callback so callers can skip expensive string building/truncation when debug is off.

Suggested change
export function logDebug(message: string): void {
if (debugEnabled) {
console.error(`[openclaw-mcp] DEBUG: ${sanitizeLogMessage(message)}`);
}
export function isDebugEnabled(): boolean {
return debugEnabled;
}
export function logDebug(message: string): void;
export function logDebug(messageFactory: () => string): void;
export function logDebug(messageOrFactory: string | (() => string)): void {
if (!debugEnabled) {
return;
}
const message =
typeof messageOrFactory === 'function' ? messageOrFactory() : messageOrFactory;
console.error(`[openclaw-mcp] DEBUG: ${sanitizeLogMessage(message)}`);

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +42
.option('model', {
alias: 'm',
type: 'string',
description: 'Model name for chat completions',
default: process.env.OPENCLAW_MODEL || DEFAULT_MODEL,
})
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

The new --model / OPENCLAW_MODEL value is accepted as-is, including empty/whitespace strings (e.g., OPENCLAW_MODEL=), which would produce requests with model: "" and likely lead to hard-to-diagnose 400s. Consider validating model after parsing (non-empty, trimmed) and failing fast with a clear error message.

Copilot uses AI. Check for mistakes.
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.

openclaw_chat returns 400 Bad Request with local Ollama/Qwen gateway

2 participants