• About Us
  • Disclaimer
  • Contact Us
  • Privacy Policy
Monday, July 13, 2026
mGrowTech
No Result
View All Result
  • Technology And Software
    • Account Based Marketing
    • Channel Marketing
    • Marketing Automation
      • Al, Analytics and Automation
      • Ad Management
  • Digital Marketing
    • Social Media Management
    • Google Marketing
  • Direct Marketing
    • Brand Management
    • Marketing Attribution and Consulting
  • Mobile Marketing
  • Event Management
  • PR Solutions
  • Technology And Software
    • Account Based Marketing
    • Channel Marketing
    • Marketing Automation
      • Al, Analytics and Automation
      • Ad Management
  • Digital Marketing
    • Social Media Management
    • Google Marketing
  • Direct Marketing
    • Brand Management
    • Marketing Attribution and Consulting
  • Mobile Marketing
  • Event Management
  • PR Solutions
No Result
View All Result
mGrowTech
No Result
View All Result
Home Al, Analytics and Automation

Building a VideoAgent-Style Multi-Agent System: Intent Parsing, Graph Planning, and Tool Routing for Video Editing Tasks

Josh by Josh
July 13, 2026
in Al, Analytics and Automation
0
Building a VideoAgent-Style Multi-Agent System: Intent Parsing, Graph Planning, and Tool Routing for Video Editing Tasks


def tool_shot_planner(instruction, captions):
   """Global-aware storyboard sub-queries from instruction + caption bank."""
   bank = "; ".join(sorted({c["caption"] for c in captions}))
   if llm.available():
       sys_p = ("You are VideoAgent's Shot-Planning Agent. Given the user "
                "instruction and a bank of available scene captions, write "
                f"{CONFIG['max_shots']} short storyboard sub-queries (one line "
                "each) describing the visual content to retrieve, in narrative "
                'order. Respond as JSON list of strings.')
       out = llm.json(sys_p, f"Instruction: {instruction}\nCaptions: {bank}")
       if isinstance(out, list) and out:
           return {"storyboards": [str(x) for x in out][:CONFIG["max_shots"]]}
   m = re.search(r"about ([^.,;!?]+)", instruction.lower())
   subj = m.group(1).strip() if m else "the main subject"
   beats = [f"opening shot introducing {subj}",
            f"a key moment about {subj}",
            f"a detailed close-up related to {subj}",
            f"a concluding shot about {subj}"]
   return {"storyboards": beats[:CONFIG["max_shots"]]}
def _cos(a, b):
   a = np.asarray(a); b = np.asarray(b)
   na, nb = np.linalg.norm(a), np.linalg.norm(b)
   return float(a @ b / (na * nb)) if na and nb else 0.0
def tool_retrieval_agent(index, storyboards):
   """For each storyboard, pick the best scene by max(text,visual) cosine."""
   q_txt = embed_texts(storyboards)
   q_img = q_txt
   chosen = []; used = set()
   for i, sb in enumerate(storyboards):
       best, best_s = None, -1
       for e in index:
           s_t = _cos(q_txt[i], e["text_emb"])
           s_v = _cos(q_img[i], e["img_emb"]) if e["img_emb"] is not None else -1
           score = max(s_t, s_v)
           if e["scene_id"] in used: score -= 0.15
           if score > best_s:
               best_s, best = score, e
       if best is not None:
           used.add(best["scene_id"])
           chosen.append({"storyboard": sb, "scene_id": best["scene_id"],
                          "t": best["t"], "score": round(best_s, 3),
                          "caption": best["caption"]})
   return {"retrieved": chosen}
def tool_trimmer(retrieved, video_path, clip_len=2.0):
   d = wp("clips"); os.makedirs(d, exist_ok=True)
   for f in os.listdir(d): os.remove(os.path.join(d, f))
   meta = ff_probe(video_path); dur = meta["dur"] or 6.0
   clips = []
   for i, r in enumerate(retrieved):
       s = max(0.0, r["t"] - clip_len / 2.0)
       s = min(s, max(0.0, dur - clip_len))
       out = os.path.join(d, f"clip_{i:03d}.mp4")
       _sh([_ff, "-y", "-ss", f"{s:.2f}", "-i", video_path, "-t", f"{clip_len:.2f}",
            "-c:v", "libx264", "-pix_fmt", "yuv420p", "-an",
            "-vf", "scale=480:270:force_original_aspect_ratio=decrease,"
                   "pad=480:270:(ow-iw)/2:(oh-ih)/2",
            "-loglevel", "error", out])
       if os.path.exists(out):
           clips.append(out)
   return {"clips": clips}
def _concat(clips, out):
   lst = wp("concat.txt")
   with open(lst, "w") as f:
       for c in clips:
           f.write(f"file '{os.path.abspath(c)}'\n")
   _sh([_ff, "-y", "-f", "concat", "-safe", "0", "-i", lst,
        "-c:v", "libx264", "-pix_fmt", "yuv420p", "-loglevel", "error", out])
   return os.path.exists(out)
def tool_video_editor(clips):
   out = wp("edited.mp4")
   if clips and _concat(clips, out):
       return {"edited_video": out}
   return {"edited_video": clips[0] if clips else ""}
def tool_beat_sync_editor(rhythm_points, scenes, video_path):
   """Cut the source onto the beat grid, cycling through detected scenes."""
   d = wp("beat"); os.makedirs(d, exist_ok=True)
   for f in os.listdir(d): os.remove(os.path.join(d, f))
   beats = sorted(set([0.0] + list(rhythm_points)))
   segs = [(beats[i], beats[i + 1]) for i in range(len(beats) - 1)
           if beats[i + 1] - beats[i] > 0.15][:12]
   clips = []
   for i, (bs, be) in enumerate(segs):
       sc = scenes[i % len(scenes)]
       src = (sc["start"] + sc["end"]) / 2.0
       dur = min(be - bs, 1.2)
       out = os.path.join(d, f"b_{i:03d}.mp4")
       _sh([_ff, "-y", "-ss", f"{src:.2f}", "-i", video_path, "-t", f"{dur:.2f}",
            "-c:v", "libx264", "-pix_fmt", "yuv420p", "-an",
            "-vf", "scale=480:270", "-loglevel", "error", out])
       if os.path.exists(out): clips.append(out)
   out = wp("beatsync.mp4")
   if clips and _concat(clips, out):
       return {"edited_video": out}
   return {"edited_video": clips[0] if clips else ""}
def _fmt_ts(x):
   return f"{int(x // 60):02d}:{int(x % 60):02d}"
def tool_summarizer(transcript):
   text = transcript.get("text", "").strip()
   if llm.available() and text:
       s = llm.chat("You are VideoAgent's summariser. Summarise the transcript "
                    "in 3-4 sentences, plain and factual.", text)
       if s: return {"summary": s.strip()}
   sents = re.split(r"(?<=[.!?])\s+", text)
   sents = [s for s in sents if len(s.split()) > 3]
   if not sents:
       return {"summary": "(no speech detected to summarise)"}
   picks = [sents[0]] + sorted(sents[1:], key=lambda s: -len(s))[:2]
   return {"summary": " ".join(dict.fromkeys(picks))}
def tool_video_qa(transcript, question):
   segs = transcript.get("segments", []); text = transcript.get("text", "")
   if llm.available() and text:
       ans = llm.chat("You are VideoAgent's VideoQA agent. Answer ONLY from the "
                      "transcript; if unknown, say so. Be concise.",
                      f"Transcript:\n{text}\n\nQuestion: {question}")
       if ans: return {"answer": ans.strip()}
   qtok = set(re.findall(r"[a-z0-9]+", question.lower()))
   scored = []
   for (s, e, t) in segs:
       ov = len(qtok & set(re.findall(r"[a-z0-9]+", t.lower())))
       if ov: scored.append((ov, s, e, t))
   scored.sort(reverse=True)
   if not scored:
       return {"answer": "I couldn't find that in the video's speech."}
   top = scored[:2]
   return {"answer": " ".join(f"[{_fmt_ts(s)}] {t}" for _o, s, _e, t in top)}
def tool_news_overview(transcript, instruction):
   text = transcript.get("text", "").strip()
   if llm.available() and text:
       ov = llm.chat("You are VideoAgent's NewsContentGenerator. Write a short, "
                     "colloquial news overview (<=120 words) of the transcript, "
                     "matching any style hints in the instruction.",
                     f"Instruction: {instruction}\nTranscript: {text}")
       if ov: return {"overview": ov.strip()}
   base = tool_summarizer(transcript)["summary"]
   return {"overview": "Here's the rundown: " + base}
def tool_renderer(edited_video):
   if not edited_video or not os.path.exists(edited_video):
       return {"final_video": ""}
   out = wp("final.mp4")
   r = _sh([_ff, "-y", "-i", edited_video, "-c:v", "libx264", "-pix_fmt",
            "yuv420p", "-movflags", "+faststart", "-loglevel", "error", out])
   return {"final_video": out if os.path.exists(out) else edited_video}
_IMPL = {
   "AudioExtractor": tool_audio_extractor, "Transcriber": tool_transcriber,
   "RhythmDetector": tool_rhythm_detector, "SceneDetector": tool_scene_detector,
   "KeyframeSampler": tool_keyframe_sampler, "Captioner": tool_captioner,
   "CrossModalIndexer": tool_cross_modal_indexer, "ShotPlanner": tool_shot_planner,
   "RetrievalAgent": tool_retrieval_agent, "Trimmer": tool_trimmer,
   "VideoEditor": tool_video_editor, "BeatSyncEditor": tool_beat_sync_editor,
   "Summarizer": tool_summarizer, "VideoQA": tool_video_qa,
   "NewsContentGenerator": tool_news_overview, "Renderer": tool_renderer,
}
for _a, _fn in _IMPL.items():
   AGENTS[_a]["fn"] = _fn
class VideoAgent:
   def __init__(self, video_path):
       self.video = video_path
   def run(self, instruction):
       print("\n" + "═" * 78)
       print("USER INSTRUCTION:", instruction)
       print("═" * 78)
       T, params = analyze_intents(instruction)
       print("[1] Intent Analysis → required intents T:")
       print("    ", ", ".join(sorted(T)))
       if params.get("query"):
           print("     extracted retrieval subject:", repr(params["query"]))
       cand = route_tools(T)
       print(f"[2] Tool Routing → {len(cand)} candidate agents match T:")
       print("    ", ", ".join(sorted(cand)))
       nodes = llm_plan(T, instruction) if llm.available() else None
       origin = "LLM-drafted" if nodes else "naive (terminals only)"
       if nodes is None:
           nodes = naive_plan(T)
       print(f"[4] Graph Construction → {origin} graph "
             f"({len(nodes)} nodes): {sorted(nodes)}")
       print("[5] Textual-Gradient Graph Optimization (τ, κ, χ):")
       nodes, history = optimize_graph(nodes, T, Tmax=CONFIG["opt_rounds"])
       order = topo_order(nodes)
       print(f"    Final agent chain: {' → '.join(order)}")
       print("[6] Graph Execution:")
       seed = {"video_path": self.video, "instruction": instruction,
               "question": params.get("question", instruction),
               "query": params.get("query", "")}
       bb, order = execute_graph(nodes, seed)
       result = {}
       for key in ("answer", "overview", "summary", "final_video", "edited_video"):
           if key in bb and bb[key]:
               result[key] = bb[key]
       print("\n── RESULT " + "─" * 68)
       for k, v in result.items():
           if k in ("final_video", "edited_video"):
               print(f"  {k}: {v}   ({os.path.getsize(v)//1024} KB)"
                     if v and os.path.exists(v) else f"  {k}: (empty)")
           else:
               print(f"  {k}:\n{textwrap.indent(textwrap.fill(str(v), 92), '    ')}")
       return result, nodes, bb



Source_link

READ ALSO

Types, Techniques & Best Practices

New method aims to keep kids safe from illegal AI-generated content | MIT News

Related Posts

Types, Techniques & Best Practices
Al, Analytics and Automation

Types, Techniques & Best Practices

July 13, 2026
New method aims to keep kids safe from illegal AI-generated content | MIT News
Al, Analytics and Automation

New method aims to keep kids safe from illegal AI-generated content | MIT News

July 13, 2026
Meet NeuroVFM: A New Neuroimaging Foundation Model Trained With Vol-JEPA on Uncurated Clinical MRI and CT Volumes
Al, Analytics and Automation

Meet NeuroVFM: A New Neuroimaging Foundation Model Trained With Vol-JEPA on Uncurated Clinical MRI and CT Volumes

July 13, 2026
A Coding Guide to NVIDIA’s Tile-Based GPU Programming: From cuTile and Triton Kernels to Flash Attention
Al, Analytics and Automation

A Coding Guide to NVIDIA’s Tile-Based GPU Programming: From cuTile and Triton Kernels to Flash Attention

July 12, 2026
Mira Murati’s Thinking Machines Lab Makes The Technical Case For Human-Centered AI Built On Customizable Model Weights
Al, Analytics and Automation

Mira Murati’s Thinking Machines Lab Makes The Technical Case For Human-Centered AI Built On Customizable Model Weights

July 12, 2026
Ant Group’s Robbyant Unveils LingBot-VA 2.0: A Causal Video-Action Model Built Natively for Physical AI
Al, Analytics and Automation

Ant Group’s Robbyant Unveils LingBot-VA 2.0: A Causal Video-Action Model Built Natively for Physical AI

July 11, 2026
Next Post
Microsoft Is Making The Windows Search Box More Streamlined And Useful

Microsoft Is Making The Windows Search Box More Streamlined And Useful

POPULAR NEWS

Trump ends trade talks with Canada over a digital services tax

Trump ends trade talks with Canada over a digital services tax

June 28, 2025
15 Trending Songs on TikTok in 2025 (+ How to Use Them)

15 Trending Songs on TikTok in 2025 (+ How to Use Them)

June 18, 2025
Communication Effectiveness Skills For Business Leaders

Communication Effectiveness Skills For Business Leaders

June 10, 2025
App Development Cost in Singapore: Pricing Breakdown & Insights

App Development Cost in Singapore: Pricing Breakdown & Insights

June 22, 2025
Comparing the Top 7 Large Language Models LLMs/Systems for Coding in 2025

Comparing the Top 7 Large Language Models LLMs/Systems for Coding in 2025

November 4, 2025

EDITOR'S PICK

Social media APIs explained (in simple terms)

Social media APIs explained (in simple terms)

May 27, 2026
Anthropic vs. The Pentagon: what enterprises should do

Anthropic vs. The Pentagon: what enterprises should do

February 28, 2026
Top 11 JPG to WEBP Conversion Tools

Top 11 JPG to WEBP Conversion Tools

March 19, 2026
Trump floats government ownership of OpenAI and Anthropic

Trump floats government ownership of OpenAI and Anthropic

June 19, 2026

About

We bring you the best Premium WordPress Themes that perfect for news, magazine, personal blog, etc. Check our landing page for details.

Follow us

Categories

  • Account Based Marketing
  • Ad Management
  • Al, Analytics and Automation
  • Brand Management
  • Channel Marketing
  • Digital Marketing
  • Direct Marketing
  • Event Management
  • Google Marketing
  • Marketing Attribution and Consulting
  • Marketing Automation
  • Mobile Marketing
  • PR Solutions
  • Social Media Management
  • Technology And Software
  • Uncategorized

Recent Posts

  • The Buffer Plugin for TRMNL Is Here, and We’re Giving Some Devices Away
  • When is a Campaign Worth Scaling?
  • Microsoft Is Making The Windows Search Box More Streamlined And Useful
  • Building a VideoAgent-Style Multi-Agent System: Intent Parsing, Graph Planning, and Tool Routing for Video Editing Tasks
  • About Us
  • Disclaimer
  • Contact Us
  • Privacy Policy
No Result
View All Result
  • Technology And Software
    • Account Based Marketing
    • Channel Marketing
    • Marketing Automation
      • Al, Analytics and Automation
      • Ad Management
  • Digital Marketing
    • Social Media Management
    • Google Marketing
  • Direct Marketing
    • Brand Management
    • Marketing Attribution and Consulting
  • Mobile Marketing
  • Event Management
  • PR Solutions