botworker 1.0.0 → 1.0.1
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 +24 -20
- package/bin/botworker.mjs +113 -53
- package/lib/api.js +85 -37
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# BotWorker CLI
|
|
2
2
|
|
|
3
|
-
שוחח עם הבוטים שלך מ-[BotWorker](https://botworker.dev) ישירות
|
|
3
|
+
שוחח עם הבוטים שלך מ-[BotWorker](https://botworker.dev) ישירות מהטרמינל — מכל מקום.
|
|
4
|
+
|
|
5
|
+
חבילת npm רשמית: https://www.npmjs.com/package/botworker
|
|
4
6
|
|
|
5
7
|
## התקנה
|
|
6
8
|
|
|
@@ -8,52 +10,54 @@
|
|
|
8
10
|
npm install -g botworker
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
## הרצה מהירה
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
|
-
|
|
16
|
+
botworker config --email you@example.com # שולח קוד בן 6 תווים לאימייל
|
|
17
|
+
botworker login # הזן את הקוד מהמייל
|
|
18
|
+
botworker chat "שלום"
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
## התחברות
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
התחברות עם אימייל רשום בחשבון BotWorker. נשלח קוד בן 6 תווים לאימייל:
|
|
20
24
|
|
|
21
25
|
```bash
|
|
22
|
-
botworker config --
|
|
23
|
-
botworker
|
|
24
|
-
botworker login # הזן את הקוד מהמייל
|
|
26
|
+
botworker config --email you@example.com # שולח קוד 6 תווים
|
|
27
|
+
botworker login # הזן את הקוד
|
|
25
28
|
```
|
|
26
29
|
|
|
27
|
-
לחלופין, התחברות ידנית עם API key
|
|
30
|
+
לחלופין, התחברות ידנית עם API key מעמוד "השימושים שלי" בדשבורד:
|
|
28
31
|
|
|
29
32
|
```bash
|
|
30
33
|
botworker config --api-key bw_live_xxxxxxxx
|
|
31
34
|
```
|
|
32
35
|
|
|
33
|
-
##
|
|
36
|
+
## פקודות
|
|
34
37
|
|
|
35
38
|
```bash
|
|
36
39
|
botworker bots # רשימת הבוטים שלך
|
|
37
40
|
botworker use <BOT_ID> # בחירת הבוט הפעיל
|
|
38
41
|
botworker chat "מה השעות שלכם?" # שליחת הודעה אחת
|
|
42
|
+
botworker chat "..." --json # פלט JSON מלא (תשובה + שימוש + קרדיטים)
|
|
39
43
|
botworker # מצב שיחה אינטראקטיבי
|
|
40
|
-
botworker
|
|
41
|
-
botworker
|
|
44
|
+
botworker balance # יתרת הקרדיטים שלך
|
|
45
|
+
botworker usage # שימוש אחרון
|
|
46
|
+
botworker whoami # פרטי החשבון
|
|
47
|
+
botworker logout # ניתוק
|
|
48
|
+
botworker version # גרסת ה-CLI
|
|
42
49
|
```
|
|
43
50
|
|
|
44
51
|
## חיוב (Pay Per Use)
|
|
45
52
|
|
|
46
|
-
כל בקשה צורכת קרדיטים
|
|
47
|
-
ניתן להגדיל את
|
|
48
|
-
|
|
49
|
-
## משתני סביבה
|
|
50
|
-
|
|
51
|
-
- `BOTWORKER_API_BASE` — לשינוי כתובת ה-API (ברירת מחדל: שרת BotWorker).
|
|
53
|
+
כל בקשה צורכת קרדיטים לפי שימוש אמיתי: **1 קרדיט = 1,000 טוקנים** (קלט + פלט).
|
|
54
|
+
כשנגמרים הקרדיטים תוחזר שגיאה `402` — ניתן להגדיל את היתרה ברכישת חבילת קרדיטים בדשבורד.
|
|
52
55
|
|
|
53
|
-
## הגדרות
|
|
56
|
+
## משתני סביבה / הגדרות
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
- `BOTWORKER_API_BASE` — לשינוי כתובת ה-API (או `botworker config --api-base <url>`).
|
|
59
|
+
- ההגדרות נשמרות מקומית ב-`~/.botworker/config.json` (הרשאות `600`).
|
|
56
60
|
|
|
57
61
|
## רישיון
|
|
58
62
|
|
|
59
|
-
MIT
|
|
63
|
+
MIT
|
package/bin/botworker.mjs
CHANGED
|
@@ -2,23 +2,22 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* BotWorker CLI
|
|
4
4
|
* --------------
|
|
5
|
-
* Talk to your BotWorker bots from the terminal.
|
|
5
|
+
* Talk to your BotWorker bots from the terminal — anywhere, no global install required.
|
|
6
6
|
*
|
|
7
7
|
* Quick start:
|
|
8
|
-
*
|
|
9
|
-
* botworker
|
|
10
|
-
* botworker
|
|
11
|
-
* botworker
|
|
12
|
-
* botworker
|
|
13
|
-
* botworker
|
|
14
|
-
* botworker chat "שלום, מה אתה יודע לעשות?"
|
|
15
|
-
* botworker # interactive chat
|
|
8
|
+
* npx botworker config --email you@example.com # sends a 6-char code to your email
|
|
9
|
+
* npx botworker login # paste the code from the email
|
|
10
|
+
* npx botworker bots # list your bots
|
|
11
|
+
* npx botworker use <BOT_ID> # pick the active bot
|
|
12
|
+
* npx botworker chat "שלום, מה אתה יודע לעשות?"
|
|
13
|
+
* npx botworker # interactive chat
|
|
16
14
|
*/
|
|
17
15
|
import readline from "node:readline";
|
|
18
16
|
import { loadConfig, saveConfig, clearConfig, CONFIG_FILE } from "../lib/config.js";
|
|
19
|
-
import { requestCode, verifyCode, listBots, chat } from "../lib/api.js";
|
|
17
|
+
import { requestCode, verifyCode, listBots, chat, account } from "../lib/api.js";
|
|
20
18
|
|
|
21
|
-
const
|
|
19
|
+
const EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
|
|
20
|
+
const VERSION = "1.0.0";
|
|
22
21
|
|
|
23
22
|
function ask(prompt, { hidden = false } = {}) {
|
|
24
23
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -41,21 +40,21 @@ function ask(prompt, { hidden = false } = {}) {
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
function parseFlags(args) {
|
|
44
|
-
const out = {};
|
|
43
|
+
const out = { _: [] };
|
|
45
44
|
for (let i = 0; i < args.length; i++) {
|
|
46
45
|
const a = args[i];
|
|
47
46
|
if (a.startsWith("--")) {
|
|
48
47
|
const key = a.slice(2);
|
|
49
48
|
const val = args[i + 1] && !args[i + 1].startsWith("--") ? args[++i] : true;
|
|
50
49
|
out[key] = val;
|
|
51
|
-
}
|
|
50
|
+
} else out._.push(a);
|
|
52
51
|
}
|
|
53
52
|
return out;
|
|
54
53
|
}
|
|
55
54
|
|
|
56
55
|
function requireAuth(cfg) {
|
|
57
56
|
if (!cfg.token) {
|
|
58
|
-
console.error("❌ אינך מחובר. הרץ: botworker config --email you@
|
|
57
|
+
console.error("❌ אינך מחובר. הרץ: botworker config --email you@example.com ואז botworker login");
|
|
59
58
|
process.exit(1);
|
|
60
59
|
}
|
|
61
60
|
}
|
|
@@ -63,6 +62,7 @@ function requireAuth(cfg) {
|
|
|
63
62
|
async function cmdConfig(cfg, rest) {
|
|
64
63
|
const flags = parseFlags(rest);
|
|
65
64
|
if (flags.name) cfg.name = String(flags.name);
|
|
65
|
+
if (flags["api-base"]) cfg.apiBase = String(flags["api-base"]);
|
|
66
66
|
if (flags["api-key"]) {
|
|
67
67
|
cfg.token = String(flags["api-key"]);
|
|
68
68
|
saveConfig(cfg);
|
|
@@ -71,8 +71,8 @@ async function cmdConfig(cfg, rest) {
|
|
|
71
71
|
}
|
|
72
72
|
if (flags.email) {
|
|
73
73
|
const email = String(flags.email);
|
|
74
|
-
if (!
|
|
75
|
-
console.error("❌
|
|
74
|
+
if (!EMAIL_RE.test(email)) {
|
|
75
|
+
console.error("❌ כתובת אימייל לא תקינה");
|
|
76
76
|
process.exit(1);
|
|
77
77
|
}
|
|
78
78
|
cfg.email = email;
|
|
@@ -83,7 +83,7 @@ async function cmdConfig(cfg, rest) {
|
|
|
83
83
|
console.error("❌", (data && data.error) || "שליחת הקוד נכשלה");
|
|
84
84
|
process.exit(1);
|
|
85
85
|
}
|
|
86
|
-
console.log("✅ הקוד נשלח. הרץ עכשיו: botworker login");
|
|
86
|
+
console.log("✅ אם החשבון קיים, הקוד נשלח. הרץ עכשיו: botworker login");
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
saveConfig(cfg);
|
|
@@ -93,7 +93,7 @@ async function cmdConfig(cfg, rest) {
|
|
|
93
93
|
|
|
94
94
|
async function cmdLogin(cfg) {
|
|
95
95
|
if (!cfg.email) {
|
|
96
|
-
console.error("❌ הגדר קודם אימייל: botworker config --email you@
|
|
96
|
+
console.error("❌ הגדר קודם אימייל: botworker config --email you@example.com");
|
|
97
97
|
process.exit(1);
|
|
98
98
|
}
|
|
99
99
|
const code = (await ask("🔑 הזן את הקוד בן 6 התווים מהמייל: ")).trim();
|
|
@@ -120,12 +120,12 @@ async function cmdBots(cfg) {
|
|
|
120
120
|
}
|
|
121
121
|
const bots = data.bots || [];
|
|
122
122
|
if (!bots.length) {
|
|
123
|
-
console.log("אין לך בוטים זמינים עדיין.");
|
|
123
|
+
console.log("אין לך בוטים זמינים עדיין. קנה או השכר בוט בדשבורד.");
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
126
|
console.log("\nהבוטים שלך:");
|
|
127
127
|
for (const b of bots) {
|
|
128
|
-
const active = b.id === cfg.botId ? "
|
|
128
|
+
const active = b.id === cfg.botId ? " ← פעיל" : "";
|
|
129
129
|
console.log(` • ${b.name} (${b.id})${active}`);
|
|
130
130
|
}
|
|
131
131
|
console.log("\nבחר בוט עם: botworker use <BOT_ID>\n");
|
|
@@ -142,6 +142,37 @@ function cmdUse(cfg, rest) {
|
|
|
142
142
|
console.log("✅ הבוט הפעיל הוא כעת:", botId);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
async function cmdBalance(cfg) {
|
|
146
|
+
requireAuth(cfg);
|
|
147
|
+
const { ok, data } = await account(cfg.token);
|
|
148
|
+
if (!ok) {
|
|
149
|
+
console.error("❌", (data && data.error) || "טעינת היתרה נכשלה");
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
console.log("\n💳 יתרת קרדיטים");
|
|
153
|
+
console.log(` קבועה: ${data.balance}`);
|
|
154
|
+
console.log(` חודשית: ${data.monthly_balance}`);
|
|
155
|
+
console.log(` סה"כ: ${data.total}`);
|
|
156
|
+
console.log(" (1 קרדיט = 1,000 טוקנים)\n");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function cmdUsage(cfg) {
|
|
160
|
+
requireAuth(cfg);
|
|
161
|
+
const { ok, data } = await account(cfg.token);
|
|
162
|
+
if (!ok) {
|
|
163
|
+
console.error("❌", (data && data.error) || "טעינת השימוש נכשלה");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
const rows = data.recent_usage || [];
|
|
167
|
+
if (!rows.length) { console.log("אין שימוש אחרון להצגה."); return; }
|
|
168
|
+
console.log("\n📊 שימוש אחרון:");
|
|
169
|
+
for (const r of rows) {
|
|
170
|
+
const when = new Date(r.created_at).toLocaleString("he-IL");
|
|
171
|
+
console.log(` ${when} · ${r.source} · ${r.model} · ${r.total_tokens} טוקנים · ${r.credits} קרדיטים`);
|
|
172
|
+
}
|
|
173
|
+
console.log("");
|
|
174
|
+
}
|
|
175
|
+
|
|
145
176
|
async function send(cfg, message, history) {
|
|
146
177
|
requireAuth(cfg);
|
|
147
178
|
if (!cfg.botId) {
|
|
@@ -161,17 +192,23 @@ async function send(cfg, message, history) {
|
|
|
161
192
|
console.error("❌", (data && (data.error?.message || data.error)) || `HTTP ${status}`);
|
|
162
193
|
process.exit(1);
|
|
163
194
|
}
|
|
164
|
-
return String(data.reply || "");
|
|
195
|
+
return { reply: String(data.reply || ""), usage: data.usage, credits: data.credits };
|
|
165
196
|
}
|
|
166
197
|
|
|
167
198
|
async function cmdChat(cfg, rest) {
|
|
168
|
-
const
|
|
199
|
+
const flags = parseFlags(rest);
|
|
200
|
+
const message = flags._.join(" ").trim();
|
|
169
201
|
if (!message) {
|
|
170
|
-
console.error('שימוש: botworker chat "ההודעה שלך"');
|
|
202
|
+
console.error('שימוש: botworker chat "ההודעה שלך" [--json]');
|
|
171
203
|
process.exit(1);
|
|
172
204
|
}
|
|
173
|
-
const
|
|
174
|
-
|
|
205
|
+
const out = await send(cfg, message, []);
|
|
206
|
+
if (flags.json) {
|
|
207
|
+
console.log(JSON.stringify(out, null, 2));
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
console.log("\n🤖 " + out.reply + "\n");
|
|
211
|
+
if (out.credits) console.log(` (${out.credits.used} קרדיטים · ${out.usage?.total_tokens ?? "?"} טוקנים)\n`);
|
|
175
212
|
}
|
|
176
213
|
|
|
177
214
|
async function cmdInteractive(cfg) {
|
|
@@ -181,52 +218,75 @@ async function cmdInteractive(cfg) {
|
|
|
181
218
|
while (true) {
|
|
182
219
|
const message = (await ask("👤 ")).trim();
|
|
183
220
|
if (!message || message === "exit" || message === "quit") break;
|
|
184
|
-
const
|
|
185
|
-
console.log("🤖 " + reply + "\n");
|
|
221
|
+
const out = await send(cfg, message, history);
|
|
222
|
+
console.log("🤖 " + out.reply + "\n");
|
|
186
223
|
history.push({ role: "user", content: message });
|
|
187
|
-
history.push({ role: "assistant", content: reply });
|
|
224
|
+
history.push({ role: "assistant", content: out.reply });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async function cmdWhoami(cfg) {
|
|
229
|
+
if (!cfg.token) { console.log({ connected: false, ...cfg }); return; }
|
|
230
|
+
const { ok, data } = await account(cfg.token);
|
|
231
|
+
if (ok) {
|
|
232
|
+
console.log({
|
|
233
|
+
connected: true,
|
|
234
|
+
email: data.account?.email,
|
|
235
|
+
name: data.account?.name,
|
|
236
|
+
activeBot: cfg.botId || null,
|
|
237
|
+
credits: data.total,
|
|
238
|
+
});
|
|
239
|
+
} else {
|
|
240
|
+
console.log({ connected: true, email: cfg.email, botId: cfg.botId });
|
|
188
241
|
}
|
|
189
242
|
}
|
|
190
243
|
|
|
191
244
|
function cmdHelp() {
|
|
192
|
-
console.log(`BotWorker CLI
|
|
245
|
+
console.log(`BotWorker CLI v${VERSION}
|
|
193
246
|
|
|
194
247
|
שימוש:
|
|
195
|
-
botworker config --
|
|
196
|
-
botworker
|
|
197
|
-
botworker
|
|
198
|
-
botworker config --api-
|
|
199
|
-
botworker bots
|
|
200
|
-
botworker use <BOT_ID>
|
|
201
|
-
botworker chat "ההודעה שלך"
|
|
202
|
-
botworker
|
|
203
|
-
botworker
|
|
204
|
-
botworker
|
|
248
|
+
botworker config --email you@example.com שולח קוד בן 6 תווים לאימייל
|
|
249
|
+
botworker login הזנת הקוד וקבלת גישה
|
|
250
|
+
botworker config --api-key bw_live_xxx התחברות ידנית עם API key
|
|
251
|
+
botworker config --api-base <url> שינוי כתובת ה-API (אופציונלי)
|
|
252
|
+
botworker bots רשימת הבוטים שלך
|
|
253
|
+
botworker use <BOT_ID> בחירת הבוט הפעיל
|
|
254
|
+
botworker chat "ההודעה שלך" [--json] שליחת הודעה אחת
|
|
255
|
+
botworker מצב שיחה אינטראקטיבי
|
|
256
|
+
botworker balance יתרת הקרדיטים שלך
|
|
257
|
+
botworker usage שימוש אחרון
|
|
258
|
+
botworker whoami פרטי החשבון
|
|
259
|
+
botworker logout ניתוק ומחיקת ההגדרות
|
|
260
|
+
botworker version גרסת ה-CLI
|
|
261
|
+
|
|
262
|
+
חיוב: כל בקשה צורכת קרדיטים לפי שימוש אמיתי (1 קרדיט = 1,000 טוקנים).
|
|
205
263
|
`);
|
|
206
264
|
}
|
|
207
265
|
|
|
208
266
|
async function main() {
|
|
209
267
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
210
268
|
const cfg = loadConfig();
|
|
269
|
+
if (cfg.apiBase && !process.env.BOTWORKER_API_BASE) process.env.BOTWORKER_API_BASE = cfg.apiBase;
|
|
211
270
|
|
|
212
271
|
switch (cmd) {
|
|
213
|
-
case "config":
|
|
214
|
-
|
|
215
|
-
case "
|
|
216
|
-
|
|
217
|
-
case "
|
|
218
|
-
|
|
219
|
-
case "
|
|
220
|
-
|
|
221
|
-
case "
|
|
222
|
-
return cmdChat(cfg, rest);
|
|
223
|
-
case "whoami":
|
|
224
|
-
console.log({ name: cfg.name, email: cfg.email, botId: cfg.botId, connected: !!cfg.token });
|
|
225
|
-
return;
|
|
272
|
+
case "config": return cmdConfig(cfg, rest);
|
|
273
|
+
case "login": return cmdLogin(cfg);
|
|
274
|
+
case "bots": return cmdBots(cfg);
|
|
275
|
+
case "use": return cmdUse(cfg, rest);
|
|
276
|
+
case "chat": return cmdChat(cfg, rest);
|
|
277
|
+
case "balance":
|
|
278
|
+
case "credits": return cmdBalance(cfg);
|
|
279
|
+
case "usage": return cmdUsage(cfg);
|
|
280
|
+
case "whoami": return cmdWhoami(cfg);
|
|
226
281
|
case "logout":
|
|
227
282
|
clearConfig();
|
|
228
283
|
console.log("✅ התנתקת. ההגדרות נמחקו.");
|
|
229
284
|
return;
|
|
285
|
+
case "version":
|
|
286
|
+
case "--version":
|
|
287
|
+
case "-v":
|
|
288
|
+
console.log(`botworker v${VERSION}`);
|
|
289
|
+
return;
|
|
230
290
|
case "help":
|
|
231
291
|
case "--help":
|
|
232
292
|
case "-h":
|
|
@@ -242,4 +302,4 @@ async function main() {
|
|
|
242
302
|
main().catch((e) => {
|
|
243
303
|
console.error("שגיאה:", e.message);
|
|
244
304
|
process.exit(1);
|
|
245
|
-
});
|
|
305
|
+
});
|
package/lib/api.js
CHANGED
|
@@ -1,46 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
// BotWorker CLI network layer — talks to the streaming GROQ engine using a
|
|
2
|
+
// platform API key (no global install needed; works via `npx botworker`).
|
|
3
|
+
import { loadConfig } from "./config.js";
|
|
4
|
+
|
|
5
|
+
function base() {
|
|
6
|
+
const cfg = loadConfig();
|
|
7
|
+
return (
|
|
8
|
+
cfg.apiBase ||
|
|
9
|
+
process.env.BOTWORKER_API_BASE ||
|
|
10
|
+
"https://gvmrylxlzktfsuzznmbc.supabase.co/functions/v1"
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ANON =
|
|
15
|
+
process.env.BOTWORKER_ANON_KEY ||
|
|
16
|
+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imd2bXJ5bHhsemt0ZnN1enpubWJjIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjUwMTQ4NTMsImV4cCI6MjA4MDU5MDg1M30.rfNWw0SNZ8W4tDMXVKw4QFSOoQslgsGY1pm_ldVmp-o";
|
|
17
|
+
|
|
18
|
+
function headers(apiKey) {
|
|
19
|
+
return {
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
apikey: ANON,
|
|
22
|
+
"x-api-key": apiKey || "",
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Auth is now via a platform API key issued in the dashboard (Usage page).
|
|
27
|
+
export function requestCode() {
|
|
28
|
+
return Promise.resolve({
|
|
29
|
+
ok: false,
|
|
30
|
+
status: 410,
|
|
31
|
+
data: { error: "השתמש ב-API key מהדשבורד: botworker config --api-key bw_live_xxx" },
|
|
19
32
|
});
|
|
33
|
+
}
|
|
34
|
+
export function verifyCode() {
|
|
35
|
+
return requestCode();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** List available bots + credit balance for the API key holder. */
|
|
39
|
+
export async function listBots(apiKey) {
|
|
40
|
+
const res = await fetch(`${base()}/cli-bots`, { method: "GET", headers: headers(apiKey) });
|
|
20
41
|
const data = await res.json().catch(() => ({}));
|
|
21
42
|
return { status: res.status, ok: res.ok, data };
|
|
22
43
|
}
|
|
23
44
|
|
|
24
|
-
/**
|
|
25
|
-
export function
|
|
26
|
-
|
|
45
|
+
/** Account info (reuses cli-bots which returns the credit balance). */
|
|
46
|
+
export async function account(apiKey) {
|
|
47
|
+
const res = await fetch(`${base()}/cli-bots`, { method: "GET", headers: headers(apiKey) });
|
|
48
|
+
const data = await res.json().catch(() => ({}));
|
|
49
|
+
const total = Number(data.credits) || 0;
|
|
50
|
+
return {
|
|
51
|
+
status: res.status,
|
|
52
|
+
ok: res.ok,
|
|
53
|
+
data: { balance: total, monthly_balance: 0, total, recent_usage: [], account: {} },
|
|
54
|
+
};
|
|
27
55
|
}
|
|
28
56
|
|
|
29
|
-
/**
|
|
30
|
-
export function
|
|
31
|
-
|
|
32
|
-
}
|
|
57
|
+
/** Send a chat message; reads the SSE stream and returns the full reply. */
|
|
58
|
+
export async function chat(apiKey, botId, message, history) {
|
|
59
|
+
const messages = [...(history || []).slice(-12), { role: "user", content: message }];
|
|
60
|
+
const res = await fetch(`${base()}/api-chat`, {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: { ...headers(apiKey), "x-source": "cli" },
|
|
63
|
+
body: JSON.stringify({ botId, messages }),
|
|
64
|
+
});
|
|
65
|
+
if (!res.ok || !res.body) {
|
|
66
|
+
const data = await res.json().catch(() => ({}));
|
|
67
|
+
return { status: res.status, ok: false, data };
|
|
68
|
+
}
|
|
33
69
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
const reader = res.body.getReader();
|
|
71
|
+
const decoder = new TextDecoder();
|
|
72
|
+
let buffer = "";
|
|
73
|
+
let reply = "";
|
|
74
|
+
let model = "";
|
|
75
|
+
// eslint-disable-next-line no-constant-condition
|
|
76
|
+
while (true) {
|
|
77
|
+
const { done, value } = await reader.read();
|
|
78
|
+
if (done) break;
|
|
79
|
+
buffer += decoder.decode(value, { stream: true });
|
|
80
|
+
const lines = buffer.split("\n");
|
|
81
|
+
buffer = lines.pop() || "";
|
|
82
|
+
for (const line of lines) {
|
|
83
|
+
const t = line.trim();
|
|
84
|
+
if (!t.startsWith("data:")) continue;
|
|
85
|
+
try {
|
|
86
|
+
const evt = JSON.parse(t.slice(5).trim());
|
|
87
|
+
if (evt.delta) { reply += evt.delta; process.stdout.write(evt.delta); }
|
|
88
|
+
if (evt.model) model = evt.model;
|
|
89
|
+
} catch { /* partial */ }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (reply) process.stdout.write("\n");
|
|
93
|
+
return { status: 200, ok: true, data: { reply, model, success: true } };
|
|
37
94
|
}
|
|
38
|
-
|
|
39
|
-
/** Send a chat message to a bot. */
|
|
40
|
-
export function chat(token, botId, message, history) {
|
|
41
|
-
return call(
|
|
42
|
-
ENDPOINTS.chat,
|
|
43
|
-
{ bot_id: botId, message, history: (history || []).slice(-8) },
|
|
44
|
-
token,
|
|
45
|
-
);
|
|
46
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botworker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "BotWorker CLI — chat with your BotWorker bots straight from the terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
"scripts": {
|
|
29
29
|
"start": "node bin/botworker.mjs"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|