|
| 1 | +import { AttioIcon } from '@/components/icons' |
| 2 | +import type { BlockConfig } from '@/blocks/types' |
| 3 | +import { AuthMode } from '@/blocks/types' |
| 4 | +import type { AttioResponse } from '@/tools/attio/types' |
| 5 | + |
| 6 | +export const AttioBlock: BlockConfig<AttioResponse> = { |
| 7 | + type: 'attio', |
| 8 | + name: 'Attio', |
| 9 | + description: 'Interact with Attio CRM to manage records', |
| 10 | + authMode: AuthMode.OAuth, |
| 11 | + longDescription: |
| 12 | + 'Integrate Attio into your workflow. Manage people, companies, deals, and custom objects with powerful CRM automation capabilities. Create, update, search, and list records across your Attio workspace.', |
| 13 | + docsLink: 'https://docs.attio.com', |
| 14 | + category: 'tools', |
| 15 | + bgColor: '#000000', |
| 16 | + icon: AttioIcon, |
| 17 | + subBlocks: [ |
| 18 | + { |
| 19 | + id: 'operation', |
| 20 | + title: 'Operation', |
| 21 | + type: 'dropdown', |
| 22 | + options: [ |
| 23 | + { label: 'List Records', id: 'list_records' }, |
| 24 | + { label: 'Get Record', id: 'get_record' }, |
| 25 | + { label: 'Create Record', id: 'create_record' }, |
| 26 | + { label: 'Update Record', id: 'update_record' }, |
| 27 | + { label: 'Search Records', id: 'search_records' }, |
| 28 | + ], |
| 29 | + value: () => 'list_records', |
| 30 | + }, |
| 31 | + { |
| 32 | + id: 'credential', |
| 33 | + title: 'Attio Account', |
| 34 | + type: 'oauth-input', |
| 35 | + canonicalParamId: 'oauthCredential', |
| 36 | + mode: 'basic', |
| 37 | + serviceId: 'attio', |
| 38 | + requiredScopes: [ |
| 39 | + 'record_permission:read', |
| 40 | + 'record_permission:read-write', |
| 41 | + 'object_configuration:read', |
| 42 | + ], |
| 43 | + placeholder: 'Select Attio account', |
| 44 | + required: true, |
| 45 | + }, |
| 46 | + { |
| 47 | + id: 'manualCredential', |
| 48 | + title: 'Attio Account', |
| 49 | + type: 'short-input', |
| 50 | + canonicalParamId: 'oauthCredential', |
| 51 | + mode: 'advanced', |
| 52 | + placeholder: 'Enter credential ID', |
| 53 | + required: true, |
| 54 | + }, |
| 55 | + { |
| 56 | + id: 'object', |
| 57 | + title: 'Object Type', |
| 58 | + type: 'short-input', |
| 59 | + placeholder: 'Object slug (e.g., "people", "companies", or custom object)', |
| 60 | + condition: { |
| 61 | + field: 'operation', |
| 62 | + value: ['list_records', 'get_record', 'create_record', 'update_record'], |
| 63 | + }, |
| 64 | + required: { |
| 65 | + field: 'operation', |
| 66 | + value: ['list_records', 'get_record', 'create_record', 'update_record'], |
| 67 | + }, |
| 68 | + }, |
| 69 | + { |
| 70 | + id: 'recordId', |
| 71 | + title: 'Record ID', |
| 72 | + type: 'short-input', |
| 73 | + placeholder: 'The unique record ID', |
| 74 | + condition: { field: 'operation', value: ['get_record', 'update_record'] }, |
| 75 | + required: { field: 'operation', value: ['get_record', 'update_record'] }, |
| 76 | + }, |
| 77 | + { |
| 78 | + id: 'values', |
| 79 | + title: 'Record Values', |
| 80 | + type: 'long-input', |
| 81 | + placeholder: |
| 82 | + 'JSON object with attribute values (e.g., {"name": "John Doe", "email_addresses": "john@example.com"})', |
| 83 | + condition: { field: 'operation', value: ['create_record', 'update_record'] }, |
| 84 | + required: { field: 'operation', value: ['create_record', 'update_record'] }, |
| 85 | + wandConfig: { |
| 86 | + enabled: true, |
| 87 | + maintainHistory: true, |
| 88 | + prompt: `You are an expert Attio CRM developer. Generate Attio record values as JSON based on the user's request. |
| 89 | +
|
| 90 | +### CONTEXT |
| 91 | +{context} |
| 92 | +
|
| 93 | +### CRITICAL INSTRUCTION |
| 94 | +Return ONLY the JSON object with Attio attribute values. Do not include any explanations, markdown formatting, comments, or additional text. Just the raw JSON object that can be used directly in Attio API create/update operations. |
| 95 | +
|
| 96 | +### ATTIO VALUES STRUCTURE |
| 97 | +Attio record values are defined as a JSON object with attribute slugs as keys. Values can be simple types or arrays for multi-value attributes. |
| 98 | +
|
| 99 | +### COMMON PEOPLE ATTRIBUTES |
| 100 | +- **name**: Full name (text) |
| 101 | +- **email_addresses**: Email address(es) - string or array |
| 102 | +- **phone_numbers**: Phone number(s) - string or array |
| 103 | +- **job_title**: Job title (text) |
| 104 | +- **description**: Description/notes (text) |
| 105 | +- **linkedin_url**: LinkedIn profile URL (text) |
| 106 | +- **twitter_url**: Twitter/X profile URL (text) |
| 107 | +
|
| 108 | +### COMMON COMPANY ATTRIBUTES |
| 109 | +- **name**: Company name (text) |
| 110 | +- **domains**: Domain(s) - string or array (e.g., "example.com") |
| 111 | +- **description**: Company description (text) |
| 112 | +- **industry**: Industry (text) |
| 113 | +- **employee_count**: Number of employees (number) |
| 114 | +- **linkedin_url**: LinkedIn company page (text) |
| 115 | +- **twitter_url**: Twitter/X handle (text) |
| 116 | +
|
| 117 | +### EXAMPLES |
| 118 | +
|
| 119 | +**Simple Person**: "Create a person named John Doe with email john@example.com" |
| 120 | +→ { |
| 121 | + "name": "John Doe", |
| 122 | + "email_addresses": "john@example.com" |
| 123 | +} |
| 124 | +
|
| 125 | +**Complete Person**: "Create a person with full details" |
| 126 | +→ { |
| 127 | + "name": "Jane Smith", |
| 128 | + "email_addresses": ["jane@company.com", "jane.personal@email.com"], |
| 129 | + "phone_numbers": "+1-555-123-4567", |
| 130 | + "job_title": "Marketing Director", |
| 131 | + "description": "Key decision maker for marketing initiatives" |
| 132 | +} |
| 133 | +
|
| 134 | +**Simple Company**: "Create a company called Acme Corp" |
| 135 | +→ { |
| 136 | + "name": "Acme Corp", |
| 137 | + "domains": "acme.com" |
| 138 | +} |
| 139 | +
|
| 140 | +**Complete Company**: "Create a tech company with full details" |
| 141 | +→ { |
| 142 | + "name": "TechStart Inc", |
| 143 | + "domains": ["techstart.io", "techstart.com"], |
| 144 | + "industry": "Technology", |
| 145 | + "employee_count": 50, |
| 146 | + "description": "Innovative software solutions company" |
| 147 | +} |
| 148 | +
|
| 149 | +### REMEMBER |
| 150 | +Return ONLY the JSON object with attribute values - no explanations, no markdown, no extra text.`, |
| 151 | + placeholder: 'Describe the record values you want to set...', |
| 152 | + generationType: 'json-object', |
| 153 | + }, |
| 154 | + }, |
| 155 | + { |
| 156 | + id: 'query', |
| 157 | + title: 'Search Query', |
| 158 | + type: 'short-input', |
| 159 | + placeholder: 'Search term (names, domains, emails, phone numbers)', |
| 160 | + condition: { field: 'operation', value: 'search_records' }, |
| 161 | + required: { field: 'operation', value: 'search_records' }, |
| 162 | + }, |
| 163 | + { |
| 164 | + id: 'objects', |
| 165 | + title: 'Object Types to Search', |
| 166 | + type: 'short-input', |
| 167 | + placeholder: 'Comma-separated object slugs (e.g., "people,companies") or leave empty for all', |
| 168 | + condition: { field: 'operation', value: 'search_records' }, |
| 169 | + }, |
| 170 | + { |
| 171 | + id: 'limit', |
| 172 | + title: 'Limit', |
| 173 | + type: 'short-input', |
| 174 | + placeholder: 'Max results (default: 25, max: 500 for list, 25 for search)', |
| 175 | + condition: { |
| 176 | + field: 'operation', |
| 177 | + value: ['list_records', 'search_records'], |
| 178 | + }, |
| 179 | + }, |
| 180 | + { |
| 181 | + id: 'offset', |
| 182 | + title: 'Offset', |
| 183 | + type: 'short-input', |
| 184 | + placeholder: 'Number of records to skip for pagination', |
| 185 | + condition: { field: 'operation', value: 'list_records' }, |
| 186 | + }, |
| 187 | + { |
| 188 | + id: 'attributes', |
| 189 | + title: 'Attributes to Return', |
| 190 | + type: 'short-input', |
| 191 | + placeholder: 'Comma-separated attribute slugs (e.g., "name,email_addresses")', |
| 192 | + condition: { field: 'operation', value: 'list_records' }, |
| 193 | + }, |
| 194 | + ], |
| 195 | + tools: { |
| 196 | + access: [ |
| 197 | + 'attio_list_records', |
| 198 | + 'attio_get_record', |
| 199 | + 'attio_create_record', |
| 200 | + 'attio_update_record', |
| 201 | + 'attio_search_records', |
| 202 | + ], |
| 203 | + config: { |
| 204 | + tool: (params) => { |
| 205 | + switch (params.operation) { |
| 206 | + case 'list_records': |
| 207 | + return 'attio_list_records' |
| 208 | + case 'get_record': |
| 209 | + return 'attio_get_record' |
| 210 | + case 'create_record': |
| 211 | + return 'attio_create_record' |
| 212 | + case 'update_record': |
| 213 | + return 'attio_update_record' |
| 214 | + case 'search_records': |
| 215 | + return 'attio_search_records' |
| 216 | + default: |
| 217 | + throw new Error(`Unknown operation: ${params.operation}`) |
| 218 | + } |
| 219 | + }, |
| 220 | + params: (params) => { |
| 221 | + const { oauthCredential, operation, attributes, objects, ...rest } = params |
| 222 | + |
| 223 | + const cleanParams: Record<string, any> = { |
| 224 | + oauthCredential, |
| 225 | + } |
| 226 | + |
| 227 | + if (attributes && operation === 'list_records') { |
| 228 | + const parsedAttributes = |
| 229 | + typeof attributes === 'string' |
| 230 | + ? attributes.split(',').map((a: string) => a.trim()) |
| 231 | + : attributes |
| 232 | + cleanParams.attributes = parsedAttributes |
| 233 | + } |
| 234 | + |
| 235 | + if (objects && operation === 'search_records') { |
| 236 | + const parsedObjects = |
| 237 | + typeof objects === 'string' ? objects.split(',').map((o: string) => o.trim()) : objects |
| 238 | + cleanParams.objects = parsedObjects |
| 239 | + } |
| 240 | + |
| 241 | + Object.entries(rest).forEach(([key, value]) => { |
| 242 | + if (value !== undefined && value !== null && value !== '') { |
| 243 | + if (key === 'limit' || key === 'offset') { |
| 244 | + cleanParams[key] = Number(value) |
| 245 | + } else { |
| 246 | + cleanParams[key] = value |
| 247 | + } |
| 248 | + } |
| 249 | + }) |
| 250 | + |
| 251 | + return cleanParams |
| 252 | + }, |
| 253 | + }, |
| 254 | + }, |
| 255 | + inputs: { |
| 256 | + operation: { type: 'string', description: 'Operation to perform' }, |
| 257 | + oauthCredential: { type: 'string', description: 'Attio access token' }, |
| 258 | + object: { type: 'string', description: 'Object type slug (e.g., people, companies)' }, |
| 259 | + recordId: { type: 'string', description: 'Record ID for get/update operations' }, |
| 260 | + values: { type: 'json', description: 'Record values to create/update (JSON object)' }, |
| 261 | + query: { type: 'string', description: 'Search query string' }, |
| 262 | + objects: { type: 'string', description: 'Comma-separated object types to search' }, |
| 263 | + limit: { type: 'number', description: 'Maximum results to return' }, |
| 264 | + offset: { type: 'number', description: 'Number of records to skip' }, |
| 265 | + attributes: { type: 'string', description: 'Comma-separated attribute slugs to return' }, |
| 266 | + }, |
| 267 | + outputs: { |
| 268 | + records: { type: 'json', description: 'Array of record objects' }, |
| 269 | + record: { type: 'json', description: 'Single record object' }, |
| 270 | + recordId: { type: 'string', description: 'Record ID' }, |
| 271 | + total: { type: 'number', description: 'Total number of matching results' }, |
| 272 | + paging: { type: 'json', description: 'Pagination info' }, |
| 273 | + metadata: { type: 'json', description: 'Operation metadata' }, |
| 274 | + success: { type: 'boolean', description: 'Operation success status' }, |
| 275 | + }, |
| 276 | +} |
0 commit comments