fix: arbiter session collision — separate session folder + always fresh session

- resolveSessionFolder now always returns unique folder for arbiter
  (prevents sharing session with owner when both use same agent type)
- Arbiter sessionId forced to undefined to prevent resume attempts
This commit is contained in:
Eyejoker
2026-03-31 04:26:48 +09:00
parent 56c85c357a
commit 60408cc1fa
3 changed files with 18 additions and 1 deletions

View File

@@ -1137,6 +1137,18 @@ export function getLastHumanMessageTimestamp(chatJid: string): string | null {
return row?.timestamp ?? null; return row?.timestamp ?? null;
} }
export function getLastHumanMessageSender(chatJid: string): string | null {
const row = db
.prepare(
`SELECT sender FROM messages
WHERE chat_jid = ? AND is_bot_message = 0 AND is_from_me = 0
AND content != '' AND content IS NOT NULL
ORDER BY timestamp DESC, seq DESC LIMIT 1`,
)
.get(chatJid) as { sender: string } | undefined;
return row?.sender ?? null;
}
export function getLastHumanMessageContent(chatJid: string): string | null { export function getLastHumanMessageContent(chatJid: string): string | null {
const row = db const row = db
.prepare( .prepare(

View File

@@ -14,8 +14,10 @@ import { listAvailableGroups } from './available-groups.js';
import { import {
createServiceHandoff, createServiceHandoff,
getAllTasks, getAllTasks,
getLastHumanMessageSender,
getLatestOpenPairedTaskForChat, getLatestOpenPairedTaskForChat,
getLatestTurnNumber, getLatestTurnNumber,
getPairedTaskById,
insertPairedTurnOutput, insertPairedTurnOutput,
} from './db.js'; } from './db.js';
import { GroupQueue } from './group-queue.js'; import { GroupQueue } from './group-queue.js';
@@ -128,7 +130,8 @@ export async function runAgentForGroup(
activeRole, activeRole,
group.agentType, group.agentType,
); );
const sessionId = sessions[sessionFolder]; // Arbiter always starts fresh — never resume a previous session
const sessionId = activeRole === 'arbiter' ? undefined : sessions[sessionFolder];
const memoryBriefing = sessionId const memoryBriefing = sessionId
? undefined ? undefined
: await buildRoomMemoryBriefing({ : await buildRoomMemoryBriefing({

View File

@@ -89,6 +89,8 @@ export function resolveSessionFolder(
role: 'owner' | 'reviewer' | 'arbiter', role: 'owner' | 'reviewer' | 'arbiter',
groupAgentType: AgentType | undefined, groupAgentType: AgentType | undefined,
): string { ): string {
// Arbiter always gets a separate session — must never share with owner/reviewer
if (role === 'arbiter') return `${groupFolder}:arbiter`;
const effectiveType = resolveEffectiveAgentType(role, groupAgentType); const effectiveType = resolveEffectiveAgentType(role, groupAgentType);
const groupDefault: AgentType = groupAgentType || 'claude-code'; const groupDefault: AgentType = groupAgentType || 'claude-code';
if (effectiveType === groupDefault) return groupFolder; if (effectiveType === groupDefault) return groupFolder;