zelari-code 1.37.0 → 1.41.0
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/cli/chatgptOAuth.js +142 -43
- package/dist/cli/chatgptOAuth.js.map +1 -1
- package/dist/cli/desktopConfig.js +8 -2
- package/dist/cli/desktopConfig.js.map +1 -1
- package/dist/cli/main.bundled.js +384 -124
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/modelDiscovery.js +22 -33
- package/dist/cli/modelDiscovery.js.map +1 -1
- package/dist/cli/oauthDesktop.js +3 -3
- package/dist/cli/provider/anthropic.js +1 -1
- package/dist/cli/provider/anthropic.js.map +1 -1
- package/dist/cli/provider/chatgpt.js +1 -1
- package/dist/cli/provider/chatgpt.js.map +1 -1
- package/dist/cli/provider/openai-compatible.js +1 -1
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/providerConfig.js +5 -5
- package/dist/cli/providerConfig.js.map +1 -1
- package/dist/cli/slashHandlers/provider.js +3 -3
- package/dist/cli/slashHandlers/provider.js.map +1 -1
- package/dist/cli/thinking.js +102 -43
- package/dist/cli/thinking.js.map +1 -1
- package/dist/cli/thinking.test.js +125 -4
- package/dist/cli/thinking.test.js.map +1 -1
- package/dist/cli/thinkingCapability.js +160 -0
- package/dist/cli/thinkingCapability.js.map +1 -0
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -794,16 +794,19 @@ __export(chatgptOAuth_exports, {
|
|
|
794
794
|
CHATGPT_DEVICE_CODE_URL: () => CHATGPT_DEVICE_CODE_URL,
|
|
795
795
|
CHATGPT_DEVICE_REDIRECT_URI: () => CHATGPT_DEVICE_REDIRECT_URI,
|
|
796
796
|
CHATGPT_DEVICE_TOKEN_URL: () => CHATGPT_DEVICE_TOKEN_URL,
|
|
797
|
+
CHATGPT_DEVICE_VERIFY_URL: () => CHATGPT_DEVICE_VERIFY_URL,
|
|
797
798
|
CHATGPT_SCOPE: () => CHATGPT_SCOPE,
|
|
798
799
|
CHATGPT_TOKEN_URL: () => CHATGPT_TOKEN_URL,
|
|
799
800
|
ChatgptOAuthError: () => ChatgptOAuthError,
|
|
800
801
|
DEFAULT_CHATGPT_CLIENT_ID: () => DEFAULT_CHATGPT_CLIENT_ID,
|
|
801
802
|
decodeJwtClaims: () => decodeJwtClaims,
|
|
802
803
|
extractChatgptAccountId: () => extractChatgptAccountId,
|
|
804
|
+
pollChatgptDeviceAuth: () => pollChatgptDeviceAuth,
|
|
803
805
|
refreshChatgptToken: () => refreshChatgptToken,
|
|
804
806
|
runChatgptBrowserFlow: () => runChatgptBrowserFlow,
|
|
805
807
|
runChatgptDeviceFlow: () => runChatgptDeviceFlow,
|
|
806
|
-
runChatgptOAuthFlow: () => runChatgptOAuthFlow
|
|
808
|
+
runChatgptOAuthFlow: () => runChatgptOAuthFlow,
|
|
809
|
+
startChatgptDeviceAuth: () => startChatgptDeviceAuth
|
|
807
810
|
});
|
|
808
811
|
function decodeJwtClaims(token) {
|
|
809
812
|
const parts = token.split(".");
|
|
@@ -845,6 +848,29 @@ function parseTokenPayload(obj, fallbackRefresh) {
|
|
|
845
848
|
}
|
|
846
849
|
return result;
|
|
847
850
|
}
|
|
851
|
+
function errorSnippet(body) {
|
|
852
|
+
const err = body.error;
|
|
853
|
+
if (typeof err === "string" && err.trim()) return err.trim().slice(0, 160);
|
|
854
|
+
if (err && typeof err === "object") {
|
|
855
|
+
const msg2 = err.message;
|
|
856
|
+
if (typeof msg2 === "string" && msg2.trim()) return msg2.trim().slice(0, 160);
|
|
857
|
+
}
|
|
858
|
+
const msg = body.message;
|
|
859
|
+
if (typeof msg === "string" && msg.trim()) return msg.trim().slice(0, 160);
|
|
860
|
+
return "";
|
|
861
|
+
}
|
|
862
|
+
function formatHttpError(prefix, status, body) {
|
|
863
|
+
const detail = errorSnippet(body);
|
|
864
|
+
return detail ? `${prefix} HTTP ${status}: ${detail}` : `${prefix} HTTP ${status}`;
|
|
865
|
+
}
|
|
866
|
+
async function readJsonBody(response) {
|
|
867
|
+
try {
|
|
868
|
+
const parsed = await response.json();
|
|
869
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
870
|
+
} catch {
|
|
871
|
+
}
|
|
872
|
+
return {};
|
|
873
|
+
}
|
|
848
874
|
async function postForm(url2, data, fetchImpl) {
|
|
849
875
|
let response;
|
|
850
876
|
try {
|
|
@@ -862,13 +888,34 @@ async function postForm(url2, data, fetchImpl) {
|
|
|
862
888
|
"network_error"
|
|
863
889
|
);
|
|
864
890
|
}
|
|
865
|
-
|
|
891
|
+
return { status: response.status, body: await readJsonBody(response) };
|
|
892
|
+
}
|
|
893
|
+
async function postJson(url2, data, fetchImpl) {
|
|
894
|
+
let response;
|
|
866
895
|
try {
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
896
|
+
response = await fetchImpl(url2, {
|
|
897
|
+
method: "POST",
|
|
898
|
+
headers: {
|
|
899
|
+
"Content-Type": "application/json",
|
|
900
|
+
Accept: "application/json"
|
|
901
|
+
},
|
|
902
|
+
body: JSON.stringify(data)
|
|
903
|
+
});
|
|
904
|
+
} catch (err) {
|
|
905
|
+
throw new ChatgptOAuthError(
|
|
906
|
+
`ChatGPT OAuth network error: ${err instanceof Error ? err.message : String(err)}`,
|
|
907
|
+
"network_error"
|
|
908
|
+
);
|
|
870
909
|
}
|
|
871
|
-
return { status: response.status, body };
|
|
910
|
+
return { status: response.status, body: await readJsonBody(response) };
|
|
911
|
+
}
|
|
912
|
+
function parsePollInterval(raw, fallback = 5) {
|
|
913
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return raw;
|
|
914
|
+
if (typeof raw === "string") {
|
|
915
|
+
const n = Number.parseInt(raw, 10);
|
|
916
|
+
if (Number.isFinite(n) && n > 0) return n;
|
|
917
|
+
}
|
|
918
|
+
return fallback;
|
|
872
919
|
}
|
|
873
920
|
async function refreshChatgptToken(options) {
|
|
874
921
|
if (!options.refreshToken.trim()) {
|
|
@@ -887,77 +934,82 @@ async function refreshChatgptToken(options) {
|
|
|
887
934
|
);
|
|
888
935
|
if (status >= 400) {
|
|
889
936
|
const code = status === 400 || status === 401 ? "invalid_grant" : `http_${status}`;
|
|
890
|
-
throw new ChatgptOAuthError(
|
|
891
|
-
`ChatGPT token refresh HTTP ${status}: ${String(body.error ?? "").slice(0, 160)}`,
|
|
892
|
-
code
|
|
893
|
-
);
|
|
937
|
+
throw new ChatgptOAuthError(formatHttpError("ChatGPT token refresh", status, body), code);
|
|
894
938
|
}
|
|
895
939
|
return parseTokenPayload(body, options.refreshToken);
|
|
896
940
|
}
|
|
897
|
-
async function
|
|
941
|
+
async function startChatgptDeviceAuth(options = {}) {
|
|
898
942
|
const clientId2 = options.clientId || process.env.CHATGPT_OAUTH_CLIENT_ID || DEFAULT_CHATGPT_CLIENT_ID;
|
|
899
943
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
900
|
-
const
|
|
901
|
-
const { verifier, challenge } = generatePkcePair();
|
|
902
|
-
const start = await postForm(
|
|
903
|
-
CHATGPT_DEVICE_CODE_URL,
|
|
904
|
-
{
|
|
905
|
-
client_id: clientId2,
|
|
906
|
-
scope: CHATGPT_SCOPE,
|
|
907
|
-
code_challenge: challenge,
|
|
908
|
-
code_challenge_method: "S256"
|
|
909
|
-
},
|
|
910
|
-
fetchImpl
|
|
911
|
-
);
|
|
944
|
+
const start = await postJson(CHATGPT_DEVICE_CODE_URL, { client_id: clientId2 }, fetchImpl);
|
|
912
945
|
if (start.status >= 400) {
|
|
913
946
|
throw new ChatgptOAuthError(
|
|
914
|
-
|
|
947
|
+
formatHttpError("ChatGPT device-code", start.status, start.body),
|
|
915
948
|
`device_http_${start.status}`
|
|
916
949
|
);
|
|
917
950
|
}
|
|
918
|
-
const
|
|
919
|
-
const userCode = start.body.user_code;
|
|
920
|
-
const verificationUri = typeof start.body.verification_uri === "string" && start.body.verification_uri || typeof start.body.
|
|
921
|
-
if (
|
|
951
|
+
const deviceAuthId = typeof start.body.device_auth_id === "string" && start.body.device_auth_id || typeof start.body.device_code === "string" && start.body.device_code || "";
|
|
952
|
+
const userCode = typeof start.body.user_code === "string" && start.body.user_code || typeof start.body.usercode === "string" && start.body.usercode || "";
|
|
953
|
+
const verificationUri = typeof start.body.verification_uri === "string" && start.body.verification_uri || typeof start.body.verification_url === "string" && start.body.verification_url || `${CHATGPT_DEVICE_VERIFY_URL}?user_code=${encodeURIComponent(userCode)}`;
|
|
954
|
+
if (!deviceAuthId || !userCode) {
|
|
922
955
|
throw new ChatgptOAuthError("Device-code response missing fields", "no_device_code");
|
|
923
956
|
}
|
|
924
|
-
|
|
957
|
+
return {
|
|
958
|
+
deviceAuthId,
|
|
925
959
|
userCode,
|
|
926
960
|
verificationUri,
|
|
961
|
+
interval: parsePollInterval(start.body.interval, 5),
|
|
927
962
|
...typeof start.body.verification_uri_complete === "string" ? { verificationUriComplete: start.body.verification_uri_complete } : {}
|
|
928
963
|
};
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
} catch {
|
|
935
|
-
}
|
|
964
|
+
}
|
|
965
|
+
async function pollChatgptDeviceAuth(options) {
|
|
966
|
+
const clientId2 = options.clientId || process.env.CHATGPT_OAUTH_CLIENT_ID || DEFAULT_CHATGPT_CLIENT_ID;
|
|
967
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
968
|
+
const sleep = options.sleepImpl ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
936
969
|
const timeoutMs = options.timeoutMs ?? 3e5;
|
|
937
970
|
const deadline = Date.now() + timeoutMs;
|
|
938
|
-
let interval = 5;
|
|
971
|
+
let interval = options.interval ?? 5;
|
|
939
972
|
let authorizationCode;
|
|
973
|
+
let codeVerifier;
|
|
940
974
|
while (Date.now() < deadline) {
|
|
941
|
-
const poll = await
|
|
975
|
+
const poll = await postJson(
|
|
942
976
|
CHATGPT_DEVICE_TOKEN_URL,
|
|
943
|
-
{
|
|
977
|
+
{ device_auth_id: options.deviceAuthId, user_code: options.userCode },
|
|
944
978
|
fetchImpl
|
|
945
979
|
);
|
|
946
980
|
const authCode = poll.body.authorization_code;
|
|
947
981
|
if (typeof authCode === "string" && authCode.length > 0) {
|
|
948
982
|
authorizationCode = authCode;
|
|
983
|
+
if (typeof poll.body.code_verifier === "string" && poll.body.code_verifier) {
|
|
984
|
+
codeVerifier = poll.body.code_verifier;
|
|
985
|
+
}
|
|
949
986
|
break;
|
|
950
987
|
}
|
|
988
|
+
if (poll.status === 403 || poll.status === 404) {
|
|
989
|
+
await sleep(interval * 1e3);
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
951
992
|
const err = typeof poll.body.error === "string" ? poll.body.error : "";
|
|
952
993
|
if (err === "slow_down") interval += 5;
|
|
953
994
|
else if (err && err !== "authorization_pending") {
|
|
954
995
|
throw new ChatgptOAuthError(`Device authorization failed: ${err}`, err);
|
|
996
|
+
} else if (poll.status >= 400) {
|
|
997
|
+
throw new ChatgptOAuthError(
|
|
998
|
+
formatHttpError("ChatGPT device poll", poll.status, poll.body),
|
|
999
|
+
`poll_http_${poll.status}`
|
|
1000
|
+
);
|
|
955
1001
|
}
|
|
956
1002
|
await sleep(interval * 1e3);
|
|
957
1003
|
}
|
|
958
1004
|
if (!authorizationCode) {
|
|
959
1005
|
throw new ChatgptOAuthError("Timed out waiting for ChatGPT device authorization", "timeout");
|
|
960
1006
|
}
|
|
1007
|
+
if (!codeVerifier) {
|
|
1008
|
+
throw new ChatgptOAuthError(
|
|
1009
|
+
"Device token response missing code_verifier (server-issued PKCE)",
|
|
1010
|
+
"no_code_verifier"
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
961
1013
|
const token = await postForm(
|
|
962
1014
|
CHATGPT_TOKEN_URL,
|
|
963
1015
|
{
|
|
@@ -965,13 +1017,13 @@ async function runChatgptDeviceFlow(options) {
|
|
|
965
1017
|
code: authorizationCode,
|
|
966
1018
|
redirect_uri: CHATGPT_DEVICE_REDIRECT_URI,
|
|
967
1019
|
client_id: clientId2,
|
|
968
|
-
code_verifier:
|
|
1020
|
+
code_verifier: codeVerifier
|
|
969
1021
|
},
|
|
970
1022
|
fetchImpl
|
|
971
1023
|
);
|
|
972
1024
|
if (token.status >= 400) {
|
|
973
1025
|
throw new ChatgptOAuthError(
|
|
974
|
-
|
|
1026
|
+
formatHttpError("ChatGPT token exchange", token.status, token.body),
|
|
975
1027
|
`token_http_${token.status}`
|
|
976
1028
|
);
|
|
977
1029
|
}
|
|
@@ -1024,12 +1076,47 @@ async function runChatgptBrowserFlow(options) {
|
|
|
1024
1076
|
);
|
|
1025
1077
|
if (token.status >= 400) {
|
|
1026
1078
|
throw new ChatgptOAuthError(
|
|
1027
|
-
|
|
1079
|
+
formatHttpError("ChatGPT token exchange", token.status, token.body),
|
|
1028
1080
|
`token_http_${token.status}`
|
|
1029
1081
|
);
|
|
1030
1082
|
}
|
|
1031
1083
|
return parseTokenPayload(token.body);
|
|
1032
1084
|
}
|
|
1085
|
+
async function runChatgptDeviceFlow(options = {}) {
|
|
1086
|
+
const session = await startChatgptDeviceAuth({
|
|
1087
|
+
clientId: options.clientId,
|
|
1088
|
+
fetchImpl: options.fetchImpl
|
|
1089
|
+
});
|
|
1090
|
+
const info = {
|
|
1091
|
+
userCode: session.userCode,
|
|
1092
|
+
verificationUri: session.verificationUri,
|
|
1093
|
+
...session.verificationUriComplete ? { verificationUriComplete: session.verificationUriComplete } : {}
|
|
1094
|
+
};
|
|
1095
|
+
if (options.onUserCode) {
|
|
1096
|
+
await options.onUserCode(info);
|
|
1097
|
+
} else {
|
|
1098
|
+
process.stderr.write(
|
|
1099
|
+
`[chatgpt oauth] Open ${info.verificationUri} and enter:
|
|
1100
|
+
${info.userCode}
|
|
1101
|
+
`
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
try {
|
|
1105
|
+
await (options.openBrowserImpl ?? openBrowser)(
|
|
1106
|
+
info.verificationUriComplete ?? info.verificationUri
|
|
1107
|
+
);
|
|
1108
|
+
} catch {
|
|
1109
|
+
}
|
|
1110
|
+
return pollChatgptDeviceAuth({
|
|
1111
|
+
deviceAuthId: session.deviceAuthId,
|
|
1112
|
+
userCode: session.userCode,
|
|
1113
|
+
clientId: options.clientId,
|
|
1114
|
+
interval: session.interval,
|
|
1115
|
+
fetchImpl: options.fetchImpl,
|
|
1116
|
+
sleepImpl: options.sleepImpl,
|
|
1117
|
+
timeoutMs: options.timeoutMs
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1033
1120
|
async function runChatgptOAuthFlow(options = {}) {
|
|
1034
1121
|
const flow = (process.env.CHATGPT_OAUTH_FLOW ?? "device").toLowerCase();
|
|
1035
1122
|
if (flow === "browser") {
|
|
@@ -1037,7 +1124,7 @@ async function runChatgptOAuthFlow(options = {}) {
|
|
|
1037
1124
|
}
|
|
1038
1125
|
return runChatgptDeviceFlow(options);
|
|
1039
1126
|
}
|
|
1040
|
-
var DEFAULT_CHATGPT_CLIENT_ID, CHATGPT_AUTHORIZE_URL, CHATGPT_TOKEN_URL, CHATGPT_DEVICE_CODE_URL, CHATGPT_DEVICE_TOKEN_URL, CHATGPT_DEVICE_REDIRECT_URI, CHATGPT_SCOPE, CHATGPT_AUTH_CLAIMS, ChatgptOAuthError;
|
|
1127
|
+
var DEFAULT_CHATGPT_CLIENT_ID, CHATGPT_AUTHORIZE_URL, CHATGPT_TOKEN_URL, CHATGPT_DEVICE_CODE_URL, CHATGPT_DEVICE_TOKEN_URL, CHATGPT_DEVICE_REDIRECT_URI, CHATGPT_DEVICE_VERIFY_URL, CHATGPT_SCOPE, CHATGPT_AUTH_CLAIMS, ChatgptOAuthError;
|
|
1041
1128
|
var init_chatgptOAuth = __esm({
|
|
1042
1129
|
"src/cli/chatgptOAuth.ts"() {
|
|
1043
1130
|
"use strict";
|
|
@@ -1049,6 +1136,7 @@ var init_chatgptOAuth = __esm({
|
|
|
1049
1136
|
CHATGPT_DEVICE_CODE_URL = "https://auth.openai.com/api/accounts/deviceauth/usercode";
|
|
1050
1137
|
CHATGPT_DEVICE_TOKEN_URL = "https://auth.openai.com/api/accounts/deviceauth/token";
|
|
1051
1138
|
CHATGPT_DEVICE_REDIRECT_URI = "https://auth.openai.com/deviceauth/callback";
|
|
1139
|
+
CHATGPT_DEVICE_VERIFY_URL = "https://auth.openai.com/codex/device";
|
|
1052
1140
|
CHATGPT_SCOPE = "openid profile email offline_access";
|
|
1053
1141
|
CHATGPT_AUTH_CLAIMS = "https://api.openai.com/auth";
|
|
1054
1142
|
ChatgptOAuthError = class extends Error {
|
|
@@ -1152,7 +1240,7 @@ async function startAnthropicOAuth(options = {}) {
|
|
|
1152
1240
|
}
|
|
1153
1241
|
return { authorizeUrl, state: state3 };
|
|
1154
1242
|
}
|
|
1155
|
-
async function
|
|
1243
|
+
async function postJson2(url2, payload, fetchImpl) {
|
|
1156
1244
|
let response;
|
|
1157
1245
|
try {
|
|
1158
1246
|
response = await fetchImpl(url2, {
|
|
@@ -1212,7 +1300,7 @@ async function completeAnthropicOAuth(options) {
|
|
|
1212
1300
|
redirect_uri: ANTHROPIC_REDIRECT_URI,
|
|
1213
1301
|
state: parsed.state ?? pending.state
|
|
1214
1302
|
};
|
|
1215
|
-
const { status, body } = await
|
|
1303
|
+
const { status, body } = await postJson2(ANTHROPIC_TOKEN_URL, payload, fetchImpl);
|
|
1216
1304
|
if (status >= 400) {
|
|
1217
1305
|
const code = status === 400 || status === 401 ? "invalid_grant" : `http_${status}`;
|
|
1218
1306
|
throw new AnthropicOAuthError(
|
|
@@ -1227,7 +1315,7 @@ async function refreshAnthropicToken(options) {
|
|
|
1227
1315
|
throw new AnthropicOAuthError("Missing refreshToken", "no_refresh_token");
|
|
1228
1316
|
}
|
|
1229
1317
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
1230
|
-
const { status, body } = await
|
|
1318
|
+
const { status, body } = await postJson2(
|
|
1231
1319
|
ANTHROPIC_TOKEN_URL,
|
|
1232
1320
|
{
|
|
1233
1321
|
grant_type: "refresh_token",
|
|
@@ -1532,9 +1620,151 @@ var init_keyStore = __esm({
|
|
|
1532
1620
|
}
|
|
1533
1621
|
});
|
|
1534
1622
|
|
|
1623
|
+
// src/cli/thinkingCapability.ts
|
|
1624
|
+
function thinkingCapabilityFor(id, model) {
|
|
1625
|
+
const base = PROVIDER_THINKING_CAPABILITY[id] ?? {};
|
|
1626
|
+
const efforts = effortLevelsFor(id, model);
|
|
1627
|
+
const budget = supportsBudget(id, model);
|
|
1628
|
+
return {
|
|
1629
|
+
...base,
|
|
1630
|
+
effort: efforts.length > 0 || Boolean(base.effort),
|
|
1631
|
+
budget,
|
|
1632
|
+
efforts: efforts.length > 0 ? efforts : void 0
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
function effortLevelsFor(id, model) {
|
|
1636
|
+
const m = (model ?? "").trim();
|
|
1637
|
+
switch (id) {
|
|
1638
|
+
case "grok":
|
|
1639
|
+
case "openai-compatible":
|
|
1640
|
+
case "custom":
|
|
1641
|
+
if (grokHasXhigh(m)) return [...BASE_EFFORTS, "xhigh"];
|
|
1642
|
+
return [...BASE_EFFORTS];
|
|
1643
|
+
case "chatgpt":
|
|
1644
|
+
if (gptHasMax(m)) return [...BASE_EFFORTS, "xhigh", "max"];
|
|
1645
|
+
if (gptHasXhigh(m)) return [...BASE_EFFORTS, "xhigh"];
|
|
1646
|
+
return [...BASE_EFFORTS];
|
|
1647
|
+
case "deepseek":
|
|
1648
|
+
return ["high", "max"];
|
|
1649
|
+
case "minimax":
|
|
1650
|
+
return [...BASE_EFFORTS];
|
|
1651
|
+
case "glm":
|
|
1652
|
+
if (glmHasEffortScale(m)) return ["low", "high", "max"];
|
|
1653
|
+
return [];
|
|
1654
|
+
case "anthropic":
|
|
1655
|
+
if (claudeHasXhigh(m)) return ["high", "xhigh", "max"];
|
|
1656
|
+
if (claudeHasMax(m)) return ["high", "max"];
|
|
1657
|
+
return [];
|
|
1658
|
+
default:
|
|
1659
|
+
return [];
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
function supportsBudget(id, model) {
|
|
1663
|
+
if (id === "anthropic") return true;
|
|
1664
|
+
if (id === "glm") return !glmHasEffortScale(model);
|
|
1665
|
+
return Boolean(PROVIDER_THINKING_CAPABILITY[id]?.budget);
|
|
1666
|
+
}
|
|
1667
|
+
function grokHasXhigh(model) {
|
|
1668
|
+
const v = parseDottedVersion(model, /grok[-_]?(\d+)(?:[.-](\d+))?/i);
|
|
1669
|
+
if (!v) return false;
|
|
1670
|
+
return v.major > 4 || v.major === 4 && v.minor >= 6;
|
|
1671
|
+
}
|
|
1672
|
+
function gptHasXhigh(model) {
|
|
1673
|
+
const v = parseDottedVersion(model, /gpt[-_]?(\d+)(?:[.-](\d+))?/i);
|
|
1674
|
+
if (!v) return false;
|
|
1675
|
+
return v.major > 5 || v.major === 5 && v.minor >= 4;
|
|
1676
|
+
}
|
|
1677
|
+
function gptHasMax(model) {
|
|
1678
|
+
const v = parseDottedVersion(model, /gpt[-_]?(\d+)(?:[.-](\d+))?/i);
|
|
1679
|
+
if (!v) return false;
|
|
1680
|
+
return v.major > 5 || v.major === 5 && v.minor >= 6;
|
|
1681
|
+
}
|
|
1682
|
+
function claudeHasMax(model) {
|
|
1683
|
+
const v = parseClaudeVersion(model);
|
|
1684
|
+
if (!v) return false;
|
|
1685
|
+
return v.major > 4 || v.major === 4 && v.minor >= 6;
|
|
1686
|
+
}
|
|
1687
|
+
function claudeHasXhigh(model) {
|
|
1688
|
+
const v = parseClaudeVersion(model);
|
|
1689
|
+
if (!v) return false;
|
|
1690
|
+
if (v.major >= 5) return true;
|
|
1691
|
+
return v.major === 4 && v.minor >= 7;
|
|
1692
|
+
}
|
|
1693
|
+
function glmHasEffortScale(model) {
|
|
1694
|
+
const v = parseDottedVersion(model ?? "", /glm[-_]?(\d+)(?:[.-](\d+))?/i);
|
|
1695
|
+
if (!v) return false;
|
|
1696
|
+
return v.major >= 5;
|
|
1697
|
+
}
|
|
1698
|
+
function parseDottedVersion(model, re) {
|
|
1699
|
+
const m = re.exec(model);
|
|
1700
|
+
if (!m) return null;
|
|
1701
|
+
return {
|
|
1702
|
+
major: Number.parseInt(m[1], 10),
|
|
1703
|
+
minor: m[2] ? Number.parseInt(m[2], 10) : 0
|
|
1704
|
+
};
|
|
1705
|
+
}
|
|
1706
|
+
function parseClaudeVersion(model) {
|
|
1707
|
+
const m = /claude-(?:sonnet|opus|haiku)[-_]?(\d+)(?:[.-](\d+))?/i.exec(model);
|
|
1708
|
+
if (!m) return null;
|
|
1709
|
+
return {
|
|
1710
|
+
major: Number.parseInt(m[1], 10),
|
|
1711
|
+
minor: m[2] ? Number.parseInt(m[2], 10) : 0
|
|
1712
|
+
};
|
|
1713
|
+
}
|
|
1714
|
+
var THINKING_EFFORTS, BASE_EFFORTS, PROVIDER_THINKING_CAPABILITY;
|
|
1715
|
+
var init_thinkingCapability = __esm({
|
|
1716
|
+
"src/cli/thinkingCapability.ts"() {
|
|
1717
|
+
"use strict";
|
|
1718
|
+
THINKING_EFFORTS = [
|
|
1719
|
+
"low",
|
|
1720
|
+
"medium",
|
|
1721
|
+
"high",
|
|
1722
|
+
"xhigh",
|
|
1723
|
+
"max"
|
|
1724
|
+
];
|
|
1725
|
+
BASE_EFFORTS = ["low", "medium", "high"];
|
|
1726
|
+
PROVIDER_THINKING_CAPABILITY = {
|
|
1727
|
+
"openai-compatible": { effort: true },
|
|
1728
|
+
grok: { effort: true },
|
|
1729
|
+
chatgpt: { effort: true },
|
|
1730
|
+
anthropic: { budget: true },
|
|
1731
|
+
glm: { budget: true },
|
|
1732
|
+
deepseek: { effort: true },
|
|
1733
|
+
minimax: { effort: true },
|
|
1734
|
+
custom: { effort: true }
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1738
|
+
|
|
1535
1739
|
// src/cli/thinking.ts
|
|
1536
|
-
function
|
|
1537
|
-
|
|
1740
|
+
function clampEffort(id, model, requested) {
|
|
1741
|
+
const native = effortLevelsFor(id, model);
|
|
1742
|
+
if (native.includes(requested)) {
|
|
1743
|
+
return { effort: requested, clamped: false };
|
|
1744
|
+
}
|
|
1745
|
+
if (native.length === 0) {
|
|
1746
|
+
return {
|
|
1747
|
+
effort: requested,
|
|
1748
|
+
clamped: true,
|
|
1749
|
+
note: `thinking '${requested}' is not supported for provider "${id}"`
|
|
1750
|
+
};
|
|
1751
|
+
}
|
|
1752
|
+
const want = EFFORT_RANK[requested];
|
|
1753
|
+
let best = native[0];
|
|
1754
|
+
let bestDist = Math.abs(EFFORT_RANK[best] - want);
|
|
1755
|
+
for (const level of native) {
|
|
1756
|
+
const dist = Math.abs(EFFORT_RANK[level] - want);
|
|
1757
|
+
if (dist < bestDist || dist === bestDist && EFFORT_RANK[level] > EFFORT_RANK[best]) {
|
|
1758
|
+
best = level;
|
|
1759
|
+
bestDist = dist;
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
const label = model ? `${id}/${model}` : id;
|
|
1763
|
+
return {
|
|
1764
|
+
effort: best,
|
|
1765
|
+
clamped: true,
|
|
1766
|
+
note: `'${requested}' is not native on ${label} \u2014 using '${best}'`
|
|
1767
|
+
};
|
|
1538
1768
|
}
|
|
1539
1769
|
function stringifyThinkingSpec(spec) {
|
|
1540
1770
|
if (spec === "auto") return "auto";
|
|
@@ -1546,7 +1776,9 @@ function parseThinkingSpec(raw) {
|
|
|
1546
1776
|
const s = (raw ?? "").trim().toLowerCase();
|
|
1547
1777
|
if (!s || s === "auto") return "auto";
|
|
1548
1778
|
if (s === "off") return { kind: "off" };
|
|
1549
|
-
if (s
|
|
1779
|
+
if (THINKING_EFFORTS.includes(s)) {
|
|
1780
|
+
return { kind: "effort", effort: s };
|
|
1781
|
+
}
|
|
1550
1782
|
const m = /^budget:(\d+)$/.exec(s);
|
|
1551
1783
|
if (m) {
|
|
1552
1784
|
const n = Number.parseInt(m[1], 10);
|
|
@@ -1556,15 +1788,19 @@ function parseThinkingSpec(raw) {
|
|
|
1556
1788
|
}
|
|
1557
1789
|
function isValidThinkingInput(raw) {
|
|
1558
1790
|
const s = raw.trim().toLowerCase();
|
|
1559
|
-
if (s === "auto" || s === "off"
|
|
1791
|
+
if (s === "auto" || s === "off") return true;
|
|
1792
|
+
if (THINKING_EFFORTS.includes(s)) return true;
|
|
1560
1793
|
return /^budget:\d+$/.test(s) && Number.parseInt(s.slice(7), 10) > 0;
|
|
1561
1794
|
}
|
|
1562
1795
|
function degrade(note) {
|
|
1563
1796
|
return { patch: {}, degraded: true, note };
|
|
1564
1797
|
}
|
|
1565
|
-
function
|
|
1798
|
+
function withClampNote(patch, clamped, note) {
|
|
1799
|
+
return { patch, degraded: false, note: clamped ? note : void 0 };
|
|
1800
|
+
}
|
|
1801
|
+
function translateOpenAiCompatibleThinking(providerId, spec, model) {
|
|
1566
1802
|
if (spec === "auto") return { patch: {}, degraded: false };
|
|
1567
|
-
const cap3 = thinkingCapabilityFor(providerId);
|
|
1803
|
+
const cap3 = thinkingCapabilityFor(providerId, model);
|
|
1568
1804
|
switch (spec.kind) {
|
|
1569
1805
|
case "off":
|
|
1570
1806
|
if (providerId === "deepseek" || providerId === "glm") {
|
|
@@ -1572,20 +1808,40 @@ function translateOpenAiCompatibleThinking(providerId, spec) {
|
|
|
1572
1808
|
}
|
|
1573
1809
|
if (cap3.effort) return { patch: { reasoning_effort: "low" }, degraded: false };
|
|
1574
1810
|
return degrade(`thinking 'off' is not supported for provider "${providerId}"`);
|
|
1575
|
-
case "effort":
|
|
1576
|
-
if (!cap3.effort) {
|
|
1811
|
+
case "effort": {
|
|
1812
|
+
if (!cap3.effort && !cap3.efforts?.length) {
|
|
1577
1813
|
return degrade(`thinking 'effort' is not supported for provider "${providerId}"`);
|
|
1578
1814
|
}
|
|
1815
|
+
const resolved = clampEffort(providerId, model, spec.effort);
|
|
1579
1816
|
if (providerId === "deepseek") {
|
|
1580
|
-
return
|
|
1581
|
-
|
|
1817
|
+
return withClampNote(
|
|
1818
|
+
{
|
|
1582
1819
|
thinking: { type: "enabled" },
|
|
1583
|
-
reasoning_effort:
|
|
1820
|
+
reasoning_effort: resolved.effort === "max" ? "max" : "high"
|
|
1584
1821
|
},
|
|
1585
|
-
|
|
1586
|
-
|
|
1822
|
+
resolved.clamped,
|
|
1823
|
+
resolved.note
|
|
1824
|
+
);
|
|
1587
1825
|
}
|
|
1588
|
-
|
|
1826
|
+
if (providerId === "glm") {
|
|
1827
|
+
if (!glmHasEffortScale(model)) {
|
|
1828
|
+
return degrade(`thinking 'effort' is not supported for GLM ${model || "4.x"} \u2014 use budget:N`);
|
|
1829
|
+
}
|
|
1830
|
+
return withClampNote(
|
|
1831
|
+
{
|
|
1832
|
+
thinking: { type: "enabled" },
|
|
1833
|
+
reasoning_effort: resolved.effort
|
|
1834
|
+
},
|
|
1835
|
+
resolved.clamped,
|
|
1836
|
+
resolved.note
|
|
1837
|
+
);
|
|
1838
|
+
}
|
|
1839
|
+
return withClampNote(
|
|
1840
|
+
{ reasoning_effort: resolved.effort },
|
|
1841
|
+
resolved.clamped,
|
|
1842
|
+
resolved.note
|
|
1843
|
+
);
|
|
1844
|
+
}
|
|
1589
1845
|
case "budget":
|
|
1590
1846
|
if (!cap3.budget) {
|
|
1591
1847
|
return degrade(`thinking 'budget' is not supported for provider "${providerId}"`);
|
|
@@ -1596,18 +1852,24 @@ function translateOpenAiCompatibleThinking(providerId, spec) {
|
|
|
1596
1852
|
};
|
|
1597
1853
|
}
|
|
1598
1854
|
}
|
|
1599
|
-
function translateResponsesThinking(spec) {
|
|
1855
|
+
function translateResponsesThinking(spec, model) {
|
|
1600
1856
|
if (spec === "auto") return { patch: {}, degraded: false };
|
|
1601
1857
|
switch (spec.kind) {
|
|
1602
1858
|
case "off":
|
|
1603
1859
|
return { patch: { reasoning: { effort: "minimal" } }, degraded: false };
|
|
1604
|
-
case "effort":
|
|
1605
|
-
|
|
1860
|
+
case "effort": {
|
|
1861
|
+
const resolved = clampEffort("chatgpt", model, spec.effort);
|
|
1862
|
+
return withClampNote(
|
|
1863
|
+
{ reasoning: { effort: resolved.effort } },
|
|
1864
|
+
resolved.clamped,
|
|
1865
|
+
resolved.note
|
|
1866
|
+
);
|
|
1867
|
+
}
|
|
1606
1868
|
case "budget":
|
|
1607
|
-
return degrade('thinking "budget" is not supported for chatgpt \u2014 use low/medium/high');
|
|
1869
|
+
return degrade('thinking "budget" is not supported for chatgpt \u2014 use low/medium/high/xhigh/max');
|
|
1608
1870
|
}
|
|
1609
1871
|
}
|
|
1610
|
-
function translateAnthropicThinking(spec) {
|
|
1872
|
+
function translateAnthropicThinking(spec, model) {
|
|
1611
1873
|
if (spec === "auto") return { patch: {}, degraded: false };
|
|
1612
1874
|
switch (spec.kind) {
|
|
1613
1875
|
case "off":
|
|
@@ -1617,23 +1879,31 @@ function translateAnthropicThinking(spec) {
|
|
|
1617
1879
|
patch: { thinking: { type: "enabled", budget_tokens: spec.budgetTokens } },
|
|
1618
1880
|
degraded: false
|
|
1619
1881
|
};
|
|
1620
|
-
case "effort":
|
|
1621
|
-
|
|
1882
|
+
case "effort": {
|
|
1883
|
+
const levels = effortLevelsFor("anthropic", model);
|
|
1884
|
+
if (levels.length === 0) {
|
|
1885
|
+
return degrade('thinking "effort" is not supported for this Claude model \u2014 use budget:N');
|
|
1886
|
+
}
|
|
1887
|
+
const resolved = clampEffort("anthropic", model, spec.effort);
|
|
1888
|
+
return withClampNote(
|
|
1889
|
+
{ output_config: { effort: resolved.effort } },
|
|
1890
|
+
resolved.clamped,
|
|
1891
|
+
resolved.note
|
|
1892
|
+
);
|
|
1893
|
+
}
|
|
1622
1894
|
}
|
|
1623
1895
|
}
|
|
1624
|
-
var
|
|
1896
|
+
var EFFORT_RANK;
|
|
1625
1897
|
var init_thinking = __esm({
|
|
1626
1898
|
"src/cli/thinking.ts"() {
|
|
1627
1899
|
"use strict";
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
"minimax": { effort: true },
|
|
1636
|
-
"custom": { effort: true }
|
|
1900
|
+
init_thinkingCapability();
|
|
1901
|
+
EFFORT_RANK = {
|
|
1902
|
+
low: 1,
|
|
1903
|
+
medium: 2,
|
|
1904
|
+
high: 3,
|
|
1905
|
+
xhigh: 4,
|
|
1906
|
+
max: 5
|
|
1637
1907
|
};
|
|
1638
1908
|
}
|
|
1639
1909
|
});
|
|
@@ -1826,14 +2096,14 @@ var init_providerConfig = __esm({
|
|
|
1826
2096
|
DEFAULTS = {
|
|
1827
2097
|
activeProviderId: "openai-compatible",
|
|
1828
2098
|
modelByProvider: {
|
|
1829
|
-
// grok-4.
|
|
1830
|
-
"openai-compatible": "grok-4.
|
|
2099
|
+
// grok-4.6: flagship; native reasoning_effort includes xhigh
|
|
2100
|
+
"openai-compatible": "grok-4.6",
|
|
1831
2101
|
"minimax": "MiniMax-M2.5",
|
|
1832
2102
|
"glm": "glm-4.6",
|
|
1833
|
-
"grok": "grok-4.
|
|
2103
|
+
"grok": "grok-4.6",
|
|
1834
2104
|
"deepseek": "deepseek-v4-pro",
|
|
1835
|
-
"chatgpt": "gpt-5.
|
|
1836
|
-
"anthropic": "claude-sonnet-4-
|
|
2105
|
+
"chatgpt": "gpt-5.6-codex",
|
|
2106
|
+
"anthropic": "claude-sonnet-4-6",
|
|
1837
2107
|
"custom": ""
|
|
1838
2108
|
},
|
|
1839
2109
|
thinkingByProvider: {
|
|
@@ -1860,6 +2130,7 @@ __export(modelDiscovery_exports, {
|
|
|
1860
2130
|
getCachedModels: () => getCachedModels,
|
|
1861
2131
|
getDiscoveredModelIds: () => getDiscoveredModelIds,
|
|
1862
2132
|
getModelsFilePath: () => getModelsFilePath,
|
|
2133
|
+
getStaticFallbackModels: () => getStaticFallbackModels,
|
|
1863
2134
|
isModelsCacheStale: () => isModelsCacheStale,
|
|
1864
2135
|
loadModelsRegistry: () => loadModelsRegistry,
|
|
1865
2136
|
pickDefaultModel: () => pickDefaultModel
|
|
@@ -1867,6 +2138,9 @@ __export(modelDiscovery_exports, {
|
|
|
1867
2138
|
import { promises as fs3, existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
|
|
1868
2139
|
import { homedir } from "node:os";
|
|
1869
2140
|
import path5 from "node:path";
|
|
2141
|
+
function getStaticFallbackModels(provider) {
|
|
2142
|
+
return STATIC_FALLBACKS[provider] ? [...STATIC_FALLBACKS[provider]] : [];
|
|
2143
|
+
}
|
|
1870
2144
|
async function resolveDiscoveryBaseUrl(provider, options) {
|
|
1871
2145
|
if (options.baseUrl) return options.baseUrl;
|
|
1872
2146
|
const { getCustomEndpoint: getCustomEndpoint2 } = await Promise.resolve().then(() => (init_providerConfig(), providerConfig_exports));
|
|
@@ -2002,10 +2276,6 @@ async function discoverModelsForProvider(provider, options = {}) {
|
|
|
2002
2276
|
const headers2 = await resolveDiscoveryHeaders(provider, authToken);
|
|
2003
2277
|
response = await fetchImpl(url2, { method: "GET", headers: headers2 });
|
|
2004
2278
|
} catch (err) {
|
|
2005
|
-
const fallback = STATIC_FALLBACKS[provider];
|
|
2006
|
-
if (fallback) {
|
|
2007
|
-
return cacheFallback(provider, baseUrl, fallback, options, `network: ${err instanceof Error ? err.message : String(err)}`);
|
|
2008
|
-
}
|
|
2009
2279
|
throw new ModelDiscoveryError(
|
|
2010
2280
|
`Network error contacting ${url2}: ${err instanceof Error ? err.message : String(err)}`,
|
|
2011
2281
|
"network_error"
|
|
@@ -2013,10 +2283,6 @@ async function discoverModelsForProvider(provider, options = {}) {
|
|
|
2013
2283
|
}
|
|
2014
2284
|
if (!response.ok) {
|
|
2015
2285
|
const body = await response.text().catch(() => "");
|
|
2016
|
-
const fallback = STATIC_FALLBACKS[provider];
|
|
2017
|
-
if (fallback) {
|
|
2018
|
-
return cacheFallback(provider, baseUrl, fallback, options, `HTTP ${response.status}: ${body.slice(0, 80)}`);
|
|
2019
|
-
}
|
|
2020
2286
|
throw new ModelDiscoveryError(
|
|
2021
2287
|
`HTTP ${response.status} from ${url2}: ${body.slice(0, 200)}`,
|
|
2022
2288
|
`http_${response.status}`
|
|
@@ -2026,10 +2292,6 @@ async function discoverModelsForProvider(provider, options = {}) {
|
|
|
2026
2292
|
try {
|
|
2027
2293
|
json2 = await response.json();
|
|
2028
2294
|
} catch (err) {
|
|
2029
|
-
const fallback = STATIC_FALLBACKS[provider];
|
|
2030
|
-
if (fallback) {
|
|
2031
|
-
return cacheFallback(provider, baseUrl, fallback, options, "invalid_json");
|
|
2032
|
-
}
|
|
2033
2295
|
throw new ModelDiscoveryError(
|
|
2034
2296
|
`Invalid JSON from ${url2}: ${err instanceof Error ? err.message : String(err)}`,
|
|
2035
2297
|
"invalid_json"
|
|
@@ -2037,10 +2299,6 @@ async function discoverModelsForProvider(provider, options = {}) {
|
|
|
2037
2299
|
}
|
|
2038
2300
|
const models = provider === "anthropic" ? parseAnthropicModelsResponse(json2) : parseOpenAIModelsResponse(json2, baseUrl);
|
|
2039
2301
|
if (models.length === 0) {
|
|
2040
|
-
const fallback = STATIC_FALLBACKS[provider];
|
|
2041
|
-
if (fallback) {
|
|
2042
|
-
return cacheFallback(provider, baseUrl, fallback, options, "empty_response");
|
|
2043
|
-
}
|
|
2044
2302
|
throw new ModelDiscoveryError(
|
|
2045
2303
|
`Provider ${provider} returned 0 models \u2014 refusing to overwrite cache`,
|
|
2046
2304
|
"empty_response"
|
|
@@ -2060,22 +2318,6 @@ async function discoverModelsForProvider(provider, options = {}) {
|
|
|
2060
2318
|
}
|
|
2061
2319
|
return entry;
|
|
2062
2320
|
}
|
|
2063
|
-
async function cacheFallback(provider, baseUrl, models, options, lastError) {
|
|
2064
|
-
const entry = {
|
|
2065
|
-
models,
|
|
2066
|
-
fetchedAt: Date.now(),
|
|
2067
|
-
baseUrl,
|
|
2068
|
-
lastError
|
|
2069
|
-
};
|
|
2070
|
-
if (!options.skipCacheWrite) {
|
|
2071
|
-
const file2 = getModelsFilePath();
|
|
2072
|
-
await readModifyWriteRegistry((current) => {
|
|
2073
|
-
current[provider] = entry;
|
|
2074
|
-
return current;
|
|
2075
|
-
}, file2);
|
|
2076
|
-
}
|
|
2077
|
-
return entry;
|
|
2078
|
-
}
|
|
2079
2321
|
function discoverModelsInBackground(provider, options = {}) {
|
|
2080
2322
|
discoverModelsForProvider(provider, options).catch((err) => {
|
|
2081
2323
|
if (err instanceof ModelDiscoveryError && options.onError) {
|
|
@@ -2113,6 +2355,9 @@ var init_modelDiscovery = __esm({
|
|
|
2113
2355
|
};
|
|
2114
2356
|
STATIC_FALLBACKS = {
|
|
2115
2357
|
chatgpt: [
|
|
2358
|
+
{ id: "gpt-5.6-codex", displayName: "GPT-5.6 Codex" },
|
|
2359
|
+
{ id: "gpt-5.6", displayName: "GPT-5.6" },
|
|
2360
|
+
{ id: "gpt-5.4", displayName: "GPT-5.4" },
|
|
2116
2361
|
{ id: "gpt-5.2-codex", displayName: "GPT-5.2 Codex" },
|
|
2117
2362
|
{ id: "gpt-5.2", displayName: "GPT-5.2" },
|
|
2118
2363
|
{ id: "gpt-5.1-codex", displayName: "GPT-5.1 Codex" },
|
|
@@ -2121,9 +2366,19 @@ var init_modelDiscovery = __esm({
|
|
|
2121
2366
|
{ id: "o4-mini", displayName: "o4-mini" }
|
|
2122
2367
|
],
|
|
2123
2368
|
anthropic: [
|
|
2369
|
+
{ id: "claude-opus-4-7", displayName: "Claude Opus 4.7" },
|
|
2124
2370
|
{ id: "claude-opus-4-6", displayName: "Claude Opus 4.6" },
|
|
2371
|
+
{ id: "claude-sonnet-4-6", displayName: "Claude Sonnet 4.6" },
|
|
2125
2372
|
{ id: "claude-sonnet-4-5", displayName: "Claude Sonnet 4.5" },
|
|
2126
2373
|
{ id: "claude-haiku-4-5", displayName: "Claude Haiku 4.5" }
|
|
2374
|
+
],
|
|
2375
|
+
grok: [
|
|
2376
|
+
{ id: "grok-4.6", displayName: "Grok 4.6" },
|
|
2377
|
+
{ id: "grok-4.5", displayName: "Grok 4.5" }
|
|
2378
|
+
],
|
|
2379
|
+
glm: [
|
|
2380
|
+
{ id: "glm-5.3", displayName: "GLM-5.3" },
|
|
2381
|
+
{ id: "glm-4.6", displayName: "GLM-4.6" }
|
|
2127
2382
|
]
|
|
2128
2383
|
};
|
|
2129
2384
|
writeChain = Promise.resolve();
|
|
@@ -28169,7 +28424,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
28169
28424
|
if (thinking.thinking) body.thinking = { type: thinking.thinking };
|
|
28170
28425
|
if (thinking.reasoningEffort) body.reasoning_effort = thinking.reasoningEffort;
|
|
28171
28426
|
} else if (thinkingSpec !== "auto") {
|
|
28172
|
-
const t = translateOpenAiCompatibleThinking(config2.providerId, thinkingSpec);
|
|
28427
|
+
const t = translateOpenAiCompatibleThinking(config2.providerId, thinkingSpec, config2.model);
|
|
28173
28428
|
if (t.degraded) {
|
|
28174
28429
|
console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
|
|
28175
28430
|
} else {
|
|
@@ -28703,7 +28958,7 @@ function anthropicMessagesProvider(config2) {
|
|
|
28703
28958
|
}
|
|
28704
28959
|
const thinkingSpec = config2.thinking ?? "auto";
|
|
28705
28960
|
if (thinkingSpec !== "auto") {
|
|
28706
|
-
const t = translateAnthropicThinking(thinkingSpec);
|
|
28961
|
+
const t = translateAnthropicThinking(thinkingSpec, config2.model);
|
|
28707
28962
|
if (t.degraded) console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
|
|
28708
28963
|
else Object.assign(body, t.patch);
|
|
28709
28964
|
}
|
|
@@ -28915,7 +29170,7 @@ function chatgptResponsesProvider(config2) {
|
|
|
28915
29170
|
}
|
|
28916
29171
|
const thinkingSpec = config2.thinking ?? "auto";
|
|
28917
29172
|
if (thinkingSpec !== "auto") {
|
|
28918
|
-
const t = translateResponsesThinking(thinkingSpec);
|
|
29173
|
+
const t = translateResponsesThinking(thinkingSpec, config2.model);
|
|
28919
29174
|
if (t.degraded) console.warn(`[thinking] ${t.note ?? "unsupported"} \u2014 falling back to provider default.`);
|
|
28920
29175
|
else Object.assign(body, t.patch);
|
|
28921
29176
|
}
|
|
@@ -42695,9 +42950,9 @@ var init_oauthDesktop = __esm({
|
|
|
42695
42950
|
init_chatgptOAuth();
|
|
42696
42951
|
init_anthropicOAuth();
|
|
42697
42952
|
DEFAULT_MODELS = {
|
|
42698
|
-
grok: "grok-4.
|
|
42699
|
-
chatgpt: "gpt-5.
|
|
42700
|
-
anthropic: "claude-sonnet-4-
|
|
42953
|
+
grok: "grok-4.6",
|
|
42954
|
+
chatgpt: "gpt-5.6-codex",
|
|
42955
|
+
anthropic: "claude-sonnet-4-6"
|
|
42701
42956
|
};
|
|
42702
42957
|
}
|
|
42703
42958
|
});
|
|
@@ -42957,12 +43212,12 @@ function handleModelSet(ctx, model) {
|
|
|
42957
43212
|
}
|
|
42958
43213
|
function handleEffortShow(ctx) {
|
|
42959
43214
|
const id = ctx.activeProviderSpec.id;
|
|
42960
|
-
const cap3 = thinkingCapabilityFor(id);
|
|
43215
|
+
const cap3 = thinkingCapabilityFor(id, ctx.activeModel);
|
|
42961
43216
|
const current = stringifyThinkingSpec(getThinkingForProvider(id));
|
|
42962
43217
|
const options = [
|
|
42963
43218
|
"auto",
|
|
42964
43219
|
"off",
|
|
42965
|
-
...cap3.effort ? ["low", "medium", "high"] : [],
|
|
43220
|
+
...cap3.efforts ?? (cap3.effort ? ["low", "medium", "high"] : []),
|
|
42966
43221
|
...cap3.budget ? ["budget:<tokens>"] : []
|
|
42967
43222
|
];
|
|
42968
43223
|
appendSystem(
|
|
@@ -42975,7 +43230,7 @@ function handleEffortSet(ctx, raw) {
|
|
|
42975
43230
|
if (!isValidThinkingInput(raw)) {
|
|
42976
43231
|
appendSystem(
|
|
42977
43232
|
ctx.setMessages,
|
|
42978
|
-
`[effort] invalid spec "${raw}" \u2014 use auto | off | low | medium | high | budget:<tokens>`
|
|
43233
|
+
`[effort] invalid spec "${raw}" \u2014 use auto | off | low | medium | high | xhigh | max | budget:<tokens>`
|
|
42979
43234
|
);
|
|
42980
43235
|
return;
|
|
42981
43236
|
}
|
|
@@ -43536,6 +43791,11 @@ function buildDesktopConfigSnapshot() {
|
|
|
43536
43791
|
const providers = PROVIDERS.map((p3) => {
|
|
43537
43792
|
const cached2 = getCachedModels(p3.id);
|
|
43538
43793
|
const models = cached2?.models.map((m) => m.id) ?? [];
|
|
43794
|
+
if (models.length === 0) {
|
|
43795
|
+
for (const m of getStaticFallbackModels(p3.id)) {
|
|
43796
|
+
if (!models.includes(m.id)) models.push(m.id);
|
|
43797
|
+
}
|
|
43798
|
+
}
|
|
43539
43799
|
const defaultModel = config2.modelByProvider[p3.id] ?? "";
|
|
43540
43800
|
if (defaultModel && !models.includes(defaultModel)) {
|
|
43541
43801
|
models.unshift(defaultModel);
|
|
@@ -43559,7 +43819,7 @@ function buildDesktopConfigSnapshot() {
|
|
|
43559
43819
|
hasRefreshToken: Boolean(stored?.refreshToken),
|
|
43560
43820
|
oauthSupported: isOAuthProvider(p3.id),
|
|
43561
43821
|
thinking: config2.thinkingByProvider[p3.id] ?? "auto",
|
|
43562
|
-
thinkingCapability: thinkingCapabilityFor(p3.id)
|
|
43822
|
+
thinkingCapability: thinkingCapabilityFor(p3.id, defaultModel)
|
|
43563
43823
|
};
|
|
43564
43824
|
});
|
|
43565
43825
|
return {
|