#Slash Skill command question

1 messages · Page 1 of 1 (latest)

zealous lava
#

I want to define a slash command that calls a script, but I don’t want a model to be involved either before or after the call.

The shell script is in the allow list and is approved. The version is 2025.2.14.

My SKILL.md looks like this:

---
name: getinfo
description: Testing
user-invocable: true
disable-model-invocation: false 
metadata:
  openclaw:
    tools:
      call-getinfo:
        command: exec
        args:
          command: "/home/pi/myopenclaw/bin/getinfo"
          workdir: "/home/pi"
---

Used in Telegram: /getinfo

In this case, the model is called before and after the script execution (see the model conversation in the session log):

--> user: Use the "getinfo" skill for this request.
<-- assistant: toolCall , "exec","arguments":{"command":"/home/pi/myopenclaw/bin/getinfo"
--> toolResult: Hello World!
<-- assistant: skill executed successfully .. Hello World!

If I change disable-model-invocation: true:

---
name: getinfo
description: Testing
user-invocable: true
disable-model-invocation: true 
...

The conversation looks like:

--> user: Use the "getinfo" skill for this request.
<-- assistant: There's no "getinfo" skill listed in the available skills

It does not work, because the model has no skill description, as expected. I would expect the gateway executes the skill directly. Is this behavior a bug?

How can I define a slash command skill that does not involve the model?

umbral quiverBOT
#

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

obsidian vaultBOT
#

On 2025.2.14 this is expected behavior, not a bug:

  • A user-invocable skill slash command (/getinfo) is implemented as “rewrite the user message to Use the "getinfo" skill… and send it to the LLM”.
  • disable-model-invocation: true only means “don’t include this skill in the model prompt”. So when the slash command triggers, the LLM quite literally can’t see the skill anymore and answers “no such skill”.

So on that version, you can’t have a skill-based slash command run a script with zero model involvement.

What you want (LLM-free slash command) exists in newer versions

This landed later as tool-dispatch skill commands.

Upgrade, then change your SKILL.md to use direct tool dispatch:

---
name: getinfo
description: Testing
#
user-invocable: true
disable-model-invocation: true
command-dispatch: tool
command-tool: exec
---

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

Caveat: tool-dispatch forwards the raw args string to the tool as { command: "<args>" }. So with command-tool: exec, you’d call:

  • /getinfo /home/pi/myopenclaw/bin/getinfo

If you need exactly /getinfo with no args to always run that fixed script, you’ll need a small wrapper (e.g. a plugin command / custom tool) rather than plain exec dispatch, because exec has no “default command” behavior.

Also note: the metadata: openclaw: tools: ... block you showed is not a supported OpenClaw skills format (OpenClaw expects metadata: as a single-line JSON object; nested YAML won’t do what you think).

zealous lava
#

Thanks. But what is the purpose of "disable-model-invocation: true ", if the skill cannot be called by the user directly? Neither /skill getinfo nor /getinfo work.

JSON/YAML: ok, will change. But in case of "disable-model-invocation: true" the skill works correctly.

Is the a bash command (bash cmd / !cmd) is solution? Is the model involved in thisd case?

obsidian vaultBOT
#

disable-model-invocation: true isn’t “run this without a model”. It only means:

  • don’t inject this skill’s instructions into the model prompt (so the model won’t pick it “by itself”, and you don’t spend context on it).

On 2025.2.14, both /getinfo and /skill getinfo still work like this:

  1. gateway rewrites your message to “Use the getinfo skill…”
  2. sends it to the LLM
  3. LLM decides what tools to call

So if you set disable-model-invocation: true, the LLM no longer sees the skill text, and then it can’t follow “use getinfo” → you get the “no such skill available” kind of response. In other words: on that version, disable-model-invocation and “user invokes skill by name” don’t really compose well, because user invocation still relies on the LLM seeing the skill.

If you want truly LLM-free command execution

You need a Gateway-side command path (no agent turn). There are three options, all added later than 2025.2.14:

  1. Skill command → direct tool dispatch (what you originally expected)
    Add this to frontmatter (newer versions):
#
   command-dispatch: tool
   command-tool: exec

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

  1. Built-in bash chat command: ! <cmd> / /bash <cmd>
    This is LLM-free (handled by the gateway), but it was added later (2026.1.x).
    Docs: https://docs.openclaw.ai/tools/slash-commands
    (Requires commands.bash=true and the usual tools.elevated allowlists / exec approvals.)

  2. Plugin auto-reply command (registerCommand) that runs your script and returns output (also LLM-free).
    Docs: https://docs.openclaw.ai/tools/plugin#register-auto-reply-commands

About “is the model involved with !cmd / /bash?”

On versions that have it: no — it bypasses the model entirely and directly runs exec (still subject to your exec allowlist/approvals).

#

If you tell me whether you can upgrade (and to what target), I can suggest the cleanest path to get an actual /getinfo that runs a fixed script with zero LLM calls.

zealous lava
#

Thanks.

  1. This means disable-model-invocation: true is only relevant if command-dispatch: tool and command-dispatch: tool are also specified. I tried, in this case I get an error message directly from the gateway (no LLM involved). Tool not available: exec

  2. I tried also as bash command. It works. BUT the LLM is still involved. Here is the conversation:

--> User: bash /home/pi/myopenclaw/bin/getinfo
<-- Assistant: toolCall: exec /home/pi/myopenclaw/bin/getinfo
--> Toolresult: Hello World
<-- Assistant: Jo, läuft! :lobster: Das \"Hello, World!\" vom Skript funktioniert einwandfrei. Brauchst du was damit oder war's nur der obligatorische Testlauf?
obsidian vaultBOT
#

Two separate things are getting mixed together here:

1) Why command-dispatch: tool says Tool not available: exec

That error is correct.

command-dispatch: tool runs in the Gateway “auto-reply” path and it only has access to the OpenClaw tools set (message/sessions/cron/browser/…).

It does not include the runtime shell tools like exec / process (those live in the “bash tools” layer), so dispatching to exec will always fail with:

Tool not available: exec

So: tool-dispatch can’t be used to run shell scripts (at least as of current behavior).

2) Why your “bash command” still hits the LLM

In your transcript you sent:

bash /home/pi/myopenclaw/bin/getinfo

#

That is not the Gateway’s bash command. It’s just normal text, so it goes to the model, and the model decides to call exec, then adds a chatty reply (your German message is the giveaway).

The LLM-free host-shell command is:

  • ! /home/pi/myopenclaw/bin/getinfo
    (and /bash /home/pi/myopenclaw/bin/getinfo is an alias)

But it only works when enabled/allowed (and it was added later than your stated 2025.2.14).

Docs: https://docs.openclaw.ai/tools/slash-commands

Quick checks

  • Does !/bash show up in /commands? If not, you’re on a version before the LLM-free bash command existed → upgrading is required.
  • If it does exist but still goes to the LLM, it’s usually because commands.bash is off or you’re not on the tools.elevated.allowFrom.telegram allowlist, so it “falls through” as plain text.

Bottom line (for “/getinfo with zero LLM”)

  • command-dispatch: tool won’t help for exec.
#
  • Use ! ... / /bash ... (LLM-free) or write a tiny plugin registerCommand({ name: "getinfo", ... }) to make a true /getinfo command that runs your script without any model.

If you paste openclaw --version and whether you’re testing in Telegram DM vs group, I can tell you exactly which of those paths is available on your install and what config keys you need to flip.

zealous lava
#

Thanks.

Indeed, I forgot the slash before bash. Now it works.

obsidian vaultBOT
#

Nice — yep, without the leading / (or !) it’s just normal chat text, so it goes through the model.

If you want to keep it LLM-free, stick to:

  • ! /home/pi/myopenclaw/bin/getinfo (text-only fast path)
  • /bash /home/pi/myopenclaw/bin/getinfo (alias)

If this solved it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it for the next person.