-
Notifications
You must be signed in to change notification settings - Fork 109
feat(plugin): Load commands as keyword-triggered skills #1676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/agent-server-plugin-loading
Are you sure you want to change the base?
feat(plugin): Load commands as keyword-triggered skills #1676
Conversation
|
Looks like there are a few issues preventing this PR from being merged!
If you'd like me to help, just leave a comment, like Feel free to include any additional details that might help me get this PR into a better state. You can manage your notification settings |
32a27fc to
326b39c
Compare
Plugin commands from the commands/ directory are now converted to keyword-triggered skills and merged into the agent context. Changes: - Add CommandDefinition.to_skill() method that converts a command to a Skill with a KeywordTrigger using Claude Code namespace format: /<plugin-name>:<command-name> - Add Plugin.get_all_skills() method that returns all skills from both skills/ and commands/ directories - Update _merge_plugin_into_request() to use get_all_skills() so commands are included when merging plugin content Example: For a plugin 'city-weather' with command 'now.md': - Trigger keyword: '/city-weather:now' - When user types '/city-weather:now Tokyo', the skill activates Closes #1674 Co-authored-by: openhands <openhands@all-hands.dev>
- Fix line too long in log message - Add None check for allowed_tools in test Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
326b39c to
f22766c
Compare
enyst
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please tell, does this PR imply that currently, "/command" doesn't trigger?
If we make them consistent, the old triggered skills with the new commands, could we maybe make the command be the canonical one, if that makes sense?
|
@enyst Exactly. The Claude plugin format has a command subdirectory and the PR we were looking at before didn't do the work of wiring up skills in that subdirectory to trigger with a slash command. Claude / AgentSkills semantics for triggering skills is different from the way OpenHands traditionally does it. When we implemented the basic AgentSkills support we moved toward those semantics but the initial plugin support didn't handle wiring up skills in the commands folder to be registered as triggered skills. (The AgentSkills standard doesn't cover this--it's part of the Claude plugin semantics which are outside the scope of AgentSkills. We are working toward not just AgentSkills compatibility but Claude plugin compatibility.) |
|
@enyst Since I've got some significant work ahead of me to get #1651 refactored into the desired shape I think it might make sense to just merge this into that branch and then when the refactoring is done and merged we'll have the plugin loading MVP done for software-agent-sdk, and I can then focus on the app server change (OpenHands/OpenHands#12321). |
|
Thank you. I think I hear you saying that commands should be skills-with-trigger. I'm trying to say that maybe skills-with-trigger should be interpreted as commands, instead. Precisely because Agentskill standard doesn't cover "triggered skills" in old OpenHands sense. Instead, plugin semantics make "triggered stuff" commands. It's not a big distinction, I'm sure. Just the objects ( |
|
I love the idea of a more first-class representation of commands! I'd likely would need some pointers to be able to execute on that, but conceptually all for it. |
This design document analyzes the proposal from PR #1676 discussion to make CommandDefinition the canonical abstraction for triggered/invokable content, rather than converting commands to skills-with-triggers. Co-authored-by: openhands <openhands@all-hands.dev>
|
Are you proposing we invert the relationship: instead of commands → skills-with-trigger, make skills-with-trigger → commands?
Would mean adding:
I've added a design document to this branch sketching out the implications and implementation tasks—does it capture the approach you'd recommend? |
Summary
Plugin commands from the
commands/directory are now automatically converted to keyword-triggered skills and merged into the agent context.This enables Claude Code format plugins that use
commands/(which is the standard location for slash commands) to work correctly with OpenHands - the agent now receives the command instructions as skills.Changes
CommandDefinition.to_skill()method that converts a command to aSkillwith aKeywordTriggerusing Claude Code namespace format:/<plugin-name>:<command-name>Plugin.get_all_skills()method that returns all skills from bothskills/andcommands/directories_merge_plugin_into_request()to useget_all_skills()so commands are included when merging plugin contentExample
For a plugin named
city-weatherwith a commandnow.md:/city-weather:now/city-weather:now Tokyo, the skill activates with$ARGUMENTS=TokyoTesting
CommandDefinition.to_skill()Plugin.get_all_skills()_merge_plugin_into_request()with commandsAll tests pass:
Closes #1674
@jpshackelford can click here to continue refining the PR
Agent Server images for this PR
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.12-nodejs22golang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:d6d6e65-pythonRun
All tags pushed for this build
About Multi-Architecture Support
d6d6e65-python) is a multi-arch manifest supporting both amd64 and arm64d6d6e65-python-amd64) are also available if needed