@nomad-e/bluma-cli 0.22.2 → 0.24.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.
- package/dist/main.js +406 -112
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2242,25 +2242,14 @@ var init_ListMailboxMessagesTool = __esm({
|
|
|
2242
2242
|
|
|
2243
2243
|
// src/app/agent/core/context-api/token_counter.ts
|
|
2244
2244
|
import { getEncoding } from "js-tiktoken";
|
|
2245
|
-
import { createHash as createHash2 } from "crypto";
|
|
2246
2245
|
function getO200kEncoding() {
|
|
2247
2246
|
if (!cachedEncoding) {
|
|
2248
2247
|
cachedEncoding = getEncoding("o200k_base");
|
|
2249
2248
|
}
|
|
2250
2249
|
return cachedEncoding;
|
|
2251
2250
|
}
|
|
2252
|
-
function
|
|
2253
|
-
|
|
2254
|
-
hash.update(`len:${messages.length}:`);
|
|
2255
|
-
for (const msg of messages) {
|
|
2256
|
-
const m = msg;
|
|
2257
|
-
hash.update(`role:${m.role ?? ""}:`);
|
|
2258
|
-
hash.update(`content:${JSON.stringify(m.content ?? "")}:`);
|
|
2259
|
-
hash.update(`tool_calls:${JSON.stringify(m.tool_calls ?? "")}:`);
|
|
2260
|
-
hash.update(`tool_call_id:${m.tool_call_id ?? ""}:`);
|
|
2261
|
-
hash.update(`name:${m.name ?? ""}:`);
|
|
2262
|
-
}
|
|
2263
|
-
return hash.digest("hex");
|
|
2251
|
+
function invalidateTokenCache() {
|
|
2252
|
+
cacheVersion++;
|
|
2264
2253
|
}
|
|
2265
2254
|
function messageBodyForTokens(msg) {
|
|
2266
2255
|
const c = msg.content;
|
|
@@ -2290,11 +2279,8 @@ function countTokens(messages, useCache = true) {
|
|
|
2290
2279
|
if (messages.length === 0) {
|
|
2291
2280
|
return CONVERSATION_BASE_OVERHEAD;
|
|
2292
2281
|
}
|
|
2293
|
-
if (useCache) {
|
|
2294
|
-
|
|
2295
|
-
if (tokenCountCache && tokenCountCache.hash === currentHash) {
|
|
2296
|
-
return tokenCountCache.count;
|
|
2297
|
-
}
|
|
2282
|
+
if (useCache && cacheVersion === cachedVersion) {
|
|
2283
|
+
return cachedCount;
|
|
2298
2284
|
}
|
|
2299
2285
|
const enc = getO200kEncoding();
|
|
2300
2286
|
let total = CONVERSATION_BASE_OVERHEAD;
|
|
@@ -2306,13 +2292,11 @@ function countTokens(messages, useCache = true) {
|
|
|
2306
2292
|
total += nBody + nExtra + MESSAGE_OVERHEAD_TOKENS;
|
|
2307
2293
|
}
|
|
2308
2294
|
if (useCache) {
|
|
2309
|
-
|
|
2295
|
+
cachedVersion = cacheVersion;
|
|
2296
|
+
cachedCount = total;
|
|
2310
2297
|
}
|
|
2311
2298
|
return total;
|
|
2312
2299
|
}
|
|
2313
|
-
function clearTokenCountCache() {
|
|
2314
|
-
tokenCountCache = null;
|
|
2315
|
-
}
|
|
2316
2300
|
function countToolDefinitionsTokens(tools) {
|
|
2317
2301
|
if (!tools || tools.length === 0) {
|
|
2318
2302
|
return 0;
|
|
@@ -2337,14 +2321,16 @@ function computeEffectiveInputBudget(rawBudget, toolDefinitions = [], options) {
|
|
|
2337
2321
|
effectiveBudget
|
|
2338
2322
|
};
|
|
2339
2323
|
}
|
|
2340
|
-
var MESSAGE_OVERHEAD_TOKENS, CONVERSATION_BASE_OVERHEAD, cachedEncoding,
|
|
2324
|
+
var MESSAGE_OVERHEAD_TOKENS, CONVERSATION_BASE_OVERHEAD, cachedEncoding, cacheVersion, cachedVersion, cachedCount, DEFAULT_OUTPUT_TOKEN_RESERVE, DEFAULT_PROTOCOL_OVERHEAD_TOKENS;
|
|
2341
2325
|
var init_token_counter = __esm({
|
|
2342
2326
|
"src/app/agent/core/context-api/token_counter.ts"() {
|
|
2343
2327
|
"use strict";
|
|
2344
2328
|
MESSAGE_OVERHEAD_TOKENS = 4;
|
|
2345
2329
|
CONVERSATION_BASE_OVERHEAD = 3;
|
|
2346
2330
|
cachedEncoding = null;
|
|
2347
|
-
|
|
2331
|
+
cacheVersion = 0;
|
|
2332
|
+
cachedVersion = -1;
|
|
2333
|
+
cachedCount = 0;
|
|
2348
2334
|
DEFAULT_OUTPUT_TOKEN_RESERVE = 8192;
|
|
2349
2335
|
DEFAULT_PROTOCOL_OVERHEAD_TOKENS = 512;
|
|
2350
2336
|
}
|
|
@@ -14307,7 +14293,7 @@ import { v4 as uuidv412 } from "uuid";
|
|
|
14307
14293
|
import chalk3 from "chalk";
|
|
14308
14294
|
|
|
14309
14295
|
// src/app/ui/BlumaSession.tsx
|
|
14310
|
-
import
|
|
14296
|
+
import { useState as useState25, useEffect as useEffect22, useRef as useRef13, useCallback as useCallback11, memo as memo25, useMemo as useMemo8 } from "react";
|
|
14311
14297
|
|
|
14312
14298
|
// src/app/ui/layout.tsx
|
|
14313
14299
|
import { memo as memo2 } from "react";
|
|
@@ -18151,6 +18137,43 @@ async function readMcpResource(args) {
|
|
|
18151
18137
|
});
|
|
18152
18138
|
}
|
|
18153
18139
|
}
|
|
18140
|
+
async function listMcpPrompts(args) {
|
|
18141
|
+
const mcp = mcpRef;
|
|
18142
|
+
if (!mcp) {
|
|
18143
|
+
return JSON.stringify({ success: false, error: "MCP client not registered." });
|
|
18144
|
+
}
|
|
18145
|
+
try {
|
|
18146
|
+
const rows = await mcp.listPromptsFromAllServers();
|
|
18147
|
+
const server = args?.server?.trim();
|
|
18148
|
+
const filtered = server ? rows.filter((r) => r.server === server) : rows;
|
|
18149
|
+
return JSON.stringify({ success: true, servers: filtered });
|
|
18150
|
+
} catch (e) {
|
|
18151
|
+
return JSON.stringify({
|
|
18152
|
+
success: false,
|
|
18153
|
+
error: e?.message || String(e)
|
|
18154
|
+
});
|
|
18155
|
+
}
|
|
18156
|
+
}
|
|
18157
|
+
async function getMcpPrompt(args) {
|
|
18158
|
+
const mcp = mcpRef;
|
|
18159
|
+
if (!mcp) {
|
|
18160
|
+
return JSON.stringify({ success: false, error: "MCP client not registered." });
|
|
18161
|
+
}
|
|
18162
|
+
const server = String(args?.server || "").trim();
|
|
18163
|
+
const name = String(args?.name || "").trim();
|
|
18164
|
+
if (!server || !name) {
|
|
18165
|
+
return JSON.stringify({ success: false, error: "server and name are required." });
|
|
18166
|
+
}
|
|
18167
|
+
try {
|
|
18168
|
+
const result = await mcp.getPromptFromServer(server, name, args.arguments);
|
|
18169
|
+
return JSON.stringify({ success: true, ...result });
|
|
18170
|
+
} catch (e) {
|
|
18171
|
+
return JSON.stringify({
|
|
18172
|
+
success: false,
|
|
18173
|
+
error: e?.message || String(e)
|
|
18174
|
+
});
|
|
18175
|
+
}
|
|
18176
|
+
}
|
|
18154
18177
|
|
|
18155
18178
|
// src/app/agent/tools/SessionCronTool/SessionCronTool.ts
|
|
18156
18179
|
import { randomBytes } from "crypto";
|
|
@@ -21244,6 +21267,28 @@ var NATIVE_TOOL_ENTRIES = [
|
|
|
21244
21267
|
},
|
|
21245
21268
|
implementation: readMcpResource
|
|
21246
21269
|
},
|
|
21270
|
+
{
|
|
21271
|
+
metadata: {
|
|
21272
|
+
name: "list_mcp_prompts",
|
|
21273
|
+
category: "knowledge",
|
|
21274
|
+
riskLevel: "safe",
|
|
21275
|
+
autoApproveInLocal: true,
|
|
21276
|
+
autoApproveInSandbox: true,
|
|
21277
|
+
description: "List prompts from connected MCP servers. Each prompt has a name, description, and optional arguments."
|
|
21278
|
+
},
|
|
21279
|
+
implementation: listMcpPrompts
|
|
21280
|
+
},
|
|
21281
|
+
{
|
|
21282
|
+
metadata: {
|
|
21283
|
+
name: "get_mcp_prompt",
|
|
21284
|
+
category: "knowledge",
|
|
21285
|
+
riskLevel: "safe",
|
|
21286
|
+
autoApproveInLocal: true,
|
|
21287
|
+
autoApproveInSandbox: true,
|
|
21288
|
+
description: "Get a specific prompt from an MCP server by server name and prompt name. Returns messages content."
|
|
21289
|
+
},
|
|
21290
|
+
implementation: getMcpPrompt
|
|
21291
|
+
},
|
|
21247
21292
|
{
|
|
21248
21293
|
metadata: {
|
|
21249
21294
|
name: "cron_create",
|
|
@@ -21665,8 +21710,33 @@ function normalizeToolResult(value) {
|
|
|
21665
21710
|
}
|
|
21666
21711
|
return { status: "success", data: value };
|
|
21667
21712
|
}
|
|
21713
|
+
var MAX_TOOL_RESULT_CHARS = 12e3;
|
|
21714
|
+
function truncateToolResultData(result) {
|
|
21715
|
+
if (result.status === "error") return result;
|
|
21716
|
+
const raw = JSON.stringify(result, null, 2);
|
|
21717
|
+
if (raw.length <= MAX_TOOL_RESULT_CHARS) return result;
|
|
21718
|
+
const d = result.data;
|
|
21719
|
+
if (typeof d === "string") {
|
|
21720
|
+
const budget = MAX_TOOL_RESULT_CHARS - 80;
|
|
21721
|
+
return { ...result, data: `${d.slice(0, budget)}
|
|
21722
|
+
|
|
21723
|
+
[\u2026 truncated \u2014 ${d.length} chars total \u2026]` };
|
|
21724
|
+
}
|
|
21725
|
+
if (d != null) {
|
|
21726
|
+
try {
|
|
21727
|
+
const full = JSON.stringify(d, null, 2);
|
|
21728
|
+
const budget = MAX_TOOL_RESULT_CHARS - 80;
|
|
21729
|
+
const truncated = `${full.slice(0, budget)}
|
|
21730
|
+
|
|
21731
|
+
[\u2026 truncated \u2014 ${full.length} chars total \u2026]`;
|
|
21732
|
+
return { ...result, data: truncated };
|
|
21733
|
+
} catch {
|
|
21734
|
+
}
|
|
21735
|
+
}
|
|
21736
|
+
return result;
|
|
21737
|
+
}
|
|
21668
21738
|
function toolResultToString(value) {
|
|
21669
|
-
const result = normalizeToolResult(value);
|
|
21739
|
+
const result = truncateToolResultData(normalizeToolResult(value));
|
|
21670
21740
|
return JSON.stringify(result, null, 2);
|
|
21671
21741
|
}
|
|
21672
21742
|
function extractMessageToolPayload(parsed) {
|
|
@@ -21944,6 +22014,37 @@ var MCPClient = class {
|
|
|
21944
22014
|
}
|
|
21945
22015
|
return client.readResource({ uri });
|
|
21946
22016
|
}
|
|
22017
|
+
// --- Prompts API ---
|
|
22018
|
+
/** List prompts from every connected MCP server. */
|
|
22019
|
+
async listPromptsFromAllServers() {
|
|
22020
|
+
const out = [];
|
|
22021
|
+
for (const [serverName, client] of this.sessions) {
|
|
22022
|
+
try {
|
|
22023
|
+
const r = await client.listPrompts({});
|
|
22024
|
+
const prompts = (r.prompts || []).map((p) => ({
|
|
22025
|
+
name: p.name,
|
|
22026
|
+
description: p.description,
|
|
22027
|
+
arguments: p.arguments
|
|
22028
|
+
}));
|
|
22029
|
+
out.push({ server: serverName, prompts });
|
|
22030
|
+
} catch (e) {
|
|
22031
|
+
out.push({
|
|
22032
|
+
server: serverName,
|
|
22033
|
+
prompts: [],
|
|
22034
|
+
error: e?.message || String(e)
|
|
22035
|
+
});
|
|
22036
|
+
}
|
|
22037
|
+
}
|
|
22038
|
+
return out;
|
|
22039
|
+
}
|
|
22040
|
+
/** Get a specific prompt from a specific server. */
|
|
22041
|
+
async getPromptFromServer(server, promptName, args) {
|
|
22042
|
+
const client = this.sessions.get(server);
|
|
22043
|
+
if (!client) {
|
|
22044
|
+
throw new Error(`Unknown MCP server: ${server}`);
|
|
22045
|
+
}
|
|
22046
|
+
return client.getPrompt({ name: promptName, arguments: args });
|
|
22047
|
+
}
|
|
21947
22048
|
// New: detailed list for UI with origin metadata
|
|
21948
22049
|
getAvailableToolsDetailed() {
|
|
21949
22050
|
const isSandboxMode = process.env.BLUMA_SANDBOX === "true";
|
|
@@ -24912,8 +25013,8 @@ Operating rule: continue from the next steps and the latest user instruction. If
|
|
|
24912
25013
|
// src/app/agent/core/context-api/history_compressor.ts
|
|
24913
25014
|
init_token_counter();
|
|
24914
25015
|
var COMPRESSION_TIMEOUT_MS = 15e3;
|
|
24915
|
-
var COMPRESS_THRESHOLD = 0.
|
|
24916
|
-
var KEEP_RECENT_TURNS =
|
|
25016
|
+
var COMPRESS_THRESHOLD = 0.85;
|
|
25017
|
+
var KEEP_RECENT_TURNS = 8;
|
|
24917
25018
|
var DEFAULT_CONTEXT_INPUT_BUDGET = 1e5;
|
|
24918
25019
|
var HistoryCompressor = class {
|
|
24919
25020
|
anchor;
|
|
@@ -24961,8 +25062,13 @@ var HistoryCompressor = class {
|
|
|
24961
25062
|
const tokenBudget = budgetBreakdown.effectiveBudget;
|
|
24962
25063
|
const compressThreshold = options?.compressThreshold ?? COMPRESS_THRESHOLD;
|
|
24963
25064
|
const keepRecentTurns = options?.keepRecentTurns ?? KEEP_RECENT_TURNS;
|
|
24964
|
-
|
|
24965
|
-
|
|
25065
|
+
let safeHistory;
|
|
25066
|
+
if (options?.skipSanitize) {
|
|
25067
|
+
safeHistory = fullHistory;
|
|
25068
|
+
} else {
|
|
25069
|
+
const sanitized = sanitizeConversationForProvider(fullHistory);
|
|
25070
|
+
safeHistory = sanitized.messages;
|
|
25071
|
+
}
|
|
24966
25072
|
const systemMessages = [];
|
|
24967
25073
|
let historyStartIndex = 0;
|
|
24968
25074
|
while (historyStartIndex < safeHistory.length && safeHistory[historyStartIndex].role === "system") {
|
|
@@ -24979,7 +25085,6 @@ var HistoryCompressor = class {
|
|
|
24979
25085
|
const thresholdTokens = tokenBudget * compressThreshold;
|
|
24980
25086
|
let pendingSlices = turnSlices.slice(sliceCount, recentStart);
|
|
24981
25087
|
let pendingFlat = pendingSlices.flat();
|
|
24982
|
-
clearTokenCountCache();
|
|
24983
25088
|
let messages = this.assembleMessages(systemMessages, pendingFlat, recentFlat);
|
|
24984
25089
|
let tokens = countTokens(messages, true);
|
|
24985
25090
|
contextEventBus.emit("context:compression_start", {
|
|
@@ -25026,12 +25131,12 @@ var HistoryCompressor = class {
|
|
|
25026
25131
|
reason: compressError?.message || "timeout"
|
|
25027
25132
|
});
|
|
25028
25133
|
}
|
|
25029
|
-
|
|
25134
|
+
invalidateTokenCache();
|
|
25030
25135
|
messages = this.assembleMessages(systemMessages, pendingFlat, recentFlat);
|
|
25031
25136
|
tokens = countTokens(messages, true);
|
|
25032
25137
|
}
|
|
25033
25138
|
if (tokens > tokenBudget) {
|
|
25034
|
-
|
|
25139
|
+
invalidateTokenCache();
|
|
25035
25140
|
const { capped, slices: cappedSlices } = this.enforceHardCap(
|
|
25036
25141
|
systemMessages,
|
|
25037
25142
|
recentSlices,
|
|
@@ -27123,7 +27228,9 @@ var BluMaTurnCoordinator = class {
|
|
|
27123
27228
|
this.deps.getLlmUserContext(),
|
|
27124
27229
|
{
|
|
27125
27230
|
tokenBudget,
|
|
27126
|
-
toolDefinitions: this.deps.mcpClient.getAvailableTools()
|
|
27231
|
+
toolDefinitions: this.deps.mcpClient.getAvailableTools(),
|
|
27232
|
+
skipSanitize: true
|
|
27233
|
+
// already sanitized above
|
|
27127
27234
|
}
|
|
27128
27235
|
);
|
|
27129
27236
|
this.turnLog.debug("Context window prepared", {
|
|
@@ -27780,6 +27887,7 @@ function toolResultToContent(result) {
|
|
|
27780
27887
|
return String(result);
|
|
27781
27888
|
}
|
|
27782
27889
|
}
|
|
27890
|
+
var MAX_FORK_HISTORY_MESSAGES = 60;
|
|
27783
27891
|
async function runMemorySubagent(params) {
|
|
27784
27892
|
const {
|
|
27785
27893
|
llm,
|
|
@@ -27794,8 +27902,12 @@ async function runMemorySubagent(params) {
|
|
|
27794
27902
|
const allTools = mcpClient.getAvailableTools();
|
|
27795
27903
|
const toolSet = new Set(SUBAGENT_TOOLS);
|
|
27796
27904
|
const tools = allTools.filter((t) => toolSet.has(t.function?.name ?? ""));
|
|
27905
|
+
const systemMsg = forkHistory.find((m) => m.role === "system");
|
|
27906
|
+
const nonSystem = forkHistory.filter((m) => m.role !== "system");
|
|
27907
|
+
const recentHistory = nonSystem.slice(-MAX_FORK_HISTORY_MESSAGES);
|
|
27908
|
+
const forkedHistory = systemMsg ? [systemMsg, ...recentHistory] : recentHistory;
|
|
27797
27909
|
const messages = [
|
|
27798
|
-
...
|
|
27910
|
+
...forkedHistory,
|
|
27799
27911
|
{ role: "user", content: userPrompt }
|
|
27800
27912
|
];
|
|
27801
27913
|
const systemNote = "You are a background memory subagent. Complete the memory task and stop. Do not chat with the user." + (systemSuffix ? `
|
|
@@ -28009,11 +28121,15 @@ function hasMetUpdateThreshold(currentTokens) {
|
|
|
28009
28121
|
// src/app/agent/memory/session_memory_update.ts
|
|
28010
28122
|
init_logger();
|
|
28011
28123
|
var log2 = logger.child("session_memory");
|
|
28124
|
+
var MIN_COOLDOWN_MS = 6e4;
|
|
28125
|
+
var lastUpdateTime = 0;
|
|
28012
28126
|
function isSessionMemoryEnabled() {
|
|
28013
28127
|
if (process.env.BLUMA_DISABLE_SESSION_MEMORY === "1") return false;
|
|
28014
28128
|
return true;
|
|
28015
28129
|
}
|
|
28016
28130
|
function shouldUpdateSessionMemory(history) {
|
|
28131
|
+
const now2 = Date.now();
|
|
28132
|
+
if (now2 - lastUpdateTime < MIN_COOLDOWN_MS) return false;
|
|
28017
28133
|
const tokens = estimateHistoryTokens(history);
|
|
28018
28134
|
if (!isSessionMemoryInitialized()) {
|
|
28019
28135
|
if (!hasMetInitializationThreshold(tokens)) return false;
|
|
@@ -28063,6 +28179,7 @@ async function runSessionMemoryUpdate(deps) {
|
|
|
28063
28179
|
});
|
|
28064
28180
|
recordExtractionTokenCount(estimateHistoryTokens(history));
|
|
28065
28181
|
setLastCursorIndex(history.length);
|
|
28182
|
+
lastUpdateTime = Date.now();
|
|
28066
28183
|
log2.debug("finished");
|
|
28067
28184
|
} catch (err) {
|
|
28068
28185
|
log2.warn("failed", { error: err instanceof Error ? err.message : String(err) });
|
|
@@ -28077,8 +28194,10 @@ function scheduleSessionMemoryUpdate(deps) {
|
|
|
28077
28194
|
|
|
28078
28195
|
// src/app/agent/memory/background_memory.ts
|
|
28079
28196
|
function runBackgroundMemoryAfterTurn(params) {
|
|
28197
|
+
const MAX_SNAPSHOT = 80;
|
|
28198
|
+
const snapshot = params.history.length > MAX_SNAPSHOT ? params.history.slice(-MAX_SNAPSHOT) : params.history;
|
|
28080
28199
|
const deps = {
|
|
28081
|
-
history:
|
|
28200
|
+
history: snapshot,
|
|
28082
28201
|
sessionId: params.sessionId,
|
|
28083
28202
|
llm: params.llm,
|
|
28084
28203
|
mcpClient: params.mcpClient,
|
|
@@ -40884,7 +41003,7 @@ var renderPluginsSnapshot = () => {
|
|
|
40884
41003
|
"global: ",
|
|
40885
41004
|
dirs.global
|
|
40886
41005
|
] }),
|
|
40887
|
-
/* @__PURE__ */ jsx94(Box_default, { marginTop: 1, flexDirection: "column", children: plugins.length === 0 ? /* @__PURE__ */ jsx94(Text, { dimColor: true, children: "No plugins installed." }) : plugins.
|
|
41006
|
+
/* @__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
41007
|
plugin.name,
|
|
40889
41008
|
" \xB7 ",
|
|
40890
41009
|
plugin.source,
|
|
@@ -41273,18 +41392,11 @@ var renderMcp = (filter) => {
|
|
|
41273
41392
|
filter ? `matching "${filter}"` : "total"
|
|
41274
41393
|
] })
|
|
41275
41394
|
] }),
|
|
41276
|
-
/* @__PURE__ */
|
|
41277
|
-
|
|
41278
|
-
|
|
41279
|
-
|
|
41280
|
-
|
|
41281
|
-
] }, tool.name)),
|
|
41282
|
-
filtered.length > 15 && /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
|
|
41283
|
-
"\u2026 +",
|
|
41284
|
-
filtered.length - 15,
|
|
41285
|
-
" more"
|
|
41286
|
-
] })
|
|
41287
|
-
] })
|
|
41395
|
+
/* @__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: [
|
|
41396
|
+
tool.name,
|
|
41397
|
+
" \xB7 ",
|
|
41398
|
+
tool.description || "no description"
|
|
41399
|
+
] }, tool.name)) })
|
|
41288
41400
|
] })
|
|
41289
41401
|
);
|
|
41290
41402
|
};
|
|
@@ -41302,18 +41414,11 @@ var renderTools = (filter) => {
|
|
|
41302
41414
|
filter ? `matching "${filter}"` : "total"
|
|
41303
41415
|
] })
|
|
41304
41416
|
] }),
|
|
41305
|
-
/* @__PURE__ */
|
|
41306
|
-
|
|
41307
|
-
|
|
41308
|
-
|
|
41309
|
-
|
|
41310
|
-
] }, tool.name)),
|
|
41311
|
-
filtered.length > 15 && /* @__PURE__ */ jsxs78(Text, { dimColor: true, children: [
|
|
41312
|
-
"\u2026 +",
|
|
41313
|
-
filtered.length - 15,
|
|
41314
|
-
" more"
|
|
41315
|
-
] })
|
|
41316
|
-
] })
|
|
41417
|
+
/* @__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: [
|
|
41418
|
+
tool.name,
|
|
41419
|
+
" \xB7 ",
|
|
41420
|
+
tool.description || "no description"
|
|
41421
|
+
] }, tool.name)) })
|
|
41317
41422
|
] })
|
|
41318
41423
|
);
|
|
41319
41424
|
};
|
|
@@ -45263,6 +45368,167 @@ function ScrollBox({
|
|
|
45263
45368
|
}
|
|
45264
45369
|
var ScrollBox_default = ScrollBox;
|
|
45265
45370
|
|
|
45371
|
+
// src/app/ui/hooks/useVirtualScroll.ts
|
|
45372
|
+
import {
|
|
45373
|
+
useCallback as useCallback10,
|
|
45374
|
+
useLayoutEffect as useLayoutEffect3,
|
|
45375
|
+
useMemo as useMemo7,
|
|
45376
|
+
useRef as useRef12,
|
|
45377
|
+
useState as useState24
|
|
45378
|
+
} from "react";
|
|
45379
|
+
var DEFAULT_ESTIMATE = 3;
|
|
45380
|
+
var OVERSCAN_ROWS = 40;
|
|
45381
|
+
var COLD_START_COUNT = 20;
|
|
45382
|
+
var MAX_MOUNTED_ITEMS = 200;
|
|
45383
|
+
var PESSIMISTIC_HEIGHT = 1;
|
|
45384
|
+
function useVirtualScroll(scrollRef, itemKeys, columns) {
|
|
45385
|
+
const heightCache = useRef12(/* @__PURE__ */ new Map());
|
|
45386
|
+
const offsetVersionRef = useRef12(0);
|
|
45387
|
+
const lastScrollTopRef = useRef12(0);
|
|
45388
|
+
const offsetsRef = useRef12({
|
|
45389
|
+
arr: new Float64Array(0),
|
|
45390
|
+
version: -1,
|
|
45391
|
+
n: -1
|
|
45392
|
+
});
|
|
45393
|
+
const itemRefs = useRef12(/* @__PURE__ */ new Map());
|
|
45394
|
+
const refCache = useRef12(/* @__PURE__ */ new Map());
|
|
45395
|
+
const prevColumns = useRef12(columns);
|
|
45396
|
+
const skipMeasurementRef = useRef12(false);
|
|
45397
|
+
if (prevColumns.current !== columns) {
|
|
45398
|
+
const ratio = prevColumns.current / columns;
|
|
45399
|
+
prevColumns.current = columns;
|
|
45400
|
+
for (const [k, h] of heightCache.current) {
|
|
45401
|
+
heightCache.current.set(k, Math.max(1, Math.round(h * ratio)));
|
|
45402
|
+
}
|
|
45403
|
+
offsetVersionRef.current++;
|
|
45404
|
+
skipMeasurementRef.current = true;
|
|
45405
|
+
}
|
|
45406
|
+
const SCROLL_QUANTUM = OVERSCAN_ROWS >> 1;
|
|
45407
|
+
const subscribe = useCallback10(
|
|
45408
|
+
(cb) => scrollRef.current?.subscribe(cb) ?? (() => {
|
|
45409
|
+
}),
|
|
45410
|
+
[scrollRef]
|
|
45411
|
+
);
|
|
45412
|
+
const getSnapshot = useCallback10(() => {
|
|
45413
|
+
const sb = scrollRef.current;
|
|
45414
|
+
if (!sb) return NaN;
|
|
45415
|
+
const raw = sb.getScrollTop();
|
|
45416
|
+
const sticky = sb.isSticky();
|
|
45417
|
+
const quantized = Math.floor(raw / SCROLL_QUANTUM) * SCROLL_QUANTUM;
|
|
45418
|
+
return sticky ? -(quantized | 1) : quantized;
|
|
45419
|
+
}, [scrollRef, SCROLL_QUANTUM]);
|
|
45420
|
+
const getServerSnapshot = useCallback10(() => NaN, []);
|
|
45421
|
+
const scrollTop = useSyncExternalStore5(subscribe, getSnapshot, getServerSnapshot);
|
|
45422
|
+
const viewportHeight = scrollRef.current?.getViewportHeight() ?? 0;
|
|
45423
|
+
const isSticky = scrollRef.current?.isSticky() ?? true;
|
|
45424
|
+
const n = itemKeys.length;
|
|
45425
|
+
const computeOffsets = useCallback10(() => {
|
|
45426
|
+
const cached = offsetsRef.current;
|
|
45427
|
+
if (cached.n === n && cached.version === offsetVersionRef.current && cached.arr.length === n + 1) {
|
|
45428
|
+
return cached.arr;
|
|
45429
|
+
}
|
|
45430
|
+
const offsets2 = new Float64Array(n + 1);
|
|
45431
|
+
for (let i = 0; i < n; i++) {
|
|
45432
|
+
const h = heightCache.current.get(itemKeys[i]) ?? DEFAULT_ESTIMATE;
|
|
45433
|
+
offsets2[i + 1] = offsets2[i] + h;
|
|
45434
|
+
}
|
|
45435
|
+
offsetsRef.current = { arr: offsets2, version: offsetVersionRef.current, n };
|
|
45436
|
+
return offsets2;
|
|
45437
|
+
}, [n, itemKeys, offsetVersionRef.current]);
|
|
45438
|
+
const offsets = computeOffsets();
|
|
45439
|
+
const totalHeight = offsets[n] ?? 0;
|
|
45440
|
+
const range = useMemo7(() => {
|
|
45441
|
+
if (n === 0) return [0, 0];
|
|
45442
|
+
if (viewportHeight <= 0) {
|
|
45443
|
+
return [0, Math.min(n, COLD_START_COUNT)];
|
|
45444
|
+
}
|
|
45445
|
+
const absScrollTop = Math.abs(scrollTop);
|
|
45446
|
+
if (isSticky) {
|
|
45447
|
+
let hi3 = n;
|
|
45448
|
+
let remaining = viewportHeight + OVERSCAN_ROWS;
|
|
45449
|
+
while (hi3 > 0 && remaining > 0) {
|
|
45450
|
+
const h = heightCache.current.get(itemKeys[hi3 - 1]) ?? DEFAULT_ESTIMATE;
|
|
45451
|
+
remaining -= h;
|
|
45452
|
+
hi3--;
|
|
45453
|
+
}
|
|
45454
|
+
const lo3 = Math.max(0, hi3 - OVERSCAN_ROWS);
|
|
45455
|
+
return [lo3, n];
|
|
45456
|
+
}
|
|
45457
|
+
let lo2 = 0;
|
|
45458
|
+
{
|
|
45459
|
+
const target = Math.max(0, absScrollTop - OVERSCAN_ROWS);
|
|
45460
|
+
let lo_ = 0;
|
|
45461
|
+
let hi_ = n;
|
|
45462
|
+
while (lo_ < hi_) {
|
|
45463
|
+
const mid = lo_ + hi_ >>> 1;
|
|
45464
|
+
if (offsets[mid] < target) lo_ = mid + 1;
|
|
45465
|
+
else hi_ = mid;
|
|
45466
|
+
}
|
|
45467
|
+
lo2 = lo_;
|
|
45468
|
+
}
|
|
45469
|
+
let hi2 = lo2;
|
|
45470
|
+
let accumulated = 0;
|
|
45471
|
+
const needed = viewportHeight + 2 * OVERSCAN_ROWS;
|
|
45472
|
+
while (hi2 < n && accumulated < needed) {
|
|
45473
|
+
const h = heightCache.current.get(itemKeys[hi2]) ?? PESSIMISTIC_HEIGHT;
|
|
45474
|
+
accumulated += h;
|
|
45475
|
+
hi2++;
|
|
45476
|
+
}
|
|
45477
|
+
return [lo2, Math.min(hi2, lo2 + MAX_MOUNTED_ITEMS)];
|
|
45478
|
+
}, [scrollTop, viewportHeight, isSticky, n, offsets, itemKeys]);
|
|
45479
|
+
const measureRef = useCallback10((key) => {
|
|
45480
|
+
if (refCache.current.has(key)) return refCache.current.get(key);
|
|
45481
|
+
const refFn = (el) => {
|
|
45482
|
+
if (skipMeasurementRef.current) return;
|
|
45483
|
+
if (el) {
|
|
45484
|
+
itemRefs.current.set(key, el);
|
|
45485
|
+
const h = el.yogaNode?.getComputedHeight();
|
|
45486
|
+
if (h != null && h > 0) {
|
|
45487
|
+
const prev = heightCache.current.get(key);
|
|
45488
|
+
if (prev !== h) {
|
|
45489
|
+
heightCache.current.set(key, h);
|
|
45490
|
+
offsetVersionRef.current++;
|
|
45491
|
+
}
|
|
45492
|
+
}
|
|
45493
|
+
}
|
|
45494
|
+
};
|
|
45495
|
+
refCache.current.set(key, refFn);
|
|
45496
|
+
return refFn;
|
|
45497
|
+
}, []);
|
|
45498
|
+
const [lo, hi] = range;
|
|
45499
|
+
const topSpacer = offsets[lo] ?? 0;
|
|
45500
|
+
const bottomSpacer = totalHeight - (offsets[hi] ?? totalHeight);
|
|
45501
|
+
return {
|
|
45502
|
+
range,
|
|
45503
|
+
topSpacer,
|
|
45504
|
+
bottomSpacer,
|
|
45505
|
+
offsets,
|
|
45506
|
+
measureRef
|
|
45507
|
+
};
|
|
45508
|
+
}
|
|
45509
|
+
function useSyncExternalStore5(subscribe, getSnapshot, getServerSnapshot) {
|
|
45510
|
+
const [value, setValue] = useState24(getSnapshot);
|
|
45511
|
+
const getSnapshotRef = useRef12(getSnapshot);
|
|
45512
|
+
getSnapshotRef.current = getSnapshot;
|
|
45513
|
+
useLayoutEffect3(() => {
|
|
45514
|
+
let didSubscribe = false;
|
|
45515
|
+
const checkForUpdates2 = () => {
|
|
45516
|
+
if (didSubscribe) {
|
|
45517
|
+
const newValue = getSnapshotRef.current();
|
|
45518
|
+
setValue(newValue);
|
|
45519
|
+
}
|
|
45520
|
+
};
|
|
45521
|
+
didSubscribe = true;
|
|
45522
|
+
checkForUpdates2();
|
|
45523
|
+
const unsubscribe = subscribe(checkForUpdates2);
|
|
45524
|
+
return () => {
|
|
45525
|
+
didSubscribe = false;
|
|
45526
|
+
unsubscribe();
|
|
45527
|
+
};
|
|
45528
|
+
}, [subscribe]);
|
|
45529
|
+
return value;
|
|
45530
|
+
}
|
|
45531
|
+
|
|
45266
45532
|
// src/app/ui/BlumaSession.tsx
|
|
45267
45533
|
import { Fragment as Fragment19, jsx as jsx104, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
45268
45534
|
var blumaUpdateRegistryCheckStarted = false;
|
|
@@ -45328,23 +45594,23 @@ function UserMessageWithOptionalImages({
|
|
|
45328
45594
|
) : /* @__PURE__ */ jsx104(Text, { color: BLUMA_TERMINAL.m3OnSurface, wrap: "wrap", children: displayRaw }) });
|
|
45329
45595
|
}
|
|
45330
45596
|
var BlumaSessionComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
45331
|
-
const agentInstance =
|
|
45332
|
-
const [history, setHistory] =
|
|
45333
|
-
const [statusMessage, setStatusMessage] =
|
|
45597
|
+
const agentInstance = useRef13(null);
|
|
45598
|
+
const [history, setHistory] = useState25([]);
|
|
45599
|
+
const [statusMessage, setStatusMessage] = useState25(
|
|
45334
45600
|
"Initializing agent..."
|
|
45335
45601
|
);
|
|
45336
|
-
const [toolsCount, setToolsCount] =
|
|
45337
|
-
const [mcpStatus, setMcpStatus] =
|
|
45602
|
+
const [toolsCount, setToolsCount] = useState25(null);
|
|
45603
|
+
const [mcpStatus, setMcpStatus] = useState25(
|
|
45338
45604
|
"connecting"
|
|
45339
45605
|
);
|
|
45340
|
-
const [isProcessing, setIsProcessing] =
|
|
45341
|
-
const [pendingConfirmation, setPendingConfirmation] =
|
|
45606
|
+
const [isProcessing, setIsProcessing] = useState25(true);
|
|
45607
|
+
const [pendingConfirmation, setPendingConfirmation] = useState25(
|
|
45342
45608
|
null
|
|
45343
45609
|
);
|
|
45344
|
-
const [confirmationPreview, setConfirmationPreview] =
|
|
45610
|
+
const [confirmationPreview, setConfirmationPreview] = useState25(
|
|
45345
45611
|
null
|
|
45346
45612
|
);
|
|
45347
|
-
const [pendingAskUserQuestions, setPendingAskUserQuestions] =
|
|
45613
|
+
const [pendingAskUserQuestions, setPendingAskUserQuestions] = useState25(null);
|
|
45348
45614
|
const {
|
|
45349
45615
|
tokenCount,
|
|
45350
45616
|
tokenBudget,
|
|
@@ -45357,7 +45623,7 @@ var BlumaSessionComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
45357
45623
|
const { currentPlan, isPlanMode, parseMessage, resetPlan } = usePlanMode();
|
|
45358
45624
|
const { agentMode } = useAgentMode();
|
|
45359
45625
|
const workdir = getSandboxPolicy().workspaceRoot;
|
|
45360
|
-
const lastUpdateRef =
|
|
45626
|
+
const lastUpdateRef = useRef13(0);
|
|
45361
45627
|
useEffect22(() => {
|
|
45362
45628
|
const now2 = Date.now();
|
|
45363
45629
|
if (now2 - lastUpdateRef.current < 250) {
|
|
@@ -45376,29 +45642,29 @@ var BlumaSessionComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
45376
45642
|
activeProjects
|
|
45377
45643
|
});
|
|
45378
45644
|
}, [tokenCount, tokenBudget, isCompressing, compressionProgress, agentMode, isPlanMode, workdir, activeProjects]);
|
|
45379
|
-
const [isInitAgentActive, setIsInitAgentActive] =
|
|
45380
|
-
const [liveToolName, setLiveToolName] =
|
|
45381
|
-
const [liveToolArgs, setLiveToolArgs] =
|
|
45382
|
-
const [isReasoning, setIsReasoning] =
|
|
45383
|
-
const alwaysAcceptList =
|
|
45384
|
-
const turnStartedAtRef =
|
|
45385
|
-
const [processingStartMs, setProcessingStartMs] =
|
|
45386
|
-
const [lastTurnDurationLabel, setLastTurnDurationLabel] =
|
|
45387
|
-
const markTurnStarted =
|
|
45645
|
+
const [isInitAgentActive, setIsInitAgentActive] = useState25(false);
|
|
45646
|
+
const [liveToolName, setLiveToolName] = useState25(null);
|
|
45647
|
+
const [liveToolArgs, setLiveToolArgs] = useState25(void 0);
|
|
45648
|
+
const [isReasoning, setIsReasoning] = useState25(false);
|
|
45649
|
+
const alwaysAcceptList = useRef13([]);
|
|
45650
|
+
const turnStartedAtRef = useRef13(null);
|
|
45651
|
+
const [processingStartMs, setProcessingStartMs] = useState25(null);
|
|
45652
|
+
const [lastTurnDurationLabel, setLastTurnDurationLabel] = useState25(null);
|
|
45653
|
+
const markTurnStarted = useCallback11(() => {
|
|
45388
45654
|
const t = Date.now();
|
|
45389
45655
|
turnStartedAtRef.current = t;
|
|
45390
45656
|
setProcessingStartMs(t);
|
|
45391
45657
|
setLastTurnDurationLabel(null);
|
|
45392
45658
|
}, []);
|
|
45393
|
-
const handleWorkComplete =
|
|
45659
|
+
const handleWorkComplete = useCallback11((elapsedMs) => {
|
|
45394
45660
|
const label = formatTurnDurationMs(elapsedMs);
|
|
45395
45661
|
setLastTurnDurationLabel(label);
|
|
45396
45662
|
}, []);
|
|
45397
|
-
const lastReasoningTextRef =
|
|
45398
|
-
const streamedReasoningTextRef =
|
|
45399
|
-
const activeReasoningHistoryIdRef =
|
|
45400
|
-
const lastStreamAssistantKeyRef =
|
|
45401
|
-
const appendExpandPreviewToHistory =
|
|
45663
|
+
const lastReasoningTextRef = useRef13(null);
|
|
45664
|
+
const streamedReasoningTextRef = useRef13("");
|
|
45665
|
+
const activeReasoningHistoryIdRef = useRef13(null);
|
|
45666
|
+
const lastStreamAssistantKeyRef = useRef13(null);
|
|
45667
|
+
const appendExpandPreviewToHistory = useCallback11(() => {
|
|
45402
45668
|
const p = peekLatestExpandable();
|
|
45403
45669
|
setHistory((prev) => {
|
|
45404
45670
|
const id = nextHistoryId(prev);
|
|
@@ -45443,7 +45709,7 @@ var BlumaSessionComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
45443
45709
|
});
|
|
45444
45710
|
});
|
|
45445
45711
|
}, []);
|
|
45446
|
-
const handleInterrupt =
|
|
45712
|
+
const handleInterrupt = useCallback11(() => {
|
|
45447
45713
|
if (!isProcessing) return;
|
|
45448
45714
|
eventBus.emit("user_interrupt");
|
|
45449
45715
|
turnStartedAtRef.current = null;
|
|
@@ -45460,7 +45726,7 @@ var BlumaSessionComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
45460
45726
|
];
|
|
45461
45727
|
});
|
|
45462
45728
|
}, [isProcessing]);
|
|
45463
|
-
const handleSubmit =
|
|
45729
|
+
const handleSubmit = useCallback11(
|
|
45464
45730
|
(text) => {
|
|
45465
45731
|
if (!text || !agentInstance.current) return;
|
|
45466
45732
|
const trimmedForSlash = text.trim();
|
|
@@ -45709,7 +45975,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
45709
45975
|
[isProcessing, markTurnStarted]
|
|
45710
45976
|
);
|
|
45711
45977
|
const { snapshot: queuedMessages, clear: clearQueue } = useMessageQueue_default();
|
|
45712
|
-
const isAgentIdle =
|
|
45978
|
+
const isAgentIdle = useMemo8(
|
|
45713
45979
|
() => !isProcessing && !pendingConfirmation && !pendingAskUserQuestions?.length && !isInitAgentActive,
|
|
45714
45980
|
[isProcessing, pendingConfirmation, pendingAskUserQuestions, isInitAgentActive]
|
|
45715
45981
|
);
|
|
@@ -45741,7 +46007,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
45741
46007
|
subscription.off("clear_queue", handleClearQueue);
|
|
45742
46008
|
};
|
|
45743
46009
|
}, [queuedMessages.length, clearQueue]);
|
|
45744
|
-
const handleConfirmation =
|
|
46010
|
+
const handleConfirmation = useCallback11(
|
|
45745
46011
|
async (decision, toolCalls, opts) => {
|
|
45746
46012
|
if (!agentInstance.current) return;
|
|
45747
46013
|
setPendingConfirmation(null);
|
|
@@ -45764,7 +46030,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
45764
46030
|
},
|
|
45765
46031
|
[]
|
|
45766
46032
|
);
|
|
45767
|
-
const appendStreamedReasoning =
|
|
46033
|
+
const appendStreamedReasoning = useCallback11((reasoning) => {
|
|
45768
46034
|
const r = String(reasoning ?? "").trim();
|
|
45769
46035
|
if (!r) return;
|
|
45770
46036
|
setHistory((prev) => {
|
|
@@ -45782,7 +46048,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
45782
46048
|
return [...prev, { id, component }];
|
|
45783
46049
|
});
|
|
45784
46050
|
}, []);
|
|
45785
|
-
const appendStreamedAssistant =
|
|
46051
|
+
const appendStreamedAssistant = useCallback11((content) => {
|
|
45786
46052
|
const t = String(content ?? "").trim();
|
|
45787
46053
|
if (!t) return;
|
|
45788
46054
|
const key = reasoningDedupeKey(t);
|
|
@@ -45808,9 +46074,9 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
45808
46074
|
return [...prev, { id, component: nextComponent }];
|
|
45809
46075
|
});
|
|
45810
46076
|
}, []);
|
|
45811
|
-
const handleConfirmationRef =
|
|
46077
|
+
const handleConfirmationRef = useRef13(handleConfirmation);
|
|
45812
46078
|
handleConfirmationRef.current = handleConfirmation;
|
|
45813
|
-
const sessionIdRef =
|
|
46079
|
+
const sessionIdRef = useRef13(sessionId);
|
|
45814
46080
|
sessionIdRef.current = sessionId;
|
|
45815
46081
|
useEffect22(() => {
|
|
45816
46082
|
const initializeAgent = async () => {
|
|
@@ -46103,17 +46369,17 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
46103
46369
|
eventBus.off("backend_message", handleBackendMessage);
|
|
46104
46370
|
};
|
|
46105
46371
|
}, [eventBus, handleConfirmation]);
|
|
46106
|
-
const handleAnswerQuestion =
|
|
46372
|
+
const handleAnswerQuestion = useCallback11((answerJson) => {
|
|
46107
46373
|
setPendingAskUserQuestions(null);
|
|
46108
46374
|
eventBus.emit("ask_user_question_answer", { answer: answerJson });
|
|
46109
46375
|
}, [eventBus]);
|
|
46110
|
-
const handleCancelQuestion =
|
|
46376
|
+
const handleCancelQuestion = useCallback11(() => {
|
|
46111
46377
|
setPendingAskUserQuestions(null);
|
|
46112
46378
|
eventBus.emit("ask_user_question_answer", {
|
|
46113
46379
|
answer: JSON.stringify({ success: false, cancelled: true })
|
|
46114
46380
|
});
|
|
46115
46381
|
}, [eventBus]);
|
|
46116
|
-
const handleDecision =
|
|
46382
|
+
const handleDecision = useCallback11(async (decision) => {
|
|
46117
46383
|
if (!pendingConfirmation || pendingConfirmation.length === 0) return;
|
|
46118
46384
|
const [currentToolCall, ...remainingToolCalls] = pendingConfirmation;
|
|
46119
46385
|
if (!currentToolCall) return;
|
|
@@ -46130,8 +46396,33 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
46130
46396
|
setIsProcessing(false);
|
|
46131
46397
|
}
|
|
46132
46398
|
}, [handleConfirmation, pendingConfirmation]);
|
|
46133
|
-
const
|
|
46134
|
-
|
|
46399
|
+
const scrollBoxRef = useRef13(null);
|
|
46400
|
+
const { columns } = useTerminalSize();
|
|
46401
|
+
const historyKeys = useMemo8(
|
|
46402
|
+
() => history.map((item) => String(item.id)),
|
|
46403
|
+
[history.length, history.length > 0 ? history[history.length - 1].id : 0]
|
|
46404
|
+
);
|
|
46405
|
+
const { range, topSpacer, bottomSpacer, measureRef } = useVirtualScroll(
|
|
46406
|
+
scrollBoxRef,
|
|
46407
|
+
historyKeys,
|
|
46408
|
+
columns
|
|
46409
|
+
);
|
|
46410
|
+
const [lo, hi] = range;
|
|
46411
|
+
const mountedItems = useMemo8(() => {
|
|
46412
|
+
return history.slice(lo, hi);
|
|
46413
|
+
}, [history, lo, hi]);
|
|
46414
|
+
const transcript = useMemo8(() => /* @__PURE__ */ jsx104(Fragment19, { children: /* @__PURE__ */ jsx104(ScrollBox_default, { ref: scrollBoxRef, stickyScroll: true, flexDirection: "column", flexGrow: 1, minHeight: 0, width: "100%", children: /* @__PURE__ */ jsxs85(Box_default, { flexDirection: "column", minHeight: 0, width: "100%", children: [
|
|
46415
|
+
topSpacer > 0 && /* @__PURE__ */ jsx104(Box_default, { height: topSpacer }),
|
|
46416
|
+
mountedItems.map((item) => /* @__PURE__ */ jsx104(
|
|
46417
|
+
Box_default,
|
|
46418
|
+
{
|
|
46419
|
+
flexDirection: "column",
|
|
46420
|
+
ref: measureRef(String(item.id)),
|
|
46421
|
+
children: item.component
|
|
46422
|
+
},
|
|
46423
|
+
item.id
|
|
46424
|
+
)),
|
|
46425
|
+
bottomSpacer > 0 && /* @__PURE__ */ jsx104(Box_default, { height: bottomSpacer }),
|
|
46135
46426
|
/* @__PURE__ */ jsx104(
|
|
46136
46427
|
StreamingText,
|
|
46137
46428
|
{
|
|
@@ -46144,10 +46435,13 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
46144
46435
|
appendStreamedAssistant,
|
|
46145
46436
|
appendStreamedReasoning,
|
|
46146
46437
|
eventBus,
|
|
46147
|
-
|
|
46438
|
+
mountedItems,
|
|
46439
|
+
topSpacer,
|
|
46440
|
+
bottomSpacer,
|
|
46441
|
+
measureRef,
|
|
46148
46442
|
liveToolName
|
|
46149
46443
|
]);
|
|
46150
|
-
const bottomDock =
|
|
46444
|
+
const bottomDock = useMemo8(() => /* @__PURE__ */ jsx104(
|
|
46151
46445
|
BlumaBottomDock,
|
|
46152
46446
|
{
|
|
46153
46447
|
eventBus,
|
|
@@ -46197,9 +46491,9 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
46197
46491
|
statusMessage,
|
|
46198
46492
|
workdir
|
|
46199
46493
|
]);
|
|
46200
|
-
const header =
|
|
46201
|
-
const overlay =
|
|
46202
|
-
const floating =
|
|
46494
|
+
const header = useMemo8(() => /* @__PURE__ */ jsx104(Header, { sessionId, workdir, cliVersion }), [cliVersion, sessionId, workdir]);
|
|
46495
|
+
const overlay = useMemo8(() => /* @__PURE__ */ jsx104(BlumaWorkersOverlay, { sessionId }), [sessionId]);
|
|
46496
|
+
const floating = useMemo8(() => /* @__PURE__ */ jsx104(CoordinatorTaskPanel, {}), []);
|
|
46203
46497
|
return /* @__PURE__ */ jsx104(
|
|
46204
46498
|
BlumaViewport,
|
|
46205
46499
|
{
|
|
@@ -46383,7 +46677,7 @@ import React39 from "react";
|
|
|
46383
46677
|
init_agent_session_paths();
|
|
46384
46678
|
|
|
46385
46679
|
// src/app/ui/components/SessionResumePicker.tsx
|
|
46386
|
-
import { memo as memo26, useCallback as
|
|
46680
|
+
import { memo as memo26, useCallback as useCallback12, useEffect as useEffect23, useMemo as useMemo9, useState as useState26 } from "react";
|
|
46387
46681
|
|
|
46388
46682
|
// src/app/agent/session_manager/session_resume_browser.ts
|
|
46389
46683
|
init_bluma_app_dir();
|
|
@@ -46530,12 +46824,12 @@ var SessionResumePickerComponent = ({
|
|
|
46530
46824
|
4,
|
|
46531
46825
|
Math.min(VISIBLE_DEFAULT, (stdout?.rows ?? 24) - 14)
|
|
46532
46826
|
);
|
|
46533
|
-
const [cwd2, setCwd] =
|
|
46534
|
-
const [entries, setEntries] =
|
|
46535
|
-
const [loading, setLoading] =
|
|
46536
|
-
const [selectedIndex, setSelectedIndex] =
|
|
46537
|
-
const [scrollTop, setScrollTop] =
|
|
46538
|
-
const reload =
|
|
46827
|
+
const [cwd2, setCwd] = useState26("");
|
|
46828
|
+
const [entries, setEntries] = useState26([]);
|
|
46829
|
+
const [loading, setLoading] = useState26(true);
|
|
46830
|
+
const [selectedIndex, setSelectedIndex] = useState26(0);
|
|
46831
|
+
const [scrollTop, setScrollTop] = useState26(0);
|
|
46832
|
+
const reload = useCallback12(async (rel) => {
|
|
46539
46833
|
setLoading(true);
|
|
46540
46834
|
try {
|
|
46541
46835
|
const list = await listSessionBrowserEntries(rel);
|
|
@@ -46561,7 +46855,7 @@ var SessionResumePickerComponent = ({
|
|
|
46561
46855
|
setScrollTop(selectedIndex - visibleCount + 1);
|
|
46562
46856
|
}
|
|
46563
46857
|
}, [selectedIndex, scrollTop, visibleCount]);
|
|
46564
|
-
const windowItems =
|
|
46858
|
+
const windowItems = useMemo9(
|
|
46565
46859
|
() => entries.slice(scrollTop, scrollTop + visibleCount),
|
|
46566
46860
|
[entries, scrollTop, visibleCount]
|
|
46567
46861
|
);
|