feat(meal-planner): structured output for add_recipe_to_meal_plan (v0.11.1)

Map verified mpcreateByRecipeId response (a00.r.r dish object) to the
same field layout as get_meal_plan entries. is_from_recipe_box is always
true since this tool only creates recipe-box entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 11:52:16 +02:00
parent e7e242151f
commit d344251796
6 changed files with 48 additions and 9 deletions
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.11.0"
__version__ = "0.11.1"
+26 -2
View File
@@ -2359,8 +2359,32 @@ def add_recipe_to_meal_plan(
except RuntimeError as exc:
return f"Error: {exc}"
# Return raw response until the structure is verified in production.
return json.dumps(data, ensure_ascii=False, indent=2)
try:
dish = data["a00"]["r"]["r"]
if not isinstance(dish, dict) or "metaId" not in dish:
raise TypeError("unexpected shape")
except (KeyError, TypeError):
return json.dumps(
{"warning": "Unexpected mpcreateByRecipeId response structure", "raw": data},
ensure_ascii=False,
indent=2,
)
rights = dish.get("rights") or {}
result: dict[str, Any] = {
"id": dish.get("metaId"),
"date": dish.get("date"),
"type": dish.get("type"),
"name": dish.get("name"),
"recipe_id": dish.get("recipeId") or None,
# mpcreateByRecipeId always creates entries from the recipe box.
"is_from_recipe_box": True,
"note": None,
"serves": None,
"can_update": rights.get("canUpdate") == "true",
"can_delete": rights.get("canDelete") == "true",
}
return json.dumps(result, ensure_ascii=False, indent=2)
# ---------------------------------------------------------------------------