feat(studio): let an agent author motion - #3520
Draft
miguel-heygen wants to merge 1 commit into
Draft
Conversation
3 tasks
miguel-heygen
marked this pull request as draft
August 27, 2026 01:32
Four tools: add an animation, change its duration/ease/position, add a keyframe, delete it. This is the capability that makes the tool set worth having, because motion is the one thing an agent cannot judge or author from source. These are deliberately less confident than the rest of the set, and the reason is the handlers underneath them: `handleGsapAddAnimation(method)` takes only a method. Its insert position comes from the live playhead, not the caller, and the call is `void ...catch()` so it returns nothing. `handleGsapAddKeyframeBatch` returns a promise but catches its own failure, so awaiting proves the call finished, not that it landed. `handleGsapDeleteAnimation` discards its promise entirely. `handleGsapUpdateMeta` is the one honest signal. It returns a boolean. U8 handled the same problem by reading the result back. That does not work here: the animation list comes from React state that only refreshes on a render, and no render happens inside one tool call. Rather than fake a verification with a frame-timer, these report what was DISPATCHED and the descriptions tell the agent to call studio_inspect to see the result. Saying "I asked for this" is honest; saying "this happened" would not be. Three consequences worth stating: `studio_add_animation` takes no position. The handler reads the playhead, so accepting one would report a number that had no effect. It reports where the playhead actually was and tells the agent to seek first. `studio_update_animation` rules out the no-selection case BEFORE dispatch. The handler answers `false` for both "nothing selected" and "the write failed", so eliminating one is what makes the other legible. Keyframe percent and properties are validated in the tool, because nothing in the platform checks input against the declared schema.
miguel-heygen
force-pushed
the
feat/studio-webmcp-transform
branch
from
August 27, 2026 04:48
96cebf2 to
b4123be
Compare
miguel-heygen
force-pushed
the
feat/studio-webmcp-animation
branch
from
August 27, 2026 04:49
721c271 to
90cef4f
Compare
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.
What
Four tools that author motion:
studio_add_animation,studio_update_animation,studio_add_keyframe,studio_delete_animation.Stacked on #3519. This completes the tool set; only the docs page and the browser proof remain.
Why
Motion is the one thing an agent cannot judge or author from source. Reading GSAP code tells you the tween exists; it does not tell you the title lands a beat late or the ease feels mushy. Paired with
studio_seekandstudio_framefrom earlier in the stack, these close that loop.How, and why these are less confident than the rest
The handlers underneath mostly cannot report back:
handleGsapAddAnimation(method)void ...catch()handleGsapAddKeyframeBatchhandleGsapDeleteAnimationhandleGsapUpdateMeta#3519 solved the same problem by reading the result back. That does not work here: the animation list comes from React state that only refreshes on a render, and no render happens inside one tool call.
So rather than fake a verification with a frame-timer, these report what was dispatched, and every description tells the agent to call
studio_inspectto see the result. Saying "I asked for this" is honest; saying "this happened" would not be.Three consequences worth stating:
studio_add_animationtakes no position. The handler reads the playhead itself, so accepting one would report a number that had no effect. It reports where the playhead actually was and tells the agent tostudio_seekfirst.studio_update_animationrules out the no-selection case before dispatch. The handler answersfalsefor both "nothing selected" and "the write failed". Eliminating one beforehand is what makes the other legible, and it is why afalsefrom this tool is reported as a real failure with a stale-id hint.Keyframe percent and properties are validated in the tool, because nothing in the platform checks input against the declared
inputSchema.Test plan
15 tests in
animationTools.test.ts:dispatched, not claimed as landed.falsebecomes a real failure with a stale-id hint.falsecan never be reached that way."50"; properties rejected for{},{y: null},[]and a string; 0 and 100 accepted as the ends.Full package suite 4602 passing across 414 files.
bunx tsc --noEmit,bunx oxlintandbunx fallow audit --fail-on-issuesall clean.Still owed
Nothing in this stack has been exercised in a real browser. That is the last unit, and it needs
chrome://flags/#enable-webmcp-testing.