 85bf1341f3
			
		
	
	85bf1341f3
	
	
	
		
			
			Frontend Enhancements: - Complete React TypeScript frontend with modern UI components - Distributed workflows management interface with real-time updates - Socket.IO integration for live agent status monitoring - Agent management dashboard with cluster visualization - Project management interface with metrics and task tracking - Responsive design with proper error handling and loading states Backend Infrastructure: - Distributed coordinator for multi-agent workflow orchestration - Cluster management API with comprehensive agent operations - Enhanced database models for agents and projects - Project service for filesystem-based project discovery - Performance monitoring and metrics collection - Comprehensive API documentation and error handling Documentation: - Complete distributed development guide (README_DISTRIBUTED.md) - Comprehensive development report with architecture insights - System configuration templates and deployment guides The platform now provides a complete web interface for managing the distributed AI cluster with real-time monitoring, workflow orchestration, and agent coordination capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			417 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			417 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
 | |
|     if (k2 === undefined) k2 = k;
 | |
|     var desc = Object.getOwnPropertyDescriptor(m, k);
 | |
|     if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
 | |
|       desc = { enumerable: true, get: function() { return m[k]; } };
 | |
|     }
 | |
|     Object.defineProperty(o, k2, desc);
 | |
| }) : (function(o, m, k, k2) {
 | |
|     if (k2 === undefined) k2 = k;
 | |
|     o[k2] = m[k];
 | |
| }));
 | |
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
 | |
|     Object.defineProperty(o, "default", { enumerable: true, value: v });
 | |
| }) : function(o, v) {
 | |
|     o["default"] = v;
 | |
| });
 | |
| var __importStar = (this && this.__importStar) || function (mod) {
 | |
|     if (mod && mod.__esModule) return mod;
 | |
|     var result = {};
 | |
|     if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
 | |
|     __setModuleDefault(result, mod);
 | |
|     return result;
 | |
| };
 | |
| var __importDefault = (this && this.__importDefault) || function (mod) {
 | |
|     return (mod && mod.__esModule) ? mod : { "default": mod };
 | |
| };
 | |
| Object.defineProperty(exports, "__esModule", { value: true });
 | |
| exports.Manager = void 0;
 | |
| const engine_io_client_1 = require("engine.io-client");
 | |
| const socket_js_1 = require("./socket.js");
 | |
| const parser = __importStar(require("socket.io-parser"));
 | |
| const on_js_1 = require("./on.js");
 | |
| const backo2_js_1 = require("./contrib/backo2.js");
 | |
| const component_emitter_1 = require("@socket.io/component-emitter");
 | |
| const debug_1 = __importDefault(require("debug")); // debug()
 | |
| const debug = (0, debug_1.default)("socket.io-client:manager"); // debug()
 | |
| class Manager extends component_emitter_1.Emitter {
 | |
|     constructor(uri, opts) {
 | |
|         var _a;
 | |
|         super();
 | |
|         this.nsps = {};
 | |
|         this.subs = [];
 | |
|         if (uri && "object" === typeof uri) {
 | |
|             opts = uri;
 | |
|             uri = undefined;
 | |
|         }
 | |
|         opts = opts || {};
 | |
|         opts.path = opts.path || "/socket.io";
 | |
|         this.opts = opts;
 | |
|         (0, engine_io_client_1.installTimerFunctions)(this, opts);
 | |
|         this.reconnection(opts.reconnection !== false);
 | |
|         this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
 | |
|         this.reconnectionDelay(opts.reconnectionDelay || 1000);
 | |
|         this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
 | |
|         this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5);
 | |
|         this.backoff = new backo2_js_1.Backoff({
 | |
|             min: this.reconnectionDelay(),
 | |
|             max: this.reconnectionDelayMax(),
 | |
|             jitter: this.randomizationFactor(),
 | |
|         });
 | |
|         this.timeout(null == opts.timeout ? 20000 : opts.timeout);
 | |
|         this._readyState = "closed";
 | |
|         this.uri = uri;
 | |
|         const _parser = opts.parser || parser;
 | |
|         this.encoder = new _parser.Encoder();
 | |
|         this.decoder = new _parser.Decoder();
 | |
|         this._autoConnect = opts.autoConnect !== false;
 | |
|         if (this._autoConnect)
 | |
|             this.open();
 | |
|     }
 | |
|     reconnection(v) {
 | |
|         if (!arguments.length)
 | |
|             return this._reconnection;
 | |
|         this._reconnection = !!v;
 | |
|         if (!v) {
 | |
|             this.skipReconnect = true;
 | |
|         }
 | |
|         return this;
 | |
|     }
 | |
|     reconnectionAttempts(v) {
 | |
|         if (v === undefined)
 | |
|             return this._reconnectionAttempts;
 | |
|         this._reconnectionAttempts = v;
 | |
|         return this;
 | |
|     }
 | |
|     reconnectionDelay(v) {
 | |
|         var _a;
 | |
|         if (v === undefined)
 | |
|             return this._reconnectionDelay;
 | |
|         this._reconnectionDelay = v;
 | |
|         (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v);
 | |
|         return this;
 | |
|     }
 | |
|     randomizationFactor(v) {
 | |
|         var _a;
 | |
|         if (v === undefined)
 | |
|             return this._randomizationFactor;
 | |
|         this._randomizationFactor = v;
 | |
|         (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v);
 | |
|         return this;
 | |
|     }
 | |
|     reconnectionDelayMax(v) {
 | |
|         var _a;
 | |
|         if (v === undefined)
 | |
|             return this._reconnectionDelayMax;
 | |
|         this._reconnectionDelayMax = v;
 | |
|         (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v);
 | |
|         return this;
 | |
|     }
 | |
|     timeout(v) {
 | |
|         if (!arguments.length)
 | |
|             return this._timeout;
 | |
|         this._timeout = v;
 | |
|         return this;
 | |
|     }
 | |
|     /**
 | |
|      * Starts trying to reconnect if reconnection is enabled and we have not
 | |
|      * started reconnecting yet
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     maybeReconnectOnOpen() {
 | |
|         // Only try to reconnect if it's the first time we're connecting
 | |
|         if (!this._reconnecting &&
 | |
|             this._reconnection &&
 | |
|             this.backoff.attempts === 0) {
 | |
|             // keeps reconnection from firing twice for the same reconnection loop
 | |
|             this.reconnect();
 | |
|         }
 | |
|     }
 | |
|     /**
 | |
|      * Sets the current transport `socket`.
 | |
|      *
 | |
|      * @param {Function} fn - optional, callback
 | |
|      * @return self
 | |
|      * @public
 | |
|      */
 | |
|     open(fn) {
 | |
|         debug("readyState %s", this._readyState);
 | |
|         if (~this._readyState.indexOf("open"))
 | |
|             return this;
 | |
|         debug("opening %s", this.uri);
 | |
|         this.engine = new engine_io_client_1.Socket(this.uri, this.opts);
 | |
|         const socket = this.engine;
 | |
|         const self = this;
 | |
|         this._readyState = "opening";
 | |
|         this.skipReconnect = false;
 | |
|         // emit `open`
 | |
|         const openSubDestroy = (0, on_js_1.on)(socket, "open", function () {
 | |
|             self.onopen();
 | |
|             fn && fn();
 | |
|         });
 | |
|         const onError = (err) => {
 | |
|             debug("error");
 | |
|             this.cleanup();
 | |
|             this._readyState = "closed";
 | |
|             this.emitReserved("error", err);
 | |
|             if (fn) {
 | |
|                 fn(err);
 | |
|             }
 | |
|             else {
 | |
|                 // Only do this if there is no fn to handle the error
 | |
|                 this.maybeReconnectOnOpen();
 | |
|             }
 | |
|         };
 | |
|         // emit `error`
 | |
|         const errorSub = (0, on_js_1.on)(socket, "error", onError);
 | |
|         if (false !== this._timeout) {
 | |
|             const timeout = this._timeout;
 | |
|             debug("connect attempt will timeout after %d", timeout);
 | |
|             // set timer
 | |
|             const timer = this.setTimeoutFn(() => {
 | |
|                 debug("connect attempt timed out after %d", timeout);
 | |
|                 openSubDestroy();
 | |
|                 onError(new Error("timeout"));
 | |
|                 socket.close();
 | |
|             }, timeout);
 | |
|             if (this.opts.autoUnref) {
 | |
|                 timer.unref();
 | |
|             }
 | |
|             this.subs.push(() => {
 | |
|                 this.clearTimeoutFn(timer);
 | |
|             });
 | |
|         }
 | |
|         this.subs.push(openSubDestroy);
 | |
|         this.subs.push(errorSub);
 | |
|         return this;
 | |
|     }
 | |
|     /**
 | |
|      * Alias for open()
 | |
|      *
 | |
|      * @return self
 | |
|      * @public
 | |
|      */
 | |
|     connect(fn) {
 | |
|         return this.open(fn);
 | |
|     }
 | |
|     /**
 | |
|      * Called upon transport open.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     onopen() {
 | |
|         debug("open");
 | |
|         // clear old subs
 | |
|         this.cleanup();
 | |
|         // mark as open
 | |
|         this._readyState = "open";
 | |
|         this.emitReserved("open");
 | |
|         // add new subs
 | |
|         const socket = this.engine;
 | |
|         this.subs.push((0, on_js_1.on)(socket, "ping", this.onping.bind(this)), (0, on_js_1.on)(socket, "data", this.ondata.bind(this)), (0, on_js_1.on)(socket, "error", this.onerror.bind(this)), (0, on_js_1.on)(socket, "close", this.onclose.bind(this)), 
 | |
|         // @ts-ignore
 | |
|         (0, on_js_1.on)(this.decoder, "decoded", this.ondecoded.bind(this)));
 | |
|     }
 | |
|     /**
 | |
|      * Called upon a ping.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     onping() {
 | |
|         this.emitReserved("ping");
 | |
|     }
 | |
|     /**
 | |
|      * Called with data.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     ondata(data) {
 | |
|         try {
 | |
|             this.decoder.add(data);
 | |
|         }
 | |
|         catch (e) {
 | |
|             this.onclose("parse error", e);
 | |
|         }
 | |
|     }
 | |
|     /**
 | |
|      * Called when parser fully decodes a packet.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     ondecoded(packet) {
 | |
|         // the nextTick call prevents an exception in a user-provided event listener from triggering a disconnection due to a "parse error"
 | |
|         (0, engine_io_client_1.nextTick)(() => {
 | |
|             this.emitReserved("packet", packet);
 | |
|         }, this.setTimeoutFn);
 | |
|     }
 | |
|     /**
 | |
|      * Called upon socket error.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     onerror(err) {
 | |
|         debug("error", err);
 | |
|         this.emitReserved("error", err);
 | |
|     }
 | |
|     /**
 | |
|      * Creates a new socket for the given `nsp`.
 | |
|      *
 | |
|      * @return {Socket}
 | |
|      * @public
 | |
|      */
 | |
|     socket(nsp, opts) {
 | |
|         let socket = this.nsps[nsp];
 | |
|         if (!socket) {
 | |
|             socket = new socket_js_1.Socket(this, nsp, opts);
 | |
|             this.nsps[nsp] = socket;
 | |
|         }
 | |
|         else if (this._autoConnect && !socket.active) {
 | |
|             socket.connect();
 | |
|         }
 | |
|         return socket;
 | |
|     }
 | |
|     /**
 | |
|      * Called upon a socket close.
 | |
|      *
 | |
|      * @param socket
 | |
|      * @private
 | |
|      */
 | |
|     _destroy(socket) {
 | |
|         const nsps = Object.keys(this.nsps);
 | |
|         for (const nsp of nsps) {
 | |
|             const socket = this.nsps[nsp];
 | |
|             if (socket.active) {
 | |
|                 debug("socket %s is still active, skipping close", nsp);
 | |
|                 return;
 | |
|             }
 | |
|         }
 | |
|         this._close();
 | |
|     }
 | |
|     /**
 | |
|      * Writes a packet.
 | |
|      *
 | |
|      * @param packet
 | |
|      * @private
 | |
|      */
 | |
|     _packet(packet) {
 | |
|         debug("writing packet %j", packet);
 | |
|         const encodedPackets = this.encoder.encode(packet);
 | |
|         for (let i = 0; i < encodedPackets.length; i++) {
 | |
|             this.engine.write(encodedPackets[i], packet.options);
 | |
|         }
 | |
|     }
 | |
|     /**
 | |
|      * Clean up transport subscriptions and packet buffer.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     cleanup() {
 | |
|         debug("cleanup");
 | |
|         this.subs.forEach((subDestroy) => subDestroy());
 | |
|         this.subs.length = 0;
 | |
|         this.decoder.destroy();
 | |
|     }
 | |
|     /**
 | |
|      * Close the current socket.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     _close() {
 | |
|         debug("disconnect");
 | |
|         this.skipReconnect = true;
 | |
|         this._reconnecting = false;
 | |
|         this.onclose("forced close");
 | |
|     }
 | |
|     /**
 | |
|      * Alias for close()
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     disconnect() {
 | |
|         return this._close();
 | |
|     }
 | |
|     /**
 | |
|      * Called when:
 | |
|      *
 | |
|      * - the low-level engine is closed
 | |
|      * - the parser encountered a badly formatted packet
 | |
|      * - all sockets are disconnected
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     onclose(reason, description) {
 | |
|         var _a;
 | |
|         debug("closed due to %s", reason);
 | |
|         this.cleanup();
 | |
|         (_a = this.engine) === null || _a === void 0 ? void 0 : _a.close();
 | |
|         this.backoff.reset();
 | |
|         this._readyState = "closed";
 | |
|         this.emitReserved("close", reason, description);
 | |
|         if (this._reconnection && !this.skipReconnect) {
 | |
|             this.reconnect();
 | |
|         }
 | |
|     }
 | |
|     /**
 | |
|      * Attempt a reconnection.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     reconnect() {
 | |
|         if (this._reconnecting || this.skipReconnect)
 | |
|             return this;
 | |
|         const self = this;
 | |
|         if (this.backoff.attempts >= this._reconnectionAttempts) {
 | |
|             debug("reconnect failed");
 | |
|             this.backoff.reset();
 | |
|             this.emitReserved("reconnect_failed");
 | |
|             this._reconnecting = false;
 | |
|         }
 | |
|         else {
 | |
|             const delay = this.backoff.duration();
 | |
|             debug("will wait %dms before reconnect attempt", delay);
 | |
|             this._reconnecting = true;
 | |
|             const timer = this.setTimeoutFn(() => {
 | |
|                 if (self.skipReconnect)
 | |
|                     return;
 | |
|                 debug("attempting reconnect");
 | |
|                 this.emitReserved("reconnect_attempt", self.backoff.attempts);
 | |
|                 // check again for the case socket closed in above events
 | |
|                 if (self.skipReconnect)
 | |
|                     return;
 | |
|                 self.open((err) => {
 | |
|                     if (err) {
 | |
|                         debug("reconnect attempt error");
 | |
|                         self._reconnecting = false;
 | |
|                         self.reconnect();
 | |
|                         this.emitReserved("reconnect_error", err);
 | |
|                     }
 | |
|                     else {
 | |
|                         debug("reconnect success");
 | |
|                         self.onreconnect();
 | |
|                     }
 | |
|                 });
 | |
|             }, delay);
 | |
|             if (this.opts.autoUnref) {
 | |
|                 timer.unref();
 | |
|             }
 | |
|             this.subs.push(() => {
 | |
|                 this.clearTimeoutFn(timer);
 | |
|             });
 | |
|         }
 | |
|     }
 | |
|     /**
 | |
|      * Called upon successful reconnect.
 | |
|      *
 | |
|      * @private
 | |
|      */
 | |
|     onreconnect() {
 | |
|         const attempt = this.backoff.attempts;
 | |
|         this._reconnecting = false;
 | |
|         this.backoff.reset();
 | |
|         this.emitReserved("reconnect", attempt);
 | |
|     }
 | |
| }
 | |
| exports.Manager = Manager;
 |