@desplega.ai/agent-swarm 2.5.1 → 2.5.3

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 (197) hide show
  1. package/dist/{acp-adapter-7g6bpwbk.js → acp-adapter-gr2fcyyj.js} +3 -3
  2. package/dist/{actions-w8xd014k.js → actions-wv766ghf.js} +18 -18
  3. package/dist/{amp-adapter-z4qvhacj.js → amp-adapter-speb906t.js} +3 -3
  4. package/dist/{app-nndcvftq.js → app-ag29n14f.js} +3 -3
  5. package/dist/{assistant-hjmqyscx.js → assistant-3x8bz3eg.js} +19 -19
  6. package/dist/{boot-reembed-r8rhf9h8.js → boot-reembed-5b3d2eea.js} +1 -1
  7. package/dist/{boot-reembed-vwcj2y5d.js → boot-reembed-jsmfrpzf.js} +1 -1
  8. package/dist/{boot-scrub-sweep-fr9q36ne.js → boot-scrub-sweep-s73gerxy.js} +2 -2
  9. package/dist/{boot-seeds-9jqwnegq.js → boot-seeds-5zmax2wr.js} +4 -4
  10. package/dist/{claude-adapter-2f8b85df.js → claude-adapter-hswdnm3t.js} +3 -3
  11. package/dist/{claude-managed-adapter-gt6pa35d.js → claude-managed-adapter-cvbzj1h6.js} +2 -2
  12. package/dist/{claude-managed-setup-c3hp36ph.js → claude-managed-setup-3k8m3hhc.js} +2 -2
  13. package/dist/{claude-sdk-session-05kat8rv.js → claude-sdk-session-fkbyk66x.js} +6905 -6855
  14. package/dist/{cli-y3zyaee5.js → cli-1fc85mvt.js} +5 -5
  15. package/dist/{cli-v2g93k4v.js → cli-210xd1f4.js} +4 -4
  16. package/dist/{cli-sn1vbtg2.js → cli-25j01dpj.js} +3 -3
  17. package/dist/{cli-n6kmqngw.js → cli-35gtk1p6.js} +1 -1
  18. package/dist/{cli-r9fy0ddc.js → cli-3ngdk5te.js} +1 -1
  19. package/dist/{cli-z63a269p.js → cli-40jsnrjm.js} +2 -2
  20. package/dist/{cli-ba8ne1es.js → cli-4rvr7zfx.js} +10 -0
  21. package/dist/{cli-qfm6my86.js → cli-502eqv93.js} +1 -1
  22. package/dist/{cli-xd4eqtr2.js → cli-6n8axjv1.js} +1 -1
  23. package/dist/{cli-hadv0725.js → cli-8s5wx3nz.js} +2 -2
  24. package/dist/{cli-z2dv25mf.js → cli-99xgw26r.js} +116 -5
  25. package/dist/{cli-jpxsrxcb.js → cli-9s05422w.js} +1 -1
  26. package/dist/{cli-kcsd1ez8.js → cli-aecdcr77.js} +343 -325
  27. package/dist/{cli-w9etnnxk.js → cli-bf8ma3f1.js} +120 -50
  28. package/dist/{cli-e9btqw4y.js → cli-ce0ak9ms.js} +18 -13
  29. package/dist/{cli-nj12tn2c.js → cli-e2ar4bp1.js} +71 -20
  30. package/dist/{cli-gwcf52gz.js → cli-e8jyq7d8.js} +11 -7
  31. package/dist/{cli-rngde2jv.js → cli-egjggehm.js} +1 -1
  32. package/dist/{cli-qfjm4gvt.js → cli-ewm3pwbq.js} +2 -2
  33. package/dist/{cli-9mm5ade4.js → cli-fsdprwrg.js} +1 -1
  34. package/dist/{cli-3ee5z0q0.js → cli-fzcn3d87.js} +1 -1
  35. package/dist/{cli-eym3jg7w.js → cli-gpsz7g88.js} +6 -6
  36. package/dist/{cli-cwyafhw1.js → cli-hcpj2xqz.js} +1 -1
  37. package/dist/{cli-j1eghqfm.js → cli-hhxjnjzs.js} +1 -1
  38. package/dist/{cli-pyy4c9ch.js → cli-jjznk3f7.js} +881 -232
  39. package/dist/{cli-q9pzwxvk.js → cli-kxawjrxg.js} +222 -37
  40. package/dist/{cli-rh5smt8t.js → cli-mz9afxxf.js} +14 -3
  41. package/dist/{cli-mz2ygeyq.js → cli-n45mr7zh.js} +2 -2
  42. package/dist/{cli-fes51ya2.js → cli-p0rzjkya.js} +2 -2
  43. package/dist/{cli-3qv8naq8.js → cli-p6zs9h4y.js} +827 -107
  44. package/dist/{cli-mq7kg1b1.js → cli-p9rafdrb.js} +41 -6
  45. package/dist/{cli-cah5detr.js → cli-qgf8emrn.js} +5 -5
  46. package/dist/{cli-2wba1ac9.js → cli-qzme5949.js} +26 -26
  47. package/dist/{cli-znvq0k3t.js → cli-s49hpn37.js} +2 -2
  48. package/dist/{cli-xc65x52q.js → cli-s53vp709.js} +1 -1
  49. package/dist/{cli-0jy85zz4.js → cli-svrj71pg.js} +18 -16
  50. package/dist/{cli-1dp1zj04.js → cli-vwn81jbs.js} +3 -3
  51. package/dist/{cli-ajqhxtnz.js → cli-w1zwctj2.js} +1 -1
  52. package/dist/{cli-22rmcjkg.js → cli-y561h5a9.js} +7 -6
  53. package/dist/{cli-2jg61wab.js → cli-z21whrrg.js} +15 -15
  54. package/dist/cli.js +19 -18
  55. package/dist/{codex-adapter-p4ptwar5.js → codex-adapter-n8ka66vf.js} +2 -2
  56. package/dist/{codex-session-runner-964c7dnk.js → codex-session-runner-fsebts37.js} +1 -1
  57. package/dist/{commands-mbvhbrcy.js → commands-t04rt2pc.js} +2 -2
  58. package/dist/{controller-gnq1k1mf.js → controller-rgna04r2.js} +2 -2
  59. package/dist/{controllers-connect-6dkm71tg.js → controllers-connect-bqm1rtft.js} +20 -20
  60. package/dist/{cursor-adapter-yq5xgfcg.js → cursor-adapter-swr2k95y.js} +1 -1
  61. package/dist/{db-88wcymxt.js → db-24ck09xy.js} +1 -1
  62. package/dist/{db-af9y8nkf.js → db-a4m7haw0.js} +3 -3
  63. package/dist/{dispatcher-606ydx5v.js → dispatcher-nwf9ss0q.js} +17 -17
  64. package/dist/{dsh-adapter-tvhc4k2d.js → dsh-adapter-kpdnhjst.js} +2 -2
  65. package/dist/{external-channel-y8q5z8z2.js → external-channel-j1e2p34p.js} +2 -2
  66. package/dist/{grok-adapter-39aha52t.js → grok-adapter-qtjz0whk.js} +4 -4
  67. package/dist/{handlers-rk9dqech.js → handlers-19xr6dnz.js} +20 -20
  68. package/dist/{heartbeat-jfe9zfjr.js → heartbeat-vtesda5d.js} +20 -20
  69. package/dist/{hook-b1mez1m8.js → hook-8wqaszda.js} +1 -1
  70. package/dist/{hook-ffevzed1.js → hook-b2hhj6rd.js} +1 -1
  71. package/dist/{http-d5b44f1r.js → http-mxcqhhcs.js} +3020 -2463
  72. package/dist/{index-5en23s5z.js → index-1r8wfpzs.js} +1 -1
  73. package/dist/{index-cbxkmfc5.js → index-9pn1pfkf.js} +1 -1
  74. package/dist/{index-mj46rk9k.js → index-kw2mmat7.js} +20 -20
  75. package/dist/{index-nq8hhv28.js → index-n1vbvta9.js} +19 -10
  76. package/dist/{index-6srwvd5b.js → index-p4xfz37z.js} +1 -1
  77. package/dist/{index-d2qeem97.js → index-spwxjgay.js} +17 -17
  78. package/dist/{index-4q3vj1yr.js → index-srg522m6.js} +17 -17
  79. package/dist/{keepalive-wsby1btq.js → keepalive-dsd8rtgx.js} +3 -3
  80. package/dist/{lead-paa141j6.js → lead-zyerk1x2.js} +30 -30
  81. package/dist/{maintenance-vnshcyv9.js → maintenance-jqmqwnet.js} +1 -1
  82. package/dist/{oauth-refresh-sweep-d6sqn5np.js → oauth-refresh-sweep-q2c3bnvm.js} +2 -2
  83. package/dist/{onboard-nr4xhpzy.js → onboard-w4yd7s8t.js} +2 -2
  84. package/dist/{opencode-adapter-e56086m1.js → opencode-adapter-9tppvxar.js} +2 -2
  85. package/dist/{otel-impl-ytn9wyv9.js → otel-impl-f36byzbd.js} +1 -1
  86. package/dist/{pricing-refresh-pva04zee.js → pricing-refresh-xvak5p4v.js} +3 -3
  87. package/dist/{rbac-roles-7rc1q3g4.js → rbac-roles-682k2mt5.js} +12 -2
  88. package/dist/rbac-roles-gfn30fb8.js +26 -0
  89. package/dist/{render-v2-pyfsg9zk.js → render-v2-hgytz8nn.js} +3 -3
  90. package/dist/{resume-phj8xhqr.js → resume-2dvq348g.js} +7 -5
  91. package/dist/{session-access-jzx2z9h5.js → session-access-7f21ekq9.js} +4 -4
  92. package/dist/{setup-rfg0f0sg.js → setup-epffxtbk.js} +1 -1
  93. package/dist/{work-objects-44z2yjg8.js → work-objects-xz1a5rqk.js} +20 -20
  94. package/dist/{worker-zsfqzxhm.js → worker-42t8emjt.js} +30 -30
  95. package/openapi.json +3163 -2114
  96. package/package.json +7 -6
  97. package/src/be/approval-config-question.ts +389 -0
  98. package/src/be/automation-preflight.ts +37 -3
  99. package/src/be/db/session-tree.ts +158 -13
  100. package/src/be/db/session-visibility.ts +31 -0
  101. package/src/be/db/skill-search.ts +87 -0
  102. package/src/be/db/tasks/read.ts +47 -7
  103. package/src/be/db/workflow-runs.ts +54 -7
  104. package/src/be/db.ts +27 -5
  105. package/src/be/migrations/233_script_run_session_tokens.sql +8 -0
  106. package/src/be/migrations/235_chat_relay_defer.sql +86 -0
  107. package/src/be/migrations/237_session_inbox_cleanup.sql +75 -0
  108. package/src/be/migrations/239_skills_fts.sql +40 -0
  109. package/src/be/migrations/240_workflow_run_parent_step_attempt.sql +37 -0
  110. package/src/be/migrations/241_skills_meta_fts.sql +39 -0
  111. package/src/be/rbac-roles.ts +138 -0
  112. package/src/be/scripts/run-credential.ts +64 -0
  113. package/src/be/scripts/run-saved.ts +3 -2
  114. package/src/be/swarm-config-guard.ts +23 -0
  115. package/src/be/users.ts +28 -4
  116. package/src/extensions/catalog.generated.json +4 -4
  117. package/src/http/all-routes.ts +1 -0
  118. package/src/http/approval-requests.ts +254 -43
  119. package/src/http/config.ts +22 -37
  120. package/src/http/index.ts +2 -0
  121. package/src/http/schedules.ts +26 -0
  122. package/src/http/scripts.ts +2 -2
  123. package/src/http/sessions.ts +118 -2
  124. package/src/http/user-roles.ts +173 -0
  125. package/src/http/users.ts +9 -0
  126. package/src/http/x.ts +2 -2
  127. package/src/integrations/chat-sdk/commands.ts +14 -1
  128. package/src/integrations/chat-sdk/inbound.ts +42 -6
  129. package/src/integrations/chat-sdk/outbound.ts +35 -10
  130. package/src/integrations/chat-sdk/reactions.ts +107 -0
  131. package/src/integrations/chat-sdk/relay.ts +75 -7
  132. package/src/integrations/chat-sdk/thread-buffer.ts +2 -0
  133. package/src/integrations/reaction-events.ts +20 -0
  134. package/src/providers/amp-adapter.ts +1 -1
  135. package/src/providers/dsh-adapter.ts +1 -1
  136. package/src/rbac/legacy-policy.ts +3 -0
  137. package/src/rbac/permissions.ts +8 -0
  138. package/src/scheduler/schedule-task.ts +44 -3
  139. package/src/scheduler/scheduler.ts +4 -4
  140. package/src/scripts-runtime/loader.ts +8 -1
  141. package/src/slack/ack.ts +2 -1
  142. package/src/slack/reaction-shortcode.ts +4 -7
  143. package/src/tasks/worker-follow-up.ts +30 -0
  144. package/src/tests/approval-config-question.test.ts +702 -0
  145. package/src/tests/approval-requests-notifications.test.ts +189 -0
  146. package/src/tests/chat-sdk-commands.test.ts +12 -0
  147. package/src/tests/chat-sdk-inbound.test.ts +183 -9
  148. package/src/tests/chat-sdk-outbound-files.test.ts +9 -2
  149. package/src/tests/chat-sdk-relay.test.ts +361 -10
  150. package/src/tests/chat-sdk-tools.test.ts +104 -0
  151. package/src/tests/docs-index-footprint.test.js +3 -3
  152. package/src/tests/dsh-adapter.test.ts +1 -1
  153. package/src/tests/entrypoint-gitlab-credential-helper.test.ts +273 -0
  154. package/src/tests/extensions-example-comms-adherence-gate.test.ts +321 -12
  155. package/src/tests/http-users.test.ts +38 -0
  156. package/src/tests/list-endpoint-slimming.test.ts +33 -0
  157. package/src/tests/migration-237-session-inbox-cleanup.test.ts +136 -0
  158. package/src/tests/migration-240-workflow-run-parent-step-attempt.test.ts +55 -0
  159. package/src/tests/rbac-engine.test.ts +2 -0
  160. package/src/tests/rbac-roles.test.ts +10 -0
  161. package/src/tests/schedule-http-triage-tools.test.ts +44 -0
  162. package/src/tests/script-api-credential.test.ts +173 -0
  163. package/src/tests/script-connections.test.ts +10 -0
  164. package/src/tests/script-run-config-scope.test.ts +120 -0
  165. package/src/tests/script-run-token.test.ts +75 -0
  166. package/src/tests/scripts-http.test.ts +19 -0
  167. package/src/tests/sessions-tree.test.ts +410 -1
  168. package/src/tests/skill-search-long-content.test.ts +193 -0
  169. package/src/tests/skill-search.test.ts +173 -22
  170. package/src/tests/user-roles-http.test.ts +204 -0
  171. package/src/tests/workflow-hitl-dynamic-questions.test.ts +1 -1
  172. package/src/tests/workflow-sub-workflow.test.ts +538 -1
  173. package/src/tools/chat-reply.ts +2 -0
  174. package/src/tools/request-human-input.ts +27 -5
  175. package/src/tools/schedules/patch-schedule.ts +18 -0
  176. package/src/tools/schedules/update-schedule.ts +18 -0
  177. package/src/types.ts +23 -0
  178. package/src/workflows/approval-notifications.ts +221 -0
  179. package/src/workflows/checkpoint.ts +69 -35
  180. package/src/workflows/engine.ts +234 -87
  181. package/src/workflows/executors/base.ts +6 -0
  182. package/src/workflows/executors/human-in-the-loop.ts +36 -173
  183. package/src/workflows/executors/sub-workflow.ts +45 -16
  184. package/src/workflows/executors/swarm-script.ts +2 -2
  185. package/src/workflows/recovery.ts +63 -1
  186. package/src/workflows/resume.ts +60 -21
  187. package/src/workflows/retry-poller.ts +25 -4
  188. package/templates/extensions/comms-adherence-gate/README.md +38 -13
  189. package/templates/extensions/comms-adherence-gate/hooks.ts +272 -69
  190. package/templates/extensions/comms-adherence-gate/manifest.json +2 -2
  191. package/templates/schedules/weekly-harness-upgrade-check/content.md +1 -1
  192. package/templates/skills/code-quality/content.md +1 -1
  193. package/templates/skills/turso-interaction/content.md +1 -1
  194. package/templates/skills/workflow-iterate/content.md +8 -1
  195. package/dist/rbac-roles-ff1ffmec.js +0 -12
  196. /package/dist/{cli-stxdrqs2.js → cli-avdvgcay.js} +0 -0
  197. /package/dist/{pi-mono-adapter-tzps8f38.js → pi-mono-adapter-tqsge1ay.js} +0 -0
@@ -111,6 +111,7 @@ import {
111
111
  cancelTask2,
112
112
  getRecentlyCancelledTasksForAgent2,
113
113
  updateTaskProgress2,
114
+ getRunningSubWorkflowSteps,
114
115
  getSettledChildRunParentSteps,
115
116
  init_workflow_runs,
116
117
  CHAT_SDK_ADAPTER_NAMES,
@@ -336,19 +337,19 @@ import {
336
337
  recordInlineScriptRun2,
337
338
  exports_db,
338
339
  init_db3
339
- } from "./cli-q9pzwxvk.js";
340
+ } from "./cli-kxawjrxg.js";
340
341
  import {
341
342
  getUserGrant2,
342
343
  init_rbac_roles
343
- } from "./cli-z2dv25mf.js";
344
+ } from "./cli-99xgw26r.js";
344
345
  import {
345
346
  ensurePricingSeeded2,
346
347
  ensureRbacSeeded2,
347
348
  ensureModelProfilesSeeded2
348
- } from "./cli-v2g93k4v.js";
349
+ } from "./cli-210xd1f4.js";
349
350
  import {
350
351
  loadModelsDevCache
351
- } from "./cli-9mm5ade4.js";
352
+ } from "./cli-fsdprwrg.js";
352
353
  import {
353
354
  buildCatalogEntries,
354
355
  listModelCatalog,
@@ -358,12 +359,12 @@ import {
358
359
  loadModelsCatalog,
359
360
  requestModelCatalogRefresh2,
360
361
  startPricingRefreshLoop2
361
- } from "./cli-mz2ygeyq.js";
362
+ } from "./cli-n45mr7zh.js";
362
363
  import {
363
364
  ampPinProviderError,
364
365
  ampPinCatalogError,
365
366
  ampModelError
366
- } from "./cli-jpxsrxcb.js";
367
+ } from "./cli-9s05422w.js";
367
368
  import {
368
369
  notifyAutomationPreflightFailure,
369
370
  isNeedsSetupFailure,
@@ -373,6 +374,17 @@ import {
373
374
  schedulePreflightInput,
374
375
  recordSchedulePreflightFailure,
375
376
  BaseExecutor,
377
+ AGENT_MAX_TASKS_CONFIG_KEY,
378
+ resetAgentMaxTasksMirror,
379
+ upsertSwarmConfigWithPolicyMirror,
380
+ getRuntimeInstanceById,
381
+ markRuntimeTerminated,
382
+ touchRuntimeInstance,
383
+ markRuntimeInstanceOffline,
384
+ reconcileAgentStatusFromRuntimes,
385
+ ConfigQuestionSettingsSchema,
386
+ normalizeApprovalQuestions,
387
+ resolveSlackConversationId,
376
388
  postApprovalCancellationUpdates,
377
389
  createApprovalFollowUpTask,
378
390
  HumanInTheLoopExecutor,
@@ -399,6 +411,7 @@ import {
399
411
  startWorkflowExecution2,
400
412
  failRunOnUnreadableReplay,
401
413
  isWorkflowRunActive,
414
+ isStepExecuting,
402
415
  holdWorkflowRun,
403
416
  walkGraph,
404
417
  findReadyNodes,
@@ -415,7 +428,7 @@ import {
415
428
  definitionNodeIds,
416
429
  validateDefinition,
417
430
  applyDefinitionPatch
418
- } from "./cli-pyy4c9ch.js";
431
+ } from "./cli-jjznk3f7.js";
419
432
  import {
420
433
  require_dist2,
421
434
  publicEndpointSsrfOptions,
@@ -446,7 +459,7 @@ import {
446
459
  MAX_SCRIPT_WALL_CLOCK_MS,
447
460
  DEFAULT_SCRIPT_RESOURCES,
448
461
  validateScriptImports,
449
- runScript,
462
+ runScriptWithRunCredential,
450
463
  extractScriptSignature,
451
464
  extractArgsJsonSchema,
452
465
  getSavedScriptOwnerAgentId,
@@ -475,21 +488,25 @@ import {
475
488
  deleteApp,
476
489
  typecheckScript,
477
490
  parseSkillContent
478
- } from "./cli-mq7kg1b1.js";
491
+ } from "./cli-p9rafdrb.js";
479
492
  import {
480
493
  buildAuthorizationUrl,
481
494
  onAuthorizationRefreshed,
482
495
  ensureAuthorizationTokenOrThrow,
483
496
  ensureToken,
484
497
  ensureTokenOrThrow
485
- } from "./cli-rngde2jv.js";
498
+ } from "./cli-egjggehm.js";
486
499
  import {
487
500
  detachedProcessGroup,
488
501
  registerProcessGroup,
489
502
  terminateProcessGroup
490
503
  } from "./cli-3ggwdtb0.js";
504
+ import {
505
+ isMultiRuntimeEnabled
506
+ } from "./cli-e8xyjvfc.js";
491
507
  import {
492
508
  noteSlackInboundSideEffect,
509
+ terminalReactionEvent,
493
510
  withSpan2,
494
511
  getTaskLink,
495
512
  getTaskUrl,
@@ -512,14 +529,14 @@ import {
512
529
  getSlackApp2,
513
530
  startSlackApp2,
514
531
  stopSlackApp2
515
- } from "./cli-e9btqw4y.js";
532
+ } from "./cli-ce0ak9ms.js";
516
533
  import {
517
534
  slackCode,
518
535
  slackMissingScopeMessage,
519
536
  withAutoJoin,
520
537
  externalChannelToolError2,
521
538
  getChannelBlockReason2
522
- } from "./cli-xc65x52q.js";
539
+ } from "./cli-s53vp709.js";
523
540
  import {
524
541
  workflowEventBus2,
525
542
  init_event_bus
@@ -541,7 +558,7 @@ import {
541
558
  recoverResolvedWaitState2,
542
559
  resumeFromChildRun2,
543
560
  initWaitBusSubscriptions2
544
- } from "./cli-nj12tn2c.js";
561
+ } from "./cli-e2ar4bp1.js";
545
562
  import {
546
563
  duplicateGuardedQueryKey,
547
564
  parseQueryParams,
@@ -568,10 +585,7 @@ import {
568
585
  isPublicRoute,
569
586
  findRoute,
570
587
  route
571
- } from "./cli-y3zyaee5.js";
572
- import {
573
- isMultiRuntimeEnabled
574
- } from "./cli-e8xyjvfc.js";
588
+ } from "./cli-1fc85mvt.js";
575
589
  import {
576
590
  FilesError,
577
591
  providerPath,
@@ -582,7 +596,7 @@ import {
582
596
  import {
583
597
  getRuntimePool2,
584
598
  init_db
585
- } from "./cli-1dp1zj04.js";
599
+ } from "./cli-vwn81jbs.js";
586
600
  import {
587
601
  getMemoryRaterNames,
588
602
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -619,11 +633,10 @@ import {
619
633
  linkIdentity,
620
634
  unlinkIdentity,
621
635
  resolveUserByToken,
622
- revokeRuntimeTokensForRuntime,
623
636
  resolveSessionToken,
624
637
  fingerprintApiKey,
625
638
  init_users
626
- } from "./cli-gwcf52gz.js";
639
+ } from "./cli-e8jyq7d8.js";
627
640
  import {
628
641
  isRbacEnabled,
629
642
  decideAdmission,
@@ -632,7 +645,7 @@ import {
632
645
  init_elevated_agents,
633
646
  can,
634
647
  init_rbac
635
- } from "./cli-ba8ne1es.js";
648
+ } from "./cli-4rvr7zfx.js";
636
649
  import {
637
650
  normalizeAssetKey,
638
651
  parseAssetKey,
@@ -692,7 +705,7 @@ import {
692
705
  KvNamespaceSchema,
693
706
  KvKeySchema,
694
707
  init_types
695
- } from "./cli-rh5smt8t.js";
708
+ } from "./cli-mz9afxxf.js";
696
709
  import {
697
710
  generateDefaultClaudeMd2,
698
711
  generateDefaultSoulMd2,
@@ -761,7 +774,7 @@ import {
761
774
  import {
762
775
  init_package,
763
776
  package_default
764
- } from "./cli-22rmcjkg.js";
777
+ } from "./cli-y561h5a9.js";
765
778
  import {
766
779
  realtimeBus,
767
780
  init_bus
@@ -20138,6 +20151,7 @@ async function recoverIncompleteRuns(registry) {
20138
20151
  }
20139
20152
  }
20140
20153
  recovered += await recoverForeachFanouts(registry);
20154
+ recovered += await recoverOrphanedSubWorkflowSteps(registry);
20141
20155
  if (recovered > 0) {
20142
20156
  console.log(`[workflows] Recovered ${recovered} incomplete run(s)`);
20143
20157
  }
@@ -20153,6 +20167,10 @@ async function recoverRunningRuns(registry) {
20153
20167
  const run = await getWorkflowRun2(runId);
20154
20168
  if (!run || run.status !== "running")
20155
20169
  continue;
20170
+ if (run.parentStepId && run.context === undefined) {
20171
+ await failRunningRun(runId, "Child workflow run lost its initial context in a restart");
20172
+ continue;
20173
+ }
20156
20174
  const workflow = await getWorkflow2(run.workflowId);
20157
20175
  if (!workflow)
20158
20176
  continue;
@@ -20179,6 +20197,43 @@ async function recoverRunningRuns(registry) {
20179
20197
  }
20180
20198
  return recovered;
20181
20199
  }
20200
+ async function failRunningRun(runId, error) {
20201
+ await getDbClient2().transaction(async () => {
20202
+ const run = await getWorkflowRun2(runId);
20203
+ if (run?.status !== "running")
20204
+ return;
20205
+ await updateWorkflowRun2(runId, {
20206
+ status: "failed",
20207
+ error,
20208
+ finishedAt: new Date().toISOString()
20209
+ });
20210
+ });
20211
+ }
20212
+ async function recoverOrphanedSubWorkflowSteps(registry) {
20213
+ let recovered = 0;
20214
+ for (const row of await getRunningSubWorkflowSteps()) {
20215
+ try {
20216
+ if (isWorkflowRunActive(row.runId) || isStepExecuting(row.stepId))
20217
+ continue;
20218
+ const run = await getWorkflowRun2(row.runId);
20219
+ if (!run || run.status !== "running" && run.status !== "waiting")
20220
+ continue;
20221
+ const workflow = await getWorkflow2(run.workflowId);
20222
+ const node = workflow?.definition.nodes.find((n) => n.id === row.nodeId);
20223
+ if (!workflow || !node)
20224
+ continue;
20225
+ if (isWorkflowRunActive(row.runId))
20226
+ continue;
20227
+ await walkGraph(workflow.definition, row.runId, run.context ?? {}, [node], registry, workflow.id, getSecretInputKeys(workflow.input));
20228
+ recovered++;
20229
+ } catch (err) {
20230
+ if (await failRunOnUnreadableReplay(row.runId, err))
20231
+ continue;
20232
+ console.error(`[workflows] Failed to recover sub-workflow step ${row.stepId}:`, err);
20233
+ }
20234
+ }
20235
+ return recovered;
20236
+ }
20182
20237
  function retryPendingNodeIds(steps) {
20183
20238
  const nodeIds = new Set;
20184
20239
  for (const step of steps) {
@@ -20407,6 +20462,7 @@ function startRetryPoller(registry, intervalMs = 5000) {
20407
20462
  release = holdWorkflowRun(run.id);
20408
20463
  if (!await claimRetry(run.id, step.id))
20409
20464
  continue;
20465
+ const fence = { retryCount: step.retryCount };
20410
20466
  const {
20411
20467
  ctx,
20412
20468
  inputCtx,
@@ -20414,7 +20470,7 @@ function startRetryPoller(registry, intervalMs = 5000) {
20414
20470
  scriptBodyUnresolved
20415
20471
  } = await rebuildNodeExecutionInput(workflow.definition, run, node, registry);
20416
20472
  if (scriptBodyUnresolved && scriptBodyUnresolved.length > 0) {
20417
- await checkpointStepFailure(run.id, step.id, scriptBodyInterpolationError(node.id, scriptBodyUnresolved), step.retryCount);
20473
+ await checkpointStepFailure(run.id, step.id, scriptBodyInterpolationError(node.id, scriptBodyUnresolved), step.retryCount, undefined, { fence });
20418
20474
  continue;
20419
20475
  }
20420
20476
  const executor = registry.get(node.type);
@@ -20434,8 +20490,8 @@ function startRetryPoller(registry, intervalMs = 5000) {
20434
20490
  meta
20435
20491
  });
20436
20492
  if (result.status === "failed") {
20437
- const retryPolicy = node.retry || executor.retryPolicy;
20438
- await checkpointStepFailure(run.id, step.id, result.error || "Retry failed", step.retryCount, retryPolicy);
20493
+ const retryPolicy = result.retryable === false ? undefined : node.retry || executor.retryPolicy;
20494
+ await checkpointStepFailure(run.id, step.id, result.error || "Retry failed", step.retryCount, retryPolicy, { fence, output: result.output });
20439
20495
  } else if ("async" in result && result.async && result.waitFor === FOREACH_ITEMS_WAIT_FOR) {
20440
20496
  const drive = await parkAndDriveForeach({
20441
20497
  runId: run.id,
@@ -20455,12 +20511,16 @@ function startRetryPoller(registry, intervalMs = 5000) {
20455
20511
  const waiting = await checkpointStepWaiting(run.id, step.id, ctx);
20456
20512
  if (!waiting)
20457
20513
  continue;
20514
+ if (result.waitFor === "workflow.child.finished") {
20515
+ const { resumeFromChildRun } = await import("./resume-2dvq348g.js");
20516
+ await resumeFromChildRun(step.id, registry);
20517
+ }
20458
20518
  } else {
20459
20519
  let validationPassed;
20460
20520
  if (node.validation) {
20461
20521
  const validationResult = await runStepValidation(registry, node, result.output, ctx, meta);
20462
20522
  if (validationResult.outcome === "halt") {
20463
- await checkpointStepFailure(run.id, step.id, "Validation failed (mustPass)", step.retryCount);
20523
+ await checkpointStepFailure(run.id, step.id, "Validation failed (mustPass)", step.retryCount, undefined, { fence });
20464
20524
  continue;
20465
20525
  }
20466
20526
  if (validationResult.outcome === "retry") {
@@ -20470,13 +20530,15 @@ function startRetryPoller(registry, intervalMs = 5000) {
20470
20530
  ctx[historyKey] = [...existing, validationResult.retryContext];
20471
20531
  }
20472
20532
  const retryPolicy = node.validation.retry || node.retry;
20473
- await checkpointStepFailure(run.id, step.id, "Validation failed, retrying", step.retryCount, retryPolicy);
20533
+ await checkpointStepFailure(run.id, step.id, "Validation failed, retrying", step.retryCount, retryPolicy, { fence });
20474
20534
  continue;
20475
20535
  }
20476
20536
  validationPassed = validationResult.passed;
20477
20537
  }
20478
20538
  result.nextPort = resolveValidationPort(node.next, result.nextPort, validationPassed);
20479
- await checkpointStep(run.id, step.id, step.nodeId, result, ctx);
20539
+ if (!await checkpointStep(run.id, step.id, step.nodeId, result, ctx, { fence })) {
20540
+ continue;
20541
+ }
20480
20542
  const port = result.nextPort || "default";
20481
20543
  const successors = getSuccessors(workflow.definition, step.nodeId, port);
20482
20544
  if (successors.length > 0) {
@@ -20490,7 +20552,9 @@ function startRetryPoller(registry, intervalMs = 5000) {
20490
20552
  continue;
20491
20553
  const errorMsg = err instanceof Error ? err.message : String(err);
20492
20554
  const retryPolicy = node.retry || executor.retryPolicy;
20493
- await checkpointStepFailure(run.id, step.id, errorMsg, step.retryCount, retryPolicy);
20555
+ await checkpointStepFailure(run.id, step.id, errorMsg, step.retryCount, retryPolicy, {
20556
+ fence
20557
+ });
20494
20558
  }
20495
20559
  } catch (err) {
20496
20560
  if (await failRunOnUnreadableReplay(step.runId, err, step.id))
@@ -21119,7 +21183,7 @@ class NotifyExecutor extends BaseExecutor {
21119
21183
  }
21120
21184
  }
21121
21185
  case "slack": {
21122
- const { getSlackApp } = await import("./app-nndcvftq.js");
21186
+ const { getSlackApp } = await import("./app-ag29n14f.js");
21123
21187
  const app = getSlackApp();
21124
21188
  if (!app) {
21125
21189
  return {
@@ -21245,7 +21309,7 @@ var RawLlmOutputSchema = object2({
21245
21309
  async function executeRawLlm(config) {
21246
21310
  let modelName = config.model ?? "google/gemini-3-flash-preview";
21247
21311
  try {
21248
- const { createOpenAI } = await import("./index-6srwvd5b.js");
21312
+ const { createOpenAI } = await import("./index-p4xfz37z.js");
21249
21313
  const llmConfig = await resolveWorkflowLlmConfig(config.model);
21250
21314
  modelName = llmConfig.model;
21251
21315
  const provider = createOpenAI({
@@ -21255,7 +21319,7 @@ async function executeRawLlm(config) {
21255
21319
  });
21256
21320
  const model = provider(llmConfig.model);
21257
21321
  if (config.schema) {
21258
- const { generateObject, jsonSchema } = await import("./index-cbxkmfc5.js");
21322
+ const { generateObject, jsonSchema } = await import("./index-9pn1pfkf.js");
21259
21323
  const { object } = await generateObject({
21260
21324
  model,
21261
21325
  schema: jsonSchema(config.schema),
@@ -21269,7 +21333,7 @@ async function executeRawLlm(config) {
21269
21333
  output: { result: object, model: modelName }
21270
21334
  };
21271
21335
  }
21272
- const { generateText } = await import("./index-cbxkmfc5.js");
21336
+ const { generateText } = await import("./index-9pn1pfkf.js");
21273
21337
  const { text } = await generateText({
21274
21338
  model,
21275
21339
  prompt: config.prompt
@@ -21538,7 +21602,7 @@ class SwarmScriptExecutor extends BaseExecutor {
21538
21602
  const credentials = await buildScriptCredentialBindingsWithFailures({
21539
21603
  agentId: agentId ?? undefined
21540
21604
  });
21541
- const output = await runScript({
21605
+ const output = await runScriptWithRunCredential({
21542
21606
  source: resolved.source,
21543
21607
  args: config.args,
21544
21608
  fsMode: "none",
@@ -21709,8 +21773,8 @@ class ValidateExecutor extends BaseExecutor {
21709
21773
  const interpolatedPrompt = this.deps.interpolate(prompt, context);
21710
21774
  const outputStr = typeof targetOutput === "string" ? targetOutput : JSON.stringify(targetOutput);
21711
21775
  try {
21712
- const { createOpenAI } = await import("./index-6srwvd5b.js");
21713
- const { generateObject, jsonSchema } = await import("./index-cbxkmfc5.js");
21776
+ const { createOpenAI } = await import("./index-p4xfz37z.js");
21777
+ const { generateObject, jsonSchema } = await import("./index-9pn1pfkf.js");
21714
21778
  const llmConfig = await resolveWorkflowLlmConfig();
21715
21779
  const provider = createOpenAI({
21716
21780
  baseURL: llmConfig.baseURL,
@@ -21950,6 +22014,27 @@ init_event_bus();
21950
22014
  init_db3();
21951
22015
  init_steering();
21952
22016
  init_context_key();
22017
+ async function answersInChat(task) {
22018
+ if (task.source === "chat")
22019
+ return true;
22020
+ if (task.source === "system" && task.taskType === "follow-up")
22021
+ return true;
22022
+ if (task.source === "schedule" && task.taskType === "deferred")
22023
+ return true;
22024
+ if (task.source === "system" && task.taskType === "resume" && task.agentId) {
22025
+ return (await getAgentById2(task.agentId))?.isLead === true;
22026
+ }
22027
+ return false;
22028
+ }
22029
+ async function scheduleTaskContextKey(schedule) {
22030
+ if (schedule.taskType === "deferred" && schedule.parentTaskId) {
22031
+ const parent = await getTaskById2(schedule.parentTaskId);
22032
+ if (parent?.contextKey && chatThreadOfContextKey(parent.contextKey) && parent.agentId && schedule.targetAgentId === parent.agentId && schedule.createdByAgentId === parent.agentId && await answersInChat(parent)) {
22033
+ return parent.contextKey;
22034
+ }
22035
+ }
22036
+ return scheduleContextKey({ scheduleId: schedule.id });
22037
+ }
21953
22038
  async function prepareStandaloneScheduleTask(schedule, extraTags = []) {
21954
22039
  if (!schedule.taskTemplate) {
21955
22040
  throw new Error(`Schedule "${schedule.name}" has no taskTemplate (targetType=agent-task)`);
@@ -21968,7 +22053,7 @@ async function prepareStandaloneScheduleTask(schedule, extraTags = []) {
21968
22053
  scheduleId: schedule.id,
21969
22054
  source: "schedule",
21970
22055
  requestedByUserId: schedule.createdBy,
21971
- contextKey: scheduleContextKey({ scheduleId: schedule.id }),
22056
+ contextKey: await scheduleTaskContextKey(schedule),
21972
22057
  parentTaskId: schedule.parentTaskId,
21973
22058
  inheritParentFollowUpConfig: schedule.taskType === "deferred" && !!schedule.parentTaskId
21974
22059
  }, { origin: "schedule" });
@@ -22207,7 +22292,7 @@ async function executeScheduleScript(schedule) {
22207
22292
  let output;
22208
22293
  try {
22209
22294
  const credentials = await buildScriptCredentialBindingsWithFailures({ agentId });
22210
- output = await runScript({
22295
+ output = await runScriptWithRunCredential({
22211
22296
  source: script.source,
22212
22297
  args,
22213
22298
  fsMode: "none",
@@ -24482,7 +24567,7 @@ function setPreloadedTools(server, names) {
24482
24567
  async function applyPreToolCall(name, args, requestInfo, inputSchema) {
24483
24568
  if (requestInfo.callOrigin !== "mcp")
24484
24569
  return { args };
24485
- const dispatcher = await import("./dispatcher-606ydx5v.js");
24570
+ const dispatcher = await import("./dispatcher-nwf9ss0q.js");
24486
24571
  const result = await dispatcher.dispatchPre("pre.tool.call", { tool: name, args, requestInfo }, inputSchema ? {
24487
24572
  validateModify: async (data) => {
24488
24573
  const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
@@ -28587,240 +28672,6 @@ function teardownAzureDevOpsOutbound() {
28587
28672
  // src/http/core.ts
28588
28673
  init_db3();
28589
28674
 
28590
- // src/be/multi-runtime.ts
28591
- init_secret_scrubber();
28592
- init_db3();
28593
- init_users();
28594
- var AGENT_MAX_TASKS_CONFIG_KEY = "AGENT_MAX_TASKS";
28595
- function parseAgentMaxTasksValue(raw) {
28596
- const str = raw.trim();
28597
- if (!/^\d+$/.test(str))
28598
- return null;
28599
- const value = Number(str);
28600
- return value >= 1 && value <= 100 ? value : null;
28601
- }
28602
- function defaultMaxTasksForAgent(agent) {
28603
- return agent.isLead ? 2 : 1;
28604
- }
28605
- async function getAgentMaxTasksConfig(agentId) {
28606
- return (await getSwarmConfigs2({ scope: "agent", scopeId: agentId, key: AGENT_MAX_TASKS_CONFIG_KEY }))[0] ?? null;
28607
- }
28608
- async function reconcileAgentMaxTasksPolicy(agentId) {
28609
- const agent = await getAgentById2(agentId);
28610
- if (!agent)
28611
- return;
28612
- const existing = await getAgentMaxTasksConfig(agentId);
28613
- if (existing) {
28614
- const authoritative = parseAgentMaxTasksValue(existing.value);
28615
- if (authoritative !== null && authoritative !== (agent.maxTasks ?? 1)) {
28616
- await updateAgentMaxTasks2(agentId, authoritative);
28617
- }
28618
- return;
28619
- }
28620
- await upsertSwarmConfig2({
28621
- scope: "agent",
28622
- scopeId: agentId,
28623
- key: AGENT_MAX_TASKS_CONFIG_KEY,
28624
- value: String(agent.maxTasks ?? defaultMaxTasksForAgent(agent)),
28625
- description: "Logical agent max-tasks policy (seeded from agents.maxTasks)"
28626
- });
28627
- }
28628
- async function resetAgentMaxTasksMirror(agentId) {
28629
- const agent = await getAgentById2(agentId);
28630
- if (!agent)
28631
- return;
28632
- await updateAgentMaxTasks2(agentId, defaultMaxTasksForAgent(agent));
28633
- }
28634
- async function upsertSwarmConfigWithPolicyMirror(data) {
28635
- const scopeId = data.scope === "agent" ? data.scopeId : null;
28636
- if (!scopeId || data.key !== AGENT_MAX_TASKS_CONFIG_KEY) {
28637
- return upsertSwarmConfig2(data);
28638
- }
28639
- return await getDbClient2().transaction(async () => {
28640
- const row = await upsertSwarmConfig2(data);
28641
- const value = parseAgentMaxTasksValue(data.value);
28642
- if (value !== null)
28643
- await updateAgentMaxTasks2(scopeId, value);
28644
- return row;
28645
- });
28646
- }
28647
- function rowToRuntimeInstance(row) {
28648
- let metadata = null;
28649
- if (row.metadata) {
28650
- try {
28651
- metadata = JSON.parse(row.metadata);
28652
- } catch {
28653
- metadata = null;
28654
- }
28655
- }
28656
- return {
28657
- id: row.id,
28658
- agentId: row.agent_id,
28659
- poolId: row.pool_id ?? null,
28660
- controllerId: row.controller_id ?? null,
28661
- externalHandle: row.external_handle ? JSON.parse(row.external_handle) : null,
28662
- provisionAttempts: row.provision_attempts ?? 0,
28663
- provisionError: row.provision_error ?? null,
28664
- provisionRequestedAt: row.provision_requested_at ?? null,
28665
- draining: row.draining === 1,
28666
- idleSince: row.idle_since ?? null,
28667
- leaseExpiresAt: row.lease_expires_at ?? null,
28668
- taskId: row.task_id ?? null,
28669
- status: row.status,
28670
- reportedSlots: row.reported_slots,
28671
- credentialReady: row.credential_ready === null ? null : row.credential_ready === 1,
28672
- metadata,
28673
- lastSeenAt: row.last_seen_at,
28674
- createdAt: row.created_at,
28675
- updatedAt: row.updated_at
28676
- };
28677
- }
28678
- function runtimeStaleThresholdMinutes() {
28679
- return Number(process.env.RUNTIME_STALE_THRESHOLD_MIN) || 5;
28680
- }
28681
- function runtimeLivenessCutoff() {
28682
- return new Date(Date.now() - runtimeStaleThresholdMinutes() * 60 * 1000).toISOString();
28683
- }
28684
- async function upsertRuntimeInstance(instance) {
28685
- const metadataJson = instance.metadata ? JSON.stringify(instance.metadata) : null;
28686
- const row = await getDbClient2().transaction(async (tx) => {
28687
- const provisioning = await tx.get("SELECT id FROM runtime_instances WHERE id = ? AND status = 'provisioning' AND agent_id = ?", [instance.id, instance.agentId]);
28688
- const row = await tx.get(`INSERT INTO runtime_instances (id, agent_id, status, reported_slots, metadata)
28689
- VALUES (?, ?, 'active', ?, ?)
28690
- ON CONFLICT(id) DO UPDATE SET
28691
- status = 'active',
28692
- reported_slots = excluded.reported_slots,
28693
- metadata = COALESCE(excluded.metadata, runtime_instances.metadata),
28694
- last_seen_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
28695
- updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
28696
- WHERE runtime_instances.agent_id = excluded.agent_id
28697
- RETURNING *`, [instance.id, instance.agentId, instance.reportedSlots, metadataJson]);
28698
- if (row?.pool_id && provisioning) {
28699
- await tx.run("UPDATE agents SET runtime_provision_attempts = 0, runtime_provision_retry_at = NULL WHERE id = ?", [row.agent_id]);
28700
- await tx.run("UPDATE runtime_pools SET consecutive_failures = 0, circuit_open_until = NULL WHERE id = ?", [row.pool_id]);
28701
- }
28702
- return row;
28703
- });
28704
- return row ? rowToRuntimeInstance(row) : null;
28705
- }
28706
- async function getRuntimeInstanceById(id) {
28707
- const row = await getDbClient2().get("SELECT * FROM runtime_instances WHERE id = ?", [id]);
28708
- return row ? rowToRuntimeInstance(row) : null;
28709
- }
28710
- async function insertProvisioningRuntime(instance) {
28711
- const row = await getDbClient2().get(`INSERT INTO runtime_instances (id, agent_id, pool_id, controller_id, status,
28712
- reported_slots, provision_requested_at)
28713
- VALUES (?, ?, ?, ?, 'provisioning', ?, ?) RETURNING *`, [
28714
- instance.id,
28715
- instance.agentId,
28716
- instance.poolId,
28717
- instance.controllerId,
28718
- instance.reportedSlots ?? 1,
28719
- new Date().toISOString()
28720
- ]);
28721
- return rowToRuntimeInstance(row);
28722
- }
28723
- async function markRuntimeTerminated(id, reason) {
28724
- await getDbClient2().transaction(async () => {
28725
- const runtime = await getRuntimeInstanceById(id);
28726
- if (!runtime)
28727
- return;
28728
- await markRuntimeInstanceOffline(id, runtime.agentId);
28729
- if (runtime.status === "provisioning") {
28730
- await getDbClient2().run("UPDATE runtime_instances SET provision_error = ? WHERE id = ?", [
28731
- scrubSecrets(reason),
28732
- id
28733
- ]);
28734
- }
28735
- await reconcileAgentStatusFromRuntimes(runtime.agentId);
28736
- await revokeRuntimeTokensForRuntime(id);
28737
- });
28738
- }
28739
- async function touchRuntimeInstance(id, agentId) {
28740
- const result = await getDbClient2().run(`UPDATE runtime_instances
28741
- SET last_seen_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
28742
- updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
28743
- WHERE id = ? AND agent_id = ? AND status = 'active' AND last_seen_at >= ?`, [id, agentId, runtimeLivenessCutoff()]);
28744
- return result.changes > 0;
28745
- }
28746
- async function markRuntimeInstanceOffline(id, agentId) {
28747
- const row = await getDbClient2().get(`UPDATE runtime_instances
28748
- SET status = 'offline', updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
28749
- WHERE id = ? AND agent_id = ? RETURNING *`, [id, agentId]);
28750
- return row ? rowToRuntimeInstance(row) : null;
28751
- }
28752
- async function countActiveRuntimeInstancesForAgent(agentId) {
28753
- const result = await getDbClient2().get(`SELECT COUNT(*) as count FROM runtime_instances
28754
- WHERE agent_id = ? AND status = 'active' AND last_seen_at >= ?`, [agentId, runtimeLivenessCutoff()]);
28755
- return result?.count ?? 0;
28756
- }
28757
- async function listRuntimeInstancesForAgent(agentId) {
28758
- const rows = await getDbClient2().query(`SELECT *, (status = 'active' AND last_seen_at >= ?) AS is_live
28759
- FROM runtime_instances
28760
- WHERE agent_id = ?
28761
- ORDER BY created_at ASC, id ASC`, [runtimeLivenessCutoff(), agentId]);
28762
- return rows.map((row) => ({ ...rowToRuntimeInstance(row), isLive: row.is_live === 1 }));
28763
- }
28764
- async function setRuntimeCredentialReady(id, agentId, ready) {
28765
- const result = await getDbClient2().run(`UPDATE runtime_instances
28766
- SET credential_ready = ?, updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
28767
- WHERE id = ? AND agent_id = ? AND status = 'active' AND last_seen_at >= ?`, [ready ? 1 : 0, id, agentId, runtimeLivenessCutoff()]);
28768
- return result.changes > 0;
28769
- }
28770
- async function hasReadyLiveRuntime(agentId) {
28771
- const row = await getDbClient2().get(`SELECT COUNT(*) c FROM runtime_instances
28772
- WHERE agent_id = ? AND status = 'active' AND last_seen_at >= ?
28773
- AND (credential_ready IS NULL OR credential_ready = 1)`, [agentId, runtimeLivenessCutoff()]);
28774
- return (row?.c ?? 0) > 0;
28775
- }
28776
- async function reconcileAgentStatusFromRuntimes(agentId) {
28777
- await getDbClient2().transaction(async () => {
28778
- const agent = await getAgentById2(agentId);
28779
- if (!agent)
28780
- return;
28781
- if (await countActiveRuntimeInstancesForAgent(agentId) === 0) {
28782
- if (agent.status !== "offline")
28783
- await updateAgentStatus2(agentId, "offline");
28784
- return;
28785
- }
28786
- if (!await hasReadyLiveRuntime(agentId)) {
28787
- if (agent.status !== "waiting_for_credentials") {
28788
- await updateAgentStatus2(agentId, "waiting_for_credentials");
28789
- }
28790
- return;
28791
- }
28792
- const next = await getActiveTaskCount2(agentId) > 0 ? "busy" : "idle";
28793
- if (agent.status !== next)
28794
- await updateAgentStatus2(agentId, next);
28795
- });
28796
- }
28797
- async function agentsWithLiveRuntime() {
28798
- const rows = await getDbClient2().query(`SELECT DISTINCT agent_id FROM runtime_instances
28799
- WHERE status = 'active' AND last_seen_at >= ?`, [runtimeLivenessCutoff()]);
28800
- return new Set(rows.map((r) => r.agent_id));
28801
- }
28802
- async function expireStaleRuntimeInstances() {
28803
- if (!isMultiRuntimeEnabled()) {
28804
- return { expired: 0, agentsOffline: 0, pruned: 0 };
28805
- }
28806
- return await getDbClient2().transaction(async (tx) => {
28807
- const cutoff = runtimeLivenessCutoff();
28808
- const stale = await tx.query(`SELECT id, agent_id FROM runtime_instances
28809
- WHERE status = 'active' AND last_seen_at < ? AND pool_id IS NULL`, [cutoff]);
28810
- const pruned = (await tx.run("DELETE FROM runtime_instances WHERE last_seen_at < ? AND status != 'provisioning' AND (pool_id IS NULL OR status = 'offline')", [cutoff])).changes;
28811
- let agentsOffline = 0;
28812
- for (const agentId of new Set(stale.map((r) => r.agent_id))) {
28813
- await reconcileAgentStatusFromRuntimes(agentId);
28814
- if ((await getAgentById2(agentId))?.status === "offline")
28815
- agentsOffline++;
28816
- }
28817
- return { expired: stale.length, agentsOffline, pruned };
28818
- });
28819
- }
28820
- async function listRuntimeInstancesForPool(poolId) {
28821
- return (await getDbClient2().query("SELECT * FROM runtime_instances WHERE pool_id = ? ORDER BY created_at", [poolId])).map(rowToRuntimeInstance);
28822
- }
28823
-
28824
28675
  // src/be/rbac-audit.ts
28825
28676
  init_env_flag();
28826
28677
  init_db3();
@@ -32175,6 +32026,14 @@ function helpText() {
32175
32026
  return ["Commands:", ...CHAT_COMMANDS.map((c) => `/${c.command}: ${c.description}`)].join(`
32176
32027
  `);
32177
32028
  }
32029
+ function welcomeText() {
32030
+ return [
32031
+ "Hi! Send a message here (in a group, mention me) and the swarm picks it up. Each answer arrives as a reply to your message.",
32032
+ "",
32033
+ helpText()
32034
+ ].join(`
32035
+ `);
32036
+ }
32178
32037
  function shortId(task) {
32179
32038
  return task.id.slice(0, 8);
32180
32039
  }
@@ -32220,6 +32079,8 @@ async function runChatCommand(command, threadId, requestedBy) {
32220
32079
  const name = command.replace(/^\//, "").toLowerCase();
32221
32080
  if (name === "help")
32222
32081
  return helpText();
32082
+ if (name === "start")
32083
+ return welcomeText();
32223
32084
  if (!CHAT_COMMANDS.some((c) => c.command === name)) {
32224
32085
  return `Unknown command /${name}.
32225
32086
  ${helpText()}`;
@@ -32931,12 +32792,13 @@ function escapeTelegramHashLines(markdown) {
32931
32792
  }).join(`
32932
32793
  `);
32933
32794
  }
32934
- async function postChunks(adapter, target, text) {
32795
+ async function postChunks(adapter, target, parts, replyFirst) {
32935
32796
  const messageIds = [];
32936
32797
  let threadId;
32937
- for (const chunk of splitChatMessage(text, chatMessageLimit(adapter))) {
32938
- const markdown = adapter === "telegram" ? escapeTelegramHashLines(chunk) : chunk;
32939
- const sent = await target.post({ markdown });
32798
+ const limit = chatMessageLimit(adapter);
32799
+ for (const chunk of parts.flatMap((part) => splitChatMessage(part, limit))) {
32800
+ const message = { markdown: adapter === "telegram" ? escapeTelegramHashLines(chunk) : chunk };
32801
+ const sent = replyFirst && messageIds.length === 0 ? await replyFirst(message) : await target.post(message);
32940
32802
  messageIds.push(sent.id);
32941
32803
  threadId ??= sent.threadId;
32942
32804
  }
@@ -33066,13 +32928,17 @@ async function postChatMessage(args) {
33066
32928
  const chat = getChatInstance(args.adapter);
33067
32929
  if (!chat)
33068
32930
  throw new ChatAdapterUnavailableError(args.adapter);
33069
- const text = scrubSecrets(args.text);
32931
+ const parts = (typeof args.text === "string" ? [args.text] : args.text).map(scrubSecrets);
32932
+ const text = parts.join(`
32933
+
32934
+ `);
33070
32935
  let result;
33071
32936
  let target;
33072
32937
  if (args.threadId) {
33073
32938
  const thread = chat.thread(args.threadId);
33074
32939
  target = thread;
33075
- const sent = await postChunks(args.adapter, thread, text);
32940
+ const replyTo = args.replyToMessageId;
32941
+ const sent = await postChunks(args.adapter, thread, parts, replyTo && thread.adapter.reply ? (message) => thread.reply(replyTo, message) : undefined);
33076
32942
  result = {
33077
32943
  adapter: args.adapter,
33078
32944
  threadId: thread.id,
@@ -33083,7 +32949,7 @@ async function postChatMessage(args) {
33083
32949
  } else if (args.channelId) {
33084
32950
  const channel = chat.channel(args.channelId);
33085
32951
  target = channel;
33086
- const sent = await postChunks(args.adapter, channel, text);
32952
+ const sent = await postChunks(args.adapter, channel, parts);
33087
32953
  result = {
33088
32954
  adapter: args.adapter,
33089
32955
  threadId: sent.threadId ?? channel.id,
@@ -33100,7 +32966,7 @@ async function postChatMessage(args) {
33100
32966
  result.unsentFiles = sent.unsent;
33101
32967
  if (sent.unsent.length > 0) {
33102
32968
  const note = formatUnsentFilesNote(sent.unsent);
33103
- const noted = await postChunks(args.adapter, target, scrubSecrets(note));
32969
+ const noted = await postChunks(args.adapter, target, [scrubSecrets(note)]);
33104
32970
  result.messageIds.push(...noted.messageIds);
33105
32971
  }
33106
32972
  }
@@ -33115,6 +32981,10 @@ async function postChatMessage(args) {
33115
32981
  return result;
33116
32982
  }
33117
32983
 
32984
+ // src/integrations/chat-sdk/reactions.ts
32985
+ init_db3();
32986
+ init_secret_scrubber();
32987
+
33118
32988
  // src/integrations/chat-sdk/router.ts
33119
32989
  init_db3();
33120
32990
 
@@ -33242,6 +33112,63 @@ async function routeChatMessage(text, ctx) {
33242
33112
  return null;
33243
33113
  }
33244
33114
 
33115
+ // src/integrations/chat-sdk/reactions.ts
33116
+ var TELEGRAM_REACTIONS = {
33117
+ accepted: "\uD83D\uDC40",
33118
+ buffered: "\uD83D\uDC40",
33119
+ now: "⚡",
33120
+ steered: "✍",
33121
+ completed: "\uD83D\uDC4D",
33122
+ failed: "\uD83D\uDC4E"
33123
+ };
33124
+ var CHAT_REACTIONS = {
33125
+ telegram: TELEGRAM_REACTIONS
33126
+ };
33127
+ function chatAdapterReacts(adapter) {
33128
+ return adapter in CHAT_REACTIONS;
33129
+ }
33130
+ async function setChatMessageReaction(adapter, threadId, messageId, event) {
33131
+ const emoji = CHAT_REACTIONS[adapter]?.[event];
33132
+ if (!emoji)
33133
+ return;
33134
+ try {
33135
+ const target = getChatInstance(adapter)?.getAdapter(adapter);
33136
+ if (!target)
33137
+ return;
33138
+ assertTrustedChatTarget(threadId);
33139
+ await target.addReaction(threadId, messageId, emoji);
33140
+ } catch (error) {
33141
+ console.warn(scrubSecrets(`[chat-sdk] Could not set the ${event} reaction on ${messageId} in ${threadId}: ${errorMessage(error)}`));
33142
+ }
33143
+ }
33144
+ async function clearChatMessageReactions(adapter, threadId, messageIds) {
33145
+ if (!chatAdapterReacts(adapter) || messageIds.length === 0)
33146
+ return;
33147
+ const target = getChatInstance(adapter)?.getAdapter(adapter);
33148
+ if (!target)
33149
+ return;
33150
+ for (const messageId of messageIds) {
33151
+ try {
33152
+ await target.removeReaction(threadId, messageId, TELEGRAM_REACTIONS.accepted);
33153
+ } catch (error) {
33154
+ console.warn(scrubSecrets(`[chat-sdk] Could not clear the reaction on ${messageId} in ${threadId}: ${errorMessage(error)}`));
33155
+ }
33156
+ }
33157
+ }
33158
+ var CHAT_CHANNEL_SETTINGS_NAMESPACE = "integrations:chat:channel-settings";
33159
+ async function wantsChatTextAck(adapter, channelId) {
33160
+ if (!chatAdapterReacts(adapter))
33161
+ return true;
33162
+ try {
33163
+ const row = await getKv2(CHAT_CHANNEL_SETTINGS_NAMESPACE, chatChannelKey(adapter, channelId));
33164
+ const settings = row?.value;
33165
+ return typeof settings === "object" && settings !== null && settings.textAcks === true;
33166
+ } catch (error) {
33167
+ console.warn(`[chat-sdk] Could not read the channel settings: ${errorMessage(error)}`);
33168
+ return false;
33169
+ }
33170
+ }
33171
+
33245
33172
  // src/integrations/chat-sdk/steering.ts
33246
33173
  init_db3();
33247
33174
  init_steering();
@@ -33435,9 +33362,12 @@ async function handleChatInbound(thread, message, kind) {
33435
33362
  });
33436
33363
  if (steering) {
33437
33364
  console.log(`[chat-sdk] ${adapter} message steered task ${steering.task.id} (${steering.result.outcome})`);
33365
+ await setChatMessageReaction(adapter, thread.id, message.id, "steered");
33366
+ if (!await wantsChatTextAck(adapter, thread.channelId))
33367
+ return;
33438
33368
  try {
33439
33369
  const ack = formatChatSteeringAck(steering.result);
33440
- const sent = await thread.post({ markdown: ack });
33370
+ const sent = thread.adapter.reply ? await thread.reply(message, { markdown: ack }) : await thread.post({ markdown: ack });
33441
33371
  emitChatMessageSent({
33442
33372
  adapter,
33443
33373
  channelId: thread.channelId,
@@ -33454,6 +33384,7 @@ async function handleChatInbound(thread, message, kind) {
33454
33384
  }
33455
33385
  }
33456
33386
  if (text || attachments.length > 0) {
33387
+ const acknowledge = kind !== "subscribed" || isDirectMessage || mentioned || facts.replyToBot;
33457
33388
  bufferChatMessage(thread.id, {
33458
33389
  messageId: message.id,
33459
33390
  channelId: thread.channelId,
@@ -33463,11 +33394,14 @@ async function handleChatInbound(thread, message, kind) {
33463
33394
  botMentioned: mentioned || facts.replyToBot,
33464
33395
  isDirectMessage,
33465
33396
  addressed,
33397
+ reacted: acknowledge && chatAdapterReacts(adapter),
33466
33398
  facts,
33467
33399
  attachments
33468
33400
  });
33469
- if (kind !== "subscribed")
33401
+ if (acknowledge) {
33470
33402
  startTypingKeepalive(adapter, thread.id);
33403
+ await setChatMessageReaction(adapter, thread.id, message.id, immediate ? "now" : "accepted");
33404
+ }
33471
33405
  }
33472
33406
  if (immediate)
33473
33407
  await instantFlushChat(thread.id);
@@ -33585,6 +33519,8 @@ async function flushChatThread(threadId, items, immediate) {
33585
33519
  const isDirectMessage = items.some((item) => item.isDirectMessage);
33586
33520
  const requester = items.find((item) => item.addressed !== "none") ?? first;
33587
33521
  const otherSenders = new Set(items.map((item) => item.userId)).size - 1;
33522
+ const answered = items.at(-1) ?? first;
33523
+ const reacted = items.filter((item) => item.reacted).map((item) => item.messageId);
33588
33524
  const resetAt = await getChatThreadResetAt(threadId);
33589
33525
  const previousTask = await getLatestTaskByContextKey2(contextKey);
33590
33526
  const mostRecentTask = previousTask && resetAt && new Date(previousTask.createdAt).getTime() <= resetAt.getTime() ? null : previousTask;
@@ -33610,6 +33546,7 @@ async function flushChatThread(threadId, items, immediate) {
33610
33546
  if (routeResult.action === "block") {
33611
33547
  console.info(`[chat-sdk] Extension blocked routing for ${threadId}:`, scrubSecrets(routeResult.reason));
33612
33548
  stopTypingKeepalive(threadId);
33549
+ await clearChatMessageReactions(adapter, threadId, reacted);
33613
33550
  return;
33614
33551
  }
33615
33552
  let target = null;
@@ -33625,10 +33562,12 @@ async function flushChatThread(threadId, items, immediate) {
33625
33562
  if (!target) {
33626
33563
  console.log(`[chat-sdk] ${threadId}: message not addressed to the swarm, ignored`);
33627
33564
  stopTypingKeepalive(threadId);
33565
+ await clearChatMessageReactions(adapter, threadId, reacted);
33628
33566
  return;
33629
33567
  }
33630
33568
  if (target.kind === "workflow") {
33631
33569
  stopTypingKeepalive(threadId);
33570
+ await clearChatMessageReactions(adapter, threadId, reacted);
33632
33571
  try {
33633
33572
  const { runId } = await handleWebhookTrigger(target.workflowId, {
33634
33573
  adapter,
@@ -33695,7 +33634,9 @@ ${combined}` : combined;
33695
33634
  requestedByUserId,
33696
33635
  parentTaskId: mostRecentTask?.id,
33697
33636
  inheritParentRequester: false,
33698
- inheritParentOutputSchema: false
33637
+ inheritParentOutputSchema: false,
33638
+ mentionMessageId: answered.messageId,
33639
+ mentionChannelId: first.channelId
33699
33640
  };
33700
33641
  try {
33701
33642
  const { task, unattached } = await createChatTaskWithFiles(description, options, inbound);
@@ -33713,8 +33654,12 @@ ${combined}` : combined;
33713
33654
  await rememberChatThreadRequester(threadId, requester.userId);
33714
33655
  await subscribe(thread);
33715
33656
  startTypingKeepalive(adapter, threadId);
33657
+ await clearChatMessageReactions(adapter, threadId, reacted.filter((id) => id !== answered.messageId));
33658
+ if (!answered.reacted)
33659
+ await setChatMessageReaction(adapter, threadId, answered.messageId, "accepted");
33716
33660
  } else {
33717
33661
  stopTypingKeepalive(threadId);
33662
+ await clearChatMessageReactions(adapter, threadId, reacted);
33718
33663
  }
33719
33664
  } catch (_catch) {
33720
33665
  var _err = _catch, _hasErr = 1;
@@ -33880,18 +33825,56 @@ async function taskOutputChatFiles(taskId) {
33880
33825
  var RELAY_GIVE_UP_AFTER_MS = 24 * 60 * 60 * 1000;
33881
33826
  var SWEEP_EVERY_N_TICKS = 20;
33882
33827
  var EARLY_TICK_DEBOUNCE_MS = 250;
33883
- function formatChatRelayText(task) {
33828
+ function formatChatTaskTag(task, agentName) {
33829
+ return agentName ? `#${shortId(task)} · ${agentName}` : `#${shortId(task)}`;
33830
+ }
33831
+ function relayHeadAndBody(task, agentName) {
33832
+ const tag = formatChatTaskTag(task, agentName);
33884
33833
  const body = (task.output || task.failureReason || "").trim();
33885
33834
  if (task.status === "failed")
33886
- return body ? `**Task failed.**
33887
-
33888
- ${body}` : "**Task failed.**";
33889
- if (task.status === "cancelled") {
33890
- return body ? `**Task cancelled.**
33835
+ return { head: `${tag}
33836
+ **Task failed.**`, body };
33837
+ if (task.status === "cancelled")
33838
+ return { head: `${tag}
33839
+ **Task cancelled.**`, body };
33840
+ return { head: tag, body: body || "Task completed." };
33841
+ }
33842
+ function formatChatRelayText(task, agentName) {
33843
+ const { head, body } = relayHeadAndBody(task, agentName);
33844
+ return body ? `${head}
33891
33845
 
33892
- ${body}` : "**Task cancelled.**";
33846
+ ${body}` : head;
33847
+ }
33848
+ var TELEGRAM_FOLD_CHARS = 1000;
33849
+ var FOLD_LEAD_MAX_CHARS = 280;
33850
+ var FOLD_MARKUP_CHARS = 80;
33851
+ function formatChatRelayMessages(task, adapter, agentName) {
33852
+ const { head, body } = relayHeadAndBody(task, agentName);
33853
+ if (adapter !== "telegram" || body.length <= TELEGRAM_FOLD_CHARS) {
33854
+ return [formatChatRelayText(task, agentName)];
33893
33855
  }
33894
- return body || "Task completed.";
33856
+ const breakAt = body.indexOf(`
33857
+
33858
+ `);
33859
+ const lead = breakAt > 0 && breakAt <= FOLD_LEAD_MAX_CHARS ? body.slice(0, breakAt) : "";
33860
+ const rest = lead ? body.slice(breakAt).trim() : body;
33861
+ const top = lead ? `${head}
33862
+
33863
+ ${lead}` : head;
33864
+ const room = chatMessageLimit(adapter) - top.length - FOLD_MARKUP_CHARS;
33865
+ const pieces = splitChatMessage(rest, room);
33866
+ return pieces.map((piece, index) => {
33867
+ const label = lead ? "Rest of the answer" : "Full answer";
33868
+ const summary = pieces.length > 1 ? `${label} (${index + 1}/${pieces.length})` : label;
33869
+ const block = `<details><summary>${summary}</summary>
33870
+
33871
+ ${piece}
33872
+
33873
+ </details>`;
33874
+ return index === 0 ? `${top}
33875
+
33876
+ ${block}` : block;
33877
+ });
33895
33878
  }
33896
33879
  async function processPendingChatRelays(now = Date.now(), signal) {
33897
33880
  const retired = await giveUpStaleChatRelays2(now, RELAY_GIVE_UP_AFTER_MS);
@@ -33922,16 +33905,21 @@ async function processPendingChatRelays(now = Date.now(), signal) {
33922
33905
  if (!await markChatRelayAttempted2(task.id, now))
33923
33906
  continue;
33924
33907
  try {
33908
+ const agent = task.agentId ? await getAgentById2(task.agentId) : null;
33925
33909
  await postChatMessage({
33926
33910
  adapter: target.adapter,
33927
33911
  threadId: target.threadId,
33928
- text: formatChatRelayText(task),
33912
+ text: formatChatRelayMessages(task, target.adapter, agent?.name),
33929
33913
  taskId: task.id,
33930
- files: await taskOutputChatFiles(task.id)
33914
+ files: await taskOutputChatFiles(task.id),
33915
+ replyToMessageId: task.mentionMessageId
33931
33916
  });
33932
33917
  stopTypingKeepalive(target.threadId);
33933
33918
  await markChatRelayDelivered2(task.id, now);
33934
33919
  console.log(`[chat-sdk] Relayed ${task.status} task ${task.id} to ${target.adapter}`);
33920
+ if (task.mentionMessageId) {
33921
+ await setChatMessageReaction(target.adapter, target.threadId, task.mentionMessageId, terminalReactionEvent(task.status));
33922
+ }
33935
33923
  } catch (error) {
33936
33924
  const message = errorMessage(error);
33937
33925
  await recordChatRelayError2(task.id, message, now);
@@ -34970,7 +34958,7 @@ async function notifySlack(text) {
34970
34958
  return;
34971
34959
  }
34972
34960
  try {
34973
- const { getSlackApp } = await import("./app-nndcvftq.js");
34961
+ const { getSlackApp } = await import("./app-ag29n14f.js");
34974
34962
  const app = getSlackApp();
34975
34963
  if (!app) {
34976
34964
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -35041,7 +35029,7 @@ async function deleteJiraWebhook(webhookId) {
35041
35029
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
35042
35030
  }
35043
35031
  async function overwriteWebhookIds(next) {
35044
- const { getDbClient } = await import("./db-88wcymxt.js");
35032
+ const { getDbClient } = await import("./db-24ck09xy.js");
35045
35033
  await getDbClient().transaction(async (tx) => {
35046
35034
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
35047
35035
  if (!row) {
@@ -108436,7 +108424,7 @@ async function reloadGlobalConfigsAndIntegrations() {
108436
108424
  return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
108437
108425
  }
108438
108426
  async function reloadGlobalConfigsAndIntegrationsInner() {
108439
- const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-5en23s5z.js");
108427
+ const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-1r8wfpzs.js");
108440
108428
  const wasEmbeddingsConfigured = getEmbeddingProvider().isConfigured();
108441
108429
  const updated = await loadGlobalConfigsIntoEnv(true);
108442
108430
  await syncTelemetryEnabled("settings").catch((err) => {
@@ -108452,10 +108440,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
108452
108440
  integrations.push("embeddings");
108453
108441
  }
108454
108442
  if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
108455
- import("./boot-reembed-r8rhf9h8.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
108443
+ import("./boot-reembed-5b3d2eea.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
108456
108444
  console.error("[config-reload] memory backfill failed (non-fatal):", err);
108457
108445
  });
108458
- import("./boot-reembed-vwcj2y5d.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
108446
+ import("./boot-reembed-jsmfrpzf.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
108459
108447
  console.error("[config-reload] script backfill failed (non-fatal):", err);
108460
108448
  });
108461
108449
  }
@@ -114166,7 +114154,8 @@ var registerChatReplyTool = (server) => {
114166
114154
  threadId: thread.threadId,
114167
114155
  text,
114168
114156
  taskId: task.id,
114169
- files: resolved.files
114157
+ files: resolved.files,
114158
+ replyToMessageId: task.mentionMessageId
114170
114159
  });
114171
114160
  return toolOk(`Posted to ${thread.adapter} thread ${sent.threadId}.${unsentFilesSummary(sent.unsentFiles)}`, {
114172
114161
  data: {
@@ -116538,6 +116527,7 @@ init_resolver();
116538
116527
  init_types();
116539
116528
  init_env_flag();
116540
116529
  init_task_attachment_links();
116530
+ init_context_key();
116541
116531
  init_templates2();
116542
116532
  var TaskFollowUpModifySchema = CreateTaskOptionsSchema.pick({
116543
116533
  agentId: true,
@@ -116725,6 +116715,7 @@ ${depLines.join(`
116725
116715
  taskType: "follow-up",
116726
116716
  priority: changes.priority,
116727
116717
  parentTaskId: task.id,
116718
+ contextKey: await deferredWorkChatContextKey(task),
116728
116719
  slackChannelId: task.slackChannelId,
116729
116720
  slackThreadTs: task.slackThreadTs,
116730
116721
  slackUserId: task.slackUserId,
@@ -116732,6 +116723,23 @@ ${depLines.join(`
116732
116723
  inheritParentOutputSchema: false
116733
116724
  }, { origin: "followUp" });
116734
116725
  }
116726
+ var MAX_CONTINUATION_HOPS = 32;
116727
+ async function deferredWorkChatContextKey(task) {
116728
+ if (chatThreadOfContextKey(task.contextKey))
116729
+ return;
116730
+ const seen = new Set;
116731
+ let current = task;
116732
+ while (current && !seen.has(current.id) && seen.size < MAX_CONTINUATION_HOPS) {
116733
+ if (chatThreadOfContextKey(current.contextKey))
116734
+ return current.contextKey;
116735
+ const continuation = current.source === "schedule" && current.taskType === "deferred" || current.source === "system" && current.taskType === "resume";
116736
+ if (!continuation || !current.parentTaskId)
116737
+ return;
116738
+ seen.add(current.id);
116739
+ current = await getTaskById2(current.parentTaskId);
116740
+ }
116741
+ return;
116742
+ }
116735
116743
  async function createResumeFollowUp(args) {
116736
116744
  const parent = await getTaskById2(args.parentId);
116737
116745
  if (!parent)
@@ -122179,8 +122187,8 @@ init_db3();
122179
122187
  init_constants2();
122180
122188
  var QuestionSchema = object2({
122181
122189
  id: string2().describe("Unique ID for the question (used as key in responses)"),
122182
- type: _enum2(["approval", "text", "single-select", "multi-select", "boolean"]).describe("Question type"),
122183
- label: string2().describe("The question text displayed to the user"),
122190
+ type: _enum2(["approval", "text", "single-select", "multi-select", "boolean", "config"]).describe("Question type"),
122191
+ label: string2().optional().describe("The question text displayed to the user (required except for config, which defaults to the key)"),
122184
122192
  required: boolean().optional().describe("Whether this question is required (default: true)"),
122185
122193
  description: string2().optional().describe("Optional help text, rendered as markdown (code fences, images)"),
122186
122194
  placeholder: string2().optional().describe("Placeholder text (for text type)"),
@@ -122192,13 +122200,14 @@ var QuestionSchema = object2({
122192
122200
  })).optional().describe("Options (for single-select/multi-select types)"),
122193
122201
  minSelections: number2().int().min(0).optional().describe("Min selections (for multi-select)"),
122194
122202
  maxSelections: number2().int().min(1).optional().describe("Max selections (for multi-select)"),
122195
- defaultValue: boolean().optional().describe("Default value (for boolean type)")
122203
+ defaultValue: boolean().optional().describe("Default value (for boolean type)"),
122204
+ config: ConfigQuestionSettingsSchema.optional().describe("Settings for a config question: the key and scope to set, plus options or defaultValue for non-secret keys")
122196
122205
  });
122197
122206
  var registerRequestHumanInputTool = (server) => {
122198
122207
  createToolRegistrar(server)("request-human-input", {
122199
122208
  title: "Request human input",
122200
122209
  annotations: { destructiveHint: false },
122201
- description: "Create an approval request and return at once with the request id and URL. The answer arrives later as a hitl-follow-up task. " + "Supports multiple question types: approval (yes/no), text, single-select, " + "multi-select, and boolean. Returns the request ID and URL for the human to respond. " + "The dashboard renders each label and description as markdown: put long content in description, fence code with a language, and put an image URL alone on its own line to show it. " + "No Slack message is sent; share the URL yourself.",
122210
+ description: "Create an approval request and return at once with the request id and URL. The answer arrives later as a hitl-follow-up task. " + "Supports multiple question types: approval (yes/no), text, single-select, " + "multi-select, boolean, and config. Returns the request ID and URL for the human to respond. " + "config asks a person to set one swarm config key on the dashboard; secrets are stored encrypted and you receive only {key, scope, isSecret, status, updatedAt}, never the value. " + "The dashboard renders each label and description as markdown: put long content in description, fence code with a language, and put an image URL alone on its own line to show it. " + "No Slack message is sent; share the URL yourself.",
122202
122211
  inputSchema: object2({
122203
122212
  title: string2().min(1).describe("Title of the approval request"),
122204
122213
  questions: array2(QuestionSchema).min(1).describe("Questions to ask the human"),
@@ -122221,12 +122230,20 @@ var registerRequestHumanInputTool = (server) => {
122221
122230
  sourceTaskId = currentTask.id;
122222
122231
  }
122223
122232
  }
122233
+ const approvers = { policy: "any" };
122234
+ const normalized = await normalizeApprovalQuestions(questions, {
122235
+ approvers,
122236
+ callerAgentId: requestInfo.agentId
122237
+ });
122238
+ if (!normalized.ok) {
122239
+ return toolErr(normalized.error, { data: { yourAgentId: requestInfo.agentId } });
122240
+ }
122224
122241
  const id = crypto.randomUUID();
122225
122242
  const request = await createApprovalRequest2({
122226
122243
  id,
122227
122244
  title,
122228
- questions,
122229
- approvers: { policy: "any" },
122245
+ questions: normalized.questions,
122246
+ approvers,
122230
122247
  sourceTaskId: sourceTaskId ?? undefined,
122231
122248
  timeoutSeconds,
122232
122249
  createdBy: await resolveTaskAuditUserId(sourceTaskId, requestInfo.agentId) ?? undefined
@@ -129793,6 +129810,7 @@ function validateRecurringTiming(merged) {
129793
129810
 
129794
129811
  // src/tools/schedules/patch-schedule.ts
129795
129812
  init_db2();
129813
+ init_rbac();
129796
129814
  init_types();
129797
129815
  var patchScheduleInputSchema = object2({
129798
129816
  key: AssetKeySchema.optional().describe("Move to a logical namespace."),
@@ -129889,6 +129907,14 @@ var registerPatchScheduleTool = (server) => {
129889
129907
  if (!caller) {
129890
129908
  return toolErr("Agent not found.");
129891
129909
  }
129910
+ if (schedule.taskType === "deferred" && !can({
129911
+ principal: { kind: "agent", agentId: caller.id, isLead: caller.isLead },
129912
+ verb: "schedule.deferral.update.any",
129913
+ resource: { kind: "owned", ownerAgentId: schedule.createdByAgentId },
129914
+ source: "mcp"
129915
+ }).allow) {
129916
+ return toolErr(`Schedule "${schedule.name}" defers another agent's task. Only that agent or a lead can change it.`);
129917
+ }
129892
129918
  if (schedule.scheduleType === "one_time" && !schedule.enabled && schedule.lastRunAt) {
129893
129919
  return toolErr(`One-time schedule "${schedule.name}" has already executed. Create a new one instead.`);
129894
129920
  }
@@ -130104,6 +130130,7 @@ init_zod();
130104
130130
  var import_cron_parser4 = __toESM(require_dist2(), 1);
130105
130131
  init_db3();
130106
130132
  init_db2();
130133
+ init_rbac();
130107
130134
  init_types();
130108
130135
  var updateScheduleInputSchema = object2({
130109
130136
  key: AssetKeySchema.optional().describe("Move to a logical namespace."),
@@ -130200,6 +130227,14 @@ var registerUpdateScheduleTool = (server) => {
130200
130227
  if (!caller) {
130201
130228
  return toolErr("Agent not found.");
130202
130229
  }
130230
+ if (schedule.taskType === "deferred" && !can({
130231
+ principal: { kind: "agent", agentId: caller.id, isLead: caller.isLead },
130232
+ verb: "schedule.deferral.update.any",
130233
+ resource: { kind: "owned", ownerAgentId: schedule.createdByAgentId },
130234
+ source: "mcp"
130235
+ }).allow) {
130236
+ return toolErr(`Schedule "${schedule.name}" defers another agent's task. Only that agent or a lead can change it.`);
130237
+ }
130203
130238
  if (schedule.scheduleType === "one_time" && !schedule.enabled && schedule.lastRunAt) {
130204
130239
  return toolErr(`One-time schedule "${schedule.name}" has already executed. Create a new one instead.`);
130205
130240
  }
@@ -133414,23 +133449,6 @@ var registerSlackListChannelsTool = (server) => {
133414
133449
  init_zod();
133415
133450
  init_db3();
133416
133451
  init_rbac();
133417
-
133418
- // src/slack/dm.ts
133419
- function isSlackUserId(id) {
133420
- return /^[UW][A-Z0-9]+$/.test(id);
133421
- }
133422
- async function resolveSlackConversationId(client, channelId) {
133423
- if (!isSlackUserId(channelId))
133424
- return channelId;
133425
- const result = await client.conversations.open({ users: channelId });
133426
- const dmId = result.channel?.id;
133427
- if (!dmId) {
133428
- throw new Error(`conversations.open returned no DM channel for user ${channelId}`);
133429
- }
133430
- return dmId;
133431
- }
133432
-
133433
- // src/tools/slack-post.ts
133434
133452
  var registerSlackPostTool = (server) => {
133435
133453
  createToolRegistrar(server)("slack-post", {
133436
133454
  title: "Post message to Slack channel",
@@ -137454,4 +137472,4 @@ async function createServer(opts = {}) {
137454
137472
  return server;
137455
137473
  }
137456
137474
 
137457
- export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, taskModelPin, resumedTaskModelSelection, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, scopeFromAttachment, backingProviderId, transcribeAudioNotes, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, handleWebhookTrigger, verifyHmacSignature, WebhookError, snapshotAndUpdateWorkflow, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry2, initWorkflows2, dispatchScheduleTarget, calculateNextRun2, startScheduler2, stopScheduler2, runScheduleNow2, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError2, isRegistered2, isExtensionAgentId2, getExtensionBridgeToken2, resolveBridgeCallOrigin2, extensionIdForAgent2, runContext2, registerLoaded2, unregister2, listRegistered2, dispatchPre2, dispatchPost2, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, repointTrackerSyncBySwarmId, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, handleWorkItemCreated, handleWorkItemUpdated, handleWorkItemCommented, handleWorkItemDeleted, handleWorkItemRestored, initAzureDevOpsOutbound, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, insertProvisioningRuntime, markRuntimeTerminated, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, listRuntimeInstancesForPool, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, isBitbucketEnabled, initBitbucket, verifyBitbucketWebhook, isDuplicateDelivery, markDeliveryProcessed, pullRequestEventOf, pullRequestCommentEventOf, handlePullRequestCreated2, handlePullRequestCommentCreated, handlePullRequestClosed, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2, handleNote, handlePipeline, isChatSdkEnabled, getChatSdkConfig, errorMessage, resolveAdapterApiUrl, trackBackground, TelegramBotApiError, callTelegramBotApi, isTrustedTeamsServiceUrl, isChatSdkStopping, startChatSdk, getChatInstance, isChatAdapterConfigured, getChatSdkHealth, stopChatSdk, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, isCookieSafePageId, extractPageSession, extractLegacyPageSession, extractAndVerifyCookie, pageSessionSetCookies, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, MCP_MAX_TOOL_INPUT_ELEMENTS, MCP_MAX_REQUEST_BODY_BYTES, userCtx, requestPrincipal, agentFirstPrincipal, rejectGuest, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, getPageEditCounter, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, MemoryKeyError, refreshLinks, indexMemoryContent, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, sessionAccessTopic, sessionPresenceRoot, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };
137475
+ export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, taskModelPin, resumedTaskModelSelection, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, scopeFromAttachment, backingProviderId, transcribeAudioNotes, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, handleWebhookTrigger, verifyHmacSignature, WebhookError, snapshotAndUpdateWorkflow, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry2, initWorkflows2, dispatchScheduleTarget, calculateNextRun2, startScheduler2, stopScheduler2, runScheduleNow2, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError2, isRegistered2, isExtensionAgentId2, getExtensionBridgeToken2, resolveBridgeCallOrigin2, extensionIdForAgent2, runContext2, registerLoaded2, unregister2, listRegistered2, dispatchPre2, dispatchPost2, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, repointTrackerSyncBySwarmId, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, handleWorkItemCreated, handleWorkItemUpdated, handleWorkItemCommented, handleWorkItemDeleted, handleWorkItemRestored, initAzureDevOpsOutbound, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, isBitbucketEnabled, initBitbucket, verifyBitbucketWebhook, isDuplicateDelivery, markDeliveryProcessed, pullRequestEventOf, pullRequestCommentEventOf, handlePullRequestCreated2, handlePullRequestCommentCreated, handlePullRequestClosed, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2, handleNote, handlePipeline, isChatSdkEnabled, getChatSdkConfig, errorMessage, resolveAdapterApiUrl, trackBackground, TelegramBotApiError, callTelegramBotApi, isTrustedTeamsServiceUrl, isChatSdkStopping, startChatSdk, getChatInstance, isChatAdapterConfigured, getChatSdkHealth, stopChatSdk, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, isCookieSafePageId, extractPageSession, extractLegacyPageSession, extractAndVerifyCookie, pageSessionSetCookies, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, MCP_MAX_TOOL_INPUT_ELEMENTS, MCP_MAX_REQUEST_BODY_BYTES, userCtx, requestPrincipal, agentFirstPrincipal, rejectGuest, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, getPageEditCounter, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, MemoryKeyError, refreshLinks, indexMemoryContent, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, sessionAccessTopic, sessionPresenceRoot, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };