686 lines
22 KiB
QBasic
686 lines
22 KiB
QBasic
|
|
' General Bots Conversational Banking
|
||
|
|
' Enterprise-grade banking through natural conversation
|
||
|
|
' Uses TOOLS (not SUBs) and HEAR AS validation
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' CONFIGURATION
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
SET CONTEXT "You are a professional banking assistant for General Bank.
|
||
|
|
Help customers with accounts, transfers, payments, cards, loans, and investments.
|
||
|
|
Always verify identity before sensitive operations. Be helpful and secure.
|
||
|
|
Use the available tools to perform banking operations.
|
||
|
|
Never ask for full card numbers or passwords in chat."
|
||
|
|
|
||
|
|
USE KB "banking-faq"
|
||
|
|
|
||
|
|
' Add specialized bots for complex operations
|
||
|
|
ADD BOT "fraud-detector" WITH TRIGGER "suspicious, fraud, unauthorized, stolen, hack"
|
||
|
|
ADD BOT "investment-advisor" WITH TRIGGER "invest, stocks, funds, portfolio, returns, CDB, LCI"
|
||
|
|
ADD BOT "loan-specialist" WITH TRIGGER "loan, financing, credit, mortgage, empréstimo"
|
||
|
|
ADD BOT "card-services" WITH TRIGGER "card, limit, block, virtual card, cartão"
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' BANKING TOOLS - Dynamic tools added to conversation
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' Account Tools
|
||
|
|
USE TOOL "check_balance"
|
||
|
|
USE TOOL "get_statement"
|
||
|
|
USE TOOL "get_transactions"
|
||
|
|
|
||
|
|
' Transfer Tools
|
||
|
|
USE TOOL "pix_transfer"
|
||
|
|
USE TOOL "ted_transfer"
|
||
|
|
USE TOOL "schedule_transfer"
|
||
|
|
|
||
|
|
' Payment Tools
|
||
|
|
USE TOOL "pay_boleto"
|
||
|
|
USE TOOL "pay_utility"
|
||
|
|
USE TOOL "list_scheduled_payments"
|
||
|
|
|
||
|
|
' Card Tools
|
||
|
|
USE TOOL "list_cards"
|
||
|
|
USE TOOL "block_card"
|
||
|
|
USE TOOL "unblock_card"
|
||
|
|
USE TOOL "create_virtual_card"
|
||
|
|
USE TOOL "request_limit_increase"
|
||
|
|
|
||
|
|
' Loan Tools
|
||
|
|
USE TOOL "simulate_loan"
|
||
|
|
USE TOOL "apply_loan"
|
||
|
|
USE TOOL "list_loans"
|
||
|
|
|
||
|
|
' Investment Tools
|
||
|
|
USE TOOL "get_portfolio"
|
||
|
|
USE TOOL "list_investments"
|
||
|
|
USE TOOL "buy_investment"
|
||
|
|
USE TOOL "redeem_investment"
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' AUTHENTICATION FLOW
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
authenticated = GET user_authenticated
|
||
|
|
|
||
|
|
IF NOT authenticated THEN
|
||
|
|
TALK "Welcome to General Bank! 🏦"
|
||
|
|
TALK "For your security, I need to verify your identity."
|
||
|
|
TALK ""
|
||
|
|
TALK "Please enter your CPF:"
|
||
|
|
|
||
|
|
HEAR cpf AS CPF
|
||
|
|
|
||
|
|
' Look up customer
|
||
|
|
customer = FIND "customers.csv" WHERE cpf = cpf
|
||
|
|
|
||
|
|
IF LEN(customer) = 0 THEN
|
||
|
|
TALK "I couldn't find an account with this CPF."
|
||
|
|
TALK "Please check the number or visit a branch to open an account."
|
||
|
|
ELSE
|
||
|
|
' Send verification code
|
||
|
|
phone_masked = MID(FIRST(customer).phone, 1, 4) + "****" + RIGHT(FIRST(customer).phone, 2)
|
||
|
|
TALK "I'll send a verification code to your phone ending in " + phone_masked
|
||
|
|
|
||
|
|
' Generate and store code
|
||
|
|
code = STR(INT(RND() * 900000) + 100000)
|
||
|
|
SET BOT MEMORY "verification_code", code
|
||
|
|
SET BOT MEMORY "verification_cpf", cpf
|
||
|
|
|
||
|
|
' In production: SEND SMS FIRST(customer).phone, "Your General Bank code is: " + code
|
||
|
|
|
||
|
|
TALK "Please enter the 6-digit code:"
|
||
|
|
HEAR entered_code AS INTEGER
|
||
|
|
|
||
|
|
stored_code = GET BOT MEMORY "verification_code"
|
||
|
|
|
||
|
|
IF STR(entered_code) = stored_code THEN
|
||
|
|
SET user_authenticated, TRUE
|
||
|
|
SET user_id, FIRST(customer).id
|
||
|
|
SET user_name, FIRST(customer).name
|
||
|
|
SET user_cpf, cpf
|
||
|
|
|
||
|
|
TALK "✅ Welcome, " + FIRST(customer).name + "!"
|
||
|
|
ELSE
|
||
|
|
TALK "❌ Invalid code. Please try again."
|
||
|
|
END IF
|
||
|
|
END IF
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' MAIN CONVERSATION - LLM handles intent naturally
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
IF GET user_authenticated THEN
|
||
|
|
user_name = GET user_name
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "How can I help you today, " + user_name + "?"
|
||
|
|
TALK ""
|
||
|
|
TALK "You can ask me things like:"
|
||
|
|
TALK "• What's my balance?"
|
||
|
|
TALK "• Send R$ 100 via PIX to 11999998888"
|
||
|
|
TALK "• Pay this boleto: 23793.38128..."
|
||
|
|
TALK "• Block my credit card"
|
||
|
|
TALK "• Simulate a loan of R$ 10,000"
|
||
|
|
|
||
|
|
ADD SUGGESTION "Check balance"
|
||
|
|
ADD SUGGESTION "Make a transfer"
|
||
|
|
ADD SUGGESTION "Pay a bill"
|
||
|
|
ADD SUGGESTION "My cards"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' TOOL: check_balance
|
||
|
|
' Returns account balances for the authenticated user
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' @tool check_balance
|
||
|
|
' @description Get account balances for the current user
|
||
|
|
' @param account_type string optional Filter by account type (checking, savings, all)
|
||
|
|
' @returns Account balances with available amounts
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' TOOL: pix_transfer
|
||
|
|
' Performs a PIX transfer
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' @tool pix_transfer
|
||
|
|
' @description Send money via PIX instant transfer
|
||
|
|
' @param pix_key string required The recipient's PIX key (CPF, phone, email, or random key)
|
||
|
|
' @param amount number required Amount to transfer in BRL
|
||
|
|
' @param description string optional Transfer description
|
||
|
|
' @returns Transfer confirmation with transaction ID
|
||
|
|
|
||
|
|
ON TOOL "pix_transfer"
|
||
|
|
pix_key = GET TOOL PARAM "pix_key"
|
||
|
|
amount = GET TOOL PARAM "amount"
|
||
|
|
description = GET TOOL PARAM "description"
|
||
|
|
|
||
|
|
' Validate PIX key format
|
||
|
|
TALK "🔍 Validating PIX key..."
|
||
|
|
|
||
|
|
' Get recipient info (simulated API call)
|
||
|
|
recipient_name = LLM "Given PIX key " + pix_key + ", return a realistic Brazilian name. Just the name, nothing else."
|
||
|
|
recipient_bank = "Banco Example"
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "📤 **Transfer Details**"
|
||
|
|
TALK "To: **" + recipient_name + "**"
|
||
|
|
TALK "Bank: " + recipient_bank
|
||
|
|
TALK "Amount: **R$ " + FORMAT(amount, "#,##0.00") + "**"
|
||
|
|
TALK ""
|
||
|
|
TALK "Confirm this PIX transfer?"
|
||
|
|
|
||
|
|
ADD SUGGESTION "Yes, confirm"
|
||
|
|
ADD SUGGESTION "No, cancel"
|
||
|
|
|
||
|
|
HEAR confirmation AS BOOLEAN
|
||
|
|
|
||
|
|
IF confirmation THEN
|
||
|
|
TALK "🔐 Enter your 4-digit PIN:"
|
||
|
|
HEAR pin AS INTEGER
|
||
|
|
|
||
|
|
' Validate PIN (in production, verify against stored hash)
|
||
|
|
IF LEN(STR(pin)) = 4 THEN
|
||
|
|
' Execute transfer
|
||
|
|
transaction_id = "PIX" + FORMAT(NOW(), "yyyyMMddHHmmss") + STR(INT(RND() * 1000))
|
||
|
|
|
||
|
|
' Get current balance
|
||
|
|
user_id = GET user_id
|
||
|
|
account = FIRST(FIND "accounts.csv" WHERE user_id = user_id)
|
||
|
|
new_balance = account.balance - amount
|
||
|
|
|
||
|
|
' Save transaction
|
||
|
|
TABLE transaction
|
||
|
|
ROW transaction_id, account.account_number, "pix_out", -amount, new_balance, NOW(), pix_key, recipient_name, "completed"
|
||
|
|
END TABLE
|
||
|
|
SAVE "transactions.csv", transaction
|
||
|
|
|
||
|
|
' Update balance
|
||
|
|
UPDATE "accounts.csv" SET balance = new_balance WHERE id = account.id
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "✅ **PIX Transfer Completed!**"
|
||
|
|
TALK ""
|
||
|
|
TALK "Transaction ID: " + transaction_id
|
||
|
|
TALK "Amount: R$ " + FORMAT(amount, "#,##0.00")
|
||
|
|
TALK "New Balance: R$ " + FORMAT(new_balance, "#,##0.00")
|
||
|
|
TALK "Date: " + FORMAT(NOW(), "dd/MM/yyyy HH:mm")
|
||
|
|
|
||
|
|
RETURN transaction_id
|
||
|
|
ELSE
|
||
|
|
TALK "❌ Invalid PIN format."
|
||
|
|
RETURN "CANCELLED"
|
||
|
|
END IF
|
||
|
|
ELSE
|
||
|
|
TALK "Transfer cancelled."
|
||
|
|
RETURN "CANCELLED"
|
||
|
|
END IF
|
||
|
|
END ON
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' TOOL: pay_boleto
|
||
|
|
' Pays a Brazilian bank slip (boleto)
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' @tool pay_boleto
|
||
|
|
' @description Pay a boleto (bank slip) using the barcode
|
||
|
|
' @param barcode string required The boleto barcode (47 or 48 digits)
|
||
|
|
' @returns Payment confirmation
|
||
|
|
|
||
|
|
ON TOOL "pay_boleto"
|
||
|
|
barcode = GET TOOL PARAM "barcode"
|
||
|
|
|
||
|
|
' Clean barcode
|
||
|
|
barcode = REPLACE(REPLACE(REPLACE(barcode, ".", ""), " ", ""), "-", "")
|
||
|
|
|
||
|
|
IF LEN(barcode) <> 47 AND LEN(barcode) <> 48 THEN
|
||
|
|
TALK "❌ Invalid barcode. Please enter all 47 or 48 digits."
|
||
|
|
RETURN "INVALID_BARCODE"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Parse boleto (simplified - in production use banking API)
|
||
|
|
beneficiary = "Company " + LEFT(barcode, 3)
|
||
|
|
amount = VAL(MID(barcode, 38, 10)) / 100
|
||
|
|
due_date = DATEADD(NOW(), INT(RND() * 30), "day")
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "📄 **Bill Details**"
|
||
|
|
TALK "Beneficiary: **" + beneficiary + "**"
|
||
|
|
TALK "Amount: **R$ " + FORMAT(amount, "#,##0.00") + "**"
|
||
|
|
TALK "Due Date: " + FORMAT(due_date, "dd/MM/yyyy")
|
||
|
|
TALK ""
|
||
|
|
TALK "Pay this bill now?"
|
||
|
|
|
||
|
|
ADD SUGGESTION "Yes, pay now"
|
||
|
|
ADD SUGGESTION "Schedule for due date"
|
||
|
|
ADD SUGGESTION "Cancel"
|
||
|
|
|
||
|
|
HEAR choice AS "Pay now", "Schedule", "Cancel"
|
||
|
|
|
||
|
|
IF choice = "Pay now" THEN
|
||
|
|
TALK "🔐 Enter your PIN:"
|
||
|
|
HEAR pin AS INTEGER
|
||
|
|
|
||
|
|
IF LEN(STR(pin)) = 4 THEN
|
||
|
|
transaction_id = "BOL" + FORMAT(NOW(), "yyyyMMddHHmmss")
|
||
|
|
auth_code = FORMAT(INT(RND() * 100000000), "00000000")
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "✅ **Payment Completed!**"
|
||
|
|
TALK ""
|
||
|
|
TALK "Transaction ID: " + transaction_id
|
||
|
|
TALK "Authentication: " + auth_code
|
||
|
|
TALK "Amount: R$ " + FORMAT(amount, "#,##0.00")
|
||
|
|
|
||
|
|
RETURN transaction_id
|
||
|
|
ELSE
|
||
|
|
TALK "❌ Invalid PIN."
|
||
|
|
RETURN "INVALID_PIN"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
ELSEIF choice = "Schedule" THEN
|
||
|
|
TABLE scheduled
|
||
|
|
ROW NOW(), GET user_id, "boleto", barcode, amount, due_date, "pending"
|
||
|
|
END TABLE
|
||
|
|
SAVE "scheduled_payments.csv", scheduled
|
||
|
|
|
||
|
|
TALK "✅ Payment scheduled for " + FORMAT(due_date, "dd/MM/yyyy")
|
||
|
|
RETURN "SCHEDULED"
|
||
|
|
ELSE
|
||
|
|
TALK "Payment cancelled."
|
||
|
|
RETURN "CANCELLED"
|
||
|
|
END IF
|
||
|
|
END ON
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' TOOL: block_card
|
||
|
|
' Blocks a card for security
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' @tool block_card
|
||
|
|
' @description Block a credit or debit card
|
||
|
|
' @param card_type string optional Type of card to block (credit, debit, all)
|
||
|
|
' @param reason string optional Reason for blocking (lost, stolen, suspicious, temporary)
|
||
|
|
' @returns Block confirmation
|
||
|
|
|
||
|
|
ON TOOL "block_card"
|
||
|
|
card_type = GET TOOL PARAM "card_type"
|
||
|
|
reason = GET TOOL PARAM "reason"
|
||
|
|
|
||
|
|
user_id = GET user_id
|
||
|
|
cards = FIND "cards.csv" WHERE user_id = user_id AND status = "active"
|
||
|
|
|
||
|
|
IF LEN(cards) = 0 THEN
|
||
|
|
TALK "You don't have any active cards to block."
|
||
|
|
RETURN "NO_CARDS"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF card_type = "" OR card_type = "all" THEN
|
||
|
|
TALK "Which card do you want to block?"
|
||
|
|
|
||
|
|
FOR i = 1 TO LEN(cards)
|
||
|
|
card = cards[i]
|
||
|
|
masked = "**** " + RIGHT(card.card_number, 4)
|
||
|
|
TALK STR(i) + ". " + UPPER(card.card_type) + " - " + masked
|
||
|
|
ADD SUGGESTION card.card_type + " " + RIGHT(card.card_number, 4)
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
HEAR selection AS INTEGER
|
||
|
|
|
||
|
|
IF selection < 1 OR selection > LEN(cards) THEN
|
||
|
|
TALK "Invalid selection."
|
||
|
|
RETURN "INVALID_SELECTION"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
selected_card = cards[selection]
|
||
|
|
ELSE
|
||
|
|
selected_card = FIRST(FILTER cards WHERE card_type = card_type)
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF reason = "" THEN
|
||
|
|
TALK "Why are you blocking this card?"
|
||
|
|
ADD SUGGESTION "Lost"
|
||
|
|
ADD SUGGESTION "Stolen"
|
||
|
|
ADD SUGGESTION "Suspicious activity"
|
||
|
|
ADD SUGGESTION "Temporary block"
|
||
|
|
|
||
|
|
HEAR reason AS "Lost", "Stolen", "Suspicious activity", "Temporary block"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Block the card
|
||
|
|
UPDATE "cards.csv" SET status = "blocked", blocked_reason = reason, blocked_at = NOW() WHERE id = selected_card.id
|
||
|
|
|
||
|
|
masked = "**** " + RIGHT(selected_card.card_number, 4)
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "🔒 **Card Blocked**"
|
||
|
|
TALK ""
|
||
|
|
TALK "Card: " + UPPER(selected_card.card_type) + " " + masked
|
||
|
|
TALK "Reason: " + reason
|
||
|
|
TALK "Blocked at: " + FORMAT(NOW(), "dd/MM/yyyy HH:mm")
|
||
|
|
|
||
|
|
IF reason = "Stolen" OR reason = "Lost" THEN
|
||
|
|
TALK ""
|
||
|
|
TALK "⚠️ For your security, we recommend requesting a replacement card."
|
||
|
|
TALK "Would you like me to request a new card?"
|
||
|
|
|
||
|
|
ADD SUGGESTION "Yes, request new card"
|
||
|
|
ADD SUGGESTION "No, not now"
|
||
|
|
|
||
|
|
HEAR request_new AS BOOLEAN
|
||
|
|
|
||
|
|
IF request_new THEN
|
||
|
|
TALK "✅ New card requested! It will arrive in 5-7 business days."
|
||
|
|
END IF
|
||
|
|
END IF
|
||
|
|
|
||
|
|
RETURN "BLOCKED"
|
||
|
|
END ON
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' TOOL: simulate_loan
|
||
|
|
' Simulates loan options
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' @tool simulate_loan
|
||
|
|
' @description Simulate a personal loan with different terms
|
||
|
|
' @param amount number required Loan amount in BRL
|
||
|
|
' @param months integer optional Number of months (12, 24, 36, 48, 60)
|
||
|
|
' @param loan_type string optional Type of loan (personal, payroll, home_equity)
|
||
|
|
' @returns Loan simulation with monthly payments
|
||
|
|
|
||
|
|
ON TOOL "simulate_loan"
|
||
|
|
amount = GET TOOL PARAM "amount"
|
||
|
|
months = GET TOOL PARAM "months"
|
||
|
|
loan_type = GET TOOL PARAM "loan_type"
|
||
|
|
|
||
|
|
IF amount < 500 THEN
|
||
|
|
TALK "Minimum loan amount is R$ 500.00"
|
||
|
|
RETURN "AMOUNT_TOO_LOW"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF amount > 100000 THEN
|
||
|
|
TALK "For amounts above R$ 100,000, please visit a branch."
|
||
|
|
RETURN "AMOUNT_TOO_HIGH"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF months = 0 THEN
|
||
|
|
TALK "In how many months would you like to pay?"
|
||
|
|
ADD SUGGESTION "12 months"
|
||
|
|
ADD SUGGESTION "24 months"
|
||
|
|
ADD SUGGESTION "36 months"
|
||
|
|
ADD SUGGESTION "48 months"
|
||
|
|
ADD SUGGESTION "60 months"
|
||
|
|
|
||
|
|
HEAR months_input AS INTEGER
|
||
|
|
months = months_input
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF loan_type = "" THEN
|
||
|
|
loan_type = "personal"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Calculate rates based on type
|
||
|
|
IF loan_type = "payroll" THEN
|
||
|
|
monthly_rate = 0.0149
|
||
|
|
rate_label = "1.49%"
|
||
|
|
ELSEIF loan_type = "home_equity" THEN
|
||
|
|
monthly_rate = 0.0099
|
||
|
|
rate_label = "0.99%"
|
||
|
|
ELSE
|
||
|
|
monthly_rate = 0.0199
|
||
|
|
rate_label = "1.99%"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' PMT calculation
|
||
|
|
pmt = amount * (monthly_rate * POWER(1 + monthly_rate, months)) / (POWER(1 + monthly_rate, months) - 1)
|
||
|
|
total = pmt * months
|
||
|
|
interest_total = total - amount
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "💰 **Loan Simulation**"
|
||
|
|
TALK ""
|
||
|
|
TALK "📊 **" + UPPER(loan_type) + " LOAN**"
|
||
|
|
TALK ""
|
||
|
|
TALK "Amount: R$ " + FORMAT(amount, "#,##0.00")
|
||
|
|
TALK "Term: " + STR(months) + " months"
|
||
|
|
TALK "Interest Rate: " + rate_label + " per month"
|
||
|
|
TALK ""
|
||
|
|
TALK "📅 **Monthly Payment: R$ " + FORMAT(pmt, "#,##0.00") + "**"
|
||
|
|
TALK ""
|
||
|
|
TALK "Total to pay: R$ " + FORMAT(total, "#,##0.00")
|
||
|
|
TALK "Total interest: R$ " + FORMAT(interest_total, "#,##0.00")
|
||
|
|
TALK ""
|
||
|
|
TALK "Would you like to apply for this loan?"
|
||
|
|
|
||
|
|
ADD SUGGESTION "Yes, apply now"
|
||
|
|
ADD SUGGESTION "Try different values"
|
||
|
|
ADD SUGGESTION "Not now"
|
||
|
|
|
||
|
|
HEAR decision AS "Apply", "Try again", "No"
|
||
|
|
|
||
|
|
IF decision = "Apply" THEN
|
||
|
|
TALK "Great! Let me collect some additional information."
|
||
|
|
|
||
|
|
TALK "What is your monthly income?"
|
||
|
|
HEAR income AS MONEY
|
||
|
|
|
||
|
|
TALK "What is your profession?"
|
||
|
|
HEAR profession AS NAME
|
||
|
|
|
||
|
|
' Check debt-to-income ratio
|
||
|
|
IF pmt > income * 0.35 THEN
|
||
|
|
TALK "⚠️ The monthly payment exceeds 35% of your income."
|
||
|
|
TALK "We recommend a smaller amount or longer term."
|
||
|
|
RETURN "HIGH_DTI"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
application_id = "LOAN" + FORMAT(NOW(), "yyyyMMddHHmmss")
|
||
|
|
|
||
|
|
TABLE loan_application
|
||
|
|
ROW application_id, GET user_id, loan_type, amount, months, monthly_rate, income, profession, NOW(), "pending"
|
||
|
|
END TABLE
|
||
|
|
SAVE "loan_applications.csv", loan_application
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "🎉 **Application Submitted!**"
|
||
|
|
TALK ""
|
||
|
|
TALK "Application ID: " + application_id
|
||
|
|
TALK "Status: Under Analysis"
|
||
|
|
TALK ""
|
||
|
|
TALK "We'll analyze your application within 24 hours."
|
||
|
|
TALK "You'll receive updates via app notifications."
|
||
|
|
|
||
|
|
RETURN application_id
|
||
|
|
|
||
|
|
ELSEIF decision = "Try again" THEN
|
||
|
|
TALK "No problem! What values would you like to try?"
|
||
|
|
RETURN "RETRY"
|
||
|
|
ELSE
|
||
|
|
TALK "No problem! I'm here whenever you need."
|
||
|
|
RETURN "DECLINED"
|
||
|
|
END IF
|
||
|
|
END ON
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' TOOL: create_virtual_card
|
||
|
|
' Creates a virtual card for online purchases
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' @tool create_virtual_card
|
||
|
|
' @description Create a virtual credit card for online shopping
|
||
|
|
' @param limit number optional Maximum limit for the virtual card
|
||
|
|
' @returns Virtual card details
|
||
|
|
|
||
|
|
ON TOOL "create_virtual_card"
|
||
|
|
limit = GET TOOL PARAM "limit"
|
||
|
|
|
||
|
|
user_id = GET user_id
|
||
|
|
credit_cards = FIND "cards.csv" WHERE user_id = user_id AND card_type = "credit" AND status = "active"
|
||
|
|
|
||
|
|
IF LEN(credit_cards) = 0 THEN
|
||
|
|
TALK "You need an active credit card to create virtual cards."
|
||
|
|
RETURN "NO_CREDIT_CARD"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
main_card = FIRST(credit_cards)
|
||
|
|
|
||
|
|
IF limit = 0 THEN
|
||
|
|
TALK "What limit would you like for this virtual card?"
|
||
|
|
TALK "Available credit: R$ " + FORMAT(main_card.available_limit, "#,##0.00")
|
||
|
|
|
||
|
|
ADD SUGGESTION "R$ 100"
|
||
|
|
ADD SUGGESTION "R$ 500"
|
||
|
|
ADD SUGGESTION "R$ 1000"
|
||
|
|
ADD SUGGESTION "Custom amount"
|
||
|
|
|
||
|
|
HEAR limit AS MONEY
|
||
|
|
END IF
|
||
|
|
|
||
|
|
IF limit > main_card.available_limit THEN
|
||
|
|
TALK "❌ Limit exceeds available credit."
|
||
|
|
TALK "Maximum available: R$ " + FORMAT(main_card.available_limit, "#,##0.00")
|
||
|
|
RETURN "LIMIT_EXCEEDED"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Generate virtual card
|
||
|
|
virtual_number = "4" + FORMAT(INT(RND() * 1000000000000000), "000000000000000")
|
||
|
|
virtual_cvv = FORMAT(INT(RND() * 1000), "000")
|
||
|
|
virtual_expiry = FORMAT(DATEADD(NOW(), 1, "year"), "MM/yy")
|
||
|
|
|
||
|
|
virtual_id = "VC" + FORMAT(NOW(), "yyyyMMddHHmmss")
|
||
|
|
|
||
|
|
TABLE virtual_card
|
||
|
|
ROW virtual_id, user_id, main_card.id, "virtual", virtual_number, virtual_cvv, virtual_expiry, limit, limit, "active", NOW()
|
||
|
|
END TABLE
|
||
|
|
SAVE "cards.csv", virtual_card
|
||
|
|
|
||
|
|
' Format card number for display
|
||
|
|
formatted_number = LEFT(virtual_number, 4) + " " + MID(virtual_number, 5, 4) + " " + MID(virtual_number, 9, 4) + " " + RIGHT(virtual_number, 4)
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "✅ **Virtual Card Created!**"
|
||
|
|
TALK ""
|
||
|
|
TALK "🔢 Number: " + formatted_number
|
||
|
|
TALK "📅 Expiry: " + virtual_expiry
|
||
|
|
TALK "🔐 CVV: " + virtual_cvv
|
||
|
|
TALK "💰 Limit: R$ " + FORMAT(limit, "#,##0.00")
|
||
|
|
TALK ""
|
||
|
|
TALK "⚠️ **Save these details now!**"
|
||
|
|
TALK "The CVV will not be shown again for security."
|
||
|
|
TALK ""
|
||
|
|
TALK "This virtual card is linked to your main credit card."
|
||
|
|
TALK "You can delete it anytime."
|
||
|
|
|
||
|
|
RETURN virtual_id
|
||
|
|
END ON
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' TOOL: get_statement
|
||
|
|
' Gets account statement
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' @tool get_statement
|
||
|
|
' @description Get account statement for a period
|
||
|
|
' @param period string optional Period: "30days", "90days", "month", or custom dates
|
||
|
|
' @param format string optional Output format: "chat", "pdf", "email"
|
||
|
|
' @returns Statement data or download link
|
||
|
|
|
||
|
|
ON TOOL "get_statement"
|
||
|
|
period = GET TOOL PARAM "period"
|
||
|
|
format = GET TOOL PARAM "format"
|
||
|
|
|
||
|
|
user_id = GET user_id
|
||
|
|
account = FIRST(FIND "accounts.csv" WHERE user_id = user_id)
|
||
|
|
|
||
|
|
IF period = "" THEN
|
||
|
|
TALK "Select the period for your statement:"
|
||
|
|
ADD SUGGESTION "Last 30 days"
|
||
|
|
ADD SUGGESTION "Last 90 days"
|
||
|
|
ADD SUGGESTION "This month"
|
||
|
|
ADD SUGGESTION "Custom dates"
|
||
|
|
|
||
|
|
HEAR period_choice AS "30 days", "90 days", "This month", "Custom"
|
||
|
|
|
||
|
|
IF period_choice = "Custom" THEN
|
||
|
|
TALK "Enter start date:"
|
||
|
|
HEAR start_date AS DATE
|
||
|
|
|
||
|
|
TALK "Enter end date:"
|
||
|
|
HEAR end_date AS DATE
|
||
|
|
ELSEIF period_choice = "30 days" THEN
|
||
|
|
start_date = DATEADD(NOW(), -30, "day")
|
||
|
|
end_date = NOW()
|
||
|
|
ELSEIF period_choice = "90 days" THEN
|
||
|
|
start_date = DATEADD(NOW(), -90, "day")
|
||
|
|
end_date = NOW()
|
||
|
|
ELSE
|
||
|
|
start_date = DATEADD(NOW(), -DAY(NOW()) + 1, "day")
|
||
|
|
end_date = NOW()
|
||
|
|
END IF
|
||
|
|
END IF
|
||
|
|
|
||
|
|
' Get transactions
|
||
|
|
transactions = FIND "transactions.csv" WHERE account_number = account.account_number AND date >= start_date AND date <= end_date ORDER BY date DESC
|
||
|
|
|
||
|
|
IF LEN(transactions) = 0 THEN
|
||
|
|
TALK "No transactions found for this period."
|
||
|
|
RETURN "NO_TRANSACTIONS"
|
||
|
|
END IF
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "📋 **Account Statement**"
|
||
|
|
TALK "Period: " + FORMAT(start_date, "dd/MM/yyyy") + " to " + FORMAT(end_date, "dd/MM/yyyy")
|
||
|
|
TALK "Account: " + account.account_number
|
||
|
|
TALK ""
|
||
|
|
|
||
|
|
total_in = 0
|
||
|
|
total_out = 0
|
||
|
|
|
||
|
|
FOR EACH tx IN transactions
|
||
|
|
IF tx.amount > 0 THEN
|
||
|
|
icon = "💵 +"
|
||
|
|
total_in = total_in + tx.amount
|
||
|
|
ELSE
|
||
|
|
icon = "💸 "
|
||
|
|
total_out = total_out + ABS(tx.amount)
|
||
|
|
END IF
|
||
|
|
|
||
|
|
TALK icon + "R$ " + FORMAT(ABS(tx.amount), "#,##0.00") + " | " + FORMAT(tx.date, "dd/MM")
|
||
|
|
TALK " " + tx.description
|
||
|
|
NEXT
|
||
|
|
|
||
|
|
TALK ""
|
||
|
|
TALK "📊 **Summary**"
|
||
|
|
TALK "Total In: R$ " + FORMAT(total_in, "#,##0.00")
|
||
|
|
TALK "Total Out: R$ " + FORMAT(total_out, "#,##0.00")
|
||
|
|
TALK "Net: R$ " + FORMAT(total_in - total_out, "#,##0.00")
|
||
|
|
|
||
|
|
IF format = "pdf" OR format = "email" THEN
|
||
|
|
TALK ""
|
||
|
|
TALK "Would you like me to send this statement to your email?"
|
||
|
|
|
||
|
|
ADD SUGGESTION "Yes, send email"
|
||
|
|
ADD SUGGESTION "No, thanks"
|
||
|
|
|
||
|
|
HEAR send_email AS BOOLEAN
|
||
|
|
|
||
|
|
IF send_email THEN
|
||
|
|
customer = FIRST(FIND "customers.csv" WHERE id = user_id)
|
||
|
|
SEND MAIL customer.email, "Your General Bank Statement", "Please find attached your account statement.", "statement.pdf"
|
||
|
|
TALK "📧 Statement sent to your email!"
|
||
|
|
END IF
|
||
|
|
END IF
|
||
|
|
|
||
|
|
RETURN "SUCCESS"
|
||
|
|
END ON
|
||
|
|
|
||
|
|
' ============================================================================
|
||
|
|
' FALLBACK - Let LLM handle anything not covered by tools
|
||
|
|
' ============================================================================
|
||
|
|
|
||
|
|
' The LLM will use the available tools based on user intent
|
||
|
|
' No need for rigid menu systems - natural conversation flow
|