Files
oh-my-opencode/src/hooks/directory-agents-injector/hook.ts
T
YeonGyu-Kim 4da48555ee fix(plugin): normalize event session ids
Handle OpenCode session events that carry the session ID under properties.info.id or properties.info.sessionID so background tasks and continuation hooks do not miss idle/error/delete events.

Add regression coverage for nested session.idle events completing background tasks and waking continuation hooks.
2026-05-12 12:32:26 +09:00

81 lines
2.1 KiB
TypeScript

import type { PluginInput } from "@opencode-ai/plugin";
import { createDynamicTruncator } from "../../shared/dynamic-truncator";
import { resolveSessionEventID } from "../../shared/event-session-id";
import { processFilePathForAgentsInjection } from "./injector";
import { clearInjectedPaths } from "./storage";
interface ToolExecuteInput {
tool: string;
sessionID: string;
callID: string;
}
interface ToolExecuteOutput {
title: string;
output: string;
metadata: unknown;
}
interface DirectoryAgentsInjectorHook {
"tool.execute.before"?: (input: ToolExecuteInput, output: { args: unknown }) => Promise<void>;
"tool.execute.after": (input: ToolExecuteInput, output: ToolExecuteOutput) => Promise<void>;
event: (input: EventInput) => Promise<void>;
}
interface EventInput {
event: {
type: string;
properties?: unknown;
};
}
export function createDirectoryAgentsInjectorHook(
ctx: PluginInput,
modelCacheState?: { anthropicContext1MEnabled: boolean },
): DirectoryAgentsInjectorHook {
const sessionCaches = new Map<string, Set<string>>();
const truncator = createDynamicTruncator(ctx, modelCacheState);
const toolExecuteAfter = async (input: ToolExecuteInput, output: ToolExecuteOutput) => {
const toolName = input.tool.toLowerCase();
if (toolName === "read") {
await processFilePathForAgentsInjection({
ctx,
truncator,
sessionCaches,
filePath: output.title,
sessionID: input.sessionID,
output,
});
return;
}
};
const eventHandler = async ({ event }: EventInput) => {
const props = event.properties as Record<string, unknown> | undefined;
if (event.type === "session.deleted") {
const sessionID = resolveSessionEventID(props);
if (sessionID) {
sessionCaches.delete(sessionID);
clearInjectedPaths(sessionID);
}
}
if (event.type === "session.compacted") {
const sessionID = resolveSessionEventID(props);
if (sessionID) {
sessionCaches.delete(sessionID);
clearInjectedPaths(sessionID);
}
}
};
return {
"tool.execute.after": toolExecuteAfter,
event: eventHandler,
};
}