Array[File], file merging issue, anyone expert here?

Hello, I have an Array[File] and a File. How can I add this File into the Array[File]? Iterating would result in two Files, and I can’t merge them back into Array[File].

Because ComfyUI’s workflow only accepts images in the form of Array[File]. I have two image upload nodes, one image is generated by the previous ComfyUI as an Array[File], and the other is a user-uploaded image (File). Both images need to be passed to the next ComfyUI node, but Array[File] and File cannot be combined.

刚好前几天也在捣腾 Array ( 作为 File 类型 现在 dify 的操作还是不太方便)

有两个思路你可以参考一下:

  1. 非常 tricky 的方案,把 Array 和 File 弄到 Code 节点里面,换成 Array<String(URL)> 然后再用一个 Iteration 去 迭代这个 Array<String(URL)>,迭代的内部处理就是用一个 HTTP Node 下载 URL 。这样就把两个合并到一个 Array 里面了 (这个核心使用 HTTP 节点换出 Array 类型的数据)
  2. 开发一个专项的 plugin ,接受参数为 Array 和 File ,然后 插件里面处理合并 yield 输出

看看大家还有什么其他好办法

app:
  description: ''
  icon: 🤖
  icon_background: '#FFEAD5'
  mode: workflow
  name: Merge files
  use_icon_as_answer_icon: false
dependencies: []
kind: app
version: 0.5.0
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      allowed_file_extensions:
      - .JPG
      - .JPEG
      - .PNG
      - .GIF
      - .WEBP
      - .SVG
      allowed_file_types:
      - image
      allowed_file_upload_methods:
      - local_file
      - remote_url
      enabled: false
      fileUploadConfig:
        audio_file_size_limit: 50
        batch_count_limit: 5
        file_size_limit: 15
        image_file_batch_limit: 10
        image_file_size_limit: 10
        single_chunk_attachment_limit: 10
        video_file_size_limit: 100
        workflow_file_upload_limit: 10
      image:
        enabled: false
        number_limits: 3
        transfer_methods:
        - local_file
        - remote_url
      number_limits: 3
    opening_statement: ''
    retriever_resource:
      enabled: true
    sensitive_word_avoidance:
      enabled: false
    speech_to_text:
      enabled: false
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
      language: ''
      voice: ''
  graph:
    edges:
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: start
        targetType: code
      id: 1765898295142-source-1765898342835-target
      source: '1765898295142'
      sourceHandle: source
      target: '1765898342835'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: code
        targetType: iteration
      id: 1765898342835-source-1765898439626-target
      source: '1765898342835'
      sourceHandle: source
      target: '1765898439626'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: true
        isInLoop: false
        iteration_id: '1765898439626'
        sourceType: iteration-start
        targetType: http-request
      id: 1765898439626start-source-1765898478509-target
      source: 1765898439626start
      sourceHandle: source
      target: '1765898478509'
      targetHandle: target
      type: custom
      zIndex: 1002
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: iteration
        targetType: end
      id: 1765898439626-source-1765898503948-target
      source: '1765898439626'
      sourceHandle: source
      target: '1765898503948'
      targetHandle: target
      type: custom
      zIndex: 0
    nodes:
    - data:
        selected: false
        title: User Input
        type: start
        variables:
        - allowed_file_extensions: []
          allowed_file_types:
          - image
          allowed_file_upload_methods:
          - local_file
          - remote_url
          default: ''
          hint: ''
          label: files
          max_length: 5
          options: []
          placeholder: ''
          required: true
          type: file-list
          variable: files
        - allowed_file_extensions: []
          allowed_file_types:
          - image
          allowed_file_upload_methods:
          - local_file
          - remote_url
          default: ''
          hint: ''
          label: file
          max_length: 48
          options: []
          placeholder: ''
          required: true
          type: file
          variable: file
      height: 135
      id: '1765898295142'
      position:
        x: 0
        y: 54
      positionAbsolute:
        x: 0
        y: 54
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    - data:
        code: "\nfunction main({arg1, arg2}) {\n    return {\n        urls: arg1.map(it\
          \ => it.url).concat(arg2)\n    }\n}\n"
        code_language: javascript
        desc: get all file url to an array
        outputs:
          urls:
            children: null
            type: array[string]
        selected: false
        title: To url list
        type: code
        variables:
        - value_selector:
          - '1765898295142'
          - files
          value_type: array[file]
          variable: arg1
        - value_selector:
          - '1765898295142'
          - file
          - url
          value_type: file
          variable: arg2
      height: 80
      id: '1765898342835'
      position:
        x: 342
        y: 96
      positionAbsolute:
        x: 342
        y: 96
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    - data:
        desc: just for getting array<file> type
        error_handle_mode: terminated
        flatten_output: true
        height: 244
        is_parallel: true
        iterator_input_type: array[string]
        iterator_selector:
        - '1765898342835'
        - urls
        output_selector:
        - '1765898478509'
        - files
        output_type: array[file]
        parallel_nums: 10
        selected: false
        start_node_id: 1765898439626start
        title: Iteration
        type: iteration
        width: 486
      height: 244
      id: '1765898439626'
      position:
        x: 684
        y: 0
      positionAbsolute:
        x: 684
        y: 0
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 486
      zIndex: 1
    - data:
        desc: ''
        isInIteration: true
        selected: false
        title: ''
        type: iteration-start
      draggable: false
      height: 48
      id: 1765898439626start
      parentId: '1765898439626'
      position:
        x: 60
        y: 98
      positionAbsolute:
        x: 744
        y: 98
      selectable: false
      sourcePosition: right
      targetPosition: left
      type: custom-iteration-start
      width: 44
      zIndex: 1002
    - data:
        authorization:
          config: null
          type: no-auth
        body:
          data: []
          type: none
        headers: ''
        isInIteration: true
        isInLoop: false
        iteration_id: '1765898439626'
        method: get
        params: ''
        retry_config:
          max_retries: 3
          retry_enabled: true
          retry_interval: 100
        selected: false
        ssl_verify: true
        timeout:
          max_connect_timeout: 0
          max_read_timeout: 0
          max_write_timeout: 0
        title: HTTP Request
        type: http-request
        url: '{{#1765898439626.item#}}'
        variables: []
      height: 124
      id: '1765898478509'
      parentId: '1765898439626'
      position:
        x: 184
        y: 60
      positionAbsolute:
        x: 868
        y: 60
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
      zIndex: 1002
    - data:
        outputs:
        - value_selector:
          - '1765898439626'
          - output
          value_type: array[file]
          variable: output
        selected: false
        title: Output
        type: end
      height: 88
      id: '1765898503948'
      position:
        x: 1441.4285714285716
        y: 86.57142857142856
      positionAbsolute:
        x: 1441.4285714285716
        y: 86.57142857142856
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    - data:
        author: Ezio Lin
        desc: ''
        height: 417
        selected: false
        showAuthor: true
        text: '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"font-size:
          14px;","text":"通过 http 节点 从新使得 URL String 变成 Array<File>","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textStyle":"font-size:
          14px;","textFormat":0},{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"font-size:
          14px;","text":"但是显然,这是个很“费劲” 的方式","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textStyle":"font-size:
          14px;","textFormat":0}],"direction":null,"format":"","indent":0,"type":"root","version":1,"textStyle":"font-size:
          14px;"}}'
        theme: blue
        title: ''
        type: ''
        width: 561
      height: 417
      id: '1765898665315'
      position:
        x: 650
        y: -110.71428571428572
      positionAbsolute:
        x: 650
        y: -110.71428571428572
      selected: true
      sourcePosition: right
      targetPosition: left
      type: custom-note
      width: 561
    viewport:
      x: 120.5
      y: 151.5
      zoom: 0.7
  rag_pipeline_variables: []

这里有个 DSL ,表示我上面说的方案