Files
oh-my-openagent/src/hooks/think-mode/index.test.ts
YeonGyu-Kim b7b6721796 refactor(think-mode): migrate hook from chat.params to chat.message and remove thinking config injection
Drop provider-specific thinking config injection (THINKING_CONFIGS, getThinkingConfig,
resolveProvider) and instead rely on the provider to handle thinking based on the variant field.
Hook now fires on chat.message using model from input rather than from the message object.

🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
2026-02-26 20:08:44 +09:00

156 lines
4.0 KiB
TypeScript

import { beforeEach, describe, expect, it } from "bun:test"
const { clearThinkModeState, createThinkModeHook } = await import("./index")
type ThinkModeHookInput = {
sessionID: string
model?: { providerID: string; modelID: string }
}
type ThinkModeHookOutput = {
message: Record<string, unknown>
parts: Array<{ type: string; text?: string; [key: string]: unknown }>
}
function createHookInput(args: {
sessionID?: string
providerID?: string
modelID?: string
}): ThinkModeHookInput {
const { sessionID = "test-session-id", providerID, modelID } = args
if (!providerID || !modelID) {
return { sessionID }
}
return {
sessionID,
model: { providerID, modelID },
}
}
function createHookOutput(promptText: string, variant?: string): ThinkModeHookOutput {
return {
message: variant ? { variant } : {},
parts: [{ type: "text", text: promptText }],
}
}
describe("createThinkModeHook", () => {
const sessionID = "test-session-id"
beforeEach(() => {
clearThinkModeState(sessionID)
})
it("sets high variant and switches model when think keyword is present", async () => {
// given
const hook = createThinkModeHook()
const input = createHookInput({
sessionID,
providerID: "github-copilot",
modelID: "claude-opus-4-6",
})
const output = createHookOutput("Please think deeply about this")
// when
await hook["chat.message"](input, output)
// then
expect(output.message.variant).toBe("high")
expect(output.message.model).toEqual({
providerID: "github-copilot",
modelID: "claude-opus-4-6-high",
})
})
it("supports dotted model IDs by switching to normalized high variant", async () => {
// given
const hook = createThinkModeHook()
const input = createHookInput({
sessionID,
providerID: "github-copilot",
modelID: "gpt-5.2",
})
const output = createHookOutput("ultrathink about this")
// when
await hook["chat.message"](input, output)
// then
expect(output.message.variant).toBe("high")
expect(output.message.model).toEqual({
providerID: "github-copilot",
modelID: "gpt-5-2-high",
})
})
it("skips when message variant is already set", async () => {
// given
const hook = createThinkModeHook()
const input = createHookInput({
sessionID,
providerID: "github-copilot",
modelID: "claude-sonnet-4-6",
})
const output = createHookOutput("think through this", "max")
// when
await hook["chat.message"](input, output)
// then
expect(output.message.variant).toBe("max")
expect(output.message.model).toBeUndefined()
})
it("does nothing when think keyword is absent", async () => {
// given
const hook = createThinkModeHook()
const input = createHookInput({
sessionID,
providerID: "google",
modelID: "gemini-3-pro",
})
const output = createHookOutput("Please solve this directly")
// when
await hook["chat.message"](input, output)
// then
expect(output.message.variant).toBeUndefined()
expect(output.message.model).toBeUndefined()
})
it("does not modify already-high models", async () => {
// given
const hook = createThinkModeHook()
const input = createHookInput({
sessionID,
providerID: "openai",
modelID: "gpt-5-high",
})
const output = createHookOutput("think deeply")
// when
await hook["chat.message"](input, output)
// then
expect(output.message.variant).toBeUndefined()
expect(output.message.model).toBeUndefined()
})
it("handles missing input model without crashing", async () => {
// given
const hook = createThinkModeHook()
const input = createHookInput({ sessionID })
const output = createHookOutput("think about this")
// when
await expect(hook["chat.message"](input, output)).resolves.toBeUndefined()
// then
expect(output.message.variant).toBeUndefined()
expect(output.message.model).toBeUndefined()
})
})