pullfrog 0.1.51 → 0.1.53

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.
@@ -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, modelAliases, modelHasStoredAuth, offeredRungs, 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, parseEffortPosition, parseModel, providers, pullfrogMcpName, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolveRung, rungLabel, rungPosition, } 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";
package/dist/internal.js CHANGED
@@ -100,7 +100,11 @@ var providers = {
100
100
  envVars: ["OPENAI_API_KEY"],
101
101
  managedCredentials: ["CODEX_AUTH_JSON"],
102
102
  models: {
103
- gpt: {
103
+ // Sol/Terra/Luna are OpenAI's durable capability tiers, so they ARE the
104
+ // brand-tier names the slug convention asks for — the pre-5.6 `gpt` /
105
+ // `gpt-pro` / `gpt-mini` slugs are holdovers from the retired GPT / GPT Pro
106
+ // / GPT Mini tiering and are carried below as deprecated aliases.
107
+ "gpt-sol": {
104
108
  displayName: "GPT Sol",
105
109
  resolve: "openai/gpt-5.6-sol",
106
110
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
@@ -111,24 +115,23 @@ var providers = {
111
115
  // Sol served at reasoning.mode=pro — same $/token as Sol, just more tokens
112
116
  // burned; not a pricier premium tier. models.dev has no -pro id, so direct-key
113
117
  // (BYOK) resolves to plain Sol; only the Router/OpenRouter path gets sol-pro.
114
- "gpt-pro": {
118
+ "gpt-sol-pro": {
115
119
  displayName: "GPT Sol Pro",
116
120
  description: "Maximum reasoning effort",
117
121
  resolve: "openai/gpt-5.6-sol",
118
122
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
119
123
  openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
120
- subagentModel: "gpt"
124
+ subagentModel: "gpt-sol"
121
125
  },
122
- // gpt-5.6's balanced mid-tier (Sol/Terra/Luna are durable capability tiers,
123
- // not version bumps). selectable on its own and doubles as `gpt`'s cheaper
124
- // lens-fanout subagent — replaces the old hidden gpt-5.4 subagent target.
126
+ // gpt-5.6's balanced mid-tier. selectable on its own and doubles as Sol's
127
+ // cheaper lens-fanout subagent replaces the old hidden gpt-5.4 target.
125
128
  "gpt-terra": {
126
129
  displayName: "GPT Terra",
127
130
  resolve: "openai/gpt-5.6-terra",
128
131
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
129
132
  openRouterResolve: "openrouter/openai/gpt-5.6-terra"
130
133
  },
131
- "gpt-mini": {
134
+ "gpt-luna": {
132
135
  displayName: "GPT Luna",
133
136
  resolve: "openai/gpt-5.6-luna",
134
137
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
@@ -143,20 +146,40 @@ var providers = {
143
146
  displayName: "GPT Codex",
144
147
  resolve: "openai/gpt-5.3-codex",
145
148
  openRouterResolve: "openrouter/openai/gpt-5.3-codex",
146
- fallback: "openai/gpt"
149
+ fallback: "openai/gpt-sol"
147
150
  },
148
151
  "gpt-codex-mini": {
149
152
  displayName: "GPT Codex Mini",
150
153
  resolve: "openai/gpt-5.1-codex-mini",
151
154
  openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
152
- fallback: "openai/gpt-mini"
155
+ fallback: "openai/gpt-luna"
156
+ },
157
+ // pre-5.6 tier slugs. the tiers themselves were renamed Sol/Sol Pro/Luna,
158
+ // so these fold forward rather than describing anything that still runs.
159
+ gpt: {
160
+ displayName: "GPT",
161
+ resolve: "openai/gpt-5.6-sol",
162
+ openRouterResolve: "openrouter/openai/gpt-5.6-sol",
163
+ fallback: "openai/gpt-sol"
164
+ },
165
+ "gpt-pro": {
166
+ displayName: "GPT Pro",
167
+ resolve: "openai/gpt-5.6-sol",
168
+ openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
169
+ fallback: "openai/gpt-sol-pro"
170
+ },
171
+ "gpt-mini": {
172
+ displayName: "GPT Mini",
173
+ resolve: "openai/gpt-5.6-luna",
174
+ openRouterResolve: "openrouter/openai/gpt-5.6-luna",
175
+ fallback: "openai/gpt-luna"
153
176
  },
154
- // dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
177
+ // dropped hidden subagent tier — folds stored pins forward to Sol.
155
178
  "gpt-5.4": {
156
179
  displayName: "GPT 5.4",
157
180
  resolve: "openai/gpt-5.4",
158
181
  openRouterResolve: "openrouter/openai/gpt-5.4",
159
- fallback: "openai/gpt"
182
+ fallback: "openai/gpt-sol"
160
183
  },
161
184
  o3: {
162
185
  displayName: "O3",
@@ -184,9 +207,9 @@ var providers = {
184
207
  },
185
208
  "gemini-flash": {
186
209
  displayName: "Gemini Flash",
187
- resolve: "google/gemini-3.5-flash",
210
+ resolve: "google/gemini-3.6-flash",
188
211
  effort: ["minimal", "low", "medium", "high"],
189
- openRouterResolve: "openrouter/google/gemini-3.5-flash"
212
+ openRouterResolve: "openrouter/google/gemini-3.6-flash"
190
213
  }
191
214
  }
192
215
  }),
@@ -196,26 +219,26 @@ var providers = {
196
219
  models: {
197
220
  grok: {
198
221
  displayName: "Grok",
199
- resolve: "xai/grok-4.3",
200
- effort: ["none", "low", "medium", "high"],
201
- openRouterResolve: "openrouter/x-ai/grok-4.3",
222
+ resolve: "xai/grok-4.5",
223
+ effort: ["low", "medium", "high"],
224
+ openRouterResolve: "openrouter/x-ai/grok-4.5",
202
225
  preferred: true
203
226
  },
204
227
  // legacy aliases — xAI retired the entire fast/code-fast line on
205
228
  // 2026-05-15 (https://docs.x.ai/developers/migration/may-15-deprecation)
206
229
  // and now redirects every deprecated text-model slug to grok-4.3 at
207
230
  // standard pricing. fall back to the live `xai/grok` so the alias
208
- // chain resolves to grok-4.3 for both direct-key and OpenRouter users.
231
+ // chain resolves to grok-4.5 for both direct-key and OpenRouter users.
209
232
  "grok-fast": {
210
233
  displayName: "Grok Fast",
211
234
  resolve: "xai/grok-4-1-fast",
212
- openRouterResolve: "openrouter/x-ai/grok-4.3",
235
+ openRouterResolve: "openrouter/x-ai/grok-4.5",
213
236
  fallback: "xai/grok"
214
237
  },
215
238
  "grok-code-fast": {
216
239
  displayName: "Grok Code Fast",
217
240
  resolve: "xai/grok-code-fast-1",
218
- openRouterResolve: "openrouter/x-ai/grok-4.3",
241
+ openRouterResolve: "openrouter/x-ai/grok-4.5",
219
242
  fallback: "xai/grok"
220
243
  }
221
244
  }
@@ -232,12 +255,25 @@ var providers = {
232
255
  openRouterResolve: "openrouter/deepseek/deepseek-v4-pro",
233
256
  preferred: true
234
257
  },
258
+ // DeepSeek upgrades the `deepseek-v4-flash` API model in place, so the
259
+ // direct `resolve` needs no version. OpenRouter instead forked the 0731
260
+ // release into its own id and left the April preview live under the
261
+ // unversioned one at a HIGHER price ($0.14/$0.28 vs $0.09/$0.18) — so the
262
+ // OpenRouter route can never use the bare id. it tracks the rolling
263
+ // `~deepseek/*-latest` pointer (rule 4), which resolves to 0731 at the
264
+ // same price today and follows the next in-place upgrade on its own,
265
+ // rather than pinning a dated snapshot that goes stale every release.
266
+ // 0731 gained a `low` rung and renamed the top to `max`, unlike Pro
267
+ // (`high, max` direct / `high, xhigh` via OpenRouter). that ladder now
268
+ // reads the same on BOTH routes — the in-place direct upgrade caught up
269
+ // to the fork — so `low`, not `high`, is position 0 either way, which is
270
+ // why the OSS effort floor in `main.ts` pins the `high` rung by name.
235
271
  "deepseek-flash": {
236
272
  displayName: "DeepSeek Flash",
237
273
  resolve: "deepseek/deepseek-v4-flash",
238
- effort: ["high", "max"],
239
- openRouterEffort: ["high", "xhigh"],
240
- openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
274
+ effort: ["low", "high", "max"],
275
+ openRouterEffort: ["low", "high", "max"],
276
+ openRouterResolve: "openrouter/~deepseek/deepseek-v4-flash-latest"
241
277
  },
242
278
  // legacy aliases — deepseek retires these on 2026-07-24; transparently
243
279
  // upgrade existing users to the v4 family via the fallback chain.
@@ -306,30 +342,30 @@ var providers = {
306
342
  resolve: "opencode/claude-haiku-4-5",
307
343
  openRouterResolve: "openrouter/anthropic/claude-haiku-4.5"
308
344
  },
309
- gpt: {
345
+ "gpt-sol": {
310
346
  displayName: "GPT Sol",
311
347
  resolve: "opencode/gpt-5.6-sol",
312
348
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
313
349
  openRouterResolve: "openrouter/openai/gpt-5.6-sol",
314
350
  subagentModel: "gpt-terra"
315
351
  },
316
- // see openai/gpt-pro — Zen has no -pro id, so direct resolves to plain Sol.
317
- "gpt-pro": {
352
+ // see openai/gpt-sol-pro — Zen has no -pro id, so direct resolves to plain Sol.
353
+ "gpt-sol-pro": {
318
354
  displayName: "GPT Sol Pro",
319
355
  description: "Maximum reasoning effort",
320
356
  resolve: "opencode/gpt-5.6-sol",
321
357
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
322
358
  openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
323
- subagentModel: "gpt"
359
+ subagentModel: "gpt-sol"
324
360
  },
325
- // gpt-5.6 balanced mid-tier — selectable + `gpt`'s subagent. see openai above.
361
+ // gpt-5.6 balanced mid-tier — selectable + Sol's subagent. see openai above.
326
362
  "gpt-terra": {
327
363
  displayName: "GPT Terra",
328
364
  resolve: "opencode/gpt-5.6-terra",
329
365
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
330
366
  openRouterResolve: "openrouter/openai/gpt-5.6-terra"
331
367
  },
332
- "gpt-mini": {
368
+ "gpt-luna": {
333
369
  displayName: "GPT Luna",
334
370
  resolve: "opencode/gpt-5.6-luna",
335
371
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
@@ -340,20 +376,39 @@ var providers = {
340
376
  displayName: "GPT Codex",
341
377
  resolve: "opencode/gpt-5.3-codex",
342
378
  openRouterResolve: "openrouter/openai/gpt-5.3-codex",
343
- fallback: "opencode/gpt"
379
+ fallback: "opencode/gpt-sol"
344
380
  },
345
381
  "gpt-codex-mini": {
346
382
  displayName: "GPT Codex Mini",
347
383
  resolve: "opencode/gpt-5.1-codex-mini",
348
384
  openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
349
- fallback: "opencode/gpt-mini"
385
+ fallback: "opencode/gpt-luna"
350
386
  },
351
- // dropped hidden subagent tier folds stored pins forward to gpt (Sol).
387
+ // pre-5.6 tier slugssee openai provider above.
388
+ gpt: {
389
+ displayName: "GPT",
390
+ resolve: "opencode/gpt-5.6-sol",
391
+ openRouterResolve: "openrouter/openai/gpt-5.6-sol",
392
+ fallback: "opencode/gpt-sol"
393
+ },
394
+ "gpt-pro": {
395
+ displayName: "GPT Pro",
396
+ resolve: "opencode/gpt-5.6-sol",
397
+ openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
398
+ fallback: "opencode/gpt-sol-pro"
399
+ },
400
+ "gpt-mini": {
401
+ displayName: "GPT Mini",
402
+ resolve: "opencode/gpt-5.6-luna",
403
+ openRouterResolve: "openrouter/openai/gpt-5.6-luna",
404
+ fallback: "opencode/gpt-luna"
405
+ },
406
+ // dropped hidden subagent tier — folds stored pins forward to Sol.
352
407
  "gpt-5.4": {
353
408
  displayName: "GPT 5.4",
354
409
  resolve: "opencode/gpt-5.4",
355
410
  openRouterResolve: "openrouter/openai/gpt-5.4",
356
- fallback: "opencode/gpt"
411
+ fallback: "opencode/gpt-sol"
357
412
  },
358
413
  "gemini-pro": {
359
414
  displayName: "Gemini Pro",
@@ -364,21 +419,19 @@ var providers = {
364
419
  },
365
420
  "gemini-flash": {
366
421
  displayName: "Gemini Flash",
367
- resolve: "opencode/gemini-3.5-flash",
422
+ resolve: "opencode/gemini-3.6-flash",
368
423
  effort: ["minimal", "low", "medium", "high"],
369
- openRouterResolve: "openrouter/google/gemini-3.5-flash"
424
+ openRouterResolve: "openrouter/google/gemini-3.6-flash"
370
425
  },
371
426
  "kimi-k2": {
372
427
  displayName: "Kimi K2",
373
- // opencode Zen serves only up to k2.6; the OpenRouter fallback (used for
374
- // router/oss proxy runs) takes the newer k2.7-code.
375
- resolve: "opencode/kimi-k2.6",
428
+ resolve: "opencode/kimi-k2.7-code",
376
429
  openRouterResolve: "openrouter/moonshotai/kimi-k2.7-code"
377
430
  },
378
- // Zen serves m2.5; the funded OpenRouter path tracks the current m2.7.
431
+ // slug pins the m2 line for DB stability; resolve tracks the current m2.7.
379
432
  "minimax-m2.5": {
380
433
  displayName: "MiniMax M2",
381
- resolve: "opencode/minimax-m2.5",
434
+ resolve: "opencode/minimax-m2.7",
382
435
  openRouterResolve: "openrouter/minimax/minimax-m2.7"
383
436
  },
384
437
  "gpt-5-nano": {
@@ -509,30 +562,30 @@ var providers = {
509
562
  // alias): after the Sol/Terra/Luna rename, ~gpt-mini-latest no longer maps
510
563
  // to Luna, so rolling aliases would silently diverge `gpt`/`gpt-mini` from
511
564
  // the chosen tiers across funding paths.
512
- gpt: {
565
+ "gpt-sol": {
513
566
  displayName: "GPT Sol",
514
567
  resolve: "openrouter/openai/gpt-5.6-sol",
515
568
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
516
569
  openRouterResolve: "openrouter/openai/gpt-5.6-sol",
517
570
  subagentModel: "gpt-terra"
518
571
  },
519
- // see openai/gpt-pro. openrouter serves sol-pro directly on both routes.
520
- "gpt-pro": {
572
+ // see openai/gpt-sol-pro. openrouter serves sol-pro directly on both routes.
573
+ "gpt-sol-pro": {
521
574
  displayName: "GPT Sol Pro",
522
575
  description: "Maximum reasoning effort",
523
576
  resolve: "openrouter/openai/gpt-5.6-sol-pro",
524
577
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
525
578
  openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
526
- subagentModel: "gpt"
579
+ subagentModel: "gpt-sol"
527
580
  },
528
- // gpt-5.6 balanced mid-tier — selectable + `gpt`'s subagent. see openai above.
581
+ // gpt-5.6 balanced mid-tier — selectable + Sol's subagent. see openai above.
529
582
  "gpt-terra": {
530
583
  displayName: "GPT Terra",
531
584
  resolve: "openrouter/openai/gpt-5.6-terra",
532
585
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
533
586
  openRouterResolve: "openrouter/openai/gpt-5.6-terra"
534
587
  },
535
- "gpt-mini": {
588
+ "gpt-luna": {
536
589
  displayName: "GPT Luna",
537
590
  resolve: "openrouter/openai/gpt-5.6-luna",
538
591
  effort: ["none", "low", "medium", "high", "xhigh", "max"],
@@ -543,20 +596,39 @@ var providers = {
543
596
  displayName: "GPT Codex",
544
597
  resolve: "openrouter/openai/gpt-5.3-codex",
545
598
  openRouterResolve: "openrouter/openai/gpt-5.3-codex",
546
- fallback: "openrouter/gpt"
599
+ fallback: "openrouter/gpt-sol"
547
600
  },
548
601
  "gpt-codex-mini": {
549
602
  displayName: "GPT Codex Mini",
550
603
  resolve: "openrouter/openai/gpt-5.1-codex-mini",
551
604
  openRouterResolve: "openrouter/openai/gpt-5.1-codex-mini",
552
- fallback: "openrouter/gpt-mini"
605
+ fallback: "openrouter/gpt-luna"
606
+ },
607
+ // pre-5.6 tier slugs — see openai provider above.
608
+ gpt: {
609
+ displayName: "GPT",
610
+ resolve: "openrouter/openai/gpt-5.6-sol",
611
+ openRouterResolve: "openrouter/openai/gpt-5.6-sol",
612
+ fallback: "openrouter/gpt-sol"
553
613
  },
554
- // dropped hidden subagent tier — folds stored pins forward to gpt (Sol).
614
+ "gpt-pro": {
615
+ displayName: "GPT Pro",
616
+ resolve: "openrouter/openai/gpt-5.6-sol-pro",
617
+ openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
618
+ fallback: "openrouter/gpt-sol-pro"
619
+ },
620
+ "gpt-mini": {
621
+ displayName: "GPT Mini",
622
+ resolve: "openrouter/openai/gpt-5.6-luna",
623
+ openRouterResolve: "openrouter/openai/gpt-5.6-luna",
624
+ fallback: "openrouter/gpt-luna"
625
+ },
626
+ // dropped hidden subagent tier — folds stored pins forward to Sol.
555
627
  "gpt-5.4": {
556
628
  displayName: "GPT 5.4",
557
629
  resolve: "openrouter/openai/gpt-5.4",
558
630
  openRouterResolve: "openrouter/openai/gpt-5.4",
559
- fallback: "openrouter/gpt"
631
+ fallback: "openrouter/gpt-sol"
560
632
  },
561
633
  "o4-mini": {
562
634
  displayName: "O4 Mini",
@@ -579,9 +651,9 @@ var providers = {
579
651
  },
580
652
  grok: {
581
653
  displayName: "Grok",
582
- resolve: "openrouter/x-ai/grok-4.3",
583
- effort: ["none", "low", "medium", "high"],
584
- openRouterResolve: "openrouter/x-ai/grok-4.3"
654
+ resolve: "openrouter/x-ai/grok-4.5",
655
+ effort: ["low", "medium", "high"],
656
+ openRouterResolve: "openrouter/x-ai/grok-4.5"
585
657
  },
586
658
  "deepseek-pro": {
587
659
  displayName: "DeepSeek Pro",
@@ -589,11 +661,13 @@ var providers = {
589
661
  effort: ["high", "xhigh"],
590
662
  openRouterResolve: "openrouter/deepseek/deepseek-v4-pro"
591
663
  },
664
+ // rolling pointer, not the bare id — see `deepseek/deepseek-flash` for why
665
+ // OpenRouter's unversioned `deepseek-v4-flash` is the stale April preview.
592
666
  "deepseek-flash": {
593
667
  displayName: "DeepSeek Flash",
594
- resolve: "openrouter/deepseek/deepseek-v4-flash",
595
- effort: ["high", "xhigh"],
596
- openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
668
+ resolve: "openrouter/~deepseek/deepseek-v4-flash-latest",
669
+ effort: ["low", "high", "max"],
670
+ openRouterResolve: "openrouter/~deepseek/deepseek-v4-flash-latest"
597
671
  },
598
672
  // legacy alias — deepseek retires this on 2026-07-24; transparently
599
673
  // upgrade existing users to the v4 family via the fallback chain.
@@ -688,7 +762,7 @@ var modelAliases = Object.entries(providers).flatMap(
688
762
  var AUTO_EFFICIENT = "auto/efficient";
689
763
  var AUTO_INTELLIGENT = "auto/intelligent";
690
764
  var AUTO_TIER_TARGET = {
691
- [AUTO_EFFICIENT]: "deepseek/deepseek-pro",
765
+ [AUTO_EFFICIENT]: "deepseek/deepseek-flash",
692
766
  [AUTO_INTELLIGENT]: "anthropic/claude-opus"
693
767
  };
694
768
  function isAutoTier(slug) {
@@ -744,6 +818,26 @@ if (!defaultProxyAlias?.openRouterResolve) {
744
818
  }
745
819
  var DEFAULT_PROXY_MODEL = defaultProxyAlias.openRouterResolve;
746
820
  var defaultProxyDisplayName = defaultProxyAlias.displayName;
821
+ var OSS_MODEL_ALLOWLIST = [
822
+ "deepseek/deepseek-flash",
823
+ "deepseek/deepseek-pro",
824
+ "openai/gpt-luna",
825
+ "openrouter/minimax-m2.5",
826
+ "moonshotai/kimi-k2"
827
+ ];
828
+ var OSS_RECOMMENDED_MODEL = AUTO_TIER_TARGET[AUTO_EFFICIENT];
829
+ var ossAllowedTargets = new Set(
830
+ OSS_MODEL_ALLOWLIST.map((slug) => {
831
+ const target = resolveOpenRouterModel(slug);
832
+ if (!target) throw new Error(`OSS_MODEL_ALLOWLIST: ${slug} has no openRouterResolve`);
833
+ return target;
834
+ })
835
+ );
836
+ function isOssAllowedModel(slug) {
837
+ if (!slug) return false;
838
+ const target = resolveOpenRouterModel(slug);
839
+ return target !== void 0 && ossAllowedTargets.has(target);
840
+ }
747
841
  function getAutoSelectHintModel() {
748
842
  return defaultProxyDisplayName;
749
843
  }
@@ -1197,7 +1291,7 @@ function formatModelLabel(params) {
1197
1291
  const ossBase = `\`${displayName}\` (free via [Pullfrog for OSS](https://pullfrog.com/for-oss))`;
1198
1292
  if (params.clamped?.reason !== "oss") return ossBase;
1199
1293
  const configured = isAutoTier(params.clamped.from) ? "the intelligent tier" : `\`${resolveDisplayAlias(params.clamped.from)?.displayName ?? params.clamped.from}\``;
1200
- return `${ossBase} (${configured} not used \u2014 the program covers this model; add its [provider key](https://docs.pullfrog.com/models) to run your pick)`;
1294
+ return `${ossBase} (${configured} not used \u2014 pick one of the [funded models](https://docs.pullfrog.com/models#pullfrog-for-oss) or add a [provider key](https://docs.pullfrog.com/keys) to run your own)`;
1201
1295
  }
1202
1296
  const base = alias?.isFree ? `\`${displayName}\` (free)` : `\`${displayName}\``;
1203
1297
  if (params.fallbackFrom) {
@@ -1597,6 +1691,8 @@ export {
1597
1691
  LEAPING_INTO_ACTION_PREFIX,
1598
1692
  MAX_LEARNINGS_LENGTH,
1599
1693
  OAuthInvalidGrantError,
1694
+ OSS_MODEL_ALLOWLIST,
1695
+ OSS_RECOMMENDED_MODEL,
1600
1696
  PULLFROG_DIVIDER,
1601
1697
  RUN_STATUS_CHECK_NAME,
1602
1698
  TIMEOUT_DISABLED,
@@ -1619,6 +1715,7 @@ export {
1619
1715
  isCardGatedModel,
1620
1716
  isEffortPosition,
1621
1717
  isLeapingIntoActionCommentBody,
1718
+ isOssAllowedModel,
1622
1719
  isPullfrog,
1623
1720
  isValidTimeString,
1624
1721
  modelAliases,
@@ -1,12 +1,12 @@
1
1
  import type { ToolContext } from "./server.ts";
2
2
  export declare const ShellParams: import("arktype/internal/variants/object.ts").ObjectType<{
3
3
  command: string;
4
- description: string;
4
+ description?: string;
5
5
  timeout?: number;
6
6
  working_directory?: string;
7
7
  background?: boolean;
8
8
  }, {}>;
9
- export type SandboxMethod = "unshare" | "sudo-unshare" | "none";
9
+ export type SandboxMethod = "unshare" | "sudo-unshare" | "userns-unshare" | "none";
10
10
  /** get the current sandbox method (for testing/diagnostics) */
11
11
  export declare function getSandboxMethod(): SandboxMethod;
12
12
  /** chars of shell output kept inline in the agent reply. anything past this
@@ -16,13 +16,13 @@ export declare function getSandboxMethod(): SandboxMethod;
16
16
  export declare const MAX_OUTPUT_CHARS = 5000;
17
17
  export declare function ShellTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
18
18
  command: string;
19
- description: string;
19
+ description?: string;
20
20
  timeout?: number;
21
21
  working_directory?: string;
22
22
  background?: boolean;
23
23
  }, {
24
24
  command: string;
25
- description: string;
25
+ description?: string;
26
26
  timeout?: number;
27
27
  working_directory?: string;
28
28
  background?: boolean;
package/dist/models.d.ts CHANGED
@@ -145,11 +145,11 @@ export declare const modelAliases: ModelAlias[];
145
145
  * concrete alias by `resolveDisplayAlias` below, so every downstream consumer
146
146
  * (CLI resolve, OpenRouter resolve, footer label) handles them transparently.
147
147
  *
148
- * `efficient` mirrors the OSS/default subsidy model (DeepSeek V4 Pro beats
149
- * Kimi K2.7 on agentic-review quality at ~4-5x lower cost, run at whatever
150
- * effort the repo asks for, clamped to its published ladder); `intelligent` is the
151
- * frontier pick (Claude Opus). a `null` model means the tier hasn't been
152
- * pinned: callers default by card status via `defaultAutoTier`.
148
+ * `efficient` mirrors the OSS/default subsidy model (DeepSeek Flashthe 0731
149
+ * release is DeepSeek's first officially-shipped V4, where Pro is still the
150
+ * April preview, and it costs ~0.45x Pro on our cache-heavy review workload);
151
+ * `intelligent` is the frontier pick (Claude Opus). a `null` model means the
152
+ * tier hasn't been pinned: callers default by card status via `defaultAutoTier`.
153
153
  */
154
154
  export declare const AUTO_EFFICIENT = "auto/efficient";
155
155
  export declare const AUTO_INTELLIGENT = "auto/intelligent";
@@ -235,6 +235,30 @@ export declare function resolveModelRung(params: {
235
235
  useOpenRouter: boolean;
236
236
  }): string | undefined;
237
237
  export declare const DEFAULT_PROXY_MODEL: string;
238
+ /**
239
+ * the models Pullfrog is willing to fund on the OSS program. an accepted OSS
240
+ * repo may pick any of these and run-context honors the pick; anything else
241
+ * falls back to `DEFAULT_PROXY_MODEL`, so a subsidized run can never land on a
242
+ * frontier model.
243
+ *
244
+ * membership is a spend decision, so it lives here as a literal rather than a
245
+ * DB toggle — changing it is a deploy, which is the right friction. costs below
246
+ * are modelled on the measured OSS token mix, where cache reads are ~87.5% of
247
+ * input and list price therefore ranks models WRONG: Luna 0.39x, Flash 0.45x,
248
+ * Pro 1.00x, MiniMax M2 1.30x, Kimi 3.88x modelled — but 7.25x as actually
249
+ * measured over the pre-#1063 Kimi era, which is the number to trust.
250
+ */
251
+ export declare const OSS_MODEL_ALLOWLIST: readonly string[];
252
+ /** the pick the console badges. DERIVED from the efficient tier rather than
253
+ * restated, so the badge cannot drift from the model that actually runs — a
254
+ * second literal here would be an invariant nothing enforces. */
255
+ export declare const OSS_RECOMMENDED_MODEL: string;
256
+ /**
257
+ * whether an OSS repo's stored pick is one the program funds. resolves through
258
+ * the fallback chain first, so `auto/*` sentinels and deprecated slugs are
259
+ * judged by the model that actually runs.
260
+ */
261
+ export declare function isOssAllowedModel(slug: string | null | undefined): slug is string;
238
262
  /** short label for the model auto-select picks today (console hint copy). */
239
263
  export declare function getAutoSelectHintModel(): string;
240
264
  /** env var that supplies the Bedrock model ID for the `bedrock/byok` slug. */
@@ -53,15 +53,19 @@ export declare function validateAgentApiKey(params: {
53
53
  */
54
54
  export declare function isApiKeyAuthError(text: string): boolean;
55
55
  /**
56
- * Expired OAuth-connection credential shapes (#931) — the fix is to
57
- * re-authenticate the provider connection (`pullfrog auth <provider>`), not
58
- * to rotate a repo-secret API key, so `formatApiKeyErrorSummary` renders
59
- * distinct copy for these. Patterns are deliberately narrow:
60
- * "authentication token has expired" (not bare "token has expired") so a
61
- * GitHub installation-token expiry can't be misread as an LLM key problem.
62
- * also covers server-side revocation ("authentication token has been
63
- * invalidated", OpenAI `token_invalidated`, #1041) and the Claude CLI's
64
- * "OAuth access token has expired" phrasing (#1072) same remediation.
56
+ * Dead OAuth-connection credential — the provider is telling us the token
57
+ * itself is finished (expired, invalidated, revoked, or unrecognised), and the
58
+ * only fix is to re-authenticate the connection (`pullfrog auth <provider>`),
59
+ * never to rotate a repo-secret API key. `formatApiKeyErrorSummary` renders
60
+ * distinct copy for the whole class.
61
+ *
62
+ * Match the SHAPE, not the sentence. Four prior issues (#931, #1041, #1072,
63
+ * #1122) each landed one more literal and the next provider rewording walked
64
+ * straight through, so these patterns are parameterised over the two things
65
+ * that vary — which token noun the provider uses, and which terminal state it
66
+ * reports. Still deliberately narrow on the noun ("authentication token" /
67
+ * "OAuth access token", never bare "token") so a GitHub installation-token
68
+ * expiry can't be misread as an LLM credential problem.
65
69
  */
66
70
  export declare function isOAuthCredentialExpiredError(text: string): boolean;
67
71
  /**
@@ -70,6 +74,7 @@ export declare function isOAuthCredentialExpiredError(text: string): boolean;
70
74
  * user controls fixes it, so it gets its own copy instead of the re-auth CTA.
71
75
  */
72
76
  export declare function isClaudeSubscriptionDisabledError(text: string): boolean;
77
+ export declare function isClaudeSessionLimitError(text: string): boolean;
73
78
  /**
74
79
  * Friendly Markdown summary for both the missing-key and invalid-key cases.
75
80
  * Used in the catch / result-failure paths in `main.ts` to overwrite the raw
@@ -17,7 +17,20 @@ type SafeGitSubcommand = "fetch" | "push";
17
17
  type GitAuthOptions = {
18
18
  token: string;
19
19
  cwd?: string;
20
+ /**
21
+ * re-mint the git token when GitHub hands out one its git edge never accepts.
22
+ * when present, an auth-class failure is retried ONCE with a fresh token.
23
+ */
24
+ refreshGitToken?: ((stale: string) => Promise<string>) | undefined;
20
25
  };
26
+ /**
27
+ * installation-token 401s on git. GitHub intermittently mints a token its git
28
+ * edge never accepts, so retrying the SAME token never recovers — only a
29
+ * re-mint does. lives here rather than next to `classifyPushError` in
30
+ * `mcp/git.ts` because the fetch path needs it too and `git.ts` imports this
31
+ * module, not the other way round. see #1115.
32
+ */
33
+ export declare const TRANSIENT_AUTH_PATTERNS: RegExp[];
21
34
  type GitResult = {
22
35
  stdout: string;
23
36
  stderr: string;
@@ -34,8 +34,10 @@ export type ModelAccessDecision = {
34
34
  * decide whether an (already-resolved) requested model can run, and how.
35
35
  *
36
36
  * - non-explicit / no model → `ok` (caller's missing-key validation applies).
37
- * - proxy active + OSS → only the funded subsidy target routes; a different
38
- * model needs the repo's own key (`byok`) else `error("oss")`.
37
+ * - proxy active + OSS → the funded subsidy target and anything else on
38
+ * `OSS_MODEL_ALLOWLIST` route; a model off the list needs the repo's own key
39
+ * (`byok`) else `error("oss")`. the allowlist arm is what keeps
40
+ * `--model=<allowlisted>` from hard-failing on a pick the console offers.
39
41
  * - proxy active + Router → honor any Router-servable model (`proxy`); fall to
40
42
  * BYOK when locally authorized, else `error("router")`.
41
43
  * - no proxy → the resolved model must be locally authorized, else
@@ -47,3 +47,25 @@ export interface EnsurePackageManagerParams {
47
47
  * still works; we just don't get our version guarantee.
48
48
  */
49
49
  export declare function ensurePackageManager(params: EnsurePackageManagerParams): Promise<boolean>;
50
+ /** `SupportedPackageManager` plus deno, which corepack never manages. */
51
+ export type ProvisionablePackageManager = SupportedPackageManager | "deno";
52
+ /**
53
+ * Put the project's package manager on PATH, by whichever route provisions it —
54
+ * corepack for pnpm/yarn, `npm i -g` for bun, the install script for deno.
55
+ * Returns an error string on failure, else null.
56
+ *
57
+ * Callers must gate this on shell being enabled; provisioning executes code.
58
+ *
59
+ * Idempotent by construction (`isCommandAvailable` short-circuits and
60
+ * `ensurePackageManager` caches on a `--version` match), which is what lets
61
+ * `main.ts` call it BEFORE the `setup` lifecycle hook and the prep phase call it
62
+ * again later for the cost of one `which`. That ordering is the point: a `setup`
63
+ * hook running `bun install` used to die with `bun: command not found` 0.8s
64
+ * before Pullfrog installed bun itself, because the pre-hook site only ever
65
+ * asked corepack — which ignores bun and deno entirely. See #1121.
66
+ */
67
+ export declare function provisionPackageManager(params: {
68
+ name: ProvisionablePackageManager;
69
+ declared: PackageManagerSpec | null;
70
+ binDir: string;
71
+ }): Promise<string | null>;