@prestyj/ai 5.27.0 → 5.28.1
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/README.md +2 -2
- package/dist/index.cjs +66 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +66 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1033,7 +1033,7 @@ function isAdaptiveThinkingModel(model) {
|
|
|
1033
1033
|
function toAnthropicThinking(level, maxTokens, model) {
|
|
1034
1034
|
if (isAdaptiveThinkingModel(model)) {
|
|
1035
1035
|
let effort = level;
|
|
1036
|
-
if (effort === "xhigh" && !/opus-5|opus-4
|
|
1036
|
+
if (effort === "xhigh" && !/opus-5|opus-4[-.]8|opus-4[-.]7|sonnet-5[-.]5/.test(model)) {
|
|
1037
1037
|
effort = "high";
|
|
1038
1038
|
}
|
|
1039
1039
|
return {
|
|
@@ -2036,7 +2036,7 @@ async function* runStream2(options) {
|
|
|
2036
2036
|
const endpointKey = reasoningFieldKey(providerName, options.baseUrl, options.model);
|
|
2037
2037
|
const client = createClient2(options);
|
|
2038
2038
|
const isLocal = options.provider === "local";
|
|
2039
|
-
const isKimiK3 = options.provider === "moonshot" && options.model === "kimi-k3";
|
|
2039
|
+
const isKimiK3 = options.provider === "moonshot" && (options.model === "kimi-k3" || options.model === "kimi-for-coding");
|
|
2040
2040
|
const isManagedKimiK3 = isKimiK3 && options.baseUrl?.replace(/\/+$/, "").endsWith("/coding/v1") === true;
|
|
2041
2041
|
const k3Effort = options.thinking ? toKimiK3Effort(options.thinking) : void 0;
|
|
2042
2042
|
const isKimiK27 = options.provider === "moonshot" && options.model.startsWith("kimi-k2.7-code");
|
|
@@ -2510,7 +2510,7 @@ function extractRequestIdFromMessage(message) {
|
|
|
2510
2510
|
|
|
2511
2511
|
// src/providers/openai-codex.ts
|
|
2512
2512
|
var DEFAULT_BASE_URL = "https://chatgpt.com/backend-api";
|
|
2513
|
-
var CODEX_CLIENT_VERSION = "0.
|
|
2513
|
+
var CODEX_CLIENT_VERSION = "0.159.1";
|
|
2514
2514
|
var CODEX_REQUEST_COMPRESSION_MIN_BYTES = 16 * 1024;
|
|
2515
2515
|
var zstdInitPromise;
|
|
2516
2516
|
async function encodeCodexRequest(body) {
|
|
@@ -2556,7 +2556,7 @@ async function encodeCodexRequest(body) {
|
|
|
2556
2556
|
}
|
|
2557
2557
|
}
|
|
2558
2558
|
function usesResponsesLite(model) {
|
|
2559
|
-
return model.startsWith("gpt-5.6-") || model.startsWith("gpt-6-");
|
|
2559
|
+
return model.startsWith("gpt-5.6-") || model.startsWith("gpt-6-") || model.startsWith("gpt-6.");
|
|
2560
2560
|
}
|
|
2561
2561
|
function outputTextKey(itemId, contentIndex) {
|
|
2562
2562
|
return `${itemId ?? ""}:${contentIndex ?? 0}`;
|
|
@@ -2678,7 +2678,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2678
2678
|
if (response.status === 400 && message === `The '${options.model}' model is not supported when using Codex with a ChatGPT account.`) {
|
|
2679
2679
|
hint = "This model is not available through your ChatGPT account. Switch to a model listed for OpenAI via the model selector, or check your ChatGPT usage limits.";
|
|
2680
2680
|
} else if (response.status === 404 && text.includes("does not exist")) {
|
|
2681
|
-
hint = "This model is not in OpenAI's current catalog for your ChatGPT account. Switch to GPT-6 Astra, GPT-6 Sol, or GPT-6 Luna via the model selector.";
|
|
2681
|
+
hint = "This model is not in OpenAI's current catalog for your ChatGPT account. Switch to GPT-6 Astra, GPT-6.1 Sol, or GPT-6 Luna via the model selector.";
|
|
2682
2682
|
}
|
|
2683
2683
|
throw new ProviderError("openai", message, {
|
|
2684
2684
|
statusCode: response.status,
|
|
@@ -2692,6 +2692,8 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2692
2692
|
const contentParts = [];
|
|
2693
2693
|
let textAccum = "";
|
|
2694
2694
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
2695
|
+
const finishedToolCalls = /* @__PURE__ */ new Set();
|
|
2696
|
+
let terminal;
|
|
2695
2697
|
const orderedItems = [];
|
|
2696
2698
|
const outputItemTypes = /* @__PURE__ */ new Map();
|
|
2697
2699
|
const outputTextByPart = /* @__PURE__ */ new Map();
|
|
@@ -2835,6 +2837,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2835
2837
|
for (const [key, tc] of toolCalls) {
|
|
2836
2838
|
if (key.endsWith(`|${itemId}`)) {
|
|
2837
2839
|
tc.argsJson = argsStr;
|
|
2840
|
+
finishedToolCalls.add(key);
|
|
2838
2841
|
break;
|
|
2839
2842
|
}
|
|
2840
2843
|
}
|
|
@@ -2860,6 +2863,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2860
2863
|
const id = `${callId}|${itemId}`;
|
|
2861
2864
|
const tc = toolCalls.get(id);
|
|
2862
2865
|
if (tc) {
|
|
2866
|
+
finishedToolCalls.add(id);
|
|
2863
2867
|
orderedItems.push({ kind: "tool", id });
|
|
2864
2868
|
const args = parseToolArguments(tc.argsJson);
|
|
2865
2869
|
yield {
|
|
@@ -2871,8 +2875,17 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2871
2875
|
}
|
|
2872
2876
|
}
|
|
2873
2877
|
}
|
|
2874
|
-
if (type === "response.completed" || type === "response.done") {
|
|
2878
|
+
if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
|
|
2875
2879
|
const resp = event.response;
|
|
2880
|
+
if (type === "response.incomplete" || resp?.status === "incomplete") {
|
|
2881
|
+
const details = resp?.incomplete_details;
|
|
2882
|
+
terminal = {
|
|
2883
|
+
status: "incomplete",
|
|
2884
|
+
reason: typeof details?.reason === "string" ? details.reason : void 0
|
|
2885
|
+
};
|
|
2886
|
+
} else {
|
|
2887
|
+
terminal = { status: "completed" };
|
|
2888
|
+
}
|
|
2876
2889
|
const usage = resp?.usage;
|
|
2877
2890
|
if (usage) {
|
|
2878
2891
|
cacheRead = usage.input_tokens_details?.cached_tokens ?? 0;
|
|
@@ -2882,6 +2895,25 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2882
2895
|
}
|
|
2883
2896
|
}
|
|
2884
2897
|
}
|
|
2898
|
+
if (!terminal) {
|
|
2899
|
+
throw new ProviderError("openai", "Stream ended before completion (no response.completed).", {
|
|
2900
|
+
statusCode: 504
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
const droppedToolCalls = [...toolCalls.keys()].filter((id) => !finishedToolCalls.has(id)).length;
|
|
2904
|
+
if (terminal.status === "completed") {
|
|
2905
|
+
for (const [id, tc] of toolCalls) {
|
|
2906
|
+
if (!finishedToolCalls.has(id)) {
|
|
2907
|
+
throw new ProviderError(
|
|
2908
|
+
"openai",
|
|
2909
|
+
`Codex reply completed with an unfinished tool call: ${tc.name} (${id}).`,
|
|
2910
|
+
{ statusCode: 502 }
|
|
2911
|
+
);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
} else {
|
|
2915
|
+
providerDiag("codex_incomplete", { reason: terminal.reason ?? null, droppedToolCalls });
|
|
2916
|
+
}
|
|
2885
2917
|
const seenTool = /* @__PURE__ */ new Set();
|
|
2886
2918
|
let textInserted = false;
|
|
2887
2919
|
for (const entry of orderedItems) {
|
|
@@ -2908,7 +2940,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2908
2940
|
contentParts.push({ type: "text", text: textAccum });
|
|
2909
2941
|
}
|
|
2910
2942
|
for (const [id, tc] of toolCalls) {
|
|
2911
|
-
if (seenTool.has(id)) continue;
|
|
2943
|
+
if (seenTool.has(id) || !finishedToolCalls.has(id)) continue;
|
|
2912
2944
|
seenTool.add(id);
|
|
2913
2945
|
contentParts.push({
|
|
2914
2946
|
type: "tool_call",
|
|
@@ -2917,8 +2949,15 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2917
2949
|
args: parseToolArguments(tc.argsJson)
|
|
2918
2950
|
});
|
|
2919
2951
|
}
|
|
2952
|
+
if (droppedToolCalls > 0) {
|
|
2953
|
+
let last = contentParts.at(-1);
|
|
2954
|
+
while (last?.type === "raw" && isEncryptedReasoning(last.data)) {
|
|
2955
|
+
contentParts.pop();
|
|
2956
|
+
last = contentParts.at(-1);
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2920
2959
|
const hasToolCalls = contentParts.some((p) => p.type === "tool_call");
|
|
2921
|
-
const stopReason = hasToolCalls ? "tool_use" : "end_turn";
|
|
2960
|
+
const stopReason = terminal.status === "incomplete" ? incompleteStopReason(terminal.reason) : hasToolCalls ? "tool_use" : "end_turn";
|
|
2922
2961
|
const streamResponse = {
|
|
2923
2962
|
message: {
|
|
2924
2963
|
role: "assistant",
|
|
@@ -2935,6 +2974,11 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2935
2974
|
yield { type: "done", stopReason };
|
|
2936
2975
|
return streamResponse;
|
|
2937
2976
|
}
|
|
2977
|
+
function incompleteStopReason(reason) {
|
|
2978
|
+
if (reason === "max_output_tokens") return "max_tokens";
|
|
2979
|
+
if (reason === "content_filter") return "refusal";
|
|
2980
|
+
return "error";
|
|
2981
|
+
}
|
|
2938
2982
|
async function* parseSSE(body) {
|
|
2939
2983
|
for await (const event of readSseStream(body)) {
|
|
2940
2984
|
const data = event.data.trim();
|
|
@@ -4070,6 +4114,8 @@ var CIRCULAR = "[CIRCULAR]";
|
|
|
4070
4114
|
var SENSITIVE_NAME = /(?:^|[_-])(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|key|auth(?:orization)?|bearer|cookie|credential|private[_-]?key|password|passwd|secret)(?:$|[_-])/i;
|
|
4071
4115
|
var ENV_SECRET_ASSIGNMENT = /\b((?:[A-Z0-9]+_)*(?:API_?KEY|ACCESS_TOKEN|REFRESH_TOKEN|TOKEN|KEY|AUTH|AUTHORIZATION|BEARER|CREDENTIALS?|PASSWORD|PASSWD|SECRET))\b(\s*[=:]\s*)(["']?)(?!\$|process\.env|os\.environ|import\.meta|env\.)(?=[^\s,"';}]*\d)([^\s,"';}=$][^\s,"';}]{7,})\3/g;
|
|
4072
4116
|
var COMPACT_SECRET_ASSIGNMENT = /\b((?:[a-z0-9]+[_-])*(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|auth|authorization|credentials?|password|passwd|secret)|(?:[a-z0-9]+[_-])+key)=(["']?)(?!\$)([^\s,"'&;}=][^\s,"'&;}]{7,})\2/gi;
|
|
4117
|
+
var URL_USERINFO = /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/?#@:"'`<>]*:[^\s/?#"'`<>]+@/gi;
|
|
4118
|
+
var URL_USERINFO_TO_FIRST_AT = /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]*:[^\s/@]+@/gi;
|
|
4073
4119
|
function escaped(value) {
|
|
4074
4120
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4075
4121
|
}
|
|
@@ -4093,7 +4139,8 @@ function redactText(text, options = {}) {
|
|
|
4093
4139
|
/-----BEGIN (?:[A-Z0-9 ]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z0-9 ]+ )?PRIVATE KEY-----/g,
|
|
4094
4140
|
REDACTED
|
|
4095
4141
|
);
|
|
4096
|
-
result = result.replace(
|
|
4142
|
+
result = result.replace(URL_USERINFO, `$1${REDACTED}@`);
|
|
4143
|
+
result = result.replace(URL_USERINFO_TO_FIRST_AT, `$1${REDACTED}@`);
|
|
4097
4144
|
result = result.replace(
|
|
4098
4145
|
/\b(authorization\s*[:=]\s*)(?:bearer|basic)\s+[^\s,;]+/gi,
|
|
4099
4146
|
`$1${REDACTED}`
|
|
@@ -4137,7 +4184,7 @@ function isMediaObject(value) {
|
|
|
4137
4184
|
function redactValue(value, options = {}) {
|
|
4138
4185
|
const maxDepth = options.maxDepth ?? 20;
|
|
4139
4186
|
const maxEntries = options.maxEntries ?? 1e4;
|
|
4140
|
-
const
|
|
4187
|
+
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
4141
4188
|
let entries = 0;
|
|
4142
4189
|
const visit = (current, depth, sensitive = false) => {
|
|
4143
4190
|
if (typeof current === "string") {
|
|
@@ -4151,8 +4198,15 @@ function redactValue(value, options = {}) {
|
|
|
4151
4198
|
if (isBinary(current)) return current;
|
|
4152
4199
|
if (current instanceof Date) return new Date(current.getTime());
|
|
4153
4200
|
if (depth >= maxDepth) return TRUNCATED;
|
|
4154
|
-
if (
|
|
4155
|
-
|
|
4201
|
+
if (ancestors.has(current)) return CIRCULAR;
|
|
4202
|
+
ancestors.add(current);
|
|
4203
|
+
try {
|
|
4204
|
+
return cloneObject(current, depth);
|
|
4205
|
+
} finally {
|
|
4206
|
+
ancestors.delete(current);
|
|
4207
|
+
}
|
|
4208
|
+
};
|
|
4209
|
+
const cloneObject = (current, depth) => {
|
|
4156
4210
|
if (current instanceof Error) {
|
|
4157
4211
|
const error = {
|
|
4158
4212
|
name: current.name,
|