215 <div className="text-center mt-8 text-white/60 text-sm">
216 <p>
217 Powered by OpenAI • Built with ❤️ on Val Town
218 </p>
219 </div>
14```
15├── backend/
16│ └── index.ts # Main API server with OpenAI integration
17├── frontend/
18│ ├── index.html # Main application interface
33## Technology Stack
34
35- **Backend**: Hono + OpenAI API
36- **Frontend**: React + TailwindCSS
37- **AI**: GPT-4o-mini for concept explanations
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { OpenAI } from "https://esm.town/v/std/openai";
3import { readFile, serveFile } from "https://esm.town/v/std/utils@85-main/index.ts";
4import type { ConceptRequest, ConceptResponse, ErrorResponse } from "../shared/types.ts";
11});
12
13const openai = new OpenAI();
14
15// Serve static files
64Return only valid JSON without any markdown formatting.`;
65
66 const completion = await openai.chat.completions.create({
67 messages: [{ role: "user", content: prompt }],
68 model: "gpt-4o-mini",
73 const responseText = completion.choices[0]?.message?.content;
74 if (!responseText) {
75 throw new Error("No response from OpenAI");
76 }
77
81 conceptResponse = JSON.parse(responseText);
82 } catch (parseError) {
83 console.error("Failed to parse OpenAI response:", responseText);
84 throw new Error("Invalid response format from AI");
85 }
6
7- **URL Content Extraction**: Fetches and parses HTML content from URLs
8- **Text Summarization**: Uses OpenAI API to generate concise summaries
9- **Error Handling**: Comprehensive error handling for various failure scenarios
10- **Static File Serving**: Serves frontend assets and shared utilities
56## Environment Variables
57
58- `OPENAI_API_KEY` - Required for AI summarization
59
60## Error Handling
62The API handles various error scenarios:
63- Invalid URLs or unreachable content
64- OpenAI API failures
65- Malformed requests
66- Content too short to summarize
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { readFile, serveFile } from "https://esm.town/v/std/utils@85-main/index.ts";
3import { OpenAI } from "https://esm.town/v/std/openai";
4import type { AITextRequest, AITextResponse, MemeTemplate } from "../shared/types.ts";
5
80 try {
81 const request: AITextRequest = await c.req.json();
82 const openai = new OpenAI();
83
84 const prompt = `Generate funny meme text for a "${request.templateName}" meme template.
96Return ONLY a JSON object with "topText" and "bottomText" fields. No other text.`;
97
98 const completion = await openai.chat.completions.create({
99 messages: [
100 { role: "system", content: "You are a hilarious meme generator that creates viral-worthy meme text. Always respond with valid JSON only." },
40- **Backend**: Hono (TypeScript API framework)
41- **Frontend**: React with TypeScript
42- **AI**: OpenAI GPT for funny text generation
43- **Styling**: TailwindCSS
44- **Canvas**: HTML5 Canvas for meme generation
88Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
89
90### OpenAI
91
92```ts
93import { OpenAI } from "https://esm.town/v/std/openai";
94const openai = new OpenAI();
95const completion = await openai.chat.completions.create({
96 messages: [
97 { role: "user", content: "Say hello in a creative way" },
94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },
88Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
89
90### OpenAI
91
92```ts
93import { OpenAI } from "https://esm.town/v/std/openai";
94const openai = new OpenAI();
95const completion = await openai.chat.completions.create({
96 messages: [
97 { role: "user", content: "Say hello in a creative way" },
94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },