@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 +59 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +59 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
1795
|
-
|
|
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: {
|
|
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: {
|
|
2030
|
+
usage: {
|
|
2031
|
+
inputTokens,
|
|
2032
|
+
outputTokens,
|
|
2033
|
+
...cacheRead > 0 && { cacheRead },
|
|
2034
|
+
...cacheWrite > 0 && { cacheWrite }
|
|
2035
|
+
}
|
|
2017
2036
|
};
|
|
2018
2037
|
}
|
|
2019
2038
|
function classifyOpenAICompatLimit(args) {
|
|
@@ -2135,6 +2154,10 @@ function extractRequestIdFromMessage(message) {
|
|
|
2135
2154
|
|
|
2136
2155
|
// src/providers/openai-codex.ts
|
|
2137
2156
|
var DEFAULT_BASE_URL = "https://chatgpt.com/backend-api";
|
|
2157
|
+
var CODEX_CLIENT_VERSION = "0.144.1";
|
|
2158
|
+
function usesResponsesLite(model) {
|
|
2159
|
+
return model.startsWith("gpt-5.6-");
|
|
2160
|
+
}
|
|
2138
2161
|
function outputTextKey(itemId, contentIndex) {
|
|
2139
2162
|
return `${itemId ?? ""}:${contentIndex ?? 0}`;
|
|
2140
2163
|
}
|
|
@@ -2150,6 +2173,7 @@ async function* runStream3(options) {
|
|
|
2150
2173
|
const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);
|
|
2151
2174
|
const downgraded = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);
|
|
2152
2175
|
const { system, input } = toCodexInput(downgraded, { supportsImages: options.supportsImages });
|
|
2176
|
+
const responsesLite = usesResponsesLite(options.model);
|
|
2153
2177
|
const body = {
|
|
2154
2178
|
model: options.model,
|
|
2155
2179
|
store: false,
|
|
@@ -2157,7 +2181,7 @@ async function* runStream3(options) {
|
|
|
2157
2181
|
instructions: system,
|
|
2158
2182
|
input,
|
|
2159
2183
|
tool_choice: "auto",
|
|
2160
|
-
parallel_tool_calls:
|
|
2184
|
+
parallel_tool_calls: !responsesLite,
|
|
2161
2185
|
include: ["reasoning.encrypted_content"]
|
|
2162
2186
|
};
|
|
2163
2187
|
if (options.tools?.length) {
|
|
@@ -2168,24 +2192,29 @@ async function* runStream3(options) {
|
|
|
2168
2192
|
body.temperature = options.temperature;
|
|
2169
2193
|
}
|
|
2170
2194
|
body.reasoning = {
|
|
2171
|
-
|
|
2172
|
-
|
|
2195
|
+
// `ultra` is a client orchestration preset, not a Codex API effort.
|
|
2196
|
+
effort: options.thinking === "ultra" ? "max" : options.thinking ?? "none",
|
|
2197
|
+
summary: "auto",
|
|
2198
|
+
...responsesLite ? { context: "all_turns" } : {}
|
|
2173
2199
|
};
|
|
2174
2200
|
const headers = {
|
|
2175
2201
|
"Content-Type": "application/json",
|
|
2176
2202
|
Accept: "text/event-stream",
|
|
2177
2203
|
Authorization: `Bearer ${options.apiKey}`,
|
|
2178
2204
|
"OpenAI-Beta": "responses=experimental",
|
|
2179
|
-
originator: "ezcoder",
|
|
2180
|
-
"User-Agent": `ezcoder (${os.platform()} ${os.release()}; ${os.arch()})
|
|
2205
|
+
originator: responsesLite ? "codex_cli_rs" : "ezcoder",
|
|
2206
|
+
"User-Agent": responsesLite ? `codex_cli_rs/${CODEX_CLIENT_VERSION}` : `ezcoder (${os.platform()} ${os.release()}; ${os.arch()})`,
|
|
2207
|
+
...responsesLite ? {
|
|
2208
|
+
version: CODEX_CLIENT_VERSION,
|
|
2209
|
+
"X-OpenAI-Internal-Codex-Responses-Lite": "true"
|
|
2210
|
+
} : {}
|
|
2181
2211
|
};
|
|
2182
2212
|
if (options.accountId) {
|
|
2183
2213
|
headers["chatgpt-account-id"] = options.accountId;
|
|
2184
2214
|
}
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
headers["
|
|
2188
|
-
headers["x-client-request-id"] = cacheScopeId;
|
|
2215
|
+
if (options.transportSessionId) {
|
|
2216
|
+
headers["session_id"] = options.transportSessionId;
|
|
2217
|
+
headers["x-client-request-id"] = options.transportSessionId;
|
|
2189
2218
|
}
|
|
2190
2219
|
const response = await fetch(url, {
|
|
2191
2220
|
method: "POST",
|
|
@@ -2229,6 +2258,7 @@ async function* runStream3(options) {
|
|
|
2229
2258
|
let inputTokens = 0;
|
|
2230
2259
|
let outputTokens = 0;
|
|
2231
2260
|
let cacheRead = 0;
|
|
2261
|
+
let cacheWrite = 0;
|
|
2232
2262
|
const diagStart = Date.now();
|
|
2233
2263
|
const diagSeen = /* @__PURE__ */ new Set();
|
|
2234
2264
|
for await (const event of parseSSE(response.body)) {
|
|
@@ -2405,7 +2435,8 @@ async function* runStream3(options) {
|
|
|
2405
2435
|
const usage = resp?.usage;
|
|
2406
2436
|
if (usage) {
|
|
2407
2437
|
cacheRead = usage.input_tokens_details?.cached_tokens ?? 0;
|
|
2408
|
-
|
|
2438
|
+
cacheWrite = usage.input_tokens_details?.cache_write_tokens ?? 0;
|
|
2439
|
+
inputTokens = (usage.input_tokens ?? 0) - cacheRead - cacheWrite;
|
|
2409
2440
|
outputTokens = usage.output_tokens ?? 0;
|
|
2410
2441
|
}
|
|
2411
2442
|
}
|
|
@@ -2453,7 +2484,12 @@ async function* runStream3(options) {
|
|
|
2453
2484
|
content: contentParts.length > 0 ? contentParts : textAccum || ""
|
|
2454
2485
|
},
|
|
2455
2486
|
stopReason,
|
|
2456
|
-
usage: {
|
|
2487
|
+
usage: {
|
|
2488
|
+
inputTokens,
|
|
2489
|
+
outputTokens,
|
|
2490
|
+
...cacheRead > 0 && { cacheRead },
|
|
2491
|
+
...cacheWrite > 0 && { cacheWrite }
|
|
2492
|
+
}
|
|
2457
2493
|
};
|
|
2458
2494
|
yield { type: "done", stopReason };
|
|
2459
2495
|
return streamResponse;
|
|
@@ -2816,6 +2852,7 @@ function toGemini3ThinkingLevel(level) {
|
|
|
2816
2852
|
case "high":
|
|
2817
2853
|
case "xhigh":
|
|
2818
2854
|
case "max":
|
|
2855
|
+
case "ultra":
|
|
2819
2856
|
return "HIGH";
|
|
2820
2857
|
}
|
|
2821
2858
|
}
|
|
@@ -2828,6 +2865,7 @@ function toThinkingBudget(level) {
|
|
|
2828
2865
|
case "high":
|
|
2829
2866
|
case "xhigh":
|
|
2830
2867
|
case "max":
|
|
2868
|
+
case "ultra":
|
|
2831
2869
|
return 8192;
|
|
2832
2870
|
}
|
|
2833
2871
|
}
|