Add elements to clips
add_elementsAdd many elements across one or more clips in a single tool call. Replaces the per-element tool — always batch.
Use after calling get_element_schema to confirm the type_data shape per element_type. Items within one call are applied in order; returns one result entry per input item so partial success is fine.
Reuse instead of rebuilding: an item may pass component_id INSTEAD of element_type/type_data to insert a saved component from this workspace exactly as stored — no generation, instant — returning every new element_id plus its parameter_schema; set its content afterwards with update_elements(type_data.parameter_values). Find them with find(type='element_components'). Use base_component_id (with element_type='animation' and a prompt) only when you want a NEW variant rather than that component.
Grouping: pass group: "<name>" to keep a unit together (a card and its label, a stat and its caption) so the user can move or hide it as one thing. Items in one call sharing a name land in the same group, and a later call with that name adds to it. Grouping never changes coordinates. It does affect z-order: a group's members render contiguously at the group's slot, and a NEW group takes the slot of its first member, so grouping already-adjacent elements keeps their z-position while grouping scattered ones pulls them together at the lowest member's slot.
Concurrency: parallel-safe (conflict domain: the individual element). Each element is applied as a granular patch under a per-guide lock and merged onto the latest data, so you can fan this tool out across parallel subagents — even targeting the same clip — as long as they touch different elements. Only two edits to the SAME element id serialize (last write wins). Do NOT run it concurrently with a whole-clip or whole-project mutation on the same guide (update_clips on that clip, add_clips/remove_clip/split_clip/duplicate_clip, add_audio, update_project) — those rewrite a larger scope and would clobber the element.
Element-type quirks (handled per-item): • zoom → x/y/width/height are ignored; use center_x/center_y in type_data • image → provide x/y/width/height (the clip is located by clip_index; the clip_id input is accepted but unused) • animation → x/y/width/height default to the full canvas if omitted (the clip is located by clip_index) For everything else, x/y/width/height are required.
Animation: pass a top-level keyframes array (sibling of x/y/type_data, NOT inside type_data) — entries are { timestamp, positionX?, positionY?, width?, height?, interpolation? } in canvas pixels. positionX/Y use the SAME alignment-aware origin as the element's x/y. Text caveat: width/height are not keyframable on text — animate its size with fontSize (letterSpacing/lineHeight/padding* are also keyframable).
Position origin: x/y is the top-left corner for every element type EXCEPT text — center-aligned text positions by its CENTER POINT, right-aligned text by its top-right. Batching text alongside other shapes? Set alignment explicitly on each text item so you know which origin you're using.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| elements | Yes | Elements to add — at least one entry. | |
| project_id | Yes | Project ID |