Simplify paired turn routing and prompt builders
This commit is contained in:
141
src/message-runtime-prompts.ts
Normal file
141
src/message-runtime-prompts.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import { buildArbiterContextPrompt } from './arbiter-context.js';
|
||||
import { formatMessages } from './router.js';
|
||||
import type { NewMessage, PairedTask, PairedTurnOutput } from './types.js';
|
||||
|
||||
function turnOutputsToMessages(
|
||||
outputs: PairedTurnOutput[],
|
||||
chatJid: string,
|
||||
): NewMessage[] {
|
||||
return outputs.map((turnOutput) => ({
|
||||
id: `turn-${turnOutput.task_id}-${turnOutput.turn_number}`,
|
||||
chat_jid: chatJid,
|
||||
sender: turnOutput.role,
|
||||
sender_name: turnOutput.role,
|
||||
content: turnOutput.output_text,
|
||||
timestamp: turnOutput.created_at,
|
||||
is_bot_message: true as const,
|
||||
is_from_me: false as const,
|
||||
}));
|
||||
}
|
||||
|
||||
function mergeHumanAndTurnOutputMessages(
|
||||
chatJid: string,
|
||||
humanMessages: NewMessage[],
|
||||
turnOutputs: PairedTurnOutput[],
|
||||
): NewMessage[] {
|
||||
return [...humanMessages, ...turnOutputsToMessages(turnOutputs, chatJid)].sort(
|
||||
(a, b) => a.timestamp.localeCompare(b.timestamp),
|
||||
);
|
||||
}
|
||||
|
||||
export function buildPairedTurnPrompt(args: {
|
||||
taskId: string;
|
||||
chatJid: string;
|
||||
timezone: string;
|
||||
missedMessages: NewMessage[];
|
||||
labeledFallbackMessages: NewMessage[];
|
||||
turnOutputs: PairedTurnOutput[];
|
||||
}): string {
|
||||
if (args.turnOutputs.length === 0) {
|
||||
return formatMessages(args.labeledFallbackMessages, args.timezone);
|
||||
}
|
||||
|
||||
const humanMessages = args.missedMessages.filter((message) => !message.is_bot_message);
|
||||
return formatMessages(
|
||||
mergeHumanAndTurnOutputMessages(
|
||||
args.chatJid,
|
||||
humanMessages,
|
||||
args.turnOutputs,
|
||||
),
|
||||
args.timezone,
|
||||
);
|
||||
}
|
||||
|
||||
export function buildReviewerPendingPrompt(args: {
|
||||
chatJid: string;
|
||||
timezone: string;
|
||||
turnOutputs: PairedTurnOutput[];
|
||||
recentHumanMessages: NewMessage[];
|
||||
lastHumanMessage: string | null | undefined;
|
||||
}): string {
|
||||
if (args.turnOutputs.length > 0) {
|
||||
return formatMessages(
|
||||
mergeHumanAndTurnOutputMessages(
|
||||
args.chatJid,
|
||||
args.recentHumanMessages,
|
||||
args.turnOutputs,
|
||||
),
|
||||
args.timezone,
|
||||
);
|
||||
}
|
||||
|
||||
if (!args.lastHumanMessage) {
|
||||
return 'Review the latest owner changes in the workspace.';
|
||||
}
|
||||
|
||||
return `User request:\n---\n${args.lastHumanMessage}\n---\n\nReview the latest owner changes in the workspace.`;
|
||||
}
|
||||
|
||||
export function buildOwnerPendingPrompt(args: {
|
||||
chatJid: string;
|
||||
timezone: string;
|
||||
turnOutputs: PairedTurnOutput[];
|
||||
recentHumanMessages: NewMessage[];
|
||||
lastHumanMessage: string | null | undefined;
|
||||
}): string {
|
||||
if (args.turnOutputs.length > 0) {
|
||||
return formatMessages(
|
||||
mergeHumanAndTurnOutputMessages(
|
||||
args.chatJid,
|
||||
args.recentHumanMessages,
|
||||
args.turnOutputs,
|
||||
),
|
||||
args.timezone,
|
||||
);
|
||||
}
|
||||
|
||||
if (!args.lastHumanMessage) {
|
||||
return 'Continue the owner turn using the latest reviewer or arbiter feedback.';
|
||||
}
|
||||
|
||||
return `User request:\n---\n${args.lastHumanMessage}\n---\n\nContinue the owner turn using the latest reviewer or arbiter feedback.`;
|
||||
}
|
||||
|
||||
export function buildArbiterPromptForTask(args: {
|
||||
task: PairedTask;
|
||||
chatJid: string;
|
||||
timezone: string;
|
||||
turnOutputs: PairedTurnOutput[];
|
||||
recentMessages: NewMessage[];
|
||||
labeledRecentMessages: NewMessage[];
|
||||
}): string {
|
||||
const messages =
|
||||
args.turnOutputs.length > 0
|
||||
? mergeHumanAndTurnOutputMessages(
|
||||
args.chatJid,
|
||||
args.recentMessages.filter((message) => !message.is_bot_message),
|
||||
args.turnOutputs,
|
||||
)
|
||||
: args.labeledRecentMessages;
|
||||
|
||||
return buildArbiterContextPrompt({
|
||||
chatJid: args.chatJid,
|
||||
taskId: args.task.id,
|
||||
roundTripCount: args.task.round_trip_count,
|
||||
timezone: args.timezone,
|
||||
messages,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildFinalizePendingPrompt(args: {
|
||||
turnOutputs: PairedTurnOutput[];
|
||||
}): string {
|
||||
const lastReviewerOutput = [...args.turnOutputs]
|
||||
.reverse()
|
||||
.find((output) => output.role === 'reviewer');
|
||||
const reviewerSummary = lastReviewerOutput?.output_text
|
||||
? `\n\nReviewer's final assessment:\n${lastReviewerOutput.output_text.slice(0, 2000)}`
|
||||
: '';
|
||||
|
||||
return `The reviewer approved your work (DONE). Finalize and report the result.${reviewerSummary}`;
|
||||
}
|
||||
Reference in New Issue
Block a user