Add Nori tabular regression plugin#115
Conversation
879c68a to
956cd9c
Compare
4360cbd to
2756726
Compare
| The Nori gateway API key is a secret and is **never** read from trigger arguments or the request | ||
| body (both are logged). It is resolved, in order: | ||
|
|
||
| 1. an incoming request header: `X-Nori-Api-Key: <key>`, or `Authorization: Api-Key <key>` (HTTP |
There was a problem hiding this comment.
Influx uses the Authorization header to authorize incoming requests, so it is not possible to use it for passing other access tokens. Therefore, it is appropriate to remove any references to it—and the associated logic—from the plugin
| | `measurement` | (required) | Source measurement (table) to read from. | | ||
| | `field` | (required) | The numeric field to predict (the regression target). **forecast**: the series to forecast. **regress**: the column to predict from `feature_fields`. | | ||
| | `mode` | `forecast` | `forecast` predicts future timestamps of `field`; `regress` predicts `field` from `feature_fields` on the same rows and fills rows where `field` is null. | | ||
| | `feature_fields` | (none) | **regress only (required there)**: numeric feature columns (X) used to predict `field`, separated by `.` or `,`. Ignored in forecast mode. | |
There was a problem hiding this comment.
Since Influx allows field names to contain a dot ("."), this argument format will be parsed incorrectly. There is also a parsing limitation regarding the --trigger-arguments parameter when using the CLI: it does not allow commas (",") within argument values, as doing so leads to incorrect parsing of the trigger arguments. A space is the preferred delimiter
| | `step` | `1h` | **forecast**: spacing between forecast points. Units: `s,min,h,d,w`. | | ||
| | `lags` | `24.168` | **forecast**: lag steps (in units of `step`) used as features, separated by `.` or `,`. `--trigger-arguments` splits pairs on `,`, so use `.` there (e.g. `24.168`); commas are fine in the HTTP JSON body. Use lags `>= horizon` for a clean multi-step forecast. | | ||
| | `rolling` | `24` | **forecast**: rolling-window size (in points) for mean/std features. `0` disables. | | ||
| | `tags` | (none) | Filter to a single series. Format: `key:val.key2:val2`. In regress mode this is required if the measurement holds more than one series (see [Regress notes](#regress-mode-notes)). | |
There was a problem hiding this comment.
Same remark as for the feature_fields arg
| | `target_database` | (trigger db) | Write predictions to a different database. | | ||
| | `dry_run` | `false` | If `true`, log predictions but do not write them. | | ||
| | `min_history` | `50` | Minimum labeled/context rows required; skip below this. | | ||
| | `config_file_path` | (none) | TOML file (under `PLUGIN_DIR`) whose values override arguments. | |
There was a problem hiding this comment.
The documentation describes this parameter and the option to use a TOML configuration, but the plugin code lacks this logic
| lagged_times, method="ffill", tolerance=step | ||
| ).to_numpy() | ||
| if cfg["rolling"] > 0 and len(series) >= cfg["rolling"]: | ||
| roll_mean = series.rolling(cfg["rolling"]).mean() |
There was a problem hiding this comment.
eries.rolling(N).mean()/.std() includes the current point, so the roll_mean/roll_std for row t already contain y[t] — the value
we're trying to predict. This leaks the label into training (and contradicts the docstring)
2756726 to
c6578d2
Compare
0ed09f1 to
58684c5
Compare
Add a scheduled and HTTP Processing Engine plugin that predicts a numeric field in an InfluxDB 3 measurement from other columns with Synthefy's Nori in-context tabular regression model, via the Baseten gateway. It trains on the rows where the target field is present and predicts (imputes) the rows where it is null, writing the predictions back with write_sync. The Nori API key is read only from a request header or the NORI_API_KEY env var, never from trigger arguments or the request body. The model slug is configurable (synthefy/nori, synthefy/nori-30m). Ships with README, manifest.toml, requirements.txt, and a plugin_library.json entry.
58684c5 to
868438e
Compare
|
@Aliaksei-Kharlap thanks for the review, and for the detailed comments. One larger change first: we have refocused this plugin to be regression-only and renamed it ( How each comment is addressed:
CI is green. This is ready for another review, thank you. |
Summary
nori_regressionis a new Processing Engine plugin that predicts a numeric field in an InfluxDB 3 measurement from other columns on the same rows with Nori, Synthefy's in-context-learning tabular regression model, served through the Baseten gateway. It trains on the rows where the target field is present and predicts (imputes) the rows where it is null, writing the predicted values back as a new measurement. It runs as a scheduled trigger (on an interval) or an HTTP trigger (on-demand).What Nori is (for reviewers not familiar with it)
Nori is a tabular regression foundation model. You send it labeled feature rows (
X_train,y_train) and query rows (X_test) in a single request, and it predicts a value for each query row in one forward pass, with no training or fine-tuning. It has no notion of time or row ordering: it only sees numeric feature rows.How the plugin works
fieldplus thefeature_fieldscolumns, filtered bytags.X_train/y_train/X_testto Nori (task: "regression").<measurement>_regressed.Typical uses: backfill a field that dropped out, impute a metric from correlated ones (for example, predict
pressurefromtempandhumidity), or derive an expensive-to-measure field from cheaper ones recorded alongside it.Trigger types
process_scheduled_call): run on an interval; re-imputes any rows still missing the target each tick.process_request): on-demand at/api/v3/engine/<path>; supports an explicitstart_time/end_timewindow.Configuration highlights
measurement,field: the source table and the target field to predict (required).feature_fields: the feature columns (X),./,-separated (required).window, orstart_time+end_time: which rows to read.tags: filter to a single series (required if the measurement holds several series).model: the Nori gateway slug (synthefy/noridefault, orsynthefy/nori-30m).output_measurement,target_database,dry_run,min_history,config_file_path.Full parameter tables are in the README.
Authentication
The Nori gateway key is a secret and is never read from trigger arguments or the request body (both are logged). It is resolved from, in order: an incoming request header (
X-Nori-Api-Key, orAuthorization: Api-Keyon the HTTP trigger), then theNORI_API_KEYenvironment variable on the InfluxDB host. Keys are obtained from the Synthefy console (https://console.synthefy.com/); a single key works for all Nori model variants.One InfluxDB-specific note for the HTTP trigger: InfluxDB's own HTTP layer parses the
Authorizationheader and only accepts the Bearer/Token/Basic schemes, soAuthorization: Api-Keyis rejected before the plugin runs. Use the customX-Nori-Api-Keyheader instead. This is documented in the README.Testing
Verified end-to-end against
influxdb:3-corev3.10.1 with a production key:sensorstable wherepressure = 1000 + 0.5*temp - 0.3*humidity + noise(sd 0.8), the plugin imputed the 24 rows missingpressurefromtempandhumidity. Predictions matched the true relationship to within the training noise (absolute errors 0.02 to 0.71).tagsfilter fails loud (a would-collide guard) rather than silently dropping values; a wrong or missing key returns a cleanfailedrather than crashing.Conformance to repo conventions
scripts/validate_readme.py --plugins nori_regression: 0 errors.scripts/validate_influxdb3_syntax.py --readme influxdata/nori_regression/README.md: 0 errors, all CLI and API usage validated.organization/plugin_name/layout with the JSON metadata docstring, README,manifest.toml, andrequirements.txt, plus aplugin_library.jsonentry (author Synthefy).write_sync/write_sync_to_db(InfluxDB 3.8.2+, the same pattern as themqtt_subscriberandsynthefy_forecastingplugins) so write errors surface during trigger execution instead of being swallowed by the buffered writer.NORI_API_KEYenvironment variable, never from trigger arguments or the request body.Files added
influxdata/nori_regression/nori_regression.py: the plugin (metadata docstring plus implementation).influxdata/nori_regression/README.md: usage, configuration, and troubleshooting.influxdata/nori_regression/manifest.toml: packaging metadata.influxdata/nori_regression/requirements.txt: Python dependencies.influxdata/library/plugin_library.json: registry entry (the plugin lives in theinfluxdata/namespace, authored by Synthefy).Limitations