From 861416072dd57d53391c3882a9f38fa99a8f9d8b Mon Sep 17 00:00:00 2001 From: Hassan Bazzi Date: Fri, 26 May 2023 17:38:55 -0700 Subject: [PATCH] add a food expert example (#1) --- .env.example | 1 + examples/calcEval.ts | 50 +++++ examples/equationProducer.ts | 52 +++++ examples/fixtures/calc.ts | 396 +++++++++++++++++++++++++++++++++++ examples/foodExpert.ts | 65 ++++++ examples/jsonSummary.ts | 41 ++++ examples/llmWithSearch.ts | 55 +++++ examples/sentiment.ts | 42 ++++ examples/summary.ts | 16 ++ 9 files changed, 718 insertions(+) create mode 100644 examples/calcEval.ts create mode 100644 examples/equationProducer.ts create mode 100644 examples/fixtures/calc.ts create mode 100644 examples/foodExpert.ts create mode 100644 examples/jsonSummary.ts create mode 100644 examples/llmWithSearch.ts create mode 100644 examples/sentiment.ts create mode 100644 examples/summary.ts diff --git a/.env.example b/.env.example index bff4b1c..f3ee74f 100644 --- a/.env.example +++ b/.env.example @@ -6,3 +6,4 @@ # ------------------------------------------------------------------------------ OPENAI_API_KEY= +METAPHOR_API_KEY= \ No newline at end of file diff --git a/examples/calcEval.ts b/examples/calcEval.ts new file mode 100644 index 0000000..5c3f665 --- /dev/null +++ b/examples/calcEval.ts @@ -0,0 +1,50 @@ +import dotenv from 'dotenv-safe' +import { OpenAIClient } from 'openai-fetch' +import { z } from 'zod' + +import { Agentic } from '../src/llm' +import { getProblems } from './fixtures/calc' + +dotenv.config() + +export async function calcEval() { + const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! }) + const $ = new Agentic({ openai }) + + const problemSet = getProblems() + + Object.entries(problemSet).map(async ([setName, problems]) => { + console.log('running set', setName) + + const setExamples = problems.slice(0, 1).map(({ question, expected }) => ({ + input: question, + output: expected + })) + const answers = await Promise.all( + problems.slice(2).map(({ question, expected }) => { + return (async () => + $.gpt4(question) + .output(z.string()) + .examples(setExamples) + // .assert((output) => output === expected) + .call())() + }) + ) + + console.log( + `======== +Results for ${setName} + : | +=======` + ) + problems.slice(2).forEach((problem, i) => { + console.log( + `${problem.expected} : ${answers[i]} | ${ + problem.expected === answers[i] ? '✅' : '❌' + }}` + ) + }) + }) +} + +calcEval() diff --git a/examples/equationProducer.ts b/examples/equationProducer.ts new file mode 100644 index 0000000..bd4542c --- /dev/null +++ b/examples/equationProducer.ts @@ -0,0 +1,52 @@ +import dotenv from 'dotenv-safe' +import { OpenAIClient } from 'openai-fetch' +import { z } from 'zod' + +import { Agentic } from '../src' + +dotenv.config() + +export async function equationProducer() { + const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! }) + const $ = new Agentic({ openai }) + + const examples = [ + { input: 'What is 37593 * 67?', output: '37593 * 67' }, + { + input: + "Janet's ducks lay 16 eggs per day. She eats three for breakfast every morning and bakes muffins for her friends every day with four. She sells the remainder at the farmers' market daily for $2 per fresh duck egg. How much in dollars does she make every day at the farmers' market?", + output: '(16-3-4)*2' + }, + { + input: + 'A robe takes 2 bolts of blue fiber and half that much white fiber. How many bolts in total does it take?', + output: '2 + 2/2' + } + ] + + const question = + 'Carla is downloading a 200 GB file. She can download 2 GB/minute, but 40% of the way through the download, the download fails. Then Carla has to restart the download from the beginning. How long did it take her to download the file in minutes?' + + const example = await $.gpt4( + `Give me the equation for the following math problem: {{question}}` + ) + .input(z.object({ question: z.string() })) + .output({ + question: z.string(), + equation: z.string(), + predictedAnswer: z.number() + }) + .examples(examples) + // .assert( + // (output) => + // output.equation === '((200 x 0.6) / 2) + (200 / 2)' && + // output.predictedAnswer === 100 + // ) + .call({ + question + }) + + console.log('example', example) +} + +equationProducer() diff --git a/examples/fixtures/calc.ts b/examples/fixtures/calc.ts new file mode 100644 index 0000000..75166eb --- /dev/null +++ b/examples/fixtures/calc.ts @@ -0,0 +1,396 @@ +export type Problem = { + id: string + question: string + expected: string + grade: string + kind: string +} + +function decimalCalcProblems(places: number, placesText: string): Problem[] { + return [ + { + id: `${placesText}-calc-0001`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of adding -942.12 and 1441.23? Give answer rounded to ${placesText} decimal places.`, + expected: (-942.12 + 1441.23).toFixed(places) + }, + { + id: `${placesText}-calc-0002`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of multiplying -942.12 by 1441.23? Give answer rounded to ${placesText} decimal places.`, + expected: (-942.12 * 1441.23).toFixed(places) + }, + { + id: `${placesText}-calc-0003`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the square root of 1441.23? Give answer rounded to ${placesText} decimal places.`, + expected: Math.sqrt(1441.23).toFixed(places) + }, + { + id: `${placesText}-calc-0004`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the absolute value of -942.12? Give answer rounded to ${placesText} decimal places.`, + expected: Math.abs(-942.12).toFixed(places) + }, + { + id: `${placesText}-calc-0005`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the mean of -942.12 and 1441.23? Give answer rounded to ${placesText} decimal places.`, + expected: ((-942.12 + 1441.23) / 2).toFixed(places) + }, + { + id: `${placesText}-calc-0006`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the sign of -942.12? Give answer rounded to ${placesText} decimal places.`, + expected: Math.sign(-942.12).toFixed(places) + }, + { + id: `${placesText}-calc-0007`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of calculating e raised to the power of 2? Give answer rounded to ${placesText} decimal places.`, + expected: Math.exp(2).toFixed(places) + }, + { + id: `${placesText}-calc-0008`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the natural logarithm of 1441.23? Give answer rounded to ${placesText} decimal places.`, + expected: Math.log(1441.23).toFixed(places) + }, + { + id: `${placesText}-calc-0009`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of calculating sine of -1.12? Give answer rounded to ${placesText} decimal places.`, + expected: Math.sin(-1.12).toFixed(places) + }, + { + id: `${placesText}-calc-0010`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of calculating cosine of 1.23? Give answer rounded to ${placesText} decimal places.`, + expected: Math.cos(1.23).toFixed(places) + }, + { + id: `${placesText}-calc-0011`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of calculating tangent of -1.12? Give answer rounded to ${placesText} decimal places.`, + expected: Math.tan(-1.12).toFixed(places) + }, + { + id: `${placesText}-calc-0012`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of calculating arctangent of 1.23? Give answer in radians rounded to ${placesText} decimal places.`, + expected: Math.atan(1.23).toFixed(places) + }, + { + id: `${placesText}-calc-0013`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of calculating arccosine of 0.12? Give answer in radians rounded to ${placesText} decimal places.`, + expected: Math.acos(0.12).toFixed(places) + }, + { + id: `${placesText}-calc-0014`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of calculating arcsine of 0.23? Give answer in radians rounded to ${placesText} decimal places.`, + expected: Math.asin(0.23).toFixed(places) + }, + { + id: `${placesText}-calc-0015`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of adding -942.1421 and 1441.134? Give answer rounded to ${placesText} decimal places.`, + expected: (-942.1421 + 1441.134).toFixed(places) + }, + { + id: `${placesText}-calc-0016`, + grade: `6`, + kind: `decimal calculation`, + question: `Calculate (2.12^3)^2. Give answer rounded to ${placesText} decimal places.`, + expected: ((2.12 ** 3) ** 2).toFixed(places) + }, + { + id: `${placesText}-calc-0017`, + grade: `6`, + kind: `decimal calculation`, + question: `Calculate (2.18^3)^4. Give answer rounded to ${placesText} decimal places.`, + expected: ((2.18 ** 3) ** 4).toFixed(places) + }, + { + id: `${placesText}-calc-0018`, + grade: `6`, + kind: `decimal calculation`, + question: `Calculate (2.3*3)^4. Give answer rounded to ${placesText} decimal places.`, + expected: ((2.3 * 3) ** 4).toFixed(places) + }, + { + id: `${placesText}-calc-0019`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of adding 6.421 and -4.2? Give answer rounded to ${placesText} decimal places.`, + expected: (6.421 + -4.2).toFixed(places) + }, + { + id: `${placesText}-calc-0020`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of subtracting 8.133 from 17.3? Give answer rounded to ${placesText} decimal places.`, + expected: (17.3 - 8.133).toFixed(places) + }, + { + id: `${placesText}-calc-0021`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the result of multiplying -0.0431 by 6.42? Give answer rounded to ${placesText} decimal places.`, + expected: (-0.0431 * 6.42).toFixed(places) + }, + { + id: `${placesText}-calc-0022`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the square root of 17.3? Give answer rounded to ${placesText} decimal places.`, + expected: Math.sqrt(17.3).toFixed(places) + }, + { + id: `${placesText}-calc-0023`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the absolute value of -4.213? Give answer rounded to ${placesText} decimal places.`, + expected: Math.abs(-4.213).toFixed(places) + }, + { + id: `${placesText}-calc-0024`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the natural logarithm of 8.131? Give answer rounded to ${placesText} decimal places.`, + expected: Math.log(8.131).toFixed(places) + }, + { + id: `${placesText}-calc-0025`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the sine of -0.413 radians? Give answer rounded to ${placesText} decimal places.`, + expected: Math.sin(-0.413).toFixed(places) + }, + { + id: `${placesText}-calc-0026`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the cosine of 6.42 radians? Give answer rounded to ${placesText} decimal places.`, + expected: Math.cos(6.42).toFixed(places) + }, + { + id: `${placesText}-calc-0027`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the tangent of -4.21 radians? Give answer rounded to ${placesText} decimal places.`, + expected: Math.tan(-4.21).toFixed(places) + }, + { + id: `${placesText}-calc-0028`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the arctangent of 17.3? Give answer in radians rounded to ${placesText} decimal places.`, + expected: Math.atan(17.3).toFixed(places) + }, + { + id: `${placesText}-calc-0029`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the arccosine of -0.04? Give answer in radians rounded to ${placesText} decimal places.`, + expected: Math.acos(-0.04).toFixed(places) + }, + { + id: `${placesText}-calc-0030`, + grade: `6`, + kind: `decimal calculation`, + question: `What is the arcsine of 0.113? Give answer in radians rounded to ${placesText} decimal places.`, + expected: Math.asin(0.113).toFixed(places) + }, + { + id: `${placesText}-calc-0031`, + grade: `6`, + kind: `decimal calculation`, + question: `What is 6.21 raised to power 8. Give answer rounded to ${placesText} decimal places.`, + expected: (6.21 ** 8).toFixed(places) + }, + { + id: `${placesText}-calc-0032`, + grade: `6`, + kind: `decimal calculation`, + question: `What is e raised to power pi/2. Give answer rounded to ${placesText} decimal places.`, + expected: Math.exp(Math.PI / 2).toFixed(places) + }, + { + id: `${placesText}-calc-0033`, + grade: `6`, + kind: `decimal calculation`, + question: `What is pi/2 raised to power e. Give answer rounded to ${placesText} decimal places.`, + expected: ((Math.PI / 2) ** Math.E).toFixed(places) + }, + { + id: `${placesText}-calc-0034`, + grade: `6`, + kind: `decimal calculation`, + question: `What is e raised to power 3.2. Give answer rounded to ${placesText} decimal places.`, + expected: Math.exp(3.2).toFixed(places) + } + ] +} + +function decimalComparisonProblems(): Problem[] { + return [ + { + id: `calc-0035`, + grade: `6`, + kind: `decimal comparison`, + question: `Is 0.31 plus 0.21 greater than 0.11 plus 0.99? Answer "true" or "false" without quotes.`, + expected: (0.31 + 0.21 > 0.11 + 0.99).toString() + }, + { + id: `calc-0036`, + grade: `6`, + kind: `decimal comparison`, + question: `Is 0.56 minus 0.23 less than or equal to 0.78 divided by 0.34? Answer "true" or "false" without quotes.`, + expected: (0.56 - 0.23 <= 0.78 / 0.34).toString() + }, + { + id: `calc-0037`, + grade: `6`, + kind: `decimal comparison`, + question: `Is 0.67 times 0.45 not equal to 0.23 plus 0.54? Answer "true" or "false" without quotes.`, + expected: (0.67 * 0.45 != 0.23 + 0.54).toString() + }, + { + id: `calc-0038`, + grade: `6`, + kind: `decimal comparison`, + question: `Is 0.89 divided by 0.12 greater than or equal to 0.34 minus 0.12? Answer "true" or "false" without quotes.`, + expected: (0.89 / 0.12 >= 0.34 - 0.12).toString() + }, + { + id: `calc-0039`, + grade: `6`, + kind: `decimal comparison`, + question: `Is 0.45 plus 0.67 less than or equal to 1 minus (1/3)? Answer "true" or "false" without quotes.`, + expected: (0.45 + 0.67 <= 1 - 1 / 3).toString() + }, + { + id: `calc-0040`, + grade: `6`, + kind: `decimal comparison`, + question: `Is (1/2) times (1/3) less than or equal to (1/4) plus (1/8)? Answer "true" or "false" without quotes.`, + expected: ((1 / 2) * (1 / 3) <= 1 / 4 + 1 / 8).toString() + }, + { + id: `calc-0041`, + grade: `6`, + kind: `decimal comparison`, + question: `Is (1/5) divided by (1/7) greater than or equal to (1/6) minus (1/8)? Answer "true" or "false" without quotes.`, + expected: (1 / 5 / (1 / 7) >= 1 / 6 - 1 / 8).toString() + }, + { + id: `calc-0042`, + grade: `6`, + kind: `decimal comparison`, + question: `Is (2/3) times (3/4) greater than or equal to (5/6) minus (7/8)? Answer "true" or "false" without quotes.`, + expected: ((2 / 3) * (3 / 4) >= 5 / 6 - 7 / 8).toString() + }, + { + id: `calc-0043`, + grade: `6`, + kind: `decimal comparison`, + question: `Is (9/10) divided by (7/10) less than or equal to (5/6) plus (7/8)? Answer "true" or "false" without quotes.`, + expected: (9 / 10 / (7 / 10) <= 5 / 6 + 7 / 8).toString() + }, + { + id: `calc-0044`, + grade: `6`, + kind: `decimal comparison`, + question: `Is sqrt(2)/2 times sqrt(3)/3 less than or equal to sqrt(5)/5 plus sqrt(7)/7? Answer "true" or "false" without quotes.`, + expected: ( + ((Math.sqrt(2) / 2) * Math.sqrt(3)) / 3 <= + Math.sqrt(5) / 5 + Math.sqrt(7) / 7 + ).toString() + }, + { + id: `calc-0045`, + grade: `6`, + kind: `decimal comparison`, + question: `Is sqrt(11)/11 divided by sqrt(13)/13 greater than or equal to sqrt(17)/17 minus sqrt(19)/19? Answer "true" or "false" without quotes.`, + expected: ( + Math.sqrt(11) / 11 / (Math.sqrt(13) / 13) >= + Math.sqrt(17) / 17 - Math.sqrt(19) / 19 + ).toString() + }, + { + id: `calc-0046`, + grade: `6`, + kind: `decimal comparison`, + question: `Is sqrt(23)/23 times sqrt(29)/29 greater than or equal to sqrt(31)/31 minus sqrt(37)/37? Answer "true" or "false" without quotes.`, + expected: ( + ((Math.sqrt(23) / 23) * Math.sqrt(29)) / 29 >= + Math.sqrt(31) / 31 - Math.sqrt(37) / 37 + ).toString() + } + ] +} + +function integerCalcProblems(): Problem[] { + return [ + { + id: `calc-0047`, + grade: `6`, + kind: `integer comparison`, + question: `Is 31 plus 210 greater than 11 plus 99? Answer "true" or "false" without quotes.`, + expected: (31 + 210 > 11 + 99).toString() + }, + { + id: `calc-0048`, + grade: `6`, + kind: `integer comparison`, + question: `Is 100 divided by 5 less than or equal to 20? Answer "true" or "false" without quotes.`, + expected: (100 / 5 <= 20).toString() + }, + { + id: `calc-0049`, + grade: `6`, + kind: `integer comparison`, + question: `Is 999 minus 888 greater than or equal to 100? Answer "true" or "false" without quotes.`, + expected: (999 - 888 >= 100).toString() + }, + { + id: `calc-0050`, + grade: `6`, + kind: `integer comparison`, + question: `Is 50 times 10 not equal to 500? Answer "true" or "false" without quotes.`, + expected: (50 * 10 != 500).toString() + }, + { + id: `calc-0051`, + grade: `6`, + kind: `integer comparison`, + question: `Is 999 divided by 3 less than or equal to 333? Answer "true" or "false" without quotes.`, + expected: (999 / 3 <= 333).toString() + } + ] +} +export const getProblems = () => ({ + one: decimalCalcProblems(1, 'one'), + two: decimalCalcProblems(2, 'two'), + three: decimalCalcProblems(3, 'three'), + four: decimalCalcProblems(4, 'four'), + comparison: decimalComparisonProblems(), + integer: integerCalcProblems() +}) diff --git a/examples/foodExpert.ts b/examples/foodExpert.ts new file mode 100644 index 0000000..8f3eeef --- /dev/null +++ b/examples/foodExpert.ts @@ -0,0 +1,65 @@ +import dotenv from 'dotenv-safe' +import { OpenAIClient } from 'openai-fetch' +import { z } from 'zod' + +import { Agentic } from '../src' +import { summaryAgent } from './summary' + +dotenv.config() + +async function main() { + const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! }) + const $ = new Agentic({ openai }) + + /////////////////////////// + // Learn about new food everyday and stay up to date + /////////////////////////// + + // const countryIsoValidation = `/^A[^ABCHJKNPVY]|B[^CKPUX]|C + // [^BEJPQST]|D[EJKMOZ]|E[CEGHRST]|F[IJKMOR]|G[^CJ + // KOVXZ]|H[KMNRTU]|I[DEL-OQ-T]|J[EMOP]|K[EGHIMNPR + // WYZ]|L[ABCIKR-VY]|M[^BIJ]|N[ACEFGILOPRUZ]|OM|P[ + // AE-HK-NRSTWY]|QA|R[EOSUW]|S[^FPQUW]|T[^ABEIPQSU + // XY]|U[AGMSYZ]|V[ACEGINU]|WF|WS|YE|YT|Z[AMW]$/ix` + + const foodSchema = z.object({ + name: z.string(), + countryOfOrigin: z.string(), + ingredients: z.string().array(), + linkToLearnMore: z.string() + }) + + const foodAgent = await $.gpt4( + `You are a world food expert. Provide me with a new food to learn about. My dietary restrictions are: {{dietaryRestrictions}}` + ) + .input(z.object({ dietaryRestrictions: z.string().array() })) + .output(foodSchema) + // .assert( (output) => { + // z.string().url(output.linkToLearnMore) + // }) + // .assertRegex({ + // value: output => output.countryOfOrigin, + // regex: countryIsoValidation, + // message: 'Country of origin must be a valid ISO 3166-1 alpha-2 country code', + // retry: true + // }) + .call({ + dietaryRestrictions: ['vegan', 'vegetarian', 'gluten-free'] + }) + + const article = await $.browse(foodAgent.linkToLearnMore) + const summary = await summaryAgent.call({ article }) + + const email = await $.gpt4( + `Here is a summary of an article about food: {{summary}}. + Here is some more information about the food: {{foodInfo}}. + Write a nice email that I can send to myself that includes the summary and the food info. + Make it fun and interesting.` + ) + .input(z.object({ summary: z.string(), foodInfo: foodSchema })) + .output(z.string()) + + // sendEmail(email) +} + +main() diff --git a/examples/jsonSummary.ts b/examples/jsonSummary.ts new file mode 100644 index 0000000..d09a16f --- /dev/null +++ b/examples/jsonSummary.ts @@ -0,0 +1,41 @@ +import dotenv from 'dotenv-safe' +import { OpenAIClient } from 'openai-fetch' +import { z } from 'zod' + +import { Agentic } from '../src' + +dotenv.config() + +export async function sentimentAgent() { + const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! }) + const $ = new Agentic({ openai }) + + const article = await $.gpt4( + 'I want an article that seems like it was on Wikipedia. It should be 500 characters long.' + ).call() + + console.log('got an article', article) + + const example = await $.gpt4( + `You are a wikipedia article summarizer. However, + you return a bunch of important information about the article in JSON format. + You're really good at coming up with semantic labels for the information you find. + + Article: {{article}}` + ) + .input(z.object({ article: z.string() })) + .output( + z.object({ + title: z.string(), + serializedJsonSummary: z.string() + }) + ) + // .assert((output) => JSON.parse(output.serializedJsonSummary)) + .call({ + article + }) + + console.log('example', example) +} + +sentimentAgent() diff --git a/examples/llmWithSearch.ts b/examples/llmWithSearch.ts new file mode 100644 index 0000000..aa98697 --- /dev/null +++ b/examples/llmWithSearch.ts @@ -0,0 +1,55 @@ +import dotenv from 'dotenv-safe' +import { OpenAIClient } from 'openai-fetch' +import { z } from 'zod' + +import { + Agentic, + MetaphorSearchTool, + MetaphorSearchToolOutputSchema +} from '../src' + +dotenv.config() + +async function main() { + const metaphorSearch = new MetaphorSearchTool() + + const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! }) + + const $ = new Agentic({ openai }) + + const searchResults = await metaphorSearch + .call({ + query: 'news from today', + numResults: 5 + }) + .map((r) => r.result.title) + + console.log('searchResults', searchResults) + + const foodAgent = await $.gpt4( + `Give me a summary of today's news. Here is what I got back from a search engine: {{searchResults.results}}` + ) + .input( + z.object({ + searchResults: MetaphorSearchToolOutputSchema, + afaf: z.string() + }) + ) + .output( + z.object({ + summary: z.string(), + linkToLearnMore: z.string(), + metaData: z.object({ + title: z.string(), + keyTopics: z.string().array(), + datePublished: z.string() + }), + isWorthFollowingUp: z.boolean() + }) + ) + .call({ + searchResults + }) +} + +main() diff --git a/examples/sentiment.ts b/examples/sentiment.ts new file mode 100644 index 0000000..07f3e32 --- /dev/null +++ b/examples/sentiment.ts @@ -0,0 +1,42 @@ +import dotenv from 'dotenv-safe' +import { OpenAIClient } from 'openai-fetch' +import { z } from 'zod' + +import { Agentic } from '../src' + +dotenv.config() + +export async function sentimentAgent() { + const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! }) + const $ = new Agentic({ openai }) + + const examples = [ + { input: 'The food was digusting', output: 'negative' }, + { input: 'We had a fantastic night', output: 'positive' }, + { input: 'Recommended', output: 'positive' }, + { input: 'The waiter was rude', output: 'negative' } + ] + + const example = await $.gpt4( + `You are a sentiment-labelling assistant. Label the following texts as positive or negative: {{texts}}` + ) + .input(z.object({ texts: z.string().array() })) + .output(z.array(z.object({ text: z.string(), label: z.string() }))) + .examples(examples) + // .assert((output) => output.filter(({ label }) => + // !['positive', 'negative'].includes(label) + // ).length === 0 + // }) + .call({ + texts: [ + 'I went to this place and it was just so awful.', + 'I had a great time.', + 'I had a terrible time.', + 'I had a good time.' + ] + }) + + console.log('example', example) +} + +sentimentAgent() diff --git a/examples/summary.ts b/examples/summary.ts new file mode 100644 index 0000000..b840848 --- /dev/null +++ b/examples/summary.ts @@ -0,0 +1,16 @@ +import dotenv from 'dotenv-safe' +import { OpenAIClient } from 'openai-fetch' +import { z } from 'zod' + +import { Agentic } from '../src' + +dotenv.config() + +export async function summaryAgent() { + const openai = new OpenAIClient({ apiKey: process.env.OPENAI_API_KEY! }) + const $ = new Agentic({ openai }) + + return $.gpt4( + `You are an expert at summarizing web pages. Summarize this article for me: {{article}}` + ).input(z.object({ article: z.string() })) +}