import { createFlow, parse, categorize, extract, split, combine, output } from '@docloai/flows';
import { createVLMProvider, createOCRProvider } from '@docloai/providers-llm';
// Create providers
const vlmProvider = createVLMProvider({
provider: 'google',
model: 'google/gemini-flash-2.5',
apiKey: process.env.OPENROUTER_API_KEY!,
via: 'openrouter'
});
const ocrProvider = createOCRProvider({
provider: 'reducto',
apiKey: process.env.REDUCTO_API_KEY!
});
// Define schemas
const invoiceSchema = {
type: 'object',
properties: {
invoiceNumber: { type: 'string' },
date: { type: 'string' },
total: { type: 'number' },
vendor: { type: 'string' },
lineItems: {
type: 'array',
items: {
type: 'object',
properties: {
description: { type: 'string' },
quantity: { type: 'number' },
amount: { type: 'number' }
}
}
}
}
};
// Build the flow
const documentFlow = createFlow({
observability: {
onStepEnd: (ctx) => {
console.log(`${ctx.stepId}: ${ctx.duration}ms, $${ctx.cost?.toFixed(4)}`);
}
},
metadata: { flowName: 'invoice-processor' }
})
.acceptFormats(['application/pdf', 'image/jpeg', 'image/png'])
.step('parse', parse({ provider: ocrProvider }))
.step('extract', extract({
provider: vlmProvider,
schema: invoiceSchema,
consensus: { runs: 3, strategy: 'majority' }
}))
.output({
name: 'invoice',
transform: 'pick',
fields: ['invoiceNumber', 'date', 'total', 'vendor']
})
.build();
// Run the flow
const result = await documentFlow.run({ base64: pdfData });
console.log('Invoice:', result.output);
console.log('Total cost:', result.aggregated.totalCostUSD);