pullfrog 0.1.62 → 0.1.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +61 -14
- package/dist/index.js +60 -13
- package/dist/internal.js +10 -1
- package/dist/utils/runErrorRenderer.d.ts +7 -7
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -106004,7 +106004,16 @@ var providers = {
|
|
|
106004
106004
|
resolve: "opencode/claude-opus-5",
|
|
106005
106005
|
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
106006
106006
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
106007
|
-
subagentModel: "claude-sonnet"
|
|
106007
|
+
subagentModel: "claude-sonnet",
|
|
106008
|
+
// TEMPORARY — clear this when Zen serves opus again. Zen still LISTS
|
|
106009
|
+
// claude-opus-5 in /zen/v1/models, so the catalog test passes, but the
|
|
106010
|
+
// endpoint answers 503 `Upstream request failed: Endpoint is
|
|
106011
|
+
// unavailable.` (measured 5/5; claude-sonnet-5, claude-opus-4-8,
|
|
106012
|
+
// claude-haiku-4-5 and claude-fable-5 all 200 on the same key). opencode
|
|
106013
|
+
// retries the 503 above the AI SDK emitting no part.updated, so a run
|
|
106014
|
+
// just produces nothing until it is killed — metaideas/init logged six
|
|
106015
|
+
// zero-output failures from 2026-08-23. see wiki/opencode-silent-stall.md
|
|
106016
|
+
fallback: "opencode/claude-sonnet"
|
|
106008
106017
|
},
|
|
106009
106018
|
"claude-sonnet": {
|
|
106010
106019
|
displayName: "Claude Sonnet",
|
|
@@ -107358,7 +107367,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
107358
107367
|
// package.json
|
|
107359
107368
|
var package_default = {
|
|
107360
107369
|
name: "pullfrog",
|
|
107361
|
-
version: "0.1.
|
|
107370
|
+
version: "0.1.64",
|
|
107362
107371
|
type: "module",
|
|
107363
107372
|
bin: {
|
|
107364
107373
|
pullfrog: "dist/cli.mjs",
|
|
@@ -116237,7 +116246,7 @@ function isModelOutput(ctx, part) {
|
|
|
116237
116246
|
async function dispatchEvent(ctx, event) {
|
|
116238
116247
|
if (event.type === "message.part.updated") {
|
|
116239
116248
|
ctx.lastEventAt = performance7.now();
|
|
116240
|
-
if (isModelOutput(ctx, event.properties.part)) ctx.sawModelOutput = true;
|
|
116249
|
+
if (isModelOutput(ctx, event.properties.part)) ctx.diagnostic.sawModelOutput = true;
|
|
116241
116250
|
await onPartUpdated(ctx, event.properties.part);
|
|
116242
116251
|
return;
|
|
116243
116252
|
}
|
|
@@ -116383,7 +116392,8 @@ async function runPromptTurn(ctx, params) {
|
|
|
116383
116392
|
const turn = ctx.currentTurn;
|
|
116384
116393
|
const part = { type: "text", text: params.text };
|
|
116385
116394
|
ctx.promptMessageID = void 0;
|
|
116386
|
-
ctx.sawModelOutput = false;
|
|
116395
|
+
ctx.diagnostic.sawModelOutput = false;
|
|
116396
|
+
ctx.diagnostic.idleSec = void 0;
|
|
116387
116397
|
let assistant;
|
|
116388
116398
|
let returnedParts;
|
|
116389
116399
|
let networkError = null;
|
|
@@ -116443,7 +116453,7 @@ async function runPromptTurn(ctx, params) {
|
|
|
116443
116453
|
usage
|
|
116444
116454
|
};
|
|
116445
116455
|
}
|
|
116446
|
-
if (!ctx.sawModelOutput && finalText.trim().length === 0 && !usage) {
|
|
116456
|
+
if (!ctx.diagnostic.sawModelOutput && finalText.trim().length === 0 && !usage) {
|
|
116447
116457
|
return {
|
|
116448
116458
|
success: false,
|
|
116449
116459
|
output: finalText,
|
|
@@ -116568,19 +116578,18 @@ function startInnerActivityWatchdog(params) {
|
|
|
116568
116578
|
const id = setInterval(() => {
|
|
116569
116579
|
if (fired) return;
|
|
116570
116580
|
const idleMs = performance7.now() - params.ctx.lastEventAt;
|
|
116571
|
-
const compiledMs = params.ctx.sawModelOutput ? params.timeoutMs : AGENT_FIRST_EVENT_TIMEOUT_MS;
|
|
116581
|
+
const compiledMs = params.ctx.diagnostic.sawModelOutput ? params.timeoutMs : AGENT_FIRST_EVENT_TIMEOUT_MS;
|
|
116572
116582
|
const budgetMs = everFired ? compiledMs : watchdogBudgetMs(
|
|
116573
116583
|
compiledMs,
|
|
116574
|
-
params.ctx.sawModelOutput ? "PULLFROG_E2E_ACTIVITY_TIMEOUT_MS" : "PULLFROG_E2E_FIRST_EVENT_TIMEOUT_MS"
|
|
116584
|
+
params.ctx.diagnostic.sawModelOutput ? "PULLFROG_E2E_ACTIVITY_TIMEOUT_MS" : "PULLFROG_E2E_FIRST_EVENT_TIMEOUT_MS"
|
|
116575
116585
|
);
|
|
116576
116586
|
if (idleMs <= budgetMs) return;
|
|
116577
116587
|
fired = true;
|
|
116578
116588
|
everFired = true;
|
|
116579
116589
|
const idleSec = Math.round(idleMs / 1e3);
|
|
116580
116590
|
params.ctx.diagnostic.idleSec = idleSec;
|
|
116581
|
-
params.ctx.diagnostic.sawModelOutput = params.ctx.sawModelOutput;
|
|
116582
116591
|
log2.info(
|
|
116583
|
-
params.ctx.sawModelOutput ? `\xBB no opencode events for ${idleSec}s \u2014 aborting in-flight prompt and notifying harness` : `\xBB no opencode events for ${idleSec}s \u2014 the provider never returned a first token; aborting in-flight prompt and notifying harness`
|
|
116592
|
+
params.ctx.diagnostic.sawModelOutput ? `\xBB no opencode events for ${idleSec}s \u2014 aborting in-flight prompt and notifying harness` : `\xBB no opencode events for ${idleSec}s \u2014 the provider never returned a first token; aborting in-flight prompt and notifying harness`
|
|
116584
116593
|
);
|
|
116585
116594
|
params.abortTurn();
|
|
116586
116595
|
try {
|
|
@@ -116724,7 +116733,6 @@ var opencode = agent({
|
|
|
116724
116733
|
currentTurn: null,
|
|
116725
116734
|
eventCount: 0,
|
|
116726
116735
|
lastEventAt: performance7.now(),
|
|
116727
|
-
sawModelOutput: false,
|
|
116728
116736
|
promptMessageID: void 0,
|
|
116729
116737
|
taskDispatchByCallID: /* @__PURE__ */ new Map(),
|
|
116730
116738
|
loggedToolCallIDs: /* @__PURE__ */ new Set(),
|
|
@@ -116788,7 +116796,9 @@ var opencode = agent({
|
|
|
116788
116796
|
);
|
|
116789
116797
|
};
|
|
116790
116798
|
const standDownIfRecovered = (turn) => {
|
|
116791
|
-
if (watchdog.firedThisTurn()
|
|
116799
|
+
if (!watchdog.firedThisTurn() || !turn.success) return turn;
|
|
116800
|
+
runnerCtx.diagnostic.idleSec = void 0;
|
|
116801
|
+
ctx.onTurnRecovered?.();
|
|
116792
116802
|
return turn;
|
|
116793
116803
|
};
|
|
116794
116804
|
const result = await attempt(text);
|
|
@@ -196276,6 +196286,43 @@ function resolveCwd(cwd) {
|
|
|
196276
196286
|
if (isAbsolute2(cwd)) return cwd;
|
|
196277
196287
|
return workspace ? resolve2(workspace, cwd) : cwd;
|
|
196278
196288
|
}
|
|
196289
|
+
var DISPATCH_PAYLOAD_KEY = '"~pullfrog"';
|
|
196290
|
+
function sliceBalancedObject(text, open) {
|
|
196291
|
+
let depth = 0;
|
|
196292
|
+
let inString = false;
|
|
196293
|
+
for (let i2 = open; i2 < text.length; i2++) {
|
|
196294
|
+
const char = text[i2];
|
|
196295
|
+
if (inString) {
|
|
196296
|
+
if (char === "\\") i2++;
|
|
196297
|
+
else if (char === '"') inString = false;
|
|
196298
|
+
continue;
|
|
196299
|
+
}
|
|
196300
|
+
if (char === '"') inString = true;
|
|
196301
|
+
else if (char === "{") depth++;
|
|
196302
|
+
else if (char === "}" && --depth === 0) return text.slice(open, i2 + 1);
|
|
196303
|
+
}
|
|
196304
|
+
return void 0;
|
|
196305
|
+
}
|
|
196306
|
+
function findEmbeddedDispatchPayload(text) {
|
|
196307
|
+
const limit = text.lastIndexOf(DISPATCH_PAYLOAD_KEY);
|
|
196308
|
+
if (limit === -1) return void 0;
|
|
196309
|
+
for (let open = text.indexOf("{"); open !== -1 && open < limit; open = text.indexOf("{", open + 1)) {
|
|
196310
|
+
const candidate = sliceBalancedObject(text, open);
|
|
196311
|
+
if (!candidate) continue;
|
|
196312
|
+
try {
|
|
196313
|
+
const parsed2 = JSON.parse(candidate);
|
|
196314
|
+
if (JsonPayload.allows(parsed2)) return parsed2;
|
|
196315
|
+
} catch {
|
|
196316
|
+
}
|
|
196317
|
+
}
|
|
196318
|
+
return void 0;
|
|
196319
|
+
}
|
|
196320
|
+
function assertDispatchPayloadIntact(promptInput) {
|
|
196321
|
+
if (!findEmbeddedDispatchPayload(promptInput)) return;
|
|
196322
|
+
throw new Error(
|
|
196323
|
+
"this workflow wraps `${{ inputs.prompt }}` in other text, so Pullfrog's dispatch payload can't be read and the run would lose its pull request context, its progress comment, and its standing instructions. in `.github/workflows/pullfrog.yml`, set `prompt:` to exactly `${{ inputs.prompt }}`, and move your own preamble into Standing instructions in the Pullfrog console."
|
|
196324
|
+
);
|
|
196325
|
+
}
|
|
196279
196326
|
function resolvePromptInput() {
|
|
196280
196327
|
const promptInput = core7.getInput("prompt");
|
|
196281
196328
|
const promptFile = core7.getInput("prompt_file");
|
|
@@ -196292,9 +196339,9 @@ function resolvePromptInput() {
|
|
|
196292
196339
|
try {
|
|
196293
196340
|
parsed2 = JSON.parse(promptInput);
|
|
196294
196341
|
} catch {
|
|
196295
|
-
return promptInput;
|
|
196296
196342
|
}
|
|
196297
196343
|
if (!parsed2 || typeof parsed2 !== "object" || !("~pullfrog" in parsed2)) {
|
|
196344
|
+
assertDispatchPayloadIntact(promptInput);
|
|
196298
196345
|
return promptInput;
|
|
196299
196346
|
}
|
|
196300
196347
|
const jsonPayload = JsonPayload.assert(parsed2);
|
|
@@ -197472,7 +197519,7 @@ ${body}`, comment: body };
|
|
|
197472
197519
|
${body}`, comment: body };
|
|
197473
197520
|
}
|
|
197474
197521
|
if (hangBody) {
|
|
197475
|
-
const explained = input.agentDiagnostic?.lastProviderError !== void 0;
|
|
197522
|
+
const explained = input.agentDiagnostic?.lastProviderError !== void 0 || input.agentDiagnostic?.sawModelOutput === false;
|
|
197476
197523
|
return {
|
|
197477
197524
|
summary: `### \u274C Pullfrog failed
|
|
197478
197525
|
|
|
@@ -199265,7 +199312,7 @@ async function runCli4(input) {
|
|
|
199265
199312
|
}
|
|
199266
199313
|
|
|
199267
199314
|
// cli.ts
|
|
199268
|
-
var VERSION10 = "0.1.
|
|
199315
|
+
var VERSION10 = "0.1.64";
|
|
199269
199316
|
var bin = basename2(process.argv[1] || "");
|
|
199270
199317
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
199271
199318
|
var rawArgs = process.argv.slice(2);
|
package/dist/index.js
CHANGED
|
@@ -103837,7 +103837,16 @@ var providers = {
|
|
|
103837
103837
|
resolve: "opencode/claude-opus-5",
|
|
103838
103838
|
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
103839
103839
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
103840
|
-
subagentModel: "claude-sonnet"
|
|
103840
|
+
subagentModel: "claude-sonnet",
|
|
103841
|
+
// TEMPORARY — clear this when Zen serves opus again. Zen still LISTS
|
|
103842
|
+
// claude-opus-5 in /zen/v1/models, so the catalog test passes, but the
|
|
103843
|
+
// endpoint answers 503 `Upstream request failed: Endpoint is
|
|
103844
|
+
// unavailable.` (measured 5/5; claude-sonnet-5, claude-opus-4-8,
|
|
103845
|
+
// claude-haiku-4-5 and claude-fable-5 all 200 on the same key). opencode
|
|
103846
|
+
// retries the 503 above the AI SDK emitting no part.updated, so a run
|
|
103847
|
+
// just produces nothing until it is killed — metaideas/init logged six
|
|
103848
|
+
// zero-output failures from 2026-08-23. see wiki/opencode-silent-stall.md
|
|
103849
|
+
fallback: "opencode/claude-sonnet"
|
|
103841
103850
|
},
|
|
103842
103851
|
"claude-sonnet": {
|
|
103843
103852
|
displayName: "Claude Sonnet",
|
|
@@ -105191,7 +105200,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
105191
105200
|
// package.json
|
|
105192
105201
|
var package_default = {
|
|
105193
105202
|
name: "pullfrog",
|
|
105194
|
-
version: "0.1.
|
|
105203
|
+
version: "0.1.64",
|
|
105195
105204
|
type: "module",
|
|
105196
105205
|
bin: {
|
|
105197
105206
|
pullfrog: "dist/cli.mjs",
|
|
@@ -114117,7 +114126,7 @@ function isModelOutput(ctx, part) {
|
|
|
114117
114126
|
async function dispatchEvent(ctx, event) {
|
|
114118
114127
|
if (event.type === "message.part.updated") {
|
|
114119
114128
|
ctx.lastEventAt = performance7.now();
|
|
114120
|
-
if (isModelOutput(ctx, event.properties.part)) ctx.sawModelOutput = true;
|
|
114129
|
+
if (isModelOutput(ctx, event.properties.part)) ctx.diagnostic.sawModelOutput = true;
|
|
114121
114130
|
await onPartUpdated(ctx, event.properties.part);
|
|
114122
114131
|
return;
|
|
114123
114132
|
}
|
|
@@ -114263,7 +114272,8 @@ async function runPromptTurn(ctx, params) {
|
|
|
114263
114272
|
const turn = ctx.currentTurn;
|
|
114264
114273
|
const part = { type: "text", text: params.text };
|
|
114265
114274
|
ctx.promptMessageID = void 0;
|
|
114266
|
-
ctx.sawModelOutput = false;
|
|
114275
|
+
ctx.diagnostic.sawModelOutput = false;
|
|
114276
|
+
ctx.diagnostic.idleSec = void 0;
|
|
114267
114277
|
let assistant;
|
|
114268
114278
|
let returnedParts;
|
|
114269
114279
|
let networkError = null;
|
|
@@ -114323,7 +114333,7 @@ async function runPromptTurn(ctx, params) {
|
|
|
114323
114333
|
usage
|
|
114324
114334
|
};
|
|
114325
114335
|
}
|
|
114326
|
-
if (!ctx.sawModelOutput && finalText.trim().length === 0 && !usage) {
|
|
114336
|
+
if (!ctx.diagnostic.sawModelOutput && finalText.trim().length === 0 && !usage) {
|
|
114327
114337
|
return {
|
|
114328
114338
|
success: false,
|
|
114329
114339
|
output: finalText,
|
|
@@ -114448,19 +114458,18 @@ function startInnerActivityWatchdog(params) {
|
|
|
114448
114458
|
const id = setInterval(() => {
|
|
114449
114459
|
if (fired) return;
|
|
114450
114460
|
const idleMs = performance7.now() - params.ctx.lastEventAt;
|
|
114451
|
-
const compiledMs = params.ctx.sawModelOutput ? params.timeoutMs : AGENT_FIRST_EVENT_TIMEOUT_MS;
|
|
114461
|
+
const compiledMs = params.ctx.diagnostic.sawModelOutput ? params.timeoutMs : AGENT_FIRST_EVENT_TIMEOUT_MS;
|
|
114452
114462
|
const budgetMs = everFired ? compiledMs : watchdogBudgetMs(
|
|
114453
114463
|
compiledMs,
|
|
114454
|
-
params.ctx.sawModelOutput ? "PULLFROG_E2E_ACTIVITY_TIMEOUT_MS" : "PULLFROG_E2E_FIRST_EVENT_TIMEOUT_MS"
|
|
114464
|
+
params.ctx.diagnostic.sawModelOutput ? "PULLFROG_E2E_ACTIVITY_TIMEOUT_MS" : "PULLFROG_E2E_FIRST_EVENT_TIMEOUT_MS"
|
|
114455
114465
|
);
|
|
114456
114466
|
if (idleMs <= budgetMs) return;
|
|
114457
114467
|
fired = true;
|
|
114458
114468
|
everFired = true;
|
|
114459
114469
|
const idleSec = Math.round(idleMs / 1e3);
|
|
114460
114470
|
params.ctx.diagnostic.idleSec = idleSec;
|
|
114461
|
-
params.ctx.diagnostic.sawModelOutput = params.ctx.sawModelOutput;
|
|
114462
114471
|
log.info(
|
|
114463
|
-
params.ctx.sawModelOutput ? `\xBB no opencode events for ${idleSec}s \u2014 aborting in-flight prompt and notifying harness` : `\xBB no opencode events for ${idleSec}s \u2014 the provider never returned a first token; aborting in-flight prompt and notifying harness`
|
|
114472
|
+
params.ctx.diagnostic.sawModelOutput ? `\xBB no opencode events for ${idleSec}s \u2014 aborting in-flight prompt and notifying harness` : `\xBB no opencode events for ${idleSec}s \u2014 the provider never returned a first token; aborting in-flight prompt and notifying harness`
|
|
114464
114473
|
);
|
|
114465
114474
|
params.abortTurn();
|
|
114466
114475
|
try {
|
|
@@ -114604,7 +114613,6 @@ var opencode = agent({
|
|
|
114604
114613
|
currentTurn: null,
|
|
114605
114614
|
eventCount: 0,
|
|
114606
114615
|
lastEventAt: performance7.now(),
|
|
114607
|
-
sawModelOutput: false,
|
|
114608
114616
|
promptMessageID: void 0,
|
|
114609
114617
|
taskDispatchByCallID: /* @__PURE__ */ new Map(),
|
|
114610
114618
|
loggedToolCallIDs: /* @__PURE__ */ new Set(),
|
|
@@ -114668,7 +114676,9 @@ var opencode = agent({
|
|
|
114668
114676
|
);
|
|
114669
114677
|
};
|
|
114670
114678
|
const standDownIfRecovered = (turn) => {
|
|
114671
|
-
if (watchdog.firedThisTurn()
|
|
114679
|
+
if (!watchdog.firedThisTurn() || !turn.success) return turn;
|
|
114680
|
+
runnerCtx.diagnostic.idleSec = void 0;
|
|
114681
|
+
ctx.onTurnRecovered?.();
|
|
114672
114682
|
return turn;
|
|
114673
114683
|
};
|
|
114674
114684
|
const result = await attempt(text);
|
|
@@ -194156,6 +194166,43 @@ function resolveCwd(cwd) {
|
|
|
194156
194166
|
if (isAbsolute2(cwd)) return cwd;
|
|
194157
194167
|
return workspace ? resolve2(workspace, cwd) : cwd;
|
|
194158
194168
|
}
|
|
194169
|
+
var DISPATCH_PAYLOAD_KEY = '"~pullfrog"';
|
|
194170
|
+
function sliceBalancedObject(text, open) {
|
|
194171
|
+
let depth = 0;
|
|
194172
|
+
let inString = false;
|
|
194173
|
+
for (let i = open; i < text.length; i++) {
|
|
194174
|
+
const char = text[i];
|
|
194175
|
+
if (inString) {
|
|
194176
|
+
if (char === "\\") i++;
|
|
194177
|
+
else if (char === '"') inString = false;
|
|
194178
|
+
continue;
|
|
194179
|
+
}
|
|
194180
|
+
if (char === '"') inString = true;
|
|
194181
|
+
else if (char === "{") depth++;
|
|
194182
|
+
else if (char === "}" && --depth === 0) return text.slice(open, i + 1);
|
|
194183
|
+
}
|
|
194184
|
+
return void 0;
|
|
194185
|
+
}
|
|
194186
|
+
function findEmbeddedDispatchPayload(text) {
|
|
194187
|
+
const limit = text.lastIndexOf(DISPATCH_PAYLOAD_KEY);
|
|
194188
|
+
if (limit === -1) return void 0;
|
|
194189
|
+
for (let open = text.indexOf("{"); open !== -1 && open < limit; open = text.indexOf("{", open + 1)) {
|
|
194190
|
+
const candidate = sliceBalancedObject(text, open);
|
|
194191
|
+
if (!candidate) continue;
|
|
194192
|
+
try {
|
|
194193
|
+
const parsed2 = JSON.parse(candidate);
|
|
194194
|
+
if (JsonPayload.allows(parsed2)) return parsed2;
|
|
194195
|
+
} catch {
|
|
194196
|
+
}
|
|
194197
|
+
}
|
|
194198
|
+
return void 0;
|
|
194199
|
+
}
|
|
194200
|
+
function assertDispatchPayloadIntact(promptInput) {
|
|
194201
|
+
if (!findEmbeddedDispatchPayload(promptInput)) return;
|
|
194202
|
+
throw new Error(
|
|
194203
|
+
"this workflow wraps `${{ inputs.prompt }}` in other text, so Pullfrog's dispatch payload can't be read and the run would lose its pull request context, its progress comment, and its standing instructions. in `.github/workflows/pullfrog.yml`, set `prompt:` to exactly `${{ inputs.prompt }}`, and move your own preamble into Standing instructions in the Pullfrog console."
|
|
194204
|
+
);
|
|
194205
|
+
}
|
|
194159
194206
|
function resolvePromptInput() {
|
|
194160
194207
|
const promptInput = core7.getInput("prompt");
|
|
194161
194208
|
const promptFile = core7.getInput("prompt_file");
|
|
@@ -194172,9 +194219,9 @@ function resolvePromptInput() {
|
|
|
194172
194219
|
try {
|
|
194173
194220
|
parsed2 = JSON.parse(promptInput);
|
|
194174
194221
|
} catch {
|
|
194175
|
-
return promptInput;
|
|
194176
194222
|
}
|
|
194177
194223
|
if (!parsed2 || typeof parsed2 !== "object" || !("~pullfrog" in parsed2)) {
|
|
194224
|
+
assertDispatchPayloadIntact(promptInput);
|
|
194178
194225
|
return promptInput;
|
|
194179
194226
|
}
|
|
194180
194227
|
const jsonPayload = JsonPayload.assert(parsed2);
|
|
@@ -195352,7 +195399,7 @@ ${body}`, comment: body };
|
|
|
195352
195399
|
${body}`, comment: body };
|
|
195353
195400
|
}
|
|
195354
195401
|
if (hangBody) {
|
|
195355
|
-
const explained = input.agentDiagnostic?.lastProviderError !== void 0;
|
|
195402
|
+
const explained = input.agentDiagnostic?.lastProviderError !== void 0 || input.agentDiagnostic?.sawModelOutput === false;
|
|
195356
195403
|
return {
|
|
195357
195404
|
summary: `### \u274C Pullfrog failed
|
|
195358
195405
|
|
package/dist/internal.js
CHANGED
|
@@ -349,7 +349,16 @@ var providers = {
|
|
|
349
349
|
resolve: "opencode/claude-opus-5",
|
|
350
350
|
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
351
351
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
352
|
-
subagentModel: "claude-sonnet"
|
|
352
|
+
subagentModel: "claude-sonnet",
|
|
353
|
+
// TEMPORARY — clear this when Zen serves opus again. Zen still LISTS
|
|
354
|
+
// claude-opus-5 in /zen/v1/models, so the catalog test passes, but the
|
|
355
|
+
// endpoint answers 503 `Upstream request failed: Endpoint is
|
|
356
|
+
// unavailable.` (measured 5/5; claude-sonnet-5, claude-opus-4-8,
|
|
357
|
+
// claude-haiku-4-5 and claude-fable-5 all 200 on the same key). opencode
|
|
358
|
+
// retries the 503 above the AI SDK emitting no part.updated, so a run
|
|
359
|
+
// just produces nothing until it is killed — metaideas/init logged six
|
|
360
|
+
// zero-output failures from 2026-08-23. see wiki/opencode-silent-stall.md
|
|
361
|
+
fallback: "opencode/claude-sonnet"
|
|
353
362
|
},
|
|
354
363
|
"claude-sonnet": {
|
|
355
364
|
displayName: "Claude Sonnet",
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
* `"activity timeout"` or `"agent still pending"` AND none of the
|
|
46
46
|
* above matched. The harness keeps structured diagnostic state on
|
|
47
47
|
* `toolState.agentDiagnostic`; `formatAgentHangBody` renders that into
|
|
48
|
-
* the job summary. The PR comment
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
48
|
+
* the job summary. The PR comment keeps that same body whenever the hang
|
|
49
|
+
* is EXPLAINED — a classified provider error (#778, #1183) or a provider
|
|
50
|
+
* that never returned a first token — and otherwise collapses to a
|
|
51
|
+
* one-line `**Run failed.** [View the logs →]`, because watchdog jargon,
|
|
52
|
+
* event counts and a benign stderr tail are operator-grade detail that
|
|
53
|
+
* only alarm the average user.
|
|
54
54
|
*
|
|
55
55
|
* 6. Default — the job summary gets a plain-English lead sentence plus the
|
|
56
56
|
* raw error in a fenced code block under the `### ❌ Pullfrog failed`
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
*
|
|
60
60
|
* Net: the actionable classifications (billing, API-key, model-not-found,
|
|
61
61
|
* no-provider-available, context-overflow, transient-upstream) render identical
|
|
62
|
-
* bodies on both surfaces; the non-actionable ones (hang,
|
|
62
|
+
* bodies on both surfaces; the non-actionable ones (unexplained hang,
|
|
63
63
|
* generic) keep the forensics in the Actions job summary and show a calm
|
|
64
64
|
* one-liner in the PR comment, whose footer already carries Pullfrog
|
|
65
65
|
* branding + rerun links.
|