sessionStop.ts 1.2 KB

12345678910111213141516171819202122
  1. import { setTimeout as delay } from 'node:timers/promises'
  2. import { HttpError } from './errors.js'
  3. /** Interrupt acknowledgement only requests cancellation; native tools may still be running. */
  4. export async function waitForHermesSessionIdle(
  5. rpc: (method: string, params: Record<string, unknown>) => Promise<any>,
  6. sessionId: string,
  7. profile: string,
  8. options: { signal?: AbortSignal; timeoutMs?: number; pollMs?: number } = {},
  9. ): Promise<void> {
  10. const deadline = Date.now() + (options.timeoutMs ?? 20_000)
  11. for (;;) {
  12. options.signal?.throwIfAborted()
  13. const state = await rpc('session.active_list', { profile, current_session_id: sessionId })
  14. if (!Array.isArray(state?.sessions)) throw new HttpError(502, 'Hermes 停止状态无效,原执行仍需核对', 'session_stop_unconfirmed')
  15. // Finalized sessions disappear from Hermes' live list.
  16. const session = state.sessions.find((item: { id?: string }) => item.id === sessionId)
  17. if (!session || session.status === 'idle') return
  18. if (Date.now() >= deadline) throw new HttpError(409, 'Hermes 原任务尚未停止,请等待执行结束后重试', 'session_still_stopping')
  19. await delay(options.pollMs ?? 100, undefined, { signal: options.signal })
  20. }
  21. }