pullfrog 0.1.100 → 0.1.101
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 +677 -726
- package/dist/external.d.ts +1 -1
- package/dist/index.js +675 -724
- package/dist/internal/index.d.ts +3 -2
- package/dist/internal.js +58 -8
- package/dist/models.d.ts +4 -0
- package/dist/toolState.d.ts +2 -4
- package/dist/utils/agentHangReport.d.ts +6 -10
- package/dist/utils/apiKeys.d.ts +47 -7
- package/dist/utils/billingErrors.d.ts +6 -3
- package/dist/utils/buildPullfrogFooter.d.ts +17 -4
- package/dist/utils/errorReport.d.ts +0 -1
- package/dist/utils/failureBody.d.ts +27 -0
- package/dist/utils/leapingComment.d.ts +9 -0
- package/dist/utils/proxy.d.ts +1 -0
- package/dist/utils/roleMirror.d.ts +3 -2
- package/dist/utils/runContext.d.ts +3 -0
- package/dist/utils/runContextData.d.ts +2 -0
- package/dist/utils/runErrorRenderer.d.ts +44 -69
- package/dist/utils/secretCommands.d.ts +5 -14
- package/package.json +1 -1
|
@@ -1,99 +1,67 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Classify + render the error thrown out of the main run try-block into
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Classify + render the error thrown out of the main run try-block into the
|
|
3
|
+
* markdown the user reads — the PR progress comment, and the same body under a
|
|
4
|
+
* `### ❌ Pullfrog failed` banner in the GitHub Actions job summary.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Every body names its cause, so none collapses to a bare "Run failed.": an
|
|
7
|
+
* error nothing below recognizes is shown as-is under "An unrecognized error
|
|
8
|
+
* occurred." The shape is `renderFailure`'s, so the copy rules hold for all of
|
|
9
|
+
* them — see `failureBody.ts`.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
* handled inline) or the agent runtime surfaced an OpenRouter
|
|
13
|
-
* "key budget exhausted" string mid-run. Both render via
|
|
14
|
-
* `formatBillingErrorSummary` so the user sees actionable copy.
|
|
11
|
+
* Classifications, in dispatch order (first match wins):
|
|
15
12
|
*
|
|
16
|
-
*
|
|
13
|
+
* 1. Trial credits — a trial key that ran out mid-run is the account's free
|
|
14
|
+
* credits running out, never the Router wallet the same wire text means
|
|
15
|
+
* on a Router run.
|
|
16
|
+
*
|
|
17
|
+
* 1a. `BillingError` — the agent runtime surfaced an OpenRouter "key budget
|
|
18
|
+
* exhausted" string mid-run on a Router run. Same copy as a proxy-token 402.
|
|
19
|
+
*
|
|
20
|
+
* 1b. Pre-rendered bodies — a throw site that already built the markdown
|
|
17
21
|
* (`MODEL_ACCESS_MARKER`, `SECRETS_UNAVAILABLE_MARKER`,
|
|
18
|
-
* `ROUTER_UNFUNDED_MARKER`, `
|
|
19
|
-
* `CREDENTIAL_POOL_REFUSED_MARKER`) passes
|
|
22
|
+
* `ROUTER_UNFUNDED_MARKER`, `TRIAL_SPENT_MARKER`,
|
|
23
|
+
* `CREDENTIAL_REJECTED_MARKER`, `CREDENTIAL_POOL_REFUSED_MARKER`) passes
|
|
24
|
+
* through verbatim.
|
|
20
25
|
*
|
|
21
26
|
* 2. BYOK provider billing-exhausted (#835) — DeepSeek "Insufficient
|
|
22
27
|
* Balance", Anthropic "credit balance is too low", OpenCode Zen
|
|
23
|
-
* `CreditsError`, Gemini "spending cap"
|
|
24
|
-
* because billing-exhausted responses
|
|
25
|
-
* that `isApiKeyAuthError` would otherwise
|
|
28
|
+
* `CreditsError`, Gemini "spending cap", a ChatGPT workspace out of
|
|
29
|
+
* credits. Checked before api-key auth because billing-exhausted responses
|
|
30
|
+
* often carry 401 status codes that `isApiKeyAuthError` would otherwise
|
|
31
|
+
* mis-classify.
|
|
26
32
|
*
|
|
27
33
|
* 2a. Provider usage limit (#1474) — a capped subscription window or a
|
|
28
34
|
* configured workspace limit; "wait or raise it", never "top up".
|
|
29
35
|
*
|
|
30
36
|
* 3. API-key auth error — `isApiKeyAuthError` sniffs the raw error string
|
|
31
37
|
* (or the activity-timeout hang body when present, since that's where
|
|
32
|
-
* the underlying provider error often lands)
|
|
33
|
-
* renders provider + console-link copy.
|
|
34
|
-
*
|
|
35
|
-
* 4. ProviderModelNotFoundError — configured model id not in the OpenCode
|
|
36
|
-
* catalog (opencode ≥1.18 words it `Model not found: <id>`, #1470);
|
|
37
|
-
* renders a nudge to pick a different model.
|
|
38
|
-
*
|
|
39
|
-
* 4a. No-provider-available (#1077) — the model IS in the catalog but the
|
|
40
|
-
* provider declines to route it on this account's plan (OpenCode Zen's
|
|
41
|
-
* own refusal string). Same "pick another model" CTA, different reason.
|
|
38
|
+
* the underlying provider error often lands).
|
|
42
39
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* 4b. Context-window overflow (#1116) — terminal `Prompt is too long` /
|
|
49
|
-
* `maximum context length is N tokens`. Actionable, so it renders on
|
|
50
|
-
* both surfaces rather than collapsing to the one-line comment.
|
|
51
|
-
*
|
|
52
|
-
* 4b'. Run time limit — the agent was still working when the run's own
|
|
53
|
-
* timeout fired. Actionable (raise the limit), so both surfaces.
|
|
40
|
+
* 4. Model not in OpenCode's catalog (opencode ≥1.18 words it `Model not
|
|
41
|
+
* found: <id>`, #1470), a provider declining the model (#1077), Zen's
|
|
42
|
+
* free-tier gate (#1377), context overflow (#1116), the run's time limit,
|
|
43
|
+
* the repo's stop script, and an agent that never posted its review.
|
|
54
44
|
*
|
|
55
45
|
* 4c. Transient upstream failure (#1173) — Anthropic `529 Overloaded`,
|
|
56
46
|
* OpenRouter `provider_unavailable` / `timeout`, Zen `Streaming response
|
|
57
|
-
* failed: [5xx]
|
|
58
|
-
*
|
|
59
|
-
* which the user can only know if we say so.
|
|
47
|
+
* failed: [5xx]`, Codex's model at capacity. Last of the classified
|
|
48
|
+
* branches so every more specific one wins first.
|
|
60
49
|
*
|
|
61
|
-
* 5. Activity-timeout hang — `
|
|
62
|
-
*
|
|
63
|
-
* above matched. The harness keeps structured diagnostic state on
|
|
64
|
-
* `toolState.agentDiagnostic`; `formatAgentHangBody` renders that into
|
|
65
|
-
* the job summary. The PR comment keeps that same body whenever the hang
|
|
66
|
-
* is EXPLAINED — a classified provider error (#778, #1183) or a provider
|
|
67
|
-
* that never returned a first token — and otherwise collapses to a
|
|
68
|
-
* one-line `**Run failed.** [View the logs →]`, because watchdog jargon,
|
|
69
|
-
* event counts and a benign stderr tail are operator-grade detail that
|
|
70
|
-
* only alarm the average user.
|
|
50
|
+
* 5. Activity-timeout hang — `formatAgentHangBody` says whose side went
|
|
51
|
+
* quiet, with the agent's last output collapsed under it.
|
|
71
52
|
*
|
|
72
53
|
* 6. Unclassified provider error (#1474) — `errorMessage` starts with
|
|
73
|
-
* `provider error:
|
|
74
|
-
* with the provider's text; claude-code (a zero-event exit) and codex (no
|
|
75
|
-
* turn error, no stderr) prefix only our classifier label. Either names
|
|
76
|
-
* something the user can act on, so both surfaces get a lead line plus the
|
|
77
|
-
* raw text in a fenced block.
|
|
54
|
+
* `provider error: `: the provider's own text, shown under a lead line.
|
|
78
55
|
*
|
|
79
|
-
* 7. Default —
|
|
80
|
-
* raw error in a fenced code block under the `### ❌ Pullfrog failed`
|
|
81
|
-
* banner; the PR comment collapses to the same one-line logs link as
|
|
82
|
-
* the hang case, since the raw internal string helps nobody on the PR.
|
|
83
|
-
*
|
|
84
|
-
* Net: the actionable classifications (billing, usage limit, API-key,
|
|
85
|
-
* model-not-found, no-provider-available, context-overflow, run time limit,
|
|
86
|
-
* transient-upstream, unclassified provider error) render identical bodies on
|
|
87
|
-
* both surfaces; the non-actionable ones (unexplained hang, generic) keep the
|
|
88
|
-
* forensics in the Actions job summary and show a calm one-liner in the PR
|
|
89
|
-
* comment, whose footer already carries Pullfrog branding + rerun links.
|
|
56
|
+
* 7. Default — "An unrecognized error occurred." over the error itself.
|
|
90
57
|
*/
|
|
58
|
+
import type { AgentCredential } from "../agents/shared.ts";
|
|
91
59
|
import type { AgentDiagnostic } from "./agentHangReport.ts";
|
|
92
60
|
export type RenderedRunError = {
|
|
93
61
|
summary: string;
|
|
94
62
|
comment: string;
|
|
95
63
|
};
|
|
96
|
-
|
|
64
|
+
type RenderRunErrorInput = {
|
|
97
65
|
errorMessage: string;
|
|
98
66
|
repo: {
|
|
99
67
|
owner: string;
|
|
@@ -104,4 +72,11 @@ export declare function renderRunError(input: {
|
|
|
104
72
|
* the user's own provider credential. `payload.proxyModel` at both call
|
|
105
73
|
* sites. */
|
|
106
74
|
routerActive: boolean;
|
|
107
|
-
|
|
75
|
+
/** the model that ran: it names the provider, and the subscription when one is in play. */
|
|
76
|
+
model?: string | undefined;
|
|
77
|
+
credential?: AgentCredential | undefined;
|
|
78
|
+
/** the run was served by the account's free trial credits. */
|
|
79
|
+
trial?: boolean | undefined;
|
|
80
|
+
};
|
|
81
|
+
export declare function renderRunError(input: RenderRunErrorInput): RenderedRunError;
|
|
82
|
+
export {};
|
|
@@ -1,19 +1,10 @@
|
|
|
1
|
+
export declare function maskSecret(value: string): void;
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Off a runner nothing consumes these commands and `@actions/core` writes the
|
|
6
|
-
* raw value to stdout instead — `setSecret` always, `saveState` / `setOutput`
|
|
7
|
-
* whenever `GITHUB_STATE` / `GITHUB_OUTPUT` are unset. That is a plaintext
|
|
8
|
-
* credential on whatever terminal is running the action, which is how an OpenAI
|
|
9
|
-
* key reached local Codex transcripts and was disabled (2026-09).
|
|
10
|
-
*
|
|
11
|
-
* Route every credential-bearing call through here instead of calling `core`
|
|
12
|
-
* directly — `nub run check:secret-commands` enforces it. Non-credential output
|
|
13
|
-
* (the agent's own `result` text) stays ungated, because the test harness reads
|
|
14
|
-
* it back through `GITHUB_OUTPUT` on a host with no runner.
|
|
3
|
+
* Every value `maskSecret` registered, replaced in `text` as the runner would in
|
|
4
|
+
* a log: whole, then line by line. Parts under 8 characters are skipped, or the
|
|
5
|
+
* `{` and `}` lines of a JSON key would blank every brace in the comment.
|
|
15
6
|
*/
|
|
16
|
-
export declare function
|
|
7
|
+
export declare function redactSecrets(text: string): string;
|
|
17
8
|
/** @see maskSecret — same gate, for state the `post:` hook reads back. */
|
|
18
9
|
export declare function saveSecretState(name: string, value: string): void;
|
|
19
10
|
/** @see maskSecret — same gate, for a step output carrying a credential. */
|