Files
oh-my-openagent/src/shared/system-directive.ts
TheEpTic 01500f1ebe Fix: prevent system-reminder tags from triggering mode keywords (#1155)
Automated system messages with <system-reminder> tags were incorrectly
triggering [search-mode], [analyze-mode], and other keyword modes when
they contained words like "search", "find", "explore", etc.

Changes:
- Add removeSystemReminders() to strip <system-reminder> content before keyword detection
- Add hasSystemReminder() utility function
- Update keyword-detector to clean text before pattern matching
- Add comprehensive test coverage for system-reminder filtering

Fixes issue where automated system notifications caused agents to
incorrectly enter MAXIMUM SEARCH EFFORT mode.

Co-authored-by: TheEpTic <git@eptic.me>
2026-01-28 16:26:37 +09:00

61 lines
2.2 KiB
TypeScript

/**
* Unified system directive prefix for oh-my-opencode internal messages.
* All system-generated messages should use this prefix for consistent filtering.
*
* Format: [SYSTEM DIRECTIVE: OH-MY-OPENCODE - {TYPE}]
*/
export const SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: OH-MY-OPENCODE"
/**
* Creates a system directive header with the given type.
* @param type - The directive type (e.g., "TODO CONTINUATION", "RALPH LOOP")
* @returns Formatted directive string like "[SYSTEM DIRECTIVE: OH-MY-OPENCODE - TODO CONTINUATION]"
*/
export function createSystemDirective(type: string): string {
return `${SYSTEM_DIRECTIVE_PREFIX} - ${type}]`
}
/**
* Checks if a message starts with the oh-my-opencode system directive prefix.
* Used by keyword-detector and other hooks to skip system-generated messages.
* @param text - The message text to check
* @returns true if the message is a system directive
*/
export function isSystemDirective(text: string): boolean {
return text.trimStart().startsWith(SYSTEM_DIRECTIVE_PREFIX)
}
/**
* Checks if a message contains system-generated content that should be excluded
* from keyword detection and mode triggering.
* @param text - The message text to check
* @returns true if the message contains system-reminder tags
*/
export function hasSystemReminder(text: string): boolean {
return /<system-reminder>[\s\S]*?<\/system-reminder>/i.test(text)
}
/**
* Removes system-reminder tag content from text.
* This prevents automated system messages from triggering mode keywords.
* @param text - The message text to clean
* @returns text with system-reminder content removed
*/
export function removeSystemReminders(text: string): string {
return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/gi, "").trim()
}
export const SystemDirectiveTypes = {
TODO_CONTINUATION: "TODO CONTINUATION",
RALPH_LOOP: "RALPH LOOP",
BOULDER_CONTINUATION: "BOULDER CONTINUATION",
DELEGATION_REQUIRED: "DELEGATION REQUIRED",
SINGLE_TASK_ONLY: "SINGLE TASK ONLY",
COMPACTION_CONTEXT: "COMPACTION CONTEXT",
CONTEXT_WINDOW_MONITOR: "CONTEXT WINDOW MONITOR",
PROMETHEUS_READ_ONLY: "PROMETHEUS READ-ONLY",
} as const
export type SystemDirectiveType = (typeof SystemDirectiveTypes)[keyof typeof SystemDirectiveTypes]