Skip to content

youvandra/OKClip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OKClip

An A2A Agent Service Provider on OKX.AI that turns a YouTube URL + a natural-language brief into decision-grade video clips. A requesting agent sends a video and a brief; OKClip negotiates scope and price, finds the best moments, cuts them with burned-in speaker-labeled subtitles, and returns structured clip metadata the agent can approve — every clip carrying a viral score, a confidence, and the reasons it was picked.

Built for the OKX.AI Genesis Hackathon. Sibling project to WalletLens.

Type A2A (Agent-to-Agent) — negotiated, escrow-settled on X Layer
OKX.AI Agent ID #5189
Protocol OKX onchainos agent (CLI + XMTP state machine); escrow is gas-free via the platform paymaster
Work engine this repo — invoked by the ASP agent on job_accepted
Human surface / — Alpine + Tailwind SPA
Stack Node 20 · TypeScript · Express 5 · Deepgram · Sumopod LLM · FFmpeg
Download loader.to API (free 3rd-party, no proxy/cookies needed)

Why OKClip

Clipping a video is a commodity — Whisper/Deepgram + an LLM + FFmpeg, and every SaaS tool already does it. OKClip is different in two ways that matter to an autonomous agent:

  • It's agent-native, not a web app. Other agents compose OKClip into workflows: find a trending video → OKClip → 3 posted clips. No competitor offers an A2A interface.
  • Its output is decision-grade, not a black box. Every clip ships the reasons it was picked (topic match, laughter/scene-cut hook, question→answer exchange, sentence-boundary), a confidence, and an evidence block. The requesting agent approves on structured data — it never has to watch the video.

Plus the things a serious clip tool needs: negotiation (infer platform/aspect, price transparently, decline out-of-scope), a revision loop (reject a clip with feedback; OKClip re-cuts just that moment from the cached transcript), and per-agent style memory that learns aspect ratio, clip length, and topics from history.


How A2A works here

OKX A2A is not an HTTP endpoint — it is an agent process driven by the onchainos agent CLI over XMTP, with escrow funded and released on the platform (gas-free). The ASP agent negotiates, applies, and — only once the job is accepted and escrow is funded — runs OKClip as its work engine, then delivers the clips over XMTP.

user publishes task
  -> job_created           ASP agent: apply (on-chain, gas-free)        [OKX CLI]
  -> user confirm-accept
  -> job_accepted          escrow funded; NOW do the work               [OKX event]
       run the engine:  okclip run --url <yt> --prompt "<brief>" --clips <n>
       -> clip files + metadata + summary
  -> deliver               attach clips + send summary over XMTP        [OKX CLI]
  -> user confirms         payment released                             [OKX]

Invoking the engine

CLI — what the ASP agent shells out to:

okclip run --url "https://youtu.be/…" --prompt "3 DeFi clips for tiktok" --clips 3
# stdout: JSON { ok, jobId, price, summary, delivery, clipFiles[], workDir }

clipFiles[] are absolute paths to attach; summary is an XMTP-ready text block.

Internal HTTP API — used by the frontend and local callers:

Method Path Purpose
POST /api/negotiate { agentId, brief }proposal | clarify | decline (probes source, applies style memory)
POST /api/jobs { agentId, brief, terms }{ jobId } (enqueues the job)
GET /api/jobs/:id poll the delivery
POST /api/jobs/:id/revise { rejections[] } → re-clips rejected moments (async)
GET /clips/:jobId/:file the produced mp4 / thumbnail (path-traversal safe)
GET /health liveness + feature flags

A brief is { url, prompt, clipCount (1–5), aspectRatio?, maxClipSeconds?, minClipSeconds?, language?, subtitleStyle?, resolution? }.

Platform auto-detect: mention tiktok/reels/shorts/youtube in prompt → aspect & max duration auto-set.

Subtitle styles: default (white, outline), bold (yellow, pop animation, thick outline), karaoke (word-by-word fill), minimal (clean, fade-in).

Delivery shape (per clip)

{
  "downloadUrl": "/clips/<job>/clip-1.mp4",
  "thumbnailUrl": "/clips/<job>/clip-1.jpg",
  "viralScore": 87,            // heuristic, capped at 95 — never certainty
  "confidence": 0.82,          // how well the moment matches the brief
  "durationSec": 47,
  "timestamp": { "startSec": 272, "endSec": 319 },
  "transcriptSnippet": "",
  "speakers": ["Speaker 1", "Speaker 2"],
  "reasons": ["topic match: DeFi", "question -> answer exchange", "opens on a scene cut"],
  "caption": "", "hashtags": ["#DeFi"],
  "evidence": { "sourceDurationSec": 3720, "analyzedSegments": 214, "asr": "deepgram-nova-2", "caveat": "" }
}

The delivery also carries scored runner-up moments (candidates not clipped), so an agent can swap a pick without a full re-process.


Pipeline

loader.to download → Deepgram transcribe + word-level + diarize
  → LLM select moments (+ score + reasons + runner-ups)
  → scene-cut refine (hook) → face-aware crop (cropdetect auto-bias)
  → FFmpeg cut + burn animated subtitles (style presets: default/bold/karaoke/minimal)
  → fade in/out (0.3s) + blur-pillarbox crop (16:9→9:16 keeps full frame)
  → smart thumbnail (3-frame sharpness scoring + AI text overlay)
  → decision-grade delivery
  → multi-clip stitch with crossfade transitions

Pricing

Transcription cost scales with source length and is paid once per task, not per clip — so price is a clip-count tier plus a length surcharge.

Clips Base (source ≤ 30 min)
1 0.5 USDT
3 1 USDT
5 1.5 USDT

+0.5 USDT per additional 30-minute block of source. Quoted up front during negotiation.


Quick start (local)

Prerequisites

  • Node.js 20+
  • ffmpeg on PATH
  • A Deepgram API key and a Sumopod (OpenAI-compatible) API key
# macOS
brew install ffmpeg

Run

cd backend
npm install
cp .env.example .env         # fill in DEEPGRAM_API_KEY + SUMOPOD_API_KEY
npm run dev                  # http://localhost:3001

Open http://localhost:3001 for the SPA, POST to /api/* as an agent, or run the engine directly:

npm run build
node dist/cli.js run --url "https://youtu.be/…" --prompt "best moments" --clips 1

Scripts

npm run dev        # tsx watch
npm run build      # tsc -> dist/
npm start          # node dist/index.js
npm test           # node:test suite (hermetic, no network)
npm run typecheck  # tsc --noEmit

The test suite is hermetic (no network): it covers the pure logic — pricing, aspect inference, sentence-boundary snapping, score clamping, SRT/ffmpeg arg building, playlist parsing, and the A2A job adapter.


Configuration

Variable Required Default Purpose
PORT no 3001 HTTP port
NODE_ENV no development Environment
DEEPGRAM_API_KEY for ASR Transcription + word timings + diarization
SUMOPOD_API_KEY for analysis LLM moment selection / scoring / captions
SUMOPOD_BASE_URL no https://ai.sumopod.com/v1 OpenAI-compatible base URL
SUMOPOD_MODEL no deepseek-v4-flash Model id
STORAGE_DIR no /tmp/okclip Temp clip storage
PREFERENCES_DIR no data/preferences Persistent per-agent style memory
CLIP_TTL_MS no 86400000 Clip retention before cleanup (24 h)
MAX_SOURCE_SECONDS no 7200 Product cap on source length (2 h)

The server boots without the API keys — /health reports which features are enabled — so discovery and negotiation always work.


Project layout

backend/src/
  index.ts        Express server: work API, clip serving, cleanup
  cli.ts          `okclip run` — headless engine the ASP agent shells out to
  worker.ts       run one job to completion (no HTTP)
  a2a-adapter.ts  OKX A2A job <-> Brief + platform auto-detect (TikTok/Reels/Shorts)
  jobs.ts         internal work API (negotiate / jobs / revise)
  negotiation.ts  pricing, aspect inference, decline/clarify
  pipeline.ts     retry logic + download → transcribe → analyze → clip orchestration
  loader-downloader.ts  YouTube download via free loader.to API (replaced yt-dlp)
  downloader.ts   oEmbed probe + loader.to download bridge
  transcriber.ts  Deepgram nova-2 (transcript + word-level + diarization)
  analyzer.ts     LLM moment selection, scoring, sentence-boundary snapping, duration enforcement
  clipper.ts      ffmpeg cut + face-aware blur-pillarbox crop + subtitle burn + fade
  subtitles.ts    style presets (default/bold/karaoke/minimal) + ASS animations + speaker labels
  thumbnail.ts    smart thumbnail (sharpness scoring 3 frames) + AI text overlay via drawtext
  hooks.ts        scene detection near candidate timestamps + hook refine
  stitch.ts       highlight-reel concat + crossfade transitions (xfade)
  memory.ts       per-agent style memory (the data moat)
  storage.ts      safe clip serving + TTL cleanup
  queue.ts        in-memory single-worker job queue
  delivery.ts     decision-grade delivery envelope
  config.ts types.ts logger.ts exec.ts
frontend/
  index.html      Alpine + Tailwind SPA (no build step)

Deployment

Node backend under pm2 behind nginx (TLS via Let's Encrypt) on a VPS. See ecosystem.config.cjs (single instance — the queue and style memory are in-process). Install ffmpeg, then: then set the API keys in backend/.env.


Honesty rules

Deliberate constraints, not omissions:

  • Viral score is capped at 95. A transcript heuristic never justifies certainty.
  • Evidence travels with every clip — source length, segments analyzed, ASR used, and an explicit caveat.
  • Reasons are real signals — topic-match, audio/scene hooks, boundary quality, conversational structure — not decoration.
  • Prices reflect real cost — the length surcharge tracks the ASR cost that actually scales.

Submission

Built for the OKX.AI Genesis Hackathon. Registered as an A2A ASP, Agent ID #5189. Deadline: Jul 17, 2026 23:59 UTC.


## License

MIT

About

An A2A Agent Service Provider on OKX.AI that turns a YouTube URL + a natural-language brief into decision-grade video clips.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors