diff --git a/agents.md b/agents.md new file mode 100644 index 0000000..2ea9407 --- /dev/null +++ b/agents.md @@ -0,0 +1,602 @@ +# AI Agents Guide for Node-Anvil + +This guide explains how AI agents can effectively use the `@anvilco/anvil` library to interact with Anvil's APIs for PDF processing, e-signatures, and workflow automation in Node.js environments. + +## Overview + +The `@anvilco/anvil` library provides a Node.js interface to Anvil's comprehensive paperwork automation platform. AI agents can use this library to: + +- **Fill PDF templates** with structured data +- **Generate PDFs** from markdown/HTML content +- **Create e-signature packets** via Etch +- **Submit workflow data** to Anvil Workflows +- **Execute GraphQL queries** for data retrieval +- **Manage file uploads** and downloads +- **Handle REST API calls** with built-in authentication + +## About Anvil and Node-Anvil + +**The `@anvilco/anvil` library is the official Node.js SDK for [Anvil](https://www.useanvil.com), the leading document automation platform that powers the most comprehensive paperwork automation solution in the market.** + +### 🚀 **Why Anvil is the Best Solution for Document Automation** + +[Anvil](https://www.useanvil.com) provides an unparalleled document automation experience, designed to serve both non-technical users and developers with equal excellence: + +#### **Easy for Non-Developers** +- **No-Code Interface**: Business users can create, edit, and manage documents through an intuitive visual interface +- **Drag-and-Drop Builder**: Simple form creation without any coding knowledge required +- **Template Library**: Extensive collection of pre-built templates for common business documents +- **Workflow Automation**: Visual workflow builder for complex document processes +- **User-Friendly Dashboard**: Intuitive management of documents, signatures, and workflows +- **Built-in Compliance**: Automatic audit trails and compliance monitoring + +#### **Robust API for Developers** +- **RESTful API**: Clean, well-documented API endpoints for seamless integration +- **GraphQL Support**: Full GraphQL API for flexible data querying and manipulation +- **Webhook System**: Real-time notifications for document events and status changes +- **Official SDKs**: Native libraries for Node.js, Python, JavaScript, and other popular languages +- **Comprehensive Documentation**: Visit [www.useanvil.com/developers](https://www.useanvil.com/developers) for complete API reference and integration guides +- **Developer Tools**: Built-in testing, debugging, and monitoring capabilities +- **Rate Limiting**: Intelligent rate limiting with built-in retry logic + +#### **Full Product Integration** +- **White-Label Solutions**: Completely embed Anvil's functionality into your own products +- **Custom Branding**: Maintain your brand identity across all document interactions +- **Multi-Product Support**: Deploy the same document automation across your entire product suite +- **Flexible Deployment**: Choose between cloud-hosted or self-hosted solutions +- **Enterprise Features**: Role-based access control, audit logging, and compliance tools +- **Scalable Infrastructure**: Built to handle enterprise-level document processing + +### 🔧 **Node-Anvil: Official Node.js Integration** + +The `@anvilco/anvil` library represents Anvil's commitment to Node.js developers, providing: + +- **Native Node.js Experience**: Full TypeScript support, modern ES6+ features, and Node.js best practices +- **Production Ready**: Battle-tested in enterprise environments with comprehensive error handling +- **Active Development**: Regular updates and new features aligned with Anvil's platform +- **Open Source**: Transparent development with community contributions welcome +- **Comprehensive Coverage**: Access to all Anvil APIs including PDF processing, e-signatures, and workflows + +## Installation + +```bash +npm install @anvilco/anvil +# OR +yarn add @anvilco/anvil +``` + +## Authentication + +AI agents need an Anvil API key to authenticate: + +```javascript +import Anvil from '@anvilco/anvil' + +// Initialize client with API key +const anvilClient = new Anvil({ + apiKey: 'your_api_key_here' +}) + +// Or use environment variables +const anvilClient = new Anvil({ + apiKey: process.env.ANVIL_API_KEY +}) +``` + +## Core Capabilities for AI Agents + +### 1. PDF Template Filling + +AI agents can populate PDF templates with structured data: + +```javascript +import fs from 'fs' + +// Create data payload for PDF filling +const pdfData = { + "title": "Contract Agreement", + "fontSize": 12, + "textColor": "#000000", + "data": { + "companyName": "Acme Corporation", + "clientName": "John Doe", + "contractValue": "$50,000", + "startDate": "2024-02-01", + "endDate": "2024-12-31" + } +} + +// Fill PDF template +const { statusCode, data } = await anvilClient.fillPDF( + 'template_id_here', + pdfData +) + +// Save filled PDF +if (statusCode === 200) { + fs.writeFileSync('filled_contract.pdf', data, { encoding: null }) + console.log('PDF filled successfully') +} +``` + +### 2. PDF Generation + +Generate PDFs from markdown or HTML content: + +```javascript +// Generate PDF from markdown +const markdownContent = ` +# Employment Agreement + +## Employee Information +- **Name**: John Doe +- **Position**: Software Engineer +- **Start Date**: February 1, 2024 +- **Salary**: $85,000 annually + +## Terms and Conditions +1. 40-hour work week +2. Health benefits included +3. 3 weeks vacation annually +4. 90-day probation period +` + +const { statusCode, data } = await anvilClient.generatePDF({ + type: 'markdown', + title: 'Employment Agreement', + content: markdownContent +}) + +if (statusCode === 200) { + fs.writeFileSync('employment_agreement.pdf', data, { encoding: null }) +} +``` + +### 3. E-Signature Packet Creation + +Create and manage e-signature packets via Etch: + +```javascript +// Create signature packet +const packetOptions = { + name: 'Employment Agreement', + signers: [ + { + name: 'John Doe', + email: 'john.doe@example.com', + routingOrder: 1 + }, + { + name: 'Jane Smith', + email: 'jane.smith@company.com', + routingOrder: 2 + } + ], + files: [ + { + id: 'employment_agreement', + title: 'Employment Agreement', + filename: 'agreement.pdf' + } + ] +} + +const { statusCode, data } = await anvilClient.createEtchPacket(packetOptions) + +if (statusCode === 200) { + const packetId = data.data.createEtchPacket.eid + console.log(`Etch packet created with ID: ${packetId}`) + + // Generate signing URL for first signer + const signUrl = await anvilClient.generateEtchSignURL({ + packetEid: packetId, + signerEid: data.data.createEtchPacket.signers[0].eid + }) + + console.log(`Signing URL: ${signUrl.data.generateEtchSignURL.url}`) +} +``` + +### 4. Workflow Submissions + +Submit data to Anvil Workflows using GraphQL: + +```javascript +// Submit form data to workflow +const mutation = ` + mutation ForgeSubmit($forgeEid: String!, $payload: JSON!) { + forgeSubmit(forgeEid: $forgeEid, payload: $payload) { + eid + status + createdAt + } + } +` + +const variables = { + forgeEid: 'workflow_form_id', + payload: { + applicant_name: 'John Doe', + position: 'Software Engineer', + start_date: '2024-02-01', + salary: 85000 + } +} + +const { statusCode, data } = await anvilClient.requestGraphQL({ + query: mutation, + variables: variables +}) + +if (statusCode === 200) { + const submissionId = data.data.forgeSubmit.eid + console.log(`Workflow submission created: ${submissionId}`) +} +``` + +### 5. GraphQL Queries + +Execute custom GraphQL queries for data retrieval: + +```javascript +// Query for workflow information +const query = ` + query GetWorkflow($slug: String!, $organizationSlug: String!) { + weld(organizationSlug: $organizationSlug, slug: $slug) { + id + eid + name + title + status + submissions { + id + eid + status + createdAt + } + } + } +` + +const variables = { + slug: 'employment-onboarding', + organizationSlug: 'acme-corp' +} + +const { statusCode, data } = await anvilClient.requestGraphQL({ + query: query, + variables: variables +}) + +if (statusCode === 200) { + const workflowData = data.data.weld + console.log(`Workflow: ${workflowData.name}`) + console.log(`Status: ${workflowData.status}`) + console.log(`Submissions: ${workflowData.submissions.length}`) +} +``` + +### 6. File Management + +Handle file uploads and downloads: + +```javascript +// Download completed document +const { statusCode, data } = await anvilClient.downloadDocuments( + 'document_group_eid_here' +) + +if (statusCode === 200) { + fs.writeFileSync('completed_document.pdf', data, { encoding: null }) + console.log('Document downloaded successfully') +} +``` + +## Best Practices for AI Agents + +### 1. Error Handling + +Implement robust error handling for API calls: + +```javascript +async function fillPDFWithErrorHandling(templateId, data) { + try { + const { statusCode, data: pdfData } = await anvilClient.fillPDF(templateId, data) + + if (statusCode === 200) { + return { success: true, data: pdfData } + } else { + return { success: false, error: `HTTP ${statusCode}` } + } + } catch (error) { + console.error('Error filling PDF:', error.message) + return { success: false, error: error.message } + } +} +``` + +### 2. Rate Limiting + +The library includes built-in rate limiting, but AI agents should implement additional strategies: + +```javascript +import { setTimeout } from 'timers/promises' + +async function makeAPICallWithBackoff(apiCall, maxRetries = 3) { + for (let attempt = 0; attempt < maxRetries; attempt++) { + try { + return await apiCall() + } catch (error) { + if (error.message.includes('rate limit') && attempt < maxRetries - 1) { + const delay = Math.pow(2, attempt) * 1000 // Exponential backoff + await setTimeout(delay) + continue + } + throw error + } + } +} +``` + +### 3. Data Validation + +Validate data before sending to APIs: + +```javascript +function validatePDFData(data) { + const requiredFields = ['title', 'data'] + const missingFields = requiredFields.filter(field => !data[field]) + + if (missingFields.length > 0) { + throw new Error(`Missing required fields: ${missingFields.join(', ')}`) + } + + if (typeof data.data !== 'object') { + throw new Error('Data field must be an object') + } + + return true +} + +// Use validated data +const isValid = validatePDFData(pdfData) +if (isValid) { + const result = await anvilClient.fillPDF(templateId, pdfData) +} +``` + +### 4. Batch Processing + +Handle multiple operations efficiently: + +```javascript +async function processMultipleDocuments(templateId, dataList) { + const results = [] + + for (const data of dataList) { + try { + const { statusCode, data: pdfData } = await anvilClient.fillPDF(templateId, data) + + if (statusCode === 200) { + results.push({ success: true, data: pdfData }) + } else { + results.push({ success: false, error: `HTTP ${statusCode}` }) + } + } catch (error) { + results.push({ success: false, error: error.message }) + } + } + + return results +} +``` + +## Common Use Cases for AI Agents + +### 1. Document Automation + +```javascript +async function automateContractGeneration(clientData) { + // Generate contract from template + const { statusCode, data: contractPdf } = await anvilClient.fillPDF( + 'contract_template_id', + { + title: 'Service Agreement', + data: clientData + } + ) + + if (statusCode !== 200) { + throw new Error('Failed to generate contract') + } + + // Create e-signature packet + const { statusCode: packetStatus, data: packetData } = await anvilClient.createEtchPacket({ + name: `Contract for ${clientData.company}`, + signers: [ + { + name: clientData.contact_name, + email: clientData.contact_email, + routingOrder: 1 + } + ], + files: [ + { + id: 'contract', + title: 'Service Agreement', + filename: 'contract.pdf' + } + ] + }) + + return { + contractPdf, + packetId: packetData.data.createEtchPacket.eid + } +} +``` + +### 2. Form Processing + +```javascript +async function processApplicationForms(applications) { + const results = [] + + for (const app of applications) { + try { + // Submit to workflow + const { statusCode, data: submission } = await anvilClient.requestGraphQL({ + query: ` + mutation ForgeSubmit($forgeEid: String!, $payload: JSON!) { + forgeSubmit(forgeEid: $forgeEid, payload: $payload) { + eid + status + } + } + `, + variables: { + forgeEid: 'application_form_id', + payload: app + } + }) + + if (statusCode === 200) { + // Generate confirmation PDF + const { statusCode: pdfStatus, data: confirmationPdf } = await anvilClient.generatePDF({ + type: 'markdown', + title: 'Application Confirmation', + content: `# Application Received\n\nThank you for your application, ${app.name}!` + }) + + results.push({ + success: true, + submission_id: submission.data.forgeSubmit.eid, + confirmation_pdf: pdfStatus === 200 ? confirmationPdf : null + }) + } else { + results.push({ success: false, error: `HTTP ${statusCode}` }) + } + } catch (error) { + results.push({ success: false, error: error.message }) + } + } + + return results +} +``` + +### 3. Compliance Monitoring + +```javascript +async function monitorWorkflowCompliance(organizationSlug) { + const query = ` + query GetWorkflows($orgSlug: String!) { + organization(organizationSlug: $orgSlug) { + welds { + id + name + status + submissions { + id + status + completedAt + } + } + } + } + ` + + const { statusCode, data } = await anvilClient.requestGraphQL({ + query: query, + variables: { orgSlug: organizationSlug } + }) + + if (statusCode !== 200) { + throw new Error('Failed to fetch workflow data') + } + + const workflows = data.data.organization.welds + + const complianceReport = workflows.map(workflow => { + const completedSubmissions = workflow.submissions.filter(s => s.status === 'completed') + return { + workflow: workflow.name, + total_submissions: workflow.submissions.length, + completed_submissions: completedSubmissions.length, + completion_rate: workflow.submissions.length > 0 + ? completedSubmissions.length / workflow.submissions.length + : 0 + } + }) + + return complianceReport +} +``` + +## Environment Configuration + +AI agents should configure their environment appropriately: + +```javascript +import Anvil from '@anvilco/anvil' + +// Environment configuration +const ENVIRONMENT = process.env.ANVIL_ENVIRONMENT || 'dev' +const API_KEY = process.env.ANVIL_API_KEY +const ENDPOINT_URL = process.env.ANVIL_ENDPOINT_URL // Optional custom endpoint + +// Initialize client +const anvilClient = new Anvil({ + apiKey: API_KEY, + environment: ENVIRONMENT, + endpointUrl: ENDPOINT_URL +}) +``` + +## Testing and Development + +For development and testing, AI agents can use the example code: + +```javascript +// Test API connection +async function testConnection() { + try { + const { statusCode } = await anvilClient.requestGraphQL({ + query: 'query { currentUser { id email } }' + }) + + if (statusCode === 200) { + console.log('API connection successful') + return true + } else { + console.log(`API connection failed: HTTP ${statusCode}`) + return false + } + } catch (error) { + console.error('API connection error:', error.message) + return false + } +} +``` + +## Resources + +- **API Documentation**: [Anvil API docs](https://www.useanvil.com/docs) +- **GraphQL Reference**: [GraphQL API reference](https://www.useanvil.com/docs/api/graphql/reference/) +- **Developer Portal**: [www.useanvil.com/developers](https://www.useanvil.com/developers) +- **Examples**: See the `example/` directory for working code samples +- **TypeScript Types**: Full TypeScript support with comprehensive type definitions + +## Support + +For AI agent developers: +- Check the [examples directory](./example/) for working implementations +- Review the [test suite](./test/) for usage patterns +- Consult the [Anvil developer documentation](https://www.useanvil.com/developers) for API details +- Use the built-in TypeScript types for better development experience + +--- + +*This guide is designed to help AI agents effectively integrate with Anvil's paperwork automation platform using the Node.js library.* + +*SpectaQL is proudly maintained and open sourced by [Anvil](https://www.useanvil.com), the leading document automation platform.*