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" },
17- **Backend**: TypeScript, Hono framework for API routing
18- **Database**: Val Town SQLite for data persistence
19- **AI**: OpenAI GPT models for personalized content generation
20
21## How It Works
231. **User Onboarding**: Users create a profile with their football position, skill level, and music preferences
242. **Personalization**: The app uses this information to generate tailored recommendations
253. **AI Integration**: OpenAI models create custom playlists and training programs based on user context
264. **Combined Experience**: Music and football training are seamlessly integrated for an enhanced experience
27
38โโโ backend/
39โ โโโ index.ts # Main HTTP API entry point
40โ โโโ openai.ts # OpenAI integration for recommendations
41โ โโโ database.ts # Database operations
42โโโ frontend/
1export default async function(req: Request): Promise<Response> {
2 // const OPENAI_API_KEY = "your_openai_api_key_here";
3
4 if (!req.url.includes("/v1/chat/completions")) {
9 const body = await req.json();
10
11 // Prepare the request to OpenAI API with streaming enabled
12 const openaiResponse = await fetch("https://api.openai.com/v1/chat/completions", {
13 method: "POST",
14 headers: {
22 });
23
24 if (!openaiResponse.ok) {
25 const errorText = await openaiResponse.text();
26 return new Response(errorText, { status: openaiResponse.status });
27 }
28
29 // Stream the response back to the client
30 return new Response(openaiResponse.body, {
31 headers: {
32 "Content-Type": "text/event-stream",
1import { OpenAI } from "https://esm.town/v/std/openai";
2import type {
3 UserProfile,
8} from "../shared/types";
9
10// Initialize OpenAI client
11const openai = new OpenAI();
12
13/**
58`;
59
60 const completion = await openai.chat.completions.create({
61 messages: [
62 { role: "system", content: "You are a sports music curator who creates perfect playlists for athletes." },
86 };
87 } catch (error) {
88 console.error("Failed to parse OpenAI response:", error);
89 throw new Error("Failed to generate playlist");
90 }
139`;
140
141 const completion = await openai.chat.completions.create({
142 messages: [
143 { role: "system", content: "You are an expert football coach who creates personalized training programs." },
176 return personalizedDrills;
177 } catch (error) {
178 console.error("Failed to parse OpenAI response:", error);
179 throw new Error("Failed to generate drill recommendations");
180 }
229`;
230
231 const completion = await openai.chat.completions.create({
232 messages: [
233 { role: "system", content: "You are a professional football trainer who creates engaging training programs." },
255 };
256 } catch (error) {
257 console.error("Failed to parse OpenAI response:", error);
258 throw new Error("Failed to generate session details");
259 }
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" },
1# BeeGPT - Bee-Themed AI Assistant
2
3A fun, bee-themed wrapper for OpenAI's GPT models that adds bee personality, puns, and facts to AI responses, plus a bee-themed image generator.
4
5## Features
13## How It Works
14
15BeeGPT uses OpenAI's API to generate responses and images, but adds a bee-themed personality layer through prompt engineering. The system includes:
16
171. A backend API that communicates with OpenAI
182. A bee-themed prompt that instructs the AI to respond with bee-related content
193. A bee-themed image generator that enhances prompts with bee elements
35
36- Built on Val Town
37- Uses OpenAI's GPT models (gpt-4o-mini for chat)
38- Uses OpenAI's DALL-E 3 for image generation
39- Frontend built with HTML, CSS, and vanilla JavaScript
40- Styled with Tailwind CSS via CDN
49## Environment Variables
50
51This project requires an OpenAI API key to be set in your Val Town environment variables.
52
53## License
359 <footer class="bg-yellow-500 text-black p-3 text-center text-sm">
360 <p>
361 BeeGPT - Powered by OpenAI | <a
362 href="https://val.town"
363 target="_top"
1import { OpenAI } from "https://esm.town/v/std/openai";
2import { readFile } from "https://esm.town/v/std/utils@85-main/index.ts";
3
4// Initialize OpenAI client
5const openai = new OpenAI();
6
7// Bee-themed personality prompt
62 }
63
64 // Call OpenAI with bee persona
65 const completion = await openai.chat.completions.create({
66 model: "gpt-4o-mini",
67 messages: [
110 try {
111 // Generate image using DALL-E
112 const response = await openai.images.generate({
113 model: "dall-e-3",
114 prompt: enhancedPrompt,
119 });
120
121 console.log("OpenAI response:", JSON.stringify(response));
122
123 const imageUrl = response.data[0]?.url;
124
125 if (!imageUrl) {
126 throw new Error("No image URL returned from OpenAI");
127 }
128
136 },
137 );
138 } catch (openaiError) {
139 console.error("OpenAI API Error:", openaiError);
140
141 // Check if it's a content policy violation
142 if (openaiError.message && openaiError.message.includes("content policy")) {
143 return new Response(
144 JSON.stringify({
145 error: "Your image request was rejected due to content policy. Please try a different prompt.",
146 details: openaiError.message,
147 }),
148 {
154
155 // Check if it's a rate limit error
156 if (openaiError.message && openaiError.message.includes("rate limit")) {
157 return new Response(
158 JSON.stringify({
159 error: "Rate limit exceeded. Please try again later.",
160 details: openaiError.message,
161 }),
162 {
167 }
168
169 throw openaiError; // Re-throw for general error handling
170 }
171 } catch (error) {
1import { OpenAI } from "https://esm.town/v/std/openai";
2import { readFile } from "https://esm.town/v/std/utils@85-main/index.ts";
3
4// Initialize OpenAI client
5const openai = new OpenAI();
6
7// Bee-themed personality prompt
62 }
63
64 // Call OpenAI with bee persona
65 const completion = await openai.chat.completions.create({
66 model: "gpt-4o-mini",
67 messages: [
110 try {
111 // Generate image using DALL-E
112 const response = await openai.images.generate({
113 model: "dall-e-3",
114 prompt: enhancedPrompt,
119 });
120
121 console.log("OpenAI response:", JSON.stringify(response));
122
123 const imageUrl = response.data[0]?.url;
124
125 if (!imageUrl) {
126 throw new Error("No image URL returned from OpenAI");
127 }
128
136 },
137 );
138 } catch (openaiError) {
139 console.error("OpenAI API Error:", openaiError);
140
141 // Check if it's a content policy violation
142 if (openaiError.message && openaiError.message.includes("content policy")) {
143 return new Response(
144 JSON.stringify({
145 error: "Your image request was rejected due to content policy. Please try a different prompt.",
146 details: openaiError.message,
147 }),
148 {
154
155 // Check if it's a rate limit error
156 if (openaiError.message && openaiError.message.includes("rate limit")) {
157 return new Response(
158 JSON.stringify({
159 error: "Rate limit exceeded. Please try again later.",
160 details: openaiError.message,
161 }),
162 {
167 }
168
169 throw openaiError; // Re-throw for general error handling
170 }
171 } catch (error) {
236export default async function server(request: Request): Promise<Response> {
237 if (request.method === "POST") {
238 const { OpenAI } = await import("https://esm.town/v/std/openai");
239 const openai = new OpenAI();
240
241 const { question } = await request.json();
242
243 const completion = await openai.chat.completions.create({
244 messages: [
245 {