Source agents
Scout, prepare, transcripts, deterministic generation, and generate specialist.
Source agents operate on media before or alongside timeline planning. They do not change the live timeline.
source.scout_agent.brief(...)
brief = source.scout_agent.brief(prompt, tools=(), name="source-brief")The scout probes the real media, builds a visual inventory, and produces a
grounded, asset-agnostic SourceBrief v2. It can request deeper motion/segment
analysis when the task calls for it. Transcript import and computation are
available only when this call includes tools=[transcribe].
The brief contains schemaVersion: 2 and selections[]. Each selection names a
manifest source, its matching kind (video, audio, image, graphic, or
text), a free-form editorial role, and an optional span for video/audio.
Whole temporal assets use span: null; image, graphic, and text selections
always use span: null. Roles such as opener, montage, ender, b_roll,
narration, audio_bed, title_card, and overlay are useful conventions,
not required values.
A useful scout prompt says:
- what each important file is for;
- which speech source should be transcribed;
- the roles to find, such as hook, establishing shot, proof, reaction, detail, transition, or closing image;
- selection criteria such as camera stability, subject visibility, continuity, and unwanted content;
- whether source order matters.
Do not ask the scout to design titles or build the final timeline. Its job is to find and explain usable evidence in the source material.
Agent-directed transcripts
Transcript work is opt-in for each specialist call. Import the agent-only capability descriptor and grant it to the scout, storyboard, or author that needs transcript evidence:
from scrambo.tools import transcribe
brief = source.scout_agent.brief(
"Find the strongest explanation in interview_maya.mov and the B-roll that "
"supports it.",
tools=[transcribe],
name="interview-brief",
)The grant is fail-closed and per call. It does not persist to later agents, and
it is not supported by generate, prepare, graphics, sound, titles, or captions.
Pass tools=[transcribe] again when storyboard or author independently needs to
import, compute, or inspect transcript evidence. Calling transcribe(...)
directly raises an error; the specialist decides which evidence is relevant and
the host performs the import or transcription.
Defaults are ElevenLabs Scribe v2, automatic language detection, speaker diarization, and mandatory word timestamps. Configure the descriptor before the agent call when the defaults are not appropriate:
# Pin a language or disable diarization while keeping ElevenLabs Scribe v2.
transcribe.set_config(language="en", diarize=False)
# Select the explicit WhisperX fallback and its default model. Other settings
# retain their current values unless reset explicitly.
transcribe.set_config(provider="whisperx", language=None, diarize=True)Configuration applies to subsequent grants in the current Python process.
Supported keys are provider, model, language, and diarize; word
timestamps cannot be disabled. Set every non-default choice before making the
agent call so the effective configuration is explicit in that task's cache
identity.
Top-level .json files supplied beside media are uploaded as untrusted
transcript candidates. They are not automatically associated with a source and
are never treated as transcripts merely because of their filename. An enabled
agent first inspects the candidates and may ask the host to validate and import
one; only if no candidate fits should it compute a transcript for selected audio
or video. The importer accepts Scrambo word-timed segments[].words[] JSON and
native ElevenLabs words[] JSON, normalizes the selected evidence, preserves
the uploaded raw payload, and publishes the working transcript used downstream.
Grant transcript access at the earliest specialist that needs it. For example, grant it to scout when quotes determine source selection, to storyboard when word timing affects narrative structure, or to a direct author when there is no separate scout/storyboard pass. The caption specialist consumes the working transcript established upstream; it cannot create one itself.
source.prepare_agent.prepare(...)
prepared = source.prepare_agent.prepare(
"Create H.264/AAC working copies of the three camera originals, extract a "
"clean WAV from interview.mov, and concatenate exterior_part_1.mov and "
"exterior_part_2.mov in that order. Preserve the originals.",
name="editor-ready-media",
)Preparation creates mechanical source derivatives and registers them so later agents can use them like other media. Supported work includes transcoding, trimming, concatenating, muxing, extracting audio, and extracting frames.
Keep preparation requests mechanical and explicit. Use the scout or storyboard for creative selects, and the author for timeline construction. A preparation request should name inputs, desired outputs, formats, ordering, and technical constraints without asking for a montage or an edit.
For a planned edit, scout the originals first, run preparation, and then tell the storyboard to prefer matching prepared assets. This preserves an editorial brief grounded in the camera originals while giving the author editor-friendly media.
Deterministic generation tools
Import deterministic generation separately from the source-agent facade:
from scrambo.tools.genAI import img2video, voiceoverBoth tools write media into source/, register it in manifest.sources[], and
return a normal Artifact. Matching requests reuse content-addressed outputs.
Each direct call defaults to a $5 spend cap, and cached work costs nothing.
These calls do not require editor.start() unless the program proceeds to
timeline editing.
In the thin cloud SDK, vendor credentials stay on the Scrambo server. Local
.json, .txt, and .md control files are read by the SDK and canonicalized
before submission. Every first/last frame must have been part of the initial
editor.open(input=...) upload; cloud generation does not late-upload frames in
this MVP. If a generation control .json is also top-level inside the initial
input directory, it is uploaded as a transcript candidate as well; keep control
files outside that directory when they are not intended as run evidence.
Create voiceover from literal text or a .txt/.md file:
voice = voiceover(
"A quieter way to start the day.",
voice="rachel",
name="brand-voiceover",
budget_usd=5.0,
)Create one or more motion clips from text and optional first/last images:
footage = img2video(
[
{
"name": "coffee-pour",
"seed_image": "./stills/cup.jpg",
"prompt": "Slow macro push-in as coffee pours into the ceramic cup; "
"preserve the cup design and morning window light.",
"duration": 4.0,
},
{
"name": "pack-shot",
"seed_image": "./stills/package.jpg",
"last_frame": "./stills/logo-lockup.jpg",
"prompt": "Controlled tabletop dolly ending on the supplied logo frame; "
"keep all packaging text unchanged.",
"duration": 4.0,
},
],
resolution="720p",
aspect_ratio="16:9",
name="generated-product-shots",
)img2video accepts one shot dictionary, a list, or a compatible prompts.json
path. Every shot requires a first-frame image; an optional last frame requests
interpolation. Its call-level arguments include duration, vendor,
resolution, aspect_ratio, name, and budget_usd; a per-shot duration
overrides the default. Text-to-video is intentionally outside this MVP.
voiceover accepts literal script text or a .txt/.md path and requires a
voice. Its optional arguments are vendor, name, and budget_usd.
Unknown pricing is rejected before vendor submission. If a cached artifact points to a missing output, Scrambo runs the deterministic kernel again; a surviving content-addressed file is adopted and re-registered without spending.
source.generate_agent.create(...)
Use the specialist when the prompt should decide what to generate:
from scrambo import source, timeline
from scrambo.tools.genAI import img2video, voiceover
brief = source.generate_agent.create(
"Create a narrated vertical tour from the listing photos.",
tools=[img2video, voiceover],
budget_usd=5.0,
max_calls=4,
name="generated-assets",
)
plan = timeline.storyboard_agent.plan(brief, "Build a 30-second tour")
# Equivalent run-directory handoff; consumes the accepted source_brief.json:
plan = timeline.storyboard_agent.plan("Build a 30-second tour")The specialist receives only the registered Scrambo tool callables explicitly
listed in tools; arbitrary Python functions are rejected. An empty tool list
fails before the provider is invoked. The specialist inspects seed images,
creates only requested assets, inspects generated video contact sheets, and
writes one complete SourceBrief v2. It does not create a generation-specific
root contract.
budget_usd is cumulative across uncached vendor work in that create() turn.
max_calls is the cumulative requested-output cap, not an LLM iteration count:
a batch of three video requests consumes three, and a cached output still
consumes one slot while spending zero dollars. The default is four outputs.
Budget, output-cap, unknown-price, and generation-tool errors fail the task.
There is no automatic specialist revision after the paid turn; successful
outputs remain content-addressed and can be adopted free on a rerun.
The portable cloud SDK exposes the same registered tool identities and sends only their stable allowlisted IDs to the server.