@alvera-ai/platform-sdk 0.18.2 → 0.19.2-next.g845dfdf

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -164,6 +164,70 @@ Anchor on the empty-render-passes rule, not on the Liquid
164
164
  keyword — `{% if ... %}...{% endif %}` and
165
165
  `{% unless ... %}...{% endunless %}` are equivalent.
166
166
 
167
+ ### `rows_from_file_template` says HOW MANY rows, never what is in them
168
+
169
+ A fetch lands a file in storage. `rows_from_file_template` is a
170
+ Liquid template that turns that file into the list of rows to
171
+ ingest. It may be set on **any** file — the content type decides
172
+ only how the file is DECODED, never whether a template is
173
+ allowed — and a run is never refused for declaring one.
174
+
175
+ `msg` binds to the decoded **whole file**: one value per file,
176
+ never a row. What it holds depends on how the fetch stored the
177
+ file:
178
+
179
+ | stored as | `msg` is |
180
+ |------------------------|-------------------------------------------|
181
+ | `application/json` | the parsed document |
182
+ | `application/x-ndjson` | the list of every parsed line |
183
+ | `text/csv` | the list of row maps, keyed by header |
184
+ | PDF, PNG, JPEG, WebP | `{ r2_key, content_type }` — a pointer, bytes undecoded |
185
+
186
+ The template must render a **JSON array**. Liquid renders text,
187
+ so any value has to be serialised on the way out; `to_json` is
188
+ the filter that does it, and there is no inverse — nothing parses
189
+ a JSON string back into a value inside the template.
190
+
191
+ Three shapes cover nearly everything:
192
+
193
+ - **one document becomes many rows** —
194
+ `{{ msg.data | to_json }}`
195
+ - **many rows become fewer** —
196
+ `{% assign kept = msg | where: "status", "active" %}{{ kept | to_json }}`
197
+ - **a whole file becomes one row** — `[{{ msg | to_json }}]`.
198
+ The brackets are what make it a list; this is the usual shape
199
+ for a PDF or an image, where `msg` is already the pointer the
200
+ contract needs.
201
+
202
+ **Leave it unset when the file is already the rows.** A
203
+ `sql_query` export, a CSV, and most `sftp` / `s3` bodies land as
204
+ rows already. Unset means take them as they are — the common
205
+ case, and it streams a chunk at a time instead of holding the
206
+ file in memory, which a template cannot do because it has to see
207
+ the whole file at once.
208
+
209
+ **The template decides how many rows there are; the contract
210
+ decides what is in each one.** A contract runs per row and can
211
+ never change the count, which is the one thing only this
212
+ template can do. Renaming or reshaping fields belongs in the
213
+ contract (`interoperability_contracts.md`), not here.
214
+
215
+ It runs on `.runManually`, on `.ingestFile`, and on every cron
216
+ fire — every path that fetches a file. It does **not** run on
217
+ `.ingest`, which takes rows inline and has no file to decode.
218
+
219
+ Extraction happens in a background job, so a template that fails
220
+ never reaches the HTTP response — `.runManually` still returns
221
+ its `batch_id`. The failure surfaces as a `data_activation_logs`
222
+ row you read back through `.logs.list` (§6.4), and in the
223
+ platform's error log under `error_code: rows_template_failed`.
224
+
225
+ **Renamed.** This field was `response_extractor` until
226
+ 2026-09-14; manifests and contracts written against the old name
227
+ need updating. The tool-level `response_extractor` (`tools.md`)
228
+ is a different field doing a different job — it maps a model
229
+ provider's envelope into a canonical result — and keeps its name.
230
+
167
231
  ## 3. Field ownership
168
232
 
169
233
  **Server-derived (Response-only).** Universal set from
@@ -199,18 +263,17 @@ downstream_connection_ids optional UUID[] — DACs triggered after this
199
263
  filter_config optional embed — TemplateConfig; server-pinned
200
264
  output_schema (enum ["true","false"]). A row-
201
265
  level filter evaluated per fetched row
202
- response_extractor optional embed — TemplateConfig ({ type, body });
203
- a Liquid template that unwraps a nested API
204
- envelope into the row array (e.g.
205
- `{{ msg.data | to_json }}`). Load-bearing for
206
- `rest_api` fetch clients; see
207
- `cookbook/subscription-saas.md` §032–035
266
+ rows_from_file_template optional embed — TemplateConfig ({ type, body });
267
+ a Liquid template that says where the rows are
268
+ inside a fetched file. It may be set on ANY
269
+ file and is never refused — see §2 for what
270
+ `msg` binds to and when to leave it unset
208
271
  ```
209
272
 
210
273
  **Write-only (Request-only).** None — every caller-supplied
211
274
  field round-trips on the response (the virtual array
212
275
  round-trips under `interoperability_contracts` on response).
213
- `filter_config` / `response_extractor` come back under the read-only
276
+ `filter_config` / `rows_from_file_template` come back under the read-only
214
277
  `SimpleTemplateConfigResponse` shape (their `output_schema` is
215
278
  server-pinned and not echoed).
216
279
 
@@ -314,7 +377,7 @@ Three run shapes exist, selected by the bound tool's
314
377
  All three produce **log rows** observable through
315
378
  `api.dataActivationClients.logs.*` (§6.4), and the canonical way
316
379
  to **verify** that ingestion worked is the two-step
317
- dataset-search pattern in §6.5.
380
+ dataset-search pattern in §6.6.
318
381
 
319
382
  ### 6.1 Inline JSON ingestion — `.ingest`
320
383
 
@@ -334,7 +397,7 @@ const { data } = await api.dataActivationClients.ingest(
334
397
  The response returns **immediately after enqueueing**, not
335
398
  after ingestion completes. To know when the row has actually
336
399
  been written, poll the logs (§6.4) or use the verification
337
- pattern (§6.5).
400
+ pattern (§6.6).
338
401
 
339
402
  The `batch_id` is the most important field on the response —
340
403
  every downstream log row and dataset row carries the same
@@ -471,7 +534,110 @@ merge step has committed the ndjson archive. Use
471
534
  `output_files.length > 0` as the "this batch's rows are fully
472
535
  durable" signal — not just the presence of the log row.
473
536
 
474
- ### 6.5 Verifying ingestion: the two-step dataset search
537
+ ### 6.5 Runs subresource — `.batches.list` / `.batches.get`
538
+
539
+ A **run** is one record; the log rows of §6.4 are one record per
540
+ dataset table that run wrote into. Read the run to answer *"is this
541
+ over, and how did it end"*; read the logs for the per-table detail,
542
+ filtered on the same `batch_id`.
543
+
544
+ Before this record existed, the only way to ask whether a run had
545
+ finished was to count log rows and guess — which cannot tell a run
546
+ still going from one that produced nothing and never will. A run
547
+ that was skipped or that died looked exactly like a slow one until
548
+ the caller's timeout expired.
549
+
550
+ ```
551
+ batch_id UUID — the run identifier, the same one `.ingest`,
552
+ `.ingestFile` and `.runManually` hand back, and the
553
+ one stamped on every per-table log row of this run
554
+ client_id UUID — the owning activation client
555
+ closed_at ISO timestamp | null — when the run was attempted and
556
+ exhausted. Null while it is still going. It does NOT
557
+ mean rows landed and it does NOT mean the archive was
558
+ merged — read `status` for the outcome, and only once
559
+ this is set.
560
+ status 'processing' | 'succeeded' | 'partial' | 'skipped' | 'failed'
561
+ rows_total number — source rows enqueued for this run. The run's own
562
+ count; each per-table log keeps its own.
563
+ inserted_at ISO timestamp — when the run started
564
+ ```
565
+
566
+ **`status` means nothing until `closed_at` is set.** A run in flight
567
+ always reads `processing`. Once it is closed:
568
+
569
+ | status | what happened |
570
+ |---|---|
571
+ | `succeeded` | it ran and nothing was refused |
572
+ | `partial` | it ran and at least one row was refused on the way in; the rows that landed are still there |
573
+ | `skipped` | it ran and there was nothing to do — empty file, every row filtered out, or the client has no contracts |
574
+ | `failed` | it died before writing anything |
575
+
576
+ ```typescript
577
+ // Paginated list of runs for an activation client. Takes the full Flop
578
+ // query (page / page_size / order_by / order_directions / filters —
579
+ // type_naming.md); without it, page 1 only.
580
+ const { data } = await api.dataActivationClients.batches.list(
581
+ tenantSlug, datalakeSlug, activationClientSlug,
582
+ { page: 1, page_size: 50, order_by: ['inserted_at'], order_directions: ['desc'] },
583
+ )
584
+ // data.data — array of run records; data.meta — pagination
585
+
586
+ // Fetch one run by its batch_id.
587
+ const { data: run } = await api.dataActivationClients.batches.get(
588
+ tenantSlug, datalakeSlug, activationClientSlug, batchId,
589
+ )
590
+ ```
591
+
592
+ > **The fourth argument is the `batch_id`, not the record's `id`.**
593
+ > A run record carries both, and both are UUIDs. The route looks the
594
+ > run up by its `batch_id` — the identifier the ingest handed you — so
595
+ > passing the record's own `id` is a **404**, not a type error.
596
+
597
+ #### Waiting on a run
598
+
599
+ This is what the run record is for. Poll until `closed_at` is set,
600
+ then branch on `status` — never poll `status` alone, because a run
601
+ in flight reads `processing` forever and tells you nothing:
602
+
603
+ ```typescript
604
+ const { data: ingest } = await api.dataActivationClients.ingest(
605
+ tenantSlug, datalakeSlug, activationClientSlug, { data: row },
606
+ )
607
+
608
+ const deadline = Date.now() + 120_000
609
+ let run
610
+ for (;;) {
611
+ const { data } = await api.dataActivationClients.batches.get(
612
+ tenantSlug, datalakeSlug, activationClientSlug, ingest.batch_id,
613
+ )
614
+ if (data.closed_at != null) { run = data; break }
615
+ if (Date.now() > deadline) throw new Error(`run ${ingest.batch_id} never closed`)
616
+ await new Promise((r) => setTimeout(r, 1_000))
617
+ }
618
+
619
+ if (run.status === 'failed') {
620
+ throw new Error(`run ${ingest.batch_id} failed before writing anything`)
621
+ }
622
+ if (run.status === 'skipped') {
623
+ throw new Error(`run ${ingest.batch_id} had nothing to do — check the row filter and the client's contracts`)
624
+ }
625
+ // 'succeeded' or 'partial' — the run is over and rows were written.
626
+ // For a partial, read the log rows (§6.4) for which table refused what.
627
+ ```
628
+
629
+ A run that failed or was skipped **ends the wait immediately, carrying
630
+ why**. That is the whole difference from counting rows: a blind poll
631
+ spends its full timeout and then reports nothing about the cause.
632
+
633
+ > **`closed_at` is not the same as "my row is queryable".** It says the
634
+ > run is over. It does not say the archive was merged (that is
635
+ > `output_files` on the log rows, §6.4), and for one specific row it
636
+ > does not replace the landing check in §6.6 — it makes that check a
637
+ > single read after the run is known finished, instead of a guess
638
+ > against a deadline.
639
+
640
+ ### 6.6 Verifying ingestion: the two-step dataset search
475
641
 
476
642
  > **Simplest landing check — `executeSql`.** Ingestion is async (the row
477
643
  > commits a moment after the `202`). When you just need to know a row
@@ -638,7 +804,7 @@ screen. Pick the mode by which of those two readers you are serving.
638
804
  response carries `batch_id` + `jobs_count`, signalling that
639
805
  downstream jobs have been enqueued — not that they've
640
806
  completed. Poll logs (or use the search verification
641
- pattern in §6.5) before treating the row as ingested.
807
+ pattern in §6.6) before treating the row as ingested.
642
808
 
643
809
  7. **`dataset_updated > 0` is the load-bearing freshness
644
810
  gate.** `rows_ingested` flips as soon as the per-row job
@@ -110,7 +110,7 @@ The platform does NOT expose a query API over the archive itself —
110
110
  cold reads happen externally so the platform's processes aren't
111
111
  responsible for analytical workloads. Live data lives in the
112
112
  datalake's Postgres halves (queryable via the dataset search
113
- two-step pattern in `data_activation_clients.md` §6.5); historical
113
+ two-step pattern in `data_activation_clients.md` §6.6); historical
114
114
  data lives in the cloud-storage buckets configured here.
115
115
 
116
116
  ### Canonical create body
@@ -299,7 +299,7 @@ in the datalake and there is nothing to search afterwards. The
299
299
  contract's `resource_type` destination) runs only when the DAC
300
300
  worker ingests a row — i.e. on `dataActivationClients.ingest`, not
301
301
  on `.run`. To prove a row *landed*, ingest and then query by
302
- `batch_id` (see `data_activation_clients.md` §6.5).
302
+ `batch_id` (see `data_activation_clients.md` §6.6).
303
303
 
304
304
  ```typescript
305
305
  const { data: result } = await api.interoperabilityContracts.run(
package/.agent/mdm.md CHANGED
@@ -185,6 +185,61 @@ is a 404, not a `'not_verified'`. The distinction matters:
185
185
  A consumer that conflates the two will mis-route an identity
186
186
  challenge as a missing-record error.
187
187
 
188
+ ### One label per kind of identifier a subject holds
189
+
190
+ An identification attaches to a legal entity under a label — its `uri` —
191
+ alongside an `id_type`. The pair `(uri, id_type)` is a **slot** on that
192
+ subject, and a subject holds each slot once. Two identifications under the
193
+ same pair are refused, not merged and not resolved to a winner.
194
+
195
+ So a subject that carries more than one identifier needs a label per kind.
196
+ Jane, from a Shopify store, with an email and a phone:
197
+
198
+ ```json
199
+ "identifications": [
200
+ { "id_type": "digital_identifier",
201
+ "uri": "shopify",
202
+ "id_number": "jane@example.com" },
203
+ { "id_type": "digital_identifier",
204
+ "uri": "shopify::phone",
205
+ "id_number": "+15551234" }
206
+ ]
207
+ ```
208
+
209
+ Written with `"uri": "shopify"` on both, the second is refused — the database
210
+ enforces it as `legal_entity_identifications_entity_uri_type_uk`.
211
+
212
+ The convention: the bare source identifies the **subject**; anything else the
213
+ subject carries gets its own label beneath it.
214
+
215
+ **Do not re-label identifications that already exist.** Changing the `uri` on a
216
+ recipe that has already run sends the next ingest to a DIFFERENT slot, which
217
+ adds a second identification rather than updating the first — the original is
218
+ orphaned, silently, and both then answer to the same person.
219
+
220
+ ### What a resolve does to the slots it does not name
221
+
222
+ A resolve speaks only about the slots it names:
223
+
224
+ | the slot you send | what happens |
225
+ |---|---|
226
+ | named, already filled | **overwritten** |
227
+ | named, empty | **added** |
228
+ | **not mentioned** | **kept, untouched** |
229
+
230
+ The third row is the one worth designing around, and the one nothing else
231
+ states. Several lanes can each resolve the same subject knowing only their own
232
+ identifiers, without destroying each other's work: a marketing lane sending
233
+ only an email and a billing lane sending only a phone both survive, in either
234
+ order.
235
+
236
+ Two limits that follow from the same rule:
237
+
238
+ - **A slot cannot be emptied through a resolve.** Omitting it means "leave it";
239
+ there is no value that means "remove it".
240
+ - **Two values under one `(uri, id_type)` in a single payload are refused**
241
+ rather than resolved to a winner — the platform does not pick.
242
+
188
243
  ## 3. Field ownership
189
244
 
190
245
  **Server-derived (Response-only).**
@@ -284,7 +339,7 @@ SDK surface:
284
339
 
285
340
  Today there is no `.list`, `.get`, or `.metadata` on the MDM
286
341
  namespace — subjects themselves are queried through the dataset
287
- search surface (see `data_activation_clients.md` §6.5), not
342
+ search surface (see `data_activation_clients.md` §6.6), not
288
343
  through `api.mdm`.
289
344
 
290
345
  ## 6. Gotchas
@@ -95,21 +95,21 @@ flowchart TD
95
95
  end
96
96
  ```
97
97
 
98
- **It lives in this repo**, at `cloudflare-workers/mock/`. Deploy from a normal checkout:
98
+ **It lives in this repo**, at `cloudflare/workers/mock/`. Deploy from a normal checkout:
99
99
 
100
100
  ```bash
101
- cd cloudflare-workers/mock && wrangler deploy
101
+ cd cloudflare/workers/mock && wrangler deploy
102
102
  ```
103
103
 
104
104
  The single line that makes this work without a vendored copy of the corpus:
105
105
 
106
106
  ```jsonc
107
- "image_build_context": ".."
107
+ "image_build_context": "../../.."
108
108
  ```
109
109
 
110
110
  That sets the Docker build context to the repo root, so the Dockerfile copies
111
111
  `wm_mappings/` and `wm_response_files/` from where they already live. Without it
112
- the context is `cloudflare-workers/mock/` and the corpus would have to be duplicated there —
112
+ the context is `cloudflare/workers/mock/` and the corpus would have to be duplicated there —
113
113
  two directories that look identical until they quietly aren't.
114
114
 
115
115
  ### There is no authentication
@@ -492,6 +492,73 @@ actions required array — inline; replace-on-PUT
492
492
  workflow_ai_agents optional array — inline; replace-on-PUT (see §3)
493
493
  ```
494
494
 
495
+ Caller-supplied fields **inside each `context_datasets[*]`** row:
496
+
497
+ ```
498
+ dataset_type required string — CLOSED ENUM, not free text. An
499
+ arbitrary value 422s at apply and
500
+ the error enumerates the allowed
501
+ types
502
+ generic_table_id required UUID when dataset_type == 'generic_table';
503
+ omit otherwise. NOT the same field
504
+ as the workflow's own
505
+ `generic_table_id` one level up
506
+ where_clause optional string — Liquid, max 10_000 chars (see
507
+ below for what it can reach, and
508
+ which tier it runs against)
509
+ limit optional int — must be positive
510
+ position optional int — default 0
511
+ ```
512
+
513
+ ### Reading what a context query returned
514
+
515
+ `additional_context.<dataset_type>` — the `dataset_type` string **literally**,
516
+ not the table name and not a slug. A `document` context is read at
517
+ `additional_context.document`.
518
+
519
+ Do not confuse this with the AI-agent form documented above
520
+ (`additional_context.<agent_slug>.<field>`): an agent is keyed by its slug, a
521
+ context dataset by its type.
522
+
523
+ ### ⚠ Two context datasets of the same `dataset_type` silently overwrite
524
+
525
+ The loader accumulates them into a map keyed by `dataset_type`, so declaring
526
+ two of the same type leaves **only the last one**. There is no error and no
527
+ warning — the workflow runs happily against the wrong context. If you need two
528
+ slices of one type, express it as one query with a wider `where_clause`.
529
+
530
+ ### The `where_clause` reaches the row differently than the filter does
531
+
532
+ This asymmetry is the easiest thing here to get wrong:
533
+
534
+ ```
535
+ where clause {{ <dataset_type>.field }} e.g. {{ generic_table.external_client_id }}
536
+ filter {{ event_dataset.field }} the SAME row, different accessor
537
+ ```
538
+
539
+ That makes three conventions for "the current row" across this corpus — the
540
+ third being `msg.row.x` in an interoperability filter versus `msg.x` in its
541
+ transform. Nothing about a name tells you which one you are in; the surface you
542
+ are authoring does.
543
+
544
+ ### Context queries run against the REGULATED tier
545
+
546
+ The loader reads context in regulated mode, so a `where_clause` must name the
547
+ **regulated** table alias (e.g. `regulated_alvera_custom_unsubscribe_list`),
548
+ not the unregulated name. This changes every where clause you write, and a
549
+ clause written against the unregulated name finds nothing rather than failing
550
+ loudly.
551
+
552
+ ### `context_datasets` cannot be cleared by omission
553
+
554
+ It is a **required, replace-on-PUT array**. Dropping the block from a manifest
555
+ does not clear it: the server retains what was last deployed, the rendered and
556
+ deployed checksums never converge, and every subsequent `plan` reports drift on
557
+ a config that was just applied. Send an explicit `[]` to mean "no context".
558
+
559
+ Same class as the `assume_role_external_id` convergence note — an omission that
560
+ reads as "leave it alone" on the wire and as "remove it" in the author's head.
561
+
495
562
  Caller-supplied fields **inside each `actions[*]`** row:
496
563
 
497
564
  ```
@@ -647,7 +714,7 @@ an error to retry.
647
714
  tables. For a **platform dataset** the server assigns the alias
648
715
  (`le` legal entities, `m` messages, `al` action logs, `d` documents,
649
716
  `bo` beneficial owners — same scheme as `data_activation_clients.md`
650
- §6.5), and `id` is ambiguous across the base query's joins, so always
717
+ §6.6), and `id` is ambiguous across the base query's joins, so always
651
718
  prefix it: `le.id`.
652
719
 
653
720
  For a **generic-table** workflow there is no alias — the run selects
package/dist/index.d.mts CHANGED
@@ -567,9 +567,9 @@ type DataActivationClientLogResponse = {
567
567
  */
568
568
  rows_ingested?: number;
569
569
  /**
570
- * `failed` when the batch died before enqueueing any row — the fetch itself errored, and `rows_ingested` and `input_files` are 0/[] on such a row. `partial` when the batch ran and at least one row was refused on the way in; the rows that landed are still there. Read `error` for the reason in both cases.
570
+ * `processing` from the moment the slice is enqueued until the batch finishes — the column has no default, so this is written, not assumed. `succeeded` is written once by the batch callback, and only over `processing`. `failed` when the batch died before enqueueing any row — the fetch or the enqueue itself errored, and `rows_ingested` and `input_files` are 0/[] on such a row. `partial` when the batch ran and at least one row was refused on the way in; the rows that landed are still there. Read `error` for the reason in the last two.
571
571
  */
572
- status?: 'succeeded' | 'partial' | 'failed';
572
+ status?: 'processing' | 'succeeded' | 'partial' | 'failed';
573
573
  readonly updated_at?: string;
574
574
  };
575
575
  /**
@@ -2150,6 +2150,42 @@ type AiAgentInvokeRequest = {
2150
2150
  [key: string]: unknown;
2151
2151
  };
2152
2152
  };
2153
+ /**
2154
+ * DataActivationClientBatchResponse
2155
+ *
2156
+ * One record per run. A run fans out into one `DataActivationClientLog` per dataset table it writes into; this is the run itself. To wait on a run, read `closed_at` here rather than reconstructing it from those logs — it is set exactly once, however the run ended.
2157
+ */
2158
+ type DataActivationClientBatchResponse = {
2159
+ /**
2160
+ * Run identifier, stamped on every Oban job and every per-table log row of this run
2161
+ */
2162
+ batch_id: string;
2163
+ /**
2164
+ * Owning Data Activation Client ID
2165
+ */
2166
+ readonly client_id: string;
2167
+ /**
2168
+ * When the run was attempted and exhausted. Null while it is still going. It does not mean rows landed and it does not mean the archive was merged — read `status` for the outcome, and only once this is set.
2169
+ */
2170
+ readonly closed_at?: string | null;
2171
+ /**
2172
+ * Run record ID
2173
+ */
2174
+ readonly id?: string;
2175
+ /**
2176
+ * When the run started
2177
+ */
2178
+ readonly inserted_at?: string;
2179
+ /**
2180
+ * Source rows enqueued for this run. The run's own count; each per-table log keeps its own.
2181
+ */
2182
+ rows_total?: number;
2183
+ /**
2184
+ * How the run ended. **It means nothing until `closed_at` is set** — a run still in flight always reads `processing`. `failed` when the run died before writing anything; `partial` when it ran and at least one row was refused on the way in; `skipped` when it ran and there was nothing to do, because the file was empty, every row was filtered out, or the client has no contracts.
2185
+ */
2186
+ status?: 'processing' | 'succeeded' | 'partial' | 'skipped' | 'failed';
2187
+ readonly updated_at?: string;
2188
+ };
2153
2189
  /**
2154
2190
  * AdvancedMigrationResponse
2155
2191
  *
@@ -3445,6 +3481,18 @@ type SqsResponse = {
3445
3481
  */
3446
3482
  region: string;
3447
3483
  };
3484
+ /**
3485
+ * DataActivationClientBatchListResponse
3486
+ *
3487
+ * Paginated list of data activation client runs
3488
+ */
3489
+ type DataActivationClientBatchListResponse = {
3490
+ /**
3491
+ * List of data activation client runs
3492
+ */
3493
+ data: Array<DataActivationClientBatchResponse>;
3494
+ meta: PaginationMeta;
3495
+ };
3448
3496
  /**
3449
3497
  * PaginationMeta
3450
3498
  *
@@ -3766,11 +3814,11 @@ type DataActivationClientResponse = {
3766
3814
  * DAC name
3767
3815
  */
3768
3816
  name: string;
3769
- response_extractor?: SimpleTemplateConfigResponse | null;
3770
3817
  /**
3771
3818
  * Optional row-level Liquid pre-filter. Renders to empty/whitespace → row passes; any non-empty trimmed render → row is skipped (rendered string is the skip reason). Nil/empty body = no filter. Same semantics as InteroperabilityContract.filter_template.
3772
3819
  */
3773
3820
  row_filter?: string | null;
3821
+ rows_from_file_template?: SimpleTemplateConfigResponse | null;
3774
3822
  /**
3775
3823
  * URL-friendly slug (derived from name on insert; immutable)
3776
3824
  */
@@ -5967,11 +6015,11 @@ type DataActivationClientRequestWritable = {
5967
6015
  * DAC name
5968
6016
  */
5969
6017
  name: string;
5970
- response_extractor?: SimpleTemplateConfigRequest;
5971
6018
  /**
5972
6019
  * Optional row-level Liquid pre-filter. Renders to empty/whitespace → row passes; any non-empty trimmed render → row is skipped (rendered string is the skip reason). Nil/empty body = no filter. Same semantics as InteroperabilityContract.filter_template.
5973
6020
  */
5974
6021
  row_filter?: string | null;
6022
+ rows_from_file_template?: SimpleTemplateConfigRequest | null;
5975
6023
  tool_call: ({
5976
6024
  tool_call_type: 'restapi_request';
5977
6025
  } & DataActivationClientRestCallRequestWritable) | ({
@@ -6593,6 +6641,59 @@ type PlatformApiAdvancedMigrationControllerIndexData = {
6593
6641
  };
6594
6642
  url: '/api/v1/tenants/{tenant_slug}/datalakes/{datalake_slug}/advanced-migrations';
6595
6643
  };
6644
+ type PlatformApiDataActivationClientControllerBatchesIndexData = {
6645
+ body?: never;
6646
+ path: {
6647
+ /**
6648
+ * Tenant slug
6649
+ */
6650
+ tenant_slug: string;
6651
+ /**
6652
+ * Datalake slug
6653
+ */
6654
+ datalake_slug: string;
6655
+ /**
6656
+ * Data Activation Client slug
6657
+ */
6658
+ slug: string;
6659
+ };
6660
+ query?: {
6661
+ /**
6662
+ * Items per page (1-100). Defaults to the resource's Flop default when omitted.
6663
+ */
6664
+ page_size?: number;
6665
+ /**
6666
+ * Page number (1-indexed). Defaults to 1 when omitted.
6667
+ */
6668
+ page?: number;
6669
+ /**
6670
+ * Fields to sort by, in order of precedence. Must appear in the resource schema's Flop `sortable:` list — unknown fields return 422.
6671
+ */
6672
+ order_by?: Array<string>;
6673
+ /**
6674
+ * Sort direction(s), pair-wise with `order_by`. `asc` or `desc`. Defaults to `asc` per unpaired `order_by` entry.
6675
+ */
6676
+ order_directions?: Array<'asc' | 'desc'>;
6677
+ /**
6678
+ * Flop-native filter array. URL shape: `?filters[][field]=status&filters[][op]=%3D%3D&filters[][value]=pending` (empty brackets — consecutive `[]` entries group into one filter object per element; indexed brackets parse as a map and fail the array cast with 422). `op` is the symbol, percent-encoded — `%3D%3D` for `==`, `%3E%3D` for `>=` — not a word like `equal`; anything outside the enum above is a 422 before the request reaches Flop. Omit `op` entirely for equality. Unknown fields return 422 via Flop validation at the context layer.
6679
+ */
6680
+ filters?: Array<{
6681
+ /**
6682
+ * Filterable field name (must be in the resource's `filterable:`)
6683
+ */
6684
+ field: string;
6685
+ /**
6686
+ * Comparison operator. Defaults to `==` when omitted.
6687
+ */
6688
+ op?: '==' | '!=' | '<' | '<=' | '>' | '>=' | 'empty' | 'not_empty' | 'like' | 'ilike' | 'like_and' | 'like_or' | 'ilike_and' | 'ilike_or' | 'in' | 'not_in' | 'contains' | 'not_contains';
6689
+ /**
6690
+ * Filter value — shape depends on `field` and `op`.
6691
+ */
6692
+ value: unknown;
6693
+ }>;
6694
+ };
6695
+ url: '/api/v1/tenants/{tenant_slug}/datalakes/{datalake_slug}/data-activation-clients/{slug}/batches';
6696
+ };
6596
6697
  type PlatformApiAiAgentControllerIndexData = {
6597
6698
  body?: never;
6598
6699
  path: {
@@ -8353,6 +8454,18 @@ declare function _buildApi(myClient: Client): {
8353
8454
  response: Response;
8354
8455
  }>;
8355
8456
  };
8457
+ batches: {
8458
+ list: (tenantSlug: string, datalakeSlug: string, slug: string, query?: PlatformApiDataActivationClientControllerBatchesIndexData["query"]) => Promise<{
8459
+ data: DataActivationClientBatchListResponse;
8460
+ request: Request;
8461
+ response: Response;
8462
+ }>;
8463
+ get: (tenantSlug: string, datalakeSlug: string, slug: string, batchId: string) => Promise<{
8464
+ data: DataActivationClientBatchResponse;
8465
+ request: Request;
8466
+ response: Response;
8467
+ }>;
8468
+ };
8356
8469
  };
8357
8470
  interoperabilityContracts: {
8358
8471
  list: (tenantSlug: string, datalakeSlug: string, query?: PlatformApiInteroperabilityContractControllerIndexData["query"]) => Promise<{
@@ -8535,5 +8648,5 @@ declare function _buildApi(myClient: Client): {
8535
8648
  //#region src/index.d.ts
8536
8649
  declare function isEnvironmentName(name: string): name is EnvironmentName;
8537
8650
  //#endregion
8538
- export { type ActionStatusUpdaterCloudWatchQueryRequest, type ActionStatusUpdaterRequestWritable, type ActionStatusUpdaterResponse, type ActionStatusUpdaterRestCallRequest, ActionType, type AdvancedMigrationListResponse, type AdvancedMigrationRequest, type AdvancedMigrationResponse, type AgenticWorkflowListResponse, type AgenticWorkflowRequestWritable, type AgenticWorkflowResponse, type AiAgentRequestWritable, type AiAgentResponse, type AlveraApiError, type AlveraClient, type ApiConfig, type ApiDebugConfig, type BatchLogListResponse, type BatchLogResponse, type ConnectedAppListResponse, type ConnectedAppRequestWritable, type ConnectedAppResponse, type CreateActionStatusUpdaterRequest, type CreateAiAgentRequest, type CreateGenericTableRequest, type CreateSessionParams, DEFAULT_ENVIRONMENT, type DataActivationClientListResponse, type DataActivationClientLogListResponse, type DataActivationClientLogResponse, type DataActivationClientRequestWritable, type DataActivationClientResponse, type DataSourceRequest, type DataSourceRequestWritable, type DataSourceResponse, type DatalakeRequestWritable, type DatalakeResponse, type DatasetMetadataOptions, type DatasetSearchOptions, type DatasetSearchResponse, type DerivedLakeTablesResponse, type DownloadUrlResponse, ENVIRONMENTS, type EnvironmentName, type ErrorResponse, type ExecuteActionRequest, type ExecuteActionResponse, type ExecuteSqlMeta, type ExecuteSqlRequest, type ExecuteSqlResponse, type GenericTableColumnRequest, type GenericTableColumnResponse, type GenericTableResponse, type IngestFileRequest, type IngestRequest, type InteroperabilityContractAiAgentRequestWritable, type InteroperabilityContractListResponse, type InteroperabilityContractRequestWritable, type InteroperabilityContractResponse, type InteroperabilityRunRequest, type InteroperabilityRunResponse, type MdmVerifyRequest, type MdmVerifyResponse, type PaginationMeta, type PlatformApi, type ResolvePageRequest, type ResyncTableRequest, type ResyncTableResponse, type RunManuallyRequestWritable, type RunManuallyResponse, type RunWorkflowRequest, type RunWorkflowResponse, type SessionResponse, type SessionResult, type SyncRoutesResponse, type TemplateConfig, type TenantListResponse, type TenantResponse, type TextToSqlRequest, type TextToSqlResponse, ToolIntent, type ToolListResponse, type ToolRequest, type ToolRequestWritable, type ToolResponse, type ToolTwilioRequest, type ToolTwilioRequestWritable, type ToolTwilioResponse, type TwilioRequest, type TwilioRequestWritable, type TwilioResponse, type UpdatePageRequest, type UploadLinkRequest, type UploadLinkResponse, type WorkflowAiAgentRequestWritable, type WorkflowLogListResponse, type WorkflowLogResponse, type WorkflowRunListResponse, type WorkflowRunResponse, createBootstrapSession, createIsolatedPlatformApi, createPlatformApi, createSession, isEnvironmentName, revokeSession };
8651
+ export { type ActionStatusUpdaterCloudWatchQueryRequest, type ActionStatusUpdaterRequestWritable, type ActionStatusUpdaterResponse, type ActionStatusUpdaterRestCallRequest, ActionType, type AdvancedMigrationListResponse, type AdvancedMigrationRequest, type AdvancedMigrationResponse, type AgenticWorkflowListResponse, type AgenticWorkflowRequestWritable, type AgenticWorkflowResponse, type AiAgentRequestWritable, type AiAgentResponse, type AlveraApiError, type AlveraClient, type ApiConfig, type ApiDebugConfig, type BatchLogListResponse, type BatchLogResponse, type ConnectedAppListResponse, type ConnectedAppRequestWritable, type ConnectedAppResponse, type CreateActionStatusUpdaterRequest, type CreateAiAgentRequest, type CreateGenericTableRequest, type CreateSessionParams, DEFAULT_ENVIRONMENT, type DataActivationClientBatchListResponse, type DataActivationClientBatchResponse, type DataActivationClientListResponse, type DataActivationClientLogListResponse, type DataActivationClientLogResponse, type DataActivationClientRequestWritable, type DataActivationClientResponse, type DataSourceRequest, type DataSourceRequestWritable, type DataSourceResponse, type DatalakeRequestWritable, type DatalakeResponse, type DatasetMetadataOptions, type DatasetSearchOptions, type DatasetSearchResponse, type DerivedLakeTablesResponse, type DownloadUrlResponse, ENVIRONMENTS, type EnvironmentName, type ErrorResponse, type ExecuteActionRequest, type ExecuteActionResponse, type ExecuteSqlMeta, type ExecuteSqlRequest, type ExecuteSqlResponse, type GenericTableColumnRequest, type GenericTableColumnResponse, type GenericTableResponse, type IngestFileRequest, type IngestRequest, type InteroperabilityContractAiAgentRequestWritable, type InteroperabilityContractListResponse, type InteroperabilityContractRequestWritable, type InteroperabilityContractResponse, type InteroperabilityRunRequest, type InteroperabilityRunResponse, type MdmVerifyRequest, type MdmVerifyResponse, type PaginationMeta, type PlatformApi, type ResolvePageRequest, type ResyncTableRequest, type ResyncTableResponse, type RunManuallyRequestWritable, type RunManuallyResponse, type RunWorkflowRequest, type RunWorkflowResponse, type SessionResponse, type SessionResult, type SyncRoutesResponse, type TemplateConfig, type TenantListResponse, type TenantResponse, type TextToSqlRequest, type TextToSqlResponse, ToolIntent, type ToolListResponse, type ToolRequest, type ToolRequestWritable, type ToolResponse, type ToolTwilioRequest, type ToolTwilioRequestWritable, type ToolTwilioResponse, type TwilioRequest, type TwilioRequestWritable, type TwilioResponse, type UpdatePageRequest, type UploadLinkRequest, type UploadLinkResponse, type WorkflowAiAgentRequestWritable, type WorkflowLogListResponse, type WorkflowLogResponse, type WorkflowRunListResponse, type WorkflowRunResponse, createBootstrapSession, createIsolatedPlatformApi, createPlatformApi, createSession, isEnvironmentName, revokeSession };
8539
8652
  //# sourceMappingURL=index.d.mts.map