@prestyj/core 5.3.0 → 5.4.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,
@@ -49,6 +51,7 @@ __export(index_exports, {
49
51
  getClaudeCodeVersion: () => getClaudeCodeVersion,
50
52
  getContextWindow: () => getContextWindow,
51
53
  getDefaultModel: () => getDefaultModel,
54
+ getFastModel: () => getFastModel,
52
55
  getMaxThinkingLevel: () => getMaxThinkingLevel,
53
56
  getModel: () => getModel,
54
57
  getModelsForProvider: () => getModelsForProvider,
@@ -103,7 +106,9 @@ function getAppPaths() {
103
106
  logFile: import_node_path.default.join(agentDir, "debug.log"),
104
107
  skillsDir: import_node_path.default.join(agentDir, "skills"),
105
108
  extensionsDir: import_node_path.default.join(agentDir, "extensions"),
106
- agentsDir: import_node_path.default.join(agentDir, "agents")
109
+ agentsDir: import_node_path.default.join(agentDir, "agents"),
110
+ progressFile: import_node_path.default.join(agentDir, "progress.json"),
111
+ progressBackupFile: import_node_path.default.join(agentDir, "progress.backup.json")
107
112
  };
108
113
  }
109
114
 
@@ -1532,49 +1537,63 @@ var MODELS = [
1532
1537
  maxThinkingLevel: "high"
1533
1538
  },
1534
1539
  // ── OpenAI (Codex) ─────────────────────────────────────
1540
+ // GPT-5.6 family — three agentic coding tiers launched July 2026. All share a
1541
+ // 372K context window: the Codex repo's models.json lists both `context_window`
1542
+ // AND `max_context_window` as 372000 for every 5.6 variant, so (unlike 5.4/5.5,
1543
+ // whose public-API 1M window exceeds the Codex-product cap) there's no split
1544
+ // between the API and Codex-transport windows — a single `contextWindow` is
1545
+ // correct in both code paths. All three take text+image input, freeform
1546
+ // apply_patch, text+image web search, and parallel tool calls.
1535
1547
  {
1536
- id: "gpt-5.5",
1537
- name: "GPT-5.5",
1548
+ // Sol — "Latest frontier agentic coding model." (priority 1, default low).
1549
+ // Reasoning ladder: low → medium → high → xhigh → max → ultra. gg-ai's
1550
+ // ThinkingLevel tops out at `max`, so that's the cap here; the `ultra` rung
1551
+ // (auto task delegation) needs a ThinkingLevel extension to expose.
1552
+ id: "gpt-5.6-sol",
1553
+ name: "GPT-5.6 Sol",
1538
1554
  provider: "openai",
1539
- contextWindow: 105e4,
1540
- codexContextWindow: 272e3,
1555
+ contextWindow: 372e3,
1541
1556
  maxOutputTokens: 128e3,
1542
1557
  supportsThinking: true,
1543
1558
  supportsImages: true,
1544
1559
  supportsVideo: false,
1545
1560
  costTier: "high",
1546
- maxThinkingLevel: "xhigh"
1561
+ maxThinkingLevel: "max"
1547
1562
  },
1548
1563
  {
1549
- id: "gpt-5.4",
1550
- name: "GPT-5.4",
1564
+ // Terra — "Balanced agentic coding model for everyday work." (priority 2,
1565
+ // default medium). Same 372K context + ultra reasoning ladder as Sol.
1566
+ id: "gpt-5.6-terra",
1567
+ name: "GPT-5.6 Terra",
1551
1568
  provider: "openai",
1552
- contextWindow: 105e4,
1553
- codexContextWindow: 272e3,
1569
+ contextWindow: 372e3,
1554
1570
  maxOutputTokens: 128e3,
1555
1571
  supportsThinking: true,
1556
1572
  supportsImages: true,
1557
1573
  supportsVideo: false,
1558
- costTier: "high",
1559
- maxThinkingLevel: "xhigh"
1574
+ costTier: "medium",
1575
+ maxThinkingLevel: "max"
1560
1576
  },
1561
1577
  {
1562
- id: "gpt-5.4-mini",
1563
- name: "GPT-5.4 Mini",
1578
+ // Luna — "Fast and affordable agentic coding model." (priority 3, default
1579
+ // medium). Same 372K context; reasoning tops out at `max` (no `ultra` rung).
1580
+ id: "gpt-5.6-luna",
1581
+ name: "GPT-5.6 Luna",
1564
1582
  provider: "openai",
1565
- contextWindow: 4e5,
1583
+ contextWindow: 372e3,
1566
1584
  maxOutputTokens: 128e3,
1567
1585
  supportsThinking: true,
1568
1586
  supportsImages: true,
1569
1587
  supportsVideo: false,
1570
1588
  costTier: "low",
1571
- maxThinkingLevel: "xhigh"
1589
+ maxThinkingLevel: "max"
1572
1590
  },
1573
1591
  {
1574
- id: "gpt-5.3-codex",
1575
- name: "GPT-5.3 Codex",
1592
+ id: "gpt-5.5",
1593
+ name: "GPT-5.5",
1576
1594
  provider: "openai",
1577
- contextWindow: 4e5,
1595
+ contextWindow: 105e4,
1596
+ codexContextWindow: 272e3,
1578
1597
  maxOutputTokens: 128e3,
1579
1598
  supportsThinking: true,
1580
1599
  supportsImages: true,
@@ -1614,8 +1633,8 @@ var MODELS = [
1614
1633
  },
1615
1634
  // ── Gemini ─────────────────────────────────────────────
1616
1635
  {
1617
- id: "gemini-3.1-flash-lite-preview",
1618
- name: "Gemini 3.1 Flash Lite Preview",
1636
+ id: "gemini-3.1-flash-lite",
1637
+ name: "Gemini 3.1 Flash Lite",
1619
1638
  provider: "gemini",
1620
1639
  contextWindow: 1048576,
1621
1640
  maxOutputTokens: 65536,
@@ -1627,7 +1646,10 @@ var MODELS = [
1627
1646
  maxThinkingLevel: "high"
1628
1647
  },
1629
1648
  {
1630
- id: "gemini-3.5-flash",
1649
+ // Wire name `gemini-3-flash` — the Code Assist (OAuth) backend rejects the
1650
+ // display string `gemini-3.5-flash` with a 404, so gemini-cli keeps this
1651
+ // alternative name (SECONDARY_GEMINI_3_5_FLASH_MODEL) for that endpoint.
1652
+ id: "gemini-3-flash",
1631
1653
  name: "Gemini 3.5 Flash",
1632
1654
  provider: "gemini",
1633
1655
  contextWindow: 1048576,
@@ -1639,6 +1661,22 @@ var MODELS = [
1639
1661
  costTier: "low",
1640
1662
  maxThinkingLevel: "high"
1641
1663
  },
1664
+ {
1665
+ // Gemini 3.1 Pro is public preview — gated behind Code Assist preview
1666
+ // enablement, so free/personal OAuth accounts 404 on it (see
1667
+ // ACCOUNT_GATED_MODELS in gg-ai's gemini provider).
1668
+ id: "gemini-3.1-pro-preview",
1669
+ name: "Gemini 3.1 Pro (Preview)",
1670
+ provider: "gemini",
1671
+ contextWindow: 1048576,
1672
+ maxOutputTokens: 65536,
1673
+ supportsThinking: true,
1674
+ supportsImages: true,
1675
+ supportsVideo: true,
1676
+ maxVideoBytes: 20 * 1024 * 1024,
1677
+ costTier: "high",
1678
+ maxThinkingLevel: "high"
1679
+ },
1642
1680
  // ── Moonshot (Kimi) ────────────────────────────────────
1643
1681
  {
1644
1682
  id: "kimi-k2.7-code",
@@ -1829,8 +1867,8 @@ function getVideoByteLimit(modelId) {
1829
1867
  }
1830
1868
  function getDefaultModel(provider) {
1831
1869
  if (provider === "xiaomi") return MODELS.find((m) => m.id === "mimo-v2.5-pro");
1832
- if (provider === "openai") return MODELS.find((m) => m.id === "gpt-5.5");
1833
- if (provider === "gemini") return MODELS.find((m) => m.id === "gemini-3.1-flash-lite-preview");
1870
+ if (provider === "openai") return MODELS.find((m) => m.id === "gpt-5.6-sol");
1871
+ if (provider === "gemini") return MODELS.find((m) => m.id === "gemini-3.1-flash-lite");
1834
1872
  if (provider === "glm") return MODELS.find((m) => m.id === "glm-5.2");
1835
1873
  if (provider === "moonshot") return MODELS.find((m) => m.id === "kimi-k2.7-code");
1836
1874
  if (provider === "minimax") return MODELS.find((m) => m.id === "MiniMax-M3");
@@ -1863,9 +1901,20 @@ function getSummaryModel(provider, currentModelId) {
1863
1901
  }
1864
1902
  return getModel(currentModelId) ?? getDefaultModel(provider);
1865
1903
  }
1904
+ function getFastModel(provider, currentModelId) {
1905
+ const low = getModelsForProvider(provider).find((m) => m.costTier === "low");
1906
+ return low ?? getModel(currentModelId) ?? getDefaultModel(provider);
1907
+ }
1866
1908
 
1867
1909
  // src/thinking-level.ts
1868
1910
  var OPENAI_GPT_THINKING_LEVELS = ["medium", "high", "xhigh"];
1911
+ var OPENAI_GPT_56_THINKING_LEVELS = [
1912
+ "low",
1913
+ "medium",
1914
+ "high",
1915
+ "xhigh",
1916
+ "max"
1917
+ ];
1869
1918
  var SAKANA_THINKING_LEVELS = ["high", "xhigh"];
1870
1919
  var ANTHROPIC_OPUS_48_47_THINKING_LEVELS = [
1871
1920
  "low",
@@ -1895,10 +1944,10 @@ function isAnthropicAdaptiveModel(provider, model) {
1895
1944
  function getSupportedThinkingLevels(provider, model) {
1896
1945
  const maxLevel = getMaxThinkingLevel(model);
1897
1946
  if (isAnthropicAdaptiveModel(provider, model)) {
1898
- const levels = isAnthropicOpus48Or47Model(provider, model) ? ANTHROPIC_OPUS_48_47_THINKING_LEVELS : ANTHROPIC_ADAPTIVE_THINKING_LEVELS;
1899
- const maxIndex2 = levels.indexOf(maxLevel);
1947
+ const levels2 = isAnthropicOpus48Or47Model(provider, model) ? ANTHROPIC_OPUS_48_47_THINKING_LEVELS : ANTHROPIC_ADAPTIVE_THINKING_LEVELS;
1948
+ const maxIndex2 = levels2.indexOf(maxLevel);
1900
1949
  if (maxIndex2 === -1) return ["low", "medium", "high"];
1901
- return levels.slice(0, maxIndex2 + 1);
1950
+ return levels2.slice(0, maxIndex2 + 1);
1902
1951
  }
1903
1952
  if (isSakanaModel(provider)) {
1904
1953
  const maxIndex2 = SAKANA_THINKING_LEVELS.indexOf(maxLevel);
@@ -1906,9 +1955,10 @@ function getSupportedThinkingLevels(provider, model) {
1906
1955
  return SAKANA_THINKING_LEVELS.slice(0, maxIndex2 + 1);
1907
1956
  }
1908
1957
  if (!isOpenAIGptModel(provider, model)) return [maxLevel];
1909
- const maxIndex = OPENAI_GPT_THINKING_LEVELS.indexOf(maxLevel);
1958
+ const levels = model.startsWith("gpt-5.6-") ? OPENAI_GPT_56_THINKING_LEVELS : OPENAI_GPT_THINKING_LEVELS;
1959
+ const maxIndex = levels.indexOf(maxLevel);
1910
1960
  if (maxIndex === -1) return ["medium"];
1911
- return OPENAI_GPT_THINKING_LEVELS.slice(0, maxIndex + 1);
1961
+ return levels.slice(0, maxIndex + 1);
1912
1962
  }
1913
1963
  function isThinkingLevelSupported(provider, model, level) {
1914
1964
  return getSupportedThinkingLevels(provider, model).includes(level);
@@ -1925,6 +1975,147 @@ function getNextThinkingLevel(provider, model, current) {
1925
1975
  return supportedLevels[index + 1];
1926
1976
  }
1927
1977
 
1978
+ // src/provider-usage.ts
1979
+ var SubscriptionUsageError = class extends Error {
1980
+ constructor(message, status) {
1981
+ super(message);
1982
+ this.status = status;
1983
+ this.name = "SubscriptionUsageError";
1984
+ }
1985
+ };
1986
+ var ANTHROPIC_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
1987
+ var CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
1988
+ function finiteNumber(value) {
1989
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1990
+ }
1991
+ function clampPercent(value) {
1992
+ const number = finiteNumber(value);
1993
+ return number === void 0 ? void 0 : Math.min(100, Math.max(0, number));
1994
+ }
1995
+ function isoTimestamp(value) {
1996
+ if (typeof value !== "string" || !value.trim()) return void 0;
1997
+ const timestamp = Date.parse(value);
1998
+ return Number.isFinite(timestamp) ? timestamp : void 0;
1999
+ }
2000
+ function unixTimestamp(value) {
2001
+ const seconds = finiteNumber(value);
2002
+ return seconds === void 0 ? void 0 : seconds * 1e3;
2003
+ }
2004
+ function codexResetAt(window, now) {
2005
+ const absolute = unixTimestamp(window.reset_at);
2006
+ if (absolute !== void 0) return absolute;
2007
+ const afterSeconds = finiteNumber(window.reset_after_seconds);
2008
+ return afterSeconds === void 0 ? void 0 : now + afterSeconds * 1e3;
2009
+ }
2010
+ function currentWindowLabel(seconds, fallbackHours) {
2011
+ const duration = finiteNumber(seconds);
2012
+ const hours = Math.max(1, Math.round((duration ?? fallbackHours * 3600) / 3600));
2013
+ return `${hours}-hour`;
2014
+ }
2015
+ async function readUsageResponse(response) {
2016
+ const text = await response.text();
2017
+ if (!response.ok) {
2018
+ throw new SubscriptionUsageError(
2019
+ `Subscription usage request failed with HTTP ${response.status}`,
2020
+ response.status
2021
+ );
2022
+ }
2023
+ try {
2024
+ return JSON.parse(text);
2025
+ } catch {
2026
+ throw new SubscriptionUsageError("Subscription usage response was not valid JSON");
2027
+ }
2028
+ }
2029
+ async function fetchAnthropicUsage(credentials, fetchFn, signal, now) {
2030
+ const response = await fetchFn(ANTHROPIC_USAGE_URL, {
2031
+ method: "GET",
2032
+ signal,
2033
+ headers: {
2034
+ Authorization: `Bearer ${credentials.accessToken}`,
2035
+ Accept: "application/json",
2036
+ "anthropic-version": "2023-06-01",
2037
+ "anthropic-beta": "oauth-2025-04-20",
2038
+ "User-Agent": "ezcoder"
2039
+ }
2040
+ });
2041
+ const data = await readUsageResponse(response);
2042
+ const windows = [];
2043
+ const currentPercent = clampPercent(data.five_hour?.utilization);
2044
+ if (currentPercent !== void 0) {
2045
+ windows.push({
2046
+ kind: "current",
2047
+ label: "5-hour",
2048
+ usedPercent: currentPercent,
2049
+ resetsAt: isoTimestamp(data.five_hour?.resets_at)
2050
+ });
2051
+ }
2052
+ const weeklyPercent = clampPercent(data.seven_day?.utilization);
2053
+ if (weeklyPercent !== void 0) {
2054
+ windows.push({
2055
+ kind: "weekly",
2056
+ label: "Weekly",
2057
+ usedPercent: weeklyPercent,
2058
+ resetsAt: isoTimestamp(data.seven_day?.resets_at)
2059
+ });
2060
+ }
2061
+ return {
2062
+ provider: "anthropic",
2063
+ displayName: "Anthropic",
2064
+ windows,
2065
+ fetchedAt: now()
2066
+ };
2067
+ }
2068
+ async function fetchCodexUsage(credentials, fetchFn, signal, now) {
2069
+ const headers = {
2070
+ Authorization: `Bearer ${credentials.accessToken}`,
2071
+ Accept: "application/json",
2072
+ originator: "ezcoder",
2073
+ "User-Agent": "ezcoder"
2074
+ };
2075
+ if (credentials.accountId) headers["ChatGPT-Account-Id"] = credentials.accountId;
2076
+ const response = await fetchFn(CODEX_USAGE_URL, { method: "GET", signal, headers });
2077
+ const data = await readUsageResponse(response);
2078
+ const windows = [];
2079
+ const current = data.rate_limit?.primary_window;
2080
+ const currentPercent = clampPercent(current?.used_percent);
2081
+ if (current && currentPercent !== void 0) {
2082
+ windows.push({
2083
+ kind: "current",
2084
+ label: currentWindowLabel(current.limit_window_seconds, 5),
2085
+ usedPercent: currentPercent,
2086
+ resetsAt: codexResetAt(current, now())
2087
+ });
2088
+ }
2089
+ const weekly = data.rate_limit?.secondary_window;
2090
+ const weeklyPercent = clampPercent(weekly?.used_percent);
2091
+ if (weekly && weeklyPercent !== void 0) {
2092
+ windows.push({
2093
+ kind: "weekly",
2094
+ label: "Weekly",
2095
+ usedPercent: weeklyPercent,
2096
+ resetsAt: codexResetAt(weekly, now())
2097
+ });
2098
+ }
2099
+ return {
2100
+ provider: "openai",
2101
+ displayName: "Codex",
2102
+ windows,
2103
+ fetchedAt: now()
2104
+ };
2105
+ }
2106
+ async function fetchSubscriptionUsage(provider, credentials, options = {}) {
2107
+ const fetchFn = options.fetchFn ?? fetch;
2108
+ const now = options.now ?? Date.now;
2109
+ const signal = AbortSignal.timeout(options.timeoutMs ?? 8e3);
2110
+ try {
2111
+ return provider === "anthropic" ? await fetchAnthropicUsage(credentials, fetchFn, signal, now) : await fetchCodexUsage(credentials, fetchFn, signal, now);
2112
+ } catch (error) {
2113
+ if (error instanceof SubscriptionUsageError) throw error;
2114
+ const message = error instanceof Error ? error.message : String(error);
2115
+ throw new SubscriptionUsageError(message);
2116
+ }
2117
+ }
2118
+
1928
2119
  // src/telegram.ts
1929
2120
  var TELEGRAM_API = "https://api.telegram.org";
1930
2121
  var MAX_MESSAGE_LENGTH = 4096;
@@ -2407,12 +2598,14 @@ function createAutoUpdater(config) {
2407
2598
  MODELS,
2408
2599
  MOONSHOT_OAUTH_KEY,
2409
2600
  NotLoggedInError,
2601
+ SubscriptionUsageError,
2410
2602
  TelegramBot,
2411
2603
  XIAOMI_CREDITS_KEY,
2412
2604
  closeLogger,
2413
2605
  createAutoUpdater,
2414
2606
  decodeOggOpus,
2415
2607
  downmixToMono,
2608
+ fetchSubscriptionUsage,
2416
2609
  generatePKCE,
2417
2610
  getAppPaths,
2418
2611
  getAuthStorageKey,
@@ -2421,6 +2614,7 @@ function createAutoUpdater(config) {
2421
2614
  getClaudeCodeVersion,
2422
2615
  getContextWindow,
2423
2616
  getDefaultModel,
2617
+ getFastModel,
2424
2618
  getMaxThinkingLevel,
2425
2619
  getModel,
2426
2620
  getModelsForProvider,