@botbotgo/agent-harness 0.0.467 → 0.0.469

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.467";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.469";
2
2
  export declare const AGENT_HARNESS_RELEASE_DATE = "2026-05-04";
@@ -1,2 +1,2 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.467";
1
+ export const AGENT_HARNESS_VERSION = "0.0.469";
2
2
  export const AGENT_HARNESS_RELEASE_DATE = "2026-05-04";
@@ -205,6 +205,44 @@ function parseCompactRouterSelection(value, subagentNames) {
205
205
  return { delegations: deduped };
206
206
  }
207
207
  }
208
+ const routingMap = typeof payload.routing === "object" && payload.routing !== null && !Array.isArray(payload.routing)
209
+ ? payload.routing
210
+ : typeof args.routing === "object" && args.routing !== null && !Array.isArray(args.routing)
211
+ ? args.routing
212
+ : undefined;
213
+ if (routingMap) {
214
+ const nestedSubagents = Array.isArray(routingMap.subagents)
215
+ ? routingMap.subagents
216
+ .map((item) => {
217
+ if (typeof item !== "string") {
218
+ return null;
219
+ }
220
+ const resolvedName = resolveExactName(item);
221
+ return resolvedName ? { subagentType: resolvedName, description: "" } : null;
222
+ })
223
+ .filter((item) => item !== null)
224
+ : [];
225
+ const delegations = Object.entries(routingMap)
226
+ .map(([rawName, rawDescription]) => {
227
+ const resolvedName = resolveExactName(rawName);
228
+ if (!resolvedName) {
229
+ return null;
230
+ }
231
+ const description = typeof rawDescription === "string" && rawDescription.trim()
232
+ ? rawDescription.trim()
233
+ : "";
234
+ return { subagentType: resolvedName, description };
235
+ })
236
+ .filter((item) => item !== null);
237
+ for (const delegation of nestedSubagents) {
238
+ if (!delegations.some((item) => item.subagentType === delegation.subagentType)) {
239
+ delegations.push(delegation);
240
+ }
241
+ }
242
+ if (delegations.length > 0) {
243
+ return { delegations };
244
+ }
245
+ }
208
246
  const status = typeof payload.status === "string" ? payload.status.trim().toLowerCase() : "";
209
247
  if (status === "refused") {
210
248
  const reason = typeof payload.reason === "string" && payload.reason.trim()
@@ -227,6 +265,18 @@ function buildCompactRouterPolicy(routingPolicy) {
227
265
  .slice(0, 80)
228
266
  .join("\n");
229
267
  }
268
+ function looksLikeStructuredMultiItemRequest(requestText) {
269
+ const lines = requestText
270
+ .split(/\r?\n/u)
271
+ .map((line) => line.trim())
272
+ .filter(Boolean);
273
+ const numberedItems = lines.filter((line) => /^\d+[\.)、]\s+/u.test(line));
274
+ if (numberedItems.length >= 2) {
275
+ return true;
276
+ }
277
+ const bulletItems = lines.filter((line) => /^[-*]\s+/u.test(line));
278
+ return bulletItems.length >= 2;
279
+ }
230
280
  function buildDelegatedOwnedTaskInstruction(input) {
231
281
  return [
232
282
  `Delegated owner: ${input.subagentType}.`,
@@ -1204,6 +1254,7 @@ export class AgentRuntimeAdapter {
1204
1254
  }
1205
1255
  const subagents = getBindingSubagents(binding);
1206
1256
  const subagentNames = new Set(subagents.map((subagent) => subagent.name));
1257
+ const structuredMultiItemRequest = looksLikeStructuredMultiItemRequest(requestText);
1207
1258
  let selection = null;
1208
1259
  const subagentCatalog = subagents
1209
1260
  .map((subagent) => `- ${subagent.name}: ${subagent.description}`)
@@ -1215,6 +1266,7 @@ export class AgentRuntimeAdapter {
1215
1266
  "You are selecting a subagent for a delegation-only agent.",
1216
1267
  "Choose exactly one listed subagent when it can responsibly handle the request.",
1217
1268
  "Use the agent routing policy as authoritative routing configuration when it maps the request meaning to a listed subagent.",
1269
+ "When the routing policy says a request class is owned by one listed subagent, keep that request with the configured owner even if the task mentions supporting evidence from other domains.",
1218
1270
  "Do not refuse while any listed subagent can own the request after applying the routing policy.",
1219
1271
  "Refuse only when the request is outside every listed subagent's configured responsibility.",
1220
1272
  compactRoutingPolicy ? "Agent routing policy:" : "",
@@ -1278,7 +1330,7 @@ export class AgentRuntimeAdapter {
1278
1330
  ].filter(Boolean).join("\n\n"),
1279
1331
  ];
1280
1332
  let previousRawText = "";
1281
- for (let index = 0; index < routerPrompts.length && !selection; index += 1) {
1333
+ for (let index = 0; index < routerPrompts.length; index += 1) {
1282
1334
  const activePrompt = index <= 1 || !previousRawText
1283
1335
  ? routerPrompts[index]
1284
1336
  : [routerPrompts[index], "Previous output:", previousRawText].join("\n\n");
@@ -1288,12 +1340,114 @@ export class AgentRuntimeAdapter {
1288
1340
  }
1289
1341
  previousRawText = readModelText(raw);
1290
1342
  const parsedSelection = parseCompactRouterSelection(previousRawText, subagentNames);
1291
- selection = parsedSelection?.refusedReason && index < routerPrompts.length - 1
1292
- ? null
1293
- : parsedSelection;
1343
+ if (!parsedSelection) {
1344
+ continue;
1345
+ }
1346
+ if (parsedSelection.delegations && parsedSelection.delegations.length > 1) {
1347
+ if (selection?.subagentType
1348
+ && !parsedSelection.delegations.some((delegation) => delegation.subagentType === selection?.subagentType)) {
1349
+ continue;
1350
+ }
1351
+ selection = parsedSelection;
1352
+ break;
1353
+ }
1354
+ if (!selection || selection.refusedReason || parsedSelection.subagentType) {
1355
+ selection = parsedSelection.refusedReason && index < routerPrompts.length - 1
1356
+ ? selection
1357
+ : parsedSelection;
1358
+ }
1294
1359
  }
1295
1360
  }
1296
- if (selection?.delegations && selection.delegations.length > 0) {
1361
+ if (selection?.delegations && selection.delegations.length > 1) {
1362
+ const aggregateToolResults = [];
1363
+ const childReports = [];
1364
+ for (const planned of selection.delegations) {
1365
+ const selectedBinding = this.options.bindingResolver(planned.subagentType);
1366
+ if (!selectedBinding) {
1367
+ const output = `Configured subagent '${planned.subagentType}' could not be resolved.`;
1368
+ childReports.push({
1369
+ subagentType: planned.subagentType,
1370
+ result: {
1371
+ sessionId,
1372
+ requestId: `${requestId}:${planned.subagentType}`,
1373
+ agentId: planned.subagentType,
1374
+ state: "failed",
1375
+ output,
1376
+ finalMessageText: output,
1377
+ metadata: { executedToolResults: [] },
1378
+ },
1379
+ output,
1380
+ });
1381
+ continue;
1382
+ }
1383
+ const delegatedResult = await this.invoke(selectedBinding, buildDelegatedOwnedTaskInstruction({
1384
+ subagentType: planned.subagentType,
1385
+ taskText: planned.description,
1386
+ originalRequest: requestText,
1387
+ }), sessionId, `${requestId}:${planned.subagentType}`, undefined, [], {
1388
+ context: options.context,
1389
+ state: options.state,
1390
+ files: options.files,
1391
+ memoryContext: options.memoryContext,
1392
+ });
1393
+ const executedToolResults = Array.isArray(delegatedResult.metadata?.executedToolResults)
1394
+ ? delegatedResult.metadata.executedToolResults
1395
+ : [];
1396
+ aggregateToolResults.push(...executedToolResults);
1397
+ childReports.push({
1398
+ subagentType: planned.subagentType,
1399
+ result: delegatedResult,
1400
+ output: typeof delegatedResult.output === "string" ? delegatedResult.output : String(delegatedResult.output ?? ""),
1401
+ });
1402
+ }
1403
+ const failedChildren = childReports.filter((child) => child.result.state === "failed");
1404
+ const uniqueToolNames = [...new Set(aggregateToolResults.map((toolResult) => toolResult.toolName))];
1405
+ const status = failedChildren.length > 0 ? "failed" : "completed";
1406
+ const report = childReports
1407
+ .map((child) => `## ${child.subagentType}\n${child.output.trim() || "No visible output returned."}`)
1408
+ .join("\n\n");
1409
+ const output = JSON.stringify({
1410
+ status,
1411
+ routing: selection.delegations.map((planned, index) => `${index + 1}) 路由判断: ${planned.subagentType} 负责 ${planned.description.trim() || "该专业域子任务"}。`),
1412
+ plan: selection.delegations.map((planned, index) => `${index + 1}) 委托 ${planned.subagentType}: ${planned.description.trim() || "执行其专业域任务"}。`),
1413
+ execution: childReports.map((child, index) => `${index + 1}) ${child.subagentType} ${child.result.state === "failed" ? "failed" : "completed"}。`),
1414
+ todoTrace: childReports.map((child, index) => `${index + 1}) ${child.subagentType}: ${hasDelegatedPlanEvidence(child.result) ? "TODO evidence observed" : "TODO evidence missing"}。`),
1415
+ stepResults: childReports.map((child, index) => `${index + 1}) ${child.subagentType}: delegated result collected; aggregate tools = ${uniqueToolNames.length > 0 ? uniqueToolNames.join(", ") : "none"}。`),
1416
+ summary: [
1417
+ status === "failed"
1418
+ ? `多 specialist 编排完成,但 ${failedChildren.length} 个委托返回 failed。`
1419
+ : "多 specialist 编排已完成,所有委托均返回 completed。",
1420
+ ],
1421
+ findings: childReports.map((child) => `${child.subagentType}: ${child.output.trim().slice(0, 500) || "No finding text returned."}`),
1422
+ blockers: failedChildren.length > 0
1423
+ ? failedChildren.map((child) => `${child.subagentType}: delegated execution failed.`)
1424
+ : ["none"],
1425
+ nextActions: failedChildren.length > 0
1426
+ ? ["查看 failed specialist 的 blocker 并单独重跑该委托。"]
1427
+ : ["可基于各 specialist 结果继续做最终修复或发布决策。"],
1428
+ report,
1429
+ });
1430
+ return {
1431
+ toolOutput: output,
1432
+ delegatedSubagentType: "multiple",
1433
+ delegatedResult: {
1434
+ sessionId,
1435
+ requestId,
1436
+ agentId: binding.agent.id,
1437
+ state: status,
1438
+ output,
1439
+ finalMessageText: output,
1440
+ metadata: {
1441
+ executedToolResults: aggregateToolResults,
1442
+ delegations: childReports.map((child) => ({
1443
+ subagentType: child.subagentType,
1444
+ state: child.result.state,
1445
+ })),
1446
+ },
1447
+ },
1448
+ };
1449
+ }
1450
+ if (selection?.delegations && selection.delegations.length === 1) {
1297
1451
  selection = { subagentType: selection.delegations[0].subagentType };
1298
1452
  }
1299
1453
  if (selection?.refusedReason) {
@@ -1553,6 +1707,7 @@ export class AgentRuntimeAdapter {
1553
1707
  }
1554
1708
  const subagents = getBindingSubagents(binding);
1555
1709
  const subagentNames = new Set(subagents.map((subagent) => subagent.name));
1710
+ const structuredMultiItemRequest = looksLikeStructuredMultiItemRequest(requestText);
1556
1711
  let selection = null;
1557
1712
  const subagentCatalog = subagents
1558
1713
  .map((subagent) => `- ${subagent.name}: ${subagent.description}`)
@@ -1564,7 +1719,16 @@ export class AgentRuntimeAdapter {
1564
1719
  "You are planning delegation for a delegation-only agent.",
1565
1720
  "Choose exactly one listed subagent when one specialist can responsibly handle the request.",
1566
1721
  "If the request naturally requires multiple specialist-owned steps, return an ordered delegation plan instead of one subagent.",
1722
+ "A single objective with multiple evidence requirements is still single-owner when one listed subagent owns the objective.",
1723
+ "Return multi-owner delegations only when the user asks for multiple independently owned specialist work items.",
1724
+ "For multi-line or numbered requests, evaluate every requested item semantically before choosing the final owner list.",
1567
1725
  "Use the agent routing policy as authoritative routing configuration when it maps request meaning to listed subagents.",
1726
+ "Apply the routing policy and subagent catalog literally; do not assign work to a subagent when the policy says that subagent is not the owner.",
1727
+ "When the routing policy or subagent catalog says a request class routes to one owner only, choose that single owner.",
1728
+ "Evidence dimensions inside one request, such as tools, files, CI, output format, failure states, routing, or runtime paths, are inputs to the selected owner; they do not create extra owners unless the user asks those specialists to do their own work.",
1729
+ "A request made from one specialist perspective is single-owner when that specialist can responsibly handle the whole requested assessment.",
1730
+ "Evaluate each listed subagent independently against the request and include every listed owner whose configured responsibility is required.",
1731
+ "Do not merge one listed subagent's configured responsibility into another listed subagent's task.",
1568
1732
  "A broad request can still be handleable when multiple listed subagents each own part of it; return a delegation plan in that case.",
1569
1733
  "Do not refuse while any listed subagent can own the request or a subtask after applying the routing policy.",
1570
1734
  "Refuse only when the request is outside every listed subagent's configured responsibility.",
@@ -1632,9 +1796,29 @@ export class AgentRuntimeAdapter {
1632
1796
  "Request:",
1633
1797
  requestText,
1634
1798
  ].filter(Boolean).join("\n\n"),
1799
+ [
1800
+ primaryModel.init?.think === false ? "/no_think" : "",
1801
+ "Multi-specialist delegation is supported.",
1802
+ "If a request needs multiple listed specialists, that is not a refusal condition.",
1803
+ "A single objective with multiple evidence requirements is still single-owner when one listed subagent owns the objective.",
1804
+ "Return multi-owner delegations only when the user asks for multiple independently owned specialist work items.",
1805
+ "Return a delegations array that assigns each specialist-owned work item to listed subagents.",
1806
+ "Evaluate each listed subagent independently against the request and include every listed owner whose configured responsibility is required.",
1807
+ "Do not merge one listed subagent's configured responsibility into another listed subagent's task.",
1808
+ "Do not turn supporting evidence dimensions into separate owners when one listed subagent owns the requested assessment.",
1809
+ "Never return final response fields such as routing, todoTrace, stepResults, summary, findings, blockers, nextActions, or report.",
1810
+ "Return JSON only with this exact shape:",
1811
+ "{\"delegations\":[{\"subagent_type\":\"<one exact listed name>\",\"description\":\"<owned subtask>\"}]}",
1812
+ compactRoutingPolicy ? "Agent routing policy:" : "",
1813
+ compactRoutingPolicy,
1814
+ "Available subagents:",
1815
+ subagentCatalog,
1816
+ "User request:",
1817
+ requestText,
1818
+ ].filter(Boolean).join("\n\n"),
1635
1819
  ];
1636
1820
  let previousRawText = "";
1637
- for (let index = 0; index < routerPrompts.length && !selection; index += 1) {
1821
+ for (let index = 0; index < routerPrompts.length; index += 1) {
1638
1822
  const activePrompt = index <= 1 || !previousRawText
1639
1823
  ? routerPrompts[index]
1640
1824
  : [routerPrompts[index], "Previous output:", previousRawText].join("\n\n");
@@ -1644,59 +1828,120 @@ export class AgentRuntimeAdapter {
1644
1828
  }
1645
1829
  previousRawText = readModelText(raw);
1646
1830
  const parsedSelection = parseCompactRouterSelection(previousRawText, subagentNames);
1647
- selection = parsedSelection?.refusedReason && index < routerPrompts.length - 1
1648
- ? null
1649
- : parsedSelection;
1831
+ if (!parsedSelection) {
1832
+ continue;
1833
+ }
1834
+ if (parsedSelection.delegations && parsedSelection.delegations.length > 1) {
1835
+ selection = parsedSelection;
1836
+ break;
1837
+ }
1838
+ if (parsedSelection.subagentType && !structuredMultiItemRequest) {
1839
+ selection = parsedSelection;
1840
+ break;
1841
+ }
1842
+ if (!selection || selection.refusedReason || parsedSelection.subagentType) {
1843
+ selection = parsedSelection.refusedReason && index < routerPrompts.length - 1
1844
+ ? selection
1845
+ : parsedSelection;
1846
+ }
1650
1847
  }
1651
1848
  }
1652
- const numberedRequestSteps = requestText
1653
- .split(/\r?\n/u)
1654
- .map((item) => item.trim())
1655
- .filter((item) => /^\d+\s*[.)、.]\s*/u.test(item));
1656
- const shouldRouteNumberedClauses = model
1657
- && numberedRequestSteps.length > 1
1658
- && (!selection
1659
- || Boolean(selection.refusedReason)
1660
- || (Array.isArray(selection.delegations)
1661
- && selection.delegations.length > 1
1662
- && selection.delegations.length < numberedRequestSteps.length));
1663
- if (shouldRouteNumberedClauses || ((!selection || selection.refusedReason) && model)) {
1664
- const routeClauses = numberedRequestSteps.length > 1 ? numberedRequestSteps : [requestText];
1665
- const routedDelegations = [];
1666
- for (const [index, clause] of routeClauses.entries()) {
1667
- const clausePrompt = [
1849
+ if (selection?.delegations || selection?.subagentType) {
1850
+ const candidateDelegations = selection.delegations ?? [{
1851
+ subagentType: selection.subagentType,
1852
+ description: requestText,
1853
+ }];
1854
+ const candidatePlan = candidateDelegations
1855
+ .map((item, index) => `${index + 1}. ${item.subagentType}: ${item.description}`)
1856
+ .join("\n");
1857
+ const coveragePrompt = [
1858
+ primaryModel.init?.think === false ? "/no_think" : "",
1859
+ "Verify this delegation plan against the user request and routing policy.",
1860
+ "Internally review every sentence or list item in the user request before returning JSON.",
1861
+ "Return one corrected JSON object only.",
1862
+ "Keep the candidate plan unchanged when it already covers every specialist-owned work item.",
1863
+ "Return a single subagent_type when one listed subagent owns the whole request and the candidate plan only split supporting evidence dimensions.",
1864
+ "A single objective with multiple evidence requirements is still single-owner when one listed subagent owns the objective.",
1865
+ "Return multi-owner delegations only when the user asks for multiple independently owned specialist work items.",
1866
+ "If the candidate omits a specialist-owned work item, add that listed subagent in the correct user-requested order.",
1867
+ "If the candidate includes a subagent whose described work is not owned by that subagent, remove or replace it.",
1868
+ "Evaluate each listed subagent independently against the request and include every listed owner whose configured responsibility is required.",
1869
+ "Do not merge one listed subagent's configured responsibility into another listed subagent's task.",
1870
+ "Do not turn supporting evidence dimensions into separate owners when one listed subagent owns the requested assessment.",
1871
+ "Do not add a subagent unless the routing policy or subagent catalog makes ownership clear.",
1872
+ "When the routing policy states that a subagent is not the owner for a domain, do not assign that domain to that subagent.",
1873
+ "Use only listed subagent names.",
1874
+ compactRoutingPolicy ? "Agent routing policy:" : "",
1875
+ compactRoutingPolicy,
1876
+ "Available subagents:",
1877
+ subagentCatalog,
1878
+ "Candidate delegation plan:",
1879
+ candidatePlan,
1880
+ "Allowed JSON shapes:",
1881
+ "{\"subagent_type\":\"<listed subagent name>\"}",
1882
+ "{\"delegations\":[{\"subagent_type\":\"<listed subagent name>\",\"description\":\"<only that specialist's owned portion>\"}]}",
1883
+ "User request:",
1884
+ requestText,
1885
+ ].filter(Boolean).join("\n\n");
1886
+ const rawCoverage = await invokeRouter(coveragePrompt, "delegation router coverage invoke");
1887
+ if (rawCoverage !== null) {
1888
+ const coverageText = readModelText(rawCoverage);
1889
+ const coverageSelection = parseCompactRouterSelection(coverageText, subagentNames);
1890
+ if (coverageSelection?.subagentType && !structuredMultiItemRequest) {
1891
+ selection = coverageSelection;
1892
+ }
1893
+ if (coverageSelection?.delegations && coverageSelection.delegations.length === 1 && !structuredMultiItemRequest) {
1894
+ selection = { subagentType: coverageSelection.delegations[0].subagentType };
1895
+ }
1896
+ if (coverageSelection?.delegations && coverageSelection.delegations.length > 1) {
1897
+ const candidateNames = new Set(candidateDelegations.map((item) => item.subagentType));
1898
+ const coverageNames = new Set(coverageSelection.delegations.map((item) => item.subagentType));
1899
+ const preservesCandidateOwners = Array.from(candidateNames).every((name) => coverageNames.has(name));
1900
+ if (preservesCandidateOwners) {
1901
+ selection = coverageSelection;
1902
+ }
1903
+ }
1904
+ }
1905
+ if (candidateDelegations.length > 1 && selection?.delegations && selection.delegations.length > 1) {
1906
+ const activePlan = selection.delegations
1907
+ .map((item, index) => `${index + 1}. ${item.subagentType}: ${item.description}`)
1908
+ .join("\n");
1909
+ const arbitrationPrompt = [
1668
1910
  primaryModel.init?.think === false ? "/no_think" : "",
1669
- "You are a strict JSON router for one bounded task.",
1670
- "Choose exactly one owner from this list:",
1671
- Array.from(subagentNames).join(", "),
1672
- "Return only JSON with this shape:",
1673
- "{\"subagent_type\":\"<one listed subagent name>\"}",
1911
+ "Arbitrate whether this delegation plan is over-split.",
1912
+ "The runtime supports both one-owner and multi-owner delegation.",
1913
+ "Choose one owner when the routing policy or subagent catalog says one listed subagent owns the whole request.",
1914
+ "A single objective with multiple evidence requirements is still single-owner when one listed subagent owns the objective.",
1915
+ "Treat supporting evidence dimensions as inputs to that owner, not as separate owners.",
1916
+ "Keep multi-owner delegation only when the user asked for multiple independently owned specialist work items.",
1917
+ "Return exactly one JSON object and no prose.",
1918
+ "Single-owner shape:",
1919
+ "{\"subagent_type\":\"<listed subagent name>\"}",
1920
+ "Multi-owner shape:",
1921
+ "{\"delegations\":[{\"subagent_type\":\"<listed subagent name>\",\"description\":\"<only that specialist's owned portion>\"}]}",
1674
1922
  compactRoutingPolicy ? "Agent routing policy:" : "",
1675
1923
  compactRoutingPolicy,
1676
1924
  "Available subagents:",
1677
1925
  subagentCatalog,
1678
- "Task:",
1679
- clause,
1926
+ "Candidate plan:",
1927
+ activePlan,
1928
+ "User request:",
1929
+ requestText,
1680
1930
  ].filter(Boolean).join("\n\n");
1681
- const raw = await invokeRouter(clausePrompt, routeClauses.length > 1
1682
- ? `delegation router clause invoke ${index + 1}`
1683
- : "delegation router single-clause invoke");
1684
- const routed = raw === null ? null : parseCompactRouterSelection(readModelText(raw), subagentNames);
1685
- if (!routed?.subagentType || routed.refusedReason) {
1686
- routedDelegations.length = 0;
1687
- break;
1688
- }
1689
- if (routedDelegations.some((item) => item.subagentType === routed.subagentType)) {
1690
- continue;
1931
+ const rawArbitration = await invokeRouter(arbitrationPrompt, "delegation router over-split arbitration invoke");
1932
+ if (rawArbitration !== null) {
1933
+ const arbitrationText = readModelText(rawArbitration);
1934
+ const arbitrationSelection = parseCompactRouterSelection(arbitrationText, subagentNames);
1935
+ if (arbitrationSelection?.subagentType && !structuredMultiItemRequest) {
1936
+ selection = arbitrationSelection;
1937
+ }
1938
+ else if (arbitrationSelection?.delegations && arbitrationSelection.delegations.length === 1 && !structuredMultiItemRequest) {
1939
+ selection = { subagentType: arbitrationSelection.delegations[0].subagentType };
1940
+ }
1941
+ else if (arbitrationSelection?.delegations && arbitrationSelection.delegations.length > 1) {
1942
+ selection = arbitrationSelection;
1943
+ }
1691
1944
  }
1692
- routedDelegations.push({ subagentType: routed.subagentType, description: clause });
1693
- }
1694
- const existingDelegationCount = selection?.delegations?.length ?? 0;
1695
- if (routedDelegations.length > 1 && routedDelegations.length > existingDelegationCount) {
1696
- selection = { delegations: routedDelegations };
1697
- }
1698
- else if (routedDelegations.length === 1 && existingDelegationCount === 0) {
1699
- selection = { subagentType: routedDelegations[0].subagentType };
1700
1945
  }
1701
1946
  }
1702
1947
  if (selection?.delegations?.length === 1) {
@@ -1705,12 +1950,7 @@ export class AgentRuntimeAdapter {
1705
1950
  }
1706
1951
  if (selection?.delegations && selection.delegations.length > 1) {
1707
1952
  const plannedDelegations = selection.delegations;
1708
- const plannedNames = new Set(plannedDelegations.map((item) => item.subagentType));
1709
- const planCoversEverySubagent = plannedDelegations.length === subagents.length
1710
- && plannedNames.size === subagentNames.size
1711
- && Array.from(subagentNames).every((name) => plannedNames.has(name));
1712
- const shouldCollapseOverbroadPlan = planCoversEverySubagent && numberedRequestSteps.length < 3;
1713
- const executableDelegations = shouldCollapseOverbroadPlan ? plannedDelegations.slice(0, 1) : plannedDelegations;
1953
+ const executableDelegations = plannedDelegations;
1714
1954
  const aggregateToolResults = [];
1715
1955
  const childReports = [];
1716
1956
  yield {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.467",
3
+ "version": "0.0.469",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "license": "MIT",
6
6
  "type": "module",