Some checks failed
CI / build-and-test (push) Failing after -31m24s
* Implement ContentEditorField for inline editing of content * Create ContentEditorModal for editing content in a modal * Introduce FormerShell for managing forms related to skills and thoughts * Enhance SkillsPage and ThoughtsPage with new components for better content management
211 lines
7.3 KiB
Go
211 lines
7.3 KiB
Go
package tools
|
|
|
|
// import (
|
|
// "context"
|
|
// "strings"
|
|
// "time"
|
|
|
|
// "github.com/google/uuid"
|
|
// "github.com/modelcontextprotocol/go-sdk/mcp"
|
|
|
|
// "git.warky.dev/wdevs/amcs/internal/store"
|
|
// ext "git.warky.dev/wdevs/amcs/internal/types"
|
|
// )
|
|
|
|
// type MealsTool struct {
|
|
// store *store.DB
|
|
// }
|
|
|
|
// func NewMealsTool(db *store.DB) *MealsTool {
|
|
// return &MealsTool{store: db}
|
|
// }
|
|
|
|
// // add_recipe
|
|
|
|
// type AddRecipeInput struct {
|
|
// Name string `json:"name" jsonschema:"recipe name"`
|
|
// Cuisine string `json:"cuisine,omitempty"`
|
|
// PrepTimeMinutes *int `json:"prep_time_minutes,omitempty"`
|
|
// CookTimeMinutes *int `json:"cook_time_minutes,omitempty"`
|
|
// Servings *int `json:"servings,omitempty"`
|
|
// Ingredients []ext.Ingredient `json:"ingredients,omitempty" jsonschema:"list of ingredients with name, quantity, unit"`
|
|
// Instructions []string `json:"instructions,omitempty" jsonschema:"ordered list of steps"`
|
|
// Tags []string `json:"tags,omitempty"`
|
|
// Rating *int `json:"rating,omitempty" jsonschema:"1-5 rating"`
|
|
// Notes string `json:"notes,omitempty"`
|
|
// }
|
|
|
|
// type AddRecipeOutput struct {
|
|
// Recipe ext.Recipe `json:"recipe"`
|
|
// }
|
|
|
|
// func (t *MealsTool) AddRecipe(ctx context.Context, _ *mcp.CallToolRequest, in AddRecipeInput) (*mcp.CallToolResult, AddRecipeOutput, error) {
|
|
// if strings.TrimSpace(in.Name) == "" {
|
|
// return nil, AddRecipeOutput{}, errRequiredField("name")
|
|
// }
|
|
// if in.Ingredients == nil {
|
|
// in.Ingredients = []ext.Ingredient{}
|
|
// }
|
|
// if in.Instructions == nil {
|
|
// in.Instructions = []string{}
|
|
// }
|
|
// if in.Tags == nil {
|
|
// in.Tags = []string{}
|
|
// }
|
|
// recipe, err := t.store.AddRecipe(ctx, ext.Recipe{
|
|
// Name: strings.TrimSpace(in.Name),
|
|
// Cuisine: strings.TrimSpace(in.Cuisine),
|
|
// PrepTimeMinutes: in.PrepTimeMinutes,
|
|
// CookTimeMinutes: in.CookTimeMinutes,
|
|
// Servings: in.Servings,
|
|
// Ingredients: in.Ingredients,
|
|
// Instructions: in.Instructions,
|
|
// Tags: in.Tags,
|
|
// Rating: in.Rating,
|
|
// Notes: strings.TrimSpace(in.Notes),
|
|
// })
|
|
// if err != nil {
|
|
// return nil, AddRecipeOutput{}, err
|
|
// }
|
|
// return nil, AddRecipeOutput{Recipe: recipe}, nil
|
|
// }
|
|
|
|
// // search_recipes
|
|
|
|
// type SearchRecipesInput struct {
|
|
// Query string `json:"query,omitempty" jsonschema:"search by recipe name"`
|
|
// Cuisine string `json:"cuisine,omitempty"`
|
|
// Tags []string `json:"tags,omitempty" jsonschema:"filter by tags (all must match)"`
|
|
// Ingredient string `json:"ingredient,omitempty" jsonschema:"filter by ingredient name"`
|
|
// }
|
|
|
|
// type SearchRecipesOutput struct {
|
|
// Recipes []ext.Recipe `json:"recipes"`
|
|
// }
|
|
|
|
// func (t *MealsTool) SearchRecipes(ctx context.Context, _ *mcp.CallToolRequest, in SearchRecipesInput) (*mcp.CallToolResult, SearchRecipesOutput, error) {
|
|
// recipes, err := t.store.SearchRecipes(ctx, in.Query, in.Cuisine, in.Tags, in.Ingredient)
|
|
// if err != nil {
|
|
// return nil, SearchRecipesOutput{}, err
|
|
// }
|
|
// if recipes == nil {
|
|
// recipes = []ext.Recipe{}
|
|
// }
|
|
// return nil, SearchRecipesOutput{Recipes: recipes}, nil
|
|
// }
|
|
|
|
// // update_recipe
|
|
|
|
// type UpdateRecipeInput struct {
|
|
// ID uuid.UUID `json:"id" jsonschema:"recipe id to update"`
|
|
// Name string `json:"name" jsonschema:"recipe name"`
|
|
// Cuisine string `json:"cuisine,omitempty"`
|
|
// PrepTimeMinutes *int `json:"prep_time_minutes,omitempty"`
|
|
// CookTimeMinutes *int `json:"cook_time_minutes,omitempty"`
|
|
// Servings *int `json:"servings,omitempty"`
|
|
// Ingredients []ext.Ingredient `json:"ingredients,omitempty"`
|
|
// Instructions []string `json:"instructions,omitempty"`
|
|
// Tags []string `json:"tags,omitempty"`
|
|
// Rating *int `json:"rating,omitempty"`
|
|
// Notes string `json:"notes,omitempty"`
|
|
// }
|
|
|
|
// type UpdateRecipeOutput struct {
|
|
// Recipe ext.Recipe `json:"recipe"`
|
|
// }
|
|
|
|
// func (t *MealsTool) UpdateRecipe(ctx context.Context, _ *mcp.CallToolRequest, in UpdateRecipeInput) (*mcp.CallToolResult, UpdateRecipeOutput, error) {
|
|
// if strings.TrimSpace(in.Name) == "" {
|
|
// return nil, UpdateRecipeOutput{}, errRequiredField("name")
|
|
// }
|
|
// if in.Ingredients == nil {
|
|
// in.Ingredients = []ext.Ingredient{}
|
|
// }
|
|
// if in.Instructions == nil {
|
|
// in.Instructions = []string{}
|
|
// }
|
|
// if in.Tags == nil {
|
|
// in.Tags = []string{}
|
|
// }
|
|
// recipe, err := t.store.UpdateRecipe(ctx, in.ID, ext.Recipe{
|
|
// Name: strings.TrimSpace(in.Name),
|
|
// Cuisine: strings.TrimSpace(in.Cuisine),
|
|
// PrepTimeMinutes: in.PrepTimeMinutes,
|
|
// CookTimeMinutes: in.CookTimeMinutes,
|
|
// Servings: in.Servings,
|
|
// Ingredients: in.Ingredients,
|
|
// Instructions: in.Instructions,
|
|
// Tags: in.Tags,
|
|
// Rating: in.Rating,
|
|
// Notes: strings.TrimSpace(in.Notes),
|
|
// })
|
|
// if err != nil {
|
|
// return nil, UpdateRecipeOutput{}, err
|
|
// }
|
|
// return nil, UpdateRecipeOutput{Recipe: recipe}, nil
|
|
// }
|
|
|
|
// // create_meal_plan
|
|
|
|
// type CreateMealPlanInput struct {
|
|
// WeekStart time.Time `json:"week_start" jsonschema:"Monday of the week to plan"`
|
|
// Meals []ext.MealPlanInput `json:"meals" jsonschema:"list of meal entries for the week"`
|
|
// }
|
|
|
|
// type CreateMealPlanOutput struct {
|
|
// Entries []ext.MealPlanEntry `json:"entries"`
|
|
// }
|
|
|
|
// func (t *MealsTool) CreateMealPlan(ctx context.Context, _ *mcp.CallToolRequest, in CreateMealPlanInput) (*mcp.CallToolResult, CreateMealPlanOutput, error) {
|
|
// if len(in.Meals) == 0 {
|
|
// return nil, CreateMealPlanOutput{}, errInvalidInput("meals are required")
|
|
// }
|
|
// entries, err := t.store.CreateMealPlan(ctx, in.WeekStart, in.Meals)
|
|
// if err != nil {
|
|
// return nil, CreateMealPlanOutput{}, err
|
|
// }
|
|
// if entries == nil {
|
|
// entries = []ext.MealPlanEntry{}
|
|
// }
|
|
// return nil, CreateMealPlanOutput{Entries: entries}, nil
|
|
// }
|
|
|
|
// // get_meal_plan
|
|
|
|
// type GetMealPlanInput struct {
|
|
// WeekStart time.Time `json:"week_start" jsonschema:"Monday of the week to retrieve"`
|
|
// }
|
|
|
|
// type GetMealPlanOutput struct {
|
|
// Entries []ext.MealPlanEntry `json:"entries"`
|
|
// }
|
|
|
|
// func (t *MealsTool) GetMealPlan(ctx context.Context, _ *mcp.CallToolRequest, in GetMealPlanInput) (*mcp.CallToolResult, GetMealPlanOutput, error) {
|
|
// entries, err := t.store.GetMealPlan(ctx, in.WeekStart)
|
|
// if err != nil {
|
|
// return nil, GetMealPlanOutput{}, err
|
|
// }
|
|
// if entries == nil {
|
|
// entries = []ext.MealPlanEntry{}
|
|
// }
|
|
// return nil, GetMealPlanOutput{Entries: entries}, nil
|
|
// }
|
|
|
|
// // generate_shopping_list
|
|
|
|
// type GenerateShoppingListInput struct {
|
|
// WeekStart time.Time `json:"week_start" jsonschema:"Monday of the week to generate shopping list for"`
|
|
// }
|
|
|
|
// type GenerateShoppingListOutput struct {
|
|
// ShoppingList ext.ShoppingList `json:"shopping_list"`
|
|
// }
|
|
|
|
// func (t *MealsTool) GenerateShoppingList(ctx context.Context, _ *mcp.CallToolRequest, in GenerateShoppingListInput) (*mcp.CallToolResult, GenerateShoppingListOutput, error) {
|
|
// list, err := t.store.GenerateShoppingList(ctx, in.WeekStart)
|
|
// if err != nil {
|
|
// return nil, GenerateShoppingListOutput{}, err
|
|
// }
|
|
// return nil, GenerateShoppingListOutput{ShoppingList: list}, nil
|
|
// }
|