UNPKG

reagentbuilder

Version:

An enterprise-grade AI agent framework based on LangChain and LangGraph, featuring dynamic tools, interceptors, breakpoints, and performance monitoring.

170 lines 7.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BreakpointManager = void 0; const index_js_1 = require("../core/index.js"); // ============ 断点管理类 ============ class BreakpointManager { constructor(config, maxConcurrentBreakpoints = 5) { this.executionQueue = new Map(); this.concurrentBreakpoints = new Set(); this.config = config; this.maxConcurrentBreakpoints = maxConcurrentBreakpoints; // 预计算配置状态 this.isEnabled = config.enabled; this.hasCoreBeforeModel = !!(config.core?.beforeModelInvoke); this.hasCoreAfterComplete = !!(config.core?.afterAgentComplete); this.hasModelBefore = !!(config.model?.beforeCall); this.hasModelAfter = !!(config.model?.afterCall); this.hasGlobalBefore = !!(config.global?.beforeToolCall); this.hasGlobalAfter = !!(config.global?.afterToolCall); this.hasToolSpecific = !!(config.toolSpecific && config.toolSpecific.size > 0); } async enqueueBreakpoint(key, breakpointFn) { if (this.concurrentBreakpoints.size >= this.maxConcurrentBreakpoints) { index_js_1.logger.debug(`断点并发限制达到上限 (${this.maxConcurrentBreakpoints}),跳过断点: ${key}`); return; } if (this.executionQueue.has(key)) { index_js_1.logger.debug(`断点已在执行队列中,跳过重复断点: ${key}`); return; } const breakpointPromise = this.executeBreakpoint(key, breakpointFn); this.executionQueue.set(key, breakpointPromise.then(() => undefined)); try { return await breakpointPromise; } finally { this.executionQueue.delete(key); } } async executeBreakpoint(key, breakpointFn) { this.concurrentBreakpoints.add(key); try { const timeout = 2000; let timeoutId; const result = await Promise.race([ breakpointFn(), new Promise((_, reject) => { timeoutId = setTimeout(() => reject(new Error(`断点执行超时: ${key}`)), timeout); }) ]); // 清理超时定时器 clearTimeout(timeoutId); return result; } catch (error) { index_js_1.logger.warn(`断点执行失败 [${key}]: ${error instanceof Error ? error.message : String(error)}`); return; } finally { this.concurrentBreakpoints.delete(key); } } async breakBeforeModelInvoke(messages, state) { if (!this.isEnabled || !this.hasCoreBeforeModel) return; const key = index_js_1.perfUtils.generateId('core-before-model'); await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug('核心开始断点 - 观察大模型输入'); await this.config.core.beforeModelInvoke(messages, state); }); } async breakAfterAgentComplete(finalState) { if (!this.isEnabled || !this.hasCoreAfterComplete) return; const key = index_js_1.perfUtils.generateId('core-after-complete'); await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug('核心结束断点 - 观察最终状态'); await this.config.core.afterAgentComplete(finalState); }); } async breakBeforeModelCall(state) { if (!this.isEnabled || !this.hasModelBefore) return; const key = index_js_1.perfUtils.generateId('model-before-call'); await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug('模型调用前断点'); await this.config.model.beforeCall(state); }); } async breakAfterModelCall(response, state) { if (!this.isEnabled || !this.hasModelAfter) return; const key = index_js_1.perfUtils.generateId('model-after-call'); await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug('模型调用后断点'); await this.config.model.afterCall(response, state); }); } async breakBeforeToolCall(toolCall, state) { if (!this.isEnabled || !this.hasGlobalBefore) return; const key = `global-before-tool-${toolCall.name}-${toolCall.id || index_js_1.perfUtils.generateId('tool')}`; await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug(`全局工具调用前断点: ${toolCall.name}`); await this.config.global.beforeToolCall(toolCall, state); }); } async breakAfterToolCall(result, toolCall, state) { if (!this.isEnabled || !this.hasGlobalAfter) return; const key = `global-after-tool-${toolCall.name}-${toolCall.id || index_js_1.perfUtils.generateId('tool')}`; await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug(`全局工具调用后断点: ${toolCall.name}`); await this.config.global.afterToolCall(result, toolCall, state); }); } async breakBeforeSpecificToolCall(toolCall, state) { if (!this.isEnabled || !this.hasToolSpecific) return; const toolName = String(toolCall.name || 'unknown'); const toolBreakpoint = this.config.toolSpecific?.get(toolName); if (!toolBreakpoint?.beforeToolCall) return; const key = `specific-before-tool-${toolName}-${toolCall.id || index_js_1.perfUtils.generateId('tool')}`; await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug(`特定工具调用前断点: ${toolName}`); await toolBreakpoint.beforeToolCall(toolCall, state); }); } async breakAfterSpecificToolCall(result, toolCall, state) { if (!this.isEnabled || !this.hasToolSpecific) return; const toolName = String(toolCall.name || 'unknown'); const toolBreakpoint = this.config.toolSpecific?.get(toolName); if (!toolBreakpoint?.afterToolCall) return; const key = `specific-after-tool-${toolName}-${toolCall.id || index_js_1.perfUtils.generateId('tool')}`; await this.enqueueBreakpoint(key, async () => { index_js_1.logger.debug(`特定工具调用后断点: ${toolName}`); await toolBreakpoint.afterToolCall(result, toolCall, state); }); } getActiveBreakpointCount() { return this.concurrentBreakpoints.size; } async cleanup() { const activeBreakpointCount = this.concurrentBreakpoints.size; if (activeBreakpointCount > 0) { index_js_1.logger.warn(`清理断点管理器时仍有 ${activeBreakpointCount} 个活跃断点`); } const maxWaitTime = 2000; let waitTime = 0; while (this.concurrentBreakpoints.size > 0 && waitTime < maxWaitTime) { await new Promise(resolve => setTimeout(resolve, 100)); waitTime += 100; } if (this.concurrentBreakpoints.size > 0) { index_js_1.logger.warn(`断点管理器清理超时,强制清理 ${this.concurrentBreakpoints.size} 个断点`); } this.executionQueue.clear(); this.concurrentBreakpoints.clear(); // 清理配置对象中的Map引用 if (this.config.toolSpecific) { this.config.toolSpecific.clear(); } index_js_1.logger.debug('断点管理器资源清理完成'); } } exports.BreakpointManager = BreakpointManager; //# sourceMappingURL=breakpoint-manager.js.map