@prestyj/core 5.6.0 → 5.8.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/paths.ts"],"sourcesContent":["import path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface AppPaths {\n agentDir: string;\n sessionsDir: string;\n subagentSessionsDir: string;\n subagentsDir: string;\n settingsFile: string;\n authFile: string;\n telegramFile: string;\n agentHomeFile: string;\n mcpFile: string;\n mcpAuthFile: string;\n logFile: string;\n skillsDir: string;\n extensionsDir: string;\n agentsDir: string;\n progressFile: string;\n progressBackupFile: string;\n}\n\nexport function getAppPaths(): AppPaths {\n const agentDir = path.join(os.homedir(), \".ezcoder\");\n return {\n agentDir,\n sessionsDir: path.join(agentDir, \"sessions\"),\n subagentSessionsDir: path.join(agentDir, \"subagent-sessions\"),\n subagentsDir: path.join(agentDir, \"subagents\"),\n settingsFile: path.join(agentDir, \"settings.json\"),\n authFile: path.join(agentDir, \"auth.json\"),\n telegramFile: path.join(agentDir, \"telegram.json\"),\n agentHomeFile: path.join(agentDir, \"agent-home.json\"),\n mcpFile: path.join(agentDir, \"mcp.json\"),\n mcpAuthFile: path.join(agentDir, \"mcp-auth.json\"),\n logFile: path.join(agentDir, \"debug.log\"),\n skillsDir: path.join(agentDir, \"skills\"),\n extensionsDir: path.join(agentDir, \"extensions\"),\n agentsDir: path.join(agentDir, \"agents\"),\n progressFile: path.join(agentDir, \"progress.json\"),\n progressBackupFile: path.join(agentDir, \"progress.backup.json\"),\n };\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAqBR,SAAS,cAAwB;AACtC,QAAM,WAAW,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU;AACnD,SAAO;AAAA,IACL;AAAA,IACA,aAAa,KAAK,KAAK,UAAU,UAAU;AAAA,IAC3C,qBAAqB,KAAK,KAAK,UAAU,mBAAmB;AAAA,IAC5D,cAAc,KAAK,KAAK,UAAU,WAAW;AAAA,IAC7C,cAAc,KAAK,KAAK,UAAU,eAAe;AAAA,IACjD,UAAU,KAAK,KAAK,UAAU,WAAW;AAAA,IACzC,cAAc,KAAK,KAAK,UAAU,eAAe;AAAA,IACjD,eAAe,KAAK,KAAK,UAAU,iBAAiB;AAAA,IACpD,SAAS,KAAK,KAAK,UAAU,UAAU;AAAA,IACvC,aAAa,KAAK,KAAK,UAAU,eAAe;AAAA,IAChD,SAAS,KAAK,KAAK,UAAU,WAAW;AAAA,IACxC,WAAW,KAAK,KAAK,UAAU,QAAQ;AAAA,IACvC,eAAe,KAAK,KAAK,UAAU,YAAY;AAAA,IAC/C,WAAW,KAAK,KAAK,UAAU,QAAQ;AAAA,IACvC,cAAc,KAAK,KAAK,UAAU,eAAe;AAAA,IACjD,oBAAoB,KAAK,KAAK,UAAU,sBAAsB;AAAA,EAChE;AACF;","names":[]}
package/dist/index.cjs CHANGED
@@ -59,6 +59,7 @@ __export(index_exports, {
59
59
  getSessionId: () => getSessionId,
60
60
  getSummaryModel: () => getSummaryModel,
61
61
  getSupportedThinkingLevels: () => getSupportedThinkingLevels,
62
+ getToolResultCharLimit: () => getToolResultCharLimit,
62
63
  getVideoByteLimit: () => getVideoByteLimit,
63
64
  isKimiCodingEndpoint: () => isKimiCodingEndpoint,
64
65
  isLoggerOpen: () => isLoggerOpen,
@@ -97,6 +98,8 @@ function getAppPaths() {
97
98
  return {
98
99
  agentDir,
99
100
  sessionsDir: import_node_path.default.join(agentDir, "sessions"),
101
+ subagentSessionsDir: import_node_path.default.join(agentDir, "subagent-sessions"),
102
+ subagentsDir: import_node_path.default.join(agentDir, "subagents"),
100
103
  settingsFile: import_node_path.default.join(agentDir, "settings.json"),
101
104
  authFile: import_node_path.default.join(agentDir, "auth.json"),
102
105
  telegramFile: import_node_path.default.join(agentDir, "telegram.json"),
@@ -141,11 +144,13 @@ var import_node_path3 = __toESM(require("path"), 1);
141
144
  var import_node_fs = __toESM(require("fs"), 1);
142
145
  var import_node_path2 = __toESM(require("path"), 1);
143
146
  var import_node_crypto = require("crypto");
147
+ var import_ai = require("@prestyj/ai");
144
148
  var MAX_BYTES = 10 * 1024 * 1024;
145
149
  var fd = null;
146
150
  var sessionId = "";
147
151
  var appName = "app";
148
152
  var cleanups = [];
153
+ var exactSecrets = [];
149
154
  function rotateIfNeeded(filePath) {
150
155
  try {
151
156
  const st = import_node_fs.default.statSync(filePath);
@@ -162,6 +167,7 @@ function rotateIfNeeded(filePath) {
162
167
  function openLog(filePath, name) {
163
168
  if (fd !== null) return false;
164
169
  appName = name;
170
+ exactSecrets = (0, import_ai.environmentSecrets)(process.env);
165
171
  try {
166
172
  import_node_fs.default.mkdirSync(import_node_path2.default.dirname(filePath), { recursive: true, mode: 448 });
167
173
  } catch {
@@ -188,9 +194,15 @@ function isLoggerOpen() {
188
194
  function log(level, category, message, data) {
189
195
  if (fd === null) return;
190
196
  const ts = (/* @__PURE__ */ new Date()).toISOString();
191
- let line = `[${ts}] [sid=${sessionId}] [${level}] [${category}] ${message}`;
197
+ const safeMessage = (0, import_ai.redactText)(message, { secrets: exactSecrets });
198
+ let line = `[${ts}] [sid=${sessionId}] [${level}] [${category}] ${safeMessage}`;
192
199
  if (data) {
193
- const pairs = Object.entries(data).map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
200
+ const safeData = (0, import_ai.redactValue)(data, { secrets: exactSecrets });
201
+ const pairs = Object.entries(safeData).map(([k, v]) => {
202
+ if (typeof v === "string") return `${k}=${v}`;
203
+ if (typeof v === "bigint") return `${k}=${String(v)}`;
204
+ return `${k}=${JSON.stringify(v)}`;
205
+ }).join(" ");
194
206
  if (pairs) line += ` ${pairs}`;
195
207
  }
196
208
  line += "\n";
@@ -210,6 +222,7 @@ function closeLogger(opts) {
210
222
  } catch {
211
223
  }
212
224
  fd = null;
225
+ exactSecrets = [];
213
226
  for (const unsub of cleanups) unsub();
214
227
  cleanups = [];
215
228
  }
@@ -1219,6 +1232,7 @@ function isAlive(pid) {
1219
1232
  var MOONSHOT_OAUTH_KEY = "moonshot-oauth";
1220
1233
  var XIAOMI_CREDITS_KEY = "xiaomi-credits";
1221
1234
  var REFRESH_SKEW_MS = 6e4;
1235
+ var USAGE_EXHAUSTED_DEFAULT_MS = 15 * 60 * 1e3;
1222
1236
  var STATIC_API_KEY_PROVIDERS = /* @__PURE__ */ new Set([
1223
1237
  "glm",
1224
1238
  "moonshot",
@@ -1226,7 +1240,8 @@ var STATIC_API_KEY_PROVIDERS = /* @__PURE__ */ new Set([
1226
1240
  "minimax",
1227
1241
  "deepseek",
1228
1242
  "openrouter",
1229
- "sakana"
1243
+ "sakana",
1244
+ "xai"
1230
1245
  ]);
1231
1246
  var AuthStorage = class {
1232
1247
  data = {};
@@ -1285,7 +1300,9 @@ var AuthStorage = class {
1285
1300
  async isStaticApiKey(provider) {
1286
1301
  await this.ensureLoaded();
1287
1302
  if (provider === "moonshot" && this.data[MOONSHOT_OAUTH_KEY]) {
1288
- return false;
1303
+ const exhaustedUntil = this.data[MOONSHOT_OAUTH_KEY].usageExhaustedUntil ?? 0;
1304
+ const apiKeyActive = Date.now() < exhaustedUntil && Boolean(this.data["moonshot"]);
1305
+ if (!apiKeyActive) return false;
1289
1306
  }
1290
1307
  return STATIC_API_KEY_PROVIDERS.has(provider);
1291
1308
  }
@@ -1342,6 +1359,30 @@ var AuthStorage = class {
1342
1359
  delete this.data[provider];
1343
1360
  await this.save();
1344
1361
  }
1362
+ /**
1363
+ * Mark the credential stored under `storageKey` as usage-exhausted until
1364
+ * `resetsAt` (unix SECONDS, from the provider's rate-limit response) or a
1365
+ * 15-minute default when no reset time is known. While the mark is in the
1366
+ * future, `resolveCredentials("moonshot")` serves the Moonshot API key
1367
+ * instead of the Kimi OAuth credential (when both are configured) — OAuth
1368
+ * stays the preferred credential and is retried automatically once the mark
1369
+ * lapses. Persisted to auth.json so a restart (or another ezcoder-app window)
1370
+ * doesn't burn a request rediscovering the same exhausted window. No-op if
1371
+ * nothing is stored under `storageKey`.
1372
+ */
1373
+ async markUsageExhausted(storageKey, resetsAt) {
1374
+ await this.ensureLoaded();
1375
+ const creds = this.data[storageKey];
1376
+ if (!creds) return;
1377
+ const until = resetsAt !== void 0 && resetsAt * 1e3 > Date.now() ? resetsAt * 1e3 : Date.now() + USAGE_EXHAUSTED_DEFAULT_MS;
1378
+ creds.usageExhaustedUntil = until;
1379
+ await this.save();
1380
+ log(
1381
+ "WARN",
1382
+ "auth",
1383
+ `Marked ${storageKey} usage-exhausted until ${new Date(until).toISOString()}`
1384
+ );
1385
+ }
1345
1386
  async clearAll() {
1346
1387
  this.data = {};
1347
1388
  await this.save();
@@ -1362,8 +1403,19 @@ var AuthStorage = class {
1362
1403
  throw new NotLoggedInError(provider);
1363
1404
  }
1364
1405
  if (provider === "moonshot" && this.data[MOONSHOT_OAUTH_KEY]) {
1406
+ const exhaustedUntil = this.data[MOONSHOT_OAUTH_KEY].usageExhaustedUntil ?? 0;
1407
+ if (Date.now() < exhaustedUntil && this.data["moonshot"]) {
1408
+ log(
1409
+ "WARN",
1410
+ "auth",
1411
+ `Kimi OAuth usage window is exhausted \u2014 using the Moonshot API key until ${new Date(exhaustedUntil).toISOString()} (OAuth resumes automatically).`
1412
+ );
1413
+ return this.data["moonshot"];
1414
+ }
1365
1415
  try {
1366
- return await this.resolveCredentials(MOONSHOT_OAUTH_KEY, opts);
1416
+ return await this.resolveCredentials(MOONSHOT_OAUTH_KEY, {
1417
+ ...opts?.forceRefresh ? { forceRefresh: true } : {}
1418
+ });
1367
1419
  } catch (err) {
1368
1420
  if (err instanceof NotLoggedInError && this.data["moonshot"]) {
1369
1421
  log(
@@ -1537,13 +1589,11 @@ var MODELS = [
1537
1589
  maxThinkingLevel: "high"
1538
1590
  },
1539
1591
  // ── 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.
1592
+ // GPT-5.6 family — three agentic coding tiers launched July 2026. The public
1593
+ // Responses API advertises a 1.05M context window; OpenAI's Codex product
1594
+ // catalog advertises 372K on the ChatGPT OAuth route. All three take
1595
+ // text+image input, freeform apply_patch, text+image web search, and parallel
1596
+ // tool calls.
1547
1597
  {
1548
1598
  // Sol — "Latest frontier agentic coding model." (priority 1, default low).
1549
1599
  // Reasoning ladder: low → medium → high → xhigh → max → ultra. Ultra is a
@@ -1552,7 +1602,8 @@ var MODELS = [
1552
1602
  id: "gpt-5.6-sol",
1553
1603
  name: "GPT-5.6 Sol",
1554
1604
  provider: "openai",
1555
- contextWindow: 372e3,
1605
+ contextWindow: 105e4,
1606
+ codexContextWindow: 372e3,
1556
1607
  maxOutputTokens: 128e3,
1557
1608
  supportsThinking: true,
1558
1609
  supportsImages: true,
@@ -1562,11 +1613,12 @@ var MODELS = [
1562
1613
  },
1563
1614
  {
1564
1615
  // Terra — "Balanced agentic coding model for everyday work." (priority 2,
1565
- // default medium). Same 372K context + ultra reasoning ladder as Sol.
1616
+ // default medium).
1566
1617
  id: "gpt-5.6-terra",
1567
1618
  name: "GPT-5.6 Terra",
1568
1619
  provider: "openai",
1569
- contextWindow: 372e3,
1620
+ contextWindow: 105e4,
1621
+ codexContextWindow: 372e3,
1570
1622
  maxOutputTokens: 128e3,
1571
1623
  supportsThinking: true,
1572
1624
  supportsImages: true,
@@ -1576,11 +1628,12 @@ var MODELS = [
1576
1628
  },
1577
1629
  {
1578
1630
  // Luna — "Fast and affordable agentic coding model." (priority 3, default
1579
- // medium). Same 372K context; reasoning tops out at `max` (no `ultra` rung).
1631
+ // medium). Reasoning tops out at `max`.
1580
1632
  id: "gpt-5.6-luna",
1581
1633
  name: "GPT-5.6 Luna",
1582
1634
  provider: "openai",
1583
- contextWindow: 372e3,
1635
+ contextWindow: 105e4,
1636
+ codexContextWindow: 372e3,
1584
1637
  maxOutputTokens: 128e3,
1585
1638
  supportsThinking: true,
1586
1639
  supportsImages: true,
@@ -1631,6 +1684,26 @@ var MODELS = [
1631
1684
  costTier: "high",
1632
1685
  maxThinkingLevel: "xhigh"
1633
1686
  },
1687
+ // ── xAI (Grok) ─────────────────────────────────────────
1688
+ // Grok 4.5 (released 2026-07-08) is xAI's flagship for coding, agentic
1689
+ // tasks, and knowledge work — 500K context, text+image input, configurable
1690
+ // `reasoning_effort` (low/medium/high, server default high; reasoning can't
1691
+ // be fully disabled). Served over the OpenAI-compatible API at
1692
+ // https://api.x.ai/v1 (API key from console.x.ai). xAI hasn't published an
1693
+ // official max-output cap for 4.5; 131K matches the Grok Responses ceiling
1694
+ // third-party integrations use.
1695
+ {
1696
+ id: "grok-4.5",
1697
+ name: "Grok 4.5",
1698
+ provider: "xai",
1699
+ contextWindow: 5e5,
1700
+ maxOutputTokens: 131072,
1701
+ supportsThinking: true,
1702
+ supportsImages: true,
1703
+ supportsVideo: false,
1704
+ costTier: "medium",
1705
+ maxThinkingLevel: "high"
1706
+ },
1634
1707
  // ── Gemini ─────────────────────────────────────────────
1635
1708
  {
1636
1709
  id: "gemini-3.1-flash-lite",
@@ -1678,9 +1751,28 @@ var MODELS = [
1678
1751
  maxThinkingLevel: "high"
1679
1752
  },
1680
1753
  // ── Moonshot (Kimi) ────────────────────────────────────
1754
+ // K3 is Kimi's 2.8T-parameter flagship for long-horizon coding, knowledge
1755
+ // work, and deep reasoning. It always reasons at the `max` effort; the public
1756
+ // API uses `reasoning_effort`, while Kimi Code OAuth keeps its managed wire shape.
1757
+ {
1758
+ id: "kimi-k3",
1759
+ name: "Kimi K3",
1760
+ provider: "moonshot",
1761
+ contextWindow: 1048576,
1762
+ // The API can be raised as high as the full context window, but 131K is the
1763
+ // documented default and keeps room for input in AgentSession's fixed cap.
1764
+ maxOutputTokens: 131072,
1765
+ supportsThinking: true,
1766
+ supportsImages: true,
1767
+ supportsVideo: true,
1768
+ maxVideoBytes: 100 * 1024 * 1024,
1769
+ costTier: "high",
1770
+ maxThinkingLevel: "max"
1771
+ },
1772
+ // Retain the cheaper dedicated coding model as an explicit alternative.
1681
1773
  {
1682
1774
  id: "kimi-k2.7-code",
1683
- name: "Kimi K2.7",
1775
+ name: "Kimi K2.7 Code",
1684
1776
  provider: "moonshot",
1685
1777
  contextWindow: 262144,
1686
1778
  maxOutputTokens: 262144,
@@ -1870,16 +1962,20 @@ function getDefaultModel(provider) {
1870
1962
  if (provider === "openai") return MODELS.find((m) => m.id === "gpt-5.6-sol");
1871
1963
  if (provider === "gemini") return MODELS.find((m) => m.id === "gemini-3.1-flash-lite");
1872
1964
  if (provider === "glm") return MODELS.find((m) => m.id === "glm-5.2");
1873
- if (provider === "moonshot") return MODELS.find((m) => m.id === "kimi-k2.7-code");
1965
+ if (provider === "moonshot") return MODELS.find((m) => m.id === "kimi-k3");
1874
1966
  if (provider === "minimax") return MODELS.find((m) => m.id === "MiniMax-M3");
1875
1967
  if (provider === "deepseek") return MODELS.find((m) => m.id === "deepseek-v4-pro");
1876
1968
  if (provider === "openrouter") return MODELS.find((m) => m.id === "qwen/qwen3.6-plus");
1877
1969
  if (provider === "sakana") return MODELS.find((m) => m.id === "fugu");
1970
+ if (provider === "xai") return MODELS.find((m) => m.id === "grok-4.5");
1878
1971
  return MODELS.find((m) => m.id === "claude-sonnet-5");
1879
1972
  }
1880
1973
  function usesOpenAICodexTransport(options) {
1881
1974
  return options?.provider === "openai" && Boolean(options.accountId);
1882
1975
  }
1976
+ function getToolResultCharLimit(_modelId, options) {
1977
+ return usesOpenAICodexTransport(options) ? 1e4 * 4 : void 0;
1978
+ }
1883
1979
  function getContextWindow(modelId, options) {
1884
1980
  const model = getModel(modelId);
1885
1981
  if (!model) return 2e5;
@@ -1917,6 +2013,7 @@ var OPENAI_GPT_56_THINKING_LEVELS = [
1917
2013
  "ultra"
1918
2014
  ];
1919
2015
  var SAKANA_THINKING_LEVELS = ["high", "xhigh"];
2016
+ var XAI_THINKING_LEVELS = ["low", "medium", "high"];
1920
2017
  var ANTHROPIC_OPUS_48_47_THINKING_LEVELS = [
1921
2018
  "low",
1922
2019
  "medium",
@@ -1936,6 +2033,9 @@ function isOpenAIGptModel(provider, model) {
1936
2033
  function isSakanaModel(provider) {
1937
2034
  return provider === "sakana";
1938
2035
  }
2036
+ function isXaiModel(provider) {
2037
+ return provider === "xai";
2038
+ }
1939
2039
  function isAnthropicOpus48Or47Model(provider, model) {
1940
2040
  return provider === "anthropic" && /opus-4-8|opus-4-7/.test(model);
1941
2041
  }
@@ -1955,6 +2055,11 @@ function getSupportedThinkingLevels(provider, model) {
1955
2055
  if (maxIndex2 === -1) return SAKANA_THINKING_LEVELS;
1956
2056
  return SAKANA_THINKING_LEVELS.slice(0, maxIndex2 + 1);
1957
2057
  }
2058
+ if (isXaiModel(provider)) {
2059
+ const maxIndex2 = XAI_THINKING_LEVELS.indexOf(maxLevel);
2060
+ if (maxIndex2 === -1) return XAI_THINKING_LEVELS;
2061
+ return XAI_THINKING_LEVELS.slice(0, maxIndex2 + 1);
2062
+ }
1958
2063
  if (!isOpenAIGptModel(provider, model)) return [maxLevel];
1959
2064
  const levels = model.startsWith("gpt-5.6-") ? OPENAI_GPT_56_THINKING_LEVELS : OPENAI_GPT_THINKING_LEVELS;
1960
2065
  const maxIndex = levels.indexOf(maxLevel);
@@ -1966,7 +2071,7 @@ function isThinkingLevelSupported(provider, model, level) {
1966
2071
  }
1967
2072
  function getNextThinkingLevel(provider, model, current) {
1968
2073
  const supportedLevels = getSupportedThinkingLevels(provider, model);
1969
- const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider);
2074
+ const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider) || isXaiModel(provider);
1970
2075
  if (!shouldCycleLevels) {
1971
2076
  return current ? void 0 : supportedLevels[0];
1972
2077
  }
@@ -2627,6 +2732,7 @@ function createAutoUpdater(config) {
2627
2732
  getSessionId,
2628
2733
  getSummaryModel,
2629
2734
  getSupportedThinkingLevels,
2735
+ getToolResultCharLimit,
2630
2736
  getVideoByteLimit,
2631
2737
  isKimiCodingEndpoint,
2632
2738
  isLoggerOpen,