ai cooking
0
fork

Configure Feed

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

Merge pull request #74 from paulgmiller/pmiller/recipesavebug

fix params saving bug

authored by

Paul Miller and committed by
GitHub
df4292b7 543178a2

+29 -19
+2 -1
cmd/careme/middleware.go
··· 3 3 import ( 4 4 "log/slog" 5 5 "net/http" 6 + "runtime/debug" 6 7 "time" 7 8 ) 8 9 ··· 26 27 func (r *recoverer) ServeHTTP(w http.ResponseWriter, req *http.Request) { 27 28 defer func() { 28 29 if err := recover(); err != nil { 29 - slog.ErrorContext(req.Context(), "panic recovered", "error", err) 30 + slog.ErrorContext(req.Context(), "panic recovered", "error", err, "stack", debug.Stack()) 30 31 http.Error(w, "internal server error", http.StatusInternalServerError) 31 32 } 32 33 }()
+22 -15
internal/recipes/generator.go
··· 149 149 } 150 150 151 151 func (g *Generator) GenerateRecipes(ctx context.Context, p *generatorParams) error { 152 - slog.InfoContext(ctx, "Generating recipes for location", "location", p.String()) 153 152 154 153 hash := p.Hash() 155 154 generating, done := g.isGenerating(hash) ··· 162 161 163 162 var err error 164 163 if p.ConversationID != "" && p.Instructions != "" { 165 - // these should both alwas be true. Warn if not because its a caching bug? 164 + slog.InfoContext(ctx, "Regenerating recipes for location", "location", p.String(), "conversation_id", p.ConversationID) 165 + // these should both always be true. Warn if not because its a caching bug? 166 166 shoppingList, err := g.aiClient.Regenerate(ctx, p.Instructions, p.ConversationID) 167 167 if err != nil { 168 168 return fmt.Errorf("failed to regenerate recipes with AI: %w", err) 169 169 } 170 170 slog.InfoContext(ctx, "regenerated chat", "location", p.String(), "duration", time.Since(start), "hash", hash) 171 + 172 + paramsJSON := lo.Must(json.Marshal(p)) 173 + if err := g.cache.Set(p.Hash()+".params", string(paramsJSON)); err != nil { 174 + slog.ErrorContext(ctx, "failed to cache params", "location", p.String(), "error", err) 175 + return err 176 + } 171 177 return saveShoppingList(ctx, g.cache, shoppingList, p) 172 178 } 173 - 179 + slog.InfoContext(ctx, "Generating recipes for location", "location", p.String()) 174 180 ingredients, err := g.GetStaples(ctx, p) 175 181 if err != nil { 176 182 return fmt.Errorf("failed to get staples: %w", err) ··· 179 185 if err != nil { 180 186 return fmt.Errorf("failed to generate recipes with AI: %w", err) 181 187 } 188 + p.ConversationID = shoppingList.ConversationID 182 189 slog.InfoContext(ctx, "generated chat", "location", p.String(), "duration", time.Since(start), "hash", hash) 183 190 if err := saveShoppingList(ctx, g.cache, shoppingList, p); err != nil { 184 191 return fmt.Errorf("failed to save shopping list: %w", err) 185 192 } 186 - // Also cache the params for hash-based retrieval 187 - // TODO: Consider embedding the params directly in the shoppingList structure. 188 - // This would allow us to cache both the shopping list and its associated parameters together, 189 - // avoiding the need for a separate cache entry for params (currently stored as "<hash>.params"). 190 - // Embedding params could simplify cache management and ensure all relevant data is retrieved together. 191 - // Persist the latest conversation IDs with the params so follow-ups can reuse them. 192 - p.ConversationID = shoppingList.ConversationID 193 - paramsJSON := lo.Must(json.Marshal(p)) 194 - if err := g.cache.Set(p.Hash()+".params", string(paramsJSON)); err != nil { 195 - slog.ErrorContext(ctx, "failed to cache params", "location", p.String(), "error", err) 196 - return err 197 - } 193 + 198 194 return nil 199 195 } 200 196 ··· 216 212 return err 217 213 } 218 214 215 + // Also cache the params for hash-based retrieval 216 + // TODO: Consider embedding the params directly in the shoppingList structure. 217 + // This would allow us to cache both the shopping list and its associated parameters together, 218 + // avoiding the need for a separate cache entry for params (currently stored as "<hash>.params"). 219 + // Embedding params could simplify cache management and ensure all relevant data is retrieved together. 220 + // Persist the latest conversation IDs with the params so follow-ups can reuse them. 221 + paramsJSON := lo.Must(json.Marshal(p)) 222 + if err := cache.Set(p.Hash()+".params", string(paramsJSON)); err != nil { 223 + slog.ErrorContext(ctx, "failed to cache params", "location", p.String(), "error", err) 224 + return err 225 + } 219 226 return nil 220 227 } 221 228
+5 -3
internal/recipes/server.go
··· 67 67 Name: "Unknown Location", 68 68 }, time.Now()) 69 69 if recipe.OriginHash != "" { 70 - p, err = s.generator.LoadParamsFromHash(recipe.OriginHash) 70 + loadedp, err := s.generator.LoadParamsFromHash(recipe.OriginHash) 71 71 if err != nil { 72 72 slog.ErrorContext(ctx, "failed to load params for hash", "hash", recipe.OriginHash, "error", err) 73 - http.Error(w, "recipe not found or expired", http.StatusNotFound) 74 - return 73 + //http.Error(w, "recipe not found or expired", http.StatusNotFound) 74 + //return 75 + } else { 76 + p = loadedp 75 77 } 76 78 } 77 79