LangChain video generation tool that runs a Sume Format
A LangChain @tool can start a Sume Format run, cap its spend, key it for safe retries, and return a run id the agent checks until the video is ready.

A LangChain video generation tool for Sume is a @tool function that starts a Format run with POST /v1/formats/{handle}/{slug}/runs, passes the agent's brief as input, caps spend with generation_spend_cap_usd, sends a stable Idempotency-Key, and returns the run id, because the run itself takes minutes.
The Sume facts come from Create a run, Runs and results, and Sume basics; the LangChain facts come from its Tools, MCP, and MCP authentication pages, all read on 2026-09-27. Sume has no official LangChain integration: this is a plain HTTPS call from your tool. How to embed AI video generation in your product covers the same API from a TypeScript backend.
Why wrap a Format instead of a model call?
A Format is a saved recipe. For each run, Sume boots a fresh sandbox, loads the recipe, runs the Agent with generation tools, and returns artifacts plus optional structured JSON; Sume's basics page calls it the surface most partners should integrate. Your LangChain agent decides that a video is needed, and the Format decides how to make it. Call your own Format at {handle}/{slug} or a catalog Format at sume/{slug}, with a key that has formats:write. New to Formats? Start with What is a Sume Format?
How do I write the tool?
LangChain's @tool decorator turns a function into a tool. Type hints are required because they define the tool's input schema, and the docstring becomes the description the model reads. These two tools start a run and read it back; pass both to create_agent:
import hashlib, os, requests
from langchain.tools import tool
API = "https://api.sume.com/v1"
AUTH = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
@tool
def start_video_run(brief: str, product_url: str) -> str:
"""Start a Sume video run for a product. Returns a run id; the video takes minutes."""
key = "lc-" + hashlib.sha256(f"{product_url}|{brief}".encode()).hexdigest()[:40]
body = {"input": {"brief": brief, "product_url": product_url}, "generation_spend_cap_usd": 20}
res = requests.post(f"{API}/formats/acme/product-video/runs", json=body,
headers={**AUTH, "Idempotency-Key": key}, timeout=30)
res.raise_for_status()
return res.json()["data"]["id"]
@tool
def get_video_run(run_id: str) -> dict:
"""Read a Sume video run. While status is queued or processing, check again later."""
run = requests.get(f"{API}/format-runs/{run_id}", headers=AUTH, timeout=30).json()["data"]
videos = [a["url"] for a in run["artifacts"] if a["type"] == "video"]
return {"status": run["status"], "videos": videos, "error": run["error"]}What goes in the request body?
The body must name at least one of instruction, input, previous_run_id, or attachments. This tool sends input and lets the Format's default instruction run:
| Field | In this tool | Rule from the docs |
|---|---|---|
input | The agent's brief and the product URL. | A JSON object, at most 64 top-level keys and 2 MiB, written whole to a file. The run is told it is caller-supplied data, not instructions. |
instruction | Omitted. | Up to 8000 characters; about the first 4000 reach the run. Omit it to run the Format's own default instruction. |
generation_spend_cap_usd | 20 | Up to 500. 0 or above 500 is a 400. Omit it to inherit the Format's cap. |
Idempotency-Key header | A hash of the arguments. | Same key and body: 200 with the original run. Same key, different body: 409 idempotency_conflict. Up to 255 characters, scoped to one Format. |
output_schema | Not sent. | Bind a JSON Schema and output comes back in that shape. |
Why derive the Idempotency-Key from the arguments?
The docs say to derive the key from the thing being made, not from the moment of asking. LangChain middleware can retry failed tool calls; when it does, the same arguments give the same key, and Sume answers with the original run instead of a second paid one. A 409 idempotency_key_in_use means a duplicate arrived at the same moment: wait about a second and resend to receive the original run.
How does the agent get the finished video?
The create answers 202 with a receipt. get_video_run reads GET /v1/format-runs/{run_id}: queued and processing mean check again later, and completed, failed, canceled, and skipped are final. artifacts[] lists every durable file the run generated, as media.sume.com URLs that do not expire and are public to anyone holding the URL.
Long-form video is 15 to 30 minutes of work, so back off between checks, doubling the gap up to a minute. expires_at is the deadline past which a run is force-finalized as failed, at most 90 minutes after created_at. Your server can also send communication.webhook_url, and Sume POSTs one signed receipt to it when the run completes or fails; the docs have production integrations keep a read of result_url as the backup. See Format run lifecycle.
Can I use LangChain's MCP adapter instead?
For single generations, yes. LangChain's MCPAdapter loads an MCP server's tools into create_agent, and a FastMCP Client(url, auth=token) sends a bearer token. The langchain.mcp namespace requires langchain[mcp]>=1.4.0 and is in beta. Sume's hosted MCP tools wrap selected API capabilities, such as generate_video and jobs_wait, and the documented tool inventory has no Format-run tool, so a Format run still goes through the Format API above. Sume's basics page also says hosted MCP still works but is not part of the primary path today.
Sources
Related posts
More in Integrations
- LlamaIndex image generation tool with the Sume Image API
Wrap POST /v1/images in a LlamaIndex FunctionTool: send sume/auto and a prompt, return URLs on a 200, and hand back the job id on a 202.
- Make.com AI video scenario with Sume: HTTP and a webhook
Split a Make.com AI video scenario in two: Make a request starts a Sume run; a custom webhook takes the signed result and checks it with sha256().
- Mastra MCP client: connect an agent to Sume's hosted MCP
Connect a Mastra agent to Sume's hosted MCP server with MCPClient: an API-key header in requestInit, a tool allow-list, and approval for paid calls.
- n8n AI video workflow: resume a Wait node on a Sume webhook
Start a Sume Format run from an n8n HTTP Request node, pass the Wait node's resume URL as webhook_url, then read the finished run with your key.
Written by Sume