symmetry-cli 1.0.7 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +0 -1
- package/dist/symmetry.js +2 -2
- package/package.json +3 -10
- package/readme.md +16 -0
- package/src/symmetry.ts +1 -2
- package/__test__/cli.test.ts +0 -62
- package/dist/client.js +0 -230
- package/dist/config-manager.js +0 -58
- package/dist/config.js +0 -44
- package/dist/constants.js +0 -31
- package/dist/database.js +0 -9
- package/dist/logger.js +0 -45
- package/dist/peer-repository.js +0 -114
- package/dist/provider.js +0 -307
- package/dist/server.js +0 -143
- package/dist/session-manager.js +0 -68
- package/dist/session-repository.js +0 -127
- package/dist/types.js +0 -2
- package/dist/utils.js +0 -53
- package/dist/websocket-server.js +0 -52
- package/src/config.ts +0 -51
- package/src/constants.ts +0 -31
- package/src/logger.ts +0 -47
- package/src/provider.ts +0 -411
- package/src/types.ts +0 -243
- package/src/utils.ts +0 -52
package/dist/symmetry.js
CHANGED
@@ -5,16 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
};
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
7
7
|
const commander_1 = require("commander");
|
8
|
+
const symmetry_core_1 = require("symmetry-core");
|
8
9
|
const os_1 = __importDefault(require("os"));
|
9
10
|
const path_1 = __importDefault(require("path"));
|
10
|
-
const provider_1 = require("./provider");
|
11
11
|
const program = new commander_1.Command();
|
12
12
|
program
|
13
13
|
.version("1.0.0")
|
14
14
|
.description("symmetry cli")
|
15
15
|
.option("-c, --config <path>", "Path to config file", path_1.default.join(os_1.default.homedir(), ".config", "symmetry", "provider.yaml"))
|
16
16
|
.action(async () => {
|
17
|
-
const client = new
|
17
|
+
const client = new symmetry_core_1.SymmetryProvider(program.opts().config);
|
18
18
|
await client.init();
|
19
19
|
});
|
20
20
|
program.parse(process.argv);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "symmetry-cli",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.11",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/symmetry.js",
|
6
6
|
"bin": "dist/symmetry.js",
|
@@ -16,14 +16,8 @@
|
|
16
16
|
"lint": "eslint . --ext .ts,.js --fix"
|
17
17
|
},
|
18
18
|
"dependencies": {
|
19
|
-
"chalk": "^4.1.2",
|
20
19
|
"commander": "^12.1.0",
|
21
|
-
"
|
22
|
-
"hyperdht": "^6.15.4",
|
23
|
-
"hyperswarm": "^4.8.0",
|
24
|
-
"js-yaml": "^4.1.0",
|
25
|
-
"sqlite3": "^5.1.7",
|
26
|
-
"ws": "^8.18.0"
|
20
|
+
"symmetry-core": "^1.0.5"
|
27
21
|
},
|
28
22
|
"devDependencies": {
|
29
23
|
"@types/jest": "^29.5.12",
|
@@ -38,6 +32,5 @@
|
|
38
32
|
"ts-jest": "^29.2.2",
|
39
33
|
"ts-node": "^10.9.2",
|
40
34
|
"typescript": "^5.5.4"
|
41
|
-
}
|
42
|
-
"types": "types/twinnymind.d.ts"
|
35
|
+
}
|
43
36
|
}
|
package/readme.md
CHANGED
@@ -34,6 +34,22 @@ To start Symmetry, run:
|
|
34
34
|
symmetry-cli
|
35
35
|
```
|
36
36
|
|
37
|
+
You will then be joined with the symmetry server and ready for connections!
|
38
|
+
|
39
|
+
```bash
|
40
|
+
ℹ️ INFO: 🔗 Initializing client using config file: /home/twinnydotdev/.config/symmetry/provider.yaml
|
41
|
+
ℹ️ INFO: 📁 Symmetry client initialized.
|
42
|
+
ℹ️ INFO: 🔑 Discovery key: xxx
|
43
|
+
ℹ️ INFO: 🔑 Server key: 4b4a9cc325d134dee6679e9407420023531fd7e96c563f6c5d00fd5549b77435
|
44
|
+
ℹ️ INFO: 🔗 Joining server, please wait.
|
45
|
+
ℹ️ INFO: 🔗 Connected to server.
|
46
|
+
ℹ️ INFO: ✅ Verification successful.
|
47
|
+
ℹ️ INFO: 👋 Saying hello to your provider...
|
48
|
+
ℹ️ INFO: 🚀 Sending test request to http://localhost:11434/v1/chat/completions
|
49
|
+
ℹ️ INFO: 📡 Got response, checking stream...
|
50
|
+
ℹ️ INFO: ✅ Test inference call successful!
|
51
|
+
```
|
52
|
+
|
37
53
|
By default, Symmetry looks for its configuration file at `~/.config/symmetry/provider.yaml`. To use a different configuration file, use:
|
38
54
|
|
39
55
|
```bash
|
package/src/symmetry.ts
CHANGED
package/__test__/cli.test.ts
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
import { SymmetryProvider } from "../src/provider";
|
2
|
-
import yaml from "js-yaml";
|
3
|
-
|
4
|
-
jest.mock("hyperswarm", () => {
|
5
|
-
return jest.fn().mockImplementation(() => ({
|
6
|
-
join: jest
|
7
|
-
.fn()
|
8
|
-
.mockReturnValue({ flushed: jest.fn().mockResolvedValue(undefined) }),
|
9
|
-
on: jest.fn(),
|
10
|
-
destroy: jest.fn().mockResolvedValue(undefined),
|
11
|
-
flush: jest.fn().mockResolvedValue(undefined),
|
12
|
-
}));
|
13
|
-
});
|
14
|
-
|
15
|
-
jest.mock("hypercore-crypto", () => ({
|
16
|
-
discoveryKey: jest.fn().mockReturnValue("test"),
|
17
|
-
keyPair: jest.fn().mockReturnValue({
|
18
|
-
publicKey: "test-public-key",
|
19
|
-
secretKey: "test-secret-key",
|
20
|
-
}),
|
21
|
-
sign: jest.fn(),
|
22
|
-
}));
|
23
|
-
|
24
|
-
jest.mock("fs", () => ({
|
25
|
-
readFileSync: jest.fn(),
|
26
|
-
writeFileSync: jest.fn(),
|
27
|
-
existsSync: jest.fn(),
|
28
|
-
}));
|
29
|
-
|
30
|
-
jest.mock("js-yaml", () => ({
|
31
|
-
load: jest.fn(),
|
32
|
-
}));
|
33
|
-
|
34
|
-
|
35
|
-
describe("Symmetry", () => {
|
36
|
-
let writer: SymmetryProvider;
|
37
|
-
const mockConfig = {
|
38
|
-
path: "/test/path",
|
39
|
-
temperature: 1,
|
40
|
-
apiHostname: "test.api.com",
|
41
|
-
apiPort: 443,
|
42
|
-
apiPath: "/v1/chat",
|
43
|
-
apiProtocol: "https",
|
44
|
-
apiKey: "test-api-key",
|
45
|
-
apiProvider: "test-provider",
|
46
|
-
modelName: "test-model",
|
47
|
-
name: "test",
|
48
|
-
public: false,
|
49
|
-
serverKey: "test-server-key",
|
50
|
-
systemMessage: "test-system-message",
|
51
|
-
};
|
52
|
-
|
53
|
-
beforeEach(() => {
|
54
|
-
jest.clearAllMocks();
|
55
|
-
(yaml.load as jest.Mock).mockReturnValue(mockConfig);
|
56
|
-
writer = new SymmetryProvider("mock-config.yaml");
|
57
|
-
});
|
58
|
-
|
59
|
-
test("init method sets up the writer correctly", async () => {
|
60
|
-
await writer.init();
|
61
|
-
});
|
62
|
-
});
|
package/dist/client.js
DELETED
@@ -1,230 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.SymmetryClient = void 0;
|
7
|
-
const node_stream_1 = require("node:stream");
|
8
|
-
const promises_1 = require("stream/promises");
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
10
|
-
const hyperswarm_1 = __importDefault(require("hyperswarm"));
|
11
|
-
const hypercore_crypto_1 = __importDefault(require("hypercore-crypto"));
|
12
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
13
|
-
const config_1 = require("./config");
|
14
|
-
const utils_1 = require("./utils");
|
15
|
-
const logger_1 = require("./logger");
|
16
|
-
const constants_1 = require("./constants");
|
17
|
-
class SymmetryClient {
|
18
|
-
constructor(configPath) {
|
19
|
-
this._conversationIndex = 0;
|
20
|
-
this._discoveryKey = null;
|
21
|
-
this._isPublic = false;
|
22
|
-
this._providerSwarm = null;
|
23
|
-
this._serverPeer = null;
|
24
|
-
this._challenge = null;
|
25
|
-
logger_1.logger.info(`🔗 Initializing client using config file: ${configPath}`);
|
26
|
-
this._config = new config_1.ConfigManager(configPath);
|
27
|
-
this._isPublic = this._config.get("public");
|
28
|
-
}
|
29
|
-
async init() {
|
30
|
-
this._providerSwarm = new hyperswarm_1.default();
|
31
|
-
const keyPair = hypercore_crypto_1.default.keyPair();
|
32
|
-
this._discoveryKey = hypercore_crypto_1.default.discoveryKey(keyPair.publicKey);
|
33
|
-
const discovery = this._providerSwarm.join(this._discoveryKey, {
|
34
|
-
client: true,
|
35
|
-
server: false,
|
36
|
-
});
|
37
|
-
await discovery.flushed();
|
38
|
-
this._providerSwarm.on("error", (err) => {
|
39
|
-
logger_1.logger.error(chalk_1.default.red("🚨 Swarm Error:"), err);
|
40
|
-
});
|
41
|
-
this._providerSwarm.on("connection", (peer) => {
|
42
|
-
var _a, _b;
|
43
|
-
(_a = this._serverPeer) === null || _a === void 0 ? void 0 : _a.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.conectionSize, {
|
44
|
-
connections: (_b = this._providerSwarm) === null || _b === void 0 ? void 0 : _b.connections.size,
|
45
|
-
}));
|
46
|
-
logger_1.logger.info(`⚡️ New connection from peer: ${peer.rawStream.remoteHost}`);
|
47
|
-
this.listeners(peer);
|
48
|
-
});
|
49
|
-
logger_1.logger.info(`📁 Symmetry client initialized.`);
|
50
|
-
logger_1.logger.info(`🔑 Discovery key: ${this._discoveryKey.toString("hex")}`);
|
51
|
-
if (this._isPublic) {
|
52
|
-
logger_1.logger.info(chalk_1.default.white(`🔑 Server key: ${this._config.get("serverKey")}`));
|
53
|
-
logger_1.logger.info(chalk_1.default.white("🔗 Joining server, please wait."));
|
54
|
-
await this.joinServer();
|
55
|
-
}
|
56
|
-
}
|
57
|
-
async joinServer() {
|
58
|
-
const serverSwarm = new hyperswarm_1.default();
|
59
|
-
const serverKey = Buffer.from(this._config.get("serverKey"));
|
60
|
-
serverSwarm.join(hypercore_crypto_1.default.discoveryKey(serverKey), {
|
61
|
-
client: true,
|
62
|
-
server: false,
|
63
|
-
});
|
64
|
-
serverSwarm.flush();
|
65
|
-
serverSwarm.on("connection", (peer) => {
|
66
|
-
this._serverPeer = peer;
|
67
|
-
logger_1.logger.info(chalk_1.default.green("🔗 Connected to server."));
|
68
|
-
this._challenge = hypercore_crypto_1.default.randomBytes(32);
|
69
|
-
this._serverPeer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.challenge, {
|
70
|
-
challenge: this._challenge,
|
71
|
-
}));
|
72
|
-
this._serverPeer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.join, {
|
73
|
-
...this._config.getAll(),
|
74
|
-
discoveryKey: this._discoveryKey,
|
75
|
-
}));
|
76
|
-
this._serverPeer.on("data", async (buffer) => {
|
77
|
-
if (!buffer)
|
78
|
-
return;
|
79
|
-
const data = (0, utils_1.safeParseJson)(buffer.toString());
|
80
|
-
if (data && data.key) {
|
81
|
-
switch (data.key) {
|
82
|
-
case constants_1.serverMessageKeys.challenge:
|
83
|
-
this.handleServerHandshake(data.data);
|
84
|
-
break;
|
85
|
-
}
|
86
|
-
}
|
87
|
-
});
|
88
|
-
});
|
89
|
-
}
|
90
|
-
getServerPublicKey(serverKeyHex) {
|
91
|
-
const publicKey = Buffer.from(serverKeyHex, "hex");
|
92
|
-
if (publicKey.length !== 32) {
|
93
|
-
throw new Error(`Expected a 32-byte public key, but got ${publicKey.length} bytes`);
|
94
|
-
}
|
95
|
-
return publicKey;
|
96
|
-
}
|
97
|
-
handleServerHandshake(data) {
|
98
|
-
if (!this._challenge) {
|
99
|
-
console.log("No challenge set. Cannot verify.");
|
100
|
-
return;
|
101
|
-
}
|
102
|
-
const serverKeyHex = this._config.get("serverKey");
|
103
|
-
try {
|
104
|
-
const publicKey = this.getServerPublicKey(serverKeyHex);
|
105
|
-
const signatureBuffer = Buffer.from(data.signature.data, "base64");
|
106
|
-
const verified = hypercore_crypto_1.default.verify(this._challenge, signatureBuffer, publicKey);
|
107
|
-
if (verified) {
|
108
|
-
logger_1.logger.info(chalk_1.default.greenBright(`✅ Verification handshake successful.`));
|
109
|
-
}
|
110
|
-
else {
|
111
|
-
logger_1.logger.error(`❌ Verification failed!`);
|
112
|
-
}
|
113
|
-
}
|
114
|
-
catch (error) {
|
115
|
-
console.error("Error during verification:", error);
|
116
|
-
}
|
117
|
-
}
|
118
|
-
heartbeat(peer) {
|
119
|
-
peer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.heartbeat, {
|
120
|
-
discoveryKey: this._discoveryKey,
|
121
|
-
}));
|
122
|
-
}
|
123
|
-
listeners(peer) {
|
124
|
-
peer.on("close", () => {
|
125
|
-
logger_1.logger.info(`🔌 Peer ${peer.rawStream.remoteHost} disconnected.`);
|
126
|
-
});
|
127
|
-
peer.on("data", async (buffer) => {
|
128
|
-
if (!buffer)
|
129
|
-
return;
|
130
|
-
const data = (0, utils_1.safeParseJson)(buffer.toString());
|
131
|
-
if (data && data.key) {
|
132
|
-
switch (data.key) {
|
133
|
-
case constants_1.serverMessageKeys.newConversation:
|
134
|
-
this._conversationIndex = this._conversationIndex + 1;
|
135
|
-
break;
|
136
|
-
case constants_1.serverMessageKeys.inference:
|
137
|
-
logger_1.logger.info(`📦 Inference message received from ${peer.rawStream.remoteHost}`);
|
138
|
-
await this.handleInference(data, peer);
|
139
|
-
break;
|
140
|
-
}
|
141
|
-
}
|
142
|
-
});
|
143
|
-
}
|
144
|
-
async handleInference(data, peer) {
|
145
|
-
const messages = data === null || data === void 0 ? void 0 : data.data;
|
146
|
-
if (!messages || !messages.length)
|
147
|
-
return;
|
148
|
-
const req = this.buildStreamRequest(messages);
|
149
|
-
if (!req)
|
150
|
-
return;
|
151
|
-
const { requestOptions, requestBody } = req;
|
152
|
-
const { protocol, hostname, port, path, method, headers } = requestOptions;
|
153
|
-
const url = `${protocol}://${hostname}:${port}${path}`;
|
154
|
-
try {
|
155
|
-
const response = await fetch(url, {
|
156
|
-
method,
|
157
|
-
headers,
|
158
|
-
body: JSON.stringify(requestBody),
|
159
|
-
});
|
160
|
-
if (!response.ok) {
|
161
|
-
throw new Error(`Server responded with status code: ${response.status}`);
|
162
|
-
}
|
163
|
-
if (!response.body) {
|
164
|
-
throw new Error("Failed to get a ReadableStream from the response");
|
165
|
-
}
|
166
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
167
|
-
const responseStream = node_stream_1.Readable.fromWeb(response.body);
|
168
|
-
const peerStream = new node_stream_1.PassThrough();
|
169
|
-
responseStream.pipe(peerStream);
|
170
|
-
let completion = "";
|
171
|
-
const provider = this._config.get("apiProvider");
|
172
|
-
const peerPipeline = (0, promises_1.pipeline)(peerStream, async function (source) {
|
173
|
-
for await (const chunk of source) {
|
174
|
-
if (peer.writable) {
|
175
|
-
completion += (0, utils_1.getChatDataFromProvider)(provider, (0, utils_1.safeParseStreamResponse)(chunk.toString()));
|
176
|
-
if (!peer.write(chunk)) {
|
177
|
-
await new Promise((resolve) => peer.once("drain", resolve));
|
178
|
-
}
|
179
|
-
}
|
180
|
-
else {
|
181
|
-
break;
|
182
|
-
}
|
183
|
-
}
|
184
|
-
});
|
185
|
-
await Promise.resolve(peerPipeline);
|
186
|
-
if (this._config.get("dataCollectionEnabled")) {
|
187
|
-
this.saveCompletion(completion, peer, messages);
|
188
|
-
}
|
189
|
-
}
|
190
|
-
catch (error) {
|
191
|
-
let errorMessage = "An error occurred during inference";
|
192
|
-
if (error instanceof Error)
|
193
|
-
errorMessage = error.message;
|
194
|
-
logger_1.logger.error(`🚨 ${errorMessage}`);
|
195
|
-
}
|
196
|
-
}
|
197
|
-
async saveCompletion(completion, peer, messages) {
|
198
|
-
node_fs_1.default.writeFile(`${this._config.get("path")}/${peer.publicKey.toString("hex")}-${this._conversationIndex}.json`, JSON.stringify([
|
199
|
-
...messages,
|
200
|
-
{
|
201
|
-
role: "assistant",
|
202
|
-
content: completion,
|
203
|
-
},
|
204
|
-
]), () => {
|
205
|
-
logger_1.logger.info(`📝 Completion saved to file`);
|
206
|
-
});
|
207
|
-
}
|
208
|
-
buildStreamRequest(messages) {
|
209
|
-
const requestOptions = {
|
210
|
-
hostname: this._config.get("apiHostname"),
|
211
|
-
port: Number(this._config.get("apiPort")),
|
212
|
-
path: this._config.get("apiPath"),
|
213
|
-
protocol: this._config.get("apiProtocol"),
|
214
|
-
method: "POST",
|
215
|
-
headers: {
|
216
|
-
"Content-Type": "application/json",
|
217
|
-
Authorization: `Bearer ${this._config.get("apiKey")}`,
|
218
|
-
},
|
219
|
-
};
|
220
|
-
const requestBody = {
|
221
|
-
model: this._config.get("modelName"),
|
222
|
-
messages: messages || undefined,
|
223
|
-
temperature: 1, // TODO: Make this configurable
|
224
|
-
stream: true,
|
225
|
-
};
|
226
|
-
return { requestOptions, requestBody };
|
227
|
-
}
|
228
|
-
}
|
229
|
-
exports.SymmetryClient = SymmetryClient;
|
230
|
-
exports.default = SymmetryClient;
|
package/dist/config-manager.js
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.ConfigManager = void 0;
|
7
|
-
exports.createConfigManager = createConfigManager;
|
8
|
-
exports.createConfigManagerClient = createConfigManagerClient;
|
9
|
-
const fs_1 = __importDefault(require("fs"));
|
10
|
-
const js_yaml_1 = __importDefault(require("js-yaml"));
|
11
|
-
class ConfigManager {
|
12
|
-
constructor(configPath) {
|
13
|
-
const configFile = fs_1.default.readFileSync(configPath, "utf8");
|
14
|
-
const loadedConfig = js_yaml_1.default.load(configFile);
|
15
|
-
this.config = {
|
16
|
-
...loadedConfig,
|
17
|
-
type: "client"
|
18
|
-
};
|
19
|
-
this.validate();
|
20
|
-
}
|
21
|
-
validate() {
|
22
|
-
this.validateClientConfig(this.config);
|
23
|
-
}
|
24
|
-
validateClientConfig(config) {
|
25
|
-
const requiredFields = [
|
26
|
-
"apiHostname",
|
27
|
-
"apiPath",
|
28
|
-
"apiPort",
|
29
|
-
"apiProtocol",
|
30
|
-
"apiProvider",
|
31
|
-
"modelName",
|
32
|
-
"path",
|
33
|
-
"public",
|
34
|
-
"serverKey",
|
35
|
-
];
|
36
|
-
for (const field of requiredFields) {
|
37
|
-
if (!(field in config)) {
|
38
|
-
throw new Error(`Missing required field in client configuration: ${field}`);
|
39
|
-
}
|
40
|
-
}
|
41
|
-
if (typeof config.public !== "boolean") {
|
42
|
-
throw new Error('The "public" field in client configuration must be a boolean');
|
43
|
-
}
|
44
|
-
}
|
45
|
-
get(key) {
|
46
|
-
return this.config[key];
|
47
|
-
}
|
48
|
-
isClientConfig() {
|
49
|
-
return this.config.type === "client";
|
50
|
-
}
|
51
|
-
}
|
52
|
-
exports.ConfigManager = ConfigManager;
|
53
|
-
function createConfigManager(configPath) {
|
54
|
-
return new ConfigManager(configPath);
|
55
|
-
}
|
56
|
-
function createConfigManagerClient(configPath) {
|
57
|
-
return new ConfigManager(configPath);
|
58
|
-
}
|
package/dist/config.js
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.ConfigManager = void 0;
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
8
|
-
const js_yaml_1 = __importDefault(require("js-yaml"));
|
9
|
-
class ConfigManager {
|
10
|
-
constructor(configPath) {
|
11
|
-
const configFile = fs_1.default.readFileSync(configPath, "utf8");
|
12
|
-
const config = js_yaml_1.default.load(configFile);
|
13
|
-
this.config = config;
|
14
|
-
this.validate();
|
15
|
-
}
|
16
|
-
getAll() {
|
17
|
-
return this.config;
|
18
|
-
}
|
19
|
-
validate() {
|
20
|
-
const requiredFields = [
|
21
|
-
"apiHostname",
|
22
|
-
"apiPath",
|
23
|
-
"apiPort",
|
24
|
-
"apiProtocol",
|
25
|
-
"apiProvider",
|
26
|
-
"modelName",
|
27
|
-
"path",
|
28
|
-
"public",
|
29
|
-
"serverKey",
|
30
|
-
];
|
31
|
-
for (const field of requiredFields) {
|
32
|
-
if (!(field in this.config)) {
|
33
|
-
throw new Error(`Missing required field in client configuration: ${field}`);
|
34
|
-
}
|
35
|
-
}
|
36
|
-
if (typeof this.config.public !== "boolean") {
|
37
|
-
throw new Error('The "public" field in client configuration must be a boolean');
|
38
|
-
}
|
39
|
-
}
|
40
|
-
get(key) {
|
41
|
-
return this.config[key];
|
42
|
-
}
|
43
|
-
}
|
44
|
-
exports.ConfigManager = ConfigManager;
|
package/dist/constants.js
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.apiProviders = exports.serverMessageKeys = exports.PROVIDER_HELLO_TIMEOUT = exports.NORMALIZE_REGEX = void 0;
|
4
|
-
exports.NORMALIZE_REGEX = /\s*\r?\n|\r/g;
|
5
|
-
exports.PROVIDER_HELLO_TIMEOUT = 15000;
|
6
|
-
exports.serverMessageKeys = {
|
7
|
-
challenge: "challenge",
|
8
|
-
conectionSize: "conectionSize",
|
9
|
-
heartbeat: "heartbeat",
|
10
|
-
inference: "inference",
|
11
|
-
inferenceEnded: "inferenceEnded",
|
12
|
-
join: "join",
|
13
|
-
joinAck: "joinAck",
|
14
|
-
leave: "leave",
|
15
|
-
newConversation: "newConversation",
|
16
|
-
ping: "ping",
|
17
|
-
pong: "pong",
|
18
|
-
providerDetails: "providerDetails",
|
19
|
-
reportCompletion: "reportCompletion",
|
20
|
-
requestProvider: "requestProvider",
|
21
|
-
sessionValid: "sessionValid",
|
22
|
-
verifySession: "verifySession",
|
23
|
-
};
|
24
|
-
exports.apiProviders = {
|
25
|
-
LiteLLM: 'litellm',
|
26
|
-
LlamaCpp: 'llamacpp',
|
27
|
-
LMStudio: 'lmstudio',
|
28
|
-
Ollama: 'ollama',
|
29
|
-
Oobabooga: 'oobabooga',
|
30
|
-
OpenWebUI: 'openwebui',
|
31
|
-
};
|
package/dist/database.js
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.database = void 0;
|
7
|
-
const path_1 = __importDefault(require("path"));
|
8
|
-
const sqlite3_1 = __importDefault(require("sqlite3"));
|
9
|
-
exports.database = new sqlite3_1.default.Database(path_1.default.join(__dirname, "../sqlite.db"));
|
package/dist/logger.js
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.logger = exports.Logger = exports.LogLevel = void 0;
|
7
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
8
|
-
const chalk_1 = __importDefault(require("chalk"));
|
9
|
-
var LogLevel;
|
10
|
-
(function (LogLevel) {
|
11
|
-
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
12
|
-
LogLevel[LogLevel["ERROR"] = 1] = "ERROR";
|
13
|
-
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
14
|
-
LogLevel[LogLevel["WARNING"] = 3] = "WARNING";
|
15
|
-
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
16
|
-
class Logger {
|
17
|
-
constructor() {
|
18
|
-
this.logLevel = LogLevel.INFO;
|
19
|
-
}
|
20
|
-
static getInstance() {
|
21
|
-
if (!Logger.instance) {
|
22
|
-
Logger.instance = new Logger();
|
23
|
-
}
|
24
|
-
return Logger.instance;
|
25
|
-
}
|
26
|
-
setLogLevel(level) {
|
27
|
-
this.logLevel = level;
|
28
|
-
}
|
29
|
-
info(message, ...args) {
|
30
|
-
if (this.logLevel <= LogLevel.INFO) {
|
31
|
-
console.log(chalk_1.default.blue("ℹ️ INFO:"), message, ...args);
|
32
|
-
}
|
33
|
-
}
|
34
|
-
warning(message, ...args) {
|
35
|
-
console.log(chalk_1.default.yellow("⚠️ WARNING:"), message, ...args);
|
36
|
-
}
|
37
|
-
error(message, ...args) {
|
38
|
-
console.error(chalk_1.default.red("❌ ERROR:"), message, ...args);
|
39
|
-
}
|
40
|
-
debug(message, ...args) {
|
41
|
-
console.log(chalk_1.default.gray("🐛 DEBUG:"), message, ...args);
|
42
|
-
}
|
43
|
-
}
|
44
|
-
exports.Logger = Logger;
|
45
|
-
exports.logger = Logger.getInstance();
|