llmist 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -58
- package/dist/{chunk-VXPZQZF5.js → chunk-RZTAKIDE.js} +1279 -360
- package/dist/chunk-RZTAKIDE.js.map +1 -0
- package/dist/{chunk-OIPLYP7M.js → chunk-TFIKR2RK.js} +459 -3
- package/dist/chunk-TFIKR2RK.js.map +1 -0
- package/dist/cli.cjs +1316 -393
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +49 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1446 -362
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +360 -32
- package/dist/index.d.ts +360 -32
- package/dist/index.js +177 -2
- package/dist/index.js.map +1 -1
- package/dist/{mock-stream-DKF5yatf.d.cts → mock-stream-DNt-HBTn.d.cts} +525 -79
- package/dist/{mock-stream-DKF5yatf.d.ts → mock-stream-DNt-HBTn.d.ts} +525 -79
- package/dist/testing/index.cjs +1739 -362
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +437 -3
- package/dist/testing/index.d.ts +437 -3
- package/dist/testing/index.js +54 -4
- package/package.json +1 -1
- package/dist/chunk-OIPLYP7M.js.map +0 -1
- package/dist/chunk-VXPZQZF5.js.map +0 -1
|
@@ -348,10 +348,21 @@ function resolveRulesTemplate(rules, context) {
|
|
|
348
348
|
}
|
|
349
349
|
return [resolved];
|
|
350
350
|
}
|
|
351
|
-
|
|
351
|
+
function resolveHintTemplate(template, defaultValue, context) {
|
|
352
|
+
const resolved = template ?? defaultValue;
|
|
353
|
+
if (typeof resolved === "function") {
|
|
354
|
+
return resolved(context);
|
|
355
|
+
}
|
|
356
|
+
return resolved.replace(/\{iteration\}/g, String(context.iteration)).replace(/\{maxIterations\}/g, String(context.maxIterations)).replace(/\{remaining\}/g, String(context.remaining));
|
|
357
|
+
}
|
|
358
|
+
var DEFAULT_HINTS, DEFAULT_PROMPTS;
|
|
352
359
|
var init_prompt_config = __esm({
|
|
353
360
|
"src/core/prompt-config.ts"() {
|
|
354
361
|
"use strict";
|
|
362
|
+
DEFAULT_HINTS = {
|
|
363
|
+
parallelGadgetsHint: "Tip: You can call multiple gadgets in a single response for efficiency.",
|
|
364
|
+
iterationProgressHint: "[Iteration {iteration}/{maxIterations}] Plan your actions accordingly."
|
|
365
|
+
};
|
|
355
366
|
DEFAULT_PROMPTS = {
|
|
356
367
|
mainInstruction: [
|
|
357
368
|
"\u26A0\uFE0F CRITICAL: RESPOND ONLY WITH GADGET INVOCATIONS",
|
|
@@ -1116,6 +1127,417 @@ var init_output_viewer = __esm({
|
|
|
1116
1127
|
}
|
|
1117
1128
|
});
|
|
1118
1129
|
|
|
1130
|
+
// src/agent/compaction/config.ts
|
|
1131
|
+
function resolveCompactionConfig(config = {}) {
|
|
1132
|
+
const trigger = config.triggerThresholdPercent ?? DEFAULT_COMPACTION_CONFIG.triggerThresholdPercent;
|
|
1133
|
+
const target = config.targetPercent ?? DEFAULT_COMPACTION_CONFIG.targetPercent;
|
|
1134
|
+
if (target >= trigger) {
|
|
1135
|
+
console.warn(
|
|
1136
|
+
`[llmist/compaction] targetPercent (${target}) should be less than triggerThresholdPercent (${trigger}) to be effective.`
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
const strategy = config.strategy ?? DEFAULT_COMPACTION_CONFIG.strategy;
|
|
1140
|
+
const strategyName = typeof strategy === "object" && "name" in strategy ? strategy.name : strategy;
|
|
1141
|
+
return {
|
|
1142
|
+
enabled: config.enabled ?? DEFAULT_COMPACTION_CONFIG.enabled,
|
|
1143
|
+
strategy: strategyName,
|
|
1144
|
+
triggerThresholdPercent: trigger,
|
|
1145
|
+
targetPercent: target,
|
|
1146
|
+
preserveRecentTurns: config.preserveRecentTurns ?? DEFAULT_COMPACTION_CONFIG.preserveRecentTurns,
|
|
1147
|
+
summarizationModel: config.summarizationModel,
|
|
1148
|
+
summarizationPrompt: config.summarizationPrompt ?? DEFAULT_SUMMARIZATION_PROMPT,
|
|
1149
|
+
onCompaction: config.onCompaction
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
var DEFAULT_COMPACTION_CONFIG, DEFAULT_SUMMARIZATION_PROMPT;
|
|
1153
|
+
var init_config = __esm({
|
|
1154
|
+
"src/agent/compaction/config.ts"() {
|
|
1155
|
+
"use strict";
|
|
1156
|
+
DEFAULT_COMPACTION_CONFIG = {
|
|
1157
|
+
enabled: true,
|
|
1158
|
+
strategy: "hybrid",
|
|
1159
|
+
triggerThresholdPercent: 80,
|
|
1160
|
+
targetPercent: 50,
|
|
1161
|
+
preserveRecentTurns: 5
|
|
1162
|
+
};
|
|
1163
|
+
DEFAULT_SUMMARIZATION_PROMPT = `Summarize this conversation history concisely, preserving:
|
|
1164
|
+
1. Key decisions made and their rationale
|
|
1165
|
+
2. Important facts and data discovered
|
|
1166
|
+
3. Errors encountered and how they were resolved
|
|
1167
|
+
4. Current task context and goals
|
|
1168
|
+
|
|
1169
|
+
Format as a brief narrative paragraph, not bullet points.
|
|
1170
|
+
Previous conversation:`;
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
|
|
1174
|
+
// src/agent/compaction/strategy.ts
|
|
1175
|
+
function groupIntoTurns(messages) {
|
|
1176
|
+
const turns = [];
|
|
1177
|
+
let currentTurn = [];
|
|
1178
|
+
for (const msg of messages) {
|
|
1179
|
+
if (msg.role === "user" && currentTurn.length > 0) {
|
|
1180
|
+
turns.push({
|
|
1181
|
+
messages: currentTurn,
|
|
1182
|
+
tokenEstimate: estimateTurnTokens(currentTurn)
|
|
1183
|
+
});
|
|
1184
|
+
currentTurn = [msg];
|
|
1185
|
+
} else {
|
|
1186
|
+
currentTurn.push(msg);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
if (currentTurn.length > 0) {
|
|
1190
|
+
turns.push({
|
|
1191
|
+
messages: currentTurn,
|
|
1192
|
+
tokenEstimate: estimateTurnTokens(currentTurn)
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
return turns;
|
|
1196
|
+
}
|
|
1197
|
+
function estimateTurnTokens(messages) {
|
|
1198
|
+
return Math.ceil(messages.reduce((sum, msg) => sum + (msg.content?.length ?? 0), 0) / 4);
|
|
1199
|
+
}
|
|
1200
|
+
function flattenTurns(turns) {
|
|
1201
|
+
return turns.flatMap((turn) => turn.messages);
|
|
1202
|
+
}
|
|
1203
|
+
var init_strategy = __esm({
|
|
1204
|
+
"src/agent/compaction/strategy.ts"() {
|
|
1205
|
+
"use strict";
|
|
1206
|
+
}
|
|
1207
|
+
});
|
|
1208
|
+
|
|
1209
|
+
// src/agent/compaction/strategies/sliding-window.ts
|
|
1210
|
+
var TRUNCATION_MARKER_TEMPLATE, SlidingWindowStrategy;
|
|
1211
|
+
var init_sliding_window = __esm({
|
|
1212
|
+
"src/agent/compaction/strategies/sliding-window.ts"() {
|
|
1213
|
+
"use strict";
|
|
1214
|
+
init_strategy();
|
|
1215
|
+
TRUNCATION_MARKER_TEMPLATE = "[Previous conversation truncated. Removed {count} turn(s) to fit context window.]";
|
|
1216
|
+
SlidingWindowStrategy = class {
|
|
1217
|
+
name = "sliding-window";
|
|
1218
|
+
async compact(messages, config, context) {
|
|
1219
|
+
const turns = groupIntoTurns(messages);
|
|
1220
|
+
const preserveCount = Math.min(config.preserveRecentTurns, turns.length);
|
|
1221
|
+
if (turns.length <= preserveCount) {
|
|
1222
|
+
return {
|
|
1223
|
+
messages,
|
|
1224
|
+
strategyName: this.name,
|
|
1225
|
+
metadata: {
|
|
1226
|
+
originalCount: messages.length,
|
|
1227
|
+
compactedCount: messages.length,
|
|
1228
|
+
tokensBefore: context.currentTokens,
|
|
1229
|
+
tokensAfter: context.currentTokens
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
const turnsToKeep = turns.slice(-preserveCount);
|
|
1234
|
+
const turnsRemoved = turns.length - preserveCount;
|
|
1235
|
+
const truncationMarker = {
|
|
1236
|
+
role: "user",
|
|
1237
|
+
content: TRUNCATION_MARKER_TEMPLATE.replace("{count}", turnsRemoved.toString())
|
|
1238
|
+
};
|
|
1239
|
+
const compactedMessages = [truncationMarker, ...flattenTurns(turnsToKeep)];
|
|
1240
|
+
const tokensAfter = Math.ceil(
|
|
1241
|
+
compactedMessages.reduce((sum, msg) => sum + (msg.content?.length ?? 0), 0) / 4
|
|
1242
|
+
);
|
|
1243
|
+
return {
|
|
1244
|
+
messages: compactedMessages,
|
|
1245
|
+
strategyName: this.name,
|
|
1246
|
+
metadata: {
|
|
1247
|
+
originalCount: messages.length,
|
|
1248
|
+
compactedCount: compactedMessages.length,
|
|
1249
|
+
tokensBefore: context.currentTokens,
|
|
1250
|
+
tokensAfter
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
// src/agent/compaction/strategies/summarization.ts
|
|
1259
|
+
var SummarizationStrategy;
|
|
1260
|
+
var init_summarization = __esm({
|
|
1261
|
+
"src/agent/compaction/strategies/summarization.ts"() {
|
|
1262
|
+
"use strict";
|
|
1263
|
+
init_strategy();
|
|
1264
|
+
SummarizationStrategy = class {
|
|
1265
|
+
name = "summarization";
|
|
1266
|
+
async compact(messages, config, context) {
|
|
1267
|
+
const turns = groupIntoTurns(messages);
|
|
1268
|
+
const preserveCount = Math.min(config.preserveRecentTurns, turns.length);
|
|
1269
|
+
if (turns.length <= preserveCount) {
|
|
1270
|
+
return {
|
|
1271
|
+
messages,
|
|
1272
|
+
strategyName: this.name,
|
|
1273
|
+
metadata: {
|
|
1274
|
+
originalCount: messages.length,
|
|
1275
|
+
compactedCount: messages.length,
|
|
1276
|
+
tokensBefore: context.currentTokens,
|
|
1277
|
+
tokensAfter: context.currentTokens
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
}
|
|
1281
|
+
const turnsToSummarize = turns.slice(0, -preserveCount);
|
|
1282
|
+
const turnsToKeep = turns.slice(-preserveCount);
|
|
1283
|
+
const conversationToSummarize = this.formatTurnsForSummary(flattenTurns(turnsToSummarize));
|
|
1284
|
+
const summary = await this.generateSummary(conversationToSummarize, config, context);
|
|
1285
|
+
const summaryMessage = {
|
|
1286
|
+
role: "user",
|
|
1287
|
+
content: `[Previous conversation summary]
|
|
1288
|
+
${summary}
|
|
1289
|
+
[End of summary - conversation continues below]`
|
|
1290
|
+
};
|
|
1291
|
+
const compactedMessages = [summaryMessage, ...flattenTurns(turnsToKeep)];
|
|
1292
|
+
const tokensAfter = Math.ceil(
|
|
1293
|
+
compactedMessages.reduce((sum, msg) => sum + (msg.content?.length ?? 0), 0) / 4
|
|
1294
|
+
);
|
|
1295
|
+
return {
|
|
1296
|
+
messages: compactedMessages,
|
|
1297
|
+
summary,
|
|
1298
|
+
strategyName: this.name,
|
|
1299
|
+
metadata: {
|
|
1300
|
+
originalCount: messages.length,
|
|
1301
|
+
compactedCount: compactedMessages.length,
|
|
1302
|
+
tokensBefore: context.currentTokens,
|
|
1303
|
+
tokensAfter
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Formats messages into a readable conversation format for summarization.
|
|
1309
|
+
*/
|
|
1310
|
+
formatTurnsForSummary(messages) {
|
|
1311
|
+
return messages.map((msg) => {
|
|
1312
|
+
const role = msg.role.charAt(0).toUpperCase() + msg.role.slice(1);
|
|
1313
|
+
return `${role}: ${msg.content}`;
|
|
1314
|
+
}).join("\n\n");
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Generates a summary using the configured LLM.
|
|
1318
|
+
*/
|
|
1319
|
+
async generateSummary(conversation, config, context) {
|
|
1320
|
+
const model = config.summarizationModel ?? context.model;
|
|
1321
|
+
const prompt = `${config.summarizationPrompt}
|
|
1322
|
+
|
|
1323
|
+
${conversation}`;
|
|
1324
|
+
const response = await context.client.complete(prompt, {
|
|
1325
|
+
model,
|
|
1326
|
+
temperature: 0.3
|
|
1327
|
+
// Low temperature for factual summarization
|
|
1328
|
+
});
|
|
1329
|
+
return response.trim();
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
|
|
1335
|
+
// src/agent/compaction/strategies/hybrid.ts
|
|
1336
|
+
var MIN_TURNS_FOR_SUMMARIZATION, HybridStrategy;
|
|
1337
|
+
var init_hybrid = __esm({
|
|
1338
|
+
"src/agent/compaction/strategies/hybrid.ts"() {
|
|
1339
|
+
"use strict";
|
|
1340
|
+
init_strategy();
|
|
1341
|
+
init_sliding_window();
|
|
1342
|
+
init_summarization();
|
|
1343
|
+
MIN_TURNS_FOR_SUMMARIZATION = 3;
|
|
1344
|
+
HybridStrategy = class {
|
|
1345
|
+
name = "hybrid";
|
|
1346
|
+
slidingWindow = new SlidingWindowStrategy();
|
|
1347
|
+
summarization = new SummarizationStrategy();
|
|
1348
|
+
async compact(messages, config, context) {
|
|
1349
|
+
const turns = groupIntoTurns(messages);
|
|
1350
|
+
const preserveCount = Math.min(config.preserveRecentTurns, turns.length);
|
|
1351
|
+
if (turns.length <= preserveCount) {
|
|
1352
|
+
return {
|
|
1353
|
+
messages,
|
|
1354
|
+
strategyName: this.name,
|
|
1355
|
+
metadata: {
|
|
1356
|
+
originalCount: messages.length,
|
|
1357
|
+
compactedCount: messages.length,
|
|
1358
|
+
tokensBefore: context.currentTokens,
|
|
1359
|
+
tokensAfter: context.currentTokens
|
|
1360
|
+
}
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
const turnsToSummarize = turns.length - preserveCount;
|
|
1364
|
+
if (turnsToSummarize < MIN_TURNS_FOR_SUMMARIZATION) {
|
|
1365
|
+
return this.slidingWindow.compact(messages, config, context);
|
|
1366
|
+
}
|
|
1367
|
+
return this.summarization.compact(messages, config, context);
|
|
1368
|
+
}
|
|
1369
|
+
};
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1372
|
+
|
|
1373
|
+
// src/agent/compaction/strategies/index.ts
|
|
1374
|
+
var init_strategies = __esm({
|
|
1375
|
+
"src/agent/compaction/strategies/index.ts"() {
|
|
1376
|
+
"use strict";
|
|
1377
|
+
init_sliding_window();
|
|
1378
|
+
init_summarization();
|
|
1379
|
+
init_hybrid();
|
|
1380
|
+
}
|
|
1381
|
+
});
|
|
1382
|
+
|
|
1383
|
+
// src/agent/compaction/manager.ts
|
|
1384
|
+
function createStrategy(name) {
|
|
1385
|
+
switch (name) {
|
|
1386
|
+
case "sliding-window":
|
|
1387
|
+
return new SlidingWindowStrategy();
|
|
1388
|
+
case "summarization":
|
|
1389
|
+
return new SummarizationStrategy();
|
|
1390
|
+
case "hybrid":
|
|
1391
|
+
return new HybridStrategy();
|
|
1392
|
+
default:
|
|
1393
|
+
throw new Error(`Unknown compaction strategy: ${name}`);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
var CompactionManager;
|
|
1397
|
+
var init_manager = __esm({
|
|
1398
|
+
"src/agent/compaction/manager.ts"() {
|
|
1399
|
+
"use strict";
|
|
1400
|
+
init_config();
|
|
1401
|
+
init_strategies();
|
|
1402
|
+
CompactionManager = class {
|
|
1403
|
+
client;
|
|
1404
|
+
model;
|
|
1405
|
+
config;
|
|
1406
|
+
strategy;
|
|
1407
|
+
modelLimits;
|
|
1408
|
+
// Statistics
|
|
1409
|
+
totalCompactions = 0;
|
|
1410
|
+
totalTokensSaved = 0;
|
|
1411
|
+
lastTokenCount = 0;
|
|
1412
|
+
constructor(client, model, config = {}) {
|
|
1413
|
+
this.client = client;
|
|
1414
|
+
this.model = model;
|
|
1415
|
+
this.config = resolveCompactionConfig(config);
|
|
1416
|
+
if (typeof config.strategy === "object" && "compact" in config.strategy) {
|
|
1417
|
+
this.strategy = config.strategy;
|
|
1418
|
+
} else {
|
|
1419
|
+
this.strategy = createStrategy(this.config.strategy);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
/**
|
|
1423
|
+
* Check if compaction is needed and perform it if so.
|
|
1424
|
+
*
|
|
1425
|
+
* @param conversation - The conversation manager to compact
|
|
1426
|
+
* @param iteration - Current agent iteration (for event metadata)
|
|
1427
|
+
* @returns CompactionEvent if compaction was performed, null otherwise
|
|
1428
|
+
*/
|
|
1429
|
+
async checkAndCompact(conversation, iteration) {
|
|
1430
|
+
if (!this.config.enabled) {
|
|
1431
|
+
return null;
|
|
1432
|
+
}
|
|
1433
|
+
if (!this.modelLimits) {
|
|
1434
|
+
this.modelLimits = this.client.modelRegistry.getModelLimits(this.model);
|
|
1435
|
+
if (!this.modelLimits) {
|
|
1436
|
+
return null;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
if (!this.client.countTokens) {
|
|
1440
|
+
return null;
|
|
1441
|
+
}
|
|
1442
|
+
const messages = conversation.getMessages();
|
|
1443
|
+
const currentTokens = await this.client.countTokens(this.model, messages);
|
|
1444
|
+
this.lastTokenCount = currentTokens;
|
|
1445
|
+
const usagePercent = currentTokens / this.modelLimits.contextWindow * 100;
|
|
1446
|
+
if (usagePercent < this.config.triggerThresholdPercent) {
|
|
1447
|
+
return null;
|
|
1448
|
+
}
|
|
1449
|
+
const historyMessages = conversation.getHistoryMessages();
|
|
1450
|
+
const baseMessages = conversation.getBaseMessages();
|
|
1451
|
+
const historyTokens = await this.client.countTokens(this.model, historyMessages);
|
|
1452
|
+
const baseTokens = await this.client.countTokens(this.model, baseMessages);
|
|
1453
|
+
return this.compact(conversation, iteration, {
|
|
1454
|
+
historyMessages,
|
|
1455
|
+
baseMessages,
|
|
1456
|
+
historyTokens,
|
|
1457
|
+
baseTokens,
|
|
1458
|
+
currentTokens: historyTokens + baseTokens
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Force compaction regardless of threshold.
|
|
1463
|
+
*
|
|
1464
|
+
* @param conversation - The conversation manager to compact
|
|
1465
|
+
* @param iteration - Current agent iteration (for event metadata). Use -1 for manual compaction.
|
|
1466
|
+
* @param precomputed - Optional pre-computed token counts (passed from checkAndCompact for efficiency)
|
|
1467
|
+
* @returns CompactionEvent with compaction details
|
|
1468
|
+
*/
|
|
1469
|
+
async compact(conversation, iteration, precomputed) {
|
|
1470
|
+
if (!this.modelLimits) {
|
|
1471
|
+
this.modelLimits = this.client.modelRegistry.getModelLimits(this.model);
|
|
1472
|
+
if (!this.modelLimits) {
|
|
1473
|
+
return null;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
const historyMessages = precomputed?.historyMessages ?? conversation.getHistoryMessages();
|
|
1477
|
+
const baseMessages = precomputed?.baseMessages ?? conversation.getBaseMessages();
|
|
1478
|
+
const historyTokens = precomputed?.historyTokens ?? await this.client.countTokens(this.model, historyMessages);
|
|
1479
|
+
const baseTokens = precomputed?.baseTokens ?? await this.client.countTokens(this.model, baseMessages);
|
|
1480
|
+
const currentTokens = precomputed?.currentTokens ?? historyTokens + baseTokens;
|
|
1481
|
+
const targetTotalTokens = Math.floor(
|
|
1482
|
+
this.modelLimits.contextWindow * this.config.targetPercent / 100
|
|
1483
|
+
);
|
|
1484
|
+
const targetHistoryTokens = Math.max(0, targetTotalTokens - baseTokens);
|
|
1485
|
+
const result = await this.strategy.compact(historyMessages, this.config, {
|
|
1486
|
+
currentTokens: historyTokens,
|
|
1487
|
+
targetTokens: targetHistoryTokens,
|
|
1488
|
+
modelLimits: this.modelLimits,
|
|
1489
|
+
client: this.client,
|
|
1490
|
+
model: this.config.summarizationModel ?? this.model
|
|
1491
|
+
});
|
|
1492
|
+
conversation.replaceHistory(result.messages);
|
|
1493
|
+
const afterTokens = await this.client.countTokens(this.model, conversation.getMessages());
|
|
1494
|
+
const tokensSaved = currentTokens - afterTokens;
|
|
1495
|
+
this.totalCompactions++;
|
|
1496
|
+
this.totalTokensSaved += tokensSaved;
|
|
1497
|
+
this.lastTokenCount = afterTokens;
|
|
1498
|
+
const event = {
|
|
1499
|
+
strategy: result.strategyName,
|
|
1500
|
+
tokensBefore: currentTokens,
|
|
1501
|
+
tokensAfter: afterTokens,
|
|
1502
|
+
messagesBefore: historyMessages.length + baseMessages.length,
|
|
1503
|
+
messagesAfter: result.messages.length + baseMessages.length,
|
|
1504
|
+
summary: result.summary,
|
|
1505
|
+
iteration
|
|
1506
|
+
};
|
|
1507
|
+
if (this.config.onCompaction) {
|
|
1508
|
+
try {
|
|
1509
|
+
this.config.onCompaction(event);
|
|
1510
|
+
} catch (err) {
|
|
1511
|
+
console.warn("[llmist/compaction] onCompaction callback error:", err);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
return event;
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Get compaction statistics.
|
|
1518
|
+
*/
|
|
1519
|
+
getStats() {
|
|
1520
|
+
const contextWindow = this.modelLimits?.contextWindow ?? 0;
|
|
1521
|
+
return {
|
|
1522
|
+
totalCompactions: this.totalCompactions,
|
|
1523
|
+
totalTokensSaved: this.totalTokensSaved,
|
|
1524
|
+
currentUsage: {
|
|
1525
|
+
tokens: this.lastTokenCount,
|
|
1526
|
+
percent: contextWindow > 0 ? this.lastTokenCount / contextWindow * 100 : 0
|
|
1527
|
+
},
|
|
1528
|
+
contextWindow
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Check if compaction is enabled.
|
|
1533
|
+
*/
|
|
1534
|
+
isEnabled() {
|
|
1535
|
+
return this.config.enabled;
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1119
1541
|
// src/agent/gadget-output-store.ts
|
|
1120
1542
|
import { randomBytes } from "node:crypto";
|
|
1121
1543
|
var GadgetOutputStore;
|
|
@@ -1206,10 +1628,16 @@ var init_conversation_manager = __esm({
|
|
|
1206
1628
|
baseMessages;
|
|
1207
1629
|
initialMessages;
|
|
1208
1630
|
historyBuilder;
|
|
1631
|
+
startPrefix;
|
|
1632
|
+
endPrefix;
|
|
1633
|
+
argPrefix;
|
|
1209
1634
|
constructor(baseMessages, initialMessages, options = {}) {
|
|
1210
1635
|
this.baseMessages = baseMessages;
|
|
1211
1636
|
this.initialMessages = initialMessages;
|
|
1212
1637
|
this.historyBuilder = new LLMMessageBuilder();
|
|
1638
|
+
this.startPrefix = options.startPrefix;
|
|
1639
|
+
this.endPrefix = options.endPrefix;
|
|
1640
|
+
this.argPrefix = options.argPrefix;
|
|
1213
1641
|
if (options.startPrefix && options.endPrefix) {
|
|
1214
1642
|
this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix, options.argPrefix);
|
|
1215
1643
|
}
|
|
@@ -1226,6 +1654,25 @@ var init_conversation_manager = __esm({
|
|
|
1226
1654
|
getMessages() {
|
|
1227
1655
|
return [...this.baseMessages, ...this.initialMessages, ...this.historyBuilder.build()];
|
|
1228
1656
|
}
|
|
1657
|
+
getHistoryMessages() {
|
|
1658
|
+
return this.historyBuilder.build();
|
|
1659
|
+
}
|
|
1660
|
+
getBaseMessages() {
|
|
1661
|
+
return [...this.baseMessages, ...this.initialMessages];
|
|
1662
|
+
}
|
|
1663
|
+
replaceHistory(newHistory) {
|
|
1664
|
+
this.historyBuilder = new LLMMessageBuilder();
|
|
1665
|
+
if (this.startPrefix && this.endPrefix) {
|
|
1666
|
+
this.historyBuilder.withPrefixes(this.startPrefix, this.endPrefix, this.argPrefix);
|
|
1667
|
+
}
|
|
1668
|
+
for (const msg of newHistory) {
|
|
1669
|
+
if (msg.role === "user") {
|
|
1670
|
+
this.historyBuilder.addUser(msg.content);
|
|
1671
|
+
} else if (msg.role === "assistant") {
|
|
1672
|
+
this.historyBuilder.addAssistant(msg.content);
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1229
1676
|
};
|
|
1230
1677
|
}
|
|
1231
1678
|
});
|
|
@@ -1346,324 +1793,264 @@ var init_exceptions = __esm({
|
|
|
1346
1793
|
}
|
|
1347
1794
|
});
|
|
1348
1795
|
|
|
1349
|
-
// src/gadgets/
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1796
|
+
// src/gadgets/schema-introspector.ts
|
|
1797
|
+
function getDef(schema) {
|
|
1798
|
+
return schema._def;
|
|
1799
|
+
}
|
|
1800
|
+
function getTypeName(schema) {
|
|
1801
|
+
const def = getDef(schema);
|
|
1802
|
+
return def?.type ?? def?.typeName;
|
|
1803
|
+
}
|
|
1804
|
+
function getShape(schema) {
|
|
1805
|
+
const def = getDef(schema);
|
|
1806
|
+
if (typeof def?.shape === "function") {
|
|
1807
|
+
return def.shape();
|
|
1808
|
+
}
|
|
1809
|
+
return def?.shape;
|
|
1810
|
+
}
|
|
1811
|
+
var SchemaIntrospector;
|
|
1812
|
+
var init_schema_introspector = __esm({
|
|
1813
|
+
"src/gadgets/schema-introspector.ts"() {
|
|
1353
1814
|
"use strict";
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
constructor(options = {}) {
|
|
1360
|
-
this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
|
|
1361
|
-
this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
|
|
1362
|
-
this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
|
|
1815
|
+
SchemaIntrospector = class {
|
|
1816
|
+
schema;
|
|
1817
|
+
cache = /* @__PURE__ */ new Map();
|
|
1818
|
+
constructor(schema) {
|
|
1819
|
+
this.schema = schema;
|
|
1363
1820
|
}
|
|
1364
1821
|
/**
|
|
1365
|
-
*
|
|
1822
|
+
* Get the expected type at a JSON pointer path.
|
|
1366
1823
|
*
|
|
1367
|
-
* @param
|
|
1368
|
-
* @
|
|
1369
|
-
* @param gadget - The gadget instance (for generating instructions)
|
|
1370
|
-
* @returns Formatted error message with usage instructions
|
|
1824
|
+
* @param pointer - JSON pointer path without leading / (e.g., "config/timeout", "items/0")
|
|
1825
|
+
* @returns Type hint for coercion decision
|
|
1371
1826
|
*/
|
|
1372
|
-
|
|
1373
|
-
const
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
const path = issue.path.join(".") || "root";
|
|
1377
|
-
parts.push(` - ${path}: ${issue.message}`);
|
|
1827
|
+
getTypeAtPath(pointer) {
|
|
1828
|
+
const cached = this.cache.get(pointer);
|
|
1829
|
+
if (cached !== void 0) {
|
|
1830
|
+
return cached;
|
|
1378
1831
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
return parts.join("\n");
|
|
1832
|
+
const result = this.resolveTypeAtPath(pointer);
|
|
1833
|
+
this.cache.set(pointer, result);
|
|
1834
|
+
return result;
|
|
1383
1835
|
}
|
|
1384
1836
|
/**
|
|
1385
|
-
*
|
|
1386
|
-
*
|
|
1387
|
-
* @param gadgetName - Name of the gadget that was called
|
|
1388
|
-
* @param parseError - The parse error message
|
|
1389
|
-
* @param gadget - The gadget instance if found (for generating instructions)
|
|
1390
|
-
* @returns Formatted error message with format reference
|
|
1837
|
+
* Internal method to resolve type at path without caching.
|
|
1391
1838
|
*/
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1839
|
+
resolveTypeAtPath(pointer) {
|
|
1840
|
+
if (!pointer) {
|
|
1841
|
+
return this.getBaseType(this.schema);
|
|
1842
|
+
}
|
|
1843
|
+
const segments = pointer.split("/");
|
|
1844
|
+
let current = this.schema;
|
|
1845
|
+
for (const segment of segments) {
|
|
1846
|
+
current = this.unwrapSchema(current);
|
|
1847
|
+
const typeName = getTypeName(current);
|
|
1848
|
+
if (typeName === "object" || typeName === "ZodObject") {
|
|
1849
|
+
const shape = getShape(current);
|
|
1850
|
+
if (!shape || !(segment in shape)) {
|
|
1851
|
+
return "unknown";
|
|
1852
|
+
}
|
|
1853
|
+
current = shape[segment];
|
|
1854
|
+
} else if (typeName === "array" || typeName === "ZodArray") {
|
|
1855
|
+
if (!/^\d+$/.test(segment)) {
|
|
1856
|
+
return "unknown";
|
|
1857
|
+
}
|
|
1858
|
+
const def = getDef(current);
|
|
1859
|
+
const elementType = def?.element ?? def?.type;
|
|
1860
|
+
if (!elementType) {
|
|
1861
|
+
return "unknown";
|
|
1862
|
+
}
|
|
1863
|
+
current = elementType;
|
|
1864
|
+
} else if (typeName === "tuple" || typeName === "ZodTuple") {
|
|
1865
|
+
if (!/^\d+$/.test(segment)) {
|
|
1866
|
+
return "unknown";
|
|
1867
|
+
}
|
|
1868
|
+
const index = parseInt(segment, 10);
|
|
1869
|
+
const def = getDef(current);
|
|
1870
|
+
const items = def?.items;
|
|
1871
|
+
if (!items || index >= items.length) {
|
|
1872
|
+
return "unknown";
|
|
1873
|
+
}
|
|
1874
|
+
current = items[index];
|
|
1875
|
+
} else if (typeName === "record" || typeName === "ZodRecord") {
|
|
1876
|
+
const def = getDef(current);
|
|
1877
|
+
const valueType = def?.valueType;
|
|
1878
|
+
if (!valueType) {
|
|
1879
|
+
return "unknown";
|
|
1880
|
+
}
|
|
1881
|
+
current = valueType;
|
|
1882
|
+
} else {
|
|
1883
|
+
return "unknown";
|
|
1884
|
+
}
|
|
1400
1885
|
}
|
|
1401
|
-
|
|
1402
|
-
parts.push("Block Format Reference:");
|
|
1403
|
-
parts.push(` ${this.startPrefix}${gadgetName}`);
|
|
1404
|
-
parts.push(` ${this.argPrefix}parameterName`);
|
|
1405
|
-
parts.push(" parameter value here");
|
|
1406
|
-
parts.push(` ${this.endPrefix}`);
|
|
1407
|
-
return parts.join("\n");
|
|
1886
|
+
return this.getBaseType(current);
|
|
1408
1887
|
}
|
|
1409
1888
|
/**
|
|
1410
|
-
*
|
|
1411
|
-
*
|
|
1412
|
-
* @param gadgetName - Name of the gadget that was not found
|
|
1413
|
-
* @param availableGadgets - List of available gadget names
|
|
1414
|
-
* @returns Formatted error message with available gadgets
|
|
1889
|
+
* Unwrap schema modifiers (optional, default, nullable, branded, etc.)
|
|
1890
|
+
* to get to the underlying type.
|
|
1415
1891
|
*/
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1892
|
+
unwrapSchema(schema) {
|
|
1893
|
+
let current = schema;
|
|
1894
|
+
let iterations = 0;
|
|
1895
|
+
const maxIterations = 20;
|
|
1896
|
+
while (iterations < maxIterations) {
|
|
1897
|
+
const typeName = getTypeName(current);
|
|
1898
|
+
const wrapperTypes = [
|
|
1899
|
+
"optional",
|
|
1900
|
+
"nullable",
|
|
1901
|
+
"default",
|
|
1902
|
+
"catch",
|
|
1903
|
+
"branded",
|
|
1904
|
+
"readonly",
|
|
1905
|
+
"pipeline",
|
|
1906
|
+
"ZodOptional",
|
|
1907
|
+
"ZodNullable",
|
|
1908
|
+
"ZodDefault",
|
|
1909
|
+
"ZodCatch",
|
|
1910
|
+
"ZodBranded",
|
|
1911
|
+
"ZodReadonly",
|
|
1912
|
+
"ZodPipeline"
|
|
1913
|
+
];
|
|
1914
|
+
if (typeName && wrapperTypes.includes(typeName)) {
|
|
1915
|
+
const def = getDef(current);
|
|
1916
|
+
const inner = def?.innerType ?? def?.in ?? def?.type;
|
|
1917
|
+
if (!inner || inner === current) break;
|
|
1918
|
+
current = inner;
|
|
1919
|
+
iterations++;
|
|
1920
|
+
continue;
|
|
1921
|
+
}
|
|
1922
|
+
break;
|
|
1923
|
+
}
|
|
1924
|
+
return current;
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Get the primitive type hint from an unwrapped schema.
|
|
1928
|
+
*/
|
|
1929
|
+
getBaseType(schema) {
|
|
1930
|
+
const unwrapped = this.unwrapSchema(schema);
|
|
1931
|
+
const typeName = getTypeName(unwrapped);
|
|
1932
|
+
switch (typeName) {
|
|
1933
|
+
// Primitive types
|
|
1934
|
+
case "string":
|
|
1935
|
+
case "ZodString":
|
|
1936
|
+
return "string";
|
|
1937
|
+
case "number":
|
|
1938
|
+
case "ZodNumber":
|
|
1939
|
+
case "bigint":
|
|
1940
|
+
case "ZodBigInt":
|
|
1941
|
+
return "number";
|
|
1942
|
+
case "boolean":
|
|
1943
|
+
case "ZodBoolean":
|
|
1944
|
+
return "boolean";
|
|
1945
|
+
// Literal types - check the literal value type
|
|
1946
|
+
case "literal":
|
|
1947
|
+
case "ZodLiteral": {
|
|
1948
|
+
const def = getDef(unwrapped);
|
|
1949
|
+
const values = def?.values;
|
|
1950
|
+
const value = values?.[0] ?? def?.value;
|
|
1951
|
+
if (typeof value === "string") return "string";
|
|
1952
|
+
if (typeof value === "number" || typeof value === "bigint")
|
|
1953
|
+
return "number";
|
|
1954
|
+
if (typeof value === "boolean") return "boolean";
|
|
1955
|
+
return "unknown";
|
|
1956
|
+
}
|
|
1957
|
+
// Enum - always string keys
|
|
1958
|
+
case "enum":
|
|
1959
|
+
case "ZodEnum":
|
|
1960
|
+
case "nativeEnum":
|
|
1961
|
+
case "ZodNativeEnum":
|
|
1962
|
+
return "string";
|
|
1963
|
+
// Union - return 'unknown' to let auto-coercion decide
|
|
1964
|
+
// Since multiple types are valid, we can't definitively say what the LLM intended
|
|
1965
|
+
// Auto-coercion will handle common cases (numbers, booleans) appropriately
|
|
1966
|
+
case "union":
|
|
1967
|
+
case "ZodUnion":
|
|
1968
|
+
return "unknown";
|
|
1969
|
+
// Discriminated union - complex, return unknown
|
|
1970
|
+
case "discriminatedUnion":
|
|
1971
|
+
case "ZodDiscriminatedUnion":
|
|
1972
|
+
return "unknown";
|
|
1973
|
+
// Intersection - check both sides
|
|
1974
|
+
case "intersection":
|
|
1975
|
+
case "ZodIntersection": {
|
|
1976
|
+
const def = getDef(unwrapped);
|
|
1977
|
+
const left = def?.left;
|
|
1978
|
+
const right = def?.right;
|
|
1979
|
+
if (!left || !right) return "unknown";
|
|
1980
|
+
const leftType = this.getBaseType(left);
|
|
1981
|
+
const rightType = this.getBaseType(right);
|
|
1982
|
+
if (leftType === rightType) return leftType;
|
|
1983
|
+
if (leftType === "string" || rightType === "string") return "string";
|
|
1984
|
+
return "unknown";
|
|
1985
|
+
}
|
|
1986
|
+
// Effects/transforms - return unknown to let Zod handle it
|
|
1987
|
+
case "effects":
|
|
1988
|
+
case "ZodEffects":
|
|
1989
|
+
return "unknown";
|
|
1990
|
+
// Lazy - can't resolve without evaluating
|
|
1991
|
+
case "lazy":
|
|
1992
|
+
case "ZodLazy":
|
|
1993
|
+
return "unknown";
|
|
1994
|
+
// Complex types - return unknown
|
|
1995
|
+
case "object":
|
|
1996
|
+
case "ZodObject":
|
|
1997
|
+
case "array":
|
|
1998
|
+
case "ZodArray":
|
|
1999
|
+
case "tuple":
|
|
2000
|
+
case "ZodTuple":
|
|
2001
|
+
case "record":
|
|
2002
|
+
case "ZodRecord":
|
|
2003
|
+
case "map":
|
|
2004
|
+
case "ZodMap":
|
|
2005
|
+
case "set":
|
|
2006
|
+
case "ZodSet":
|
|
2007
|
+
case "function":
|
|
2008
|
+
case "ZodFunction":
|
|
2009
|
+
case "promise":
|
|
2010
|
+
case "ZodPromise":
|
|
2011
|
+
case "date":
|
|
2012
|
+
case "ZodDate":
|
|
2013
|
+
return "unknown";
|
|
2014
|
+
// Unknown/any/never/void/undefined/null
|
|
2015
|
+
case "unknown":
|
|
2016
|
+
case "ZodUnknown":
|
|
2017
|
+
case "any":
|
|
2018
|
+
case "ZodAny":
|
|
2019
|
+
case "never":
|
|
2020
|
+
case "ZodNever":
|
|
2021
|
+
case "void":
|
|
2022
|
+
case "ZodVoid":
|
|
2023
|
+
case "undefined":
|
|
2024
|
+
case "ZodUndefined":
|
|
2025
|
+
case "null":
|
|
2026
|
+
case "ZodNull":
|
|
2027
|
+
return "unknown";
|
|
2028
|
+
default:
|
|
2029
|
+
return "unknown";
|
|
1425
2030
|
}
|
|
1426
|
-
return parts.join("\n");
|
|
1427
2031
|
}
|
|
1428
2032
|
};
|
|
1429
2033
|
}
|
|
1430
2034
|
});
|
|
1431
2035
|
|
|
1432
|
-
// src/gadgets/
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
/**
|
|
1451
|
-
* Creates a promise that rejects with a TimeoutException after the specified timeout.
|
|
1452
|
-
*/
|
|
1453
|
-
createTimeoutPromise(gadgetName, timeoutMs) {
|
|
1454
|
-
return new Promise((_, reject) => {
|
|
1455
|
-
setTimeout(() => {
|
|
1456
|
-
reject(new TimeoutException(gadgetName, timeoutMs));
|
|
1457
|
-
}, timeoutMs);
|
|
1458
|
-
});
|
|
1459
|
-
}
|
|
1460
|
-
// Execute a gadget call asynchronously
|
|
1461
|
-
async execute(call) {
|
|
1462
|
-
const startTime = Date.now();
|
|
1463
|
-
this.logger.debug("Executing gadget", {
|
|
1464
|
-
gadgetName: call.gadgetName,
|
|
1465
|
-
invocationId: call.invocationId,
|
|
1466
|
-
parameters: call.parameters
|
|
1467
|
-
});
|
|
1468
|
-
const rawParameters = call.parameters ?? {};
|
|
1469
|
-
let validatedParameters = rawParameters;
|
|
1470
|
-
try {
|
|
1471
|
-
const gadget = this.registry.get(call.gadgetName);
|
|
1472
|
-
if (!gadget) {
|
|
1473
|
-
this.logger.error("Gadget not found", { gadgetName: call.gadgetName });
|
|
1474
|
-
const availableGadgets = this.registry.getNames();
|
|
1475
|
-
return {
|
|
1476
|
-
gadgetName: call.gadgetName,
|
|
1477
|
-
invocationId: call.invocationId,
|
|
1478
|
-
parameters: call.parameters ?? {},
|
|
1479
|
-
error: this.errorFormatter.formatRegistryError(call.gadgetName, availableGadgets),
|
|
1480
|
-
executionTimeMs: Date.now() - startTime
|
|
1481
|
-
};
|
|
1482
|
-
}
|
|
1483
|
-
if (call.parseError || !call.parameters) {
|
|
1484
|
-
this.logger.error("Gadget parameter parse error", {
|
|
1485
|
-
gadgetName: call.gadgetName,
|
|
1486
|
-
parseError: call.parseError,
|
|
1487
|
-
rawParameters: call.parametersRaw
|
|
1488
|
-
});
|
|
1489
|
-
const parseErrorMessage = call.parseError ?? "Failed to parse parameters";
|
|
1490
|
-
return {
|
|
1491
|
-
gadgetName: call.gadgetName,
|
|
1492
|
-
invocationId: call.invocationId,
|
|
1493
|
-
parameters: {},
|
|
1494
|
-
error: this.errorFormatter.formatParseError(call.gadgetName, parseErrorMessage, gadget),
|
|
1495
|
-
executionTimeMs: Date.now() - startTime
|
|
1496
|
-
};
|
|
1497
|
-
}
|
|
1498
|
-
if (gadget.parameterSchema) {
|
|
1499
|
-
const validationResult = gadget.parameterSchema.safeParse(rawParameters);
|
|
1500
|
-
if (!validationResult.success) {
|
|
1501
|
-
const validationError = this.errorFormatter.formatValidationError(
|
|
1502
|
-
call.gadgetName,
|
|
1503
|
-
validationResult.error,
|
|
1504
|
-
gadget
|
|
1505
|
-
);
|
|
1506
|
-
this.logger.error("Gadget parameter validation failed", {
|
|
1507
|
-
gadgetName: call.gadgetName,
|
|
1508
|
-
issueCount: validationResult.error.issues.length
|
|
1509
|
-
});
|
|
1510
|
-
return {
|
|
1511
|
-
gadgetName: call.gadgetName,
|
|
1512
|
-
invocationId: call.invocationId,
|
|
1513
|
-
parameters: rawParameters,
|
|
1514
|
-
error: validationError,
|
|
1515
|
-
executionTimeMs: Date.now() - startTime
|
|
1516
|
-
};
|
|
1517
|
-
}
|
|
1518
|
-
validatedParameters = validationResult.data;
|
|
1519
|
-
}
|
|
1520
|
-
const timeoutMs = gadget.timeoutMs ?? this.defaultGadgetTimeoutMs;
|
|
1521
|
-
let result;
|
|
1522
|
-
if (timeoutMs && timeoutMs > 0) {
|
|
1523
|
-
this.logger.debug("Executing gadget with timeout", {
|
|
1524
|
-
gadgetName: call.gadgetName,
|
|
1525
|
-
timeoutMs
|
|
1526
|
-
});
|
|
1527
|
-
result = await Promise.race([
|
|
1528
|
-
Promise.resolve(gadget.execute(validatedParameters)),
|
|
1529
|
-
this.createTimeoutPromise(call.gadgetName, timeoutMs)
|
|
1530
|
-
]);
|
|
1531
|
-
} else {
|
|
1532
|
-
result = await Promise.resolve(gadget.execute(validatedParameters));
|
|
1533
|
-
}
|
|
1534
|
-
const executionTimeMs = Date.now() - startTime;
|
|
1535
|
-
this.logger.info("Gadget executed successfully", {
|
|
1536
|
-
gadgetName: call.gadgetName,
|
|
1537
|
-
invocationId: call.invocationId,
|
|
1538
|
-
executionTimeMs
|
|
1539
|
-
});
|
|
1540
|
-
this.logger.debug("Gadget result", {
|
|
1541
|
-
gadgetName: call.gadgetName,
|
|
1542
|
-
invocationId: call.invocationId,
|
|
1543
|
-
parameters: validatedParameters,
|
|
1544
|
-
result,
|
|
1545
|
-
executionTimeMs
|
|
1546
|
-
});
|
|
1547
|
-
return {
|
|
1548
|
-
gadgetName: call.gadgetName,
|
|
1549
|
-
invocationId: call.invocationId,
|
|
1550
|
-
parameters: validatedParameters,
|
|
1551
|
-
result,
|
|
1552
|
-
executionTimeMs
|
|
1553
|
-
};
|
|
1554
|
-
} catch (error) {
|
|
1555
|
-
if (error instanceof BreakLoopException) {
|
|
1556
|
-
this.logger.info("Gadget requested loop termination", {
|
|
1557
|
-
gadgetName: call.gadgetName,
|
|
1558
|
-
message: error.message
|
|
1559
|
-
});
|
|
1560
|
-
return {
|
|
1561
|
-
gadgetName: call.gadgetName,
|
|
1562
|
-
invocationId: call.invocationId,
|
|
1563
|
-
parameters: validatedParameters,
|
|
1564
|
-
result: error.message,
|
|
1565
|
-
breaksLoop: true,
|
|
1566
|
-
executionTimeMs: Date.now() - startTime
|
|
1567
|
-
};
|
|
1568
|
-
}
|
|
1569
|
-
if (error instanceof TimeoutException) {
|
|
1570
|
-
this.logger.error("Gadget execution timed out", {
|
|
1571
|
-
gadgetName: call.gadgetName,
|
|
1572
|
-
timeoutMs: error.timeoutMs,
|
|
1573
|
-
executionTimeMs: Date.now() - startTime
|
|
1574
|
-
});
|
|
1575
|
-
return {
|
|
1576
|
-
gadgetName: call.gadgetName,
|
|
1577
|
-
invocationId: call.invocationId,
|
|
1578
|
-
parameters: validatedParameters,
|
|
1579
|
-
error: error.message,
|
|
1580
|
-
executionTimeMs: Date.now() - startTime
|
|
1581
|
-
};
|
|
1582
|
-
}
|
|
1583
|
-
if (error instanceof HumanInputException) {
|
|
1584
|
-
this.logger.info("Gadget requested human input", {
|
|
1585
|
-
gadgetName: call.gadgetName,
|
|
1586
|
-
question: error.question
|
|
1587
|
-
});
|
|
1588
|
-
if (this.onHumanInputRequired) {
|
|
1589
|
-
try {
|
|
1590
|
-
const answer = await this.onHumanInputRequired(error.question);
|
|
1591
|
-
this.logger.debug("Human input received", {
|
|
1592
|
-
gadgetName: call.gadgetName,
|
|
1593
|
-
answerLength: answer.length
|
|
1594
|
-
});
|
|
1595
|
-
return {
|
|
1596
|
-
gadgetName: call.gadgetName,
|
|
1597
|
-
invocationId: call.invocationId,
|
|
1598
|
-
parameters: validatedParameters,
|
|
1599
|
-
result: answer,
|
|
1600
|
-
executionTimeMs: Date.now() - startTime
|
|
1601
|
-
};
|
|
1602
|
-
} catch (inputError) {
|
|
1603
|
-
this.logger.error("Human input callback error", {
|
|
1604
|
-
gadgetName: call.gadgetName,
|
|
1605
|
-
error: inputError instanceof Error ? inputError.message : String(inputError)
|
|
1606
|
-
});
|
|
1607
|
-
return {
|
|
1608
|
-
gadgetName: call.gadgetName,
|
|
1609
|
-
invocationId: call.invocationId,
|
|
1610
|
-
parameters: validatedParameters,
|
|
1611
|
-
error: inputError instanceof Error ? inputError.message : String(inputError),
|
|
1612
|
-
executionTimeMs: Date.now() - startTime
|
|
1613
|
-
};
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
this.logger.warn("Human input required but no callback provided", {
|
|
1617
|
-
gadgetName: call.gadgetName
|
|
1618
|
-
});
|
|
1619
|
-
return {
|
|
1620
|
-
gadgetName: call.gadgetName,
|
|
1621
|
-
invocationId: call.invocationId,
|
|
1622
|
-
parameters: validatedParameters,
|
|
1623
|
-
error: "Human input required but not available (stdin is not interactive)",
|
|
1624
|
-
executionTimeMs: Date.now() - startTime
|
|
1625
|
-
};
|
|
1626
|
-
}
|
|
1627
|
-
const executionTimeMs = Date.now() - startTime;
|
|
1628
|
-
this.logger.error("Gadget execution failed", {
|
|
1629
|
-
gadgetName: call.gadgetName,
|
|
1630
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1631
|
-
executionTimeMs
|
|
1632
|
-
});
|
|
1633
|
-
return {
|
|
1634
|
-
gadgetName: call.gadgetName,
|
|
1635
|
-
invocationId: call.invocationId,
|
|
1636
|
-
parameters: validatedParameters,
|
|
1637
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1638
|
-
executionTimeMs
|
|
1639
|
-
};
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
// Execute multiple gadget calls in parallel
|
|
1643
|
-
async executeAll(calls) {
|
|
1644
|
-
return Promise.all(calls.map((call) => this.execute(call)));
|
|
1645
|
-
}
|
|
1646
|
-
};
|
|
1647
|
-
}
|
|
1648
|
-
});
|
|
1649
|
-
|
|
1650
|
-
// src/gadgets/block-params.ts
|
|
1651
|
-
function parseBlockParams(content, options) {
|
|
1652
|
-
const argPrefix = options?.argPrefix ?? GADGET_ARG_PREFIX;
|
|
1653
|
-
const result = {};
|
|
1654
|
-
const seenPointers = /* @__PURE__ */ new Set();
|
|
1655
|
-
const parts = content.split(argPrefix);
|
|
1656
|
-
for (let i = 1; i < parts.length; i++) {
|
|
1657
|
-
const part = parts[i];
|
|
1658
|
-
const newlineIndex = part.indexOf("\n");
|
|
1659
|
-
if (newlineIndex === -1) {
|
|
1660
|
-
const pointer2 = part.trim();
|
|
1661
|
-
if (pointer2) {
|
|
1662
|
-
if (seenPointers.has(pointer2)) {
|
|
1663
|
-
throw new Error(`Duplicate pointer: ${pointer2}`);
|
|
1664
|
-
}
|
|
1665
|
-
seenPointers.add(pointer2);
|
|
1666
|
-
setByPointer(result, pointer2, "");
|
|
2036
|
+
// src/gadgets/block-params.ts
|
|
2037
|
+
function parseBlockParams(content, options) {
|
|
2038
|
+
const argPrefix = options?.argPrefix ?? GADGET_ARG_PREFIX;
|
|
2039
|
+
const result = {};
|
|
2040
|
+
const seenPointers = /* @__PURE__ */ new Set();
|
|
2041
|
+
const introspector = options?.schema ? new SchemaIntrospector(options.schema) : void 0;
|
|
2042
|
+
const parts = content.split(argPrefix);
|
|
2043
|
+
for (let i = 1; i < parts.length; i++) {
|
|
2044
|
+
const part = parts[i];
|
|
2045
|
+
const newlineIndex = part.indexOf("\n");
|
|
2046
|
+
if (newlineIndex === -1) {
|
|
2047
|
+
const pointer2 = part.trim();
|
|
2048
|
+
if (pointer2) {
|
|
2049
|
+
if (seenPointers.has(pointer2)) {
|
|
2050
|
+
throw new Error(`Duplicate pointer: ${pointer2}`);
|
|
2051
|
+
}
|
|
2052
|
+
seenPointers.add(pointer2);
|
|
2053
|
+
setByPointer(result, pointer2, "", introspector);
|
|
1667
2054
|
}
|
|
1668
2055
|
continue;
|
|
1669
2056
|
}
|
|
@@ -1679,15 +2066,30 @@ function parseBlockParams(content, options) {
|
|
|
1679
2066
|
throw new Error(`Duplicate pointer: ${pointer}`);
|
|
1680
2067
|
}
|
|
1681
2068
|
seenPointers.add(pointer);
|
|
1682
|
-
setByPointer(result, pointer, value);
|
|
2069
|
+
setByPointer(result, pointer, value, introspector);
|
|
1683
2070
|
}
|
|
1684
2071
|
return result;
|
|
1685
2072
|
}
|
|
1686
|
-
function coerceValue(value) {
|
|
2073
|
+
function coerceValue(value, expectedType) {
|
|
1687
2074
|
if (value.includes("\n")) {
|
|
1688
2075
|
return value;
|
|
1689
2076
|
}
|
|
1690
2077
|
const trimmed = value.trim();
|
|
2078
|
+
if (expectedType === "string") {
|
|
2079
|
+
return value;
|
|
2080
|
+
}
|
|
2081
|
+
if (expectedType === "boolean") {
|
|
2082
|
+
if (trimmed === "true") return true;
|
|
2083
|
+
if (trimmed === "false") return false;
|
|
2084
|
+
return value;
|
|
2085
|
+
}
|
|
2086
|
+
if (expectedType === "number") {
|
|
2087
|
+
const num = Number(trimmed);
|
|
2088
|
+
if (!isNaN(num) && isFinite(num) && trimmed !== "") {
|
|
2089
|
+
return num;
|
|
2090
|
+
}
|
|
2091
|
+
return value;
|
|
2092
|
+
}
|
|
1691
2093
|
if (trimmed === "true") return true;
|
|
1692
2094
|
if (trimmed === "false") return false;
|
|
1693
2095
|
if (trimmed !== "" && /^-?\d+(\.\d+)?$/.test(trimmed)) {
|
|
@@ -1698,7 +2100,7 @@ function coerceValue(value) {
|
|
|
1698
2100
|
}
|
|
1699
2101
|
return value;
|
|
1700
2102
|
}
|
|
1701
|
-
function setByPointer(obj, pointer, value) {
|
|
2103
|
+
function setByPointer(obj, pointer, value, introspector) {
|
|
1702
2104
|
const segments = pointer.split("/");
|
|
1703
2105
|
let current = obj;
|
|
1704
2106
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
@@ -1726,7 +2128,8 @@ function setByPointer(obj, pointer, value) {
|
|
|
1726
2128
|
}
|
|
1727
2129
|
}
|
|
1728
2130
|
const lastSegment = segments[segments.length - 1];
|
|
1729
|
-
const
|
|
2131
|
+
const expectedType = introspector?.getTypeAtPath(pointer);
|
|
2132
|
+
const coercedValue = coerceValue(value, expectedType);
|
|
1730
2133
|
if (Array.isArray(current)) {
|
|
1731
2134
|
const index = parseInt(lastSegment, 10);
|
|
1732
2135
|
if (isNaN(index) || index < 0) {
|
|
@@ -1744,6 +2147,7 @@ var init_block_params = __esm({
|
|
|
1744
2147
|
"src/gadgets/block-params.ts"() {
|
|
1745
2148
|
"use strict";
|
|
1746
2149
|
init_constants();
|
|
2150
|
+
init_schema_introspector();
|
|
1747
2151
|
}
|
|
1748
2152
|
});
|
|
1749
2153
|
|
|
@@ -1861,64 +2265,424 @@ var init_parser = __esm({
|
|
|
1861
2265
|
break;
|
|
1862
2266
|
}
|
|
1863
2267
|
}
|
|
1864
|
-
const parametersRaw = this.buffer.substring(contentStartIndex, partEndIndex).trim();
|
|
1865
|
-
const { parameters, parseError } = this.parseParameters(parametersRaw);
|
|
1866
|
-
yield {
|
|
1867
|
-
type: "gadget_call",
|
|
1868
|
-
call: {
|
|
1869
|
-
gadgetName: actualGadgetName,
|
|
1870
|
-
invocationId,
|
|
1871
|
-
parametersRaw,
|
|
1872
|
-
parameters,
|
|
1873
|
-
parseError
|
|
2268
|
+
const parametersRaw = this.buffer.substring(contentStartIndex, partEndIndex).trim();
|
|
2269
|
+
const { parameters, parseError } = this.parseParameters(parametersRaw);
|
|
2270
|
+
yield {
|
|
2271
|
+
type: "gadget_call",
|
|
2272
|
+
call: {
|
|
2273
|
+
gadgetName: actualGadgetName,
|
|
2274
|
+
invocationId,
|
|
2275
|
+
parametersRaw,
|
|
2276
|
+
parameters,
|
|
2277
|
+
parseError
|
|
2278
|
+
}
|
|
2279
|
+
};
|
|
2280
|
+
startIndex = partEndIndex + endMarkerLength;
|
|
2281
|
+
this.lastReportedTextLength = startIndex;
|
|
2282
|
+
}
|
|
2283
|
+
if (startIndex > 0) {
|
|
2284
|
+
this.buffer = this.buffer.substring(startIndex);
|
|
2285
|
+
this.lastReportedTextLength = 0;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
// Finalize parsing and return remaining text or incomplete gadgets
|
|
2289
|
+
*finalize() {
|
|
2290
|
+
const startIndex = this.buffer.indexOf(this.startPrefix, this.lastReportedTextLength);
|
|
2291
|
+
if (startIndex !== -1) {
|
|
2292
|
+
const textBefore = this.takeTextUntil(startIndex);
|
|
2293
|
+
if (textBefore !== void 0) {
|
|
2294
|
+
yield { type: "text", content: textBefore };
|
|
2295
|
+
}
|
|
2296
|
+
const metadataStartIndex = startIndex + this.startPrefix.length;
|
|
2297
|
+
const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
|
|
2298
|
+
if (metadataEndIndex !== -1) {
|
|
2299
|
+
const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
|
|
2300
|
+
const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);
|
|
2301
|
+
const contentStartIndex = metadataEndIndex + 1;
|
|
2302
|
+
const parametersRaw = this.buffer.substring(contentStartIndex).trim();
|
|
2303
|
+
const { parameters, parseError } = this.parseParameters(parametersRaw);
|
|
2304
|
+
yield {
|
|
2305
|
+
type: "gadget_call",
|
|
2306
|
+
call: {
|
|
2307
|
+
gadgetName: actualGadgetName,
|
|
2308
|
+
invocationId,
|
|
2309
|
+
parametersRaw,
|
|
2310
|
+
parameters,
|
|
2311
|
+
parseError
|
|
2312
|
+
}
|
|
2313
|
+
};
|
|
2314
|
+
return;
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
const remainingText = this.takeTextUntil(this.buffer.length);
|
|
2318
|
+
if (remainingText !== void 0) {
|
|
2319
|
+
yield { type: "text", content: remainingText };
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
// Reset parser state (note: global invocation counter is NOT reset to ensure unique IDs)
|
|
2323
|
+
reset() {
|
|
2324
|
+
this.buffer = "";
|
|
2325
|
+
this.lastReportedTextLength = 0;
|
|
2326
|
+
}
|
|
2327
|
+
};
|
|
2328
|
+
}
|
|
2329
|
+
});
|
|
2330
|
+
|
|
2331
|
+
// src/gadgets/error-formatter.ts
|
|
2332
|
+
var GadgetErrorFormatter;
|
|
2333
|
+
var init_error_formatter = __esm({
|
|
2334
|
+
"src/gadgets/error-formatter.ts"() {
|
|
2335
|
+
"use strict";
|
|
2336
|
+
init_constants();
|
|
2337
|
+
GadgetErrorFormatter = class {
|
|
2338
|
+
argPrefix;
|
|
2339
|
+
startPrefix;
|
|
2340
|
+
endPrefix;
|
|
2341
|
+
constructor(options = {}) {
|
|
2342
|
+
this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
|
|
2343
|
+
this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
|
|
2344
|
+
this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
|
|
2345
|
+
}
|
|
2346
|
+
/**
|
|
2347
|
+
* Format a Zod validation error with full gadget instructions.
|
|
2348
|
+
*
|
|
2349
|
+
* @param gadgetName - Name of the gadget that was called
|
|
2350
|
+
* @param zodError - The Zod validation error
|
|
2351
|
+
* @param gadget - The gadget instance (for generating instructions)
|
|
2352
|
+
* @returns Formatted error message with usage instructions
|
|
2353
|
+
*/
|
|
2354
|
+
formatValidationError(gadgetName, zodError, gadget) {
|
|
2355
|
+
const parts = [];
|
|
2356
|
+
parts.push(`Error: Invalid parameters for '${gadgetName}':`);
|
|
2357
|
+
for (const issue of zodError.issues) {
|
|
2358
|
+
const path = issue.path.join(".") || "root";
|
|
2359
|
+
parts.push(` - ${path}: ${issue.message}`);
|
|
2360
|
+
}
|
|
2361
|
+
parts.push("");
|
|
2362
|
+
parts.push("Gadget Usage:");
|
|
2363
|
+
parts.push(gadget.getInstruction(this.argPrefix));
|
|
2364
|
+
return parts.join("\n");
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Format a parse error with block format reference.
|
|
2368
|
+
*
|
|
2369
|
+
* @param gadgetName - Name of the gadget that was called
|
|
2370
|
+
* @param parseError - The parse error message
|
|
2371
|
+
* @param gadget - The gadget instance if found (for generating instructions)
|
|
2372
|
+
* @returns Formatted error message with format reference
|
|
2373
|
+
*/
|
|
2374
|
+
formatParseError(gadgetName, parseError, gadget) {
|
|
2375
|
+
const parts = [];
|
|
2376
|
+
parts.push(`Error: Failed to parse parameters for '${gadgetName}':`);
|
|
2377
|
+
parts.push(` ${parseError}`);
|
|
2378
|
+
if (gadget) {
|
|
2379
|
+
parts.push("");
|
|
2380
|
+
parts.push("Gadget Usage:");
|
|
2381
|
+
parts.push(gadget.getInstruction(this.argPrefix));
|
|
2382
|
+
}
|
|
2383
|
+
parts.push("");
|
|
2384
|
+
parts.push("Block Format Reference:");
|
|
2385
|
+
parts.push(` ${this.startPrefix}${gadgetName}`);
|
|
2386
|
+
parts.push(` ${this.argPrefix}parameterName`);
|
|
2387
|
+
parts.push(" parameter value here");
|
|
2388
|
+
parts.push(` ${this.endPrefix}`);
|
|
2389
|
+
return parts.join("\n");
|
|
2390
|
+
}
|
|
2391
|
+
/**
|
|
2392
|
+
* Format a registry error (gadget not found) with available gadgets list.
|
|
2393
|
+
*
|
|
2394
|
+
* @param gadgetName - Name of the gadget that was not found
|
|
2395
|
+
* @param availableGadgets - List of available gadget names
|
|
2396
|
+
* @returns Formatted error message with available gadgets
|
|
2397
|
+
*/
|
|
2398
|
+
formatRegistryError(gadgetName, availableGadgets) {
|
|
2399
|
+
const parts = [];
|
|
2400
|
+
parts.push(`Error: Gadget '${gadgetName}' not found.`);
|
|
2401
|
+
if (availableGadgets.length > 0) {
|
|
2402
|
+
parts.push("");
|
|
2403
|
+
parts.push(`Available gadgets: ${availableGadgets.join(", ")}`);
|
|
2404
|
+
} else {
|
|
2405
|
+
parts.push("");
|
|
2406
|
+
parts.push("No gadgets are currently registered.");
|
|
2407
|
+
}
|
|
2408
|
+
return parts.join("\n");
|
|
2409
|
+
}
|
|
2410
|
+
};
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
2413
|
+
|
|
2414
|
+
// src/gadgets/executor.ts
|
|
2415
|
+
var GadgetExecutor;
|
|
2416
|
+
var init_executor = __esm({
|
|
2417
|
+
"src/gadgets/executor.ts"() {
|
|
2418
|
+
"use strict";
|
|
2419
|
+
init_constants();
|
|
2420
|
+
init_logger();
|
|
2421
|
+
init_block_params();
|
|
2422
|
+
init_error_formatter();
|
|
2423
|
+
init_exceptions();
|
|
2424
|
+
init_parser();
|
|
2425
|
+
GadgetExecutor = class {
|
|
2426
|
+
constructor(registry, onHumanInputRequired, logger, defaultGadgetTimeoutMs, errorFormatterOptions) {
|
|
2427
|
+
this.registry = registry;
|
|
2428
|
+
this.onHumanInputRequired = onHumanInputRequired;
|
|
2429
|
+
this.defaultGadgetTimeoutMs = defaultGadgetTimeoutMs;
|
|
2430
|
+
this.logger = logger ?? createLogger({ name: "llmist:executor" });
|
|
2431
|
+
this.errorFormatter = new GadgetErrorFormatter(errorFormatterOptions);
|
|
2432
|
+
this.argPrefix = errorFormatterOptions?.argPrefix ?? GADGET_ARG_PREFIX;
|
|
2433
|
+
}
|
|
2434
|
+
logger;
|
|
2435
|
+
errorFormatter;
|
|
2436
|
+
argPrefix;
|
|
2437
|
+
/**
|
|
2438
|
+
* Creates a promise that rejects with a TimeoutException after the specified timeout.
|
|
2439
|
+
*/
|
|
2440
|
+
createTimeoutPromise(gadgetName, timeoutMs) {
|
|
2441
|
+
return new Promise((_, reject) => {
|
|
2442
|
+
setTimeout(() => {
|
|
2443
|
+
reject(new TimeoutException(gadgetName, timeoutMs));
|
|
2444
|
+
}, timeoutMs);
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
// Execute a gadget call asynchronously
|
|
2448
|
+
async execute(call) {
|
|
2449
|
+
const startTime = Date.now();
|
|
2450
|
+
this.logger.debug("Executing gadget", {
|
|
2451
|
+
gadgetName: call.gadgetName,
|
|
2452
|
+
invocationId: call.invocationId,
|
|
2453
|
+
parameters: call.parameters
|
|
2454
|
+
});
|
|
2455
|
+
const rawParameters = call.parameters ?? {};
|
|
2456
|
+
let validatedParameters = rawParameters;
|
|
2457
|
+
try {
|
|
2458
|
+
const gadget = this.registry.get(call.gadgetName);
|
|
2459
|
+
if (!gadget) {
|
|
2460
|
+
this.logger.error("Gadget not found", { gadgetName: call.gadgetName });
|
|
2461
|
+
const availableGadgets = this.registry.getNames();
|
|
2462
|
+
return {
|
|
2463
|
+
gadgetName: call.gadgetName,
|
|
2464
|
+
invocationId: call.invocationId,
|
|
2465
|
+
parameters: call.parameters ?? {},
|
|
2466
|
+
error: this.errorFormatter.formatRegistryError(call.gadgetName, availableGadgets),
|
|
2467
|
+
executionTimeMs: Date.now() - startTime
|
|
2468
|
+
};
|
|
2469
|
+
}
|
|
2470
|
+
if (call.parseError || !call.parameters) {
|
|
2471
|
+
this.logger.error("Gadget parameter parse error", {
|
|
2472
|
+
gadgetName: call.gadgetName,
|
|
2473
|
+
parseError: call.parseError,
|
|
2474
|
+
rawParameters: call.parametersRaw
|
|
2475
|
+
});
|
|
2476
|
+
const parseErrorMessage = call.parseError ?? "Failed to parse parameters";
|
|
2477
|
+
return {
|
|
2478
|
+
gadgetName: call.gadgetName,
|
|
2479
|
+
invocationId: call.invocationId,
|
|
2480
|
+
parameters: {},
|
|
2481
|
+
error: this.errorFormatter.formatParseError(call.gadgetName, parseErrorMessage, gadget),
|
|
2482
|
+
executionTimeMs: Date.now() - startTime
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
let schemaAwareParameters = rawParameters;
|
|
2486
|
+
const hasBlockFormat = call.parametersRaw?.includes(this.argPrefix);
|
|
2487
|
+
if (gadget.parameterSchema && hasBlockFormat) {
|
|
2488
|
+
try {
|
|
2489
|
+
const cleanedRaw = stripMarkdownFences(call.parametersRaw);
|
|
2490
|
+
const initialParse = parseBlockParams(cleanedRaw, { argPrefix: this.argPrefix });
|
|
2491
|
+
const parametersWereModified = !this.deepEquals(rawParameters, initialParse);
|
|
2492
|
+
if (parametersWereModified) {
|
|
2493
|
+
this.logger.debug("Parameters modified by interceptor, skipping re-parse", {
|
|
2494
|
+
gadgetName: call.gadgetName
|
|
2495
|
+
});
|
|
2496
|
+
schemaAwareParameters = rawParameters;
|
|
2497
|
+
} else {
|
|
2498
|
+
schemaAwareParameters = parseBlockParams(cleanedRaw, {
|
|
2499
|
+
argPrefix: this.argPrefix,
|
|
2500
|
+
schema: gadget.parameterSchema
|
|
2501
|
+
});
|
|
2502
|
+
this.logger.debug("Re-parsed parameters with schema", {
|
|
2503
|
+
gadgetName: call.gadgetName,
|
|
2504
|
+
original: rawParameters,
|
|
2505
|
+
schemaAware: schemaAwareParameters
|
|
2506
|
+
});
|
|
2507
|
+
}
|
|
2508
|
+
} catch (error) {
|
|
2509
|
+
this.logger.warn("Schema-aware re-parsing failed, using original parameters", {
|
|
2510
|
+
gadgetName: call.gadgetName,
|
|
2511
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2512
|
+
});
|
|
2513
|
+
schemaAwareParameters = rawParameters;
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
if (gadget.parameterSchema) {
|
|
2517
|
+
const validationResult = gadget.parameterSchema.safeParse(schemaAwareParameters);
|
|
2518
|
+
if (!validationResult.success) {
|
|
2519
|
+
const validationError = this.errorFormatter.formatValidationError(
|
|
2520
|
+
call.gadgetName,
|
|
2521
|
+
validationResult.error,
|
|
2522
|
+
gadget
|
|
2523
|
+
);
|
|
2524
|
+
this.logger.error("Gadget parameter validation failed", {
|
|
2525
|
+
gadgetName: call.gadgetName,
|
|
2526
|
+
issueCount: validationResult.error.issues.length
|
|
2527
|
+
});
|
|
2528
|
+
return {
|
|
2529
|
+
gadgetName: call.gadgetName,
|
|
2530
|
+
invocationId: call.invocationId,
|
|
2531
|
+
parameters: schemaAwareParameters,
|
|
2532
|
+
error: validationError,
|
|
2533
|
+
executionTimeMs: Date.now() - startTime
|
|
2534
|
+
};
|
|
1874
2535
|
}
|
|
2536
|
+
validatedParameters = validationResult.data;
|
|
2537
|
+
} else {
|
|
2538
|
+
validatedParameters = schemaAwareParameters;
|
|
2539
|
+
}
|
|
2540
|
+
const timeoutMs = gadget.timeoutMs ?? this.defaultGadgetTimeoutMs;
|
|
2541
|
+
let result;
|
|
2542
|
+
if (timeoutMs && timeoutMs > 0) {
|
|
2543
|
+
this.logger.debug("Executing gadget with timeout", {
|
|
2544
|
+
gadgetName: call.gadgetName,
|
|
2545
|
+
timeoutMs
|
|
2546
|
+
});
|
|
2547
|
+
result = await Promise.race([
|
|
2548
|
+
Promise.resolve(gadget.execute(validatedParameters)),
|
|
2549
|
+
this.createTimeoutPromise(call.gadgetName, timeoutMs)
|
|
2550
|
+
]);
|
|
2551
|
+
} else {
|
|
2552
|
+
result = await Promise.resolve(gadget.execute(validatedParameters));
|
|
2553
|
+
}
|
|
2554
|
+
const executionTimeMs = Date.now() - startTime;
|
|
2555
|
+
this.logger.info("Gadget executed successfully", {
|
|
2556
|
+
gadgetName: call.gadgetName,
|
|
2557
|
+
invocationId: call.invocationId,
|
|
2558
|
+
executionTimeMs
|
|
2559
|
+
});
|
|
2560
|
+
this.logger.debug("Gadget result", {
|
|
2561
|
+
gadgetName: call.gadgetName,
|
|
2562
|
+
invocationId: call.invocationId,
|
|
2563
|
+
parameters: validatedParameters,
|
|
2564
|
+
result,
|
|
2565
|
+
executionTimeMs
|
|
2566
|
+
});
|
|
2567
|
+
return {
|
|
2568
|
+
gadgetName: call.gadgetName,
|
|
2569
|
+
invocationId: call.invocationId,
|
|
2570
|
+
parameters: validatedParameters,
|
|
2571
|
+
result,
|
|
2572
|
+
executionTimeMs
|
|
1875
2573
|
};
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
yield { type: "text", content: textBefore };
|
|
2574
|
+
} catch (error) {
|
|
2575
|
+
if (error instanceof BreakLoopException) {
|
|
2576
|
+
this.logger.info("Gadget requested loop termination", {
|
|
2577
|
+
gadgetName: call.gadgetName,
|
|
2578
|
+
message: error.message
|
|
2579
|
+
});
|
|
2580
|
+
return {
|
|
2581
|
+
gadgetName: call.gadgetName,
|
|
2582
|
+
invocationId: call.invocationId,
|
|
2583
|
+
parameters: validatedParameters,
|
|
2584
|
+
result: error.message,
|
|
2585
|
+
breaksLoop: true,
|
|
2586
|
+
executionTimeMs: Date.now() - startTime
|
|
2587
|
+
};
|
|
1891
2588
|
}
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
2589
|
+
if (error instanceof TimeoutException) {
|
|
2590
|
+
this.logger.error("Gadget execution timed out", {
|
|
2591
|
+
gadgetName: call.gadgetName,
|
|
2592
|
+
timeoutMs: error.timeoutMs,
|
|
2593
|
+
executionTimeMs: Date.now() - startTime
|
|
2594
|
+
});
|
|
2595
|
+
return {
|
|
2596
|
+
gadgetName: call.gadgetName,
|
|
2597
|
+
invocationId: call.invocationId,
|
|
2598
|
+
parameters: validatedParameters,
|
|
2599
|
+
error: error.message,
|
|
2600
|
+
executionTimeMs: Date.now() - startTime
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
if (error instanceof HumanInputException) {
|
|
2604
|
+
this.logger.info("Gadget requested human input", {
|
|
2605
|
+
gadgetName: call.gadgetName,
|
|
2606
|
+
question: error.question
|
|
2607
|
+
});
|
|
2608
|
+
if (this.onHumanInputRequired) {
|
|
2609
|
+
try {
|
|
2610
|
+
const answer = await this.onHumanInputRequired(error.question);
|
|
2611
|
+
this.logger.debug("Human input received", {
|
|
2612
|
+
gadgetName: call.gadgetName,
|
|
2613
|
+
answerLength: answer.length
|
|
2614
|
+
});
|
|
2615
|
+
return {
|
|
2616
|
+
gadgetName: call.gadgetName,
|
|
2617
|
+
invocationId: call.invocationId,
|
|
2618
|
+
parameters: validatedParameters,
|
|
2619
|
+
result: answer,
|
|
2620
|
+
executionTimeMs: Date.now() - startTime
|
|
2621
|
+
};
|
|
2622
|
+
} catch (inputError) {
|
|
2623
|
+
this.logger.error("Human input callback error", {
|
|
2624
|
+
gadgetName: call.gadgetName,
|
|
2625
|
+
error: inputError instanceof Error ? inputError.message : String(inputError)
|
|
2626
|
+
});
|
|
2627
|
+
return {
|
|
2628
|
+
gadgetName: call.gadgetName,
|
|
2629
|
+
invocationId: call.invocationId,
|
|
2630
|
+
parameters: validatedParameters,
|
|
2631
|
+
error: inputError instanceof Error ? inputError.message : String(inputError),
|
|
2632
|
+
executionTimeMs: Date.now() - startTime
|
|
2633
|
+
};
|
|
1908
2634
|
}
|
|
2635
|
+
}
|
|
2636
|
+
this.logger.warn("Human input required but no callback provided", {
|
|
2637
|
+
gadgetName: call.gadgetName
|
|
2638
|
+
});
|
|
2639
|
+
return {
|
|
2640
|
+
gadgetName: call.gadgetName,
|
|
2641
|
+
invocationId: call.invocationId,
|
|
2642
|
+
parameters: validatedParameters,
|
|
2643
|
+
error: "Human input required but not available (stdin is not interactive)",
|
|
2644
|
+
executionTimeMs: Date.now() - startTime
|
|
1909
2645
|
};
|
|
1910
|
-
return;
|
|
1911
2646
|
}
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
2647
|
+
const executionTimeMs = Date.now() - startTime;
|
|
2648
|
+
this.logger.error("Gadget execution failed", {
|
|
2649
|
+
gadgetName: call.gadgetName,
|
|
2650
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2651
|
+
executionTimeMs
|
|
2652
|
+
});
|
|
2653
|
+
return {
|
|
2654
|
+
gadgetName: call.gadgetName,
|
|
2655
|
+
invocationId: call.invocationId,
|
|
2656
|
+
parameters: validatedParameters,
|
|
2657
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2658
|
+
executionTimeMs
|
|
2659
|
+
};
|
|
1916
2660
|
}
|
|
1917
2661
|
}
|
|
1918
|
-
//
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
2662
|
+
// Execute multiple gadget calls in parallel
|
|
2663
|
+
async executeAll(calls) {
|
|
2664
|
+
return Promise.all(calls.map((call) => this.execute(call)));
|
|
2665
|
+
}
|
|
2666
|
+
/**
|
|
2667
|
+
* Deep equality check for objects/arrays.
|
|
2668
|
+
* Used to detect if parameters were modified by an interceptor.
|
|
2669
|
+
*/
|
|
2670
|
+
deepEquals(a, b) {
|
|
2671
|
+
if (a === b) return true;
|
|
2672
|
+
if (a === null || b === null) return a === b;
|
|
2673
|
+
if (typeof a !== typeof b) return false;
|
|
2674
|
+
if (typeof a !== "object") return a === b;
|
|
2675
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
2676
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
2677
|
+
if (a.length !== b.length) return false;
|
|
2678
|
+
return a.every((val, i) => this.deepEquals(val, b[i]));
|
|
2679
|
+
}
|
|
2680
|
+
const aObj = a;
|
|
2681
|
+
const bObj = b;
|
|
2682
|
+
const aKeys = Object.keys(aObj);
|
|
2683
|
+
const bKeys = Object.keys(bObj);
|
|
2684
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
2685
|
+
return aKeys.every((key) => this.deepEquals(aObj[key], bObj[key]));
|
|
1922
2686
|
}
|
|
1923
2687
|
};
|
|
1924
2688
|
}
|
|
@@ -2115,7 +2879,8 @@ var init_stream_processor = __esm({
|
|
|
2115
2879
|
options.registry,
|
|
2116
2880
|
options.onHumanInputRequired,
|
|
2117
2881
|
this.logger.getSubLogger({ name: "executor" }),
|
|
2118
|
-
options.defaultGadgetTimeoutMs
|
|
2882
|
+
options.defaultGadgetTimeoutMs,
|
|
2883
|
+
{ argPrefix: options.gadgetArgPrefix }
|
|
2119
2884
|
);
|
|
2120
2885
|
}
|
|
2121
2886
|
/**
|
|
@@ -4227,6 +4992,7 @@ var init_agent = __esm({
|
|
|
4227
4992
|
init_model_shortcuts();
|
|
4228
4993
|
init_output_viewer();
|
|
4229
4994
|
init_logger();
|
|
4995
|
+
init_manager();
|
|
4230
4996
|
init_gadget_output_store();
|
|
4231
4997
|
init_agent_internal_key();
|
|
4232
4998
|
init_conversation_manager();
|
|
@@ -4257,6 +5023,8 @@ var init_agent = __esm({
|
|
|
4257
5023
|
outputStore;
|
|
4258
5024
|
outputLimitEnabled;
|
|
4259
5025
|
outputLimitCharLimit;
|
|
5026
|
+
// Context compaction
|
|
5027
|
+
compactionManager;
|
|
4260
5028
|
/**
|
|
4261
5029
|
* Creates a new Agent instance.
|
|
4262
5030
|
* @internal This constructor is private. Use LLMist.createAgent() or AgentBuilder instead.
|
|
@@ -4316,6 +5084,14 @@ var init_agent = __esm({
|
|
|
4316
5084
|
if (options.userPrompt) {
|
|
4317
5085
|
this.conversation.addUserMessage(options.userPrompt);
|
|
4318
5086
|
}
|
|
5087
|
+
const compactionEnabled = options.compactionConfig?.enabled ?? true;
|
|
5088
|
+
if (compactionEnabled) {
|
|
5089
|
+
this.compactionManager = new CompactionManager(
|
|
5090
|
+
this.client,
|
|
5091
|
+
this.model,
|
|
5092
|
+
options.compactionConfig
|
|
5093
|
+
);
|
|
5094
|
+
}
|
|
4319
5095
|
}
|
|
4320
5096
|
/**
|
|
4321
5097
|
* Get the gadget registry for this agent.
|
|
@@ -4338,6 +5114,53 @@ var init_agent = __esm({
|
|
|
4338
5114
|
getRegistry() {
|
|
4339
5115
|
return this.registry;
|
|
4340
5116
|
}
|
|
5117
|
+
/**
|
|
5118
|
+
* Manually trigger context compaction.
|
|
5119
|
+
*
|
|
5120
|
+
* Forces compaction regardless of threshold. Useful for:
|
|
5121
|
+
* - Pre-emptive context management before expected long operations
|
|
5122
|
+
* - Testing compaction behavior
|
|
5123
|
+
*
|
|
5124
|
+
* @returns CompactionEvent if compaction was performed, null if not configured or no history
|
|
5125
|
+
*
|
|
5126
|
+
* @example
|
|
5127
|
+
* ```typescript
|
|
5128
|
+
* const agent = await LLMist.createAgent()
|
|
5129
|
+
* .withModel('sonnet')
|
|
5130
|
+
* .withCompaction()
|
|
5131
|
+
* .ask('...');
|
|
5132
|
+
*
|
|
5133
|
+
* // Manually compact before a long operation
|
|
5134
|
+
* const event = await agent.compact();
|
|
5135
|
+
* if (event) {
|
|
5136
|
+
* console.log(`Saved ${event.tokensBefore - event.tokensAfter} tokens`);
|
|
5137
|
+
* }
|
|
5138
|
+
* ```
|
|
5139
|
+
*/
|
|
5140
|
+
async compact() {
|
|
5141
|
+
if (!this.compactionManager) {
|
|
5142
|
+
return null;
|
|
5143
|
+
}
|
|
5144
|
+
return this.compactionManager.compact(this.conversation, -1);
|
|
5145
|
+
}
|
|
5146
|
+
/**
|
|
5147
|
+
* Get compaction statistics.
|
|
5148
|
+
*
|
|
5149
|
+
* @returns CompactionStats if compaction is enabled, null otherwise
|
|
5150
|
+
*
|
|
5151
|
+
* @example
|
|
5152
|
+
* ```typescript
|
|
5153
|
+
* const stats = agent.getCompactionStats();
|
|
5154
|
+
* if (stats) {
|
|
5155
|
+
* console.log(`Total compactions: ${stats.totalCompactions}`);
|
|
5156
|
+
* console.log(`Tokens saved: ${stats.totalTokensSaved}`);
|
|
5157
|
+
* console.log(`Current usage: ${stats.currentUsage.percent.toFixed(1)}%`);
|
|
5158
|
+
* }
|
|
5159
|
+
* ```
|
|
5160
|
+
*/
|
|
5161
|
+
getCompactionStats() {
|
|
5162
|
+
return this.compactionManager?.getStats() ?? null;
|
|
5163
|
+
}
|
|
4341
5164
|
/**
|
|
4342
5165
|
* Run the agent loop.
|
|
4343
5166
|
* Clean, simple orchestration - all complexity is in StreamProcessor.
|
|
@@ -4358,6 +5181,30 @@ var init_agent = __esm({
|
|
|
4358
5181
|
while (currentIteration < this.maxIterations) {
|
|
4359
5182
|
this.logger.debug("Starting iteration", { iteration: currentIteration });
|
|
4360
5183
|
try {
|
|
5184
|
+
if (this.compactionManager) {
|
|
5185
|
+
const compactionEvent = await this.compactionManager.checkAndCompact(
|
|
5186
|
+
this.conversation,
|
|
5187
|
+
currentIteration
|
|
5188
|
+
);
|
|
5189
|
+
if (compactionEvent) {
|
|
5190
|
+
this.logger.info("Context compacted", {
|
|
5191
|
+
strategy: compactionEvent.strategy,
|
|
5192
|
+
tokensBefore: compactionEvent.tokensBefore,
|
|
5193
|
+
tokensAfter: compactionEvent.tokensAfter
|
|
5194
|
+
});
|
|
5195
|
+
yield { type: "compaction", event: compactionEvent };
|
|
5196
|
+
await this.safeObserve(async () => {
|
|
5197
|
+
if (this.hooks.observers?.onCompaction) {
|
|
5198
|
+
await this.hooks.observers.onCompaction({
|
|
5199
|
+
iteration: currentIteration,
|
|
5200
|
+
event: compactionEvent,
|
|
5201
|
+
stats: this.compactionManager.getStats(),
|
|
5202
|
+
logger: this.logger
|
|
5203
|
+
});
|
|
5204
|
+
}
|
|
5205
|
+
});
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
4361
5208
|
let llmOptions = {
|
|
4362
5209
|
model: this.model,
|
|
4363
5210
|
messages: this.conversation.getMessages(),
|
|
@@ -4377,6 +5224,7 @@ var init_agent = __esm({
|
|
|
4377
5224
|
if (this.hooks.controllers?.beforeLLMCall) {
|
|
4378
5225
|
const context = {
|
|
4379
5226
|
iteration: currentIteration,
|
|
5227
|
+
maxIterations: this.maxIterations,
|
|
4380
5228
|
options: llmOptions,
|
|
4381
5229
|
logger: this.logger
|
|
4382
5230
|
};
|
|
@@ -4441,12 +5289,17 @@ var init_agent = __esm({
|
|
|
4441
5289
|
});
|
|
4442
5290
|
let finalMessage = result.finalMessage;
|
|
4443
5291
|
if (this.hooks.controllers?.afterLLMCall) {
|
|
5292
|
+
const gadgetCallCount = result.outputs.filter(
|
|
5293
|
+
(output) => output.type === "gadget_result"
|
|
5294
|
+
).length;
|
|
4444
5295
|
const context = {
|
|
4445
5296
|
iteration: currentIteration,
|
|
5297
|
+
maxIterations: this.maxIterations,
|
|
4446
5298
|
options: llmOptions,
|
|
4447
5299
|
finishReason: result.finishReason,
|
|
4448
5300
|
usage: result.usage,
|
|
4449
5301
|
finalMessage: result.finalMessage,
|
|
5302
|
+
gadgetCallCount,
|
|
4450
5303
|
logger: this.logger
|
|
4451
5304
|
};
|
|
4452
5305
|
const action = await this.hooks.controllers.afterLLMCall(context);
|
|
@@ -4708,6 +5561,7 @@ var init_builder = __esm({
|
|
|
4708
5561
|
defaultGadgetTimeoutMs;
|
|
4709
5562
|
gadgetOutputLimit;
|
|
4710
5563
|
gadgetOutputLimitPercent;
|
|
5564
|
+
compactionConfig;
|
|
4711
5565
|
constructor(client) {
|
|
4712
5566
|
this.client = client;
|
|
4713
5567
|
}
|
|
@@ -5103,6 +5957,57 @@ var init_builder = __esm({
|
|
|
5103
5957
|
this.gadgetOutputLimitPercent = percent;
|
|
5104
5958
|
return this;
|
|
5105
5959
|
}
|
|
5960
|
+
/**
|
|
5961
|
+
* Configure context compaction.
|
|
5962
|
+
*
|
|
5963
|
+
* Context compaction automatically manages conversation history to prevent
|
|
5964
|
+
* context window overflow in long-running agent conversations.
|
|
5965
|
+
*
|
|
5966
|
+
* @param config - Compaction configuration options
|
|
5967
|
+
* @returns This builder for chaining
|
|
5968
|
+
*
|
|
5969
|
+
* @example
|
|
5970
|
+
* ```typescript
|
|
5971
|
+
* // Custom thresholds
|
|
5972
|
+
* .withCompaction({
|
|
5973
|
+
* triggerThresholdPercent: 70,
|
|
5974
|
+
* targetPercent: 40,
|
|
5975
|
+
* preserveRecentTurns: 10,
|
|
5976
|
+
* })
|
|
5977
|
+
*
|
|
5978
|
+
* // Different strategy
|
|
5979
|
+
* .withCompaction({
|
|
5980
|
+
* strategy: 'sliding-window',
|
|
5981
|
+
* })
|
|
5982
|
+
*
|
|
5983
|
+
* // With callback
|
|
5984
|
+
* .withCompaction({
|
|
5985
|
+
* onCompaction: (event) => {
|
|
5986
|
+
* console.log(`Saved ${event.tokensBefore - event.tokensAfter} tokens`);
|
|
5987
|
+
* }
|
|
5988
|
+
* })
|
|
5989
|
+
* ```
|
|
5990
|
+
*/
|
|
5991
|
+
withCompaction(config) {
|
|
5992
|
+
this.compactionConfig = { ...config, enabled: config.enabled ?? true };
|
|
5993
|
+
return this;
|
|
5994
|
+
}
|
|
5995
|
+
/**
|
|
5996
|
+
* Disable context compaction.
|
|
5997
|
+
*
|
|
5998
|
+
* By default, compaction is enabled. Use this method to explicitly disable it.
|
|
5999
|
+
*
|
|
6000
|
+
* @returns This builder for chaining
|
|
6001
|
+
*
|
|
6002
|
+
* @example
|
|
6003
|
+
* ```typescript
|
|
6004
|
+
* .withoutCompaction() // Disable automatic compaction
|
|
6005
|
+
* ```
|
|
6006
|
+
*/
|
|
6007
|
+
withoutCompaction() {
|
|
6008
|
+
this.compactionConfig = { enabled: false };
|
|
6009
|
+
return this;
|
|
6010
|
+
}
|
|
5106
6011
|
/**
|
|
5107
6012
|
* Add a synthetic gadget call to the conversation history.
|
|
5108
6013
|
*
|
|
@@ -5218,7 +6123,8 @@ ${endPrefix}`
|
|
|
5218
6123
|
shouldContinueAfterError: this.shouldContinueAfterError,
|
|
5219
6124
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
5220
6125
|
gadgetOutputLimit: this.gadgetOutputLimit,
|
|
5221
|
-
gadgetOutputLimitPercent: this.gadgetOutputLimitPercent
|
|
6126
|
+
gadgetOutputLimitPercent: this.gadgetOutputLimitPercent,
|
|
6127
|
+
compactionConfig: this.compactionConfig
|
|
5222
6128
|
};
|
|
5223
6129
|
return new Agent(AGENT_INTERNAL_KEY, options);
|
|
5224
6130
|
}
|
|
@@ -5320,7 +6226,8 @@ ${endPrefix}`
|
|
|
5320
6226
|
shouldContinueAfterError: this.shouldContinueAfterError,
|
|
5321
6227
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
5322
6228
|
gadgetOutputLimit: this.gadgetOutputLimit,
|
|
5323
|
-
gadgetOutputLimitPercent: this.gadgetOutputLimitPercent
|
|
6229
|
+
gadgetOutputLimitPercent: this.gadgetOutputLimitPercent,
|
|
6230
|
+
compactionConfig: this.compactionConfig
|
|
5324
6231
|
};
|
|
5325
6232
|
return new Agent(AGENT_INTERNAL_KEY, options);
|
|
5326
6233
|
}
|
|
@@ -5585,9 +6492,11 @@ export {
|
|
|
5585
6492
|
init_schema_validator,
|
|
5586
6493
|
GadgetRegistry,
|
|
5587
6494
|
init_registry,
|
|
6495
|
+
DEFAULT_HINTS,
|
|
5588
6496
|
DEFAULT_PROMPTS,
|
|
5589
6497
|
resolvePromptTemplate,
|
|
5590
6498
|
resolveRulesTemplate,
|
|
6499
|
+
resolveHintTemplate,
|
|
5591
6500
|
init_prompt_config,
|
|
5592
6501
|
LLMMessageBuilder,
|
|
5593
6502
|
init_messages,
|
|
@@ -5602,6 +6511,16 @@ export {
|
|
|
5602
6511
|
init_create_gadget,
|
|
5603
6512
|
createGadgetOutputViewer,
|
|
5604
6513
|
init_output_viewer,
|
|
6514
|
+
DEFAULT_COMPACTION_CONFIG,
|
|
6515
|
+
DEFAULT_SUMMARIZATION_PROMPT,
|
|
6516
|
+
init_config,
|
|
6517
|
+
init_strategy,
|
|
6518
|
+
SlidingWindowStrategy,
|
|
6519
|
+
SummarizationStrategy,
|
|
6520
|
+
HybridStrategy,
|
|
6521
|
+
init_strategies,
|
|
6522
|
+
CompactionManager,
|
|
6523
|
+
init_manager,
|
|
5605
6524
|
GadgetOutputStore,
|
|
5606
6525
|
init_gadget_output_store,
|
|
5607
6526
|
ConversationManager,
|
|
@@ -5613,10 +6532,10 @@ export {
|
|
|
5613
6532
|
BreakLoopException,
|
|
5614
6533
|
HumanInputException,
|
|
5615
6534
|
init_exceptions,
|
|
5616
|
-
GadgetExecutor,
|
|
5617
|
-
init_executor,
|
|
5618
6535
|
StreamParser,
|
|
5619
6536
|
init_parser,
|
|
6537
|
+
GadgetExecutor,
|
|
6538
|
+
init_executor,
|
|
5620
6539
|
StreamProcessor,
|
|
5621
6540
|
init_stream_processor,
|
|
5622
6541
|
FALLBACK_CHARS_PER_TOKEN,
|
|
@@ -5644,4 +6563,4 @@ export {
|
|
|
5644
6563
|
AgentBuilder,
|
|
5645
6564
|
init_builder
|
|
5646
6565
|
};
|
|
5647
|
-
//# sourceMappingURL=chunk-
|
|
6566
|
+
//# sourceMappingURL=chunk-RZTAKIDE.js.map
|