fix(keyword-detector): skip synthetic turns

This commit is contained in:
YeonGyu-Kim
2026-05-15 22:49:17 +09:00
parent 196f6512ae
commit 672f5d6e9b
2 changed files with 45 additions and 10 deletions
+20 -10
View File
@@ -1,20 +1,20 @@
import type { PluginInput } from "@opencode-ai/plugin"
import type { KeywordDetectorConfig } from "../../config/schema/keyword-detector"
import type { DetectedKeyword } from "./detector"
import { detectKeywordsWithType, extractPromptText, looksLikeSlashCommand } from "./detector"
import { isPlannerAgent, isNonOmoAgent } from "./constants"
import { log } from "../../shared"
import {
isSystemDirective,
removeSystemReminders,
} from "../../shared/system-directive"
import {
getMainSessionID,
getSessionAgent,
subagentSessions,
} from "../../features/claude-code-session-state"
import type { ContextCollector } from "../../features/context-injector"
import { log } from "../../shared"
import {
isSystemDirective,
removeSystemReminders,
} from "../../shared/system-directive"
import type { RalphLoopHook } from "../ralph-loop"
import { isNonOmoAgent, isPlannerAgent } from "./constants"
import type { DetectedKeyword } from "./detector"
import { detectKeywordsWithType, extractPromptText, looksLikeSlashCommand } from "./detector"
function suppressComboStandalones(detected: DetectedKeyword[]): DetectedKeyword[] {
const hasCombo = detected.some((k) => k.type === "hyperplan-ultrawork")
@@ -22,6 +22,11 @@ function suppressComboStandalones(detected: DetectedKeyword[]): DetectedKeyword[
return detected.filter((k) => k.type !== "ultrawork" && k.type !== "hyperplan")
}
function isSyntheticTextMessage(parts: Array<{ type: string; text?: string; [key: string]: unknown }>): boolean {
const textParts = parts.filter((part) => part.type === "text" && part.text !== undefined)
return textParts.length > 0 && textParts.every((part) => part.synthetic === true)
}
export function createKeywordDetectorHook(
ctx: PluginInput,
_collector?: ContextCollector,
@@ -30,8 +35,8 @@ export function createKeywordDetectorHook(
) {
const disabledKeywords = config?.disabled_keywords
function getRuntimeVariant(input: { variant?: string }, message: Record<string, unknown>): string | undefined {
if (typeof message["variant"] === "string") {
return message["variant"]
if (typeof message.variant === "string") {
return message.variant
}
return typeof input.variant === "string" ? input.variant : undefined
@@ -51,6 +56,11 @@ export function createKeywordDetectorHook(
parts: Array<{ type: string; text?: string; [key: string]: unknown }>
}
): Promise<void> => {
if (isSyntheticTextMessage(output.parts)) {
log(`[keyword-detector] Skipping synthetic text message`, { sessionID: input.sessionID })
return
}
const promptText = extractPromptText(output.parts)
if (isSystemDirective(promptText)) {