Files
oh-my-opencode/src/hooks/keyword-detector/index.ts
T

82 lines
2.7 KiB
TypeScript
Raw Normal View History

import type { PluginInput } from "@opencode-ai/plugin"
import { detectKeywordsWithType, extractPromptText, removeCodeBlocks } from "./detector"
import { log } from "../../shared"
export * from "./detector"
export * from "./constants"
export * from "./types"
export function createKeywordDetectorHook(ctx: PluginInput) {
return {
"chat.message": async (
input: {
sessionID: string
agent?: string
model?: { providerID: string; modelID: string }
messageID?: string
},
output: {
message: Record<string, unknown>
parts: Array<{ type: string; text?: string; [key: string]: unknown }>
}
): Promise<void> => {
const promptText = extractPromptText(output.parts)
let detectedKeywords = detectKeywordsWithType(removeCodeBlocks(promptText), input.agent)
if (detectedKeywords.length === 0) {
return
}
// Check if this is a subagent session (has parent)
// Only ultrawork keywords work in subagent sessions
// Other keywords (search, analyze, etc.) only work in main sessions
try {
const sessionInfo = await ctx.client.session.get({ path: { id: input.sessionID } })
const isSubagentSession = !!sessionInfo.data?.parentID
if (isSubagentSession) {
// Filter to only ultrawork keywords in subagent sessions
detectedKeywords = detectedKeywords.filter((k) => k.type === "ultrawork")
if (detectedKeywords.length === 0) {
log(`[keyword-detector] Skipping non-ultrawork keywords in subagent session`, {
sessionID: input.sessionID,
parentID: sessionInfo.data?.parentID,
})
return
}
}
} catch (err) {
log(`[keyword-detector] Failed to get session info, proceeding with all keywords`, {
error: err,
sessionID: input.sessionID,
})
}
const hasUltrawork = detectedKeywords.some((k) => k.type === "ultrawork")
if (hasUltrawork) {
log(`[keyword-detector] Ultrawork mode activated`, { sessionID: input.sessionID })
output.message.variant = "max"
ctx.client.tui
.showToast({
body: {
title: "Ultrawork Mode Activated",
message: "Maximum precision engaged. All agents at your disposal.",
variant: "success" as const,
duration: 3000,
},
})
.catch((err) =>
log(`[keyword-detector] Failed to show toast`, { error: err, sessionID: input.sessionID })
)
}
log(`[keyword-detector] Detected ${detectedKeywords.length} keywords`, {
sessionID: input.sessionID,
types: detectedKeywords.map((k) => k.type),
})
},
}
}