llmist 2.5.0 → 3.0.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 +10 -1
- package/dist/{chunk-YHS2DYXP.js → chunk-67MMSOAT.js} +1144 -799
- package/dist/chunk-67MMSOAT.js.map +1 -0
- package/dist/{chunk-IHSZUAYN.js → chunk-NBPKLSXJ.js} +136 -20
- package/dist/chunk-NBPKLSXJ.js.map +1 -0
- package/dist/cli.cjs +3994 -3128
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3254 -2748
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +792 -323
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +734 -481
- package/dist/index.d.ts +734 -481
- package/dist/index.js +32 -16
- package/dist/{mock-stream-ga4KIiwX.d.cts → mock-stream-COHw8h9b.d.cts} +441 -58
- package/dist/{mock-stream-ga4KIiwX.d.ts → mock-stream-COHw8h9b.d.ts} +441 -58
- package/dist/testing/index.cjs +1115 -761
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +346 -346
- package/dist/testing/index.d.ts +346 -346
- package/dist/testing/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-IHSZUAYN.js.map +0 -1
- package/dist/chunk-YHS2DYXP.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -192,7 +192,9 @@ var init_input_content = __esm({
|
|
|
192
192
|
// WAV (RIFF)
|
|
193
193
|
{ bytes: [82, 73, 70, 70], mimeType: "audio/wav" },
|
|
194
194
|
// WebM
|
|
195
|
-
{ bytes: [26, 69, 223, 163], mimeType: "audio/webm" }
|
|
195
|
+
{ bytes: [26, 69, 223, 163], mimeType: "audio/webm" },
|
|
196
|
+
// FLAC (fLaC)
|
|
197
|
+
{ bytes: [102, 76, 97, 67], mimeType: "audio/flac" }
|
|
196
198
|
];
|
|
197
199
|
}
|
|
198
200
|
});
|
|
@@ -564,13 +566,13 @@ var init_prompt_config = __esm({
|
|
|
564
566
|
});
|
|
565
567
|
|
|
566
568
|
// src/core/messages.ts
|
|
567
|
-
function
|
|
569
|
+
function normalizeMessageContent(content) {
|
|
568
570
|
if (typeof content === "string") {
|
|
569
571
|
return [{ type: "text", text: content }];
|
|
570
572
|
}
|
|
571
573
|
return content;
|
|
572
574
|
}
|
|
573
|
-
function
|
|
575
|
+
function extractMessageText(content) {
|
|
574
576
|
if (typeof content === "string") {
|
|
575
577
|
return content;
|
|
576
578
|
}
|
|
@@ -930,7 +932,17 @@ Produces: { "items": ["first", "second"] }`);
|
|
|
930
932
|
this.messages.push({ role: "user", content: parts });
|
|
931
933
|
return this;
|
|
932
934
|
}
|
|
933
|
-
|
|
935
|
+
/**
|
|
936
|
+
* Record a gadget execution result in the message history.
|
|
937
|
+
* Creates an assistant message with the gadget invocation and a user message with the result.
|
|
938
|
+
*
|
|
939
|
+
* @param gadget - Name of the gadget that was executed
|
|
940
|
+
* @param parameters - Parameters that were passed to the gadget
|
|
941
|
+
* @param result - Text result from the gadget execution
|
|
942
|
+
* @param media - Optional media outputs from the gadget
|
|
943
|
+
* @param mediaIds - Optional IDs for the media outputs
|
|
944
|
+
*/
|
|
945
|
+
addGadgetCallResult(gadget, parameters, result, media, mediaIds) {
|
|
934
946
|
const paramStr = this.formatBlockParameters(parameters, "");
|
|
935
947
|
this.messages.push({
|
|
936
948
|
role: "assistant",
|
|
@@ -938,10 +950,25 @@ Produces: { "items": ["first", "second"] }`);
|
|
|
938
950
|
${paramStr}
|
|
939
951
|
${this.endPrefix}`
|
|
940
952
|
});
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
953
|
+
if (media && media.length > 0 && mediaIds && mediaIds.length > 0) {
|
|
954
|
+
const idRefs = media.map((m, i) => `[Media: ${mediaIds[i]} (${m.kind})]`).join("\n");
|
|
955
|
+
const textWithIds = `Result: ${result}
|
|
956
|
+
${idRefs}`;
|
|
957
|
+
const parts = [text(textWithIds)];
|
|
958
|
+
for (const item of media) {
|
|
959
|
+
if (item.kind === "image") {
|
|
960
|
+
parts.push(imageFromBase64(item.data, item.mimeType));
|
|
961
|
+
} else if (item.kind === "audio") {
|
|
962
|
+
parts.push(audioFromBase64(item.data, item.mimeType));
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
this.messages.push({ role: "user", content: parts });
|
|
966
|
+
} else {
|
|
967
|
+
this.messages.push({
|
|
968
|
+
role: "user",
|
|
969
|
+
content: `Result: ${result}`
|
|
970
|
+
});
|
|
971
|
+
}
|
|
945
972
|
return this;
|
|
946
973
|
}
|
|
947
974
|
/**
|
|
@@ -978,22 +1005,226 @@ ${this.endPrefix}`
|
|
|
978
1005
|
}
|
|
979
1006
|
});
|
|
980
1007
|
|
|
1008
|
+
// src/gadgets/media-store.ts
|
|
1009
|
+
function getLlmistTmpDir() {
|
|
1010
|
+
return (0, import_node_path.join)((0, import_node_os.homedir)(), ".llmist", "tmp");
|
|
1011
|
+
}
|
|
1012
|
+
var import_node_crypto, import_promises, import_node_os, import_node_path, MIME_TO_EXTENSION, MediaStore;
|
|
1013
|
+
var init_media_store = __esm({
|
|
1014
|
+
"src/gadgets/media-store.ts"() {
|
|
1015
|
+
"use strict";
|
|
1016
|
+
import_node_crypto = require("crypto");
|
|
1017
|
+
import_promises = require("fs/promises");
|
|
1018
|
+
import_node_os = require("os");
|
|
1019
|
+
import_node_path = require("path");
|
|
1020
|
+
MIME_TO_EXTENSION = {
|
|
1021
|
+
// Images
|
|
1022
|
+
"image/png": ".png",
|
|
1023
|
+
"image/jpeg": ".jpg",
|
|
1024
|
+
"image/gif": ".gif",
|
|
1025
|
+
"image/webp": ".webp",
|
|
1026
|
+
"image/svg+xml": ".svg",
|
|
1027
|
+
"image/bmp": ".bmp",
|
|
1028
|
+
"image/tiff": ".tiff",
|
|
1029
|
+
// Audio
|
|
1030
|
+
"audio/mp3": ".mp3",
|
|
1031
|
+
"audio/mpeg": ".mp3",
|
|
1032
|
+
"audio/wav": ".wav",
|
|
1033
|
+
"audio/webm": ".webm",
|
|
1034
|
+
"audio/ogg": ".ogg",
|
|
1035
|
+
"audio/flac": ".flac",
|
|
1036
|
+
"audio/aac": ".aac",
|
|
1037
|
+
// Video
|
|
1038
|
+
"video/mp4": ".mp4",
|
|
1039
|
+
"video/webm": ".webm",
|
|
1040
|
+
"video/ogg": ".ogv",
|
|
1041
|
+
"video/quicktime": ".mov",
|
|
1042
|
+
"video/x-msvideo": ".avi",
|
|
1043
|
+
// Documents
|
|
1044
|
+
"application/pdf": ".pdf",
|
|
1045
|
+
"application/json": ".json",
|
|
1046
|
+
"text/plain": ".txt",
|
|
1047
|
+
"text/html": ".html",
|
|
1048
|
+
"text/css": ".css",
|
|
1049
|
+
"text/javascript": ".js"
|
|
1050
|
+
};
|
|
1051
|
+
MediaStore = class {
|
|
1052
|
+
items = /* @__PURE__ */ new Map();
|
|
1053
|
+
outputDir;
|
|
1054
|
+
counter = 0;
|
|
1055
|
+
initialized = false;
|
|
1056
|
+
/**
|
|
1057
|
+
* Create a new MediaStore.
|
|
1058
|
+
*
|
|
1059
|
+
* @param sessionId - Optional session ID for the output directory.
|
|
1060
|
+
* If not provided, a random ID is generated.
|
|
1061
|
+
*/
|
|
1062
|
+
constructor(sessionId) {
|
|
1063
|
+
const id = sessionId ?? (0, import_node_crypto.randomBytes)(8).toString("hex");
|
|
1064
|
+
this.outputDir = (0, import_node_path.join)(getLlmistTmpDir(), `media-${id}`);
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Get the output directory path.
|
|
1068
|
+
*/
|
|
1069
|
+
getOutputDir() {
|
|
1070
|
+
return this.outputDir;
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Ensure the output directory exists.
|
|
1074
|
+
* @throws Error if directory creation fails
|
|
1075
|
+
*/
|
|
1076
|
+
async ensureDir() {
|
|
1077
|
+
if (this.initialized) return;
|
|
1078
|
+
try {
|
|
1079
|
+
await (0, import_promises.mkdir)(this.outputDir, { recursive: true });
|
|
1080
|
+
this.initialized = true;
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
throw new Error(
|
|
1083
|
+
`MediaStore: Failed to create directory ${this.outputDir}: ${error instanceof Error ? error.message : String(error)}`
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Generate a unique media ID.
|
|
1089
|
+
* Format: "media_" + 6 random alphanumeric characters
|
|
1090
|
+
*/
|
|
1091
|
+
generateId() {
|
|
1092
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
1093
|
+
let id = "media_";
|
|
1094
|
+
const bytes = (0, import_node_crypto.randomBytes)(6);
|
|
1095
|
+
for (let i = 0; i < 6; i++) {
|
|
1096
|
+
id += chars[bytes[i] % chars.length];
|
|
1097
|
+
}
|
|
1098
|
+
return id;
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Get file extension from MIME type.
|
|
1102
|
+
*/
|
|
1103
|
+
getExtension(mimeType) {
|
|
1104
|
+
return MIME_TO_EXTENSION[mimeType] ?? ".bin";
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Store media and return stored metadata with ID.
|
|
1108
|
+
*
|
|
1109
|
+
* @param media - The media output from a gadget
|
|
1110
|
+
* @param gadgetName - Name of the gadget that created this media
|
|
1111
|
+
* @returns Stored media information including generated ID
|
|
1112
|
+
* @throws Error if file write fails
|
|
1113
|
+
*/
|
|
1114
|
+
async store(media, gadgetName) {
|
|
1115
|
+
await this.ensureDir();
|
|
1116
|
+
const id = this.generateId();
|
|
1117
|
+
const ext = this.getExtension(media.mimeType);
|
|
1118
|
+
const filename = media.fileName ?? `${gadgetName}_${String(++this.counter).padStart(3, "0")}${ext}`;
|
|
1119
|
+
const filePath = (0, import_node_path.join)(this.outputDir, filename);
|
|
1120
|
+
const buffer = Buffer.from(media.data, "base64");
|
|
1121
|
+
try {
|
|
1122
|
+
await (0, import_promises.writeFile)(filePath, buffer);
|
|
1123
|
+
} catch (error) {
|
|
1124
|
+
throw new Error(
|
|
1125
|
+
`MediaStore: Failed to write media file ${filePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
1126
|
+
);
|
|
1127
|
+
}
|
|
1128
|
+
const stored = {
|
|
1129
|
+
id,
|
|
1130
|
+
kind: media.kind,
|
|
1131
|
+
path: filePath,
|
|
1132
|
+
mimeType: media.mimeType,
|
|
1133
|
+
sizeBytes: buffer.length,
|
|
1134
|
+
description: media.description,
|
|
1135
|
+
metadata: media.metadata,
|
|
1136
|
+
gadgetName,
|
|
1137
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
1138
|
+
};
|
|
1139
|
+
this.items.set(id, stored);
|
|
1140
|
+
return stored;
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Get stored media by ID.
|
|
1144
|
+
*
|
|
1145
|
+
* @param id - The media ID (e.g., "media_a1b2c3")
|
|
1146
|
+
* @returns The stored media or undefined if not found
|
|
1147
|
+
*/
|
|
1148
|
+
get(id) {
|
|
1149
|
+
return this.items.get(id);
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Get the actual file path for a media ID.
|
|
1153
|
+
* Convenience method for gadgets that need the raw path.
|
|
1154
|
+
*
|
|
1155
|
+
* @param id - The media ID
|
|
1156
|
+
* @returns The file path or undefined if not found
|
|
1157
|
+
*/
|
|
1158
|
+
getPath(id) {
|
|
1159
|
+
return this.items.get(id)?.path;
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* List all stored media, optionally filtered by kind.
|
|
1163
|
+
*
|
|
1164
|
+
* @param kind - Optional media kind to filter by
|
|
1165
|
+
* @returns Array of stored media items
|
|
1166
|
+
*/
|
|
1167
|
+
list(kind) {
|
|
1168
|
+
const all = Array.from(this.items.values());
|
|
1169
|
+
if (kind) {
|
|
1170
|
+
return all.filter((item) => item.kind === kind);
|
|
1171
|
+
}
|
|
1172
|
+
return all;
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* Get the count of stored media items.
|
|
1176
|
+
*/
|
|
1177
|
+
get size() {
|
|
1178
|
+
return this.items.size;
|
|
1179
|
+
}
|
|
1180
|
+
/**
|
|
1181
|
+
* Check if a media ID exists.
|
|
1182
|
+
*/
|
|
1183
|
+
has(id) {
|
|
1184
|
+
return this.items.has(id);
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Clear in-memory store without deleting files.
|
|
1188
|
+
* Resets the counter but leaves files on disk.
|
|
1189
|
+
*/
|
|
1190
|
+
clear() {
|
|
1191
|
+
this.items.clear();
|
|
1192
|
+
this.counter = 0;
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Delete all stored files and clear memory.
|
|
1196
|
+
* Removes the entire session directory.
|
|
1197
|
+
*/
|
|
1198
|
+
async cleanup() {
|
|
1199
|
+
if (this.initialized) {
|
|
1200
|
+
try {
|
|
1201
|
+
await (0, import_promises.rm)(this.outputDir, { recursive: true, force: true });
|
|
1202
|
+
} catch {
|
|
1203
|
+
}
|
|
1204
|
+
this.initialized = false;
|
|
1205
|
+
}
|
|
1206
|
+
this.clear();
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
|
|
981
1212
|
// src/gadgets/exceptions.ts
|
|
982
|
-
var
|
|
1213
|
+
var TaskCompletionSignal, HumanInputRequiredException, TimeoutException, AbortException;
|
|
983
1214
|
var init_exceptions = __esm({
|
|
984
1215
|
"src/gadgets/exceptions.ts"() {
|
|
985
1216
|
"use strict";
|
|
986
|
-
|
|
1217
|
+
TaskCompletionSignal = class extends Error {
|
|
987
1218
|
constructor(message) {
|
|
988
1219
|
super(message ?? "Agent loop terminated by gadget");
|
|
989
|
-
this.name = "
|
|
1220
|
+
this.name = "TaskCompletionSignal";
|
|
990
1221
|
}
|
|
991
1222
|
};
|
|
992
|
-
|
|
1223
|
+
HumanInputRequiredException = class extends Error {
|
|
993
1224
|
question;
|
|
994
1225
|
constructor(question) {
|
|
995
1226
|
super(`Human input required: ${question}`);
|
|
996
|
-
this.name = "
|
|
1227
|
+
this.name = "HumanInputRequiredException";
|
|
997
1228
|
this.question = question;
|
|
998
1229
|
}
|
|
999
1230
|
};
|
|
@@ -1007,10 +1238,10 @@ var init_exceptions = __esm({
|
|
|
1007
1238
|
this.timeoutMs = timeoutMs;
|
|
1008
1239
|
}
|
|
1009
1240
|
};
|
|
1010
|
-
|
|
1241
|
+
AbortException = class extends Error {
|
|
1011
1242
|
constructor(message) {
|
|
1012
1243
|
super(message || "Gadget execution was aborted");
|
|
1013
|
-
this.name = "
|
|
1244
|
+
this.name = "AbortException";
|
|
1014
1245
|
}
|
|
1015
1246
|
};
|
|
1016
1247
|
}
|
|
@@ -1050,7 +1281,7 @@ function createLogger(options = {}) {
|
|
|
1050
1281
|
let finalType = defaultType;
|
|
1051
1282
|
if (envLogFile) {
|
|
1052
1283
|
try {
|
|
1053
|
-
(0, import_node_fs.mkdirSync)((0,
|
|
1284
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path2.dirname)(envLogFile), { recursive: true });
|
|
1054
1285
|
const flags = logReset ? "w" : "a";
|
|
1055
1286
|
logFileStream = (0, import_node_fs.createWriteStream)(envLogFile, { flags });
|
|
1056
1287
|
finalType = "hidden";
|
|
@@ -1075,12 +1306,12 @@ function createLogger(options = {}) {
|
|
|
1075
1306
|
}
|
|
1076
1307
|
return logger;
|
|
1077
1308
|
}
|
|
1078
|
-
var import_node_fs,
|
|
1309
|
+
var import_node_fs, import_node_path2, import_tslog, LEVEL_NAME_TO_ID, defaultLogger;
|
|
1079
1310
|
var init_logger = __esm({
|
|
1080
1311
|
"src/logging/logger.ts"() {
|
|
1081
1312
|
"use strict";
|
|
1082
1313
|
import_node_fs = require("fs");
|
|
1083
|
-
|
|
1314
|
+
import_node_path2 = require("path");
|
|
1084
1315
|
import_tslog = require("tslog");
|
|
1085
1316
|
LEVEL_NAME_TO_ID = {
|
|
1086
1317
|
silly: 0,
|
|
@@ -1179,7 +1410,7 @@ var init_schema_to_json = __esm({
|
|
|
1179
1410
|
});
|
|
1180
1411
|
|
|
1181
1412
|
// src/gadgets/gadget.ts
|
|
1182
|
-
function
|
|
1413
|
+
function formatParamsForBlockExample(params, prefix = "", argPrefix = GADGET_ARG_PREFIX) {
|
|
1183
1414
|
const lines = [];
|
|
1184
1415
|
for (const [key, value] of Object.entries(params)) {
|
|
1185
1416
|
const fullPath = prefix ? `${prefix}/${key}` : key;
|
|
@@ -1187,14 +1418,14 @@ function formatParamsAsBlock(params, prefix = "", argPrefix = GADGET_ARG_PREFIX)
|
|
|
1187
1418
|
value.forEach((item, index) => {
|
|
1188
1419
|
const itemPath = `${fullPath}/${index}`;
|
|
1189
1420
|
if (typeof item === "object" && item !== null) {
|
|
1190
|
-
lines.push(
|
|
1421
|
+
lines.push(formatParamsForBlockExample(item, itemPath, argPrefix));
|
|
1191
1422
|
} else {
|
|
1192
1423
|
lines.push(`${argPrefix}${itemPath}`);
|
|
1193
1424
|
lines.push(String(item));
|
|
1194
1425
|
}
|
|
1195
1426
|
});
|
|
1196
1427
|
} else if (typeof value === "object" && value !== null) {
|
|
1197
|
-
lines.push(
|
|
1428
|
+
lines.push(formatParamsForBlockExample(value, fullPath, argPrefix));
|
|
1198
1429
|
} else {
|
|
1199
1430
|
lines.push(`${argPrefix}${fullPath}`);
|
|
1200
1431
|
lines.push(String(value));
|
|
@@ -1283,7 +1514,7 @@ function formatSchemaAsPlainText(schema, indent = "", atRoot = true) {
|
|
|
1283
1514
|
}
|
|
1284
1515
|
return lines.join("\n");
|
|
1285
1516
|
}
|
|
1286
|
-
var
|
|
1517
|
+
var AbstractGadget;
|
|
1287
1518
|
var init_gadget = __esm({
|
|
1288
1519
|
"src/gadgets/gadget.ts"() {
|
|
1289
1520
|
"use strict";
|
|
@@ -1291,7 +1522,7 @@ var init_gadget = __esm({
|
|
|
1291
1522
|
init_exceptions();
|
|
1292
1523
|
init_schema_to_json();
|
|
1293
1524
|
init_schema_validator();
|
|
1294
|
-
|
|
1525
|
+
AbstractGadget = class {
|
|
1295
1526
|
/**
|
|
1296
1527
|
* The name of the gadget. Used for identification when LLM calls it.
|
|
1297
1528
|
* If not provided, defaults to the class name.
|
|
@@ -1319,14 +1550,14 @@ var init_gadget = __esm({
|
|
|
1319
1550
|
*/
|
|
1320
1551
|
examples;
|
|
1321
1552
|
/**
|
|
1322
|
-
* Throws an
|
|
1553
|
+
* Throws an AbortException if the execution has been aborted.
|
|
1323
1554
|
*
|
|
1324
1555
|
* Call this at key checkpoints in long-running gadgets to allow early exit
|
|
1325
1556
|
* when the gadget has been cancelled (e.g., due to timeout). This enables
|
|
1326
1557
|
* resource cleanup and prevents unnecessary work after cancellation.
|
|
1327
1558
|
*
|
|
1328
1559
|
* @param ctx - The execution context containing the abort signal
|
|
1329
|
-
* @throws
|
|
1560
|
+
* @throws AbortException if ctx.signal.aborted is true
|
|
1330
1561
|
*
|
|
1331
1562
|
* @example
|
|
1332
1563
|
* ```typescript
|
|
@@ -1351,7 +1582,7 @@ var init_gadget = __esm({
|
|
|
1351
1582
|
*/
|
|
1352
1583
|
throwIfAborted(ctx) {
|
|
1353
1584
|
if (ctx?.signal?.aborted) {
|
|
1354
|
-
throw new
|
|
1585
|
+
throw new AbortException();
|
|
1355
1586
|
}
|
|
1356
1587
|
}
|
|
1357
1588
|
/**
|
|
@@ -1492,7 +1723,9 @@ var init_gadget = __esm({
|
|
|
1492
1723
|
parts.push(`# ${example.comment}`);
|
|
1493
1724
|
}
|
|
1494
1725
|
parts.push(`${effectiveStartPrefix}${gadgetName}`);
|
|
1495
|
-
parts.push(
|
|
1726
|
+
parts.push(
|
|
1727
|
+
formatParamsForBlockExample(example.params, "", effectiveArgPrefix)
|
|
1728
|
+
);
|
|
1496
1729
|
parts.push(effectiveEndPrefix);
|
|
1497
1730
|
if (example.output !== void 0) {
|
|
1498
1731
|
parts.push("");
|
|
@@ -1509,7 +1742,7 @@ var init_gadget = __esm({
|
|
|
1509
1742
|
|
|
1510
1743
|
// src/gadgets/create-gadget.ts
|
|
1511
1744
|
function createGadget(config) {
|
|
1512
|
-
class DynamicGadget extends
|
|
1745
|
+
class DynamicGadget extends AbstractGadget {
|
|
1513
1746
|
name = config.name;
|
|
1514
1747
|
description = config.description;
|
|
1515
1748
|
parameterSchema = config.schema;
|
|
@@ -1694,6 +1927,18 @@ var init_output_viewer = __esm({
|
|
|
1694
1927
|
}
|
|
1695
1928
|
});
|
|
1696
1929
|
|
|
1930
|
+
// src/agent/agent-internal-key.ts
|
|
1931
|
+
function isValidAgentKey(key) {
|
|
1932
|
+
return key === AGENT_INTERNAL_KEY;
|
|
1933
|
+
}
|
|
1934
|
+
var AGENT_INTERNAL_KEY;
|
|
1935
|
+
var init_agent_internal_key = __esm({
|
|
1936
|
+
"src/agent/agent-internal-key.ts"() {
|
|
1937
|
+
"use strict";
|
|
1938
|
+
AGENT_INTERNAL_KEY = Symbol("AGENT_INTERNAL_KEY");
|
|
1939
|
+
}
|
|
1940
|
+
});
|
|
1941
|
+
|
|
1697
1942
|
// src/agent/compaction/config.ts
|
|
1698
1943
|
function resolveCompactionConfig(config = {}) {
|
|
1699
1944
|
const trigger = config.triggerThresholdPercent ?? DEFAULT_COMPACTION_CONFIG.triggerThresholdPercent;
|
|
@@ -1941,9 +2186,9 @@ var init_hybrid = __esm({
|
|
|
1941
2186
|
var init_strategies = __esm({
|
|
1942
2187
|
"src/agent/compaction/strategies/index.ts"() {
|
|
1943
2188
|
"use strict";
|
|
2189
|
+
init_hybrid();
|
|
1944
2190
|
init_sliding_window();
|
|
1945
2191
|
init_summarization();
|
|
1946
|
-
init_hybrid();
|
|
1947
2192
|
}
|
|
1948
2193
|
});
|
|
1949
2194
|
|
|
@@ -2105,98 +2350,6 @@ var init_manager = __esm({
|
|
|
2105
2350
|
}
|
|
2106
2351
|
});
|
|
2107
2352
|
|
|
2108
|
-
// src/agent/gadget-output-store.ts
|
|
2109
|
-
var import_node_crypto, GadgetOutputStore;
|
|
2110
|
-
var init_gadget_output_store = __esm({
|
|
2111
|
-
"src/agent/gadget-output-store.ts"() {
|
|
2112
|
-
"use strict";
|
|
2113
|
-
import_node_crypto = require("crypto");
|
|
2114
|
-
GadgetOutputStore = class {
|
|
2115
|
-
outputs = /* @__PURE__ */ new Map();
|
|
2116
|
-
/**
|
|
2117
|
-
* Store a gadget output and return its ID.
|
|
2118
|
-
*
|
|
2119
|
-
* @param gadgetName - Name of the gadget that produced the output
|
|
2120
|
-
* @param content - Full output content to store
|
|
2121
|
-
* @returns Generated ID for retrieving the output later
|
|
2122
|
-
*/
|
|
2123
|
-
store(gadgetName, content) {
|
|
2124
|
-
const id = this.generateId(gadgetName);
|
|
2125
|
-
const encoder = new TextEncoder();
|
|
2126
|
-
const stored = {
|
|
2127
|
-
id,
|
|
2128
|
-
gadgetName,
|
|
2129
|
-
content,
|
|
2130
|
-
byteSize: encoder.encode(content).length,
|
|
2131
|
-
lineCount: content.split("\n").length,
|
|
2132
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2133
|
-
};
|
|
2134
|
-
this.outputs.set(id, stored);
|
|
2135
|
-
return id;
|
|
2136
|
-
}
|
|
2137
|
-
/**
|
|
2138
|
-
* Retrieve a stored output by ID.
|
|
2139
|
-
*
|
|
2140
|
-
* @param id - The output ID (e.g., "Search_d34db33f")
|
|
2141
|
-
* @returns The stored output or undefined if not found
|
|
2142
|
-
*/
|
|
2143
|
-
get(id) {
|
|
2144
|
-
return this.outputs.get(id);
|
|
2145
|
-
}
|
|
2146
|
-
/**
|
|
2147
|
-
* Check if an output exists.
|
|
2148
|
-
*
|
|
2149
|
-
* @param id - The output ID to check
|
|
2150
|
-
* @returns True if the output exists
|
|
2151
|
-
*/
|
|
2152
|
-
has(id) {
|
|
2153
|
-
return this.outputs.has(id);
|
|
2154
|
-
}
|
|
2155
|
-
/**
|
|
2156
|
-
* Get all stored output IDs.
|
|
2157
|
-
*
|
|
2158
|
-
* @returns Array of output IDs
|
|
2159
|
-
*/
|
|
2160
|
-
getIds() {
|
|
2161
|
-
return Array.from(this.outputs.keys());
|
|
2162
|
-
}
|
|
2163
|
-
/**
|
|
2164
|
-
* Get the number of stored outputs.
|
|
2165
|
-
*/
|
|
2166
|
-
get size() {
|
|
2167
|
-
return this.outputs.size;
|
|
2168
|
-
}
|
|
2169
|
-
/**
|
|
2170
|
-
* Clear all stored outputs.
|
|
2171
|
-
* Called when the agent run completes.
|
|
2172
|
-
*/
|
|
2173
|
-
clear() {
|
|
2174
|
-
this.outputs.clear();
|
|
2175
|
-
}
|
|
2176
|
-
/**
|
|
2177
|
-
* Generate a unique ID for a stored output.
|
|
2178
|
-
* Format: {GadgetName}_{8 hex chars}
|
|
2179
|
-
*/
|
|
2180
|
-
generateId(gadgetName) {
|
|
2181
|
-
const hex = (0, import_node_crypto.randomBytes)(4).toString("hex");
|
|
2182
|
-
return `${gadgetName}_${hex}`;
|
|
2183
|
-
}
|
|
2184
|
-
};
|
|
2185
|
-
}
|
|
2186
|
-
});
|
|
2187
|
-
|
|
2188
|
-
// src/agent/agent-internal-key.ts
|
|
2189
|
-
function isValidAgentKey(key) {
|
|
2190
|
-
return key === AGENT_INTERNAL_KEY;
|
|
2191
|
-
}
|
|
2192
|
-
var AGENT_INTERNAL_KEY;
|
|
2193
|
-
var init_agent_internal_key = __esm({
|
|
2194
|
-
"src/agent/agent-internal-key.ts"() {
|
|
2195
|
-
"use strict";
|
|
2196
|
-
AGENT_INTERNAL_KEY = Symbol("AGENT_INTERNAL_KEY");
|
|
2197
|
-
}
|
|
2198
|
-
});
|
|
2199
|
-
|
|
2200
2353
|
// src/agent/conversation-manager.ts
|
|
2201
2354
|
var ConversationManager;
|
|
2202
2355
|
var init_conversation_manager = __esm({
|
|
@@ -2227,8 +2380,8 @@ var init_conversation_manager = __esm({
|
|
|
2227
2380
|
addAssistantMessage(content) {
|
|
2228
2381
|
this.historyBuilder.addAssistant(content);
|
|
2229
2382
|
}
|
|
2230
|
-
|
|
2231
|
-
this.historyBuilder.
|
|
2383
|
+
addGadgetCallResult(gadgetName, parameters, result, media, mediaIds) {
|
|
2384
|
+
this.historyBuilder.addGadgetCallResult(gadgetName, parameters, result, media, mediaIds);
|
|
2232
2385
|
}
|
|
2233
2386
|
getMessages() {
|
|
2234
2387
|
return [...this.baseMessages, ...this.initialMessages, ...this.historyBuilder.build()];
|
|
@@ -2248,7 +2401,7 @@ var init_conversation_manager = __esm({
|
|
|
2248
2401
|
if (msg.role === "user") {
|
|
2249
2402
|
this.historyBuilder.addUser(msg.content);
|
|
2250
2403
|
} else if (msg.role === "assistant") {
|
|
2251
|
-
this.historyBuilder.addAssistant(
|
|
2404
|
+
this.historyBuilder.addAssistant(extractMessageText(msg.content));
|
|
2252
2405
|
}
|
|
2253
2406
|
}
|
|
2254
2407
|
}
|
|
@@ -2342,6 +2495,86 @@ var init_event_handlers = __esm({
|
|
|
2342
2495
|
}
|
|
2343
2496
|
});
|
|
2344
2497
|
|
|
2498
|
+
// src/agent/gadget-output-store.ts
|
|
2499
|
+
var import_node_crypto2, GadgetOutputStore;
|
|
2500
|
+
var init_gadget_output_store = __esm({
|
|
2501
|
+
"src/agent/gadget-output-store.ts"() {
|
|
2502
|
+
"use strict";
|
|
2503
|
+
import_node_crypto2 = require("crypto");
|
|
2504
|
+
GadgetOutputStore = class {
|
|
2505
|
+
outputs = /* @__PURE__ */ new Map();
|
|
2506
|
+
/**
|
|
2507
|
+
* Store a gadget output and return its ID.
|
|
2508
|
+
*
|
|
2509
|
+
* @param gadgetName - Name of the gadget that produced the output
|
|
2510
|
+
* @param content - Full output content to store
|
|
2511
|
+
* @returns Generated ID for retrieving the output later
|
|
2512
|
+
*/
|
|
2513
|
+
store(gadgetName, content) {
|
|
2514
|
+
const id = this.generateId(gadgetName);
|
|
2515
|
+
const encoder = new TextEncoder();
|
|
2516
|
+
const stored = {
|
|
2517
|
+
id,
|
|
2518
|
+
gadgetName,
|
|
2519
|
+
content,
|
|
2520
|
+
byteSize: encoder.encode(content).length,
|
|
2521
|
+
lineCount: content.split("\n").length,
|
|
2522
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2523
|
+
};
|
|
2524
|
+
this.outputs.set(id, stored);
|
|
2525
|
+
return id;
|
|
2526
|
+
}
|
|
2527
|
+
/**
|
|
2528
|
+
* Retrieve a stored output by ID.
|
|
2529
|
+
*
|
|
2530
|
+
* @param id - The output ID (e.g., "Search_d34db33f")
|
|
2531
|
+
* @returns The stored output or undefined if not found
|
|
2532
|
+
*/
|
|
2533
|
+
get(id) {
|
|
2534
|
+
return this.outputs.get(id);
|
|
2535
|
+
}
|
|
2536
|
+
/**
|
|
2537
|
+
* Check if an output exists.
|
|
2538
|
+
*
|
|
2539
|
+
* @param id - The output ID to check
|
|
2540
|
+
* @returns True if the output exists
|
|
2541
|
+
*/
|
|
2542
|
+
has(id) {
|
|
2543
|
+
return this.outputs.has(id);
|
|
2544
|
+
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Get all stored output IDs.
|
|
2547
|
+
*
|
|
2548
|
+
* @returns Array of output IDs
|
|
2549
|
+
*/
|
|
2550
|
+
getIds() {
|
|
2551
|
+
return Array.from(this.outputs.keys());
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Get the number of stored outputs.
|
|
2555
|
+
*/
|
|
2556
|
+
get size() {
|
|
2557
|
+
return this.outputs.size;
|
|
2558
|
+
}
|
|
2559
|
+
/**
|
|
2560
|
+
* Clear all stored outputs.
|
|
2561
|
+
* Called when the agent run completes.
|
|
2562
|
+
*/
|
|
2563
|
+
clear() {
|
|
2564
|
+
this.outputs.clear();
|
|
2565
|
+
}
|
|
2566
|
+
/**
|
|
2567
|
+
* Generate a unique ID for a stored output.
|
|
2568
|
+
* Format: {GadgetName}_{8 hex chars}
|
|
2569
|
+
*/
|
|
2570
|
+
generateId(gadgetName) {
|
|
2571
|
+
const hex = (0, import_node_crypto2.randomBytes)(4).toString("hex");
|
|
2572
|
+
return `${gadgetName}_${hex}`;
|
|
2573
|
+
}
|
|
2574
|
+
};
|
|
2575
|
+
}
|
|
2576
|
+
});
|
|
2577
|
+
|
|
2345
2578
|
// src/agent/hook-validators.ts
|
|
2346
2579
|
function validateBeforeLLMCallAction(action) {
|
|
2347
2580
|
if (!action || typeof action !== "object" || !("action" in action)) {
|
|
@@ -2652,8 +2885,7 @@ var init_schema_introspector = __esm({
|
|
|
2652
2885
|
const values = def?.values;
|
|
2653
2886
|
const value = values?.[0] ?? def?.value;
|
|
2654
2887
|
if (typeof value === "string") return "string";
|
|
2655
|
-
if (typeof value === "number" || typeof value === "bigint")
|
|
2656
|
-
return "number";
|
|
2888
|
+
if (typeof value === "number" || typeof value === "bigint") return "number";
|
|
2657
2889
|
if (typeof value === "boolean") return "boolean";
|
|
2658
2890
|
return "unknown";
|
|
2659
2891
|
}
|
|
@@ -2925,7 +3157,13 @@ var init_cost_reporting_client = __esm({
|
|
|
2925
3157
|
cacheCreationInputTokens = chunk.usage.cacheCreationInputTokens ?? 0;
|
|
2926
3158
|
}
|
|
2927
3159
|
}
|
|
2928
|
-
this.reportCostFromUsage(
|
|
3160
|
+
this.reportCostFromUsage(
|
|
3161
|
+
model,
|
|
3162
|
+
inputTokens,
|
|
3163
|
+
outputTokens,
|
|
3164
|
+
cachedInputTokens,
|
|
3165
|
+
cacheCreationInputTokens
|
|
3166
|
+
);
|
|
2929
3167
|
return result;
|
|
2930
3168
|
}
|
|
2931
3169
|
/**
|
|
@@ -2965,7 +3203,13 @@ var init_cost_reporting_client = __esm({
|
|
|
2965
3203
|
}
|
|
2966
3204
|
}
|
|
2967
3205
|
} finally {
|
|
2968
|
-
this.reportCostFromUsage(
|
|
3206
|
+
this.reportCostFromUsage(
|
|
3207
|
+
model,
|
|
3208
|
+
inputTokens,
|
|
3209
|
+
outputTokens,
|
|
3210
|
+
cachedInputTokens,
|
|
3211
|
+
cacheCreationInputTokens
|
|
3212
|
+
);
|
|
2969
3213
|
}
|
|
2970
3214
|
}
|
|
2971
3215
|
/**
|
|
@@ -3003,7 +3247,13 @@ var init_cost_reporting_client = __esm({
|
|
|
3003
3247
|
}
|
|
3004
3248
|
} finally {
|
|
3005
3249
|
if (inputTokens > 0 || outputTokens > 0) {
|
|
3006
|
-
reportCostFromUsage(
|
|
3250
|
+
reportCostFromUsage(
|
|
3251
|
+
model,
|
|
3252
|
+
inputTokens,
|
|
3253
|
+
outputTokens,
|
|
3254
|
+
cachedInputTokens,
|
|
3255
|
+
cacheCreationInputTokens
|
|
3256
|
+
);
|
|
3007
3257
|
}
|
|
3008
3258
|
}
|
|
3009
3259
|
}
|
|
@@ -3031,12 +3281,12 @@ var init_cost_reporting_client = __esm({
|
|
|
3031
3281
|
});
|
|
3032
3282
|
|
|
3033
3283
|
// src/gadgets/error-formatter.ts
|
|
3034
|
-
var
|
|
3284
|
+
var GadgetExecutionErrorFormatter;
|
|
3035
3285
|
var init_error_formatter = __esm({
|
|
3036
3286
|
"src/gadgets/error-formatter.ts"() {
|
|
3037
3287
|
"use strict";
|
|
3038
3288
|
init_constants();
|
|
3039
|
-
|
|
3289
|
+
GadgetExecutionErrorFormatter = class {
|
|
3040
3290
|
argPrefix;
|
|
3041
3291
|
startPrefix;
|
|
3042
3292
|
endPrefix;
|
|
@@ -3122,16 +3372,16 @@ function stripMarkdownFences(content) {
|
|
|
3122
3372
|
cleaned = cleaned.replace(closingFence, "");
|
|
3123
3373
|
return cleaned.trim();
|
|
3124
3374
|
}
|
|
3125
|
-
var globalInvocationCounter,
|
|
3375
|
+
var globalInvocationCounter, GadgetCallParser;
|
|
3126
3376
|
var init_parser = __esm({
|
|
3127
3377
|
"src/gadgets/parser.ts"() {
|
|
3128
3378
|
"use strict";
|
|
3129
3379
|
init_constants();
|
|
3130
3380
|
init_block_params();
|
|
3131
3381
|
globalInvocationCounter = 0;
|
|
3132
|
-
|
|
3382
|
+
GadgetCallParser = class {
|
|
3133
3383
|
buffer = "";
|
|
3134
|
-
|
|
3384
|
+
lastEmittedTextOffset = 0;
|
|
3135
3385
|
startPrefix;
|
|
3136
3386
|
endPrefix;
|
|
3137
3387
|
argPrefix;
|
|
@@ -3140,16 +3390,20 @@ var init_parser = __esm({
|
|
|
3140
3390
|
this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
|
|
3141
3391
|
this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
|
|
3142
3392
|
}
|
|
3143
|
-
|
|
3144
|
-
|
|
3393
|
+
/**
|
|
3394
|
+
* Extract and consume text up to the given index.
|
|
3395
|
+
* Returns undefined if no meaningful text to emit.
|
|
3396
|
+
*/
|
|
3397
|
+
extractTextSegment(index) {
|
|
3398
|
+
if (index <= this.lastEmittedTextOffset) {
|
|
3145
3399
|
return void 0;
|
|
3146
3400
|
}
|
|
3147
|
-
const segment = this.buffer.slice(this.
|
|
3148
|
-
this.
|
|
3401
|
+
const segment = this.buffer.slice(this.lastEmittedTextOffset, index);
|
|
3402
|
+
this.lastEmittedTextOffset = index;
|
|
3149
3403
|
return segment.trim().length > 0 ? segment : void 0;
|
|
3150
3404
|
}
|
|
3151
3405
|
/**
|
|
3152
|
-
* Parse gadget
|
|
3406
|
+
* Parse gadget invocation metadata from the header line.
|
|
3153
3407
|
*
|
|
3154
3408
|
* Supported formats:
|
|
3155
3409
|
* - `GadgetName` - Auto-generate ID, no dependencies
|
|
@@ -3158,24 +3412,24 @@ var init_parser = __esm({
|
|
|
3158
3412
|
*
|
|
3159
3413
|
* Dependencies must be comma-separated invocation IDs.
|
|
3160
3414
|
*/
|
|
3161
|
-
|
|
3162
|
-
const parts =
|
|
3415
|
+
parseInvocationMetadata(headerLine) {
|
|
3416
|
+
const parts = headerLine.split(":");
|
|
3163
3417
|
if (parts.length === 1) {
|
|
3164
3418
|
return {
|
|
3165
|
-
|
|
3419
|
+
gadgetName: parts[0],
|
|
3166
3420
|
invocationId: `gadget_${++globalInvocationCounter}`,
|
|
3167
3421
|
dependencies: []
|
|
3168
3422
|
};
|
|
3169
3423
|
} else if (parts.length === 2) {
|
|
3170
3424
|
return {
|
|
3171
|
-
|
|
3425
|
+
gadgetName: parts[0],
|
|
3172
3426
|
invocationId: parts[1].trim(),
|
|
3173
3427
|
dependencies: []
|
|
3174
3428
|
};
|
|
3175
3429
|
} else {
|
|
3176
3430
|
const deps = parts[2].split(",").map((d) => d.trim()).filter((d) => d.length > 0);
|
|
3177
3431
|
return {
|
|
3178
|
-
|
|
3432
|
+
gadgetName: parts[0],
|
|
3179
3433
|
invocationId: parts[1].trim(),
|
|
3180
3434
|
dependencies: deps
|
|
3181
3435
|
};
|
|
@@ -3207,15 +3461,15 @@ var init_parser = __esm({
|
|
|
3207
3461
|
while (true) {
|
|
3208
3462
|
const partStartIndex = this.buffer.indexOf(this.startPrefix, startIndex);
|
|
3209
3463
|
if (partStartIndex === -1) break;
|
|
3210
|
-
const textBefore = this.
|
|
3464
|
+
const textBefore = this.extractTextSegment(partStartIndex);
|
|
3211
3465
|
if (textBefore !== void 0) {
|
|
3212
3466
|
yield { type: "text", content: textBefore };
|
|
3213
3467
|
}
|
|
3214
3468
|
const metadataStartIndex = partStartIndex + this.startPrefix.length;
|
|
3215
3469
|
const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
|
|
3216
3470
|
if (metadataEndIndex === -1) break;
|
|
3217
|
-
const
|
|
3218
|
-
const {
|
|
3471
|
+
const headerLine = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
|
|
3472
|
+
const { gadgetName, invocationId, dependencies } = this.parseInvocationMetadata(headerLine);
|
|
3219
3473
|
const contentStartIndex = metadataEndIndex + 1;
|
|
3220
3474
|
let partEndIndex;
|
|
3221
3475
|
let endMarkerLength = 0;
|
|
@@ -3235,7 +3489,7 @@ var init_parser = __esm({
|
|
|
3235
3489
|
yield {
|
|
3236
3490
|
type: "gadget_call",
|
|
3237
3491
|
call: {
|
|
3238
|
-
gadgetName
|
|
3492
|
+
gadgetName,
|
|
3239
3493
|
invocationId,
|
|
3240
3494
|
parametersRaw,
|
|
3241
3495
|
parameters,
|
|
@@ -3244,33 +3498,33 @@ var init_parser = __esm({
|
|
|
3244
3498
|
}
|
|
3245
3499
|
};
|
|
3246
3500
|
startIndex = partEndIndex + endMarkerLength;
|
|
3247
|
-
this.
|
|
3501
|
+
this.lastEmittedTextOffset = startIndex;
|
|
3248
3502
|
}
|
|
3249
3503
|
if (startIndex > 0) {
|
|
3250
3504
|
this.buffer = this.buffer.substring(startIndex);
|
|
3251
|
-
this.
|
|
3505
|
+
this.lastEmittedTextOffset = 0;
|
|
3252
3506
|
}
|
|
3253
3507
|
}
|
|
3254
3508
|
// Finalize parsing and return remaining text or incomplete gadgets
|
|
3255
3509
|
*finalize() {
|
|
3256
|
-
const startIndex = this.buffer.indexOf(this.startPrefix, this.
|
|
3510
|
+
const startIndex = this.buffer.indexOf(this.startPrefix, this.lastEmittedTextOffset);
|
|
3257
3511
|
if (startIndex !== -1) {
|
|
3258
|
-
const textBefore = this.
|
|
3512
|
+
const textBefore = this.extractTextSegment(startIndex);
|
|
3259
3513
|
if (textBefore !== void 0) {
|
|
3260
3514
|
yield { type: "text", content: textBefore };
|
|
3261
3515
|
}
|
|
3262
3516
|
const metadataStartIndex = startIndex + this.startPrefix.length;
|
|
3263
3517
|
const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
|
|
3264
3518
|
if (metadataEndIndex !== -1) {
|
|
3265
|
-
const
|
|
3266
|
-
const {
|
|
3519
|
+
const headerLine = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
|
|
3520
|
+
const { gadgetName, invocationId, dependencies } = this.parseInvocationMetadata(headerLine);
|
|
3267
3521
|
const contentStartIndex = metadataEndIndex + 1;
|
|
3268
3522
|
const parametersRaw = this.buffer.substring(contentStartIndex).trim();
|
|
3269
3523
|
const { parameters, parseError } = this.parseParameters(parametersRaw);
|
|
3270
3524
|
yield {
|
|
3271
3525
|
type: "gadget_call",
|
|
3272
3526
|
call: {
|
|
3273
|
-
gadgetName
|
|
3527
|
+
gadgetName,
|
|
3274
3528
|
invocationId,
|
|
3275
3529
|
parametersRaw,
|
|
3276
3530
|
parameters,
|
|
@@ -3281,7 +3535,7 @@ var init_parser = __esm({
|
|
|
3281
3535
|
return;
|
|
3282
3536
|
}
|
|
3283
3537
|
}
|
|
3284
|
-
const remainingText = this.
|
|
3538
|
+
const remainingText = this.extractTextSegment(this.buffer.length);
|
|
3285
3539
|
if (remainingText !== void 0) {
|
|
3286
3540
|
yield { type: "text", content: remainingText };
|
|
3287
3541
|
}
|
|
@@ -3289,7 +3543,7 @@ var init_parser = __esm({
|
|
|
3289
3543
|
// Reset parser state (note: global invocation counter is NOT reset to ensure unique IDs)
|
|
3290
3544
|
reset() {
|
|
3291
3545
|
this.buffer = "";
|
|
3292
|
-
this.
|
|
3546
|
+
this.lastEmittedTextOffset = 0;
|
|
3293
3547
|
}
|
|
3294
3548
|
};
|
|
3295
3549
|
}
|
|
@@ -3308,13 +3562,16 @@ var init_executor = __esm({
|
|
|
3308
3562
|
init_exceptions();
|
|
3309
3563
|
init_parser();
|
|
3310
3564
|
GadgetExecutor = class {
|
|
3311
|
-
constructor(registry,
|
|
3565
|
+
constructor(registry, requestHumanInput, logger, defaultGadgetTimeoutMs, errorFormatterOptions, client, mediaStore, agentConfig, subagentConfig) {
|
|
3312
3566
|
this.registry = registry;
|
|
3313
|
-
this.
|
|
3567
|
+
this.requestHumanInput = requestHumanInput;
|
|
3314
3568
|
this.defaultGadgetTimeoutMs = defaultGadgetTimeoutMs;
|
|
3315
3569
|
this.client = client;
|
|
3570
|
+
this.mediaStore = mediaStore;
|
|
3571
|
+
this.agentConfig = agentConfig;
|
|
3572
|
+
this.subagentConfig = subagentConfig;
|
|
3316
3573
|
this.logger = logger ?? createLogger({ name: "llmist:executor" });
|
|
3317
|
-
this.errorFormatter = new
|
|
3574
|
+
this.errorFormatter = new GadgetExecutionErrorFormatter(errorFormatterOptions);
|
|
3318
3575
|
this.argPrefix = errorFormatterOptions?.argPrefix ?? GADGET_ARG_PREFIX;
|
|
3319
3576
|
}
|
|
3320
3577
|
logger;
|
|
@@ -3334,13 +3591,17 @@ var init_executor = __esm({
|
|
|
3334
3591
|
});
|
|
3335
3592
|
}
|
|
3336
3593
|
/**
|
|
3337
|
-
*
|
|
3338
|
-
* Handles
|
|
3594
|
+
* Unify gadget execute result to consistent internal format.
|
|
3595
|
+
* Handles string returns (backwards compat), object returns with cost,
|
|
3596
|
+
* and object returns with media.
|
|
3339
3597
|
*/
|
|
3340
|
-
|
|
3598
|
+
unifyExecuteResult(raw) {
|
|
3341
3599
|
if (typeof raw === "string") {
|
|
3342
3600
|
return { result: raw, cost: 0 };
|
|
3343
3601
|
}
|
|
3602
|
+
if ("media" in raw && raw.media) {
|
|
3603
|
+
return { result: raw.result, media: raw.media, cost: raw.cost ?? 0 };
|
|
3604
|
+
}
|
|
3344
3605
|
return { result: raw.result, cost: raw.cost ?? 0 };
|
|
3345
3606
|
}
|
|
3346
3607
|
// Execute a gadget call asynchronously
|
|
@@ -3452,7 +3713,9 @@ var init_executor = __esm({
|
|
|
3452
3713
|
const ctx = {
|
|
3453
3714
|
reportCost,
|
|
3454
3715
|
llmist: this.client ? new CostReportingLLMistWrapper(this.client, reportCost) : void 0,
|
|
3455
|
-
signal: abortController.signal
|
|
3716
|
+
signal: abortController.signal,
|
|
3717
|
+
agentConfig: this.agentConfig,
|
|
3718
|
+
subagentConfig: this.subagentConfig
|
|
3456
3719
|
};
|
|
3457
3720
|
let rawResult;
|
|
3458
3721
|
if (timeoutMs && timeoutMs > 0) {
|
|
@@ -3467,8 +3730,21 @@ var init_executor = __esm({
|
|
|
3467
3730
|
} else {
|
|
3468
3731
|
rawResult = await Promise.resolve(gadget.execute(validatedParameters, ctx));
|
|
3469
3732
|
}
|
|
3470
|
-
const { result, cost: returnCost } = this.
|
|
3733
|
+
const { result, media, cost: returnCost } = this.unifyExecuteResult(rawResult);
|
|
3471
3734
|
const totalCost = callbackCost + returnCost;
|
|
3735
|
+
let mediaIds;
|
|
3736
|
+
let storedMedia;
|
|
3737
|
+
if (media && media.length > 0 && this.mediaStore) {
|
|
3738
|
+
storedMedia = await Promise.all(
|
|
3739
|
+
media.map((item) => this.mediaStore.store(item, call.gadgetName))
|
|
3740
|
+
);
|
|
3741
|
+
mediaIds = storedMedia.map((m) => m.id);
|
|
3742
|
+
this.logger.debug("Stored media outputs", {
|
|
3743
|
+
gadgetName: call.gadgetName,
|
|
3744
|
+
mediaIds,
|
|
3745
|
+
count: media.length
|
|
3746
|
+
});
|
|
3747
|
+
}
|
|
3472
3748
|
const executionTimeMs = Date.now() - startTime;
|
|
3473
3749
|
this.logger.info("Gadget executed successfully", {
|
|
3474
3750
|
gadgetName: call.gadgetName,
|
|
@@ -3476,7 +3752,8 @@ var init_executor = __esm({
|
|
|
3476
3752
|
executionTimeMs,
|
|
3477
3753
|
cost: totalCost > 0 ? totalCost : void 0,
|
|
3478
3754
|
callbackCost: callbackCost > 0 ? callbackCost : void 0,
|
|
3479
|
-
returnCost: returnCost > 0 ? returnCost : void 0
|
|
3755
|
+
returnCost: returnCost > 0 ? returnCost : void 0,
|
|
3756
|
+
mediaCount: media?.length
|
|
3480
3757
|
});
|
|
3481
3758
|
this.logger.debug("Gadget result", {
|
|
3482
3759
|
gadgetName: call.gadgetName,
|
|
@@ -3484,7 +3761,8 @@ var init_executor = __esm({
|
|
|
3484
3761
|
parameters: validatedParameters,
|
|
3485
3762
|
result,
|
|
3486
3763
|
cost: totalCost,
|
|
3487
|
-
executionTimeMs
|
|
3764
|
+
executionTimeMs,
|
|
3765
|
+
mediaIds
|
|
3488
3766
|
});
|
|
3489
3767
|
return {
|
|
3490
3768
|
gadgetName: call.gadgetName,
|
|
@@ -3492,10 +3770,13 @@ var init_executor = __esm({
|
|
|
3492
3770
|
parameters: validatedParameters,
|
|
3493
3771
|
result,
|
|
3494
3772
|
executionTimeMs,
|
|
3495
|
-
cost: totalCost
|
|
3773
|
+
cost: totalCost,
|
|
3774
|
+
media,
|
|
3775
|
+
mediaIds,
|
|
3776
|
+
storedMedia
|
|
3496
3777
|
};
|
|
3497
3778
|
} catch (error) {
|
|
3498
|
-
if (error instanceof
|
|
3779
|
+
if (error instanceof TaskCompletionSignal) {
|
|
3499
3780
|
this.logger.info("Gadget requested loop termination", {
|
|
3500
3781
|
gadgetName: call.gadgetName,
|
|
3501
3782
|
message: error.message
|
|
@@ -3523,7 +3804,7 @@ var init_executor = __esm({
|
|
|
3523
3804
|
executionTimeMs: Date.now() - startTime
|
|
3524
3805
|
};
|
|
3525
3806
|
}
|
|
3526
|
-
if (error instanceof
|
|
3807
|
+
if (error instanceof AbortException) {
|
|
3527
3808
|
this.logger.info("Gadget execution was aborted", {
|
|
3528
3809
|
gadgetName: call.gadgetName,
|
|
3529
3810
|
executionTimeMs: Date.now() - startTime
|
|
@@ -3536,14 +3817,14 @@ var init_executor = __esm({
|
|
|
3536
3817
|
executionTimeMs: Date.now() - startTime
|
|
3537
3818
|
};
|
|
3538
3819
|
}
|
|
3539
|
-
if (error instanceof
|
|
3820
|
+
if (error instanceof HumanInputRequiredException) {
|
|
3540
3821
|
this.logger.info("Gadget requested human input", {
|
|
3541
3822
|
gadgetName: call.gadgetName,
|
|
3542
3823
|
question: error.question
|
|
3543
3824
|
});
|
|
3544
|
-
if (this.
|
|
3825
|
+
if (this.requestHumanInput) {
|
|
3545
3826
|
try {
|
|
3546
|
-
const answer = await this.
|
|
3827
|
+
const answer = await this.requestHumanInput(error.question);
|
|
3547
3828
|
this.logger.debug("Human input received", {
|
|
3548
3829
|
gadgetName: call.gadgetName,
|
|
3549
3830
|
answerLength: answer.length
|
|
@@ -3641,13 +3922,13 @@ var init_stream_processor = __esm({
|
|
|
3641
3922
|
parser;
|
|
3642
3923
|
executor;
|
|
3643
3924
|
stopOnGadgetError;
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3925
|
+
canRecoverFromGadgetError;
|
|
3926
|
+
responseText = "";
|
|
3927
|
+
executionHalted = false;
|
|
3647
3928
|
observerFailureCount = 0;
|
|
3648
3929
|
// Dependency tracking for gadget execution DAG
|
|
3649
3930
|
/** Gadgets waiting for their dependencies to complete */
|
|
3650
|
-
|
|
3931
|
+
gadgetsAwaitingDependencies = /* @__PURE__ */ new Map();
|
|
3651
3932
|
/** Completed gadget results, keyed by invocation ID */
|
|
3652
3933
|
completedResults = /* @__PURE__ */ new Map();
|
|
3653
3934
|
/** Invocation IDs of gadgets that have failed (error or skipped due to dependency) */
|
|
@@ -3658,19 +3939,22 @@ var init_stream_processor = __esm({
|
|
|
3658
3939
|
this.hooks = options.hooks ?? {};
|
|
3659
3940
|
this.logger = options.logger ?? createLogger({ name: "llmist:stream-processor" });
|
|
3660
3941
|
this.stopOnGadgetError = options.stopOnGadgetError ?? true;
|
|
3661
|
-
this.
|
|
3662
|
-
this.parser = new
|
|
3942
|
+
this.canRecoverFromGadgetError = options.canRecoverFromGadgetError;
|
|
3943
|
+
this.parser = new GadgetCallParser({
|
|
3663
3944
|
startPrefix: options.gadgetStartPrefix,
|
|
3664
3945
|
endPrefix: options.gadgetEndPrefix,
|
|
3665
3946
|
argPrefix: options.gadgetArgPrefix
|
|
3666
3947
|
});
|
|
3667
3948
|
this.executor = new GadgetExecutor(
|
|
3668
3949
|
options.registry,
|
|
3669
|
-
options.
|
|
3950
|
+
options.requestHumanInput,
|
|
3670
3951
|
this.logger.getSubLogger({ name: "executor" }),
|
|
3671
3952
|
options.defaultGadgetTimeoutMs,
|
|
3672
3953
|
{ argPrefix: options.gadgetArgPrefix },
|
|
3673
|
-
options.client
|
|
3954
|
+
options.client,
|
|
3955
|
+
options.mediaStore,
|
|
3956
|
+
options.agentConfig,
|
|
3957
|
+
options.subagentConfig
|
|
3674
3958
|
);
|
|
3675
3959
|
}
|
|
3676
3960
|
/**
|
|
@@ -3691,7 +3975,7 @@ var init_stream_processor = __esm({
|
|
|
3691
3975
|
if (this.hooks.interceptors?.interceptRawChunk) {
|
|
3692
3976
|
const context = {
|
|
3693
3977
|
iteration: this.iteration,
|
|
3694
|
-
accumulatedText: this.
|
|
3978
|
+
accumulatedText: this.responseText,
|
|
3695
3979
|
logger: this.logger
|
|
3696
3980
|
};
|
|
3697
3981
|
const intercepted = this.hooks.interceptors.interceptRawChunk(processedChunk, context);
|
|
@@ -3702,7 +3986,7 @@ var init_stream_processor = __esm({
|
|
|
3702
3986
|
}
|
|
3703
3987
|
}
|
|
3704
3988
|
if (processedChunk) {
|
|
3705
|
-
this.
|
|
3989
|
+
this.responseText += processedChunk;
|
|
3706
3990
|
}
|
|
3707
3991
|
}
|
|
3708
3992
|
if (this.hooks.observers?.onStreamChunk && (processedChunk || chunk.usage)) {
|
|
@@ -3711,7 +3995,7 @@ var init_stream_processor = __esm({
|
|
|
3711
3995
|
const context = {
|
|
3712
3996
|
iteration: this.iteration,
|
|
3713
3997
|
rawChunk: processedChunk,
|
|
3714
|
-
accumulatedText: this.
|
|
3998
|
+
accumulatedText: this.responseText,
|
|
3715
3999
|
usage,
|
|
3716
4000
|
logger: this.logger
|
|
3717
4001
|
};
|
|
@@ -3734,12 +4018,12 @@ var init_stream_processor = __esm({
|
|
|
3734
4018
|
}
|
|
3735
4019
|
}
|
|
3736
4020
|
}
|
|
3737
|
-
if (this.
|
|
4021
|
+
if (this.executionHalted) {
|
|
3738
4022
|
this.logger.info("Breaking from LLM stream due to gadget error");
|
|
3739
4023
|
break;
|
|
3740
4024
|
}
|
|
3741
4025
|
}
|
|
3742
|
-
if (!this.
|
|
4026
|
+
if (!this.executionHalted) {
|
|
3743
4027
|
for (const event of this.parser.finalize()) {
|
|
3744
4028
|
const processedEvents = await this.processEvent(event);
|
|
3745
4029
|
outputs.push(...processedEvents);
|
|
@@ -3763,11 +4047,11 @@ var init_stream_processor = __esm({
|
|
|
3763
4047
|
}
|
|
3764
4048
|
}
|
|
3765
4049
|
}
|
|
3766
|
-
let finalMessage = this.
|
|
4050
|
+
let finalMessage = this.responseText;
|
|
3767
4051
|
if (this.hooks.interceptors?.interceptAssistantMessage) {
|
|
3768
4052
|
const context = {
|
|
3769
4053
|
iteration: this.iteration,
|
|
3770
|
-
rawResponse: this.
|
|
4054
|
+
rawResponse: this.responseText,
|
|
3771
4055
|
logger: this.logger
|
|
3772
4056
|
};
|
|
3773
4057
|
finalMessage = this.hooks.interceptors.interceptAssistantMessage(finalMessage, context);
|
|
@@ -3778,7 +4062,7 @@ var init_stream_processor = __esm({
|
|
|
3778
4062
|
didExecuteGadgets,
|
|
3779
4063
|
finishReason,
|
|
3780
4064
|
usage,
|
|
3781
|
-
rawResponse: this.
|
|
4065
|
+
rawResponse: this.responseText,
|
|
3782
4066
|
finalMessage
|
|
3783
4067
|
};
|
|
3784
4068
|
}
|
|
@@ -3801,7 +4085,7 @@ var init_stream_processor = __esm({
|
|
|
3801
4085
|
if (this.hooks.interceptors?.interceptTextChunk) {
|
|
3802
4086
|
const context = {
|
|
3803
4087
|
iteration: this.iteration,
|
|
3804
|
-
accumulatedText: this.
|
|
4088
|
+
accumulatedText: this.responseText,
|
|
3805
4089
|
logger: this.logger
|
|
3806
4090
|
};
|
|
3807
4091
|
const intercepted = this.hooks.interceptors.interceptTextChunk(content, context);
|
|
@@ -3820,7 +4104,7 @@ var init_stream_processor = __esm({
|
|
|
3820
4104
|
* After each execution, pending gadgets are checked to see if they can now run.
|
|
3821
4105
|
*/
|
|
3822
4106
|
async processGadgetCall(call) {
|
|
3823
|
-
if (this.
|
|
4107
|
+
if (this.executionHalted) {
|
|
3824
4108
|
this.logger.debug("Skipping gadget execution due to previous error", {
|
|
3825
4109
|
gadgetName: call.gadgetName
|
|
3826
4110
|
});
|
|
@@ -3859,7 +4143,7 @@ var init_stream_processor = __esm({
|
|
|
3859
4143
|
invocationId: call.invocationId,
|
|
3860
4144
|
waitingOn: unsatisfied
|
|
3861
4145
|
});
|
|
3862
|
-
this.
|
|
4146
|
+
this.gadgetsAwaitingDependencies.set(call.invocationId, call);
|
|
3863
4147
|
return events;
|
|
3864
4148
|
}
|
|
3865
4149
|
}
|
|
@@ -3881,14 +4165,14 @@ var init_stream_processor = __esm({
|
|
|
3881
4165
|
error: call.parseError,
|
|
3882
4166
|
rawParameters: call.parametersRaw
|
|
3883
4167
|
});
|
|
3884
|
-
const shouldContinue = await this.
|
|
4168
|
+
const shouldContinue = await this.checkCanRecoverFromError(
|
|
3885
4169
|
call.parseError,
|
|
3886
4170
|
call.gadgetName,
|
|
3887
4171
|
"parse",
|
|
3888
4172
|
call.parameters
|
|
3889
4173
|
);
|
|
3890
4174
|
if (!shouldContinue) {
|
|
3891
|
-
this.
|
|
4175
|
+
this.executionHalted = true;
|
|
3892
4176
|
}
|
|
3893
4177
|
}
|
|
3894
4178
|
let parameters = call.parameters ?? {};
|
|
@@ -4012,14 +4296,14 @@ var init_stream_processor = __esm({
|
|
|
4012
4296
|
events.push({ type: "gadget_result", result });
|
|
4013
4297
|
if (result.error) {
|
|
4014
4298
|
const errorType = this.determineErrorType(call, result);
|
|
4015
|
-
const shouldContinue = await this.
|
|
4299
|
+
const shouldContinue = await this.checkCanRecoverFromError(
|
|
4016
4300
|
result.error,
|
|
4017
4301
|
result.gadgetName,
|
|
4018
4302
|
errorType,
|
|
4019
4303
|
result.parameters
|
|
4020
4304
|
);
|
|
4021
4305
|
if (!shouldContinue) {
|
|
4022
|
-
this.
|
|
4306
|
+
this.executionHalted = true;
|
|
4023
4307
|
}
|
|
4024
4308
|
}
|
|
4025
4309
|
return events;
|
|
@@ -4106,11 +4390,11 @@ var init_stream_processor = __esm({
|
|
|
4106
4390
|
async processPendingGadgets() {
|
|
4107
4391
|
const events = [];
|
|
4108
4392
|
let progress = true;
|
|
4109
|
-
while (progress && this.
|
|
4393
|
+
while (progress && this.gadgetsAwaitingDependencies.size > 0) {
|
|
4110
4394
|
progress = false;
|
|
4111
4395
|
const readyToExecute = [];
|
|
4112
4396
|
const readyToSkip = [];
|
|
4113
|
-
for (const [invocationId, call] of this.
|
|
4397
|
+
for (const [invocationId, call] of this.gadgetsAwaitingDependencies) {
|
|
4114
4398
|
const failedDep = call.dependencies.find((dep) => this.failedInvocations.has(dep));
|
|
4115
4399
|
if (failedDep) {
|
|
4116
4400
|
readyToSkip.push({ call, failedDep });
|
|
@@ -4122,7 +4406,7 @@ var init_stream_processor = __esm({
|
|
|
4122
4406
|
}
|
|
4123
4407
|
}
|
|
4124
4408
|
for (const { call, failedDep } of readyToSkip) {
|
|
4125
|
-
this.
|
|
4409
|
+
this.gadgetsAwaitingDependencies.delete(call.invocationId);
|
|
4126
4410
|
const skipEvents = await this.handleFailedDependency(call, failedDep);
|
|
4127
4411
|
events.push(...skipEvents);
|
|
4128
4412
|
progress = true;
|
|
@@ -4133,7 +4417,7 @@ var init_stream_processor = __esm({
|
|
|
4133
4417
|
invocationIds: readyToExecute.map((c) => c.invocationId)
|
|
4134
4418
|
});
|
|
4135
4419
|
for (const call of readyToExecute) {
|
|
4136
|
-
this.
|
|
4420
|
+
this.gadgetsAwaitingDependencies.delete(call.invocationId);
|
|
4137
4421
|
}
|
|
4138
4422
|
const executePromises = readyToExecute.map((call) => this.executeGadgetWithHooks(call));
|
|
4139
4423
|
const results = await Promise.all(executePromises);
|
|
@@ -4143,9 +4427,9 @@ var init_stream_processor = __esm({
|
|
|
4143
4427
|
progress = true;
|
|
4144
4428
|
}
|
|
4145
4429
|
}
|
|
4146
|
-
if (this.
|
|
4147
|
-
const pendingIds = new Set(this.
|
|
4148
|
-
for (const [invocationId, call] of this.
|
|
4430
|
+
if (this.gadgetsAwaitingDependencies.size > 0) {
|
|
4431
|
+
const pendingIds = new Set(this.gadgetsAwaitingDependencies.keys());
|
|
4432
|
+
for (const [invocationId, call] of this.gadgetsAwaitingDependencies) {
|
|
4149
4433
|
const missingDeps = call.dependencies.filter((dep) => !this.completedResults.has(dep));
|
|
4150
4434
|
const circularDeps = missingDeps.filter((dep) => pendingIds.has(dep));
|
|
4151
4435
|
const trulyMissingDeps = missingDeps.filter((dep) => !pendingIds.has(dep));
|
|
@@ -4176,7 +4460,7 @@ var init_stream_processor = __esm({
|
|
|
4176
4460
|
};
|
|
4177
4461
|
events.push(skipEvent);
|
|
4178
4462
|
}
|
|
4179
|
-
this.
|
|
4463
|
+
this.gadgetsAwaitingDependencies.clear();
|
|
4180
4464
|
}
|
|
4181
4465
|
return events;
|
|
4182
4466
|
}
|
|
@@ -4206,19 +4490,19 @@ var init_stream_processor = __esm({
|
|
|
4206
4490
|
);
|
|
4207
4491
|
}
|
|
4208
4492
|
/**
|
|
4209
|
-
* Check if execution
|
|
4493
|
+
* Check if execution can recover from an error.
|
|
4210
4494
|
*
|
|
4211
4495
|
* Returns true if we should continue processing subsequent gadgets, false if we should stop.
|
|
4212
4496
|
*
|
|
4213
4497
|
* Logic:
|
|
4214
|
-
* - If custom
|
|
4498
|
+
* - If custom canRecoverFromGadgetError is provided, use it
|
|
4215
4499
|
* - Otherwise, use stopOnGadgetError config:
|
|
4216
4500
|
* - stopOnGadgetError=true → return false (stop execution)
|
|
4217
4501
|
* - stopOnGadgetError=false → return true (continue execution)
|
|
4218
4502
|
*/
|
|
4219
|
-
async
|
|
4220
|
-
if (this.
|
|
4221
|
-
return await this.
|
|
4503
|
+
async checkCanRecoverFromError(error, gadgetName, errorType, parameters) {
|
|
4504
|
+
if (this.canRecoverFromGadgetError) {
|
|
4505
|
+
return await this.canRecoverFromGadgetError({
|
|
4222
4506
|
error,
|
|
4223
4507
|
gadgetName,
|
|
4224
4508
|
errorType,
|
|
@@ -4259,13 +4543,14 @@ var init_agent = __esm({
|
|
|
4259
4543
|
init_constants();
|
|
4260
4544
|
init_messages();
|
|
4261
4545
|
init_model_shortcuts();
|
|
4546
|
+
init_media_store();
|
|
4262
4547
|
init_output_viewer();
|
|
4263
4548
|
init_logger();
|
|
4264
|
-
init_manager();
|
|
4265
|
-
init_gadget_output_store();
|
|
4266
4549
|
init_agent_internal_key();
|
|
4550
|
+
init_manager();
|
|
4267
4551
|
init_conversation_manager();
|
|
4268
4552
|
init_event_handlers();
|
|
4553
|
+
init_gadget_output_store();
|
|
4269
4554
|
init_hook_validators();
|
|
4270
4555
|
init_stream_processor();
|
|
4271
4556
|
Agent = class {
|
|
@@ -4280,22 +4565,27 @@ var init_agent = __esm({
|
|
|
4280
4565
|
gadgetStartPrefix;
|
|
4281
4566
|
gadgetEndPrefix;
|
|
4282
4567
|
gadgetArgPrefix;
|
|
4283
|
-
|
|
4568
|
+
requestHumanInput;
|
|
4284
4569
|
textOnlyHandler;
|
|
4285
4570
|
textWithGadgetsHandler;
|
|
4286
4571
|
stopOnGadgetError;
|
|
4287
|
-
|
|
4572
|
+
canRecoverFromGadgetError;
|
|
4288
4573
|
defaultGadgetTimeoutMs;
|
|
4289
4574
|
defaultMaxTokens;
|
|
4290
|
-
|
|
4575
|
+
hasUserPrompt;
|
|
4291
4576
|
// Gadget output limiting
|
|
4292
4577
|
outputStore;
|
|
4293
4578
|
outputLimitEnabled;
|
|
4294
4579
|
outputLimitCharLimit;
|
|
4295
4580
|
// Context compaction
|
|
4296
4581
|
compactionManager;
|
|
4582
|
+
// Media storage (for gadgets returning images, audio, etc.)
|
|
4583
|
+
mediaStore;
|
|
4297
4584
|
// Cancellation
|
|
4298
4585
|
signal;
|
|
4586
|
+
// Subagent configuration
|
|
4587
|
+
agentContextConfig;
|
|
4588
|
+
subagentConfig;
|
|
4299
4589
|
/**
|
|
4300
4590
|
* Creates a new Agent instance.
|
|
4301
4591
|
* @internal This constructor is private. Use LLMist.createAgent() or AgentBuilder instead.
|
|
@@ -4315,15 +4605,16 @@ var init_agent = __esm({
|
|
|
4315
4605
|
this.gadgetStartPrefix = options.gadgetStartPrefix;
|
|
4316
4606
|
this.gadgetEndPrefix = options.gadgetEndPrefix;
|
|
4317
4607
|
this.gadgetArgPrefix = options.gadgetArgPrefix;
|
|
4318
|
-
this.
|
|
4608
|
+
this.requestHumanInput = options.requestHumanInput;
|
|
4319
4609
|
this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
|
|
4320
4610
|
this.textWithGadgetsHandler = options.textWithGadgetsHandler;
|
|
4321
4611
|
this.stopOnGadgetError = options.stopOnGadgetError ?? true;
|
|
4322
|
-
this.
|
|
4612
|
+
this.canRecoverFromGadgetError = options.canRecoverFromGadgetError;
|
|
4323
4613
|
this.defaultGadgetTimeoutMs = options.defaultGadgetTimeoutMs;
|
|
4324
4614
|
this.defaultMaxTokens = this.resolveMaxTokensFromCatalog(options.model);
|
|
4325
4615
|
this.outputLimitEnabled = options.gadgetOutputLimit ?? DEFAULT_GADGET_OUTPUT_LIMIT;
|
|
4326
4616
|
this.outputStore = new GadgetOutputStore();
|
|
4617
|
+
this.mediaStore = new MediaStore();
|
|
4327
4618
|
const limitPercent = options.gadgetOutputLimitPercent ?? DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT;
|
|
4328
4619
|
const limits = this.client.modelRegistry.getModelLimits(this.model);
|
|
4329
4620
|
const contextWindow = limits?.contextWindow ?? FALLBACK_CONTEXT_WINDOW;
|
|
@@ -4334,7 +4625,7 @@ var init_agent = __esm({
|
|
|
4334
4625
|
createGadgetOutputViewer(this.outputStore, this.outputLimitCharLimit)
|
|
4335
4626
|
);
|
|
4336
4627
|
}
|
|
4337
|
-
this.hooks = this.
|
|
4628
|
+
this.hooks = this.chainOutputLimiterWithUserHooks(options.hooks);
|
|
4338
4629
|
const baseBuilder = new LLMMessageBuilder(options.promptConfig);
|
|
4339
4630
|
if (options.systemPrompt) {
|
|
4340
4631
|
baseBuilder.addSystem(options.systemPrompt);
|
|
@@ -4354,7 +4645,7 @@ var init_agent = __esm({
|
|
|
4354
4645
|
endPrefix: options.gadgetEndPrefix,
|
|
4355
4646
|
argPrefix: options.gadgetArgPrefix
|
|
4356
4647
|
});
|
|
4357
|
-
this.
|
|
4648
|
+
this.hasUserPrompt = !!options.userPrompt;
|
|
4358
4649
|
if (options.userPrompt) {
|
|
4359
4650
|
this.conversation.addUserMessage(options.userPrompt);
|
|
4360
4651
|
}
|
|
@@ -4367,6 +4658,11 @@ var init_agent = __esm({
|
|
|
4367
4658
|
);
|
|
4368
4659
|
}
|
|
4369
4660
|
this.signal = options.signal;
|
|
4661
|
+
this.agentContextConfig = {
|
|
4662
|
+
model: this.model,
|
|
4663
|
+
temperature: this.temperature
|
|
4664
|
+
};
|
|
4665
|
+
this.subagentConfig = options.subagentConfig;
|
|
4370
4666
|
}
|
|
4371
4667
|
/**
|
|
4372
4668
|
* Get the gadget registry for this agent.
|
|
@@ -4389,6 +4685,36 @@ var init_agent = __esm({
|
|
|
4389
4685
|
getRegistry() {
|
|
4390
4686
|
return this.registry;
|
|
4391
4687
|
}
|
|
4688
|
+
/**
|
|
4689
|
+
* Get the media store for this agent session.
|
|
4690
|
+
*
|
|
4691
|
+
* The media store holds all media outputs (images, audio, etc.) produced by gadgets
|
|
4692
|
+
* during this agent's execution. Use this to:
|
|
4693
|
+
* - Access stored media files by ID
|
|
4694
|
+
* - List all stored media
|
|
4695
|
+
* - Clean up temporary files after execution
|
|
4696
|
+
*
|
|
4697
|
+
* @returns The MediaStore instance for this agent
|
|
4698
|
+
*
|
|
4699
|
+
* @example
|
|
4700
|
+
* ```typescript
|
|
4701
|
+
* const agent = new AgentBuilder()
|
|
4702
|
+
* .withModel("sonnet")
|
|
4703
|
+
* .build();
|
|
4704
|
+
*
|
|
4705
|
+
* // After execution, access stored media
|
|
4706
|
+
* const store = agent.getMediaStore();
|
|
4707
|
+
* for (const media of store.list()) {
|
|
4708
|
+
* console.log(`${media.id}: ${media.path}`);
|
|
4709
|
+
* }
|
|
4710
|
+
*
|
|
4711
|
+
* // Clean up when done
|
|
4712
|
+
* await store.cleanup();
|
|
4713
|
+
* ```
|
|
4714
|
+
*/
|
|
4715
|
+
getMediaStore() {
|
|
4716
|
+
return this.mediaStore;
|
|
4717
|
+
}
|
|
4392
4718
|
/**
|
|
4393
4719
|
* Manually trigger context compaction.
|
|
4394
4720
|
*
|
|
@@ -4443,7 +4769,7 @@ var init_agent = __esm({
|
|
|
4443
4769
|
* @throws {Error} If no user prompt was provided (when using build() without ask())
|
|
4444
4770
|
*/
|
|
4445
4771
|
async *run() {
|
|
4446
|
-
if (!this.
|
|
4772
|
+
if (!this.hasUserPrompt) {
|
|
4447
4773
|
throw new Error(
|
|
4448
4774
|
"No user prompt provided. Use .ask(prompt) instead of .build(), or call agent.run() after providing a prompt."
|
|
4449
4775
|
);
|
|
@@ -4560,11 +4886,14 @@ var init_agent = __esm({
|
|
|
4560
4886
|
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
4561
4887
|
hooks: this.hooks,
|
|
4562
4888
|
logger: this.logger.getSubLogger({ name: "stream-processor" }),
|
|
4563
|
-
|
|
4889
|
+
requestHumanInput: this.requestHumanInput,
|
|
4564
4890
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
4565
|
-
|
|
4891
|
+
canRecoverFromGadgetError: this.canRecoverFromGadgetError,
|
|
4566
4892
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
4567
|
-
client: this.client
|
|
4893
|
+
client: this.client,
|
|
4894
|
+
mediaStore: this.mediaStore,
|
|
4895
|
+
agentConfig: this.agentContextConfig,
|
|
4896
|
+
subagentConfig: this.subagentConfig
|
|
4568
4897
|
});
|
|
4569
4898
|
const result = await processor.process(stream2);
|
|
4570
4899
|
for (const output of result.outputs) {
|
|
@@ -4617,19 +4946,21 @@ var init_agent = __esm({
|
|
|
4617
4946
|
if (msg.role === "user") {
|
|
4618
4947
|
this.conversation.addUserMessage(msg.content);
|
|
4619
4948
|
} else if (msg.role === "assistant") {
|
|
4620
|
-
this.conversation.addAssistantMessage(
|
|
4949
|
+
this.conversation.addAssistantMessage(extractMessageText(msg.content));
|
|
4621
4950
|
} else if (msg.role === "system") {
|
|
4622
|
-
this.conversation.addUserMessage(`[System] ${
|
|
4951
|
+
this.conversation.addUserMessage(`[System] ${extractMessageText(msg.content)}`);
|
|
4623
4952
|
}
|
|
4624
4953
|
}
|
|
4625
4954
|
}
|
|
4626
4955
|
}
|
|
4627
4956
|
if (result.didExecuteGadgets) {
|
|
4628
4957
|
if (this.textWithGadgetsHandler) {
|
|
4629
|
-
const textContent = result.outputs.filter(
|
|
4958
|
+
const textContent = result.outputs.filter(
|
|
4959
|
+
(output) => output.type === "text"
|
|
4960
|
+
).map((output) => output.content).join("");
|
|
4630
4961
|
if (textContent.trim()) {
|
|
4631
4962
|
const { gadgetName, parameterMapping, resultMapping } = this.textWithGadgetsHandler;
|
|
4632
|
-
this.conversation.
|
|
4963
|
+
this.conversation.addGadgetCallResult(
|
|
4633
4964
|
gadgetName,
|
|
4634
4965
|
parameterMapping(textContent),
|
|
4635
4966
|
resultMapping ? resultMapping(textContent) : textContent
|
|
@@ -4639,16 +4970,18 @@ var init_agent = __esm({
|
|
|
4639
4970
|
for (const output of result.outputs) {
|
|
4640
4971
|
if (output.type === "gadget_result") {
|
|
4641
4972
|
const gadgetResult = output.result;
|
|
4642
|
-
this.conversation.
|
|
4973
|
+
this.conversation.addGadgetCallResult(
|
|
4643
4974
|
gadgetResult.gadgetName,
|
|
4644
4975
|
gadgetResult.parameters,
|
|
4645
|
-
gadgetResult.error ?? gadgetResult.result ?? ""
|
|
4976
|
+
gadgetResult.error ?? gadgetResult.result ?? "",
|
|
4977
|
+
gadgetResult.media,
|
|
4978
|
+
gadgetResult.mediaIds
|
|
4646
4979
|
);
|
|
4647
4980
|
}
|
|
4648
4981
|
}
|
|
4649
4982
|
} else {
|
|
4650
4983
|
if (finalMessage.trim()) {
|
|
4651
|
-
this.conversation.
|
|
4984
|
+
this.conversation.addGadgetCallResult(
|
|
4652
4985
|
"TellUser",
|
|
4653
4986
|
{ message: finalMessage, done: false, type: "info" },
|
|
4654
4987
|
`\u2139\uFE0F ${finalMessage}`
|
|
@@ -4774,10 +5107,10 @@ var init_agent = __esm({
|
|
|
4774
5107
|
return this.client.modelRegistry.getModelLimits(unprefixedModelId)?.maxOutputTokens;
|
|
4775
5108
|
}
|
|
4776
5109
|
/**
|
|
4777
|
-
*
|
|
5110
|
+
* Chain the output limiter interceptor with user-provided hooks.
|
|
4778
5111
|
* The limiter runs first, then chains to any user interceptor.
|
|
4779
5112
|
*/
|
|
4780
|
-
|
|
5113
|
+
chainOutputLimiterWithUserHooks(userHooks) {
|
|
4781
5114
|
if (!this.outputLimitEnabled) {
|
|
4782
5115
|
return userHooks ?? {};
|
|
4783
5116
|
}
|
|
@@ -5131,9 +5464,9 @@ var init_base_provider = __esm({
|
|
|
5131
5464
|
*/
|
|
5132
5465
|
async *stream(options, descriptor, spec) {
|
|
5133
5466
|
const preparedMessages = this.prepareMessages(options.messages);
|
|
5134
|
-
const payload = this.
|
|
5467
|
+
const payload = this.buildApiRequest(options, descriptor, spec, preparedMessages);
|
|
5135
5468
|
const rawStream = await this.executeStreamRequest(payload, options.signal);
|
|
5136
|
-
yield* this.
|
|
5469
|
+
yield* this.normalizeProviderStream(rawStream);
|
|
5137
5470
|
}
|
|
5138
5471
|
/**
|
|
5139
5472
|
* Prepare messages for the request.
|
|
@@ -5233,11 +5566,11 @@ var init_anthropic = __esm({
|
|
|
5233
5566
|
"Anthropic does not support speech generation. Use OpenAI (TTS) or Google Gemini (TTS) instead."
|
|
5234
5567
|
);
|
|
5235
5568
|
}
|
|
5236
|
-
|
|
5569
|
+
buildApiRequest(options, descriptor, spec, messages) {
|
|
5237
5570
|
const systemMessages = messages.filter((message) => message.role === "system");
|
|
5238
5571
|
const system = systemMessages.length > 0 ? systemMessages.map((m, index) => ({
|
|
5239
5572
|
type: "text",
|
|
5240
|
-
text:
|
|
5573
|
+
text: extractMessageText(m.content),
|
|
5241
5574
|
// Add cache_control to the LAST system message block
|
|
5242
5575
|
...index === systemMessages.length - 1 ? { cache_control: { type: "ephemeral" } } : {}
|
|
5243
5576
|
})) : void 0;
|
|
@@ -5274,7 +5607,7 @@ var init_anthropic = __esm({
|
|
|
5274
5607
|
* Handles text, images (base64 only), and applies cache_control.
|
|
5275
5608
|
*/
|
|
5276
5609
|
convertToAnthropicContent(content, addCacheControl) {
|
|
5277
|
-
const parts =
|
|
5610
|
+
const parts = normalizeMessageContent(content);
|
|
5278
5611
|
return parts.map((part, index) => {
|
|
5279
5612
|
const isLastPart = index === parts.length - 1;
|
|
5280
5613
|
const cacheControl = addCacheControl && isLastPart ? { cache_control: { type: "ephemeral" } } : {};
|
|
@@ -5320,7 +5653,7 @@ var init_anthropic = __esm({
|
|
|
5320
5653
|
const stream2 = await client.messages.create(payload, signal ? { signal } : void 0);
|
|
5321
5654
|
return stream2;
|
|
5322
5655
|
}
|
|
5323
|
-
async *
|
|
5656
|
+
async *normalizeProviderStream(iterable) {
|
|
5324
5657
|
const stream2 = iterable;
|
|
5325
5658
|
let inputTokens = 0;
|
|
5326
5659
|
let cachedInputTokens = 0;
|
|
@@ -5397,7 +5730,7 @@ var init_anthropic = __esm({
|
|
|
5397
5730
|
async countTokens(messages, descriptor, _spec) {
|
|
5398
5731
|
const client = this.client;
|
|
5399
5732
|
const systemMessages = messages.filter((message) => message.role === "system");
|
|
5400
|
-
const system = systemMessages.length > 0 ? systemMessages.map((m) =>
|
|
5733
|
+
const system = systemMessages.length > 0 ? systemMessages.map((m) => extractMessageText(m.content)).join("\n\n") : void 0;
|
|
5401
5734
|
const conversation = messages.filter(
|
|
5402
5735
|
(message) => message.role !== "system"
|
|
5403
5736
|
).map((message) => ({
|
|
@@ -5419,7 +5752,7 @@ var init_anthropic = __esm({
|
|
|
5419
5752
|
let totalChars = 0;
|
|
5420
5753
|
let imageCount = 0;
|
|
5421
5754
|
for (const msg of messages) {
|
|
5422
|
-
const parts =
|
|
5755
|
+
const parts = normalizeMessageContent(msg.content);
|
|
5423
5756
|
for (const part of parts) {
|
|
5424
5757
|
if (part.type === "text") {
|
|
5425
5758
|
totalChars += part.text.length;
|
|
@@ -6110,7 +6443,7 @@ var init_gemini = __esm({
|
|
|
6110
6443
|
format: spec?.defaultFormat ?? "wav"
|
|
6111
6444
|
};
|
|
6112
6445
|
}
|
|
6113
|
-
|
|
6446
|
+
buildApiRequest(options, descriptor, _spec, messages) {
|
|
6114
6447
|
const contents = this.convertMessagesToContents(messages);
|
|
6115
6448
|
const generationConfig = this.buildGenerationConfig(options);
|
|
6116
6449
|
const config = {
|
|
@@ -6162,7 +6495,7 @@ var init_gemini = __esm({
|
|
|
6162
6495
|
if (message.role === "system") {
|
|
6163
6496
|
expandedMessages.push({
|
|
6164
6497
|
role: "user",
|
|
6165
|
-
content:
|
|
6498
|
+
content: extractMessageText(message.content)
|
|
6166
6499
|
});
|
|
6167
6500
|
expandedMessages.push({
|
|
6168
6501
|
role: "assistant",
|
|
@@ -6212,7 +6545,7 @@ var init_gemini = __esm({
|
|
|
6212
6545
|
* Handles text, images, and audio (Gemini supports all three).
|
|
6213
6546
|
*/
|
|
6214
6547
|
convertToGeminiParts(content) {
|
|
6215
|
-
const parts =
|
|
6548
|
+
const parts = normalizeMessageContent(content);
|
|
6216
6549
|
return parts.map((part) => {
|
|
6217
6550
|
if (part.type === "text") {
|
|
6218
6551
|
return { text: part.text };
|
|
@@ -6257,10 +6590,10 @@ var init_gemini = __esm({
|
|
|
6257
6590
|
}
|
|
6258
6591
|
return Object.keys(config).length > 0 ? config : null;
|
|
6259
6592
|
}
|
|
6260
|
-
async *
|
|
6593
|
+
async *normalizeProviderStream(iterable) {
|
|
6261
6594
|
const stream2 = iterable;
|
|
6262
6595
|
for await (const chunk of stream2) {
|
|
6263
|
-
const text3 = this.
|
|
6596
|
+
const text3 = this.extractMessageText(chunk);
|
|
6264
6597
|
if (text3) {
|
|
6265
6598
|
yield { text: text3, rawEvent: chunk };
|
|
6266
6599
|
}
|
|
@@ -6271,7 +6604,7 @@ var init_gemini = __esm({
|
|
|
6271
6604
|
}
|
|
6272
6605
|
}
|
|
6273
6606
|
}
|
|
6274
|
-
|
|
6607
|
+
extractMessageText(chunk) {
|
|
6275
6608
|
if (!chunk?.candidates) {
|
|
6276
6609
|
return "";
|
|
6277
6610
|
}
|
|
@@ -6336,7 +6669,7 @@ var init_gemini = __esm({
|
|
|
6336
6669
|
let totalChars = 0;
|
|
6337
6670
|
let mediaCount = 0;
|
|
6338
6671
|
for (const msg of messages) {
|
|
6339
|
-
const parts =
|
|
6672
|
+
const parts = normalizeMessageContent(msg.content);
|
|
6340
6673
|
for (const part of parts) {
|
|
6341
6674
|
if (part.type === "text") {
|
|
6342
6675
|
totalChars += part.text.length;
|
|
@@ -6857,14 +7190,7 @@ var OPENAI_TTS_VOICES, OPENAI_TTS_EXTENDED_VOICES, OPENAI_TTS_FORMATS, openaiSpe
|
|
|
6857
7190
|
var init_openai_speech_models = __esm({
|
|
6858
7191
|
"src/providers/openai-speech-models.ts"() {
|
|
6859
7192
|
"use strict";
|
|
6860
|
-
OPENAI_TTS_VOICES = [
|
|
6861
|
-
"alloy",
|
|
6862
|
-
"echo",
|
|
6863
|
-
"fable",
|
|
6864
|
-
"onyx",
|
|
6865
|
-
"nova",
|
|
6866
|
-
"shimmer"
|
|
6867
|
-
];
|
|
7193
|
+
OPENAI_TTS_VOICES = ["alloy", "echo", "fable", "onyx", "nova", "shimmer"];
|
|
6868
7194
|
OPENAI_TTS_EXTENDED_VOICES = [
|
|
6869
7195
|
...OPENAI_TTS_VOICES,
|
|
6870
7196
|
"ash",
|
|
@@ -7089,7 +7415,7 @@ var init_openai = __esm({
|
|
|
7089
7415
|
format
|
|
7090
7416
|
};
|
|
7091
7417
|
}
|
|
7092
|
-
|
|
7418
|
+
buildApiRequest(options, descriptor, spec, messages) {
|
|
7093
7419
|
const { maxTokens, temperature, topP, stopSequences, extra } = options;
|
|
7094
7420
|
const supportsTemperature = spec?.metadata?.supportsTemperature !== false;
|
|
7095
7421
|
const shouldIncludeTemperature = typeof temperature === "number" && supportsTemperature;
|
|
@@ -7124,7 +7450,7 @@ var init_openai = __esm({
|
|
|
7124
7450
|
...message.name ? { name: message.name } : {}
|
|
7125
7451
|
};
|
|
7126
7452
|
}
|
|
7127
|
-
const textContent = typeof message.content === "string" ? message.content :
|
|
7453
|
+
const textContent = typeof message.content === "string" ? message.content : extractMessageText(message.content);
|
|
7128
7454
|
if (role === "system") {
|
|
7129
7455
|
return {
|
|
7130
7456
|
role: "system",
|
|
@@ -7184,7 +7510,7 @@ var init_openai = __esm({
|
|
|
7184
7510
|
const stream2 = await client.chat.completions.create(payload, signal ? { signal } : void 0);
|
|
7185
7511
|
return stream2;
|
|
7186
7512
|
}
|
|
7187
|
-
async *
|
|
7513
|
+
async *normalizeProviderStream(iterable) {
|
|
7188
7514
|
const stream2 = iterable;
|
|
7189
7515
|
for await (const chunk of stream2) {
|
|
7190
7516
|
const text3 = chunk.choices.map((choice) => choice.delta?.content ?? "").join("");
|
|
@@ -7242,9 +7568,9 @@ var init_openai = __esm({
|
|
|
7242
7568
|
tokenCount += OPENAI_MESSAGE_OVERHEAD_TOKENS;
|
|
7243
7569
|
const roleText = ROLE_MAP[message.role];
|
|
7244
7570
|
tokenCount += encoding.encode(roleText).length;
|
|
7245
|
-
const textContent =
|
|
7571
|
+
const textContent = extractMessageText(message.content);
|
|
7246
7572
|
tokenCount += encoding.encode(textContent).length;
|
|
7247
|
-
const parts =
|
|
7573
|
+
const parts = normalizeMessageContent(message.content);
|
|
7248
7574
|
for (const part of parts) {
|
|
7249
7575
|
if (part.type === "image") {
|
|
7250
7576
|
imageCount++;
|
|
@@ -7269,7 +7595,7 @@ var init_openai = __esm({
|
|
|
7269
7595
|
let totalChars = 0;
|
|
7270
7596
|
let imageCount = 0;
|
|
7271
7597
|
for (const msg of messages) {
|
|
7272
|
-
const parts =
|
|
7598
|
+
const parts = normalizeMessageContent(msg.content);
|
|
7273
7599
|
for (const part of parts) {
|
|
7274
7600
|
if (part.type === "text") {
|
|
7275
7601
|
totalChars += part.text.length;
|
|
@@ -7562,9 +7888,7 @@ var init_image = __esm({
|
|
|
7562
7888
|
return this.findImageAdapter(modelId) !== void 0;
|
|
7563
7889
|
}
|
|
7564
7890
|
findImageAdapter(modelId) {
|
|
7565
|
-
return this.adapters.find(
|
|
7566
|
-
(adapter) => adapter.supportsImageGeneration?.(modelId) ?? false
|
|
7567
|
-
);
|
|
7891
|
+
return this.adapters.find((adapter) => adapter.supportsImageGeneration?.(modelId) ?? false);
|
|
7568
7892
|
}
|
|
7569
7893
|
};
|
|
7570
7894
|
}
|
|
@@ -7616,9 +7940,7 @@ var init_speech = __esm({
|
|
|
7616
7940
|
return this.findSpeechAdapter(modelId) !== void 0;
|
|
7617
7941
|
}
|
|
7618
7942
|
findSpeechAdapter(modelId) {
|
|
7619
|
-
return this.adapters.find(
|
|
7620
|
-
(adapter) => adapter.supportsSpeechGeneration?.(modelId) ?? false
|
|
7621
|
-
);
|
|
7943
|
+
return this.adapters.find((adapter) => adapter.supportsSpeechGeneration?.(modelId) ?? false);
|
|
7622
7944
|
}
|
|
7623
7945
|
};
|
|
7624
7946
|
}
|
|
@@ -7729,11 +8051,7 @@ var init_vision = __esm({
|
|
|
7729
8051
|
if (!parsed) {
|
|
7730
8052
|
throw new Error("Invalid data URL format");
|
|
7731
8053
|
}
|
|
7732
|
-
builder.addUserWithImage(
|
|
7733
|
-
options.prompt,
|
|
7734
|
-
parsed.data,
|
|
7735
|
-
parsed.mimeType
|
|
7736
|
-
);
|
|
8054
|
+
builder.addUserWithImage(options.prompt, parsed.data, parsed.mimeType);
|
|
7737
8055
|
} else {
|
|
7738
8056
|
const buffer = Buffer.from(options.image, "base64");
|
|
7739
8057
|
builder.addUserWithImage(options.prompt, buffer, options.mimeType);
|
|
@@ -8142,20 +8460,21 @@ var init_builder = __esm({
|
|
|
8142
8460
|
promptConfig;
|
|
8143
8461
|
gadgets = [];
|
|
8144
8462
|
initialMessages = [];
|
|
8145
|
-
|
|
8463
|
+
requestHumanInput;
|
|
8146
8464
|
gadgetStartPrefix;
|
|
8147
8465
|
gadgetEndPrefix;
|
|
8148
8466
|
gadgetArgPrefix;
|
|
8149
8467
|
textOnlyHandler;
|
|
8150
8468
|
textWithGadgetsHandler;
|
|
8151
8469
|
stopOnGadgetError;
|
|
8152
|
-
|
|
8470
|
+
canRecoverFromGadgetError;
|
|
8153
8471
|
defaultGadgetTimeoutMs;
|
|
8154
8472
|
gadgetOutputLimit;
|
|
8155
8473
|
gadgetOutputLimitPercent;
|
|
8156
8474
|
compactionConfig;
|
|
8157
8475
|
signal;
|
|
8158
8476
|
trailingMessage;
|
|
8477
|
+
subagentConfig;
|
|
8159
8478
|
constructor(client) {
|
|
8160
8479
|
this.client = client;
|
|
8161
8480
|
}
|
|
@@ -8246,13 +8565,13 @@ var init_builder = __esm({
|
|
|
8246
8565
|
*
|
|
8247
8566
|
* @example
|
|
8248
8567
|
* ```typescript
|
|
8249
|
-
* .
|
|
8568
|
+
* .withPromptTemplateConfig({
|
|
8250
8569
|
* mainInstruction: "Use the gadget markers below:",
|
|
8251
8570
|
* rules: ["Always use markers", "Never use function calling"]
|
|
8252
8571
|
* })
|
|
8253
8572
|
* ```
|
|
8254
8573
|
*/
|
|
8255
|
-
|
|
8574
|
+
withPromptTemplateConfig(config) {
|
|
8256
8575
|
this.promptConfig = config;
|
|
8257
8576
|
return this;
|
|
8258
8577
|
}
|
|
@@ -8332,7 +8651,7 @@ var init_builder = __esm({
|
|
|
8332
8651
|
* ```
|
|
8333
8652
|
*/
|
|
8334
8653
|
onHumanInput(handler) {
|
|
8335
|
-
this.
|
|
8654
|
+
this.requestHumanInput = handler;
|
|
8336
8655
|
return this;
|
|
8337
8656
|
}
|
|
8338
8657
|
/**
|
|
@@ -8467,9 +8786,9 @@ var init_builder = __esm({
|
|
|
8467
8786
|
* Provides fine-grained control over whether to continue after different types of errors.
|
|
8468
8787
|
* Overrides `stopOnGadgetError` when provided.
|
|
8469
8788
|
*
|
|
8470
|
-
* **Note:** This builder method configures the underlying `
|
|
8789
|
+
* **Note:** This builder method configures the underlying `canRecoverFromGadgetError` option
|
|
8471
8790
|
* in `AgentOptions`. The method is named `withErrorHandler` for better developer experience,
|
|
8472
|
-
* but maps to the `
|
|
8791
|
+
* but maps to the `canRecoverFromGadgetError` property internally.
|
|
8473
8792
|
*
|
|
8474
8793
|
* @param handler - Function that decides whether to continue after an error.
|
|
8475
8794
|
* Return `true` to continue execution, `false` to stop.
|
|
@@ -8490,7 +8809,7 @@ var init_builder = __esm({
|
|
|
8490
8809
|
* ```
|
|
8491
8810
|
*/
|
|
8492
8811
|
withErrorHandler(handler) {
|
|
8493
|
-
this.
|
|
8812
|
+
this.canRecoverFromGadgetError = handler;
|
|
8494
8813
|
return this;
|
|
8495
8814
|
}
|
|
8496
8815
|
/**
|
|
@@ -8631,6 +8950,27 @@ var init_builder = __esm({
|
|
|
8631
8950
|
this.signal = signal;
|
|
8632
8951
|
return this;
|
|
8633
8952
|
}
|
|
8953
|
+
/**
|
|
8954
|
+
* Set subagent configuration overrides.
|
|
8955
|
+
*
|
|
8956
|
+
* Subagent gadgets (like BrowseWeb) can read these settings from ExecutionContext
|
|
8957
|
+
* to inherit model and other options from the CLI configuration.
|
|
8958
|
+
*
|
|
8959
|
+
* @param config - Subagent configuration map keyed by gadget name
|
|
8960
|
+
* @returns This builder for chaining
|
|
8961
|
+
*
|
|
8962
|
+
* @example
|
|
8963
|
+
* ```typescript
|
|
8964
|
+
* .withSubagentConfig({
|
|
8965
|
+
* BrowseWeb: { model: "inherit", maxIterations: 20, headless: true },
|
|
8966
|
+
* CodeAnalyzer: { model: "sonnet", maxIterations: 10 }
|
|
8967
|
+
* })
|
|
8968
|
+
* ```
|
|
8969
|
+
*/
|
|
8970
|
+
withSubagentConfig(config) {
|
|
8971
|
+
this.subagentConfig = config;
|
|
8972
|
+
return this;
|
|
8973
|
+
}
|
|
8634
8974
|
/**
|
|
8635
8975
|
* Add an ephemeral trailing message that appears at the end of each LLM request.
|
|
8636
8976
|
*
|
|
@@ -8795,19 +9135,20 @@ ${endPrefix}`
|
|
|
8795
9135
|
hooks: this.composeHooks(),
|
|
8796
9136
|
promptConfig: this.promptConfig,
|
|
8797
9137
|
initialMessages: this.initialMessages,
|
|
8798
|
-
|
|
9138
|
+
requestHumanInput: this.requestHumanInput,
|
|
8799
9139
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
8800
9140
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
8801
9141
|
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
8802
9142
|
textOnlyHandler: this.textOnlyHandler,
|
|
8803
9143
|
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
8804
9144
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
8805
|
-
|
|
9145
|
+
canRecoverFromGadgetError: this.canRecoverFromGadgetError,
|
|
8806
9146
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
8807
9147
|
gadgetOutputLimit: this.gadgetOutputLimit,
|
|
8808
9148
|
gadgetOutputLimitPercent: this.gadgetOutputLimitPercent,
|
|
8809
9149
|
compactionConfig: this.compactionConfig,
|
|
8810
|
-
signal: this.signal
|
|
9150
|
+
signal: this.signal,
|
|
9151
|
+
subagentConfig: this.subagentConfig
|
|
8811
9152
|
};
|
|
8812
9153
|
}
|
|
8813
9154
|
ask(userPrompt) {
|
|
@@ -8976,19 +9317,20 @@ ${endPrefix}`
|
|
|
8976
9317
|
hooks: this.composeHooks(),
|
|
8977
9318
|
promptConfig: this.promptConfig,
|
|
8978
9319
|
initialMessages: this.initialMessages,
|
|
8979
|
-
|
|
9320
|
+
requestHumanInput: this.requestHumanInput,
|
|
8980
9321
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
8981
9322
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
8982
9323
|
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
8983
9324
|
textOnlyHandler: this.textOnlyHandler,
|
|
8984
9325
|
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
8985
9326
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
8986
|
-
|
|
9327
|
+
canRecoverFromGadgetError: this.canRecoverFromGadgetError,
|
|
8987
9328
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
8988
9329
|
gadgetOutputLimit: this.gadgetOutputLimit,
|
|
8989
9330
|
gadgetOutputLimitPercent: this.gadgetOutputLimitPercent,
|
|
8990
9331
|
compactionConfig: this.compactionConfig,
|
|
8991
|
-
signal: this.signal
|
|
9332
|
+
signal: this.signal,
|
|
9333
|
+
subagentConfig: this.subagentConfig
|
|
8992
9334
|
};
|
|
8993
9335
|
return new Agent(AGENT_INTERNAL_KEY, options);
|
|
8994
9336
|
}
|
|
@@ -8999,11 +9341,10 @@ ${endPrefix}`
|
|
|
8999
9341
|
// src/index.ts
|
|
9000
9342
|
var index_exports = {};
|
|
9001
9343
|
__export(index_exports, {
|
|
9002
|
-
|
|
9344
|
+
AbortException: () => AbortException,
|
|
9345
|
+
AbstractGadget: () => AbstractGadget,
|
|
9003
9346
|
AgentBuilder: () => AgentBuilder,
|
|
9004
9347
|
AnthropicMessagesProvider: () => AnthropicMessagesProvider,
|
|
9005
|
-
BaseGadget: () => BaseGadget,
|
|
9006
|
-
BreakLoopException: () => BreakLoopException,
|
|
9007
9348
|
CompactionManager: () => CompactionManager,
|
|
9008
9349
|
ConversationManager: () => ConversationManager,
|
|
9009
9350
|
DEFAULT_COMPACTION_CONFIG: () => DEFAULT_COMPACTION_CONFIG,
|
|
@@ -9011,16 +9352,18 @@ __export(index_exports, {
|
|
|
9011
9352
|
DEFAULT_PROMPTS: () => DEFAULT_PROMPTS,
|
|
9012
9353
|
DEFAULT_SUMMARIZATION_PROMPT: () => DEFAULT_SUMMARIZATION_PROMPT,
|
|
9013
9354
|
Gadget: () => Gadget,
|
|
9355
|
+
GadgetCallParser: () => GadgetCallParser,
|
|
9014
9356
|
GadgetExecutor: () => GadgetExecutor,
|
|
9015
9357
|
GadgetOutputStore: () => GadgetOutputStore,
|
|
9016
9358
|
GadgetRegistry: () => GadgetRegistry,
|
|
9017
9359
|
GeminiGenerativeProvider: () => GeminiGenerativeProvider,
|
|
9018
9360
|
HookPresets: () => HookPresets,
|
|
9019
|
-
|
|
9361
|
+
HumanInputRequiredException: () => HumanInputRequiredException,
|
|
9020
9362
|
HybridStrategy: () => HybridStrategy,
|
|
9021
9363
|
LLMMessageBuilder: () => LLMMessageBuilder,
|
|
9022
9364
|
LLMist: () => LLMist,
|
|
9023
9365
|
MODEL_ALIASES: () => MODEL_ALIASES,
|
|
9366
|
+
MediaStore: () => MediaStore,
|
|
9024
9367
|
MockBuilder: () => MockBuilder,
|
|
9025
9368
|
MockManager: () => MockManager,
|
|
9026
9369
|
MockProviderAdapter: () => MockProviderAdapter,
|
|
@@ -9028,9 +9371,10 @@ __export(index_exports, {
|
|
|
9028
9371
|
ModelRegistry: () => ModelRegistry,
|
|
9029
9372
|
OpenAIChatProvider: () => OpenAIChatProvider,
|
|
9030
9373
|
SlidingWindowStrategy: () => SlidingWindowStrategy,
|
|
9031
|
-
StreamParser: () => StreamParser,
|
|
9032
9374
|
StreamProcessor: () => StreamProcessor,
|
|
9033
9375
|
SummarizationStrategy: () => SummarizationStrategy,
|
|
9376
|
+
TaskCompletionSignal: () => TaskCompletionSignal,
|
|
9377
|
+
TimeoutException: () => TimeoutException,
|
|
9034
9378
|
audioFromBase64: () => audioFromBase64,
|
|
9035
9379
|
audioFromBuffer: () => audioFromBuffer,
|
|
9036
9380
|
collectEvents: () => collectEvents,
|
|
@@ -9042,6 +9386,7 @@ __export(index_exports, {
|
|
|
9042
9386
|
createGeminiProviderFromEnv: () => createGeminiProviderFromEnv,
|
|
9043
9387
|
createHints: () => createHints,
|
|
9044
9388
|
createLogger: () => createLogger,
|
|
9389
|
+
createMediaOutput: () => createMediaOutput,
|
|
9045
9390
|
createMockAdapter: () => createMockAdapter,
|
|
9046
9391
|
createMockClient: () => createMockClient,
|
|
9047
9392
|
createMockStream: () => createMockStream,
|
|
@@ -9051,7 +9396,7 @@ __export(index_exports, {
|
|
|
9051
9396
|
detectAudioMimeType: () => detectAudioMimeType,
|
|
9052
9397
|
detectImageMimeType: () => detectImageMimeType,
|
|
9053
9398
|
discoverProviderAdapters: () => discoverProviderAdapters,
|
|
9054
|
-
|
|
9399
|
+
extractMessageText: () => extractMessageText,
|
|
9055
9400
|
getMockManager: () => getMockManager,
|
|
9056
9401
|
getModelId: () => getModelId,
|
|
9057
9402
|
getProvider: () => getProvider,
|
|
@@ -9065,13 +9410,18 @@ __export(index_exports, {
|
|
|
9065
9410
|
isTextPart: () => isTextPart,
|
|
9066
9411
|
iterationProgressHint: () => iterationProgressHint,
|
|
9067
9412
|
mockLLM: () => mockLLM,
|
|
9068
|
-
|
|
9413
|
+
normalizeMessageContent: () => normalizeMessageContent,
|
|
9069
9414
|
parallelGadgetHint: () => parallelGadgetHint,
|
|
9070
9415
|
parseDataUrl: () => parseDataUrl,
|
|
9071
9416
|
resolveHintTemplate: () => resolveHintTemplate,
|
|
9072
9417
|
resolveModel: () => resolveModel,
|
|
9073
9418
|
resolvePromptTemplate: () => resolvePromptTemplate,
|
|
9074
9419
|
resolveRulesTemplate: () => resolveRulesTemplate,
|
|
9420
|
+
resultWithAudio: () => resultWithAudio,
|
|
9421
|
+
resultWithFile: () => resultWithFile,
|
|
9422
|
+
resultWithImage: () => resultWithImage,
|
|
9423
|
+
resultWithImages: () => resultWithImages,
|
|
9424
|
+
resultWithMedia: () => resultWithMedia,
|
|
9075
9425
|
runWithHandlers: () => runWithHandlers,
|
|
9076
9426
|
stream: () => stream,
|
|
9077
9427
|
text: () => text,
|
|
@@ -9625,9 +9975,7 @@ var HookPresets = class _HookPresets {
|
|
|
9625
9975
|
console.log(
|
|
9626
9976
|
`\u{1F5DC}\uFE0F Compaction (${ctx.event.strategy}): ${ctx.event.tokensBefore} \u2192 ${ctx.event.tokensAfter} tokens (saved ${saved}, ${percent}%)`
|
|
9627
9977
|
);
|
|
9628
|
-
console.log(
|
|
9629
|
-
` Messages: ${ctx.event.messagesBefore} \u2192 ${ctx.event.messagesAfter}`
|
|
9630
|
-
);
|
|
9978
|
+
console.log(` Messages: ${ctx.event.messagesBefore} \u2192 ${ctx.event.messagesAfter}`);
|
|
9631
9979
|
if (ctx.stats.totalCompactions > 1) {
|
|
9632
9980
|
console.log(
|
|
9633
9981
|
` Cumulative: ${ctx.stats.totalCompactions} compactions, ${ctx.stats.totalTokensSaved} tokens saved`
|
|
@@ -9862,16 +10210,15 @@ var HookPresets = class _HookPresets {
|
|
|
9862
10210
|
}
|
|
9863
10211
|
};
|
|
9864
10212
|
|
|
9865
|
-
// src/agent/index.ts
|
|
9866
|
-
init_conversation_manager();
|
|
9867
|
-
init_stream_processor();
|
|
9868
|
-
init_gadget_output_store();
|
|
9869
|
-
|
|
9870
10213
|
// src/agent/compaction/index.ts
|
|
9871
10214
|
init_config();
|
|
9872
|
-
init_strategy();
|
|
9873
|
-
init_strategies();
|
|
9874
10215
|
init_manager();
|
|
10216
|
+
init_strategies();
|
|
10217
|
+
init_strategy();
|
|
10218
|
+
|
|
10219
|
+
// src/agent/index.ts
|
|
10220
|
+
init_conversation_manager();
|
|
10221
|
+
init_gadget_output_store();
|
|
9875
10222
|
|
|
9876
10223
|
// src/agent/hints.ts
|
|
9877
10224
|
init_prompt_config();
|
|
@@ -9895,11 +10242,7 @@ function iterationProgressHint(options) {
|
|
|
9895
10242
|
maxIterations,
|
|
9896
10243
|
remaining
|
|
9897
10244
|
};
|
|
9898
|
-
let hint = resolveHintTemplate(
|
|
9899
|
-
template,
|
|
9900
|
-
DEFAULT_HINTS.iterationProgressHint,
|
|
9901
|
-
hintContext
|
|
9902
|
-
);
|
|
10245
|
+
let hint = resolveHintTemplate(template, DEFAULT_HINTS.iterationProgressHint, hintContext);
|
|
9903
10246
|
if (showUrgency && progress >= 0.8) {
|
|
9904
10247
|
hint += " \u26A0\uFE0F Running low on iterations - focus on completing the task.";
|
|
9905
10248
|
}
|
|
@@ -9974,6 +10317,9 @@ function createHints(config) {
|
|
|
9974
10317
|
return HookPresets.merge(...hooksToMerge);
|
|
9975
10318
|
}
|
|
9976
10319
|
|
|
10320
|
+
// src/agent/index.ts
|
|
10321
|
+
init_stream_processor();
|
|
10322
|
+
|
|
9977
10323
|
// src/index.ts
|
|
9978
10324
|
init_client();
|
|
9979
10325
|
init_input_content();
|
|
@@ -9984,17 +10330,17 @@ init_options();
|
|
|
9984
10330
|
init_prompt_config();
|
|
9985
10331
|
init_quick_methods();
|
|
9986
10332
|
init_create_gadget();
|
|
9987
|
-
init_output_viewer();
|
|
9988
10333
|
init_exceptions();
|
|
9989
10334
|
init_executor();
|
|
9990
10335
|
init_gadget();
|
|
10336
|
+
init_output_viewer();
|
|
9991
10337
|
init_parser();
|
|
9992
10338
|
init_registry();
|
|
9993
10339
|
|
|
9994
10340
|
// src/gadgets/typed-gadget.ts
|
|
9995
10341
|
init_gadget();
|
|
9996
10342
|
function Gadget(config) {
|
|
9997
|
-
class GadgetBase extends
|
|
10343
|
+
class GadgetBase extends AbstractGadget {
|
|
9998
10344
|
description = config.description;
|
|
9999
10345
|
parameterSchema = config.schema;
|
|
10000
10346
|
name = config.name;
|
|
@@ -10012,6 +10358,119 @@ function Gadget(config) {
|
|
|
10012
10358
|
return GadgetBase;
|
|
10013
10359
|
}
|
|
10014
10360
|
|
|
10361
|
+
// src/gadgets/helpers.ts
|
|
10362
|
+
init_input_content();
|
|
10363
|
+
function createMediaOutput(kind, data, mimeType, options) {
|
|
10364
|
+
const buffer = data instanceof Buffer ? data : Buffer.from(data);
|
|
10365
|
+
return {
|
|
10366
|
+
kind,
|
|
10367
|
+
data: buffer.toString("base64"),
|
|
10368
|
+
mimeType,
|
|
10369
|
+
description: options?.description,
|
|
10370
|
+
metadata: options?.metadata,
|
|
10371
|
+
fileName: options?.fileName
|
|
10372
|
+
};
|
|
10373
|
+
}
|
|
10374
|
+
function resultWithMedia(result, media, cost) {
|
|
10375
|
+
if (media.length === 0) {
|
|
10376
|
+
throw new Error("resultWithMedia: media array cannot be empty");
|
|
10377
|
+
}
|
|
10378
|
+
return {
|
|
10379
|
+
result,
|
|
10380
|
+
media,
|
|
10381
|
+
cost
|
|
10382
|
+
};
|
|
10383
|
+
}
|
|
10384
|
+
function resultWithImage(result, imageData, options) {
|
|
10385
|
+
const buffer = imageData instanceof Buffer ? imageData : Buffer.from(imageData);
|
|
10386
|
+
const mimeType = options?.mimeType ?? detectImageMimeType(buffer);
|
|
10387
|
+
if (!mimeType) {
|
|
10388
|
+
throw new Error(
|
|
10389
|
+
"Could not detect image MIME type. Please provide mimeType explicitly in options."
|
|
10390
|
+
);
|
|
10391
|
+
}
|
|
10392
|
+
return {
|
|
10393
|
+
result,
|
|
10394
|
+
media: [
|
|
10395
|
+
{
|
|
10396
|
+
kind: "image",
|
|
10397
|
+
data: buffer.toString("base64"),
|
|
10398
|
+
mimeType,
|
|
10399
|
+
description: options?.description,
|
|
10400
|
+
metadata: options?.metadata,
|
|
10401
|
+
fileName: options?.fileName
|
|
10402
|
+
}
|
|
10403
|
+
],
|
|
10404
|
+
cost: options?.cost
|
|
10405
|
+
};
|
|
10406
|
+
}
|
|
10407
|
+
function resultWithImages(result, images, cost) {
|
|
10408
|
+
if (images.length === 0) {
|
|
10409
|
+
throw new Error("resultWithImages: images array cannot be empty");
|
|
10410
|
+
}
|
|
10411
|
+
const media = images.map((img, index) => {
|
|
10412
|
+
const buffer = img.data instanceof Buffer ? img.data : Buffer.from(img.data);
|
|
10413
|
+
const mimeType = img.mimeType ?? detectImageMimeType(buffer);
|
|
10414
|
+
if (!mimeType) {
|
|
10415
|
+
throw new Error(
|
|
10416
|
+
`Could not detect MIME type for image at index ${index}. Please provide mimeType explicitly.`
|
|
10417
|
+
);
|
|
10418
|
+
}
|
|
10419
|
+
return {
|
|
10420
|
+
kind: "image",
|
|
10421
|
+
data: buffer.toString("base64"),
|
|
10422
|
+
mimeType,
|
|
10423
|
+
description: img.description,
|
|
10424
|
+
metadata: img.metadata,
|
|
10425
|
+
fileName: img.fileName
|
|
10426
|
+
};
|
|
10427
|
+
});
|
|
10428
|
+
return { result, media, cost };
|
|
10429
|
+
}
|
|
10430
|
+
function resultWithAudio(result, audioData, options) {
|
|
10431
|
+
const buffer = audioData instanceof Buffer ? audioData : Buffer.from(audioData);
|
|
10432
|
+
const mimeType = options?.mimeType ?? detectAudioMimeType(buffer);
|
|
10433
|
+
if (!mimeType) {
|
|
10434
|
+
throw new Error(
|
|
10435
|
+
"Could not detect audio MIME type. Please provide mimeType explicitly in options."
|
|
10436
|
+
);
|
|
10437
|
+
}
|
|
10438
|
+
const metadata = options?.durationMs ? { durationMs: options.durationMs } : void 0;
|
|
10439
|
+
return {
|
|
10440
|
+
result,
|
|
10441
|
+
media: [
|
|
10442
|
+
{
|
|
10443
|
+
kind: "audio",
|
|
10444
|
+
data: buffer.toString("base64"),
|
|
10445
|
+
mimeType,
|
|
10446
|
+
description: options?.description,
|
|
10447
|
+
metadata,
|
|
10448
|
+
fileName: options?.fileName
|
|
10449
|
+
}
|
|
10450
|
+
],
|
|
10451
|
+
cost: options?.cost
|
|
10452
|
+
};
|
|
10453
|
+
}
|
|
10454
|
+
function resultWithFile(result, fileData, mimeType, options) {
|
|
10455
|
+
const buffer = fileData instanceof Buffer ? fileData : Buffer.from(fileData);
|
|
10456
|
+
return {
|
|
10457
|
+
result,
|
|
10458
|
+
media: [
|
|
10459
|
+
{
|
|
10460
|
+
kind: "file",
|
|
10461
|
+
data: buffer.toString("base64"),
|
|
10462
|
+
mimeType,
|
|
10463
|
+
description: options?.description,
|
|
10464
|
+
fileName: options?.fileName
|
|
10465
|
+
}
|
|
10466
|
+
],
|
|
10467
|
+
cost: options?.cost
|
|
10468
|
+
};
|
|
10469
|
+
}
|
|
10470
|
+
|
|
10471
|
+
// src/index.ts
|
|
10472
|
+
init_media_store();
|
|
10473
|
+
|
|
10015
10474
|
// src/gadgets/validation.ts
|
|
10016
10475
|
function validateAndApplyDefaults(schema, params) {
|
|
10017
10476
|
const result = schema.safeParse(params);
|
|
@@ -10049,6 +10508,9 @@ init_discovery();
|
|
|
10049
10508
|
init_gemini();
|
|
10050
10509
|
init_openai();
|
|
10051
10510
|
|
|
10511
|
+
// src/testing/cli-helpers.ts
|
|
10512
|
+
var import_node_stream = require("stream");
|
|
10513
|
+
|
|
10052
10514
|
// src/testing/mock-manager.ts
|
|
10053
10515
|
init_logger();
|
|
10054
10516
|
var MockManager = class _MockManager {
|
|
@@ -10601,7 +11063,9 @@ var MockBuilder = class {
|
|
|
10601
11063
|
*/
|
|
10602
11064
|
whenMessageContains(text3) {
|
|
10603
11065
|
this.matchers.push(
|
|
10604
|
-
(ctx) => ctx.messages.some(
|
|
11066
|
+
(ctx) => ctx.messages.some(
|
|
11067
|
+
(msg) => extractMessageText(msg.content).toLowerCase().includes(text3.toLowerCase())
|
|
11068
|
+
)
|
|
10605
11069
|
);
|
|
10606
11070
|
return this;
|
|
10607
11071
|
}
|
|
@@ -10615,7 +11079,7 @@ var MockBuilder = class {
|
|
|
10615
11079
|
this.matchers.push((ctx) => {
|
|
10616
11080
|
const lastMsg = ctx.messages[ctx.messages.length - 1];
|
|
10617
11081
|
if (!lastMsg) return false;
|
|
10618
|
-
return
|
|
11082
|
+
return extractMessageText(lastMsg.content).toLowerCase().includes(text3.toLowerCase());
|
|
10619
11083
|
});
|
|
10620
11084
|
return this;
|
|
10621
11085
|
}
|
|
@@ -10626,7 +11090,7 @@ var MockBuilder = class {
|
|
|
10626
11090
|
* mockLLM().whenMessageMatches(/calculate \d+/)
|
|
10627
11091
|
*/
|
|
10628
11092
|
whenMessageMatches(regex) {
|
|
10629
|
-
this.matchers.push((ctx) => ctx.messages.some((msg) => regex.test(
|
|
11093
|
+
this.matchers.push((ctx) => ctx.messages.some((msg) => regex.test(extractMessageText(msg.content))));
|
|
10630
11094
|
return this;
|
|
10631
11095
|
}
|
|
10632
11096
|
/**
|
|
@@ -10638,7 +11102,7 @@ var MockBuilder = class {
|
|
|
10638
11102
|
whenRoleContains(role, text3) {
|
|
10639
11103
|
this.matchers.push(
|
|
10640
11104
|
(ctx) => ctx.messages.some(
|
|
10641
|
-
(msg) => msg.role === role &&
|
|
11105
|
+
(msg) => msg.role === role && extractMessageText(msg.content).toLowerCase().includes(text3.toLowerCase())
|
|
10642
11106
|
)
|
|
10643
11107
|
);
|
|
10644
11108
|
return this;
|
|
@@ -11041,16 +11505,12 @@ function createMockClient(options) {
|
|
|
11041
11505
|
|
|
11042
11506
|
// src/testing/mock-gadget.ts
|
|
11043
11507
|
init_gadget();
|
|
11044
|
-
|
|
11045
|
-
// src/testing/cli-helpers.ts
|
|
11046
|
-
var import_node_stream = require("stream");
|
|
11047
11508
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11048
11509
|
0 && (module.exports = {
|
|
11049
|
-
|
|
11510
|
+
AbortException,
|
|
11511
|
+
AbstractGadget,
|
|
11050
11512
|
AgentBuilder,
|
|
11051
11513
|
AnthropicMessagesProvider,
|
|
11052
|
-
BaseGadget,
|
|
11053
|
-
BreakLoopException,
|
|
11054
11514
|
CompactionManager,
|
|
11055
11515
|
ConversationManager,
|
|
11056
11516
|
DEFAULT_COMPACTION_CONFIG,
|
|
@@ -11058,16 +11518,18 @@ var import_node_stream = require("stream");
|
|
|
11058
11518
|
DEFAULT_PROMPTS,
|
|
11059
11519
|
DEFAULT_SUMMARIZATION_PROMPT,
|
|
11060
11520
|
Gadget,
|
|
11521
|
+
GadgetCallParser,
|
|
11061
11522
|
GadgetExecutor,
|
|
11062
11523
|
GadgetOutputStore,
|
|
11063
11524
|
GadgetRegistry,
|
|
11064
11525
|
GeminiGenerativeProvider,
|
|
11065
11526
|
HookPresets,
|
|
11066
|
-
|
|
11527
|
+
HumanInputRequiredException,
|
|
11067
11528
|
HybridStrategy,
|
|
11068
11529
|
LLMMessageBuilder,
|
|
11069
11530
|
LLMist,
|
|
11070
11531
|
MODEL_ALIASES,
|
|
11532
|
+
MediaStore,
|
|
11071
11533
|
MockBuilder,
|
|
11072
11534
|
MockManager,
|
|
11073
11535
|
MockProviderAdapter,
|
|
@@ -11075,9 +11537,10 @@ var import_node_stream = require("stream");
|
|
|
11075
11537
|
ModelRegistry,
|
|
11076
11538
|
OpenAIChatProvider,
|
|
11077
11539
|
SlidingWindowStrategy,
|
|
11078
|
-
StreamParser,
|
|
11079
11540
|
StreamProcessor,
|
|
11080
11541
|
SummarizationStrategy,
|
|
11542
|
+
TaskCompletionSignal,
|
|
11543
|
+
TimeoutException,
|
|
11081
11544
|
audioFromBase64,
|
|
11082
11545
|
audioFromBuffer,
|
|
11083
11546
|
collectEvents,
|
|
@@ -11089,6 +11552,7 @@ var import_node_stream = require("stream");
|
|
|
11089
11552
|
createGeminiProviderFromEnv,
|
|
11090
11553
|
createHints,
|
|
11091
11554
|
createLogger,
|
|
11555
|
+
createMediaOutput,
|
|
11092
11556
|
createMockAdapter,
|
|
11093
11557
|
createMockClient,
|
|
11094
11558
|
createMockStream,
|
|
@@ -11098,7 +11562,7 @@ var import_node_stream = require("stream");
|
|
|
11098
11562
|
detectAudioMimeType,
|
|
11099
11563
|
detectImageMimeType,
|
|
11100
11564
|
discoverProviderAdapters,
|
|
11101
|
-
|
|
11565
|
+
extractMessageText,
|
|
11102
11566
|
getMockManager,
|
|
11103
11567
|
getModelId,
|
|
11104
11568
|
getProvider,
|
|
@@ -11112,13 +11576,18 @@ var import_node_stream = require("stream");
|
|
|
11112
11576
|
isTextPart,
|
|
11113
11577
|
iterationProgressHint,
|
|
11114
11578
|
mockLLM,
|
|
11115
|
-
|
|
11579
|
+
normalizeMessageContent,
|
|
11116
11580
|
parallelGadgetHint,
|
|
11117
11581
|
parseDataUrl,
|
|
11118
11582
|
resolveHintTemplate,
|
|
11119
11583
|
resolveModel,
|
|
11120
11584
|
resolvePromptTemplate,
|
|
11121
11585
|
resolveRulesTemplate,
|
|
11586
|
+
resultWithAudio,
|
|
11587
|
+
resultWithFile,
|
|
11588
|
+
resultWithImage,
|
|
11589
|
+
resultWithImages,
|
|
11590
|
+
resultWithMedia,
|
|
11122
11591
|
runWithHandlers,
|
|
11123
11592
|
stream,
|
|
11124
11593
|
text,
|