diff --git a/app/app.js b/app/app.js index 3925bbd4..cbd18f34 100644 --- a/app/app.js +++ b/app/app.js @@ -1,18 +1,18 @@ -import express from 'express'; -import { OpenAI } from 'openai'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import dotenv from 'dotenv'; +import dotenv from "dotenv"; +import express from "express"; +import { OpenAI } from "openai"; +import path from "path"; +import { fileURLToPath } from "url"; -import json from './public/characters.json' with { type: "json" }; +dotenv.config(); + +import json from "./public/characters.json" with { type: "json" }; let systemMessage = json[4].description; let page = json[4].page; -console.log("SERVER systemMessage: ", systemMessage); -console.log("SERVER page: ", page); - -dotenv.config(); +// console.log("SERVER systemMessage: ", systemMessage); +// console.log("SERVER page: ", page); const app = express(); const port = process.env.PORT || 3000; @@ -23,16 +23,16 @@ const __dirname = path.dirname(__filename); app.use(express.json()); // Serve static files from the 'public' directory -app.use(express.static(path.join(__dirname, 'public'))); +app.use(express.static(path.join(__dirname, "public"))); -app.locals.delimiters = '{{ }}'; +app.locals.delimiters = "{{ }}"; function getCharacterByName(name) { - return json.find(character => character.name === name) || null; + return json.find((character) => character.name === name) || null; } // Route to send the prompt -app.post('/send', async (req, res) => { +app.post("/send", async (req, res) => { const { message, character } = req.body; systemMessage = character.description; @@ -41,13 +41,13 @@ app.post('/send', async (req, res) => { const messages = [ { - "role": "system", - "content": systemMessage, + role: "system", + content: systemMessage, }, { - "role": "user", - "content": prompt - } + role: "user", + content: prompt, + }, ]; const openai = new OpenAI({ @@ -56,20 +56,18 @@ app.post('/send', async (req, res) => { }); try { - console.log(`SERVER sending prompt ${prompt}`) const completion = await openai.chat.completions.create({ - model: 'gpt-4o-mini', + model: "gpt-4o-mini", messages: messages, }); - console.log(`SERVER: ${completion.choices[0]?.message?.content}`); res.json({ prompt: prompt, - answer: completion.choices[0]?.message?.content + answer: completion.choices[0]?.message?.content, }); } catch (error) { console.error(`Error: ${error.message}`); // Log the error message for debugging - res.status(500).json({ message: 'An unexpected error occurred. Please try again later.' }); // Send a generic error message + res.status(500).json({ message: "An unexpected error occurred. Please try again later." }); // Send a generic error message } }); diff --git a/app/cipher.js b/app/cipher.js new file mode 100644 index 00000000..f4f3b7dd --- /dev/null +++ b/app/cipher.js @@ -0,0 +1,41 @@ +import { OpenAI } from "openai"; +import dotenv from "dotenv"; +dotenv.config(); + +// Create prompt including inputs should include chain of thought + +const bootSequence = `nomi`; + +const prompt = `Provide the boot sequence for the aerial screw, the text should be mirrored and encoded with a Caesar cipher with a shift of 3. The boot sequence is: ${bootSequence}.`; + +// Call the language model with the prompt + +const messages = [ + { + role: "user", + content: prompt, + }, +]; + +// 2. Create client +// ----------------------------------- + +const openai = new OpenAI({ + baseURL: "https://models.inference.ai.azure.com", + apiKey: process.env.GITHUB_TOKEN, +}); + +// 3. Send the request +// ----------------------------------- + +const completion = await openai.chat.completions.create({ + model: "gpt-4o-mini", + messages: messages, +}); + +console.log(`Answer for "${prompt}":`); + +// 4. Print the answer +// ----------------------------------- + +console.log(completion.choices[0]?.message?.content); diff --git a/app/context.js b/app/context.js new file mode 100644 index 00000000..36de1025 --- /dev/null +++ b/app/context.js @@ -0,0 +1,47 @@ +import dotenv from "dotenv"; +dotenv.config(); +import { OpenAI } from "openai"; + +// Define the context + +const messages = [ + { + role: "user", + content: "I want to book a trip to Italy.", + }, + { + role: "assistant", + content: "Sure, when would you like to go?", + }, + { + role: "user", + content: "Next month would be great.", + }, + { + role: "assistant", + content: "Got it, where in Italy would you like to visit?", + }, + { + role: "user", + content: "I'm thinking of Rome. Tell me more about it.", + }, +]; + +const openai = new OpenAI({ + baseURL: "https://models.inference.ai.azure.com", + apiKey: process.env.GITHUB_TOKEN, +}); + +// 3. Send the request +// ----------------------------------- +const completion = await openai.chat.completions.create({ + model: "gpt-4o-mini", + messages: messages, + // temperature: 0.7, // Adjust the temperature for creativity, 0.0 (more deterministic) to 1.0 (more creative) + // max_completion_tokens: 512, // Limit the response length. +}); + +// 4. Print the answer +// ----------------------------------- + +console.log(completion.choices[0]?.message?.content); diff --git a/app/csv-rag.js b/app/csv-rag.js new file mode 100644 index 00000000..7f5f60aa --- /dev/null +++ b/app/csv-rag.js @@ -0,0 +1,81 @@ +// This example demonstrates how to use the Retrieval Augmented Generation (RAG) +// to answer questions based on a hybrid car data set. +// The code below reads the CSV file, searches for matches to the user question, +// and then generates a response based on the information found. + +import dotenv from "dotenv"; +import { fileURLToPath } from "node:url"; +import { dirname } from "node:path"; +import process from "node:process"; +import fs from "node:fs"; +import { OpenAI } from "openai"; + +dotenv.config(); +// Change the current working directory to the directory of the script +const __dirname = dirname(fileURLToPath(import.meta.url)); +process.chdir(__dirname); + +// 1. Ask a question about hybrid cars +// ----------------------------------- + +const question = `what's the fastest prius`; + +// 2. Retriever component: search the data for relevant information +// ---------------------------------------------------------------- + +// Load CSV data as an array of objects +const rows = fs.readFileSync("./hybrid.csv", "utf8").split("\n"); +const columns = rows[0].split(","); + +// Search the data using a very naive search +const words = question + .toLowerCase() + .replaceAll(/[.?!()'":,]/g, "") + .split(" ") + .filter((word) => word.length > 2); +const matches = rows.slice(1).filter((row) => words.some((word) => row.toLowerCase().includes(word))); + +// Format as a markdown table, since language models understand markdown +const table = + `| ${columns.join(" | ")} |\n` + + `|${columns.map(() => "---").join(" | ")}|\n` + + matches.map((row) => `| ${row.replaceAll(",", " | ")} |\n`).join(""); + +console.log(`Found ${matches.length} matches:`); +console.log(table); + +// 3. Context augmentation: create a combined prompt with the search results +// -------------------------------------------------------------------------- + +const augmentedPrompt = ` +## Instructions +Answer questions about a time period or characters from said time period using only the sources below. +If there's not enough data in provided sources, say that you don't know. +Be brief and straight to the point. + +## Sources +${table} + +## Question +${question} +`; + +// 4. Generator component: use the search results to generate a response +// --------------------------------------------------------------------- + +const openai = new OpenAI({ + baseURL: "https://models.inference.ai.azure.com", + apiKey: process.env.GITHUB_TOKEN, +}); + +const chunks = await openai.chat.completions.create({ + model: "gpt-4o-mini", + messages: [{ role: "user", content: augmentedPrompt }], + stream: true, +}); + +console.log(`Answer for "${question}":`); + +for await (const chunk of chunks) { + process.stdout.write(chunk.choices[0].delta.content ?? ""); +} diff --git a/app/hybrid.csv b/app/hybrid.csv new file mode 100644 index 00000000..499105a8 --- /dev/null +++ b/app/hybrid.csv @@ -0,0 +1,154 @@ +vehicle,year,msrp,0-60 mph acceleration,mpg,class +Prius (1st Gen),1997,24509.74,7.46,41.26,Compact +Tino,2000,35354.97,8.2,54.1,Compact +Prius (2nd Gen),2000,26832.25,7.97,45.23,Compact +Insight,2000,18936.41,9.52,53.0,Two Seater +Civic (1st Gen),2001,25833.38,7.04,47.04,Compact +Insight,2001,19036.71,9.52,53.0,Two Seater +Insight,2002,19137.01,9.71,53.0,Two Seater +Alphard,2003,38084.77,8.33,40.46,Minivan +Insight,2003,19137.01,9.52,53.0,Two Seater +Civic,2003,14071.92,8.62,41.0,Compact +Escape,2004,36676.1,10.32,31.99,SUV +Insight,2004,19237.31,9.35,52.0,Two Seater +Prius,2004,20355.64,9.9,46.0,Midsize +Silverado 15 2WD,2004,30089.64,9.09,17.0,Pickup Truck +Lexus RX400h,2005,58521.14,12.76,28.23,SUV +Civic (2nd Gen),2005,26354.44,7.63,39.99,Compact +Highlander,2005,29186.21,12.76,29.4,SUV +Insight,2005,19387.76,9.71,52.0,Two Seater +Civic,2005,18236.33,8.26,41.0,Compact +Escape 2WD,2005,19322.56,9.52,29.0,SUV +Accord,2005,16343.69,14.93,28.0,Midsize +Silverado 15 2WD,2005,32647.26,11.11,17.0,Pickup Truck +Mercury Mariner,2006,34772.4,8.98,32.93,SUV +Camry,2006,29853.25,11.28,33.64,Midsize +Lexus GS450h,2006,64547.56,18.65,33.4,Midsize +Estima,2006,36012.7,9.26,47.04,Minivan +Altima,2006,29524.75,13.29,32.93,Midsize +Chevrolet Tahoe,2007,42924.35,10.91,22.35,SUV +Kluger,2007,46229.48,12.76,25.87,SUV +Lexus LS600h/hL,2007,118543.6,17.54,21.0,Midsize +Tribute,2007,24823.83,11.28,31.75,SUV +GMC Yukon,2007,57094.81,12.28,21.78,SUV +Aura,2007,22110.87,10.87,27.0,Midsize +Vue,2007,22938.33,10.75,26.0,SUV +Silverado 15 2WD,2007,34653.23,11.49,17.0,Pickup Truck +Crown,2008,62290.38,8.7,37.16,Midsize +Cadillac Escalade,2008,78932.81,9.09,22.35,SUV +F3DM,2008,23744.06,9.52,30.11,Midsize +Altima,2008,18675.63,13.7,34.0,Midsize +A5 BSG,2009,11849.43,7.87,35.28,Midsize +Lexus RX450h,2009,46233.36,13.47,31.99,SUV +ML450 Blue HV,2009,60519.83,12.6,23.99,SUV +Prius (3rd Gen),2009,24641.18,9.6,47.98,Compact +S400 Long,2009,96208.93,13.89,26.34,Large +Mercury Milan,2009,30522.57,11.55,40.69,Midsize +Lexus HS250h,2009,38478.15,11.55,54.1,Compact +Avante/Elantra LPI,2009,21872.71,10.21,41.87,Compact +ActiveHybrid X6,2009,97237.9,17.96,18.82,SUV +SAI,2009,39172.44,11.55,54.1,Midsize +Malibu,2009,24768.79,9.09,29.0,Midsize +Vue,2009,26408.67,13.7,28.0,SUV +Aspen HEV,2009,44903.77,13.51,21.0,SUV +Durango,2009,41033.24,8.33,21.0,SUV +Auris HSD,2010,35787.29,8.85,68.21,Compact +CR-Z,2010,21435.54,9.24,37.0,Two Seater +F3DM PHEV,2010,23124.59,9.24,30.15,Midsize +Touareg,2010,64198.95,15.38,28.7,SUV +Audi Q5,2010,37510.86,14.08,33.64,SUV +Jeep Patriot,2010,17045.06,12.05,29.4,SUV +Besturn B50 ,2010,14586.61,7.14,31.28,Midsize +ActiveHybrid 7,2010,104300.43,20.41,22.11,Large +Lincoln MKZ,2010,37036.64,11.15,37.63,Midsize +Fit/Jazz,2010,16911.85,8.26,30.0,Compact +Sonata,2010,28287.66,14.7,37.0,Midsize +Cayenne S,2010,73183.47,14.71,26.11,SUV +Insight,2010,19859.16,9.17,41.0,Compact +Fuga Infiniti M35H,2010,70157.02,18.65,33.64,Midsize +Chevrolet Volt,2010,42924.35,10.78,35.0,Compact +Tribute 4WD,2010,27968.32,12.35,29.0,SUV +Fusion FWD,2010,28033.51,11.49,39.0,Midsize +HS 250h,2010,34753.53,11.76,35.0,Compact +Mariner FWD,2010,30194.95,11.63,32.0,SUV +RX 450h,2010,42812.54,13.89,30.0,SUV +ML450 4natic,2010,55164.33,12.99,22.0,SUV +Silverado 15 2WD,2010,38454.56,11.76,22.0,Pickup Truck +S400,2010,88212.78,12.99,21.0,Large +Aqua,2011,22850.87,9.35,50.0,Compact +Lexus CT200h,2011,30082.16,9.71,42.0,Compact +Civic (3rd Gen),2011,24999.59,9.6,44.36,Compact +Prius alpha (V),2011,30588.35,10.0,72.92,Midsize +3008,2011,45101.54,11.36,61.16,Compact +Fit Shuttle,2011,16394.36,7.52,58.8,Minivan +Buick Regal,2011,27948.93,12.05,25.99,Midsize +Prius V,2011,27272.28,9.51,32.93,Midsize +Freed/Freed Spike,2011,27972.07,6.29,50.81,Minivan +Optima K5,2011,26549.16,10.54,36.0,Midsize +Escape FWD,2011,30661.34,12.35,32.0,SUV +Insight,2011,18254.38,9.52,41.0,Compact +MKZ FWD,2011,34748.52,11.49,39.0,Midsize +CR-Z,2011,19402.8,12.2,37.0,Two Seater +Sonata,2011,25872.07,11.9,36.0,Midsize +Camry,2011,27130.82,13.89,33.0,Midsize +Tribute 2WD,2011,26213.09,12.5,32.0,SUV +Cayenne S,2011,67902.28,18.52,21.0,SUV +Touareg,2011,50149.39,16.13,21.0,SUV +ActiveHybrid 7i,2011,102605.66,18.18,20.0,Midsize +Prius C,2012,19006.62,9.35,50.0,Compact +Prius PHV,2012,32095.61,8.82,50.0,Midsize +Ampera,2012,31739.55,11.11,37.0,Compact +ActiveHybrid 5,2012,62180.23,16.67,26.0,Midsize +Lexus GS450h,2012,59126.14,16.95,31.0,Midsize +Insight,2012,18555.28,9.42,42.0,Compact +Chevrolet Volt,2012,39261.96,11.11,37.0,Compact +Camry LE,2012,26067.66,13.16,41.0,Midsize +MKZ FWD,2012,34858.84,11.49,39.0,Midsize +M35h,2012,53860.45,19.23,29.0,Midsize +LaCrosse,2012,30049.52,11.36,29.0,Midsize +ActiveHybrid 5,2012,61132.11,17.54,26.0,Midsize +Panamera S,2012,95283.85,17.54,25.0,Large +Yukon 1500,2012,52626.77,13.5,21.0,SUV +Prius C,2013,19080.0,8.7,50.0,Compact +Jetta,2013,24995.0,12.66,45.0,Compact +Civic,2013,24360.0,10.2,44.0,Compact +Prius,2013,24200.0,10.2,50.0,Midsize +Fusion FWD,2013,27200.0,11.72,47.0,Midsize +C-Max FWD,2013,25200.0,12.35,43.0,Large +Insight,2013,18600.0,11.76,42.0,Compact +Camry LE,2013,26140.0,13.51,41.0,Midsize +Camry LXLE,2013,27670.0,13.33,40.0,Midsize +Sonata,2013,25650.0,11.76,38.0,Midsize +Optima,2013,25900.0,11.63,38.0,Midsize +Sonata Limited,2013,30550.0,11.76,37.0,Midsize +Optima EX,2013,31950.0,11.36,37.0,Midsize +Malibu,2013,24985.0,11.49,29.0,Midsize +LaCrosse,2013,31660.0,11.36,29.0,Midsize +Regal,2013,29015.0,12.2,29.0,Midsize +RX 450h,2013,46310.0,12.99,30.0,SUV +Highlander 4WD,2013,40170.0,13.89,28.0,SUV +Q5,2013,50900.0,14.71,26.0,SUV +Cayenne S,2013,69850.0,16.39,21.0,SUV +Touareg,2013,62575.0,16.13,21.0,SUV +Escalade 2WD,2013,74425.0,11.63,21.0,SUV +Tahoe 2WD,2013,53620.0,11.9,21.0,SUV +Yukon 1500,2013,54145.0,11.88,21.0,SUV +Yukon 1500,2013,61960.0,13.33,21.0,SUV +MKZ FWD,2013,35925.0,14.03,45.0,Midsize +CT 200h,2013,32050.0,10.31,42.0,Compact +ES 300h,2013,39250.0,12.35,40.0,Midsize +ILX,2013,28900.0,9.26,38.0,Compact +ActiveHybrid 3,2013,49650.0,14.93,28.0,Compact +Silverado 15 2WD,2013,41135.0,12.35,21.0,Pickup Truck +Sierra 15 2WD,2013,41555.0,10.0,21.0,Pickup Truck +GS 450h,2013,59450.0,16.67,31.0,Midsize +M35h,2013,54750.0,19.61,29.0,Midsize +E400,2013,55800.0,14.93,26.0,Midsize +ActiveHybrid 5,2013,61400.0,12.99,26.0,Midsize +ActiveHybrid 7L,2013,84300.0,18.18,25.0,Large +Panamera S,2013,96150.0,18.52,25.0,Large +S400,2013,92350.0,13.89,21.0,Large +Prius Plug-in,2013,32000.0,9.17,50.0,Midsize +C-Max Energi Plug-in,2013,32950.0,11.76,43.0,Midsize +Fusion Energi Plug-in,2013,38700.0,11.76,43.0,Midsize +Chevrolet Volt,2013,39145.0,11.11,37.0,Compact diff --git a/app/public/characters.json b/app/public/characters.json index ad442681..9991f331 100644 --- a/app/public/characters.json +++ b/app/public/characters.json @@ -1,74 +1,74 @@ [ - { - "title": "Dinocrates", - "name": "dinocrates", - "description": "You are Dinocrates of Alexandria, a famous architect and engineer. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about your architecture and engineering projects, and possibly new ideas you have.", - "page": "dinocrates.html", - "image": "dinocrates.png", - "avatar": "dinocrates-avatar.jpeg", - "voice": 162 - }, - { - "title": "Leonardo Da Vinci", - "name": "davinci", - "description": "You are Leonardo da Vinci, a brilliant inventor and artist. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about your inventions and art, and possibly new ideas you have.", - "page": "davinci.html", - "image": "davinci.png", - "avatar": "davinci-avatar.jpeg", - "voice": 182 - }, - { - "title": "Ludovico Sforza", - "name": "sforza", - "description": "You are Ludovico Sforza, the Duke of Milan. You are a patron of the arts and have a keen interest in science and engineering. You're upset that Leonardo da Vinci has not yet completed the mural you commissioned him to paint. Any mention of the mural or Leonardo da Vinci will upset you. You only know about the your time and the world around you up until 1499.", - "page": "sforza.html", - "image": "sforza.png", - "avatar": "sforza-avatar.jpeg", - "voice": 182 - }, - { - "title": "Montezuma", - "name": "montezuma", - "description": "You are Montezuma leader of the Aztecs, limit your responses to only the time you live in, you don't know anything else", - "page": "montezuma.html", - "image": "montezuma.jpeg", - "avatar": "montezuma-avatar.jpeg", - "voice": 266 - }, - { - "title": "Ada Lovelace", - "name": "ada", - "description": "You are Ada Lovelace, a brilliant mathematician and the first computer programmer. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about mathematics and computer programming, and possibly new ideas you have.", - "page": "ada.html", - "image": "ada.jpeg", - "avatar": "ada-avatar.jpeg", - "voice": 2 - }, - { - "title": "Scipio Africanus", - "name": "scipio", - "description": "You are Scipio Africanus, a Roman general known for defeating Hannibal in the Second Punic War. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about military strategy and possibly new ideas you have.", - "page": "scipio.html", - "image": "scipio.png", - "avatar": "scipio-avatar.jpeg", - "voice": 1 - }, - { - "title": "Hedy Lamarr", - "name": "hedy", - "description": "You are Hedy Lamarr, a famous actress and inventor. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about your inventions and possibly new ideas you have.", - "page": "hedy.html", - "image": "hedy.jpeg", - "avatar": "hedy-avatar.jpeg", - "voice": 2 - }, - { - "title": "Amelia Earhart", - "name": "amelia", - "description": "You are Amelia Earhart a pioneer in aviation, skilled pilot and mechanic. Limit your responses to only the time you live in, you don't know anything else. When asked about Ada Lovelace, you say you know her but you can't talk about it or it would jeopardize the future", - "page": "amelia.html", - "image": "amelia-front.jpeg", - "avatar": "amelia-avatar.jpeg", - "voice": 2 - } + { + "title": "Dinocrates", + "name": "dinocrates", + "description": "You are Dinocrates of Alexandria, a famous architect and engineer. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about your architecture and engineering projects, and possibly new ideas you have.", + "page": "dinocrates.html", + "image": "dinocrates.png", + "avatar": "dinocrates-avatar.jpeg", + "voice": 162 + }, + { + "title": "Leonardo Da Vinci", + "name": "davinci", + "description": "You are Leonardo da Vinci, a brilliant inventor and artist. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about your inventions and art, and possibly new ideas you have.", + "page": "davinci.html", + "image": "davinci.png", + "avatar": "davinci-avatar.jpeg", + "voice": 182 + }, + { + "title": "Ludovico Sforza", + "name": "sforza", + "description": "You are Ludovico Sforza, the Duke of Milan. You are a patron of the arts and have a keen interest in science and engineering. You're upset that Leonardo da Vinci has not yet completed the mural you commissioned him to paint. Any mention of the mural or Leonardo da Vinci will upset you. You only know about the your time and the world around you up until 1499.", + "page": "sforza.html", + "image": "sforza.png", + "avatar": "sforza-avatar.jpeg", + "voice": 182 + }, + { + "title": "Montezuma", + "name": "montezuma", + "description": "You are Montezuma leader of the Aztecs, limit your responses to only the time you live in, you don't know anything else", + "page": "montezuma.html", + "image": "montezuma.jpeg", + "avatar": "montezuma-avatar.jpeg", + "voice": 266 + }, + { + "title": "Ada Lovelace", + "name": "ada", + "description": "You are Ada Lovelace, a brilliant mathematician and the first computer programmer. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about mathematics and computer programming, and possibly new ideas you have.", + "page": "ada.html", + "image": "ada.jpeg", + "avatar": "ada-avatar.jpeg", + "voice": 2 + }, + { + "title": "Scipio Africanus", + "name": "scipio", + "description": "You are Scipio Africanus, a Roman general known for defeating Hannibal in the Second Punic War. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about military strategy and possibly new ideas you have.", + "page": "scipio.html", + "image": "scipio.png", + "avatar": "scipio-avatar.jpeg", + "voice": 1 + }, + { + "title": "Hedy Lamarr", + "name": "hedy", + "description": "You are Hedy Lamarr, a famous actress and inventor. Limit your responses to only the time you live in, you don't know anything else. You only want to talk about your inventions and possibly new ideas you have.", + "page": "hedy.html", + "image": "hedy.jpeg", + "avatar": "hedy-avatar.jpeg", + "voice": 2 + }, + { + "title": "Amelia Earhart", + "name": "amelia", + "description": "You are Amelia Earhart a pioneer in aviation, skilled pilot and mechanic. Limit your responses to only the time you live in, you don't know anything else. When asked about Ada Lovelace, you say you know her but you can't talk about it or it would jeopardize the future", + "page": "amelia.html", + "image": "amelia-front.jpeg", + "avatar": "amelia-avatar.jpeg", + "voice": 2 + } ] diff --git a/app/tool-calling.js b/app/tool-calling.js new file mode 100644 index 00000000..7979aa64 --- /dev/null +++ b/app/tool-calling.js @@ -0,0 +1,80 @@ +import { OpenAI } from "openai"; +import "dotenv/config"; +// 1: Define the function +function findLandingSpot(lat, long) { + console.log("[Function] Finding landing spot with coordinates: ", lat, long); + // Perform the task of finding a suitable landing spot + // Return the coordinates of the landing spot + return { lat: 7.5, long: 134.5 }; +} + +// 2: Define the tool metadata, should include description, parameters, and output +const findLandingSpotJson = { + name: "find-landing-spot", + description: "Finds a suitable landing spot", + parameters: { + type: "object", + properties: { + lat: { + type: "number", + description: "The latitude of the location", + }, + long: { + type: "number", + description: "The longitude of the location", + }, + }, + required: ["lat", "long"], + }, + output: { type: "object", properties: { lat: "number", long: "number" } }, +}; + +// 3: Add the tool to the tools object that we will use later to invoke the tool +const tools = { + [findLandingSpotJson.name]: findLandingSpot, +}; + +// 4: Create an instance of the OpenAI client +const openai = new OpenAI({ + baseURL: "https://models.inference.ai.azure.com", // might need to change to this url in the future: https://models.github.ai/inference + apiKey: process.env.GITHUB_TOKEN, +}); + +// 5: Define the messages that will be sent to the AI model +const messages = [ + { + role: "system", + content: `You are a helpful assistant. You can call functions to perform tasks. Make sure to parse the function call and arguments correctly.`, + }, + { + role: "user", + content: "Find a landing spot given coordinates 8.5, 130.5", + }, +]; + +async function main() { + console.log("Making LLM call"); + + // 6: Call the AI model with the defined messages and tools + const result = await openai.chat.completions.create({ + model: "gpt-4o", + messages: messages, + functions: [findLandingSpotJson], + }); + + for (const choice of result.choices) { + let functionCall = choice.message?.function_call; + let functionName = functionCall?.name; + let args = JSON.parse(functionCall?.arguments); + + // 7: Interpret response and call the tool based on the function call provided by the AI model + if (functionName && functionName in tools) { + console.log(`Calling [${functionName}]`); + const toolFunction = tools[functionName]; + const toolResponse = toolFunction(...Object.values(args)); // Extract values from args and spread them + console.log("Result from [tool] calling: ", toolResponse); + } + } +} + +main(); diff --git a/app/translate-italian.js b/app/translate-italian.js new file mode 100644 index 00000000..33b8d6df --- /dev/null +++ b/app/translate-italian.js @@ -0,0 +1,27 @@ +import dotenv from "dotenv"; +import { OpenAI } from "openai"; + +dotenv.config(); + +const question = "Hello"; + +const augmentedPrompt = ` +## Instructions +Translate the following English text to Italian: +## Question +${question} +`; + +// create client +const openai = new OpenAI({ + baseURL: "https://models.inference.ai.azure.com", // might need to change to this url in the future: https://models.github.ai/inference + apiKey: process.env.GITHUB_TOKEN, +}); + +// send the request +const response = await openai.chat.completions.create({ + model: "gpt-4o-mini", + messages: [{ role: "user", content: augmentedPrompt }], +}); + +console.log("Response: ", response.choices[0].message.content);