symmetry-cli 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- import { SymmetryClient } from "../src/client";
1
+ import { SymmetryProvider } from "../src/provider";
2
2
  import yaml from "js-yaml";
3
3
 
4
4
  jest.mock("hyperswarm", () => {
@@ -33,7 +33,7 @@ jest.mock("js-yaml", () => ({
33
33
 
34
34
 
35
35
  describe("Symmetry", () => {
36
- let writer: SymmetryClient;
36
+ let writer: SymmetryProvider;
37
37
  const mockConfig = {
38
38
  path: "/test/path",
39
39
  temperature: 1,
@@ -47,12 +47,13 @@ describe("Symmetry", () => {
47
47
  name: "test",
48
48
  public: true,
49
49
  serverKey: "test-server-key",
50
+ systemMessage: "test-system-message",
50
51
  };
51
52
 
52
53
  beforeEach(() => {
53
54
  jest.clearAllMocks();
54
55
  (yaml.load as jest.Mock).mockReturnValue(mockConfig);
55
- writer = new SymmetryClient("mock-config.yaml");
56
+ writer = new SymmetryProvider("mock-config.yaml");
56
57
  });
57
58
 
58
59
  test("init method sets up the writer correctly", async () => {
package/dist/provider.js CHANGED
@@ -149,7 +149,14 @@ class SymmetryProvider {
149
149
  }
150
150
  async handleInferenceRequest(data, peer) {
151
151
  const emitterKey = data.data.key;
152
+ const messages = data === null || data === void 0 ? void 0 : data.data.messages;
152
153
  const req = this.buildStreamRequest(data === null || data === void 0 ? void 0 : data.data.messages);
154
+ if (messages.length === 2) {
155
+ messages.unshift({
156
+ role: "system",
157
+ content: this._config.get("systemMessage"),
158
+ });
159
+ }
153
160
  if (!req)
154
161
  return;
155
162
  const { requestOptions, requestBody } = req;
@@ -192,10 +199,7 @@ class SymmetryProvider {
192
199
  });
193
200
  await Promise.resolve(peerPipeline);
194
201
  peer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.inferenceEnded, data === null || data === void 0 ? void 0 : data.data.key));
195
- if (this._config.get("dataCollectionEnabled") &&
196
- data.data.key === constants_1.serverMessageKeys.inference) {
197
- this.saveCompletion(completion, peer, data.data.messages);
198
- }
202
+ this.saveCompletion(completion, peer, data.data.messages);
199
203
  }
200
204
  catch (error) {
201
205
  let errorMessage = "An error occurred during inference";
package/install.ps1 CHANGED
@@ -1,6 +1,6 @@
1
+ # Symmetry CLI Install Script for Windows
1
2
  $ErrorActionPreference = "Stop"
2
3
 
3
- # Colors for output
4
4
  $RED = "`e[31m"
5
5
  $GREEN = "`e[32m"
6
6
  $YELLOW = "`e[33m"
@@ -10,48 +10,19 @@ function Print-Color($color, $message) {
10
10
  Write-Host "$color$message$NC"
11
11
  }
12
12
 
13
- # Check if npm is installed
14
13
  if (!(Get-Command npm -ErrorAction SilentlyContinue)) {
15
14
  Print-Color $RED "Error: npm is not installed. Please install Node.js and npm first."
16
15
  exit 1
17
16
  }
18
17
 
19
- # Install symmetry-cli globally
20
18
  Print-Color $YELLOW "Installing symmetry-cli globally..."
21
- try {
22
- npm install -g symmetry-cli
19
+ if (npm install -g .) {
23
20
  Print-Color $GREEN "symmetry-cli installed successfully!"
24
- }
25
- catch {
21
+ } else {
26
22
  Print-Color $RED "Failed to install symmetry-cli. Please check your npm configuration and try again."
27
23
  exit 1
28
24
  }
29
25
 
30
- # Prompt for API provider
31
- Print-Color $YELLOW "Please select an API provider:"
32
- $providers = @{
33
- 1 = @{name = "LiteLLM"; value = "litellm"}
34
- 2 = @{name = "LlamaCpp"; value = "llamacpp"}
35
- 3 = @{name = "LMStudio"; value = "lmstudio"}
36
- 4 = @{name = "Ollama"; value = "ollama"}
37
- 5 = @{name = "Oobabooga"; value = "oobabooga"}
38
- 6 = @{name = "OpenWebUI"; value = "openwebui"}
39
- }
40
-
41
- $providers.GetEnumerator() | ForEach-Object {
42
- Write-Host "$($_.Key): $($_.Value.name)"
43
- }
44
-
45
- do {
46
- $selection = Read-Host "Enter the number of your choice"
47
- $api_provider = $providers[$selection].value
48
- } while (-not $api_provider)
49
-
50
- # Prompt for model name
51
- Print-Color $YELLOW "Please enter the model name you want to use:"
52
- $model_name = Read-Host
53
-
54
- # Create config directory and provider.yaml file
55
26
  $config_dir = "$env:USERPROFILE\.config\symmetry"
56
27
  $provider_yaml = "$config_dir\provider.yaml"
57
28
 
@@ -66,18 +37,17 @@ apiKey:
66
37
  apiPath: /v1/chat/completions
67
38
  apiPort: 11434
68
39
  apiProtocol: http
69
- apiProvider: $api_provider
40
+ apiProvider: ollama
70
41
  dataCollectionEnabled: true
71
42
  maxConnections: 10
72
- modelName: $model_name
43
+ modelName: llama3.1:latest
73
44
  name: $env:USERNAME
74
45
  path: $config_dir
75
46
  public: true
76
47
  serverKey: 4b4a9cc325d134dee6679e9407420023531fd7e96c563f6c5d00fd5549b77435
77
48
  "@ | Set-Content $provider_yaml
78
49
  Print-Color $GREEN "provider.yaml created successfully at $provider_yaml"
79
- }
80
- else {
50
+ } else {
81
51
  Print-Color $YELLOW "provider.yaml already exists at $provider_yaml"
82
52
  }
83
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "symmetry-cli",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "",
5
5
  "main": "dist/symmetry.js",
6
6
  "bin": "dist/symmetry.js",
package/readme.md CHANGED
@@ -1,63 +1,66 @@
1
- # Symmetry
1
+ # Symmetry
2
2
 
3
- In the vast lands of the Internet, where bits and bytes flow like the rivers of old, there arose a tool of great power and purpose. Symmetry the enchanted mirror. With Symmetry, users of the digital realm could offer their computational strength to others, allowing seekers of knowledge to tap into the wisdom of distant machines.
3
+ Use this repository to become an inference provider on the Symmetry network.
4
+
5
+ Symmetry is a decentralized peer-to-peer network tool that allows users to share computational resources for AI inference. It enables users to connect directly and securely with each other, offering or seeking computational power for various AI tasks.
4
6
 
5
7
  ## Features
6
8
 
7
- - **Network**: A decentralized network, of interconnected peers.
8
- - **Configuration**: A scroll of YAML, easily inscribed to bend Symmetry to one's will.
9
- - **Privacy**: A choice between openness and secrecy.
10
- - **Data collection**: An option to gather tales of interactions, should the provider wish it so.
9
+ - Decentralized peer-to-peer network
10
+ - YAML-based configuration
11
+ - Privacy options
12
+ - Optional data collection for providers
13
+ - Compatible with various AI inference providers
11
14
 
12
15
  ## Installation
13
16
 
14
- To call forth Symmetry into your realm, speak these words of power:
17
+ To install Symmetry, use the following commands:
15
18
 
16
- Linux and MacOs
17
- ```
19
+ For Linux and macOS:
20
+ ```bash
18
21
  curl -fsSL https://raw.githubusercontent.com/twinnydotdev/symmetry/master/install.sh | sh
19
22
  ```
20
23
 
21
- Windows
22
- ```
24
+ For Windows:
25
+ ```powershell
23
26
  iwr -useb https://raw.githubusercontent.com/twinnydotdev/symmetry/master/install.ps1 | iex
24
27
  ```
25
28
 
26
29
  ## Usage
27
30
 
28
- To awaken Symmetry, utter this command:
31
+ To start Symmetry, run:
29
32
 
30
- ```
33
+ ```bash
31
34
  symmetry-cli
32
35
  ```
33
36
 
34
- Symmetry will seek its tome of knowledge in the halls of `~/.config/symmetry/provider.yaml`. Should you wish to direct it to another scroll, speak thus:
37
+ By default, Symmetry looks for its configuration file at `~/.config/symmetry/provider.yaml`. To use a different configuration file, use:
35
38
 
36
- ```
37
- symmetry -c /path/to/your/sacred/provider.yaml
39
+ ```bash
40
+ symmetry-cli -c /path/to/your/provider.yaml
38
41
  ```
39
42
 
40
43
  ## Configuration
41
44
 
42
- Inscribe your `provider.yaml` with these mystical runes:
45
+ Here's an example `provider.yaml` configuration:
43
46
 
44
47
  ```yaml
45
- apiHostname: localhost # The dwelling of your local oracle
46
- apiKey: # The secret word to commune with your oracle
47
- apiPath: /v1/chat/completions # The path to wisdom
48
- apiPort: 11434 # The gate through which knowledge flows
49
- apiProtocol: http # The method of communion
50
- apiProvider: ollama # The lineage of your oracle
51
- dataCollectionEnabled: true # Whether to gather lore
52
- maxConnections: 10 # The limit of simultaneous seekers
53
- modelName: llama3:8b # The true name of your oracle
54
- name: # Your title in this realm
55
- path: /home/richard/.config/symmetry/default # The dwelling for data
56
- public: true # Whether your services are open to all
57
- serverKey: 4b4a9cc325d134dee6679e9407420023531fd7e96c563f6c5d00fd5549b77435 # The key of the central tower
48
+ apiHostname: localhost # The hostname of the API server.
49
+ apiKey: # The API key for authentication.
50
+ apiPath: /v1/chat/completions # The endpoint path for chat completions.
51
+ apiPort: 11434 # The port number on which the API server is listening.
52
+ apiProtocol: http # The protocol used to communicate with the API server.
53
+ apiProvider: ollama # The name of the API provider.
54
+ dataCollectionEnabled: false # Whether to enable data collection.
55
+ maxConnections: 10 # The maximum number of connections.
56
+ modelName: llama3.1:latest # The name and version of the AI model to use.
57
+ name: twinnydotdev # Your chosen name as a provider on the Symmetry network.
58
+ path: /home/twinnydotdev/.config/symmetry/data # The local path where Symmetry will store its configuration and data files.
59
+ public: true # Whether this provider is publicly accessible on the Symmetry network.
60
+ serverKey: 4b4a9cc325d134dee6679e9407420023531fd7e96c563f6c5d00fd5549b77435 # The unique key for connecting to the Symmetry server.
58
61
  ```
59
62
 
60
- Adjust these runes to align with your own preferences.
63
+ Adjust these settings according to your preferences and setup.
61
64
 
62
65
  ## Architecture
63
66
 
@@ -88,80 +91,46 @@ graph TB
88
91
 
89
92
  C1 <--> |"4. Inference<br/>Request/Response"| P2
90
93
  C2 <--> |"4. Inference<br/>Request/Response"| P3
91
-
92
- style S fill:#ff9900,stroke:#333,stroke-width:4px
93
- style P1 fill:#00ccff,stroke:#333,stroke-width:2px
94
- style P2 fill:#00ccff,stroke:#333,stroke-width:2px
95
- style P3 fill:#00ccff,stroke:#333,stroke-width:2px
96
- style C1 fill:#333,stroke:#fff,stroke-width:2px
97
- style C2 fill:#333,stroke:#fff,stroke-width:2px
98
94
  ```
99
95
 
100
- ### Server, Providers and Clients:
101
- - **Central Server**: Symmetry Server, a beacon of order in the chaotic digital winds.
102
- - **Providers**: Inference Providers, keepers of knowledge and computational might.
103
- - **Client**: Clients, adventurers in search of answers from the oracles of data.
104
-
105
- ### Connection:
106
-
107
- 1. The Providers approach the Central Tower, proving their worth and declaring their specialties.
108
- 2. Seekers call out to the Tower, their questions echoing in the digital void.
109
- 3. The Tower, in its wisdom, guides each Seeker to a suitable Provider.
110
- 4. Seeker and Provider join in a dance of query and response, their connection direct and true.
111
-
112
- ### Communication:
113
-
114
- - All messages between Seekers and Providers are cloaked in unbreakable encryption, safe from prying eyes.
115
- - The Providers may choose to remember the tales told to them, a choice they must declare openly.
116
- - Seekers are granted the wisdom to choose their Providers based on these declarations of memory.
96
+ ## Development
117
97
 
118
- ### Features:
98
+ To set up Symmetry for development:
119
99
 
120
- - **Adaptability**: As changeable as the seasons, ready for new knowledge and new seekers.
121
- - **Swiftness**: Direct connections ensure that wisdom flows like the rapids of a mountain stream.
122
- - **Guardianship**: Only the worthy may enter this circle of trust.
123
- - **Balance**: The Tower ensures no single Provider bears too heavy a burden.
124
- - **Growth**: New Providers may join the circle, expanding the realm of possibility.
125
-
126
- Thus does Symmetry weave its web of connections, bringing together the seekers and keepers of digital wisdom in a grand tapestry of knowledge and computation.
127
-
128
- ## Forging of Symmetry
129
-
130
- For those who wish to shape Symmetry with their own hands:
131
-
132
- 1. Summon the essence:
133
- ```
100
+ 1. Clone the repository:
101
+ ```bash
134
102
  git clone https://github.com/twinnydotdev/symmetry.git
135
103
  cd symmetry
136
104
  ```
137
105
 
138
- 2. Gather the necessary elements:
139
- ```
106
+ 2. Install dependencies:
107
+ ```bash
140
108
  npm install
141
109
  ```
142
110
 
143
- 3. Forge the tool:
144
- ```
111
+ 3. Build the project:
112
+ ```bash
145
113
  npm run build
146
114
  ```
147
115
 
148
- 4. Awaken:
149
- ```
150
- npm start
116
+ 4. Start the development server:
117
+ ```bash
118
+ npm run dev
151
119
  ```
152
120
 
153
- ## Call for Heroes
121
+ ## Contributing
122
+
123
+ Contributions are welcome! Please submit your pull requests to the [GitHub repository](https://github.com/twinnydotdev/symmetry/pulls).
154
124
 
155
- Brave souls willing to improve upon this grand design are most welcome. Present your [scrolls of change](https://github.com/twinnydotdev/symmetry/pulls) for consideration.
125
+ ## License
156
126
 
157
- ## Covenant
127
+ This project is licensed under the [MIT License](https://github.com/twinnydotdev/symmetry/blob/master/LICENCE).
158
128
 
159
- This work is protected under the [Oath of MIT](https://github.com/twinnydotdev/symmetry/blob/main/LICENSE), a sacred bond between creator and user.
129
+ ## Support
160
130
 
161
- ## Council of Elders
131
+ If you encounter any issues or have questions, please [open an issue](https://github.com/twinnydotdev/symmetry/issues) on GitHub.
162
132
 
163
- Should you face trials or seek guidance, bring your [queries](https://github.com/twinnydotdev/symmetry/issues) before the Council on GitHub.
133
+ ## Acknowledgments
164
134
 
165
- ## A Nod to the Ancients
135
+ We thank [Hyperswarm](https://github.com/holepunchto/hyperswarm) for providing the underlying peer-to-peer networking capabilities.
166
136
 
167
- We pay homage to [Hyperswarm](https://github.com/holepunchto/hyperswarm), the tool that makes our connections possible.
package/src/provider.ts CHANGED
@@ -13,10 +13,8 @@ import {
13
13
  safeParseStreamResponse,
14
14
  } from "./utils";
15
15
  import { logger } from "./logger";
16
- import { Peer, ProviderMessage, InferenceRequest } from "./types";
17
- import {
18
- serverMessageKeys,
19
- } from "./constants";
16
+ import { Peer, ProviderMessage, InferenceRequest, Message } from "./types";
17
+ import { serverMessageKeys } from "./constants";
20
18
 
21
19
  export class SymmetryProvider {
22
20
  private _challenge: Buffer | null = null;
@@ -192,13 +190,24 @@ export class SymmetryProvider {
192
190
  });
193
191
  }
194
192
 
193
+ private getMessagesWithSystem(messages: Message[]): Message[] {
194
+ const systemMessage = this._config.get("systemMessage")
195
+ if (messages.length === 2 && systemMessage) {
196
+ messages.unshift({
197
+ role: "system",
198
+ content: systemMessage,
199
+ });
200
+ }
201
+ return messages;
202
+ }
203
+
195
204
  private async handleInferenceRequest(
196
205
  data: ProviderMessage<InferenceRequest>,
197
206
  peer: Peer
198
207
  ): Promise<void> {
199
208
  const emitterKey = data.data.key;
200
-
201
- const req = this.buildStreamRequest(data?.data.messages);
209
+ const messages = this.getMessagesWithSystem(data?.data.messages);
210
+ const req = this.buildStreamRequest(messages);
202
211
 
203
212
  if (!req) return;
204
213
 
@@ -277,7 +286,7 @@ export class SymmetryProvider {
277
286
  private async saveCompletion(
278
287
  completion: string,
279
288
  peer: Peer,
280
- messages: { role: string; content: string }[]
289
+ messages: Message[]
281
290
  ) {
282
291
  fs.writeFile(
283
292
  `${this._config.get("path")}/${peer.publicKey.toString("hex")}-${
@@ -296,7 +305,7 @@ export class SymmetryProvider {
296
305
  );
297
306
  }
298
307
 
299
- private buildStreamRequest(messages: { role: string; content: string }[]) {
308
+ private buildStreamRequest(messages: Message[]) {
300
309
  const requestOptions = {
301
310
  hostname: this._config.get("apiHostname"),
302
311
  port: Number(this._config.get("apiPort")),
package/src/types.ts CHANGED
@@ -18,6 +18,7 @@ export interface ProviderConfig {
18
18
  port: number;
19
19
  public: boolean;
20
20
  serverKey: string;
21
+ systemMessage: string;
21
22
  }
22
23
 
23
24
  export interface ProviderMessage<T = unknown> {
@@ -27,7 +28,7 @@ export interface ProviderMessage<T = unknown> {
27
28
 
28
29
  export interface InferenceRequest {
29
30
  key: string;
30
- messages: { role: string; content: string }[];
31
+ messages: Message[];
31
32
  }
32
33
 
33
34
  interface ReadableState {