Make prompt construction more disciplined (#173)
* Make prompt construction more disciplined * Clean up * Tweaks
This commit is contained in:
committed by
pullfrog[bot]
parent
54279e313b
commit
210084a3b6
@@ -138323,8 +138323,7 @@ function GetIssueCommentsTool(ctx) {
|
||||
comments: comments.map((comment) => ({
|
||||
id: comment.id,
|
||||
body: comment.body,
|
||||
user: comment.user?.login,
|
||||
author_association: comment.author_association
|
||||
user: comment.user?.login
|
||||
})),
|
||||
count: comments.length
|
||||
};
|
||||
@@ -139239,7 +139238,7 @@ function computeModes() {
|
||||
{
|
||||
name: "Build",
|
||||
description: "Implement, build, create, or develop code changes; make specific changes to files or features; execute a plan; or handle tasks with specific implementation details",
|
||||
prompt: `Follow these steps. THINK HARDER.
|
||||
prompt: `Follow these steps exactly.
|
||||
1. Determine whether to work on the current branch or create a new one:
|
||||
- **PR event, modifying the existing PR**: The PR branch is probably already checked out. Continue on this branch.
|
||||
- **PR event, but user wants a NEW branch/PR**: Use \`${ghPullfrogMcpName}/create_branch\` to create a new branch from the current HEAD.
|
||||
@@ -139253,17 +139252,19 @@ function computeModes() {
|
||||
|
||||
4. Understand the requirements and any existing plan
|
||||
|
||||
5. Make the necessary code changes using file operations. Then use ${ghPullfrogMcpName}/commit_files to commit your changes, and ${ghPullfrogMcpName}/push_branch to push the branch. Do NOT use git commands like \`git commit\` or \`git push\` directly.
|
||||
5. Make the necessary code changes using file operations. You should change the minimum amount of code necessary to accomplish your task. Emphasize code quality and elegance.
|
||||
|
||||
6. Test your changes to ensure they work correctly
|
||||
6. Then use ${ghPullfrogMcpName}/commit_files to commit your changes, and ${ghPullfrogMcpName}/push_branch to push the branch. Do NOT use git commands like \`git commit\` or \`git push\` directly.
|
||||
|
||||
7. ${reportProgressInstruction}
|
||||
7. Test your changes to ensure they work correctly
|
||||
|
||||
8. Determine whether to create a PR:
|
||||
8. ${reportProgressInstruction}
|
||||
|
||||
9. Determine whether to create a PR (if not already on a PR branch):
|
||||
- **Default behavior**: Create a PR using ${ghPullfrogMcpName}/create_pull_request with an informative title and body. If relevant, indicate which issue the PR addresses (e.g. "Fixes #123").
|
||||
- **Branch-only request**: If the user explicitly asks for a branch without a PR (e.g. "don't create a PR", "branch only", "just create a branch"), do NOT create a PR. Simply push the branch and report the branch link.
|
||||
|
||||
9. Call report_progress one final time ONLY if you haven't already included all the important information (PR links, branch links, summary) in a previous report_progress call. If you already called report_progress with complete information including PR links after creating the PR, you do NOT need to call it again. Only make a final call if you need to add missing information. When making the final call, ensure it includes:
|
||||
10. Call report_progress one final time ONLY if you haven't already included all the important information (PR links, branch links, summary) in a previous report_progress call. If you already called report_progress with complete information including PR links after creating the PR, you do NOT need to call it again. Only make a final call if you need to add missing information. When making the final call, ensure it includes:
|
||||
- A summary of what was accomplished
|
||||
- Links to any artifacts created (PRs, branches, issues)
|
||||
- If you created a PR, ALWAYS include the PR link. e.g.:
|
||||
@@ -156190,7 +156191,14 @@ var agent = (input) => {
|
||||
const search2 = ctx.payload.search;
|
||||
const write = ctx.payload.write;
|
||||
log.info(`\xBB running ${input.name} with effort=${ctx.payload.effort}...`);
|
||||
log.box(ctx.instructions.user.trim() + "\n\n" + ctx.instructions.event.trim(), {
|
||||
const logParts = [
|
||||
ctx.instructions.eventInstructions ? `EVENT-LEVEL INSTRUCTIONS:
|
||||
${ctx.instructions.eventInstructions}` : null,
|
||||
ctx.instructions.user ? `USER REQUEST:
|
||||
${ctx.instructions.user}` : null,
|
||||
ctx.instructions.event
|
||||
].filter(Boolean);
|
||||
log.box(logParts.join("\n\n---\n\n"), {
|
||||
title: "Instructions"
|
||||
});
|
||||
log.info(`\xBB tool permissions: web=${web}, search=${search2}, write=${write}, bash=${bash}`);
|
||||
@@ -157885,6 +157893,7 @@ function buildRuntimeContext(ctx) {
|
||||
const {
|
||||
"~pullfrog": _,
|
||||
prompt: _p,
|
||||
eventInstructions: _ei,
|
||||
repoInstructions: _r,
|
||||
event: _e,
|
||||
...payloadRest
|
||||
@@ -157911,24 +157920,26 @@ function buildRuntimeContext(ctx) {
|
||||
const filtered = Object.fromEntries(Object.entries(data).filter(([_2, v]) => v !== void 0));
|
||||
return encode(filtered);
|
||||
}
|
||||
function buildEventData(event) {
|
||||
const { title, body, trigger, ...rest } = event;
|
||||
function buildEventTitleBody(event) {
|
||||
const sections = [];
|
||||
const trimmedTitle = typeof title === "string" ? title.trim() : "";
|
||||
const trimmedBody = typeof body === "string" ? body.trim() : "";
|
||||
const trimmedTitle = typeof event.title === "string" ? event.title.trim() : "";
|
||||
const trimmedBody = typeof event.body === "string" ? event.body.trim() : "";
|
||||
if (trimmedTitle) {
|
||||
sections.push(`# ${trimmedTitle}`);
|
||||
}
|
||||
if (trimmedBody) {
|
||||
sections.push(trimmedBody);
|
||||
}
|
||||
const restWithTrigger = trigger === "workflow_dispatch" ? rest : { trigger, ...rest };
|
||||
if (Object.keys(restWithTrigger).length > 0) {
|
||||
if (sections.length > 0) sections.push("---");
|
||||
sections.push(encode(restWithTrigger));
|
||||
}
|
||||
return sections.join("\n\n");
|
||||
}
|
||||
function buildEventMetadata(event) {
|
||||
const { title: _t, body: _b, trigger, ...rest } = event;
|
||||
const restWithTrigger = trigger === "workflow_dispatch" ? rest : { trigger, ...rest };
|
||||
if (Object.keys(restWithTrigger).length === 0) {
|
||||
return "";
|
||||
}
|
||||
return encode(restWithTrigger);
|
||||
}
|
||||
function getShellInstructions(bash) {
|
||||
const backgroundInstructions = `For long-running processes (dev servers, watchers), use \`bash({ command, background: true })\` which returns a handle. Use \`${ghPullfrogMcpName}/kill_background\` to stop background processes by handle.`;
|
||||
switch (bash) {
|
||||
@@ -157945,11 +157956,16 @@ function getShellInstructions(bash) {
|
||||
}
|
||||
}
|
||||
function resolveInstructions(ctx) {
|
||||
const event = buildEventData(ctx.payload.event);
|
||||
const eventTitleBody = buildEventTitleBody(ctx.payload.event);
|
||||
const eventMetadata = buildEventMetadata(ctx.payload.event);
|
||||
const runtime = buildRuntimeContext(ctx);
|
||||
const user = ctx.payload.prompt;
|
||||
const eventInstructions = ctx.payload.eventInstructions ?? "";
|
||||
const repo = ctx.payload.repoInstructions ?? "";
|
||||
const userQuoted = user.split("\n").map((line) => `> ${line}`).join("\n");
|
||||
const isPr = ctx.payload.event.is_pr === true;
|
||||
const relatedLabel = isPr ? "--- related PR ---" : "--- related issue ---";
|
||||
const event = [eventTitleBody, eventMetadata].filter(Boolean).join("\n\n---\n\n");
|
||||
const userQuoted = user ? user.split("\n").map((line) => `> ${line}`).join("\n") : "";
|
||||
const system = `***********************************************
|
||||
************* SYSTEM INSTRUCTIONS *************
|
||||
***********************************************
|
||||
@@ -157972,11 +157988,10 @@ Use backticks liberally for inline code (e.g. \`z.string()\`) even in headers.
|
||||
## Priority Order
|
||||
|
||||
In case of conflict between instructions, follow this precedence (highest to lowest):
|
||||
1. Security rules (below)
|
||||
2. System instructions (this document)
|
||||
3. Mode instructions (returned by select_mode)
|
||||
4. Repository-specific instructions (AGENTS.md, CLAUDE.md, etc.)
|
||||
5. User prompt
|
||||
1. Security rules and system instructions (non-overridable)
|
||||
2. User prompt
|
||||
3. Event-level instructions
|
||||
4. Repo-level instructions
|
||||
|
||||
## Security
|
||||
|
||||
@@ -158024,29 +158039,42 @@ ${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 *************
|
||||
const repoSection = repo ? `************* REPO-LEVEL INSTRUCTIONS *************
|
||||
|
||||
${repo}` : "";
|
||||
const full = `
|
||||
${system}
|
||||
const eventInstructionsSection = eventInstructions ? `************* EVENT-LEVEL INSTRUCTIONS *************
|
||||
|
||||
************* USER PROMPT *************
|
||||
${eventInstructions}` : "";
|
||||
const titleBodySection = eventTitleBody ? `${relatedLabel}
|
||||
|
||||
${eventTitleBody}` : "";
|
||||
const metadataSection = eventMetadata ? `--- event context ---
|
||||
|
||||
${eventMetadata}` : "";
|
||||
const userSection = userQuoted ? `************* USER PROMPT \u2014 THIS IS YOUR TASK *************
|
||||
|
||||
${userQuoted}
|
||||
|
||||
${titleBodySection}
|
||||
|
||||
${metadataSection}` : `************* EVENT CONTEXT *************
|
||||
|
||||
${titleBodySection}
|
||||
|
||||
${metadataSection}`;
|
||||
const rawFull = `************* RUNTIME CONTEXT *************
|
||||
|
||||
${runtime}
|
||||
|
||||
${system}
|
||||
|
||||
${repoSection}
|
||||
|
||||
************* EVENT DATA *************
|
||||
${eventInstructionsSection}
|
||||
|
||||
${event}
|
||||
|
||||
************* RUNTIME CONTEXT *************
|
||||
|
||||
The following contains the agent configuration (agent, effort, permissions) and runtime environment details.
|
||||
|
||||
${runtime}`;
|
||||
return { full, system, user, repo, event, runtime };
|
||||
${userSection}`;
|
||||
const full = rawFull.trim().replace(/\n{3,}/g, "\n\n");
|
||||
return { full, system, user, eventInstructions, repo, event, runtime };
|
||||
}
|
||||
|
||||
// utils/normalizeEnv.ts
|
||||
@@ -158123,9 +158151,10 @@ var ToolPermissionInput = type.enumerated("disabled", "enabled");
|
||||
var BashPermissionInput = type.enumerated("disabled", "restricted", "enabled");
|
||||
var JsonPayload = type({
|
||||
"~pullfrog": "true",
|
||||
"version": "string",
|
||||
version: "string",
|
||||
"agent?": AgentName.or("undefined"),
|
||||
"prompt?": "string",
|
||||
"eventInstructions?": "string",
|
||||
"repoInstructions?": "string",
|
||||
"event?": "object",
|
||||
"effort?": Effort.or("undefined")
|
||||
@@ -158204,6 +158233,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,
|
||||
eventInstructions: jsonPayload?.eventInstructions,
|
||||
repoInstructions: jsonPayload?.repoInstructions,
|
||||
event,
|
||||
effort: inputs.effort ?? jsonPayload?.effort ?? "auto",
|
||||
|
||||
Reference in New Issue
Block a user