From 4db4b70e494537ef71d431a9cfcb37cfba07a6b5 Mon Sep 17 00:00:00 2001 From: Rishabh Singh Date: Fri, 25 Sep 2026 17:32:57 +0530 Subject: [PATCH 1/6] fix(ingest): distinguish YouTube blocks from missing captions --- src/server/ingest/stt.test.ts | 26 +---- src/server/ingest/stt.ts | 24 +---- src/server/ingest/youtube-captions.test.ts | 112 +++++++++++++++++++++ src/server/ingest/youtube-loader.test.ts | 33 +++--- src/server/ingest/youtube-loader.ts | 42 +++++--- 5 files changed, 160 insertions(+), 77 deletions(-) create mode 100644 src/server/ingest/youtube-captions.test.ts diff --git a/src/server/ingest/stt.test.ts b/src/server/ingest/stt.test.ts index 27f3a02..f957c5a 100644 --- a/src/server/ingest/stt.test.ts +++ b/src/server/ingest/stt.test.ts @@ -1,30 +1,6 @@ -import { - YoutubeTranscriptDisabledError, - YoutubeTranscriptError, - YoutubeTranscriptNotAvailableError, - YoutubeTranscriptNotAvailableLanguageError, - YoutubeTranscriptTooManyRequestError, - YoutubeTranscriptVideoUnavailableError, -} from "youtube-transcript"; import { describe, expect, it } from "vitest"; -import { assertWithinCap, isNoCaptions, MAX_STT_MINUTES, toSegments } from "~/server/ingest/stt"; - -describe("STT trigger — only genuine no-captions may lead to a paid call", () => { - it("fires on disabled / no track / no usable language", () => { - expect(isNoCaptions(new YoutubeTranscriptDisabledError("v"))).toBe(true); - expect(isNoCaptions(new YoutubeTranscriptNotAvailableError("v"))).toBe(true); - expect(isNoCaptions(new YoutubeTranscriptNotAvailableLanguageError("en", ["hi"], "v"))).toBe(true); - }); - - it("never fires on throttle, private/removed, or anything unknown", () => { - expect(isNoCaptions(new YoutubeTranscriptTooManyRequestError())).toBe(false); - expect(isNoCaptions(new YoutubeTranscriptVideoUnavailableError("v"))).toBe(false); - expect(isNoCaptions(new YoutubeTranscriptError("boom"))).toBe(false); - expect(isNoCaptions(new TypeError("fetch failed"))).toBe(false); - expect(isNoCaptions(undefined)).toBe(false); - }); -}); +import { assertWithinCap, MAX_STT_MINUTES, toSegments } from "~/server/ingest/stt"; describe("STT duration cap", () => { it("rejects a known duration over the cap, names the cap", () => { diff --git a/src/server/ingest/stt.ts b/src/server/ingest/stt.ts index 724083e..d73e64a 100644 --- a/src/server/ingest/stt.ts +++ b/src/server/ingest/stt.ts @@ -1,19 +1,13 @@ import { createAssemblyAI } from "@ai-sdk/assemblyai"; import { transcribe } from "ai"; -import { - YoutubeTranscriptDisabledError, - YoutubeTranscriptNotAvailableError, - YoutubeTranscriptNotAvailableLanguageError, -} from "youtube-transcript"; import { env } from "~/env"; import type { Segment, SttProvider } from "~/server/domain/types"; /** * Speech-to-text for caption-less videos. This file is the whole provider choice: swapping - * AssemblyAI for another `transcribe()` provider touches nothing else. The decisions that - * guard the bill (which caption failures may trigger a paid call, how long a video may be) - * live here as pure functions so they are tested without any network. + * AssemblyAI for another `transcribe()` provider touches nothing else. The duration guard + * lives here as a pure function so it is tested without any network. */ export const STT_PROVIDER: SttProvider = "assemblyai"; @@ -27,20 +21,6 @@ const STT_MODEL = "universal-3-5-pro"; */ export const MAX_STT_MINUTES = 180; -/** - * The fallback trigger. Only "these captions genuinely do not exist" may lead to a paid - * transcription: disabled by the owner, no track at all, or no track in a language we can use. - * Everything else — rate limit, private/removed video, network — rethrows so the video is - * `failed` and a throttle can never fan out into paid calls. Rerunning is the retry. - */ -export function isNoCaptions(error: unknown): boolean { - return ( - error instanceof YoutubeTranscriptDisabledError || - error instanceof YoutubeTranscriptNotAvailableError || - error instanceof YoutubeTranscriptNotAvailableLanguageError - ); -} - export function assertWithinCap(videoId: string, durationSec: number | undefined): void { if (durationSec === undefined) return; const minutes = Math.round(durationSec / 60); diff --git a/src/server/ingest/youtube-captions.test.ts b/src/server/ingest/youtube-captions.test.ts new file mode 100644 index 0000000..43c98ba --- /dev/null +++ b/src/server/ingest/youtube-captions.test.ts @@ -0,0 +1,112 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { youtubeLoader } from "~/server/ingest/youtube-loader"; + +const mocks = vi.hoisted(() => ({ + env: { TRANSCRIBE_FALLBACK: false }, + getBasicInfo: vi.fn(), +})); + +vi.mock("~/env", () => ({ env: mocks.env })); +vi.mock("youtubei.js", () => ({ + Log: { setLevel: () => undefined, Level: { NONE: 0 } }, + Innertube: { create: async () => ({ getBasicInfo: mocks.getBasicInfo }) }, +})); + +afterEach(() => { + vi.unstubAllGlobals(); + vi.clearAllMocks(); + mocks.env.TRANSCRIBE_FALLBACK = false; +}); + +describe("YouTube captions in channel imports", () => { + it("reports YouTube bot protection instead of claiming captions are absent", async () => { + mocks.env.TRANSCRIBE_FALLBACK = true; + mocks.getBasicInfo.mockResolvedValue({ + playability_status: { + status: "LOGIN_REQUIRED", + reason: "Sign in to confirm you’re not a bot", + }, + captions: { caption_tracks: [] }, + }); + const fetchSpy = vi.fn(); + vi.stubGlobal("fetch", fetchSpy); + + await expect( + youtubeLoader.loadTranscript({ kind: "youtube_video", externalId: "5e37ZT3SQbk" }), + ).rejects.toThrow(/YouTube player returned LOGIN_REQUIRED.*not a bot/); + expect(fetchSpy).not.toHaveBeenCalled(); + expect(mocks.getBasicInfo).toHaveBeenCalledTimes(1); + }); + + it("indexes a playable video with an English caption track", async () => { + const videoId = "5e37ZT3SQbk"; + mocks.getBasicInfo.mockResolvedValue({ + playability_status: { status: "OK" }, + captions: { + caption_tracks: [ + { + language_code: "en", + base_url: "https://www.youtube.com/api/timedtext?test=1", + }, + ], + }, + }); + vi.stubGlobal( + "fetch", + vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + const url = String(input); + if (init?.method === "POST") return Response.json({ + captions: { playerCaptionsTracklistRenderer: { captionTracks: [ + { languageCode: "en", baseUrl: "https://www.youtube.com/api/timedtext?test=1" }, + ] } }, + }); + if (url.includes("/api/timedtext?")) { + return new Response('Real caption'); + } + throw new Error(`Unexpected request: ${url}`); + }), + ); + + await expect( + youtubeLoader.loadTranscript({ kind: "youtube_video", externalId: videoId }), + ).resolves.toEqual({ + provenance: "captions", + segments: [{ text: "Real caption", startSec: 12.5, endSec: 15 }], + }); + }); + + it("does not pay for transcription when a caption URL returns HTTP 403", async () => { + mocks.env.TRANSCRIBE_FALLBACK = true; + mocks.getBasicInfo.mockResolvedValue({ + playability_status: { status: "OK" }, + captions: { + caption_tracks: [ + { + language_code: "en", + base_url: "https://www.youtube.com/api/timedtext?test=1", + }, + ], + }, + }); + vi.stubGlobal( + "fetch", + vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + if (init?.method === "POST") return Response.json({ + captions: { playerCaptionsTracklistRenderer: { captionTracks: [ + { languageCode: "en", baseUrl: "https://www.youtube.com/api/timedtext?test=1" }, + ] } }, + }); + if (String(input).includes("/api/timedtext?")) { + return new Response("", { status: 403 }); + } + throw new Error(`Unexpected request: ${String(input)}`); + }), + ); + + await expect( + youtubeLoader.loadTranscript({ kind: "youtube_video", externalId: "5e37ZT3SQbk" }), + ).rejects.toThrow(/caption retrieval returned HTTP 403/); + expect(mocks.getBasicInfo).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/server/ingest/youtube-loader.test.ts b/src/server/ingest/youtube-loader.test.ts index 11498ff..c042f76 100644 --- a/src/server/ingest/youtube-loader.test.ts +++ b/src/server/ingest/youtube-loader.test.ts @@ -1,6 +1,4 @@ import { - YoutubeTranscriptDisabledError, - YoutubeTranscriptNotAvailableError, YoutubeTranscriptTooManyRequestError, YoutubeTranscriptVideoUnavailableError, } from "youtube-transcript"; @@ -129,6 +127,8 @@ const ref = { kind: "youtube_video", externalId: "UF8uR6Z6KLc" } as const; function videoOf(durationSec: number | undefined) { mocks.getBasicInfo.mockResolvedValue({ basic_info: { duration: durationSec }, + playability_status: { status: "OK" }, + captions: { caption_tracks: [] }, download: mocks.download, }); mocks.download.mockImplementation(async () => new Blob([new Uint8Array([1, 2, 3])]).stream()); @@ -138,6 +138,14 @@ describe("loadTranscript — captions first, STT only behind every guard", () => beforeEach(() => { vi.clearAllMocks(); mocks.env.TRANSCRIBE_FALLBACK = false; + mocks.getBasicInfo.mockResolvedValue({ + playability_status: { status: "OK" }, + captions: { + caption_tracks: [ + { language_code: "en", base_url: "https://www.youtube.com/api/timedtext" }, + ], + }, + }); mocks.transcribe.mockResolvedValue({ segments: [ { text: "Hello", startSecond: 0, endSecond: 0.5 }, @@ -152,14 +160,16 @@ describe("loadTranscript — captions first, STT only behind every guard", () => segments: [{ text: "hi", startSec: 0, endSec: 1 }], provenance: "captions", }); - expect(mocks.getBasicInfo).not.toHaveBeenCalled(); + expect(mocks.getBasicInfo).toHaveBeenCalledWith("UF8uR6Z6KLc", { + client: "VISIONOS", + }); expect(mocks.transcribe).not.toHaveBeenCalled(); }); - it("no captions + flag off → fails naming the flag, before any Innertube call", async () => { - mocks.fetchTranscript.mockRejectedValue(new YoutubeTranscriptDisabledError("UF8uR6Z6KLc")); + it("no caption tracks + flag off → fails before audio download", async () => { + videoOf(60); await expect(youtubeLoader.loadTranscript(ref)).rejects.toThrow(/TRANSCRIBE_FALLBACK=true/); - expect(mocks.getBasicInfo).not.toHaveBeenCalled(); + expect(mocks.download).not.toHaveBeenCalled(); expect(mocks.transcribe).not.toHaveBeenCalled(); }); @@ -173,13 +183,11 @@ describe("loadTranscript — captions first, STT only behind every guard", () => mocks.fetchTranscript.mockRejectedValue(error); await expect(youtubeLoader.loadTranscript(ref)).rejects.toBe(error); } - expect(mocks.getBasicInfo).not.toHaveBeenCalled(); expect(mocks.transcribe).not.toHaveBeenCalled(); }); it("over the cap → fails before a byte is downloaded", async () => { mocks.env.TRANSCRIBE_FALLBACK = true; - mocks.fetchTranscript.mockRejectedValue(new YoutubeTranscriptDisabledError("UF8uR6Z6KLc")); videoOf(200 * 60); await expect(youtubeLoader.loadTranscript(ref)).rejects.toThrow(/over the 180 min STT cap/); expect(mocks.download).not.toHaveBeenCalled(); @@ -188,7 +196,6 @@ describe("loadTranscript — captions first, STT only behind every guard", () => it("flag on + genuinely no captions → exactly one transcribe() call, stt provenance", async () => { mocks.env.TRANSCRIBE_FALLBACK = true; - mocks.fetchTranscript.mockRejectedValue(new YoutubeTranscriptNotAvailableError("UF8uR6Z6KLc")); videoOf(5 * 60); const stderr = vi.spyOn(console, "error").mockImplementation(() => undefined); @@ -204,12 +211,10 @@ describe("loadTranscript — captions first, STT only behind every guard", () => stderr.mockRestore(); }); - it("captions that exist but are empty count as no captions", async () => { + it("an empty caption track fails without starting paid transcription", async () => { mocks.env.TRANSCRIBE_FALLBACK = true; mocks.fetchTranscript.mockResolvedValue([]); - videoOf(60); - vi.spyOn(console, "error").mockImplementation(() => undefined); - await expect(youtubeLoader.loadTranscript(ref)).resolves.toMatchObject({ provenance: "stt" }); - expect(mocks.transcribe).toHaveBeenCalledTimes(1); + await expect(youtubeLoader.loadTranscript(ref)).rejects.toThrow(/caption track returned no text/); + expect(mocks.transcribe).not.toHaveBeenCalled(); }); }); diff --git a/src/server/ingest/youtube-loader.ts b/src/server/ingest/youtube-loader.ts index ab90af9..3ef8e1e 100644 --- a/src/server/ingest/youtube-loader.ts +++ b/src/server/ingest/youtube-loader.ts @@ -12,7 +12,6 @@ import type { } from "~/server/domain/types"; import { assertWithinCap, - isNoCaptions, STT_PROVIDER, transcribeAudio, } from "~/server/ingest/stt"; @@ -104,26 +103,37 @@ async function fetchMeta( } } -/** - * Fetch the captions, preferring English. YouTube exposes many caption tracks (including - * auto-translations), and the library's default can land on a non-English one — so we ask - * for English first and fall back to whatever the default track is if English is unavailable. - * - * Returns `undefined` only when captions genuinely do not exist (the STT trigger). Any other - * failure — rate limit, private/removed, network — rethrows: that video is `failed`, and a - * throttle can never turn into a paid transcription. - */ +/** Only a playable video with no caption tracks may use paid speech-to-text. */ async function fetchCaptions(videoId: string): Promise { - try { - const entries = await YoutubeTranscript.fetchTranscript(videoId, { lang: "en" }).catch( - () => YoutubeTranscript.fetchTranscript(videoId), + const info = await (await getInnertube()).getBasicInfo(videoId, { client: AUDIO_CLIENT }); + const playability = info.playability_status; + if (playability?.status !== "OK") { + throw new Error( + `${videoId}: YouTube player returned ${playability?.status ?? "UNKNOWN"}${playability?.reason ? ` (${playability.reason})` : ""}`, ); - const segments = toSeconds(entries); - return segments.length > 0 ? segments : undefined; + } + const tracks = info.captions?.caption_tracks; + const track = tracks?.find((item) => item.language_code === "en") ?? tracks?.[0]; + if (!track) return undefined; + + let httpFailure: string | undefined; + const transcriptFetch: typeof fetch = async (input, init) => { + const response = await fetch(input, init); + if (!response.ok) httpFailure = `HTTP ${response.status} at ${new URL(String(input)).pathname}`; + return response; + }; + let entries: TranscriptEntry[]; + try { + entries = await YoutubeTranscript.fetchTranscript(videoId, { + lang: track.language_code, + fetch: transcriptFetch, + }); } catch (error) { - if (isNoCaptions(error)) return undefined; + if (httpFailure) throw new Error(`${videoId}: caption retrieval returned ${httpFailure}`, { cause: error }); throw error; } + if (entries.length === 0) throw new Error(`${videoId}: caption track returned no text`); + return toSeconds(entries); } /** From 178b29dbeee7a32cb587efdde89f031c094247b1 Mon Sep 17 00:00:00 2001 From: Rishabh Singh Date: Fri, 25 Sep 2026 17:38:29 +0530 Subject: [PATCH 2/6] docs: add caption verification video --- .../evidence/issue-50-caption-verification.mp4 | Bin 0 -> 118516 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/evidence/issue-50-caption-verification.mp4 diff --git a/docs/evidence/issue-50-caption-verification.mp4 b/docs/evidence/issue-50-caption-verification.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..55c3ff381a86aeb446650799c9495dd2fb7f2ee2 GIT binary patch literal 118516 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�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Ò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

hP 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®KhWywh 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 ABme*a literal 0 HcmV?d00001 From c4f283e382a94871b272b6967d508ccd2ba71896 Mon Sep 17 00:00:00 2001 From: Rishabh Singh Date: Fri, 25 Sep 2026 18:48:21 +0530 Subject: [PATCH 3/6] fix(ingest): fetch hosted native captions with Supadata --- .env.example | 1 + README.md | 6 +++ src/env.js | 3 ++ src/server/ingest/channel.test.ts | 26 ++++++++++- src/server/ingest/channel.ts | 3 +- src/server/ingest/supadata.test.ts | 57 ++++++++++++++++++++++++ src/server/ingest/supadata.ts | 50 +++++++++++++++++++++ src/server/ingest/youtube-loader.test.ts | 32 ++++++++++++- src/server/ingest/youtube-loader.ts | 17 +++++-- src/workflows/channel-import.test.ts | 23 ++++++++++ src/workflows/channel-import.ts | 6 ++- 11 files changed, 215 insertions(+), 9 deletions(-) create mode 100644 src/server/ingest/supadata.test.ts create mode 100644 src/server/ingest/supadata.ts diff --git a/.env.example b/.env.example index 933256e..293bb76 100644 --- a/.env.example +++ b/.env.example @@ -33,6 +33,7 @@ EVAL_USER_ID="" # so a fresh checkout can never pay; flip it per run when you intend to use it. ASSEMBLYAI_API_KEY="" TRANSCRIBE_FALLBACK="false" +SUPADATA_API_KEY="" # Clerk — auth for the web app. Optional at build/typecheck time (see src/env.js) so a fresh # checkout builds without keys, but the authenticated app cannot run without them. diff --git a/README.md b/README.md index 096a3e2..3754f8c 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,12 @@ library unless ownership is assigned separately. Use the Sources page for the no AssemblyAI transcription is an opt-in fallback for videos without captions. Set `TRANSCRIBE_FALLBACK=true` only when you intend to use it. +For hosted imports, set `SUPADATA_API_KEY` on the server. Nexus requests existing +timestamped captions with Supadata's `mode=native` (one API credit per video); +it does not request Supadata AI transcription. Without a key, local runs fetch +captions directly from YouTube. Keep `TRANSCRIBE_FALLBACK=false` on Vercel while +YouTube blocks its audio downloads. + ## Quality checks ```bash diff --git a/src/env.js b/src/env.js index b9b1399..c1d07c1 100644 --- a/src/env.js +++ b/src/env.js @@ -55,6 +55,8 @@ export const env = createEnv({ TRANSCRIBE_FALLBACK: booleanFlag("false"), /** AssemblyAI key, direct — the AI Gateway does not route transcription. */ ASSEMBLYAI_API_KEY: z.string().optional(), + /** Hosted native YouTube captions for serverless imports. */ + SUPADATA_API_KEY: z.string().optional(), /** * Clerk secret key. Optional at build/typecheck time so a fresh checkout without Clerk * keys still builds and tests; the authed web app cannot actually run without it. Clerk's @@ -89,6 +91,7 @@ export const env = createEnv({ EVAL_USER_ID: process.env.EVAL_USER_ID, TRANSCRIBE_FALLBACK: process.env.TRANSCRIBE_FALLBACK, ASSEMBLYAI_API_KEY: process.env.ASSEMBLYAI_API_KEY, + SUPADATA_API_KEY: process.env.SUPADATA_API_KEY, CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, diff --git a/src/server/ingest/channel.test.ts b/src/server/ingest/channel.test.ts index 40ce8ff..86b8a05 100644 --- a/src/server/ingest/channel.test.ts +++ b/src/server/ingest/channel.test.ts @@ -1,4 +1,7 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; + +const mockEnv = vi.hoisted(() => ({ SUPADATA_API_KEY: undefined as string | undefined })); +vi.mock("~/env", () => ({ env: mockEnv })); import type { SourceLoader, SourceRef } from "~/server/domain/types"; import { IN_FLIGHT, ingestChannel, summarize } from "~/server/ingest/channel"; @@ -63,6 +66,27 @@ describe("ingestChannel — per-video isolation, discovery order", () => { expect(peak).toBe(IN_FLIGHT); }); + it("runs one video at a time when Supadata is configured", async () => { + mockEnv.SUPADATA_API_KEY = "test-key"; + let running = 0; + let peak = 0; + try { + await ingestChannel("@x", { + loader: loaderOf(["1", "2", "3"]), + ingest: async (r) => { + running++; + peak = Math.max(peak, running); + await new Promise((resolve) => setTimeout(resolve, 5)); + running--; + return ingestedResult(r); + }, + }); + expect(peak).toBe(1); + } finally { + mockEnv.SUPADATA_API_KEY = undefined; + } + }); + it("passes --limit through to discovery", async () => { const outcomes = await ingestChannel("@x", { limit: 2, diff --git a/src/server/ingest/channel.ts b/src/server/ingest/channel.ts index c649b40..9df362d 100644 --- a/src/server/ingest/channel.ts +++ b/src/server/ingest/channel.ts @@ -1,5 +1,6 @@ import pMap from "p-map"; +import { env } from "~/env"; import type { ChannelScope, SourceLoader, SourceRef } from "~/server/domain/types"; import type { IngestResult } from "~/server/ingest/pipeline"; @@ -27,7 +28,7 @@ export async function ingestChannel( return { status: "failed", ref, error }; } }, - { concurrency: IN_FLIGHT }, + { concurrency: env.SUPADATA_API_KEY ? 1 : IN_FLIGHT }, ); } diff --git a/src/server/ingest/supadata.test.ts b/src/server/ingest/supadata.test.ts new file mode 100644 index 0000000..4a76da4 --- /dev/null +++ b/src/server/ingest/supadata.test.ts @@ -0,0 +1,57 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { fetchSupadataCaptions } from "~/server/ingest/supadata"; + +afterEach(() => vi.unstubAllGlobals()); + +describe("Supadata native captions", () => { + it("requests existing captions only and converts milliseconds to seconds", async () => { + const fetchMock = vi.fn(async (_url: URL, _init: RequestInit) => Response.json({ + content: [ + { text: " Hello ", offset: 12500, duration: 2500, lang: "en" }, + { text: " ", offset: 15000, duration: 1000, lang: "en" }, + ], + lang: "en", + availableLangs: ["en"], + })); + vi.stubGlobal("fetch", fetchMock); + + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).resolves.toEqual([ + { text: "Hello", startSec: 12.5, endSec: 15 }, + ]); + const [url, init] = fetchMock.mock.calls[0]!; + expect(new URL(url).searchParams.get("mode")).toBe("native"); + expect(new URL(url).searchParams.get("url")).toBe("https://www.youtube.com/watch?v=5e37ZT3SQbk"); + expect(init.headers).toEqual({ "x-api-key": "secret" }); + }); + + it("reports unavailable captions without attempting AI generation", async () => { + vi.stubGlobal("fetch", vi.fn(async () => Response.json({ error: "transcript-unavailable" }, { status: 206 }))); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).resolves.toBeUndefined(); + }); + + it("does not accept an empty or malformed transcript as success", async () => { + vi.stubGlobal("fetch", vi.fn(async () => Response.json({ content: [{ text: " ", offset: 0, duration: 1000 }] }))); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).rejects.toThrow(/no text/); + vi.stubGlobal("fetch", vi.fn(async () => Response.json({ content: "wrong shape" }))); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).rejects.toThrow(/invalid response/); + }); + + it("surfaces provider authentication and quota errors", async () => { + vi.stubGlobal("fetch", vi.fn(async () => Response.json({ message: "bad key" }, { status: 401 }))); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).rejects.toThrow(/Supadata HTTP 401/); + }); + + it("retries a rate limit and then returns captions", async () => { + const fetchMock = vi.fn() + .mockResolvedValueOnce(new Response(null, { status: 429, headers: { "retry-after": "0" } })) + .mockResolvedValueOnce(Response.json({ content: [ + { text: "Recovered", offset: 0, duration: 1000 }, + ] })); + vi.stubGlobal("fetch", fetchMock); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).resolves.toEqual([ + { text: "Recovered", startSec: 0, endSec: 1 }, + ]); + expect(fetchMock).toHaveBeenCalledTimes(2); + }); +}); diff --git a/src/server/ingest/supadata.ts b/src/server/ingest/supadata.ts new file mode 100644 index 0000000..156bb36 --- /dev/null +++ b/src/server/ingest/supadata.ts @@ -0,0 +1,50 @@ +import { z } from "zod"; + +import type { Segment } from "~/server/domain/types"; + +const transcriptResponse = z.object({ + content: z.array(z.object({ + text: z.string(), + offset: z.number().nonnegative(), + duration: z.number().nonnegative(), + })), +}); + +/** Fetch only existing captions. `mode=native` never starts paid AI transcription. */ +export async function fetchSupadataCaptions( + videoId: string, + apiKey: string, +): Promise { + const url = new URL("https://api.supadata.ai/v1/transcript"); + url.searchParams.set("url", `https://www.youtube.com/watch?v=${videoId}`); + url.searchParams.set("lang", "en"); + url.searchParams.set("text", "false"); + url.searchParams.set("mode", "native"); + + let response: Response; + for (let attempt = 0; ; attempt++) { + response = await fetch(url, { headers: { "x-api-key": apiKey } }); + if (response.status !== 429 || attempt === 3) break; + const retryAfter = Number(response.headers.get("retry-after")); + const delayMs = Number.isFinite(retryAfter) && retryAfter > 0 + ? Math.min(retryAfter * 1000, 10_000) + : 1000 * (attempt + 1); + await new Promise((resolve) => setTimeout(resolve, delayMs)); + } + + if (response.status === 206) return undefined; + if (!response.ok) throw new Error(`${videoId}: Supadata HTTP ${response.status}`); + if (response.status === 202) throw new Error(`${videoId}: Supadata returned an asynchronous job for native captions`); + + const parsed = transcriptResponse.safeParse(await response.json()); + if (!parsed.success) throw new Error(`${videoId}: Supadata returned an invalid response`); + const segments = parsed.data.content + .filter((entry) => entry.text.trim()) + .map((entry) => ({ + text: entry.text.trim(), + startSec: entry.offset / 1000, + endSec: (entry.offset + entry.duration) / 1000, + })); + if (segments.length === 0) throw new Error(`${videoId}: Supadata caption track returned no text`); + return segments; +} diff --git a/src/server/ingest/youtube-loader.test.ts b/src/server/ingest/youtube-loader.test.ts index c042f76..0a5fd94 100644 --- a/src/server/ingest/youtube-loader.test.ts +++ b/src/server/ingest/youtube-loader.test.ts @@ -104,7 +104,7 @@ describe("toSeconds — unit normalization at the boundary", () => { // --------------------------------------------------------------------------------------------- const mocks = vi.hoisted(() => ({ - env: { TRANSCRIBE_FALLBACK: false, ASSEMBLYAI_API_KEY: "test-key" }, + env: { TRANSCRIBE_FALLBACK: false, ASSEMBLYAI_API_KEY: "test-key", SUPADATA_API_KEY: undefined as string | undefined }, fetchTranscript: vi.fn(), getBasicInfo: vi.fn(), download: vi.fn(), @@ -138,6 +138,7 @@ describe("loadTranscript — captions first, STT only behind every guard", () => beforeEach(() => { vi.clearAllMocks(); mocks.env.TRANSCRIBE_FALLBACK = false; + mocks.env.SUPADATA_API_KEY = undefined; mocks.getBasicInfo.mockResolvedValue({ playability_status: { status: "OK" }, captions: { @@ -217,4 +218,33 @@ describe("loadTranscript — captions first, STT only behind every guard", () => await expect(youtubeLoader.loadTranscript(ref)).rejects.toThrow(/caption track returned no text/); expect(mocks.transcribe).not.toHaveBeenCalled(); }); + + it("a whitespace-only caption track also fails", async () => { + mocks.fetchTranscript.mockResolvedValue([{ text: " ", offset: 0, duration: 1000 }]); + await expect(youtubeLoader.loadTranscript(ref)).rejects.toThrow(/caption track returned no text/); + }); + + it("uses Supadata without requesting the blocked YouTube player", async () => { + mocks.env.SUPADATA_API_KEY = "test-key"; + const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue(Response.json({ + content: [{ text: "Real caption", offset: 12500, duration: 2500 }], + })); + await expect(youtubeLoader.loadTranscript(ref)).resolves.toEqual({ + provenance: "captions", + segments: [{ text: "Real caption", startSec: 12.5, endSec: 15 }], + }); + expect(mocks.getBasicInfo).not.toHaveBeenCalled(); + expect(mocks.transcribe).not.toHaveBeenCalled(); + fetchSpy.mockRestore(); + }); + + it("reports missing Supadata captions without trying AssemblyAI", async () => { + mocks.env.SUPADATA_API_KEY = "test-key"; + mocks.env.TRANSCRIBE_FALLBACK = true; + const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue(Response.json({}, { status: 206 })); + await expect(youtubeLoader.loadTranscript(ref)).rejects.toThrow(/no native captions/); + expect(mocks.getBasicInfo).not.toHaveBeenCalled(); + expect(mocks.transcribe).not.toHaveBeenCalled(); + fetchSpy.mockRestore(); + }); }); diff --git a/src/server/ingest/youtube-loader.ts b/src/server/ingest/youtube-loader.ts index 3ef8e1e..13258c5 100644 --- a/src/server/ingest/youtube-loader.ts +++ b/src/server/ingest/youtube-loader.ts @@ -15,6 +15,7 @@ import { STT_PROVIDER, transcribeAudio, } from "~/server/ingest/stt"; +import { fetchSupadataCaptions } from "~/server/ingest/supadata"; type OEmbed = { title?: string; author_name?: string }; @@ -105,6 +106,9 @@ async function fetchMeta( /** Only a playable video with no caption tracks may use paid speech-to-text. */ async function fetchCaptions(videoId: string): Promise { + if (env.SUPADATA_API_KEY) { + return fetchSupadataCaptions(videoId, env.SUPADATA_API_KEY); + } const info = await (await getInnertube()).getBasicInfo(videoId, { client: AUDIO_CLIENT }); const playability = info.playability_status; if (playability?.status !== "OK") { @@ -132,8 +136,9 @@ async function fetchCaptions(videoId: string): Promise { if (httpFailure) throw new Error(`${videoId}: caption retrieval returned ${httpFailure}`, { cause: error }); throw error; } - if (entries.length === 0) throw new Error(`${videoId}: caption track returned no text`); - return toSeconds(entries); + const nonblank = entries.filter((entry) => entry.text.trim()); + if (nonblank.length === 0) throw new Error(`${videoId}: caption track returned no text`); + return toSeconds(nonblank); } /** @@ -301,7 +306,7 @@ export async function discoverYoutubeChannel( }; } -/** SourceLoader for YouTube: discovery via Innertube, captions via youtube-transcript. */ +/** SourceLoader for YouTube: discovery via Innertube, captions via Supadata when configured. */ export const youtubeLoader: SourceLoader = { async *discover(scope, { limit } = {}) { const { channel } = await loadChannel(scope); @@ -311,7 +316,11 @@ export const youtubeLoader: SourceLoader = { async loadTranscript(ref): Promise { const videoId = toVideoId(ref.externalId); const segments = await fetchCaptions(videoId); - return segments ? { segments, provenance: "captions" } : sttTranscript(videoId); + if (segments) return { segments, provenance: "captions" }; + if (env.SUPADATA_API_KEY) { + throw new Error(`${videoId}: Supadata found no native captions; AI transcription is not enabled`); + } + return sttTranscript(videoId); }, async loadMeta(ref): Promise { diff --git a/src/workflows/channel-import.test.ts b/src/workflows/channel-import.test.ts index 636fedf..4c5826e 100644 --- a/src/workflows/channel-import.test.ts +++ b/src/workflows/channel-import.test.ts @@ -1,5 +1,8 @@ import { describe, expect, it, vi } from "vitest"; +const mockEnv = vi.hoisted(() => ({ SUPADATA_API_KEY: undefined as string | undefined })); +vi.mock("~/env", () => ({ env: mockEnv })); + const workflow = vi.hoisted(() => { const dispose = vi.fn(); const getConflict = vi.fn(); @@ -59,6 +62,26 @@ describe("channel import orchestration", () => { expect(peak).toBe(IN_FLIGHT); }); + it("processes one video at a time with Supadata's rate limit", async () => { + mockEnv.SUPADATA_API_KEY = "test-key"; + let running = 0; + let peak = 0; + try { + await settleImportItems(items(4), { + process: async () => { + running++; + peak = Math.max(peak, running); + await new Promise((resolve) => setTimeout(resolve, 5)); + running--; + }, + fail: vi.fn(), + }); + expect(peak).toBe(1); + } finally { + mockEnv.SUPADATA_API_KEY = undefined; + } + }); + it("records one failure and continues later batches", async () => { const processed: string[] = []; const fail = vi.fn(); diff --git a/src/workflows/channel-import.ts b/src/workflows/channel-import.ts index d82853c..f5099d2 100644 --- a/src/workflows/channel-import.ts +++ b/src/workflows/channel-import.ts @@ -1,6 +1,7 @@ import { and, asc, eq, inArray, sql } from "drizzle-orm"; import { createHook, FatalError } from "workflow"; +import { env } from "~/env"; import { db } from "~/server/db"; import { channelImport, @@ -32,9 +33,10 @@ export async function settleImportItems( items: ImportWorkItem[], steps: ImportItemSteps, ): Promise { - for (let index = 0; index < items.length; index += IN_FLIGHT) { + const batchSize = env.SUPADATA_API_KEY ? 1 : IN_FLIGHT; + for (let index = 0; index < items.length; index += batchSize) { const results = await Promise.allSettled( - items.slice(index, index + IN_FLIGHT).map(async (item) => { + items.slice(index, index + batchSize).map(async (item) => { try { await steps.process(item); } catch (error) { From ec247600b40eb8f8ead958685e918b90bada118a Mon Sep 17 00:00:00 2001 From: Rishabh Singh Date: Fri, 25 Sep 2026 18:49:19 +0530 Subject: [PATCH 4/6] fix(ingest): let direct caption lookup select its track --- src/server/ingest/youtube-loader.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/server/ingest/youtube-loader.ts b/src/server/ingest/youtube-loader.ts index 13258c5..c17e963 100644 --- a/src/server/ingest/youtube-loader.ts +++ b/src/server/ingest/youtube-loader.ts @@ -117,8 +117,7 @@ async function fetchCaptions(videoId: string): Promise { ); } const tracks = info.captions?.caption_tracks; - const track = tracks?.find((item) => item.language_code === "en") ?? tracks?.[0]; - if (!track) return undefined; + if (!tracks?.length) return undefined; let httpFailure: string | undefined; const transcriptFetch: typeof fetch = async (input, init) => { @@ -128,10 +127,8 @@ async function fetchCaptions(videoId: string): Promise { }; let entries: TranscriptEntry[]; try { - entries = await YoutubeTranscript.fetchTranscript(videoId, { - lang: track.language_code, - fetch: transcriptFetch, - }); + // The library performs its own player lookup, so let it select from that lookup. + entries = await YoutubeTranscript.fetchTranscript(videoId, { fetch: transcriptFetch }); } catch (error) { if (httpFailure) throw new Error(`${videoId}: caption retrieval returned ${httpFailure}`, { cause: error }); throw error; From 26d583689f60a204b36391cc1021dda3f36cc5ab Mon Sep 17 00:00:00 2001 From: Rishabh Singh Date: Fri, 25 Sep 2026 19:50:44 +0530 Subject: [PATCH 5/6] fix(imports): limit channel imports to three videos --- src/server/api/routers/imports.test.ts | 2 +- src/server/domain/channel-import.ts | 2 +- src/server/imports/channel-import.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/server/api/routers/imports.test.ts b/src/server/api/routers/imports.test.ts index c047b01..05ff7d5 100644 --- a/src/server/api/routers/imports.test.ts +++ b/src/server/api/routers/imports.test.ts @@ -52,7 +52,7 @@ describe("imports router ownership boundary", () => { channelId: "UC123", creatorHandle: "creator", displayName: "Creator", - importLimit: 50, + importLimit: 3, }); await expect(caller("user-a").preview({ scope: " @creator " })).resolves.toMatchObject({ diff --git a/src/server/domain/channel-import.ts b/src/server/domain/channel-import.ts index f6a6b9b..cf23e7a 100644 --- a/src/server/domain/channel-import.ts +++ b/src/server/domain/channel-import.ts @@ -6,7 +6,7 @@ import type { export type ImportJobStatus = ChannelImport["status"]; export type ImportItemStatus = ChannelImportItem["status"]; -export const CHANNEL_IMPORT_LIMIT = 50; +export const CHANNEL_IMPORT_LIMIT = 3; export type ImportSummary = { discovered: number; diff --git a/src/server/imports/channel-import.test.ts b/src/server/imports/channel-import.test.ts index 9ccd9b1..6c013b6 100644 --- a/src/server/imports/channel-import.test.ts +++ b/src/server/imports/channel-import.test.ts @@ -79,7 +79,7 @@ describe("channel import launch", () => { channelId: "UC123", creatorHandle: "creator", displayName: "Creator Name", - importLimit: 50, + importLimit: 3, }); expect(mocks.discover).toHaveBeenCalledWith("@Creator", 1); expect(mocks.start).not.toHaveBeenCalled(); From ef0832f186748438c107e777f5d2b7e948732281 Mon Sep 17 00:00:00 2001 From: Rishabh Singh Date: Fri, 25 Sep 2026 20:07:02 +0530 Subject: [PATCH 6/6] fix(ingest): bound and retry Supadata caption requests --- src/server/ingest/supadata.test.ts | 58 +++++++++++++++++++- src/server/ingest/supadata.ts | 86 +++++++++++++++++++++--------- 2 files changed, 119 insertions(+), 25 deletions(-) diff --git a/src/server/ingest/supadata.test.ts b/src/server/ingest/supadata.test.ts index 4a76da4..2ecaa82 100644 --- a/src/server/ingest/supadata.test.ts +++ b/src/server/ingest/supadata.test.ts @@ -44,7 +44,7 @@ describe("Supadata native captions", () => { it("retries a rate limit and then returns captions", async () => { const fetchMock = vi.fn() - .mockResolvedValueOnce(new Response(null, { status: 429, headers: { "retry-after": "0" } })) + .mockResolvedValueOnce(new Response(null, { status: 429, headers: { "retry-after": "0.001" } })) .mockResolvedValueOnce(Response.json({ content: [ { text: "Recovered", offset: 0, duration: 1000 }, ] })); @@ -54,4 +54,60 @@ describe("Supadata native captions", () => { ]); expect(fetchMock).toHaveBeenCalledTimes(2); }); + + it("uses an abort deadline and retries a temporary server failure", async () => { + const fetchMock = vi.fn() + .mockResolvedValueOnce(new Response(null, { status: 503, headers: { "retry-after": "0.001" } })) + .mockResolvedValueOnce(Response.json({ content: [ + { text: "Available", offset: 1000, duration: 1000 }, + ] })); + vi.stubGlobal("fetch", fetchMock); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).resolves.toEqual([ + { text: "Available", startSec: 1, endSec: 2 }, + ]); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(fetchMock.mock.calls[0]![1].signal).toBeInstanceOf(AbortSignal); + }); + + it("retries a transient network failure without repeating authentication errors", async () => { + const fetchMock = vi.fn() + .mockRejectedValueOnce(new TypeError("fetch failed")) + .mockResolvedValueOnce(Response.json({ content: [ + { text: "Recovered", offset: 0, duration: 1000 }, + ] })); + vi.stubGlobal("fetch", fetchMock); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).resolves.toHaveLength(1); + expect(fetchMock).toHaveBeenCalledTimes(2); + }); + + it("polls an asynchronous native transcript job without resubmitting it", async () => { + const fetchMock = vi.fn() + .mockResolvedValueOnce(Response.json({ jobId: "job-1" }, { status: 202 })) + .mockResolvedValueOnce(Response.json({ status: "queued" })) + .mockResolvedValueOnce(Response.json({ status: "completed", content: [ + { text: "Later", offset: 2000, duration: 500 }, + ] })); + vi.stubGlobal("fetch", fetchMock); + await expect(fetchSupadataCaptions("5e37ZT3SQbk", "secret")).resolves.toEqual([ + { text: "Later", startSec: 2, endSec: 2.5 }, + ]); + expect(fetchMock).toHaveBeenCalledTimes(3); + expect(String(fetchMock.mock.calls[1]![0])).toBe("https://api.supadata.ai/v1/transcript/job-1"); + expect(String(fetchMock.mock.calls[2]![0])).toBe("https://api.supadata.ai/v1/transcript/job-1"); + }); + + it("stops a stalled request at the shared deadline", async () => { + const controller = new AbortController(); + const timeout = vi.spyOn(AbortSignal, "timeout").mockReturnValue(controller.signal); + vi.stubGlobal("fetch", vi.fn((_url: URL, init: RequestInit) => new Promise((_resolve, reject) => { + init.signal?.addEventListener("abort", () => reject(init.signal?.reason)); + }))); + try { + const pending = fetchSupadataCaptions("5e37ZT3SQbk", "secret"); + controller.abort(new DOMException("deadline", "TimeoutError")); + await expect(pending).rejects.toThrow(/Supadata request timed out/); + } finally { + timeout.mockRestore(); + } + }); }); diff --git a/src/server/ingest/supadata.ts b/src/server/ingest/supadata.ts index 156bb36..c21274c 100644 --- a/src/server/ingest/supadata.ts +++ b/src/server/ingest/supadata.ts @@ -1,3 +1,4 @@ +import { setTimeout as delay } from "node:timers/promises"; import { z } from "zod"; import type { Segment } from "~/server/domain/types"; @@ -9,42 +10,79 @@ const transcriptResponse = z.object({ duration: z.number().nonnegative(), })), }); +const jobStatus = z.object({ status: z.enum(["queued", "active", "completed", "failed"]) }); + +async function request(url: URL, apiKey: string, signal: AbortSignal): Promise { + for (let attempt = 0; attempt < 4; attempt++) { + let response: Response; + try { + response = await fetch(url, { headers: { "x-api-key": apiKey }, signal }); + } catch (error) { + if (signal.aborted || attempt === 3) throw error; + await delay(1000 * (attempt + 1), undefined, { signal }); + continue; + } + if ((response.status === 429 || response.status >= 500) && attempt < 3) { + const retryAfter = Number(response.headers.get("retry-after")); + const delayMs = Number.isFinite(retryAfter) && retryAfter > 0 + ? Math.min(retryAfter * 1000, 10_000) + : 1000 * (attempt + 1); + await delay(delayMs, undefined, { signal }); + continue; + } + return response; + } + throw new Error("Supadata retry limit reached"); +} /** Fetch only existing captions. `mode=native` never starts paid AI transcription. */ export async function fetchSupadataCaptions( videoId: string, apiKey: string, ): Promise { + const signal = AbortSignal.timeout(120_000); const url = new URL("https://api.supadata.ai/v1/transcript"); url.searchParams.set("url", `https://www.youtube.com/watch?v=${videoId}`); url.searchParams.set("lang", "en"); url.searchParams.set("text", "false"); url.searchParams.set("mode", "native"); - let response: Response; - for (let attempt = 0; ; attempt++) { - response = await fetch(url, { headers: { "x-api-key": apiKey } }); - if (response.status !== 429 || attempt === 3) break; - const retryAfter = Number(response.headers.get("retry-after")); - const delayMs = Number.isFinite(retryAfter) && retryAfter > 0 - ? Math.min(retryAfter * 1000, 10_000) - : 1000 * (attempt + 1); - await new Promise((resolve) => setTimeout(resolve, delayMs)); - } + try { + let response = await request(url, apiKey, signal); + if (response.status === 206) return undefined; + if (!response.ok) throw new Error(`${videoId}: Supadata HTTP ${response.status}`); + let payload: unknown = await response.json(); - if (response.status === 206) return undefined; - if (!response.ok) throw new Error(`${videoId}: Supadata HTTP ${response.status}`); - if (response.status === 202) throw new Error(`${videoId}: Supadata returned an asynchronous job for native captions`); + if (response.status === 202) { + const job = z.object({ jobId: z.string().min(1) }).safeParse(payload); + if (!job.success) throw new Error(`${videoId}: Supadata returned an invalid job ID`); + const jobUrl = new URL(`https://api.supadata.ai/v1/transcript/${encodeURIComponent(job.data.jobId)}`); + for (;;) { + response = await request(jobUrl, apiKey, signal); + if (response.status === 206) return undefined; + if (!response.ok) throw new Error(`${videoId}: Supadata job HTTP ${response.status}`); + payload = await response.json(); + const status = jobStatus.safeParse(payload); + if (!status.success) throw new Error(`${videoId}: Supadata returned an invalid job status`); + if (status.data.status === "completed") break; + if (status.data.status === "failed") throw new Error(`${videoId}: Supadata transcript job failed`); + await delay(1000, undefined, { signal }); + } + } - const parsed = transcriptResponse.safeParse(await response.json()); - if (!parsed.success) throw new Error(`${videoId}: Supadata returned an invalid response`); - const segments = parsed.data.content - .filter((entry) => entry.text.trim()) - .map((entry) => ({ - text: entry.text.trim(), - startSec: entry.offset / 1000, - endSec: (entry.offset + entry.duration) / 1000, - })); - if (segments.length === 0) throw new Error(`${videoId}: Supadata caption track returned no text`); - return segments; + const parsed = transcriptResponse.safeParse(payload); + if (!parsed.success) throw new Error(`${videoId}: Supadata returned an invalid response`); + const segments = parsed.data.content + .filter((entry) => entry.text.trim()) + .map((entry) => ({ + text: entry.text.trim(), + startSec: entry.offset / 1000, + endSec: (entry.offset + entry.duration) / 1000, + })); + if (segments.length === 0) throw new Error(`${videoId}: Supadata caption track returned no text`); + return segments; + } catch (error) { + if (signal.aborted) throw new Error(`${videoId}: Supadata request timed out`, { cause: error }); + throw error; + } }