diff --git a/CHANGELOG.md b/CHANGELOG.md index c39e66a7..dbb346ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Fixed +- Explain Codex ChatGPT-login model rejections with localized recovery and distinguish model catalog discovery from verified access (#613). - #615: Validate Windows process ancestry by creation time so reused parent PIDs cannot attach unrelated processes to the packaged-app smoke test or its cleanup tree. - #611: Preserve complete Codex employee questions and thread context on Windows by sending prompts through stdin. Chinese, multiline and long requests no longer lose their content through `.cmd` launchers; input-pipe failures produce a typed error. - #609: Refresh the Codex employee model picker from the installed CLI's model catalog, preserve saved selections, and show stale/unavailable fallback status instead of silently relying on an outdated disk cache. diff --git a/README.md b/README.md index 499d5d83..7211e94d 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ Useful commands from the repository root: ## Current limits -For Codex employees, the model picker queries the installed Codex CLI's `model/list` catalog and caches results briefly. Use **Refresh model list** to retry discovery. Failed discovery keeps the previous list or local disk cache and shows a fallback status; saved model choices remain available. A listed model does not guarantee inference access for the account or provider. +For Codex employees, the model picker queries the installed Codex CLI's `model/list` catalog and caches results briefly. Use **Refresh model list** to retry discovery. Failed discovery keeps the previous list or local disk cache and shows a fallback status; saved model choices remain available. A listed or recommended model does not guarantee inference access for the account or provider; refreshing the list does not verify that access. If Codex rejects a model for the ChatGPT login, the conversation explains the rejection and the picker flags the last matching failed request. Choose another employee model or check the login in the same Codex CLI before resending. RoleWeave keeps the saved model and never switches to API billing automatically. - Real Qoder execution has been verified on a macOS machine. Claude Code live execution, full delegation chains, and end-to-end long-term context workflows are not yet part of the verified baseline. - macOS has a signed-manifest update mechanism. New Windows builds can check, download, and install unsigned NSIS updates after user confirmation. The downloaded installer is checked against SHA-512 metadata fetched over HTTPS; there is no independent publisher signature on this channel. Publishing a release exposes its metadata to clients checking these channels. diff --git a/apps/desktop/renderer/src/turns/ConversationOptions.tsx b/apps/desktop/renderer/src/turns/ConversationOptions.tsx index 9930743d..b656e349 100644 --- a/apps/desktop/renderer/src/turns/ConversationOptions.tsx +++ b/apps/desktop/renderer/src/turns/ConversationOptions.tsx @@ -103,6 +103,9 @@ export function ConversationOptions({ config, engine, saving, disabled, loading const contextPanel = useRef(null); const usagePanel = useRef(null); const completed = turns.filter((turn) => !turn.provisional && turn.status !== "running"); + const codex = engine === "codex" || engine === "codex-local"; + const lastModelAttempt = codex ? completed.filter((turn) => turn.engine === engine && turn.model === config?.selected).at(-1) : undefined; + const modelWasRejected = lastModelAttempt?.status === "failed" && lastModelAttempt.errorCode === "codex.model_access_denied"; const reported = completed.filter((turn) => turn.totalTokens !== undefined); const total = reported.reduce((sum, turn) => sum + turn.totalTokens!, 0); // The latest completed turn is authoritative. Do not surface an older @@ -211,6 +214,8 @@ export function ConversationOptions({ config, engine, saving, disabled, loading : null} {config.catalogStatus && config.catalogStatus !== "ready" ?

{t(`model.catalog.${config.catalogStatus}`)}

: null} + {codex ?

{t("model.codexAccessUnverified")}

: null} + {modelWasRejected ?

{t("model.codexLastRejected")}

: null} {connection ?
: null} {menu} {config.allowCustomModel && !connectionInvalid && onModel ? : null} diff --git a/apps/desktop/renderer/src/turns/TurnThread.tsx b/apps/desktop/renderer/src/turns/TurnThread.tsx index 6c797e54..9fd7610c 100644 --- a/apps/desktop/renderer/src/turns/TurnThread.tsx +++ b/apps/desktop/renderer/src/turns/TurnThread.tsx @@ -485,6 +485,9 @@ export function TurnThread({ turns, loading = false, onEdit, viewportMemory, ret