diff --git a/codex-cli/src/components/chat/terminal-chat-response-item.tsx b/codex-cli/src/components/chat/terminal-chat-response-item.tsx index 4b7e069f..dc4b16dd 100644 --- a/codex-cli/src/components/chat/terminal-chat-response-item.tsx +++ b/codex-cli/src/components/chat/terminal-chat-response-item.tsx @@ -1,3 +1,4 @@ +import type { OverlayModeType } from "./terminal-chat"; import type { TerminalRendererOptions } from "marked-terminal"; import type { ResponseFunctionToolCallItem, @@ -14,18 +15,25 @@ import chalk, { type ForegroundColorName } from "chalk"; import { Box, Text } from "ink"; import { parse, setOptions } from "marked"; import TerminalRenderer from "marked-terminal"; -import React, { useMemo } from "react"; +import React, { useEffect, useMemo } from "react"; export default function TerminalChatResponseItem({ item, fullStdout = false, + setOverlayMode, }: { item: ResponseItem; fullStdout?: boolean; + setOverlayMode?: React.Dispatch>; }): React.ReactElement { switch (item.type) { case "message": - return ; + return ( + + ); case "function_call": return ; case "function_call_output": @@ -98,9 +106,23 @@ const colorsByRole: Record = { function TerminalChatResponseMessage({ message, + setOverlayMode, }: { message: ResponseInputMessageItem | ResponseOutputMessage; + setOverlayMode?: React.Dispatch>; }) { + // auto switch to model mode if the system message contains "has been deprecated" + useEffect(() => { + if (message.role === "system") { + const systemMessage = message.content.find( + (c) => c.type === "input_text", + )?.text; + if (systemMessage?.includes("has been deprecated")) { + setOverlayMode?.("model"); + } + } + }, [message, setOverlayMode]); + return ( diff --git a/codex-cli/src/components/chat/terminal-chat.tsx b/codex-cli/src/components/chat/terminal-chat.tsx index fd4cff5d..5f702577 100644 --- a/codex-cli/src/components/chat/terminal-chat.tsx +++ b/codex-cli/src/components/chat/terminal-chat.tsx @@ -37,6 +37,14 @@ import OpenAI from "openai"; import React, { useEffect, useMemo, useRef, useState } from "react"; import { inspect } from "util"; +export type OverlayModeType = + | "none" + | "history" + | "model" + | "approval" + | "help" + | "diff"; + type Props = { config: AppConfig; prompt?: string; @@ -182,9 +190,7 @@ export default function TerminalChat({ explanation, submitConfirmation, } = useConfirmation(); - const [overlayMode, setOverlayMode] = useState< - "none" | "history" | "model" | "approval" | "help" | "diff" - >("none"); + const [overlayMode, setOverlayMode] = useState("none"); // Store the diff text when opening the diff overlay so the view isn’t // recomputed on every re‑render while it is open. @@ -461,6 +467,7 @@ export default function TerminalChat({ {agent ? ( >; }; const MessageHistory: React.FC = ({ @@ -30,6 +32,7 @@ const MessageHistory: React.FC = ({ loading: _loading, thinkingSeconds: _thinkingSeconds, fullStdout, + setOverlayMode, }) => { // Flatten batch entries to response items. const messages = useMemo(() => batch.map(({ item }) => item!), [batch]); @@ -65,6 +68,7 @@ const MessageHistory: React.FC = ({ );