Skip to content

video/research-to-shorts

Research → Hooks → AI Shorts — end-to-end pipeline.

Category: video
Source: workflows/video/research_to_shorts.py

FieldTypeDefaultDescription
bgm_volumenumber0.15Background music volume (0.0-1.0)
duration_secsinteger60Target video duration in seconds
moodstring""Mood/tone for the video
platformstring"tiktok"Target platform
presenter_lookstring""Actor appearance description
querystring""Alias for topic (either works)
regenerateobjectWhen set, this run is a regeneration. Workflows may read direction / keep / extra_instructions to modulate prompts; the engine persists parent_run_id and parent_variant_index as run lineage columns.
topicstring""Topic to research and produce a video about
variantsinteger1Number of independent variant executions (1–10). When > 1, the engine runs the workflow N times with different sampling, producing N outputs.
visual_stylestring""Visual style for b-roll generation
FieldTypeDefaultDescription
audio_asset_idobjectFabric asset ID of the TTS audio
kindobjectVariant card shape: video / carousel / image / text. Surfaced on the per-variant entry of the run-output API and used by gallery UIs to pick the right layout.
scriptstring""The narration script text
tagsstring[]Hashtags/keywords
titlestring""Generated title
video_asset_idobjectFabric asset ID of the generated video
normalize_input → plan_research → search_web → read_webpages → research_youtube → fetch_rss_feeds → search_reddit → merge_research → synthesize_research → format_report → bridge_research_to_hooks → generate_hook_ideas → select_hook → generate_script → generate_ai_actor → generate_voiceover → generate_all_broll → generate_bgm → merge_generation → generate_talking_heads → lipsync_talking_heads → mix_audio → compose_timeline → prepare_for_post_processing → burn_subtitles → burn_hook_overlay_safe → generate_effect_filters → apply_effects → add_outro_fade → collect_final_output
TaskDescription
normalize_inputMap topicquery so callers can use either name.
plan_researchValidate input and decide which sources to activate.
search_webSearch the web via Exa (semantic search) or Jina Search (free fallback).
read_webpagesRead top web results as clean markdown via Jina Reader (free, no API key).
research_youtubeSearch YouTube for relevant videos and extract metadata + transcript excerpts.
fetch_rss_feedsParse RSS/Atom feeds for latest content.
search_redditSearch Reddit via shared Reddit client (old.reddit.com, UA rotation, retry).
merge_researchJoin function — merge parallel branch outputs into a unified context.
synthesize_researchAnalyze all collected sources with Gemini and produce a structured synthesis.
format_reportStructure the final output, stripping internal keys.
bridge_research_to_hooksTransform deep-research output into hook-generation input.
generate_hook_ideasGenerate hook ideas — delegates to SDK stage (70/20/10 strategy, PromptExtension).
select_hookPick the strongest hook and prepare input for video script generation.
generate_scriptGenerate a viral video script, optionally grounded in research findings.
generate_ai_actorGenerate AI actor portrait — delegates to SDK stage.
generate_voiceoverGenerate TTS voiceover — delegates to SDK stage.
generate_all_brollGenerate all b-roll clips — delegates to SDK stage.
generate_bgmGenerate background music — delegates to SDK stage.
merge_generationMerge parallel generation branches into a single context.
generate_talking_headsGenerate talking heads — delegates to SDK stage.
lipsync_talking_headsLip-sync talking heads — delegates to SDK stage.
mix_audioMix voiceover + BGM — delegates to SDK stage.
compose_timelineAssemble video timeline — delegates to SDK stage.
prepare_for_post_processingMap keys for post-processing — delegates to SDK stage.
burn_subtitlesBurn word-level subtitles — delegates to SDK stage.
burn_hook_overlay_safeBurn hook text overlay — delegates to SDK stage.
generate_effect_filtersUse Gemini to suggest FFmpeg filters based on content type.
apply_effectsApply AI-generated FFmpeg filters to the video.
add_outro_fadeAdd a fade-to-black outro at the end of the video.
collect_final_outputCollect final output — delegates to SDK stage.

Save the YAML below as my-run.yaml, edit the values, and run with the CLI or POST it to the API. Required fields are uncommented; optional knobs are documented above the input: block — copy any line under input: and uncomment to set.

workflow: video/research-to-shorts
# Optional fields — copy any line(s) under `input:` and uncomment to set:
# Background music volume (0.0-1.0)
# bgm_volume: 0.15
#
# Target video duration in seconds
# duration_secs: 60
#
# Mood/tone for the video
# mood: ""
#
# Target platform
# platform: tiktok
#
# Actor appearance description
# presenter_look: ""
#
# Alias for topic (either works)
# query: ""
#
# Topic to research and produce a video about
# topic: ""
#
# Visual style for b-roll generation
# visual_style: ""
#
input: {}

Run it locally:

Terminal window
fab-workflow --from-file my-run.yaml

Or submit over the wire — the same file is the request body:

Terminal window
curl -X POST 'https://gofabric.dev/v1/workflows/runs?name=video/research-to-shorts' \
-H 'Authorization: Bearer fab_xxx' \
-H 'content-type: application/yaml' \
--data-binary @my-run.yaml

Every workflow also accepts the universal WorkflowInput fields — variants (1–10 fan-out) and regenerate (creative-direction hints with run lineage). See Run-specs (YAML / TOML / JSON) for the full top-level shape (metadata, priority, bundle, parent, etc.).

  • Task merge_research has no Pydantic types — contract is opaque to consumers.
  • Task generate_hook_ideas has no Pydantic types — contract is opaque to consumers.
  • Task generate_ai_actor has no Pydantic types — contract is opaque to consumers.
  • Task generate_voiceover has no Pydantic types — contract is opaque to consumers.
  • Task generate_all_broll has no Pydantic types — contract is opaque to consumers.
  • Task generate_bgm has no Pydantic types — contract is opaque to consumers.
  • Task merge_generation has no Pydantic types — contract is opaque to consumers.
  • Task generate_talking_heads has no Pydantic types — contract is opaque to consumers.
  • Task lipsync_talking_heads has no Pydantic types — contract is opaque to consumers.
  • Task mix_audio has no Pydantic types — contract is opaque to consumers.
  • Task prepare_for_post_processing has no Pydantic types — contract is opaque to consumers.
  • Task burn_subtitles has no Pydantic types — contract is opaque to consumers.
  • Task burn_hook_overlay_safe has no Pydantic types — contract is opaque to consumers.
  • Task collect_final_output has no Pydantic types — contract is opaque to consumers.