I’ve been having trouble creating a Field Agent that’s able to read the content of an attachment in another column. I can get Omni to read the data and perform the activity one row at a time (essentially review an attendance .csv file and spit out attendee organisations for meetings) but that’s very slow and one-at-a-time. Is this a current limitation of Field Agents or have I done something wrong framing my request? I just get a ‘data not available’ error in the field generated.
Hm, weird, I just tried to replicate this and couldn’t even get the AI field to recognize that an attachment even existed

I had this trouble as well.
So, I decided to solve it in other way

I posted whole story already here. But in short, after few formatting fixes I had a working code. TBH I could write it myself, but this way was faster and easier.

then I changed headers to make it more unified and extract plain text from any files
So I think it could be useful for your needs.

Text for copying. I understand it’s just a workaround, but I don’t worked so much with Agent to know how to fix it in order to process the whole column and not ignore insertions of new data in required field.
//galex,2025
let settings = input.config({ title: 'Text Extractor', items: [
input.config.table('table', { label: 'Select table', description: 'Table containing files' }),
input.config.view('view', { label: 'Select view', parentTable: 'table' }),
input.config.field('source', { label: 'Attachment field', parentTable: 'table' }),
input.config.field('dest', { label: 'Content destination field', parentTable: 'table' }) ] })
const {table, view, source, dest} = settings
// Get records with attachments
const query = await view.selectRecordsAsync({ fields: [source, dest] })
const records = query.records.filter(r=>r.getCellValue(source)&&!r.getCellValue(dest))
if (!records.length) throw new Error('No new files found to process')
output.markdown(`**Found ${records.length} files to process**`)
const go=await input.buttonsAsync('Continue?',
[{label:'Process',variant:'primary'},{label:'Cancel',variant:'danger'}])
if (go === 'Cancel') throw new Error('Operation cancelled')
const file=rec=>rec.getCellValue(source)?.[0]
const update=async rec=>await fetch(file(rec)?.url).then(r=>r.text()).
then(content=>({id:rec.id, fields:{[dest.name]:content}}))
const upd=await Promise.all(records.map(r=>update(r)))
const valid = upd.filter(Boolean)
while (valid.length) await table.updateRecordsAsync(valid.splice(0, 50))
output.markdown('> ✅ **Done!** All files processed successfully.')
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.
