ai cooking
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #201 from paulgmiller/wineresearch

prompt improvement and collect wine styles

authored by

Paul Miller and committed by
GitHub
3ef7ea6e ecfa50ab

+30 -10
+8 -1
cmd/ingredients/main.go
··· 46 46 } 47 47 48 48 for _, i := range ings { 49 - fmt.Println(toString(i.Description)) 49 + fmt.Printf("%s:$%s original ($%s)\n", toString(i.Description), toFloat(i.PriceSale), toFloat(i.PriceRegular)) 50 50 } 51 51 52 + } 53 + 54 + func toFloat(f *float32) string { 55 + if f == nil { 56 + return "0" 57 + } 58 + return fmt.Sprintf("%.2f", *f) 52 59 } 53 60 54 61 func toString(s *string) string {
+11 -9
internal/ai/client.go
··· 43 43 Instructions []string `json:"instructions"` 44 44 Health string `json:"health"` 45 45 DrinkPairing string `json:"drink_pairing"` 46 + WineStyles []string `json:"wine_styles"` 46 47 OriginHash string `json:"origin_hash,omitempty" jsonschema:"-"` //not in schema 47 48 Saved bool `json:"previously_saved,omitempty" jsonschema:"-"` //not in schema 48 49 } ··· 101 102 Generate distinct, practical recipes using the provided constraints to maximize ingredient freshness, quality, and value while ensuring meal variety. 102 103 103 104 # Instructions 104 - - Each meal must feature a protein and at least one side of either a vegetable and/or a starch. A combined dish (such as a pasta, stew, or similar) that incorporates a vegetable or starch alongside protein is acceptable and satisfies the side requirement. 105 + - Each meal must feature a protein and at least one side of either a vegetable and/or a starch. A combined dish (such as a pasta, stew, or similar) that incorporates a vegetable or starch is also good. 105 106 - Recipes should use diverse cooking methods and represent a variety of cuisines. 106 - - Provide clear, step-by-step instructions and an ingredient list for each recipe. 107 + - Provide clear, step-by-step instructions and an ingredient list for each recipe. repeat amounts and prep for each recipe in instructions. 107 108 - Recipes should take under 1 hour to prepare, unless the user asks for something longer 108 - - Optionally include a wine pairing suggestion for each recipe if appropriate. Suggest a local brand if possible. 109 - - Prioritize ingredients that are on sale (the bigger the discount, the higher the priority) 109 + - Optionally include a wine pairing suggestion for each recipe if appropriate. Suggest a couple of styles and a local brand if possible. Really put your Sommielier hat on for this. 110 + - Prioritize ingredients that are on sale (the bigger the discount, the higher the priority but but don't pay more for something on sale than a similar ingredient that isn't) 110 111 111 112 112 113 # Output Format ··· 116 117 - Ingredient list: should include quantities and price if in input. 117 118 - Step-by-step instructions starting with prep. Don't prefix with numbers. 118 119 - A guess at calorie count and healthiness 119 - - Optional wine or beer pairing. 120 + - Optional wine pairing guidance. 121 + - Three wine or less wine styles. 120 122 121 123 # Planning & Verification 122 124 - Before generating each recipe, reference your checklist to ensure variety in cooking methods and cuisines, and confirm ingredient prioritization matches sale/seasonal data.` ··· 217 219 func (c *Client) buildRecipeMessages(location *locations.Location, saleIngredients []kroger.Ingredient, instructions string, date time.Time, lastRecipes []string) (responses.ResponseInputParam, error) { 218 220 var messages []responses.ResponseInputItemUnionParam 219 221 //constants we might make variable later 220 - messages = append(messages, user("Each recipe should serve 2 people.")) 221 - messages = append(messages, user("generate 3 recipes")) 222 - messages = append(messages, user("Permitted cooking methods: oven, stove, grill, slow cooker")) 223 - //location and date for seasonal ingredientss 224 222 messages = append(messages, user("Prioritize ingredients that are in season for the current date and user's state location "+date.Format("January 2nd")+" in "+location.State+".")) 223 + messages = append(messages, user("Default: each recipe should serve 2 people.")) 224 + messages = append(messages, user("Default: generate 3 recipes")) 225 + messages = append(messages, user("Default: cooking methods: oven, stove, grill, slow cooker")) 226 + //location and date for seasonal ingredientss 225 227 226 228 //Available ingredients (in TOON format for token efficiency) 227 229 ingredientsMessage := "Ingredients currently on sale in TOON format\n"
+11
internal/recipes/server.go
··· 178 178 } 179 179 return 180 180 } 181 + styles := wineStyles(slist.Recipes) 182 + slog.InfoContext(ctx, "wines!", "hash", hashParam, "wine_styles", styles) 181 183 _, err = s.clerk.GetUserIDFromRequest(r) 182 184 signedIn := !errors.Is(err, auth.ErrNoSession) 183 185 FormatShoppingListHTML(p, *slist, signedIn, w) ··· 239 241 http.Error(w, "failed to save recipes", http.StatusInternalServerError) 240 242 return 241 243 } 244 + //styles := wineStyles(p.Saved) 245 + // todo regeenrate after grabbing list of wine styles from store. 242 246 slog.InfoContext(ctx, "finalized recipes", "user_id", currentUser.ID, "count", len(p.Saved)) 243 247 244 248 // Display the saved recipes ··· 261 265 s.kickgeneration(ctx, p, currentUser) 262 266 263 267 redirectToHash(w, r, hash, true /*useStart*/) 268 + } 269 + 270 + func wineStyles(recipes []ai.Recipe) []string { 271 + styles := lo.Flatten(lo.Map(recipes, func(r ai.Recipe, _ int) []string { 272 + return r.WineStyles 273 + })) 274 + return lo.Uniq(styles) 264 275 } 265 276 266 277 func (s *server) kickgeneration(ctx context.Context, p *generatorParams, currentUser *utypes.User) {