@yemi33/minions 0.1.635 → 0.1.637

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/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.635 (2026-04-08)
3
+ ## 0.1.637 (2026-04-08)
4
+
5
+ ### Other
6
+ - perf: reduce CC/doc-chat tool eagerness and max-turns
7
+
8
+ ## 0.1.636 (2026-04-08)
9
+
10
+ ### Fixes
11
+ - retry items bypass completed-dedup in isAlreadyDispatched
4
12
 
5
13
  ### Other
6
14
  - perf: extend caches, skip doc re-send on session resume
package/dashboard.js CHANGED
@@ -538,10 +538,10 @@ Additional: pause-plan, approve-plan, reject-plan, archive-plan, edit-prd-item,
538
538
  Terms like schedules, pipelines, agents, inbox, work items, plans, PRD, PRs, dispatch, routing, KB, notes, pinned, meetings have Minions-specific meanings. Always resolve against Minions state first (read files or call APIs). Fall back to generic only if no Minions context exists.
539
539
 
540
540
  ## Rules
541
- 1. Use tools proactivelyread files before answering.
541
+ 1. Answer from the state preamble and context first. Only use tools for specific file lookups the user asked about not to explore or investigate.
542
542
  2. Be specific — cite IDs, names, filenames, line numbers.
543
543
  3. Never modify engine source. Never push to git without user confirmation.
544
- 4. Delegate exploration to agents. You are the dispatcher, not the worker.`;
544
+ 4. Delegate exploration to agents. You are the dispatcher, not the worker. If answering requires reading more than 2-3 files, dispatch an agent instead.`;
545
545
 
546
546
  // Hash the system prompt so we can detect changes and invalidate stale sessions
547
547
  const _ccPromptHash = require('crypto').createHash('md5').update(CC_STATIC_SYSTEM_PROMPT).digest('hex').slice(0, 8);
@@ -694,7 +694,7 @@ function updateSession(store, key, sessionId, existing) {
694
694
  * @param {number} opts.maxTurns - Max tool-use turns
695
695
  * @param {string} opts.allowedTools - Comma-separated tool list
696
696
  */
697
- async function ccCall(message, { store = 'cc', sessionKey, extraContext, label = 'command-center', timeout = 900000, maxTurns = 50, allowedTools = 'Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch', skipStatePreamble = false, model } = {}) {
697
+ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label = 'command-center', timeout = 900000, maxTurns = 25, allowedTools = 'Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch', skipStatePreamble = false, model } = {}) {
698
698
  if (!model) model = CONFIG.engine?.ccModel || shared.ENGINE_DEFAULTS.ccModel;
699
699
  const ccEffort = CONFIG.engine?.ccEffort || shared.ENGINE_DEFAULTS.ccEffort;
700
700
  const existing = resolveSession(store, sessionKey);
@@ -792,6 +792,9 @@ async function ccDocCall({ message, document, title, filePath, selection, canEdi
792
792
  const result = await ccCall(message, {
793
793
  store: 'doc', sessionKey,
794
794
  extraContext: docContext, label: 'doc-chat',
795
+ allowedTools: canEdit ? 'Read,Write,Edit,Glob,Grep' : 'Read,Glob,Grep',
796
+ maxTurns: canEdit ? 15 : 10,
797
+ skipStatePreamble: true,
795
798
  ...(model ? { model } : {}),
796
799
  });
797
800
  // Store doc hash for next call's unchanged check
@@ -3356,7 +3359,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
3356
3359
  const streamModel = CONFIG.engine?.ccModel || shared.ENGINE_DEFAULTS.ccModel;
3357
3360
  const streamEffort = CONFIG.engine?.ccEffort || shared.ENGINE_DEFAULTS.ccEffort;
3358
3361
  const llmPromise = callLLMStreaming(prompt, CC_STATIC_SYSTEM_PROMPT, {
3359
- timeout: 900000, label: 'command-center', model: streamModel, maxTurns: 50,
3362
+ timeout: 900000, label: 'command-center', model: streamModel, maxTurns: 25,
3360
3363
  allowedTools: 'Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch',
3361
3364
  sessionId, effort: streamEffort, direct: true,
3362
3365
  onChunk: (text) => {
package/engine.js CHANGED
@@ -1696,15 +1696,28 @@ function discoverFromWorkItems(config, project) {
1696
1696
  delete item._resumedAt;
1697
1697
  needsWrite = true;
1698
1698
  }
1699
+ // Skip dedup for items explicitly marked for retry (_retryCount set by engine)
1700
+ const isRetry = !!item._retryCount;
1699
1701
  if (isAlreadyDispatched(key)) {
1700
- // Only self-heal to DISPATCHED if actually in dispatch.active (agent spawned) (#480)
1701
- const existingActive = getDispatch().active?.find(d => d.meta?.dispatchKey === key);
1702
- if (existingActive) {
1703
- if (item.status === WI_STATUS.PENDING) { item.status = WI_STATUS.DISPATCHED; needsWrite = true; }
1704
- if (!item.dispatched_to && existingActive.agent) { item.dispatched_to = existingActive.agent; needsWrite = true; }
1702
+ // Retry items should bypass the completed-dedup but still block if in-flight
1703
+ if (isRetry) {
1704
+ const inFlight = [...(getDispatch().pending || []), ...(getDispatch().active || [])];
1705
+ if (!inFlight.some(d => d.meta?.dispatchKey === key)) {
1706
+ // Not in-flight allow retry to proceed
1707
+ } else {
1708
+ if (item._pendingReason !== 'already_dispatched') { item._pendingReason = 'already_dispatched'; needsWrite = true; }
1709
+ skipped.gated++; continue;
1710
+ }
1711
+ } else {
1712
+ // Only self-heal to DISPATCHED if actually in dispatch.active (agent spawned) (#480)
1713
+ const existingActive = getDispatch().active?.find(d => d.meta?.dispatchKey === key);
1714
+ if (existingActive) {
1715
+ if (item.status === WI_STATUS.PENDING) { item.status = WI_STATUS.DISPATCHED; needsWrite = true; }
1716
+ if (!item.dispatched_to && existingActive.agent) { item.dispatched_to = existingActive.agent; needsWrite = true; }
1717
+ }
1718
+ if (item._pendingReason !== 'already_dispatched') { item._pendingReason = 'already_dispatched'; needsWrite = true; }
1719
+ skipped.gated++; continue;
1705
1720
  }
1706
- if (item._pendingReason !== 'already_dispatched') { item._pendingReason = 'already_dispatched'; needsWrite = true; }
1707
- skipped.gated++; continue;
1708
1721
  }
1709
1722
  if (isOnCooldown(key, cooldownMs)) {
1710
1723
  if (item._pendingReason !== 'cooldown') { item._pendingReason = 'cooldown'; needsWrite = true; }
@@ -2130,7 +2143,8 @@ function discoverCentralWorkItems(config) {
2130
2143
 
2131
2144
  const key = `central-work-${item.id}`;
2132
2145
  // Self-heal: if already dispatched but work item is still pending, fix the status
2133
- if (isAlreadyDispatched(key)) {
2146
+ // Skip dedup for items explicitly marked for retry (_retryCount set by engine)
2147
+ if (!item._retryCount && isAlreadyDispatched(key)) {
2134
2148
  // Only self-heal to DISPATCHED if actually in dispatch.active (agent spawned) (#480)
2135
2149
  const existingActive = getDispatch().active?.find(d => d.meta?.dispatchKey === key);
2136
2150
  if (existingActive) {
@@ -2141,6 +2155,11 @@ function discoverCentralWorkItems(config) {
2141
2155
  }
2142
2156
  continue;
2143
2157
  }
2158
+ // Still block if actively in flight (pending or active dispatch)
2159
+ if (item._retryCount && isAlreadyDispatched(key)) {
2160
+ const inFlight = [...(getDispatch().pending || []), ...(getDispatch().active || [])];
2161
+ if (inFlight.some(d => d.meta?.dispatchKey === key)) continue;
2162
+ }
2144
2163
  if (isOnCooldown(key, 0)) continue;
2145
2164
 
2146
2165
  const workType = item.type || 'implement';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.635",
3
+ "version": "0.1.637",
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"