@nomad-e/bluma-cli 0.22.1 → 0.23.0

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 (2) hide show
  1. package/dist/main.js +146 -32
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2295,6 +2295,17 @@ function countTokens(messages, useCache = true) {
2295
2295
  if (tokenCountCache && tokenCountCache.hash === currentHash) {
2296
2296
  return tokenCountCache.count;
2297
2297
  }
2298
+ const enc2 = getO200kEncoding();
2299
+ let total2 = CONVERSATION_BASE_OVERHEAD;
2300
+ for (const msg of messages) {
2301
+ const body = messageBodyForTokens(msg);
2302
+ const extra = messageExtraForTokens(msg);
2303
+ const nBody = body ? enc2.encode(body).length : 0;
2304
+ const nExtra = extra ? enc2.encode(extra).length : 0;
2305
+ total2 += nBody + nExtra + MESSAGE_OVERHEAD_TOKENS;
2306
+ }
2307
+ tokenCountCache = { hash: currentHash, count: total2 };
2308
+ return total2;
2298
2309
  }
2299
2310
  const enc = getO200kEncoding();
2300
2311
  let total = CONVERSATION_BASE_OVERHEAD;
@@ -2305,9 +2316,6 @@ function countTokens(messages, useCache = true) {
2305
2316
  const nExtra = extra ? enc.encode(extra).length : 0;
2306
2317
  total += nBody + nExtra + MESSAGE_OVERHEAD_TOKENS;
2307
2318
  }
2308
- if (useCache) {
2309
- tokenCountCache = { hash: hashHistory(messages), count: total };
2310
- }
2311
2319
  return total;
2312
2320
  }
2313
2321
  function clearTokenCountCache() {
@@ -18151,6 +18159,43 @@ async function readMcpResource(args) {
18151
18159
  });
18152
18160
  }
18153
18161
  }
18162
+ async function listMcpPrompts(args) {
18163
+ const mcp = mcpRef;
18164
+ if (!mcp) {
18165
+ return JSON.stringify({ success: false, error: "MCP client not registered." });
18166
+ }
18167
+ try {
18168
+ const rows = await mcp.listPromptsFromAllServers();
18169
+ const server = args?.server?.trim();
18170
+ const filtered = server ? rows.filter((r) => r.server === server) : rows;
18171
+ return JSON.stringify({ success: true, servers: filtered });
18172
+ } catch (e) {
18173
+ return JSON.stringify({
18174
+ success: false,
18175
+ error: e?.message || String(e)
18176
+ });
18177
+ }
18178
+ }
18179
+ async function getMcpPrompt(args) {
18180
+ const mcp = mcpRef;
18181
+ if (!mcp) {
18182
+ return JSON.stringify({ success: false, error: "MCP client not registered." });
18183
+ }
18184
+ const server = String(args?.server || "").trim();
18185
+ const name = String(args?.name || "").trim();
18186
+ if (!server || !name) {
18187
+ return JSON.stringify({ success: false, error: "server and name are required." });
18188
+ }
18189
+ try {
18190
+ const result = await mcp.getPromptFromServer(server, name, args.arguments);
18191
+ return JSON.stringify({ success: true, ...result });
18192
+ } catch (e) {
18193
+ return JSON.stringify({
18194
+ success: false,
18195
+ error: e?.message || String(e)
18196
+ });
18197
+ }
18198
+ }
18154
18199
 
18155
18200
  // src/app/agent/tools/SessionCronTool/SessionCronTool.ts
18156
18201
  import { randomBytes } from "crypto";
@@ -21244,6 +21289,28 @@ var NATIVE_TOOL_ENTRIES = [
21244
21289
  },
21245
21290
  implementation: readMcpResource
21246
21291
  },
21292
+ {
21293
+ metadata: {
21294
+ name: "list_mcp_prompts",
21295
+ category: "knowledge",
21296
+ riskLevel: "safe",
21297
+ autoApproveInLocal: true,
21298
+ autoApproveInSandbox: true,
21299
+ description: "List prompts from connected MCP servers. Each prompt has a name, description, and optional arguments."
21300
+ },
21301
+ implementation: listMcpPrompts
21302
+ },
21303
+ {
21304
+ metadata: {
21305
+ name: "get_mcp_prompt",
21306
+ category: "knowledge",
21307
+ riskLevel: "safe",
21308
+ autoApproveInLocal: true,
21309
+ autoApproveInSandbox: true,
21310
+ description: "Get a specific prompt from an MCP server by server name and prompt name. Returns messages content."
21311
+ },
21312
+ implementation: getMcpPrompt
21313
+ },
21247
21314
  {
21248
21315
  metadata: {
21249
21316
  name: "cron_create",
@@ -21665,8 +21732,33 @@ function normalizeToolResult(value) {
21665
21732
  }
21666
21733
  return { status: "success", data: value };
21667
21734
  }
21735
+ var MAX_TOOL_RESULT_CHARS = 12e3;
21736
+ function truncateToolResultData(result) {
21737
+ if (result.status === "error") return result;
21738
+ const raw = JSON.stringify(result, null, 2);
21739
+ if (raw.length <= MAX_TOOL_RESULT_CHARS) return result;
21740
+ const d = result.data;
21741
+ if (typeof d === "string") {
21742
+ const budget = MAX_TOOL_RESULT_CHARS - 80;
21743
+ return { ...result, data: `${d.slice(0, budget)}
21744
+
21745
+ [\u2026 truncated \u2014 ${d.length} chars total \u2026]` };
21746
+ }
21747
+ if (d != null) {
21748
+ try {
21749
+ const full = JSON.stringify(d, null, 2);
21750
+ const budget = MAX_TOOL_RESULT_CHARS - 80;
21751
+ const truncated = `${full.slice(0, budget)}
21752
+
21753
+ [\u2026 truncated \u2014 ${full.length} chars total \u2026]`;
21754
+ return { ...result, data: truncated };
21755
+ } catch {
21756
+ }
21757
+ }
21758
+ return result;
21759
+ }
21668
21760
  function toolResultToString(value) {
21669
- const result = normalizeToolResult(value);
21761
+ const result = truncateToolResultData(normalizeToolResult(value));
21670
21762
  return JSON.stringify(result, null, 2);
21671
21763
  }
21672
21764
  function extractMessageToolPayload(parsed) {
@@ -21944,6 +22036,37 @@ var MCPClient = class {
21944
22036
  }
21945
22037
  return client.readResource({ uri });
21946
22038
  }
22039
+ // --- Prompts API ---
22040
+ /** List prompts from every connected MCP server. */
22041
+ async listPromptsFromAllServers() {
22042
+ const out = [];
22043
+ for (const [serverName, client] of this.sessions) {
22044
+ try {
22045
+ const r = await client.listPrompts({});
22046
+ const prompts = (r.prompts || []).map((p) => ({
22047
+ name: p.name,
22048
+ description: p.description,
22049
+ arguments: p.arguments
22050
+ }));
22051
+ out.push({ server: serverName, prompts });
22052
+ } catch (e) {
22053
+ out.push({
22054
+ server: serverName,
22055
+ prompts: [],
22056
+ error: e?.message || String(e)
22057
+ });
22058
+ }
22059
+ }
22060
+ return out;
22061
+ }
22062
+ /** Get a specific prompt from a specific server. */
22063
+ async getPromptFromServer(server, promptName, args) {
22064
+ const client = this.sessions.get(server);
22065
+ if (!client) {
22066
+ throw new Error(`Unknown MCP server: ${server}`);
22067
+ }
22068
+ return client.getPrompt({ name: promptName, arguments: args });
22069
+ }
21947
22070
  // New: detailed list for UI with origin metadata
21948
22071
  getAvailableToolsDetailed() {
21949
22072
  const isSandboxMode = process.env.BLUMA_SANDBOX === "true";
@@ -24912,8 +25035,8 @@ Operating rule: continue from the next steps and the latest user instruction. If
24912
25035
  // src/app/agent/core/context-api/history_compressor.ts
24913
25036
  init_token_counter();
24914
25037
  var COMPRESSION_TIMEOUT_MS = 15e3;
24915
- var COMPRESS_THRESHOLD = 0.95;
24916
- var KEEP_RECENT_TURNS = 10;
25038
+ var COMPRESS_THRESHOLD = 0.85;
25039
+ var KEEP_RECENT_TURNS = 8;
24917
25040
  var DEFAULT_CONTEXT_INPUT_BUDGET = 1e5;
24918
25041
  var HistoryCompressor = class {
24919
25042
  anchor;
@@ -27780,6 +27903,7 @@ function toolResultToContent(result) {
27780
27903
  return String(result);
27781
27904
  }
27782
27905
  }
27906
+ var MAX_FORK_HISTORY_MESSAGES = 60;
27783
27907
  async function runMemorySubagent(params) {
27784
27908
  const {
27785
27909
  llm,
@@ -27794,8 +27918,12 @@ async function runMemorySubagent(params) {
27794
27918
  const allTools = mcpClient.getAvailableTools();
27795
27919
  const toolSet = new Set(SUBAGENT_TOOLS);
27796
27920
  const tools = allTools.filter((t) => toolSet.has(t.function?.name ?? ""));
27921
+ const systemMsg = forkHistory.find((m) => m.role === "system");
27922
+ const nonSystem = forkHistory.filter((m) => m.role !== "system");
27923
+ const recentHistory = nonSystem.slice(-MAX_FORK_HISTORY_MESSAGES);
27924
+ const forkedHistory = systemMsg ? [systemMsg, ...recentHistory] : recentHistory;
27797
27925
  const messages = [
27798
- ...forkHistory,
27926
+ ...forkedHistory,
27799
27927
  { role: "user", content: userPrompt }
27800
27928
  ];
27801
27929
  const systemNote = "You are a background memory subagent. Complete the memory task and stop. Do not chat with the user." + (systemSuffix ? `
@@ -40884,7 +41012,7 @@ var renderPluginsSnapshot = () => {
40884
41012
  "global: ",
40885
41013
  dirs.global
40886
41014
  ] }),
40887
- /* @__PURE__ */ jsx94(Box_default, { marginTop: 1, flexDirection: "column", children: plugins.length === 0 ? /* @__PURE__ */ jsx94(Text, { dimColor: true, children: "No plugins installed." }) : plugins.slice(0, 12).map((plugin) => /* @__PURE__ */ jsxs77(Text, { dimColor: true, children: [
41015
+ /* @__PURE__ */ jsx94(Box_default, { marginTop: 1, flexDirection: "column", children: plugins.length === 0 ? /* @__PURE__ */ jsx94(Text, { dimColor: true, children: "No plugins installed." }) : plugins.map((plugin) => /* @__PURE__ */ jsxs77(Text, { dimColor: true, children: [
40888
41016
  plugin.name,
40889
41017
  " \xB7 ",
40890
41018
  plugin.source,
@@ -41273,18 +41401,11 @@ var renderMcp = (filter) => {
41273
41401
  filter ? `matching "${filter}"` : "total"
41274
41402
  ] })
41275
41403
  ] }),
41276
- /* @__PURE__ */ jsxs78(Box_default, { flexDirection: "column", children: [
41277
- filtered.length === 0 ? /* @__PURE__ */ jsx95(Text, { dimColor: true, children: "No MCP tools found." }) : filtered.slice(0, 15).map((tool) => /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
41278
- tool.name,
41279
- " \xB7 ",
41280
- tool.description || "no description"
41281
- ] }, tool.name)),
41282
- filtered.length > 15 && /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
41283
- "\u2026 +",
41284
- filtered.length - 15,
41285
- " more"
41286
- ] })
41287
- ] })
41404
+ /* @__PURE__ */ jsx95(Box_default, { flexDirection: "column", children: filtered.length === 0 ? /* @__PURE__ */ jsx95(Text, { dimColor: true, children: "No MCP tools found." }) : filtered.map((tool) => /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
41405
+ tool.name,
41406
+ " \xB7 ",
41407
+ tool.description || "no description"
41408
+ ] }, tool.name)) })
41288
41409
  ] })
41289
41410
  );
41290
41411
  };
@@ -41302,18 +41423,11 @@ var renderTools = (filter) => {
41302
41423
  filter ? `matching "${filter}"` : "total"
41303
41424
  ] })
41304
41425
  ] }),
41305
- /* @__PURE__ */ jsxs78(Box_default, { flexDirection: "column", children: [
41306
- filtered.length === 0 ? /* @__PURE__ */ jsx95(Text, { dimColor: true, children: "No native tools found." }) : filtered.slice(0, 15).map((tool) => /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
41307
- tool.name,
41308
- " \xB7 ",
41309
- tool.description || "no description"
41310
- ] }, tool.name)),
41311
- filtered.length > 15 && /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
41312
- "\u2026 +",
41313
- filtered.length - 15,
41314
- " more"
41315
- ] })
41316
- ] })
41426
+ /* @__PURE__ */ jsx95(Box_default, { flexDirection: "column", children: filtered.length === 0 ? /* @__PURE__ */ jsx95(Text, { dimColor: true, children: "No native tools found." }) : filtered.map((tool) => /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
41427
+ tool.name,
41428
+ " \xB7 ",
41429
+ tool.description || "no description"
41430
+ ] }, tool.name)) })
41317
41431
  ] })
41318
41432
  );
41319
41433
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomad-e/bluma-cli",
3
- "version": "0.22.1",
3
+ "version": "0.23.0",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",