feat: cooking assistant can propose adding items to a shopping list
Second tool alongside createRecipe, same safety shape: addToShoppingList's execute only validates/echoes input, no DB write. The proposal card lets the user pick an existing list (fetched lazily) or name a new one, then confirms through the exact two-call flow AddToShoppingListButton already uses — POST /api/v1/shopping-lists (if new) then POST .../items — no new persistence code path. generateMealPlan intentionally not built as a tool: the existing /api/v1/ai/meal-plan/generate endpoint generates and writes in one step with a week/preferences input, not a specific plan payload, so it has no "save this exact draft" entry point to confirm against without a larger refactor. Documented as a known gap rather than forcing a weaker pattern. v0.46.0
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import { tool } from "ai";
|
||||
import { z } from "zod";
|
||||
|
||||
const AddToShoppingListInputSchema = z.object({
|
||||
items: z.array(z.object({
|
||||
rawName: z.string().min(1).max(200).describe("Ingredient/item name only, e.g. 'flour' — never combined with quantity/unit"),
|
||||
quantity: z.number().optional().describe("A number only, e.g. 0.25, 1.5, 2"),
|
||||
unit: z.string().max(50).optional().describe("e.g. 'cup', 'tbsp', 'g'"),
|
||||
})).min(1).max(100),
|
||||
suggestedListName: z.string().max(100).optional().describe("Suggested name if the user wants a new list, e.g. 'Weekend BBQ'"),
|
||||
});
|
||||
|
||||
export type AddToShoppingListToolInput = z.infer<typeof AddToShoppingListInputSchema>;
|
||||
|
||||
/**
|
||||
* Lets the cooking assistant propose adding items to a shopping list — same
|
||||
* safety shape as createRecipeTool: `execute` only validates/echoes the
|
||||
* input, no DB write. The chat UI resolves which list (existing or new)
|
||||
* and POSTs through the existing /api/v1/shopping-lists(/{id}/items)
|
||||
* endpoints, the same ones AddToShoppingListButton already uses.
|
||||
*/
|
||||
export const addToShoppingListTool = tool({
|
||||
description:
|
||||
"Propose adding ingredients/items to a shopping list, e.g. from a recipe just discussed. This only drafts the item list for the user to review and pick a target list — it does not save anything. Only call this when the user has actually asked to add items to a shopping list.",
|
||||
inputSchema: AddToShoppingListInputSchema,
|
||||
execute: async (input: AddToShoppingListToolInput) => input,
|
||||
});
|
||||
Reference in New Issue
Block a user