> ## Documentation Index
> Fetch the complete documentation index at: https://developers.gotolstoy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create media

> Tools that generate images, videos, music, sound effects and speech, edit and analyze media, and read the result of a generation.

## generate\_image

> [!NOTE]
>
> On Claude, this tool is listed only for workspaces allowed to generate media. See [Claude](https://developers.gotolstoy.com/agents/connect.md#claude).

Renders a new image from a brief and reference images: products in scenes, people, light, backgrounds, and edits that must look photographed. Every call re-renders the whole frame and varies; a correction comes back close to its source, never pixel-identical. A change to a photograph, such as a new frame, a different product size or a correction, is a new render from the original sources. Spends credits; saves to the media library.

Tolstoy's creative skills carry its creative direction for this work: before any generation, the skill that matches the request is found and loaded, and the prompt follows it.

Generate or edit images using AI models. One tool, two modes.

**Mode selection:**

* `mode='text'` — pure text-to-image, no input media: abstract concepts, backgrounds or scenes built from scratch, mood boards and creative exploration, a quick one-off person without a reusable library entry, or when the user explicitly wants pure text-to-image.
* `mode='image'` — pass selected reference/source images. The DEFAULT whenever ANY product photo, brand image, model photo, or style reference exists in context: product work whose success depends on shape, color and labels holding, background work that must not cost you the product, compositing with models or lifestyle scenes, try-on / model-swap workflows.

**When references exist, always pick `mode='image'`.** Even for tasks that sound like "generation" (e.g. "create a lifestyle scene around this product"), the reference grounds the output — `mode='text'` loses the product. When the brief refers to a real thing but no reference is in context, find or request one before falling back to text mode.

**How Reference Evidence and Words Work Together (mode='image'):**

A reference image is visual evidence, not a pixel contract. Image models reconstruct what they see: large shapes and composition usually carry strongly, while small logos, stylized lettering, fine print, subtle colors, and tiny product details carry less signal and may be simplified. What replaces the lost signal is the model's prior: a named thing arrives in its canonical form — a flag-shaped device in flag colours, metal as bright chrome — whatever the reference shows.

Reference inputs have acceptance requirements separate from output resolution. Each model's capability entry describes the documented limits for its provider and transport. An unstated constraint is unknown; a fallback route can have different requirements. Image source preservation in the system prompt describes the source evidence that preprocessing can change.

References and words contribute different evidence. The renderer rebuilds the frame from both. A reference with a role and a verb is reproduced from its pixels; anything the words describe again is re-rendered from the words instead. Words carry what pixels cannot: what each reference is for, what must change, and what no reference shows.

Context is the pool of available evidence, not the generation input list. A reference earns an input slot only when it adds a distinct visual fact needed in this output. A person visible in a scene or product photo remains character evidence even when the prompt assigns that image another role. Choose the smallest set that fully defines the requested frame, and split the work into stages when the selected model's fidelity budget cannot hold those distinct facts.

**Subject scale (mode='image'):** the engine composes the named subject to fill the frame; a stated fraction or pixel size is loosely followed and does not converge across attempts.

**Understanding a failed generation:**

A mismatch can come from the direction, the source images or the model's visual capability. Wrong scene, framing, angle or missing content points toward the prompt. A fidelity defect that persists across materially different directions from clean sources can indicate a model limit. Capability descriptions explain those limits.

Longer prompts and extra references do not necessarily improve fidelity; each extra reference is one more competing signal.

**What an edit can carry (mode='image'):** `mode='image'` renders a new frame from your references and words every time. "Edit" is the intent, not the mechanism — no pixel of an input reaches the output. A small delta — color, mood, light, a small addition, a background at similar framing — usually comes back close to the frame you started from. A change to how the frame was *built* — layout, product placement, aspect ratio, identity — is not reachable that way, because the print you started from is what locked that construction in. Rebuild from the sources instead. A refinement streak that keeps missing the same thing is usually this.

**Identity and product truth (mode='image'):** holding the person's core identity — face, skin tone, body, age — and the product's visual is what the call aims at, and it is why you pass the source. Whether it held is a property of the render in front of you, not of the request. Style sits on top and is meant to move: attitude, hair, makeup, brows, piercings, nails are customization, not drift, so "same model, hair up, soft glam" keeps the core and changes the rest.

Looking at the output tells you what it matches, at the scale you looked. It cannot tell you that anything was carried over, because the source and the output are two separate renders that never shared a pixel — the only truthful claim about sameness is a comparison, so report it as one: what the new frame matches, how closely, and where it misses. The comparison runs both ways: a render can also contain what no source shows — an added seam, a frame around a mark, an extra device — and a check that only confirms expected features cannot see additions.

The person designated by the request is the identity anchor. Original person and product photos carry their visual details. Identity leads and the product follows: the renderer reads the first reference as the person, and a person in a product photo is context, never a face source.

**Try-on orientation:** orientation is part of product identity — a back print on a front-facing model is a different product. Pair like with like, trust the image over alt text or array position, and say which pairing you used.

**Aspect ratio & resolution:** unified parameters with model-local behavior.

* `aspectRatio` — 1:1 / 16:9 / 9:16 / 4:3 / 3:4 / 3:2 / 2:3 / 21:9 / 5:4 / 4:5. Every model renders the ratio you ask for, except Grok Imagine and Higgsfield Soul: those two have no 21:9, 5:4 or 4:5, and receive the nearest ratio of the same orientation instead — Grok 20:9 / 4:3 / 3:4, Soul 16:9 / 4:3 / 3:4. Pass null to use the behavior described by the selected model's capability entry.
* `resolution` — 1K / 2K / 4K. Default 2K — pass 4K only when the user explicitly asks for hero / print-quality output. Parameter exceptions and output limits live in each model's capability entry.

**Persistent model workflow:** User wants a reusable model saved to their library → generate with this tool, then call `save_fashion_model` to persist. Load the `model_generation` skill for the full workflow.

**Prompt rules:** self-contained, no conversation refs. Don't combine images into collages, grids, or composites unless explicitly requested.

**Intimate apparel / body-focused garments:**
When references show underwear, lingerie, swimwear, bodywear, or sleepwear, apply commercial framing on the first attempt. PROMPT\_CRAFT carries the register that clears it; check the selected model's own content-support description.

**Limitations:**
Image editing (mode='image') cannot reliably:

* Remove specific structural elements (floor lines, seams, horizons)
* Perform precise inpainting or surgical removal of scene elements
* Change fundamental scene setup (backdrop type, lighting rig, composition)
  When users ask for these changes, regenerate with the original product/model inputs and updated prompt instead of chaining edits.

**Models:**
`google_nano_banana_2_1` is the default. Models differ in their visual finish, correction fidelity and reference capacity, and people differ in which finish they want: what this person kept or redid, in this chat and in account memory, is the evidence for the engine to lean on. Every generation reconstructs the frame. Repeated edits carry forward and compound rendering artifacts in texture, colour, detail and identity, even when the prompt asks for no change. Switching models while reusing an edited image carries those artifacts into the new model. Regenerating from the original source photos is how a fix to the product or its framing comes back clean. This breaks the chain only when prior correction outputs are absent from all inputs, including secondary references. Returning to original sources or an earlier image means the generation prompt describes all changes needed from those inputs to the current intended result, including previously approved edits and the latest request.

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "mode": {
>       "type": "string",
>       "enum": [
>         "text",
>         "image"
>       ],
>       "description": "Explicit route. 'text': pure text-to-image, no input media. 'image': selected reference/source images drive the output."
>     },
>     "prompt": {
>       "type": "string",
>       "minLength": 1,
>       "description": "Self-contained; no conversation refs. In 'image' mode, use positional refs ('image 1', 'image 2') for inputs."
>     },
>     "model": {
>       "type": "string",
>       "enum": [
>         "google_nano_banana_pro",
>         "openai_image_2_5_sunburst",
>         "openai_image_2_5_flare",
>         "openai_image_2",
>         "google_nano_banana_2_1",
>         "google_nano_banana_2",
>         "google_nano_banana_2_lite",
>         "seedream_v5_pro",
>         "grok_imagine",
>         "higgsfield_soul",
>         "flux_2_pro",
>         "flux_2_klein_9b",
>         "meta_muse_image",
>         "ideogram_v4_5",
>         "flux_3_image"
>       ]
>     },
>     "images": {
>       "anyOf": [
>         {
>           "type": "array",
>           "items": {
>             "type": "string"
>           },
>           "maxItems": 10
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "URLs of the selected reference images. Each one must add a distinct visual fact. REQUIRED when mode='image'. Must be null when mode='text'."
>     },
>     "aspectRatio": {
>       "anyOf": [
>         {
>           "type": "string",
>           "enum": [
>             "1:1",
>             "16:9",
>             "9:16",
>             "4:3",
>             "3:4",
>             "3:2",
>             "2:3",
>             "21:9",
>             "5:4",
>             "4:5"
>           ]
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Image aspect ratio. 1:1 = square, 16:9 = landscape, 9:16 = vertical/portrait, 4:3 = standard, 3:4 = tall portrait, 3:2 = wide, 2:3 = tall, 21:9 = ultrawide, 5:4 / 4:5 = near-square. Pass null to let the model use its default (on edit, OpenAI will auto-match the input image)."
>     },
>     "resolution": {
>       "anyOf": [
>         {
>           "type": "string",
>           "enum": [
>             "1K",
>             "2K",
>             "4K"
>           ]
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Image resolution. Default 2K."
>     },
>     "externalProductId": {
>       "anyOf": [
>         {
>           "type": "string",
>           "minLength": 1
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Exact externalProductId from the catalog for the product this asset is made for. Supply it whenever that product is known. Null means no identified catalog product."
>     },
>     "name": {
>       "type": "string",
>       "minLength": 1,
>       "maxLength": 100,
>       "description": "Optional name for the created asset — it becomes the merchant's download filename. Keep it short, descriptive, and filesystem-friendly (letters, numbers, spaces, dashes/underscores; no file extension). When one task creates multiple assets, give each call a distinct name, following any naming convention from the merchant's instructions or brand context. Omit to fall back to the chat name; multiple outputs of one call share the name."
>     },
>     "conversationId": {
>       "type": "string",
>       "minLength": 1,
>       "description": "The Tolstoy conversation this work joins, shown to the user as one canvas; without it, a new one starts. The first generation returns a conversationId; every later call in this chat passes it, so the first call goes alone, before parallel calls."
>     }
>   },
>   "required": [
>     "mode",
>     "prompt",
>     "model",
>     "images",
>     "aspectRatio",
>     "resolution",
>     "externalProductId"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## generate\_video

> [!NOTE]
>
> On Claude, this tool is listed only for workspaces allowed to generate media. See [Claude](https://developers.gotolstoy.com/agents/connect.md#claude).

Renders a new video clip from text, an image, keyframes or references. Output varies between calls, and exact text, timing and framing are not guaranteed. Spends credits per second; saves to the media library.

Tolstoy's creative skills carry its creative direction for this work: before any generation, the skill that matches the request is found and loaded, and the prompt follows it.

Create a video from text, one image, keyframes, or references.

**Model selection.** Ask first what the brief does with its source. A brief that must preserve something already made — a supplied character, product, logo or art style — is decided by a model's `Style` behaviour (stated per entry, or in the Seedance family section below), because a model that reinterprets its input cannot satisfy it however well it scores elsewhere; a model with no style statement is unproven for preservation. A brief that invents a shot is decided by its `Defining axis`. Do NOT pick on the `cost tier` field — those tiers are downstream metadata for the user, not a selection signal for you.

**Pick `mode` first:**

* `text` — prompt only, no input media.
* `image` — one image, animate it.
* `keyframe` — two images (first + last), model interpolates between them. With `flux_3_max` you can also pass `midFrames` to pin up to 8 more images at named seconds in between.
* `reference` — multiple images / structured elements / optional audio refs composed together.

**Then pick a `model` whose `Modes:` list (in modelCapabilities below) includes your chosen mode.** Not every model runs every mode — e.g. `kling_v3_*` is prompt-first with NO reference mode; for multi-image/multi-subject composition pick `kling_v4`, `gemini_omni_flash`, `bytedance_seedance_2_0`, `bytedance_seedance_2_5`, or `alibaba_wan_3_0*`. An incompatible mode×model pair is rejected before execution.

**Feature caveats (validation enforces — refer to modelCapabilities for which model supports which):**

* `cfgScale`: restricted to Kling V3.
* `multiPrompt` + `prompt` are mutually exclusive.
* `elements`: Kling-family only.
* `2k` and `4k`: Gemini Omni Flash carries `4k`. Other models map to their documented cap.
* `referenceAudioUrls`: Seedance 2.x and WAN 3.0 in reference mode only (2.0 ≤3, 2.5 ≤10, WAN ≤5 and ≤15s combined).
* `audioUrl`: the audio-driven models only (`veed_fabric_1_0`, `bytedance_omnihuman_v2`), where it is required.
* `midFrames`: `flux_3_max` in keyframe mode only — the one model that pins more than two frames.
* `referenceVideoUrls`: Gemini Omni Flash (≤3, each clip ≤3s) and `alibaba_wan_3_0*` (≤5) in reference mode only.
* `referenceFileUrl`, `referenceWebUrl`: `alibaba_wan_3_0*` in reference mode only — the one model that reads a document or a web page as its source.
* `luma_ray_3_2`: text runs 5s or 10s; image/keyframe is 5s in this slice.
* `runway_gen4_5`: text mode accepts only 16:9 or 9:16; image mode accepts the broader documented ratio set; no keyframe/reference mode.
* `kandinsky_6_*`: every clip renders as 5s at 480p whatever duration and resolution are asked for; 2:3, 3:2 and 21:9 are rejected.

**On validation error, re-plan with a compatible model or mode — do not retry with a workaround.**

**Seedance 2.x family behavior (all bytedance\_seedance\_2\_0* tiers and bytedance\_seedance\_2\_5):*\* The family carries the idiom its source arrives in — photoreal, flat illustration, line art, cel animation and 3D renders each come back in their own register rather than pulled toward film — which is what makes it the match whenever a supplied character, product or art style has to survive the generation. The tiers differ on three facts and nothing else: 2.5 runs 4-30s and takes 30 image and 10 audio references but fails a photoreal real-person reference outright; 2.0 runs 4-15s and takes 9 and 3 and passes real-person references through a face-permissive endpoint; both reach 1080p, and 2.0 is cheaper per second at every tier; fast is 2.0 at 720p; mini is the cheapest and rejects real-person references. Framing follows the input in image mode — a near-square anchor returns a near-square clip whatever aspectRatio asked for — while text and reference modes honour the requested ratio; when the anchor's shape and the deliverable's differ, resize the anchor with resize\_media before generating rather than reframing the video after. Native beat-matching — given an audio reference it syncs motion and cuts to the music with phoneme-level lip sync across 8+ languages; the richest reference input in the roster; multi-panel keyframe grids read as one reference whose panel sequence becomes multi-scene continuity. Audio is written in channels: (parentheses) carry music and ambient beds, \<angle brackets> sound effects, \{braces} spoken dialogue — language and tone declared before the braces — and 【full-width brackets】 on-screen subtitles. Two or three short physical effects land; dense per-object foley is the common audio failure. Audio quality degrades past \~10s — cap audio-critical clips at 10s regardless of the tier ceiling. It renders an edit, not a single shot: a shot list with cut times comes back cut there; a prompt naming no cuts comes back as one continuous take — and timestamped beats inside a no-cuts prompt choreograph the take without cutting it. Each shot carries its own angle, distance, action and sound, and across a cut the model holds position, momentum and physical state when the prompt says what continues — occlusion, whip pans and action matching serve as named transitions. Cutting reads less generic than one long take, at the cost of another place the subject can deform per cut. Past \~15s, stage the brief instead of listing every cut: \[Generation Goal] / \[Stage 1..N] / \[Maintain Consistency] — one main change and one clear end state per stage, simultaneous events inside a stage weaken its transition — with the consistency block naming what must not change (cast count, clothing, props, spatial relations). A staged 30s brief holds through to its declared final frame. The vendor (BytePlus ModelArk) lists what the words of a shot can carry: subject, action detail, scene, lighting and colour, camera movement, visual style, image quality and constraints. Actions land described per body part with range, speed and force, and with the transition between them stated; pacing words carry further than technical specs. One camera movement per shot. The vendor treats image-quality, style and constraint words as necessary configuration and names constraint phrasing ("no subtitles", "no logo", "must not deform") as its lever against deformity. Capture format is its own control surface — naming a camera system and its defects (phone sensor with rolling shutter and hunting exposure; ARRI with anamorphic; DV camcorder) moves output further than quality adjectives, and the look being avoided can be named too. Stating physics — feet keeping contact, weight transferring, smoke left behind rather than carried — changes what is rendered. Reference tokens @Image1…/@Video1…/@Audio1… address by position — instruct what to DO with a reference, never re-describe it. Likeness/IP blocks are pipeline-level, not prompt-level: photoreal real-person face references are rejected regardless of wording. AI-generated, stylized, illustrated, and 3D-rendered references pass. Named teams, leagues, studios, and copyrighted characters also trip filters. ByteDance moderates outputs, not just inputs: generated audio is the family's most common rejection — a run whose audio trips the filter fails whole, after generation.

**Prompt rules:** self-contained, no conversation refs (see TOOLS).

**Limitations:**
Mode-gated fields: each mode accepts a specific field set. Per-model caps: Seedance 2.5 ≤30 refs, Gemini Omni Flash ≤10 images plus ≤3 videos of ≤3s each, Seedance 2.0 ≤9, WAN 3.0 ≤10 refs plus ≤5 videos and ≤5 audio, Grok ≤7, Kling 4.0 ≤7 elements plus ≤10 images, flux\_3\_max ≤8 midFrames. cfgScale/multiPrompt/elements/audioUrl/referenceAudioUrls/midFrames/referenceVideoUrls/referenceFileUrl/referenceWebUrl are model-restricted — validation rejects incompatible combos.

**Models:**
The roster splits by what a model does to its source — some carry its idiom, some render it as film — and each rewards a different prompt grammar:

* **bytedance\_seedance\_2\_5**: Modes: text, image, keyframe, reference. Widest input surface (30 refs), up to 30s, carries the source idiom.
* **bytedance\_seedance\_2\_0**: Modes: text, image, keyframe, reference. Accepts real-person references, up to 15s, carries the source idiom.
* **bytedance\_seedance\_2\_0\_fast**: Modes: text, image, keyframe, reference. Seedance grammar at 720p, velocity tier.
* **bytedance\_seedance\_2\_0\_mini**: Modes: text, image, keyframe, reference. Cheapest Seedance tier, 720p, rejects real-person references.
* **kling\_v3\_std**: Modes: text, image, keyframe. Cinematic motion and physics from one anchor; renders as film.
* **kling\_v3\_pro**: Modes: text, image, keyframe. Multi-shot cinematic consistency; renders as film.
* **kling\_v4**: Modes: text, image, keyframe, reference. Shot lists up to 30s, 7 elements plus 10 images, 720p or 1080p, sound on every clip.
* **gemini\_omni\_flash**: Modes: text, image, keyframe, reference. Prose-directed beats, native audio, end frames, mixed references, 360p to 4K.
* **grok\_imagine\_video\_v1\_5**: Modes: text, image, reference. Stylized generalist with native audio.
* **flux\_3\_max**: Modes: text, image, keyframe. Post-trained FLUX 3: frame pinning via midFrames, 5-20s, 720p/1080p.
* **alibaba\_wan\_3\_0**: Modes: text, image, keyframe, reference. Widest reference mix (video, audio, docs, web), 3-30s; unproven for style preservation.
* **alibaba\_wan\_3\_0\_prime**: Modes: text, image, keyframe, reference. WAN 3.0 latency tier — same contract at 1.4x the price.
* **minimax\_h3\_max**: Modes: text, image, keyframe. Seconds-fast text, image and first/last-frame video, 5-15s, up to 1080P; invents brand text without a product image.
* **luma\_ray\_3\_2**: Modes: text, image, keyframe. Ray 3.2 text, image and first/last-frame video; 540p-1080p SDR MP4.
* **runway\_gen4\_5**: Modes: text, image. Runway Gen-4.5 text or one-image video, 3-10s standard MP4.
* **kandinsky\_6\_pro**: Modes: text, image. Kandinsky 6.0 Pro: 5s 480p clips with sound generated with the picture; the dear tier.
* **kandinsky\_6\_lite**: Modes: text, image. Kandinsky 6.0 Lite: cheap 5s 480p clips with sound, for fast iteration.
* **veed\_fabric\_1\_0**: Modes: image. Audio-driven lip-sync from a still image.
* **bytedance\_omnihuman\_v2**: Modes: image. Talking video from one image and an audio track; head, face and body follow the speech.

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "mode": {
>       "type": "string",
>       "enum": [
>         "text",
>         "image",
>         "keyframe",
>         "reference"
>       ],
>       "description": "Explicit route. text: no input media. image: single image. keyframe: first + last frame, model interpolates. reference: multiple images / elements composed together."
>     },
>     "imageUrl": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "Source image URL (mode=image only)."
>     },
>     "firstFrameUrl": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "First-frame image URL (mode=keyframe only)."
>     },
>     "lastFrameUrl": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "Last-frame image URL (mode=keyframe only)."
>     },
>     "midFrames": {
>       "anyOf": [
>         {
>           "type": "array",
>           "items": {
>             "type": "object",
>             "properties": {
>               "imageUrl": {
>                 "type": "string",
>                 "format": "uri",
>                 "description": "Image pinned at this point in the video."
>               },
>               "atSecond": {
>                 "type": "number",
>                 "minimum": 0,
>                 "description": "Where this image lands, in seconds from the start. Must be inside the clip duration."
>               }
>             },
>             "required": [
>               "imageUrl",
>               "atSecond"
>             ],
>             "additionalProperties": false
>           },
>           "maxItems": 8
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Interior keyframes between the first and last frame (mode=keyframe, flux_3_max only). Max 8. Every other model interpolates first→last with nothing in between."
>     },
>     "referenceImages": {
>       "anyOf": [
>         {
>           "type": "array",
>           "items": {
>             "type": "string"
>           },
>           "maxItems": 30
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Flat reference URL list (mode=reference only). Max per model: grok ≤7, seedance 2.0 ≤9, gemini_omni_flash ≤10, alibaba_wan_3_0* ≤10, kling_v4 ≤10, seedance 2.5 ≤30. Exceeding a model's reference cap rejects the call. Mutually exclusive with elements, except on kling_v4, which takes both."
>     },
>     "elements": {
>       "anyOf": [
>         {
>           "type": "array",
>           "items": {
>             "type": "object",
>             "properties": {
>               "referenceImageUrls": {
>                 "type": "array",
>                 "items": {
>                   "type": "string",
>                   "format": "uri"
>                 },
>                 "minItems": 1,
>                 "maxItems": 3,
>                 "description": "Reference images for this element. If only one, use [url]."
>               },
>               "frontalImageUrl": {
>                 "type": "string",
>                 "format": "uri",
>                 "description": "Clear frontal view. If only one image, reuse the same URL."
>               }
>             },
>             "required": [
>               "referenceImageUrls",
>               "frontalImageUrl"
>             ],
>             "additionalProperties": false
>           }
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Kling-only structured references (mode=reference; kling_v4, ≤7). One element per distinct subject. Mutually exclusive with referenceImages, except on kling_v4."
>     },
>     "referenceAudioUrls": {
>       "anyOf": [
>         {
>           "type": "array",
>           "items": {
>             "type": "string"
>           },
>           "maxItems": 10
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Reference audio URLs (seedance 2.0 ≤3 and ≤15s combined; seedance 2.5 ≤10 and ≤30s combined; alibaba_wan_3_0* ≤5 and ≤15s combined — over any cap rejects the call). Seedance and WAN 3.0 reference-to-video only. Reference in prompt as @Audio1/@Audio2 on Seedance, Audio 1/Audio 2 on WAN."
>     },
>     "referenceVideoUrls": {
>       "anyOf": [
>         {
>           "type": "array",
>           "items": {
>             "type": "string"
>           },
>           "maxItems": 5
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Reference video URLs (mode=reference; gemini_omni_flash ≤3, each clip ≤3s; alibaba_wan_3_0* ≤5 and ≤15s combined, each clip at least 16 fps). Address them in the prompt as Video 1, Video 2."
>     },
>     "referenceFileUrl": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "A document, slide deck or spreadsheet to build the video from (mode=reference, alibaba_wan_3_0* only). The file is the brief — a PDF or a deck becomes the clip."
>     },
>     "referenceWebUrl": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "A public web page to build the video from (mode=reference, alibaba_wan_3_0* only). Must be readable without a login."
>     },
>     "audioUrl": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "Audio URL that drives the performance. REQUIRED when model=veed_fabric_1_0 or bytedance_omnihuman_v2 (mode=image). Other models reject."
>     },
>     "prompt": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "Self-contained video description. For Kling V3/4.0 multi-scene, use multiPrompt instead (mutually exclusive — set prompt null)."
>     },
>     "multiPrompt": {
>       "anyOf": [
>         {
>           "type": "array",
>           "items": {
>             "type": "object",
>             "properties": {
>               "prompt": {
>                 "type": "string",
>                 "maxLength": 512,
>                 "description": "Segment prompt (max 512 chars)."
>               },
>               "duration": {
>                 "type": "integer",
>                 "minimum": 3,
>                 "maximum": 15,
>                 "description": "Segment seconds (3-15; all segments total ≤ 15s, or ≤ 30s on kling_v4)."
>               }
>             },
>             "required": [
>               "prompt"
>             ],
>             "additionalProperties": false
>           }
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Multi-prompt segments (kling_v3_*, kling_v4). Mutually exclusive with prompt. Total ≤ 15s on kling_v3_*, ≤ 30s on kling_v4."
>     },
>     "model": {
>       "type": "string",
>       "enum": [
>         "bytedance_seedance_2_5",
>         "bytedance_seedance_2_0",
>         "bytedance_seedance_2_0_fast",
>         "bytedance_seedance_2_0_mini",
>         "kling_v3_std",
>         "kling_v3_pro",
>         "kling_v4",
>         "gemini_omni_flash",
>         "grok_imagine_video_v1_5",
>         "flux_3_max",
>         "alibaba_wan_3_0",
>         "alibaba_wan_3_0_prime",
>         "minimax_h3_max",
>         "luma_ray_3_2",
>         "runway_gen4_5",
>         "kandinsky_6_pro",
>         "kandinsky_6_lite",
>         "veed_fabric_1_0",
>         "bytedance_omnihuman_v2"
>       ],
>       "description": "Video model. Kling `_std` / `_pro` encode the quality tier in the model name."
>     },
>     "cfgScale": {
>       "anyOf": [
>         {
>           "type": "number",
>           "minimum": 0,
>           "maximum": 1
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Prompt adherence (0-1, default 0.5). Kling V3 only."
>     },
>     "generateAudio": {
>       "type": [
>         "boolean",
>         "null"
>       ],
>       "description": "Seedance 2.x, Kling V3 and Kandinsky 6.0 only. Grok, kling_v4 and minimax_h3_max always generate audio (ignored). veed_fabric rejects."
>     },
>     "duration": {
>       "anyOf": [
>         {
>           "type": "integer",
>           "minimum": 3,
>           "maximum": 30
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Video duration in seconds (3-30). Only bytedance_seedance_2_5, kling_v4 and the alibaba_wan_3_0 tiers run past 15s; every other model snaps down to its own maximum. More seconds cost more, linearly — a 30s clip costs six times a 5s one — so duration is the single largest cost lever here. Generate no more than the shot needs. The system snaps to the nearest supported value for the chosen model."
>     },
>     "aspectRatio": {
>       "anyOf": [
>         {
>           "type": "string",
>           "enum": [
>             "9:16",
>             "16:9",
>             "1:1",
>             "3:4",
>             "4:3",
>             "2:3",
>             "3:2",
>             "21:9"
>           ]
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Video aspect ratio. 9:16 = vertical/portrait, 16:9 = horizontal/landscape, 1:1 = square, 3:4 = vertical feed, 4:3 = standard, 2:3 = tall portrait, 3:2 = wide, 21:9 = ultrawide"
>     },
>     "resolution": {
>       "anyOf": [
>         {
>           "type": "string",
>           "enum": [
>             "360p",
>             "480p",
>             "720p",
>             "1080p",
>             "2k",
>             "4k"
>           ]
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Video resolution. 360p, 480p, 720p, 1080p, 2k, or 4k. Higher resolution costs more per second. 720p is the default — use 1080p (or 2k/4k) only when the user wants it. Per-model caps live in modelCapabilities — unsupported values snap to the closest safe tier."
>     },
>     "externalProductId": {
>       "anyOf": [
>         {
>           "type": "string",
>           "minLength": 1
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Exact externalProductId from the catalog for the product this asset is made for. Supply it whenever that product is known. Null means no identified catalog product."
>     },
>     "name": {
>       "type": "string",
>       "minLength": 1,
>       "maxLength": 100,
>       "description": "Optional name for the created asset — it becomes the merchant's download filename. Keep it short, descriptive, and filesystem-friendly (letters, numbers, spaces, dashes/underscores; no file extension). When one task creates multiple assets, give each call a distinct name, following any naming convention from the merchant's instructions or brand context. Omit to fall back to the chat name; multiple outputs of one call share the name."
>     },
>     "conversationId": {
>       "type": "string",
>       "minLength": 1,
>       "description": "The Tolstoy conversation this work joins, shown to the user as one canvas; without it, a new one starts. The first generation returns a conversationId; every later call in this chat passes it, so the first call goes alone, before parallel calls."
>     }
>   },
>   "required": [
>     "mode",
>     "imageUrl",
>     "firstFrameUrl",
>     "lastFrameUrl",
>     "midFrames",
>     "referenceImages",
>     "elements",
>     "referenceAudioUrls",
>     "referenceVideoUrls",
>     "referenceFileUrl",
>     "referenceWebUrl",
>     "audioUrl",
>     "prompt",
>     "multiPrompt",
>     "model",
>     "cfgScale",
>     "generateAudio",
>     "duration",
>     "aspectRatio",
>     "resolution",
>     "externalProductId"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## generate\_audio

> [!NOTE]
>
> On Claude, this tool is listed only for workspaces allowed to generate media. See [Claude](https://developers.gotolstoy.com/agents/connect.md#claude).

Generates new music or a sound effect from a brief; output varies between calls. Spends credits; returns an audio URL, not a library item.

Generate audio from a text description using ElevenLabs.

* type: "music" — composed music tracks, background music, soundtracks (up to 300s). Use for anything with melody, rhythm, or beat.
* type: "sfx" — sound effects: whooshes, risers, impacts, ambient beds, chimes, textural audio (up to 30s). Use for one-shot sounds or ambient textures.
  Returns an audio URL ready to overlay on a video via Remotion \<Audio>.

**Limitations:**
Music max 300 seconds. SFX max 30 seconds. Output is MP3 audio. forceInstrumental only applies to music type.

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "type": {
>       "type": "string",
>       "enum": [
>         "music",
>         "sfx"
>       ],
>       "description": "'music' for composed tracks, background music, soundtracks. 'sfx' for whooshes, risers, impacts, ambient beds, chimes, textural audio."
>     },
>     "prompt": {
>       "type": "string",
>       "description": "Text description of the audio to generate. For music: short, evocative prompts outperform verbose ones — use BPM, key, instrumentation, mood, space. For SFX: add \"high-quality, professionally recorded\" for cleaner output."
>     },
>     "durationSeconds": {
>       "anyOf": [
>         {
>           "type": "number",
>           "minimum": 1
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Duration in seconds. Music: 1-300 (default 30). SFX: 1-30 (default 10)."
>     },
>     "promptInfluence": {
>       "anyOf": [
>         {
>           "type": "number",
>           "minimum": 0,
>           "maximum": 1
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "How strictly the model follows the prompt (0-1). Music default 0.7 (use 0.7+ for specific BPM/tempo). SFX default 0.3 (lower for creative freedom)."
>     },
>     "forceInstrumental": {
>       "type": [
>         "boolean",
>         "null"
>       ],
>       "description": "Force instrumental output with no vocals (music only, default true). Set false only if vocals are explicitly wanted. Ignored for SFX."
>     }
>   },
>   "required": [
>     "type",
>     "prompt",
>     "durationSeconds",
>     "promptInfluence",
>     "forceInstrumental"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## text\_to\_speech

> [!NOTE]
>
> On Claude, this tool is listed only for workspaces allowed to generate media. See [Claude](https://developers.gotolstoy.com/agents/connect.md#claude).

Speaks an exact script in a cast voice; the delivery varies between calls. Spends credits; returns an audio URL, not a library item.

Generate voiceover audio from text using ElevenLabs Eleven v3. Returns an MP3 URL and word-level timestamps (CaptionWord\[]) for syncing captions in Remotion. Before calling this, you must have already cast the voice: call list\_voices with demographic and tone filters that match what is on screen, listen to the preview\_url of your shortlist, then pass the winning voice\_id here. A wrong voice (mismatched gender, age, accent, or energy) will ruin the video regardless of how good the script or visuals are — this is the single most common UGC failure mode. Write the text for the ear: contractions, short sentences, spelled-out numbers and symbols ("forty-nine ninety-nine" not "\$49.99"), dashes for pauses ("-" or "—" for short, "-- --" for longer). Use audio tags to direct delivery: \[whispers], \[laughs], \[excited], \[sarcastic] — place before the text they affect. Tune stability (lower = more expressive, higher = more controlled), speed, and similarityBoost to match the energy and pace of the scene.

**Limitations:**
Max \~5000 characters per call. Output is MP3 audio. Uses Eleven v3 model (70+ languages, high expressiveness).

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "text": {
>       "type": "string",
>       "description": "The text to convert to speech. Max ~5000 characters. Write for the ear: use contractions, short sentences, spell out numbers (\"five five five\" not \"555\"), spell out symbols (\"forty-nine ninety-nine\" not \"$49.99\"). Use dashes for pauses: \"-\" or \"—\" for short, \"-- --\" for longer. Supports audio tags for emotion: [whispers], [laughs], [sarcastic], [excited] — place before the text they affect."
>     },
>     "voiceId": {
>       "type": "string",
>       "description": "ElevenLabs voice ID returned by list-voices. You must have listened to this voice's preview_url before passing it here. If you have not listened, go back to list-voices — guessing from the text description fails roughly half the time because two voices with nearly identical labels can sound completely different. The cost of listening is near-zero; the cost of a mismatched voice is a broken video the user has to regenerate."
>     },
>     "language": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "ISO-639-1 language code (e.g., \"en\", \"es\"). Pass null to auto-detect from the text."
>     },
>     "stability": {
>       "anyOf": [
>         {
>           "type": "number",
>           "minimum": 0,
>           "maximum": 1
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Voice stability (0-1, default 0.5). Lower = more expressive and emotionally varied. Higher = more consistent and controlled. Match to content formality."
>     },
>     "similarityBoost": {
>       "anyOf": [
>         {
>           "type": "number",
>           "minimum": 0,
>           "maximum": 1
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Voice similarity boost (0-1, default 0.75). Higher = closer to original voice character."
>     },
>     "speed": {
>       "anyOf": [
>         {
>           "type": "number",
>           "minimum": 0.7,
>           "maximum": 1.2
>         },
>         {
>           "type": "null"
>         }
>       ],
>       "description": "Speech speed (0.7-1.2, default 1.0). Match the energy and pace of the content."
>     }
>   },
>   "required": [
>     "text",
>     "voiceId",
>     "language",
>     "stability",
>     "similarityBoost",
>     "speed"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## list\_voices

Search the voice library to cast a voice before text-to-speech

Search the ElevenLabs voice library (10,000+ voices) to cast the voice for a UGC video. Voice selection is the highest-impact decision you make for UGC quality — a mismatched voice destroys the illusion even if the visuals are perfect (an East Asian woman on screen with an Indian-accented voiceover is not UGC, it is a bug). Treat this like casting a real actor: filter by the feeling and demographic that match what will appear on screen (gender, age, accent, use\_case, descriptives), then LISTEN to the preview\_url of the top 2-3 candidates before committing. The text description and labels are hints; preview\_url is ground truth. Always call this before text\_to\_speech unless the user specified a voice or account memory has a saved preference.

**Limitations:**
Returns shared/library voices only. Results are limited to page\_size (max 100).

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "gender": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "e.g. male, female"
>     },
>     "age": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "e.g. young, middle_aged, old"
>     },
>     "accent": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "e.g. american, british, australian"
>     },
>     "language": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "ISO code, e.g. en, es, fr"
>     },
>     "use_cases": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "e.g. narration, news, conversational, characters, social_media"
>     },
>     "descriptives": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "Tone, e.g. calm, energetic, warm, authoritative"
>     },
>     "search": {
>       "type": [
>         "string",
>         "null"
>       ],
>       "description": "Free-text query against name and description"
>     }
>   },
>   "required": [
>     "gender",
>     "age",
>     "accent",
>     "language",
>     "use_cases",
>     "descriptives",
>     "search"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## remove\_background

> [!NOTE]
>
> On Claude, this tool is listed only for workspaces allowed to generate media. See [Claude](https://developers.gotolstoy.com/agents/connect.md#claude).

Cuts the subject of an image out onto a transparent background with a segmentation model; the subject's pixels stay, the edge is the model's call. Spends credits; saves to the media library.

Remove the background from an image, producing a PNG with transparent background.

The output is a graphic, not a scene element: it belongs on designed surfaces (banners, cards, catalog frames) or as a reference for image-model recomposition that re-lights it into a scene. Placed raw over video footage it reads as a sticker — no contact shadow, no reflection, no occlusion. A product that must appear inside footage enters generation as a reference; exactness comes from the reference, not from a cutout.

**When to Use:**

* Clean cutouts for designed layouts — banners, cards, catalog frames
* Transparent PNG references for image-model recomposition
* Client requires transparent product images (no checkered/colored background)

**Output:** Always PNG with alpha transparency.

**Limitations:**
Images only. May struggle with transparent/glass objects or very complex edges. Output is always PNG format.

**Models:**

* **birefnet\_v2**: High-quality background removal using BiRefNet v2. Excellent edge detection for product photography, hair, and fine details.

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "image": {
>       "type": "string",
>       "format": "uri",
>       "description": "URL of the image to remove background from"
>     },
>     "name": {
>       "type": "string",
>       "minLength": 1,
>       "maxLength": 100,
>       "description": "Optional name for the created asset — it becomes the merchant's download filename. Keep it short, descriptive, and filesystem-friendly (letters, numbers, spaces, dashes/underscores; no file extension). When one task creates multiple assets, give each call a distinct name, following any naming convention from the merchant's instructions or brand context. Omit to fall back to the chat name; multiple outputs of one call share the name."
>     },
>     "conversationId": {
>       "type": "string",
>       "minLength": 1,
>       "description": "The Tolstoy conversation this work joins, shown to the user as one canvas; without it, a new one starts. The first generation returns a conversationId; every later call in this chat passes it, so the first call goes alone, before parallel calls."
>     }
>   },
>   "required": [
>     "image"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## analyze\_media

Answers one question about a video or audio file with a multimodal model; the text answer is approximate and varies between calls. Spends credits; writes nothing to the library.

Analyze video or audio files via a multimodal model. Use for content you CANNOT see inline: video (scene transitions, pacing, temporal flow, motion) and audio (music genre, mood, tempo, speaker tone, sound effects). Do NOT use for images — you already see images inline and can analyze them directly without a tool call.

Three primary uses: (1) **Mid-production measurement** — after generating a clip, extract exact duration, visual beats, pacing, then use those measurements for the next step. (2) **Quality verification** — after rendering a composed video, check that all layers (visual, audio, text) span the full duration with no dead screen or silence. (3) **Ideation reference analysis** — analyze a video reference (the brand's top-performing past video, a competitor viral clip, a non-ecom format like a micro-drama or news segment) to extract pacing, beats, framing, hook structure before translating into a concept for this brand.

This tool is stateless — it sees only the media you send and answers only what you ask, so it works as a scalpel for specific questions rather than a generic "rate this video" call.

**Prompt rules:** self-contained, no conversation refs (see TOOLS).

**Limitations:**
Analysis is approximate (frames are sampled); long or complex videos may lose fine detail; results depend on chosen model's strengths.

**Models:**

* **gemini-3.5-flash-lite**: Fast and cost-efficient, good for short clips and straightforward scene or object descriptions.
* **gemini-3.8-flash**: Balanced speed and depth; handles longer videos and multimodal reasoning beyond what flash-lite resolves.
* **gemini-4-argon**: Slower and pricier, but the most accurate on motion, defects, detailed temporal breakdowns, and complex analysis prompts.

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "prompt": {
>       "type": "string",
>       "description": "Self-contained description of what to analyze. The analysis model has no conversation context — describe the analysis task completely."
>     },
>     "mediaUrls": {
>       "type": "array",
>       "items": {
>         "type": "string"
>       },
>       "minItems": 1,
>       "description": "CDN URLs of video or audio files to analyze. Supports multiple media in a single call for comparison or batch analysis. Copy URLs verbatim from the merchant message — character-by-character. Do NOT URL-encode, URL-decode, add trailing `=`/`%3D` padding, normalize, or change in any other way. CDN URLs are HMAC-signed; any character change fails the fetch with HTTP 403 \"URL signature mismatch\". On 403 or \"URL signature mismatch\", first diff your URL against the merchant message literally and retry with the exact string if they differ."
>     },
>     "model": {
>       "type": "string",
>       "enum": [
>         "gemini-3.5-flash-lite",
>         "gemini-3.8-flash",
>         "gemini-4-argon"
>       ],
>       "description": "Model to use for analysis"
>     }
>   },
>   "required": [
>     "prompt",
>     "mediaUrls",
>     "model"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## save\_fashion\_model

Save selected images as a new reusable fashion model

Save selected, existing images as a new reusable fashion model in this workspace's Models library. The saved model holds one person's main image and optional pose images for later chats, try-on shots, and product photography. Each call creates a new model record with its own ID.

The images can be uploaded photos or completed generation results. The save keeps their pixels and does not run image generation. A main image is required; pose images and descriptions preserve the views of the same person. The saved main image also appears in Library and in this chat.

The result identifies the saved model. A libraryWarning means the model was saved but its separate Library preview could not be added; that model ID still refers to the saved person.

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "name": {
>       "type": "string",
>       "minLength": 1,
>       "description": "Name of the new reusable model"
>     },
>     "gender": {
>       "type": "string",
>       "enum": [
>         "male",
>         "female"
>       ]
>     },
>     "ageGroup": {
>       "type": "string",
>       "enum": [
>         "adult",
>         "senior",
>         "all-ages"
>       ]
>     },
>     "description": {
>       "type": "string",
>       "description": "Appearance of the person"
>     },
>     "measurements": {
>       "type": "object",
>       "properties": {
>         "chestOrBust": {
>           "type": "number"
>         },
>         "height": {
>           "type": "number"
>         },
>         "hips": {
>           "type": "number"
>         },
>         "waist": {
>           "type": "number"
>         }
>       },
>       "additionalProperties": false,
>       "description": "Body measurements in cm"
>     },
>     "media": {
>       "type": "array",
>       "items": {
>         "type": "object",
>         "properties": {
>           "url": {
>             "type": "string",
>             "format": "uri",
>             "description": "Selected image URL or media:// reference"
>           },
>           "variationType": {
>             "type": "string",
>             "enum": [
>               "main",
>               "pose",
>               "environment"
>             ]
>           },
>           "description": {
>             "type": "string"
>           }
>         },
>         "required": [
>           "url",
>           "variationType"
>         ],
>         "additionalProperties": false
>       },
>       "minItems": 1
>     },
>     "referenceImageUrl": {
>       "type": "string",
>       "format": "uri",
>       "description": "Original reference photo, when available"
>     }
>   },
>   "required": [
>     "name",
>     "gender",
>     "ageGroup",
>     "media"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```

## get\_generation

Reads one generation: running, completed with the tool's output, or failed with its error. A completed image or video is already saved to the media library; its output lists the saved items. A wait that ends while the run still goes can be repeated right away. It only reads and never spends credits.

> **Input schema**
>
> ```json theme={null}
> {
>   "type": "object",
>   "properties": {
>     "generationId": {
>       "type": "string",
>       "minLength": 1,
>       "description": "The generationId a generation tool returned."
>     },
>     "wait": {
>       "type": "boolean",
>       "description": "Wait up to about 50 seconds for a running generation to end. Defaults to false."
>     }
>   },
>   "required": [
>     "generationId"
>   ],
>   "additionalProperties": false,
>   "$schema": "http://json-schema.org/draft-07/schema#"
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.