@prestyj/ai 5.8.0 → 5.9.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 +44 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +44 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -41,6 +41,21 @@ interface ToolResult {
|
|
|
41
41
|
toolCallId: string;
|
|
42
42
|
content: ToolResultContent;
|
|
43
43
|
isError?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Set when the agent loop trimmed `content` to fit a per-result or per-turn
|
|
46
|
+
* budget. The provider (model input) and the persistent transcript both see
|
|
47
|
+
* the trimmed `content`, but the live `tool_call_end` event carried the FULL
|
|
48
|
+
* preview — so this marker makes that divergence explicit and reconcilable.
|
|
49
|
+
* Internal metadata only: it is never serialized onto the provider wire.
|
|
50
|
+
*/
|
|
51
|
+
capped?: {
|
|
52
|
+
/** Length of the original, untrimmed string content. */
|
|
53
|
+
originalChars: number;
|
|
54
|
+
/** Length of the trimmed content actually sent to the model. */
|
|
55
|
+
keptChars: number;
|
|
56
|
+
/** Which budget triggered the trim. */
|
|
57
|
+
scope: "per-result" | "per-turn";
|
|
58
|
+
};
|
|
44
59
|
}
|
|
45
60
|
interface ServerToolCall {
|
|
46
61
|
type: "server_tool_call";
|
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,21 @@ interface ToolResult {
|
|
|
41
41
|
toolCallId: string;
|
|
42
42
|
content: ToolResultContent;
|
|
43
43
|
isError?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Set when the agent loop trimmed `content` to fit a per-result or per-turn
|
|
46
|
+
* budget. The provider (model input) and the persistent transcript both see
|
|
47
|
+
* the trimmed `content`, but the live `tool_call_end` event carried the FULL
|
|
48
|
+
* preview — so this marker makes that divergence explicit and reconcilable.
|
|
49
|
+
* Internal metadata only: it is never serialized onto the provider wire.
|
|
50
|
+
*/
|
|
51
|
+
capped?: {
|
|
52
|
+
/** Length of the original, untrimmed string content. */
|
|
53
|
+
originalChars: number;
|
|
54
|
+
/** Length of the trimmed content actually sent to the model. */
|
|
55
|
+
keptChars: number;
|
|
56
|
+
/** Which budget triggered the trim. */
|
|
57
|
+
scope: "per-result" | "per-turn";
|
|
58
|
+
};
|
|
44
59
|
}
|
|
45
60
|
interface ServerToolCall {
|
|
46
61
|
type: "server_tool_call";
|
package/dist/index.js
CHANGED
|
@@ -264,6 +264,9 @@ function providerGuidance(provider, message, statusCode) {
|
|
|
264
264
|
if (lower.includes("context_length_exceeded") || lower.includes("prompt is too long")) {
|
|
265
265
|
return `Context window for this ${name} model is full. Compact the conversation to shrink history, or start a new session.`;
|
|
266
266
|
}
|
|
267
|
+
if (lower.includes("many-image request") || lower.includes("image dimensions") && lower.includes("max allowed size")) {
|
|
268
|
+
return `An image in conversation history exceeds ${name}'s many-image limit. Restart EZ Coder so restored images are resized, then retry; if it persists, start a new session.`;
|
|
269
|
+
}
|
|
267
270
|
if (statusCode === 413 || lower.includes("request_too_large") || lower.includes("request exceeds the maximum size")) {
|
|
268
271
|
return `The request to ${name} is too large. Compact the conversation to shrink history, or start a new session.`;
|
|
269
272
|
}
|
|
@@ -760,9 +763,14 @@ function toAnthropicMessages(messages, cacheControl) {
|
|
|
760
763
|
continue;
|
|
761
764
|
}
|
|
762
765
|
if (msg.role === "user") {
|
|
766
|
+
if (typeof msg.content === "string") {
|
|
767
|
+
if (msg.content === "") continue;
|
|
768
|
+
} else if (!msg.content.some((p) => !(p.type === "text" && p.text === ""))) {
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
763
771
|
out.push({
|
|
764
772
|
role: "user",
|
|
765
|
-
content: typeof msg.content === "string" ? msg.content : msg.content.map((part) => {
|
|
773
|
+
content: typeof msg.content === "string" ? msg.content : msg.content.filter((part) => !(part.type === "text" && part.text === "")).map((part) => {
|
|
766
774
|
if (part.type === "text") return { type: "text", text: part.text };
|
|
767
775
|
if (part.type === "video") {
|
|
768
776
|
return {
|
|
@@ -787,6 +795,7 @@ function toAnthropicMessages(messages, cacheControl) {
|
|
|
787
795
|
continue;
|
|
788
796
|
}
|
|
789
797
|
if (msg.role === "assistant") {
|
|
798
|
+
if (typeof msg.content === "string" && msg.content === "") continue;
|
|
790
799
|
const content = typeof msg.content === "string" ? msg.content : toAnthropicAssistantContent(msg.content, msgIdx > trajectoryStartIdx, idMap);
|
|
791
800
|
if (Array.isArray(content) && content.length === 0) continue;
|
|
792
801
|
out.push({ role: "assistant", content });
|
|
@@ -907,7 +916,7 @@ function remapToolCallId(id, idMap) {
|
|
|
907
916
|
if (!id.startsWith("toolu_")) return id;
|
|
908
917
|
const existing = idMap.get(id);
|
|
909
918
|
if (existing) return existing;
|
|
910
|
-
const mapped = `call_${id.slice(
|
|
919
|
+
const mapped = `call_${id.slice(6)}`;
|
|
911
920
|
idMap.set(id, mapped);
|
|
912
921
|
return mapped;
|
|
913
922
|
}
|
|
@@ -1518,6 +1527,12 @@ async function* runStream(options) {
|
|
|
1518
1527
|
statusCode: 504
|
|
1519
1528
|
});
|
|
1520
1529
|
}
|
|
1530
|
+
if (stopReason === null) {
|
|
1531
|
+
throw new ProviderError("anthropic", "Stream ended before completion (no stop_reason).", {
|
|
1532
|
+
statusCode: 504,
|
|
1533
|
+
cause: { partialContent: contentParts, outputTokens }
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1521
1536
|
const normalizedStop = normalizeAnthropicStopReason(stopReason);
|
|
1522
1537
|
const response = {
|
|
1523
1538
|
message: {
|
|
@@ -1784,6 +1799,17 @@ function getEnvironment() {
|
|
|
1784
1799
|
}
|
|
1785
1800
|
|
|
1786
1801
|
// src/providers/openai.ts
|
|
1802
|
+
function toKimiK3Effort(level) {
|
|
1803
|
+
switch (level) {
|
|
1804
|
+
case "low":
|
|
1805
|
+
return "low";
|
|
1806
|
+
case "medium":
|
|
1807
|
+
case "high":
|
|
1808
|
+
return "high";
|
|
1809
|
+
default:
|
|
1810
|
+
return "max";
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1787
1813
|
function extractOpenAIUsage(usage) {
|
|
1788
1814
|
let cacheRead = 0;
|
|
1789
1815
|
let cacheWrite = 0;
|
|
@@ -1840,6 +1866,7 @@ async function* runStream2(options) {
|
|
|
1840
1866
|
const client = createClient2(options);
|
|
1841
1867
|
const isKimiK3 = options.provider === "moonshot" && options.model === "kimi-k3";
|
|
1842
1868
|
const isManagedKimiK3 = isKimiK3 && options.baseUrl?.replace(/\/+$/, "").endsWith("/coding/v1") === true;
|
|
1869
|
+
const k3Effort = options.thinking ? toKimiK3Effort(options.thinking) : void 0;
|
|
1843
1870
|
const isKimiK27 = options.provider === "moonshot" && options.model.startsWith("kimi-k2.7-code");
|
|
1844
1871
|
const hasFixedKimiSampling = isKimiK3 || isKimiK27;
|
|
1845
1872
|
const usesThinkingParam = options.provider === "glm" || options.provider === "moonshot" && !isKimiK3 && !isKimiK27 || options.provider === "xiaomi";
|
|
@@ -1854,9 +1881,11 @@ async function* runStream2(options) {
|
|
|
1854
1881
|
}
|
|
1855
1882
|
const messages = toOpenAIMessages(downgradedMessages, {
|
|
1856
1883
|
provider: options.provider,
|
|
1857
|
-
//
|
|
1858
|
-
//
|
|
1859
|
-
|
|
1884
|
+
// K2.7 preserves reasoning even when the user hides thinking in the UI;
|
|
1885
|
+
// keep assistant tool-call history wire-valid in that display mode. A
|
|
1886
|
+
// disabled K3 must NOT carry placeholder reasoning_content (mirrors the
|
|
1887
|
+
// official CLI: reasoning is preserved only while thinking is enabled).
|
|
1888
|
+
thinking: isKimiK27 || !!options.thinking,
|
|
1860
1889
|
supportsImages: options.supportsImages
|
|
1861
1890
|
});
|
|
1862
1891
|
const defaultTemp = options.provider === "glm" ? 0.6 : void 0;
|
|
@@ -1889,9 +1918,11 @@ async function* runStream2(options) {
|
|
|
1889
1918
|
if (isKimiK3) {
|
|
1890
1919
|
const paramsAny = params;
|
|
1891
1920
|
if (isManagedKimiK3) {
|
|
1892
|
-
paramsAny.thinking = { type: "enabled", effort:
|
|
1921
|
+
paramsAny.thinking = k3Effort ? { type: "enabled", effort: k3Effort, keep: "all" } : { type: "disabled" };
|
|
1922
|
+
} else if (k3Effort) {
|
|
1923
|
+
paramsAny.reasoning_effort = k3Effort;
|
|
1893
1924
|
} else {
|
|
1894
|
-
paramsAny.
|
|
1925
|
+
paramsAny.thinking = { type: "disabled" };
|
|
1895
1926
|
}
|
|
1896
1927
|
}
|
|
1897
1928
|
if (usesThinkingParam) {
|
|
@@ -1997,6 +2028,12 @@ async function* runStream2(options) {
|
|
|
1997
2028
|
statusCode: 504
|
|
1998
2029
|
});
|
|
1999
2030
|
}
|
|
2031
|
+
if (finishReason === null) {
|
|
2032
|
+
throw new ProviderError(providerName, "Stream ended before completion (no finish_reason).", {
|
|
2033
|
+
statusCode: 504,
|
|
2034
|
+
cause: { partialText: textAccum, outputTokens }
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2000
2037
|
if (thinkingAccum) {
|
|
2001
2038
|
contentParts.push({ type: "thinking", text: thinkingAccum });
|
|
2002
2039
|
}
|