Skip to content

feat(skills): add shell command execution in frontmatter for dynamic context#2582

Merged
VascoSch92 merged 6 commits intomainfrom
vasco/skill-command
Apr 3, 2026
Merged

feat(skills): add shell command execution in frontmatter for dynamic context#2582
VascoSch92 merged 6 commits intomainfrom
vasco/skill-command

Conversation

@VascoSch92
Copy link
Copy Markdown
Contributor

@VascoSch92 VascoSch92 commented Mar 26, 2026

Summary

Closes #2045

  • Inline command syntax: Skills can embed dynamic shell output in markdown using !command`` — the command is executed at render time and replaced with its stdout.
  • Code-block safety: Fenced () and inline (`) code blocks are never executed. Unclosed fenced blocks (odd number of delimiters) extend to EOF, preventing accidental execution of trailing content.
  • Escape hatch: !cmd produces the literal text !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

  • _execute_inline_command: success, failure, timeout, working directory, output truncation
  • render_content_with_commands: plain text passthrough, single/multiple commands, empty backticks
  • Code-block preservation: inline code, fenced blocks, inline code adjacent to commands
  • Unclosed fenced blocks don't leak commands
  • Escaped !cmd`` produces literal output
  • Skill.render_content integration and Skill.load round-trip

Checklist

  • If the PR is changing/adding functionality, are there tests to reflect this?
  • If there is an example, have you run the example to make sure that it works?
  • If there are instructions on how to run the code, have you followed the instructions and made sure that it works?
  • If the feature is significant enough to require documentation, is there a PR open on the OpenHands/docs repository with the same branch name?
  • Is the github CI passing?

Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:e104e74-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-e104e74-python \
  ghcr.io/openhands/agent-server:e104e74-python

All tags pushed for this build

ghcr.io/openhands/agent-server:e104e74-golang-amd64
ghcr.io/openhands/agent-server:e104e74-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:e104e74-golang-arm64
ghcr.io/openhands/agent-server:e104e74-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:e104e74-java-amd64
ghcr.io/openhands/agent-server:e104e74-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:e104e74-java-arm64
ghcr.io/openhands/agent-server:e104e74-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:e104e74-python-amd64
ghcr.io/openhands/agent-server:e104e74-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:e104e74-python-arm64
ghcr.io/openhands/agent-server:e104e74-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:e104e74-golang
ghcr.io/openhands/agent-server:e104e74-java
ghcr.io/openhands/agent-server:e104e74-python

About Multi-Architecture Support

  • Each variant tag (e.g., e104e74-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., e104e74-python-amd64) are also available if needed

openhands-agent and others added 2 commits March 26, 2026 11:55
…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>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

all-hands-bot

This comment was marked as outdated.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/context/skills
   execute.py39489%92–95
   skill.py4303392%94–95, 249–250, 436–442, 445, 562–565, 809–810, 869–870, 938–939, 1007, 1035, 1058, 1065–1066, 1110–1111, 1117–1118, 1124–1125
TOTAL21295620770% 

all-hands-bot

This comment was marked as outdated.

Copy link
Copy Markdown
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Comment thread openhands-sdk/openhands/sdk/context/skills/skill.py Outdated
@VascoSch92 VascoSch92 marked this pull request as ready for review March 26, 2026 12:51
all-hands-bot

This comment was marked as outdated.

Comment thread openhands-sdk/openhands/sdk/context/skills/skill.py Outdated
Copy link
Copy Markdown
Collaborator

@enyst enyst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we please see how exactly an Agentskill with commands looks like? Sorry if it’s obvious 🙊

@VascoSch92
Copy link
Copy Markdown
Contributor Author

VascoSch92 commented Mar 27, 2026

@enyst

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 SKILL.md with commands looks like this:

  ---                                                                                                                                                                                                                                    
  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.

Copy link
Copy Markdown
Collaborator

@enyst enyst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does Anthropic do this? I mean, please correct me if wrong, I think I saw they announced something like this

@VascoSch92
Copy link
Copy Markdown
Contributor Author

They have the special carachter ! that you can use.

For example:

{{!git pull}}

They don't have a field in the frontmatter

@enyst
Copy link
Copy Markdown
Collaborator

enyst commented Mar 27, 2026

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.

@VascoSch92
Copy link
Copy Markdown
Contributor Author

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.

@VascoSch92
Copy link
Copy Markdown
Contributor Author

Or actually we can support both

@enyst
Copy link
Copy Markdown
Collaborator

enyst commented Mar 27, 2026

I think maybe we should start with the one that people are using, Anthropic’s. And add extensions when we see an actual need?

Copy link
Copy Markdown
Contributor

@neubig neubig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree on trying to match the anthropic format!

Copy link
Copy Markdown
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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.

Comment thread openhands-sdk/openhands/sdk/context/skills/execute.py
@VascoSch92
Copy link
Copy Markdown
Contributor Author

VascoSch92 commented Mar 31, 2026

@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

VascoSch92 pushed a commit to OpenHands/docs that referenced this pull request Mar 31, 2026
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>
@VascoSch92 VascoSch92 requested review from enyst and neubig March 31, 2026 10:27
Copy link
Copy Markdown
Contributor

@neubig neubig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@VascoSch92 VascoSch92 merged commit 807369c into main Apr 3, 2026
33 of 34 checks passed
@VascoSch92 VascoSch92 deleted the vasco/skill-command branch April 3, 2026 18:50
VascoSch92 added a commit to OpenHands/docs that referenced this pull request Apr 5, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(skills): Shell command execution in frontmatter for context injection

5 participants