ai cooking
0
fork

Configure Feed

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

simpler high level spans (#534)

* simpler high level spans

* unused

---------

Co-authored-by: paul miller <paul.miller>

authored by

Paul Miller
paul miller
and committed by
GitHub
c062ba3b 5e5811e0

+30
+6
internal/recipes/critique/manager.go
··· 10 10 "careme/internal/ai" 11 11 "careme/internal/cache" 12 12 "careme/internal/config" 13 + 14 + "go.opentelemetry.io/otel" 13 15 ) 14 16 15 17 const MinimumRecipeScore = 8 ··· 72 74 return mc.critiquer.Ready(ctx) 73 75 } 74 76 77 + var tracer = otel.Tracer("careme/internal/recipes/critiques") 78 + 75 79 func (mc *multiCritiquer) CritiqueRecipes(ctx context.Context, recipes []ai.Recipe) <-chan Result { 76 80 results := make(chan Result, len(recipes)) 77 81 mc.wg.Add(len(recipes)) ··· 80 84 for _, recipe := range recipes { 81 85 localWg.Go(func() { 82 86 defer mc.wg.Done() 87 + ctx, span := tracer.Start(ctx, "critques.recipe") 88 + defer span.End() 83 89 critique, err := mc.critiquer.CritiqueRecipe(ctx, recipe) 84 90 results <- Result{ 85 91 Recipe: &recipe,
+15
internal/recipes/generator.go
··· 16 16 17 17 "github.com/samber/lo" 18 18 "github.com/samber/lo/mutable" 19 + "go.opentelemetry.io/otel" 20 + "go.opentelemetry.io/otel/attribute" 19 21 ) 20 22 21 23 type aiClient interface { ··· 38 40 staples staplesService 39 41 statusWriter statusWriter 40 42 } 43 + 44 + var tracer = otel.Tracer("careme/internal/recipes") 41 45 42 46 func NewGenerator(aiClient aiClient, critiquer critique.Service, staples staplesService, statuses statusWriter) (*generatorService, error) { 43 47 if aiClient == nil { ··· 58 62 } 59 63 60 64 func (g *generatorService) PickAWine(ctx context.Context, location string, recipe ai.Recipe, date time.Time) (*ai.WineSelection, error) { 65 + ctx, span := tracer.Start(ctx, "recipes.pickawine") 66 + defer span.End() 61 67 var styles []string 62 68 for _, style := range recipe.WineStyles { 63 69 style = strings.TrimSpace(style) ··· 102 108 // if we have a response id one of the three should be true? Or did they just not care and hit try again? 103 109 if p.ResponseID != "" && (p.Instructions != "" || len(p.Saved) > 0 || len(p.Dismissed) > 0) { 104 110 slog.InfoContext(ctx, "Regenerating recipes for location", "location", p.String(), "response_id", p.ResponseID) 111 + ctx, span := tracer.Start(ctx, "recipes.regenerate") 112 + defer span.End() 105 113 instructions := regenerateInstructions(p) 106 114 107 115 // TODO give them some sort of status. ··· 125 133 return shoppingList, nil 126 134 } 127 135 136 + ctx, span := tracer.Start(ctx, "recipes.generate") 137 + defer span.End() 128 138 slog.InfoContext(ctx, "Generating recipes for location", "location", p.String()) 129 139 ingredients, err := g.staples.FetchStaples(ctx, p) 130 140 if err != nil { ··· 141 151 mutable.Shuffle(ingredients) 142 152 143 153 instructions := []string{p.Directive, p.Instructions} 154 + 144 155 shoppingList, err := g.aiClient.GenerateRecipes(ctx, p.Location, ingredients, instructions, p.Date, p.LastRecipes) 145 156 if err != nil { 146 157 return nil, fmt.Errorf("failed to generate recipes with AI: %w", err) ··· 210 221 if g.critiquer == nil { 211 222 return shoppingList, nil 212 223 } 224 + ctx, span := tracer.Start(ctx, "recipes.critique") 225 + defer span.End() 226 + 213 227 g.writeStatus(ctx, hash, titles("Getting feeeback on these recipes:", shoppingList.Recipes)) 214 228 results := g.critiquer.CritiqueRecipes(ctx, shoppingList.Recipes) 215 229 good, garbage := critique.Split(ctx, results, critique.MinimumRecipeScore) ··· 219 233 if len(garbage) == 0 { 220 234 return shoppingList, nil 221 235 } 236 + span.SetAttributes(attribute.Bool("regenaftercrique", true)) 222 237 slog.InfoContext(ctx, "Regenerating recipes based on critique feedback:", "garbage_count", len(garbage), "good_count", len(good)) 223 238 garbageRecipes := lo.Map(garbage, func(r critique.Result, _ int) ai.Recipe { return *r.Recipe }) 224 239 g.writeStatus(ctx, hash, titles("Making adjustments to these recipes: ", garbageRecipes))
+9
internal/recipes/staples.go
··· 23 23 "careme/internal/wholefoods" 24 24 25 25 "github.com/samber/lo" 26 + "go.opentelemetry.io/otel/attribute" 26 27 ) 27 28 28 29 type identityProvider interface { ··· 59 60 if err != nil { 60 61 return nil, err 61 62 } 63 + ctx, span := tracer.Start(ctx, "staples.fetchstaples") 64 + span.SetAttributes(attribute.String("backend", fmt.Sprintf("%T", provider))) 65 + defer span.End() 62 66 return provider.FetchStaples(ctx, locationID) 63 67 } 64 68 ··· 67 71 if err != nil { 68 72 return nil, err 69 73 } 74 + ctx, span := tracer.Start(ctx, "staples.getingredients") 75 + span.SetAttributes(attribute.String("backend", fmt.Sprintf("%T", provider))) 76 + defer span.End() 70 77 return provider.GetIngredients(ctx, locationID, searchTerm, skip) 71 78 } 72 79 ··· 155 162 return nil, fmt.Errorf("failed to get ingredients for staples for %s: %w", locationID, err) 156 163 } 157 164 165 + ctx, span := tracer.Start(ctx, "staples.gradeingredients") 166 + defer span.End() 158 167 graded, err := s.grader.GradeIngredients(ctx, ingredients) 159 168 if err != nil { 160 169 slog.ErrorContext(ctx, "failed to grade cached staples", "error", err)