Skip to main content
The combine node merges outputs from forEach operations or parallel processing branches into a single result.

Basic Usage

import { createFlow, split, extract, combine } from '@docloai/flows';

const flow = createFlow()
  .step('split', split({
    provider: vlmProvider,
    schemas: { invoice: invoiceSchema, receipt: receiptSchema }
  }))
  .forEach('extract', (doc) =>
    createFlow()
      .step('extract', extract({
        provider: vlmProvider,
        schema: doc.schema
      }))
  )
  .step('combine', combine())  // Merge all extraction results
  .build();

Configuration Options

combine({
  strategy: 'merge'  // 'merge' | 'concatenate' | 'first' | 'last'
})

Options Reference

OptionTypeDefaultDescription
strategystring'merge'How to combine results

Strategies

Merge (Default)

Intelligently merges results based on type:
combine({ strategy: 'merge' })
  • Arrays: Flattens into single array
  • Objects: Merges properties (later values override)
  • Mixed: Returns as array
// Arrays
[['a', 'b'], ['c', 'd']] → ['a', 'b', 'c', 'd']

// Objects
[{a: 1}, {b: 2}] → {a: 1, b: 2}

// Mixed
['string', {a: 1}] → ['string', {a: 1}]

Concatenate

Always returns array of all inputs:
combine({ strategy: 'concatenate' })
// All inputs preserved as array
[{a: 1}, {b: 2}] → [{a: 1}, {b: 2}]

First

Returns first non-null result:
combine({ strategy: 'first' })
[null, {a: 1}, {b: 2}] → {a: 1}

Last

Returns last non-null result:
combine({ strategy: 'last' })
[{a: 1}, {b: 2}, null] → {b: 2}

Use Cases

Multi-Document Extraction

Combine extracted data from split documents:
const flow = createFlow()
  .step('split', split({
    provider: vlmProvider,
    schemas: { invoice: invoiceSchema }
  }))
  .forEach('extract', (doc) =>
    createFlow()
      .step('extract', extract({
        provider: vlmProvider,
        schema: doc.schema
      }))
  )
  .step('combine', combine({ strategy: 'concatenate' }))
  .build();

// Result: array of extracted invoices
// [{ invoiceNumber: 'INV-001', ... }, { invoiceNumber: 'INV-002', ... }]

Parallel Provider Extraction

Combine results from multiple providers:
const flow = createFlow()
  .parallel('extract', [
    extract({ provider: provider1, schema: schema }),
    extract({ provider: provider2, schema: schema }),
    extract({ provider: provider3, schema: schema })
  ])
  .step('combine', combine({ strategy: 'first' }))
  .build();

// Returns first successful extraction

Chunked Processing

Combine results from processing chunks:
const flow = createFlow()
  .step('parse', parse({ provider: ocrProvider }))
  .step('chunk', chunk({ strategy: 'page', pagesPerChunk: 5 }))
  .forEach('extract', (chunks) =>
    createFlow()
      .step('extract', extract({
        provider: llmProvider,
        schema: {
          type: 'object',
          properties: {
            items: { type: 'array', items: itemSchema }
          }
        }
      }))
  )
  .step('combine', combine({ strategy: 'merge' }))
  .build();

// Merges items from all chunks into single object

Object Merging

Combine partial extractions:
const flow = createFlow()
  .parallel('extract', [
    extract({
      provider: vlmProvider,
      schema: headerSchema  // Extracts header info
    }),
    extract({
      provider: vlmProvider,
      schema: lineItemsSchema  // Extracts line items
    }),
    extract({
      provider: vlmProvider,
      schema: totalsSchema  // Extracts totals
    })
  ])
  .step('combine', combine({ strategy: 'merge' }))
  .build();

// Result: single object with all fields merged
// { header: {...}, lineItems: [...], totals: {...} }

Without Provider

The combine node doesn’t require an AI provider—it performs local data transformation:
combine()  // No provider needed

Next Steps