Skip to content

Sentence-clean highlights, no-outro, folder pooling + editable reel sessions (CLI/MCP/UI)#45

Merged
nmbrthirteen merged 10 commits into
feat/moment-detection-phase2from
feat/moment-detection-phase3
Jul 6, 2026
Merged

Sentence-clean highlights, no-outro, folder pooling + editable reel sessions (CLI/MCP/UI)#45
nmbrthirteen merged 10 commits into
feat/moment-detection-phase2from
feat/moment-detection-phase3

Conversation

@nmbrthirteen

Copy link
Copy Markdown
Owner

Stacked on #44.

What

Makes the highlights flow usable end to end and adds fast per-moment iteration across CLI, MCP, and web UI.

Highlight quality

  • Skip transcription for saliency profiles (reuses a cached transcript when present).
  • Sentence-clean boundaries — split words on .?! punctuation and snap clip edges to real sentences, so no clip starts or ends mid-thought (Whisper segments straddle sentences, so segment-snapping wasn't enough).
  • No auto-outro for highlight profiles + a --no-outro flag on process.
  • Folder poolingdetect_highlights_pooled ranks the best moments across a folder of clips, reaction-first, each tagged with source_file.

Editable reel sessions (the iteration feature)

Detect once, then edit moments fast. A persisted ReelSession stores the moments; editing one (longer/shorter/earlier/later/shift/drop/toggle) re-cuts only that moment straight from the source (~5s) and rebuilds — no re-detection, no heavy render.

  • Core: services/reel.py (shared by all surfaces).
  • CLI: podcli reel new|show|edit|build.
  • MCP: manage_reel tool → /api/reel → reel service.
  • UI: /reel page with per-moment controls.

Verification

  • CLI: reel edit 1 longer 8 extended a moment and rebuilt.
  • MCP: /api/reel show + edit verified against a live server (alt port).
  • UI: tsc + vite build clean; server serves the new bundle at /reel.
  • 387 tests pass (+10 reel, +others). The 3 test_ai_fallback failures are pre-existing and environment-dependent.

Known follow-up

On a real 71-min podcast the reel came out all energy-picks, zero laugh-triggered — the reaction threshold (0.15) is likely too high for conversational chuckles. Tuning next.

Note for reviewers

MCP tools route through the web server, so the studio must be rebuilt/restarted (npm run build && npm run ui) to pick up /api/reel and the manage_reel tool.

Saliency profiles select on audio/visual signals, not dialogue, so transcribing
a long party video is wasted work. Detect the profile before Step 1 and skip
transcription entirely (no words/segments needed), relax the no-segments gate,
and stop the misleading 'heuristic mode' message when clips are already chosen.

Verified end to end: 'process --profile party' skips transcription, detects
highlights, and renders clips including a reaction clip.
Saliency detection now takes optional segments: clip windows are built from whole
sentences (never cutting mid-thought) when a transcript is available, falling back
to audio-lull snapping only for true no-dialogue footage. The process flow reuses a
cached transcript for saliency profiles instead of skipping it, so podcast
highlights are sentence-clean. Verified on a real cached 71-min episode: clips land
on segment boundaries with coherent text.
…files

- Snap saliency clip boundaries to real sentences (split words on .?! punctuation)
  so highlights never start or end mid-thought; falls back to segments then audio
  lulls when word punctuation is absent
- Add --no-outro to process and stop auto-appending the outro for saliency
  (party/action) profiles — highlights are raw moments, not branded shorts
Detect once, then iterate on moments fast. A persisted ReelSession stores the
detected moments; editing one (longer/shorter/earlier/later/shift/drop/toggle)
re-cuts only that moment straight from the source (~seconds) and rebuilds the reel,
with no re-detection or heavy render.

- services/reel.py: shared core (session persistence, edit ops, fast ffmpeg re-cut
  + concat) used by every surface
- CLI: 'podcli reel new|show|edit|build'
- MCP: 'manage_reel' task handler (new/show/edit/build)
- 10 tests covering edit math, drop/toggle, and session round-trip

Next: TS MCP tool definition and the web-studio reel panel.
Add the manage_reel MCP tool (server.ts) routing through a new /api/reel web
endpoint to the Python reel service, so the agent can create a reel and edit
moments (longer/shorter/drop/...) conversationally. Mirrors the analyze_energy
tool path; add manage_reel + detect_highlights to the TaskRequest union.
Verified end to end: /api/reel show and edit against a live server.
A 'Reel' page in the studio: paste a video path, detect party/action moments,
then adjust each moment (+5s/-5s end, start earlier/later, disable, drop) with
one click — each edit calls /api/reel and rebuilds. Routed at /reel with a
sidebar link. Builds clean (tsc + vite).
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9be8c449-3c2d-4ec2-a277-1bc1bcccd582

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/moment-detection-phase3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

YAMNet scores subtle podcast chuckles far lower than belly-laughs: across a
71-min episode the max laughter was 0.15, so the 0.15 cutoff surfaced zero
reactions. Thread a reaction_threshold param (default 0.06) used consistently for
candidate-picking and reaction-window classification. On the same episode this
turns 0 laugh-driven clips into 6 of 12, landing on the genuinely playful moments
(a quip, rapid-fire banter, the warm sign-off).
- Render reels in vertical, horizontal or square (was hardcoded 1080p landscape)
- Thread moment count and min/max duration through CLI, MCP and web API
- Add reel session list and delete, plus an absolute "set" trim edit
- Add a generalized "auto" detection profile (new default) so the content
  type no longer has to be chosen by hand
- Expose per-clip and reel file paths; add a path-guarded /api/reel-download
- Re-cut shifted moments after a drop so the reel stops reusing stale clips
- Rename Reel to Highlights (nav, route /highlights, /reel redirects)
- Drop or browse a video instead of pasting a path
- Trim each moment on a video timeline with draggable in/out handles
- Download the whole reel or individual clips
- List, open and delete saved sessions
- set edit op: absolute bounds, start/end-only, clamping
- seed_session builds moments and normalizes the format
- build_reel cuts at the session format, reuses clean clips, and
  re-cuts shifted moments after a drop; concat includes only enabled moments
- auto profile resolves as a saliency profile and fuses channels
@nmbrthirteen nmbrthirteen merged commit a4de3b5 into feat/moment-detection-phase2 Jul 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant