@botbotgo/agent-harness 0.0.374 → 0.0.377
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.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.377";
|
|
2
2
|
export declare const AGENT_HARNESS_RELEASE_DATE = "2026-04-30";
|
package/dist/package-version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.377";
|
|
2
2
|
export const AGENT_HARNESS_RELEASE_DATE = "2026-04-30";
|
|
@@ -153,6 +153,39 @@ function parseCompactRouterSelection(value, subagentNames) {
|
|
|
153
153
|
}
|
|
154
154
|
return null;
|
|
155
155
|
}
|
|
156
|
+
function inferCompactRouterSelectionFromRequest(requestText, subagents) {
|
|
157
|
+
const normalized = requestText.toLowerCase();
|
|
158
|
+
const score = (subagent) => {
|
|
159
|
+
const name = subagent.name.toLowerCase();
|
|
160
|
+
const description = (subagent.description ?? "").toLowerCase();
|
|
161
|
+
let value = 0;
|
|
162
|
+
if (normalized.includes(name))
|
|
163
|
+
value += 4;
|
|
164
|
+
const keywordGroups = {
|
|
165
|
+
k8s: ["k8s", "kubernetes", "kubectl", "cluster", "pod", "node", "节点", "集群", "调度"],
|
|
166
|
+
software: ["code", "repo", "implementation", "debug", "代码", "仓库", "实现", "配置"],
|
|
167
|
+
ops: ["ci", "cd", "github actions", "disk", "storage", "deploy", "磁盘", "存储", "运维"],
|
|
168
|
+
qa: ["test", "coverage", "regression", "验证", "测试", "回归"],
|
|
169
|
+
release: ["release", "publish", "version", "tag", "发版", "发布", "版本"],
|
|
170
|
+
research: ["research", "web", "latest", "调查资料", "外部", "搜索"],
|
|
171
|
+
secretary: ["summary", "transcript", "youtube", "brief", "摘要", "讲稿", "转写"],
|
|
172
|
+
};
|
|
173
|
+
const keywords = keywordGroups[name] ?? [];
|
|
174
|
+
for (const keyword of keywords) {
|
|
175
|
+
if (normalized.includes(keyword))
|
|
176
|
+
value += description.includes(keyword) || name.includes(keyword) ? 3 : 1;
|
|
177
|
+
}
|
|
178
|
+
return value;
|
|
179
|
+
};
|
|
180
|
+
const ranked = subagents
|
|
181
|
+
.map((subagent) => ({ name: subagent.name, score: score(subagent) }))
|
|
182
|
+
.filter((item) => item.score > 0)
|
|
183
|
+
.sort((left, right) => right.score - left.score);
|
|
184
|
+
if (ranked.length === 0 || (ranked[1] && ranked[1].score === ranked[0].score)) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
return ranked[0].name;
|
|
188
|
+
}
|
|
156
189
|
function isDelegationOnlyDeepAgentBinding(binding) {
|
|
157
190
|
return isDeepAgentBinding(binding)
|
|
158
191
|
&& getBindingSubagents(binding).length > 0
|
|
@@ -846,6 +879,8 @@ export class AgentRuntimeAdapter {
|
|
|
846
879
|
}
|
|
847
880
|
const subagents = getBindingSubagents(binding);
|
|
848
881
|
const subagentNames = new Set(subagents.map((subagent) => subagent.name));
|
|
882
|
+
const inferredSubagent = inferCompactRouterSelectionFromRequest(requestText, subagents);
|
|
883
|
+
let selection = inferredSubagent ? { subagentType: inferredSubagent } : null;
|
|
849
884
|
const subagentCatalog = subagents
|
|
850
885
|
.map((subagent) => `- ${subagent.name}: ${subagent.description}`)
|
|
851
886
|
.join("\n");
|
|
@@ -865,57 +900,58 @@ export class AgentRuntimeAdapter {
|
|
|
865
900
|
"User request:",
|
|
866
901
|
requestText,
|
|
867
902
|
].filter(Boolean).join("\n\n");
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
requestId,
|
|
875
|
-
context: options.context,
|
|
876
|
-
toolRuntimeContext: this.buildFunctionToolRuntimeContext(binding, {
|
|
877
|
-
...options,
|
|
903
|
+
if (!selection) {
|
|
904
|
+
const model = await this.resolveModel(primaryModel);
|
|
905
|
+
if (typeof model.invoke !== "function") {
|
|
906
|
+
return null;
|
|
907
|
+
}
|
|
908
|
+
const invokeRouter = async (activePrompt, operationName) => this.invokeWithProviderRetry(binding, () => this.withTimeout(() => model.invoke(activePrompt, resolveLangChainInvocationConfig(binding, {
|
|
878
909
|
sessionId,
|
|
879
910
|
requestId,
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
911
|
+
context: options.context,
|
|
912
|
+
toolRuntimeContext: this.buildFunctionToolRuntimeContext(binding, {
|
|
913
|
+
...options,
|
|
914
|
+
sessionId,
|
|
915
|
+
requestId,
|
|
916
|
+
}),
|
|
917
|
+
})), resolveBindingTimeout(binding), operationName, "invoke"));
|
|
918
|
+
const routerPrompts = [
|
|
885
919
|
prompt,
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
920
|
+
[
|
|
921
|
+
prompt,
|
|
922
|
+
"Your previous router output was invalid.",
|
|
923
|
+
"Return only one JSON object now. Do not include prose, markdown, labels, or tool-call wrappers.",
|
|
924
|
+
].join("\n\n"),
|
|
925
|
+
[
|
|
926
|
+
primaryModel.init?.think === false ? "/no_think" : "",
|
|
927
|
+
"Select one subagent from this exact list:",
|
|
928
|
+
Array.from(subagentNames).join(", "),
|
|
929
|
+
"Return JSON only:",
|
|
930
|
+
"{\"subagent_type\":\"<one exact listed name>\"}",
|
|
931
|
+
"User request:",
|
|
932
|
+
requestText,
|
|
933
|
+
].filter(Boolean).join("\n\n"),
|
|
934
|
+
[
|
|
935
|
+
primaryModel.init?.think === false ? "/no_think" : "",
|
|
936
|
+
"JSON only. Pick a listed subagent or refuse.",
|
|
937
|
+
"Listed subagents:",
|
|
938
|
+
Array.from(subagentNames).join(", "),
|
|
939
|
+
"Allowed outputs:",
|
|
940
|
+
"{\"subagent_type\":\"<listed name>\"}",
|
|
941
|
+
"{\"status\":\"refused\",\"reason\":\"No configured subagent can handle the request.\"}",
|
|
942
|
+
"Request:",
|
|
943
|
+
requestText,
|
|
944
|
+
].filter(Boolean).join("\n\n"),
|
|
945
|
+
];
|
|
946
|
+
let previousRawText = "";
|
|
947
|
+
for (let index = 0; index < routerPrompts.length && !selection; index += 1) {
|
|
948
|
+
const activePrompt = index <= 1 || !previousRawText
|
|
949
|
+
? routerPrompts[index]
|
|
950
|
+
: [routerPrompts[index], "Previous output:", previousRawText].join("\n\n");
|
|
951
|
+
const raw = await invokeRouter(activePrompt, index === 0 ? "delegation router invoke" : `delegation router retry invoke ${index}`);
|
|
952
|
+
previousRawText = readModelText(raw);
|
|
953
|
+
selection = parseCompactRouterSelection(previousRawText, subagentNames);
|
|
954
|
+
}
|
|
919
955
|
}
|
|
920
956
|
if (selection?.refusedReason) {
|
|
921
957
|
return {
|
|
@@ -1211,6 +1247,8 @@ export class AgentRuntimeAdapter {
|
|
|
1211
1247
|
}
|
|
1212
1248
|
const subagents = getBindingSubagents(binding);
|
|
1213
1249
|
const subagentNames = new Set(subagents.map((subagent) => subagent.name));
|
|
1250
|
+
const inferredSubagent = inferCompactRouterSelectionFromRequest(requestText, subagents);
|
|
1251
|
+
let selection = inferredSubagent ? { subagentType: inferredSubagent } : null;
|
|
1214
1252
|
const subagentCatalog = subagents
|
|
1215
1253
|
.map((subagent) => `- ${subagent.name}: ${subagent.description}`)
|
|
1216
1254
|
.join("\n");
|
|
@@ -1230,57 +1268,58 @@ export class AgentRuntimeAdapter {
|
|
|
1230
1268
|
"User request:",
|
|
1231
1269
|
requestText,
|
|
1232
1270
|
].filter(Boolean).join("\n\n");
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
requestId,
|
|
1240
|
-
context: options.context,
|
|
1241
|
-
toolRuntimeContext: this.buildFunctionToolRuntimeContext(binding, {
|
|
1242
|
-
...options,
|
|
1271
|
+
if (!selection) {
|
|
1272
|
+
const model = await this.resolveModel(primaryModel);
|
|
1273
|
+
if (typeof model.invoke !== "function") {
|
|
1274
|
+
return null;
|
|
1275
|
+
}
|
|
1276
|
+
const invokeRouter = async (activePrompt, operationName) => this.invokeWithProviderRetry(binding, () => this.withTimeout(() => model.invoke(activePrompt, resolveLangChainInvocationConfig(binding, {
|
|
1243
1277
|
sessionId,
|
|
1244
1278
|
requestId,
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1279
|
+
context: options.context,
|
|
1280
|
+
toolRuntimeContext: this.buildFunctionToolRuntimeContext(binding, {
|
|
1281
|
+
...options,
|
|
1282
|
+
sessionId,
|
|
1283
|
+
requestId,
|
|
1284
|
+
}),
|
|
1285
|
+
})), resolveBindingTimeout(binding), operationName, "invoke"));
|
|
1286
|
+
const routerPrompts = [
|
|
1250
1287
|
prompt,
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1288
|
+
[
|
|
1289
|
+
prompt,
|
|
1290
|
+
"Your previous router output was invalid.",
|
|
1291
|
+
"Return only one JSON object now. Do not include prose, markdown, labels, or tool-call wrappers.",
|
|
1292
|
+
].join("\n\n"),
|
|
1293
|
+
[
|
|
1294
|
+
primaryModel.init?.think === false ? "/no_think" : "",
|
|
1295
|
+
"Select one subagent from this exact list:",
|
|
1296
|
+
Array.from(subagentNames).join(", "),
|
|
1297
|
+
"Return JSON only:",
|
|
1298
|
+
"{\"subagent_type\":\"<one exact listed name>\"}",
|
|
1299
|
+
"User request:",
|
|
1300
|
+
requestText,
|
|
1301
|
+
].filter(Boolean).join("\n\n"),
|
|
1302
|
+
[
|
|
1303
|
+
primaryModel.init?.think === false ? "/no_think" : "",
|
|
1304
|
+
"JSON only. Pick a listed subagent or refuse.",
|
|
1305
|
+
"Listed subagents:",
|
|
1306
|
+
Array.from(subagentNames).join(", "),
|
|
1307
|
+
"Allowed outputs:",
|
|
1308
|
+
"{\"subagent_type\":\"<listed name>\"}",
|
|
1309
|
+
"{\"status\":\"refused\",\"reason\":\"No configured subagent can handle the request.\"}",
|
|
1310
|
+
"Request:",
|
|
1311
|
+
requestText,
|
|
1312
|
+
].filter(Boolean).join("\n\n"),
|
|
1313
|
+
];
|
|
1314
|
+
let previousRawText = "";
|
|
1315
|
+
for (let index = 0; index < routerPrompts.length && !selection; index += 1) {
|
|
1316
|
+
const activePrompt = index <= 1 || !previousRawText
|
|
1317
|
+
? routerPrompts[index]
|
|
1318
|
+
: [routerPrompts[index], "Previous output:", previousRawText].join("\n\n");
|
|
1319
|
+
const raw = await invokeRouter(activePrompt, index === 0 ? "delegation router invoke" : `delegation router retry invoke ${index}`);
|
|
1320
|
+
previousRawText = readModelText(raw);
|
|
1321
|
+
selection = parseCompactRouterSelection(previousRawText, subagentNames);
|
|
1322
|
+
}
|
|
1284
1323
|
}
|
|
1285
1324
|
if (selection?.refusedReason) {
|
|
1286
1325
|
return {
|