Operations

PDF forms

Give an AI Employee a form and have the completed original come back — not a retyped summary of it. Genosyn handles both kinds of PDF: the ones built with real interactive fields, and the far more common ones that were laid out for a printer and have none.

Two kinds of form

A PDF that was exported from a form builder carries an AcroForm: named fields a program can set. A PDF that was printed, scanned, or exported from a word processor carries none — the boxes and ruled lines on it are just ink. The two need different tools, and the first thing an employee does is find out which it is holding.

  • read_pdf_fields lists the interactive fields, with each one's name, type, current value, and — for dropdowns and radio groups — the options it accepts.
  • fill_pdf_form sets those fields and returns the filled document. By default it flattens the result so the values are baked in; pass flatten: false to leave it editable.

If read_pdf_fields comes back empty, the document is the second kind, and the pair below takes over.

Forms with no fields

These are completed by drawing on top of the original. The source pages stay exactly as they are and become the background, so what the counterparty receives is their own form with answers on it.

  • read_pdf_layout reports each page's displayed size and rotation, plus every run of printed text and where it sits. That is how the employee finds Full name: and the blank after it instead of guessing at coordinates.
  • overlay_pdf_text draws text and tick marks at those coordinates and returns the completed document.

Coordinates

Every coordinate in both tools is measured in points from the top-left corner of the page as it appears on screen — the way a person reads a page, not the way PDF stores one. A page's /Rotate is already applied, so a landscape scan reports the width and height you actually see and needs no adjustment.

Positions round-trip exactly. A run's y handed back as anchor: "top", or its baselineY handed back as anchor: "baseline", lands on the line it was read from. Reusing the nearby label's fontSize keeps the answer the same size as the form.

// 1. find the label
read_pdf_layout({ attachmentId })
// → pages[0].texts includes
//   { text: "Full name:", x: 72, y: 86.2, width: 55, baselineY: 92, fontSize: 12 }

// 2. write in the gap after it, on the same line
overlay_pdf_text({
  attachmentId,
  items: [
    { page: 1, x: 200, y: 92, anchor: "baseline", size: 12, text: "Ada Lovelace" },
    { page: 1, x: 96, y: 300, type: "check", size: 10 },
  ],
})
// → { attachment: { id, filename: "supplier-form-completed.pdf" }, warnings: [] }

What you can draw

  • Text, at a point size and colour, optionally wrapped into a column with maxWidth and aligned left, centre, or right. Newlines start a new line, so a postal address goes on in one item.
  • Tick markscheck and cross — stroked as geometry rather than set as a character, so they land square inside a printed box.

Text is drawn in Noto, with Arabic and Chinese faces embedded only when the text needs them, so a form answered in more than one script comes out right without anyone choosing a font.

Getting the file in and out

All four tools take an attachmentId. That can be a file a teammate uploaded into chat, one opened off an email with read_mail_attachment, or one pulled from the web with download_web_file — which is how an employee fetches the current blank version of a form it has been asked to complete.

The completed document comes back as a new attachment. Its id goes straight onto a reply through Email, or to a teammate with send_chat_attachment. The original is never modified.

A form that needs a signature rather than answers belongs in Document signing, which collects real recipient evidence instead of drawing a name onto a page.