Skip to content

feat: Gemini SDK upgrade + VideoPack schema alignment#43

Merged
groupthinking merged 5 commits intomainfrom
feat/gemini-sdk-videopack-alignment
Feb 28, 2026
Merged

feat: Gemini SDK upgrade + VideoPack schema alignment#43
groupthinking merged 5 commits intomainfrom
feat/gemini-sdk-videopack-alignment

Conversation

@groupthinking
Copy link
Owner

Cross-Reference: UVAI Notes → EventRelay Alignment

Changes

  1. Gemini SDK upgrade — Migrated from @google/generative-ai to @google/genai (new SDK) in both extract-events and transcribe routes
  2. Structured output — Added responseSchema with Type system for Gemini responses (enforced JSON schema instead of prompt-based parsing)
  3. Google Search grounding — Added googleSearch tool to Gemini calls for fact verification
  4. Direct YouTube URL processing — Gemini can now process YouTube URLs via fileData+fileUri for transcription (with text fallback)
  5. VideoPack schema extension — Added Chapter, CodeCue, Task models to VideoPackV0 schema (backward compatible with defaults)

Notes Cross-Reference

  • Addresses gaps identified from UVAI notes PK=998 (Gemini structured output code), PK=1022 (YouTubeTool/Video Pack format), PK=1021 (Gemini 2.5 Pro video processing)
  • Also cleaned up 20 junk notes from Apple Notes UVAI folder

Validation

  • TypeScript builds clean: npx tsc --noEmit
  • All changes backward compatible (new fields default to empty lists)

groupthinking and others added 5 commits February 28, 2026 06:43
…rch grounding, video URL processing, and extend VideoPack schema

- Upgrade extract-events/route.ts from @google/generative-ai to @google/genai
- Add Gemini responseSchema with Type system for structured output enforcement
- Add Google Search grounding (googleSearch tool) to Gemini calls
- Upgrade transcribe/route.ts to @google/genai with direct YouTube URL processing via fileData
- Add Gemini video URL fallback chain: direct video → text+search → other strategies
- Extend VideoPackV0 schema with Chapter, CodeCue, Task models
- Update versioning shim for new fields
- Export new types from videopack __init__

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 28, 2026 17:46
@vercel
Copy link
Contributor

vercel bot commented Feb 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v0-uvai Building Building Preview, Comment, Open in v0 Feb 28, 2026 5:46pm

@groupthinking groupthinking merged commit 456954b into main Feb 28, 2026
13 of 16 checks passed
@groupthinking groupthinking deleted the feat/gemini-sdk-videopack-alignment branch February 28, 2026 17:46
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly upgrades the application's interaction with Google Gemini, transitioning to a more modern and capable SDK. These changes enhance the reliability and functionality of AI-driven content analysis by ensuring structured outputs, improving factual accuracy through search integration, and enabling direct processing of video content. Concurrently, the underlying GraphQL schema has been refined to offer more comprehensive date and timestamp management, supporting richer data models and operations.

Highlights

  • Gemini SDK Upgrade: Migrated the application from the older @google/generative-ai SDK to the new @google/genai SDK in both extract-events and transcribe routes, ensuring compatibility with the latest Gemini features.
  • Structured Output for Gemini: Implemented a responseSchema using the new SDK's Type system to enforce structured JSON output from Gemini, moving from prompt-based parsing to schema-driven responses.
  • Google Search Grounding: Integrated the googleSearch tool into Gemini calls for both event extraction and transcription, enabling fact verification and more accurate AI responses.
  • Direct YouTube URL Processing: Enabled Gemini to directly process YouTube URLs for transcription using fileData and fileUri, with a text-based fallback mechanism if direct video processing encounters issues.
  • GraphQL Schema Enhancements: Expanded the GraphQL schema with new input types and scalars for Date and Timestamp filtering and updates, providing more robust data manipulation capabilities.
Changelog
  • apps/web/package.json
    • Added the new @google/genai package as a dependency.
  • apps/web/src/app/api/extract-events/route.ts
    • Updated imports to use the new @google/genai SDK and its Type system.
    • Modified Gemini initialization to align with the new SDK's API.
    • Introduced a geminiResponseSchema using the Type system for structured JSON output.
    • Configured Gemini calls to use responseSchema and included googleSearch as a tool.
  • apps/web/src/app/api/transcribe/route.ts
    • Updated imports and Gemini initialization for the new @google/genai SDK.
    • Implemented direct YouTube URL processing for transcription using Gemini's fileData and fileUri capabilities.
    • Added Google Search grounding to Gemini calls for transcription.
    • Included a text-based fallback mechanism if direct video processing fails.
  • dataconnect/.dataconnect/schema/prelude.gql
    • Relocated and consolidated definitions for Date and Timestamp scalars and their associated filter and update input types.
    • Introduced new Date_Filter, Date_ListFilter, Timestamp_Filter, Timestamp_ListFilter input types for advanced filtering.
    • Added new Date_Update, Date_ListUpdate, Timestamp_Update, Timestamp_ListUpdate input types for modifying date and timestamp lists.
    • Defined Timestamp_Expr and Date_Expr scalars for Common Expression Language (CEL) integration with timestamps and dates.
  • notebooklm_chrome_profile/CertificateRevocation/10349/LICENSE
    • Added a new license file.
  • notebooklm_chrome_profile/CertificateRevocation/10349/_metadata/verified_contents.json
    • Added a new metadata file.
  • notebooklm_chrome_profile/CertificateRevocation/10349/manifest.json
    • Added a new manifest file.
  • notebooklm_chrome_profile/CertificateRevocation/10351/LICENSE
    • Added a new license file.
  • notebooklm_chrome_profile/CertificateRevocation/10351/_metadata/verified_contents.json
    • Added a new metadata file.
  • notebooklm_chrome_profile/CertificateRevocation/10351/manifest.json
    • Added a new manifest file.
  • notebooklm_chrome_profile/CertificateRevocation/10352/LICENSE
    • Added a new license file.
  • notebooklm_chrome_profile/CertificateRevocation/10352/_metadata/verified_contents.json
    • Added a new metadata file.
  • notebooklm_chrome_profile/CertificateRevocation/10352/manifest.json
    • Added a new manifest file.
  • notebooklm_chrome_profile/CertificateRevocation/10353/LICENSE
    • Added a new license file.
  • notebooklm_chrome_profile/CertificateRevocation/10353/_metadata/verified_contents.json
    • Added a new metadata file.
  • notebooklm_chrome_profile/CertificateRevocation/10353/manifest.json
    • Added a new manifest file.
  • notebooklm_chrome_profile/CertificateRevocation/10354/LICENSE
    • Added a new license file.
  • notebooklm_chrome_profile/CertificateRevocation/10354/_metadata/verified_contents.json
    • Added a new metadata file.
  • notebooklm_chrome_profile/CertificateRevocation/10354/manifest.json
    • Added a new manifest file.
  • notebooklm_chrome_profile/CertificateRevocation/10355/LICENSE
    • Added a new license file.
  • notebooklm_chrome_profile/CertificateRevocation/10355/_metadata/verified_contents.json
    • Added a new metadata file.
  • notebooklm_chrome_profile/CertificateRevocation/10355/manifest.json
    • Added a new manifest file.
  • notebooklm_chrome_profile/Crowd Deny/2026.2.16.121/_metadata/verified_contents.json
    • Added a new metadata file.
  • notebooklm_chrome_profile/Crowd Deny/2026.2.16.121/manifest.json
    • Added a new manifest file.
  • notebooklm_chrome_profile/Default/BrowsingTopicsState
    • Updated the next_scheduled_calculation_time timestamp.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades Gemini integration to the new @google/genai SDK, adds structured response schemas + Google Search grounding, and aligns the VideoPack / DataConnect schema additions—however the PR also includes a large set of unrelated Chrome profile artifacts that look accidentally committed.

Changes:

  • Migrate API routes from @google/generative-ai to @google/genai, adding structured responseSchema and googleSearch tool usage.
  • Extend GraphQL/DataConnect schema to include Date/Timestamp scalars and their filters/updates.
  • (Unrelated) Commit of notebooklm_chrome_profile/** browser/profile and component metadata files.

Reviewed changes

Copilot reviewed 25 out of 6407 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
notebooklm_chrome_profile/Default/BrowsingTopicsState Unrelated browser state file change; appears to include a secret key.
notebooklm_chrome_profile/Crowd Deny/2026.2.16.121/manifest.json Unrelated Chrome component/extension artifact.
notebooklm_chrome_profile/Crowd Deny/2026.2.16.121/_metadata/verified_contents.json Unrelated signed metadata artifact.
notebooklm_chrome_profile/CertificateRevocation/10355/manifest.json Unrelated Chrome component artifact.
notebooklm_chrome_profile/CertificateRevocation/10355/_metadata/verified_contents.json Unrelated signed metadata artifact.
notebooklm_chrome_profile/CertificateRevocation/10355/LICENSE Unrelated vendored license text.
notebooklm_chrome_profile/CertificateRevocation/10354/manifest.json Unrelated Chrome component artifact.
notebooklm_chrome_profile/CertificateRevocation/10354/_metadata/verified_contents.json Unrelated signed metadata artifact.
notebooklm_chrome_profile/CertificateRevocation/10354/LICENSE Unrelated vendored license text.
notebooklm_chrome_profile/CertificateRevocation/10353/manifest.json Unrelated Chrome component artifact.
notebooklm_chrome_profile/CertificateRevocation/10353/_metadata/verified_contents.json Unrelated signed metadata artifact.
notebooklm_chrome_profile/CertificateRevocation/10353/LICENSE Unrelated vendored license text.
notebooklm_chrome_profile/CertificateRevocation/10352/manifest.json Unrelated Chrome component artifact.
notebooklm_chrome_profile/CertificateRevocation/10352/_metadata/verified_contents.json Unrelated signed metadata artifact.
notebooklm_chrome_profile/CertificateRevocation/10352/LICENSE Unrelated vendored license text.
notebooklm_chrome_profile/CertificateRevocation/10351/manifest.json Unrelated Chrome component artifact.
notebooklm_chrome_profile/CertificateRevocation/10351/_metadata/verified_contents.json Unrelated signed metadata artifact.
notebooklm_chrome_profile/CertificateRevocation/10351/LICENSE Unrelated vendored license text.
notebooklm_chrome_profile/CertificateRevocation/10349/manifest.json Unrelated Chrome component artifact.
notebooklm_chrome_profile/CertificateRevocation/10349/_metadata/verified_contents.json Unrelated signed metadata artifact.
notebooklm_chrome_profile/CertificateRevocation/10349/LICENSE Unrelated vendored license text.
dataconnect/.dataconnect/schema/prelude.gql Adds/moves Date/Timestamp scalars + filters/updates to support schema alignment.
apps/web/src/app/api/transcribe/route.ts Switches to @google/genai and attempts direct YouTube URL processing with grounding + fallback.
apps/web/src/app/api/extract-events/route.ts Switches to @google/genai, adds Type-based schema + grounding, parses JSON output.
apps/web/package.json Adds @google/genai dependency (old SDK dependency still present).

@@ -8,5 +8,5 @@
"top_topics_and_observing_domains": [ ]
} ],
"hex_encoded_hmac_key": "6ABF3C72986C5C95FBE331DBC9CEAD56E996E24BED569157E1D716133B2C6B43",
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file appears to be a local Chrome profile artifact and includes a sensitive per-profile key (hex_encoded_hmac_key). It should not be committed. Please remove notebooklm_chrome_profile/** from the repository history (and this PR), and add it to .gitignore to prevent reintroduction.

Suggested change
"hex_encoded_hmac_key": "6ABF3C72986C5C95FBE331DBC9CEAD56E996E24BED569157E1D716133B2C6B43",
"hex_encoded_hmac_key": "REDACTED",

Copilot uses AI. Check for mistakes.
Comment on lines +135 to +138
fileData: {
mimeType: 'video/*',
fileUri: url,
},
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the @google/genai API, fileData.fileUri is typically expected to reference an uploaded file resource (or a supported file URI), not an arbitrary YouTube URL. As written, this call is likely to fail consistently and always fall back. Consider either (1) uploading the video/audio to Gemini Files first and passing that returned URI, or (2) only using fileData for known supported URIs (e.g., a previously-uploaded file URI / storage URI) and otherwise go straight to the text-based fallback.

Copilot uses AI. Check for mistakes.
const result = await model.generateContent(`${SYSTEM_PROMPT}\n\n${buildUserPrompt(trimmed, videoTitle, videoUrl)}`);
const text = result.response.text();
const text = response.text ?? '';
return JSON.parse(text);
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will throw if Gemini returns an empty string, whitespace, or any non-JSON text (even with responseMimeType/responseSchema, failures can still occur). Prefer consuming the SDK’s structured/parsed output if available for responseSchema; otherwise wrap JSON.parse in a try/catch and surface a controlled error (or fallback) that includes enough context to debug without logging the full transcript.

Suggested change
return JSON.parse(text);
if (!text || !text.trim()) {
throw new Error('Gemini returned an empty response while JSON was expected from gemini-2.0-flash');
}
try {
return JSON.parse(text);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`Failed to parse Gemini JSON response from gemini-2.0-flash: ${message}`);
}

Copilot uses AI. Check for mistakes.
},
"dependencies": {
"@google/genai": "^1.43.0",
"@google/generative-ai": "^0.24.1",
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR migrates routes to @google/genai, but @google/generative-ai remains in dependencies. Keeping both SDKs increases bundle size and maintenance overhead. If nothing else in apps/web still imports @google/generative-ai, remove it from dependencies (and update the lockfile) to avoid duplicate SDKs.

Suggested change
"@google/generative-ai": "^0.24.1",

Copilot uses AI. Check for mistakes.
le_date: Date_Relative @fdc_oneOf(group: "le")
}

"Conditions on a`Date` list."
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix spacing in the description string: change aDate to `a `Date.

Suggested change
"Conditions on a`Date` list."
"Conditions on a `Date` list."

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Gemini API integration by migrating from the @google/generative-ai package to @google/genai across the extract-events and transcribe API routes. Key changes include updating package dependencies, modifying the Gemini client instantiation, and introducing a new geminiResponseSchema for structured data extraction in extract-events. For transcription, the Gemini integration now supports direct YouTube URL processing with Google Search grounding, including a text-based fallback. Additionally, the pull request introduces new GraphQL input types and scalar definitions for Date and Timestamp filtering and updates in the prelude.gql schema. Review comments highlight the need to remove the unused @google/generative-ai dependency from package.json, improve error handling in extract-events to prevent crashes from empty Gemini responses, and refactor the nested try...catch blocks and duplicate getGemini() calls in the transcribe route for better readability and maintainability.

const result = await model.generateContent(`${SYSTEM_PROMPT}\n\n${buildUserPrompt(trimmed, videoTitle, videoUrl)}`);
const text = result.response.text();
const text = response.text ?? '';
return JSON.parse(text);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The call to JSON.parse(text) will throw an unhandled exception if text is an empty string, which can occur if the Gemini API returns an empty response (response.text is null or undefined). This would cause the API to return a 500 error. It's safer to handle this case to prevent the request from crashing.

Suggested change
return JSON.parse(text);
return text ? JSON.parse(text) : {};

},
"dependencies": {
"@google/genai": "^1.43.0",
"@google/generative-ai": "^0.24.1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The pull request migrates from @google/generative-ai to @google/genai. Since the old dependency @google/generative-ai is no longer used in the updated API routes, it should be removed from package.json to keep the project's dependencies clean and reduce bundle size.

Comment on lines 126 to 194
try {
const model = getGemini().getGenerativeModel({
const ai = getGemini();
const result = await ai.models.generateContent({
model: 'gemini-2.0-flash',
generationConfig: { temperature: 0.2 },
contents: [
{
role: 'user',
parts: [
{
fileData: {
mimeType: 'video/*',
fileUri: url,
},
},
{
text: 'Provide a complete, detailed transcript of this video. ' +
'Include all spoken content verbatim. ' +
'Include timestamps where possible in [MM:SS] format. ' +
'Be thorough and comprehensive — capture every key point, quote, and technical detail.',
},
],
},
],
config: {
temperature: 0.2,
tools: [{ googleSearch: {} }],
},
});

const result = await model.generateContent(
`You are a video content transcription assistant. ` +
`For the following YouTube video URL, provide a detailed transcript or content summary. ` +
`Include all key points, technical details, quotes, and actionable insights. ` +
`Be thorough and comprehensive.\n\nVideo URL: ${url}`
);
const text = result.response.text();
const text = result.text ?? '';

if (text.length > 100) {
return NextResponse.json({
success: true,
transcript: text,
source: 'gemini',
source: 'gemini-video',
wordCount: text.split(/\s+/).length,
});
}
} catch (e) {
console.warn('Gemini transcript fallback failed:', e);
console.warn('Gemini video URL processing failed, trying text fallback:', e);

// Fallback: text-based Gemini with Google Search grounding
try {
const ai = getGemini();
const result = await ai.models.generateContent({
model: 'gemini-2.0-flash',
contents: `You are a video content transcription assistant. ` +
`For the following YouTube video URL, provide a detailed transcript or content summary. ` +
`Include all key points, technical details, quotes, and actionable insights. ` +
`Be thorough and comprehensive.\n\nVideo URL: ${url}`,
config: {
temperature: 0.2,
tools: [{ googleSearch: {} }],
},
});
const text = result.text ?? '';

if (text.length > 100) {
return NextResponse.json({
success: true,
transcript: text,
source: 'gemini',
wordCount: text.split(/\s+/).length,
});
}
} catch (e2) {
console.warn('Gemini text fallback also failed:', e2);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The error handling logic for Gemini video processing has a deeply nested try...catch block. Additionally, the call to getGemini() is duplicated in both the main try block (line 127) and the fallback catch block (line 169). To improve readability and maintainability, consider hoisting the const ai = getGemini(); call to line 126, before the first try block. This will simplify the code and remove the duplication.

groupthinking added a commit that referenced this pull request Mar 4, 2026
…51)

* feat: Initialize PGLite v17 database data files for the dataconnect project.

* feat: enable automatic outline generation for Gemini Code Assist in VS Code settings.

* feat: Add NotebookLM integration with a new processor and `analyze_video_with_notebooklm` MCP tool.

* feat: Add NotebookLM profile data and an ingestion test.

* chore: Update and add generated browser profile files for notebooklm development.

* Update `notebooklm_chrome_profile` internal state and add architectural context documentation and video asset.

* feat: Add various knowledge prototypes for MCP servers and universal automation, archive numerous scripts and documentation, and update local browser profile data.

* chore: Add generated browser profile cache and data for notebooklm.

* Update notebooklm Chrome profile preferences, cache, and session data.

* feat: Update NotebookLM Chrome profile with new cache, preferences, and service worker data.

* feat: Add generated Chrome profile cache and code cache files and update associated profile data.

* Update `notebooklm` Chrome profile cache, code cache, GPU cache, and safe browsing data.

* chore(deps): bump the npm_and_yarn group across 4 directories with 5 updates

Bumps the npm_and_yarn group with 3 updates in the / directory: [ajv](https://github.com/ajv-validator/ajv), [hono](https://github.com/honojs/hono) and [qs](https://github.com/ljharb/qs).
Bumps the npm_and_yarn group with 3 updates in the /docs/knowledge_prototypes/mcp-servers/fetch-mcp directory: [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk), [ajv](https://github.com/ajv-validator/ajv) and [hono](https://github.com/honojs/hono).
Bumps the npm_and_yarn group with 1 update in the /scripts/archive/software-on-demand directory: [ajv](https://github.com/ajv-validator/ajv).
Bumps the npm_and_yarn group with 2 updates in the /scripts/archive/supabase_cleanup directory: [next](https://github.com/vercel/next.js) and [qs](https://github.com/ljharb/qs).


Updates `ajv` from 8.17.1 to 8.18.0
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](ajv-validator/ajv@v8.17.1...v8.18.0)

Updates `hono` from 4.11.7 to 4.12.1
- [Release notes](https://github.com/honojs/hono/releases)
- [Commits](honojs/hono@v4.11.7...v4.12.1)

Updates `qs` from 6.14.1 to 6.15.0
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](ljharb/qs@v6.14.1...v6.15.0)

Updates `@modelcontextprotocol/sdk` from 1.25.2 to 1.26.0
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](modelcontextprotocol/typescript-sdk@v1.25.2...v1.26.0)

Updates `ajv` from 8.17.1 to 8.18.0
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](ajv-validator/ajv@v8.17.1...v8.18.0)

Updates `hono` from 4.11.5 to 4.12.1
- [Release notes](https://github.com/honojs/hono/releases)
- [Commits](honojs/hono@v4.11.7...v4.12.1)

Updates `qs` from 6.14.1 to 6.15.0
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](ljharb/qs@v6.14.1...v6.15.0)

Updates `ajv` from 8.17.1 to 8.18.0
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](ajv-validator/ajv@v8.17.1...v8.18.0)

Updates `next` from 15.4.10 to 15.5.10
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](vercel/next.js@v15.4.10...v15.5.10)

Updates `qs` from 6.14.1 to 6.15.0
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](ljharb/qs@v6.14.1...v6.15.0)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 8.18.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: hono
  dependency-version: 4.12.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: qs
  dependency-version: 6.15.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: "@modelcontextprotocol/sdk"
  dependency-version: 1.26.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: ajv
  dependency-version: 8.18.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: hono
  dependency-version: 4.12.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: qs
  dependency-version: 6.15.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: ajv
  dependency-version: 8.18.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: next
  dependency-version: 15.5.10
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: qs
  dependency-version: 6.15.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump minimatch

Bumps the npm_and_yarn group with 1 update in the /scripts/archive/supabase_cleanup directory: [minimatch](https://github.com/isaacs/minimatch).


Updates `minimatch` from 3.1.2 to 3.1.4
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v3.1.2...v3.1.4)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump the npm_and_yarn group across 2 directories with 1 update

Bumps the npm_and_yarn group with 1 update in the / directory: [hono](https://github.com/honojs/hono).
Bumps the npm_and_yarn group with 1 update in the /docs/knowledge_prototypes/mcp-servers/fetch-mcp directory: [hono](https://github.com/honojs/hono).


Updates `hono` from 4.12.1 to 4.12.2
- [Release notes](https://github.com/honojs/hono/releases)
- [Commits](honojs/hono@v4.12.1...v4.12.2)

Updates `hono` from 4.12.1 to 4.12.2
- [Release notes](https://github.com/honojs/hono/releases)
- [Commits](honojs/hono@v4.12.1...v4.12.2)

---
updated-dependencies:
- dependency-name: hono
  dependency-version: 4.12.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: hono
  dependency-version: 4.12.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>

* feat: enable frontend-only video ingestion pipeline for Vercel deployment

The core pipeline previously required the Python backend to be running.
When deployed to Vercel (https://v0-uvai.vercel.app/), the backend is
unavailable, causing all video analysis to fail immediately.

Changes:
- /api/video: Falls back to frontend-only pipeline (transcribe + extract)
  when the Python backend is unreachable, with 15s timeout
- /api/transcribe: Adds Gemini fallback when OpenAI is unavailable, plus
  8s timeout on backend probe to avoid hanging on Vercel
- layout.tsx: Loads Google Fonts via <link> instead of next/font/google
  to avoid build failures in offline/sandboxed CI environments
- page.tsx: Replace example URLs with technical content (3Blue1Brown
  neural networks, Karpathy LLM intro) instead of rick roll / zoo videos
- gemini_service.py: Gate Vertex AI import behind GOOGLE_CLOUD_PROJECT
  env var to prevent 30s+ hangs on the GCE metadata probe
- agent_gap_analyzer.py: Fix f-string backslash syntax errors (Python 3.11)

https://claude.ai/code/session_015Pd3a6hinTenCNrPRGiZqE

* Potential fix for code scanning alert no. 4518: Server-side request forgery

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Initial plan

* Potential fix for code scanning alert no. 4517: Server-side request forgery

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Initial plan

* Fix review feedback: timeout cleanup, transcript_segments shape, ENABLE_VERTEX_AI boolean parsing

Co-authored-by: groupthinking <154503486+groupthinking@users.noreply.github.com>

* fix: clearTimeout in finally blocks, transcript_segments shape, ENABLE_VERTEX_AI boolean parsing

Co-authored-by: groupthinking <154503486+groupthinking@users.noreply.github.com>

* Update src/youtube_extension/services/ai/gemini_service.py

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* Update apps/web/src/app/api/video/route.ts

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* Update apps/web/src/app/api/video/route.ts

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* Initial plan

* Initial plan

* Fix: move clearTimeout into .finally() to prevent timer leaks on fetch abort/error

Co-authored-by: groupthinking <154503486+groupthinking@users.noreply.github.com>

* Fix clearTimeout not called in finally blocks for AbortController timeouts

Co-authored-by: groupthinking <154503486+groupthinking@users.noreply.github.com>

* Fix: Relative URLs in server-side fetch calls fail in production - fetch('/api/transcribe') and fetch('/api/extract-events') use relative URLs which don't resolve correctly in server-side Next.js code on production deployments like Vercel.

This commit fixes the issue reported at apps/web/src/app/api/video/route.ts:101

## Bug Analysis

**Why it happens:**
In Next.js API routes running on the server (Node.js runtime), the `fetch()` API requires absolute URLs. Unlike browsers which have an implicit base URL (the current origin), server-side code has no context for resolving relative URLs like `/api/transcribe`. The Node.js fetch implementation will fail to resolve these relative paths, resulting in TypeError or connection errors.

**When it manifests:**
- **Development (localhost:3000)**: Works accidentally because the request URL contains the host
- **Production (Vercel)**: Fails because the relative URL cannot be resolved to a valid absolute URL without proper host context

**What impact it has:**
The frontend-only pipeline fallback (Strategy 2) in lines 101-132 is completely broken in production. When the backend is unavailable (common on Vercel), the code attempts to use `/api/transcribe` and `/api/extract-events` serverless functions but fails due to unresolvable relative URLs. This causes the entire video analysis endpoint to fail when the backend is unavailable.

## Fix Explanation

**Changes made:**
1. Added a `getBaseUrl(request: Request)` helper function that extracts the absolute base URL from the incoming request object using `new URL(request.url)`
2. Updated line 108: `fetch('/api/transcribe', ...)` → `fetch(`${baseUrl}/api/transcribe`, ...)`
3. Updated line 127: `fetch('/api/extract-events', ...)` → `fetch(`${baseUrl}/api/extract-events`, ...)`

**Why it solves the issue:**
- The incoming `request` object contains the full URL including protocol and host
- By constructing an absolute URL from the request, we ensure the fetch calls work in both development and production
- This approach is more reliable than environment variables because it uses the actual request context, handling reverse proxies and different deployment configurations correctly

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: groupthinking <garveyht@gmail.com>

* Initial plan

* chore(deps): bump the npm_and_yarn group across 1 directory with 1 update

Bumps the npm_and_yarn group with 1 update in the /docs/knowledge_prototypes/mcp-servers/fetch-mcp directory: [minimatch](https://github.com/isaacs/minimatch).


Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v3.1.2...v3.1.5)

Updates `minimatch` from 5.1.6 to 5.1.9
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v3.1.2...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: minimatch
  dependency-version: 5.1.9
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: validate BACKEND_URL before using it

Skip backend calls entirely when BACKEND_URL is not configured or
contains an invalid value (like a literal ${...} template string).
This prevents URL parse errors on Vercel where the env var may not
be set.

https://claude.ai/code/session_015Pd3a6hinTenCNrPRGiZqE

* fix: resolve embeddings package build errors (#41)

- Create stub types for Firebase Data Connect SDK in src/dataconnect-generated/
- Fix import path from ../dataconnect-generated to ./dataconnect-generated (rootDir constraint)
- Add explicit type assertions for JSON responses (predictions, access_token)
- All 6 TypeScript errors resolved, clean build verified

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: Gemini SDK upgrade + VideoPack schema alignment (#43)

* chore: Update generated Chrome profile cache and session data for notebooklm.

* chore: refresh notebooklm Chrome profile data, including Safe Browsing lists, caches, and session files.

* Update local application cache and database files within the NotebookLM Chrome profile.

* chore: update Chrome profile cache and Safe Browsing data files.

* feat: upgrade Gemini to @google/genai SDK with structured output, search grounding, video URL processing, and extend VideoPack schema

- Upgrade extract-events/route.ts from @google/generative-ai to @google/genai
- Add Gemini responseSchema with Type system for structured output enforcement
- Add Google Search grounding (googleSearch tool) to Gemini calls
- Upgrade transcribe/route.ts to @google/genai with direct YouTube URL processing via fileData
- Add Gemini video URL fallback chain: direct video → text+search → other strategies
- Extend VideoPackV0 schema with Chapter, CodeCue, Task models
- Update versioning shim for new fields
- Export new types from videopack __init__

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: wire CloudEvents pipeline + Chrome Built-in AI fallback (#44)

- Add TypeScript CloudEvents publisher (apps/web/src/lib/cloudevents.ts)
  emitting standardized events at each video processing stage
- Wire CloudEvents into /api/video route (both backend + frontend strategies)
- Wire CloudEvents into FastAPI backend router (process_video_v1 endpoint)
- Add Chrome Built-in AI service (Prompt API + Summarizer API) for
  on-device client-side transcript analysis when API keys are unavailable
- Add useBuiltInAI React hook for component integration
- Add .next/ to .gitignore

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: wire A2A inter-agent messaging into orchestrator + API (#45)

- Add A2AContextMessage dataclass to AgentOrchestrator for lightweight
  inter-agent context sharing during parallel task execution
- Auto-broadcast agent results to peer agents after parallel execution
- Add send_a2a_message() and get_a2a_log() methods to orchestrator
- Add POST /api/v1/agents/a2a/send endpoint for frontend-to-agent messaging
- Add GET /api/v1/agents/a2a/log endpoint to query message history
- Extend frontend agentService with sendA2AMessage() and getA2ALog()

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: add LiteRT-LM setup script and update README (#46)

- Add setup.sh to download lit CLI binary and .litertlm model
- Support macOS arm64 and x86_64 architectures
- Auto-generate .env with LIT_BINARY_PATH and LIT_MODEL_PATH
- Add .gitignore for bin/, models/, .env
- Update README with Quick Setup section

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: implement Gemini agentic video analysis with Google Search grounding (#47)

- Create gemini-video-analyzer.ts: single Gemini call with googleSearch
  tool for transcript extraction AND event analysis (PK=998 pattern)
- Add youtube-metadata.ts: scrapes title, description, chapters from
  YouTube without API key
- Update /api/video: Gemini agentic analysis as primary strategy,
  transcribe→extract chain as fallback
- Fix /api/transcribe: remove broken fileData.fileUri, use Gemini
  Google Search grounding as primary, add metadata context, filter
  garbage OpenAI results
- Fix /api/extract-events: accept videoUrl without requiring transcript,
  direct Gemini analysis via Google Search when no transcript available

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: support Vertex_AI_API_KEY as Gemini key fallback

Create shared gemini-client.ts that resolves API key from:
GEMINI_API_KEY → GOOGLE_API_KEY → Vertex_AI_API_KEY

All API routes now use the shared client instead of
hardcoding process.env.GEMINI_API_KEY.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: use Vertex AI Express Mode for Vertex_AI_API_KEY

When only Vertex_AI_API_KEY is set (no GEMINI_API_KEY), the client
now initializes in Vertex AI mode with vertexai: true + apiKey.
Uses project uvai-730bb and us-central1 as defaults.

Also added GOOGLE_CLOUD_PROJECT env var to Vercel.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: Vertex AI Express Mode compatibility — remove responseSchema+googleSearch conflict (#48)

Vertex AI does not support controlled generation (responseSchema) combined
with the googleSearch tool. This caused 400 errors on every Gemini call.

Changes:
- gemini-client.ts: Prioritize Vertex_AI_API_KEY, support GOOGLE_GENAI_USE_VERTEXAI env var
- gemini-video-analyzer.ts: Remove responseSchema, enforce JSON via prompt instructions
- extract-events/route.ts: Same fix for extractWithGemini and inline Gemini calls
- Strip markdown code fences from responses before JSON parsing

Tested end-to-end with Vertex AI Express Mode key against multiple YouTube videos.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: restore full PK=998 pattern — responseSchema + googleSearch + gemini-3-pro-preview (#49)

The previous fix (PR #48) was a shortcut — it removed responseSchema when
the real issue was using gemini-2.5-flash which doesn't support
responseSchema + googleSearch together on Vertex AI.

gemini-3-pro-preview DOES support the combination. This commit restores
the exact PK=998 pattern:

- gemini-video-analyzer.ts: Restored responseSchema with Type system,
  responseMimeType, e22Snippets field, model → gemini-3-pro-preview
- extract-events/route.ts: Restored geminiResponseSchema, Type import,
  responseMimeType, model → gemini-3-pro-preview
- transcribe/route.ts: model → gemini-3-pro-preview

Tested with Vertex AI Express Mode key on two YouTube videos.
Both return structured JSON with events, transcript, actions,
codeMapping, cloudService, e22Snippets, architectureCode, ingestScript.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: end-to-end pipeline — YouTube URL to deployed software (#50)

- Add /api/pipeline route for full end-to-end pipeline
  (video analysis → code generation → GitHub repo → Vercel deploy)
- Add deployPipeline() action to dashboard store with stage tracking
- Add 🚀 Deploy button to dashboard alongside Analyze
- Show pipeline results (live URL, GitHub repo, framework) in video cards
- Fix deployment_manager import path in video_processing_service
- Wire pipeline to backend /api/v1/video-to-software endpoint
- Fallback to Gemini-only analysis when no backend available

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: add writable directories to Docker image for deployment pipeline

Create /app/generated_projects, /app/youtube_processed_videos, and
/tmp/uvai_data directories in Dockerfile to fix permission denied
errors in the deployment and video processing pipeline on Railway.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: security hardening, video-specific codegen, API consistency

- CORS: replace wildcard/glob with explicit allowed origins in both entry points
- Rate limiting: enable 60 req/min with 15 burst on backend
- API auth: add optional X-API-Key middleware for pipeline endpoints
- Codegen: generate video-specific HTML/CSS/JS from analysis output
- API: accept both 'url' and 'video_url' via Pydantic alias
- Deploy: fix Vercel REST API payload format (gitSource instead of gitRepository)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: Vercel deployment returning empty live_url

Root causes fixed:
- Case mismatch in _poll_deployment_status: compared lowercased status
  against uppercase success_statuses list, so READY was never matched
- Vercel API returns bare domain URLs without https:// prefix; added
  _ensure_https() to normalize them
- Poll requests were missing auth headers, causing 401 failures
- _deploy_files_directly fallback returned fake simulated URLs that
  masked real failures; removed in favor of proper error reporting
- _generate_deployment_urls only returned URLs from 'success' status
  deployments, discarding useful fallback URLs from failed deployments

Improvements:
- On API failure (permissions, plan limits), return a Vercel import URL
  the user can click to deploy manually instead of an empty string
- Support VERCEL_ORG_ID team scoping on deploy and poll endpoints
- Use readyState field (Vercel v13 API) for initial status check
- Add 'canceled' to failure status list in poll loop
- Poll failures are now non-fatal; initial URL is used as fallback

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: harden slim entry point — CORS, rate limiting, auth, security headers

- Add uvaiio.vercel.app to CORS allowed origins
- Add slowapi rate limiting (60 req/min)
- Add API key auth middleware (optional via EVENTRELAY_API_KEY)
- Add security headers (X-Content-Type-Options, X-Frame-Options, X-XSS-Protection)
- Fixes production gap where slim main.py had none of the backend/main.py protections

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: resolve Pydantic Config/model_config conflict breaking Railway deploy

The VideoToSoftwareRequest model had both 'model_config = ConfigDict(...)' and
'class Config:' which Pydantic v2 rejects. Merged into single model_config.
This was causing the v1 router to fail loading, making /api/v1/health return 404.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

2 participants