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/index.js
CHANGED
|
@@ -99809,6 +99809,36 @@ import { chmodSync as chmodSync2, mkdirSync as mkdirSync4, writeFileSync as writ
|
|
|
99809
99809
|
import { join as join4 } from "node:path";
|
|
99810
99810
|
import { performance as performance5 } from "node:perf_hooks";
|
|
99811
99811
|
|
|
99812
|
+
// effort.ts
|
|
99813
|
+
var DEFAULT_EFFORT_POSITION = 0.75;
|
|
99814
|
+
var EFFORT_ALIASES = {
|
|
99815
|
+
low: 0,
|
|
99816
|
+
medium: 0.25,
|
|
99817
|
+
high: 0.5,
|
|
99818
|
+
xhigh: 0.75,
|
|
99819
|
+
max: 1
|
|
99820
|
+
};
|
|
99821
|
+
var DISABLING_RUNGS = ["none", "minimal"];
|
|
99822
|
+
function isEffortPosition(value2) {
|
|
99823
|
+
return Number.isFinite(value2) && value2 >= 0 && value2 <= 1;
|
|
99824
|
+
}
|
|
99825
|
+
function parseEffortPosition(raw2) {
|
|
99826
|
+
const normalized = raw2.trim().toLowerCase();
|
|
99827
|
+
const named = EFFORT_ALIASES[normalized === "med" ? "medium" : normalized];
|
|
99828
|
+
if (named !== void 0) return named;
|
|
99829
|
+
const numeric = Number(normalized);
|
|
99830
|
+
return normalized !== "" && isEffortPosition(numeric) ? numeric : void 0;
|
|
99831
|
+
}
|
|
99832
|
+
function offeredRungs(published) {
|
|
99833
|
+
return published.filter((rung) => !DISABLING_RUNGS.includes(rung));
|
|
99834
|
+
}
|
|
99835
|
+
function resolveRung(params) {
|
|
99836
|
+
const rungs = offeredRungs(params.published);
|
|
99837
|
+
if (rungs.length === 0) return void 0;
|
|
99838
|
+
const clamped = Math.min(1, Math.max(0, params.position));
|
|
99839
|
+
return rungs[Math.floor(clamped * (rungs.length - 1))];
|
|
99840
|
+
}
|
|
99841
|
+
|
|
99812
99842
|
// models.ts
|
|
99813
99843
|
function provider(config3) {
|
|
99814
99844
|
return config3;
|
|
@@ -99828,6 +99858,7 @@ var providers = {
|
|
|
99828
99858
|
"claude-fable": {
|
|
99829
99859
|
displayName: "Claude Fable",
|
|
99830
99860
|
resolve: "anthropic/claude-fable-5",
|
|
99861
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
99831
99862
|
// rolling alias: models.dev's OpenRouter mirror lags brand-new pinned
|
|
99832
99863
|
// versions (claude-fable-5 isn't indexed yet), so track ~…-latest to
|
|
99833
99864
|
// stay catalog-valid and auto-follow version bumps.
|
|
@@ -99837,6 +99868,7 @@ var providers = {
|
|
|
99837
99868
|
"claude-opus": {
|
|
99838
99869
|
displayName: "Claude Opus",
|
|
99839
99870
|
resolve: "anthropic/claude-opus-5",
|
|
99871
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
99840
99872
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
99841
99873
|
preferred: true,
|
|
99842
99874
|
subagentModel: "claude-sonnet"
|
|
@@ -99844,6 +99876,7 @@ var providers = {
|
|
|
99844
99876
|
"claude-sonnet": {
|
|
99845
99877
|
displayName: "Claude Sonnet",
|
|
99846
99878
|
resolve: "anthropic/claude-sonnet-5",
|
|
99879
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
99847
99880
|
openRouterResolve: "openrouter/anthropic/claude-sonnet-5"
|
|
99848
99881
|
},
|
|
99849
99882
|
"claude-haiku": {
|
|
@@ -99861,6 +99894,7 @@ var providers = {
|
|
|
99861
99894
|
gpt: {
|
|
99862
99895
|
displayName: "GPT Sol",
|
|
99863
99896
|
resolve: "openai/gpt-5.6-sol",
|
|
99897
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
99864
99898
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
99865
99899
|
preferred: true,
|
|
99866
99900
|
subagentModel: "gpt-terra"
|
|
@@ -99872,6 +99906,7 @@ var providers = {
|
|
|
99872
99906
|
displayName: "GPT Sol Pro",
|
|
99873
99907
|
description: "Maximum reasoning effort",
|
|
99874
99908
|
resolve: "openai/gpt-5.6-sol",
|
|
99909
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
99875
99910
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
99876
99911
|
subagentModel: "gpt"
|
|
99877
99912
|
},
|
|
@@ -99881,11 +99916,13 @@ var providers = {
|
|
|
99881
99916
|
"gpt-terra": {
|
|
99882
99917
|
displayName: "GPT Terra",
|
|
99883
99918
|
resolve: "openai/gpt-5.6-terra",
|
|
99919
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
99884
99920
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
99885
99921
|
},
|
|
99886
99922
|
"gpt-mini": {
|
|
99887
99923
|
displayName: "GPT Luna",
|
|
99888
99924
|
resolve: "openai/gpt-5.6-luna",
|
|
99925
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
99889
99926
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
99890
99927
|
},
|
|
99891
99928
|
// legacy aliases — openai unified the codex line into the main GPT family
|
|
@@ -99915,6 +99952,7 @@ var providers = {
|
|
|
99915
99952
|
o3: {
|
|
99916
99953
|
displayName: "O3",
|
|
99917
99954
|
resolve: "openai/o3",
|
|
99955
|
+
effort: ["low", "medium", "high"],
|
|
99918
99956
|
openRouterResolve: "openrouter/openai/o3"
|
|
99919
99957
|
}
|
|
99920
99958
|
}
|
|
@@ -99926,6 +99964,7 @@ var providers = {
|
|
|
99926
99964
|
"gemini-pro": {
|
|
99927
99965
|
displayName: "Gemini Pro",
|
|
99928
99966
|
resolve: "google/gemini-3.1-pro-preview",
|
|
99967
|
+
effort: ["low", "medium", "high"],
|
|
99929
99968
|
openRouterResolve: "openrouter/google/gemini-3.1-pro-preview",
|
|
99930
99969
|
preferred: true
|
|
99931
99970
|
// Inherit (subagents stay on Pro). Google has no in-between tier;
|
|
@@ -99937,6 +99976,7 @@ var providers = {
|
|
|
99937
99976
|
"gemini-flash": {
|
|
99938
99977
|
displayName: "Gemini Flash",
|
|
99939
99978
|
resolve: "google/gemini-3.5-flash",
|
|
99979
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
99940
99980
|
openRouterResolve: "openrouter/google/gemini-3.5-flash"
|
|
99941
99981
|
}
|
|
99942
99982
|
}
|
|
@@ -99948,6 +99988,7 @@ var providers = {
|
|
|
99948
99988
|
grok: {
|
|
99949
99989
|
displayName: "Grok",
|
|
99950
99990
|
resolve: "xai/grok-4.3",
|
|
99991
|
+
effort: ["none", "low", "medium", "high"],
|
|
99951
99992
|
openRouterResolve: "openrouter/x-ai/grok-4.3",
|
|
99952
99993
|
preferred: true
|
|
99953
99994
|
},
|
|
@@ -99977,12 +100018,16 @@ var providers = {
|
|
|
99977
100018
|
"deepseek-pro": {
|
|
99978
100019
|
displayName: "DeepSeek Pro",
|
|
99979
100020
|
resolve: "deepseek/deepseek-v4-pro",
|
|
100021
|
+
effort: ["high", "max"],
|
|
100022
|
+
openRouterEffort: ["high", "xhigh"],
|
|
99980
100023
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro",
|
|
99981
100024
|
preferred: true
|
|
99982
100025
|
},
|
|
99983
100026
|
"deepseek-flash": {
|
|
99984
100027
|
displayName: "DeepSeek Flash",
|
|
99985
100028
|
resolve: "deepseek/deepseek-v4-flash",
|
|
100029
|
+
effort: ["high", "max"],
|
|
100030
|
+
openRouterEffort: ["high", "xhigh"],
|
|
99986
100031
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
|
|
99987
100032
|
},
|
|
99988
100033
|
// legacy aliases — deepseek retires these on 2026-07-24; transparently
|
|
@@ -100011,6 +100056,7 @@ var providers = {
|
|
|
100011
100056
|
"kimi-k3": {
|
|
100012
100057
|
displayName: "Kimi K3",
|
|
100013
100058
|
resolve: "moonshotai/kimi-k3",
|
|
100059
|
+
effort: ["low", "high", "max"],
|
|
100014
100060
|
openRouterResolve: "openrouter/moonshotai/kimi-k3",
|
|
100015
100061
|
preferred: true,
|
|
100016
100062
|
subagentModel: "kimi-k2"
|
|
@@ -100023,7 +100069,7 @@ var providers = {
|
|
|
100023
100069
|
}
|
|
100024
100070
|
}),
|
|
100025
100071
|
opencode: provider({
|
|
100026
|
-
displayName: "OpenCode",
|
|
100072
|
+
displayName: "OpenCode Zen",
|
|
100027
100073
|
envVars: ["OPENCODE_API_KEY"],
|
|
100028
100074
|
models: {
|
|
100029
100075
|
"big-pickle": {
|
|
@@ -100036,12 +100082,14 @@ var providers = {
|
|
|
100036
100082
|
"claude-opus": {
|
|
100037
100083
|
displayName: "Claude Opus",
|
|
100038
100084
|
resolve: "opencode/claude-opus-5",
|
|
100085
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
100039
100086
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
100040
100087
|
subagentModel: "claude-sonnet"
|
|
100041
100088
|
},
|
|
100042
100089
|
"claude-sonnet": {
|
|
100043
100090
|
displayName: "Claude Sonnet",
|
|
100044
100091
|
resolve: "opencode/claude-sonnet-5",
|
|
100092
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
100045
100093
|
openRouterResolve: "openrouter/anthropic/claude-sonnet-5"
|
|
100046
100094
|
},
|
|
100047
100095
|
"claude-haiku": {
|
|
@@ -100052,6 +100100,7 @@ var providers = {
|
|
|
100052
100100
|
gpt: {
|
|
100053
100101
|
displayName: "GPT Sol",
|
|
100054
100102
|
resolve: "opencode/gpt-5.6-sol",
|
|
100103
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100055
100104
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100056
100105
|
subagentModel: "gpt-terra"
|
|
100057
100106
|
},
|
|
@@ -100060,6 +100109,7 @@ var providers = {
|
|
|
100060
100109
|
displayName: "GPT Sol Pro",
|
|
100061
100110
|
description: "Maximum reasoning effort",
|
|
100062
100111
|
resolve: "opencode/gpt-5.6-sol",
|
|
100112
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100063
100113
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100064
100114
|
subagentModel: "gpt"
|
|
100065
100115
|
},
|
|
@@ -100067,11 +100117,13 @@ var providers = {
|
|
|
100067
100117
|
"gpt-terra": {
|
|
100068
100118
|
displayName: "GPT Terra",
|
|
100069
100119
|
resolve: "opencode/gpt-5.6-terra",
|
|
100120
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100070
100121
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
100071
100122
|
},
|
|
100072
100123
|
"gpt-mini": {
|
|
100073
100124
|
displayName: "GPT Luna",
|
|
100074
100125
|
resolve: "opencode/gpt-5.6-luna",
|
|
100126
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100075
100127
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
100076
100128
|
},
|
|
100077
100129
|
// legacy aliases — see openai provider above for context.
|
|
@@ -100097,12 +100149,14 @@ var providers = {
|
|
|
100097
100149
|
"gemini-pro": {
|
|
100098
100150
|
displayName: "Gemini Pro",
|
|
100099
100151
|
resolve: "opencode/gemini-3.1-pro",
|
|
100152
|
+
effort: ["low", "medium", "high"],
|
|
100100
100153
|
openRouterResolve: "openrouter/google/gemini-3.1-pro-preview"
|
|
100101
100154
|
// Inherit — see google/gemini-pro for rationale.
|
|
100102
100155
|
},
|
|
100103
100156
|
"gemini-flash": {
|
|
100104
100157
|
displayName: "Gemini Flash",
|
|
100105
100158
|
resolve: "opencode/gemini-3.5-flash",
|
|
100159
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
100106
100160
|
openRouterResolve: "openrouter/google/gemini-3.5-flash"
|
|
100107
100161
|
},
|
|
100108
100162
|
"kimi-k2": {
|
|
@@ -100121,6 +100175,7 @@ var providers = {
|
|
|
100121
100175
|
"gpt-5-nano": {
|
|
100122
100176
|
displayName: "GPT Nano",
|
|
100123
100177
|
resolve: "opencode/gpt-5-nano",
|
|
100178
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
100124
100179
|
openRouterResolve: "openrouter/openai/gpt-5-nano"
|
|
100125
100180
|
},
|
|
100126
100181
|
"mimo-v2-pro-free": {
|
|
@@ -100147,6 +100202,8 @@ var providers = {
|
|
|
100147
100202
|
"glm-5.1": {
|
|
100148
100203
|
displayName: "GLM 5.2",
|
|
100149
100204
|
resolve: "opencode-go/glm-5.2",
|
|
100205
|
+
effort: ["high", "max"],
|
|
100206
|
+
openRouterEffort: ["high", "xhigh"],
|
|
100150
100207
|
openRouterResolve: "openrouter/z-ai/glm-5.2",
|
|
100151
100208
|
preferred: true
|
|
100152
100209
|
},
|
|
@@ -100200,6 +100257,10 @@ var providers = {
|
|
|
100200
100257
|
// bring-your-own generic OpenAI-compatible endpoint — Cloudflare AI Gateway,
|
|
100201
100258
|
// Alibaba DashScope, self-hosted vLLM, or any compatible gateway. base URL +
|
|
100202
100259
|
// key + model ID are all supplied via env; nothing is cataloged or bumped.
|
|
100260
|
+
// the two token limits are deliberately absent: this list is the auth
|
|
100261
|
+
// heuristic (`hasPullfrogStoredAuthForModel`, `validateAgentApiKey`), and a
|
|
100262
|
+
// stored context number is config, not proof of a key. the console picks
|
|
100263
|
+
// them up from `PROVIDER_EXTRA_SECRET_NAMES` instead.
|
|
100203
100264
|
envVars: ["OPENAI_COMPATIBLE_BASE_URL", "OPENAI_COMPATIBLE_API_KEY", "OPENAI_COMPATIBLE_MODEL"],
|
|
100204
100265
|
models: {
|
|
100205
100266
|
// single routing entry — the actual model ID is read from
|
|
@@ -100219,6 +100280,7 @@ var providers = {
|
|
|
100219
100280
|
"claude-opus": {
|
|
100220
100281
|
displayName: "Claude Opus",
|
|
100221
100282
|
resolve: "openrouter/~anthropic/claude-opus-latest",
|
|
100283
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
100222
100284
|
openRouterResolve: "openrouter/~anthropic/claude-opus-latest",
|
|
100223
100285
|
preferred: true,
|
|
100224
100286
|
subagentModel: "claude-sonnet"
|
|
@@ -100226,6 +100288,7 @@ var providers = {
|
|
|
100226
100288
|
"claude-sonnet": {
|
|
100227
100289
|
displayName: "Claude Sonnet",
|
|
100228
100290
|
resolve: "openrouter/~anthropic/claude-sonnet-latest",
|
|
100291
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
100229
100292
|
openRouterResolve: "openrouter/~anthropic/claude-sonnet-latest"
|
|
100230
100293
|
},
|
|
100231
100294
|
"claude-haiku": {
|
|
@@ -100240,6 +100303,7 @@ var providers = {
|
|
|
100240
100303
|
gpt: {
|
|
100241
100304
|
displayName: "GPT Sol",
|
|
100242
100305
|
resolve: "openrouter/openai/gpt-5.6-sol",
|
|
100306
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100243
100307
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
100244
100308
|
subagentModel: "gpt-terra"
|
|
100245
100309
|
},
|
|
@@ -100248,6 +100312,7 @@ var providers = {
|
|
|
100248
100312
|
displayName: "GPT Sol Pro",
|
|
100249
100313
|
description: "Maximum reasoning effort",
|
|
100250
100314
|
resolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100315
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100251
100316
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
100252
100317
|
subagentModel: "gpt"
|
|
100253
100318
|
},
|
|
@@ -100255,11 +100320,13 @@ var providers = {
|
|
|
100255
100320
|
"gpt-terra": {
|
|
100256
100321
|
displayName: "GPT Terra",
|
|
100257
100322
|
resolve: "openrouter/openai/gpt-5.6-terra",
|
|
100323
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100258
100324
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
100259
100325
|
},
|
|
100260
100326
|
"gpt-mini": {
|
|
100261
100327
|
displayName: "GPT Luna",
|
|
100262
100328
|
resolve: "openrouter/openai/gpt-5.6-luna",
|
|
100329
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
100263
100330
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
100264
100331
|
},
|
|
100265
100332
|
// legacy aliases — see openai provider for context.
|
|
@@ -100285,32 +100352,38 @@ var providers = {
|
|
|
100285
100352
|
"o4-mini": {
|
|
100286
100353
|
displayName: "O4 Mini",
|
|
100287
100354
|
resolve: "openrouter/openai/o4-mini",
|
|
100355
|
+
effort: ["low", "medium", "high"],
|
|
100288
100356
|
openRouterResolve: "openrouter/openai/o4-mini"
|
|
100289
100357
|
},
|
|
100290
100358
|
"gemini-pro": {
|
|
100291
100359
|
displayName: "Gemini Pro",
|
|
100292
100360
|
resolve: "openrouter/~google/gemini-pro-latest",
|
|
100361
|
+
effort: ["low", "medium", "high"],
|
|
100293
100362
|
openRouterResolve: "openrouter/~google/gemini-pro-latest"
|
|
100294
100363
|
// Inherit — see google/gemini-pro for rationale.
|
|
100295
100364
|
},
|
|
100296
100365
|
"gemini-flash": {
|
|
100297
100366
|
displayName: "Gemini Flash",
|
|
100298
100367
|
resolve: "openrouter/~google/gemini-flash-latest",
|
|
100368
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
100299
100369
|
openRouterResolve: "openrouter/~google/gemini-flash-latest"
|
|
100300
100370
|
},
|
|
100301
100371
|
grok: {
|
|
100302
100372
|
displayName: "Grok",
|
|
100303
100373
|
resolve: "openrouter/x-ai/grok-4.3",
|
|
100374
|
+
effort: ["none", "low", "medium", "high"],
|
|
100304
100375
|
openRouterResolve: "openrouter/x-ai/grok-4.3"
|
|
100305
100376
|
},
|
|
100306
100377
|
"deepseek-pro": {
|
|
100307
100378
|
displayName: "DeepSeek Pro",
|
|
100308
100379
|
resolve: "openrouter/deepseek/deepseek-v4-pro",
|
|
100380
|
+
effort: ["high", "xhigh"],
|
|
100309
100381
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro"
|
|
100310
100382
|
},
|
|
100311
100383
|
"deepseek-flash": {
|
|
100312
100384
|
displayName: "DeepSeek Flash",
|
|
100313
100385
|
resolve: "openrouter/deepseek/deepseek-v4-flash",
|
|
100386
|
+
effort: ["high", "xhigh"],
|
|
100314
100387
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
|
|
100315
100388
|
},
|
|
100316
100389
|
// legacy alias — deepseek retires this on 2026-07-24; transparently
|
|
@@ -100329,6 +100402,7 @@ var providers = {
|
|
|
100329
100402
|
"kimi-k3": {
|
|
100330
100403
|
displayName: "Kimi K3",
|
|
100331
100404
|
resolve: "openrouter/moonshotai/kimi-k3",
|
|
100405
|
+
effort: ["low", "high", "max"],
|
|
100332
100406
|
openRouterResolve: "openrouter/moonshotai/kimi-k3"
|
|
100333
100407
|
},
|
|
100334
100408
|
// slug pins the m2 line for DB stability; resolve tracks the current m2.7.
|
|
@@ -100383,6 +100457,8 @@ var modelAliases = Object.entries(providers).flatMap(
|
|
|
100383
100457
|
// here to a fully-qualified slug so callers can look up the target alias
|
|
100384
100458
|
// directly without re-deriving the provider.
|
|
100385
100459
|
subagentModel: def.subagentModel ? `${providerKey}/${def.subagentModel}` : void 0,
|
|
100460
|
+
effort: def.effort,
|
|
100461
|
+
openRouterEffort: def.openRouterEffort,
|
|
100386
100462
|
hidden: def.hidden ?? false
|
|
100387
100463
|
}))
|
|
100388
100464
|
);
|
|
@@ -100421,6 +100497,17 @@ function resolveCliModel(slug2) {
|
|
|
100421
100497
|
function resolveOpenRouterModel(slug2) {
|
|
100422
100498
|
return resolveDisplayAlias(slug2)?.openRouterResolve;
|
|
100423
100499
|
}
|
|
100500
|
+
function getModelEffortLevels(params) {
|
|
100501
|
+
const alias = resolveDisplayAlias(params.slug);
|
|
100502
|
+
if (!alias) return void 0;
|
|
100503
|
+
if (params.useOpenRouter) return alias.openRouterEffort ?? alias.effort;
|
|
100504
|
+
return alias.effort;
|
|
100505
|
+
}
|
|
100506
|
+
function resolveModelRung(params) {
|
|
100507
|
+
const published = getModelEffortLevels(params);
|
|
100508
|
+
if (!published) return void 0;
|
|
100509
|
+
return resolveRung({ position: params.position, published });
|
|
100510
|
+
}
|
|
100424
100511
|
var defaultProxyAlias = resolveDisplayAlias(AUTO_EFFICIENT);
|
|
100425
100512
|
if (!defaultProxyAlias?.openRouterResolve) {
|
|
100426
100513
|
throw new Error(`DEFAULT_PROXY_MODEL: ${AUTO_EFFICIENT} has no openRouterResolve`);
|
|
@@ -101108,6 +101195,40 @@ function extractProviderId(text) {
|
|
|
101108
101195
|
return match3 ? match3[1].toLowerCase() : null;
|
|
101109
101196
|
}
|
|
101110
101197
|
|
|
101198
|
+
// utils/runEffort.ts
|
|
101199
|
+
function matchHostedAnthropicAlias(modelId) {
|
|
101200
|
+
const id = modelId.toLowerCase();
|
|
101201
|
+
if (id.startsWith("arn:")) return void 0;
|
|
101202
|
+
return modelAliases.find(
|
|
101203
|
+
(a) => !a.fallback && a.provider === "anthropic" && id.includes(a.resolve.replace(/^anthropic\//, ""))
|
|
101204
|
+
);
|
|
101205
|
+
}
|
|
101206
|
+
function resolveRunAlias(ctx) {
|
|
101207
|
+
const proxyModel = ctx.payload.proxyModel;
|
|
101208
|
+
if (proxyModel) {
|
|
101209
|
+
return modelAliases.find((a) => !a.fallback && a.openRouterResolve === proxyModel);
|
|
101210
|
+
}
|
|
101211
|
+
const model = ctx.resolvedModel;
|
|
101212
|
+
if (!model) return void 0;
|
|
101213
|
+
return modelAliases.find((a) => !a.fallback && a.resolve === model) ?? matchHostedAnthropicAlias(model);
|
|
101214
|
+
}
|
|
101215
|
+
function resolveRunEffort(ctx) {
|
|
101216
|
+
const configured = ctx.payload.effort !== void 0;
|
|
101217
|
+
const position = ctx.payload.effort ?? DEFAULT_EFFORT_POSITION;
|
|
101218
|
+
const alias = resolveRunAlias(ctx);
|
|
101219
|
+
if (!alias) return { position, configured, rung: void 0, alias: void 0 };
|
|
101220
|
+
return {
|
|
101221
|
+
position,
|
|
101222
|
+
configured,
|
|
101223
|
+
rung: resolveModelRung({
|
|
101224
|
+
slug: alias.slug,
|
|
101225
|
+
position,
|
|
101226
|
+
useOpenRouter: !!ctx.payload.proxyModel
|
|
101227
|
+
}),
|
|
101228
|
+
alias
|
|
101229
|
+
};
|
|
101230
|
+
}
|
|
101231
|
+
|
|
101111
101232
|
// utils/skills.ts
|
|
101112
101233
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
101113
101234
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -101121,7 +101242,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
101121
101242
|
// package.json
|
|
101122
101243
|
var package_default = {
|
|
101123
101244
|
name: "pullfrog",
|
|
101124
|
-
version: "0.1.
|
|
101245
|
+
version: "0.1.48",
|
|
101125
101246
|
type: "module",
|
|
101126
101247
|
bin: {
|
|
101127
101248
|
pullfrog: "dist/cli.mjs",
|
|
@@ -102681,8 +102802,18 @@ function stripProviderPrefix(specifier) {
|
|
|
102681
102802
|
const slashIndex = specifier.indexOf("/");
|
|
102682
102803
|
return slashIndex > 0 ? specifier.slice(slashIndex + 1) : specifier;
|
|
102683
102804
|
}
|
|
102684
|
-
|
|
102685
|
-
|
|
102805
|
+
var CLAUDE_EFFORT_ENV = "CLAUDE_CODE_EFFORT_LEVEL";
|
|
102806
|
+
var CLAUDE_CODE_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
102807
|
+
function effortCapabilities(levels) {
|
|
102808
|
+
const topRungs = levels.filter((l) => l === "xhigh" || l === "max").map((l) => `${l}_effort`);
|
|
102809
|
+
return ["effort", ...topRungs, "adaptive_thinking", "thinking"].join(",");
|
|
102810
|
+
}
|
|
102811
|
+
function applyHostedEffortCapabilities(params) {
|
|
102812
|
+
params.env.ANTHROPIC_MODEL ||= params.modelId;
|
|
102813
|
+
params.env.ANTHROPIC_CUSTOM_MODEL_OPTION ||= params.modelId;
|
|
102814
|
+
params.env.ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIES ||= effortCapabilities(
|
|
102815
|
+
params.levels
|
|
102816
|
+
);
|
|
102686
102817
|
}
|
|
102687
102818
|
function tailLines2(text, maxCodeUnits) {
|
|
102688
102819
|
if (text.length <= maxCodeUnits) return text;
|
|
@@ -103158,7 +103289,7 @@ var claude = agent({
|
|
|
103158
103289
|
});
|
|
103159
103290
|
installBundledSkills({ home: homeEnv.HOME });
|
|
103160
103291
|
const mcpConfigPath = writeMcpConfig(ctx);
|
|
103161
|
-
const effort =
|
|
103292
|
+
const effort = resolveRunEffort(ctx);
|
|
103162
103293
|
const pretoolGate = writePretoolGateAssets(ctx);
|
|
103163
103294
|
const stopHookPath = join4(ctx.tmpdir, "pullfrog-stop-hook.sh");
|
|
103164
103295
|
writeFileSync3(stopHookPath, buildStopHookScript(), { mode: 493 });
|
|
@@ -103172,13 +103303,16 @@ var claude = agent({
|
|
|
103172
103303
|
"--settings",
|
|
103173
103304
|
pretoolGate.settingsPath,
|
|
103174
103305
|
"--verbose",
|
|
103175
|
-
"--effort",
|
|
103176
|
-
effort,
|
|
103177
103306
|
"--disallowedTools",
|
|
103178
103307
|
CLAUDE_DISALLOWED_TOOLS,
|
|
103179
103308
|
"--agents",
|
|
103180
103309
|
buildAgentsJson()
|
|
103181
103310
|
];
|
|
103311
|
+
if (effort.rung && !CLAUDE_CODE_EFFORTS.includes(effort.rung)) {
|
|
103312
|
+
log.warning(`\xBB effort ${effort.rung} not sent \u2014 claude-code doesn't accept that level`);
|
|
103313
|
+
} else if (effort.rung) {
|
|
103314
|
+
baseArgs.push("--effort", effort.rung);
|
|
103315
|
+
}
|
|
103182
103316
|
if (model) {
|
|
103183
103317
|
baseArgs.push("--model", model);
|
|
103184
103318
|
}
|
|
@@ -103196,6 +103330,9 @@ var claude = agent({
|
|
|
103196
103330
|
applyClaudeVertexEnv(env2);
|
|
103197
103331
|
env2.ANTHROPIC_MODEL = specifier;
|
|
103198
103332
|
}
|
|
103333
|
+
if ((isBedrockRoute || isVertexRoute2) && specifier && effort.alias?.effort) {
|
|
103334
|
+
applyHostedEffortCapabilities({ env: env2, modelId: specifier, levels: effort.alias.effort });
|
|
103335
|
+
}
|
|
103199
103336
|
if (env2.CLAUDE_CODE_OAUTH_TOKEN && !isBedrockRoute && env2.ANTHROPIC_API_KEY) {
|
|
103200
103337
|
const preflight = await preflightClaudeSubscription({
|
|
103201
103338
|
token: env2.CLAUDE_CODE_OAUTH_TOKEN,
|
|
@@ -103213,7 +103350,12 @@ var claude = agent({
|
|
|
103213
103350
|
delete env2.CLAUDE_CODE_OAUTH_TOKEN;
|
|
103214
103351
|
}
|
|
103215
103352
|
}
|
|
103216
|
-
|
|
103353
|
+
const effortEnvOverride = env2[CLAUDE_EFFORT_ENV]?.trim();
|
|
103354
|
+
if (effortEnvOverride) {
|
|
103355
|
+
log.warning(
|
|
103356
|
+
`\xBB ${CLAUDE_EFFORT_ENV}=${effortEnvOverride} in the run env overrides the effort setting for this session`
|
|
103357
|
+
);
|
|
103358
|
+
}
|
|
103217
103359
|
log.debug(`\xBB starting Pullfrog (Claude Code): ${cliPath} ${baseArgs.join(" ")}`);
|
|
103218
103360
|
log.debug(`\xBB working directory: ${repoDir}`);
|
|
103219
103361
|
const gateServer = __using(_stack, await startGateServer(ctx), true);
|
|
@@ -103237,7 +103379,7 @@ var claude = agent({
|
|
|
103237
103379
|
}
|
|
103238
103380
|
});
|
|
103239
103381
|
|
|
103240
|
-
// agents/
|
|
103382
|
+
// agents/opencode.ts
|
|
103241
103383
|
var core2 = __toESM(require_core(), 1);
|
|
103242
103384
|
import { spawn as nodeSpawn2 } from "node:child_process";
|
|
103243
103385
|
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
@@ -108647,7 +108789,7 @@ function createOpencodeClient(config3) {
|
|
|
108647
108789
|
// node_modules/.pnpm/@opencode-ai+sdk@1.18.5/node_modules/@opencode-ai/sdk/dist/v2/server.js
|
|
108648
108790
|
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
108649
108791
|
|
|
108650
|
-
// agents/
|
|
108792
|
+
// agents/opencode.ts
|
|
108651
108793
|
var import_undici = __toESM(require_undici2(), 1);
|
|
108652
108794
|
|
|
108653
108795
|
// utils/codexHome.ts
|
|
@@ -108962,14 +109104,6 @@ function deriveSubagentModels(orchestratorSpec) {
|
|
|
108962
109104
|
}
|
|
108963
109105
|
|
|
108964
109106
|
// agents/opencodeShared.ts
|
|
108965
|
-
function geminiHighThinkingOverrides() {
|
|
108966
|
-
return Object.fromEntries(
|
|
108967
|
-
modelAliases.filter((a) => a.provider === "google").map((a) => [
|
|
108968
|
-
a.resolve.replace(/^google\//, ""),
|
|
108969
|
-
{ options: { thinkingConfig: { thinkingLevel: "high" } } }
|
|
108970
|
-
])
|
|
108971
|
-
);
|
|
108972
|
-
}
|
|
108973
109107
|
function openAICompatibleLimit() {
|
|
108974
109108
|
return {
|
|
108975
109109
|
context: Number(process.env[OPENAI_COMPATIBLE_CONTEXT_ENV]),
|
|
@@ -109002,10 +109136,6 @@ function kimiOpenRouterProviderOverrides() {
|
|
|
109002
109136
|
])
|
|
109003
109137
|
);
|
|
109004
109138
|
}
|
|
109005
|
-
function deepseekHighEffortOverrides() {
|
|
109006
|
-
const orModel = modelAliases.find((a) => a.slug === "deepseek/deepseek-pro")?.openRouterResolve?.replace(/^openrouter\//, "");
|
|
109007
|
-
return orModel ? { [orModel]: { options: { reasoning: { effort: "high" } } } } : {};
|
|
109008
|
-
}
|
|
109009
109139
|
function buildReviewerAgentConfig(orchestratorModel) {
|
|
109010
109140
|
const overrides = deriveSubagentModels(orchestratorModel);
|
|
109011
109141
|
return {
|
|
@@ -109047,7 +109177,7 @@ function autoSelectModel() {
|
|
|
109047
109177
|
return void 0;
|
|
109048
109178
|
}
|
|
109049
109179
|
|
|
109050
|
-
// agents/
|
|
109180
|
+
// agents/opencode.ts
|
|
109051
109181
|
var installCli = () => installOpencodeCli({ binPath: "bin/opencode.exe" });
|
|
109052
109182
|
function buildSecurityConfig(ctx, model) {
|
|
109053
109183
|
const config3 = {
|
|
@@ -109074,17 +109204,13 @@ function buildSecurityConfig(ctx, model) {
|
|
|
109074
109204
|
log.info(`\xBB subagent models: reviewfrog=${reviewerModel}`);
|
|
109075
109205
|
return cfg;
|
|
109076
109206
|
})(),
|
|
109077
|
-
//
|
|
109078
|
-
//
|
|
109079
|
-
//
|
|
109080
|
-
//
|
|
109081
|
-
//
|
|
109082
|
-
// upstream default, anthropic: --effort flag in claude.ts). see opencodeShared.ts.
|
|
109207
|
+
// kimi pinned away from Enforcer-less openrouter providers (siliconflow /
|
|
109208
|
+
// together) that drop optional tool-call params — per-model on the
|
|
109209
|
+
// openrouter route, so other models are unaffected. this is routing, not
|
|
109210
|
+
// reasoning: every model's effort now rides the per-prompt `variant`.
|
|
109211
|
+
// see opencodeShared.ts.
|
|
109083
109212
|
provider: {
|
|
109084
|
-
|
|
109085
|
-
openrouter: {
|
|
109086
|
-
models: { ...deepseekHighEffortOverrides(), ...kimiOpenRouterProviderOverrides() }
|
|
109087
|
-
},
|
|
109213
|
+
openrouter: { models: kimiOpenRouterProviderOverrides() },
|
|
109088
109214
|
...openAICompatibleProvider(model)
|
|
109089
109215
|
}
|
|
109090
109216
|
};
|
|
@@ -109395,6 +109521,7 @@ async function runPromptTurn(ctx, params) {
|
|
|
109395
109521
|
{
|
|
109396
109522
|
sessionID: ctx.sessionID,
|
|
109397
109523
|
parts: [part],
|
|
109524
|
+
...ctx.variant ? { variant: ctx.variant } : {},
|
|
109398
109525
|
...params.model ? { model: params.model } : {}
|
|
109399
109526
|
},
|
|
109400
109527
|
// wire the inner activity watchdog's abort signal into the SDK request
|
|
@@ -109584,6 +109711,10 @@ var opencode = agent({
|
|
|
109584
109711
|
const cliPath = await installCli();
|
|
109585
109712
|
const rawModel = ctx.payload.proxyModel ?? ctx.resolvedModel ?? autoSelectModel();
|
|
109586
109713
|
if (rawModel) ctx.toolState.model = rawModel;
|
|
109714
|
+
const effort = resolveRunEffort({ ...ctx, resolvedModel: rawModel });
|
|
109715
|
+
if (!ctx.resolvedModel && !ctx.payload.proxyModel) {
|
|
109716
|
+
log.info(`\xBB effort: ${effort.rung ?? "n/a (model has no effort control)"}`);
|
|
109717
|
+
}
|
|
109587
109718
|
const bedrockModelId = process.env[BEDROCK_MODEL_ID_ENV]?.trim();
|
|
109588
109719
|
const isBedrockRoute = rawModel !== void 0 && bedrockModelId !== void 0 && bedrockModelId === rawModel;
|
|
109589
109720
|
const vertexModel = resolveVertexOpenCodeModel(rawModel);
|
|
@@ -109676,6 +109807,8 @@ var opencode = agent({
|
|
|
109676
109807
|
orchestratorSessionID: sessionID,
|
|
109677
109808
|
labeler,
|
|
109678
109809
|
toolState: ctx.toolState,
|
|
109810
|
+
// `rawModel` folds in the auto-select pick — see the opencode.ts twin.
|
|
109811
|
+
variant: effort.rung,
|
|
109679
109812
|
todoTracker: ctx.todoTracker,
|
|
109680
109813
|
onActivityTimeout: ctx.onActivityTimeout,
|
|
109681
109814
|
onToolUse: ctx.onToolUse,
|
|
@@ -158061,6 +158194,7 @@ var JsonPayload = type({
|
|
|
158061
158194
|
version: "string",
|
|
158062
158195
|
"model?": "string | undefined",
|
|
158063
158196
|
"modelExplicit?": "boolean | undefined",
|
|
158197
|
+
"effort?": "number | string | undefined",
|
|
158064
158198
|
prompt: "string",
|
|
158065
158199
|
"triggerer?": "string | undefined",
|
|
158066
158200
|
"baseInstructions?": "string | undefined",
|
|
@@ -158080,6 +158214,9 @@ var JsonPayload = type({
|
|
|
158080
158214
|
id: "string",
|
|
158081
158215
|
type: "'issue' | 'review'"
|
|
158082
158216
|
}).or("undefined"),
|
|
158217
|
+
// optional so a payload from an older server build (pre-`checkRun`) still parses
|
|
158218
|
+
// against a newer action across a rolling deploy.
|
|
158219
|
+
"checkRun?": type({ id: "string" }).or("undefined"),
|
|
158083
158220
|
"generateSummary?": "boolean | undefined"
|
|
158084
158221
|
});
|
|
158085
158222
|
var COLLABORATOR_PERMISSIONS = ["admin", "maintain", "write"];
|
|
@@ -158091,6 +158228,7 @@ var Inputs = type({
|
|
|
158091
158228
|
"prompt?": type.string.or("undefined"),
|
|
158092
158229
|
"prompt_file?": type.string.or("undefined"),
|
|
158093
158230
|
"model?": type.string.or("undefined"),
|
|
158231
|
+
"effort?": type.string.or("undefined"),
|
|
158094
158232
|
"timeout?": type.string.or("undefined"),
|
|
158095
158233
|
"push?": PushPermissionInput.or("undefined"),
|
|
158096
158234
|
"shell?": ShellPermissionInput.or("undefined"),
|
|
@@ -158145,6 +158283,7 @@ function resolvePromptFile(input) {
|
|
|
158145
158283
|
function resolveNonPromptInputs() {
|
|
158146
158284
|
return Inputs.omit("prompt", "prompt_file").assert({
|
|
158147
158285
|
model: core4.getInput("model") || void 0,
|
|
158286
|
+
effort: core4.getInput("effort") || void 0,
|
|
158148
158287
|
timeout: core4.getInput("timeout") || void 0,
|
|
158149
158288
|
cwd: core4.getInput("cwd") || void 0,
|
|
158150
158289
|
push: core4.getInput("push") || void 0,
|
|
@@ -158163,6 +158302,8 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
158163
158302
|
const rawEvent = jsonPayload?.event;
|
|
158164
158303
|
const event = isPayloadEvent(rawEvent) ? rawEvent : { trigger: "unknown" };
|
|
158165
158304
|
const model = jsonPayload?.model ?? inputs.model ?? repoSettings.model ?? void 0;
|
|
158305
|
+
const rawEffort = jsonPayload?.effort ?? inputs.effort ?? repoSettings.effort ?? void 0;
|
|
158306
|
+
const effort = rawEffort === void 0 ? void 0 : parseEffortPosition(String(rawEffort));
|
|
158166
158307
|
const isNonCollaborator = !isCollaborator(event);
|
|
158167
158308
|
const repoShell = repoSettings.shell ?? "restricted";
|
|
158168
158309
|
const inputShell = inputs.shell;
|
|
@@ -158182,6 +158323,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
158182
158323
|
// explicit only when the model came from a per-run override flag (carried on
|
|
158183
158324
|
// the JSON payload). a GHA `model` input or the repo default is not explicit.
|
|
158184
158325
|
modelExplicit: jsonPayload?.modelExplicit ?? false,
|
|
158326
|
+
effort,
|
|
158185
158327
|
prompt,
|
|
158186
158328
|
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
|
|
158187
158329
|
(!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
|
|
@@ -158193,13 +158335,19 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
158193
158335
|
timeout: inputs.timeout ?? jsonPayload?.timeout,
|
|
158194
158336
|
cwd: resolveCwd(inputs.cwd),
|
|
158195
158337
|
progressComment: jsonPayload?.progressComment,
|
|
158338
|
+
checkRun: jsonPayload?.checkRun,
|
|
158196
158339
|
generateSummary: jsonPayload?.generateSummary,
|
|
158197
158340
|
// permissions: inputs > repoSettings > fallbacks
|
|
158198
158341
|
push: inputs.push ?? repoSettings.push ?? "restricted",
|
|
158199
158342
|
shell: resolvedShell,
|
|
158200
|
-
//
|
|
158201
|
-
//
|
|
158202
|
-
|
|
158343
|
+
// the `pullfrog` run-lifecycle check. ON by default — the whole point is that a PR
|
|
158344
|
+
// shows whether Pullfrog is running without anyone having to opt in. the workflow
|
|
158345
|
+
// input is the source of truth when set (mirrors `push`); otherwise the repo
|
|
158346
|
+
// setting decides.
|
|
158347
|
+
runStatusCheck: inputs.status_checks === void 0 ? repoSettings.statusChecks : inputs.status_checks === "enabled",
|
|
158348
|
+
// the `pullfrog-approval` verdict check stays opt-in and workflow-only. it exists to
|
|
158349
|
+
// be *required* by branch protection, so it must never turn itself on.
|
|
158350
|
+
approvalCheck: inputs.status_checks === "enabled",
|
|
158203
158351
|
// temporary progress chrome. the workflow input is the source of truth when
|
|
158204
158352
|
// set (mirrors `push`); otherwise the repo setting decides. defaults to true.
|
|
158205
158353
|
progressComments: inputs.progress_comments === void 0 ? repoSettings.progressComments : inputs.progress_comments === "enabled",
|
|
@@ -158727,7 +158875,11 @@ async function approveAfterFix(ctx) {
|
|
|
158727
158875
|
approved: true,
|
|
158728
158876
|
hasComments: false
|
|
158729
158877
|
});
|
|
158730
|
-
ctx.toolState.approval = {
|
|
158878
|
+
ctx.toolState.approval = {
|
|
158879
|
+
wouldApprove: true,
|
|
158880
|
+
sha: headSha,
|
|
158881
|
+
url: result.data.html_url
|
|
158882
|
+
};
|
|
158731
158883
|
log.info(`\xBB auto-approved #${pullNumber} after fix run (review ${result.data.id})`);
|
|
158732
158884
|
await deleteProgressComment(ctx).catch((err) => {
|
|
158733
158885
|
log.debug(`progress comment cleanup after fix auto-approval failed: ${err}`);
|
|
@@ -159060,6 +159212,7 @@ function CreatePullRequestReviewTool(ctx) {
|
|
|
159060
159212
|
}
|
|
159061
159213
|
const reviewId = result.data.id;
|
|
159062
159214
|
const reviewNodeId = result.data.node_id;
|
|
159215
|
+
if (ctx.toolState.approval) ctx.toolState.approval.url = result.data.html_url;
|
|
159063
159216
|
log.info(`\xBB created review ${reviewId} on pull request #${pull_number}`);
|
|
159064
159217
|
const actuallyReviewedSha = primary.checkoutSha ?? params.commit_id;
|
|
159065
159218
|
ctx.toolState.review = {
|
|
@@ -163636,6 +163789,140 @@ function formatApiKeyErrorSummary(params) {
|
|
|
163636
163789
|
].join("\n");
|
|
163637
163790
|
}
|
|
163638
163791
|
|
|
163792
|
+
// utils/billingErrors.ts
|
|
163793
|
+
var BillingError = class extends Error {
|
|
163794
|
+
code;
|
|
163795
|
+
declineCode;
|
|
163796
|
+
needsReauthentication;
|
|
163797
|
+
constructor(message, opts = {}) {
|
|
163798
|
+
super(message);
|
|
163799
|
+
this.name = "BillingError";
|
|
163800
|
+
this.code = opts.code ?? null;
|
|
163801
|
+
this.declineCode = opts.declineCode ?? null;
|
|
163802
|
+
this.needsReauthentication = opts.needsReauthentication ?? false;
|
|
163803
|
+
}
|
|
163804
|
+
};
|
|
163805
|
+
var TransientError = class extends Error {
|
|
163806
|
+
constructor(message) {
|
|
163807
|
+
super(message);
|
|
163808
|
+
this.name = "TransientError";
|
|
163809
|
+
}
|
|
163810
|
+
};
|
|
163811
|
+
function billingConsoleUrl(owner) {
|
|
163812
|
+
return `https://pullfrog.com/console/${encodeURIComponent(owner)}#billing`;
|
|
163813
|
+
}
|
|
163814
|
+
function commercialPaywallBody(params) {
|
|
163815
|
+
if (params.reason === "commercial") {
|
|
163816
|
+
return [
|
|
163817
|
+
`**Pullfrog needs a confirmed Pro plan for ${params.ownerLogin}, so this run paused.**`,
|
|
163818
|
+
"",
|
|
163819
|
+
"Open Plan and payment to confirm Pro or review the organization's billing status.",
|
|
163820
|
+
"",
|
|
163821
|
+
`[Review plan and payment \u2192](${params.url})`
|
|
163822
|
+
].join("\n");
|
|
163823
|
+
}
|
|
163824
|
+
params.reason;
|
|
163825
|
+
return [
|
|
163826
|
+
`**Pullfrog paused runs on ${params.ownerLogin}: the Pro renewal failed.**`,
|
|
163827
|
+
"",
|
|
163828
|
+
"Update the card on file to resume runs.",
|
|
163829
|
+
"",
|
|
163830
|
+
`[Update billing \u2192](${params.url})`
|
|
163831
|
+
].join("\n");
|
|
163832
|
+
}
|
|
163833
|
+
function formatCommercialGateSummary(params) {
|
|
163834
|
+
return commercialPaywallBody({
|
|
163835
|
+
reason: params.reason,
|
|
163836
|
+
ownerLogin: params.ownerLogin,
|
|
163837
|
+
url: billingConsoleUrl(params.ownerLogin)
|
|
163838
|
+
});
|
|
163839
|
+
}
|
|
163840
|
+
function formatBillingErrorSummary(error49, owner) {
|
|
163841
|
+
if (error49.code === "router_requires_card") {
|
|
163842
|
+
return [
|
|
163843
|
+
"**Your Pullfrog Router balance is empty.**",
|
|
163844
|
+
"",
|
|
163845
|
+
"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.",
|
|
163846
|
+
"",
|
|
163847
|
+
`[Add a card to top up \u2192](${billingConsoleUrl(owner)}) \xB7 [Bring your own key \u2192](${billingConsoleUrl(owner)})`
|
|
163848
|
+
].join("\n");
|
|
163849
|
+
}
|
|
163850
|
+
if (error49.code === "router_balance_exhausted") {
|
|
163851
|
+
return [
|
|
163852
|
+
"**Your Pullfrog Router balance is exhausted.**",
|
|
163853
|
+
"",
|
|
163854
|
+
"You have a payment method on file but auto-reload is disabled, so runs paused once your balance went past the overdraft buffer.",
|
|
163855
|
+
"",
|
|
163856
|
+
`[Top up balance \u2192](${billingConsoleUrl(owner)}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner)})`
|
|
163857
|
+
].join("\n");
|
|
163858
|
+
}
|
|
163859
|
+
if (error49.code === "router_keylimit_exhausted") {
|
|
163860
|
+
return [
|
|
163861
|
+
"**This run was cut short: your Pullfrog Router balance ran out mid-run.**",
|
|
163862
|
+
"",
|
|
163863
|
+
"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.",
|
|
163864
|
+
"",
|
|
163865
|
+
`[Top up balance \u2192](${billingConsoleUrl(owner)}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner)})`
|
|
163866
|
+
].join("\n");
|
|
163867
|
+
}
|
|
163868
|
+
if (error49.code === "router_monthly_limit") {
|
|
163869
|
+
return [
|
|
163870
|
+
"**Pullfrog Router hit its monthly spend limit.**",
|
|
163871
|
+
"",
|
|
163872
|
+
"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.",
|
|
163873
|
+
"",
|
|
163874
|
+
`[Adjust limit \u2192](${billingConsoleUrl(owner)})`
|
|
163875
|
+
].join("\n");
|
|
163876
|
+
}
|
|
163877
|
+
if (error49.code === "commercial_plan_required") {
|
|
163878
|
+
return formatCommercialGateSummary({
|
|
163879
|
+
reason: "commercial",
|
|
163880
|
+
ownerLogin: owner
|
|
163881
|
+
});
|
|
163882
|
+
}
|
|
163883
|
+
if (error49.code === "subscription_unpaid") {
|
|
163884
|
+
return formatCommercialGateSummary({
|
|
163885
|
+
reason: "subscription_unpaid",
|
|
163886
|
+
ownerLogin: owner
|
|
163887
|
+
});
|
|
163888
|
+
}
|
|
163889
|
+
if (error49.needsReauthentication) {
|
|
163890
|
+
const code = error49.declineCode ?? "authentication_required";
|
|
163891
|
+
return [
|
|
163892
|
+
`**Your card issuer requires 3D Secure on every charge** (\`${code}\`).`,
|
|
163893
|
+
"",
|
|
163894
|
+
"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.",
|
|
163895
|
+
"",
|
|
163896
|
+
`[Top up balance \u2192](${billingConsoleUrl(owner)})`
|
|
163897
|
+
].join("\n");
|
|
163898
|
+
}
|
|
163899
|
+
if (error49.declineCode) {
|
|
163900
|
+
return [
|
|
163901
|
+
`**Your card was declined** (\`${error49.declineCode}\`).`,
|
|
163902
|
+
"",
|
|
163903
|
+
"Update your payment method and Pullfrog will retry on the next run.",
|
|
163904
|
+
"",
|
|
163905
|
+
`[Update payment method \u2192](${billingConsoleUrl(owner)})`
|
|
163906
|
+
].join("\n");
|
|
163907
|
+
}
|
|
163908
|
+
return [
|
|
163909
|
+
"**Your Pullfrog balance is empty.**",
|
|
163910
|
+
"",
|
|
163911
|
+
"Top up your balance or enable auto-reload to keep runs flowing.",
|
|
163912
|
+
"",
|
|
163913
|
+
`[Manage billing \u2192](${billingConsoleUrl(owner)})`
|
|
163914
|
+
].join("\n");
|
|
163915
|
+
}
|
|
163916
|
+
function formatTransientErrorSummary(error49, owner) {
|
|
163917
|
+
return [
|
|
163918
|
+
"**Pullfrog billing is temporarily unavailable.**",
|
|
163919
|
+
"",
|
|
163920
|
+
error49.message,
|
|
163921
|
+
"",
|
|
163922
|
+
`Usually transient; the next dispatch should succeed. If it persists, check [status.pullfrog.com](https://status.pullfrog.com) or [your console](${billingConsoleUrl(owner)}).`
|
|
163923
|
+
].join("\n");
|
|
163924
|
+
}
|
|
163925
|
+
|
|
163639
163926
|
// utils/gitAuthServer.ts
|
|
163640
163927
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
163641
163928
|
import { writeFileSync as writeFileSync13 } from "node:fs";
|
|
@@ -164436,102 +164723,6 @@ function applyOverrides(params) {
|
|
|
164436
164723
|
// utils/proxy.ts
|
|
164437
164724
|
var core8 = __toESM(require_core(), 1);
|
|
164438
164725
|
|
|
164439
|
-
// utils/billingErrors.ts
|
|
164440
|
-
var BillingError = class extends Error {
|
|
164441
|
-
code;
|
|
164442
|
-
declineCode;
|
|
164443
|
-
needsReauthentication;
|
|
164444
|
-
constructor(message, opts = {}) {
|
|
164445
|
-
super(message);
|
|
164446
|
-
this.name = "BillingError";
|
|
164447
|
-
this.code = opts.code ?? null;
|
|
164448
|
-
this.declineCode = opts.declineCode ?? null;
|
|
164449
|
-
this.needsReauthentication = opts.needsReauthentication ?? false;
|
|
164450
|
-
}
|
|
164451
|
-
};
|
|
164452
|
-
var TransientError = class extends Error {
|
|
164453
|
-
constructor(message) {
|
|
164454
|
-
super(message);
|
|
164455
|
-
this.name = "TransientError";
|
|
164456
|
-
}
|
|
164457
|
-
};
|
|
164458
|
-
function billingConsoleUrl(owner, anchor) {
|
|
164459
|
-
return `https://pullfrog.com/console/${encodeURIComponent(owner)}#${anchor}`;
|
|
164460
|
-
}
|
|
164461
|
-
function formatBillingErrorSummary(error49, owner) {
|
|
164462
|
-
if (error49.code === "router_requires_card") {
|
|
164463
|
-
return [
|
|
164464
|
-
"**Add a card to start using Pullfrog Router.**",
|
|
164465
|
-
"",
|
|
164466
|
-
"Router proxies OpenRouter at raw cost \u2014 no platform markup. Add a card and we'll auto-reload your wallet so runs keep flowing.",
|
|
164467
|
-
"",
|
|
164468
|
-
`[Add a card \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
164469
|
-
].join("\n");
|
|
164470
|
-
}
|
|
164471
|
-
if (error49.code === "router_balance_exhausted") {
|
|
164472
|
-
return [
|
|
164473
|
-
"**Your Pullfrog Router balance is exhausted.**",
|
|
164474
|
-
"",
|
|
164475
|
-
"You have a payment method on file but auto-reload is disabled, so runs paused once your balance went past the overdraft buffer.",
|
|
164476
|
-
"",
|
|
164477
|
-
`[Top up balance \u2192](${billingConsoleUrl(owner, "billing")}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
164478
|
-
].join("\n");
|
|
164479
|
-
}
|
|
164480
|
-
if (error49.code === "router_keylimit_exhausted") {
|
|
164481
|
-
return [
|
|
164482
|
-
"**This run was cut short \u2014 your Pullfrog Router balance ran out mid-run.**",
|
|
164483
|
-
"",
|
|
164484
|
-
"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.",
|
|
164485
|
-
"",
|
|
164486
|
-
`[Top up balance \u2192](${billingConsoleUrl(owner, "billing")}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
164487
|
-
].join("\n");
|
|
164488
|
-
}
|
|
164489
|
-
if (error49.code === "router_monthly_limit") {
|
|
164490
|
-
return [
|
|
164491
|
-
"**Pullfrog Router hit its monthly spend limit.**",
|
|
164492
|
-
"",
|
|
164493
|
-
"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.",
|
|
164494
|
-
"",
|
|
164495
|
-
`[Adjust limit \u2192](${billingConsoleUrl(owner, "model-access")})`
|
|
164496
|
-
].join("\n");
|
|
164497
|
-
}
|
|
164498
|
-
if (error49.needsReauthentication) {
|
|
164499
|
-
const code = error49.declineCode ?? "authentication_required";
|
|
164500
|
-
return [
|
|
164501
|
-
`**Your card issuer requires 3D Secure on every charge** (\`${code}\`).`,
|
|
164502
|
-
"",
|
|
164503
|
-
"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.",
|
|
164504
|
-
"",
|
|
164505
|
-
`[Top up balance \u2192](${billingConsoleUrl(owner, "billing")})`
|
|
164506
|
-
].join("\n");
|
|
164507
|
-
}
|
|
164508
|
-
if (error49.declineCode) {
|
|
164509
|
-
return [
|
|
164510
|
-
`**Your card was declined** (\`${error49.declineCode}\`).`,
|
|
164511
|
-
"",
|
|
164512
|
-
"Update your payment method and Pullfrog will retry on the next run.",
|
|
164513
|
-
"",
|
|
164514
|
-
`[Update payment method \u2192](${billingConsoleUrl(owner, "billing")})`
|
|
164515
|
-
].join("\n");
|
|
164516
|
-
}
|
|
164517
|
-
return [
|
|
164518
|
-
"**Your Pullfrog balance is empty.**",
|
|
164519
|
-
"",
|
|
164520
|
-
"Top up your balance or enable auto-reload to keep runs flowing.",
|
|
164521
|
-
"",
|
|
164522
|
-
`[Manage billing \u2192](${billingConsoleUrl(owner, "billing")})`
|
|
164523
|
-
].join("\n");
|
|
164524
|
-
}
|
|
164525
|
-
function formatTransientErrorSummary(error49, owner) {
|
|
164526
|
-
return [
|
|
164527
|
-
"**Pullfrog billing is temporarily unavailable.**",
|
|
164528
|
-
"",
|
|
164529
|
-
error49.message,
|
|
164530
|
-
"",
|
|
164531
|
-
`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")}).`
|
|
164532
|
-
].join("\n");
|
|
164533
|
-
}
|
|
164534
|
-
|
|
164535
164726
|
// utils/token.ts
|
|
164536
164727
|
var core7 = __toESM(require_core(), 1);
|
|
164537
164728
|
import assert2 from "node:assert/strict";
|
|
@@ -165065,6 +165256,7 @@ var core9 = __toESM(require_core(), 1);
|
|
|
165065
165256
|
// utils/runContext.ts
|
|
165066
165257
|
var defaultSettings = {
|
|
165067
165258
|
model: null,
|
|
165259
|
+
effort: null,
|
|
165068
165260
|
modes: [],
|
|
165069
165261
|
setupScript: null,
|
|
165070
165262
|
postCheckoutScript: null,
|
|
@@ -165076,6 +165268,7 @@ var defaultSettings = {
|
|
|
165076
165268
|
autoMergeEnabled: false,
|
|
165077
165269
|
signedCommits: false,
|
|
165078
165270
|
progressComments: true,
|
|
165271
|
+
statusChecks: true,
|
|
165079
165272
|
modeInstructions: {},
|
|
165080
165273
|
learnings: null,
|
|
165081
165274
|
learningsHeadings: [],
|
|
@@ -165111,6 +165304,11 @@ async function fetchRunContext(params) {
|
|
|
165111
165304
|
signal: controller.signal
|
|
165112
165305
|
});
|
|
165113
165306
|
clearTimeout(timeoutId);
|
|
165307
|
+
if (response.status === 402) {
|
|
165308
|
+
const body = await response.json().catch(() => null);
|
|
165309
|
+
const reason = typeof body === "object" && body !== null && "reason" in body && body.reason === "subscription_unpaid" ? "subscription_unpaid" : "commercial";
|
|
165310
|
+
return { ...defaultRunContext, commercialRefused: reason };
|
|
165311
|
+
}
|
|
165114
165312
|
if (!response.ok) {
|
|
165115
165313
|
return response.status >= 500 ? unknownSecretsRunContext : defaultRunContext;
|
|
165116
165314
|
}
|
|
@@ -165189,6 +165387,7 @@ async function resolveRunContextData(params) {
|
|
|
165189
165387
|
plan: runContext.plan,
|
|
165190
165388
|
proxyModel: runContext.proxyModel,
|
|
165191
165389
|
dbSecrets: runContext.dbSecrets,
|
|
165390
|
+
commercialRefused: runContext.commercialRefused,
|
|
165192
165391
|
// a failed mint on a runner that should have been able to mint is the same
|
|
165193
165392
|
// outcome as the server-side failure: the run never sees stored secrets.
|
|
165194
165393
|
secretsUnavailable: runContext.secretsUnavailable || !!process.env.ACTIONS_ID_TOKEN_REQUEST_URL && oidcToken === void 0
|
|
@@ -165572,6 +165771,7 @@ async function dispatchFollowUpReReview(ctx, reviewedSha) {
|
|
|
165572
165771
|
"~pullfrog": true,
|
|
165573
165772
|
version: ctx.payload.version,
|
|
165574
165773
|
model: ctx.payload.model,
|
|
165774
|
+
effort: ctx.payload.effort,
|
|
165575
165775
|
prompt: "",
|
|
165576
165776
|
eventInstructions: RE_REVIEW_PREAMBLE,
|
|
165577
165777
|
event
|
|
@@ -165597,30 +165797,123 @@ function getCurrentWorkflowFilename() {
|
|
|
165597
165797
|
return match3?.[1] ?? "pullfrog.yml";
|
|
165598
165798
|
}
|
|
165599
165799
|
|
|
165600
|
-
// utils/
|
|
165601
|
-
var
|
|
165602
|
-
var
|
|
165603
|
-
|
|
165800
|
+
// utils/runStatusCheck.ts
|
|
165801
|
+
var RUN_STATUS_CHECK_NAME = "Pullfrog";
|
|
165802
|
+
var APPROVAL_CHECK_NAME = "Pullfrog approval";
|
|
165803
|
+
function parseCheckRunId(raw2) {
|
|
165804
|
+
if (!raw2?.id) return void 0;
|
|
165805
|
+
const id = parseInt(raw2.id, 10);
|
|
165806
|
+
if (Number.isNaN(id) || id <= 0) return void 0;
|
|
165807
|
+
return id;
|
|
165808
|
+
}
|
|
165809
|
+
function disableCheckLine(owner, repo) {
|
|
165810
|
+
const url4 = `https://pullfrog.com/console/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}#auto-review-prs`;
|
|
165811
|
+
return `
|
|
165812
|
+
|
|
165813
|
+
[Turn off this check \u2192](${url4}) \u2014 it reports run status only and gates nothing unless you required it in branch protection.`;
|
|
165814
|
+
}
|
|
165815
|
+
var TERMINAL_OUTPUT = {
|
|
165816
|
+
success: {
|
|
165817
|
+
title: "Pullfrog run completed",
|
|
165818
|
+
summary: "The Pullfrog run finished successfully."
|
|
165819
|
+
},
|
|
165820
|
+
failure: {
|
|
165821
|
+
title: "Pullfrog run failed",
|
|
165822
|
+
summary: "The Pullfrog run failed. See the run logs for details."
|
|
165823
|
+
},
|
|
165824
|
+
cancelled: {
|
|
165825
|
+
title: "Pullfrog run cancelled",
|
|
165826
|
+
summary: "The Pullfrog run was cancelled before it finished."
|
|
165827
|
+
},
|
|
165828
|
+
timed_out: {
|
|
165829
|
+
title: "Pullfrog run timed out",
|
|
165830
|
+
summary: "The Pullfrog run exceeded its timeout. See the run logs for details."
|
|
165831
|
+
},
|
|
165832
|
+
action_required: {
|
|
165833
|
+
title: "Pullfrog run needs attention",
|
|
165834
|
+
summary: "The Pullfrog run stopped and needs attention. See the run logs for details."
|
|
165835
|
+
},
|
|
165836
|
+
neutral: {
|
|
165837
|
+
title: "Pullfrog run finished",
|
|
165838
|
+
summary: "The Pullfrog run finished without a pass or fail outcome."
|
|
165839
|
+
},
|
|
165840
|
+
skipped: {
|
|
165841
|
+
title: "Pullfrog run skipped",
|
|
165842
|
+
summary: "This run was superseded by another Pullfrog run."
|
|
165843
|
+
},
|
|
165844
|
+
stale: {
|
|
165845
|
+
title: "Pullfrog run didn't finish",
|
|
165846
|
+
summary: "Pullfrog never received a completion signal for this run. See the run logs for details."
|
|
165847
|
+
}
|
|
165848
|
+
};
|
|
165849
|
+
function terminalOutput(params) {
|
|
165850
|
+
const base = TERMINAL_OUTPUT[params.conclusion];
|
|
165851
|
+
const review = params.reviewUrl ? `
|
|
165852
|
+
|
|
165853
|
+
[View the review Pullfrog posted \u2192](${params.reviewUrl})` : "";
|
|
165854
|
+
const disable = params.conclusion === "success" ? "" : disableCheckLine(params.owner, params.repo);
|
|
165855
|
+
return { title: base.title, summary: base.summary + review + disable };
|
|
165856
|
+
}
|
|
165857
|
+
async function finalizeRunStatusCheck(params) {
|
|
165858
|
+
const updateParams = {
|
|
165859
|
+
owner: params.owner,
|
|
165860
|
+
repo: params.repo,
|
|
165861
|
+
check_run_id: params.checkRunId,
|
|
165862
|
+
status: "completed",
|
|
165863
|
+
conclusion: params.conclusion,
|
|
165864
|
+
output: terminalOutput({
|
|
165865
|
+
conclusion: params.conclusion,
|
|
165866
|
+
owner: params.owner,
|
|
165867
|
+
repo: params.repo,
|
|
165868
|
+
reviewUrl: params.reviewUrl
|
|
165869
|
+
})
|
|
165870
|
+
};
|
|
165871
|
+
if (params.detailsUrl) updateParams.details_url = params.detailsUrl;
|
|
165872
|
+
await params.octokit.rest.checks.update(updateParams);
|
|
165873
|
+
}
|
|
165874
|
+
async function createTerminalRunStatusCheck(params) {
|
|
165604
165875
|
const createParams = {
|
|
165605
|
-
owner:
|
|
165606
|
-
repo:
|
|
165607
|
-
name:
|
|
165876
|
+
owner: params.owner,
|
|
165877
|
+
repo: params.repo,
|
|
165878
|
+
name: RUN_STATUS_CHECK_NAME,
|
|
165608
165879
|
head_sha: params.headSha,
|
|
165609
165880
|
status: "completed",
|
|
165610
165881
|
conclusion: params.conclusion,
|
|
165611
|
-
output: {
|
|
165882
|
+
output: terminalOutput({
|
|
165883
|
+
conclusion: params.conclusion,
|
|
165884
|
+
owner: params.owner,
|
|
165885
|
+
repo: params.repo,
|
|
165886
|
+
reviewUrl: params.reviewUrl
|
|
165887
|
+
})
|
|
165612
165888
|
};
|
|
165613
|
-
if (
|
|
165614
|
-
|
|
165615
|
-
}
|
|
165616
|
-
await ctx.octokit.rest.checks.create(createParams);
|
|
165617
|
-
log.info(`\xBB posted ${params.name} check (${params.conclusion}) on ${params.headSha.slice(0, 7)}`);
|
|
165889
|
+
if (params.detailsUrl) createParams.details_url = params.detailsUrl;
|
|
165890
|
+
await params.octokit.rest.checks.create(createParams);
|
|
165618
165891
|
}
|
|
165892
|
+
|
|
165893
|
+
// utils/statusChecks.ts
|
|
165619
165894
|
async function reportStatusChecks(ctx, params) {
|
|
165620
|
-
if (!ctx.payload.statusChecks) return;
|
|
165621
165895
|
const event = ctx.payload.event;
|
|
165622
165896
|
const pullNumber = event.issue_number;
|
|
165623
165897
|
if (event.is_pr !== true || typeof pullNumber !== "number") return;
|
|
165898
|
+
const checkRunId = parseCheckRunId(ctx.payload.checkRun);
|
|
165899
|
+
if (checkRunId === void 0 && !ctx.payload.runStatusCheck && !ctx.payload.approvalCheck) return;
|
|
165900
|
+
const conclusion = params.runSucceeded ? "success" : "failure";
|
|
165901
|
+
const detailsUrl = ctx.runId ? `https://github.com/${ctx.repo.owner}/${ctx.repo.name}/actions/runs/${ctx.runId}` : void 0;
|
|
165902
|
+
if (checkRunId !== void 0) {
|
|
165903
|
+
await finalizeRunStatusCheck({
|
|
165904
|
+
octokit: ctx.octokit,
|
|
165905
|
+
owner: ctx.repo.owner,
|
|
165906
|
+
repo: ctx.repo.name,
|
|
165907
|
+
checkRunId,
|
|
165908
|
+
conclusion,
|
|
165909
|
+
detailsUrl,
|
|
165910
|
+
reviewUrl: ctx.toolState.approval?.url
|
|
165911
|
+
}).then(() => log.info(`\xBB finalized ${RUN_STATUS_CHECK_NAME} check (${conclusion})`)).catch((err) => log.debug(`status checks: ${RUN_STATUS_CHECK_NAME} finalize failed: ${err}`));
|
|
165912
|
+
}
|
|
165913
|
+
const approval = ctx.toolState.approval;
|
|
165914
|
+
const needsApprovalCheck = ctx.payload.approvalCheck && params.runSucceeded && approval;
|
|
165915
|
+
const needsFallbackRunCheck = ctx.payload.runStatusCheck && checkRunId === void 0;
|
|
165916
|
+
if (!needsApprovalCheck && !needsFallbackRunCheck) return;
|
|
165624
165917
|
let headSha;
|
|
165625
165918
|
try {
|
|
165626
165919
|
const pr = await ctx.octokit.rest.pulls.get({
|
|
@@ -165633,24 +165926,32 @@ async function reportStatusChecks(ctx, params) {
|
|
|
165633
165926
|
log.debug(`status checks: failed to resolve PR #${pullNumber} head sha: ${err}`);
|
|
165634
165927
|
return;
|
|
165635
165928
|
}
|
|
165636
|
-
|
|
165637
|
-
|
|
165638
|
-
|
|
165639
|
-
|
|
165640
|
-
|
|
165641
|
-
|
|
165642
|
-
|
|
165643
|
-
|
|
165644
|
-
|
|
165645
|
-
|
|
165646
|
-
|
|
165647
|
-
|
|
165648
|
-
|
|
165649
|
-
|
|
165929
|
+
if (needsFallbackRunCheck) {
|
|
165930
|
+
await createTerminalRunStatusCheck({
|
|
165931
|
+
octokit: ctx.octokit,
|
|
165932
|
+
owner: ctx.repo.owner,
|
|
165933
|
+
repo: ctx.repo.name,
|
|
165934
|
+
headSha: primaryRepoState(ctx.toolState).checkoutSha ?? headSha,
|
|
165935
|
+
conclusion,
|
|
165936
|
+
detailsUrl,
|
|
165937
|
+
reviewUrl: ctx.toolState.approval?.url
|
|
165938
|
+
}).then(() => log.info(`\xBB posted ${RUN_STATUS_CHECK_NAME} check (${conclusion})`)).catch((err) => log.debug(`status checks: ${RUN_STATUS_CHECK_NAME} post failed: ${err}`));
|
|
165939
|
+
}
|
|
165940
|
+
if (!needsApprovalCheck || !approval) return;
|
|
165941
|
+
const createParams = {
|
|
165942
|
+
owner: ctx.repo.owner,
|
|
165943
|
+
repo: ctx.repo.name,
|
|
165944
|
+
name: APPROVAL_CHECK_NAME,
|
|
165945
|
+
head_sha: approval.sha ?? headSha,
|
|
165946
|
+
status: "completed",
|
|
165947
|
+
conclusion: approval.wouldApprove ? "success" : "failure",
|
|
165948
|
+
output: {
|
|
165650
165949
|
title: approval.wouldApprove ? "Pullfrog would approve" : "Pullfrog would not approve",
|
|
165651
165950
|
summary: approval.wouldApprove ? "Pullfrog has no outstanding review feedback on this PR." : "Pullfrog has outstanding review feedback or requested changes on this PR."
|
|
165652
|
-
}
|
|
165653
|
-
}
|
|
165951
|
+
}
|
|
165952
|
+
};
|
|
165953
|
+
if (detailsUrl) createParams.details_url = detailsUrl;
|
|
165954
|
+
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}`));
|
|
165654
165955
|
}
|
|
165655
165956
|
|
|
165656
165957
|
// utils/runLifecycle.ts
|
|
@@ -165723,7 +166024,8 @@ async function writeRunErrorOutputs(input) {
|
|
|
165723
166024
|
error: input.rendered.comment,
|
|
165724
166025
|
createIfMissing: true
|
|
165725
166026
|
});
|
|
165726
|
-
} catch {
|
|
166027
|
+
} catch (error49) {
|
|
166028
|
+
log.warning(`error comment failed: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
165727
166029
|
}
|
|
165728
166030
|
}
|
|
165729
166031
|
|
|
@@ -165763,6 +166065,13 @@ function resolveModelForLog(ctx) {
|
|
|
165763
166065
|
if (ctx.payload.model) return `${ctx.payload.model} (unresolved)`;
|
|
165764
166066
|
return "auto";
|
|
165765
166067
|
}
|
|
166068
|
+
function resolveEffortForLog(ctx) {
|
|
166069
|
+
const effort = resolveRunEffort(ctx);
|
|
166070
|
+
if (!ctx.resolvedModel && !ctx.payload.proxyModel) return "pending \u2014 model not chosen yet";
|
|
166071
|
+
if (!effort.alias) return "not applied \u2014 model not recognized";
|
|
166072
|
+
if (!effort.rung) return "n/a (model has no effort control)";
|
|
166073
|
+
return effort.configured ? effort.rung : `${effort.rung} (default)`;
|
|
166074
|
+
}
|
|
165766
166075
|
function resolveAgentForLog(ctx) {
|
|
165767
166076
|
const envAgent = process.env.PULLFROG_AGENT?.trim();
|
|
165768
166077
|
if (envAgent && envAgent === ctx.agentName) {
|
|
@@ -165777,6 +166086,9 @@ function logRunStartup(ctx) {
|
|
|
165777
166086
|
log.info(
|
|
165778
166087
|
`\xBB model: ${resolveModelForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`
|
|
165779
166088
|
);
|
|
166089
|
+
log.info(
|
|
166090
|
+
`\xBB effort: ${resolveEffortForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`
|
|
166091
|
+
);
|
|
165780
166092
|
log.info(
|
|
165781
166093
|
`\xBB agent: ${resolveAgentForLog({ agentName: ctx.agentName, resolvedModel: ctx.resolvedModel })}`
|
|
165782
166094
|
);
|
|
@@ -165942,7 +166254,7 @@ async function resolveRun(params) {
|
|
|
165942
166254
|
|
|
165943
166255
|
// main.ts
|
|
165944
166256
|
async function main() {
|
|
165945
|
-
var
|
|
166257
|
+
var _stack3 = [];
|
|
165946
166258
|
try {
|
|
165947
166259
|
normalizeEnv();
|
|
165948
166260
|
const overridesRaw = process.env.UNSAFE_OVERRIDES ?? "";
|
|
@@ -165970,12 +166282,48 @@ async function main() {
|
|
|
165970
166282
|
const initialOctokit = createOctokit(jobToken);
|
|
165971
166283
|
const runContext = await resolveRunContextData({ octokit: initialOctokit, token: jobToken });
|
|
165972
166284
|
timer.checkpoint("runContextData");
|
|
166285
|
+
const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
|
|
165973
166286
|
const toolState = initToolState({
|
|
165974
166287
|
progressComment: typeof resolvedPromptInput !== "string" ? resolvedPromptInput.progressComment : void 0,
|
|
165975
166288
|
owner: runContext.repo.owner,
|
|
165976
166289
|
name: runContext.repo.name,
|
|
165977
166290
|
dir: process.cwd()
|
|
165978
166291
|
});
|
|
166292
|
+
toolState.model = payload.model;
|
|
166293
|
+
toolState.oss = runContext.oss;
|
|
166294
|
+
toolState.shaPinned = isActionPinnedToSha();
|
|
166295
|
+
if (payload.event.issue_number !== void 0) {
|
|
166296
|
+
primaryRepoState(toolState).issueNumber = payload.event.issue_number;
|
|
166297
|
+
}
|
|
166298
|
+
if (payload.event.trigger === "pull_request_synchronize") {
|
|
166299
|
+
primaryRepoState(toolState).beforeSha = payload.event.before_sha;
|
|
166300
|
+
}
|
|
166301
|
+
const oidcCredentials = process.env.ACTIONS_ID_TOKEN_REQUEST_URL && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN ? {
|
|
166302
|
+
requestUrl: process.env.ACTIONS_ID_TOKEN_REQUEST_URL,
|
|
166303
|
+
requestToken: process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN
|
|
166304
|
+
} : null;
|
|
166305
|
+
if (runContext.commercialRefused) {
|
|
166306
|
+
var _stack = [];
|
|
166307
|
+
try {
|
|
166308
|
+
const _commentTokenRef = __using(_stack, await resolveTokens({
|
|
166309
|
+
push: "disabled",
|
|
166310
|
+
oidc: oidcCredentials
|
|
166311
|
+
}), true);
|
|
166312
|
+
const errorMessage = runContext.commercialRefused === "subscription_unpaid" ? "Pro renewal failed for this organization" : "Pro plan required for this organization";
|
|
166313
|
+
log.error(errorMessage);
|
|
166314
|
+
const body = formatCommercialGateSummary({
|
|
166315
|
+
reason: runContext.commercialRefused,
|
|
166316
|
+
ownerLogin: runContext.repo.owner
|
|
166317
|
+
});
|
|
166318
|
+
await writeRunErrorOutputs({ rendered: { summary: body, comment: body }, toolState });
|
|
166319
|
+
return { success: false, error: errorMessage };
|
|
166320
|
+
} catch (_) {
|
|
166321
|
+
var _error = _, _hasError = true;
|
|
166322
|
+
} finally {
|
|
166323
|
+
var _promise2 = __callDispose(_stack, _error, _hasError);
|
|
166324
|
+
_promise2 && await _promise2;
|
|
166325
|
+
}
|
|
166326
|
+
}
|
|
165979
166327
|
createTempDirectory();
|
|
165980
166328
|
const opencodeCliPath = await agents.opencode.install();
|
|
165981
166329
|
captureBaselineModels(opencodeCliPath);
|
|
@@ -165994,27 +166342,13 @@ async function main() {
|
|
|
165994
166342
|
if (runContext.repoSettings.envAllowlist) {
|
|
165995
166343
|
setEnvAllowlist(runContext.repoSettings.envAllowlist);
|
|
165996
166344
|
}
|
|
165997
|
-
const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
|
|
165998
|
-
toolState.model = payload.model;
|
|
165999
|
-
toolState.oss = runContext.oss;
|
|
166000
|
-
toolState.shaPinned = isActionPinnedToSha();
|
|
166001
|
-
if (payload.event.issue_number !== void 0) {
|
|
166002
|
-
primaryRepoState(toolState).issueNumber = payload.event.issue_number;
|
|
166003
|
-
}
|
|
166004
|
-
if (payload.event.trigger === "pull_request_synchronize") {
|
|
166005
|
-
primaryRepoState(toolState).beforeSha = payload.event.before_sha;
|
|
166006
|
-
}
|
|
166007
|
-
const oidcCredentials = process.env.ACTIONS_ID_TOKEN_REQUEST_URL && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN ? {
|
|
166008
|
-
requestUrl: process.env.ACTIONS_ID_TOKEN_REQUEST_URL,
|
|
166009
|
-
requestToken: process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN
|
|
166010
|
-
} : null;
|
|
166011
166345
|
const xrepoUnavailable = payload.xrepo?.unavailable ?? [];
|
|
166012
166346
|
if (xrepoUnavailable.length > 0) {
|
|
166013
166347
|
log.warning(
|
|
166014
166348
|
`\xBB --xrepo: requested but not granted: ${xrepoUnavailable.join(", ")} (unknown repo, different owner, or you lack access)`
|
|
166015
166349
|
);
|
|
166016
166350
|
}
|
|
166017
|
-
const tokenRef = __using(
|
|
166351
|
+
const tokenRef = __using(_stack3, await resolveTokens({
|
|
166018
166352
|
push: payload.push,
|
|
166019
166353
|
xrepo: payload.xrepo,
|
|
166020
166354
|
oidc: oidcCredentials
|
|
@@ -166039,7 +166373,7 @@ async function main() {
|
|
|
166039
166373
|
let todoTracker;
|
|
166040
166374
|
let vertexCredentials;
|
|
166041
166375
|
try {
|
|
166042
|
-
var
|
|
166376
|
+
var _stack2 = [];
|
|
166043
166377
|
try {
|
|
166044
166378
|
if (payload.cwd && process.cwd() !== payload.cwd) {
|
|
166045
166379
|
process.chdir(payload.cwd);
|
|
@@ -166059,7 +166393,7 @@ async function main() {
|
|
|
166059
166393
|
payload.prompt = payload.prompt.replace(originalBody, resolvedBody ?? "");
|
|
166060
166394
|
}
|
|
166061
166395
|
}
|
|
166062
|
-
const gitAuthServer = __using(
|
|
166396
|
+
const gitAuthServer = __using(_stack2, await startGitAuthServer(tmpdir3), true);
|
|
166063
166397
|
setGitAuthServer(gitAuthServer);
|
|
166064
166398
|
const access = decideModelAccess({
|
|
166065
166399
|
modelExplicit: payload.modelExplicit ?? false,
|
|
@@ -166082,6 +166416,7 @@ async function main() {
|
|
|
166082
166416
|
}
|
|
166083
166417
|
if (access.kind === "proxy") payload.proxyModel = access.target;
|
|
166084
166418
|
if (access.kind === "byok") payload.proxyModel = void 0;
|
|
166419
|
+
if (runContext.oss && payload.proxyModel) payload.effort = 0;
|
|
166085
166420
|
const resolvedModel = payload.proxyModel ? void 0 : resolveModel({ slug: payload.model });
|
|
166086
166421
|
vertexCredentials = materializeVertexCredentials({ model: resolvedModel });
|
|
166087
166422
|
const agent2 = resolveAgent({ model: resolvedModel });
|
|
@@ -166162,7 +166497,7 @@ async function main() {
|
|
|
166162
166497
|
plan: runContext.plan,
|
|
166163
166498
|
resolvedModel
|
|
166164
166499
|
};
|
|
166165
|
-
const mcpHttpServer = __using(
|
|
166500
|
+
const mcpHttpServer = __using(_stack2, await startMcpHttpServer(toolContext, { outputSchema }), true);
|
|
166166
166501
|
toolContext.mcpServerUrl = mcpHttpServer.url;
|
|
166167
166502
|
log.info(`\xBB MCP server started at ${mcpHttpServer.url}`);
|
|
166168
166503
|
timer.checkpoint("mcpServer");
|
|
@@ -166345,7 +166680,7 @@ ${instructions.user}` : null,
|
|
|
166345
166680
|
const timeoutMs = usable ?? 36e5;
|
|
166346
166681
|
const actualTimeout = usable !== null ? payload.timeout : "1h";
|
|
166347
166682
|
let timeoutId;
|
|
166348
|
-
const timeoutPromise = new Promise((
|
|
166683
|
+
const timeoutPromise = new Promise((_4, reject) => {
|
|
166349
166684
|
timeoutId = setTimeout(() => {
|
|
166350
166685
|
reject(new Error(`agent run timed out after ${actualTimeout}`));
|
|
166351
166686
|
}, timeoutMs);
|
|
@@ -166372,11 +166707,11 @@ ${instructions.user}` : null,
|
|
|
166372
166707
|
toolContext,
|
|
166373
166708
|
silent: payload.event.silent ?? false
|
|
166374
166709
|
});
|
|
166375
|
-
} catch (
|
|
166376
|
-
var
|
|
166710
|
+
} catch (_2) {
|
|
166711
|
+
var _error2 = _2, _hasError2 = true;
|
|
166377
166712
|
} finally {
|
|
166378
|
-
var
|
|
166379
|
-
|
|
166713
|
+
var _promise3 = __callDispose(_stack2, _error2, _hasError2);
|
|
166714
|
+
_promise3 && await _promise3;
|
|
166380
166715
|
}
|
|
166381
166716
|
} catch (error49) {
|
|
166382
166717
|
const errorMessage = error49 instanceof Error ? error49.message : "unknown error occurred";
|
|
@@ -166420,11 +166755,11 @@ ${instructions.user}` : null,
|
|
|
166420
166755
|
}
|
|
166421
166756
|
cleanupVertexCredentials(vertexCredentials);
|
|
166422
166757
|
}
|
|
166423
|
-
} catch (
|
|
166424
|
-
var
|
|
166758
|
+
} catch (_3) {
|
|
166759
|
+
var _error3 = _3, _hasError3 = true;
|
|
166425
166760
|
} finally {
|
|
166426
|
-
var
|
|
166427
|
-
|
|
166761
|
+
var _promise4 = __callDispose(_stack3, _error3, _hasError3);
|
|
166762
|
+
_promise4 && await _promise4;
|
|
166428
166763
|
}
|
|
166429
166764
|
}
|
|
166430
166765
|
export {
|