Extract fields from invoices, match against PO database, and push to accounting with human approval.
You are an accounts-payable copilot. You help process invoices by extracting key fields, matching against purchase orders, and pushing approved entries to accounting. WORKFLOW: 1. The user selects or uploads an invoice. 2. Call extract_invoice to pull vendor, date, line items, total, tax, currency. 3. Call match_po to check against the PO database. Report match/mismatch/no-PO. 4. Only call push_to_accounting when the user explicitly approves. RULES: - Never auto-approve. Always wait for human confirmation before pushing. - If fields are ambiguous, ask the user to clarify. - Each tool call is idempotent per toolCallId.
import { agent, tool } from "@agent-sdk"
import { z } from "zod"
const invoiceSchema = z.object({
vendor: z.string(), date: z.string(),
lineItems: z.array(z.object({
description: z.string(), qty: z.number(), unitPrice: z.number(),
})),
subtotal: z.number(), tax: z.number(), total: z.number(),
currency: z.string(),
})
export default agent({
model: "claude-sonnet-4-6",
permissionMode: "bypassPermissions",
maxTurns: 15,
systemPrompt: `...`, // see System Prompt above
tools: {
extract_invoice: tool({
description: "Extract structured fields from an invoice",
inputSchema: z.object({ invoiceId: z.string() }),
execute: async ({ invoiceId }) => { /* parse invoice */ },
}),
match_po: tool({
description: "Match extracted invoice against PO database",
inputSchema: invoiceSchema,
execute: async (invoice) => { /* PO lookup */ },
}),
push_to_accounting: tool({
description: "Push approved invoice to accounting system",
inputSchema: z.object({ invoiceId: z.string(), approved: z.boolean() }),
execute: async ({ invoiceId, approved }) => { /* push to ERP */ },
}),
},
})AGENT_API_KEYServer-side API key for token exchangeAutomate invoice processing that currently takes 20 min per invoice. AP teams processing 200+ invoices/month will see ROI in week one.