@yemi33/minions 0.1.2274 → 0.1.2275

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.
Files changed (2) hide show
  1. package/engine/queries.js +26 -3
  2. package/package.json +1 -1
package/engine/queries.js CHANGED
@@ -1977,6 +1977,18 @@ function getWorkItems(config, opts) {
1977
1977
  // Use snapshot — sync access; cold start before any async warm returns [].
1978
1978
  // Best-effort enrichment for work item _artifacts.notes, not correctness-critical.
1979
1979
  const _kbEntries = getKnowledgeBaseEntriesSnapshot();
1980
+ // PERF (dashboard event-loop freeze fix): the notes-linkage match below is
1981
+ // `entry contains agentId AND entry contains itemId`. Filtering the FULL
1982
+ // _kbEntries (can be ~10k) and _archiveFiles (~2k) per work item is O(items ×
1983
+ // files) — on a busy instance that's millions of String.includes() per
1984
+ // /api/work-items call, run synchronously, which hard-freezes the single
1985
+ // dashboard event loop. Bucket the two large collections by agentId ONCE per
1986
+ // distinct agent (lazily, like _agentDirCache above), then each item only
1987
+ // scans its agent's much-smaller bucket for the itemId. Exact same match
1988
+ // semantics; O(agents × files) one-time + O(items × bucket) instead of
1989
+ // O(items × files). _inboxFiles stays a direct filter (tiny — a handful).
1990
+ const _kbByAgent = {}; // agentId → kb entries whose source includes agentId
1991
+ const _archiveByAgent = {}; // agentId → archive filenames that include agentId
1980
1992
  // P-34fa5d79 — pre-build the wiId → notes map so each item's _notes lookup
1981
1993
  // is O(1) instead of re-scanning inbox+archive per item.
1982
1994
  const _notesByWi = _buildNotesByWiMap();
@@ -1996,14 +2008,25 @@ function getWorkItems(config, opts) {
1996
2008
  // Notes: inbox → KB (via source field) → archive (fallback if KB was swept)
1997
2009
  const itemId = item.id || '___';
1998
2010
  const matchInbox = _inboxFiles.filter(f => f.includes(agentId) && f.includes(itemId));
1999
- const matchKb = _kbEntries.filter(kb => kb.source && kb.source.includes(agentId) && kb.source.includes(itemId));
2011
+ // Lazily bucket KB by agentId (computed once per distinct agent), then
2012
+ // filter the small bucket by itemId — same result as filtering all of
2013
+ // _kbEntries by (agentId AND itemId), without the per-item full scan.
2014
+ if (_kbByAgent[agentId] === undefined) {
2015
+ _kbByAgent[agentId] = _kbEntries.filter(kb => kb.source && kb.source.includes(agentId));
2016
+ }
2017
+ const matchKb = _kbByAgent[agentId].filter(kb => kb.source.includes(itemId));
2000
2018
  const allNotes = [
2001
2019
  ...matchInbox,
2002
2020
  ...matchKb.map(kb => 'kb:' + kb.cat + '/' + kb.file),
2003
2021
  ];
2004
- // Archive fallback — only if nothing found in inbox or KB
2022
+ // Archive fallback — only if nothing found in inbox or KB. Same agentId
2023
+ // bucketing as KB so the (potentially large) archive list isn't fully
2024
+ // re-scanned per item.
2005
2025
  if (allNotes.length === 0) {
2006
- const matchArchive = _archiveFiles.filter(f => f.includes(agentId) && f.includes(itemId));
2026
+ if (_archiveByAgent[agentId] === undefined) {
2027
+ _archiveByAgent[agentId] = _archiveFiles.filter(f => f.includes(agentId));
2028
+ }
2029
+ const matchArchive = _archiveByAgent[agentId].filter(f => f.includes(itemId));
2007
2030
  for (const f of matchArchive) allNotes.push('archive:' + f);
2008
2031
  }
2009
2032
  if (allNotes.length > 0) arts.notes = _mergeArtifactNotes(arts.notes, allNotes);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.2274",
3
+ "version": "0.1.2275",
4
4
  "description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
5
5
  "bin": {
6
6
  "minions": "bin/minions.js"