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.
Files changed (110) hide show
  1. package/dist/agent/index.d.ts +3 -3
  2. package/dist/agent/index.js +107 -6
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +114 -6
  5. package/dist/cli.js.map +1 -1
  6. package/dist/db/index.d.ts +2 -2
  7. package/dist/{index-BAsQWqZj.d.ts → index-Cl_eUatM.d.ts} +96 -96
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.js +114 -6
  10. package/dist/index.js.map +1 -1
  11. package/dist/{schema-Dz-wABVY.d.ts → schema-BSz4MzhJ.d.ts} +3 -3
  12. package/dist/{search-CVVfuBPZ.d.ts → search-DOzC4ojH.d.ts} +4 -4
  13. package/dist/server/index.js +114 -6
  14. package/dist/server/index.js.map +1 -1
  15. package/dist/tools/index.d.ts +3 -3
  16. package/package.json +1 -1
  17. package/web/.next/BUILD_ID +1 -1
  18. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  19. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  20. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  21. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  22. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  24. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  26. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
  37. package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  55. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  64. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  72. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  73. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  76. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  77. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  80. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  81. package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
  83. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
  84. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  85. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  86. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  87. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  88. package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
  89. package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
  90. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
  91. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
  92. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
  93. package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  94. package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  95. package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  96. package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  97. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  98. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  99. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  100. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  101. package/web/.next/standalone/web/runtime-config.json +2 -2
  102. /package/web/.next/standalone/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_buildManifest.js +0 -0
  103. /package/web/.next/standalone/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_clientMiddlewareManifest.json +0 -0
  104. /package/web/.next/standalone/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_ssgManifest.js +0 -0
  105. /package/web/.next/standalone/web/.next/static/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_buildManifest.js +0 -0
  106. /package/web/.next/standalone/web/.next/static/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_clientMiddlewareManifest.json +0 -0
  107. /package/web/.next/standalone/web/.next/static/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_ssgManifest.js +0 -0
  108. /package/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_buildManifest.js +0 -0
  109. /package/web/.next/static/{rY6TfiRfMLnxUYYyNit1Q → QkKMkVPV-LLRD2i9PBP_Y}/_clientMiddlewareManifest.json +0 -0
  110. /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: "completed" | "error" | "active" | "waiting";
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: "completed" | "error" | "pending" | "approved" | "rejected";
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: "running" | "error" | "stopped";
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" | "y" | "n" | undefined;
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: "running" | "completed" | "error" | "stopped";
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;
@@ -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 { contextWindow } = getModelLimits(this.modelId);
8031
- const ceiling = Math.max(2e4, Math.floor(contextWindow * 0.9));
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
- while (start < lastIndex && total > ceiling) {
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 > ceiling) {
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 ${ceiling} tokens).`
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
  }