Sections with written analysis
The agent organizes the document into sections and writes the text for each one: what it looked at, what it found and what it recommends. That is where its reasoning adds value — and it is the only part it drafts.
The Squad queries your systems, analyzes what it finds and publishes an analytical document: sections, tables fed straight from the API, charts drawn by the server and a PDF. Then it sends the report by email — only to people on the authorized list.
Part of the Hal-AI Agentic platform. The same agent that does the work is the one that reports on it.
Publishing a document is one of the agent's tools, like querying the ERP or sending a message. It decides the analysis is worth a report, assembles the piece and delivers it — with nobody opening an editor.
The agent organizes the document into sections and writes the text for each one: what it looked at, what it found and what it recommends. That is where its reasoning adds value — and it is the only part it drafts.
Tables and charts are never typed out. The agent declares which API call the data comes from, which list to use and how to join it with another source. The server reads the response and builds the block.
The same document comes out as HTML for reading on screen and as a PDF to attach to an email. The stylesheet belongs to the platform: the agent writes content, never appearance.
The agent chooses what to show. The server does the math and the drawing.
At the scheduled time, the Squad calls your systems' APIs and receives the data for the period.
With the subagent fan-out enabled, dozens of readings run in parallel — one per order, per patient, per contract — each answer validated against a declared schema.
It writes the sections and points every table and every chart at a call it already made in the same run.
The server assembles the document, generates the PDF and emails it to the authorized recipients. The run is logged with everything that was done.
Below is a representation of the document as it reaches the manager. The stylesheet is light and serifed on purpose — the deliverable does not look like the console, it looks like a report.
Appointment Confirmation · run #47
Report published by the Squad at the end of the 8:00 AM run, covering this week's appointments.
There were 412 appointments in the period. The routine reached out to the 318 with no confirmation on record and got an answer from 244 people the same day. The 29 contacts outside the 24-hour window are still pending and can only be approached with an approved template.
Figure 1 — share of each outcome across the 318 contacts reached in run #47.
| Location | Shift | Contacted | Confirmed | State |
|---|---|---|---|---|
| Victoria Clinic — Downtown | morning | 126 | 108 | fully booked |
| Victoria Clinic — North | afternoon | 94 | 71 | fully booked |
| Aurora Site | morning | 61 | 42 | 19 open slots |
| Route 12 Site | afternoon | 37 | 23 | outside the window |
| Total for the period | 318 | 244 |
The header names the routine and the run that produced the piece, and the mono line declares which API call each block in that document came from. Every row of the site table ends in a state seal — fully booked, 19 open slots, outside the window — and every number card says underneath it what happens next, like the retry set for 8:00 AM the following day.
The block that closes the document is the only one that does not report: it separates what the Squad already handled from what needs a person to decide.
The piece arrives with the cases already flagged and the open item named, so nobody has to open the system to find out where to look. Exporting the period's spreadsheet, cross-checking the lists and writing the summary stops being manual work — and it comes out overnight, before the operation opens.
Because the structure is the same on every run, today's document can be compared with last week's without anyone redoing the math to line the two readings up.
With the subagent fan-out enabled, every case in the table comes from a reading of its own: dozens of analyses run in parallel, one per order, per patient or per contract, each with dedicated reasoning and an answer checked against a schema declared before it can become a row.
A flow automation walks a tree and hands back the total for the set. Here the set is looked at case by case — and the subagents inherit read-only tools: writing, emailing or firing off a message does not exist in their world.
The same document comes back into the run's chat as a clickable attachment, with the file name, format and size — that is how the manager opens the piece without leaving the conversation with the orchestrator.
The published document bubble, as it appears in the Squad's run chat.
A table retyped by a language model is a plausible table. The difference here is architectural, not a matter of careful wording.
The agent declares the shape of the data — ranking, series, distribution — and the angle. Calculating the scale, positioning the bars and writing the legend is the server's job.
| Type | Data shape it shows |
|---|---|
| Horizontal bars | A ranking of items by one value — who leads and who trails. |
| Stacked columns | The makeup of each group, with the segments adding up inside the column. |
| Line series | One or more series over time, to spot trends and breaks. |
| Donut | Each part's share of the whole, when there are only a few parts. |
| Composition | Side-by-side proportions across groups, in absolute values or percentages. |
| Scatter by group | Where each case falls inside its group — clustering and outliers. |
| Matrix | Two dimensions crossed, with the intensity shown in each cell. |
| Waterfall | Where it started and where it ended: what added and what subtracted along the way. |
| Histogram | The distribution of values by range, to see the shape of the sample. |
The agent never picks a hex code. It picks a meaning — ok, warning, bad, missing, info, neutral — and the palette belongs to the server.
When nothing is declared, the chart comes out in a single color. That is deliberate: in a report where red means open this case first, seventeen bars in seventeen colors teach the reader to ignore color altogether. The exceptions are donut and composition charts, where color identifies the slice.
Before publishing, the server checks the piece. Two explicit rejections, instead of silent cleanup:
Failing to deliver is bad. Delivering a handsome axis with nothing behind it is worse, because it goes unnoticed.
An agent that sends email on its own needs a hard limit on who it can send to. At Hal-AI that limit is not a line of instructions: it is a registry.
The list of people who can receive a report is registered by the manager in the console. During a run the agent chooses from that list — it does not type in a new address, does not edit the list and does not improvise a forward. Every recipient is checked before the send.
The daily, weekly or month-end report goes out at the agreed time. The Squad wakes up, reads its own context and decides what that run calls for — including concluding that there is nothing new to report.
The manager attaches the report the team already builds by hand and asks for that same shape using API data. The Squad works out the structure once and keeps the template — declared sections, tables and charts. After that it only fills in the text for each gap.
Every run keeps a record of what was queried, what was decided and what was sent. There is a simulation mode to rehearse without sending anything and a stop button to halt it immediately.
On the console side, that same delivery shows up as configuration.
| Run | Document | Format | Recipients | Outcome |
|---|---|---|---|---|
| #47 · today 8:04 AM | Appointment Confirmation | 3 | Delivered | |
| #46 · yesterday 8:03 AM | Appointment Confirmation | 3 | Delivered | |
| #45 · Aug 21, 8:02 AM | — | — | 0 | No report · nothing new |
| #44 · Aug 20, 8:06 AM | Appointment Confirmation | 2 | 1 address off the list | |
| Total across the 4 sends | 8 | 3 + 3 + 0 + 2 |
On the left, the routine's tabs, with Schedule and delivery open. In the center, the frequency and the next run, the format the piece goes out in and the mode it runs in. Below that, the closed-list banner and the registered addresses: three active and one paused by the manager.
The history underneath is the record of each send — how many recipients were reached, the run that published nothing and the one with an address blocked — with the period total showing the parts that add up to it.
Delivery stops depending on someone remembering to run the report and forward the file. When the manager asks whether Tuesday's piece went out and to whom, the answer is on the same screen, with no digging through an inbox.
Taking someone off the list is a registry change, not a rewrite of the agent's instructions — and an address outside the list is blocked before dispatch, so a document holding your customer's data never goes out by mistake to someone who should not receive it.
A scheduled automation fires because the clock struck. Here, waking up is not an order to act.
It is the same difference on the inside: the agent decides what that particular run calls for, instead of walking a tree drawn up in advance.
Alongside the documents the agent publishes, the console ships three operational reports a supervisor can pull on the spot — filtered by queue and by channel, with the PDF generated on the server, email delivery and recurring schedules.
How much each person handled in the period, with the count of distinct conversations always shown next to the per-operator total.
The volume that went through human service, separated from what the agent resolved on its own.
Who talked to the company in the chosen window, broken down by queue and by channel.
When a conversation changes hands, counting by queue alone erases the work of whoever handled it first. The count uses the union of the queue with the card movement log — and the report shows both readings side by side, so the per-operator total is never mistaken for the total number of conversations.
An aggregate figure printed alongside its parts is a figure the supervisor can actually check.
The PDF also carries a plain-language reading of that period's numbers: what went up, what went down and where it is worth looking. The text comes from the AI; the table still comes from the query.
Not every question deserves a scheduled report. The manager opens the Copilot, asks in plain language and gets the answer already formatted — text, table and chart right on the screen.
The Copilot answers the manager with the chart on screen and the PDF ready to forward.
The Squad publishes the full document and delivers it to the authorized list, with nobody asking.
The memory and the tools are the same on both sides. What changes is who pulls the trigger.
AI reporting usually fails in a way that is hard to notice: the document reads well, the axis is there, and the data is approximate. Here the data takes a different path.
Table and chart read the same API response, resolved in the same place. There is no table version and chart version.
Scale, sums, percentages and the position of every element are computed outside the model. What it would get wrong is no longer its job.
A document with no content does not go out. A recipient outside the list does not receive it. Every run is logged with what was done and what was not.
This difference is easier to see in the deliverable than to explain. Below, the weekly route close for a carrier: the same API call feeds the chart and the table on the following page.
Route Close · run #31
Report published by the Squad at the end of the Saturday run, covering the week's four reference routes.
There were 1,453 deliveries across Meridiano Transport's four reference routes. 1,325 arrived inside the window agreed with the customer and 128 ran late — 47 on Route 41 and 41 on Route 58, which together account for 88 of the 128 occurrences.
Wednesday holds the peak: 31 of the 128 occurrences fall on a single day, against 11 on Saturday, when local volume is lower.
Figure 1 — late occurrences by business day: 14 + 19 + 31 + 26 + 27 + 11 add up to the 128 in the period.
| Route | Shift | Deliveries | Late | Status |
|---|---|---|---|---|
| Route 12 — Downtown | morning | 486 | 22 | on target |
| Route 27 — Coastal | afternoon | 402 | 18 | on target |
| Route 41 — Highlands | morning | 351 | 47 | delays concentrated |
| Route 58 — Inland | night | 214 | 41 | off target |
| Period total | 1,453 | 128 |
Table 1 — the same api_get_deliveries call that fed Figure 1, grouped by route.
This is the document as it reaches the manager: light page, numbered sections, and a metadata line declaring the period, the run and the API call that fed the piece. The chart in Figure 1 and the table in section 03 read the same api_get_deliveries response — one grouped by day, the other by route.
No number in the text is left without its parts: the 1,453 deliveries appear as 486 + 402 + 351 + 214, and the six bars in the chart add up to exactly the 128 occurrences in the table column.
Because the sum, the scale and the height of every bar are computed outside the model, checking the piece means looking at two figures on screen — not rerunning the query in the system. If the chart and the table disagreed, it would be because the data changed at the source, never because the text was retyped.
And what the piece asks of the manager comes separated from what it reports: Route 41 is named at the end of the document as a human decision, not buried in the middle of the analysis.
A report exists so you can decide. Deciding on approximate numbers is worse than having no report at all.
No. In reference blocks, the agent declares which API call the data comes from, which list to use and how to join it with another source. The server reads that response, builds the table and draws the chart. The model writes the analysis and chooses the angle; the arithmetic and the drawing are not its job.
Only people on the authorized recipient list, registered by the manager in the console. The agent does not type in a new address or edit the list during a run, and every recipient is checked before delivery. A published report with no valid recipient does not go out.
Yes. The manager attaches the existing document in the Squad chat and asks for that same shape using API data. The Squad works out the structure once and keeps a template: the sections, the tables and the charts already declared. On later runs it fills in the text for each gap and the server rebuilds the document, so the monthly series stays comparable.
We will show you how the agent queries your systems, publishes the document and delivers it on schedule — with every number coming from the source.