@alvera-ai/platform-sdk 0.17.0 → 0.18.0
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.
- package/.agent/AGENTS.md +82 -144
- package/.agent/account_management.md +2 -2
- package/.agent/action_logs.md +4 -4
- package/.agent/ai_agents.md +28 -21
- package/.agent/ai_sandbox.md +49 -39
- package/.agent/connected_apps.md +3 -3
- package/.agent/cookbook/_fixtures/README.md +1 -1
- package/.agent/cookbook/_fixtures/{foundation → organic-marketing}/_lead_submissions_foundation_generic_table.liquid +1 -1
- package/.agent/cookbook/_fixtures/organic-marketing/_lead_submissions_foundation_legal_entity.liquid +80 -0
- package/.agent/cookbook/_fixtures/{foundation → organic-marketing}/_lead_submissions_foundation_mdm.liquid +2 -1
- package/.agent/cookbook/_fixtures/payments-compliance/_compliance_screenings_generic_table.liquid +57 -0
- package/.agent/cookbook/_fixtures/payments-compliance/_compliance_screenings_legal_entity.liquid +30 -0
- package/.agent/cookbook/_fixtures/payments-compliance/_compliance_screenings_mdm.liquid +44 -0
- package/.agent/cookbook/_fixtures/payments-compliance/_payment_accounts_generic_table.liquid +57 -0
- package/.agent/cookbook/_fixtures/payments-compliance/_payment_accounts_legal_entity.liquid +36 -0
- package/.agent/cookbook/_fixtures/payments-compliance/_payment_accounts_mdm.liquid +41 -0
- package/.agent/cookbook/_fixtures/primary-care-feedback/_cahps_appointments_generic_table.liquid +70 -0
- package/.agent/cookbook/_fixtures/primary-care-feedback/_cahps_appointments_legal_entity.liquid +52 -0
- package/.agent/cookbook/_fixtures/primary-care-feedback/_cahps_appointments_mdm.liquid +42 -0
- package/.agent/cookbook/_fixtures/subscription-saas/_customers_subscription_generic_table.liquid +38 -0
- package/.agent/cookbook/_fixtures/subscription-saas/_customers_subscription_legal_entity.liquid +48 -0
- package/.agent/cookbook/_fixtures/subscription-saas/_customers_subscription_mdm.liquid +49 -0
- package/.agent/cookbook/organic-marketing.md +2801 -0
- package/.agent/cookbook/payments-compliance.md +2180 -0
- package/.agent/cookbook/primary-care.md +2175 -0
- package/.agent/cookbook/subscription-saas.md +2403 -0
- package/.agent/data_activation_clients.md +65 -52
- package/.agent/datalakes.md +338 -171
- package/.agent/errors.md +3 -3
- package/.agent/generic_tables.md +151 -62
- package/.agent/interoperability_contracts.md +57 -22
- package/.agent/mdm.md +136 -153
- package/.agent/messages.md +36 -34
- package/.agent/mock-services.md +1 -1
- package/.agent/mutations.md +2 -2
- package/.agent/templates.md +14 -13
- package/.agent/tools.md +63 -21
- package/.agent/type_naming.md +13 -13
- package/.agent/workflows.md +99 -53
- package/README.md +2 -2
- package/dist/bin/platform-sdk.mjs +33 -47
- package/dist/bin/platform-sdk.mjs.map +1 -1
- package/dist/index.d.mts +565 -379
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +494 -59
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
- package/.agent/cookbook/_fixtures/foundation/_lead_submissions_foundation_legal_entity.liquid +0 -88
- package/.agent/cookbook/_fixtures/healthcare/_cahps_appointments_healthcare_appointment.liquid +0 -47
- package/.agent/cookbook/_fixtures/healthcare/_cahps_appointments_healthcare_mdm.liquid +0 -24
- package/.agent/cookbook/_fixtures/healthcare/_cahps_appointments_healthcare_patient.liquid +0 -38
- package/.agent/cookbook/_fixtures/payments/_compliance_screenings_payments_compliance_screening.liquid +0 -59
- package/.agent/cookbook/_fixtures/payments/_compliance_screenings_payments_mdm.liquid +0 -36
- package/.agent/cookbook/_fixtures/payments/_payment_accounts_payments_mdm.liquid +0 -30
- package/.agent/cookbook/_fixtures/payments/_payment_accounts_payments_payment_account.liquid +0 -55
- package/.agent/cookbook/_fixtures/subscription/_customers_subscription_mdm.liquid +0 -20
- package/.agent/cookbook/_setup/foundation.md +0 -359
- package/.agent/cookbook/_setup/healthcare.md +0 -361
- package/.agent/cookbook/_setup/payments.md +0 -365
- package/.agent/cookbook/_setup/subscription.md +0 -364
- package/.agent/cookbook/action-status-updaters.md +0 -278
- package/.agent/cookbook/ai-agent-invoke.md +0 -279
- package/.agent/cookbook/appointment-review-sms-workflow.md +0 -801
- package/.agent/cookbook/birthday-greeting-sms-trigger.md +0 -696
- package/.agent/cookbook/bulk-ingest.md +0 -302
- package/.agent/cookbook/contact-us-triage-with-llm.md +0 -663
- package/.agent/cookbook/dunning-sms-for-delinquent.md +0 -659
- package/.agent/cookbook/generic-tables.md +0 -244
- package/.agent/cookbook/invite-team.md +0 -200
- package/.agent/cookbook/kyc-notification-on-account-activation.md +0 -661
- package/.agent/cookbook/marketing-campaign-send.md +0 -1044
- package/.agent/cookbook/paginated-restapi-poller.md +0 -383
- package/.agent/cookbook/rest-fetch.md +0 -273
- package/.agent/cookbook/sanctions-screening-with-agent-review.md +0 -773
- package/.agent/cookbook/score-leads-with-llm-categorization.md +0 -665
- package/.agent/cookbook/system-templates.md +0 -165
- package/.agent/cookbook/talk-to-data.md +0 -178
- package/.agent/cookbook/triage-prospects-by-priority.md +0 -571
- package/.agent/cookbook/welcome-sms-for-customers.md +0 -647
- /package/.agent/cookbook/_fixtures/{healthcare → primary-care-feedback}/memorandum-of-association-01.png +0 -0
- /package/.agent/cookbook/_fixtures/{healthcare → primary-care-feedback}/sample_two_page.pdf +0 -0
- /package/.agent/cookbook/_fixtures/{subscription → subscription-saas}/_customers_subscription_customer.liquid +0 -0
- /package/.agent/cookbook/_fixtures/{subscription → subscription-saas}/stripe_customers_batch1.csv +0 -0
|
@@ -38,7 +38,6 @@ const { data: created } = await api.dataActivationClients.create(
|
|
|
38
38
|
tool_call: { tool_call_type: 'manual_upload' },
|
|
39
39
|
interoperability_contract_ids: [patientContractId, appointmentContractId],
|
|
40
40
|
cron_expressions: [], // omit for on-demand; e.g. ['0 7,19 * * *']
|
|
41
|
-
loop_over: [], // 'services' | 'locations' | 'providers'
|
|
42
41
|
row_filter: undefined, // Liquid pre-filter; see §2
|
|
43
42
|
downstream_connection_ids: [], // DAC chaining; cycle-checked
|
|
44
43
|
},
|
|
@@ -75,8 +74,9 @@ Discover it and ingest through it:
|
|
|
75
74
|
const { data: clients } = await api.dataActivationClients.list(tenantSlug, datalakeSlug)
|
|
76
75
|
// `list` returns the paged envelope { data, meta } — the DAC array is clients.data
|
|
77
76
|
const seedDac = (clients.data ?? []).find(
|
|
78
|
-
(c) => c.is_default && c.name.endsWith('customer DataActivationClient'),
|
|
77
|
+
(c) => c.is_default && (c.name ?? '').endsWith('customer DataActivationClient'),
|
|
79
78
|
)
|
|
79
|
+
if (!seedDac?.slug) throw new Error('no default activation client for that table')
|
|
80
80
|
// ingest is SLUG-keyed (see §6) — pass seedDac.slug, not seedDac.id
|
|
81
81
|
await api.dataActivationClients.ingest(tenantSlug, datalakeSlug, seedDac.slug, { data: row })
|
|
82
82
|
```
|
|
@@ -203,7 +203,8 @@ response_extractor optional embed — TemplateConfig ({ type, body
|
|
|
203
203
|
a Liquid template that unwraps a nested API
|
|
204
204
|
envelope into the row array (e.g.
|
|
205
205
|
`{{ msg.data | to_json }}`). Load-bearing for
|
|
206
|
-
`rest_api` fetch
|
|
206
|
+
`rest_api` fetch clients; see
|
|
207
|
+
`cookbook/subscription-saas.md` §032–035
|
|
207
208
|
```
|
|
208
209
|
|
|
209
210
|
**Write-only (Request-only).** None — every caller-supplied
|
|
@@ -429,7 +430,7 @@ rows_ingested number — count of top-level rows the contract emitted
|
|
|
429
430
|
dataset_updated number — count of dataset rows whose batch_id this run wrote
|
|
430
431
|
(load-bearing: see Gotcha 7)
|
|
431
432
|
output_files { object_key, mode }[] — merged ndjson archive refs, one per
|
|
432
|
-
bucket; mode is '
|
|
433
|
+
bucket; mode is 'raw' | 'tokenized' | 'redacted'
|
|
433
434
|
(empty until the post-batch merge worker commits).
|
|
434
435
|
NOT a string[] — each entry is an embed object;
|
|
435
436
|
use /logs/:id/download to fetch a presigned URL
|
|
@@ -483,12 +484,12 @@ durable" signal — not just the presence of the log row.
|
|
|
483
484
|
>
|
|
484
485
|
> ```typescript
|
|
485
486
|
> const { data: probe } = await api.datalakes.executeSql(tenantSlug, datalakeSlug, {
|
|
486
|
-
> sql: `SELECT 1 FROM
|
|
487
|
-
> mode: '
|
|
487
|
+
> sql: `SELECT 1 FROM ${tableName} WHERE batch_id = '${batchId}' LIMIT 1`,
|
|
488
|
+
> mode: 'raw',
|
|
488
489
|
> })
|
|
489
490
|
> // `data` is an array-of-arrays (a `string` only for { format: 'csv' });
|
|
490
|
-
> // a non-empty page proves the batch landed.
|
|
491
|
-
> //
|
|
491
|
+
> // a non-empty page proves the batch landed. The table is named the same
|
|
492
|
+
> // in every lake — `mode` selects which copy answers, not which name.
|
|
492
493
|
> const landed = typeof probe !== 'string' && probe.data.length > 0
|
|
493
494
|
> ```
|
|
494
495
|
>
|
|
@@ -507,7 +508,7 @@ default — the datalake is mandatory and explicit, mirroring
|
|
|
507
508
|
|
|
508
509
|
```typescript
|
|
509
510
|
// (1) POST creates a user search and runs the underlying SQL
|
|
510
|
-
// synchronously against the
|
|
511
|
+
// synchronously against the raw lake. The result
|
|
511
512
|
// set is materialised server-side and identified by the
|
|
512
513
|
// returned UUID.
|
|
513
514
|
const { data: search } = await api.datasets.createUserSearch(
|
|
@@ -516,24 +517,32 @@ const { data: search } = await api.datasets.createUserSearch(
|
|
|
516
517
|
'patient', // dataset name
|
|
517
518
|
{
|
|
518
519
|
search_query: `ri.value = '${externalPatientId}'` // SQL WHERE-clause fragment
|
|
519
|
-
+ ` AND
|
|
520
|
+
+ ` AND le.batch_id = '${batchId}'`,
|
|
520
521
|
},
|
|
521
522
|
)
|
|
522
523
|
// search.id — UUID of the materialised result set
|
|
523
|
-
// search.status — '
|
|
524
|
+
// search.status — 'new' | 'in_progress' | 'completed' | 'error'.
|
|
525
|
+
// The failure member is 'error', NOT 'failed' — and it is
|
|
526
|
+
// 'error' that carries error_message. There is no 'failed'.
|
|
524
527
|
// search.results_count — ALWAYS null on the POST response (see Gotcha 5)
|
|
525
528
|
|
|
526
529
|
// (2) GET paginates rows from the materialised result set.
|
|
527
|
-
// dataAccessMode selects
|
|
528
|
-
// '
|
|
529
|
-
// '
|
|
530
|
-
//
|
|
531
|
-
//
|
|
530
|
+
// dataAccessMode selects which lake answers:
|
|
531
|
+
// 'raw' — real values verbatim
|
|
532
|
+
// 'tokenized' — masked columns return a stable tok_<hash>
|
|
533
|
+
// 'redacted' — masked columns return an unjoinable placeholder
|
|
534
|
+
// `search.id` is `string | undefined` on the response type, and
|
|
535
|
+
// `DatasetSearchOptions.userSearchId` is declared `?: string` — optional, but
|
|
536
|
+
// NOT `| undefined`. So an app with `exactOptionalPropertyTypes` will not
|
|
537
|
+
// compile the shorthand, and an app without it gets a runtime 404 that reads
|
|
538
|
+
// like a wrong path. Narrow it first.
|
|
539
|
+
if (!search.id) throw new Error(`createUserSearch returned no id (status ${search.status})`)
|
|
540
|
+
|
|
532
541
|
const { data: page } = await api.datasets.search(
|
|
533
542
|
tenantSlug,
|
|
534
543
|
datalakeSlug,
|
|
535
544
|
'patient',
|
|
536
|
-
{ userSearchId: search.id, dataAccessMode: '
|
|
545
|
+
{ userSearchId: search.id, dataAccessMode: 'tokenized' },
|
|
537
546
|
)
|
|
538
547
|
// page.data — array of rows
|
|
539
548
|
// page.meta — pagination
|
|
@@ -541,50 +550,54 @@ const { data: page } = await api.datasets.search(
|
|
|
541
550
|
|
|
542
551
|
#### SQL aliases
|
|
543
552
|
|
|
544
|
-
`createUserSearch` accepts a WHERE-clause fragment against a
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
decomposed query — it is NOT derivable from the dataset name, and
|
|
549
|
-
different datasets reuse the same letters.** Verified examples:
|
|
553
|
+
`createUserSearch` accepts a WHERE-clause fragment against a fixed set
|
|
554
|
+
of server-assigned table aliases. **The alias is assigned by the
|
|
555
|
+
dataset's server-side decomposed query — it is not derivable from the
|
|
556
|
+
dataset name**, so confirm it rather than guessing:
|
|
550
557
|
|
|
551
558
|
```
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
559
|
+
legal_entity → le
|
|
560
|
+
message → m
|
|
561
|
+
action_log → al
|
|
562
|
+
document → d
|
|
563
|
+
beneficial_owner → bo
|
|
555
564
|
```
|
|
556
565
|
|
|
557
|
-
|
|
558
|
-
`
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
scopes the search to one run.
|
|
566
|
+
GH-859 removed the per-domain datasets this list used to name —
|
|
567
|
+
`patient`, `appointment`, `customer` and their `regulated_*` tables
|
|
568
|
+
are gone, and with them the `rp` / `ra` / `rc` aliases. **A customer,
|
|
569
|
+
a patient or an appointment is now a generic table you declare, plus
|
|
570
|
+
the legal entity its rows resolve to**; there is no dataset of that
|
|
571
|
+
name to search. The four cookbooks all take this shape.
|
|
564
572
|
|
|
565
|
-
|
|
573
|
+
The `<alias>.batch_id` predicate scopes a search to one run, which is
|
|
574
|
+
the usual reason to reach for this surface at all.
|
|
566
575
|
|
|
567
|
-
|
|
568
|
-
as objects, NOT primitives:
|
|
576
|
+
#### What a masked column looks like coming back
|
|
569
577
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
578
|
+
**Every column comes back as a plain value of its own type, in every
|
|
579
|
+
mode.** A masked column is a string; it is not wrapped in an object.
|
|
580
|
+
|
|
581
|
+
Measured on a live three-lake tenant, the same `first_name` read three
|
|
582
|
+
ways through `datasets.search`:
|
|
583
|
+
|
|
584
|
+
```
|
|
585
|
+
raw "Teodoro"
|
|
586
|
+
tokenized "tok_def1e9dd0d0d276ea8e39f885790f5ad"
|
|
587
|
+
redacted "xxxx-oro"
|
|
581
588
|
```
|
|
582
589
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
590
|
+
An older version of this guide described tokenized columns arriving as
|
|
591
|
+
`{ redacted_data, token, type }` objects and told consumers to branch on
|
|
592
|
+
`typeof row.field === 'object'`. That branch can never be taken. If you
|
|
593
|
+
are carrying such a guard, it is dead code — and worse, the `else` arm
|
|
594
|
+
it guards is the one doing all the work.
|
|
595
|
+
|
|
596
|
+
The two masked forms differ in what they are *for*. `tok_<hash>` is
|
|
597
|
+
stable, so the same input yields the same token and a machine can join
|
|
598
|
+
on it across tables without ever resolving it. `xxxx-<tail>` is
|
|
599
|
+
deliberately unjoinable — a placeholder for a person glancing at a
|
|
600
|
+
screen. Pick the mode by which of those two readers you are serving.
|
|
588
601
|
|
|
589
602
|
## 7. Gotchas
|
|
590
603
|
|