sparkecoder 0.1.139 → 0.1.140
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/agent/index.d.ts +3 -3
- package/dist/agent/index.js +107 -6
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +114 -6
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-BAsQWqZj.d.ts → index-Cl_eUatM.d.ts} +96 -96
- package/dist/index.d.ts +5 -5
- package/dist/index.js +114 -6
- package/dist/index.js.map +1 -1
- package/dist/{schema-Dz-wABVY.d.ts → schema-BSz4MzhJ.d.ts} +3 -3
- package/dist/{search-CVVfuBPZ.d.ts → search-DOzC4ojH.d.ts} +4 -4
- package/dist/server/index.js +114 -6
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +3 -3
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/standalone/web/runtime-config.json +2 -2
- /package/web/.next/standalone/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_ssgManifest.js +0 -0
- /package/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_buildManifest.js +0 -0
- /package/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_ssgManifest.js +0 -0
|
@@ -85,7 +85,7 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
85
85
|
tableName: "sessions";
|
|
86
86
|
dataType: "string";
|
|
87
87
|
columnType: "SQLiteText";
|
|
88
|
-
data: "
|
|
88
|
+
data: "error" | "completed" | "active" | "waiting";
|
|
89
89
|
driverParam: string;
|
|
90
90
|
notNull: true;
|
|
91
91
|
hasDefault: true;
|
|
@@ -391,7 +391,7 @@ declare const toolExecutions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
391
391
|
tableName: "tool_executions";
|
|
392
392
|
dataType: "string";
|
|
393
393
|
columnType: "SQLiteText";
|
|
394
|
-
data: "
|
|
394
|
+
data: "error" | "completed" | "pending" | "approved" | "rejected";
|
|
395
395
|
driverParam: string;
|
|
396
396
|
notNull: true;
|
|
397
397
|
hasDefault: true;
|
|
@@ -814,7 +814,7 @@ declare const terminals: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
814
814
|
tableName: "terminals";
|
|
815
815
|
dataType: "string";
|
|
816
816
|
columnType: "SQLiteText";
|
|
817
|
-
data: "
|
|
817
|
+
data: "error" | "running" | "stopped";
|
|
818
818
|
driverParam: string;
|
|
819
819
|
notNull: true;
|
|
820
820
|
hasDefault: true;
|
|
@@ -16,11 +16,11 @@ interface BashToolOptions {
|
|
|
16
16
|
declare function createBashTool(options: BashToolOptions): ai.Tool<{
|
|
17
17
|
background: boolean;
|
|
18
18
|
id?: string | undefined;
|
|
19
|
-
input?: string | undefined;
|
|
20
19
|
command?: string | undefined;
|
|
20
|
+
input?: string | undefined;
|
|
21
21
|
kill?: boolean | undefined;
|
|
22
22
|
tail?: number | undefined;
|
|
23
|
-
key?: "Enter" | "Escape" | "Up" | "Down" | "Left" | "Right" | "Tab" | "C-c" | "C-d" | "
|
|
23
|
+
key?: "y" | "Enter" | "Escape" | "Up" | "Down" | "Left" | "Right" | "Tab" | "C-c" | "C-d" | "n" | undefined;
|
|
24
24
|
}, {
|
|
25
25
|
success: boolean;
|
|
26
26
|
id: string;
|
|
@@ -66,7 +66,7 @@ declare function createBashTool(options: BashToolOptions): ai.Tool<{
|
|
|
66
66
|
id: string;
|
|
67
67
|
output: string;
|
|
68
68
|
exitCode: number;
|
|
69
|
-
status: "
|
|
69
|
+
status: "error" | "completed" | "running" | "stopped";
|
|
70
70
|
message?: undefined;
|
|
71
71
|
error?: undefined;
|
|
72
72
|
} | {
|
|
@@ -218,8 +218,8 @@ interface SearchToolOptions {
|
|
|
218
218
|
* Progress is streamed back to the UI so users can see exploration happening.
|
|
219
219
|
*/
|
|
220
220
|
declare function createSearchTool(options: SearchToolOptions): ai.Tool<{
|
|
221
|
-
query: string;
|
|
222
221
|
context: string;
|
|
222
|
+
query: string;
|
|
223
223
|
}, {
|
|
224
224
|
success: boolean;
|
|
225
225
|
error: string;
|
package/dist/server/index.js
CHANGED
|
@@ -7652,6 +7652,105 @@ var init_cap_image_count = __esm({
|
|
|
7652
7652
|
}
|
|
7653
7653
|
});
|
|
7654
7654
|
|
|
7655
|
+
// src/utils/sanitize-images.ts
|
|
7656
|
+
function hasImageMagic(bytes) {
|
|
7657
|
+
if (bytes.length < 12) return false;
|
|
7658
|
+
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) return true;
|
|
7659
|
+
if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return true;
|
|
7660
|
+
if (bytes[0] === 71 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 56) return true;
|
|
7661
|
+
if (bytes[0] === 82 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 70 && bytes[8] === 87 && bytes[9] === 69 && bytes[10] === 66 && bytes[11] === 80) return true;
|
|
7662
|
+
return false;
|
|
7663
|
+
}
|
|
7664
|
+
function extractBase64(part) {
|
|
7665
|
+
const raw = typeof part?.data === "string" ? part.data : typeof part?.image === "string" ? part.image : null;
|
|
7666
|
+
if (typeof raw !== "string" || raw.length === 0) return null;
|
|
7667
|
+
if (/^https?:\/\//i.test(raw)) return null;
|
|
7668
|
+
const dataUrl = raw.match(/^data:[^;,]+;base64,([\s\S]*)$/);
|
|
7669
|
+
return dataUrl ? dataUrl[1] : raw;
|
|
7670
|
+
}
|
|
7671
|
+
function isInvalidImagePart(part) {
|
|
7672
|
+
if (!part || typeof part !== "object") return false;
|
|
7673
|
+
const t = part.type;
|
|
7674
|
+
if (t !== "image" && t !== "image-data" && t !== "media") return false;
|
|
7675
|
+
const mt = part.mediaType;
|
|
7676
|
+
const b64 = extractBase64(part);
|
|
7677
|
+
if (b64 === null) {
|
|
7678
|
+
return typeof mt === "string" && mt.startsWith("image/") && !SUPPORTED_IMAGE_TYPES.includes(mt);
|
|
7679
|
+
}
|
|
7680
|
+
let bytes;
|
|
7681
|
+
try {
|
|
7682
|
+
bytes = Buffer.from(b64, "base64");
|
|
7683
|
+
} catch {
|
|
7684
|
+
return true;
|
|
7685
|
+
}
|
|
7686
|
+
if (bytes.length === 0) return true;
|
|
7687
|
+
return !hasImageMagic(bytes);
|
|
7688
|
+
}
|
|
7689
|
+
function placeholder() {
|
|
7690
|
+
return { type: "text", text: INVALID_IMAGE_PLACEHOLDER };
|
|
7691
|
+
}
|
|
7692
|
+
function sanitizeInvalidImages(messages) {
|
|
7693
|
+
if (!Array.isArray(messages) || messages.length === 0) return messages;
|
|
7694
|
+
let mutated = false;
|
|
7695
|
+
let dropped = 0;
|
|
7696
|
+
const out = messages.slice();
|
|
7697
|
+
for (let i = 0; i < out.length; i++) {
|
|
7698
|
+
const msg = out[i];
|
|
7699
|
+
if (!Array.isArray(msg.content)) continue;
|
|
7700
|
+
let contentCloned = false;
|
|
7701
|
+
const ensureCloned = () => {
|
|
7702
|
+
if (contentCloned) return;
|
|
7703
|
+
out[i] = { ...msg, content: [...msg.content] };
|
|
7704
|
+
contentCloned = true;
|
|
7705
|
+
};
|
|
7706
|
+
const content = () => out[i].content;
|
|
7707
|
+
for (let j = 0; j < content().length; j++) {
|
|
7708
|
+
const part = content()[j];
|
|
7709
|
+
if (isInvalidImagePart(part)) {
|
|
7710
|
+
ensureCloned();
|
|
7711
|
+
out[i].content[j] = placeholder();
|
|
7712
|
+
mutated = true;
|
|
7713
|
+
dropped++;
|
|
7714
|
+
continue;
|
|
7715
|
+
}
|
|
7716
|
+
if (part && typeof part === "object" && part.type === "tool-result" && part.output && part.output.type === "content" && Array.isArray(part.output.value)) {
|
|
7717
|
+
const innerValue = part.output.value;
|
|
7718
|
+
let innerMutated = false;
|
|
7719
|
+
const newValue = innerValue.slice();
|
|
7720
|
+
for (let k = 0; k < newValue.length; k++) {
|
|
7721
|
+
if (isInvalidImagePart(newValue[k])) {
|
|
7722
|
+
newValue[k] = placeholder();
|
|
7723
|
+
innerMutated = true;
|
|
7724
|
+
dropped++;
|
|
7725
|
+
}
|
|
7726
|
+
}
|
|
7727
|
+
if (innerMutated) {
|
|
7728
|
+
ensureCloned();
|
|
7729
|
+
out[i].content[j] = {
|
|
7730
|
+
...part,
|
|
7731
|
+
output: { ...part.output, value: newValue }
|
|
7732
|
+
};
|
|
7733
|
+
mutated = true;
|
|
7734
|
+
}
|
|
7735
|
+
}
|
|
7736
|
+
}
|
|
7737
|
+
}
|
|
7738
|
+
if (mutated) {
|
|
7739
|
+
console.warn(
|
|
7740
|
+
`[sanitize-images] Replaced ${dropped} invalid image part(s) with a text placeholder (non-image bytes / unsupported type) to avoid provider 400 "invalid image" errors.`
|
|
7741
|
+
);
|
|
7742
|
+
}
|
|
7743
|
+
return mutated ? out : messages;
|
|
7744
|
+
}
|
|
7745
|
+
var SUPPORTED_IMAGE_TYPES, INVALID_IMAGE_PLACEHOLDER;
|
|
7746
|
+
var init_sanitize_images = __esm({
|
|
7747
|
+
"src/utils/sanitize-images.ts"() {
|
|
7748
|
+
"use strict";
|
|
7749
|
+
SUPPORTED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
7750
|
+
INVALID_IMAGE_PLACEHOLDER = "[invalid image omitted \u2014 the data was not a valid jpeg/png/gif/webp]";
|
|
7751
|
+
}
|
|
7752
|
+
});
|
|
7753
|
+
|
|
7655
7754
|
// src/agent/model-limits.ts
|
|
7656
7755
|
function getModelLimits(modelId) {
|
|
7657
7756
|
const normalized = modelId.trim().toLowerCase();
|
|
@@ -7967,6 +8066,7 @@ var init_context = __esm({
|
|
|
7967
8066
|
init_prompts();
|
|
7968
8067
|
init_sanitize_messages();
|
|
7969
8068
|
init_cap_image_count();
|
|
8069
|
+
init_sanitize_images();
|
|
7970
8070
|
init_model_limits();
|
|
7971
8071
|
TOOL_OUTPUT_TRIM_CHARS = 400;
|
|
7972
8072
|
COMPACTABLE_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -8016,6 +8116,7 @@ ${summaryContent}`
|
|
|
8016
8116
|
messages = repairToolPairing(messages);
|
|
8017
8117
|
messages = ensureToolResultsFollowCalls(messages);
|
|
8018
8118
|
messages = ensureEndsWithUserOrTool(messages);
|
|
8119
|
+
messages = sanitizeInvalidImages(messages);
|
|
8019
8120
|
messages = capImageCount(messages);
|
|
8020
8121
|
messages = this.enforceHardCap(messages);
|
|
8021
8122
|
return messages;
|
|
@@ -8027,28 +8128,35 @@ ${summaryContent}`
|
|
|
8027
8128
|
* repairs tool pairing so dropping can't orphan a tool result.
|
|
8028
8129
|
*/
|
|
8029
8130
|
enforceHardCap(messages) {
|
|
8030
|
-
const {
|
|
8031
|
-
const
|
|
8131
|
+
const { rollingTarget } = getModelLimits(this.modelId);
|
|
8132
|
+
const MAX_MESSAGES = 120;
|
|
8133
|
+
const tokenCeiling = Math.max(2e4, Math.floor(rollingTarget * 1.5));
|
|
8032
8134
|
const tokens = messages.map((m) => this.messageTokens(m));
|
|
8033
8135
|
let total = tokens.reduce((a, b) => a + b, 0);
|
|
8034
|
-
if (total <= ceiling) return messages;
|
|
8035
8136
|
const hasLeadingSummary = messages.length > 0 && messages[0].role === "system";
|
|
8036
8137
|
const firstBody = hasLeadingSummary ? 1 : 0;
|
|
8037
8138
|
const lastIndex = messages.length - 1;
|
|
8139
|
+
const bodyCount = messages.length - firstBody;
|
|
8140
|
+
if (bodyCount <= MAX_MESSAGES && total <= tokenCeiling) return messages;
|
|
8038
8141
|
let start = firstBody;
|
|
8039
|
-
|
|
8142
|
+
const countDropTarget = messages.length - MAX_MESSAGES;
|
|
8143
|
+
while (start < countDropTarget && start < lastIndex) {
|
|
8144
|
+
total -= tokens[start];
|
|
8145
|
+
start += 1;
|
|
8146
|
+
}
|
|
8147
|
+
while (start < lastIndex && total > tokenCeiling) {
|
|
8040
8148
|
total -= tokens[start];
|
|
8041
8149
|
start += 1;
|
|
8042
8150
|
}
|
|
8043
8151
|
let out = hasLeadingSummary ? [messages[0], ...messages.slice(start)] : messages.slice(start);
|
|
8044
|
-
if (total >
|
|
8152
|
+
if (total > tokenCeiling) {
|
|
8045
8153
|
out = out.map((m) => hardTruncateMessageText(m));
|
|
8046
8154
|
}
|
|
8047
8155
|
out = repairToolPairing(out);
|
|
8048
8156
|
out = ensureToolResultsFollowCalls(out);
|
|
8049
8157
|
out = ensureEndsWithUserOrTool(out);
|
|
8050
8158
|
console.warn(
|
|
8051
|
-
`[Context] hard cap engaged for ${this.modelId}: trimmed ${messages.length}\u2192${out.length} msgs (ceiling ${
|
|
8159
|
+
`[Context] hard cap engaged for ${this.modelId}: trimmed ${messages.length}\u2192${out.length} msgs (ceiling ${tokenCeiling} est-tokens / ${MAX_MESSAGES} msgs).`
|
|
8052
8160
|
);
|
|
8053
8161
|
return out;
|
|
8054
8162
|
}
|