fix: push variant renames and default switches to the platform - #297
Merged
Conversation
Renaming a variant to a name with the same "clean name" (e.g. only punctuation changes) never reached the platform. Variant.file_path is derived from clean_name(), which maps punctuation and whitespace to "_", so such a rename keeps the same path: the variant is treated as kept rather than delete+create, and its changed hash puts it in updated_resources. But build_update_proto returned Variant_SetDefaultVariant, which has no name field, so the rename was dropped while local state was rewritten as if the push had succeeded. Variant updates now send Variant_UpdateVariant(id, name). attribute_values is deliberately left unset: the platform only rewrites a variant's attribute values when that field is present, and a present map must cover every non-archived attribute or the command is rejected. This also fixes a new variant marked is_default never becoming the default, since Variant_CreateVariant has no is_default field and only the update path emitted a set-default command. Set-default emission moves out of AgentStudioInterface.queue_resources into queue_set_default_commands, called at the end of _stage_commands, for both handoffs and variants. It has to run after the creates and updates because the platform rejects a set-default for a resource that does not exist yet, and queue_resources goes back to being purely generic. prepush.filter_nondefault_variant_updates is removed. It dropped every update for a non-default variant, existed only because "update" used to mean "set default", and would now suppress legitimate renames. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Coverage Report
Changed file coverage
|
polyai-moaed
approved these changes
Sep 1, 2026
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.
Summary
Renaming a variant to a name with the same "clean name" (e.g. only the punctuation changes) was silently dropped on push, and a new variant marked
is_defaultnever actually became the default. Both are fixed, and set-default command emission moves out ofqueue_resourcesinto_stage_commands.Motivation
Variant.file_pathis derived fromclean_name(), which maps punctuation and whitespace to_. So renaming a variant fromMy Variant - ProdtoMy_Variant - Prodkeeps the same path: the variant is treated as kept rather than delete+create, and its changed hash puts it inupdated_resources. ButVariant.build_update_protoreturnedVariant_SetDefaultVariant, which has nonamefield, so the rename never reached the platform — while local state andfile_structure_infowere rewritten as if the push had succeeded, leaving local and remote permanently out of sync with no error.Separately,
Variant_CreateVarianthas nois_defaultfield, and the only thing emitting a set-default command was the update path, which new resources never reach. A variant created withis_default: truetherefore never became the default.prepush.filter_nondefault_variant_updatesdropped every update for a non-default variant. That was only safe because "update" literally meant "set default"; once updates carry a name it would suppress legitimate renames, so it is removed.Changes
Variant.update_command_typeis nowvariant_update_variant, andbuild_update_protoreturnsVariant_UpdateVariant(id, name), so renames reach the platform.attribute_valueson that proto is deliberately left unset. The platform only rewrites a variant's attribute values when the field is present, and a present map must cover every non-archived attribute or the command is rejected — sending it would risk wiping values. There is a regression test guarding this.AgentStudioInterface.queue_resourcesintoqueue_set_default_commandsinpoly/utils/commands.py, called at the end ofAgentStudioProject._stage_commands, for both handoffs and variants. It has to run after the creates and updates, because the platform rejects a set-default for a resource that does not exist yet. This is what fixes the new-default-variant case.queue_resourcesgoes back to being purely generic (deletes → creates → updates, duck-typed on*_command_type/build_*_proto) with no per-resource-type knowledge.prepush.filter_nondefault_variant_updatesremoved, along with its call site and a stale docstring line.create_command_handoff_set_default/create_command_variant_set_defaultbuilders alongside the existing standalone command builders.Test strategy
poly <command>)Checklist
ruff check .andruff format --check .passpytestpassespolyCLI interface (or migration path documented)Screenshots / Logs
🤖 Generated with Claude Code