describe_cast_member
shallowpro.aicut/aicut · Verify this server
CHANGES ONE cast member into a different character: you pass a new one-line visual description, aicut rewrites that member's stored look from it, and draws ONE new portrait. Costs ONE image generation - the rest of the roster is untouched and not re-charged. THIS IS THE TOOL FOR 'make the husband smaller and a white strawberry'. It is NOT `regenerate_cast_portrait`, which draws the SAME character again from its existing look, and it is NOT a reason to call `generate_cast` - a fresh draft re-authors every member and buys every portrait again, which is the expensive mistake this tool exists to stop. One member changed, one portrait charged. WHEN: the user looked at the cast and wants a member to BE something else. `character_id` is that member's `id` from `generate_cast_portraits` or `list_characters` (kind `cast_member`) - the FREE `generate_cast` draft has no library ids at all, so re-draft that one instead (free) while it is still a draft. THE DESCRIPTION IS ONE LINE OF PLAIN VISUAL ENGLISH, in the user's own terms - what the character looks like now, WHOLE, not a diff. Write 'a small white strawberry man in a rumpled shirt', never 'the same but smaller and white': the stored look is rebuilt from this sentence alone and anything you leave out is gone. Fold what the user said into what the member already was, and keep it under about 500 characters. DO NOT RECITE THE LINE YOU ARE SENDING. It is internal - the wording aicut stores to draw the picture with - and reading it out to the user is the same mistake as pasting a prompt at them: they asked for a character to change, not for a description to approve. Apply the change and show them the RESULT. (Only if the user's ask is genuinely ambiguous about WHAT the character now is - not about how you will word it - ask them the one question that resolves it, in their words, before you spend.) IT PERSISTS, WHICH IS THE POINT: every future episode that casts this member casts the NEW character. The member's world stays what it was (it cannot be moved into a different visual world), and its name, personality and voice are untouched - only the look changes. THE CARD: this call has ALREADY put the aicut cast card in front of the user with this ONE member on it - the new face fills itself in as it generates, and the card carries the same download and the same review actions the full roster's card does. So do NOT call `show_generation` on the portrait, and do NOT poll: no `get_image` or `wait_for_generation` loops. ONE read is not a loop - if the user asks how it is doing, read `portrait_image_id` once with `get_image` and say what it says. Say one short line (what the member now is, in the user's own words) and stop. IF YOU CANNOT RENDER AN AICUT CARD - a terminal, a plain SDK client, anything that did not negotiate the MCP Apps UI extension - no card appeared, so poll `portrait_image_id` with `wait_for_generation` (media `image`) and give the user the portrait url yourself. aicut cannot see which clients render cards and sends the same answer to all of them. AFTER: returns the member with its new `description`, `portrait_image_id` and `portrait_status: "generating"`. Repeat if they want it different again; each repeat is one more portrait's price, which you state each time. REPORT WHAT CHANGED, VERBATIM. The answer carries `changed` - which can be `[]` - and a `report` sentence. RELAY THE `report` AS IT IS WRITTEN. `changed: []` means this member ALREADY had exactly this description, so nothing about the character moved and a portrait was bought anyway: the `description` in the response is the one you sent, not evidence that anything changed. Send a genuinely different description or tell the user it is already that. IF THE PICTURE FAILS OR THE ACCOUNT RUNS OUT (402) THE DESCRIPTION HAS ALREADY CHANGED: the member is the new character and is wearing its old portrait. Say that plainly - it is not lost work, and `regenerate_cast_portrait` draws the new look for one portrait's price. Do not re-send this tool to 'fix' it, which would re-describe an already-correct member and buy a second picture. REFUSALS you act on: 404 = unknown member, or not this account's. 400 `invalid_request` = an empty/too-long description, an unavailable `image_model`, or a description aicut could not build a look from (the message says which) - reword it with the user rather than retrying the same text. 402 = not enough tokens. 503 `portrait_unavailable` = transient, try again. 503 `portrait_not_attached` = the portrait WAS generated and CHARGED but did not attach; say so and call this member's `regenerate_cast_portrait`, not this tool. COST: one standard image generation, charged at `image_model` (or the platform default portrait model when you pass none) - the same number `regenerate_cast_portrait` costs for the same model. `estimate_only: true` prices it without spending and WITHOUT re-describing anything, so a quote is always free and never changes the member. State the figure before you ask for the go, every time. SPEND ETIQUETTE (the money grammar): in the webapp the priced button is the user's own finger; in chat YOUR tool call is not - so state the price IN THE SAME MESSAGE as the ask, and the user's explicit go is the button press. Never charge on inference: quoting is not asking, and after a price you wait for the yes. THIS APPLIES TO EVERY TOOL CARRYING THIS NOTE, including this one. A GO IS SCOPED TO ONE PURCHASE, AND IT MUST BE UNAMBIGUOUS. The user's instruction has to NAME the thing you are about to buy, or refer to it so plainly that it cannot mean anything else. A BARE AFFIRMATION - 'go', 'yes', 'ok', 'do it', 'just do it', 'sure' - counts ONLY when ALL THREE of these hold: the message immediately before it was YOUR priced ask for THAT EXACT action, nothing else was raised in between, and NOTHING THE USER ASKED FOR EARLIER IS STILL OUTSTANDING. That last one is the trap the others miss: if the user's OWN previous turn asked for something else - a refusal, a different scene, an edit, a redraw, a question - their 'just do it' may be answering THAT, and it is AMBIGUOUS even when your priced ask happens to be the last thing said in the thread. An ambiguous affirmation is not a go: ask WHICH one they mean and state that price again. WHEN IN DOUBT ABOUT WHAT A 'GO' REFERS TO, ASK. A wrong guess spends the user's money on something they never asked for, and nothing on this surface can undo it or give it back - asking costs one sentence. An episode's STAGES - cast portraits, episode create, fire, render - are each their own priced ask. A STANDING GO IS NOT UNLIMITED: 'just make it' or 'go ahead with the whole episode' authorizes the stages you PRICED IN THAT SAME MESSAGE, in the order you named them, and nothing beyond them - so do not re-ask per stage while it holds, and do not stretch it over a stage whose price the user never saw. IT EXPIRES THE MOMENT THE USER RAISES ANYTHING ELSE - a change, a question, a refusal, a redraw, a new idea - and after that the next stage needs its own priced ask. ONE STAGE IS NEVER COVERED BY A STANDING GO AT ALL: the FIRE (`fire_story_video`) is irreversible and the biggest single charge in the episode, so it always takes a go that NAMES firing, whatever was said earlier - see that tool's own note. A REDRAW IS NOT A STAGE: `regenerate_story_frame` and `regenerate_cast_portrait` are extra spends the user asks for one at a time, so state that price every time, even under a standing go. A standing go never carries to a different episode, and never to `generate_video`, `generate_image` or `generate_audio` - each of those is its own ask. ACCOUNT FOR YOUR OWN CALLS: if the user says something happened that you did not intend - a charge they did not expect, a step they did not ask for - RE-READ YOUR OWN TOOL CALLS IN THIS CONVERSATION before you answer, and tell them plainly which tools you called and when. NEVER SPECULATE ABOUT A CAUSE YOU CANNOT OBSERVE: not a button on an aicut card, not the user's own click, not their client. The aicut cards CANNOT SPEND - the only tools they ever call are the reads (`get_video` / `get_image` / `get_audio`), and their buttons either save a file or send a VISIBLE user turn into the chat - none of them calls a spending tool - so saying a card might have generated or charged something is false, not a hedge. (If a spend followed one of those visible turns, it was still YOUR call, and the honest answer names it.) If your call history disagrees with what you told the user, say what you actually called and let them correct you; do not invent an explanation that makes the two agree. IDEMPOTENCY: `idempotency_key` is optional and makes a retry safe. Set it on the FIRST call, not only on a retry - the job is addressed by the key, so a key added afterwards cannot find a job that was created without one. Reusing a key REPLAYS the job that key already created and returns it unchanged - even if you send a different prompt or different settings, and even after that job has finished. A key is therefore spent permanently. Do NOT reuse one to make another generation: two deliberate generations are two jobs and need two different keys (or none). ONE EXCEPTION, on `render_story_video`: replaying a key whose render FAILED answers 409 `render_failed` rather than replaying the failure, because a spent key stays spent - retry that one with a NEW key or with none. A KEY IS NOT SCOPED TO A TOOL: it addresses a job on the whole account, so reusing the key you gave `generate_video` on `generate_story_video` replays that first video instead of starting an episode. One key, one thing you made. (`render_story_video` is the one door that namespaces its own, which is why an episode's key can be reused on its render without colliding - but there is no reason to reuse it there either.) Never derive the key from the request body. You do NOT need to pass one to be safe against a duplicated delivery: aicut already derives a per-call key server-side, so a retry the transport makes on its own replays rather than charging twice. Pass your own only when YOU want to retry a call whose answer you never saw. OUTPUT: this returns JSON for you to read. When you report back to the user, give them the media URL plus a one-line summary. Do not paste the raw JSON, job ids, or internal field names into the conversation.
1 trials · measured 27 days ago
describe_cast_member scores 100.0/100 on Vouch's measured behaviour index, from 1 real invocation trials against pro.aicut/aicut, measured 11 Sept 2026 under methodology v0.2.0. Every measured component scored 100.
Component breakdown
| Component | Weight | Value |
|---|---|---|
| Reliability | 35% | not applicable |
| Schema integrity | 25% | 100.0 |
| Failure behaviour | 15% | not applicable |
| Latency | 15% | not applicable |
| Concurrency | 10% | not applicable |
Tool details
- Transport
- remote
- Credential class
- gated
- Input schema
- not declared
- Output schema
- not declared
- Side-effect classification
- unclassified
Score history
| Day | Score | Tier | Methodology |
|---|---|---|---|
| 2026-09-11 | 100.0 | shallow | v0.2.0 |
Probe evidence
| Probe | Outcomes |
|---|---|
| schema_integrity | pass: 1 |
Raw request/response logs are not archived yet — the outcome counts above are drawn directly from every recorded trial.
Embed this score
Available for every tool, scored or not — not a verification perk. Always links back to this page.
[](https://vouch.tools/tools/cbdf3ee0-5e35-43a2-96ed-8b921ace8aa7)