fix(plugin): ignore compaction session agent updates
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,83 @@
|
|||||||
|
declare const require: (name: string) => any
|
||||||
|
const { afterEach, describe, expect, test } = require("bun:test")
|
||||||
|
|
||||||
|
import { _resetForTesting, getSessionAgent, updateSessionAgent } from "../features/claude-code-session-state"
|
||||||
|
import { createEventHandler } from "./event"
|
||||||
|
|
||||||
|
function createMinimalEventHandler() {
|
||||||
|
return createEventHandler({
|
||||||
|
ctx: {} as never,
|
||||||
|
pluginConfig: {} as never,
|
||||||
|
firstMessageVariantGate: {
|
||||||
|
markSessionCreated: () => {},
|
||||||
|
clear: () => {},
|
||||||
|
},
|
||||||
|
managers: {
|
||||||
|
tmuxSessionManager: {
|
||||||
|
onSessionCreated: async () => {},
|
||||||
|
onSessionDeleted: async () => {},
|
||||||
|
},
|
||||||
|
skillMcpManager: {
|
||||||
|
disconnectSession: async () => {},
|
||||||
|
},
|
||||||
|
} as never,
|
||||||
|
hooks: {
|
||||||
|
autoUpdateChecker: { event: async () => {} },
|
||||||
|
claudeCodeHooks: { event: async () => {} },
|
||||||
|
backgroundNotificationHook: { event: async () => {} },
|
||||||
|
sessionNotification: async () => {},
|
||||||
|
todoContinuationEnforcer: { handler: async () => {} },
|
||||||
|
unstableAgentBabysitter: { event: async () => {} },
|
||||||
|
contextWindowMonitor: { event: async () => {} },
|
||||||
|
directoryAgentsInjector: { event: async () => {} },
|
||||||
|
directoryReadmeInjector: { event: async () => {} },
|
||||||
|
rulesInjector: { event: async () => {} },
|
||||||
|
thinkMode: { event: async () => {} },
|
||||||
|
anthropicContextWindowLimitRecovery: { event: async () => {} },
|
||||||
|
runtimeFallback: undefined,
|
||||||
|
modelFallback: undefined,
|
||||||
|
agentUsageReminder: { event: async () => {} },
|
||||||
|
categorySkillReminder: { event: async () => {} },
|
||||||
|
interactiveBashSession: { event: async () => {} },
|
||||||
|
ralphLoop: { event: async () => {} },
|
||||||
|
stopContinuationGuard: { event: async () => {}, isStopped: () => false },
|
||||||
|
compactionTodoPreserver: { event: async () => {} },
|
||||||
|
writeExistingFileGuard: { event: async () => {} },
|
||||||
|
atlasHook: { handler: async () => {} },
|
||||||
|
} as never,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("createEventHandler compaction agent filtering", () => {
|
||||||
|
afterEach(() => {
|
||||||
|
_resetForTesting()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("does not overwrite the stored session agent with compaction", async () => {
|
||||||
|
// given
|
||||||
|
const sessionID = "ses_compaction_poisoning"
|
||||||
|
updateSessionAgent(sessionID, "atlas")
|
||||||
|
const eventHandler = createMinimalEventHandler()
|
||||||
|
const input: Parameters<ReturnType<typeof createEventHandler>>[0] = {
|
||||||
|
event: {
|
||||||
|
type: "message.updated",
|
||||||
|
properties: {
|
||||||
|
info: {
|
||||||
|
id: "msg-compaction",
|
||||||
|
sessionID,
|
||||||
|
role: "user",
|
||||||
|
agent: "compaction",
|
||||||
|
time: { created: Date.now() },
|
||||||
|
model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
await eventHandler(input)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(getSessionAgent(sessionID)).toBe("atlas")
|
||||||
|
})
|
||||||
|
})
|
||||||
+6
-1
@@ -97,6 +97,11 @@ function extractProviderModelFromErrorMessage(message: string): { providerID?: s
|
|||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCompactionAgent(agent: string): boolean {
|
||||||
|
return agent.toLowerCase() === "compaction";
|
||||||
|
}
|
||||||
|
|
||||||
type EventInput = Parameters<NonNullable<NonNullable<CreatedHooks["writeExistingFileGuard"]>["event"]>>[0];
|
type EventInput = Parameters<NonNullable<NonNullable<CreatedHooks["writeExistingFileGuard"]>["event"]>>[0];
|
||||||
export function createEventHandler(args: {
|
export function createEventHandler(args: {
|
||||||
ctx: PluginContext;
|
ctx: PluginContext;
|
||||||
@@ -261,7 +266,7 @@ export function createEventHandler(args: {
|
|||||||
const agent = info?.agent as string | undefined;
|
const agent = info?.agent as string | undefined;
|
||||||
const role = info?.role as string | undefined;
|
const role = info?.role as string | undefined;
|
||||||
if (sessionID && role === "user") {
|
if (sessionID && role === "user") {
|
||||||
if (agent) {
|
if (agent && !isCompactionAgent(agent)) {
|
||||||
updateSessionAgent(sessionID, agent);
|
updateSessionAgent(sessionID, agent);
|
||||||
}
|
}
|
||||||
const providerID = info?.providerID as string | undefined;
|
const providerID = info?.providerID as string | undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user