Documentation
What the AI Analysis page computes
Why the page named AI Analysis calls no model, the deterministic arithmetic behind its brief, and what the exported context leaves out.
Last reviewed against the product on .
AI Analysis builds a structured brief about your organization that you can paste into whatever assistant you already use. The page is named for what the brief is for. Nothing on it is produced by a model.
No model runs here
There is no AI provider connected to this site, no inference call in this page or anything it imports, and no machine-learning library among its dependencies. Every figure in the brief is arithmetic over rows already in the database, run in the same process that renders the page.
- AI providers connected
- None
- no model, no inference endpoint, no provider key
- AI or machine-learning dependencies
- None
- the package manifest lists none
- Outbound calls the page makes
- None
- two database reads, then arithmetic; nothing leaves the server
Measured from app/app/ai-analysis/page.tsx, src/lib/analytics/queries.ts and the dependencies block in package.json.
This matters because the word in the route name usually promises something else. A rule that a person could follow with a calculator is not a model, and calling it one would invite you to trust it in ways the arithmetic does not support. The brief says the same thing about itself: the JSON carries a methodology line stating that the calculations are deterministic, that currencies stay separate, and that no AI API was called.
Every calculation behind the brief
| Figure | How it is calculated | Model involved |
|---|---|---|
| Change percent | Current value minus prior value, divided by prior, times one hundred | None |
| Confidence | A fixed weighted sum of coverage, freshness against the source's own cadence, the stored provider confidence, and match quality | None |
| Priority | A fixed weighted sum of movement severity, your spend weight for that item, and confidence | None |
| Purchasing totals | Row totals added up per currency and rounded to two decimal places | None |
Measured from percentageChange, confidenceScore and priorityScore in src/lib/analytics/engine.ts, and the totals reducer in app/app/ai-analysis/page.tsx.
The weights are constants in the source. They were not learned from anything, they do not adapt to your data, and they are the same for every organization on the site. Reading the analytics page sets out each weight and what it measures, because these are the same calculations that page shows its working for.
One consequence worth stating plainly: the page is deterministic. Run it twice on unchanged data and the only field that differs is the generation timestamp.
What the page reads first
| Read | Cap | What it feeds |
|---|---|---|
| Market observations | 2,000 | Your organization's own country only, newest first, before comparison groups are formed |
| Purchase rows for weighting | 10,000 | The spend weight and impact carried inside each signal |
| Purchase rows for the totals | No cap | The purchasing totals printed in the brief |
Measured from getMarketAnalytics in src/lib/analytics/queries.ts and the purchase query in app/app/ai-analysis/page.tsx.
The two purchase reads are not the same read, and on a long history they will not agree. The totals in the brief count every accepted row you have; the weighting inside the signals sees the most recent rows up to its cap. Treat the totals as the complete figure and the weighting as a recent-history approximation of it.
The observation read is your country's, always. This page has no scope switch, so a movement published only for another country cannot appear in the brief even when it drives your costs.
What the brief contains
- Signals in the JSON
- 20
- highest priority first; anything below the cut is not in the file at all
- Signals shown as prose
- 5
- the same ordering, as a readable summary above the JSON
- Explanation lines per signal
- 3
- current against prior, the change with its confidence and priority, then either the absolute movement or an estimated spend impact
Measured from the context object in app/app/ai-analysis/page.tsx and buildInsight in src/lib/analytics/engine.ts.
Each signal carries the item name, the data level it was published at, the change, confidence, priority, the explanation lines, and the source URL the observation came from. The purchasing section carries your row count and your totals, one per currency.
Currencies are never added together. A row whose file carried no currency is counted under an explicit unspecified label rather than folded into another currency's total, so a bucket under that name in your brief means rows arrived without a currency column, not that they are worthless.
What the page will not do
It sends nothing anywhere. The JSON sits in a collapsed panel for you to copy. The page does not transmit it, does not store the generated brief, and has no assistant on the other end of it.
It does not interpret. The explanation lines restate the arithmetic in words; nothing in them recommends an action, predicts a further movement, or says a supplier is charging too much. Two observations describe a step, not a trend.
It does not detect anything about your own invoices. The signals are public market observations, and they reach your spend only through the exact-name match described in market data against your own costs, which fails in both directions more often than it looks like it should.