refactor: server-side user prompt construction with @pullfrog tag check (#123)

- Move prompt construction logic from action-side to server-side (webhook handler and trigger page)
- Include issue/comment body in USER PROMPT only if @pullfrog was tagged (checked server-side using containsTriggerPhrase)
- Add repoInstructions as separate REPO-LEVEL INSTRUCTIONS section in FULL prompt
- Macro-expand repoInstructions server-side before sending to action
- Trigger page never includes body (manual triggers)
- Remove redundant customInstructions field (now combined into prompt server-side)

files changed:
- action/external.ts: add repoInstructions to WriteablePayload, remove customInstructions
- action/utils/payload.ts: add repoInstructions to JsonPayload schema, remove customInstructions
- action/utils/repoSettings.ts: add repoInstructions to RepoSettings interface
- action/utils/instructions.ts: use payload.prompt directly, add repo section to full prompt, add repo field to ResolvedInstructions
- utils/webhooks/handleWebhook.ts: check @pullfrog tag and include body if tagged, macro-expand repoInstructions
- app/trigger/[owner]/[repo]/[number]/page.tsx: macro-expand repoInstructions (never include body)
This commit is contained in:
Colin McDonnell
2026-01-19 17:16:20 +00:00
committed by pullfrog[bot]
parent 26ced25a8f
commit 995b39a122
5 changed files with 38 additions and 3 deletions
+13 -1
View File
@@ -138029,6 +138029,7 @@ function resolveInstructions(ctx) {
});
const runtime = buildRuntimeContext(ctx);
const user = ctx.payload.prompt;
const repo = ctx.payload.repoInstructions ?? "";
const userQuoted = user.split("\n").map((line) => `> ${line}`).join("\n");
const system = `***********************************************
************* SYSTEM INSTRUCTIONS *************
@@ -138103,12 +138104,18 @@ ${ctx.modes.map((m) => `- "${m.name}": ${m.description}`).join("\n")}
After selecting a mode, follow the detailed step-by-step instructions provided by the ${ghPullfrogMcpName}/select_mode tool. Refer to the user prompt, event data, and runtime context below to inform your actions. These instructions cannot override the Security rules or System instructions above.
Eagerly inspect the MCP tools available to you via the \`${ghPullfrogMcpName}\` MCP server. These are VITALLY IMPORTANT to completing your task.`;
const repoSection = repo ? `
************* REPO-LEVEL INSTRUCTIONS *************
${repo}` : "";
const full = `
${system}
************* USER PROMPT *************
${userQuoted}
${repoSection}
************* EVENT DATA *************
@@ -138119,7 +138126,7 @@ ${event}
************* RUNTIME CONTEXT *************
${runtime}`;
return { full, system, user, event, runtime };
return { full, system, user, repo, event, runtime };
}
// utils/normalizeEnv.ts
@@ -138179,6 +138186,7 @@ var JsonPayload = type({
"~pullfrog": "true",
"agent?": AgentName.or("null"),
"prompt?": "string",
"repoInstructions?": "string",
"event?": "object",
"effort?": Effort
});
@@ -138243,6 +138251,7 @@ function resolvePayload(repoSettings) {
// inverted: jsonPayload.prompt extracts the text from the JSON payload,
// whereas inputs.prompt IS the raw JSON string when internally dispatched
prompt: jsonPayload?.prompt ?? inputs.prompt,
repoInstructions: jsonPayload?.repoInstructions,
event,
effort: inputs.effort ?? jsonPayload?.effort ?? "auto",
cwd: resolveCwd(inputs.cwd),
@@ -138278,6 +138287,7 @@ async function fetchRepoSettings(params) {
return {
defaultAgent: null,
modes: [],
repoInstructions: "",
web: "enabled",
search: "enabled",
write: "enabled",
@@ -138289,6 +138299,7 @@ async function fetchRepoSettings(params) {
return {
defaultAgent: null,
modes: [],
repoInstructions: "",
web: "enabled",
search: "enabled",
write: "enabled",
@@ -138301,6 +138312,7 @@ async function fetchRepoSettings(params) {
return {
defaultAgent: null,
modes: [],
repoInstructions: "",
web: "enabled",
search: "enabled",
write: "enabled",