#Verbose in chat despite changes

1 messages · Page 1 of 1 (latest)

rough quiver
#

I realize there are other posts already discussing this. I've looked through them.

My bot is being verbose after updating openclaw to the most recent version today. Prior, I was running a version from early February. I've been talking this through with the bot as well, which most recently said verbosely: "The user is frustrated that I'm still being verbose despite all the changes we've made. They've shown me a screenshot demonstrating this. Let me look at the screenshot to see what I'm doing wrong."

The session's settings are as follows: thinking:inherit, fast:inherit, verbose:off(explicit), reasoning:off

It's also begun to react messages repeatedly since updating...

Hosting & openclaw info:
Host device - Raspberry Pi
Model - Kimi 2.5 via API

fading topazBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

calm thunderBOT
#

This smells like two separate “new defaults” biting you after the update:

1) “Verbose” text that looks like inner monologue is usually thinking, not /verbose

On recent versions, reasoning-capable models default to a non-off thinking level unless you explicitly disable it. With Moonshot/Kimi, “thinking enabled” can come back as plain assistant text (so /verbose off won’t help).

Try in that exact chat (as a standalone message):

/think off

Then send a normal message and see if the self-talk stops.

If that fixes it and you want it globally, set the config default to off (current schema):

#
{
  agents: {
    defaults: {
      model: {
        thinkingDefault: "off",
      },
    },
  },
}

Docs: https://docs.openclaw.ai/tools/thinking

2) “Reacting repeatedly” is very often the new ack reaction

OpenClaw can add an acknowledgement reaction while it’s processing. If you don’t want that on Discord, disable it:

#
{
  channels: {
    discord: {
      ackReaction: "",
    },
  },
  // or globally:
  messages: {
    ackReaction: "",
  },
}

If you do like the ack reaction but just want it removed after the reply:

#
{
  messages: {
    removeAckAfterReply: true,
  },
}

Config reference: https://docs.openclaw.ai/gateway/configuration-reference#messages (ackReaction)

Quick sanity check (this also catches “two gateways running” issues)

Can you paste:

  • openclaw --version
  • openclaw gateway status

If you accidentally have two gateway processes connected to Discord, you can get “settings say verbose off, but it still happens” and extra reactions/events.

#

Also: are the reactions the same emoji every time (often 👀), or is it doing random/varied reactions? That tells us whether it’s ackReaction vs the model calling react as a tool.

rough quiver
calm thunderBOT
#

Yes — that distinction matters, and in your pasted config you’re actually using the right shape.

Correct config shape (current)

In current OpenClaw builds, these live at:

agents.defaults.thinkingDefault
agents.defaults.verboseDefault

…and not inside agents.defaults.model.

So this:

"agents": {
#
  "defaults": {
    "verboseDefault": "off",
    "thinkingDefault": "off"
  }
}

is correct.

My earlier snippet that showed them under agents.defaults.model was misleading (there’s a docs/example mismatch floating around).

Why it may still “talk like that” even with thinking off

Two common gotchas:

  1. GUI thinking selector vs session default
    In the web chat UI, the thinking dropdown often sets “thinking once” for the next message, but doesn’t always persist the session default the same way a directive does.
#

To hard-force it for that chat/session, do this in Discord (standalone message):

/think off

Then send a normal message and see if the “The user is frustrated…” style text stops.

  1. If it still does it after /think off, then it’s likely the model output itself, not OpenClaw “verbose mode”. In that case the fix is prompt-level:
  • add an instruction in your SOUL.md / channel system prompt like “Do not narrate your internal reasoning or next steps; reply with the answer only.”

Quick check I’d love to see

Can you paste:

  • openclaw --version
  • and one short example of the bot output (exact text), plus whether it’s also sending a separate Reasoning: message or if it’s all in the main reply?

That’ll tell us immediately whether OpenClaw is leaking a reasoning block, or Kimi is just being chatty in its normal output.

rough quiver
# calm thunder To hard-force it for that chat/session, do this in Discord (standalone message):...

Openclaw version output: OpenClaw 2026.3.12 (6472949)

I cannot do slash commands. I've re-added the bot to the Discord guild with that feature "checked", yet this feature never showed up. Enough time has elapsed that if it were a sync issue, it should have appeared by now.

Also, soul.md has already been edited and that did not work. The soul.md edit reads:
"Never narrate your thought process.** Don't say "I need to check..." or "Let me look at..." — just do it and report results. Actions, not commentary."

calm thunderBOT
#

Your config keys are fine where they are (agents.defaults.thinkingDefault / agents.defaults.verboseDefault). That part is not the problem.

What is important here:

1) You do not need Discord “native slash commands” for /think

OpenClaw’s /think, /verbose, /reasoning are message directives. They’re parsed from normal message text.

If Discord’s UI is being annoying about messages that start with /, send it with a leading space (the directive parser allows whitespace):

 /think off
 /verbose off
 /reasoning off

That should still set the session overrides even if native slash commands are not registered.

#

Docs: https://docs.openclaw.ai/tools/thinking

2) With Moonshot/Kimi, there’s a second “thinking” knob: native Moonshot thinking

Even if OpenClaw thinking is “off”, Moonshot can still be in native thinking mode unless you explicitly disable it per model.

Add this (exactly like the Moonshot provider docs):

{
  agents: {
    defaults: {
      models: {
        "moonshot/kimi-k2.5": {
          params: {
            thinking: { type: "disabled" },
          },
#
        },
      },
    },
  },
}

Docs (Moonshot “Native thinking mode” section): https://docs.openclaw.ai/providers/moonshot

3) Double-check you’re not accidentally on a “thinking” model variant

That “The user is frustrated…” text really looks like you might be hitting kimi-k2-thinking* instead of plain kimi-k2.5.

Can you paste just these two lines from your openclaw.json (redact keys, keep model ids):

  • agents.defaults.model.primary
  • the agents.defaults.models[...] entry for whichever moonshot model you’re using
#

4) Re: reactions repeating

If you mean the bot keeps adding an “eyes”/ack reaction while processing, that’s ackReaction. You can kill it with:

{ channels: { discord: { ackReaction: "" } } }

(or set messages.removeAckAfterReply: true if you want it to clean up after itself).

If you paste what emoji it’s reacting with, I can tell you immediately which mechanism it is.

rough quiver
calm thunderBOT
#

Got it — if you’re truly on:

  • agents.defaults.model.primary = "moonshot/kimi-k2.5"
  • and you’ve set agents.defaults.models["moonshot/kimi-k2.5"].params.thinking.type = "disabled"

…and it still emits “The user is frustrated…” style inner-monologue, then it’s almost certainly not the Moonshot “thinking” toggle anymore.

At this point the two highest-probability causes are:

A) You’re editing config/workspace that the running gateway service is not actually using

This would also explain why “doing it in chat” and SOUL changes appear to have no effect.

Can you paste the output of:

openclaw gateway status
#

Specifically, it prints lines like Config (cli) vs Config (service) (and usually the probe target). If those paths/state dirs don’t match, you can restart all day and it’ll keep running the “other” config.

If you can also paste:

openclaw status --all

that’s ideal — it’s designed to be shareable (tokens redacted) and usually makes mismatches obvious.

B) You’re actually receiving “reaction/system events” and the model is narrating them

Since you mentioned it’s reacting repeatedly after the update: Discord can feed reaction events into the session depending on reactionNotifications, and ack reactions can add noise too.

Two quick questions:

  1. What emoji is it “repeatedly reacting” with?
  2. In your Discord config, what is channels.discord.guilds.<guildId>.reactionNotifications set to?
#

(If you’re not sure, paste just that guild block with ids; redact token.)


One more clarifier: Discord native slash commands

The fact that Discord native slash commands never showed up is another hint you might have a service/config mismatch, because commands.native defaults to "auto" and usually registers on startup unless the service isn’t the one you think it is (or the bot invite is missing the application-commands scope).

So: openclaw gateway status is the key next datapoint here.

rough quiver
# calm thunder Got it — if you’re truly on: - `agents.defaults.model.primary = "moonshot/kimi-...

openclaw gateway status

Service: systemd (enabled)
File logs: /tmp/openclaw/openclaw-2026-03-14.log
Command: /usr/bin/node /home/rpi/.npm-global/lib/node_modules/openclaw/dist/index.js gateway --port 18789
Service file: ~/.config/systemd/user/openclaw-gateway.service
Service env: OPENCLAW_GATEWAY_PORT=18789

Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json

Gateway: bind=loopback (127.0.0.1), port=18789 (service args)
Probe target: ws://127.0.0.1:18789
Dashboard: http://127.0.0.1:18789/
Probe note: Loopback-only gateway; only local clients can connect.

Runtime: running (pid 6399, state active, sub running, last exit 0, reason 0)
RPC probe: ok


Also, channels.discord.guilds.<guildId>.reactionNotifications does not exist. channels.discord.guilds.<guildId> does exist, not .reactionNotifications

calm thunderBOT
#

Nice — that gateway status output rules out the “wrong config / wrong service” class of problems. So we can stop chasing that.

About reactionNotifications

It does exist in 2026.3.12 — it’s just optional, so it won’t be present in your file unless you add it.

Path (per the current schema + runtime code):

channels.discord.guilds["<guildId>"].reactionNotifications: "off" | "own" | "all" | "allowlist"

If you don’t set it, it defaults to "own".

So if you want to eliminate reaction events as a possible source of “noise”/loops, explicitly set it to off for that guild.

About the repeated reactions

Most likely this is just ack reactions being enabled by default now. If you want to completely stop that behavior on Discord:

#
{
  channels: {
    discord: {
      ackReaction: "",
    },
  },
}

(or globally: messages.ackReaction: "")

The “The user is frustrated…” text

Given you’re on moonshot/kimi-k2.5 (non-reasoning model in our docs) and you’ve explicitly disabled Moonshot native thinking, that style of output strongly suggests one of these:

  1. It’s not OpenClaw “verbose/thinking” at all — it’s the model’s normal output (Kimi sometimes does this meta narration even when not in “thinking mode”), or
  2. There’s a provider response parsing / reasoning-block stripping bug where something that should be treated as “reasoning” is getting merged into normal assistant text.
#

To tell which one it is, I need one more concrete artifact:

  • Paste an exact raw snippet of one of the bad replies as it appears in Discord (a few lines is enough).
  • And paste the corresponding log lines around that time from /tmp/openclaw/openclaw-2026-03-14.log (even 20–40 lines is fine). We’re looking for anything that mentions moonshot, thinking, reasoning, or “blocks”.

If you don’t want to dig logs yet, at least answer this: when it “reacts repeatedly”, what emoji is it using? If it’s 👀 (or your identity emoji), that’s 99% ackReaction. If it’s a variety of emojis, that’s the model calling the react tool.

rough quiver
# calm thunder To tell which one it is, I need one more concrete artifact: - Paste an **exact ...

It will constantly react, remove reaction, and then react again, cycling through 🤔 and 👨‍💻

I am text character limited here, so here are a couple logs relevant
grep log output

{"0":"{"subsystem":"gateway/reload"}","1":"config change detected; evaluating reload (agents.defaults.models.moonshot/kimi-k2.5.params, agents.defaults.contextPruning)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway/reload"}","parentNames":["openclaw"],"date":"2026-03-14T05:04:36.354Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"file:///home/rpi/.npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js:1058:14","fileName":"subsystem-DBBM_0ww.js","fileNameWithLine":"subsystem-DBBM_0ww.js:1058","fileColumn":"14","fileLine":"1058","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js:1058","method":"logToFile"}},"time":"2026-03-14T01:04:36.354-04:00"}
{"0":"{"subsystem":"gateway/reload"}","1":"config hot reload applied (agents.defaults.models.moonshot/kimi-k2.5.params)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway/reload"}","parentNames":["openclaw"],"date":"2026-03-14T05:04:36.359Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"file:///home/rpi/.npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js:1058:14","fileName":"subsystem-DBBM_0ww.js","fileNameWithLine":"subsystem-DBBM_0ww.js:1058","fileColumn":"14","fileLine":"1058","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js:1058","method":"logToFile"}},"time":"2026-03-14T01:04:36.360-04:00"}
"}

calm thunderBOT
#

Those two emojis are a huge clue.

  • 🤔 looks like someone configured an ack/processing reaction (either messages.ackReaction or channels.discord.ackReaction)
  • 👨‍💻 is very commonly the agent identity emoji (which is also used as the ackReaction fallback)

The fact it’s adding/removing in a loop and alternating strongly suggests you’ve hit a feedback loop like:

bot adds reaction → Discord emits a reaction event → OpenClaw ingests it (reactionNotifications) → treats it as a new inbound event → adds ackReaction again → …

Immediate stop-the-bleeding fix (Discord)

  1. Disable reaction notification ingestion for that guild:
{
  channels: {
    discord: {
#
      guilds: {
        "YOUR_GUILD_ID_HERE": {
          reactionNotifications: "off",
        },
      },
    },
  },
}
  1. Disable ack reactions (so even if something else triggers, you don’t see a reaction storm):
{
  channels: { discord: { ackReaction: "" } },
#
  // or globally:
  // messages: { ackReaction: "" }
}

Restart the gateway after that.

If you also want to ensure the model can’t call reactions as a tool (separate from ackReaction), you can additionally set:

{
  channels: {
    discord: {
      actions: { reactions: false },
    },
#
  },
}

Re: “reactionNotifications does not exist”

It’s not a top-level key and it won’t appear unless you add it, but it is valid on channels.discord.guilds.<id> on 2026.3.12 (it’s in the current schema/runtime). Put it alongside requireMention, channels, etc inside that guild object.

Your log snippet is actually good news

The “config hot reload applied (agents.defaults.models.moonshot/kimi-k2.5.params)” line confirms the gateway is seeing your config edits and applying them — so this isn’t a “wrong file” situation.


If you apply the three settings above and the reaction loop stops, then we can re-focus on the “verbose / inner-monologue” part. There’s a decent chance the reaction loop is what’s causing the bot to constantly re-enter runs and emit that meta narration.

If you want, paste your channels.discord.guilds block (just ids + those few fields; redact token) and I’ll point out exactly where to drop reactionNotifications: "off".

rough quiver
calm thunderBOT
#

Put it inside the guild object, at the same level as channels (and requireMention / users / etc if you have them).

Example (based on your snippet):

"channels": {
  "discord": {
    "enabled": true,
    "groupPolicy": "allowlist",
    "streaming": "off",
    "guilds": {
      "1213612874392670329": {
        "reactionNotifications": "off",
        "channels": {
          "vulcan": {
            "allow": true
#
          }
        }
      }
    }
  }
}

After you add that, I’d also strongly recommend disabling ack reactions while testing (since you’re seeing the reaction loop):

"channels": { "discord": { "ackReaction": "" } }

Then restart the gateway (or rely on hot reload if you see it apply in logs).

rough quiver
# calm thunder ```json5 } } } } } } ``` After you add that, I’d ...

Added both "reactionNotifications": "off", and { "ackReaction": "" } }
The narration issue still persists, but reaction loop has stopped. I asked an astrological question as a test. The bot began by stating: "The user is asking about the gases that make up Jupiter's Great Red Spot. This is a straightforward factual question. I should answer directly without narration."

Most recent log:
{"0":"{"subsystem":"gateway"}","1":"agent model: moonshot/kimi-k2.5","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway"}","parentNames":["openclaw"],"date":"2026-03-14T05:43:35.439Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"file:///home/rpi/.npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js:1058:14","fileName":"subsystem-DBBM_0ww.js","fileNameWithLine":"subsystem-DBBM_0ww.js:1058","fileColumn":"14","fileLine":"1058","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-DBBM_0ww.js:1058","method":"logToFile"}},"time":"2026-03-14T01:43:35.440-04:00"}

calm thunderBOT
#

Good — the reaction loop stopping after reactionNotifications: "off" + ackReaction: "" basically confirms we were in a reaction-event feedback loop.

Now for the remaining narration:

That preface (“The user is asking… I should…”) looks exactly like a reasoning/scratchpad leak. Since you’re on moonshot/kimi-k2.5 (non-thinking model) and you’ve already forced thinking: { type: "disabled" }, the next thing to verify is: what OpenClaw thinks the Moonshot provider/model capabilities are at runtime (reasoning on/off + which OpenAI-compatible API mode it’s using).

Can you run and paste just the Moonshot part of:

openclaw models status

I’m looking for:

  • provider moonshot “api:” value (ideally openai-completions)
  • whether the selected model is marked reasoning: true/false
  • which model is actually active

Why: if the provider is running in a mode where Moonshot returns a separate reasoning field/block, OpenClaw might be merging it into normal text (bug/regression), which would produce exactly what you’re seeing.

#

Temporary mitigation (while we diagnose)

If you want to try to “beat it into compliance” at the model level, add a strict per-model decoding param to reduce the tendency to preface:

{
  agents: {
    defaults: {
      models: {
        "moonshot/kimi-k2.5": {
          params: {
            temperature: 0,
          },
        },
      },
    },
  },
#
}

(Not a guaranteed fix, but it often reduces the “meta” chatter.)

Also: confirm SOUL.md is definitely being used

Even though config reload is working, it’s still possible your Discord agent/session is on a different workspace/agent. openclaw status --all usually shows which agent/workspace is active — if you can paste that, we can rule it out quickly.

Once I see models status, I can tell you whether this is (a) a provider-mode/capabilities mismatch we can fix in config, or (b) Moonshot returning the preface as plain content (in which case we’ll need a stronger prompt or different model).

rough quiver
#

openclaw models status
Config : ~/.openclaw/openclaw.json
Agent dir : ~/.openclaw/agents/main/agent
Default : moonshot/kimi-k2.5
Fallbacks (0) : -
Image model : -
Image fallbacks (0): -
Aliases (1) : Kimi -> moonshot/kimi-k2.5
Configured models (1): moonshot/kimi-k2.5

Auth overview
Auth store : ~/.openclaw/agents/main/agent/auth-profiles.json
Shell env : off
Providers w/ OAuth/tokens (0): -

  • anthropic effective=profiles:~/.openclaw/agents/main/agent/auth-profiles.json | profiles=1 (oauth=0, token=0, api_key=1) | anthropic:default=...
  • moonshot effective=profiles:~/.openclaw/agents/main/agent/auth-profiles.json | profiles=1 (oauth=0, token=0, api_key=1) | moonshot:default=...

calm thunderBOT
#

Reaction loop fixed = great, and that log line confirms you really are running moonshot/kimi-k2.5.

On the narration: the phrasing you quoted (“The user is asking… I should…”) is exactly the kind of “scratchpad” that usually comes from a reasoning-mode response format. The key detail is: openclaw models status output you pasted doesn’t show what Moonshot API mode OpenClaw is using (chat completions vs responses-style), and that can matter a lot for whether “reasoning” gets delivered as normal text.

Try forcing Moonshot to use Chat Completions mode explicitly

In ~/.openclaw/openclaw.json, add a models.providers.moonshot block and set api: "openai-completions" (this matches the Moonshot docs):

{
  models: {
    mode: "merge",
    providers: {
      moonshot: {
        baseUrl: "https://api.moonshot.ai/v1",
        api: "openai-completions",
      },
#
    },
  },
}

Then restart the gateway and re-test.

Why this is worth trying: if the gateway is currently using a responses-style format (or Moonshot is returning a reasoning field that’s being merged), you can get exactly the “The user is asking… I should…” preface even when you’ve disabled thinking.

If it still narrates after that

Then it’s almost certainly Moonshot returning that preface as plain content, and OpenClaw can’t reliably strip it (because it’s indistinguishable from “real answer” text). At that point the practical options are:

  • keep temperature: 0 (often helps a bit), and/or
  • switch to a model/provider that doesn’t emit scratchpad in content.

If you try the api: "openai-completions" change and it doesn’t fix it, I’d treat it as a provider/model behavior and/or file a GitHub issue with your version + this minimal repro text, because it’s a pretty bad UX regression.

rough quiver
calm thunderBOT
#

Yep — if models.providers.moonshot.api is already openai-completions, and you’re on moonshot/kimi-k2.5 with thinking: {type:"disabled"}, then OpenClaw isn’t “accidentally in a reasoning API mode”.

At this point that narration is almost certainly coming back in the model’s normal content (i.e. Kimi is “thinking out loud”), which OpenClaw can’t safely strip automatically without risking deleting real answer text.

Best remaining levers (that actually change behavior)

  1. Make the “no narration” rule self-correcting (this tends to work better than “never do X”) using a channel-level systemPrompt:
"channels": {
  "discord": {
    "guilds": {
      "1213612874392670329": {
        "channels": {
          "vulcan": {
            "allow": true,
            "systemPrompt": "Do not include any meta commentary (e.g. 'The user is asking...', 'I should...', 'Let me...'). If you generate any such sentences, delete them and output only the final answer."
#
          }
        }
      }
    }
  }
}
  1. Force deterministic decoding (often reduces preambles):
"agents": {
  "defaults": {
    "models": {
      "moonshot/kimi-k2.5": { "params": { "temperature": 0 } }
    }
#
  }
}

If those still don’t stop it, I’d file a GitHub issue with:

  • OpenClaw 2026.3.12 (6472949)
  • Moonshot provider + kimi-k2.5
  • one example output showing the scratchpad preface

Because at that point it’s either a Kimi behavior regression or we need an opt-in “strip scratchpad-style prefaces” feature in OpenClaw.

rough quiver
calm thunderBOT
#

Because two things can change “today”, even if you only changed one:

1) kimi-k2.5 is a moving target

Moonshot can (and does) update what’s behind the model id without changing the id. So it’s totally possible the backend model behavior shifted recently and started emitting that scratchpad-style preface more often.

2) OpenClaw’s prompt + run loop did change a lot between early Feb → 2026.3.12

Even if the model is “the same”, OpenClaw can trigger different behavior by:

  • changing the system prompt scaffolding (more tool instructions, new safety text, etc.)
  • changing how it frames runs (and when it retries)
  • changing defaults (ack reactions, reaction notifications, thinking defaults, etc.)

You already saw one real behavioral change from the OpenClaw upgrade (the reaction loop).

Fast way to tell which side changed

Do one clean-room test:

  1. Start a brand new session (important — don’t reuse the old transcript).
#
  1. Run a direct Moonshot API call outside OpenClaw with a tiny prompt (so OpenClaw prompt can’t be the cause). If the response still starts with “The user is asking…”, it’s Moonshot/Kimi behavior.

Example skeleton (keep your key private):

curl https://api.moonshot.ai/v1/chat/completions \
  -H "Authorization: Bearer $MOONSHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k2.5",
    "messages": [
      {"role":"system","content":"Answer directly. No meta commentary."},
      {"role":"user","content":"What gases make up Jupiter'\''s Great Red Spot?"}
    ],
    "thinking": {"type":"disabled"},
    "temperature": 0
#
  }'
  • If curl shows narration too → provider/model changed (or just how Kimi behaves now).
  • If curl is clean but OpenClaw isn’t → OpenClaw prompt/run framing is what’s triggering it (and that’s worth a GitHub issue with your repro).

If you want, paste what happens in the curl test (just the first ~2–3 lines of the model’s reply; no keys) and I’ll tell you which bucket you’re in.

rough quiver
# calm thunder 2) Run a direct Moonshot API call *outside* OpenClaw with a tiny prompt (so Open...

attempting to curl a response. I got: {"error":{"message":"Invalid request: invalid character '}' looking for beginning of object key string","type":"invalid_request_error"}}

This is what I put in:
curl https://api.moonshot.ai/v1/chat/completions
-H "Authorization: Bearer key"
-H "Content-Type: application/json"
-d '{
"model": "kimi-k2.5",
"messages": [
{"role":"system","content":"Answer directly. No meta commentary."},
{"role":"user","content":"What gases make up Jupiter'''s Great Red Spot?"}
],
"thinking": {"type":"disabled"},
}'

calm thunderBOT
#

That error is just JSON syntax/quoting — your payload currently has a trailing comma after "thinking": … and you’re missing the final fields (and JSON doesn’t allow trailing commas).

Here’s a fixed version of what you were trying (note: no trailing commas):

curl https://api.moonshot.ai/v1/chat/completions \
  -H "Authorization: Bearer $MOONSHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kimi-k2.5",
    "messages": [
      {"role":"system","content":"Answer directly. No meta commentary."},
      {"role":"user","content":"What gases make up Jupiter'\''s Great Red Spot?"}
    ],
    "thinking": {"type":"disabled"},
    "temperature": 0
#
  }'

If you want to avoid the annoying Jupiter'\''s escaping entirely, use a heredoc (cleaner and harder to mess up):

curl https://api.moonshot.ai/v1/chat/completions \
  -H "Authorization: Bearer $MOONSHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<'JSON'
{
  "model": "kimi-k2.5",
  "messages": [
    {"role":"system","content":"Answer directly. No meta commentary."},
    {"role":"user","content":"What gases make up Jupiter's Great Red Spot?"}
#
  ],
  "thinking": {"type":"disabled"},
  "temperature": 0
}
JSON

Run that and paste just the first couple lines of the response (no key) — we’ll know immediately whether the narration is coming from Moonshot/Kimi or from OpenClaw’s prompting.

rough quiver
# calm thunder ```bash }' ``` If you want to avoid the annoying `Jupiter'\''s` escaping enti...

The curl did NOT return any narration
This is the return:
{"id":"chatcmpl-69b4fe536bbfcd75ebc1d48f","object":"chat.completion","created":1773469267,"model":"kimi-k2.5","choices":[{"index":0,"message":{"role":"assistant","content":"The Great Red Spot's reddish color is believed to come from complex organic molecules, ammonia, or sulfur compounds in Jupiter's atmosphere. The storm itself consists primarily of hydrogen and helium (Jupiter's main atmospheric components), with traces of ammonia, methane, water vapor, and other compounds. The exact chemical composition causing the red coloration remains uncertain, though it likely involves photochemical reactions of ammonia and acetylene at high altitudes, possibly mixed with phosphorus or sulfur compounds rising from deeper atmospheric layers."},"finish_reason":"stop"}],"usage":{"prompt_tokens":28,"completion_tokens":103,"total_tokens":131}}

calm thunderBOT
#

That curl result is super useful: it proves Kimi is capable of answering cleanly with a short system prompt + thinking: disabled.

So if OpenClaw is the only place you see the “The user is asking… I should…” preface, it’s almost always one of these:

1) Session “style drift” (very likely given you had a reaction-loop storm)

If the session transcript already contains a bunch of those narrated turns (or weird system/react events), models tend to continue the same style even after you fix the underlying cause.

Fix: start a fresh session now that the reaction loop is gone (Control UI → Sessions → reset/new for that chat). Then ask the same Jupiter question again.

If the narration disappears in a fresh session, that was it.

2) OpenClaw’s larger system prompt is triggering a “planning preface” in Kimi

OpenClaw’s prompt is much bigger than your curl test (tools/skills/policies/routing/etc). Some models respond to big prompts by doing a one-line “here’s what I’m going to do” preamble.

Best mitigation I’ve seen for that is making the rule mechanical, not “be polite”:

Add this to your Discord channel’s systemPrompt (under channels.discord.guilds.<id>.channels.vulcan.systemPrompt):

#

“Your reply MUST NOT contain the substrings The user or I should or Let me. If you produce a draft containing any of those, rewrite and output only the final answer.”

(Keep temperature: 0 too.)


If you reset to a brand new session and it still starts with “The user is asking…”, I’d call it a real OpenClaw↔Moonshot interaction regression worth a GitHub issue — because we now have a clean curl repro showing the model itself doesn’t need to do it.

rough quiver
calm thunderBOT
#

Nice — that confirms it was session style drift from the earlier reaction/event chaos.

To get a single “ack” reaction per inbound message back (without reintroducing the loop), do this:

  1. Keep the guild setting you added:
"reactionNotifications": "off"

That’s the important part that prevents reaction events from being fed back into the session.

  1. Re-enable ack reactions on Discord with a single emoji:
{
  channels: {
    discord: {
#
      ackReaction: "đź‘€",              // pick whatever you want
      ackReactionScope: "group-mentions", // direct | group-mentions | group-all | all
    },
  },

  // optional: keep it on the message after the reply
  messages: { removeAckAfterReply: false },
}

If you’d rather have it auto-clean up after replying, set:

messages: { removeAckAfterReply: true }

That should give you the “bot acknowledged this message” reaction without the previous reaction storm.

rough quiver
# calm thunder That curl result is super useful: it proves **Kimi is capable of answering clean...

I am replying to this message so that I may mark this message, my message, as the answer

Future reader, the "style drift" mentioned in the replied message was the final fix; however, this was combined with an earlier fix about "reaction storms". The bot would react several times to my single message. Krill thinks that caused some loop and broke the bot elsewhere in replying, then it picked up that style and stuck with it. Killing the session and restarting worked as that forced a fresh "style".