@botconnector/bccli 0.4.9 → 0.4.11
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/{acp-VEXFXT5P.js → acp-IPHWC6CO.js} +20 -5
- package/dist/acp.d.ts +17 -1
- package/dist/args-K5AJFDCZ.js +13 -0
- package/dist/args.d.ts +6 -0
- package/dist/budget.d.ts +4 -1
- package/dist/{chunk-2YG6L3YO.js → chunk-2DFY43RP.js} +2 -2
- package/dist/{chunk-KREGVQ63.js → chunk-6BXW7DGQ.js} +47 -18
- package/dist/{chunk-WSSJH765.js → chunk-6KZIOICR.js} +1 -1
- package/dist/{chunk-OUJRD7GG.js → chunk-6M5T7N7A.js} +8 -3
- package/dist/{chunk-DRJSANKH.js → chunk-C2FUGQJX.js} +9 -7
- package/dist/{chunk-OETLWNGS.js → chunk-F54FDJBD.js} +3 -3
- package/dist/{chunk-XCVYR5BK.js → chunk-G5TG43R4.js} +15 -1
- package/dist/{chunk-RRECJTOG.js → chunk-IHQGXDSG.js} +1 -1
- package/dist/{chunk-AWBEZY4D.js → chunk-JFYQCPXL.js} +7 -5
- package/dist/{chunk-6H6MPG7L.js → chunk-MBAMDCCV.js} +23 -9
- package/dist/{chunk-HCW67S5M.js → chunk-N6APAYSF.js} +1 -1
- package/dist/{chunk-TLCFBQ6E.js → chunk-NT2G5FSX.js} +2 -2
- package/dist/{chunk-CSIQDFEF.js → chunk-OAXD3X4R.js} +34 -50
- package/dist/{chunk-EOJNFGOP.js → chunk-OOOS5RCT.js} +98 -28
- package/dist/{chunk-Z2ELYJ5O.js → chunk-WSZF2CTU.js} +11 -4
- package/dist/{chunk-62UTSCWF.js → chunk-X24APPXO.js} +1 -1
- package/dist/{chunk-EAR2C6TS.js → chunk-XZ2TI5HV.js} +1 -1
- package/dist/{chunk-HPYI7L4W.js → chunk-Y6AZGGH7.js} +4 -4
- package/dist/{chunk-WFZKJY3R.js → chunk-YYTFJUO2.js} +3 -2
- package/dist/cli.js +40 -40
- package/dist/{completion-FETH4OGC.js → completion-QVDGAYUY.js} +1 -1
- package/dist/{config-KR5JI5RA.js → config-7TQ2KVVX.js} +3 -3
- package/dist/{config-RVMC23W3.js → config-RZY3XQZJ.js} +2 -2
- package/dist/{ghBotCli-Z6GWXCJ6.js → ghBotCli-HHJ4ANTH.js} +18 -16
- package/dist/{integrationCli-GPRR6J6W.js → integrationCli-LNNZDGZX.js} +40 -5
- package/dist/{login-DFSN77L3.js → login-MQEZGF2C.js} +6 -4
- package/dist/login.d.ts +2 -0
- package/dist/{mcpCli-64P3SVUE.js → mcpCli-CUIOYJ2A.js} +22 -7
- package/dist/{modelsCli-PFQY3G2Q.js → modelsCli-AAFHFI4H.js} +6 -6
- package/dist/{oauthLogin-NR22NWEV.js → oauthLogin-YFL2N4QA.js} +1 -1
- package/dist/{pluginsCli-UKRJ3AHN.js → pluginsCli-2QXXFLQA.js} +6 -2
- package/dist/{prCli-6FCI36AJ.js → prCli-KSA73RCS.js} +1 -1
- package/dist/print.d.ts +1 -0
- package/dist/providerCli-TXMVPSW5.js +15 -0
- package/dist/sdk.js +196 -87
- package/dist/{serve-PKUTKQQT.js → serve-EIQHEUYD.js} +3 -3
- package/dist/{serve-JYXPQAVY.js → serve-QYDBFTHC.js} +16 -16
- package/dist/session-CQCQ7KAP.js +12 -0
- package/dist/setup-DBSGMWHM.js +24 -0
- package/dist/setup.d.ts +5 -0
- package/dist/{statsCli-FR7GOKWO.js → statsCli-EHNJIQ2Z.js} +2 -2
- package/dist/tools/bash.d.ts +2 -0
- package/dist/{transferCli-GIE4MEJ4.js → transferCli-IXJ2O74Q.js} +4 -4
- package/dist/{ui-NZVOCQSU.js → ui-A2LASWDK.js} +14 -14
- package/dist/{update-DIYDD7LT.js → update-TR62JV3A.js} +2 -2
- package/package.json +1 -1
- package/dist/args-6XMUZDAK.js +0 -13
- package/dist/providerCli-PBSZECBM.js +0 -15
- package/dist/session-XABMBIIF.js +0 -12
- package/dist/setup-CLPQLTM7.js +0 -24
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-PSO7R5AD.js";
|
|
5
5
|
import {
|
|
6
6
|
t
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-G5TG43R4.js";
|
|
8
8
|
|
|
9
9
|
// src/tools/bash.ts
|
|
10
10
|
import { spawn } from "child_process";
|
|
@@ -34,60 +34,39 @@ function darwinProfile(cwd, network) {
|
|
|
34
34
|
network ? "(allow network*)" : "(deny network*)"
|
|
35
35
|
].join("\n");
|
|
36
36
|
}
|
|
37
|
+
function bwrapArgv(cwd, network, command) {
|
|
38
|
+
return [
|
|
39
|
+
"bwrap",
|
|
40
|
+
"--ro-bind",
|
|
41
|
+
"/",
|
|
42
|
+
"/",
|
|
43
|
+
"--dev-bind",
|
|
44
|
+
"/dev",
|
|
45
|
+
"/dev",
|
|
46
|
+
"--proc",
|
|
47
|
+
"/proc",
|
|
48
|
+
"--bind",
|
|
49
|
+
cwd,
|
|
50
|
+
cwd,
|
|
51
|
+
"--tmpfs",
|
|
52
|
+
"/tmp",
|
|
53
|
+
"--die-with-parent",
|
|
54
|
+
...network ? [] : ["--unshare-net"],
|
|
55
|
+
"--",
|
|
56
|
+
"/bin/bash",
|
|
57
|
+
"-c",
|
|
58
|
+
command
|
|
59
|
+
];
|
|
60
|
+
}
|
|
37
61
|
function sandboxArgv(command, opts) {
|
|
38
62
|
if (opts.platform === "darwin") {
|
|
39
63
|
return ["sandbox-exec", "-p", darwinProfile(opts.cwd, opts.network), "/bin/bash", "-c", command];
|
|
40
64
|
}
|
|
41
65
|
if (opts.platform === "linux") {
|
|
42
|
-
return
|
|
43
|
-
"bwrap",
|
|
44
|
-
"--ro-bind",
|
|
45
|
-
"/",
|
|
46
|
-
"/",
|
|
47
|
-
"--dev-bind",
|
|
48
|
-
"/dev",
|
|
49
|
-
"/dev",
|
|
50
|
-
"--proc",
|
|
51
|
-
"/proc",
|
|
52
|
-
"--bind",
|
|
53
|
-
opts.cwd,
|
|
54
|
-
opts.cwd,
|
|
55
|
-
"--tmpfs",
|
|
56
|
-
"/tmp",
|
|
57
|
-
"--die-with-parent",
|
|
58
|
-
...opts.network ? [] : ["--unshare-net"],
|
|
59
|
-
"--",
|
|
60
|
-
"/bin/bash",
|
|
61
|
-
"-c",
|
|
62
|
-
command
|
|
63
|
-
];
|
|
66
|
+
return bwrapArgv(opts.cwd, opts.network, command);
|
|
64
67
|
}
|
|
65
68
|
if (opts.platform === "win32" && (opts.wslBwrap || process.env.BCCLI_WIN32_WSL_SANDBOX === "1")) {
|
|
66
|
-
|
|
67
|
-
return [
|
|
68
|
-
"wsl.exe",
|
|
69
|
-
"--",
|
|
70
|
-
"bwrap",
|
|
71
|
-
"--ro-bind",
|
|
72
|
-
"/",
|
|
73
|
-
"/",
|
|
74
|
-
"--dev-bind",
|
|
75
|
-
"/dev",
|
|
76
|
-
"/dev",
|
|
77
|
-
"--proc",
|
|
78
|
-
"/proc",
|
|
79
|
-
"--bind",
|
|
80
|
-
wslCwd,
|
|
81
|
-
wslCwd,
|
|
82
|
-
"--tmpfs",
|
|
83
|
-
"/tmp",
|
|
84
|
-
"--die-with-parent",
|
|
85
|
-
...opts.network ? [] : ["--unshare-net"],
|
|
86
|
-
"--",
|
|
87
|
-
"/bin/bash",
|
|
88
|
-
"-c",
|
|
89
|
-
command
|
|
90
|
-
];
|
|
69
|
+
return ["wsl.exe", "--", ...bwrapArgv(winPathToWsl(opts.cwd), opts.network, command)];
|
|
91
70
|
}
|
|
92
71
|
return void 0;
|
|
93
72
|
}
|
|
@@ -156,7 +135,7 @@ function killAllCommands() {
|
|
|
156
135
|
}
|
|
157
136
|
var backgrounds = /* @__PURE__ */ new Map();
|
|
158
137
|
var nextBackgroundId = 1;
|
|
159
|
-
function startBackground(command, cwd, env, shell) {
|
|
138
|
+
function startBackground(command, cwd, env, shell, maxRetained) {
|
|
160
139
|
const child = spawnChild(command, cwd, env, shell);
|
|
161
140
|
const task = {
|
|
162
141
|
id: nextBackgroundId++,
|
|
@@ -177,6 +156,10 @@ function startBackground(command, cwd, env, shell) {
|
|
|
177
156
|
if (child.pid !== void 0) killProcessTree(child.pid);
|
|
178
157
|
};
|
|
179
158
|
backgrounds.set(task.id, task);
|
|
159
|
+
for (const [id, other] of backgrounds) {
|
|
160
|
+
if (backgrounds.size <= maxRetained) break;
|
|
161
|
+
if (id !== task.id && other.status === "exited") backgrounds.delete(id);
|
|
162
|
+
}
|
|
180
163
|
const onData = (data) => {
|
|
181
164
|
let s = data;
|
|
182
165
|
if (task.head.length < HALF) {
|
|
@@ -385,6 +368,7 @@ var SHELL_NOTE = {
|
|
|
385
368
|
function createBashTool(options = {}) {
|
|
386
369
|
const offline = options.networkPolicy === "offline";
|
|
387
370
|
const sandbox = options.sandbox === true;
|
|
371
|
+
const maxRetained = options.maxRetainedTasks ?? 50;
|
|
388
372
|
const platform = options.platform ?? process.platform;
|
|
389
373
|
const shell = resolveShell({ platform, env: process.env, exists: existsSync2, ...options.shellDeps });
|
|
390
374
|
const childEnv = offline ? offlineEnv() : void 0;
|
|
@@ -431,7 +415,7 @@ Network access is off (networkPolicy "offline"): internet commands such as curl,
|
|
|
431
415
|
}
|
|
432
416
|
if (input.background) {
|
|
433
417
|
if (!input.command) return { output: 'The "command" argument is required to start a background task.', isError: true };
|
|
434
|
-
const task = startBackground(exec, ctx.cwd, childEnv, shell);
|
|
418
|
+
const task = startBackground(exec, ctx.cwd, childEnv, shell, maxRetained);
|
|
435
419
|
return {
|
|
436
420
|
output: `Background task #${task.id} started: ${input.command}
|
|
437
421
|
Poll it with {task_id: ${task.id}}; stop it with {task_id: ${task.id}, kill: true}.`
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
reasoningPayload
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XZ2TI5HV.js";
|
|
5
5
|
import {
|
|
6
6
|
t
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-G5TG43R4.js";
|
|
8
8
|
|
|
9
9
|
// src/provider.ts
|
|
10
10
|
import OpenAI from "openai";
|
|
@@ -78,6 +78,17 @@ function outputReasoningSummary(items) {
|
|
|
78
78
|
}).map((part) => part && typeof part === "object" && "text" in part && typeof part.text === "string" ? part.text : "").filter(Boolean).join("\n");
|
|
79
79
|
}
|
|
80
80
|
var retryable = (status) => status === 429 || status >= 500;
|
|
81
|
+
function httpIdleMs() {
|
|
82
|
+
const raw = Number(process.env.BCCLI_HTTP_IDLE_TIMEOUT_MS);
|
|
83
|
+
return Number.isFinite(raw) && raw > 0 ? raw : 6e4;
|
|
84
|
+
}
|
|
85
|
+
function statusHint(status) {
|
|
86
|
+
if (status === 401 || status === 403) return t("The API key was rejected. Check the key for this provider (bccli login) or its API key environment variable.");
|
|
87
|
+
if (status === 404) return t("Model or endpoint not found. Check the model name and the provider base URL.");
|
|
88
|
+
if (status === 429) return t("Rate limit reached. Wait a moment, or switch model with /model.");
|
|
89
|
+
if (status >= 500) return t("The provider is having trouble. Try again, or switch model with /model.");
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
81
92
|
function detectRepetition(text) {
|
|
82
93
|
const tail = text.slice(-600);
|
|
83
94
|
for (let len = 1; len <= 12; len++) {
|
|
@@ -120,7 +131,7 @@ var toUsage = (u) => u ? {
|
|
|
120
131
|
...u.prompt_tokens_details?.cached_tokens != null ? { cachedInputTokens: u.prompt_tokens_details.cached_tokens } : {},
|
|
121
132
|
...u.prompt_tokens_details?.cache_write_tokens != null ? { cacheWriteTokens: u.prompt_tokens_details.cache_write_tokens } : {}
|
|
122
133
|
} : void 0;
|
|
123
|
-
async function readStream(res, onText, onThinking) {
|
|
134
|
+
async function readStream(res, onText, onThinking, signal) {
|
|
124
135
|
let text = "";
|
|
125
136
|
let thinking = "";
|
|
126
137
|
const splitter = new ThinkSplitter();
|
|
@@ -137,6 +148,7 @@ async function readStream(res, onText, onThinking) {
|
|
|
137
148
|
};
|
|
138
149
|
let usage;
|
|
139
150
|
let finishReason;
|
|
151
|
+
let sawDone = false;
|
|
140
152
|
const calls = [];
|
|
141
153
|
const byIndex = /* @__PURE__ */ new Map();
|
|
142
154
|
let current;
|
|
@@ -146,7 +158,11 @@ async function readStream(res, onText, onThinking) {
|
|
|
146
158
|
const handle = (line) => {
|
|
147
159
|
if (!line.startsWith("data:")) return;
|
|
148
160
|
const data = line.slice(5).trim();
|
|
149
|
-
if (!data
|
|
161
|
+
if (!data) return;
|
|
162
|
+
if (data === "[DONE]") {
|
|
163
|
+
sawDone = true;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
150
166
|
let event;
|
|
151
167
|
try {
|
|
152
168
|
event = JSON.parse(data);
|
|
@@ -175,18 +191,45 @@ async function readStream(res, onText, onThinking) {
|
|
|
175
191
|
if (tc.function?.arguments) target.arguments += tc.function.arguments;
|
|
176
192
|
}
|
|
177
193
|
};
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
194
|
+
const iterator = res.body[Symbol.asyncIterator]();
|
|
195
|
+
const idle = httpIdleMs();
|
|
196
|
+
const onAbort = () => void iterator.return?.();
|
|
197
|
+
if (signal?.aborted) onAbort();
|
|
198
|
+
else signal?.addEventListener("abort", onAbort);
|
|
199
|
+
try {
|
|
200
|
+
for (; ; ) {
|
|
201
|
+
let timer;
|
|
202
|
+
const stalled = new Promise((_, reject) => {
|
|
203
|
+
timer = setTimeout(
|
|
204
|
+
() => reject(new ProviderError(t("The provider stopped sending data for {seconds}s. The answer above may be incomplete; try again.", { seconds: String(Math.round(idle / 1e3)) }))),
|
|
205
|
+
idle
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
let step;
|
|
209
|
+
try {
|
|
210
|
+
step = await Promise.race([iterator.next(), stalled]);
|
|
211
|
+
} finally {
|
|
212
|
+
if (timer) clearTimeout(timer);
|
|
213
|
+
}
|
|
214
|
+
if (step.done) break;
|
|
215
|
+
buffer += decoder.decode(step.value, { stream: true });
|
|
216
|
+
let newline = buffer.indexOf("\n");
|
|
217
|
+
while (newline >= 0 && loopAt < 0) {
|
|
218
|
+
handle(buffer.slice(0, newline).trim());
|
|
219
|
+
buffer = buffer.slice(newline + 1);
|
|
220
|
+
newline = buffer.indexOf("\n");
|
|
221
|
+
}
|
|
222
|
+
if (loopAt >= 0) return { text: text.slice(0, loopAt), toolCalls: [], thinking: thinking || void 0, usage, finishReason: "repetition" };
|
|
223
|
+
}
|
|
224
|
+
} finally {
|
|
225
|
+
signal?.removeEventListener("abort", onAbort);
|
|
226
|
+
void iterator.return?.();
|
|
187
227
|
}
|
|
188
228
|
handle(buffer.trim());
|
|
189
229
|
emit(splitter.flush());
|
|
230
|
+
if (!sawDone && !finishReason) {
|
|
231
|
+
throw new ProviderError(t("The response ended before it finished (no finish_reason or [DONE]). The answer above is incomplete; try again."));
|
|
232
|
+
}
|
|
190
233
|
const toolCalls = calls.map((call, index) => ({ ...call, id: call.id || `call_${index}` }));
|
|
191
234
|
return { text, toolCalls, thinking: thinking || void 0, usage, finishReason };
|
|
192
235
|
}
|
|
@@ -397,7 +440,7 @@ function hasPendingProgrammaticReplay(messages) {
|
|
|
397
440
|
}
|
|
398
441
|
return pending;
|
|
399
442
|
}
|
|
400
|
-
async function readResponsesStream(res, onText, onThinking) {
|
|
443
|
+
async function readResponsesStream(res, onText, onThinking, signal) {
|
|
401
444
|
let text = "";
|
|
402
445
|
let thinking = "";
|
|
403
446
|
let usage;
|
|
@@ -499,17 +542,28 @@ async function readResponsesStream(res, onText, onThinking) {
|
|
|
499
542
|
);
|
|
500
543
|
}
|
|
501
544
|
};
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
545
|
+
const iterator = res.body[Symbol.asyncIterator]();
|
|
546
|
+
const onAbort = () => void iterator.return?.();
|
|
547
|
+
if (signal?.aborted) onAbort();
|
|
548
|
+
else signal?.addEventListener("abort", onAbort);
|
|
549
|
+
try {
|
|
550
|
+
for (; ; ) {
|
|
551
|
+
const step = await iterator.next();
|
|
552
|
+
if (step.done) break;
|
|
553
|
+
buffer += decoder.decode(step.value, { stream: true });
|
|
554
|
+
let newline = buffer.indexOf("\n");
|
|
555
|
+
while (newline >= 0 && loopAt < 0) {
|
|
556
|
+
handle(buffer.slice(0, newline).trim());
|
|
557
|
+
buffer = buffer.slice(newline + 1);
|
|
558
|
+
newline = buffer.indexOf("\n");
|
|
559
|
+
}
|
|
560
|
+
if (loopAt >= 0) {
|
|
561
|
+
return { text: text.slice(0, loopAt), toolCalls: [], usage, finishReason: "repetition" };
|
|
562
|
+
}
|
|
512
563
|
}
|
|
564
|
+
} finally {
|
|
565
|
+
signal?.removeEventListener("abort", onAbort);
|
|
566
|
+
void iterator.return?.();
|
|
513
567
|
}
|
|
514
568
|
handle(buffer.trim());
|
|
515
569
|
return {
|
|
@@ -882,12 +936,26 @@ function createProvider(options) {
|
|
|
882
936
|
await sleep(delay, signal);
|
|
883
937
|
}
|
|
884
938
|
let res;
|
|
939
|
+
const idleAbort = new AbortController();
|
|
940
|
+
const forwardAbort = () => idleAbort.abort(signal?.reason);
|
|
941
|
+
if (signal?.aborted) forwardAbort();
|
|
942
|
+
else signal?.addEventListener("abort", forwardAbort);
|
|
943
|
+
const idle = httpIdleMs();
|
|
944
|
+
const headerTimer = setTimeout(() => idleAbort.abort(new Error("idle-timeout")), idle);
|
|
885
945
|
try {
|
|
886
|
-
res = await doFetch(`${baseURL}${path}`, { method: "POST", headers, body: JSON.stringify(body), signal });
|
|
946
|
+
res = await doFetch(`${baseURL}${path}`, { method: "POST", headers, body: JSON.stringify(body), signal: idleAbort.signal });
|
|
887
947
|
} catch (error) {
|
|
888
948
|
if (signal?.aborted) throw error;
|
|
949
|
+
if (idleAbort.signal.aborted) {
|
|
950
|
+
throw new ProviderError(
|
|
951
|
+
t("The provider did not respond within {seconds}s. Check the connection, then try again.", { seconds: String(Math.round(idle / 1e3)) })
|
|
952
|
+
);
|
|
953
|
+
}
|
|
889
954
|
lastError = new ProviderError(t("Cannot connect to {url}: {error}", { url: baseURL, error: error.message }));
|
|
890
955
|
continue;
|
|
956
|
+
} finally {
|
|
957
|
+
clearTimeout(headerTimer);
|
|
958
|
+
signal?.removeEventListener("abort", forwardAbort);
|
|
891
959
|
}
|
|
892
960
|
if (res.ok) return res;
|
|
893
961
|
const retryHeader = res.headers.get("retry-after");
|
|
@@ -896,7 +964,9 @@ function createProvider(options) {
|
|
|
896
964
|
if (Number.isFinite(secs) && secs > 0 && secs <= 30) retryAfterWaitMs = Math.ceil(secs * 1e3);
|
|
897
965
|
}
|
|
898
966
|
const text = await res.text().catch(() => "");
|
|
899
|
-
|
|
967
|
+
const raw = t("{status} from {url}: {message}", { status: res.status, url: baseURL, message: errorMessage(text) });
|
|
968
|
+
const hint = statusHint(res.status);
|
|
969
|
+
lastError = new ProviderError(hint ? `${hint} (${raw})` : raw, res.status);
|
|
900
970
|
const deterministicQuota429 = res.status === 429 && /"code"\s*:\s*"(?:luna_monthly_quota_exhausted|plan_allowance_exhausted)"/i.test(text);
|
|
901
971
|
if (!retryable(res.status) || deterministicQuota429) throw lastError;
|
|
902
972
|
}
|
|
@@ -937,7 +1007,7 @@ function createProvider(options) {
|
|
|
937
1007
|
);
|
|
938
1008
|
if ((res2.headers.get("content-type") ?? "").includes("application/json")) return readResponsesJson(res2, onThinking);
|
|
939
1009
|
if (!res2.body) throw new ProviderError(t("Empty response from the provider"));
|
|
940
|
-
return readResponsesStream(res2, onText, onThinking);
|
|
1010
|
+
return readResponsesStream(res2, onText, onThinking, signal);
|
|
941
1011
|
}
|
|
942
1012
|
const res = await post(
|
|
943
1013
|
"/chat/completions",
|
|
@@ -946,7 +1016,7 @@ function createProvider(options) {
|
|
|
946
1016
|
);
|
|
947
1017
|
if ((res.headers.get("content-type") ?? "").includes("application/json")) return readJson(res, onText, onThinking);
|
|
948
1018
|
if (!res.body) throw new ProviderError(t("Empty response from the provider"));
|
|
949
|
-
return readStream(res, onText, onThinking);
|
|
1019
|
+
return readStream(res, onText, onThinking, signal);
|
|
950
1020
|
},
|
|
951
1021
|
async listModels() {
|
|
952
1022
|
const res = await doFetch(`${baseURL}/models`, { headers });
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
MODE_ORDER
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YYTFJUO2.js";
|
|
5
5
|
import {
|
|
6
6
|
REASONING_LEVELS,
|
|
7
7
|
isReasoningLevel
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XZ2TI5HV.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigError
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-C2FUGQJX.js";
|
|
12
12
|
import {
|
|
13
13
|
parseLang,
|
|
14
14
|
t
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-G5TG43R4.js";
|
|
16
16
|
|
|
17
17
|
// src/args.ts
|
|
18
18
|
import { parseArgs } from "util";
|
|
@@ -112,6 +112,7 @@ Options:
|
|
|
112
112
|
-r, --resume pick a session to continue
|
|
113
113
|
--allow-all run all tools without asking for permission
|
|
114
114
|
--allowed-tools <a,b> tools allowed without asking: bash, edit, fetch
|
|
115
|
+
--fail-on-tool-error with -p: exit 1 when any tool call fails (for CI)
|
|
115
116
|
-w, --worktree <name> run in git worktree ../<repo>.worktrees/<name> (created, or reused if it exists)
|
|
116
117
|
--output-format <fmt> text | json | stream-json for -p (machine-readable output)
|
|
117
118
|
--permission-mode <mode> default | acceptEdits | plan | allowAll
|
|
@@ -137,6 +138,9 @@ function parseCliArgs(argv) {
|
|
|
137
138
|
continue: { type: "boolean", short: "c" },
|
|
138
139
|
resume: { type: "boolean", short: "r" },
|
|
139
140
|
"allow-all": { type: "boolean" },
|
|
141
|
+
command: { type: "string" },
|
|
142
|
+
args: { type: "string" },
|
|
143
|
+
"fail-on-tool-error": { type: "boolean" },
|
|
140
144
|
"allowed-tools": { type: "string" },
|
|
141
145
|
worktree: { type: "string", short: "w" },
|
|
142
146
|
"output-format": { type: "string" },
|
|
@@ -210,6 +214,7 @@ function parseCliArgs(argv) {
|
|
|
210
214
|
continue: !!values.continue,
|
|
211
215
|
resume: !!values.resume,
|
|
212
216
|
allowAll: !!values["allow-all"],
|
|
217
|
+
failOnToolError: !!values["fail-on-tool-error"],
|
|
213
218
|
allowedTools: (values["allowed-tools"] ?? "").split(",").map((s) => s.trim()).filter(Boolean),
|
|
214
219
|
worktree: values.worktree,
|
|
215
220
|
outputFormat,
|
|
@@ -221,6 +226,8 @@ function parseCliArgs(argv) {
|
|
|
221
226
|
logout: !!values.logout,
|
|
222
227
|
subArgs: ["models", "plugins", "gh-bot", "provider", "mcp", "connect", "disconnect", "integrations", "completion", "stats", "export", "import", "pr"].includes(command) ? rest : [],
|
|
223
228
|
url: values.url,
|
|
229
|
+
stdioCommand: values.command,
|
|
230
|
+
stdioArgs: values.args,
|
|
224
231
|
name: values.name,
|
|
225
232
|
keyEnv: values["key-env"],
|
|
226
233
|
values: values.value ?? [],
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
hasKey,
|
|
4
4
|
providerName
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-X24APPXO.js";
|
|
6
6
|
import {
|
|
7
7
|
createProvider
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-OOOS5RCT.js";
|
|
9
9
|
import {
|
|
10
10
|
PRESETS,
|
|
11
11
|
readCredentials
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-C2FUGQJX.js";
|
|
13
13
|
import {
|
|
14
14
|
t
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-G5TG43R4.js";
|
|
16
16
|
|
|
17
17
|
// src/models.ts
|
|
18
18
|
function order(ids) {
|
|
@@ -94,7 +94,7 @@ var Permissions = class {
|
|
|
94
94
|
}
|
|
95
95
|
/** Rules that "[a] allow for this session" would add; undefined when it must always be asked. */
|
|
96
96
|
rulesFor(req) {
|
|
97
|
-
if (requiresSensitiveToolApproval(req) && (req.kind === "read" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
|
|
97
|
+
if (requiresSensitiveToolApproval(req) && (req.kind === "read" || req.kind === "edit" || process.env.BC_TOOL_POLICY_ENFORCE === "true"))
|
|
98
98
|
return void 0;
|
|
99
99
|
if (req.kind === "edit") return this.editInProject(req.target) ? ["edit(project)"] : void 0;
|
|
100
100
|
if (req.kind === "fetch") {
|
|
@@ -116,7 +116,8 @@ var Permissions = class {
|
|
|
116
116
|
}
|
|
117
117
|
check(req) {
|
|
118
118
|
if (this.mode === "plan" && req.kind !== "read") return "deny";
|
|
119
|
-
if (req.kind === "read" && this.mode !== "allowAll" && requiresSensitiveToolApproval(req))
|
|
119
|
+
if ((req.kind === "read" || req.kind === "edit") && this.mode !== "allowAll" && requiresSensitiveToolApproval(req))
|
|
120
|
+
return "ask";
|
|
120
121
|
if (process.env.BC_TOOL_POLICY_ENFORCE === "true" && requiresSensitiveToolApproval(req)) return "ask";
|
|
121
122
|
if (req.kind === "read") return "allow";
|
|
122
123
|
if (this.mode === "allowAll") return "allow";
|