@prestyj/ai 5.4.1 → 5.6.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.d.cts CHANGED
@@ -3,7 +3,7 @@ import Anthropic from '@anthropic-ai/sdk';
3
3
  import OpenAI from 'openai';
4
4
 
5
5
  type Provider = "anthropic" | "xiaomi" | "openai" | "gemini" | "glm" | "moonshot" | "minimax" | "deepseek" | "openrouter" | "sakana" | "palsu";
6
- type ThinkingLevel = "low" | "medium" | "high" | "xhigh" | "max";
6
+ type ThinkingLevel = "low" | "medium" | "high" | "xhigh" | "max" | "ultra";
7
7
  type CacheRetention = "none" | "short" | "long";
8
8
  interface TextContent {
9
9
  type: "text";
@@ -175,6 +175,10 @@ interface StreamOptions {
175
175
  serviceTier?: "auto" | "default" | "flex" | "priority";
176
176
  /** OpenAI ChatGPT account ID (from OAuth JWT) for codex endpoint */
177
177
  accountId?: string;
178
+ /** Stable conversation identity for Codex transport headers. This is distinct from
179
+ * promptCacheKey: sessions with matching prefixes may share a cache key, but must
180
+ * retain independent session/thread identities. */
181
+ transportSessionId?: string;
178
182
  /** Google Cloud/Code Assist project ID used by Gemini OAuth transport. */
179
183
  projectId?: string;
180
184
  /** Enable provider-native web search. Each provider uses its own format:
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import Anthropic from '@anthropic-ai/sdk';
3
3
  import OpenAI from 'openai';
4
4
 
5
5
  type Provider = "anthropic" | "xiaomi" | "openai" | "gemini" | "glm" | "moonshot" | "minimax" | "deepseek" | "openrouter" | "sakana" | "palsu";
6
- type ThinkingLevel = "low" | "medium" | "high" | "xhigh" | "max";
6
+ type ThinkingLevel = "low" | "medium" | "high" | "xhigh" | "max" | "ultra";
7
7
  type CacheRetention = "none" | "short" | "long";
8
8
  interface TextContent {
9
9
  type: "text";
@@ -175,6 +175,10 @@ interface StreamOptions {
175
175
  serviceTier?: "auto" | "default" | "flex" | "priority";
176
176
  /** OpenAI ChatGPT account ID (from OAuth JWT) for codex endpoint */
177
177
  accountId?: string;
178
+ /** Stable conversation identity for Codex transport headers. This is distinct from
179
+ * promptCacheKey: sessions with matching prefixes may share a cache key, but must
180
+ * retain independent session/thread identities. */
181
+ transportSessionId?: string;
178
182
  /** Google Cloud/Code Assist project ID used by Gemini OAuth transport. */
179
183
  projectId?: string;
180
184
  /** Enable provider-native web search. Each provider uses its own format:
package/dist/index.js CHANGED
@@ -818,7 +818,7 @@ function toAnthropicThinking(level, maxTokens, model) {
818
818
  };
819
819
  }
820
820
  const VISIBLE_FLOOR = 1024;
821
- const effectiveLevel = level === "xhigh" || level === "max" ? "high" : level;
821
+ const effectiveLevel = level === "xhigh" || level === "max" || level === "ultra" ? "high" : level;
822
822
  const budgetMap = {
823
823
  low: Math.max(1024, Math.floor(maxTokens * 0.2)),
824
824
  medium: Math.max(2048, Math.floor(maxTokens * 0.45)),
@@ -986,7 +986,7 @@ function toOpenAIToolChoice(choice) {
986
986
  return { type: "function", function: { name: choice.name } };
987
987
  }
988
988
  function toOpenAIReasoningEffort(level, model) {
989
- const effort = level === "max" ? "xhigh" : level;
989
+ const effort = level === "max" || level === "ultra" ? "xhigh" : level;
990
990
  if (model.startsWith("fugu") && (effort === "low" || effort === "medium")) {
991
991
  return "high";
992
992
  }
@@ -1712,11 +1712,16 @@ function getEnvironment() {
1712
1712
  // src/providers/openai.ts
1713
1713
  function extractOpenAIUsage(usage) {
1714
1714
  let cacheRead = 0;
1715
+ let cacheWrite = 0;
1715
1716
  const details = usage.prompt_tokens_details;
1716
1717
  if (details?.cached_tokens) {
1717
1718
  cacheRead = details.cached_tokens;
1718
1719
  }
1719
1720
  const usageAny = usage;
1721
+ const detailsAny = details;
1722
+ if (typeof detailsAny?.cache_write_tokens === "number") {
1723
+ cacheWrite = detailsAny.cache_write_tokens;
1724
+ }
1720
1725
  if (!cacheRead && typeof usageAny.cached_tokens === "number" && usageAny.cached_tokens > 0) {
1721
1726
  cacheRead = usageAny.cached_tokens;
1722
1727
  }
@@ -1724,9 +1729,10 @@ function extractOpenAIUsage(usage) {
1724
1729
  cacheRead = usageAny.prompt_cache_hit_tokens;
1725
1730
  }
1726
1731
  return {
1727
- inputTokens: usage.prompt_tokens - cacheRead,
1732
+ inputTokens: usage.prompt_tokens - cacheRead - cacheWrite,
1728
1733
  outputTokens: usage.completion_tokens,
1729
- cacheRead
1734
+ cacheRead,
1735
+ cacheWrite
1730
1736
  };
1731
1737
  }
1732
1738
  var openaiClientCache = /* @__PURE__ */ new Map();
@@ -1791,8 +1797,9 @@ async function* runStream2(options) {
1791
1797
  if (options.provider === "openai" || options.provider === "moonshot") {
1792
1798
  const paramsAny = params;
1793
1799
  paramsAny.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? "ezcoder");
1794
- const retention = options.cacheRetention ?? "short";
1795
- if (retention === "long") {
1800
+ if (options.provider === "openai" && options.model.startsWith("gpt-5.6")) {
1801
+ paramsAny.prompt_cache_options = { mode: "implicit", ttl: "30m" };
1802
+ } else if ((options.cacheRetention ?? "short") === "long") {
1796
1803
  paramsAny.prompt_cache_retention = "24h";
1797
1804
  }
1798
1805
  }
@@ -1843,6 +1850,7 @@ async function* runStream2(options) {
1843
1850
  let inputTokens = 0;
1844
1851
  let outputTokens = 0;
1845
1852
  let cacheRead = 0;
1853
+ let cacheWrite = 0;
1846
1854
  let finishReason = null;
1847
1855
  let receivedAnyChunk = false;
1848
1856
  try {
@@ -1850,7 +1858,7 @@ async function* runStream2(options) {
1850
1858
  receivedAnyChunk = true;
1851
1859
  const choice = chunk.choices?.[0];
1852
1860
  if (chunk.usage) {
1853
- ({ inputTokens, outputTokens, cacheRead } = extractOpenAIUsage(chunk.usage));
1861
+ ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(chunk.usage));
1854
1862
  }
1855
1863
  if (!choice) continue;
1856
1864
  if (choice.finish_reason) {
@@ -1930,7 +1938,12 @@ async function* runStream2(options) {
1930
1938
  content: contentParts.length > 0 ? contentParts : textAccum || ""
1931
1939
  },
1932
1940
  stopReason,
1933
- usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
1941
+ usage: {
1942
+ inputTokens,
1943
+ outputTokens,
1944
+ ...cacheRead > 0 && { cacheRead },
1945
+ ...cacheWrite > 0 && { cacheWrite }
1946
+ }
1934
1947
  };
1935
1948
  yield { type: "done", stopReason };
1936
1949
  return response;
@@ -2003,8 +2016,9 @@ function completionToResponse(completion) {
2003
2016
  let inputTokens = 0;
2004
2017
  let outputTokens = 0;
2005
2018
  let cacheRead = 0;
2019
+ let cacheWrite = 0;
2006
2020
  if (completion.usage) {
2007
- ({ inputTokens, outputTokens, cacheRead } = extractOpenAIUsage(completion.usage));
2021
+ ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(completion.usage));
2008
2022
  }
2009
2023
  const stopReason = normalizeOpenAIStopReason(choice?.finish_reason ?? null);
2010
2024
  return {
@@ -2013,7 +2027,12 @@ function completionToResponse(completion) {
2013
2027
  content: contentParts.length > 0 ? contentParts : textAccum
2014
2028
  },
2015
2029
  stopReason,
2016
- usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
2030
+ usage: {
2031
+ inputTokens,
2032
+ outputTokens,
2033
+ ...cacheRead > 0 && { cacheRead },
2034
+ ...cacheWrite > 0 && { cacheWrite }
2035
+ }
2017
2036
  };
2018
2037
  }
2019
2038
  function classifyOpenAICompatLimit(args) {
@@ -2173,7 +2192,8 @@ async function* runStream3(options) {
2173
2192
  body.temperature = options.temperature;
2174
2193
  }
2175
2194
  body.reasoning = {
2176
- effort: options.thinking ?? "none",
2195
+ // `ultra` is a client orchestration preset, not a Codex API effort.
2196
+ effort: options.thinking === "ultra" ? "max" : options.thinking ?? "none",
2177
2197
  summary: "auto",
2178
2198
  ...responsesLite ? { context: "all_turns" } : {}
2179
2199
  };
@@ -2192,10 +2212,9 @@ async function* runStream3(options) {
2192
2212
  if (options.accountId) {
2193
2213
  headers["chatgpt-account-id"] = options.accountId;
2194
2214
  }
2195
- const cacheScopeId = body.prompt_cache_key;
2196
- if (cacheScopeId) {
2197
- headers["session_id"] = cacheScopeId;
2198
- headers["x-client-request-id"] = cacheScopeId;
2215
+ if (options.transportSessionId) {
2216
+ headers["session_id"] = options.transportSessionId;
2217
+ headers["x-client-request-id"] = options.transportSessionId;
2199
2218
  }
2200
2219
  const response = await fetch(url, {
2201
2220
  method: "POST",
@@ -2239,6 +2258,7 @@ async function* runStream3(options) {
2239
2258
  let inputTokens = 0;
2240
2259
  let outputTokens = 0;
2241
2260
  let cacheRead = 0;
2261
+ let cacheWrite = 0;
2242
2262
  const diagStart = Date.now();
2243
2263
  const diagSeen = /* @__PURE__ */ new Set();
2244
2264
  for await (const event of parseSSE(response.body)) {
@@ -2415,7 +2435,8 @@ async function* runStream3(options) {
2415
2435
  const usage = resp?.usage;
2416
2436
  if (usage) {
2417
2437
  cacheRead = usage.input_tokens_details?.cached_tokens ?? 0;
2418
- inputTokens = (usage.input_tokens ?? 0) - cacheRead;
2438
+ cacheWrite = usage.input_tokens_details?.cache_write_tokens ?? 0;
2439
+ inputTokens = (usage.input_tokens ?? 0) - cacheRead - cacheWrite;
2419
2440
  outputTokens = usage.output_tokens ?? 0;
2420
2441
  }
2421
2442
  }
@@ -2463,7 +2484,12 @@ async function* runStream3(options) {
2463
2484
  content: contentParts.length > 0 ? contentParts : textAccum || ""
2464
2485
  },
2465
2486
  stopReason,
2466
- usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
2487
+ usage: {
2488
+ inputTokens,
2489
+ outputTokens,
2490
+ ...cacheRead > 0 && { cacheRead },
2491
+ ...cacheWrite > 0 && { cacheWrite }
2492
+ }
2467
2493
  };
2468
2494
  yield { type: "done", stopReason };
2469
2495
  return streamResponse;
@@ -2826,6 +2852,7 @@ function toGemini3ThinkingLevel(level) {
2826
2852
  case "high":
2827
2853
  case "xhigh":
2828
2854
  case "max":
2855
+ case "ultra":
2829
2856
  return "HIGH";
2830
2857
  }
2831
2858
  }
@@ -2838,6 +2865,7 @@ function toThinkingBudget(level) {
2838
2865
  case "high":
2839
2866
  case "xhigh":
2840
2867
  case "max":
2868
+ case "ultra":
2841
2869
  return 8192;
2842
2870
  }
2843
2871
  }