Repository navigation
Insert gap information into segment_id transcript for long pauses - #884
ttlequals0 merged 2 commits into
Conversation
Inserts lines into the transcript prompt describing gaps above a certain duration (1.5s by default), enabling the LLM to reason about long pauses between cues. The first "gap" line includes a description.
|
Merged, thanks. The idea is right: in segment-ID mode the model has no timestamps, so a pause is invisible to it, and this cue is cheap. I resolved the conflict with main myself by merging main into your branch (#886 changed the timestamp line format in the same function) and moved the changelog line into the 2.100.19 section, which is the current unbuilt version. There is no separate Unreleased heading in this repo. One thing I found while reviewing, fixed in #889 rather than holding this up: the System One adapter reads the prompt back into segments in Two small things for later, no action needed from you: the benchmark runner carries a copy of the formatter loop and could call |
… UI consistency pass (2.100.22) (#889) ## Why Three detection reports, seven open issues, a batch of phone layout problems and the foldable-phone viewports, shipped as 2.100.19. A second round on the same branch, 2.100.20, fixes what a UI audit found after the first deploy. A third, 2.100.21, applies the full audit. A fourth, 2.100.22, fixes two things 2.100.21 got wrong. #886 and #894 are already on main. Closes #874, #875, #876, #879, #888, #891, #895. ## What changed - Same-sponsor merge: a fold only extends an end. When the later fragment sat inside the first, the merged marker took the inner end and a cross-fetch differential span lost its measured tail (2.7 s at an episode start, 4.5 s before the credits on one episode). - Reviewer: an inward trim now stops at a removable template cue inside the LLM span, not only at an edge the cue snap already moved. An ad-break stinger 7 s into a span was being left in the output. - Detection notes: per-feed notes go to the detector, the verification pass and the reviewer as their own prompt block marked as operator instructions, outside the 800-character description budget. Notes are stripped of HTML only, so a cited time survives. - Cue templates can cut every match on their own (#874). Global setting, feed override and per-template value, explicit beating inherited. Each match becomes a marker with the cue type's category, and the feed's segment category actions decide the outcome. Content transition cues are excluded. Cue-only safety still holds an unproven template. - Issue fixes. The pattern dialog's podcast link went to the API path (#876). The current-position pin drag follows the play-while-dragging setting (#875). The cue pair override is named like the global setting (#879). ffmpeg's big-endian ID3v2.4 frame sizes no longer fail chapter restore, and a chapter tag that cannot be read is skipped instead of failing the episode (#888, fix from ChaosHat). Recut works for cue-only feeds without a transcript (#891). - Web UI: Calls by phase is a table. The pattern details dialog uses the shared button recipes. On phones its footer is a row of equal-width text buttons, with Save as the edit label like every other dialog. The Feeds header shows compact actions below 768 px and two columns from 600 px. Copy buttons center their icon when the label is hidden. Play buttons are one square size everywhere, 32 px inside the 44 px target on phones. Overlapping cut markers render as one block with a segments toggle. Dialog footers, close buttons, destructive outlines and icon buttons share one set of recipes, documented in the design guide. The transcript viewer groups lines into paragraphs at render time, with a Lines toggle, and the stored transcript is unchanged (#887). - Settings > System Status drops Time Saved, LLM Tokens and Cost and links to the Stats page. Reject buttons on non-sponsor markers read "Keep" (#877 follow-up). - Foldable phones (466x678 folded, 890x626 unfolded). The shell and fixed bars pad for the side safe-area insets. Grids use even column counts between 640 and 1023 px. Dialogs stay inside one viewport segment when the browser reports two. - MP3 stream copy fixes ported from batram's plusminuspod fork, kept as their own commits so the squash credits the author. Review follow-ups on top: the disk-space estimate no longer counts PCM files that are not written, the final-cut extension checks protected audio, and ffmpeg's stderr is drained so a chatty decode cannot stall. - After #886, the startup refresh of shipped defaults moves never-customized prompt rows to the new timestamp form. - After #884, the System One adapter skips the new gap cue rows when it reads a segment-ID prompt back into segments; before, the first gap row ended the transcript. - Image build: the 30 upstream security patches for ffmpeg, x264, libass, libsndfile, glibc, cairo, cjson and glib ship in the repo instead of being downloaded from their git forges at build time. One forge now answers automated fetches with a bot challenge page and another changed its patch rendering, so the pinned checksums no longer matched. - 2.100.20: the coarse-pointer floor was stretching four icon buttons and leaving their icons off center: edit feed title, open in editor, and the ad editor's add and close. They now use the icon recipe or flex centering, and lucide icons replace the hand-rolled paths. Held-marker and Ad Review action rows share one button height. A browser contract measures icon centering on the routes the contract suite reaches without a backend. The data-driven pages were measured with the mocked harness. The reject button and badges read "Not ad". Settings > System Status drops the sentence pointing at the Stats page. - 2.100.21: UI consistency pass. Headings, buttons and labels are sentence case. Errors read "Could not <verb> <noun>." and empty lists "No <things> yet." Held markers are "Needs review"; decisions are "Confirm" or "Not ad" everywhere, including the editor footer; reruns are "Re-detect ads" or "Full reprocess"; the nav says "Feeds" and "Add feed"; destructive confirms repeat verb and noun under question titles. Percents and durations share two formatters ("99% confidence", "2m 5s"). Every button, field, label and badge composes a shared recipe. Stat grids use one tile, episode status one badge, close buttons one component, and lucide replaces the hand-drawn icons. Dialogs pin their header and footer and scroll only the body. Stats and Search use the underline tabs. On phones the Add feed modes stack, the status bar shows the stage only, the Sponsors search spans the row, episode lists drop the artwork, review action rows are 44 px tall and icon buttons fill their target. - Auto-process window (#895). New episodes were auto-queued only when published in the last 48 hours, and the value was hardcoded. An instance that runs a few times a week never processed what arrived while it was off. The window is now a global setting, default 48 hours and up to 720, with a per-feed override that inherits when empty. - 2.100.22: the reviewer trimmed a cut back to the last spoken word whenever the wordless stretch past it was under 8 s. A pre-roll's closing music (2.7 s) and a post-roll's tagline music (4.7 s) survived the cut that way. It now holds the edge at the file head or tail and at a differential-measured edge at any length; an edge snapped to a labelled boundary cue keeps the cue. On phones, Detected ads cards keep their four controls on one line; only the five-control Ad review card wraps below 430 px. The Podping listener polls the Hive node through one keep-alive session instead of a new connection and DNS lookup per call (two calls every 3 s); health probes still open their own connections, since they fan out across threads. - brotli 1.2.1 for PYSEC-2026-4322, filelock 4.2.4 for CVE-2026-112940, zod 4.6.7 for GHSA-mrhx-c7xc-m3w5, happy-dom 21.0.4 for GHSA-834v-8h66-3h79, plus fast-uri 3.1.9 and serialize-javascript 7.1.4. ## Verification - `PYTHONPATH=src pytest tests/` (12246 passed, 2 skipped) and `ruff check src/ tests/` pass. - `npx tsc --noEmit`, `npm run lint`, `npm run test` (158 files, 1883 tests), `npm run design:check` and `npm audit --audit-level=high` pass. The browser contract suite passes on the four Chromium projects (34 tests). - Browser checks with a mocked API and coarse pointer at 320, 360, 390, 466, 626, 678, 768, 890 and 1280 px for the Feeds page, episode page, pattern dialog (view, edit and delete states), settings sections, cue templates panel and play buttons. - Before and after captures of 19 states at 390 px (coarse pointer) and 1280 px with a mocked API. At 390 no state has a button under 44 px, horizontal overflow or clipped text, and the three dialogs keep their footer inside the viewport. - One episode was reprocessed against sharper detection notes and came back as one contiguous block instead of three cuts. - Trivy on the 2.100.19 through 2.100.22 GPU images: 0 critical, 0 high, 348 medium, all Ubuntu ffmpeg-family packages with no fix available. The previous image scans today at 5 critical and 23 high. The secret scan's only hits are Anthropic SDK docstrings, now allowed by rule. Co-authored-by: batram <[email protected]> Co-authored-by: ChaosHat <[email protected]>
Summary
This pull request enhances how transcript gaps are represented in prompts when using the "segment_ids" addressing mode. Now, long gaps between transcript segments are explicitly marked, providing clearer cues for LLM processing. The changes affect both the core implementation and related tests.
Prompt formatting improvements:
_format_transcript_linesmethod insrc/ad_detector/__init__.pyto insert explicit gap cues (e.g.,[gap of 2.0s ...]) when a silence or non-transcribed segment longer than a threshold is detected between transcript segments in "segment_ids" mode._build_user_promptfunction inbenchmarks/llm/src/benchmark/runner.pyto include these gap cues in the constructed prompt when using "segment_ids" addressing.Testing updates:
test_id_transcript_linestest intests/unit/test_segment_id_addressing.pyto verify that gap cues are correctly inserted between transcript segments with significant pauses.Resolves issue #883. See it for more information.
Test plan
PYTHONPATH=src pytest tests/passesruff check src/ tests/passesFrontend (if touched):npx tsc --noEmit,npm run lint,npm run testUI changes:npm run design:checkandnpm run test:browserpassUI changes: before/after evidence identifies routes, viewport widths, input modes, and data limitationsUI changes: failure/retry, keyboard, dirty-state, and destructive-action behavior checked where affected