feat(hooks): add empty-message-sanitizer to prevent API errors from empty chat messages

Add new hook that uses the `experimental.chat.messages.transform` hook to prevent 'non-empty content' API errors by injecting placeholder text into empty messages BEFORE they're sent to the API.

This is a preventive fix - unlike session-recovery which fixes errors after they occur, this hook prevents the error from happening by sanitizing messages before API transmission.

Files:
- src/hooks/empty-message-sanitizer/index.ts (new hook implementation)
- src/hooks/index.ts (export hook function)
- src/config/schema.ts (add hook to HookName type)
- src/index.ts (wire up hook to plugin)

🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
YeonGyu-Kim
2025-12-16 21:02:38 +09:00
parent 3761d45712
commit 7293b8845d
4 changed files with 105 additions and 0 deletions

View File

@@ -20,6 +20,7 @@ import {
createAgentUsageReminderHook,
createNonInteractiveEnvHook,
createInteractiveBashSessionHook,
createEmptyMessageSanitizerHook,
} from "./hooks";
import { createGoogleAntigravityAuthPlugin } from "./auth/antigravity";
import {
@@ -246,6 +247,9 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
const interactiveBashSession = isHookEnabled("interactive-bash-session")
? createInteractiveBashSessionHook(ctx)
: null;
const emptyMessageSanitizer = isHookEnabled("empty-message-sanitizer")
? createEmptyMessageSanitizerHook()
: null;
updateTerminalTitle({ sessionId: "main" });
@@ -281,6 +285,14 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
await keywordDetector?.["chat.message"]?.(input, output);
},
"experimental.chat.messages.transform": async (
input: Record<string, never>,
output: { messages: Array<{ info: unknown; parts: unknown[] }> }
) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await emptyMessageSanitizer?.["experimental.chat.messages.transform"]?.(input, output as any);
},
config: async (config) => {
const builtinAgents = createBuiltinAgents(
pluginConfig.disabled_agents,