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

@@ -3,7 +3,11 @@ import { CronExpressionParser } from 'cron-parser';
import fs from 'fs';
import { getAgentOutputText } from './agent-output.js';
import { createEvaluatedOutputHandler } from './agent-attempt.js';
import { resolveAttemptRetryAction } from './agent-attempt-retry.js';
import {
executeAttemptRetryAction,
runClaudeAttemptWithRotation,
runCodexAttemptWithRotation,
} from './agent-attempt-orchestration.js';
import { getErrorMessage } from './utils.js';
import { ASSISTANT_NAME, SCHEDULER_POLL_INTERVAL, TIMEZONE } from './config.js';
@@ -29,10 +33,6 @@ import {
} from './group-folder.js';
import { createScopedLogger, logger } from './logger.js';
import { createTaskStatusTracker } from './task-status-tracker.js';
import {
runClaudeRotationLoop,
runCodexRotationLoop,
} from './provider-retry.js';
import {
detectCodexRotationTrigger,
rotateCodexToken,
@@ -447,69 +447,53 @@ async function runTask(
retryAfterMs?: number;
},
rotationMessage?: string,
): Promise<void> => {
const logCtx = {
): Promise<'success' | 'error'> => {
const logContext = {
taskId: task.id,
group: context.group.name,
groupFolder: task.group_folder,
};
const outcome = await runClaudeRotationLoop(
const outcome = await runClaudeAttemptWithRotation({
initialTrigger,
async () => {
const attempt = await runTaskAttempt('claude');
runAttempt: () => runTaskAttempt('claude'),
logContext,
rotationMessage,
afterAttempt: (attempt) => {
result = attempt.attemptResult;
error = attempt.attemptError;
return {
output: attempt.output,
sawOutput: attempt.sawOutput,
streamedTriggerReason: attempt.streamedTriggerReason,
};
},
logCtx,
rotationMessage,
);
});
switch (outcome.type) {
case 'success':
error = null;
return;
case 'error':
if (outcome.trigger) {
error = `Claude ${outcome.trigger.reason}`;
}
return;
if (outcome === 'success') {
error = null;
}
return outcome;
};
const retryCodexTaskWithRotation = async (
initialTrigger: { reason: CodexRotationReason },
rotationMessage?: string,
): Promise<void> => {
const outcome = await runCodexRotationLoop(
): Promise<'success' | 'error'> => {
const outcome = await runCodexAttemptWithRotation({
initialTrigger,
async () => {
const retryAttempt = await runTaskAttempt('codex');
result = retryAttempt.attemptResult;
error = retryAttempt.attemptError;
return {
output: retryAttempt.output,
thrownError: null,
sawOutput: retryAttempt.sawOutput,
streamedTriggerReason: retryAttempt.streamedTriggerReason,
};
},
{
runAttempt: () => runTaskAttempt('codex'),
logContext: {
taskId: task.id,
group: context.group.name,
groupFolder: task.group_folder,
},
rotationMessage,
);
afterAttempt: (attempt) => {
result = attempt.attemptResult;
error = attempt.attemptError;
},
});
if (outcome.type === 'success') {
if (outcome === 'success') {
error = null;
}
return outcome;
};
const provider = context.taskAgentType === 'codex' ? 'codex' : 'claude';
@@ -519,25 +503,17 @@ async function runTask(
result = attempt.attemptResult;
error = attempt.attemptError;
const retryAction = resolveAttemptRetryAction({
const retryAction = await executeAttemptRetryAction({
provider,
canRetryClaudeCredentials: provider === 'claude' && getTokenCount() > 0,
canRetryCodex: provider === 'codex' && getCodexAccountCount() > 1,
attempt,
rotationMessage: error,
runClaude: retryClaudeTaskWithRotation,
runCodex: retryCodexTaskWithRotation,
});
if (retryAction.kind === 'claude') {
await retryClaudeTaskWithRotation(
retryAction.trigger,
retryAction.rotationMessage,
);
} else if (retryAction.kind === 'codex') {
await retryCodexTaskWithRotation(
retryAction.trigger,
retryAction.rotationMessage,
);
} else if (attempt.output.status === 'error') {
if (retryAction.kind === 'none' && attempt.output.status === 'error') {
error = attempt.attemptError || 'Unknown error';
}
} // end else (non-exhausted path)