xiaozhou-chat 1.0.0
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/README.md +28 -0
- package/bin/cli.js +149 -0
- package/package.json +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# my-newapi-chat
|
|
2
|
+
|
|
3
|
+
CLI chatbot based on NewAPI.
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
npm i -g my-newapi-chat
|
|
7
|
+
|
|
8
|
+
## 配置
|
|
9
|
+
export NEWAPI_API_KEY="你的Key"
|
|
10
|
+
|
|
11
|
+
可选:
|
|
12
|
+
export NEWAPI_BASE_URL="https://api.newapi.pro/v1"
|
|
13
|
+
export NEWAPI_MODEL="gpt-3.5-turbo"
|
|
14
|
+
|
|
15
|
+
## 使用
|
|
16
|
+
newapi-chat
|
|
17
|
+
|
|
18
|
+
## CLI 参数
|
|
19
|
+
newapi-chat --model gpt-4 --base-url https://api.newapi.pro/v1
|
|
20
|
+
|
|
21
|
+
## 历史记录
|
|
22
|
+
默认保存在:
|
|
23
|
+
~/.newapi-chat-history.json
|
|
24
|
+
|
|
25
|
+
## Windows 打包
|
|
26
|
+
npm i -g pkg
|
|
27
|
+
npm run build:win
|
|
28
|
+
dist/newapi-chat.exe
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import readline from "node:readline";
|
|
6
|
+
import minimist from "minimist";
|
|
7
|
+
|
|
8
|
+
const args = minimist(process.argv.slice(2));
|
|
9
|
+
|
|
10
|
+
const configFile = path.join(os.homedir(), ".newapi-chat-config.json");
|
|
11
|
+
const historyFile = path.join(os.homedir(), ".newapi-chat-history.json");
|
|
12
|
+
|
|
13
|
+
function initConfigFile() {
|
|
14
|
+
if (fs.existsSync(configFile)) return;
|
|
15
|
+
|
|
16
|
+
const defaultConfig = {
|
|
17
|
+
apiKey: "",
|
|
18
|
+
baseUrl: "https://api.newapi.pro/v1",
|
|
19
|
+
model: "gpt-3.5-turbo"
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
fs.writeFileSync(configFile, JSON.stringify(defaultConfig, null, 2), "utf-8");
|
|
23
|
+
console.log(`✅ 已创建配置文件: ${configFile}`);
|
|
24
|
+
console.log("👉 请编辑该文件填入 apiKey");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function loadConfig() {
|
|
28
|
+
if (!fs.existsSync(configFile)) return {};
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(fs.readFileSync(configFile, "utf-8"));
|
|
31
|
+
} catch {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function loadHistory() {
|
|
37
|
+
if (!fs.existsSync(historyFile)) return [];
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(fs.readFileSync(historyFile, "utf-8"));
|
|
40
|
+
} catch {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function saveHistory(messages) {
|
|
46
|
+
fs.writeFileSync(historyFile, JSON.stringify(messages, null, 2));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
initConfigFile();
|
|
50
|
+
const config = loadConfig();
|
|
51
|
+
|
|
52
|
+
const API_KEY = config.apiKey || process.env.NEWAPI_API_KEY;
|
|
53
|
+
const BASE_URL =
|
|
54
|
+
config.baseUrl ||
|
|
55
|
+
args["base-url"] ||
|
|
56
|
+
process.env.NEWAPI_BASE_URL ||
|
|
57
|
+
"https://api.newapi.pro/v1";
|
|
58
|
+
const MODEL =
|
|
59
|
+
config.model ||
|
|
60
|
+
args["model"] ||
|
|
61
|
+
process.env.NEWAPI_MODEL ||
|
|
62
|
+
"gpt-3.5-turbo";
|
|
63
|
+
|
|
64
|
+
if (!API_KEY) {
|
|
65
|
+
console.error("❌ 请在 ~/.newapi-chat-config.json 或环境变量中配置 NEWAPI_API_KEY");
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let messages = loadHistory();
|
|
70
|
+
|
|
71
|
+
const rl = readline.createInterface({
|
|
72
|
+
input: process.stdin,
|
|
73
|
+
output: process.stdout,
|
|
74
|
+
prompt: "你> "
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
console.log("✅ NewAPI Chat CLI 已启动,输入 exit 退出");
|
|
78
|
+
|
|
79
|
+
async function chatStream(userInput) {
|
|
80
|
+
messages.push({ role: "user", content: userInput });
|
|
81
|
+
|
|
82
|
+
const res = await fetch(`${BASE_URL}/chat/completions`, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: {
|
|
85
|
+
"Content-Type": "application/json",
|
|
86
|
+
Authorization: `Bearer ${API_KEY}`
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
model: MODEL,
|
|
90
|
+
messages,
|
|
91
|
+
stream: true
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (!res.ok) {
|
|
96
|
+
const text = await res.text();
|
|
97
|
+
throw new Error(`API 错误: ${res.status} ${text}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const reader = res.body.getReader();
|
|
101
|
+
const decoder = new TextDecoder("utf-8");
|
|
102
|
+
let reply = "";
|
|
103
|
+
|
|
104
|
+
while (true) {
|
|
105
|
+
const { done, value } = await reader.read();
|
|
106
|
+
if (done) break;
|
|
107
|
+
|
|
108
|
+
const chunk = decoder.decode(value);
|
|
109
|
+
const lines = chunk.split("\n").filter(Boolean);
|
|
110
|
+
|
|
111
|
+
for (const line of lines) {
|
|
112
|
+
if (!line.startsWith("data:")) continue;
|
|
113
|
+
const data = line.replace("data: ", "").trim();
|
|
114
|
+
if (data === "[DONE]") break;
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const json = JSON.parse(data);
|
|
118
|
+
const token = json.choices?.[0]?.delta?.content;
|
|
119
|
+
if (token) {
|
|
120
|
+
process.stdout.write(token);
|
|
121
|
+
reply += token;
|
|
122
|
+
}
|
|
123
|
+
} catch {}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
process.stdout.write("\n");
|
|
128
|
+
messages.push({ role: "assistant", content: reply });
|
|
129
|
+
saveHistory(messages);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
rl.prompt();
|
|
133
|
+
|
|
134
|
+
rl.on("line", async (line) => {
|
|
135
|
+
const input = line.trim();
|
|
136
|
+
if (!input) return rl.prompt();
|
|
137
|
+
if (input === "exit" || input === "quit") {
|
|
138
|
+
rl.close();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
await chatStream(input);
|
|
144
|
+
} catch (e) {
|
|
145
|
+
console.error("❌", e.message);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
rl.prompt();
|
|
149
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xiaozhou-chat",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI chatbot based on NewAPI",
|
|
5
|
+
"bin": {
|
|
6
|
+
"xiaozhou-chat": "bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build:win": "pkg . --targets node18-win-x64 --output dist/newapi-chat.exe"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"minimist": "^1.2.8"
|
|
17
|
+
},
|
|
18
|
+
"pkg": {
|
|
19
|
+
"assets": []
|
|
20
|
+
}
|
|
21
|
+
}
|