fix(session-runtime): make Gemini auth handling and Codex resume state deterministic

Why:
- Gemini exit-code 41 auth guidance was defined in two places with slightly different wording, which creates drift and inconsistent UX when auth fails.
- Gemini env bootstrap only short-circuited when *all* auth-related vars were present; that forced unnecessary user-level env file reads even when a valid primary credential already existed.
- Codex session registration only populated the active-session map when an id was unseen; resumed sessions could retain stale thread/abort/status objects, leading to incorrect lifecycle behavior.
- Debug console logs in runtime request paths added noise without operational value.

What changed:
- Removed exit-code 41 from mapGeminiExitCodeToMessage and kept a single authoritative 41 message in the close-handler auth branch.
- Aligned 41 remediation phrasing to consistently reference a valid GEMINI_API_KEY.
- Updated uildGeminiProcessEnv to return early when any primary auth signal is already present (GEMINI_API_KEY, GOOGLE_API_KEY, or GOOGLE_APPLICATION_CREDENTIALS).
- Changed Codex 
egisterSession to always overwrite session state for valid ids so resumed runs replace stale entries.
- Removed unnecessary console.log debug statements in touched runtime paths, including the chat submit debug log.

Impact:
- More predictable Gemini authentication error messaging.
- Avoids needless env-file fallback when credentials are already available.
- Prevents stale Codex session controllers/status from leaking across resumes.
- Cleaner logs with no behavior change to error/warn reporting.
This commit is contained in:
Haileyesus
2026-05-08 15:52:25 +03:00
parent 5554e4e85e
commit e57ce4248e
3 changed files with 9 additions and 24 deletions

View File

@@ -18,8 +18,6 @@ let activeGeminiProcesses = new Map(); // Track active processes by session ID
function mapGeminiExitCodeToMessage(exitCode) {
switch (exitCode) {
case 41:
return 'Gemini authentication failed (exit code 41). Run `gemini` in a terminal to choose an auth method, or configure a valid `GEMINI_API_KEY`.';
case 42:
return 'Gemini rejected the request input (exit code 42).';
case 44:
@@ -103,7 +101,7 @@ async function loadGeminiUserLevelEnv() {
async function buildGeminiProcessEnv() {
const processEnv = { ...process.env };
if (GEMINI_AUTH_ENV_KEYS.every((key) => processEnv[key])) {
if (processEnv.GEMINI_API_KEY || processEnv.GOOGLE_API_KEY || processEnv.GOOGLE_APPLICATION_CREDENTIALS) {
return processEnv;
}
@@ -265,9 +263,6 @@ async function spawnGemini(command, options = {}, ws) {
// Try to find gemini in PATH first, then fall back to environment variable
const geminiPath = process.env.GEMINI_PATH || 'gemini';
console.log('Spawning Gemini CLI:', geminiPath, args.join(' '));
console.log('Working directory:', workingDir);
let spawnCmd = geminiPath;
let spawnArgs = args;
@@ -525,7 +520,7 @@ async function spawnGemini(command, options = {}, ws) {
terminalFailureReason =
'Gemini authentication failed (exit code 41). '
+ 'Run `gemini` in a terminal to choose an auth method, or configure `GEMINI_API_KEY`.'
+ 'Run `gemini` in a terminal to choose an auth method, or configure a valid `GEMINI_API_KEY`.'
+ authErrorSuffix;
ws.send(createNormalizedMessage({ kind: 'error', content: terminalFailureReason, sessionId: socketSessionId, provider: 'gemini' }));
} else {

View File

@@ -232,21 +232,17 @@ export async function queryCodex(command, options = {}, ws) {
thread = codex.startThread(threadOptions);
}
console.log(`[Codex] Started thread, sandboxMode: ${sandboxMode}, approvalPolicy: ${approvalPolicy}`);
const registerSession = (id) => {
if (!id) {
return;
}
if (!activeCodexSessions.has(id)) {
activeCodexSessions.set(id, {
thread,
codex,
status: 'running',
abortController,
startedAt: new Date().toISOString()
});
}
activeCodexSessions.set(id, {
thread,
codex,
status: 'running',
abortController,
startedAt: new Date().toISOString()
});
};
// Existing sessions can be tracked immediately; new sessions are tracked after thread.started.