Merge pull request #159 from phj1081/codex/owner/ejclaw
fix: limit arbiter context to recent outputs
This commit is contained in:
@@ -111,7 +111,9 @@ describe('message-runtime-prompts carry-forward guidance', () => {
|
|||||||
'Do not repeat, continue, or answer that carried-forward final directly.',
|
'Do not repeat, continue, or answer that carried-forward final directly.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('message-runtime-prompts output-only context', () => {
|
||||||
it('keeps reviewer pending prompts output-only when current task outputs exist', () => {
|
it('keeps reviewer pending prompts output-only when current task outputs exist', () => {
|
||||||
const prompt = buildReviewerPendingPrompt({
|
const prompt = buildReviewerPendingPrompt({
|
||||||
chatJid: 'group@test',
|
chatJid: 'group@test',
|
||||||
@@ -196,6 +198,34 @@ describe('message-runtime-prompts carry-forward guidance', () => {
|
|||||||
expect(prompt).not.toContain('예전 유저 지시');
|
expect(prompt).not.toContain('예전 유저 지시');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('limits arbiter prompts to recent turn outputs', () => {
|
||||||
|
const prompt = buildArbiterPromptForTask({
|
||||||
|
task: makeTask({ status: 'arbiter_requested' }),
|
||||||
|
chatJid: 'group@test',
|
||||||
|
timezone: 'UTC',
|
||||||
|
turnOutputs: Array.from({ length: 8 }, (_, index) => {
|
||||||
|
const turnNumber = index + 1;
|
||||||
|
return makeTurnOutput(
|
||||||
|
`arbiter-context-output-${String(turnNumber).padStart(2, '0')}`,
|
||||||
|
turnNumber % 2 === 0 ? 'reviewer' : 'owner',
|
||||||
|
{
|
||||||
|
id: turnNumber,
|
||||||
|
turn_number: turnNumber,
|
||||||
|
created_at: `2026-04-20T02:${String(turnNumber).padStart(2, '0')}:00.000Z`,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
recentMessages: [makeHumanMessage('예전 유저 지시')],
|
||||||
|
labeledRecentMessages: [makeHumanMessage('예전 유저 지시')],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(prompt).not.toContain('arbiter-context-output-01');
|
||||||
|
expect(prompt).not.toContain('arbiter-context-output-02');
|
||||||
|
expect(prompt).toContain('arbiter-context-output-03');
|
||||||
|
expect(prompt).toContain('arbiter-context-output-08');
|
||||||
|
expect(prompt).not.toContain('예전 유저 지시');
|
||||||
|
});
|
||||||
|
|
||||||
it('preserves turn output order instead of timestamp interleaving', () => {
|
it('preserves turn output order instead of timestamp interleaving', () => {
|
||||||
const prompt = buildReviewerPendingPrompt({
|
const prompt = buildReviewerPendingPrompt({
|
||||||
chatJid: 'group@test',
|
chatJid: 'group@test',
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ const CARRIED_FORWARD_OWNER_FINAL_MARKER =
|
|||||||
const CARRIED_FORWARD_OWNER_FINAL_GUIDANCE = `System note:
|
const CARRIED_FORWARD_OWNER_FINAL_GUIDANCE = `System note:
|
||||||
If you see a message beginning with "${CARRIED_FORWARD_OWNER_FINAL_MARKER}", treat it as background only. Do not repeat, continue, or answer that carried-forward final directly. Respond only to the latest human request and the current task.`;
|
If you see a message beginning with "${CARRIED_FORWARD_OWNER_FINAL_MARKER}", treat it as background only. Do not repeat, continue, or answer that carried-forward final directly. Respond only to the latest human request and the current task.`;
|
||||||
|
|
||||||
|
const ARBITER_TURN_OUTPUT_CONTEXT_LIMIT = 6;
|
||||||
|
|
||||||
function turnOutputsToMessages(
|
function turnOutputsToMessages(
|
||||||
outputs: PairedTurnOutput[],
|
outputs: PairedTurnOutput[],
|
||||||
chatJid: string,
|
chatJid: string,
|
||||||
@@ -35,6 +37,16 @@ function mergeHumanAndTurnOutputMessages(
|
|||||||
].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function latestTurnOutputs(
|
||||||
|
outputs: PairedTurnOutput[],
|
||||||
|
limit: number,
|
||||||
|
): PairedTurnOutput[] {
|
||||||
|
if (outputs.length <= limit) {
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
return outputs.slice(-limit);
|
||||||
|
}
|
||||||
|
|
||||||
function hasCarriedForwardOwnerFinal(outputs: PairedTurnOutput[]): boolean {
|
function hasCarriedForwardOwnerFinal(outputs: PairedTurnOutput[]): boolean {
|
||||||
return outputs.some((output) =>
|
return outputs.some((output) =>
|
||||||
output.output_text.startsWith(CARRIED_FORWARD_OWNER_FINAL_MARKER),
|
output.output_text.startsWith(CARRIED_FORWARD_OWNER_FINAL_MARKER),
|
||||||
@@ -136,7 +148,13 @@ export function buildArbiterPromptForTask(args: {
|
|||||||
}): string {
|
}): string {
|
||||||
const messages =
|
const messages =
|
||||||
args.turnOutputs.length > 0
|
args.turnOutputs.length > 0
|
||||||
? turnOutputsToMessages(args.turnOutputs, args.chatJid)
|
? turnOutputsToMessages(
|
||||||
|
latestTurnOutputs(
|
||||||
|
args.turnOutputs,
|
||||||
|
ARBITER_TURN_OUTPUT_CONTEXT_LIMIT,
|
||||||
|
),
|
||||||
|
args.chatJid,
|
||||||
|
)
|
||||||
: args.labeledRecentMessages;
|
: args.labeledRecentMessages;
|
||||||
|
|
||||||
return buildArbiterContextPrompt({
|
return buildArbiterContextPrompt({
|
||||||
|
|||||||
Reference in New Issue
Block a user