mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-09 07:05:51 +08:00
Compare commits
2 Commits
v1.33.2
...
fix/codex-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0299beccb9 | ||
|
|
f4a1614a0a |
@@ -455,7 +455,7 @@ async function sandboxCommand(args) {
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
|
||||
console.log(`${c.info('▶')} Launching CloudCLI web server...`);
|
||||
sbx(['exec', opts.name, 'bash', '-c', 'cloudcli start --port 3001 &']);
|
||||
sbx(['exec', opts.name, 'bash', '-c', 'nohup cloudcli start --port 3001 > /tmp/cloudcli-ui.log 2>&1 & disown']);
|
||||
|
||||
console.log(`${c.info('▶')} Forwarding port ${opts.port} → 3001...`);
|
||||
try {
|
||||
@@ -554,7 +554,7 @@ async function sandboxCommand(args) {
|
||||
|
||||
// Step 3: Start CloudCLI inside the sandbox
|
||||
console.log(`${c.info('▶')} Launching CloudCLI web server...`);
|
||||
sbx(['exec', opts.name, 'bash', '-c', 'cloudcli start --port 3001 &']);
|
||||
sbx(['exec', opts.name, 'bash', '-c', 'nohup cloudcli start --port 3001 > /tmp/cloudcli-ui.log 2>&1 & disown']);
|
||||
|
||||
// Step 4: Forward port
|
||||
console.log(`${c.info('▶')} Forwarding port ${opts.port} → 3001...`);
|
||||
|
||||
@@ -279,6 +279,16 @@ export async function queryCodex(command, options = {}, ws) {
|
||||
startedAt: new Date().toISOString()
|
||||
});
|
||||
};
|
||||
const markSessionFinished = (id) => {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const session = activeCodexSessions.get(id);
|
||||
if (session && session.status !== 'aborted') {
|
||||
session.status = 'completed';
|
||||
}
|
||||
};
|
||||
|
||||
// Existing sessions can be tracked immediately; new sessions are tracked after thread.started.
|
||||
if (capturedSessionId) {
|
||||
@@ -324,6 +334,10 @@ export async function queryCodex(command, options = {}, ws) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event.type === 'turn.completed' || event.type === 'turn.failed') {
|
||||
markSessionFinished(capturedSessionId || sessionId);
|
||||
}
|
||||
|
||||
const transformed = transformCodexEvent(event);
|
||||
|
||||
// Normalize the transformed event into NormalizedMessage(s) via adapter
|
||||
@@ -354,6 +368,8 @@ export async function queryCodex(command, options = {}, ws) {
|
||||
|
||||
// Send completion event
|
||||
if (!terminalFailure) {
|
||||
markSessionFinished(capturedSessionId || sessionId);
|
||||
|
||||
sendMessage(ws, createNormalizedMessage({
|
||||
kind: 'complete',
|
||||
actualSessionId: capturedSessionId || thread.id || sessionId || null,
|
||||
|
||||
@@ -98,6 +98,7 @@ export function useChatRealtimeHandlers({
|
||||
}: UseChatRealtimeHandlersArgs) {
|
||||
const paletteOps = usePaletteOps();
|
||||
const lastProcessedMessageRef = useRef<LatestChatMessage | null>(null);
|
||||
const terminalSessionIdsRef = useRef<Set<string>>(new Set());
|
||||
|
||||
useEffect(() => {
|
||||
if (!latestMessage) return;
|
||||
@@ -151,6 +152,17 @@ export function useChatRealtimeHandlers({
|
||||
const isCurrentSession =
|
||||
statusSessionId === currentSessionId || (selectedSession && statusSessionId === selectedSession.id);
|
||||
|
||||
if (msg.isProcessing && terminalSessionIdsRef.current.has(statusSessionId)) {
|
||||
onSessionInactive?.(statusSessionId);
|
||||
onSessionNotProcessing?.(statusSessionId);
|
||||
if (isCurrentSession) {
|
||||
setIsLoading(false);
|
||||
setCanAbortSession(false);
|
||||
setClaudeStatus(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.isProcessing) {
|
||||
onSessionActive?.(statusSessionId);
|
||||
onSessionProcessing?.(statusSessionId);
|
||||
@@ -180,6 +192,10 @@ export function useChatRealtimeHandlers({
|
||||
|
||||
const sid = msg.sessionId || activeViewSessionId;
|
||||
|
||||
if (sid && msg.kind === 'session_created') {
|
||||
terminalSessionIdsRef.current.delete(sid);
|
||||
}
|
||||
|
||||
// --- Streaming: buffer for performance ---
|
||||
if (msg.kind === 'stream_delta') {
|
||||
const text = msg.content || '';
|
||||
@@ -258,6 +274,10 @@ export function useChatRealtimeHandlers({
|
||||
}
|
||||
|
||||
case 'complete': {
|
||||
if (sid) {
|
||||
terminalSessionIdsRef.current.add(sid);
|
||||
}
|
||||
|
||||
// Flush any remaining streaming state
|
||||
if (streamTimerRef.current) {
|
||||
clearTimeout(streamTimerRef.current);
|
||||
@@ -313,6 +333,10 @@ export function useChatRealtimeHandlers({
|
||||
}
|
||||
|
||||
case 'error': {
|
||||
if (sid) {
|
||||
terminalSessionIdsRef.current.add(sid);
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
setCanAbortSession(false);
|
||||
setClaudeStatus(null);
|
||||
|
||||
@@ -131,6 +131,8 @@ export function useChatSessionState({
|
||||
const pendingInitialScrollRef = useRef(true);
|
||||
const messagesOffsetRef = useRef(0);
|
||||
const scrollPositionRef = useRef({ height: 0, top: 0 });
|
||||
const previousProcessingSessionsRef = useRef<Set<string> | null>(null);
|
||||
const previousProcessingSessionViewIdRef = useRef<string | null>(null);
|
||||
const loadAllFinishedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const loadAllOverlayTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const lastLoadedSessionKeyRef = useRef<string | null>(null);
|
||||
@@ -693,9 +695,17 @@ export function useChatSessionState({
|
||||
|
||||
useEffect(() => {
|
||||
const activeViewSessionId = selectedSession?.id || currentSessionId;
|
||||
const previousProcessingSessions = previousProcessingSessionsRef.current;
|
||||
const previousProcessingSessionViewId = previousProcessingSessionViewIdRef.current;
|
||||
previousProcessingSessionsRef.current = processingSessions ?? null;
|
||||
previousProcessingSessionViewIdRef.current = activeViewSessionId ?? null;
|
||||
|
||||
if (!activeViewSessionId || !processingSessions) return;
|
||||
|
||||
const activeViewSessionChanged = previousProcessingSessionViewId !== activeViewSessionId;
|
||||
const wasProcessing = previousProcessingSessions?.has(activeViewSessionId) ?? false;
|
||||
const shouldBeProcessing = processingSessions.has(activeViewSessionId);
|
||||
if (shouldBeProcessing && !isLoading) {
|
||||
if (shouldBeProcessing && (!wasProcessing || activeViewSessionChanged) && !isLoading) {
|
||||
setIsLoading(true);
|
||||
setCanAbortSession(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user