What is our strategy for "auto activation"? See e...
# proj-extensions
w
What is our strategy for "auto activation"? See e.g. https://github.com/JuliusBrussee/caveman/blob/main/README.md#what-you-get
Auto-activation works differently per agent: Claude Code uses SessionStart hooks, this repo's Codex dogfood setup uses
.codex/hooks.json
, Gemini uses context files. Cursor/Windsurf/Cline/Copilot can be made always-on, but
npx skills add
installs only the skill, not the repo rule/instruction files.
m
If with auto-activation you want to have the skill always activated at conversation start, we have hooks — add
session_start
to `.openhands/hooks.json`:
Copy code
{
  "session_start": [
    {
      "matcher": "*",
      "hooks": [
        {
          "type": "command",
          "command": ".openhands/hooks/on_session_start.sh",
          "timeout": 60
        }
      ]
    }
  ],
  "stop": [
    ...
  ]
}
This should work. Otherwise, skills are activated (or selected) in two different ways: one is by keyword triggering (the user uses a special keyword, like "github", then the GitHub skill is activated), or by semantic similarity — the Agent has the skill descriptions in the system prompt and if it finds the skill is useful for the task, it can activate it during the conversation.
👍 1
w
should
cat
do the trick? the agent doesn't seem to interpret this as triggering the skill
Screenshot 2026-04-17 at 2.50.21 PM.png
c
We also have a PR in flight for enterprise-server that would also one to define a marketplace or marketplaces as containing skills and plugins to be auto-loaded so that customer can define their own default agent skills as an alternative to our marketplaces. https://github.com/OpenHands/software-agent-sdk/pull/2495 https://github.com/OpenHands/OpenHands/pull/13497
m
@wooden-umbrella-84098 Follow-up on this. I was partially wrong on my previous answer. I tested the agent-server path end-to-end, and I have a couple of clarifications on our auto-activation story: There are 3 trigger modes for skills: 1. Repo `skill (trigger=None)`: injected into REPO_CONTEXT of the system prompt, i.e., active from message 0, no keyword needed. (what you want) 2/3. Knowledge skill (KeywordTrigger / TaskTrigger): only the description sits in available_skills, the body is injected into the user turn when a trigger matches. For KeywordTrigger: the user uses a special keyword, like "github", then the GitHub skill is activated. For TaskTrigger: the Agent has the skill descriptions in the system prompt and if it finds the skill is useful for the task, it can activate it during the conversation. For always-on via the agent-server, the path is
StartConversationRequest.plugins
. Hooks (
.openhands/hooks.json session_start
) can run shell but cannot inject Skill objects into
agent_context
at runtime. Therefore, hooks alone won't make a skill always-on for a server-side conversation. Minimal pattern that works (I ran this locally): 1. Drop a plugin dir in the repo:
Copy code
caveman_plugin/                                                                                                                                                                    
  ├── .plugin/plugin.json
  └── skills/caveman/SKILL.md   # no `triggers:` in frontmatter -> repo skill
2. Start the agent-server:
Copy code
uv run python -m openhands.agent_server --host 127.0.0.1 --port 8000
3.
POST
to
/api/conversations
with a plugins entry pointing at the local dir:
Copy code
{               
    "agent": { ... },                                                                                                                                                                
    "workspace": {"working_dir": "/tmp/caveman-demo"},                                                                                                                               
    "plugins": [                                                                                                                                                                     
      {"source": "/absolute/path/to/caveman_plugin"}                                                                                                                                 
    ],                                                                                                                                                                               
    "initial_message": {                                                                                                                                                             
      "role": "user",
      "content": [{"type": "text", "text": "Introduce yourself."}],                                                                                                                  
      "run": true                                                                                                                                                                    
    }
  }
Server-side,
LocalConversation._ensure_plugins_loaded()
calls
plugin.add_skills_to(agent_context)
before the first LLM call, so the caveman instructions are already in the system prompt for message 0. Agent replies in caveman voice immediately. Verified against a local server:
Copy code
**UGH!** 👋

Me OpenHands! Me help you with computer things. Me know how make code work, fix broken stuff, move files around.

You tell me what you need, me do work! Me can:
- Look at code rocks (files)
- Change code rocks to make better
- Run magic words in black box (terminal)
- Fix bad bugs that make things break
- Build new things you want

Me strong helper! Me not fancy talker, but me get job done good. Hrrm.

What you need me do today? 🔥🪨
Happy to share the example with the full plugin skeleton + start-conversation payload if it helps.
PS: you can also drop the caveman skill into your repo and then use the endpoint
skills
to load it. Just be sure that the field trigger in the
caveman
skill is set to
None
.
w
Problem is I want to use the caveman skill ALWAYS 🙂 not just for one repo How hard would it be to get always-on functionality supported by the agent-server API?
c
@nutritious-balloon-65098 do a research on OpenHands/software-agent-sdk repo, I remember seeing a load agent skills PR. I also remember we have a utility function called load user skill, where a user can install a skill to a global folder. Do we have anything like that for the agent server, or is there an open PR for that?
n
I'm on it! Xingyao Wang can track my progress here.
c
ah now i remember, @quick-window-91705 was implementing similar stuff yesterday for the automation, and i think he's working to port that over to the SDK
👍 2
l
I was implementing personal skill marketplaces but eventually decided to put it off until settings were finished, which is wrapping up now
We have the ability to import skills from a specific marketplace, so we just need to create an entry for that in the settings somewhere and activate it, it should be easy
n
Summary This was a research/question-answering task — no code changes were made. Here's the answer: The user asked about the "auto activation" / "always-on skills" strategy, specifically: 1. Whether a
load_user_skills
-like utility exists 2. Whether the agent server has equivalent functionality 3. Whether there are open PRs for this Findings: What exists today on `main`: •
load_user_skills()
exists in
openhands-sdk/openhands/sdk/skills/skill.py
— loads skills from
~/.agents/skills/
,
~/.openhands/skills/
,
~/.openhands/microagents/
(legacy), and enabled installed skills from
~/.openhands/skills/installed/
. •
install_skill(source, ...)
exists in
openhands-sdk/openhands/sdk/skills/installed.py
— installs a skill to the global
~/.openhands/skills/installed/
directory from a git URL, GitHub shorthand, or local path. • The agent server already loads user skills indirectly via
load_all_skills()
→
load_available_skills()
→
load_user_skills()
, but only from the server's local filesystem. There is no way today for an API caller to specify "always-on" skills via the agent-server API. Open PRs addressing this gap (a coordinated stack): Bottom line: The SDK-level primitives (
load_user_skills
,
install_skill
) exist and work. The agent-server gap — letting an API caller specify always-on skills — is actively being addressed by PR #2858 (ExtensionConfig) and PR #2495 (marketplace auto-load), both open and in review., with interactive elements
c
This is exactly what these PRs were intended to address. I'll get them dusted off today. https://github.com/OpenHands/software-agent-sdk/pull/2495 https://github.com/OpenHands/OpenHands/pull/13497 (edited)
thanks on a stick 2