Script tools
Everything that produces or changes a script. In practice you call
generate_script and then edit_script until the words are right; the other
three are for reading state and for the cases where you want to be explicit.
generate_script
Start generating a social-video script, either from existing reporting (an article URL, pasted text, or an uploaded document) or, with `brief`, from a story the user describes and wants written for them. When the user has ALREADY WRITTEN the narration and wants it used as is, pass it as `script_text` instead: it is saved word for word, nothing is generated, and the returned script_id is ready for create_video_from_script immediately. Call this ONCE per story: it runs in the background and returns a script_id immediately; poll with get_generation_status and revise with edit_script. Calling it again for a story you already started returns the SAME script rather than writing a second one. Style settings omitted here fall back to the user's saved defaults. Documents uploaded in this conversation are attached automatically; you do not need to pass their URLs.
| Parameter | Type | Description |
|---|---|---|
source | string | Article URL or the full article text. Optional when the user uploaded a document to work from, or when you're passing a brief instead. |
brief | string | Use when there is NO article and the user wants the story written for them (e.g. announcing a partnership, a product, an event). Write the brief yourself from what the user told you: what the story is, who/what it names, the angle, the audience, and anything they want it to end on. Everything factual in it must come from the user. Confirm the scope with them first and never invent facts, figures, or quotes. Ignored if `source` is provided. |
script_text | string | The user's own finished narration, to be spoken exactly as written. Saved verbatim with no rewriting and no generation; timing marks such as [1.9] or (0:03) are stripped so they are not read aloud. Use whenever the user pasted the words and wants THOSE words; never paraphrase them into a brief. Takes precedence over source and brief. (To lay narration over a video the user attached, use create_video_from_upload with narration_lines instead.) |
title | string | Optional headline for the script. |
force_new | boolean | Write a second, separate script for a story this conversation already covered. Only when the user explicitly wants a fresh take from scratch. To change an existing script, use edit_script. |
article_file_url | string | URL of an uploaded document (PDF/DOCX/TXT) to use as the article itself. Chat uploads are attached automatically; pass this only over MCP, or to override which upload is the primary source. |
evidence_file_urls | string[] | URLs of supporting documents the writer should reference alongside the article. |
duration_seconds | number | Target video length in seconds (10–600). Omit to use the user's defaults. |
tone | string | Overall tone, e.g. professional, conversational, dramatic, playful. |
speaking_styles | string[] | Speaking styles, e.g. unbiased, professional, educational, conversational, serious, playful, casual, dramatic. |
style_description | string | Freeform description of the desired style/voice. |
story_focus | string | Story focus: retelling, strengthen, or summary. |
cta | string | Call to action to end the script with. |
custom_instructions | string | High-priority freeform instructions injected into the script prompt. |
Returns: Generation runs detached, so `status` here is where the job STARTED, not where it ended. Poll get_generation_status. A `script_text` call (mode "verbatim") generates nothing and returns already completed.
| Field | Type | Description |
|---|---|---|
card always | "script" | What kind of result this is. |
script_id always | string | Pass this to get_script, edit_script and create_video_from_script. |
status always | string | Lifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check. |
id | string | The same value as script_id, under the row's own column name. |
title | string | null | The headline. Null until the writer has produced one. |
current_stage | string | null | The step now running, while it is still being written. |
progress | number | null | Percent complete, 0-100. |
error_message | string | null | Why it failed, when it did. |
has_script_text | boolean | null | Whether any text has been written yet. False on a script that is still generating. |
script_text | string | null | The script itself, once it exists. |
links | object | Absolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered. |
note | string | Guidance for you, not for the user. Act on it; do not read it out. |
source_key | string | Identifies the story within this conversation, so a second call returns the same script. |
mode | string | "source" when written from reporting, "prompt" when drafted from a brief, "verbatim" when the user's own words were saved as written. |
brief | string | null | The brief this was commissioned to, echoed back so the user can correct the scope. |
reused | boolean | True when this story already had a script in this conversation and it was handed back. |
Writing without an article
Section titled “Writing without an article”generate_script takes either a source (a URL, or pasted text) or a
brief describing the story you want. With a brief there is no article at all:
you supply the facts and the angle, and Editory drafts from them.
{ "brief": "Announce our partnership with Northwind. Mention that it starts in March, and point viewers at their Instagram @northwind.", "duration_seconds": 45, "tone": "upbeat"}Everything in the brief is treated as fact, and the model is instructed not to invent specifics beyond it: no statistics, quotes, dates or outcomes you didn’t give it. If you want those in the script, put them in the brief.
edit_script
Ask the script-editing agent to revise a script conversationally (tone, length, structure, hook, CTA). Returns the updated script and persists it. Use for edits described in natural language; use update_script for verbatim replacement text you already have.
| Parameter | Type | Description |
|---|---|---|
script_id required | string | |
instruction required | string | The edit request, e.g. "make the hook punchier and cut it to 45 seconds". |
Returns
| Field | Type | Description |
|---|---|---|
card always | "script" | What kind of result this is. |
script_id always | string | Pass this to get_script, edit_script and create_video_from_script. |
status always | string | Lifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check. |
script_text always | string | null | The script itself, once it exists. |
id | string | The same value as script_id, under the row's own column name. |
title | string | null | The headline. Null until the writer has produced one. |
current_stage | string | null | The step now running, while it is still being written. |
progress | number | null | Percent complete, 0-100. |
error_message | string | null | Why it failed, when it did. |
has_script_text | boolean | null | Whether any text has been written yet. False on a script that is still generating. |
links | object | Absolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered. |
note | string | Guidance for you, not for the user. Act on it; do not read it out. |
editor_notes | string | null | The editing agent's own account of what it changed. |
Revisions are conversational and cumulative. Each one is kept, so a later instruction can refer back to an earlier state.
{ "script_id": "…", "instruction": "Cut the third paragraph and make the ending land harder." }get_script
Fetch a script's status, text, and the photos scraped from its source article. Use after generate_script completes, or to review/edit an existing script.
| Parameter | Type | Description |
|---|---|---|
script_id required | string |
Returns
| Field | Type | Description |
|---|---|---|
card always | "script" | What kind of result this is. |
script_id always | string | Pass this to get_script, edit_script and create_video_from_script. |
status always | string | Lifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check. |
id | string | The same value as script_id, under the row's own column name. |
title | string | null | The headline. Null until the writer has produced one. |
current_stage | string | null | The step now running, while it is still being written. |
progress | number | null | Percent complete, 0-100. |
error_message | string | null | Why it failed, when it did. |
has_script_text | boolean | null | Whether any text has been written yet. False on a script that is still generating. |
script_text | string | null | The script itself, once it exists. |
links | object | Absolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered. |
note | string | Guidance for you, not for the user. Act on it; do not read it out. |
article_image_count | number | Photos from the source article currently switched on for b-roll. |
update_script
Replace a script's text verbatim. Use when you (or the user) already have the exact final text; use edit_script for natural-language revisions.
| Parameter | Type | Description |
|---|---|---|
script_id required | string | |
script_text required | string |
Returns
| Field | Type | Description |
|---|---|---|
card always | "script" | What kind of result this is. |
script_id always | string | Pass this to get_script, edit_script and create_video_from_script. |
status always | string | Lifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check. |
script_text always | string | null | The script itself, once it exists. |
id | string | The same value as script_id, under the row's own column name. |
title | string | null | The headline. Null until the writer has produced one. |
current_stage | string | null | The step now running, while it is still being written. |
progress | number | null | Percent complete, 0-100. |
error_message | string | null | Why it failed, when it did. |
has_script_text | boolean | null | Whether any text has been written yet. False on a script that is still generating. |
links | object | Absolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered. |
note | string | Guidance for you, not for the user. Act on it; do not read it out. |
scrape_article
Fetch and extract an article from a URL (title, text, authors, and the photos published with it). Use to preview/confirm an article before generating a script, or to show the user what images the story comes with. generate_script scrapes internally (it keeps the same photos), so you do NOT need to call this first unless you want to show the user what was found or answer questions about the article.
| Parameter | Type | Description |
|---|---|---|
url required | string | The article URL to scrape. |
Returns
| Field | Type | Description |
|---|---|---|
card always | "status" | What kind of result this is. |
word_count always | number | Length of the extracted body text. |
image_count always | number | How many photos were published with the story. |
images always | object[] | Up to 12 of them. The hero is used as b-roll by default; the rest start switched off. |
title | string | null | The article's headline. |
authors | array | null | Bylines, where the page declares any. |
preview | string | null | The first ~600 characters of the article. |
url | string | The article URL that was scraped. |
note | string | Guidance for you, not for the user. Act on it; do not read it out. |
You rarely need this: generate_script scrapes a URL itself. It’s useful when
you want to read the article first and decide whether it’s worth a script, or to
pull the headline and photos out for something else.