fix(athena): use getAgentConfigKey for keyword-detector Athena exclusion
The previous check used currentAgent?.toLowerCase() === 'athena' which failed after display name remapping stored the agent as 'Athena (Council)' in session state. Now uses getAgentConfigKey() to resolve display names back to config keys, matching the established pattern used by other hooks (atlas, todo-continuation, etc.). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
00051d6f19
commit
5a92c30f18
@ -11,6 +11,7 @@ import {
|
||||
getSessionAgent,
|
||||
subagentSessions,
|
||||
} from "../../features/claude-code-session-state"
|
||||
import { getAgentConfigKey } from "../../shared/agent-display-names"
|
||||
import type { ContextCollector } from "../../features/context-injector"
|
||||
|
||||
export function createKeywordDetectorHook(ctx: PluginInput, _collector?: ContextCollector) {
|
||||
@ -48,7 +49,9 @@ export function createKeywordDetectorHook(ctx: PluginInput, _collector?: Context
|
||||
// Athena is a council orchestrator — skip all keyword injections.
|
||||
// search/analyze modes tell the agent to use explore agents and grep directly,
|
||||
// which conflicts with Athena's job of calling athena_council for council fan-out.
|
||||
if (currentAgent?.toLowerCase() === "athena") {
|
||||
// Use getAgentConfigKey to handle display name remapping ("Athena (Council)" → "athena").
|
||||
const agentConfigKey = currentAgent ? getAgentConfigKey(currentAgent) : undefined
|
||||
if (agentConfigKey === "athena") {
|
||||
log(`[keyword-detector] Skipping all keywords for Athena (council orchestrator)`, {
|
||||
sessionID: input.sessionID,
|
||||
skippedTypes: detectedKeywords.map((k) => k.type),
|
||||
|
||||
@ -745,4 +745,54 @@ describe("keyword-detector agent-specific ultrawork messages", () => {
|
||||
expect(textPart!.text).toBe("ultrawork plan this")
|
||||
expect(textPart!.text).not.toContain("YOU ARE A PLANNER, NOT AN IMPLEMENTER")
|
||||
})
|
||||
|
||||
test("should skip ALL keyword injections for Athena with display name", async () => {
|
||||
// given - session agent is stored as display name "Athena (Council)" after remapping
|
||||
const collector = new ContextCollector()
|
||||
const hook = createKeywordDetectorHook(createMockPluginInput(), collector)
|
||||
const sessionID = "athena-display-name-session"
|
||||
updateSessionAgent(sessionID, "Athena (Council)")
|
||||
|
||||
const output = {
|
||||
message: {} as Record<string, unknown>,
|
||||
parts: [{ type: "text", text: "ultrawork search for bugs in the code" }],
|
||||
}
|
||||
|
||||
// when - keyword detection runs with Athena display name in session state
|
||||
await hook["chat.message"]({ sessionID }, output)
|
||||
|
||||
// then - ALL keywords should be skipped (no injection)
|
||||
const textPart = output.parts.find(p => p.type === "text")
|
||||
expect(textPart!.text).toBe("ultrawork search for bugs in the code")
|
||||
expect(textPart!.text).not.toContain("[search-mode]")
|
||||
expect(textPart!.text).not.toContain("MAXIMIZE SEARCH EFFORT")
|
||||
|
||||
const skipLog = logCalls.find(c => c.msg.includes("Skipping all keywords for Athena"))
|
||||
expect(skipLog).toBeDefined()
|
||||
|
||||
clearSessionAgent(sessionID)
|
||||
})
|
||||
|
||||
test("should skip ALL keyword injections for Athena with lowercase config key", async () => {
|
||||
// given - session agent is stored as lowercase "athena"
|
||||
const collector = new ContextCollector()
|
||||
const hook = createKeywordDetectorHook(createMockPluginInput(), collector)
|
||||
const sessionID = "athena-lowercase-session"
|
||||
|
||||
const output = {
|
||||
message: {} as Record<string, unknown>,
|
||||
parts: [{ type: "text", text: "search for the implementation" }],
|
||||
}
|
||||
|
||||
// when - keyword detection runs with athena as input.agent
|
||||
await hook["chat.message"]({ sessionID, agent: "athena" }, output)
|
||||
|
||||
// then - ALL keywords should be skipped
|
||||
const textPart = output.parts.find(p => p.type === "text")
|
||||
expect(textPart!.text).toBe("search for the implementation")
|
||||
expect(textPart!.text).not.toContain("[search-mode]")
|
||||
|
||||
const skipLog = logCalls.find(c => c.msg.includes("Skipping all keywords for Athena"))
|
||||
expect(skipLog).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user