@credal/actions 0.2.147 → 0.2.149

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.
@@ -22,24 +22,37 @@ class SlackUserCache {
22
22
  constructor(client) {
23
23
  this.client = client;
24
24
  this.cache = new Map();
25
+ this.pendingRequests = new Map();
25
26
  this.client = client;
26
27
  }
27
28
  get(id) {
28
29
  return __awaiter(this, void 0, void 0, function* () {
29
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
30
30
  const cached = this.cache.get(id);
31
31
  if (cached)
32
32
  return cached;
33
- const res = yield this.client.users.info({ user: id });
34
- const u = {
35
- name: (_g = (_e = (_c = (_b = (_a = res.user) === null || _a === void 0 ? void 0 : _a.profile) === null || _b === void 0 ? void 0 : _b.display_name) !== null && _c !== void 0 ? _c : (_d = res.user) === null || _d === void 0 ? void 0 : _d.real_name) !== null && _e !== void 0 ? _e : (_f = res.user) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : "",
36
- email: (_k = (_j = (_h = res.user) === null || _h === void 0 ? void 0 : _h.profile) === null || _j === void 0 ? void 0 : _j.email) !== null && _k !== void 0 ? _k : "",
37
- };
38
- if (res.user && id) {
39
- this.cache.set(id, u);
40
- return u;
41
- }
42
- return undefined;
33
+ const pending = this.pendingRequests.get(id);
34
+ if (pending)
35
+ return pending;
36
+ const promise = (() => __awaiter(this, void 0, void 0, function* () {
37
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
38
+ try {
39
+ const res = yield this.client.users.info({ user: id });
40
+ const u = {
41
+ name: (_g = (_e = (_c = (_b = (_a = res.user) === null || _a === void 0 ? void 0 : _a.profile) === null || _b === void 0 ? void 0 : _b.display_name) !== null && _c !== void 0 ? _c : (_d = res.user) === null || _d === void 0 ? void 0 : _d.real_name) !== null && _e !== void 0 ? _e : (_f = res.user) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : "",
42
+ email: (_k = (_j = (_h = res.user) === null || _h === void 0 ? void 0 : _h.profile) === null || _j === void 0 ? void 0 : _j.email) !== null && _k !== void 0 ? _k : "",
43
+ };
44
+ if (res.user && id) {
45
+ this.cache.set(id, u);
46
+ return u;
47
+ }
48
+ return undefined;
49
+ }
50
+ finally {
51
+ this.pendingRequests.delete(id);
52
+ }
53
+ }))();
54
+ this.pendingRequests.set(id, promise);
55
+ return promise;
43
56
  });
44
57
  }
45
58
  set(id, { email, name }) {
@@ -238,44 +251,58 @@ const searchSlack = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params,
238
251
  const targetIds = (emails === null || emails === void 0 ? void 0 : emails.length) ? yield lookupUserIdsByEmail(client, emails, cache) : [];
239
252
  const filteredTargetIds = targetIds.filter(id => id !== myUserId);
240
253
  const allMatches = [];
241
- // --- Scoped DM/MPIM searches ---
254
+ // --- Parallel search execution for better performance ---
255
+ const searchPromises = [];
256
+ // Scoped DM/MPIM searches
242
257
  if (filteredTargetIds.length === 1) {
243
- allMatches.push(...(yield searchScoped({ client, scope: `<@${filteredTargetIds[0]}>`, topic, timeRange, limit })));
258
+ searchPromises.push(searchScoped({ client, scope: `<@${filteredTargetIds[0]}>`, topic, timeRange, limit }));
244
259
  }
245
260
  else if (filteredTargetIds.length >= 2) {
246
- const mpimName = yield tryGetMPIMName(client, filteredTargetIds);
247
- if (mpimName) {
248
- allMatches.push(...(yield searchScoped({ client, scope: mpimName, topic, timeRange, limit })));
249
- }
250
- for (const id of filteredTargetIds) {
251
- allMatches.push(...(yield searchScoped({ client, scope: `<@${id}>`, topic, timeRange, limit })));
252
- }
261
+ // Run MPIM lookup and individual DM searches in parallel
262
+ const searchMPIM = () => __awaiter(void 0, void 0, void 0, function* () {
263
+ const mpimName = yield tryGetMPIMName(client, filteredTargetIds);
264
+ return mpimName ? searchScoped({ client, scope: mpimName, topic, timeRange, limit }) : [];
265
+ });
266
+ searchPromises.push(searchMPIM());
267
+ // Add individual DM searches
268
+ searchPromises.push(...filteredTargetIds.map(id => searchScoped({ client, scope: `<@${id}>`, topic, timeRange, limit })));
253
269
  }
254
270
  else if (channel) {
255
- allMatches.push(...(yield searchScoped({ client, scope: normalizeChannelOperand(channel), topic, timeRange, limit })));
271
+ searchPromises.push(searchScoped({ client, scope: normalizeChannelOperand(channel), topic, timeRange, limit }));
256
272
  }
257
- // --- Topic-wide search ---
258
- const topicMatches = topic ? yield searchByTopic({ client, topic, timeRange, limit }) : [];
259
- allMatches.push(...topicMatches);
273
+ // Topic-wide search in parallel
274
+ searchPromises.push(...(topic ? [searchByTopic({ client, topic, timeRange, limit })] : []));
275
+ // Execute all searches in parallel
276
+ const searchResults = yield Promise.all(searchPromises);
277
+ searchResults.forEach(matches => allMatches.push(...matches));
260
278
  // --- Expand hits with context + filter overlap ---
279
+ // Create a channel info cache to avoid redundant API calls
280
+ const channelInfoCache = new Map();
261
281
  const expanded = yield Promise.all(allMatches.map(m => limitHit(() => __awaiter(void 0, void 0, void 0, function* () {
262
- var _a, _b, _c, _d, _e, _f;
282
+ var _a, _b, _c, _d, _e, _f, _g, _h;
263
283
  if (!m.ts || !((_a = m.channel) === null || _a === void 0 ? void 0 : _a.id))
264
284
  return null;
265
285
  const anchor = yield fetchOneMessage(client, m.channel.id, m.ts);
266
286
  const rootTs = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts) || m.ts;
267
287
  let members = [];
268
- // Check convo type (DM, MPIM, channel)
269
- const convoInfo = yield client.conversations.info({ channel: m.channel.id });
270
- const isIm = (_b = convoInfo.channel) === null || _b === void 0 ? void 0 : _b.is_im;
271
- const isMpim = (_c = convoInfo.channel) === null || _c === void 0 ? void 0 : _c.is_mpim;
288
+ // Check convo type (DM, MPIM, channel) with caching
289
+ let channelInfo = channelInfoCache.get(m.channel.id);
290
+ if (!channelInfo) {
291
+ const convoInfo = yield client.conversations.info({ channel: m.channel.id });
292
+ channelInfo = {
293
+ isIm: (_c = (_b = convoInfo.channel) === null || _b === void 0 ? void 0 : _b.is_im) !== null && _c !== void 0 ? _c : false,
294
+ isMpim: (_e = (_d = convoInfo.channel) === null || _d === void 0 ? void 0 : _d.is_mpim) !== null && _e !== void 0 ? _e : false,
295
+ };
296
+ channelInfoCache.set(m.channel.id, channelInfo);
297
+ }
298
+ const { isIm, isMpim } = channelInfo;
272
299
  const [contextMsgs, permalink] = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts)
273
300
  ? [yield fetchThread(client, m.channel.id, rootTs), yield getPermalink(client, m.channel.id, rootTs)]
274
301
  : [yield fetchContextWindow(client, m.channel.id, m.ts), yield getPermalink(client, m.channel.id, m.ts)];
275
302
  let passesFilter = false;
276
303
  if (isIm || isMpim) {
277
304
  // DM/MPIM: use members, not authorship
278
- const membersRes = (_d = (yield client.conversations.members({ channel: m.channel.id })).members) !== null && _d !== void 0 ? _d : [];
305
+ const membersRes = (_f = (yield client.conversations.members({ channel: m.channel.id })).members) !== null && _f !== void 0 ? _f : [];
279
306
  members = yield Promise.all(membersRes.map((uid) => __awaiter(void 0, void 0, void 0, function* () {
280
307
  const u = yield cache.get(uid);
281
308
  return { userId: uid, userEmail: u === null || u === void 0 ? void 0 : u.email, userName: u === null || u === void 0 ? void 0 : u.name };
@@ -302,8 +329,8 @@ const searchSlack = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params,
302
329
  channelId: m.channel.id,
303
330
  ts: rootTs,
304
331
  text: (anchor === null || anchor === void 0 ? void 0 : anchor.text) ? yield expandSlackEntities(client, cache, anchor.text) : undefined,
305
- userEmail: (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? (_e = (yield cache.get(anchor.user))) === null || _e === void 0 ? void 0 : _e.email : undefined,
306
- userName: (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? (_f = (yield cache.get(anchor.user))) === null || _f === void 0 ? void 0 : _f.name : undefined,
332
+ userEmail: (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? (_g = (yield cache.get(anchor.user))) === null || _g === void 0 ? void 0 : _g.email : undefined,
333
+ userName: (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? (_h = (yield cache.get(anchor.user))) === null || _h === void 0 ? void 0 : _h.name : undefined,
307
334
  context,
308
335
  permalink,
309
336
  members,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@credal/actions",
3
- "version": "0.2.147",
3
+ "version": "0.2.149",
4
4
  "type": "module",
5
5
  "description": "AI Actions by Credal AI",
6
6
  "sideEffects": false,