agent-tower 0.7.0-beta.0 → 0.7.0-beta.2

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 (150) hide show
  1. package/dist/runtime/acp/acp-driver.d.ts.map +1 -1
  2. package/dist/runtime/acp/acp-driver.js +25 -2
  3. package/dist/runtime/acp/acp-driver.js.map +1 -1
  4. package/dist/services/__tests__/member-heartbeat-scheduler.test.js +29 -0
  5. package/dist/services/__tests__/member-heartbeat-scheduler.test.js.map +1 -1
  6. package/dist/services/__tests__/team-member-admission-barrier.test.d.ts +2 -0
  7. package/dist/services/__tests__/team-member-admission-barrier.test.d.ts.map +1 -0
  8. package/dist/services/__tests__/team-member-admission-barrier.test.js +51 -0
  9. package/dist/services/__tests__/team-member-admission-barrier.test.js.map +1 -0
  10. package/dist/services/__tests__/team-reconciler.service.test.js +115 -0
  11. package/dist/services/__tests__/team-reconciler.service.test.js.map +1 -1
  12. package/dist/services/__tests__/team-scheduler.service.test.js +87 -0
  13. package/dist/services/__tests__/team-scheduler.service.test.js.map +1 -1
  14. package/dist/services/member-heartbeat-scheduler.d.ts +11 -0
  15. package/dist/services/member-heartbeat-scheduler.d.ts.map +1 -1
  16. package/dist/services/member-heartbeat-scheduler.js +31 -2
  17. package/dist/services/member-heartbeat-scheduler.js.map +1 -1
  18. package/dist/services/session-manager.d.ts.map +1 -1
  19. package/dist/services/session-manager.js +1 -1
  20. package/dist/services/session-manager.js.map +1 -1
  21. package/dist/services/team-member-admission-barrier.d.ts +23 -1
  22. package/dist/services/team-member-admission-barrier.d.ts.map +1 -1
  23. package/dist/services/team-member-admission-barrier.js +68 -2
  24. package/dist/services/team-member-admission-barrier.js.map +1 -1
  25. package/dist/services/team-reconciler.service.d.ts +20 -2
  26. package/dist/services/team-reconciler.service.d.ts.map +1 -1
  27. package/dist/services/team-reconciler.service.js +112 -20
  28. package/dist/services/team-reconciler.service.js.map +1 -1
  29. package/dist/services/team-scheduler.service.d.ts +7 -0
  30. package/dist/services/team-scheduler.service.d.ts.map +1 -1
  31. package/dist/services/team-scheduler.service.js +15 -5
  32. package/dist/services/team-scheduler.service.js.map +1 -1
  33. package/dist/web/assets/{AgentDemoPage-Cb99MrCc.js → AgentDemoPage-DP9u0ylA.js} +1 -1
  34. package/dist/web/assets/{AgentEnvironmentSettingsPage-ebCjwkrN.js → AgentEnvironmentSettingsPage-B571SLF5.js} +1 -1
  35. package/dist/web/assets/{AgentLogo-DonTQxM9.js → AgentLogo-VGcaaJum.js} +1 -1
  36. package/dist/web/assets/ConversationPage-CbMlQ5UC.js +3 -0
  37. package/dist/web/assets/CreateTaskInput-kkWy5nmc.js +1 -0
  38. package/dist/web/assets/{DemoPage-Bgivi3Ks.js → DemoPage-CpMV8Rv7.js} +1 -1
  39. package/dist/web/assets/{GeneralSettingsPage-DvMYB2cP.js → GeneralSettingsPage-BvME4SJc.js} +1 -1
  40. package/dist/web/assets/{Icons-CjfPc49M.js → Icons-DXzgw2xT.js} +1 -1
  41. package/dist/web/assets/{LoadingPreviewPage-CYzE_rah.js → LoadingPreviewPage-D6OzaV9-.js} +1 -1
  42. package/dist/web/assets/{McpSettingsPage-D5OEjiw4.js → McpSettingsPage-CCWuZ-IU.js} +1 -1
  43. package/dist/web/assets/{MemberAvatar-CK6Kg4RE.js → MemberAvatar-DeKYSBH9.js} +1 -1
  44. package/dist/web/assets/{NotificationSettingsPage-G7b4V0bX.js → NotificationSettingsPage-BOhJqIXv.js} +1 -1
  45. package/dist/web/assets/{ProfileSettingsPage-nKzInN5R.js → ProfileSettingsPage-BEMuDjhF.js} +1 -1
  46. package/dist/web/assets/{ProjectKanbanPage-BbRguX0a.js → ProjectKanbanPage-Ka243_RU.js} +5 -5
  47. package/dist/web/assets/{ProjectSettingsPage-B_uG_eME.js → ProjectSettingsPage-sE0Thu7d.js} +1 -1
  48. package/dist/web/assets/{ProviderSettingsPage-Yhr6QSK3.js → ProviderSettingsPage-BCXTXcbc.js} +1 -1
  49. package/dist/web/assets/{SettingsMasterDetail-fY_-qGyA.js → SettingsMasterDetail-DmqYixrL.js} +1 -1
  50. package/dist/web/assets/{TeamSettingsPage-C3bS2GiK.js → TeamSettingsPage-Dxk7-1fD.js} +1 -1
  51. package/dist/web/assets/{arc-BO0W2mHj.js → arc-Bl7tPfS7.js} +1 -1
  52. package/dist/web/assets/{architectureDiagram-3BPJPVTR-C3cEkBBe.js → architectureDiagram-3BPJPVTR-CoP7qomY.js} +1 -1
  53. package/dist/web/assets/{arrow-left-KfI6LIDH.js → arrow-left-4_9exfZH.js} +1 -1
  54. package/dist/web/assets/{blockDiagram-GPEHLZMM-DWXMs31a.js → blockDiagram-GPEHLZMM-Dyj3wCtX.js} +1 -1
  55. package/dist/web/assets/{c4Diagram-AAUBKEIU-Br4Xlw_Z.js → c4Diagram-AAUBKEIU-BHpYwHH5.js} +1 -1
  56. package/dist/web/assets/channel-D6ei4By-.js +1 -0
  57. package/dist/web/assets/check-CIGH6GLr.js +1 -0
  58. package/dist/web/assets/{chevron-down-BeBVnkqU.js → chevron-down-B8PIP1yU.js} +1 -1
  59. package/dist/web/assets/{chevron-right-Q1Dgt2I3.js → chevron-right-h-JkCAHM.js} +1 -1
  60. package/dist/web/assets/{chevron-up-D2HXcF3G.js → chevron-up-C5SQd6qy.js} +1 -1
  61. package/dist/web/assets/{chunk-2J33WTMH-BX5SFZtu.js → chunk-2J33WTMH--mm3IA_q.js} +1 -1
  62. package/dist/web/assets/{chunk-4BX2VUAB-CQvYESAm.js → chunk-4BX2VUAB-DSTjg6vT.js} +1 -1
  63. package/dist/web/assets/{chunk-55IACEB6-D9YFdDf3.js → chunk-55IACEB6-BMI8DRl6.js} +1 -1
  64. package/dist/web/assets/{chunk-727SXJPM-BUCrEURW.js → chunk-727SXJPM-DB6yt8nI.js} +1 -1
  65. package/dist/web/assets/{chunk-AQP2D5EJ-C8ERMAty.js → chunk-AQP2D5EJ-BMFO2BIQ.js} +1 -1
  66. package/dist/web/assets/{chunk-FMBD7UC4-CzEZabFM.js → chunk-FMBD7UC4-BWW53Tgv.js} +1 -1
  67. package/dist/web/assets/{chunk-ND2GUHAM-Dw35tn0f.js → chunk-ND2GUHAM-3Q1rz4Rn.js} +1 -1
  68. package/dist/web/assets/{chunk-QZHKN3VN-CR7z6_1v.js → chunk-QZHKN3VN-DHZfBhTv.js} +1 -1
  69. package/dist/web/assets/{circle-alert-Dwtt3OAP.js → circle-alert-B2WJJFVc.js} +1 -1
  70. package/dist/web/assets/classDiagram-4FO5ZUOK-Dy0gEbpJ.js +1 -0
  71. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-Dy0gEbpJ.js +1 -0
  72. package/dist/web/assets/{code-block-OCS4YCEC-CAzJ3mQn.js → code-block-OCS4YCEC-DAvNvPo_.js} +1 -1
  73. package/dist/web/assets/{confirm-dialog-BcfJ2Xus.js → confirm-dialog-59aNupkb.js} +1 -1
  74. package/dist/web/assets/{cose-bilkent-S5V4N54A-CUXR9dk3.js → cose-bilkent-S5V4N54A-BkBXPAOW.js} +1 -1
  75. package/dist/web/assets/{cssMode-BpC8I4Ek.js → cssMode-r4PsUEeI.js} +1 -1
  76. package/dist/web/assets/{dagre-BM42HDAG-Dhy7S5s1.js → dagre-BM42HDAG-0o3tAN58.js} +1 -1
  77. package/dist/web/assets/{diagram-2AECGRRQ-DIR5PGZF.js → diagram-2AECGRRQ-BaozWVAC.js} +1 -1
  78. package/dist/web/assets/{diagram-5GNKFQAL-DzXKfh_N.js → diagram-5GNKFQAL-BQGxsEX-.js} +1 -1
  79. package/dist/web/assets/{diagram-KO2AKTUF-us7dQ7xA.js → diagram-KO2AKTUF-BhOfCrvE.js} +1 -1
  80. package/dist/web/assets/{diagram-LMA3HP47-BjK9ExKN.js → diagram-LMA3HP47-1C0Ajian.js} +1 -1
  81. package/dist/web/assets/{diagram-OG6HWLK6-BTx88v4L.js → diagram-OG6HWLK6-BZsvylQi.js} +1 -1
  82. package/dist/web/assets/{erDiagram-TEJ5UH35-8rgd6uCk.js → erDiagram-TEJ5UH35-BODPoCQX.js} +1 -1
  83. package/dist/web/assets/{flowDiagram-I6XJVG4X-C47DsydX.js → flowDiagram-I6XJVG4X-B0BsMsro.js} +1 -1
  84. package/dist/web/assets/{folder-picker-NzVodD5j.js → folder-picker-B5RdK3CX.js} +1 -1
  85. package/dist/web/assets/{freemarker2-Gzu5EJMh.js → freemarker2-B62GnwxO.js} +1 -1
  86. package/dist/web/assets/{ganttDiagram-6RSMTGT7-B7qxtFDa.js → ganttDiagram-6RSMTGT7-BsXOoMru.js} +1 -1
  87. package/dist/web/assets/{gitGraphDiagram-PVQCEYII-DtXsV-rD.js → gitGraphDiagram-PVQCEYII-DVuq4oVA.js} +1 -1
  88. package/dist/web/assets/{handlebars-3Znn7m4J.js → handlebars-BBm4KBDp.js} +1 -1
  89. package/dist/web/assets/{html-Dgt18Ofs.js → html-BlMJourI.js} +1 -1
  90. package/dist/web/assets/{htmlMode-C2t1O0sW.js → htmlMode-vGjPTlal.js} +1 -1
  91. package/dist/web/assets/{index-BVh0eL1_.js → index-BziFEuBL.js} +4 -4
  92. package/dist/web/assets/{index--1agBpnq.js → index-DfRNL5pP.js} +4 -4
  93. package/dist/web/assets/index-KjsBZlkg.css +1 -0
  94. package/dist/web/assets/{infoDiagram-5YYISTIA-AQRMJJ6t.js → infoDiagram-5YYISTIA-CkI-s2fN.js} +1 -1
  95. package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-CTcfBywF.js → ishikawaDiagram-YF4QCWOH-DExbu0jt.js} +1 -1
  96. package/dist/web/assets/javascript-CnnNs3bZ.js +1 -0
  97. package/dist/web/assets/{journeyDiagram-JHISSGLW-CRv0PNLh.js → journeyDiagram-JHISSGLW-C03_8hib.js} +1 -1
  98. package/dist/web/assets/{jsonMode-DQPoQ9kR.js → jsonMode-SxmrKu-q.js} +1 -1
  99. package/dist/web/assets/{kanban-definition-UN3LZRKU-AcoPh0xh.js → kanban-definition-UN3LZRKU-CkQ5JqTm.js} +1 -1
  100. package/dist/web/assets/{layers-DePAliGw.js → layers-DVjF8vaY.js} +1 -1
  101. package/dist/web/assets/{linear-GlxaBVoM.js → linear-VXyesiU2.js} +1 -1
  102. package/dist/web/assets/{liquid-Dr6EmgCe.js → liquid-B_CJMcDS.js} +1 -1
  103. package/dist/web/assets/{lspLanguageFeatures-DN91604C.js → lspLanguageFeatures-D46XQnYj.js} +1 -1
  104. package/dist/web/assets/{mdx-JG8OT2YG.js → mdx-B2i6poYS.js} +1 -1
  105. package/dist/web/assets/mermaid-NOHMQCX5-Cxj8y3xL.js +125 -0
  106. package/dist/web/assets/{message-square-DWgJpKCx.js → message-square-BleDaJqD.js} +1 -1
  107. package/dist/web/assets/{mindmap-definition-RKZ34NQL-DGrhHpUO.js → mindmap-definition-RKZ34NQL-OB13sryT.js} +1 -1
  108. package/dist/web/assets/{modal-CORyqdln.js → modal-DCycqy3L.js} +1 -1
  109. package/dist/web/assets/{monaco-ORn-kQwM.js → monaco-C5uCiSc1.js} +3 -3
  110. package/dist/web/assets/{pencil-B1BeYe1f.js → pencil-7Lu7CiFO.js} +1 -1
  111. package/dist/web/assets/{pieDiagram-4H26LBE5-BX2kHm8X.js → pieDiagram-4H26LBE5-CU-pnTSj.js} +1 -1
  112. package/dist/web/assets/{python-v-kAqpdQ.js → python-CdqaVxbU.js} +1 -1
  113. package/dist/web/assets/{quadrantDiagram-W4KKPZXB-D8kpdSHK.js → quadrantDiagram-W4KKPZXB-yZ7s-n8V.js} +1 -1
  114. package/dist/web/assets/{razor-1mzCjQ7_.js → razor-BZtfxDHk.js} +1 -1
  115. package/dist/web/assets/{requirementDiagram-4Y6WPE33-BeCKrFYk.js → requirementDiagram-4Y6WPE33-B0anLb96.js} +1 -1
  116. package/dist/web/assets/{sankeyDiagram-5OEKKPKP-BhppOHK-.js → sankeyDiagram-5OEKKPKP-DHcV9eve.js} +1 -1
  117. package/dist/web/assets/{select-C0_GwcaL.js → select-EnAkHFwg.js} +1 -1
  118. package/dist/web/assets/{sequenceDiagram-3UESZ5HK-kd48NbrY.js → sequenceDiagram-3UESZ5HK-DqgRRD9W.js} +1 -1
  119. package/dist/web/assets/{server-ezmEd1Bn.js → server-a_4ZRCwE.js} +1 -1
  120. package/dist/web/assets/{stateDiagram-AJRCARHV-BVEJJ862.js → stateDiagram-AJRCARHV-BM_vAe4X.js} +1 -1
  121. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-DXSW0BBn.js +1 -0
  122. package/dist/web/assets/{switch-DTs2bsdf.js → switch-D_UoJD1K.js} +1 -1
  123. package/dist/web/assets/{textarea-DDugro1C.js → textarea-Cmy7-X_E.js} +1 -1
  124. package/dist/web/assets/{timeline-definition-PNZ67QCA-DSTFfNuv.js → timeline-definition-PNZ67QCA-BRstBzgi.js} +1 -1
  125. package/dist/web/assets/{trash-2-0qxC5GZF.js → trash-2-0UA8zJ8I.js} +1 -1
  126. package/dist/web/assets/{tsMode-BiIcawoi.js → tsMode-BASXySxT.js} +1 -1
  127. package/dist/web/assets/{typescript-ChINO0ge.js → typescript-DbOfWuuq.js} +1 -1
  128. package/dist/web/assets/{upload-Bvn4pVZf.js → upload-CfzBeWxL.js} +1 -1
  129. package/dist/web/assets/{use-profiles-DQpUUzXs.js → use-profiles-MVQfFrhT.js} +1 -1
  130. package/dist/web/assets/{use-projects-BQB2BPEN.js → use-projects-CJ8Wn6Xl.js} +1 -1
  131. package/dist/web/assets/{use-providers--I6m_J5h.js → use-providers-DvV0mdqo.js} +1 -1
  132. package/dist/web/assets/{useNormalizedLogs-BB31QSMo.js → useNormalizedLogs-D8-yjxOI.js} +1 -1
  133. package/dist/web/assets/{vennDiagram-CIIHVFJN-CQ8tm8nY.js → vennDiagram-CIIHVFJN-DzhupKpF.js} +1 -1
  134. package/dist/web/assets/{wardley-L42UT6IY-DKg1J16d.js → wardley-L42UT6IY-BwWhS3dk.js} +1 -1
  135. package/dist/web/assets/{wardleyDiagram-YWT4CUSO-DnqGz1sa.js → wardleyDiagram-YWT4CUSO-iG6xXnIJ.js} +1 -1
  136. package/dist/web/assets/{xml-YFMD1O7m.js → xml-Dn2Ep0JI.js} +1 -1
  137. package/dist/web/assets/{xychartDiagram-2RQKCTM6-BTCVgq8k.js → xychartDiagram-2RQKCTM6-hgKK9aU8.js} +1 -1
  138. package/dist/web/assets/{yaml-pAIxoEG3.js → yaml-CA2Cgl3R.js} +1 -1
  139. package/dist/web/index.html +2 -2
  140. package/package.json +1 -1
  141. package/dist/web/assets/ConversationPage-Bd1WHiCB.js +0 -3
  142. package/dist/web/assets/CreateTaskInput-C9aO7QVE.js +0 -1
  143. package/dist/web/assets/channel-TREDjZBM.js +0 -1
  144. package/dist/web/assets/check-VbbiSgv8.js +0 -1
  145. package/dist/web/assets/classDiagram-4FO5ZUOK-C8tJPglt.js +0 -1
  146. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-C8tJPglt.js +0 -1
  147. package/dist/web/assets/index-CVgeXPf_.css +0 -1
  148. package/dist/web/assets/javascript-BfysNn1k.js +0 -1
  149. package/dist/web/assets/mermaid-NOHMQCX5-Cc97ICqZ.js +0 -122
  150. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-aOH6_7W_.js +0 -1
@@ -8,6 +8,7 @@ import { AgentType, TaskStatus } from '../../types/index.js';
8
8
  import { ServiceError } from '../../errors.js';
9
9
  import { TEAM_ROOM_SYSTEM_SHARED_PROTOCOL } from '../../prompts/team-room-system-shared-protocol.js';
10
10
  import { TeamLockService } from '../team-lock.service.js';
11
+ import { acquireTeamMemberAdmission } from '../team-member-admission-barrier.js';
11
12
  const testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-tower-team-scheduler-'));
12
13
  const dbPath = path.join(testDir, 'test.db');
13
14
  process.env.AGENT_TOWER_DATABASE_URL = `file:${dbPath}`;
@@ -17,6 +18,7 @@ const serverRoot = path.resolve(__dirname, '../../..');
17
18
  const schemaPath = path.join(serverRoot, 'prisma/schema.prisma');
18
19
  let TeamSchedulerService;
19
20
  let TeamRunService;
21
+ let TeamReconcilerService;
20
22
  let prisma;
21
23
  let CommandBuildError;
22
24
  let ExecutorNotFoundError;
@@ -225,11 +227,13 @@ describe('TeamSchedulerService', () => {
225
227
  });
226
228
  const serviceModule = await import('../team-scheduler.service.js');
227
229
  const teamRunServiceModule = await import('../team-run.service.js');
230
+ const reconcilerModule = await import('../team-reconciler.service.js');
228
231
  const utilsModule = await import('../../utils/index.js');
229
232
  const commandBuilderModule = await import('../../executors/command-builder.js');
230
233
  const startErrorModule = await import('../../executors/start-error.js');
231
234
  TeamSchedulerService = serviceModule.TeamSchedulerService;
232
235
  TeamRunService = teamRunServiceModule.TeamRunService;
236
+ TeamReconcilerService = reconcilerModule.TeamReconcilerService;
233
237
  prisma = utilsModule.prisma;
234
238
  CommandBuildError = commandBuilderModule.CommandBuildError;
235
239
  ExecutorNotFoundError = startErrorModule.ExecutorNotFoundError;
@@ -3133,5 +3137,88 @@ describe('TeamSchedulerService', () => {
3133
3137
  where: { id: requests.get(last.teamRun.id).id },
3134
3138
  })).resolves.toMatchObject({ status: 'STARTED' });
3135
3139
  });
3140
+ it('answers stop with MEMBER_ADMISSION_BUSY when the member barrier never frees up', async () => {
3141
+ const { teamRun, members } = await createTeamRunFixture();
3142
+ const releaseStuckOwner = await acquireTeamMemberAdmission(teamRun.id, members[0].id, {
3143
+ holder: 'stuck-owner',
3144
+ });
3145
+ service = new TeamSchedulerService(lockService, {
3146
+ workspaceService: createWorkspaceServiceMock(),
3147
+ sessionManager: createSessionManagerMock(),
3148
+ getProviderById: createProviderLookup(),
3149
+ memberAdmissionTimeoutMs: 25,
3150
+ });
3151
+ const startedAt = Date.now();
3152
+ await expect(service.stopMemberWork(teamRun.id, members[0].id)).rejects.toMatchObject({
3153
+ name: 'MemberAdmissionBusyError',
3154
+ code: 'MEMBER_ADMISSION_BUSY',
3155
+ statusCode: 409,
3156
+ });
3157
+ expect(Date.now() - startedAt).toBeLessThan(1_000);
3158
+ releaseStuckOwner();
3159
+ });
3160
+ it('answers stop after a dead session is reclaimed mid-invocation', async () => {
3161
+ const { workspace, teamRun, members } = await createTeamRunFixture();
3162
+ const request = await createWorkRequest({
3163
+ teamRunId: teamRun.id,
3164
+ targetMemberId: members[0].id,
3165
+ status: 'STARTED',
3166
+ });
3167
+ const session = await prisma.session.create({
3168
+ data: {
3169
+ workspaceId: workspace.id,
3170
+ agentType: AgentType.CODEX,
3171
+ providerId: members[0].providerId,
3172
+ prompt: 'In-flight work',
3173
+ status: 'FAILED',
3174
+ },
3175
+ });
3176
+ const invocation = await prisma.agentInvocation.create({
3177
+ data: {
3178
+ teamRunId: teamRun.id,
3179
+ workRequestId: request.id,
3180
+ memberId: members[0].id,
3181
+ workspaceId: workspace.id,
3182
+ sessionId: session.id,
3183
+ status: 'WAITING_ROOM_REPLY',
3184
+ roomReplyReminderCount: 1,
3185
+ nextRoomReplyReminderAt: new Date(0),
3186
+ },
3187
+ });
3188
+ const reconciler = new TeamReconcilerService({
3189
+ scheduler: {
3190
+ releaseInvocationLocks: (invocationId) => lockService.releaseByOwner(invocationId),
3191
+ startNextSessions: vi.fn(async () => []),
3192
+ },
3193
+ sessionMessenger: { sendMessage: vi.fn(async () => null) },
3194
+ now: () => new Date(),
3195
+ scheduleReminders: false,
3196
+ });
3197
+ service = new TeamSchedulerService(lockService, {
3198
+ workspaceService: createWorkspaceServiceMock(),
3199
+ sessionManager: createSessionManagerMock(),
3200
+ getProviderById: createProviderLookup(),
3201
+ memberAdmissionTimeoutMs: 500,
3202
+ });
3203
+ const reclaimed = await Promise.race([
3204
+ reconciler.reconcileDueRoomReplyReminders(),
3205
+ new Promise((resolve) => setTimeout(() => resolve('TIMEOUT'), 2_000)),
3206
+ ]);
3207
+ expect(reclaimed).not.toBe('TIMEOUT');
3208
+ await expect(prisma.agentInvocation.findUniqueOrThrow({ where: { id: invocation.id } })).resolves.toMatchObject({
3209
+ status: 'FAILED',
3210
+ });
3211
+ await expect(prisma.workRequest.findUniqueOrThrow({ where: { id: request.id } })).resolves.toMatchObject({
3212
+ status: 'FAILED',
3213
+ });
3214
+ const startedAt = Date.now();
3215
+ const stopped = await Promise.race([
3216
+ service.stopMemberWork(teamRun.id, members[0].id),
3217
+ new Promise((resolve) => setTimeout(() => resolve('TIMEOUT'), 2_000)),
3218
+ ]);
3219
+ expect(stopped).not.toBe('TIMEOUT');
3220
+ expect(Date.now() - startedAt).toBeLessThan(1_500);
3221
+ expect(stopped).toMatchObject({ stoppedSessionIds: [], cancelledInvocationIds: [] });
3222
+ });
3136
3223
  });
3137
3224
  //# sourceMappingURL=team-scheduler.service.test.js.map