@botconnector/bccli 0.4.0-beta.44 → 0.4.0-beta.46

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.
Files changed (48) hide show
  1. package/dist/{acp-U25MNDND.js → acp-YXBMSWYP.js} +2 -2
  2. package/dist/{args-MFTMBNRN.js → args-6MWRODGH.js} +4 -4
  3. package/dist/{chunk-ZGH4B7OU.js → chunk-2QNYWBDG.js} +21 -12
  4. package/dist/{chunk-TW5HZOTB.js → chunk-33OBF43H.js} +3 -3
  5. package/dist/{chunk-VO6MF6JJ.js → chunk-65OGHOGS.js} +1 -1
  6. package/dist/{chunk-Y3QKYORR.js → chunk-6RML6SN7.js} +6 -6
  7. package/dist/{chunk-PSRNKKGA.js → chunk-7PRH5NDO.js} +1 -1
  8. package/dist/{chunk-RMDW3OQ6.js → chunk-ASJRO2WF.js} +68 -12
  9. package/dist/{chunk-ZKMSTD6G.js → chunk-FIY424O5.js} +1 -1
  10. package/dist/{chunk-NVRNFR4S.js → chunk-GF6CRNT3.js} +1 -1
  11. package/dist/{chunk-QHNWI3OT.js → chunk-GI5GVU2L.js} +8 -2
  12. package/dist/{chunk-BQHKN7JI.js → chunk-IA5PRX4Z.js} +4 -1
  13. package/dist/{chunk-LTAQXU5Z.js → chunk-IHYNME3G.js} +1 -1
  14. package/dist/{chunk-I7GXIJCY.js → chunk-K3SWFB5S.js} +2 -2
  15. package/dist/{chunk-2ON3WIDP.js → chunk-KDVKD3QA.js} +4 -4
  16. package/dist/{chunk-GIGWZFCY.js → chunk-NGHOZRIM.js} +2 -1
  17. package/dist/{chunk-CYTRCZXI.js → chunk-OZPSNMUD.js} +26 -5
  18. package/dist/{chunk-25DSN3Y3.js → chunk-PBBD37E7.js} +4 -4
  19. package/dist/{chunk-PZC2Q6MJ.js → chunk-PQB4CGSL.js} +2 -2
  20. package/dist/chunk-QZKLZELZ.js +64 -0
  21. package/dist/cli.js +42 -39
  22. package/dist/{completion-6K4AXKK2.js → completion-D3HXSAQY.js} +1 -1
  23. package/dist/{config-Z4HSA435.js → config-BAAESXVB.js} +3 -3
  24. package/dist/{config-LCY27K3L.js → config-CJGPM5MJ.js} +2 -2
  25. package/dist/{ghBotCli-TJMKJU3E.js → ghBotCli-DCCFACAA.js} +14 -14
  26. package/dist/{integrationCli-33KU6GIK.js → integrationCli-EYAHT6VL.js} +2 -2
  27. package/dist/{login-LNF7ZV2S.js → login-FXTMDCCC.js} +3 -3
  28. package/dist/{mcpCli-TXFS3AOJ.js → mcpCli-57JTECJY.js} +5 -5
  29. package/dist/{modelsCli-IZSMIYVB.js → modelsCli-NH7W6MAZ.js} +6 -6
  30. package/dist/{oauthLogin-QGDYTOW7.js → oauthLogin-FTOPZW7X.js} +1 -1
  31. package/dist/{pluginsCli-RD4QW3DX.js → pluginsCli-UUPFG2CF.js} +2 -2
  32. package/dist/{prCli-PE7KIPMK.js → prCli-6OQ5ZUBO.js} +1 -1
  33. package/dist/providerCli-L6SQHIRK.js +15 -0
  34. package/dist/sdk.js +149 -14
  35. package/dist/{serve-HW5XZ5LF.js → serve-HPQ2K7UE.js} +15 -15
  36. package/dist/{serve-YNKE332Z.js → serve-HZZYEI3J.js} +3 -3
  37. package/dist/session-QIZKAZK3.js +12 -0
  38. package/dist/setup-4I5FXW37.js +24 -0
  39. package/dist/statsCli-G7GYLCPM.js +353 -0
  40. package/dist/{transferCli-RQBB6RVY.js → transferCli-7FW2SJY4.js} +4 -4
  41. package/dist/{ui-4ZTUMTYM.js → ui-KHNDA2RT.js} +120 -32
  42. package/dist/{update-34FDI6H3.js → update-UG7GWBXT.js} +2 -2
  43. package/package.json +1 -1
  44. package/dist/chunk-U6PCNS4B.js +0 -20
  45. package/dist/providerCli-AA3CHCGV.js +0 -15
  46. package/dist/session-KRV2UP5C.js +0 -12
  47. package/dist/setup-L4OPF3XW.js +0 -24
  48. package/dist/statsCli-4KYPVYCN.js +0 -109
package/dist/sdk.js CHANGED
@@ -68,6 +68,9 @@ var ID = {
68
68
  " enter save \xB7 esc cancel": " enter simpan \xB7 esc batal",
69
69
  "shift+tab switch mode": "shift+tab ganti mode",
70
70
  "{n} tokens": "{n} token",
71
+ "click to toggle": "klik untuk buka/tutup",
72
+ "Model: {model} \xB7 reasoning: {level}": "Model: {model} \xB7 penalaran: {level}",
73
+ "No reasoning summary received yet; tool activity remains visible above.": "Belum ada ringkasan penalaran dari model; aktivitas tool tetap terlihat di atas.",
71
74
  "esc to cancel": "esc batal",
72
75
  "/ for commands": "/ perintah",
73
76
  "\u2026 {n} earlier steps": "\u2026 {n} langkah sebelumnya",
@@ -155,7 +158,8 @@ Usage:
155
158
  bccli provider list|add <id>|remove <id> manage providers (custom: --url <url> [--name N] [--key-env ENV])
156
159
  bccli mcp list|add <name>|remove <name>|auth <name>|logout <name>|serve [--base-url <url>] manage MCP servers, or serve this account's tools over stdio
157
160
  bccli completion <shell> print a shell completion script (bash, zsh, fish, powershell)
158
- bccli stats [--days N] show token usage from local sessions (default: last 7 days)
161
+ bccli stats [--days N] [--tools N] [--models [N|all]] [--project slug]
162
+ show token usage from local sessions (default: last 7 days)
159
163
  bccli export [session] [file] copy a session JSONL to a file (default: last session here)
160
164
  bccli import <file> import a session JSONL into the current project
161
165
  bccli pr <number> [--repo owner/name] [task] check out a GitHub PR and run a task on it
@@ -283,6 +287,7 @@ Opsi:
283
287
  "Note: {env} is still set in the environment and will keep being used.": "Catatan: {env} masih ter-set di environment dan akan terus dipakai.",
284
288
  "To revoke keys on your account, open {dashboard}.": "Untuk mencabut key akun kamu, buka {dashboard}.",
285
289
  "Budget exceeded ({kind}): {used} of {limit}. Further model calls are blocked; raise usageCap in ~/.bccli/config.json.": "Anggaran terlampaui ({kind}): {used} dari {limit}. Panggilan model selanjutnya diblokir; naikkan usageCap di ~/.bccli/config.json.",
290
+ "Could not save thinking visibility: {error}": "Gagal menyimpan pengaturan tampilan Thinking: {error}",
286
291
  "Verifying edits: {cmds}": "Memverifikasi edit: {cmds}",
287
292
  "Verification passed.": "Verifikasi lulus.",
288
293
  "Verification still failing after {n} fix round(s). Run the commands manually to see why.": "Verifikasi masih gagal setelah {n} ronde perbaikan. Jalankan perintahnya secara manual untuk melihat penyebabnya.",
@@ -483,11 +488,12 @@ Opsi:
483
488
  "Blocked: {host} resolves to a private address ({addr}). Fetching an internal host through a public DNS name is not allowed.": "Diblokir: {host} mengarah ke alamat privat ({addr}). Mengambil host internal lewat nama DNS publik tidak diizinkan.",
484
489
  "usage: bccli completion <{shells}>": "pakai: bccli completion <{shells}>",
485
490
  "--days must be a positive integer": "--days harus bilangan bulat positif",
491
+ "--tools must be a positive integer": "--tools harus bilangan bulat positif",
492
+ '--models must be a positive integer or "all"': '--models harus bilangan bulat positif atau "all"',
486
493
  "no sessions in the last {days} day(s)": "tidak ada sesi dalam {days} hari terakhir",
487
494
  "sessions (last {days} day(s)):": "sesi ({days} hari terakhir):",
488
495
  "session(s)": "sesi",
489
496
  "message(s)": "pesan",
490
- "recorded": "tercatat",
491
497
  "no session to export in this folder": "tidak ada sesi untuk diekspor di folder ini",
492
498
  "exported {file}": "diekspor ke {file}",
493
499
  "file not found: {file}": "file tidak ditemukan: {file}",
@@ -681,6 +687,7 @@ function loadConfig(cwd, env = process.env) {
681
687
  model: project.model ?? global.model ?? DEFAULT_CONFIG.model,
682
688
  permissionMode: global.permissionMode ?? DEFAULT_CONFIG.permissionMode,
683
689
  reasoning: global.reasoning ?? DEFAULT_CONFIG.reasoning,
690
+ thinkingVisible: global.thinkingVisible === true,
684
691
  maxSteps: resolvedMaxSteps(global),
685
692
  hooks: global.hooks,
686
693
  vision: global.vision ?? DEFAULT_CONFIG.vision,
@@ -876,8 +883,11 @@ var LOOPBACK_BIND = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "::1"]);
876
883
 
877
884
  // src/args.ts
878
885
  function parseCliArgs(argv) {
886
+ const expanded = argv.map(
887
+ (a, i) => a === "--models" && (i + 1 >= argv.length || argv[i + 1].startsWith("-")) ? "--models=all" : a
888
+ );
879
889
  const { values, positionals } = parseArgs({
880
- args: argv,
890
+ args: expanded,
881
891
  allowPositionals: true,
882
892
  options: {
883
893
  print: { type: "boolean", short: "p" },
@@ -904,6 +914,9 @@ function parseCliArgs(argv) {
904
914
  token: { type: "string" },
905
915
  "base-url": { type: "string" },
906
916
  days: { type: "string" },
917
+ tools: { type: "string" },
918
+ models: { type: "string" },
919
+ project: { type: "string" },
907
920
  repo: { type: "string" }
908
921
  }
909
922
  });
@@ -932,6 +945,17 @@ function parseCliArgs(argv) {
932
945
  if (days !== void 0 && (!Number.isInteger(days) || days < 1)) {
933
946
  throw new ConfigError(t("--days must be a positive integer"));
934
947
  }
948
+ const tools = values.tools !== void 0 ? Number(values.tools) : void 0;
949
+ if (tools !== void 0 && (!Number.isInteger(tools) || tools < 1)) {
950
+ throw new ConfigError(t("--tools must be a positive integer"));
951
+ }
952
+ let models;
953
+ if (values.models !== void 0) {
954
+ models = values.models === "" || values.models === "all" ? "all" : values.models;
955
+ if (models !== "all" && (!Number.isInteger(Number(models)) || Number(models) < 1)) {
956
+ throw new ConfigError(t('--models must be a positive integer or "all"'));
957
+ }
958
+ }
935
959
  if (values.host !== void 0 && !LOOPBACK_BIND.has(values.host)) {
936
960
  throw new ConfigError(t("serve only accepts loopback --host (127.0.0.1, localhost, ::1)"));
937
961
  }
@@ -964,6 +988,9 @@ function parseCliArgs(argv) {
964
988
  token: values.token,
965
989
  baseUrl: values["base-url"],
966
990
  days,
991
+ tools,
992
+ models,
993
+ project: values.project,
967
994
  repo: values.repo
968
995
  };
969
996
  }
@@ -1032,6 +1059,13 @@ var ProviderError = class extends Error {
1032
1059
  status;
1033
1060
  code;
1034
1061
  };
1062
+ function outputReasoningSummary(items) {
1063
+ return (items ?? []).flatMap((item) => {
1064
+ if (!item || typeof item !== "object" || !("type" in item) || item.type !== "reasoning") return [];
1065
+ if (!("summary" in item) || !Array.isArray(item.summary)) return [];
1066
+ return item.summary;
1067
+ }).map((part) => part && typeof part === "object" && "text" in part && typeof part.text === "string" ? part.text : "").filter(Boolean).join("\n");
1068
+ }
1035
1069
  var retryable = (status) => status === 429 || status >= 500;
1036
1070
  function detectRepetition(text) {
1037
1071
  const tail = text.slice(-600);
@@ -1313,8 +1347,8 @@ function responseTools(tools, enableProgrammaticToolCalling = false, programmati
1313
1347
  return lunaToolPlan(tools, enableProgrammaticToolCalling, programmaticToolNames, forceProgrammaticOnly).tools;
1314
1348
  }
1315
1349
  function responseReasoning(level) {
1316
- if (level === "auto") return {};
1317
- return { reasoning: { effort: level === "off" ? "none" : level } };
1350
+ if (level === "off") return { reasoning: { effort: "none" } };
1351
+ return { reasoning: { ...level === "auto" ? {} : { effort: level }, summary: "auto" } };
1318
1352
  }
1319
1353
  function toResponsesUsage(usage) {
1320
1354
  return usage ? { inputTokens: usage.input_tokens ?? 0, outputTokens: usage.output_tokens ?? 0 } : void 0;
@@ -1341,8 +1375,9 @@ function hasPendingProgrammaticReplay(messages) {
1341
1375
  }
1342
1376
  return pending;
1343
1377
  }
1344
- async function readResponsesStream(res, onText) {
1378
+ async function readResponsesStream(res, onText, onThinking) {
1345
1379
  let text = "";
1380
+ let thinking = "";
1346
1381
  let usage;
1347
1382
  let finishReason;
1348
1383
  let loopAt = -1;
@@ -1373,6 +1408,12 @@ async function readResponsesStream(res, onText) {
1373
1408
  if (event.type === "response.failed") {
1374
1409
  throw new ProviderError(t("Error from the provider: {message}", { message: event.response?.error?.message ?? "Response failed" }));
1375
1410
  }
1411
+ if (event.type === "response.reasoning_summary_text.delta" || event.type === "response.reasoning_summary.delta") {
1412
+ const summary = String(event.delta ?? "");
1413
+ thinking += summary;
1414
+ if (summary) onThinking?.(summary);
1415
+ return;
1416
+ }
1376
1417
  if (event.type === "response.output_text.delta" || event.type === "response.refusal.delta") {
1377
1418
  emitText(String(event.delta ?? ""));
1378
1419
  return;
@@ -1409,12 +1450,26 @@ async function readResponsesStream(res, onText) {
1409
1450
  if (event.type === "response.completed") {
1410
1451
  usage = toResponsesUsage(event.response?.usage);
1411
1452
  responsesOutputItems = event.response?.output ?? [...outputItems.entries()].sort(([a], [b]) => a - b).map(([, item]) => item);
1453
+ if (!thinking) {
1454
+ const summary = outputReasoningSummary(responsesOutputItems);
1455
+ if (summary) {
1456
+ thinking = summary;
1457
+ onThinking?.(summary);
1458
+ }
1459
+ }
1412
1460
  finishReason = responsesFinishReason(responsesOutputItems, calls.size);
1413
1461
  return;
1414
1462
  }
1415
1463
  if (event.type === "response.incomplete") {
1416
1464
  usage = toResponsesUsage(event.response?.usage);
1417
1465
  responsesOutputItems = event.response?.output ?? [...outputItems.entries()].sort(([a], [b]) => a - b).map(([, item]) => item);
1466
+ if (!thinking) {
1467
+ const summary = outputReasoningSummary(responsesOutputItems);
1468
+ if (summary) {
1469
+ thinking = summary;
1470
+ onThinking?.(summary);
1471
+ }
1472
+ }
1418
1473
  finishReason = responsesFinishReason(
1419
1474
  responsesOutputItems,
1420
1475
  calls.size,
@@ -1438,14 +1493,16 @@ async function readResponsesStream(res, onText) {
1438
1493
  return {
1439
1494
  text,
1440
1495
  toolCalls: [...calls.entries()].sort(([a], [b]) => a - b).map(([, call]) => call),
1496
+ thinking: thinking || void 0,
1441
1497
  usage,
1442
1498
  finishReason,
1443
1499
  responsesOutputItems
1444
1500
  };
1445
1501
  }
1446
- async function readResponsesJson(res) {
1502
+ async function readResponsesJson(res, onThinking) {
1447
1503
  const body = await res.json();
1448
1504
  let text = "";
1505
+ let thinking = "";
1449
1506
  const toolCalls = [];
1450
1507
  for (const item of body.output ?? []) {
1451
1508
  if (item?.type === "message") {
@@ -1453,6 +1510,12 @@ async function readResponsesJson(res) {
1453
1510
  if (part?.type === "output_text" && typeof part.text === "string") text += part.text;
1454
1511
  else if (part?.type === "refusal" && typeof part.refusal === "string") text += part.refusal;
1455
1512
  }
1513
+ } else if (item?.type === "reasoning" && Array.isArray(item.summary)) {
1514
+ const summary = item.summary.filter((part) => typeof part === "object" && part !== null && typeof part.text === "string").map((part) => part.text).join("");
1515
+ if (summary) {
1516
+ thinking += summary;
1517
+ onThinking?.(summary);
1518
+ }
1456
1519
  } else if (item?.type === "function_call") {
1457
1520
  toolCalls.push({
1458
1521
  id: String(item.call_id || item.id || `call_${toolCalls.length}`),
@@ -1465,6 +1528,7 @@ async function readResponsesJson(res) {
1465
1528
  return {
1466
1529
  text,
1467
1530
  toolCalls,
1531
+ thinking: thinking || void 0,
1468
1532
  usage: toResponsesUsage(body.usage),
1469
1533
  responsesOutputItems: body.output,
1470
1534
  finishReason: responsesFinishReason(
@@ -1522,9 +1586,10 @@ function responseContinuationInput(messages, continuation) {
1522
1586
  incremental: true
1523
1587
  };
1524
1588
  }
1525
- async function readResponsesWebSocketTurn(events, ws, onText, signal) {
1589
+ async function readResponsesWebSocketTurn(events, ws, onText, onThinking, signal) {
1526
1590
  let responseId = "";
1527
1591
  let text = "";
1592
+ let thinking = "";
1528
1593
  let usage;
1529
1594
  let finishReason;
1530
1595
  let loopAt = -1;
@@ -1571,6 +1636,12 @@ async function readResponsesWebSocketTurn(events, ws, onText, signal) {
1571
1636
  responseId = String(event.response?.id || responseId);
1572
1637
  continue;
1573
1638
  }
1639
+ if (event.type === "response.reasoning_summary_text.delta") {
1640
+ const summary = String(event.delta ?? "");
1641
+ thinking += summary;
1642
+ if (summary) onThinking?.(summary);
1643
+ continue;
1644
+ }
1574
1645
  if (event.type === "response.output_text.delta" || event.type === "response.refusal.delta") {
1575
1646
  emitText(String(event.delta ?? ""));
1576
1647
  if (loopAt >= 0) {
@@ -1621,6 +1692,13 @@ async function readResponsesWebSocketTurn(events, ws, onText, signal) {
1621
1692
  responseId = String(event.response?.id || responseId);
1622
1693
  usage = toResponsesUsage(event.response?.usage);
1623
1694
  const responsesOutputItems = event.response?.output ?? [...outputItems.entries()].sort(([a], [b]) => a - b).map(([, item]) => item);
1695
+ if (!thinking) {
1696
+ const summary = outputReasoningSummary(responsesOutputItems);
1697
+ if (summary) {
1698
+ thinking = summary;
1699
+ onThinking?.(summary);
1700
+ }
1701
+ }
1624
1702
  finishReason = responsesFinishReason(
1625
1703
  responsesOutputItems,
1626
1704
  calls.size,
@@ -1631,6 +1709,7 @@ async function readResponsesWebSocketTurn(events, ws, onText, signal) {
1631
1709
  completion: {
1632
1710
  text,
1633
1711
  toolCalls: [...calls.entries()].sort(([a], [b]) => a - b).map(([, call]) => call),
1712
+ thinking: thinking || void 0,
1634
1713
  usage,
1635
1714
  finishReason,
1636
1715
  responsesOutputItems
@@ -1703,7 +1782,7 @@ function createProvider(options) {
1703
1782
  lunaWsIdleTimer = setTimeout(() => resetLunaWebSocket(), 10 * 6e4);
1704
1783
  lunaWsIdleTimer.unref?.();
1705
1784
  };
1706
- async function chatLunaWebSocket(messages, tools, programmaticToolNames, reasoning, signal, onText) {
1785
+ async function chatLunaWebSocket(messages, tools, programmaticToolNames, reasoning, signal, onText, onThinking) {
1707
1786
  const ptcEnabled = shouldEnableLunaPtc(messages, enableProgrammaticToolCalling, programmaticToolNames);
1708
1787
  const forcePtc = shouldForceLunaPtc(messages, ptcEnabled);
1709
1788
  const nativeTools = responseTools(tools, ptcEnabled, programmaticToolNames, forcePtc);
@@ -1728,9 +1807,13 @@ function createProvider(options) {
1728
1807
  if (delta) emittedText = true;
1729
1808
  onText?.(delta);
1730
1809
  };
1810
+ const trackSummary = (delta) => {
1811
+ if (delta) emittedText = true;
1812
+ onThinking?.(delta);
1813
+ };
1731
1814
  try {
1732
1815
  ws.send(createEvent);
1733
- const result = await readResponsesWebSocketTurn(events, ws, trackText, signal);
1816
+ const result = await readResponsesWebSocketTurn(events, ws, trackText, trackSummary, signal);
1734
1817
  if (result.completion.finishReason === "repetition") {
1735
1818
  resetLunaWebSocket();
1736
1819
  return result.completion;
@@ -1791,7 +1874,7 @@ function createProvider(options) {
1791
1874
  }
1792
1875
  if (useResponsesWebSocket) {
1793
1876
  try {
1794
- return await chatLunaWebSocket(messages, tools, programmaticToolNames, reasoning, signal, onText);
1877
+ return await chatLunaWebSocket(messages, tools, programmaticToolNames, reasoning, signal, onText, onThinking);
1795
1878
  } catch (error) {
1796
1879
  const err = error instanceof ProviderError ? error : new ProviderError(error.message);
1797
1880
  if (err.code !== "bc_ws_http_fallback") throw err;
@@ -1814,9 +1897,9 @@ function createProvider(options) {
1814
1897
  },
1815
1898
  signal
1816
1899
  );
1817
- if ((res2.headers.get("content-type") ?? "").includes("application/json")) return readResponsesJson(res2);
1900
+ if ((res2.headers.get("content-type") ?? "").includes("application/json")) return readResponsesJson(res2, onThinking);
1818
1901
  if (!res2.body) throw new ProviderError(t("Empty response from the provider"));
1819
- return readResponsesStream(res2, onText);
1902
+ return readResponsesStream(res2, onText, onThinking);
1820
1903
  }
1821
1904
  const res = await post(
1822
1905
  "/chat/completions",
@@ -3231,6 +3314,48 @@ function trimToFit(messages, maxTokens) {
3231
3314
  }
3232
3315
  return out;
3233
3316
  }
3317
+ function splitKeepRecent(messages, keepTokens) {
3318
+ if (messages.length === 0) return [[], []];
3319
+ let start = messages.length;
3320
+ for (let i = messages.length - 1; i >= 0; i--) {
3321
+ if (i > 0 && messages[i].role !== "user") continue;
3322
+ if (estimateMessages(messages.slice(i)) <= keepTokens) start = i;
3323
+ else break;
3324
+ }
3325
+ if (start === messages.length) {
3326
+ for (let i = messages.length - 1; i >= 0; i--) {
3327
+ if (messages[i].role === "user") {
3328
+ start = i;
3329
+ break;
3330
+ }
3331
+ }
3332
+ }
3333
+ return [messages.slice(0, start), messages.slice(start)];
3334
+ }
3335
+ var TOOL_STUB = "[Old tool result content cleared]";
3336
+ var TOOL_PRUNE_KEEP_TOKENS = 4e4;
3337
+ var TOOL_PRUNE_MIN_TOKENS = 2e4;
3338
+ var isToolStub = (content) => content.startsWith(TOOL_STUB);
3339
+ function pruneOldToolOutputs(messages) {
3340
+ let kept = 0;
3341
+ let oldTokens = 0;
3342
+ const old = [];
3343
+ for (let i = messages.length - 1; i >= 0; i--) {
3344
+ const m = messages[i];
3345
+ if (m.role !== "tool" || isToolStub(m.content)) continue;
3346
+ kept += estimateTokens(m.content);
3347
+ if (kept > TOOL_PRUNE_KEEP_TOKENS) {
3348
+ old.push(i);
3349
+ oldTokens += estimateTokens(m.content);
3350
+ }
3351
+ }
3352
+ if (oldTokens <= TOOL_PRUNE_MIN_TOKENS) return false;
3353
+ for (const i of old) {
3354
+ const m = messages[i];
3355
+ messages[i] = { ...m, content: TOOL_STUB };
3356
+ }
3357
+ return true;
3358
+ }
3234
3359
 
3235
3360
  // src/agent.ts
3236
3361
  var CANCELLED = "Cancelled by the user.";
@@ -3310,7 +3435,10 @@ var Agent2 = class {
3310
3435
  this.opts.onReset?.();
3311
3436
  }
3312
3437
  async compact(signal) {
3313
- const history = trimToFit(this.messages, Math.floor(this.contextWindow * 0.8));
3438
+ pruneOldToolOutputs(this.messages);
3439
+ const keepTokens = Math.min(15e3, Math.floor(this.contextWindow * 0.1));
3440
+ const [older, keep] = splitKeepRecent(this.messages, keepTokens);
3441
+ const history = trimToFit(older, Math.floor(this.contextWindow * 0.8));
3314
3442
  const completion = await this.provider.chat({
3315
3443
  messages: [{ role: "system", content: this.systemPrompt }, ...history, { role: "user", content: COMPACT_PROMPT }],
3316
3444
  // Some gateways reject tool_calls in history when no tools are declared.
@@ -3322,6 +3450,7 @@ var Agent2 = class {
3322
3450
  this.push({ role: "user", content: `Summary of the previous conversation:
3323
3451
  ${completion.text}` });
3324
3452
  this.push({ role: "assistant", content: "OK, I will continue from this summary." });
3453
+ for (const m of keep) this.push(m);
3325
3454
  this.onEvent({ type: "compacted" });
3326
3455
  }
3327
3456
  /**
@@ -3384,6 +3513,7 @@ ${completion.text}` });
3384
3513
  this.totalUsage.cacheWriteTokens = (this.totalUsage.cacheWriteTokens ?? 0) + (usage.cacheWriteTokens ?? 0);
3385
3514
  this.lastInputTokens = usage.inputTokens;
3386
3515
  this.onEvent({ type: "usage", ...this.totalUsage });
3516
+ this.opts.onUsage?.(usage);
3387
3517
  this.push(completionAssistantMessage(completion));
3388
3518
  if (completion.finishReason === "repetition") {
3389
3519
  this.onEvent({ type: "textReplace", text: completion.text });
@@ -3531,6 +3661,7 @@ ${t("This model may not support tool calling. Try another model with /model.")}`
3531
3661
  this.totalUsage.cachedInputTokens = (this.totalUsage.cachedInputTokens ?? 0) + (u.cachedInputTokens ?? 0);
3532
3662
  this.totalUsage.cacheWriteTokens = (this.totalUsage.cacheWriteTokens ?? 0) + (u.cacheWriteTokens ?? 0);
3533
3663
  this.onEvent({ type: "usage", ...this.totalUsage });
3664
+ this.opts.onUsage?.(u);
3534
3665
  }
3535
3666
  };
3536
3667
  emit({ type: "toolStart", id: call.id, tool: tool.name, target });
@@ -4299,6 +4430,9 @@ var Session = class _Session {
4299
4430
  append(message) {
4300
4431
  this.write({ t: "msg", m: message });
4301
4432
  }
4433
+ appendUsage(usage) {
4434
+ this.write({ t: "usage", ...usage });
4435
+ }
4302
4436
  reset() {
4303
4437
  this.write({ t: "reset" });
4304
4438
  }
@@ -5066,6 +5200,7 @@ function createRuntime(opts) {
5066
5200
  budgetModel: modelRef,
5067
5201
  contextWindow: contextWindowFor(modelRef, env),
5068
5202
  onMessage: (m) => session.append(m),
5203
+ onUsage: (u) => session.appendUsage({ ...u, model: modelRef }),
5069
5204
  onReset: () => session.reset(),
5070
5205
  onTurnStart: () => {
5071
5206
  for (let i = turnMarks.length - 1; i >= 0 && turnMarks[i] > agent.messages.length; i--) {
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createRuntime
4
- } from "./chunk-ZGH4B7OU.js";
5
- import "./chunk-U6PCNS4B.js";
6
- import "./chunk-PSRNKKGA.js";
7
- import "./chunk-NVRNFR4S.js";
4
+ } from "./chunk-2QNYWBDG.js";
5
+ import "./chunk-QZKLZELZ.js";
6
+ import "./chunk-7PRH5NDO.js";
7
+ import "./chunk-GF6CRNT3.js";
8
8
  import "./chunk-PSO7R5AD.js";
9
9
  import {
10
10
  VERSION
11
- } from "./chunk-LTAQXU5Z.js";
11
+ } from "./chunk-IHYNME3G.js";
12
12
  import {
13
13
  LOOPBACK_BIND,
14
14
  MAX_FRAME_BYTES,
@@ -17,25 +17,25 @@ import {
17
17
  parseClientFrame,
18
18
  randomToken,
19
19
  trustFence
20
- } from "./chunk-CYTRCZXI.js";
20
+ } from "./chunk-OZPSNMUD.js";
21
21
  import "./chunk-GAFJEQTJ.js";
22
- import "./chunk-2ON3WIDP.js";
22
+ import "./chunk-KDVKD3QA.js";
23
23
  import {
24
24
  listAllModels
25
- } from "./chunk-25DSN3Y3.js";
26
- import "./chunk-VO6MF6JJ.js";
25
+ } from "./chunk-PBBD37E7.js";
26
+ import "./chunk-65OGHOGS.js";
27
27
  import "./chunk-7F3IWBPQ.js";
28
28
  import {
29
29
  Session
30
- } from "./chunk-BQHKN7JI.js";
31
- import "./chunk-RMDW3OQ6.js";
32
- import "./chunk-ZKMSTD6G.js";
33
- import "./chunk-PZC2Q6MJ.js";
30
+ } from "./chunk-IA5PRX4Z.js";
31
+ import "./chunk-ASJRO2WF.js";
32
+ import "./chunk-FIY424O5.js";
33
+ import "./chunk-PQB4CGSL.js";
34
34
  import {
35
35
  bccliHome,
36
36
  loadConfig
37
- } from "./chunk-GIGWZFCY.js";
38
- import "./chunk-QHNWI3OT.js";
37
+ } from "./chunk-NGHOZRIM.js";
38
+ import "./chunk-GI5GVU2L.js";
39
39
 
40
40
  // src/serve.ts
41
41
  import { randomBytes } from "crypto";
@@ -3,15 +3,15 @@ import {
3
3
  createFetchTool,
4
4
  createWebSearchTool,
5
5
  isPrivateHost
6
- } from "./chunk-NVRNFR4S.js";
6
+ } from "./chunk-GF6CRNT3.js";
7
7
  import "./chunk-PSO7R5AD.js";
8
8
  import {
9
9
  loadConfig,
10
10
  readCredentials
11
- } from "./chunk-GIGWZFCY.js";
11
+ } from "./chunk-NGHOZRIM.js";
12
12
  import {
13
13
  t
14
- } from "./chunk-QHNWI3OT.js";
14
+ } from "./chunk-GI5GVU2L.js";
15
15
 
16
16
  // src/mcpServer/serve.ts
17
17
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ Session,
4
+ pruneSessions
5
+ } from "./chunk-IA5PRX4Z.js";
6
+ import "./chunk-ASJRO2WF.js";
7
+ import "./chunk-FIY424O5.js";
8
+ import "./chunk-GI5GVU2L.js";
9
+ export {
10
+ Session,
11
+ pruneSessions
12
+ };
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createRuntime,
4
+ lunaPtcAutoEnabled
5
+ } from "./chunk-2QNYWBDG.js";
6
+ import "./chunk-QZKLZELZ.js";
7
+ import "./chunk-7PRH5NDO.js";
8
+ import "./chunk-GF6CRNT3.js";
9
+ import "./chunk-PSO7R5AD.js";
10
+ import "./chunk-GAFJEQTJ.js";
11
+ import "./chunk-KDVKD3QA.js";
12
+ import "./chunk-PBBD37E7.js";
13
+ import "./chunk-65OGHOGS.js";
14
+ import "./chunk-7F3IWBPQ.js";
15
+ import "./chunk-IA5PRX4Z.js";
16
+ import "./chunk-ASJRO2WF.js";
17
+ import "./chunk-FIY424O5.js";
18
+ import "./chunk-PQB4CGSL.js";
19
+ import "./chunk-NGHOZRIM.js";
20
+ import "./chunk-GI5GVU2L.js";
21
+ export {
22
+ createRuntime,
23
+ lunaPtcAutoEnabled
24
+ };