Last active
August 5, 2025 07:48
-
-
Save patrickloeber/87a4c7ff615a9f3bb8874a332cceca90 to your computer and use it in GitHub Desktop.
AI SDK + Gemini market researcher example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { google } from "@ai-sdk/google"; | |
| import { z } from "zod"; | |
| import { generateText, generateObject } from "ai"; | |
| import "dotenv/config"; | |
| import puppeteer from "puppeteer"; | |
| import { ChartConfiguration } from "chart.js"; | |
| function createChartConfig({labels, data, label, type, colors,}: { | |
| labels: string[]; | |
| data: number[]; | |
| label: string; | |
| type: "bar" | "line"; | |
| colors: string[]; | |
| }): ChartConfiguration { | |
| return { | |
| type: type, | |
| data: { | |
| labels: labels, | |
| datasets: [ | |
| { | |
| label: label, | |
| data: data, | |
| borderWidth: 1, | |
| ...(type === "bar" && { backgroundColor: colors }), | |
| ...(type === "line" && colors.length > 0 && { borderColor: colors[0] }), | |
| }, | |
| ], | |
| }, | |
| options: { | |
| animation: { duration: 0 }, | |
| }, | |
| }; | |
| } | |
| async function main() { | |
| // Step 1: Search market trends | |
| const { text: marketTrends } = await generateText({ | |
| model: google("gemini-2.5-flash"), | |
| tools: { | |
| google_search: google.tools.googleSearch({}), | |
| }, | |
| prompt: `Search the web for market trends for plant-based milk in North America for 2024-2025. | |
| I need to know the market size, key players and their market share, and primary consumer drivers. | |
| `, | |
| }); | |
| console.log(marketTrends); | |
| // Step 2: Extract chart data | |
| const { object } = await generateObject({ | |
| model: google("gemini-2.5-flash"), | |
| schema: z.object({ | |
| chartConfigurations: z | |
| .array( | |
| z.object({ | |
| type: z.enum(["bar", "line"]).describe('The type of chart to generate. Either "bar" or "line"',), | |
| labels: z.array(z.string()).describe("A list of chart labels"), | |
| data: z.array(z.number()).describe("A list of the chart data"), | |
| label: z.string().describe("A label for the chart"), | |
| colors: z.array(z.string()).describe('A list of colors to use for the chart, e.g. "rgba(255, 99, 132, 0.8)"',), | |
| }), | |
| ) | |
| .describe("A list of chart configurations"), | |
| }), | |
| prompt: `Given the following market trends text, come up with a list of 1-3 meaningful bar or line charts | |
| and generate chart data. | |
| Market Trends: | |
| ${marketTrends} | |
| `, | |
| }); | |
| // Step 3: Create chart configs | |
| const chartConfigs = object.chartConfigurations.map((config) => | |
| createChartConfig(config), | |
| ); | |
| // Step 4: Write final HTML report | |
| const { text: html } = await generateText({ | |
| model: google("gemini-2.5-flash"), | |
| prompt: `You are an expert report writer. Combine the market trends and the chart data into one HTML report. | |
| Below is an example HTML code needed to generate one example graph. Use this snippet to create the charts: | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Chart</title> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <body> | |
| <div style="width: 800px; height: 600px;"> | |
| <canvas id="myChart"></canvas> | |
| </div> | |
| <script> | |
| const ctx = document.getElementById('myChart').getContext('2d'); | |
| new Chart(ctx, configuration); | |
| </script> | |
| </body> | |
| </html> | |
| Market Trends: | |
| ${marketTrends} | |
| Chart configurations: | |
| ${JSON.stringify(chartConfigs)} | |
| Return only the HTML code.`, | |
| }); | |
| // Step 5: Save report to PDF | |
| let finalHtml = html; | |
| if (finalHtml.startsWith("```html")) { | |
| finalHtml = finalHtml.substring(7); | |
| } | |
| if (finalHtml.endsWith("```")) { | |
| finalHtml = finalHtml.slice(0, -3); | |
| } | |
| const browser = await puppeteer.launch(); | |
| const page = await browser.newPage(); | |
| await page.setContent(finalHtml); | |
| await page.pdf({ path: "report.pdf", format: "A4" }); | |
| await browser.close(); | |
| } | |
| main().catch(console.error); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment