Skip to content

Operations

The AIMO Agent runs inside your environment and holds credentials to your databases. AIMO delivers work as jobs.

Strict job types—not arbitrary code

The agent is not a general runtime for scripts or user programs. It accepts only a fixed, enumerated set of job types—a closed allowlist. Each type maps to known behavior in the agent (connection tests, schema analysis, profiling, monitor calculation, validation).

  1. Transparency — You know in advance what categories of work can be requested (no hidden “run anything” channel).
  2. No unconstrained code on the agent — AIMO does not execute arbitrary smuggled logic in your perimeter. Monitor SQL is generated from typed definitions and validated; see Monitors.

Payloads that do not deserialize as a supported job model are rejected. Training, monitor generation, and outlier modeling run on AIMO workers, not as mystery payloads on the agent.

The sections below are agent job types (roughly JobType in code). Orchestration that runs only in AIMO’s cloud is not listed here.

Examples use illustrative table/column names. Dialect note: SQL is compiled for your engine (SQLAlchemy). Regex in PatternMonitor is PostgreSQL-style (!~) in the current implementation; other databases may differ.


ANALYZE_TABLE — Analyze table

Purpose — Deep inspection of one table: structure, statistics, and samples within limits, packaged for downstream use (including monitor generation on AIMO).

Behavior — Connects with stored credentials, reflects the table, gathers profile and sample data, returns an analysis payload AIMO uses to propose monitors.

When — Onboarding or refresh before generating or updating monitors.

Example SQL

  • Schema and constraints — Implemented with the SQLAlchemy inspector: dialect-specific metadata queries (for example against information_schema or catalog tables) to load columns, indexes, primary key, unique constraints, and foreign keys. There is no single fixed SELECT for this step.

  • Profiling sample (when enabled) — One bounded read of row data:

sql
SELECT orders.id, orders.created_at, …
FROM orders
LIMIT 1000;

The limit comes from the job’s sample_limit (default 1000 in code if not overridden). All columns are selected; profiles are computed in the agent from this dataframe (not sent as raw rows to AIMO).


TEST_CONNECTION — Test database connection

Purpose — Verify credentials and reachability.

Behavior — Short-lived connection; success or failure with a useful error message.

When — After saving or rotating connections, or from product health checks.

Example SQL

sql
SELECT 1;

CALCULATE_MONITORING — Calculate monitors

PurposeProduction monitoring: compute monitor results for time blocks, using time-block expressions, optional dimensions, and active monitor definitions.

Behavior — Builds the grouped aggregate queries implied by your monitors (same shape as validation, without validation-only row limits on the inner source). Returns results for AIMO to store, compare, and alert on.

Why it matters — This is where strict monitor types become bounded SQL on your database.

Example SQL — outer shape

All active monitors for a table are combined into one statement. The inner source is always a subquery over the monitored table (production: no LIMIT on the inner SELECT).

Inner source:

sql
FROM (
  SELECT *
  FROM schema.orders
) AS anon_1

Optional grouping — If a time-block expression is configured, it appears in SELECT and GROUP BY as time_block_start. Dimension columns are grouped and exposed as dim_<column_name>.

Production time windows — When a time-block expression is set, the agent runs the grouped query once per requested block, adding:

sql
WHERE <time_block_expression> = :that_block_start

No time block and no dimensions — No GROUP BY; one row of aggregates over the whole inner source, for example:

sql
SELECT count(*) AS rowcountmonitor_3
FROM (SELECT orders.id FROM orders) AS anon_1;

With time block and one dimension (example; WHERE value changes per scheduled block):

sql
SELECT date_trunc('day', created_at::timestamp) AS time_block_start,
       anon_1.status AS dim_status,
       count(*) - count(anon_1.id) AS nullmonitor_7,
       count(*) AS rowcountmonitor_3
FROM (SELECT orders.id, orders.created_at, orders.status FROM orders) AS anon_1
WHERE date_trunc('day', created_at::timestamp) = '2024-01-15 00:00:00+00:00'
GROUP BY date_trunc('day', created_at::timestamp), anon_1.status;

Monitor column aliases are {monitor_type}_{monitor_id} normalized to lowercase with non-alphanumeric characters replaced by _.

Example SQL — monitor aggregate fragments (monitor_type)

Each monitor adds one aggregate column. Possible shapes:

monitor_typeAggregate expression (conceptual; c = inner column)
NullMonitorcount(*) - count(c)
RowCountMonitorcount(*)
UniqueMonitorcount(c) - count(DISTINCT c)
RangeMonitorsum(CASE WHEN (out of range) THEN 1 ELSE 0 END) or literal 0 if no bounds; string columns with numeric bounds use CAST(c AS FLOAT)
CategoricalSetMonitorsum(CASE WHEN (c NOT IN (...)) THEN 1 ELSE 0 END)
PatternMonitorsum(CASE WHEN (CAST(c AS VARCHAR) !~ 'pattern') THEN 1 ELSE 0 END) (PostgreSQL-style in current code)
SQLQueryMonitor( <your single aggregate SQL> )

ANALYZE_CONNECTION_SCHEMA — Analyze database schema

PurposeSchema-level inventory: tables, columns, and related metadata for browsing and setup in the UI.

Behavior — Dialect-appropriate discovery; results feed connection and table navigation.

When — New connection or after large migrations.

Example SQL

  • Table list — Via the SQLAlchemy inspector (dialect-specific queries to enumerate schemas/tables).

  • Per table — Same inspector-based metadata as in ANALYZE_TABLE (columns, indexes, constraints). Profiling is off for this job: there is no SELECT * … LIMIT n over table data—only metadata and empty profile shells.


VALIDATE_TABLE_CHARACTERISTICS — Validate table characteristics

PurposeSafety gate for the proposed time-block expression and dimension columns before monitor SQL is validated: prove the expression is well-defined over the whole table and summarize its range.

Behavior — Reflects the table, checks that dimension columns exist, and runs full-table aggregates: MIN, MAX, and COUNT(DISTINCT) of the time-block expression (no sampling-only path). Empty tables fail validation where data is required.

When — During the table-characteristics step in the generate-monitors pipeline, before AI monitor definitions are written and validated.

Example SQL

Over the full table, the time-block expression is evaluated in a subquery, then aggregated:

sql
SELECT min(anon_1.tb) AS min_1,
       max(anon_1.tb) AS max_1,
       count(DISTINCT anon_1.tb) AS count_1
FROM (
  SELECT (date_trunc('day', created_at::timestamp)) AS tb
  FROM orders
) AS anon_1;

Replace the inner expression with your configured time_block_expression. Dimension columns are validated to exist on the table; this statement does not group by dimensions—it only characterizes the time-block expression’s range and cardinality.


VALIDATE_MONITOR_ARTIFACTS — Validate monitor artifacts

PurposeSafety gate for AIMO-generated monitor configuration: prove time blocks, dimensions, and compiled SQL against your real table before production use.

Behavior — Builds the same grouped monitor query context as production (time-block expression and dimensions with GROUP BY). Runs validation queries with a minimal read path (cheap limits on the inner source). SQLQueryMonitor fragments run in this real context. Failures return per-monitor errors. Empty tables may block validation where a row is required.

Relationship to AIMO — After monitors are generated in AIMO, this job proves them on your database: assign → constrain → validate.

Example SQL

  1. Non-empty table check (when execution is required):
sql
SELECT 1
FROM orders
LIMIT 1;
  1. Time-block and dimension shape (no monitor columns)—proves GROUP BY / WHERE compile and execute; inner source uses LIMIT 1; validation uses a fixed example timestamp for WHERE on time_block_start (2020-01-02 12:00:00+00:00 UTC):
sql
SELECT date_trunc('day', created_at::timestamp) AS time_block_start,
       anon_1.status AS dim_status
FROM (
  SELECT orders.id, orders.created_at, orders.status
  FROM orders
  LIMIT 1
) AS anon_1
WHERE date_trunc('day', created_at::timestamp) = '2020-01-02 12:00:00+00:00'
GROUP BY date_trunc('day', created_at::timestamp), anon_1.status;
  1. Per-monitor validation — Same grouped shell as CALCULATE_MONITORING, but the inner source is (SELECT … FROM table LIMIT 1) AS anon_1, the same fixed WHERE on the time block when applicable, and one monitor’s aggregate columns appended. The monitor aggregate fragments match the monitor_type table in the CALCULATE_MONITORING section above.

What runs in the cloud

Examples: monitor generation, model training, quantile inference, outlier detection on historical series. Those steps consume artifacts the agent already produced (analysis, calculated monitor batches, schema snapshots). This page lists only work that hits your database on the agent.

Relation to monitors

  • Strict monitor types — The only flexible text path is SQLQueryMonitor, still a single aggregate in a fixed outer query.
  • VALIDATE_TABLE_CHARACTERISTICS — Confirms the time-block expression and dimensions are valid over the full table (including aggregate range checks) before monitor SQL is validated.
  • CALCULATE_MONITORING — Turns definitions into repeatable, bounded SQL.
  • VALIDATE_MONITOR_ARTIFACTS — Confirms monitor definitions execute in the same grouped shape as production before you rely on them.

See Monitors for the monitor catalog and how AIMO assigns and validates definitions.