Add quick_ideas skill and job for Quick dinners (Feature 18)
CI / ci (push) Successful in 5m36s
CI / ci (pull_request) Successful in 5m34s

quick_ideas v1 suggests Quick dinners of one kind, crockpot or under30,
from the household context, never returning a name already shown: the
exclude list is checked against normalized names with harness.Similar.
POST /api/v1/ideas/quick {kind, exclude[]} validates both fields (no
default kind) and answers 202 {jobId}; the quick_ideas job asks for 12
ideas, grounds them through the same GroundEach rounds as
ideas_from_ingredients and keeps up to 6 whose grounded recipe is of the
kind (crockpot: method crockpot; under30: minutes_total <= 30), so the
model's estimate never decides. Fewer survivors make a shorter page,
never a padded one.

The grounding loop, failure clearing and failed-result view are now
shared generic helpers used by both idea jobs rather than a second copy.

Maestro task 243a6812-f52b-4215-a4a2-8eb599914f7e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 20:25:41 -04:00
co-authored by Claude Opus 5.5
parent 3c58e0c7f7
commit 290e3d3cd3
18 changed files with 1800 additions and 110 deletions
+5 -2
View File
@@ -192,7 +192,7 @@ func newTestSuggest(t *testing.T) *suggest.Service {
}
// newTestIdeas returns an ideas service with its own unstarted job runner
// and a generator that always fails.
// and generators that always fail.
func newTestIdeas(t *testing.T) *ideas.Service {
t.Helper()
st := newTestStore(t)
@@ -205,7 +205,10 @@ func newTestIdeas(t *testing.T) *ideas.Service {
fail := func(context.Context, string, skills.IdeasRequest) (skills.Ideas, error) {
return skills.Ideas{}, errors.New("no model in this test")
}
svc, err := ideas.NewService(g, fail, runner, logger)
failQuick := func(context.Context, string, skills.QuickIdeasRequest) (skills.QuickIdeaList, error) {
return skills.QuickIdeaList{}, errors.New("no model in this test")
}
svc, err := ideas.NewService(st, g, fail, failQuick, runner, logger)
if err != nil {
t.Fatal(err)
}