@slates/provider-handler 1.0.0-rc.32 → 1.0.0-rc.34

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
@@ -112,6 +112,7 @@ var mapAuthMethod = (slate, m) => ({
112
112
  title: s.title,
113
113
  description: s.description
114
114
  })) : void 0,
115
+ adapters: "adapters" in m ? m.adapters : void 0,
115
116
  inputSchema: toJsonSchema(m.inputSchema ?? import_zod.default.object({})),
116
117
  outputSchema: toJsonSchema(slate.spec.auth.outputSchema),
117
118
  capabilities: {
@@ -195,6 +196,16 @@ var getMappableAction = (slate, actionId) => {
195
196
  }
196
197
  return action;
197
198
  };
199
+ var getExposedActions = (slate, includeAdapterActions) => slate.actions.filter(
200
+ (action) => isMappableTrigger(action) && (includeAdapterActions || !action.adapter)
201
+ );
202
+ var getExposedAction = (slate, actionId, includeAdapterActions) => {
203
+ let action = getMappableAction(slate, actionId);
204
+ if (action.adapter && !includeAdapterActions) {
205
+ throw new import_error2.ServiceError((0, import_error2.notFoundError)(`action`, actionId));
206
+ }
207
+ return action;
208
+ };
198
209
  var getTriggerGroup = (slate, triggerGroupId) => {
199
210
  let group = slate.triggerGroups.find((g) => g.key === triggerGroupId);
200
211
  if (!group) {
@@ -205,6 +216,14 @@ var getTriggerGroup = (slate, triggerGroupId) => {
205
216
  var getTriggersForGroup = (slate, triggerGroupId) => slate.actions.filter(
206
217
  (action) => action.type === "trigger" && action.triggerGroup?.key === triggerGroupId
207
218
  );
219
+ var getExposedTriggerGroups = (slate, includeAdapterActions) => {
220
+ let triggerGroupIds = new Set(
221
+ getExposedActions(slate, includeAdapterActions).flatMap(
222
+ (action) => action.type === "trigger" && action.triggerGroup ? [action.triggerGroup.key] : []
223
+ )
224
+ );
225
+ return slate.triggerGroups.filter((group) => triggerGroupIds.has(group.key));
226
+ };
208
227
  var evaluateTriggerMatches = (slate, triggerGroupId, payload) => getTriggersForGroup(slate, triggerGroupId).filter((trigger) => trigger.matches(payload)).map((trigger) => trigger.key);
209
228
  var getWebhookAutoRegistration = (group) => {
210
229
  if (group.source !== "webhook" || !group.webhook?.autoRegistration) {
@@ -427,6 +446,7 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
427
446
  };
428
447
  };
429
448
  let supportsTriggerGroups = () => !!hubCapabilities.get()?.triggers;
449
+ let supportsAdapters = () => !!hubCapabilities.get()?.adapters;
430
450
  let logger = new import_provider2.SlateLogger(listeners);
431
451
  let providerTrace = {
432
452
  providerId: slate.spec.key,
@@ -980,8 +1000,10 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
980
1000
  });
981
1001
  manager.onRequest("slates/actions.list", async ({ params }) => {
982
1002
  getContextBasic();
983
- let actions = params.includeAdapterActions ? slate.actions : slate.actions.filter((action) => !action.adapter);
984
- actions = actions.filter(isMappableTrigger);
1003
+ let actions = getExposedActions(
1004
+ slate,
1005
+ !!params.includeAdapterActions && supportsAdapters()
1006
+ );
985
1007
  if (!supportsTriggerGroups()) {
986
1008
  actions = actions.filter((action) => action.type !== "trigger");
987
1009
  }
@@ -992,11 +1014,14 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
992
1014
  manager.onRequest("slates/adapters.list", async () => {
993
1015
  getContextBasic();
994
1016
  return {
995
- adapters: slate.adapters.map(mapAdapter)
1017
+ adapters: supportsAdapters() ? slate.adapters.map(mapAdapter) : []
996
1018
  };
997
1019
  });
998
1020
  manager.onRequest("slates/adapter.get", async ({ params }) => {
999
1021
  getContextBasic();
1022
+ if (!supportsAdapters()) {
1023
+ throw new import_error4.ServiceError((0, import_error4.notFoundError)(`adapter`, params.adapterId));
1024
+ }
1000
1025
  let adapter = getAdapter(slate, params.adapterId);
1001
1026
  return {
1002
1027
  adapter: mapAdapter(adapter)
@@ -1004,7 +1029,7 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
1004
1029
  });
1005
1030
  manager.onRequest("slates/action.get", async ({ params }) => {
1006
1031
  getContextBasic();
1007
- let action = getMappableAction(slate, params.actionId);
1032
+ let action = getExposedAction(slate, params.actionId, supportsAdapters());
1008
1033
  return {
1009
1034
  action: mapAction(slate, action)
1010
1035
  };
@@ -1012,7 +1037,7 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
1012
1037
  manager.onRequest("slates/trigger_groups.list", async () => {
1013
1038
  getContextBasic();
1014
1039
  return {
1015
- triggerGroups: slate.triggerGroups.map(mapTriggerGroup)
1040
+ triggerGroups: getExposedTriggerGroups(slate, supportsAdapters()).map(mapTriggerGroup)
1016
1041
  };
1017
1042
  });
1018
1043
  manager.onRequest("slates/trigger_group.get", async ({ params }) => {
@@ -1,5 +1,10 @@
1
1
  // src/index.ts
2
- import { badRequestError as badRequestError3, preconditionFailedError, ServiceError as ServiceError4 } from "@lowerdeck/error";
2
+ import {
3
+ badRequestError as badRequestError3,
4
+ notFoundError as notFoundError2,
5
+ preconditionFailedError,
6
+ ServiceError as ServiceError4
7
+ } from "@lowerdeck/error";
3
8
  import {
4
9
  createSlatesProviderProtoHandler,
5
10
  SLATES_PROTOCOL_VERSION
@@ -90,6 +95,7 @@ var mapAuthMethod = (slate, m) => ({
90
95
  title: s.title,
91
96
  description: s.description
92
97
  })) : void 0,
98
+ adapters: "adapters" in m ? m.adapters : void 0,
93
99
  inputSchema: toJsonSchema(m.inputSchema ?? z.object({})),
94
100
  outputSchema: toJsonSchema(slate.spec.auth.outputSchema),
95
101
  capabilities: {
@@ -173,6 +179,16 @@ var getMappableAction = (slate, actionId) => {
173
179
  }
174
180
  return action;
175
181
  };
182
+ var getExposedActions = (slate, includeAdapterActions) => slate.actions.filter(
183
+ (action) => isMappableTrigger(action) && (includeAdapterActions || !action.adapter)
184
+ );
185
+ var getExposedAction = (slate, actionId, includeAdapterActions) => {
186
+ let action = getMappableAction(slate, actionId);
187
+ if (action.adapter && !includeAdapterActions) {
188
+ throw new ServiceError2(notFoundError(`action`, actionId));
189
+ }
190
+ return action;
191
+ };
176
192
  var getTriggerGroup = (slate, triggerGroupId) => {
177
193
  let group = slate.triggerGroups.find((g) => g.key === triggerGroupId);
178
194
  if (!group) {
@@ -183,6 +199,14 @@ var getTriggerGroup = (slate, triggerGroupId) => {
183
199
  var getTriggersForGroup = (slate, triggerGroupId) => slate.actions.filter(
184
200
  (action) => action.type === "trigger" && action.triggerGroup?.key === triggerGroupId
185
201
  );
202
+ var getExposedTriggerGroups = (slate, includeAdapterActions) => {
203
+ let triggerGroupIds = new Set(
204
+ getExposedActions(slate, includeAdapterActions).flatMap(
205
+ (action) => action.type === "trigger" && action.triggerGroup ? [action.triggerGroup.key] : []
206
+ )
207
+ );
208
+ return slate.triggerGroups.filter((group) => triggerGroupIds.has(group.key));
209
+ };
186
210
  var evaluateTriggerMatches = (slate, triggerGroupId, payload) => getTriggersForGroup(slate, triggerGroupId).filter((trigger) => trigger.matches(payload)).map((trigger) => trigger.key);
187
211
  var getWebhookAutoRegistration = (group) => {
188
212
  if (group.source !== "webhook" || !group.webhook?.autoRegistration) {
@@ -405,6 +429,7 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
405
429
  };
406
430
  };
407
431
  let supportsTriggerGroups = () => !!hubCapabilities.get()?.triggers;
432
+ let supportsAdapters = () => !!hubCapabilities.get()?.adapters;
408
433
  let logger = new SlateLogger(listeners);
409
434
  let providerTrace = {
410
435
  providerId: slate.spec.key,
@@ -958,8 +983,10 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
958
983
  });
959
984
  manager.onRequest("slates/actions.list", async ({ params }) => {
960
985
  getContextBasic();
961
- let actions = params.includeAdapterActions ? slate.actions : slate.actions.filter((action) => !action.adapter);
962
- actions = actions.filter(isMappableTrigger);
986
+ let actions = getExposedActions(
987
+ slate,
988
+ !!params.includeAdapterActions && supportsAdapters()
989
+ );
963
990
  if (!supportsTriggerGroups()) {
964
991
  actions = actions.filter((action) => action.type !== "trigger");
965
992
  }
@@ -970,11 +997,14 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
970
997
  manager.onRequest("slates/adapters.list", async () => {
971
998
  getContextBasic();
972
999
  return {
973
- adapters: slate.adapters.map(mapAdapter)
1000
+ adapters: supportsAdapters() ? slate.adapters.map(mapAdapter) : []
974
1001
  };
975
1002
  });
976
1003
  manager.onRequest("slates/adapter.get", async ({ params }) => {
977
1004
  getContextBasic();
1005
+ if (!supportsAdapters()) {
1006
+ throw new ServiceError4(notFoundError2(`adapter`, params.adapterId));
1007
+ }
978
1008
  let adapter = getAdapter(slate, params.adapterId);
979
1009
  return {
980
1010
  adapter: mapAdapter(adapter)
@@ -982,7 +1012,7 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
982
1012
  });
983
1013
  manager.onRequest("slates/action.get", async ({ params }) => {
984
1014
  getContextBasic();
985
- let action = getMappableAction(slate, params.actionId);
1015
+ let action = getExposedAction(slate, params.actionId, supportsAdapters());
986
1016
  return {
987
1017
  action: mapAction(slate, action)
988
1018
  };
@@ -990,7 +1020,7 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
990
1020
  manager.onRequest("slates/trigger_groups.list", async () => {
991
1021
  getContextBasic();
992
1022
  return {
993
- triggerGroups: slate.triggerGroups.map(mapTriggerGroup)
1023
+ triggerGroups: getExposedTriggerGroups(slate, supportsAdapters()).map(mapTriggerGroup)
994
1024
  };
995
1025
  });
996
1026
  manager.onRequest("slates/trigger_group.get", async ({ params }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slates/provider-handler",
3
- "version": "1.0.0-rc.32",
3
+ "version": "1.0.0-rc.34",
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.19",
36
- "@slates/provider": "1.0.0-rc.23",
35
+ "@slates/proto": "1.0.0-rc.20",
36
+ "@slates/provider": "1.0.0-rc.24",
37
37
  "p-queue": "^6.6.2",
38
38
  "zod": "^4.2.1"
39
39
  },
@@ -43,4 +43,4 @@
43
43
  "typescript": "5.8.2",
44
44
  "vitest": "^3.1.2"
45
45
  }
46
- }
46
+ }
@@ -0,0 +1,161 @@
1
+ import { SLATES_PROTOCOL_VERSION, SlatesProviderProtoHandlerManager } from '@slates/proto';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { z } from 'zod';
4
+ import { createProviderHandler } from './index';
5
+
6
+ let createManager = async () => {
7
+ let providerGroup = {
8
+ key: 'provider_group',
9
+ name: 'Provider Group',
10
+ description: undefined,
11
+ metadata: {},
12
+ source: 'polling',
13
+ polling: { intervalSeconds: 60 }
14
+ };
15
+ let adapterGroup = {
16
+ key: 'adapter_group',
17
+ name: 'Adapter Group',
18
+ description: undefined,
19
+ metadata: {},
20
+ source: 'polling',
21
+ polling: { intervalSeconds: 60 }
22
+ };
23
+ let emptyGroup = {
24
+ key: 'empty_group',
25
+ name: 'Empty Group',
26
+ description: undefined,
27
+ metadata: {},
28
+ source: 'polling',
29
+ polling: { intervalSeconds: 60 }
30
+ };
31
+ let action = {
32
+ name: 'Action',
33
+ description: undefined,
34
+ instructions: undefined,
35
+ constraints: undefined,
36
+ tags: [],
37
+ metadata: {},
38
+ scopes: [],
39
+ authMethods: [],
40
+ docs: [],
41
+ inputSchema: z.object({}),
42
+ outputSchema: z.object({}),
43
+ matches: () => true,
44
+ map: async () => ({ type: 'event', output: {} })
45
+ };
46
+ let slate = {
47
+ spec: { key: 'test', name: 'Test' },
48
+ adapters: [{ id: 'chat', name: 'Chat', capabilities: [] }],
49
+ actions: [
50
+ { ...action, key: 'provider_tool', type: 'tool', isPublic: false },
51
+ {
52
+ ...action,
53
+ key: 'adapter_tool',
54
+ type: 'tool',
55
+ adapter: 'chat',
56
+ isPublic: false
57
+ },
58
+ { ...action, key: 'provider_trigger', type: 'trigger', triggerGroup: providerGroup },
59
+ {
60
+ ...action,
61
+ key: 'adapter_trigger',
62
+ type: 'trigger',
63
+ adapter: 'chat',
64
+ triggerGroup: adapterGroup
65
+ }
66
+ ],
67
+ triggerGroups: [providerGroup, adapterGroup, emptyGroup]
68
+ };
69
+ let manager = await createProviderHandler(slate as any, []).run();
70
+
71
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
72
+ jsonrpc: '2.0',
73
+ method: 'slates/hello',
74
+ params: { protocol: SLATES_PROTOCOL_VERSION }
75
+ });
76
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
77
+ jsonrpc: '2.0',
78
+ method: 'slates/participant.set',
79
+ params: { participants: [] }
80
+ });
81
+
82
+ return manager;
83
+ };
84
+
85
+ let request = async (
86
+ manager: SlatesProviderProtoHandlerManager,
87
+ method:
88
+ | 'slates/actions.list'
89
+ | 'slates/action.get'
90
+ | 'slates/adapters.list'
91
+ | 'slates/adapter.get'
92
+ | 'slates/trigger_groups.list',
93
+ params: Record<string, unknown> = {}
94
+ ) =>
95
+ SlatesProviderProtoHandlerManager.handleInput(manager, {
96
+ jsonrpc: '2.0',
97
+ id: method,
98
+ method,
99
+ params
100
+ } as any);
101
+
102
+ describe('adapter capability exposure', () => {
103
+ it('hides adapter surfaces from a legacy hub that only supports triggers', async () => {
104
+ let manager = await createManager();
105
+
106
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
107
+ jsonrpc: '2.0',
108
+ method: 'slates/hub.capabilities.set',
109
+ params: { capabilities: { triggers: true } }
110
+ });
111
+
112
+ expect(await request(manager, 'slates/adapters.list')).toMatchObject({
113
+ result: { adapters: [] }
114
+ });
115
+ expect(
116
+ await request(manager, 'slates/actions.list', { includeAdapterActions: true })
117
+ ).toMatchObject({
118
+ result: { actions: [{ id: 'provider_tool' }, { id: 'provider_trigger' }] }
119
+ });
120
+ expect(await request(manager, 'slates/trigger_groups.list')).toMatchObject({
121
+ result: { triggerGroups: [{ id: 'provider_group' }] }
122
+ });
123
+ expect(await request(manager, 'slates/adapter.get', { adapterId: 'chat' })).toHaveProperty(
124
+ 'error'
125
+ );
126
+ expect(
127
+ await request(manager, 'slates/action.get', { actionId: 'adapter_tool' })
128
+ ).toHaveProperty('error');
129
+ });
130
+
131
+ it('exposes adapters and their actions when the hub enables them', async () => {
132
+ let manager = await createManager();
133
+
134
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
135
+ jsonrpc: '2.0',
136
+ method: 'slates/hub.capabilities.set',
137
+ params: { capabilities: { adapters: true, triggers: true } }
138
+ });
139
+
140
+ expect(await request(manager, 'slates/adapters.list')).toMatchObject({
141
+ result: { adapters: [{ id: 'chat' }] }
142
+ });
143
+ expect(
144
+ await request(manager, 'slates/actions.list', { includeAdapterActions: true })
145
+ ).toMatchObject({
146
+ result: {
147
+ actions: [
148
+ { id: 'provider_tool' },
149
+ { id: 'adapter_tool' },
150
+ { id: 'provider_trigger' },
151
+ { id: 'adapter_trigger' }
152
+ ]
153
+ }
154
+ });
155
+ expect(await request(manager, 'slates/trigger_groups.list')).toMatchObject({
156
+ result: {
157
+ triggerGroups: [{ id: 'provider_group' }, { id: 'adapter_group' }]
158
+ }
159
+ });
160
+ });
161
+ });
package/src/index.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { badRequestError, preconditionFailedError, ServiceError } from '@lowerdeck/error';
1
+ import {
2
+ badRequestError,
3
+ notFoundError,
4
+ preconditionFailedError,
5
+ ServiceError
6
+ } from '@lowerdeck/error';
2
7
  import {
3
8
  createSlatesProviderProtoHandler,
4
9
  SLATES_PROTOCOL_VERSION,
@@ -22,7 +27,9 @@ import {
22
27
  getActionWithType,
23
28
  getAdapter,
24
29
  getAuthMethod,
25
- getMappableAction,
30
+ getExposedAction,
31
+ getExposedActions,
32
+ getExposedTriggerGroups,
26
33
  getTriggerGroup,
27
34
  getWebhookAutoRegistration,
28
35
  getWebhookManualRegistration,
@@ -191,6 +198,7 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
191
198
 
192
199
  let hubCapabilities = new State<{
193
200
  attachments?: { directUpload?: { enabled: boolean; maxAttachmentSizeBytes?: number } };
201
+ adapters?: boolean;
194
202
  triggers?: boolean;
195
203
  } | null>(null);
196
204
  let liveInvocation = new State<Pick<SlateLiveInvocationInfo, 'token' | 'baseUrl'> | null>(
@@ -211,6 +219,7 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
211
219
  };
212
220
 
213
221
  let supportsTriggerGroups = () => !!hubCapabilities.get()?.triggers;
222
+ let supportsAdapters = () => !!hubCapabilities.get()?.adapters;
214
223
 
215
224
  let logger = new SlateLogger(listeners);
216
225
  let providerTrace = {
@@ -867,11 +876,10 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
867
876
  manager.onRequest('slates/actions.list', async ({ params }) => {
868
877
  getContextBasic();
869
878
 
870
- let actions = params.includeAdapterActions
871
- ? slate.actions
872
- : slate.actions.filter(action => !action.adapter);
873
-
874
- actions = actions.filter(isMappableTrigger);
879
+ let actions = getExposedActions(
880
+ slate,
881
+ !!params.includeAdapterActions && supportsAdapters()
882
+ );
875
883
 
876
884
  if (!supportsTriggerGroups()) {
877
885
  actions = actions.filter(action => action.type !== 'trigger');
@@ -886,12 +894,15 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
886
894
  getContextBasic();
887
895
 
888
896
  return {
889
- adapters: slate.adapters.map(mapAdapter)
897
+ adapters: supportsAdapters() ? slate.adapters.map(mapAdapter) : []
890
898
  };
891
899
  });
892
900
 
893
901
  manager.onRequest('slates/adapter.get', async ({ params }) => {
894
902
  getContextBasic();
903
+ if (!supportsAdapters()) {
904
+ throw new ServiceError(notFoundError(`adapter`, params.adapterId));
905
+ }
895
906
  let adapter = getAdapter(slate, params.adapterId);
896
907
 
897
908
  return {
@@ -901,7 +912,7 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
901
912
 
902
913
  manager.onRequest('slates/action.get', async ({ params }) => {
903
914
  getContextBasic();
904
- let action = getMappableAction(slate, params.actionId);
915
+ let action = getExposedAction(slate, params.actionId, supportsAdapters());
905
916
 
906
917
  return {
907
918
  action: mapAction(slate, action)
@@ -912,7 +923,7 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
912
923
  getContextBasic();
913
924
 
914
925
  return {
915
- triggerGroups: slate.triggerGroups.map(mapTriggerGroup)
926
+ triggerGroups: getExposedTriggerGroups(slate, supportsAdapters()).map(mapTriggerGroup)
916
927
  };
917
928
  });
918
929
 
package/src/spec.test.ts CHANGED
@@ -1,7 +1,15 @@
1
1
  import { isServiceError } from '@lowerdeck/error';
2
2
  import { describe, expect, it } from 'vitest';
3
3
  import { z } from 'zod';
4
- import { getMappableAction, getTriggersForGroup, isMappableTrigger, mapAction } from './spec';
4
+ import {
5
+ getExposedAction,
6
+ getExposedActions,
7
+ getExposedTriggerGroups,
8
+ getMappableAction,
9
+ getTriggersForGroup,
10
+ isMappableTrigger,
11
+ mapAction
12
+ } from './spec';
5
13
 
6
14
  let baseAction = {
7
15
  key: 'do_thing',
@@ -81,3 +89,46 @@ describe('getMappableAction', () => {
81
89
  }
82
90
  });
83
91
  });
92
+
93
+ describe('adapter exposure', () => {
94
+ let providerTool: any = { ...toolAction, key: 'provider_tool' };
95
+ let adapterTool: any = { ...toolAction, key: 'adapter_tool', adapter: 'chat' };
96
+ let providerGroup = { key: 'provider_group', name: 'Provider Group' };
97
+ let adapterGroup = { key: 'adapter_group', name: 'Adapter Group' };
98
+ let emptyGroup = { key: 'empty_group', name: 'Empty Group' };
99
+ let providerTrigger: any = {
100
+ ...validTrigger,
101
+ key: 'provider_trigger',
102
+ triggerGroup: providerGroup
103
+ };
104
+ let adapterTrigger: any = {
105
+ ...validTrigger,
106
+ key: 'adapter_trigger',
107
+ adapter: 'chat',
108
+ triggerGroup: adapterGroup
109
+ };
110
+ let slate = {
111
+ actions: [providerTool, adapterTool, providerTrigger, adapterTrigger],
112
+ triggerGroups: [providerGroup, adapterGroup, emptyGroup]
113
+ } as any;
114
+
115
+ it('only exposes adapter actions when adapters are enabled', () => {
116
+ expect(getExposedActions(slate, false)).toEqual([providerTool, providerTrigger]);
117
+ expect(getExposedActions(slate, true)).toEqual([
118
+ providerTool,
119
+ adapterTool,
120
+ providerTrigger,
121
+ adapterTrigger
122
+ ]);
123
+ });
124
+
125
+ it('does not expose an adapter action directly when adapters are disabled', () => {
126
+ expect(() => getExposedAction(slate, 'adapter_tool', false)).toThrow();
127
+ expect(getExposedAction(slate, 'adapter_tool', true)).toBe(adapterTool);
128
+ });
129
+
130
+ it('only exposes trigger groups that contain an exposed trigger', () => {
131
+ expect(getExposedTriggerGroups(slate, false)).toEqual([providerGroup]);
132
+ expect(getExposedTriggerGroups(slate, true)).toEqual([providerGroup, adapterGroup]);
133
+ });
134
+ });
package/src/spec.ts CHANGED
@@ -8,8 +8,8 @@ import type {
8
8
  import {
9
9
  type Slate,
10
10
  type SlateAdapter,
11
- type SlateTrigger,
12
- SlateDefaultPollingIntervalSeconds
11
+ SlateDefaultPollingIntervalSeconds,
12
+ type SlateTrigger
13
13
  } from '@slates/provider';
14
14
  import z from 'zod';
15
15
  import { toJsonSchema } from './validation';
@@ -47,6 +47,8 @@ export let mapAuthMethod = <ConfigType extends {}, AuthType extends {}>(
47
47
  }))
48
48
  : undefined,
49
49
 
50
+ adapters: 'adapters' in m ? m.adapters : undefined,
51
+
50
52
  inputSchema: toJsonSchema(m.inputSchema ?? z.object({})),
51
53
  outputSchema: toJsonSchema(slate.spec.auth.outputSchema),
52
54
 
@@ -171,6 +173,27 @@ export let getMappableAction = <ConfigType extends {}, AuthType extends {}>(
171
173
  return action;
172
174
  };
173
175
 
176
+ export let getExposedActions = <ConfigType extends {}, AuthType extends {}>(
177
+ slate: Slate<ConfigType, AuthType>,
178
+ includeAdapterActions: boolean
179
+ ) =>
180
+ slate.actions.filter(
181
+ action => isMappableTrigger(action) && (includeAdapterActions || !action.adapter)
182
+ );
183
+
184
+ export let getExposedAction = <ConfigType extends {}, AuthType extends {}>(
185
+ slate: Slate<ConfigType, AuthType>,
186
+ actionId: string,
187
+ includeAdapterActions: boolean
188
+ ) => {
189
+ let action = getMappableAction(slate, actionId);
190
+ if (action.adapter && !includeAdapterActions) {
191
+ throw new ServiceError(notFoundError(`action`, actionId));
192
+ }
193
+
194
+ return action;
195
+ };
196
+
174
197
  export let getTriggerGroup = <ConfigType extends {}, AuthType extends {}>(
175
198
  slate: Slate<ConfigType, AuthType>,
176
199
  triggerGroupId: string
@@ -192,6 +215,19 @@ export let getTriggersForGroup = <ConfigType extends {}, AuthType extends {}>(
192
215
  action.type === 'trigger' && action.triggerGroup?.key === triggerGroupId
193
216
  );
194
217
 
218
+ export let getExposedTriggerGroups = <ConfigType extends {}, AuthType extends {}>(
219
+ slate: Slate<ConfigType, AuthType>,
220
+ includeAdapterActions: boolean
221
+ ) => {
222
+ let triggerGroupIds = new Set(
223
+ getExposedActions(slate, includeAdapterActions).flatMap(action =>
224
+ action.type === 'trigger' && action.triggerGroup ? [action.triggerGroup.key] : []
225
+ )
226
+ );
227
+
228
+ return slate.triggerGroups.filter(group => triggerGroupIds.has(group.key));
229
+ };
230
+
195
231
  export let evaluateTriggerMatches = <ConfigType extends {}, AuthType extends {}>(
196
232
  slate: Slate<ConfigType, AuthType>,
197
233
  triggerGroupId: string,