fix: reviewer auto-trigger now receives owner turn outputs instead of static prompt

This commit is contained in:
Eyejoker
2026-03-31 03:55:45 +09:00
parent efb5710aad
commit 61c9b8c2e9
3 changed files with 36 additions and 20 deletions

View File

@@ -2469,7 +2469,13 @@ export function insertPairedTurnOutput(
): void { ): void {
if (outputText.length > MAX_TURN_OUTPUT_CHARS) { if (outputText.length > MAX_TURN_OUTPUT_CHARS) {
logger.warn( logger.warn(
{ taskId, turnNumber, role, originalLen: outputText.length, maxLen: MAX_TURN_OUTPUT_CHARS }, {
taskId,
turnNumber,
role,
originalLen: outputText.length,
maxLen: MAX_TURN_OUTPUT_CHARS,
},
'Paired turn output truncated — agent output exceeds storage limit', 'Paired turn output truncated — agent output exceeds storage limit',
); );
} }
@@ -2486,9 +2492,7 @@ export function insertPairedTurnOutput(
); );
} }
export function getPairedTurnOutputs( export function getPairedTurnOutputs(taskId: string): PairedTurnOutput[] {
taskId: string,
): PairedTurnOutput[] {
return db return db
.prepare( .prepare(
`SELECT * FROM paired_turn_outputs `SELECT * FROM paired_turn_outputs

View File

@@ -116,6 +116,7 @@ vi.mock('./db.js', () => {
getOpenWorkItem: vi.fn(() => undefined), getOpenWorkItem: vi.fn(() => undefined),
getPendingServiceHandoffs: vi.fn(() => []), getPendingServiceHandoffs: vi.fn(() => []),
getLatestOpenPairedTaskForChat: vi.fn(() => undefined), getLatestOpenPairedTaskForChat: vi.fn(() => undefined),
getPairedTurnOutputs: vi.fn(() => []),
createProducedWorkItem: vi.fn((input) => ({ createProducedWorkItem: vi.fn((input) => ({
id: 1, id: 1,
group_folder: input.group_folder, group_folder: input.group_folder,

View File

@@ -201,8 +201,8 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
const agentMessages = turnOutputsToMessages(turnOutputs, chatJid); const agentMessages = turnOutputsToMessages(turnOutputs, chatJid);
// Merge human + agent messages chronologically // Merge human + agent messages chronologically
const allMessages = [...humanMessages, ...agentMessages].sort( const allMessages = [...humanMessages, ...agentMessages].sort((a, b) =>
(a, b) => a.timestamp.localeCompare(b.timestamp), a.timestamp.localeCompare(b.timestamp),
); );
return formatMessages(allMessages, timezone); return formatMessages(allMessages, timezone);
@@ -651,18 +651,31 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
: null; : null;
const pendingRole = resolveActiveRole(pendingReviewTask?.status); const pendingRole = resolveActiveRole(pendingReviewTask?.status);
if (pendingReviewTask && pendingRole === 'reviewer') { if (pendingReviewTask && pendingRole === 'reviewer') {
// No processable messages remain. Review workspace state using the // Build reviewer prompt from turn outputs (Discord-independent).
// user's request as context, but don't re-inject filtered raw bot // Includes full owner/reviewer conversation history + human messages.
// output from older turns into the next review prompt. const turnOutputs = getPairedTurnOutputs(pendingReviewTask.id);
const userMessage = getLastHumanMessageContent(chatJid); let reviewPrompt: string;
const parts: string[] = []; if (turnOutputs.length > 0) {
if (userMessage) { const humanMsgs = getRecentChatMessages(chatJid, 20).filter(
parts.push(`User request:\n---\n${userMessage}\n---`); (m) => !m.is_bot_message,
);
const allMsgs = [
...humanMsgs,
...turnOutputsToMessages(turnOutputs, chatJid),
].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
reviewPrompt = formatMessages(allMsgs, deps.timezone);
} else {
// Fallback: no turn outputs yet (pre-migration task)
const userMessage = getLastHumanMessageContent(chatJid);
const parts: string[] = [];
if (userMessage) {
parts.push(`User request:\n---\n${userMessage}\n---`);
}
reviewPrompt =
parts.length > 0
? `${parts.join('\n\n')}\n\nReview the latest owner changes in the workspace.`
: 'Review the latest owner changes in the workspace.';
} }
const reviewPrompt =
parts.length > 0
? `${parts.join('\n\n')}\n\nReview the latest owner changes in the workspace.`
: 'Review the latest owner changes in the workspace.';
// Advance reviewer cursor (not owner cursor) so the reviewer // Advance reviewer cursor (not owner cursor) so the reviewer
// still sees the owner's messages on subsequent turns. // still sees the owner's messages on subsequent turns.
@@ -703,9 +716,7 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
); );
} }
const arbiterTurnOutputs = getPairedTurnOutputs( const arbiterTurnOutputs = getPairedTurnOutputs(pendingReviewTask.id);
pendingReviewTask.id,
);
const recentMsgs = getRecentChatMessages(chatJid, 20); const recentMsgs = getRecentChatMessages(chatJid, 20);
const arbiterMessages = const arbiterMessages =
arbiterTurnOutputs.length > 0 arbiterTurnOutputs.length > 0