UNPKG

ai-ip-plugin

Version:

AI-IP Plugin for MCP Workflow Management with SSE streaming and event handling

354 lines 11 kB
"use strict"; /** * MCP Manager - Core class for managing MCP workflows */ Object.defineProperty(exports, "__esModule", { value: true }); exports.MCPPlugin = exports.MCPManager = void 0; const api_1 = require("../services/api"); const EventHandler_1 = require("./EventHandler"); const StreamProcessor_1 = require("./StreamProcessor"); const DataManager_1 = require("./DataManager"); const utils_1 = require("../utils"); class MCPManager { constructor(config) { this.streamController = null; this.config = config; this.apiService = new api_1.APIService(config); this.eventHandler = new EventHandler_1.EventHandler(); this.streamProcessor = new StreamProcessor_1.StreamProcessor(); this.dataManager = new DataManager_1.DataManager(); this.state = { taskId: null, isLoading: false, error: null, currentStep: null, }; this.setupEventHandlers(); } /** * Setup event handlers */ setupEventHandlers() { this.eventHandler.on("workflow_created", (data) => { this.updateState({ taskId: data.task_id, isLoading: true }); this.handleWorkflowCreated(data); }); this.eventHandler.on("workflow_restarted", (data) => { this.updateState({ taskId: data.thread_id, isLoading: true }); this.handleWorkflowRestarted(data); }); this.eventHandler.on("start_of_agent", (data) => { this.updateState({ currentStep: data.agent_name }); this.handleStartOfAgent(data); }); this.eventHandler.on("end_of_agent", (data) => { this.handleEndOfAgent(data); }); this.eventHandler.on("message", (data) => { this.handleMessage(data); }); this.eventHandler.on("tool_call", (data) => { this.handleToolCall(data); }); this.eventHandler.on("tool_call_result", (data) => { this.handleToolCallResult(data); }); this.eventHandler.on("workflow_interrupted", (data) => { this.updateState({ isLoading: false }); this.handleWorkflowInterrupted(data); }); this.eventHandler.on("end_of_workflow", () => { this.updateState({ isLoading: false, currentStep: null }); }); this.eventHandler.on("error", (data) => { this.updateState({ isLoading: false, error: data.message || "Unknown error", }); this.handleError(data); }); } /** * Update manager state */ updateState(updates) { this.state = { ...this.state, ...updates }; this.config.onStateChange?.(this.state); } /** * Start workflow */ async startWorkflow(params) { try { this.updateState({ isLoading: true, error: null }); const { responseData, controller } = await this.apiService.startWorkflow(params); if (!responseData.ok || !responseData.body) { throw new Error("Failed to start workflow"); } this.streamController = { controller, reader: responseData.body.getReader(), }; const handlers = this.createSSEHandlers(); if (this.streamController.reader) { await this.streamProcessor.processStream(this.streamController.reader, handlers); } } catch (error) { this.updateState({ isLoading: false, error: error.message }); this.config.onError?.(error); } } /** * Continue workflow */ async continueWorkflow(params) { try { this.updateState({ isLoading: true, error: null }); const { responseData, controller } = await this.apiService.continueWorkflow(params); if (!responseData.ok || !responseData.body) { throw new Error("Failed to continue workflow"); } this.streamController = { controller, reader: responseData.body.getReader(), }; const handlers = this.createSSEHandlers(); if (this.streamController.reader) { await this.streamProcessor.processStream(this.streamController.reader, handlers); } } catch (error) { this.updateState({ isLoading: false, error: error.message }); this.config.onError?.(error); } } /** * Resume workflow */ async resumeWorkflow(params) { try { this.updateState({ isLoading: true, error: null }); const { responseData, controller } = await this.apiService.resumeWorkflow(params); if (!responseData.ok || !responseData.body) { throw new Error("Failed to resume workflow"); } this.streamController = { controller, reader: responseData.body.getReader(), }; const handlers = this.createSSEHandlers(); if (this.streamController.reader) { await this.streamProcessor.processStream(this.streamController.reader, handlers); } } catch (error) { this.updateState({ isLoading: false, error: error.message }); this.config.onError?.(error); } } /** * Stop workflow */ async stopWorkflow(params) { try { await this.apiService.stopWorkflow(params); this.abortCurrentStream(); this.updateState({ isLoading: false }); } catch (error) { this.config.onError?.(error); } } /** * Get workflow history */ async getWorkflowHistory(taskId) { try { const response = await this.apiService.getWorkflowHistory(taskId); if (!response.ok) { throw new Error("Failed to get workflow history"); } const result = await response.json(); return result.data?.history || []; } catch (error) { this.config.onError?.(error); return []; } } /** * Get workflow state data */ async getWorkflowStateData(taskId) { try { const result = await this.apiService.getWorkflowStateData(taskId); if (result.code === 200) { return { success: true, oralText: result.data.polisher_content || result.data.writer_content || "", }; } return { success: false, oralText: "" }; } catch (error) { this.config.onError?.(error); return { success: false, oralText: "" }; } } /** * Create SSE handlers */ createSSEHandlers() { return { onopen: () => { console.log("SSE connection established"); }, onerror: (error) => { console.error("SSE error:", error); this.updateState({ isLoading: false, error: "Connection error" }); }, onmessage: ({ event, data }) => { this.eventHandler.emit(event, data); }, }; } /** * Abort current stream */ abortCurrentStream() { if (this.streamController && !this.streamController.controller.signal.aborted) { this.streamController.controller.abort(); this.streamController = null; } } /** * Get current state */ getState() { return { ...this.state }; } /** * Get workflow data */ getWorkflowData() { return this.dataManager.getWorkflowData(); } /** * Handle workflow created event */ handleWorkflowCreated(data) { const uuid = (0, utils_1.generateUUID)(); const messageItem = { content: data.user_input, additional_kwargs: {}, response_metadata: {}, type: "human", agent_type: "user", name: "", id: uuid, example: false, uuid: uuid, event: "workflow_created", task_id: data.task_id, finished: true, session_id: uuid, tool_calls: [], invalid_tool_calls: [], }; this.dataManager.addWorkflowItem(uuid, messageItem); this.notifyDataUpdate(); } /** * Handle workflow restarted event */ handleWorkflowRestarted(data) { const uuid = (0, utils_1.generateUUID)(); const messageItem = { content: data.user_input, additional_kwargs: {}, response_metadata: {}, type: "human", agent_type: "user", name: "", id: uuid, example: false, uuid: uuid, event: "workflow_restarted", task_id: data.thread_id, finished: true, session_id: uuid, tool_calls: [], invalid_tool_calls: [], }; this.dataManager.addWorkflowItem(uuid, messageItem); this.notifyDataUpdate(); } /** * Handle start of agent event */ handleStartOfAgent(data) { this.dataManager.handleStartOfAgent(data); this.notifyDataUpdate(); } /** * Handle end of agent event */ handleEndOfAgent(data) { this.dataManager.handleEndOfAgent(data); this.notifyDataUpdate(); } /** * Handle message event */ handleMessage(data) { this.dataManager.handleMessage(data); this.notifyDataUpdate(); } /** * Handle tool call event */ handleToolCall(data) { this.dataManager.handleToolCall(data); this.notifyDataUpdate(); } /** * Handle tool call result event */ handleToolCallResult(data) { this.dataManager.handleToolCallResult(data); this.notifyDataUpdate(); } /** * Handle workflow interrupted event */ handleWorkflowInterrupted(data) { this.dataManager.handleWorkflowInterrupted(data); this.notifyDataUpdate(); } /** * Handle error event */ handleError(data) { this.dataManager.handleError(data); this.notifyDataUpdate(); } /** * Notify data update */ notifyDataUpdate() { this.config.onDataUpdate?.(this.dataManager.getWorkflowData()); } /** * Cleanup resources */ destroy() { this.abortCurrentStream(); this.eventHandler.removeAllListeners(); this.dataManager.clear(); } } exports.MCPManager = MCPManager; exports.MCPPlugin = MCPManager; //# sourceMappingURL=MCPManager.js.map