symmetry-cli 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -45,7 +45,7 @@ describe("Symmetry", () => {
45
45
  apiProvider: "test-provider",
46
46
  modelName: "test-model",
47
47
  name: "test",
48
- public: true,
48
+ public: false,
49
49
  serverKey: "test-server-key",
50
50
  systemMessage: "test-system-message",
51
51
  };
package/dist/constants.js CHANGED
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.apiProviders = exports.serverMessageKeys = exports.NORMALIZE_REGEX = void 0;
3
+ exports.apiProviders = exports.serverMessageKeys = exports.PROVIDER_HELLO_TIMEOUT = exports.NORMALIZE_REGEX = void 0;
4
4
  exports.NORMALIZE_REGEX = /\s*\r?\n|\r/g;
5
+ exports.PROVIDER_HELLO_TIMEOUT = 15000;
5
6
  exports.serverMessageKeys = {
6
7
  challenge: "challenge",
7
8
  conectionSize: "conectionSize",
package/dist/provider.js CHANGED
@@ -22,6 +22,7 @@ class SymmetryProvider {
22
22
  this._isPublic = false;
23
23
  this._providerConnections = 0;
24
24
  this._providerSwarm = null;
25
+ this._serverSwarm = null;
25
26
  this._serverPeer = null;
26
27
  logger_1.logger.info(`🔗 Initializing client using config file: ${configPath}`);
27
28
  this._config = new config_1.ConfigManager(configPath);
@@ -50,7 +51,7 @@ class SymmetryProvider {
50
51
  if (this._isPublic) {
51
52
  logger_1.logger.info(chalk_1.default.white(`🔑 Server key: ${this._config.get("serverKey")}`));
52
53
  logger_1.logger.info(chalk_1.default.white("🔗 Joining server, please wait."));
53
- this.testProviderCall();
54
+ this.joinServer();
54
55
  }
55
56
  process.on("SIGINT", async () => {
56
57
  var _a;
@@ -63,62 +64,74 @@ class SymmetryProvider {
63
64
  }
64
65
  });
65
66
  }
67
+ async destroySwarms() {
68
+ var _a, _b;
69
+ await ((_a = this._providerSwarm) === null || _a === void 0 ? void 0 : _a.destroy());
70
+ await ((_b = this._serverSwarm) === null || _b === void 0 ? void 0 : _b.destroy());
71
+ }
66
72
  async testProviderCall() {
67
- logger_1.logger.info(chalk_1.default.white(`👋 Saying hello to your provider...`));
68
- const testMessages = [
69
- { role: "user", content: "Hello, this is a test message." },
70
- ];
71
- const req = this.buildStreamRequest(testMessages);
72
- if (!req) {
73
- logger_1.logger.error(chalk_1.default.red("❌ Failed to build test request"));
74
- throw new Error("Failed to build test request");
75
- }
76
- const { requestOptions, requestBody } = req;
77
- const { protocol, hostname, port, path, method, headers } = requestOptions;
78
- const url = `${protocol}://${hostname}:${port}${path}`;
79
- logger_1.logger.info(chalk_1.default.white(`🚀 Sending test request to ${url}`));
80
- try {
81
- const response = await fetch(url, {
82
- method,
83
- headers,
84
- body: JSON.stringify(requestBody),
85
- });
86
- if (!response.ok) {
87
- logger_1.logger.error(chalk_1.default.red(`❌ Server responded with status code: ${response.status}`));
88
- throw new Error(`Server responded with status code: ${response.status}`);
73
+ const testCall = async () => {
74
+ logger_1.logger.info(chalk_1.default.white(`👋 Saying hello to your provider...`));
75
+ const testMessages = [
76
+ { role: "user", content: "Hello, this is a test message." },
77
+ ];
78
+ const req = this.buildStreamRequest(testMessages);
79
+ if (!req) {
80
+ logger_1.logger.error(chalk_1.default.red("Failed to build test request"));
81
+ throw new Error("Failed to build test request");
89
82
  }
90
- if (!response.body) {
91
- logger_1.logger.error(chalk_1.default.red("❌ Failed to get a ReadableStream from the response"));
92
- throw new Error("Failed to get a ReadableStream from the response");
83
+ const { requestOptions, requestBody } = req;
84
+ const { protocol, hostname, port, path, method, headers } = requestOptions;
85
+ const url = `${protocol}://${hostname}:${port}${path}`;
86
+ logger_1.logger.info(chalk_1.default.white(`🚀 Sending test request to ${url}`));
87
+ try {
88
+ const response = await fetch(url, {
89
+ method,
90
+ headers,
91
+ body: JSON.stringify(requestBody),
92
+ });
93
+ if (!response.ok) {
94
+ logger_1.logger.error(chalk_1.default.red(`❌ Server responded with status code: ${response.status}`));
95
+ this.destroySwarms();
96
+ throw new Error(`Server responded with status code: ${response.status}`);
97
+ }
98
+ if (!response.body) {
99
+ logger_1.logger.error(chalk_1.default.red("❌ Failed to get a ReadableStream from the response"));
100
+ this.destroySwarms();
101
+ throw new Error("Failed to get a ReadableStream from the response");
102
+ }
103
+ logger_1.logger.info(chalk_1.default.white(`📡 Got response, checking stream...`));
104
+ const reader = response.body.getReader();
105
+ const { done } = await reader.read();
106
+ if (done) {
107
+ logger_1.logger.error(chalk_1.default.red("❌ Stream ended without data"));
108
+ this.destroySwarms();
109
+ throw new Error("Stream ended without data");
110
+ }
111
+ logger_1.logger.info(chalk_1.default.green(`✅ Test inference call successful!`));
93
112
  }
94
- logger_1.logger.info(chalk_1.default.white(`📡 Got response, checking stream...`));
95
- const reader = response.body.getReader();
96
- const { done } = await reader.read();
97
- if (done) {
98
- logger_1.logger.error(chalk_1.default.red("❌ Stream ended without data"));
99
- throw new Error("Stream ended without data");
113
+ catch (error) {
114
+ this.destroySwarms();
115
+ logger_1.logger.error(chalk_1.default.red(`❌ Error during test inference call: ${error}`));
116
+ throw error;
100
117
  }
101
- logger_1.logger.info(chalk_1.default.green(`✅ Test inference call successful!`));
102
- }
103
- catch (error) {
104
- logger_1.logger.error(chalk_1.default.red(`❌ Error during test inference call: ${error}`));
105
- throw error;
106
- }
107
- logger_1.logger.info(chalk_1.default.white(`🔗 Proceeding to join server...`));
108
- await this.joinServer();
118
+ logger_1.logger.info(chalk_1.default.white(`🔗 Test call successful!`));
119
+ };
120
+ setTimeout(() => testCall(), constants_1.PROVIDER_HELLO_TIMEOUT);
109
121
  }
110
122
  async joinServer() {
111
- const serverSwarm = new hyperswarm_1.default();
123
+ this._serverSwarm = new hyperswarm_1.default();
112
124
  const serverKey = Buffer.from(this._config.get("serverKey"));
113
- serverSwarm.join(hypercore_crypto_1.default.discoveryKey(serverKey), {
125
+ this._serverSwarm.join(hypercore_crypto_1.default.discoveryKey(serverKey), {
114
126
  client: true,
115
127
  server: false,
116
128
  });
117
- serverSwarm.flush();
118
- serverSwarm.on("connection", (peer) => {
129
+ this._serverSwarm.flush();
130
+ this._serverSwarm.on("connection", (peer) => {
119
131
  var _a;
120
132
  this._serverPeer = peer;
121
133
  logger_1.logger.info(chalk_1.default.green("🔗 Connected to server."));
134
+ this.testProviderCall();
122
135
  this._challenge = hypercore_crypto_1.default.randomBytes(32);
123
136
  this._serverPeer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.challenge, {
124
137
  challenge: this._challenge,
package/install.ps1 CHANGED
@@ -16,7 +16,7 @@ if (!(Get-Command npm -ErrorAction SilentlyContinue)) {
16
16
  }
17
17
 
18
18
  Print-Color $YELLOW "Installing symmetry-cli globally..."
19
- if (npm install -g .) {
19
+ if (npm install -g symmetry-cli) {
20
20
  Print-Color $GREEN "symmetry-cli installed successfully!"
21
21
  } else {
22
22
  Print-Color $RED "Failed to install symmetry-cli. Please check your npm configuration and try again."
@@ -56,4 +56,4 @@ Print-Color $GREEN "Installation complete! You can now run 'symmetry-cli' to sta
56
56
  Print-Color $YELLOW "Please edit $provider_yaml to customize your provider settings, especially:"
57
57
  Print-Color $YELLOW " - apiKey: Add your API key if required"
58
58
  Print-Color $YELLOW " - name: Currently set to your system username, change if needed"
59
- Print-Color $YELLOW " - public: Set to true by default, change to false if you don't want to be publicly accessible"
59
+ Print-Color $YELLOW " - public: Set to true by default, change to false if you don't want to be publicly accessible"
package/install.sh CHANGED
@@ -18,7 +18,7 @@ if ! command -v npm >/dev/null 2>&1; then
18
18
  fi
19
19
 
20
20
  print_color "$YELLOW" "Installing symmetry-cli globally..."
21
- if npm install -g .; then
21
+ if npm install -g symmetry-cli; then
22
22
  print_color "$GREEN" "symmetry-cli installed successfully!"
23
23
  else
24
24
  print_color "$RED" "Failed to install symmetry-cli. Please check your npm configuration and try again."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "symmetry-cli",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "",
5
5
  "main": "dist/symmetry.js",
6
6
  "bin": "dist/symmetry.js",
package/readme.md CHANGED
@@ -18,12 +18,12 @@ To install Symmetry, use the following commands:
18
18
 
19
19
  For Linux and macOS:
20
20
  ```bash
21
- curl -fsSL https://raw.githubusercontent.com/twinnydotdev/symmetry/master/install.sh | sh
21
+ curl -fsSL https://www.twinny.dev/symmetry-unix.sh | sh
22
22
  ```
23
23
 
24
24
  For Windows:
25
25
  ```powershell
26
- iwr -useb https://raw.githubusercontent.com/twinnydotdev/symmetry/master/install.ps1 | iex
26
+ iwr -useb https://www.twinny.dev/symmetry-windows.ps1 | iex
27
27
  ```
28
28
 
29
29
  ## Usage
package/src/constants.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export const NORMALIZE_REGEX = /\s*\r?\n|\r/g;
2
2
 
3
+ export const PROVIDER_HELLO_TIMEOUT = 30000
4
+
3
5
  export const serverMessageKeys = {
4
6
  challenge: "challenge",
5
7
  conectionSize: "conectionSize",
package/src/provider.ts CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  } from "./utils";
15
15
  import { logger } from "./logger";
16
16
  import { Peer, ProviderMessage, InferenceRequest, Message } from "./types";
17
- import { serverMessageKeys } from "./constants";
17
+ import { PROVIDER_HELLO_TIMEOUT, serverMessageKeys } from "./constants";
18
18
 
19
19
  export class SymmetryProvider {
20
20
  private _challenge: Buffer | null = null;
@@ -24,6 +24,7 @@ export class SymmetryProvider {
24
24
  private _isPublic = false;
25
25
  private _providerConnections: number = 0;
26
26
  private _providerSwarm: Hyperswarm | null = null;
27
+ private _serverSwarm: Hyperswarm | null = null;
27
28
  private _serverPeer: Peer | null = null;
28
29
 
29
30
  constructor(configPath: string) {
@@ -63,7 +64,7 @@ export class SymmetryProvider {
63
64
  chalk.white(`🔑 Server key: ${this._config.get("serverKey")}`)
64
65
  );
65
66
  logger.info(chalk.white("🔗 Joining server, please wait."));
66
- this.testProviderCall();
67
+ this.joinServer();
67
68
  }
68
69
 
69
70
  process.on("SIGINT", async () => {
@@ -78,78 +79,97 @@ export class SymmetryProvider {
78
79
  });
79
80
  }
80
81
 
82
+ async destroySwarms() {
83
+ await this._providerSwarm?.destroy();
84
+ await this._serverSwarm?.destroy();
85
+ }
86
+
81
87
  private async testProviderCall(): Promise<void> {
82
- logger.info(chalk.white(`👋 Saying hello to your provider...`));
83
- const testMessages: Message[] = [
84
- { role: "user", content: "Hello, this is a test message." },
85
- ];
86
- const req = this.buildStreamRequest(testMessages);
87
-
88
- if (!req) {
89
- logger.error(chalk.red("❌ Failed to build test request"));
90
- throw new Error("Failed to build test request");
91
- }
88
+ const testCall = async () => {
89
+ logger.info(chalk.white(`👋 Saying hello to your provider...`));
90
+ const testMessages: Message[] = [
91
+ { role: "user", content: "Hello, this is a test message." },
92
+ ];
93
+ const req = this.buildStreamRequest(testMessages);
94
+
95
+ if (!req) {
96
+ logger.error(chalk.red("Failed to build test request"));
97
+ throw new Error("Failed to build test request");
98
+ }
92
99
 
93
- const { requestOptions, requestBody } = req;
94
- const { protocol, hostname, port, path, method, headers } = requestOptions;
95
- const url = `${protocol}://${hostname}:${port}${path}`;
100
+ const { requestOptions, requestBody } = req;
101
+ const { protocol, hostname, port, path, method, headers } =
102
+ requestOptions;
103
+ const url = `${protocol}://${hostname}:${port}${path}`;
104
+
105
+ logger.info(chalk.white(`🚀 Sending test request to ${url}`));
106
+
107
+ try {
108
+ const response = await fetch(url, {
109
+ method,
110
+ headers,
111
+ body: JSON.stringify(requestBody),
112
+ });
113
+
114
+ if (!response.ok) {
115
+ logger.error(
116
+ chalk.red(
117
+ `❌ Server responded with status code: ${response.status}`
118
+ )
119
+ );
120
+ this.destroySwarms();
121
+ throw new Error(
122
+ `Server responded with status code: ${response.status}`
123
+ );
124
+ }
96
125
 
97
- logger.info(chalk.white(`🚀 Sending test request to ${url}`));
126
+ if (!response.body) {
127
+ logger.error(
128
+ chalk.red("❌ Failed to get a ReadableStream from the response")
129
+ );
130
+ this.destroySwarms();
131
+ throw new Error("Failed to get a ReadableStream from the response");
132
+ }
98
133
 
99
- try {
100
- const response = await fetch(url, {
101
- method,
102
- headers,
103
- body: JSON.stringify(requestBody),
104
- });
134
+ logger.info(chalk.white(`📡 Got response, checking stream...`));
105
135
 
106
- if (!response.ok) {
107
- logger.error(
108
- chalk.red(`❌ Server responded with status code: ${response.status}`)
109
- );
110
- throw new Error(
111
- `Server responded with status code: ${response.status}`
112
- );
113
- }
136
+ const reader = response.body.getReader();
137
+ const { done } = await reader.read();
138
+ if (done) {
139
+ logger.error(chalk.red("❌ Stream ended without data"));
140
+ this.destroySwarms();
141
+ throw new Error("Stream ended without data");
142
+ }
114
143
 
115
- if (!response.body) {
144
+ logger.info(chalk.green(`✅ Test inference call successful!`));
145
+ } catch (error) {
146
+ this.destroySwarms();
116
147
  logger.error(
117
- chalk.red("❌ Failed to get a ReadableStream from the response")
148
+ chalk.red(`❌ Error during test inference call: ${error}`)
118
149
  );
119
- throw new Error("Failed to get a ReadableStream from the response");
150
+ throw error;
120
151
  }
121
152
 
122
- logger.info(chalk.white(`📡 Got response, checking stream...`));
123
-
124
- const reader = response.body.getReader();
125
- const { done } = await reader.read();
126
- if (done) {
127
- logger.error(chalk.red("❌ Stream ended without data"));
128
- throw new Error("Stream ended without data");
129
- }
130
-
131
- logger.info(chalk.green(`✅ Test inference call successful!`));
132
- } catch (error) {
133
- logger.error(chalk.red(`❌ Error during test inference call: ${error}`));
134
- throw error;
135
- }
153
+ logger.info(chalk.white(`🔗 Test call successful!`));
154
+ };
136
155
 
137
- logger.info(chalk.white(`🔗 Proceeding to join server...`));
138
- await this.joinServer();
156
+ setTimeout(() => testCall(), PROVIDER_HELLO_TIMEOUT)
139
157
  }
140
158
 
141
159
  async joinServer(): Promise<void> {
142
- const serverSwarm = new Hyperswarm();
160
+ this._serverSwarm = new Hyperswarm();
143
161
  const serverKey = Buffer.from(this._config.get("serverKey"));
144
- serverSwarm.join(crypto.discoveryKey(serverKey), {
162
+ this._serverSwarm.join(crypto.discoveryKey(serverKey), {
145
163
  client: true,
146
164
  server: false,
147
165
  });
148
- serverSwarm.flush();
149
- serverSwarm.on("connection", (peer: Peer) => {
166
+ this._serverSwarm.flush();
167
+ this._serverSwarm.on("connection", (peer: Peer) => {
150
168
  this._serverPeer = peer;
151
169
  logger.info(chalk.green("🔗 Connected to server."));
152
170
 
171
+ this.testProviderCall();
172
+
153
173
  this._challenge = crypto.randomBytes(32);
154
174
 
155
175
  this._serverPeer.write(