UNPKG

symmetry-core

Version:

Use this repository to become an inference provider on the Symmetry network programmatically.

131 lines (130 loc) 5.18 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseProvider = void 0; const promises_1 = __importDefault(require("fs/promises")); const path_1 = __importDefault(require("path")); const net_1 = __importDefault(require("net")); const os_1 = __importDefault(require("os")); const node_crypto_1 = __importDefault(require("node:crypto")); const js_yaml_1 = __importDefault(require("js-yaml")); const readline_1 = __importDefault(require("readline")); const logger_1 = require("../logger"); class BaseProvider { constructor() { this.serverConfig = { apiProtocol: "http", apiHostname: "localhost", apiModelsPath: "/v1/models", apiBasePath: "/v1", systemMessage: "You are a helpful AI assistant.", serverKey: node_crypto_1.default.randomBytes(32).toString("hex"), userSecret: node_crypto_1.default.randomBytes(16).toString("hex"), }; } static async promptUser(question) { const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => { rl.question(question, (answer) => { rl.close(); resolve(answer); }); }); } async checkPort(port) { if (!port) return false; return new Promise((resolve) => { const socket = new net_1.default.Socket(); const onError = () => { socket.destroy(); resolve(false); }; socket.setTimeout(1000); socket.once("error", onError); socket.once("timeout", onError); socket.connect(port, "localhost", () => { socket.end(); resolve(true); }); }); } async getModels(apiKey) { const path = `${this.serverConfig.apiProtocol}://${this.serverConfig.apiHostname}:${this.serverConfig.apiPort}${this.serverConfig.apiModelsPath}`; try { const response = await fetch(path, { headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : {}, }); if (!response.ok) throw new Error(`Failed to fetch models: ${response.statusText}`); const data = (await response.json()); return data.data; } catch (error) { logger_1.logger.error("Failed to fetch models"); return []; } } async createConfig(server) { const configDir = path_1.default.join(BaseProvider.DEFAULT_CONFIG_PATH); const dataDir = path_1.default.join(configDir, "data"); const config = this.generateConfig(server); try { await promises_1.default.mkdir(configDir, { recursive: true }); await promises_1.default.mkdir(dataDir, { recursive: true }); await promises_1.default.writeFile(path_1.default.join(configDir, "provider.yaml"), js_yaml_1.default.dump(config), "utf-8"); } catch (error) { logger_1.logger.error(`Failed to create config file: ${error instanceof Error ? error.message : "Unknown error"}`); throw error; } } generateConfig(server) { return { name: `symmetry-${server.name}`, public: true, maxConnections: 10, apiHostname: "localhost", apiPort: server.apiPort, apiProtocol: "http", apiBasePath: server.apiBasePath, modelName: server.modelName, systemMessage: "You are a helpful AI assistant.", serverKey: "4b4a9cc325d134dee6679e9407420023531fd7e96c563f6c5d00fd5549b77435", userSecret: node_crypto_1.default.randomBytes(16).toString("hex"), }; } async selectModel(models) { if (models.length === 0) return ""; console.log("\nAvailable models:"); models.forEach((model, index) => { console.log(`${index + 1}. ${model.id}`); }); const selection = await BaseProvider.promptUser("\nSelect a model (enter number): "); const index = parseInt(selection) - 1; if (index >= 0 && index < models.length) { return models[index].id; } return "gpt-3.5-turbo"; } async detectServer() { try { const isPortOpen = await this.checkPort(this.serverConfig.apiPort); if (!isPortOpen) return null; const response = await fetch(`${this.serverConfig.apiProtocol}://${this.serverConfig.apiHostname}:${this.serverConfig.apiPort}${this.serverConfig.apiHealthPath}`); return response.ok ? this.serverConfig : null; } catch (_a) { return null; } } } exports.BaseProvider = BaseProvider; BaseProvider.DEFAULT_CONFIG_PATH = path_1.default.join(os_1.default.homedir(), ".config", "symmetry");