{
  "schema_version": "1.0",
  "nodes": [
    {
      "id": "terrace_photo",
      "type": "input/image",
      "label": "Photo of the terrace (from the customer)",
      "parameters": {
        "image": "__TERRACE_PHOTO_ASSET_PATH__",
        "required": true
      }
    },
    {
      "id": "notes",
      "type": "input/text",
      "label": "Customer notes",
      "parameters": {
        "text": "Terrazzo di circa 12 m² al quinto piano, esposto a sud-ovest: sole pieno dal primo pomeriggio fino a sera, d'estate fa molto caldo.\nVorrei un angolo verde dove leggere e cenare, un po' di privacy dal palazzo di fronte sul lato destro, e profumo la sera.\nNon ho molto tempo: piante che non muoiano se salto qualche annaffiatura. Niente piante spinose, ho un gatto.",
        "multiline": true,
        "required": true
      }
    },
    {
      "id": "proposal",
      "type": "input/json_value",
      "label": "Selected plants and prices (from the nursery)",
      "parameters": {
        "required": true
      }
    },
    {
      "id": "plants",
      "type": "utility/extract",
      "label": "Selected plants",
      "parameters": {
        "path": "plants",
        "expected_type": "json",
        "on_missing": "fail"
      }
    },
    {
      "id": "brief",
      "type": "text/template",
      "label": "Compose the brief",
      "parameters": {
        "template": "NOTE DEL CLIENTE\n[notes]\n\nPIANTE SCELTE DAL VIVAIO (JSON)\n[plants]",
        "placeholders": [
          {
            "name": "notes",
            "inputPort": "notes"
          },
          {
            "name": "plants",
            "inputPort": "plants"
          }
        ]
      }
    },
    {
      "id": "writer",
      "type": "ai/text_generation",
      "label": "Write the proposal and the staging",
      "parameters": {
        "system_prompt": "You write the green proposals of a plant nursery for its private customers.\nYou receive the customer's notes about their terrace and the plants the nursery selected, with their facts.\nWrite in Italian, warm and concrete, addressing the customer with \"tu\"; no superlatives, no exclamation marks.\n\nReturn one JSON object and nothing else:\n{\n  \"headline\": \"the promise of the proposal in one line, at most 60 characters\",\n  \"intro\": \"2–3 sentences, at most 300 characters: how the selection answers what the customer asked (shade, privacy, scent, little care), naming at most three plants\",\n  \"care_tips\": [ { \"title\": \"at most 26 characters\", \"text\": \"at most 150 characters\" } ]  — exactly 3 tips,\n  \"staging_prompt\": \"an instruction in English for an image editing model (see below)\"\n}\n\nRules for the words:\n- Use only the facts given (names, exposure, water, height, quantities). Never invent prices, discounts, guarantees, deliveries or plants.\n- Never write prices, totals, codes or dates: the proposal prints them.\n- Never claim that a plant is safe (or unsafe) for pets, children or allergies: the nursery gives that advice in person.\n- The intro talks to the customer about what they asked (reading and dining, privacy, scent, little time), not about \"the selection\".\n- The care tips are practical and follow from the exposure and the water of the selected plants and from the notes.\n  They cover three different subjects (for example watering, the summer heat of the terrace, training the climbers on the trellis): never two tips about watering.\n\nRules for staging_prompt (the model receives the customer's photo of the empty terrace):\n- Start with \"Edit this photo of a terrace:\" and keep everything that is there exactly as it is: floor, railing, walls, building opposite, sky, light, perspective, framing, camera quality.\n- Add only the selected plants in their pots, with their quantities, placed where the notes ask (for example the climbers on a trellis against the side facing the building opposite, for privacy), plus at most a small table with two chairs if the notes mention eating or reading.\n- Photorealistic, same time of day; no people, no text, no watermark, full bleed, no border.\n- At most 700 characters.",
        "response_format": "json_object",
        "temperature": 0.5,
        "max_tokens": 4000
      }
    },
    {
      "id": "copy_contract",
      "type": "utility/json_schema_validate",
      "label": "Copy fits the proposal",
      "parameters": {
        "schema_source": "inline",
        "schema_definition": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "headline",
            "intro",
            "care_tips",
            "staging_prompt"
          ],
          "properties": {
            "headline": {
              "type": "string",
              "minLength": 10,
              "maxLength": 66
            },
            "intro": {
              "type": "string",
              "minLength": 80,
              "maxLength": 330
            },
            "care_tips": {
              "type": "array",
              "minItems": 3,
              "maxItems": 3,
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "title",
                  "text"
                ],
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 29
                  },
                  "text": {
                    "type": "string",
                    "minLength": 30,
                    "maxLength": 165
                  }
                }
              }
            },
            "staging_prompt": {
              "type": "string",
              "minLength": 80,
              "maxLength": 900
            }
          }
        },
        "mode": "fail"
      }
    },
    {
      "id": "staging_prompt",
      "type": "utility/extract",
      "label": "Staging instruction",
      "parameters": {
        "path": "staging_prompt",
        "expected_type": "text",
        "on_missing": "fail"
      }
    },
    {
      "id": "staging",
      "type": "ai/image_transform",
      "label": "Stage the plants on the terrace",
      "parameters": {
        "aspect_ratio": "match_input"
      }
    },
    {
      "id": "render",
      "type": "design/template_render",
      "label": "Compose the proposal",
      "parameters": {
        "template_id": "__TEMPLATE_ID__",
        "template_revision": "__TEMPLATE_REVISION__",
        "output": "both",
        "page_selection": "all",
        "missing_policy": "fail_required",
        "overflow_policy": "template",
        "max_repeat": 8
      }
    },
    {
      "id": "proposal_pdf",
      "type": "output/pdf",
      "label": "Proposal — PDF",
      "parameters": {
        "output_name": "proposal_pdf"
      }
    },
    {
      "id": "proposal_pages",
      "type": "output/json",
      "label": "Proposal — page images",
      "parameters": {
        "output_name": "proposal_pages"
      }
    },
    {
      "id": "staging_output",
      "type": "output/image",
      "label": "Staged terrace (AI simulation)",
      "parameters": {
        "output_name": "staged_terrace"
      }
    },
    {
      "id": "copy_output",
      "type": "output/json",
      "label": "Approved copy",
      "parameters": {
        "output_name": "proposal_copy"
      }
    },
    {
      "id": "layout_report",
      "type": "output/json",
      "label": "Layout report",
      "parameters": {
        "output_name": "layout_report"
      }
    }
  ],
  "connections": [
    {
      "from_node": "proposal",
      "from_output": "json",
      "to_node": "plants",
      "to_input": "json"
    },
    {
      "from_node": "notes",
      "from_output": "text",
      "to_node": "brief",
      "to_input": "notes"
    },
    {
      "from_node": "plants",
      "from_output": "value",
      "to_node": "brief",
      "to_input": "plants"
    },
    {
      "from_node": "brief",
      "from_output": "result",
      "to_node": "writer",
      "to_input": "prompt"
    },
    {
      "from_node": "writer",
      "from_output": "json",
      "to_node": "copy_contract",
      "to_input": "document"
    },
    {
      "from_node": "copy_contract",
      "from_output": "normalized_json",
      "to_node": "staging_prompt",
      "to_input": "json"
    },
    {
      "from_node": "terrace_photo",
      "from_output": "image",
      "to_node": "staging",
      "to_input": "images_0"
    },
    {
      "from_node": "staging_prompt",
      "from_output": "value",
      "to_node": "staging",
      "to_input": "prompt"
    },
    {
      "from_node": "copy_contract",
      "from_output": "normalized_json",
      "to_node": "render",
      "to_input": "data_0"
    },
    {
      "from_node": "proposal",
      "from_output": "json",
      "to_node": "render",
      "to_input": "data_1"
    },
    {
      "from_node": "terrace_photo",
      "from_output": "image",
      "to_node": "render",
      "to_input": "terrace_photo"
    },
    {
      "from_node": "staging",
      "from_output": "result",
      "to_node": "render",
      "to_input": "staging_image"
    },
    {
      "from_node": "render",
      "from_output": "pdf",
      "to_node": "proposal_pdf",
      "to_input": "pdf"
    },
    {
      "from_node": "render",
      "from_output": "pages_manifest",
      "to_node": "proposal_pages",
      "to_input": "json"
    },
    {
      "from_node": "staging",
      "from_output": "result",
      "to_node": "staging_output",
      "to_input": "image"
    },
    {
      "from_node": "copy_contract",
      "from_output": "normalized_json",
      "to_node": "copy_output",
      "to_input": "json"
    },
    {
      "from_node": "render",
      "from_output": "layout_report",
      "to_node": "layout_report",
      "to_input": "json"
    }
  ],
  "layout": {
    "nodes": {
      "terrace_photo": {
        "x": 0,
        "y": 520
      },
      "notes": {
        "x": 0,
        "y": 0
      },
      "proposal": {
        "x": 0,
        "y": 260
      },
      "plants": {
        "x": 420,
        "y": 260
      },
      "brief": {
        "x": 840,
        "y": 60
      },
      "writer": {
        "x": 1260,
        "y": 60
      },
      "copy_contract": {
        "x": 1680,
        "y": 60
      },
      "staging_prompt": {
        "x": 2100,
        "y": 300
      },
      "staging": {
        "x": 2520,
        "y": 480
      },
      "render": {
        "x": 2940,
        "y": 240
      },
      "proposal_pdf": {
        "x": 3380,
        "y": 120
      },
      "proposal_pages": {
        "x": 3380,
        "y": 280
      },
      "staging_output": {
        "x": 2940,
        "y": 640
      },
      "copy_output": {
        "x": 2100,
        "y": -160
      },
      "layout_report": {
        "x": 3380,
        "y": 440
      }
    }
  }
}
