@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 +30 -5
- package/dist/index.module.js +36 -6
- package/package.json +4 -4
- package/src/exposure.test.ts +161 -0
- package/src/index.ts +21 -10
- package/src/spec.test.ts +52 -1
- package/src/spec.ts +38 -2
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 =
|
|
984
|
-
|
|
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 =
|
|
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.
|
|
1040
|
+
triggerGroups: getExposedTriggerGroups(slate, supportsAdapters()).map(mapTriggerGroup)
|
|
1016
1041
|
};
|
|
1017
1042
|
});
|
|
1018
1043
|
manager.onRequest("slates/trigger_group.get", async ({ params }) => {
|
package/dist/index.module.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import {
|
|
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 =
|
|
962
|
-
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
36
|
-
"@slates/provider": "1.0.0-rc.
|
|
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 {
|
|
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
|
-
|
|
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 =
|
|
871
|
-
|
|
872
|
-
|
|
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 =
|
|
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.
|
|
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 {
|
|
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
|
-
|
|
12
|
-
|
|
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,
|