symmetry-cli 1.0.7 → 1.0.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,127 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.SessionRepository = void 0;
|
4
|
-
const database_1 = require("./database");
|
5
|
-
class SessionRepository {
|
6
|
-
constructor() {
|
7
|
-
this.create = (session) => {
|
8
|
-
return new Promise((resolve, reject) => {
|
9
|
-
const sql = `INSERT INTO sessions (id, provider_id, created_at, expires_at) VALUES (?, ?, ?, ?)`;
|
10
|
-
this.db.run(sql, [
|
11
|
-
session.id,
|
12
|
-
session.providerId,
|
13
|
-
session.createdAt.toISOString(),
|
14
|
-
session.expiresAt.toISOString(),
|
15
|
-
], function (err) {
|
16
|
-
if (err) {
|
17
|
-
reject(err);
|
18
|
-
}
|
19
|
-
else {
|
20
|
-
resolve();
|
21
|
-
}
|
22
|
-
});
|
23
|
-
});
|
24
|
-
};
|
25
|
-
this.get = (id) => {
|
26
|
-
return new Promise((resolve, reject) => {
|
27
|
-
const sql = `
|
28
|
-
SELECT s.id, s.provider_id as providerId, s.created_at as createdAt, s.expires_at as expiresAt
|
29
|
-
FROM sessions s
|
30
|
-
WHERE s.id = ?
|
31
|
-
`;
|
32
|
-
this.db.get(sql, [id], (err, row) => {
|
33
|
-
if (err) {
|
34
|
-
reject(err);
|
35
|
-
}
|
36
|
-
else if (row) {
|
37
|
-
resolve({
|
38
|
-
id: row.id,
|
39
|
-
providerId: row.providerId,
|
40
|
-
createdAt: new Date(row.createdAt),
|
41
|
-
expiresAt: new Date(row.expiresAt),
|
42
|
-
});
|
43
|
-
}
|
44
|
-
else {
|
45
|
-
resolve(null);
|
46
|
-
}
|
47
|
-
});
|
48
|
-
});
|
49
|
-
};
|
50
|
-
this.update = (session) => {
|
51
|
-
return new Promise((resolve, reject) => {
|
52
|
-
const sql = `UPDATE sessions SET provider_id = ?, created_at = ?, expires_at = ? WHERE id = ?`;
|
53
|
-
this.db.run(sql, [
|
54
|
-
session.providerId,
|
55
|
-
session.createdAt.toISOString(),
|
56
|
-
session.expiresAt.toISOString(),
|
57
|
-
session.id,
|
58
|
-
], function (err) {
|
59
|
-
if (err) {
|
60
|
-
reject(err);
|
61
|
-
}
|
62
|
-
else if (this.changes === 0) {
|
63
|
-
reject(new Error("No session found with the provided id"));
|
64
|
-
}
|
65
|
-
else {
|
66
|
-
resolve();
|
67
|
-
}
|
68
|
-
});
|
69
|
-
});
|
70
|
-
};
|
71
|
-
this.delete = (id) => {
|
72
|
-
return new Promise((resolve, reject) => {
|
73
|
-
const sql = `DELETE FROM sessions WHERE id = ?`;
|
74
|
-
this.db.run(sql, [id], function (err) {
|
75
|
-
if (err) {
|
76
|
-
reject(err);
|
77
|
-
}
|
78
|
-
else {
|
79
|
-
resolve(this.changes > 0);
|
80
|
-
}
|
81
|
-
});
|
82
|
-
});
|
83
|
-
};
|
84
|
-
this.getAllActiveSessions = () => {
|
85
|
-
return new Promise((resolve, reject) => {
|
86
|
-
const sql = `
|
87
|
-
SELECT s.id, s.provider_id as providerId, s.created_at as createdAt, s.expires_at as expiresAt,
|
88
|
-
p.key as peer_key, p.discovery_key, p.model_name
|
89
|
-
FROM sessions s
|
90
|
-
LEFT JOIN peers p ON s.provider_id = p.id
|
91
|
-
WHERE s.expires_at > datetime('now')
|
92
|
-
`;
|
93
|
-
this.db.all(sql, [], (err, rows) => {
|
94
|
-
if (err) {
|
95
|
-
reject(err);
|
96
|
-
}
|
97
|
-
else {
|
98
|
-
resolve(rows.map((row) => ({
|
99
|
-
id: row.id,
|
100
|
-
providerId: row.providerId,
|
101
|
-
createdAt: new Date(row.createdAt),
|
102
|
-
expiresAt: new Date(row.expiresAt),
|
103
|
-
peer_key: row.peer_key,
|
104
|
-
discovery_key: row.discovery_key,
|
105
|
-
model_name: row.model_name,
|
106
|
-
})));
|
107
|
-
}
|
108
|
-
});
|
109
|
-
});
|
110
|
-
};
|
111
|
-
this.deleteExpired = () => {
|
112
|
-
return new Promise((resolve, reject) => {
|
113
|
-
const sql = `DELETE FROM sessions WHERE expires_at <= datetime('now')`;
|
114
|
-
this.db.run(sql, function (err) {
|
115
|
-
if (err) {
|
116
|
-
reject(err);
|
117
|
-
}
|
118
|
-
else {
|
119
|
-
resolve(this.changes);
|
120
|
-
}
|
121
|
-
});
|
122
|
-
});
|
123
|
-
};
|
124
|
-
this.db = database_1.database;
|
125
|
-
}
|
126
|
-
}
|
127
|
-
exports.SessionRepository = SessionRepository;
|
package/dist/types.js
DELETED
package/dist/utils.js
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.getChatDataFromProvider = void 0;
|
4
|
-
exports.safeParseJson = safeParseJson;
|
5
|
-
exports.createMessage = createMessage;
|
6
|
-
exports.isStreamWithDataPrefix = isStreamWithDataPrefix;
|
7
|
-
exports.safeParseStreamResponse = safeParseStreamResponse;
|
8
|
-
const constants_1 = require("./constants");
|
9
|
-
function safeParseJson(data) {
|
10
|
-
try {
|
11
|
-
return JSON.parse(data);
|
12
|
-
}
|
13
|
-
catch (e) {
|
14
|
-
return undefined;
|
15
|
-
}
|
16
|
-
}
|
17
|
-
function createMessage(key, data) {
|
18
|
-
return JSON.stringify({ key, data });
|
19
|
-
}
|
20
|
-
function isStreamWithDataPrefix(stringBuffer) {
|
21
|
-
return stringBuffer.startsWith('data:');
|
22
|
-
}
|
23
|
-
function safeParseStreamResponse(stringBuffer) {
|
24
|
-
try {
|
25
|
-
if (isStreamWithDataPrefix(stringBuffer)) {
|
26
|
-
return JSON.parse(stringBuffer.split('data:')[1]);
|
27
|
-
}
|
28
|
-
return JSON.parse(stringBuffer);
|
29
|
-
}
|
30
|
-
catch (e) {
|
31
|
-
return undefined;
|
32
|
-
}
|
33
|
-
}
|
34
|
-
const getChatDataFromProvider = (provider, data) => {
|
35
|
-
var _a, _b;
|
36
|
-
switch (provider) {
|
37
|
-
case constants_1.apiProviders.Ollama:
|
38
|
-
case constants_1.apiProviders.OpenWebUI:
|
39
|
-
return ((_a = data === null || data === void 0 ? void 0 : data.choices[0].delta) === null || _a === void 0 ? void 0 : _a.content)
|
40
|
-
? data === null || data === void 0 ? void 0 : data.choices[0].delta.content
|
41
|
-
: '';
|
42
|
-
case constants_1.apiProviders.LlamaCpp:
|
43
|
-
return data === null || data === void 0 ? void 0 : data.content;
|
44
|
-
case constants_1.apiProviders.LiteLLM:
|
45
|
-
default:
|
46
|
-
if ((data === null || data === void 0 ? void 0 : data.choices[0].delta.content) === 'undefined')
|
47
|
-
return '';
|
48
|
-
return ((_b = data === null || data === void 0 ? void 0 : data.choices[0].delta) === null || _b === void 0 ? void 0 : _b.content)
|
49
|
-
? data === null || data === void 0 ? void 0 : data.choices[0].delta.content
|
50
|
-
: '';
|
51
|
-
}
|
52
|
-
};
|
53
|
-
exports.getChatDataFromProvider = getChatDataFromProvider;
|
package/dist/websocket-server.js
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.WsServer = void 0;
|
4
|
-
const http_1 = require("http");
|
5
|
-
const ws_1 = require("ws");
|
6
|
-
class WsServer {
|
7
|
-
constructor(port, peerRepository, swarm) {
|
8
|
-
this.wssListeners = () => {
|
9
|
-
var _a;
|
10
|
-
(_a = this._wss) === null || _a === void 0 ? void 0 : _a.on("connection", (ws) => {
|
11
|
-
this.sendStats(ws);
|
12
|
-
const interval = setInterval(() => this.sendStats(ws), 5000);
|
13
|
-
ws.on("close", () => {
|
14
|
-
clearInterval(interval);
|
15
|
-
});
|
16
|
-
});
|
17
|
-
};
|
18
|
-
this._peerRepository = peerRepository;
|
19
|
-
this._swarm = swarm;
|
20
|
-
this.start(port);
|
21
|
-
}
|
22
|
-
start(port) {
|
23
|
-
const server = (0, http_1.createServer)();
|
24
|
-
this._wss = new ws_1.WebSocketServer({ server });
|
25
|
-
server.listen(port);
|
26
|
-
this.wssListeners();
|
27
|
-
}
|
28
|
-
async sendStats(ws) {
|
29
|
-
const stats = await this.getStats(this._swarm);
|
30
|
-
ws.send(JSON.stringify(stats));
|
31
|
-
}
|
32
|
-
async broadcastStats() {
|
33
|
-
var _a;
|
34
|
-
const stats = await this.getStats(this._swarm);
|
35
|
-
(_a = this._wss) === null || _a === void 0 ? void 0 : _a.clients.forEach((client) => {
|
36
|
-
if (client.readyState === ws_1.WebSocket.OPEN) {
|
37
|
-
client.send(JSON.stringify(stats));
|
38
|
-
}
|
39
|
-
});
|
40
|
-
}
|
41
|
-
async getStats(swarm) {
|
42
|
-
const activePeers = await this._peerRepository.getActivePeerCount();
|
43
|
-
const activeModels = await this._peerRepository.getActiveModelCount();
|
44
|
-
const swarmConnections = swarm.connections.size;
|
45
|
-
return {
|
46
|
-
activePeers,
|
47
|
-
activeModels,
|
48
|
-
swarmConnections,
|
49
|
-
};
|
50
|
-
}
|
51
|
-
}
|
52
|
-
exports.WsServer = WsServer;
|
package/src/config.ts
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
import { ProviderConfig } from "./types";
|
2
|
-
import fs from "fs";
|
3
|
-
import yaml from "js-yaml";
|
4
|
-
|
5
|
-
export class ConfigManager {
|
6
|
-
private config: ProviderConfig;
|
7
|
-
|
8
|
-
constructor(configPath: string) {
|
9
|
-
const configFile = fs.readFileSync(configPath, "utf8");
|
10
|
-
const config = yaml.load(configFile) as ProviderConfig;
|
11
|
-
this.config = config
|
12
|
-
this.validate();
|
13
|
-
}
|
14
|
-
|
15
|
-
public getAll () {
|
16
|
-
return this.config;
|
17
|
-
}
|
18
|
-
|
19
|
-
private validate(): void {
|
20
|
-
const requiredFields: (keyof ProviderConfig)[] = [
|
21
|
-
"apiHostname",
|
22
|
-
"apiPath",
|
23
|
-
"apiPort",
|
24
|
-
"apiProtocol",
|
25
|
-
"apiProvider",
|
26
|
-
"modelName",
|
27
|
-
"path",
|
28
|
-
"public",
|
29
|
-
"serverKey",
|
30
|
-
];
|
31
|
-
|
32
|
-
for (const field of requiredFields) {
|
33
|
-
if (!(field in this.config)) {
|
34
|
-
throw new Error(
|
35
|
-
`Missing required field in client configuration: ${field}`
|
36
|
-
);
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
if (typeof this.config.public !== "boolean") {
|
41
|
-
throw new Error(
|
42
|
-
'The "public" field in client configuration must be a boolean'
|
43
|
-
);
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
get<K extends keyof ProviderConfig>(key: K): ProviderConfig[K];
|
48
|
-
get(key: string): unknown {
|
49
|
-
return this.config[key as keyof ProviderConfig];
|
50
|
-
}
|
51
|
-
}
|
package/src/constants.ts
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
export const NORMALIZE_REGEX = /\s*\r?\n|\r/g;
|
2
|
-
|
3
|
-
export const PROVIDER_HELLO_TIMEOUT = 30000
|
4
|
-
|
5
|
-
export const serverMessageKeys = {
|
6
|
-
challenge: "challenge",
|
7
|
-
conectionSize: "conectionSize",
|
8
|
-
heartbeat: "heartbeat",
|
9
|
-
inference: "inference",
|
10
|
-
inferenceEnded: "inferenceEnded",
|
11
|
-
join: "join",
|
12
|
-
joinAck: "joinAck",
|
13
|
-
leave: "leave",
|
14
|
-
newConversation: "newConversation",
|
15
|
-
ping: "ping",
|
16
|
-
pong: "pong",
|
17
|
-
providerDetails: "providerDetails",
|
18
|
-
reportCompletion: "reportCompletion",
|
19
|
-
requestProvider: "requestProvider",
|
20
|
-
sessionValid: "sessionValid",
|
21
|
-
verifySession: "verifySession",
|
22
|
-
} as const;
|
23
|
-
|
24
|
-
export const apiProviders = {
|
25
|
-
LiteLLM: 'litellm',
|
26
|
-
LlamaCpp: 'llamacpp',
|
27
|
-
LMStudio: 'lmstudio',
|
28
|
-
Ollama: 'ollama',
|
29
|
-
Oobabooga: 'oobabooga',
|
30
|
-
OpenWebUI: 'openwebui',
|
31
|
-
} as const
|
package/src/logger.ts
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
2
|
-
import chalk from "chalk";
|
3
|
-
|
4
|
-
export enum LogLevel {
|
5
|
-
DEBUG,
|
6
|
-
ERROR,
|
7
|
-
INFO,
|
8
|
-
WARNING,
|
9
|
-
}
|
10
|
-
|
11
|
-
export class Logger {
|
12
|
-
private static instance: Logger;
|
13
|
-
private logLevel: LogLevel = LogLevel.INFO;
|
14
|
-
|
15
|
-
private constructor() {}
|
16
|
-
|
17
|
-
public static getInstance(): Logger {
|
18
|
-
if (!Logger.instance) {
|
19
|
-
Logger.instance = new Logger();
|
20
|
-
}
|
21
|
-
return Logger.instance;
|
22
|
-
}
|
23
|
-
|
24
|
-
public setLogLevel(level: LogLevel): void {
|
25
|
-
this.logLevel = level;
|
26
|
-
}
|
27
|
-
|
28
|
-
public info(message: string, ...args: any[]): void {
|
29
|
-
if (this.logLevel <= LogLevel.INFO) {
|
30
|
-
console.log(chalk.blue("ℹ️ INFO:"), message, ...args);
|
31
|
-
}
|
32
|
-
}
|
33
|
-
|
34
|
-
public warning(message: string, ...args: any[]): void {
|
35
|
-
console.log(chalk.yellow("⚠️ WARNING:"), message, ...args);
|
36
|
-
}
|
37
|
-
|
38
|
-
public error(message: string, ...args: any[]): void {
|
39
|
-
console.error(chalk.red("❌ ERROR:"), message, ...args);
|
40
|
-
}
|
41
|
-
|
42
|
-
public debug(message: string, ...args: any[]): void {
|
43
|
-
console.log(chalk.gray("🐛 DEBUG:"), message, ...args);
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
export const logger = Logger.getInstance();
|