Merge pull request #1614 from code-yeongyu/fix/1501-ulw-plan-loop

fix(ultrawork): widen isPlannerAgent matching to prevent ULW infinite plan loop (#1501)
This commit is contained in:
YeonGyu-Kim
2026-02-07 19:59:41 +09:00
committed by GitHub
2 changed files with 24 additions and 1 deletions

View File

@@ -598,6 +598,26 @@ describe("keyword-detector agent-specific ultrawork messages", () => {
expect(textPart!.text).not.toContain("YOU ARE A PLANNER, NOT AN IMPLEMENTER")
})
test("should skip ultrawork injection when agent name contains 'plan' token", async () => {
//#given - collector and agent name that includes a plan token
const collector = new ContextCollector()
const hook = createKeywordDetectorHook(createMockPluginInput(), collector)
const sessionID = "plan-agent-session"
const output = {
message: {} as Record<string, unknown>,
parts: [{ type: "text", text: "ultrawork draft a plan" }],
}
//#when - ultrawork keyword detected with plan-like agent name
await hook["chat.message"]({ sessionID, agent: "Plan Agent" }, output)
//#then - ultrawork should be skipped, text unchanged
const textPart = output.parts.find(p => p.type === "text")
expect(textPart).toBeDefined()
expect(textPart!.text).toBe("ultrawork draft a plan")
expect(textPart!.text).not.toContain("YOU ARE A PLANNER, NOT AN IMPLEMENTER")
})
test("should use normal ultrawork message when agent is Sisyphus", async () => {
// given - collector and Sisyphus agent
const collector = new ContextCollector()

View File

@@ -14,7 +14,10 @@
export function isPlannerAgent(agentName?: string): boolean {
if (!agentName) return false
const lowerName = agentName.toLowerCase()
return lowerName.includes("prometheus") || lowerName.includes("planner") || lowerName === "plan"
if (lowerName.includes("prometheus") || lowerName.includes("planner")) return true
const normalized = lowerName.replace(/[_-]+/g, " ")
return /\bplan\b/.test(normalized)
}
/**