add #timeout, macro errors, refactor tests (#191)

This commit is contained in:
David Blass
2026-01-28 21:06:57 +00:00
committed by pullfrog[bot]
parent f77fecc2a0
commit 943409c417
18 changed files with 472 additions and 94 deletions
+54 -10
View File
@@ -136833,7 +136833,7 @@ function GetCheckSuiteLogsTool(ctx) {
// utils/buildPullfrogFooter.ts
var PULLFROG_DIVIDER = "<!-- PULLFROG_DIVIDER_DO_NOT_REMOVE_PLZ -->";
var FROG_LOGO = `<a href="https://pullfrog.com"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pullfrog.com/logos/frog-white-full-128px.png"><img src="https://pullfrog.com/logos/frog-green-full-128px.png" width="9px" height="9px" style="vertical-align: middle; " alt="Pullfrog"></picture></a>`;
var FROG_LOGO = `<a href="https://pullfrog.com"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pullfrog.com/logos/frog-white-full-18px.png"><img src="https://pullfrog.com/logos/frog-green-full-18px.png" width="9px" height="9px" style="vertical-align: middle; " alt="Pullfrog"></picture></a>`;
function buildPullfrogFooter(params) {
const parts = [];
if (params.triggeredBy) {
@@ -160004,9 +160004,7 @@ var package_default = {
typecheck: "tsc --noEmit",
build: "node esbuild.config.js",
play: "node play.ts",
smoke: "node test/smoke.ts",
nobash: "node test/nobash.ts",
restricted: "node test/restricted.ts",
runtest: "node test/run.ts",
scratch: "node scratch.ts",
upDeps: "pnpm up --latest",
lock: "pnpm --ignore-workspace install",
@@ -160267,10 +160265,16 @@ var agent = (input) => {
const web = ctx.payload.web;
const search2 = ctx.payload.search;
const write2 = ctx.payload.write;
log.info(`\xBB running ${input.name} with effort=${ctx.payload.effort}...`);
const eventWithInstructions = ctx.instructions.eventInstructions ? `additionalInstructions: ${ctx.instructions.eventInstructions}
${ctx.instructions.event}` : ctx.instructions.event;
const logParts = [ctx.instructions.user, eventWithInstructions].filter(Boolean);
log.info(
`\xBB running ${input.name} with effort=${ctx.payload.effort}, timeout=${ctx.payload.timeout}...`
);
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"
});
@@ -162301,7 +162305,8 @@ var JsonPayload = type({
"eventInstructions?": "string",
"repoInstructions?": "string",
"event?": "object",
"effort?": Effort.or("undefined")
"effort?": Effort.or("undefined"),
"timeout?": type.string.or("undefined")
});
var COLLABORATOR_PERMISSIONS = ["admin", "maintain", "write"];
function isCollaborator(event) {
@@ -162311,6 +162316,7 @@ function isCollaborator(event) {
var Inputs = type({
prompt: "string",
"effort?": Effort.or("undefined"),
"timeout?": type.string.or("undefined"),
"agent?": AgentName.or("undefined"),
"web?": ToolPermissionInput.or("undefined"),
"search?": ToolPermissionInput.or("undefined"),
@@ -162334,6 +162340,7 @@ function resolvePayload(repoSettings) {
const inputs = Inputs.assert({
prompt: core4.getInput("prompt", { required: true }),
effort: core4.getInput("effort") || void 0,
timeout: core4.getInput("timeout") || void 0,
agent: core4.getInput("agent") || void 0,
cwd: core4.getInput("cwd") || void 0,
web: core4.getInput("web") || void 0,
@@ -162381,6 +162388,7 @@ function resolvePayload(repoSettings) {
repoInstructions: jsonPayload?.repoInstructions,
event,
effort: inputs.effort ?? jsonPayload?.effort ?? "auto",
timeout: inputs.timeout ?? jsonPayload?.timeout,
cwd: resolveCwd(inputs.cwd),
// permissions: inputs > repoSettings > fallbacks
web: inputs.web ?? repoSettings.web ?? "enabled",
@@ -162553,6 +162561,18 @@ async function setupGit(params) {
params.toolState.prNumber = prContext.prNumber;
}
// utils/time.ts
var TIMEOUT_DISABLED = "none";
var TIME_STRING_REGEX = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/;
function parseTimeString(input) {
const match2 = input.match(TIME_STRING_REGEX);
if (!match2 || !match2[1] && !match2[2] && !match2[3]) return null;
const hours = parseInt(match2[1] || "0", 10);
const minutes = parseInt(match2[2] || "0", 10);
const seconds = parseInt(match2[3] || "0", 10);
return (hours * 3600 + minutes * 60 + seconds) * 1e3;
}
// utils/timer.ts
var Timer = class {
initialTimestamp;
@@ -162694,12 +162714,36 @@ async function main() {
repo: runContext.repo,
modes: modes2
});
const result = await agent2.run({
const agentPromise = agent2.run({
payload,
mcpServerUrl: mcpHttpServer.url,
tmpdir: tmpdir3,
instructions
});
let result;
if (payload.timeout === TIMEOUT_DISABLED) {
result = await agentPromise;
} else {
const parsed2 = payload.timeout ? parseTimeString(payload.timeout) : null;
if (payload.timeout && parsed2 === null) {
log.warning(`Invalid timeout format "${payload.timeout}", using default 1h`);
}
const timeoutMs = parsed2 ?? 36e5;
const actualTimeout = parsed2 !== null ? payload.timeout : "1h";
let timeoutId;
const timeoutPromise = new Promise((_3, reject) => {
timeoutId = setTimeout(() => {
reject(new Error(`agent run timed out after ${actualTimeout}`));
}, timeoutMs);
});
timeoutPromise.catch(() => {
});
try {
result = await Promise.race([agentPromise, timeoutPromise]);
} finally {
clearTimeout(timeoutId);
}
}
if (toolState.lastProgressBody) {
await writeSummary(toolState.lastProgressBody);
}