pullfrog 0.1.66 → 0.1.67
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 +1 -0
- package/dist/cli.mjs +265 -65
- package/dist/index.js +149 -2
- package/dist/internal.js +137 -0
- package/dist/models.d.ts +2 -0
- package/dist/utils/apiKeys.d.ts +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -525,15 +525,15 @@ var require_file_command = __commonJS({
|
|
|
525
525
|
}
|
|
526
526
|
exports.issueFileCommand = issueFileCommand;
|
|
527
527
|
function prepareKeyValueMessage(key, value2) {
|
|
528
|
-
const
|
|
528
|
+
const delimiter3 = `ghadelimiter_${crypto5.randomUUID()}`;
|
|
529
529
|
const convertedValue = (0, utils_1.toCommandValue)(value2);
|
|
530
|
-
if (key.includes(
|
|
531
|
-
throw new Error(`Unexpected input: name should not contain the delimiter "${
|
|
530
|
+
if (key.includes(delimiter3)) {
|
|
531
|
+
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter3}"`);
|
|
532
532
|
}
|
|
533
|
-
if (convertedValue.includes(
|
|
534
|
-
throw new Error(`Unexpected input: value should not contain the delimiter "${
|
|
533
|
+
if (convertedValue.includes(delimiter3)) {
|
|
534
|
+
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter3}"`);
|
|
535
535
|
}
|
|
536
|
-
return `${key}<<${
|
|
536
|
+
return `${key}<<${delimiter3}${os2.EOL}${convertedValue}${os2.EOL}${delimiter3}`;
|
|
537
537
|
}
|
|
538
538
|
exports.prepareKeyValueMessage = prepareKeyValueMessage;
|
|
539
539
|
}
|
|
@@ -11973,10 +11973,10 @@ var require_headers = __commonJS({
|
|
|
11973
11973
|
const lowercaseName = name.toLowerCase();
|
|
11974
11974
|
const exists = this[kHeadersMap].get(lowercaseName);
|
|
11975
11975
|
if (exists) {
|
|
11976
|
-
const
|
|
11976
|
+
const delimiter3 = lowercaseName === "cookie" ? "; " : ", ";
|
|
11977
11977
|
this[kHeadersMap].set(lowercaseName, {
|
|
11978
11978
|
name: exists.name,
|
|
11979
|
-
value: `${exists.value}${
|
|
11979
|
+
value: `${exists.value}${delimiter3}${value2}`
|
|
11980
11980
|
});
|
|
11981
11981
|
} else {
|
|
11982
11982
|
this[kHeadersMap].set(lowercaseName, { name, value: value2 });
|
|
@@ -46981,10 +46981,10 @@ var require_headers2 = __commonJS({
|
|
|
46981
46981
|
const lowercaseName = isLowerCase ? name : name.toLowerCase();
|
|
46982
46982
|
const exists = this.headersMap.get(lowercaseName);
|
|
46983
46983
|
if (exists) {
|
|
46984
|
-
const
|
|
46984
|
+
const delimiter3 = lowercaseName === "cookie" ? "; " : ", ";
|
|
46985
46985
|
this.headersMap.set(lowercaseName, {
|
|
46986
46986
|
name: exists.name,
|
|
46987
|
-
value: `${exists.value}${
|
|
46987
|
+
value: `${exists.value}${delimiter3}${value2}`
|
|
46988
46988
|
});
|
|
46989
46989
|
} else {
|
|
46990
46990
|
this.headersMap.set(lowercaseName, { name, value: value2 });
|
|
@@ -59293,8 +59293,8 @@ var init_regexes = __esm({
|
|
|
59293
59293
|
_emoji = `^[\\p{Extended_Pictographic}\\p{Emoji_Component}]+$`;
|
|
59294
59294
|
ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
59295
59295
|
ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
|
|
59296
|
-
mac = (
|
|
59297
|
-
const escapedDelim = escapeRegex(
|
|
59296
|
+
mac = (delimiter3) => {
|
|
59297
|
+
const escapedDelim = escapeRegex(delimiter3 ?? ":");
|
|
59298
59298
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
59299
59299
|
};
|
|
59300
59300
|
cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
|
@@ -102436,10 +102436,10 @@ var require_turndown_cjs = __commonJS({
|
|
|
102436
102436
|
if (!content) return "";
|
|
102437
102437
|
content = content.replace(/\r?\n|\r/g, " ");
|
|
102438
102438
|
var extraSpace = /^`|^ .*?[^ ].* $|`$/.test(content) ? " " : "";
|
|
102439
|
-
var
|
|
102439
|
+
var delimiter3 = "`";
|
|
102440
102440
|
var matches = content.match(/`+/gm) || [];
|
|
102441
|
-
while (matches.indexOf(
|
|
102442
|
-
return
|
|
102441
|
+
while (matches.indexOf(delimiter3) !== -1) delimiter3 = delimiter3 + "`";
|
|
102442
|
+
return delimiter3 + extraSpace + content + extraSpace + delimiter3;
|
|
102443
102443
|
}
|
|
102444
102444
|
};
|
|
102445
102445
|
rules.image = {
|
|
@@ -104189,8 +104189,8 @@ var require_common = __commonJS({
|
|
|
104189
104189
|
}
|
|
104190
104190
|
return debug4;
|
|
104191
104191
|
}
|
|
104192
|
-
function extend3(namespace,
|
|
104193
|
-
const newDebug = createDebug(this.namespace + (typeof
|
|
104192
|
+
function extend3(namespace, delimiter3) {
|
|
104193
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter3 === "undefined" ? ":" : delimiter3) + namespace);
|
|
104194
104194
|
newDebug.log = this.log;
|
|
104195
104195
|
return newDebug;
|
|
104196
104196
|
}
|
|
@@ -108809,9 +108809,9 @@ var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
|
108809
108809
|
|
|
108810
108810
|
// utils/codexAuth.ts
|
|
108811
108811
|
import { spawn } from "node:child_process";
|
|
108812
|
-
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
108812
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
108813
108813
|
import { tmpdir } from "node:os";
|
|
108814
|
-
import { join } from "node:path";
|
|
108814
|
+
import { delimiter, join } from "node:path";
|
|
108815
108815
|
|
|
108816
108816
|
// utils/oauthShared.ts
|
|
108817
108817
|
var OAuthInvalidGrantError = class extends Error {
|
|
@@ -108960,11 +108960,60 @@ async function mintCodexAuth(options) {
|
|
|
108960
108960
|
}
|
|
108961
108961
|
}
|
|
108962
108962
|
var SIGTERM_GRACE_MS = 5e3;
|
|
108963
|
+
var DEVICE_AUTH_ARGS = ["login", "--device-auth"];
|
|
108964
|
+
var DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD";
|
|
108965
|
+
function envValue(env2, name) {
|
|
108966
|
+
if (env2[name] !== void 0) return env2[name];
|
|
108967
|
+
const key = Object.keys(env2).find((candidate) => candidate.toUpperCase() === name.toUpperCase());
|
|
108968
|
+
return key === void 0 ? void 0 : env2[key];
|
|
108969
|
+
}
|
|
108970
|
+
function commandProcessor(env2) {
|
|
108971
|
+
return envValue(env2, "ComSpec") ?? join(envValue(env2, "SystemRoot") ?? "C:\\Windows", "system32", "cmd.exe");
|
|
108972
|
+
}
|
|
108973
|
+
function resolveSpawnTarget(params) {
|
|
108974
|
+
if (process.platform !== "win32") {
|
|
108975
|
+
return { file: params.command, args: params.args, wrapped: false };
|
|
108976
|
+
}
|
|
108977
|
+
const extensions2 = (envValue(params.env, "PATHEXT") ?? DEFAULT_PATHEXT).split(";").filter(Boolean);
|
|
108978
|
+
for (const directory of (envValue(params.env, "PATH") ?? "").split(delimiter).filter(Boolean)) {
|
|
108979
|
+
for (const extension of extensions2) {
|
|
108980
|
+
const candidate = join(directory, `${params.command}${extension.toLowerCase()}`);
|
|
108981
|
+
if (!existsSync(candidate)) continue;
|
|
108982
|
+
if (!/\.(cmd|bat)$/i.test(candidate)) {
|
|
108983
|
+
return { file: candidate, args: params.args, wrapped: false };
|
|
108984
|
+
}
|
|
108985
|
+
const command = [`"${candidate}"`, ...params.args].join(" ");
|
|
108986
|
+
return {
|
|
108987
|
+
file: commandProcessor(params.env),
|
|
108988
|
+
args: ["/d", "/s", "/c", `"${command}"`],
|
|
108989
|
+
wrapped: true
|
|
108990
|
+
};
|
|
108991
|
+
}
|
|
108992
|
+
}
|
|
108993
|
+
return null;
|
|
108994
|
+
}
|
|
108995
|
+
function codexNotFoundMessage(env2) {
|
|
108996
|
+
const install = "install it with `npm i -g @openai/codex` or see https://developers.openai.com/codex/cli for other install options.";
|
|
108997
|
+
if (process.platform !== "win32") return `codex CLI not found on PATH. ${install}`;
|
|
108998
|
+
const extensions2 = (envValue(env2, "PATHEXT") ?? DEFAULT_PATHEXT).split(";").filter(Boolean).join(" ");
|
|
108999
|
+
return `codex CLI not found on PATH (searched every PATH entry for codex with ${extensions2}). a working \`codex --version\` in a shell does not prove Node can spawn it. ${install}`;
|
|
109000
|
+
}
|
|
108963
109001
|
function runDeviceAuth(input2) {
|
|
108964
109002
|
return new Promise((resolve3, reject) => {
|
|
108965
|
-
const
|
|
109003
|
+
const target = resolveSpawnTarget({
|
|
109004
|
+
command: "codex",
|
|
109005
|
+
args: DEVICE_AUTH_ARGS,
|
|
109006
|
+
env: process.env
|
|
109007
|
+
});
|
|
109008
|
+
if (!target) {
|
|
109009
|
+
reject(new Error(codexNotFoundMessage(process.env)));
|
|
109010
|
+
return;
|
|
109011
|
+
}
|
|
109012
|
+
const child = spawn(target.file, target.args, {
|
|
108966
109013
|
env: { ...process.env, CODEX_HOME: input2.codexHome },
|
|
108967
|
-
stdio: ["ignore", input2.childStdio, input2.childStdio]
|
|
109014
|
+
stdio: ["ignore", input2.childStdio, input2.childStdio],
|
|
109015
|
+
windowsVerbatimArguments: target.wrapped,
|
|
109016
|
+
windowsHide: true
|
|
108968
109017
|
});
|
|
108969
109018
|
if (input2.childStdio === "pipe") {
|
|
108970
109019
|
const onLine = input2.onChildLine ?? (() => {
|
|
@@ -108976,6 +109025,10 @@ function runDeviceAuth(input2) {
|
|
|
108976
109025
|
let timedOut = false;
|
|
108977
109026
|
const timeoutTimer = setTimeout(() => {
|
|
108978
109027
|
timedOut = true;
|
|
109028
|
+
if (target.wrapped && child.pid) {
|
|
109029
|
+
spawn("taskkill", ["/pid", String(child.pid), "/t", "/f"], { stdio: "ignore" });
|
|
109030
|
+
return;
|
|
109031
|
+
}
|
|
108979
109032
|
child.kill("SIGTERM");
|
|
108980
109033
|
killTimer = setTimeout(() => child.kill("SIGKILL"), SIGTERM_GRACE_MS);
|
|
108981
109034
|
}, input2.timeoutMs);
|
|
@@ -108983,7 +109036,7 @@ function runDeviceAuth(input2) {
|
|
|
108983
109036
|
clearTimeout(timeoutTimer);
|
|
108984
109037
|
if (killTimer) clearTimeout(killTimer);
|
|
108985
109038
|
const errno = err;
|
|
108986
|
-
const message = errno.code === "ENOENT" ?
|
|
109039
|
+
const message = errno.code === "ENOENT" ? codexNotFoundMessage(process.env) : `failed to spawn codex: ${errno.message}`;
|
|
108987
109040
|
reject(new Error(message));
|
|
108988
109041
|
});
|
|
108989
109042
|
child.on("close", (code, signal) => {
|
|
@@ -109797,7 +109850,7 @@ var import_arg2 = __toESM(require_arg(), 1);
|
|
|
109797
109850
|
import { dirname as dirname6 } from "node:path";
|
|
109798
109851
|
|
|
109799
109852
|
// main.ts
|
|
109800
|
-
import { existsSync as
|
|
109853
|
+
import { existsSync as existsSync11, readdirSync as readdirSync2 } from "node:fs";
|
|
109801
109854
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
109802
109855
|
import { join as join28 } from "node:path";
|
|
109803
109856
|
|
|
@@ -110479,6 +110532,69 @@ var providers = {
|
|
|
110479
110532
|
}
|
|
110480
110533
|
}
|
|
110481
110534
|
}),
|
|
110535
|
+
// the same models as `moonshotai` above, billed against a Kimi membership
|
|
110536
|
+
// instead of a Moonshot API balance — a separate endpoint, separate model
|
|
110537
|
+
// ids and a separate key, which is why it is a provider rather than a second
|
|
110538
|
+
// `envVars` entry. no provider injection is needed: models.dev carries
|
|
110539
|
+
// `kimi-for-coding` (api `https://api.kimi.com/coding/v1`, npm
|
|
110540
|
+
// `@ai-sdk/anthropic`) and opencode's env loop enables it from a bare
|
|
110541
|
+
// `KIMI_API_KEY`, verified against our pinned opencode-ai@1.18.5 — all four
|
|
110542
|
+
// ids list in `opencode models` and a run reaches Kimi's own auth check.
|
|
110543
|
+
//
|
|
110544
|
+
// NO `openRouterResolve` ON PURPOSE. OpenRouter cannot serve a Kimi
|
|
110545
|
+
// membership, so a Router path here would silently bill the wallet for
|
|
110546
|
+
// Moonshot pay-as-you-go under a slug picked for the opposite reason. The
|
|
110547
|
+
// absence is load-bearing: `isCardGatedModel` reads it as "not Router-
|
|
110548
|
+
// resolvable", `decideModelAccess` answers an explicit pick with the
|
|
110549
|
+
// `router` copy ("add your own provider key"), and run-context clamps a
|
|
110550
|
+
// keyless Router pick to the default subsidy model with `noRouterPath`.
|
|
110551
|
+
"kimi-for-coding": provider({
|
|
110552
|
+
// "Kimi Code" is the product name on kimi.com/code and in the console the
|
|
110553
|
+
// key is minted from. The provider KEY has to stay `kimi-for-coding` — it
|
|
110554
|
+
// is models.dev's id, so it is what `enabled_providers` and every
|
|
110555
|
+
// `resolve` prefix must spell.
|
|
110556
|
+
displayName: "Kimi Code",
|
|
110557
|
+
envVars: ["KIMI_API_KEY"],
|
|
110558
|
+
models: {
|
|
110559
|
+
// the tier each model needs is in `description` because Kimi answers an
|
|
110560
|
+
// out-of-tier request with 401 — indistinguishable from a bad key by
|
|
110561
|
+
// status alone, and only `isKimiPlanTierError` tells them apart after the
|
|
110562
|
+
// fact. saying it in the picker is the half that stops the run happening.
|
|
110563
|
+
"kimi-k3": {
|
|
110564
|
+
displayName: "Kimi K3",
|
|
110565
|
+
description: "1M context, but only on Allegretto and above \xB7 Moderato caps it at 256K",
|
|
110566
|
+
resolve: "kimi-for-coding/k3",
|
|
110567
|
+
effort: ["low", "high", "max"],
|
|
110568
|
+
subagentModel: "kimi-k2"
|
|
110569
|
+
},
|
|
110570
|
+
// `preferred` sits on the 256K variant rather than the 1M flagship, which
|
|
110571
|
+
// inverts the usual "top tier wins" rule for a reason specific to Kimi:
|
|
110572
|
+
// below Allegretto the two are the SAME 256K ceiling and `k3` charges
|
|
110573
|
+
// roughly double the quota for it, so on the median tier the flagship is
|
|
110574
|
+
// strictly dominated rather than merely pricier. This flag seeds the
|
|
110575
|
+
// onboarding pick (`getRecommendedSlug`) and wins key-only auto-select
|
|
110576
|
+
// (`autoSelectModel`), which are exactly the two moments nobody has
|
|
110577
|
+
// chosen yet.
|
|
110578
|
+
"kimi-k3-256k": {
|
|
110579
|
+
displayName: "Kimi K3 256K",
|
|
110580
|
+
description: "Same model at 256K for ~half the quota \xB7 Moderato or above",
|
|
110581
|
+
resolve: "kimi-for-coding/k3-256k",
|
|
110582
|
+
effort: ["low", "high", "max"],
|
|
110583
|
+
preferred: true,
|
|
110584
|
+
subagentModel: "kimi-k2"
|
|
110585
|
+
},
|
|
110586
|
+
"kimi-k2": {
|
|
110587
|
+
displayName: "Kimi K2",
|
|
110588
|
+
description: "Included in every Kimi membership tier",
|
|
110589
|
+
resolve: "kimi-for-coding/kimi-for-coding"
|
|
110590
|
+
},
|
|
110591
|
+
"kimi-k2-highspeed": {
|
|
110592
|
+
displayName: "Kimi K2 HighSpeed",
|
|
110593
|
+
description: "~6x output speed for ~3x quota \xB7 needs Allegretto or above",
|
|
110594
|
+
resolve: "kimi-for-coding/kimi-for-coding-highspeed"
|
|
110595
|
+
}
|
|
110596
|
+
}
|
|
110597
|
+
}),
|
|
110482
110598
|
opencode: provider({
|
|
110483
110599
|
displayName: "OpenCode Zen",
|
|
110484
110600
|
envVars: ["OPENCODE_API_KEY"],
|
|
@@ -111031,6 +111147,80 @@ var providers = {
|
|
|
111031
111147
|
openRouterResolve: "openrouter/minimax/minimax-m3"
|
|
111032
111148
|
}
|
|
111033
111149
|
}
|
|
111150
|
+
}),
|
|
111151
|
+
vercel: provider({
|
|
111152
|
+
// Vercel AI Gateway — one key serves every model it fronts. model IDs use
|
|
111153
|
+
// the models.dev `vercel` catalog's own naming (dotted versions, e.g.
|
|
111154
|
+
// `anthropic/claude-opus-5`, `zai/glm-5.3`), and effort ladders mirror that
|
|
111155
|
+
// catalog's entries, not the upstream vendor's. deliberately no
|
|
111156
|
+
// `openRouterResolve`: a gateway pick is BYOK-only — silently rerouting it
|
|
111157
|
+
// over the Router proxy would bill the wallet for traffic the user pointed
|
|
111158
|
+
// at their own gateway.
|
|
111159
|
+
displayName: "Vercel AI Gateway",
|
|
111160
|
+
envVars: ["AI_GATEWAY_API_KEY"],
|
|
111161
|
+
models: {
|
|
111162
|
+
"claude-opus": {
|
|
111163
|
+
displayName: "Claude Opus",
|
|
111164
|
+
resolve: "vercel/anthropic/claude-opus-5",
|
|
111165
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
111166
|
+
preferred: true,
|
|
111167
|
+
subagentModel: "claude-sonnet"
|
|
111168
|
+
},
|
|
111169
|
+
"claude-sonnet": {
|
|
111170
|
+
displayName: "Claude Sonnet",
|
|
111171
|
+
resolve: "vercel/anthropic/claude-sonnet-5",
|
|
111172
|
+
effort: ["low", "medium", "high", "xhigh"]
|
|
111173
|
+
},
|
|
111174
|
+
"claude-haiku": {
|
|
111175
|
+
displayName: "Claude Haiku",
|
|
111176
|
+
resolve: "vercel/anthropic/claude-haiku-4.5"
|
|
111177
|
+
},
|
|
111178
|
+
"gpt-sol": {
|
|
111179
|
+
displayName: "GPT Sol",
|
|
111180
|
+
resolve: "vercel/openai/gpt-5.6-sol",
|
|
111181
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
111182
|
+
subagentModel: "gpt-terra"
|
|
111183
|
+
},
|
|
111184
|
+
"gpt-terra": {
|
|
111185
|
+
displayName: "GPT Terra",
|
|
111186
|
+
resolve: "vercel/openai/gpt-5.6-terra",
|
|
111187
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"]
|
|
111188
|
+
},
|
|
111189
|
+
"gpt-luna": {
|
|
111190
|
+
displayName: "GPT Luna",
|
|
111191
|
+
resolve: "vercel/openai/gpt-5.6-luna",
|
|
111192
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"]
|
|
111193
|
+
},
|
|
111194
|
+
"gemini-pro": {
|
|
111195
|
+
displayName: "Gemini Pro",
|
|
111196
|
+
resolve: "vercel/google/gemini-3.1-pro-preview",
|
|
111197
|
+
effort: ["low", "medium", "high"]
|
|
111198
|
+
},
|
|
111199
|
+
"gemini-flash": {
|
|
111200
|
+
displayName: "Gemini Flash",
|
|
111201
|
+
resolve: "vercel/google/gemini-3.6-flash",
|
|
111202
|
+
effort: ["minimal", "low", "medium", "high"]
|
|
111203
|
+
},
|
|
111204
|
+
"deepseek-pro": {
|
|
111205
|
+
displayName: "DeepSeek Pro",
|
|
111206
|
+
resolve: "vercel/deepseek/deepseek-v4-pro-0813",
|
|
111207
|
+
effort: ["high", "xhigh"]
|
|
111208
|
+
},
|
|
111209
|
+
"deepseek-flash": {
|
|
111210
|
+
displayName: "DeepSeek Flash",
|
|
111211
|
+
resolve: "vercel/deepseek/deepseek-v4-flash",
|
|
111212
|
+
effort: ["high", "xhigh"]
|
|
111213
|
+
},
|
|
111214
|
+
glm: {
|
|
111215
|
+
displayName: "GLM",
|
|
111216
|
+
resolve: "vercel/zai/glm-5.3",
|
|
111217
|
+
effort: ["low", "high", "max"]
|
|
111218
|
+
},
|
|
111219
|
+
"kimi-k3": {
|
|
111220
|
+
displayName: "Kimi K3",
|
|
111221
|
+
resolve: "vercel/moonshotai/kimi-k3"
|
|
111222
|
+
}
|
|
111223
|
+
}
|
|
111034
111224
|
})
|
|
111035
111225
|
};
|
|
111036
111226
|
function parseModel(slug2) {
|
|
@@ -111458,9 +111648,9 @@ function logTokenTable(t2) {
|
|
|
111458
111648
|
}
|
|
111459
111649
|
|
|
111460
111650
|
// utils/globals.ts
|
|
111461
|
-
import { existsSync } from "node:fs";
|
|
111651
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
111462
111652
|
var isGitHubActions = !!process.env.GITHUB_ACTIONS;
|
|
111463
|
-
var isInsideDocker =
|
|
111653
|
+
var isInsideDocker = existsSync2("/.dockerenv");
|
|
111464
111654
|
|
|
111465
111655
|
// utils/log.ts
|
|
111466
111656
|
var logContext = new AsyncLocalStorage();
|
|
@@ -111688,7 +111878,7 @@ function formatUsageSummary(entries) {
|
|
|
111688
111878
|
|
|
111689
111879
|
// utils/install.ts
|
|
111690
111880
|
import { spawnSync } from "node:child_process";
|
|
111691
|
-
import { chmodSync, createWriteStream, existsSync as
|
|
111881
|
+
import { chmodSync, createWriteStream, existsSync as existsSync3, mkdirSync } from "node:fs";
|
|
111692
111882
|
import { join as join2 } from "node:path";
|
|
111693
111883
|
import { pipeline } from "node:stream/promises";
|
|
111694
111884
|
async function installFromNpmTarball(params) {
|
|
@@ -111697,7 +111887,7 @@ async function installFromNpmTarball(params) {
|
|
|
111697
111887
|
const packageRoot = join2(tempDir, `npm-${params.packageName.replace(/[^a-z0-9]+/gi, "-")}`);
|
|
111698
111888
|
const extractedDir = join2(packageRoot, "package");
|
|
111699
111889
|
const cliPath = join2(extractedDir, params.executablePath);
|
|
111700
|
-
if (
|
|
111890
|
+
if (existsSync3(cliPath)) {
|
|
111701
111891
|
log2.debug(`\xBB using cached binary at ${cliPath}`);
|
|
111702
111892
|
return cliPath;
|
|
111703
111893
|
}
|
|
@@ -111771,7 +111961,7 @@ async function installFromNpmTarball(params) {
|
|
|
111771
111961
|
}
|
|
111772
111962
|
log2.debug(`\xBB dependencies installed`);
|
|
111773
111963
|
}
|
|
111774
|
-
if (!
|
|
111964
|
+
if (!existsSync3(cliPath)) {
|
|
111775
111965
|
throw new Error(`Executable not found in extracted package at ${cliPath}`);
|
|
111776
111966
|
}
|
|
111777
111967
|
chmodSync(cliPath, 493);
|
|
@@ -111978,7 +112168,7 @@ function resolveRunEffort(ctx) {
|
|
|
111978
112168
|
|
|
111979
112169
|
// utils/skills.ts
|
|
111980
112170
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
111981
|
-
import { existsSync as
|
|
112171
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
111982
112172
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
111983
112173
|
import { dirname, join as join3 } from "node:path";
|
|
111984
112174
|
import { fileURLToPath } from "node:url";
|
|
@@ -111989,7 +112179,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
111989
112179
|
// package.json
|
|
111990
112180
|
var package_default = {
|
|
111991
112181
|
name: "pullfrog",
|
|
111992
|
-
version: "0.1.
|
|
112182
|
+
version: "0.1.67",
|
|
111993
112183
|
type: "module",
|
|
111994
112184
|
bin: {
|
|
111995
112185
|
pullfrog: "dist/cli.mjs",
|
|
@@ -112118,7 +112308,7 @@ function resolveSkillPath(name) {
|
|
|
112118
112308
|
join3(here, "skills", name, "SKILL.md")
|
|
112119
112309
|
];
|
|
112120
112310
|
for (const candidate of candidates) {
|
|
112121
|
-
if (
|
|
112311
|
+
if (existsSync4(candidate)) return candidate;
|
|
112122
112312
|
}
|
|
112123
112313
|
throw new Error(`bundled skill not found: ${name} (looked in ${candidates.join(", ")})`);
|
|
112124
112314
|
}
|
|
@@ -114159,13 +114349,13 @@ var claude = agent({
|
|
|
114159
114349
|
|
|
114160
114350
|
// agents/codex.ts
|
|
114161
114351
|
var core2 = __toESM(require_core(), 1);
|
|
114162
|
-
import { existsSync as
|
|
114352
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
114163
114353
|
import { join as join7 } from "node:path";
|
|
114164
114354
|
import { performance as performance6 } from "node:perf_hooks";
|
|
114165
114355
|
|
|
114166
114356
|
// utils/codexHome.ts
|
|
114167
114357
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
114168
|
-
import { existsSync as
|
|
114358
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
114169
114359
|
import { homedir as homedir2, userInfo } from "node:os";
|
|
114170
114360
|
import { join as join6 } from "node:path";
|
|
114171
114361
|
var CODEX_AUTH_ENV = "CODEX_AUTH_JSON";
|
|
@@ -114214,7 +114404,7 @@ function installCodexAuth() {
|
|
|
114214
114404
|
}
|
|
114215
114405
|
function writeOpenCodeAuthEntry(params) {
|
|
114216
114406
|
let existing = {};
|
|
114217
|
-
if (
|
|
114407
|
+
if (existsSync5(params.authPath)) {
|
|
114218
114408
|
try {
|
|
114219
114409
|
const parsed2 = JSON.parse(readFileSync3(params.authPath, "utf8"));
|
|
114220
114410
|
if (parsed2 && typeof parsed2 === "object") existing = parsed2;
|
|
@@ -114531,7 +114721,7 @@ var APPROVAL_MODE_KEY = "default_tools_approval_mode";
|
|
|
114531
114721
|
var APPROVE_TOOLS = `${APPROVAL_MODE_KEY} = "approve"`;
|
|
114532
114722
|
function repoMcpApprovals(repoDir) {
|
|
114533
114723
|
const path4 = join7(repoDir, ".codex", "config.toml");
|
|
114534
|
-
if (!
|
|
114724
|
+
if (!existsSync6(path4)) return [];
|
|
114535
114725
|
const out = [];
|
|
114536
114726
|
let section = [];
|
|
114537
114727
|
let isServerTable = false;
|
|
@@ -178940,7 +179130,7 @@ var pbkdf2Async = promisify(pbkdf2);
|
|
|
178940
179130
|
|
|
178941
179131
|
// utils/browser.ts
|
|
178942
179132
|
import { execFileSync as execFileSync5, spawnSync as spawnSync4 } from "node:child_process";
|
|
178943
|
-
import { existsSync as
|
|
179133
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
178944
179134
|
import { dirname as dirname2 } from "node:path";
|
|
178945
179135
|
var CHROME_PATHS = ["/usr/bin/google-chrome-stable"];
|
|
178946
179136
|
var systemChromePath;
|
|
@@ -178949,7 +179139,7 @@ function findSystemChromePath() {
|
|
|
178949
179139
|
return systemChromePath || void 0;
|
|
178950
179140
|
}
|
|
178951
179141
|
for (const p of CHROME_PATHS) {
|
|
178952
|
-
if (
|
|
179142
|
+
if (existsSync7(p)) {
|
|
178953
179143
|
systemChromePath = p;
|
|
178954
179144
|
log2.info(`found system chrome: ${p}`);
|
|
178955
179145
|
return p;
|
|
@@ -182620,7 +182810,7 @@ var describeExpressionOptions = {
|
|
|
182620
182810
|
};
|
|
182621
182811
|
var expressBranches = (expressions) => describeBranches(expressions, describeExpressionOptions);
|
|
182622
182812
|
var describeBranches = (descriptions, opts) => {
|
|
182623
|
-
const
|
|
182813
|
+
const delimiter3 = opts?.delimiter ?? ", ";
|
|
182624
182814
|
const finalDelimiter = opts?.finalDelimiter ?? " or ";
|
|
182625
182815
|
if (descriptions.length === 0)
|
|
182626
182816
|
return "never";
|
|
@@ -182631,7 +182821,7 @@ var describeBranches = (descriptions, opts) => {
|
|
|
182631
182821
|
const seen = {};
|
|
182632
182822
|
const unique = descriptions.filter((s) => seen[s] ? false : seen[s] = true);
|
|
182633
182823
|
const last = unique.pop();
|
|
182634
|
-
return `${unique.join(
|
|
182824
|
+
return `${unique.join(delimiter3)}${unique.length ? finalDelimiter : ""}${last}`;
|
|
182635
182825
|
};
|
|
182636
182826
|
var intersectBranches = (l2, r2, ctx) => {
|
|
182637
182827
|
const batchesByR = r2.map(() => []);
|
|
@@ -193349,7 +193539,7 @@ function isValidUnquotedKey(key) {
|
|
|
193349
193539
|
function isIdentifierSegment(key) {
|
|
193350
193540
|
return /^[A-Z_]\w*$/i.test(key);
|
|
193351
193541
|
}
|
|
193352
|
-
function isSafeUnquoted(value2,
|
|
193542
|
+
function isSafeUnquoted(value2, delimiter3 = DEFAULT_DELIMITER) {
|
|
193353
193543
|
if (!value2) return false;
|
|
193354
193544
|
if (value2 !== value2.trim()) return false;
|
|
193355
193545
|
if (isBooleanOrNullLiteral(value2) || isNumericLike(value2)) return false;
|
|
@@ -193357,7 +193547,7 @@ function isSafeUnquoted(value2, delimiter2 = DEFAULT_DELIMITER) {
|
|
|
193357
193547
|
if (value2.includes('"') || value2.includes("\\")) return false;
|
|
193358
193548
|
if (/[[\]{}]/.test(value2)) return false;
|
|
193359
193549
|
if (/[\n\r\t]/.test(value2)) return false;
|
|
193360
|
-
if (value2.includes(
|
|
193550
|
+
if (value2.includes(delimiter3)) return false;
|
|
193361
193551
|
if (value2.startsWith(LIST_ITEM_MARKER)) return false;
|
|
193362
193552
|
return true;
|
|
193363
193553
|
}
|
|
@@ -193408,33 +193598,33 @@ function collectSingleKeyChain(startKey, startValue, maxDepth) {
|
|
|
193408
193598
|
function buildFoldedKey(segments) {
|
|
193409
193599
|
return segments.join(DOT);
|
|
193410
193600
|
}
|
|
193411
|
-
function encodePrimitive(value2,
|
|
193601
|
+
function encodePrimitive(value2, delimiter3) {
|
|
193412
193602
|
if (value2 === null) return NULL_LITERAL;
|
|
193413
193603
|
if (typeof value2 === "boolean") return String(value2);
|
|
193414
193604
|
if (typeof value2 === "number") return String(value2);
|
|
193415
|
-
return encodeStringLiteral(value2,
|
|
193605
|
+
return encodeStringLiteral(value2, delimiter3);
|
|
193416
193606
|
}
|
|
193417
|
-
function encodeStringLiteral(value2,
|
|
193418
|
-
if (isSafeUnquoted(value2,
|
|
193607
|
+
function encodeStringLiteral(value2, delimiter3 = DEFAULT_DELIMITER) {
|
|
193608
|
+
if (isSafeUnquoted(value2, delimiter3)) return value2;
|
|
193419
193609
|
return `${DOUBLE_QUOTE}${escapeString(value2)}${DOUBLE_QUOTE}`;
|
|
193420
193610
|
}
|
|
193421
193611
|
function encodeKey(key) {
|
|
193422
193612
|
if (isValidUnquotedKey(key)) return key;
|
|
193423
193613
|
return `${DOUBLE_QUOTE}${escapeString(key)}${DOUBLE_QUOTE}`;
|
|
193424
193614
|
}
|
|
193425
|
-
function encodeAndJoinPrimitives(values,
|
|
193426
|
-
return values.map((v) => encodePrimitive(v,
|
|
193615
|
+
function encodeAndJoinPrimitives(values, delimiter3 = DEFAULT_DELIMITER) {
|
|
193616
|
+
return values.map((v) => encodePrimitive(v, delimiter3)).join(delimiter3);
|
|
193427
193617
|
}
|
|
193428
193618
|
function formatHeader(length, options) {
|
|
193429
193619
|
const key = options?.key;
|
|
193430
193620
|
const fields = options?.fields;
|
|
193431
|
-
const
|
|
193621
|
+
const delimiter3 = options?.delimiter ?? COMMA2;
|
|
193432
193622
|
let header = "";
|
|
193433
193623
|
if (key) header += encodeKey(key);
|
|
193434
|
-
header += `[${length}${
|
|
193624
|
+
header += `[${length}${delimiter3 !== DEFAULT_DELIMITER ? delimiter3 : ""}]`;
|
|
193435
193625
|
if (fields) {
|
|
193436
193626
|
const quotedFields = fields.map((f) => encodeKey(f));
|
|
193437
|
-
header += `{${quotedFields.join(
|
|
193627
|
+
header += `{${quotedFields.join(delimiter3)}}`;
|
|
193438
193628
|
}
|
|
193439
193629
|
header += ":";
|
|
193440
193630
|
return header;
|
|
@@ -193527,12 +193717,12 @@ function* encodeArrayOfArraysAsListItemsLines(prefix, values, depth, options) {
|
|
|
193527
193717
|
yield indentedListItem(depth + 1, arrayLine, options.indent);
|
|
193528
193718
|
}
|
|
193529
193719
|
}
|
|
193530
|
-
function encodeInlineArrayLine(values,
|
|
193720
|
+
function encodeInlineArrayLine(values, delimiter3, prefix) {
|
|
193531
193721
|
const header = formatHeader(values.length, {
|
|
193532
193722
|
key: prefix,
|
|
193533
|
-
delimiter:
|
|
193723
|
+
delimiter: delimiter3
|
|
193534
193724
|
});
|
|
193535
|
-
const joinedValue = encodeAndJoinPrimitives(values,
|
|
193725
|
+
const joinedValue = encodeAndJoinPrimitives(values, delimiter3);
|
|
193536
193726
|
if (values.length === 0) return header;
|
|
193537
193727
|
return `${header} ${joinedValue}`;
|
|
193538
193728
|
}
|
|
@@ -196951,14 +197141,14 @@ function ReopenCurrentTool(ctx) {
|
|
|
196951
197141
|
import { performance as performance9 } from "node:perf_hooks";
|
|
196952
197142
|
|
|
196953
197143
|
// prep/installNodeDependencies.ts
|
|
196954
|
-
import { existsSync as
|
|
197144
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
196955
197145
|
import { join as join19 } from "node:path";
|
|
196956
197146
|
|
|
196957
197147
|
// utils/packageManager.ts
|
|
196958
197148
|
var import_semver2 = __toESM(require_semver2(), 1);
|
|
196959
|
-
import { existsSync as
|
|
197149
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
196960
197150
|
import { mkdir, readFile as readFile2 } from "node:fs/promises";
|
|
196961
|
-
import { delimiter, join as join18 } from "node:path";
|
|
197151
|
+
import { delimiter as delimiter2, join as join18 } from "node:path";
|
|
196962
197152
|
var SUPPORTED_NAMES = ["npm", "pnpm", "yarn", "bun"];
|
|
196963
197153
|
var COREPACK_MANAGED = ["pnpm", "yarn"];
|
|
196964
197154
|
function isSupported(name) {
|
|
@@ -196997,7 +197187,7 @@ function parseDevEnginesField(field) {
|
|
|
196997
197187
|
}
|
|
196998
197188
|
async function resolvePackageManagerSpec(cwd) {
|
|
196999
197189
|
const pkgPath = join18(cwd, "package.json");
|
|
197000
|
-
if (!
|
|
197190
|
+
if (!existsSync8(pkgPath)) return null;
|
|
197001
197191
|
let pkg;
|
|
197002
197192
|
try {
|
|
197003
197193
|
pkg = JSON.parse(await readFile2(pkgPath, "utf-8"));
|
|
@@ -197085,7 +197275,7 @@ async function ensurePackageManager(params) {
|
|
|
197085
197275
|
);
|
|
197086
197276
|
return false;
|
|
197087
197277
|
}
|
|
197088
|
-
process.env.PATH = `${params.binDir}${
|
|
197278
|
+
process.env.PATH = `${params.binDir}${delimiter2}${process.env.PATH ?? ""}`;
|
|
197089
197279
|
const prepare = await runCorepack(["prepare", `${spec.name}@${spec.version}`, "--activate"]);
|
|
197090
197280
|
if (prepare.exitCode !== 0) {
|
|
197091
197281
|
log2.warning(
|
|
@@ -197152,7 +197342,7 @@ var installNodeDependencies = {
|
|
|
197152
197342
|
name: "installNodeDependencies",
|
|
197153
197343
|
shouldRun: () => {
|
|
197154
197344
|
const packageJsonPath = join19(process.cwd(), "package.json");
|
|
197155
|
-
return
|
|
197345
|
+
return existsSync9(packageJsonPath);
|
|
197156
197346
|
},
|
|
197157
197347
|
run: async (options) => {
|
|
197158
197348
|
const declared = await resolvePackageManagerSpec(process.cwd());
|
|
@@ -197246,14 +197436,14 @@ ${errorMessage}`]
|
|
|
197246
197436
|
};
|
|
197247
197437
|
|
|
197248
197438
|
// prep/installPythonDependencies.ts
|
|
197249
|
-
import { existsSync as
|
|
197439
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6 } from "node:fs";
|
|
197250
197440
|
import { join as join20 } from "node:path";
|
|
197251
197441
|
function declaresBuildSystem(path4) {
|
|
197252
197442
|
return /^\s*\[\s*build-system\s*\]/m.test(readFileSync6(path4, "utf8"));
|
|
197253
197443
|
}
|
|
197254
197444
|
function configApplies(config3, cwd) {
|
|
197255
197445
|
const path4 = join20(cwd, config3.file);
|
|
197256
|
-
return
|
|
197446
|
+
return existsSync10(path4) && (config3.applies?.(path4) ?? true);
|
|
197257
197447
|
}
|
|
197258
197448
|
var PYTHON_CONFIGS = [
|
|
197259
197449
|
{
|
|
@@ -200121,7 +200311,7 @@ function validateAgentApiKey(params) {
|
|
|
200121
200311
|
}
|
|
200122
200312
|
function isApiKeyAuthError(text) {
|
|
200123
200313
|
if (!text) return false;
|
|
200124
|
-
return text.includes(MISSING_KEY_MARKER) || /Invalid API key/i.test(text) || /Incorrect API key provided/i.test(text) || /\bUser not found\b/i.test(text) || /\bInvalid authentication\b/i.test(text) || /authentication_error/i.test(text) || /Invalid bearer token/i.test(text) || /api_error_status\s*=\s*401/i.test(text) || /API Error:\s*401/i.test(text) || /Failed to authenticate\. API Error:/i.test(text) || /Your api key:.*is invalid/i.test(text) || isMalformedKeyError(text) || isClaudeSubscriptionDisabledError(text) || isClaudeSessionLimitError(text) || isOAuthCredentialExpiredError(text);
|
|
200314
|
+
return text.includes(MISSING_KEY_MARKER) || /Invalid API key/i.test(text) || /Incorrect API key provided/i.test(text) || /\bUser not found\b/i.test(text) || /\bInvalid authentication\b/i.test(text) || /authentication_error/i.test(text) || /Invalid bearer token/i.test(text) || /api_error_status\s*=\s*401/i.test(text) || /API Error:\s*401/i.test(text) || /Failed to authenticate\. API Error:/i.test(text) || /Your api key:.*is invalid/i.test(text) || isMalformedKeyError(text) || isClaudeSubscriptionDisabledError(text) || isKimiPlanTierError(text) || isClaudeSessionLimitError(text) || isOAuthCredentialExpiredError(text);
|
|
200125
200315
|
}
|
|
200126
200316
|
function isOAuthCredentialExpiredError(text) {
|
|
200127
200317
|
return (
|
|
@@ -200142,6 +200332,9 @@ function isMalformedKeyError(text) {
|
|
|
200142
200332
|
function isClaudeSubscriptionDisabledError(text) {
|
|
200143
200333
|
return /disabled Claude subscription access/i.test(text);
|
|
200144
200334
|
}
|
|
200335
|
+
function isKimiPlanTierError(text) {
|
|
200336
|
+
return /Your current (?:subscription does not have access to|plan supports only)\b/i.test(text);
|
|
200337
|
+
}
|
|
200145
200338
|
var CLAUDE_SESSION_LIMIT_PATTERN = /hit your (?:session|weekly|five-hour|Opus|Sonnet|Haiku)\s+limit(?:\s*·\s*resets\s+([^"\n]+))?/i;
|
|
200146
200339
|
function isClaudeSessionLimitError(text) {
|
|
200147
200340
|
return CLAUDE_SESSION_LIMIT_PATTERN.test(text);
|
|
@@ -200215,6 +200408,13 @@ function formatApiKeyErrorSummary(params) {
|
|
|
200215
200408
|
`[Add repo secret \u2192](${githubSecretsUrl}) \xB7 [Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/keys) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`
|
|
200216
200409
|
].join("\n");
|
|
200217
200410
|
}
|
|
200411
|
+
if (isKimiPlanTierError(params.raw)) {
|
|
200412
|
+
return [
|
|
200413
|
+
"**Your Kimi membership doesn't include the model this run asked for.** Kimi K3 needs a Moderato plan or above, and K3's 1M context and Kimi K2 HighSpeed need Allegretto or above. Upgrade the membership, or switch this repo to **Kimi K2**, which every tier includes.",
|
|
200414
|
+
"",
|
|
200415
|
+
`[Kimi plans \u2192](https://www.kimi.com/membership/pricing) \xB7 [Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/kimi-code) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`
|
|
200416
|
+
].join("\n");
|
|
200417
|
+
}
|
|
200218
200418
|
if (isOAuthCredentialExpiredError(params.raw)) {
|
|
200219
200419
|
return [
|
|
200220
200420
|
`**Your provider OAuth credential has expired or been revoked.** Re-authenticate the provider connection (e.g. \`pullfrog auth claude\` / \`pullfrog auth codex\` / \`pullfrog auth grok\`), then re-trigger the run.`,
|
|
@@ -203860,7 +204060,7 @@ ${instructions.user}` : null,
|
|
|
203860
204060
|
});
|
|
203861
204061
|
if (agentId === "opencode") {
|
|
203862
204062
|
const pluginDir = join28(process.cwd(), ".opencode", "plugin");
|
|
203863
|
-
const hasPlugins =
|
|
204063
|
+
const hasPlugins = existsSync11(pluginDir) && readdirSync2(pluginDir).some((f) => /\.[jt]sx?$/.test(f));
|
|
203864
204064
|
if (hasPlugins && toolState.dependencyInstallation?.promise) {
|
|
203865
204065
|
log2.info(
|
|
203866
204066
|
"\xBB .opencode/plugin/ detected \u2014 awaiting dependency installation before agent start"
|
|
@@ -204597,7 +204797,7 @@ function resolveTarget(repo) {
|
|
|
204597
204797
|
return { owner: match3[1], repo: match3[2] };
|
|
204598
204798
|
}
|
|
204599
204799
|
function cliVersion() {
|
|
204600
|
-
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.
|
|
204800
|
+
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.67");
|
|
204601
204801
|
if (!parts) return "0.0.0";
|
|
204602
204802
|
return `${Number(parts[1])}.${Number(parts[2])}.${Number(parts[3])}`;
|
|
204603
204803
|
}
|
|
@@ -204764,7 +204964,7 @@ async function runCli5(input2) {
|
|
|
204764
204964
|
}
|
|
204765
204965
|
|
|
204766
204966
|
// cli.ts
|
|
204767
|
-
var VERSION10 = "0.1.
|
|
204967
|
+
var VERSION10 = "0.1.67";
|
|
204768
204968
|
var bin = basename2(process.argv[1] || "");
|
|
204769
204969
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
204770
204970
|
var rawArgs = process.argv.slice(2);
|
package/dist/index.js
CHANGED
|
@@ -108042,6 +108042,69 @@ var providers = {
|
|
|
108042
108042
|
}
|
|
108043
108043
|
}
|
|
108044
108044
|
}),
|
|
108045
|
+
// the same models as `moonshotai` above, billed against a Kimi membership
|
|
108046
|
+
// instead of a Moonshot API balance — a separate endpoint, separate model
|
|
108047
|
+
// ids and a separate key, which is why it is a provider rather than a second
|
|
108048
|
+
// `envVars` entry. no provider injection is needed: models.dev carries
|
|
108049
|
+
// `kimi-for-coding` (api `https://api.kimi.com/coding/v1`, npm
|
|
108050
|
+
// `@ai-sdk/anthropic`) and opencode's env loop enables it from a bare
|
|
108051
|
+
// `KIMI_API_KEY`, verified against our pinned opencode-ai@1.18.5 — all four
|
|
108052
|
+
// ids list in `opencode models` and a run reaches Kimi's own auth check.
|
|
108053
|
+
//
|
|
108054
|
+
// NO `openRouterResolve` ON PURPOSE. OpenRouter cannot serve a Kimi
|
|
108055
|
+
// membership, so a Router path here would silently bill the wallet for
|
|
108056
|
+
// Moonshot pay-as-you-go under a slug picked for the opposite reason. The
|
|
108057
|
+
// absence is load-bearing: `isCardGatedModel` reads it as "not Router-
|
|
108058
|
+
// resolvable", `decideModelAccess` answers an explicit pick with the
|
|
108059
|
+
// `router` copy ("add your own provider key"), and run-context clamps a
|
|
108060
|
+
// keyless Router pick to the default subsidy model with `noRouterPath`.
|
|
108061
|
+
"kimi-for-coding": provider({
|
|
108062
|
+
// "Kimi Code" is the product name on kimi.com/code and in the console the
|
|
108063
|
+
// key is minted from. The provider KEY has to stay `kimi-for-coding` — it
|
|
108064
|
+
// is models.dev's id, so it is what `enabled_providers` and every
|
|
108065
|
+
// `resolve` prefix must spell.
|
|
108066
|
+
displayName: "Kimi Code",
|
|
108067
|
+
envVars: ["KIMI_API_KEY"],
|
|
108068
|
+
models: {
|
|
108069
|
+
// the tier each model needs is in `description` because Kimi answers an
|
|
108070
|
+
// out-of-tier request with 401 — indistinguishable from a bad key by
|
|
108071
|
+
// status alone, and only `isKimiPlanTierError` tells them apart after the
|
|
108072
|
+
// fact. saying it in the picker is the half that stops the run happening.
|
|
108073
|
+
"kimi-k3": {
|
|
108074
|
+
displayName: "Kimi K3",
|
|
108075
|
+
description: "1M context, but only on Allegretto and above \xB7 Moderato caps it at 256K",
|
|
108076
|
+
resolve: "kimi-for-coding/k3",
|
|
108077
|
+
effort: ["low", "high", "max"],
|
|
108078
|
+
subagentModel: "kimi-k2"
|
|
108079
|
+
},
|
|
108080
|
+
// `preferred` sits on the 256K variant rather than the 1M flagship, which
|
|
108081
|
+
// inverts the usual "top tier wins" rule for a reason specific to Kimi:
|
|
108082
|
+
// below Allegretto the two are the SAME 256K ceiling and `k3` charges
|
|
108083
|
+
// roughly double the quota for it, so on the median tier the flagship is
|
|
108084
|
+
// strictly dominated rather than merely pricier. This flag seeds the
|
|
108085
|
+
// onboarding pick (`getRecommendedSlug`) and wins key-only auto-select
|
|
108086
|
+
// (`autoSelectModel`), which are exactly the two moments nobody has
|
|
108087
|
+
// chosen yet.
|
|
108088
|
+
"kimi-k3-256k": {
|
|
108089
|
+
displayName: "Kimi K3 256K",
|
|
108090
|
+
description: "Same model at 256K for ~half the quota \xB7 Moderato or above",
|
|
108091
|
+
resolve: "kimi-for-coding/k3-256k",
|
|
108092
|
+
effort: ["low", "high", "max"],
|
|
108093
|
+
preferred: true,
|
|
108094
|
+
subagentModel: "kimi-k2"
|
|
108095
|
+
},
|
|
108096
|
+
"kimi-k2": {
|
|
108097
|
+
displayName: "Kimi K2",
|
|
108098
|
+
description: "Included in every Kimi membership tier",
|
|
108099
|
+
resolve: "kimi-for-coding/kimi-for-coding"
|
|
108100
|
+
},
|
|
108101
|
+
"kimi-k2-highspeed": {
|
|
108102
|
+
displayName: "Kimi K2 HighSpeed",
|
|
108103
|
+
description: "~6x output speed for ~3x quota \xB7 needs Allegretto or above",
|
|
108104
|
+
resolve: "kimi-for-coding/kimi-for-coding-highspeed"
|
|
108105
|
+
}
|
|
108106
|
+
}
|
|
108107
|
+
}),
|
|
108045
108108
|
opencode: provider({
|
|
108046
108109
|
displayName: "OpenCode Zen",
|
|
108047
108110
|
envVars: ["OPENCODE_API_KEY"],
|
|
@@ -108594,6 +108657,80 @@ var providers = {
|
|
|
108594
108657
|
openRouterResolve: "openrouter/minimax/minimax-m3"
|
|
108595
108658
|
}
|
|
108596
108659
|
}
|
|
108660
|
+
}),
|
|
108661
|
+
vercel: provider({
|
|
108662
|
+
// Vercel AI Gateway — one key serves every model it fronts. model IDs use
|
|
108663
|
+
// the models.dev `vercel` catalog's own naming (dotted versions, e.g.
|
|
108664
|
+
// `anthropic/claude-opus-5`, `zai/glm-5.3`), and effort ladders mirror that
|
|
108665
|
+
// catalog's entries, not the upstream vendor's. deliberately no
|
|
108666
|
+
// `openRouterResolve`: a gateway pick is BYOK-only — silently rerouting it
|
|
108667
|
+
// over the Router proxy would bill the wallet for traffic the user pointed
|
|
108668
|
+
// at their own gateway.
|
|
108669
|
+
displayName: "Vercel AI Gateway",
|
|
108670
|
+
envVars: ["AI_GATEWAY_API_KEY"],
|
|
108671
|
+
models: {
|
|
108672
|
+
"claude-opus": {
|
|
108673
|
+
displayName: "Claude Opus",
|
|
108674
|
+
resolve: "vercel/anthropic/claude-opus-5",
|
|
108675
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
108676
|
+
preferred: true,
|
|
108677
|
+
subagentModel: "claude-sonnet"
|
|
108678
|
+
},
|
|
108679
|
+
"claude-sonnet": {
|
|
108680
|
+
displayName: "Claude Sonnet",
|
|
108681
|
+
resolve: "vercel/anthropic/claude-sonnet-5",
|
|
108682
|
+
effort: ["low", "medium", "high", "xhigh"]
|
|
108683
|
+
},
|
|
108684
|
+
"claude-haiku": {
|
|
108685
|
+
displayName: "Claude Haiku",
|
|
108686
|
+
resolve: "vercel/anthropic/claude-haiku-4.5"
|
|
108687
|
+
},
|
|
108688
|
+
"gpt-sol": {
|
|
108689
|
+
displayName: "GPT Sol",
|
|
108690
|
+
resolve: "vercel/openai/gpt-5.6-sol",
|
|
108691
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
108692
|
+
subagentModel: "gpt-terra"
|
|
108693
|
+
},
|
|
108694
|
+
"gpt-terra": {
|
|
108695
|
+
displayName: "GPT Terra",
|
|
108696
|
+
resolve: "vercel/openai/gpt-5.6-terra",
|
|
108697
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"]
|
|
108698
|
+
},
|
|
108699
|
+
"gpt-luna": {
|
|
108700
|
+
displayName: "GPT Luna",
|
|
108701
|
+
resolve: "vercel/openai/gpt-5.6-luna",
|
|
108702
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"]
|
|
108703
|
+
},
|
|
108704
|
+
"gemini-pro": {
|
|
108705
|
+
displayName: "Gemini Pro",
|
|
108706
|
+
resolve: "vercel/google/gemini-3.1-pro-preview",
|
|
108707
|
+
effort: ["low", "medium", "high"]
|
|
108708
|
+
},
|
|
108709
|
+
"gemini-flash": {
|
|
108710
|
+
displayName: "Gemini Flash",
|
|
108711
|
+
resolve: "vercel/google/gemini-3.6-flash",
|
|
108712
|
+
effort: ["minimal", "low", "medium", "high"]
|
|
108713
|
+
},
|
|
108714
|
+
"deepseek-pro": {
|
|
108715
|
+
displayName: "DeepSeek Pro",
|
|
108716
|
+
resolve: "vercel/deepseek/deepseek-v4-pro-0813",
|
|
108717
|
+
effort: ["high", "xhigh"]
|
|
108718
|
+
},
|
|
108719
|
+
"deepseek-flash": {
|
|
108720
|
+
displayName: "DeepSeek Flash",
|
|
108721
|
+
resolve: "vercel/deepseek/deepseek-v4-flash",
|
|
108722
|
+
effort: ["high", "xhigh"]
|
|
108723
|
+
},
|
|
108724
|
+
glm: {
|
|
108725
|
+
displayName: "GLM",
|
|
108726
|
+
resolve: "vercel/zai/glm-5.3",
|
|
108727
|
+
effort: ["low", "high", "max"]
|
|
108728
|
+
},
|
|
108729
|
+
"kimi-k3": {
|
|
108730
|
+
displayName: "Kimi K3",
|
|
108731
|
+
resolve: "vercel/moonshotai/kimi-k3"
|
|
108732
|
+
}
|
|
108733
|
+
}
|
|
108597
108734
|
})
|
|
108598
108735
|
};
|
|
108599
108736
|
function parseModel(slug2) {
|
|
@@ -109552,7 +109689,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
109552
109689
|
// package.json
|
|
109553
109690
|
var package_default = {
|
|
109554
109691
|
name: "pullfrog",
|
|
109555
|
-
version: "0.1.
|
|
109692
|
+
version: "0.1.67",
|
|
109556
109693
|
type: "module",
|
|
109557
109694
|
bin: {
|
|
109558
109695
|
pullfrog: "dist/cli.mjs",
|
|
@@ -197757,7 +197894,7 @@ function validateAgentApiKey(params) {
|
|
|
197757
197894
|
}
|
|
197758
197895
|
function isApiKeyAuthError(text) {
|
|
197759
197896
|
if (!text) return false;
|
|
197760
|
-
return text.includes(MISSING_KEY_MARKER) || /Invalid API key/i.test(text) || /Incorrect API key provided/i.test(text) || /\bUser not found\b/i.test(text) || /\bInvalid authentication\b/i.test(text) || /authentication_error/i.test(text) || /Invalid bearer token/i.test(text) || /api_error_status\s*=\s*401/i.test(text) || /API Error:\s*401/i.test(text) || /Failed to authenticate\. API Error:/i.test(text) || /Your api key:.*is invalid/i.test(text) || isMalformedKeyError(text) || isClaudeSubscriptionDisabledError(text) || isClaudeSessionLimitError(text) || isOAuthCredentialExpiredError(text);
|
|
197897
|
+
return text.includes(MISSING_KEY_MARKER) || /Invalid API key/i.test(text) || /Incorrect API key provided/i.test(text) || /\bUser not found\b/i.test(text) || /\bInvalid authentication\b/i.test(text) || /authentication_error/i.test(text) || /Invalid bearer token/i.test(text) || /api_error_status\s*=\s*401/i.test(text) || /API Error:\s*401/i.test(text) || /Failed to authenticate\. API Error:/i.test(text) || /Your api key:.*is invalid/i.test(text) || isMalformedKeyError(text) || isClaudeSubscriptionDisabledError(text) || isKimiPlanTierError(text) || isClaudeSessionLimitError(text) || isOAuthCredentialExpiredError(text);
|
|
197761
197898
|
}
|
|
197762
197899
|
function isOAuthCredentialExpiredError(text) {
|
|
197763
197900
|
return (
|
|
@@ -197778,6 +197915,9 @@ function isMalformedKeyError(text) {
|
|
|
197778
197915
|
function isClaudeSubscriptionDisabledError(text) {
|
|
197779
197916
|
return /disabled Claude subscription access/i.test(text);
|
|
197780
197917
|
}
|
|
197918
|
+
function isKimiPlanTierError(text) {
|
|
197919
|
+
return /Your current (?:subscription does not have access to|plan supports only)\b/i.test(text);
|
|
197920
|
+
}
|
|
197781
197921
|
var CLAUDE_SESSION_LIMIT_PATTERN = /hit your (?:session|weekly|five-hour|Opus|Sonnet|Haiku)\s+limit(?:\s*·\s*resets\s+([^"\n]+))?/i;
|
|
197782
197922
|
function isClaudeSessionLimitError(text) {
|
|
197783
197923
|
return CLAUDE_SESSION_LIMIT_PATTERN.test(text);
|
|
@@ -197851,6 +197991,13 @@ function formatApiKeyErrorSummary(params) {
|
|
|
197851
197991
|
`[Add repo secret \u2192](${githubSecretsUrl}) \xB7 [Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/keys) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`
|
|
197852
197992
|
].join("\n");
|
|
197853
197993
|
}
|
|
197994
|
+
if (isKimiPlanTierError(params.raw)) {
|
|
197995
|
+
return [
|
|
197996
|
+
"**Your Kimi membership doesn't include the model this run asked for.** Kimi K3 needs a Moderato plan or above, and K3's 1M context and Kimi K2 HighSpeed need Allegretto or above. Upgrade the membership, or switch this repo to **Kimi K2**, which every tier includes.",
|
|
197997
|
+
"",
|
|
197998
|
+
`[Kimi plans \u2192](https://www.kimi.com/membership/pricing) \xB7 [Model settings \u2192](${settingsUrl}) \xB7 [Setup docs \u2192](https://docs.pullfrog.com/kimi-code) \xB7 [Ask in Discord \u2192](https://discord.gg/8y96raFg8e)`
|
|
197999
|
+
].join("\n");
|
|
198000
|
+
}
|
|
197854
198001
|
if (isOAuthCredentialExpiredError(params.raw)) {
|
|
197855
198002
|
return [
|
|
197856
198003
|
`**Your provider OAuth credential has expired or been revoked.** Re-authenticate the provider connection (e.g. \`pullfrog auth claude\` / \`pullfrog auth codex\` / \`pullfrog auth grok\`), then re-trigger the run.`,
|
package/dist/internal.js
CHANGED
|
@@ -338,6 +338,69 @@ var providers = {
|
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
}),
|
|
341
|
+
// the same models as `moonshotai` above, billed against a Kimi membership
|
|
342
|
+
// instead of a Moonshot API balance — a separate endpoint, separate model
|
|
343
|
+
// ids and a separate key, which is why it is a provider rather than a second
|
|
344
|
+
// `envVars` entry. no provider injection is needed: models.dev carries
|
|
345
|
+
// `kimi-for-coding` (api `https://api.kimi.com/coding/v1`, npm
|
|
346
|
+
// `@ai-sdk/anthropic`) and opencode's env loop enables it from a bare
|
|
347
|
+
// `KIMI_API_KEY`, verified against our pinned opencode-ai@1.18.5 — all four
|
|
348
|
+
// ids list in `opencode models` and a run reaches Kimi's own auth check.
|
|
349
|
+
//
|
|
350
|
+
// NO `openRouterResolve` ON PURPOSE. OpenRouter cannot serve a Kimi
|
|
351
|
+
// membership, so a Router path here would silently bill the wallet for
|
|
352
|
+
// Moonshot pay-as-you-go under a slug picked for the opposite reason. The
|
|
353
|
+
// absence is load-bearing: `isCardGatedModel` reads it as "not Router-
|
|
354
|
+
// resolvable", `decideModelAccess` answers an explicit pick with the
|
|
355
|
+
// `router` copy ("add your own provider key"), and run-context clamps a
|
|
356
|
+
// keyless Router pick to the default subsidy model with `noRouterPath`.
|
|
357
|
+
"kimi-for-coding": provider({
|
|
358
|
+
// "Kimi Code" is the product name on kimi.com/code and in the console the
|
|
359
|
+
// key is minted from. The provider KEY has to stay `kimi-for-coding` — it
|
|
360
|
+
// is models.dev's id, so it is what `enabled_providers` and every
|
|
361
|
+
// `resolve` prefix must spell.
|
|
362
|
+
displayName: "Kimi Code",
|
|
363
|
+
envVars: ["KIMI_API_KEY"],
|
|
364
|
+
models: {
|
|
365
|
+
// the tier each model needs is in `description` because Kimi answers an
|
|
366
|
+
// out-of-tier request with 401 — indistinguishable from a bad key by
|
|
367
|
+
// status alone, and only `isKimiPlanTierError` tells them apart after the
|
|
368
|
+
// fact. saying it in the picker is the half that stops the run happening.
|
|
369
|
+
"kimi-k3": {
|
|
370
|
+
displayName: "Kimi K3",
|
|
371
|
+
description: "1M context, but only on Allegretto and above \xB7 Moderato caps it at 256K",
|
|
372
|
+
resolve: "kimi-for-coding/k3",
|
|
373
|
+
effort: ["low", "high", "max"],
|
|
374
|
+
subagentModel: "kimi-k2"
|
|
375
|
+
},
|
|
376
|
+
// `preferred` sits on the 256K variant rather than the 1M flagship, which
|
|
377
|
+
// inverts the usual "top tier wins" rule for a reason specific to Kimi:
|
|
378
|
+
// below Allegretto the two are the SAME 256K ceiling and `k3` charges
|
|
379
|
+
// roughly double the quota for it, so on the median tier the flagship is
|
|
380
|
+
// strictly dominated rather than merely pricier. This flag seeds the
|
|
381
|
+
// onboarding pick (`getRecommendedSlug`) and wins key-only auto-select
|
|
382
|
+
// (`autoSelectModel`), which are exactly the two moments nobody has
|
|
383
|
+
// chosen yet.
|
|
384
|
+
"kimi-k3-256k": {
|
|
385
|
+
displayName: "Kimi K3 256K",
|
|
386
|
+
description: "Same model at 256K for ~half the quota \xB7 Moderato or above",
|
|
387
|
+
resolve: "kimi-for-coding/k3-256k",
|
|
388
|
+
effort: ["low", "high", "max"],
|
|
389
|
+
preferred: true,
|
|
390
|
+
subagentModel: "kimi-k2"
|
|
391
|
+
},
|
|
392
|
+
"kimi-k2": {
|
|
393
|
+
displayName: "Kimi K2",
|
|
394
|
+
description: "Included in every Kimi membership tier",
|
|
395
|
+
resolve: "kimi-for-coding/kimi-for-coding"
|
|
396
|
+
},
|
|
397
|
+
"kimi-k2-highspeed": {
|
|
398
|
+
displayName: "Kimi K2 HighSpeed",
|
|
399
|
+
description: "~6x output speed for ~3x quota \xB7 needs Allegretto or above",
|
|
400
|
+
resolve: "kimi-for-coding/kimi-for-coding-highspeed"
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}),
|
|
341
404
|
opencode: provider({
|
|
342
405
|
displayName: "OpenCode Zen",
|
|
343
406
|
envVars: ["OPENCODE_API_KEY"],
|
|
@@ -890,6 +953,80 @@ var providers = {
|
|
|
890
953
|
openRouterResolve: "openrouter/minimax/minimax-m3"
|
|
891
954
|
}
|
|
892
955
|
}
|
|
956
|
+
}),
|
|
957
|
+
vercel: provider({
|
|
958
|
+
// Vercel AI Gateway — one key serves every model it fronts. model IDs use
|
|
959
|
+
// the models.dev `vercel` catalog's own naming (dotted versions, e.g.
|
|
960
|
+
// `anthropic/claude-opus-5`, `zai/glm-5.3`), and effort ladders mirror that
|
|
961
|
+
// catalog's entries, not the upstream vendor's. deliberately no
|
|
962
|
+
// `openRouterResolve`: a gateway pick is BYOK-only — silently rerouting it
|
|
963
|
+
// over the Router proxy would bill the wallet for traffic the user pointed
|
|
964
|
+
// at their own gateway.
|
|
965
|
+
displayName: "Vercel AI Gateway",
|
|
966
|
+
envVars: ["AI_GATEWAY_API_KEY"],
|
|
967
|
+
models: {
|
|
968
|
+
"claude-opus": {
|
|
969
|
+
displayName: "Claude Opus",
|
|
970
|
+
resolve: "vercel/anthropic/claude-opus-5",
|
|
971
|
+
effort: ["low", "medium", "high", "xhigh", "max"],
|
|
972
|
+
preferred: true,
|
|
973
|
+
subagentModel: "claude-sonnet"
|
|
974
|
+
},
|
|
975
|
+
"claude-sonnet": {
|
|
976
|
+
displayName: "Claude Sonnet",
|
|
977
|
+
resolve: "vercel/anthropic/claude-sonnet-5",
|
|
978
|
+
effort: ["low", "medium", "high", "xhigh"]
|
|
979
|
+
},
|
|
980
|
+
"claude-haiku": {
|
|
981
|
+
displayName: "Claude Haiku",
|
|
982
|
+
resolve: "vercel/anthropic/claude-haiku-4.5"
|
|
983
|
+
},
|
|
984
|
+
"gpt-sol": {
|
|
985
|
+
displayName: "GPT Sol",
|
|
986
|
+
resolve: "vercel/openai/gpt-5.6-sol",
|
|
987
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"],
|
|
988
|
+
subagentModel: "gpt-terra"
|
|
989
|
+
},
|
|
990
|
+
"gpt-terra": {
|
|
991
|
+
displayName: "GPT Terra",
|
|
992
|
+
resolve: "vercel/openai/gpt-5.6-terra",
|
|
993
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"]
|
|
994
|
+
},
|
|
995
|
+
"gpt-luna": {
|
|
996
|
+
displayName: "GPT Luna",
|
|
997
|
+
resolve: "vercel/openai/gpt-5.6-luna",
|
|
998
|
+
effort: ["none", "low", "medium", "high", "xhigh", "max"]
|
|
999
|
+
},
|
|
1000
|
+
"gemini-pro": {
|
|
1001
|
+
displayName: "Gemini Pro",
|
|
1002
|
+
resolve: "vercel/google/gemini-3.1-pro-preview",
|
|
1003
|
+
effort: ["low", "medium", "high"]
|
|
1004
|
+
},
|
|
1005
|
+
"gemini-flash": {
|
|
1006
|
+
displayName: "Gemini Flash",
|
|
1007
|
+
resolve: "vercel/google/gemini-3.6-flash",
|
|
1008
|
+
effort: ["minimal", "low", "medium", "high"]
|
|
1009
|
+
},
|
|
1010
|
+
"deepseek-pro": {
|
|
1011
|
+
displayName: "DeepSeek Pro",
|
|
1012
|
+
resolve: "vercel/deepseek/deepseek-v4-pro-0813",
|
|
1013
|
+
effort: ["high", "xhigh"]
|
|
1014
|
+
},
|
|
1015
|
+
"deepseek-flash": {
|
|
1016
|
+
displayName: "DeepSeek Flash",
|
|
1017
|
+
resolve: "vercel/deepseek/deepseek-v4-flash",
|
|
1018
|
+
effort: ["high", "xhigh"]
|
|
1019
|
+
},
|
|
1020
|
+
glm: {
|
|
1021
|
+
displayName: "GLM",
|
|
1022
|
+
resolve: "vercel/zai/glm-5.3",
|
|
1023
|
+
effort: ["low", "high", "max"]
|
|
1024
|
+
},
|
|
1025
|
+
"kimi-k3": {
|
|
1026
|
+
displayName: "Kimi K3",
|
|
1027
|
+
resolve: "vercel/moonshotai/kimi-k3"
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
893
1030
|
})
|
|
894
1031
|
};
|
|
895
1032
|
function parseModel(slug) {
|
package/dist/models.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ export declare const providers: {
|
|
|
120
120
|
xai: ProviderConfig;
|
|
121
121
|
deepseek: ProviderConfig;
|
|
122
122
|
moonshotai: ProviderConfig;
|
|
123
|
+
"kimi-for-coding": ProviderConfig;
|
|
123
124
|
opencode: ProviderConfig;
|
|
124
125
|
"opencode-go": ProviderConfig;
|
|
125
126
|
bedrock: ProviderConfig;
|
|
@@ -127,6 +128,7 @@ export declare const providers: {
|
|
|
127
128
|
azure: ProviderConfig;
|
|
128
129
|
"openai-compatible": ProviderConfig;
|
|
129
130
|
openrouter: ProviderConfig;
|
|
131
|
+
vercel: ProviderConfig;
|
|
130
132
|
};
|
|
131
133
|
export type ModelProvider = keyof typeof providers;
|
|
132
134
|
export declare function parseModel(slug: string): {
|
package/dist/utils/apiKeys.d.ts
CHANGED
|
@@ -135,6 +135,21 @@ export declare function isMalformedKeyError(text: string): boolean;
|
|
|
135
135
|
* user controls fixes it, so it gets its own copy instead of the re-auth CTA.
|
|
136
136
|
*/
|
|
137
137
|
export declare function isClaudeSubscriptionDisabledError(text: string): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Kimi Code entitlement denial — the key is valid and the membership is live,
|
|
140
|
+
* but the tier doesn't include the model or the context window the run asked
|
|
141
|
+
* for (`k3` and `k3-256k` need Moderato, `kimi-for-coding-highspeed` and K3's
|
|
142
|
+
* 1M window need Allegretto). Kimi answers all of them with **401**, the same
|
|
143
|
+
* status as a revoked key, so nothing but the sentence tells them apart — and
|
|
144
|
+
* without that the run renders "rotate the key in your provider dashboard",
|
|
145
|
+
* which names three things that will not fix it.
|
|
146
|
+
*
|
|
147
|
+
* Both published shapes, parameterised over the clause that varies rather than
|
|
148
|
+
* the model id inside it, per `isOAuthCredentialExpiredError`. Listed in
|
|
149
|
+
* `isApiKeyAuthError` below so the branch is reachable whatever `type` Kimi
|
|
150
|
+
* puts in the payload. See wiki/kimi-code.md.
|
|
151
|
+
*/
|
|
152
|
+
export declare function isKimiPlanTierError(text: string): boolean;
|
|
138
153
|
export declare function isClaudeSessionLimitError(text: string): boolean;
|
|
139
154
|
/**
|
|
140
155
|
* The provider rejected a credential we checked before the agent started, and
|