This repository was archived by the owner on Jul 27, 2026. It is now read-only.
Repository navigation
Conversation
…tall UI Closes #380. Depends on typescript-client PR #166 (SkillsClient CRUD methods) which targets agent-server PR OpenHands/software-agent-sdk#3231. Changes: - Bump @openhands/typescript-client to main SHA 306f121 (picks up SkillsClient installSkill / uninstallSkill / toggleSkill / listInstalledSkills / getMarketplace methods) - Settings type: add default_skills?: string[] - services/settings: export CURATED_DEFAULT_SKILLS; seed DEFAULT_SETTINGS with disabled_skills:[] and default_skills:CURATED_DEFAULT_SKILLS - skills-preferences-store: localStorage helper for default_skills - settings-service (local + cloud): persist/restore default_skills - use-settings hook: map default_skills from API response - skills-service: full CRUD — listInstalledSkills, installSkill, uninstallSkill, toggleInstalledSkill, getMarketplace (all typed against SkillsClient, no casts) - use-installed-skills query hook (InstalledSkillSummary[]) - use-install-skill / use-uninstall-skill mutation hooks - i18n: add SETTINGS$SKILLS_DEFAULT_*, SETTINGS$SKILLS_INSTALL_*, SETTINGS$SKILLS_INSTALLED_* keys; regenerate i18n-keys enum - skill-card: isDefault / isInstalled props; DEFAULT + INSTALLED badges with data-testid attributes - skills-settings route: rewrite with three sections — (1) Default Skills chips + Reset-to-recommended button (persisted via useSaveSettings on every toggle), (2) Installed Skills list with version badge + Uninstall button, (3) Marketplace / install-from-source input - skills-handlers MSW mock: mutable store for installedSkills; handlers for GET /api/skills/installed, POST /api/skills/install, GET/PATCH/DELETE /api/skills/installed/:name, GET /api/skills/marketplace - Register SKILLS_HANDLERS in handlers.ts - skills-settings.test: 20 tests covering all new behaviours (default badge, chip toggle, reset, installed section, marketplace input enable/disable) Co-authored-by: openhands <openhands@all-hands.dev>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…em-curated static list
- Add public/default-skills-marketplace.json: system-curated skill manifest
(github, code-review, docker)
- Add src/services/default-skills.ts: DEFAULT_SKILL_NAMES constant (drives
DEFAULT badge client-side) and DEFAULT_MARKETPLACE_PATH ('/default-skills-marketplace.json')
- Remove CURATED_DEFAULT_SKILLS array and default_skills field from
DEFAULT_SETTINGS in services/settings.ts
- Remove default_skills from Settings interface (types/settings.ts)
- Delete skills-preferences-store.ts (no longer needed)
- Strip all default_skills persistence/propagation from settings-service.api.ts
and cloud/settings-service.api.ts
- Remove default_skills mapping from use-settings normalizer
- Rewrite skills-settings.tsx: remove chips section, reset button, and
defaultSet state; drive DEFAULT badge via DEFAULT_SKILL_NAMES.includes()
- Remove stale i18n keys: SKILLS_DEFAULT_TITLE, SKILLS_DEFAULT_DESCRIPTION,
SKILLS_RESET_TO_RECOMMENDED
- Wire marketplace_path into loadSkillsForConversation and createAgentFromSettings
(used when VITE_LOAD_PUBLIC_SKILLS=true to scope public skill loading to the
curated list instead of all 44+ marketplace skills)
- Update __tests__/routes/skills-settings.test.tsx: remove chip/default_skills
tests, add badge tests driven by static DEFAULT_SKILL_NAMES
- Update __tests__/api/agent-server-adapter.test.ts: expect marketplace_path
in agent_context when load_public=true
All 2,305+ tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Adds the openhands-automation skill to both public/default-skills-marketplace.json and DEFAULT_SKILL_NAMES so it shows the DEFAULT badge on the Skills settings page and is included in the curated public skill load when VITE_LOAD_PUBLIC_SKILLS=true. Co-authored-by: openhands <openhands@all-hands.dev>
…on start Previously: - Skills settings page: always fetched with load_public:true (full catalog) - Conversation creation: sent untyped load_public_skills/load_user_skills/ marketplace_path flags in agent_context — not in the AgentContext type, effectively ignored by the server. disabled_skills was never forwarded. VITE_LOAD_PUBLIC_SKILLS defaulted to false → agents got zero skills. Now: - buildStartConversationRequestWithEncryptedSettings fetches skills in parallel (same load_public/load_user/load_project flags as the settings page), filters by settings.disabled_skills, and passes the result as the typed agent_context.skills field. - loadSkillsForConversation also uses load_public:true unconditionally. - Removed the VITE_LOAD_PUBLIC_SKILLS env-var gate and marketplace_path scoping from the conversation path — no longer needed. - Tests updated accordingly. Co-authored-by: openhands <openhands@all-hands.dev>
Previously load_public:true with no marketplace_path loaded all 44+ skills from the full cached OpenHands/extensions clone on the server. Now all three getSkills call sites (settings page, conversation builder, loadSkillsForConversation) always pair load_public:true with marketplace_path pointing at /default-skills-marketplace.json. The server uses marketplace_path as a scoping filter on load_public — so only the 4 curated skills (github, code-review, docker, openhands-automation) are loaded as "public" skills. User-installed and project skills are unaffected (load_user/load_project still set). To load more skills users install them explicitly via the CRUD endpoints (POST /api/skills/install). Browsing the full 44+ catalog is handled separately via getMarketplace(). Co-authored-by: openhands <openhands@all-hands.dev>
marketplace_path is a relative filesystem path inside the server's cloned
extensions git repo (~/.openhands/cache/skills/), NOT a URL. Passing
window.location.origin + '/default-skills-marketplace.json' caused the
server to look for that string as a path within its repo, fail to find it,
and return [] for all public skills — breaking the skills page entirely.
Server behaviour (from skill.py):
- marketplace_path == DEFAULT_MARKETPLACE_PATH ('marketplaces/default.json')
and file not found → falls back to loading all public skills
- marketplace_path != DEFAULT and file not found → returns [] (our bug)
- marketplace_path == null → loads all public skills unconditionally
Note: 'marketplaces/default.json' does not currently exist in
OpenHands/extensions, so the server always falls back to loading all
public skills when no override is provided.
The DEFAULT badge on skill cards is still driven client-side by
DEFAULT_SKILL_NAMES; public/default-skills-marketplace.json is retained
as a frontend asset (for future install-flow use) but is not a mechanism
for server-side skill scoping.
Co-authored-by: openhands <openhands@all-hands.dev>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes agent-canvas issue #2276. Integrates
typescript-clientPR #166 (SkillsClient CRUD methods) and establishes a clean end-to-end skills flow: from what appears on the Settings page, through user configuration, to what the agent receives when a conversation starts.Design: Default Skills vs. Full Marketplace
Default skills are a system concern, not a user preference.
public/default-skills-marketplace.json+marketplace_pathon everygetSkillscallPOST /api/skills/install→ stored in~/.openhands/skills/installed/.agents/skills/in working directoryGET /api/skills/marketplace; install individuallyThe full 44+ OpenHands/extensions marketplace cache on the server is never loaded by default. All
getSkillscalls pairload_public: truewithmarketplace_pathpointing at the curated manifest — the server uses this as a scoping filter, returning only those 4 skills from its public cache.New / Changed Files
New
public/default-skills-marketplace.jsongithub,code-review,docker,openhands-automation— served as a static assetsrc/services/default-skills.tsDEFAULT_SKILL_NAMES(badge driver) andDEFAULT_MARKETPLACE_PATHconstantRemoved
src/api/skills-preferences-store.ts— deleteddefault_skillsfield removed fromSettingstype,DEFAULT_SETTINGS,use-settingsnormalizer, both settings-service API filesskills-settings.tsx— the user-editable panel, Reset to Recommended button, and associated state/handlersSETTINGS$SKILLS_DEFAULT_TITLE,SETTINGS$SKILLS_DEFAULT_DESCRIPTION,SETTINGS$SKILLS_RESET_TO_RECOMMENDEDVITE_LOAD_PUBLIC_SKILLSenv-var gate (replaced by always-on marketplace-scoped loading)Updated
src/api/skills-service.tsgetSkills()always passesload_public: true+marketplace_path— settings page shows only curated defaults + user-installed + project skills, never the full 44+ cacheSkillsClient:listInstalledSkills(),installSkill(source),uninstallSkill(name),toggleInstalledSkill(name, enabled),getMarketplace()src/api/agent-server-adapter.tscreateAgentFromSettings— removed untypedload_public_skills/load_user_skills/marketplace_pathfromagent_context(not in theAgentContextSDK type; server ignores them via open index signature); replaced withagent_context.skills: SkillInfo[]— the only typed skill-injection fieldbuildStartConversationRequestWithEncryptedSettings— fetches skills in parallel with encrypted settings and secrets using the sameload_public: true + marketplace_pathflags as the settings page, filters outsettings.disabled_skills, embeds result asagent_context.skills. What you see in Settings is exactly what the agent gets.loadSkillsForConversation— uses the same flags for consistency with the settings pagedefaultMarketplaceUrl()helper — single construction point for the absolute manifest URLskills?: SdkSkillInfo[]toStartConversationOptionssrc/routes/skills-settings.tsxDEFAULT_SKILL_NAMES.includes(skill.name)(static, not user-controlled)agent_context.skillsrationale: TheAgentContextSDK type exposesskills?: unknown[]as the only typed field for passing skill content to a conversation. Pre-fetching skills client-side, applyingdisabled_skillsfiltering, and embedding the fullSkillInfo[](withcontent) is the only spec-compliant approach that also honours user preferences.End-to-End Skills Flow
GET /api/skillswithload_public: true + marketplace_path + load_user: true + load_project: true→ returns curated 4 + user-installed + project skills; DEFAULT badge shown for names inDEFAULT_SKILL_NAMESsettings.disabled_skills[]; no server callPOST /api/skills/install { source }→ server clones to~/.openhands/skills/installed/; appears on next page load viaload_user: trueDELETE /api/skills/installed/{name}/POST /api/skills/installed/{name}/refreshbuildStartConversationRequestWithEncryptedSettingsfetches skills (same flags), filtersdisabled_skills, setsagent_context.skillsinCreateConversationRequestloadSkillsForConversationuses same flags → consistent with settings pageGET /api/skills/marketplace(separate TTL-cached endpoint); user installs skills individually from thereTests
agent-server-adapter.test.ts—agent_contextassertion updated: sync builder produces{}; staleshouldLoadPublicSkillsmock removedskills-service.test.ts— assertsmarketplace_pathis always included ingetSkillsrequestsskills-settings.test.tsx— chip/default_skillstests replaced with static DEFAULT-badge tests