snow-ai 0.6.32 → 0.6.33
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/bundle/cli.mjs +1583 -51
- package/bundle/package.json +1 -1
- package/package.json +1 -1
package/bundle/cli.mjs
CHANGED
|
@@ -81929,6 +81929,7 @@ var init_en = __esm({
|
|
|
81929
81929
|
description: "This checkpoint has",
|
|
81930
81930
|
filesCount: "{count} file(s) will be rolled back",
|
|
81931
81931
|
filesCountWithSelection: "{count} file(s) will be rolled back ({selected}/{total} selected)",
|
|
81932
|
+
notebookCount: "{count} notebook(s) will also be rolled back",
|
|
81932
81933
|
question: "Do you want to rollback the files as well?",
|
|
81933
81934
|
yesRollbackFiles: "Yes, rollback files and conversation",
|
|
81934
81935
|
noConversationOnly: "No, rollback conversation only",
|
|
@@ -83179,6 +83180,7 @@ var init_zh = __esm({
|
|
|
83179
83180
|
description: "\u6B64\u68C0\u67E5\u70B9\u5305\u542B",
|
|
83180
83181
|
filesCount: "{count} \u4E2A\u6587\u4EF6\u5C06\u88AB\u56DE\u6EDA",
|
|
83181
83182
|
filesCountWithSelection: "{count} \u4E2A\u6587\u4EF6\u5C06\u88AB\u56DE\u6EDA ({selected}/{total} \u5DF2\u9009\u62E9)",
|
|
83183
|
+
notebookCount: "{count} \u6761\u5907\u5FD8\u5F55\u4E5F\u5C06\u88AB\u56DE\u6EDA",
|
|
83182
83184
|
question: "\u662F\u5426\u540C\u65F6\u56DE\u6EDA\u6587\u4EF6\uFF1F",
|
|
83183
83185
|
yesRollbackFiles: "\u662F\uFF0C\u56DE\u6EDA\u6587\u4EF6\u548C\u5BF9\u8BDD",
|
|
83184
83186
|
noConversationOnly: "\u5426\uFF0C\u4EC5\u56DE\u6EDA\u5BF9\u8BDD",
|
|
@@ -84428,6 +84430,7 @@ var init_zh_TW = __esm({
|
|
|
84428
84430
|
description: "\u6B64\u6AA2\u67E5\u9EDE\u5305\u542B",
|
|
84429
84431
|
filesCount: "{count} \u500B\u6A94\u6848\u5C07\u88AB\u56DE\u6EFE",
|
|
84430
84432
|
filesCountWithSelection: "{count} \u500B\u6A94\u6848\u5C07\u88AB\u56DE\u6EFE ({selected}/{total} \u5DF2\u9078\u64C7)",
|
|
84433
|
+
notebookCount: "{count} \u689D\u5099\u5FD8\u9304\u4E5F\u5C07\u88AB\u56DE\u6EFE",
|
|
84431
84434
|
question: "\u662F\u5426\u540C\u6642\u56DE\u6EFE\u6A94\u6848\uFF1F",
|
|
84432
84435
|
yesRollbackFiles: "\u662F\uFF0C\u56DE\u6EFE\u6A94\u6848\u548C\u5C0D\u8A71",
|
|
84433
84436
|
noConversationOnly: "\u5426\uFF0C\u50C5\u56DE\u6EFE\u5C0D\u8A71",
|
|
@@ -352053,6 +352056,16 @@ function getNotebooksByFile(filePath) {
|
|
|
352053
352056
|
const data = readNotebookData();
|
|
352054
352057
|
return data[normalizedPath] || [];
|
|
352055
352058
|
}
|
|
352059
|
+
function findNotebookById(notebookId) {
|
|
352060
|
+
const data = readNotebookData();
|
|
352061
|
+
for (const [, entries] of Object.entries(data)) {
|
|
352062
|
+
const entry = entries.find((e) => e.id === notebookId);
|
|
352063
|
+
if (entry) {
|
|
352064
|
+
return { ...entry };
|
|
352065
|
+
}
|
|
352066
|
+
}
|
|
352067
|
+
return null;
|
|
352068
|
+
}
|
|
352056
352069
|
function updateNotebook(notebookId, newNote) {
|
|
352057
352070
|
const data = readNotebookData();
|
|
352058
352071
|
let updatedEntry = null;
|
|
@@ -352087,6 +352100,141 @@ function deleteNotebook(notebookId) {
|
|
|
352087
352100
|
}
|
|
352088
352101
|
return found;
|
|
352089
352102
|
}
|
|
352103
|
+
function getNotebookSnapshotFilePath() {
|
|
352104
|
+
const projectRoot = process.cwd();
|
|
352105
|
+
const projectName = path16.basename(projectRoot);
|
|
352106
|
+
const notebookDir = getNotebookDir();
|
|
352107
|
+
return path16.join(notebookDir, `${projectName}_snapshots.json`);
|
|
352108
|
+
}
|
|
352109
|
+
function readNotebookSnapshotData() {
|
|
352110
|
+
const filePath = getNotebookSnapshotFilePath();
|
|
352111
|
+
if (!fs16.existsSync(filePath)) {
|
|
352112
|
+
return {};
|
|
352113
|
+
}
|
|
352114
|
+
try {
|
|
352115
|
+
const content = fs16.readFileSync(filePath, "utf-8");
|
|
352116
|
+
return JSON.parse(content);
|
|
352117
|
+
} catch {
|
|
352118
|
+
return {};
|
|
352119
|
+
}
|
|
352120
|
+
}
|
|
352121
|
+
function saveNotebookSnapshotData(data) {
|
|
352122
|
+
const filePath = getNotebookSnapshotFilePath();
|
|
352123
|
+
try {
|
|
352124
|
+
fs16.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
352125
|
+
} catch (error) {
|
|
352126
|
+
console.error("Failed to save notebook snapshot data:", error);
|
|
352127
|
+
}
|
|
352128
|
+
}
|
|
352129
|
+
function appendNotebookOperation(sessionId, messageIndex, operation) {
|
|
352130
|
+
const data = readNotebookSnapshotData();
|
|
352131
|
+
const key = `${sessionId}:${messageIndex}`;
|
|
352132
|
+
if (!data[key]) {
|
|
352133
|
+
data[key] = [];
|
|
352134
|
+
}
|
|
352135
|
+
data[key].push(operation);
|
|
352136
|
+
saveNotebookSnapshotData(data);
|
|
352137
|
+
}
|
|
352138
|
+
function recordNotebookAddition(sessionId, messageIndex, notebookId) {
|
|
352139
|
+
appendNotebookOperation(sessionId, messageIndex, {
|
|
352140
|
+
op: "add",
|
|
352141
|
+
notebookId
|
|
352142
|
+
});
|
|
352143
|
+
}
|
|
352144
|
+
function recordNotebookUpdate(sessionId, messageIndex, notebookId, previousNote) {
|
|
352145
|
+
appendNotebookOperation(sessionId, messageIndex, {
|
|
352146
|
+
op: "update",
|
|
352147
|
+
notebookId,
|
|
352148
|
+
previousNote
|
|
352149
|
+
});
|
|
352150
|
+
}
|
|
352151
|
+
function recordNotebookDeletion(sessionId, messageIndex, entry) {
|
|
352152
|
+
appendNotebookOperation(sessionId, messageIndex, {
|
|
352153
|
+
op: "delete",
|
|
352154
|
+
entry
|
|
352155
|
+
});
|
|
352156
|
+
}
|
|
352157
|
+
function getNotebookOpsToRollback(sessionId, targetMessageIndex) {
|
|
352158
|
+
const data = readNotebookSnapshotData();
|
|
352159
|
+
const ops = [];
|
|
352160
|
+
for (const [key, operations] of Object.entries(data)) {
|
|
352161
|
+
if (!key.startsWith(`${sessionId}:`))
|
|
352162
|
+
continue;
|
|
352163
|
+
const msgIndex = parseInt(key.split(":")[1] || "", 10);
|
|
352164
|
+
if (!isNaN(msgIndex) && msgIndex >= targetMessageIndex) {
|
|
352165
|
+
ops.push(...operations);
|
|
352166
|
+
}
|
|
352167
|
+
}
|
|
352168
|
+
return ops;
|
|
352169
|
+
}
|
|
352170
|
+
function getNotebookRollbackCount(sessionId, targetMessageIndex) {
|
|
352171
|
+
return getNotebookOpsToRollback(sessionId, targetMessageIndex).length;
|
|
352172
|
+
}
|
|
352173
|
+
function rollbackNotebooks(sessionId, targetMessageIndex) {
|
|
352174
|
+
const ops = getNotebookOpsToRollback(sessionId, targetMessageIndex);
|
|
352175
|
+
let rolledBackCount = 0;
|
|
352176
|
+
for (let i = ops.length - 1; i >= 0; i--) {
|
|
352177
|
+
const op2 = ops[i];
|
|
352178
|
+
if (!op2)
|
|
352179
|
+
continue;
|
|
352180
|
+
try {
|
|
352181
|
+
switch (op2.op) {
|
|
352182
|
+
case "add":
|
|
352183
|
+
deleteNotebook(op2.notebookId);
|
|
352184
|
+
rolledBackCount++;
|
|
352185
|
+
break;
|
|
352186
|
+
case "update":
|
|
352187
|
+
updateNotebook(op2.notebookId, op2.previousNote);
|
|
352188
|
+
rolledBackCount++;
|
|
352189
|
+
break;
|
|
352190
|
+
case "delete": {
|
|
352191
|
+
const data = readNotebookData();
|
|
352192
|
+
const fp = op2.entry.filePath;
|
|
352193
|
+
if (!data[fp]) {
|
|
352194
|
+
data[fp] = [];
|
|
352195
|
+
}
|
|
352196
|
+
data[fp].unshift(op2.entry);
|
|
352197
|
+
saveNotebookData(data);
|
|
352198
|
+
rolledBackCount++;
|
|
352199
|
+
break;
|
|
352200
|
+
}
|
|
352201
|
+
}
|
|
352202
|
+
} catch (error) {
|
|
352203
|
+
console.error(`Failed to rollback notebook operation:`, error);
|
|
352204
|
+
}
|
|
352205
|
+
}
|
|
352206
|
+
deleteNotebookSnapshotsFromIndex(sessionId, targetMessageIndex);
|
|
352207
|
+
return rolledBackCount;
|
|
352208
|
+
}
|
|
352209
|
+
function deleteNotebookSnapshotsFromIndex(sessionId, targetMessageIndex) {
|
|
352210
|
+
const data = readNotebookSnapshotData();
|
|
352211
|
+
let changed = false;
|
|
352212
|
+
for (const key of Object.keys(data)) {
|
|
352213
|
+
if (!key.startsWith(`${sessionId}:`))
|
|
352214
|
+
continue;
|
|
352215
|
+
const msgIndex = parseInt(key.split(":")[1] || "", 10);
|
|
352216
|
+
if (!isNaN(msgIndex) && msgIndex >= targetMessageIndex) {
|
|
352217
|
+
delete data[key];
|
|
352218
|
+
changed = true;
|
|
352219
|
+
}
|
|
352220
|
+
}
|
|
352221
|
+
if (changed) {
|
|
352222
|
+
saveNotebookSnapshotData(data);
|
|
352223
|
+
}
|
|
352224
|
+
}
|
|
352225
|
+
function clearAllNotebookSnapshots(sessionId) {
|
|
352226
|
+
const data = readNotebookSnapshotData();
|
|
352227
|
+
let changed = false;
|
|
352228
|
+
for (const key of Object.keys(data)) {
|
|
352229
|
+
if (key.startsWith(`${sessionId}:`)) {
|
|
352230
|
+
delete data[key];
|
|
352231
|
+
changed = true;
|
|
352232
|
+
}
|
|
352233
|
+
}
|
|
352234
|
+
if (changed) {
|
|
352235
|
+
saveNotebookSnapshotData(data);
|
|
352236
|
+
}
|
|
352237
|
+
}
|
|
352090
352238
|
var MAX_ENTRIES_PER_FILE;
|
|
352091
352239
|
var init_notebookManager = __esm({
|
|
352092
352240
|
"dist/utils/core/notebookManager.js"() {
|
|
@@ -361462,7 +361610,7 @@ var require_lib12 = __commonJS({
|
|
|
361462
361610
|
module2.exports._canonicalizeEncoding = function(encoding) {
|
|
361463
361611
|
return ("" + encoding).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, "");
|
|
361464
361612
|
};
|
|
361465
|
-
module2.exports.getEncoder = function
|
|
361613
|
+
module2.exports.getEncoder = function getEncoder2(encoding, options3) {
|
|
361466
361614
|
var codec = module2.exports.getCodec(encoding);
|
|
361467
361615
|
var encoder = new codec.encoder(options3, codec);
|
|
361468
361616
|
if (codec.bomAware && options3 && options3.addBOM) {
|
|
@@ -438009,11 +438157,11 @@ var init_compactAgent = __esm({
|
|
|
438009
438157
|
let chunkCount = 0;
|
|
438010
438158
|
let encoder;
|
|
438011
438159
|
try {
|
|
438012
|
-
const { encoding_for_model:
|
|
438013
|
-
encoder =
|
|
438160
|
+
const { encoding_for_model: encoding_for_model3 } = await Promise.resolve().then(() => __toESM(require_tiktoken(), 1));
|
|
438161
|
+
encoder = encoding_for_model3("gpt-5");
|
|
438014
438162
|
} catch (e) {
|
|
438015
|
-
const { encoding_for_model:
|
|
438016
|
-
encoder =
|
|
438163
|
+
const { encoding_for_model: encoding_for_model3 } = await Promise.resolve().then(() => __toESM(require_tiktoken(), 1));
|
|
438164
|
+
encoder = encoding_for_model3("gpt-5");
|
|
438017
438165
|
}
|
|
438018
438166
|
try {
|
|
438019
438167
|
for await (const chunk2 of streamGenerator) {
|
|
@@ -443046,6 +443194,13 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
443046
443194
|
};
|
|
443047
443195
|
}
|
|
443048
443196
|
const entry = addNotebook(filePath, note);
|
|
443197
|
+
try {
|
|
443198
|
+
const context2 = getConversationContext();
|
|
443199
|
+
if (context2) {
|
|
443200
|
+
recordNotebookAddition(context2.sessionId, context2.messageIndex, entry.id);
|
|
443201
|
+
}
|
|
443202
|
+
} catch {
|
|
443203
|
+
}
|
|
443049
443204
|
return {
|
|
443050
443205
|
content: [
|
|
443051
443206
|
{
|
|
@@ -443113,6 +443268,8 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
443113
443268
|
isError: true
|
|
443114
443269
|
};
|
|
443115
443270
|
}
|
|
443271
|
+
const previousEntry = findNotebookById(notebookId);
|
|
443272
|
+
const previousNote = previousEntry == null ? void 0 : previousEntry.note;
|
|
443116
443273
|
const updatedEntry = updateNotebook(notebookId, note);
|
|
443117
443274
|
if (!updatedEntry) {
|
|
443118
443275
|
return {
|
|
@@ -443128,6 +443285,13 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
443128
443285
|
isError: true
|
|
443129
443286
|
};
|
|
443130
443287
|
}
|
|
443288
|
+
try {
|
|
443289
|
+
const context2 = getConversationContext();
|
|
443290
|
+
if (context2 && previousNote !== void 0) {
|
|
443291
|
+
recordNotebookUpdate(context2.sessionId, context2.messageIndex, notebookId, previousNote);
|
|
443292
|
+
}
|
|
443293
|
+
} catch {
|
|
443294
|
+
}
|
|
443131
443295
|
return {
|
|
443132
443296
|
content: [
|
|
443133
443297
|
{
|
|
@@ -443159,6 +443323,7 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
443159
443323
|
isError: true
|
|
443160
443324
|
};
|
|
443161
443325
|
}
|
|
443326
|
+
const entryToDelete = findNotebookById(notebookId);
|
|
443162
443327
|
const deleted = deleteNotebook(notebookId);
|
|
443163
443328
|
if (!deleted) {
|
|
443164
443329
|
return {
|
|
@@ -443174,6 +443339,13 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
443174
443339
|
isError: true
|
|
443175
443340
|
};
|
|
443176
443341
|
}
|
|
443342
|
+
try {
|
|
443343
|
+
const context2 = getConversationContext();
|
|
443344
|
+
if (context2 && entryToDelete) {
|
|
443345
|
+
recordNotebookDeletion(context2.sessionId, context2.messageIndex, entryToDelete);
|
|
443346
|
+
}
|
|
443347
|
+
} catch {
|
|
443348
|
+
}
|
|
443177
443349
|
return {
|
|
443178
443350
|
content: [
|
|
443179
443351
|
{
|
|
@@ -443247,6 +443419,7 @@ var init_notebook = __esm({
|
|
|
443247
443419
|
"dist/mcp/notebook.js"() {
|
|
443248
443420
|
"use strict";
|
|
443249
443421
|
init_notebookManager();
|
|
443422
|
+
init_conversationContext();
|
|
443250
443423
|
mcpTools8 = [
|
|
443251
443424
|
{
|
|
443252
443425
|
name: "notebook-add",
|
|
@@ -444803,6 +444976,368 @@ var init_yoloPermissionChecker = __esm({
|
|
|
444803
444976
|
}
|
|
444804
444977
|
});
|
|
444805
444978
|
|
|
444979
|
+
// dist/utils/core/subAgentContextCompressor.js
|
|
444980
|
+
function getEncoder() {
|
|
444981
|
+
if (!_encoder) {
|
|
444982
|
+
try {
|
|
444983
|
+
_encoder = (0, import_tiktoken.encoding_for_model)("gpt-4o");
|
|
444984
|
+
} catch {
|
|
444985
|
+
_encoder = (0, import_tiktoken.encoding_for_model)("gpt-3.5-turbo");
|
|
444986
|
+
}
|
|
444987
|
+
}
|
|
444988
|
+
return _encoder;
|
|
444989
|
+
}
|
|
444990
|
+
function countMessagesTokens(messages) {
|
|
444991
|
+
var _a21, _b14;
|
|
444992
|
+
try {
|
|
444993
|
+
const encoder = getEncoder();
|
|
444994
|
+
let total = 0;
|
|
444995
|
+
for (const msg of messages) {
|
|
444996
|
+
if (msg.content) {
|
|
444997
|
+
total += encoder.encode(msg.content).length;
|
|
444998
|
+
}
|
|
444999
|
+
if (msg.tool_calls) {
|
|
445000
|
+
for (const tc of msg.tool_calls) {
|
|
445001
|
+
if ((_a21 = tc.function) == null ? void 0 : _a21.arguments) {
|
|
445002
|
+
total += encoder.encode(tc.function.arguments).length;
|
|
445003
|
+
}
|
|
445004
|
+
if ((_b14 = tc.function) == null ? void 0 : _b14.name) {
|
|
445005
|
+
total += encoder.encode(tc.function.name).length;
|
|
445006
|
+
}
|
|
445007
|
+
}
|
|
445008
|
+
}
|
|
445009
|
+
total += 4;
|
|
445010
|
+
}
|
|
445011
|
+
return total;
|
|
445012
|
+
} catch (error) {
|
|
445013
|
+
console.error("[SubAgentCompressor] tiktoken counting failed:", error);
|
|
445014
|
+
const totalChars = messages.reduce((sum, m) => {
|
|
445015
|
+
var _a22;
|
|
445016
|
+
return sum + (((_a22 = m.content) == null ? void 0 : _a22.length) || 0);
|
|
445017
|
+
}, 0);
|
|
445018
|
+
return Math.round(totalChars / 4);
|
|
445019
|
+
}
|
|
445020
|
+
}
|
|
445021
|
+
function getContextPercentage(totalTokens, maxContextTokens) {
|
|
445022
|
+
if (!maxContextTokens || maxContextTokens <= 0)
|
|
445023
|
+
return 0;
|
|
445024
|
+
return Math.min(100, totalTokens / maxContextTokens * 100);
|
|
445025
|
+
}
|
|
445026
|
+
function shouldCompressSubAgentContext(totalTokens, maxContextTokens) {
|
|
445027
|
+
return getContextPercentage(totalTokens, maxContextTokens) >= COMPRESS_THRESHOLD;
|
|
445028
|
+
}
|
|
445029
|
+
function getAdaptiveKeepRounds(percentage) {
|
|
445030
|
+
if (percentage >= 95)
|
|
445031
|
+
return 1;
|
|
445032
|
+
if (percentage >= 85)
|
|
445033
|
+
return 2;
|
|
445034
|
+
return DEFAULT_KEEP_RECENT_ROUNDS;
|
|
445035
|
+
}
|
|
445036
|
+
function findRecentRoundsStartIndex(messages, keepRounds) {
|
|
445037
|
+
var _a21, _b14, _c6, _d4;
|
|
445038
|
+
let roundCount = 0;
|
|
445039
|
+
let i = messages.length - 1;
|
|
445040
|
+
while (i >= 0 && roundCount < keepRounds) {
|
|
445041
|
+
const msg = messages[i];
|
|
445042
|
+
if ((msg == null ? void 0 : msg.role) === "tool") {
|
|
445043
|
+
while (i >= 0 && ((_a21 = messages[i]) == null ? void 0 : _a21.role) === "tool") {
|
|
445044
|
+
i--;
|
|
445045
|
+
}
|
|
445046
|
+
if (i >= 0 && ((_b14 = messages[i]) == null ? void 0 : _b14.role) === "assistant" && ((_d4 = (_c6 = messages[i]) == null ? void 0 : _c6.tool_calls) == null ? void 0 : _d4.length)) {
|
|
445047
|
+
roundCount++;
|
|
445048
|
+
i--;
|
|
445049
|
+
}
|
|
445050
|
+
} else {
|
|
445051
|
+
i--;
|
|
445052
|
+
}
|
|
445053
|
+
}
|
|
445054
|
+
return Math.max(0, i + 1);
|
|
445055
|
+
}
|
|
445056
|
+
function formatMessageForTranscript(msg) {
|
|
445057
|
+
var _a21, _b14;
|
|
445058
|
+
if (msg.role === "tool") {
|
|
445059
|
+
return null;
|
|
445060
|
+
}
|
|
445061
|
+
if (msg.role === "system") {
|
|
445062
|
+
return null;
|
|
445063
|
+
}
|
|
445064
|
+
const parts = [];
|
|
445065
|
+
const roleLabel = msg.role === "user" ? "[User]" : "[Assistant]";
|
|
445066
|
+
if (msg.role === "assistant" && msg.tool_calls && msg.tool_calls.length > 0) {
|
|
445067
|
+
if (msg.content) {
|
|
445068
|
+
parts.push(`${roleLabel}
|
|
445069
|
+
${msg.content}`);
|
|
445070
|
+
} else {
|
|
445071
|
+
parts.push(roleLabel);
|
|
445072
|
+
}
|
|
445073
|
+
for (const tc of msg.tool_calls) {
|
|
445074
|
+
const funcName = ((_a21 = tc.function) == null ? void 0 : _a21.name) || "unknown";
|
|
445075
|
+
const args2 = ((_b14 = tc.function) == null ? void 0 : _b14.arguments) || "{}";
|
|
445076
|
+
const truncatedArgs = args2.length > 500 ? args2.substring(0, 500) + "..." : args2;
|
|
445077
|
+
parts.push(` -> Tool Call: ${funcName}(${truncatedArgs})`);
|
|
445078
|
+
}
|
|
445079
|
+
return parts.join("\n");
|
|
445080
|
+
}
|
|
445081
|
+
if (msg.content) {
|
|
445082
|
+
parts.push(`${roleLabel}
|
|
445083
|
+
${msg.content}`);
|
|
445084
|
+
}
|
|
445085
|
+
return parts.length > 0 ? parts.join("\n") : null;
|
|
445086
|
+
}
|
|
445087
|
+
function prepareMessagesForAICompression(conversationMessages) {
|
|
445088
|
+
const messages = [];
|
|
445089
|
+
messages.push({
|
|
445090
|
+
role: "system",
|
|
445091
|
+
content: "You are a technical summarization assistant. Your job is to compress a tool-using AI agent's conversation history into a concise but complete handover document."
|
|
445092
|
+
});
|
|
445093
|
+
const transcriptParts = [];
|
|
445094
|
+
for (const msg of conversationMessages) {
|
|
445095
|
+
const formatted = formatMessageForTranscript(msg);
|
|
445096
|
+
if (formatted) {
|
|
445097
|
+
transcriptParts.push(formatted);
|
|
445098
|
+
}
|
|
445099
|
+
}
|
|
445100
|
+
const transcript = transcriptParts.join("\n\n---\n\n");
|
|
445101
|
+
messages.push({
|
|
445102
|
+
role: "user",
|
|
445103
|
+
content: `## Sub-Agent Conversation History to Compress
|
|
445104
|
+
|
|
445105
|
+
${transcript}`
|
|
445106
|
+
});
|
|
445107
|
+
messages.push({
|
|
445108
|
+
role: "user",
|
|
445109
|
+
content: SUB_AGENT_COMPRESSION_PROMPT
|
|
445110
|
+
});
|
|
445111
|
+
return messages;
|
|
445112
|
+
}
|
|
445113
|
+
async function aiSummaryCompress(messages, keepRounds, config3) {
|
|
445114
|
+
const preserveStartIndex = findRecentRoundsStartIndex(messages, keepRounds);
|
|
445115
|
+
if (preserveStartIndex === 0) {
|
|
445116
|
+
return messages;
|
|
445117
|
+
}
|
|
445118
|
+
const messagesToCompress = messages.slice(0, preserveStartIndex);
|
|
445119
|
+
const preservedMessages = messages.slice(preserveStartIndex);
|
|
445120
|
+
const compressionMessages = prepareMessagesForAICompression(messagesToCompress);
|
|
445121
|
+
let summary = "";
|
|
445122
|
+
try {
|
|
445123
|
+
switch (config3.requestMethod) {
|
|
445124
|
+
case "gemini": {
|
|
445125
|
+
for await (const chunk2 of createStreamingGeminiCompletion({
|
|
445126
|
+
model: config3.model,
|
|
445127
|
+
messages: compressionMessages,
|
|
445128
|
+
configProfile: config3.configProfile
|
|
445129
|
+
})) {
|
|
445130
|
+
if (chunk2.type === "content" && chunk2.content) {
|
|
445131
|
+
summary += chunk2.content;
|
|
445132
|
+
}
|
|
445133
|
+
}
|
|
445134
|
+
break;
|
|
445135
|
+
}
|
|
445136
|
+
case "anthropic": {
|
|
445137
|
+
for await (const chunk2 of createStreamingAnthropicCompletion({
|
|
445138
|
+
model: config3.model,
|
|
445139
|
+
messages: compressionMessages,
|
|
445140
|
+
max_tokens: config3.maxTokens || 4096,
|
|
445141
|
+
disableThinking: true,
|
|
445142
|
+
configProfile: config3.configProfile
|
|
445143
|
+
})) {
|
|
445144
|
+
if (chunk2.type === "content" && chunk2.content) {
|
|
445145
|
+
summary += chunk2.content;
|
|
445146
|
+
}
|
|
445147
|
+
}
|
|
445148
|
+
break;
|
|
445149
|
+
}
|
|
445150
|
+
case "responses": {
|
|
445151
|
+
for await (const chunk2 of createStreamingResponse({
|
|
445152
|
+
model: config3.model,
|
|
445153
|
+
messages: compressionMessages,
|
|
445154
|
+
configProfile: config3.configProfile
|
|
445155
|
+
})) {
|
|
445156
|
+
if (chunk2.type === "content" && chunk2.content) {
|
|
445157
|
+
summary += chunk2.content;
|
|
445158
|
+
}
|
|
445159
|
+
}
|
|
445160
|
+
break;
|
|
445161
|
+
}
|
|
445162
|
+
case "chat":
|
|
445163
|
+
default: {
|
|
445164
|
+
for await (const chunk2 of createStreamingChatCompletion({
|
|
445165
|
+
model: config3.model,
|
|
445166
|
+
messages: compressionMessages,
|
|
445167
|
+
stream: true,
|
|
445168
|
+
configProfile: config3.configProfile
|
|
445169
|
+
})) {
|
|
445170
|
+
if (chunk2.type === "content" && chunk2.content) {
|
|
445171
|
+
summary += chunk2.content;
|
|
445172
|
+
}
|
|
445173
|
+
}
|
|
445174
|
+
break;
|
|
445175
|
+
}
|
|
445176
|
+
}
|
|
445177
|
+
} catch (error) {
|
|
445178
|
+
console.error("[SubAgentCompressor] AI compression failed:", error);
|
|
445179
|
+
return messages;
|
|
445180
|
+
}
|
|
445181
|
+
if (!summary) {
|
|
445182
|
+
console.warn("[SubAgentCompressor] AI compression returned empty summary");
|
|
445183
|
+
return messages;
|
|
445184
|
+
}
|
|
445185
|
+
const newMessages = [
|
|
445186
|
+
{
|
|
445187
|
+
role: "user",
|
|
445188
|
+
content: `## Previous Context (Auto-Compressed Summary)
|
|
445189
|
+
|
|
445190
|
+
${summary}
|
|
445191
|
+
|
|
445192
|
+
---
|
|
445193
|
+
|
|
445194
|
+
*The above is a compressed summary of earlier conversation. Continue the task based on this context and the recent tool interactions below.*`
|
|
445195
|
+
},
|
|
445196
|
+
...preservedMessages
|
|
445197
|
+
];
|
|
445198
|
+
return newMessages;
|
|
445199
|
+
}
|
|
445200
|
+
function truncateToolResults(messages, keepRounds) {
|
|
445201
|
+
if (messages.length === 0)
|
|
445202
|
+
return [];
|
|
445203
|
+
const preserveStartIndex = findRecentRoundsStartIndex(messages, keepRounds);
|
|
445204
|
+
const result2 = [];
|
|
445205
|
+
const MIN_TRUNCATION_LENGTH = 500;
|
|
445206
|
+
const MAX_PRESERVED_CHARS = 2e3;
|
|
445207
|
+
for (let i = 0; i < messages.length; i++) {
|
|
445208
|
+
const msg = messages[i];
|
|
445209
|
+
if (!msg)
|
|
445210
|
+
continue;
|
|
445211
|
+
const findToolName = () => {
|
|
445212
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
445213
|
+
const prev = messages[j];
|
|
445214
|
+
if ((prev == null ? void 0 : prev.role) === "assistant" && prev.tool_calls) {
|
|
445215
|
+
const match2 = prev.tool_calls.find((tc) => tc.id === msg.tool_call_id);
|
|
445216
|
+
if (match2)
|
|
445217
|
+
return match2.function.name;
|
|
445218
|
+
}
|
|
445219
|
+
if ((prev == null ? void 0 : prev.role) !== "tool")
|
|
445220
|
+
break;
|
|
445221
|
+
}
|
|
445222
|
+
return "unknown";
|
|
445223
|
+
};
|
|
445224
|
+
if (i < preserveStartIndex) {
|
|
445225
|
+
if (msg.role === "tool" && msg.content && msg.content.length > MIN_TRUNCATION_LENGTH) {
|
|
445226
|
+
result2.push({
|
|
445227
|
+
...msg,
|
|
445228
|
+
content: `[Tool result truncated: ${findToolName()}, original ${msg.content.length} chars]`
|
|
445229
|
+
});
|
|
445230
|
+
} else {
|
|
445231
|
+
result2.push(msg);
|
|
445232
|
+
}
|
|
445233
|
+
continue;
|
|
445234
|
+
}
|
|
445235
|
+
if (msg.role === "tool" && msg.content && msg.content.length > MAX_PRESERVED_CHARS) {
|
|
445236
|
+
const toolName = findToolName();
|
|
445237
|
+
const keepStart = Math.floor(MAX_PRESERVED_CHARS * 0.6);
|
|
445238
|
+
const keepEnd = Math.floor(MAX_PRESERVED_CHARS * 0.3);
|
|
445239
|
+
const truncated = msg.content.length - keepStart - keepEnd;
|
|
445240
|
+
result2.push({
|
|
445241
|
+
...msg,
|
|
445242
|
+
content: msg.content.substring(0, keepStart) + `
|
|
445243
|
+
|
|
445244
|
+
[... ${truncated} chars truncated from ${toolName} result ...]
|
|
445245
|
+
|
|
445246
|
+
` + msg.content.substring(msg.content.length - keepEnd)
|
|
445247
|
+
});
|
|
445248
|
+
} else {
|
|
445249
|
+
result2.push(msg);
|
|
445250
|
+
}
|
|
445251
|
+
}
|
|
445252
|
+
return result2;
|
|
445253
|
+
}
|
|
445254
|
+
async function compressSubAgentContext(messages, totalTokens, maxContextTokens, config3) {
|
|
445255
|
+
const percentage = getContextPercentage(totalTokens, maxContextTokens);
|
|
445256
|
+
if (percentage < COMPRESS_THRESHOLD) {
|
|
445257
|
+
return {
|
|
445258
|
+
compressed: false,
|
|
445259
|
+
messages
|
|
445260
|
+
};
|
|
445261
|
+
}
|
|
445262
|
+
const keepRounds = getAdaptiveKeepRounds(percentage);
|
|
445263
|
+
const compressedMessages = await aiSummaryCompress(messages, keepRounds, config3);
|
|
445264
|
+
if (compressedMessages !== messages) {
|
|
445265
|
+
const afterTokens2 = countMessagesTokens(compressedMessages);
|
|
445266
|
+
return {
|
|
445267
|
+
compressed: true,
|
|
445268
|
+
messages: compressedMessages,
|
|
445269
|
+
beforeTokens: totalTokens,
|
|
445270
|
+
afterTokensEstimate: afterTokens2
|
|
445271
|
+
};
|
|
445272
|
+
}
|
|
445273
|
+
console.warn(`[SubAgentCompressor] AI compression ineffective, falling back to truncation`);
|
|
445274
|
+
const truncatedMessages = truncateToolResults(messages, keepRounds);
|
|
445275
|
+
const afterTokens = countMessagesTokens(truncatedMessages);
|
|
445276
|
+
if (afterTokens < totalTokens) {
|
|
445277
|
+
return {
|
|
445278
|
+
compressed: true,
|
|
445279
|
+
messages: truncatedMessages,
|
|
445280
|
+
beforeTokens: totalTokens,
|
|
445281
|
+
afterTokensEstimate: afterTokens
|
|
445282
|
+
};
|
|
445283
|
+
}
|
|
445284
|
+
return {
|
|
445285
|
+
compressed: false,
|
|
445286
|
+
messages
|
|
445287
|
+
};
|
|
445288
|
+
}
|
|
445289
|
+
var import_tiktoken, COMPRESS_THRESHOLD, DEFAULT_KEEP_RECENT_ROUNDS, SUB_AGENT_COMPRESSION_PROMPT, _encoder;
|
|
445290
|
+
var init_subAgentContextCompressor = __esm({
|
|
445291
|
+
"dist/utils/core/subAgentContextCompressor.js"() {
|
|
445292
|
+
"use strict";
|
|
445293
|
+
import_tiktoken = __toESM(require_tiktoken(), 1);
|
|
445294
|
+
init_chat();
|
|
445295
|
+
init_responses();
|
|
445296
|
+
init_gemini();
|
|
445297
|
+
init_anthropic();
|
|
445298
|
+
COMPRESS_THRESHOLD = 80;
|
|
445299
|
+
DEFAULT_KEEP_RECENT_ROUNDS = 3;
|
|
445300
|
+
SUB_AGENT_COMPRESSION_PROMPT = `**TASK: Create a concise handover document from the sub-agent conversation history above.**
|
|
445301
|
+
|
|
445302
|
+
You are creating a technical handover document for a tool-using AI agent. Extract and preserve all critical information with rigorous detail.
|
|
445303
|
+
|
|
445304
|
+
**OUTPUT FORMAT:**
|
|
445305
|
+
|
|
445306
|
+
## Task Objective
|
|
445307
|
+
- What the agent was asked to do
|
|
445308
|
+
- Current completion status
|
|
445309
|
+
|
|
445310
|
+
## Key Findings
|
|
445311
|
+
- Important information discovered via tool calls
|
|
445312
|
+
- **EXACT** file paths, function names, code identifiers
|
|
445313
|
+
- Search results, code patterns, architecture details
|
|
445314
|
+
|
|
445315
|
+
## Actions Taken
|
|
445316
|
+
- Files read/modified (with exact paths)
|
|
445317
|
+
- Commands executed and their outcomes
|
|
445318
|
+
- Tools used and their results (key details only)
|
|
445319
|
+
|
|
445320
|
+
## Work In Progress
|
|
445321
|
+
- Incomplete tasks with specific reasons
|
|
445322
|
+
- Planned next steps (concrete, actionable)
|
|
445323
|
+
- Known issues and blockers
|
|
445324
|
+
|
|
445325
|
+
## Critical Reference Data
|
|
445326
|
+
- Important values, IDs, error messages (exact wording)
|
|
445327
|
+
- User requirements and constraints
|
|
445328
|
+
- Edge cases and special handling
|
|
445329
|
+
|
|
445330
|
+
**QUALITY REQUIREMENTS:**
|
|
445331
|
+
1. Preserve EXACT technical terms \u2014 never paraphrase code/file names
|
|
445332
|
+
2. Include FULL context \u2014 paths, versions, configurations
|
|
445333
|
+
3. NO vague summaries \u2014 provide actionable, specific details
|
|
445334
|
+
4. Use markdown code blocks for code snippets
|
|
445335
|
+
|
|
445336
|
+
**EXECUTE NOW \u2014 Output the handover document immediately.**`;
|
|
445337
|
+
_encoder = null;
|
|
445338
|
+
}
|
|
445339
|
+
});
|
|
445340
|
+
|
|
444806
445341
|
// dist/utils/execution/runningSubAgentTracker.js
|
|
444807
445342
|
var runningSubAgentTracker_exports = {};
|
|
444808
445343
|
__export(runningSubAgentTracker_exports, {
|
|
@@ -444838,6 +445373,24 @@ var init_runningSubAgentTracker = __esm({
|
|
|
444838
445373
|
writable: true,
|
|
444839
445374
|
value: /* @__PURE__ */ new Map()
|
|
444840
445375
|
});
|
|
445376
|
+
Object.defineProperty(this, "interAgentQueues", {
|
|
445377
|
+
enumerable: true,
|
|
445378
|
+
configurable: true,
|
|
445379
|
+
writable: true,
|
|
445380
|
+
value: /* @__PURE__ */ new Map()
|
|
445381
|
+
});
|
|
445382
|
+
Object.defineProperty(this, "spawnedResults", {
|
|
445383
|
+
enumerable: true,
|
|
445384
|
+
configurable: true,
|
|
445385
|
+
writable: true,
|
|
445386
|
+
value: []
|
|
445387
|
+
});
|
|
445388
|
+
Object.defineProperty(this, "interAgentListeners", {
|
|
445389
|
+
enumerable: true,
|
|
445390
|
+
configurable: true,
|
|
445391
|
+
writable: true,
|
|
445392
|
+
value: /* @__PURE__ */ new Set()
|
|
445393
|
+
});
|
|
444841
445394
|
}
|
|
444842
445395
|
/**
|
|
444843
445396
|
* Register a running sub-agent
|
|
@@ -444845,6 +445398,7 @@ var init_runningSubAgentTracker = __esm({
|
|
|
444845
445398
|
register(agent) {
|
|
444846
445399
|
this.agents.set(agent.instanceId, agent);
|
|
444847
445400
|
this.messageQueues.set(agent.instanceId, []);
|
|
445401
|
+
this.interAgentQueues.set(agent.instanceId, []);
|
|
444848
445402
|
this.rebuildSnapshot();
|
|
444849
445403
|
this.notifyListeners();
|
|
444850
445404
|
}
|
|
@@ -444854,6 +445408,7 @@ var init_runningSubAgentTracker = __esm({
|
|
|
444854
445408
|
unregister(instanceId) {
|
|
444855
445409
|
if (this.agents.delete(instanceId)) {
|
|
444856
445410
|
this.messageQueues.delete(instanceId);
|
|
445411
|
+
this.interAgentQueues.delete(instanceId);
|
|
444857
445412
|
this.rebuildSnapshot();
|
|
444858
445413
|
this.notifyListeners();
|
|
444859
445414
|
}
|
|
@@ -444878,6 +445433,68 @@ var init_runningSubAgentTracker = __esm({
|
|
|
444878
445433
|
isRunning(instanceId) {
|
|
444879
445434
|
return this.agents.has(instanceId);
|
|
444880
445435
|
}
|
|
445436
|
+
/**
|
|
445437
|
+
* Check if there are any spawned sub-agents still running.
|
|
445438
|
+
* Spawned agents have instanceIds starting with "spawn-".
|
|
445439
|
+
*/
|
|
445440
|
+
hasRunningSpawnedAgents() {
|
|
445441
|
+
for (const instanceId of this.agents.keys()) {
|
|
445442
|
+
if (instanceId.startsWith("spawn-")) {
|
|
445443
|
+
return true;
|
|
445444
|
+
}
|
|
445445
|
+
}
|
|
445446
|
+
return false;
|
|
445447
|
+
}
|
|
445448
|
+
/**
|
|
445449
|
+
* Wait for all spawned agents to complete, with a timeout.
|
|
445450
|
+
* Resolves when all spawned agents finish or the timeout is reached.
|
|
445451
|
+
* @param timeoutMs Maximum time to wait in milliseconds (default: 5 minutes)
|
|
445452
|
+
* @param abortSignal Optional abort signal to cancel waiting early
|
|
445453
|
+
* @returns true if all spawned agents completed, false if timed out or aborted
|
|
445454
|
+
*/
|
|
445455
|
+
waitForSpawnedAgents(timeoutMs = 3e5, abortSignal) {
|
|
445456
|
+
return new Promise((resolve12) => {
|
|
445457
|
+
if (!this.hasRunningSpawnedAgents()) {
|
|
445458
|
+
resolve12(true);
|
|
445459
|
+
return;
|
|
445460
|
+
}
|
|
445461
|
+
const startTime = Date.now();
|
|
445462
|
+
let unsubscribe;
|
|
445463
|
+
const checkDone = () => {
|
|
445464
|
+
if (abortSignal == null ? void 0 : abortSignal.aborted) {
|
|
445465
|
+
cleanup();
|
|
445466
|
+
resolve12(false);
|
|
445467
|
+
return;
|
|
445468
|
+
}
|
|
445469
|
+
if (!this.hasRunningSpawnedAgents()) {
|
|
445470
|
+
cleanup();
|
|
445471
|
+
resolve12(true);
|
|
445472
|
+
return;
|
|
445473
|
+
}
|
|
445474
|
+
if (Date.now() - startTime > timeoutMs) {
|
|
445475
|
+
cleanup();
|
|
445476
|
+
resolve12(false);
|
|
445477
|
+
return;
|
|
445478
|
+
}
|
|
445479
|
+
};
|
|
445480
|
+
const cleanup = () => {
|
|
445481
|
+
if (unsubscribe) {
|
|
445482
|
+
unsubscribe();
|
|
445483
|
+
unsubscribe = void 0;
|
|
445484
|
+
}
|
|
445485
|
+
};
|
|
445486
|
+
unsubscribe = this.subscribe(() => {
|
|
445487
|
+
checkDone();
|
|
445488
|
+
});
|
|
445489
|
+
if (abortSignal) {
|
|
445490
|
+
abortSignal.addEventListener("abort", () => {
|
|
445491
|
+
cleanup();
|
|
445492
|
+
resolve12(false);
|
|
445493
|
+
}, { once: true });
|
|
445494
|
+
}
|
|
445495
|
+
checkDone();
|
|
445496
|
+
});
|
|
445497
|
+
}
|
|
444881
445498
|
// ── Message queue for injecting user messages into running sub-agents ──
|
|
444882
445499
|
/**
|
|
444883
445500
|
* Enqueue a user message for a running sub-agent.
|
|
@@ -444906,6 +445523,120 @@ var init_runningSubAgentTracker = __esm({
|
|
|
444906
445523
|
queue.length = 0;
|
|
444907
445524
|
return messages;
|
|
444908
445525
|
}
|
|
445526
|
+
// ── Inter-agent messaging ──────────────────────────────────────────────
|
|
445527
|
+
/**
|
|
445528
|
+
* Send a message from one sub-agent to another.
|
|
445529
|
+
* The message is queued for the target and also triggers a listener notification
|
|
445530
|
+
* so that the UI can display the inter-agent communication.
|
|
445531
|
+
* Returns true if the target agent is running and the message was enqueued.
|
|
445532
|
+
*/
|
|
445533
|
+
sendInterAgentMessage(fromInstanceId, targetInstanceId, content) {
|
|
445534
|
+
const queue = this.interAgentQueues.get(targetInstanceId);
|
|
445535
|
+
if (!queue) {
|
|
445536
|
+
return false;
|
|
445537
|
+
}
|
|
445538
|
+
const fromAgent = this.agents.get(fromInstanceId);
|
|
445539
|
+
if (!fromAgent) {
|
|
445540
|
+
return false;
|
|
445541
|
+
}
|
|
445542
|
+
const message = {
|
|
445543
|
+
fromInstanceId,
|
|
445544
|
+
fromAgentId: fromAgent.agentId,
|
|
445545
|
+
fromAgentName: fromAgent.agentName,
|
|
445546
|
+
content,
|
|
445547
|
+
sentAt: /* @__PURE__ */ new Date()
|
|
445548
|
+
};
|
|
445549
|
+
queue.push(message);
|
|
445550
|
+
this.notifyInterAgentListeners(fromAgent, targetInstanceId, message);
|
|
445551
|
+
return true;
|
|
445552
|
+
}
|
|
445553
|
+
/**
|
|
445554
|
+
* Dequeue all pending inter-agent messages for a sub-agent instance.
|
|
445555
|
+
* Called by the sub-agent executor at the top of each while-loop iteration.
|
|
445556
|
+
*/
|
|
445557
|
+
dequeueInterAgentMessages(instanceId) {
|
|
445558
|
+
const queue = this.interAgentQueues.get(instanceId);
|
|
445559
|
+
if (!queue || queue.length === 0) {
|
|
445560
|
+
return [];
|
|
445561
|
+
}
|
|
445562
|
+
const messages = [...queue];
|
|
445563
|
+
queue.length = 0;
|
|
445564
|
+
return messages;
|
|
445565
|
+
}
|
|
445566
|
+
/**
|
|
445567
|
+
* Find a running sub-agent instance by agentId (type).
|
|
445568
|
+
* If multiple instances of the same type are running, returns the first match.
|
|
445569
|
+
* Use this to resolve agentId -> instanceId for inter-agent messaging.
|
|
445570
|
+
*/
|
|
445571
|
+
findInstanceByAgentId(agentId) {
|
|
445572
|
+
for (const agent of this.agents.values()) {
|
|
445573
|
+
if (agent.agentId === agentId) {
|
|
445574
|
+
return agent;
|
|
445575
|
+
}
|
|
445576
|
+
}
|
|
445577
|
+
return void 0;
|
|
445578
|
+
}
|
|
445579
|
+
/**
|
|
445580
|
+
* Find all running sub-agent instances by agentId (type).
|
|
445581
|
+
*/
|
|
445582
|
+
findAllInstancesByAgentId(agentId) {
|
|
445583
|
+
const result2 = [];
|
|
445584
|
+
for (const agent of this.agents.values()) {
|
|
445585
|
+
if (agent.agentId === agentId) {
|
|
445586
|
+
result2.push(agent);
|
|
445587
|
+
}
|
|
445588
|
+
}
|
|
445589
|
+
return result2;
|
|
445590
|
+
}
|
|
445591
|
+
onInterAgentMessage(listener) {
|
|
445592
|
+
this.interAgentListeners.add(listener);
|
|
445593
|
+
return () => {
|
|
445594
|
+
this.interAgentListeners.delete(listener);
|
|
445595
|
+
};
|
|
445596
|
+
}
|
|
445597
|
+
notifyInterAgentListeners(fromAgent, targetInstanceId, message) {
|
|
445598
|
+
const targetAgent = this.agents.get(targetInstanceId);
|
|
445599
|
+
if (!targetAgent)
|
|
445600
|
+
return;
|
|
445601
|
+
for (const listener of this.interAgentListeners) {
|
|
445602
|
+
try {
|
|
445603
|
+
listener({
|
|
445604
|
+
from: fromAgent,
|
|
445605
|
+
to: targetAgent,
|
|
445606
|
+
message
|
|
445607
|
+
});
|
|
445608
|
+
} catch {
|
|
445609
|
+
}
|
|
445610
|
+
}
|
|
445611
|
+
}
|
|
445612
|
+
// ── Spawned agent result storage ──────────────────────────────────────
|
|
445613
|
+
/**
|
|
445614
|
+
* Store the result of a sub-agent that was spawned by another sub-agent.
|
|
445615
|
+
* The main conversation flow drains these between tool execution rounds.
|
|
445616
|
+
*/
|
|
445617
|
+
storeSpawnedResult(result2) {
|
|
445618
|
+
this.spawnedResults.push(result2);
|
|
445619
|
+
this.notifyListeners();
|
|
445620
|
+
}
|
|
445621
|
+
/**
|
|
445622
|
+
* Drain all completed spawned agent results.
|
|
445623
|
+
* Called by the main conversation flow to inject results as context.
|
|
445624
|
+
* Returns an empty array if no results are pending.
|
|
445625
|
+
*/
|
|
445626
|
+
drainSpawnedResults() {
|
|
445627
|
+
if (this.spawnedResults.length === 0) {
|
|
445628
|
+
return [];
|
|
445629
|
+
}
|
|
445630
|
+
const results = [...this.spawnedResults];
|
|
445631
|
+
this.spawnedResults.length = 0;
|
|
445632
|
+
return results;
|
|
445633
|
+
}
|
|
445634
|
+
/**
|
|
445635
|
+
* Check if there are any pending spawned agent results.
|
|
445636
|
+
*/
|
|
445637
|
+
hasSpawnedResults() {
|
|
445638
|
+
return this.spawnedResults.length > 0;
|
|
445639
|
+
}
|
|
444909
445640
|
/**
|
|
444910
445641
|
* Subscribe to changes in the running agents list.
|
|
444911
445642
|
* Returns an unsubscribe function.
|
|
@@ -444920,9 +445651,11 @@ var init_runningSubAgentTracker = __esm({
|
|
|
444920
445651
|
* Clear all running agents (useful for cleanup)
|
|
444921
445652
|
*/
|
|
444922
445653
|
clear() {
|
|
444923
|
-
if (this.agents.size > 0) {
|
|
445654
|
+
if (this.agents.size > 0 || this.spawnedResults.length > 0) {
|
|
444924
445655
|
this.agents.clear();
|
|
444925
445656
|
this.messageQueues.clear();
|
|
445657
|
+
this.interAgentQueues.clear();
|
|
445658
|
+
this.spawnedResults.length = 0;
|
|
444926
445659
|
this.rebuildSnapshot();
|
|
444927
445660
|
this.notifyListeners();
|
|
444928
445661
|
}
|
|
@@ -444944,7 +445677,8 @@ var init_runningSubAgentTracker = __esm({
|
|
|
444944
445677
|
});
|
|
444945
445678
|
|
|
444946
445679
|
// dist/utils/execution/subAgentExecutor.js
|
|
444947
|
-
async function executeSubAgent(agentId, prompt, onMessage, abortSignal, requestToolConfirmation, isToolAutoApproved, yoloMode, addToAlwaysApproved, requestUserQuestion, instanceId) {
|
|
445680
|
+
async function executeSubAgent(agentId, prompt, onMessage, abortSignal, requestToolConfirmation, isToolAutoApproved, yoloMode, addToAlwaysApproved, requestUserQuestion, instanceId, spawnDepth = 0) {
|
|
445681
|
+
var _a21, _b14, _c6;
|
|
444948
445682
|
try {
|
|
444949
445683
|
let agent;
|
|
444950
445684
|
if (agentId === "agent_explore" || agentId === "agent_plan" || agentId === "agent_general" || agentId === "agent_analyze" || agentId === "agent_debug") {
|
|
@@ -445853,12 +446587,117 @@ Inserted log points:
|
|
|
445853
446587
|
error: `Sub-agent "${agent.name}" has no valid tools configured`
|
|
445854
446588
|
};
|
|
445855
446589
|
}
|
|
446590
|
+
const { runningSubAgentTracker: runningSubAgentTracker2 } = await Promise.resolve().then(() => (init_runningSubAgentTracker(), runningSubAgentTracker_exports));
|
|
446591
|
+
const sendMessageTool = {
|
|
446592
|
+
type: "function",
|
|
446593
|
+
function: {
|
|
446594
|
+
name: "send_message_to_agent",
|
|
446595
|
+
description: "Send a message to another running sub-agent. Use this to share information, findings, or coordinate work with other agents that are executing in parallel. The message will be injected into the target agent's context. IMPORTANT: Use query_agents_status first to check if the target agent is still running before sending.",
|
|
446596
|
+
parameters: {
|
|
446597
|
+
type: "object",
|
|
446598
|
+
properties: {
|
|
446599
|
+
target_agent_id: {
|
|
446600
|
+
type: "string",
|
|
446601
|
+
description: 'The agent ID (type) of the target sub-agent (e.g., "agent_explore", "agent_general"). If multiple instances of the same type are running, the message is sent to the first found instance.'
|
|
446602
|
+
},
|
|
446603
|
+
target_instance_id: {
|
|
446604
|
+
type: "string",
|
|
446605
|
+
description: "(Optional) The specific instance ID of the target sub-agent. Use this for precise targeting when multiple instances of the same agent type are running."
|
|
446606
|
+
},
|
|
446607
|
+
message: {
|
|
446608
|
+
type: "string",
|
|
446609
|
+
description: "The message content to send to the target agent. Be clear and specific about what information you are sharing or what action you are requesting."
|
|
446610
|
+
}
|
|
446611
|
+
},
|
|
446612
|
+
required: ["message"]
|
|
446613
|
+
}
|
|
446614
|
+
}
|
|
446615
|
+
};
|
|
446616
|
+
const queryAgentsStatusTool = {
|
|
446617
|
+
type: "function",
|
|
446618
|
+
function: {
|
|
446619
|
+
name: "query_agents_status",
|
|
446620
|
+
description: "Query the current status of all running sub-agents. Returns a list of currently active agents with their IDs, names, prompts, and how long they have been running. Use this to check if a target agent is still running before sending it a message, or to discover new agents that have started.",
|
|
446621
|
+
parameters: {
|
|
446622
|
+
type: "object",
|
|
446623
|
+
properties: {},
|
|
446624
|
+
required: []
|
|
446625
|
+
}
|
|
446626
|
+
}
|
|
446627
|
+
};
|
|
446628
|
+
const spawnSubAgentTool = {
|
|
446629
|
+
type: "function",
|
|
446630
|
+
function: {
|
|
446631
|
+
name: "spawn_sub_agent",
|
|
446632
|
+
description: `Spawn a NEW sub-agent of a DIFFERENT type to get specialized help. The spawned agent runs in parallel and results are reported back automatically.
|
|
446633
|
+
|
|
446634
|
+
**WHEN TO USE** \u2014 Only spawn when you genuinely need a different agent's specialization:
|
|
446635
|
+
- You are an Explore Agent and need code modifications \u2192 spawn agent_general
|
|
446636
|
+
- You are a General Purpose Agent and need deep code analysis \u2192 spawn agent_explore
|
|
446637
|
+
- You need a detailed implementation plan \u2192 spawn agent_plan
|
|
446638
|
+
- You need requirement clarification with user \u2192 spawn agent_analyze
|
|
446639
|
+
|
|
446640
|
+
**WHEN NOT TO USE** \u2014 Do NOT spawn to offload YOUR OWN work:
|
|
446641
|
+
- NEVER spawn an agent of the same type as yourself to delegate your task \u2014 that is lazy and wasteful
|
|
446642
|
+
- NEVER spawn an agent just to "break work into pieces" if you can do it yourself
|
|
446643
|
+
- NEVER spawn when you are simply stuck \u2014 try harder or ask the user instead
|
|
446644
|
+
- If you can complete the task with your own tools, DO IT YOURSELF
|
|
446645
|
+
|
|
446646
|
+
Available agent types: agent_explore (code exploration, read-only), agent_plan (planning, read-only), agent_general (full access, code modification), agent_analyze (requirement analysis), agent_debug (debug logging).`,
|
|
446647
|
+
parameters: {
|
|
446648
|
+
type: "object",
|
|
446649
|
+
properties: {
|
|
446650
|
+
agent_id: {
|
|
446651
|
+
type: "string",
|
|
446652
|
+
description: 'The agent type to spawn. Must be a DIFFERENT type from yourself unless you have a very strong justification. (e.g., "agent_explore", "agent_plan", "agent_general", "agent_analyze", "agent_debug", or a user-defined agent ID).'
|
|
446653
|
+
},
|
|
446654
|
+
prompt: {
|
|
446655
|
+
type: "string",
|
|
446656
|
+
description: "CRITICAL: The task prompt for the spawned agent. Must include COMPLETE context since the spawned agent has NO access to your conversation history. Include all relevant file paths, findings, constraints, and requirements."
|
|
446657
|
+
}
|
|
446658
|
+
},
|
|
446659
|
+
required: ["agent_id", "prompt"]
|
|
446660
|
+
}
|
|
446661
|
+
}
|
|
446662
|
+
};
|
|
446663
|
+
allowedTools.push(sendMessageTool, queryAgentsStatusTool);
|
|
446664
|
+
if (spawnDepth < MAX_SPAWN_DEPTH) {
|
|
446665
|
+
allowedTools.push(spawnSubAgentTool);
|
|
446666
|
+
}
|
|
446667
|
+
const otherAgents = runningSubAgentTracker2.getRunningAgents().filter((a) => a.instanceId !== instanceId);
|
|
446668
|
+
const canSpawn = spawnDepth < MAX_SPAWN_DEPTH;
|
|
446669
|
+
let otherAgentsContext = "";
|
|
446670
|
+
if (otherAgents.length > 0) {
|
|
446671
|
+
const agentList = otherAgents.map((a) => `- ${a.agentName} (id: ${a.agentId}, instance: ${a.instanceId}): "${a.prompt ? a.prompt.substring(0, 120) : "N/A"}"`).join("\n");
|
|
446672
|
+
const spawnHint = canSpawn ? ", or `spawn_sub_agent` to request a DIFFERENT type of agent for specialized help" : "";
|
|
446673
|
+
const spawnAdvice = canSpawn ? "\n\n**Spawn rules**: Only spawn agents of a DIFFERENT type for work you CANNOT do with your own tools. Complete your own task first \u2014 do NOT delegate it." : "";
|
|
446674
|
+
otherAgentsContext = `
|
|
446675
|
+
|
|
446676
|
+
## Currently Running Peer Agents
|
|
446677
|
+
The following sub-agents are running in parallel with you. You can use \`query_agents_status\` to get real-time status, \`send_message_to_agent\` to communicate${spawnHint}.
|
|
446678
|
+
|
|
446679
|
+
${agentList}
|
|
446680
|
+
|
|
446681
|
+
If you discover information useful to another agent, proactively share it.${spawnAdvice}`;
|
|
446682
|
+
} else {
|
|
446683
|
+
const spawnToolLine = canSpawn ? "\n- `spawn_sub_agent`: Spawn a DIFFERENT type of agent for specialized help (do NOT spawn your own type to offload work)" : "";
|
|
446684
|
+
const spawnUsage = canSpawn ? '\n\n**Spawn rules**: Only use `spawn_sub_agent` when you genuinely need a different agent\'s specialization (e.g., you are read-only but need code changes). NEVER spawn to delegate your own task or to "parallelize" work you should do yourself.' : "";
|
|
446685
|
+
otherAgentsContext = `
|
|
446686
|
+
|
|
446687
|
+
## Agent Collaboration Tools
|
|
446688
|
+
You have access to these collaboration tools:
|
|
446689
|
+
- \`query_agents_status\`: Check which sub-agents are currently running
|
|
446690
|
+
- \`send_message_to_agent\`: Send a message to a running peer agent (check status first!)${spawnToolLine}${spawnUsage}`;
|
|
446691
|
+
}
|
|
445856
446692
|
let finalPrompt = prompt;
|
|
445857
446693
|
if (agent.role) {
|
|
445858
446694
|
finalPrompt = `${prompt}
|
|
445859
446695
|
|
|
445860
446696
|
${agent.role}`;
|
|
445861
446697
|
}
|
|
446698
|
+
if (otherAgentsContext) {
|
|
446699
|
+
finalPrompt = `${finalPrompt}${otherAgentsContext}`;
|
|
446700
|
+
}
|
|
445862
446701
|
const messages = [
|
|
445863
446702
|
{
|
|
445864
446703
|
role: "user",
|
|
@@ -445869,7 +446708,9 @@ ${agent.role}`;
|
|
|
445869
446708
|
let hasError = false;
|
|
445870
446709
|
let errorMessage = "";
|
|
445871
446710
|
let totalUsage;
|
|
446711
|
+
let latestTotalTokens = 0;
|
|
445872
446712
|
const collectedInjectedMessages = [];
|
|
446713
|
+
const spawnedChildInstanceIds = /* @__PURE__ */ new Set();
|
|
445873
446714
|
const sessionApprovedTools = /* @__PURE__ */ new Set();
|
|
445874
446715
|
while (true) {
|
|
445875
446716
|
if (abortSignal == null ? void 0 : abortSignal.aborted) {
|
|
@@ -445890,7 +446731,6 @@ ${agent.role}`;
|
|
|
445890
446731
|
};
|
|
445891
446732
|
}
|
|
445892
446733
|
if (instanceId) {
|
|
445893
|
-
const { runningSubAgentTracker: runningSubAgentTracker2 } = await Promise.resolve().then(() => (init_runningSubAgentTracker(), runningSubAgentTracker_exports));
|
|
445894
446734
|
const injectedMessages = runningSubAgentTracker2.dequeueMessages(instanceId);
|
|
445895
446735
|
for (const injectedMsg of injectedMessages) {
|
|
445896
446736
|
collectedInjectedMessages.push(injectedMsg);
|
|
@@ -445911,6 +446751,27 @@ ${injectedMsg}`
|
|
|
445911
446751
|
});
|
|
445912
446752
|
}
|
|
445913
446753
|
}
|
|
446754
|
+
const interAgentMessages = runningSubAgentTracker2.dequeueInterAgentMessages(instanceId);
|
|
446755
|
+
for (const iaMsg of interAgentMessages) {
|
|
446756
|
+
messages.push({
|
|
446757
|
+
role: "user",
|
|
446758
|
+
content: `[Inter-agent message from ${iaMsg.fromAgentName} (${iaMsg.fromAgentId})]
|
|
446759
|
+
${iaMsg.content}`
|
|
446760
|
+
});
|
|
446761
|
+
if (onMessage) {
|
|
446762
|
+
onMessage({
|
|
446763
|
+
type: "sub_agent_message",
|
|
446764
|
+
agentId: agent.id,
|
|
446765
|
+
agentName: agent.name,
|
|
446766
|
+
message: {
|
|
446767
|
+
type: "inter_agent_received",
|
|
446768
|
+
fromAgentId: iaMsg.fromAgentId,
|
|
446769
|
+
fromAgentName: iaMsg.fromAgentName,
|
|
446770
|
+
content: iaMsg.content
|
|
446771
|
+
}
|
|
446772
|
+
});
|
|
446773
|
+
}
|
|
446774
|
+
}
|
|
445914
446775
|
}
|
|
445915
446776
|
const currentSession = sessionManager.getCurrentSession();
|
|
445916
446777
|
let config3;
|
|
@@ -445981,6 +446842,7 @@ ${injectedMsg}`
|
|
|
445981
446842
|
}
|
|
445982
446843
|
if (event.type === "usage" && event.usage) {
|
|
445983
446844
|
const eventUsage = event.usage;
|
|
446845
|
+
latestTotalTokens = eventUsage.total_tokens || (eventUsage.prompt_tokens || 0) + (eventUsage.completion_tokens || 0);
|
|
445984
446846
|
if (!totalUsage) {
|
|
445985
446847
|
totalUsage = {
|
|
445986
446848
|
inputTokens: eventUsage.prompt_tokens || 0,
|
|
@@ -445998,6 +446860,20 @@ ${injectedMsg}`
|
|
|
445998
446860
|
totalUsage.cacheReadInputTokens = (totalUsage.cacheReadInputTokens || 0) + eventUsage.cache_read_input_tokens;
|
|
445999
446861
|
}
|
|
446000
446862
|
}
|
|
446863
|
+
if (onMessage && config3.maxContextTokens && latestTotalTokens > 0) {
|
|
446864
|
+
const ctxPct = getContextPercentage(latestTotalTokens, config3.maxContextTokens);
|
|
446865
|
+
onMessage({
|
|
446866
|
+
type: "sub_agent_message",
|
|
446867
|
+
agentId: agent.id,
|
|
446868
|
+
agentName: agent.name,
|
|
446869
|
+
message: {
|
|
446870
|
+
type: "context_usage",
|
|
446871
|
+
percentage: Math.max(1, Math.round(ctxPct)),
|
|
446872
|
+
inputTokens: latestTotalTokens,
|
|
446873
|
+
maxTokens: config3.maxContextTokens
|
|
446874
|
+
}
|
|
446875
|
+
});
|
|
446876
|
+
}
|
|
446001
446877
|
}
|
|
446002
446878
|
if (event.type === "content" && event.content) {
|
|
446003
446879
|
currentContent += event.content;
|
|
@@ -446041,7 +446917,129 @@ ${injectedMsg}`
|
|
|
446041
446917
|
messages.push(assistantMessage);
|
|
446042
446918
|
finalResponse = currentContent;
|
|
446043
446919
|
}
|
|
446920
|
+
if (latestTotalTokens === 0 && config3.maxContextTokens) {
|
|
446921
|
+
latestTotalTokens = countMessagesTokens(messages);
|
|
446922
|
+
if (onMessage && latestTotalTokens > 0) {
|
|
446923
|
+
const ctxPct = getContextPercentage(latestTotalTokens, config3.maxContextTokens);
|
|
446924
|
+
onMessage({
|
|
446925
|
+
type: "sub_agent_message",
|
|
446926
|
+
agentId: agent.id,
|
|
446927
|
+
agentName: agent.name,
|
|
446928
|
+
message: {
|
|
446929
|
+
type: "context_usage",
|
|
446930
|
+
percentage: Math.max(1, Math.round(ctxPct)),
|
|
446931
|
+
inputTokens: latestTotalTokens,
|
|
446932
|
+
maxTokens: config3.maxContextTokens
|
|
446933
|
+
}
|
|
446934
|
+
});
|
|
446935
|
+
}
|
|
446936
|
+
}
|
|
446937
|
+
let justCompressed = false;
|
|
446938
|
+
if (latestTotalTokens > 0 && config3.maxContextTokens) {
|
|
446939
|
+
if (shouldCompressSubAgentContext(latestTotalTokens, config3.maxContextTokens)) {
|
|
446940
|
+
const ctxPercentage = getContextPercentage(latestTotalTokens, config3.maxContextTokens);
|
|
446941
|
+
if (onMessage) {
|
|
446942
|
+
onMessage({
|
|
446943
|
+
type: "sub_agent_message",
|
|
446944
|
+
agentId: agent.id,
|
|
446945
|
+
agentName: agent.name,
|
|
446946
|
+
message: {
|
|
446947
|
+
type: "context_compressing",
|
|
446948
|
+
percentage: Math.round(ctxPercentage)
|
|
446949
|
+
}
|
|
446950
|
+
});
|
|
446951
|
+
}
|
|
446952
|
+
try {
|
|
446953
|
+
const compressionResult = await compressSubAgentContext(messages, latestTotalTokens, config3.maxContextTokens, {
|
|
446954
|
+
model,
|
|
446955
|
+
requestMethod: config3.requestMethod,
|
|
446956
|
+
maxTokens: config3.maxTokens,
|
|
446957
|
+
configProfile: agent.configProfile
|
|
446958
|
+
});
|
|
446959
|
+
if (compressionResult.compressed) {
|
|
446960
|
+
messages.length = 0;
|
|
446961
|
+
messages.push(...compressionResult.messages);
|
|
446962
|
+
justCompressed = true;
|
|
446963
|
+
if (compressionResult.afterTokensEstimate) {
|
|
446964
|
+
latestTotalTokens = compressionResult.afterTokensEstimate;
|
|
446965
|
+
}
|
|
446966
|
+
if (onMessage) {
|
|
446967
|
+
onMessage({
|
|
446968
|
+
type: "sub_agent_message",
|
|
446969
|
+
agentId: agent.id,
|
|
446970
|
+
agentName: agent.name,
|
|
446971
|
+
message: {
|
|
446972
|
+
type: "context_compressed",
|
|
446973
|
+
beforeTokens: compressionResult.beforeTokens,
|
|
446974
|
+
afterTokensEstimate: compressionResult.afterTokensEstimate
|
|
446975
|
+
}
|
|
446976
|
+
});
|
|
446977
|
+
}
|
|
446978
|
+
console.log(`[SubAgent:${agent.name}] Context compressed: ${compressionResult.beforeTokens} \u2192 ~${compressionResult.afterTokensEstimate} tokens`);
|
|
446979
|
+
}
|
|
446980
|
+
} catch (compressError) {
|
|
446981
|
+
console.error(`[SubAgent:${agent.name}] Context compression failed:`, compressError);
|
|
446982
|
+
}
|
|
446983
|
+
}
|
|
446984
|
+
}
|
|
446985
|
+
if (justCompressed && toolCalls.length === 0) {
|
|
446986
|
+
while (messages.length > 0 && ((_a21 = messages[messages.length - 1]) == null ? void 0 : _a21.role) === "assistant") {
|
|
446987
|
+
messages.pop();
|
|
446988
|
+
}
|
|
446989
|
+
messages.push({
|
|
446990
|
+
role: "user",
|
|
446991
|
+
content: "[System] Your context has been auto-compressed to free up space. Your task is NOT finished. Continue working based on the compressed context above. Pick up where you left off."
|
|
446992
|
+
});
|
|
446993
|
+
continue;
|
|
446994
|
+
}
|
|
446044
446995
|
if (toolCalls.length === 0) {
|
|
446996
|
+
const runningChildren = Array.from(spawnedChildInstanceIds).filter((id) => runningSubAgentTracker2.isRunning(id));
|
|
446997
|
+
if (runningChildren.length > 0 || runningSubAgentTracker2.hasSpawnedResults()) {
|
|
446998
|
+
if (runningChildren.length > 0) {
|
|
446999
|
+
await runningSubAgentTracker2.waitForSpawnedAgents(
|
|
447000
|
+
3e5,
|
|
447001
|
+
// 5 min timeout
|
|
447002
|
+
abortSignal
|
|
447003
|
+
);
|
|
447004
|
+
}
|
|
447005
|
+
const spawnedResults = runningSubAgentTracker2.drainSpawnedResults();
|
|
447006
|
+
if (spawnedResults.length > 0) {
|
|
447007
|
+
for (const sr of spawnedResults) {
|
|
447008
|
+
const statusIcon = sr.success ? "\u2713" : "\u2717";
|
|
447009
|
+
const resultSummary = sr.success ? sr.result.length > 800 ? sr.result.substring(0, 800) + "..." : sr.result : sr.error || "Unknown error";
|
|
447010
|
+
messages.push({
|
|
447011
|
+
role: "user",
|
|
447012
|
+
content: `[Spawned Sub-Agent Result] ${statusIcon} ${sr.agentName} (${sr.agentId})
|
|
447013
|
+
Prompt: ${sr.prompt}
|
|
447014
|
+
Result: ${resultSummary}`
|
|
447015
|
+
});
|
|
447016
|
+
if (onMessage) {
|
|
447017
|
+
onMessage({
|
|
447018
|
+
type: "sub_agent_message",
|
|
447019
|
+
agentId: agent.id,
|
|
447020
|
+
agentName: agent.name,
|
|
447021
|
+
message: {
|
|
447022
|
+
type: "spawned_agent_completed",
|
|
447023
|
+
spawnedAgentId: sr.agentId,
|
|
447024
|
+
spawnedAgentName: sr.agentName,
|
|
447025
|
+
success: sr.success
|
|
447026
|
+
}
|
|
447027
|
+
});
|
|
447028
|
+
}
|
|
447029
|
+
}
|
|
447030
|
+
if (onMessage) {
|
|
447031
|
+
onMessage({
|
|
447032
|
+
type: "sub_agent_message",
|
|
447033
|
+
agentId: agent.id,
|
|
447034
|
+
agentName: agent.name,
|
|
447035
|
+
message: {
|
|
447036
|
+
type: "done"
|
|
447037
|
+
}
|
|
447038
|
+
});
|
|
447039
|
+
}
|
|
447040
|
+
continue;
|
|
447041
|
+
}
|
|
447042
|
+
}
|
|
446045
447043
|
try {
|
|
446046
447044
|
const hookResult = await unifiedHooksExecutor.executeHooks("onSubAgentComplete", {
|
|
446047
447045
|
agentId: agent.id,
|
|
@@ -446095,6 +447093,238 @@ ${injectedMsg}`
|
|
|
446095
447093
|
}
|
|
446096
447094
|
break;
|
|
446097
447095
|
}
|
|
447096
|
+
const sendMsgTools = toolCalls.filter((tc) => tc.function.name === "send_message_to_agent");
|
|
447097
|
+
if (sendMsgTools.length > 0 && instanceId) {
|
|
447098
|
+
for (const sendMsgTool of sendMsgTools) {
|
|
447099
|
+
let targetAgentId;
|
|
447100
|
+
let targetInstanceId;
|
|
447101
|
+
let msgContent = "";
|
|
447102
|
+
try {
|
|
447103
|
+
const args2 = JSON.parse(sendMsgTool.function.arguments);
|
|
447104
|
+
targetAgentId = args2.target_agent_id;
|
|
447105
|
+
targetInstanceId = args2.target_instance_id;
|
|
447106
|
+
msgContent = args2.message || "";
|
|
447107
|
+
} catch (error) {
|
|
447108
|
+
console.error("Failed to parse send_message_to_agent arguments:", error);
|
|
447109
|
+
}
|
|
447110
|
+
let success = false;
|
|
447111
|
+
let resultText = "";
|
|
447112
|
+
if (!msgContent) {
|
|
447113
|
+
resultText = "Error: message content is empty";
|
|
447114
|
+
} else if (targetInstanceId) {
|
|
447115
|
+
success = runningSubAgentTracker2.sendInterAgentMessage(instanceId, targetInstanceId, msgContent);
|
|
447116
|
+
if (success) {
|
|
447117
|
+
const targetAgent = runningSubAgentTracker2.getRunningAgents().find((a) => a.instanceId === targetInstanceId);
|
|
447118
|
+
resultText = `Message sent to ${(targetAgent == null ? void 0 : targetAgent.agentName) || targetInstanceId}`;
|
|
447119
|
+
} else {
|
|
447120
|
+
resultText = `Error: Target agent instance "${targetInstanceId}" is not running`;
|
|
447121
|
+
}
|
|
447122
|
+
} else if (targetAgentId) {
|
|
447123
|
+
const targetAgent = runningSubAgentTracker2.findInstanceByAgentId(targetAgentId);
|
|
447124
|
+
if (targetAgent && targetAgent.instanceId !== instanceId) {
|
|
447125
|
+
success = runningSubAgentTracker2.sendInterAgentMessage(instanceId, targetAgent.instanceId, msgContent);
|
|
447126
|
+
if (success) {
|
|
447127
|
+
resultText = `Message sent to ${targetAgent.agentName} (instance: ${targetAgent.instanceId})`;
|
|
447128
|
+
} else {
|
|
447129
|
+
resultText = `Error: Failed to send message to ${targetAgentId}`;
|
|
447130
|
+
}
|
|
447131
|
+
} else if (targetAgent && targetAgent.instanceId === instanceId) {
|
|
447132
|
+
resultText = "Error: Cannot send a message to yourself";
|
|
447133
|
+
} else {
|
|
447134
|
+
resultText = `Error: No running agent found with ID "${targetAgentId}"`;
|
|
447135
|
+
}
|
|
447136
|
+
} else {
|
|
447137
|
+
resultText = "Error: Either target_agent_id or target_instance_id must be provided";
|
|
447138
|
+
}
|
|
447139
|
+
const toolResultMessage = {
|
|
447140
|
+
role: "tool",
|
|
447141
|
+
tool_call_id: sendMsgTool.id,
|
|
447142
|
+
content: JSON.stringify({ success, result: resultText })
|
|
447143
|
+
};
|
|
447144
|
+
messages.push(toolResultMessage);
|
|
447145
|
+
if (onMessage) {
|
|
447146
|
+
onMessage({
|
|
447147
|
+
type: "sub_agent_message",
|
|
447148
|
+
agentId: agent.id,
|
|
447149
|
+
agentName: agent.name,
|
|
447150
|
+
message: {
|
|
447151
|
+
type: "inter_agent_sent",
|
|
447152
|
+
targetAgentId: targetAgentId || targetInstanceId || "unknown",
|
|
447153
|
+
targetAgentName: (targetInstanceId ? (_b14 = runningSubAgentTracker2.getRunningAgents().find((a) => a.instanceId === targetInstanceId)) == null ? void 0 : _b14.agentName : targetAgentId ? (_c6 = runningSubAgentTracker2.findInstanceByAgentId(targetAgentId)) == null ? void 0 : _c6.agentName : void 0) || targetAgentId || "unknown",
|
|
447154
|
+
content: msgContent,
|
|
447155
|
+
success
|
|
447156
|
+
}
|
|
447157
|
+
});
|
|
447158
|
+
}
|
|
447159
|
+
}
|
|
447160
|
+
toolCalls = toolCalls.filter((tc) => tc.function.name !== "send_message_to_agent");
|
|
447161
|
+
if (toolCalls.length === 0) {
|
|
447162
|
+
continue;
|
|
447163
|
+
}
|
|
447164
|
+
}
|
|
447165
|
+
const queryStatusTools = toolCalls.filter((tc) => tc.function.name === "query_agents_status");
|
|
447166
|
+
if (queryStatusTools.length > 0) {
|
|
447167
|
+
for (const queryTool of queryStatusTools) {
|
|
447168
|
+
const allAgents = runningSubAgentTracker2.getRunningAgents();
|
|
447169
|
+
const statusList = allAgents.map((a) => ({
|
|
447170
|
+
instanceId: a.instanceId,
|
|
447171
|
+
agentId: a.agentId,
|
|
447172
|
+
agentName: a.agentName,
|
|
447173
|
+
prompt: a.prompt ? a.prompt.substring(0, 150) : "N/A",
|
|
447174
|
+
runningFor: `${Math.floor((Date.now() - a.startedAt.getTime()) / 1e3)}s`,
|
|
447175
|
+
isSelf: a.instanceId === instanceId
|
|
447176
|
+
}));
|
|
447177
|
+
const toolResultMessage = {
|
|
447178
|
+
role: "tool",
|
|
447179
|
+
tool_call_id: queryTool.id,
|
|
447180
|
+
content: JSON.stringify({
|
|
447181
|
+
totalRunning: allAgents.length,
|
|
447182
|
+
agents: statusList
|
|
447183
|
+
})
|
|
447184
|
+
};
|
|
447185
|
+
messages.push(toolResultMessage);
|
|
447186
|
+
}
|
|
447187
|
+
toolCalls = toolCalls.filter((tc) => tc.function.name !== "query_agents_status");
|
|
447188
|
+
if (toolCalls.length === 0) {
|
|
447189
|
+
continue;
|
|
447190
|
+
}
|
|
447191
|
+
}
|
|
447192
|
+
const spawnTools = toolCalls.filter((tc) => tc.function.name === "spawn_sub_agent");
|
|
447193
|
+
if (spawnTools.length > 0 && instanceId) {
|
|
447194
|
+
for (const spawnTool of spawnTools) {
|
|
447195
|
+
let spawnAgentId = "";
|
|
447196
|
+
let spawnPrompt = "";
|
|
447197
|
+
try {
|
|
447198
|
+
const args2 = JSON.parse(spawnTool.function.arguments);
|
|
447199
|
+
spawnAgentId = args2.agent_id || "";
|
|
447200
|
+
spawnPrompt = args2.prompt || "";
|
|
447201
|
+
} catch (error) {
|
|
447202
|
+
console.error("Failed to parse spawn_sub_agent arguments:", error);
|
|
447203
|
+
}
|
|
447204
|
+
if (!spawnAgentId || !spawnPrompt) {
|
|
447205
|
+
const toolResultMessage2 = {
|
|
447206
|
+
role: "tool",
|
|
447207
|
+
tool_call_id: spawnTool.id,
|
|
447208
|
+
content: JSON.stringify({
|
|
447209
|
+
success: false,
|
|
447210
|
+
error: "Both agent_id and prompt are required"
|
|
447211
|
+
})
|
|
447212
|
+
};
|
|
447213
|
+
messages.push(toolResultMessage2);
|
|
447214
|
+
continue;
|
|
447215
|
+
}
|
|
447216
|
+
if (spawnAgentId === agent.id) {
|
|
447217
|
+
const toolResultMessage2 = {
|
|
447218
|
+
role: "tool",
|
|
447219
|
+
tool_call_id: spawnTool.id,
|
|
447220
|
+
content: JSON.stringify({
|
|
447221
|
+
success: false,
|
|
447222
|
+
error: `REJECTED: You (${agent.name}) attempted to spawn another "${spawnAgentId}" which is the SAME type as yourself. This is not allowed because it wastes resources and delegates work you should complete yourself. If you need help from a DIFFERENT specialization, spawn a different agent type. If the task is within your capabilities, do it yourself.`
|
|
447223
|
+
})
|
|
447224
|
+
};
|
|
447225
|
+
messages.push(toolResultMessage2);
|
|
447226
|
+
continue;
|
|
447227
|
+
}
|
|
447228
|
+
let spawnAgentName = spawnAgentId;
|
|
447229
|
+
try {
|
|
447230
|
+
const agentConfig = getSubAgent(spawnAgentId);
|
|
447231
|
+
if (agentConfig) {
|
|
447232
|
+
spawnAgentName = agentConfig.name;
|
|
447233
|
+
}
|
|
447234
|
+
} catch {
|
|
447235
|
+
const builtinNames = {
|
|
447236
|
+
agent_explore: "Explore Agent",
|
|
447237
|
+
agent_plan: "Plan Agent",
|
|
447238
|
+
agent_general: "General Purpose Agent",
|
|
447239
|
+
agent_analyze: "Requirement Analysis Agent",
|
|
447240
|
+
agent_debug: "Debug Assistant"
|
|
447241
|
+
};
|
|
447242
|
+
spawnAgentName = builtinNames[spawnAgentId] || spawnAgentId;
|
|
447243
|
+
}
|
|
447244
|
+
const spawnInstanceId = `spawn-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
447245
|
+
const spawnerInfo = {
|
|
447246
|
+
instanceId,
|
|
447247
|
+
agentId: agent.id,
|
|
447248
|
+
agentName: agent.name
|
|
447249
|
+
};
|
|
447250
|
+
spawnedChildInstanceIds.add(spawnInstanceId);
|
|
447251
|
+
runningSubAgentTracker2.register({
|
|
447252
|
+
instanceId: spawnInstanceId,
|
|
447253
|
+
agentId: spawnAgentId,
|
|
447254
|
+
agentName: spawnAgentName,
|
|
447255
|
+
prompt: spawnPrompt,
|
|
447256
|
+
startedAt: /* @__PURE__ */ new Date()
|
|
447257
|
+
});
|
|
447258
|
+
executeSubAgent(
|
|
447259
|
+
spawnAgentId,
|
|
447260
|
+
spawnPrompt,
|
|
447261
|
+
onMessage,
|
|
447262
|
+
// Same UI callback — spawned agent's messages are visible
|
|
447263
|
+
abortSignal,
|
|
447264
|
+
// Same abort signal — ESC stops everything
|
|
447265
|
+
requestToolConfirmation,
|
|
447266
|
+
isToolAutoApproved,
|
|
447267
|
+
yoloMode,
|
|
447268
|
+
addToAlwaysApproved,
|
|
447269
|
+
requestUserQuestion,
|
|
447270
|
+
spawnInstanceId,
|
|
447271
|
+
spawnDepth + 1
|
|
447272
|
+
).then((result2) => {
|
|
447273
|
+
runningSubAgentTracker2.storeSpawnedResult({
|
|
447274
|
+
instanceId: spawnInstanceId,
|
|
447275
|
+
agentId: spawnAgentId,
|
|
447276
|
+
agentName: spawnAgentName,
|
|
447277
|
+
prompt: spawnPrompt.length > 200 ? spawnPrompt.substring(0, 200) + "..." : spawnPrompt,
|
|
447278
|
+
success: result2.success,
|
|
447279
|
+
result: result2.result,
|
|
447280
|
+
error: result2.error,
|
|
447281
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
447282
|
+
spawnedBy: spawnerInfo
|
|
447283
|
+
});
|
|
447284
|
+
}).catch((error) => {
|
|
447285
|
+
runningSubAgentTracker2.storeSpawnedResult({
|
|
447286
|
+
instanceId: spawnInstanceId,
|
|
447287
|
+
agentId: spawnAgentId,
|
|
447288
|
+
agentName: spawnAgentName,
|
|
447289
|
+
prompt: spawnPrompt.length > 200 ? spawnPrompt.substring(0, 200) + "..." : spawnPrompt,
|
|
447290
|
+
success: false,
|
|
447291
|
+
result: "",
|
|
447292
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
447293
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
447294
|
+
spawnedBy: spawnerInfo
|
|
447295
|
+
});
|
|
447296
|
+
}).finally(() => {
|
|
447297
|
+
runningSubAgentTracker2.unregister(spawnInstanceId);
|
|
447298
|
+
});
|
|
447299
|
+
if (onMessage) {
|
|
447300
|
+
onMessage({
|
|
447301
|
+
type: "sub_agent_message",
|
|
447302
|
+
agentId: agent.id,
|
|
447303
|
+
agentName: agent.name,
|
|
447304
|
+
message: {
|
|
447305
|
+
type: "agent_spawned",
|
|
447306
|
+
spawnedAgentId: spawnAgentId,
|
|
447307
|
+
spawnedAgentName: spawnAgentName,
|
|
447308
|
+
spawnedInstanceId: spawnInstanceId,
|
|
447309
|
+
spawnedPrompt: spawnPrompt
|
|
447310
|
+
}
|
|
447311
|
+
});
|
|
447312
|
+
}
|
|
447313
|
+
const toolResultMessage = {
|
|
447314
|
+
role: "tool",
|
|
447315
|
+
tool_call_id: spawnTool.id,
|
|
447316
|
+
content: JSON.stringify({
|
|
447317
|
+
success: true,
|
|
447318
|
+
result: `Agent "${spawnAgentName}" (${spawnAgentId}) has been spawned and is now running in the background with instance ID "${spawnInstanceId}". Its results will be automatically reported to the main workflow when it completes.`
|
|
447319
|
+
})
|
|
447320
|
+
};
|
|
447321
|
+
messages.push(toolResultMessage);
|
|
447322
|
+
}
|
|
447323
|
+
toolCalls = toolCalls.filter((tc) => tc.function.name !== "spawn_sub_agent");
|
|
447324
|
+
if (toolCalls.length === 0) {
|
|
447325
|
+
continue;
|
|
447326
|
+
}
|
|
447327
|
+
}
|
|
446098
447328
|
const askUserTool = toolCalls.find((tc) => tc.function.name.startsWith("askuser-"));
|
|
446099
447329
|
if (askUserTool && requestUserQuestion) {
|
|
446100
447330
|
let question = "Please select an option:";
|
|
@@ -446291,6 +447521,7 @@ ${injectedMsg}`
|
|
|
446291
447521
|
};
|
|
446292
447522
|
}
|
|
446293
447523
|
}
|
|
447524
|
+
var MAX_SPAWN_DEPTH;
|
|
446294
447525
|
var init_subAgentExecutor = __esm({
|
|
446295
447526
|
"dist/utils/execution/subAgentExecutor.js"() {
|
|
446296
447527
|
"use strict";
|
|
@@ -446304,6 +447535,8 @@ var init_subAgentExecutor = __esm({
|
|
|
446304
447535
|
init_sessionManager();
|
|
446305
447536
|
init_unifiedHooksExecutor();
|
|
446306
447537
|
init_yoloPermissionChecker();
|
|
447538
|
+
init_subAgentContextCompressor();
|
|
447539
|
+
MAX_SPAWN_DEPTH = 1;
|
|
446307
447540
|
}
|
|
446308
447541
|
});
|
|
446309
447542
|
|
|
@@ -453611,6 +454844,12 @@ var init_LSPClient = __esm({
|
|
|
453611
454844
|
writable: true,
|
|
453612
454845
|
value: false
|
|
453613
454846
|
});
|
|
454847
|
+
Object.defineProperty(this, "isProcessAlive", {
|
|
454848
|
+
enumerable: true,
|
|
454849
|
+
configurable: true,
|
|
454850
|
+
writable: true,
|
|
454851
|
+
value: false
|
|
454852
|
+
});
|
|
453614
454853
|
Object.defineProperty(this, "openDocuments", {
|
|
453615
454854
|
enumerable: true,
|
|
453616
454855
|
configurable: true,
|
|
@@ -453661,6 +454900,7 @@ var init_LSPClient = __esm({
|
|
|
453661
454900
|
}
|
|
453662
454901
|
}
|
|
453663
454902
|
async start() {
|
|
454903
|
+
var _a21;
|
|
453664
454904
|
if (this.isInitialized) {
|
|
453665
454905
|
return;
|
|
453666
454906
|
}
|
|
@@ -453683,17 +454923,34 @@ var init_LSPClient = __esm({
|
|
|
453683
454923
|
stdio: ["pipe", "pipe", "pipe"],
|
|
453684
454924
|
cwd: this.config.rootPath
|
|
453685
454925
|
});
|
|
454926
|
+
this.isProcessAlive = true;
|
|
454927
|
+
this.process.on("exit", () => {
|
|
454928
|
+
this.isProcessAlive = false;
|
|
454929
|
+
});
|
|
454930
|
+
this.process.on("error", () => {
|
|
454931
|
+
this.isProcessAlive = false;
|
|
454932
|
+
});
|
|
454933
|
+
(_a21 = this.process.stdin) == null ? void 0 : _a21.on("error", () => {
|
|
454934
|
+
this.isProcessAlive = false;
|
|
454935
|
+
});
|
|
453686
454936
|
processManager.register(this.process);
|
|
453687
454937
|
this.connection = (0, import_node.createMessageConnection)(new import_node.StreamMessageReader(this.process.stdout), new import_node.StreamMessageWriter(this.process.stdin));
|
|
454938
|
+
this.connection.onError(([error]) => {
|
|
454939
|
+
console.debug("LSP connection error:", (error == null ? void 0 : error.message) || error);
|
|
454940
|
+
});
|
|
454941
|
+
this.connection.onClose(() => {
|
|
454942
|
+
this.isInitialized = false;
|
|
454943
|
+
this.isProcessAlive = false;
|
|
454944
|
+
});
|
|
453688
454945
|
this.connection.onRequest("window/workDoneProgress/create", () => null);
|
|
453689
454946
|
this.connection.onRequest("client/registerCapability", () => null);
|
|
453690
454947
|
this.connection.onRequest("workspace/configuration", () => []);
|
|
453691
454948
|
this.connection.onNotification("window/logMessage", (params) => {
|
|
453692
|
-
var
|
|
454949
|
+
var _a22;
|
|
453693
454950
|
const message = typeof (params == null ? void 0 : params.message) === "string" ? params.message : "";
|
|
453694
454951
|
if (!this.csharpSolutionLoaded && message.includes("Finished loading solution")) {
|
|
453695
454952
|
this.csharpSolutionLoaded = true;
|
|
453696
|
-
(
|
|
454953
|
+
(_a22 = this.resolveCsharpSolutionLoad) == null ? void 0 : _a22.call(this);
|
|
453697
454954
|
}
|
|
453698
454955
|
});
|
|
453699
454956
|
this.connection.onNotification("window/showMessage", (_params) => {
|
|
@@ -453765,11 +455022,23 @@ var init_LSPClient = __esm({
|
|
|
453765
455022
|
return;
|
|
453766
455023
|
}
|
|
453767
455024
|
try {
|
|
453768
|
-
|
|
453769
|
-
|
|
455025
|
+
if (this.isProcessAlive) {
|
|
455026
|
+
for (const uri of [...this.openDocuments]) {
|
|
455027
|
+
try {
|
|
455028
|
+
await this.closeDocument(uri);
|
|
455029
|
+
} catch {
|
|
455030
|
+
break;
|
|
455031
|
+
}
|
|
455032
|
+
}
|
|
455033
|
+
try {
|
|
455034
|
+
await this.connection.sendRequest("shutdown", null);
|
|
455035
|
+
} catch {
|
|
455036
|
+
}
|
|
455037
|
+
try {
|
|
455038
|
+
await this.connection.sendNotification("exit", null);
|
|
455039
|
+
} catch {
|
|
455040
|
+
}
|
|
453770
455041
|
}
|
|
453771
|
-
await this.connection.sendRequest("shutdown", null);
|
|
453772
|
-
await this.connection.sendNotification("exit", null);
|
|
453773
455042
|
} catch (error) {
|
|
453774
455043
|
console.debug("Error during LSP shutdown:", error);
|
|
453775
455044
|
} finally {
|
|
@@ -453778,14 +455047,21 @@ var init_LSPClient = __esm({
|
|
|
453778
455047
|
}
|
|
453779
455048
|
async cleanup() {
|
|
453780
455049
|
if (this.connection) {
|
|
453781
|
-
|
|
455050
|
+
try {
|
|
455051
|
+
this.connection.dispose();
|
|
455052
|
+
} catch {
|
|
455053
|
+
}
|
|
453782
455054
|
this.connection = void 0;
|
|
453783
455055
|
}
|
|
453784
455056
|
if (this.process) {
|
|
453785
|
-
|
|
455057
|
+
try {
|
|
455058
|
+
this.process.kill();
|
|
455059
|
+
} catch {
|
|
455060
|
+
}
|
|
453786
455061
|
this.process = void 0;
|
|
453787
455062
|
}
|
|
453788
455063
|
this.isInitialized = false;
|
|
455064
|
+
this.isProcessAlive = false;
|
|
453789
455065
|
this.openDocuments.clear();
|
|
453790
455066
|
this.documentVersions.clear();
|
|
453791
455067
|
}
|
|
@@ -453942,7 +455218,7 @@ var init_LSPClient = __esm({
|
|
|
453942
455218
|
return this.capabilities;
|
|
453943
455219
|
}
|
|
453944
455220
|
isReady() {
|
|
453945
|
-
return this.isInitialized;
|
|
455221
|
+
return this.isInitialized && this.isProcessAlive;
|
|
453946
455222
|
}
|
|
453947
455223
|
};
|
|
453948
455224
|
}
|
|
@@ -454190,6 +455466,11 @@ var init_LSPManager = __esm({
|
|
|
454190
455466
|
if (client.isReady()) {
|
|
454191
455467
|
return client;
|
|
454192
455468
|
}
|
|
455469
|
+
try {
|
|
455470
|
+
await client.shutdown();
|
|
455471
|
+
} catch {
|
|
455472
|
+
}
|
|
455473
|
+
this.clients.delete(language);
|
|
454193
455474
|
}
|
|
454194
455475
|
const config3 = LSPServerRegistry.getConfig(language);
|
|
454195
455476
|
if (!config3) {
|
|
@@ -454653,8 +455934,8 @@ async function validateTokenLimit(content, maxTokens) {
|
|
|
454653
455934
|
contentStr = String(contentWithoutImages);
|
|
454654
455935
|
}
|
|
454655
455936
|
try {
|
|
454656
|
-
const { encoding_for_model:
|
|
454657
|
-
const encoder =
|
|
455937
|
+
const { encoding_for_model: encoding_for_model3 } = await Promise.resolve().then(() => __toESM(require_tiktoken(), 1));
|
|
455938
|
+
const encoder = encoding_for_model3("gpt-4o");
|
|
454658
455939
|
try {
|
|
454659
455940
|
const tokens2 = encoder.encode(contentStr);
|
|
454660
455941
|
const tokenCount = tokens2.length;
|
|
@@ -454687,8 +455968,8 @@ Tip: Consider breaking down the operation into smaller chunks or filtering the d
|
|
|
454687
455968
|
}
|
|
454688
455969
|
async function truncateToTokenLimit(content, maxTokens) {
|
|
454689
455970
|
try {
|
|
454690
|
-
const { encoding_for_model:
|
|
454691
|
-
const encoder =
|
|
455971
|
+
const { encoding_for_model: encoding_for_model3 } = await Promise.resolve().then(() => __toESM(require_tiktoken(), 1));
|
|
455972
|
+
const encoder = encoding_for_model3("gpt-4o");
|
|
454692
455973
|
try {
|
|
454693
455974
|
const tokens2 = encoder.encode(content);
|
|
454694
455975
|
if (tokens2.length <= maxTokens) {
|
|
@@ -455804,19 +457085,48 @@ ${combinedOutput}`);
|
|
|
455804
457085
|
result2 = await wrapToolResultWithTokenLimit2(result2, toolName);
|
|
455805
457086
|
return result2;
|
|
455806
457087
|
}
|
|
457088
|
+
function isConnectionError(error) {
|
|
457089
|
+
if (error instanceof Error) {
|
|
457090
|
+
const msg = error.message.toLowerCase();
|
|
457091
|
+
return msg.includes("stream") || msg.includes("destroyed") || msg.includes("closed") || msg.includes("ended") || msg.includes("econnreset") || msg.includes("econnrefused") || msg.includes("epipe") || msg.includes("not connected") || msg.includes("transport") || error.code === "ERR_STREAM_DESTROYED";
|
|
457092
|
+
}
|
|
457093
|
+
return false;
|
|
457094
|
+
}
|
|
455807
457095
|
async function executeOnExternalMCPService(serviceName, server, toolName, args2) {
|
|
455808
|
-
|
|
455809
|
-
|
|
455810
|
-
|
|
455811
|
-
|
|
455812
|
-
|
|
455813
|
-
|
|
455814
|
-
|
|
455815
|
-
|
|
455816
|
-
|
|
455817
|
-
|
|
455818
|
-
|
|
455819
|
-
|
|
457096
|
+
let retried = false;
|
|
457097
|
+
const attemptCall = async () => {
|
|
457098
|
+
const client = await getPersistentClient(serviceName, server);
|
|
457099
|
+
logger.debug(`Using persistent MCP client for ${serviceName} tool ${toolName}`);
|
|
457100
|
+
const timeout2 = server.timeout ?? 3e5;
|
|
457101
|
+
const result2 = await client.callTool({
|
|
457102
|
+
name: toolName,
|
|
457103
|
+
arguments: args2
|
|
457104
|
+
}, void 0, {
|
|
457105
|
+
timeout: timeout2,
|
|
457106
|
+
resetTimeoutOnProgress: true
|
|
457107
|
+
});
|
|
457108
|
+
logger.debug(`result from ${serviceName} tool ${toolName}:`, result2);
|
|
457109
|
+
return result2.content;
|
|
457110
|
+
};
|
|
457111
|
+
try {
|
|
457112
|
+
return await attemptCall();
|
|
457113
|
+
} catch (error) {
|
|
457114
|
+
if (!retried && isConnectionError(error)) {
|
|
457115
|
+
retried = true;
|
|
457116
|
+
logger.info(`Connection error for ${serviceName}, reconnecting and retrying...`);
|
|
457117
|
+
const clientInfo = persistentClients.get(serviceName);
|
|
457118
|
+
if (clientInfo) {
|
|
457119
|
+
try {
|
|
457120
|
+
await clientInfo.client.close();
|
|
457121
|
+
} catch {
|
|
457122
|
+
}
|
|
457123
|
+
resourceMonitor.trackMCPConnectionClosed(serviceName);
|
|
457124
|
+
persistentClients.delete(serviceName);
|
|
457125
|
+
}
|
|
457126
|
+
return await attemptCall();
|
|
457127
|
+
}
|
|
457128
|
+
throw error;
|
|
457129
|
+
}
|
|
455820
457130
|
}
|
|
455821
457131
|
var toolsCache, CACHE_DURATION, todoService, persistentClients, CLIENT_IDLE_TIMEOUT;
|
|
455822
457132
|
var init_mcpToolsManager = __esm({
|
|
@@ -549841,11 +551151,29 @@ function MessageRenderer({ message, index, filteredMessages, terminalWidth, show
|
|
|
549841
551151
|
const lines = content.split("\n");
|
|
549842
551152
|
const titleLine = lines[0] || "";
|
|
549843
551153
|
const treeLines = lines.slice(1);
|
|
551154
|
+
const ctxUsage = message.subAgentContextUsage;
|
|
551155
|
+
const showCtxBar = ctxUsage && ctxUsage.percentage > 0;
|
|
549844
551156
|
return import_react79.default.createElement(
|
|
549845
551157
|
import_react79.default.Fragment,
|
|
549846
551158
|
null,
|
|
549847
551159
|
import_react79.default.createElement(Text, { color: toolStatusColor }, removeAnsiCodes2(titleLine)),
|
|
549848
|
-
treeLines.length > 0 && import_react79.default.createElement(Text, { color: theme14.colors.menuSecondary }, treeLines.map((line) => removeAnsiCodes2(line || "")).join("\n"))
|
|
551160
|
+
treeLines.length > 0 && import_react79.default.createElement(Text, { color: theme14.colors.menuSecondary }, treeLines.map((line) => removeAnsiCodes2(line || "")).join("\n")),
|
|
551161
|
+
showCtxBar && (() => {
|
|
551162
|
+
const pct = ctxUsage.percentage;
|
|
551163
|
+
const barWidth = 10;
|
|
551164
|
+
const filled = Math.round(pct / 100 * barWidth);
|
|
551165
|
+
const empty = barWidth - filled;
|
|
551166
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
|
|
551167
|
+
const barColor = pct >= 80 ? "red" : pct >= 65 ? "yellow" : pct >= 50 ? "cyan" : "gray";
|
|
551168
|
+
return import_react79.default.createElement(
|
|
551169
|
+
Text,
|
|
551170
|
+
{ color: barColor, dimColor: true },
|
|
551171
|
+
"\u2514\u2500 Context: ",
|
|
551172
|
+
pct,
|
|
551173
|
+
"% ",
|
|
551174
|
+
bar
|
|
551175
|
+
);
|
|
551176
|
+
})()
|
|
549849
551177
|
);
|
|
549850
551178
|
}
|
|
549851
551179
|
return import_react79.default.createElement(
|
|
@@ -559837,7 +561165,7 @@ var init_CustomCommandExecutionDisplay = __esm({
|
|
|
559837
561165
|
});
|
|
559838
561166
|
|
|
559839
561167
|
// dist/ui/components/tools/FileRollbackConfirmation.js
|
|
559840
|
-
function FileRollbackConfirmation({ fileCount, filePaths, previewSessionId, previewTargetMessageIndex, onConfirm }) {
|
|
561168
|
+
function FileRollbackConfirmation({ fileCount, filePaths, notebookCount, previewSessionId, previewTargetMessageIndex, onConfirm }) {
|
|
559841
561169
|
const { t } = useI18n();
|
|
559842
561170
|
const [selectedIndex, setSelectedIndex] = (0, import_react117.useState)(0);
|
|
559843
561171
|
const [showFullList, setShowFullList] = (0, import_react117.useState)(false);
|
|
@@ -560060,6 +561388,11 @@ function FileRollbackConfirmation({ fileCount, filePaths, previewSessionId, prev
|
|
|
560060
561388
|
remainingCountCompact > 1 ? "s" : ""
|
|
560061
561389
|
)
|
|
560062
561390
|
),
|
|
561391
|
+
notebookCount !== void 0 && notebookCount > 0 && import_react117.default.createElement(
|
|
561392
|
+
Box_default,
|
|
561393
|
+
{ marginBottom: 1, marginLeft: 2 },
|
|
561394
|
+
import_react117.default.createElement(Text, { color: "magenta" }, t.fileRollback.notebookCount.replace("{count}", String(notebookCount)))
|
|
561395
|
+
),
|
|
560063
561396
|
!showFullList && import_react117.default.createElement(
|
|
560064
561397
|
import_react117.default.Fragment,
|
|
560065
561398
|
null,
|
|
@@ -565227,6 +566560,9 @@ function getToolResourceType(toolName) {
|
|
|
565227
566560
|
if (toolName === "todo-update" || toolName === "todo-add" || toolName === "todo-delete") {
|
|
565228
566561
|
return "todo-state";
|
|
565229
566562
|
}
|
|
566563
|
+
if (toolName === "notebook-add" || toolName === "notebook-update" || toolName === "notebook-delete" || toolName === "notebook-list" || toolName === "notebook-query") {
|
|
566564
|
+
return "notebook-state";
|
|
566565
|
+
}
|
|
565230
566566
|
if (toolName === "terminal-execute") {
|
|
565231
566567
|
return "terminal-execution";
|
|
565232
566568
|
}
|
|
@@ -565241,6 +566577,9 @@ function getResourceIdentifier(toolCall) {
|
|
|
565241
566577
|
if (resourceType === "todo-state") {
|
|
565242
566578
|
return "todo-state";
|
|
565243
566579
|
}
|
|
566580
|
+
if (resourceType === "notebook-state") {
|
|
566581
|
+
return "notebook-state";
|
|
566582
|
+
}
|
|
565244
566583
|
if (resourceType === "terminal-execution") {
|
|
565245
566584
|
return "terminal-execution";
|
|
565246
566585
|
}
|
|
@@ -565447,7 +566786,7 @@ function cleanOrphanedToolCalls(messages) {
|
|
|
565447
566786
|
console.log(`[contextCompressor:cleanOrphanedToolCalls] Removed ${indicesToRemove.length} orphaned messages from compression input`);
|
|
565448
566787
|
}
|
|
565449
566788
|
}
|
|
565450
|
-
function
|
|
566789
|
+
function formatMessageForTranscript2(msg) {
|
|
565451
566790
|
var _a21, _b14;
|
|
565452
566791
|
if (msg.role === "tool") {
|
|
565453
566792
|
return null;
|
|
@@ -565504,7 +566843,7 @@ function prepareMessagesForCompression(conversationMessages, customSystemPrompt)
|
|
|
565504
566843
|
if (msg.role === "system") {
|
|
565505
566844
|
continue;
|
|
565506
566845
|
}
|
|
565507
|
-
const formatted =
|
|
566846
|
+
const formatted = formatMessageForTranscript2(msg);
|
|
565508
566847
|
if (formatted) {
|
|
565509
566848
|
transcriptParts.push(formatted);
|
|
565510
566849
|
}
|
|
@@ -567314,6 +568653,14 @@ var useConversation_exports = {};
|
|
|
567314
568653
|
__export(useConversation_exports, {
|
|
567315
568654
|
handleConversationWithTools: () => handleConversationWithTools
|
|
567316
568655
|
});
|
|
568656
|
+
function formatTokenCount(tokens2) {
|
|
568657
|
+
if (!tokens2)
|
|
568658
|
+
return "0";
|
|
568659
|
+
if (tokens2 >= 1e3) {
|
|
568660
|
+
return `${(tokens2 / 1e3).toFixed(1)}K`;
|
|
568661
|
+
}
|
|
568662
|
+
return String(tokens2);
|
|
568663
|
+
}
|
|
567317
568664
|
async function handleConversationWithTools(options3) {
|
|
567318
568665
|
const {
|
|
567319
568666
|
userContent,
|
|
@@ -567379,10 +568726,10 @@ async function handleConversationWithTools(options3) {
|
|
|
567379
568726
|
}
|
|
567380
568727
|
};
|
|
567381
568728
|
try {
|
|
567382
|
-
encoder = (0,
|
|
568729
|
+
encoder = (0, import_tiktoken2.encoding_for_model)("gpt-5");
|
|
567383
568730
|
resourceMonitor.trackEncoderCreated();
|
|
567384
568731
|
} catch (e) {
|
|
567385
|
-
encoder = (0,
|
|
568732
|
+
encoder = (0, import_tiktoken2.encoding_for_model)("gpt-3.5-turbo");
|
|
567386
568733
|
resourceMonitor.trackEncoderCreated();
|
|
567387
568734
|
}
|
|
567388
568735
|
setStreamTokenCount(0);
|
|
@@ -567677,18 +569024,147 @@ async function handleConversationWithTools(options3) {
|
|
|
567677
569024
|
let subAgentTokenCount = 0;
|
|
567678
569025
|
let lastSubAgentFlushTime = 0;
|
|
567679
569026
|
const SUB_AGENT_FLUSH_INTERVAL = 100;
|
|
569027
|
+
const latestSubAgentCtxUsage = {};
|
|
567680
569028
|
const toolResults = await executeToolCalls(
|
|
567681
569029
|
approvedTools,
|
|
567682
569030
|
controller.signal,
|
|
567683
569031
|
setStreamTokenCount,
|
|
567684
569032
|
async (subAgentMessage) => {
|
|
567685
569033
|
setMessages((prev) => {
|
|
569034
|
+
var _a21;
|
|
569035
|
+
if (subAgentMessage.message.type === "context_usage") {
|
|
569036
|
+
const ctxData = {
|
|
569037
|
+
percentage: subAgentMessage.message.percentage,
|
|
569038
|
+
inputTokens: subAgentMessage.message.inputTokens,
|
|
569039
|
+
maxTokens: subAgentMessage.message.maxTokens
|
|
569040
|
+
};
|
|
569041
|
+
latestSubAgentCtxUsage[subAgentMessage.agentId] = ctxData;
|
|
569042
|
+
let targetIndex = -1;
|
|
569043
|
+
for (let i = prev.length - 1; i >= 0; i--) {
|
|
569044
|
+
const m = prev[i];
|
|
569045
|
+
if (m && m.role === "subagent" && ((_a21 = m.subAgent) == null ? void 0 : _a21.agentId) === subAgentMessage.agentId) {
|
|
569046
|
+
targetIndex = i;
|
|
569047
|
+
break;
|
|
569048
|
+
}
|
|
569049
|
+
}
|
|
569050
|
+
if (targetIndex !== -1) {
|
|
569051
|
+
const updated = [...prev];
|
|
569052
|
+
const existing = updated[targetIndex];
|
|
569053
|
+
if (existing) {
|
|
569054
|
+
updated[targetIndex] = {
|
|
569055
|
+
...existing,
|
|
569056
|
+
subAgentContextUsage: ctxData
|
|
569057
|
+
};
|
|
569058
|
+
}
|
|
569059
|
+
return updated;
|
|
569060
|
+
}
|
|
569061
|
+
return prev;
|
|
569062
|
+
}
|
|
569063
|
+
if (subAgentMessage.message.type === "context_compressing") {
|
|
569064
|
+
const uiMsg = {
|
|
569065
|
+
role: "subagent",
|
|
569066
|
+
content: `\x1B[36m\u2687 ${subAgentMessage.agentName}\x1B[0m \x1B[33m\u2735 Auto-compressing context (${subAgentMessage.message.percentage}%)...\x1B[0m`,
|
|
569067
|
+
streaming: false,
|
|
569068
|
+
subAgent: {
|
|
569069
|
+
agentId: subAgentMessage.agentId,
|
|
569070
|
+
agentName: subAgentMessage.agentName,
|
|
569071
|
+
isComplete: false
|
|
569072
|
+
},
|
|
569073
|
+
subAgentInternal: true
|
|
569074
|
+
};
|
|
569075
|
+
return [...prev, uiMsg];
|
|
569076
|
+
}
|
|
569077
|
+
if (subAgentMessage.message.type === "context_compressed") {
|
|
569078
|
+
const msg = subAgentMessage.message;
|
|
569079
|
+
const uiMsg = {
|
|
569080
|
+
role: "subagent",
|
|
569081
|
+
content: `\x1B[36m\u2687 ${subAgentMessage.agentName}\x1B[0m \x1B[32m\u2735 Context compressed (~${formatTokenCount(msg.beforeTokens)} \u2192 ~${formatTokenCount(msg.afterTokensEstimate)})\x1B[0m`,
|
|
569082
|
+
streaming: false,
|
|
569083
|
+
messageStatus: "success",
|
|
569084
|
+
subAgent: {
|
|
569085
|
+
agentId: subAgentMessage.agentId,
|
|
569086
|
+
agentName: subAgentMessage.agentName,
|
|
569087
|
+
isComplete: false
|
|
569088
|
+
},
|
|
569089
|
+
subAgentInternal: true
|
|
569090
|
+
};
|
|
569091
|
+
return [...prev, uiMsg];
|
|
569092
|
+
}
|
|
569093
|
+
if (subAgentMessage.message.type === "inter_agent_sent") {
|
|
569094
|
+
const msg = subAgentMessage.message;
|
|
569095
|
+
const statusIcon = msg.success ? "\u2192" : "\u2717";
|
|
569096
|
+
const targetName = msg.targetAgentName || msg.targetAgentId;
|
|
569097
|
+
const truncatedContent = msg.content.length > 80 ? msg.content.substring(0, 80) + "..." : msg.content;
|
|
569098
|
+
const uiMsg = {
|
|
569099
|
+
role: "subagent",
|
|
569100
|
+
content: `\x1B[38;2;255;165;0m\u2687${statusIcon} [${subAgentMessage.agentName}] \u2192 [${targetName}]\x1B[0m: ${truncatedContent}`,
|
|
569101
|
+
streaming: false,
|
|
569102
|
+
messageStatus: msg.success ? "success" : "error",
|
|
569103
|
+
subAgent: {
|
|
569104
|
+
agentId: subAgentMessage.agentId,
|
|
569105
|
+
agentName: subAgentMessage.agentName,
|
|
569106
|
+
isComplete: false
|
|
569107
|
+
},
|
|
569108
|
+
subAgentInternal: true
|
|
569109
|
+
};
|
|
569110
|
+
return [...prev, uiMsg];
|
|
569111
|
+
}
|
|
569112
|
+
if (subAgentMessage.message.type === "inter_agent_received") {
|
|
569113
|
+
return prev;
|
|
569114
|
+
}
|
|
569115
|
+
if (subAgentMessage.message.type === "agent_spawned") {
|
|
569116
|
+
const msg = subAgentMessage.message;
|
|
569117
|
+
const promptText = msg.spawnedPrompt ? msg.spawnedPrompt.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim() : "";
|
|
569118
|
+
const truncatedPrompt = promptText.length > 100 ? promptText.substring(0, 100) + "..." : promptText;
|
|
569119
|
+
const promptLine = truncatedPrompt ? `
|
|
569120
|
+
\x1B[2m\u2514\u2500 prompt: "${truncatedPrompt}"\x1B[0m` : "";
|
|
569121
|
+
const uiMsg = {
|
|
569122
|
+
role: "subagent",
|
|
569123
|
+
content: `\x1B[38;2;150;120;255m\u2687\u2295 [${subAgentMessage.agentName}] spawned [${msg.spawnedAgentName}]\x1B[0m${promptLine}`,
|
|
569124
|
+
streaming: false,
|
|
569125
|
+
messageStatus: "success",
|
|
569126
|
+
subAgent: {
|
|
569127
|
+
agentId: subAgentMessage.agentId,
|
|
569128
|
+
agentName: subAgentMessage.agentName,
|
|
569129
|
+
isComplete: false
|
|
569130
|
+
},
|
|
569131
|
+
subAgentInternal: true
|
|
569132
|
+
};
|
|
569133
|
+
return [...prev, uiMsg];
|
|
569134
|
+
}
|
|
569135
|
+
if (subAgentMessage.message.type === "spawned_agent_completed") {
|
|
569136
|
+
const msg = subAgentMessage.message;
|
|
569137
|
+
const statusIcon = msg.success ? "\u2713" : "\u2717";
|
|
569138
|
+
const uiMsg = {
|
|
569139
|
+
role: "subagent",
|
|
569140
|
+
content: `\x1B[38;2;150;120;255m\u2687${statusIcon} Spawned [${msg.spawnedAgentName}] completed\x1B[0m (parent: ${subAgentMessage.agentName})`,
|
|
569141
|
+
streaming: false,
|
|
569142
|
+
messageStatus: msg.success ? "success" : "error",
|
|
569143
|
+
subAgent: {
|
|
569144
|
+
agentId: subAgentMessage.agentId,
|
|
569145
|
+
agentName: subAgentMessage.agentName,
|
|
569146
|
+
isComplete: false
|
|
569147
|
+
},
|
|
569148
|
+
subAgentInternal: true
|
|
569149
|
+
};
|
|
569150
|
+
return [...prev, uiMsg];
|
|
569151
|
+
}
|
|
567686
569152
|
if (subAgentMessage.message.type === "tool_calls") {
|
|
567687
569153
|
const toolCalls = subAgentMessage.message.tool_calls;
|
|
567688
569154
|
if (toolCalls && toolCalls.length > 0) {
|
|
567689
|
-
const
|
|
567690
|
-
|
|
569155
|
+
const internalAgentTools = /* @__PURE__ */ new Set([
|
|
569156
|
+
"send_message_to_agent",
|
|
569157
|
+
"query_agents_status",
|
|
569158
|
+
"spawn_sub_agent"
|
|
569159
|
+
]);
|
|
569160
|
+
const displayableToolCalls = toolCalls.filter((tc) => !internalAgentTools.has(tc.function.name));
|
|
569161
|
+
if (displayableToolCalls.length === 0) {
|
|
569162
|
+
return prev;
|
|
569163
|
+
}
|
|
569164
|
+
const timeConsumingTools = displayableToolCalls.filter((tc) => isToolNeedTwoStepDisplay(tc.function.name));
|
|
569165
|
+
const quickTools = displayableToolCalls.filter((tc) => !isToolNeedTwoStepDisplay(tc.function.name));
|
|
567691
569166
|
const newMessages = [];
|
|
569167
|
+
const inheritedCtxUsage = latestSubAgentCtxUsage[subAgentMessage.agentId];
|
|
567692
569168
|
for (const toolCall of timeConsumingTools) {
|
|
567693
569169
|
const toolDisplay = formatToolCallMessage(toolCall);
|
|
567694
569170
|
let toolArgs;
|
|
@@ -567720,7 +569196,8 @@ async function handleConversationWithTools(options3) {
|
|
|
567720
569196
|
agentName: subAgentMessage.agentName,
|
|
567721
569197
|
isComplete: false
|
|
567722
569198
|
},
|
|
567723
|
-
subAgentInternal: true
|
|
569199
|
+
subAgentInternal: true,
|
|
569200
|
+
subAgentContextUsage: inheritedCtxUsage
|
|
567724
569201
|
};
|
|
567725
569202
|
newMessages.push(uiMsg);
|
|
567726
569203
|
}
|
|
@@ -567744,7 +569221,8 @@ async function handleConversationWithTools(options3) {
|
|
|
567744
569221
|
},
|
|
567745
569222
|
subAgentInternal: true,
|
|
567746
569223
|
// Store pending tool call IDs for later status update
|
|
567747
|
-
pendingToolIds: quickTools.map((tc) => tc.id)
|
|
569224
|
+
pendingToolIds: quickTools.map((tc) => tc.id),
|
|
569225
|
+
subAgentContextUsage: inheritedCtxUsage
|
|
567748
569226
|
};
|
|
567749
569227
|
newMessages.push(uiMsg);
|
|
567750
569228
|
}
|
|
@@ -567863,8 +569341,8 @@ async function handleConversationWithTools(options3) {
|
|
|
567863
569341
|
return [...prev, uiMsg];
|
|
567864
569342
|
}
|
|
567865
569343
|
const pendingMsgIndex = prev.findIndex((m) => {
|
|
567866
|
-
var
|
|
567867
|
-
return m.role === "subagent" && ((
|
|
569344
|
+
var _a22, _b14, _c6;
|
|
569345
|
+
return m.role === "subagent" && ((_a22 = m.subAgent) == null ? void 0 : _a22.agentId) === subAgentMessage.agentId && !((_b14 = m.subAgent) == null ? void 0 : _b14.isComplete) && ((_c6 = m.pendingToolIds) == null ? void 0 : _c6.includes(msg.tool_call_id));
|
|
567868
569346
|
});
|
|
567869
569347
|
if (pendingMsgIndex !== -1) {
|
|
567870
569348
|
const updated = [...prev];
|
|
@@ -567881,8 +569359,8 @@ async function handleConversationWithTools(options3) {
|
|
|
567881
569359
|
return prev;
|
|
567882
569360
|
}
|
|
567883
569361
|
const existingIndex = prev.findIndex((m) => {
|
|
567884
|
-
var
|
|
567885
|
-
return m.role === "subagent" && ((
|
|
569362
|
+
var _a22, _b14;
|
|
569363
|
+
return m.role === "subagent" && ((_a22 = m.subAgent) == null ? void 0 : _a22.agentId) === subAgentMessage.agentId && !((_b14 = m.subAgent) == null ? void 0 : _b14.isComplete) && m.streaming === true && !m.pendingToolIds;
|
|
567886
569364
|
});
|
|
567887
569365
|
let contentToApply = "";
|
|
567888
569366
|
if (subAgentMessage.message.type === "content") {
|
|
@@ -568146,6 +569624,46 @@ async function handleConversationWithTools(options3) {
|
|
|
568146
569624
|
if (resultMessages.length > 0) {
|
|
568147
569625
|
setMessages((prev) => [...prev, ...resultMessages]);
|
|
568148
569626
|
}
|
|
569627
|
+
try {
|
|
569628
|
+
const { runningSubAgentTracker: runningSubAgentTracker2 } = await Promise.resolve().then(() => (init_runningSubAgentTracker(), runningSubAgentTracker_exports));
|
|
569629
|
+
const spawnedResults = runningSubAgentTracker2.drainSpawnedResults();
|
|
569630
|
+
if (spawnedResults.length > 0) {
|
|
569631
|
+
for (const sr of spawnedResults) {
|
|
569632
|
+
const statusIcon = sr.success ? "\u2713" : "\u2717";
|
|
569633
|
+
const resultSummary = sr.success ? sr.result.length > 500 ? sr.result.substring(0, 500) + "..." : sr.result : sr.error || "Unknown error";
|
|
569634
|
+
const spawnedContent = `[Spawned Sub-Agent Result] ${statusIcon} ${sr.agentName} (${sr.agentId}) \u2014 spawned by ${sr.spawnedBy.agentName}
|
|
569635
|
+
Prompt: ${sr.prompt}
|
|
569636
|
+
Result: ${resultSummary}`;
|
|
569637
|
+
conversationMessages.push({
|
|
569638
|
+
role: "user",
|
|
569639
|
+
content: spawnedContent
|
|
569640
|
+
});
|
|
569641
|
+
try {
|
|
569642
|
+
await saveMessage({
|
|
569643
|
+
role: "user",
|
|
569644
|
+
content: spawnedContent
|
|
569645
|
+
});
|
|
569646
|
+
} catch (error) {
|
|
569647
|
+
console.error("Failed to save spawned agent result:", error);
|
|
569648
|
+
}
|
|
569649
|
+
const uiMsg = {
|
|
569650
|
+
role: "subagent",
|
|
569651
|
+
content: `\x1B[38;2;150;120;255m\u2687${statusIcon} Spawned ${sr.agentName}\x1B[0m (by ${sr.spawnedBy.agentName}): ${sr.success ? "completed" : "failed"}`,
|
|
569652
|
+
streaming: false,
|
|
569653
|
+
messageStatus: sr.success ? "success" : "error",
|
|
569654
|
+
subAgent: {
|
|
569655
|
+
agentId: sr.agentId,
|
|
569656
|
+
agentName: sr.agentName,
|
|
569657
|
+
isComplete: true
|
|
569658
|
+
},
|
|
569659
|
+
subAgentInternal: true
|
|
569660
|
+
};
|
|
569661
|
+
setMessages((prev) => [...prev, uiMsg]);
|
|
569662
|
+
}
|
|
569663
|
+
}
|
|
569664
|
+
} catch (error) {
|
|
569665
|
+
console.error("Failed to process spawned agent results:", error);
|
|
569666
|
+
}
|
|
568149
569667
|
if (options3.getPendingMessages && options3.clearPendingMessages) {
|
|
568150
569668
|
const pendingMessages = options3.getPendingMessages();
|
|
568151
569669
|
if (pendingMessages.length > 0) {
|
|
@@ -568338,11 +569856,11 @@ async function handleConversationWithTools(options3) {
|
|
|
568338
569856
|
}
|
|
568339
569857
|
return { usage: accumulatedUsage };
|
|
568340
569858
|
}
|
|
568341
|
-
var
|
|
569859
|
+
var import_tiktoken2;
|
|
568342
569860
|
var init_useConversation = __esm({
|
|
568343
569861
|
async "dist/hooks/conversation/useConversation.js"() {
|
|
568344
569862
|
"use strict";
|
|
568345
|
-
|
|
569863
|
+
import_tiktoken2 = __toESM(require_tiktoken(), 1);
|
|
568346
569864
|
init_chat();
|
|
568347
569865
|
init_responses();
|
|
568348
569866
|
init_gemini();
|
|
@@ -571862,10 +573380,12 @@ ${errorMsg}`,
|
|
|
571862
573380
|
}
|
|
571863
573381
|
if (totalFileCount > 0) {
|
|
571864
573382
|
const filePaths2 = await hashBasedSnapshotManager.getFilesToRollback(currentSession.id, selectedIndex);
|
|
573383
|
+
const nbCount2 = getNotebookRollbackCount(currentSession.id, selectedIndex);
|
|
571865
573384
|
snapshotState.setPendingRollback({
|
|
571866
573385
|
messageIndex: selectedIndex,
|
|
571867
573386
|
fileCount: filePaths2.length,
|
|
571868
573387
|
filePaths: filePaths2,
|
|
573388
|
+
notebookCount: nbCount2,
|
|
571869
573389
|
message: cleanIDEContext(message),
|
|
571870
573390
|
images,
|
|
571871
573391
|
crossSessionRollback: true,
|
|
@@ -571898,11 +573418,13 @@ ${errorMsg}`,
|
|
|
571898
573418
|
}
|
|
571899
573419
|
}
|
|
571900
573420
|
const filePaths = await hashBasedSnapshotManager.getFilesToRollback(currentSession.id, selectedIndex);
|
|
571901
|
-
|
|
573421
|
+
const nbCount = getNotebookRollbackCount(currentSession.id, selectedIndex);
|
|
573422
|
+
if (filePaths.length > 0 || nbCount > 0) {
|
|
571902
573423
|
snapshotState.setPendingRollback({
|
|
571903
573424
|
messageIndex: selectedIndex,
|
|
571904
573425
|
fileCount: filePaths.length,
|
|
571905
573426
|
filePaths,
|
|
573427
|
+
notebookCount: nbCount,
|
|
571906
573428
|
message: cleanIDEContext(message),
|
|
571907
573429
|
images
|
|
571908
573430
|
});
|
|
@@ -571923,6 +573445,11 @@ ${errorMsg}`,
|
|
|
571923
573445
|
} else {
|
|
571924
573446
|
await hashBasedSnapshotManager.rollbackToMessageIndex(currentSession.id, selectedIndex);
|
|
571925
573447
|
}
|
|
573448
|
+
try {
|
|
573449
|
+
rollbackNotebooks(currentSession.id, selectedIndex);
|
|
573450
|
+
} catch (error) {
|
|
573451
|
+
console.error("Failed to rollback notebooks:", error);
|
|
573452
|
+
}
|
|
571926
573453
|
}
|
|
571927
573454
|
if (currentSession) {
|
|
571928
573455
|
const messagesAfterSelected = messages.slice(selectedIndex);
|
|
@@ -571960,6 +573487,7 @@ ${errorMsg}`,
|
|
|
571960
573487
|
}
|
|
571961
573488
|
if (sessionTruncateIndex === 0 && currentSession) {
|
|
571962
573489
|
await hashBasedSnapshotManager.clearAllSnapshots(currentSession.id);
|
|
573490
|
+
clearAllNotebookSnapshots(currentSession.id);
|
|
571963
573491
|
await sessionManager.deleteSession(currentSession.id);
|
|
571964
573492
|
sessionManager.clearCurrentSession();
|
|
571965
573493
|
setMessages([]);
|
|
@@ -571972,6 +573500,9 @@ ${errorMsg}`,
|
|
|
571972
573500
|
return;
|
|
571973
573501
|
}
|
|
571974
573502
|
await hashBasedSnapshotManager.deleteSnapshotsFromIndex(currentSession.id, selectedIndex);
|
|
573503
|
+
if (!rollbackFiles) {
|
|
573504
|
+
deleteNotebookSnapshotsFromIndex(currentSession.id, selectedIndex);
|
|
573505
|
+
}
|
|
571975
573506
|
const snapshots = await hashBasedSnapshotManager.listSnapshots(currentSession.id);
|
|
571976
573507
|
const counts = /* @__PURE__ */ new Map();
|
|
571977
573508
|
for (const snapshot of snapshots) {
|
|
@@ -572337,6 +573868,7 @@ var init_useChatLogic = __esm({
|
|
|
572337
573868
|
init_vscodeConnection();
|
|
572338
573869
|
init_reindexCodebase();
|
|
572339
573870
|
init_runningSubAgentTracker();
|
|
573871
|
+
init_notebookManager();
|
|
572340
573872
|
}
|
|
572341
573873
|
});
|
|
572342
573874
|
|
|
@@ -573918,7 +575450,7 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
|
|
|
573918
575450
|
import_react143.default.createElement(PermissionsPanel2, { alwaysApprovedTools, onRemoveTool: removeFromAlwaysApproved, onClearAll: clearAllAlwaysApproved, onClose: () => setShowPermissionsPanel(false) })
|
|
573919
575451
|
)
|
|
573920
575452
|
),
|
|
573921
|
-
snapshotState.pendingRollback && import_react143.default.createElement(FileRollbackConfirmation, { fileCount: snapshotState.pendingRollback.fileCount, filePaths: snapshotState.pendingRollback.filePaths || [], previewSessionId: (_a21 = sessionManager.getCurrentSession()) == null ? void 0 : _a21.id, previewTargetMessageIndex: snapshotState.pendingRollback.messageIndex, onConfirm: handleRollbackConfirm }),
|
|
575453
|
+
snapshotState.pendingRollback && import_react143.default.createElement(FileRollbackConfirmation, { fileCount: snapshotState.pendingRollback.fileCount, filePaths: snapshotState.pendingRollback.filePaths || [], notebookCount: snapshotState.pendingRollback.notebookCount, previewSessionId: (_a21 = sessionManager.getCurrentSession()) == null ? void 0 : _a21.id, previewTargetMessageIndex: snapshotState.pendingRollback.messageIndex, onConfirm: handleRollbackConfirm }),
|
|
573922
575454
|
!pendingToolConfirmation && !pendingUserQuestion && !bashSensitiveCommand && !terminalExecutionState.state.needsInput && !(panelState.showSessionPanel || panelState.showMcpPanel || panelState.showUsagePanel || panelState.showModelsPanel || panelState.showCustomCommandConfig || panelState.showSkillsCreation || panelState.showRoleCreation || panelState.showRoleDeletion || panelState.showRoleList || panelState.showWorkingDirPanel || panelState.showBranchPanel || showPermissionsPanel) && !snapshotState.pendingRollback && import_react143.default.createElement(ChatFooter, { onSubmit: handleMessageSubmit, onCommand: handleCommandExecution, onHistorySelect: handleHistorySelect, onSwitchProfile: handleSwitchProfile, handleProfileSelect, handleHistorySelect, showReviewCommitPanel: panelState.showReviewCommitPanel, setShowReviewCommitPanel: panelState.setShowReviewCommitPanel, onReviewCommitConfirm: handleReviewCommitConfirm, disabled: !!pendingToolConfirmation || !!bashSensitiveCommand || isExecutingTerminalCommand || isCompressing || streamingState.isStopping, isStopping: streamingState.isStopping, isProcessing: streamingState.isStreaming || isSaving || bashMode.state.isExecuting || isCompressing, chatHistory: messages, yoloMode, setYoloMode, planMode, setPlanMode, vulnerabilityHuntingMode, setVulnerabilityHuntingMode, contextUsage: streamingState.contextUsage ? {
|
|
573923
575455
|
inputTokens: streamingState.contextUsage.prompt_tokens,
|
|
573924
575456
|
maxContextTokens: getOpenAiConfig().maxContextTokens || 4e3,
|