@botconnector/bccli 0.3.0-beta.1 → 0.3.0-beta.3
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/dist/{chunk-MANM7HY6.js → chunk-5ISYVAXI.js} +19 -1
- package/dist/{chunk-E4BWUMQ2.js → chunk-R37QWDTL.js} +1 -1
- package/dist/cli.js +16 -7
- package/dist/{login-IXJD5O7Z.js → login-WJMGVDRM.js} +1 -1
- package/dist/{providerCli-7QNAYIFT.js → providerCli-SJRCBSRE.js} +1 -1
- package/dist/{ui-6PGC4T6N.js → ui-HAW5NMFA.js} +42 -8
- package/package.json +1 -1
|
@@ -21,6 +21,21 @@ var ProviderError = class extends Error {
|
|
|
21
21
|
status;
|
|
22
22
|
};
|
|
23
23
|
var retryable = (status) => status === 429 || status >= 500;
|
|
24
|
+
function detectRepetition(text) {
|
|
25
|
+
const tail = text.slice(-600);
|
|
26
|
+
for (let len = 1; len <= 12; len++) {
|
|
27
|
+
const unit = tail.slice(-len);
|
|
28
|
+
if (unit.length < len || !unit.trim()) continue;
|
|
29
|
+
let i = tail.length;
|
|
30
|
+
let count = 0;
|
|
31
|
+
while (i >= len && tail.slice(i - len, i) === unit) {
|
|
32
|
+
count++;
|
|
33
|
+
i -= len;
|
|
34
|
+
}
|
|
35
|
+
if (count >= 20 && count * len >= 300) return text.length - count * len;
|
|
36
|
+
}
|
|
37
|
+
return -1;
|
|
38
|
+
}
|
|
24
39
|
function sleep(ms, signal) {
|
|
25
40
|
return new Promise((resolve, reject) => {
|
|
26
41
|
const timer = setTimeout(resolve, ms);
|
|
@@ -52,6 +67,7 @@ async function readStream(res, onText) {
|
|
|
52
67
|
let current;
|
|
53
68
|
const decoder = new TextDecoder();
|
|
54
69
|
let buffer = "";
|
|
70
|
+
let loopAt = -1;
|
|
55
71
|
const handle = (line) => {
|
|
56
72
|
if (!line.startsWith("data:")) return;
|
|
57
73
|
const data = line.slice(5).trim();
|
|
@@ -71,6 +87,7 @@ async function readStream(res, onText) {
|
|
|
71
87
|
if (delta.content) {
|
|
72
88
|
text += delta.content;
|
|
73
89
|
onText?.(delta.content);
|
|
90
|
+
if (loopAt < 0) loopAt = detectRepetition(text);
|
|
74
91
|
}
|
|
75
92
|
for (const tc of delta.tool_calls ?? []) {
|
|
76
93
|
let target = tc.index !== void 0 ? byIndex.get(tc.index) : current;
|
|
@@ -88,11 +105,12 @@ async function readStream(res, onText) {
|
|
|
88
105
|
for await (const chunk of res.body) {
|
|
89
106
|
buffer += decoder.decode(chunk, { stream: true });
|
|
90
107
|
let newline = buffer.indexOf("\n");
|
|
91
|
-
while (newline >= 0) {
|
|
108
|
+
while (newline >= 0 && loopAt < 0) {
|
|
92
109
|
handle(buffer.slice(0, newline).trim());
|
|
93
110
|
buffer = buffer.slice(newline + 1);
|
|
94
111
|
newline = buffer.indexOf("\n");
|
|
95
112
|
}
|
|
113
|
+
if (loopAt >= 0) return { text: text.slice(0, loopAt), toolCalls: [], usage, finishReason: "repetition" };
|
|
96
114
|
}
|
|
97
115
|
handle(buffer.trim());
|
|
98
116
|
const toolCalls = calls.map((call, index) => ({ ...call, id: call.id || `call_${index}` }));
|
|
@@ -35,7 +35,7 @@ function readSecret(prompt) {
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
async function runLogin(providerId, cwd) {
|
|
38
|
-
const { runProviderCommand } = await import("./providerCli-
|
|
38
|
+
const { runProviderCommand } = await import("./providerCli-SJRCBSRE.js");
|
|
39
39
|
const { parseCliArgs } = await import("./args-EVIFNGPQ.js");
|
|
40
40
|
return runProviderCommand(parseCliArgs(["provider", "add", providerId]), {
|
|
41
41
|
env: process.env,
|
package/dist/cli.js
CHANGED
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
addProviderKey,
|
|
8
8
|
createProvider,
|
|
9
9
|
listAllModels
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5ISYVAXI.js";
|
|
11
11
|
import {
|
|
12
12
|
runLogin
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-R37QWDTL.js";
|
|
14
14
|
import {
|
|
15
15
|
Session,
|
|
16
16
|
pruneSessions
|
|
@@ -624,6 +624,14 @@ ${completion.text}` });
|
|
|
624
624
|
}))
|
|
625
625
|
} : {}
|
|
626
626
|
});
|
|
627
|
+
if (completion.finishReason === "repetition") {
|
|
628
|
+
this.onEvent({ type: "textReplace", text: completion.text });
|
|
629
|
+
this.onEvent({
|
|
630
|
+
type: "error",
|
|
631
|
+
message: "Model terjebak mengulang teks, jawaban dihentikan. Coba ulangi atau ganti model dengan /model."
|
|
632
|
+
});
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
627
635
|
if (!completion.toolCalls.length) {
|
|
628
636
|
this.onEvent({ type: "done" });
|
|
629
637
|
return;
|
|
@@ -715,6 +723,7 @@ Model ini sepertinya tidak mendukung tool calling. Coba model lain dengan /model
|
|
|
715
723
|
...this.opts.label ? { agent: this.opts.label } : {}
|
|
716
724
|
});
|
|
717
725
|
if (answer === "session") this.permissions.allowForSession(request);
|
|
726
|
+
if (answer === "all") this.permissions.mode = "allowAll";
|
|
718
727
|
decision = answer === "no" ? "deny" : "allow";
|
|
719
728
|
}
|
|
720
729
|
if (decision === "deny") {
|
|
@@ -1182,7 +1191,7 @@ function createRuntime(opts) {
|
|
|
1182
1191
|
}
|
|
1183
1192
|
|
|
1184
1193
|
// src/version.ts
|
|
1185
|
-
var VERSION = true ? "0.3.0-beta.
|
|
1194
|
+
var VERSION = true ? "0.3.0-beta.3" : "0.0.0-dev";
|
|
1186
1195
|
|
|
1187
1196
|
// src/cli.ts
|
|
1188
1197
|
async function main() {
|
|
@@ -1199,12 +1208,12 @@ async function main() {
|
|
|
1199
1208
|
if (args.command === "login") return runLogin(args.loginProvider ?? "bc-cloud", cwd);
|
|
1200
1209
|
if (args.command === "mcp") {
|
|
1201
1210
|
const { runMcpCommand } = await import("./mcpCli-BV3IGR47.js");
|
|
1202
|
-
const { readSecret } = await import("./login-
|
|
1211
|
+
const { readSecret } = await import("./login-WJMGVDRM.js");
|
|
1203
1212
|
return runMcpCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
|
|
1204
1213
|
}
|
|
1205
1214
|
if (args.command === "provider") {
|
|
1206
|
-
const { runProviderCommand } = await import("./providerCli-
|
|
1207
|
-
const { readSecret } = await import("./login-
|
|
1215
|
+
const { runProviderCommand } = await import("./providerCli-SJRCBSRE.js");
|
|
1216
|
+
const { readSecret } = await import("./login-WJMGVDRM.js");
|
|
1208
1217
|
return runProviderCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
|
|
1209
1218
|
}
|
|
1210
1219
|
if (args.command === "models") {
|
|
@@ -1234,7 +1243,7 @@ async function main() {
|
|
|
1234
1243
|
}
|
|
1235
1244
|
}
|
|
1236
1245
|
if (!process.stdin.isTTY) throw new ConfigError('Mode interaktif butuh terminal. Untuk skrip/CI pakai: bccli -p "tugas"');
|
|
1237
|
-
const { startInteractive } = await import("./ui-
|
|
1246
|
+
const { startInteractive } = await import("./ui-HAW5NMFA.js");
|
|
1238
1247
|
return startInteractive(rt, { initialPrompt: args.prompt, resume: args.resume, version: VERSION });
|
|
1239
1248
|
}
|
|
1240
1249
|
main().then(
|
|
@@ -209,6 +209,7 @@ function PermissionPrompt({
|
|
|
209
209
|
const k = input.toLowerCase();
|
|
210
210
|
if (k === "y") onAnswer("yes");
|
|
211
211
|
else if (k === "a" && request.sessionRules?.length) onAnswer("session");
|
|
212
|
+
else if (k === "s") onAnswer("all");
|
|
212
213
|
else if (k === "n" || key.escape) onAnswer("no");
|
|
213
214
|
});
|
|
214
215
|
const rules = request.sessionRules ?? [];
|
|
@@ -220,6 +221,7 @@ function PermissionPrompt({
|
|
|
220
221
|
/* @__PURE__ */ jsx6(Text6, { color: color("green"), children: "[y] ya" }),
|
|
221
222
|
" ",
|
|
222
223
|
sessionLabel ? /* @__PURE__ */ jsx6(Text6, { color: color("cyan"), children: `[a] ${sessionLabel} ` }) : null,
|
|
224
|
+
/* @__PURE__ */ jsx6(Text6, { color: color("yellow"), children: "[s] ya semua " }),
|
|
223
225
|
/* @__PURE__ */ jsx6(Text6, { color: color("red"), children: "[n] tidak" })
|
|
224
226
|
] })
|
|
225
227
|
] });
|
|
@@ -247,23 +249,51 @@ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
|
247
249
|
function PromptInput({ disabled, history, cwd, onSubmit, extraCommands }) {
|
|
248
250
|
const [value, setValue] = useState4("");
|
|
249
251
|
const [historyIndex, setHistoryIndex] = useState4(null);
|
|
252
|
+
const [selected, setSelected] = useState4(0);
|
|
253
|
+
const all = [...SLASH_COMMANDS, ...(extraCommands ?? []).filter((c) => !SLASH_COMMANDS.some((b) => b.name === c.name))];
|
|
254
|
+
const suggestions = value.startsWith("/") && !/\s/.test(value) ? all.filter((c) => c.name.startsWith(value.slice(1))).slice(0, 8) : [];
|
|
255
|
+
const highlighted = Math.min(selected, Math.max(0, suggestions.length - 1));
|
|
256
|
+
const edit = (next) => {
|
|
257
|
+
setValue(next);
|
|
258
|
+
setSelected(0);
|
|
259
|
+
};
|
|
250
260
|
useInput5(
|
|
251
261
|
(input, key) => {
|
|
262
|
+
if (suggestions.length) {
|
|
263
|
+
if (key.upArrow) {
|
|
264
|
+
setSelected(Math.max(0, highlighted - 1));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (key.downArrow) {
|
|
268
|
+
setSelected(Math.min(suggestions.length - 1, highlighted + 1));
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (key.tab && !key.shift) {
|
|
272
|
+
edit(`/${suggestions[highlighted].name} `);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (key.return) {
|
|
276
|
+
edit("");
|
|
277
|
+
setHistoryIndex(null);
|
|
278
|
+
onSubmit(`/${suggestions[highlighted].name}`);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
252
282
|
if (key.return) {
|
|
253
283
|
if (value.endsWith("\\")) {
|
|
254
|
-
|
|
284
|
+
edit(`${value.slice(0, -1)}
|
|
255
285
|
`);
|
|
256
286
|
return;
|
|
257
287
|
}
|
|
258
288
|
const text = value.trim();
|
|
259
289
|
if (!text) return;
|
|
260
|
-
|
|
290
|
+
edit("");
|
|
261
291
|
setHistoryIndex(null);
|
|
262
292
|
onSubmit(text);
|
|
263
293
|
return;
|
|
264
294
|
}
|
|
265
295
|
if (key.backspace || key.delete) {
|
|
266
|
-
|
|
296
|
+
edit((v) => v.slice(0, -1));
|
|
267
297
|
return;
|
|
268
298
|
}
|
|
269
299
|
if (key.upArrow) {
|
|
@@ -281,23 +311,21 @@ function PromptInput({ disabled, history, cwd, onSubmit, extraCommands }) {
|
|
|
281
311
|
return;
|
|
282
312
|
}
|
|
283
313
|
if (key.tab && !key.shift) {
|
|
284
|
-
|
|
314
|
+
edit((v) => completeFile(v, cwd));
|
|
285
315
|
return;
|
|
286
316
|
}
|
|
287
317
|
if (key.ctrl || key.meta || key.escape || key.tab || key.leftArrow || key.rightArrow) return;
|
|
288
|
-
|
|
318
|
+
edit((v) => v + input.replace(/\r/g, "\n"));
|
|
289
319
|
},
|
|
290
320
|
{ isActive: !disabled }
|
|
291
321
|
);
|
|
292
|
-
const all = [...SLASH_COMMANDS, ...(extraCommands ?? []).filter((c) => !SLASH_COMMANDS.some((b) => b.name === c.name))];
|
|
293
|
-
const suggestions = value.startsWith("/") && !/\s/.test(value) ? all.filter((c) => c.name.startsWith(value.slice(1))).slice(0, 8) : [];
|
|
294
322
|
return /* @__PURE__ */ jsxs5(Box7, { flexDirection: "column", children: [
|
|
295
323
|
/* @__PURE__ */ jsx7(Box7, { borderStyle: "round", borderColor: color("gray"), paddingX: 1, children: /* @__PURE__ */ jsxs5(Text7, { children: [
|
|
296
324
|
/* @__PURE__ */ jsx7(Text7, { color: color("green"), children: "> " }),
|
|
297
325
|
value,
|
|
298
326
|
disabled ? "" : /* @__PURE__ */ jsx7(Text7, { inverse: true, children: " " })
|
|
299
327
|
] }) }),
|
|
300
|
-
suggestions.map((s) => /* @__PURE__ */ jsx7(Text7, { dimColor:
|
|
328
|
+
suggestions.map((s, i) => /* @__PURE__ */ jsx7(Text7, { color: i === highlighted ? color("green") : void 0, dimColor: i !== highlighted, children: `${i === highlighted ? "\u203A" : " "} /${s.name} ${s.description}` }, s.name))
|
|
301
329
|
] });
|
|
302
330
|
}
|
|
303
331
|
|
|
@@ -433,6 +461,11 @@ function applyEvent(t, event) {
|
|
|
433
461
|
if (last?.kind === "assistant") return { ...t, live: [...t.live.slice(0, -1), { ...last, text: last.text + event.delta }] };
|
|
434
462
|
return { ...t, live: [...t.live, entry({ kind: "assistant", text: event.delta })] };
|
|
435
463
|
}
|
|
464
|
+
case "textReplace": {
|
|
465
|
+
const last = t.live.at(-1);
|
|
466
|
+
if (last?.kind !== "assistant") return t;
|
|
467
|
+
return { ...t, live: [...t.live.slice(0, -1), { ...last, text: event.text }] };
|
|
468
|
+
}
|
|
436
469
|
case "toolStart": {
|
|
437
470
|
const running = t.live.some((e) => e.kind === "tool" && !e.done);
|
|
438
471
|
const tool = entry({ kind: "tool", callId: event.id, tool: event.tool, target: event.target, done: false });
|
|
@@ -716,6 +749,7 @@ ${t.output}`);
|
|
|
716
749
|
const answer = (a) => {
|
|
717
750
|
pending?.resolve(a);
|
|
718
751
|
setAsks((q) => q.slice(1));
|
|
752
|
+
if (a === "all") setMode("allowAll");
|
|
719
753
|
};
|
|
720
754
|
const cwd = runtime.cwd.startsWith(homedir()) ? `~${runtime.cwd.slice(homedir().length)}` : runtime.cwd;
|
|
721
755
|
const renderEntry = (e) => {
|