feat: unify 3 bot services into single process

- Add UNIFIED_MODE flag (default on, disable with UNIFIED_MODE=0)
- Register all 3 Discord bots in one process (claude, codex, review)
- Load all registered groups regardless of agent_type (codex/owner priority)
- Start credential proxy and container cleanup at unified startup
- shouldServiceProcessChat returns true in unified mode
- Add findChannelByName for role-based response routing
- Backward compatible: UNIFIED_MODE=0 restores per-service behavior
This commit is contained in:
Eyejoker
2026-03-29 18:22:57 +09:00
parent fc9f2867b9
commit d01f98bd61
20 changed files with 118 additions and 759 deletions

View File

@@ -918,57 +918,6 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
}
}
const lease = getEffectiveChannelLease(chatJid);
const roomRoleContext = buildRoomRoleContext(lease, SERVICE_ID);
const recoveryPlan = planPairedExecutionRecovery({
group,
chatJid,
roomRoleContext,
});
if (!recoveryPlan) {
continue;
}
deps.queue.enqueueTask(chatJid, recoveryPlan.recoveryKey, async () => {
const recoveryChannel = findChannel(deps.channels, chatJid);
if (!recoveryChannel) {
logger.warn(
{
chatJid,
taskId: recoveryPlan.task.id,
role: recoveryPlan.role,
recoveryKey: recoveryPlan.recoveryKey,
},
'Skipping paired execution recovery because no channel owns the chat',
);
return;
}
const runId = `recovery-${Date.now().toString(36)}-${Math.random()
.toString(36)
.slice(2, 8)}`;
logger.info(
{
chatJid,
group: group.name,
taskId: recoveryPlan.task.id,
role: recoveryPlan.role,
checkpointFingerprint: recoveryPlan.checkpointFingerprint,
recoveryKey: recoveryPlan.recoveryKey,
runId,
},
'Recovery: resuming paired execution after restart',
);
await executeTurn({
group,
prompt: recoveryPlan.prompt,
chatJid,
runId,
channel: recoveryChannel,
startSeq: null,
endSeq: null,
});
});
}
};