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