@prestyj/ai 5.4.0 → 5.5.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
@@ -873,7 +873,7 @@ function toAnthropicThinking(level, maxTokens, model) {
873
873
  };
874
874
  }
875
875
  const VISIBLE_FLOOR = 1024;
876
- const effectiveLevel = level === "xhigh" || level === "max" ? "high" : level;
876
+ const effectiveLevel = level === "xhigh" || level === "max" || level === "ultra" ? "high" : level;
877
877
  const budgetMap = {
878
878
  low: Math.max(1024, Math.floor(maxTokens * 0.2)),
879
879
  medium: Math.max(2048, Math.floor(maxTokens * 0.45)),
@@ -1041,7 +1041,7 @@ function toOpenAIToolChoice(choice) {
1041
1041
  return { type: "function", function: { name: choice.name } };
1042
1042
  }
1043
1043
  function toOpenAIReasoningEffort(level, model) {
1044
- const effort = level === "max" ? "xhigh" : level;
1044
+ const effort = level === "max" || level === "ultra" ? "xhigh" : level;
1045
1045
  if (model.startsWith("fugu") && (effort === "low" || effort === "medium")) {
1046
1046
  return "high";
1047
1047
  }
@@ -1767,11 +1767,16 @@ function getEnvironment() {
1767
1767
  // src/providers/openai.ts
1768
1768
  function extractOpenAIUsage(usage) {
1769
1769
  let cacheRead = 0;
1770
+ let cacheWrite = 0;
1770
1771
  const details = usage.prompt_tokens_details;
1771
1772
  if (details?.cached_tokens) {
1772
1773
  cacheRead = details.cached_tokens;
1773
1774
  }
1774
1775
  const usageAny = usage;
1776
+ const detailsAny = details;
1777
+ if (typeof detailsAny?.cache_write_tokens === "number") {
1778
+ cacheWrite = detailsAny.cache_write_tokens;
1779
+ }
1775
1780
  if (!cacheRead && typeof usageAny.cached_tokens === "number" && usageAny.cached_tokens > 0) {
1776
1781
  cacheRead = usageAny.cached_tokens;
1777
1782
  }
@@ -1779,9 +1784,10 @@ function extractOpenAIUsage(usage) {
1779
1784
  cacheRead = usageAny.prompt_cache_hit_tokens;
1780
1785
  }
1781
1786
  return {
1782
- inputTokens: usage.prompt_tokens - cacheRead,
1787
+ inputTokens: usage.prompt_tokens - cacheRead - cacheWrite,
1783
1788
  outputTokens: usage.completion_tokens,
1784
- cacheRead
1789
+ cacheRead,
1790
+ cacheWrite
1785
1791
  };
1786
1792
  }
1787
1793
  var openaiClientCache = /* @__PURE__ */ new Map();
@@ -1846,8 +1852,9 @@ async function* runStream2(options) {
1846
1852
  if (options.provider === "openai" || options.provider === "moonshot") {
1847
1853
  const paramsAny = params;
1848
1854
  paramsAny.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? "ezcoder");
1849
- const retention = options.cacheRetention ?? "short";
1850
- if (retention === "long") {
1855
+ if (options.provider === "openai" && options.model.startsWith("gpt-5.6")) {
1856
+ paramsAny.prompt_cache_options = { mode: "implicit", ttl: "30m" };
1857
+ } else if ((options.cacheRetention ?? "short") === "long") {
1851
1858
  paramsAny.prompt_cache_retention = "24h";
1852
1859
  }
1853
1860
  }
@@ -1898,6 +1905,7 @@ async function* runStream2(options) {
1898
1905
  let inputTokens = 0;
1899
1906
  let outputTokens = 0;
1900
1907
  let cacheRead = 0;
1908
+ let cacheWrite = 0;
1901
1909
  let finishReason = null;
1902
1910
  let receivedAnyChunk = false;
1903
1911
  try {
@@ -1905,7 +1913,7 @@ async function* runStream2(options) {
1905
1913
  receivedAnyChunk = true;
1906
1914
  const choice = chunk.choices?.[0];
1907
1915
  if (chunk.usage) {
1908
- ({ inputTokens, outputTokens, cacheRead } = extractOpenAIUsage(chunk.usage));
1916
+ ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(chunk.usage));
1909
1917
  }
1910
1918
  if (!choice) continue;
1911
1919
  if (choice.finish_reason) {
@@ -1985,7 +1993,12 @@ async function* runStream2(options) {
1985
1993
  content: contentParts.length > 0 ? contentParts : textAccum || ""
1986
1994
  },
1987
1995
  stopReason,
1988
- usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
1996
+ usage: {
1997
+ inputTokens,
1998
+ outputTokens,
1999
+ ...cacheRead > 0 && { cacheRead },
2000
+ ...cacheWrite > 0 && { cacheWrite }
2001
+ }
1989
2002
  };
1990
2003
  yield { type: "done", stopReason };
1991
2004
  return response;
@@ -2058,8 +2071,9 @@ function completionToResponse(completion) {
2058
2071
  let inputTokens = 0;
2059
2072
  let outputTokens = 0;
2060
2073
  let cacheRead = 0;
2074
+ let cacheWrite = 0;
2061
2075
  if (completion.usage) {
2062
- ({ inputTokens, outputTokens, cacheRead } = extractOpenAIUsage(completion.usage));
2076
+ ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(completion.usage));
2063
2077
  }
2064
2078
  const stopReason = normalizeOpenAIStopReason(choice?.finish_reason ?? null);
2065
2079
  return {
@@ -2068,7 +2082,12 @@ function completionToResponse(completion) {
2068
2082
  content: contentParts.length > 0 ? contentParts : textAccum
2069
2083
  },
2070
2084
  stopReason,
2071
- usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
2085
+ usage: {
2086
+ inputTokens,
2087
+ outputTokens,
2088
+ ...cacheRead > 0 && { cacheRead },
2089
+ ...cacheWrite > 0 && { cacheWrite }
2090
+ }
2072
2091
  };
2073
2092
  }
2074
2093
  function classifyOpenAICompatLimit(args) {
@@ -2190,6 +2209,10 @@ function extractRequestIdFromMessage(message) {
2190
2209
 
2191
2210
  // src/providers/openai-codex.ts
2192
2211
  var DEFAULT_BASE_URL = "https://chatgpt.com/backend-api";
2212
+ var CODEX_CLIENT_VERSION = "0.144.1";
2213
+ function usesResponsesLite(model) {
2214
+ return model.startsWith("gpt-5.6-");
2215
+ }
2193
2216
  function outputTextKey(itemId, contentIndex) {
2194
2217
  return `${itemId ?? ""}:${contentIndex ?? 0}`;
2195
2218
  }
@@ -2205,6 +2228,7 @@ async function* runStream3(options) {
2205
2228
  const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);
2206
2229
  const downgraded = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);
2207
2230
  const { system, input } = toCodexInput(downgraded, { supportsImages: options.supportsImages });
2231
+ const responsesLite = usesResponsesLite(options.model);
2208
2232
  const body = {
2209
2233
  model: options.model,
2210
2234
  store: false,
@@ -2212,7 +2236,7 @@ async function* runStream3(options) {
2212
2236
  instructions: system,
2213
2237
  input,
2214
2238
  tool_choice: "auto",
2215
- parallel_tool_calls: true,
2239
+ parallel_tool_calls: !responsesLite,
2216
2240
  include: ["reasoning.encrypted_content"]
2217
2241
  };
2218
2242
  if (options.tools?.length) {
@@ -2223,24 +2247,29 @@ async function* runStream3(options) {
2223
2247
  body.temperature = options.temperature;
2224
2248
  }
2225
2249
  body.reasoning = {
2226
- effort: options.thinking ?? "none",
2227
- summary: "auto"
2250
+ // `ultra` is a client orchestration preset, not a Codex API effort.
2251
+ effort: options.thinking === "ultra" ? "max" : options.thinking ?? "none",
2252
+ summary: "auto",
2253
+ ...responsesLite ? { context: "all_turns" } : {}
2228
2254
  };
2229
2255
  const headers = {
2230
2256
  "Content-Type": "application/json",
2231
2257
  Accept: "text/event-stream",
2232
2258
  Authorization: `Bearer ${options.apiKey}`,
2233
2259
  "OpenAI-Beta": "responses=experimental",
2234
- originator: "ezcoder",
2235
- "User-Agent": `ezcoder (${import_node_os.default.platform()} ${import_node_os.default.release()}; ${import_node_os.default.arch()})`
2260
+ originator: responsesLite ? "codex_cli_rs" : "ezcoder",
2261
+ "User-Agent": responsesLite ? `codex_cli_rs/${CODEX_CLIENT_VERSION}` : `ezcoder (${import_node_os.default.platform()} ${import_node_os.default.release()}; ${import_node_os.default.arch()})`,
2262
+ ...responsesLite ? {
2263
+ version: CODEX_CLIENT_VERSION,
2264
+ "X-OpenAI-Internal-Codex-Responses-Lite": "true"
2265
+ } : {}
2236
2266
  };
2237
2267
  if (options.accountId) {
2238
2268
  headers["chatgpt-account-id"] = options.accountId;
2239
2269
  }
2240
- const cacheScopeId = body.prompt_cache_key;
2241
- if (cacheScopeId) {
2242
- headers["session_id"] = cacheScopeId;
2243
- headers["x-client-request-id"] = cacheScopeId;
2270
+ if (options.transportSessionId) {
2271
+ headers["session_id"] = options.transportSessionId;
2272
+ headers["x-client-request-id"] = options.transportSessionId;
2244
2273
  }
2245
2274
  const response = await fetch(url, {
2246
2275
  method: "POST",
@@ -2284,6 +2313,7 @@ async function* runStream3(options) {
2284
2313
  let inputTokens = 0;
2285
2314
  let outputTokens = 0;
2286
2315
  let cacheRead = 0;
2316
+ let cacheWrite = 0;
2287
2317
  const diagStart = Date.now();
2288
2318
  const diagSeen = /* @__PURE__ */ new Set();
2289
2319
  for await (const event of parseSSE(response.body)) {
@@ -2460,7 +2490,8 @@ async function* runStream3(options) {
2460
2490
  const usage = resp?.usage;
2461
2491
  if (usage) {
2462
2492
  cacheRead = usage.input_tokens_details?.cached_tokens ?? 0;
2463
- inputTokens = (usage.input_tokens ?? 0) - cacheRead;
2493
+ cacheWrite = usage.input_tokens_details?.cache_write_tokens ?? 0;
2494
+ inputTokens = (usage.input_tokens ?? 0) - cacheRead - cacheWrite;
2464
2495
  outputTokens = usage.output_tokens ?? 0;
2465
2496
  }
2466
2497
  }
@@ -2508,7 +2539,12 @@ async function* runStream3(options) {
2508
2539
  content: contentParts.length > 0 ? contentParts : textAccum || ""
2509
2540
  },
2510
2541
  stopReason,
2511
- usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
2542
+ usage: {
2543
+ inputTokens,
2544
+ outputTokens,
2545
+ ...cacheRead > 0 && { cacheRead },
2546
+ ...cacheWrite > 0 && { cacheWrite }
2547
+ }
2512
2548
  };
2513
2549
  yield { type: "done", stopReason };
2514
2550
  return streamResponse;
@@ -2871,6 +2907,7 @@ function toGemini3ThinkingLevel(level) {
2871
2907
  case "high":
2872
2908
  case "xhigh":
2873
2909
  case "max":
2910
+ case "ultra":
2874
2911
  return "HIGH";
2875
2912
  }
2876
2913
  }
@@ -2883,6 +2920,7 @@ function toThinkingBudget(level) {
2883
2920
  case "high":
2884
2921
  case "xhigh":
2885
2922
  case "max":
2923
+ case "ultra":
2886
2924
  return 8192;
2887
2925
  }
2888
2926
  }