app:
  description: 既存レシピを任意ロットにスケールし、与えられた単価で概算原価を算出するワークフロー
  icon: 🍲
  icon_background: '#FFEAD5'
  mode: workflow
  name: レシピスケール & 原価算出
  use_icon_as_answer_icon: false
kind: app
version: 0.6.0
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      image:
        enabled: false
    opening_statement: ''
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
  graph:
    edges:
    - data:
        sourceType: start
        targetType: parameter-extractor
      id: start-to-extractor1
      source: start
      target: extractor1
    - data:
        sourceType: parameter-extractor
        targetType: code
      id: extractor1-to-code1
      source: extractor1
      target: code1
    - data:
        sourceType: code
        targetType: end
      id: code1-to-end
      source: code1
      target: end
    nodes:
    - data:
        title: 開始
        type: start
        variables:
        - label: query
          max_length: 2048
          options: []
          required: true
          type: paragraph
          variable: query
      height: 90
      id: start
      position:
        x: 80
        y: 282
      type: custom
      width: 244
    - data:
        title: 情報抽出（レシピ・単価）
        type: parameter-extractor
        model:
          provider: openai
          name: gpt-5-mini
          mode: chat
          completion_params:
            temperature: 0.2
        query:
        - start
        - query
        parameters:
        - name: current_batch_size
          type: number
          description: '既存レシピのバッチサイズ（例: 10）'
          required: true
        - name: desired_batch_size
          type: number
          description: 'スケールしたいバッチサイズまたはロット（例: 25）'
          required: true
        - name: ingredients
          type: string
          description: '材料リスト。1行ごとに name|quantity|unit|unit_price の形式で記載してください。単価は1単位あたりの価格を数値で入力。例:
            小麦粉|2.5|kg|120'
          required: true
        reasoning_mode: prompt
        instruction: '入力テキストから次の項目を抽出してください。

          - current_batch_size: 既存レシピのバッチサイズ（数値）

          - desired_batch_size: スケール後のバッチサイズ（数値）

          - ingredients: 各材料を 1行に "name|quantity|unit|unit_price" の形式で出力してください。quantity
          は既存レシピの分量、unit_price はその単位あたりの価格（数値）。複数材料は改行で区切ること。

          出力はパラメータ名ごとに明確に分けて返してください。

          '
        id: extractor1
      height: 180
      id: extractor1
      position:
        x: 380
        y: 282
      type: custom
      width: 244
    - data:
        title: スケール計算と原価算出
        type: code
        code_language: python3
        code: "def _safe_str(v):\n    \"\"\"Convert any value to string safely.\"\"\
          \"\n    if v is None:\n        return \"\"\n    if isinstance(v, list):\n\
          \        return \"\\n\".join(str(i) for i in v)\n    return str(v)\n\ndef\
          \ _safe_list(v):\n    \"\"\"Ensure value is a list.\"\"\"\n    if v is None:\n\
          \        return []\n    if isinstance(v, str):\n        return [v]\n   \
          \ if isinstance(v, list):\n        return v\n    return [v]\n\ndef main(**kwargs)\
          \ -> dict:\n    inputs = kwargs\n    # 入力取得（すべて文字列として来る可能性があるため安全に処理）\n\
          \    current_raw = inputs.get(\"current_batch_size\", \"1\")\n    desired_raw\
          \ = inputs.get(\"desired_batch_size\", \"1\")\n    ingredients_raw = inputs.get(\"\
          ingredients\", \"\")\n    # 安全にキャスト\n    try:\n        current = float(str(current_raw))\n\
          \    except Exception:\n        current = 1.0\n    try:\n        desired\
          \ = float(str(desired_raw))\n    except Exception:\n        desired = current\
          \ if current != 0 else 1.0\n    if current == 0:\n        scale = 1.0\n\
          \    else:\n        scale = desired / current\n    lines = []\n    total_cost\
          \ = 0.0\n    # 期待フォーマット: 1行ごとに name|quantity|unit|unit_price\n    raw_lines\
          \ = [l.strip() for l in str(ingredients_raw).splitlines() if l.strip() !=\
          \ \"\"]\n    if not raw_lines:\n        # もう一つの分離候補としてカンマ区切りも受け付ける\n   \
          \     raw_lines = [p.strip() for p in str(ingredients_raw).split(\",\")\
          \ if p.strip() != \"\"]\n    for ln in raw_lines:\n        # 区切りはパイプ優先、なければカンマまたはスペース\n\
          \        if \"|\" in ln:\n            parts = [p.strip() for p in ln.split(\"\
          |\")]\n        elif \",\" in ln:\n            parts = [p.strip() for p in\
          \ ln.split(\",\")]\n        else:\n            parts = [p.strip() for p\
          \ in ln.split()]\n        # 必要項目が揃っていない場合はスキップせず、可能な限り補完\n        name =\
          \ parts[0] if len(parts) >= 1 else \"unknown\"\n        try:\n         \
          \   qty = float(parts[1]) if len(parts) >= 2 else 0.0\n        except Exception:\n\
          \            qty = 0.0\n        unit = parts[2] if len(parts) >= 3 else\
          \ \"\"\n        try:\n            unit_price = float(parts[3]) if len(parts)\
          \ >= 4 else 0.0\n        except Exception:\n            unit_price = 0.0\n\
          \        scaled_qty = qty * scale\n        cost = scaled_qty * unit_price\n\
          \        total_cost += cost\n        # 表示用に数値を簡潔に整形\n        scaled_qty_s\
          \ = str(round(scaled_qty, 4)).rstrip(\"0\").rstrip(\".\") if isinstance(scaled_qty,\
          \ float) else str(scaled_qty)\n        cost_s = str(round(cost, 2)).rstrip(\"\
          0\").rstrip(\".\") if isinstance(cost, float) else str(cost)\n        line\
          \ = name + \" | \" + scaled_qty_s + \" \" + unit + \" | 単価: \" + str(unit_price)\
          \ + \" | 費用: \" + cost_s\n        lines.append(line)\n    total_cost_s =\
          \ str(round(total_cost, 2))\n    header = \"スケール比: \" + str(round(scale,\
          \ 4)) + \" (既存 \" + str(current) + \" -> 希望 \" + str(desired) + \")\\n\\\
          n\"\n    body = \"\\n\".join(lines) if lines else \"材料情報が見つかりませんでした。入力形式を確認してください。\\\
          n\"\n    footer = \"\\n合計概算原価: \" + total_cost_s\n    output_text = header\
          \ + body + footer\n    return dict(output=output_text)\n"
        variables:
        - value_selector:
          - extractor1
          - current_batch_size
          variable: current_batch_size
        - value_selector:
          - extractor1
          - desired_batch_size
          variable: desired_batch_size
        - value_selector:
          - extractor1
          - ingredients
          variable: ingredients
        outputs:
          output:
            type: string
            children: null
      height: 220
      id: code1
      position:
        x: 680
        y: 282
      type: custom
      width: 244
    - data:
        title: 終了
        type: end
        outputs:
        - value_selector:
          - code1
          - output
          variable: result
      height: 90
      id: end
      position:
        x: 980
        y: 282
      type: custom
      width: 244
  hash: null
