feat: migrate agent versioning to v2 branch model - #29
Merged
Conversation
prat11m
requested review from
abhishekmishragithub,
harshitajain165 and
maharshi-smallest
as code owners
July 16, 2026 10:58
maharshi-smallest
previously approved these changes
Jul 16, 2026
abhishekmishragithub
previously approved these changes
Jul 16, 2026
prat11m
force-pushed
the
feat/versioning-v2-branch-model
branch
2 times, most recently
from
July 16, 2026 13:11
42147b8 to
a7e6ebe
Compare
Cut the MCP over from the v1 draft/version model to the v2 branch/revision model, and redesign the edit/versioning tool surface around it. Reads and test-calls keep working; the v1 write + list endpoints 409 once the backend flips ENABLE_BRANCH_MODEL, so the MCP now uses the branch APIs. Core: - versioning.ts: branch client — resolveBranch (branch_id | single | ask-when- ambiguous), resolveLiveBranch, saveConfigToBranch, publishBranch with async security-scan polling (200 committed / 202 scanning; on 404 confirm the head advanced before reporting committed). - api.ts: PUT; formatApiError translates 423 AGENT_CONFIG_FROZEN and 409 versioning_v2_migration_required into clear messages. - Tool edits are a single read-modify-write against the TARGET branch — its open draft, else its head revision (?versionId=headRevisionId), never the live config — with a guard that aborts rather than wiping tools if the config can't be resolved. Tool surface (74 tools; branch_id optional on edit/read/publish/test, asks when the agent has multiple branches): - Branches: list_branches, create_branch, rename_branch, make_branch_live - Draft (per branch, unnamed): get_branch_draft, publish_draft - Revisions (branch-scoped): list_revisions, get_revision - Diff/Test: diff, test_agent - Edit: update_agent (config+prompt+pre-call API), add_agent_tool (api_call), remove_agent_tool, configure_call_actions (end_call/transfer, agent-level) - Playbooks (multi_agents) migrated to the branch model: add_playbooks, update_playbook, configure_playbooks now edit the branch draft via branch_id. - Renamed: list_versions→list_revisions, get_version→get_revision, get_draft→get_branch_draft, list_drafts→list_branches, activate_version→make_branch_live - Merged: diff_versions+get_draft_diff→diff; test_draft+test_version→test_agent - Removed: rename_draft, update_version, compare_version_metrics Adds a stdio smoke test (smoke.mjs, npm run smoke) asserting the tool surface. No backend changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
prat11m
force-pushed
the
feat/versioning-v2-branch-model
branch
from
July 16, 2026 13:32
a7e6ebe to
500af4a
Compare
maharshi-smallest
approved these changes
Jul 16, 2026
harshitajain165
approved these changes
Jul 23, 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
Cuts the MCP's write path over from the v1 draft/version model to the v2 branch/revision model. Every config edit now targets the agent's live branch draft; publishing commits a new revision that goes live. This is a hard cutover — no dual path, no
activeVersionIdconditional. Once the backend flipsENABLE_BRANCH_MODEL, the v1 write + list endpoints 409 (versioning_v2_migration_required), so the MCP must use the branch APIs.Spec: PRO-1789. Backend guard: #3066. Freeze: #3063. Plan:
workdocs/agent-versioning/mcp-v2-migration-plan.md.Merging to
mainauto-publishes to npm (release.yml), andnpxusers pull it on their next editor restart. A v2-only MCP against a pre-flip backend 404s on/branches. So this must merge only at T0, after the backend flipsENABLE_BRANCH_MODELand the migration is validated. (Client-side tool → there's no local flag to flip; the published version is the switch.)What changed
src/versioning.ts(new) — branch client:resolveLiveBranch(GET/branches→isLive),saveConfigToLiveBranch(PUT/branches/{id}/draft),publishLiveBranch/restoreRevisionOnLiveBranchwith async security-scan polling (200committed/ 202scanning; poll draft until it commits orsecurityCheck.status === "failed").src/api.ts— addPUT;formatApiErrornow returns first-class messages for 423AGENT_CONFIG_FROZEN("edits paused for a maintenance window") and 409versioning_v2_migration_required("update your MCP").activeVersionIdconditional everywhere — write helpers are linear (resolve live branch → PUT draft); non-versioned direct-PATCH config paths deleted.update_agent(+add/remove_agent_tool) → live branch draft (see the consolidation section below);publish_draft→ branch publish (+poll, no separate activate);activate_version→make_branch_live(POST/branches/{id}/live— in v2 only a branch head can serve, so this switches which branch runs; takesbranch_id);list_versions→ branch revisions;list_drafts→ branches;make_call→ live head revision.draft_idparams — one implicit draft per branch, edits auto-stack.Versioning surface redesigned around the branch model
The whole edit/versioning surface was reworked to the v2 model (branches → revisions; one unnamed draft per branch), reviewed call-by-call with the owner. 74 tools.
Branch selection: edit/read/publish/list-revisions/test tools take an optional
branch_id. Omitted + one branch → act on it; omitted + multiple branches → return the branch list and ask the user to pick (retry withbranch_id); given → use it.resolveBranch()drives this;make_callalways uses the live head.Final versioning tools:
list_branches,create_branch,rename_branch,make_branch_liveget_branch_draft,publish_draftlist_revisions,get_revisiondiff(GET /agent/{id}/diff, refs =revisionIdor<branchId>:draft),test_agent(POST /branches/{id}/test-call,include_draft|revision_id)branch_id):update_agent(config + prompt + pre-call API),add_agent_tool(api_call),remove_agent_tool,configure_call_actions(end_call/transfer — restored; agent-level, matters for multi-agent)Renamed: list_versions→list_revisions, get_version→get_revision, get_draft→get_branch_draft, list_drafts→list_branches, activate_version→make_branch_live.
Merged: diff_versions+get_draft_diff→diff; test_draft+test_version→test_agent.
Removed: rename_draft (unnamed drafts), update_version (label set at publish), compare_version_metrics (not in v2). No archive_branch (not in v2 scope yet).
Draft-safe list edits:
add/remove_agent_toolandconfigure_call_actionsshare one read-modify-write against the branch's open draft (GET /agent?draftId=<openDraftId>→_resolvedConfig.tools, else head), so stacked edits compose. No backend changes.Review fixes (all 8 addressed)
add_playbooks/update_playbook/configure_playbooksnow edit the branch draft (branch_id,saveConfigToBranch); no morePOST /draftswithsourceVersionId: activeVersionId. Multi-agent editing works post-flip.fetchAgentAndToolsreads the target branch's open draft, else its head (?versionId=headRevisionId), never the live config; plus a guard that aborts instead of wiping tools if_resolvedConfigis absent.test_draftrefs inupdate_agent/chat→test_agent.description— confirmed intended: the v2 branch-publish body is{label?}only; there is nodescriptionfield to forward.smoke.mjs+npm run smokeasserts the tool surface (all expected present, none removed leaked).workflowscope; add- run: node smoke.mjsto.github/workflows/ci.ymlafter the build step.add_agent_tooldescription now says make tool edits one at a time (RMW; concurrent edits to one branch can drop each other).Freeze behaviour (per requirement)
While
AGENT_CONFIG_FROZENis on, every config-write tool surfaces the clean "frozen, edits paused" message (the backend 423 covers branch writes too). Reads,test_draft/test_version, and scoring keep working. Enforcement stays at the API — the MCP only translates.Not in this PR (follow-ups before/around launch)
playbooks.ts(multi-agent editing) still uses v1 draft endpoints → will 409 under the flag. Needs a follow-up before multi-agent users are cut over.rename_draft,update_versionstill call v1 (draft naming / version metadata don't exist in v2) → they 409 with the "update your MCP" message. Deprecate/remap in a follow-up.get_draft,get_version,get_draft_diff,diff_versions) andtest_draft/test_versionare unchanged — they keep working under v2.What to test
Against a dev backend with
ENABLE_BRANCH_MODELon + a migrated agent (ATOMS_API_URL=https://api.dev.smallest.ai/atoms/v1):update_agent_config/update_agent_prompt/add_agent_tool/set_pre_call_api/configure_call_actions→ change lands on the live branch draft (list_draftsshowshasOpenDraft: true).publish_draft→ both paths: synccommitted(live immediately) and asyncscanning(polls, then live); a prompt that fails the scan →failed, draft kept.make_branch_live(branch_id)→ that branch's head becomes the live config (get branch IDs fromlist_drafts).list_versions→ branch revisions;make_call→ dispatches with the head revision.AGENT_CONFIG_FROZENon dev → every write tool returns the frozen message; test-call + reads still work.What to validate
npm run type-check && npm run build). ✅tools/list). ✅activeVersionIdreads remain on the write path.Deployment
npxusers auto-update on editor restart; binary-installer users must re-run the installer (covered by launch comms).🤖 Generated with Claude Code