← All ivy-agents
IVYXSTUDIO · IVY AGENT
R

Report Mailer

ivy.agent.report-mailer · v1.1.1

ivyx

Reads a sales sheet, sums the amounts per month, draws the chart and mails the monthly table with the chart attached, with no model involved.

Steps

In the order the agent's file lists them, each with where its inputs come from and the values the file fixes. A branch or a loop is a step too.

  1. 01
    Read the sheet
    ivy.node.excel-read

    Reads one sheet of an Excel workbook into rows with the column names, row count and the workbook's sheet names.

    takes
    path from the agent's input
    sheet from the agent's input
    Ivy Node
  2. 02
    Clean the numbers and dates
    ivy.node.table-clean

    Cleans rows for analysis: trims text, drops empty rows, turns number columns into numbers and date columns into ISO dates.

    takes
    rows from step 1
    set
    number_columns ["amount"]
    date_columns ["date"]
    Ivy Node
  3. 03
    Sum per month
    ivy.node.table-aggregate

    Groups rows and sums, averages, counts or takes the minimum or maximum of one column, optionally by month, year or day of a date column.

    takes
    rows from step 2
    set
    group_by ["date"]
    value amount
    op sum
    period month
    returns
    groups
    Ivy Node
  4. 04
    Draw the chart
    ivy.node.chart-image

    Draws a bar or line chart of two columns of rows and writes it as a PNG file.

    takes
    rows from step 3
    set
    path reports/sales.png
    x date
    y amount
    kind bar
    title Monthly sales
    width 800
    height 400
    returns
    chart
    Ivy Node
  5. 05
    Lay out the table
    ivy.node.markdown-table

    Formats rows as a Markdown table, with the columns in the order given or as they first appear.

    takes
    rows from step 3
    returns
    table
    Ivy Node
  6. 06
    Write the body
    ivy.node.template-render

    Fills {{ name }} placeholders in a text template from a mapping, and reports which names were missing.

    takes
    values.file from the agent's input, path
    values.table from step 5, markdown
    set
    template Monthly sales from {{ file }}: {{ table }} The chart is attached.
    on_missing empty
    Ivy Node
  7. 07
    Attach the chart
    ivy.node.email-builder

    Builds an email message with a plain-text body and an optional attachment, given as bytes or as a file path, and returns it with its attachment count.

    takes
    from_email from the agent's input, username
    to_email from the agent's input, to
    body from step 6, text
    file_path from step 4, path
    set
    subject Sales report
    returns
    attachments
    Ivy Node
  8. 08
    Send the report
    ivy.node.email-provider

    Sends an email message through an SMTP server and returns the recipients it went to.

    takes
    email_message from step 7
    admin from the agent's input, username
    smtp_server from the agent's input, smtp_host
    smtp_port from the agent's input
    use_tls from the agent's input, smtp_tls
    set
    smtp_server smtp.gmail.com
    smtp_port 587
    use_tls true
    secret
    password the stored secret mail-password
    returns
    sent, recipients
    Ivy Node

What it touches

Collected from what each of its nodes declares, plus the model call when a step is a model turn. A declaration is the author's statement, and it is what policy rules select on.

Writes filesmessage-sendNetwork

What it needs

  • A stored secret named mail-password. The agent's file carries the name, never the value.

Inputs

FieldTypeDescription
pathrequiredstringPath to the .xlsx file.
sheetstringThe sheet to read; the first one when left out.
usernamerequiredstringThe mailbox address, which is the login name; its password is the stored secret mail-password.
torequiredstringWho receives the report.
smtp_hoststringThe SMTP server; smtp.gmail.com when left out.
smtp_portintegerThe SMTP port; 587 when left out.
smtp_tlsbooleanUpgrade SMTP with STARTTLS; on when left out.

Outputs

FieldTypeDescription
sentbooleanTrue once the server accepted the report.
recipientsarrayWho received it.
attachmentsintegerHow many files were attached.
groupsintegerHow many months the sheet covers.
chartstringThe chart that was written and attached.
tablestringThe monthly table that was mailed.

Tests

2 of 2 test cases passed on Oct 7, 2026, in the publisher's own environment, before this version was published. The registry keeps that record; it does not run the cases again.

Requires: python:3.9, an SMTP server (Gmail unless smtp_host says otherwise) with the sending account's password stored as the secret mail-password, for the cases, GreenMail on 127.0.0.1:3025 (mkdata-mail.py)

  • q3-workbook

    The Q3 export: three months, the chart attached, the mail accepted.

    given
    smtp_host 127.0.0.1
    smtp_port 3025
    smtp_tls false
    path data/sales.xlsx
    sheet Sales
    username agent@ivyx.test
    to agent@ivyx.test
    expects
    sent equals true
    attachments equals 1
    groups equals 3
    recipients matches @
    chart matches sales\.png$
    table matches 2026-07[\s\S]*2026-08[\s\S]*2026-09
  • q4-workbook

    Another workbook gives other months; its first sheet is a note, so the sheet is named.

    given
    smtp_host 127.0.0.1
    smtp_port 3025
    smtp_tls false
    path data/q4/q4-export.xlsx
    sheet Sales
    username agent@ivyx.test
    to agent@ivyx.test
    expects
    sent equals true
    attachments equals 1
    table matches 2026-10[\s\S]*2026-12