linCut turns a creative brief into a finished MP4 using six cooperating agents, each with its own responsibility and built-in retry logic.
linCut — Lin's AI Video Studio
Brief (text)
│
▼
Planner Agent ──► Writer Agent
│
├── Footage Agent (Hailuo clips, per-segment retry)
├── Narrator Agent (TTS)
└── Composer Agent (optional score, soft-fail)
│
▼
Assembler Agent (ffmpeg mux + captions)
│
▼
deliverable.mp4
Footage, Narrator, and Composer run in parallel after the Writer finishes. The 60s option generates 10 clips × 6s and stitches them into one minute.
| Agent | Role | Retry |
|---|---|---|
| Planner | Brief → blueprint JSON | 2× on LLM / parse errors |
| Writer | Blueprint → render specs | 2× on LLM / parse errors |
| Footage | Hailuo clip per segment | 2× per clip + parallel pool |
| Narrator | TTS voiceover per segment | 2× per track |
| Composer | Background score | 2×, optional — skips on failure |
| Assembler | ffmpeg mux + captions | 1× |
All agents inherit from BaseAgent (backend/agents/base.py) which provides invoke() with configurable retries and SSE progress events.
End-to-end quality evaluation runs the full agent pipeline against MiniMax + ffmpeg (costs API credits and time).
pip install -r backend/requirements.txt
cp .env.example .env # MINIMAX_API_KEY required
brew install ffmpeg # macOS
# Daily regression — 2 × 12s cases (~8–15 min depending on Hailuo queue)
python -m backend.eval.run_eval
# Include 60s / 10-clip case (expensive)
python -m backend.eval.run_eval --tag quick --tag full
# Single case + LLM judge on blueprint quality
python -m backend.eval.run_eval --case product_intro --judge
# Compare against a previous run
python -m backend.eval.run_eval --compare eval_runs/20250624_120000/report.jsonReports are written to eval_runs/{run_id}/:
| File | Content |
|---|---|
report.json |
Summary scores, pass/fail, all checks |
{case_id}/trace.json |
Planner/Writer/Media artifact paths |
{case_id}/events.json |
Agent SSE-style event log |
{case_id}/metrics.json |
Per-case checks |
Metrics (rule-based): segment counts, blueprint/plan field completeness, clip & voice file presence, SRT entry count, deliverable duration vs Hailuo 6s cap, ffprobe video+audio streams, retry/complete events. Optional --judge adds an LLM 1–5 relevance score on the blueprint.
Edit cases in backend/eval/prompts.json (quick tag = 12s/2 clips, full = 60s/10 clips).
git clone https://github.com/Linkaiup/linCut.git
cd linCut
pip install -r backend/requirements.txt
cp .env.example .env # add MINIMAX_API_KEY
python -m backend.main- ffmpeg (with libass for burned-in captions) — not in
requirements.txt - MiniMax API key —
MINIMAX_API_KEYin.env
brew install ffmpeg # macOSBy default, all six agents run in-process inside the main API (mode=default). Hybrid mode runs each agent as a separate A2A (JSON-RPC) server; the main API acts as the orchestrator client.
| Mode | Trigger | Agents |
|---|---|---|
default |
Frontend default, or ?mode=default |
All in-process (studio.produce()) |
hybrid_a2a |
Frontend Hybrid checkbox, or ?mode=hybrid_a2a |
All six via A2A servers |
Hybrid pipeline:
Planner → Writer → [ Footage ∥ Narrator ∥ Composer ] → Assembler
:8001 :8002 :8003 :8004 :8005 :8006
Media agents (Footage, Narrator, Composer) run in parallel after planning. Composer remains optional — failures are non-fatal. All services must share the same machine workspace (backend/workspace/project_{id}/) because artifacts use local file paths.
Open six terminals for the agent servers, then start the main API:
# Agent servers (one per terminal)
python -m backend.a2a.main_planner # :8001
python -m backend.a2a.main_writer # :8002
python -m backend.a2a.main_footage # :8003
python -m backend.a2a.main_narrator # :8004
python -m backend.a2a.main_composer # :8005
python -m backend.a2a.main_assembler # :8006
# Main API + frontend
python -m backend.main # :8000Then either:
- Open http://localhost:8000, enter a prompt, enable Hybrid, and click Start Production, or
- Call the API directly:
curl -X POST "http://localhost:8000/api/projects?mode=hybrid_a2a" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A 30-second cinematic product intro for an AI writing assistant.",
"duration": 30,
"segment_count": 3,
"with_score": true
}'Poll progress via SSE (GET /api/projects/{id}/events) or status (GET /api/projects/{id}). Download the MP4 from GET /api/projects/{id}/file.
With all six agent servers running:
python -m backend.a2a.smoke_hybridUses a lightweight 12s / 2-clip case (with_score=false). Requires real MiniMax credits and ffmpeg.
Other A2A smoke scripts:
python -m backend.a2a.smoke_planner # Planner only (:8001)
python -m backend.a2a.smoke_pipeline # Planner + Writer (:8001, :8002)Shared (optional Bearer token for agent servers):
| Variable | Default | Description |
|---|---|---|
A2A_SERVICE_TOKEN |
(empty) | If set, agent servers require Authorization: Bearer … |
Orchestrator client URLs (main API reads these when dispatching Hybrid jobs):
| Variable | Default |
|---|---|
PLANNER_A2A_URL |
http://localhost:8001/a2a |
WRITER_A2A_URL |
http://localhost:8002/a2a |
FOOTAGE_A2A_URL |
http://localhost:8003/a2a |
NARRATOR_A2A_URL |
http://localhost:8004/a2a |
COMPOSER_A2A_URL |
http://localhost:8005/a2a |
ASSEMBLER_A2A_URL |
http://localhost:8006/a2a |
Per-server port / public URL overrides (examples):
| Agent | Port var | Public URL var |
|---|---|---|
| Planner | PLANNER_A2A_PORT (8001) |
PLANNER_A2A_PUBLIC_URL |
| Writer | WRITER_A2A_PORT (8002) |
WRITER_A2A_PUBLIC_URL |
| Footage | FOOTAGE_A2A_PORT (8003) |
FOOTAGE_A2A_PUBLIC_URL |
| Narrator | NARRATOR_A2A_PORT (8004) |
NARRATOR_A2A_PUBLIC_URL |
| Composer | COMPOSER_A2A_PORT (8005) |
COMPOSER_A2A_PUBLIC_URL |
| Assembler | ASSEMBLER_A2A_PORT (8006) |
ASSEMBLER_A2A_PUBLIC_URL |
Each agent exposes its Agent Card at GET /.well-known/agent.json. See docs/a2a/README.md for protocol details, schemas, and agent cards.
无需安装 Python,只需 Docker Desktop。
git clone https://github.com/Linkaiup/linCut.git
cd linCut
./start.sh # macOS / Linux
# start.bat # Windows首次运行会自动从 .env.example 创建 .env,填入 MINIMAX_API_KEY 后再次执行 ./start.sh 即可。
浏览器打开 http://localhost:8000
生成的视频保存在 data/workspace/ 目录。
docker compose logs -f # 查看日志
docker compose down # 停止服务
docker compose up -d # 后台启动(已构建过可跳过 --build)修改端口:在 .env 中添加 LINCUT_PORT=9000,然后 docker compose up -d。
cp .env.example .env # 编辑 MINIMAX_API_KEY
mkdir -p data/workspace
docker compose up --build -d| Method | Path | Description |
|---|---|---|
| POST | /api/projects?mode=default |
Start production (all agents in-process) |
| POST | /api/projects?mode=hybrid_a2a |
Start production (six A2A agent servers required) |
| GET | /api/projects/{id} |
Status |
| GET | /api/projects/{id}/events |
SSE agent events |
| GET | /api/projects/{id}/file |
Download MP4 |
Request body (POST /api/projects):
{
"prompt": "Your creative brief…",
"duration": 30,
"segment_count": 3,
"with_score": true
}duration must be ≥ 18. segment_count is the number of Hailuo clips (6s each for the 60s preset).
backend/
agents/ base + planner, writer, footage, narrator, composer, assembler
a2a/ A2A servers (:8001–:8006), client, orchestrator
core/ settings, llm helper
eval/ real-API quality eval (prompts.json, metrics, run_eval)
studio.py in-process orchestrator (default mode)
api/app.py FastAPI routes (+ hybrid_a2a mode)
docs/a2a/ Agent cards, JSON schemas, design notes
eval_runs/ eval reports (gitignored)
frontend/
index.html UI with Hybrid mode toggle