mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-07 06:52:28 +00:00
refactor(codex): extract session management and launcher logic into separate modules
Reorganized runCodex.ts to improve maintainability by extracting: - CodexSession class for session lifecycle management - CodexLocalLauncher and CodexRemoteLauncher for mode-specific initialization - CodexEventConverter for MCP message handling and UI buffer updates - CodexSessionScanner for resume file discovery - emitReadyIfIdle utility for ready event emission Added codexSessionId field to metadata schema for session tracking. Updated UI components to work with refactored architecture.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import { logger } from '@/ui/logger';
|
||||
import { codexLocal } from './codexLocal';
|
||||
import { CodexSession } from './session';
|
||||
import { Future } from '@/utils/future';
|
||||
import { createCodexSessionScanner } from './utils/codexSessionScanner';
|
||||
import { convertCodexEvent } from './utils/codexEventConverter';
|
||||
|
||||
export async function codexLocalLauncher(session: CodexSession): Promise<'switch' | 'exit'> {
|
||||
const scanner = await createCodexSessionScanner({
|
||||
sessionId: session.sessionId,
|
||||
onSessionFound: (sessionId) => {
|
||||
session.onSessionFound(sessionId);
|
||||
},
|
||||
onEvent: (event) => {
|
||||
const converted = convertCodexEvent(event);
|
||||
if (converted?.sessionId) {
|
||||
session.onSessionFound(converted.sessionId);
|
||||
scanner.onNewSession(converted.sessionId);
|
||||
}
|
||||
if (converted?.message) {
|
||||
session.sendCodexMessage(converted.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let exitReason: 'switch' | 'exit' | null = null;
|
||||
const processAbortController = new AbortController();
|
||||
const exitFuture = new Future<void>();
|
||||
|
||||
try {
|
||||
async function abortProcess() {
|
||||
if (!processAbortController.signal.aborted) {
|
||||
processAbortController.abort();
|
||||
}
|
||||
await exitFuture.promise;
|
||||
}
|
||||
|
||||
async function doAbort() {
|
||||
logger.debug('[codex-local]: doAbort');
|
||||
if (!exitReason) {
|
||||
exitReason = 'switch';
|
||||
}
|
||||
session.queue.reset();
|
||||
await abortProcess();
|
||||
}
|
||||
|
||||
async function doSwitch() {
|
||||
logger.debug('[codex-local]: doSwitch');
|
||||
if (!exitReason) {
|
||||
exitReason = 'switch';
|
||||
}
|
||||
await abortProcess();
|
||||
}
|
||||
|
||||
session.client.rpcHandlerManager.registerHandler('abort', doAbort);
|
||||
session.client.rpcHandlerManager.registerHandler('switch', doSwitch);
|
||||
session.queue.setOnMessage(() => {
|
||||
void doSwitch();
|
||||
});
|
||||
|
||||
if (session.queue.size() > 0) {
|
||||
return 'switch';
|
||||
}
|
||||
|
||||
const handleSessionFound = (sessionId: string) => {
|
||||
session.onSessionFound(sessionId);
|
||||
scanner.onNewSession(sessionId);
|
||||
};
|
||||
|
||||
while (true) {
|
||||
if (exitReason) {
|
||||
return exitReason;
|
||||
}
|
||||
|
||||
logger.debug('[codex-local]: launch');
|
||||
try {
|
||||
await codexLocal({
|
||||
path: session.path,
|
||||
sessionId: session.sessionId,
|
||||
onSessionFound: handleSessionFound,
|
||||
abort: processAbortController.signal
|
||||
});
|
||||
|
||||
if (!exitReason) {
|
||||
exitReason = 'exit';
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
logger.debug('[codex-local]: launch error', error);
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
session.sendSessionEvent({ type: 'message', message: `Local Codex process failed: ${message}` });
|
||||
if (!exitReason) {
|
||||
exitReason = 'switch';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
exitFuture.resolve(undefined);
|
||||
session.client.rpcHandlerManager.registerHandler('abort', async () => {});
|
||||
session.client.rpcHandlerManager.registerHandler('switch', async () => {});
|
||||
session.queue.setOnMessage(null);
|
||||
await scanner.cleanup();
|
||||
}
|
||||
|
||||
return exitReason || 'exit';
|
||||
}
|
||||
Reference in New Issue
Block a user