Skip to main content

Overview

Internal finance operations assistant using Plaid API for banking and account management. What it does:
  • Check account balances
  • View recent transactions
  • Transfer funds between accounts
  • Generate financial reports
  • Verify payments
APIs used: Plaid API (external banking)

Complete Implementation

src/index.ts

import { LuaAgent, LuaSkill, LuaJob } from "lua-cli";
import {
  GetBalanceTool,
  GetTransactionsTool,
  TransferFundsTool
} from "./tools/FinanceTools";

// Finance operations skill
const financeSkill = new LuaSkill({
  name: "finance-operations",
  description: "Internal finance and banking operations",
  context: `
    This skill provides finance team with banking operations.
    
    - get_balance: Check account balances
    - get_transactions: View transaction history
    - transfer_funds: Move money between accounts
    
    Always verify amounts and account numbers.
    Follow approval workflows for large transfers.
  `,
  tools: [
    new GetBalanceTool(),
    new GetTransactionsTool(),
    new TransferFundsTool()
  ]
});

// Weekly reconciliation job
const weeklyReconciliationJob = new LuaJob({
  name: 'weekly-reconciliation',
  description: 'Send weekly account reconciliation summary',
  schedule: {
    type: 'cron',
    pattern: '0 9 * * 1'  // Every Monday at 9 AM
  },
  execute: async (job) => {
    const user = await job.user();
    await user.send([{
      type: 'text',
      text: '📊 Weekly reconciliation report is ready for review.'
    }]);
  }
});

// Configure agent (v3.0.0)
export const agent = new LuaAgent({
  name: "finance-operations-assistant",
  
  persona: `You are a finance operations specialist assistant.
  
Your role:
- Help finance team check account balances
- Provide transaction histories
- Process fund transfers
- Generate financial reports
- Monitor account activities

Communication style:
- Professional and precise
- Detail-oriented
- Security-conscious
- Clear with numbers
- Compliant with regulations

Best practices:
- Always verify account numbers before transfers
- Double-check transfer amounts
- Provide clear transaction summaries
- Flag unusual activity
- Follow approval workflows for large amounts

Security requirements:
- Verify user authorization
- Log all transfer requests
- Require approval for transfers >$10,000
- Maintain audit trail
- Follow SOX compliance

When to escalate:
- Transfers over $10,000
- Suspicious transactions
- Account discrepancies
- External audit requests`,

  
  skills: [financeSkill],
  jobs: [weeklyReconciliationJob]
});
v3.0.0 Features: This demo uses LuaAgent with scheduled jobs for weekly reconciliation reports.

src/tools/FinanceTools.ts

import { LuaTool, env } from "lua-cli";
import { z } from "zod";

// 1. Get Account Balance
export class GetBalanceTool implements LuaTool {
  name = "get_balance";
  description = "Check account balance";
  
  inputSchema = z.object({
    accountId: z.string().describe("Account ID")
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const plaidKey = env('PLAID_CLIENT_ID');
    const plaidSecret = env('PLAID_SECRET');
    
    const response = await fetch('https://production.plaid.com/accounts/balance/get', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        client_id: plaidKey,
        secret: plaidSecret,
        access_token: env('PLAID_ACCESS_TOKEN'),
        options: {
          account_ids: [input.accountId]
        }
      })
    });
    
    const data = await response.json();
    const account = data.accounts[0];
    
    return {
      accountId: account.account_id,
      accountName: account.name,
      currentBalance: `$${account.balances.current.toLocaleString()}`,
      availableBalance: `$${account.balances.available.toLocaleString()}`,
      currency: account.balances.iso_currency_code,
      lastUpdated: new Date().toISOString()
    };
  }
}

// 2. Get Transactions
export class GetTransactionsTool implements LuaTool {
  name = "get_transactions";
  description = "View recent transactions";
  
  inputSchema = z.object({
    accountId: z.string(),
    days: z.number().min(1).max(90).default(30)
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const plaidKey = env('PLAID_CLIENT_ID');
    const plaidSecret = env('PLAID_SECRET');
    
    const endDate = new Date();
    const startDate = new Date();
    startDate.setDate(startDate.getDate() - input.days);
    
    const response = await fetch('https://production.plaid.com/transactions/get', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        client_id: plaidKey,
        secret: plaidSecret,
        access_token: env('PLAID_ACCESS_TOKEN'),
        start_date: startDate.toISOString().split('T')[0],
        end_date: endDate.toISOString().split('T')[0],
        options: {
          account_ids: [input.accountId]
        }
      })
    });
    
    const data = await response.json();
    
    return {
      transactions: data.transactions.map(t => ({
        date: t.date,
        name: t.name,
        amount: `$${Math.abs(t.amount).toFixed(2)}`,
        type: t.amount < 0 ? 'debit' : 'credit',
        category: t.category[0],
        pending: t.pending
      })),
      total: data.transactions.length
    };
  }
}

// 3. Transfer Funds
export class TransferFundsTool implements LuaTool {
  name = "transfer_funds";
  description = "Transfer money between accounts";
  
  inputSchema = z.object({
    fromAccountId: z.string(),
    toAccountId: z.string(),
    amount: z.number().positive(),
    description: z.string().optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    // Validate amount
    if (input.amount > 10000) {
      throw new Error('Transfers over $10,000 require additional approval');
    }
    
    const plaidKey = env('PLAID_CLIENT_ID');
    const plaidSecret = env('PLAID_SECRET');
    
    const response = await fetch('https://production.plaid.com/transfer/create', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        client_id: plaidKey,
        secret: plaidSecret,
        access_token: env('PLAID_ACCESS_TOKEN'),
        account_id: input.fromAccountId,
        type: 'debit',
        network: 'ach',
        amount: input.amount.toString(),
        description: input.description || 'Transfer',
        user: {
          legal_name: 'Company Name'
        }
      })
    });
    
    const data = await response.json();
    
    return {
      success: true,
      transferId: data.transfer.id,
      amount: `$${input.amount.toFixed(2)}`,
      status: data.transfer.status,
      message: `Transfer of $${input.amount.toFixed(2)} initiated successfully`
    };
  }
}

Environment Setup

# .env
PLAID_CLIENT_ID=your_plaid_client_id
PLAID_SECRET=your_plaid_secret
PLAID_ACCESS_TOKEN=your_access_token
PLAID_ENV=production

Key Features

External Banking

Plaid API integration

Secure

Bank-grade security

Real-Time

Live account data

Compliance

Financial regulations