@kenkaiiii/gg-core 5.9.6 → 5.10.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/index.cjs CHANGED
@@ -35,12 +35,14 @@ __export(index_exports, {
35
35
  MODELS: () => MODELS,
36
36
  MOONSHOT_OAUTH_KEY: () => MOONSHOT_OAUTH_KEY,
37
37
  NotLoggedInError: () => NotLoggedInError,
38
+ SubscriptionUsageError: () => SubscriptionUsageError,
38
39
  TelegramBot: () => TelegramBot,
39
40
  XIAOMI_CREDITS_KEY: () => XIAOMI_CREDITS_KEY,
40
41
  closeLogger: () => closeLogger,
41
42
  createAutoUpdater: () => createAutoUpdater,
42
43
  decodeOggOpus: () => decodeOggOpus,
43
44
  downmixToMono: () => downmixToMono,
45
+ fetchSubscriptionUsage: () => fetchSubscriptionUsage,
44
46
  generatePKCE: () => generatePKCE,
45
47
  getAppPaths: () => getAppPaths,
46
48
  getAuthStorageKey: () => getAuthStorageKey,
@@ -1895,6 +1897,13 @@ function getFastModel(provider, currentModelId) {
1895
1897
 
1896
1898
  // src/thinking-level.ts
1897
1899
  var OPENAI_GPT_THINKING_LEVELS = ["medium", "high", "xhigh"];
1900
+ var OPENAI_GPT_56_THINKING_LEVELS = [
1901
+ "low",
1902
+ "medium",
1903
+ "high",
1904
+ "xhigh",
1905
+ "max"
1906
+ ];
1898
1907
  var SAKANA_THINKING_LEVELS = ["high", "xhigh"];
1899
1908
  var ANTHROPIC_OPUS_48_47_THINKING_LEVELS = [
1900
1909
  "low",
@@ -1924,10 +1933,10 @@ function isAnthropicAdaptiveModel(provider, model) {
1924
1933
  function getSupportedThinkingLevels(provider, model) {
1925
1934
  const maxLevel = getMaxThinkingLevel(model);
1926
1935
  if (isAnthropicAdaptiveModel(provider, model)) {
1927
- const levels = isAnthropicOpus48Or47Model(provider, model) ? ANTHROPIC_OPUS_48_47_THINKING_LEVELS : ANTHROPIC_ADAPTIVE_THINKING_LEVELS;
1928
- const maxIndex2 = levels.indexOf(maxLevel);
1936
+ const levels2 = isAnthropicOpus48Or47Model(provider, model) ? ANTHROPIC_OPUS_48_47_THINKING_LEVELS : ANTHROPIC_ADAPTIVE_THINKING_LEVELS;
1937
+ const maxIndex2 = levels2.indexOf(maxLevel);
1929
1938
  if (maxIndex2 === -1) return ["low", "medium", "high"];
1930
- return levels.slice(0, maxIndex2 + 1);
1939
+ return levels2.slice(0, maxIndex2 + 1);
1931
1940
  }
1932
1941
  if (isSakanaModel(provider)) {
1933
1942
  const maxIndex2 = SAKANA_THINKING_LEVELS.indexOf(maxLevel);
@@ -1935,9 +1944,10 @@ function getSupportedThinkingLevels(provider, model) {
1935
1944
  return SAKANA_THINKING_LEVELS.slice(0, maxIndex2 + 1);
1936
1945
  }
1937
1946
  if (!isOpenAIGptModel(provider, model)) return [maxLevel];
1938
- const maxIndex = OPENAI_GPT_THINKING_LEVELS.indexOf(maxLevel);
1947
+ const levels = model.startsWith("gpt-5.6-") ? OPENAI_GPT_56_THINKING_LEVELS : OPENAI_GPT_THINKING_LEVELS;
1948
+ const maxIndex = levels.indexOf(maxLevel);
1939
1949
  if (maxIndex === -1) return ["medium"];
1940
- return OPENAI_GPT_THINKING_LEVELS.slice(0, maxIndex + 1);
1950
+ return levels.slice(0, maxIndex + 1);
1941
1951
  }
1942
1952
  function isThinkingLevelSupported(provider, model, level) {
1943
1953
  return getSupportedThinkingLevels(provider, model).includes(level);
@@ -1954,6 +1964,147 @@ function getNextThinkingLevel(provider, model, current) {
1954
1964
  return supportedLevels[index + 1];
1955
1965
  }
1956
1966
 
1967
+ // src/provider-usage.ts
1968
+ var SubscriptionUsageError = class extends Error {
1969
+ constructor(message, status) {
1970
+ super(message);
1971
+ this.status = status;
1972
+ this.name = "SubscriptionUsageError";
1973
+ }
1974
+ };
1975
+ var ANTHROPIC_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
1976
+ var CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
1977
+ function finiteNumber(value) {
1978
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1979
+ }
1980
+ function clampPercent(value) {
1981
+ const number = finiteNumber(value);
1982
+ return number === void 0 ? void 0 : Math.min(100, Math.max(0, number));
1983
+ }
1984
+ function isoTimestamp(value) {
1985
+ if (typeof value !== "string" || !value.trim()) return void 0;
1986
+ const timestamp = Date.parse(value);
1987
+ return Number.isFinite(timestamp) ? timestamp : void 0;
1988
+ }
1989
+ function unixTimestamp(value) {
1990
+ const seconds = finiteNumber(value);
1991
+ return seconds === void 0 ? void 0 : seconds * 1e3;
1992
+ }
1993
+ function codexResetAt(window, now) {
1994
+ const absolute = unixTimestamp(window.reset_at);
1995
+ if (absolute !== void 0) return absolute;
1996
+ const afterSeconds = finiteNumber(window.reset_after_seconds);
1997
+ return afterSeconds === void 0 ? void 0 : now + afterSeconds * 1e3;
1998
+ }
1999
+ function currentWindowLabel(seconds, fallbackHours) {
2000
+ const duration = finiteNumber(seconds);
2001
+ const hours = Math.max(1, Math.round((duration ?? fallbackHours * 3600) / 3600));
2002
+ return `${hours}-hour`;
2003
+ }
2004
+ async function readUsageResponse(response) {
2005
+ const text = await response.text();
2006
+ if (!response.ok) {
2007
+ throw new SubscriptionUsageError(
2008
+ `Subscription usage request failed with HTTP ${response.status}`,
2009
+ response.status
2010
+ );
2011
+ }
2012
+ try {
2013
+ return JSON.parse(text);
2014
+ } catch {
2015
+ throw new SubscriptionUsageError("Subscription usage response was not valid JSON");
2016
+ }
2017
+ }
2018
+ async function fetchAnthropicUsage(credentials, fetchFn, signal, now) {
2019
+ const response = await fetchFn(ANTHROPIC_USAGE_URL, {
2020
+ method: "GET",
2021
+ signal,
2022
+ headers: {
2023
+ Authorization: `Bearer ${credentials.accessToken}`,
2024
+ Accept: "application/json",
2025
+ "anthropic-version": "2023-06-01",
2026
+ "anthropic-beta": "oauth-2025-04-20",
2027
+ "User-Agent": "ggcoder"
2028
+ }
2029
+ });
2030
+ const data = await readUsageResponse(response);
2031
+ const windows = [];
2032
+ const currentPercent = clampPercent(data.five_hour?.utilization);
2033
+ if (currentPercent !== void 0) {
2034
+ windows.push({
2035
+ kind: "current",
2036
+ label: "5-hour",
2037
+ usedPercent: currentPercent,
2038
+ resetsAt: isoTimestamp(data.five_hour?.resets_at)
2039
+ });
2040
+ }
2041
+ const weeklyPercent = clampPercent(data.seven_day?.utilization);
2042
+ if (weeklyPercent !== void 0) {
2043
+ windows.push({
2044
+ kind: "weekly",
2045
+ label: "Weekly",
2046
+ usedPercent: weeklyPercent,
2047
+ resetsAt: isoTimestamp(data.seven_day?.resets_at)
2048
+ });
2049
+ }
2050
+ return {
2051
+ provider: "anthropic",
2052
+ displayName: "Anthropic",
2053
+ windows,
2054
+ fetchedAt: now()
2055
+ };
2056
+ }
2057
+ async function fetchCodexUsage(credentials, fetchFn, signal, now) {
2058
+ const headers = {
2059
+ Authorization: `Bearer ${credentials.accessToken}`,
2060
+ Accept: "application/json",
2061
+ originator: "ggcoder",
2062
+ "User-Agent": "ggcoder"
2063
+ };
2064
+ if (credentials.accountId) headers["ChatGPT-Account-Id"] = credentials.accountId;
2065
+ const response = await fetchFn(CODEX_USAGE_URL, { method: "GET", signal, headers });
2066
+ const data = await readUsageResponse(response);
2067
+ const windows = [];
2068
+ const current = data.rate_limit?.primary_window;
2069
+ const currentPercent = clampPercent(current?.used_percent);
2070
+ if (current && currentPercent !== void 0) {
2071
+ windows.push({
2072
+ kind: "current",
2073
+ label: currentWindowLabel(current.limit_window_seconds, 5),
2074
+ usedPercent: currentPercent,
2075
+ resetsAt: codexResetAt(current, now())
2076
+ });
2077
+ }
2078
+ const weekly = data.rate_limit?.secondary_window;
2079
+ const weeklyPercent = clampPercent(weekly?.used_percent);
2080
+ if (weekly && weeklyPercent !== void 0) {
2081
+ windows.push({
2082
+ kind: "weekly",
2083
+ label: "Weekly",
2084
+ usedPercent: weeklyPercent,
2085
+ resetsAt: codexResetAt(weekly, now())
2086
+ });
2087
+ }
2088
+ return {
2089
+ provider: "openai",
2090
+ displayName: "Codex",
2091
+ windows,
2092
+ fetchedAt: now()
2093
+ };
2094
+ }
2095
+ async function fetchSubscriptionUsage(provider, credentials, options = {}) {
2096
+ const fetchFn = options.fetchFn ?? fetch;
2097
+ const now = options.now ?? Date.now;
2098
+ const signal = AbortSignal.timeout(options.timeoutMs ?? 8e3);
2099
+ try {
2100
+ return provider === "anthropic" ? await fetchAnthropicUsage(credentials, fetchFn, signal, now) : await fetchCodexUsage(credentials, fetchFn, signal, now);
2101
+ } catch (error) {
2102
+ if (error instanceof SubscriptionUsageError) throw error;
2103
+ const message = error instanceof Error ? error.message : String(error);
2104
+ throw new SubscriptionUsageError(message);
2105
+ }
2106
+ }
2107
+
1957
2108
  // src/telegram.ts
1958
2109
  var TELEGRAM_API = "https://api.telegram.org";
1959
2110
  var MAX_MESSAGE_LENGTH = 4096;
@@ -2436,12 +2587,14 @@ function createAutoUpdater(config) {
2436
2587
  MODELS,
2437
2588
  MOONSHOT_OAUTH_KEY,
2438
2589
  NotLoggedInError,
2590
+ SubscriptionUsageError,
2439
2591
  TelegramBot,
2440
2592
  XIAOMI_CREDITS_KEY,
2441
2593
  closeLogger,
2442
2594
  createAutoUpdater,
2443
2595
  decodeOggOpus,
2444
2596
  downmixToMono,
2597
+ fetchSubscriptionUsage,
2445
2598
  generatePKCE,
2446
2599
  getAppPaths,
2447
2600
  getAuthStorageKey,