feat(skills): add shell command execution in frontmatter for dynamic context#2582
feat(skills): add shell command execution in frontmatter for dynamic context#2582VascoSch92 merged 6 commits intomainfrom
Conversation
…injection
Add support for dynamic context injection via shell commands in skill
frontmatter. Commands are executed before skill content is processed,
and their outputs are available as {{name}} template variables.
New features:
- CommandSpec model with name, command, timeout, and on_error fields
- commands field in Skill frontmatter schema
- Skill.render_content() method for command execution and substitution
- Graceful error handling (fail/empty/message modes)
Closes #2045
Co-authored-by: openhands <openhands@all-hands.dev>
Python API breakage checks — ✅ PASSEDResult: ✅ PASSED |
REST API breakage checks (OpenAPI) — ✅ PASSEDResult: ✅ PASSED |
all-hands-bot
left a comment
There was a problem hiding this comment.
🟡 Acceptable - Pragmatic feature with solid implementation. One comment needs clarification.
This PR changes agent behavior (skill loading/rendering) and should not be approved without running evals to verify no benchmark impact. Posting as COMMENT per repo policy on eval-risk changes.
enyst
left a comment
There was a problem hiding this comment.
Could we please see how exactly an Agentskill with commands looks like? Sorry if it’s obvious 🙊
This is not part of the AgentSkill spec — it's an extension we're adding on our side. The commands field is a new frontmatter field specific to our Skill model (which extends the AgentSkill base with additional fields like resources, allowed_tools, etc.). The idea is to allow skill authors to declare shell commands in frontmatter that produce dynamic context at render time. For example, a skill could inject the output of git status or date into its content via {{var_name}} template variables. A concrete ---
name: my-skill
description: A skill with dynamic context
commands:
- name: git_status
command: "git status --short"
timeout: 5
on_error: message
- name: current_branch
command: "git branch --show-current"
---
Current branch: {{current_branch}}
Status: {{git_status}}
Rest of the skill content... So the commands field this PR adds is not part of the AgentSkills standard, it's an addition to the Skill model on top of the standard fields. |
enyst
left a comment
There was a problem hiding this comment.
How does Anthropic do this? I mean, please correct me if wrong, I think I saw they announced something like this
|
They have the special carachter ! that you can use. For example: {{!git pull}} They don't have a field in the frontmatter |
|
What do you think, is there a reason why we don’t support that format? We were trying to support Anthropic formats in the measure of possible, to ease migration for users. That is, users shouldn’t have to change their skills in order to try OpenHands. |
actually this is True. I implemented the format explained in the issue. But what you say makes sense. |
|
Or actually we can support both |
|
I think maybe we should start with the one that people are using, Anthropic’s. And add extensions when we see an actual need? |
neubig
left a comment
There was a problem hiding this comment.
Agree on trying to match the anthropic format!
all-hands-bot
left a comment
There was a problem hiding this comment.
🟢 Good taste - Clean implementation of a pragmatic feature.
This PR changes skill loading/rendering and should not be approved without running evals to verify no benchmark impact. Posting as COMMENT per repo policy on eval-risk changes.
The implementation is solid:
- Regex pattern correctly separates code blocks from executable commands
- Error handling is appropriate (timeouts, failures, output truncation)
- Security warnings are present and match the existing trust model
- Tests exercise real code paths rather than mocks
One minor documentation issue noted inline.
|
@enyst @neubig Now it follows the Claude convention Example: ---
name: my-skill
description: A skill with dynamic context
---
Current branch: !`git branch --show-current`
Status: !`git status --short`
Rest of the skill content... docs: OpenHands/docs#426 |
Document the new inline shell command execution feature (! syntax) for skills that enables dynamic context injection at render time. - Add 'Dynamic Command Execution' section to SDK skills guide - Update skill architecture with Dynamic Content Rendering capability - Update architecture diagram to show dynamic commands flow - Add render_content_with_commands to key components table Related to: OpenHands/software-agent-sdk#2582 Co-authored-by: openhands <openhands@all-hands.dev>
* docs: add dynamic command execution for skills Document the new inline shell command execution feature (! syntax) for skills that enables dynamic context injection at render time. - Add 'Dynamic Command Execution' section to SDK skills guide - Update skill architecture with Dynamic Content Rendering capability - Update architecture diagram to show dynamic commands flow - Add render_content_with_commands to key components table Related to: OpenHands/software-agent-sdk#2582 Co-authored-by: openhands <openhands@all-hands.dev> * update docs because of rendering of code blocks * adress feedbacks in review * adress feedbacks in review --------- Co-authored-by: openhands <openhands@all-hands.dev>
Summary
Closes #2045
) and inline (`) code blocks are never executed. Unclosed fenced blocks (odd number ofdelimiters) extend to EOF, preventing accidental execution of trailing content.!cmd without execution, letting authors document the syntax itself. - Error handling: Failed commands and timeouts return inline [Error: ...] markers. Large outputs are truncated at 50KB.Test Plan
Checklist
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.13-nodejs22-slimgolang: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:e104e74-pythonRun
All tags pushed for this build
About Multi-Architecture Support
e104e74-python) is a multi-arch manifest supporting both amd64 and arm64e104e74-python-amd64) are also available if needed