Complete paired-room SSOT cleanup and logger singleton

This commit is contained in:
ejclaw
2026-04-07 05:12:22 +09:00
parent ae12b157be
commit 10e10b499c
18 changed files with 648 additions and 473 deletions

View File

@@ -6,9 +6,11 @@ import { getErrorMessage } from './utils.js';
import { getAgentOutputText } from './agent-output.js';
import { createEvaluatedOutputHandler } from './agent-attempt.js';
import {
isRetryableClaudeSessionFailureAttempt,
resolveAttemptRetryAction,
} from './agent-attempt-retry.js';
executeAttemptRetryAction,
runClaudeAttemptWithRotation,
runCodexAttemptWithRotation,
} from './agent-attempt-orchestration.js';
import { isRetryableClaudeSessionFailureAttempt } from './agent-attempt-retry.js';
import {
AgentOutput,
runAgentProcess,
@@ -37,10 +39,6 @@ import { resolveExecutionTarget } from './message-runtime-rules.js';
import { resolvePairedFollowUpQueueAction } from './message-agent-executor-rules.js';
import { buildRoomRoleContext } from './room-role-context.js';
import { type AgentTriggerReason } from './agent-error-detection.js';
import {
runClaudeRotationLoop,
runCodexRotationLoop,
} from './provider-retry.js';
import {
shouldResetSessionOnAgentFailure,
shouldRetryFreshSessionOnAgentFailure,
@@ -649,27 +647,17 @@ export async function runAgentForGroup(
initialTrigger: { reason: CodexRotationReason },
rotationMessage?: string,
): Promise<'success' | 'error'> => {
const outcome = await runCodexRotationLoop(
return runCodexAttemptWithRotation({
initialTrigger,
async () => {
const attempt = await runAttempt('codex');
return {
output: attempt.output,
thrownError: attempt.error,
sawOutput: attempt.sawOutput,
streamedTriggerReason: attempt.streamedTriggerReason,
};
},
{
runAttempt: () => runAttempt('codex'),
logContext: {
chatJid,
group: group.name,
groupFolder: group.folder,
runId,
},
rotationMessage,
);
return outcome.type === 'success' ? 'success' : 'error';
});
};
type AgentAttempt = Awaited<ReturnType<typeof runAttempt>>;
@@ -688,81 +676,63 @@ export async function runAgentForGroup(
runId,
};
const outcome = await runClaudeRotationLoop(
return runClaudeAttemptWithRotation({
initialTrigger,
async () => {
const attempt = await runAttempt('claude');
return {
output: attempt.output,
thrownError: attempt.error,
sawOutput: attempt.sawOutput,
sawSuccessNullResult: attempt.sawSuccessNullResultWithoutOutput,
streamedTriggerReason: attempt.streamedTriggerReason,
};
},
logCtx,
runAttempt: () => runAttempt('claude'),
logContext: logCtx,
rotationMessage,
);
switch (outcome.type) {
case 'success':
pairedSawOutput = outcome.sawOutput;
return 'success';
case 'error':
return 'error';
}
onSuccess: ({ sawOutput }) => {
pairedSawOutput = sawOutput;
},
});
};
const retryClaudeAttemptIfNeeded = async (
attempt: AgentAttempt,
rotationMessage?: string | null,
): Promise<'success' | 'error' | null> => {
const retryAction = resolveAttemptRetryAction({
const retryAction = await executeAttemptRetryAction({
provider,
canRetryClaudeCredentials,
canRetryCodex: false,
attempt,
rotationMessage,
runClaude: retryClaudeWithRotation,
runCodex: retryCodexWithRotation,
});
if (retryAction.kind !== 'claude') {
return null;
}
const result = await retryClaudeWithRotation(
retryAction.trigger,
retryAction.rotationMessage,
);
if (result === 'error') {
if (retryAction.result === 'error') {
return maybeHandoffAfterError(retryAction.trigger.reason, attempt);
}
pairedExecutionStatus = 'succeeded';
return result;
return retryAction.result;
};
const retryCodexAttemptIfNeeded = async (
attempt: AgentAttempt,
rotationMessage?: string | null,
): Promise<'success' | 'error' | null> => {
const retryAction = resolveAttemptRetryAction({
const retryAction = await executeAttemptRetryAction({
provider,
canRetryClaudeCredentials: false,
canRetryCodex: !isClaudeCodeAgent && getCodexAccountCount() > 1,
attempt,
rotationMessage,
runClaude: retryClaudeWithRotation,
runCodex: retryCodexWithRotation,
});
if (retryAction.kind !== 'codex') {
return null;
}
const result = await retryCodexWithRotation(
retryAction.trigger,
retryAction.rotationMessage,
);
if (result === 'success') {
if (retryAction.result === 'success') {
pairedExecutionStatus = 'succeeded';
}
return result;
return retryAction.result;
};
const maybeHandoffAfterError = (