|
| 1 | +// This script uses GenAIScript (https://aka.ms/genaiscript) |
| 2 | +// to generate the menu for a burger restaurant. |
| 3 | +import { z } from "@genaiscript/runtime"; |
| 4 | + |
| 5 | +const role = `## Role |
| 6 | +You're a renowned chef with a passion for creating amazing burgers. You have a deep knowledge of American cuisine and international flavors that appeal to diverse customers.`; |
| 7 | + |
| 8 | +// ---------------------------------------------------------------------------- |
| 9 | +// Generate burger menu |
| 10 | + |
| 11 | +export const burgerSchema = z.object({ |
| 12 | + id: z.string(), |
| 13 | + name: z.string(), |
| 14 | + description: z.string(), |
| 15 | + price: z.number(), |
| 16 | + imageUrl: z.string(), |
| 17 | + toppings: z.array(z.string()), |
| 18 | +}); |
| 19 | +export const burgerMenuSchema = z.array(burgerSchema); |
| 20 | + |
| 21 | +const { text: burgers } = await runPrompt((_) => { |
| 22 | + const schema = _.defSchema("SCHEMA", burgerMenuSchema); |
| 23 | + _.$`${role} |
| 24 | +
|
| 25 | +## Task |
| 26 | +You have to create a selection of 10 burgers for a burger restaurant. The menu should include a variety of flavors and styles, including classic American burgers, gourmet specialty burgers, and international fusion burgers. Each burger should have a name, description, and a list of toppings. The menu must include options for vegetarian, vegan and gluten-free burgers. |
| 27 | +
|
| 28 | +## Output |
| 29 | +The output should be an array of JSON objects that conforms to the following schema: |
| 30 | +${schema} |
| 31 | +
|
| 32 | +Use simple, incremental ID numbers starting from 1 for each burger. |
| 33 | +ImageUrl should be an empty string for now, as the images will be added later. |
| 34 | +`; |
| 35 | +}); |
| 36 | + |
| 37 | +// ---------------------------------------------------------------------------- |
| 38 | +// Generate toppings |
| 39 | + |
| 40 | +export const toppingSchema = z.object({ |
| 41 | + id: z.string(), |
| 42 | + name: z.string(), |
| 43 | + description: z.string(), |
| 44 | + price: z.number(), |
| 45 | + imageUrl: z.string(), |
| 46 | + category: z.enum([ |
| 47 | + "vegetable", |
| 48 | + "meat", |
| 49 | + "cheese", |
| 50 | + "sauce", |
| 51 | + "bun", |
| 52 | + "extras", |
| 53 | + ]), |
| 54 | +}); |
| 55 | +export const toppingMenuSchema = z.array(toppingSchema); |
| 56 | +const { text: toppings } = await runPrompt((_) => { |
| 57 | + const burgerMenu = def("BURGERS", burgers, { language: "json" }); |
| 58 | + const schema = _.defSchema("SCHEMA", toppingMenuSchema); |
| 59 | + _.$`${role} |
| 60 | +
|
| 61 | +## Task |
| 62 | +You have to create a selection of toppings for a burger restaurant. The toppings must include all the ones already used in the ${burgerMenu}, as well as a few extra ones to cover all the categories if needed. Bun are not considered toppings, but rather part of the burger itself. |
| 63 | +
|
| 64 | +## Output |
| 65 | +The output should be an array of JSON objects that conforms to the following schema: |
| 66 | +${schema} |
| 67 | +
|
| 68 | +Use simple, incremental ID numbers starting from 1 for each topping. |
| 69 | +ImageUrl should be an empty string for now, as the images will be added later. |
| 70 | +`; |
| 71 | +}); |
| 72 | + |
| 73 | +// ---------------------------------------------------------------------------- |
| 74 | +// Replace toppings with their IDs in burgers |
| 75 | + |
| 76 | +const { text: finalBurgers } = await runPrompt((_) => { |
| 77 | + const burgerMenu = _.def("BURGERS", burgers, { language: "json" }); |
| 78 | + const toppingMenu = _.def("TOPPINGS", toppings, { language: "json" }); |
| 79 | + const schema = _.defSchema("SCHEMA", burgerMenuSchema); |
| 80 | + _.$`${role} |
| 81 | +
|
| 82 | +## Task |
| 83 | +For each burger in the ${burgerMenu}, replace the toppings with their IDs from the ${toppingMenu}. The output should be a valid JSON array of burgers, where each burger has a list of topping IDs instead of names. |
| 84 | +
|
| 85 | +## Output |
| 86 | +The output should be an array of JSON objects that conforms to the following schema: |
| 87 | +${schema} |
| 88 | +`; |
| 89 | +}); |
| 90 | + |
| 91 | +// ---------------------------------------------------------------------------- |
| 92 | +// Sanity check |
| 93 | + |
| 94 | +const parsedBurgers = burgerMenuSchema.parse(JSON.parse(finalBurgers)); |
| 95 | +const parsedToppings = toppingMenuSchema.parse(JSON.parse(toppings)); |
| 96 | +const toppingIds = new Set(parsedToppings.map((topping) => topping.id)); |
| 97 | + |
| 98 | +for (const burger of parsedBurgers) { |
| 99 | + // Check that all toppings are valid |
| 100 | + for (const topping of burger.toppings) { |
| 101 | + if (!toppingIds.has(topping)) { |
| 102 | + throw new Error(`Invalid topping ID ${topping} in burger ${burger.name}`); |
| 103 | + } |
| 104 | + } |
| 105 | + // Check that the burger has at least one topping |
| 106 | + if (burger.toppings.length === 0) { |
| 107 | + throw new Error(`Burger ${burger.name} has no toppings`); |
| 108 | + } |
| 109 | + // Check that the burger has a valid price |
| 110 | + if (burger.price <= 0) { |
| 111 | + throw new Error(`Burger ${burger.name} has an invalid price`); |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +// ---------------------------------------------------------------------------- |
| 116 | +// Save files |
| 117 | + |
| 118 | +await workspace.writeText("data/burgers.json", finalBurgers); |
| 119 | +await workspace.writeText("data/toppings.json", toppings); |
0 commit comments