fix: preserve subagent target precedence · openclaw/openclaw@f7a6b9b
steipete
·
2026-05-10
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { describe, expect, it } from "vitest"; |
| 2 | +import { createSubagentsTool } from "./subagents-tool.js"; |
| 3 | + |
| 4 | +describe("subagents tool", () => { |
| 5 | +it("does not advertise sessions_yield as unconditionally available", () => { |
| 6 | +const tool = createSubagentsTool(); |
| 7 | + |
| 8 | +expect(tool.description).toContain("If sessions_yield is available"); |
| 9 | +expect(tool.description).not.toContain("Use sessions_yield to wait"); |
| 10 | +}); |
| 11 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -35,7 +35,7 @@ export function createSubagentsTool(opts?: { agentSessionKey?: string }): AnyAge
|
35 | 35 | label: "Subagents", |
36 | 36 | name: "subagents", |
37 | 37 | description: |
38 | | -"On-demand list, kill, or steer spawned sub-agents for this requester session. Use sessions_yield to wait for completion events; do not poll this tool in wait loops.", |
| 38 | +"On-demand list, kill, or steer spawned sub-agents for this requester session. If sessions_yield is available, use it to wait for completion events; do not poll this tool in wait loops.", |
39 | 39 | parameters: SubagentsToolSchema, |
40 | 40 | execute: async (_toolCallId, args) => { |
41 | 41 | const params = args as Record<string, unknown>; |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -152,6 +152,16 @@ describe("subagents utils", () => {
|
152 | 152 | expectResolvedRunId(runs, "copy_", "run-review-2"); |
153 | 153 | }); |
154 | 154 | |
| 155 | +it("preserves exact label targets before taskName prefix aliases", () => { |
| 156 | +const runs = [ |
| 157 | +makeRun({ runId: "run-review-label", label: "review" }), |
| 158 | +makeRun({ runId: "run-review-docs", label: "docs", taskName: "review_docs" }), |
| 159 | +]; |
| 160 | + |
| 161 | +expectResolvedRunId(runs, "review", "run-review-label"); |
| 162 | +expectResolvedRunId(runs, "review_", "run-review-docs"); |
| 163 | +}); |
| 164 | + |
155 | 165 | it("ignores stale duplicate taskName aliases when a current run reuses the handle", () => { |
156 | 166 | vi.spyOn(Date, "now").mockReturnValue(NOW_MS); |
157 | 167 | const runs = [ |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -107,15 +107,6 @@ export function resolveSubagentTargetFromRuns(params: {
|
107 | 107 | if (byExactAlias.length > 1) { |
108 | 108 | return { error: params.errors.ambiguousLabel(trimmed) }; |
109 | 109 | } |
110 | | -const byAliasPrefix = numericOrder.filter((entry) => |
111 | | -aliases(entry).some((alias) => normalizeLowercaseStringOrEmpty(alias).startsWith(lowered)), |
112 | | -); |
113 | | -if (byAliasPrefix.length === 1) { |
114 | | -return { entry: byAliasPrefix[0] }; |
115 | | -} |
116 | | -if (byAliasPrefix.length > 1) { |
117 | | -return { error: params.errors.ambiguousLabelPrefix(trimmed) }; |
118 | | -} |
119 | 110 | const byExactLabel = deduped.filter( |
120 | 111 | (entry) => normalizeLowercaseStringOrEmpty(params.label(entry)) === lowered, |
121 | 112 | ); |
@@ -125,6 +116,15 @@ export function resolveSubagentTargetFromRuns(params: {
|
125 | 116 | if (byExactLabel.length > 1) { |
126 | 117 | return { error: params.errors.ambiguousLabel(trimmed) }; |
127 | 118 | } |
| 119 | +const byAliasPrefix = numericOrder.filter((entry) => |
| 120 | +aliases(entry).some((alias) => normalizeLowercaseStringOrEmpty(alias).startsWith(lowered)), |
| 121 | +); |
| 122 | +if (byAliasPrefix.length === 1) { |
| 123 | +return { entry: byAliasPrefix[0] }; |
| 124 | +} |
| 125 | +if (byAliasPrefix.length > 1) { |
| 126 | +return { error: params.errors.ambiguousLabelPrefix(trimmed) }; |
| 127 | +} |
128 | 128 | const byLabelPrefix = deduped.filter((entry) => |
129 | 129 | normalizeLowercaseStringOrEmpty(params.label(entry)).startsWith(lowered), |
130 | 130 | ); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。