@botconnector/bccli 0.4.0-beta.18 → 0.4.0-beta.19

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.
@@ -35,7 +35,7 @@ function readSecret(prompt) {
35
35
  });
36
36
  }
37
37
  async function runLogin(providerId, cwd) {
38
- const { runProviderCommand } = await import("./providerCli-3FJAUH7C.js");
38
+ const { runProviderCommand } = await import("./providerCli-WBBIQEJ2.js");
39
39
  const { parseCliArgs } = await import("./args-L555OESS.js");
40
40
  return runProviderCommand(parseCliArgs(["provider", "add", providerId]), {
41
41
  env: process.env,
@@ -192,13 +192,167 @@ async function readJson(res) {
192
192
  const thinking = (choice?.message?.reasoning_content || choice?.message?.reasoning || "") + split.thinking;
193
193
  return { text: split.text, toolCalls, thinking: thinking || void 0, usage: toUsage(body.usage), finishReason: choice?.finish_reason };
194
194
  }
195
+ function responseInputFromMessages(messages) {
196
+ const input = [];
197
+ for (const message of messages) {
198
+ if (message.role === "system" || message.role === "user") {
199
+ input.push({ role: message.role, content: message.content });
200
+ continue;
201
+ }
202
+ if (message.role === "assistant") {
203
+ if (message.content) input.push({ role: "assistant", content: message.content });
204
+ for (const call of message.tool_calls ?? []) {
205
+ input.push({
206
+ type: "function_call",
207
+ call_id: call.id,
208
+ name: call.function.name,
209
+ arguments: call.function.arguments || "{}"
210
+ });
211
+ }
212
+ continue;
213
+ }
214
+ input.push({ type: "function_call_output", call_id: message.tool_call_id, output: message.content });
215
+ }
216
+ return input;
217
+ }
218
+ function responseTools(tools) {
219
+ return (tools ?? []).map((tool) => ({
220
+ type: "function",
221
+ name: tool.function.name,
222
+ description: tool.function.description,
223
+ parameters: tool.function.parameters,
224
+ strict: false
225
+ }));
226
+ }
227
+ function responseReasoning(level) {
228
+ if (level === "auto") return {};
229
+ return { reasoning: { effort: level === "off" ? "none" : level } };
230
+ }
231
+ function toResponsesUsage(usage) {
232
+ return usage ? { inputTokens: usage.input_tokens ?? 0, outputTokens: usage.output_tokens ?? 0 } : void 0;
233
+ }
234
+ async function readResponsesStream(res, onText) {
235
+ let text = "";
236
+ let usage;
237
+ let finishReason;
238
+ let loopAt = -1;
239
+ const calls = /* @__PURE__ */ new Map();
240
+ const decoder = new TextDecoder();
241
+ let buffer = "";
242
+ const emitText = (delta) => {
243
+ if (!delta) return;
244
+ text += delta;
245
+ onText?.(delta);
246
+ if (loopAt < 0) loopAt = detectRepetition(text);
247
+ };
248
+ const handle = (line) => {
249
+ if (!line.startsWith("data:")) return;
250
+ const data = line.slice(5).trim();
251
+ if (!data || data === "[DONE]") return;
252
+ let event;
253
+ try {
254
+ event = JSON.parse(data);
255
+ } catch {
256
+ return;
257
+ }
258
+ if (event.type === "error") {
259
+ throw new ProviderError(t("Error from the provider: {message}", { message: event.message ?? event.error?.message ?? JSON.stringify(event) }));
260
+ }
261
+ if (event.type === "response.failed") {
262
+ throw new ProviderError(t("Error from the provider: {message}", { message: event.response?.error?.message ?? "Response failed" }));
263
+ }
264
+ if (event.type === "response.output_text.delta" || event.type === "response.refusal.delta") {
265
+ emitText(String(event.delta ?? ""));
266
+ return;
267
+ }
268
+ if (event.type === "response.output_item.added" && event.item?.type === "function_call") {
269
+ calls.set(Number(event.output_index ?? calls.size), {
270
+ id: String(event.item.call_id || event.item.id || `call_${calls.size}`),
271
+ name: String(event.item.name || ""),
272
+ arguments: String(event.item.arguments || "")
273
+ });
274
+ return;
275
+ }
276
+ if (event.type === "response.function_call_arguments.delta") {
277
+ const index = Number(event.output_index ?? 0);
278
+ const call = calls.get(index);
279
+ if (call) call.arguments += String(event.delta || "");
280
+ return;
281
+ }
282
+ if (event.type === "response.output_item.done" && event.item?.type === "function_call") {
283
+ const index = Number(event.output_index ?? 0);
284
+ const current = calls.get(index);
285
+ calls.set(index, {
286
+ id: String(event.item.call_id || current?.id || event.item.id || `call_${index}`),
287
+ name: String(event.item.name || current?.name || ""),
288
+ arguments: String(event.item.arguments ?? current?.arguments ?? "")
289
+ });
290
+ return;
291
+ }
292
+ if (event.type === "response.completed") {
293
+ usage = toResponsesUsage(event.response?.usage);
294
+ finishReason = calls.size ? "tool_calls" : "stop";
295
+ return;
296
+ }
297
+ if (event.type === "response.incomplete") {
298
+ usage = toResponsesUsage(event.response?.usage);
299
+ finishReason = String(event.response?.incomplete_details?.reason || "incomplete");
300
+ }
301
+ };
302
+ for await (const chunk of res.body) {
303
+ buffer += decoder.decode(chunk, { stream: true });
304
+ let newline = buffer.indexOf("\n");
305
+ while (newline >= 0 && loopAt < 0) {
306
+ handle(buffer.slice(0, newline).trim());
307
+ buffer = buffer.slice(newline + 1);
308
+ newline = buffer.indexOf("\n");
309
+ }
310
+ if (loopAt >= 0) {
311
+ return { text: text.slice(0, loopAt), toolCalls: [], usage, finishReason: "repetition" };
312
+ }
313
+ }
314
+ handle(buffer.trim());
315
+ return {
316
+ text,
317
+ toolCalls: [...calls.entries()].sort(([a], [b]) => a - b).map(([, call]) => call),
318
+ usage,
319
+ finishReason
320
+ };
321
+ }
322
+ async function readResponsesJson(res) {
323
+ const body = await res.json();
324
+ let text = "";
325
+ const toolCalls = [];
326
+ for (const item of body.output ?? []) {
327
+ if (item?.type === "message") {
328
+ for (const part of item.content ?? []) {
329
+ if (part?.type === "output_text" && typeof part.text === "string") text += part.text;
330
+ else if (part?.type === "refusal" && typeof part.refusal === "string") text += part.refusal;
331
+ }
332
+ } else if (item?.type === "function_call") {
333
+ toolCalls.push({
334
+ id: String(item.call_id || item.id || `call_${toolCalls.length}`),
335
+ name: String(item.name || ""),
336
+ arguments: String(item.arguments || "{}")
337
+ });
338
+ }
339
+ }
340
+ return {
341
+ text,
342
+ toolCalls,
343
+ usage: toResponsesUsage(body.usage),
344
+ finishReason: toolCalls.length ? "tool_calls" : body.status === "incomplete" ? String(body.incomplete_details?.reason || "incomplete") : "stop"
345
+ };
346
+ }
195
347
  function createProvider({ baseURL, apiKey, model, providerId, fetch: doFetch = fetch, retryDelayMs = 1e3 }) {
196
348
  const headers = { "content-type": "application/json" };
197
349
  if (apiKey) headers.authorization = `Bearer ${apiKey}`;
198
- if (/^https:\/\/api\.botconnector\.id\/v1\/?$/.test(baseURL) && apiKey?.startsWith("bc_live_")) {
350
+ const isBotConnectorCloud = /^https:\/\/api\.botconnector\.id\/v1\/?$/.test(baseURL) && apiKey?.startsWith("bc_live_");
351
+ if (isBotConnectorCloud) {
199
352
  headers["x-botconnector-client"] = "bccli";
200
353
  headers["x-botconnector-client-version"] = "0.4.0";
201
354
  }
355
+ const useNativeResponses = isBotConnectorCloud && providerId === "bc-cloud" && model === "gpt-6-luna";
202
356
  async function post(path, body, signal) {
203
357
  let lastError;
204
358
  for (let attempt = 0; attempt < 4; attempt++) {
@@ -226,6 +380,24 @@ function createProvider({ baseURL, apiKey, model, providerId, fetch: doFetch = f
226
380
  } catch (error) {
227
381
  throw new ProviderError(error.message);
228
382
  }
383
+ if (useNativeResponses) {
384
+ const nativeTools = responseTools(tools);
385
+ const res2 = await post(
386
+ "/responses",
387
+ {
388
+ model,
389
+ input: responseInputFromMessages(messages),
390
+ stream: true,
391
+ store: false,
392
+ ...nativeTools.length ? { tools: nativeTools } : {},
393
+ ...responseReasoning(reasoning)
394
+ },
395
+ signal
396
+ );
397
+ if ((res2.headers.get("content-type") ?? "").includes("application/json")) return readResponsesJson(res2);
398
+ if (!res2.body) throw new ProviderError(t("Empty response from the provider"));
399
+ return readResponsesStream(res2, onText);
400
+ }
229
401
  const res = await post(
230
402
  "/chat/completions",
231
403
  { model, messages, stream: true, stream_options: { include_usage: true }, ...tools?.length ? { tools } : {}, ...reasoningOverride },
package/dist/cli.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  addProviderKey,
21
21
  createProvider,
22
22
  listAllModels
23
- } from "./chunk-RY7NCJXH.js";
23
+ } from "./chunk-DXRLNNM7.js";
24
24
  import {
25
25
  providerName,
26
26
  readGlobalConfigFile
@@ -28,7 +28,7 @@ import {
28
28
  import "./chunk-VEZFR7M7.js";
29
29
  import {
30
30
  runLogin
31
- } from "./chunk-4KMOCORM.js";
31
+ } from "./chunk-BPWCF4EJ.js";
32
32
  import {
33
33
  Session,
34
34
  pruneSessions
@@ -1604,7 +1604,7 @@ function createRuntime(opts) {
1604
1604
  }
1605
1605
 
1606
1606
  // src/version.ts
1607
- var VERSION = true ? "0.4.0-beta.18" : "0.0.0-dev";
1607
+ var VERSION = true ? "0.4.0-beta.19" : "0.0.0-dev";
1608
1608
 
1609
1609
  // src/cli.ts
1610
1610
  function chooseLanguage(argv) {
@@ -1630,12 +1630,12 @@ async function main() {
1630
1630
  if (args.command === "login") return runLogin(args.loginProvider ?? "bc-cloud", cwd);
1631
1631
  if (args.command === "mcp") {
1632
1632
  const { runMcpCommand } = await import("./mcpCli-QJE7P76I.js");
1633
- const { readSecret } = await import("./login-O2BQX6LZ.js");
1633
+ const { readSecret } = await import("./login-W4A3EQ53.js");
1634
1634
  return runMcpCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
1635
1635
  }
1636
1636
  if (args.command === "provider") {
1637
- const { runProviderCommand } = await import("./providerCli-3FJAUH7C.js");
1638
- const { readSecret } = await import("./login-O2BQX6LZ.js");
1637
+ const { runProviderCommand } = await import("./providerCli-WBBIQEJ2.js");
1638
+ const { readSecret } = await import("./login-W4A3EQ53.js");
1639
1639
  return runProviderCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), readSecret });
1640
1640
  }
1641
1641
  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-4KMOCORM.js";
5
+ } from "./chunk-BPWCF4EJ.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-RY7NCJXH.js";
5
+ } from "./chunk-DXRLNNM7.js";
6
6
  import "./chunk-D7CF42EW.js";
7
7
  import "./chunk-VEZFR7M7.js";
8
8
  import "./chunk-DDA5TJ7T.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botconnector/bccli",
3
- "version": "0.4.0-beta.18",
3
+ "version": "0.4.0-beta.19",
4
4
  "description": "BCCLI — BotConnector AI coding agent for the terminal",
5
5
  "type": "module",
6
6
  "bin": {