@botconnector/bccli 0.4.0-beta.6 → 0.4.0-beta.8
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 +8 -0
- package/dist/{args-FCLPQ7TO.js → args-FLTRM57K.js} +3 -2
- package/dist/{chunk-RZUJYAQV.js → chunk-2MGINW4O.js} +2 -0
- package/dist/{chunk-U7DLMVPZ.js → chunk-7S6JXQCH.js} +1 -1
- package/dist/{chunk-NGLKANMD.js → chunk-BFZXRKW5.js} +1 -1
- package/dist/chunk-CLN4Z5E3.js +60 -0
- package/dist/{chunk-UESQNU4A.js → chunk-DX7CZTBB.js} +1 -1
- package/dist/{chunk-GW36UMHZ.js → chunk-IM3KMPVZ.js} +2 -2
- package/dist/{chunk-C5AFWX7H.js → chunk-U7GK73CK.js} +18 -5
- package/dist/{chunk-UN7QXPCB.js → chunk-Z7PM3LTC.js} +12 -1
- package/dist/cli.js +32 -16
- package/dist/{config-NPSYFAFD.js → config-YUNKPCNB.js} +2 -2
- package/dist/{login-F4G5QXOU.js → login-JXFORO3J.js} +1 -1
- package/dist/{mcpCli-Q2H63ISP.js → mcpCli-DZWQPTOS.js} +3 -3
- package/dist/providerCli-Q7LRM2NP.js +12 -0
- package/dist/{ui-4EBFPASA.js → ui-6GTQUJOE.js} +53 -10
- package/package.json +1 -1
- package/dist/providerCli-MXV6PD6F.js +0 -11
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ cd project-kamu && bccli
|
|
|
17
17
|
| `bccli -p "tugas"` | satu tugas tanpa interaksi (skrip/CI) |
|
|
18
18
|
| `bccli -c` / `bccli -r` | lanjutkan sesi terakhir / pilih sesi |
|
|
19
19
|
| `bccli -m provider/model` | pilih model |
|
|
20
|
+
| `bccli --reasoning <auto|off|low|medium|high|max>` | pilih level reasoning untuk invocation ini |
|
|
20
21
|
| `bccli models` | daftar model |
|
|
21
22
|
|
|
22
23
|
Perintah di dalam sesi (ketik `/` untuk saran, ↑↓ pilih, Enter jalankan):
|
|
@@ -25,6 +26,7 @@ Perintah di dalam sesi (ketik `/` untuk saran, ↑↓ pilih, Enter jalankan):
|
|
|
25
26
|
|---|---|
|
|
26
27
|
| `/help` | daftar perintah dan pintasan |
|
|
27
28
|
| `/model` | ganti model |
|
|
29
|
+
| `/reasoning` | pilih Auto / Off / Low / Medium / High / Max |
|
|
28
30
|
| `/provider` | tambah/pilih provider AI |
|
|
29
31
|
| `/mcp` | pasang/kelola server MCP |
|
|
30
32
|
| `/new` | sesi baru (sesi lama tetap tersimpan) |
|
|
@@ -76,7 +78,13 @@ Provider lain yang OpenAI-compatible: pilih **Custom…** di `/provider`, atau
|
|
|
76
78
|
`/model` menampilkan model dari **semua** provider yang sudah punya key, dikelompokkan
|
|
77
79
|
per provider; ketik untuk menyaring. Pilihan tersimpan sebagai default.
|
|
78
80
|
|
|
81
|
+
Reasoning dapat dipilih lewat `bccli --reasoning <auto|off|low|medium|high|max>` atau `/reasoning`.
|
|
82
|
+
**Auto** memakai default model/provider dan BCCLI tidak mengirim override reasoning apa pun. BCCLI tidak
|
|
83
|
+
otomatis menurunkan atau menaikkan reasoning effort. Level manual diteruskan bila kontrak provider/model
|
|
84
|
+
mendukungnya; level yang tidak didukung menghasilkan error yang jelas dan tidak di-downgrade diam-diam.
|
|
85
|
+
|
|
79
86
|
`.bccli/config.json` di dalam project hanya boleh memilih `model` dan menambah provider baru tanpa API key —
|
|
87
|
+
preference `reasoning` hanya dibaca dari config user `~/.bccli/config.json`, bukan dari repo yang di-clone —
|
|
80
88
|
izin (`permissionMode`, `allow`) dan provider yang sudah ada hanya diatur dari `~/.bccli/config.json`,
|
|
81
89
|
supaya repo yang kamu clone tidak bisa memberi dirinya izin penuh atau mencuri API key.
|
|
82
90
|
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
HELP_TEXT,
|
|
4
4
|
parseCliArgs
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-Z7PM3LTC.js";
|
|
6
6
|
import "./chunk-ELML4KVQ.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-CLN4Z5E3.js";
|
|
8
|
+
import "./chunk-2MGINW4O.js";
|
|
8
9
|
export {
|
|
9
10
|
HELP_TEXT,
|
|
10
11
|
parseCliArgs
|
|
@@ -22,6 +22,7 @@ var ConfigError = class extends Error {
|
|
|
22
22
|
var DEFAULT_CONFIG = {
|
|
23
23
|
model: "bc-cloud/glm-5.3-flash",
|
|
24
24
|
permissionMode: "default",
|
|
25
|
+
reasoning: "auto",
|
|
25
26
|
providers: Object.fromEntries(PRESETS.map((p) => [p.id, { baseURL: p.baseURL, apiKeyEnv: p.apiKeyEnv }])),
|
|
26
27
|
allow: []
|
|
27
28
|
};
|
|
@@ -52,6 +53,7 @@ function loadConfig(cwd, env = process.env) {
|
|
|
52
53
|
return {
|
|
53
54
|
model: project.model ?? global.model ?? DEFAULT_CONFIG.model,
|
|
54
55
|
permissionMode: global.permissionMode ?? DEFAULT_CONFIG.permissionMode,
|
|
56
|
+
reasoning: global.reasoning ?? DEFAULT_CONFIG.reasoning,
|
|
55
57
|
providers: { ...known, ...fromProject },
|
|
56
58
|
projectProviders: Object.keys(fromProject),
|
|
57
59
|
allow: [...global.allow ?? []]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/reasoning.ts
|
|
4
|
+
var REASONING_LEVELS = ["auto", "off", "low", "medium", "high", "max"];
|
|
5
|
+
var OPENAI_LEVELS = ["auto", "low", "medium", "high"];
|
|
6
|
+
var BOTCONNECTOR_LEVELS = REASONING_LEVELS;
|
|
7
|
+
function isReasoningLevel(value) {
|
|
8
|
+
return REASONING_LEVELS.includes(value);
|
|
9
|
+
}
|
|
10
|
+
function parseReasoningLevel(value, label = "reasoning") {
|
|
11
|
+
if (!isReasoningLevel(value)) {
|
|
12
|
+
throw new Error(`${label} harus salah satu dari: ${REASONING_LEVELS.join(", ")}`);
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function reasoningCapability(providerId) {
|
|
17
|
+
switch (providerId) {
|
|
18
|
+
case "bc-cloud":
|
|
19
|
+
return { levels: BOTCONNECTOR_LEVELS, parameter: "reasoning_effort" };
|
|
20
|
+
case "openai":
|
|
21
|
+
return { levels: OPENAI_LEVELS, parameter: "reasoning_effort" };
|
|
22
|
+
case "openrouter":
|
|
23
|
+
return { levels: ["auto", "low", "medium", "high"], parameter: "reasoning" };
|
|
24
|
+
default:
|
|
25
|
+
return void 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function supportedReasoningLevels(providerId) {
|
|
29
|
+
return reasoningCapability(providerId)?.levels ?? ["auto"];
|
|
30
|
+
}
|
|
31
|
+
function assertReasoningSupported(providerId, level) {
|
|
32
|
+
if (level === "auto") return;
|
|
33
|
+
const capability = reasoningCapability(providerId);
|
|
34
|
+
if (!capability) {
|
|
35
|
+
throw new Error("Provider ini belum memiliki kontrak reasoning manual. Gunakan Auto.");
|
|
36
|
+
}
|
|
37
|
+
if (!capability.levels.includes(level)) {
|
|
38
|
+
const supported = capability.levels.filter((x) => x !== "auto").map(capitalize).join("/");
|
|
39
|
+
throw new Error(`Model/provider ini tidak mendukung reasoning level '${level}'. Gunakan Auto${supported ? `/${supported}` : ""}.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function reasoningPayload(providerId, level) {
|
|
43
|
+
if (level === "auto") return {};
|
|
44
|
+
assertReasoningSupported(providerId, level);
|
|
45
|
+
const capability = reasoningCapability(providerId);
|
|
46
|
+
if (capability.parameter === "reasoning") return { reasoning: { effort: level } };
|
|
47
|
+
return { reasoning_effort: level };
|
|
48
|
+
}
|
|
49
|
+
function capitalize(value) {
|
|
50
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
REASONING_LEVELS,
|
|
55
|
+
isReasoningLevel,
|
|
56
|
+
parseReasoningLevel,
|
|
57
|
+
supportedReasoningLevels,
|
|
58
|
+
assertReasoningSupported,
|
|
59
|
+
reasoningPayload
|
|
60
|
+
};
|
|
@@ -35,8 +35,8 @@ function readSecret(prompt) {
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
async function runLogin(providerId, cwd) {
|
|
38
|
-
const { runProviderCommand } = await import("./providerCli-
|
|
39
|
-
const { parseCliArgs } = await import("./args-
|
|
38
|
+
const { runProviderCommand } = await import("./providerCli-Q7LRM2NP.js");
|
|
39
|
+
const { parseCliArgs } = await import("./args-FLTRM57K.js");
|
|
40
40
|
return runProviderCommand(parseCliArgs(["provider", "add", providerId]), {
|
|
41
41
|
env: process.env,
|
|
42
42
|
cwd,
|
|
@@ -4,13 +4,16 @@ import {
|
|
|
4
4
|
providerName,
|
|
5
5
|
removeGlobalProvider,
|
|
6
6
|
writeGlobalConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7S6JXQCH.js";
|
|
8
|
+
import {
|
|
9
|
+
reasoningPayload
|
|
10
|
+
} from "./chunk-CLN4Z5E3.js";
|
|
8
11
|
import {
|
|
9
12
|
PRESETS,
|
|
10
13
|
loadConfig,
|
|
11
14
|
readCredentials,
|
|
12
15
|
saveCredential
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2MGINW4O.js";
|
|
14
17
|
|
|
15
18
|
// src/thinking.ts
|
|
16
19
|
var OPEN = "<think>";
|
|
@@ -188,9 +191,13 @@ async function readJson(res) {
|
|
|
188
191
|
const thinking = (choice?.message?.reasoning_content || choice?.message?.reasoning || "") + split.thinking;
|
|
189
192
|
return { text: split.text, toolCalls, thinking: thinking || void 0, usage: toUsage(body.usage), finishReason: choice?.finish_reason };
|
|
190
193
|
}
|
|
191
|
-
function createProvider({ baseURL, apiKey, model, fetch: doFetch = fetch, retryDelayMs = 1e3 }) {
|
|
194
|
+
function createProvider({ baseURL, apiKey, model, providerId, fetch: doFetch = fetch, retryDelayMs = 1e3 }) {
|
|
192
195
|
const headers = { "content-type": "application/json" };
|
|
193
196
|
if (apiKey) headers.authorization = `Bearer ${apiKey}`;
|
|
197
|
+
if (/^https:\/\/api\.botconnector\.id\/v1\/?$/.test(baseURL) && apiKey?.startsWith("bc_live_")) {
|
|
198
|
+
headers["x-botconnector-client"] = "bccli";
|
|
199
|
+
headers["x-botconnector-client-version"] = "0.4.0";
|
|
200
|
+
}
|
|
194
201
|
async function post(path, body, signal) {
|
|
195
202
|
let lastError;
|
|
196
203
|
for (let attempt = 0; attempt < 4; attempt++) {
|
|
@@ -211,10 +218,16 @@ function createProvider({ baseURL, apiKey, model, fetch: doFetch = fetch, retryD
|
|
|
211
218
|
throw lastError ?? new ProviderError("Permintaan gagal");
|
|
212
219
|
}
|
|
213
220
|
return {
|
|
214
|
-
async chat({ messages, tools, signal, onText, onThinking }) {
|
|
221
|
+
async chat({ messages, tools, signal, onText, onThinking, reasoning = "auto" }) {
|
|
222
|
+
let reasoningOverride;
|
|
223
|
+
try {
|
|
224
|
+
reasoningOverride = reasoningPayload(providerId, reasoning);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
throw new ProviderError(error.message);
|
|
227
|
+
}
|
|
215
228
|
const res = await post(
|
|
216
229
|
"/chat/completions",
|
|
217
|
-
{ model, messages, stream: true, stream_options: { include_usage: true }, ...tools?.length ? { tools } : {} },
|
|
230
|
+
{ model, messages, stream: true, stream_options: { include_usage: true }, ...tools?.length ? { tools } : {}, ...reasoningOverride },
|
|
218
231
|
signal
|
|
219
232
|
);
|
|
220
233
|
if ((res.headers.get("content-type") ?? "").includes("application/json")) return readJson(res);
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
MODE_ORDER
|
|
4
4
|
} from "./chunk-ELML4KVQ.js";
|
|
5
|
+
import {
|
|
6
|
+
REASONING_LEVELS,
|
|
7
|
+
isReasoningLevel
|
|
8
|
+
} from "./chunk-CLN4Z5E3.js";
|
|
5
9
|
import {
|
|
6
10
|
ConfigError
|
|
7
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-2MGINW4O.js";
|
|
8
12
|
|
|
9
13
|
// src/args.ts
|
|
10
14
|
import { parseArgs } from "util";
|
|
@@ -20,6 +24,7 @@ Pemakaian:
|
|
|
20
24
|
|
|
21
25
|
Opsi:
|
|
22
26
|
-m, --model <provider/model> pilih model, contoh bc-cloud/glm-5.3-flash
|
|
27
|
+
--reasoning <level> auto | off | low | medium | high | max
|
|
23
28
|
-c, --continue lanjutkan sesi terakhir di folder ini
|
|
24
29
|
-r, --resume pilih sesi untuk dilanjutkan
|
|
25
30
|
--allow-all jalankan semua alat tanpa minta izin
|
|
@@ -34,6 +39,7 @@ function parseCliArgs(argv) {
|
|
|
34
39
|
options: {
|
|
35
40
|
print: { type: "boolean", short: "p" },
|
|
36
41
|
model: { type: "string", short: "m" },
|
|
42
|
+
reasoning: { type: "string" },
|
|
37
43
|
continue: { type: "boolean", short: "c" },
|
|
38
44
|
resume: { type: "boolean", short: "r" },
|
|
39
45
|
"allow-all": { type: "boolean" },
|
|
@@ -47,6 +53,10 @@ function parseCliArgs(argv) {
|
|
|
47
53
|
value: { type: "string", multiple: true }
|
|
48
54
|
}
|
|
49
55
|
});
|
|
56
|
+
const reasoning = values.reasoning;
|
|
57
|
+
if (reasoning && !isReasoningLevel(reasoning)) {
|
|
58
|
+
throw new ConfigError(`--reasoning harus salah satu dari: ${REASONING_LEVELS.join(", ")}`);
|
|
59
|
+
}
|
|
50
60
|
const mode = values["permission-mode"];
|
|
51
61
|
if (mode && !MODE_ORDER.includes(mode)) {
|
|
52
62
|
throw new ConfigError(`--permission-mode harus salah satu dari: ${MODE_ORDER.join(", ")}`);
|
|
@@ -60,6 +70,7 @@ function parseCliArgs(argv) {
|
|
|
60
70
|
prompt: command === "run" && words.length ? words.join(" ") : void 0,
|
|
61
71
|
print: !!values.print,
|
|
62
72
|
model: values.model,
|
|
73
|
+
reasoning,
|
|
63
74
|
continue: !!values.continue,
|
|
64
75
|
resume: !!values.resume,
|
|
65
76
|
allowAll: !!values["allow-all"],
|
package/dist/cli.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
HELP_TEXT,
|
|
4
4
|
parseCliArgs
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-Z7PM3LTC.js";
|
|
6
6
|
import {
|
|
7
7
|
addProviderKey,
|
|
8
8
|
createProvider,
|
|
9
9
|
listAllModels
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-U7GK73CK.js";
|
|
11
11
|
import {
|
|
12
12
|
runLogin
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-IM3KMPVZ.js";
|
|
14
14
|
import {
|
|
15
15
|
BUILTIN_AGENTS,
|
|
16
16
|
buildSystemPrompt,
|
|
@@ -26,7 +26,8 @@ import {
|
|
|
26
26
|
} from "./chunk-ELML4KVQ.js";
|
|
27
27
|
import {
|
|
28
28
|
providerName
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-7S6JXQCH.js";
|
|
30
|
+
import "./chunk-CLN4Z5E3.js";
|
|
30
31
|
import {
|
|
31
32
|
Session,
|
|
32
33
|
pruneSessions
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
bccliHome,
|
|
37
38
|
loadConfig,
|
|
38
39
|
resolveModel
|
|
39
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-2MGINW4O.js";
|
|
40
41
|
|
|
41
42
|
// src/tools/index.ts
|
|
42
43
|
import { z as z8 } from "zod";
|
|
@@ -616,6 +617,7 @@ var Agent = class {
|
|
|
616
617
|
this.maxSteps = opts.maxSteps ?? 50;
|
|
617
618
|
this.contextWindow = opts.contextWindow ?? 128e3;
|
|
618
619
|
this.systemPrompt = opts.systemPrompt;
|
|
620
|
+
this.reasoning = opts.reasoning ?? "auto";
|
|
619
621
|
}
|
|
620
622
|
opts;
|
|
621
623
|
provider;
|
|
@@ -625,6 +627,7 @@ var Agent = class {
|
|
|
625
627
|
lastInputTokens = 0;
|
|
626
628
|
onEvent = () => {
|
|
627
629
|
};
|
|
630
|
+
reasoning;
|
|
628
631
|
askPermission = async () => "no";
|
|
629
632
|
tools;
|
|
630
633
|
definitions;
|
|
@@ -674,7 +677,8 @@ var Agent = class {
|
|
|
674
677
|
messages: [{ role: "system", content: this.systemPrompt }, ...this.messages, { role: "user", content: COMPACT_PROMPT }],
|
|
675
678
|
// Some gateways reject tool_calls in history when no tools are declared.
|
|
676
679
|
tools: this.definitions,
|
|
677
|
-
signal
|
|
680
|
+
signal,
|
|
681
|
+
reasoning: this.reasoning
|
|
678
682
|
});
|
|
679
683
|
this.clear();
|
|
680
684
|
this.push({ role: "user", content: `Ringkasan percakapan sebelumnya:
|
|
@@ -699,7 +703,8 @@ ${completion.text}` });
|
|
|
699
703
|
tools: this.turnDefinitions,
|
|
700
704
|
signal,
|
|
701
705
|
onText: (delta) => this.onEvent({ type: "text", delta }),
|
|
702
|
-
onThinking: (delta) => this.onEvent({ type: "thinking", delta })
|
|
706
|
+
onThinking: (delta) => this.onEvent({ type: "thinking", delta }),
|
|
707
|
+
reasoning: this.reasoning
|
|
703
708
|
});
|
|
704
709
|
if (!completion.toolCalls.length && completion.finishReason !== "repetition") {
|
|
705
710
|
const recovered = recoverTextToolCalls(completion.text, this.turnDefinitions);
|
|
@@ -1161,6 +1166,7 @@ ${def.prompt}`,
|
|
|
1161
1166
|
cwd: opts.cwd,
|
|
1162
1167
|
maxSteps: def.maxSteps ?? 50,
|
|
1163
1168
|
label: def.name,
|
|
1169
|
+
reasoning: opts.reasoning?.() ?? "auto",
|
|
1164
1170
|
// Subagent edits belong to the parent's turn so /undo reverts them too.
|
|
1165
1171
|
checkpoint: ctx.checkpoint
|
|
1166
1172
|
});
|
|
@@ -1229,9 +1235,10 @@ function createRuntime(opts) {
|
|
|
1229
1235
|
const home = bccliHome(env);
|
|
1230
1236
|
let config = loadConfig(opts.cwd, env);
|
|
1231
1237
|
let modelRef = opts.args.model ?? config.model;
|
|
1238
|
+
let reasoning = opts.args.reasoning ?? config.reasoning;
|
|
1232
1239
|
const makeProvider = (ref) => {
|
|
1233
1240
|
const resolved = resolveModel(config, ref, env);
|
|
1234
|
-
return opts.provider ?? createProvider({ baseURL: resolved.baseURL, apiKey: resolved.apiKey, model: resolved.model });
|
|
1241
|
+
return opts.provider ?? createProvider({ baseURL: resolved.baseURL, apiKey: resolved.apiKey, model: resolved.model, providerId: resolved.providerId });
|
|
1235
1242
|
};
|
|
1236
1243
|
const provider = makeProvider(modelRef);
|
|
1237
1244
|
const mode = opts.args.allowAll ? "allowAll" : opts.args.permissionMode ?? config.permissionMode;
|
|
@@ -1274,7 +1281,8 @@ function createRuntime(opts) {
|
|
|
1274
1281
|
provider: () => agent.provider,
|
|
1275
1282
|
providerFor: makeProvider,
|
|
1276
1283
|
systemPrompt,
|
|
1277
|
-
cwd: opts.cwd
|
|
1284
|
+
cwd: opts.cwd,
|
|
1285
|
+
reasoning: () => reasoning
|
|
1278
1286
|
});
|
|
1279
1287
|
const agent = new Agent({
|
|
1280
1288
|
provider,
|
|
@@ -1283,6 +1291,7 @@ function createRuntime(opts) {
|
|
|
1283
1291
|
systemPrompt,
|
|
1284
1292
|
cwd: opts.cwd,
|
|
1285
1293
|
history,
|
|
1294
|
+
reasoning,
|
|
1286
1295
|
onMessage: (m) => session.append(m),
|
|
1287
1296
|
onReset: () => session.reset(),
|
|
1288
1297
|
onTurnStart: () => checkpoints.beginTurn(),
|
|
@@ -1324,6 +1333,9 @@ function createRuntime(opts) {
|
|
|
1324
1333
|
get modelRef() {
|
|
1325
1334
|
return modelRef;
|
|
1326
1335
|
},
|
|
1336
|
+
get reasoning() {
|
|
1337
|
+
return reasoning;
|
|
1338
|
+
},
|
|
1327
1339
|
agent,
|
|
1328
1340
|
get session() {
|
|
1329
1341
|
return session;
|
|
@@ -1353,12 +1365,16 @@ function createRuntime(opts) {
|
|
|
1353
1365
|
setModel(ref) {
|
|
1354
1366
|
agent.provider = makeProvider(ref);
|
|
1355
1367
|
modelRef = ref;
|
|
1368
|
+
},
|
|
1369
|
+
setReasoning(level) {
|
|
1370
|
+
reasoning = level;
|
|
1371
|
+
agent.reasoning = level;
|
|
1356
1372
|
}
|
|
1357
1373
|
};
|
|
1358
1374
|
}
|
|
1359
1375
|
|
|
1360
1376
|
// src/version.ts
|
|
1361
|
-
var VERSION = true ? "0.4.0-beta.
|
|
1377
|
+
var VERSION = true ? "0.4.0-beta.8" : "0.0.0-dev";
|
|
1362
1378
|
|
|
1363
1379
|
// src/cli.ts
|
|
1364
1380
|
async function main() {
|
|
@@ -1374,13 +1390,13 @@ async function main() {
|
|
|
1374
1390
|
const cwd = process.cwd();
|
|
1375
1391
|
if (args.command === "login") return runLogin(args.loginProvider ?? "bc-cloud", cwd);
|
|
1376
1392
|
if (args.command === "mcp") {
|
|
1377
|
-
const { runMcpCommand } = await import("./mcpCli-
|
|
1378
|
-
const { readSecret } = await import("./login-
|
|
1393
|
+
const { runMcpCommand } = await import("./mcpCli-DZWQPTOS.js");
|
|
1394
|
+
const { readSecret } = await import("./login-JXFORO3J.js");
|
|
1379
1395
|
return runMcpCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
|
|
1380
1396
|
}
|
|
1381
1397
|
if (args.command === "provider") {
|
|
1382
|
-
const { runProviderCommand } = await import("./providerCli-
|
|
1383
|
-
const { readSecret } = await import("./login-
|
|
1398
|
+
const { runProviderCommand } = await import("./providerCli-Q7LRM2NP.js");
|
|
1399
|
+
const { readSecret } = await import("./login-JXFORO3J.js");
|
|
1384
1400
|
return runProviderCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
|
|
1385
1401
|
}
|
|
1386
1402
|
if (args.command === "models") {
|
|
@@ -1397,7 +1413,7 @@ async function main() {
|
|
|
1397
1413
|
}
|
|
1398
1414
|
if (args.print) {
|
|
1399
1415
|
if (!args.prompt) throw new ConfigError('Mode -p butuh tugas, contoh: bccli -p "jelaskan repo ini"');
|
|
1400
|
-
const { serversToStart } = await import("./config-
|
|
1416
|
+
const { serversToStart } = await import("./config-YUNKPCNB.js");
|
|
1401
1417
|
const plan = serversToStart(rt.home, cwd);
|
|
1402
1418
|
for (const s of plan.needTrust) {
|
|
1403
1419
|
console.error(`Server MCP project "${s.name}" dilewati (belum diizinkan; jalankan bccli interaktif sekali untuk menyetujuinya).`);
|
|
@@ -1410,7 +1426,7 @@ async function main() {
|
|
|
1410
1426
|
}
|
|
1411
1427
|
}
|
|
1412
1428
|
if (!process.stdin.isTTY) throw new ConfigError('Mode interaktif butuh terminal. Untuk skrip/CI pakai: bccli -p "tugas"');
|
|
1413
|
-
const { startInteractive } = await import("./ui-
|
|
1429
|
+
const { startInteractive } = await import("./ui-6GTQUJOE.js");
|
|
1414
1430
|
return startInteractive(rt, { initialPrompt: args.prompt, resume: args.resume, version: VERSION });
|
|
1415
1431
|
}
|
|
1416
1432
|
main().then(
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CATALOG,
|
|
4
4
|
fillTemplate
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DX7CZTBB.js";
|
|
6
6
|
import {
|
|
7
7
|
addGlobalServer,
|
|
8
8
|
globalMcpPath,
|
|
9
9
|
readMcpFile,
|
|
10
10
|
removeGlobalServer
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-BFZXRKW5.js";
|
|
12
12
|
import {
|
|
13
13
|
bccliHome
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-2MGINW4O.js";
|
|
15
15
|
|
|
16
16
|
// src/mcpCli.ts
|
|
17
17
|
async function runMcpCommand(args, deps) {
|
|
@@ -13,24 +13,30 @@ import {
|
|
|
13
13
|
hasKey,
|
|
14
14
|
providerName,
|
|
15
15
|
writeGlobalConfig
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-7S6JXQCH.js";
|
|
17
|
+
import {
|
|
18
|
+
REASONING_LEVELS,
|
|
19
|
+
assertReasoningSupported,
|
|
20
|
+
parseReasoningLevel,
|
|
21
|
+
supportedReasoningLevels
|
|
22
|
+
} from "./chunk-CLN4Z5E3.js";
|
|
17
23
|
import {
|
|
18
24
|
Session
|
|
19
25
|
} from "./chunk-SJH3YLW4.js";
|
|
20
26
|
import {
|
|
21
27
|
CATALOG,
|
|
22
28
|
fillTemplate
|
|
23
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-DX7CZTBB.js";
|
|
24
30
|
import {
|
|
25
31
|
addGlobalServer,
|
|
26
32
|
globalMcpPath,
|
|
27
33
|
readMcpFile,
|
|
28
34
|
removeGlobalServer
|
|
29
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-BFZXRKW5.js";
|
|
30
36
|
import {
|
|
31
37
|
PRESETS,
|
|
32
38
|
removeCredential
|
|
33
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-2MGINW4O.js";
|
|
34
40
|
|
|
35
41
|
// src/ui/index.tsx
|
|
36
42
|
import { render } from "ink";
|
|
@@ -47,6 +53,7 @@ import { useCallback, useEffect as useEffect2, useRef, useState as useState8 } f
|
|
|
47
53
|
var SLASH_COMMANDS = [
|
|
48
54
|
{ name: "help", description: "daftar perintah dan pintasan" },
|
|
49
55
|
{ name: "model", description: "ganti model" },
|
|
56
|
+
{ name: "reasoning", description: "atur reasoning: auto/off/low/medium/high/max" },
|
|
50
57
|
{ name: "provider", description: "tambah/pilih provider AI" },
|
|
51
58
|
{ name: "mcp", description: "pasang/kelola server MCP" },
|
|
52
59
|
{ name: "new", description: "sesi baru (sesi lama tetap tersimpan)" },
|
|
@@ -272,7 +279,7 @@ function ListPicker({ title, items, onPick }) {
|
|
|
272
279
|
useInput2((input, key) => {
|
|
273
280
|
if (key.upArrow) setIndex(Math.max(0, cursor - 1));
|
|
274
281
|
else if (key.downArrow) setIndex(Math.min(shown.length - 1, cursor + 1));
|
|
275
|
-
else if (key.return) onPick(shown[cursor]?.id);
|
|
282
|
+
else if (key.return && !shown[cursor]?.disabled) onPick(shown[cursor]?.id);
|
|
276
283
|
else if (key.escape) onPick(void 0);
|
|
277
284
|
else if (key.backspace || key.delete) {
|
|
278
285
|
setFilter((f) => f.slice(0, -1));
|
|
@@ -285,7 +292,7 @@ function ListPicker({ title, items, onPick }) {
|
|
|
285
292
|
const start = Math.max(0, Math.min(cursor - 5, shown.length - VISIBLE));
|
|
286
293
|
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: [
|
|
287
294
|
/* @__PURE__ */ jsx3(Text3, { bold: true, children: `${title} (\u2191\u2193 enter \xB7 ketik untuk menyaring${filter ? `: ${filter}` : ""} \xB7 esc batal)` }),
|
|
288
|
-
shown.slice(start, start + VISIBLE).map((item, i) => /* @__PURE__ */ jsxs2(Text3, { color: start + i === cursor ? color("green") : void 0, children: [
|
|
295
|
+
shown.slice(start, start + VISIBLE).map((item, i) => /* @__PURE__ */ jsxs2(Text3, { color: start + i === cursor && !item.disabled ? color("green") : void 0, dimColor: item.disabled, children: [
|
|
289
296
|
`${start + i === cursor ? "\u203A" : " "} ${item.label}`,
|
|
290
297
|
item.hint ? /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: ` ${item.hint}` }) : null
|
|
291
298
|
] }, item.id)),
|
|
@@ -533,9 +540,9 @@ var LABEL = {
|
|
|
533
540
|
function formatTokens(n) {
|
|
534
541
|
return n >= 1e3 ? `${Math.round(n / 1e3)}k` : String(n);
|
|
535
542
|
}
|
|
536
|
-
function StatusBar({ mode, tokens, busy, model }) {
|
|
543
|
+
function StatusBar({ mode, tokens, busy, model, reasoning = "auto" }) {
|
|
537
544
|
const danger = mode === "allowAll";
|
|
538
|
-
return /* @__PURE__ */ jsx10(Text10, { color: danger ? color("red") : void 0, dimColor: !danger, children: ` ${LABEL[mode]}${model ? ` \xB7 ${model}` : ""} \xB7 shift+tab ganti mode \xB7 ${formatTokens(tokens)} token \xB7 ${busy ? "esc batal" : "/ perintah"}` });
|
|
545
|
+
return /* @__PURE__ */ jsx10(Text10, { color: danger ? color("red") : void 0, dimColor: !danger, children: ` ${LABEL[mode]}${model ? ` \xB7 ${model}` : ""} \xB7 reasoning: ${reasoning} \xB7 shift+tab ganti mode \xB7 ${formatTokens(tokens)} token \xB7 ${busy ? "esc batal" : "/ perintah"}` });
|
|
539
546
|
}
|
|
540
547
|
|
|
541
548
|
// src/ui/McpMenu.tsx
|
|
@@ -729,6 +736,7 @@ function App({ runtime, initialPrompt, version }) {
|
|
|
729
736
|
const [busy, setBusy] = useState8(false);
|
|
730
737
|
const [startedAt, setStartedAt] = useState8(0);
|
|
731
738
|
const [mode, setMode] = useState8(runtime.agent.permissions.mode);
|
|
739
|
+
const [reasoning, setReasoning] = useState8(runtime.reasoning);
|
|
732
740
|
const [tokens, setTokens] = useState8(runtime.agent.totalUsage.inputTokens + runtime.agent.totalUsage.outputTokens);
|
|
733
741
|
const [asks, setAsks] = useState8([]);
|
|
734
742
|
const pending = asks[0] ?? null;
|
|
@@ -814,6 +822,41 @@ function App({ runtime, initialPrompt, version }) {
|
|
|
814
822
|
setBusy(false);
|
|
815
823
|
return;
|
|
816
824
|
}
|
|
825
|
+
case "reasoning": {
|
|
826
|
+
const apply = (value) => {
|
|
827
|
+
try {
|
|
828
|
+
const level = parseReasoningLevel(value, "/reasoning");
|
|
829
|
+
const providerId2 = runtime.modelRef.slice(0, runtime.modelRef.indexOf("/"));
|
|
830
|
+
assertReasoningSupported(providerId2, level);
|
|
831
|
+
runtime.setReasoning(level);
|
|
832
|
+
writeGlobalConfig({ reasoning: level }, runtime.env);
|
|
833
|
+
setReasoning(level);
|
|
834
|
+
notice(`Reasoning: ${level} (tersimpan sebagai default)`);
|
|
835
|
+
} catch (error) {
|
|
836
|
+
notice(error.message, "error");
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
if (args) {
|
|
840
|
+
apply(args);
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
const providerId = runtime.modelRef.slice(0, runtime.modelRef.indexOf("/"));
|
|
844
|
+
const supported = supportedReasoningLevels(providerId);
|
|
845
|
+
setListPicker({
|
|
846
|
+
title: "Reasoning",
|
|
847
|
+
items: REASONING_LEVELS.map((level) => ({
|
|
848
|
+
id: level,
|
|
849
|
+
label: level === "auto" ? "Auto (model default)" : level.charAt(0).toUpperCase() + level.slice(1),
|
|
850
|
+
disabled: !supported.includes(level),
|
|
851
|
+
hint: supported.includes(level) ? void 0 : "tidak didukung provider ini"
|
|
852
|
+
})),
|
|
853
|
+
onPick: (id) => {
|
|
854
|
+
setListPicker(null);
|
|
855
|
+
if (id) apply(id);
|
|
856
|
+
}
|
|
857
|
+
});
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
817
860
|
case "model": {
|
|
818
861
|
if (args) {
|
|
819
862
|
try {
|
|
@@ -1325,7 +1368,7 @@ ${t.output}`);
|
|
|
1325
1368
|
/* @__PURE__ */ jsx15(TodoList, { items: todos }),
|
|
1326
1369
|
queued.map((q, i) => /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: ` \u23F3 antri: ${q}` }, `${i}-${q}`)),
|
|
1327
1370
|
/* @__PURE__ */ jsx15(PromptInput, { disabled: !!pending || !!picker || !!providerMenu || !!prompt || !!planAsk || !!mcpMenu || !!listPicker, history, cwd: runtime.cwd, onSubmit: onPrompt, extraCommands }),
|
|
1328
|
-
/* @__PURE__ */ jsx15(StatusBar, { mode, tokens, busy, model: modelLabel })
|
|
1371
|
+
/* @__PURE__ */ jsx15(StatusBar, { mode, tokens, busy, model: modelLabel, reasoning })
|
|
1329
1372
|
] });
|
|
1330
1373
|
}
|
|
1331
1374
|
|
|
@@ -1348,7 +1391,7 @@ async function startInteractive(rt, opts) {
|
|
|
1348
1391
|
if (chosen) rt.resume(chosen.session);
|
|
1349
1392
|
}
|
|
1350
1393
|
}
|
|
1351
|
-
const { serversToStart, setProjectTrust } = await import("./config-
|
|
1394
|
+
const { serversToStart, setProjectTrust } = await import("./config-YUNKPCNB.js");
|
|
1352
1395
|
const plan = serversToStart(rt.home, rt.cwd);
|
|
1353
1396
|
if (plan.needTrust.length) {
|
|
1354
1397
|
const { createInterface } = await import("readline/promises");
|
package/package.json
CHANGED