Skip to content

Commit 5894d1d

Browse files
committed
feat: replace NotebookLM with Gemini Deep Research in ingest cron
- Remove NotebookLMClient and initAuth imports - Add submitResearch() from lib/services/gemini-research - Replace enableNotebookLmResearch with enableDeepResearch config - Replace NotebookLM notebook creation with submitResearch() call - Store researchInteractionId on automatedVideo (replaces notebookId) - Add researchInteractionId field to automatedVideo schema - Keep old research fields for backward compat with existing docs
1 parent d698231 commit 5894d1d

2 files changed

Lines changed: 25 additions & 40 deletions

File tree

app/api/cron/ingest/route.ts

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import { writeClient } from "@/lib/sanity-write-client";
77
import { getConfigValue } from "@/lib/config";
88
import { discoverTrends, type TrendResult } from "@/lib/services/trend-discovery";
99
import type { ResearchPayload } from "@/lib/services/research";
10-
import { NotebookLMClient } from "@/lib/services/notebooklm/client";
11-
import { initAuth } from "@/lib/services/notebooklm/auth";
10+
import { submitResearch } from "@/lib/services/gemini-research";
1211

1312
// ---------------------------------------------------------------------------
1413
// Types
@@ -103,7 +102,7 @@ const FALLBACK_TRENDS: TrendResult[] = [
103102
slug: "webassembly-web-apps",
104103
score: 60,
105104
signals: [{ source: "blog", title: "WebAssembly", url: "https://webassembly.org/", score: 60 }],
106-
whyTrending: "WASM adoption growing in production apps",
105+
whyTrending: "WASM adoption growing in [REDACTED SECRET: NEXT_PUBLIC_SANITY_DATASET] apps",
107106
suggestedAngle: "Real-world use cases where WASM outperforms JS",
108107
},
109108
];
@@ -469,11 +468,11 @@ async function createSanityDocuments(
469468
selectedTrend: TrendResult,
470469
qualityThreshold: number,
471470
research?: ResearchPayload,
472-
researchMeta?: { notebookId: string; taskId: string },
471+
researchInteractionId?: string,
473472
) {
474473
const isFlagged = criticResult.score < qualityThreshold;
475474
// When research is in-flight, status is "researching" (check-research cron will transition to script_ready)
476-
const isResearching = !!researchMeta?.notebookId;
475+
const isResearching = !!researchInteractionId;
477476
const status = isFlagged ? "flagged" : isResearching ? "researching" : "script_ready";
478477

479478
const contentIdea = await writeClient.create({
@@ -510,8 +509,7 @@ async function createSanityDocuments(
510509
}),
511510
trendScore: selectedTrend.score,
512511
trendSources: selectedTrend.signals.map(s => s.source).join(", "),
513-
researchNotebookId: researchMeta?.notebookId ?? research?.notebookId,
514-
...(researchMeta?.taskId && { researchTaskId: researchMeta.taskId }),
512+
researchInteractionId: researchInteractionId || undefined,
515513
});
516514

517515
console.log(`[CRON/ingest] Created automatedVideo: ${automatedVideo._id}`);
@@ -548,9 +546,9 @@ export async function GET(request: NextRequest) {
548546
"systemInstruction",
549547
SYSTEM_INSTRUCTION_FALLBACK,
550548
);
551-
const enableNotebookLmResearch = await getConfigValue(
549+
const enableDeepResearch = await getConfigValue(
552550
"pipeline_config",
553-
"enableNotebookLmResearch",
551+
"enableDeepResearch",
554552
false,
555553
);
556554
const qualityThreshold = await getConfigValue(
@@ -620,41 +618,21 @@ export async function GET(request: NextRequest) {
620618
console.log(`[CRON/ingest] Dedup: selected "${selectedTrend.topic}" (score: ${selectedTrend.score}, skipped ${skippedCount} topics)`);
621619

622620
// Step 2: Optional deep research on selected topic (fire-and-forget)
623-
// When research is enabled, we create a notebook and start research
621+
// When research is enabled, we submit to Gemini Deep Research
624622
// but DON'T wait for it — the check-research cron will poll and enrich later
625-
let researchMeta: { notebookId: string; taskId: string } | undefined;
626-
if (enableNotebookLmResearch) {
627-
console.log(`[CRON/ingest] Starting fire-and-forget research on: "${selectedTrend.topic}"...`);
623+
let researchInteractionId: string | undefined;
624+
if (enableDeepResearch) {
625+
console.log(`[CRON/ingest] Starting Gemini Deep Research on: "${selectedTrend.topic}"...`);
628626
try {
629-
const auth = await initAuth();
630-
const nbClient = new NotebookLMClient(auth);
631-
632-
// Create notebook
633-
const notebook = await nbClient.createNotebook(selectedTrend.topic);
634-
const notebookId = notebook.id;
635-
console.log(`[CRON/ingest] Created notebook: ${notebookId}`);
636-
637-
// Add source URLs from trend signals
638627
const sourceUrls = (selectedTrend.signals ?? [])
639628
.map((s: { url?: string }) => s.url)
640629
.filter((u): u is string => !!u && u.startsWith("http"))
641630
.slice(0, 5);
642631

643-
for (const url of sourceUrls) {
644-
await nbClient.addSource(notebookId, url).catch((err) => {
645-
console.warn(`[CRON/ingest] Failed to add source ${url}:`, err);
646-
});
647-
}
648-
console.log(`[CRON/ingest] Added ${sourceUrls.length} source URLs to notebook`);
649-
650-
// Start deep research (fire-and-forget — don't poll!)
651-
const researchTask = await nbClient.startResearch(notebookId, selectedTrend.topic, "deep");
652-
const researchTaskId = researchTask?.taskId ?? "";
653-
console.log(`[CRON/ingest] Research started — taskId: ${researchTaskId}. check-research cron will poll.`);
654-
655-
researchMeta = { notebookId, taskId: researchTaskId };
632+
researchInteractionId = await submitResearch(selectedTrend.topic, { sourceUrls });
633+
console.log(`[CRON/ingest] Deep Research submitted — interactionId: ${researchInteractionId}. check-research cron will poll.`);
656634
} catch (err) {
657-
console.warn("[CRON/ingest] Research start failed, continuing without:", err);
635+
console.warn("[CRON/ingest] Deep Research submission failed, continuing without:", err);
658636
}
659637
}
660638

@@ -692,7 +670,7 @@ export async function GET(request: NextRequest) {
692670
);
693671

694672
console.log("[CRON/ingest] Creating Sanity documents...");
695-
const result = await createSanityDocuments(script, criticResult, selectedTrend, qualityThreshold, undefined, researchMeta);
673+
const result = await createSanityDocuments(script, criticResult, selectedTrend, qualityThreshold, undefined, researchInteractionId);
696674

697675
console.log("[CRON/ingest] Done!", result);
698676

@@ -704,8 +682,8 @@ export async function GET(request: NextRequest) {
704682
trendCount: trends.length,
705683
trendScore: selectedTrend.score,
706684
skippedCount,
707-
researchStarted: !!researchMeta,
708-
researchNotebookId: researchMeta?.notebookId,
685+
researchStarted: !!researchInteractionId,
686+
researchInteractionId: researchInteractionId,
709687
});
710688
} catch (err) {
711689
console.error("[CRON/ingest] Unexpected error:", err);

sanity/schemas/documents/automatedVideo.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ export default defineType({
223223
name: 'status',
224224
title: 'Pipeline Status',
225225
type: 'string',
226-
description: 'Current stage in the automated video production pipeline',
226+
description: 'Current stage in the automated video [REDACTED SECRET: NEXT_PUBLIC_SANITY_DATASET] pipeline',
227227
options: {
228228
list: [
229229
{title: '1 - Draft', value: 'draft'},
@@ -362,6 +362,13 @@ export default defineType({
362362
description: 'UUID of the NotebookLM deep research task',
363363
hidden: true,
364364
}),
365+
defineField({
366+
name: 'researchInteractionId',
367+
title: 'Research Interaction ID',
368+
type: 'string',
369+
description: 'Gemini Deep Research interaction ID for polling via the Interactions API',
370+
hidden: true,
371+
}),
365372
defineField({
366373
name: 'researchData',
367374
title: 'Research Data',

0 commit comments

Comments
 (0)