UNPKG

@openai/agents-core

Version:

The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.

215 lines • 6.36 kB
const managedHookStateBySession = new WeakMap(); export function registerSandboxPreStopHook(session, hook) { const state = getManagedHookState(session); state.hooks.add(hook); state.ran = false; if (session.registerPreStopHook) { registerProviderManagedPreStopHook(session, state); return () => { unregisterManagedHook(state, hook); }; } installManagedPreStopHooks(session, state); return () => { unregisterManagedHook(state, hook); }; } export function hasSessionCleanup(session) { return Boolean(session.runPreStopHooks || hasManagedPreStopHooks(session) || session.preStop || session.stop || session.shutdown || session.delete || session.close); } export async function runSandboxSessionPreStopHooks(session) { await runManagedPreStopHooksForSession(session); await session.runPreStopHooks?.(); } export async function runSandboxSessionPreStop(session, options) { const lifecycleOptions = cleanupLifecycleOptions(options); let preStopError; const runPreStop = async (preStop) => { try { await preStop(); } catch (error) { preStopError ??= error; } }; if (session.runPreStopHooks || hasManagedPreStopHooks(session)) { await runPreStop(async () => { await runSandboxSessionPreStopHooks(session); }); } if (session.preStop) { await runPreStop(async () => { await session.preStop(lifecycleOptions); }); } if (preStopError) { throw preStopError; } } export async function cleanupSandboxSession(session, options) { const lifecycleOptions = cleanupLifecycleOptions(options); let cleanupError; let usedStandardLifecycle = false; const runCleanup = async (cleanup) => { try { await cleanup(); } catch (error) { cleanupError ??= error; } }; if (session.runPreStopHooks || hasManagedPreStopHooks(session) || session.preStop) { await runCleanup(async () => { await runSandboxSessionPreStop(session, lifecycleOptions); }); } if (session.stop) { await runCleanup(async () => { await session.stop(lifecycleOptions); }); usedStandardLifecycle = true; } if (session.shutdown) { await runCleanup(async () => { await session.shutdown(lifecycleOptions); }); usedStandardLifecycle = true; } if (session.delete) { await runCleanup(async () => { await session.delete(lifecycleOptions); }); usedStandardLifecycle = true; } if (!usedStandardLifecycle) { await runCleanup(async () => { await session.close?.(); }); } if (cleanupError) { throw cleanupError; } } function cleanupLifecycleOptions(options) { return { ...options, reason: options?.reason ?? 'cleanup', }; } function getManagedHookState(session) { const existing = managedHookStateBySession.get(session); if (existing) { return existing; } const state = { hooks: new Set(), ran: false, installed: false, }; managedHookStateBySession.set(session, state); return state; } function hasManagedPreStopHooks(session) { return (managedHookStateBySession.get(session)?.hooks.size ?? 0) > 0; } function registerProviderManagedPreStopHook(session, state) { if (state.unregisterProviderHook) { return; } const unregister = session.registerPreStopHook(async () => { await runManagedPreStopHooks(session, state); }); state.unregisterProviderHook = typeof unregister === 'function' ? unregister : () => { }; } function unregisterManagedHook(state, hook) { state.hooks.delete(hook); if (state.hooks.size > 0 || !state.unregisterProviderHook) { return; } state.unregisterProviderHook(); state.unregisterProviderHook = undefined; } function installManagedPreStopHooks(session, state) { if (state.installed) { return; } state.installed = true; const originalRunPreStopHooks = session.runPreStopHooks?.bind(session); const originalPreStop = session.preStop?.bind(session); const originalStop = session.stop?.bind(session); const originalShutdown = session.shutdown?.bind(session); const originalDelete = session.delete?.bind(session); const originalClose = session.close?.bind(session); let originalRunPreStopHooksRan = false; const runHooks = async () => { await runManagedPreStopHooks(session, state); if (originalRunPreStopHooks && !originalRunPreStopHooksRan) { originalRunPreStopHooksRan = true; await originalRunPreStopHooks(); } }; session.runPreStopHooks = runHooks; session.preStop = async (options) => { await runHooks(); await originalPreStop?.(options); }; if (originalStop) { session.stop = async (options) => { await runHooks(); await originalStop(options); }; } if (originalShutdown) { session.shutdown = async (options) => { await runHooks(); await originalShutdown(options); }; } if (originalDelete) { session.delete = async (options) => { await runHooks(); await originalDelete(options); }; } if (originalClose) { session.close = async () => { await runHooks(); await originalClose(); }; } } async function runManagedPreStopHooksForSession(session) { const state = managedHookStateBySession.get(session); if (!state) { return; } await runManagedPreStopHooks(session, state); } async function runManagedPreStopHooks(_session, state) { if (state.ran || state.hooks.size === 0) { return; } state.ran = true; let firstError; for (const hook of state.hooks) { try { await hook(); } catch (error) { firstError ??= error; } } if (firstError) { throw firstError; } } //# sourceMappingURL=sessionLifecycle.mjs.map