137Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
138
139### OpenAI
140```ts
141import { OpenAI } from "https://esm.town/v/std/openai";
142const openai = new OpenAI();
143const completion = await openai.chat.completions.create({
144 messages: [
145 { role: "user", content: "Say hello in a creative way" },
567// --- Backend Server (Val Town) ---
568export default async function server(request: Request): Promise<Response> {
569 const { OpenAI } = await import("https://esm.town/v/std/openai");
570
571 if (request.method === "OPTIONS") {
590 if (request.method === "POST" && new URL(request.url).pathname === "/grade-card") {
591 try {
592 // Check for OpenAI API Key in Val Town secrets
593 const openai = new OpenAI(); // Assumes OPENAI_API_KEY is set in Val Town secrets
594 const { imageBase64 } = await request.json();
595 if (!imageBase64 || typeof imageBase64 !== "string") {
600 }
601
602 console.log("Received image data, preparing request to OpenAI...");
603
604 const modelChoice = "gpt-4o"; // Or "gpt-4o-mini"
605
606 // --- Construct the detailed prompt for OpenAI ---
607 const prompt = `
608Alright, listen up, collector fam—here’s the no-BS, sharp-as-a-PSA-10 shorthand guide to grading and authenticating cards. No fluff, just gospel truths. Let’s get it:
712`;
713
714 const response = await openai.chat.completions.create({
715 model: modelChoice,
716 response_format: { type: "json_object" },
734 });
735
736 console.log("Received response from OpenAI.");
737
738 const jsonString = response.choices[0]?.message?.content;
739 if (!jsonString) {
740 throw new Error("OpenAI did not return valid response content.");
741 }
742
746 console.log("Successfully parsed JSON response.");
747 } catch (parseError) {
748 console.error("Failed to parse JSON from OpenAI:", jsonString);
749 throw new Error("AI returned improperly formatted JSON data.");
750 }
567// --- Backend Server (Val Town) ---
568export default async function server(request: Request): Promise<Response> {
569 const { OpenAI } = await import("https://esm.town/v/std/openai");
570
571 if (request.method === "OPTIONS") {
590 if (request.method === "POST" && new URL(request.url).pathname === "/grade-card") {
591 try {
592 // Check for OpenAI API Key in Val Town secrets
593 const openai = new OpenAI(); // Assumes OPENAI_API_KEY is set in Val Town secrets
594 const { imageBase64 } = await request.json();
595 if (!imageBase64 || typeof imageBase64 !== "string") {
600 }
601
602 console.log("Received image data, preparing request to OpenAI...");
603
604 const modelChoice = "gpt-4o"; // Or "gpt-4o-mini"
605
606 // --- Construct the detailed prompt for OpenAI ---
607 const prompt = `
608 Alright, listen up, collector fam—here’s the no-BS, sharp-as-a-PSA-10 shorthand guide to grading and authenticating cards. No fluff, just gospel truths. Let’s get it:
727`;
728
729 const response = await openai.chat.completions.create({
730 model: modelChoice,
731 response_format: { type: "json_object" },
749 });
750
751 console.log("Received response from OpenAI.");
752
753 const jsonString = response.choices[0]?.message?.content;
754 if (!jsonString) {
755 throw new Error("OpenAI did not return valid response content.");
756 }
757
761 console.log("Successfully parsed JSON response.");
762 } catch (parseError) {
763 console.error("Failed to parse JSON from OpenAI:", jsonString);
764 throw new Error("AI returned improperly formatted JSON data.");
765 }
757// --- Backend Server (Val Town / Cloud Function) ---
758export default async function server(request: Request): Promise<Response> {
759 // Dynamically import OpenAI only when needed on the server
760 const { OpenAI } = await import("https://esm.town/v/std/openai");
761
762 // Standard CORS preflight handling
782 if (request.method === "POST" && new URL(request.url).pathname === "/analyze-aircraft") {
783 try {
784 // Check for OpenAI API Key in Val Town secrets (Val Town automatically injects process.env)
785 // The library handles finding the key from secrets/env vars.
786
787 const openai = new OpenAI(); // Instantiates with key from secrets
788
789 const { imageBase64 } = await request.json();
796 }
797
798 console.log("Received image data for aircraft analysis, preparing request to OpenAI...");
799
800 const modelChoice = "gpt-4o"; // Use the powerful vision model
801
802 // --- Construct the detailed prompt for OpenAI ---
803 // This prompt guides the AI to act as an aircraft maintenance analyzer.
804 const prompt = `
899`;
900
901 // --- Call OpenAI API ---
902 const response = await openai.chat.completions.create({
903 model: modelChoice,
904 response_format: { type: "json_object" }, // Enforce JSON output
926 });
927
928 console.log("Received response from OpenAI for aircraft analysis.");
929
930 const jsonString = response.choices[0]?.message?.content;
931 if (!jsonString) {
932 throw new Error("OpenAI did not return valid response content.");
933 }
934
936 try {
937 parsedResponse = JSON.parse(jsonString);
938 console.log("Successfully parsed JSON response from OpenAI.");
939 } catch (parseError) {
940 console.error("Failed to parse JSON from OpenAI:", jsonString);
941 // Try to provide the invalid JSON in the error for debugging
942 throw new Error(`AI returned improperly formatted JSON data. Received: ${jsonString.substring(0, 500)}...`);
239
240async function fetchAIResponse(query: string): Promise<string> {
241 const { OpenAI } = await import("https://esm.town/v/std/openai");
242 const openai = new OpenAI();
243
244 const completion = await openai.chat.completions.create({
245 messages: [
246 { role: "system", content: "You are a helpful voice assistant. Keep responses concise and friendly." },
239
240async function fetchAIResponse(query: string): Promise<string> {
241 const { OpenAI } = await import("https://esm.town/v/std/openai");
242 const openai = new OpenAI();
243
244 const completion = await openai.chat.completions.create({
245 messages: [
246 { role: "system", content: "You are a helpful voice assistant. Keep responses concise and friendly." },
408 const { sqlite } = await import("https://esm.town/v/stevekrouse/sqlite");
409 const { email: sendEmail } = await import("https://esm.town/v/std/email");
410 const { OpenAI } = await import("https://esm.town/v/std/openai");
411 const openai = new OpenAI();
412
413 const KEY = "bhaavsynthlandipgpage";
1import { readFile } from "https://esm.town/v/std/utils@71-main/index.ts";
2import { createOpenAI } from "npm:@ai-sdk/openai";
3import { streamText, tool } from "npm:ai";
4import { z } from "npm:zod";
56});
57
58const openai = createOpenAI({
59 baseURL: "https://std-openaiproxy.web.val.run/v1",
60 apiKey: Deno.env.get("valtown"),
61 organization: undefined,
79 try {
80 const result = await streamText({
81 model: openai("gpt-4o-mini"),
82 messages,
83 tools: {
111 });
112 } catch (error) {
113 console.error("OpenAI API error:", error);
114 return new Response("An error occurred during the analysis.");
115 }
7// Import a deep cloning library for safe state updates
8import cloneDeep from "https://esm.sh/lodash-es@4.17.21/cloneDeep";
9// Use Val Town's std/openai as requested via example
10import { OpenAI } from "https://esm.town/v/std/openai";
11
12// --- TypeScript Interfaces: Defining the AI's Structured Output ---
396 console.log(`Analyzing: "${sentence.substring(0, 50)}..."`);
397
398 // --- OpenAI Setup using std/openai ---
399 // NOTE: Using std/openai as requested via example. API key handling might be managed by Val Town infrastructure.
400 // If issues occur, consider switching back to `npm:openai` and using API Key secret.
401 console.log("Using std/openai client");
402 const openai = new OpenAI(); // Assumes std/openai handles auth/key implicitly
403
404 // --- System Prompt for Structured Tree Output ---
407 `You are an AI language structuring expert... [PROMPT REMAINS THE SAME AS PREVIOUS VERSION - asking for AnalysisTree JSON with effects, IDs, options etc, using double quotes in JSON output] ... Output ONLY the raw, valid JSON object using double quotes for all JSON keys and string values.`;
408
409 console.log("Sending prompt to OpenAI (gpt-4o)...");
410 const response = await openai.chat.completions.create({
411 model: "gpt-4o",
412 messages: [{ role: "system", content: systemPrompt }],
415 max_tokens: 3000,
416 });
417 console.log(`OpenAI Response. Finish: ${response.choices[0]?.finish_reason}.`);
418
419 const aiResponseContent = response.choices[0]?.message?.content;
137Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
138
139### OpenAI
140```ts
141import { OpenAI } from "https://esm.town/v/std/openai";
142const openai = new OpenAI();
143const completion = await openai.chat.completions.create({
144 messages: [
145 { role: "user", content: "Say hello in a creative way" },