Skip to content

fix: stackable draft edits (draft_id) + honest publish with security-check wait#22

Merged
maharshi-smallest merged 1 commit into
mainfrom
fix/stackable-draft-edits
Jun 12, 2026
Merged

fix: stackable draft edits (draft_id) + honest publish with security-check wait#22
maharshi-smallest merged 1 commit into
mainfrom
fix/stackable-draft-edits

Conversation

@maharshi-smallest

Copy link
Copy Markdown
Collaborator

Problem

Two defects in the versioned-agent draft workflow, found while wiring a multi-tool agent via MCP:

  1. Edits can't stack. Every edit tool (update_agent_prompt, set_pre_call_api, add_agent_tool, remove_agent_tool) creates a new draft from the live version on each call. Configuring prompt + pre-call API + N tools produces N+2 divergent drafts, each holding one change — there is no way to build up a single coherent draft.
  2. publish_draft falsely reports activation. It sends {activate: true}, but main-backend always publishes versions inactive pending an async security check (AgentVersionService publishes with isActive: false by design). The flag is ignored, the tool reports "published and activated successfully", and activeVersionId never moves — silently breaking every subsequent edit, which branches from the stale live version.

Fix

  • draft_id (optional) on all four edit tools — when provided, the tool PATCHes /agent/:id/drafts/:draftId/config directly, stacking a new revision onto that draft (backend already supports this; the MCP just never targeted an existing draft). Omitted → previous behavior (fresh draft from live).
  • Batch tools array on add_agent_tool — the backend replaces singlePromptConfig.tools wholesale, so sequential single-tool writes to one draft clobber each other. Batch mode lands a full toolset in one write. Single-tool top-level params still work; duplicate names rejected; enum-param validation preserved.
  • publish_draft reports the truth — publishes, polls the version's securityCheck (pending/passed/failed, ~60s max), activates via PATCH /versions/:id/activate on pass, and reports the real outcome: activated ✓ / still pending (with activate_version follow-up instruction) / failed (with reason). New activate param (default true) to publish without activating.

Param shapes verified against main-backend: preCallAPISchema (timeout seconds), apiCallSchema (timeout ms, queryParams [{key,value}]), SecurityCheckStatus enum values.

Testing

  • npm run type-check ✓, npm run build
  • Live repro of both defects against prod API (agent 6a2bc236e4ae5f01956e0e03): three sequential edits produced three divergent drafts; three "successful" publishes left activeVersionId unmoved. Post-merge, will re-wire that agent through the new flow (stacked draft → single publish) as the end-to-end check.

🤖 Generated with Claude Code

…check wait

Two fixes for the draft workflow:

1. Edit tools spawned a new draft from the live version on every call, so
   multi-step changes (prompt + pre-call + tools) could never accumulate.
   update_agent_prompt, set_pre_call_api, add_agent_tool and
   remove_agent_tool now accept an optional draft_id and PATCH
   /drafts/:draftId/config directly — each call stacks a new revision onto
   the same draft. add_agent_tool also gains a batch `tools` array so a
   full toolset lands in one workflow_tools write (the backend replaces
   that array wholesale).

2. publish_draft sent {activate: true}, but the backend always publishes
   inactive pending an async security check (AgentVersionService:433) —
   the tool then falsely reported "activated". It now publishes, polls
   the version's securityCheck (up to ~60s), activates via
   PATCH /versions/:id/activate when it passes, and reports the real
   state: activated / pending (with activate_version follow-up) / failed
   (with reason). New `activate` param (default true) to skip activation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant