pullfrog 0.1.47 → 0.1.49
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/agents/opencodePlugin.d.ts +2 -2
- package/dist/agents/opencodeShared.d.ts +0 -28
- package/dist/cli.mjs +378 -159
- package/dist/effort.d.ts +80 -0
- package/dist/external.d.ts +6 -1
- package/dist/index.js +377 -158
- package/dist/internal/index.d.ts +3 -2
- package/dist/internal.js +138 -1
- package/dist/models.d.ts +36 -2
- package/dist/utils/billingErrors.d.ts +27 -10
- package/dist/utils/payload.d.ts +4 -1
- package/dist/utils/runContext.d.ts +14 -3
- package/dist/utils/runContextData.d.ts +2 -1
- package/dist/utils/runEffort.d.ts +27 -0
- package/dist/utils/runStartupLog.d.ts +3 -3
- package/package.json +1 -1
- /package/dist/agents/{opencode_v2.d.ts → opencode.d.ts} +0 -0
package/dist/internal/index.d.ts
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Internal entrypoint for the root app.
|
|
3
3
|
* Re-exports shared types, values, and utilities needed by the Next.js app.
|
|
4
4
|
*/
|
|
5
|
-
export type { AuthorPermission, AutoTier, ModelAlias, ModelProvider, Payload, PayloadEvent, ProviderConfig, PushPermission, ShellPermission, ToolPermission, WriteablePayload, XrepoConfig, } from "../external.ts";
|
|
6
|
-
export { AUTO_EFFICIENT, AUTO_INTELLIGENT, DEFAULT_PROXY_MODEL, defaultAutoTier, getAutoSelectHintModel, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoTier, isCardGatedModel, modelAliases, parseModel, providers, pullfrogMcpName, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelSlug, resolveOpenRouterModel, } from "../external.ts";
|
|
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, 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
|
+
export { commercialPaywallBody } from "../utils/billingErrors.ts";
|
|
9
10
|
export type { BuildPullfrogFooterParams, WorkflowRunFooterInfo, } from "../utils/buildPullfrogFooter.ts";
|
|
10
11
|
export { buildPullfrogFooter, PULLFROG_DIVIDER, stripExistingFooter, } from "../utils/buildPullfrogFooter.ts";
|
|
11
12
|
export type { CodexAuthBody } from "../utils/codexOAuth.ts";
|
package/dist/internal.js
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from 'module'; import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __dirnameFn } from 'path'; const require = __createRequire(import.meta.url); const __filename = __fileURLToPath(import.meta.url); const __dirname = __dirnameFn(__filename);
|
|
2
2
|
|
|
3
|
+
// effort.ts
|
|
4
|
+
var DEFAULT_EFFORT_POSITION = 0.5;
|
|
5
|
+
var EFFORT_ALIASES = {
|
|
6
|
+
low: 0,
|
|
7
|
+
medium: 0.25,
|
|
8
|
+
high: 0.5,
|
|
9
|
+
xhigh: 0.75,
|
|
10
|
+
max: 1
|
|
11
|
+
};
|
|
12
|
+
var DISABLING_RUNGS = ["none", "minimal"];
|
|
13
|
+
function isEffortPosition(value) {
|
|
14
|
+
return Number.isFinite(value) && value >= 0 && value <= 1;
|
|
15
|
+
}
|
|
16
|
+
function parseEffortPosition(raw) {
|
|
17
|
+
const normalized = raw.trim().toLowerCase();
|
|
18
|
+
const named = EFFORT_ALIASES[normalized === "med" ? "medium" : normalized];
|
|
19
|
+
if (named !== void 0) return named;
|
|
20
|
+
const numeric = Number(normalized);
|
|
21
|
+
return normalized !== "" && isEffortPosition(numeric) ? numeric : void 0;
|
|
22
|
+
}
|
|
23
|
+
function offeredRungs(published) {
|
|
24
|
+
return published.filter((rung) => !DISABLING_RUNGS.includes(rung));
|
|
25
|
+
}
|
|
26
|
+
function resolveRung(params) {
|
|
27
|
+
const rungs = offeredRungs(params.published);
|
|
28
|
+
if (rungs.length === 0) return void 0;
|
|
29
|
+
const clamped = Math.min(1, Math.max(0, params.position));
|
|
30
|
+
return rungs[Math.floor(clamped * (rungs.length - 1))];
|
|
31
|
+
}
|
|
32
|
+
function rungPosition(params) {
|
|
33
|
+
const rungs = offeredRungs(params.published);
|
|
34
|
+
const index = rungs.indexOf(params.rung);
|
|
35
|
+
if (index === -1) return void 0;
|
|
36
|
+
return rungs.length > 1 ? index / (rungs.length - 1) : 0;
|
|
37
|
+
}
|
|
38
|
+
function rungLabel(rung) {
|
|
39
|
+
const known = {
|
|
40
|
+
none: "None",
|
|
41
|
+
minimal: "Minimal",
|
|
42
|
+
low: "Low",
|
|
43
|
+
medium: "Medium",
|
|
44
|
+
high: "High",
|
|
45
|
+
xhigh: "Extra high",
|
|
46
|
+
max: "Max"
|
|
47
|
+
};
|
|
48
|
+
return known[rung] ?? rung.charAt(0).toUpperCase() + rung.slice(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
3
51
|
// models.ts
|
|
4
52
|
function provider(config) {
|
|
5
53
|
return config;
|
|
@@ -19,6 +67,7 @@ var providers = {
|
|
|
19
67
|
"claude-fable": {
|
|
20
68
|
displayName: "Claude Fable",
|
|
21
69
|
resolve: "anthropic/claude-fable-5",
|
|
70
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
22
71
|
// rolling alias: models.dev's OpenRouter mirror lags brand-new pinned
|
|
23
72
|
// versions (claude-fable-5 isn't indexed yet), so track ~…-latest to
|
|
24
73
|
// stay catalog-valid and auto-follow version bumps.
|
|
@@ -28,6 +77,7 @@ var providers = {
|
|
|
28
77
|
"claude-opus": {
|
|
29
78
|
displayName: "Claude Opus",
|
|
30
79
|
resolve: "anthropic/claude-opus-5",
|
|
80
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
31
81
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
32
82
|
preferred: true,
|
|
33
83
|
subagentModel: "claude-sonnet"
|
|
@@ -35,6 +85,7 @@ var providers = {
|
|
|
35
85
|
"claude-sonnet": {
|
|
36
86
|
displayName: "Claude Sonnet",
|
|
37
87
|
resolve: "anthropic/claude-sonnet-5",
|
|
88
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
38
89
|
openRouterResolve: "openrouter/anthropic/claude-sonnet-5"
|
|
39
90
|
},
|
|
40
91
|
"claude-haiku": {
|
|
@@ -52,6 +103,7 @@ var providers = {
|
|
|
52
103
|
gpt: {
|
|
53
104
|
displayName: "GPT Sol",
|
|
54
105
|
resolve: "openai/gpt-5.6-sol",
|
|
106
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
55
107
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
56
108
|
preferred: true,
|
|
57
109
|
subagentModel: "gpt-terra"
|
|
@@ -63,6 +115,7 @@ var providers = {
|
|
|
63
115
|
displayName: "GPT Sol Pro",
|
|
64
116
|
description: "Maximum reasoning effort",
|
|
65
117
|
resolve: "openai/gpt-5.6-sol",
|
|
118
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
66
119
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
67
120
|
subagentModel: "gpt"
|
|
68
121
|
},
|
|
@@ -72,11 +125,13 @@ var providers = {
|
|
|
72
125
|
"gpt-terra": {
|
|
73
126
|
displayName: "GPT Terra",
|
|
74
127
|
resolve: "openai/gpt-5.6-terra",
|
|
128
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
75
129
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
76
130
|
},
|
|
77
131
|
"gpt-mini": {
|
|
78
132
|
displayName: "GPT Luna",
|
|
79
133
|
resolve: "openai/gpt-5.6-luna",
|
|
134
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
80
135
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
81
136
|
},
|
|
82
137
|
// legacy aliases — openai unified the codex line into the main GPT family
|
|
@@ -106,6 +161,7 @@ var providers = {
|
|
|
106
161
|
o3: {
|
|
107
162
|
displayName: "O3",
|
|
108
163
|
resolve: "openai/o3",
|
|
164
|
+
effort: ["low", "medium", "high"],
|
|
109
165
|
openRouterResolve: "openrouter/openai/o3"
|
|
110
166
|
}
|
|
111
167
|
}
|
|
@@ -117,6 +173,7 @@ var providers = {
|
|
|
117
173
|
"gemini-pro": {
|
|
118
174
|
displayName: "Gemini Pro",
|
|
119
175
|
resolve: "google/gemini-3.1-pro-preview",
|
|
176
|
+
effort: ["low", "medium", "high"],
|
|
120
177
|
openRouterResolve: "openrouter/google/gemini-3.1-pro-preview",
|
|
121
178
|
preferred: true
|
|
122
179
|
// Inherit (subagents stay on Pro). Google has no in-between tier;
|
|
@@ -128,6 +185,7 @@ var providers = {
|
|
|
128
185
|
"gemini-flash": {
|
|
129
186
|
displayName: "Gemini Flash",
|
|
130
187
|
resolve: "google/gemini-3.5-flash",
|
|
188
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
131
189
|
openRouterResolve: "openrouter/google/gemini-3.5-flash"
|
|
132
190
|
}
|
|
133
191
|
}
|
|
@@ -139,6 +197,7 @@ var providers = {
|
|
|
139
197
|
grok: {
|
|
140
198
|
displayName: "Grok",
|
|
141
199
|
resolve: "xai/grok-4.3",
|
|
200
|
+
effort: ["none", "low", "medium", "high"],
|
|
142
201
|
openRouterResolve: "openrouter/x-ai/grok-4.3",
|
|
143
202
|
preferred: true
|
|
144
203
|
},
|
|
@@ -168,12 +227,16 @@ var providers = {
|
|
|
168
227
|
"deepseek-pro": {
|
|
169
228
|
displayName: "DeepSeek Pro",
|
|
170
229
|
resolve: "deepseek/deepseek-v4-pro",
|
|
230
|
+
effort: ["high", "max"],
|
|
231
|
+
openRouterEffort: ["high", "xhigh"],
|
|
171
232
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro",
|
|
172
233
|
preferred: true
|
|
173
234
|
},
|
|
174
235
|
"deepseek-flash": {
|
|
175
236
|
displayName: "DeepSeek Flash",
|
|
176
237
|
resolve: "deepseek/deepseek-v4-flash",
|
|
238
|
+
effort: ["high", "max"],
|
|
239
|
+
openRouterEffort: ["high", "xhigh"],
|
|
177
240
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
|
|
178
241
|
},
|
|
179
242
|
// legacy aliases — deepseek retires these on 2026-07-24; transparently
|
|
@@ -202,6 +265,7 @@ var providers = {
|
|
|
202
265
|
"kimi-k3": {
|
|
203
266
|
displayName: "Kimi K3",
|
|
204
267
|
resolve: "moonshotai/kimi-k3",
|
|
268
|
+
effort: ["low", "high", "max"],
|
|
205
269
|
openRouterResolve: "openrouter/moonshotai/kimi-k3",
|
|
206
270
|
preferred: true,
|
|
207
271
|
subagentModel: "kimi-k2"
|
|
@@ -214,7 +278,7 @@ var providers = {
|
|
|
214
278
|
}
|
|
215
279
|
}),
|
|
216
280
|
opencode: provider({
|
|
217
|
-
displayName: "OpenCode",
|
|
281
|
+
displayName: "OpenCode Zen",
|
|
218
282
|
envVars: ["OPENCODE_API_KEY"],
|
|
219
283
|
models: {
|
|
220
284
|
"big-pickle": {
|
|
@@ -227,12 +291,14 @@ var providers = {
|
|
|
227
291
|
"claude-opus": {
|
|
228
292
|
displayName: "Claude Opus",
|
|
229
293
|
resolve: "opencode/claude-opus-5",
|
|
294
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
230
295
|
openRouterResolve: "openrouter/anthropic/claude-opus-5",
|
|
231
296
|
subagentModel: "claude-sonnet"
|
|
232
297
|
},
|
|
233
298
|
"claude-sonnet": {
|
|
234
299
|
displayName: "Claude Sonnet",
|
|
235
300
|
resolve: "opencode/claude-sonnet-5",
|
|
301
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
236
302
|
openRouterResolve: "openrouter/anthropic/claude-sonnet-5"
|
|
237
303
|
},
|
|
238
304
|
"claude-haiku": {
|
|
@@ -243,6 +309,7 @@ var providers = {
|
|
|
243
309
|
gpt: {
|
|
244
310
|
displayName: "GPT Sol",
|
|
245
311
|
resolve: "opencode/gpt-5.6-sol",
|
|
312
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
246
313
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
247
314
|
subagentModel: "gpt-terra"
|
|
248
315
|
},
|
|
@@ -251,6 +318,7 @@ var providers = {
|
|
|
251
318
|
displayName: "GPT Sol Pro",
|
|
252
319
|
description: "Maximum reasoning effort",
|
|
253
320
|
resolve: "opencode/gpt-5.6-sol",
|
|
321
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
254
322
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
255
323
|
subagentModel: "gpt"
|
|
256
324
|
},
|
|
@@ -258,11 +326,13 @@ var providers = {
|
|
|
258
326
|
"gpt-terra": {
|
|
259
327
|
displayName: "GPT Terra",
|
|
260
328
|
resolve: "opencode/gpt-5.6-terra",
|
|
329
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
261
330
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
262
331
|
},
|
|
263
332
|
"gpt-mini": {
|
|
264
333
|
displayName: "GPT Luna",
|
|
265
334
|
resolve: "opencode/gpt-5.6-luna",
|
|
335
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
266
336
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
267
337
|
},
|
|
268
338
|
// legacy aliases — see openai provider above for context.
|
|
@@ -288,12 +358,14 @@ var providers = {
|
|
|
288
358
|
"gemini-pro": {
|
|
289
359
|
displayName: "Gemini Pro",
|
|
290
360
|
resolve: "opencode/gemini-3.1-pro",
|
|
361
|
+
effort: ["low", "medium", "high"],
|
|
291
362
|
openRouterResolve: "openrouter/google/gemini-3.1-pro-preview"
|
|
292
363
|
// Inherit — see google/gemini-pro for rationale.
|
|
293
364
|
},
|
|
294
365
|
"gemini-flash": {
|
|
295
366
|
displayName: "Gemini Flash",
|
|
296
367
|
resolve: "opencode/gemini-3.5-flash",
|
|
368
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
297
369
|
openRouterResolve: "openrouter/google/gemini-3.5-flash"
|
|
298
370
|
},
|
|
299
371
|
"kimi-k2": {
|
|
@@ -312,6 +384,7 @@ var providers = {
|
|
|
312
384
|
"gpt-5-nano": {
|
|
313
385
|
displayName: "GPT Nano",
|
|
314
386
|
resolve: "opencode/gpt-5-nano",
|
|
387
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
315
388
|
openRouterResolve: "openrouter/openai/gpt-5-nano"
|
|
316
389
|
},
|
|
317
390
|
"mimo-v2-pro-free": {
|
|
@@ -338,6 +411,8 @@ var providers = {
|
|
|
338
411
|
"glm-5.1": {
|
|
339
412
|
displayName: "GLM 5.2",
|
|
340
413
|
resolve: "opencode-go/glm-5.2",
|
|
414
|
+
effort: ["high", "max"],
|
|
415
|
+
openRouterEffort: ["high", "xhigh"],
|
|
341
416
|
openRouterResolve: "openrouter/z-ai/glm-5.2",
|
|
342
417
|
preferred: true
|
|
343
418
|
},
|
|
@@ -391,6 +466,10 @@ var providers = {
|
|
|
391
466
|
// bring-your-own generic OpenAI-compatible endpoint — Cloudflare AI Gateway,
|
|
392
467
|
// Alibaba DashScope, self-hosted vLLM, or any compatible gateway. base URL +
|
|
393
468
|
// key + model ID are all supplied via env; nothing is cataloged or bumped.
|
|
469
|
+
// the two token limits are deliberately absent: this list is the auth
|
|
470
|
+
// heuristic (`hasPullfrogStoredAuthForModel`, `validateAgentApiKey`), and a
|
|
471
|
+
// stored context number is config, not proof of a key. the console picks
|
|
472
|
+
// them up from `PROVIDER_EXTRA_SECRET_NAMES` instead.
|
|
394
473
|
envVars: ["OPENAI_COMPATIBLE_BASE_URL", "OPENAI_COMPATIBLE_API_KEY", "OPENAI_COMPATIBLE_MODEL"],
|
|
395
474
|
models: {
|
|
396
475
|
// single routing entry — the actual model ID is read from
|
|
@@ -410,6 +489,7 @@ var providers = {
|
|
|
410
489
|
"claude-opus": {
|
|
411
490
|
displayName: "Claude Opus",
|
|
412
491
|
resolve: "openrouter/~anthropic/claude-opus-latest",
|
|
492
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
413
493
|
openRouterResolve: "openrouter/~anthropic/claude-opus-latest",
|
|
414
494
|
preferred: true,
|
|
415
495
|
subagentModel: "claude-sonnet"
|
|
@@ -417,6 +497,7 @@ var providers = {
|
|
|
417
497
|
"claude-sonnet": {
|
|
418
498
|
displayName: "Claude Sonnet",
|
|
419
499
|
resolve: "openrouter/~anthropic/claude-sonnet-latest",
|
|
500
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
420
501
|
openRouterResolve: "openrouter/~anthropic/claude-sonnet-latest"
|
|
421
502
|
},
|
|
422
503
|
"claude-haiku": {
|
|
@@ -431,6 +512,7 @@ var providers = {
|
|
|
431
512
|
gpt: {
|
|
432
513
|
displayName: "GPT Sol",
|
|
433
514
|
resolve: "openrouter/openai/gpt-5.6-sol",
|
|
515
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
434
516
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol",
|
|
435
517
|
subagentModel: "gpt-terra"
|
|
436
518
|
},
|
|
@@ -439,6 +521,7 @@ var providers = {
|
|
|
439
521
|
displayName: "GPT Sol Pro",
|
|
440
522
|
description: "Maximum reasoning effort",
|
|
441
523
|
resolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
524
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
442
525
|
openRouterResolve: "openrouter/openai/gpt-5.6-sol-pro",
|
|
443
526
|
subagentModel: "gpt"
|
|
444
527
|
},
|
|
@@ -446,11 +529,13 @@ var providers = {
|
|
|
446
529
|
"gpt-terra": {
|
|
447
530
|
displayName: "GPT Terra",
|
|
448
531
|
resolve: "openrouter/openai/gpt-5.6-terra",
|
|
532
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
449
533
|
openRouterResolve: "openrouter/openai/gpt-5.6-terra"
|
|
450
534
|
},
|
|
451
535
|
"gpt-mini": {
|
|
452
536
|
displayName: "GPT Luna",
|
|
453
537
|
resolve: "openrouter/openai/gpt-5.6-luna",
|
|
538
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
454
539
|
openRouterResolve: "openrouter/openai/gpt-5.6-luna"
|
|
455
540
|
},
|
|
456
541
|
// legacy aliases — see openai provider for context.
|
|
@@ -476,32 +561,38 @@ var providers = {
|
|
|
476
561
|
"o4-mini": {
|
|
477
562
|
displayName: "O4 Mini",
|
|
478
563
|
resolve: "openrouter/openai/o4-mini",
|
|
564
|
+
effort: ["low", "medium", "high"],
|
|
479
565
|
openRouterResolve: "openrouter/openai/o4-mini"
|
|
480
566
|
},
|
|
481
567
|
"gemini-pro": {
|
|
482
568
|
displayName: "Gemini Pro",
|
|
483
569
|
resolve: "openrouter/~google/gemini-pro-latest",
|
|
570
|
+
effort: ["low", "medium", "high"],
|
|
484
571
|
openRouterResolve: "openrouter/~google/gemini-pro-latest"
|
|
485
572
|
// Inherit — see google/gemini-pro for rationale.
|
|
486
573
|
},
|
|
487
574
|
"gemini-flash": {
|
|
488
575
|
displayName: "Gemini Flash",
|
|
489
576
|
resolve: "openrouter/~google/gemini-flash-latest",
|
|
577
|
+
effort: ["minimal", "low", "medium", "high"],
|
|
490
578
|
openRouterResolve: "openrouter/~google/gemini-flash-latest"
|
|
491
579
|
},
|
|
492
580
|
grok: {
|
|
493
581
|
displayName: "Grok",
|
|
494
582
|
resolve: "openrouter/x-ai/grok-4.3",
|
|
583
|
+
effort: ["none", "low", "medium", "high"],
|
|
495
584
|
openRouterResolve: "openrouter/x-ai/grok-4.3"
|
|
496
585
|
},
|
|
497
586
|
"deepseek-pro": {
|
|
498
587
|
displayName: "DeepSeek Pro",
|
|
499
588
|
resolve: "openrouter/deepseek/deepseek-v4-pro",
|
|
589
|
+
effort: ["high", "xhigh"],
|
|
500
590
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-pro"
|
|
501
591
|
},
|
|
502
592
|
"deepseek-flash": {
|
|
503
593
|
displayName: "DeepSeek Flash",
|
|
504
594
|
resolve: "openrouter/deepseek/deepseek-v4-flash",
|
|
595
|
+
effort: ["high", "xhigh"],
|
|
505
596
|
openRouterResolve: "openrouter/deepseek/deepseek-v4-flash"
|
|
506
597
|
},
|
|
507
598
|
// legacy alias — deepseek retires this on 2026-07-24; transparently
|
|
@@ -520,6 +611,7 @@ var providers = {
|
|
|
520
611
|
"kimi-k3": {
|
|
521
612
|
displayName: "Kimi K3",
|
|
522
613
|
resolve: "openrouter/moonshotai/kimi-k3",
|
|
614
|
+
effort: ["low", "high", "max"],
|
|
523
615
|
openRouterResolve: "openrouter/moonshotai/kimi-k3"
|
|
524
616
|
},
|
|
525
617
|
// slug pins the m2 line for DB stability; resolve tracks the current m2.7.
|
|
@@ -583,6 +675,8 @@ var modelAliases = Object.entries(providers).flatMap(
|
|
|
583
675
|
// here to a fully-qualified slug so callers can look up the target alias
|
|
584
676
|
// directly without re-deriving the provider.
|
|
585
677
|
subagentModel: def.subagentModel ? `${providerKey}/${def.subagentModel}` : void 0,
|
|
678
|
+
effort: def.effort,
|
|
679
|
+
openRouterEffort: def.openRouterEffort,
|
|
586
680
|
hidden: def.hidden ?? false
|
|
587
681
|
}))
|
|
588
682
|
);
|
|
@@ -628,6 +722,17 @@ function resolveCliModel(slug) {
|
|
|
628
722
|
function resolveOpenRouterModel(slug) {
|
|
629
723
|
return resolveDisplayAlias(slug)?.openRouterResolve;
|
|
630
724
|
}
|
|
725
|
+
function getModelEffortLevels(params) {
|
|
726
|
+
const alias = resolveDisplayAlias(params.slug);
|
|
727
|
+
if (!alias) return void 0;
|
|
728
|
+
if (params.useOpenRouter) return alias.openRouterEffort ?? alias.effort;
|
|
729
|
+
return alias.effort;
|
|
730
|
+
}
|
|
731
|
+
function resolveModelRung(params) {
|
|
732
|
+
const published = getModelEffortLevels(params);
|
|
733
|
+
if (!published) return void 0;
|
|
734
|
+
return resolveRung({ position: params.position, published });
|
|
735
|
+
}
|
|
631
736
|
var defaultProxyAlias = resolveDisplayAlias(AUTO_EFFICIENT);
|
|
632
737
|
if (!defaultProxyAlias?.openRouterResolve) {
|
|
633
738
|
throw new Error(`DEFAULT_PROXY_MODEL: ${AUTO_EFFICIENT} has no openRouterResolve`);
|
|
@@ -1043,6 +1148,27 @@ ${PR_SUMMARY_FORMAT}`
|
|
|
1043
1148
|
}
|
|
1044
1149
|
var modes = computeModes("opencode");
|
|
1045
1150
|
|
|
1151
|
+
// utils/billingErrors.ts
|
|
1152
|
+
function commercialPaywallBody(params) {
|
|
1153
|
+
if (params.reason === "commercial") {
|
|
1154
|
+
return [
|
|
1155
|
+
`**Pullfrog needs a confirmed Pro plan for ${params.ownerLogin}, so this run paused.**`,
|
|
1156
|
+
"",
|
|
1157
|
+
"Open Plan and payment to confirm Pro or review the organization's billing status.",
|
|
1158
|
+
"",
|
|
1159
|
+
`[Review plan and payment \u2192](${params.url})`
|
|
1160
|
+
].join("\n");
|
|
1161
|
+
}
|
|
1162
|
+
params.reason;
|
|
1163
|
+
return [
|
|
1164
|
+
`**Pullfrog paused runs on ${params.ownerLogin}: the Pro renewal failed.**`,
|
|
1165
|
+
"",
|
|
1166
|
+
"Update the card on file to resume runs.",
|
|
1167
|
+
"",
|
|
1168
|
+
`[Update billing \u2192](${params.url})`
|
|
1169
|
+
].join("\n");
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1046
1172
|
// utils/buildPullfrogFooter.ts
|
|
1047
1173
|
var PULLFROG_DIVIDER = "<!-- PULLFROG_DIVIDER_DO_NOT_REMOVE_PLZ -->";
|
|
1048
1174
|
var FROG_LOGO = `<a href="https://pullfrog.com"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pullfrog.com/logos/frog-white-full-18px.png"><img src="https://pullfrog.com/logos/frog-green-full-18px.png" width="9px" height="9px" style="vertical-align: middle; " alt="Pullfrog"></picture></a>`;
|
|
@@ -1454,7 +1580,9 @@ export {
|
|
|
1454
1580
|
APPROVAL_CHECK_NAME,
|
|
1455
1581
|
AUTO_EFFICIENT,
|
|
1456
1582
|
AUTO_INTELLIGENT,
|
|
1583
|
+
DEFAULT_EFFORT_POSITION,
|
|
1457
1584
|
DEFAULT_PROXY_MODEL,
|
|
1585
|
+
EFFORT_ALIASES,
|
|
1458
1586
|
LEAPING_INTO_ACTION_PREFIX,
|
|
1459
1587
|
MAX_LEARNINGS_LENGTH,
|
|
1460
1588
|
OAuthInvalidGrantError,
|
|
@@ -1462,6 +1590,7 @@ export {
|
|
|
1462
1590
|
RUN_STATUS_CHECK_NAME,
|
|
1463
1591
|
TIMEOUT_DISABLED,
|
|
1464
1592
|
buildPullfrogFooter,
|
|
1593
|
+
commercialPaywallBody,
|
|
1465
1594
|
createLeapingProgressComment,
|
|
1466
1595
|
createRunStatusCheck,
|
|
1467
1596
|
decodeJwtExpMs,
|
|
@@ -1469,6 +1598,7 @@ export {
|
|
|
1469
1598
|
deleteProgressCommentApi,
|
|
1470
1599
|
finalizeRunStatusCheck,
|
|
1471
1600
|
getAutoSelectHintModel,
|
|
1601
|
+
getModelEffortLevels,
|
|
1472
1602
|
getModelEnvVars,
|
|
1473
1603
|
getModelManagedCredentials,
|
|
1474
1604
|
getModelProvider,
|
|
@@ -1476,11 +1606,14 @@ export {
|
|
|
1476
1606
|
getProviderDisplayName,
|
|
1477
1607
|
isAutoTier,
|
|
1478
1608
|
isCardGatedModel,
|
|
1609
|
+
isEffortPosition,
|
|
1479
1610
|
isLeapingIntoActionCommentBody,
|
|
1480
1611
|
isValidTimeString,
|
|
1481
1612
|
modelAliases,
|
|
1482
1613
|
modes,
|
|
1614
|
+
offeredRungs,
|
|
1483
1615
|
parseCodexAuthBody,
|
|
1616
|
+
parseEffortPosition,
|
|
1484
1617
|
parseModel,
|
|
1485
1618
|
parseTimeString,
|
|
1486
1619
|
providers,
|
|
@@ -1489,9 +1622,13 @@ export {
|
|
|
1489
1622
|
resolveAutoTier,
|
|
1490
1623
|
resolveCliModel,
|
|
1491
1624
|
resolveDisplayAlias,
|
|
1625
|
+
resolveModelRung,
|
|
1492
1626
|
resolveModelSlug,
|
|
1493
1627
|
resolveOpenRouterModel,
|
|
1628
|
+
resolveRung,
|
|
1494
1629
|
runStatusCheckNeedsFinalizing,
|
|
1630
|
+
rungLabel,
|
|
1631
|
+
rungPosition,
|
|
1495
1632
|
stringifyCodexAuthBody,
|
|
1496
1633
|
stripExistingFooter,
|
|
1497
1634
|
truncateAtLineBoundary,
|
package/dist/models.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* slugs use the format `provider/model-id` (e.g. "anthropic/claude-opus").
|
|
5
5
|
* bump `resolve` when a new model generation ships — the alias (slug) stays stable.
|
|
6
6
|
*/
|
|
7
|
+
import { type EffortPosition } from "./effort.ts";
|
|
7
8
|
/**
|
|
8
9
|
* routing discriminant for entries whose `resolve` is dynamic — looked up
|
|
9
10
|
* from a separate env var at run time rather than fixed in the catalog.
|
|
@@ -50,6 +51,14 @@ export interface ModelAlias {
|
|
|
50
51
|
/** alias key (within same provider) of the cheaper sibling reviewfrog should
|
|
51
52
|
* use as its lens-fanout subagent. e.g. claude-opus → "claude-sonnet". */
|
|
52
53
|
subagentModel: string | undefined;
|
|
54
|
+
/** reasoning-effort rungs this model accepts on the direct route, ascending.
|
|
55
|
+
* mirrors models.dev `reasoning_options[type=effort].values`. undefined means
|
|
56
|
+
* the model has no effort control and the setting is a documented no-op. */
|
|
57
|
+
effort: readonly string[] | undefined;
|
|
58
|
+
/** effort rungs on the OpenRouter route, when they differ from `effort` (the
|
|
59
|
+
* DeepSeek/GLM top rung is `max` natively but `xhigh` via OpenRouter).
|
|
60
|
+
* undefined falls back to `effort`. */
|
|
61
|
+
openRouterEffort: readonly string[] | undefined;
|
|
53
62
|
/** hide from selectable lists (UI dropdowns, CLI pickers). does NOT affect
|
|
54
63
|
* resolution — for that use `fallback`. used to keep a redundant alias out of
|
|
55
64
|
* pickers (e.g. the free `minimax-m2.5-free` duplicate). */
|
|
@@ -75,6 +84,10 @@ interface ModelDef {
|
|
|
75
84
|
/** alias key (within same provider) of the cheaper sibling reviewfrog should
|
|
76
85
|
* use as its lens-fanout subagent (e.g. claude-opus → "claude-sonnet"). */
|
|
77
86
|
subagentModel?: string;
|
|
87
|
+
/** effort rungs accepted on the direct route, ascending — see ModelAlias.effort */
|
|
88
|
+
effort?: readonly string[];
|
|
89
|
+
/** effort rungs on the OpenRouter route when they differ — see ModelAlias.openRouterEffort */
|
|
90
|
+
openRouterEffort?: readonly string[];
|
|
78
91
|
/** hide from selectable lists. does NOT affect resolution; for that use `fallback`. */
|
|
79
92
|
hidden?: boolean;
|
|
80
93
|
}
|
|
@@ -123,8 +136,8 @@ export declare const modelAliases: ModelAlias[];
|
|
|
123
136
|
* (CLI resolve, OpenRouter resolve, footer label) handles them transparently.
|
|
124
137
|
*
|
|
125
138
|
* `efficient` mirrors the OSS/default subsidy model (DeepSeek V4 Pro — beats
|
|
126
|
-
* Kimi K2.7 on agentic-review quality at ~4-5x lower cost, run at
|
|
127
|
-
*
|
|
139
|
+
* Kimi K2.7 on agentic-review quality at ~4-5x lower cost, run at whatever
|
|
140
|
+
* effort the repo asks for, clamped to its published ladder); `intelligent` is the
|
|
128
141
|
* frontier pick (Claude Opus). a `null` model means the tier hasn't been
|
|
129
142
|
* pinned: callers default by card status via `defaultAutoTier`.
|
|
130
143
|
*/
|
|
@@ -190,6 +203,27 @@ export declare function resolveCliModel(slug: string): string | undefined;
|
|
|
190
203
|
* (e.g. free opencode models).
|
|
191
204
|
*/
|
|
192
205
|
export declare function resolveOpenRouterModel(slug: string): string | undefined;
|
|
206
|
+
/**
|
|
207
|
+
* the effort rungs `slug` accepts on the route being used, or undefined when the
|
|
208
|
+
* model has no effort control at all. walks the fallback chain, so a deprecated
|
|
209
|
+
* slug is judged by the model that actually runs. drives both the console's
|
|
210
|
+
* level list and the runtime clamp, so the two can't disagree.
|
|
211
|
+
*/
|
|
212
|
+
export declare function getModelEffortLevels(params: {
|
|
213
|
+
slug: string;
|
|
214
|
+
useOpenRouter: boolean;
|
|
215
|
+
}): readonly string[] | undefined;
|
|
216
|
+
/**
|
|
217
|
+
* the rung a run actually sends: a position landed on this model's own published
|
|
218
|
+
* ladder. the result is always a rung the model offers, so there is no arithmetic
|
|
219
|
+
* anywhere that can produce a level it doesn't have. undefined means the model
|
|
220
|
+
* publishes no rungs and the harness gets no flag.
|
|
221
|
+
*/
|
|
222
|
+
export declare function resolveModelRung(params: {
|
|
223
|
+
slug: string;
|
|
224
|
+
position: EffortPosition;
|
|
225
|
+
useOpenRouter: boolean;
|
|
226
|
+
}): string | undefined;
|
|
193
227
|
export declare const DEFAULT_PROXY_MODEL: string;
|
|
194
228
|
/** short label for the model auto-select picks today (console hint copy). */
|
|
195
229
|
export declare function getAutoSelectHintModel(): string;
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* in `action/test/coverage.ts::ALWAYS_RUN_ALL`).
|
|
14
14
|
*/
|
|
15
15
|
/**
|
|
16
|
-
* Billing-layer error surfaced from `/api/proxy-token` as a 402. User-actionable
|
|
17
|
-
*
|
|
16
|
+
* Billing-layer error surfaced from `/api/proxy-token` as a 402. User-actionable,
|
|
17
|
+
* distinct from TransientError (503 / transient sync issue) so the job
|
|
18
18
|
* summary + PR comment can use affirmative "you need to do X" copy rather than
|
|
19
19
|
* the ambiguous "billing error" label that makes transient outages look like
|
|
20
20
|
* the user's fault.
|
|
@@ -37,28 +37,45 @@ export declare class BillingError extends Error {
|
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* Transient service failures from `/api/proxy-token` (503: partial OpenRouter
|
|
40
|
-
* usage sync, DB flake, in-flight payment intent). Not the user's fault
|
|
40
|
+
* usage sync, DB flake, in-flight payment intent). Not the user's fault, the
|
|
41
41
|
* summary uses "temporarily unavailable" framing, and the non-zero exit lets
|
|
42
42
|
* GH Actions apply whatever retry policy the workflow has configured.
|
|
43
43
|
*/
|
|
44
44
|
export declare class TransientError extends Error {
|
|
45
45
|
constructor(message: string);
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Canonical paused-run paywall body (billing model v2). Single source of truth so
|
|
49
|
+
* the two surfaces that show it can never drift: the trigger-time comment (a run
|
|
50
|
+
* refused before it starts, `triggerWorkflow.postPaywallComment`) and the mid-run
|
|
51
|
+
* 402 render (`formatBillingErrorSummary` via `renderRunError`). `url` is the
|
|
52
|
+
* caller's billing surface (each passes its own, internal plan page vs console).
|
|
53
|
+
*/
|
|
54
|
+
export declare function commercialPaywallBody(params: {
|
|
55
|
+
reason: "commercial" | "subscription_unpaid";
|
|
56
|
+
ownerLogin: string;
|
|
57
|
+
url: string;
|
|
58
|
+
}): string;
|
|
59
|
+
/** commercial-gate copy for action runs, linked to the account billing card. */
|
|
60
|
+
export declare function formatCommercialGateSummary(params: {
|
|
61
|
+
reason: "commercial" | "subscription_unpaid";
|
|
62
|
+
ownerLogin: string;
|
|
63
|
+
}): string;
|
|
47
64
|
/**
|
|
48
65
|
* Render a BillingError as user-facing markdown (shared between GH job summary
|
|
49
66
|
* and the PR progress comment). Goals:
|
|
50
67
|
*
|
|
51
|
-
* - quiet, not alarmist
|
|
68
|
+
* - quiet, not alarmist, bold first line instead of an `### ❌` H3, since
|
|
52
69
|
* the comment already has Pullfrog branding in the footer
|
|
53
|
-
* - actionable
|
|
70
|
+
* - actionable, every branch ends in a single CTA deep-linked to the
|
|
54
71
|
* correct section of the owner's console
|
|
55
|
-
* - honest
|
|
72
|
+
* - honest, say what actually went wrong (card declined vs. balance
|
|
56
73
|
* empty vs. 3DS required), don't lump them under "billing error"
|
|
57
74
|
*
|
|
58
75
|
* Branches:
|
|
59
76
|
* - `router_requires_card`: user is on Router mode with no card AND no
|
|
60
|
-
* wallet balance
|
|
61
|
-
* "add a card to continue", link to `#
|
|
77
|
+
* wallet balance. Frame as
|
|
78
|
+
* "add a card to continue", link to `#billing` where the Add
|
|
62
79
|
* Card flow lives.
|
|
63
80
|
* - `router_balance_exhausted`: user has a card on file but auto-reload is
|
|
64
81
|
* disabled and they've spent past their $5 overdraft buffer. Frame as
|
|
@@ -69,7 +86,7 @@ export declare class TransientError extends Error {
|
|
|
69
86
|
* wallet is now negative; same remediation as `router_balance_exhausted`
|
|
70
87
|
* but framed for the after-the-fact case ("this run was cut short").
|
|
71
88
|
* - `needsReauthentication`: issuer requires 3DS on every off-session
|
|
72
|
-
* charge. Re-adding the card won't help
|
|
89
|
+
* charge. Re-adding the card won't help, the only escape is a manual
|
|
73
90
|
* top-up where 3DS runs interactively in Stripe Checkout.
|
|
74
91
|
* - `declineCode` set: Stripe declined a real charge. Show the sub-code
|
|
75
92
|
* so support can act on it; tell the user we'll retry on next dispatch.
|
|
@@ -80,6 +97,6 @@ export declare function formatBillingErrorSummary(error: BillingError, owner: st
|
|
|
80
97
|
/**
|
|
81
98
|
* Render a TransientError as user-facing markdown. Distinct framing from
|
|
82
99
|
* BillingError so the user doesn't read an alarm and assume their card
|
|
83
|
-
* failed
|
|
100
|
+
* failed, this branch is "our fault, retry shortly", not theirs.
|
|
84
101
|
*/
|
|
85
102
|
export declare function formatTransientErrorSummary(error: TransientError, owner: string): string;
|
package/dist/utils/payload.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PayloadEvent } from "../external.ts";
|
|
2
2
|
import type { RepoSettings } from "./runContext.ts";
|
|
3
3
|
export declare const JsonPayload: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
4
4
|
"~pullfrog": true;
|
|
@@ -6,6 +6,7 @@ export declare const JsonPayload: import("arktype/internal/variants/object.ts").
|
|
|
6
6
|
prompt: string;
|
|
7
7
|
model?: string | undefined;
|
|
8
8
|
modelExplicit?: boolean | undefined;
|
|
9
|
+
effort?: string | number | undefined;
|
|
9
10
|
triggerer?: string | undefined;
|
|
10
11
|
baseInstructions?: string | undefined;
|
|
11
12
|
eventInstructions?: string;
|
|
@@ -31,6 +32,7 @@ export declare const Inputs: import("arktype/internal/variants/object.ts").Objec
|
|
|
31
32
|
prompt?: string | undefined;
|
|
32
33
|
prompt_file?: string | undefined;
|
|
33
34
|
model?: string | undefined;
|
|
35
|
+
effort?: string | undefined;
|
|
34
36
|
timeout?: string | undefined;
|
|
35
37
|
push?: "disabled" | "enabled" | "restricted" | undefined;
|
|
36
38
|
shell?: "disabled" | "enabled" | "restricted" | undefined;
|
|
@@ -53,6 +55,7 @@ export declare function resolvePayload(resolvedPromptInput: ResolvedPromptInput,
|
|
|
53
55
|
version: string;
|
|
54
56
|
model: string | undefined;
|
|
55
57
|
modelExplicit: boolean;
|
|
58
|
+
effort: number | undefined;
|
|
56
59
|
prompt: string;
|
|
57
60
|
triggerer: string | undefined;
|
|
58
61
|
baseInstructions: string | undefined;
|