fix(sdk): preserve pinned requested_ref in InstallationManager.update() - #4448
Open
santhiprakash wants to merge 1 commit into
Open
Conversation
update() hardcoded ref=None when re-fetching, so refreshing an extension pinned to a tag or commit silently un-pinned it and jumped to the source's default-branch HEAD. Re-fetch at current_info.requested_ref instead: a pinned install stays pinned (only its resolved SHA may move, e.g. a moved tag), and a floating install (requested_ref is None) still resolves to latest, same as before. Re-pinning to a different ref remains an explicit install(source, ref=new_ref, force=True) call. This mirrors the reconcile-vs-repin split already used by the Canvas Extensions staged refresh (check_canvas_extension_update), and fixes the public /refresh endpoints for Plugins and Skills that route through update(). Fixes OpenHands#4363
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
HUMAN:
Santhi Prakash — small correctness fix for the extension update path; see AGENT section for evidence.
AGENT:
Why
InstallationManager.update()always re-fetched withref=None, ignoring therequested_refrecorded at install time (added in #4349 / #4375). Callingupdate()on an extension pinned to a tag or commit silently un-pinned it and jumped to the source's current default-branch HEAD instead of just re-syncing to the pinned ref. This is reachable today via the public API for both Plugins and Skills:plugins_router.pyPOST /installed/{plugin_name}/refresh→service_update_plugin→InstallationManager.update()skills_router.pyPOST /installed/{skill_name}/refresh→service_update_skill→InstallationManager.update()Reported in #4363.
Summary
update()now re-fetches atcurrent_info.requested_refinstead of hardcodingref=None. A pinned install (tag/commit) stays pinned (only its resolved SHA may move, e.g. a moved tag); a floating install (requested_refisNone) still resolves to latest, same as before.install(source, ref=new_ref, force=True)call —update()needs no new parameter.check_canvas_extension_updatefetches withref=current_info.requested_ref), so the sharedInstallationManagernow matches that established pattern.test_update_clears_requested_ref_to_track_latest(which encoded the old un-pinning behavior) withtest_update_preserves_pinned_requested_ref, and addedtest_update_floating_install_resolves_latestto guard the floating case.Issue Number
Fixes #4363
How to Test
Video/Screenshots
Not applicable — pure logic change with no UI/visual surface; behavior is covered by the unit tests above.
Design Doc
Not added — this is a small one-line correctness fix (a trivial PR per CONTRIBUTING.md), not a new API or behavior-change in the agent loop.
Type
Notes
This changes the (previously undocumented) behavior of
update()and the/refreshendpoints for Plugins and Skills: a pinned extension now stays pinned on refresh instead of jumping to latest. The issue calls this out explicitly and the new behavior matches the reconcile-vs-repin distinction already shipped for Canvas Extensions in #4374. No persisted settings shape or REST contract changes —InstallationInfo.requested_refis unchanged.