pullfrog 0.1.67 → 0.1.68

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
@@ -107718,6 +107718,7 @@ import { performance as performance5 } from "node:perf_hooks";
107718
107718
 
107719
107719
  // effort.ts
107720
107720
  var DEFAULT_EFFORT_POSITION = 0.5;
107721
+ var SUBSIDY_RUNG = "high";
107721
107722
  var EFFORT_ALIASES = {
107722
107723
  low: 0,
107723
107724
  medium: 0.25,
@@ -108121,6 +108122,15 @@ var providers = {
108121
108122
  // the model does cost nothing.
108122
108123
  isFree: true
108123
108124
  },
108125
+ // Zen meters Fable like any other model, so this route reaches it without
108126
+ // the Anthropic access grant `anthropic/claude-fable` still needs.
108127
+ "claude-fable": {
108128
+ displayName: "Claude Fable",
108129
+ resolve: "opencode/claude-fable-5-1",
108130
+ effort: ["low", "medium", "high", "xhigh", "max"],
108131
+ openRouterResolve: "openrouter/~anthropic/claude-fable-latest",
108132
+ subagentModel: "claude-sonnet"
108133
+ },
108124
108134
  "claude-opus": {
108125
108135
  displayName: "Claude Opus",
108126
108136
  resolve: "opencode/claude-opus-5",
@@ -108234,6 +108244,17 @@ var providers = {
108234
108244
  effort: ["minimal", "low", "medium", "high"],
108235
108245
  openRouterResolve: "openrouter/google/gemini-3.6-flash"
108236
108246
  },
108247
+ // Zen serves K3, but rule 7 can only move a mirror when its upstream moves,
108248
+ // so the K3 generation could never reach this block by bumping `kimi-k2`.
108249
+ "kimi-k3": {
108250
+ displayName: "Kimi K3",
108251
+ resolve: "opencode/kimi-k3",
108252
+ // Zen publishes a single rung for K3 where OpenRouter publishes three.
108253
+ effort: ["max"],
108254
+ openRouterEffort: ["low", "high", "max"],
108255
+ openRouterResolve: "openrouter/moonshotai/kimi-k3",
108256
+ subagentModel: "kimi-k2"
108257
+ },
108237
108258
  "kimi-k2": {
108238
108259
  displayName: "Kimi K2",
108239
108260
  // k2.7-code is UNDEPLOYED on Zen — still listed in /zen/v1/models, but
@@ -108245,25 +108266,58 @@ var providers = {
108245
108266
  resolve: "opencode/kimi-k2.6",
108246
108267
  openRouterResolve: "openrouter/moonshotai/kimi-k2.7-code"
108247
108268
  },
108269
+ // M3 is its own line beside M2, not a bump of it — same reason `kimi-k3`
108270
+ // sits beside `kimi-k2` rather than replacing it.
108271
+ "minimax-m3": {
108272
+ displayName: "MiniMax M3",
108273
+ resolve: "opencode/minimax-m3",
108274
+ openRouterResolve: "openrouter/minimax/minimax-m3"
108275
+ },
108248
108276
  // slug pins the m2 line for DB stability; resolve tracks the current m2.7.
108249
108277
  "minimax-m2.5": {
108250
108278
  displayName: "MiniMax M2",
108251
108279
  resolve: "opencode/minimax-m2.7",
108252
108280
  openRouterResolve: "openrouter/minimax/minimax-m2.7"
108253
108281
  },
108282
+ // Z.ai and xAI reach Zen subscribers only here — before this, `opencode-go`
108283
+ // was the catalog's only GLM route, and Grok had no Zen route at all.
108284
+ glm: {
108285
+ displayName: "GLM",
108286
+ resolve: "opencode/glm-5.2",
108287
+ effort: ["high", "max"],
108288
+ openRouterEffort: ["high", "xhigh"],
108289
+ openRouterResolve: "openrouter/z-ai/glm-5.2"
108290
+ },
108291
+ grok: {
108292
+ displayName: "Grok",
108293
+ resolve: "opencode/grok-4.6",
108294
+ effort: ["low", "medium", "high", "xhigh"],
108295
+ openRouterResolve: "openrouter/x-ai/grok-4.6"
108296
+ },
108254
108297
  "gpt-5-nano": {
108255
108298
  displayName: "GPT Nano",
108256
108299
  resolve: "opencode/gpt-5-nano",
108257
108300
  effort: ["minimal", "low", "medium", "high"],
108258
108301
  openRouterResolve: "openrouter/openai/gpt-5-nano"
108259
108302
  },
108303
+ // Zen's live free MiMo, and the second free row in a menu that big-pickle
108304
+ // was alone in since `mimo-v2-pro-free` lost its model.
108305
+ mimo: {
108306
+ displayName: "MiMo",
108307
+ resolve: "opencode/mimo-v2.5-free",
108308
+ // free to run, still gated on the provider's own OPENCODE_API_KEY —
108309
+ // see the big-pickle note above (#1077).
108310
+ isFree: true
108311
+ },
108260
108312
  "mimo-v2-pro-free": {
108261
108313
  displayName: "MiMo V2 Pro",
108262
108314
  resolve: "opencode/mimo-v2-pro-free",
108263
108315
  // free to run, still gated on the provider's own OPENCODE_API_KEY —
108264
108316
  // see the big-pickle note above (#1077).
108265
108317
  isFree: true,
108266
- fallback: "opencode/big-pickle"
108318
+ // the model id Zen dropped; land a stored MiMo pick back on MiMo rather
108319
+ // than on the unrelated model it had to settle for while none was live.
108320
+ fallback: "opencode/mimo"
108267
108321
  },
108268
108322
  "minimax-m2.5-free": {
108269
108323
  displayName: "MiniMax M2",
@@ -108358,6 +108412,16 @@ var providers = {
108358
108412
  resolve: "opencode-go/qwen3.7-plus",
108359
108413
  openRouterResolve: "openrouter/qwen/qwen3.7-plus"
108360
108414
  },
108415
+ // the cheap rung Alibaba added under Plus (0.15/0.47 against 0.5/3), and
108416
+ // the only model either OpenCode plan has added since this block was written.
108417
+ "qwen-flash": {
108418
+ displayName: "Qwen Flash",
108419
+ resolve: "opencode-go/qwen3.8-flash",
108420
+ effort: ["low", "medium", "xhigh"],
108421
+ // the Go route publishes rungs where OpenRouter publishes none.
108422
+ openRouterEffort: [],
108423
+ openRouterResolve: "openrouter/qwen/qwen3.8-flash"
108424
+ },
108361
108425
  // MiniMax — parity with opencode/* and openrouter/*; the m2 slug pins the
108362
108426
  // line for DB stability while the resolve tracks the current m2.7.
108363
108427
  "minimax-m3": {
@@ -109482,6 +109546,7 @@ async function installFromNpmTarball(params) {
109482
109546
  // utils/providerErrors.ts
109483
109547
  var PROVIDER_BILLING_EXHAUSTED_LABEL = "provider billing exhausted";
109484
109548
  var PROVIDER_NO_ENDPOINTS_LABEL = "provider no routable endpoints";
109549
+ var PROVIDER_USAGE_LIMIT_LABEL = "provider usage limit reached";
109485
109550
  var statusKey = `\\b(?:status[_ ]?code|http[_ ]?status|status)["']?\\s*[:=]\\s*["']?`;
109486
109551
  var ANTHROPIC_SPEND_CAP_PATTERN = /reached your specified API usage limits\.?(?:\s*You will regain access on ([^"\n]+?)\.)?/i;
109487
109552
  function findAnthropicSpendCap(text) {
@@ -109527,6 +109592,14 @@ var PROVIDER_ERROR_PATTERNS = [
109527
109592
  // the wallet-shaped patterns above reach, and its 400 sits nowhere near a
109528
109593
  // `status:` key either — so the whole message was dropped on the floor (#1208).
109529
109594
  { regex: ANTHROPIC_SPEND_CAP_PATTERN, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
109595
+ // OpenCode Zen / Codex-subscription cap: `AI_APICallError: The usage limit has
109596
+ // been reached`. Its noun is "usage limit" with no "rate", no status code and
109597
+ // no wallet wording, so every pattern here missed it and `lastProviderError`
109598
+ // stayed unset — which suppresses nothing, so the run was reported as "The
109599
+ // model produced no output at all … usually transient; re-running often
109600
+ // succeeds" while the same log held nine of these. Measured on a live account
109601
+ // whose ChatGPT subscription was capped.
109602
+ { regex: /\bthe usage limit has been reached\b/i, label: PROVIDER_USAGE_LIMIT_LABEL },
109530
109603
  // the OpenRouter shapes `isRouterKeylimitExhaustedError` matches. on a Router
109531
109604
  // run those mean the PULLFROG wallet is empty and `renderRunError` returns a
109532
109605
  // `BillingError` before ever reaching this list; on a BYOK run the very same
@@ -109657,7 +109730,7 @@ function ossEffortFloor(ctx) {
109657
109730
  const alias = resolveRunAlias(ctx);
109658
109731
  const published = alias?.openRouterEffort ?? alias?.effort;
109659
109732
  if (!published) return 0;
109660
- return rungPosition({ rung: "high", published }) ?? 0;
109733
+ return rungPosition({ rung: SUBSIDY_RUNG, published }) ?? 0;
109661
109734
  }
109662
109735
  function resolveRunEffort(ctx) {
109663
109736
  const configured = ctx.payload.effort !== void 0;
@@ -109689,7 +109762,7 @@ var import_semver = __toESM(require_semver2(), 1);
109689
109762
  // package.json
109690
109763
  var package_default = {
109691
109764
  name: "pullfrog",
109692
- version: "0.1.67",
109765
+ version: "0.1.68",
109693
109766
  type: "module",
109694
109767
  bin: {
109695
109768
  pullfrog: "dist/cli.mjs",
@@ -192373,6 +192446,9 @@ function formatModelLabel(params) {
192373
192446
  if (params.fallbackFrom) {
192374
192447
  return `${base} (credentials for ${providerDisplayName(params.fallbackFrom)} were rejected by the provider)`;
192375
192448
  }
192449
+ if (params.clamped?.reason === "trial") {
192450
+ return `${base} (free trial)`;
192451
+ }
192376
192452
  if (params.clamped) {
192377
192453
  const target = isAutoTier(params.clamped.from) ? "the intelligent tier" : `\`${resolveDisplayAlias(params.clamped.from)?.displayName ?? params.clamped.from}\``;
192378
192454
  return params.clamped.reason === "card" ? `${base} (${target} needs a [card on file](https://docs.pullfrog.com/models))` : `${base} (${target} needs a [provider key](https://docs.pullfrog.com/models) \u2014 no Router support yet)`;
@@ -192382,6 +192458,15 @@ function formatModelLabel(params) {
192382
192458
  }
192383
192459
  return base;
192384
192460
  }
192461
+ function buildTrialDisclosure(owner) {
192462
+ const consoleUrl = owner ? `https://pullfrog.com/console/${owner}` : "https://pullfrog.com/console";
192463
+ return [
192464
+ "---",
192465
+ "",
192466
+ "> [!IMPORTANT]",
192467
+ `> **This run used the free trial model.** \`DeepSeek Flash\` is fast and cheap \u2014 expect lighter work than a frontier model. [Connect a subscription or API key \u2192](${consoleUrl})`
192468
+ ].join("\n");
192469
+ }
192385
192470
  function buildPullfrogFooter(params) {
192386
192471
  const parts = [];
192387
192472
  if (params.shaPinned) {
@@ -192414,10 +192499,13 @@ function buildPullfrogFooter(params) {
192414
192499
  );
192415
192500
  }
192416
192501
  const allParts = [...parts, "[\u{1D54F}](https://x.com/pullfrogai)"];
192502
+ const disclosure = params.clamped?.reason === "trial" ? `${buildTrialDisclosure(params.owner)}
192503
+
192504
+ ` : "";
192417
192505
  return `
192418
192506
 
192419
192507
  ${PULLFROG_DIVIDER}
192420
- <sup>${FROG_LOGO}&nbsp;&nbsp;\uFF5C ${allParts.join(" \uFF5C ")}</sup>`;
192508
+ ${disclosure}<sup>${FROG_LOGO}&nbsp;&nbsp;\uFF5C ${allParts.join(" \uFF5C ")}</sup>`;
192421
192509
  }
192422
192510
  function stripExistingFooter(body) {
192423
192511
  const dividerIndex = body.indexOf(PULLFROG_DIVIDER);
@@ -192571,7 +192659,8 @@ function buildCommentFooter(ctx, customParts) {
192571
192659
  clamped: ctx.toolState.modelClamped,
192572
192660
  unselectedProxyDefault: ctx.toolState.unselectedProxyDefault,
192573
192661
  shaPinned: ctx.toolState.shaPinned,
192574
- oss: ctx.oss
192662
+ oss: ctx.oss,
192663
+ owner: ctx.repo.owner
192575
192664
  });
192576
192665
  }
192577
192666
  function buildImplementPlanLink(ctx, issueNumber, commentId) {
@@ -193570,7 +193659,8 @@ async function createAndSubmitWithFooter(ctx, params, opts) {
193570
193659
  clamped: ctx.toolState.modelClamped,
193571
193660
  unselectedProxyDefault: ctx.toolState.unselectedProxyDefault,
193572
193661
  shaPinned: ctx.toolState.shaPinned,
193573
- oss: ctx.oss
193662
+ oss: ctx.oss,
193663
+ owner: ctx.repo.owner
193574
193664
  });
193575
193665
  return await ctx.octokit.rest.pulls.submitReview({
193576
193666
  owner: params.owner,
@@ -196331,7 +196421,8 @@ function buildPrBodyWithFooter(ctx, body) {
196331
196421
  clamped: ctx.toolState.modelClamped,
196332
196422
  unselectedProxyDefault: ctx.toolState.unselectedProxyDefault,
196333
196423
  shaPinned: ctx.toolState.shaPinned,
196334
- oss: ctx.oss
196424
+ oss: ctx.oss,
196425
+ owner: ctx.repo.owner
196335
196426
  });
196336
196427
  const bodyWithoutFooter = stripExistingFooter(fixDoubleEscapedString(body));
196337
196428
  return `${bodyWithoutFooter}${footer}`;
@@ -197638,10 +197729,12 @@ function isByokSetupError(text) {
197638
197729
  var SECRETS_UNAVAILABLE_MARKER = "couldn't load your Pullfrog secrets";
197639
197730
  var ROUTER_UNFUNDED_MARKER = "your Pullfrog Router balance is empty";
197640
197731
  var CREDENTIAL_REJECTED_MARKER = "was rejected by its provider";
197641
- function buildKeyError(params) {
197642
- if (params.secretsUnavailable) return buildSecretsUnavailableError(params);
197643
- if (params.routerUnfunded) return buildRouterUnfundedError(params);
197644
- return buildMissingApiKeyError(params);
197732
+ var NoUsableCredentialError = class extends Error {
197733
+ };
197734
+ function throwKeyError(params) {
197735
+ if (params.secretsUnavailable) throw new Error(buildSecretsUnavailableError(params));
197736
+ if (params.routerUnfunded) throw new NoUsableCredentialError(buildRouterUnfundedError(params));
197737
+ throw new NoUsableCredentialError(buildMissingApiKeyError(params));
197645
197738
  }
197646
197739
  function buildRouterUnfundedError(params) {
197647
197740
  const billingUrl = `${getApiUrl()}/console/${params.owner}#billing`;
@@ -197840,57 +197933,51 @@ function validateAgentApiKey(params) {
197840
197933
  validateVertexSetup({ owner: params.owner, name: params.name });
197841
197934
  return;
197842
197935
  }
197843
- validateBedrockSetup({ owner: params.owner, name: params.name });
197844
- return;
197936
+ if (process.env[BEDROCK_MODEL_ID_ENV]?.trim() === params.model) {
197937
+ validateBedrockSetup({ owner: params.owner, name: params.name });
197938
+ return;
197939
+ }
197845
197940
  }
197846
197941
  if (params.agent.name === "opencode") {
197847
197942
  if (params.authorized.has(params.model)) return;
197848
197943
  const reason = getModelsFailure();
197849
197944
  if (reason) throw new Error(reason);
197850
197945
  if (getModelEnvVars(params.model).some(hasEnvVar2)) return;
197851
- throw new Error(
197852
- buildKeyError({
197853
- owner: params.owner,
197854
- name: params.name,
197855
- model: params.model,
197856
- secretsUnavailable: params.secretsUnavailable,
197857
- routerUnfunded: params.routerUnfunded
197858
- })
197859
- );
197860
- }
197861
- if (hasSingleProviderAuth(params.agent.name)) return;
197862
- throw new Error(
197863
- buildKeyError({
197946
+ throwKeyError({
197864
197947
  owner: params.owner,
197865
197948
  name: params.name,
197866
197949
  model: params.model,
197867
197950
  secretsUnavailable: params.secretsUnavailable,
197868
197951
  routerUnfunded: params.routerUnfunded
197869
- })
197870
- );
197952
+ });
197953
+ }
197954
+ if (hasSingleProviderAuth(params.agent.name)) return;
197955
+ throwKeyError({
197956
+ owner: params.owner,
197957
+ name: params.name,
197958
+ model: params.model,
197959
+ secretsUnavailable: params.secretsUnavailable,
197960
+ routerUnfunded: params.routerUnfunded
197961
+ });
197871
197962
  }
197872
197963
  if (params.agent.name === "opencode") {
197873
197964
  if ([...params.authorized].some(modelHasRuntimeAuth)) return;
197874
197965
  const reason = getModelsFailure();
197875
197966
  if (reason) throw new Error(reason);
197876
- throw new Error(
197877
- buildKeyError({
197878
- owner: params.owner,
197879
- name: params.name,
197880
- secretsUnavailable: params.secretsUnavailable,
197881
- routerUnfunded: params.routerUnfunded
197882
- })
197883
- );
197884
- }
197885
- if (hasSingleProviderAuth(params.agent.name)) return;
197886
- throw new Error(
197887
- buildKeyError({
197967
+ throwKeyError({
197888
197968
  owner: params.owner,
197889
197969
  name: params.name,
197890
197970
  secretsUnavailable: params.secretsUnavailable,
197891
197971
  routerUnfunded: params.routerUnfunded
197892
- })
197893
- );
197972
+ });
197973
+ }
197974
+ if (hasSingleProviderAuth(params.agent.name)) return;
197975
+ throwKeyError({
197976
+ owner: params.owner,
197977
+ name: params.name,
197978
+ secretsUnavailable: params.secretsUnavailable,
197979
+ routerUnfunded: params.routerUnfunded
197980
+ });
197894
197981
  }
197895
197982
  function isApiKeyAuthError(text) {
197896
197983
  if (!text) return false;
@@ -198015,9 +198102,9 @@ function formatApiKeyErrorSummary(params) {
198015
198102
  ].join("\n");
198016
198103
  }
198017
198104
  return [
198018
- `**Your LLM provider API key was rejected.** Rotate the key in your provider dashboard, then update the matching GitHub Actions secret.`,
198105
+ `**Your LLM provider API key was rejected.** Rotate the key in your provider dashboard, then update the copy Pullfrog uses \u2014 wherever you saved it.`,
198019
198106
  "",
198020
- `[Update repo secret \u2192](${githubSecretsUrl}) \xB7 [Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/keys) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`
198107
+ `[Pullfrog secrets \u2192](${getApiUrl()}/console/${params.owner}) \xB7 [Repo secrets \u2192](${githubSecretsUrl}) \xB7 [Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/keys) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`
198021
198108
  ].join("\n");
198022
198109
  }
198023
198110
 
@@ -199243,6 +199330,9 @@ var DebugInput = type.enumerated("disabled", "enabled");
199243
199330
  var JsonPayload = type({
199244
199331
  "~pullfrog": "true",
199245
199332
  version: "string",
199333
+ // the server's run type, forwarded verbatim to run-context. optional so a
199334
+ // payload from an older server build still parses against a newer action.
199335
+ "type?": "string | undefined",
199246
199336
  "model?": "string | undefined",
199247
199337
  "modelExplicit?": "boolean | undefined",
199248
199338
  "effort?": "number | string | undefined",
@@ -199728,7 +199818,8 @@ ${ctx.error}` : ctx.error;
199728
199818
  clamped: ctx.toolState.modelClamped,
199729
199819
  unselectedProxyDefault: ctx.toolState.unselectedProxyDefault,
199730
199820
  shaPinned: ctx.toolState.shaPinned,
199731
- oss: ctx.toolState.oss
199821
+ oss: ctx.toolState.oss,
199822
+ owner: repoContext.owner
199732
199823
  });
199733
199824
  const body = `${formattedError}${footer}`;
199734
199825
  const comment = ctx.toolState.progressComment;
@@ -199811,7 +199902,7 @@ async function mintProxyKey(ctx) {
199811
199902
  }
199812
199903
  }
199813
199904
  async function buildProxyTokenHeaders(ctx) {
199814
- const fundingSource = ctx.oss ? "oss" : "router";
199905
+ const fundingSource = ctx.fundingSource;
199815
199906
  if (ctx.oidcCredentials) {
199816
199907
  const creds = ctx.oidcCredentials;
199817
199908
  const oidcToken = await op(() => fetchIdTokenFromStash(creds), {
@@ -199843,7 +199934,7 @@ async function resolveProxyModel(ctx) {
199843
199934
  const key = await mintProxyKey({
199844
199935
  oidcCredentials: ctx.oidcCredentials,
199845
199936
  repo: ctx.repo,
199846
- oss: ctx.oss
199937
+ fundingSource: ctx.oss ? "oss" : "router"
199847
199938
  });
199848
199939
  if (!key) return;
199849
199940
  process.env.OPENROUTER_API_KEY = key;
@@ -199915,6 +200006,26 @@ async function runProxyResolution(ctx) {
199915
200006
  throw error62;
199916
200007
  }
199917
200008
  }
200009
+ async function resolveTrialFallback(ctx) {
200010
+ if (process.env.PULLFROG_MODEL?.trim()) return false;
200011
+ if (!ctx.oidcCredentials && !isLocalApiUrl()) return false;
200012
+ const key = await mintProxyKey({
200013
+ oidcCredentials: ctx.oidcCredentials,
200014
+ repo: ctx.repo,
200015
+ fundingSource: "trial"
200016
+ });
200017
+ if (!key) return false;
200018
+ process.env.OPENROUTER_API_KEY = key;
200019
+ core9.setSecret(key);
200020
+ ctx.payload.proxyModel = DEFAULT_PROXY_MODEL;
200021
+ ctx.toolState.model = DEFAULT_PROXY_MODEL;
200022
+ ctx.toolState.modelClamped = {
200023
+ from: ctx.configuredModel ?? DEFAULT_PROXY_MODEL,
200024
+ reason: "trial"
200025
+ };
200026
+ log.info(`\xBB proxy: trial \u2192 ${DEFAULT_PROXY_MODEL}`);
200027
+ return true;
200028
+ }
199918
200029
 
199919
200030
  // utils/prSummary.ts
199920
200031
  import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises";
@@ -200092,8 +200203,9 @@ async function fetchRunContext(params) {
200092
200203
  if (params.oidcToken) {
200093
200204
  headers["X-GitHub-OIDC-Token"] = params.oidcToken;
200094
200205
  }
200206
+ const query = params.runType ? `?type=${encodeURIComponent(params.runType)}` : "";
200095
200207
  const response = await apiFetch({
200096
- path: `/api/repo/${params.repoContext.owner}/${params.repoContext.name}/run-context`,
200208
+ path: `/api/repo/${params.repoContext.owner}/${params.repoContext.name}/run-context${query}`,
200097
200209
  headers,
200098
200210
  signal: controller.signal
200099
200211
  });
@@ -200130,7 +200242,8 @@ async function fetchRunContext(params) {
200130
200242
  proxyModel: data.proxyModel,
200131
200243
  dbSecrets: data.dbSecrets,
200132
200244
  secretsUnavailable: data.secretsUnavailable,
200133
- routerUnfunded: data.routerUnfunded
200245
+ routerUnfunded: data.routerUnfunded,
200246
+ trialFallback: data.trialFallback
200134
200247
  };
200135
200248
  } catch {
200136
200249
  clearTimeout(timeoutId);
@@ -200171,7 +200284,7 @@ async function resolveRunContextData(params) {
200171
200284
  retries: [100, 500],
200172
200285
  bail: (error62) => !isTransientOctokitError(error62)
200173
200286
  })(),
200174
- fetchRunContext({ token: params.token, repoContext, oidcToken })
200287
+ fetchRunContext({ token: params.token, repoContext, oidcToken, runType: params.runType })
200175
200288
  ]);
200176
200289
  return {
200177
200290
  repo: {
@@ -200189,7 +200302,8 @@ async function resolveRunContextData(params) {
200189
200302
  // a failed mint on a runner that should have been able to mint is the same
200190
200303
  // outcome as the server-side failure: the run never sees stored secrets.
200191
200304
  secretsUnavailable: runContext.secretsUnavailable || !!process.env.ACTIONS_ID_TOKEN_REQUEST_URL && oidcToken === void 0,
200192
- routerUnfunded: runContext.routerUnfunded
200305
+ routerUnfunded: runContext.routerUnfunded,
200306
+ trialFallback: runContext.trialFallback
200193
200307
  };
200194
200308
  }
200195
200309
 
@@ -201269,7 +201383,11 @@ async function main() {
201269
201383
  resolveGit();
201270
201384
  const jobToken = getJobToken();
201271
201385
  const initialOctokit = createOctokit(jobToken);
201272
- const runContext = await resolveRunContextData({ octokit: initialOctokit, token: jobToken });
201386
+ const runContext = await resolveRunContextData({
201387
+ octokit: initialOctokit,
201388
+ token: jobToken,
201389
+ runType: typeof resolvedPromptInput === "string" ? void 0 : resolvedPromptInput.type
201390
+ });
201273
201391
  timer.checkpoint("runContextData");
201274
201392
  const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
201275
201393
  const toolState = initToolState({
@@ -201450,7 +201568,7 @@ async function main() {
201450
201568
  }
201451
201569
  const resolvedModel = credentials.kind === "fellBack" ? credentials.replacement : configuredModel;
201452
201570
  vertexCredentials = materializeVertexCredentials({ model: resolvedModel });
201453
- const agent2 = resolveAgent({
201571
+ let agent2 = resolveAgent({
201454
201572
  model: resolvedModel,
201455
201573
  proxyModel: payload.proxyModel,
201456
201574
  // the account opt-in and the canary arm are both admissions to codex, so
@@ -201462,15 +201580,32 @@ async function main() {
201462
201580
  const effectiveModel = payload.proxyModel ?? resolvedModel ?? payload.model;
201463
201581
  toolState.model = effectiveModel;
201464
201582
  if (!payload.proxyModel) {
201465
- validateAgentApiKey({
201466
- agent: agent2,
201467
- model: effectiveModel,
201468
- authorized: getAuthorizedModels(),
201469
- owner: runContext.repo.owner,
201470
- name: runContext.repo.name,
201471
- secretsUnavailable: runContext.secretsUnavailable,
201472
- routerUnfunded: runContext.routerUnfunded
201473
- });
201583
+ try {
201584
+ validateAgentApiKey({
201585
+ agent: agent2,
201586
+ model: effectiveModel,
201587
+ authorized: getAuthorizedModels(),
201588
+ owner: runContext.repo.owner,
201589
+ name: runContext.repo.name,
201590
+ secretsUnavailable: runContext.secretsUnavailable,
201591
+ routerUnfunded: runContext.routerUnfunded
201592
+ });
201593
+ } catch (missingKey) {
201594
+ const funded = runContext.trialFallback && missingKey instanceof NoUsableCredentialError ? await resolveTrialFallback({
201595
+ payload,
201596
+ configuredModel: effectiveModel,
201597
+ oidcCredentials,
201598
+ repo: runContext.repo,
201599
+ toolState
201600
+ }) : false;
201601
+ if (!funded) throw missingKey;
201602
+ agent2 = resolveAgent({
201603
+ model: resolvedModel,
201604
+ proxyModel: payload.proxyModel,
201605
+ codexAgent: runContext.repoSettings.codexAgent || payload.codexArm === true
201606
+ });
201607
+ toolState.agent = agent2.name;
201608
+ }
201474
201609
  }
201475
201610
  await setupGit({
201476
201611
  gitToken: tokenRef.gitToken,
@@ -3,7 +3,7 @@
3
3
  * Re-exports shared types, values, and utilities needed by the Next.js app.
4
4
  */
5
5
  export type { AuthorPermission, AutoTier, EffortPosition, ModelAlias, ModelProvider, Payload, PayloadEvent, ProviderConfig, PushPermission, ShellPermission, ToolPermission, WriteablePayload, XrepoConfig, } from "../external.ts";
6
- export { AUTO_EFFICIENT, AUTO_INTELLIGENT, DEFAULT_EFFORT_POSITION, DEFAULT_PROXY_MODEL, defaultAutoTier, EFFORT_ALIASES, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoTier, isCardGatedModel, isEffortPosition, isOssAllowedModel, modelAliases, modelHasStoredAuth, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, offeredRungs, ossFundedModelNames, parseEffortPosition, parseModel, providers, pullfrogMcpName, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolveRung, rungLabel, rungPosition, } from "../external.ts";
6
+ export { AUTO_EFFICIENT, AUTO_INTELLIGENT, DEFAULT_EFFORT_POSITION, DEFAULT_PROXY_MODEL, defaultAutoTier, EFFORT_ALIASES, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoTier, isCardGatedModel, isEffortPosition, isOssAllowedModel, modelAliases, modelHasStoredAuth, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, offeredRungs, ossFundedModelNames, parseEffortPosition, parseModel, providers, pullfrogMcpName, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolveRung, rungLabel, rungPosition, SUBSIDY_RUNG, } from "../external.ts";
7
7
  export type { Mode } from "../modes.ts";
8
8
  export { modes } from "../modes.ts";
9
9
  export { commercialPaywallBody } from "../utils/billingErrors.ts";