Docs / Documents and data
Documents and data
Besides code and incidents, ivralo's office side reads and produces documents and data: Word files, decks, workbooks, PDFs and charts, SQL over files and over your own databases, and OCR for scans.
How it works
The work is done by specialists that write Python in the worker and call ivralo.engine, the document and data library the skills teach. You ask in your own words, and the file lands in the workspace.
turn errors.csv into a workbook with a summary sheet and a chart of errors per service
| Output | Specialist | Engine calls |
|---|---|---|
| Word document | Document and Deck Writer | build_doc, read_docx, docx_replace, mail_merge |
| PowerPoint deck | Document and Deck Writer | build_deck, read_pptx, docx_to_deck, pptx_replace |
| Excel workbook | Data Analyst, Spreadsheet Builder | build_workbook, read_workbook, audit_workbook, compare_tables |
| PDF report | Report Writer | build_pdf, build_report, kpi_row, pdf_table |
| an existing PDF | PDF Operator | read_pdf, and the pdf-manipulate and pdf-forms scripts |
| chart | Chart Designer | matplotlib, seaborn or plotly, with chart_theme; chart_image to place one in a document |
The skills that teach each one are on Shipped skills.
SQL over files
query_files runs DuckDB over files in the workspace, named in the query:
select service, count(*) from 'errors.csv' group by 1 order by 2 desc
It reads CSV, TSV, Parquet and JSON directly, and loads .xlsx through pandas. Names are relative to the workspace; a path that climbs out of it is refused.
Your own databases, read-only
IVRALO_SQL_URL takes a SQLAlchemy URL, such as postgresql+psycopg://reader:...@db.internal/app. That connection is named default. To name more, list them in databases.json in the home, or in .ivralo/databases.json in a trusted repository. Each entry names the environment variable that holds the URL, never the URL itself:
{
"app": { "description": "production replica, orders and users", "env": "APP_DATABASE_URL" }
}
The agent calls list_databases, list_tables, describe_table and query_database. The URL never reaches the model's code: the query runs in ivralo's own process.
Every query is read-only twice over. The statement is checked before it leaves: one statement, a read first, no write or schema keyword. And the connection itself is read-only at the database: a read-only transaction on PostgreSQL and MySQL, query_only on SQLite, and a rollback at the end everywhere. On other dialects, SQL Server among them, the check and the rollback are all there is, and ivralo doctor says so. Give each connection a database user that can only read anyway.
| Variable | Default | Sets |
|---|---|---|
IVRALO_SQL_URL | unset | the database named default |
IVRALO_DATABASES | databases.json in the home | where the home's named connections are |
IVRALO_SQL_ROW_CAP | 200 | rows a query may return |
IVRALO_SQL_TIMEOUT | 20 | seconds per statement |
MySQL and SQL Server need the mysql or mssql extra.
Scans and images: OCR
document_to_markdown reads a scanned PDF or an image through OCR, and the knowledge index does the same for a PDF with no text layer. OCR runs through the docling command, installed as a separate tool rather than a dependency, because docling cannot share ivralo's environment:
uv tool install docling
Turkish and English are read by default. IVRALO_OCR_LANGS=tr,en sets the languages, and IVRALO_DOCLING points at the executable when it is not on the PATH. Without docling, the call says how to install it.
House colours
Every document, deck, workbook and chart takes its colours from brand.json in the home:
{
"appName": "ivralo",
"primary": "#0E9384",
"secondary": "#115E59",
"accent": "#2DD4BF",
"text": "#1F2937",
"bg": "#F0FDFA",
"grid": "#D9E7E4",
"zebra": "#F6FCFB",
"logo": null
}
That file is the one source. A request for other colours gets a palette for that document; the file is never edited for it. IVRALO_BRAND_FILE points at another file, and IVRALO_FONT at a TrueType font for PDFs.
Research tools
| Tool | What it does | Setting |
|---|---|---|
search_web, read_url, save_url | the public web without an API key; every claim cites the URL and date | IVRALO_WEB (on by default) |
| a self-hosted SearXNG | one more search leg | IVRALO_SEARXNG_URL |
search_photos, save_photo | a stock photo from Unsplash, saved with its credit line | IVRALO_UNSPLASH_ACCESS_KEY |
Only the query leaves the machine: one line, at most 200 characters, so a document cannot be pasted into a search box. Every hop of a fetch is judged by the egress policy, and loopback and private addresses are refused. See What leaves the machine.