Skip to content

Conversation

@xingyaoww
Copy link
Collaborator

@xingyaoww xingyaoww commented Nov 24, 2025

Overview

This PR adds a new load_public_skills() function that fetches and loads skills from the OpenHands/skills public repository. This allows users to get the latest community skills without waiting for SDK updates.

Related to:

Changes

Core Functionality

  • New load_public_skills() function in skill.py:
    • Fetches skill files from GitHub using the GitHub API
    • Downloads and loads skills dynamically
    • Handles errors gracefully (HTTP errors, network errors, invalid skills)
    • Supports custom repository URLs and branches for flexibility

AgentContext Integration

  • Add load_public_skills boolean field to AgentContext
  • Add _load_public_skills validator to automatically load public skills when enabled
  • Merge public skills with explicit skills, avoiding duplicates
  • Explicit skills take precedence over public skills

API Export

  • Export load_public_skills from skills.__init__ module for easy access

Testing

  • Comprehensive test coverage in test_load_public_skills.py:
    • Test successful loading from repository
    • Test HTTP and network error handling
    • Test custom repositories and branches
    • Test invalid skill handling
    • Test AgentContext integration
    • Test skill precedence and merging
    • All 11 new tests passing

Usage Examples

Loading public skills directly

from openhands.sdk.context.skills import load_public_skills

# Load skills from the official repository
public_skills = load_public_skills()

# Or from a custom repository
custom_skills = load_public_skills(
    repo_url="https://github.com/my-org/my-skills",
    branch="develop"
)

Using with AgentContext

from openhands.sdk.context import AgentContext

# Automatically load public skills
context = AgentContext(load_public_skills=True)

# Or combine with user skills
context = AgentContext(
    load_user_skills=True,
    load_public_skills=True
)

Benefits

  1. Latest Skills: Users get the latest community skills without SDK updates
  2. Flexibility: Serves skills independently from SDK releases
  3. Community: Easier for the community to contribute and use shared skills
  4. Backward Compatible: All existing functionality remains unchanged

Testing

All tests pass:

uv run pytest tests/sdk/context/skill/test_load_public_skills.py -v

All skill-related tests pass:

uv run pytest tests/sdk/context/skill/ -v

@xingyaoww 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:b5b7a45-python

Run

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

All tags pushed for this build

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

About Multi-Architecture Support

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

This change adds a new load_public_skills() function that fetches and loads
skills from the OpenHands/skills public repository on GitHub. This allows users
to get the latest community skills without waiting for SDK updates.

Changes:
- Add load_public_skills() function in skill.py that:
  - Fetches skill files from GitHub using the GitHub API
  - Downloads and loads skills dynamically
  - Handles errors gracefully (HTTP, network, invalid skills)
  - Supports custom repository URLs and branches

- Update AgentContext to support load_public_skills flag:
  - Add load_public_skills boolean field
  - Add _load_public_skills validator to automatically load public skills
  - Merge public skills with explicit skills, avoiding duplicates

- Export load_public_skills from skills.__init__ module

- Add comprehensive test coverage:
  - Test successful loading from repository
  - Test HTTP and network error handling
  - Test custom repositories and branches
  - Test invalid skill handling
  - Test AgentContext integration
  - Test skill precedence and merging

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

github-actions bot commented Nov 24, 2025

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/context
   agent_context.py876426%72–73, 75–80, 85–86, 88–89, 91–94, 96, 100–101, 103, 108–111, 113–116, 118, 122–124, 135–136, 138, 140, 146–149, 162–164, 166, 169, 171–174, 176–181, 186, 193–194, 199–201, 205–207
openhands-sdk/openhands/sdk/context/skills
   skill.py21817420%81, 84–85, 92, 105, 108–109, 111, 115, 118–120, 123–125, 127–129, 132, 135, 138–140, 146, 148–154, 157, 165–166, 174–177, 189–196, 202–203, 206–207, 209, 215–216, 218, 226–236, 243–245, 253–255, 273–274, 276–277, 280, 283–284, 287–291, 294–296, 299–303, 306–307, 309–311, 313–314, 316, 320, 341–342, 344–347, 349–351, 354–358, 360, 364–365, 367, 370, 384–386, 404, 406–410, 417, 424–428, 433–435, 437, 452, 454, 456–460, 463–466, 500, 502, 504–505, 507–509, 512–515, 518, 520, 523–525, 529–533, 535–536, 538, 541
TOTAL12578581253% 

Update the load_public_skills() function to fetch skills from the skills/
subdirectory in the repository, keeping the root folder clean and organized.

Changes:
- Modified GitHub API call to target skills/ subdirectory
- Updated file path construction to include skills/ prefix
- Updated all tests to expect skills/ prefix in URLs

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

With the current implementation, skill data is fetched remotely from GitHub every time the application starts. As the skill library grows larger, this will incur considerable overhead. I'm wondering if we could add a local cache directory to address this. WDYT

@xingyaoww
Copy link
Collaborator Author

@OpenHands please review diff against main for this PR, and implement this: #1248 (comment)

We should maintain a git repo locally and try to pull it to make sure it stays up-to-date everytime we launch it

@openhands-ai
Copy link

openhands-ai bot commented Nov 25, 2025

I'm on it! xingyaoww can track my progress at all-hands.dev

Instead of fetching individual skill files via HTTP on every launch,
maintain a local git clone of the skills repository. This approach:

1. Clones the repository to ~/.openhands/skills-cache/ on first run
2. Pulls latest changes on subsequent runs to stay up-to-date
3. Falls back to cached version if update fails (network issues)
4. Much more efficient for larger skill libraries

Benefits:
- Significantly reduces overhead as skill library grows
- Only fetches changed files (git fetch/pull is efficient)
- Works offline after initial clone
- More reliable with automatic fallback to cache

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

openhands-ai bot commented Nov 25, 2025

Perfect! The changes have been pushed. Let me provide a final summary:

Summary

I've successfully implemented the requested change from PR #1248 comment. The implementation now uses git-based caching instead of fetching individual files via HTTP on every launch.

Changes Made

1. Core Implementation (skill.py):

  • Added _get_skills_cache_dir() - Creates/returns cache directory at ~/.openhands/skills-cache/
  • Added _update_skills_repository() - Clones or updates the local git repository:
    • First run: Clones repository with --depth 1 for efficiency
    • Subsequent runs: Fetches and resets to latest changes using git fetch + git reset --hard
    • Network failures: Gracefully falls back to existing cached version
  • Modified load_public_skills() - Loads skills from local git clone instead of HTTP

2. Test Suite (test_load_public_skills.py):

  • Completely rewrote all 14 tests to mock git operations instead of HTTP calls
  • Added tests for:
    • Repository cloning and updating
    • Timeout handling
    • Fallback to cache when updates fail
    • All AgentContext integration scenarios

Benefits

More Efficient: Only fetches changed files (git is optimized for incremental updates)
Scales Better: As skill library grows, git pull is much faster than fetching individual files
Offline Support: Works offline after initial clone
Reliable: Automatic fallback to cache if network issues occur
Follows Best Practices: Standard approach for dependency management

Test Results

All 51 skill-related tests pass successfully. The implementation is backward compatible and doesn't break any existing functionality.

The changes have been committed and pushed to the add-load-public-skills branch, updating PR #1248.

View full conversation

@xingyaoww xingyaoww marked this pull request as ready for review November 25, 2025 23:08
@xingyaoww xingyaoww marked this pull request as draft November 25, 2025 23:09
openhands-agent and others added 4 commits November 25, 2025 23:12
Remove complex URL parsing logic since repo URL is hardcoded to
https://github.com/OpenHands/skills. Use fixed directory name
'openhands-skills' instead of generating safe name from URL.

This makes the code simpler and more maintainable while keeping
all the important git operations (clone/fetch/reset).

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

@OpenHands review the updated example 03_activate_skills.py in this PR, then checkout OpenHands/docs repo, and update the docs corresponding to this example https://github.com/OpenHands/docs/blob/main/sdk/guides/skill.mdx by adding a new section following existing pattern to explalin the new load public skill feature

@xingyaoww xingyaoww marked this pull request as ready for review November 26, 2025 16:12
@openhands-ai
Copy link

openhands-ai bot commented Nov 26, 2025

I'm on it! xingyaoww can track my progress at all-hands.dev

xingyaoww pushed a commit to OpenHands/docs that referenced this pull request Nov 26, 2025
Add comprehensive documentation for the new load_public_skills feature:
- Update example code to reflect the latest version
- Add new section 'Loading Public Skills' with subsections:
  - Automatic loading via AgentContext
  - Programmatic loading for manual control
  - Custom skills repository support
  - Explanation of git-based caching mechanism
- Document skill precedence rules
- Add note about exploring the public skills repository

Related to OpenHands/software-agent-sdk#1248

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

@OpenHands review diff from main

fix these tests

TOTAL 7210 4581 36%
=========================== short test summary info ============================
FAILED tests/sdk/context/skill/test_load_public_skills.py::test_update_skills_repository_update_existing
FAILED tests/sdk/context/skill/test_load_public_skills.py::test_update_skills_repository_update_fails_uses_cache
================== 2 failed, 1274 passed in 160.47s (0:02:40) ==================
Error: Process completed with exit code 1.

@openhands-ai
Copy link

openhands-ai bot commented Nov 26, 2025

I'm on it! xingyaoww can track my progress at all-hands.dev

@openhands-ai
Copy link

openhands-ai bot commented Nov 26, 2025

Summary

I've successfully completed your request to review the updated example and update the documentation for the load_public_skills feature.

Work Completed

1. Reviewed the Updated Example

Examined examples/01_standalone_sdk/03_activate_skill.py in PR #1248, which now includes:

  • load_public_skills=True in AgentContext
  • A test case demonstrating the 'github' public skill
  • Comprehensive comments explaining AgentContext capabilities

2. Created Documentation PR

Repository: OpenHands/docs
Branch: add-load-public-skills
PR: OpenHands/docs#133 (draft)
File Updated: sdk/guides/skill.mdx

3. Documentation Changes

Updated the skill guide with:

Synced Example Code

  • Updated to match the latest version from the SDK repository
  • Fixed model name and added all new comments and features

New Section: "Loading Public Skills"

Added comprehensive documentation with four subsections:

  1. Automatic Loading via AgentContext - How to enable load_public_skills=True and what happens automatically
  2. Programmatic Loading - Manual loading with load_public_skills() function for more control
  3. Custom Skills Repository - Support for loading from custom repositories with custom branches
  4. How It Works - Detailed explanation of the git-based caching mechanism (~/.openhands/cache/skills/)

Also documented:

  • Skill precedence rules (explicit skills override public skills)
  • Link to explore the public skills repository
  • Offline mode fallback behavior

PRs Cross-Referenced

Both PRs are on the same branch name (add-load-public-skills) for easy tracking. The documentation PR should be reviewed and merged after the SDK PR is merged to maintain consistency.

View full conversation

The implementation uses 'public-skills' as the repository directory name,
but the tests were creating 'openhands-skills'. This caused two test
failures where the expected path didn't match the actual path.

Updated both tests to use 'public-skills' to match the implementation.

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

openhands-ai bot commented Nov 26, 2025

I've successfully fixed the failing tests! Here's a summary of the changes:

Summary

Problem: Two tests were failing in test_load_public_skills.py:

  • test_update_skills_repository_update_existing
  • test_update_skills_repository_update_fails_uses_cache

Root Cause: The tests were creating a directory named "openhands-skills" but the implementation in skill.py uses "public-skills" as the repository directory name (line 404). This mismatch caused assertion failures where the expected path didn't match the actual returned path.

Solution: Updated both tests to use "public-skills" instead of "openhands-skills" to match the implementation.

Changes Made:

  • Line 206: Changed repo_path = cache_dir / "openhands-skills"repo_path = cache_dir / "public-skills"
  • Line 258: Changed repo_path = cache_dir / "openhands-skills"repo_path = cache_dir / "public-skills"

Verification:
✅ Both previously failing tests now pass
✅ All 14 tests in test_load_public_skills.py pass
✅ Pre-commit hooks pass (Ruff format, Ruff lint, pycodestyle, pyright, import checks)
✅ Changes committed and pushed to branch add-load-public-skills

The fix is minimal and focused—only the directory names in the test assertions were changed to match the implementation's behavior.

View full conversation

@xingyaoww xingyaoww requested review from enyst and neubig November 26, 2025 16:20
Co-authored-by: Engel Nyst <engel.nyst@gmail.com>
@xingyaoww
Copy link
Collaborator Author

@OpenHands please fix the failing actions on PR #1248 at branch add-load-public-skills

@openhands-ai
Copy link

openhands-ai bot commented Nov 26, 2025

I'm on it! xingyaoww can track my progress at all-hands.dev

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

openhands-ai bot commented Nov 26, 2025

Summary

I've successfully fixed the failing actions on PR #1248 (add-load-public-skills branch). The changes have been pushed to the remote branch.

Issues Fixed

Pre-commit checks - Fixed a formatting issue in examples/01_standalone_sdk/03_activate_skill.py
Check Documented Examples - Verified that the example is properly documented in the docs repository

Changes Made

File Modified: examples/01_standalone_sdk/03_activate_skill.py

  • Fixed line length issue (E501) by breaking a long conversation.send_message() call across multiple lines
  • Changed from a single line to a multi-line format to comply with the 88-character line length limit

Verification

All checks now pass:

  • ✅ Ruff format
  • ✅ Ruff lint
  • ✅ PEP8 style check (pycodestyle)
  • ✅ Type check with pyright
  • ✅ Import dependency rules
  • ✅ Documented examples check (verified against the add-load-public-skills branch in the docs repository)

The commit has been pushed to origin/add-load-public-skills and the GitHub Actions should now pass on the next CI run.

View full conversation

@openhands-ai
Copy link

openhands-ai bot commented Nov 26, 2025

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

  • GitHub Actions are failing:
    • Check Documented Examples

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

@OpenHands please fix the failing actions on PR #1248 at branch `add-load-public-skills`

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

You can manage your notification settings

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

LGTM, thank you!

@xingyaoww xingyaoww enabled auto-merge (squash) November 26, 2025 17:04
@xingyaoww xingyaoww merged commit 8e29633 into main Nov 26, 2025
16 of 17 checks passed
@xingyaoww xingyaoww deleted the add-load-public-skills branch November 26, 2025 17:05
enyst added a commit to OpenHands/docs that referenced this pull request Nov 27, 2025
* Document load_public_skills feature

Add comprehensive documentation for the new load_public_skills feature:
- Update example code to reflect the latest version
- Add new section 'Loading Public Skills' with subsections:
  - Automatic loading via AgentContext
  - Programmatic loading for manual control
  - Custom skills repository support
  - Explanation of git-based caching mechanism
- Document skill precedence rules
- Add note about exploring the public skills repository

Related to OpenHands/software-agent-sdk#1248

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

* docs: sync SDK example code blocks

• Updated sdk/guides/skill.mdx to match examples/01_standalone_sdk/03_activate_skill.py from software-agent-sdk@8e296334
• Ran sync script against local agent-sdk checkout to ensure exact parity
• Also refreshed other SDK guide code blocks that had drifted during the same sync run

Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: enyst <engel.nyst@gmail.com>
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.

5 participants