microscopic-jackal-24676
09/03/2026, 1:28 PMdisable-model-invocation: true in the skill front-matter. They're designed for use with Claude, and I think the behaviour in Claude is that the model cannot invoke that skill, but the user still can, perhaps both deterministically via trigger matching on the name, but by model-judgement invocation too.
In the software-agent-sdk case, it will be excluded from <available-skills> but the InvokeSkillExecutor won't see it either, so it essentially becomes invocable only if a trigger matches on an KeywordTrigger/TaskTrigger/PathTrigger. I'm not sure that's desirable behaviour because those are rare fields for skill frontmatter from my experience. This is doubly confusing behaviour because the UI shows skills as available when disable-model-invocation: true ... so it looks like they'd be easily invoked.
If somebody could confirm this/the below approach, would appreciate.
glm-5.2 take on the issue:
> Currently the only deterministic activation is match_trigger(), which requires frontmatter triggers. To get Claude-Code parity you'd need:
> 1. A user-dispatch path in LocalConversation.send_message (or `send_message`'s caller / a dedicated API). When a message begins with /<name> (whole-token) and <name> matches a loaded skill that is user-invocable, inject the skill content deterministically — bypassing match_trigger and bypassing the disable_model_invocation check in InvokeSkillExecutor. Mechanically it would look like `get_user_message_suffix()`: append the rendered content as extended_content on the MessageEvent, record the name in `activated_knowledge_skills`/`invoked_skills` for dedup. For TaskTrigger skills with inputs:, this is also where `$ARGUMENTS`/variable substitution and the missing-inputs prompt would slot in.
> 2. Semantics: treat disable-model-invocation as "user-invocable-only", not "trigger-only". Concretely:
> ◦ `_partition_skills()`stays as-is (still excluded from`available_skills`) — the point is the model can'tproactivelyinvoke it.
> ◦ `InvokeSkillExecutor`gets a distinction: invocations originating from a user-dispatch message are allowed even for disabled skills (or simpler: user dispatch never goes through the tool at all, so the executor check only ever sees model-initiated calls and can stay strict).
> ◦ The "Available skills" list in the error message can keep excluding them — model-initiated calls on disabled skills remain an error.
> 3. Skill model addition (optional but useful for parity): a user_invocable flag (default true) so the complement behavior exists, plus a way to report user-invocability in the /api/skills payload so the frontend can act on it.
> 4. Frontend (OpenHands/) wiring: use-slash-command.ts already builds a derived /<name> entry for every AgentSkills skill, including disabled ones — it just currently splices text and hopes for a trigger. Once the backend dispatch exists, that entry becomes real. You'd also want:
> ◦ honor a future`user-invocable: false`(hide from the menu),
> ◦ the "disable model invocation" pill could gain a tooltip ("user-invocable only — use /name").
> 5. Edge cases to nail down: precedence when a skill name collides with built-in slash commands (/new, /model) or plugin entry commands; whether the dispatch should match /<name> anywhere in the message or only as the leading token (Claude Code matches leading-token dispatch); and interaction with `stuck_detection`/condenser — the injected content should record invoked_skills the same way invoke_skill does so condensation and dedup behave consistently.calm-artist-7206
09/03/2026, 3:49 PMcalm-artist-7206
09/03/2026, 3:51 PMcalm-artist-7206
09/03/2026, 3:53 PMmicroscopic-jackal-24676
09/03/2026, 4:21 PMdisable_model_invocation: true in the frontmatter, then it gets removed from <available_skills> (openhands-sdk/openhands/sdk/context/agent_context.py ) :
if s.is_agentskills_format or s.trigger is not None:
# Path rules force disable_model_invocation (Skill validator), so
# they fall out here — injected only on file-touch, never listed.
if not s.disable_model_invocation:
available_skills.append(s)
That's desirable, I think. That's the block that prevents the model from proactively invoking it "autonomously".
Currently, we also puts a hard block on invoke_skill (openhands-sdk/openhands/sdk/tool/builtins/invoke_skill.py ) :
match = next((s for s in skills if s.name == name), None)
if match is None:
available = (
", ".join(
sorted(s.name for s in skills if not s.disable_model_invocation)
)
or "<none>"
)
return self._error(
name, f"Unknown skill '{name}'. Available skills: {available}."
)
if match.disable_model_invocation:
return self._error(
name,
(
f"Skill '{name}' cannot be invoked directly. "
"It can only be activated by trigger matching."
),
)
rendered = render_content_with_commands(match.content, working_dir=working_dir)
From my understanding, this means any skill with disable_model_invocation: true cannot be invoked at all. Either by the User in a prompt, or the model. That's not intention behind that flag though.
The intention behind the flag is:
`disable-model-invocation: true`: Only you can invoke the skill. Use this for workflows with side effects or that you want to control timing, like,/commit, or/deploy. You don't want Claude deciding to deploy because your code looks ready./send-slack-message
microscopic-jackal-24676
09/03/2026, 4:24 PMcalm-artist-7206
09/03/2026, 4:27 PMinvoke_skill is only about model, not usercalm-artist-7206
09/03/2026, 4:30 PM/commit in a user message, then this is not the code path that is in use - or if it is in use, and prevents them, then it’s a bug
The execution path for user prompt with /commit should be looking at “triggers”: if /commit is one of the triggers of a skill, it should be matched and loaded automatically in context.
Have you seen it not work?calm-artist-7206
09/03/2026, 4:32 PMsdk/tools/builtins, those are tools loaded in LLM’s context, I mean, well, tools. Those apply only to the agent, not the usermicroscopic-jackal-24676
09/03/2026, 4:44 PMsend_message() only runs get_user_message_suffix() -> match_trigge() as you say. That requires frontmatter triggers, which skills often don't have. For trigger-less skills with a disable-model-invocation: true flag, there is no way they can ever be called.
In reality, skills with the `_`disable-model-invocation: true`_` flag need to be model-invisible but user-invocable and they're not. They're just impossible to use.microscopic-jackal-24676
09/03/2026, 4:45 PMcalm-artist-7206
09/03/2026, 4:45 PMcalm-artist-7206
09/03/2026, 4:45 PMcalm-artist-7206
09/03/2026, 4:50 PMmicroscopic-jackal-24676
09/03/2026, 4:57 PMdisable-model-invocation: true flag.
The User should be able to do /grill-me-with-docs <design feature> , /to-spec, /to-tickets , /implement let's implement issue #54 . From my experience there are three agents trajectories:
1. I can't find the skills (they've been loaded as User skills), I'm stopping here
2. I can't find the skills (they've been loaded as User skills), but I know what /implement means and I have Git access already and I see Issue #54, so I can muddle through
3. I can't find the skills (because the disabled flag) but they were added as project skills and I've found the skill by grepping around and loaded it manually into the convohundreds-twilight-32833
09/04/2026, 2:35 AM/handoff for a conversation and the agent had no issue. How are you installing/using them in agent canvas and what LLM?microscopic-jackal-24676
09/04/2026, 10:47 AMnpx and install them to the skills folder. I am using GLM-5.2 and GLM-53/GLM-5.3-flash. They show up/register in the OpenHands as below:microscopic-jackal-24676
09/04/2026, 10:48 AMmicroscopic-jackal-24676
09/04/2026, 10:50 AMdisable-model-invocation: true from his skills so I can use them, but re-added it for the above test.microscopic-jackal-24676
09/04/2026, 10:54 AMdisable-model-invocation: true , the injection/loading works finehundreds-twilight-32833
09/04/2026, 12:16 PM/handoff without asking the agent about it? exmicroscopic-jackal-24676
09/04/2026, 12:33 PM/setup-matt-pocock-skills as this often installs the skills into the project directory, and then they can be easily found (but the agent still has to search for them in my situation). OpenHands will only show them in the ~/.agents directory though, because of its precedence.microscopic-jackal-24676
09/04/2026, 12:36 PMmicroscopic-jackal-24676
09/04/2026, 12:36 PMmicroscopic-jackal-24676
09/04/2026, 12:39 PMAGENTS.md around themhundreds-twilight-32833
09/04/2026, 12:42 PM/setup... from his skill, just install them into my agents folder. Let me try running it in other projects and an empty one.hundreds-twilight-32833
09/04/2026, 12:50 PM/handoff in the same project it works fine on a conversation where things have actually happened but on a fresh conversation in the same project the agent doesn't use it but says it is because there is nothing to handoff. Trying to invoke it on a fresh conversation is the only place I see it fail but at that point there is nothing for the skill to do.microscopic-jackal-24676
09/04/2026, 12:59 PMdisable-model-invocation: true that doesn't require previous repo work to do something sensible like /grill-with-docs . That should fail on a fresh convo/repo with no project skills added too