@yourgpt/llm-sdk 2.1.3 → 2.1.4-alpha.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 +59 -0
- package/dist/adapters/index.d.mts +9 -2
- package/dist/adapters/index.d.ts +9 -2
- package/dist/adapters/index.js +421 -19
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs +421 -19
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/index.d.mts +164 -11
- package/dist/index.d.ts +164 -11
- package/dist/index.js +638 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +635 -55
- package/dist/index.mjs.map +1 -1
- package/dist/providers/anthropic/index.d.mts +1 -1
- package/dist/providers/anthropic/index.d.ts +1 -1
- package/dist/providers/anthropic/index.js +95 -1
- package/dist/providers/anthropic/index.js.map +1 -1
- package/dist/providers/anthropic/index.mjs +95 -1
- package/dist/providers/anthropic/index.mjs.map +1 -1
- package/dist/providers/azure/index.d.mts +1 -1
- package/dist/providers/azure/index.d.ts +1 -1
- package/dist/providers/azure/index.js +51 -5
- package/dist/providers/azure/index.js.map +1 -1
- package/dist/providers/azure/index.mjs +51 -5
- package/dist/providers/azure/index.mjs.map +1 -1
- package/dist/providers/google/index.d.mts +1 -1
- package/dist/providers/google/index.d.ts +1 -1
- package/dist/providers/google/index.js +76 -0
- package/dist/providers/google/index.js.map +1 -1
- package/dist/providers/google/index.mjs +76 -0
- package/dist/providers/google/index.mjs.map +1 -1
- package/dist/providers/ollama/index.d.mts +2 -2
- package/dist/providers/ollama/index.d.ts +2 -2
- package/dist/providers/ollama/index.js +51 -8
- package/dist/providers/ollama/index.js.map +1 -1
- package/dist/providers/ollama/index.mjs +51 -8
- package/dist/providers/ollama/index.mjs.map +1 -1
- package/dist/providers/openai/index.d.mts +1 -1
- package/dist/providers/openai/index.d.ts +1 -1
- package/dist/providers/openai/index.js +301 -3
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/openai/index.mjs +301 -3
- package/dist/providers/openai/index.mjs.map +1 -1
- package/dist/providers/openrouter/index.d.mts +1 -1
- package/dist/providers/openrouter/index.d.ts +1 -1
- package/dist/providers/openrouter/index.js +301 -3
- package/dist/providers/openrouter/index.js.map +1 -1
- package/dist/providers/openrouter/index.mjs +301 -3
- package/dist/providers/openrouter/index.mjs.map +1 -1
- package/dist/providers/xai/index.d.mts +1 -1
- package/dist/providers/xai/index.d.ts +1 -1
- package/dist/providers/xai/index.js +51 -5
- package/dist/providers/xai/index.js.map +1 -1
- package/dist/providers/xai/index.mjs +51 -5
- package/dist/providers/xai/index.mjs.map +1 -1
- package/dist/{types-D20jKwJW.d.mts → types-COAOEe_y.d.mts} +68 -8
- package/dist/{types-D20jKwJW.d.ts → types-COAOEe_y.d.ts} +68 -8
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1147,6 +1147,279 @@ var GenerateResult = class {
|
|
|
1147
1147
|
}
|
|
1148
1148
|
};
|
|
1149
1149
|
|
|
1150
|
+
// src/server/tool-selection.ts
|
|
1151
|
+
var BM25_K1 = 1.2;
|
|
1152
|
+
var BM25_B = 0.75;
|
|
1153
|
+
var MIN_SCORE = 0.1;
|
|
1154
|
+
function unique(values) {
|
|
1155
|
+
return [...new Set(values)];
|
|
1156
|
+
}
|
|
1157
|
+
function tokenize(text) {
|
|
1158
|
+
return text.toLowerCase().replace(/[^a-z0-9_\s-]/g, " ").split(/\s+/).filter((token) => token.length > 1);
|
|
1159
|
+
}
|
|
1160
|
+
function stringifyContent(content) {
|
|
1161
|
+
if (typeof content === "string") return content;
|
|
1162
|
+
if (!content) return "";
|
|
1163
|
+
try {
|
|
1164
|
+
return JSON.stringify(content);
|
|
1165
|
+
} catch {
|
|
1166
|
+
return String(content);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
function buildToolQuery(messages) {
|
|
1170
|
+
return messages.filter((m) => m.role === "user" || m.role === "assistant").slice(-3).map((m) => stringifyContent(m.content)).filter(Boolean).join(" ");
|
|
1171
|
+
}
|
|
1172
|
+
function buildSearchText(tool2) {
|
|
1173
|
+
return [
|
|
1174
|
+
tool2.name.replace(/_/g, " "),
|
|
1175
|
+
tool2.description,
|
|
1176
|
+
tool2.category ?? "",
|
|
1177
|
+
tool2.group ?? "",
|
|
1178
|
+
...tool2.profiles ?? [],
|
|
1179
|
+
...tool2.searchKeywords ?? []
|
|
1180
|
+
].filter(Boolean).join(" ");
|
|
1181
|
+
}
|
|
1182
|
+
function matchesSelector(tool2, selector, activeProfile) {
|
|
1183
|
+
const normalized = selector.trim().toLowerCase();
|
|
1184
|
+
if (!normalized) return false;
|
|
1185
|
+
if (normalized === "*" || normalized === "all") return true;
|
|
1186
|
+
if (normalized === tool2.name.toLowerCase()) return true;
|
|
1187
|
+
if (normalized.startsWith("group:")) {
|
|
1188
|
+
return (tool2.group ?? "").toLowerCase() === normalized.slice(6);
|
|
1189
|
+
}
|
|
1190
|
+
if (normalized.startsWith("category:")) {
|
|
1191
|
+
return (tool2.category ?? "").toLowerCase() === normalized.slice(9);
|
|
1192
|
+
}
|
|
1193
|
+
if (normalized.startsWith("profile:")) {
|
|
1194
|
+
return (tool2.profiles ?? []).map((v) => v.toLowerCase()).includes(normalized.slice(8));
|
|
1195
|
+
}
|
|
1196
|
+
if (activeProfile && normalized === activeProfile.toLowerCase()) {
|
|
1197
|
+
return (tool2.profiles ?? []).map((v) => v.toLowerCase()).includes(normalized);
|
|
1198
|
+
}
|
|
1199
|
+
return false;
|
|
1200
|
+
}
|
|
1201
|
+
function scoreTool(tool2, queryTokens, activeProfile) {
|
|
1202
|
+
const haystack = [
|
|
1203
|
+
tool2.name,
|
|
1204
|
+
tool2.description,
|
|
1205
|
+
tool2.category,
|
|
1206
|
+
tool2.group,
|
|
1207
|
+
...tool2.profiles ?? [],
|
|
1208
|
+
...tool2.searchKeywords ?? []
|
|
1209
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
1210
|
+
let score = tool2.deferLoading ? 0 : 2;
|
|
1211
|
+
if (activeProfile && tool2.profiles?.includes(activeProfile)) score += 2;
|
|
1212
|
+
for (const token of queryTokens) {
|
|
1213
|
+
if (tool2.name.toLowerCase() === token) score += 6;
|
|
1214
|
+
else if (tool2.name.toLowerCase().includes(token)) score += 4;
|
|
1215
|
+
else if (haystack.includes(token)) score += 2;
|
|
1216
|
+
}
|
|
1217
|
+
return score;
|
|
1218
|
+
}
|
|
1219
|
+
function filterToolsByProfile(params) {
|
|
1220
|
+
const available = params.tools.filter((tool2) => tool2.available !== false);
|
|
1221
|
+
const config = params.config;
|
|
1222
|
+
if (!config) return available;
|
|
1223
|
+
const activeProfile = params.activeProfile ?? config.defaultProfile;
|
|
1224
|
+
const includeUnprofiled = config.includeUnprofiled ?? true;
|
|
1225
|
+
const profile = activeProfile ? config.profiles?.[activeProfile] : void 0;
|
|
1226
|
+
let filtered = available;
|
|
1227
|
+
if (profile?.include?.length) {
|
|
1228
|
+
filtered = filtered.filter(
|
|
1229
|
+
(tool2) => profile.include.some(
|
|
1230
|
+
(selector) => matchesSelector(tool2, selector, activeProfile)
|
|
1231
|
+
) || !!activeProfile && tool2.profiles?.includes(activeProfile)
|
|
1232
|
+
);
|
|
1233
|
+
} else if (activeProfile) {
|
|
1234
|
+
filtered = filtered.filter((tool2) => {
|
|
1235
|
+
if (tool2.profiles?.length) return tool2.profiles.includes(activeProfile);
|
|
1236
|
+
return includeUnprofiled;
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
if (profile?.exclude?.length) {
|
|
1240
|
+
filtered = filtered.filter(
|
|
1241
|
+
(tool2) => !profile.exclude.some(
|
|
1242
|
+
(selector) => matchesSelector(tool2, selector, activeProfile)
|
|
1243
|
+
)
|
|
1244
|
+
);
|
|
1245
|
+
}
|
|
1246
|
+
return filtered;
|
|
1247
|
+
}
|
|
1248
|
+
function calculateBM25Score(tool2, queryTerms, idf, avgDocLength, activeProfile) {
|
|
1249
|
+
const text = buildSearchText(tool2);
|
|
1250
|
+
const tokens = tokenize(text);
|
|
1251
|
+
const docLength = Math.max(1, tokens.length);
|
|
1252
|
+
let score = 0;
|
|
1253
|
+
for (const term of queryTerms) {
|
|
1254
|
+
const termFreq = tokens.filter((t) => t === term).length;
|
|
1255
|
+
if (termFreq === 0) continue;
|
|
1256
|
+
const termIDF = idf.get(term) ?? 0;
|
|
1257
|
+
const numerator = termFreq * (BM25_K1 + 1);
|
|
1258
|
+
const denominator = termFreq + BM25_K1 * (1 - BM25_B + BM25_B * (docLength / avgDocLength));
|
|
1259
|
+
score += termIDF * (numerator / denominator);
|
|
1260
|
+
}
|
|
1261
|
+
const nameLower = tool2.name.toLowerCase();
|
|
1262
|
+
for (const term of queryTerms) {
|
|
1263
|
+
if (nameLower === term) score += 3;
|
|
1264
|
+
else if (nameLower.includes(term)) score += 1.5;
|
|
1265
|
+
}
|
|
1266
|
+
if (activeProfile && tool2.profiles?.includes(activeProfile)) score += 0.75;
|
|
1267
|
+
return score;
|
|
1268
|
+
}
|
|
1269
|
+
function selectTools(params) {
|
|
1270
|
+
const config = params.config;
|
|
1271
|
+
const available = filterToolsByProfile({
|
|
1272
|
+
tools: params.tools,
|
|
1273
|
+
config,
|
|
1274
|
+
activeProfile: params.activeProfile
|
|
1275
|
+
});
|
|
1276
|
+
if (!config) return available;
|
|
1277
|
+
const activeProfile = params.activeProfile ?? config.defaultProfile;
|
|
1278
|
+
const forceIncludeNames = new Set(params.forceIncludeNames ?? []);
|
|
1279
|
+
let filtered = available.filter(
|
|
1280
|
+
(tool2) => !tool2.deferLoading || forceIncludeNames.has(tool2.name)
|
|
1281
|
+
);
|
|
1282
|
+
if (filtered.length === 0) return filtered;
|
|
1283
|
+
const maxTools = Math.max(1, Math.min(config.maxEagerTools, filtered.length));
|
|
1284
|
+
const queryTokens = unique(tokenize(buildToolQuery(params.messages)));
|
|
1285
|
+
const ranked = [...filtered].sort((a, b) => {
|
|
1286
|
+
const diff = scoreTool(b, queryTokens, activeProfile) - scoreTool(a, queryTokens, activeProfile);
|
|
1287
|
+
return diff !== 0 ? diff : a.name.localeCompare(b.name);
|
|
1288
|
+
});
|
|
1289
|
+
if (forceIncludeNames.size === 0) return ranked.slice(0, maxTools);
|
|
1290
|
+
const forced = ranked.filter((t) => forceIncludeNames.has(t.name));
|
|
1291
|
+
const others = ranked.filter((t) => !forceIncludeNames.has(t.name));
|
|
1292
|
+
const remaining = Math.max(0, maxTools - forced.length);
|
|
1293
|
+
return [...forced, ...others.slice(0, remaining)];
|
|
1294
|
+
}
|
|
1295
|
+
function searchTools(params) {
|
|
1296
|
+
const queryTerms = unique(tokenize(params.query));
|
|
1297
|
+
if (queryTerms.length === 0) return [];
|
|
1298
|
+
const candidates = filterToolsByProfile({
|
|
1299
|
+
tools: params.tools,
|
|
1300
|
+
config: params.config,
|
|
1301
|
+
activeProfile: params.activeProfile
|
|
1302
|
+
}).filter((tool2) => {
|
|
1303
|
+
if ((params.excludeNames ?? []).includes(tool2.name)) return false;
|
|
1304
|
+
if (params.includeSelected) return true;
|
|
1305
|
+
return tool2.deferLoading === true;
|
|
1306
|
+
});
|
|
1307
|
+
if (candidates.length === 0) return [];
|
|
1308
|
+
const docs = candidates.map((tool2) => tokenize(buildSearchText(tool2)));
|
|
1309
|
+
const avgDocLength = docs.reduce((sum, tokens) => sum + Math.max(1, tokens.length), 0) / docs.length;
|
|
1310
|
+
const idf = /* @__PURE__ */ new Map();
|
|
1311
|
+
for (const term of queryTerms) {
|
|
1312
|
+
const docFreq = docs.reduce(
|
|
1313
|
+
(count, tokens) => count + (tokens.includes(term) ? 1 : 0),
|
|
1314
|
+
0
|
|
1315
|
+
);
|
|
1316
|
+
idf.set(
|
|
1317
|
+
term,
|
|
1318
|
+
Math.log((docs.length - docFreq + 0.5) / (docFreq + 0.5) + 1)
|
|
1319
|
+
);
|
|
1320
|
+
}
|
|
1321
|
+
const limit = Math.max(1, params.limit ?? params.config?.maxResults ?? 8);
|
|
1322
|
+
const activeProfile = params.activeProfile ?? params.config?.defaultProfile;
|
|
1323
|
+
return candidates.map((tool2) => ({
|
|
1324
|
+
tool: tool2,
|
|
1325
|
+
score: calculateBM25Score(
|
|
1326
|
+
tool2,
|
|
1327
|
+
queryTerms,
|
|
1328
|
+
idf,
|
|
1329
|
+
avgDocLength,
|
|
1330
|
+
activeProfile
|
|
1331
|
+
)
|
|
1332
|
+
})).filter((entry) => entry.score >= MIN_SCORE).sort((a, b) => {
|
|
1333
|
+
const diff = b.score - a.score;
|
|
1334
|
+
return diff !== 0 ? diff : a.tool.name.localeCompare(b.tool.name);
|
|
1335
|
+
}).slice(0, limit).map(({ tool: tool2, score }) => ({
|
|
1336
|
+
name: tool2.name,
|
|
1337
|
+
description: tool2.description,
|
|
1338
|
+
location: tool2.location,
|
|
1339
|
+
category: tool2.category,
|
|
1340
|
+
group: tool2.group,
|
|
1341
|
+
profiles: tool2.profiles,
|
|
1342
|
+
searchKeywords: tool2.searchKeywords,
|
|
1343
|
+
score: Number(score.toFixed(4))
|
|
1344
|
+
}));
|
|
1345
|
+
}
|
|
1346
|
+
function normalizeModelName(modelName) {
|
|
1347
|
+
return (modelName ?? "").trim().toLowerCase();
|
|
1348
|
+
}
|
|
1349
|
+
function supportsAnthropicNativeToolSearch(modelName) {
|
|
1350
|
+
const model = normalizeModelName(modelName);
|
|
1351
|
+
if (!model || model.includes("haiku")) return false;
|
|
1352
|
+
return /(?:^|[-_ ])(?:sonnet|opus)[-_ ]?4(?:$|[-_. ])/.test(model) || /claude[-_ ](?:sonnet|opus)[-_ ]?4/.test(model) || /claude[-_ ]?4[-_ ](?:sonnet|opus)/.test(model);
|
|
1353
|
+
}
|
|
1354
|
+
function supportsOpenAINativeToolSearch(modelName) {
|
|
1355
|
+
const model = normalizeModelName(modelName);
|
|
1356
|
+
if (!model) return false;
|
|
1357
|
+
const match = model.match(/^gpt-5(?:[._-](\d+))?(?:$|[._-])/);
|
|
1358
|
+
if (!match) return false;
|
|
1359
|
+
const minorVersion = match[1] ? Number.parseInt(match[1], 10) : Number.NaN;
|
|
1360
|
+
if (!Number.isFinite(minorVersion)) return false;
|
|
1361
|
+
return minorVersion >= 4;
|
|
1362
|
+
}
|
|
1363
|
+
function resolveNativeToolSearch(params) {
|
|
1364
|
+
if (!params.config) return null;
|
|
1365
|
+
if (params.providerName === "anthropic" && supportsAnthropicNativeToolSearch(params.modelName)) {
|
|
1366
|
+
return { provider: "anthropic", variant: "bm25" };
|
|
1367
|
+
}
|
|
1368
|
+
if (params.providerName === "openai" && supportsOpenAINativeToolSearch(params.modelName)) {
|
|
1369
|
+
return { provider: "openai", useResponsesApi: true };
|
|
1370
|
+
}
|
|
1371
|
+
return null;
|
|
1372
|
+
}
|
|
1373
|
+
function shouldExposeToolSearch(params) {
|
|
1374
|
+
if (!params.config) return false;
|
|
1375
|
+
const deferredCount = params.tools.filter((t) => t.deferLoading).length;
|
|
1376
|
+
if (deferredCount === 0) return false;
|
|
1377
|
+
return params.tools.length >= params.config.exposeWhenExceeds;
|
|
1378
|
+
}
|
|
1379
|
+
function buildProviderToolOptions(params) {
|
|
1380
|
+
const { toolChoice, parallelCalls } = params.config ?? {};
|
|
1381
|
+
const resolvedNativeSearch = resolveNativeToolSearch({
|
|
1382
|
+
providerName: params.providerName,
|
|
1383
|
+
modelName: params.modelName,
|
|
1384
|
+
config: params.config
|
|
1385
|
+
});
|
|
1386
|
+
if (params.providerName === "openai") {
|
|
1387
|
+
if (toolChoice === void 0 && parallelCalls === void 0 && !resolvedNativeSearch) {
|
|
1388
|
+
return void 0;
|
|
1389
|
+
}
|
|
1390
|
+
let oaiToolChoice;
|
|
1391
|
+
if (toolChoice === "required") oaiToolChoice = "required";
|
|
1392
|
+
else if (toolChoice === "auto") oaiToolChoice = "auto";
|
|
1393
|
+
return {
|
|
1394
|
+
openai: {
|
|
1395
|
+
toolChoice: oaiToolChoice,
|
|
1396
|
+
parallelToolCalls: parallelCalls,
|
|
1397
|
+
nativeToolSearch: resolvedNativeSearch?.provider === "openai" ? {
|
|
1398
|
+
enabled: true,
|
|
1399
|
+
useResponsesApi: resolvedNativeSearch.useResponsesApi
|
|
1400
|
+
} : void 0
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
if (params.providerName === "anthropic") {
|
|
1405
|
+
if (toolChoice === void 0 && parallelCalls === void 0 && !resolvedNativeSearch) {
|
|
1406
|
+
return void 0;
|
|
1407
|
+
}
|
|
1408
|
+
let anthropicToolChoice;
|
|
1409
|
+
if (toolChoice === "required") anthropicToolChoice = "any";
|
|
1410
|
+
else if (toolChoice === "auto") anthropicToolChoice = "auto";
|
|
1411
|
+
return {
|
|
1412
|
+
anthropic: {
|
|
1413
|
+
toolChoice: anthropicToolChoice,
|
|
1414
|
+
// parallelCalls: false → disableParallelToolUse: true
|
|
1415
|
+
disableParallelToolUse: parallelCalls === false ? true : void 0,
|
|
1416
|
+
nativeToolSearch: resolvedNativeSearch?.provider === "anthropic" ? { enabled: true, variant: resolvedNativeSearch.variant ?? "bm25" } : void 0
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
return void 0;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1150
1423
|
// src/server/runtime.ts
|
|
1151
1424
|
function buildToolResultForAI(tool2, result, args) {
|
|
1152
1425
|
const typedResult = result;
|
|
@@ -1271,7 +1544,8 @@ var Runtime = class {
|
|
|
1271
1544
|
systemPrompt: request.systemPrompt || this.config.systemPrompt,
|
|
1272
1545
|
config: request.config,
|
|
1273
1546
|
signal,
|
|
1274
|
-
webSearch: this.getWebSearchConfig()
|
|
1547
|
+
webSearch: this.getWebSearchConfig(),
|
|
1548
|
+
debug: this.config.debug
|
|
1275
1549
|
};
|
|
1276
1550
|
const stream = this.adapter.stream(completionRequest);
|
|
1277
1551
|
for await (const event of stream) {
|
|
@@ -1328,11 +1602,18 @@ var Runtime = class {
|
|
|
1328
1602
|
try {
|
|
1329
1603
|
const body = await request.json();
|
|
1330
1604
|
if (this.config.debug) {
|
|
1331
|
-
console.log("[Copilot SDK] Request:",
|
|
1605
|
+
console.log("[Copilot SDK] Request:", {
|
|
1606
|
+
messageCount: body.messages?.length ?? 0,
|
|
1607
|
+
toolCount: body.tools?.length ?? 0,
|
|
1608
|
+
hasSystemPrompt: Boolean(body.systemPrompt),
|
|
1609
|
+
threadId: body.threadId,
|
|
1610
|
+
streaming: body.streaming !== false,
|
|
1611
|
+
toolProfile: body.toolProfile
|
|
1612
|
+
});
|
|
1332
1613
|
}
|
|
1333
1614
|
const signal = request.signal;
|
|
1334
1615
|
const hasTools = body.tools && body.tools.length > 0 || this.tools.size > 0;
|
|
1335
|
-
const useAgentLoop = hasTools
|
|
1616
|
+
const useAgentLoop = hasTools;
|
|
1336
1617
|
if (body.streaming === false) {
|
|
1337
1618
|
return this.handleNonStreamingRequest(
|
|
1338
1619
|
body,
|
|
@@ -1588,6 +1869,170 @@ var Runtime = class {
|
|
|
1588
1869
|
}
|
|
1589
1870
|
return void 0;
|
|
1590
1871
|
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Resolve effective tool selection config for a request.
|
|
1874
|
+
*/
|
|
1875
|
+
resolveEffectiveToolSelectionConfig(request) {
|
|
1876
|
+
const toolSearch = "toolSearch" in this.config ? this.config.toolSearch : void 0;
|
|
1877
|
+
const hasDeferredServerTool = [...this.tools.values()].some(
|
|
1878
|
+
(t) => t.deferLoading
|
|
1879
|
+
);
|
|
1880
|
+
const hasDeferredInRequest = request.tools?.some((t) => t.deferLoading);
|
|
1881
|
+
if (!hasDeferredServerTool && !hasDeferredInRequest && !toolSearch) {
|
|
1882
|
+
return void 0;
|
|
1883
|
+
}
|
|
1884
|
+
return {
|
|
1885
|
+
maxEagerTools: toolSearch?.maxEagerTools ?? 20,
|
|
1886
|
+
maxResults: toolSearch?.maxResults ?? 8,
|
|
1887
|
+
exposeWhenExceeds: toolSearch?.exposeWhenExceeds ?? 8,
|
|
1888
|
+
toolChoice: toolSearch?.toolChoice,
|
|
1889
|
+
parallelCalls: toolSearch?.parallelCalls,
|
|
1890
|
+
defaultProfile: toolSearch?.defaultProfile,
|
|
1891
|
+
profiles: toolSearch?.profiles,
|
|
1892
|
+
includeUnprofiled: toolSearch?.includeUnprofiled
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
collectToolsForRequest(request) {
|
|
1896
|
+
const allTools = [...this.tools.values()];
|
|
1897
|
+
if (request.tools) {
|
|
1898
|
+
for (const tool2 of request.tools) {
|
|
1899
|
+
allTools.push({
|
|
1900
|
+
name: tool2.name,
|
|
1901
|
+
description: tool2.description,
|
|
1902
|
+
location: "client",
|
|
1903
|
+
category: tool2.category,
|
|
1904
|
+
group: tool2.group,
|
|
1905
|
+
deferLoading: tool2.deferLoading,
|
|
1906
|
+
profiles: tool2.profiles,
|
|
1907
|
+
searchKeywords: tool2.searchKeywords,
|
|
1908
|
+
inputSchema: tool2.inputSchema
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
return allTools;
|
|
1913
|
+
}
|
|
1914
|
+
selectToolsForRequest(request, allTools, toolSearchState) {
|
|
1915
|
+
return selectTools({
|
|
1916
|
+
tools: allTools,
|
|
1917
|
+
messages: request.messages,
|
|
1918
|
+
config: this.resolveEffectiveToolSelectionConfig(request),
|
|
1919
|
+
activeProfile: request.toolProfile,
|
|
1920
|
+
forceIncludeNames: toolSearchState?.loadedToolNames
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
resolveNativeToolSearchForRequest(request) {
|
|
1924
|
+
return resolveNativeToolSearch({
|
|
1925
|
+
providerName: this.adapter.provider,
|
|
1926
|
+
modelName: this.getModel(),
|
|
1927
|
+
config: this.resolveEffectiveToolSelectionConfig(request)
|
|
1928
|
+
});
|
|
1929
|
+
}
|
|
1930
|
+
buildNativeToolCatalogForRequest(request, allTools) {
|
|
1931
|
+
return filterToolsByProfile({
|
|
1932
|
+
tools: allTools,
|
|
1933
|
+
config: this.resolveEffectiveToolSelectionConfig(request),
|
|
1934
|
+
activeProfile: request.toolProfile
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
buildProviderToolOptionsForRequest(selectedTools, request) {
|
|
1938
|
+
return buildProviderToolOptions({
|
|
1939
|
+
providerName: this.adapter.provider,
|
|
1940
|
+
modelName: this.getModel(),
|
|
1941
|
+
config: this.resolveEffectiveToolSelectionConfig(request),
|
|
1942
|
+
metaToolName: this.getToolSearchMetaToolName()
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
getToolSearchMetaToolName() {
|
|
1946
|
+
const toolSearch = "toolSearch" in this.config ? this.config.toolSearch : void 0;
|
|
1947
|
+
return toolSearch?.name ?? "search_tools";
|
|
1948
|
+
}
|
|
1949
|
+
createToolSearchTool(request, allTools, selectedTools) {
|
|
1950
|
+
if (!shouldExposeToolSearch({
|
|
1951
|
+
tools: allTools,
|
|
1952
|
+
config: this.resolveEffectiveToolSelectionConfig(request)
|
|
1953
|
+
})) {
|
|
1954
|
+
return null;
|
|
1955
|
+
}
|
|
1956
|
+
const toolName = this.getToolSearchMetaToolName();
|
|
1957
|
+
const excludedNames = selectedTools.map((tool2) => tool2.name);
|
|
1958
|
+
return {
|
|
1959
|
+
name: toolName,
|
|
1960
|
+
description: "toolSearch" in this.config && this.config.toolSearch?.description || "Search available deferred tools and load the most relevant ones for the next step when the right tool is not currently exposed.",
|
|
1961
|
+
location: "server",
|
|
1962
|
+
hidden: true,
|
|
1963
|
+
inputSchema: {
|
|
1964
|
+
type: "object",
|
|
1965
|
+
properties: {
|
|
1966
|
+
query: {
|
|
1967
|
+
type: "string",
|
|
1968
|
+
description: "Describe the tool capability you need to find."
|
|
1969
|
+
},
|
|
1970
|
+
limit: {
|
|
1971
|
+
type: "number",
|
|
1972
|
+
description: "Maximum number of matching tools to load."
|
|
1973
|
+
}
|
|
1974
|
+
},
|
|
1975
|
+
required: ["query"]
|
|
1976
|
+
},
|
|
1977
|
+
handler: async (params) => {
|
|
1978
|
+
const args = params;
|
|
1979
|
+
const results = searchTools({
|
|
1980
|
+
tools: allTools,
|
|
1981
|
+
query: args.query,
|
|
1982
|
+
config: this.resolveEffectiveToolSelectionConfig(request),
|
|
1983
|
+
activeProfile: request.toolProfile,
|
|
1984
|
+
limit: args.limit,
|
|
1985
|
+
excludeNames: excludedNames
|
|
1986
|
+
});
|
|
1987
|
+
if (this.config.debug) {
|
|
1988
|
+
console.log("[Copilot SDK] search_tools result:", {
|
|
1989
|
+
query: args.query,
|
|
1990
|
+
activeProfile: request.toolProfile,
|
|
1991
|
+
selectedToolCount: selectedTools.length,
|
|
1992
|
+
catalogCount: allTools.length,
|
|
1993
|
+
loadedTools: results.map((result) => result.name),
|
|
1994
|
+
results: results.map((result) => ({
|
|
1995
|
+
name: result.name,
|
|
1996
|
+
location: result.location,
|
|
1997
|
+
category: result.category,
|
|
1998
|
+
group: result.group,
|
|
1999
|
+
score: result.score
|
|
2000
|
+
}))
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
return {
|
|
2004
|
+
success: true,
|
|
2005
|
+
query: args.query,
|
|
2006
|
+
loadedTools: results.map((result) => result.name),
|
|
2007
|
+
results
|
|
2008
|
+
};
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
2012
|
+
extendLoadedToolNames(current, results) {
|
|
2013
|
+
const loaded = new Set(current?.loadedToolNames ?? []);
|
|
2014
|
+
const searchToolName = this.getToolSearchMetaToolName();
|
|
2015
|
+
for (const result of results) {
|
|
2016
|
+
if (result.name !== searchToolName) {
|
|
2017
|
+
continue;
|
|
2018
|
+
}
|
|
2019
|
+
const typedResult = result.result;
|
|
2020
|
+
if (!Array.isArray(typedResult?.loadedTools)) {
|
|
2021
|
+
continue;
|
|
2022
|
+
}
|
|
2023
|
+
for (const toolName of typedResult.loadedTools) {
|
|
2024
|
+
if (typeof toolName === "string" && toolName) {
|
|
2025
|
+
loaded.add(toolName);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
if (loaded.size === 0) {
|
|
2030
|
+
return current;
|
|
2031
|
+
}
|
|
2032
|
+
return {
|
|
2033
|
+
loadedToolNames: [...loaded]
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
1591
2036
|
/**
|
|
1592
2037
|
* Process a chat request with tool support (Vercel AI SDK pattern)
|
|
1593
2038
|
*
|
|
@@ -1599,8 +2044,8 @@ var Runtime = class {
|
|
|
1599
2044
|
* 5. Loop continues until no more tool calls or max iterations reached
|
|
1600
2045
|
* 6. Returns all new messages in the done event for client to append
|
|
1601
2046
|
*/
|
|
1602
|
-
async *processChatWithLoop(request, signal, _accumulatedMessages, _isRecursive, _httpRequest) {
|
|
1603
|
-
const debug = this.config.debug
|
|
2047
|
+
async *processChatWithLoop(request, signal, _accumulatedMessages, _isRecursive, _httpRequest, _toolSearchState) {
|
|
2048
|
+
const debug = this.config.debug;
|
|
1604
2049
|
if (request.streaming === false) {
|
|
1605
2050
|
if (debug) {
|
|
1606
2051
|
console.log("[Copilot SDK] Using non-streaming mode");
|
|
@@ -1610,29 +2055,41 @@ var Runtime = class {
|
|
|
1610
2055
|
signal,
|
|
1611
2056
|
_accumulatedMessages,
|
|
1612
2057
|
_isRecursive,
|
|
1613
|
-
_httpRequest
|
|
2058
|
+
_httpRequest,
|
|
2059
|
+
_toolSearchState
|
|
1614
2060
|
)) {
|
|
1615
2061
|
yield event;
|
|
1616
2062
|
}
|
|
1617
2063
|
return;
|
|
1618
2064
|
}
|
|
1619
2065
|
const newMessages = _accumulatedMessages || [];
|
|
1620
|
-
this.config.
|
|
1621
|
-
const allTools =
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
2066
|
+
this.config.maxIterations ?? 20;
|
|
2067
|
+
const allTools = this.collectToolsForRequest(request);
|
|
2068
|
+
const nativeToolSearch = this.resolveNativeToolSearchForRequest(request);
|
|
2069
|
+
const nativeToolCatalog = nativeToolSearch ? this.buildNativeToolCatalogForRequest(request, allTools) : null;
|
|
2070
|
+
const selectedTools = nativeToolCatalog ?? this.selectToolsForRequest(request, allTools, _toolSearchState);
|
|
2071
|
+
const toolSearchTool = nativeToolSearch ? null : this.createToolSearchTool(request, allTools, selectedTools);
|
|
2072
|
+
const effectiveSelectedTools = nativeToolCatalog ? nativeToolCatalog : toolSearchTool ? [...selectedTools, toolSearchTool] : selectedTools;
|
|
2073
|
+
const providerToolOptions = this.buildProviderToolOptionsForRequest(
|
|
2074
|
+
effectiveSelectedTools,
|
|
2075
|
+
request
|
|
2076
|
+
);
|
|
2077
|
+
const selectedToolMap = new Map(
|
|
2078
|
+
effectiveSelectedTools.map((tool2) => [tool2.name, tool2])
|
|
2079
|
+
);
|
|
1632
2080
|
if (debug) {
|
|
1633
2081
|
console.log(
|
|
1634
2082
|
`[Copilot SDK] Processing chat with ${allTools.length} tools`
|
|
1635
2083
|
);
|
|
2084
|
+
if (effectiveSelectedTools.length !== allTools.length) {
|
|
2085
|
+
console.log(
|
|
2086
|
+
`[Copilot SDK] Tool selection active: ${effectiveSelectedTools.length}/${allTools.length} tools`,
|
|
2087
|
+
{
|
|
2088
|
+
activeProfile: request.toolProfile,
|
|
2089
|
+
nativeSearch: nativeToolSearch?.provider ?? null
|
|
2090
|
+
}
|
|
2091
|
+
);
|
|
2092
|
+
}
|
|
1636
2093
|
for (let i = 0; i < request.messages.length; i++) {
|
|
1637
2094
|
const msg = request.messages[i];
|
|
1638
2095
|
const hasAttachments = msg.attachments && msg.attachments.length > 0;
|
|
@@ -1657,11 +2114,14 @@ var Runtime = class {
|
|
|
1657
2114
|
messages: [],
|
|
1658
2115
|
// Not used when rawMessages is provided
|
|
1659
2116
|
rawMessages: request.messages,
|
|
1660
|
-
actions: this.convertToolsToActions(
|
|
2117
|
+
actions: nativeToolSearch ? void 0 : this.convertToolsToActions(effectiveSelectedTools),
|
|
2118
|
+
toolDefinitions: nativeToolSearch ? effectiveSelectedTools : void 0,
|
|
1661
2119
|
systemPrompt,
|
|
1662
2120
|
config: request.config,
|
|
1663
2121
|
signal,
|
|
1664
|
-
webSearch: this.getWebSearchConfig()
|
|
2122
|
+
webSearch: this.getWebSearchConfig(),
|
|
2123
|
+
providerToolOptions,
|
|
2124
|
+
debug
|
|
1665
2125
|
};
|
|
1666
2126
|
const stream = this.adapter.stream(completionRequest);
|
|
1667
2127
|
for await (const event of stream) {
|
|
@@ -1738,7 +2198,7 @@ var Runtime = class {
|
|
|
1738
2198
|
const serverToolCalls = [];
|
|
1739
2199
|
const clientToolCalls = [];
|
|
1740
2200
|
for (const tc of toolCalls) {
|
|
1741
|
-
const tool2 =
|
|
2201
|
+
const tool2 = selectedToolMap.get(tc.name);
|
|
1742
2202
|
if (tool2?.location === "server" && tool2.handler) {
|
|
1743
2203
|
serverToolCalls.push(tc);
|
|
1744
2204
|
} else {
|
|
@@ -1748,7 +2208,7 @@ var Runtime = class {
|
|
|
1748
2208
|
const serverToolResults = [];
|
|
1749
2209
|
const toolContextData = "toolContext" in this.config ? this.config.toolContext : void 0;
|
|
1750
2210
|
for (const tc of serverToolCalls) {
|
|
1751
|
-
const tool2 =
|
|
2211
|
+
const tool2 = selectedToolMap.get(tc.name);
|
|
1752
2212
|
if (tool2?.handler) {
|
|
1753
2213
|
if (debug) {
|
|
1754
2214
|
console.log(`[Copilot SDK] Executing server-side tool: ${tc.name}`);
|
|
@@ -1772,6 +2232,7 @@ var Runtime = class {
|
|
|
1772
2232
|
yield {
|
|
1773
2233
|
type: "action:end",
|
|
1774
2234
|
id: tc.id,
|
|
2235
|
+
name: tc.name,
|
|
1775
2236
|
result
|
|
1776
2237
|
};
|
|
1777
2238
|
} catch (error) {
|
|
@@ -1789,6 +2250,7 @@ var Runtime = class {
|
|
|
1789
2250
|
yield {
|
|
1790
2251
|
type: "action:end",
|
|
1791
2252
|
id: tc.id,
|
|
2253
|
+
name: tc.name,
|
|
1792
2254
|
error: error instanceof Error ? error.message : "Tool execution failed"
|
|
1793
2255
|
};
|
|
1794
2256
|
}
|
|
@@ -1834,6 +2296,13 @@ var Runtime = class {
|
|
|
1834
2296
|
...request,
|
|
1835
2297
|
messages: messagesWithResults
|
|
1836
2298
|
};
|
|
2299
|
+
const nextToolSearchState = this.extendLoadedToolNames(
|
|
2300
|
+
_toolSearchState,
|
|
2301
|
+
serverToolResults.map((result) => ({
|
|
2302
|
+
name: result.name,
|
|
2303
|
+
result: result.result
|
|
2304
|
+
}))
|
|
2305
|
+
);
|
|
1837
2306
|
yield { type: "message:end" };
|
|
1838
2307
|
for await (const event of this.processChatWithLoop(
|
|
1839
2308
|
nextRequest,
|
|
@@ -1841,7 +2310,8 @@ var Runtime = class {
|
|
|
1841
2310
|
newMessages,
|
|
1842
2311
|
true,
|
|
1843
2312
|
// Mark as recursive
|
|
1844
|
-
_httpRequest
|
|
2313
|
+
_httpRequest,
|
|
2314
|
+
nextToolSearchState
|
|
1845
2315
|
)) {
|
|
1846
2316
|
yield event;
|
|
1847
2317
|
}
|
|
@@ -1900,22 +2370,14 @@ var Runtime = class {
|
|
|
1900
2370
|
* - Easier debugging (full response at once)
|
|
1901
2371
|
* - More predictable retry behavior
|
|
1902
2372
|
*/
|
|
1903
|
-
async *processChatWithLoopNonStreaming(request, signal, _accumulatedMessages, _isRecursive, _httpRequest) {
|
|
2373
|
+
async *processChatWithLoopNonStreaming(request, signal, _accumulatedMessages, _isRecursive, _httpRequest, _toolSearchState) {
|
|
1904
2374
|
const newMessages = _accumulatedMessages || [];
|
|
1905
|
-
const debug = this.config.debug
|
|
1906
|
-
const maxIterations = this.config.
|
|
2375
|
+
const debug = this.config.debug;
|
|
2376
|
+
const maxIterations = this.config.maxIterations ?? 20;
|
|
1907
2377
|
let accumulatedUsage = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
|
|
1908
|
-
const allTools =
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
allTools.push({
|
|
1912
|
-
name: tool2.name,
|
|
1913
|
-
description: tool2.description,
|
|
1914
|
-
location: "client",
|
|
1915
|
-
inputSchema: tool2.inputSchema
|
|
1916
|
-
});
|
|
1917
|
-
}
|
|
1918
|
-
}
|
|
2378
|
+
const allTools = this.collectToolsForRequest(request);
|
|
2379
|
+
const nativeToolSearch = this.resolveNativeToolSearchForRequest(request);
|
|
2380
|
+
let toolSearchState = _toolSearchState;
|
|
1919
2381
|
const systemPrompt = request.systemPrompt || this.config.systemPrompt || "";
|
|
1920
2382
|
let iteration = 0;
|
|
1921
2383
|
let conversationMessages = request.messages;
|
|
@@ -1944,20 +2406,35 @@ var Runtime = class {
|
|
|
1944
2406
|
signal,
|
|
1945
2407
|
_accumulatedMessages,
|
|
1946
2408
|
_isRecursive,
|
|
1947
|
-
_httpRequest
|
|
2409
|
+
_httpRequest,
|
|
2410
|
+
toolSearchState
|
|
1948
2411
|
)) {
|
|
1949
2412
|
yield event;
|
|
1950
2413
|
}
|
|
1951
2414
|
return;
|
|
1952
2415
|
}
|
|
2416
|
+
const nativeToolCatalog = nativeToolSearch ? this.buildNativeToolCatalogForRequest(request, allTools) : null;
|
|
2417
|
+
const selectedTools = nativeToolCatalog ?? this.selectToolsForRequest(request, allTools, toolSearchState);
|
|
2418
|
+
const toolSearchTool = nativeToolSearch ? null : this.createToolSearchTool(request, allTools, selectedTools);
|
|
2419
|
+
const effectiveSelectedTools = nativeToolCatalog ? nativeToolCatalog : toolSearchTool ? [...selectedTools, toolSearchTool] : selectedTools;
|
|
2420
|
+
const providerToolOptions = this.buildProviderToolOptionsForRequest(
|
|
2421
|
+
effectiveSelectedTools,
|
|
2422
|
+
request
|
|
2423
|
+
);
|
|
2424
|
+
const selectedToolMap = new Map(
|
|
2425
|
+
effectiveSelectedTools.map((tool2) => [tool2.name, tool2])
|
|
2426
|
+
);
|
|
1953
2427
|
const completionRequest = {
|
|
1954
2428
|
messages: [],
|
|
1955
2429
|
rawMessages: conversationMessages,
|
|
1956
|
-
actions: this.convertToolsToActions(
|
|
2430
|
+
actions: nativeToolSearch ? void 0 : this.convertToolsToActions(effectiveSelectedTools),
|
|
2431
|
+
toolDefinitions: nativeToolSearch ? effectiveSelectedTools : void 0,
|
|
1957
2432
|
systemPrompt,
|
|
1958
2433
|
config: request.config,
|
|
1959
2434
|
signal,
|
|
1960
|
-
webSearch: this.getWebSearchConfig()
|
|
2435
|
+
webSearch: this.getWebSearchConfig(),
|
|
2436
|
+
providerToolOptions,
|
|
2437
|
+
debug
|
|
1961
2438
|
};
|
|
1962
2439
|
try {
|
|
1963
2440
|
const result = await this.adapter.complete(completionRequest);
|
|
@@ -1983,7 +2460,7 @@ var Runtime = class {
|
|
|
1983
2460
|
const serverToolCalls = [];
|
|
1984
2461
|
const clientToolCalls = [];
|
|
1985
2462
|
for (const tc of result.toolCalls) {
|
|
1986
|
-
const tool2 =
|
|
2463
|
+
const tool2 = selectedToolMap.get(tc.name);
|
|
1987
2464
|
if (tool2?.location === "server" && tool2.handler) {
|
|
1988
2465
|
serverToolCalls.push(tc);
|
|
1989
2466
|
} else {
|
|
@@ -1995,7 +2472,7 @@ var Runtime = class {
|
|
|
1995
2472
|
}
|
|
1996
2473
|
}
|
|
1997
2474
|
for (const tc of result.toolCalls) {
|
|
1998
|
-
const tool2 =
|
|
2475
|
+
const tool2 = selectedToolMap.get(tc.name);
|
|
1999
2476
|
yield {
|
|
2000
2477
|
type: "action:start",
|
|
2001
2478
|
id: tc.id,
|
|
@@ -2011,7 +2488,7 @@ var Runtime = class {
|
|
|
2011
2488
|
const serverToolResults = [];
|
|
2012
2489
|
const toolContextData = "toolContext" in this.config ? this.config.toolContext : void 0;
|
|
2013
2490
|
for (const tc of serverToolCalls) {
|
|
2014
|
-
const tool2 =
|
|
2491
|
+
const tool2 = selectedToolMap.get(tc.name);
|
|
2015
2492
|
if (tool2?.handler) {
|
|
2016
2493
|
if (debug) {
|
|
2017
2494
|
console.log(`[Copilot SDK] Executing tool: ${tc.name}`);
|
|
@@ -2035,6 +2512,7 @@ var Runtime = class {
|
|
|
2035
2512
|
yield {
|
|
2036
2513
|
type: "action:end",
|
|
2037
2514
|
id: tc.id,
|
|
2515
|
+
name: tc.name,
|
|
2038
2516
|
result: toolResult
|
|
2039
2517
|
};
|
|
2040
2518
|
} catch (error) {
|
|
@@ -2052,6 +2530,7 @@ var Runtime = class {
|
|
|
2052
2530
|
yield {
|
|
2053
2531
|
type: "action:end",
|
|
2054
2532
|
id: tc.id,
|
|
2533
|
+
name: tc.name,
|
|
2055
2534
|
error: error instanceof Error ? error.message : "Tool execution failed"
|
|
2056
2535
|
};
|
|
2057
2536
|
}
|
|
@@ -2090,6 +2569,13 @@ var Runtime = class {
|
|
|
2090
2569
|
assistantWithToolCalls,
|
|
2091
2570
|
...toolResultMessages
|
|
2092
2571
|
];
|
|
2572
|
+
toolSearchState = this.extendLoadedToolNames(
|
|
2573
|
+
toolSearchState,
|
|
2574
|
+
serverToolResults.map((toolResult) => ({
|
|
2575
|
+
name: toolResult.name,
|
|
2576
|
+
result: toolResult.result
|
|
2577
|
+
}))
|
|
2578
|
+
);
|
|
2093
2579
|
continue;
|
|
2094
2580
|
}
|
|
2095
2581
|
if (clientToolCalls.length > 0) {
|
|
@@ -2552,7 +3038,11 @@ function transformTools(tools) {
|
|
|
2552
3038
|
function: {
|
|
2553
3039
|
name: tool2.name,
|
|
2554
3040
|
description: tool2.description,
|
|
2555
|
-
parameters: tool2.inputSchema
|
|
3041
|
+
parameters: tool2.inputSchema ? {
|
|
3042
|
+
type: "object",
|
|
3043
|
+
properties: tool2.inputSchema.properties ?? {},
|
|
3044
|
+
required: tool2.inputSchema.required
|
|
3045
|
+
} : { type: "object", properties: {} }
|
|
2556
3046
|
}
|
|
2557
3047
|
}));
|
|
2558
3048
|
}
|
|
@@ -2641,7 +3131,11 @@ function transformTools2(tools) {
|
|
|
2641
3131
|
return tools.map((tool2) => ({
|
|
2642
3132
|
name: tool2.name,
|
|
2643
3133
|
description: tool2.description,
|
|
2644
|
-
input_schema: tool2.inputSchema
|
|
3134
|
+
input_schema: tool2.inputSchema ? {
|
|
3135
|
+
type: "object",
|
|
3136
|
+
properties: tool2.inputSchema.properties ?? {},
|
|
3137
|
+
required: tool2.inputSchema.required
|
|
3138
|
+
} : { type: "object", properties: {} }
|
|
2645
3139
|
}));
|
|
2646
3140
|
}
|
|
2647
3141
|
function parseToolCalls2(response) {
|
|
@@ -2722,7 +3216,11 @@ function transformTools3(tools) {
|
|
|
2722
3216
|
functionDeclarations: tools.map((tool2) => ({
|
|
2723
3217
|
name: tool2.name,
|
|
2724
3218
|
description: tool2.description,
|
|
2725
|
-
parameters: tool2.inputSchema
|
|
3219
|
+
parameters: tool2.inputSchema ? {
|
|
3220
|
+
type: "object",
|
|
3221
|
+
properties: tool2.inputSchema.properties ?? {},
|
|
3222
|
+
required: tool2.inputSchema.required
|
|
3223
|
+
} : { type: "object", properties: {} }
|
|
2726
3224
|
}))
|
|
2727
3225
|
}
|
|
2728
3226
|
];
|
|
@@ -2871,29 +3369,34 @@ async function* runAgentLoop(options) {
|
|
|
2871
3369
|
systemPrompt,
|
|
2872
3370
|
provider,
|
|
2873
3371
|
signal,
|
|
2874
|
-
|
|
3372
|
+
maxIterations: optMaxIterations,
|
|
3373
|
+
debug: optDebug,
|
|
3374
|
+
toolSelectionConfig,
|
|
3375
|
+
toolProfile,
|
|
2875
3376
|
callLLM,
|
|
2876
3377
|
executeServerTool,
|
|
2877
3378
|
waitForClientToolResult
|
|
2878
3379
|
} = options;
|
|
2879
|
-
const maxIterations =
|
|
2880
|
-
const debug =
|
|
3380
|
+
const maxIterations = optMaxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
3381
|
+
const debug = optDebug ?? false;
|
|
2881
3382
|
const formatter = getFormatter(provider.name);
|
|
3383
|
+
const toolSearchMetaToolName = "search_tools";
|
|
2882
3384
|
const serverTools = tools.filter((t) => t.location === "server");
|
|
2883
3385
|
const clientTools = tools.filter((t) => t.location === "client");
|
|
2884
3386
|
const allTools = [...serverTools, ...clientTools];
|
|
2885
|
-
const providerTools = formatter.transformTools(allTools);
|
|
2886
3387
|
const conversation = buildConversation(
|
|
2887
3388
|
messages,
|
|
2888
3389
|
systemPrompt
|
|
2889
3390
|
);
|
|
2890
3391
|
let iteration = 0;
|
|
3392
|
+
let loadedToolNames = /* @__PURE__ */ new Set();
|
|
2891
3393
|
if (debug) {
|
|
2892
3394
|
console.log("[AgentLoop] Starting with", {
|
|
2893
3395
|
messageCount: messages.length,
|
|
2894
|
-
|
|
3396
|
+
availableToolCount: allTools.length,
|
|
2895
3397
|
serverToolCount: serverTools.length,
|
|
2896
3398
|
clientToolCount: clientTools.length,
|
|
3399
|
+
activeProfile: toolProfile ?? toolSelectionConfig?.defaultProfile,
|
|
2897
3400
|
maxIterations
|
|
2898
3401
|
});
|
|
2899
3402
|
}
|
|
@@ -2912,11 +3415,71 @@ async function* runAgentLoop(options) {
|
|
|
2912
3415
|
iteration,
|
|
2913
3416
|
maxIterations
|
|
2914
3417
|
};
|
|
3418
|
+
const selectedTools = selectTools({
|
|
3419
|
+
tools: allTools,
|
|
3420
|
+
messages,
|
|
3421
|
+
config: toolSelectionConfig,
|
|
3422
|
+
activeProfile: toolProfile,
|
|
3423
|
+
forceIncludeNames: [...loadedToolNames]
|
|
3424
|
+
});
|
|
3425
|
+
const toolSearchTool = shouldExposeToolSearch({
|
|
3426
|
+
tools: allTools,
|
|
3427
|
+
config: toolSelectionConfig
|
|
3428
|
+
}) ? {
|
|
3429
|
+
name: toolSearchMetaToolName,
|
|
3430
|
+
description: "Search available deferred tools and load the most relevant ones for the next step when the required tool is not currently exposed.",
|
|
3431
|
+
location: "server",
|
|
3432
|
+
hidden: true,
|
|
3433
|
+
inputSchema: {
|
|
3434
|
+
type: "object",
|
|
3435
|
+
properties: {
|
|
3436
|
+
query: {
|
|
3437
|
+
type: "string",
|
|
3438
|
+
description: "Describe the tool capability you need to find."
|
|
3439
|
+
},
|
|
3440
|
+
limit: {
|
|
3441
|
+
type: "number",
|
|
3442
|
+
description: "Maximum number of matching tools to load."
|
|
3443
|
+
}
|
|
3444
|
+
},
|
|
3445
|
+
required: ["query"]
|
|
3446
|
+
},
|
|
3447
|
+
handler: async (params) => {
|
|
3448
|
+
const query = typeof params.query === "string" ? params.query : "";
|
|
3449
|
+
const limit = typeof params.limit === "number" ? params.limit : void 0;
|
|
3450
|
+
const results = searchTools({
|
|
3451
|
+
tools: allTools,
|
|
3452
|
+
query,
|
|
3453
|
+
config: toolSelectionConfig,
|
|
3454
|
+
activeProfile: toolProfile,
|
|
3455
|
+
limit,
|
|
3456
|
+
excludeNames: selectedTools.map((tool2) => tool2.name)
|
|
3457
|
+
});
|
|
3458
|
+
return {
|
|
3459
|
+
success: true,
|
|
3460
|
+
query,
|
|
3461
|
+
loadedTools: results.map((result) => result.name),
|
|
3462
|
+
results
|
|
3463
|
+
};
|
|
3464
|
+
}
|
|
3465
|
+
} : null;
|
|
3466
|
+
const effectiveSelectedTools = toolSearchTool ? [...selectedTools, toolSearchTool] : selectedTools;
|
|
3467
|
+
const providerToolOptions = buildProviderToolOptions({
|
|
3468
|
+
providerName: provider.name,
|
|
3469
|
+
config: toolSelectionConfig});
|
|
3470
|
+
const providerTools = formatter.transformTools(effectiveSelectedTools);
|
|
2915
3471
|
if (debug) {
|
|
2916
|
-
console.log(`[AgentLoop] Iteration ${iteration}/${maxIterations}
|
|
3472
|
+
console.log(`[AgentLoop] Iteration ${iteration}/${maxIterations}`, {
|
|
3473
|
+
selectedToolCount: effectiveSelectedTools.length,
|
|
3474
|
+
loadedDeferredTools: [...loadedToolNames]
|
|
3475
|
+
});
|
|
2917
3476
|
}
|
|
2918
3477
|
try {
|
|
2919
|
-
const response = await callLLM(
|
|
3478
|
+
const response = await callLLM(
|
|
3479
|
+
conversation,
|
|
3480
|
+
providerTools,
|
|
3481
|
+
providerToolOptions
|
|
3482
|
+
);
|
|
2920
3483
|
const toolCalls = formatter.parseToolCalls(response);
|
|
2921
3484
|
const textContent = formatter.extractTextContent(response);
|
|
2922
3485
|
if (textContent) {
|
|
@@ -2934,7 +3497,7 @@ async function* runAgentLoop(options) {
|
|
|
2934
3497
|
}
|
|
2935
3498
|
const results = await executeToolCalls(
|
|
2936
3499
|
toolCalls,
|
|
2937
|
-
|
|
3500
|
+
effectiveSelectedTools,
|
|
2938
3501
|
executeServerTool,
|
|
2939
3502
|
waitForClientToolResult,
|
|
2940
3503
|
function* (event) {
|
|
@@ -2953,6 +3516,23 @@ async function* runAgentLoop(options) {
|
|
|
2953
3516
|
};
|
|
2954
3517
|
}
|
|
2955
3518
|
}
|
|
3519
|
+
for (const result of results) {
|
|
3520
|
+
const toolCall = toolCalls.find((tc) => tc.id === result.toolCallId);
|
|
3521
|
+
if (!toolCall || toolCall.name !== toolSearchMetaToolName) {
|
|
3522
|
+
continue;
|
|
3523
|
+
}
|
|
3524
|
+
try {
|
|
3525
|
+
const parsed = JSON.parse(result.content);
|
|
3526
|
+
if (Array.isArray(parsed.loadedTools)) {
|
|
3527
|
+
for (const toolName of parsed.loadedTools) {
|
|
3528
|
+
if (typeof toolName === "string" && toolName) {
|
|
3529
|
+
loadedToolNames.add(toolName);
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
}
|
|
3533
|
+
} catch {
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
2956
3536
|
const assistantMessage = formatter.buildAssistantToolMessage(
|
|
2957
3537
|
toolCalls,
|
|
2958
3538
|
textContent
|
|
@@ -3103,6 +3683,6 @@ async function executeToolCalls(toolCalls, tools, executeServerTool, waitForClie
|
|
|
3103
3683
|
return results;
|
|
3104
3684
|
}
|
|
3105
3685
|
|
|
3106
|
-
export { DEFAULT_CAPABILITIES, DEFAULT_MAX_ITERATIONS, GenerateResult, Runtime, StreamResult, createEventStream, createExpressHandler, createExpressMiddleware, createHonoApp, createNextHandler, createNodeHandler, createRuntime, createSSEHeaders, createSSEResponse, createStreamResult, createTextStreamHeaders, createTextStreamResponse, formatSSEData, formatToolsForAnthropic, formatToolsForGoogle, formatToolsForOpenAI, generateMessageId, generateText, generateThreadId, generateToolCallId, pipeSSEToResponse, pipeTextToResponse, runAgentLoop, streamText, tool };
|
|
3686
|
+
export { DEFAULT_CAPABILITIES, DEFAULT_MAX_ITERATIONS, GenerateResult, Runtime, StreamResult, buildProviderToolOptions, createEventStream, createExpressHandler, createExpressMiddleware, createHonoApp, createNextHandler, createNodeHandler, createRuntime, createSSEHeaders, createSSEResponse, createStreamResult, createTextStreamHeaders, createTextStreamResponse, formatSSEData, formatToolsForAnthropic, formatToolsForGoogle, formatToolsForOpenAI, generateMessageId, generateText, generateThreadId, generateToolCallId, pipeSSEToResponse, pipeTextToResponse, runAgentLoop, searchTools, selectTools, shouldExposeToolSearch, streamText, tool };
|
|
3107
3687
|
//# sourceMappingURL=index.mjs.map
|
|
3108
3688
|
//# sourceMappingURL=index.mjs.map
|