Skip to content

Conversation

@jpshackelford
Copy link
Contributor

@jpshackelford jpshackelford commented Dec 10, 2025

Experimental support for loading skills from installed packages via entry points.

See docs/skill-packages.md and examples/01_standalone_sdk/04_use_skill_packages.py for details.

@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

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.12-nodejs22 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:92b0578-python

Run

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

All tags pushed for this build

ghcr.io/openhands/agent-server:92b0578-golang-amd64
ghcr.io/openhands/agent-server:92b0578-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:92b0578-golang-arm64
ghcr.io/openhands/agent-server:92b0578-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:92b0578-java-amd64
ghcr.io/openhands/agent-server:92b0578-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:92b0578-java-arm64
ghcr.io/openhands/agent-server:92b0578-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:92b0578-python-amd64
ghcr.io/openhands/agent-server:92b0578-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-amd64
ghcr.io/openhands/agent-server:92b0578-python-arm64
ghcr.io/openhands/agent-server:92b0578-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-arm64
ghcr.io/openhands/agent-server:92b0578-golang
ghcr.io/openhands/agent-server:92b0578-java
ghcr.io/openhands/agent-server:92b0578-python

About Multi-Architecture Support

  • Each variant tag (e.g., 92b0578-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., 92b0578-python-amd64) are also available if needed

This commit adds the ability to load skills from installed OpenHands skill
packages, enabling reusable skill distribution across projects.

Features:
- Package discovery using Python entry points
- Configuration via .openhands/packages.yaml
- Functions to list, load, and inspect skill packages
- Integration with existing skill loading infrastructure
- Comprehensive tests and documentation
- Example demonstrating all features

New files:
- openhands-sdk/openhands/sdk/context/skills/package_loader.py
- tests/sdk/context/skill/test_package_loader.py
- examples/01_standalone_sdk/04_use_skill_packages.py
- docs/skill-packages.md
- .openhands/packages.yaml (template)

Related to: https://github.com/OpenHands/package-poc
jpshackelford and others added 3 commits December 18, 2025 11:35
Update package_loader.py to support both manifest.json (Claude Code format)
and skill-package.yaml (legacy format), with manifest.json taking priority.

This aligns the software-agent-sdk with the OpenHands package-poc refactoring
(PR #17) that migrated from YAML to JSON-based manifests for cross-ecosystem
compatibility with Claude Code.

Changes:
- Add _load_package_descriptor() helper function that tries manifest.json first,
  then falls back to skill-package.yaml
- Update list_skill_packages() to use the new helper
- Update get_skill_package() to use the new helper
- Add json import for manifest parsing
- Add type checking for triggers data

Tested with openhands-simple-code-review package using manifest.json format.

Co-authored-by: openhands <openhands@all-hands.dev>
Convert Claude Code manifest.json format to skill-package.yaml structure
to maintain compatibility with existing code that expects the nested format.

Changes:
- Add _normalize_manifest() helper to convert flat manifest structure
  to nested metadata/spec structure
- Handle both string and dict author formats
- Map keywords to tags field
- Extract repository URL from repository object

This allows the SDK to seamlessly work with both manifest.json (Claude Code)
and skill-package.yaml (legacy) formats.

Co-authored-by: openhands <openhands@all-hands.dev>
BREAKING CHANGE: Skill packages must now use manifest.json format only.
The legacy skill-package.yaml format is no longer supported.

This aligns with PR #17 in package-poc which fully migrated to the Claude Code
manifest.json standard. Packages without manifest.json will fail to load with
a clear error message.

Changes:
- Remove fallback to skill-package.yaml in _load_package_descriptor()
- Update error messages to indicate manifest.json is required
- Update docstrings and comments to reflect manifest.json-only support
- Keep _normalize_manifest() to convert Claude Code flat structure to
  internal nested structure

Note: yaml import is retained for loading user configuration files
(.openhands/packages.yaml), not package descriptors.

Co-authored-by: openhands <openhands@all-hands.dev>
@openhands-ai
Copy link

openhands-ai bot commented Dec 19, 2025

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • Pre-commit checks
    • Run tests
    • [Optional] Docs example

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #1378 at branch `jps/skill-package-loading-experiment`

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

- Updated test_package_loader.py to use manifest.json format instead of YAML
- Fixed E501 line too long issue in skill package example
- Renamed 04_use_skill_packages.py to 31_use_skill_packages.py for correct numbering

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions
Copy link
Contributor

github-actions bot commented Dec 19, 2025

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/context/skills
   package_loader.py13011313%41–43, 45–48, 67–69, 71, 74, 88, 107, 109, 111–112, 114, 117, 119, 122, 124, 126, 143, 145–147, 149, 152, 154, 159–161, 163, 189–191, 193–194, 196–197, 200, 202, 204–206, 208–209, 212, 214, 216, 220, 225, 227, 229–231, 234–236, 238–240, 243, 248–249, 251, 253, 255–258, 260, 265, 284–285, 287–295, 297, 315, 317–318, 320–323, 325–326, 328, 330–332, 334–336, 338–340, 342–344, 360, 362–364, 366
TOTAL13004591454% 

jpshackelford and others added 2 commits December 18, 2025 21:22
yamlfmt hook added the standard --- separator

Co-authored-by: openhands <openhands@all-hands.dev>
jpshackelford added a commit that referenced this pull request Dec 19, 2025
…ll_packages.py

- Updated example code to access flat manifest.json structure instead of nested metadata/spec
- Fixed descriptor access patterns: descriptor['displayName'] instead of descriptor['metadata']['displayName']
- Renamed from 04_use_skill_packages.py to 31_use_skill_packages.py to match PR #1378
- Updated documentation reference to point to new filename
- Added defensive handling for author and repository fields that can be string or object

Co-authored-by: openhands <openhands@all-hands.dev>
@jpshackelford
Copy link
Contributor Author

Closed in favor of #1399

@jpshackelford jpshackelford deleted the jps/skill-package-loading-experiment branch December 19, 2025 03:01
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.

3 participants