pullfrog 0.1.76 → 0.1.78

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/internal.js CHANGED
@@ -8,7 +8,7 @@ var __export = (target, all) => {
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "pullfrog",
11
- version: "0.1.76",
11
+ version: "0.1.78",
12
12
  cliContractVersion: "1",
13
13
  type: "module",
14
14
  bin: {
@@ -14509,26 +14509,34 @@ var providers = {
14509
14509
  models: {
14510
14510
  grok: {
14511
14511
  displayName: "Grok",
14512
- resolve: "xai/grok-4.5",
14513
- effort: ["low", "medium", "high"],
14514
- openRouterResolve: "openrouter/x-ai/grok-4.5",
14512
+ resolve: "xai/grok-4.6",
14513
+ effort: ["low", "medium", "high", "xhigh"],
14514
+ openRouterResolve: "openrouter/x-ai/grok-4.6",
14515
14515
  preferred: true
14516
14516
  },
14517
+ // the Smart ladder's cheap rung: 1.25/2.5 against 4.6's 2/6, and a 0.2
14518
+ // cache read against 0.5 — the only live xAI model a rung can save on.
14519
+ "grok-4.3": {
14520
+ displayName: "Grok 4.3",
14521
+ resolve: "xai/grok-4.3",
14522
+ effort: ["none", "low", "medium", "high"],
14523
+ openRouterResolve: "openrouter/x-ai/grok-4.3"
14524
+ },
14517
14525
  // legacy aliases — xAI retired the entire fast/code-fast line on
14518
14526
  // 2026-05-15 (https://docs.x.ai/developers/migration/may-15-deprecation)
14519
14527
  // and now redirects every deprecated text-model slug to grok-4.3 at
14520
14528
  // standard pricing. fall back to the live `xai/grok` so the alias
14521
- // chain resolves to grok-4.5 for both direct-key and OpenRouter users.
14529
+ // chain resolves to grok-4.6 for both direct-key and OpenRouter users.
14522
14530
  "grok-fast": {
14523
14531
  displayName: "Grok Fast",
14524
14532
  resolve: "xai/grok-4-1-fast",
14525
- openRouterResolve: "openrouter/x-ai/grok-4.5",
14533
+ openRouterResolve: "openrouter/x-ai/grok-4.6",
14526
14534
  fallback: "xai/grok"
14527
14535
  },
14528
14536
  "grok-code-fast": {
14529
14537
  displayName: "Grok Code Fast",
14530
14538
  resolve: "xai/grok-code-fast-1",
14531
- openRouterResolve: "openrouter/x-ai/grok-4.5",
14539
+ openRouterResolve: "openrouter/x-ai/grok-4.6",
14532
14540
  fallback: "xai/grok"
14533
14541
  }
14534
14542
  }
@@ -14547,6 +14555,12 @@ var providers = {
14547
14555
  // $0.0405. there is no `~deepseek/*-pro-latest` pointer to track, so this
14548
14556
  // one has to be a dated pin; the `models-catalog` drift test is what
14549
14557
  // catches the next release.
14558
+ // from 2026-09-14 DeepSeek serves every direct `deepseek-v4-pro` call with
14559
+ // V4.1-Flash at Flash rates until V4.1-Pro ships. it is still the only Pro
14560
+ // id the vendor lists, and the OpenRouter 0813 pin is third-party-hosted
14561
+ // and unaffected — so no `fallback` to Flash, which would drag the Router
14562
+ // route down with it. the OSS program dropped Pro from its menu instead;
14563
+ // see `OSS_MODEL_ALLOWLIST`.
14550
14564
  "deepseek-pro": {
14551
14565
  displayName: "DeepSeek Pro",
14552
14566
  resolve: "deepseek/deepseek-v4-pro",
@@ -14555,30 +14569,24 @@ var providers = {
14555
14569
  openRouterResolve: "openrouter/deepseek/deepseek-v4-pro-0813",
14556
14570
  preferred: true
14557
14571
  },
14558
- // DeepSeek upgrades the `deepseek-v4-flash` API model in place, so the
14559
- // direct `resolve` needs no version. OpenRouter instead forked the 0731
14560
- // release into its own id and left the April preview live under the
14561
- // unversioned one at a HIGHER price ($0.14/$0.28 vs $0.09/$0.18) — so the
14562
- // OpenRouter route can never use the bare id. it tracks the rolling
14563
- // `~deepseek/*-latest` pointer (rule 4), which follows the next in-place
14564
- // upgrade on its own rather than pinning a dated snapshot that goes stale
14565
- // every release. that pointer is NOT priced like 0731 — its listed rates
14566
- // run +40% on output and +57.5% on cache read, and it costs 12% more per
14567
- // run on authoritative spend ($0.0405 vs $0.0361). kept anyway: ~$45/yr
14568
- // buys auto-following the upgrade, and the listed gap overstates the real
14569
- // one because a rolling alias prices at its routing ceiling.
14570
- // 0731 gained a `low` rung and renamed the top to `max`, and that ladder
14571
- // now reads the same on BOTH routes — the in-place direct upgrade caught
14572
- // up to the fork. so `low`, not `high`, is position 0 either way, which is
14573
- // why the OSS effort floor in `main.ts` pins the `high` rung by name. Pro
14574
- // is the same shape via OpenRouter since 0813; only its direct route still
14575
- // starts at `high`.
14572
+ // V4.1-Flash (2026-09-10) retired `deepseek-v4-flash`; DeepSeek's /models
14573
+ // now lists the unversioned `deepseek-flash`, so the direct resolve is the
14574
+ // rolling id at the same price. OpenRouter treats V4.1 as its own id
14575
+ // (`deepseek/deepseek-v4.1-flash`, $0.15/$0.6, cache $0.003) and its
14576
+ // `~deepseek/deepseek-v4-flash-latest` pointer still served 0731 on
14577
+ // 2026-09-11, so this is a pinned id rather than the pointer and the next
14578
+ // Flash release is a catalog edit (the bump cron flags it). this target is
14579
+ // the funded OSS default: priced on the measured OSS token mix at x1.34
14580
+ // the pointer's $0.0531/run on the DeepSeek-hosted endpoint — see
14581
+ // wiki/oss-model-allowlist.md. the bare `deepseek-v4-flash` on OpenRouter
14582
+ // is still the April preview, so that route can never use it. both routes
14583
+ // publish `low, high, max`; the OSS effort floor pins `high` by name.
14576
14584
  "deepseek-flash": {
14577
14585
  displayName: "DeepSeek Flash",
14578
- resolve: "deepseek/deepseek-v4-flash",
14586
+ resolve: "deepseek/deepseek-flash",
14579
14587
  effort: ["low", "high", "max"],
14580
14588
  openRouterEffort: ["low", "high", "max"],
14581
- openRouterResolve: "openrouter/~deepseek/deepseek-v4-flash-latest"
14589
+ openRouterResolve: "openrouter/deepseek/deepseek-v4.1-flash"
14582
14590
  },
14583
14591
  // legacy aliases — deepseek retires these on 2026-07-24; transparently
14584
14592
  // upgrade existing users to the v4 family via the fallback chain.
@@ -14681,6 +14689,40 @@ var providers = {
14681
14689
  }
14682
14690
  }
14683
14691
  }),
14692
+ // Meta Model API — the direct route to Muse Spark. a registry entry, like
14693
+ // kimi-for-coding: models.dev carries `meta` (`https://api.meta.ai/v1`, npm
14694
+ // `@ai-sdk/openai`) and opencode 1.18.29 enables it from a bare
14695
+ // META_MODEL_API_KEY — all five ids list in `opencode models`, and a bogus key
14696
+ // reaches Meta's own auth check (`invalid_api_key`). see wiki/muse-spark.md.
14697
+ meta: provider({
14698
+ displayName: "Meta",
14699
+ envVars: ["META_MODEL_API_KEY"],
14700
+ models: {
14701
+ // the Standard tier. no `subagentModel`: the contributor tier below is
14702
+ // the same model, not a cheaper sibling.
14703
+ "muse-spark": {
14704
+ displayName: "Muse Spark",
14705
+ resolve: "meta/muse-spark-1.3",
14706
+ effort: ["minimal", "low", "medium", "high", "xhigh", "max"],
14707
+ openRouterResolve: "openrouter/meta/muse-spark-1.3",
14708
+ preferred: true
14709
+ },
14710
+ // the Contributor tier: the same model at $0.10 / $0.20 (cache read
14711
+ // $0.002) because Meta trains on the prompts and completions. an opt-in
14712
+ // pick on the OSS menu (public code, headless runs), never the default.
14713
+ // OpenRouter only serves it when the account allows paid-model training,
14714
+ // so the runtime opens data collection for this id alone — see
14715
+ // `openRouterProvider` in opencodeShared.ts.
14716
+ "muse-spark-contributor": {
14717
+ displayName: "Muse Spark Contributor",
14718
+ description: "Meta trains on prompts and completions",
14719
+ resolve: "meta/muse-spark-1.3-contributor",
14720
+ effort: ["minimal", "low", "medium", "high", "xhigh"],
14721
+ openRouterEffort: ["minimal", "low", "medium", "high", "xhigh", "max"],
14722
+ openRouterResolve: "openrouter/meta/muse-spark-1.3-contributor"
14723
+ }
14724
+ }
14725
+ }),
14684
14726
  opencode: provider({
14685
14727
  displayName: "OpenCode Zen",
14686
14728
  envVars: ["OPENCODE_API_KEY"],
@@ -14881,6 +14923,17 @@ var providers = {
14881
14923
  effort: ["minimal", "low", "medium", "high"],
14882
14924
  openRouterResolve: "openrouter/openai/gpt-5-nano"
14883
14925
  },
14926
+ // Zen's PAID Muse Spark, priced like Meta's own Standard tier. not the
14927
+ // `-contributor-free` id beside it, which is the data-collection variant
14928
+ // Go refuses with DataPolicyError. unverified through the harness on
14929
+ // 2026-09-11: the workspace was out of balance and a claude-sonnet-5
14930
+ // control failed identically. see wiki/muse-spark.md.
14931
+ "muse-spark": {
14932
+ displayName: "Muse Spark",
14933
+ resolve: "opencode/muse-spark-1.3",
14934
+ effort: ["minimal", "low", "medium", "high", "xhigh", "max"],
14935
+ openRouterResolve: "openrouter/meta/muse-spark-1.3"
14936
+ },
14884
14937
  // Zen's live free MiMo, and the second free row in a menu that big-pickle
14885
14938
  // was alone in since `mimo-v2-pro-free` lost its model.
14886
14939
  mimo: {
@@ -15260,9 +15313,9 @@ var providers = {
15260
15313
  },
15261
15314
  grok: {
15262
15315
  displayName: "Grok",
15263
- resolve: "openrouter/x-ai/grok-4.5",
15264
- effort: ["low", "medium", "high"],
15265
- openRouterResolve: "openrouter/x-ai/grok-4.5"
15316
+ resolve: "openrouter/x-ai/grok-4.6",
15317
+ effort: ["low", "medium", "high", "xhigh"],
15318
+ openRouterResolve: "openrouter/x-ai/grok-4.6"
15266
15319
  },
15267
15320
  // dated pin, not the bare id — see `deepseek/deepseek-pro` for why
15268
15321
  // OpenRouter's unversioned `deepseek-v4-pro` is the stale April preview.
@@ -15272,13 +15325,14 @@ var providers = {
15272
15325
  effort: ["low", "high", "max"],
15273
15326
  openRouterResolve: "openrouter/deepseek/deepseek-v4-pro-0813"
15274
15327
  },
15275
- // rolling pointer, not the bare id — see `deepseek/deepseek-flash` for why
15276
- // OpenRouter's unversioned `deepseek-v4-flash` is the stale April preview.
15328
+ // the V4.1 id, not the bare one — see `deepseek/deepseek-flash` for why
15329
+ // OpenRouter's unversioned `deepseek-v4-flash` is the stale April preview
15330
+ // and why the `~deepseek/*-latest` pointer is no longer the target.
15277
15331
  "deepseek-flash": {
15278
15332
  displayName: "DeepSeek Flash",
15279
- resolve: "openrouter/~deepseek/deepseek-v4-flash-latest",
15333
+ resolve: "openrouter/deepseek/deepseek-v4.1-flash",
15280
15334
  effort: ["low", "high", "max"],
15281
- openRouterResolve: "openrouter/~deepseek/deepseek-v4-flash-latest"
15335
+ openRouterResolve: "openrouter/deepseek/deepseek-v4.1-flash"
15282
15336
  },
15283
15337
  // legacy alias — deepseek retires this on 2026-07-24; transparently
15284
15338
  // upgrade existing users to the v4 family via the fallback chain.
@@ -15309,6 +15363,23 @@ var providers = {
15309
15363
  displayName: "MiniMax M3",
15310
15364
  resolve: "openrouter/minimax/minimax-m3",
15311
15365
  openRouterResolve: "openrouter/minimax/minimax-m3"
15366
+ },
15367
+ // OpenRouter gates Meta models on an ACCOUNT-level 18+ confirmation
15368
+ // (openrouter.ai/settings/preferences). Pullfrog's account has it, so the
15369
+ // Router path runs; a BYOK OpenRouter key without it refuses with that
15370
+ // link before the request reaches Meta. see wiki/muse-spark.md.
15371
+ "muse-spark": {
15372
+ displayName: "Muse Spark",
15373
+ resolve: "openrouter/meta/muse-spark-1.3",
15374
+ effort: ["minimal", "low", "medium", "high", "xhigh", "max"],
15375
+ openRouterResolve: "openrouter/meta/muse-spark-1.3"
15376
+ },
15377
+ "muse-spark-contributor": {
15378
+ displayName: "Muse Spark Contributor",
15379
+ description: "Meta trains on prompts and completions",
15380
+ resolve: "openrouter/meta/muse-spark-1.3-contributor",
15381
+ effort: ["minimal", "low", "medium", "high", "xhigh", "max"],
15382
+ openRouterResolve: "openrouter/meta/muse-spark-1.3-contributor"
15312
15383
  }
15313
15384
  }
15314
15385
  }),
@@ -15376,10 +15447,13 @@ var providers = {
15376
15447
  resolve: "vercel/deepseek/deepseek-v4-pro-0813",
15377
15448
  effort: ["high", "xhigh"]
15378
15449
  },
15450
+ // the gateway's bare `deepseek-v4-flash` is the April preview — the same
15451
+ // fork trap as OpenRouter, with `deepseek-v4-flash-0731` beside it — so
15452
+ // this entry sat on the preview until V4.1. the gateway publishes no
15453
+ // effort ladder for the V4.1 id.
15379
15454
  "deepseek-flash": {
15380
15455
  displayName: "DeepSeek Flash",
15381
- resolve: "vercel/deepseek/deepseek-v4-flash",
15382
- effort: ["high", "xhigh"]
15456
+ resolve: "vercel/deepseek/deepseek-v4.1-flash"
15383
15457
  },
15384
15458
  glm: {
15385
15459
  displayName: "GLM",
@@ -15390,6 +15464,11 @@ var providers = {
15390
15464
  displayName: "Kimi K3",
15391
15465
  resolve: "vercel/moonshotai/kimi-k3",
15392
15466
  effort: ["low", "high", "max"]
15467
+ },
15468
+ // the gateway publishes no effort ladder for this id.
15469
+ "muse-spark": {
15470
+ displayName: "Muse Spark",
15471
+ resolve: "vercel/meta/muse-spark-1.3"
15393
15472
  }
15394
15473
  }
15395
15474
  })
@@ -15475,6 +15554,97 @@ function resolveAutoTier(params) {
15475
15554
  if (!params.hasCard) return AUTO_EFFICIENT;
15476
15555
  return isAutoTier(params.model) ? params.model : defaultAutoTier(params.hasCard);
15477
15556
  }
15557
+ var ROUTER_TIERS = ["minimal", "light", "standard", "deep"];
15558
+ function isRouterTier(value) {
15559
+ return typeof value === "string" && ROUTER_TIERS.some((tier) => tier === value);
15560
+ }
15561
+ var PROVIDER_LADDERS = {
15562
+ anthropic: {
15563
+ minimal: "anthropic/claude-haiku",
15564
+ light: "anthropic/claude-sonnet",
15565
+ standard: "anthropic/claude-opus",
15566
+ deep: "anthropic/claude-opus"
15567
+ },
15568
+ openai: {
15569
+ minimal: "openai/gpt-luna",
15570
+ light: "openai/gpt-terra",
15571
+ standard: "openai/gpt-sol",
15572
+ deep: "openai/gpt-astra"
15573
+ },
15574
+ google: {
15575
+ minimal: "google/gemini-flash",
15576
+ light: "google/gemini-flash",
15577
+ standard: "google/gemini-pro",
15578
+ deep: "google/gemini-pro"
15579
+ },
15580
+ deepseek: {
15581
+ minimal: "deepseek/deepseek-flash",
15582
+ light: "deepseek/deepseek-flash",
15583
+ standard: "deepseek/deepseek-pro",
15584
+ deep: "deepseek/deepseek-pro"
15585
+ },
15586
+ xai: {
15587
+ minimal: "xai/grok-4.3",
15588
+ light: "xai/grok-4.3",
15589
+ standard: "xai/grok",
15590
+ deep: "xai/grok"
15591
+ },
15592
+ moonshotai: {
15593
+ minimal: "moonshotai/kimi-k2",
15594
+ light: "moonshotai/kimi-k2",
15595
+ standard: "moonshotai/kimi-k3",
15596
+ deep: "moonshotai/kimi-k3"
15597
+ },
15598
+ openrouter: {
15599
+ minimal: "openrouter/deepseek-flash",
15600
+ light: "openrouter/gpt-luna",
15601
+ standard: "openrouter/gpt-sol",
15602
+ deep: "openrouter/claude-opus"
15603
+ },
15604
+ opencode: {
15605
+ minimal: "opencode/gpt-luna",
15606
+ light: "opencode/gpt-luna",
15607
+ standard: "opencode/gpt-sol",
15608
+ deep: "opencode/claude-opus"
15609
+ }
15610
+ };
15611
+ var ROUTER_LADDER = {
15612
+ minimal: "deepseek/deepseek-flash",
15613
+ light: "openai/gpt-luna",
15614
+ standard: "openai/gpt-sol",
15615
+ deep: "anthropic/claude-opus"
15616
+ };
15617
+ var AUTO_ROUTER = "auto/router";
15618
+ var AUTO_PREFIX = "auto/";
15619
+ function autoLadder(slug) {
15620
+ if (!slug || !slug.startsWith(AUTO_PREFIX) || isAutoTier(slug)) return void 0;
15621
+ const target = slug.slice(AUTO_PREFIX.length);
15622
+ return target === "router" ? ROUTER_LADDER : PROVIDER_LADDERS[target];
15623
+ }
15624
+ function isAutoRouted(slug) {
15625
+ return autoLadder(slug) !== void 0;
15626
+ }
15627
+ function isAutoSlug(slug) {
15628
+ return isAutoTier(slug) || isAutoRouted(slug);
15629
+ }
15630
+ function autoRoutedSlug(provider2) {
15631
+ return `${AUTO_PREFIX}${provider2}`;
15632
+ }
15633
+ var ROUTED_PROVIDERS = Object.keys(
15634
+ PROVIDER_LADDERS
15635
+ ).map((key) => ({ key, displayName: providers[key].displayName }));
15636
+ function ladderRungs(ladder) {
15637
+ const rungs = [];
15638
+ for (const tier of ROUTER_TIERS) {
15639
+ const last = rungs[rungs.length - 1];
15640
+ if (last?.slug === ladder[tier]) last.tiers.push(tier);
15641
+ else rungs.push({ slug: ladder[tier], tiers: [tier] });
15642
+ }
15643
+ return rungs;
15644
+ }
15645
+ function resolveRoutedModel(params) {
15646
+ return autoLadder(params.configured)?.[params.tier];
15647
+ }
15478
15648
  function isCardGatedModel(slug) {
15479
15649
  return resolveOpenRouterModel(slug) !== void 0;
15480
15650
  }
@@ -15483,7 +15653,7 @@ function resolveModelSlug(slug) {
15483
15653
  }
15484
15654
  var MAX_FALLBACK_DEPTH = 10;
15485
15655
  function resolveDisplayAlias(slug) {
15486
- let current = isAutoTier(slug) ? AUTO_TIER_TARGET[slug] : slug;
15656
+ let current = isAutoTier(slug) ? AUTO_TIER_TARGET[slug] : autoLadder(slug)?.standard ?? slug;
15487
15657
  const visited = /* @__PURE__ */ new Set();
15488
15658
  for (let i = 0; i < MAX_FALLBACK_DEPTH; i++) {
15489
15659
  if (visited.has(current)) return void 0;
@@ -15518,11 +15688,23 @@ if (!defaultProxyAlias?.openRouterResolve) {
15518
15688
  }
15519
15689
  var DEFAULT_PROXY_MODEL = defaultProxyAlias.openRouterResolve;
15520
15690
  var defaultProxyDisplayName = defaultProxyAlias.displayName;
15691
+ for (const [name, ladder] of Object.entries({ ...PROVIDER_LADDERS, router: ROUTER_LADDER })) {
15692
+ const terminal = /* @__PURE__ */ new Set();
15693
+ for (const slug of Object.values(ladder)) {
15694
+ const alias = resolveDisplayAlias(slug);
15695
+ if (!alias) throw new Error(`${name} ladder names unknown alias ${slug}`);
15696
+ terminal.add(alias.slug);
15697
+ }
15698
+ if (terminal.size < 2) throw new Error(`${name} ladder runs every tier on ${[...terminal][0]}`);
15699
+ }
15521
15700
  var OSS_MODEL_ALLOWLIST = [
15522
15701
  "deepseek/deepseek-flash",
15523
- "deepseek/deepseek-pro",
15524
15702
  "openai/gpt-luna",
15525
- "openrouter/minimax-m2.5"
15703
+ "openrouter/minimax-m2.5",
15704
+ // opt-in: 0.86x the old default on the measured mix, and Meta trains on the
15705
+ // traffic — fine for public code on headless runs, the human decided
15706
+ // 2026-09-11. unmeasured on a real run; not the default until it is.
15707
+ "meta/muse-spark-contributor"
15526
15708
  ];
15527
15709
  var OSS_RECOMMENDED_MODEL = AUTO_TIER_TARGET[AUTO_EFFICIENT];
15528
15710
  function ossFundedModelNames() {
@@ -16599,6 +16781,7 @@ export {
16599
16781
  APPROVAL_CHECK_NAME,
16600
16782
  AUTO_EFFICIENT,
16601
16783
  AUTO_INTELLIGENT,
16784
+ AUTO_ROUTER,
16602
16785
  CLI_CONTRACT_HEADER,
16603
16786
  CLI_CONTRACT_VERSION,
16604
16787
  CLI_UPGRADE_MESSAGE,
@@ -16612,9 +16795,14 @@ export {
16612
16795
  OSS_RECOMMENDED_MODEL,
16613
16796
  PROVIDER_GATEWAY_URL_ENV,
16614
16797
  PULLFROG_DIVIDER,
16798
+ ROUTED_PROVIDERS,
16799
+ ROUTER_LADDER,
16800
+ ROUTER_TIERS,
16615
16801
  RUN_STATUS_CHECK_NAME,
16616
16802
  SUBSIDY_RUNG,
16617
16803
  TIMEOUT_DISABLED,
16804
+ autoLadder,
16805
+ autoRoutedSlug,
16618
16806
  buildPullfrogFooter,
16619
16807
  commercialPaywallBody,
16620
16808
  configEntrySchema,
@@ -16634,6 +16822,8 @@ export {
16634
16822
  getModelProvider,
16635
16823
  getProgressComment,
16636
16824
  getProviderDisplayName,
16825
+ isAutoRouted,
16826
+ isAutoSlug,
16637
16827
  isAutoTier,
16638
16828
  isCardGatedModel,
16639
16829
  isCredentialProbeable,
@@ -16641,7 +16831,9 @@ export {
16641
16831
  isLeapingIntoActionCommentBody,
16642
16832
  isOssAllowedModel,
16643
16833
  isPullfrog,
16834
+ isRouterTier,
16644
16835
  isValidTimeString,
16836
+ ladderRungs,
16645
16837
  modelAliases,
16646
16838
  modelHasStoredAuth,
16647
16839
  modes,
@@ -16662,6 +16854,7 @@ export {
16662
16854
  resolveModelRung,
16663
16855
  resolveModelSlug,
16664
16856
  resolveOpenRouterModel,
16857
+ resolveRoutedModel,
16665
16858
  resolveRung,
16666
16859
  runStatusCheckNeedsFinalizing,
16667
16860
  rungLabel,
package/dist/models.d.ts CHANGED
@@ -121,6 +121,7 @@ export declare const providers: {
121
121
  deepseek: ProviderConfig;
122
122
  moonshotai: ProviderConfig;
123
123
  "kimi-for-coding": ProviderConfig;
124
+ meta: ProviderConfig;
124
125
  opencode: ProviderConfig;
125
126
  "opencode-go": ProviderConfig;
126
127
  bedrock: ProviderConfig;
@@ -218,6 +219,58 @@ export declare function resolveAutoTier(params: {
218
219
  model: string | null;
219
220
  hasCard: boolean;
220
221
  }): AutoTier;
222
+ /**
223
+ * the four rungs the model router scores a review into, ascending. `minimal` is
224
+ * a PR with no behavioural surface, `deep` one whose defects are absences the
225
+ * diff does not show. see wiki/router.md for how a tier is earned.
226
+ */
227
+ export declare const ROUTER_TIERS: readonly ["minimal", "light", "standard", "deep"];
228
+ export type RouterTier = (typeof ROUTER_TIERS)[number];
229
+ export declare function isRouterTier(value: unknown): value is RouterTier;
230
+ type Ladder = Record<RouterTier, string>;
231
+ /**
232
+ * the Router's own ladder for an account on `auto/router` with a card on
233
+ * file. an account without a card is never routed onto this:
234
+ * `resolveAutoTier` clamps it to the efficient default at every tier, exactly
235
+ * as before the router existed.
236
+ */
237
+ export declare const ROUTER_LADDER: Ladder;
238
+ /**
239
+ * the `repo.model` sentinel that turns the router on: `auto/<provider>` runs
240
+ * each piece of work on that provider's ladder, `auto/router` on the Pullfrog
241
+ * Router's. distinct from the two managed tiers above, which each name ONE
242
+ * model. a Pro feature — outside Pro the sentinel simply runs its ladder's
243
+ * `standard` rung, which is what `resolveDisplayAlias` resolves it to.
244
+ */
245
+ export declare const AUTO_ROUTER = "auto/router";
246
+ /** the ladder an Auto sentinel routes on; undefined for a tier or a pin */
247
+ export declare function autoLadder(slug: string | null | undefined): Ladder | undefined;
248
+ export declare function isAutoRouted(slug: string | null | undefined): boolean;
249
+ /** any `auto/*` sentinel — a managed tier or the router — as opposed to a concrete pin */
250
+ export declare function isAutoSlug(slug: string | null | undefined): boolean;
251
+ export declare function autoRoutedSlug(provider: string): string;
252
+ /** the providers a BYOK repo can put on Auto — exactly the ones with a ladder */
253
+ export declare const ROUTED_PROVIDERS: readonly {
254
+ key: string;
255
+ displayName: string;
256
+ }[];
257
+ /**
258
+ * a ladder's distinct models in ascending order, each with the tiers it
259
+ * serves — the console's "what Auto runs on" list, where a model that covers
260
+ * two tiers is one row.
261
+ */
262
+ export declare function ladderRungs(ladder: Ladder): {
263
+ slug: string;
264
+ tiers: RouterTier[];
265
+ }[];
266
+ /**
267
+ * the model a routed run takes: the tier's rung on the ladder the configured
268
+ * Auto sentinel names. undefined for a pin — a pin opts out of routing.
269
+ */
270
+ export declare function resolveRoutedModel(params: {
271
+ configured: string | null | undefined;
272
+ tier: RouterTier;
273
+ }): string | undefined;
221
274
  /**
222
275
  * Router-resolvable — the set a card on file unlocks. custom (non-Auto) picks
223
276
  * are card-gated wholesale on the Router: the console locks the Custom tab
@@ -292,6 +345,12 @@ export declare const DEFAULT_PROXY_MODEL: string;
292
345
  * over 2,203 real runs ($0.4782 vs $0.0362), almost entirely on its cache-read
293
346
  * RATE — 8.5x Flash's. it also fails 2.9% of runs against Flash's 0.0%. best
294
347
  * achievable was 10.9x (cheapest OpenRouter endpoint), so no routing fixes it.
348
+ *
349
+ * DeepSeek Pro was funded and then dropped on 2026-09-11: 88% of OSS spend at
350
+ * $0.3117/run authoritative over 4,795 runs (30d), against Flash's $0.0531 —
351
+ * and DeepSeek's V4.1-Flash release says it beats V4-Pro and phases Pro out.
352
+ * a subsidised Pro pick now runs V4.1 Flash; BYOK and Router Pro are untouched.
353
+ * re-add it only after V4.1-Pro ships AND is priced on a real run.
295
354
  * see wiki/oss-model-allowlist.md.
296
355
  */
297
356
  export declare const OSS_MODEL_ALLOWLIST: readonly string[];
@@ -7,6 +7,13 @@ export declare const JsonPayload: import("arktype/internal/variants/object.ts").
7
7
  type?: string | undefined;
8
8
  model?: string | undefined;
9
9
  modelExplicit?: boolean | undefined;
10
+ routing?: {
11
+ tier: "minimal" | "light" | "standard" | "deep";
12
+ stakes: number;
13
+ workload: number;
14
+ source: "scorer" | "heuristic" | "fixed";
15
+ rationale: string;
16
+ } | undefined;
10
17
  effort?: string | number | undefined;
11
18
  debug?: boolean | undefined;
12
19
  triggerer?: string | undefined;
@@ -54,6 +61,13 @@ export declare function resolvePayload(resolvedPromptInput: ResolvedPromptInput,
54
61
  version: string;
55
62
  model: string | undefined;
56
63
  modelExplicit: boolean;
64
+ routing: {
65
+ tier: "minimal" | "light" | "standard" | "deep";
66
+ stakes: number;
67
+ workload: number;
68
+ source: "scorer" | "heuristic" | "fixed";
69
+ rationale: string;
70
+ } | undefined;
57
71
  effort: number | undefined;
58
72
  debug: true | undefined;
59
73
  prompt: string;
@@ -1,4 +1,5 @@
1
1
  import type { PushPermission, ShellPermission } from "../external.ts";
2
+ import type { RouterTier } from "../models.ts";
2
3
  import type { RepoContext } from "./github.ts";
3
4
  export interface Mode {
4
5
  id: string;
@@ -104,4 +105,7 @@ export declare function fetchRunContext(params: {
104
105
  /** `payload.type` — lets the server apply this repo's per-trigger model
105
106
  * override, which it cannot derive from owner/repo alone. */
106
107
  runType?: string | undefined;
108
+ /** `payload.routing.tier` — the model router's tier, which run-context
109
+ * applies to the Router proxy mint the same way it applies `runType`. */
110
+ routedTier?: RouterTier | undefined;
107
111
  }): Promise<RunContext>;
@@ -1,4 +1,5 @@
1
1
  import type { Octokit } from "@octokit/rest";
2
+ import type { RouterTier } from "../models.ts";
2
3
  import { type OctokitWithPlugins } from "./github.ts";
3
4
  import { type AccountPlan, type CommercialRefusal, type RepoSettings } from "./runContext.ts";
4
5
  export interface RunContextData {
@@ -33,6 +34,8 @@ interface ResolveRunContextDataParams {
33
34
  * because run-context is fetched first and needs it to pick this trigger's
34
35
  * model override. */
35
36
  runType?: string | undefined;
37
+ /** the model router's tier from the payload, forwarded so run-context applies it to the proxy mint. */
38
+ routedTier?: RouterTier | undefined;
36
39
  }
37
40
  /**
38
41
  * initialize run context data: parse context, fetch repo info and settings
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.76",
3
+ "version": "0.1.78",
4
4
  "cliContractVersion": "1",
5
5
  "type": "module",
6
6
  "bin": {