@alvera-ai/platform-sdk 0.17.2 → 0.17.4-next.g6daa781

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/tools.md CHANGED
@@ -12,10 +12,11 @@ dimensions:
12
12
  - **body type** declares HOW the tool connects (S3, SFTP, SQL,
13
13
  REST, AWS Lambda, …) via a polymorphic discriminator
14
14
 
15
- A datalake can own many tools. Some tools nest under a data source
16
- (`data_source_id` populated — typical for ingestion-receiving
17
- tools like `manual_upload`); others are standalone and reachable
18
- to any workflow on the datalake.
15
+ A datalake can own many tools, and every tool names the data source
16
+ it belongs to (`data_source_id`, required on every intent — see §2).
17
+ A tool stays reachable to any workflow on the datalake; the data
18
+ source decides which `uri` the messages it sends carry, which is what
19
+ action status updaters match on.
19
20
 
20
21
  ## 1. Wire shape
21
22
 
@@ -119,6 +120,7 @@ happened to it** — no delivery status, no reconciliation.
119
120
  await api.tools.create(tenantSlug, datalakeSlug, {
120
121
  name: 'Campaign Sender — Main Line',
121
122
  intent: 'sms',
123
+ data_source_id: dataSourceId, // every tool names one; its messages carry this source's uri
122
124
  tool_body_type: 'twilio',
123
125
  variant_type: 'primary',
124
126
  account_sid: 'AC…', // "AC" + 32 hex
@@ -182,14 +184,16 @@ What stays with the variant is the sender identity and its event routing:
182
184
  twilio from_number XOR messaging_service_sid
183
185
  sns phone_number
184
186
  end_user_messaging phone_number · configuration_set_name
185
- email :mailgun from_email · from_name · reply_to · domain
186
- email :ses from_email · from_name · reply_to
187
- email :sendgrid from_email · from_name · reply_to
188
- email :smtp from_email · from_name · reply_to
187
+ email :mailgun base_from_email · base_from_name · base_reply_to · domain
188
+ email :ses base_from_email · base_from_name · base_reply_to
189
+ email :sendgrid base_from_email · base_from_name · base_reply_to
190
+ email :smtp base_from_email · base_from_name · base_reply_to
189
191
  ```
190
192
 
191
193
  Everything else — auth, region, endpoints, the MMS staging bucket — comes
192
- from the primary. Two entries look arbitrary and are not: Mailgun's
194
+ from the primary; an SES variant on `assume_role` uses its primary's
195
+ role. `base_from_email` is required on every email tool, primary or
196
+ variant. Two entries look arbitrary and are not: Mailgun's
193
197
  `domain` is also a path segment in the request URL
194
198
  (`/v3/{domain}/messages`), and End User Messaging's
195
199
  `configuration_set_name` is the *event-routing* address, of which AWS
@@ -227,16 +231,29 @@ create time:
227
231
  A misaligned pair (e.g. `intent: sms` + `tool_body_type: sftp`)
228
232
  returns a `422` with `body.tool_body_type` in `errors`.
229
233
 
230
- ### `data_source_id` is optional but discriminator-aware
234
+ ### `data_source_id` is required on every tool
231
235
 
232
- When set, the tool is **embedded under a data source** — its
233
- lifecycle is tied to the parent data source, and ingestion paths
234
- expect it at that scope. When omitted, the tool is **standalone**
235
- on the datalake — available to any workflow that names it.
236
+ Every tool names the data source it belongs to, whatever its intent
237
+ or body type. A create without `data_source_id` is a `422` at
238
+ `/data_source_id` (`can't be blank`); `update()` is a full
239
+ replacement, so send it on every PUT too. The generated type still
240
+ marks the field optional and nullable — the server's rule is the one
241
+ that holds.
236
242
 
237
- The body type itself signals the typical pattern: `manual_upload`
238
- is almost always embedded (the data source IS the upload sink);
239
- `sns`, `rest_api`, `sql_database` are typically standalone.
243
+ What it drives:
244
+
245
+ - **The messages a tool sends carry its data source's `uri`.** An
246
+ action status updater names one data source and matches polled
247
+ events to messages and action logs by that `uri` plus the vendor's
248
+ id (`action_status_updaters.md` §2). One data source may hold SMS,
249
+ MMS and voice tools; nothing checks what else is on it.
250
+ - **A data source cannot be deleted while it still has tools.** The
251
+ delete answers `409` (`still has tools`); delete or move its tools
252
+ first. The foreign key restricts, so nothing cascades.
253
+
254
+ The body type still signals the typical pattern: a `manual_upload`
255
+ tool's data source IS the upload sink; a sender's data source is the
256
+ one its messages, and its status updater, belong to.
240
257
 
241
258
  ### Body-type sub-fields are validated against the matching discriminator branch (server-side)
242
259
 
@@ -325,15 +342,53 @@ tool body. Nothing you can put in `endpoint_url` changes it.
325
342
 
326
343
  ### `assume_role` needs the platform's ARN — read it from `GET /api/ping`
327
344
 
328
- The `assume_role` auth method (on `sns` and `end_user_messaging`
329
- bodies) is configured from two values that come from opposite
330
- sides of the trust relationship:
345
+ The `assume_role` auth method (on `sns`, `end_user_messaging` and
346
+ SES `email` bodies) is configured from two values that come from
347
+ opposite sides of the trust relationship:
331
348
 
332
349
  ```
333
350
  assume_role_arn the role YOU create in YOUR AWS
334
351
  account, for the platform to assume
335
- assume_role_external_id the platform-generated external ID
336
- that role must require
352
+ (arn:aws:iam::<12 digits>:role/<name>)
353
+ assume_role_external_id the external ID that role must require
354
+ — kept as sent, generated by the
355
+ platform when sent blank
356
+ ```
357
+
358
+ Because the customer writes the external ID into the role's trust
359
+ policy before the tool exists, send it on create rather than letting
360
+ the platform generate one — a generated value is one the policy does
361
+ not know yet.
362
+
363
+ **SES email tools on `assume_role`.** The email body's `auth_method`
364
+ (`access_key | iam_role | assume_role`, SES only) defaults to
365
+ `access_key` when an SES tool is saved without it; a non-SES email
366
+ tool has all three auth fields cleared on save. Saving an SES tool on
367
+ `assume_role` checks the role, the SES account and the sending address
368
+ (the rendered `base_from_email`) against AWS. A failure is a `422` in
369
+ the standard envelope (`errors.md`) pointing at `/body/auth_method`,
370
+ `/body/region`, `/body/base_from_email` or `/body/primary_tool_id`,
371
+ and it carries what AWS said. A variant (`variant_type: 'variant'`,
372
+ `primary_tool_id`) uses its primary's role.
373
+
374
+ ```typescript
375
+ const { data: sesTool } = await api.tools.create(tenantSlug, datalakeSlug, {
376
+ name: 'Campaign Email',
377
+ intent: ToolIntent.EMAIL,
378
+ status: 'active',
379
+ datalake_id: datalakeId,
380
+ data_source_id: dataSourceId,
381
+ body: {
382
+ tool_body_type: 'email',
383
+ provider: 'ses',
384
+ region: 'us-east-1',
385
+ auth_method: 'assume_role',
386
+ assume_role_arn: 'arn:aws:iam::123456789012:role/alvera-ses-sender',
387
+ assume_role_external_id: externalId, // the value already in the role's trust policy
388
+ base_from_email: { type: 'custom', body: 'campaigns@example.com' },
389
+ base_from_name: { type: 'custom', body: 'Example Salon' },
390
+ },
391
+ })
337
392
  ```
338
393
 
339
394
  Creating that role means naming a principal in its trust policy,
@@ -507,8 +562,8 @@ silent OIDC-provider outage can fail an otherwise-cosmetic
507
562
 
508
563
  scoping
509
564
  datalake_id parent datalake (UUID)
510
- data_source_id (optional) parent data source for embedded
511
- tools; omit for standalone
565
+ data_source_id required — the data source the tool belongs
566
+ to (every intent; send it on every PUT)
512
567
 
513
568
  body (polymorphic — required keys depend on tool_body_type)
514
569
  tool_body_type discriminator — names which branch shape
@@ -542,8 +597,8 @@ Capture both `id` and `slug` from the create response; never
542
597
  pre-compute either client-side. The **UUID `id`** is the CRUD path
543
598
  key (`.get` / `.update` / `.delete`) AND the cross-resource
544
599
  reference — workflows and data-activation clients bind a tool by
545
- `id` (`tool_id`), and action status updaters by `updater_tool_id` /
546
- `sender_tool_ids` (see §7). The `slug` is the human handle; it does
600
+ `id` (`tool_id`), and action status updaters by `updater_tool_id`
601
+ (see §7; an updater names a data source, not its sender tools). The `slug` is the human handle; it does
547
602
  NOT key a CRUD `.get` (passing it 422s `Expected :uuid`). See
548
603
  `type_naming.md` for the id/slug/name convention.
549
604
 
@@ -805,9 +860,9 @@ downstream resource that names a tool must apply AFTER it.
805
860
  `status: "error"` + non-empty `error_message`. If you see a
806
861
  5xx, file a platform bug, do not retry.
807
862
 
808
- 5. **Standalone vs embedded tool routing differs at list time**
863
+ 5. **Tools list per datalake, not per data source**
809
864
  — `tools.list(tenant, datalake, query?)` returns ALL tools on
810
- the datalake (standalone + embedded). The Flop query
865
+ the datalake, across every data source. The Flop query
811
866
  (type_naming.md) filters on `intent`, `status`, `name`, etc. —
812
867
  but `data_source_id` is NOT in the filterable set, so tools
813
868
  owned by a specific data source must still be filtered
@@ -63,7 +63,7 @@ they are **not** interchangeable as call arguments:
63
63
  id UUID — the API path key for CRUD. `.get` / `.update` /
64
64
  `.delete` on every datalake-scoped resource take the
65
65
  `id`, and cross-resource references (`tool_id`,
66
- `updater_tool_id`, `sender_tool_ids`, …) are `id`s too.
66
+ `updater_tool_id`, `data_source_id`, …) are `id`s too.
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
@@ -105,6 +105,7 @@ await api.tools.get(tenantSlug, datalakeSlug, toolId)
105
105
  // 2b. downstream resources reference the tool by id
106
106
  await api.actionStatusUpdaters.create(tenantSlug, datalakeSlug, {
107
107
  updater_tool_id: toolId,
108
+ data_source_id: dataSourceId, // a data source's id, the same way
108
109
  action_log_config: {
109
110
  type: 'custom',
110
111
  body: '{"external_id": "{{ notification.messageId }}", "status": "delivered"}',
package/dist/index.d.mts CHANGED
@@ -567,6 +567,10 @@ type ActionStatusUpdaterResponse = {
567
567
  * Cron schedule expression (e.g. "*30 * * * *")
568
568
  */
569
569
  cron_expression: string;
570
+ /**
571
+ * The data source whose messages and action logs this updater updates, found by the data source's uri and the vendor's id. An updater without one skips its runs.
572
+ */
573
+ data_source_id: string | null;
570
574
  /**
571
575
  * Datalake ID
572
576
  */
@@ -612,10 +616,6 @@ type ActionStatusUpdaterResponse = {
612
616
  pagination_context_output_schema?: {
613
617
  [key: string]: unknown;
614
618
  } | null;
615
- /**
616
- * IDs of sender tools whose messages this updater monitors
617
- */
618
- sender_tool_ids?: Array<string> | null;
619
619
  /**
620
620
  * Whether this updater may poll. The server sets cycle_detected when a run re-reads events it has already handled, and every later job then fails without calling the provider. Set it back to active to resume polling — nothing else clears it.
621
621
  */
@@ -1446,7 +1446,7 @@ type InvitationResponse = {
1446
1446
  */
1447
1447
  type ToolRequest = {
1448
1448
  /**
1449
- * Data Source ID
1449
+ * Data Source ID. Required for SMS, MMS, email and voice tools: the messages they send carry this data source's uri, which status updaters match on.
1450
1450
  */
1451
1451
  data_source_id?: string | null;
1452
1452
  /**
@@ -1784,10 +1784,13 @@ type ConnectedAppListResponse = {
1784
1784
  /**
1785
1785
  * EmailCallResponse
1786
1786
  *
1787
- * Email tool-call config — Liquid-templated recipient, subject, and body.
1787
+ * Email tool-call config — Liquid-templated recipient, subject, and body. The optional from_name, from_email, and reply_to override the email tool's own sender, field by field.
1788
1788
  */
1789
1789
  type EmailCallResponse = {
1790
1790
  body: SimpleTemplateConfigResponse;
1791
+ from_email?: SimpleTemplateConfigResponse;
1792
+ from_name?: SimpleTemplateConfigResponse;
1793
+ reply_to?: SimpleTemplateConfigResponse;
1791
1794
  subject: SimpleTemplateConfigResponse;
1792
1795
  to: SimpleTemplateConfigResponse;
1793
1796
  };
@@ -3022,7 +3025,7 @@ type ToolResponse = {
3022
3025
  */
3023
3026
  readonly checksum?: string;
3024
3027
  /**
3025
- * Data Source ID
3028
+ * Data Source ID. Required for SMS, MMS, email and voice tools: the messages they send carry this data source's uri, which status updaters match on.
3026
3029
  */
3027
3030
  data_source_id?: string | null;
3028
3031
  /**
@@ -3408,25 +3411,53 @@ type DataActivationClientSharePointExcelCallResponse = SharePointExcelCallRespon
3408
3411
  */
3409
3412
  type EmailResponse = {
3410
3413
  /**
3411
- * AWS access key ID (SES)
3414
+ * AWS access key ID (SES, auth_method access_key)
3412
3415
  */
3413
3416
  access_key_id?: string;
3414
3417
  /**
3415
- * Sending domain (Mailgun)
3418
+ * SES only. The IAM role to assume in the customer's AWS account (auth_method assume_role)
3416
3419
  */
3417
- domain?: string;
3420
+ assume_role_arn?: string;
3418
3421
  /**
3419
- * Custom provider endpoint. Mailgun: the API base URL, which the sending domain is appended to (e.g., https://api.eu.mailgun.net/v3 for EU domains, or a WireMock endpoint for integration tests). SES: the whole request URL (e.g., https://email.us-west-2.amazonaws.com, or http://localhost:4566 for LocalStack). Leave blank for the provider's own endpoint.
3422
+ * SES only. The external id the customer's role requires (auth_method assume_role). Kept as sent; generated when blank.
3420
3423
  */
3421
- endpoint_url?: string | null;
3424
+ assume_role_external_id?: string;
3425
+ /**
3426
+ * SES only. How the tool reaches its AWS account: its own key, the platform's role, or a role in the customer's account. An SES tool saved without one uses its key.
3427
+ */
3428
+ auth_method?: 'access_key' | 'iam_role' | 'assume_role';
3429
+ /**
3430
+ * Liquid template for the body, with the tool's own variables only; used when a workflow action's body renders blank
3431
+ */
3432
+ base_body?: SimpleTemplateConfigResponse | null;
3433
+ /**
3434
+ * Liquid template for the sender address, with the tool's own variables only (tool.name and the tool's settings other than credentials, such as tool.provider, tool.domain, tool.region); rendered and checked when the tool is saved. A workflow action's from_email wins when it renders non-blank.
3435
+ */
3436
+ base_from_email: SimpleTemplateConfigResponse;
3437
+ /**
3438
+ * Liquid template for the sender display name, with the tool's own variables only. A workflow action's from_name wins when it renders non-blank.
3439
+ */
3440
+ base_from_name?: SimpleTemplateConfigResponse | null;
3441
+ /**
3442
+ * Liquid template for the reply-to address, with the tool's own variables only. A workflow action's reply_to wins when it renders non-blank.
3443
+ */
3444
+ base_reply_to?: SimpleTemplateConfigResponse | null;
3445
+ /**
3446
+ * Liquid template for the subject, with the tool's own variables only; used when a workflow action's subject renders blank
3447
+ */
3448
+ base_subject?: SimpleTemplateConfigResponse | null;
3449
+ /**
3450
+ * Liquid template for the recipient address, with the tool's own variables only; used when a workflow action's to renders blank
3451
+ */
3452
+ base_to?: SimpleTemplateConfigResponse | null;
3422
3453
  /**
3423
- * Default sender email address
3454
+ * Sending domain (Mailgun)
3424
3455
  */
3425
- from_email: string;
3456
+ domain?: string;
3426
3457
  /**
3427
- * Default sender display name
3458
+ * Custom provider endpoint. Mailgun: the API base URL, which the sending domain is appended to (e.g., https://api.eu.mailgun.net/v3 for EU domains, or a WireMock endpoint for integration tests). SES: the whole request URL (e.g., https://email.us-west-2.amazonaws.com, or http://localhost:4566 for LocalStack). Leave blank for the provider's own endpoint.
3428
3459
  */
3429
- from_name?: string | null;
3460
+ endpoint_url?: string | null;
3430
3461
  /**
3431
3462
  * ID of the primary Email tool supplying credentials; required when variant_type is variant
3432
3463
  */
@@ -3439,10 +3470,6 @@ type EmailResponse = {
3439
3470
  * AWS region (SES)
3440
3471
  */
3441
3472
  region?: string;
3442
- /**
3443
- * Default reply-to address
3444
- */
3445
- reply_to?: string | null;
3446
3473
  /**
3447
3474
  * SMTP server hostname
3448
3475
  */
@@ -4707,10 +4734,13 @@ type ToolRestapiRequestWritable = RestapiRequestWritable & {
4707
4734
  /**
4708
4735
  * EmailCallRequest
4709
4736
  *
4710
- * Email tool-call config — Liquid-templated recipient, subject, and body. Request
4737
+ * Email tool-call config — Liquid-templated recipient, subject, and body. The optional from_name, from_email, and reply_to override the email tool's own sender, field by field. Request
4711
4738
  */
4712
4739
  type EmailCallRequestWritable = {
4713
4740
  body: SimpleTemplateConfigRequest;
4741
+ from_email?: SimpleTemplateConfigRequest;
4742
+ from_name?: SimpleTemplateConfigRequest;
4743
+ reply_to?: SimpleTemplateConfigRequest;
4714
4744
  subject: SimpleTemplateConfigRequest;
4715
4745
  to: SimpleTemplateConfigRequest;
4716
4746
  };
@@ -4918,7 +4948,7 @@ type ToolRequestWritable = {
4918
4948
  tool_body_type: 'manual_upload';
4919
4949
  } & ToolManualUploadRequest);
4920
4950
  /**
4921
- * Data Source ID
4951
+ * Data Source ID. Required for SMS, MMS, email and voice tools: the messages they send carry this data source's uri, which status updaters match on.
4922
4952
  */
4923
4953
  data_source_id?: string | null;
4924
4954
  /**
@@ -5164,7 +5194,7 @@ type AiAgentRequestWritable = {
5164
5194
  */
5165
5195
  type EmailRequestWritable = {
5166
5196
  /**
5167
- * AWS access key ID (SES)
5197
+ * AWS access key ID (SES, auth_method access_key)
5168
5198
  */
5169
5199
  access_key_id?: string;
5170
5200
  /**
@@ -5172,21 +5202,31 @@ type EmailRequestWritable = {
5172
5202
  */
5173
5203
  api_key?: string;
5174
5204
  /**
5175
- * Sending domain (Mailgun)
5205
+ * SES only. The IAM role to assume in the customer's AWS account (auth_method assume_role)
5176
5206
  */
5177
- domain?: string;
5207
+ assume_role_arn?: string;
5178
5208
  /**
5179
- * Custom provider endpoint. Mailgun: the API base URL, which the sending domain is appended to (e.g., https://api.eu.mailgun.net/v3 for EU domains, or a WireMock endpoint for integration tests). SES: the whole request URL (e.g., https://email.us-west-2.amazonaws.com, or http://localhost:4566 for LocalStack). Leave blank for the provider's own endpoint.
5209
+ * SES only. The external id the customer's role requires (auth_method assume_role). Kept as sent; generated when blank.
5180
5210
  */
5181
- endpoint_url?: string | null;
5211
+ assume_role_external_id?: string;
5182
5212
  /**
5183
- * Default sender email address
5213
+ * SES only. How the tool reaches its AWS account: its own key, the platform's role, or a role in the customer's account. An SES tool saved without one uses its key.
5184
5214
  */
5185
- from_email: string;
5215
+ auth_method?: 'access_key' | 'iam_role' | 'assume_role';
5216
+ base_body?: SimpleTemplateConfigRequest;
5217
+ base_from_email: SimpleTemplateConfigRequest;
5218
+ base_from_name?: SimpleTemplateConfigRequest;
5219
+ base_reply_to?: SimpleTemplateConfigRequest;
5220
+ base_subject?: SimpleTemplateConfigRequest;
5221
+ base_to?: SimpleTemplateConfigRequest;
5186
5222
  /**
5187
- * Default sender display name
5223
+ * Sending domain (Mailgun)
5188
5224
  */
5189
- from_name?: string | null;
5225
+ domain?: string;
5226
+ /**
5227
+ * Custom provider endpoint. Mailgun: the API base URL, which the sending domain is appended to (e.g., https://api.eu.mailgun.net/v3 for EU domains, or a WireMock endpoint for integration tests). SES: the whole request URL (e.g., https://email.us-west-2.amazonaws.com, or http://localhost:4566 for LocalStack). Leave blank for the provider's own endpoint.
5228
+ */
5229
+ endpoint_url?: string | null;
5190
5230
  /**
5191
5231
  * ID of the primary Email tool supplying credentials; required when variant_type is variant
5192
5232
  */
@@ -5200,11 +5240,7 @@ type EmailRequestWritable = {
5200
5240
  */
5201
5241
  region?: string;
5202
5242
  /**
5203
- * Default reply-to address
5204
- */
5205
- reply_to?: string | null;
5206
- /**
5207
- * AWS secret access key (SES)
5243
+ * AWS secret access key (SES, auth_method access_key)
5208
5244
  */
5209
5245
  secret_access_key?: string;
5210
5246
  /**
@@ -6150,6 +6186,10 @@ type ActionStatusUpdaterRequestWritable = {
6150
6186
  * Cron schedule expression (e.g. "*30 * * * *")
6151
6187
  */
6152
6188
  cron_expression: string;
6189
+ /**
6190
+ * The data source whose messages and action logs this updater updates, found by the data source's uri and the vendor's id. An updater without one skips its runs.
6191
+ */
6192
+ data_source_id: string | null;
6153
6193
  /**
6154
6194
  * Datalake ID
6155
6195
  */
@@ -6171,10 +6211,6 @@ type ActionStatusUpdaterRequestWritable = {
6171
6211
  pagination_context_output_schema?: {
6172
6212
  [key: string]: unknown;
6173
6213
  } | null;
6174
- /**
6175
- * IDs of sender tools whose messages this updater monitors
6176
- */
6177
- sender_tool_ids?: Array<string> | null;
6178
6214
  /**
6179
6215
  * Whether this updater may poll. The server sets cycle_detected when a run re-reads events it has already handled, and every later job then fails without calling the provider. Set it back to active to resume polling — nothing else clears it.
6180
6216
  */
@@ -7417,7 +7453,7 @@ interface CreateActionStatusUpdaterRequest {
7417
7453
  updater_type: 'cloud_watch' | 'restapi';
7418
7454
  updater_tool_id: string;
7419
7455
  datalake_id: string;
7420
- sender_tool_ids?: string[] | null;
7456
+ data_source_id: string;
7421
7457
  message_config: TemplateConfig;
7422
7458
  action_log_config: TemplateConfig;
7423
7459
  events_output_schema?: Record<string, unknown> | null;