diff --git a/src/plugin/chat-message.test.ts b/src/plugin/chat-message.test.ts index 7cf86656b..b00784b2e 100644 --- a/src/plugin/chat-message.test.ts +++ b/src/plugin/chat-message.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, test, expect } from "bun:test" -import { mkdirSync, rmSync, writeFileSync } from "node:fs" +import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs" import { tmpdir } from "node:os" import { join } from "node:path" import { randomUUID } from "node:crypto" @@ -11,6 +11,7 @@ import { createStartWorkHook } from "../hooks/start-work" import { readBoulderState } from "../features/boulder-state" import { _resetForTesting, setMainSession, subagentSessions, registerAgentName, updateSessionAgent, getSessionAgent } from "../features/claude-code-session-state" import { getAgentListDisplayName } from "../shared/agent-display-names" +import { getOmoOpenCodeCacheDir, getOpenCodeCacheDir } from "../shared/data-path" import { clearSessionModel, getSessionModel, setSessionModel } from "../shared/session-model-state" type ChatMessagePart = { type: string; text?: string; [key: string]: unknown } @@ -48,6 +49,94 @@ afterEach(() => { clearSessionModel("subagent-session") }) +describe("createChatMessageHandler - cache warning behavior", () => { + let cacheRoot = "" + let originalXdgCacheHome: string | undefined + + beforeEach(() => { + cacheRoot = join(tmpdir(), `chat-message-cache-${randomUUID()}`) + originalXdgCacheHome = process.env.XDG_CACHE_HOME + process.env.XDG_CACHE_HOME = cacheRoot + }) + + afterEach(() => { + if (originalXdgCacheHome === undefined) { + delete process.env.XDG_CACHE_HOME + } else { + process.env.XDG_CACHE_HOME = originalXdgCacheHome + } + + if (existsSync(cacheRoot)) { + rmSync(cacheRoot, { recursive: true, force: true }) + } + }) + + test("does not show provider cache warning when provider-models cache exists", async () => { + // given + const toastCalls: Array<{ body: { title: string; message: string } }> = [] + const providerModelsCachePath = join(getOmoOpenCodeCacheDir(), "provider-models.json") + mkdirSync(getOmoOpenCodeCacheDir(), { recursive: true }) + writeFileSync(providerModelsCachePath, JSON.stringify({ + models: { + openai: [{ id: "gpt-5.4" }], + }, + connected: ["openai"], + updatedAt: new Date().toISOString(), + })) + + const args = createMockHandlerArgs() + args.ctx = { + client: { + tui: { + showToast: async (input: { body: { title: string; message: string } }) => { + toastCalls.push(input) + }, + }, + }, + } as never + const handler = createChatMessageHandler(args) + + // when + await handler(createMockInput("sisyphus"), createMockOutput()) + + // then + expect(toastCalls).toHaveLength(0) + }) + + test("does not show provider cache warning when OpenCode models cache exists", async () => { + // given + const toastCalls: Array<{ body: { title: string; message: string } }> = [] + const modelsCachePath = join(getOpenCodeCacheDir(), "models.json") + mkdirSync(getOpenCodeCacheDir(), { recursive: true }) + writeFileSync(modelsCachePath, JSON.stringify({ + openai: { + id: "openai", + models: { + "gpt-5.4": { id: "gpt-5.4" }, + }, + }, + })) + + const args = createMockHandlerArgs() + args.ctx = { + client: { + tui: { + showToast: async (input: { body: { title: string; message: string } }) => { + toastCalls.push(input) + }, + }, + }, + } as never + const handler = createChatMessageHandler(args) + + // when + await handler(createMockInput("sisyphus"), createMockOutput()) + + // then + expect(toastCalls).toHaveLength(0) + }) +}) + describe("createChatMessageHandler - /start-work integration", () => { let testDir = "" let originalWorkingDirectory = "" diff --git a/src/plugin/chat-message.ts b/src/plugin/chat-message.ts index b0683979b..890265877 100644 --- a/src/plugin/chat-message.ts +++ b/src/plugin/chat-message.ts @@ -1,7 +1,7 @@ import type { OhMyOpenCodeConfig } from "../config" import type { PluginContext } from "./types" -import { hasConnectedProvidersCache } from "../shared" +import { isModelCacheAvailable } from "../shared" import { getAgentConfigKey } from "../shared/agent-display-names" import { getSessionModel, setSessionModel } from "../shared/session-model-state" import { getMainSessionID, setSessionAgent, subagentSessions } from "../features/claude-code-session-state" @@ -210,7 +210,7 @@ export function createChatMessageHandler(args: { await hooks.startWork["chat.message"]?.(input, output) } - if (!hasConnectedProvidersCache()) { + if (!isModelCacheAvailable()) { pluginContext.client.tui .showToast({ body: {