125if (request.method === "POST") {
126try {
127const { OpenAI } = await import("https://esm.town/v/std/openai");
128const openai = new OpenAI();
129130const formData = await request.formData();
138const cvText = new TextDecoder().decode(cvBuffer);
139140const completion = await openai.chat.completions.create({
141messages: [
142{
197const [isInitialized, setIsInitialized] = useState(false);
198199// --- OpenAI Interaction (Unchanged) ---
200// !!! IMPORTANT SECURITY WARNING & Val Town Note !!!
201// ... (same as before)
205if (!text) return;
206setStatus("Sending to AI...");
207console.log("Sending to OpenAI:", text);
208setAiResponse(""); // Clear previous response
209setError(null);
213try {
214// ---- START: Replace this block in Val Town ----
215const response = await fetch("https://api.openai.com/v1/chat/completions", {
216method: "POST",
217headers: {
226const errorData = await response.json().catch(() => ({})); // Try to get JSON error details
227throw new Error(
228`OpenAI API Error: ${response.status} ${response.statusText} - ${
229errorData?.error?.message ?? "Check API key or usage limits."
230}`,
240speakText(reply);
241} catch (err: any) {
242console.error("OpenAI call failed:", err);
243const errMsg = `AI Error: ${err.message}`;
244setError(errMsg);
FixItWandgenerate.ts6 matches
1import OpenAI from "https://esm.sh/openai@4.96.0";
2import { search } from "./locations/mod.ts";
34const openai = new OpenAI();
56/**
39const audioFile = new File([audioBlob], "a.mp3", { type: "audio/mp3" });
4041transcription = await openai.audio.transcriptions.create({
42file: audioFile,
43model: "whisper-1",
50if (transcription) {
51// Detect possible location references in the transcription
52const locationDetectionResponse = await openai.chat.completions.create({
53model: "gpt-4o-mini",
54messages: [
149});
150151const chatResponse = await openai.chat.completions.create({
152model: "gpt-4o",
153messages: messages as any, // Type assertion to fix any TypeScript issues
166`;
167168const subjectResponse = await openai.chat.completions.create({
169model: "gpt-4o-mini",
170messages: [
OpenTownie_jacksonsystem_prompt.txt4 matches
88Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
8990### OpenAI
9192```ts
93import { OpenAI } from "https://esm.town/v/std/openai";
94const openai = new OpenAI();
95const completion = await openai.chat.completions.create({
96messages: [
97{ role: "user", content: "Say hello in a creative way" },
1// Val Town Script: Dynamic Character Race Carousel with OpenAI + Plane Tilt + Fanning Cards + Animated Borders
23// =============================================================================
5// =============================================================================
67// Import OpenAI library from Val Town's standard modules
8import { OpenAI } from "https://esm.town/v/std/openai"; // Ensure 'openai' secret is set
910// --- Configuration ---
21borderAnimationHint?: string; // <<< NEW: Optional hint for border style
22}
23interface OpenAIResponse {
24races: RaceInfo[];
25}
65];
6667// --- OpenAI Generation Function ---
68async function generateRaceDataWithOpenAI(): Promise<RaceInfo[]> {
69const openai = new OpenAI();
70const numToRequest = Math.max(1, NUM_CARDS_TO_GENERATE);
71const prompt = `
8182try {
83console.info(`Requesting ${numToRequest} race data generation from OpenAI...`);
84const completion = await openai.chat.completions.create({
85model: "gpt-4o", // Or your preferred model
86messages: [{ role: "user", content: prompt }],
9091const rawContent = completion.choices[0]?.message?.content;
92if (!rawContent) throw new Error("OpenAI returned an empty response message.");
93console.info("Received response from OpenAI. Parsing and validating JSON...");
94const parsedJson = JSON.parse(rawContent);
95109)
110) {
111console.warn(`OpenAI response JSON failed validation for ${numToRequest} races:`, parsedJson);
112throw new Error("OpenAI response JSON structure, count, data types, or hint value invalid.");
113}
114115const generatedData = (parsedJson as OpenAIResponse).races.map(race => ({
116...race,
117// Ensure borderAnimationHint defaults to 'none' if missing from response
119}));
120121console.info(`Successfully generated and validated ${generatedData.length} races from OpenAI.`);
122return generatedData;
123} catch (error) {
124console.error("Error fetching or processing data from OpenAI:", error);
125console.warn("Using fallback race data due to the error.");
126// Ensure fallback data also has the hint, slice correctly
134// --- Main HTTP Handler (Val Town Entry Point) ---
135export default async function server(request: Request): Promise<Response> {
136const activeRaceData = await generateRaceDataWithOpenAI();
137138// Define CSS Styles
7* Serves HTML UI & API endpoint from the same Val.
8* Based on user-provided glassmorphism UI example.
9* Assumes 'openai' secret is set in Val Town environment variables.
10*
11* Last Updated: 2025-05-01 (Reference Relevance & Paradigmatic Analysis Integration)
916export default async function(req: Request) {
917// --- Dynamic Imports (Inside Handler) ---
918const { OpenAI } = await import("https://esm.town/v/std/openai");
919const { z } = await import("npm:zod");
920const { fetch } = await import("https://esm.town/v/std/fetch");
944}
945946// --- Helper Function: Call OpenAI API (Unchanged) ---
947async function callOpenAI(
948openai: OpenAI,
949systemPrompt: string,
950userMessage: string,
953): Promise<{ role: "assistant" | "system"; content: string | object }> {
954try {
955const response = await openai.chat.completions.create({
956model,
957messages: [{ role: "system", content: systemPrompt }, { role: "user", content: userMessage }],
971else { return { role: "assistant", content }; }
972} catch (error) {
973console.error(`OpenAI call failed (ExpectJSON: ${expectJson}):`, error);
974let msg = "Error communicating with AI.";
975if (error.message) msg += ` Details: ${error.message}`;
976if (error.status === 401) msg = "OpenAI Auth Error.";
977if (error.status === 429) msg = "OpenAI Rate Limit Exceeded.";
978return { role: "system", content: msg };
979}
1042log: LogEntry[],
1043): Promise<LogEntry[]> {
1044const openai = new OpenAI();
1045log.push({ agent: "System", type: "step", message: "Workflow started." });
1046log.push({
1115// --- Content Analysis (Unchanged) ---
1116log.push({ agent: "System", type: "step", message: "Analyzing content..." });
1117const anaRes = await callOpenAI(openai, contentAnalysisSystemPrompt, truncText, "gpt-4o", true);
1118if (anaRes.role === "assistant" && anaRes.content && (anaRes.content as AnalysisResult).summary) { // Type assertion for check
1119log.push({ agent: "Content Analysis Agent", type: "result", message: anaRes.content });
1124// --- NEW: Paradigmatic Analysis ---
1125log.push({ agent: "System", type: "step", message: "Analyzing document context/paradigm..." });
1126const paradigmRes = await callOpenAI(openai, paradigmaticAnalysisSystemPrompt, truncText, "gpt-4o", true);
1127if (
1128paradigmRes.role === "assistant" && paradigmRes.content && (paradigmRes.content as ParadigmaticInfo).documentType
1135// --- MODIFIED: Reference Extraction ---
1136log.push({ agent: "System", type: "step", message: "Extracting references..." });
1137const refRes = await callOpenAI(openai, referenceExtractionSystemPrompt, truncText, "gpt-4o", true); // Use updated prompt
1138let extRef: Reference[] = []; // Use Reference type
1139// Check the correct key 'references' from the prompt
2* Multi-Agent Policy Document Analysis (Single Val Version with PDF Upload & Dashboard Style)
3* Demonstrates document ingestion (URL, Text, PDF Upload), content analysis,
4* citation extraction, and basic reference traversal using collaborative AI agents via OpenAI.
5* Uses 'npm:pdf.js-extract' for direct PDF text extraction within the Val (experimental).
6* Serves an HTML UI with a dashboard grid background and handles API requests within the same Val.
7* OpenAI import is dynamically done inside the main server function.
8*
9* Based on structure from multi-agent support simulation example.
10* Assumes 'openai' secret is set in Val Town environment variables.
11*
12* Last Updated: 2025-05-01 (Added PDF upload, dashboard style)
171<p class="description">
172Enter a document URL, paste text, or upload a PDF below. AI agents will analyze content, extract citations, and attempt reference traversal.<br>
173Uses OpenAI via Val Town & <code>npm:pdf.js-extract</code> for PDFs. Current Date: ${
174new Date().toLocaleDateString()
175}
339export default async function(req: Request) {
340// --- Dynamic Imports (Inside Handler) ---
341const { OpenAI } = await import("https://esm.town/v/std/openai");
342const { z } = await import("npm:zod");
343const { fetch } = await import("https://esm.town/v/std/fetch");
397}
398399// --- Helper Function: Call OpenAI API (Unchanged) ---
400async function callOpenAI(
401openai: OpenAI,
402systemPrompt: string,
403userMessage: string,
406): Promise<{ role: "assistant" | "system"; content: string | object }> {
407try {
408const response = await openai.chat.completions.create({
409model: model,
410messages: [{ role: "system", content: systemPrompt }, { role: "user", content: userMessage }],
418return { role: "assistant", content: JSON.parse(content) };
419} catch (parseError) {
420console.error("OpenAI JSON Parse Error:", parseError, "Raw Content:", content);
421throw new Error(`AI response was not valid JSON. Raw: ${content.substring(0, 150)}...`);
422}
423} else { return { role: "assistant", content: content }; }
424} catch (error) {
425console.error(`OpenAI API call failed. ExpectJSON: ${expectJson}. Error:`, error);
426let errorMessage = "Error communicating with AI model.";
427if (error.message) { errorMessage += ` Details: ${error.message}`; }
486log: LogEntry[],
487): Promise<LogEntry[]> {
488const openai = new OpenAI();
489490log.push({ agent: "System", type: "step", message: "Starting analysis workflow." });
554555// Limit text length
556const MAX_TEXT_LENGTH = 20000; // Consider limits for OpenAI context window
557const truncatedText = documentText.substring(0, MAX_TEXT_LENGTH);
558if (documentText.length > MAX_TEXT_LENGTH) {
566// --- Steps 2, 3, 4, 5 (Analysis, Extraction, Traversal, Final Output) ---
567log.push({ agent: "System", type: "step", message: "Starting Content Analysis..." });
568const analysisResponse = await callOpenAI(openai, contentAnalysisSystemPrompt, truncatedText, "gpt-4o", true);
569let analysisResult: AnalysisResult | null = null;
570if (analysisResponse.role === "assistant" && typeof analysisResponse.content === "object") {
575576log.push({ agent: "System", type: "step", message: "Starting Citation Extraction..." });
577const citationResponse = await callOpenAI(openai, citationExtractionSystemPrompt, truncatedText, "gpt-4o", true);
578let extractedCitations: Citation[] = [];
579if (
5// =============================================================================
67import { OpenAI } from "https://esm.town/v/std/openai";
8// import { Request, Response } from "https://esm.town/v/std/fetch"; // Usually global
916}
1718interface OpenAIResponse {
19races: RaceInfo[];
20}
4950// --- ***** THIS FUNCTION WAS MISSING ***** ---
51// --- OpenAI Generation Function ---
52// Asynchronously fetches race data from OpenAI's Chat Completion API.
53async function generateRaceDataWithOpenAI(): Promise<RaceInfo[]> {
54let openai;
55try {
56// IMPORTANT: Ensure the 'openai' secret is configured in your Val Town settings.
57openai = new OpenAI();
58} catch (error) {
59console.error("Failed to initialize OpenAI client. Check 'openai' secret in Val Town.", error);
60console.warn("Using fallback race data due to OpenAI initialization error.");
61return fallbackRaceData;
62}
8687try {
88console.info("Requesting race data generation from OpenAI...");
89const completion = await openai.chat.completions.create({
90model: "gpt-4o", // Or "gpt-3.5-turbo"
91messages: [{ role: "user", content: prompt }],
96const rawContent = completion.choices[0]?.message?.content;
97if (!rawContent) {
98throw new Error("OpenAI returned an empty response message.");
99}
100console.info("Received response from OpenAI. Parsing and validating JSON...");
101let parsedJson;
102try {
103parsedJson = JSON.parse(rawContent);
104} catch (parseError) {
105console.error("Failed to parse OpenAI response as JSON:", rawContent);
106throw new Error("Invalid JSON received from OpenAI.");
107}
108122)
123) {
124console.warn("OpenAI response JSON failed validation:", parsedJson);
125throw new Error("OpenAI response JSON does not match expected structure/data.");
126}
127128const generatedData = (parsedJson as OpenAIResponse).races;
129console.info(`Successfully generated and validated ${generatedData.length} races from OpenAI.`);
130// Trim whitespace just in case
131return generatedData.map(race => ({
136}));
137} catch (error) {
138console.error("Error fetching or processing data from OpenAI:", error);
139if (error.constructor.name === "AuthenticationError") {
140console.error("OpenAI Authentication Error: Check 'openai' secret.");
141} // Add more specific error checks if needed
142console.warn("Using fallback race data due to the error.");
154// 1. Fetch Race Data - Ensure this line is calling the function defined above
155console.log("Attempting to fetch race data...");
156const activeRaceData = await generateRaceDataWithOpenAI();
157console.log(`Workspaceed ${activeRaceData.length} races. First race: ${activeRaceData[0]?.name || "N/A"}`);
158
5// =============================================================================
67import { OpenAI } from "https://esm.town/v/std/openai";
8// import { Request, Response } from "https://esm.town/v/std/fetch"; // Usually global
915}
1617interface OpenAIResponse {
18races: RaceInfo[];
19}
31];
3233async function generateRaceDataWithOpenAI(): Promise<RaceInfo[]> {
34let openai;
35try {
36openai = new OpenAI(); // Ensure 'openai' secret is set in Val Town
37} catch (error) {
38console.error("Failed to initialize OpenAI client.", error);
39return fallbackRaceData;
40}
41const prompt = `{Your OpenAI prompt from previous version - unchanged}`; // Keep the prompt as before
4243try {
44console.info("Requesting race data from OpenAI...");
45const completion = await openai.chat.completions.create({
46model: "gpt-4o",
47messages: [{ role: "user", content: prompt }],
50});
51const rawContent = completion.choices[0]?.message?.content;
52if (!rawContent) throw new Error("OpenAI returned empty content.");
53console.info("Parsing and validating OpenAI response...");
54let parsedJson = JSON.parse(rawContent);
5559|| parsedJson.races.some(/*... detailed item checks ...*/)
60) {
61throw new Error("OpenAI response JSON failed validation.");
62}
63const generatedData = (parsedJson as OpenAIResponse).races;
64console.info(`Successfully validated ${generatedData.length} races from OpenAI.`);
65return generatedData.map(race => ({ ...race, name: race.name.trim() /* etc */
66}));
67} catch (error) {
68console.error("Error fetching/processing from OpenAI:", error);
69return fallbackRaceData;
70}
75// =============================================================================
76export default async function server(request: Request): Promise<Response> {
77const activeRaceData = await generateRaceDataWithOpenAI();
7879const css = `
5// =============================================================================
67// Import OpenAI library from Val Town's standard modules
8// Ensure you have the 'openai' secret set in your Val Town account.
9import { OpenAI } from "https://esm.town/v/std/openai";
10// Import Request and Response types if needed (usually available globally in Val Town)
11// Example: import { Request, Response } from "https://esm.town/v/std/fetch";
21}
2223// Defines the specific JSON structure expected back from the OpenAI API
24interface OpenAIResponse {
25races: RaceInfo[]; // An array containing the race information
26}
2728// --- Fallback Data ---
29// Provides default race data if the OpenAI API call fails or returns invalid data.
30const fallbackRaceData: RaceInfo[] = [
31{
55];
5657// --- OpenAI Generation Function ---
58// Asynchronously fetches race data from OpenAI's Chat Completion API.
59async function generateRaceDataWithOpenAI(): Promise<RaceInfo[]> {
60// Initialize the OpenAI client (using API key from Val Town secrets)
61// Ensure the 'openai' secret is configured in your Val Town settings.
62let openai;
63try {
64openai = new OpenAI();
65} catch (error) {
66console.error("Failed to initialize OpenAI client. Check 'openai' secret in Val Town.", error);
67console.warn("Using fallback race data due to OpenAI initialization error.");
68return fallbackRaceData;
69}
7071// Detailed prompt instructing OpenAI to generate race data in a specific JSON format.
72const prompt = `
73Generate a list of exactly 4 distinct fantasy character races suitable for an RPG character creator carousel.
9495try {
96console.info("Requesting race data generation from OpenAI...");
97const completion = await openai.chat.completions.create({
98model: "gpt-4o", // Recommended model
99messages: [{ role: "user", content: prompt }],
105const rawContent = completion.choices[0]?.message?.content;
106if (!rawContent) {
107throw new Error("OpenAI returned an empty response message.");
108}
109// console.debug("Raw OpenAI Response:", rawContent); // Uncomment for debugging
110111console.info("Received response from OpenAI. Parsing and validating JSON...");
112let parsedJson;
113try {
114parsedJson = JSON.parse(rawContent);
115} catch (parseError) {
116console.error("Failed to parse OpenAI response as JSON:", rawContent);
117throw new Error("Invalid JSON received from OpenAI.");
118}
119133)
134) {
135console.warn("OpenAI response JSON failed validation:", parsedJson);
136throw new Error(
137"OpenAI response JSON does not match the expected structure or contains invalid data.",
138);
139}
140141// Type assertion after successful validation
142const generatedData = (parsedJson as OpenAIResponse).races;
143144console.info(`Successfully generated and validated ${generatedData.length} races from OpenAI.`);
145// Sanitize potentially empty strings just in case validation missed something edge-casey (unlikely with checks above)
146return generatedData.map(race => ({
151}));
152} catch (error) {
153// Log the specific error encountered during the OpenAI call or processing
154console.error("Error fetching or processing data from OpenAI:", error);
155// Check if the error is specifically an AuthenticationError
156if (error.constructor.name === "AuthenticationError") {
157console.error(
158"OpenAI Authentication Error: Please ensure your 'openai' secret is correctly configured in Val Town settings.",
159);
160} else if (error instanceof SyntaxError) {
161console.error("JSON Parsing Error: The response from OpenAI was not valid JSON.");
162} else {
163// General error
164console.error("An unexpected error occurred while communicating with OpenAI.");
165}
166console.warn("Using fallback race data due to the error.");
176// This function handles incoming HTTP requests and returns the HTML for the game.
177export default async function server(request: Request): Promise<Response> {
178// 1. Fetch Race Data: Attempt to get dynamic data from OpenAI, use fallback on error.
179const activeRaceData = await generateRaceDataWithOpenAI();
180181// 2. Define CSS Styles: Includes base carousel, new game UI, and enhanced effects.