pullfrog 0.1.47 → 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/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.47",
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
- function resolveEffort(_model) {
102685
- return "high";
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 = resolveEffort(model);
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
- log.info(`\xBB effort: ${effort}`);
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/opencode_v2.ts
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/opencode_v2.ts
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/opencode_v2.ts
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
- // gemini-3 thinking pinned to high for review depth; deepseek (funded
109078
- // efficient tier) pinned to high reasoning effort, and kimi pinned away
109079
- // from Enforcer-less openrouter providers (siliconflow / together) that
109080
- // drop optional tool-call params both per-model on the openrouter route,
109081
- // so other models are unaffected. gpt/anthropic effort set elsewhere (gpt:
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
- google: { models: geminiHighThinkingOverrides() },
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",
@@ -158094,6 +158228,7 @@ var Inputs = type({
158094
158228
  "prompt?": type.string.or("undefined"),
158095
158229
  "prompt_file?": type.string.or("undefined"),
158096
158230
  "model?": type.string.or("undefined"),
158231
+ "effort?": type.string.or("undefined"),
158097
158232
  "timeout?": type.string.or("undefined"),
158098
158233
  "push?": PushPermissionInput.or("undefined"),
158099
158234
  "shell?": ShellPermissionInput.or("undefined"),
@@ -158148,6 +158283,7 @@ function resolvePromptFile(input) {
158148
158283
  function resolveNonPromptInputs() {
158149
158284
  return Inputs.omit("prompt", "prompt_file").assert({
158150
158285
  model: core4.getInput("model") || void 0,
158286
+ effort: core4.getInput("effort") || void 0,
158151
158287
  timeout: core4.getInput("timeout") || void 0,
158152
158288
  cwd: core4.getInput("cwd") || void 0,
158153
158289
  push: core4.getInput("push") || void 0,
@@ -158166,6 +158302,8 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
158166
158302
  const rawEvent = jsonPayload?.event;
158167
158303
  const event = isPayloadEvent(rawEvent) ? rawEvent : { trigger: "unknown" };
158168
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));
158169
158307
  const isNonCollaborator = !isCollaborator(event);
158170
158308
  const repoShell = repoSettings.shell ?? "restricted";
158171
158309
  const inputShell = inputs.shell;
@@ -158185,6 +158323,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
158185
158323
  // explicit only when the model came from a per-run override flag (carried on
158186
158324
  // the JSON payload). a GHA `model` input or the repo default is not explicit.
158187
158325
  modelExplicit: jsonPayload?.modelExplicit ?? false,
158326
+ effort,
158188
158327
  prompt,
158189
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
158190
158329
  (!isPullfrog(process.env.GITHUB_ACTOR) ? process.env.GITHUB_ACTOR : void 0),
@@ -163650,6 +163789,140 @@ function formatApiKeyErrorSummary(params) {
163650
163789
  ].join("\n");
163651
163790
  }
163652
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
+
163653
163926
  // utils/gitAuthServer.ts
163654
163927
  import { randomUUID as randomUUID5 } from "node:crypto";
163655
163928
  import { writeFileSync as writeFileSync13 } from "node:fs";
@@ -164450,102 +164723,6 @@ function applyOverrides(params) {
164450
164723
  // utils/proxy.ts
164451
164724
  var core8 = __toESM(require_core(), 1);
164452
164725
 
164453
- // utils/billingErrors.ts
164454
- var BillingError = class extends Error {
164455
- code;
164456
- declineCode;
164457
- needsReauthentication;
164458
- constructor(message, opts = {}) {
164459
- super(message);
164460
- this.name = "BillingError";
164461
- this.code = opts.code ?? null;
164462
- this.declineCode = opts.declineCode ?? null;
164463
- this.needsReauthentication = opts.needsReauthentication ?? false;
164464
- }
164465
- };
164466
- var TransientError = class extends Error {
164467
- constructor(message) {
164468
- super(message);
164469
- this.name = "TransientError";
164470
- }
164471
- };
164472
- function billingConsoleUrl(owner, anchor) {
164473
- return `https://pullfrog.com/console/${encodeURIComponent(owner)}#${anchor}`;
164474
- }
164475
- function formatBillingErrorSummary(error49, owner) {
164476
- if (error49.code === "router_requires_card") {
164477
- return [
164478
- "**Add a card to start using Pullfrog Router.**",
164479
- "",
164480
- "Router proxies OpenRouter at raw cost \u2014 no platform markup. Add a card and we'll auto-reload your wallet so runs keep flowing.",
164481
- "",
164482
- `[Add a card \u2192](${billingConsoleUrl(owner, "model-access")})`
164483
- ].join("\n");
164484
- }
164485
- if (error49.code === "router_balance_exhausted") {
164486
- return [
164487
- "**Your Pullfrog Router balance is exhausted.**",
164488
- "",
164489
- "You have a payment method on file but auto-reload is disabled, so runs paused once your balance went past the overdraft buffer.",
164490
- "",
164491
- `[Top up balance \u2192](${billingConsoleUrl(owner, "billing")}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner, "model-access")})`
164492
- ].join("\n");
164493
- }
164494
- if (error49.code === "router_keylimit_exhausted") {
164495
- return [
164496
- "**This run was cut short \u2014 your Pullfrog Router balance ran out mid-run.**",
164497
- "",
164498
- "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.",
164499
- "",
164500
- `[Top up balance \u2192](${billingConsoleUrl(owner, "billing")}) \xB7 [Enable auto-reload \u2192](${billingConsoleUrl(owner, "model-access")})`
164501
- ].join("\n");
164502
- }
164503
- if (error49.code === "router_monthly_limit") {
164504
- return [
164505
- "**Pullfrog Router hit its monthly spend limit.**",
164506
- "",
164507
- "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.",
164508
- "",
164509
- `[Adjust limit \u2192](${billingConsoleUrl(owner, "model-access")})`
164510
- ].join("\n");
164511
- }
164512
- if (error49.needsReauthentication) {
164513
- const code = error49.declineCode ?? "authentication_required";
164514
- return [
164515
- `**Your card issuer requires 3D Secure on every charge** (\`${code}\`).`,
164516
- "",
164517
- "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.",
164518
- "",
164519
- `[Top up balance \u2192](${billingConsoleUrl(owner, "billing")})`
164520
- ].join("\n");
164521
- }
164522
- if (error49.declineCode) {
164523
- return [
164524
- `**Your card was declined** (\`${error49.declineCode}\`).`,
164525
- "",
164526
- "Update your payment method and Pullfrog will retry on the next run.",
164527
- "",
164528
- `[Update payment method \u2192](${billingConsoleUrl(owner, "billing")})`
164529
- ].join("\n");
164530
- }
164531
- return [
164532
- "**Your Pullfrog balance is empty.**",
164533
- "",
164534
- "Top up your balance or enable auto-reload to keep runs flowing.",
164535
- "",
164536
- `[Manage billing \u2192](${billingConsoleUrl(owner, "billing")})`
164537
- ].join("\n");
164538
- }
164539
- function formatTransientErrorSummary(error49, owner) {
164540
- return [
164541
- "**Pullfrog billing is temporarily unavailable.**",
164542
- "",
164543
- error49.message,
164544
- "",
164545
- `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")}).`
164546
- ].join("\n");
164547
- }
164548
-
164549
164726
  // utils/token.ts
164550
164727
  var core7 = __toESM(require_core(), 1);
164551
164728
  import assert2 from "node:assert/strict";
@@ -165079,6 +165256,7 @@ var core9 = __toESM(require_core(), 1);
165079
165256
  // utils/runContext.ts
165080
165257
  var defaultSettings = {
165081
165258
  model: null,
165259
+ effort: null,
165082
165260
  modes: [],
165083
165261
  setupScript: null,
165084
165262
  postCheckoutScript: null,
@@ -165126,6 +165304,11 @@ async function fetchRunContext(params) {
165126
165304
  signal: controller.signal
165127
165305
  });
165128
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
+ }
165129
165312
  if (!response.ok) {
165130
165313
  return response.status >= 500 ? unknownSecretsRunContext : defaultRunContext;
165131
165314
  }
@@ -165204,6 +165387,7 @@ async function resolveRunContextData(params) {
165204
165387
  plan: runContext.plan,
165205
165388
  proxyModel: runContext.proxyModel,
165206
165389
  dbSecrets: runContext.dbSecrets,
165390
+ commercialRefused: runContext.commercialRefused,
165207
165391
  // a failed mint on a runner that should have been able to mint is the same
165208
165392
  // outcome as the server-side failure: the run never sees stored secrets.
165209
165393
  secretsUnavailable: runContext.secretsUnavailable || !!process.env.ACTIONS_ID_TOKEN_REQUEST_URL && oidcToken === void 0
@@ -165587,6 +165771,7 @@ async function dispatchFollowUpReReview(ctx, reviewedSha) {
165587
165771
  "~pullfrog": true,
165588
165772
  version: ctx.payload.version,
165589
165773
  model: ctx.payload.model,
165774
+ effort: ctx.payload.effort,
165590
165775
  prompt: "",
165591
165776
  eventInstructions: RE_REVIEW_PREAMBLE,
165592
165777
  event
@@ -165839,7 +166024,8 @@ async function writeRunErrorOutputs(input) {
165839
166024
  error: input.rendered.comment,
165840
166025
  createIfMissing: true
165841
166026
  });
165842
- } catch {
166027
+ } catch (error49) {
166028
+ log.warning(`error comment failed: ${error49 instanceof Error ? error49.message : String(error49)}`);
165843
166029
  }
165844
166030
  }
165845
166031
 
@@ -165879,6 +166065,13 @@ function resolveModelForLog(ctx) {
165879
166065
  if (ctx.payload.model) return `${ctx.payload.model} (unresolved)`;
165880
166066
  return "auto";
165881
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
+ }
165882
166075
  function resolveAgentForLog(ctx) {
165883
166076
  const envAgent = process.env.PULLFROG_AGENT?.trim();
165884
166077
  if (envAgent && envAgent === ctx.agentName) {
@@ -165893,6 +166086,9 @@ function logRunStartup(ctx) {
165893
166086
  log.info(
165894
166087
  `\xBB model: ${resolveModelForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`
165895
166088
  );
166089
+ log.info(
166090
+ `\xBB effort: ${resolveEffortForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`
166091
+ );
165896
166092
  log.info(
165897
166093
  `\xBB agent: ${resolveAgentForLog({ agentName: ctx.agentName, resolvedModel: ctx.resolvedModel })}`
165898
166094
  );
@@ -166058,7 +166254,7 @@ async function resolveRun(params) {
166058
166254
 
166059
166255
  // main.ts
166060
166256
  async function main() {
166061
- var _stack2 = [];
166257
+ var _stack3 = [];
166062
166258
  try {
166063
166259
  normalizeEnv();
166064
166260
  const overridesRaw = process.env.UNSAFE_OVERRIDES ?? "";
@@ -166086,12 +166282,48 @@ async function main() {
166086
166282
  const initialOctokit = createOctokit(jobToken);
166087
166283
  const runContext = await resolveRunContextData({ octokit: initialOctokit, token: jobToken });
166088
166284
  timer.checkpoint("runContextData");
166285
+ const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
166089
166286
  const toolState = initToolState({
166090
166287
  progressComment: typeof resolvedPromptInput !== "string" ? resolvedPromptInput.progressComment : void 0,
166091
166288
  owner: runContext.repo.owner,
166092
166289
  name: runContext.repo.name,
166093
166290
  dir: process.cwd()
166094
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
+ }
166095
166327
  createTempDirectory();
166096
166328
  const opencodeCliPath = await agents.opencode.install();
166097
166329
  captureBaselineModels(opencodeCliPath);
@@ -166110,27 +166342,13 @@ async function main() {
166110
166342
  if (runContext.repoSettings.envAllowlist) {
166111
166343
  setEnvAllowlist(runContext.repoSettings.envAllowlist);
166112
166344
  }
166113
- const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
166114
- toolState.model = payload.model;
166115
- toolState.oss = runContext.oss;
166116
- toolState.shaPinned = isActionPinnedToSha();
166117
- if (payload.event.issue_number !== void 0) {
166118
- primaryRepoState(toolState).issueNumber = payload.event.issue_number;
166119
- }
166120
- if (payload.event.trigger === "pull_request_synchronize") {
166121
- primaryRepoState(toolState).beforeSha = payload.event.before_sha;
166122
- }
166123
- const oidcCredentials = process.env.ACTIONS_ID_TOKEN_REQUEST_URL && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN ? {
166124
- requestUrl: process.env.ACTIONS_ID_TOKEN_REQUEST_URL,
166125
- requestToken: process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN
166126
- } : null;
166127
166345
  const xrepoUnavailable = payload.xrepo?.unavailable ?? [];
166128
166346
  if (xrepoUnavailable.length > 0) {
166129
166347
  log.warning(
166130
166348
  `\xBB --xrepo: requested but not granted: ${xrepoUnavailable.join(", ")} (unknown repo, different owner, or you lack access)`
166131
166349
  );
166132
166350
  }
166133
- const tokenRef = __using(_stack2, await resolveTokens({
166351
+ const tokenRef = __using(_stack3, await resolveTokens({
166134
166352
  push: payload.push,
166135
166353
  xrepo: payload.xrepo,
166136
166354
  oidc: oidcCredentials
@@ -166155,7 +166373,7 @@ async function main() {
166155
166373
  let todoTracker;
166156
166374
  let vertexCredentials;
166157
166375
  try {
166158
- var _stack = [];
166376
+ var _stack2 = [];
166159
166377
  try {
166160
166378
  if (payload.cwd && process.cwd() !== payload.cwd) {
166161
166379
  process.chdir(payload.cwd);
@@ -166175,7 +166393,7 @@ async function main() {
166175
166393
  payload.prompt = payload.prompt.replace(originalBody, resolvedBody ?? "");
166176
166394
  }
166177
166395
  }
166178
- const gitAuthServer = __using(_stack, await startGitAuthServer(tmpdir3), true);
166396
+ const gitAuthServer = __using(_stack2, await startGitAuthServer(tmpdir3), true);
166179
166397
  setGitAuthServer(gitAuthServer);
166180
166398
  const access = decideModelAccess({
166181
166399
  modelExplicit: payload.modelExplicit ?? false,
@@ -166198,6 +166416,7 @@ async function main() {
166198
166416
  }
166199
166417
  if (access.kind === "proxy") payload.proxyModel = access.target;
166200
166418
  if (access.kind === "byok") payload.proxyModel = void 0;
166419
+ if (runContext.oss && payload.proxyModel) payload.effort = 0;
166201
166420
  const resolvedModel = payload.proxyModel ? void 0 : resolveModel({ slug: payload.model });
166202
166421
  vertexCredentials = materializeVertexCredentials({ model: resolvedModel });
166203
166422
  const agent2 = resolveAgent({ model: resolvedModel });
@@ -166278,7 +166497,7 @@ async function main() {
166278
166497
  plan: runContext.plan,
166279
166498
  resolvedModel
166280
166499
  };
166281
- const mcpHttpServer = __using(_stack, await startMcpHttpServer(toolContext, { outputSchema }), true);
166500
+ const mcpHttpServer = __using(_stack2, await startMcpHttpServer(toolContext, { outputSchema }), true);
166282
166501
  toolContext.mcpServerUrl = mcpHttpServer.url;
166283
166502
  log.info(`\xBB MCP server started at ${mcpHttpServer.url}`);
166284
166503
  timer.checkpoint("mcpServer");
@@ -166461,7 +166680,7 @@ ${instructions.user}` : null,
166461
166680
  const timeoutMs = usable ?? 36e5;
166462
166681
  const actualTimeout = usable !== null ? payload.timeout : "1h";
166463
166682
  let timeoutId;
166464
- const timeoutPromise = new Promise((_3, reject) => {
166683
+ const timeoutPromise = new Promise((_4, reject) => {
166465
166684
  timeoutId = setTimeout(() => {
166466
166685
  reject(new Error(`agent run timed out after ${actualTimeout}`));
166467
166686
  }, timeoutMs);
@@ -166488,11 +166707,11 @@ ${instructions.user}` : null,
166488
166707
  toolContext,
166489
166708
  silent: payload.event.silent ?? false
166490
166709
  });
166491
- } catch (_) {
166492
- var _error = _, _hasError = true;
166710
+ } catch (_2) {
166711
+ var _error2 = _2, _hasError2 = true;
166493
166712
  } finally {
166494
- var _promise2 = __callDispose(_stack, _error, _hasError);
166495
- _promise2 && await _promise2;
166713
+ var _promise3 = __callDispose(_stack2, _error2, _hasError2);
166714
+ _promise3 && await _promise3;
166496
166715
  }
166497
166716
  } catch (error49) {
166498
166717
  const errorMessage = error49 instanceof Error ? error49.message : "unknown error occurred";
@@ -166536,11 +166755,11 @@ ${instructions.user}` : null,
166536
166755
  }
166537
166756
  cleanupVertexCredentials(vertexCredentials);
166538
166757
  }
166539
- } catch (_2) {
166540
- var _error2 = _2, _hasError2 = true;
166758
+ } catch (_3) {
166759
+ var _error3 = _3, _hasError3 = true;
166541
166760
  } finally {
166542
- var _promise3 = __callDispose(_stack2, _error2, _hasError2);
166543
- _promise3 && await _promise3;
166761
+ var _promise4 = __callDispose(_stack3, _error3, _hasError3);
166762
+ _promise4 && await _promise4;
166544
166763
  }
166545
166764
  }
166546
166765
  export {