crewly 1.20.368 → 1.20.369

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 (61) hide show
  1. package/config/skills/agent/core/complete-task/SKILL.md +4 -1
  2. package/config/skills/agent/core/complete-task/execute.sh +7 -2
  3. package/config/skills/agent/core/complete-task/execute.test.sh +10 -0
  4. package/config/skills/agent/core/get-my-context/SKILL.md +2 -0
  5. package/config/skills/agent/core/report-progress/SKILL.md +6 -0
  6. package/config/skills/agent/core/report-progress/execute.sh +18 -2
  7. package/config/skills/agent/core/report-progress/execute.test.sh +65 -0
  8. package/dist/backend/backend/src/constants.d.ts +40 -0
  9. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  10. package/dist/backend/backend/src/constants.js +40 -0
  11. package/dist/backend/backend/src/constants.js.map +1 -1
  12. package/dist/backend/backend/src/controllers/memory/memory.controller.d.ts +1 -1
  13. package/dist/backend/backend/src/controllers/memory/memory.controller.d.ts.map +1 -1
  14. package/dist/backend/backend/src/controllers/memory/memory.controller.js +12 -1
  15. package/dist/backend/backend/src/controllers/memory/memory.controller.js.map +1 -1
  16. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +4 -1
  17. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  18. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +45 -4
  19. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  20. package/dist/backend/backend/src/index.d.ts +18 -0
  21. package/dist/backend/backend/src/index.d.ts.map +1 -1
  22. package/dist/backend/backend/src/index.js +60 -7
  23. package/dist/backend/backend/src/index.js.map +1 -1
  24. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts +6 -2
  25. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts.map +1 -1
  26. package/dist/backend/backend/src/services/agent/resource-mode-protection.js +10 -4
  27. package/dist/backend/backend/src/services/agent/resource-mode-protection.js.map +1 -1
  28. package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts +15 -3
  29. package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/agent/resource-mode.service.js +12 -2
  31. package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
  32. package/dist/backend/backend/src/services/ai/self-improvement/index.d.ts +1 -0
  33. package/dist/backend/backend/src/services/ai/self-improvement/index.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/ai/self-improvement/index.js +1 -0
  35. package/dist/backend/backend/src/services/ai/self-improvement/index.js.map +1 -1
  36. package/dist/backend/backend/src/services/ai/self-improvement/task-timing.service.d.ts +157 -0
  37. package/dist/backend/backend/src/services/ai/self-improvement/task-timing.service.d.ts.map +1 -0
  38. package/dist/backend/backend/src/services/ai/self-improvement/task-timing.service.js +248 -0
  39. package/dist/backend/backend/src/services/ai/self-improvement/task-timing.service.js.map +1 -0
  40. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +14 -0
  41. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -1
  42. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +17 -0
  43. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -1
  44. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +3 -1
  45. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  46. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +7 -2
  47. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  48. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +8 -0
  49. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  50. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +20 -0
  51. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  52. package/dist/backend/build-info.json +2 -2
  53. package/dist/cli/backend/src/constants.d.ts +40 -0
  54. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  55. package/dist/cli/backend/src/constants.js +40 -0
  56. package/dist/cli/backend/src/constants.js.map +1 -1
  57. package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts +15 -3
  58. package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  59. package/dist/cli/backend/src/services/agent/resource-mode.service.js +12 -2
  60. package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
  61. package/package.json +1 -1
@@ -2211,9 +2211,11 @@ export class CrewlyServer {
2211
2211
  // (specs/2026-10-08-owner-thread-sentinel.md).
2212
2212
  // … and so is an agent the owner spoke to in the last two hours, answered
2213
2213
  // or not: evicting it loses the conversation the owner is in (crewly#1344).
2214
- owesOwnerThread: (name) => getOwnerThreadSentinel()?.owesOwner(name) === true ||
2215
- getOwnerThreadSentinel()?.ownerActiveRecently(name) === true ||
2216
- getFollowThrough()?.holdsIntent(name) === true,
2214
+ // Both soft reasons lapse after SOFT_KEEP_MAX_IDLE_MS idle: the owner
2215
+ // conversation resumes when the owner writes again (2026-10-19: Ella waited 2 h 38 min).
2216
+ owesOwnerThread: (name, idleMs) => getOwnerThreadSentinel()?.owesOwner(name) === true ||
2217
+ (idleMs < RESOURCE_MODE_CONSTANTS.SOFT_KEEP_MAX_IDLE_MS &&
2218
+ (getOwnerThreadSentinel()?.ownerActiveRecently(name) === true || getFollowThrough()?.holdsIntent(name) === true)),
2217
2219
  onStoppedForSlot: (name) => {
2218
2220
  reportOwnerThreadBlocking(name, { kind: 'stopped', why: 'slot' });
2219
2221
  // Same hook as every other stop path: what it owes goes back to the queue and it is brought back.
@@ -4382,6 +4384,8 @@ export class CrewlyServer {
4382
4384
  // Starts the staggered restore queue; it drains in the background.
4383
4385
  await this.autoRestoreAgentSessionsIfEnabled();
4384
4386
  this.wakeQueuedAgentsAfterBoot();
4387
+ const queuedWakeSweep = setInterval(() => this.wakeQueuedAgents(), SUB_AGENT_QUEUE_CONSTANTS.QUEUED_WAKE_SWEEP_MS);
4388
+ queuedWakeSweep.unref?.();
4385
4389
  // Re-deliver interrupted turns now that their agents are coming back.
4386
4390
  // Background: the orchestrator may take minutes to register.
4387
4391
  void this.resumeInterruptedTurnsAfterBoot();
@@ -6581,6 +6585,8 @@ export class CrewlyServer {
6581
6585
  */
6582
6586
  /** Last time a session was woken for queued messages (loop guard). */
6583
6587
  queuedWakeAt = new Map();
6588
+ /** Periodic queued-wake sweep: wakes per agent since it was last seen up, for the backoff */
6589
+ sweepWakes = new Map();
6584
6590
  /**
6585
6591
  * Start the unanswered-owner-message watchdog and feed it what the owner
6586
6592
  * can see: Slack posts (any bot, any machine), chat-v2 agent turns,
@@ -7266,6 +7272,29 @@ export class CrewlyServer {
7266
7272
  * (with its messages persisted) was never started again (Pia, 2026-10-16).
7267
7273
  */
7268
7274
  wakeQueuedAgentsAfterBoot() {
7275
+ this.wakeQueuedAgents({ boot: true });
7276
+ }
7277
+ /**
7278
+ * Start every agent that has messages queued for it and is not running,
7279
+ * being restored, owner-stopped or on a paused team. Runs once after boot
7280
+ * and then every QUEUED_WAKE_SWEEP_MS. Never throws.
7281
+ *
7282
+ * @param opts - `boot`: the one-off sweep after boot (paced with the restore queue)
7283
+ */
7284
+ wakeQueuedAgents(opts = {}) {
7285
+ this.wakeQueuedAgentsNow(opts).catch((err) => {
7286
+ this.logger.warn('Could not sweep agents with queued messages', { error: err instanceof Error ? err.message : String(err) });
7287
+ });
7288
+ }
7289
+ /**
7290
+ * Body of {@link wakeQueuedAgents} (may throw). A periodic sweep skips an
7291
+ * agent with no local team member (renamed, deleted, moved away), and backs
7292
+ * off per agent — the gap doubles with each wake that did not bring it up
7293
+ * (QUEUED_WAKE_SWEEP_MS, then 2x, 4x … up to QUEUED_WAKE_SWEEP_MAX_BACKOFF_MS)
7294
+ * — so a start that keeps failing is not relaunched four times an hour.
7295
+ */
7296
+ async wakeQueuedAgentsNow(opts) {
7297
+ const { sweepWakeDue } = await import('./services/messaging/deferred-start-retry.js');
7269
7298
  const restoreQueue = getRestoreQueue();
7270
7299
  const backend = getSessionBackendSync();
7271
7300
  const registration = this.apiController.agentRegistrationService;
@@ -7278,11 +7307,35 @@ export class CrewlyServer {
7278
7307
  !pausedTeamOfSession(name) &&
7279
7308
  !backend?.sessionExists(name) &&
7280
7309
  !registration.getInProcessRuntime(name));
7281
- if (sessions.length === 0)
7310
+ if (opts.boot) {
7311
+ if (sessions.length === 0)
7312
+ return;
7313
+ this.logger.info('Starting agents that were down with messages queued for them', { sessions, boot: true });
7314
+ for (const name of sessions)
7315
+ this.retryStartWhileQueued(name, SUB_AGENT_QUEUE_CONSTANTS.BOOT_QUEUED_WAKE_DELAY_MS, { boot: true });
7316
+ return;
7317
+ }
7318
+ // Up again (or nothing queued any more): its backoff starts over.
7319
+ const down = new Set(sessions);
7320
+ for (const name of this.sweepWakes.keys())
7321
+ if (!down.has(name))
7322
+ this.sweepWakes.delete(name);
7323
+ const now = Date.now();
7324
+ const due = [];
7325
+ for (const name of sessions) {
7326
+ const prev = this.sweepWakes.get(name);
7327
+ if (!sweepWakeDue(prev, now))
7328
+ continue;
7329
+ if (!(await this.storageService.findMemberBySessionName(name).catch(() => null)))
7330
+ continue;
7331
+ this.sweepWakes.set(name, { count: (prev?.count ?? 0) + 1, at: now });
7332
+ due.push(name);
7333
+ }
7334
+ if (due.length === 0)
7282
7335
  return;
7283
- this.logger.info('Starting agents that were down with messages queued for them', { sessions });
7284
- for (const name of sessions)
7285
- this.retryStartWhileQueued(name, SUB_AGENT_QUEUE_CONSTANTS.BOOT_QUEUED_WAKE_DELAY_MS, { boot: true });
7336
+ this.logger.info('Starting agents that were down with messages queued for them', { sessions: due, boot: false });
7337
+ for (const name of due)
7338
+ this.retryStartWhileQueued(name, 0);
7286
7339
  }
7287
7340
  /**
7288
7341
  * Write a system note into the orchestrator's own chat (the conversation