@botconnector/bccli 0.4.0-beta.24 → 0.4.0-beta.26

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.
@@ -236,7 +236,40 @@ function responseInputFromMessages(messages) {
236
236
  var LUNA_TOOL_SEARCH_MIN_MCP_TOOLS = 20;
237
237
  var LUNA_TOOL_SEARCH_MIN_MCP_SCHEMA_CHARS = 32e3;
238
238
  var LUNA_PTC_SAFE_FUNCTIONS = /* @__PURE__ */ new Set(["read", "grep", "glob"]);
239
- function lunaToolPlan(tools, enableProgrammaticToolCalling = false) {
239
+ var LUNA_PTC_TOOL_OUTPUT_TRIGGER_CHARS = 8e3;
240
+ var LUNA_PTC_MULTI_WORK_CUE = /\b(both|all|multiple|several|compare|comparison|aggregate|aggregation|total|count|sum|average|filter|join|merge|dedupe|deduplicate|rank|scan|across|every|semua|keduanya|beberapa|bandingkan|perbandingan|agregasi|hitung|jumlah|rata[- ]?rata|gabung|deduplikasi|urutkan|pindai|seluruh)\b|\b(many|banyak)\s+(files?|file|records?|rows?|items?|dokumen|berkas)\b/i;
241
+ function shouldEnableLunaPtc(messages, enabled, programmaticToolNames = []) {
242
+ if (!enabled) return false;
243
+ let lastUser = -1;
244
+ for (let i = messages.length - 1; i >= 0; i--) {
245
+ if (messages[i].role === "user") {
246
+ lastUser = i;
247
+ break;
248
+ }
249
+ }
250
+ const turn = messages.slice(Math.max(0, lastUser));
251
+ const latestUser = lastUser >= 0 ? messages[lastUser] : void 0;
252
+ const prompt = latestUser?.role === "user" ? latestUser.content : "";
253
+ if (LUNA_PTC_MULTI_WORK_CUE.test(prompt)) return true;
254
+ const safeToolNames = /* @__PURE__ */ new Set([...LUNA_PTC_SAFE_FUNCTIONS, ...programmaticToolNames]);
255
+ const safeCalls = /* @__PURE__ */ new Set();
256
+ let safeOutputChars = 0;
257
+ for (const message of turn) {
258
+ if (message.role === "assistant") {
259
+ if (message.responses_output_items?.some((item) => item.type === "program")) return true;
260
+ for (const call of message.tool_calls ?? []) {
261
+ if (safeToolNames.has(call.function.name)) safeCalls.add(call.id);
262
+ }
263
+ continue;
264
+ }
265
+ if (message.role === "tool" && safeCalls.has(message.tool_call_id)) {
266
+ safeOutputChars += message.content.length;
267
+ if (safeOutputChars >= LUNA_PTC_TOOL_OUTPUT_TRIGGER_CHARS) return true;
268
+ }
269
+ }
270
+ return false;
271
+ }
272
+ function lunaToolPlan(tools, enableProgrammaticToolCalling = false, programmaticToolNames = []) {
240
273
  const native = (tools ?? []).map((tool) => ({
241
274
  type: "function",
242
275
  name: tool.function.name,
@@ -248,9 +281,10 @@ function lunaToolPlan(tools, enableProgrammaticToolCalling = false) {
248
281
  const deferredSchemaChars = mcpIndexes.reduce((sum, index) => sum + JSON.stringify(native[index]).length, 0);
249
282
  const useToolSearch = mcpIndexes.length >= LUNA_TOOL_SEARCH_MIN_MCP_TOOLS || deferredSchemaChars >= LUNA_TOOL_SEARCH_MIN_MCP_SCHEMA_CHARS;
250
283
  let programmaticToolCount = 0;
284
+ const safeToolNames = /* @__PURE__ */ new Set([...LUNA_PTC_SAFE_FUNCTIONS, ...programmaticToolNames]);
251
285
  if (enableProgrammaticToolCalling) {
252
286
  for (let index = 0; index < native.length; index++) {
253
- if (LUNA_PTC_SAFE_FUNCTIONS.has(String(native[index].name))) {
287
+ if (safeToolNames.has(String(native[index].name))) {
254
288
  native[index] = { ...native[index], allowed_callers: ["direct", "programmatic"] };
255
289
  programmaticToolCount++;
256
290
  }
@@ -280,8 +314,8 @@ function lunaToolPlan(tools, enableProgrammaticToolCalling = false) {
280
314
  deferredSchemaChars
281
315
  };
282
316
  }
283
- function responseTools(tools, enableProgrammaticToolCalling = false) {
284
- return lunaToolPlan(tools, enableProgrammaticToolCalling).tools;
317
+ function responseTools(tools, enableProgrammaticToolCalling = false, programmaticToolNames = []) {
318
+ return lunaToolPlan(tools, enableProgrammaticToolCalling, programmaticToolNames).tools;
285
319
  }
286
320
  function responseReasoning(level) {
287
321
  if (level === "auto") return {};
@@ -674,8 +708,9 @@ function createProvider(options) {
674
708
  lunaWsIdleTimer = setTimeout(() => resetLunaWebSocket(), 10 * 6e4);
675
709
  lunaWsIdleTimer.unref?.();
676
710
  };
677
- async function chatLunaWebSocket(messages, tools, reasoning, signal, onText) {
678
- const nativeTools = responseTools(tools, enableProgrammaticToolCalling);
711
+ async function chatLunaWebSocket(messages, tools, programmaticToolNames, reasoning, signal, onText) {
712
+ const ptcEnabled = shouldEnableLunaPtc(messages, enableProgrammaticToolCalling, programmaticToolNames);
713
+ const nativeTools = responseTools(tools, ptcEnabled, programmaticToolNames);
679
714
  const initialPlan = responseContinuationInput(messages, lunaContinuation);
680
715
  for (let attempt = 0; attempt < 2; attempt++) {
681
716
  if (signal?.aborted) throw signal.reason ?? new Error("Request aborted");
@@ -751,7 +786,7 @@ function createProvider(options) {
751
786
  throw lastError ?? new ProviderError(t("Request failed"));
752
787
  }
753
788
  return {
754
- async chat({ messages, tools, signal, onText, onThinking, reasoning = "auto" }) {
789
+ async chat({ messages, tools, programmaticToolNames = [], signal, onText, onThinking, reasoning = "auto" }) {
755
790
  let reasoningOverride;
756
791
  try {
757
792
  reasoningOverride = reasoningPayload(providerId, reasoning);
@@ -760,14 +795,15 @@ function createProvider(options) {
760
795
  }
761
796
  if (useResponsesWebSocket) {
762
797
  try {
763
- return await chatLunaWebSocket(messages, tools, reasoning, signal, onText);
798
+ return await chatLunaWebSocket(messages, tools, programmaticToolNames, reasoning, signal, onText);
764
799
  } catch (error) {
765
800
  const err = error instanceof ProviderError ? error : new ProviderError(error.message);
766
801
  if (err.code !== "bc_ws_http_fallback") throw err;
767
802
  }
768
803
  }
769
804
  if (useNativeResponses) {
770
- const nativeTools = responseTools(tools, enableProgrammaticToolCalling);
805
+ const ptcEnabled = shouldEnableLunaPtc(messages, enableProgrammaticToolCalling, programmaticToolNames);
806
+ const nativeTools = responseTools(tools, ptcEnabled, programmaticToolNames);
771
807
  const res2 = await post(
772
808
  "/responses",
773
809
  {
@@ -35,7 +35,7 @@ function readSecret(prompt) {
35
35
  });
36
36
  }
37
37
  async function runLogin(providerId, cwd) {
38
- const { runProviderCommand } = await import("./providerCli-XD7MUX46.js");
38
+ const { runProviderCommand } = await import("./providerCli-RY6T7K6G.js");
39
39
  const { parseCliArgs } = await import("./args-XQYEBOKB.js");
40
40
  return runProviderCommand(parseCliArgs(["provider", "add", providerId]), {
41
41
  env: process.env,
package/dist/cli.js CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  createProvider,
23
23
  hasPendingProgrammaticReplay,
24
24
  listAllModels
25
- } from "./chunk-QXLXJWIL.js";
25
+ } from "./chunk-MGCXWN3E.js";
26
26
  import {
27
27
  providerName,
28
28
  readGlobalConfigFile
@@ -30,7 +30,7 @@ import {
30
30
  import "./chunk-SN3ODJZN.js";
31
31
  import {
32
32
  runLogin
33
- } from "./chunk-ZBOI364S.js";
33
+ } from "./chunk-WJWECLSO.js";
34
34
  import {
35
35
  Session,
36
36
  pruneSessions
@@ -966,6 +966,7 @@ ${completion.text}` });
966
966
  let completion = await this.provider.chat({
967
967
  messages: [{ role: "system", content: this.systemPrompt }, ...this.messages],
968
968
  tools: this.turnDefinitions,
969
+ programmaticToolNames: this.turnTools.filter((tool) => tool.programmaticSafe).map((tool) => tool.name),
969
970
  signal,
970
971
  onText: (delta) => this.onEvent({ type: "text", delta }),
971
972
  onThinking: (delta) => this.onEvent({ type: "thinking", delta }),
@@ -1247,6 +1248,7 @@ var McpManager = class {
1247
1248
  schema: z9.record(z9.string(), z9.unknown()),
1248
1249
  jsonSchema: tool.inputSchema,
1249
1250
  kind: "mcp",
1251
+ programmaticSafe: tool.annotations?.readOnlyHint === true,
1250
1252
  target: (input) => {
1251
1253
  const text = JSON.stringify(input);
1252
1254
  return text.length > 80 ? `${text.slice(0, 77)}\u2026` : text;
@@ -1659,7 +1661,7 @@ function createRuntime(opts) {
1659
1661
  }
1660
1662
 
1661
1663
  // src/version.ts
1662
- var VERSION = true ? "0.4.0-beta.24" : "0.0.0-dev";
1664
+ var VERSION = true ? "0.4.0-beta.26" : "0.0.0-dev";
1663
1665
 
1664
1666
  // src/cli.ts
1665
1667
  function chooseLanguage(argv) {
@@ -1685,12 +1687,12 @@ async function main() {
1685
1687
  if (args.command === "login") return runLogin(args.loginProvider ?? "bc-cloud", cwd);
1686
1688
  if (args.command === "mcp") {
1687
1689
  const { runMcpCommand } = await import("./mcpCli-J43FHF2H.js");
1688
- const { readSecret } = await import("./login-YHBC2ITY.js");
1690
+ const { readSecret } = await import("./login-IUSX5CB3.js");
1689
1691
  return runMcpCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
1690
1692
  }
1691
1693
  if (args.command === "provider") {
1692
- const { runProviderCommand } = await import("./providerCli-XD7MUX46.js");
1693
- const { readSecret } = await import("./login-YHBC2ITY.js");
1694
+ const { runProviderCommand } = await import("./providerCli-RY6T7K6G.js");
1695
+ const { readSecret } = await import("./login-IUSX5CB3.js");
1694
1696
  return runProviderCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
1695
1697
  }
1696
1698
  if (args.command === "connect" || args.command === "disconnect" || args.command === "integrations") {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  readSecret,
4
4
  runLogin
5
- } from "./chunk-ZBOI364S.js";
5
+ } from "./chunk-WJWECLSO.js";
6
6
  export {
7
7
  readSecret,
8
8
  runLogin
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  addProviderKey,
4
4
  runProviderCommand
5
- } from "./chunk-QXLXJWIL.js";
5
+ } from "./chunk-MGCXWN3E.js";
6
6
  import "./chunk-K5JNR3HL.js";
7
7
  import "./chunk-SN3ODJZN.js";
8
8
  import "./chunk-EO7IVVX4.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botconnector/bccli",
3
- "version": "0.4.0-beta.24",
3
+ "version": "0.4.0-beta.26",
4
4
  "description": "BCCLI — BotConnector AI coding agent for the terminal",
5
5
  "type": "module",
6
6
  "bin": {