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
package/dist/cli.js
CHANGED
|
@@ -8395,6 +8395,105 @@ var init_cap_image_count = __esm({
|
|
|
8395
8395
|
}
|
|
8396
8396
|
});
|
|
8397
8397
|
|
|
8398
|
+
// src/utils/sanitize-images.ts
|
|
8399
|
+
function hasImageMagic(bytes) {
|
|
8400
|
+
if (bytes.length < 12) return false;
|
|
8401
|
+
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) return true;
|
|
8402
|
+
if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return true;
|
|
8403
|
+
if (bytes[0] === 71 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 56) return true;
|
|
8404
|
+
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;
|
|
8405
|
+
return false;
|
|
8406
|
+
}
|
|
8407
|
+
function extractBase64(part) {
|
|
8408
|
+
const raw = typeof part?.data === "string" ? part.data : typeof part?.image === "string" ? part.image : null;
|
|
8409
|
+
if (typeof raw !== "string" || raw.length === 0) return null;
|
|
8410
|
+
if (/^https?:\/\//i.test(raw)) return null;
|
|
8411
|
+
const dataUrl = raw.match(/^data:[^;,]+;base64,([\s\S]*)$/);
|
|
8412
|
+
return dataUrl ? dataUrl[1] : raw;
|
|
8413
|
+
}
|
|
8414
|
+
function isInvalidImagePart(part) {
|
|
8415
|
+
if (!part || typeof part !== "object") return false;
|
|
8416
|
+
const t = part.type;
|
|
8417
|
+
if (t !== "image" && t !== "image-data" && t !== "media") return false;
|
|
8418
|
+
const mt = part.mediaType;
|
|
8419
|
+
const b64 = extractBase64(part);
|
|
8420
|
+
if (b64 === null) {
|
|
8421
|
+
return typeof mt === "string" && mt.startsWith("image/") && !SUPPORTED_IMAGE_TYPES.includes(mt);
|
|
8422
|
+
}
|
|
8423
|
+
let bytes;
|
|
8424
|
+
try {
|
|
8425
|
+
bytes = Buffer.from(b64, "base64");
|
|
8426
|
+
} catch {
|
|
8427
|
+
return true;
|
|
8428
|
+
}
|
|
8429
|
+
if (bytes.length === 0) return true;
|
|
8430
|
+
return !hasImageMagic(bytes);
|
|
8431
|
+
}
|
|
8432
|
+
function placeholder() {
|
|
8433
|
+
return { type: "text", text: INVALID_IMAGE_PLACEHOLDER };
|
|
8434
|
+
}
|
|
8435
|
+
function sanitizeInvalidImages(messages) {
|
|
8436
|
+
if (!Array.isArray(messages) || messages.length === 0) return messages;
|
|
8437
|
+
let mutated = false;
|
|
8438
|
+
let dropped = 0;
|
|
8439
|
+
const out = messages.slice();
|
|
8440
|
+
for (let i = 0; i < out.length; i++) {
|
|
8441
|
+
const msg = out[i];
|
|
8442
|
+
if (!Array.isArray(msg.content)) continue;
|
|
8443
|
+
let contentCloned = false;
|
|
8444
|
+
const ensureCloned = () => {
|
|
8445
|
+
if (contentCloned) return;
|
|
8446
|
+
out[i] = { ...msg, content: [...msg.content] };
|
|
8447
|
+
contentCloned = true;
|
|
8448
|
+
};
|
|
8449
|
+
const content = () => out[i].content;
|
|
8450
|
+
for (let j = 0; j < content().length; j++) {
|
|
8451
|
+
const part = content()[j];
|
|
8452
|
+
if (isInvalidImagePart(part)) {
|
|
8453
|
+
ensureCloned();
|
|
8454
|
+
out[i].content[j] = placeholder();
|
|
8455
|
+
mutated = true;
|
|
8456
|
+
dropped++;
|
|
8457
|
+
continue;
|
|
8458
|
+
}
|
|
8459
|
+
if (part && typeof part === "object" && part.type === "tool-result" && part.output && part.output.type === "content" && Array.isArray(part.output.value)) {
|
|
8460
|
+
const innerValue = part.output.value;
|
|
8461
|
+
let innerMutated = false;
|
|
8462
|
+
const newValue = innerValue.slice();
|
|
8463
|
+
for (let k = 0; k < newValue.length; k++) {
|
|
8464
|
+
if (isInvalidImagePart(newValue[k])) {
|
|
8465
|
+
newValue[k] = placeholder();
|
|
8466
|
+
innerMutated = true;
|
|
8467
|
+
dropped++;
|
|
8468
|
+
}
|
|
8469
|
+
}
|
|
8470
|
+
if (innerMutated) {
|
|
8471
|
+
ensureCloned();
|
|
8472
|
+
out[i].content[j] = {
|
|
8473
|
+
...part,
|
|
8474
|
+
output: { ...part.output, value: newValue }
|
|
8475
|
+
};
|
|
8476
|
+
mutated = true;
|
|
8477
|
+
}
|
|
8478
|
+
}
|
|
8479
|
+
}
|
|
8480
|
+
}
|
|
8481
|
+
if (mutated) {
|
|
8482
|
+
console.warn(
|
|
8483
|
+
`[sanitize-images] Replaced ${dropped} invalid image part(s) with a text placeholder (non-image bytes / unsupported type) to avoid provider 400 "invalid image" errors.`
|
|
8484
|
+
);
|
|
8485
|
+
}
|
|
8486
|
+
return mutated ? out : messages;
|
|
8487
|
+
}
|
|
8488
|
+
var SUPPORTED_IMAGE_TYPES, INVALID_IMAGE_PLACEHOLDER;
|
|
8489
|
+
var init_sanitize_images = __esm({
|
|
8490
|
+
"src/utils/sanitize-images.ts"() {
|
|
8491
|
+
"use strict";
|
|
8492
|
+
SUPPORTED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
8493
|
+
INVALID_IMAGE_PLACEHOLDER = "[invalid image omitted \u2014 the data was not a valid jpeg/png/gif/webp]";
|
|
8494
|
+
}
|
|
8495
|
+
});
|
|
8496
|
+
|
|
8398
8497
|
// src/agent/model-limits.ts
|
|
8399
8498
|
function getModelLimits(modelId) {
|
|
8400
8499
|
const normalized = modelId.trim().toLowerCase();
|
|
@@ -8710,6 +8809,7 @@ var init_context = __esm({
|
|
|
8710
8809
|
init_prompts();
|
|
8711
8810
|
init_sanitize_messages();
|
|
8712
8811
|
init_cap_image_count();
|
|
8812
|
+
init_sanitize_images();
|
|
8713
8813
|
init_model_limits();
|
|
8714
8814
|
TOOL_OUTPUT_TRIM_CHARS = 400;
|
|
8715
8815
|
COMPACTABLE_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -8759,6 +8859,7 @@ ${summaryContent}`
|
|
|
8759
8859
|
messages = repairToolPairing(messages);
|
|
8760
8860
|
messages = ensureToolResultsFollowCalls(messages);
|
|
8761
8861
|
messages = ensureEndsWithUserOrTool(messages);
|
|
8862
|
+
messages = sanitizeInvalidImages(messages);
|
|
8762
8863
|
messages = capImageCount(messages);
|
|
8763
8864
|
messages = this.enforceHardCap(messages);
|
|
8764
8865
|
return messages;
|
|
@@ -8770,28 +8871,35 @@ ${summaryContent}`
|
|
|
8770
8871
|
* repairs tool pairing so dropping can't orphan a tool result.
|
|
8771
8872
|
*/
|
|
8772
8873
|
enforceHardCap(messages) {
|
|
8773
|
-
const {
|
|
8774
|
-
const
|
|
8874
|
+
const { rollingTarget } = getModelLimits(this.modelId);
|
|
8875
|
+
const MAX_MESSAGES = 120;
|
|
8876
|
+
const tokenCeiling = Math.max(2e4, Math.floor(rollingTarget * 1.5));
|
|
8775
8877
|
const tokens = messages.map((m) => this.messageTokens(m));
|
|
8776
8878
|
let total = tokens.reduce((a, b) => a + b, 0);
|
|
8777
|
-
if (total <= ceiling) return messages;
|
|
8778
8879
|
const hasLeadingSummary = messages.length > 0 && messages[0].role === "system";
|
|
8779
8880
|
const firstBody = hasLeadingSummary ? 1 : 0;
|
|
8780
8881
|
const lastIndex = messages.length - 1;
|
|
8882
|
+
const bodyCount = messages.length - firstBody;
|
|
8883
|
+
if (bodyCount <= MAX_MESSAGES && total <= tokenCeiling) return messages;
|
|
8781
8884
|
let start = firstBody;
|
|
8782
|
-
|
|
8885
|
+
const countDropTarget = messages.length - MAX_MESSAGES;
|
|
8886
|
+
while (start < countDropTarget && start < lastIndex) {
|
|
8887
|
+
total -= tokens[start];
|
|
8888
|
+
start += 1;
|
|
8889
|
+
}
|
|
8890
|
+
while (start < lastIndex && total > tokenCeiling) {
|
|
8783
8891
|
total -= tokens[start];
|
|
8784
8892
|
start += 1;
|
|
8785
8893
|
}
|
|
8786
8894
|
let out = hasLeadingSummary ? [messages[0], ...messages.slice(start)] : messages.slice(start);
|
|
8787
|
-
if (total >
|
|
8895
|
+
if (total > tokenCeiling) {
|
|
8788
8896
|
out = out.map((m) => hardTruncateMessageText(m));
|
|
8789
8897
|
}
|
|
8790
8898
|
out = repairToolPairing(out);
|
|
8791
8899
|
out = ensureToolResultsFollowCalls(out);
|
|
8792
8900
|
out = ensureEndsWithUserOrTool(out);
|
|
8793
8901
|
console.warn(
|
|
8794
|
-
`[Context] hard cap engaged for ${this.modelId}: trimmed ${messages.length}\u2192${out.length} msgs (ceiling ${
|
|
8902
|
+
`[Context] hard cap engaged for ${this.modelId}: trimmed ${messages.length}\u2192${out.length} msgs (ceiling ${tokenCeiling} est-tokens / ${MAX_MESSAGES} msgs).`
|
|
8795
8903
|
);
|
|
8796
8904
|
return out;
|
|
8797
8905
|
}
|