@alvera-ai/platform-sdk 0.19.2 → 0.20.0-next.gaafd87a

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.
@@ -84,11 +84,11 @@ Sends an SMS message via the configured SMS provider.
84
84
 
85
85
  ## Tool Call Configuration (mms_request)
86
86
 
87
- Sends an MMS (media message) via AWS End User Messaging.
87
+ Sends an MMS (media message) via AWS End User Messaging or Twilio.
88
88
 
89
89
  - **to** (TemplateConfig) — Recipient phone number in E.164 format, rendered as Liquid template
90
90
  - **body** (TemplateConfig) — Message body (caption), rendered as Liquid template
91
- - **media_url** (string) — Public http(s) URL of the media to attach; verified reachable (GET 2xx + image/*) at authoring, fetched and re-staged into the tool's S3 media bucket at send
91
+ - **media_url** (string) — Public http(s) URL of the media to attach; verified reachable (GET 2xx + image/*) at authoring, fetched at send (re-staged into the tool's S3 media bucket for End User Messaging; passed to Twilio as `MediaUrl`)
92
92
 
93
93
  <!-- alvera:section kind="tool-call-config" atom="email_request" module="Platform.Tools.ToolCallConfig.EmailRequest" -->
94
94
 
package/.agent/tools.md CHANGED
@@ -628,6 +628,7 @@ await api.tools.testInvocation(
628
628
  to: { type: 'custom', body: '+15551234567' },
629
629
  body: { type: 'custom', body: 'Hello' },
630
630
  sms_type: 'transactional', // sms_request-specific
631
+ link_prefix: 'https://go.example.com/l', // required on sms / mms / email
631
632
  },
632
633
  },
633
634
  )
@@ -671,11 +672,15 @@ per-branch required-list for the five test-invocable variants:
671
672
 
672
673
  ```
673
674
  tool_call_type: 'sms_request'
674
- required: to, body, sms_type
675
+ required: to, body, sms_type, link_prefix
676
+ optional: link_validity_days (default 365)
675
677
  enums: sms_type ∈ { 'transactional' (default), 'promotional' }
678
+ notes: every URL in body goes out as <link_prefix>/<token> —
679
+ see authenticated_links.md
676
680
 
677
681
  tool_call_type: 'mms_request'
678
- required: to, body, media_url
682
+ required: to, body, media_url, link_prefix
683
+ optional: link_validity_days (default 365)
679
684
  notes: body is the message caption; media_url is a PLAIN
680
685
  STRING — a public http(s) URL, no Liquid. The server
681
686
  verifies it at authoring (GET must answer 2xx with an
@@ -685,7 +690,9 @@ per-branch required-list for the five test-invocable variants:
685
690
  is end_user_messaging
686
691
 
687
692
  tool_call_type: 'email_request'
688
- required: to, subject, body
693
+ required: to, subject, body, link_prefix
694
+ optional: link_validity_days (default 365)
695
+ notes: every href in body goes out as <link_prefix>/<token>
689
696
  embeds: TemplateConfig variants accepted on each ({ type:
690
697
  'custom', body } or { type: 'identity' } or
691
698
  { type: 'system', path }); 'null' is not valid here
@@ -67,8 +67,7 @@ they are **not** interchangeable as call arguments:
67
67
  slug the human handle — the path key for runtime / operations
68
68
  verbs (workflows `execute` / `run` / logs, datalakes
69
69
  `migrate`, data-activation-client ingest / run, interop
70
- `run`, connected-apps `resolvePage` /
71
- `updateMessageTracking`). NOT accepted by a CRUD `.get`.
70
+ `run`). NOT accepted by a CRUD `.get`.
72
71
  name generic tables only — the physical Postgres table name
73
72
  (`alvera_custom_<slug>`) a DAC ingests into. NOT an API
74
73
  path key; CRUD still keys on the UUID `id`. See
@@ -100,8 +99,8 @@ const toolId = created.id! // <-- CRUD + cross-resource refs
100
99
  // A tool has NO slug, and neither does a generic table — they are
101
100
  // addressed by id and by name respectively. The slug-bearing responses
102
101
  // are the ones whose ops verbs take a slug in the path: datalakes,
103
- // workflows, data activation clients, connected apps, AI agents and
104
- // interoperability contracts. Reach for `.slug` only on those, and
102
+ // workflows, data activation clients, AI agents and interoperability
103
+ // contracts. Reach for `.slug` only on those, and
105
104
  // note every id and slug is optional on the wire, so a strict consumer
106
105
  // needs the `!` (or a guard) that the cookbooks use.
107
106
 
@@ -30,8 +30,8 @@ api.workflows.workflowLogs — one log row per dataset row processed
30
30
  ```
31
31
 
32
32
  Workflows are **Datalake-DB-resident** — the parent datalake must
33
- be `status: 'ready'` and every referenced resource (tools,
34
- connected apps, AI agents) must exist before you `create()`.
33
+ be `status: 'ready'` and every referenced resource (tools, AI
34
+ agents) must exist before you `create()`.
35
35
 
36
36
  ## 1. Wire shape
37
37
 
@@ -54,9 +54,9 @@ const { data: created } = await api.workflows.create(
54
54
  dataset_type: 'generic_table',
55
55
  generic_table_id: appointmentsTableId,
56
56
 
57
- // Load-bearing whenever an action mints a per-subject
58
- // `connected_app_form_url`: resolution is what attaches the row
59
- // to its legal entity. See §2.
57
+ // Load-bearing whenever a message carries a link: resolution is
58
+ // what gives the link its `legal_entity_id`, the person a tap on
59
+ // it belongs to. See §2 and authenticated_links.md.
60
60
  skip_mdm_resolution: false,
61
61
 
62
62
  status: 'live', // 'live' | 'draft' | 'manual' (see §5)
@@ -99,15 +99,19 @@ const { data: created } = await api.workflows.create(
99
99
  idempotency_template:
100
100
  '{{ event_dataset.appointment_id }}-{{ decision_key }}',
101
101
 
102
- connected_app_id: connectedAppId,
103
- connected_app_route: '/forms/review',
104
- connected_app_metadata_template:
102
+ // Rendered once per send and stored on the message; the host
103
+ // behind link_prefix reads it back from the exchange's
104
+ // `message.metadata`. See §7.
105
+ metadata_template:
105
106
  '{"appointment_id":"{{ event_dataset.appointment_id }}"}',
106
107
  tool_call: {
107
108
  tool_call_type: 'sms_request',
108
109
  to: { type: 'custom', body: '{{ event_dataset.patient_mobile | e164 }}' },
109
- body: { type: 'custom', body: 'Hi {{ event_dataset.patient_name | split: " " | first }}, please share your feedback at {{ connected_app_form_url }}' },
110
+ // Write the real destination. At send, every URL in the body
111
+ // goes out as <link_prefix>/<token>.
112
+ body: { type: 'custom', body: 'Hi {{ event_dataset.patient_name | split: " " | first }}, please share your feedback at https://reviews.example.com/visit' },
110
113
  sms_type: 'transactional',
114
+ link_prefix: 'https://go.example.com/l', // REQUIRED on sms / mms / email calls
111
115
  },
112
116
  },
113
117
  ],
@@ -446,9 +450,9 @@ for every dataset type.** Choose it by what the workflow needs:
446
450
 
447
451
  - **Leave it `false`** whenever the workflow must resolve the row to an
448
452
  MDM subject — which is required for anything keyed on a subject: a
449
- connected-app page token / tracked link (the token *requires* a
450
- subject id — see `connected_apps.md`), a `messages` row, or
451
- cross-dataset context. A `generic_table` workflow can absolutely run
453
+ link that knows who tapped it (without resolution its
454
+ `legal_entity_id` is `null` — see `authenticated_links.md`), a
455
+ `messages` row, or cross-dataset context. A `generic_table` workflow can absolutely run
452
456
  with resolution ON: stamp the entity FK (e.g. `legal_entity_id`) onto
453
457
  the row at ingestion and the workflow resolves its subject from that
454
458
  FK.
@@ -573,11 +577,14 @@ position optional int — display order, default 0
573
577
  runtime_filter optional string — fire-time skip / pause lever (§2)
574
578
  action_window_start optional int — send-window open hour 0–23 (§2)
575
579
  action_window_end optional int — send-window close hour 0–23 (§2)
576
- connected_app_id optional UUID — :sms/:email only (see connected_apps.md)
577
- connected_app_route optional string — required when connected_app_id set
578
- connected_app_metadata_template optional string — Liquid→JSON stored in the page token
580
+ metadata_template optional string — Liquid→JSON rendered once per send, stored
581
+ on the message (§7); every action type
579
582
  ```
580
583
 
584
+ Inside `tool_call`, the `sms_request`, `mms_request` and `email_request`
585
+ variants also take `link_prefix` (**required**) and `link_validity_days`
586
+ (optional, default 365) — see §7.
587
+
581
588
  **Write-only (Request-only).** None.
582
589
 
583
590
  ## 5. Lifecycle
@@ -714,7 +721,7 @@ an error to retry.
714
721
  tables. For a **platform dataset** the server assigns the alias
715
722
  (`le` legal entities, `m` messages, `al` action logs, `d` documents,
716
723
  `bo` beneficial owners — same scheme as `data_activation_clients.md`
717
- §6.5), and `id` is ambiguous across the base query's joins, so always
724
+ §6.6), and `id` is ambiguous across the base query's joins, so always
718
725
  prefix it: `le.id`.
719
726
 
720
727
  For a **generic-table** workflow there is no alias — the run selects
@@ -970,34 +977,31 @@ workflow execution log row's `error_message` is intentionally
970
977
  coarse so the database column doesn't grow with arbitrary
971
978
  provider responses. Always read `error.json` for diagnostics.
972
979
 
973
- ## 7. Connected apps as action sinks
974
-
975
- Workflows that send messages (SMS, email) typically link to a
976
- **connected app** — a registered consumer of the action's
977
- rendered URL. See `api.connectedApps`:
980
+ ## 7. Links in a message
978
981
 
979
- ```typescript
980
- await api.connectedApps.create(tenantSlug, datalakeSlug, {
981
- name: 'Review form',
982
- description: '...',
983
- mode: 'self_hosted', // 'self_hosted' | 'managed'
984
- urls: [{ url: 'https://app.example.com', is_primary: true, label: 'production' }],
985
- })
986
- ```
982
+ Every URL in an SMS or MMS body, and every `href` in an email body,
983
+ goes out as an authenticated link, `<link_prefix>/<token>`. Write the
984
+ real destination into the body; the platform rewrites it at send.
987
985
 
988
986
  Action wiring on the workflow:
989
- - `connected_app_id` — UUID of the bound connected app
990
- - `connected_app_route` — path on the app (e.g. `/forms/review`)
991
- - `connected_app_metadata_template` — Liquid template rendering
992
- a JSON object that the recipient can introspect after
993
- resolving the token
994
-
995
- At fire time, the action's message body's `{{ connected_app_form_url }}`
996
- expands to `https://<app-primary>/t/<short_path>`. The recipient
997
- hits that URL; the connected app calls
998
- `api.connectedApps.resolvePage` with the `short_path` to fetch
999
- the metadata, then `api.connectedApps.updateMessageTracking` to
1000
- record `opened_at` / `form_submitted_at`.
987
+ - `tool_call.link_prefix` — **required** on `sms_request`,
988
+ `mms_request` and `email_request`: the address of the host you run
989
+ to serve the links. Absolute `http`/`https`, path allowed, no query,
990
+ fragment or trailing slash.
991
+ - `tool_call.link_validity_days` — how many days each link resolves
992
+ after the send; default 365.
993
+ - `metadata_template` — on the action itself, any action type: a
994
+ Liquid template rendering a JSON object, once per send. It is
995
+ stored on the message, beside the recipient's `to`, and a template
996
+ that does not render fails the send.
997
+
998
+ When a person taps the link, your host calls
999
+ `api.authenticatedLinks.exchange` with the token and gets back where
1000
+ the link goes, who it was for, and the message — its `metadata`
1001
+ included. When the page opens or the form is submitted, the host
1002
+ reports it with `api.authenticatedLinks.updateMessageTracking`. The
1003
+ whole surface, its refusals (404 · 410 · 503) and what counts as a
1004
+ person's tap are in `authenticated_links.md`.
1001
1005
 
1002
1006
  ## 8. Watching a run — what to read for which question
1003
1007
 
package/README.md CHANGED
@@ -138,7 +138,7 @@ Every resource is a typed namespace on the client (`api.<resource>.<verb>`):
138
138
  | `genericTables` | `list`, `create` |
139
139
  | `actionStatusUpdaters` | `list`, `create`, `update` |
140
140
  | `aiAgents` | `list`, `get`, `create`, `update`, `delete`, `invoke` |
141
- | `connectedApps` | `list`, `get`, `create`, `update`, `syncRoutes`, `resolvePage`, `updateMessageTracking` |
141
+ | `authenticatedLinks` | `exchange`, `updateMessageTracking` |
142
142
  | `dataActivationClients` | `list`, `get`, `create`, `update`, `delete`, `metadata`, `runManually`, `ingest`, `ingestFile`, `logs.list`, `logs.get` |
143
143
  | `interoperabilityContracts` | `list`, `get`, `create`, `update`, `delete`, `metadata`, `run` |
144
144
  | `mdm` | `verify` |