@slates/provider-handler 1.0.0-rc.39 → 1.0.0-rc.40

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/dist/index.cjs CHANGED
@@ -158,7 +158,7 @@ var getActionWithType = (slate, type, actionId) => {
158
158
  }
159
159
  return action;
160
160
  };
161
- var mapAction = (_slate, a) => {
161
+ var mapAction = (slate, a) => {
162
162
  let base = {
163
163
  id: a.key,
164
164
  name: a.name,
@@ -175,11 +175,13 @@ var mapAction = (_slate, a) => {
175
175
  outputSchema: toJsonSchema(a.outputSchema)
176
176
  };
177
177
  if (a.type === "tool") {
178
+ let toolCategoryIds = slate.getToolCategoryKeys?.(a.key) ?? [];
178
179
  return {
179
180
  ...base,
180
181
  type: "action.tool",
181
182
  capabilities: {},
182
- isPublic: a.isPublic
183
+ isPublic: a.isPublic,
184
+ ...toolCategoryIds.length ? { toolCategoryIds } : {}
183
185
  };
184
186
  }
185
187
  return {
@@ -246,6 +248,20 @@ var getWebhookManualRegistration = (group) => {
246
248
  }
247
249
  return group.webhook.manualRegistration;
248
250
  };
251
+ var mapToolCategory = (category) => ({
252
+ id: category.key,
253
+ name: category.name,
254
+ description: category.description,
255
+ imageUrl: category.imageUrl
256
+ });
257
+ var getExposedToolCategories = (slate, includeAdapterActions) => {
258
+ let exposedCategoryKeys = new Set(
259
+ getExposedActions(slate, includeAdapterActions).filter((action) => action.type === "tool").flatMap((action) => slate.getToolCategoryKeys?.(action.key) ?? [])
260
+ );
261
+ return (slate.toolCategories ?? []).filter(
262
+ (category) => exposedCategoryKeys.has(category.key)
263
+ );
264
+ };
249
265
  var mapTriggerGroup = (group) => ({
250
266
  id: group.key,
251
267
  name: group.name,
@@ -590,7 +606,8 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
590
606
  liveInvocation: true
591
607
  },
592
608
  provider: {
593
- triggerGroups: (slate.triggerGroups?.length ?? 0) > 0 && (slate.actions ?? []).every(isMappableTrigger)
609
+ triggerGroups: (slate.triggerGroups?.length ?? 0) > 0 && (slate.actions ?? []).every(isMappableTrigger),
610
+ toolCategories: (slate.toolCategories?.length ?? 0) > 0
594
611
  }
595
612
  }
596
613
  }));
@@ -1041,6 +1058,14 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
1041
1058
  triggerGroups: getExposedTriggerGroups(slate, supportsAdapters()).map(mapTriggerGroup)
1042
1059
  };
1043
1060
  });
1061
+ manager.onRequest("slates/tool_categories.list", async () => {
1062
+ getContextBasic();
1063
+ return {
1064
+ toolCategories: getExposedToolCategories(slate, supportsAdapters()).map(
1065
+ mapToolCategory
1066
+ )
1067
+ };
1068
+ });
1044
1069
  manager.onRequest("slates/trigger_group.get", async ({ params }) => {
1045
1070
  getContextBasic();
1046
1071
  let triggerGroup = getTriggerGroup(slate, params.triggerGroupId);
@@ -142,7 +142,7 @@ var getActionWithType = (slate, type, actionId) => {
142
142
  }
143
143
  return action;
144
144
  };
145
- var mapAction = (_slate, a) => {
145
+ var mapAction = (slate, a) => {
146
146
  let base = {
147
147
  id: a.key,
148
148
  name: a.name,
@@ -159,11 +159,13 @@ var mapAction = (_slate, a) => {
159
159
  outputSchema: toJsonSchema(a.outputSchema)
160
160
  };
161
161
  if (a.type === "tool") {
162
+ let toolCategoryIds = slate.getToolCategoryKeys?.(a.key) ?? [];
162
163
  return {
163
164
  ...base,
164
165
  type: "action.tool",
165
166
  capabilities: {},
166
- isPublic: a.isPublic
167
+ isPublic: a.isPublic,
168
+ ...toolCategoryIds.length ? { toolCategoryIds } : {}
167
169
  };
168
170
  }
169
171
  return {
@@ -230,6 +232,20 @@ var getWebhookManualRegistration = (group) => {
230
232
  }
231
233
  return group.webhook.manualRegistration;
232
234
  };
235
+ var mapToolCategory = (category) => ({
236
+ id: category.key,
237
+ name: category.name,
238
+ description: category.description,
239
+ imageUrl: category.imageUrl
240
+ });
241
+ var getExposedToolCategories = (slate, includeAdapterActions) => {
242
+ let exposedCategoryKeys = new Set(
243
+ getExposedActions(slate, includeAdapterActions).filter((action) => action.type === "tool").flatMap((action) => slate.getToolCategoryKeys?.(action.key) ?? [])
244
+ );
245
+ return (slate.toolCategories ?? []).filter(
246
+ (category) => exposedCategoryKeys.has(category.key)
247
+ );
248
+ };
233
249
  var mapTriggerGroup = (group) => ({
234
250
  id: group.key,
235
251
  name: group.name,
@@ -574,7 +590,8 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
574
590
  liveInvocation: true
575
591
  },
576
592
  provider: {
577
- triggerGroups: (slate.triggerGroups?.length ?? 0) > 0 && (slate.actions ?? []).every(isMappableTrigger)
593
+ triggerGroups: (slate.triggerGroups?.length ?? 0) > 0 && (slate.actions ?? []).every(isMappableTrigger),
594
+ toolCategories: (slate.toolCategories?.length ?? 0) > 0
578
595
  }
579
596
  }
580
597
  }));
@@ -1025,6 +1042,14 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
1025
1042
  triggerGroups: getExposedTriggerGroups(slate, supportsAdapters()).map(mapTriggerGroup)
1026
1043
  };
1027
1044
  });
1045
+ manager.onRequest("slates/tool_categories.list", async () => {
1046
+ getContextBasic();
1047
+ return {
1048
+ toolCategories: getExposedToolCategories(slate, supportsAdapters()).map(
1049
+ mapToolCategory
1050
+ )
1051
+ };
1052
+ });
1028
1053
  manager.onRequest("slates/trigger_group.get", async ({ params }) => {
1029
1054
  getContextBasic();
1030
1055
  let triggerGroup = getTriggerGroup(slate, params.triggerGroupId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slates/provider-handler",
3
- "version": "1.0.0-rc.39",
3
+ "version": "1.0.0-rc.40",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -32,8 +32,8 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@lowerdeck/error": "^1.1.0",
35
- "@slates/proto": "1.0.0-rc.24",
36
- "@slates/provider": "1.0.0-rc.29",
35
+ "@slates/proto": "1.0.0-rc.25",
36
+ "@slates/provider": "1.0.0-rc.30",
37
37
  "p-queue": "^6.6.2",
38
38
  "zod": "^4.2.1"
39
39
  },
package/src/index.ts CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  getAuthMethod,
31
31
  getExposedAction,
32
32
  getExposedActions,
33
+ getExposedToolCategories,
33
34
  getExposedTriggerGroups,
34
35
  getTriggerGroup,
35
36
  getWebhookAutoRegistration,
@@ -38,6 +39,7 @@ import {
38
39
  mapAction,
39
40
  mapAdapter,
40
41
  mapAuthMethod,
42
+ mapToolCategory,
41
43
  mapTriggerGroup
42
44
  } from './spec';
43
45
  import { State } from './state';
@@ -415,7 +417,8 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
415
417
  provider: {
416
418
  triggerGroups:
417
419
  (slate.triggerGroups?.length ?? 0) > 0 &&
418
- (slate.actions ?? []).every(isMappableTrigger)
420
+ (slate.actions ?? []).every(isMappableTrigger),
421
+ toolCategories: (slate.toolCategories?.length ?? 0) > 0
419
422
  }
420
423
  }
421
424
  }));
@@ -928,6 +931,16 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
928
931
  };
929
932
  });
930
933
 
934
+ manager.onRequest('slates/tool_categories.list', async () => {
935
+ getContextBasic();
936
+
937
+ return {
938
+ toolCategories: getExposedToolCategories(slate, supportsAdapters()).map(
939
+ mapToolCategory
940
+ )
941
+ };
942
+ });
943
+
931
944
  manager.onRequest('slates/trigger_group.get', async ({ params }) => {
932
945
  getContextBasic();
933
946
  let triggerGroup = getTriggerGroup(slate, params.triggerGroupId);
package/src/spec.test.ts CHANGED
@@ -4,13 +4,15 @@ import { z } from 'zod';
4
4
  import {
5
5
  getExposedAction,
6
6
  getExposedActions,
7
+ getExposedToolCategories,
7
8
  getExposedTriggerGroups,
8
9
  getMappableAction,
9
10
  getTriggersForGroup,
10
11
  isMappableTrigger,
11
12
  mapAction,
12
13
  mapAdapter,
13
- mapAuthMethod
14
+ mapAuthMethod,
15
+ mapToolCategory
14
16
  } from './spec';
15
17
 
16
18
  let baseAction = {
@@ -61,6 +63,36 @@ describe('mapAction', () => {
61
63
  let mapped = mapAction({} as any, validTrigger);
62
64
  expect(mapped).toMatchObject({ type: 'action.trigger', triggerGroupId: 'my_group' });
63
65
  });
66
+
67
+ it('includes the tool categories a tool belongs to', () => {
68
+ let slate = { getToolCategoryKeys: () => ['crm', 'reporting'] } as any;
69
+
70
+ expect(mapAction(slate, toolAction)).toMatchObject({
71
+ type: 'action.tool',
72
+ toolCategoryIds: ['crm', 'reporting']
73
+ });
74
+ });
75
+
76
+ it('omits categories for tools without any, including on slates that predate them', () => {
77
+ expect(mapAction({ getToolCategoryKeys: () => [] } as any, toolAction)).not.toHaveProperty(
78
+ 'toolCategoryIds'
79
+ );
80
+ expect(mapAction({} as any, toolAction)).not.toHaveProperty('toolCategoryIds');
81
+ });
82
+ });
83
+
84
+ describe('mapToolCategory', () => {
85
+ it('maps the category key to the protocol id', () => {
86
+ expect(
87
+ mapToolCategory({ key: 'crm', name: 'CRM', description: 'Records' } as any)
88
+ ).toEqual({ id: 'crm', name: 'CRM', description: 'Records', imageUrl: undefined });
89
+ });
90
+
91
+ it('includes the category image when one is set', () => {
92
+ expect(
93
+ mapToolCategory({ key: 'crm', name: 'CRM', imageUrl: 'https://cdn.test/crm.svg' } as any)
94
+ ).toMatchObject({ id: 'crm', imageUrl: 'https://cdn.test/crm.svg' });
95
+ });
64
96
  });
65
97
 
66
98
  describe('getTriggersForGroup', () => {
@@ -129,6 +161,29 @@ describe('adapter exposure', () => {
129
161
  expect(getExposedAction(slate, 'adapter_tool', true)).toBe(adapterTool);
130
162
  });
131
163
 
164
+ it('only exposes tool categories that contain an exposed tool', () => {
165
+ let providerCategory = { key: 'provider_category', name: 'Provider' };
166
+ let adapterCategory = { key: 'adapter_category', name: 'Adapter' };
167
+ let emptyCategory = { key: 'empty_category', name: 'Empty' };
168
+ let categorizedSlate = {
169
+ ...slate,
170
+ toolCategories: [providerCategory, adapterCategory, emptyCategory],
171
+ getToolCategoryKeys: (key: string) =>
172
+ key === 'provider_tool'
173
+ ? ['provider_category']
174
+ : key === 'adapter_tool'
175
+ ? ['adapter_category']
176
+ : []
177
+ } as any;
178
+
179
+ expect(getExposedToolCategories(categorizedSlate, false)).toEqual([providerCategory]);
180
+ expect(getExposedToolCategories(categorizedSlate, true)).toEqual([
181
+ providerCategory,
182
+ adapterCategory
183
+ ]);
184
+ expect(getExposedToolCategories(slate, true)).toEqual([]);
185
+ });
186
+
132
187
  it('only exposes trigger groups that contain an exposed trigger', () => {
133
188
  expect(getExposedTriggerGroups(slate, false)).toEqual([providerGroup]);
134
189
  expect(getExposedTriggerGroups(slate, true)).toEqual([providerGroup, adapterGroup]);
package/src/spec.ts CHANGED
@@ -3,12 +3,14 @@ import type {
3
3
  SlateAuthenticationMethod,
4
4
  SlatesAction,
5
5
  SlateAdapter as SlatesAdapter,
6
+ SlatesToolCategory,
6
7
  SlatesTriggerGroup
7
8
  } from '@slates/proto';
8
9
  import {
9
10
  type Slate,
10
11
  type SlateAdapter,
11
12
  SlateDefaultPollingIntervalSeconds,
13
+ type SlateToolCategory,
12
14
  type SlateTrigger
13
15
  } from '@slates/provider';
14
16
  import z from 'zod';
@@ -124,7 +126,7 @@ export let getActionWithType = <
124
126
  };
125
127
 
126
128
  export let mapAction = <ConfigType extends {}, AuthType extends {}>(
127
- _slate: Slate<ConfigType, AuthType>,
129
+ slate: Slate<ConfigType, AuthType>,
128
130
  a: ReturnType<typeof getAction<ConfigType, AuthType>>
129
131
  ): SlatesAction => {
130
132
  let base = {
@@ -145,11 +147,14 @@ export let mapAction = <ConfigType extends {}, AuthType extends {}>(
145
147
  };
146
148
 
147
149
  if (a.type === 'tool') {
150
+ let toolCategoryIds = slate.getToolCategoryKeys?.(a.key) ?? [];
151
+
148
152
  return {
149
153
  ...base,
150
154
  type: 'action.tool',
151
155
  capabilities: {},
152
- isPublic: a.isPublic
156
+ isPublic: a.isPublic,
157
+ ...(toolCategoryIds.length ? { toolCategoryIds } : {})
153
158
  };
154
159
  }
155
160
 
@@ -269,6 +274,29 @@ export let getWebhookManualRegistration = <ConfigType extends {}, AuthType exten
269
274
  return group.webhook.manualRegistration;
270
275
  };
271
276
 
277
+ export let mapToolCategory = (category: SlateToolCategory): SlatesToolCategory => ({
278
+ id: category.key,
279
+ name: category.name,
280
+ description: category.description,
281
+ imageUrl: category.imageUrl
282
+ });
283
+
284
+ // Like trigger groups, a category is only listed when the hub can see one of its tools.
285
+ export let getExposedToolCategories = <ConfigType extends {}, AuthType extends {}>(
286
+ slate: Slate<ConfigType, AuthType>,
287
+ includeAdapterActions: boolean
288
+ ) => {
289
+ let exposedCategoryKeys = new Set(
290
+ getExposedActions(slate, includeAdapterActions)
291
+ .filter(action => action.type === 'tool')
292
+ .flatMap(action => slate.getToolCategoryKeys?.(action.key) ?? [])
293
+ );
294
+
295
+ return (slate.toolCategories ?? []).filter(category =>
296
+ exposedCategoryKeys.has(category.key)
297
+ );
298
+ };
299
+
272
300
  export let mapTriggerGroup = <ConfigType extends {}, AuthType extends {}>(
273
301
  group: ReturnType<typeof getTriggerGroup<ConfigType, AuthType>>
274
302
  ): SlatesTriggerGroup => ({