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

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
@@ -128,14 +128,14 @@ var mapAuthMethod = (slate, m) => ({
128
128
  docs: m.docs ?? []
129
129
  });
130
130
  var getAction = (slate, actionId) => {
131
- let action = slate.actions.find((m) => m.key === actionId);
131
+ let action = (slate.actions ?? []).find((m) => m.key === actionId);
132
132
  if (!action) {
133
133
  throw new import_error2.ServiceError((0, import_error2.notFoundError)(`action`, actionId));
134
134
  }
135
135
  return action;
136
136
  };
137
137
  var getAdapter = (slate, adapterId) => {
138
- let adapter = slate.adapters.find((m) => m.id === adapterId);
138
+ let adapter = (slate.adapters ?? []).find((m) => m.id === adapterId);
139
139
  if (!adapter) {
140
140
  throw new import_error2.ServiceError((0, import_error2.notFoundError)(`adapter`, adapterId));
141
141
  }
@@ -144,7 +144,7 @@ var getAdapter = (slate, adapterId) => {
144
144
  var mapAdapter = (adapter) => ({
145
145
  id: adapter.id,
146
146
  name: adapter.name,
147
- capabilities: adapter.capabilities
147
+ capabilities: adapter.capabilities ?? []
148
148
  });
149
149
  var getActionWithType = (slate, type, actionId) => {
150
150
  let action = getAction(slate, actionId);
@@ -196,7 +196,7 @@ var getMappableAction = (slate, actionId) => {
196
196
  }
197
197
  return action;
198
198
  };
199
- var getExposedActions = (slate, includeAdapterActions) => slate.actions.filter(
199
+ var getExposedActions = (slate, includeAdapterActions) => (slate.actions ?? []).filter(
200
200
  (action) => isMappableTrigger(action) && (includeAdapterActions || !action.adapter)
201
201
  );
202
202
  var getExposedAction = (slate, actionId, includeAdapterActions) => {
@@ -207,13 +207,13 @@ var getExposedAction = (slate, actionId, includeAdapterActions) => {
207
207
  return action;
208
208
  };
209
209
  var getTriggerGroup = (slate, triggerGroupId) => {
210
- let group = slate.triggerGroups.find((g) => g.key === triggerGroupId);
210
+ let group = (slate.triggerGroups ?? []).find((g) => g.key === triggerGroupId);
211
211
  if (!group) {
212
212
  throw new import_error2.ServiceError((0, import_error2.notFoundError)(`trigger_group`, triggerGroupId));
213
213
  }
214
214
  return group;
215
215
  };
216
- var getTriggersForGroup = (slate, triggerGroupId) => slate.actions.filter(
216
+ var getTriggersForGroup = (slate, triggerGroupId) => (slate.actions ?? []).filter(
217
217
  (action) => action.type === "trigger" && action.triggerGroup?.key === triggerGroupId
218
218
  );
219
219
  var getExposedTriggerGroups = (slate, includeAdapterActions) => {
@@ -222,7 +222,7 @@ var getExposedTriggerGroups = (slate, includeAdapterActions) => {
222
222
  (action) => action.type === "trigger" && action.triggerGroup ? [action.triggerGroup.key] : []
223
223
  )
224
224
  );
225
- return slate.triggerGroups.filter((group) => triggerGroupIds.has(group.key));
225
+ return (slate.triggerGroups ?? []).filter((group) => triggerGroupIds.has(group.key));
226
226
  };
227
227
  var evaluateTriggerMatches = (slate, triggerGroupId, payload) => getTriggersForGroup(slate, triggerGroupId).filter((trigger) => trigger.matches(payload)).map((trigger) => trigger.key);
228
228
  var getWebhookAutoRegistration = (group) => {
@@ -1014,7 +1014,7 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
1014
1014
  manager.onRequest("slates/adapters.list", async () => {
1015
1015
  getContextBasic();
1016
1016
  return {
1017
- adapters: supportsAdapters() ? slate.adapters.map(mapAdapter) : []
1017
+ adapters: supportsAdapters() ? (slate.adapters ?? []).map(mapAdapter) : []
1018
1018
  };
1019
1019
  });
1020
1020
  manager.onRequest("slates/adapter.get", async ({ params }) => {
@@ -1222,7 +1222,8 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
1222
1222
  );
1223
1223
  return withRequestTraces(context, {
1224
1224
  targets: res.targets,
1225
- nextPageToken: res.nextPageToken ?? null
1225
+ nextPageToken: res.nextPageToken ?? null,
1226
+ isPartial: res.isPartial ?? false
1226
1227
  });
1227
1228
  });
1228
1229
  manager.onRequest("slates/trigger_group.webhook.register", async ({ params }) => {
@@ -1400,7 +1401,8 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
1400
1401
  },
1401
1402
  onSuccess: (result) => ({
1402
1403
  eventCount: result.events.length,
1403
- hasResponse: result.response !== void 0
1404
+ hasResponse: result.response !== void 0,
1405
+ skipped: !!result.skipped
1404
1406
  })
1405
1407
  },
1406
1408
  () => (0, import_provider2.runWithContext)(context, () => group.webhook.process(context))
@@ -1422,7 +1424,8 @@ var createProviderHandler = (slate, listeners) => (0, import_proto.createSlatesP
1422
1424
  idempotencyKey: event.idempotencyKey,
1423
1425
  triggerIds: evaluateTriggerMatches(slate, group.key, event.payload)
1424
1426
  })),
1425
- response
1427
+ response,
1428
+ skipped: res.skipped ?? null
1426
1429
  });
1427
1430
  });
1428
1431
  manager.onRequest("slates/trigger_group.routing_matchers.get", async ({ params }) => {
@@ -111,14 +111,14 @@ var mapAuthMethod = (slate, m) => ({
111
111
  docs: m.docs ?? []
112
112
  });
113
113
  var getAction = (slate, actionId) => {
114
- let action = slate.actions.find((m) => m.key === actionId);
114
+ let action = (slate.actions ?? []).find((m) => m.key === actionId);
115
115
  if (!action) {
116
116
  throw new ServiceError2(notFoundError(`action`, actionId));
117
117
  }
118
118
  return action;
119
119
  };
120
120
  var getAdapter = (slate, adapterId) => {
121
- let adapter = slate.adapters.find((m) => m.id === adapterId);
121
+ let adapter = (slate.adapters ?? []).find((m) => m.id === adapterId);
122
122
  if (!adapter) {
123
123
  throw new ServiceError2(notFoundError(`adapter`, adapterId));
124
124
  }
@@ -127,7 +127,7 @@ var getAdapter = (slate, adapterId) => {
127
127
  var mapAdapter = (adapter) => ({
128
128
  id: adapter.id,
129
129
  name: adapter.name,
130
- capabilities: adapter.capabilities
130
+ capabilities: adapter.capabilities ?? []
131
131
  });
132
132
  var getActionWithType = (slate, type, actionId) => {
133
133
  let action = getAction(slate, actionId);
@@ -179,7 +179,7 @@ var getMappableAction = (slate, actionId) => {
179
179
  }
180
180
  return action;
181
181
  };
182
- var getExposedActions = (slate, includeAdapterActions) => slate.actions.filter(
182
+ var getExposedActions = (slate, includeAdapterActions) => (slate.actions ?? []).filter(
183
183
  (action) => isMappableTrigger(action) && (includeAdapterActions || !action.adapter)
184
184
  );
185
185
  var getExposedAction = (slate, actionId, includeAdapterActions) => {
@@ -190,13 +190,13 @@ var getExposedAction = (slate, actionId, includeAdapterActions) => {
190
190
  return action;
191
191
  };
192
192
  var getTriggerGroup = (slate, triggerGroupId) => {
193
- let group = slate.triggerGroups.find((g) => g.key === triggerGroupId);
193
+ let group = (slate.triggerGroups ?? []).find((g) => g.key === triggerGroupId);
194
194
  if (!group) {
195
195
  throw new ServiceError2(notFoundError(`trigger_group`, triggerGroupId));
196
196
  }
197
197
  return group;
198
198
  };
199
- var getTriggersForGroup = (slate, triggerGroupId) => slate.actions.filter(
199
+ var getTriggersForGroup = (slate, triggerGroupId) => (slate.actions ?? []).filter(
200
200
  (action) => action.type === "trigger" && action.triggerGroup?.key === triggerGroupId
201
201
  );
202
202
  var getExposedTriggerGroups = (slate, includeAdapterActions) => {
@@ -205,7 +205,7 @@ var getExposedTriggerGroups = (slate, includeAdapterActions) => {
205
205
  (action) => action.type === "trigger" && action.triggerGroup ? [action.triggerGroup.key] : []
206
206
  )
207
207
  );
208
- return slate.triggerGroups.filter((group) => triggerGroupIds.has(group.key));
208
+ return (slate.triggerGroups ?? []).filter((group) => triggerGroupIds.has(group.key));
209
209
  };
210
210
  var evaluateTriggerMatches = (slate, triggerGroupId, payload) => getTriggersForGroup(slate, triggerGroupId).filter((trigger) => trigger.matches(payload)).map((trigger) => trigger.key);
211
211
  var getWebhookAutoRegistration = (group) => {
@@ -997,7 +997,7 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
997
997
  manager.onRequest("slates/adapters.list", async () => {
998
998
  getContextBasic();
999
999
  return {
1000
- adapters: supportsAdapters() ? slate.adapters.map(mapAdapter) : []
1000
+ adapters: supportsAdapters() ? (slate.adapters ?? []).map(mapAdapter) : []
1001
1001
  };
1002
1002
  });
1003
1003
  manager.onRequest("slates/adapter.get", async ({ params }) => {
@@ -1205,7 +1205,8 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
1205
1205
  );
1206
1206
  return withRequestTraces(context, {
1207
1207
  targets: res.targets,
1208
- nextPageToken: res.nextPageToken ?? null
1208
+ nextPageToken: res.nextPageToken ?? null,
1209
+ isPartial: res.isPartial ?? false
1209
1210
  });
1210
1211
  });
1211
1212
  manager.onRequest("slates/trigger_group.webhook.register", async ({ params }) => {
@@ -1383,7 +1384,8 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
1383
1384
  },
1384
1385
  onSuccess: (result) => ({
1385
1386
  eventCount: result.events.length,
1386
- hasResponse: result.response !== void 0
1387
+ hasResponse: result.response !== void 0,
1388
+ skipped: !!result.skipped
1387
1389
  })
1388
1390
  },
1389
1391
  () => runWithContext(context, () => group.webhook.process(context))
@@ -1405,7 +1407,8 @@ var createProviderHandler = (slate, listeners) => createSlatesProviderProtoHandl
1405
1407
  idempotencyKey: event.idempotencyKey,
1406
1408
  triggerIds: evaluateTriggerMatches(slate, group.key, event.payload)
1407
1409
  })),
1408
- response
1410
+ response,
1411
+ skipped: res.skipped ?? null
1409
1412
  });
1410
1413
  });
1411
1414
  manager.onRequest("slates/trigger_group.routing_matchers.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.34",
3
+ "version": "1.0.0-rc.36",
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.20",
36
- "@slates/provider": "1.0.0-rc.24",
35
+ "@slates/proto": "1.0.0-rc.22",
36
+ "@slates/provider": "1.0.0-rc.26",
37
37
  "p-queue": "^6.6.2",
38
38
  "zod": "^4.2.1"
39
39
  },
@@ -158,4 +158,59 @@ describe('adapter capability exposure', () => {
158
158
  }
159
159
  });
160
160
  });
161
+
162
+ it('returns empty adapter and trigger group lists for older slates that omit those collections', async () => {
163
+ let manager = await createProviderHandler(
164
+ {
165
+ spec: { key: 'legacy', name: 'Legacy' },
166
+ actions: [
167
+ {
168
+ key: 'provider_tool',
169
+ type: 'tool',
170
+ name: 'Action',
171
+ description: undefined,
172
+ instructions: undefined,
173
+ constraints: undefined,
174
+ tags: [],
175
+ metadata: {},
176
+ scopes: [],
177
+ authMethods: [],
178
+ docs: [],
179
+ inputSchema: z.object({}),
180
+ outputSchema: z.object({}),
181
+ isPublic: false
182
+ }
183
+ ]
184
+ } as any,
185
+ []
186
+ ).run();
187
+
188
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
189
+ jsonrpc: '2.0',
190
+ method: 'slates/hello',
191
+ params: { protocol: SLATES_PROTOCOL_VERSION }
192
+ });
193
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
194
+ jsonrpc: '2.0',
195
+ method: 'slates/participant.set',
196
+ params: { participants: [] }
197
+ });
198
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
199
+ jsonrpc: '2.0',
200
+ method: 'slates/hub.capabilities.set',
201
+ params: { capabilities: { adapters: true, triggers: true } }
202
+ });
203
+
204
+ expect(await request(manager, 'slates/adapters.list')).toMatchObject({
205
+ result: { adapters: [] }
206
+ });
207
+ expect(await request(manager, 'slates/trigger_groups.list')).toMatchObject({
208
+ result: { triggerGroups: [] }
209
+ });
210
+ expect(
211
+ await request(manager, 'slates/actions.list', { includeAdapterActions: true })
212
+ ).toMatchObject({
213
+ result: { actions: [{ id: 'provider_tool' }] }
214
+ });
215
+ });
161
216
  });
package/src/index.ts CHANGED
@@ -894,7 +894,7 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
894
894
  getContextBasic();
895
895
 
896
896
  return {
897
- adapters: supportsAdapters() ? slate.adapters.map(mapAdapter) : []
897
+ adapters: supportsAdapters() ? (slate.adapters ?? []).map(mapAdapter) : []
898
898
  };
899
899
  });
900
900
 
@@ -1139,7 +1139,8 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
1139
1139
 
1140
1140
  return withRequestTraces(context, {
1141
1141
  targets: res.targets,
1142
- nextPageToken: res.nextPageToken ?? null
1142
+ nextPageToken: res.nextPageToken ?? null,
1143
+ isPartial: res.isPartial ?? false
1143
1144
  });
1144
1145
  });
1145
1146
 
@@ -1336,7 +1337,8 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
1336
1337
  },
1337
1338
  onSuccess: result => ({
1338
1339
  eventCount: result.events.length,
1339
- hasResponse: result.response !== undefined
1340
+ hasResponse: result.response !== undefined,
1341
+ skipped: !!result.skipped
1340
1342
  })
1341
1343
  },
1342
1344
  () => runWithContext(context, () => group.webhook!.process(context))
@@ -1364,7 +1366,8 @@ export let createProviderHandler = <ConfigType extends {}, AuthType extends {}>(
1364
1366
  idempotencyKey: event.idempotencyKey,
1365
1367
  triggerIds: evaluateTriggerMatches(slate, group.key, event.payload)
1366
1368
  })),
1367
- response
1369
+ response,
1370
+ skipped: res.skipped ?? null
1368
1371
  });
1369
1372
  });
1370
1373
 
package/src/spec.test.ts CHANGED
@@ -8,7 +8,8 @@ import {
8
8
  getMappableAction,
9
9
  getTriggersForGroup,
10
10
  isMappableTrigger,
11
- mapAction
11
+ mapAction,
12
+ mapAdapter
12
13
  } from './spec';
13
14
 
14
15
  let baseAction = {
@@ -131,4 +132,16 @@ describe('adapter exposure', () => {
131
132
  expect(getExposedTriggerGroups(slate, false)).toEqual([providerGroup]);
132
133
  expect(getExposedTriggerGroups(slate, true)).toEqual([providerGroup, adapterGroup]);
133
134
  });
135
+
136
+ it('treats missing adapters and trigger groups as empty collections', () => {
137
+ let legacySlate = { actions: [providerTool, providerTrigger] } as any;
138
+
139
+ expect(getExposedActions(legacySlate, true)).toEqual([providerTool, providerTrigger]);
140
+ expect(getExposedTriggerGroups(legacySlate, true)).toEqual([]);
141
+ expect(mapAdapter({ id: 'chat', name: 'Chat' } as any)).toEqual({
142
+ id: 'chat',
143
+ name: 'Chat',
144
+ capabilities: []
145
+ });
146
+ });
134
147
  });
package/src/spec.ts CHANGED
@@ -70,7 +70,7 @@ export let getAction = <ConfigType extends {}, AuthType extends {}>(
70
70
  slate: Slate<ConfigType, AuthType>,
71
71
  actionId: string
72
72
  ) => {
73
- let action = slate.actions.find(m => m.key === actionId);
73
+ let action = (slate.actions ?? []).find(m => m.key === actionId);
74
74
  if (!action) {
75
75
  throw new ServiceError(notFoundError(`action`, actionId));
76
76
  }
@@ -82,7 +82,7 @@ export let getAdapter = <ConfigType extends {}, AuthType extends {}>(
82
82
  slate: Slate<ConfigType, AuthType>,
83
83
  adapterId: string
84
84
  ) => {
85
- let adapter = slate.adapters.find(m => m.id === adapterId);
85
+ let adapter = (slate.adapters ?? []).find(m => m.id === adapterId);
86
86
  if (!adapter) {
87
87
  throw new ServiceError(notFoundError(`adapter`, adapterId));
88
88
  }
@@ -95,7 +95,7 @@ export let mapAdapter = <ConfigType extends {}, AuthType extends {}>(
95
95
  ): SlatesAdapter => ({
96
96
  id: adapter.id,
97
97
  name: adapter.name,
98
- capabilities: adapter.capabilities
98
+ capabilities: adapter.capabilities ?? []
99
99
  });
100
100
 
101
101
  export let getActionWithType = <
@@ -177,7 +177,7 @@ export let getExposedActions = <ConfigType extends {}, AuthType extends {}>(
177
177
  slate: Slate<ConfigType, AuthType>,
178
178
  includeAdapterActions: boolean
179
179
  ) =>
180
- slate.actions.filter(
180
+ (slate.actions ?? []).filter(
181
181
  action => isMappableTrigger(action) && (includeAdapterActions || !action.adapter)
182
182
  );
183
183
 
@@ -198,7 +198,7 @@ export let getTriggerGroup = <ConfigType extends {}, AuthType extends {}>(
198
198
  slate: Slate<ConfigType, AuthType>,
199
199
  triggerGroupId: string
200
200
  ) => {
201
- let group = slate.triggerGroups.find(g => g.key === triggerGroupId);
201
+ let group = (slate.triggerGroups ?? []).find(g => g.key === triggerGroupId);
202
202
  if (!group) {
203
203
  throw new ServiceError(notFoundError(`trigger_group`, triggerGroupId));
204
204
  }
@@ -210,7 +210,7 @@ export let getTriggersForGroup = <ConfigType extends {}, AuthType extends {}>(
210
210
  slate: Slate<ConfigType, AuthType>,
211
211
  triggerGroupId: string
212
212
  ): SlateTrigger<ConfigType, AuthType, any, any>[] =>
213
- slate.actions.filter(
213
+ (slate.actions ?? []).filter(
214
214
  (action): action is SlateTrigger<ConfigType, AuthType, any, any> =>
215
215
  action.type === 'trigger' && action.triggerGroup?.key === triggerGroupId
216
216
  );
@@ -225,7 +225,7 @@ export let getExposedTriggerGroups = <ConfigType extends {}, AuthType extends {}
225
225
  )
226
226
  );
227
227
 
228
- return slate.triggerGroups.filter(group => triggerGroupIds.has(group.key));
228
+ return (slate.triggerGroups ?? []).filter(group => triggerGroupIds.has(group.key));
229
229
  };
230
230
 
231
231
  export let evaluateTriggerMatches = <ConfigType extends {}, AuthType extends {}>(
@@ -0,0 +1,99 @@
1
+ import { SLATES_PROTOCOL_VERSION, SlatesProviderProtoHandlerManager } from '@slates/proto';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { createProviderHandler } from './index';
4
+
5
+ let createManager = async (
6
+ process: () => Promise<{
7
+ events: any[];
8
+ response?: { status?: number; body?: string };
9
+ skipped?: { reason: string };
10
+ }>
11
+ ) => {
12
+ let webhookGroup = {
13
+ key: 'webhook_group',
14
+ name: 'Webhook Group',
15
+ description: undefined,
16
+ metadata: {},
17
+ source: 'webhook',
18
+ webhook: {
19
+ autoRegistration: {
20
+ webhookTargetList: async () => ({ targets: [], nextPageToken: null }),
21
+ webhookRegister: async () => ({
22
+ webhookRegistrationIdentifier: 'reg',
23
+ webhookRegistrationPayload: {}
24
+ }),
25
+ webhookUnregister: async () => {}
26
+ },
27
+ process
28
+ }
29
+ };
30
+ let slate = {
31
+ spec: { key: 'test', name: 'Test' },
32
+ adapters: [],
33
+ actions: [],
34
+ triggerGroups: [webhookGroup]
35
+ };
36
+ let manager = await createProviderHandler(slate as any, []).run();
37
+
38
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
39
+ jsonrpc: '2.0',
40
+ method: 'slates/hello',
41
+ params: { protocol: SLATES_PROTOCOL_VERSION }
42
+ });
43
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
44
+ jsonrpc: '2.0',
45
+ method: 'slates/participant.set',
46
+ params: { participants: [] }
47
+ });
48
+ await SlatesProviderProtoHandlerManager.handleInput(manager, {
49
+ jsonrpc: '2.0',
50
+ method: 'slates/hub.capabilities.set',
51
+ params: { capabilities: { triggers: true } }
52
+ });
53
+
54
+ return manager;
55
+ };
56
+
57
+ let processWebhook = (manager: SlatesProviderProtoHandlerManager) =>
58
+ SlatesProviderProtoHandlerManager.handleInput(manager, {
59
+ jsonrpc: '2.0',
60
+ id: 'process',
61
+ method: 'slates/trigger_group.webhook.process',
62
+ params: {
63
+ triggerGroupId: 'webhook_group',
64
+ url: 'https://hub.example/receive/key',
65
+ method: 'POST',
66
+ headers: {},
67
+ body: null,
68
+ webhookRegistrationPayload: {}
69
+ }
70
+ } as any);
71
+
72
+ describe('slates/trigger_group.webhook.process', () => {
73
+ it('passes the skipped marker through to the hub', async () => {
74
+ let manager = await createManager(async () => ({
75
+ events: [],
76
+ response: { status: 401, body: 'Invalid webhook signature.' },
77
+ skipped: { reason: 'invalid_signature' }
78
+ }));
79
+
80
+ expect(await processWebhook(manager)).toMatchObject({
81
+ result: {
82
+ events: [],
83
+ response: { status: 401 },
84
+ skipped: { reason: 'invalid_signature' }
85
+ }
86
+ });
87
+ });
88
+
89
+ it('reports null skipped when the handler did not skip', async () => {
90
+ let manager = await createManager(async () => ({
91
+ events: [],
92
+ response: { status: 200, body: '' }
93
+ }));
94
+
95
+ expect(await processWebhook(manager)).toMatchObject({
96
+ result: { events: [], skipped: null }
97
+ });
98
+ });
99
+ });