@knocklabs/agent-toolkit 0.1.14 → 0.3.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.
@@ -20,7 +20,23 @@ var KnockTool = (args) => {
20
20
  ...restOfArgs,
21
21
  parameters,
22
22
  fullDescription,
23
- bindExecute: (knockClient, config) => execute(knockClient, config)
23
+ bindExecute: (knockClient, config) => async (input) => {
24
+ try {
25
+ return await execute(knockClient, config)(input);
26
+ } catch (error) {
27
+ console.error(error);
28
+ if (error instanceof Error) {
29
+ return {
30
+ message: `An error occurred with the call to the Knock API: ${error.message}`,
31
+ error
32
+ };
33
+ }
34
+ return {
35
+ message: "An unknown error occurred with the call to the Knock API.",
36
+ error
37
+ };
38
+ }
39
+ }
24
40
  };
25
41
  };
26
42
 
@@ -156,7 +172,9 @@ import { z as z4 } from "zod";
156
172
  function serializeEmailLayoutResponse(emailLayout) {
157
173
  return {
158
174
  key: emailLayout.key,
159
- name: emailLayout.name
175
+ name: emailLayout.name,
176
+ htmlContent: emailLayout.html_layout,
177
+ textContent: emailLayout.text_layout
160
178
  };
161
179
  }
162
180
  var listEmailLayouts = KnockTool({
@@ -180,11 +198,45 @@ var listEmailLayouts = KnockTool({
180
198
  return allEmailLayouts;
181
199
  }
182
200
  });
201
+ var createOrUpdateEmailLayout = KnockTool({
202
+ method: "upsert_email_layout",
203
+ name: "Create or update email layout",
204
+ description: `Create or update a new email layout within the environment given. Use this tool when you need to define shared pieces of content across multiple email templates, like a header/footer. The email layout will be used to render the email template.
205
+
206
+ Here are the rules for creating an email layout:
207
+
208
+ - Every email layout must have a \`{{ content }}\` tag. This is where the content of the email will be injected.
209
+ - You must set both an HTML and text version of the email layout.
210
+ - CSS should be included in the HTML version of the email layout under <style> tags.
211
+ `,
212
+ parameters: z4.object({
213
+ environment: z4.string().optional().describe(
214
+ "(string): The environment to create or update the email layout for. Defaults to `development`."
215
+ ),
216
+ key: z4.string().describe("(string): The key of the email layout to create or update."),
217
+ name: z4.string().describe("(string): The name of the email layout."),
218
+ htmlContent: z4.string().describe("(string): The HTML content of the email layout."),
219
+ textContent: z4.string().describe("(string): The text content of the email layout.")
220
+ }),
221
+ execute: (knockClient, config) => async (params) => {
222
+ const response = await knockClient.emailLayouts.upsert(params.key, {
223
+ environment: params.environment ?? config.environment ?? "development",
224
+ email_layout: {
225
+ name: params.name,
226
+ html_layout: params.htmlContent,
227
+ text_layout: params.textContent
228
+ }
229
+ });
230
+ return serializeEmailLayoutResponse(response.email_layout);
231
+ }
232
+ });
183
233
  var emailLayouts = {
184
- listEmailLayouts
234
+ listEmailLayouts,
235
+ createOrUpdateEmailLayout
185
236
  };
186
237
  var permissions4 = {
187
- read: ["listEmailLayouts"]
238
+ read: ["listEmailLayouts"],
239
+ manage: ["createOrUpdateEmailLayout"]
188
240
  };
189
241
 
190
242
  // src/lib/tools/environments.ts
@@ -215,8 +267,271 @@ var permissions5 = {
215
267
  read: ["listEnvironments"]
216
268
  };
217
269
 
218
- // src/lib/tools/message-types.ts
270
+ // src/lib/tools/guides.ts
271
+ import { z as z6 } from "zod";
272
+
273
+ // src/lib/tools/shared.ts
219
274
  import { z as z5 } from "zod";
275
+ var recipientSchema = z5.union([
276
+ z5.string().describe("A user ID (string)."),
277
+ z5.object({ id: z5.string(), collection: z5.string() }).describe("A reference to an object in a collection.")
278
+ ]).describe(
279
+ "A recipient can be a user ID or a reference to an object in a collection."
280
+ );
281
+ var conditionSchema = z5.object({
282
+ operator: z5.enum([
283
+ "equal_to",
284
+ "not_equal_to",
285
+ "greater_than",
286
+ "less_than",
287
+ "greater_than_or_equal_to",
288
+ "less_than_or_equal_to",
289
+ "contains",
290
+ "not_contains",
291
+ "contains_all",
292
+ "empty",
293
+ "not_empty"
294
+ ]).describe("(string): The operator to apply to the argument."),
295
+ value: z5.any().describe("(any): The value of the condition."),
296
+ argument: z5.string().optional().describe(
297
+ "(string): The argument of the condition. Can be empty when using empty or not_empty operators."
298
+ )
299
+ }).describe("(object): A condition.");
300
+
301
+ // src/lib/tools/guides.ts
302
+ function serializeGuide(guide) {
303
+ return {
304
+ key: guide.key,
305
+ name: guide.name,
306
+ description: guide.description,
307
+ type: guide.type,
308
+ active: guide.active,
309
+ steps: (guide.steps ?? []).map((step) => ({
310
+ ref: step.ref,
311
+ name: step.name,
312
+ schemaKey: step.schema_key,
313
+ schemaVariantKey: step.schema_variant_key,
314
+ schemaContent: step.values
315
+ }))
316
+ };
317
+ }
318
+ var listGuides = KnockTool({
319
+ method: "list_guides",
320
+ name: "List guides",
321
+ description: `
322
+ List all guides available for the given environment. Returns structural information about the guides, including the key, name, description, type, and status.
323
+
324
+ Use this tool when you need to understand which guides are available in the environment.
325
+ `,
326
+ parameters: z6.object({
327
+ environment: z6.string().optional().describe(
328
+ "(string): The environment to list guides for. Defaults to `development`."
329
+ ),
330
+ page_size: z6.number().optional().describe("(number): The number of guides to return per page."),
331
+ after: z6.string().optional().describe("(string): The cursor to use for pagination.")
332
+ }),
333
+ execute: (knockClient, config) => async (params) => {
334
+ const allGuides = [];
335
+ const listParams = {
336
+ environment: params.environment ?? config.environment ?? "development",
337
+ page_size: params.page_size,
338
+ after: params.after
339
+ };
340
+ for await (const guide of knockClient.guides.list(listParams)) {
341
+ allGuides.push(serializeGuide(guide));
342
+ }
343
+ return allGuides;
344
+ }
345
+ });
346
+ var getGuide = KnockTool({
347
+ method: "get_guide",
348
+ name: "Get guide",
349
+ description: `
350
+ Get a guide by its key. Returns structural information about the guide, including the key, name, description, type, and status.
351
+
352
+ Use this tool when you need to retrieve information about a specific guide.
353
+ `,
354
+ parameters: z6.object({
355
+ environment: z6.string().optional().describe(
356
+ "(string): The environment to get the guide for. Defaults to `development`."
357
+ ),
358
+ guideKey: z6.string().describe("(string): The key of the guide to get."),
359
+ hide_uncommitted_changes: z6.boolean().optional().describe(
360
+ "(boolean): Whether to hide uncommitted changes and return only published version."
361
+ )
362
+ }),
363
+ execute: (knockClient, config) => async (params) => {
364
+ const guide = await knockClient.guides.retrieve(params.guideKey, {
365
+ environment: params.environment ?? config.environment ?? "development",
366
+ hide_uncommitted_changes: params.hide_uncommitted_changes
367
+ });
368
+ return serializeGuide(guide);
369
+ }
370
+ });
371
+ var createOrUpdateGuide = KnockTool({
372
+ method: "upsert_guide",
373
+ name: "Upsert guide",
374
+ description: `
375
+ Create or update a guide. A guide defines an in-app guide that can be displayed to users based on priority and other conditions.
376
+
377
+ Use this tool when you need to create a new guide or update an existing one. The guide will be created with the specified configuration.
378
+
379
+ Note: This endpoint only operates on guides in the "development" environment.
380
+
381
+ ## Guide step schema
382
+
383
+ When working with guide steps, you must use a \`schemaKey\` and \`schemaVariantKey\` to reference the message type schema that the step's content conforms to. You can use the \`list_message_types\` tool to get a list of available message types and the available variants for that message type.
384
+
385
+ You **must** supply a \`schemaContent\` that sets the content for each of the fields in the \`fields\` object inside of the message type schema variant you select.
386
+
387
+ For example, if you have a message type schema with a \`fields\` object that looks like this:
388
+
389
+ \`\`\`json
390
+ {
391
+ "fields": {
392
+ "title": {
393
+ "type": "string",
394
+ "required": true
395
+ }
396
+ }
397
+ }
398
+ \`\`\`
399
+
400
+ You would need to supply a \`schemaContent\` that looks like this:
401
+
402
+ \`\`\`json
403
+ {
404
+ "title": "Hello, world!"
405
+ }
406
+ \`\`\`
407
+
408
+ ### Guide targeting
409
+
410
+ By default, a guide will target all users. If you want to target users with specific attributes, you can use \`targetPropertyConditions\` to describe the targeting conditions.
411
+
412
+ When using targeting conditions, you can use the following properties:
413
+
414
+ - \`recipient\`: Use a property on the recipient
415
+ - \`data\`: Use data coming from the application
416
+ - \`tenant\`: Use a property on the tenant
417
+
418
+ For example, if you want to target users with the email \`john.doe@example.com\`, you would supply the following targeting conditions:
419
+
420
+ \`\`\`json
421
+ [
422
+ { "operator": "equal_to", "value": "john.doe@example.com", "argument": "recipient.email" }
423
+ ]
424
+ \`\`\`
425
+
426
+ ### Activation location rules
427
+
428
+ You can supply a list of activation location rules to describe where in your application the guide should be shown. Each activation rule is a directive that describes whether the guide should be shown or hidden based on the pathname of the page.
429
+
430
+ For example, if you want to show the guide on all pages except for the \`admin\` path, you would supply the following activation location rules:
431
+
432
+ \`\`\`json
433
+ [
434
+ { "directive": "allow", "pathname": "*" },
435
+ { "directive": "block", "pathname": "/admin" }
436
+ ]
437
+ \`\`\`
438
+ `,
439
+ parameters: z6.object({
440
+ environment: z6.string().optional().describe(
441
+ "(string): The environment to upsert the guide for. Defaults to `development`."
442
+ ),
443
+ guideKey: z6.string().describe(
444
+ "(string): The key of the guide to upsert. Must be at minimum 3 characters and at maximum 255 characters in length. Must be in the format of ^[a-z0-9_-]+$."
445
+ ),
446
+ name: z6.string().describe(
447
+ "(string): A name for the guide. Must be at maximum 255 characters in length."
448
+ ),
449
+ channelKey: z6.string().optional().describe(
450
+ "(string): The key of the channel in which the guide exists. Defaults to `knock-guide`."
451
+ ).default("knock-guide"),
452
+ description: z6.string().optional().describe(
453
+ "(string): An arbitrary string attached to a guide object. Maximum of 280 characters allowed."
454
+ ),
455
+ step: z6.object({
456
+ name: z6.string().describe("(string): The name of the step.").optional().default("Default"),
457
+ ref: z6.string().describe("(string): The unique identifier of the step.").optional().default("default"),
458
+ schemaKey: z6.string().describe(
459
+ "(string): The key of the schema that the step's content conforms to."
460
+ ),
461
+ schemaVariantKey: z6.string().describe(
462
+ "(string): The key of the schema variant that the step's content conforms to."
463
+ ).optional().default("default"),
464
+ schemaContent: z6.record(z6.string(), z6.any()).describe(
465
+ "(object): A map of values that make up the step's content. Each value must conform to its respective template schema field settings."
466
+ )
467
+ }).describe("(object): The guide step to upsert."),
468
+ targetPropertyConditions: z6.array(conditionSchema).describe(
469
+ "(array): A list of property conditions that describe the target audience for the guide. Conditions are joined as AND operations."
470
+ ),
471
+ activationLocationRules: z6.array(
472
+ z6.object({
473
+ directive: z6.enum(["allow", "block"]).describe(
474
+ "(string): The directive to apply to the activation location rule (allow or block)."
475
+ ),
476
+ pathname: z6.string().describe(
477
+ "(string): The pathname to target. Should correspond to a URI in your application."
478
+ )
479
+ })
480
+ ).describe(
481
+ "(array): A list of activation location rules that describe where in your application the guide should be shown."
482
+ )
483
+ }),
484
+ execute: (knockClient, config) => async (params) => {
485
+ const messageType = await knockClient.messageTypes.retrieve(
486
+ params.step.schemaKey,
487
+ {
488
+ environment: params.environment ?? config.environment ?? "development"
489
+ }
490
+ );
491
+ const schemaVariant = messageType.variants.find(
492
+ (variant) => variant.key === params.step.schemaVariantKey
493
+ );
494
+ if (!schemaVariant) {
495
+ throw new Error(
496
+ `Schema variant ${params.step.schemaVariantKey} not found in message type ${messageType.key}`
497
+ );
498
+ }
499
+ const result = await knockClient.guides.upsert(params.guideKey, {
500
+ environment: params.environment ?? config.environment ?? "development",
501
+ guide: {
502
+ name: params.name,
503
+ description: params.description,
504
+ channel_key: params.channelKey ?? "knock-guide",
505
+ steps: [
506
+ {
507
+ ref: params.step.ref ?? "default",
508
+ schema_key: messageType.key,
509
+ schema_semver: messageType.semver,
510
+ schema_variant_key: schemaVariant.key,
511
+ values: params.step.schemaContent
512
+ }
513
+ ],
514
+ target_property_conditions: {
515
+ all: params.targetPropertyConditions
516
+ },
517
+ activation_location_rules: params.activationLocationRules
518
+ }
519
+ });
520
+ return serializeGuide(result.guide);
521
+ }
522
+ });
523
+ var guides = {
524
+ listGuides,
525
+ getGuide,
526
+ createOrUpdateGuide
527
+ };
528
+ var permissions6 = {
529
+ read: ["listGuides", "getGuide"],
530
+ manage: ["createOrUpdateGuide"]
531
+ };
532
+
533
+ // src/lib/tools/message-types.ts
534
+ import { z as z7 } from "zod";
220
535
  function serializeMessageTypeResponse(messageType) {
221
536
  return {
222
537
  key: messageType.key,
@@ -229,8 +544,8 @@ var listMessageTypes = KnockTool({
229
544
  method: "list_message_types",
230
545
  name: "List message types",
231
546
  description: "List all message types available for the environment. Each message type returns the schema, which includes information about the variants and the fields available per-variant. Use this tool when you need to understand the different message types that are available for the environment for use in Guides.",
232
- parameters: z5.object({
233
- environment: z5.string().optional().describe(
547
+ parameters: z7.object({
548
+ environment: z7.string().optional().describe(
234
549
  "(string): The environment to list message types for. Defaults to `development`."
235
550
  )
236
551
  }),
@@ -245,7 +560,7 @@ var listMessageTypes = KnockTool({
245
560
  }
246
561
  });
247
562
  var createOrUpdateMessageType = KnockTool({
248
- method: "create_or_update_message_type",
563
+ method: "upsert_message_type",
249
564
  name: "Create or update message type",
250
565
  description: `
251
566
  Create or update a message type. A message type is a schema that defines fields available to an editor within Knock. Message types always have at least one variant, that MUST be named "default". Use this tool when you need to create a new message type, or update an existing message type.
@@ -292,29 +607,29 @@ var createOrUpdateMessageType = KnockTool({
292
607
  }
293
608
  </example>
294
609
  `,
295
- parameters: z5.object({
296
- environment: z5.string().optional().describe(
610
+ parameters: z7.object({
611
+ environment: z7.string().optional().describe(
297
612
  "(string): The environment to create or update the message type in. Defaults to `development`."
298
613
  ),
299
- messageTypeKey: z5.string().describe("(string): The key of the message type to create or update."),
300
- name: z5.string().describe("(string): The name of the message type."),
301
- description: z5.string().optional().describe("(string): The description of the message type."),
302
- preview: z5.string().optional().describe(
614
+ messageTypeKey: z7.string().describe("(string): The key of the message type to create or update."),
615
+ name: z7.string().describe("(string): The name of the message type."),
616
+ description: z7.string().optional().describe("(string): The description of the message type."),
617
+ preview: z7.string().optional().describe(
303
618
  "(string): The preview of the variant. This is a string of HTML that will be rendered in the preview of the message type. There is a single preview shared by all variants."
304
619
  ),
305
- variants: z5.array(
306
- z5.object({
307
- key: z5.string().describe("(string): The key of the variant."),
308
- name: z5.string().describe("(string): The name of the variant."),
309
- description: z5.string().optional().describe("(string): The description of the variant."),
310
- fields: z5.array(
311
- z5.object({
312
- key: z5.string().describe("(string): The key of the field."),
313
- type: z5.string().describe(
620
+ variants: z7.array(
621
+ z7.object({
622
+ key: z7.string().describe("(string): The key of the variant."),
623
+ name: z7.string().describe("(string): The name of the variant."),
624
+ description: z7.string().optional().describe("(string): The description of the variant."),
625
+ fields: z7.array(
626
+ z7.object({
627
+ key: z7.string().describe("(string): The key of the field."),
628
+ type: z7.string().describe(
314
629
  "(string): The type of the field. One of `text`, `textarea`, `button`, `markdown`, `select`, `multi_select`, `image`."
315
630
  ),
316
- label: z5.string().describe("(string): The label of the field."),
317
- settings: z5.object({}).optional().describe("(object): The settings of the field.")
631
+ label: z7.string().describe("(string): The label of the field."),
632
+ settings: z7.object({}).optional().describe("(object): The settings of the field.")
318
633
  })
319
634
  ).describe("(array): The fields of the variant.")
320
635
  })
@@ -336,24 +651,24 @@ var messageTypes = {
336
651
  listMessageTypes,
337
652
  createOrUpdateMessageType
338
653
  };
339
- var permissions6 = {
654
+ var permissions7 = {
340
655
  read: ["listMessageTypes"],
341
656
  manage: ["createOrUpdateMessageType"]
342
657
  };
343
658
 
344
659
  // src/lib/tools/messages.ts
345
- import { z as z6 } from "zod";
660
+ import { z as z8 } from "zod";
346
661
  var getMessageContent = KnockTool({
347
662
  method: "get_message_content",
348
663
  name: "Get message content",
349
664
  description: `
350
665
  Retrieves the complete contents of a single message, specified by the messageId. The message contents includes the rendered template that was sent to the recipient. Use this tool when you want to surface information about the emails, SMS, and push notifications that were sent to a user.
351
666
  `,
352
- parameters: z6.object({
353
- environment: z6.string().optional().describe(
667
+ parameters: z8.object({
668
+ environment: z8.string().optional().describe(
354
669
  "(string): The environment to retrieve the message from. Defaults to `development`."
355
670
  ),
356
- messageId: z6.string().describe("(string): The messageId of the message to retrieve.")
671
+ messageId: z8.string().describe("(string): The messageId of the message to retrieve.")
357
672
  }),
358
673
  execute: (knockClient) => async (params) => {
359
674
  const publicClient = await knockClient.publicApi(params.environment);
@@ -363,21 +678,21 @@ var getMessageContent = KnockTool({
363
678
  var messages = {
364
679
  getMessageContent
365
680
  };
366
- var permissions7 = {
681
+ var permissions8 = {
367
682
  read: ["getMessageContent"]
368
683
  };
369
684
 
370
685
  // src/lib/tools/objects.ts
371
- import { z as z7 } from "zod";
686
+ import { z as z9 } from "zod";
372
687
  var listObjects = KnockTool({
373
688
  method: "list_objects",
374
689
  name: "List objects",
375
690
  description: "List all objects in a single collection. Objects are used to model custom collections in Knock that are NOT users or tenants. Use this tool when you need to return a paginated list of objects in a single collection.",
376
- parameters: z7.object({
377
- environment: z7.string().optional().describe(
691
+ parameters: z9.object({
692
+ environment: z9.string().optional().describe(
378
693
  "(string): The environment to list objects from. Defaults to `development`."
379
694
  ),
380
- collection: z7.string().describe("(string): The collection to list objects from.")
695
+ collection: z9.string().describe("(string): The collection to list objects from.")
381
696
  }),
382
697
  execute: (knockClient, _config) => async (params) => {
383
698
  const publicClient = await knockClient.publicApi(params.environment);
@@ -388,12 +703,12 @@ var getObject = KnockTool({
388
703
  method: "get_object",
389
704
  name: "Get object",
390
705
  description: "Get an object wihin a collection. Returns information about the object including any custom properties. Use this tool when you need to retrieve an object to understand it's properties.",
391
- parameters: z7.object({
392
- environment: z7.string().optional().describe(
706
+ parameters: z9.object({
707
+ environment: z9.string().optional().describe(
393
708
  "(string): The environment to get the object from. Defaults to `development`."
394
709
  ),
395
- collection: z7.string().describe("(string): The collection to get the object from."),
396
- objectId: z7.string().describe("(string): The ID of the object to get.")
710
+ collection: z9.string().describe("(string): The collection to get the object from."),
711
+ objectId: z9.string().describe("(string): The ID of the object to get.")
397
712
  }),
398
713
  execute: (knockClient, _config) => async (params) => {
399
714
  const publicClient = await knockClient.publicApi(params.environment);
@@ -401,18 +716,18 @@ var getObject = KnockTool({
401
716
  }
402
717
  });
403
718
  var createOrUpdateObject = KnockTool({
404
- method: "create_or_update_object",
719
+ method: "upsert_object",
405
720
  name: "Create or update object",
406
721
  description: `Create or update an object in a specific collection. Objects are used to model custom collections in Knock that are NOT users or tenants. If the object does not exist, it will be created. If the object exists, it will be updated with the provided properties. The update will always perform an upsert operation, so you do not need to provide the full properties each time.
407
722
 
408
723
  Use this tool when you need to create a new object, or update an existing custom-object. Custom objects can be used to subscribe users' to as lists, and also send non-user facing notifications to.`,
409
- parameters: z7.object({
410
- environment: z7.string().optional().describe(
724
+ parameters: z9.object({
725
+ environment: z9.string().optional().describe(
411
726
  "(string): The environment to create or update the object in. Defaults to `development`."
412
727
  ),
413
- collection: z7.string().describe("(string): The collection to create or update the object in."),
414
- objectId: z7.string().describe("(string): The ID of the object to create or update."),
415
- properties: z7.record(z7.string(), z7.any()).optional().describe("(object): The properties to set on the object.")
728
+ collection: z9.string().describe("(string): The collection to create or update the object in."),
729
+ objectId: z9.string().describe("(string): The ID of the object to create or update."),
730
+ properties: z9.record(z9.string(), z9.any()).optional().describe("(object): The properties to set on the object.")
416
731
  }),
417
732
  execute: (knockClient, _config) => async (params) => {
418
733
  const publicClient = await knockClient.publicApi(params.environment);
@@ -433,13 +748,13 @@ var subscribeUsersToObject = KnockTool({
433
748
 
434
749
  Before using this tool, you should create the object in the collection using the createOrUpdateObject tool.
435
750
  `,
436
- parameters: z7.object({
437
- environment: z7.string().optional().describe(
751
+ parameters: z9.object({
752
+ environment: z9.string().optional().describe(
438
753
  "(string): The environment to subscribe the user to. Defaults to `development`."
439
754
  ),
440
- collection: z7.string().describe("(string): The collection to subscribe the user to."),
441
- objectId: z7.string().describe("(string): The ID of the object to subscribe the user to."),
442
- userIds: z7.array(z7.string()).describe(
755
+ collection: z9.string().describe("(string): The collection to subscribe the user to."),
756
+ objectId: z9.string().describe("(string): The ID of the object to subscribe the user to."),
757
+ userIds: z9.array(z9.string()).describe(
443
758
  "(array): The IDs of the users to subscribe to the object. If not provided, the current user will be subscribed."
444
759
  )
445
760
  }),
@@ -460,13 +775,13 @@ var unsubscribeUsersFromObject = KnockTool({
460
775
  description: `Unsubscribe a list of users from an object in a specific collection. We use this to model lists of users, for pub-sub use cases.
461
776
 
462
777
  Use this tool when you need to unsubscribe one or more users from an object where you will then trigger workflows for those lists of users to send notifications to.`,
463
- parameters: z7.object({
464
- environment: z7.string().optional().describe(
778
+ parameters: z9.object({
779
+ environment: z9.string().optional().describe(
465
780
  "(string): The environment to unsubscribe the user from. Defaults to `development`."
466
781
  ),
467
- collection: z7.string().describe("(string): The collection to unsubscribe the user from."),
468
- objectId: z7.string().describe("(string): The ID of the object to unsubscribe the user from."),
469
- userIds: z7.array(z7.string()).describe(
782
+ collection: z9.string().describe("(string): The collection to unsubscribe the user from."),
783
+ objectId: z9.string().describe("(string): The ID of the object to unsubscribe the user from."),
784
+ userIds: z9.array(z9.string()).describe(
470
785
  "(array): The IDs of the users to unsubscribe from the object."
471
786
  )
472
787
  }),
@@ -488,7 +803,7 @@ var objects = {
488
803
  subscribeUsersToObject,
489
804
  unsubscribeUsersFromObject
490
805
  };
491
- var permissions8 = {
806
+ var permissions9 = {
492
807
  read: ["listObjects", "getObject"],
493
808
  manage: [
494
809
  "createOrUpdateObject",
@@ -498,7 +813,7 @@ var permissions8 = {
498
813
  };
499
814
 
500
815
  // src/lib/tools/partials.ts
501
- import { z as z8 } from "zod";
816
+ import { z as z10 } from "zod";
502
817
  function serializePartial(partial) {
503
818
  return {
504
819
  key: partial.key,
@@ -513,8 +828,8 @@ var listPartials = KnockTool({
513
828
  description: `
514
829
  List all partials within the environment given. Partials provide common building blocks for notification templates. Returns information about the partial, including the name and the key.
515
830
  Use this tool when you need to know the available partials for the environment, like when building a notification template and wanting to use a partial to build the template.`,
516
- parameters: z8.object({
517
- environment: z8.string().optional().describe(
831
+ parameters: z10.object({
832
+ environment: z10.string().optional().describe(
518
833
  "(string): The environment to list partials for. Defaults to `development`."
519
834
  )
520
835
  }),
@@ -534,11 +849,11 @@ var getPartial = KnockTool({
534
849
  description: `
535
850
  Get a partial by its key. Use this tool when you need to know if a specific partial exists by key.
536
851
  `,
537
- parameters: z8.object({
538
- environment: z8.string().optional().describe(
852
+ parameters: z10.object({
853
+ environment: z10.string().optional().describe(
539
854
  "(string): The environment to get the partial for. Defaults to `development`."
540
855
  ),
541
- key: z8.string().describe("(string): The key of the partial to get.")
856
+ key: z10.string().describe("(string): The key of the partial to get.")
542
857
  }),
543
858
  execute: (knockClient, config) => async (params) => {
544
859
  const partial = await knockClient.partials.retrieve(params.key, {
@@ -568,15 +883,15 @@ var createOrUpdatePartial = KnockTool({
568
883
 
569
884
  Changes to a partial MUST be committed before they can be used in a template.
570
885
  `,
571
- parameters: z8.object({
572
- environment: z8.string().optional().describe(
886
+ parameters: z10.object({
887
+ environment: z10.string().optional().describe(
573
888
  "(string): The environment to upsert the partial for. Defaults to `development`."
574
889
  ),
575
- key: z8.string().describe("(string): The key of the partial to upsert."),
576
- name: z8.string().describe("(string): The name of the partial."),
577
- description: z8.string().optional().describe("(string): The description of the partial."),
578
- content: z8.string().describe("(string): The content of the partial."),
579
- type: z8.enum(["html", "text", "json", "markdown"]).describe("(string): The type of the partial.")
890
+ key: z10.string().describe("(string): The key of the partial to upsert."),
891
+ name: z10.string().describe("(string): The name of the partial."),
892
+ description: z10.string().optional().describe("(string): The description of the partial."),
893
+ content: z10.string().describe("(string): The content of the partial."),
894
+ type: z10.enum(["html", "text", "json", "markdown"]).describe("(string): The type of the partial.")
580
895
  }),
581
896
  execute: (knockClient, config) => async (params) => {
582
897
  const partial = await knockClient.partials.upsert(params.key, {
@@ -596,13 +911,13 @@ var partials = {
596
911
  listPartials,
597
912
  createOrUpdatePartial
598
913
  };
599
- var permissions9 = {
914
+ var permissions10 = {
600
915
  read: ["getPartial", "listPartials"],
601
916
  manage: ["createOrUpdatePartial"]
602
917
  };
603
918
 
604
919
  // src/lib/tools/tenants.ts
605
- import { z as z9 } from "zod";
920
+ import { z as z11 } from "zod";
606
921
  var getTenant = KnockTool({
607
922
  method: "get_tenant",
608
923
  name: "Get tenant",
@@ -611,11 +926,11 @@ var getTenant = KnockTool({
611
926
 
612
927
  Use this tool when you need to lookup the information about a tenant, including name, and if there are any custom properties set.
613
928
  `,
614
- parameters: z9.object({
615
- environment: z9.string().optional().describe(
929
+ parameters: z11.object({
930
+ environment: z11.string().optional().describe(
616
931
  "(string): The environment to retrieve the tenant from. Defaults to `development`."
617
932
  ),
618
- tenantId: z9.string().describe("(string): The ID of the tenant to retrieve.")
933
+ tenantId: z11.string().describe("(string): The ID of the tenant to retrieve.")
619
934
  }),
620
935
  execute: (knockClient) => async (params) => {
621
936
  const publicClient = await knockClient.publicApi(params.environment);
@@ -630,8 +945,8 @@ var listTenants = KnockTool({
630
945
 
631
946
  Use this tool when you need to list all tenants in an environment.
632
947
  `,
633
- parameters: z9.object({
634
- environment: z9.string().optional().describe(
948
+ parameters: z11.object({
949
+ environment: z11.string().optional().describe(
635
950
  "(string): The environment to retrieve the tenants from. Defaults to `development`."
636
951
  )
637
952
  }),
@@ -640,21 +955,21 @@ var listTenants = KnockTool({
640
955
  return await publicClient.tenants.list();
641
956
  }
642
957
  });
643
- var setTenant = KnockTool({
644
- method: "set_tenant",
645
- name: "Set tenant",
958
+ var createOrUpdateTenant = KnockTool({
959
+ method: "upsert_tenant",
960
+ name: "Create or update tenant",
646
961
  description: `
647
962
  Creates or updates a tenant using the properties provided. Tenants in Knock are used to model organizations, teams, and other groups of users. They are a special type of object.
648
963
 
649
964
  Use this tool when you need to create a new tenant, or update an existing tenant's properties.
650
965
  `,
651
- parameters: z9.object({
652
- environment: z9.string().optional().describe(
966
+ parameters: z11.object({
967
+ environment: z11.string().optional().describe(
653
968
  "(string): The environment to set the tenant in. Defaults to `development`."
654
969
  ),
655
- tenantId: z9.string().describe("(string): The ID of the tenant to update."),
656
- name: z9.string().optional().describe("(string): The name of the tenant."),
657
- properties: z9.record(z9.string(), z9.any()).optional().describe("(object): The properties to set on the tenant.")
970
+ tenantId: z11.string().describe("(string): The ID of the tenant to update."),
971
+ name: z11.string().optional().describe("(string): The name of the tenant."),
972
+ properties: z11.record(z11.string(), z11.any()).optional().describe("(object): The properties to set on the tenant.")
658
973
  }),
659
974
  execute: (knockClient) => async (params) => {
660
975
  const publicClient = await knockClient.publicApi(params.environment);
@@ -667,30 +982,19 @@ var setTenant = KnockTool({
667
982
  var tenants = {
668
983
  getTenant,
669
984
  listTenants,
670
- setTenant
985
+ createOrUpdateTenant
671
986
  };
672
- var permissions10 = {
987
+ var permissions11 = {
673
988
  read: ["getTenant", "listTenants"],
674
- manage: ["setTenant"]
989
+ manage: ["createOrUpdateTenant"]
675
990
  };
676
991
 
677
992
  // src/lib/tools/users.ts
678
- import { z as z12 } from "zod";
993
+ import { z as z13 } from "zod";
679
994
 
680
995
  // src/lib/tools/workflows-as-tools.ts
681
996
  import jsonSchemaToZod from "json-schema-to-zod";
682
- import { z as z11 } from "zod";
683
-
684
- // src/lib/tools/shared.ts
685
- import { z as z10 } from "zod";
686
- var recipientSchema = z10.union([
687
- z10.string().describe("A user ID (string)."),
688
- z10.object({ id: z10.string(), collection: z10.string() }).describe("A reference to an object in a collection.")
689
- ]).describe(
690
- "A recipient can be a user ID or a reference to an object in a collection."
691
- );
692
-
693
- // src/lib/tools/workflows-as-tools.ts
997
+ import { z as z12 } from "zod";
694
998
  function workflowAsTool(workflow) {
695
999
  return KnockTool({
696
1000
  method: `trigger_${workflow.key.replace("-", "_")}_workflow`,
@@ -700,18 +1004,18 @@ function workflowAsTool(workflow) {
700
1004
  ${workflow.description ? `Additional information to consider on when to use this tool: ${workflow.description}` : ""}
701
1005
 
702
1006
  Returns the workflow run ID, which can be used to lookup messages produced by the workflow.`,
703
- parameters: z11.object({
704
- environment: z11.string().optional(),
1007
+ parameters: z12.object({
1008
+ environment: z12.string().optional(),
705
1009
  actor: recipientSchema.optional().describe("An optional actor to trigger the workflow with."),
706
- recipients: z11.array(recipientSchema).describe(
1010
+ recipients: z12.array(recipientSchema).describe(
707
1011
  "An optional array of recipients to trigger the workflow with."
708
1012
  ).optional(),
709
1013
  // Here we dynamically generate a zod schema from the workflow's `trigger_data_json_schema`
710
1014
  // This allows us to validate the data passed to the workflow
711
1015
  data: workflow.trigger_data_json_schema ? eval(jsonSchemaToZod(workflow.trigger_data_json_schema)).describe(
712
1016
  "The data to pass to the workflow."
713
- ) : z11.record(z11.string(), z11.any()).optional().describe("The data to pass to the workflow."),
714
- tenant: z11.string().optional().describe("The tenant ID to trigger the workflow for.")
1017
+ ) : z12.record(z12.string(), z12.any()).optional().describe("The data to pass to the workflow."),
1018
+ tenant: z12.string().optional().describe("The tenant ID to trigger the workflow for.")
715
1019
  }),
716
1020
  execute: (knockClient, config) => async (params) => {
717
1021
  const publicClient = await knockClient.publicApi(params.environment);
@@ -838,11 +1142,11 @@ var getUser = KnockTool({
838
1142
 
839
1143
  If the userId is not provided, it will use the userId from the config.
840
1144
  `,
841
- parameters: z12.object({
842
- environment: z12.string().optional().describe(
1145
+ parameters: z13.object({
1146
+ environment: z13.string().optional().describe(
843
1147
  "(string): The environment to retrieve the user from. Defaults to `development`."
844
1148
  ),
845
- userId: z12.string().optional().describe("(string): The userId of the User to retrieve.")
1149
+ userId: z13.string().optional().describe("(string): The userId of the User to retrieve.")
846
1150
  }),
847
1151
  execute: (knockClient, config) => async (params) => {
848
1152
  const publicClient = await knockClient.publicApi(params.environment);
@@ -851,7 +1155,7 @@ var getUser = KnockTool({
851
1155
  }
852
1156
  });
853
1157
  var createOrUpdateUser = KnockTool({
854
- method: "create_or_update_user",
1158
+ method: "upsert_user",
855
1159
  name: "Create or update user",
856
1160
  description: `
857
1161
  Creates a new user if they don't exist, or updates the user object for the given userId, including email, name, phone number, and any custom properties.
@@ -860,15 +1164,15 @@ var createOrUpdateUser = KnockTool({
860
1164
 
861
1165
  If the userId is not provided, it will use the userId from the config.
862
1166
  `,
863
- parameters: z12.object({
864
- environment: z12.string().optional().describe(
1167
+ parameters: z13.object({
1168
+ environment: z13.string().optional().describe(
865
1169
  "(string): The environment to create or update the user in. Defaults to `development`."
866
1170
  ),
867
- userId: z12.string().optional().describe("(string): The userId of the User to update."),
868
- email: z12.string().optional().describe("(string): The email of the User to update."),
869
- name: z12.string().optional().describe("(string): The name of the User to update."),
870
- phoneNumber: z12.string().optional().describe("(string): The phone number of the User to update."),
871
- customProperties: z12.record(z12.string(), z12.any()).optional().describe(
1171
+ userId: z13.string().optional().describe("(string): The userId of the User to update."),
1172
+ email: z13.string().optional().describe("(string): The email of the User to update."),
1173
+ name: z13.string().optional().describe("(string): The name of the User to update."),
1174
+ phoneNumber: z13.string().optional().describe("(string): The phone number of the User to update."),
1175
+ customProperties: z13.record(z13.string(), z13.any()).optional().describe(
872
1176
  "(object): A dictionary of custom properties to update for the User."
873
1177
  )
874
1178
  }),
@@ -894,14 +1198,14 @@ var getUserPreferences = KnockTool({
894
1198
 
895
1199
  If the userId is not provided, it will use the userId from the config.
896
1200
  `,
897
- parameters: z12.object({
898
- environment: z12.string().optional().describe(
1201
+ parameters: z13.object({
1202
+ environment: z13.string().optional().describe(
899
1203
  "(string): The environment to retrieve the user preferences from. Defaults to `development`."
900
1204
  ),
901
- userId: z12.string().optional().describe(
1205
+ userId: z13.string().optional().describe(
902
1206
  "(string): The userId of the User to retrieve Preferences for."
903
1207
  ),
904
- preferenceSetId: z12.string().optional().describe(
1208
+ preferenceSetId: z13.string().optional().describe(
905
1209
  "(string): The preferenceSetId of the User to retrieve preferences for. Defaults to `default`."
906
1210
  )
907
1211
  }),
@@ -950,18 +1254,18 @@ var setUserPreferences = KnockTool({
950
1254
  </example>
951
1255
  </examples>
952
1256
  `,
953
- parameters: z12.object({
954
- environment: z12.string().optional().describe(
1257
+ parameters: z13.object({
1258
+ environment: z13.string().optional().describe(
955
1259
  "(string): The environment to set the user preferences in. Defaults to `development`."
956
1260
  ),
957
- userId: z12.string().optional().describe("(string): The userId of the User to update preferences for."),
958
- workflows: z12.record(z12.string(), z12.any()).optional().describe(
1261
+ userId: z13.string().optional().describe("(string): The userId of the User to update preferences for."),
1262
+ workflows: z13.record(z13.string(), z13.any()).optional().describe(
959
1263
  "(object): The workflows to update where the key is the workflow key, and the value of the object is an object that contains a `channel_types` key with a boolean value for each channel type."
960
1264
  ),
961
- categories: z12.record(z12.string(), z12.any()).optional().describe(
1265
+ categories: z13.record(z13.string(), z13.any()).optional().describe(
962
1266
  "(object): The categories to update where the key is the category key, and the value of the object is an object that contains a `channel_types` key with a boolean value for each channel type."
963
1267
  ),
964
- channel_types: z12.record(z12.string(), z12.boolean()).optional().describe(
1268
+ channel_types: z13.record(z13.string(), z13.boolean()).optional().describe(
965
1269
  "(object): The channel types to update where the key is the channel type, and the value of the object is a boolean value."
966
1270
  )
967
1271
  }),
@@ -1002,12 +1306,12 @@ var getUserMessages = KnockTool({
1002
1306
 
1003
1307
  If the userId is not provided, it will use the userId from the config.
1004
1308
  `,
1005
- parameters: z12.object({
1006
- environment: z12.string().optional().describe(
1309
+ parameters: z13.object({
1310
+ environment: z13.string().optional().describe(
1007
1311
  "(string): The environment to retrieve the user messages from. Defaults to `development`."
1008
1312
  ),
1009
- userId: z12.string().optional().describe("(string): The userId of the User to retrieve messages for."),
1010
- workflowRunId: z12.string().optional().describe(
1313
+ userId: z13.string().optional().describe("(string): The userId of the User to retrieve messages for."),
1314
+ workflowRunId: z13.string().optional().describe(
1011
1315
  "(string): The workflowRunId of the User to retrieve. Use this when you want to retrieve messages sent from a workflow trigger."
1012
1316
  )
1013
1317
  }),
@@ -1029,26 +1333,33 @@ var users = {
1029
1333
  setUserPreferences,
1030
1334
  getUserMessages
1031
1335
  };
1032
- var permissions11 = {
1336
+ var permissions12 = {
1033
1337
  read: ["getUser", "getUserMessages", "getUserPreferences"],
1034
1338
  manage: ["createOrUpdateUser", "setUserPreferences"]
1035
1339
  };
1036
1340
 
1037
1341
  // src/lib/tools/workflows.ts
1038
- import { z as z14 } from "zod";
1342
+ import { z as z15 } from "zod";
1039
1343
 
1040
1344
  // src/lib/tools/workflow-steps.ts
1041
- import { z as z13 } from "zod";
1345
+ import { z as z14 } from "zod";
1042
1346
  function generateStepRef(stepType) {
1043
1347
  const randomString = Math.random().toString(36).substring(2, 7).toUpperCase();
1044
1348
  return `${stepType}_${randomString}`;
1045
1349
  }
1046
1350
  async function updateWorkflowWithStep(knockClient, workflow2, step, environment) {
1351
+ let workflowSteps = workflow2.steps;
1352
+ const existingStepIdx = workflow2.steps.findIndex((s) => s.ref === step.ref);
1353
+ if (existingStepIdx !== -1) {
1354
+ workflowSteps[existingStepIdx] = step;
1355
+ } else {
1356
+ workflowSteps.push(step);
1357
+ }
1047
1358
  const workflowParams = {
1048
1359
  environment,
1049
1360
  workflow: {
1050
1361
  ...workflow2,
1051
- steps: [...workflow2.steps, step]
1362
+ steps: workflowSteps
1052
1363
  }
1053
1364
  };
1054
1365
  const result = await knockClient.workflows.upsert(
@@ -1059,7 +1370,9 @@ async function updateWorkflowWithStep(knockClient, workflow2, step, environment)
1059
1370
  }
1060
1371
  var SHARED_PROMPTS = {
1061
1372
  workflow: `
1062
- To use this tool, you MUST first create a workflow using the \`createWorkflow\` tool, or get an existing workflow using the \`getWorkflow\` tool. You ONLY need to pass the workflow key to this tool and the sms step will be added to the end of the workflow's steps array.
1373
+ To use this tool, you MUST first create a workflow using the \`createWorkflow\` tool, or get an existing workflow using the \`getWorkflow\` tool.
1374
+
1375
+ If you are updating an existing step, you can pass the \`stepRef\` parameter to the tool. If you do not pass the \`stepRef\` parameter, a new step will be created and added to the end of the workflow's steps array. You should ONLY pass the \`stepRef\` parameter if you are updating an existing step.
1063
1376
  `,
1064
1377
  liquid: `
1065
1378
  ## Personalization
@@ -1067,7 +1380,7 @@ var SHARED_PROMPTS = {
1067
1380
  If you need to include personalization, you can use liquid to include dynamic content in the email and the subject line.
1068
1381
  The following variables are always available to use in liquid:
1069
1382
 
1070
- - \`recipient.id\`: The ID of the recipient.
1383
+ - \`recipient.id\`: The ID of the recipient.
1071
1384
  - \`recipient.name\`: The name of the recipient.
1072
1385
  - \`recipient.email\`: The email of the recipient.
1073
1386
  - \`recipient.phone_number\`: The phone number of the recipient.
@@ -1077,8 +1390,8 @@ var SHARED_PROMPTS = {
1077
1390
  <example>
1078
1391
  # Hello, {{ recipient.name }}
1079
1392
 
1080
- This is a dynamic message:
1081
-
1393
+ This is a dynamic message:
1394
+
1082
1395
  > {{ data.message }}
1083
1396
  </example>
1084
1397
 
@@ -1091,17 +1404,56 @@ var SHARED_PROMPTS = {
1091
1404
  </example>
1092
1405
  `
1093
1406
  };
1094
- var createEmailStepInWorkflow = KnockTool({
1095
- method: "create_email_step_in_workflow",
1096
- name: "Create email step in workflow",
1407
+ var contentBlockSchema = z14.union([
1408
+ z14.object({
1409
+ type: z14.literal("markdown"),
1410
+ content: z14.string().describe("(string): The markdown content of the block.")
1411
+ }),
1412
+ z14.object({
1413
+ type: z14.literal("html"),
1414
+ content: z14.string().describe("(string): The HTML content of the block.")
1415
+ }),
1416
+ z14.object({
1417
+ type: z14.literal("image"),
1418
+ url: z14.string().describe("(string): The URL of the image.")
1419
+ }),
1420
+ z14.object({
1421
+ type: z14.literal("button_set"),
1422
+ buttons: z14.array(
1423
+ z14.object({
1424
+ label: z14.string().describe("(string): The label of the button."),
1425
+ action: z14.string().describe("(string): The action of the button."),
1426
+ variant: z14.enum(["solid", "outline"]).default("solid").describe(
1427
+ "(enum): The variant of the button. Defaults to `solid`."
1428
+ )
1429
+ })
1430
+ ).describe("(array): The buttons for the button set.")
1431
+ }),
1432
+ z14.object({
1433
+ type: z14.literal("divider")
1434
+ }),
1435
+ z14.object({
1436
+ type: z14.literal("partial"),
1437
+ key: z14.string().describe("(string): The key of the partial to use."),
1438
+ name: z14.string().describe("(string): The name of the partial."),
1439
+ attrs: z14.record(z14.string(), z14.string()).describe(
1440
+ "(object): The attributes for the partial. ALWAYS supply an empty object when you don't know which params are required."
1441
+ )
1442
+ })
1443
+ ]);
1444
+ var createOrUpdateEmailStepInWorkflow = KnockTool({
1445
+ method: "upsert_workflow_email_step",
1446
+ name: "Create or update email step in workflow",
1097
1447
  description: `
1098
- Creates an email step in a workflow. Use this tool when you're asked to create an email notification and you need to specify the content of the email.
1448
+ Creates or updates an email step in a workflow. Use this tool when you're asked to create an email notification and you need to specify the content of the email.
1099
1449
 
1100
1450
  ${SHARED_PROMPTS.workflow}
1101
1451
 
1452
+ When you're asked to create an email step, you can either set the HTML content directly or use blocks to build the email. If you're asked to set the HTML content directly, you can use the \`htmlContent\` parameter. We prefer to use blocks.
1453
+
1102
1454
  ## Blocks
1103
1455
 
1104
- The content of the email is supplied as an array of "blocks". The simplest block is a "markdown" block, which supports content in a markdown format. That should always be your default block type.
1456
+ The content of the email is supplied as an array of "blocks". The simplest block is a "markdown" block, which supports content in a markdown format. That should always be your default block type.
1105
1457
 
1106
1458
  The following block types are supported:
1107
1459
 
@@ -1148,7 +1500,7 @@ Hello, {{ recipient.name }}."
1148
1500
  }
1149
1501
  </example>
1150
1502
 
1151
- ### HTML
1503
+ ### HTML
1152
1504
 
1153
1505
  The \`html\` block supports raw HTML content. This should be used sparingly, and only when you need to include custom HTML content that markdown doesn't support. When using the \`html\` block, you must supply a \`content\` key. HTML content can include liquid personalization.
1154
1506
 
@@ -1194,10 +1546,19 @@ Hello, {{ recipient.name }}."
1194
1546
 
1195
1547
  Unless asked otherwise, you should write content for the email in a concise and formal writing style. Do NOT use complex language or try to over explain. Keep the subject line to 8 words or less.
1196
1548
  `,
1197
- parameters: z13.object({
1198
- workflowKey: z13.string().describe("(string): The key of the workflow to add the step to."),
1199
- blocks: z13.array(z13.any()).describe("(array): The blocks for the email step."),
1200
- subject: z13.string().describe("(string): The subject of the email step.")
1549
+ parameters: z14.object({
1550
+ workflowKey: z14.string().describe("(string): The key of the workflow to add the step to."),
1551
+ stepRef: z14.string().optional().describe(
1552
+ "(string): The reference of the step to update. If not provided, a new step will be created."
1553
+ ),
1554
+ htmlContent: z14.string().describe(
1555
+ "(string): The HTML content of the email template. Use this when not setting blocks."
1556
+ ),
1557
+ blocks: z14.array(contentBlockSchema).describe(
1558
+ "(array): The blocks for the email step. Use this when you don't need to set HTML directly."
1559
+ ),
1560
+ layoutKey: z14.string().describe("(string): The key of the layout to use for the email step."),
1561
+ subject: z14.string().describe("(string): The subject of the email step.")
1201
1562
  }),
1202
1563
  execute: (knockClient, config) => async (params) => {
1203
1564
  const workflow2 = await knockClient.workflows.retrieve(params.workflowKey, {
@@ -1219,30 +1580,34 @@ Hello, {{ recipient.name }}."
1219
1580
  channel_key: emailChannels[0].key,
1220
1581
  template: {
1221
1582
  settings: {
1222
- layout_key: "default"
1583
+ layout_key: params.layoutKey ?? "default"
1223
1584
  },
1224
1585
  subject: params.subject,
1225
- visual_blocks: params.blocks
1586
+ visual_blocks: params.blocks,
1587
+ html_content: params.htmlContent
1226
1588
  },
1227
- ref: generateStepRef("email")
1589
+ ref: params.stepRef ?? generateStepRef("email")
1228
1590
  },
1229
1591
  config.environment ?? "development"
1230
1592
  );
1231
1593
  }
1232
1594
  });
1233
- var createSmsStepInWorkflow = KnockTool({
1234
- method: "create_sms_step_in_workflow",
1235
- name: "Create sms step in workflow",
1595
+ var createOrUpdateSmsStepInWorkflow = KnockTool({
1596
+ method: "upsert_workflow_sms_step",
1597
+ name: "Create or update sms step in workflow",
1236
1598
  description: `
1237
- Creates an SMS step in a workflow. Use this tool when you're asked to create an SMS notification and you need to specify the content of the SMS.
1238
-
1599
+ Creates an SMS step in a workflow. Use this tool when you're asked to create an SMS notification and you need to specify the content of the SMS.
1600
+
1239
1601
  ${SHARED_PROMPTS.workflow}
1240
1602
 
1241
1603
  ${SHARED_PROMPTS.liquid}
1242
1604
  `,
1243
- parameters: z13.object({
1244
- workflowKey: z13.string().describe("(string): The key of the workflow to add the step to."),
1245
- content: z13.string().describe("(string): The content of the SMS.")
1605
+ parameters: z14.object({
1606
+ workflowKey: z14.string().describe("(string): The key of the workflow to add the step to."),
1607
+ stepRef: z14.string().optional().describe(
1608
+ "(string): The reference of the step to update. If not provided, a new step will be created."
1609
+ ),
1610
+ content: z14.string().describe("(string): The content of the SMS.")
1246
1611
  }),
1247
1612
  execute: (knockClient, config) => async (params) => {
1248
1613
  const workflow2 = await knockClient.workflows.retrieve(params.workflowKey, {
@@ -1265,15 +1630,15 @@ var createSmsStepInWorkflow = KnockTool({
1265
1630
  template: {
1266
1631
  text_body: params.content
1267
1632
  },
1268
- ref: generateStepRef("sms")
1633
+ ref: params.stepRef ?? generateStepRef("sms")
1269
1634
  },
1270
1635
  config.environment ?? "development"
1271
1636
  );
1272
1637
  }
1273
1638
  });
1274
- var createPushStepInWorkflow = KnockTool({
1275
- method: "create_push_step_in_workflow",
1276
- name: "Create push step in workflow",
1639
+ var createOrUpdatePushStepInWorkflow = KnockTool({
1640
+ method: "upsert_workflow_push_step",
1641
+ name: "Create or update push step in workflow",
1277
1642
  description: `
1278
1643
  Creates a push step in a workflow. Use this tool when you're asked to create a push notification and you need to specify the content of the push notification.
1279
1644
 
@@ -1283,10 +1648,13 @@ var createPushStepInWorkflow = KnockTool({
1283
1648
 
1284
1649
  Be terse in your writing as this is a push notification and should be direct and to the point.
1285
1650
  `,
1286
- parameters: z13.object({
1287
- workflowKey: z13.string().describe("(string): The key of the workflow to add the step to."),
1288
- title: z13.string().describe("(string): The title of the push notification."),
1289
- content: z13.string().describe("(string): The content (body) of the push notification.")
1651
+ parameters: z14.object({
1652
+ workflowKey: z14.string().describe("(string): The key of the workflow to add the step to."),
1653
+ stepRef: z14.string().optional().describe(
1654
+ "(string): The reference of the step to update. If not provided, a new step will be created."
1655
+ ),
1656
+ title: z14.string().describe("(string): The title of the push notification."),
1657
+ content: z14.string().describe("(string): The content (body) of the push notification.")
1290
1658
  }),
1291
1659
  execute: (knockClient, config) => async (params) => {
1292
1660
  const workflow2 = await knockClient.workflows.retrieve(params.workflowKey, {
@@ -1310,28 +1678,31 @@ var createPushStepInWorkflow = KnockTool({
1310
1678
  title: params.title,
1311
1679
  text_body: params.content
1312
1680
  },
1313
- ref: generateStepRef("push")
1681
+ ref: params.stepRef ?? generateStepRef("push")
1314
1682
  },
1315
1683
  config.environment ?? "development"
1316
1684
  );
1317
1685
  }
1318
1686
  });
1319
- var createInAppFeedStepInWorkflow = KnockTool({
1320
- method: "create_in_app_feed_step_in_workflow",
1321
- name: "Create in app feed step in workflow",
1687
+ var createOrUpdateInAppFeedStepInWorkflow = KnockTool({
1688
+ method: "upsert_workflow_in_app_step",
1689
+ name: "Create or update in app feed step in workflow",
1322
1690
  description: `
1323
- Creates an in app feed step in a workflow. Use this tool when you're asked to create an in app feed notification and you need to specify the content of the in app feed notification.
1691
+ Creates an in app feed step in a workflow. Use this tool when you're asked to create an in app feed notification and you need to specify the content of the in app feed notification.
1324
1692
 
1325
1693
  ${SHARED_PROMPTS.workflow}
1326
1694
 
1327
1695
  ${SHARED_PROMPTS.liquid}
1328
1696
  `,
1329
- parameters: z13.object({
1330
- workflowKey: z13.string().describe("(string): The key of the workflow to add the step to."),
1331
- actionUrl: z13.string().describe(
1697
+ parameters: z14.object({
1698
+ workflowKey: z14.string().describe("(string): The key of the workflow to add the step to."),
1699
+ stepRef: z14.string().optional().describe(
1700
+ "(string): The reference of the step to update. If not provided, a new step will be created."
1701
+ ),
1702
+ actionUrl: z14.string().describe(
1332
1703
  "(string): The URL to navigate to when the in app feed is tapped."
1333
1704
  ),
1334
- body: z13.string().describe("(string): The markdown content of the in app feed.")
1705
+ body: z14.string().describe("(string): The markdown content of the in app feed.")
1335
1706
  }),
1336
1707
  execute: (knockClient, config) => async (params) => {
1337
1708
  const workflow2 = await knockClient.workflows.retrieve(params.workflowKey, {
@@ -1355,15 +1726,15 @@ var createInAppFeedStepInWorkflow = KnockTool({
1355
1726
  action_url: params.actionUrl,
1356
1727
  markdown_body: params.body
1357
1728
  },
1358
- ref: generateStepRef("in_app_feed")
1729
+ ref: params.stepRef ?? generateStepRef("in_app_feed")
1359
1730
  },
1360
1731
  config.environment ?? "development"
1361
1732
  );
1362
1733
  }
1363
1734
  });
1364
- var createChatStepInWorkflow = KnockTool({
1365
- method: "create_chat_step_in_workflow",
1366
- name: "Create chat step in workflow",
1735
+ var createOrUpdateChatStepInWorkflow = KnockTool({
1736
+ method: "upsert_workflow_chat_step",
1737
+ name: "Create or update chat step in workflow",
1367
1738
  description: `
1368
1739
  Creates a chat step in a workflow. Use this tool when you're asked to create a chat, Slack, Discord, or Microsoft Teams notification and you need to specify the content of the chat notification.
1369
1740
 
@@ -1371,9 +1742,12 @@ var createChatStepInWorkflow = KnockTool({
1371
1742
 
1372
1743
  ${SHARED_PROMPTS.liquid}
1373
1744
  `,
1374
- parameters: z13.object({
1375
- workflowKey: z13.string().describe("(string): The key of the workflow to add the step to."),
1376
- body: z13.string().describe("(string): The markdown content of the notification.")
1745
+ parameters: z14.object({
1746
+ workflowKey: z14.string().describe("(string): The key of the workflow to add the step to."),
1747
+ stepRef: z14.string().describe(
1748
+ "(string): The reference of the step to update. If not provided, a new step will be created."
1749
+ ),
1750
+ body: z14.string().describe("(string): The markdown content of the notification.")
1377
1751
  }),
1378
1752
  execute: (knockClient, config) => async (params) => {
1379
1753
  const workflow2 = await knockClient.workflows.retrieve(params.workflowKey, {
@@ -1396,20 +1770,20 @@ var createChatStepInWorkflow = KnockTool({
1396
1770
  template: {
1397
1771
  markdown_body: params.body
1398
1772
  },
1399
- ref: generateStepRef("chat")
1773
+ ref: params.stepRef ?? generateStepRef("chat")
1400
1774
  },
1401
1775
  config.environment ?? "development"
1402
1776
  );
1403
1777
  }
1404
1778
  });
1405
- var createDelayStepInWorkflow = KnockTool({
1406
- method: "create_delay_step_in_workflow",
1407
- name: "Create delay step in workflow",
1779
+ var createOrUpdateDelayStepInWorkflow = KnockTool({
1780
+ method: "upsert_workflow_delay_step",
1781
+ name: "Create or update delay step in workflow",
1408
1782
  description: `
1409
1783
  Creates a delay step in a workflow. Use this tool when you're asked to add a delay to the workflow that pauses, or waits for a period of time before continuing.
1410
1784
 
1411
1785
  ${SHARED_PROMPTS.workflow}
1412
-
1786
+
1413
1787
  Delays are specified in "unit" and "value" pairs. The only valid units are "seconds", "minutes", "hours", and "days".
1414
1788
 
1415
1789
  <example>
@@ -1419,10 +1793,13 @@ var createDelayStepInWorkflow = KnockTool({
1419
1793
  }
1420
1794
  </example>
1421
1795
  `,
1422
- parameters: z13.object({
1423
- workflowKey: z13.string().describe("(string): The key of the workflow to add the step to."),
1424
- delayValue: z13.number().describe("(number): The value of the delay."),
1425
- delayUnit: z13.enum(["seconds", "minutes", "hours", "days"]).describe("(enum): The unit of the delay.")
1796
+ parameters: z14.object({
1797
+ workflowKey: z14.string().describe("(string): The key of the workflow to add the step to."),
1798
+ stepRef: z14.string().optional().describe(
1799
+ "(string): The reference of the step to update. If not provided, a new step will be created."
1800
+ ),
1801
+ delayValue: z14.number().describe("(number): The value of the delay."),
1802
+ delayUnit: z14.enum(["seconds", "minutes", "hours", "days"]).describe("(enum): The unit of the delay.")
1426
1803
  }),
1427
1804
  execute: (knockClient, config) => async (params) => {
1428
1805
  const workflow2 = await knockClient.workflows.retrieve(params.workflowKey, {
@@ -1444,7 +1821,7 @@ var createDelayStepInWorkflow = KnockTool({
1444
1821
  unit: params.delayUnit
1445
1822
  }
1446
1823
  },
1447
- ref: generateStepRef("delay")
1824
+ ref: params.stepRef ?? generateStepRef("delay")
1448
1825
  }
1449
1826
  ]
1450
1827
  }
@@ -1456,9 +1833,9 @@ var createDelayStepInWorkflow = KnockTool({
1456
1833
  return serializeWorkflowResponse(result.workflow);
1457
1834
  }
1458
1835
  });
1459
- var createBatchStepInWorkflow = KnockTool({
1460
- method: "create_batch_step_in_workflow",
1461
- name: "Create batch step in workflow",
1836
+ var createOrUpdateBatchStepInWorkflow = KnockTool({
1837
+ method: "upsert_workflow_batch_step",
1838
+ name: "Create or update batch step in workflow",
1462
1839
  description: `
1463
1840
  Creates a batch step in a workflow. Use this tool when you're asked to create a batch step or asked to add digesting behavior to a workflow. The batch step collects multiple workflow triggers for a single recipient over a period of time and then flushes the content to the next step.
1464
1841
 
@@ -1475,11 +1852,14 @@ var createBatchStepInWorkflow = KnockTool({
1475
1852
  }
1476
1853
  </example>
1477
1854
  `,
1478
- parameters: z13.object({
1479
- workflowKey: z13.string().describe("(string): The key of the workflow to add the step to."),
1480
- batchWindow: z13.object({
1481
- value: z13.number().describe("(number): The value of the batch window."),
1482
- unit: z13.enum(["seconds", "minutes", "hours", "days"]).describe("(enum): The unit of the batch window.")
1855
+ parameters: z14.object({
1856
+ workflowKey: z14.string().describe("(string): The key of the workflow to add the step to."),
1857
+ stepRef: z14.string().optional().describe(
1858
+ "(string): The reference of the step to update. If not provided, a new step will be created."
1859
+ ),
1860
+ batchWindow: z14.object({
1861
+ value: z14.number().describe("(number): The value of the batch window."),
1862
+ unit: z14.enum(["seconds", "minutes", "hours", "days"]).describe("(enum): The unit of the batch window.")
1483
1863
  })
1484
1864
  }),
1485
1865
  execute: (knockClient, config) => async (params) => {
@@ -1498,7 +1878,7 @@ var createBatchStepInWorkflow = KnockTool({
1498
1878
  unit: params.batchWindow.unit
1499
1879
  }
1500
1880
  },
1501
- ref: generateStepRef("batch")
1881
+ ref: params.stepRef ?? generateStepRef("batch")
1502
1882
  },
1503
1883
  config.environment ?? "development"
1504
1884
  );
@@ -1506,14 +1886,14 @@ var createBatchStepInWorkflow = KnockTool({
1506
1886
  });
1507
1887
  var workflowStepTools = {
1508
1888
  // Channel steps
1509
- createEmailStepInWorkflow,
1510
- createSmsStepInWorkflow,
1511
- createPushStepInWorkflow,
1512
- createInAppFeedStepInWorkflow,
1513
- createChatStepInWorkflow,
1889
+ createOrUpdateEmailStepInWorkflow,
1890
+ createOrUpdateSmsStepInWorkflow,
1891
+ createOrUpdatePushStepInWorkflow,
1892
+ createOrUpdateInAppFeedStepInWorkflow,
1893
+ createOrUpdateChatStepInWorkflow,
1514
1894
  // Function steps
1515
- createDelayStepInWorkflow,
1516
- createBatchStepInWorkflow
1895
+ createOrUpdateDelayStepInWorkflow,
1896
+ createOrUpdateBatchStepInWorkflow
1517
1897
  };
1518
1898
 
1519
1899
  // src/lib/tools/workflows.ts
@@ -1526,6 +1906,16 @@ function serializeWorkflowResponse(workflow2) {
1526
1906
  schema: workflow2.trigger_data_json_schema
1527
1907
  };
1528
1908
  }
1909
+ function serializeFullWorkflowResponse(workflow2) {
1910
+ return {
1911
+ key: workflow2.key,
1912
+ name: workflow2.name,
1913
+ description: workflow2.description,
1914
+ categories: workflow2.categories,
1915
+ schema: workflow2.trigger_data_json_schema,
1916
+ steps: workflow2.steps
1917
+ };
1918
+ }
1529
1919
  var listWorkflows = KnockTool({
1530
1920
  method: "list_workflows",
1531
1921
  name: "List workflows",
@@ -1534,8 +1924,8 @@ var listWorkflows = KnockTool({
1534
1924
 
1535
1925
  Use this tool when you need to understand which workflows are available to be called.
1536
1926
  `,
1537
- parameters: z14.object({
1538
- environment: z14.string().optional().describe(
1927
+ parameters: z15.object({
1928
+ environment: z15.string().optional().describe(
1539
1929
  "(string): The environment to list workflows for. Defaults to `development`."
1540
1930
  )
1541
1931
  }),
@@ -1556,17 +1946,17 @@ var getWorkflow = KnockTool({
1556
1946
  description: `
1557
1947
  Get a workflow by key. Returns structural information about the workflow, including the key, name, description, and categories.
1558
1948
  `,
1559
- parameters: z14.object({
1560
- environment: z14.string().optional().describe(
1949
+ parameters: z15.object({
1950
+ environment: z15.string().optional().describe(
1561
1951
  "(string): The environment to get the workflow for. Defaults to `development`."
1562
1952
  ),
1563
- workflowKey: z14.string().describe("(string): The key of the workflow to get.")
1953
+ workflowKey: z15.string().describe("(string): The key of the workflow to get.")
1564
1954
  }),
1565
1955
  execute: (knockClient, config) => async (params) => {
1566
1956
  const workflow2 = await knockClient.workflows.retrieve(params.workflowKey, {
1567
1957
  environment: params.environment ?? config.environment ?? "development"
1568
1958
  });
1569
- return serializeWorkflowResponse(workflow2);
1959
+ return serializeFullWorkflowResponse(workflow2);
1570
1960
  }
1571
1961
  });
1572
1962
  var triggerWorkflow = KnockTool({
@@ -1581,16 +1971,16 @@ var triggerWorkflow = KnockTool({
1581
1971
 
1582
1972
  Returns the workflow run ID, which can be used to lookup messages produced by the workflow.
1583
1973
  `,
1584
- parameters: z14.object({
1585
- environment: z14.string().optional().describe(
1974
+ parameters: z15.object({
1975
+ environment: z15.string().optional().describe(
1586
1976
  "(string): The environment to trigger the workflow in. Defaults to `development`."
1587
1977
  ),
1588
- workflowKey: z14.string().describe("(string): The key of the workflow to trigger."),
1589
- recipients: z14.array(z14.string()).optional().describe(
1978
+ workflowKey: z15.string().describe("(string): The key of the workflow to trigger."),
1979
+ recipients: z15.array(z15.string()).optional().describe(
1590
1980
  "(array): The recipients to trigger the workflow for. This is an array of user IDs."
1591
1981
  ),
1592
- data: z14.record(z14.string(), z14.any()).optional().describe("(object): Data to pass to the workflow."),
1593
- tenant: z14.record(z14.string(), z14.any()).optional().describe(
1982
+ data: z15.record(z15.string(), z15.any()).optional().describe("(object): Data to pass to the workflow."),
1983
+ tenant: z15.record(z15.string(), z15.any()).optional().describe(
1594
1984
  "(object): The tenant to trigger the workflow for. Must contain an id if being sent."
1595
1985
  )
1596
1986
  }),
@@ -1610,16 +2000,16 @@ var createWorkflow = KnockTool({
1610
2000
  description: `
1611
2001
  Create a new workflow, which is used to control the flow of notifications. Use this tool when you're asked to create a new workflow, or you need to create a new workflow before adding a step to it.
1612
2002
  `,
1613
- parameters: z14.object({
1614
- environment: z14.string().optional().describe(
2003
+ parameters: z15.object({
2004
+ environment: z15.string().optional().describe(
1615
2005
  "(string): The environment to create the workflow in. Defaults to `development`."
1616
2006
  ),
1617
- workflowKey: z14.string().describe(
2007
+ workflowKey: z15.string().describe(
1618
2008
  "(string): The key of the workflow to create. Only use a kebab-case string with no spaces or special characters."
1619
2009
  ),
1620
- name: z14.string().describe("(string): The name of the workflow."),
1621
- description: z14.string().describe("(string): The description of the workflow."),
1622
- categories: z14.array(z14.string()).describe("(array): The categories to add to the workflow.")
2010
+ name: z15.string().describe("(string): The name of the workflow."),
2011
+ description: z15.string().describe("(string): The description of the workflow."),
2012
+ categories: z15.array(z15.string()).describe("(array): The categories to add to the workflow.")
1623
2013
  }),
1624
2014
  execute: (knockClient, config) => async (params) => {
1625
2015
  const result = await knockClient.workflows.upsert(params.workflowKey, {
@@ -1648,18 +2038,18 @@ var createOneOffWorkflowSchedule = KnockTool({
1648
2038
  - In one hour, send a password reset email to a user
1649
2039
  - In two weeks, send a survey to a user
1650
2040
  `,
1651
- parameters: z14.object({
1652
- environment: z14.string().optional().describe(
2041
+ parameters: z15.object({
2042
+ environment: z15.string().optional().describe(
1653
2043
  "(string): The environment to create the workflow in. Defaults to `development`."
1654
2044
  ),
1655
- workflowKey: z14.string().describe("(string): The key of the workflow to schedule."),
1656
- userId: z14.string().describe(
2045
+ workflowKey: z15.string().describe("(string): The key of the workflow to schedule."),
2046
+ userId: z15.string().describe(
1657
2047
  "(string): The userId of the user to schedule the workflow for."
1658
2048
  ),
1659
- scheduledAt: z14.string().describe(
2049
+ scheduledAt: z15.string().describe(
1660
2050
  "(string): The date and time to schedule the workflow for. Must be in ISO 8601 format."
1661
2051
  ),
1662
- data: z14.record(z14.string(), z14.any()).optional().describe("(object): Data to pass to the workflow.")
2052
+ data: z15.record(z15.string(), z15.any()).optional().describe("(object): Data to pass to the workflow.")
1663
2053
  }),
1664
2054
  execute: (knockClient, config) => async (params) => {
1665
2055
  const publicClient = await knockClient.publicApi(params.environment);
@@ -1678,7 +2068,7 @@ var workflows = {
1678
2068
  ...workflowStepTools,
1679
2069
  createOneOffWorkflowSchedule
1680
2070
  };
1681
- var permissions12 = {
2071
+ var permissions13 = {
1682
2072
  read: ["listWorkflows", "getWorkflow"],
1683
2073
  manage: [
1684
2074
  "createWorkflow",
@@ -1695,6 +2085,7 @@ var tools = {
1695
2085
  documentation,
1696
2086
  emailLayouts,
1697
2087
  environments,
2088
+ guides,
1698
2089
  messages,
1699
2090
  messageTypes,
1700
2091
  objects,
@@ -1709,6 +2100,7 @@ var allTools = {
1709
2100
  ...documentation,
1710
2101
  ...emailLayouts,
1711
2102
  ...environments,
2103
+ ...guides,
1712
2104
  ...messageTypes,
1713
2105
  ...messages,
1714
2106
  ...objects,
@@ -1723,13 +2115,14 @@ var toolPermissions = {
1723
2115
  documentation: permissions3,
1724
2116
  emailLayouts: permissions4,
1725
2117
  environments: permissions5,
1726
- messages: permissions7,
1727
- messageTypes: permissions6,
1728
- objects: permissions8,
1729
- partials: permissions9,
1730
- tenants: permissions10,
1731
- users: permissions11,
1732
- workflows: permissions12
2118
+ guides: permissions6,
2119
+ messages: permissions8,
2120
+ messageTypes: permissions7,
2121
+ objects: permissions9,
2122
+ partials: permissions10,
2123
+ tenants: permissions11,
2124
+ users: permissions12,
2125
+ workflows: permissions13
1733
2126
  };
1734
2127
 
1735
2128
  export {
@@ -1740,4 +2133,4 @@ export {
1740
2133
  getToolsByPermissionsInCategories,
1741
2134
  getToolMap
1742
2135
  };
1743
- //# sourceMappingURL=chunk-RMUYOYLN.js.map
2136
+ //# sourceMappingURL=chunk-YLJGTJTR.js.map