:gem: [Feature] Place endpoints in local secrets
Browse files- .gitignore +2 -1
- server.js +16 -0
- storages/endpoint_storage.js +32 -4
.gitignore
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
node_modules
|
2 |
package-lock.json
|
3 |
.vscode
|
4 |
-
live.js
|
|
|
|
1 |
node_modules
|
2 |
package-lock.json
|
3 |
.vscode
|
4 |
+
live.js
|
5 |
+
secrets.json
|
server.js
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
const express = require("express");
|
2 |
const axios = require("axios");
|
3 |
const bodyParser = require("body-parser");
|
@@ -12,6 +13,21 @@ app.get("/", (req, res) => {
|
|
12 |
res.sendFile(path.join(__dirname + "/index.html"));
|
13 |
});
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
app.post("/chat/completions", async (req, res) => {
|
16 |
try {
|
17 |
const {
|
|
|
1 |
+
const fs = require("fs").promises;
|
2 |
const express = require("express");
|
3 |
const axios = require("axios");
|
4 |
const bodyParser = require("body-parser");
|
|
|
13 |
res.sendFile(path.join(__dirname + "/index.html"));
|
14 |
});
|
15 |
|
16 |
+
app.get("/endpoints", async (req, res) => {
|
17 |
+
try {
|
18 |
+
let secrets_path = path.join(__dirname, "secrets.json");
|
19 |
+
const data = await fs.readFile(secrets_path, "utf-8");
|
20 |
+
const secrets = JSON.parse(data);
|
21 |
+
const local_points = secrets.endpoints;
|
22 |
+
res.json(local_points);
|
23 |
+
} catch (error) {
|
24 |
+
console.error(error);
|
25 |
+
res.status(500).json({
|
26 |
+
error: "Failed to get local endpoints: Maybe secrets.json not existed?",
|
27 |
+
});
|
28 |
+
}
|
29 |
+
});
|
30 |
+
|
31 |
app.post("/chat/completions", async (req, res) => {
|
32 |
try {
|
33 |
const {
|
storages/endpoint_storage.js
CHANGED
@@ -9,12 +9,13 @@ class EndpointStorage {
|
|
9 |
constructor() {
|
10 |
this.init_database();
|
11 |
this.fill_available_models_select("user-customized");
|
|
|
12 |
this.create_endpoint_and_api_key_items();
|
13 |
}
|
14 |
init_database() {
|
15 |
this.db = new Dexie("endpoints");
|
16 |
this.db.version(1).stores({
|
17 |
-
endpoints: "index, endpoint, api_key",
|
18 |
});
|
19 |
this.db.endpoints.count((count) => {
|
20 |
console.log(`${count} endpoints loaded.`);
|
@@ -24,7 +25,30 @@ class EndpointStorage {
|
|
24 |
this.db.endpoints.clear();
|
25 |
console.log("endpoints cleared.");
|
26 |
}
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
let endpoint_and_api_key_item_html = `
|
29 |
<div class="row mt-2 no-gutters">
|
30 |
<div class="col-auto">
|
@@ -54,7 +78,7 @@ class EndpointStorage {
|
|
54 |
add_endpoint_and_api_key_item() {
|
55 |
let endpoint_and_api_key_items = $("#endpoint-and-api-key-items");
|
56 |
let endpoint_and_api_key_item = $(
|
57 |
-
this.
|
58 |
);
|
59 |
endpoint_and_api_key_items.append(endpoint_and_api_key_item);
|
60 |
this.bind_endpoint_and_api_key_buttons(endpoint_and_api_key_item);
|
@@ -65,8 +89,11 @@ class EndpointStorage {
|
|
65 |
endpoint_and_api_key_items.empty();
|
66 |
|
67 |
endpoints.each((row) => {
|
|
|
|
|
|
|
68 |
let endpoint_and_api_key_item_html =
|
69 |
-
this.
|
70 |
let endpoint_and_api_key_item = $(endpoint_and_api_key_item_html);
|
71 |
let endpoint_input =
|
72 |
endpoint_and_api_key_item.find(".endpoint-input");
|
@@ -104,6 +131,7 @@ class EndpointStorage {
|
|
104 |
index: endpoint_input_value,
|
105 |
endpoint: endpoint_input_value,
|
106 |
api_key: api_key_input_value,
|
|
|
107 |
});
|
108 |
console.log(`new_endpoint: ${endpoint_input_value}`);
|
109 |
}
|
|
|
9 |
constructor() {
|
10 |
this.init_database();
|
11 |
this.fill_available_models_select("user-customized");
|
12 |
+
this.load_local_endpoints();
|
13 |
this.create_endpoint_and_api_key_items();
|
14 |
}
|
15 |
init_database() {
|
16 |
this.db = new Dexie("endpoints");
|
17 |
this.db.version(1).stores({
|
18 |
+
endpoints: "index, endpoint, api_key, need_protect",
|
19 |
});
|
20 |
this.db.endpoints.count((count) => {
|
21 |
console.log(`${count} endpoints loaded.`);
|
|
|
25 |
this.db.endpoints.clear();
|
26 |
console.log("endpoints cleared.");
|
27 |
}
|
28 |
+
async load_local_endpoints() {
|
29 |
+
fetch("/endpoints")
|
30 |
+
.then((response) => response.json())
|
31 |
+
.then((data) => {
|
32 |
+
if (data.error) {
|
33 |
+
console.error(data.error);
|
34 |
+
return;
|
35 |
+
}
|
36 |
+
let count = Object.keys(data).length;
|
37 |
+
console.log(`${count} local endpoints loaded.`);
|
38 |
+
// data is array of endpint items, each item has 4 keys:
|
39 |
+
// - `endpoint`, `api_key`, `api_type`, `need_protect`
|
40 |
+
// add these to db.endpoints
|
41 |
+
data.forEach((endpoint) => {
|
42 |
+
this.db.endpoints.put({
|
43 |
+
index: endpoint.endpoint,
|
44 |
+
endpoint: endpoint.endpoint,
|
45 |
+
api_key: endpoint.api_key,
|
46 |
+
need_protect: endpoint.need_protect || true,
|
47 |
+
});
|
48 |
+
});
|
49 |
+
});
|
50 |
+
}
|
51 |
+
generate_endpoint_and_api_key_item_html() {
|
52 |
let endpoint_and_api_key_item_html = `
|
53 |
<div class="row mt-2 no-gutters">
|
54 |
<div class="col-auto">
|
|
|
78 |
add_endpoint_and_api_key_item() {
|
79 |
let endpoint_and_api_key_items = $("#endpoint-and-api-key-items");
|
80 |
let endpoint_and_api_key_item = $(
|
81 |
+
this.generate_endpoint_and_api_key_item_html()
|
82 |
);
|
83 |
endpoint_and_api_key_items.append(endpoint_and_api_key_item);
|
84 |
this.bind_endpoint_and_api_key_buttons(endpoint_and_api_key_item);
|
|
|
89 |
endpoint_and_api_key_items.empty();
|
90 |
|
91 |
endpoints.each((row) => {
|
92 |
+
if (row.need_protect) {
|
93 |
+
return;
|
94 |
+
}
|
95 |
let endpoint_and_api_key_item_html =
|
96 |
+
this.generate_endpoint_and_api_key_item_html();
|
97 |
let endpoint_and_api_key_item = $(endpoint_and_api_key_item_html);
|
98 |
let endpoint_input =
|
99 |
endpoint_and_api_key_item.find(".endpoint-input");
|
|
|
131 |
index: endpoint_input_value,
|
132 |
endpoint: endpoint_input_value,
|
133 |
api_key: api_key_input_value,
|
134 |
+
need_protect: false,
|
135 |
});
|
136 |
console.log(`new_endpoint: ${endpoint_input_value}`);
|
137 |
}
|