@alvera-ai/platform-sdk 0.10.0-rc.1 → 0.10.0-rc.11

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.
Files changed (32) hide show
  1. package/.agent/AGENTS.md +392 -0
  2. package/.agent/account_management.md +455 -0
  3. package/.agent/action_status_updaters.md +262 -0
  4. package/.agent/ai_agents.md +423 -0
  5. package/.agent/ai_sandbox.md +265 -0
  6. package/.agent/async.md +111 -0
  7. package/.agent/connected_apps.md +402 -0
  8. package/.agent/cookbook/_fixtures/README.md +77 -0
  9. package/.agent/cookbook/_fixtures/foundation/_lead_submissions_foundation_generic_table.liquid +33 -0
  10. package/.agent/cookbook/_fixtures/foundation/_lead_submissions_foundation_legal_entity.liquid +88 -0
  11. package/.agent/cookbook/_fixtures/foundation/_lead_submissions_foundation_mdm.liquid +48 -0
  12. package/.agent/cookbook/_setup/foundation.md +257 -0
  13. package/.agent/cookbook/birthday-greeting-sms-trigger.md +253 -0
  14. package/.agent/cookbook/score-leads-with-llm-categorization.md +442 -0
  15. package/.agent/custom_datasets.md +345 -0
  16. package/.agent/data_activation_clients.md +548 -0
  17. package/.agent/data_sources.md +234 -0
  18. package/.agent/datalakes.md +712 -0
  19. package/.agent/debugging.md +137 -0
  20. package/.agent/errors.md +235 -0
  21. package/.agent/interoperability_contracts.md +351 -0
  22. package/.agent/mdm.md +293 -0
  23. package/.agent/mutations.md +153 -0
  24. package/.agent/templates.md +98 -0
  25. package/.agent/tools.md +548 -0
  26. package/.agent/type_naming.md +135 -0
  27. package/.agent/workflows.md +601 -0
  28. package/dist/index.d.mts +4217 -3292
  29. package/dist/index.d.mts.map +1 -1
  30. package/dist/index.mjs +1282 -514
  31. package/dist/index.mjs.map +1 -1
  32. package/package.json +10 -3
@@ -0,0 +1,392 @@
1
+ # AGENTS.md — `@alvera-ai/platform-sdk` corpus
2
+
3
+ This corpus documents the platform's resource surface. It ships
4
+ inside the npm package and is read directly via `node_modules`
5
+ filesystem walk. Consumers include downstream agents writing
6
+ code in CLIs, React apps, integration test suites, and code
7
+ generators.
8
+
9
+ ## If you know MCP — vocabulary mapping
10
+
11
+ The platform's resources don't implement MCP wire format, but
12
+ the conceptual roles map cleanly onto MCP terms. If you've
13
+ landed here from an MCP background, this table tells you which
14
+ corpus page documents the surface you already know:
15
+
16
+ | MCP concept | Alvera resource | Corpus page |
17
+ |-----------------------|------------------------------|-----------------------------------------------|
18
+ | Host | The platform itself | This corpus + `account_management.md` |
19
+ | Client | Data Activation Client | `data_activation_clients.md` |
20
+ | Server | Agentic Workflow | `workflows.md` |
21
+ | Resources | Datasets (per data domain) | `custom_datasets.md`, `mdm.md` |
22
+ | Prompts | Interoperability Contracts | `interoperability_contracts.md`, `templates.md` |
23
+ | Sampling | Dataset event triggers | `data_activation_clients.md` §6.4 logs |
24
+ | Tools | Tool Calls (polymorphic body)| `tools.md` |
25
+ | Roots | Datalake boundaries | `datalakes.md` |
26
+ | Human-in-the-loop | Connected Apps + page tokens | `connected_apps.md` |
27
+ | Sandboxed execution | Liquid + SQL fragment lanes | `ai_sandbox.md` |
28
+
29
+ A few caveats on the mapping:
30
+
31
+ - **Capability negotiation is configuration, not runtime
32
+ handshake.** Tools declare their `intent` and `tool_body_type`
33
+ at create time; data activation clients declare their bound
34
+ contracts and tool call shape; workflows declare their event
35
+ dataset and decision keys. The platform doesn't negotiate
36
+ these per session — they're fixed by the resource records.
37
+ - **Sampling is lossless, not subscribed.** Dataset events
38
+ surface through database triggers and per-tenant work queues
39
+ rather than an MCP-style sampling subscription. Consumers
40
+ observe outcomes through the log subresource on the data
41
+ activation client or the workflow, not through a streaming
42
+ channel.
43
+ - **Roots are the tenancy boundary, full stop.** Cross-datalake
44
+ reads and writes are physically blocked at the connection
45
+ layer; a session scoped to one datalake can never reach
46
+ another tenant's data even if the calling code addresses a
47
+ different slug.
48
+
49
+ The rest of this preamble covers the actual SDK auth and client
50
+ construction.
51
+
52
+ ## SDK auth + client construction
53
+
54
+ The SDK is a strict-TypeScript REST client for the Alvera
55
+ platform. Two-step auth + client construction:
56
+
57
+ import {
58
+ createSession,
59
+ createIsolatedPlatformApi,
60
+ type PlatformApi,
61
+ } from '@alvera-ai/platform-sdk'
62
+
63
+ // 1. mint a session
64
+ const session = await createSession({
65
+ baseUrl,
66
+ email,
67
+ password,
68
+ tenantSlug, // optional; omit for tenantless session
69
+ })
70
+
71
+ // 2. build a typed client
72
+ const api: PlatformApi = createIsolatedPlatformApi({
73
+ baseUrl,
74
+ sessionToken: session.sessionToken,
75
+ })
76
+
77
+ Sessions come in three scopes:
78
+ - **root** — Alvera root admin; user signup + confirmation
79
+ - **tenantless** — authenticated user with no tenant chosen yet;
80
+ used once to create a tenant via `api.tenants.create(...)`
81
+ - **tenant-scoped** — the canonical Bearer for tenant operations
82
+
83
+ Consumers holding multiple concurrent clients in the same file
84
+ (e.g. integration tests that need root + tenantless + tenant-
85
+ scoped APIs concurrently) MUST use `createIsolatedPlatformApi`
86
+ rather than the singleton `createPlatformApi`. The singleton
87
+ mutates a shared client; the most-recent construction call
88
+ clobbers earlier instances' auth.
89
+
90
+ ## Resources
91
+
92
+ ```
93
+ INFRASTRUCTURE (stood up before data flows)
94
+ ──────────────
95
+ datalakes.md Storage layer; regulated +
96
+ unregulated tiers.
97
+ data_sources.md External ingestion endpoints.
98
+ tools.md Authenticated connections for
99
+ action execution.
100
+ templates.md Platform-shipped Liquid templates
101
+ consumed by other resources.
102
+ ai_agents.md LLM-backed workers.
103
+ action_status_updaters.md Polling reconcilers.
104
+ connected_apps.md External app bridges.
105
+ mdm.md Entity resolution + identity
106
+ verification across domains.
107
+ ai_sandbox.md Three-layer safety contract
108
+ bounding every AI-authored
109
+ fragment: compliance gates,
110
+ Liquid sandbox, SQL boundary.
111
+
112
+ DATA ACTIVATION (how data flows in)
113
+ ───────────────
114
+ custom_datasets.md Schema-on-write tables.
115
+ interoperability_contracts.md Liquid template mappings.
116
+ data_activation_clients.md Ingestion pipelines — both the
117
+ binding row (CRUD) and the
118
+ runtime verbs (.ingest, .ingestFile,
119
+ .runManually, logs, dataset search).
120
+
121
+ WORKFLOWS (composition on top)
122
+ ─────────
123
+ workflows.md Filter + decision + action;
124
+ standard + agent-driven variants.
125
+ ```
126
+
127
+ Axes are mostly disjoint but a few resources cross. AI Agents
128
+ anchor INFRASTRUCTURE and appear in DATA ACTIVATION (they
129
+ tokenize during ingestion) and WORKFLOWS (workflows invoke
130
+ them). Connected Apps anchor INFRASTRUCTURE and tag into
131
+ WORKFLOWS.
132
+
133
+ Each resource is exposed via a TypeScript namespace on the
134
+ typed client. The SDK namespace name follows TS conventions
135
+ (camelCase); the corpus MD filename matches the platform's
136
+ wire name (snake_case):
137
+
138
+ SDK namespace Corpus MD
139
+ ──────────────────── ───────────────────────────
140
+ api.datalakes datalakes.md
141
+ api.dataSources data_sources.md
142
+ api.tools tools.md
143
+ api.aiAgents ai_agents.md
144
+ api.actionStatusUpdaters action_status_updaters.md
145
+ api.connectedApps connected_apps.md
146
+ api.mdm mdm.md
147
+ api.genericTables custom_datasets.md
148
+ api.interoperabilityContracts interoperability_contracts.md
149
+ api.dataActivationClients data_activation_clients.md
150
+ api.workflows workflows.md
151
+
152
+ ## Cookbooks (Golden Path scenarios)
153
+
154
+ `.agent/cookbook/<slug>.md` files are pure-markdown scenario
155
+ stories — one business outcome each, told as a numbered API-call
156
+ sequence drawn from a green end-to-end vitest scenario in the
157
+ platform's integration-tests suite. Agents read these directly
158
+ from the filesystem at
159
+ `node_modules/@alvera-ai/platform-sdk/.agent/cookbook/`; there
160
+ is no SDK function and no CLI verb that returns cookbook bytes
161
+ at runtime.
162
+
163
+ Each cookbook structure:
164
+
165
+ - **Front matter** — `title`, `summary`, `industry`, `slug`,
166
+ `vitest_source` (list of integration-test files the snippets
167
+ are lifted from, anchor file first), `status`. The `industry:`
168
+ field also drives automatic discovery of the per-industry
169
+ bootstrap setup file at `_setup/<industry>.md` — see
170
+ "Industry-derived setup files" below.
171
+ - **Problem** — the business-outcome statement in domain terms,
172
+ sourced from the anchor vitest's behaviour (not from
173
+ customer-narrative documentation).
174
+ - **Composition** — table of resources provisioned, mapped to
175
+ the audience skill that owns each (setup / build / compose).
176
+ - **Walkthrough** — numbered `## NNN — <step>` subsections, each
177
+ carrying one fenced TypeScript block lifted from the anchor or
178
+ ancillary vitest. State threads forward across subsections via
179
+ plain JavaScript variables in the validator's generated
180
+ `describe` closure.
181
+ - **Branches** — alternate paths the anchor vitest covers (a
182
+ filter rejection, a transport failure, an agent-classification
183
+ fallback).
184
+ - **Rollback** — teardown order for the resources the cookbook
185
+ provisioned.
186
+ - **Outcome** — author's prose summary of what the scenario
187
+ produces.
188
+ - **See also** — links to relevant per-resource reference MDs
189
+ and to the anchor + ancillary vitest files.
190
+
191
+ ### Industry-derived setup files
192
+
193
+ Cookbook authoring uses per-industry bootstrap setup files
194
+ under `.agent/cookbook/_setup/<industry>.md` to DRY out the
195
+ auth + tenant + datalake + dataset-seeding steps every
196
+ scenario in an industry shares. The convention matches the
197
+ markdown-doctest / doc-vitest ecosystem pattern — setup
198
+ belongs to a scope (the industry), and any cookbook in that
199
+ scope inherits the setup by being there. No per-cookbook
200
+ opt-in field is required.
201
+
202
+ - Setup files live under `_setup/`. The leading underscore on
203
+ the directory marks them as fragments (not standalone
204
+ scenarios); the validator's discovery walk skips them and
205
+ the corpus index does not list them under "Available
206
+ cookbooks."
207
+ - The validator reads each scenario cookbook's existing
208
+ `industry:` front-matter field and auto-discovers the
209
+ setup file at `_setup/<industry>.md`. A cookbook in an
210
+ industry that has no setup file gets nothing inlined; the
211
+ validator does not fail if the setup file is absent.
212
+ Cookbook authors write no additional front-matter for
213
+ setup inclusion — the relationship is implicit, by
214
+ convention.
215
+ - The validator inlines the setup file's numbered `it()`
216
+ blocks BEFORE the scenario's own numbered `it()` blocks
217
+ inside the same `describe(...)`. Each `it()` label is
218
+ prefixed with its source slug so failure output
219
+ unambiguously points at the file to open (e.g.
220
+ `_setup/foundation §001 — auth` versus
221
+ `birthday-greeting-sms-trigger §001 — create workflow`).
222
+ Cookbook authors keep clean local §001-§00N numbering
223
+ inside their own markdown.
224
+ - An agent reading a scenario cookbook discovers the matching
225
+ setup file at the predictable conventional path
226
+ `_setup/<industry>.md` — one extra file open at a
227
+ fixed-by-convention location, not via cookbook-specific
228
+ metadata the agent has to learn.
229
+
230
+ ### Vendored fixtures (Liquid templates, CSV bodies)
231
+
232
+ End-to-end cookbooks walk the full data-activation chain
233
+ (data source → interoperability contract → Data Activation
234
+ Client → CSV ingest), which requires Liquid templates that
235
+ map inbound rows into the platform's upsert shapes. Inlining
236
+ those templates verbatim inside every cookbook markdown
237
+ bloats each recipe to several hundred lines of Liquid noise
238
+ that obscures the cookbook's lesson. The corpus ships them
239
+ as **vendored fixtures** instead — same pattern the platform
240
+ repo's own integration tests use.
241
+
242
+ - Fixtures live under
243
+ `.agent/cookbook/_fixtures/<industry>/`. The leading
244
+ underscore marks the directory as fragment infrastructure
245
+ (not a cookbook); the validator's discovery walk skips it.
246
+ Each `<industry>/` subdirectory carries a `README.md`
247
+ listing every template + which cookbook consumes it + the
248
+ production source-of-truth path it was vendored from
249
+ (`platform/priv/liquid_templates/…`).
250
+ - Cookbook code loads fixtures via the
251
+ `COOKBOOK_FIXTURES_DIR` environment variable:
252
+ ```typescript
253
+ import fs from 'node:fs'
254
+ import path from 'node:path'
255
+
256
+ const LE_TEMPLATE = fs.readFileSync(
257
+ path.join(
258
+ process.env.COOKBOOK_FIXTURES_DIR!,
259
+ 'foundation/_lead_submissions_foundation_legal_entity.liquid',
260
+ ),
261
+ 'utf8',
262
+ )
263
+ ```
264
+ Same env-var pattern as the `ALVERA_BASE_URL` /
265
+ `ALVERA_ROOT_EMAIL` / `ALVERA_ROOT_PASSWORD` credentials
266
+ the generated specs already consume.
267
+ `make validate-cookbook` exports
268
+ `COOKBOOK_FIXTURES_DIR=<absolute path to _fixtures>` to the
269
+ spawned Vitest process; any operator running cookbook code
270
+ directly from a Bun script must set the same variable.
271
+ - The fixtures ship with the `@alvera-ai/platform-sdk` npm
272
+ package via the `files: [.agent]` field, so a consumer
273
+ who installed the package finds the templates at
274
+ `node_modules/@alvera-ai/platform-sdk/.agent/cookbook/_fixtures/`.
275
+ - An agent reading the corpus discovers vendored templates by
276
+ directory walk:
277
+ `_fixtures/` → `<industry>/` → `README.md` lists every
278
+ template plus the cookbooks that depend on it. No need to
279
+ read cookbook code first to know what fixtures exist.
280
+
281
+ ### Available cookbooks
282
+
283
+ The eight cookbook scenarios shipped at v0.10. Each is anchored
284
+ to a green end-to-end vitest scenario in the platform's
285
+ integration-tests suite and is verified at dev time by
286
+ `make validate-cookbook` at the platform-sdk repo root (not a
287
+ CLI verb). The entries between the managed markers below are
288
+ what Milestone 12's `alvera-sdk-init` lifts into consumer
289
+ `<cwd>/AGENTS.md` files as a managed block.
290
+
291
+ <!-- BEGIN:cookbook-index -->
292
+
293
+ **Healthcare**
294
+
295
+ - [appointment-review-sms-workflow](./cookbook/appointment-review-sms-workflow.md)
296
+ — Send a patient review-request SMS after a fulfilled
297
+ appointment, deep-linked to a connected-app feedback form.
298
+ - [contact-us-triage-with-llm](./cookbook/contact-us-triage-with-llm.md)
299
+ — Triage inbound contact-us messages into three priority
300
+ buckets (appointment / job-application / spam) via an LLM
301
+ agent, route each to a tailored SMS action.
302
+
303
+ **Accounts Receivable**
304
+
305
+ - [welcome-sms-for-customers](./cookbook/welcome-sms-for-customers.md)
306
+ — Send a welcome SMS to newly contracted customers with a
307
+ self-serve billing-portal link.
308
+ - [dunning-sms-for-delinquent](./cookbook/dunning-sms-for-delinquent.md)
309
+ — Send a payment-reminder SMS to delinquent customers
310
+ (filtered on phone-on-file and tax-id-verified) with a
311
+ pay-invoice link.
312
+
313
+ **Payment Risk**
314
+
315
+ - [kyc-notification-on-account-activation](./cookbook/kyc-notification-on-account-activation.md)
316
+ — Send a KYC-notification SMS when a payment account
317
+ transitions to active status.
318
+ - [sanctions-screening-with-agent-review](./cookbook/sanctions-screening-with-agent-review.md)
319
+ — Disambiguate gray-zone sanctions screenings via an LLM
320
+ agent, route confirmed-clean and confirmed-block outcomes to
321
+ distinct SMS actions.
322
+
323
+ **Foundation**
324
+
325
+ - [birthday-greeting-sms-trigger](./cookbook/birthday-greeting-sms-trigger.md)
326
+ — Send a happy-birthday SMS on each contact's next birthday
327
+ using a pure-Liquid trigger (year-roll math).
328
+ - [score-leads-with-llm-categorization](./cookbook/score-leads-with-llm-categorization.md)
329
+ — Score inbound leads into four bands
330
+ (hot / warm / cold / spam) via an LLM agent, route each band
331
+ to a tailored SMS action.
332
+
333
+ <!-- END:cookbook-index -->
334
+
335
+ ## Utility namespaces
336
+
337
+ Cross-resource utilities not documented in this corpus:
338
+
339
+ api.auth signUp + auth helpers
340
+ api.admin confirmUser + admin actions
341
+ api.tenants create + tenant lifecycle
342
+ api.datasets cross-resource search / metadata /
343
+ user-saved searches
344
+ api.templates system-template discovery + per-tenant
345
+ metadata
346
+
347
+ ## Resource page structure
348
+
349
+ Each per-resource MD (e.g. `tools.md`) follows a consistent
350
+ 6-section structure: Wire shape, Rules the type cannot encode,
351
+ Field ownership, Error envelopes, Lifecycle, Gotchas.
352
+
353
+ ## Common sections (apply to all resources)
354
+
355
+ These sibling files cover patterns that apply uniformly across
356
+ all resources. Per-resource MDs reference them by name instead
357
+ of restating:
358
+
359
+ | Topic | File |
360
+ |-----------------------------------------------|------------------|
361
+ | Error envelope shape | `errors.md` |
362
+ | Mutations (PUT and limited exceptions) | `mutations.md` |
363
+ | Async + readiness | `async.md` |
364
+ | Debugging (HTTP interceptor + safe redaction) | `debugging.md` |
365
+ | Type naming + server-derived fields | `type_naming.md` |
366
+
367
+ ## Just getting started?
368
+
369
+ In your consumer repo, run:
370
+
371
+ ```
372
+ npx @alvera-ai/platform-sdk agent-init
373
+ ```
374
+
375
+ This writes a managed block into your `AGENTS.md` pointing back
376
+ at this corpus, and an `@AGENTS.md` import into `CLAUDE.md` for
377
+ Claude Code compatibility. Re-running replaces only the managed
378
+ block — content outside the markers is preserved.
379
+
380
+ ## Base path
381
+
382
+ All resources are scoped under a tenant + datalake:
383
+
384
+ ```
385
+ /api/v1/tenants/{tenant_slug}/datalakes/{datalake_slug}/<resource>
386
+ ```
387
+
388
+ The `{tenant_slug}` comes from your authenticated session's
389
+ tenant; the `{datalake_slug}` comes from the response of
390
+ `api.datalakes.create(tenantSlug, body)` (server-derived; never
391
+ pre-compute client-side — see `type_naming.md` "Server-derived
392
+ fields auto-excluded from Writable").