pullfrog 0.1.46 → 0.1.48
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/README.md +1 -1
- package/dist/agents/opencodePlugin.d.ts +2 -2
- package/dist/agents/opencodeShared.d.ts +0 -28
- package/dist/cli.mjs +541 -199
- package/dist/effort.d.ts +76 -0
- package/dist/external.d.ts +14 -1
- package/dist/index.js +527 -192
- package/dist/internal/index.d.ts +5 -2
- package/dist/internal.js +250 -1
- package/dist/models.d.ts +36 -2
- package/dist/toolState.d.ts +1 -0
- package/dist/utils/billingErrors.d.ts +27 -10
- package/dist/utils/payload.d.ts +12 -2
- package/dist/utils/runContext.d.ts +15 -3
- package/dist/utils/runContextData.d.ts +2 -1
- package/dist/utils/runEffort.d.ts +27 -0
- package/dist/utils/runStartupLog.d.ts +3 -3
- package/dist/utils/runStatusCheck.d.ts +170 -0
- package/dist/utils/statusChecks.d.ts +14 -17
- package/package.json +1 -1
- /package/dist/agents/{opencode_v2.d.ts → opencode.d.ts} +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -101356,6 +101356,10 @@ async function setPullfrogSecret(ctx) {
|
|
|
101356
101356
|
}
|
|
101357
101357
|
return { saved: false, error: result.data.error || `api returned ${result.status}` };
|
|
101358
101358
|
}
|
|
101359
|
+
function describeSecretTarget(ctx) {
|
|
101360
|
+
if (ctx.scope === "account") return `account ${import_picocolors.default.cyan(`@${ctx.owner}`)}`;
|
|
101361
|
+
return `repo ${import_picocolors.default.cyan(`${ctx.owner}/${ctx.repo}`)}`;
|
|
101362
|
+
}
|
|
101359
101363
|
async function promptScope(ctx) {
|
|
101360
101364
|
const scope2 = await _t({
|
|
101361
101365
|
message: "secret scope",
|
|
@@ -101579,7 +101583,8 @@ async function runCodexAuth() {
|
|
|
101579
101583
|
O2.warn(err instanceof Error ? err.message : String(err));
|
|
101580
101584
|
savable = auth2;
|
|
101581
101585
|
}
|
|
101582
|
-
|
|
101586
|
+
const target = describeSecretTarget({ owner: remote.owner, repo: remote.repo, scope: scope2 });
|
|
101587
|
+
spin.start(`saving ${import_picocolors2.default.cyan(CODEX_AUTH_SECRET)} to ${target}`);
|
|
101583
101588
|
const result = await setPullfrogSecret({
|
|
101584
101589
|
token,
|
|
101585
101590
|
owner: remote.owner,
|
|
@@ -101596,7 +101601,7 @@ async function runCodexAuth() {
|
|
|
101596
101601
|
);
|
|
101597
101602
|
process.exit(1);
|
|
101598
101603
|
}
|
|
101599
|
-
spin.stop(`saved ${import_picocolors2.default.cyan(CODEX_AUTH_SECRET)} to
|
|
101604
|
+
spin.stop(`saved ${import_picocolors2.default.cyan(CODEX_AUTH_SECRET)} to ${target}`);
|
|
101600
101605
|
setActiveSpin(null);
|
|
101601
101606
|
gt("done.");
|
|
101602
101607
|
} catch (error49) {
|
|
@@ -101693,7 +101698,8 @@ async function runClaudeAuth() {
|
|
|
101693
101698
|
`that doesn't look like a ${import_picocolors2.default.cyan("claude setup-token")} token (expected ${import_picocolors2.default.cyan(`${CLAUDE_OAUTH_TOKEN_PREFIX}\u2026`)}). saving it anyway.`
|
|
101694
101699
|
);
|
|
101695
101700
|
}
|
|
101696
|
-
|
|
101701
|
+
const target = describeSecretTarget({ owner: remote.owner, repo: remote.repo, scope: scope2 });
|
|
101702
|
+
spin.start(`saving ${import_picocolors2.default.cyan(CLAUDE_OAUTH_SECRET)} to ${target}`);
|
|
101697
101703
|
const result = await setPullfrogSecret({
|
|
101698
101704
|
token,
|
|
101699
101705
|
owner: remote.owner,
|
|
@@ -101710,7 +101716,7 @@ async function runClaudeAuth() {
|
|
|
101710
101716
|
);
|
|
101711
101717
|
process.exit(1);
|
|
101712
101718
|
}
|
|
101713
|
-
spin.stop(`saved ${import_picocolors2.default.cyan(CLAUDE_OAUTH_SECRET)} to
|
|
101719
|
+
spin.stop(`saved ${import_picocolors2.default.cyan(CLAUDE_OAUTH_SECRET)} to ${target}`);
|
|
101714
101720
|
setActiveSpin(null);
|
|
101715
101721
|
gt("done.");
|
|
101716
101722
|
} catch (error49) {
|
|
@@ -101738,6 +101744,36 @@ import { chmodSync as chmodSync2, mkdirSync as mkdirSync4, writeFileSync as writ
|
|
|
101738
101744
|
import { join as join5 } from "node:path";
|
|
101739
101745
|
import { performance as performance5 } from "node:perf_hooks";
|
|
101740
101746
|
|
|
101747
|
+
// effort.ts
|
|
101748
|
+
var DEFAULT_EFFORT_POSITION = 0.75;
|
|
101749
|
+
var EFFORT_ALIASES = {
|
|
101750
|
+
low: 0,
|
|
101751
|
+
medium: 0.25,
|
|
101752
|
+
high: 0.5,
|
|
101753
|
+
xhigh: 0.75,
|
|
101754
|
+
max: 1
|
|
101755
|
+
};
|
|
101756
|
+
var DISABLING_RUNGS = ["none", "minimal"];
|
|
101757
|
+
function isEffortPosition(value2) {
|
|
101758
|
+
return Number.isFinite(value2) && value2 >= 0 && value2 <= 1;
|
|
101759
|
+
}
|
|
101760
|
+
function parseEffortPosition(raw2) {
|
|
101761
|
+
const normalized = raw2.trim().toLowerCase();
|
|
101762
|
+
const named = EFFORT_ALIASES[normalized === "med" ? "medium" : normalized];
|
|
101763
|
+
if (named !== void 0) return named;
|
|
101764
|
+
const numeric = Number(normalized);
|
|
101765
|
+
return normalized !== "" && isEffortPosition(numeric) ? numeric : void 0;
|
|
101766
|
+
}
|
|
101767
|
+
function offeredRungs(published) {
|
|
101768
|
+
return published.filter((rung) => !DISABLING_RUNGS.includes(rung));
|
|
101769
|
+
}
|
|
101770
|
+
function resolveRung(params) {
|
|
101771
|
+
const rungs = offeredRungs(params.published);
|
|
101772
|
+
if (rungs.length === 0) return void 0;
|
|
101773
|
+
const clamped = Math.min(1, Math.max(0, params.position));
|
|
101774
|
+
return rungs[Math.floor(clamped * (rungs.length - 1))];
|
|
101775
|
+
}
|
|
101776
|
+
|
|
101741
101777
|
// models.ts
|
|
101742
101778
|
function provider(config3) {
|
|
101743
101779
|
return config3;
|
|
@@ -101757,6 +101793,7 @@ var providers = {
|
|
|
101757
101793
|
"claude-fable": {
|
|
101758
101794
|
displayName: "Claude Fable",
|
|
101759
101795
|
resolve: "anthropic/claude-fable-5",
|
|
101796
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
101760
101797
|
// rolling alias: models.dev's OpenRouter mirror lags brand-new pinned
|
|
101761
101798
|
// versions (claude-fable-5 isn't indexed yet), so track ~…-latest to
|
|
101762
101799
|
// stay catalog-valid and auto-follow version bumps.
|
|
@@ -101766,6 +101803,7 @@ var providers = {
|
|
|
101766
101803
|
"claude-opus": {
|
|
101767
101804
|
displayName: "Claude Opus",
|
|
101768
101805
|
resolve: "anthropic/claude-opus-5",
|
|
101806
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
101769
101807
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
101770
101808
|
preferred: true,
|
|
101771
101809
|
subagentModel: "claude-sonnet"
|
|
@@ -101773,6 +101811,7 @@ var providers = {
|
|
|
101773
101811
|
"claude-sonnet": {
|
|
101774
101812
|
displayName: "Claude Sonnet",
|
|
101775
101813
|
resolve: "anthropic/claude-sonnet-5",
|
|
101814
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
101776
101815
|
openRouterResolve: "openrouter/anthropic/claude-sonnet-5"
|
|
101777
101816
|
},
|
|
101778
101817
|
"claude-haiku": {
|
|
@@ -101790,6 +101829,7 @@ var providers = {
|
|
|
101790
101829
|
gpt: {
|
|
101791
101830
|
displayName: "GPT Sol",
|
|
101792
101831
|
resolve: "openai/gpt-5.6-sol",
|
|
101832
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
101793
101833
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
101794
101834
|
preferred: true,
|
|
101795
101835
|
subagentModel: "gpt-terra"
|
|
@@ -101801,6 +101841,7 @@ var providers = {
|
|
|
101801
101841
|
displayName: "GPT Sol Pro",
|
|
101802
101842
|
description: "Maximum reasoning effort",
|
|
101803
101843
|
resolve: "openai/gpt-5.6-sol",
|
|
101844
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
101804
101845
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
101805
101846
|
subagentModel: "gpt"
|
|
101806
101847
|
},
|
|
@@ -101810,11 +101851,13 @@ var providers = {
|
|
|
101810
101851
|
"gpt-terra": {
|
|
101811
101852
|
displayName: "GPT Terra",
|
|
101812
101853
|
resolve: "openai/gpt-5.6-terra",
|
|
101854
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
101813
101855
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
101814
101856
|
},
|
|
101815
101857
|
"gpt-mini": {
|
|
101816
101858
|
displayName: "GPT Luna",
|
|
101817
101859
|
resolve: "openai/gpt-5.6-luna",
|
|
101860
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
101818
101861
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
101819
101862
|
},
|
|
101820
101863
|
// legacy aliases — openai unified the codex line into the main GPT family
|
|
@@ -101844,6 +101887,7 @@ var providers = {
|
|
|
101844
101887
|
o3: {
|
|
101845
101888
|
displayName: "O3",
|
|
101846
101889
|
resolve: "openai/o3",
|
|
101890
|
+
effort: ["low", "medium", "high"],
|
|
101847
101891
|
openRouterResolve: "openrouter/openai/o3"
|
|
101848
101892
|
}
|
|
101849
101893
|
}
|
|
@@ -101855,6 +101899,7 @@ var providers = {
|
|
|
101855
101899
|
"gemini-pro": {
|
|
101856
101900
|
displayName: "Gemini Pro",
|
|
101857
101901
|
resolve: "google/gemini-3.1-pro-preview",
|
|
101902
|
+
effort: ["low", "medium", "high"],
|
|
101858
101903
|
openRouterResolve: "openrouter/google/gemini-3.1-pro-preview",
|
|
101859
101904
|
preferred: true
|
|
101860
101905
|
// Inherit (subagents stay on Pro). Google has no in-between tier;
|
|
@@ -101866,6 +101911,7 @@ var providers = {
|
|
|
101866
101911
|
"gemini-flash": {
|
|
101867
101912
|
displayName: "Gemini Flash",
|
|
101868
101913
|
resolve: "google/gemini-3.5-flash",
|
|
101914
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
101869
101915
|
openRouterResolve: "openrouter/google/gemini-3.5-flash"
|
|
101870
101916
|
}
|
|
101871
101917
|
}
|
|
@@ -101877,6 +101923,7 @@ var providers = {
|
|
|
101877
101923
|
grok: {
|
|
101878
101924
|
displayName: "Grok",
|
|
101879
101925
|
resolve: "xai/grok-4.3",
|
|
101926
|
+
effort: ["none", "low", "medium", "high"],
|
|
101880
101927
|
openRouterResolve: "openrouter/x-ai/grok-4.3",
|
|
101881
101928
|
preferred: true
|
|
101882
101929
|
},
|
|
@@ -101906,12 +101953,16 @@ var providers = {
|
|
|
101906
101953
|
"deepseek-pro": {
|
|
101907
101954
|
displayName: "DeepSeek Pro",
|
|
101908
101955
|
resolve: "deepseek/deepseek-v4-pro",
|
|
101956
|
+
effort: ["high", "max"],
|
|
101957
|
+
openRouterEffort: ["high", "xhigh"],
|
|
101909
101958
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro",
|
|
101910
101959
|
preferred: true
|
|
101911
101960
|
},
|
|
101912
101961
|
"deepseek-flash": {
|
|
101913
101962
|
displayName: "DeepSeek Flash",
|
|
101914
101963
|
resolve: "deepseek/deepseek-v4-flash",
|
|
101964
|
+
effort: ["high", "max"],
|
|
101965
|
+
openRouterEffort: ["high", "xhigh"],
|
|
101915
101966
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
|
|
101916
101967
|
},
|
|
101917
101968
|
// legacy aliases — deepseek retires these on 2026-07-24; transparently
|
|
@@ -101940,6 +101991,7 @@ var providers = {
|
|
|
101940
101991
|
"kimi-k3": {
|
|
101941
101992
|
displayName: "Kimi K3",
|
|
101942
101993
|
resolve: "moonshotai/kimi-k3",
|
|
101994
|
+
effort: ["low", "high", "max"],
|
|
101943
101995
|
openRouterResolve: "openrouter/moonshotai/kimi-k3",
|
|
101944
101996
|
preferred: true,
|
|
101945
101997
|
subagentModel: "kimi-k2"
|
|
@@ -101952,7 +102004,7 @@ var providers = {
|
|
|
101952
102004
|
}
|
|
101953
102005
|
}),
|
|
101954
102006
|
opencode: provider({
|
|
101955
|
-
displayName: "OpenCode",
|
|
102007
|
+
displayName: "OpenCode Zen",
|
|
101956
102008
|
envVars: ["OPENCODE_API_KEY"],
|
|
101957
102009
|
models: {
|
|
101958
102010
|
"big-pickle": {
|
|
@@ -101965,12 +102017,14 @@ var providers = {
|
|
|
101965
102017
|
"claude-opus": {
|
|
101966
102018
|
displayName: "Claude Opus",
|
|
101967
102019
|
resolve: "opencode/claude-opus-5",
|
|
102020
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
101968
102021
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
101969
102022
|
subagentModel: "claude-sonnet"
|
|
101970
102023
|
},
|
|
101971
102024
|
"claude-sonnet": {
|
|
101972
102025
|
displayName: "Claude Sonnet",
|
|
101973
102026
|
resolve: "opencode/claude-sonnet-5",
|
|
102027
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
101974
102028
|
openRouterResolve: "openrouter/anthropic/claude-sonnet-5"
|
|
101975
102029
|
},
|
|
101976
102030
|
"claude-haiku": {
|
|
@@ -101981,6 +102035,7 @@ var providers = {
|
|
|
101981
102035
|
gpt: {
|
|
101982
102036
|
displayName: "GPT Sol",
|
|
101983
102037
|
resolve: "opencode/gpt-5.6-sol",
|
|
102038
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
101984
102039
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
101985
102040
|
subagentModel: "gpt-terra"
|
|
101986
102041
|
},
|
|
@@ -101989,6 +102044,7 @@ var providers = {
|
|
|
101989
102044
|
displayName: "GPT Sol Pro",
|
|
101990
102045
|
description: "Maximum reasoning effort",
|
|
101991
102046
|
resolve: "opencode/gpt-5.6-sol",
|
|
102047
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
101992
102048
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
101993
102049
|
subagentModel: "gpt"
|
|
101994
102050
|
},
|
|
@@ -101996,11 +102052,13 @@ var providers = {
|
|
|
101996
102052
|
"gpt-terra": {
|
|
101997
102053
|
displayName: "GPT Terra",
|
|
101998
102054
|
resolve: "opencode/gpt-5.6-terra",
|
|
102055
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
101999
102056
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
102000
102057
|
},
|
|
102001
102058
|
"gpt-mini": {
|
|
102002
102059
|
displayName: "GPT Luna",
|
|
102003
102060
|
resolve: "opencode/gpt-5.6-luna",
|
|
102061
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
102004
102062
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
102005
102063
|
},
|
|
102006
102064
|
// legacy aliases — see openai provider above for context.
|
|
@@ -102026,12 +102084,14 @@ var providers = {
|
|
|
102026
102084
|
"gemini-pro": {
|
|
102027
102085
|
displayName: "Gemini Pro",
|
|
102028
102086
|
resolve: "opencode/gemini-3.1-pro",
|
|
102087
|
+
effort: ["low", "medium", "high"],
|
|
102029
102088
|
openRouterResolve: "openrouter/google/gemini-3.1-pro-preview"
|
|
102030
102089
|
// Inherit — see google/gemini-pro for rationale.
|
|
102031
102090
|
},
|
|
102032
102091
|
"gemini-flash": {
|
|
102033
102092
|
displayName: "Gemini Flash",
|
|
102034
102093
|
resolve: "opencode/gemini-3.5-flash",
|
|
102094
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
102035
102095
|
openRouterResolve: "openrouter/google/gemini-3.5-flash"
|
|
102036
102096
|
},
|
|
102037
102097
|
"kimi-k2": {
|
|
@@ -102050,6 +102110,7 @@ var providers = {
|
|
|
102050
102110
|
"gpt-5-nano": {
|
|
102051
102111
|
displayName: "GPT Nano",
|
|
102052
102112
|
resolve: "opencode/gpt-5-nano",
|
|
102113
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
102053
102114
|
openRouterResolve: "openrouter/openai/gpt-5-nano"
|
|
102054
102115
|
},
|
|
102055
102116
|
"mimo-v2-pro-free": {
|
|
@@ -102076,6 +102137,8 @@ var providers = {
|
|
|
102076
102137
|
"glm-5.1": {
|
|
102077
102138
|
displayName: "GLM 5.2",
|
|
102078
102139
|
resolve: "opencode-go/glm-5.2",
|
|
102140
|
+
effort: ["high", "max"],
|
|
102141
|
+
openRouterEffort: ["high", "xhigh"],
|
|
102079
102142
|
openRouterResolve: "openrouter/z-ai/glm-5.2",
|
|
102080
102143
|
preferred: true
|
|
102081
102144
|
},
|
|
@@ -102129,6 +102192,10 @@ var providers = {
|
|
|
102129
102192
|
// bring-your-own generic OpenAI-compatible endpoint — Cloudflare AI Gateway,
|
|
102130
102193
|
// Alibaba DashScope, self-hosted vLLM, or any compatible gateway. base URL +
|
|
102131
102194
|
// key + model ID are all supplied via env; nothing is cataloged or bumped.
|
|
102195
|
+
// the two token limits are deliberately absent: this list is the auth
|
|
102196
|
+
// heuristic (`hasPullfrogStoredAuthForModel`, `validateAgentApiKey`), and a
|
|
102197
|
+
// stored context number is config, not proof of a key. the console picks
|
|
102198
|
+
// them up from `PROVIDER_EXTRA_SECRET_NAMES` instead.
|
|
102132
102199
|
envVars: ["OPENAI_COMPATIBLE_BASE_URL", "OPENAI_COMPATIBLE_API_KEY", "OPENAI_COMPATIBLE_MODEL"],
|
|
102133
102200
|
models: {
|
|
102134
102201
|
// single routing entry — the actual model ID is read from
|
|
@@ -102148,6 +102215,7 @@ var providers = {
|
|
|
102148
102215
|
"claude-opus": {
|
|
102149
102216
|
displayName: "Claude Opus",
|
|
102150
102217
|
resolve: "openrouter/~anthropic/claude-opus-latest",
|
|
102218
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
102151
102219
|
openRouterResolve: "openrouter/~anthropic/claude-opus-latest",
|
|
102152
102220
|
preferred: true,
|
|
102153
102221
|
subagentModel: "claude-sonnet"
|
|
@@ -102155,6 +102223,7 @@ var providers = {
|
|
|
102155
102223
|
"claude-sonnet": {
|
|
102156
102224
|
displayName: "Claude Sonnet",
|
|
102157
102225
|
resolve: "openrouter/~anthropic/claude-sonnet-latest",
|
|
102226
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
102158
102227
|
openRouterResolve: "openrouter/~anthropic/claude-sonnet-latest"
|
|
102159
102228
|
},
|
|
102160
102229
|
"claude-haiku": {
|
|
@@ -102169,6 +102238,7 @@ var providers = {
|
|
|
102169
102238
|
gpt: {
|
|
102170
102239
|
displayName: "GPT Sol",
|
|
102171
102240
|
resolve: "openrouter/openai/gpt-5.6-sol",
|
|
102241
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
102172
102242
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
102173
102243
|
subagentModel: "gpt-terra"
|
|
102174
102244
|
},
|
|
@@ -102177,6 +102247,7 @@ var providers = {
|
|
|
102177
102247
|
displayName: "GPT Sol Pro",
|
|
102178
102248
|
description: "Maximum reasoning effort",
|
|
102179
102249
|
resolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
102250
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
102180
102251
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
102181
102252
|
subagentModel: "gpt"
|
|
102182
102253
|
},
|
|
@@ -102184,11 +102255,13 @@ var providers = {
|
|
|
102184
102255
|
"gpt-terra": {
|
|
102185
102256
|
displayName: "GPT Terra",
|
|
102186
102257
|
resolve: "openrouter/openai/gpt-5.6-terra",
|
|
102258
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
102187
102259
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
102188
102260
|
},
|
|
102189
102261
|
"gpt-mini": {
|
|
102190
102262
|
displayName: "GPT Luna",
|
|
102191
102263
|
resolve: "openrouter/openai/gpt-5.6-luna",
|
|
102264
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
102192
102265
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
102193
102266
|
},
|
|
102194
102267
|
// legacy aliases — see openai provider for context.
|
|
@@ -102214,32 +102287,38 @@ var providers = {
|
|
|
102214
102287
|
"o4-mini": {
|
|
102215
102288
|
displayName: "O4 Mini",
|
|
102216
102289
|
resolve: "openrouter/openai/o4-mini",
|
|
102290
|
+
effort: ["low", "medium", "high"],
|
|
102217
102291
|
openRouterResolve: "openrouter/openai/o4-mini"
|
|
102218
102292
|
},
|
|
102219
102293
|
"gemini-pro": {
|
|
102220
102294
|
displayName: "Gemini Pro",
|
|
102221
102295
|
resolve: "openrouter/~google/gemini-pro-latest",
|
|
102296
|
+
effort: ["low", "medium", "high"],
|
|
102222
102297
|
openRouterResolve: "openrouter/~google/gemini-pro-latest"
|
|
102223
102298
|
// Inherit — see google/gemini-pro for rationale.
|
|
102224
102299
|
},
|
|
102225
102300
|
"gemini-flash": {
|
|
102226
102301
|
displayName: "Gemini Flash",
|
|
102227
102302
|
resolve: "openrouter/~google/gemini-flash-latest",
|
|
102303
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
102228
102304
|
openRouterResolve: "openrouter/~google/gemini-flash-latest"
|
|
102229
102305
|
},
|
|
102230
102306
|
grok: {
|
|
102231
102307
|
displayName: "Grok",
|
|
102232
102308
|
resolve: "openrouter/x-ai/grok-4.3",
|
|
102309
|
+
effort: ["none", "low", "medium", "high"],
|
|
102233
102310
|
openRouterResolve: "openrouter/x-ai/grok-4.3"
|
|
102234
102311
|
},
|
|
102235
102312
|
"deepseek-pro": {
|
|
102236
102313
|
displayName: "DeepSeek Pro",
|
|
102237
102314
|
resolve: "openrouter/deepseek/deepseek-v4-pro",
|
|
102315
|
+
effort: ["high", "xhigh"],
|
|
102238
102316
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro"
|
|
102239
102317
|
},
|
|
102240
102318
|
"deepseek-flash": {
|
|
102241
102319
|
displayName: "DeepSeek Flash",
|
|
102242
102320
|
resolve: "openrouter/deepseek/deepseek-v4-flash",
|
|
102321
|
+
effort: ["high", "xhigh"],
|
|
102243
102322
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
|
|
102244
102323
|
},
|
|
102245
102324
|
// legacy alias — deepseek retires this on 2026-07-24; transparently
|
|
@@ -102258,6 +102337,7 @@ var providers = {
|
|
|
102258
102337
|
"kimi-k3": {
|
|
102259
102338
|
displayName: "Kimi K3",
|
|
102260
102339
|
resolve: "openrouter/moonshotai/kimi-k3",
|
|
102340
|
+
effort: ["low", "high", "max"],
|
|
102261
102341
|
openRouterResolve: "openrouter/moonshotai/kimi-k3"
|
|
102262
102342
|
},
|
|
102263
102343
|
// slug pins the m2 line for DB stability; resolve tracks the current m2.7.
|
|
@@ -102312,6 +102392,8 @@ var modelAliases = Object.entries(providers).flatMap(
|
|
|
102312
102392
|
// here to a fully-qualified slug so callers can look up the target alias
|
|
102313
102393
|
// directly without re-deriving the provider.
|
|
102314
102394
|
subagentModel: def.subagentModel ? `${providerKey}/${def.subagentModel}` : void 0,
|
|
102395
|
+
effort: def.effort,
|
|
102396
|
+
openRouterEffort: def.openRouterEffort,
|
|
102315
102397
|
hidden: def.hidden ?? false
|
|
102316
102398
|
}))
|
|
102317
102399
|
);
|
|
@@ -102350,6 +102432,17 @@ function resolveCliModel(slug2) {
|
|
|
102350
102432
|
function resolveOpenRouterModel(slug2) {
|
|
102351
102433
|
return resolveDisplayAlias(slug2)?.openRouterResolve;
|
|
102352
102434
|
}
|
|
102435
|
+
function getModelEffortLevels(params) {
|
|
102436
|
+
const alias = resolveDisplayAlias(params.slug);
|
|
102437
|
+
if (!alias) return void 0;
|
|
102438
|
+
if (params.useOpenRouter) return alias.openRouterEffort ?? alias.effort;
|
|
102439
|
+
return alias.effort;
|
|
102440
|
+
}
|
|
102441
|
+
function resolveModelRung(params) {
|
|
102442
|
+
const published = getModelEffortLevels(params);
|
|
102443
|
+
if (!published) return void 0;
|
|
102444
|
+
return resolveRung({ position: params.position, published });
|
|
102445
|
+
}
|
|
102353
102446
|
var defaultProxyAlias = resolveDisplayAlias(AUTO_EFFICIENT);
|
|
102354
102447
|
if (!defaultProxyAlias?.openRouterResolve) {
|
|
102355
102448
|
throw new Error(`DEFAULT_PROXY_MODEL: ${AUTO_EFFICIENT} has no openRouterResolve`);
|
|
@@ -103037,6 +103130,40 @@ function extractProviderId(text) {
|
|
|
103037
103130
|
return match3 ? match3[1].toLowerCase() : null;
|
|
103038
103131
|
}
|
|
103039
103132
|
|
|
103133
|
+
// utils/runEffort.ts
|
|
103134
|
+
function matchHostedAnthropicAlias(modelId) {
|
|
103135
|
+
const id = modelId.toLowerCase();
|
|
103136
|
+
if (id.startsWith("arn:")) return void 0;
|
|
103137
|
+
return modelAliases.find(
|
|
103138
|
+
(a) => !a.fallback && a.provider === "anthropic" && id.includes(a.resolve.replace(/^anthropic\//, ""))
|
|
103139
|
+
);
|
|
103140
|
+
}
|
|
103141
|
+
function resolveRunAlias(ctx) {
|
|
103142
|
+
const proxyModel = ctx.payload.proxyModel;
|
|
103143
|
+
if (proxyModel) {
|
|
103144
|
+
return modelAliases.find((a) => !a.fallback && a.openRouterResolve === proxyModel);
|
|
103145
|
+
}
|
|
103146
|
+
const model = ctx.resolvedModel;
|
|
103147
|
+
if (!model) return void 0;
|
|
103148
|
+
return modelAliases.find((a) => !a.fallback && a.resolve === model) ?? matchHostedAnthropicAlias(model);
|
|
103149
|
+
}
|
|
103150
|
+
function resolveRunEffort(ctx) {
|
|
103151
|
+
const configured = ctx.payload.effort !== void 0;
|
|
103152
|
+
const position = ctx.payload.effort ?? DEFAULT_EFFORT_POSITION;
|
|
103153
|
+
const alias = resolveRunAlias(ctx);
|
|
103154
|
+
if (!alias) return { position, configured, rung: void 0, alias: void 0 };
|
|
103155
|
+
return {
|
|
103156
|
+
position,
|
|
103157
|
+
configured,
|
|
103158
|
+
rung: resolveModelRung({
|
|
103159
|
+
slug: alias.slug,
|
|
103160
|
+
position,
|
|
103161
|
+
useOpenRouter: !!ctx.payload.proxyModel
|
|
103162
|
+
}),
|
|
103163
|
+
alias
|
|
103164
|
+
};
|
|
103165
|
+
}
|
|
103166
|
+
|
|
103040
103167
|
// utils/skills.ts
|
|
103041
103168
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
103042
103169
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
@@ -103050,7 +103177,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
103050
103177
|
// package.json
|
|
103051
103178
|
var package_default = {
|
|
103052
103179
|
name: "pullfrog",
|
|
103053
|
-
version: "0.1.
|
|
103180
|
+
version: "0.1.48",
|
|
103054
103181
|
type: "module",
|
|
103055
103182
|
bin: {
|
|
103056
103183
|
pullfrog: "dist/cli.mjs",
|
|
@@ -104610,8 +104737,18 @@ function stripProviderPrefix(specifier) {
|
|
|
104610
104737
|
const slashIndex = specifier.indexOf("/");
|
|
104611
104738
|
return slashIndex > 0 ? specifier.slice(slashIndex + 1) : specifier;
|
|
104612
104739
|
}
|
|
104613
|
-
|
|
104614
|
-
|
|
104740
|
+
var CLAUDE_EFFORT_ENV = "CLAUDE_CODE_EFFORT_LEVEL";
|
|
104741
|
+
var CLAUDE_CODE_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
104742
|
+
function effortCapabilities(levels) {
|
|
104743
|
+
const topRungs = levels.filter((l) => l === "xhigh" || l === "max").map((l) => `${l}_effort`);
|
|
104744
|
+
return ["effort", ...topRungs, "adaptive_thinking", "thinking"].join(",");
|
|
104745
|
+
}
|
|
104746
|
+
function applyHostedEffortCapabilities(params) {
|
|
104747
|
+
params.env.ANTHROPIC_MODEL ||= params.modelId;
|
|
104748
|
+
params.env.ANTHROPIC_CUSTOM_MODEL_OPTION ||= params.modelId;
|
|
104749
|
+
params.env.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES ||= effortCapabilities(
|
|
104750
|
+
params.levels
|
|
104751
|
+
);
|
|
104615
104752
|
}
|
|
104616
104753
|
function tailLines2(text, maxCodeUnits) {
|
|
104617
104754
|
if (text.length <= maxCodeUnits) return text;
|
|
@@ -105087,7 +105224,7 @@ var claude = agent({
|
|
|
105087
105224
|
});
|
|
105088
105225
|
installBundledSkills({ home: homeEnv.HOME });
|
|
105089
105226
|
const mcpConfigPath = writeMcpConfig(ctx);
|
|
105090
|
-
const effort =
|
|
105227
|
+
const effort = resolveRunEffort(ctx);
|
|
105091
105228
|
const pretoolGate = writePretoolGateAssets(ctx);
|
|
105092
105229
|
const stopHookPath = join5(ctx.tmpdir, "pullfrog-stop-hook.sh");
|
|
105093
105230
|
writeFileSync4(stopHookPath, buildStopHookScript(), { mode: 493 });
|
|
@@ -105101,13 +105238,16 @@ var claude = agent({
|
|
|
105101
105238
|
"--settings",
|
|
105102
105239
|
pretoolGate.settingsPath,
|
|
105103
105240
|
"--verbose",
|
|
105104
|
-
"--effort",
|
|
105105
|
-
effort,
|
|
105106
105241
|
"--disallowedTools",
|
|
105107
105242
|
CLAUDE_DISALLOWED_TOOLS,
|
|
105108
105243
|
"--agents",
|
|
105109
105244
|
buildAgentsJson()
|
|
105110
105245
|
];
|
|
105246
|
+
if (effort.rung && !CLAUDE_CODE_EFFORTS.includes(effort.rung)) {
|
|
105247
|
+
log.warning(`\xBB effort ${effort.rung} not sent \u2014 claude-code doesn't accept that level`);
|
|
105248
|
+
} else if (effort.rung) {
|
|
105249
|
+
baseArgs.push("--effort", effort.rung);
|
|
105250
|
+
}
|
|
105111
105251
|
if (model) {
|
|
105112
105252
|
baseArgs.push("--model", model);
|
|
105113
105253
|
}
|
|
@@ -105125,6 +105265,9 @@ var claude = agent({
|
|
|
105125
105265
|
applyClaudeVertexEnv(env2);
|
|
105126
105266
|
env2.ANTHROPIC_MODEL = specifier;
|
|
105127
105267
|
}
|
|
105268
|
+
if ((isBedrockRoute || isVertexRoute2) && specifier && effort.alias?.effort) {
|
|
105269
|
+
applyHostedEffortCapabilities({ env: env2, modelId: specifier, levels: effort.alias.effort });
|
|
105270
|
+
}
|
|
105128
105271
|
if (env2.CLAUDE_CODE_OAUTH_TOKEN && !isBedrockRoute && env2.ANTHROPIC_API_KEY) {
|
|
105129
105272
|
const preflight = await preflightClaudeSubscription({
|
|
105130
105273
|
token: env2.CLAUDE_CODE_OAUTH_TOKEN,
|
|
@@ -105142,7 +105285,12 @@ var claude = agent({
|
|
|
105142
105285
|
delete env2.CLAUDE_CODE_OAUTH_TOKEN;
|
|
105143
105286
|
}
|
|
105144
105287
|
}
|
|
105145
|
-
|
|
105288
|
+
const effortEnvOverride = env2[CLAUDE_EFFORT_ENV]?.trim();
|
|
105289
|
+
if (effortEnvOverride) {
|
|
105290
|
+
log.warning(
|
|
105291
|
+
`\xBB ${CLAUDE_EFFORT_ENV}=${effortEnvOverride} in the run env overrides the effort setting for this session`
|
|
105292
|
+
);
|
|
105293
|
+
}
|
|
105146
105294
|
log.debug(`\xBB starting Pullfrog (Claude Code): ${cliPath} ${baseArgs.join(" ")}`);
|
|
105147
105295
|
log.debug(`\xBB working directory: ${repoDir}`);
|
|
105148
105296
|
const gateServer = __using(_stack, await startGateServer(ctx), true);
|
|
@@ -105166,7 +105314,7 @@ var claude = agent({
|
|
|
105166
105314
|
}
|
|
105167
105315
|
});
|
|
105168
105316
|
|
|
105169
|
-
// agents/
|
|
105317
|
+
// agents/opencode.ts
|
|
105170
105318
|
var core2 = __toESM(require_core(), 1);
|
|
105171
105319
|
import { spawn as nodeSpawn2 } from "node:child_process";
|
|
105172
105320
|
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
@@ -110576,7 +110724,7 @@ function createOpencodeClient(config3) {
|
|
|
110576
110724
|
// node_modules/.pnpm/@opencode-ai+sdk@1.18.5/node_modules/@opencode-ai/sdk/dist/v2/server.js
|
|
110577
110725
|
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
110578
110726
|
|
|
110579
|
-
// agents/
|
|
110727
|
+
// agents/opencode.ts
|
|
110580
110728
|
var import_undici = __toESM(require_undici2(), 1);
|
|
110581
110729
|
|
|
110582
110730
|
// utils/codexHome.ts
|
|
@@ -110849,14 +110997,6 @@ function deriveSubagentModels(orchestratorSpec) {
|
|
|
110849
110997
|
}
|
|
110850
110998
|
|
|
110851
110999
|
// agents/opencodeShared.ts
|
|
110852
|
-
function geminiHighThinkingOverrides() {
|
|
110853
|
-
return Object.fromEntries(
|
|
110854
|
-
modelAliases.filter((a) => a.provider === "google").map((a) => [
|
|
110855
|
-
a.resolve.replace(/^google\//, ""),
|
|
110856
|
-
{ options: { thinkingConfig: { thinkingLevel: "high" } } }
|
|
110857
|
-
])
|
|
110858
|
-
);
|
|
110859
|
-
}
|
|
110860
111000
|
function openAICompatibleLimit() {
|
|
110861
111001
|
return {
|
|
110862
111002
|
context: Number(process.env[OPENAI_COMPATIBLE_CONTEXT_ENV]),
|
|
@@ -110889,10 +111029,6 @@ function kimiOpenRouterProviderOverrides() {
|
|
|
110889
111029
|
])
|
|
110890
111030
|
);
|
|
110891
111031
|
}
|
|
110892
|
-
function deepseekHighEffortOverrides() {
|
|
110893
|
-
const orModel = modelAliases.find((a) => a.slug === "deepseek/deepseek-pro")?.openRouterResolve?.replace(/^openrouter\//, "");
|
|
110894
|
-
return orModel ? { [orModel]: { options: { reasoning: { effort: "high" } } } } : {};
|
|
110895
|
-
}
|
|
110896
111032
|
function buildReviewerAgentConfig(orchestratorModel) {
|
|
110897
111033
|
const overrides = deriveSubagentModels(orchestratorModel);
|
|
110898
111034
|
return {
|
|
@@ -110934,7 +111070,7 @@ function autoSelectModel() {
|
|
|
110934
111070
|
return void 0;
|
|
110935
111071
|
}
|
|
110936
111072
|
|
|
110937
|
-
// agents/
|
|
111073
|
+
// agents/opencode.ts
|
|
110938
111074
|
var installCli = () => installOpencodeCli({ binPath: "bin/opencode.exe" });
|
|
110939
111075
|
function buildSecurityConfig(ctx, model) {
|
|
110940
111076
|
const config3 = {
|
|
@@ -110961,17 +111097,13 @@ function buildSecurityConfig(ctx, model) {
|
|
|
110961
111097
|
log.info(`\xBB subagent models: reviewfrog=${reviewerModel}`);
|
|
110962
111098
|
return cfg;
|
|
110963
111099
|
})(),
|
|
110964
|
-
//
|
|
110965
|
-
//
|
|
110966
|
-
//
|
|
110967
|
-
//
|
|
110968
|
-
//
|
|
110969
|
-
// upstream default, anthropic: --effort flag in claude.ts). see opencodeShared.ts.
|
|
111100
|
+
// kimi pinned away from Enforcer-less openrouter providers (siliconflow /
|
|
111101
|
+
// together) that drop optional tool-call params — per-model on the
|
|
111102
|
+
// openrouter route, so other models are unaffected. this is routing, not
|
|
111103
|
+
// reasoning: every model's effort now rides the per-prompt `variant`.
|
|
111104
|
+
// see opencodeShared.ts.
|
|
110970
111105
|
provider: {
|
|
110971
|
-
|
|
110972
|
-
openrouter: {
|
|
110973
|
-
models: { ...deepseekHighEffortOverrides(), ...kimiOpenRouterProviderOverrides() }
|
|
110974
|
-
},
|
|
111106
|
+
openrouter: { models: kimiOpenRouterProviderOverrides() },
|
|
110975
111107
|
...openAICompatibleProvider(model)
|
|
110976
111108
|
}
|
|
110977
111109
|
};
|
|
@@ -111282,6 +111414,7 @@ async function runPromptTurn(ctx, params) {
|
|
|
111282
111414
|
{
|
|
111283
111415
|
sessionID: ctx.sessionID,
|
|
111284
111416
|
parts: [part],
|
|
111417
|
+
...ctx.variant ? { variant: ctx.variant } : {},
|
|
111285
111418
|
...params.model ? { model: params.model } : {}
|
|
111286
111419
|
},
|
|
111287
111420
|
// wire the inner activity watchdog's abort signal into the SDK request
|
|
@@ -111471,6 +111604,10 @@ var opencode = agent({
|
|
|
111471
111604
|
const cliPath = await installCli();
|
|
111472
111605
|
const rawModel = ctx.payload.proxyModel ?? ctx.resolvedModel ?? autoSelectModel();
|
|
111473
111606
|
if (rawModel) ctx.toolState.model = rawModel;
|
|
111607
|
+
const effort = resolveRunEffort({ ...ctx, resolvedModel: rawModel });
|
|
111608
|
+
if (!ctx.resolvedModel && !ctx.payload.proxyModel) {
|
|
111609
|
+
log.info(`\xBB effort: ${effort.rung ?? "n/a (model has no effort control)"}`);
|
|
111610
|
+
}
|
|
111474
111611
|
const bedrockModelId = process.env[BEDROCK_MODEL_ID_ENV]?.trim();
|
|
111475
111612
|
const isBedrockRoute = rawModel !== void 0 && bedrockModelId !== void 0 && bedrockModelId === rawModel;
|
|
111476
111613
|
const vertexModel = resolveVertexOpenCodeModel(rawModel);
|
|
@@ -111563,6 +111700,8 @@ var opencode = agent({
|
|
|
111563
111700
|
orchestratorSessionID: sessionID,
|
|
111564
111701
|
labeler,
|
|
111565
111702
|
toolState: ctx.toolState,
|
|
111703
|
+
// `rawModel` folds in the auto-select pick — see the opencode.ts twin.
|
|
111704
|
+
variant: effort.rung,
|
|
111566
111705
|
todoTracker: ctx.todoTracker,
|
|
111567
111706
|
onActivityTimeout: ctx.onActivityTimeout,
|
|
111568
111707
|
onToolUse: ctx.onToolUse,
|
|
@@ -159948,6 +160087,7 @@ var JsonPayload = type({
|
|
|
159948
160087
|
version: "string",
|
|
159949
160088
|
"model?": "string | undefined",
|
|
159950
160089
|
"modelExplicit?": "boolean | undefined",
|
|
160090
|
+
"effort?": "number | string | undefined",
|
|
159951
160091
|
prompt: "string",
|
|
159952
160092
|
"triggerer?": "string | undefined",
|
|
159953
160093
|
"baseInstructions?": "string | undefined",
|
|
@@ -159967,6 +160107,9 @@ var JsonPayload = type({
|
|
|
159967
160107
|
id: "string",
|
|
159968
160108
|
type: "'issue' | 'review'"
|
|
159969
160109
|
}).or("undefined"),
|
|
160110
|
+
// optional so a payload from an older server build (pre-`checkRun`) still parses
|
|
160111
|
+
// against a newer action across a rolling deploy.
|
|
160112
|
+
"checkRun?": type({ id: "string" }).or("undefined"),
|
|
159970
160113
|
"generateSummary?": "boolean | undefined"
|
|
159971
160114
|
});
|
|
159972
160115
|
var COLLABORATOR_PERMISSIONS = ["admin", "maintain", "write"];
|
|
@@ -159978,6 +160121,7 @@ var Inputs = type({
|
|
|
159978
160121
|
"prompt?": type.string.or("undefined"),
|
|
159979
160122
|
"prompt_file?": type.string.or("undefined"),
|
|
159980
160123
|
"model?": type.string.or("undefined"),
|
|
160124
|
+
"effort?": type.string.or("undefined"),
|
|
159981
160125
|
"timeout?": type.string.or("undefined"),
|
|
159982
160126
|
"push?": PushPermissionInput.or("undefined"),
|
|
159983
160127
|
"shell?": ShellPermissionInput.or("undefined"),
|
|
@@ -160032,6 +160176,7 @@ function resolvePromptFile(input) {
|
|
|
160032
160176
|
function resolveNonPromptInputs() {
|
|
160033
160177
|
return Inputs.omit("prompt", "prompt_file").assert({
|
|
160034
160178
|
model: core4.getInput("model") || void 0,
|
|
160179
|
+
effort: core4.getInput("effort") || void 0,
|
|
160035
160180
|
timeout: core4.getInput("timeout") || void 0,
|
|
160036
160181
|
cwd: core4.getInput("cwd") || void 0,
|
|
160037
160182
|
push: core4.getInput("push") || void 0,
|
|
@@ -160050,6 +160195,8 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
160050
160195
|
const rawEvent = jsonPayload?.event;
|
|
160051
160196
|
const event = isPayloadEvent(rawEvent) ? rawEvent : { trigger: "unknown" };
|
|
160052
160197
|
const model = jsonPayload?.model ?? inputs.model ?? repoSettings.model ?? void 0;
|
|
160198
|
+
const rawEffort = jsonPayload?.effort ?? inputs.effort ?? repoSettings.effort ?? void 0;
|
|
160199
|
+
const effort = rawEffort === void 0 ? void 0 : parseEffortPosition(String(rawEffort));
|
|
160053
160200
|
const isNonCollaborator = !isCollaborator(event);
|
|
160054
160201
|
const repoShell = repoSettings.shell ?? "restricted";
|
|
160055
160202
|
const inputShell = inputs.shell;
|
|
@@ -160069,6 +160216,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
160069
160216
|
// explicit only when the model came from a per-run override flag (carried on
|
|
160070
160217
|
// the JSON payload). a GHA `model` input or the repo default is not explicit.
|
|
160071
160218
|
modelExplicit: jsonPayload?.modelExplicit ?? false,
|
|
160219
|
+
effort,
|
|
160072
160220
|
prompt,
|
|
160073
160221
|
triggerer: jsonPayload?.triggerer ?? // it's not a common use case but GITHUB_ACTOR can be a user when the workflow is manually triggered by a user through GitHub Actions UI
|
|
160074
160222
|
(!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
|
|
@@ -160080,13 +160228,19 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
160080
160228
|
timeout: inputs.timeout ?? jsonPayload?.timeout,
|
|
160081
160229
|
cwd: resolveCwd(inputs.cwd),
|
|
160082
160230
|
progressComment: jsonPayload?.progressComment,
|
|
160231
|
+
checkRun: jsonPayload?.checkRun,
|
|
160083
160232
|
generateSummary: jsonPayload?.generateSummary,
|
|
160084
160233
|
// permissions: inputs > repoSettings > fallbacks
|
|
160085
160234
|
push: inputs.push ?? repoSettings.push ?? "restricted",
|
|
160086
160235
|
shell: resolvedShell,
|
|
160087
|
-
//
|
|
160088
|
-
//
|
|
160089
|
-
|
|
160236
|
+
// the `pullfrog` run-lifecycle check. ON by default — the whole point is that a PR
|
|
160237
|
+
// shows whether Pullfrog is running without anyone having to opt in. the workflow
|
|
160238
|
+
// input is the source of truth when set (mirrors `push`); otherwise the repo
|
|
160239
|
+
// setting decides.
|
|
160240
|
+
runStatusCheck: inputs.status_checks === void 0 ? repoSettings.statusChecks : inputs.status_checks === "enabled",
|
|
160241
|
+
// the `pullfrog-approval` verdict check stays opt-in and workflow-only. it exists to
|
|
160242
|
+
// be *required* by branch protection, so it must never turn itself on.
|
|
160243
|
+
approvalCheck: inputs.status_checks === "enabled",
|
|
160090
160244
|
// temporary progress chrome. the workflow input is the source of truth when
|
|
160091
160245
|
// set (mirrors `push`); otherwise the repo setting decides. defaults to true.
|
|
160092
160246
|
progressComments: inputs.progress_comments === void 0 ? repoSettings.progressComments : inputs.progress_comments === "enabled",
|
|
@@ -160614,7 +160768,11 @@ async function approveAfterFix(ctx) {
|
|
|
160614
160768
|
approved: true,
|
|
160615
160769
|
hasComments: false
|
|
160616
160770
|
});
|
|
160617
|
-
ctx.toolState.approval = {
|
|
160771
|
+
ctx.toolState.approval = {
|
|
160772
|
+
wouldApprove: true,
|
|
160773
|
+
sha: headSha,
|
|
160774
|
+
url: result.data.html_url
|
|
160775
|
+
};
|
|
160618
160776
|
log.info(`\xBB auto-approved #${pullNumber} after fix run (review ${result.data.id})`);
|
|
160619
160777
|
await deleteProgressComment(ctx).catch((err) => {
|
|
160620
160778
|
log.debug(`progress comment cleanup after fix auto-approval failed: ${err}`);
|
|
@@ -160947,6 +161105,7 @@ function CreatePullRequestReviewTool(ctx) {
|
|
|
160947
161105
|
}
|
|
160948
161106
|
const reviewId = result.data.id;
|
|
160949
161107
|
const reviewNodeId = result.data.node_id;
|
|
161108
|
+
if (ctx.toolState.approval) ctx.toolState.approval.url = result.data.html_url;
|
|
160950
161109
|
log.info(`\xBB created review ${reviewId} on pull request #${pull_number}`);
|
|
160951
161110
|
const actuallyReviewedSha = primary.checkoutSha ?? params.commit_id;
|
|
160952
161111
|
ctx.toolState.review = {
|
|
@@ -165523,6 +165682,140 @@ function formatApiKeyErrorSummary(params) {
|
|
|
165523
165682
|
].join("\n");
|
|
165524
165683
|
}
|
|
165525
165684
|
|
|
165685
|
+
// utils/billingErrors.ts
|
|
165686
|
+
var BillingError = class extends Error {
|
|
165687
|
+
code;
|
|
165688
|
+
declineCode;
|
|
165689
|
+
needsReauthentication;
|
|
165690
|
+
constructor(message, opts = {}) {
|
|
165691
|
+
super(message);
|
|
165692
|
+
this.name = "BillingError";
|
|
165693
|
+
this.code = opts.code ?? null;
|
|
165694
|
+
this.declineCode = opts.declineCode ?? null;
|
|
165695
|
+
this.needsReauthentication = opts.needsReauthentication ?? false;
|
|
165696
|
+
}
|
|
165697
|
+
};
|
|
165698
|
+
var TransientError = class extends Error {
|
|
165699
|
+
constructor(message) {
|
|
165700
|
+
super(message);
|
|
165701
|
+
this.name = "TransientError";
|
|
165702
|
+
}
|
|
165703
|
+
};
|
|
165704
|
+
function billingConsoleUrl(owner) {
|
|
165705
|
+
return `https://pullfrog.com/console/${encodeURIComponent(owner)}#billing`;
|
|
165706
|
+
}
|
|
165707
|
+
function commercialPaywallBody(params) {
|
|
165708
|
+
if (params.reason === "commercial") {
|
|
165709
|
+
return [
|
|
165710
|
+
`**Pullfrog needs a confirmed Pro plan for ${params.ownerLogin}, so this run paused.**`,
|
|
165711
|
+
"",
|
|
165712
|
+
"Open Plan and payment to confirm Pro or review the organization's billing status.",
|
|
165713
|
+
"",
|
|
165714
|
+
`[Review plan and payment \u2192](${params.url})`
|
|
165715
|
+
].join("\n");
|
|
165716
|
+
}
|
|
165717
|
+
params.reason;
|
|
165718
|
+
return [
|
|
165719
|
+
`**Pullfrog paused runs on ${params.ownerLogin}: the Pro renewal failed.**`,
|
|
165720
|
+
"",
|
|
165721
|
+
"Update the card on file to resume runs.",
|
|
165722
|
+
"",
|
|
165723
|
+
`[Update billing \u2192](${params.url})`
|
|
165724
|
+
].join("\n");
|
|
165725
|
+
}
|
|
165726
|
+
function formatCommercialGateSummary(params) {
|
|
165727
|
+
return commercialPaywallBody({
|
|
165728
|
+
reason: params.reason,
|
|
165729
|
+
ownerLogin: params.ownerLogin,
|
|
165730
|
+
url: billingConsoleUrl(params.ownerLogin)
|
|
165731
|
+
});
|
|
165732
|
+
}
|
|
165733
|
+
function formatBillingErrorSummary(error49, owner) {
|
|
165734
|
+
if (error49.code === "router_requires_card") {
|
|
165735
|
+
return [
|
|
165736
|
+
"**Your Pullfrog Router balance is empty.**",
|
|
165737
|
+
"",
|
|
165738
|
+
"Add a card to top up your Router balance, or bring your own key. Router usage is billed at provider cost with no platform markup.",
|
|
165739
|
+
"",
|
|
165740
|
+
`[Add a card to top up \u2192](${billingConsoleUrl(owner)}) \xB7 [Bring your own key \u2192](${billingConsoleUrl(owner)})`
|
|
165741
|
+
].join("\n");
|
|
165742
|
+
}
|
|
165743
|
+
if (error49.code === "router_balance_exhausted") {
|
|
165744
|
+
return [
|
|
165745
|
+
"**Your Pullfrog Router balance is exhausted.**",
|
|
165746
|
+
"",
|
|
165747
|
+
"You have a payment method on file but auto-reload is disabled, so runs paused once your balance went past the overdraft buffer.",
|
|
165748
|
+
"",
|
|
165749
|
+
`[Top up balance \u2192](${billingConsoleUrl(owner)}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner)})`
|
|
165750
|
+
].join("\n");
|
|
165751
|
+
}
|
|
165752
|
+
if (error49.code === "router_keylimit_exhausted") {
|
|
165753
|
+
return [
|
|
165754
|
+
"**This run was cut short: your Pullfrog Router balance ran out mid-run.**",
|
|
165755
|
+
"",
|
|
165756
|
+
"OpenRouter stopped the agent because the per-run budget was exhausted. Your wallet is now negative; top up or enable auto-reload to keep runs flowing.",
|
|
165757
|
+
"",
|
|
165758
|
+
`[Top up balance \u2192](${billingConsoleUrl(owner)}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner)})`
|
|
165759
|
+
].join("\n");
|
|
165760
|
+
}
|
|
165761
|
+
if (error49.code === "router_monthly_limit") {
|
|
165762
|
+
return [
|
|
165763
|
+
"**Pullfrog Router hit its monthly spend limit.**",
|
|
165764
|
+
"",
|
|
165765
|
+
"Auto-reloads are paused for the rest of this UTC month. Ask your admin to raise the cap, or wait for it to reset at 00:00 UTC on the 1st.",
|
|
165766
|
+
"",
|
|
165767
|
+
`[Adjust limit \u2192](${billingConsoleUrl(owner)})`
|
|
165768
|
+
].join("\n");
|
|
165769
|
+
}
|
|
165770
|
+
if (error49.code === "commercial_plan_required") {
|
|
165771
|
+
return formatCommercialGateSummary({
|
|
165772
|
+
reason: "commercial",
|
|
165773
|
+
ownerLogin: owner
|
|
165774
|
+
});
|
|
165775
|
+
}
|
|
165776
|
+
if (error49.code === "subscription_unpaid") {
|
|
165777
|
+
return formatCommercialGateSummary({
|
|
165778
|
+
reason: "subscription_unpaid",
|
|
165779
|
+
ownerLogin: owner
|
|
165780
|
+
});
|
|
165781
|
+
}
|
|
165782
|
+
if (error49.needsReauthentication) {
|
|
165783
|
+
const code = error49.declineCode ?? "authentication_required";
|
|
165784
|
+
return [
|
|
165785
|
+
`**Your card issuer requires 3D Secure on every charge** (\`${code}\`).`,
|
|
165786
|
+
"",
|
|
165787
|
+
"Pullfrog can't complete a 3DS challenge from inside a workflow. Top up your Router balance once in Stripe Checkout, subsequent runs draw from the prepaid balance without re-triggering 3DS.",
|
|
165788
|
+
"",
|
|
165789
|
+
`[Top up balance \u2192](${billingConsoleUrl(owner)})`
|
|
165790
|
+
].join("\n");
|
|
165791
|
+
}
|
|
165792
|
+
if (error49.declineCode) {
|
|
165793
|
+
return [
|
|
165794
|
+
`**Your card was declined** (\`${error49.declineCode}\`).`,
|
|
165795
|
+
"",
|
|
165796
|
+
"Update your payment method and Pullfrog will retry on the next run.",
|
|
165797
|
+
"",
|
|
165798
|
+
`[Update payment method \u2192](${billingConsoleUrl(owner)})`
|
|
165799
|
+
].join("\n");
|
|
165800
|
+
}
|
|
165801
|
+
return [
|
|
165802
|
+
"**Your Pullfrog balance is empty.**",
|
|
165803
|
+
"",
|
|
165804
|
+
"Top up your balance or enable auto-reload to keep runs flowing.",
|
|
165805
|
+
"",
|
|
165806
|
+
`[Manage billing \u2192](${billingConsoleUrl(owner)})`
|
|
165807
|
+
].join("\n");
|
|
165808
|
+
}
|
|
165809
|
+
function formatTransientErrorSummary(error49, owner) {
|
|
165810
|
+
return [
|
|
165811
|
+
"**Pullfrog billing is temporarily unavailable.**",
|
|
165812
|
+
"",
|
|
165813
|
+
error49.message,
|
|
165814
|
+
"",
|
|
165815
|
+
`Usually transient; the next dispatch should succeed. If it persists, check [status.pullfrog.com](https://status.pullfrog.com) or [your console](${billingConsoleUrl(owner)}).`
|
|
165816
|
+
].join("\n");
|
|
165817
|
+
}
|
|
165818
|
+
|
|
165526
165819
|
// utils/gitAuthServer.ts
|
|
165527
165820
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
165528
165821
|
import { writeFileSync as writeFileSync14 } from "node:fs";
|
|
@@ -166323,102 +166616,6 @@ function applyOverrides(params) {
|
|
|
166323
166616
|
// utils/proxy.ts
|
|
166324
166617
|
var core8 = __toESM(require_core(), 1);
|
|
166325
166618
|
|
|
166326
|
-
// utils/billingErrors.ts
|
|
166327
|
-
var BillingError = class extends Error {
|
|
166328
|
-
code;
|
|
166329
|
-
declineCode;
|
|
166330
|
-
needsReauthentication;
|
|
166331
|
-
constructor(message, opts = {}) {
|
|
166332
|
-
super(message);
|
|
166333
|
-
this.name = "BillingError";
|
|
166334
|
-
this.code = opts.code ?? null;
|
|
166335
|
-
this.declineCode = opts.declineCode ?? null;
|
|
166336
|
-
this.needsReauthentication = opts.needsReauthentication ?? false;
|
|
166337
|
-
}
|
|
166338
|
-
};
|
|
166339
|
-
var TransientError = class extends Error {
|
|
166340
|
-
constructor(message) {
|
|
166341
|
-
super(message);
|
|
166342
|
-
this.name = "TransientError";
|
|
166343
|
-
}
|
|
166344
|
-
};
|
|
166345
|
-
function billingConsoleUrl(owner, anchor) {
|
|
166346
|
-
return `https://pullfrog.com/console/${encodeURIComponent(owner)}#${anchor}`;
|
|
166347
|
-
}
|
|
166348
|
-
function formatBillingErrorSummary(error49, owner) {
|
|
166349
|
-
if (error49.code === "router_requires_card") {
|
|
166350
|
-
return [
|
|
166351
|
-
"**Add a card to start using Pullfrog Router.**",
|
|
166352
|
-
"",
|
|
166353
|
-
"Router proxies OpenRouter at raw cost \u2014 no platform markup. Add a card and we'll auto-reload your wallet so runs keep flowing.",
|
|
166354
|
-
"",
|
|
166355
|
-
`[Add a card \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
166356
|
-
].join("\n");
|
|
166357
|
-
}
|
|
166358
|
-
if (error49.code === "router_balance_exhausted") {
|
|
166359
|
-
return [
|
|
166360
|
-
"**Your Pullfrog Router balance is exhausted.**",
|
|
166361
|
-
"",
|
|
166362
|
-
"You have a payment method on file but auto-reload is disabled, so runs paused once your balance went past the overdraft buffer.",
|
|
166363
|
-
"",
|
|
166364
|
-
`[Top up balance \u2192](${billingConsoleUrl(owner, "billing")}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
166365
|
-
].join("\n");
|
|
166366
|
-
}
|
|
166367
|
-
if (error49.code === "router_keylimit_exhausted") {
|
|
166368
|
-
return [
|
|
166369
|
-
"**This run was cut short \u2014 your Pullfrog Router balance ran out mid-run.**",
|
|
166370
|
-
"",
|
|
166371
|
-
"OpenRouter stopped the agent because the per-run budget was exhausted. Your wallet is now negative; top up or enable auto-reload to keep runs flowing.",
|
|
166372
|
-
"",
|
|
166373
|
-
`[Top up balance \u2192](${billingConsoleUrl(owner, "billing")}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
166374
|
-
].join("\n");
|
|
166375
|
-
}
|
|
166376
|
-
if (error49.code === "router_monthly_limit") {
|
|
166377
|
-
return [
|
|
166378
|
-
"**Pullfrog Router hit its monthly spend limit.**",
|
|
166379
|
-
"",
|
|
166380
|
-
"Auto-reloads are paused for the rest of this UTC month. Ask your admin to raise the cap, or wait for it to reset at 00:00 UTC on the 1st.",
|
|
166381
|
-
"",
|
|
166382
|
-
`[Adjust limit \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
166383
|
-
].join("\n");
|
|
166384
|
-
}
|
|
166385
|
-
if (error49.needsReauthentication) {
|
|
166386
|
-
const code = error49.declineCode ?? "authentication_required";
|
|
166387
|
-
return [
|
|
166388
|
-
`**Your card issuer requires 3D Secure on every charge** (\`${code}\`).`,
|
|
166389
|
-
"",
|
|
166390
|
-
"Pullfrog can't complete a 3DS challenge from inside a workflow. Top up your Router balance once in Stripe Checkout \u2014 subsequent runs draw from the prepaid balance without re-triggering 3DS.",
|
|
166391
|
-
"",
|
|
166392
|
-
`[Top up balance \u2192](${billingConsoleUrl(owner, "billing")})`
|
|
166393
|
-
].join("\n");
|
|
166394
|
-
}
|
|
166395
|
-
if (error49.declineCode) {
|
|
166396
|
-
return [
|
|
166397
|
-
`**Your card was declined** (\`${error49.declineCode}\`).`,
|
|
166398
|
-
"",
|
|
166399
|
-
"Update your payment method and Pullfrog will retry on the next run.",
|
|
166400
|
-
"",
|
|
166401
|
-
`[Update payment method \u2192](${billingConsoleUrl(owner, "billing")})`
|
|
166402
|
-
].join("\n");
|
|
166403
|
-
}
|
|
166404
|
-
return [
|
|
166405
|
-
"**Your Pullfrog balance is empty.**",
|
|
166406
|
-
"",
|
|
166407
|
-
"Top up your balance or enable auto-reload to keep runs flowing.",
|
|
166408
|
-
"",
|
|
166409
|
-
`[Manage billing \u2192](${billingConsoleUrl(owner, "billing")})`
|
|
166410
|
-
].join("\n");
|
|
166411
|
-
}
|
|
166412
|
-
function formatTransientErrorSummary(error49, owner) {
|
|
166413
|
-
return [
|
|
166414
|
-
"**Pullfrog billing is temporarily unavailable.**",
|
|
166415
|
-
"",
|
|
166416
|
-
error49.message,
|
|
166417
|
-
"",
|
|
166418
|
-
`Usually transient \u2014 the next dispatch should succeed. If it persists, check [status.pullfrog.com](https://status.pullfrog.com) or [your console](${billingConsoleUrl(owner, "billing")}).`
|
|
166419
|
-
].join("\n");
|
|
166420
|
-
}
|
|
166421
|
-
|
|
166422
166619
|
// utils/token.ts
|
|
166423
166620
|
var core7 = __toESM(require_core(), 1);
|
|
166424
166621
|
import assert2 from "node:assert/strict";
|
|
@@ -166952,6 +167149,7 @@ var core9 = __toESM(require_core(), 1);
|
|
|
166952
167149
|
// utils/runContext.ts
|
|
166953
167150
|
var defaultSettings = {
|
|
166954
167151
|
model: null,
|
|
167152
|
+
effort: null,
|
|
166955
167153
|
modes: [],
|
|
166956
167154
|
setupScript: null,
|
|
166957
167155
|
postCheckoutScript: null,
|
|
@@ -166963,6 +167161,7 @@ var defaultSettings = {
|
|
|
166963
167161
|
autoMergeEnabled: false,
|
|
166964
167162
|
signedCommits: false,
|
|
166965
167163
|
progressComments: true,
|
|
167164
|
+
statusChecks: true,
|
|
166966
167165
|
modeInstructions: {},
|
|
166967
167166
|
learnings: null,
|
|
166968
167167
|
learningsHeadings: [],
|
|
@@ -166998,6 +167197,11 @@ async function fetchRunContext(params) {
|
|
|
166998
167197
|
signal: controller.signal
|
|
166999
167198
|
});
|
|
167000
167199
|
clearTimeout(timeoutId);
|
|
167200
|
+
if (response.status === 402) {
|
|
167201
|
+
const body = await response.json().catch(() => null);
|
|
167202
|
+
const reason = typeof body === "object" && body !== null && "reason" in body && body.reason === "subscription_unpaid" ? "subscription_unpaid" : "commercial";
|
|
167203
|
+
return { ...defaultRunContext, commercialRefused: reason };
|
|
167204
|
+
}
|
|
167001
167205
|
if (!response.ok) {
|
|
167002
167206
|
return response.status >= 500 ? unknownSecretsRunContext : defaultRunContext;
|
|
167003
167207
|
}
|
|
@@ -167076,6 +167280,7 @@ async function resolveRunContextData(params) {
|
|
|
167076
167280
|
plan: runContext.plan,
|
|
167077
167281
|
proxyModel: runContext.proxyModel,
|
|
167078
167282
|
dbSecrets: runContext.dbSecrets,
|
|
167283
|
+
commercialRefused: runContext.commercialRefused,
|
|
167079
167284
|
// a failed mint on a runner that should have been able to mint is the same
|
|
167080
167285
|
// outcome as the server-side failure: the run never sees stored secrets.
|
|
167081
167286
|
secretsUnavailable: runContext.secretsUnavailable || !!process.env.ACTIONS_ID_TOKEN_REQUEST_URL && oidcToken === void 0
|
|
@@ -167459,6 +167664,7 @@ async function dispatchFollowUpReReview(ctx, reviewedSha) {
|
|
|
167459
167664
|
"~pullfrog": true,
|
|
167460
167665
|
version: ctx.payload.version,
|
|
167461
167666
|
model: ctx.payload.model,
|
|
167667
|
+
effort: ctx.payload.effort,
|
|
167462
167668
|
prompt: "",
|
|
167463
167669
|
eventInstructions: RE_REVIEW_PREAMBLE,
|
|
167464
167670
|
event
|
|
@@ -167484,30 +167690,123 @@ function getCurrentWorkflowFilename() {
|
|
|
167484
167690
|
return match3?.[1] ?? "pullfrog.yml";
|
|
167485
167691
|
}
|
|
167486
167692
|
|
|
167487
|
-
// utils/
|
|
167488
|
-
var
|
|
167489
|
-
var
|
|
167490
|
-
|
|
167693
|
+
// utils/runStatusCheck.ts
|
|
167694
|
+
var RUN_STATUS_CHECK_NAME = "Pullfrog";
|
|
167695
|
+
var APPROVAL_CHECK_NAME = "Pullfrog approval";
|
|
167696
|
+
function parseCheckRunId(raw2) {
|
|
167697
|
+
if (!raw2?.id) return void 0;
|
|
167698
|
+
const id = parseInt(raw2.id, 10);
|
|
167699
|
+
if (Number.isNaN(id) || id <= 0) return void 0;
|
|
167700
|
+
return id;
|
|
167701
|
+
}
|
|
167702
|
+
function disableCheckLine(owner, repo) {
|
|
167703
|
+
const url4 = `https://pullfrog.com/console/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}#auto-review-prs`;
|
|
167704
|
+
return `
|
|
167705
|
+
|
|
167706
|
+
[Turn off this check \u2192](${url4}) \u2014 it reports run status only and gates nothing unless you required it in branch protection.`;
|
|
167707
|
+
}
|
|
167708
|
+
var TERMINAL_OUTPUT = {
|
|
167709
|
+
success: {
|
|
167710
|
+
title: "Pullfrog run completed",
|
|
167711
|
+
summary: "The Pullfrog run finished successfully."
|
|
167712
|
+
},
|
|
167713
|
+
failure: {
|
|
167714
|
+
title: "Pullfrog run failed",
|
|
167715
|
+
summary: "The Pullfrog run failed. See the run logs for details."
|
|
167716
|
+
},
|
|
167717
|
+
cancelled: {
|
|
167718
|
+
title: "Pullfrog run cancelled",
|
|
167719
|
+
summary: "The Pullfrog run was cancelled before it finished."
|
|
167720
|
+
},
|
|
167721
|
+
timed_out: {
|
|
167722
|
+
title: "Pullfrog run timed out",
|
|
167723
|
+
summary: "The Pullfrog run exceeded its timeout. See the run logs for details."
|
|
167724
|
+
},
|
|
167725
|
+
action_required: {
|
|
167726
|
+
title: "Pullfrog run needs attention",
|
|
167727
|
+
summary: "The Pullfrog run stopped and needs attention. See the run logs for details."
|
|
167728
|
+
},
|
|
167729
|
+
neutral: {
|
|
167730
|
+
title: "Pullfrog run finished",
|
|
167731
|
+
summary: "The Pullfrog run finished without a pass or fail outcome."
|
|
167732
|
+
},
|
|
167733
|
+
skipped: {
|
|
167734
|
+
title: "Pullfrog run skipped",
|
|
167735
|
+
summary: "This run was superseded by another Pullfrog run."
|
|
167736
|
+
},
|
|
167737
|
+
stale: {
|
|
167738
|
+
title: "Pullfrog run didn't finish",
|
|
167739
|
+
summary: "Pullfrog never received a completion signal for this run. See the run logs for details."
|
|
167740
|
+
}
|
|
167741
|
+
};
|
|
167742
|
+
function terminalOutput(params) {
|
|
167743
|
+
const base = TERMINAL_OUTPUT[params.conclusion];
|
|
167744
|
+
const review = params.reviewUrl ? `
|
|
167745
|
+
|
|
167746
|
+
[View the review Pullfrog posted \u2192](${params.reviewUrl})` : "";
|
|
167747
|
+
const disable = params.conclusion === "success" ? "" : disableCheckLine(params.owner, params.repo);
|
|
167748
|
+
return { title: base.title, summary: base.summary + review + disable };
|
|
167749
|
+
}
|
|
167750
|
+
async function finalizeRunStatusCheck(params) {
|
|
167751
|
+
const updateParams = {
|
|
167752
|
+
owner: params.owner,
|
|
167753
|
+
repo: params.repo,
|
|
167754
|
+
check_run_id: params.checkRunId,
|
|
167755
|
+
status: "completed",
|
|
167756
|
+
conclusion: params.conclusion,
|
|
167757
|
+
output: terminalOutput({
|
|
167758
|
+
conclusion: params.conclusion,
|
|
167759
|
+
owner: params.owner,
|
|
167760
|
+
repo: params.repo,
|
|
167761
|
+
reviewUrl: params.reviewUrl
|
|
167762
|
+
})
|
|
167763
|
+
};
|
|
167764
|
+
if (params.detailsUrl) updateParams.details_url = params.detailsUrl;
|
|
167765
|
+
await params.octokit.rest.checks.update(updateParams);
|
|
167766
|
+
}
|
|
167767
|
+
async function createTerminalRunStatusCheck(params) {
|
|
167491
167768
|
const createParams = {
|
|
167492
|
-
owner:
|
|
167493
|
-
repo:
|
|
167494
|
-
name:
|
|
167769
|
+
owner: params.owner,
|
|
167770
|
+
repo: params.repo,
|
|
167771
|
+
name: RUN_STATUS_CHECK_NAME,
|
|
167495
167772
|
head_sha: params.headSha,
|
|
167496
167773
|
status: "completed",
|
|
167497
167774
|
conclusion: params.conclusion,
|
|
167498
|
-
output: {
|
|
167775
|
+
output: terminalOutput({
|
|
167776
|
+
conclusion: params.conclusion,
|
|
167777
|
+
owner: params.owner,
|
|
167778
|
+
repo: params.repo,
|
|
167779
|
+
reviewUrl: params.reviewUrl
|
|
167780
|
+
})
|
|
167499
167781
|
};
|
|
167500
|
-
if (
|
|
167501
|
-
|
|
167502
|
-
}
|
|
167503
|
-
await ctx.octokit.rest.checks.create(createParams);
|
|
167504
|
-
log.info(`\xBB posted ${params.name} check (${params.conclusion}) on ${params.headSha.slice(0, 7)}`);
|
|
167782
|
+
if (params.detailsUrl) createParams.details_url = params.detailsUrl;
|
|
167783
|
+
await params.octokit.rest.checks.create(createParams);
|
|
167505
167784
|
}
|
|
167785
|
+
|
|
167786
|
+
// utils/statusChecks.ts
|
|
167506
167787
|
async function reportStatusChecks(ctx, params) {
|
|
167507
|
-
if (!ctx.payload.statusChecks) return;
|
|
167508
167788
|
const event = ctx.payload.event;
|
|
167509
167789
|
const pullNumber = event.issue_number;
|
|
167510
167790
|
if (event.is_pr !== true || typeof pullNumber !== "number") return;
|
|
167791
|
+
const checkRunId = parseCheckRunId(ctx.payload.checkRun);
|
|
167792
|
+
if (checkRunId === void 0 && !ctx.payload.runStatusCheck && !ctx.payload.approvalCheck) return;
|
|
167793
|
+
const conclusion = params.runSucceeded ? "success" : "failure";
|
|
167794
|
+
const detailsUrl = ctx.runId ? `https://github.com/${ctx.repo.owner}/${ctx.repo.name}/actions/runs/${ctx.runId}` : void 0;
|
|
167795
|
+
if (checkRunId !== void 0) {
|
|
167796
|
+
await finalizeRunStatusCheck({
|
|
167797
|
+
octokit: ctx.octokit,
|
|
167798
|
+
owner: ctx.repo.owner,
|
|
167799
|
+
repo: ctx.repo.name,
|
|
167800
|
+
checkRunId,
|
|
167801
|
+
conclusion,
|
|
167802
|
+
detailsUrl,
|
|
167803
|
+
reviewUrl: ctx.toolState.approval?.url
|
|
167804
|
+
}).then(() => log.info(`\xBB finalized ${RUN_STATUS_CHECK_NAME} check (${conclusion})`)).catch((err) => log.debug(`status checks: ${RUN_STATUS_CHECK_NAME} finalize failed: ${err}`));
|
|
167805
|
+
}
|
|
167806
|
+
const approval = ctx.toolState.approval;
|
|
167807
|
+
const needsApprovalCheck = ctx.payload.approvalCheck && params.runSucceeded && approval;
|
|
167808
|
+
const needsFallbackRunCheck = ctx.payload.runStatusCheck && checkRunId === void 0;
|
|
167809
|
+
if (!needsApprovalCheck && !needsFallbackRunCheck) return;
|
|
167511
167810
|
let headSha;
|
|
167512
167811
|
try {
|
|
167513
167812
|
const pr = await ctx.octokit.rest.pulls.get({
|
|
@@ -167520,24 +167819,32 @@ async function reportStatusChecks(ctx, params) {
|
|
|
167520
167819
|
log.debug(`status checks: failed to resolve PR #${pullNumber} head sha: ${err}`);
|
|
167521
167820
|
return;
|
|
167522
167821
|
}
|
|
167523
|
-
|
|
167524
|
-
|
|
167525
|
-
|
|
167526
|
-
|
|
167527
|
-
|
|
167528
|
-
|
|
167529
|
-
|
|
167530
|
-
|
|
167531
|
-
|
|
167532
|
-
|
|
167533
|
-
|
|
167534
|
-
|
|
167535
|
-
|
|
167536
|
-
|
|
167822
|
+
if (needsFallbackRunCheck) {
|
|
167823
|
+
await createTerminalRunStatusCheck({
|
|
167824
|
+
octokit: ctx.octokit,
|
|
167825
|
+
owner: ctx.repo.owner,
|
|
167826
|
+
repo: ctx.repo.name,
|
|
167827
|
+
headSha: primaryRepoState(ctx.toolState).checkoutSha ?? headSha,
|
|
167828
|
+
conclusion,
|
|
167829
|
+
detailsUrl,
|
|
167830
|
+
reviewUrl: ctx.toolState.approval?.url
|
|
167831
|
+
}).then(() => log.info(`\xBB posted ${RUN_STATUS_CHECK_NAME} check (${conclusion})`)).catch((err) => log.debug(`status checks: ${RUN_STATUS_CHECK_NAME} post failed: ${err}`));
|
|
167832
|
+
}
|
|
167833
|
+
if (!needsApprovalCheck || !approval) return;
|
|
167834
|
+
const createParams = {
|
|
167835
|
+
owner: ctx.repo.owner,
|
|
167836
|
+
repo: ctx.repo.name,
|
|
167837
|
+
name: APPROVAL_CHECK_NAME,
|
|
167838
|
+
head_sha: approval.sha ?? headSha,
|
|
167839
|
+
status: "completed",
|
|
167840
|
+
conclusion: approval.wouldApprove ? "success" : "failure",
|
|
167841
|
+
output: {
|
|
167537
167842
|
title: approval.wouldApprove ? "Pullfrog would approve" : "Pullfrog would not approve",
|
|
167538
167843
|
summary: approval.wouldApprove ? "Pullfrog has no outstanding review feedback on this PR." : "Pullfrog has outstanding review feedback or requested changes on this PR."
|
|
167539
|
-
}
|
|
167540
|
-
}
|
|
167844
|
+
}
|
|
167845
|
+
};
|
|
167846
|
+
if (detailsUrl) createParams.details_url = detailsUrl;
|
|
167847
|
+
await ctx.octokit.rest.checks.create(createParams).then(() => log.info(`\xBB posted ${APPROVAL_CHECK_NAME} check`)).catch((err) => log.debug(`status checks: ${APPROVAL_CHECK_NAME} post failed: ${err}`));
|
|
167541
167848
|
}
|
|
167542
167849
|
|
|
167543
167850
|
// utils/runLifecycle.ts
|
|
@@ -167610,7 +167917,8 @@ async function writeRunErrorOutputs(input) {
|
|
|
167610
167917
|
error: input.rendered.comment,
|
|
167611
167918
|
createIfMissing: true
|
|
167612
167919
|
});
|
|
167613
|
-
} catch {
|
|
167920
|
+
} catch (error49) {
|
|
167921
|
+
log.warning(`error comment failed: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
167614
167922
|
}
|
|
167615
167923
|
}
|
|
167616
167924
|
|
|
@@ -167650,6 +167958,13 @@ function resolveModelForLog(ctx) {
|
|
|
167650
167958
|
if (ctx.payload.model) return `${ctx.payload.model} (unresolved)`;
|
|
167651
167959
|
return "auto";
|
|
167652
167960
|
}
|
|
167961
|
+
function resolveEffortForLog(ctx) {
|
|
167962
|
+
const effort = resolveRunEffort(ctx);
|
|
167963
|
+
if (!ctx.resolvedModel && !ctx.payload.proxyModel) return "pending \u2014 model not chosen yet";
|
|
167964
|
+
if (!effort.alias) return "not applied \u2014 model not recognized";
|
|
167965
|
+
if (!effort.rung) return "n/a (model has no effort control)";
|
|
167966
|
+
return effort.configured ? effort.rung : `${effort.rung} (default)`;
|
|
167967
|
+
}
|
|
167653
167968
|
function resolveAgentForLog(ctx) {
|
|
167654
167969
|
const envAgent = process.env.PULLFROG_AGENT?.trim();
|
|
167655
167970
|
if (envAgent && envAgent === ctx.agentName) {
|
|
@@ -167664,6 +167979,9 @@ function logRunStartup(ctx) {
|
|
|
167664
167979
|
log.info(
|
|
167665
167980
|
`\xBB model: ${resolveModelForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`
|
|
167666
167981
|
);
|
|
167982
|
+
log.info(
|
|
167983
|
+
`\xBB effort: ${resolveEffortForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`
|
|
167984
|
+
);
|
|
167667
167985
|
log.info(
|
|
167668
167986
|
`\xBB agent: ${resolveAgentForLog({ agentName: ctx.agentName, resolvedModel: ctx.resolvedModel })}`
|
|
167669
167987
|
);
|
|
@@ -167829,7 +168147,7 @@ async function resolveRun(params) {
|
|
|
167829
168147
|
|
|
167830
168148
|
// main.ts
|
|
167831
168149
|
async function main() {
|
|
167832
|
-
var
|
|
168150
|
+
var _stack3 = [];
|
|
167833
168151
|
try {
|
|
167834
168152
|
normalizeEnv();
|
|
167835
168153
|
const overridesRaw = process.env.UNSAFE_OVERRIDES ?? "";
|
|
@@ -167857,12 +168175,48 @@ async function main() {
|
|
|
167857
168175
|
const initialOctokit = createOctokit(jobToken);
|
|
167858
168176
|
const runContext = await resolveRunContextData({ octokit: initialOctokit, token: jobToken });
|
|
167859
168177
|
timer.checkpoint("runContextData");
|
|
168178
|
+
const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
|
|
167860
168179
|
const toolState = initToolState({
|
|
167861
168180
|
progressComment: typeof resolvedPromptInput !== "string" ? resolvedPromptInput.progressComment : void 0,
|
|
167862
168181
|
owner: runContext.repo.owner,
|
|
167863
168182
|
name: runContext.repo.name,
|
|
167864
168183
|
dir: process.cwd()
|
|
167865
168184
|
});
|
|
168185
|
+
toolState.model = payload.model;
|
|
168186
|
+
toolState.oss = runContext.oss;
|
|
168187
|
+
toolState.shaPinned = isActionPinnedToSha();
|
|
168188
|
+
if (payload.event.issue_number !== void 0) {
|
|
168189
|
+
primaryRepoState(toolState).issueNumber = payload.event.issue_number;
|
|
168190
|
+
}
|
|
168191
|
+
if (payload.event.trigger === "pull_request_synchronize") {
|
|
168192
|
+
primaryRepoState(toolState).beforeSha = payload.event.before_sha;
|
|
168193
|
+
}
|
|
168194
|
+
const oidcCredentials = process.env.ACTIONS_ID_TOKEN_REQUEST_URL && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN ? {
|
|
168195
|
+
requestUrl: process.env.ACTIONS_ID_TOKEN_REQUEST_URL,
|
|
168196
|
+
requestToken: process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN
|
|
168197
|
+
} : null;
|
|
168198
|
+
if (runContext.commercialRefused) {
|
|
168199
|
+
var _stack = [];
|
|
168200
|
+
try {
|
|
168201
|
+
const _commentTokenRef = __using(_stack, await resolveTokens({
|
|
168202
|
+
push: "disabled",
|
|
168203
|
+
oidc: oidcCredentials
|
|
168204
|
+
}), true);
|
|
168205
|
+
const errorMessage = runContext.commercialRefused === "subscription_unpaid" ? "Pro renewal failed for this organization" : "Pro plan required for this organization";
|
|
168206
|
+
log.error(errorMessage);
|
|
168207
|
+
const body = formatCommercialGateSummary({
|
|
168208
|
+
reason: runContext.commercialRefused,
|
|
168209
|
+
ownerLogin: runContext.repo.owner
|
|
168210
|
+
});
|
|
168211
|
+
await writeRunErrorOutputs({ rendered: { summary: body, comment: body }, toolState });
|
|
168212
|
+
return { success: false, error: errorMessage };
|
|
168213
|
+
} catch (_2) {
|
|
168214
|
+
var _error = _2, _hasError = true;
|
|
168215
|
+
} finally {
|
|
168216
|
+
var _promise2 = __callDispose(_stack, _error, _hasError);
|
|
168217
|
+
_promise2 && await _promise2;
|
|
168218
|
+
}
|
|
168219
|
+
}
|
|
167866
168220
|
createTempDirectory();
|
|
167867
168221
|
const opencodeCliPath = await agents.opencode.install();
|
|
167868
168222
|
captureBaselineModels(opencodeCliPath);
|
|
@@ -167881,27 +168235,13 @@ async function main() {
|
|
|
167881
168235
|
if (runContext.repoSettings.envAllowlist) {
|
|
167882
168236
|
setEnvAllowlist(runContext.repoSettings.envAllowlist);
|
|
167883
168237
|
}
|
|
167884
|
-
const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
|
|
167885
|
-
toolState.model = payload.model;
|
|
167886
|
-
toolState.oss = runContext.oss;
|
|
167887
|
-
toolState.shaPinned = isActionPinnedToSha();
|
|
167888
|
-
if (payload.event.issue_number !== void 0) {
|
|
167889
|
-
primaryRepoState(toolState).issueNumber = payload.event.issue_number;
|
|
167890
|
-
}
|
|
167891
|
-
if (payload.event.trigger === "pull_request_synchronize") {
|
|
167892
|
-
primaryRepoState(toolState).beforeSha = payload.event.before_sha;
|
|
167893
|
-
}
|
|
167894
|
-
const oidcCredentials = process.env.ACTIONS_ID_TOKEN_REQUEST_URL && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN ? {
|
|
167895
|
-
requestUrl: process.env.ACTIONS_ID_TOKEN_REQUEST_URL,
|
|
167896
|
-
requestToken: process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN
|
|
167897
|
-
} : null;
|
|
167898
168238
|
const xrepoUnavailable = payload.xrepo?.unavailable ?? [];
|
|
167899
168239
|
if (xrepoUnavailable.length > 0) {
|
|
167900
168240
|
log.warning(
|
|
167901
168241
|
`\xBB --xrepo: requested but not granted: ${xrepoUnavailable.join(", ")} (unknown repo, different owner, or you lack access)`
|
|
167902
168242
|
);
|
|
167903
168243
|
}
|
|
167904
|
-
const tokenRef = __using(
|
|
168244
|
+
const tokenRef = __using(_stack3, await resolveTokens({
|
|
167905
168245
|
push: payload.push,
|
|
167906
168246
|
xrepo: payload.xrepo,
|
|
167907
168247
|
oidc: oidcCredentials
|
|
@@ -167926,7 +168266,7 @@ async function main() {
|
|
|
167926
168266
|
let todoTracker;
|
|
167927
168267
|
let vertexCredentials;
|
|
167928
168268
|
try {
|
|
167929
|
-
var
|
|
168269
|
+
var _stack2 = [];
|
|
167930
168270
|
try {
|
|
167931
168271
|
if (payload.cwd && process.cwd() !== payload.cwd) {
|
|
167932
168272
|
process.chdir(payload.cwd);
|
|
@@ -167946,7 +168286,7 @@ async function main() {
|
|
|
167946
168286
|
payload.prompt = payload.prompt.replace(originalBody, resolvedBody ?? "");
|
|
167947
168287
|
}
|
|
167948
168288
|
}
|
|
167949
|
-
const gitAuthServer = __using(
|
|
168289
|
+
const gitAuthServer = __using(_stack2, await startGitAuthServer(tmpdir4), true);
|
|
167950
168290
|
setGitAuthServer(gitAuthServer);
|
|
167951
168291
|
const access = decideModelAccess({
|
|
167952
168292
|
modelExplicit: payload.modelExplicit ?? false,
|
|
@@ -167969,6 +168309,7 @@ async function main() {
|
|
|
167969
168309
|
}
|
|
167970
168310
|
if (access.kind === "proxy") payload.proxyModel = access.target;
|
|
167971
168311
|
if (access.kind === "byok") payload.proxyModel = void 0;
|
|
168312
|
+
if (runContext.oss && payload.proxyModel) payload.effort = 0;
|
|
167972
168313
|
const resolvedModel = payload.proxyModel ? void 0 : resolveModel({ slug: payload.model });
|
|
167973
168314
|
vertexCredentials = materializeVertexCredentials({ model: resolvedModel });
|
|
167974
168315
|
const agent2 = resolveAgent({ model: resolvedModel });
|
|
@@ -168049,7 +168390,7 @@ async function main() {
|
|
|
168049
168390
|
plan: runContext.plan,
|
|
168050
168391
|
resolvedModel
|
|
168051
168392
|
};
|
|
168052
|
-
const mcpHttpServer = __using(
|
|
168393
|
+
const mcpHttpServer = __using(_stack2, await startMcpHttpServer(toolContext, { outputSchema }), true);
|
|
168053
168394
|
toolContext.mcpServerUrl = mcpHttpServer.url;
|
|
168054
168395
|
log.info(`\xBB MCP server started at ${mcpHttpServer.url}`);
|
|
168055
168396
|
timer.checkpoint("mcpServer");
|
|
@@ -168232,7 +168573,7 @@ ${instructions.user}` : null,
|
|
|
168232
168573
|
const timeoutMs = usable ?? 36e5;
|
|
168233
168574
|
const actualTimeout = usable !== null ? payload.timeout : "1h";
|
|
168234
168575
|
let timeoutId;
|
|
168235
|
-
const timeoutPromise = new Promise((
|
|
168576
|
+
const timeoutPromise = new Promise((_5, reject) => {
|
|
168236
168577
|
timeoutId = setTimeout(() => {
|
|
168237
168578
|
reject(new Error(`agent run timed out after ${actualTimeout}`));
|
|
168238
168579
|
}, timeoutMs);
|
|
@@ -168259,11 +168600,11 @@ ${instructions.user}` : null,
|
|
|
168259
168600
|
toolContext,
|
|
168260
168601
|
silent: payload.event.silent ?? false
|
|
168261
168602
|
});
|
|
168262
|
-
} catch (
|
|
168263
|
-
var
|
|
168603
|
+
} catch (_3) {
|
|
168604
|
+
var _error2 = _3, _hasError2 = true;
|
|
168264
168605
|
} finally {
|
|
168265
|
-
var
|
|
168266
|
-
|
|
168606
|
+
var _promise3 = __callDispose(_stack2, _error2, _hasError2);
|
|
168607
|
+
_promise3 && await _promise3;
|
|
168267
168608
|
}
|
|
168268
168609
|
} catch (error49) {
|
|
168269
168610
|
const errorMessage = error49 instanceof Error ? error49.message : "unknown error occurred";
|
|
@@ -168307,11 +168648,11 @@ ${instructions.user}` : null,
|
|
|
168307
168648
|
}
|
|
168308
168649
|
cleanupVertexCredentials(vertexCredentials);
|
|
168309
168650
|
}
|
|
168310
|
-
} catch (
|
|
168311
|
-
var
|
|
168651
|
+
} catch (_4) {
|
|
168652
|
+
var _error3 = _4, _hasError3 = true;
|
|
168312
168653
|
} finally {
|
|
168313
|
-
var
|
|
168314
|
-
|
|
168654
|
+
var _promise4 = __callDispose(_stack3, _error3, _hasError3);
|
|
168655
|
+
_promise4 && await _promise4;
|
|
168315
168656
|
}
|
|
168316
168657
|
}
|
|
168317
168658
|
|
|
@@ -168938,7 +169279,8 @@ async function handleSecret(ctx) {
|
|
|
168938
169279
|
}
|
|
168939
169280
|
if (method === "pullfrog") {
|
|
168940
169281
|
const scope2 = ctx.secrets.isOrg ? await promptScope2(ctx) : "account";
|
|
168941
|
-
|
|
169282
|
+
const target = describeSecretTarget({ owner: ctx.owner, repo: ctx.repo, scope: scope2 });
|
|
169283
|
+
activeSpin2.start(`saving ${import_picocolors3.default.cyan(envVar)} to ${target}`);
|
|
168942
169284
|
let saveResult;
|
|
168943
169285
|
try {
|
|
168944
169286
|
saveResult = await setPullfrogSecret2({
|
|
@@ -168958,7 +169300,7 @@ async function handleSecret(ctx) {
|
|
|
168958
169300
|
return;
|
|
168959
169301
|
}
|
|
168960
169302
|
if (saveResult.saved) {
|
|
168961
|
-
activeSpin2.stop(`saved ${import_picocolors3.default.cyan(envVar)} to
|
|
169303
|
+
activeSpin2.stop(`saved ${import_picocolors3.default.cyan(envVar)} to ${target}`);
|
|
168962
169304
|
} else {
|
|
168963
169305
|
activeSpin2.stop(import_picocolors3.default.red("could not save secret"));
|
|
168964
169306
|
O2.warn(
|
|
@@ -169308,7 +169650,7 @@ async function runCli4(input) {
|
|
|
169308
169650
|
}
|
|
169309
169651
|
|
|
169310
169652
|
// cli.ts
|
|
169311
|
-
var VERSION10 = "0.1.
|
|
169653
|
+
var VERSION10 = "0.1.48";
|
|
169312
169654
|
var bin = basename2(process.argv[1] || "");
|
|
169313
169655
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
169314
169656
|
var rawArgs = process.argv.slice(2);
|