diff --git a/external.ts b/external.ts index 9a4d88a..052b4ee 100644 --- a/external.ts +++ b/external.ts @@ -273,6 +273,13 @@ export interface WriteablePayload { triggerer?: string | undefined; /** event-level instructions for this trigger type (flag-expanded server-side) */ eventInstructions?: string | undefined; + /** + * system-injected note about prior superseded runs (e.g. when the + * triggering @pullfrog comment is edited). rendered alongside the user's + * prompt rather than via eventInstructions so it survives user-prompt + * precedence. + */ + previousRunsNote?: string | undefined; /** event data from webhook payload - discriminated union based on trigger field */ event: PayloadEvent; /** timeout for agent run (e.g., "10m", "1h30m") - defaults to "1h" */ diff --git a/utils/instructions.ts b/utils/instructions.ts index 3f14d42..07a48fc 100644 --- a/utils/instructions.ts +++ b/utils/instructions.ts @@ -32,6 +32,7 @@ function buildRuntimeContext(ctx: InstructionsContext): string { "~pullfrog": _, prompt: _p, eventInstructions: _ei, + previousRunsNote: _prn, event: _e, ...payloadRest } = ctx.payload; @@ -146,17 +147,23 @@ In case of conflict between instructions, follow this precedence (highest to low // section builders // --------------------------------------------------------------------------- -// the user's task: blockquoted user prompt, or event-level instructions for auto-triggers +// the user's task: blockquoted user prompt, or event-level instructions for auto-triggers. +// `previousRunsNote` is system-injected context (e.g. prior runs superseded by a +// comment edit); it's appended regardless of which branch wins so it survives +// user-prompt precedence over eventInstructions. function buildTaskSection(ctx: PromptContext): string { + const previousRunsNote = ctx.payload.previousRunsNote?.trim() ?? ""; + if (ctx.userQuoted) { + const parts = [ctx.userQuoted, previousRunsNote].filter(Boolean); return `************* YOUR TASK ************* -${ctx.userQuoted}`; +${parts.join("\n\n")}`; } const eventInstructions = ctx.payload.eventInstructions ?? ""; - if (eventInstructions) { - const parts = [ctx.eventTitle, eventInstructions].filter(Boolean); + if (eventInstructions || previousRunsNote) { + const parts = [ctx.eventTitle, eventInstructions, previousRunsNote].filter(Boolean); return `************* YOUR TASK ************* ${parts.join("\n\n")}`; diff --git a/utils/payload.ts b/utils/payload.ts index fd526ae..13003a9 100644 --- a/utils/payload.ts +++ b/utils/payload.ts @@ -21,6 +21,7 @@ export const JsonPayload = type({ "triggerer?": "string | undefined", "eventInstructions?": "string", + "previousRunsNote?": "string", "event?": "object", "timeout?": "string | undefined", "progressComment?": type({ @@ -157,6 +158,7 @@ export function resolvePayload( // it's not a common use case but GITHUB_ACTOR can be a user when the workflow is manually triggered by a user through GitHub Actions UI (!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : undefined), eventInstructions: jsonPayload?.eventInstructions, + previousRunsNote: jsonPayload?.previousRunsNote, event, timeout: inputs.timeout ?? jsonPayload?.timeout, cwd: resolveCwd(inputs.cwd),